From 11be575b6dddeba424c0bf02d848f6dd143ada8d Mon Sep 17 00:00:00 2001 From: kym Date: Thu, 5 Dec 2013 11:40:44 +0000 Subject: [PATCH 0001/2161] Initial Creativision Import --- asminc/creativision.inc | 38 +++++++ include/creativision.h | 59 +++++++++++ libsrc/creativision/_scrsize.s | 15 +++ libsrc/creativision/boxchars.inc | 62 +++++++++++ libsrc/creativision/cclear.s | 29 ++++++ libsrc/creativision/cgetc.s | 17 +++ libsrc/creativision/chline.s | 24 +++++ libsrc/creativision/clrscr.s | 41 ++++++++ libsrc/creativision/color.s | 13 +++ libsrc/creativision/cputc.s | 125 ++++++++++++++++++++++ libsrc/creativision/ctype.s | 172 +++++++++++++++++++++++++++++++ libsrc/creativision/cvline.s | 29 ++++++ libsrc/creativision/gotox.s | 19 ++++ libsrc/creativision/gotoxy.s | 22 ++++ libsrc/creativision/gotoy.s | 19 ++++ libsrc/creativision/joy.s | 58 +++++++++++ libsrc/creativision/libref.s | 9 ++ libsrc/creativision/mainargs.s | 24 +++++ libsrc/creativision/psg.s | 68 ++++++++++++ libsrc/creativision/setcursor.s | 36 +++++++ libsrc/creativision/sysuname.s | 39 +++++++ libsrc/creativision/wherex.s | 19 ++++ libsrc/creativision/wherey.s | 19 ++++ 23 files changed, 956 insertions(+) create mode 100644 asminc/creativision.inc create mode 100644 include/creativision.h create mode 100644 libsrc/creativision/_scrsize.s create mode 100644 libsrc/creativision/boxchars.inc create mode 100644 libsrc/creativision/cclear.s create mode 100644 libsrc/creativision/cgetc.s create mode 100644 libsrc/creativision/chline.s create mode 100644 libsrc/creativision/clrscr.s create mode 100644 libsrc/creativision/color.s create mode 100644 libsrc/creativision/cputc.s create mode 100644 libsrc/creativision/ctype.s create mode 100644 libsrc/creativision/cvline.s create mode 100644 libsrc/creativision/gotox.s create mode 100644 libsrc/creativision/gotoxy.s create mode 100644 libsrc/creativision/gotoy.s create mode 100644 libsrc/creativision/joy.s create mode 100644 libsrc/creativision/libref.s create mode 100644 libsrc/creativision/mainargs.s create mode 100644 libsrc/creativision/psg.s create mode 100644 libsrc/creativision/setcursor.s create mode 100644 libsrc/creativision/sysuname.s create mode 100644 libsrc/creativision/wherex.s create mode 100644 libsrc/creativision/wherey.s diff --git a/asminc/creativision.inc b/asminc/creativision.inc new file mode 100644 index 000000000..624b65e8f --- /dev/null +++ b/asminc/creativision.inc @@ -0,0 +1,38 @@ +;* +;** VTech Creativision Definitions +;* + +;** Screen +SCREEN_ROWS = 24 +SCREEN_COLS = 32 +SCREEN_PTR = $3A +CURSOR_X = $3C +CURSOR_Y = $3D + +;** VDP +VDP_CONTROL_W = $3001 +VDP_DATA_W = $3000 +VDP_STATUS_R = $2001 +VDP_DATA_R = $2000 + +;** PIA +PIA0_DATA = $1000 +PIA0_STATUS = $1001 +PIA1_DATA = $1002 +PIA1_STATUS = $1003 + +;** General +CH_VLINE = 33 +CH_HLINE = 34 +CH_ULCORNER = 35 +CH_URCORNER = 36 +CH_LLCORNER = 37 +CH_LRCORNER = 38 + +;** I/O +ZP_KEYBOARD = $10 +ZP_JOY0_DIR = $11 +ZP_JOY1_DIR = $13 +ZP_JOY_LBUTTONS = $16 +ZP_JOY_RBUTTONS = $17 + diff --git a/include/creativision.h b/include/creativision.h new file mode 100644 index 000000000..adaa1caab --- /dev/null +++ b/include/creativision.h @@ -0,0 +1,59 @@ +/* CreatiVision Header */ + +#ifndef _CVISION_H + +#define _CVISION_H + +#define CH_VLINE 33 +#define CH_HLINE 34 +#define CH_ULCORNER 35 +#define CH_URCORNER 36 +#define CH_LLCORNER 37 +#define CH_LRCORNER 38 + +#define DYN_DRV 0 + +/* Colours - from TMS9918 */ +#define C_TRANSPARENT 0 +#define C_BLACK 1 +#define C_MED_GREEN 2 +#define C_LIGHT_GREEN 3 +#define C_DARK_BLUE 4 +#define C_LIGHT_BLUE 5 +#define C_DARK_RED 6 +#define C_CYAN 7 +#define C_MED_RED 8 +#define C_LIGHT_RED 9 +#define C_DARK_YELLOW 10 +#define C_LIGHT_YELLOW 11 +#define C_DARK_GREEN 12 +#define C_MAGENTA 13 +#define C_GREY 14 +#define C_WHITE 15 + +/* Joystick states */ +#define JOY_UP 5 +#define JOY_DOWN 1 +#define JOY_LEFT 7 +#define JOY_RIGHT 3 +#define JOY_LEFT_UP 6 +#define JOY_LEFT_DOWN 8 +#define JOY_RIGHT_UP 4 +#define JOY_RIGHT_DOWN 2 +#define JOY_LBUTTON 1 +#define JOY_RBUTTON 2 + +/* Joystick values */ +#define JOY_LEFT_DIR 1 +#define JOY_RIGHT_DIR 2 +#define JOY_LEFT_BUTTONS 3 +#define JOY_RIGHT_BUTTONS 4 + +/* Protos */ +void __fastcall__ psg_outb( unsigned char b ); +void __fastcall__ psg_delay( unsigned char b ); +void psg_silence( void ); +void __fastcall__ bios_playsound( void *a, unsigned char b); +unsigned char __fastcall__ joystate( unsigned char which ); + +#endif diff --git a/libsrc/creativision/_scrsize.s b/libsrc/creativision/_scrsize.s new file mode 100644 index 000000000..fdcc7fc60 --- /dev/null +++ b/libsrc/creativision/_scrsize.s @@ -0,0 +1,15 @@ +;* +;** _scrsize.s +;* + + .export screensize + + .include "creativision.inc" + +.proc screensize + + ldx #SCREEN_COLS + ldy #SCREEN_ROWS + rts + +.endproc diff --git a/libsrc/creativision/boxchars.inc b/libsrc/creativision/boxchars.inc new file mode 100644 index 000000000..0916d49ce --- /dev/null +++ b/libsrc/creativision/boxchars.inc @@ -0,0 +1,62 @@ +; Boxchars + +boxchars: + ; Vertical Line + .byte $18 + .byte $18 + .byte $18 + .byte $18 + .byte $18 + .byte $18 + .byte $18 + .byte $18 + + ; Horizontal Line + .byte 0 + .byte 0 + .byte 0 + .byte $ff + .byte 0 + .byte 0 + .byte 0 + .byte 0 + + ; Top Left + .byte 0 + .byte 0 + .byte 0 + .byte $1f + .byte $18 + .byte $18 + .byte $18 + .byte $18 + + ; Top Right + .byte 0 + .byte 0 + .byte 0 + .byte $F8 + .byte $18 + .byte $18 + .byte $18 + .byte $18 + + ; Bottom Left + .byte $18 + .byte $18 + .byte $18 + .byte $1F + .byte 0 + .byte 0 + .byte 0 + .byte 0 + + ; Bottom Right + .byte $18 + .byte $18 + .byte $18 + .byte $F8 + .byte 0 + .byte 0 + .byte 0 + .byte 0 diff --git a/libsrc/creativision/cclear.s b/libsrc/creativision/cclear.s new file mode 100644 index 000000000..507c072bd --- /dev/null +++ b/libsrc/creativision/cclear.s @@ -0,0 +1,29 @@ +;* +;* void cclearxy (unsigned char x, unsigned char y, unsigned char length); +;* void cclear (unsigned char length); +;* + + .export _cclearxy, _cclear + .import popa, _gotoxy, cputdirect + .importzp tmp1 + +_cclearxy: + pha ; Save length + jsr popa ; get Y + jsr _gotoxy + pla + +_cclear: + cmp #0 ; Zero length? + beq L2 + sta tmp1 + +L1: + lda #$20 ; Space + jsr cputdirect + dec tmp1 + bne L1 + +L2: rts + + diff --git a/libsrc/creativision/cgetc.s b/libsrc/creativision/cgetc.s new file mode 100644 index 000000000..f1e89942a --- /dev/null +++ b/libsrc/creativision/cgetc.s @@ -0,0 +1,17 @@ +;* cgetc + + .export _cgetc + .include "creativision.inc" + +_cgetc: + lda #$80 + +L1: + bit ZP_KEYBOARD + bpl L1 + + lda ZP_KEYBOARD + and #$7f + rts + + diff --git a/libsrc/creativision/chline.s b/libsrc/creativision/chline.s new file mode 100644 index 000000000..c206180e0 --- /dev/null +++ b/libsrc/creativision/chline.s @@ -0,0 +1,24 @@ +;* void chlinexy (unsigned char x, unsigned char y, unsigned char length); +;* void chline (unsigned char length); + + .export _chlinexy, _chline + .import popa, _gotoxy, cputdirect + .importzp tmp1 + + .include "creativision.inc" + +_chlinexy: + pha ; Save the length + jsr popa ; Get y + jsr _gotoxy ; Call this one, will pop params + pla ; Restore the length + +_chline: + cmp #0 ; Is the length zero? + beq L9 ; Jump if done + sta tmp1 +L1: lda #CH_HLINE ; Horizontal line, screen code + jsr cputdirect ; Direct output + dec tmp1 + bne L1 +L9: rts diff --git a/libsrc/creativision/clrscr.s b/libsrc/creativision/clrscr.s new file mode 100644 index 000000000..ef800a9bd --- /dev/null +++ b/libsrc/creativision/clrscr.s @@ -0,0 +1,41 @@ +;* +;* clrscr +;* +;* NB: All screen functions assume Graphics Mode 1 in a default configuration. +;* Therefore, this is hard coded to use $1000-$12FF as screen VRAM. + + .export _clrscr + .include "creativision.inc" + +_clrscr: + + sei ; Disable interrupts. Default INT handler reads VDP_STATUS + ; and would lose any setup done here. + + lda #$00 ; VRAM offset low + sta VDP_CONTROL_W + + lda #$50 ; VRAM offset high ($10 OR $40) + sta VDP_CONTROL_W + + lda #$C0 ; Space from ROM setup + + ldx #0 + ldy #3 + +L1: sta VDP_DATA_W + inx + bne L1 + dey + bne L1 + + cli ; Let interrupts go again + + lda #0 + sta CURSOR_X + sta CURSOR_Y + sta SCREEN_PTR + + rts diff --git a/libsrc/creativision/color.s b/libsrc/creativision/color.s new file mode 100644 index 000000000..b6fd360b4 --- /dev/null +++ b/libsrc/creativision/color.s @@ -0,0 +1,13 @@ +;* +;* unsigned char __fastcall__ textcolor (unsigned char color); +;* unsigned char __fastcall__ bgcolor (unsigned char color); +;* unsigned char __fastcall__ bordercolor (unsigned char color); +;* + + .export _textcolor, _bgcolor, _bordercolor + .import return0 + .include "creativision.inc" + +_bordercolor = return0; +_textcolor = return0; +_bgcolor = return0; diff --git a/libsrc/creativision/cputc.s b/libsrc/creativision/cputc.s new file mode 100644 index 000000000..902caf277 --- /dev/null +++ b/libsrc/creativision/cputc.s @@ -0,0 +1,125 @@ +; +; Written by Groepaz/Hitmen +; Cleanup by Ullrich von Bassewitz +; +; void cputcxy (unsigned char x, unsigned char y, char c); +; void cputc (char c); +; + + .export _cputcxy, _cputc, cputdirect, putchar + .export newline + .constructor initconio + .import popa, _gotoxy + .import setcursor + + .importzp tmp3,tmp4 + + .include "creativision.inc" + .include "boxchars.inc" + +;----------------------------------------------------------------------------- + +.code + +_cputcxy: + pha ; Save C + jsr popa ; Get Y + jsr _gotoxy ; Set cursor, drop x + pla ; Restore C + +; Plot a character - also used as internal function + +_cputc: cmp #$0d ; CR? + bne L1 + lda #0 + sta CURSOR_X + beq plot ; Recalculate pointers + +L1: cmp #$0a ; LF? + beq newline ; Recalculate pointers + +; Printable char of some sort + +cputdirect: + jsr putchar ; Write the character to the screen + +; Advance cursor position + +advance: + ldy CURSOR_X + iny + cpy #SCREEN_COLS + bne L3 + inc CURSOR_Y ; new line + ldy #0 ; + cr +L3: sty CURSOR_X + jmp plot + +newline: + inc CURSOR_Y + +; Set cursor position, calculate RAM pointers + +plot: ldy CURSOR_X + ldx CURSOR_Y + jmp setcursor ; Set the new cursor + + +; Write one character to the screen without doing anything else, return X +; position in Y + +putchar: + cmp #$5B + bcc IS_UPPER + + clc + sbc #$1F + +IS_UPPER: + cmp #$20 + bcc BAD_CHAR + + pha + lda SCREEN_PTR + sei + sta VDP_CONTROL_W + lda SCREEN_PTR+1 + ora #$40 + sta VDP_CONTROL_W + pla + clc + adc #160 + sta VDP_DATA_W + cli + +BAD_CHAR: + jmp plot + +;----------------------------------------------------------------------------- +; Initialize the conio subsystem. Code goes into the INIT segment, which may +; be reused after startup. + +.segment "INIT" + +initconio: + lda #$0 + sta SCREEN_PTR + lda #$10 + sta SCREEN_PTR+1 + + ; Copy box characters to slot + sei + lda #08 + sta VDP_CONTROL_W + lda #$46 + sta VDP_CONTROL_W + ldx #0 +LL: + lda boxchars,x + sta VDP_DATA_W + inx + cpx #48 + bne LL + + cli + jmp plot diff --git a/libsrc/creativision/ctype.s b/libsrc/creativision/ctype.s new file mode 100644 index 000000000..6e0ab1785 --- /dev/null +++ b/libsrc/creativision/ctype.s @@ -0,0 +1,172 @@ +; +; Ullrich von Bassewitz, 02.06.1998 +; +; Character specification table. +; + +; The tables are readonly, put them into the rodata segment + +.rodata + +; The following 256 byte wide table specifies attributes for the isxxx type +; of functions. Doing it by a table means some overhead in space, but it +; has major advantages: +; +; * It is fast. If it were'nt for the slow parameter passing of cc65, one +; could even define macros for the isxxx functions (this is usually +; done on other platforms). +; +; * It is highly portable. The only unportable part is the table itself, +; all real code goes into the common library. +; +; * We save some code in the isxxx functions. +; +; +; Bit assignments: +; +; 0 - Lower case char +; 1 - Upper case char +; 2 - Numeric digit +; 3 - Hex digit (both, lower and upper) +; 4 - Control character +; 5 - The space character itself +; 6 - Other whitespace (that is: '\f', '\n', '\r', '\t' and '\v') +; 7 - Space or tab character + + .export __ctype + +__ctype: + +.repeat 2 ; 2 times for normal and inverted + + .byte $10 ; 0/00 ___ctrl_@___ + .byte $10 ; 1/01 ___ctrl_A___ + .byte $10 ; 2/02 ___ctrl_B___ + .byte $10 ; 3/03 ___ctrl_C___ + .byte $10 ; 4/04 ___ctrl_D___ + .byte $10 ; 5/05 ___ctrl_E___ + .byte $10 ; 6/06 ___ctrl_F___ + .byte $10 ; 7/07 ___ctrl_G___ + .byte $10 ; 8/08 ___ctrl_H___ + .byte $D0 ; 9/09 ___ctrl_I___ + .byte $50 ; 10/0a ___ctrl_J___ + .byte $50 ; 11/0b ___ctrl_K___ + .byte $50 ; 12/0c ___ctrl_L___ + .byte $50 ; 13/0d ___ctrl_M___ + .byte $10 ; 14/0e ___ctrl_N___ + .byte $10 ; 15/0f ___ctrl_O___ + .byte $10 ; 16/10 ___ctrl_P___ + .byte $10 ; 17/11 ___ctrl_Q___ + .byte $10 ; 18/12 ___ctrl_R___ + .byte $10 ; 19/13 ___ctrl_S___ + .byte $10 ; 20/14 ___ctrl_T___ + .byte $10 ; 21/15 ___ctrl_U___ + .byte $10 ; 22/16 ___ctrl_V___ + .byte $10 ; 23/17 ___ctrl_W___ + .byte $10 ; 24/18 ___ctrl_X___ + .byte $10 ; 25/19 ___ctrl_Y___ + .byte $10 ; 26/1a ___ctrl_Z___ + .byte $10 ; 27/1b ___ctrl_[___ + .byte $10 ; 28/1c ___ctrl_\___ + .byte $10 ; 29/1d ___ctrl_]___ + .byte $10 ; 30/1e ___ctrl_^___ + .byte $10 ; 31/1f ___ctrl_____ + .byte $A0 ; 32/20 ___SPACE___ + .byte $00 ; 33/21 _____!_____ + .byte $00 ; 34/22 _____"_____ + .byte $00 ; 35/23 _____#_____ + .byte $00 ; 36/24 _____$_____ + .byte $00 ; 37/25 _____%_____ + .byte $00 ; 38/26 _____&_____ + .byte $00 ; 39/27 _____'_____ + .byte $00 ; 40/28 _____(_____ + .byte $00 ; 41/29 _____)_____ + .byte $00 ; 42/2a _____*_____ + .byte $00 ; 43/2b _____+_____ + .byte $00 ; 44/2c _____,_____ + .byte $00 ; 45/2d _____-_____ + .byte $00 ; 46/2e _____._____ + .byte $00 ; 47/2f _____/_____ + .byte $0C ; 48/30 _____0_____ + .byte $0C ; 49/31 _____1_____ + .byte $0C ; 50/32 _____2_____ + .byte $0C ; 51/33 _____3_____ + .byte $0C ; 52/34 _____4_____ + .byte $0C ; 53/35 _____5_____ + .byte $0C ; 54/36 _____6_____ + .byte $0C ; 55/37 _____7_____ + .byte $0C ; 56/38 _____8_____ + .byte $0C ; 57/39 _____9_____ + .byte $00 ; 58/3a _____:_____ + .byte $00 ; 59/3b _____;_____ + .byte $00 ; 60/3c _____<_____ + .byte $00 ; 61/3d _____=_____ + .byte $00 ; 62/3e _____>_____ + .byte $00 ; 63/3f _____?_____ + + .byte $00 ; 64/40 _____@_____ + .byte $0A ; 65/41 _____A_____ + .byte $0A ; 66/42 _____B_____ + .byte $0A ; 67/43 _____C_____ + .byte $0A ; 68/44 _____D_____ + .byte $0A ; 69/45 _____E_____ + .byte $0A ; 70/46 _____F_____ + .byte $02 ; 71/47 _____G_____ + .byte $02 ; 72/48 _____H_____ + .byte $02 ; 73/49 _____I_____ + .byte $02 ; 74/4a _____J_____ + .byte $02 ; 75/4b _____K_____ + .byte $02 ; 76/4c _____L_____ + .byte $02 ; 77/4d _____M_____ + .byte $02 ; 78/4e _____N_____ + .byte $02 ; 79/4f _____O_____ + .byte $02 ; 80/50 _____P_____ + .byte $02 ; 81/51 _____Q_____ + .byte $02 ; 82/52 _____R_____ + .byte $02 ; 83/53 _____S_____ + .byte $02 ; 84/54 _____T_____ + .byte $02 ; 85/55 _____U_____ + .byte $02 ; 86/56 _____V_____ + .byte $02 ; 87/57 _____W_____ + .byte $02 ; 88/58 _____X_____ + .byte $02 ; 89/59 _____Y_____ + .byte $02 ; 90/5a _____Z_____ + .byte $00 ; 91/5b _____[_____ + .byte $00 ; 92/5c _____\_____ + .byte $00 ; 93/5d _____]_____ + .byte $00 ; 94/5e _____^_____ + .byte $00 ; 95/5f _UNDERLINE_ + .byte $00 ; 96/60 ___grave___ + .byte $09 ; 97/61 _____a_____ + .byte $09 ; 98/62 _____b_____ + .byte $09 ; 99/63 _____c_____ + .byte $09 ; 100/64 _____d_____ + .byte $09 ; 101/65 _____e_____ + .byte $09 ; 102/66 _____f_____ + .byte $01 ; 103/67 _____g_____ + .byte $01 ; 104/68 _____h_____ + .byte $01 ; 105/69 _____i_____ + .byte $01 ; 106/6a _____j_____ + .byte $01 ; 107/6b _____k_____ + .byte $01 ; 108/6c _____l_____ + .byte $01 ; 109/6d _____m_____ + .byte $01 ; 110/6e _____n_____ + .byte $01 ; 111/6f _____o_____ + .byte $01 ; 112/70 _____p_____ + .byte $01 ; 113/71 _____q_____ + .byte $01 ; 114/72 _____r_____ + .byte $01 ; 115/73 _____s_____ + .byte $01 ; 116/74 _____t_____ + .byte $01 ; 117/75 _____u_____ + .byte $01 ; 118/76 _____v_____ + .byte $01 ; 119/77 _____w_____ + .byte $01 ; 120/78 _____x_____ + .byte $01 ; 121/79 _____y_____ + .byte $01 ; 122/7a _____z_____ + .byte $00 ; 123/7b _____{_____ + .byte $00 ; 124/7c _____|_____ + .byte $00 ; 125/7d _____}_____ + .byte $00 ; 126/7e _____~_____ + .byte $40 ; 127/7f ____DEL____ + +.endrepeat diff --git a/libsrc/creativision/cvline.s b/libsrc/creativision/cvline.s new file mode 100644 index 000000000..4e7d2563e --- /dev/null +++ b/libsrc/creativision/cvline.s @@ -0,0 +1,29 @@ +; +; Ullrich von Bassewitz, 08.08.1998 +; +; void cvlinexy (unsigned char x, unsigned char y, unsigned char length); +; void cvline (unsigned char length); +; + + .export _cvlinexy, _cvline + .import popa, _gotoxy, putchar, newline + .importzp tmp1 + + .include "creativision.inc" + +_cvlinexy: + pha ; Save the length + jsr popa ; Get y + jsr _gotoxy ; Call this one, will pop params + pla ; Restore the length and run into _cvline + +_cvline: + cmp #0 ; Is the length zero? + beq L9 ; Jump if done + sta tmp1 +L1: lda #CH_VLINE ; Vertical bar + jsr putchar ; Write, no cursor advance + jsr newline ; Advance cursor to next line + dec tmp1 + bne L1 +L9: rts diff --git a/libsrc/creativision/gotox.s b/libsrc/creativision/gotox.s new file mode 100644 index 000000000..6970e5d24 --- /dev/null +++ b/libsrc/creativision/gotox.s @@ -0,0 +1,19 @@ +; +; Ullrich von Bassewitz, 2003-05-02 +; +; void gotox (unsigned char x); +; + + .export _gotox + .import setcursor + + .include "creativision.inc" + +.proc _gotox + + sta CURSOR_X ; Set new position + tay + ldx CURSOR_Y + jmp setcursor ; Set the cursor to the new position + +.endproc diff --git a/libsrc/creativision/gotoxy.s b/libsrc/creativision/gotoxy.s new file mode 100644 index 000000000..6c0cf932f --- /dev/null +++ b/libsrc/creativision/gotoxy.s @@ -0,0 +1,22 @@ +; +; Ullrich von Bassewitz, 06.08.1998 +; +; void gotoxy (unsigned char x, unsigned char y); +; + + .export _gotoxy + .import setcursor + .import popa + + .include "creativision.inc" + +.proc _gotoxy + + sta CURSOR_Y ; Set Y + jsr popa ; Get X + sta CURSOR_X ; Set X + tay + ldx CURSOR_Y + jmp setcursor ; Set the cursor position + +.endproc diff --git a/libsrc/creativision/gotoy.s b/libsrc/creativision/gotoy.s new file mode 100644 index 000000000..484608d75 --- /dev/null +++ b/libsrc/creativision/gotoy.s @@ -0,0 +1,19 @@ +; +; Ullrich von Bassewitz, 2003-05-02 +; +; void gotoy (unsigned char y); +; + + .export _gotoy + .import setcursor + + .include "creativision.inc" + +.proc _gotoy + + sta CURSOR_Y ; Set new position + tax + ldy CURSOR_X + jmp setcursor ; Set the cursor to the new position + +.endproc diff --git a/libsrc/creativision/joy.s b/libsrc/creativision/joy.s new file mode 100644 index 000000000..f1c9b09f7 --- /dev/null +++ b/libsrc/creativision/joy.s @@ -0,0 +1,58 @@ +;* +;* Creativision Joystick Function +;* +;* unsigned char __fastcall__ joystate(unsigned char joy); +;* +;* JOY_1 -> Return Left Joystick direction +;* JOY_2 -> Return Right Joystick direction +;* JOY_3 -> Return Left Joystick buttons +;* JOY_4 -> Return Right Joystick buttons +;* +;* Will only work if interrupts are enabled. + + .export _joystate + .include "creativision.inc" + +_joystate: + cmp #1 ; Left Direction + bne l1 + + lda $11 + beq l5 + and #$f + lsr a + tax + inx + txa + rts + +l1: cmp #2 ; Right Direction + bne l2 + + lda $13 + beq l5 + and #$f + lsr a + tax + inx + txa + rts + +l2: cmp #3 ; Left Buttons + bne l3 + + lda $16 + beq l5 + and #$f + rts + +l3: cmp #4 + bne l4 + + lda $17 + beq l5 + and #$f + rts + +l4: lda #0 +l5: rts diff --git a/libsrc/creativision/libref.s b/libsrc/creativision/libref.s new file mode 100644 index 000000000..d947c1aa4 --- /dev/null +++ b/libsrc/creativision/libref.s @@ -0,0 +1,9 @@ +; +; Oliver Schmidt, 2013-05-31 +; + + .export joy_libref, tgi_libref + .import _exit + +joy_libref := _exit +tgi_libref := _exit diff --git a/libsrc/creativision/mainargs.s b/libsrc/creativision/mainargs.s new file mode 100644 index 000000000..7ed8d46f4 --- /dev/null +++ b/libsrc/creativision/mainargs.s @@ -0,0 +1,24 @@ +; +; Ullrich von Bassewitz, 2003-03-07 +; +; Setup arguments for main +; + + + .constructor initmainargs, 24 + .import __argc, __argv + + +;--------------------------------------------------------------------------- +; Get possible command-line arguments. Goes into the special INIT segment, +; which may be reused after the startup code is run + +.segment "INIT" + +.proc initmainargs + + rts + +.endproc + + diff --git a/libsrc/creativision/psg.s b/libsrc/creativision/psg.s new file mode 100644 index 000000000..12b474339 --- /dev/null +++ b/libsrc/creativision/psg.s @@ -0,0 +1,68 @@ +; void __fastcall__ psg_outb( unsigned char b ); +; void __fastcall__ psg_delayms( unsigned char c); +; void __fastcall__ bios_playsound( void *b, unsigned char c); +; void psg_silence( void ); + + .export _psg_outb, _psg_silence, _psg_delay + .export _bios_playsound + .import popa + .include "creativision.inc" + +_psg_outb: + + ;* Let BIOS output the value + jmp $FE77 + +_psg_silence: + + jmp $FE54 + + +_psg_delay: + + tay +l1: + lda #200 +l2: + sbc #1 + bne l2 + + lda #200 +l3: + sbc #1 + bne l3 + + dey + bne l1 + + rts + + +;* Creativision Sound Player +;* +;* Based on BIOS sound player. +;* Pass a pointer to a set of note triples, terminated with a tempo byte +;* and the len (max 255) + +_bios_playsound: + + pha ; Save Length Byte + + sei + + lda #$D5 ; BIOS volume table low + sta $4 + lda #$FC ; BIOS volume table high + sta $5 + + jsr popa ; Get Sound table pointer low + sta $0 + jsr popa ; Get Sound table pointer high + sta $1 + + pla + tay ; Put length in Y + dey + php + jmp $fbed ; Let BIOS do it's thing + diff --git a/libsrc/creativision/setcursor.s b/libsrc/creativision/setcursor.s new file mode 100644 index 000000000..9918cbcb2 --- /dev/null +++ b/libsrc/creativision/setcursor.s @@ -0,0 +1,36 @@ +; +; Written by Groepaz/Hitmen +; Cleanup by Ullrich von Bassewitz +; +; Set the cursor position + + .export setcursor + + .include "creativision.inc" + +;----------------------------------------------------------------------------- + +.proc setcursor + + tya + clc + adc addrlo,x + sta SCREEN_PTR + + lda addrhi,x + adc #0 + sta SCREEN_PTR+1 + rts + +.endproc + +;----------------------------------------------------------------------------- +; Tables with screen addresses + +addrlo: .repeat SCREEN_ROWS,line + .byte <($1000+(line*SCREEN_COLS)) + .endrepeat + +addrhi: .repeat SCREEN_ROWS,line + .byte >($1000+(line*SCREEN_COLS)) + .endrepeat diff --git a/libsrc/creativision/sysuname.s b/libsrc/creativision/sysuname.s new file mode 100644 index 000000000..df1a81b67 --- /dev/null +++ b/libsrc/creativision/sysuname.s @@ -0,0 +1,39 @@ +; +; 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 ((.VERSION >> 8) & $0F) + '0' + .byte '.' + .byte ((.VERSION >> 4) & $0F) + '0' + .byte $00 + + ; version + .byte (.VERSION & $0F) + '0' + .byte $00 + + ; machine + .asciiz "CREATIVISION" + + + diff --git a/libsrc/creativision/wherex.s b/libsrc/creativision/wherex.s new file mode 100644 index 000000000..f9df2d1a1 --- /dev/null +++ b/libsrc/creativision/wherex.s @@ -0,0 +1,19 @@ +; +; Ullrich von Bassewitz, 2003-05-02 +; +; unsigned char wherex (void); +; + + .export _wherex + + .include "creativision.inc" + +.proc _wherex + + lda CURSOR_X + ldx #$00 + rts + +.endproc + + diff --git a/libsrc/creativision/wherey.s b/libsrc/creativision/wherey.s new file mode 100644 index 000000000..6d7b056f5 --- /dev/null +++ b/libsrc/creativision/wherey.s @@ -0,0 +1,19 @@ +; +; Ullrich von Bassewitz, 2003-05-02 +; +; unsigned char wherey (void); +; + + .export _wherey + + .include "creativision.inc" + +.proc _wherey + + lda CURSOR_Y + ldx #$00 + rts + +.endproc + + From d23db09f7f424ae837b2cabaa1f57506073044e9 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Thu, 25 Feb 2016 12:40:31 -0800 Subject: [PATCH 0002/2161] Add optional feature to use brackets instead of parens for 6502 indirect addressing. --- doc/ca65.sgml | 14 ++++++++++++ src/ca65/ea65.c | 56 +++++++++++++++++++++++++++++----------------- src/ca65/feature.c | 2 ++ src/ca65/feature.h | 1 + src/ca65/global.c | 1 + src/ca65/global.h | 1 + 6 files changed, 55 insertions(+), 20 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 213033cd4..f863e7e10 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -2699,6 +2699,20 @@ Here's a list of all control commands and a description, what they do: at character is not allowed to start an identifier, even with this feature enabled. + bracket_as_indirect + + Use [] intead of () for the indirect addressing mode. + Example: + + + lda [$82] + lda [$82,x] + lda [$82],y + + / for more information. + c_comments Allow C like comments using /* and */ as left and right diff --git a/src/ca65/ea65.c b/src/ca65/ea65.c index 5f76f2966..69468c072 100644 --- a/src/ca65/ea65.c +++ b/src/ca65/ea65.c @@ -40,6 +40,7 @@ #include "expr.h" #include "instr.h" #include "nexttok.h" +#include "global.h" @@ -53,6 +54,20 @@ void GetEA (EffAddr* A) /* Parse an effective address, return the result in A */ { unsigned long Restrictions; + token_t IndirectEnter; + token_t IndirectLeave; + const char* IndirectExpect; + + /* Choose syntax for indirection */ + if (BracketAsIndirect) { + IndirectEnter = TOK_LBRACK; + IndirectLeave = TOK_RBRACK; + IndirectExpect = "']' expected"; + } else { + IndirectEnter = TOK_LPAREN; + IndirectLeave = TOK_RPAREN; + IndirectExpect = "')' expected"; + } /* Clear the output struct */ A->AddrModeSet = 0; @@ -97,23 +112,7 @@ void GetEA (EffAddr* A) NextTok (); A->AddrModeSet = AM65_ACCU; - } else if (CurTok.Tok == TOK_LBRACK) { - - /* [dir] or [dir],y */ - NextTok (); - A->Expr = Expression (); - Consume (TOK_RBRACK, "']' expected"); - if (CurTok.Tok == TOK_COMMA) { - /* [dir],y */ - NextTok (); - Consume (TOK_Y, "`Y' expected"); - A->AddrModeSet = AM65_DIR_IND_LONG_Y; - } else { - /* [dir] */ - A->AddrModeSet = AM65_DIR_IND_LONG | AM65_ABS_IND_LONG; - } - - } else if (CurTok.Tok == TOK_LPAREN) { + } else if (CurTok.Tok == IndirectEnter) { /* One of the indirect modes */ NextTok (); @@ -127,12 +126,12 @@ void GetEA (EffAddr* A) /* (adr,x) */ NextTok (); A->AddrModeSet = AM65_ABS_X_IND | AM65_DIR_X_IND; - ConsumeRParen (); + Consume (IndirectLeave, IndirectExpect); } else if (CurTok.Tok == TOK_S) { /* (rel,s),y */ NextTok (); A->AddrModeSet = AM65_STACK_REL_IND_Y; - ConsumeRParen (); + Consume (IndirectLeave, IndirectExpect); ConsumeComma (); Consume (TOK_Y, "`Y' expected"); } else { @@ -142,7 +141,7 @@ void GetEA (EffAddr* A) } else { /* (adr) or (adr),y */ - ConsumeRParen (); + Consume (IndirectLeave, IndirectExpect); if (CurTok.Tok == TOK_COMMA) { /* (adr),y */ NextTok (); @@ -154,6 +153,23 @@ void GetEA (EffAddr* A) } } + } else if (CurTok.Tok == TOK_LBRACK) { + + /* Never executed if BracketAsIndirect feature is enabled. */ + /* [dir] or [dir],y */ + NextTok (); + A->Expr = Expression (); + Consume (TOK_RBRACK, "']' expected"); + if (CurTok.Tok == TOK_COMMA) { + /* [dir],y */ + NextTok (); + Consume (TOK_Y, "`Y' expected"); + A->AddrModeSet = AM65_DIR_IND_LONG_Y; + } else { + /* [dir] */ + A->AddrModeSet = AM65_DIR_IND_LONG | AM65_ABS_IND_LONG; + } + } else { /* Remaining stuff: diff --git a/src/ca65/feature.c b/src/ca65/feature.c index 3462d5501..35bdf4b98 100644 --- a/src/ca65/feature.c +++ b/src/ca65/feature.c @@ -64,6 +64,7 @@ static const char* FeatureKeys[FEAT_COUNT] = { "force_range", "underline_in_numbers", "addrsize", + "bracket_as_indirect", }; @@ -121,6 +122,7 @@ feature_t SetFeature (const StrBuf* Key) case FEAT_FORCE_RANGE: ForceRange = 1; break; case FEAT_UNDERLINE_IN_NUMBERS: UnderlineInNumbers= 1; break; case FEAT_ADDRSIZE: AddrSize = 1; break; + case FEAT_BRACKET_AS_INDIRECT: BracketAsIndirect = 1; break; default: /* Keep gcc silent */ break; } diff --git a/src/ca65/feature.h b/src/ca65/feature.h index 3a520a54a..050c197f0 100644 --- a/src/ca65/feature.h +++ b/src/ca65/feature.h @@ -66,6 +66,7 @@ typedef enum { FEAT_FORCE_RANGE, FEAT_UNDERLINE_IN_NUMBERS, FEAT_ADDRSIZE, + FEAT_BRACKET_AS_INDIRECT, /* Special value: Number of features available */ FEAT_COUNT diff --git a/src/ca65/global.c b/src/ca65/global.c index e77b9201c..31e599f00 100644 --- a/src/ca65/global.c +++ b/src/ca65/global.c @@ -83,4 +83,5 @@ unsigned char CComments = 0; /* Allow C like comments */ unsigned char ForceRange = 0; /* Force values into expected range */ unsigned char UnderlineInNumbers = 0; /* Allow underlines in numbers */ unsigned char AddrSize = 0; /* Allow .ADDRSIZE function */ +unsigned char BracketAsIndirect = 0; /* Use '[]' not '()' for indirection */ diff --git a/src/ca65/global.h b/src/ca65/global.h index fb254f835..397d9221b 100644 --- a/src/ca65/global.h +++ b/src/ca65/global.h @@ -85,6 +85,7 @@ extern unsigned char CComments; /* Allow C like comments */ extern unsigned char ForceRange; /* Force values into expected range */ extern unsigned char UnderlineInNumbers; /* Allow underlines in numbers */ extern unsigned char AddrSize; /* Allow .ADDRSIZE function */ +extern unsigned char BracketAsIndirect; /* Use '[]' not '()' for indirection */ From ef153364eab92e2124035e5555b8c5cfbfa6e5b4 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Fri, 26 Feb 2016 08:10:11 -0800 Subject: [PATCH 0003/2161] Add indirect JMP examples and fix typos in the documentation. --- doc/ca65.sgml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index f863e7e10..14fe8714f 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -2701,13 +2701,15 @@ Here's a list of all control commands and a description, what they do: bracket_as_indirect - Use [] intead of () for the indirect addressing mode. + Use [] instead of () for the indirect addressing modes. Example: lda [$82] lda [$82,x] lda [$82],y + jmp [$fffe] + jmp [table,x] Date: Fri, 26 Feb 2016 17:11:11 -0500 Subject: [PATCH 0004/2161] draft of cc65-intern document --- doc/cc65-intern.sgml | 138 +++++++++++++++++++++++++++++++++++++++++++ doc/index.sgml | 3 + 2 files changed, 141 insertions(+) create mode 100644 doc/cc65-intern.sgml diff --git a/doc/cc65-intern.sgml b/doc/cc65-intern.sgml new file mode 100644 index 000000000..f3aef939a --- /dev/null +++ b/doc/cc65-intern.sgml @@ -0,0 +1,138 @@ + + +
+cc65 internals +<author><url url="mailto:brad@rainwarrior.ca" name="Brad Smith"> +<date>2016-02-27 + +<abstract> +Internal details of cc65 code generation, +such as calling assembly functions from C. +</abstract> + +<!-- Table of contents --> +<toc> + +<!-- Begin the document --> + + + +<sect>Calling assembly functions from C<p> + +<sect1>Calling conventions<p> + +There are two calling conventions used in cc65: + +<itemize> + <item><tt/cdecl/ - passes all parameters on the C-stack. + <p> + <item><tt/fastcall/ - passes the rightmost parameter in + registers <tt>A/X/sreg</tt> an all others on the C-stack. + <p> +</itemize> + +The default convention is <tt/fastcall/, but this can be changed with +the <tt/--all-cdecl/ command line option. If a convention is specified in +the function's declaration, that convention will be used instead. +Variadic functions will always use <tt/cdecl/ convention. + +If the <tt/--standard/ command line option is used, +the <tt/cdecl/ and <tt/fastcall/ keywords will not be available. +The standard compliant variations <tt/__cdecl__/ and <tt/__fastcall__/ are always available. + +K & R style function prototypes may be used, but they do not alter the calling conventions in any way. + +<sect1>Prologue, before the function call<p> + +If the function is declared as fastcall, the rightmost argument will be loaded into +the <tt>A/X/sreg</tt> registers: + +<itemize> + <item><tt/A/ - 8-bit parameter, or low byte of larger tyes<p> + <item><tt/X/ - 16-bit high byte, or second byte of 32-bits<p> + <item><tt/sreg/ - Zeropage pseudo-register including high 2 bytes of 32-bit parameter<p> +</itemize> + +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/Y/ register will contain the number of bytes pushed to the stack for this function, +and the <tt/sp/ pseudo-register is a zeropage pointer to the base of the C-stack. + +Example: +<tscreen><verb> +// C prototype +void foo(unsigned bar, unsigned char baz); + +; C-stack layout within the function: +; +; +------------------+ +; | High byte of bar | +; Offset 2 ->+------------------+ +; | Low byte of bar | +; Offset 1 ->+------------------+ +; | baz | +; Offset 0 ->+------------------+ + +; 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 + tax ; High byte now in X + dey ; Offset of low byte of bar + lda (sp),y ; Low byte now in A +</verb></tscreen> + +Variadic functions push all parameters exactly as other <tt/cdecl/ convention functions, +but the value of <tt/Y/ should be used to determine how many bytes of parameters +were placed onto the stack. + +<sect1>Epilogue, after the functiona call<p> + +<sect2>Return requirements</p> + +If the function has a return value, it will appear in the <tt>A/X/sreg</tt> registers. + +Functions with an 8-bit return value (<tt/char/ or <tt/unsigned char/) are expected +to promote this value to a 16-bit integer on return, and store the high byte in <tt/X/. +The compiler will depend on the promoted value in some cases (e.g. implicit conversion to <tt/int/), +and failure to return the high byte in <tt/X/ will cause unexpected errors. +This problem does not apply to the <tt/sreg/ pseudo-register, which is only +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 +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. +On entry to the function the <tt/Y/ register contains the number of bytes +pushed to the stack, which may be added to <tt/sp/ to restore its original state. + +The internal pseudo-register <tt/regbank/ must not be changed by the function. + +<sect2>Clobbered state</p> + +The <tt/Y/ register may be clobbered by the function. +The compiler will not depend on its state after a function call. + +The <tt>A/X/sreg</tt> registers may be clobbered if any of them +are not used by the return value (see above). + +Many of the internal pseudo-registers used by cc65 are available for +free use by any function called by C, and do not need to be preserved. +Note that if another C function is called from your assembly function, +it may clobber any of these itself: +<itemize> + <item><tt>tmp1 .. tmp4</tt><p> + <item><tt>ptr1 .. ptr4</tt><p> + <item><tt>regsave</tt><p> + <item><tt>sreg</tt> (if unused by return)<p> +</itemize> + + + +</article> + diff --git a/doc/index.sgml b/doc/index.sgml index b6ef06ef9..5b36db6e9 100644 --- a/doc/index.sgml +++ b/doc/index.sgml @@ -58,6 +58,9 @@ <tag><htmlurl url="coding.html" name="coding.html"></tag> Contains hints on creating the most effective code with cc65. + + <tag><htmlurl url="cc65-intern.html" name="cc65-intern.html"></tag> + Describes internal details of cc65, such as calling conventions. <tag><htmlurl url="using-make.html" name="using-make.html"></tag> Build programs, using the GNU Make utility. From 222ab93026cdd03ea85c49a1999f5d568be2efab Mon Sep 17 00:00:00 2001 From: Brad Smith <rainwarrior@gmail.com> Date: Fri, 26 Feb 2016 17:33:46 -0500 Subject: [PATCH 0005/2161] revise note on prototypes/K&R conventions --- doc/cc65-intern.sgml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/doc/cc65-intern.sgml b/doc/cc65-intern.sgml index f3aef939a..0bcb51cba 100644 --- a/doc/cc65-intern.sgml +++ b/doc/cc65-intern.sgml @@ -40,7 +40,11 @@ If the <tt/--standard/ command line option is used, the <tt/cdecl/ and <tt/fastcall/ keywords will not be available. The standard compliant variations <tt/__cdecl__/ and <tt/__fastcall__/ are always available. -K & R style function prototypes may be used, but they do not alter the calling conventions in any way. +If a function has a prototype, parameters are pushed to the C-stack as their respective types +(i.e. a <tt/char/ parameter will push 1 byte), but if a function has no prototype, default +promotions will apply. This means that with no prototype, <tt/char/ will be promoted +to <tt/int/ and be pushed as 2 bytes. K & R style function prototypes may be used, +but they will function the same as if no prototype was used. <sect1>Prologue, before the function call<p> @@ -57,8 +61,9 @@ 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/Y/ register will contain the number of bytes pushed to the stack for this function, -and the <tt/sp/ pseudo-register is a zeropage pointer to the base of the C-stack. +The <tt/sp/ pseudo-register is a zeropage pointer to the base of the C-stack. +If the function has no prototype or is variadic +the <tt/Y/ register will contain the number of bytes pushed to the stack for this function. Example: <tscreen><verb> @@ -84,10 +89,6 @@ void foo(unsigned bar, unsigned char baz); lda (sp),y ; Low byte now in A </verb></tscreen> -Variadic functions push all parameters exactly as other <tt/cdecl/ convention functions, -but the value of <tt/Y/ should be used to determine how many bytes of parameters -were placed onto the stack. - <sect1>Epilogue, after the functiona call<p> <sect2>Return requirements</p> @@ -106,10 +107,10 @@ 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 function call prologue. It may pop all of its parameters from the C-stack -(e.g. using the <tt/runtime/ function <tt/popa/.), +(e.g. using the <tt/runtime/ function <tt/popa/), or it could adjust <tt/sp/ directly. -On entry to the function the <tt/Y/ register contains the number of bytes -pushed to the stack, which may be added to <tt/sp/ to restore its original state. +If the function has no prototype, or 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 original state. The internal pseudo-register <tt/regbank/ must not be changed by the function. From 54e09fdd0369fe4388956ca7ed65528af1675bd7 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 25 Nov 2013 22:52:04 +0100 Subject: [PATCH 0006/2161] Added basic frame for new target 'creativision'. Kym Greenshields <kym.greenshields@gmail.com> has expressed interest in contributing and maintaining support for the VTech CreatiVision system. this resembles commit 8e6b8dd0afed52c1963ea29c4921157693463cbe from oliver --- cfg/creativision.cfg | 35 +++++++++++++ libsrc/Makefile | 1 + libsrc/creativision/crt0.s | 102 +++++++++++++++++++++++++++++++++++++ src/ca65/main.c | 38 +++++++++----- src/cc65/main.c | 38 +++++++++----- src/common/target.c | 16 +++--- src/common/target.h | 15 +++--- 7 files changed, 203 insertions(+), 42 deletions(-) create mode 100644 cfg/creativision.cfg create mode 100644 libsrc/creativision/crt0.s diff --git a/cfg/creativision.cfg b/cfg/creativision.cfg new file mode 100644 index 000000000..9122ccd42 --- /dev/null +++ b/cfg/creativision.cfg @@ -0,0 +1,35 @@ +SYMBOLS { + __STACKSIZE__: type = weak, value = $0180; +} +MEMORY { + ZP: file = "", define = yes, start = $0020, size = $00E0; + RAM: file = "", define = yes, start = $01FA, size = $0206; + ROM: file = %O, define = yes, start = $B000, size = $1000; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + ZP: load = ZP, type = zp, optional = yes; + VECTORS: load = ROM, run = RAM, type = rw, define = yes; + DATA: load = ROM, run = RAM, type = rw, define = yes, start = $0204; + BSS: load = RAM, type = bss, define = yes; + CODE: load = ROM, type = ro; + INIT: load = ROM, type = ro; + RODATA: load = ROM, type = ro; + AUDIO: load = ROM, type = ro, optional = yes, start = $BF00; + SETUP: load = ROM, type = ro, start = $BFE8; +} +FEATURES { + CONDES: type = constructor, + label = __CONSTRUCTOR_TABLE__, + count = __CONSTRUCTOR_COUNT__, + segment = INIT; + 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/libsrc/Makefile b/libsrc/Makefile index a4101aecd..364b266c8 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -20,6 +20,7 @@ TARGETS = apple2 \ atarixl \ atari5200 \ atmos \ + creativision \ $(CBMS) \ $(GEOS) \ gamate \ diff --git a/libsrc/creativision/crt0.s b/libsrc/creativision/crt0.s new file mode 100644 index 000000000..ccae38e81 --- /dev/null +++ b/libsrc/creativision/crt0.s @@ -0,0 +1,102 @@ +; +; Startup code for cc65 (CreatiVision version) +; + + .export _exit + .export __STARTUP__ : absolute = 1 ; Mark as startup + .import zerobss, copydata + .import initlib, donelib, callmain + .import __VECTORS_LOAD__, __VECTORS_RUN__, __VECTORS_SIZE__ + .import __ZP_LAST__, __STACKSIZE__, __RAM_START__ + + .include "zeropage.inc" + +; ------------------------------------------------------------------------ + +entry: + ; Init the CPU + sei + cld + + ; Copy the IRQ vectors + ldx #<__VECTORS_SIZE__ - 1 +: lda __VECTORS_LOAD__,x + sta __VECTORS_RUN__,x + dex + bpl :- + + ; Setup the CPU stack ptr + ldx #<__RAM_START__ - 1 + txs + + ; Start interrupts + cli + + ; Clear the BSS data + jsr zerobss + + ; Copy data from ROM to RAM + jsr copydata + + ; Setup the argument stack ptr + lda #<(__ZP_LAST__ + __STACKSIZE__) + ldx #>(__ZP_LAST__ + __STACKSIZE__) + sta sp + stx sp+1 + + ; Call module constructors + jsr initlib + + ; Call main() + jsr callmain + + ; Call module destructors. This is also the _exit entry. +_exit: jsr donelib + + ; TODO: Replace with some sort of reset +loop: jmp loop + +; ------------------------------------------------------------------------ +; Define the IRQ vectors. + +.segment "VECTORS" + +irq1: jmp $FF3F +irq2: jmp $FF52 + +; ------------------------------------------------------------------------ +; Define CART setup values for BIOS. + +.segment "SETUP" + + ; BIOS Jump Start + ; This is where the entry point of the program needs to be + .addr entry + .addr irq2 + + .res 4 + + ; VDP Setup + ; This sets to Graphics Mode 1 + .byte $00 ; Register 0 + .byte $C0 ; Register 1 16K RAM, Active Display, Mode 1 + .byte $04 ; Register 2 Name Table at $1000 - $12FF + .byte $60 ; Register 3 Colour Table at $1800 - $181F + .byte $00 ; Register 4 Pattern Table at $0000 - $07FF + .byte $10 ; Register 5 Sprite Attribute at $0800 - $087F + .byte $01 ; Register 6 Sprite Pattern + .byte $F1 ; Register 7 Text colour Foreground / background + + .res 4 + + ; BIOS Vector after NMI or RESET + ; Keeping with retail cartridges, we jump back to BIOS ROM and have it + ; setup zeropage etc, and show the Creativision logo and copyright. + .addr $F808 + + ; BIOS Short Interrupt Handler + ; Vectored from BIOS ROM:FE2C. This should contain a pointer to the user's + ; BIOS interrupt handler. + .addr irq1 + +; ------------------------------------------------------------------------ diff --git a/src/ca65/main.c b/src/ca65/main.c index 0016c46f3..b25d5ad9f 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -251,10 +251,6 @@ static void SetSys (const char* Sys) CBMSystem ("__PET__"); break; - case TGT_BBC: - NewSymbol ("__BBC__", 1); - break; - case TGT_APPLE2: NewSymbol ("__APPLE2__", 1); break; @@ -274,31 +270,41 @@ static void SetSys (const char* Sys) NewSymbol ("__GEOS_CBM__", 1); break; + case TGT_ATMOS: + NewSymbol ("__ATMOS__", 1); + break; + + case TGT_BBC: + NewSymbol ("__BBC__", 1); + break; + + case TGT_CREATIVISION: + NewSymbol ("__CREATIVISION__", 1); + break; + case TGT_GEOS_APPLE: NewSymbol ("__GEOS__", 1); NewSymbol ("__GEOS_APPLE__", 1); break; + case TGT_GEOS_CBM: + /* Do not handle as a CBM system */ + NewSymbol ("__GEOS__", 1); + NewSymbol ("__GEOS_CBM__", 1); + break; + case TGT_LUNIX: NewSymbol ("__LUNIX__", 1); break; - case TGT_ATMOS: - NewSymbol ("__ATMOS__", 1); + case TGT_LYNX: + NewSymbol ("__LYNX__", 1); break; case TGT_NES: NewSymbol ("__NES__", 1); break; - case TGT_SUPERVISION: - NewSymbol ("__SUPERVISION__", 1); - break; - - case TGT_LYNX: - NewSymbol ("__LYNX__", 1); - break; - case TGT_SIM6502: NewSymbol ("__SIM6502__", 1); break; @@ -315,6 +321,10 @@ static void SetSys (const char* Sys) NewSymbol ("__PCE__", 1); break; + case TGT_SUPERVISION: + NewSymbol ("__SUPERVISION__", 1); + break; + default: AbEnd ("Invalid target name: `%s'", Sys); diff --git a/src/cc65/main.c b/src/cc65/main.c index abe2af56e..c4a5c3788 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -207,10 +207,6 @@ static void SetSys (const char* Sys) cbmsys ("__PET__"); break; - case TGT_BBC: - DefineNumericMacro ("__BBC__", 1); - break; - case TGT_APPLE2: DefineNumericMacro ("__APPLE2__", 1); break; @@ -230,31 +226,41 @@ static void SetSys (const char* Sys) DefineNumericMacro ("__GEOS_CBM__", 1); break; + case TGT_ATMOS: + DefineNumericMacro ("__ATMOS__", 1); + break; + + case TGT_BBC: + DefineNumericMacro ("__BBC__", 1); + break; + + case TGT_CREATIVISION: + DefineNumericMacro ("__CREATIVISION__", 1); + break; + case TGT_GEOS_APPLE: DefineNumericMacro ("__GEOS__", 1); DefineNumericMacro ("__GEOS_APPLE__", 1); break; + case TGT_GEOS_CBM: + /* Do not handle as a CBM system */ + DefineNumericMacro ("__GEOS__", 1); + DefineNumericMacro ("__GEOS_CBM__", 1); + break; + case TGT_LUNIX: DefineNumericMacro ("__LUNIX__", 1); break; - case TGT_ATMOS: - DefineNumericMacro ("__ATMOS__", 1); + case TGT_LYNX: + DefineNumericMacro ("__LYNX__", 1); break; case TGT_NES: DefineNumericMacro ("__NES__", 1); break; - case TGT_SUPERVISION: - DefineNumericMacro ("__SUPERVISION__", 1); - break; - - case TGT_LYNX: - DefineNumericMacro ("__LYNX__", 1); - break; - case TGT_SIM6502: DefineNumericMacro ("__SIM6502__", 1); break; @@ -271,6 +277,10 @@ static void SetSys (const char* Sys) DefineNumericMacro ("__PCE__", 1); break; + case TGT_SUPERVISION: + DefineNumericMacro ("__SUPERVISION__", 1); + break; + default: AbEnd ("Unknown target system type %d", Target); } diff --git a/src/common/target.c b/src/common/target.c index e89010123..cc5d41206 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -134,7 +134,7 @@ static const unsigned char CTPET[256] = { /* One entry in the target map */ typedef struct TargetEntry TargetEntry; struct TargetEntry { - char Name[12]; /* Target name */ + char Name[13]; /* Target name */ target_t Id; /* Target id */ }; @@ -154,6 +154,7 @@ static const TargetEntry TargetMap[] = { { "c64", TGT_C64 }, { "cbm510", TGT_CBM510 }, { "cbm610", TGT_CBM610 }, + { "creativision", TGT_CREATIVISION}, { "gamate", TGT_GAMATE }, { "geos", TGT_GEOS_CBM }, { "geos-apple", TGT_GEOS_APPLE }, @@ -192,20 +193,21 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "cbm610", CPU_6502, BINFMT_BINARY, CTPET }, { "osic1p", CPU_6502, BINFMT_BINARY, CTOSI }, { "pet", CPU_6502, BINFMT_BINARY, CTPET }, - { "bbc", CPU_6502, BINFMT_BINARY, CTNone }, { "apple2", CPU_6502, BINFMT_BINARY, CTNone }, { "apple2enh", CPU_65C02, BINFMT_BINARY, CTNone }, - { "geos-cbm", CPU_6502, BINFMT_BINARY, CTNone }, - { "geos-apple", CPU_65C02, BINFMT_BINARY, CTNone }, - { "lunix", CPU_6502, BINFMT_O65, CTNone }, { "atmos", CPU_6502, BINFMT_BINARY, CTNone }, - { "nes", CPU_6502, BINFMT_BINARY, CTNone }, - { "supervision", CPU_65SC02, BINFMT_BINARY, CTNone }, + { "bbc", CPU_6502, BINFMT_BINARY, CTNone }, + { "creativision", CPU_6502, BINFMT_BINARY, CTNone }, + { "geos-apple", CPU_65C02, BINFMT_BINARY, CTNone }, + { "geos-cbm", CPU_6502, BINFMT_BINARY, CTNone }, + { "lunix", CPU_6502, BINFMT_O65, CTNone }, { "lynx", CPU_65C02, BINFMT_BINARY, CTNone }, + { "nes", CPU_6502, BINFMT_BINARY, CTNone }, { "sim6502", CPU_6502, BINFMT_BINARY, CTNone }, { "sim65c02", CPU_65C02, BINFMT_BINARY, CTNone }, { "pce", CPU_HUC6280, BINFMT_BINARY, CTNone }, { "gamate", CPU_6502, BINFMT_BINARY, CTNone }, + { "supervision", CPU_65SC02, BINFMT_BINARY, CTNone }, }; /* Target system */ diff --git a/src/common/target.h b/src/common/target.h index 6366b725f..c266a4408 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -66,27 +66,28 @@ typedef enum { TGT_CBM610, TGT_OSIC1P, TGT_PET, - TGT_BBC, TGT_APPLE2, TGT_APPLE2ENH, - TGT_GEOS_CBM, - TGT_GEOS_APPLE, - TGT_LUNIX, TGT_ATMOS, - TGT_NES, - TGT_SUPERVISION, + TGT_BBC, + TGT_CREATIVISION, + TGT_GEOS_APPLE, + TGT_GEOS_CBM, + TGT_LUNIX, TGT_LYNX, + TGT_NES, TGT_SIM6502, TGT_SIM65C02, TGT_PCENGINE, TGT_GAMATE, + TGT_SUPERVISION, TGT_COUNT /* Number of target systems */ } target_t; /* Collection of target properties */ typedef struct TargetProperties TargetProperties; struct TargetProperties { - const char Name[12]; /* Name of the target */ + const char Name[13]; /* Name of the target */ cpu_t DefaultCPU; /* Default CPU for this target */ unsigned char BinFmt; /* Default binary format for this target */ const unsigned char* CharMap; /* Character translation table */ From 0dc85268c4c4c4651899b6211984b07f8b25723c Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 28 Feb 2016 19:11:04 +0100 Subject: [PATCH 0007/2161] fix merge fxxxup --- src/ca65/main.c | 6 ------ src/cc65/main.c | 6 ------ 2 files changed, 12 deletions(-) diff --git a/src/ca65/main.c b/src/ca65/main.c index b25d5ad9f..49e7a1fb5 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -287,12 +287,6 @@ static void SetSys (const char* Sys) NewSymbol ("__GEOS_APPLE__", 1); break; - case TGT_GEOS_CBM: - /* Do not handle as a CBM system */ - NewSymbol ("__GEOS__", 1); - NewSymbol ("__GEOS_CBM__", 1); - break; - case TGT_LUNIX: NewSymbol ("__LUNIX__", 1); break; diff --git a/src/cc65/main.c b/src/cc65/main.c index c4a5c3788..d8b312fab 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -243,12 +243,6 @@ static void SetSys (const char* Sys) DefineNumericMacro ("__GEOS_APPLE__", 1); break; - case TGT_GEOS_CBM: - /* Do not handle as a CBM system */ - DefineNumericMacro ("__GEOS__", 1); - DefineNumericMacro ("__GEOS_CBM__", 1); - break; - case TGT_LUNIX: DefineNumericMacro ("__LUNIX__", 1); break; From 3d08abcfa802bb9862ed01427b37256bd7210663 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 28 Feb 2016 19:29:37 +0100 Subject: [PATCH 0008/2161] Load INITBSS segment from disk. Conceptually the INITBSS segment is not initialized in any way. Therefore it makes sense to not load it from disk. However the INIT segment has to be loaded from disk and therefore moved to its run location above the INITBSS segment. The necessary move routine increases runtime RAM usage :-( Therefore we now "unnecessarily" load the INITBSS segment from disk too meaning that the INIT segment is loaded at its run location. Therefore there's no need for the move routine anymore. After all we trade disk space for (runtime) RAM space - an easy decision ;-) Notes: - The code allowing to re-run a program without re-load present so far could not have worked as far as I can see as it only avoided to re-run the move routine but still tried to re-run the code in the INIT segment that was clobbered by zeroing the BSS. Therefore I removed the code in question altogether. I'm personally not into this "dirty re-run" but if someone wants to add an actually working solution I won't block that. - INITBSS is intentionally not just merged with the DATA segment as ROM-based targets can't reuse the INIT segment for the BSS and therefore have no reason to place the INIT segment above INITBSS. - Because ROM-based targets don't copy INITBSS from the ROM (like it is done with the DATA segment) all users of INITBSS _MUST_NOT_ presume INITBSS to be initialized with zeros! --- cfg/c64-overlay.cfg | 61 ++++++++++++++++++++-------------------- cfg/c64.cfg | 25 ++++++++-------- libsrc/c64/crt0.s | 39 ++++++------------------- libsrc/common/moveinit.s | 45 ----------------------------- 4 files changed, 51 insertions(+), 119 deletions(-) delete mode 100644 libsrc/common/moveinit.s diff --git a/cfg/c64-overlay.cfg b/cfg/c64-overlay.cfg index 1c3b19c09..522a6d1a6 100644 --- a/cfg/c64-overlay.cfg +++ b/cfg/c64-overlay.cfg @@ -15,8 +15,7 @@ MEMORY { 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 = __OVERLAYSTART__ - __STACKSIZE__ - __HEADER_LAST__; - MOVE: file = %O, start = __INITBSS_LOAD__, size = __HIMEM__ - __BSS_RUN__; - INIT: file = "", start = __BSS_RUN__, size = __HIMEM__ - __BSS_RUN__; + INIT: file = %O, start = __BSS_RUN__, size = __HIMEM__ - __BSS_RUN__; OVL1ADDR: file = "%O.1", start = __OVERLAYSTART__ - 2, size = $0002; OVL1: file = "%O.1", start = __OVERLAYSTART__, size = __OVERLAYSIZE__; OVL2ADDR: file = "%O.2", start = __OVERLAYSTART__ - 2, size = $0002; @@ -37,35 +36,35 @@ MEMORY { OVL9: file = "%O.9", start = __OVERLAYSTART__, size = __OVERLAYSIZE__; } 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; - INITBSS: load = MAIN, type = bss, define = yes; - BSS: load = MAIN, type = bss, define = yes; - INIT: load = MOVE, run = INIT, type = ro, define = yes; - OVL1ADDR: load = OVL1ADDR, type = ro; - OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; - OVL2ADDR: load = OVL2ADDR, type = ro; - OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes; - OVL3ADDR: load = OVL3ADDR, type = ro; - OVERLAY3: load = OVL3, type = ro, define = yes, optional = yes; - OVL4ADDR: load = OVL4ADDR, type = ro; - OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes; - OVL5ADDR: load = OVL5ADDR, type = ro; - OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes; - OVL6ADDR: load = OVL6ADDR, type = ro; - OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes; - OVL7ADDR: load = OVL7ADDR, type = ro; - OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes; - OVL8ADDR: load = OVL8ADDR, type = ro; - OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes; - OVL9ADDR: load = OVL9ADDR, type = ro; - OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes; + 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; + INITBSS: load = MAIN, type = rw; + BSS: load = MAIN, type = bss, define = yes; + INIT: load = INIT, type = ro; + OVL1ADDR: load = OVL1ADDR, type = ro; + OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; + OVL2ADDR: load = OVL2ADDR, type = ro; + OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes; + OVL3ADDR: load = OVL3ADDR, type = ro; + OVERLAY3: load = OVL3, type = ro, define = yes, optional = yes; + OVL4ADDR: load = OVL4ADDR, type = ro; + OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes; + OVL5ADDR: load = OVL5ADDR, type = ro; + OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes; + OVL6ADDR: load = OVL6ADDR, type = ro; + OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes; + OVL7ADDR: load = OVL7ADDR, type = ro; + OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes; + OVL8ADDR: load = OVL8ADDR, type = ro; + OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes; + OVL9ADDR: load = OVL9ADDR, type = ro; + OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/c64.cfg b/cfg/c64.cfg index 2a105c7f1..8ff7db03c 100644 --- a/cfg/c64.cfg +++ b/cfg/c64.cfg @@ -12,21 +12,20 @@ MEMORY { 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 = __HIMEM__ - __STACKSIZE__ - __HEADER_LAST__; - MOVE: file = %O, start = __INITBSS_LOAD__, size = __HIMEM__ - __BSS_RUN__; - INIT: file = "", start = __BSS_RUN__, size = __HIMEM__ - __BSS_RUN__; + INIT: file = %O, start = __BSS_RUN__, size = __HIMEM__ - __BSS_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; - INITBSS: load = MAIN, type = bss, define = yes; - BSS: load = MAIN, type = bss, define = yes; - INIT: load = MOVE, run = INIT, type = ro, define = yes; + 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; + INITBSS: load = MAIN, type = rw; + BSS: load = MAIN, type = bss, define = yes; + INIT: load = INIT, type = ro, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/libsrc/c64/crt0.s b/libsrc/c64/crt0.s index 78268422b..ea7867925 100644 --- a/libsrc/c64/crt0.s +++ b/libsrc/c64/crt0.s @@ -6,7 +6,7 @@ .export __STARTUP__ : absolute = 1 ; Mark as startup .import initlib, donelib - .import moveinit, zerobss, callmain + .import zerobss, callmain .import BSOUT .import __MAIN_START__, __MAIN_SIZE__ ; Linker generated .import __STACKSIZE__ ; from configure file @@ -23,11 +23,6 @@ Start: -; Switch to the second charset. - - lda #14 - jsr BSOUT - ; Switch off the BASIC ROM. lda $01 @@ -39,22 +34,10 @@ Start: tsx stx spsave ; Save the system stack ptr -; Allow some re-entrancy by skipping the next task if it already was done. -; This sometimes can let us rerun the program without reloading it. - - ldx move_init - beq L0 - -; Move the INIT segment from where it was loaded (over the bss segments) -; into where it must be run (over the BSS segment). - - jsr moveinit - dec move_init ; Set to false - ; Save space by putting some of the start-up code in the INIT segment, ; which can be re-used by the BSS segment, the heap and the C stack. -L0: jsr runinit + jsr init ; Clear the BSS data. @@ -98,7 +81,7 @@ L2: lda zpsave,x .segment "INIT" -runinit: +init: ; Save the zero-page locations that we need. @@ -115,6 +98,11 @@ L1: lda sp,x sta sp stx sp+1 ; Set argument stack ptr +; Switch to the second charset. + + lda #14 + jsr BSOUT + ; Call the module constructors. jmp initlib @@ -123,17 +111,8 @@ L1: lda sp,x ; ------------------------------------------------------------------------ ; Data -.data - -; These two variables were moved out of the BSS segment, and into DATA, because -; we need to use them before INIT is moved off of BSS, and before BSS is zeroed. +.segment "INITBSS" mmusave:.res 1 spsave: .res 1 - -move_init: - .byte 1 - -.segment "INITBSS" - zpsave: .res zpspace diff --git a/libsrc/common/moveinit.s b/libsrc/common/moveinit.s deleted file mode 100644 index 2b22be02d..000000000 --- a/libsrc/common/moveinit.s +++ /dev/null @@ -1,45 +0,0 @@ -; -; 2015-10-07, Greg King -; - - .export moveinit - - .import __INIT_LOAD__, __INIT_RUN__, __INIT_SIZE__ ; Linker-generated - - .macpack cpu - .macpack generic - - -; Put this in the DATA segment because it is self-modifying code. - -.data - -; Move the INIT segment from where it was loaded (over the bss segments) -; into where it must be run (over the BSS segment). The two areas might overlap; -; and, the segment is moved upwards. Therefore, this code starts at the highest -; address, and decrements to the lowest address. The low bytes of the starting -; pointers are not sums. The high bytes are sums; but, they do not include the -; carry. Both the low-byte sums and the carries will be done when the pointers -; are indexed by the .Y register. - -moveinit: - -; First, move the last, partial page. -; Then, move all of the full pages. - - ldy #<__INIT_SIZE__ ; size of partial page - ldx #>__INIT_SIZE__ + (<__INIT_SIZE__ <> 0) ; number of pages, including partial - -L1: dey -init_load: - lda __INIT_LOAD__ + (__INIT_SIZE__ & $FF00) - $0100 * (<__INIT_SIZE__ = 0),y -init_run: - sta __INIT_RUN__ + (__INIT_SIZE__ & $FF00) - $0100 * (<__INIT_SIZE__ = 0),y - tya - bnz L1 ; page not finished - - dec init_load+2 - dec init_run+2 - dex - bnz L1 ; move next page - rts From f328532030db1f4e2d97ebde6607dee99e6cde0b Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 28 Feb 2016 20:12:28 +0100 Subject: [PATCH 0009/2161] updated docs with recently added extended memory drivers --- doc/c128.sgml | 8 ++++++++ doc/c64.sgml | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/doc/c128.sgml b/doc/c128.sgml index 4154c0a8d..2468b17e6 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -191,11 +191,19 @@ missing on VDC, and are translated to the two colors missing from the VIC palett <descrip> + <tag><tt/c128-efnram.emd (c128_georam_emd)/</tag> + Extended memory driver for the C128 External Function RAM. + Written and contributed by Marco van den Heuvel. + <tag><tt/c128-georam.emd (c128_georam_emd)/</tag> A driver for the GeoRam cartridge. The driver will always assume 2048 pages of 256 bytes each. There are no checks, so if your program knows better, just go ahead. + <tag><tt/c128-ifnram.emd (c128_georam_emd)/</tag> + Extended memory driver for the C128 Internal Function RAM. + Written and contributed by Marco van den Heuvel. + <tag><tt/c128-ram.emd (c128_ram_emd)/</tag> An extended memory driver for the RAM in page 1. The common memory area is excluded, so this driver supports 251 pages of 256 bytes each. diff --git a/doc/c64.sgml b/doc/c64.sgml index 8767d212d..4bf43453d 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -257,6 +257,10 @@ Note that the graphics drivers are incompatible with the <descrip> + <tag><tt/c64-65816.emd (c64_65816_emd)/</tag> + Extended memory driver for 65816 (eg SCPU) based extra RAM. + Written and contributed by Marco van den Heuvel. + <tag><tt/c64-c256k.emd (c64_c256k_emd)/</tag> A driver for the C64 256K memory expansion. This driver offers 768 pages of 256 bytes each. Written and contributed by Marco van den Heuvel. From 7d2969d5acf703b07a7c5e779d298d496d8192b9 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 28 Feb 2016 21:39:49 +0100 Subject: [PATCH 0010/2161] fixed copypaste errors --- doc/c128.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/c128.sgml b/doc/c128.sgml index 2468b17e6..a98b04f49 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -191,7 +191,7 @@ missing on VDC, and are translated to the two colors missing from the VIC palett <descrip> - <tag><tt/c128-efnram.emd (c128_georam_emd)/</tag> + <tag><tt/c128-efnram.emd (c128_efnram_emd)/</tag> Extended memory driver for the C128 External Function RAM. Written and contributed by Marco van den Heuvel. @@ -200,7 +200,7 @@ missing on VDC, and are translated to the two colors missing from the VIC palett of 256 bytes each. There are no checks, so if your program knows better, just go ahead. - <tag><tt/c128-ifnram.emd (c128_georam_emd)/</tag> + <tag><tt/c128-ifnram.emd (c128_ifnram_emd)/</tag> Extended memory driver for the C128 Internal Function RAM. Written and contributed by Marco van den Heuvel. From 85760e0c531d127f2a52e1d87a6f02214c98a5fd Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 28 Feb 2016 22:13:05 +0100 Subject: [PATCH 0011/2161] initial import from old sources --- libsrc/c128/kbrepeat.s | 22 ++++++++++++++++++++++ libsrc/c64/kbrepeat.s | 22 ++++++++++++++++++++++ libsrc/pet/kbrepeat.s | 22 ++++++++++++++++++++++ libsrc/plus4/kbrepeat.s | 22 ++++++++++++++++++++++ libsrc/vic20/kbrepeat.s | 22 ++++++++++++++++++++++ 5 files changed, 110 insertions(+) create mode 100644 libsrc/c128/kbrepeat.s create mode 100644 libsrc/c64/kbrepeat.s create mode 100644 libsrc/pet/kbrepeat.s create mode 100644 libsrc/plus4/kbrepeat.s create mode 100644 libsrc/vic20/kbrepeat.s diff --git a/libsrc/c128/kbrepeat.s b/libsrc/c128/kbrepeat.s new file mode 100644 index 000000000..f515e4ca3 --- /dev/null +++ b/libsrc/c128/kbrepeat.s @@ -0,0 +1,22 @@ + + .export _kbrepeat, _kbrepeatdelay, _kbrepeatrate + + .include "c128/c128.inc" + +_kbrepeat: + ldx KBDREPEAT ; get old value + sta KBDREPEAT ; store new value + txa ; return old value + rts + +_kbrepeatdelay: + ldx KBDREPEATDELAY ; get old value + sta KBDREPEATDELAY ; store new value + txa ; return old value + rts + +_kbrepeatrate: + ldx KBDREPEATRATE ; get old value + sta KBDREPEATRATE ; store new value + txa ; return old value + rts diff --git a/libsrc/c64/kbrepeat.s b/libsrc/c64/kbrepeat.s new file mode 100644 index 000000000..b6c33250b --- /dev/null +++ b/libsrc/c64/kbrepeat.s @@ -0,0 +1,22 @@ + + .export _kbrepeat, _kbrepeatdelay, _kbrepeatrate + + .include "c64/c64.inc" + +_kbrepeat: + ldx KBDREPEAT ; get old value + sta KBDREPEAT ; store new value + txa ; return old value + rts + +_kbrepeatdelay: + ldx KBDREPEATDELAY ; get old value + sta KBDREPEATDELAY ; store new value + txa ; return old value + rts + +_kbrepeatrate: + ldx KBDREPEATRATE ; get old value + sta KBDREPEATRATE ; store new value + txa ; return old value + rts diff --git a/libsrc/pet/kbrepeat.s b/libsrc/pet/kbrepeat.s new file mode 100644 index 000000000..44d60575f --- /dev/null +++ b/libsrc/pet/kbrepeat.s @@ -0,0 +1,22 @@ + + .export _kbrepeat, _kbrepeatdelay, _kbrepeatrate + + .include "pet/pet.inc" + +_kbrepeat: + ldx KBDREPEAT ; get old value + sta KBDREPEAT ; store new value + txa ; return old value + rts + +_kbrepeatdelay: + ldx KBDREPEATDELAY ; get old value + sta KBDREPEATDELAY ; store new value + txa ; return old value + rts + +_kbrepeatrate: + ldx KBDREPEATRATE ; get old value + sta KBDREPEATRATE ; store new value + txa ; return old value + rts diff --git a/libsrc/plus4/kbrepeat.s b/libsrc/plus4/kbrepeat.s new file mode 100644 index 000000000..8636d0e33 --- /dev/null +++ b/libsrc/plus4/kbrepeat.s @@ -0,0 +1,22 @@ + + .export _kbrepeat, _kbrepeatdelay, _kbrepeatrate + + .include "plus4/plus4.inc" + +_kbrepeat: + ldx KBDREPEAT ; get old value + sta KBDREPEAT ; store new value + txa ; return old value + rts + +_kbrepeatdelay: + ldx KBDREPEATDELAY ; get old value + sta KBDREPEATDELAY ; store new value + txa ; return old value + rts + +_kbrepeatrate: + ldx KBDREPEATRATE ; get old value + sta KBDREPEATRATE ; store new value + txa ; return old value + rts diff --git a/libsrc/vic20/kbrepeat.s b/libsrc/vic20/kbrepeat.s new file mode 100644 index 000000000..5a4ad96f6 --- /dev/null +++ b/libsrc/vic20/kbrepeat.s @@ -0,0 +1,22 @@ + + .export _kbrepeat, _kbrepeatdelay, _kbrepeatrate + + .include "vic20/vic20.inc" + +_kbrepeat: + ldx KBDREPEAT ; get old value + sta KBDREPEAT ; store new value + txa ; return old value + rts + +_kbrepeatdelay: + ldx KBDREPEATDELAY ; get old value + sta KBDREPEATDELAY ; store new value + txa ; return old value + rts + +_kbrepeatrate: + ldx KBDREPEATRATE ; get old value + sta KBDREPEATRATE ; store new value + txa ; return old value + rts From eb96a90e5fe642102b5b81dc1e031641ed362c29 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 28 Feb 2016 22:35:46 +0100 Subject: [PATCH 0012/2161] initial import from old sources --- libsrc/c128/waitvblank.s | 20 ++++++++++++++++++++ libsrc/c64/waitvblank.s | 20 ++++++++++++++++++++ libsrc/cbm510/waitvblank.s | 37 +++++++++++++++++++++++++++++++++++++ libsrc/vic20/waitvblank.s | 16 ++++++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 libsrc/c128/waitvblank.s create mode 100644 libsrc/c64/waitvblank.s create mode 100644 libsrc/cbm510/waitvblank.s create mode 100644 libsrc/vic20/waitvblank.s diff --git a/libsrc/c128/waitvblank.s b/libsrc/c128/waitvblank.s new file mode 100644 index 000000000..a3904d858 --- /dev/null +++ b/libsrc/c128/waitvblank.s @@ -0,0 +1,20 @@ + + .export _waitvblank + + .include "c128/c128.inc" + +_waitvblank: + lda PALFLAG + beq @ntsc + ldx #(312-24)-256 + .byte $2c +@ntsc: + ldx #(262-4)-256 +@l1: + lda VIC_CTRL1 + and #$80 + beq @l1 +@l2: + cpx VIC_HLINE + bcs @l2 + rts diff --git a/libsrc/c64/waitvblank.s b/libsrc/c64/waitvblank.s new file mode 100644 index 000000000..09570f873 --- /dev/null +++ b/libsrc/c64/waitvblank.s @@ -0,0 +1,20 @@ + + .export _waitvblank + + .include "c64/c64.inc" + +_waitvblank: + lda PALFLAG + beq @ntsc + ldx #(312-24)-256 + .byte $2c +@ntsc: + ldx #(262-4)-256 +@l1: + lda VIC_CTRL1 + and #$80 + beq @l1 +@l2: + cpx VIC_HLINE + bcs @l2 + rts diff --git a/libsrc/cbm510/waitvblank.s b/libsrc/cbm510/waitvblank.s new file mode 100644 index 000000000..30cbf072f --- /dev/null +++ b/libsrc/cbm510/waitvblank.s @@ -0,0 +1,37 @@ + + .export _waitvblank + .import PALFLAG + .import sys_bank, restore_bank + + .importzp vic + + .include "cbm510/cbm510.inc" + +_waitvblank: + rts ; FIXME + + jsr sys_bank ; Switch to the system bank + + lda PALFLAG + beq ntsc + ldx #(312-24)-256 + .byte $2c +ntsc: + ldx #(262-2)-256 + + sei + ldy #VIC_CTRL1 +l1: + lda (vic),y + and #$80 + beq l1 + +;?!? +; ldy #VIC_HLINE +; txa +;l2: +; cmp (vic),y +; bcs l2 + + cli + jmp restore_bank diff --git a/libsrc/vic20/waitvblank.s b/libsrc/vic20/waitvblank.s new file mode 100644 index 000000000..b99c74bed --- /dev/null +++ b/libsrc/vic20/waitvblank.s @@ -0,0 +1,16 @@ + .export _waitvblank + + .include "vic20/vic20.inc" + +_waitvblank: + lda PALFLAG + beq @ntsc + ldx #(312-8)/2 + .byte $2c +@ntsc: + ldx #(262-8)/2 +@l2: + cpx VIC_HLINE + bcs @l2 + rts + From 18dec35312ebdd5dc120abeff039d032e316e256 Mon Sep 17 00:00:00 2001 From: Brad Smith <rainwarrior@gmail.com> Date: Wed, 2 Mar 2016 01:58:44 -0500 Subject: [PATCH 0013/2161] cc65-intern sgml fixes --- doc/cc65-intern.sgml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/cc65-intern.sgml b/doc/cc65-intern.sgml index 0bcb51cba..bfbe4d78e 100644 --- a/doc/cc65-intern.sgml +++ b/doc/cc65-intern.sgml @@ -89,9 +89,9 @@ void foo(unsigned bar, unsigned char baz); lda (sp),y ; Low byte now in A </verb></tscreen> -<sect1>Epilogue, after the functiona call<p> +<sect1>Epilogue, after the function call<p> -<sect2>Return requirements</p> +<sect2>Return requirements<p> If the function has a return value, it will appear in the <tt>A/X/sreg</tt> registers. @@ -114,7 +114,7 @@ number of bytes pushed to the stack on entry, which may be added to <tt/sp/ to r The internal pseudo-register <tt/regbank/ must not be changed by the function. -<sect2>Clobbered state</p> +<sect2>Clobbered state<p> The <tt/Y/ register may be clobbered by the function. The compiler will not depend on its state after a function call. @@ -126,6 +126,7 @@ Many of the internal pseudo-registers used by cc65 are available for free use by any function called by C, and do not need to be preserved. Note that if another C function is called from your assembly function, it may clobber any of these itself: + <itemize> <item><tt>tmp1 .. tmp4</tt><p> <item><tt>ptr1 .. ptr4</tt><p> From 85a58453cb881d92ea51aa927981eae1c4137c9d Mon Sep 17 00:00:00 2001 From: Brad Smith <rainwarrior@gmail.com> Date: Wed, 2 Mar 2016 02:03:23 -0500 Subject: [PATCH 0014/2161] cc65-intern adjusting mailing address --- doc/cc65-intern.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/cc65-intern.sgml b/doc/cc65-intern.sgml index bfbe4d78e..faa2d5609 100644 --- a/doc/cc65-intern.sgml +++ b/doc/cc65-intern.sgml @@ -2,7 +2,7 @@ <article> <title>cc65 internals -<author><url url="mailto:brad@rainwarrior.ca" name="Brad Smith"> +<author><url url="mailto:bbbradsmith@users.noreply.github.com" name="Brad Smith"> <date>2016-02-27 <abstract> From 97e6a8c5698cad2a62f09b2664ea74e58830b604 Mon Sep 17 00:00:00 2001 From: Brad Smith <rainwarrior@gmail.com> Date: Wed, 2 Mar 2016 21:01:46 -0500 Subject: [PATCH 0015/2161] cc65-intern update minor change notes from greg-king5 --- doc/cc65-intern.sgml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/cc65-intern.sgml b/doc/cc65-intern.sgml index faa2d5609..231c04544 100644 --- a/doc/cc65-intern.sgml +++ b/doc/cc65-intern.sgml @@ -27,7 +27,7 @@ There are two calling conventions used in cc65: <item><tt/cdecl/ - passes all parameters on the C-stack. <p> <item><tt/fastcall/ - passes the rightmost parameter in - registers <tt>A/X/sreg</tt> an all others on the C-stack. + registers <tt>A/X/sreg</tt> and all others on the C-stack. <p> </itemize> @@ -52,7 +52,7 @@ If the function is declared as fastcall, the rightmost argument will be loaded i the <tt>A/X/sreg</tt> registers: <itemize> - <item><tt/A/ - 8-bit parameter, or low byte of larger tyes<p> + <item><tt/A/ - 8-bit parameter, or low byte of larger types<p> <item><tt/X/ - 16-bit high byte, or second byte of 32-bits<p> <item><tt/sreg/ - Zeropage pseudo-register including high 2 bytes of 32-bit parameter<p> </itemize> @@ -68,7 +68,7 @@ the <tt/Y/ register will contain the number of bytes pushed to the stack for thi Example: <tscreen><verb> // C prototype -void foo(unsigned bar, unsigned char baz); +void cdecl foo(unsigned bar, unsigned char baz); ; C-stack layout within the function: ; From 419eb700b5cd730ecf425ed8a597e9cf41ad7208 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 6 Mar 2016 21:26:22 +0100 Subject: [PATCH 0016/2161] Renamed INITBSS to INIT and INIT to ONCE. The way we want to use the INITBSS segment - and especially the fact that it won't have the type bss on all ROM based targets - means that the name INITBSS is misleading. After all INIT is the best name from my perspective as it serves several purposes and therefore needs a rather generic name. Unfortunately this means that the current INIT segment needs to be renamed too. Looking for a short (ideally 4 letter) name I came up with ONCE as it contains all code (and data) accessed only once during initialization. --- cfg/apple2-overlay.cfg | 8 ++-- cfg/apple2-system.cfg | 8 ++-- cfg/apple2.cfg | 8 ++-- cfg/apple2enh-overlay.cfg | 8 ++-- cfg/apple2enh-system.cfg | 8 ++-- cfg/apple2enh.cfg | 8 ++-- cfg/atari-cart.cfg | 24 +++++------ cfg/atari-cassette.cfg | 24 +++++------ cfg/atari-overlay.cfg | 10 ++--- cfg/atari.cfg | 10 ++--- cfg/atari5200.cfg | 8 ++-- cfg/atarixl-largehimem.cfg | 11 ++--- cfg/atarixl-overlay.cfg | 11 ++--- cfg/atarixl.cfg | 11 ++--- cfg/atmos.cfg | 4 +- cfg/bbc.cfg | 6 +-- cfg/c128-overlay.cfg | 8 ++-- cfg/c128.cfg | 8 ++-- cfg/c16.cfg | 8 ++-- cfg/c64-overlay.cfg | 6 +-- cfg/c64.cfg | 6 +-- cfg/cbm510.cfg | 6 +-- cfg/cbm610.cfg | 6 +-- cfg/gamate.cfg | 64 ++++++++++++++++------------ cfg/geos-apple.cfg | 4 +- cfg/geos-cbm.cfg | 4 +- cfg/lunix.cfg | 4 +- cfg/lynx-bll.cfg | 10 ++--- cfg/lynx-coll.cfg | 10 ++--- cfg/lynx-uploader.cfg | 10 ++--- cfg/lynx.cfg | 10 ++--- cfg/module.cfg | 2 +- cfg/nes.cfg | 6 +-- cfg/none.cfg | 6 +-- cfg/osic1p-asm.cfg | 4 +- cfg/osic1p.cfg | 8 ++-- cfg/pce.cfg | 38 ++++++++--------- cfg/pet.cfg | 8 ++-- cfg/plus4.cfg | 8 ++-- cfg/sim6502.cfg | 26 +++++------ cfg/sim65c02.cfg | 26 +++++------ cfg/supervision-128k.cfg | 2 +- cfg/supervision-16k.cfg | 6 +-- cfg/supervision-64k.cfg | 2 +- cfg/supervision.cfg | 6 +-- cfg/vic20-32k.cfg | 6 +-- cfg/vic20.cfg | 8 ++-- doc/atari.sgml | 14 +++--- doc/customizing.sgml | 20 ++++----- doc/ld65.sgml | 6 +-- libsrc/apple2/cputc.s | 2 +- libsrc/apple2/crt0.s | 30 ++++++------- libsrc/apple2/dosdetect.s | 2 +- libsrc/apple2/extra/iobuf-0800.s | 2 +- libsrc/apple2/get_ostype.s | 2 +- libsrc/apple2/irq.s | 2 +- libsrc/apple2/mainargs.s | 4 +- libsrc/apple2/open.s | 2 +- libsrc/apple2/read.s | 2 +- libsrc/apple2/reboot.s | 2 +- libsrc/atari/casinit.s | 2 +- libsrc/atari/dosdetect.s | 2 +- libsrc/atari/getargs.s | 2 +- libsrc/atari/irq.s | 2 +- libsrc/atari/mcbpm.s | 2 +- libsrc/atari/shadow_ram_handlers.s | 2 +- libsrc/atari5200/conioscreen.s | 2 +- libsrc/atari5200/irq.s | 2 +- libsrc/atmos/capslock.s | 2 +- libsrc/atmos/cgetc.s | 4 +- libsrc/atmos/irq.s | 2 +- libsrc/atmos/mainargs.s | 4 +- libsrc/atmos/read.s | 2 +- libsrc/c128/cgetc.s | 2 +- libsrc/c128/crt0.s | 2 +- libsrc/c128/irq.s | 2 +- libsrc/c128/mainargs.s | 6 +-- libsrc/c128/mcbdefault.s | 2 +- libsrc/c128/systime.s | 2 +- libsrc/c16/cgetc.s | 2 +- libsrc/c16/crt0.s | 2 +- libsrc/c16/irq.s | 2 +- libsrc/c16/mainargs.s | 6 +-- libsrc/c64/crt0.s | 6 +-- libsrc/c64/irq.s | 2 +- libsrc/c64/mainargs.s | 6 +-- libsrc/c64/mcbdefault.s | 2 +- libsrc/c64/soft80_charset.s | 2 +- libsrc/c64/soft80_conio.s | 4 +- libsrc/c64/soft80mono_conio.s | 4 +- libsrc/c64/systime.s | 2 +- libsrc/cbm/filevars.s | 4 +- libsrc/cbm/mcbpointercolor.s | 2 +- libsrc/cbm/mcbpointershape.s | 2 +- libsrc/cbm/read.s | 2 +- libsrc/cbm/write.s | 2 +- libsrc/cbm510/mainargs.s | 6 +-- libsrc/cbm510/mcbdefault.s | 2 +- libsrc/cbm610/mainargs.s | 6 +-- libsrc/common/_cwd.s | 2 +- libsrc/common/_heap.s | 2 +- libsrc/gamate/clock.s | 2 +- libsrc/gamate/conio.s | 2 +- libsrc/gamate/irq.s | 2 +- libsrc/gamate/nmi.s | 2 +- libsrc/geos-common/conio/_scrsize.s | 2 +- libsrc/geos-common/system/mainargs.s | 2 +- libsrc/lynx/clock.s | 2 +- libsrc/lynx/defdir.s | 13 +++--- libsrc/lynx/irq.s | 2 +- libsrc/lynx/mainargs.s | 4 +- libsrc/nes/cputc.s | 4 +- libsrc/nes/irq.s | 2 +- libsrc/nes/mainargs.s | 4 +- libsrc/osic1p/cgetc.s | 2 +- libsrc/pce/clock.s | 2 +- libsrc/pce/conio.s | 2 +- libsrc/pce/irq.s | 2 +- libsrc/pce/psg.s | 2 +- libsrc/pce/vce.s | 2 +- libsrc/pet/crt0.s | 2 +- libsrc/pet/irq.s | 2 +- libsrc/pet/mainargs.s | 6 +-- libsrc/plus4/cgetc.s | 2 +- libsrc/plus4/crt0.s | 2 +- libsrc/plus4/mainargs.s | 6 +-- libsrc/runtime/condes.s | 2 +- libsrc/runtime/stkchk.s | 4 +- libsrc/sim6502/mainargs.s | 2 +- libsrc/vic20/crt0.s | 2 +- libsrc/vic20/irq.s | 2 +- libsrc/vic20/mainargs.s | 6 +-- 132 files changed, 402 insertions(+), 390 deletions(-) diff --git a/cfg/apple2-overlay.cfg b/cfg/apple2-overlay.cfg index 244e4582f..ef9103b49 100644 --- a/cfg/apple2-overlay.cfg +++ b/cfg/apple2-overlay.cfg @@ -18,7 +18,7 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay __LOADADDR__: type = weak, value = __STARTUP_RUN__; - __LOADSIZE__: type = weak, value = __INITBSS_RUN__ - __STARTUP_RUN__ + + __LOADSIZE__: type = weak, value = __INIT_RUN__ - __STARTUP_RUN__ + __MOVE_LAST__ - __MOVE_START__; } MEMORY { @@ -45,9 +45,9 @@ SEGMENTS { CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss, define = yes; + INIT: load = RAM, type = bss, define = yes; BSS: load = RAM, type = bss, define = yes; - INIT: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; + ONCE: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; LC: load = MOVE, run = LC, type = ro, optional = yes; OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes; @@ -63,7 +63,7 @@ FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/apple2-system.cfg b/cfg/apple2-system.cfg index f07208e45..52cad960f 100644 --- a/cfg/apple2-system.cfg +++ b/cfg/apple2-system.cfg @@ -5,7 +5,7 @@ SYMBOLS { __LCSIZE__: type = weak, value = $0C00; # Rest of bank two __STACKSIZE__: type = weak, value = $0800; # 2k stack __LOADADDR__: type = weak, value = __STARTUP_RUN__; - __LOADSIZE__: type = weak, value = __INITBSS_RUN__ - __STARTUP_RUN__ + + __LOADSIZE__: type = weak, value = __INIT_RUN__ - __STARTUP_RUN__ + __MOVE_LAST__ - __MOVE_START__; } MEMORY { @@ -21,16 +21,16 @@ SEGMENTS { CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss, define = yes; + INIT: load = RAM, type = bss, define = yes; BSS: load = RAM, type = bss, define = yes; - INIT: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; + ONCE: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; LC: load = MOVE, run = LC, type = ro, optional = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/apple2.cfg b/cfg/apple2.cfg index 27eb706c4..8e63090f5 100644 --- a/cfg/apple2.cfg +++ b/cfg/apple2.cfg @@ -10,7 +10,7 @@ SYMBOLS { __LCSIZE__: type = weak, value = $0C00; # Rest of bank two __STACKSIZE__: type = weak, value = $0800; # 2k stack __LOADADDR__: type = weak, value = __STARTUP_RUN__; - __LOADSIZE__: type = weak, value = __INITBSS_RUN__ - __STARTUP_RUN__ + + __LOADSIZE__: type = weak, value = __INIT_RUN__ - __STARTUP_RUN__ + __MOVE_LAST__ - __MOVE_START__; } MEMORY { @@ -28,16 +28,16 @@ SEGMENTS { CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss, define = yes; + INIT: load = RAM, type = bss, define = yes; BSS: load = RAM, type = bss, define = yes; - INIT: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; + ONCE: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; LC: load = MOVE, run = LC, type = ro, optional = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/apple2enh-overlay.cfg b/cfg/apple2enh-overlay.cfg index 244e4582f..ef9103b49 100644 --- a/cfg/apple2enh-overlay.cfg +++ b/cfg/apple2enh-overlay.cfg @@ -18,7 +18,7 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay __LOADADDR__: type = weak, value = __STARTUP_RUN__; - __LOADSIZE__: type = weak, value = __INITBSS_RUN__ - __STARTUP_RUN__ + + __LOADSIZE__: type = weak, value = __INIT_RUN__ - __STARTUP_RUN__ + __MOVE_LAST__ - __MOVE_START__; } MEMORY { @@ -45,9 +45,9 @@ SEGMENTS { CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss, define = yes; + INIT: load = RAM, type = bss, define = yes; BSS: load = RAM, type = bss, define = yes; - INIT: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; + ONCE: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; LC: load = MOVE, run = LC, type = ro, optional = yes; OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes; @@ -63,7 +63,7 @@ FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/apple2enh-system.cfg b/cfg/apple2enh-system.cfg index f07208e45..52cad960f 100644 --- a/cfg/apple2enh-system.cfg +++ b/cfg/apple2enh-system.cfg @@ -5,7 +5,7 @@ SYMBOLS { __LCSIZE__: type = weak, value = $0C00; # Rest of bank two __STACKSIZE__: type = weak, value = $0800; # 2k stack __LOADADDR__: type = weak, value = __STARTUP_RUN__; - __LOADSIZE__: type = weak, value = __INITBSS_RUN__ - __STARTUP_RUN__ + + __LOADSIZE__: type = weak, value = __INIT_RUN__ - __STARTUP_RUN__ + __MOVE_LAST__ - __MOVE_START__; } MEMORY { @@ -21,16 +21,16 @@ SEGMENTS { CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss, define = yes; + INIT: load = RAM, type = bss, define = yes; BSS: load = RAM, type = bss, define = yes; - INIT: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; + ONCE: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; LC: load = MOVE, run = LC, type = ro, optional = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/apple2enh.cfg b/cfg/apple2enh.cfg index 27eb706c4..8e63090f5 100644 --- a/cfg/apple2enh.cfg +++ b/cfg/apple2enh.cfg @@ -10,7 +10,7 @@ SYMBOLS { __LCSIZE__: type = weak, value = $0C00; # Rest of bank two __STACKSIZE__: type = weak, value = $0800; # 2k stack __LOADADDR__: type = weak, value = __STARTUP_RUN__; - __LOADSIZE__: type = weak, value = __INITBSS_RUN__ - __STARTUP_RUN__ + + __LOADSIZE__: type = weak, value = __INIT_RUN__ - __STARTUP_RUN__ + __MOVE_LAST__ - __MOVE_START__; } MEMORY { @@ -28,16 +28,16 @@ SEGMENTS { CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss, define = yes; + INIT: load = RAM, type = bss, define = yes; BSS: load = RAM, type = bss, define = yes; - INIT: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; + ONCE: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; LC: load = MOVE, run = LC, type = ro, optional = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/atari-cart.cfg b/cfg/atari-cart.cfg index 58457c606..09bf86761 100644 --- a/cfg/atari-cart.cfg +++ b/cfg/atari-cart.cfg @@ -16,23 +16,23 @@ MEMORY { CARTID: file = %O, start = $BFFA, size = $0006; } SEGMENTS { - STARTUP: load = ROM, type = ro, define = yes, optional = yes; - LOWCODE: load = ROM, type = ro, define = yes, optional = yes; - INIT: load = ROM, type = ro, optional = yes; - CODE: load = ROM, type = ro, define = yes; - RODATA: load = ROM, type = ro, optional = yes; - DATA: load = ROM, run = RAM, type = rw, define = yes, optional = yes; - INITBSS: load = RAM, type = bss, optional = yes; - BSS: load = RAM, type = bss, define = yes, optional = yes; - CARTHDR: load = CARTID, type = ro; - ZEROPAGE: load = ZP, type = zp, optional = yes; - EXTZP: load = ZP, type = zp, optional = yes; + ZEROPAGE: load = ZP, type = zp, optional = yes; + EXTZP: load = ZP, type = zp, 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; + CODE: load = ROM, type = ro, define = yes; + RODATA: load = ROM, type = ro, optional = yes; + DATA: load = ROM, run = RAM, type = rw, define = yes, optional = yes; + INIT: load = RAM, type = bss, optional = yes; + BSS: load = RAM, type = bss, define = yes, optional = yes; + CARTHDR: load = CARTID, type = ro; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/atari-cassette.cfg b/cfg/atari-cassette.cfg index 80b5c695f..ad68bb8b4 100644 --- a/cfg/atari-cassette.cfg +++ b/cfg/atari-cassette.cfg @@ -12,23 +12,23 @@ MEMORY { RAM: file = %O, define = yes, start = %S, size = $BC20 - __STACKSIZE__ - __RESERVED_MEMORY__ - %S; } SEGMENTS { - CASHDR: load = RAM, type = ro; - STARTUP: load = RAM, type = ro, define = yes, optional = yes; - LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - INIT: load = RAM, type = ro, optional = yes; - CODE: load = RAM, type = ro, define = yes; - RODATA: load = RAM, type = ro, optional = yes; - DATA: load = RAM, type = rw, optional = yes; - INITBSS: load = RAM, type = bss, optional = yes; - BSS: load = RAM, type = bss, define = yes, optional = yes; - ZEROPAGE: load = ZP, type = zp, optional = yes; - EXTZP: load = ZP, type = zp, optional = yes; + ZEROPAGE: load = ZP, type = zp, optional = yes; + EXTZP: load = ZP, type = zp, optional = yes; + CASHDR: load = RAM, type = ro; + STARTUP: load = RAM, type = ro, define = yes, optional = yes; + LOWCODE: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, optional = yes; + CODE: load = RAM, type = ro, define = yes; + RODATA: load = RAM, type = ro, optional = yes; + DATA: load = RAM, type = rw, optional = yes; + INIT: load = RAM, type = bss, optional = yes; + BSS: load = RAM, type = bss, define = yes, optional = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/atari-overlay.cfg b/cfg/atari-overlay.cfg index b3abad988..b14a93a39 100644 --- a/cfg/atari-overlay.cfg +++ b/cfg/atari-overlay.cfg @@ -38,6 +38,8 @@ MEMORY { OVL9: file = "%O.9", start = %S, size = __OVERLAYSIZE__; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; EXEHDR: load = HEADER, type = ro; SYSCHKHDR: load = SYSCHKHDR, type = ro, optional = yes; SYSCHK: load = SYSCHKCHNK, type = rw, define = yes, optional = yes; @@ -45,14 +47,12 @@ SEGMENTS { MAINHDR: load = MAINHDR, type = ro; STARTUP: load = RAM, type = ro, define = yes; LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - INIT: load = RAM, type = ro, optional = yes; + ONCE: load = RAM, type = ro, optional = yes; CODE: load = RAM, type = ro, define = yes; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss, optional = yes; + INIT: load = RAM, type = bss, optional = yes; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = zp, optional = yes; AUTOSTRT: load = TRAILER, type = ro; OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes; @@ -68,7 +68,7 @@ FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/atari.cfg b/cfg/atari.cfg index 97b289d7e..7460a0f66 100644 --- a/cfg/atari.cfg +++ b/cfg/atari.cfg @@ -26,6 +26,8 @@ MEMORY { TRAILER: file = %O, start = $0000, size = $0006; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; EXEHDR: load = HEADER, type = ro; SYSCHKHDR: load = SYSCHKHDR, type = ro, optional = yes; SYSCHK: load = SYSCHKCHNK, type = rw, define = yes, optional = yes; @@ -33,21 +35,19 @@ SEGMENTS { MAINHDR: load = MAINHDR, type = ro; STARTUP: load = RAM, type = ro, define = yes; LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - INIT: load = RAM, type = ro, optional = yes; + ONCE: load = RAM, type = ro, optional = yes; CODE: load = RAM, type = ro, define = yes; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss, optional = yes; + INIT: load = RAM, type = bss, optional = yes; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = zp, optional = yes; AUTOSTRT: load = TRAILER, type = ro; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/atari5200.cfg b/cfg/atari5200.cfg index 4a90303cf..3db8765d6 100644 --- a/cfg/atari5200.cfg +++ b/cfg/atari5200.cfg @@ -13,9 +13,11 @@ MEMORY { CARTENTRY: file = %O, start = $BFFE, size = $0002; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp, optional = yes; + EXTZP: load = ZP, type = zp, optional = yes; STARTUP: load = ROM, type = ro, define = yes, optional = yes; LOWCODE: load = ROM, type = ro, define = yes, optional = yes; - INIT: load = ROM, type = ro, optional = yes; + ONCE: load = ROM, type = ro, optional = yes; CODE: load = ROM, type = ro, define = yes; RODATA: load = ROM, type = ro, optional = yes; DATA: load = ROM, run = RAM, type = rw, define = yes, optional = yes; @@ -23,14 +25,12 @@ SEGMENTS { CARTNAME: load = CARTNAME, type = ro, define = yes; CARTYEAR: load = CARTYEAR, type = ro, define = yes; CARTENTRY: load = CARTENTRY, type = ro, define = yes; - ZEROPAGE: load = ZP, type = zp, optional = yes; - EXTZP: load = ZP, type = zp, optional = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/atarixl-largehimem.cfg b/cfg/atarixl-largehimem.cfg index f96096995..a1ec5cf08 100644 --- a/cfg/atarixl-largehimem.cfg +++ b/cfg/atarixl-largehimem.cfg @@ -50,6 +50,9 @@ MEMORY { } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; + EXEHDR: load = HEADER, type = ro; SYSCHKHDR: load = SYSCHKHDR, type = ro, optional = yes; @@ -66,21 +69,19 @@ SEGMENTS { MAINHDR: load = MAINHDR, type = ro; STARTUP: load = RAM, type = ro, define = yes; LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - INIT: load = RAM, type = ro, optional = yes; + ONCE: load = RAM, type = ro, optional = yes; CODE: load = RAM, type = ro, define = yes; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss, optional = yes; + INIT: load = RAM, type = bss, optional = yes; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = zp, optional = yes; AUTOSTRT: load = TRAILER, type = ro; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/atarixl-overlay.cfg b/cfg/atarixl-overlay.cfg index 7356fc03e..b0b4f3b88 100644 --- a/cfg/atarixl-overlay.cfg +++ b/cfg/atarixl-overlay.cfg @@ -62,6 +62,9 @@ MEMORY { } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; + EXEHDR: load = HEADER, type = ro; SYSCHKHDR: load = SYSCHKHDR, type = ro, optional = yes; @@ -78,14 +81,12 @@ SEGMENTS { MAINHDR: load = MAINHDR, type = ro; STARTUP: load = RAM, type = ro, define = yes; LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - INIT: load = RAM, type = ro, optional = yes; + ONCE: load = RAM, type = ro, optional = yes; CODE: load = RAM, type = ro, define = yes; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss, optional = yes; + INIT: load = RAM, type = bss, optional = yes; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = zp, optional = yes; AUTOSTRT: load = TRAILER, type = ro; OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; @@ -102,7 +103,7 @@ FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/atarixl.cfg b/cfg/atarixl.cfg index 84992a205..2f9523c59 100644 --- a/cfg/atarixl.cfg +++ b/cfg/atarixl.cfg @@ -48,6 +48,9 @@ MEMORY { } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; + EXEHDR: load = HEADER, type = ro; SYSCHKHDR: load = SYSCHKHDR, type = ro, optional = yes; @@ -64,21 +67,19 @@ SEGMENTS { MAINHDR: load = MAINHDR, type = ro; STARTUP: load = RAM, type = ro, define = yes; LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - INIT: load = RAM, type = ro, optional = yes; + ONCE: load = RAM, type = ro, optional = yes; CODE: load = RAM, type = ro, define = yes; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss, optional = yes; + INIT: load = RAM, type = bss, optional = yes; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = zp, optional = yes; AUTOSTRT: load = TRAILER, type = ro; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/atmos.cfg b/cfg/atmos.cfg index a1f935efa..a0f7e1c3d 100644 --- a/cfg/atmos.cfg +++ b/cfg/atmos.cfg @@ -21,7 +21,7 @@ SEGMENTS { LOWCODE: load = RAM, type = ro, optional = yes; CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; DATA: load = RAM, type = rw; ZPSAVE1: load = RAM, type = rw, define = yes; # ZPSAVE1, ZPSAVE2 must be together ZPSAVE2: load = RAM, type = bss; # see "libsrc/atmos/crt0.s" @@ -31,7 +31,7 @@ FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/bbc.cfg b/cfg/bbc.cfg index 6304c309b..98779b6fd 100644 --- a/cfg/bbc.cfg +++ b/cfg/bbc.cfg @@ -6,20 +6,20 @@ MEMORY { RAM: file = %O, start = $0E00, size = $7200 - __STACKSIZE__; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; STARTUP: load = RAM, type = ro, define = yes; LOWCODE: load = RAM, type = ro, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/c128-overlay.cfg b/cfg/c128-overlay.cfg index f2cc3c40c..771bd290b 100644 --- a/cfg/c128-overlay.cfg +++ b/cfg/c128-overlay.cfg @@ -30,17 +30,17 @@ MEMORY { OVL9: file = "%O.9", start = $C000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; STARTUP: load = RAM, type = ro; LOWCODE: load = RAM, type = ro, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss; + INIT: load = RAM, type = bss; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; OVL1ADDR: load = OVL1ADDR, type = ro; OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; OVL2ADDR: load = OVL2ADDR, type = ro; @@ -64,7 +64,7 @@ FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/c128.cfg b/cfg/c128.cfg index ef2aa4184..0ea6066ad 100644 --- a/cfg/c128.cfg +++ b/cfg/c128.cfg @@ -10,23 +10,23 @@ MEMORY { RAM: file = %O, define = yes, start = $1C0D, size = $A3F3 - __STACKSIZE__; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; STARTUP: load = RAM, type = ro; LOWCODE: load = RAM, type = ro, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss; + INIT: load = RAM, type = bss; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/c16.cfg b/cfg/c16.cfg index efb42991f..b4b5ccaf7 100644 --- a/cfg/c16.cfg +++ b/cfg/c16.cfg @@ -10,23 +10,23 @@ MEMORY { RAM: file = %O, start = $100D, size = $6FF3 - __STACKSIZE__; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; STARTUP: load = RAM, type = ro; LOWCODE: load = RAM, type = ro, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss; + INIT: load = RAM, type = bss; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/c64-overlay.cfg b/cfg/c64-overlay.cfg index 522a6d1a6..872fdd775 100644 --- a/cfg/c64-overlay.cfg +++ b/cfg/c64-overlay.cfg @@ -44,9 +44,9 @@ SEGMENTS { CODE: load = MAIN, type = ro; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; - INITBSS: load = MAIN, type = rw; + INIT: load = MAIN, type = rw; BSS: load = MAIN, type = bss, define = yes; - INIT: load = INIT, type = ro; + ONCE: load = INIT, type = ro; OVL1ADDR: load = OVL1ADDR, type = ro; OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; OVL2ADDR: load = OVL2ADDR, type = ro; @@ -70,7 +70,7 @@ FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/c64.cfg b/cfg/c64.cfg index 8ff7db03c..3735a0a65 100644 --- a/cfg/c64.cfg +++ b/cfg/c64.cfg @@ -23,15 +23,15 @@ SEGMENTS { CODE: load = MAIN, type = ro; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; - INITBSS: load = MAIN, type = rw; + INIT: load = MAIN, type = rw; BSS: load = MAIN, type = bss, define = yes; - INIT: load = INIT, type = ro, define = yes; + ONCE: load = INIT, type = ro, define = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/cbm510.cfg b/cfg/cbm510.cfg index d0775b6f2..8b01dff0b 100644 --- a/cfg/cbm510.cfg +++ b/cfg/cbm510.cfg @@ -18,11 +18,11 @@ SEGMENTS { PAGE2: load = PAGE2, type = rw; PAGE3: load = PAGE3, type = rw; LOWCODE: load = RAM, type = ro, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss; + INIT: load = RAM, type = bss; BSS: load = RAM, type = bss, define = yes; ZEROPAGE: load = ZP, type = zp; EXTZP: load = ZP, type = rw, define = yes; @@ -31,7 +31,7 @@ FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/cbm610.cfg b/cfg/cbm610.cfg index ae66f4c4a..6df9f1f5a 100644 --- a/cfg/cbm610.cfg +++ b/cfg/cbm610.cfg @@ -15,11 +15,11 @@ SEGMENTS { PAGE2: load = PAGE2, type = rw; PAGE3: load = PAGE3, type = rw; LOWCODE: load = RAM, type = ro, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss; + INIT: load = RAM, type = bss; BSS: load = RAM, type = bss, define = yes; ZEROPAGE: load = ZP, type = zp; EXTZP: load = ZP, type = rw, define = yes; @@ -28,7 +28,7 @@ FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/gamate.cfg b/cfg/gamate.cfg index 90ced1ea5..f0f669f27 100644 --- a/cfg/gamate.cfg +++ b/cfg/gamate.cfg @@ -1,41 +1,51 @@ # linker config to produce simple Gamate cartridge (.bin) SYMBOLS { - __STARTUP__: type = import; - __STACKSIZE__: type = weak, value = $0080; # 1 page stack + __STARTUP__: type = import; + __STACKSIZE__: type = weak, value = $0080; # 1 page stack } MEMORY { - # 0000-03ff is RAM - # FIXME: what zp range can we actually use? - # $0a-$11 is used by IRQ/NMI, $e8 is used by NMI - ZP: start = $0012, size = $e8 - $12; - CPUSTACK: start = $0100, size =$100; - RAM: start = $0200, size = $200 - __STACKSIZE__, define = yes; + # 0000-03ff is RAM + # FIXME: what zp range can we actually use? + # $0a-$11 is used by IRQ/NMI, $e8 is used by NMI + ZP: start = $0012, size = $e8 - $12; + CPUSTACK: start = $0100, size =$100; + RAM: start = $0200, size = $200 - __STACKSIZE__, define = yes; - CARTHEADER: file = %O, define = yes, start = %S, size = $0029; - # 6000-e000 can be (Cartridge) ROM - # WARNING: fill value must be $00 else it will no more work - #ROM: start = $6000, size = $1000, fill = yes, fillval = $00, file = %O, define = yes; - #ROMFILL: start = $7000, size = $7000, fill = yes, fillval = $00, file = %O, define = yes; - # for images that have code >$6fff we must calculate the checksum! - ROM: start = $6000 + $29, size = $8000 - $29, fill = yes, fillval = $00, file = %O, define = yes; + CARTHEADER: file = %O, define = yes, start = %S, size = $0029; + # 6000-e000 can be (Cartridge) ROM + # WARNING: fill value must be $00 else it will no more work + #ROM: start = $6000, size = $1000, fill = yes, fillval = $00, file = %O, define = yes; + #ROMFILL: start = $7000, size = $7000, fill = yes, fillval = $00, file = %O, define = yes; + # for images that have code >$6fff we must calculate the checksum! + ROM: start = $6000 + $29, size = $8000 - $29, fill = yes, fillval = $00, file = %O, define = yes; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp, define = yes; - EXTZP: load = ZP, type = zp, define = yes, optional = yes; - APPZP: load = ZP, type = zp, define = yes, optional = yes; - STARTUP: load = CARTHEADER, type = ro, define=yes; - INIT: load = ROM, type = ro, define = yes, optional = yes; - CODE: load = ROM, type = ro, define=yes; - RODATA: load = ROM, type = ro, define=yes; - DATA: load = ROM, run=RAM, type = rw, define = yes; - BSS: load = RAM, type = bss, define = yes; + ZEROPAGE: load = ZP, type = zp, define = yes; + EXTZP: load = ZP, type = zp, define = yes, optional = yes; + APPZP: load = ZP, type = zp, define = yes, optional = yes; + STARTUP: load = CARTHEADER, type = ro, define = yes; + ONCE: load = ROM, type = ro, define = yes, optional = yes; + CODE: load = ROM, type = ro, define = yes; + RODATA: load = ROM, type = ro, define = yes; + DATA: load = ROM, run = RAM, type = rw, define = yes; + BSS: load = RAM, type = bss, define = yes; } FEATURES { - CONDES: segment = RODATA, type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__; - CONDES: segment = RODATA, type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__; - CONDES: segment = RODATA, type = interruptor, label = __INTERRUPTOR_TABLE__, count = __INTERRUPTOR_COUNT__, import = __CALLIRQ__; + 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/geos-apple.cfg b/cfg/geos-apple.cfg index 746e1f2bf..ee8b61aec 100644 --- a/cfg/geos-apple.cfg +++ b/cfg/geos-apple.cfg @@ -40,7 +40,7 @@ SEGMENTS { VLIRIDX0: type = ro, load = CVT, align = $200, optional = yes; STARTUP: type = ro, run = VLIR0, load = CVT, align_load = $200, define = yes; LOWCODE: type = ro, run = VLIR0, load = CVT, optional = yes; - INIT: type = ro, run = VLIR0, load = CVT, define = yes, optional = yes; + ONCE: type = ro, run = VLIR0, load = CVT, define = yes, optional = yes; CODE: type = ro, run = VLIR0, load = CVT; RODATA: type = ro, run = VLIR0, load = CVT; DATA: type = rw, run = VLIR0, load = CVT; @@ -88,7 +88,7 @@ FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/geos-cbm.cfg b/cfg/geos-cbm.cfg index ddef00a99..42cbe9a48 100644 --- a/cfg/geos-cbm.cfg +++ b/cfg/geos-cbm.cfg @@ -37,7 +37,7 @@ SEGMENTS { RECORDS: type = ro, load = CVT, align = $FE, optional = yes; STARTUP: type = ro, run = VLIR0, load = CVT, align_load = $FE, define = yes; LOWCODE: type = ro, run = VLIR0, load = CVT, optional = yes; - INIT: type = ro, run = VLIR0, load = CVT, define = yes, optional = yes; + ONCE: type = ro, run = VLIR0, load = CVT, define = yes, optional = yes; CODE: type = ro, run = VLIR0, load = CVT; RODATA: type = ro, run = VLIR0, load = CVT; DATA: type = rw, run = VLIR0, load = CVT; @@ -66,7 +66,7 @@ FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/lunix.cfg b/cfg/lunix.cfg index 1342c390b..aabacbeb2 100644 --- a/cfg/lunix.cfg +++ b/cfg/lunix.cfg @@ -12,7 +12,7 @@ SEGMENTS { ZEROPAGE: load = ZP, type = zp, define = yes; # Pseudo-registers STARTUP: load = RAM, type = ro; # First initialization code LOWCODE: load = RAM, type = ro, optional = yes; # Legacy from other platforms - INIT: load = RAM, type = ro, define = yes, optional = yes; # Library initialization code + ONCE: load = RAM, type = ro, define = yes, optional = yes; # Library initialization code CODE: load = RAM, type = ro; # Program RODATA: load = RAM, type = ro; # Literals, constants DATA: load = RAM, type = rw; # Initialized variables @@ -22,7 +22,7 @@ FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/lynx-bll.cfg b/cfg/lynx-bll.cfg index 21967752f..fcf6d4c60 100644 --- a/cfg/lynx-bll.cfg +++ b/cfg/lynx-bll.cfg @@ -10,23 +10,23 @@ MEMORY { RAM: file = %O, define = yes, start = $0400, size = $BC38 - __STACKSIZE__; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; + APPZP: load = ZP, type = zp, optional = yes; BLLHDR: load = HEADER, type = ro; STARTUP: load = RAM, type = ro, define = yes; LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; CODE: load = RAM, type = ro, define = yes; RODATA: load = RAM, type = ro, define = yes; DATA: load = RAM, type = rw, define = yes; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = zp, optional = yes; - APPZP: load = ZP, type = zp, optional = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/lynx-coll.cfg b/cfg/lynx-coll.cfg index b7fd787e7..d40c18237 100644 --- a/cfg/lynx-coll.cfg +++ b/cfg/lynx-coll.cfg @@ -14,25 +14,25 @@ MEMORY { RAM: file = %O, define = yes, start = $0200, size = $9E58 - __STACKSIZE__; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; + APPZP: load = ZP, type = zp, optional = yes; EXEHDR: load = HEADER, type = ro; BOOTLDR: load = BOOT, type = ro; DIRECTORY: load = DIR, type = ro; STARTUP: load = RAM, type = ro, define = yes; LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; CODE: load = RAM, type = ro, define = yes; RODATA: load = RAM, type = ro, define = yes; DATA: load = RAM, type = rw, define = yes; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = zp, optional = yes; - APPZP: load = ZP, type = zp, optional = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/lynx-uploader.cfg b/cfg/lynx-uploader.cfg index 740a18b0a..fe6d6133d 100644 --- a/cfg/lynx-uploader.cfg +++ b/cfg/lynx-uploader.cfg @@ -16,27 +16,27 @@ MEMORY { UPLDR: file = %O, define = yes, start = $BFDC, size = $005C; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; + APPZP: load = ZP, type = zp, optional = yes; EXEHDR: load = HEADER, type = ro; BOOTLDR: load = BOOT, type = ro; DIRECTORY:load = DIR, type = ro; STARTUP: load = RAM, type = ro, define = yes; LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; CODE: load = RAM, type = ro, define = yes; RODATA: load = RAM, type = ro, define = yes; DATA: load = RAM, type = rw, define = yes; BSS: load = RAM, type = bss, define = yes; UPCODE: load = UPLDR, type = ro, define = yes; UPDATA: load = UPLDR, type = rw, define = yes; - ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = zp, optional = yes; - APPZP: load = ZP, type = zp, optional = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/lynx.cfg b/cfg/lynx.cfg index 2c9e76207..4d41c1bbf 100644 --- a/cfg/lynx.cfg +++ b/cfg/lynx.cfg @@ -14,25 +14,25 @@ MEMORY { RAM: file = %O, define = yes, start = $0200, size = $BE38 - __STACKSIZE__; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; + APPZP: load = ZP, type = zp, optional = yes; EXEHDR: load = HEADER, type = ro; BOOTLDR: load = BOOT, type = ro; DIRECTORY: load = DIR, type = ro; STARTUP: load = RAM, type = ro, define = yes; LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; CODE: load = RAM, type = ro, define = yes; RODATA: load = RAM, type = ro, define = yes; DATA: load = RAM, type = rw, define = yes; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = zp, optional = yes; - APPZP: load = ZP, type = zp, optional = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/module.cfg b/cfg/module.cfg index 452491eb4..be312585c 100644 --- a/cfg/module.cfg +++ b/cfg/module.cfg @@ -6,7 +6,7 @@ SEGMENTS { ZEROPAGE: load = ZP, type = zp; EXTZP: load = ZP, type = zp, optional = yes; HEADER: load = COMBINED, type = ro; - INIT: load = COMBINED, type = ro, optional = yes; + ONCE: load = COMBINED, type = ro, optional = yes; CODE: load = COMBINED, type = ro; RODATA: load = COMBINED, type = ro; DATA: load = COMBINED, type = rw; diff --git a/cfg/nes.cfg b/cfg/nes.cfg index 3e2f408cc..f68330425 100644 --- a/cfg/nes.cfg +++ b/cfg/nes.cfg @@ -33,23 +33,23 @@ MEMORY { RAM: file = "", start = $6000, size = $2000, define = yes; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; HEADER: load = HEADER, type = ro; STARTUP: load = ROM0, type = ro, define = yes; LOWCODE: load = ROM0, type = ro, optional = yes; - INIT: load = ROM0, type = ro, define = yes, optional = yes; + ONCE: load = ROM0, type = ro, define = yes, optional = yes; CODE: load = ROM0, type = ro, define = yes; RODATA: load = ROM0, type = ro, define = yes; DATA: load = ROM0, run = RAM, type = rw, define = yes; VECTORS: load = ROMV, type = rw; CHARS: load = ROM2, type = rw; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/none.cfg b/cfg/none.cfg index 49409a82c..54ae54eb4 100644 --- a/cfg/none.cfg +++ b/cfg/none.cfg @@ -6,19 +6,19 @@ MEMORY { RAM: file = %O, start = %S, size = $10000 - __STACKSIZE__; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; LOWCODE: load = RAM, type = ro, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; CODE: load = RAM, type = rw; RODATA: load = RAM, type = rw; DATA: load = RAM, type = rw; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/osic1p-asm.cfg b/cfg/osic1p-asm.cfg index 4000890be..ac2e76dc9 100644 --- a/cfg/osic1p-asm.cfg +++ b/cfg/osic1p-asm.cfg @@ -15,11 +15,11 @@ MEMORY { RAM: file = %O, define = yes, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; BOOT: load = HEAD, type = ro, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; CODE: load = RAM, type = rw; RODATA: load = RAM, type = rw; DATA: load = RAM, type = rw; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; } diff --git a/cfg/osic1p.cfg b/cfg/osic1p.cfg index fd9aa604e..314eac0b9 100644 --- a/cfg/osic1p.cfg +++ b/cfg/osic1p.cfg @@ -15,22 +15,22 @@ MEMORY { RAM: file = %O, define = yes, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, define = yes, optional = yes; BOOT: load = HEAD, type = ro, optional = yes; STARTUP: load = RAM, type = ro; LOWCODE: load = RAM, type = ro, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; CODE: load = RAM, type = rw; RODATA: load = RAM, type = rw; DATA: load = RAM, type = rw; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = zp, define = yes, optional = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/pce.cfg b/cfg/pce.cfg index 9128eb727..219cbdec3 100644 --- a/cfg/pce.cfg +++ b/cfg/pce.cfg @@ -1,39 +1,39 @@ # linker config to produce simple NEC PC-Engine cartridge (.pce) SYMBOLS { - __STACKSIZE__: type = weak, value = $0300; # 3 pages stack + __STACKSIZE__: type = weak, value = $0300; # 3 pages stack } MEMORY { - # FIXME: is this correct? the first 3? bytes cant be used? - ZP: start = $03, size = $fd, type = rw, define = yes; + # FIXME: is this correct? the first 3? bytes cant be used? + ZP: file = "", start = $0003, size = $00FD, type = rw, define = yes; - # reset-bank and hardware vectors - ROM0: start = $e000, size = $1ff6, file = %O ,fill = yes, define = yes; - ROMV: start = $fff6, size = $a, file = %O,fill = yes; + # reset-bank and hardware vectors + ROM0: file = %O, start = $E000, size = $1FF6, fill = yes, define = yes; + ROMV: file = %O, start = $FFF6, size = $000A, fill = yes; - # first RAM page (also contains stack and zeropage) - RAM: start = $2200, size = $1e00, define = yes; + # first RAM page (also contains stack and zeropage) + RAM: file = "", start = $2200, size = $1e00, define = yes; } SEGMENTS { - STARTUP: load = ROM0, type = ro, define = yes; - INIT: load = ROM0, type = ro, define = yes, optional = yes; - CODE: load = ROM0, type = ro, define = yes; - RODATA: load = ROM0, type = ro, define = yes; - DATA: load = ROM0, run= RAM, type = rw, define = yes; - BSS: load = RAM, type = bss, define = yes; - VECTORS: load = ROMV, type = rw, define = yes; - ZEROPAGE: load = ZP, type = zp, define = yes; - EXTZP: load = ZP, type = zp, define = yes, optional = yes; - APPZP: load = ZP, type = zp, define = yes, optional = yes; + ZEROPAGE: load = ZP, type = zp, define = yes; + EXTZP: load = ZP, type = zp, define = yes, optional = yes; + APPZP: load = ZP, type = zp, define = yes, optional = yes; + STARTUP: load = ROM0, type = ro, define = yes; + ONCE: load = ROM0, type = ro, define = yes, optional = yes; + CODE: load = ROM0, type = ro, define = yes; + RODATA: load = ROM0, type = ro, define = yes; + DATA: load = ROM0, run = RAM, type = rw, define = yes; + BSS: load = RAM, type = bss, define = yes; + VECTORS: load = ROMV, type = rw, define = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/pet.cfg b/cfg/pet.cfg index 80d89ee50..aad3f579e 100644 --- a/cfg/pet.cfg +++ b/cfg/pet.cfg @@ -10,23 +10,23 @@ MEMORY { RAM: file = %O, start = $040D, size = $7BF3 - __STACKSIZE__; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; STARTUP: load = RAM, type = ro; LOWCODE: load = RAM, type = ro, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss; + INIT: load = RAM, type = bss; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/plus4.cfg b/cfg/plus4.cfg index 6eeddf12e..16e9d12c8 100644 --- a/cfg/plus4.cfg +++ b/cfg/plus4.cfg @@ -10,23 +10,23 @@ MEMORY { RAM: file = %O, define = yes, start = $100D, size = $ECF3 - __STACKSIZE__; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; STARTUP: load = RAM, type = ro; LOWCODE: load = RAM, type = ro, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss; + INIT: load = RAM, type = bss; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/sim6502.cfg b/cfg/sim6502.cfg index edb630d7f..8e78fceb2 100644 --- a/cfg/sim6502.cfg +++ b/cfg/sim6502.cfg @@ -3,26 +3,26 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack } MEMORY { - ZP: file = "", start = $0000, size = $001A; - HEADER: file = %O, start = $0000, size = $0001; - RAM: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; + ZP: file = "", start = $0000, size = $001A; + HEADER: file = %O, start = $0000, size = $0001; + RAM: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; } SEGMENTS { - EXEHDR: load = HEADER, type = ro; - STARTUP: load = RAM, type = ro; - LOWCODE: load = RAM, type = ro, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; + ZEROPAGE: load = ZP, type = zp; + EXEHDR: load = HEADER, type = ro; + STARTUP: load = RAM, type = ro; + LOWCODE: load = RAM, type = ro, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; + CODE: load = RAM, type = ro; + RODATA: load = RAM, type = ro; + DATA: load = RAM, type = rw; + BSS: load = RAM, type = bss, define = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/sim65c02.cfg b/cfg/sim65c02.cfg index edb630d7f..8e78fceb2 100644 --- a/cfg/sim65c02.cfg +++ b/cfg/sim65c02.cfg @@ -3,26 +3,26 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack } MEMORY { - ZP: file = "", start = $0000, size = $001A; - HEADER: file = %O, start = $0000, size = $0001; - RAM: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; + ZP: file = "", start = $0000, size = $001A; + HEADER: file = %O, start = $0000, size = $0001; + RAM: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; } SEGMENTS { - EXEHDR: load = HEADER, type = ro; - STARTUP: load = RAM, type = ro; - LOWCODE: load = RAM, type = ro, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; + ZEROPAGE: load = ZP, type = zp; + EXEHDR: load = HEADER, type = ro; + STARTUP: load = RAM, type = ro; + LOWCODE: load = RAM, type = ro, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; + CODE: load = RAM, type = ro; + RODATA: load = RAM, type = ro; + DATA: load = RAM, type = rw; + BSS: load = RAM, type = bss, define = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/supervision-128k.cfg b/cfg/supervision-128k.cfg index ce835db50..3cfdf1276 100644 --- a/cfg/supervision-128k.cfg +++ b/cfg/supervision-128k.cfg @@ -21,7 +21,7 @@ MEMORY { } SEGMENTS { LOWCODE: load = ROM, type = ro, optional = yes; - INIT: load = ROM, type = ro, define = yes, optional = yes; + ONCE: load = ROM, type = ro, define = yes, optional = yes; CODE: load = ROM, type = ro; BANK1: load = BANKROM1, type = ro; BANK2: load = BANKROM2, type = ro; diff --git a/cfg/supervision-16k.cfg b/cfg/supervision-16k.cfg index e38948d5f..2e96b9a72 100644 --- a/cfg/supervision-16k.cfg +++ b/cfg/supervision-16k.cfg @@ -14,21 +14,21 @@ MEMORY { ROM: file = %O, start = $C000, size = $4000, fill = yes, fillval = $ff, define=yes; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp, define = yes; LOWCODE: load = ROM, type = ro, optional = yes; - INIT: load = ROM, type = ro, define = yes, optional = yes; + ONCE: load = ROM, type = ro, define = yes, optional = yes; CODE: load = ROM, type = ro, define = yes; RODATA: load = ROM, type = ro, define = yes; DATA: load = ROM, run = RAM, type = rw, define = yes; FFF0: load = ROM, type = ro, offset = $3FF0; VECTOR: load = ROM, type = ro, offset = $3FFA; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp, define = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/supervision-64k.cfg b/cfg/supervision-64k.cfg index fd5370fa5..63338d1e3 100644 --- a/cfg/supervision-64k.cfg +++ b/cfg/supervision-64k.cfg @@ -17,7 +17,7 @@ MEMORY { } SEGMENTS { LOWCODE: load = ROM, type = ro, optional = yes; - INIT: load = ROM, type = ro, define = yes, optional = yes; + ONCE: load = ROM, type = ro, define = yes, optional = yes; CODE: load = ROM, type = ro; RODATA: load = ROM, type = ro; BANK1: load = BANKROM1, type = ro; diff --git a/cfg/supervision.cfg b/cfg/supervision.cfg index 66fb4cfad..b7ae207b8 100644 --- a/cfg/supervision.cfg +++ b/cfg/supervision.cfg @@ -10,21 +10,21 @@ MEMORY { ROM: file = %O, start = $8000, size = $8000, fill = yes, fillval = $FF, define = yes; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp, define = yes; LOWCODE: load = ROM, type = ro, optional = yes; - INIT: load = ROM, type = ro, define = yes, optional = yes; + ONCE: load = ROM, type = ro, define = yes, optional = yes; CODE: load = ROM, type = ro, define = yes; RODATA: load = ROM, type = ro, define = yes; DATA: load = ROM, run = RAM, type = rw, define = yes; FFF0: load = ROM, type = ro, offset = $7FF0; VECTOR: load = ROM, type = ro, offset = $7FFA; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp, define = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/vic20-32k.cfg b/cfg/vic20-32k.cfg index 23cd718df..a1b609106 100644 --- a/cfg/vic20-32k.cfg +++ b/cfg/vic20-32k.cfg @@ -16,11 +16,11 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro; STARTUP: load = RAM, type = ro; LOWCODE: load = RAM, type = ro, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss; + INIT: load = RAM, type = bss; BSS: load = RAM, type = bss, define = yes; ZEROPAGE: load = ZP, type = zp; } @@ -28,7 +28,7 @@ FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/cfg/vic20.cfg b/cfg/vic20.cfg index 9a5ce9a63..693b356a3 100644 --- a/cfg/vic20.cfg +++ b/cfg/vic20.cfg @@ -10,23 +10,23 @@ MEMORY { RAM: file = %O, define = yes, start = $100D, size = $0DF3 - __STACKSIZE__; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; STARTUP: load = RAM, type = ro; LOWCODE: load = RAM, type = ro, optional = yes; - INIT: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, define = yes, optional = yes; CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; - INITBSS: load = RAM, type = bss; + INIT: load = RAM, type = bss; BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, - segment = INIT; + segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, diff --git a/doc/atari.sgml b/doc/atari.sgml index 47ce050e1..f37b43929 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -743,7 +743,7 @@ segments should go above $7FFF. <p> The main problem is that the EXE header generated by the cc65 runtime lib is wrong. It defines a single load chunk with the sizes/addresses -of the STARTUP, LOWCODE, INIT, CODE, RODATA, and DATA segments, in +of the STARTUP, LOWCODE, ONCE, CODE, RODATA, and DATA segments, in fact, the whole user program (we're disregarding the "system check" load chunk here). <p> @@ -796,7 +796,7 @@ SEGMENTS { NEXEHDR: load = FSTHDR, type = ro; # first load chunk STARTUP: load = RAMLO, type = ro, define = yes; LOWCODE: load = RAMLO, type = ro, define = yes, optional = yes; - INIT: load = RAMLO, type = ro, optional = yes; + ONCE: load = RAMLO, type = ro, optional = yes; CODE: load = RAMLO, type = ro, define = yes; CHKHDR: load = SECHDR, type = ro; # second load chunk @@ -808,7 +808,7 @@ SEGMENTS { AUTOSTRT: load = RAM, type = ro; # defines program entry point } FEATURES { - CONDES: segment = RODATA, + CONDES: segment = ONCE, type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__; @@ -827,7 +827,7 @@ the MAINHDR segment get discarded. <p> The newly added NEXEHDR segment defines the correct chunk header for the first intended load chunk. It -puts the STARTUP, LOWCODE, INIT, and CODE segments, which are the +puts the STARTUP, LOWCODE, ONCE, and CODE segments, which are the segments containing only code, into load chunk #1 (RAMLO memory area). <p> The header for the second load chunk comes from the new CHKHDR @@ -858,7 +858,7 @@ cl65 -t atari -C split.cfg -o prog.com prog.c split.s <sect2>Low data and high code example<p> -Goal: Put RODATA and DATA into low memory and STARTUP, LOWCODE, INIT, +Goal: Put RODATA and DATA into low memory and STARTUP, LOWCODE, ONCE, CODE, BSS, ZPSAVE into high memory (split2.cfg): <tscreen><verb> @@ -893,7 +893,7 @@ SEGMENTS { CHKHDR: load = SECHDR, type = ro; # second load chunk STARTUP: load = RAM, type = ro, define = yes; - INIT: load = RAM, type = ro, optional = yes; + ONCE: load = RAM, type = ro, optional = yes; CODE: load = RAM, type = ro, define = yes; BSS: load = RAM, type = bss, define = yes; @@ -901,7 +901,7 @@ SEGMENTS { AUTOSTRT: load = RAM, type = ro; # defines program entry point } FEATURES { - CONDES: segment = RODATA, + CONDES: segment = ONCE, type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__; diff --git a/doc/customizing.sgml b/doc/customizing.sgml index 0a0b8c87e..e502f2e9d 100644 --- a/doc/customizing.sgml +++ b/doc/customizing.sgml @@ -78,15 +78,15 @@ vectors at the proper memory locations. The segment definition is: <tscreen><code> SEGMENTS { - ZEROPAGE: load = ZP, type = zp, define = yes; - DATA: load = ROM, type = rw, define = yes, run = RAM; - BSS: load = RAM, type = bss, define = yes; - HEAP: load = RAM, type = bss, optional = yes; - STARTUP: load = ROM, type = ro; - INIT: load = ROM, type = ro, optional = yes; - CODE: load = ROM, type = ro; - RODATA: load = ROM, type = ro; - VECTORS: load = ROM, type = ro, start = $FFFA; + ZEROPAGE: load = ZP, type = zp, define = yes; + DATA: load = ROM, type = rw, define = yes, run = RAM; + BSS: load = RAM, type = bss, define = yes; + HEAP: load = RAM, type = bss, optional = yes; + STARTUP: load = ROM, type = ro; + ONCE: load = ROM, type = ro, optional = yes; + CODE: load = ROM, type = ro; + RODATA: load = ROM, type = ro; + VECTORS: load = ROM, type = ro, start = $FFFA; } </code></tscreen> @@ -97,7 +97,7 @@ The meaning of each of these segments is as follows. <p><tt> BSS: </tt>Uninitialized data stored in RAM (used for variable storage) <p><tt> HEAP: </tt>Uninitialized C-level heap storage in RAM, optional <p><tt> STARTUP: </tt>The program initialization code, stored in ROM -<p><tt> INIT: </tt>The code needed to initialize the system, stored in ROM +<p><tt> ONCE: </tt>The code run once to initialize the system, stored in ROM <p><tt> CODE: </tt>The program code, stored in ROM <p><tt> RODATA: </tt>Initialized data that cannot be modified by the program, stored in ROM <p><tt> VECTORS: </tt>The interrupt vector table, stored in ROM at location $FFFA diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 329f975e1..448157ce0 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -1032,11 +1032,11 @@ The builtin config files do contain segments that have a special meaning for the compiler and the libraries that come with it. If you replace the builtin config files, you will need the following information. -<sect1>INIT<p> +<sect1>ONCE<p> -The INIT segment is used for initialization code that may be reused once +The ONCE segment is used for initialization code run only once before execution reaches main() - provided that the program runs in RAM. You -may for example add the INIT segment to the heap in really memory +may for example add the ONCE segment to the heap in really memory constrained systems. <sect1>LOWCODE<p> diff --git a/libsrc/apple2/cputc.s b/libsrc/apple2/cputc.s index 1cadd1f1c..2db2962f9 100644 --- a/libsrc/apple2/cputc.s +++ b/libsrc/apple2/cputc.s @@ -14,7 +14,7 @@ .include "apple2.inc" - .segment "INIT" + .segment "ONCE" .ifdef __APPLE2ENH__ initconio: diff --git a/libsrc/apple2/crt0.s b/libsrc/apple2/crt0.s index f061b212b..7eee390fa 100644 --- a/libsrc/apple2/crt0.s +++ b/libsrc/apple2/crt0.s @@ -10,8 +10,8 @@ .import initlib, donelib .import callmain .import __LC_START__, __LC_LAST__ ; Linker generated - .import __INIT_RUN__, __INIT_SIZE__ ; Linker generated - .import __INITBSS_RUN__ ; Linker generated + .import __ONCE_RUN__, __ONCE_SIZE__ ; Linker generated + .import __INIT_RUN__ ; Linker generated .include "zeropage.inc" .include "apple2.inc" @@ -29,14 +29,14 @@ bit $C081 ; Set the source start address. - lda #<(__INITBSS_RUN__ + __INIT_SIZE__) - ldy #>(__INITBSS_RUN__ + __INIT_SIZE__) + lda #<(__INIT_RUN__ + __ONCE_SIZE__) + ldy #>(__INIT_RUN__ + __ONCE_SIZE__) sta $9B sty $9C ; Set the source last address. - lda #<(__INITBSS_RUN__ + __INIT_SIZE__ + __LC_LAST__ - __LC_START__) - ldy #>(__INITBSS_RUN__ + __INIT_SIZE__ + __LC_LAST__ - __LC_START__) + lda #<(__INIT_RUN__ + __ONCE_SIZE__ + __LC_LAST__ - __LC_START__) + ldy #>(__INIT_RUN__ + __ONCE_SIZE__ + __LC_LAST__ - __LC_START__) sta $96 sty $97 @@ -51,25 +51,25 @@ jsr $D39A ; BLTU2 ; Set the source start address. - lda #<__INITBSS_RUN__ - ldy #>__INITBSS_RUN__ + lda #<__INIT_RUN__ + ldy #>__INIT_RUN__ sta $9B sty $9C ; Set the source last address. - lda #<(__INITBSS_RUN__ + __INIT_SIZE__) - ldy #>(__INITBSS_RUN__ + __INIT_SIZE__) + lda #<(__INIT_RUN__ + __ONCE_SIZE__) + ldy #>(__INIT_RUN__ + __ONCE_SIZE__) sta $96 sty $97 ; Set the destination last address. - lda #<(__INIT_RUN__ + __INIT_SIZE__) - ldy #>(__INIT_RUN__ + __INIT_SIZE__) + lda #<(__ONCE_RUN__ + __ONCE_SIZE__) + ldy #>(__ONCE_RUN__ + __ONCE_SIZE__) sta $94 sty $95 ; Call into Applesoft Block Transfer Up -- which handles moving - ; overlapping blocks upwards well -- to move the INIT segment. + ; overlapping blocks upwards well -- to move the ONCE segment. jsr $D39A ; BLTU2 ; Delegate all further processing, to keep the STARTUP segment small. @@ -109,7 +109,7 @@ exit: ldx #$02 ; We're done jmp done - .segment "INIT" + .segment "ONCE" ; Save the zero-page locations that we need. init: ldx #zpspace-1 @@ -201,7 +201,7 @@ q_param:.byte $04 ; param_count ; Final jump when we're done done: jmp DOSWARM ; Potentially patched at runtime - .segment "INITBSS" + .segment "INIT" zpsave: .res zpspace diff --git a/libsrc/apple2/dosdetect.s b/libsrc/apple2/dosdetect.s index 68910e3da..cedb1f3e3 100644 --- a/libsrc/apple2/dosdetect.s +++ b/libsrc/apple2/dosdetect.s @@ -30,7 +30,7 @@ ; - Apple II ProDOS 8 TechNote #23, ProDOS 8 Changes and Minutia ; - ProDOS TechRefMan, chapter 5.2.4 - .segment "INIT" + .segment "ONCE" initdostype: lda $BF00 diff --git a/libsrc/apple2/extra/iobuf-0800.s b/libsrc/apple2/extra/iobuf-0800.s index 7951ccbb0..2e5d1927e 100644 --- a/libsrc/apple2/extra/iobuf-0800.s +++ b/libsrc/apple2/extra/iobuf-0800.s @@ -14,7 +14,7 @@ .include "errno.inc" .include "../filedes.inc" - .segment "INIT" + .segment "ONCE" initiobuf: ; Convert end address highbyte to table index diff --git a/libsrc/apple2/get_ostype.s b/libsrc/apple2/get_ostype.s index 68ae865ac..cff6af9a3 100644 --- a/libsrc/apple2/get_ostype.s +++ b/libsrc/apple2/get_ostype.s @@ -10,7 +10,7 @@ ; Identify machine according to: ; Apple II Miscellaneous TechNote #7, Apple II Family Identification - .segment "INIT" + .segment "ONCE" initostype: sec diff --git a/libsrc/apple2/irq.s b/libsrc/apple2/irq.s index 0b0555695..97a1633b4 100644 --- a/libsrc/apple2/irq.s +++ b/libsrc/apple2/irq.s @@ -9,7 +9,7 @@ .include "apple2.inc" - .segment "INIT" + .segment "ONCE" initirq: ; Check for ProDOS diff --git a/libsrc/apple2/mainargs.s b/libsrc/apple2/mainargs.s index 2e809dc56..e3db8bb10 100644 --- a/libsrc/apple2/mainargs.s +++ b/libsrc/apple2/mainargs.s @@ -46,10 +46,10 @@ FNAM_LEN = $280 FNAM = $281 REM = $B2 ; BASIC token-code -; Get possible command-line arguments. Goes into the special INIT segment, +; Get possible command-line arguments. Goes into the special ONCE segment, ; which may be reused after the startup code is run. - .segment "INIT" + .segment "ONCE" initmainargs: diff --git a/libsrc/apple2/open.s b/libsrc/apple2/open.s index b1686df70..e47722973 100644 --- a/libsrc/apple2/open.s +++ b/libsrc/apple2/open.s @@ -19,7 +19,7 @@ .include "mli.inc" .include "filedes.inc" - .segment "INIT" + .segment "ONCE" raisefilelevel: ; Raise file level diff --git a/libsrc/apple2/read.s b/libsrc/apple2/read.s index ef994d6aa..14c80b7e2 100644 --- a/libsrc/apple2/read.s +++ b/libsrc/apple2/read.s @@ -16,7 +16,7 @@ .include "filedes.inc" .include "apple2.inc" - .segment "INIT" + .segment "ONCE" initprompt: ; Set prompt <> ']' to let DOS 3.3 know that we're diff --git a/libsrc/apple2/reboot.s b/libsrc/apple2/reboot.s index 8ee1ba067..e674ea1bc 100644 --- a/libsrc/apple2/reboot.s +++ b/libsrc/apple2/reboot.s @@ -10,7 +10,7 @@ _rebootafterexit := return - .segment "INIT" + .segment "ONCE" initreboot: ; Quit to PWRUP diff --git a/libsrc/atari/casinit.s b/libsrc/atari/casinit.s index c91989aad..668f34867 100644 --- a/libsrc/atari/casinit.s +++ b/libsrc/atari/casinit.s @@ -13,7 +13,7 @@ .import start .export _cas_init -.segment "INIT" +.segment "ONCE" _cas_init: .ifdef DEBUG diff --git a/libsrc/atari/dosdetect.s b/libsrc/atari/dosdetect.s index 654da55b5..cac9a6536 100644 --- a/libsrc/atari/dosdetect.s +++ b/libsrc/atari/dosdetect.s @@ -11,7 +11,7 @@ ; ------------------------------------------------------------------------ ; DOS type detection -.segment "INIT" +.segment "ONCE" detect: lda DOS cmp #'S' ; SpartaDOS diff --git a/libsrc/atari/getargs.s b/libsrc/atari/getargs.s index fb3b7bc03..d32c0a268 100644 --- a/libsrc/atari/getargs.s +++ b/libsrc/atari/getargs.s @@ -20,7 +20,7 @@ SPACE = 32 ; SPACE char. ; -------------------------------------------------------------------------- ; Get command line -.segment "INIT" +.segment "ONCE" initmainargs: lda #0 diff --git a/libsrc/atari/irq.s b/libsrc/atari/irq.s index 0a8efe466..1878ea0a2 100644 --- a/libsrc/atari/irq.s +++ b/libsrc/atari/irq.s @@ -13,7 +13,7 @@ ; ------------------------------------------------------------------------ -.segment "INIT" +.segment "ONCE" initirq: lda VVBLKD diff --git a/libsrc/atari/mcbpm.s b/libsrc/atari/mcbpm.s index c5c5dd433..9e6ccc2c5 100644 --- a/libsrc/atari/mcbpm.s +++ b/libsrc/atari/mcbpm.s @@ -180,7 +180,7 @@ update_colors: ; ------------------------------------------------------------------------ - .segment "INIT" + .segment "ONCE" pm_init: lda #0 diff --git a/libsrc/atari/shadow_ram_handlers.s b/libsrc/atari/shadow_ram_handlers.s index 53a71ab71..d65e6bd68 100644 --- a/libsrc/atari/shadow_ram_handlers.s +++ b/libsrc/atari/shadow_ram_handlers.s @@ -26,7 +26,7 @@ SHRAM_HANDLERS = 1 BUFSZ = 128 ; bounce buffer size BUFSZ_SIO = 256 -.segment "INIT" +.segment "ONCE" ; Turn off ROMs, install system and interrupt wrappers, set new chargen pointer diff --git a/libsrc/atari5200/conioscreen.s b/libsrc/atari5200/conioscreen.s index 660276675..2e86001c2 100644 --- a/libsrc/atari5200/conioscreen.s +++ b/libsrc/atari5200/conioscreen.s @@ -9,7 +9,7 @@ SCREEN_BUF = $4000 - SCREEN_BUF_SIZE .export screen_setup_20x24 - .segment "INIT" + .segment "ONCE" screen_setup_20x24: diff --git a/libsrc/atari5200/irq.s b/libsrc/atari5200/irq.s index 720113f82..263805d02 100644 --- a/libsrc/atari5200/irq.s +++ b/libsrc/atari5200/irq.s @@ -9,7 +9,7 @@ ; ------------------------------------------------------------------------ -.segment "INIT" +.segment "ONCE" initirq: lda VVBLKD diff --git a/libsrc/atmos/capslock.s b/libsrc/atmos/capslock.s index 0ed6e70da..91c484250 100644 --- a/libsrc/atmos/capslock.s +++ b/libsrc/atmos/capslock.s @@ -17,7 +17,7 @@ ;-------------------------------------------------------------------------- ; Put this constructor into a segment that can be re-used by programs. ; -.segment "INIT" +.segment "ONCE" ; Turn the capitals lock off. diff --git a/libsrc/atmos/cgetc.s b/libsrc/atmos/cgetc.s index e4ea15ac6..64d597bc6 100644 --- a/libsrc/atmos/cgetc.s +++ b/libsrc/atmos/cgetc.s @@ -55,10 +55,10 @@ .endproc ; ------------------------------------------------------------------------ -; Switch the cursor off. Code goes into the INIT segment +; Switch the cursor off. Code goes into the ONCE segment ; which may be reused after it is run. -.segment "INIT" +.segment "ONCE" initcgetc: lsr STATUS diff --git a/libsrc/atmos/irq.s b/libsrc/atmos/irq.s index ed443caae..751c860f2 100644 --- a/libsrc/atmos/irq.s +++ b/libsrc/atmos/irq.s @@ -9,7 +9,7 @@ ; ------------------------------------------------------------------------ -.segment "INIT" +.segment "ONCE" initirq: lda IRQVec diff --git a/libsrc/atmos/mainargs.s b/libsrc/atmos/mainargs.s index d6d9ed1ef..8b57d9855 100644 --- a/libsrc/atmos/mainargs.s +++ b/libsrc/atmos/mainargs.s @@ -17,10 +17,10 @@ REM = $9d ; BASIC token-code ;--------------------------------------------------------------------------- -; Get possible command-line arguments. Goes into the special INIT segment, +; Get possible command-line arguments. Goes into the special ONCE segment, ; which may be reused after the startup code is run -.segment "INIT" +.segment "ONCE" .proc initmainargs diff --git a/libsrc/atmos/read.s b/libsrc/atmos/read.s index 324ac789e..edf9d161d 100644 --- a/libsrc/atmos/read.s +++ b/libsrc/atmos/read.s @@ -69,7 +69,7 @@ L9: lda ptr3 ;-------------------------------------------------------------------------- ; initstdin: Reset the stdin console. -.segment "INIT" +.segment "ONCE" initstdin: ldx #<-1 diff --git a/libsrc/c128/cgetc.s b/libsrc/c128/cgetc.s index 46f13d197..7cb4c159e 100644 --- a/libsrc/c128/cgetc.s +++ b/libsrc/c128/cgetc.s @@ -42,7 +42,7 @@ L2: jsr KBDREAD ; Read char and return in A .bss keyvec: .res 2 -.segment "INIT" +.segment "ONCE" initcgetc: ; Save the old vector diff --git a/libsrc/c128/crt0.s b/libsrc/c128/crt0.s index 4c6a0f7d9..5891bacf3 100644 --- a/libsrc/c128/crt0.s +++ b/libsrc/c128/crt0.s @@ -108,7 +108,7 @@ L2: lda zpsave,x ; ------------------------------------------------------------------------ ; Data -.segment "INITBSS" +.segment "INIT" zpsave: .res zpspace diff --git a/libsrc/c128/irq.s b/libsrc/c128/irq.s index 79aa8faaa..9f6d0c6d1 100644 --- a/libsrc/c128/irq.s +++ b/libsrc/c128/irq.s @@ -9,7 +9,7 @@ ; ------------------------------------------------------------------------ -.segment "INIT" +.segment "ONCE" initirq: lda IRQVec diff --git a/libsrc/c128/mainargs.s b/libsrc/c128/mainargs.s index dcd5a11bd..f53ceafa0 100644 --- a/libsrc/c128/mainargs.s +++ b/libsrc/c128/mainargs.s @@ -32,10 +32,10 @@ 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 INIT segment, +; Get possible command-line arguments. Goes into the special ONCE segment, ; which may be reused after the startup code is run -.segment "INIT" +.segment "ONCE" initmainargs: @@ -127,7 +127,7 @@ done: lda #<argv stx __argv + 1 rts -.segment "INITBSS" +.segment "INIT" term: .res 1 name: .res NAME_LEN + 1 diff --git a/libsrc/c128/mcbdefault.s b/libsrc/c128/mcbdefault.s index 1951129a6..eb521eb3a 100644 --- a/libsrc/c128/mcbdefault.s +++ b/libsrc/c128/mcbdefault.s @@ -29,7 +29,7 @@ VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register ; -------------------------------------------------------------------------- ; Initialize the mouse sprite. -.segment "INIT" +.segment "ONCE" initmcb: diff --git a/libsrc/c128/systime.s b/libsrc/c128/systime.s index e12d016b8..b2a7f8721 100644 --- a/libsrc/c128/systime.s +++ b/libsrc/c128/systime.s @@ -63,7 +63,7 @@ BCD2dec:tax ; 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 "INIT" +.segment "ONCE" .proc initsystime diff --git a/libsrc/c16/cgetc.s b/libsrc/c16/cgetc.s index 8bcb72100..a476a5d1b 100644 --- a/libsrc/c16/cgetc.s +++ b/libsrc/c16/cgetc.s @@ -56,7 +56,7 @@ L2: jsr KBDREAD ; Read char and return in A .constructor initkbd .destructor donekbd -.segment "INIT" +.segment "ONCE" .proc initkbd diff --git a/libsrc/c16/crt0.s b/libsrc/c16/crt0.s index c4d179529..bee81a113 100644 --- a/libsrc/c16/crt0.s +++ b/libsrc/c16/crt0.s @@ -90,7 +90,7 @@ L2: lda zpsave,x ; ------------------------------------------------------------------------ -.segment "INITBSS" +.segment "INIT" zpsave: .res zpspace diff --git a/libsrc/c16/irq.s b/libsrc/c16/irq.s index 46dd75fe8..91dd8c05c 100644 --- a/libsrc/c16/irq.s +++ b/libsrc/c16/irq.s @@ -9,7 +9,7 @@ ; ------------------------------------------------------------------------ -.segment "INIT" +.segment "ONCE" initirq: lda IRQVec diff --git a/libsrc/c16/mainargs.s b/libsrc/c16/mainargs.s index db93ae2e6..c1d77a0e7 100644 --- a/libsrc/c16/mainargs.s +++ b/libsrc/c16/mainargs.s @@ -32,10 +32,10 @@ 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 INIT segment, +; Get possible command-line arguments. Goes into the special ONCE segment, ; which may be reused after the startup code is run -.segment "INIT" +.segment "ONCE" initmainargs: @@ -126,7 +126,7 @@ done: lda #<argv stx __argv + 1 rts -.segment "INITBSS" +.segment "INIT" term: .res 1 name: .res NAME_LEN + 1 diff --git a/libsrc/c64/crt0.s b/libsrc/c64/crt0.s index ea7867925..c8a7386cb 100644 --- a/libsrc/c64/crt0.s +++ b/libsrc/c64/crt0.s @@ -34,7 +34,7 @@ Start: tsx stx spsave ; Save the system stack ptr -; Save space by putting some of the start-up code in the INIT segment, +; 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 @@ -79,7 +79,7 @@ L2: lda zpsave,x ; ------------------------------------------------------------------------ -.segment "INIT" +.segment "ONCE" init: @@ -111,7 +111,7 @@ L1: lda sp,x ; ------------------------------------------------------------------------ ; Data -.segment "INITBSS" +.segment "INIT" mmusave:.res 1 spsave: .res 1 diff --git a/libsrc/c64/irq.s b/libsrc/c64/irq.s index 10d03aa2c..d0767d53f 100644 --- a/libsrc/c64/irq.s +++ b/libsrc/c64/irq.s @@ -9,7 +9,7 @@ ; ------------------------------------------------------------------------ -.segment "INIT" +.segment "ONCE" initirq: lda IRQVec diff --git a/libsrc/c64/mainargs.s b/libsrc/c64/mainargs.s index a31c1b54f..a381b49e1 100644 --- a/libsrc/c64/mainargs.s +++ b/libsrc/c64/mainargs.s @@ -32,10 +32,10 @@ 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 INIT segment, +; Get possible command-line arguments. Goes into the special ONCE segment, ; which may be reused after the startup code is run -.segment "INIT" +.segment "ONCE" initmainargs: @@ -125,7 +125,7 @@ done: lda #<argv stx __argv + 1 rts -.segment "INITBSS" +.segment "INIT" term: .res 1 name: .res NAME_LEN + 1 diff --git a/libsrc/c64/mcbdefault.s b/libsrc/c64/mcbdefault.s index cd36d8515..dd2f7cee7 100644 --- a/libsrc/c64/mcbdefault.s +++ b/libsrc/c64/mcbdefault.s @@ -30,7 +30,7 @@ VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register ; -------------------------------------------------------------------------- ; Initialize the mouse sprite. -.segment "INIT" +.segment "ONCE" initmcb: diff --git a/libsrc/c64/soft80_charset.s b/libsrc/c64/soft80_charset.s index 69fd3527f..1faa9f775 100644 --- a/libsrc/c64/soft80_charset.s +++ b/libsrc/c64/soft80_charset.s @@ -43,7 +43,7 @@ .export soft80_charset - .segment "INIT" + .segment "ONCE" soft80_charset: .byte $0f,$03,$0f,$00,$0f,$07,$05,$0e .byte $0f,$05,$0e,$0b,$0f,$0b,$0f,$0f diff --git a/libsrc/c64/soft80_conio.s b/libsrc/c64/soft80_conio.s index 874d41a53..48039d288 100644 --- a/libsrc/c64/soft80_conio.s +++ b/libsrc/c64/soft80_conio.s @@ -56,7 +56,7 @@ soft80_shutdown: sta CIA2_PRA jmp $FF5B ; Initialize video I/O - .segment "INIT" + .segment "ONCE" firstinit: ; copy charset to RAM under I/O sei @@ -146,7 +146,7 @@ soft80_bitmapyhi_data: soft80_tables_data_end: ;------------------------------------------------------------------------------- - .segment "INITBSS" + .segment "INIT" soft80_internal_cellcolor: .res 1 soft80_internal_bgcolor: diff --git a/libsrc/c64/soft80mono_conio.s b/libsrc/c64/soft80mono_conio.s index 759b280c6..25c2fc558 100644 --- a/libsrc/c64/soft80mono_conio.s +++ b/libsrc/c64/soft80mono_conio.s @@ -60,7 +60,7 @@ soft80mono_shutdown: sta VIC_VIDEO_ADR rts - .segment "INIT" + .segment "ONCE" firstinit: ; copy charset to RAM under I/O sei @@ -150,7 +150,7 @@ soft80_bitmapyhi_data: soft80_tables_data_end: ;------------------------------------------------------------------------------- - .segment "INITBSS" + .segment "INIT" soft80mono_internal_cellcolor: .res 1 soft80mono_internal_bgcolor: diff --git a/libsrc/c64/systime.s b/libsrc/c64/systime.s index f8cd1b714..c28ace32e 100644 --- a/libsrc/c64/systime.s +++ b/libsrc/c64/systime.s @@ -63,7 +63,7 @@ BCD2dec:tax ; 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 "INIT" +.segment "ONCE" .proc initsystime diff --git a/libsrc/cbm/filevars.s b/libsrc/cbm/filevars.s index db2dec7b3..2cbf0436e 100644 --- a/libsrc/cbm/filevars.s +++ b/libsrc/cbm/filevars.s @@ -9,13 +9,13 @@ .importzp devnum -.segment "INITBSS" +.segment "INIT" curunit: .res 1 -.segment "INIT" +.segment "ONCE" .proc initcurunit diff --git a/libsrc/cbm/mcbpointercolor.s b/libsrc/cbm/mcbpointercolor.s index c9cb6330e..a52830d6b 100644 --- a/libsrc/cbm/mcbpointercolor.s +++ b/libsrc/cbm/mcbpointercolor.s @@ -3,7 +3,7 @@ .export _mouse_def_pointercolor -.segment "INIT" +.segment "ONCE" _mouse_def_pointercolor: diff --git a/libsrc/cbm/mcbpointershape.s b/libsrc/cbm/mcbpointershape.s index 7364201b1..82c7ed91d 100644 --- a/libsrc/cbm/mcbpointershape.s +++ b/libsrc/cbm/mcbpointershape.s @@ -3,7 +3,7 @@ .export _mouse_def_pointershape -.segment "INIT" +.segment "ONCE" _mouse_def_pointershape: diff --git a/libsrc/cbm/read.s b/libsrc/cbm/read.s index e0fd8d51b..87a2c7037 100644 --- a/libsrc/cbm/read.s +++ b/libsrc/cbm/read.s @@ -22,7 +22,7 @@ ;-------------------------------------------------------------------------- ; initstdin: Open the stdin file descriptors for the keyboard -.segment "INIT" +.segment "ONCE" .proc initstdin diff --git a/libsrc/cbm/write.s b/libsrc/cbm/write.s index e6da59c0f..20999d2ac 100644 --- a/libsrc/cbm/write.s +++ b/libsrc/cbm/write.s @@ -20,7 +20,7 @@ ;-------------------------------------------------------------------------- ; initstdout: Open the stdout and stderr file descriptors for the screen. -.segment "INIT" +.segment "ONCE" .proc initstdout diff --git a/libsrc/cbm510/mainargs.s b/libsrc/cbm510/mainargs.s index 0ec7d0c4c..45f35eedb 100644 --- a/libsrc/cbm510/mainargs.s +++ b/libsrc/cbm510/mainargs.s @@ -35,10 +35,10 @@ 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 INIT segment, +; Get possible command-line arguments. Goes into the special ONCE segment, ; which may be reused after the startup code is run. ; -.segment "INIT" +.segment "ONCE" initmainargs: @@ -144,7 +144,7 @@ done: lda #<argv stx __argv + 1 rts -.segment "INITBSS" +.segment "INIT" term: .res 1 name: .res NAME_LEN + 1 diff --git a/libsrc/cbm510/mcbdefault.s b/libsrc/cbm510/mcbdefault.s index 0db753e92..700dcebb1 100644 --- a/libsrc/cbm510/mcbdefault.s +++ b/libsrc/cbm510/mcbdefault.s @@ -31,7 +31,7 @@ VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register ; -------------------------------------------------------------------------- ; Initialize the mouse sprite. -.segment "INIT" +.segment "ONCE" initmcb: diff --git a/libsrc/cbm610/mainargs.s b/libsrc/cbm610/mainargs.s index 02461ac26..9f708698e 100644 --- a/libsrc/cbm610/mainargs.s +++ b/libsrc/cbm610/mainargs.s @@ -35,10 +35,10 @@ 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 INIT segment, +; Get possible command-line arguments. Goes into the special ONCE segment, ; which may be reused after the startup code is run. ; -.segment "INIT" +.segment "ONCE" initmainargs: @@ -142,7 +142,7 @@ done: lda #<argv stx __argv + 1 rts -.segment "INITBSS" +.segment "INIT" term: .res 1 name: .res NAME_LEN + 1 diff --git a/libsrc/common/_cwd.s b/libsrc/common/_cwd.s index 7b4031f52..92276ead9 100644 --- a/libsrc/common/_cwd.s +++ b/libsrc/common/_cwd.s @@ -19,7 +19,7 @@ cwd_init := initcwd -.segment "INITBSS" +.segment "INIT" __cwd: .res __cwd_buf_size diff --git a/libsrc/common/_heap.s b/libsrc/common/_heap.s index 5af434050..e2470577a 100644 --- a/libsrc/common/_heap.s +++ b/libsrc/common/_heap.s @@ -27,7 +27,7 @@ __heaplast: ; Initialization. Will be called from startup! -.segment "INIT" +.segment "ONCE" initheap: sec diff --git a/libsrc/gamate/clock.s b/libsrc/gamate/clock.s index 223c07967..98ad54624 100644 --- a/libsrc/gamate/clock.s +++ b/libsrc/gamate/clock.s @@ -23,7 +23,7 @@ .endproc - .segment "INIT" + .segment "ONCE" initclock: lda #0 ldx #3 diff --git a/libsrc/gamate/conio.s b/libsrc/gamate/conio.s index a43eeb1a3..18d5da674 100644 --- a/libsrc/gamate/conio.s +++ b/libsrc/gamate/conio.s @@ -8,7 +8,7 @@ .macpack longbranch - .segment "INIT" + .segment "ONCE" initconio: lda #0 sta LCD_XPOS diff --git a/libsrc/gamate/irq.s b/libsrc/gamate/irq.s index 862307f58..ddb6ce4ea 100644 --- a/libsrc/gamate/irq.s +++ b/libsrc/gamate/irq.s @@ -10,7 +10,7 @@ .include "extzp.inc" ; ------------------------------------------------------------------------ -.segment "INIT" +.segment "ONCE" ; a constructor ; diff --git a/libsrc/gamate/nmi.s b/libsrc/gamate/nmi.s index 61db62416..a09eea2e5 100644 --- a/libsrc/gamate/nmi.s +++ b/libsrc/gamate/nmi.s @@ -3,7 +3,7 @@ ; .export NMIStub - .segment "INIT" + .segment "ONCE" NMIStub: ; A is saved by the BIOS diff --git a/libsrc/geos-common/conio/_scrsize.s b/libsrc/geos-common/conio/_scrsize.s index 01aac96a4..dded4ca42 100644 --- a/libsrc/geos-common/conio/_scrsize.s +++ b/libsrc/geos-common/conio/_scrsize.s @@ -14,7 +14,7 @@ .include "geossym.inc" -.segment "INIT" +.segment "ONCE" initscrsize: .ifdef __GEOS_CBM__ diff --git a/libsrc/geos-common/system/mainargs.s b/libsrc/geos-common/system/mainargs.s index db829cc0b..14c624759 100644 --- a/libsrc/geos-common/system/mainargs.s +++ b/libsrc/geos-common/system/mainargs.s @@ -18,7 +18,7 @@ .include "const.inc" .include "geossym.inc" -.segment "INIT" +.segment "ONCE" ; Setup arguments for main diff --git a/libsrc/lynx/clock.s b/libsrc/lynx/clock.s index 881c43554..dbccb32cb 100644 --- a/libsrc/lynx/clock.s +++ b/libsrc/lynx/clock.s @@ -78,7 +78,7 @@ update_clock: ;----------------------------------------------------------------------------- ; Enable the interrupt that update_clock needs. ; - .segment "INIT" + .segment "ONCE" init_clock: lda #%10000000 tsb VTIMCTLA diff --git a/libsrc/lynx/defdir.s b/libsrc/lynx/defdir.s index 08358563b..a36848227 100644 --- a/libsrc/lynx/defdir.s +++ b/libsrc/lynx/defdir.s @@ -6,8 +6,8 @@ .include "lynx.inc" .import __STARTOFDIRECTORY__ .import __RAM_START__ - .import __CODE_SIZE__,__DATA_SIZE__,__RODATA_SIZE__ - .import __STARTUP_SIZE__,__INIT_SIZE__,__LOWCODE_SIZE__ + .import __CODE_SIZE__, __DATA_SIZE__, __RODATA_SIZE__ + .import __STARTUP_SIZE__, __ONCE_SIZE__, __LOWCODE_SIZE__ .import __BLOCKSIZE__ .export __DEFDIR__: absolute = 1 @@ -17,15 +17,14 @@ .segment "DIRECTORY" __DIRECTORY_START__: -off0=__STARTOFDIRECTORY__+(__DIRECTORY_END__-__DIRECTORY_START__) -blocka=off0/__BLOCKSIZE__ +off0 = __STARTOFDIRECTORY__ + (__DIRECTORY_END__ - __DIRECTORY_START__) +blocka = off0 / __BLOCKSIZE__ ; Entry 0 - first executable -block0=off0/__BLOCKSIZE__ -len0=__STARTUP_SIZE__+__INIT_SIZE__+__CODE_SIZE__+__DATA_SIZE__+__RODATA_SIZE__+__LOWCODE_SIZE__ +block0 = off0 / __BLOCKSIZE__ +len0 = __STARTUP_SIZE__ + __ONCE_SIZE__ + __CODE_SIZE__ + __DATA_SIZE__ + __RODATA_SIZE__ + __LOWCODE_SIZE__ .byte <block0 .word off0 & (__BLOCKSIZE__ - 1) .byte $88 .word __RAM_START__ .word len0 __DIRECTORY_END__: - diff --git a/libsrc/lynx/irq.s b/libsrc/lynx/irq.s index 4a6adfb04..d3b7976e0 100644 --- a/libsrc/lynx/irq.s +++ b/libsrc/lynx/irq.s @@ -9,7 +9,7 @@ ; ------------------------------------------------------------------------ -.segment "INIT" +.segment "ONCE" initirq: lda #<IRQStub diff --git a/libsrc/lynx/mainargs.s b/libsrc/lynx/mainargs.s index 8ab1b7c68..b402704c2 100644 --- a/libsrc/lynx/mainargs.s +++ b/libsrc/lynx/mainargs.s @@ -10,10 +10,10 @@ ;--------------------------------------------------------------------------- -; Get possible command-line arguments. Goes into the special INIT segment, +; Get possible command-line arguments. Goes into the special ONCE segment, ; which may be reused after the startup code is run -.segment "INIT" +.segment "ONCE" .proc initmainargs diff --git a/libsrc/nes/cputc.s b/libsrc/nes/cputc.s index 10915028b..5bcdc7994 100644 --- a/libsrc/nes/cputc.s +++ b/libsrc/nes/cputc.s @@ -75,10 +75,10 @@ putchar: jmp ppubuf_put ;----------------------------------------------------------------------------- -; Initialize the conio subsystem. Code goes into the INIT segment, which may +; Initialize the conio subsystem. Code goes into the ONCE segment, which may ; be reused after startup. -.segment "INIT" +.segment "ONCE" initconio: jsr ppuinit diff --git a/libsrc/nes/irq.s b/libsrc/nes/irq.s index 9c026f0ed..267d9de0a 100644 --- a/libsrc/nes/irq.s +++ b/libsrc/nes/irq.s @@ -6,7 +6,7 @@ ; ------------------------------------------------------------------------ -.segment "INIT" +.segment "ONCE" initirq: rts diff --git a/libsrc/nes/mainargs.s b/libsrc/nes/mainargs.s index 7ed8d46f4..def01e81d 100644 --- a/libsrc/nes/mainargs.s +++ b/libsrc/nes/mainargs.s @@ -10,10 +10,10 @@ ;--------------------------------------------------------------------------- -; Get possible command-line arguments. Goes into the special INIT segment, +; Get possible command-line arguments. Goes into the special ONCE segment, ; which may be reused after the startup code is run -.segment "INIT" +.segment "ONCE" .proc initmainargs diff --git a/libsrc/osic1p/cgetc.s b/libsrc/osic1p/cgetc.s index 5ddca2870..9161645c7 100644 --- a/libsrc/osic1p/cgetc.s +++ b/libsrc/osic1p/cgetc.s @@ -11,7 +11,7 @@ .include "zeropage.inc" ; Initialize one-character buffer that is filled by kbhit() - .segment "INIT" + .segment "ONCE" initcgetc: lda #$00 sta CHARBUF ; No character in buffer initially diff --git a/libsrc/pce/clock.s b/libsrc/pce/clock.s index 261739df8..828efdc1d 100644 --- a/libsrc/pce/clock.s +++ b/libsrc/pce/clock.s @@ -23,7 +23,7 @@ .endproc - .segment "INIT" + .segment "ONCE" initclock: lda #0 ldx #3 diff --git a/libsrc/pce/conio.s b/libsrc/pce/conio.s index b2bb0f9d5..674b70279 100644 --- a/libsrc/pce/conio.s +++ b/libsrc/pce/conio.s @@ -10,7 +10,7 @@ .macpack longbranch - .segment "INIT" + .segment "ONCE" initconio: jsr vce_init jsr psg_init diff --git a/libsrc/pce/irq.s b/libsrc/pce/irq.s index f34303d07..e0fb68556 100644 --- a/libsrc/pce/irq.s +++ b/libsrc/pce/irq.s @@ -10,7 +10,7 @@ .include "extzp.inc" ; ------------------------------------------------------------------------ -.segment "INIT" +.segment "ONCE" ; a constructor ; diff --git a/libsrc/pce/psg.s b/libsrc/pce/psg.s index b1d610fa1..c3392d9ff 100644 --- a/libsrc/pce/psg.s +++ b/libsrc/pce/psg.s @@ -2,7 +2,7 @@ .export psg_init - .segment "INIT" + .segment "ONCE" psg_init: clx stz PSG_GLOBAL_PAN ; Clear global balance diff --git a/libsrc/pce/vce.s b/libsrc/pce/vce.s index af69c5ed1..70f4d376a 100644 --- a/libsrc/pce/vce.s +++ b/libsrc/pce/vce.s @@ -2,7 +2,7 @@ .export vce_init - .segment "INIT" + .segment "ONCE" vce_init: ; Set CTA to zero stz VCE_ADDR_LO diff --git a/libsrc/pet/crt0.s b/libsrc/pet/crt0.s index c1c805308..520a147f7 100644 --- a/libsrc/pet/crt0.s +++ b/libsrc/pet/crt0.s @@ -94,7 +94,7 @@ L2: lda zpsave,x ; ------------------------------------------------------------------------ -.segment "INITBSS" +.segment "INIT" zpsave: .res zpspace diff --git a/libsrc/pet/irq.s b/libsrc/pet/irq.s index ddaf43ca5..9da45f1df 100644 --- a/libsrc/pet/irq.s +++ b/libsrc/pet/irq.s @@ -9,7 +9,7 @@ ; ------------------------------------------------------------------------ -.segment "INIT" +.segment "ONCE" initirq: lda IRQVec diff --git a/libsrc/pet/mainargs.s b/libsrc/pet/mainargs.s index 8ba6e3117..bc685b699 100644 --- a/libsrc/pet/mainargs.s +++ b/libsrc/pet/mainargs.s @@ -16,10 +16,10 @@ NAME_LEN = 16 ; Maximum length of command-name ;--------------------------------------------------------------------------- -; Get possible command-line arguments. Goes into the special INIT segment, +; Get possible command-line arguments. Goes into the special ONCE segment, ; which may be reused after the startup code is run -.segment "INIT" +.segment "ONCE" .proc initmainargs @@ -111,7 +111,7 @@ done: lda #<argv .endproc -.segment "INITBSS" +.segment "INIT" term: .res 1 name: .res NAME_LEN + 1 diff --git a/libsrc/plus4/cgetc.s b/libsrc/plus4/cgetc.s index 7ff568101..25a63c053 100644 --- a/libsrc/plus4/cgetc.s +++ b/libsrc/plus4/cgetc.s @@ -59,7 +59,7 @@ L2: sta ENABLE_ROM ; Bank in the ROM .constructor initkbd .destructor donekbd -.segment "INIT" ; Special init code segment may get overwritten +.segment "ONCE" ; Special init code segment may get overwritten .proc initkbd diff --git a/libsrc/plus4/crt0.s b/libsrc/plus4/crt0.s index ae3297562..9696d50f4 100644 --- a/libsrc/plus4/crt0.s +++ b/libsrc/plus4/crt0.s @@ -195,7 +195,7 @@ spsave: .res 1 irqcount: .byte 0 -.segment "INITBSS" +.segment "INIT" zpsave: .res zpspace diff --git a/libsrc/plus4/mainargs.s b/libsrc/plus4/mainargs.s index 59879978e..42e2ba029 100644 --- a/libsrc/plus4/mainargs.s +++ b/libsrc/plus4/mainargs.s @@ -32,10 +32,10 @@ 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 INIT segment, +; Get possible command-line arguments. Goes into the special ONCE segment, ; which may be reused after the startup code is run -.segment "INIT" +.segment "ONCE" initmainargs: @@ -125,7 +125,7 @@ done: lda #<argv stx __argv + 1 rts -.segment "INITBSS" +.segment "INIT" term: .res 1 name: .res NAME_LEN + 1 diff --git a/libsrc/runtime/condes.s b/libsrc/runtime/condes.s index c04f71808..a99b713f5 100644 --- a/libsrc/runtime/condes.s +++ b/libsrc/runtime/condes.s @@ -23,7 +23,7 @@ ; -------------------------------------------------------------------------- ; Initialize library modules -.segment "INIT" +.segment "ONCE" .proc initlib diff --git a/libsrc/runtime/stkchk.s b/libsrc/runtime/stkchk.s index 6186fe4e2..ceab4c703 100644 --- a/libsrc/runtime/stkchk.s +++ b/libsrc/runtime/stkchk.s @@ -28,7 +28,7 @@ ; Initialization code. This is a constructor, so it is called on startup if ; the linker has detected references to this module. -.segment "INIT" +.segment "ONCE" .proc initstkchk @@ -101,7 +101,7 @@ Fail: lda #4 ; ---------------------------------------------------------------------------- ; Data -.segment "INITBSS" +.segment "INIT" ; Initial stack pointer value. Stack is reset to this in case of overflows to ; allow program exit processing. diff --git a/libsrc/sim6502/mainargs.s b/libsrc/sim6502/mainargs.s index 1daa23ace..a3c8dee6d 100644 --- a/libsrc/sim6502/mainargs.s +++ b/libsrc/sim6502/mainargs.s @@ -5,7 +5,7 @@ .constructor initmainargs, 24 .import __argc, __argv, args - .segment "INIT" + .segment "ONCE" initmainargs: lda #<__argv diff --git a/libsrc/vic20/crt0.s b/libsrc/vic20/crt0.s index 6a0f94a03..723971168 100644 --- a/libsrc/vic20/crt0.s +++ b/libsrc/vic20/crt0.s @@ -86,7 +86,7 @@ L2: lda zpsave,x ; ------------------------------------------------------------------------ -.segment "INITBSS" +.segment "INIT" zpsave: .res zpspace diff --git a/libsrc/vic20/irq.s b/libsrc/vic20/irq.s index ca47347f8..4c7c832ac 100644 --- a/libsrc/vic20/irq.s +++ b/libsrc/vic20/irq.s @@ -9,7 +9,7 @@ ; ------------------------------------------------------------------------ -.segment "INIT" +.segment "ONCE" initirq: lda IRQVec diff --git a/libsrc/vic20/mainargs.s b/libsrc/vic20/mainargs.s index a41a1c495..b24745c08 100644 --- a/libsrc/vic20/mainargs.s +++ b/libsrc/vic20/mainargs.s @@ -32,10 +32,10 @@ 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 INIT segment, +; Get possible command-line arguments. Goes into the special ONCE segment, ; which may be reused after the startup code is run -.segment "INIT" +.segment "ONCE" initmainargs: @@ -125,7 +125,7 @@ done: lda #<argv stx __argv + 1 rts -.segment "INITBSS" +.segment "INIT" term: .res 1 name: .res NAME_LEN + 1 From d8c31cf1d3b724b83bd411736472e1c16fb1b0c0 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 7 Mar 2016 01:28:55 +0100 Subject: [PATCH 0017/2161] Renamed RAM to MAIN for all disk based targets. The name RAM doesn't make much sense in general for a memeory area because i.e. the zero page is for sure RAM but is not part of the memory area named RAM. For disk based targets it makes sense to put the disk file more into focus and here MAIN means the main part of the file - in contrast to some header. Only for ROM based targets the name RAM is kept as it makes sense to focus on the difference between RAM and ROM. --- cfg/apple2-asm.cfg | 10 ++--- cfg/apple2-overlay.cfg | 42 +++++++++---------- cfg/apple2-system.cfg | 16 +++---- cfg/apple2.cfg | 24 +++++------ cfg/apple2enh-asm.cfg | 10 ++--- cfg/apple2enh-overlay.cfg | 42 +++++++++---------- cfg/apple2enh-system.cfg | 22 +++++----- cfg/apple2enh.cfg | 24 +++++------ cfg/atari-asm.cfg | 34 +++++++-------- cfg/atari-cart.cfg | 30 ++++++------- cfg/atari-cassette.cfg | 26 ++++++------ cfg/atari-overlay.cfg | 50 +++++++++++----------- cfg/atari.cfg | 32 +++++++------- cfg/atarixl-largehimem.cfg | 60 +++++++++++++------------- cfg/atarixl-overlay.cfg | 86 +++++++++++++++++++------------------- cfg/atarixl.cfg | 62 +++++++++++++-------------- cfg/atmos.cfg | 20 ++++----- cfg/bbc.cfg | 20 ++++----- cfg/c128-overlay.cfg | 18 ++++---- cfg/c128.cfg | 18 ++++---- cfg/c16.cfg | 22 +++++----- cfg/c64-asm.cfg | 12 +++--- cfg/cbm510.cfg | 20 ++++----- cfg/cbm610.cfg | 20 ++++----- cfg/gamate.cfg | 14 +++---- cfg/lunix.cfg | 20 ++++----- cfg/lynx-bll.cfg | 16 +++---- cfg/lynx-coll.cfg | 16 +++---- cfg/lynx-uploader.cfg | 16 +++---- cfg/lynx.cfg | 16 +++---- cfg/none.cfg | 18 ++++---- cfg/osic1p-asm.cfg | 16 +++---- cfg/osic1p.cfg | 20 ++++----- cfg/plus4.cfg | 18 ++++---- cfg/sim6502.cfg | 16 +++---- cfg/sim65c02.cfg | 16 +++---- cfg/vic20-32k.cfg | 20 ++++----- cfg/vic20.cfg | 18 ++++---- doc/atari.sgml | 4 +- libsrc/atari/crt0.s | 8 ++-- libsrc/atari/exehdr.s | 4 +- libsrc/atmos/crt0.s | 8 ++-- libsrc/c128/crt0.s | 8 ++-- libsrc/gamate/crt0.s | 6 +-- libsrc/lynx/bllhdr.s | 7 ++-- libsrc/lynx/crt0.s | 8 ++-- libsrc/lynx/defdir.s | 4 +- libsrc/osic1p/bootstrap.s | 12 +++--- libsrc/osic1p/crt0.s | 8 ++-- libsrc/plus4/crt0.s | 10 ++--- libsrc/sim6502/crt0.s | 6 +-- libsrc/vic20/crt0.s | 8 ++-- 52 files changed, 530 insertions(+), 531 deletions(-) diff --git a/cfg/apple2-asm.cfg b/cfg/apple2-asm.cfg index 1e187764c..b9095cf0c 100644 --- a/cfg/apple2-asm.cfg +++ b/cfg/apple2-asm.cfg @@ -10,13 +10,13 @@ SYMBOLS { MEMORY { ZP: start = $0080, size = $001A, define = yes; HEADER: file = %O, start = $0000, size = $0004; - RAM: file = %O, start = %S, size = $C000 - %S; + MAIN: file = %O, start = %S, size = $C000 - %S; } SEGMENTS { ZEROPAGE: load = ZP, type = zp, optional = yes; EXEHDR: load = HEADER, type = ro, optional = yes; - CODE: load = RAM, type = rw, optional = yes, define = yes; - RODATA: load = RAM, type = ro, optional = yes; - DATA: load = RAM, type = rw, optional = yes; - BSS: load = RAM, type = bss, optional = yes, define = yes; + CODE: load = MAIN, type = rw, optional = yes, define = yes; + 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/apple2-overlay.cfg b/cfg/apple2-overlay.cfg index ef9103b49..1e34b6250 100644 --- a/cfg/apple2-overlay.cfg +++ b/cfg/apple2-overlay.cfg @@ -24,7 +24,7 @@ SYMBOLS { MEMORY { ZP: define = yes, start = $0080, size = $001A; HEADER: file = %O, start = $0000, size = $0004; - RAM: file = %O, start = %S + __OVERLAYSIZE__, size = __HIMEM__ - __STACKSIZE__ - __OVERLAYSIZE__ - %S; + MAIN: file = %O, start = %S + __OVERLAYSIZE__, size = __HIMEM__ - __STACKSIZE__ - __OVERLAYSIZE__ - %S; MOVE: file = %O, define = yes, start = $0000, size = $FFFF; LC: define = yes, start = __LCADDR__, size = __LCSIZE__; OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__; @@ -38,26 +38,26 @@ MEMORY { OVL9: file = "%O.9", start = %S, size = __OVERLAYSIZE__; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp; - EXEHDR: load = HEADER, type = ro; - STARTUP: load = RAM, type = ro, define = yes; - LOWCODE: load = RAM, type = ro, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss, define = yes; - BSS: load = RAM, type = bss, define = yes; - ONCE: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; - LC: load = MOVE, run = LC, type = ro, 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; - OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes; - OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes; - OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes; - OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes; - OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes; - OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes; + ZEROPAGE: load = ZP, type = zp; + EXEHDR: load = HEADER, type = ro; + STARTUP: load = MAIN, type = ro, define = 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 = bss, define = yes; + BSS: load = MAIN, type = bss, define = yes; + ONCE: load = MOVE, run = MAIN, type = ro, define = yes, optional = yes; + LC: load = MOVE, run = LC, type = ro, 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; + OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes; + OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes; + OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes; + OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes; + OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes; + OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/apple2-system.cfg b/cfg/apple2-system.cfg index 52cad960f..960be378c 100644 --- a/cfg/apple2-system.cfg +++ b/cfg/apple2-system.cfg @@ -10,19 +10,19 @@ SYMBOLS { } MEMORY { ZP: define = yes, start = $0080, size = $001A; - RAM: file = %O, start = $2000, size = $9F00 - __STACKSIZE__; + MAIN: file = %O, start = $2000, size = $9F00 - __STACKSIZE__; MOVE: file = %O, define = yes, start = $0000, size = $FFFF; LC: define = yes, start = __LCADDR__, size = __LCSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; - STARTUP: load = RAM, type = ro, define = yes; - LOWCODE: load = RAM, type = ro, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss, define = yes; - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro, define = 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 = bss, define = yes; + BSS: load = MAIN, type = bss, define = yes; ONCE: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; LC: load = MOVE, run = LC, type = ro, optional = yes; } diff --git a/cfg/apple2.cfg b/cfg/apple2.cfg index 8e63090f5..875103041 100644 --- a/cfg/apple2.cfg +++ b/cfg/apple2.cfg @@ -16,22 +16,22 @@ SYMBOLS { MEMORY { ZP: define = yes, start = $0080, size = $001A; HEADER: file = %O, start = $0000, size = $0004; - RAM: file = %O, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S; + MAIN: file = %O, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S; MOVE: file = %O, define = yes, start = $0000, size = $FFFF; LC: define = yes, start = __LCADDR__, size = __LCSIZE__; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp; - EXEHDR: load = HEADER, type = ro; - STARTUP: load = RAM, type = ro, define = yes; - LOWCODE: load = RAM, type = ro, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss, define = yes; - BSS: load = RAM, type = bss, define = yes; - ONCE: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; - LC: load = MOVE, run = LC, type = ro, optional = yes; + ZEROPAGE: load = ZP, type = zp; + EXEHDR: load = HEADER, type = ro; + STARTUP: load = MAIN, type = ro, define = 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 = bss, define = yes; + BSS: load = MAIN, type = bss, define = yes; + ONCE: load = MOVE, run = MAIN, type = ro, define = yes, optional = yes; + LC: load = MOVE, run = LC, type = ro, optional = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/apple2enh-asm.cfg b/cfg/apple2enh-asm.cfg index e70ed4484..f7ede1bfe 100644 --- a/cfg/apple2enh-asm.cfg +++ b/cfg/apple2enh-asm.cfg @@ -9,12 +9,12 @@ SYMBOLS { } MEMORY { HEADER: file = %O, start = $0000, size = $0004; - RAM: file = %O, start = %S, size = $C000 - %S; + MAIN: file = %O, start = %S, size = $C000 - %S; } SEGMENTS { EXEHDR: load = HEADER, type = ro, optional = yes; - CODE: load = RAM, type = rw, optional = yes, define = yes; - RODATA: load = RAM, type = ro, optional = yes; - DATA: load = RAM, type = rw, optional = yes; - BSS: load = RAM, type = bss, optional = yes, define = yes; + CODE: load = MAIN, type = rw, optional = yes, define = yes; + 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/apple2enh-overlay.cfg b/cfg/apple2enh-overlay.cfg index ef9103b49..1e34b6250 100644 --- a/cfg/apple2enh-overlay.cfg +++ b/cfg/apple2enh-overlay.cfg @@ -24,7 +24,7 @@ SYMBOLS { MEMORY { ZP: define = yes, start = $0080, size = $001A; HEADER: file = %O, start = $0000, size = $0004; - RAM: file = %O, start = %S + __OVERLAYSIZE__, size = __HIMEM__ - __STACKSIZE__ - __OVERLAYSIZE__ - %S; + MAIN: file = %O, start = %S + __OVERLAYSIZE__, size = __HIMEM__ - __STACKSIZE__ - __OVERLAYSIZE__ - %S; MOVE: file = %O, define = yes, start = $0000, size = $FFFF; LC: define = yes, start = __LCADDR__, size = __LCSIZE__; OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__; @@ -38,26 +38,26 @@ MEMORY { OVL9: file = "%O.9", start = %S, size = __OVERLAYSIZE__; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp; - EXEHDR: load = HEADER, type = ro; - STARTUP: load = RAM, type = ro, define = yes; - LOWCODE: load = RAM, type = ro, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss, define = yes; - BSS: load = RAM, type = bss, define = yes; - ONCE: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; - LC: load = MOVE, run = LC, type = ro, 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; - OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes; - OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes; - OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes; - OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes; - OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes; - OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes; + ZEROPAGE: load = ZP, type = zp; + EXEHDR: load = HEADER, type = ro; + STARTUP: load = MAIN, type = ro, define = 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 = bss, define = yes; + BSS: load = MAIN, type = bss, define = yes; + ONCE: load = MOVE, run = MAIN, type = ro, define = yes, optional = yes; + LC: load = MOVE, run = LC, type = ro, 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; + OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes; + OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes; + OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes; + OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes; + OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes; + OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/apple2enh-system.cfg b/cfg/apple2enh-system.cfg index 52cad960f..6134851f0 100644 --- a/cfg/apple2enh-system.cfg +++ b/cfg/apple2enh-system.cfg @@ -10,21 +10,21 @@ SYMBOLS { } MEMORY { ZP: define = yes, start = $0080, size = $001A; - RAM: file = %O, start = $2000, size = $9F00 - __STACKSIZE__; + MAIN: file = %O, start = $2000, size = $9F00 - __STACKSIZE__; MOVE: file = %O, define = yes, start = $0000, size = $FFFF; LC: define = yes, start = __LCADDR__, size = __LCSIZE__; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp; - STARTUP: load = RAM, type = ro, define = yes; - LOWCODE: load = RAM, type = ro, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss, define = yes; - BSS: load = RAM, type = bss, define = yes; - ONCE: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; - LC: load = MOVE, run = LC, type = ro, optional = yes; + ZEROPAGE: load = ZP, type = zp; + STARTUP: load = MAIN, type = ro, define = 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 = bss, define = yes; + BSS: load = MAIN, type = bss, define = yes; + ONCE: load = MOVE, run = MAIN, type = ro, define = yes, optional = yes; + LC: load = MOVE, run = LC, type = ro, optional = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/apple2enh.cfg b/cfg/apple2enh.cfg index 8e63090f5..875103041 100644 --- a/cfg/apple2enh.cfg +++ b/cfg/apple2enh.cfg @@ -16,22 +16,22 @@ SYMBOLS { MEMORY { ZP: define = yes, start = $0080, size = $001A; HEADER: file = %O, start = $0000, size = $0004; - RAM: file = %O, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S; + MAIN: file = %O, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S; MOVE: file = %O, define = yes, start = $0000, size = $FFFF; LC: define = yes, start = __LCADDR__, size = __LCSIZE__; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp; - EXEHDR: load = HEADER, type = ro; - STARTUP: load = RAM, type = ro, define = yes; - LOWCODE: load = RAM, type = ro, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss, define = yes; - BSS: load = RAM, type = bss, define = yes; - ONCE: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; - LC: load = MOVE, run = LC, type = ro, optional = yes; + ZEROPAGE: load = ZP, type = zp; + EXEHDR: load = HEADER, type = ro; + STARTUP: load = MAIN, type = ro, define = 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 = bss, define = yes; + BSS: load = MAIN, type = bss, define = yes; + ONCE: load = MOVE, run = MAIN, type = ro, define = yes, optional = yes; + LC: load = MOVE, run = LC, type = ro, optional = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/atari-asm.cfg b/cfg/atari-asm.cfg index 4ff7c3173..bea547765 100644 --- a/cfg/atari-asm.cfg +++ b/cfg/atari-asm.cfg @@ -2,29 +2,29 @@ FEATURES { STARTADDRESS: default = $2E00; } SYMBOLS { - __EXEHDR__: type = import; - __AUTOSTART__: type = import; # force inclusion of autostart "trailer" - __STARTADDRESS__: type = export, value = %S; + __EXEHDR__: type = import; + __AUTOSTART__: type = import; # force inclusion of autostart "trailer" + __STARTADDRESS__: type = export, value = %S; } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # file header, just $FFFF - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $0002; # "main program" load chunk - MAINHDR: file = %O, start = $0000, size = $0004; - RAM: file = %O, define = yes, start = %S, size = $BC20 - %S; - TRAILER: file = %O, start = $0000, size = $0006; + MAINHDR: file = %O, start = $0000, size = $0004; + MAIN: file = %O, define = yes, start = %S, size = $BC20 - %S; + TRAILER: file = %O, start = $0000, size = $0006; } SEGMENTS { - EXEHDR: load = HEADER, type = ro, optional = yes; - MAINHDR: load = MAINHDR, type = ro, optional = yes; - CODE: load = RAM, type = ro, define = yes, optional = yes; - RODATA: load = RAM, type = ro optional = yes; - DATA: load = RAM, type = rw optional = yes; - BSS: load = RAM, type = bss, define = yes, optional = yes; - ZEROPAGE: load = ZP, type = zp, optional = yes; - EXTZP: load = ZP, type = zp, optional = yes; # to enable modules to be able to link to C and assembler programs - AUTOSTRT: load = TRAILER, type = ro, optional = yes; + ZEROPAGE: load = ZP, type = zp, optional = yes; + EXTZP: load = ZP, type = zp, optional = yes; # to enable modules to be able to link to C and assembler programs + EXEHDR: load = HEADER, type = ro, optional = yes; + MAINHDR: load = MAINHDR, type = ro, optional = yes; + CODE: load = MAIN, type = ro, define = yes, optional = yes; + RODATA: load = MAIN, type = ro optional = yes; + DATA: load = MAIN, type = rw optional = yes; + BSS: load = MAIN, type = bss, define = yes, optional = yes; + AUTOSTRT: load = TRAILER, type = ro, optional = yes; } diff --git a/cfg/atari-cart.cfg b/cfg/atari-cart.cfg index 09bf86761..31d2cb1b9 100644 --- a/cfg/atari-cart.cfg +++ b/cfg/atari-cart.cfg @@ -10,23 +10,23 @@ SYMBOLS { __CARTFLAGS__: type = weak, value = $01; # see documentation for other possible values } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; - RAM: file = "", define = yes, start = %S, size = __CARTSIZE__; - ROM: file = %O, define = yes, start = $C000 - __CARTSIZE__, size = __CARTSIZE__ - 6, fill = yes, fillval = $FF; - CARTID: file = %O, start = $BFFA, size = $0006; + ZP: file = "", define = yes, start = $0082, size = $007E; + MAIN: file = "", define = yes, start = %S, size = __CARTSIZE__; + ROM: file = %O, define = yes, start = $C000 - __CARTSIZE__, size = __CARTSIZE__ - 6, fill = yes, fillval = $FF; + CARTID: file = %O, start = $BFFA, size = $0006; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp, optional = yes; - EXTZP: load = ZP, type = zp, 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; - CODE: load = ROM, type = ro, define = yes; - RODATA: load = ROM, type = ro, optional = yes; - DATA: load = ROM, run = RAM, type = rw, define = yes, optional = yes; - INIT: load = RAM, type = bss, optional = yes; - BSS: load = RAM, type = bss, define = yes, optional = yes; - CARTHDR: load = CARTID, type = ro; + ZEROPAGE: load = ZP, type = zp, optional = yes; + EXTZP: load = ZP, type = zp, 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; + CODE: load = ROM, type = ro, define = yes; + RODATA: load = ROM, type = ro, optional = yes; + DATA: load = ROM, run = MAIN, type = rw, define = yes, optional = yes; + INIT: load = MAIN, type = bss, optional = yes; + BSS: load = MAIN, type = bss, define = yes, optional = yes; + CARTHDR: load = CARTID, type = ro; } FEATURES { CONDES: type = constructor, diff --git a/cfg/atari-cassette.cfg b/cfg/atari-cassette.cfg index ad68bb8b4..b138b8f0e 100644 --- a/cfg/atari-cassette.cfg +++ b/cfg/atari-cassette.cfg @@ -8,21 +8,21 @@ SYMBOLS { _cas_hdr: type = import; } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; - RAM: file = %O, define = yes, start = %S, size = $BC20 - __STACKSIZE__ - __RESERVED_MEMORY__ - %S; + ZP: file = "", define = yes, start = $0082, size = $007E; + MAIN: file = %O, define = yes, start = %S, size = $BC20 - __STACKSIZE__ - __RESERVED_MEMORY__ - %S; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp, optional = yes; - EXTZP: load = ZP, type = zp, optional = yes; - CASHDR: load = RAM, type = ro; - STARTUP: load = RAM, type = ro, define = yes, optional = yes; - LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - ONCE: load = RAM, type = ro, optional = yes; - CODE: load = RAM, type = ro, define = yes; - RODATA: load = RAM, type = ro, optional = yes; - DATA: load = RAM, type = rw, optional = yes; - INIT: load = RAM, type = bss, optional = yes; - BSS: load = RAM, type = bss, define = yes, optional = yes; + ZEROPAGE: load = ZP, type = zp, optional = yes; + EXTZP: load = ZP, type = zp, optional = yes; + CASHDR: load = MAIN, type = ro; + STARTUP: load = MAIN, type = ro, define = yes, optional = yes; + LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; + 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, optional = yes; + BSS: load = MAIN, type = bss, define = yes, optional = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/atari-overlay.cfg b/cfg/atari-overlay.cfg index b14a93a39..1dec49b7d 100644 --- a/cfg/atari-overlay.cfg +++ b/cfg/atari-overlay.cfg @@ -11,31 +11,31 @@ SYMBOLS { __RESERVED_MEMORY__: type = weak, value = $0000; } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # file header, just $FFFF - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $0002; # "system check" load chunk - SYSCHKHDR: file = %O, start = $0000, size = $0004; - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; - SYSCHKTRL: file = %O, start = $0000, size = $0006; + SYSCHKHDR: file = %O, start = $0000, size = $0004; + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + SYSCHKTRL: file = %O, start = $0000, size = $0006; # "main program" load chunk - MAINHDR: file = %O, start = $0000, size = $0004; - RAM: file = %O, define = yes, start = %S + __OVERLAYSIZE__, + MAINHDR: file = %O, start = $0000, size = $0004; + MAIN: file = %O, define = yes, start = %S + __OVERLAYSIZE__, size = $BC20 - __OVERLAYSIZE__ - __STACKSIZE__ - __RESERVED_MEMORY__ - %S; - TRAILER: file = %O, start = $0000, size = $0006; + TRAILER: file = %O, start = $0000, size = $0006; - OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__; - OVL2: file = "%O.2", start = %S, size = __OVERLAYSIZE__; - OVL3: file = "%O.3", start = %S, size = __OVERLAYSIZE__; - OVL4: file = "%O.4", start = %S, size = __OVERLAYSIZE__; - OVL5: file = "%O.5", start = %S, size = __OVERLAYSIZE__; - OVL6: file = "%O.6", start = %S, size = __OVERLAYSIZE__; - OVL7: file = "%O.7", start = %S, size = __OVERLAYSIZE__; - OVL8: file = "%O.8", start = %S, size = __OVERLAYSIZE__; - OVL9: file = "%O.9", start = %S, size = __OVERLAYSIZE__; + OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__; + OVL2: file = "%O.2", start = %S, size = __OVERLAYSIZE__; + OVL3: file = "%O.3", start = %S, size = __OVERLAYSIZE__; + OVL4: file = "%O.4", start = %S, size = __OVERLAYSIZE__; + OVL5: file = "%O.5", start = %S, size = __OVERLAYSIZE__; + OVL6: file = "%O.6", start = %S, size = __OVERLAYSIZE__; + OVL7: file = "%O.7", start = %S, size = __OVERLAYSIZE__; + OVL8: file = "%O.8", start = %S, size = __OVERLAYSIZE__; + OVL9: file = "%O.9", start = %S, size = __OVERLAYSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; @@ -45,14 +45,14 @@ SEGMENTS { SYSCHK: load = SYSCHKCHNK, type = rw, define = yes, optional = yes; SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes; MAINHDR: load = MAINHDR, type = ro; - STARTUP: load = RAM, type = ro, define = yes; - LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - ONCE: load = RAM, type = ro, optional = yes; - CODE: load = RAM, type = ro, define = yes; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss, optional = yes; - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro, define = yes; + LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; + CODE: load = MAIN, type = ro, define = yes; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = bss, optional = yes; + BSS: load = MAIN, type = bss, define = yes; AUTOSTRT: load = TRAILER, type = ro; OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes; diff --git a/cfg/atari.cfg b/cfg/atari.cfg index 7460a0f66..959a07e4c 100644 --- a/cfg/atari.cfg +++ b/cfg/atari.cfg @@ -10,20 +10,20 @@ SYMBOLS { __RESERVED_MEMORY__: type = weak, value = $0000; } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # file header, just $FFFF - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $0002; # "system check" load chunk - SYSCHKHDR: file = %O, start = $0000, size = $0004; - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; - SYSCHKTRL: file = %O, start = $0000, size = $0006; + SYSCHKHDR: file = %O, start = $0000, size = $0004; + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + SYSCHKTRL: file = %O, start = $0000, size = $0006; # "main program" load chunk - MAINHDR: file = %O, start = $0000, size = $0004; - RAM: file = %O, define = yes, start = %S, size = $BC20 - __STACKSIZE__ - __RESERVED_MEMORY__ - %S; - TRAILER: file = %O, start = $0000, size = $0006; + MAINHDR: file = %O, start = $0000, size = $0004; + MAIN: file = %O, define = yes, start = %S, size = $BC20 - __STACKSIZE__ - __RESERVED_MEMORY__ - %S; + TRAILER: file = %O, start = $0000, size = $0006; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; @@ -33,14 +33,14 @@ SEGMENTS { SYSCHK: load = SYSCHKCHNK, type = rw, define = yes, optional = yes; SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes; MAINHDR: load = MAINHDR, type = ro; - STARTUP: load = RAM, type = ro, define = yes; - LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - ONCE: load = RAM, type = ro, optional = yes; - CODE: load = RAM, type = ro, define = yes; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss, optional = yes; - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro, define = yes; + LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; + CODE: load = MAIN, type = ro, define = yes; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = bss, optional = yes; + BSS: load = MAIN, type = bss, define = yes; AUTOSTRT: load = TRAILER, type = ro; } FEATURES { diff --git a/cfg/atarixl-largehimem.cfg b/cfg/atarixl-largehimem.cfg index a1ec5cf08..94405fce2 100644 --- a/cfg/atarixl-largehimem.cfg +++ b/cfg/atarixl-largehimem.cfg @@ -8,45 +8,45 @@ FEATURES { } SYMBOLS { - __EXEHDR__: type = import; - __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk - __AUTOSTART__: type = import; # force inclusion of autostart "trailer" - __STACKSIZE__: type = weak, value = $0800; # 2k stack - __STARTADDRESS__: type = export, value = %S; + __EXEHDR__: type = import; + __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk + __AUTOSTART__: type = import; # force inclusion of autostart "trailer" + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __STARTADDRESS__: type = export, value = %S; } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # just $FFFF - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $0002; # "system check" load chunk - SYSCHKHDR: file = %O, start = $0000, size = $0004; - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; - SYSCHKTRL: file = %O, start = $0000, size = $0006; + SYSCHKHDR: file = %O, start = $0000, size = $0004; + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + SYSCHKTRL: file = %O, start = $0000, size = $0006; # "shadow RAM preparation" load chunk - SRPREPHDR: file = %O, start = $0000, size = $0004; - SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned - SRPREPTRL: file = %O, start = $0000, size = $0006; + SRPREPHDR: file = %O, start = $0000, size = $0004; + SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned + SRPREPTRL: file = %O, start = $0000, size = $0006; # "main program" load chunk - MAINHDR: file = %O, start = $0000, size = $0004; - RAM: file = %O, define = yes, start = %S + - __LOWBSS_SIZE__, size = $D000 - - __STACKSIZE__ - - %S - - __LOWBSS_SIZE__; + MAINHDR: file = %O, start = $0000, size = $0004; + MAIN: file = %O, define = yes, start = %S + + __LOWBSS_SIZE__, size = $D000 - + __STACKSIZE__ - + %S - + __LOWBSS_SIZE__; # defines entry point into program - TRAILER: file = %O, start = $0000, size = $0006; + TRAILER: file = %O, start = $0000, size = $0006; # address of relocated character generator - CHARGEN: file = "", define = yes, start = $D800, size = $0400; + CHARGEN: file = "", define = yes, start = $D800, size = $0400; # memory beneath the ROM - HIDDEN_RAM: file = "", define = yes, start = $DC00, size = $FFFA - $DC00; + HIDDEN_RAM: file = "", define = yes, start = $DC00, size = $FFFA - $DC00; } SEGMENTS { @@ -67,14 +67,14 @@ SEGMENTS { SRPREPTRL: load = SRPREPTRL, type = ro; MAINHDR: load = MAINHDR, type = ro; - STARTUP: load = RAM, type = ro, define = yes; - LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - ONCE: load = RAM, type = ro, optional = yes; - CODE: load = RAM, type = ro, define = yes; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss, optional = yes; - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro, define = yes; + LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; + CODE: load = MAIN, type = ro, define = yes; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = bss, optional = yes; + BSS: load = MAIN, type = bss, define = yes; AUTOSTRT: load = TRAILER, type = ro; } FEATURES { diff --git a/cfg/atarixl-overlay.cfg b/cfg/atarixl-overlay.cfg index b0b4f3b88..89240170b 100644 --- a/cfg/atarixl-overlay.cfg +++ b/cfg/atarixl-overlay.cfg @@ -3,62 +3,62 @@ FEATURES { } SYMBOLS { - __EXEHDR__: type = import; - __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk - __AUTOSTART__: type = import; # force inclusion of autostart "trailer" - __STACKSIZE__: type = weak, value = $0800; # 2k stack - __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay - __STARTADDRESS__: type = export, value = %S; + __EXEHDR__: type = import; + __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk + __AUTOSTART__: type = import; # force inclusion of autostart "trailer" + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay + __STARTADDRESS__: type = export, value = %S; } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # just $FFFF - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $0002; # "system check" load chunk - SYSCHKHDR: file = %O, start = $0000, size = $0004; - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; - SYSCHKTRL: file = %O, start = $0000, size = $0006; + SYSCHKHDR: file = %O, start = $0000, size = $0004; + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + SYSCHKTRL: file = %O, start = $0000, size = $0006; # "shadow RAM preparation" load chunk - SRPREPHDR: file = %O, start = $0000, size = $0004; - SRPREPCHNK: file = %O, define = yes, start = %S + __OVERLAYSIZE__, size = $7C20 - %S - __OVERLAYSIZE__ - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned - SRPREPTRL: file = %O, start = $0000, size = $0006; + SRPREPHDR: file = %O, start = $0000, size = $0004; + SRPREPCHNK: file = %O, define = yes, start = %S + __OVERLAYSIZE__, size = $7C20 - %S - __OVERLAYSIZE__ - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned + SRPREPTRL: file = %O, start = $0000, size = $0006; # "main program" load chunk - MAINHDR: file = %O, start = $0000, size = $0004; - RAM: file = %O, define = yes, start = %S + - __OVERLAYSIZE__ + - __LOWBSS_SIZE__, size = $D000 - - __STACKSIZE__ - - %S - - __OVERLAYSIZE__ - - __LOWBSS_SIZE__; + MAINHDR: file = %O, start = $0000, size = $0004; + MAIN: file = %O, define = yes, start = %S + + __OVERLAYSIZE__ + + __LOWBSS_SIZE__, size = $D000 - + __STACKSIZE__ - + %S - + __OVERLAYSIZE__ - + __LOWBSS_SIZE__; # defines entry point into program - TRAILER: file = %O, start = $0000, size = $0006; + TRAILER: file = %O, start = $0000, size = $0006; # memory beneath the ROM preceeding the character generator - HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; + HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; # address of relocated character generator (same addess as ROM version) - CHARGEN: file = "", define = yes, start = $E000, size = $0400; + CHARGEN: file = "", define = yes, start = $E000, size = $0400; # memory beneath the ROM - HIDDEN_RAM: file = "", define = yes, start = $E400, size = $FFFA - $E400; + HIDDEN_RAM: file = "", define = yes, start = $E400, size = $FFFA - $E400; # overlays - OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__; - OVL2: file = "%O.2", start = %S, size = __OVERLAYSIZE__; - OVL3: file = "%O.3", start = %S, size = __OVERLAYSIZE__; - OVL4: file = "%O.4", start = %S, size = __OVERLAYSIZE__; - OVL5: file = "%O.5", start = %S, size = __OVERLAYSIZE__; - OVL6: file = "%O.6", start = %S, size = __OVERLAYSIZE__; - OVL7: file = "%O.7", start = %S, size = __OVERLAYSIZE__; - OVL8: file = "%O.8", start = %S, size = __OVERLAYSIZE__; - OVL9: file = "%O.9", start = %S, size = __OVERLAYSIZE__; + OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__; + OVL2: file = "%O.2", start = %S, size = __OVERLAYSIZE__; + OVL3: file = "%O.3", start = %S, size = __OVERLAYSIZE__; + OVL4: file = "%O.4", start = %S, size = __OVERLAYSIZE__; + OVL5: file = "%O.5", start = %S, size = __OVERLAYSIZE__; + OVL6: file = "%O.6", start = %S, size = __OVERLAYSIZE__; + OVL7: file = "%O.7", start = %S, size = __OVERLAYSIZE__; + OVL8: file = "%O.8", start = %S, size = __OVERLAYSIZE__; + OVL9: file = "%O.9", start = %S, size = __OVERLAYSIZE__; } SEGMENTS { @@ -79,14 +79,14 @@ SEGMENTS { SRPREPTRL: load = SRPREPTRL, type = ro; MAINHDR: load = MAINHDR, type = ro; - STARTUP: load = RAM, type = ro, define = yes; - LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - ONCE: load = RAM, type = ro, optional = yes; - CODE: load = RAM, type = ro, define = yes; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss, optional = yes; - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro, define = yes; + LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; + CODE: load = MAIN, type = ro, define = yes; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = bss, 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/atarixl.cfg b/cfg/atarixl.cfg index 2f9523c59..9573fc78c 100644 --- a/cfg/atarixl.cfg +++ b/cfg/atarixl.cfg @@ -3,48 +3,48 @@ FEATURES { } SYMBOLS { - __EXEHDR__: type = import; - __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk - __AUTOSTART__: type = import; # force inclusion of autostart "trailer" - __STACKSIZE__: type = weak, value = $0800; # 2k stack - __STARTADDRESS__: type = export, value = %S; + __EXEHDR__: type = import; + __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk + __AUTOSTART__: type = import; # force inclusion of autostart "trailer" + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __STARTADDRESS__: type = export, value = %S; } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # just $FFFF - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $0002; # "system check" load chunk - SYSCHKHDR: file = %O, start = $0000, size = $0004; - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; - SYSCHKTRL: file = %O, start = $0000, size = $0006; + SYSCHKHDR: file = %O, start = $0000, size = $0004; + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + SYSCHKTRL: file = %O, start = $0000, size = $0006; # "shadow RAM preparation" load chunk - SRPREPHDR: file = %O, start = $0000, size = $0004; - SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned - SRPREPTRL: file = %O, start = $0000, size = $0006; + SRPREPHDR: file = %O, start = $0000, size = $0004; + SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned + SRPREPTRL: file = %O, start = $0000, size = $0006; # "main program" load chunk - MAINHDR: file = %O, start = $0000, size = $0004; - RAM: file = %O, define = yes, start = %S + - __LOWBSS_SIZE__, size = $D000 - - __STACKSIZE__ - - %S - - __LOWBSS_SIZE__; + MAINHDR: file = %O, start = $0000, size = $0004; + MAIN: file = %O, define = yes, start = %S + + __LOWBSS_SIZE__, size = $D000 - + __STACKSIZE__ - + %S - + __LOWBSS_SIZE__; # defines entry point into program - TRAILER: file = %O, start = $0000, size = $0006; + TRAILER: file = %O, start = $0000, size = $0006; # memory beneath the ROM preceeding the character generator - HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; + HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; # address of relocated character generator (same addess as ROM version) - CHARGEN: file = "", define = yes, start = $E000, size = $0400; + CHARGEN: file = "", define = yes, start = $E000, size = $0400; # memory beneath the ROM - HIDDEN_RAM: file = "", define = yes, start = $E400, size = $FFFA - $E400; + HIDDEN_RAM: file = "", define = yes, start = $E400, size = $FFFA - $E400; } SEGMENTS { @@ -65,14 +65,14 @@ SEGMENTS { SRPREPTRL: load = SRPREPTRL, type = ro; MAINHDR: load = MAINHDR, type = ro; - STARTUP: load = RAM, type = ro, define = yes; - LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - ONCE: load = RAM, type = ro, optional = yes; - CODE: load = RAM, type = ro, define = yes; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss, optional = yes; - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro, define = yes; + LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; + CODE: load = MAIN, type = ro, define = yes; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = bss, optional = yes; + BSS: load = MAIN, type = bss, define = yes; AUTOSTRT: load = TRAILER, type = ro; } FEATURES { diff --git a/cfg/atmos.cfg b/cfg/atmos.cfg index a0f7e1c3d..e5a574f0a 100644 --- a/cfg/atmos.cfg +++ b/cfg/atmos.cfg @@ -11,21 +11,21 @@ MEMORY { ZP: file = "", define = yes, start = $00E2, size = $001A; TAPEHDR: file = %O, type = ro, start = $0000, size = $001F; BASHEAD: file = %O, define = yes, start = $0501, size = $000D; - RAM: file = %O, define = yes, start = __BASHEAD_LAST__, size = __RAMEND__ - __RAM_START__ - __STACKSIZE__; + MAIN: file = %O, define = yes, start = __BASHEAD_LAST__, size = __RAMEND__ - __RAM_START__ - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; TAPEHDR: load = TAPEHDR, type = ro; BASHDR: load = BASHEAD, type = ro, define = yes, optional = yes; - STARTUP: load = RAM, type = ro; - LOWCODE: load = RAM, type = ro, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - DATA: load = RAM, type = rw; - ZPSAVE1: load = RAM, type = rw, define = yes; # ZPSAVE1, ZPSAVE2 must be together - ZPSAVE2: load = RAM, type = bss; # see "libsrc/atmos/crt0.s" - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro; + LOWCODE: load = MAIN, type = ro, optional = yes; + CODE: load = MAIN, type = ro; + RODATA: load = MAIN, type = ro; + ONCE: load = MAIN, type = ro, define = yes, optional = yes; + DATA: load = MAIN, type = rw; + ZPSAVE1: load = MAIN, type = rw, define = yes; # ZPSAVE1, ZPSAVE2 must be together + ZPSAVE2: load = MAIN, type = bss; # see "libsrc/atmos/crt0.s" + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/bbc.cfg b/cfg/bbc.cfg index 98779b6fd..c451951ad 100644 --- a/cfg/bbc.cfg +++ b/cfg/bbc.cfg @@ -2,18 +2,18 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack } MEMORY { - ZP: file = "", define = yes, start = $0070, size = $0020; - RAM: file = %O, start = $0E00, size = $7200 - __STACKSIZE__; + ZP: file = "", define = yes, start = $0070, size = $0020; + MAIN: file = %O, start = $0E00, size = $7200 - __STACKSIZE__; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp; - STARTUP: load = RAM, type = ro, define = yes; - LOWCODE: load = RAM, type = ro, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - BSS: load = RAM, type = bss, define = yes; + ZEROPAGE: load = ZP, type = zp; + STARTUP: load = MAIN, type = ro, define = yes; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, define = yes, optional = yes; + CODE: load = MAIN, type = ro; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/c128-overlay.cfg b/cfg/c128-overlay.cfg index 771bd290b..8f60fa347 100644 --- a/cfg/c128-overlay.cfg +++ b/cfg/c128-overlay.cfg @@ -9,7 +9,7 @@ MEMORY { ZP: file = "", define = yes, start = $0002, size = $001A; LOADADDR: file = %O, start = $1BFF, size = $0002; HEADER: file = %O, start = $1C01, size = $000C; - RAM: file = %O, define = yes, start = $1C0D, size = $A3F3 - __OVERLAYSIZE__ - __STACKSIZE__; + MAIN: file = %O, define = yes, start = $1C0D, size = $A3F3 - __OVERLAYSIZE__ - __STACKSIZE__; OVL1ADDR: file = "%O.1", start = $BFFE - __OVERLAYSIZE__, size = $0002; OVL1: file = "%O.1", start = $C000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__; OVL2ADDR: file = "%O.2", start = $BFFE - __OVERLAYSIZE__, size = $0002; @@ -33,14 +33,14 @@ SEGMENTS { ZEROPAGE: load = ZP, type = zp; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; - STARTUP: load = RAM, type = ro; - LOWCODE: load = RAM, type = ro, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss; - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, define = yes, optional = yes; + CODE: load = MAIN, type = ro; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = bss; + BSS: load = MAIN, type = bss, define = yes; OVL1ADDR: load = OVL1ADDR, type = ro; OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; OVL2ADDR: load = OVL2ADDR, type = ro; diff --git a/cfg/c128.cfg b/cfg/c128.cfg index 0ea6066ad..6a98dc5cf 100644 --- a/cfg/c128.cfg +++ b/cfg/c128.cfg @@ -7,20 +7,20 @@ MEMORY { ZP: file = "", define = yes, start = $0002, size = $001A; LOADADDR: file = %O, start = $1BFF, size = $0002; HEADER: file = %O, start = $1C01, size = $000C; - RAM: file = %O, define = yes, start = $1C0D, size = $A3F3 - __STACKSIZE__; + MAIN: file = %O, define = yes, start = $1C0D, size = $A3F3 - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; - STARTUP: load = RAM, type = ro; - LOWCODE: load = RAM, type = ro, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss; - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, define = yes, optional = yes; + CODE: load = MAIN, type = ro; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = bss; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/c16.cfg b/cfg/c16.cfg index b4b5ccaf7..f1ab747cd 100644 --- a/cfg/c16.cfg +++ b/cfg/c16.cfg @@ -7,20 +7,20 @@ MEMORY { ZP: file = "", define = yes, start = $0002, size = $001A; LOADADDR: file = %O, start = $0FFF, size = $0002; HEADER: file = %O, start = $1001, size = $000C; - RAM: file = %O, start = $100D, size = $6FF3 - __STACKSIZE__; + MAIN: file = %O, start = $100D, size = $6FF3 - __STACKSIZE__; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp; + ZEROPAGE: load = ZP, type = zp; LOADADDR: load = LOADADDR, type = ro; - EXEHDR: load = HEADER, type = ro; - STARTUP: load = RAM, type = ro; - LOWCODE: load = RAM, type = ro, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss; - BSS: load = RAM, type = bss, define = yes; + EXEHDR: load = HEADER, type = ro; + STARTUP: load = MAIN, type = ro; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, define = yes, optional = yes; + CODE: load = MAIN, type = ro; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = bss; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/c64-asm.cfg b/cfg/c64-asm.cfg index 1ab80be8e..224bd704a 100644 --- a/cfg/c64-asm.cfg +++ b/cfg/c64-asm.cfg @@ -7,14 +7,14 @@ SYMBOLS { MEMORY { ZP: file = "", start = $0002, size = $001A, define = yes; LOADADDR: file = %O, start = %S - 2, size = $0002; - RAM: file = %O, start = %S, size = $D000 - %S; + MAIN: file = %O, start = %S, size = $D000 - %S; } SEGMENTS { LOADADDR: load = LOADADDR, type = ro; - EXEHDR: load = RAM, type = ro, optional = yes; - CODE: load = RAM, type = rw, optional = yes; - RODATA: load = RAM, type = ro, optional = yes; - DATA: load = RAM, type = rw, optional = yes; - BSS: load = RAM, type = bss, optional = yes; + EXEHDR: load = MAIN, type = ro, optional = yes; + CODE: load = MAIN, type = rw, optional = yes; + RODATA: load = MAIN, type = ro, optional = yes; + DATA: load = MAIN, type = rw, optional = yes; + BSS: load = MAIN, type = bss, optional = yes; ZEROPAGE: load = ZP, type = zp, optional = yes; } diff --git a/cfg/cbm510.cfg b/cfg/cbm510.cfg index 8b01dff0b..5f73174f3 100644 --- a/cfg/cbm510.cfg +++ b/cfg/cbm510.cfg @@ -8,24 +8,24 @@ MEMORY { STARTUP: file = %O, start = $00FE, size = $0102, fill = yes; PAGE2: file = %O, start = $0200, size = $0100, fill = yes; PAGE3: file = %O, start = $0300, size = $0100, fill = yes; - RAM: file = %O, start = $0400, size = $DC00; + MAIN: file = %O, start = $0400, size = $DC00; CHARRAM: file = "", define = yes, start = $E000, size = $1000; VIDRAM: file = "", define = yes, start = $F000, size = $0400; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = rw, define = yes; EXEHDR: load = HEADER, type = rw; STARTUP: load = STARTUP, type = rw; PAGE2: load = PAGE2, type = rw; PAGE3: load = PAGE3, type = rw; - LOWCODE: load = RAM, type = ro, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss; - BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = rw, define = yes; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, define = yes, optional = yes; + CODE: load = MAIN, type = ro; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = bss; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/cbm610.cfg b/cfg/cbm610.cfg index 6df9f1f5a..fb4349dba 100644 --- a/cfg/cbm610.cfg +++ b/cfg/cbm610.cfg @@ -7,22 +7,22 @@ MEMORY { STARTUP: file = %O, start = $00FE, size = $0102, fill = yes; PAGE2: file = %O, start = $0200, size = $0100, fill = yes; PAGE3: file = %O, start = $0300, size = $0100, fill = yes; - RAM: file = %O, start = $0400, size = $FECB - __STACKSIZE__; + MAIN: file = %O, start = $0400, size = $FECB - __STACKSIZE__; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = rw, define = yes; EXEHDR: load = HEADER, type = rw; STARTUP: load = STARTUP, type = rw; PAGE2: load = PAGE2, type = rw; PAGE3: load = PAGE3, type = rw; - LOWCODE: load = RAM, type = ro, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss; - BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = rw, define = yes; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, define = yes, optional = yes; + CODE: load = MAIN, type = ro; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = bss; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/gamate.cfg b/cfg/gamate.cfg index f0f669f27..4e4253194 100644 --- a/cfg/gamate.cfg +++ b/cfg/gamate.cfg @@ -9,17 +9,17 @@ MEMORY { # 0000-03ff is RAM # FIXME: what zp range can we actually use? # $0a-$11 is used by IRQ/NMI, $e8 is used by NMI - ZP: start = $0012, size = $e8 - $12; - CPUSTACK: start = $0100, size =$100; - RAM: start = $0200, size = $200 - __STACKSIZE__, define = yes; + ZP: start = $0012, size = $00E8 - $0012; + CPUSTACK: start = $0100, size = $0100; + RAM: start = $0200, size = $0200 - __STACKSIZE__, define = yes; - CARTHEADER: file = %O, define = yes, start = %S, size = $0029; + CARTHEADER: file = %O, define = yes, start = %S, size = $0029; # 6000-e000 can be (Cartridge) ROM # WARNING: fill value must be $00 else it will no more work - #ROM: start = $6000, size = $1000, fill = yes, fillval = $00, file = %O, define = yes; - #ROMFILL: start = $7000, size = $7000, fill = yes, fillval = $00, file = %O, define = yes; + #ROM: start = $6000, size = $1000, fill = yes, fillval = $00, file = %O, define = yes; + #ROMFILL: start = $7000, size = $7000, fill = yes, fillval = $00, file = %O, define = yes; # for images that have code >$6fff we must calculate the checksum! - ROM: start = $6000 + $29, size = $8000 - $29, fill = yes, fillval = $00, file = %O, define = yes; + ROM: start = $6000 + $0029, size = $8000 - $0029, fill = yes, fillval = $00, file = %O, define = yes; } SEGMENTS { diff --git a/cfg/lunix.cfg b/cfg/lunix.cfg index aabacbeb2..3a11cc5d4 100644 --- a/cfg/lunix.cfg +++ b/cfg/lunix.cfg @@ -5,18 +5,18 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0400; # 1k stack (do typical LUnix apps. need 2k?) } MEMORY { - ZP: start = $0080, size = $0040; - RAM: start = %S, size = $7600 - __STACKSIZE__; + ZP: start = $0080, size = $0040; + MAIN: start = %S, size = $7600 - __STACKSIZE__; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp, define = yes; # Pseudo-registers - STARTUP: load = RAM, type = ro; # First initialization code - LOWCODE: load = RAM, type = ro, optional = yes; # Legacy from other platforms - ONCE: load = RAM, type = ro, define = yes, optional = yes; # Library initialization code - CODE: load = RAM, type = ro; # Program - RODATA: load = RAM, type = ro; # Literals, constants - DATA: load = RAM, type = rw; # Initialized variables - BSS: load = RAM, type = bss, define = yes; # Uninitialized variables + ZEROPAGE: load = ZP, type = zp, define = yes; # Pseudo-registers + STARTUP: load = MAIN, type = ro; # First initialization code + LOWCODE: load = MAIN, type = ro, optional = yes; # Legacy from other platforms + ONCE: load = MAIN, type = ro, define = yes, optional = yes; # Library initialization code + CODE: load = MAIN, type = ro; # Program + RODATA: load = MAIN, type = ro; # Literals, constants + DATA: load = MAIN, type = rw; # Initialized variables + BSS: load = MAIN, type = bss, define = yes; # Uninitialized variables } FEATURES { CONDES: type = constructor, diff --git a/cfg/lynx-bll.cfg b/cfg/lynx-bll.cfg index fcf6d4c60..a1687b423 100644 --- a/cfg/lynx-bll.cfg +++ b/cfg/lynx-bll.cfg @@ -7,20 +7,20 @@ SYMBOLS { MEMORY { ZP: file = "", define = yes, start = $0000, size = $0100; HEADER: file = %O, start = $0000, size = $000a; - RAM: file = %O, define = yes, start = $0400, size = $BC38 - __STACKSIZE__; + MAIN: file = %O, define = yes, start = $0400, size = $BC38 - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; EXTZP: load = ZP, type = zp, optional = yes; APPZP: load = ZP, type = zp, optional = yes; BLLHDR: load = HEADER, type = ro; - STARTUP: load = RAM, type = ro, define = yes; - LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = ro, define = yes; - RODATA: load = RAM, type = ro, define = yes; - DATA: load = RAM, type = rw, define = yes; - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro, define = yes; + LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: load = MAIN, type = ro, define = yes, optional = yes; + CODE: load = MAIN, type = ro, define = yes; + RODATA: load = MAIN, type = ro, define = yes; + DATA: load = MAIN, type = rw, define = yes; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/lynx-coll.cfg b/cfg/lynx-coll.cfg index d40c18237..9467c3c92 100644 --- a/cfg/lynx-coll.cfg +++ b/cfg/lynx-coll.cfg @@ -11,7 +11,7 @@ MEMORY { HEADER: file = %O, start = $0000, size = $0040; BOOT: file = %O, start = $0200, size = __STARTOFDIRECTORY__; DIR: file = %O, start = $0000, size = 8; - RAM: file = %O, define = yes, start = $0200, size = $9E58 - __STACKSIZE__; + MAIN: file = %O, define = yes, start = $0200, size = $9E58 - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; @@ -20,13 +20,13 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro; BOOTLDR: load = BOOT, type = ro; DIRECTORY: load = DIR, type = ro; - STARTUP: load = RAM, type = ro, define = yes; - LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = ro, define = yes; - RODATA: load = RAM, type = ro, define = yes; - DATA: load = RAM, type = rw, define = yes; - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro, define = yes; + LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: load = MAIN, type = ro, define = yes, optional = yes; + CODE: load = MAIN, type = ro, define = yes; + RODATA: load = MAIN, type = ro, define = yes; + DATA: load = MAIN, type = rw, define = yes; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/lynx-uploader.cfg b/cfg/lynx-uploader.cfg index fe6d6133d..c32e3583f 100644 --- a/cfg/lynx-uploader.cfg +++ b/cfg/lynx-uploader.cfg @@ -12,7 +12,7 @@ MEMORY { HEADER: file = %O, start = $0000, size = $0040; BOOT: file = %O, start = $0200, size = __STARTOFDIRECTORY__; DIR: file = %O, start = $0000, size = 8; - RAM: file = %O, define = yes, start = $0200, size = $BD38 - __STACKSIZE__; + MAIN: file = %O, define = yes, start = $0200, size = $BD38 - __STACKSIZE__; UPLDR: file = %O, define = yes, start = $BFDC, size = $005C; } SEGMENTS { @@ -22,13 +22,13 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro; BOOTLDR: load = BOOT, type = ro; DIRECTORY:load = DIR, type = ro; - STARTUP: load = RAM, type = ro, define = yes; - LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = ro, define = yes; - RODATA: load = RAM, type = ro, define = yes; - DATA: load = RAM, type = rw, define = yes; - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro, define = yes; + LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: load = MAIN, type = ro, define = yes, optional = yes; + CODE: load = MAIN, type = ro, define = yes; + 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; } diff --git a/cfg/lynx.cfg b/cfg/lynx.cfg index 4d41c1bbf..5140b342f 100644 --- a/cfg/lynx.cfg +++ b/cfg/lynx.cfg @@ -11,7 +11,7 @@ MEMORY { HEADER: file = %O, start = $0000, size = $0040; BOOT: file = %O, start = $0200, size = __STARTOFDIRECTORY__; DIR: file = %O, start = $0000, size = 8; - RAM: file = %O, define = yes, start = $0200, size = $BE38 - __STACKSIZE__; + MAIN: file = %O, define = yes, start = $0200, size = $BE38 - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; @@ -20,13 +20,13 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro; BOOTLDR: load = BOOT, type = ro; DIRECTORY: load = DIR, type = ro; - STARTUP: load = RAM, type = ro, define = yes; - LOWCODE: load = RAM, type = ro, define = yes, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = ro, define = yes; - RODATA: load = RAM, type = ro, define = yes; - DATA: load = RAM, type = rw, define = yes; - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro, define = yes; + LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: load = MAIN, type = ro, define = yes, optional = yes; + CODE: load = MAIN, type = ro, define = yes; + RODATA: load = MAIN, type = ro, define = yes; + DATA: load = MAIN, type = rw, define = yes; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/none.cfg b/cfg/none.cfg index 54ae54eb4..dcee60419 100644 --- a/cfg/none.cfg +++ b/cfg/none.cfg @@ -2,17 +2,17 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack } MEMORY { - ZP: file = "", define = yes, start = $0000, size = $0001F; - RAM: file = %O, start = %S, size = $10000 - __STACKSIZE__; + ZP: file = "", define = yes, start = $0000, size = $0001F; + MAIN: file = %O, start = %S, size = $10000 - __STACKSIZE__; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp; - LOWCODE: load = RAM, type = ro, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = rw; - RODATA: load = RAM, type = rw; - DATA: load = RAM, type = rw; - BSS: load = RAM, type = bss, define = yes; + ZEROPAGE: load = ZP, type = zp; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, define = yes, 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, diff --git a/cfg/osic1p-asm.cfg b/cfg/osic1p-asm.cfg index ac2e76dc9..3c1b1bda3 100644 --- a/cfg/osic1p-asm.cfg +++ b/cfg/osic1p-asm.cfg @@ -10,16 +10,16 @@ SYMBOLS { } MEMORY { # for size of ZP, see runtime/zeropage.s and c1p/extzp.s - ZP: file = "", define = yes, start = $0002, size = $001A + $0006; - HEAD: file = %O, start = $0000, size = $00B6; - RAM: file = %O, define = yes, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S; + ZP: file = "", define = yes, start = $0002, size = $001A + $0006; + HEAD: file = %O, start = $0000, size = $00B6; + MAIN: file = %O, define = yes, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; BOOT: load = HEAD, type = ro, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = rw; - RODATA: load = RAM, type = rw; - DATA: load = RAM, type = rw; - BSS: load = RAM, type = bss, define = yes; + ONCE: load = MAIN, type = ro, define = yes, optional = yes; + CODE: load = MAIN, type = rw; + RODATA: load = MAIN, type = rw; + DATA: load = MAIN, type = rw; + BSS: load = MAIN, type = bss, define = yes; } diff --git a/cfg/osic1p.cfg b/cfg/osic1p.cfg index 314eac0b9..3507ebeba 100644 --- a/cfg/osic1p.cfg +++ b/cfg/osic1p.cfg @@ -10,21 +10,21 @@ SYMBOLS { } MEMORY { # for size of ZP, see runtime/zeropage.s and c1p/extzp.s - ZP: file = "", define = yes, start = $0002, size = $001A + $0020; - HEAD: file = %O, start = $0000, size = $00B6; - RAM: file = %O, define = yes, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S; + ZP: file = "", define = yes, start = $0002, size = $001A + $0020; + HEAD: file = %O, start = $0000, size = $00B6; + MAIN: file = %O, define = yes, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; EXTZP: load = ZP, type = zp, define = yes, optional = yes; BOOT: load = HEAD, type = ro, optional = yes; - STARTUP: load = RAM, type = ro; - LOWCODE: load = RAM, type = ro, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = rw; - RODATA: load = RAM, type = rw; - DATA: load = RAM, type = rw; - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, define = yes, 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, diff --git a/cfg/plus4.cfg b/cfg/plus4.cfg index 16e9d12c8..4f73e40c2 100644 --- a/cfg/plus4.cfg +++ b/cfg/plus4.cfg @@ -7,20 +7,20 @@ MEMORY { ZP: file = "", define = yes, start = $0002, size = $001A; LOADADDR: file = %O, start = $0FFF, size = $0002; HEADER: file = %O, start = $1001, size = $000C; - RAM: file = %O, define = yes, start = $100D, size = $ECF3 - __STACKSIZE__; + MAIN: file = %O, define = yes, start = $100D, size = $ECF3 - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; - STARTUP: load = RAM, type = ro; - LOWCODE: load = RAM, type = ro, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss; - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, define = yes, optional = yes; + CODE: load = MAIN, type = ro; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = bss; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/sim6502.cfg b/cfg/sim6502.cfg index 8e78fceb2..b50703bab 100644 --- a/cfg/sim6502.cfg +++ b/cfg/sim6502.cfg @@ -5,18 +5,18 @@ SYMBOLS { MEMORY { ZP: file = "", start = $0000, size = $001A; HEADER: file = %O, start = $0000, size = $0001; - RAM: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; + MAIN: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; EXEHDR: load = HEADER, type = ro; - STARTUP: load = RAM, type = ro; - LOWCODE: load = RAM, type = ro, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, define = yes, optional = yes; + CODE: load = MAIN, type = ro; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/sim65c02.cfg b/cfg/sim65c02.cfg index 8e78fceb2..b50703bab 100644 --- a/cfg/sim65c02.cfg +++ b/cfg/sim65c02.cfg @@ -5,18 +5,18 @@ SYMBOLS { MEMORY { ZP: file = "", start = $0000, size = $001A; HEADER: file = %O, start = $0000, size = $0001; - RAM: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; + MAIN: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; EXEHDR: load = HEADER, type = ro; - STARTUP: load = RAM, type = ro; - LOWCODE: load = RAM, type = ro, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, define = yes, optional = yes; + CODE: load = MAIN, type = ro; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/vic20-32k.cfg b/cfg/vic20-32k.cfg index a1b609106..4f4225825 100644 --- a/cfg/vic20-32k.cfg +++ b/cfg/vic20-32k.cfg @@ -9,20 +9,20 @@ MEMORY { ZP: file = "", define = yes, start = $0002, size = $001A; LOADADDR: file = %O, start = $11FF, size = $0002; HEADER: file = %O, start = $1201, size = $000C; - RAM: file = %O, define = yes, start = $120D, size = $6DF3 - __STACKSIZE__; + MAIN: file = %O, define = yes, start = $120D, size = $6DF3 - __STACKSIZE__; } SEGMENTS { + ZEROPAGE: load = ZP, type = zp; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; - STARTUP: load = RAM, type = ro; - LOWCODE: load = RAM, type = ro, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss; - BSS: load = RAM, type = bss, define = yes; - ZEROPAGE: load = ZP, type = zp; + STARTUP: load = MAIN, type = ro; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, define = yes, optional = yes; + CODE: load = MAIN, type = ro; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = bss; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/vic20.cfg b/cfg/vic20.cfg index 693b356a3..4eba7bfa9 100644 --- a/cfg/vic20.cfg +++ b/cfg/vic20.cfg @@ -7,20 +7,20 @@ MEMORY { ZP: file = "", define = yes, start = $0002, size = $001A; LOADADDR: file = %O, start = $0FFF, size = $0002; HEADER: file = %O, start = $1001, size = $000C; - RAM: file = %O, define = yes, start = $100D, size = $0DF3 - __STACKSIZE__; + MAIN: file = %O, define = yes, start = $100D, size = $0DF3 - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; - STARTUP: load = RAM, type = ro; - LOWCODE: load = RAM, type = ro, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; - CODE: load = RAM, type = ro; - RODATA: load = RAM, type = ro; - DATA: load = RAM, type = rw; - INIT: load = RAM, type = bss; - BSS: load = RAM, type = bss, define = yes; + STARTUP: load = MAIN, type = ro; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, define = yes, optional = yes; + CODE: load = MAIN, type = ro; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = bss; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/doc/atari.sgml b/doc/atari.sgml index f37b43929..2087a8541 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -148,7 +148,7 @@ Special locations: ($58). <tag/Stack/ - The C runtime stack is located at end of the RAM memory area ($CFFF) + The C runtime stack is located at end of the MAIN memory area ($CFFF) and grows downwards. <tag/Heap/ @@ -561,7 +561,7 @@ The contents of this chunk come from the SYSCHKCHNK memory area of the linker co <item>main program&nl; This load chunk is loaded at the selected program start address (default $2000) and contains all of the code and data of the program.&nl; -The contents of this chunk come from the RAM memory area of the linker config file. +The contents of this chunk come from the MAIN memory area of the linker config file. </enum> diff --git a/libsrc/atari/crt0.s b/libsrc/atari/crt0.s index 0ea6e390f..317fe5697 100644 --- a/libsrc/atari/crt0.s +++ b/libsrc/atari/crt0.s @@ -14,7 +14,7 @@ .import initlib, donelib .import callmain, zerobss .import __RESERVED_MEMORY__ - .import __RAM_START__, __RAM_SIZE__ + .import __MAIN_START__, __MAIN_SIZE__ .ifdef __ATARIXL__ .import __STACKSIZE__ .import sram_init @@ -55,10 +55,10 @@ start: .ifdef __ATARIXL__ - lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) + lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) + ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) sta sp - lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) - sta sp+1 + stx sp+1 .else diff --git a/libsrc/atari/exehdr.s b/libsrc/atari/exehdr.s index ea9fa95d7..7abb7c1ac 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 __RAM_START__, __BSS_LOAD__ + .import __MAIN_START__, __BSS_LOAD__ .segment "EXEHDR" .word $FFFF .segment "MAINHDR" - .word __RAM_START__ + .word __MAIN_START__ .word __BSS_LOAD__ - 1 diff --git a/libsrc/atmos/crt0.s b/libsrc/atmos/crt0.s index e789b28c2..6ad7a3ff3 100644 --- a/libsrc/atmos/crt0.s +++ b/libsrc/atmos/crt0.s @@ -9,7 +9,7 @@ .export __STARTUP__ : absolute = 1 ; Mark as startup .import initlib, donelib .import callmain, zerobss - .import __RAM_START__, __RAM_SIZE__, __STACKSIZE__ + .import __MAIN_START__, __MAIN_SIZE__, __STACKSIZE__ .include "zeropage.inc" .include "atmos.inc" @@ -44,10 +44,10 @@ L1: lda sp,x tsx stx spsave ; Save system stk ptr - lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) + lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) + ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) sta sp - lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) - sta sp+1 ; Set argument stack ptr + stx sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/c128/crt0.s b/libsrc/c128/crt0.s index 5891bacf3..ba6a78ac5 100644 --- a/libsrc/c128/crt0.s +++ b/libsrc/c128/crt0.s @@ -8,7 +8,7 @@ .import zerobss .import push0, callmain .import RESTOR, BSOUT, CLRCH - .import __RAM_START__, __RAM_SIZE__, __STACKSIZE__ + .import __MAIN_START__, __MAIN_SIZE__, __STACKSIZE__ .importzp ST .include "zeropage.inc" @@ -56,10 +56,10 @@ L1: lda sp,x tsx stx spsave ; Save the system stack pointer - lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) + lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) + ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) sta sp - lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) - sta sp+1 ; Set argument stack ptr + stx sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/gamate/crt0.s b/libsrc/gamate/crt0.s index ead45b7ea..99af9b2d9 100644 --- a/libsrc/gamate/crt0.s +++ b/libsrc/gamate/crt0.s @@ -33,16 +33,16 @@ Start: ; setup the stack lda #<(__RAM_START__+__RAM_SIZE__) + ldx #>(__RAM_START__+__RAM_SIZE__) sta sp - lda #>(__RAM_START__+__RAM_SIZE__) - sta sp + 1 + stx sp + 1 ; Call module constructors jsr initlib lda #1 sta ZP_IRQ_CTRL ; enable calling cartridge IRQ/NMI handler - cli ; allow IRQ only after constructors have run + cli ; allow IRQ only after constructors have run ; Pass an empty command line jsr push0 ; argc diff --git a/libsrc/lynx/bllhdr.s b/libsrc/lynx/bllhdr.s index 60fc87725..07ed06ffb 100644 --- a/libsrc/lynx/bllhdr.s +++ b/libsrc/lynx/bllhdr.s @@ -4,7 +4,7 @@ ; This header is required for BLL builds. ; .import __BSS_LOAD__ - .import __RAM_START__ + .import __MAIN_START__ .export __BLLHDR__: absolute = 1 ; ------------------------------------------------------------------------ @@ -12,8 +12,7 @@ .segment "BLLHDR" .word $0880 - .dbyt __RAM_START__ - .dbyt __BSS_LOAD__ - __RAM_START__ + 10 + .dbyt __MAIN_START__ + .dbyt __BSS_LOAD__ - __MAIN_START__ + 10 .byte $42,$53 .byte $39,$33 - diff --git a/libsrc/lynx/crt0.s b/libsrc/lynx/crt0.s index 725f74ebd..c924f742f 100644 --- a/libsrc/lynx/crt0.s +++ b/libsrc/lynx/crt0.s @@ -22,7 +22,7 @@ .import zerobss .import callmain .import _main - .import __RAM_START__, __RAM_SIZE__, __STACKSIZE__ + .import __MAIN_START__, __MAIN_SIZE__, __STACKSIZE__ .include "zeropage.inc" .include "extzp.inc" @@ -79,10 +79,10 @@ MikeyInitData: .byte $9e,$18,$68,$1f,$00,$00,$00,$00,$00,$ff,$1a,$1b,$04,$0d,$2 ; Set up the stack. - lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) + lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) + ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) sta sp - lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) - sta sp+1 + stx sp+1 ; Init Mickey. diff --git a/libsrc/lynx/defdir.s b/libsrc/lynx/defdir.s index a36848227..2930edf4b 100644 --- a/libsrc/lynx/defdir.s +++ b/libsrc/lynx/defdir.s @@ -5,7 +5,7 @@ ; .include "lynx.inc" .import __STARTOFDIRECTORY__ - .import __RAM_START__ + .import __MAIN_START__ .import __CODE_SIZE__, __DATA_SIZE__, __RODATA_SIZE__ .import __STARTUP_SIZE__, __ONCE_SIZE__, __LOWCODE_SIZE__ .import __BLOCKSIZE__ @@ -25,6 +25,6 @@ len0 = __STARTUP_SIZE__ + __ONCE_SIZE__ + __CODE_SIZE__ + __DATA_SIZE__ + __RODA .byte <block0 .word off0 & (__BLOCKSIZE__ - 1) .byte $88 - .word __RAM_START__ + .word __MAIN_START__ .word len0 __DIRECTORY_END__: diff --git a/libsrc/osic1p/bootstrap.s b/libsrc/osic1p/bootstrap.s index 2a501b980..ed2ade222 100644 --- a/libsrc/osic1p/bootstrap.s +++ b/libsrc/osic1p/bootstrap.s @@ -6,16 +6,16 @@ ; add "-u __BOOT__" to the cl65/ld65 command line. Then, the linker ; will import this symbol name; and, link this module at the front ; of your program file. -; - .export __BOOT__:abs = 1 - .import __RAM_START__, __RAM_SIZE__, __BSS_RUN__ + .export __BOOT__ : abs = 1 + + .import __MAIN_START__, __MAIN_SIZE__, __BSS_RUN__ ; ------------------------------------------------------------------------ -load_addr := __RAM_START__ -load_size = __BSS_RUN__ - __RAM_START__ -ram_top := __RAM_START__ + __RAM_SIZE__ +load_addr := __MAIN_START__ +load_size = __BSS_RUN__ - __MAIN_START__ +ram_top := __MAIN_START__ + __MAIN_SIZE__ .segment "BOOT" diff --git a/libsrc/osic1p/crt0.s b/libsrc/osic1p/crt0.s index 62342c206..56abb7cdb 100644 --- a/libsrc/osic1p/crt0.s +++ b/libsrc/osic1p/crt0.s @@ -8,7 +8,7 @@ .import _main .export __STARTUP__ : absolute = 1 ; Mark as startup -.import __RAM_START__, __RAM_SIZE__ ; Linker generated +.import __MAIN_START__, __MAIN_SIZE__ ; Linker generated .import __STACKSIZE__ .import zerobss, initlib, donelib @@ -32,10 +32,10 @@ _init: ldx #$FF ; Initialize stack pointer to $01FF ; --------------------------------------------------------------------------- ; Set cc65 argument stack pointer - lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) + lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) + ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) sta sp - lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) - sta sp+1 + stx sp+1 ; --------------------------------------------------------------------------- ; Initialize memory storage diff --git a/libsrc/plus4/crt0.s b/libsrc/plus4/crt0.s index 9696d50f4..2262b4c42 100644 --- a/libsrc/plus4/crt0.s +++ b/libsrc/plus4/crt0.s @@ -9,7 +9,7 @@ .import callirq_y, initlib, donelib .import callmain, zerobss .import __INTERRUPTOR_COUNT__ - .import __RAM_START__, __RAM_SIZE__ ; Linker generated + .import __MAIN_START__, __MAIN_SIZE__ ; Linker generated .import __STACKSIZE__ ; Linker generated .importzp ST @@ -50,12 +50,12 @@ L1: lda sp,x ; of the usable RAM. tsx - stx spsave ; save system stk ptr + stx spsave ; Save system stk ptr - lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) + lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) + ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) sta sp - lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) - sta sp+1 + stx sp+1 ; Set up the IRQ vector in the banked RAM; and, switch off the ROM. diff --git a/libsrc/sim6502/crt0.s b/libsrc/sim6502/crt0.s index d1831ad81..bd02f0e42 100644 --- a/libsrc/sim6502/crt0.s +++ b/libsrc/sim6502/crt0.s @@ -9,7 +9,7 @@ .import zerobss, callmain .import initlib, donelib .import exit - .import __RAM_START__, __RAM_SIZE__ ; Linker generated + .import __MAIN_START__, __MAIN_SIZE__ ; Linker generated .import __STACKSIZE__ ; Linker generated .include "zeropage.inc" @@ -19,8 +19,8 @@ cld ldx #$FF txs - lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) - ldx #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) + lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) + ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) sta sp stx sp+1 jsr zerobss diff --git a/libsrc/vic20/crt0.s b/libsrc/vic20/crt0.s index 723971168..68ab3ed12 100644 --- a/libsrc/vic20/crt0.s +++ b/libsrc/vic20/crt0.s @@ -8,7 +8,7 @@ .import zerobss, push0 .import callmain .import RESTOR, BSOUT, CLRCH - .import __RAM_START__, __RAM_SIZE__ ; Linker generated + .import __MAIN_START__, __MAIN_SIZE__ ; Linker generated .import __STACKSIZE__ ; Linker generated .importzp ST @@ -44,10 +44,10 @@ L1: lda sp,x tsx stx spsave ; Save the system stack ptr - lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) + lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) + ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) sta sp - lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) - sta sp+1 ; Set argument stack ptr + stx sp+1 ; Set argument stack ptr ; Call the module constructors. From 69fbcb30fd393277c93eade43737a52d20582c47 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 7 Mar 2016 01:44:19 +0100 Subject: [PATCH 0018/2161] Use AX paradigm for stack initalization. --- libsrc/atari5200/crt0.s | 4 ++-- libsrc/gamate/crt0.s | 4 ++-- libsrc/nes/crt0.s | 4 ++-- libsrc/pce/crt0.s | 17 ++++++++--------- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/libsrc/atari5200/crt0.s b/libsrc/atari5200/crt0.s index 7073bb2a7..ee3d0de4f 100644 --- a/libsrc/atari5200/crt0.s +++ b/libsrc/atari5200/crt0.s @@ -27,9 +27,9 @@ start: ; Set up the stack. lda #<(__RAM_START__ + __RAM_SIZE__ - __RESERVED_MEMORY__) + ldx #>(__RAM_START__ + __RAM_SIZE__ - __RESERVED_MEMORY__) sta sp - lda #>(__RAM_START__ + __RAM_SIZE__ - __RESERVED_MEMORY__) - sta sp+1 ; Set argument stack ptr + stx sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/gamate/crt0.s b/libsrc/gamate/crt0.s index 99af9b2d9..5a5bb3aa0 100644 --- a/libsrc/gamate/crt0.s +++ b/libsrc/gamate/crt0.s @@ -20,7 +20,7 @@ Start: ldx #0 stx ZP_IRQ_CTRL ; disable calling cartridge IRQ/NMI handler - ; Setup stack and memory mapping + ; Set up stack and memory mapping ;ldx #$FF ; Stack top ($01FF) dex txs @@ -31,7 +31,7 @@ Start: ; Copy the .data segment to RAM jsr copydata - ; setup the stack + ; Set up the stack lda #<(__RAM_START__+__RAM_SIZE__) ldx #>(__RAM_START__+__RAM_SIZE__) sta sp diff --git a/libsrc/nes/crt0.s b/libsrc/nes/crt0.s index de874d363..4d258ff9e 100644 --- a/libsrc/nes/crt0.s +++ b/libsrc/nes/crt0.s @@ -100,9 +100,9 @@ start: ; Set up the stack. lda #<(__SRAM_START__ + __SRAM_SIZE__) + ldx #>(__SRAM_START__ + __SRAM_SIZE__) sta sp - lda #>(__SRAM_START__ + __SRAM_SIZE__) - sta sp+1 ; Set argument stack ptr + stx sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/pce/crt0.s b/libsrc/pce/crt0.s index e92e9eca3..80b32c089 100644 --- a/libsrc/pce/crt0.s +++ b/libsrc/pce/crt0.s @@ -39,22 +39,21 @@ start: - ; setup the CPU and System-IRQ + ; Set up the CPU and System-IRQ ; Initialize CPU - sei nop - csh ; set high speed CPU mode + csh ; Set high speed CPU mode nop cld nop - ; Setup stack and memory mapping + ; Set up stack and memory mapping ldx #$FF ; Stack top ($21FF) txs - ; at startup all MPRs are set to 0, so init them + ; At startup all MPRs are set to 0, so init them lda #$ff tam #%00000001 ; 0000-1FFF = Hardware page lda #$F8 @@ -98,11 +97,11 @@ start: ; Copy the .data segment to RAM tii __DATA_LOAD__, __DATA_RUN__, __DATA_SIZE__ - ; setup the stack + ; Set up the stack lda #<(__RAM_START__+__RAM_SIZE__) + ldx #>(__RAM_START__+__RAM_SIZE__) sta sp - lda #>(__RAM_START__+__RAM_SIZE__) - sta sp + 1 + stx sp + 1 ; Call module constructors jsr initlib @@ -114,7 +113,7 @@ start: jsr push0 ; argv ldy #4 ; Argument size - jsr _main ; call the users code + jsr _main ; Call the users code ; Call module destructors. This is also the _exit entry. _exit: From 084453ba57307131dc4465196d177f83a79e0068 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 10 Mar 2016 10:07:09 +0100 Subject: [PATCH 0019/2161] Don't presume the stack size to be a multiple of pages. --- libsrc/supervision/crt0.s | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libsrc/supervision/crt0.s b/libsrc/supervision/crt0.s index d78bfeab5..6c1287868 100644 --- a/libsrc/supervision/crt0.s +++ b/libsrc/supervision/crt0.s @@ -31,9 +31,10 @@ reset: ; Initialize data. jsr copydata - lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) - sta sp+1 ; Set argument stack ptr - stz sp ; #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) + lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) + ldx #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) + sta sp + stx sp+1 ; Set argument stack ptr jsr initlib jsr _main _exit: jsr donelib From a3a22733f8f83f0cf8547a9d2cf34d8056b97c97 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 13 Mar 2016 14:32:07 +0100 Subject: [PATCH 0020/2161] Cleaned up C64 linker configs. The BSS segment and the ONCE segment share the same start address. So they need to be placed in two different memory areas. So far BSS was placed in the MAIN memory area and ONCE was placed in an additional memory area. Both memory areas were written to the output file. They just "happened" to be loadable and runnable at a stretch. Now ONCE is placed in the MAIN memory area and BSS is placed in an additional memory area. Only MAIN is written to the output file. It becomes more obvious that BSS is "just" defined to share memory with ONCE. --- cfg/c64-asm.cfg | 2 +- cfg/c64-overlay.cfg | 10 +++++----- cfg/c64.cfg | 16 ++++++++-------- libsrc/c64/crt0.s | 4 ++-- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/cfg/c64-asm.cfg b/cfg/c64-asm.cfg index 224bd704a..25d12ee71 100644 --- a/cfg/c64-asm.cfg +++ b/cfg/c64-asm.cfg @@ -10,11 +10,11 @@ MEMORY { 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, optional = yes; RODATA: load = MAIN, type = ro, optional = yes; DATA: load = MAIN, type = rw, optional = yes; BSS: load = MAIN, type = bss, optional = yes; - ZEROPAGE: load = ZP, type = zp, optional = yes; } diff --git a/cfg/c64-overlay.cfg b/cfg/c64-overlay.cfg index 872fdd775..e88bffe00 100644 --- a/cfg/c64-overlay.cfg +++ b/cfg/c64-overlay.cfg @@ -1,5 +1,5 @@ FEATURES { - STARTADDRESS: default = $0801; + STARTADDRESS: default = $0801; } SYMBOLS { __LOADADDR__: type = import; @@ -14,8 +14,8 @@ 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 = $000D; - MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __OVERLAYSTART__ - __STACKSIZE__ - __HEADER_LAST__; - INIT: file = %O, start = __BSS_RUN__, size = __HIMEM__ - __BSS_RUN__; + MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__; + BSS: file = "", start = __ONCE_RUN__, size = __OVERLAYSTART__ - __STACKSIZE__ - __ONCE_RUN__; OVL1ADDR: file = "%O.1", start = __OVERLAYSTART__ - 2, size = $0002; OVL1: file = "%O.1", start = __OVERLAYSTART__, size = __OVERLAYSIZE__; OVL2ADDR: file = "%O.2", start = __OVERLAYSTART__ - 2, size = $0002; @@ -45,8 +45,8 @@ SEGMENTS { RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; INIT: load = MAIN, type = rw; - BSS: load = MAIN, type = bss, define = yes; - ONCE: load = INIT, type = ro; + ONCE: load = MAIN, type = ro, define = yes; + BSS: load = BSS, type = bss, define = yes; OVL1ADDR: load = OVL1ADDR, type = ro; OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; OVL2ADDR: load = OVL2ADDR, type = ro; diff --git a/cfg/c64.cfg b/cfg/c64.cfg index 3735a0a65..43ccce2ca 100644 --- a/cfg/c64.cfg +++ b/cfg/c64.cfg @@ -1,5 +1,5 @@ FEATURES { - STARTADDRESS: default = $0801; + STARTADDRESS: default = $0801; } SYMBOLS { __LOADADDR__: type = import; @@ -8,11 +8,11 @@ SYMBOLS { __HIMEM__: type = weak, value = $D000; } 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 = $000D; - MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __STACKSIZE__ - __HEADER_LAST__; - INIT: file = %O, start = __BSS_RUN__, size = __HIMEM__ - __BSS_RUN__; + 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 = __HIMEM__ - __HEADER_LAST__; + BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; @@ -24,8 +24,8 @@ SEGMENTS { RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; INIT: load = MAIN, type = rw; - BSS: load = MAIN, type = bss, define = yes; - ONCE: load = INIT, type = ro, define = yes; + ONCE: load = MAIN, type = ro, define = yes; + BSS: load = BSS, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/libsrc/c64/crt0.s b/libsrc/c64/crt0.s index c8a7386cb..7bd294ca7 100644 --- a/libsrc/c64/crt0.s +++ b/libsrc/c64/crt0.s @@ -93,8 +93,8 @@ L1: lda sp,x ; Set up the stack. - lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) + lda #<(__MAIN_START__ + __MAIN_SIZE__) + ldx #>(__MAIN_START__ + __MAIN_SIZE__) sta sp stx sp+1 ; Set argument stack ptr From 56a8c69b14496d6b8d32e3e7c55aaff6a2f0d9a9 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 13 Mar 2016 21:23:45 +0100 Subject: [PATCH 0021/2161] Use AX paradigm. --- libsrc/atari/crt0.s | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libsrc/atari/crt0.s b/libsrc/atari/crt0.s index 317fe5697..87d7d036f 100644 --- a/libsrc/atari/crt0.s +++ b/libsrc/atari/crt0.s @@ -65,9 +65,9 @@ start: ; Report the memory usage. lda APPMHI + ldx APPMHI+1 sta APPMHI_save ; remember old APPMHI value - lda APPMHI+1 - sta APPMHI_save+1 + stx APPMHI_save+1 sec lda MEMTOP @@ -129,9 +129,9 @@ _exit: jsr donelib ; Run module destructors ; Restore APPMHI. lda APPMHI_save + ldx APPMHI_save+1 sta APPMHI - lda APPMHI_save+1 - sta APPMHI+1 + stx APPMHI+1 .ifdef __ATARIXL__ @@ -142,9 +142,9 @@ _exit: jsr donelib ; Run module destructors lda RAMTOP_save sta RAMTOP lda MEMTOP_save + ldx MEMTOP_save+1 sta MEMTOP - lda MEMTOP_save+1 - sta MEMTOP+1 + stx MEMTOP+1 ; Issue a GRAPHICS 0 call (copied'n'pasted from the TGI drivers), in From 692f96409d4e809d8d0db6adba6eddd549861e8f Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 13 Mar 2016 22:13:41 +0100 Subject: [PATCH 0022/2161] Fixed BSS properties. The cassette boot file header references __BSS_RUN__ so BSS must be the first bss type segment (and for sure isn't optional). --- cfg/atari-cassette.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/atari-cassette.cfg b/cfg/atari-cassette.cfg index b138b8f0e..84bb5ad02 100644 --- a/cfg/atari-cassette.cfg +++ b/cfg/atari-cassette.cfg @@ -21,8 +21,8 @@ SEGMENTS { CODE: load = MAIN, type = ro, define = yes; RODATA: load = MAIN, type = ro, optional = yes; DATA: load = MAIN, type = rw, optional = yes; + BSS: load = MAIN, type = bss, define = yes; INIT: load = MAIN, type = bss, optional = yes; - BSS: load = MAIN, type = bss, define = yes, optional = yes; } FEATURES { CONDES: type = constructor, From c768de156ad67e2df769fc7c36ee37b989f15ddf Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 13 Mar 2016 22:18:51 +0100 Subject: [PATCH 0023/2161] Fixed INIT properties. The main chunk load header references __BSS_LOAD__ so BSS must be the first bss type segment. Subsequent changes will move ONCE to share its address with the BSS. Then it'll be necessary to load INIT from disk. Therefore we do it right now. --- cfg/atari-overlay.cfg | 38 ++++++++++++------------- cfg/atari.cfg | 2 +- cfg/atarixl-largehimem.cfg | 35 +++++++++-------------- cfg/atarixl-overlay.cfg | 58 ++++++++++++++++---------------------- cfg/atarixl.cfg | 37 ++++++++++-------------- 5 files changed, 74 insertions(+), 96 deletions(-) diff --git a/cfg/atari-overlay.cfg b/cfg/atari-overlay.cfg index 1dec49b7d..87e62d764 100644 --- a/cfg/atari-overlay.cfg +++ b/cfg/atari-overlay.cfg @@ -11,31 +11,31 @@ SYMBOLS { __RESERVED_MEMORY__: type = weak, value = $0000; } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # file header, just $FFFF - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $0002; # "system check" load chunk - SYSCHKHDR: file = %O, start = $0000, size = $0004; - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; - SYSCHKTRL: file = %O, start = $0000, size = $0006; + SYSCHKHDR: file = %O, start = $0000, size = $0004; + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + SYSCHKTRL: file = %O, start = $0000, size = $0006; # "main program" load chunk - MAINHDR: file = %O, start = $0000, size = $0004; - MAIN: file = %O, define = yes, start = %S + __OVERLAYSIZE__, - size = $BC20 - __OVERLAYSIZE__ - __STACKSIZE__ - __RESERVED_MEMORY__ - %S; - TRAILER: file = %O, start = $0000, size = $0006; + MAINHDR: file = %O, start = $0000, size = $0004; + MAIN: file = %O, define = yes, start = %S + __OVERLAYSIZE__, size = $BC20 - __OVERLAYSIZE__ - __STACKSIZE__ - __RESERVED_MEMORY__ - %S; + TRAILER: file = %O, start = $0000, size = $0006; - OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__; - OVL2: file = "%O.2", start = %S, size = __OVERLAYSIZE__; - OVL3: file = "%O.3", start = %S, size = __OVERLAYSIZE__; - OVL4: file = "%O.4", start = %S, size = __OVERLAYSIZE__; - OVL5: file = "%O.5", start = %S, size = __OVERLAYSIZE__; - OVL6: file = "%O.6", start = %S, size = __OVERLAYSIZE__; - OVL7: file = "%O.7", start = %S, size = __OVERLAYSIZE__; - OVL8: file = "%O.8", start = %S, size = __OVERLAYSIZE__; - OVL9: file = "%O.9", start = %S, size = __OVERLAYSIZE__; +# overlays + OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__; + OVL2: file = "%O.2", start = %S, size = __OVERLAYSIZE__; + OVL3: file = "%O.3", start = %S, size = __OVERLAYSIZE__; + OVL4: file = "%O.4", start = %S, size = __OVERLAYSIZE__; + OVL5: file = "%O.5", start = %S, size = __OVERLAYSIZE__; + OVL6: file = "%O.6", start = %S, size = __OVERLAYSIZE__; + OVL7: file = "%O.7", start = %S, size = __OVERLAYSIZE__; + OVL8: file = "%O.8", start = %S, size = __OVERLAYSIZE__; + OVL9: file = "%O.9", start = %S, size = __OVERLAYSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; @@ -51,7 +51,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 = rw, 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.cfg b/cfg/atari.cfg index 959a07e4c..4680a89ed 100644 --- a/cfg/atari.cfg +++ b/cfg/atari.cfg @@ -39,7 +39,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 = rw, 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 94405fce2..56d2af15b 100644 --- a/cfg/atarixl-largehimem.cfg +++ b/cfg/atarixl-largehimem.cfg @@ -6,7 +6,6 @@ FEATURES { STARTADDRESS: default = $2400; } - SYMBOLS { __EXEHDR__: type = import; __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk @@ -14,41 +13,35 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack __STARTADDRESS__: type = export, value = %S; } - MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # just $FFFF - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $0002; # "system check" load chunk - SYSCHKHDR: file = %O, start = $0000, size = $0004; - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; - SYSCHKTRL: file = %O, start = $0000, size = $0006; + SYSCHKHDR: file = %O, start = $0000, size = $0004; + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + SYSCHKTRL: file = %O, start = $0000, size = $0006; # "shadow RAM preparation" load chunk - SRPREPHDR: file = %O, start = $0000, size = $0004; - SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned - SRPREPTRL: file = %O, start = $0000, size = $0006; + SRPREPHDR: file = %O, start = $0000, size = $0004; + SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned + SRPREPTRL: file = %O, start = $0000, size = $0006; # "main program" load chunk - MAINHDR: file = %O, start = $0000, size = $0004; - MAIN: file = %O, define = yes, start = %S + - __LOWBSS_SIZE__, size = $D000 - - __STACKSIZE__ - - %S - - __LOWBSS_SIZE__; + MAINHDR: file = %O, start = $0000, size = $0004; + MAIN: file = %O, define = yes, start = %S + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __LOWBSS_SIZE__; # defines entry point into program - TRAILER: file = %O, start = $0000, size = $0006; + TRAILER: file = %O, start = $0000, size = $0006; # address of relocated character generator - CHARGEN: file = "", define = yes, start = $D800, size = $0400; + CHARGEN: file = "", define = yes, start = $D800, size = $0400; # memory beneath the ROM - HIDDEN_RAM: file = "", define = yes, start = $DC00, size = $FFFA - $DC00; + HIDDEN_RAM: file = "", define = yes, start = $DC00, size = $FFFA - $DC00; } - SEGMENTS { ZEROPAGE: load = ZP, type = zp; EXTZP: load = ZP, type = zp, optional = yes; @@ -73,7 +66,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 = rw, 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 89240170b..923436497 100644 --- a/cfg/atarixl-overlay.cfg +++ b/cfg/atarixl-overlay.cfg @@ -1,7 +1,6 @@ FEATURES { STARTADDRESS: default = $2400; } - SYMBOLS { __EXEHDR__: type = import; __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk @@ -10,57 +9,50 @@ SYMBOLS { __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay __STARTADDRESS__: type = export, value = %S; } - MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # just $FFFF - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $0002; # "system check" load chunk - SYSCHKHDR: file = %O, start = $0000, size = $0004; - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; - SYSCHKTRL: file = %O, start = $0000, size = $0006; + SYSCHKHDR: file = %O, start = $0000, size = $0004; + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + SYSCHKTRL: file = %O, start = $0000, size = $0006; # "shadow RAM preparation" load chunk - SRPREPHDR: file = %O, start = $0000, size = $0004; - SRPREPCHNK: file = %O, define = yes, start = %S + __OVERLAYSIZE__, size = $7C20 - %S - __OVERLAYSIZE__ - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned - SRPREPTRL: file = %O, start = $0000, size = $0006; + SRPREPHDR: file = %O, start = $0000, size = $0004; + SRPREPCHNK: file = %O, define = yes, start = %S + __OVERLAYSIZE__, size = $7C20 - %S - __OVERLAYSIZE__ - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned + SRPREPTRL: file = %O, start = $0000, size = $0006; # "main program" load chunk - MAINHDR: file = %O, start = $0000, size = $0004; - MAIN: file = %O, define = yes, start = %S + - __OVERLAYSIZE__ + - __LOWBSS_SIZE__, size = $D000 - - __STACKSIZE__ - - %S - - __OVERLAYSIZE__ - - __LOWBSS_SIZE__; + MAINHDR: file = %O, start = $0000, size = $0004; + MAIN: file = %O, define = yes, start = %S + __OVERLAYSIZE__ + + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __OVERLAYSIZE__ - __LOWBSS_SIZE__; # defines entry point into program - TRAILER: file = %O, start = $0000, size = $0006; + TRAILER: file = %O, start = $0000, size = $0006; # memory beneath the ROM preceeding the character generator - HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; + HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; # address of relocated character generator (same addess as ROM version) - CHARGEN: file = "", define = yes, start = $E000, size = $0400; + CHARGEN: file = "", define = yes, start = $E000, size = $0400; # memory beneath the ROM - HIDDEN_RAM: file = "", define = yes, start = $E400, size = $FFFA - $E400; + HIDDEN_RAM: file = "", define = yes, start = $E400, size = $FFFA - $E400; # overlays - OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__; - OVL2: file = "%O.2", start = %S, size = __OVERLAYSIZE__; - OVL3: file = "%O.3", start = %S, size = __OVERLAYSIZE__; - OVL4: file = "%O.4", start = %S, size = __OVERLAYSIZE__; - OVL5: file = "%O.5", start = %S, size = __OVERLAYSIZE__; - OVL6: file = "%O.6", start = %S, size = __OVERLAYSIZE__; - OVL7: file = "%O.7", start = %S, size = __OVERLAYSIZE__; - OVL8: file = "%O.8", start = %S, size = __OVERLAYSIZE__; - OVL9: file = "%O.9", start = %S, size = __OVERLAYSIZE__; + OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__; + OVL2: file = "%O.2", start = %S, size = __OVERLAYSIZE__; + OVL3: file = "%O.3", start = %S, size = __OVERLAYSIZE__; + OVL4: file = "%O.4", start = %S, size = __OVERLAYSIZE__; + OVL5: file = "%O.5", start = %S, size = __OVERLAYSIZE__; + OVL6: file = "%O.6", start = %S, size = __OVERLAYSIZE__; + OVL7: file = "%O.7", start = %S, size = __OVERLAYSIZE__; + OVL8: file = "%O.8", start = %S, size = __OVERLAYSIZE__; + OVL9: file = "%O.9", start = %S, size = __OVERLAYSIZE__; } - SEGMENTS { ZEROPAGE: load = ZP, type = zp; EXTZP: load = ZP, type = zp, optional = yes; @@ -85,7 +77,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 = rw, optional = yes; BSS: load = MAIN, type = bss, define = yes; AUTOSTRT: load = TRAILER, type = ro; diff --git a/cfg/atarixl.cfg b/cfg/atarixl.cfg index 9573fc78c..197daace6 100644 --- a/cfg/atarixl.cfg +++ b/cfg/atarixl.cfg @@ -1,7 +1,6 @@ FEATURES { STARTADDRESS: default = $2400; } - SYMBOLS { __EXEHDR__: type = import; __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk @@ -9,44 +8,38 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack __STARTADDRESS__: type = export, value = %S; } - MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # just $FFFF - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $0002; # "system check" load chunk - SYSCHKHDR: file = %O, start = $0000, size = $0004; - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; - SYSCHKTRL: file = %O, start = $0000, size = $0006; + SYSCHKHDR: file = %O, start = $0000, size = $0004; + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + SYSCHKTRL: file = %O, start = $0000, size = $0006; # "shadow RAM preparation" load chunk - SRPREPHDR: file = %O, start = $0000, size = $0004; - SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned - SRPREPTRL: file = %O, start = $0000, size = $0006; + SRPREPHDR: file = %O, start = $0000, size = $0004; + SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned + SRPREPTRL: file = %O, start = $0000, size = $0006; # "main program" load chunk - MAINHDR: file = %O, start = $0000, size = $0004; - MAIN: file = %O, define = yes, start = %S + - __LOWBSS_SIZE__, size = $D000 - - __STACKSIZE__ - - %S - - __LOWBSS_SIZE__; + MAINHDR: file = %O, start = $0000, size = $0004; + MAIN: file = %O, define = yes, start = %S + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __LOWBSS_SIZE__; # defines entry point into program - TRAILER: file = %O, start = $0000, size = $0006; + TRAILER: file = %O, start = $0000, size = $0006; # memory beneath the ROM preceeding the character generator - HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; + HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; # address of relocated character generator (same addess as ROM version) - CHARGEN: file = "", define = yes, start = $E000, size = $0400; + CHARGEN: file = "", define = yes, start = $E000, size = $0400; # memory beneath the ROM - HIDDEN_RAM: file = "", define = yes, start = $E400, size = $FFFA - $E400; + HIDDEN_RAM: file = "", define = yes, start = $E400, size = $FFFA - $E400; } - SEGMENTS { ZEROPAGE: load = ZP, type = zp; EXTZP: load = ZP, type = zp, optional = yes; @@ -71,7 +64,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 = rw, optional = yes; BSS: load = MAIN, type = bss, define = yes; AUTOSTRT: load = TRAILER, type = ro; } From 46d4307bbb5e7f536e9ddf5c11f8ff700524ca7e Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 15 Mar 2016 21:19:25 +0100 Subject: [PATCH 0024/2161] Removed ONCE segment. Pure assembler programs don't have constructors. Therefore constructor code ending up in an assembler program should trigger an error. --- cfg/osic1p-asm.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/cfg/osic1p-asm.cfg b/cfg/osic1p-asm.cfg index 3c1b1bda3..88ab69062 100644 --- a/cfg/osic1p-asm.cfg +++ b/cfg/osic1p-asm.cfg @@ -17,7 +17,6 @@ MEMORY { SEGMENTS { ZEROPAGE: load = ZP, type = zp; BOOT: load = HEAD, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, define = yes, optional = yes; CODE: load = MAIN, type = rw; RODATA: load = MAIN, type = rw; DATA: load = MAIN, type = rw; From 0edd05b4bf425e3327e7aec7435a18e593707800 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 15 Mar 2016 21:25:22 +0100 Subject: [PATCH 0025/2161] Removed symbol definition for ONCE. Almost all targets don't need symbols for the ONCE segment. Likely their definition was a C&P error in the first place. --- cfg/bbc.cfg | 2 +- cfg/c128-overlay.cfg | 2 +- cfg/c128.cfg | 2 +- cfg/c16.cfg | 2 +- cfg/gamate.cfg | 2 +- cfg/geos-apple.cfg | 2 +- cfg/geos-cbm.cfg | 2 +- cfg/lunix.cfg | 2 +- cfg/nes.cfg | 2 +- cfg/none.cfg | 2 +- cfg/osic1p.cfg | 2 +- cfg/pce.cfg | 2 +- cfg/pet.cfg | 2 +- cfg/plus4.cfg | 2 +- cfg/sim6502.cfg | 2 +- cfg/sim65c02.cfg | 2 +- cfg/supervision-128k.cfg | 2 +- cfg/supervision-16k.cfg | 2 +- cfg/supervision-64k.cfg | 2 +- cfg/supervision.cfg | 2 +- cfg/vic20-32k.cfg | 2 +- cfg/vic20.cfg | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/cfg/bbc.cfg b/cfg/bbc.cfg index c451951ad..f1aa4a877 100644 --- a/cfg/bbc.cfg +++ b/cfg/bbc.cfg @@ -9,7 +9,7 @@ SEGMENTS { ZEROPAGE: load = ZP, type = zp; STARTUP: load = MAIN, type = ro, define = yes; LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: 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/c128-overlay.cfg b/cfg/c128-overlay.cfg index 8f60fa347..e2cff8b7c 100644 --- a/cfg/c128-overlay.cfg +++ b/cfg/c128-overlay.cfg @@ -35,7 +35,7 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: 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/c128.cfg b/cfg/c128.cfg index 6a98dc5cf..7546e7921 100644 --- a/cfg/c128.cfg +++ b/cfg/c128.cfg @@ -15,7 +15,7 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: 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/c16.cfg b/cfg/c16.cfg index f1ab747cd..1aae78824 100644 --- a/cfg/c16.cfg +++ b/cfg/c16.cfg @@ -15,7 +15,7 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: 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/gamate.cfg b/cfg/gamate.cfg index 4e4253194..74ae9f3e3 100644 --- a/cfg/gamate.cfg +++ b/cfg/gamate.cfg @@ -27,7 +27,7 @@ SEGMENTS { EXTZP: load = ZP, type = zp, define = yes, optional = yes; APPZP: load = ZP, type = zp, define = yes, optional = yes; STARTUP: load = CARTHEADER, type = ro, define = yes; - ONCE: load = ROM, type = ro, define = yes, optional = yes; + ONCE: load = ROM, type = ro, optional = yes; CODE: load = ROM, type = ro, define = yes; RODATA: load = ROM, type = ro, define = yes; DATA: load = ROM, run = RAM, type = rw, define = yes; diff --git a/cfg/geos-apple.cfg b/cfg/geos-apple.cfg index ee8b61aec..9fc7024e1 100644 --- a/cfg/geos-apple.cfg +++ b/cfg/geos-apple.cfg @@ -40,7 +40,7 @@ SEGMENTS { VLIRIDX0: type = ro, load = CVT, align = $200, optional = yes; STARTUP: type = ro, run = VLIR0, load = CVT, align_load = $200, define = yes; LOWCODE: type = ro, run = VLIR0, load = CVT, optional = yes; - ONCE: type = ro, run = VLIR0, load = CVT, define = yes, optional = yes; + ONCE: type = ro, run = VLIR0, load = CVT, optional = yes; CODE: type = ro, run = VLIR0, load = CVT; RODATA: type = ro, run = VLIR0, load = CVT; DATA: type = rw, run = VLIR0, load = CVT; diff --git a/cfg/geos-cbm.cfg b/cfg/geos-cbm.cfg index 42cbe9a48..f9bea76a0 100644 --- a/cfg/geos-cbm.cfg +++ b/cfg/geos-cbm.cfg @@ -37,7 +37,7 @@ SEGMENTS { RECORDS: type = ro, load = CVT, align = $FE, optional = yes; STARTUP: type = ro, run = VLIR0, load = CVT, align_load = $FE, define = yes; LOWCODE: type = ro, run = VLIR0, load = CVT, optional = yes; - ONCE: type = ro, run = VLIR0, load = CVT, define = yes, optional = yes; + ONCE: type = ro, run = VLIR0, load = CVT, optional = yes; CODE: type = ro, run = VLIR0, load = CVT; RODATA: type = ro, run = VLIR0, load = CVT; DATA: type = rw, run = VLIR0, load = CVT; diff --git a/cfg/lunix.cfg b/cfg/lunix.cfg index 3a11cc5d4..0b7b9c8ff 100644 --- a/cfg/lunix.cfg +++ b/cfg/lunix.cfg @@ -12,7 +12,7 @@ SEGMENTS { ZEROPAGE: load = ZP, type = zp, define = yes; # Pseudo-registers STARTUP: load = MAIN, type = ro; # First initialization code LOWCODE: load = MAIN, type = ro, optional = yes; # Legacy from other platforms - ONCE: load = MAIN, type = ro, define = yes, optional = yes; # Library initialization code + ONCE: load = MAIN, type = ro, optional = yes; # Library initialization code CODE: load = MAIN, type = ro; # Program RODATA: load = MAIN, type = ro; # Literals, constants DATA: load = MAIN, type = rw; # Initialized variables diff --git a/cfg/nes.cfg b/cfg/nes.cfg index f68330425..0cc2ce334 100644 --- a/cfg/nes.cfg +++ b/cfg/nes.cfg @@ -37,7 +37,7 @@ SEGMENTS { HEADER: load = HEADER, type = ro; STARTUP: load = ROM0, type = ro, define = yes; LOWCODE: load = ROM0, type = ro, optional = yes; - ONCE: load = ROM0, type = ro, define = yes, optional = yes; + ONCE: load = ROM0, type = ro, optional = yes; CODE: load = ROM0, type = ro, define = yes; RODATA: load = ROM0, type = ro, define = yes; DATA: load = ROM0, run = RAM, type = rw, define = yes; diff --git a/cfg/none.cfg b/cfg/none.cfg index dcee60419..8cd9c4f95 100644 --- a/cfg/none.cfg +++ b/cfg/none.cfg @@ -8,7 +8,7 @@ MEMORY { SEGMENTS { ZEROPAGE: load = ZP, type = zp; LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = rw; RODATA: load = MAIN, type = rw; DATA: load = MAIN, type = rw; diff --git a/cfg/osic1p.cfg b/cfg/osic1p.cfg index 3507ebeba..f7ca08344 100644 --- a/cfg/osic1p.cfg +++ b/cfg/osic1p.cfg @@ -20,7 +20,7 @@ SEGMENTS { BOOT: load = HEAD, type = ro, optional = yes; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = rw; RODATA: load = MAIN, type = rw; DATA: load = MAIN, type = rw; diff --git a/cfg/pce.cfg b/cfg/pce.cfg index 219cbdec3..6332f8eff 100644 --- a/cfg/pce.cfg +++ b/cfg/pce.cfg @@ -21,7 +21,7 @@ SEGMENTS { EXTZP: load = ZP, type = zp, define = yes, optional = yes; APPZP: load = ZP, type = zp, define = yes, optional = yes; STARTUP: load = ROM0, type = ro, define = yes; - ONCE: load = ROM0, type = ro, define = yes, optional = yes; + ONCE: load = ROM0, type = ro, optional = yes; CODE: load = ROM0, type = ro, define = yes; RODATA: load = ROM0, type = ro, define = yes; DATA: load = ROM0, run = RAM, type = rw, define = yes; diff --git a/cfg/pet.cfg b/cfg/pet.cfg index aad3f579e..efde48efe 100644 --- a/cfg/pet.cfg +++ b/cfg/pet.cfg @@ -15,7 +15,7 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro; STARTUP: load = RAM, type = ro; LOWCODE: load = RAM, type = ro, optional = yes; - ONCE: load = RAM, type = ro, define = yes, optional = yes; + ONCE: load = RAM, type = ro, optional = yes; CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; diff --git a/cfg/plus4.cfg b/cfg/plus4.cfg index 4f73e40c2..610a7c23c 100644 --- a/cfg/plus4.cfg +++ b/cfg/plus4.cfg @@ -15,7 +15,7 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: 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/sim6502.cfg b/cfg/sim6502.cfg index b50703bab..5e7402262 100644 --- a/cfg/sim6502.cfg +++ b/cfg/sim6502.cfg @@ -12,7 +12,7 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: 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/sim65c02.cfg b/cfg/sim65c02.cfg index b50703bab..5e7402262 100644 --- a/cfg/sim65c02.cfg +++ b/cfg/sim65c02.cfg @@ -12,7 +12,7 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: 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/supervision-128k.cfg b/cfg/supervision-128k.cfg index 3cfdf1276..6cfde6551 100644 --- a/cfg/supervision-128k.cfg +++ b/cfg/supervision-128k.cfg @@ -21,7 +21,7 @@ MEMORY { } SEGMENTS { LOWCODE: load = ROM, type = ro, optional = yes; - ONCE: load = ROM, type = ro, define = yes, optional = yes; + ONCE: load = ROM, type = ro, optional = yes; CODE: load = ROM, type = ro; BANK1: load = BANKROM1, type = ro; BANK2: load = BANKROM2, type = ro; diff --git a/cfg/supervision-16k.cfg b/cfg/supervision-16k.cfg index 2e96b9a72..e42677304 100644 --- a/cfg/supervision-16k.cfg +++ b/cfg/supervision-16k.cfg @@ -16,7 +16,7 @@ MEMORY { SEGMENTS { ZEROPAGE: load = ZP, type = zp, define = yes; LOWCODE: load = ROM, type = ro, optional = yes; - ONCE: load = ROM, type = ro, define = yes, optional = yes; + ONCE: load = ROM, type = ro, optional = yes; CODE: load = ROM, type = ro, define = yes; RODATA: load = ROM, type = ro, define = yes; DATA: load = ROM, run = RAM, type = rw, define = yes; diff --git a/cfg/supervision-64k.cfg b/cfg/supervision-64k.cfg index 63338d1e3..18c7b4a45 100644 --- a/cfg/supervision-64k.cfg +++ b/cfg/supervision-64k.cfg @@ -17,7 +17,7 @@ MEMORY { } SEGMENTS { LOWCODE: load = ROM, type = ro, optional = yes; - ONCE: load = ROM, type = ro, define = yes, optional = yes; + ONCE: load = ROM, type = ro, optional = yes; CODE: load = ROM, type = ro; RODATA: load = ROM, type = ro; BANK1: load = BANKROM1, type = ro; diff --git a/cfg/supervision.cfg b/cfg/supervision.cfg index b7ae207b8..da701b511 100644 --- a/cfg/supervision.cfg +++ b/cfg/supervision.cfg @@ -12,7 +12,7 @@ MEMORY { SEGMENTS { ZEROPAGE: load = ZP, type = zp, define = yes; LOWCODE: load = ROM, type = ro, optional = yes; - ONCE: load = ROM, type = ro, define = yes, optional = yes; + ONCE: load = ROM, type = ro, optional = yes; CODE: load = ROM, type = ro, define = yes; RODATA: load = ROM, type = ro, define = yes; DATA: load = ROM, run = RAM, type = rw, define = yes; diff --git a/cfg/vic20-32k.cfg b/cfg/vic20-32k.cfg index 4f4225825..f592d7bd0 100644 --- a/cfg/vic20-32k.cfg +++ b/cfg/vic20-32k.cfg @@ -17,7 +17,7 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: 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.cfg b/cfg/vic20.cfg index 4eba7bfa9..98f6f82b3 100644 --- a/cfg/vic20.cfg +++ b/cfg/vic20.cfg @@ -15,7 +15,7 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; From a2c9cb021a396c8e8771ad6bfb00fbed6e47cc87 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 15 Mar 2016 21:36:38 +0100 Subject: [PATCH 0026/2161] Moved things into ONCE. Code and or data used only during initialization belongs into the ONCE segment. --- libsrc/c16/cgetc.s | 11 +++-------- libsrc/nes/ppu.s | 5 +++-- libsrc/plus4/cgetc.s | 11 +++-------- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/libsrc/c16/cgetc.s b/libsrc/c16/cgetc.s index a476a5d1b..3ee31a757 100644 --- a/libsrc/c16/cgetc.s +++ b/libsrc/c16/cgetc.s @@ -69,6 +69,9 @@ L2: jsr KBDREAD ; Read char and return in A .endproc +fnkeys: .byte $01, $01, $01, $01, $01, $01, $01, $01 + .byte 133, 137, 134, 138, 135, 139, 136, 140 + .code @@ -82,11 +85,3 @@ L2: jsr KBDREAD ; Read char and return in A rts .endproc - - -; Function key table, readonly - -.rodata -fnkeys: .byte $01, $01, $01, $01, $01, $01, $01, $01 - .byte 133, 137, 134, 138, 135, 139, 136, 140 - diff --git a/libsrc/nes/ppu.s b/libsrc/nes/ppu.s index 06dc10a65..07b6842f7 100644 --- a/libsrc/nes/ppu.s +++ b/libsrc/nes/ppu.s @@ -68,6 +68,8 @@ ;----------------------------------------------------------------------------- +.segment "ONCE" + .proc ppuinit lda #%10101000 @@ -104,7 +106,6 @@ .endproc - ;----------------------------------------------------------------------------- .proc paletteinit @@ -126,7 +127,7 @@ bne @loop rts - + .endproc ;----------------------------------------------------------------------------- diff --git a/libsrc/plus4/cgetc.s b/libsrc/plus4/cgetc.s index 25a63c053..784bac267 100644 --- a/libsrc/plus4/cgetc.s +++ b/libsrc/plus4/cgetc.s @@ -72,6 +72,9 @@ L2: sta ENABLE_ROM ; Bank in the ROM .endproc +fnkeys: .byte $01, $01, $01, $01, $01, $01, $01, $01 + .byte 133, 137, 134, 138, 135, 139, 136, 140 + .segment "LOWCODE" ; Accesses the ROM - must go into low mem @@ -87,11 +90,3 @@ L2: sta ENABLE_ROM ; Bank in the ROM rts .endproc - - -; Function key table, readonly - -.rodata -fnkeys: .byte $01, $01, $01, $01, $01, $01, $01, $01 - .byte 133, 137, 134, 138, 135, 139, 136, 140 - From 4270b8a96c9cdad5c20cc9760070c23e5e07d9a1 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 15 Mar 2016 21:48:44 +0100 Subject: [PATCH 0027/2161] Fixed segment properties. The CBMx10 targets don't use the INIT segment in the startup code. So it may turn out to be not necessary at all for certain programs. The CBMx10 targets don't need symbols for the ONCE segment. Likely their definition was a C&P error in the first place. --- cfg/cbm510.cfg | 4 ++-- cfg/cbm610.cfg | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cfg/cbm510.cfg b/cfg/cbm510.cfg index 5f73174f3..b4e228fdd 100644 --- a/cfg/cbm510.cfg +++ b/cfg/cbm510.cfg @@ -20,11 +20,11 @@ SEGMENTS { PAGE2: load = PAGE2, type = rw; PAGE3: load = PAGE3, type = rw; LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: 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 = bss; + INIT: load = MAIN, type = bss, optional = yes; BSS: load = MAIN, type = bss, define = yes; } FEATURES { diff --git a/cfg/cbm610.cfg b/cfg/cbm610.cfg index fb4349dba..431734cd2 100644 --- a/cfg/cbm610.cfg +++ b/cfg/cbm610.cfg @@ -17,11 +17,11 @@ SEGMENTS { PAGE2: load = PAGE2, type = rw; PAGE3: load = PAGE3, type = rw; LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: 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 = bss; + INIT: load = MAIN, type = bss, optional = yes; BSS: load = MAIN, type = bss, define = yes; } FEATURES { From 3d6cbec6a1e52340ce9459eea7d9bdc2dcd4717b Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 16 Mar 2016 16:00:09 +0100 Subject: [PATCH 0028/2161] Adjust linker config to match startup code. Apply https://github.com/cc65/cc65/commit/aaf90c1252a09346deb1ccdab96546368afdbbdd to the Supervision default configuration. --- cfg/supervision.cfg | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cfg/supervision.cfg b/cfg/supervision.cfg index da701b511..c96351e5f 100644 --- a/cfg/supervision.cfg +++ b/cfg/supervision.cfg @@ -2,10 +2,13 @@ # make sure the halves are mirrored in the 64kbyte cartridge image # or reset from code >0xc000 and switch bank to the 3rd bank +SYMBOLS { + __STACKSIZE__: type = weak, value = $0100; # 1 page stack +} MEMORY { ZP: file = "", start = $0000, size = $0100; CPUSTACK: file = "", start = $0100, size = $0100; - RAM: file = "", start = $0200, size = $1E00, define = yes; + RAM: file = "", start = $0200, size = $1E00 - __STACKSIZE__; VRAM: file = "", start = $4000, size = $2000; ROM: file = %O, start = $8000, size = $8000, fill = yes, fillval = $FF, define = yes; } From 1d1ba3ed3bf0b0b31e34601b7f40201589887537 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 16 Mar 2016 16:28:32 +0100 Subject: [PATCH 0029/2161] Adjusted constructors. The constructors are _NOT_ allowed anymore to access the BSS. Rather they must use the DATA segment or the INIT segment. The latter isn't cleared at any point so the constructors may use it to expose values to the main program. However they must make sure to always write the values as they are not pre-initialized. --- cfg/atmos.cfg | 11 +++++---- cfg/geos-apple.cfg | 1 + cfg/geos-cbm.cfg | 1 + libsrc/apple2/dosdetect.s | 4 ++-- libsrc/apple2/extra/iobuf-0800.s | 2 +- libsrc/apple2/get_ostype.s | 2 +- libsrc/apple2/mainargs.s | 8 +++---- libsrc/atari/dosdetect.s | 4 ++-- libsrc/atari/getargs.s | 10 ++------ libsrc/atmos/capslock.s | 2 +- libsrc/atmos/mainargs.s | 34 +++++++++++++++------------- libsrc/atmos/read.s | 3 +-- libsrc/c128/cgetc.s | 8 +++---- libsrc/common/_environ.s | 8 +++---- libsrc/geos-common/conio/_scrsize.s | 2 +- libsrc/geos-common/system/mainargs.s | 4 ++-- 16 files changed, 49 insertions(+), 55 deletions(-) diff --git a/cfg/atmos.cfg b/cfg/atmos.cfg index e5a574f0a..bb79a1e8a 100644 --- a/cfg/atmos.cfg +++ b/cfg/atmos.cfg @@ -8,10 +8,10 @@ SYMBOLS { __RAMEND__: type = weak, value = $9800 + $1C00 * __GRAB__; } MEMORY { - ZP: file = "", define = yes, start = $00E2, size = $001A; - TAPEHDR: file = %O, type = ro, start = $0000, size = $001F; - BASHEAD: file = %O, define = yes, start = $0501, size = $000D; - MAIN: file = %O, define = yes, start = __BASHEAD_LAST__, size = __RAMEND__ - __RAM_START__ - __STACKSIZE__; + ZP: file = "", define = yes, start = $00E2, size = $001A; + TAPEHDR: file = %O, type = ro, start = $0000, size = $001F; + BASHEAD: file = %O, define = yes, start = $0501, size = $000D; + MAIN: file = %O, define = yes, start = __BASHEAD_LAST__, size = __RAMEND__ - __MAIN_START__ - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; @@ -21,8 +21,9 @@ SEGMENTS { LOWCODE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; RODATA: load = MAIN, type = ro; - ONCE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = rw, optional = yes; ZPSAVE1: load = MAIN, type = rw, define = yes; # ZPSAVE1, ZPSAVE2 must be together ZPSAVE2: load = MAIN, type = bss; # see "libsrc/atmos/crt0.s" BSS: load = MAIN, type = bss, define = yes; diff --git a/cfg/geos-apple.cfg b/cfg/geos-apple.cfg index 9fc7024e1..b39cf1ebe 100644 --- a/cfg/geos-apple.cfg +++ b/cfg/geos-apple.cfg @@ -44,6 +44,7 @@ SEGMENTS { CODE: type = ro, run = VLIR0, load = CVT; RODATA: type = ro, run = VLIR0, load = CVT; DATA: type = rw, run = VLIR0, load = CVT; + INIT: type = bss, load = VLIR0, optional = yes; BSS: type = bss, load = VLIR0, define = yes; VLIRIDX1: type = ro, load = CVT, align = $200, optional = yes; OVERLAY1: type = ro, run = VLIR1, load = CVT, align_load = $200, optional = yes; diff --git a/cfg/geos-cbm.cfg b/cfg/geos-cbm.cfg index f9bea76a0..0269dbacb 100644 --- a/cfg/geos-cbm.cfg +++ b/cfg/geos-cbm.cfg @@ -41,6 +41,7 @@ SEGMENTS { CODE: type = ro, run = VLIR0, load = CVT; RODATA: type = ro, run = VLIR0, load = CVT; DATA: type = rw, run = VLIR0, load = CVT; + INIT: type = bss, load = VLIR0, optional = yes; BSS: type = bss, load = VLIR0, define = yes; OVERLAY1: type = ro, run = VLIR1, load = CVT, align_load = $FE, optional = yes; OVERLAY2: type = ro, run = VLIR2, load = CVT, align_load = $FE, optional = yes; diff --git a/libsrc/apple2/dosdetect.s b/libsrc/apple2/dosdetect.s index cedb1f3e3..46fbb5484 100644 --- a/libsrc/apple2/dosdetect.s +++ b/libsrc/apple2/dosdetect.s @@ -43,6 +43,6 @@ initdostype: : sta __dos_type done: rts - .bss + .data -__dos_type: .res 1 +__dos_type: .byte $00 diff --git a/libsrc/apple2/extra/iobuf-0800.s b/libsrc/apple2/extra/iobuf-0800.s index 2e5d1927e..0ad7a751f 100644 --- a/libsrc/apple2/extra/iobuf-0800.s +++ b/libsrc/apple2/extra/iobuf-0800.s @@ -90,6 +90,6 @@ iobuf_free: ; ------------------------------------------------------------------------ - .bss + .data table: .res MAX_FDS diff --git a/libsrc/apple2/get_ostype.s b/libsrc/apple2/get_ostype.s index cff6af9a3..b54e38d63 100644 --- a/libsrc/apple2/get_ostype.s +++ b/libsrc/apple2/get_ostype.s @@ -65,6 +65,6 @@ _get_ostype: ldx #$00 rts - .bss + .segment "INIT" ostype: .res 1 diff --git a/libsrc/apple2/mainargs.s b/libsrc/apple2/mainargs.s index e3db8bb10..de2f385f1 100644 --- a/libsrc/apple2/mainargs.s +++ b/libsrc/apple2/mainargs.s @@ -83,6 +83,7 @@ initmainargs: ; destroyed. ldy #$00 + sty buffer + BUF_LEN - 1 : lda BASIC_BUF,x sta buffer,y inx @@ -166,14 +167,13 @@ done: lda #<argv stx __argv+1 rts -; This array is zeroed before initmainargs is called. -; char* argv[MAXARGS+1] = {FNAM}; - .data +; char* argv[MAXARGS+1] = {FNAM}; + argv: .addr FNAM .res MAXARGS * 2 - .bss + .segment "INIT" buffer: .res BUF_LEN diff --git a/libsrc/atari/dosdetect.s b/libsrc/atari/dosdetect.s index cac9a6536..c2888d888 100644 --- a/libsrc/atari/dosdetect.s +++ b/libsrc/atari/dosdetect.s @@ -48,6 +48,6 @@ done: rts ; ------------------------------------------------------------------------ ; Data - .bss + .data -__dos_type: .res 1 ; default to ATARIDOS +__dos_type: .byte 0 ; default to ATARIDOS diff --git a/libsrc/atari/getargs.s b/libsrc/atari/getargs.s index d32c0a268..e3b18b2f9 100644 --- a/libsrc/atari/getargs.s +++ b/libsrc/atari/getargs.s @@ -23,12 +23,6 @@ SPACE = 32 ; SPACE char. .segment "ONCE" initmainargs: - lda #0 - sta __argc - sta __argc+1 - sta __argv - sta __argv+1 - lda __dos_type ; which DOS? cmp #ATARIDOS beq nargdos ; DOS does not support arguments @@ -120,7 +114,7 @@ eopar: finargs: lda __argc - asl + asl tax lda #0 sta argv,x @@ -134,7 +128,7 @@ finargs: ; -------------------------------------------------------------------------- ; Data -.bss +.segment "INIT" argv: .res (1 + MAXARGS) * 2 diff --git a/libsrc/atmos/capslock.s b/libsrc/atmos/capslock.s index 91c484250..0260b3f9f 100644 --- a/libsrc/atmos/capslock.s +++ b/libsrc/atmos/capslock.s @@ -43,7 +43,7 @@ restore_caps: ;-------------------------------------------------------------------------- -.bss +.segment "INIT" capsave: .res 1 diff --git a/libsrc/atmos/mainargs.s b/libsrc/atmos/mainargs.s index 8b57d9855..3ab353c15 100644 --- a/libsrc/atmos/mainargs.s +++ b/libsrc/atmos/mainargs.s @@ -13,7 +13,7 @@ .macpack generic MAXARGS = 10 ; Maximum number of arguments allowed -REM = $9d ; BASIC token-code +REM = $9D ; BASIC token-code ;--------------------------------------------------------------------------- @@ -26,21 +26,21 @@ REM = $9d ; BASIC token-code ; Assume that the program was loaded, a moment ago, by the traditional LOAD ; statement. Save the "most-recent filename" as argument #0. -; Because the buffer, that we're copying into, was zeroed out, -; we don't need to add a NUL character. -; - ldy #FNAME_LEN - 1 ; limit the length + + ldy #FNAME_LEN ; Limit the length + lda #0 ; The terminating NUL character + beq L1 ; Branch always L0: lda CFOUND_NAME,y - sta name,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. + beq done ; No "rem", no args. inx cmp #REM bne L2 @@ -62,7 +62,7 @@ next: lda BASIC_BUF,x beq done ; End of line reached inx cmp #' ' ; Skip leading spaces - beq next ; + 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 @@ -79,7 +79,7 @@ setterm:sta term ; Set end of argument marker txa ; Get low byte add #<args - sta argv,y ; argv[y]= &arg + sta argv,y ; argv[y]=&arg lda #>$0000 adc #>args sta argv+1,y @@ -99,7 +99,7 @@ argloop:lda BASIC_BUF,x ; A contains the terminating character. To make the argument a valid C string, ; replace the terminating character by a zero. - lda #$00 + lda #0 sta args-1,x ; Check if the maximum number of command line arguments is reached. If not, @@ -120,14 +120,16 @@ done: lda #<argv .endproc ; These arrays are zeroed before initmainargs is called. -; char name[16+1]; -; char* argv[MAXARGS+1]={name}; -; -.bss + +.segment "INIT" + term: .res 1 name: .res FNAME_LEN + 1 args: .res SCREEN_XSIZE * 2 - 1 .data + +; char* argv[MAXARGS+1]={name}; + argv: .addr name - .res MAXARGS * 2, $00 + .res MAXARGS * 2 diff --git a/libsrc/atmos/read.s b/libsrc/atmos/read.s index edf9d161d..c44dc8584 100644 --- a/libsrc/atmos/read.s +++ b/libsrc/atmos/read.s @@ -79,8 +79,7 @@ initstdin: ;-------------------------------------------------------------------------- -.bss +.segment "INIT" text_count: .res 1 - diff --git a/libsrc/c128/cgetc.s b/libsrc/c128/cgetc.s index 7cb4c159e..bc9d8da7f 100644 --- a/libsrc/c128/cgetc.s +++ b/libsrc/c128/cgetc.s @@ -39,7 +39,7 @@ L2: jsr KBDREAD ; Read char and return in A ;-------------------------------------------------------------------------- ; Module constructor/destructor -.bss +.segment "INIT" keyvec: .res 2 .segment "ONCE" @@ -48,9 +48,9 @@ initcgetc: ; Save the old vector lda KeyStoreVec + ldx KeyStoreVec+1 sta keyvec - lda KeyStoreVec+1 - sta keyvec+1 + stx keyvec+1 ; Set the new vector. I can only hope that this works for other C128 ; versions... @@ -68,5 +68,3 @@ SetVec: sei stx KeyStoreVec+1 cli rts - - diff --git a/libsrc/common/_environ.s b/libsrc/common/_environ.s index 6a53f80a8..f9a349e67 100644 --- a/libsrc/common/_environ.s +++ b/libsrc/common/_environ.s @@ -15,10 +15,10 @@ .export __environ, __envcount, __envsize .import initenv .constructor env_init - + env_init := initenv - -.bss + +.data __environ: .addr 0 @@ -26,5 +26,3 @@ __envcount: .byte 0 __envsize: .byte 0 - - diff --git a/libsrc/geos-common/conio/_scrsize.s b/libsrc/geos-common/conio/_scrsize.s index dded4ca42..494182b9d 100644 --- a/libsrc/geos-common/conio/_scrsize.s +++ b/libsrc/geos-common/conio/_scrsize.s @@ -43,7 +43,7 @@ screensize: ldy ysize rts -.bss +.segment "INIT" xsize: .res 1 diff --git a/libsrc/geos-common/system/mainargs.s b/libsrc/geos-common/system/mainargs.s index 14c624759..f38beab34 100644 --- a/libsrc/geos-common/system/mainargs.s +++ b/libsrc/geos-common/system/mainargs.s @@ -5,7 +5,7 @@ ; Setup arguments for main ; ; There is always either 1 or 3 arguments: -; <program name>,0 +; <program name>, 0 ; or ; <program name>, <data file name>, <data disk name>, 0 ; the 2nd case is when using DeskTop user drags an icon of a file and drops it @@ -71,7 +71,7 @@ argv: .word dataDiskName ; dataDiskName .word $0000 ; last one must be NULL -.bss +.segment "INIT" argv0: .res 17 ; Program name From e3cbc7e8b8e1cbb294934cd3d80f9a9f01a2cf28 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 17 Mar 2016 21:07:19 +0100 Subject: [PATCH 0030/2161] Moved run location of ONCE segment. Make the same changes to the Apple II that were done with https://github.com/cc65/cc65/commit/0ee9b2e446198746c3a05b142ecd00784becf727 to the C64. Notes: - The startup code deliberately doesn't make use of symbols defined for the LC segment as that segment is optional. - The <...>-asm.cfg configs move the segment BSS to an own memory area BSS although this doesn't seem necessary. However the benefit is that the size of the memeory area MAIN is identical to the number of bytes loaded from disk into RAM. To keep this an invariant for all Apple II configs allows to simplify the EXEHDR to just refer to the symbols defined for MAIN. --- cfg/apple2-asm.cfg | 15 ++--- cfg/apple2-overlay.cfg | 55 ++++++++-------- cfg/apple2-system.cfg | 33 +++++----- cfg/apple2.cfg | 37 +++++------ cfg/apple2enh-asm.cfg | 21 +++--- cfg/apple2enh-overlay.cfg | 55 ++++++++-------- cfg/apple2enh-system.cfg | 33 +++++----- cfg/apple2enh.cfg | 37 +++++------ libsrc/apple2/crt0.s | 131 ++++++++++++++++++-------------------- libsrc/apple2/exehdr.s | 6 +- 10 files changed, 196 insertions(+), 227 deletions(-) diff --git a/cfg/apple2-asm.cfg b/cfg/apple2-asm.cfg index b9095cf0c..151ba84c4 100644 --- a/cfg/apple2-asm.cfg +++ b/cfg/apple2-asm.cfg @@ -3,20 +3,17 @@ FEATURES { STARTADDRESS: default = $0803; } -SYMBOLS { - __LOADADDR__: type = weak, value = __CODE_RUN__; - __LOADSIZE__: type = weak, value = __BSS_RUN__ - __CODE_RUN__; -} MEMORY { - ZP: start = $0080, size = $001A, define = yes; - HEADER: file = %O, start = $0000, size = $0004; - MAIN: file = %O, start = %S, size = $C000 - %S; + ZP: file = "", start = $0000, size = $00FF; + HEADER: file = %O, start = %S - 4, size = $0004; + MAIN: file = %O, define = yes, start = %S, size = $C000 - %S; + BSS: file = "", start = __MAIN_LAST__, size = $C000 - __MAIN_LAST__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp, optional = yes; EXEHDR: load = HEADER, type = ro, optional = yes; - CODE: load = MAIN, type = rw, optional = yes, define = yes; + CODE: load = MAIN, type = rw, optional = yes; RODATA: load = MAIN, type = ro, optional = yes; DATA: load = MAIN, type = rw, optional = yes; - BSS: load = MAIN, type = bss, optional = yes, define = yes; + BSS: load = BSS, type = bss, optional = yes, define = yes; } diff --git a/cfg/apple2-overlay.cfg b/cfg/apple2-overlay.cfg index 1e34b6250..e6a5ae25c 100644 --- a/cfg/apple2-overlay.cfg +++ b/cfg/apple2-overlay.cfg @@ -12,21 +12,18 @@ FEATURES { } SYMBOLS { __EXEHDR__: type = import; + __STACKSIZE__: type = weak, value = $0800; # 2k stack __HIMEM__: type = weak, value = $9600; # Presumed RAM end __LCADDR__: type = weak, value = $D400; # Behind quit code __LCSIZE__: type = weak, value = $0C00; # Rest of bank two - __STACKSIZE__: type = weak, value = $0800; # 2k stack __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay - __LOADADDR__: type = weak, value = __STARTUP_RUN__; - __LOADSIZE__: type = weak, value = __INIT_RUN__ - __STARTUP_RUN__ + - __MOVE_LAST__ - __MOVE_START__; } MEMORY { - ZP: define = yes, start = $0080, size = $001A; - HEADER: file = %O, start = $0000, size = $0004; - MAIN: file = %O, start = %S + __OVERLAYSIZE__, size = __HIMEM__ - __STACKSIZE__ - __OVERLAYSIZE__ - %S; - MOVE: file = %O, define = yes, start = $0000, size = $FFFF; - LC: define = yes, start = __LCADDR__, size = __LCSIZE__; + ZP: file = "", define = yes, start = $0080, size = $001A; + HEADER: file = %O, start = %S - 4, size = $0004; + 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__; OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__; OVL2: file = "%O.2", start = %S, size = __OVERLAYSIZE__; OVL3: file = "%O.3", start = %S, size = __OVERLAYSIZE__; @@ -38,26 +35,26 @@ MEMORY { OVL9: file = "%O.9", start = %S, size = __OVERLAYSIZE__; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp; - EXEHDR: load = HEADER, type = ro; - STARTUP: load = MAIN, type = ro, define = 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 = bss, define = yes; - BSS: load = MAIN, type = bss, define = yes; - ONCE: load = MOVE, run = MAIN, type = ro, define = yes, optional = yes; - LC: load = MOVE, run = LC, type = ro, 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; - OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes; - OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes; - OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes; - OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes; - OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes; - OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes; + ZEROPAGE: load = ZP, type = zp; + EXEHDR: load = HEADER, type = ro; + STARTUP: load = MAIN, type = ro, define = 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; + ONCE: load = MAIN, type = ro, define = yes; + LC: load = MAIN, run = LC, type = ro, optional = yes; + BSS: load = BSS, type = bss, define = 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; + OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes; + OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes; + OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes; + OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes; + OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes; + OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/apple2-system.cfg b/cfg/apple2-system.cfg index 960be378c..f4684d9c2 100644 --- a/cfg/apple2-system.cfg +++ b/cfg/apple2-system.cfg @@ -1,30 +1,27 @@ # Configuration for ProDOS 8 system programs (without the header) SYMBOLS { + __STACKSIZE__: type = weak, value = $0800; # 2k stack __LCADDR__: type = weak, value = $D400; # Behind quit code __LCSIZE__: type = weak, value = $0C00; # Rest of bank two - __STACKSIZE__: type = weak, value = $0800; # 2k stack - __LOADADDR__: type = weak, value = __STARTUP_RUN__; - __LOADSIZE__: type = weak, value = __INIT_RUN__ - __STARTUP_RUN__ + - __MOVE_LAST__ - __MOVE_START__; } MEMORY { - ZP: define = yes, start = $0080, size = $001A; - MAIN: file = %O, start = $2000, size = $9F00 - __STACKSIZE__; - MOVE: file = %O, define = yes, start = $0000, size = $FFFF; - LC: define = yes, start = __LCADDR__, size = __LCSIZE__; + ZP: file = "", define = yes, start = $0080, size = $001A; + MAIN: file = %O, start = $2000, size = $BF00 - $2000; + BSS: file = "", start = __ONCE_RUN__, size = $BF00 - __STACKSIZE__ - __ONCE_RUN__; + LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp; - STARTUP: load = MAIN, type = ro, define = 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 = bss, define = yes; - BSS: load = MAIN, type = bss, define = yes; - ONCE: load = MOVE, run = RAM, type = ro, define = yes, optional = yes; - LC: load = MOVE, run = LC, type = ro, optional = yes; + ZEROPAGE: load = ZP, type = zp; + 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; + ONCE: load = MAIN, type = ro, define = yes; + LC: load = MAIN, run = LC, type = ro, optional = yes; + BSS: load = BSS, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/apple2.cfg b/cfg/apple2.cfg index 875103041..eba2a0e66 100644 --- a/cfg/apple2.cfg +++ b/cfg/apple2.cfg @@ -5,33 +5,30 @@ FEATURES { } SYMBOLS { __EXEHDR__: type = import; + __STACKSIZE__: type = weak, value = $0800; # 2k stack __HIMEM__: type = weak, value = $9600; # Presumed RAM end __LCADDR__: type = weak, value = $D400; # Behind quit code __LCSIZE__: type = weak, value = $0C00; # Rest of bank two - __STACKSIZE__: type = weak, value = $0800; # 2k stack - __LOADADDR__: type = weak, value = __STARTUP_RUN__; - __LOADSIZE__: type = weak, value = __INIT_RUN__ - __STARTUP_RUN__ + - __MOVE_LAST__ - __MOVE_START__; } MEMORY { - ZP: define = yes, start = $0080, size = $001A; - HEADER: file = %O, start = $0000, size = $0004; - MAIN: file = %O, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S; - MOVE: file = %O, define = yes, start = $0000, size = $FFFF; - LC: define = yes, start = __LCADDR__, size = __LCSIZE__; + ZP: file = "", define = yes, start = $0080, size = $001A; + HEADER: file = %O, start = %S - 4, size = $0004; + 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__; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp; - EXEHDR: load = HEADER, type = ro; - STARTUP: load = MAIN, type = ro, define = 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 = bss, define = yes; - BSS: load = MAIN, type = bss, define = yes; - ONCE: load = MOVE, run = MAIN, type = ro, define = yes, optional = yes; - LC: load = MOVE, run = LC, type = ro, optional = yes; + ZEROPAGE: load = ZP, type = zp; + 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; + ONCE: load = MAIN, type = ro, define = yes; + LC: load = MAIN, run = LC, type = ro, optional = yes; + BSS: load = BSS, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/apple2enh-asm.cfg b/cfg/apple2enh-asm.cfg index f7ede1bfe..151ba84c4 100644 --- a/cfg/apple2enh-asm.cfg +++ b/cfg/apple2enh-asm.cfg @@ -3,18 +3,17 @@ FEATURES { STARTADDRESS: default = $0803; } -SYMBOLS { - __LOADADDR__: type = weak, value = __CODE_RUN__; - __LOADSIZE__: type = weak, value = __BSS_RUN__ - __CODE_RUN__; -} MEMORY { - HEADER: file = %O, start = $0000, size = $0004; - MAIN: file = %O, start = %S, size = $C000 - %S; + ZP: file = "", start = $0000, size = $00FF; + HEADER: file = %O, start = %S - 4, size = $0004; + MAIN: file = %O, define = yes, start = %S, size = $C000 - %S; + BSS: file = "", start = __MAIN_LAST__, size = $C000 - __MAIN_LAST__; } SEGMENTS { - EXEHDR: load = HEADER, type = ro, optional = yes; - CODE: load = MAIN, type = rw, optional = yes, define = yes; - RODATA: load = MAIN, type = ro, optional = yes; - DATA: load = MAIN, type = rw, optional = yes; - BSS: load = MAIN, type = bss, optional = yes, define = yes; + ZEROPAGE: load = ZP, type = zp, optional = yes; + EXEHDR: load = HEADER, type = ro, optional = yes; + CODE: load = MAIN, type = rw, optional = yes; + RODATA: load = MAIN, type = ro, optional = yes; + DATA: load = MAIN, type = rw, optional = yes; + BSS: load = BSS, type = bss, optional = yes, define = yes; } diff --git a/cfg/apple2enh-overlay.cfg b/cfg/apple2enh-overlay.cfg index 1e34b6250..e6a5ae25c 100644 --- a/cfg/apple2enh-overlay.cfg +++ b/cfg/apple2enh-overlay.cfg @@ -12,21 +12,18 @@ FEATURES { } SYMBOLS { __EXEHDR__: type = import; + __STACKSIZE__: type = weak, value = $0800; # 2k stack __HIMEM__: type = weak, value = $9600; # Presumed RAM end __LCADDR__: type = weak, value = $D400; # Behind quit code __LCSIZE__: type = weak, value = $0C00; # Rest of bank two - __STACKSIZE__: type = weak, value = $0800; # 2k stack __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay - __LOADADDR__: type = weak, value = __STARTUP_RUN__; - __LOADSIZE__: type = weak, value = __INIT_RUN__ - __STARTUP_RUN__ + - __MOVE_LAST__ - __MOVE_START__; } MEMORY { - ZP: define = yes, start = $0080, size = $001A; - HEADER: file = %O, start = $0000, size = $0004; - MAIN: file = %O, start = %S + __OVERLAYSIZE__, size = __HIMEM__ - __STACKSIZE__ - __OVERLAYSIZE__ - %S; - MOVE: file = %O, define = yes, start = $0000, size = $FFFF; - LC: define = yes, start = __LCADDR__, size = __LCSIZE__; + ZP: file = "", define = yes, start = $0080, size = $001A; + HEADER: file = %O, start = %S - 4, size = $0004; + 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__; OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__; OVL2: file = "%O.2", start = %S, size = __OVERLAYSIZE__; OVL3: file = "%O.3", start = %S, size = __OVERLAYSIZE__; @@ -38,26 +35,26 @@ MEMORY { OVL9: file = "%O.9", start = %S, size = __OVERLAYSIZE__; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp; - EXEHDR: load = HEADER, type = ro; - STARTUP: load = MAIN, type = ro, define = 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 = bss, define = yes; - BSS: load = MAIN, type = bss, define = yes; - ONCE: load = MOVE, run = MAIN, type = ro, define = yes, optional = yes; - LC: load = MOVE, run = LC, type = ro, 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; - OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes; - OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes; - OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes; - OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes; - OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes; - OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes; + ZEROPAGE: load = ZP, type = zp; + EXEHDR: load = HEADER, type = ro; + STARTUP: load = MAIN, type = ro, define = 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; + ONCE: load = MAIN, type = ro, define = yes; + LC: load = MAIN, run = LC, type = ro, optional = yes; + BSS: load = BSS, type = bss, define = 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; + OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes; + OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes; + OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes; + OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes; + OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes; + OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/apple2enh-system.cfg b/cfg/apple2enh-system.cfg index 6134851f0..f4684d9c2 100644 --- a/cfg/apple2enh-system.cfg +++ b/cfg/apple2enh-system.cfg @@ -1,30 +1,27 @@ # Configuration for ProDOS 8 system programs (without the header) SYMBOLS { + __STACKSIZE__: type = weak, value = $0800; # 2k stack __LCADDR__: type = weak, value = $D400; # Behind quit code __LCSIZE__: type = weak, value = $0C00; # Rest of bank two - __STACKSIZE__: type = weak, value = $0800; # 2k stack - __LOADADDR__: type = weak, value = __STARTUP_RUN__; - __LOADSIZE__: type = weak, value = __INIT_RUN__ - __STARTUP_RUN__ + - __MOVE_LAST__ - __MOVE_START__; } MEMORY { - ZP: define = yes, start = $0080, size = $001A; - MAIN: file = %O, start = $2000, size = $9F00 - __STACKSIZE__; - MOVE: file = %O, define = yes, start = $0000, size = $FFFF; - LC: define = yes, start = __LCADDR__, size = __LCSIZE__; + ZP: file = "", define = yes, start = $0080, size = $001A; + MAIN: file = %O, start = $2000, size = $BF00 - $2000; + BSS: file = "", start = __ONCE_RUN__, size = $BF00 - __STACKSIZE__ - __ONCE_RUN__; + LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp; - STARTUP: load = MAIN, type = ro, define = 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 = bss, define = yes; - BSS: load = MAIN, type = bss, define = yes; - ONCE: load = MOVE, run = MAIN, type = ro, define = yes, optional = yes; - LC: load = MOVE, run = LC, type = ro, optional = yes; + ZEROPAGE: load = ZP, type = zp; + 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; + ONCE: load = MAIN, type = ro, define = yes; + LC: load = MAIN, run = LC, type = ro, optional = yes; + BSS: load = BSS, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/apple2enh.cfg b/cfg/apple2enh.cfg index 875103041..eba2a0e66 100644 --- a/cfg/apple2enh.cfg +++ b/cfg/apple2enh.cfg @@ -5,33 +5,30 @@ FEATURES { } SYMBOLS { __EXEHDR__: type = import; + __STACKSIZE__: type = weak, value = $0800; # 2k stack __HIMEM__: type = weak, value = $9600; # Presumed RAM end __LCADDR__: type = weak, value = $D400; # Behind quit code __LCSIZE__: type = weak, value = $0C00; # Rest of bank two - __STACKSIZE__: type = weak, value = $0800; # 2k stack - __LOADADDR__: type = weak, value = __STARTUP_RUN__; - __LOADSIZE__: type = weak, value = __INIT_RUN__ - __STARTUP_RUN__ + - __MOVE_LAST__ - __MOVE_START__; } MEMORY { - ZP: define = yes, start = $0080, size = $001A; - HEADER: file = %O, start = $0000, size = $0004; - MAIN: file = %O, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S; - MOVE: file = %O, define = yes, start = $0000, size = $FFFF; - LC: define = yes, start = __LCADDR__, size = __LCSIZE__; + ZP: file = "", define = yes, start = $0080, size = $001A; + HEADER: file = %O, start = %S - 4, size = $0004; + 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__; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp; - EXEHDR: load = HEADER, type = ro; - STARTUP: load = MAIN, type = ro, define = 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 = bss, define = yes; - BSS: load = MAIN, type = bss, define = yes; - ONCE: load = MOVE, run = MAIN, type = ro, define = yes, optional = yes; - LC: load = MOVE, run = LC, type = ro, optional = yes; + ZEROPAGE: load = ZP, type = zp; + 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; + ONCE: load = MAIN, type = ro, define = yes; + LC: load = MAIN, run = LC, type = ro, optional = yes; + BSS: load = BSS, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/libsrc/apple2/crt0.s b/libsrc/apple2/crt0.s index 7eee390fa..60a8516d1 100644 --- a/libsrc/apple2/crt0.s +++ b/libsrc/apple2/crt0.s @@ -6,16 +6,17 @@ .export _exit, done, return .export __STARTUP__ : absolute = 1 ; Mark as startup - .import zerobss + .import initlib, donelib - .import callmain + .import zerobss, callmain + .import __ONCE_LOAD__, __ONCE_SIZE__ ; Linker generated .import __LC_START__, __LC_LAST__ ; Linker generated - .import __ONCE_RUN__, __ONCE_SIZE__ ; Linker generated - .import __INIT_RUN__ ; Linker generated .include "zeropage.inc" .include "apple2.inc" +; ------------------------------------------------------------------------ + .segment "STARTUP" ; ProDOS TechRefMan, chapter 5.2.1: @@ -24,57 +25,16 @@ ldx #$FF txs ; Init stack pointer - ; Switch in LC bank 2 for W/O. - bit $C081 - bit $C081 - - ; Set the source start address. - lda #<(__INIT_RUN__ + __ONCE_SIZE__) - ldy #>(__INIT_RUN__ + __ONCE_SIZE__) - sta $9B - sty $9C - - ; Set the source last address. - lda #<(__INIT_RUN__ + __ONCE_SIZE__ + __LC_LAST__ - __LC_START__) - ldy #>(__INIT_RUN__ + __ONCE_SIZE__ + __LC_LAST__ - __LC_START__) - sta $96 - sty $97 - - ; Set the destination last address. - lda #<__LC_LAST__ - ldy #>__LC_LAST__ - sta $94 - sty $95 - - ; Call into Applesoft Block Transfer Up -- which handles zero- - ; sized blocks well -- to move the content of the LC memory area. - jsr $D39A ; BLTU2 - - ; Set the source start address. - lda #<__INIT_RUN__ - ldy #>__INIT_RUN__ - sta $9B - sty $9C - - ; Set the source last address. - lda #<(__INIT_RUN__ + __ONCE_SIZE__) - ldy #>(__INIT_RUN__ + __ONCE_SIZE__) - sta $96 - sty $97 - - ; Set the destination last address. - lda #<(__ONCE_RUN__ + __ONCE_SIZE__) - ldy #>(__ONCE_RUN__ + __ONCE_SIZE__) - sta $94 - sty $95 - - ; Call into Applesoft Block Transfer Up -- which handles moving - ; overlapping blocks upwards well -- to move the ONCE segment. - jsr $D39A ; BLTU2 - - ; Delegate all further processing, to keep the STARTUP segment small. + ; 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 + ; Avoid a re-entrance of donelib. This is also the exit() entry. _exit: ldx #<exit lda #>exit @@ -109,6 +69,8 @@ exit: ldx #$02 ; We're done jmp done +; ------------------------------------------------------------------------ + .segment "ONCE" ; Save the zero-page locations that we need. @@ -118,9 +80,6 @@ init: ldx #zpspace-1 dex bpl :- - ; Clear the BSS data. - jsr zerobss - ; Save the original RESET vector. ldx #$02 : lda SOFTEV,x @@ -128,13 +87,6 @@ init: ldx #zpspace-1 dex bpl :- - ; ProDOS TechRefMan, chapter 5.3.5: - ; "Your system program should place in the RESET vector the - ; address of a routine that ... closes the files." - ldx #<_exit - lda #>_exit - jsr reset ; Setup RESET vector - ; Check for ProDOS. ldy $BF00 ; MLI call entry point cpy #$4C ; Is MLI present? (JMP opcode) @@ -164,14 +116,50 @@ basic: lda HIMEM : sta sp stx sp+1 + ; ProDOS TechRefMan, chapter 5.3.5: + ; "Your system program should place in the RESET vector the + ; address of a routine that ... closes the files." + ldx #<_exit + lda #>_exit + jsr reset ; Setup RESET vector + ; Call the module constructors. jsr initlib - ; Switch in LC bank 2 for R/O. - bit $C080 + ; Switch in LC bank 2 for W/O. + bit $C081 + bit $C081 - ; Push the command-line arguments; and, call main(). - jmp callmain + ; Set the source start address. + ; Aka __LC_LOAD__ iff segment LC exists. + lda #<(__ONCE_LOAD__ + __ONCE_SIZE__) + ldy #>(__ONCE_LOAD__ + __ONCE_SIZE__) + sta $9B + sty $9C + + ; Set the source last address. + ; Aka __LC_LOAD__ + __LC_SIZE__ iff segment LC exists. + lda #<((__ONCE_LOAD__ + __ONCE_SIZE__) + (__LC_LAST__ - __LC_START__)) + ldy #>((__ONCE_LOAD__ + __ONCE_SIZE__) + (__LC_LAST__ - __LC_START__)) + sta $96 + sty $97 + + ; Set the destination last address. + ; Aka __LC_RUN__ + __LC_SIZE__ iff segment LC exists. + lda #<__LC_LAST__ + ldy #>__LC_LAST__ + sta $94 + sty $95 + + ; Call into Applesoft Block Transfer Up -- which handles zero- + ; sized blocks well -- to move the content of the LC memory area. + jsr $D39A ; BLTU2 + + ; Switch in LC bank 2 for R/O and return. + bit $C080 + rts + +; ------------------------------------------------------------------------ .code @@ -187,6 +175,8 @@ quit: jsr $BF00 ; MLI call entry point .byte $65 ; Quit .word q_param +; ------------------------------------------------------------------------ + .rodata ; MLI parameter list for quit @@ -196,15 +186,16 @@ q_param:.byte $04 ; param_count .byte $00 ; reserved .word $0000 ; reserved +; ------------------------------------------------------------------------ + .data ; Final jump when we're done done: jmp DOSWARM ; Potentially patched at runtime +; ------------------------------------------------------------------------ + .segment "INIT" zpsave: .res zpspace - - .bss - rvsave: .res 3 diff --git a/libsrc/apple2/exehdr.s b/libsrc/apple2/exehdr.s index eb05e66be..778eee903 100644 --- a/libsrc/apple2/exehdr.s +++ b/libsrc/apple2/exehdr.s @@ -6,11 +6,11 @@ ; .export __EXEHDR__ : absolute = 1 ; Linker referenced - .import __LOADADDR__, __LOADSIZE__ ; Linker generated + .import __MAIN_START__, __MAIN_LAST__ ; Linker generated ; ------------------------------------------------------------------------ .segment "EXEHDR" - .addr __LOADADDR__ ; Load address - .word __LOADSIZE__ ; Load length + .addr __MAIN_START__ ; Load address + .word __MAIN_LAST__ - __MAIN_START__ ; Load length From d5092d2d3f37dc3522daa9306b61b6224bc57998 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 17 Mar 2016 21:31:43 +0100 Subject: [PATCH 0031/2161] Consider the segment attributes 'define' and 'optional' mutually exclusive. In normal situations it isn't too useful to define symbols for optional segments as those symbols can't be presumed to be always present. I in fact suspect that most currently present combinations of 'define' and 'optional' aren't useful - apart form the overlay configurations of course. --- cfg/bbc.cfg | 8 ++++---- cfg/c128.cfg | 6 +++--- cfg/c16.cfg | 6 +++--- cfg/c64.cfg | 6 +++--- cfg/cbm510.cfg | 10 +++++----- cfg/cbm610.cfg | 10 +++++----- cfg/geos-apple.cfg | 4 ++-- cfg/geos-cbm.cfg | 4 ++-- cfg/lunix.cfg | 16 ++++++++-------- cfg/nes.cfg | 14 +++++++------- cfg/none.cfg | 6 +++--- cfg/osic1p-asm.cfg | 4 ++-- cfg/pet.cfg | 6 +++--- cfg/plus4.cfg | 6 +++--- cfg/sim6502.cfg | 6 +++--- cfg/sim65c02.cfg | 6 +++--- cfg/supervision-128k.cfg | 12 ++++++------ cfg/supervision-16k.cfg | 18 +++++++++--------- cfg/supervision-64k.cfg | 12 ++++++------ cfg/supervision.cfg | 18 +++++++++--------- cfg/vic20-32k.cfg | 6 +++--- cfg/vic20.cfg | 6 +++--- 22 files changed, 95 insertions(+), 95 deletions(-) diff --git a/cfg/bbc.cfg b/cfg/bbc.cfg index f1aa4a877..60bf372f0 100644 --- a/cfg/bbc.cfg +++ b/cfg/bbc.cfg @@ -7,13 +7,13 @@ MEMORY { } SEGMENTS { ZEROPAGE: load = ZP, type = zp; - STARTUP: load = MAIN, type = ro, define = yes; - LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, optional = yes; + STARTUP: load = MAIN, type = ro, define = yes; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; - BSS: load = MAIN, type = bss, define = yes; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/c128.cfg b/cfg/c128.cfg index 7546e7921..0ed22266c 100644 --- a/cfg/c128.cfg +++ b/cfg/c128.cfg @@ -14,13 +14,13 @@ SEGMENTS { LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; - LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, optional = yes; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: 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 = bss; - BSS: load = MAIN, type = bss, define = yes; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/c16.cfg b/cfg/c16.cfg index 1aae78824..b67c66b96 100644 --- a/cfg/c16.cfg +++ b/cfg/c16.cfg @@ -14,13 +14,13 @@ SEGMENTS { LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; - LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, optional = yes; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: 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 = bss; - BSS: load = MAIN, type = bss, define = yes; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/c64.cfg b/cfg/c64.cfg index 43ccce2ca..5bd8d8240 100644 --- a/cfg/c64.cfg +++ b/cfg/c64.cfg @@ -19,13 +19,13 @@ SEGMENTS { LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; - LOWCODE: 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; - ONCE: load = MAIN, type = ro, define = yes; - BSS: load = BSS, type = bss, define = yes; + ONCE: load = MAIN, type = ro, define = yes; + BSS: load = BSS, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/cbm510.cfg b/cfg/cbm510.cfg index b4e228fdd..f4db154ab 100644 --- a/cfg/cbm510.cfg +++ b/cfg/cbm510.cfg @@ -14,18 +14,18 @@ MEMORY { } SEGMENTS { ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = rw, define = yes; + EXTZP: load = ZP, type = rw, define = yes; EXEHDR: load = HEADER, type = rw; STARTUP: load = STARTUP, type = rw; PAGE2: load = PAGE2, type = rw; PAGE3: load = PAGE3, type = rw; - LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, optional = yes; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: 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 = bss, optional = yes; - BSS: load = MAIN, type = bss, define = yes; + INIT: load = MAIN, type = bss, optional = yes; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/cbm610.cfg b/cfg/cbm610.cfg index 431734cd2..da829c9b4 100644 --- a/cfg/cbm610.cfg +++ b/cfg/cbm610.cfg @@ -11,18 +11,18 @@ MEMORY { } SEGMENTS { ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = rw, define = yes; + EXTZP: load = ZP, type = rw, define = yes; EXEHDR: load = HEADER, type = rw; STARTUP: load = STARTUP, type = rw; PAGE2: load = PAGE2, type = rw; PAGE3: load = PAGE3, type = rw; - LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, optional = yes; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: 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 = bss, optional = yes; - BSS: load = MAIN, type = bss, define = yes; + INIT: load = MAIN, type = bss, optional = yes; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/geos-apple.cfg b/cfg/geos-apple.cfg index b39cf1ebe..2c9f6c589 100644 --- a/cfg/geos-apple.cfg +++ b/cfg/geos-apple.cfg @@ -32,7 +32,7 @@ MEMORY { } SEGMENTS { ZEROPAGE: type = zp, load = ZP; - EXTZP: type = zp, load = ZP, optional = yes; + EXTZP: type = zp, load = ZP, optional = yes; EXTBSS: type = bss, load = EXT, define = yes, optional = yes; FILEINFO: type = ro, load = CVT, offset = $002; RECORDS: type = ro, load = CVT, offset = $100, optional = yes; @@ -45,7 +45,7 @@ SEGMENTS { RODATA: type = ro, run = VLIR0, load = CVT; DATA: type = rw, run = VLIR0, load = CVT; INIT: type = bss, load = VLIR0, optional = yes; - BSS: type = bss, load = VLIR0, define = yes; + BSS: type = bss, load = VLIR0, define = yes; VLIRIDX1: type = ro, load = CVT, align = $200, optional = yes; OVERLAY1: type = ro, run = VLIR1, load = CVT, align_load = $200, optional = yes; VLIRIDX2: type = ro, load = CVT, align = $200, optional = yes; diff --git a/cfg/geos-cbm.cfg b/cfg/geos-cbm.cfg index 0269dbacb..d2e896fa5 100644 --- a/cfg/geos-cbm.cfg +++ b/cfg/geos-cbm.cfg @@ -31,7 +31,7 @@ MEMORY { } SEGMENTS { ZEROPAGE: type = zp, load = ZP; - EXTZP: type = zp, load = ZP, optional = yes; + EXTZP: type = zp, load = ZP, optional = yes; DIRENTRY: type = ro, load = CVT, align = $FE; FILEINFO: type = ro, load = CVT, align = $FE; RECORDS: type = ro, load = CVT, align = $FE, optional = yes; @@ -42,7 +42,7 @@ SEGMENTS { RODATA: type = ro, run = VLIR0, load = CVT; DATA: type = rw, run = VLIR0, load = CVT; INIT: type = bss, load = VLIR0, optional = yes; - BSS: type = bss, load = VLIR0, define = yes; + BSS: type = bss, load = VLIR0, define = yes; OVERLAY1: type = ro, run = VLIR1, load = CVT, align_load = $FE, optional = yes; OVERLAY2: type = ro, run = VLIR2, load = CVT, align_load = $FE, optional = yes; OVERLAY3: type = ro, run = VLIR3, load = CVT, align_load = $FE, optional = yes; diff --git a/cfg/lunix.cfg b/cfg/lunix.cfg index 0b7b9c8ff..560b501d5 100644 --- a/cfg/lunix.cfg +++ b/cfg/lunix.cfg @@ -9,14 +9,14 @@ MEMORY { MAIN: start = %S, size = $7600 - __STACKSIZE__; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp, define = yes; # Pseudo-registers - STARTUP: load = MAIN, type = ro; # First initialization code - LOWCODE: load = MAIN, type = ro, optional = yes; # Legacy from other platforms - ONCE: load = MAIN, type = ro, optional = yes; # Library initialization code - CODE: load = MAIN, type = ro; # Program - RODATA: load = MAIN, type = ro; # Literals, constants - DATA: load = MAIN, type = rw; # Initialized variables - BSS: load = MAIN, type = bss, define = yes; # Uninitialized variables + ZEROPAGE: load = ZP, type = zp, define = yes; # Pseudo-registers + STARTUP: load = MAIN, type = ro; # First initialization code + LOWCODE: load = MAIN, type = ro, optional = yes; # Legacy from other platforms + ONCE: load = MAIN, type = ro, optional = yes; # Library initialization code + CODE: load = MAIN, type = ro; # Program + RODATA: load = MAIN, type = ro; # Literals, constants + DATA: load = MAIN, type = rw; # Initialized variables + BSS: load = MAIN, type = bss, define = yes; # Uninitialized variables } FEATURES { CONDES: type = constructor, diff --git a/cfg/nes.cfg b/cfg/nes.cfg index 0cc2ce334..fdd992fe0 100644 --- a/cfg/nes.cfg +++ b/cfg/nes.cfg @@ -35,15 +35,15 @@ MEMORY { SEGMENTS { ZEROPAGE: load = ZP, type = zp; HEADER: load = HEADER, type = ro; - STARTUP: load = ROM0, type = ro, define = yes; - LOWCODE: load = ROM0, type = ro, optional = yes; - ONCE: load = ROM0, type = ro, optional = yes; - CODE: load = ROM0, type = ro, define = yes; - RODATA: load = ROM0, type = ro, define = yes; - DATA: load = ROM0, run = RAM, type = rw, define = yes; + STARTUP: load = ROM0, type = ro, define = yes; + LOWCODE: load = ROM0, type = ro, optional = yes; + ONCE: load = ROM0, type = ro, optional = yes; + CODE: load = ROM0, type = ro, define = yes; + RODATA: load = ROM0, type = ro, define = yes; + DATA: load = ROM0, run = RAM, type = rw, define = yes; VECTORS: load = ROMV, type = rw; CHARS: load = ROM2, type = rw; - BSS: load = RAM, type = bss, define = yes; + BSS: load = RAM, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/none.cfg b/cfg/none.cfg index 8cd9c4f95..6742da7c8 100644 --- a/cfg/none.cfg +++ b/cfg/none.cfg @@ -7,12 +7,12 @@ MEMORY { } SEGMENTS { ZEROPAGE: load = ZP, type = zp; - LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: 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; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/osic1p-asm.cfg b/cfg/osic1p-asm.cfg index 88ab69062..1cebe4449 100644 --- a/cfg/osic1p-asm.cfg +++ b/cfg/osic1p-asm.cfg @@ -16,9 +16,9 @@ MEMORY { } SEGMENTS { ZEROPAGE: load = ZP, type = zp; - BOOT: load = HEAD, type = ro, optional = yes; + BOOT: load = HEAD, 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; + BSS: load = MAIN, type = bss, define = yes; } diff --git a/cfg/pet.cfg b/cfg/pet.cfg index efde48efe..6eb2465b0 100644 --- a/cfg/pet.cfg +++ b/cfg/pet.cfg @@ -14,13 +14,13 @@ SEGMENTS { LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; STARTUP: load = RAM, type = ro; - LOWCODE: load = RAM, type = ro, optional = yes; - ONCE: load = RAM, type = ro, optional = yes; + LOWCODE: load = RAM, type = ro, optional = yes; + ONCE: load = RAM, type = ro, optional = yes; CODE: load = RAM, type = ro; RODATA: load = RAM, type = ro; DATA: load = RAM, type = rw; INIT: load = RAM, type = bss; - BSS: load = RAM, type = bss, define = yes; + BSS: load = RAM, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/plus4.cfg b/cfg/plus4.cfg index 610a7c23c..802f1076e 100644 --- a/cfg/plus4.cfg +++ b/cfg/plus4.cfg @@ -14,13 +14,13 @@ SEGMENTS { LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; - LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, optional = yes; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: 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 = bss; - BSS: load = MAIN, type = bss, define = yes; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/sim6502.cfg b/cfg/sim6502.cfg index 5e7402262..b4f7738f5 100644 --- a/cfg/sim6502.cfg +++ b/cfg/sim6502.cfg @@ -11,12 +11,12 @@ SEGMENTS { ZEROPAGE: load = ZP, type = zp; EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; - LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, optional = yes; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; - BSS: load = MAIN, type = bss, define = yes; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/sim65c02.cfg b/cfg/sim65c02.cfg index 5e7402262..b4f7738f5 100644 --- a/cfg/sim65c02.cfg +++ b/cfg/sim65c02.cfg @@ -11,12 +11,12 @@ SEGMENTS { ZEROPAGE: load = ZP, type = zp; EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; - LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, optional = yes; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; - BSS: load = MAIN, type = bss, define = yes; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/supervision-128k.cfg b/cfg/supervision-128k.cfg index 6cfde6551..0304e2c02 100644 --- a/cfg/supervision-128k.cfg +++ b/cfg/supervision-128k.cfg @@ -20,8 +20,8 @@ MEMORY { ROM: file = %O, start = $c000, size = $4000, fill = yes, fillval = $FF; } SEGMENTS { - LOWCODE: load = ROM, type = ro, optional = yes; - ONCE: load = ROM, type = ro, optional = yes; + LOWCODE: load = ROM, type = ro, optional = yes; + ONCE: load = ROM, type = ro, optional = yes; CODE: load = ROM, type = ro; BANK1: load = BANKROM1, type = ro; BANK2: load = BANKROM2, type = ro; @@ -30,8 +30,8 @@ SEGMENTS { BANK5: load = BANKROM5, type = ro; BANK6: load = BANKROM6, type = ro; BANK7: load = BANKROM7, type = ro; - ZEROPAGE: load = RAM, type = bss, define = yes; - DATA: load = RAM, type = bss, define = yes, offset = $0200; - BSS: load = RAM, type = bss, define = yes; - VECTOR: load = ROM, type = ro, offset = $3FFA; + ZEROPAGE: load = RAM, type = bss, define = yes; + DATA: load = RAM, type = bss, define = yes, offset = $0200; + BSS: load = RAM, type = bss, define = yes; + VECTOR: load = ROM, type = ro, offset = $3FFA; } diff --git a/cfg/supervision-16k.cfg b/cfg/supervision-16k.cfg index e42677304..86c8fface 100644 --- a/cfg/supervision-16k.cfg +++ b/cfg/supervision-16k.cfg @@ -14,15 +14,15 @@ MEMORY { ROM: file = %O, start = $C000, size = $4000, fill = yes, fillval = $ff, define=yes; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp, define = yes; - LOWCODE: load = ROM, type = ro, optional = yes; - ONCE: load = ROM, type = ro, optional = yes; - CODE: load = ROM, type = ro, define = yes; - RODATA: load = ROM, type = ro, define = yes; - DATA: load = ROM, run = RAM, type = rw, define = yes; - FFF0: load = ROM, type = ro, offset = $3FF0; - VECTOR: load = ROM, type = ro, offset = $3FFA; - BSS: load = RAM, type = bss, define = yes; + ZEROPAGE: load = ZP, type = zp, define = yes; + LOWCODE: load = ROM, type = ro, optional = yes; + ONCE: load = ROM, type = ro, optional = yes; + CODE: load = ROM, type = ro, define = yes; + RODATA: load = ROM, type = ro, define = yes; + DATA: load = ROM, run = RAM, type = rw, define = yes; + FFF0: load = ROM, type = ro, offset = $3FF0; + VECTOR: load = ROM, type = ro, offset = $3FFA; + BSS: load = RAM, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/supervision-64k.cfg b/cfg/supervision-64k.cfg index 18c7b4a45..8a7665c30 100644 --- a/cfg/supervision-64k.cfg +++ b/cfg/supervision-64k.cfg @@ -16,15 +16,15 @@ MEMORY { ROM: file = %O, start = $C000, size = $4000, fill = yes, fillval = $FF; } SEGMENTS { - LOWCODE: load = ROM, type = ro, optional = yes; - ONCE: load = ROM, type = ro, optional = yes; + LOWCODE: load = ROM, type = ro, optional = yes; + ONCE: load = ROM, type = ro, optional = yes; CODE: load = ROM, type = ro; RODATA: load = ROM, type = ro; BANK1: load = BANKROM1, type = ro; BANK2: load = BANKROM2, type = ro; BANK3: load = BANKROM3, type = ro; - ZEROPAGE: load = RAM, type = bss, define = yes; - DATA: load = RAM, type = bss, define = yes, offset = $0200; - BSS: load = RAM, type = bss, define = yes; - VECTOR: load = ROM, type = ro, offset = $3FFA; + ZEROPAGE: load = RAM, type = bss, define = yes; + DATA: load = RAM, type = bss, define = yes, offset = $0200; + BSS: load = RAM, type = bss, define = yes; + VECTOR: load = ROM, type = ro, offset = $3FFA; } diff --git a/cfg/supervision.cfg b/cfg/supervision.cfg index c96351e5f..2d20e3461 100644 --- a/cfg/supervision.cfg +++ b/cfg/supervision.cfg @@ -13,15 +13,15 @@ MEMORY { ROM: file = %O, start = $8000, size = $8000, fill = yes, fillval = $FF, define = yes; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp, define = yes; - LOWCODE: load = ROM, type = ro, optional = yes; - ONCE: load = ROM, type = ro, optional = yes; - CODE: load = ROM, type = ro, define = yes; - RODATA: load = ROM, type = ro, define = yes; - DATA: load = ROM, run = RAM, type = rw, define = yes; - FFF0: load = ROM, type = ro, offset = $7FF0; - VECTOR: load = ROM, type = ro, offset = $7FFA; - BSS: load = RAM, type = bss, define = yes; + ZEROPAGE: load = ZP, type = zp, define = yes; + LOWCODE: load = ROM, type = ro, optional = yes; + ONCE: load = ROM, type = ro, optional = yes; + CODE: load = ROM, type = ro, define = yes; + RODATA: load = ROM, type = ro, define = yes; + DATA: load = ROM, run = RAM, type = rw, define = yes; + FFF0: load = ROM, type = ro, offset = $7FF0; + VECTOR: load = ROM, type = ro, offset = $7FFA; + BSS: load = RAM, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/vic20-32k.cfg b/cfg/vic20-32k.cfg index f592d7bd0..28dd661ad 100644 --- a/cfg/vic20-32k.cfg +++ b/cfg/vic20-32k.cfg @@ -16,13 +16,13 @@ SEGMENTS { LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; - LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, optional = yes; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: 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 = bss; - BSS: load = MAIN, type = bss, define = yes; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/vic20.cfg b/cfg/vic20.cfg index 98f6f82b3..ceaee3a87 100644 --- a/cfg/vic20.cfg +++ b/cfg/vic20.cfg @@ -14,13 +14,13 @@ SEGMENTS { LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; - LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, optional = yes; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: 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 = bss; - BSS: load = MAIN, type = bss, define = yes; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, From 78dcb61cb8d59efa93ac8d5cb4fa08598553121a Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 17 Mar 2016 21:51:20 +0100 Subject: [PATCH 0032/2161] Harmonized asm linker configs. - All segments but CODE are optional and CODE is R/W. Both together allow to "just" write code/data without ever explicitly using a segment. - Symbols are defined for the BSS. This allows to use/implement zerobss. - The ZP memory area isn't artificially limited. --- cfg/apple2-asm.cfg | 2 +- cfg/apple2enh-asm.cfg | 2 +- cfg/atari-asm.cfg | 20 ++++++++++---------- cfg/c64-asm.cfg | 6 +++--- cfg/osic1p-asm.cfg | 12 ++++++------ 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/cfg/apple2-asm.cfg b/cfg/apple2-asm.cfg index 151ba84c4..8e5abefc5 100644 --- a/cfg/apple2-asm.cfg +++ b/cfg/apple2-asm.cfg @@ -12,7 +12,7 @@ MEMORY { SEGMENTS { ZEROPAGE: load = ZP, type = zp, optional = yes; EXEHDR: load = HEADER, type = ro, optional = yes; - CODE: load = MAIN, type = rw, optional = yes; + CODE: load = MAIN, type = rw; RODATA: load = MAIN, type = ro, optional = yes; DATA: load = MAIN, type = rw, optional = yes; BSS: load = BSS, type = bss, optional = yes, define = yes; diff --git a/cfg/apple2enh-asm.cfg b/cfg/apple2enh-asm.cfg index 151ba84c4..8e5abefc5 100644 --- a/cfg/apple2enh-asm.cfg +++ b/cfg/apple2enh-asm.cfg @@ -12,7 +12,7 @@ MEMORY { SEGMENTS { ZEROPAGE: load = ZP, type = zp, optional = yes; EXEHDR: load = HEADER, type = ro, optional = yes; - CODE: load = MAIN, type = rw, optional = yes; + CODE: load = MAIN, type = rw; RODATA: load = MAIN, type = ro, optional = yes; DATA: load = MAIN, type = rw, optional = yes; BSS: load = BSS, type = bss, optional = yes, define = yes; diff --git a/cfg/atari-asm.cfg b/cfg/atari-asm.cfg index bea547765..6fc1c2caa 100644 --- a/cfg/atari-asm.cfg +++ b/cfg/atari-asm.cfg @@ -3,7 +3,7 @@ FEATURES { } SYMBOLS { __EXEHDR__: type = import; - __AUTOSTART__: type = import; # force inclusion of autostart "trailer" + __AUTOSTART__: type = import; # force inclusion of autostart "trailer" __STARTADDRESS__: type = export, value = %S; } MEMORY { @@ -18,13 +18,13 @@ MEMORY { TRAILER: file = %O, start = $0000, size = $0006; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp, optional = yes; - EXTZP: load = ZP, type = zp, optional = yes; # to enable modules to be able to link to C and assembler programs - EXEHDR: load = HEADER, type = ro, optional = yes; - MAINHDR: load = MAINHDR, type = ro, optional = yes; - CODE: load = MAIN, type = ro, define = yes, optional = yes; - RODATA: load = MAIN, type = ro optional = yes; - DATA: load = MAIN, type = rw optional = yes; - BSS: load = MAIN, type = bss, define = yes, optional = yes; - AUTOSTRT: load = TRAILER, type = ro, optional = yes; + ZEROPAGE: load = ZP, type = zp, optional = yes; + EXTZP: load = ZP, type = zp, optional = yes; # to enable modules to be able to link to C and assembler programs + EXEHDR: load = HEADER, type = ro, optional = yes; + MAINHDR: load = MAINHDR, type = ro, optional = yes; + CODE: load = MAIN, type = rw, define = yes; + RODATA: load = MAIN, type = ro optional = yes; + DATA: load = MAIN, type = rw optional = yes; + BSS: load = MAIN, type = bss, optional = yes, define = yes; + AUTOSTRT: load = TRAILER, type = ro, optional = yes; } diff --git a/cfg/c64-asm.cfg b/cfg/c64-asm.cfg index 25d12ee71..e2dda5362 100644 --- a/cfg/c64-asm.cfg +++ b/cfg/c64-asm.cfg @@ -5,7 +5,7 @@ SYMBOLS { __LOADADDR__: type = import; } MEMORY { - ZP: file = "", start = $0002, size = $001A, define = yes; + ZP: file = "", start = $0002, size = $00FE, define = yes; LOADADDR: file = %O, start = %S - 2, size = $0002; MAIN: file = %O, start = %S, size = $D000 - %S; } @@ -13,8 +13,8 @@ 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, 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; + BSS: load = MAIN, type = bss, optional = yes, define = yes; } diff --git a/cfg/osic1p-asm.cfg b/cfg/osic1p-asm.cfg index 1cebe4449..a16f248ab 100644 --- a/cfg/osic1p-asm.cfg +++ b/cfg/osic1p-asm.cfg @@ -10,15 +10,15 @@ SYMBOLS { } MEMORY { # for size of ZP, see runtime/zeropage.s and c1p/extzp.s - ZP: file = "", define = yes, start = $0002, size = $001A + $0006; + ZP: file = "", define = yes, start = $0002, size = $00FE; HEAD: file = %O, start = $0000, size = $00B6; - MAIN: file = %O, define = yes, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S; + MAIN: file = %O, define = yes, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp; + ZEROPAGE: load = ZP, type = zp, optional = yes; BOOT: load = HEAD, 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; + RODATA: load = MAIN, type = ro, optional = yes; + DATA: load = MAIN, type = rw, optional = yes; + BSS: load = MAIN, type = bss, optional = yes, define = yes; } From 7773fcb1e124805eec492ebe77af6b6d69475605 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 18 Mar 2016 11:28:56 -0400 Subject: [PATCH 0033/2161] Converted the Atmos configuration to the new constructor segment model. --- cfg/atmos.cfg | 16 ++++----- libsrc/atmos/bashdr.s | 12 ++++++- libsrc/atmos/capslock.s | 3 +- libsrc/atmos/cgetc.s | 4 +-- libsrc/atmos/crt0.s | 79 +++++++++++++++++++---------------------- libsrc/atmos/mainargs.s | 5 ++- libsrc/atmos/tapehdr.s | 23 ++++++------ 7 files changed, 73 insertions(+), 69 deletions(-) diff --git a/cfg/atmos.cfg b/cfg/atmos.cfg index bb79a1e8a..35f184f4f 100644 --- a/cfg/atmos.cfg +++ b/cfg/atmos.cfg @@ -11,22 +11,22 @@ MEMORY { ZP: file = "", define = yes, start = $00E2, size = $001A; TAPEHDR: file = %O, type = ro, start = $0000, size = $001F; BASHEAD: file = %O, define = yes, start = $0501, size = $000D; - MAIN: file = %O, define = yes, start = __BASHEAD_LAST__, size = __RAMEND__ - __MAIN_START__ - __STACKSIZE__; + MAIN: file = %O, define = yes, start = __BASHEAD_LAST__, size = __RAMEND__ - __MAIN_START__; + BSS: file = "", start = __ONCE_RUN__, size = __RAMEND__ - __STACKSIZE__ - __ONCE_RUN__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; TAPEHDR: load = TAPEHDR, type = ro; - BASHDR: load = BASHEAD, type = ro, define = yes, optional = yes; + BASHDR: load = BASHEAD, type = ro, optional = yes; STARTUP: load = MAIN, type = ro; - LOWCODE: load = MAIN, type = ro, optional = yes; + LOWCODE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; RODATA: load = MAIN, type = ro; - ONCE: load = MAIN, type = ro, optional = yes; DATA: load = MAIN, type = rw; - INIT: load = MAIN, type = rw, optional = yes; - ZPSAVE1: load = MAIN, type = rw, define = yes; # ZPSAVE1, ZPSAVE2 must be together - ZPSAVE2: load = MAIN, type = bss; # see "libsrc/atmos/crt0.s" - BSS: load = MAIN, type = bss, define = yes; + INIT: load = MAIN, type = rw; + ONCE: load = MAIN, type = ro, define = yes; + BASTAIL: load = MAIN, type = ro, optional = yes; + BSS: load = BSS, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/libsrc/atmos/bashdr.s b/libsrc/atmos/bashdr.s index e09bc9fec..79cf9acb1 100644 --- a/libsrc/atmos/bashdr.s +++ b/libsrc/atmos/bashdr.s @@ -1,6 +1,6 @@ ; ; 2010-11-14, Ullrich von Bassewitz -; 2014-09-06, Greg King +; 2016-03-17, Greg King ; ; This module supplies a small BASIC stub program that uses CALL ; to jump to the machine-language code that follows it. @@ -22,3 +22,13 @@ .byte $00 ; End of BASIC line Next: .addr $0000 ; BASIC program end marker Start: + +; ------------------------------------------------------------------------ + +; This padding is needed by a bug in the ROM. +; (The CLOAD command starts BASIC's variables table on top of the last byte +; that was loaded [instead of at the next address].) + +.segment "BASTAIL" + + .byte 0 diff --git a/libsrc/atmos/capslock.s b/libsrc/atmos/capslock.s index 0260b3f9f..1451513b4 100644 --- a/libsrc/atmos/capslock.s +++ b/libsrc/atmos/capslock.s @@ -15,7 +15,8 @@ ;-------------------------------------------------------------------------- -; Put this constructor into a segment that can be re-used by programs. +; Put this constructor into a segment whose space +; will be re-used by BSS, the heap, and the C stack. ; .segment "ONCE" diff --git a/libsrc/atmos/cgetc.s b/libsrc/atmos/cgetc.s index 64d597bc6..f1d727a50 100644 --- a/libsrc/atmos/cgetc.s +++ b/libsrc/atmos/cgetc.s @@ -55,8 +55,8 @@ .endproc ; ------------------------------------------------------------------------ -; Switch the cursor off. Code goes into the ONCE segment -; which may be reused after it is run. +; Switch the cursor off. Code goes into the ONCE segment, +; which will be reused after it is run. .segment "ONCE" diff --git a/libsrc/atmos/crt0.s b/libsrc/atmos/crt0.s index 6ad7a3ff3..8c2be656c 100644 --- a/libsrc/atmos/crt0.s +++ b/libsrc/atmos/crt0.s @@ -2,14 +2,15 @@ ; Startup code for cc65 (Oric version) ; ; By Debrune Jérôme <jede@oric.org> and Ullrich von Bassewitz <uz@cc65.org> -; 2015-01-09, Greg King +; 2016-03-18, Greg King ; .export _exit .export __STARTUP__ : absolute = 1 ; Mark as startup + .import initlib, donelib .import callmain, zerobss - .import __MAIN_START__, __MAIN_SIZE__, __STACKSIZE__ + .import __MAIN_START__, __MAIN_SIZE__ .include "zeropage.inc" .include "atmos.inc" @@ -19,39 +20,17 @@ .segment "STARTUP" -; Save the zero-page area that we're about to use. - - ldx #zpspace-1 -L1: lda sp,x - sta zpsave,x - dex - bpl L1 - -; Clear the BSS data. - - jsr zerobss - -; Currently, color isn't supported on the text screen. -; Unprotect screen columns 0 and 1 (where each line's color codes would sit). - - lda STATUS - sta stsave - and #%11011111 - sta STATUS - -; Save some system stuff; and, set up the stack. - tsx stx spsave ; Save system stk ptr - lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 ; Set argument stack ptr +; Save space by putting some of the start-up code in a segment +; that will be re-used. -; Call the module constructors. + jsr init - jsr initlib +; Clear the BSS variables (after the constructors have been run). + + jsr zerobss ; Push the command-line arguments; and, call main(). @@ -70,7 +49,7 @@ _exit: jsr donelib ; Copy back the zero-page stuff. - ldx #zpspace-1 + ldx #zpspace - 1 L2: lda zpsave,x sta sp,x dex @@ -81,28 +60,42 @@ L2: lda zpsave,x rts ; ------------------------------------------------------------------------ +; Put this code in a place that will be re-used by BSS, the heap, +; and the C stack. -.segment "ZPSAVE1" +.segment "ONCE" -zpsave: +; Save the zero-page area that we're about to use. -; This padding is needed by a bug in the ROM. -; (The CLOAD command starts BASIC's variables table on top of the last byte -; that was loaded [instead of at the next address].) -; This is overlaid on a buffer, so that it doesn't use extra space in RAM. +init: ldx #zpspace - 1 +L1: lda sp,x + sta zpsave,x + dex + bpl L1 - .byte 0 +; Currently, color isn't supported on the text screen. +; Unprotect screen columns 0 and 1 (where each line's color codes would sit). -; The segments "ZPSAVE1" and "ZPSAVE2" always must be together. -; They create a single object (the zpsave buffer). + lda STATUS + sta stsave + and #%11011111 + sta STATUS -.segment "ZPSAVE2" +; Set up the C stack. - .res zpspace - 1 + lda #<(__MAIN_START__ + __MAIN_SIZE__) + ldx #>(__MAIN_START__ + __MAIN_SIZE__) + sta sp + stx sp+1 ; Set argument stack ptr + +; Call the module constructors. + + jmp initlib ; ------------------------------------------------------------------------ -.bss +.segment "INIT" spsave: .res 1 stsave: .res 1 +zpsave: .res zpspace diff --git a/libsrc/atmos/mainargs.s b/libsrc/atmos/mainargs.s index 3ab353c15..b8d19dccc 100644 --- a/libsrc/atmos/mainargs.s +++ b/libsrc/atmos/mainargs.s @@ -18,7 +18,7 @@ REM = $9D ; BASIC token-code ;--------------------------------------------------------------------------- ; Get possible command-line arguments. Goes into the special ONCE segment, -; which may be reused after the startup code is run +; which will be reused after the startup code is run. .segment "ONCE" @@ -119,8 +119,6 @@ done: lda #<argv .endproc -; These arrays are zeroed before initmainargs is called. - .segment "INIT" term: .res 1 @@ -129,6 +127,7 @@ args: .res SCREEN_XSIZE * 2 - 1 .data +; This array has zeroes when initmainargs starts. ; char* argv[MAXARGS+1]={name}; argv: .addr name diff --git a/libsrc/atmos/tapehdr.s b/libsrc/atmos/tapehdr.s index d90c908eb..1848c48cb 100644 --- a/libsrc/atmos/tapehdr.s +++ b/libsrc/atmos/tapehdr.s @@ -1,6 +1,6 @@ ; ; Based on code by Debrune Jérôme <jede@oric.org> -; 2015-01-08, Greg King +; 2016-03-17, Greg King ; ; The following symbol is used by the linker config. file @@ -8,7 +8,8 @@ .export __TAPEHDR__:abs = 1 ; These symbols, also, come from the configuration file. - .import __BASHDR_LOAD__, __ZPSAVE1_LOAD__, __AUTORUN__, __PROGFLAG__ + .import __AUTORUN__, __PROGFLAG__ + .import __BASHEAD_START__, __MAIN_LAST__ ; ------------------------------------------------------------------------ @@ -16,16 +17,16 @@ .segment "TAPEHDR" - .byte $16, $16, $16 ; Sync bytes - .byte $24 ; Beginning-of-header marker + .byte $16, $16, $16 ; Sync bytes + .byte $24 ; Beginning-of-header marker - .byte $00 ; $2B0 - .byte $00 ; $2AF - .byte <__PROGFLAG__ ; $2AE Language flag ($00=BASIC, $80=machine code) - .byte <__AUTORUN__ ; $2AD Auto-run flag ($C7=run, $00=only load) - .dbyt __ZPSAVE1_LOAD__ ;$2AB Address of end of file - .dbyt __BASHDR_LOAD__ ; $2A9 Address of start of file - .byte $00 ; $2A8 + .byte $00 ; $2B0 + .byte $00 ; $2AF + .byte <__PROGFLAG__ ; $2AE Language flag ($00=BASIC, $80=machine code) + .byte <__AUTORUN__ ; $2AD Auto-run flag ($C7=run, $00=only load) + .dbyt __MAIN_LAST__ - 1 ; $2AB Address of end of file + .dbyt __BASHEAD_START__ ; $2A9 Address of start of file + .byte $00 ; $2A8 ; File name (a maximum of 17 characters), zero-terminated .asciiz .sprintf("%u", .time) From 9aac382afbd7ba689659ea53bbdc1b7eada3318c Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 25 Mar 2016 18:48:23 +0100 Subject: [PATCH 0034/2161] Updated documentation to reflect the current linker configs. --- doc/apple2.sgml | 185 +++++++++++++++++++++++--------------------- doc/apple2enh.sgml | 189 +++++++++++++++++++++++---------------------- 2 files changed, 192 insertions(+), 182 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index e58565359..7443e50b7 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -75,13 +75,30 @@ However while running module constructors/destructors the Language Card is disab Enabling the Language Card allows to use it as additional memory for cc65 generated code. However code is never automatically placed there. Rather code needs to be explicitly placed in the Language Card either per file by compiling -with <tt/--code-name HIGHCODE/ or per function by enclosing in <tt/#pragma -code-name (push, "HIGHCODE")/ and <tt/#pragma code-name (pop)/. In either case the -cc65 runtime system takes care of actually moving the code into the Language -Card. +with <tt/--code-name LC/ or per function by enclosing in <tt/#pragma code-name +(push, "LC")/ and <tt/#pragma code-name (pop)/. In either case the cc65 runtime +system takes care of actually moving the code into the Language Card. The amount of memory available in the Language Card for generated code depends -on the chosen <ref id="link-configs" name="linker configuration">. +on the <ref id="link-configs" name="linker configuration"> parameters. There are +several usefull settings: + +<descrip> + + <tag>LCADDR: $D400, LCSIZE: $C00</tag> + For plain vanilla ProDOS 8 which doesn't actually use the Language Card bank 2 + memory from $D400 to $DFFF. This is the default setting. + + <tag>LCADDR: $D000, LCSIZE: $1000</tag> + For ProDOS 8 together with the function <tt/rebootafterexit()/. If a program + doesn't quit to the ProDOS 8 dispatcher but rather reboots the machine after + exit then a plain vanilla ProDOS 8 doesn't make use of the Language Card bank + 2 at all. + + <tag>LCADDR: $D000, LCSIZE: $3000</tag> + For plain vanilla DOS 3.3 which doesn't make use of the Language Card at all. + +</descrip><p> @@ -93,126 +110,114 @@ The apple2 package comes with additional secondary linker config files, which are used via <tt/-t apple2 -C <configfile>/. -<sect1>default config file (<tt/apple2.cfg/)<p> +<sect1>default config file (<tt/apple2.cfg/)<label id="apple-def-cfg"><p> -Default configuration optimized for a binary program running on ProDOS 8 with -BASIC.SYSTEM. A plain vanilla ProDOS 8 doesn't actually use the Language Card -bank 2 memory from $D400 to $DFFF. +Default configuration for a binary program. + +Parameters: <descrip> - <tag><tt/RAM:/ Main memory area</tag> - From $803 to $95FF (35.5 KB) - - <tag><tt/LC:/ Language Card memory area</tag> - From $D400 to $DFFF (3 KB) - <tag><tt/STARTADDRESS:/ Program start address</tag> - Variable (default: $803) + Default: $803. Use <tt/-S <addr>/ to set a different start address. - <tag><tt/HEADER:/ Binary file header</tag> - DOS 3.3 header (address and length) + <tag><tt/__EXEHDR__:/ Executable file header</tag> + Default: DOS 3.3 header (address and length). Use <tt/-D __EXEHDR__=0/ to omit + the header. -</descrip><p> + <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> + Default: $800. Use <tt/-D __STACKSIZE__=<size>/ to set a different + stack size. + <tag><tt/__HIMEM__:/ Highest usable memory address presumed at link time</tag> + Default: $9600. Use <tt/-D __HIMEM__=<addr>/ to set a different + highest usable address. -<sect1><tt/apple2-dos33.cfg/<p> + <tag><tt/__LCADDR__:/ Address of code in the Language Card</tag> + Default: $D400. Use <tt/-D __LCADDR__=<addr>/ to set a different + code address. -Configuration optimized for a binary program running on DOS 3.3. A plain -vanilla DOS 3.3 doesn't make use of the Language Card at all. - -<descrip> - - <tag><tt/RAM:/ Main memory area</tag> - From $803 to $95FF (35.5 KB) - - <tag><tt/LC:/ Language Card memory area</tag> - From $D000 to $FFFF (12 KB) - - <tag><tt/STARTADDRESS:/ Program start address</tag> - Variable (default: $803) - - <tag><tt/HEADER:/ Binary file header</tag> - DOS 3.3 header (address and length) + <tag><tt/__LCSIZE__:/ Size of code in the Language Card</tag> + Default: $C00. Use <tt/-D __LCSIZE__=<size>/ to set a different + code size. </descrip><p> <sect1><tt/apple2-system.cfg/<label id="apple-sys-cfg"><p> -Configuration for a system program running on ProDOS 8. +Configuration for a system program running on ProDOS 8 and using the memory from +$2000 to $BEFF. <descrip> - <tag><tt/RAM:/ Main memory area</tag> - From $2000 to $BEFF (39.75 KB) + <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> + Default: $800. Use <tt/-D __STACKSIZE__=<size>/ to set a different + stack size. - <tag><tt/LC:/ Language Card memory area</tag> - From $D400 to $DFFF (3 KB) + <tag><tt/__LCADDR__:/ Address of code in the Language Card</tag> + Default: $D400. Use <tt/-D __LCADDR__=<addr>/ to set a different + code address. - <tag><tt/STARTADDRESS:/ Program start address</tag> - Fixed ($2000) - - <tag><tt/HEADER:/ Binary file header</tag> - None + <tag><tt/__LCSIZE__:/ Size of code in the Language Card</tag> + Default: $C00. Use <tt/-D __LCSIZE__=<size>/ to set a different + code size. </descrip><p> -<sect1><tt/apple2-loader.cfg/<label id="apple-load-cfg"><p> +<sect1><tt/apple2-overlay.cfg/<p> -Configuration optimized for a binary program running on ProDOS 8 without -BASIC.SYSTEM. Intended to be used with <bf/LOADER.SYSTEM - an -Apple ][ ProDOS 8 loader for cc65 programs/, which is available -in the cc65 User Contributions section. - -A program loaded by LOADER.SYSTEM works like a ProDOS 8 system program but -isn't tied to the start address $2000. Thus with the default start -address $800 the main memory area is increased by 6 KB. +Configuration for overlay programs with the up to nine overlays. The overlay files +don't include the DOS 3.3 header. See <tt>samples/overlaydemo.c</tt> for more +information on overlays. <descrip> - <tag><tt/RAM:/ Main memory area</tag> - From $800 to $BEFF (45.75 KB) - - <tag><tt/LC:/ Language Card memory area</tag> - From $D400 to $DFFF (3 KB) - <tag><tt/STARTADDRESS:/ Program start address</tag> - Variable (default: $800) + Default: $803. Use <tt/-S <addr>/ to set a different start address. - <tag><tt/HEADER:/ Binary file header</tag> - DOS 3.3 header (address and length) + <tag><tt/__EXEHDR__:/ Executable file header</tag> + Default: DOS 3.3 header (address and length). Use <tt/-D __EXEHDR__=0/ to omit + the header. + + <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> + Default: $800. Use <tt/-D __STACKSIZE__=<size>/ to set a different + stack size. + + <tag><tt/__HIMEM__:/ Highest usable memory address presumed at link time</tag> + Default: $9600. Use <tt/-D __HIMEM__=<addr>/ to set a different + highest usable address. + + <tag><tt/__LCADDR__:/ Address of code in the Language Card</tag> + Default: $D400. Use <tt/-D __LCADDR__=<addr>/ to set a different + code address. + + <tag><tt/__LCSIZE__:/ Size of code in the Language Card</tag> + Default: $C00. Use <tt/-D __LCSIZE__=<size>/ to set a different + code size. + + <tag><tt/__OVERLAYSIZE__:/ Size of code in the overlays</tag> + Default: $1000. Use <tt/-D __OVERLAYSIZE__=<size>/ to set a different + code size. </descrip><p> -<sect1><tt/apple2-reboot.cfg/<p> +<sect1><tt/apple2-asm.cfg/<p> -Configuration optimized for a binary program running on ProDOS 8 without -BASIC.SYSTEM. Intended to be used with <bf/LOADER.SYSTEM - an -Apple ][ ProDOS 8 loader for cc65 programs/ (see above) together -with the function <tt/rebootafterexit()/. +Configuration for a assembler programs which don't need a special setup. -If a ProDOS 8 system program doesn't quit to the ProDOS 8 dispatcher but rather -reboots the machine after exit then a plain vanilla ProDOS 8 doesn't make use of -the Language Card bank 2 at all. - -This setup makes nearly 50 KB available to a cc65 program - on a 64 KB machine! +Parameters: <descrip> - <tag><tt/RAM:/ Main memory area</tag> - From $800 to $BEFF (45.75 KB) - - <tag><tt/LC:/ Language Card memory area</tag> - From $D000 to $DFFF (4 KB) - <tag><tt/STARTADDRESS:/ Program start address</tag> - Variable (default: $800) + Default: $803. Use <tt/-S <addr>/ to set a different start address. - <tag><tt/HEADER:/ Binary file header</tag> - DOS 3.3 header (address and length) + <tag><tt/__EXEHDR__:/ Executable file header</tag> + Default: No header. Use <tt/-u __EXEHDR__ apple2.lib/ to add a DOS 3.3 header + (address and length). </descrip><p> @@ -230,10 +235,10 @@ range. The easiest (and for really large programs in fact the only) way to have a cc65 program use the memory from $800 to $2000 is to link it as binary -(as opposed to system) program using the linker configuration -<ref id="apple-load-cfg" name="apple2-loader.cfg"> with start address -$803 and load it with the targetutil LOADER.SYSTEM. The program then works -like a system program (i.e. quits to the ProDOS dispatcher). +(as opposed to system) program using the default linker configuration +<ref id="apple-def-cfg" name="apple2.cfg"> with __HIMEM__ set to $BF00 +and load it with the targetutil LOADER.SYSTEM. The program then works like a system +program (i.e. quits to the ProDOS dispatcher). Using LOADER.SYSTEM is as simple as copying it to the ProDOS 8 directory of the program to load under name <program>.SYSTEM as a system program. For @@ -325,8 +330,8 @@ The names in the parentheses denote the symbols to be used for static linking of <tag><tt/a2.hi.tgi (a2_hi_tgi)/</tag> This driver features a resolution of 280×192 with 8 colors and two hires pages. Note that programs using this driver will have to be linked - with <tt/--start-addr $4000/ to reserve the first hires page or with - <tt/--start-addr $6000/ to reserve both hires pages. + with <tt/-S $4000/ to reserve the first hires page or with <tt/-S $6000/ + to reserve both hires pages. 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. @@ -374,7 +379,7 @@ The names in the parentheses denote the symbols to be used for static linking of for an AppleMouse II Card compatible firmware. The default bounding box is [0..279,0..191]. - Programs using this driver will have to be linked with <tt/--start-addr $4000/ + Programs using this driver will have to be linked with <tt/-S $4000/ to reserve the first hires page if they are intended to run on an Apple ][ (in contrast to an Apple //e) because the AppleMouse II Card firmware writes to the hires page when initializing diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 215c6d384..5a9da7704 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -75,13 +75,30 @@ However while running module constructors/destructors the Language Card is disab Enabling the Language Card allows to use it as additional memory for cc65 generated code. However code is never automatically placed there. Rather code needs to be explicitly placed in the Language Card either per file by compiling -with <tt/--code-name HIGHCODE/ or per function by enclosing in <tt/#pragma -code-name (push, "HIGHCODE")/ and <tt/#pragma code-name (pop)/. In either case the -cc65 runtime system takes care of actually moving the code into the Language -Card. +with <tt/--code-name LC/ or per function by enclosing in <tt/#pragma code-name +(push, "LC")/ and <tt/#pragma code-name (pop)/. In either case the cc65 runtime +system takes care of actually moving the code into the Language Card. The amount of memory available in the Language Card for generated code depends -on the chosen <ref id="link-configs" name="linker configuration">. +on the <ref id="link-configs" name="linker configuration"> parameters. There are +several usefull settings: + +<descrip> + + <tag>LCADDR: $D400, LCSIZE: $C00</tag> + For plain vanilla ProDOS 8 which doesn't actually use the Language Card bank 2 + memory from $D400 to $DFFF. This is the default setting. + + <tag>LCADDR: $D000, LCSIZE: $1000</tag> + For ProDOS 8 together with the function <tt/rebootafterexit()/. If a program + doesn't quit to the ProDOS 8 dispatcher but rather reboots the machine after + exit then a plain vanilla ProDOS 8 doesn't make use of the Language Card bank + 2 at all. + + <tag>LCADDR: $D000, LCSIZE: $3000</tag> + For plain vanilla DOS 3.3 which doesn't make use of the Language Card at all. + +</descrip><p> @@ -93,126 +110,114 @@ The apple2enh package comes with additional secondary linker config files, which are used via <tt/-t apple2enh -C <configfile>/. -<sect1>default config file (<tt/apple2enh.cfg/)<p> +<sect1>default config file (<tt/apple2enh.cfg/)<label id="apple-def-cfg"><p> -Default configuration optimized for a binary program running on ProDOS 8 with -BASIC.SYSTEM. A plain vanilla ProDOS 8 doesn't actually use the Language Card -bank 2 memory from $D400 to $DFFF. +Default configuration for a binary program. + +Parameters: <descrip> - <tag><tt/RAM:/ Main memory area</tag> - From $803 to $95FF (35.5 KB) - - <tag><tt/LC:/ Language Card memory area</tag> - From $D400 to $DFFF (3 KB) - <tag><tt/STARTADDRESS:/ Program start address</tag> - Variable (default: $803) + Default: $803. Use <tt/-S <addr>/ to set a different start address. - <tag><tt/HEADER:/ Binary file header</tag> - DOS 3.3 header (address and length) + <tag><tt/__EXEHDR__:/ Executable file header</tag> + Default: DOS 3.3 header (address and length). Use <tt/-D __EXEHDR__=0/ to omit + the header. -</descrip><p> + <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> + Default: $800. Use <tt/-D __STACKSIZE__=<size>/ to set a different + stack size. + <tag><tt/__HIMEM__:/ Highest usable memory address presumed at link time</tag> + Default: $9600. Use <tt/-D __HIMEM__=<addr>/ to set a different + highest usable address. -<sect1><tt/apple2enh-dos33.cfg/<p> + <tag><tt/__LCADDR__:/ Address of code in the Language Card</tag> + Default: $D400. Use <tt/-D __LCADDR__=<addr>/ to set a different + code address. -Configuration optimized for a binary program running on DOS 3.3. A plain -vanilla DOS 3.3 doesn't make use of the Language Card at all. - -<descrip> - - <tag><tt/RAM:/ Main memory area</tag> - From $803 to $95FF (35.5 KB) - - <tag><tt/LC:/ Language Card memory area</tag> - From $D000 to $FFFF (12 KB) - - <tag><tt/STARTADDRESS:/ Program start address</tag> - Variable (default: $803) - - <tag><tt/HEADER:/ Binary file header</tag> - DOS 3.3 header (address and length) + <tag><tt/__LCSIZE__:/ Size of code in the Language Card</tag> + Default: $C00. Use <tt/-D __LCSIZE__=<size>/ to set a different + code size. </descrip><p> <sect1><tt/apple2enh-system.cfg/<label id="apple-sys-cfg"><p> -Configuration for a system program running on ProDOS 8. +Configuration for a system program running on ProDOS 8 and using the memory from +$2000 to $BEFF. <descrip> - <tag><tt/RAM:/ Main memory area</tag> - From $2000 to $BEFF (39.75 KB) + <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> + Default: $800. Use <tt/-D __STACKSIZE__=<size>/ to set a different + stack size. - <tag><tt/LC:/ Language Card memory area</tag> - From $D400 to $DFFF (3 KB) + <tag><tt/__LCADDR__:/ Address of code in the Language Card</tag> + Default: $D400. Use <tt/-D __LCADDR__=<addr>/ to set a different + code address. - <tag><tt/STARTADDRESS:/ Program start address</tag> - Fixed ($2000) - - <tag><tt/HEADER:/ Binary file header</tag> - None + <tag><tt/__LCSIZE__:/ Size of code in the Language Card</tag> + Default: $C00. Use <tt/-D __LCSIZE__=<size>/ to set a different + code size. </descrip><p> -<sect1><tt/apple2enh-loader.cfg/<label id="apple-load-cfg"><p> +<sect1><tt/apple2enh-overlay.cfg/<p> -Configuration optimized for a binary program running on ProDOS 8 without -BASIC.SYSTEM. Intended to be used with <bf/LOADER.SYSTEM - an -Apple ][ ProDOS 8 loader for cc65 programs/, which is available -in the cc65 User Contributions section. - -A program loaded by LOADER.SYSTEM works like a ProDOS 8 system program but -isn't tied to the start address $2000. Thus with the default start -address $800 the main memory area is increased by 6 KB. +Configuration for overlay programs with the up to nine overlays. The overlay files +don't include the DOS 3.3 header. See <tt>samples/overlaydemo.c</tt> for more +information on overlays. <descrip> - <tag><tt/RAM:/ Main memory area</tag> - From $800 to $BEFF (45.75 KB) - - <tag><tt/LC:/ Language Card memory area</tag> - From $D400 to $DFFF (3 KB) - <tag><tt/STARTADDRESS:/ Program start address</tag> - Variable (default: $800) + Default: $803. Use <tt/-S <addr>/ to set a different start address. - <tag><tt/HEADER:/ Binary file header</tag> - DOS 3.3 header (address and length) + <tag><tt/__EXEHDR__:/ Executable file header</tag> + Default: DOS 3.3 header (address and length). Use <tt/-D __EXEHDR__=0/ to omit + the header. + + <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> + Default: $800. Use <tt/-D __STACKSIZE__=<size>/ to set a different + stack size. + + <tag><tt/__HIMEM__:/ Highest usable memory address presumed at link time</tag> + Default: $9600. Use <tt/-D __HIMEM__=<addr>/ to set a different + highest usable address. + + <tag><tt/__LCADDR__:/ Address of code in the Language Card</tag> + Default: $D400. Use <tt/-D __LCADDR__=<addr>/ to set a different + code address. + + <tag><tt/__LCSIZE__:/ Size of code in the Language Card</tag> + Default: $C00. Use <tt/-D __LCSIZE__=<size>/ to set a different + code size. + + <tag><tt/__OVERLAYSIZE__:/ Size of code in the overlays</tag> + Default: $1000. Use <tt/-D __OVERLAYSIZE__=<size>/ to set a different + code size. </descrip><p> -<sect1><tt/apple2enh-reboot.cfg/<p> +<sect1><tt/apple2enh-asm.cfg/<p> -Configuration optimized for a binary program running on ProDOS 8 without -BASIC.SYSTEM. Intended to be used with <bf/LOADER.SYSTEM - an -Apple ][ ProDOS 8 loader for cc65 programs/ (see above) together -with the function <tt/rebootafterexit()/. +Configuration for a assembler programs which don't need a special setup. -If a ProDOS 8 system program doesn't quit to the ProDOS 8 dispatcher but rather -reboots the machine after exit then a plain vanilla ProDOS 8 doesn't make use of -the Language Card bank 2 at all. - -This setup makes nearly 50 KB available to a cc65 program - on a 64 KB machine! +Parameters: <descrip> - <tag><tt/RAM:/ Main memory area</tag> - From $800 to $BEFF (45.75 KB) - - <tag><tt/LC:/ Language Card memory area</tag> - From $D000 to $DFFF (4 KB) - <tag><tt/STARTADDRESS:/ Program start address</tag> - Variable (default: $800) + Default: $803. Use <tt/-S <addr>/ to set a different start address. - <tag><tt/HEADER:/ Binary file header</tag> - DOS 3.3 header (address and length) + <tag><tt/__EXEHDR__:/ Executable file header</tag> + Default: No header. Use <tt/-u __EXEHDR__ apple2enh.lib/ to add a DOS 3.3 header + (address and length). </descrip><p> @@ -230,10 +235,10 @@ range. The easiest (and for really large programs in fact the only) way to have a cc65 program use the memory from $800 to $2000 is to link it as binary -(as opposed to system) program using the linker configuration -<ref id="apple-load-cfg" name="apple2enh-loader.cfg"> with start address -$803 and load it with the targetutil LOADER.SYSTEM. The program then works -like a system program (i.e. quits to the ProDOS dispatcher). +(as opposed to system) program using the default linker configuration +<ref id="apple-def-cfg" name="apple2enh.cfg"> with __HIMEM__ set to $BF00 +and load it with the targetutil LOADER.SYSTEM. The program then works like a system +program (i.e. quits to the ProDOS dispatcher). Using LOADER.SYSTEM is as simple as copying it to the ProDOS 8 directory of the program to load under name <program>.SYSTEM as a system program. For @@ -328,8 +333,8 @@ The names in the parentheses denote the symbols to be used for static linking of <tag><tt/a2e.hi.tgi (a2e_hi_tgi)/</tag> This driver features a resolution of 280×192 with 8 colors and two hires pages. Note that programs using this driver will have to be linked - with <tt/--start-addr $4000/ to reserve the first hires page or with - <tt/--start-addr $6000/ to reserve both hires pages. + 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);/ @@ -354,7 +359,7 @@ The names in the parentheses denote the symbols to be used for static linking of <tag><tt/a2e.auxmem.emd (a2e_auxmem_emd)/</tag> Gives access to 47.5 KB RAM (190 pages of 256 bytes each) on an Extended 80-Column Text Card. - + Note that this driver doesn't check for the actual existence of the memory and that it doesn't check for ProDOS 8 RAM disk content! @@ -429,7 +434,7 @@ BASIC.SYSTEM) there are some limitations for DOS 3.3: 'Failed to alloc interrupt' on program startup. This implicitly means that <tt/a2e.stdmou.mou/ and <tt/a2e.ssc.ser/ are not functional as they depend on interrupts. - + </descrip><p> @@ -494,7 +499,7 @@ url="ca65.html" name="assembler manual">. <tag/Drive ID/ The function <url url="dio.html#s1" name="dio_open()"> has the single parameter <tt/device/ to identify the device to be opened. Therefore an - Apple II slot and drive pair is mapped to that <tt/drive_id/ according + Apple II slot and drive pair is mapped to that <tt/device/ according to the formula <tscreen> From c9734004eed9741ec90786e3d8fedb2ecbab3b2a Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 25 Mar 2016 19:03:12 +0100 Subject: [PATCH 0035/2161] Minor fixes for recent doc change. --- doc/apple2.sgml | 12 ++++++++---- doc/apple2enh.sgml | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 7443e50b7..b576ae6c1 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -85,17 +85,17 @@ several usefull settings: <descrip> - <tag>LCADDR: $D400, LCSIZE: $C00</tag> + <tag>LC address: $D400, LC size: $C00</tag> For plain vanilla ProDOS 8 which doesn't actually use the Language Card bank 2 memory from $D400 to $DFFF. This is the default setting. - <tag>LCADDR: $D000, LCSIZE: $1000</tag> + <tag>LC address: $D000, LC size: $1000</tag> For ProDOS 8 together with the function <tt/rebootafterexit()/. If a program doesn't quit to the ProDOS 8 dispatcher but rather reboots the machine after exit then a plain vanilla ProDOS 8 doesn't make use of the Language Card bank 2 at all. - <tag>LCADDR: $D000, LCSIZE: $3000</tag> + <tag>LC address: $D000, LC size: $3000</tag> For plain vanilla DOS 3.3 which doesn't make use of the Language Card at all. </descrip><p> @@ -149,6 +149,8 @@ Parameters: Configuration for a system program running on ProDOS 8 and using the memory from $2000 to $BEFF. +Parameters: + <descrip> <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> @@ -172,6 +174,8 @@ Configuration for overlay programs with the up to nine overlays. The overlay fil don't include the DOS 3.3 header. See <tt>samples/overlaydemo.c</tt> for more information on overlays. +Parameters: + <descrip> <tag><tt/STARTADDRESS:/ Program start address</tag> @@ -236,7 +240,7 @@ range. The easiest (and for really large programs in fact the only) way to have a cc65 program use the memory from $800 to $2000 is to link it as binary (as opposed to system) program using the default linker configuration -<ref id="apple-def-cfg" name="apple2.cfg"> with __HIMEM__ set to $BF00 +<ref id="apple-def-cfg" name="apple2.cfg"> with <tt/__HIMEM__/ set to $BF00 and load it with the targetutil LOADER.SYSTEM. The program then works like a system program (i.e. quits to the ProDOS dispatcher). diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 5a9da7704..6ee525114 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -85,17 +85,17 @@ several usefull settings: <descrip> - <tag>LCADDR: $D400, LCSIZE: $C00</tag> + <tag>LC address: $D400, LC size: $C00</tag> For plain vanilla ProDOS 8 which doesn't actually use the Language Card bank 2 memory from $D400 to $DFFF. This is the default setting. - <tag>LCADDR: $D000, LCSIZE: $1000</tag> + <tag>LC address: $D000, LC size: $1000</tag> For ProDOS 8 together with the function <tt/rebootafterexit()/. If a program doesn't quit to the ProDOS 8 dispatcher but rather reboots the machine after exit then a plain vanilla ProDOS 8 doesn't make use of the Language Card bank 2 at all. - <tag>LCADDR: $D000, LCSIZE: $3000</tag> + <tag>LC address: $D000, LC size: $3000</tag> For plain vanilla DOS 3.3 which doesn't make use of the Language Card at all. </descrip><p> @@ -149,6 +149,8 @@ Parameters: Configuration for a system program running on ProDOS 8 and using the memory from $2000 to $BEFF. +Parameters: + <descrip> <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> @@ -172,6 +174,8 @@ Configuration for overlay programs with the up to nine overlays. The overlay fil don't include the DOS 3.3 header. See <tt>samples/overlaydemo.c</tt> for more information on overlays. +Parameters: + <descrip> <tag><tt/STARTADDRESS:/ Program start address</tag> @@ -236,7 +240,7 @@ range. The easiest (and for really large programs in fact the only) way to have a cc65 program use the memory from $800 to $2000 is to link it as binary (as opposed to system) program using the default linker configuration -<ref id="apple-def-cfg" name="apple2enh.cfg"> with __HIMEM__ set to $BF00 +<ref id="apple-def-cfg" name="apple2enh.cfg"> with <tt/__HIMEM__/set to $BF00 and load it with the targetutil LOADER.SYSTEM. The program then works like a system program (i.e. quits to the ProDOS dispatcher). From 29d1400340f803d0df1ca2b6b2f85a3e3baca9a3 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 25 Mar 2016 21:57:06 +0100 Subject: [PATCH 0036/2161] Allow _sys() to call ROM routines. _sys() is supposed to be (primarily) intended to call ROM routines. Leveraging the "file overlay" mechanism of the cc65 build system allows to provide a Apple II specific _sys() implementation that temporarily switches in the ROM. --- libsrc/apple2/_sys.s | 81 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 libsrc/apple2/_sys.s diff --git a/libsrc/apple2/_sys.s b/libsrc/apple2/_sys.s new file mode 100644 index 000000000..ae4ea81d2 --- /dev/null +++ b/libsrc/apple2/_sys.s @@ -0,0 +1,81 @@ +; +; void __fastcall__ _sys (struct regs* r); +; + + .export __sys + .import jmpvec + + .include "zeropage.inc" + + .segment "LOWCODE" + +__sys: sta ptr1 + stx ptr1+1 ; Save the pointer to r + + ; Fetch the PC and store it into the jump vector + ldy #5 + lda (ptr1),y + sta jmpvec+2 + dey + lda (ptr1),y + sta jmpvec+1 + + ; Remember the flags so we can restore them to a known state after calling the + ; routine + php + + ; Get the flags, keep the state of bit 4 and 5 using the other flags from + ; the flags value passed by the caller. Push the new flags and push A. + dey + php + pla ; Current flags -> A + eor (ptr1),y + and #%00110000 + eor (ptr1),y + pha ; Push new flags value + ldy #0 + lda (ptr1),y + pha + + ; Get and assign X and Y + iny + lda (ptr1),y + tax + iny + lda (ptr1),y + tay + + ; Switch in ROM + bit $C082 + + ; Set A and the flags, call the machine code routine + pla + plp + jsr jmpvec + + ; Back from the routine. Save the flags and A. + php + pha + + ; Switch in LC bank 2 for R/O + bit $C080 + + ; Put the register values into the regs structure + tya + ldy #2 + sta (ptr1),y + dey + txa + sta (ptr1),y + dey + pla + sta (ptr1),y + ldy #3 + pla + sta (ptr1),y + + ; Restore the old flags value + plp + + ; Done + rts From e2419ece0b596d137b6a9b98f4eb2844c8c29578 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 27 Mar 2016 18:26:46 +0200 Subject: [PATCH 0037/2161] Added scrcode macro for the Apple II. Although the Apple II generally works with plain ASCII (i.e. in the ProDOS 8 MLI) the actual screen codes differ. This fixes #260. --- asminc/apple2.mac | 48 +++++++++++++++++++++++++++++++++++++++++++++++ doc/ca65.sgml | 6 ++++++ 2 files changed, 54 insertions(+) create mode 100644 asminc/apple2.mac diff --git a/asminc/apple2.mac b/asminc/apple2.mac new file mode 100644 index 000000000..b9860c092 --- /dev/null +++ b/asminc/apple2.mac @@ -0,0 +1,48 @@ +; Convert characters to screen codes + +; Helper macro that converts and outputs one character +.macro _scrcode char + .if (char < 256) + .byte (char + 128) + .else + .error "scrcode: Character constant out of range" + .endif +.endmacro + +.macro scrcode arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 + + ; Bail out if next argument is empty + .if .blank (arg1) + .exitmacro + .endif + + ; Check for a string + .if .match ({arg1}, "") + + ; Walk over all string chars + .repeat .strlen (arg1), i + _scrcode {.strat (arg1, i)} + .endrepeat + + ; Check for a number + .elseif .match (.left (1, {arg1}), 0) + + ; Just output the number + _scrcode arg1 + + ; Check for a character + .elseif .match (.left (1, {arg1}), 'a') + + ; Just output the character + _scrcode arg1 + + ; Anything else is an error + .else + + .error "scrcode: invalid argument type" + + .endif + + ; Call the macro recursively with the remaining args + scrcode arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 +.endmacro diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 14fe8714f..6ea17d335 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -4450,6 +4450,12 @@ The package defines the following macros: +<sect1><tt>.MACPACK apple2</tt><p> + +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 atari</tt><p> This macro package defines a macro named <tt/scrcode/. It takes a string From e92f3547408978f6f289e9549ad6e32f19e9fd15 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 27 Mar 2016 18:27:53 +0200 Subject: [PATCH 0038/2161] Made use of recently added Apple scrcode macro. --- libsrc/apple2/irq.s | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/libsrc/apple2/irq.s b/libsrc/apple2/irq.s index 97a1633b4..a356e1660 100644 --- a/libsrc/apple2/irq.s +++ b/libsrc/apple2/irq.s @@ -9,6 +9,8 @@ .include "apple2.inc" + .macpack apple2 + .segment "ONCE" initirq: @@ -36,17 +38,9 @@ prterr: ldx #msglen-1 jmp _exit errmsg: .ifdef __APPLE2ENH__ - .byte $8D, 't'|$80, 'p'|$80, 'u'|$80, 'r'|$80, 'r'|$80 - .byte 'e'|$80, 't'|$80, 'n'|$80, 'i'|$80, ' '|$80, 'c'|$80 - .byte 'o'|$80, 'l'|$80, 'l'|$80, 'a'|$80, ' '|$80, 'o'|$80 - .byte 't'|$80, ' '|$80, 'd'|$80, 'e'|$80, 'l'|$80, 'i'|$80 - .byte 'a'|$80, 'F'|$80, $8D + scrcode $0D, "tpurretni colla ot deliaF", $0D .else - .byte $8D, 'T'|$80, 'P'|$80, 'U'|$80, 'R'|$80, 'R'|$80 - .byte 'E'|$80, 'T'|$80, 'N'|$80, 'I'|$80, ' '|$80, 'C'|$80 - .byte 'O'|$80, 'L'|$80, 'L'|$80, 'A'|$80, ' '|$80, 'O'|$80 - .byte 'T'|$80, ' '|$80, 'D'|$80, 'E'|$80, 'L'|$80, 'I'|$80 - .byte 'A'|$80, 'F'|$80, $8D + scrcode $0D, "TPURRETNI COLLA OT DELIAF", $0D .endif msglen = * - errmsg From f10361751275b96afb1348c92e6059ca2cb787fb Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 27 Mar 2016 18:29:45 +0200 Subject: [PATCH 0039/2161] Use .macpack to include macro package. --- libsrc/atari5200/cartname.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/atari5200/cartname.s b/libsrc/atari5200/cartname.s index c6a701884..11cbaaa67 100644 --- a/libsrc/atari5200/cartname.s +++ b/libsrc/atari5200/cartname.s @@ -2,10 +2,10 @@ ; ; Christian Groessler, 01-Mar-2014 -.include "atari.mac" - .export __CART_NAME__: absolute = 1 +.macpack atari + .segment "CARTNAME" scrcode " cc" From d2f012e4143de46e4f8892b90dc0dd2adeeaa45a Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 27 Mar 2016 18:50:54 +0200 Subject: [PATCH 0040/2161] Updated Protovision Shop URL. --- doc/c128.sgml | 5 +++-- doc/c64.sgml | 5 +++-- doc/pet.sgml | 5 +++-- doc/vic20.sgml | 5 +++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/doc/c128.sgml b/doc/c128.sgml index a98b04f49..460621be0 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -244,8 +244,9 @@ The default drivers, <tt/joy_stddrv (joy_static_stddrv)/, point to <tt/c128-stdj <tag><tt/c128-ptvjoy.joy (c128_ptvjoy_joy)/</tag> Driver for the Protovision 4-player adapter originally written by Groepaz for the C64, and converted for the C128 by Uz. See <url - url="http://www.protovision-online.de/hardw/hardwstart.htm"> for prices and - building instructions. Up to four joysticks are supported. + url="http://www.protovision-online.de/hardw/4_player.php?language=en" + name="Protovision shop"> for prices and building instructions. Up to four + joysticks are supported. <tag><tt/c128-stdjoy.joy (c128_stdjoy_joy)/</tag> Supports up to two joysticks connected to the standard joysticks ports of diff --git a/doc/c64.sgml b/doc/c64.sgml index 4bf43453d..40bcb37ac 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -319,8 +319,9 @@ The default drivers, <tt/joy_stddrv (joy_static_stddrv)/, point to <tt/c64-stdjo <tag><tt/c64-ptvjoy.joy (c64_ptvjoy_joy)/</tag> Driver for the Protovision 4-player adapter contributed by Groepaz. See - <url url="http://www.protovision-online.de/hardw/hardwstart.htm"> for prices and - building instructions. Up to four joysticks are supported. + <url url="http://www.protovision-online.de/hardw/4_player.php?language=en" + name="Protovision shop"> for prices and building instructions. Up to four + joysticks are supported. <tag><tt/c64-stdjoy.joy (c64_stdjoy_joy)/</tag> Supports up to two standard joysticks connected to the joysticks port of diff --git a/doc/pet.sgml b/doc/pet.sgml index 7c5bd71ea..fd61716dd 100644 --- a/doc/pet.sgml +++ b/doc/pet.sgml @@ -155,8 +155,9 @@ The default drivers, <tt/joy_stddrv (joy_static_stddrv)/, point to <tt/pet-stdjo <tag><tt/pet-ptvjoy.joy (pet_ptvjoy_joy)/</tag> Driver for the Protovision 4-player adapter contributed by Groepaz. See - <url url="http://www.protovision-online.de/hardw/hardwstart.htm"> for prices and - building instructions. Up to two joysticks are supported. + <url url="http://www.protovision-online.de/hardw/4_player.php?language=en" + name="Protovision shop"> for prices and building instructions. Up to two + joysticks are supported. <tag><tt/pet-stdjoy.joy (pet_stdjoy_joy)/</tag> Driver for the standard PET userport joystick. diff --git a/doc/vic20.sgml b/doc/vic20.sgml index 5fba59a13..b1a08ac83 100644 --- a/doc/vic20.sgml +++ b/doc/vic20.sgml @@ -161,8 +161,9 @@ The default drivers, <tt/joy_stddrv (joy_static_stddrv)/, point to <tt/vic20-std <tag><tt/vic20-ptvjoy.joy (vic20_ptvjoy_joy)/</tag> Driver for the Protovision 4-player adapter contributed by Groepaz. See - <url url="http://www.protovision-online.de/hardw/hardwstart.htm"> for prices and - building instructions. Up to three joysticks are supported. + <url url="http://www.protovision-online.de/hardw/4_player.php?language=en" + name="Protovision shop"> for prices and building instructions. Up to three + joysticks are supported. </descrip><p> From 8b685763d4c0845b6f877aa79ec6c6db890f7ffc Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 27 Mar 2016 19:09:00 +0200 Subject: [PATCH 0041/2161] Renamed chrcvt to chrcvt65 and added it to the build. The /Makefile presumes that all binaries are are named *65 so chrcvt had to be renamed in order to be added to the build. --- doc/{chrcvt.sgml => chrcvt65.sgml} | 14 +++++++------- doc/index.sgml | 4 ++-- src/Makefile | 21 +++++++++++---------- src/{chrcvt => chrcvt65}/error.c | 2 +- src/{chrcvt => chrcvt65}/error.h | 2 +- src/{chrcvt => chrcvt65}/main.c | 9 ++++----- 6 files changed, 26 insertions(+), 26 deletions(-) rename doc/{chrcvt.sgml => chrcvt65.sgml} (86%) rename src/{chrcvt => chrcvt65}/error.c (97%) rename src/{chrcvt => chrcvt65}/error.h (97%) rename src/{chrcvt => chrcvt65}/main.c (98%) diff --git a/doc/chrcvt.sgml b/doc/chrcvt65.sgml similarity index 86% rename from doc/chrcvt.sgml rename to doc/chrcvt65.sgml index 848fb529d..0c5538426 100644 --- a/doc/chrcvt.sgml +++ b/doc/chrcvt65.sgml @@ -1,12 +1,12 @@ <!doctype linuxdoc system> <!-- -*- text-mode -*- --> <article> -<title>chrcvt Users Guide +<title>chrcvt65 Users Guide <author><url url="mailto:polluks@sdf.lonestar.org" name="Stefan A. Haubenthal"> <date>2013-02-10 <abstract> -chrcvt is the vector font converter. It is able to convert a foreign font into +chrcvt65 is the vector font converter. It is able to convert a foreign font into the native format. </abstract> @@ -18,7 +18,7 @@ the native format. <sect>Overview<p> -chrcvt is a vector font converter. It is able to convert a "BGI Stroked +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. @@ -26,7 +26,7 @@ url="funcref.html#tgi_load_vectorfont" name="tgi_load_vectorfont"> for usage. <sect>Usage<p> -The chrcvt utility converts the font of one Borland file to its cc65 equivalent. +The chrcvt65 utility converts the font of one Borland file to its cc65 equivalent. <sect1>Command line option overview<p> @@ -35,7 +35,7 @@ The program may be called as follows: <tscreen><verb> --------------------------------------------------------------------------- -Usage: chrcvt [options] file [options] [file] +Usage: chrcvt65 [options] file [options] [file] Short options: -h Help (this text) -v Be more verbose @@ -80,7 +80,7 @@ in TCH format to a new file. Example output for the command <tscreen><verb> -chrcvt --verbose LITT.CHR +chrcvt65 --verbose LITT.CHR </verb></tscreen> <tscreen><verb> BGI Stroked Font V1.1 - Aug 12, 1991 @@ -91,7 +91,7 @@ Copyright (c) 1987,1988 Borland International <sect>Copyright<p> -chrcvt is (C) Copyright 2009, Ullrich von Bassewitz. For usage of the +chrcvt65 is (C) Copyright 2009, Ullrich von Bassewitz. For usage of the binaries and/or sources the following conditions apply: This software is provided 'as-is', without any expressed or implied diff --git a/doc/index.sgml b/doc/index.sgml index 68f755a29..44b58ef5e 100644 --- a/doc/index.sgml +++ b/doc/index.sgml @@ -18,7 +18,7 @@ <tag><htmlurl url="cc65.html" name="cc65.html"></tag> Describes the cc65 C compiler. - <tag><htmlurl url="chrcvt.html" name="chrcvt.html"></tag> + <tag><htmlurl url="chrcvt65.html" name="chrcvt65.html"></tag> Describes the vector font converter. <tag><htmlurl url="cl65.html" name="cl65.html"></tag> @@ -31,7 +31,7 @@ Describes the da65 6502/65C02 disassembler. <tag><htmlurl url="grc65.html" name="grc65.html"></tag> - Describes the GEOS resource compiler (grc65). + Describes the GEOS resource compiler. <tag><htmlurl url="ld65.html" name="ld65.html"></tag> Describes the ld65 linker. diff --git a/src/Makefile b/src/Makefile index 5aafc4bb8..f10c189b3 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,16 +2,17 @@ ifneq ($(shell echo),) CMD_EXE = 1 endif -PROGS = ar65 \ - ca65 \ - cc65 \ - cl65 \ - co65 \ - da65 \ - grc65 \ - ld65 \ - od65 \ - sim65 \ +PROGS = ar65 \ + ca65 \ + cc65 \ + chrcvt65 \ + cl65 \ + co65 \ + da65 \ + grc65 \ + ld65 \ + od65 \ + sim65 \ sp65 .PHONY: all mostlyclean clean install zip avail unavail bin $(PROGS) diff --git a/src/chrcvt/error.c b/src/chrcvt65/error.c similarity index 97% rename from src/chrcvt/error.c rename to src/chrcvt65/error.c index 424080d83..d6bc57fdf 100644 --- a/src/chrcvt/error.c +++ b/src/chrcvt65/error.c @@ -2,7 +2,7 @@ /* */ /* error.c */ /* */ -/* Error handling for the chrcvt vector font converter */ +/* Error handling for the chrcvt65 vector font converter */ /* */ /* */ /* */ diff --git a/src/chrcvt/error.h b/src/chrcvt65/error.h similarity index 97% rename from src/chrcvt/error.h rename to src/chrcvt65/error.h index 93f59ccfd..c5d1474e9 100644 --- a/src/chrcvt/error.h +++ b/src/chrcvt65/error.h @@ -2,7 +2,7 @@ /* */ /* error.h */ /* */ -/* Error handling for the chrcvt vector font converter */ +/* Error handling for the chrcvt65 vector font converter */ /* */ /* */ /* */ diff --git a/src/chrcvt/main.c b/src/chrcvt65/main.c similarity index 98% rename from src/chrcvt/main.c rename to src/chrcvt65/main.c index 7b1c3219e..8685e06b9 100644 --- a/src/chrcvt/main.c +++ b/src/chrcvt65/main.c @@ -2,7 +2,7 @@ /* */ /* main.c */ /* */ -/* Main program of the chrcvt vector font converter */ +/* Main program of the chrcvt65 vector font converter */ /* */ /* */ /* */ @@ -46,7 +46,7 @@ #include "xmalloc.h" #include "version.h" -/* chrcvt */ +/* chrcvt65 */ #include "error.h" @@ -219,8 +219,7 @@ static void OptVersion (const char* Opt attribute ((unused)), /* Print the assembler version */ { fprintf (stderr, - "%s V%s - (C) Copyright 2009, Ullrich von Bassewitz\n", - ProgName, GetVersionAsString ()); + "%s V%s\n", ProgName, GetVersionAsString ()); } @@ -482,7 +481,7 @@ int main (int argc, char* argv []) unsigned I; /* Initialize the cmdline module */ - InitCmdLine (&argc, &argv, "chrcvt"); + InitCmdLine (&argc, &argv, "chrcvt65"); /* Check the parameters */ I = 1; From fac246c799aee0bc0efebc8656cfeb1122177902 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 29 Mar 2016 05:40:12 -0400 Subject: [PATCH 0042/2161] Moved a warning message, about misaligned segments, to a configuration function. It used to be shown only if the segment was written into a binary file. Now, it's shown for all badly-aligned segments. --- src/ld65/bin.c | 12 ------------ src/ld65/config.c | 18 ++++++++++++++++-- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/ld65/bin.c b/src/ld65/bin.c index ada4f1e3c..c3efd9cd1 100644 --- a/src/ld65/bin.c +++ b/src/ld65/bin.c @@ -169,18 +169,6 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M) PrintNumVal ("Address", Addr); PrintNumVal ("FileOffs", (unsigned long) ftell (D->F)); - /* Check if the alignment for the segment from the linker config is - ** a multiple for that of the segment. - */ - if ((S->RunAlignment % S->Seg->Alignment) != 0) { - /* Segment requires another alignment than configured - ** in the linker. - */ - Warning ("Segment `%s' is not aligned properly. Resulting " - "executable may not be functional.", - GetString (S->Name)); - } - /* If this is the run memory area, we must apply run alignment. If ** this is not the run memory area but the load memory area (which ** means that both are different), we must apply load alignment. diff --git a/src/ld65/config.c b/src/ld65/config.c index 8e7a049c7..5959067b2 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -1855,6 +1855,20 @@ unsigned CfgProcess (void) /* This is the run (and maybe load) memory area. Handle ** alignment and explict start address and offset. */ + + /* Check if the alignment for the segment from the linker + ** config. is a multiple for that of the segment. + */ + if ((S->RunAlignment % S->Seg->Alignment) != 0) { + /* Segment requires another alignment than configured + ** in the linker. + */ + CfgWarning (GetSourcePos (S->LI), + "Segment `%s' isn't aligned properly; the" + " resulting executable might not be functional.", + GetString (S->Name)); + } + if (S->Flags & SF_ALIGN) { /* Align the address */ unsigned long NewAddr = AlignAddr (Addr, S->RunAlignment); @@ -1865,8 +1879,8 @@ unsigned CfgProcess (void) */ if (M->FillLevel == 0 && NewAddr > Addr) { CfgWarning (GetSourcePos (S->LI), - "First segment in memory area `%s' does " - "already need fill bytes for alignment", + "The first segment in memory area `%s' " + "needs fill bytes for alignment.", GetString (M->Name)); } From 7f06405bdb739e84da46b96c14ae7d59776a6bfa Mon Sep 17 00:00:00 2001 From: KORISNIK <korisnik@Powerbook-3.fritz.box> Date: Sun, 10 Apr 2016 02:21:36 +0200 Subject: [PATCH 0043/2161] A forgotten option. Empty arguments are not silent anymore. --- doc/sp65.sgml | 7 +++++++ src/sp65/main.c | 8 +++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/doc/sp65.sgml b/doc/sp65.sgml index 909ac6d25..ccad930c3 100644 --- a/doc/sp65.sgml +++ b/doc/sp65.sgml @@ -49,6 +49,7 @@ Short options: Long options: --convert-to fmt[,attrlist] Convert into target format + --dump-palette Dump palette as table --help Help (this text) --list-conversions List all possible conversions --pop Restore the original loaded image @@ -76,6 +77,12 @@ attribute lists see <ref id="attr-lists" name="below">. see section <ref id="conversions" name="Conversions">. + <label id="option--dump-palette"> + <tag><tt>--dump-palette</tt></tag> + + Dump palette as table. + + <label id="option--help"> <tag><tt>-h, --help</tt></tag> diff --git a/src/sp65/main.c b/src/sp65/main.c index ef2188c82..32cc1b936 100644 --- a/src/sp65/main.c +++ b/src/sp65/main.c @@ -92,6 +92,7 @@ static void Usage (void) "\n" "Long options:\n" " --convert-to fmt[,attrlist]\tConvert into target format\n" + " --dump-palette\t\tDump palette as table\n" " --help\t\t\tHelp (this text)\n" " --list-conversions\t\tList all possible conversions\n" " --pop\t\t\t\tRestore the original loaded image\n" @@ -273,7 +274,7 @@ static void OptSlice (const char* Opt attribute ((unused)), const char* Arg) static void OptVerbose (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) -/* Increase versbosity */ +/* Increase verbosity */ { ++Verbosity; } @@ -397,6 +398,11 @@ int main (int argc, char* argv []) ++I; } + /* Do we have an input file? */ + if (I == 1) { + Error ("No input file"); + } + /* Cleanup data */ SetWorkBitmap (C); FreeBitmap (B); From b14021e9ac4d7677d08903f7150fd8408b35ca30 Mon Sep 17 00:00:00 2001 From: Polluks <korisnik@Powerbook-3.fritz.box> Date: Tue, 12 Apr 2016 23:58:30 +0200 Subject: [PATCH 0044/2161] Fixed CPU definition of Lynx. Removed nonsense target vc20. --- asminc/lynx.inc | 2 +- asminc/supervision.inc | 5 ++--- src/common/target.c | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/asminc/lynx.inc b/asminc/lynx.inc index 2225bf3c8..81a60bf2e 100644 --- a/asminc/lynx.inc +++ b/asminc/lynx.inc @@ -4,7 +4,7 @@ ; ; Reference: ; Bastian Schick's Lynx Documentation -; http://www.geocities.com/SiliconValley/Byte/4242/lynx/ +; http://www.geocities.ws/SiliconValley/Byte/4242/lynx/ ; ; *** diff --git a/asminc/supervision.inc b/asminc/supervision.inc index a75fb02f6..a1cc212f6 100644 --- a/asminc/supervision.inc +++ b/asminc/supervision.inc @@ -1,8 +1,7 @@ ; supervision symbols -; supervision 65c02s -; in cc65 up to 2.9.1 65c02 means 65c02s -.pc02 +; supervision 65c02s +; in cc65 up to 2.9.1 65c02 means 65sc02 lcd_addr = $4000 LCD_LINESIZE = $30 diff --git a/src/common/target.c b/src/common/target.c index 7e152fe94..f76d03ffb 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -139,7 +139,7 @@ struct TargetEntry { }; /* Table that maps target names to ids. Sorted alphabetically for bsearch. -** Allows mupltiple entries for one target id (target name aliases). +** Allows multiple entries for one target id (target name aliases). */ static const TargetEntry TargetMap[] = { { "apple2", TGT_APPLE2 }, @@ -168,7 +168,6 @@ static const TargetEntry TargetMap[] = { { "sim6502", TGT_SIM6502 }, { "sim65c02", TGT_SIM65C02 }, { "supervision", TGT_SUPERVISION }, - { "vc20", TGT_VIC20 }, { "vic20", TGT_VIC20 }, }; #define MAP_ENTRY_COUNT (sizeof (TargetMap) / sizeof (TargetMap[0])) @@ -199,7 +198,7 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "atmos", CPU_6502, BINFMT_BINARY, CTNone }, { "nes", CPU_6502, BINFMT_BINARY, CTNone }, { "supervision", CPU_65SC02, BINFMT_BINARY, CTNone }, - { "lynx", CPU_65C02, BINFMT_BINARY, CTNone }, + { "lynx", CPU_65SC02, BINFMT_BINARY, CTNone }, { "sim6502", CPU_6502, BINFMT_BINARY, CTNone }, { "sim65c02", CPU_65C02, BINFMT_BINARY, CTNone }, }; From 2c7ccca2103c159b27b696dbf263b86eacf4f69c Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 22 Apr 2016 11:33:52 -0400 Subject: [PATCH 0045/2161] Added the optional C keyword "volatile" to the __asm__ statement grammar. It prevents the statement's Assembly code from being optimized (e.g., moved or removed). Optimization is disabled for that statement's entire function (other functions aren't affected). --- doc/cc65.sgml | 107 ++++++++++++++++++++++++--------------------- src/cc65/asmstmt.c | 11 +++++ 2 files changed, 68 insertions(+), 50 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 9198d6982..8346bac6b 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -2,8 +2,9 @@ <article> <title>cc65 Users Guide -<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2015-05-26 +<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> +<url url="mailto:gregdk@users.sf.net" name="Greg King"> +<date>2016-04-22 <abstract> cc65 is a C compiler for 6502 targets. It supports several 6502 based home @@ -15,7 +16,6 @@ computers like the Commodore and Atari machines, but it is easily retargetable. <!-- Begin the document --> - <sect>Overview<p> cc65 was originally a C compiler for the Atari 8-bit machines written by @@ -564,7 +564,7 @@ and the one defined by the ISO standard: that you must not mix pointers to those functions with pointers to user-written, cdecl functions (the calling conventions are incompatible). <p> -<item> The <tt/volatile/ keyword doesn't have an effect. This is not as bad +<item> The <tt/volatile/ keyword has almost no effect. That is not as bad as it sounds, since the 6502 has so few registers that it isn't possible to keep values in registers anyway. <p> @@ -586,14 +586,14 @@ This cc65 version has some extensions to the ISO C standard. file. The syntax is <tscreen><verb> - asm (<string literal>[, optional parameters]) ; + asm [optional volatile] (<string literal>[, optional parameters]) ; </verb></tscreen> or <tscreen><verb> - __asm__ (<string literal>[, optional parameters]) ; + __asm__ [optional volatile] (<string literal>[, optional parameters]) ; </verb></tscreen> - The first form is in the user namespace and is disabled if the <tt/-A/ + The first form is in the user namespace; and, is disabled if the <tt/-A/ switch is given. There is a whole section covering inline assembler statements, @@ -735,6 +735,7 @@ This cc65 version has some extensions to the ISO C standard. <p> + <sect>Predefined macros<p> The compiler defines several macros at startup: @@ -1224,39 +1225,44 @@ The compiler allows to insert assembler statements into the output file. The syntax is <tscreen><verb> - asm (<string literal>[, optional parameters]) ; + asm [optional volatile] (<string literal>[, optional parameters]) ; </verb></tscreen> or <tscreen><verb> - __asm__ (<string literal>[, optional parameters]) ; + __asm__ [optional volatile] (<string literal>[, optional parameters]) ; </verb></tscreen> <p> -The first form is in the user namespace and is disabled by <tt><ref +The first form is in the user namespace; and, is disabled by <tt><ref id="option--standard" name="--standard"></tt> if the argument is not <tt/cc65/. -The asm statement may be used inside a function and on global file level. An -inline assembler statement is a primary expression, so it may also be used as -part of an expression. Please note however that the result of an expression -containing just an inline assembler statement is always of type <tt/void/. +The <tt/asm/ statement can be used only inside a function. Please note that +the result of an inline assembler expression is always of type <tt/void/. -The contents of the string literal are preparsed by the compiler and inserted -into the generated assembly output, so that the can be further processed by -the backend and especially the optimizer. For this reason, the compiler does -only allow regular 6502 opcodes to be used with the inline assembler. Pseudo -instructions (like <tt/.import/, <tt/.byte/ and so on) are <em/not/ allowed, +The contents of the string literal are preparsed by the compiler; and, inserted +into the generated assembly output, so that it can be processed further by +the backend -- and, especially the optimizer. For that reason, the compiler does +allow only regular 6502 opcodes to be used with the inline assembler. Pseudo +instructions (like <tt/.import/, <tt/.byte/, and so on) are <em/not/ allowed, even if the ca65 assembler (which is used to translate the generated assembler -code) would accept them. The builtin inline assembler is not a replacement for -the full blown macro assembler which comes with the compiler. +code) would accept them. The built-in inline assembler is not a replacement for +the full-blown macro assembler which comes with the compiler. Note: Inline assembler statements are subject to all optimizations done by the -compiler. There is currently no way to protect an inline assembler statement -from being moved or removed completely by the optimizer. If in doubt, check -the generated assembler output, or disable optimizations. +compiler. There currently is no way to protect an inline assembler statement +-- alone -- from being moved or removed completely by the optimizer. If in +doubt, check the generated assembler output; or, disable optimizations (for +that function). + +As a shortcut, you can put the <tt/volatile/ qualifier in your <tt/asm/ +statements. It will disable optimization for the functions in which those +<tt/asm volatile/ statements sit. The effect is the same as though you put +</#pragma optimize(push, off)/ above those functions, and </#pragma +optimize(pop)/ below those functions. The string literal may contain format specifiers from the following list. For each format specifier, an argument is expected which is inserted instead of -the format specifier before passing the assembly code line to the backend. +the format specifier, before passing the assembly code line to the backend. <itemize> <item><tt/%b/ - Numerical 8-bit value @@ -1269,33 +1275,33 @@ the format specifier before passing the assembly code line to the backend. <item><tt/%%/ - The % sign itself </itemize><p> -Using these format specifiers, you can access C <tt/#defines/, variables or +Using those format specifiers, you can access C <tt/#defines/, variables, or similar stuff from the inline assembler. For example, to load the value of -a C <tt/#define/ into the Y register, one would use +a C <tt/#define/ into the Y index register, one would use <tscreen><verb> - #define OFFS 23 - __asm__ ("ldy #%b", OFFS); + #define OFFS 23 + __asm__ ("ldy #%b", OFFS); </verb></tscreen> Or, to access a struct member of a static variable: <tscreen><verb> - typedef struct { - unsigned char x; - unsigned char y; - unsigned char color; - } pixel_t; - static pixel_t pixel; - __asm__ ("ldy #%b", offsetof(pixel_t, color)); - __asm__ ("lda %v,y", pixel); + typedef struct { + unsigned char x; + unsigned char y; + unsigned char color; + } pixel_t; + static pixel_t pixel; + __asm__ ("ldy #%b", offsetof(pixel_t, color)); + __asm__ ("lda %v,y", pixel); </verb></tscreen> <p> The next example shows how to use global variables to exchange data between C -an assembler and how to handle assembler jumps: +and assembler; and, how to handle assembler jumps: <tscreen><verb> - unsigned char globalSubA, globalSubB, globalSubResult; + static unsigned char globalSubA, globalSubB, globalSubResult; /* return a-b, return 255 if b>a */ unsigned char sub (unsigned char a, unsigned char b) @@ -1314,19 +1320,19 @@ an assembler and how to handle assembler jumps: </verb></tscreen> <p> -Arrays can also be accessed: +Arrays also can be accessed: <tscreen><verb> - unsigned char globalSquareTable[] = { + static const unsigned char globalSquareTable[] = { 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225 }; - unsigned char globalSquareA, globalSquareResult; + static unsigned char globalSquareA, globalSquareResult; /* return a*a for a<16, else 255 */ unsigned char square (unsigned char a) { - if (a>15){ + if (a > 15) { return 255; } globalSquareA = a; @@ -1339,28 +1345,30 @@ Arrays can also be accessed: <p> Note: Do not embed the assembler labels that are used as names of global -variables or functions into your asm statements. Code like this +variables or functions into your <tt/asm/ statements. Code such as this: <tscreen><verb> int foo; - int bar () { return 1; } - __asm__ ("lda _foo"); /* DON'T DO THAT! */ + int bar (void) { return 1; } + ... + __asm__ ("lda _foo"); /* DON'T DO THAT! */ ... __asm__ ("jsr _bar"); /* DON'T DO THAT EITHER! */ </verb></tscreen> <p> -may stop working if the way, the compiler generates these names is changed in -a future version. Instead use the format specifiers from the table above: +might stop working if the way that the compiler generates those names is changed in +a future version. Instead, use the format specifiers from the table above: <tscreen><verb> - __asm__ ("lda %v", foo); /* OK */ + __asm__ ("lda %v", foo); /* OK */ ... __asm__ ("jsr %v", bar); /* OK */ </verb></tscreen> <p> + <sect>Implementation-defined behavior<p> This section describes the behavior of cc65 when the standard describes the @@ -1434,4 +1442,3 @@ freely, subject to the following restrictions: </enum> </article> - diff --git a/src/cc65/asmstmt.c b/src/cc65/asmstmt.c index 59c1332ff..4dd6628c4 100644 --- a/src/cc65/asmstmt.c +++ b/src/cc65/asmstmt.c @@ -41,12 +41,14 @@ /* cc65 */ #include "asmlabel.h" #include "codegen.h" +#include "codeseg.h" #include "datatype.h" #include "error.h" #include "expr.h" #include "function.h" #include "litpool.h" #include "scanner.h" +#include "segments.h" #include "stackptr.h" #include "symtab.h" #include "asmstmt.h" @@ -422,6 +424,15 @@ void AsmStatement (void) /* Skip the ASM */ NextToken (); + /* An optional volatile qualifier disables optimization for + ** the entire function [same as #pragma optimize(push, off)]. + */ + if (CurTok.Tok == TOK_VOLATILE) { + /* Don't optimize the Current code Segment */ + CS->Code->Optimize = 0; + NextToken (); + } + /* Need left parenthesis */ if (!ConsumeLParen ()) { return; From 8bd2628d1e1eeabe170304b564bf9ade9c2baf0b Mon Sep 17 00:00:00 2001 From: OzHawk <OzHawk@users.noreply.github.com> Date: Wed, 11 May 2016 19:24:16 +0930 Subject: [PATCH 0046/2161] Update the missing entries in the kernel jump table for the Vic20 with the actual function addresses. The Vic20 does not have kernal table entries for the following functions. ;----------------------------------------------------------------------------- ; Functions which are not in the kernal jump table for VIC-20 but are for C64 CINT := $E518 IOINIT := $FDF9 RAMTAS := $FD8D All other kernal entries are the same as the C64, however, without this change, the startup code fails. Without this change the vic20.lib builds incorrectly. --- libsrc/vic20/kernal.s | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libsrc/vic20/kernal.s b/libsrc/vic20/kernal.s index 35bedb466..d9e7a9d03 100644 --- a/libsrc/vic20/kernal.s +++ b/libsrc/vic20/kernal.s @@ -47,9 +47,9 @@ ;----------------------------------------------------------------------------- ; All functions are available in the kernal jump table -CINT = $FF81 -IOINIT = $FF84 -RAMTAS = $FF87 +CINT = $E518 ; No entries are in the kernal jump table for these functions. +IOINIT = $FDF9 ; The entries point directly to the function. +RAMTAS = $FD8D ; RESTOR = $FF8A VECTOR = $FF8D SETMSG = $FF90 From 93f55c274b3fc88f26590b0fb104eca2f3da0c37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrycjusz=20R=2E=20=C5=81ogiewa?= <patrycjusz.logiewa@srebrnysen.com> Date: Fri, 13 May 2016 14:28:58 +0200 Subject: [PATCH 0047/2161] moved output of target utils and drivers to separate directory --- doc/Makefile | 2 ++ libsrc/Makefile | 24 ++++++++++++++--------- libsrc/apple2/targetutil/Makefile.inc | 4 ++-- libsrc/atari/targetutil/Makefile.inc | 4 ++-- libsrc/geos-apple/targetutil/Makefile.inc | 4 ++-- libsrc/nes/Makefile.inc | 16 +++++++-------- 6 files changed, 31 insertions(+), 23 deletions(-) diff --git a/doc/Makefile b/doc/Makefile index 967443ef0..8b0b316b0 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -41,7 +41,9 @@ ifeq ($(wildcard ../info),../info) endif zip: +ifneq "$(wildcard ../html)" "" @cd .. && zip cc65 html/*.* +endif doc: html info diff --git a/libsrc/Makefile b/libsrc/Makefile index a4101aecd..ae65dc9b6 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -37,12 +37,15 @@ DRVTYPES = emd \ ser \ tgi -OUTPUTDIRS := lib \ - $(DRVTYPES) \ - targetutil \ - asminc \ - cfg \ - include \ +DRVOUTPUTDIRS := $(foreach drvtype,$(DRVTYPES),goodies/drivers/$(drvtype)) + +OUTPUTDIRS := lib \ + $(DRVOUTPUTDIRS) \ + goodies/targetutil \ + asminc \ + cfg \ + include \ + samples \ $(subst ../,,$(filter-out $(wildcard ../include/*.*),$(wildcard ../include/*))) .PHONY: all mostlyclean clean install zip lib $(TARGETS) @@ -76,8 +79,11 @@ all lib: $(TARGETS) mostlyclean: $(call RMDIR,../libwrk) +# Transitional line active. Final line commented out below in order to +# allow some time for transition between the directory structures clean: - $(call RMDIR,../libwrk ../lib ../targetutil $(addprefix ../,$(DRVTYPES))) + $(call RMDIR,../libwrk ../lib ../targetutil ../goodies $(addprefix ../,$(DRVTYPES))) +# $(call RMDIR,../libwrk ../lib ../goodies) ifdef CMD_EXE @@ -212,7 +218,7 @@ define DRVTYPE_template $1_SRCDIR = $$(SRCDIR)/$1 $1_STCDIR = ../libwrk/$$(TARGET) $1_DYNDIR = ../libwrk/$$(TARGET)/$1 -$1_DRVDIR = ../$1 +$1_DRVDIR = ../goodies/drivers/$1 $1_SRCPAT = $$($1_SRCDIR)/$$(OBJPFX)%.s $1_STCPAT = $$($1_STCDIR)/$$(OBJPFX)%-$1.o @@ -283,7 +289,7 @@ $(EXTRA_OBJPAT): $(EXTRA_SRCPAT) | ../lib ../lib/$(TARGET).lib: $(OBJS) | ../lib $(AR65) a $@ $? -../libwrk/$(TARGET) ../lib ../targetutil: +../libwrk/$(TARGET) ../lib ../goodies/targetutil: @$(call MKDIR,$@) $(TARGET): $(EXTRA_OBJS) ../lib/$(TARGET).lib diff --git a/libsrc/apple2/targetutil/Makefile.inc b/libsrc/apple2/targetutil/Makefile.inc index 105a5324f..0b8b39e1f 100644 --- a/libsrc/apple2/targetutil/Makefile.inc +++ b/libsrc/apple2/targetutil/Makefile.inc @@ -3,7 +3,7 @@ DEPS += ../libwrk/$(TARGET)/loader.d ../libwrk/$(TARGET)/loader.o: $(SRCDIR)/targetutil/loader.s | ../libwrk/$(TARGET) $(ASSEMBLE_recipe) -../targetutil/loader.system: ../libwrk/$(TARGET)/loader.o $(SRCDIR)/targetutil/loader.cfg | ../targetutil +../goodies/targetutil/loader.system: ../libwrk/$(TARGET)/loader.o $(SRCDIR)/targetutil/loader.cfg | ../goodies/targetutil $(LD65) -o $@ -C $(filter %.cfg,$^) $(filter-out %.cfg,$^) -$(TARGET): ../targetutil/loader.system +$(TARGET): ../goodies/targetutil/loader.system diff --git a/libsrc/atari/targetutil/Makefile.inc b/libsrc/atari/targetutil/Makefile.inc index 05405f2e6..42903a3ca 100644 --- a/libsrc/atari/targetutil/Makefile.inc +++ b/libsrc/atari/targetutil/Makefile.inc @@ -3,7 +3,7 @@ DEPS += ../libwrk/$(TARGET)/w2cas.d ../libwrk/$(TARGET)/w2cas.o: $(SRCDIR)/targetutil/w2cas.c | ../libwrk/$(TARGET) $(COMPILE_recipe) -../targetutil/w2cas.com: ../libwrk/$(TARGET)/w2cas.o ../lib/$(TARGET).lib | ../targetutil +../goodies/targetutil/w2cas.com: ../libwrk/$(TARGET)/w2cas.o ../lib/$(TARGET).lib | ../goodies/targetutil $(LD65) -o $@ -t $(TARGET) $^ -$(TARGET): ../targetutil/w2cas.com +$(TARGET): ../goodies/targetutil/w2cas.com diff --git a/libsrc/geos-apple/targetutil/Makefile.inc b/libsrc/geos-apple/targetutil/Makefile.inc index fbe31981c..d842b4d3f 100644 --- a/libsrc/geos-apple/targetutil/Makefile.inc +++ b/libsrc/geos-apple/targetutil/Makefile.inc @@ -8,7 +8,7 @@ DEPS += ../libwrk/$(TARGET)/convert.d ../lib/apple2enh.lib: @$(MAKE) --no-print-directory apple2enh -../targetutil/convert.system: ../libwrk/$(TARGET)/convert.o ../lib/apple2enh.lib | ../targetutil +../goodies/targetutil/convert.system: ../libwrk/$(TARGET)/convert.o ../lib/apple2enh.lib | ../goodies/targetutil $(LD65) -o $@ -C apple2enh-system.cfg $^ -$(TARGET): ../targetutil/convert.system +$(TARGET): ../goodies/targetutil/convert.system diff --git a/libsrc/nes/Makefile.inc b/libsrc/nes/Makefile.inc index f1dcbf18e..aaebef1db 100644 --- a/libsrc/nes/Makefile.inc +++ b/libsrc/nes/Makefile.inc @@ -1,8 +1,8 @@ -../tgi/nes-64-56-2.tgi: ../libwrk/nes/clrscr.o \ - ../libwrk/nes/cputc.o \ - ../libwrk/nes/get_tv.o \ - ../libwrk/nes/gotoxy.o \ - ../libwrk/nes/popa.o \ - ../libwrk/nes/ppu.o \ - ../libwrk/nes/ppubuf.o \ - ../libwrk/nes/setcursor.o +../goodies/drivers/tgi/nes-64-56-2.tgi: ../libwrk/nes/clrscr.o \ + ../libwrk/nes/cputc.o \ + ../libwrk/nes/get_tv.o \ + ../libwrk/nes/gotoxy.o \ + ../libwrk/nes/popa.o \ + ../libwrk/nes/ppu.o \ + ../libwrk/nes/ppubuf.o \ + ../libwrk/nes/setcursor.o From 1369bed8810e75f7cf87212ae75ec672fbe084ef Mon Sep 17 00:00:00 2001 From: OzHawk <OzHawk@users.noreply.github.com> Date: Mon, 16 May 2016 08:41:13 +0930 Subject: [PATCH 0048/2161] Update kernal.s --- libsrc/vic20/kernal.s | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libsrc/vic20/kernal.s b/libsrc/vic20/kernal.s index d9e7a9d03..040dbf5e5 100644 --- a/libsrc/vic20/kernal.s +++ b/libsrc/vic20/kernal.s @@ -47,9 +47,9 @@ ;----------------------------------------------------------------------------- ; All functions are available in the kernal jump table -CINT = $E518 ; No entries are in the kernal jump table for these functions. -IOINIT = $FDF9 ; The entries point directly to the function. -RAMTAS = $FD8D ; +CINT = $E518 ; No entries are in the kernal jump table of the Vic20 for these three (3) functions. +IOINIT = $FDF9 ; The entries for these functions have been set to point directly to the functions +RAMTAS = $FD8D ; in the kernal to maintain compatibility with the other Commodore platforms. RESTOR = $FF8A VECTOR = $FF8D SETMSG = $FF90 From ba10c74a7a2783fea88b24c41c5b8a84afe32570 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrycjusz=20R=2E=20=C5=81ogiewa?= <patrycjusz.logiewa@srebrnysen.com> Date: Mon, 16 May 2016 19:49:43 +0200 Subject: [PATCH 0049/2161] directory structure changed from driver-centric to target-centric --- libsrc/Makefile | 14 ++++++-------- libsrc/apple2/targetutil/Makefile.inc | 4 ++-- libsrc/atari/targetutil/Makefile.inc | 4 ++-- libsrc/geos-apple/targetutil/Makefile.inc | 4 ++-- libsrc/nes/Makefile.inc | 16 ++++++++-------- samples/Makefile | 20 ++++++++++++-------- 6 files changed, 32 insertions(+), 30 deletions(-) diff --git a/libsrc/Makefile b/libsrc/Makefile index ae65dc9b6..c4c1b78a7 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -1,3 +1,4 @@ + ifneq ($(shell echo),) CMD_EXE = 1 endif @@ -37,11 +38,8 @@ DRVTYPES = emd \ ser \ tgi -DRVOUTPUTDIRS := $(foreach drvtype,$(DRVTYPES),goodies/drivers/$(drvtype)) - OUTPUTDIRS := lib \ - $(DRVOUTPUTDIRS) \ - goodies/targetutil \ + target \ asminc \ cfg \ include \ @@ -82,8 +80,8 @@ mostlyclean: # Transitional line active. Final line commented out below in order to # allow some time for transition between the directory structures clean: - $(call RMDIR,../libwrk ../lib ../targetutil ../goodies $(addprefix ../,$(DRVTYPES))) -# $(call RMDIR,../libwrk ../lib ../goodies) + $(call RMDIR,../libwrk ../lib ../targetutil ../target $(addprefix ../,$(DRVTYPES))) +# $(call RMDIR,../libwrk ../lib ../target) ifdef CMD_EXE @@ -218,7 +216,7 @@ define DRVTYPE_template $1_SRCDIR = $$(SRCDIR)/$1 $1_STCDIR = ../libwrk/$$(TARGET) $1_DYNDIR = ../libwrk/$$(TARGET)/$1 -$1_DRVDIR = ../goodies/drivers/$1 +$1_DRVDIR = ../target/$$(TARGET)/drv/$1 $1_SRCPAT = $$($1_SRCDIR)/$$(OBJPFX)%.s $1_STCPAT = $$($1_STCDIR)/$$(OBJPFX)%-$1.o @@ -289,7 +287,7 @@ $(EXTRA_OBJPAT): $(EXTRA_SRCPAT) | ../lib ../lib/$(TARGET).lib: $(OBJS) | ../lib $(AR65) a $@ $? -../libwrk/$(TARGET) ../lib ../goodies/targetutil: +../libwrk/$(TARGET) ../lib ../target/$(TARGET)/util: @$(call MKDIR,$@) $(TARGET): $(EXTRA_OBJS) ../lib/$(TARGET).lib diff --git a/libsrc/apple2/targetutil/Makefile.inc b/libsrc/apple2/targetutil/Makefile.inc index 0b8b39e1f..d9d727b0a 100644 --- a/libsrc/apple2/targetutil/Makefile.inc +++ b/libsrc/apple2/targetutil/Makefile.inc @@ -3,7 +3,7 @@ DEPS += ../libwrk/$(TARGET)/loader.d ../libwrk/$(TARGET)/loader.o: $(SRCDIR)/targetutil/loader.s | ../libwrk/$(TARGET) $(ASSEMBLE_recipe) -../goodies/targetutil/loader.system: ../libwrk/$(TARGET)/loader.o $(SRCDIR)/targetutil/loader.cfg | ../goodies/targetutil +../target/$(TARGET)/util/loader.system: ../libwrk/$(TARGET)/loader.o $(SRCDIR)/targetutil/loader.cfg | ../target/$(TARGET)/util $(LD65) -o $@ -C $(filter %.cfg,$^) $(filter-out %.cfg,$^) -$(TARGET): ../goodies/targetutil/loader.system +$(TARGET): ../target/$(TARGET)/util/loader.system diff --git a/libsrc/atari/targetutil/Makefile.inc b/libsrc/atari/targetutil/Makefile.inc index 42903a3ca..e78585238 100644 --- a/libsrc/atari/targetutil/Makefile.inc +++ b/libsrc/atari/targetutil/Makefile.inc @@ -3,7 +3,7 @@ DEPS += ../libwrk/$(TARGET)/w2cas.d ../libwrk/$(TARGET)/w2cas.o: $(SRCDIR)/targetutil/w2cas.c | ../libwrk/$(TARGET) $(COMPILE_recipe) -../goodies/targetutil/w2cas.com: ../libwrk/$(TARGET)/w2cas.o ../lib/$(TARGET).lib | ../goodies/targetutil +../target/$(TARGET)/util/w2cas.com: ../libwrk/$(TARGET)/w2cas.o ../lib/$(TARGET).lib | ../target/$(TARGET)/util $(LD65) -o $@ -t $(TARGET) $^ -$(TARGET): ../goodies/targetutil/w2cas.com +$(TARGET): ../target/$(TARGET)/util/w2cas.com diff --git a/libsrc/geos-apple/targetutil/Makefile.inc b/libsrc/geos-apple/targetutil/Makefile.inc index d842b4d3f..3d366f913 100644 --- a/libsrc/geos-apple/targetutil/Makefile.inc +++ b/libsrc/geos-apple/targetutil/Makefile.inc @@ -8,7 +8,7 @@ DEPS += ../libwrk/$(TARGET)/convert.d ../lib/apple2enh.lib: @$(MAKE) --no-print-directory apple2enh -../goodies/targetutil/convert.system: ../libwrk/$(TARGET)/convert.o ../lib/apple2enh.lib | ../goodies/targetutil +../target/$(TARGET)/util/convert.system: ../libwrk/$(TARGET)/convert.o ../lib/apple2enh.lib | ../target/$(TARGET)/util $(LD65) -o $@ -C apple2enh-system.cfg $^ -$(TARGET): ../goodies/targetutil/convert.system +$(TARGET): ../target/$(TARGET)/util/convert.system diff --git a/libsrc/nes/Makefile.inc b/libsrc/nes/Makefile.inc index aaebef1db..6f2e7c7d2 100644 --- a/libsrc/nes/Makefile.inc +++ b/libsrc/nes/Makefile.inc @@ -1,8 +1,8 @@ -../goodies/drivers/tgi/nes-64-56-2.tgi: ../libwrk/nes/clrscr.o \ - ../libwrk/nes/cputc.o \ - ../libwrk/nes/get_tv.o \ - ../libwrk/nes/gotoxy.o \ - ../libwrk/nes/popa.o \ - ../libwrk/nes/ppu.o \ - ../libwrk/nes/ppubuf.o \ - ../libwrk/nes/setcursor.o +../target/nes/drv/tgi/nes-64-56-2.tgi: ../libwrk/nes/clrscr.o \ + ../libwrk/nes/cputc.o \ + ../libwrk/nes/get_tv.o \ + ../libwrk/nes/gotoxy.o \ + ../libwrk/nes/popa.o \ + ../libwrk/nes/ppu.o \ + ../libwrk/nes/ppubuf.o \ + ../libwrk/nes/setcursor.o diff --git a/samples/Makefile b/samples/Makefile index 951706ce6..0cef19798 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -12,15 +12,19 @@ SYS = c64 # source tree; otherwise, use the "install" directories. ifeq "$(wildcard ../src)" "" # No source tree -MOUS = /usr/lib/cc65/mou/$(SYS)*.mou -TGI = /usr/lib/cc65/tgi/$(SYS)*.tgi +MOUS = /usr/lib/cc65/target/$(SYS)/drv/mou/$(SYS)*.mou +TGI = /usr/lib/cc65/target/$(SYS)/drv/tgi/$(SYS)*.tgi ifneq "$(wildcard /usr/local/lib/cc65)" "" -MOUS = /usr/local/lib/cc65/mou/$(SYS)*.mou -TGI = /usr/local/lib/cc65/tgi/$(SYS)*.tgi +MOUS = /usr/local/lib/cc65/target/$(SYS)/drv/mou/$(SYS)*.mou +TGI = /usr/local/lib/cc65/target/$(SYS)/drv/tgi/$(SYS)*.tgi +endif +ifneq "$(wildcard /opt/local/share/cc65)" "" +MOUS = /opt/local/share/cc65/target/$(SYS)/drv/mou/$(SYS)*.mou +TGI = /opt/local/share/cc65/target/$(SYS)/drv/tgi/$(SYS)*.tgi endif ifdef CC65_HOME -MOUS = $(CC65_HOME)/mou/$(SYS)*.mou -TGI = $(CC65_HOME)/tgi/$(SYS)*.tgi +MOUS = $(CC65_HOME)/target/$(SYS)/drv/mou/$(SYS)*.mou +TGI = $(CC65_HOME)/target/$(SYS)/drv/tgi/$(SYS)*.tgi endif CLIB = --lib $(SYS).lib CL = cl65 @@ -31,8 +35,8 @@ LD = ld65 else # "samples/" is a part of a complete source tree. export CC65_HOME := $(abspath ..) -MOUS = ../mou/$(SYS)*.mou -TGI = ../tgi/$(SYS)*.tgi +MOUS = ../target/$(SYS)/drv/mou/$(SYS)*.mou +TGI = ../target/$(SYS)/drv/tgi/$(SYS)*.tgi CLIB = ../lib/$(SYS).lib CL = ../bin/cl65 CC = ../bin/cc65 From a5bff259bc241fc33763ce51f125d887b2221440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrycjusz=20R=2E=20=C5=81ogiewa?= <patrycjusz.logiewa@srebrnysen.com> Date: Mon, 16 May 2016 19:50:02 +0200 Subject: [PATCH 0050/2161] Ignores adjusted --- .gitignore | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 196cdc3d7..e1f69d072 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,8 @@ /bin/ -/emd/ /html/ /info/ -/joy/ /lib/ /libwrk/ -/mou/ -/ser/ -/targetutil/ +/target/ /testwrk/ -/tgi/ /wrk/ From 37f992909416defbb34454137ff89705fb4f40ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrycjusz=20R=2E=20=C5=81ogiewa?= <patrycjusz.logiewa@srebrnysen.com> Date: Mon, 16 May 2016 22:14:05 +0200 Subject: [PATCH 0051/2161] adapted for zip/install targets --- libsrc/Makefile | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libsrc/Makefile b/libsrc/Makefile index c4c1b78a7..54e0a7540 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -39,12 +39,13 @@ DRVTYPES = emd \ tgi OUTPUTDIRS := lib \ - target \ asminc \ cfg \ include \ samples \ - $(subst ../,,$(filter-out $(wildcard ../include/*.*),$(wildcard ../include/*))) + $(subst ../,,$(filter-out $(wildcard ../include/*.*),$(wildcard ../include/*)))\ + $(subst ../,,$(wildcard ../target/*/drv/*))\ + $(subst ../,,$(wildcard ../target/*/util))\ .PHONY: all mostlyclean clean install zip lib $(TARGETS) @@ -80,8 +81,8 @@ mostlyclean: # Transitional line active. Final line commented out below in order to # allow some time for transition between the directory structures clean: - $(call RMDIR,../libwrk ../lib ../targetutil ../target $(addprefix ../,$(DRVTYPES))) -# $(call RMDIR,../libwrk ../lib ../target) + $(call RMDIR,../libwrk ../lib ../targetutil ../$(TARGETDIR) $(addprefix ../,$(DRVTYPES))) +# $(call RMDIR,../libwrk ../lib ../$(TARGETDIR)) ifdef CMD_EXE @@ -95,13 +96,14 @@ define INSTALL_recipe $(if $(prefix),,$(error variable `prefix' must be set)) $(INSTALL) -d $(DESTDIR)$(datadir)/$(dir) -$(INSTALL) -m644 ../$(dir)/*.* $(DESTDIR)$(datadir)/$(dir) +$(INSTALL) -m0644 ../$(dir)/*.* $(DESTDIR)$(datadir)/$(dir) endef # INSTALL_recipe install: $(foreach dir,$(OUTPUTDIRS),$(INSTALL_recipe)) + endif # CMD_EXE define ZIP_recipe From 9c3f89fa1fb43336eb588aec7b8c367a788d9a84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrycjusz=20R=2E=20=C5=81ogiewa?= <patrycjusz.logiewa@srebrnysen.com> Date: Mon, 16 May 2016 22:34:43 +0200 Subject: [PATCH 0052/2161] ignoring zip target output --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e1f69d072..dac38c48b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ /target/ /testwrk/ /wrk/ +cc65.zip From cc747946b282b59d9e29ea1f5772172ac6ed7c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrycjusz=20R=2E=20=C5=81ogiewa?= <patrycjusz.logiewa@srebrnysen.com> Date: Mon, 16 May 2016 22:35:24 +0200 Subject: [PATCH 0053/2161] removed variable usage --- libsrc/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/Makefile b/libsrc/Makefile index 54e0a7540..3f6d2746c 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -81,8 +81,8 @@ mostlyclean: # Transitional line active. Final line commented out below in order to # allow some time for transition between the directory structures clean: - $(call RMDIR,../libwrk ../lib ../targetutil ../$(TARGETDIR) $(addprefix ../,$(DRVTYPES))) -# $(call RMDIR,../libwrk ../lib ../$(TARGETDIR)) + $(call RMDIR,../libwrk ../lib ../targetutil ../target $(addprefix ../,$(DRVTYPES))) +# $(call RMDIR,../libwrk ../lib ../target) ifdef CMD_EXE From 759f5f5f486170db50148ffae5b95caffa240c81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrycjusz=20R=2E=20=C5=81ogiewa?= <patrycjusz.logiewa@srebrnysen.com> Date: Wed, 18 May 2016 16:42:51 +0200 Subject: [PATCH 0054/2161] docs for targets with target utilities adjusted --- doc/apple2.sgml | 2 +- doc/apple2enh.sgml | 4 ++-- doc/atari.sgml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index b576ae6c1..00cd565b4 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -241,7 +241,7 @@ The easiest (and for really large programs in fact the only) way to have a cc65 program use the memory from $800 to $2000 is to link it as binary (as opposed to system) program using the default linker configuration <ref id="apple-def-cfg" name="apple2.cfg"> with <tt/__HIMEM__/ set to $BF00 -and load it with the targetutil LOADER.SYSTEM. The program then works like a system +and load it with the LOADER.SYSTEM utility. The program then works like a system program (i.e. quits to the ProDOS dispatcher). Using LOADER.SYSTEM is as simple as copying it to the ProDOS 8 directory of the diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 6ee525114..7c17c24f2 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -241,7 +241,7 @@ The easiest (and for really large programs in fact the only) way to have a cc65 program use the memory from $800 to $2000 is to link it as binary (as opposed to system) program using the default linker configuration <ref id="apple-def-cfg" name="apple2enh.cfg"> with <tt/__HIMEM__/set to $BF00 -and load it with the targetutil LOADER.SYSTEM. The program then works like a system +and load it with the LOADER.SYSTEM utility. The program then works like a system program (i.e. quits to the ProDOS dispatcher). Using LOADER.SYSTEM is as simple as copying it to the ProDOS 8 directory of the @@ -277,7 +277,7 @@ default I/O buffer allocation basically yields the same placement of I/O buffers in memory the primary benefit of <tt/apple2enh-iobuf-0800.o/ is a reduction in code size - and thus program file size - of more than 1400 bytes. -Using <tt/apple2enh-iobuf-0800.o/ is as simple as placing it on the linker command +Using <tt/apple2enh-iobuf-0800.o/ is as simple as placing it on the linker command line like this: <tscreen><verb> diff --git a/doc/atari.sgml b/doc/atari.sgml index 2087a8541..cfa1937e0 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -229,8 +229,8 @@ for C and assembly language programs. The size of a cassette boot file is restricted to 32K. Larger programs would need to be split in more parts and the parts to be loaded manually. -To write the generated file to a cassette, a utility to run -on an Atari is provided in the <tt/targetutil/ directory (<tt/w2cas.com/). +To write the generated file to a cassette, a utility (<tt/w2cas.com/) to run +on an Atari is provided in the <tt/util/ directory of <tt/atari/ target dir. <sect1><tt/atarixl/ config files<p> From 03cb0bd2fd010fdba9a653dfd4515e5d3570f0a9 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 24 May 2016 00:10:47 +0200 Subject: [PATCH 0055/2161] atari.inc: add XDOS defines and remove trailing whitespace --- asminc/atari.inc | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/asminc/atari.inc b/asminc/atari.inc index 3cce03046..e6d165524 100644 --- a/asminc/atari.inc +++ b/asminc/atari.inc @@ -106,7 +106,7 @@ SIO_WRPERCOM = $4F ;write PERCOM block (XF551) SIO_WRITE = $50 ;write sector SIO_READ = $52 ;read sector SIO_STAT = $53 ;get status information -SIO_VERIFY = $56 ;verify sector +SIO_VERIFY = $56 ;verify sector SIO_WRITEV = $57 ;write sector with verify SIO_WRITETRK = $60 ;write track (Speedy) SIO_READTRK = $62 ;read track (Speedy) @@ -689,7 +689,7 @@ CASFLG = $030F ;CASSETTE MODE WHEN SET TIMER2 = $0310 ;2-byte final baud rate timer value TEMP1 = $0312 ;TEMPORARY STORAGE REGISTER ;TEMP2 = $0314 ;##old## TEMPORARY STORAGE REGISTER -TEMP2 = $0313 ;##1200xl## 1-byte temporary +TEMP2 = $0313 ;##1200xl## 1-byte temporary PTIMOT = $0314 ;##1200xl## 1-byte printer timeout TEMP3 = $0315 ;TEMPORARY STORAGE REGISTER SAVIO = $0316 ;SAVE SERIAL IN DATA PORT @@ -765,7 +765,7 @@ CART = $BFFC ;##rev2## 1-byte cartridge present indicator ;0=Cart Exists CARTFG = $BFFD ;##rev2## 1-byte cartridge flags ;D7 0=Not a Diagnostic Cart - ; 1=Is a Diagnostic cart and control is + ; 1=Is a Diagnostic cart and control is ; given to cart before any OS is init. ;D2 0=Init but Do not Start Cart ; 1=Init and Start Cart @@ -925,7 +925,7 @@ RADON = 0 ;INDICATES RADIANS DEGON = 6 ;INDICATES DEGREES ASCZER = '0' ;ASCII ZERO -COLON = $3A ;ASCII COLON +COLON = $3A ;ASCII COLON CR = $9B ;SYSTEM EOL (CARRIAGE RETURN) ;------------------------------------------------------------------------- @@ -1004,6 +1004,21 @@ MYDOS = 3 XDOS = 4 NODOS = 255 +;------------------------------------------------------------------------- +; XDOS defines (version 2.4, taken from xdos24.pdf) +;------------------------------------------------------------------------- + +XOPT = $70B ; XDOS options +XCAR = $70C ; XDOS cartridge address (+ $70D) +XPAT = $86F ; XDOS bugfix and patch number +XVER = $870 ; XDOS version number +XFILE = $87D ; XDOS filename buffer +XLINE = $880 ; XDOS DUP input line +XGLIN = $871 ; get line +XSKIP = $874 ; skip parameter +XMOVE = $877 ; move filename +XGNUM = $87A ; get number + ;------------------------------------------------------------------------- ; End of atari.inc ;------------------------------------------------------------------------- From 6d7dfad80b8d17f7342cdcc38d90441b5c0b22ff Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 24 May 2016 02:57:21 +0200 Subject: [PATCH 0056/2161] add support for XDOS command lines --- asminc/atari.inc | 13 ++++++++----- libsrc/atari/dosdetect.s | 2 +- libsrc/atari/getargs.s | 30 ++++++++++++++++++++---------- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/asminc/atari.inc b/asminc/atari.inc index e6d165524..183564f1f 100644 --- a/asminc/atari.inc +++ b/asminc/atari.inc @@ -997,12 +997,15 @@ diopp_size = 5 ; size of structure ; VALUES for dos_type ;------------------------------------------------------------------------- -ATARIDOS = 0 -SPARTADOS = 1 -OSADOS = 2 ; OS/A+ -MYDOS = 3 -XDOS = 4 +SPARTADOS = 0 +OSADOS = 1 ; OS/A+ +XDOS = 2 +ATARIDOS = 3 +MYDOS = 4 NODOS = 255 +; The DOSes with dos_type below or equal MAX_DOS_WITH_CMDLINE do support +; command line arguments. +MAX_DOS_WITH_CMDLINE = XDOS ;------------------------------------------------------------------------- ; XDOS defines (version 2.4, taken from xdos24.pdf) diff --git a/libsrc/atari/dosdetect.s b/libsrc/atari/dosdetect.s index c2888d888..68f4aefb2 100644 --- a/libsrc/atari/dosdetect.s +++ b/libsrc/atari/dosdetect.s @@ -50,4 +50,4 @@ done: rts .data -__dos_type: .byte 0 ; default to ATARIDOS +__dos_type: .byte ATARIDOS; default to ATARIDOS diff --git a/libsrc/atari/getargs.s b/libsrc/atari/getargs.s index e3b18b2f9..b1b5d258d 100644 --- a/libsrc/atari/getargs.s +++ b/libsrc/atari/getargs.s @@ -7,6 +7,8 @@ ; startup code but is nevertheless included in the compiled program when ; needed. +; XDOS support added 05/2016 by Christian Groessler + MAXARGS = 16 ; max. amount of arguments in arg. table CL_SIZE = 64 ; command line buffer size SPACE = 32 ; SPACE char. @@ -22,22 +24,30 @@ SPACE = 32 ; SPACE char. .segment "ONCE" +nargdos:rts + initmainargs: lda __dos_type ; which DOS? - cmp #ATARIDOS - beq nargdos ; DOS does not support arguments - cmp #MYDOS - bne argdos ; DOS supports arguments -nargdos:rts + cmp #MAX_DOS_WITH_CMDLINE + 1 + bcs nargdos ; Initialize ourcl buffer -argdos: lda #ATEOL - sta ourcl+CL_SIZE +argdos: ldy #ATEOL + sty ourcl+CL_SIZE -; Move SpartaDOS command line to our own buffer +; Move SpartaDOS/XDOS command line to our own buffer - lda DOSVEC + cmp #XDOS + bne sparta + + lda #<XLINE + sta ptr1 + lda #>XLINE + sta ptr1+1 + bne cpcl0 + +sparta: lda DOSVEC clc adc #<LBUF sta ptr1 @@ -45,7 +55,7 @@ argdos: lda #ATEOL adc #>LBUF sta ptr1+1 - ldy #0 +cpcl0: ldy #0 cpcl: lda (ptr1),y sta ourcl,y iny From 2dd8f9f5efdda6824c2eb95e74091be3bf0ff968 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 24 May 2016 04:37:35 +0200 Subject: [PATCH 0057/2161] atari.h: update _dos_type values --- include/atari.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/atari.h b/include/atari.h index 82cd07330..5e36b1daa 100644 --- a/include/atari.h +++ b/include/atari.h @@ -261,11 +261,11 @@ extern void atrx15p2_tgi[]; #define AT_PAL 1 /* valid _dos_type values */ -#define ATARIDOS 0 -#define SPARTADOS 1 -#define OSADOS 2 -#define MYDOS 3 -#define XDOS 4 +#define SPARTADOS 0 +#define OSADOS 1 +#define XDOS 2 +#define ATARIDOS 3 +#define MYDOS 4 #define NODOS 255 /* Define hardware */ From 2abbd9449262a3b41e450234085fb79f1fad34a9 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 24 May 2016 15:47:34 +0200 Subject: [PATCH 0058/2161] Fix style issue. --- asminc/atari.inc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/asminc/atari.inc b/asminc/atari.inc index 183564f1f..b8f883cd8 100644 --- a/asminc/atari.inc +++ b/asminc/atari.inc @@ -1011,16 +1011,16 @@ MAX_DOS_WITH_CMDLINE = XDOS ; XDOS defines (version 2.4, taken from xdos24.pdf) ;------------------------------------------------------------------------- -XOPT = $70B ; XDOS options -XCAR = $70C ; XDOS cartridge address (+ $70D) -XPAT = $86F ; XDOS bugfix and patch number -XVER = $870 ; XDOS version number -XFILE = $87D ; XDOS filename buffer -XLINE = $880 ; XDOS DUP input line -XGLIN = $871 ; get line -XSKIP = $874 ; skip parameter -XMOVE = $877 ; move filename -XGNUM = $87A ; get number +XOPT = $070B ; XDOS options +XCAR = $070C ; XDOS cartridge address (+ $70D) +XPAT = $086F ; XDOS bugfix and patch number +XVER = $0870 ; XDOS version number +XFILE = $087D ; XDOS filename buffer +XLINE = $0880 ; XDOS DUP input line +XGLIN = $0871 ; get line +XSKIP = $0874 ; skip parameter +XMOVE = $0877 ; move filename +XGNUM = $087A ; get number ;------------------------------------------------------------------------- ; End of atari.inc From 8d5717b57add7bf67c7d7a18a5c67e87b9faacbc Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 24 May 2016 15:52:12 -0400 Subject: [PATCH 0059/2161] Small optimization of some cc65-generated loops. "bne" means also branch-on-not-zero. Therefore, this optimization doesn't put a compare-to-zero between an increment and a "bne". --- src/cc65/codegen.c | 7 ++++--- src/cc65/stdfunc.c | 33 ++++++++++++++++++++++----------- src/cc65/stdfunc.h | 7 ++++++- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index f6ec2f51a..bf0251813 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -55,6 +55,7 @@ #include "global.h" #include "segments.h" #include "stackptr.h" +#include "stdfunc.h" #include "textseg.h" #include "util.h" #include "codegen.h" @@ -4241,7 +4242,7 @@ void g_initauto (unsigned Label, unsigned Size) AddCodeLine ("lda %s,y", GetLabelName (CF_STATIC, Label, 0)); AddCodeLine ("sta (sp),y"); AddCodeLine ("iny"); - AddCodeLine ("cpy #$%02X", (unsigned char) Size); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Size); AddCodeLine ("bne %s", LocalLabelName (CodeLabel)); } } @@ -4266,10 +4267,10 @@ void g_initstatic (unsigned InitLabel, unsigned VarLabel, unsigned Size) AddCodeLine ("lda %s,y", GetLabelName (CF_STATIC, InitLabel, 0)); AddCodeLine ("sta %s,y", GetLabelName (CF_STATIC, VarLabel, 0)); AddCodeLine ("iny"); - AddCodeLine ("cpy #$%02X", (unsigned char) Size); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Size); AddCodeLine ("bne %s", LocalLabelName (CodeLabel)); } else { - /* Use the easy way here: memcpy */ + /* Use the easy way here: memcpy() */ g_getimmed (CF_STATIC, VarLabel, 0); AddCodeLine ("jsr pushax"); g_getimmed (CF_STATIC, InitLabel, 0); diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 182cad1ef..720e6db15 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -185,6 +185,19 @@ static void ParseArg (ArgDesc* Arg, Type* Type) +void AddCmpCodeIfSizeNot256 (const char* Code, long Size) +/* Add a line of Assembly code that compares an index register +** only if it isn't comparing to #<256. (If the next line +** is "bne", then this will avoid a redundant line.) +*/ +{ + if (Size != 256) { + AddCodeLine (Code, (unsigned int)Size); + } +} + + + /*****************************************************************************/ /* memcpy */ /*****************************************************************************/ @@ -272,7 +285,6 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) if (Arg3.Expr.IVal <= 127) { AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal-1)); - AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal); g_defcodelabel (Label); if (Reg2) { AddCodeLine ("lda (%s),y", ED_GetLabelName (&Arg2.Expr, 0)); @@ -290,7 +302,6 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) } else { AddCodeLine ("ldy #$00"); - AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal); g_defcodelabel (Label); if (Reg2) { AddCodeLine ("lda (%s),y", ED_GetLabelName (&Arg2.Expr, 0)); @@ -303,7 +314,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0)); } AddCodeLine ("iny"); - AddCodeLine ("cpy #$%02X", (unsigned char) Arg3.Expr.IVal); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal); AddCodeLine ("bne %s", LocalLabelName (Label)); } @@ -366,7 +377,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs)); AddCodeLine ("sta (sp),y"); AddCodeLine ("iny"); - AddCodeLine ("cpy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal)); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); AddCodeLine ("bne %s", LocalLabelName (Label)); } else { AddCodeLine ("ldx #$00"); @@ -376,7 +387,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("sta (sp),y"); AddCodeLine ("iny"); AddCodeLine ("inx"); - AddCodeLine ("cpx #$%02X", (unsigned char) Arg3.Expr.IVal); + AddCmpCodeIfSizeNot256 ("cpx #$%02X", Arg3.Expr.IVal); AddCodeLine ("bne %s", LocalLabelName (Label)); } @@ -440,7 +451,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("lda (sp),y"); AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, -Offs)); AddCodeLine ("iny"); - AddCodeLine ("cpy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal)); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); AddCodeLine ("bne %s", LocalLabelName (Label)); } else { AddCodeLine ("ldx #$00"); @@ -450,7 +461,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0)); AddCodeLine ("iny"); AddCodeLine ("inx"); - AddCodeLine ("cpx #$%02X", (unsigned char) Arg3.Expr.IVal); + AddCmpCodeIfSizeNot256 ("cpx #$%02X", Arg3.Expr.IVal); AddCodeLine ("bne %s", LocalLabelName (Label)); } @@ -487,7 +498,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("lda (sp),y"); AddCodeLine ("sta (ptr1),y"); AddCodeLine ("iny"); - AddCodeLine ("cpy #$%02X", (unsigned char) Arg3.Expr.IVal); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal); AddCodeLine ("bne %s", LocalLabelName (Label)); } @@ -631,7 +642,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0)); } AddCodeLine ("iny"); - AddCodeLine ("cpy #$%02X", (unsigned char) Arg3.Expr.IVal); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal); AddCodeLine ("bne %s", LocalLabelName (Label)); } @@ -661,7 +672,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) g_defcodelabel (Label); AddCodeLine ("sta (sp),y"); AddCodeLine ("iny"); - AddCodeLine ("cpy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal)); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); AddCodeLine ("bne %s", LocalLabelName (Label)); /* memset returns the address, so the result is actually identical @@ -697,7 +708,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) g_defcodelabel (Label); AddCodeLine ("sta (ptr1),y"); AddCodeLine ("iny"); - AddCodeLine ("cpy #$%02X", (unsigned char) Arg3.Expr.IVal); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal); AddCodeLine ("bne %s", LocalLabelName (Label)); } diff --git a/src/cc65/stdfunc.h b/src/cc65/stdfunc.h index 7fc3abd3e..e944d70b9 100644 --- a/src/cc65/stdfunc.h +++ b/src/cc65/stdfunc.h @@ -50,6 +50,12 @@ +void AddCmpCodeIfSizeNot256 (const char* Code, long Size); +/* Add a line of Assembly code that compares an index register +** only if it isn't comparing to #<256. (If the next line +** is "bne", then this will avoid a redundant line.) +*/ + int FindStdFunc (const char* Name); /* Determine if the given function is a known standard function that may be ** called in a special way. If so, return the index, otherwise return -1. @@ -61,5 +67,4 @@ void HandleStdFunc (int Index, struct FuncDesc* F, ExprDesc* lval); /* End of stdfunc.h */ - #endif From da65866e24efd7698e7b5675ebc926b358bd7122 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 25 May 2016 00:51:40 +0200 Subject: [PATCH 0060/2161] Atari: add new function '_is_cmdline_dos()' and some other small changes. - use this function instead of directly looking at _dos_type in the included targetutil and test programs - fixes/improvements to the Atari runtime library regarding the recently changed _dos_type values - libsrc/atari/targetutil/w2cas.c: exit if no filename was entered - add documentation for the new function --- doc/atari.sgml | 1 + doc/funcref.sgml | 35 +++++++++++++++++++++++++++++++++ include/atari.h | 11 ++++++----- libsrc/atari/getdefdev.s | 7 +++---- libsrc/atari/sysrmdir.s | 5 +++-- libsrc/atari/targetutil/w2cas.c | 28 +++++++++++++++++--------- testcode/lib/atari/defdev.c | 2 +- testcode/lib/atari/mem.c | 3 +-- 8 files changed, 69 insertions(+), 23 deletions(-) diff --git a/doc/atari.sgml b/doc/atari.sgml index 2087a8541..f911d568e 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -275,6 +275,7 @@ See the <url url="funcref.html" name="function reference"> for declaration and u <item>_getcolor <item>_getdefdev <item>_graphics +<item>_is_cmdline_dos <item>_rest_vecs <item>_save_vecs <item>_scroll diff --git a/doc/funcref.sgml b/doc/funcref.sgml index a2ccf6c73..9bd4a3595 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -98,6 +98,7 @@ function. <!-- <item><ref id="_getcolor" name="_getcolor"> --> <!-- <item><ref id="_getdefdev" name="_getdefdev"> --> <!-- <item><ref id="_graphics" name="_graphics"> --> +<item><ref id="_is_cmdline_dos" name="_is_cmdline_dos"> <!-- <item><ref id="_rest_vecs" name="_rest_vecs"> --> <!-- <item><ref id="_save_vecs" name="_save_vecs"> --> <!-- <item><ref id="_scroll" name="_scroll"> --> @@ -939,6 +940,40 @@ id="malloc" name="malloc"> may still return <tt/NULL/. </quote> +<sect1>_is_cmdline_dos<label id="_is_cmdline_dos"><p> + +<quote> +<descrip> +<tag/Function/Determines whether the underlying DOS supports command line arguments. +<tag/Header/<tt/<ref id="atari.h" name="atari.h">/ +<tag/Declaration/<tt/unsigned char _is_cmdline_dos (void);/ +<tag/Description/The function returns 0 if the DOS doesn't support command line arguments. +It returns 1 if it does. +<tag/Notes/<itemize> +<item>Many Atari DOSes which don't support command line arguments immediately clear the screen +and display their menu after a program exits. Therefore it might be difficult to read +the last messages printed by the program prior to its exit. This function can be used +to decide if a delay or wait for a key press should be executed when then program +exits. +</itemize> +<tag/Availability/cc65 (<tt/atari/ and <tt/atarixl/ platforms) +<tag/Example/<verb> +/* Hello World for Atari */ +#include <stdio.h> +#include <unistd.h> +#include <atari.h> +int main(void) +{ + printf("Hello World\n"); + if (! _is_cmdline_dos()) + sleep(5); + return 0; +} +</verb> +</descrip> +</quote> + + <sect1>_poserror<label id="_poserror"><p> <quote> diff --git a/include/atari.h b/include/atari.h index 5e36b1daa..fa99fca20 100644 --- a/include/atari.h +++ b/include/atari.h @@ -161,11 +161,12 @@ extern void __fastcall__ _scroll (signed char numlines); /* numlines < 0 scrolls down */ /* 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 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 */ /* global variables */ extern unsigned char _dos_type; /* the DOS flavour */ diff --git a/libsrc/atari/getdefdev.s b/libsrc/atari/getdefdev.s index 47d8714e6..280c042e5 100644 --- a/libsrc/atari/getdefdev.s +++ b/libsrc/atari/getdefdev.s @@ -27,10 +27,9 @@ __getdefdev: lda __dos_type ; which DOS? - cmp #ATARIDOS - beq finish - cmp #MYDOS - beq finish + cmp #OSADOS+1 + bcs finish ; only supported on OS/A+ and SpartaDOS + ; (TODO: add XDOS support) ldy #BUFOFF lda #0 diff --git a/libsrc/atari/sysrmdir.s b/libsrc/atari/sysrmdir.s index 3f5b9e447..f568ded6e 100644 --- a/libsrc/atari/sysrmdir.s +++ b/libsrc/atari/sysrmdir.s @@ -26,11 +26,12 @@ pha lda __dos_type - beq not_impl ; AtariDOS cmp #OSADOS+1 bcc do_sparta ; OS/A and SpartaDOS + cmp #MYDOS + bne not_impl ; neither MyDOS, OS/A, nor SpartaDOS pla - jmp __sysremove ; MyDOS and others (TODO: check XDOS) + jmp __sysremove ; MyDOS not_impl: pla diff --git a/libsrc/atari/targetutil/w2cas.c b/libsrc/atari/targetutil/w2cas.c index 4d574da07..453785140 100644 --- a/libsrc/atari/targetutil/w2cas.c +++ b/libsrc/atari/targetutil/w2cas.c @@ -45,7 +45,7 @@ int main(int argc, char **argv) if (! iocb) { fprintf(stderr, "couldn't find a free iocb\n"); - if (_dos_type != 1) + if (! _is_cmdline_dos()) cgetc(); return 1; } @@ -57,10 +57,20 @@ int main(int argc, char **argv) printf("\nfilename: "); x = fgets(buf, 19, stdin); printf("\n"); - if (! x) + if (! x) { + printf("empty filename, exiting...\n"); + if (! _is_cmdline_dos()) + cgetc(); return 1; + } if (*x && *(x + strlen(x) - 1) == '\n') *(x + strlen(x) - 1) = 0; + if (! strlen(x)) { /* empty filename */ + printf("empty filename, exiting...\n"); + if (! _is_cmdline_dos()) + cgetc(); + return 1; + } filename = x; } else { @@ -74,7 +84,7 @@ int main(int argc, char **argv) buffer = malloc(buflen); if (! buffer) { fprintf(stderr, "cannot alloc %ld bytes -- aborting...\n", (long)buflen); - if (_dos_type != 1) + if (! _is_cmdline_dos()) cgetc(); return 1; } @@ -87,7 +97,7 @@ int main(int argc, char **argv) if (! file) { free(buffer); fprintf(stderr, "cannot open '%s': %s\n", filename, strerror(errno)); - if (_dos_type != 1) + if (! _is_cmdline_dos()) cgetc(); return 1; } @@ -101,7 +111,7 @@ int main(int argc, char **argv) file_err: fclose(file); free(buffer); - if (_dos_type != 1) + if (! _is_cmdline_dos()) cgetc(); return 1; } @@ -133,7 +143,7 @@ int main(int argc, char **argv) if (regs.y != 1) { fprintf(stderr, "CIO call to open cassette returned %d\n", regs.y); free(buffer); - if (_dos_type != 1) + if (! _is_cmdline_dos()) cgetc(); return 1; } @@ -157,7 +167,7 @@ int main(int argc, char **argv) regs.pc = 0xe456; /* CIOV */ _sys(®s); - if (_dos_type != 1) + if (! _is_cmdline_dos()) cgetc(); return 1; } @@ -173,14 +183,14 @@ int main(int argc, char **argv) if (regs.y != 1) { fprintf(stderr, "CIO call to close cassette returned %d\n", regs.y); - if (_dos_type != 1) + if (! _is_cmdline_dos()) cgetc(); return 1; } /* all is fine */ printf("success\n"); - if (_dos_type != 1) + if (! _is_cmdline_dos()) cgetc(); return 0; } diff --git a/testcode/lib/atari/defdev.c b/testcode/lib/atari/defdev.c index f679985ec..06ddb6365 100644 --- a/testcode/lib/atari/defdev.c +++ b/testcode/lib/atari/defdev.c @@ -13,6 +13,6 @@ extern char _defdev[]; int main(void) { printf("default device: %s\n", _defdev); - if (_dos_type != SPARTADOS && _dos_type != OSADOS) cgetc(); + if (! _is_cmdline_dos()) cgetc(); return 0; } diff --git a/testcode/lib/atari/mem.c b/testcode/lib/atari/mem.c index 36222e08b..a8d50cf30 100644 --- a/testcode/lib/atari/mem.c +++ b/testcode/lib/atari/mem.c @@ -11,7 +11,6 @@ extern int getsp(void); /* comes from ../getsp.s */ -extern char _dos_type; /* bss variable */ unsigned char data = 0x12; /* data variable */ unsigned int *APPMHI = (unsigned int *)14; /* 14,15 */ @@ -42,6 +41,6 @@ int main(void) printf(" sp: $%04X (stack ptr)\n", getsp()); if (allocmem) free(allocmem); - if (_dos_type != 1) cgetc(); + if (! _is_cmdline_dos()) cgetc(); return(0); } From b3d7c09ba186326c5d539a65c531a06dea566c81 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 25 May 2016 01:06:53 +0200 Subject: [PATCH 0061/2161] forgot to add the new file atari/is_cmdline_dos.s in my last commit... --- libsrc/atari/is_cmdline_dos.s | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 libsrc/atari/is_cmdline_dos.s diff --git a/libsrc/atari/is_cmdline_dos.s b/libsrc/atari/is_cmdline_dos.s new file mode 100644 index 000000000..71b35fbad --- /dev/null +++ b/libsrc/atari/is_cmdline_dos.s @@ -0,0 +1,20 @@ +; +; Christian Groessler, May-2016 +; +; unsigned char _is_cmdline_dos(void); +; +; returns 0 for non-commandline DOS, 1 for commandline DOS +; + + .export __is_cmdline_dos + .import __dos_type + .include "atari.inc" + +__is_cmdline_dos: + ldx #0 + lda __dos_type + cmp #MAX_DOS_WITH_CMDLINE + 1 + txa + rol a + eor #$01 + rts From e2d14291b74e3cbbbc584c9d24f95860bf65313d Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 25 May 2016 01:29:00 +0200 Subject: [PATCH 0062/2161] make BSS segment optional in atari-cassette.cfg --- cfg/atari-cassette.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/atari-cassette.cfg b/cfg/atari-cassette.cfg index 84bb5ad02..5e99c303e 100644 --- a/cfg/atari-cassette.cfg +++ b/cfg/atari-cassette.cfg @@ -21,7 +21,7 @@ SEGMENTS { CODE: load = MAIN, type = ro, define = yes; RODATA: load = MAIN, type = ro, optional = yes; DATA: load = MAIN, type = rw, optional = yes; - BSS: load = MAIN, type = bss, define = yes; + BSS: load = MAIN, type = bss, define = yes, optional = yes; INIT: load = MAIN, type = bss, optional = yes; } FEATURES { From 8951e74ba7563589bf19102881ba8428ddaf55e0 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <curaga@operamail.com> Date: Fri, 27 May 2016 20:03:58 +0300 Subject: [PATCH 0063/2161] ld65: Be more verbose in token errors --- src/ld65/scanner.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ld65/scanner.c b/src/ld65/scanner.c index 0f6ea58de..3c2346aac 100644 --- a/src/ld65/scanner.c +++ b/src/ld65/scanner.c @@ -505,7 +505,7 @@ void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name) } /* Not found or no identifier */ - CfgError (&CfgErrorPos, "%s expected", Name); + CfgError (&CfgErrorPos, "%s expected, got '%s'", Name, SB_GetConstBuf(&CfgSVal)); } From ac5bb6707d9ccfd2f586a0de7c2bb108e5811dd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrycjusz=20R=2E=20=C5=81ogiewa?= <patrycjusz.logiewa@srebrnysen.com> Date: Sun, 29 May 2016 16:19:03 +0200 Subject: [PATCH 0064/2161] Post-review changes --- doc/Makefile | 4 ++-- libsrc/Makefile | 6 +----- libsrc/nes/Makefile.inc | 14 +++++++------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/doc/Makefile b/doc/Makefile index 8b0b316b0..862164e1b 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -33,11 +33,11 @@ install: $(if $(prefix),,$(error variable `prefix' must be set)) ifeq ($(wildcard ../html),../html) $(INSTALL) -d $(DESTDIR)$(htmldir) - $(INSTALL) -m644 ../html/*.* $(DESTDIR)$(htmldir) + $(INSTALL) -m0644 ../html/*.* $(DESTDIR)$(htmldir) endif ifeq ($(wildcard ../info),../info) $(INSTALL) -d $(DESTDIR)$(infodir) - $(INSTALL) -m644 ../info/*.* $(DESTDIR)$(infodir) + $(INSTALL) -m0644 ../info/*.* $(DESTDIR)$(infodir) endif zip: diff --git a/libsrc/Makefile b/libsrc/Makefile index 3f6d2746c..549a7d4e9 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -78,11 +78,8 @@ all lib: $(TARGETS) mostlyclean: $(call RMDIR,../libwrk) -# Transitional line active. Final line commented out below in order to -# allow some time for transition between the directory structures clean: - $(call RMDIR,../libwrk ../lib ../targetutil ../target $(addprefix ../,$(DRVTYPES))) -# $(call RMDIR,../libwrk ../lib ../target) + $(call RMDIR,../libwrk ../lib ../target) ifdef CMD_EXE @@ -103,7 +100,6 @@ endef # INSTALL_recipe install: $(foreach dir,$(OUTPUTDIRS),$(INSTALL_recipe)) - endif # CMD_EXE define ZIP_recipe diff --git a/libsrc/nes/Makefile.inc b/libsrc/nes/Makefile.inc index 6f2e7c7d2..e23605781 100644 --- a/libsrc/nes/Makefile.inc +++ b/libsrc/nes/Makefile.inc @@ -1,8 +1,8 @@ ../target/nes/drv/tgi/nes-64-56-2.tgi: ../libwrk/nes/clrscr.o \ - ../libwrk/nes/cputc.o \ - ../libwrk/nes/get_tv.o \ - ../libwrk/nes/gotoxy.o \ - ../libwrk/nes/popa.o \ - ../libwrk/nes/ppu.o \ - ../libwrk/nes/ppubuf.o \ - ../libwrk/nes/setcursor.o + ../libwrk/nes/cputc.o \ + ../libwrk/nes/get_tv.o \ + ../libwrk/nes/gotoxy.o \ + ../libwrk/nes/popa.o \ + ../libwrk/nes/ppu.o \ + ../libwrk/nes/ppubuf.o \ + ../libwrk/nes/setcursor.o From e36a636eee796466242874507fa3712b504f08ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrycjusz=20R=2E=20=C5=81ogiewa?= <patrycjusz.logiewa@srebrnysen.com> Date: Sun, 29 May 2016 16:34:22 +0200 Subject: [PATCH 0065/2161] Indenting optimised --- libsrc/nes/Makefile.inc | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/libsrc/nes/Makefile.inc b/libsrc/nes/Makefile.inc index e23605781..ee43b4ff8 100644 --- a/libsrc/nes/Makefile.inc +++ b/libsrc/nes/Makefile.inc @@ -1,8 +1,9 @@ -../target/nes/drv/tgi/nes-64-56-2.tgi: ../libwrk/nes/clrscr.o \ - ../libwrk/nes/cputc.o \ - ../libwrk/nes/get_tv.o \ - ../libwrk/nes/gotoxy.o \ - ../libwrk/nes/popa.o \ - ../libwrk/nes/ppu.o \ - ../libwrk/nes/ppubuf.o \ - ../libwrk/nes/setcursor.o +../target/nes/drv/tgi/nes-64-56-2.tgi: \ + ../libwrk/nes/clrscr.o \ + ../libwrk/nes/cputc.o \ + ../libwrk/nes/get_tv.o \ + ../libwrk/nes/gotoxy.o \ + ../libwrk/nes/popa.o \ + ../libwrk/nes/ppu.o \ + ../libwrk/nes/ppubuf.o \ + ../libwrk/nes/setcursor.o From a6c306500a79120fb8398b6512bcf46065fc1c42 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Mon, 30 May 2016 14:16:37 +0200 Subject: [PATCH 0066/2161] Small optimization in apple2 exec.s. --- libsrc/apple2/exec.s | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libsrc/apple2/exec.s b/libsrc/apple2/exec.s index d24de604c..429afef54 100644 --- a/libsrc/apple2/exec.s +++ b/libsrc/apple2/exec.s @@ -233,11 +233,10 @@ source: jsr $BF00 system: lda $2000 cmp #$4C bne jump - lda $2003 - cmp #$EE + lda #$EE + cmp $2003 bne jump - lda $2004 - cmp #$EE + cmp $2004 bne jump ; Store cmdline in startup filename buffer From b979fb5763d44917b00d35a56bcb335ef58d5100 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 30 May 2016 14:31:53 +0200 Subject: [PATCH 0067/2161] Minor adjustment to recent change. --- libsrc/apple2/exec.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/apple2/exec.s b/libsrc/apple2/exec.s index 429afef54..c0cd98650 100644 --- a/libsrc/apple2/exec.s +++ b/libsrc/apple2/exec.s @@ -230,8 +230,8 @@ source: jsr $BF00 ; Check for startup filename support ; ProDOS TechRefMan, chapter 5.1.5.1: ; "$2000 is a jump instruction. $2003 and $2004 are $EE." -system: lda $2000 - cmp #$4C +system: lda #$4C + cmp $2000 bne jump lda #$EE cmp $2003 From 4dcfc036c8d29a9c57f3181931448027aeea0ce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrycjusz=20R=2E=20=C5=81ogiewa?= <patrycjusz.logiewa@srebrnysen.com> Date: Mon, 30 May 2016 17:42:01 +0200 Subject: [PATCH 0068/2161] samples zip and install targets moved into samples/Makefile as agreed --- Makefile | 17 +++++++++-------- libsrc/Makefile | 1 - samples/Makefile | 49 ++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index e0530e9f0..a10df8db0 100644 --- a/Makefile +++ b/Makefile @@ -3,21 +3,22 @@ .SUFFIXES: all mostlyclean clean install zip: - @$(MAKE) -C src --no-print-directory $@ - @$(MAKE) -C libsrc --no-print-directory $@ - @$(MAKE) -C doc --no-print-directory $@ + @$(MAKE) -C src --no-print-directory $@ + @$(MAKE) -C libsrc --no-print-directory $@ + @$(MAKE) -C doc --no-print-directory $@ + @$(MAKE) -C samples --no-print-directory $@ avail unavail bin: - @$(MAKE) -C src --no-print-directory $@ + @$(MAKE) -C src --no-print-directory $@ lib: - @$(MAKE) -C libsrc --no-print-directory $@ + @$(MAKE) -C libsrc --no-print-directory $@ doc: - @$(MAKE) -C doc --no-print-directory $@ + @$(MAKE) -C doc --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 $@ diff --git a/libsrc/Makefile b/libsrc/Makefile index 549a7d4e9..99f120f3a 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -42,7 +42,6 @@ OUTPUTDIRS := lib \ asminc \ cfg \ include \ - samples \ $(subst ../,,$(filter-out $(wildcard ../include/*.*),$(wildcard ../include/*)))\ $(subst ../,,$(wildcard ../target/*/drv/*))\ $(subst ../,,$(wildcard ../target/*/util))\ diff --git a/samples/Makefile b/samples/Makefile index 0cef19798..d9b51e827 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -12,20 +12,19 @@ SYS = c64 # source tree; otherwise, use the "install" directories. ifeq "$(wildcard ../src)" "" # No source tree -MOUS = /usr/lib/cc65/target/$(SYS)/drv/mou/$(SYS)*.mou -TGI = /usr/lib/cc65/target/$(SYS)/drv/tgi/$(SYS)*.tgi +installdir = /usr/lib/cc65 ifneq "$(wildcard /usr/local/lib/cc65)" "" -MOUS = /usr/local/lib/cc65/target/$(SYS)/drv/mou/$(SYS)*.mou -TGI = /usr/local/lib/cc65/target/$(SYS)/drv/tgi/$(SYS)*.tgi +installdir = /usr/local/lib/cc65 endif ifneq "$(wildcard /opt/local/share/cc65)" "" -MOUS = /opt/local/share/cc65/target/$(SYS)/drv/mou/$(SYS)*.mou -TGI = /opt/local/share/cc65/target/$(SYS)/drv/tgi/$(SYS)*.tgi +installdir = /opt/local/share/cc65 endif ifdef CC65_HOME -MOUS = $(CC65_HOME)/target/$(SYS)/drv/mou/$(SYS)*.mou -TGI = $(CC65_HOME)/target/$(SYS)/drv/tgi/$(SYS)*.tgi +installdir = $(CC65_HOME) endif + +MOUS = $(installdir)/target/$(SYS)/drv/mou/$(SYS)*.mou +TGI = $(installdir)/target/$(SYS)/drv/tgi/$(SYS)*.tgi CLIB = --lib $(SYS).lib CL = cl65 CC = cc65 @@ -109,8 +108,11 @@ EXELIST = ascii \ # -------------------------------------------------------------------------- # Rules to make the binaries -.PHONY: all -all: $(EXELIST) +.PHONY: all samples +all: + +samples: + $(EXELIST) # -------------------------------------------------------------------------- # Overlay rules. Overlays need special ld65 configuration files. Also, the @@ -138,9 +140,36 @@ samples.d64: all $(C1541) -attach $@ -write $$mod > /dev/null || exit $$?;\ done +# -------------------------------------------------------------------------- +# Installation rules + +INSTALL = install +samplesdir = $(prefix)/share/cc65 +.PHONY: install +install: + $(if $(prefix),,$(error variable `prefix' must be set)) + $(INSTALL) -d $(DESTDIR)$(samplesdir) + $(INSTALL) -d $(DESTDIR)$(samplesdir)/geos + $(INSTALL) -d $$(DESTDIR)$(samplesdir)/tutorial + $(INSTALL) -m0644 *.* $(DESTDIR)$(samplesdir) + $(INSTALL) -m0644 README $(DESTDIR)$(samplesdir) + $(INSTALL) -m0644 Makefile $(DESTDIR)$(samplesdir) + $(INSTALL) -m0644 geos/*.* $(DESTDIR)$(samplesdir)/geos + $(INSTALL) -m0644 tutorial/*.* $(DESTDIR)$(samplesdir)/tutorial + +# -------------------------------------------------------------------------- +# Packaging rules + +.PHONY: zip +zip: + @cd .. && zip -r cc65 samples/ + # -------------------------------------------------------------------------- # Clean-up rules +.PHONY: mostlyclean +mostlyclean: + .PHONY: clean clean: $(RM) *~ *.map *.o *.s *.lbl From 9523fa2d33f08cc380f28e7499b7d5200ceaa37f Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 31 May 2016 07:37:58 +0200 Subject: [PATCH 0069/2161] Atari: get current drive on XDOS --- asminc/atari.inc | 1 + libsrc/atari/getdefdev.s | 14 ++++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/asminc/atari.inc b/asminc/atari.inc index b8f883cd8..f7a7ab223 100644 --- a/asminc/atari.inc +++ b/asminc/atari.inc @@ -1021,6 +1021,7 @@ XGLIN = $0871 ; get line XSKIP = $0874 ; skip parameter XMOVE = $0877 ; move filename XGNUM = $087A ; get number +XDEFDEV = $0816 ; current drive * undocumented * ;------------------------------------------------------------------------- ; End of atari.inc diff --git a/libsrc/atari/getdefdev.s b/libsrc/atari/getdefdev.s index 280c042e5..56ad8ff65 100644 --- a/libsrc/atari/getdefdev.s +++ b/libsrc/atari/getdefdev.s @@ -27,9 +27,10 @@ __getdefdev: lda __dos_type ; which DOS? - cmp #OSADOS+1 - bcs finish ; only supported on OS/A+ and SpartaDOS - ; (TODO: add XDOS support) + cmp #XDOS + beq xdos ; only supported on XDOS ... +; cmp #OSADOS+1 ; (redundant: #OSADOS+1 = #XDOS) + bcs finish ; ... and on OS/A+ and SpartaDOS ldy #BUFOFF lda #0 @@ -68,7 +69,7 @@ crvec: jsr $FFFF ; will be set to crunch vector sta __defdev iny lda (DOSVEC),y - sta __defdev+1 +done: sta __defdev+1 ; Return pointer to default device @@ -76,6 +77,11 @@ finish: lda #<__defdev ldx #>__defdev rts +; XDOS version + +xdos: lda XDEFDEV + bne done + .data ; Default device From c1f17e9c18603724c7795709cbcb4b9b5a18f60b Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 31 May 2016 09:28:53 +0200 Subject: [PATCH 0070/2161] Atari: make __getdefdev function ROM-friendly --- libsrc/atari/getdefdev.s | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libsrc/atari/getdefdev.s b/libsrc/atari/getdefdev.s index 56ad8ff65..ed0d49907 100644 --- a/libsrc/atari/getdefdev.s +++ b/libsrc/atari/getdefdev.s @@ -60,7 +60,7 @@ __getdefdev: lda (DOSVEC),y sta crvec+2 -crvec: jsr $FFFF ; will be set to crunch vector + jsr crvec ; Get default device @@ -84,6 +84,8 @@ xdos: lda XDEFDEV .data +crvec: .byte $4C,$FF,$FF ; will be set to crunch vector + ; Default device __defdev: From 4d02d478325f737b35a18d6efb8147c2edabd990 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 31 May 2016 10:38:02 +0200 Subject: [PATCH 0071/2161] Use atexit() to wait for key press at program ternination. Idea by polluks. --- libsrc/atari/targetutil/w2cas.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/libsrc/atari/targetutil/w2cas.c b/libsrc/atari/targetutil/w2cas.c index 453785140..c95ff7ba5 100644 --- a/libsrc/atari/targetutil/w2cas.c +++ b/libsrc/atari/targetutil/w2cas.c @@ -32,6 +32,13 @@ static struct __iocb *findfreeiocb(void) return NULL; } +static void exitfn(void) +{ + /* if DOS will automatically clear the screen, after the program exits, wait for a keypress... */ + if (! _is_cmdline_dos()) + cgetc(); +} + int main(int argc, char **argv) { char *filename, *x; @@ -43,10 +50,10 @@ int main(int argc, char **argv) struct __iocb *iocb = findfreeiocb(); int iocb_num; + atexit(exitfn); + if (! iocb) { fprintf(stderr, "couldn't find a free iocb\n"); - if (! _is_cmdline_dos()) - cgetc(); return 1; } iocb_num = (iocb - &IOCB) * 16; @@ -59,16 +66,12 @@ int main(int argc, char **argv) printf("\n"); if (! x) { printf("empty filename, exiting...\n"); - if (! _is_cmdline_dos()) - cgetc(); return 1; } if (*x && *(x + strlen(x) - 1) == '\n') *(x + strlen(x) - 1) = 0; if (! strlen(x)) { /* empty filename */ printf("empty filename, exiting...\n"); - if (! _is_cmdline_dos()) - cgetc(); return 1; } filename = x; @@ -84,8 +87,6 @@ int main(int argc, char **argv) buffer = malloc(buflen); if (! buffer) { fprintf(stderr, "cannot alloc %ld bytes -- aborting...\n", (long)buflen); - if (! _is_cmdline_dos()) - cgetc(); return 1; } } @@ -97,8 +98,6 @@ int main(int argc, char **argv) if (! file) { free(buffer); fprintf(stderr, "cannot open '%s': %s\n", filename, strerror(errno)); - if (! _is_cmdline_dos()) - cgetc(); return 1; } @@ -111,8 +110,6 @@ int main(int argc, char **argv) file_err: fclose(file); free(buffer); - if (! _is_cmdline_dos()) - cgetc(); return 1; } if (filen > 32767l) { @@ -143,8 +140,6 @@ int main(int argc, char **argv) if (regs.y != 1) { fprintf(stderr, "CIO call to open cassette returned %d\n", regs.y); free(buffer); - if (! _is_cmdline_dos()) - cgetc(); return 1; } @@ -167,8 +162,6 @@ int main(int argc, char **argv) regs.pc = 0xe456; /* CIOV */ _sys(®s); - if (! _is_cmdline_dos()) - cgetc(); return 1; } @@ -183,14 +176,10 @@ int main(int argc, char **argv) if (regs.y != 1) { fprintf(stderr, "CIO call to close cassette returned %d\n", regs.y); - if (! _is_cmdline_dos()) - cgetc(); return 1; } /* all is fine */ printf("success\n"); - if (! _is_cmdline_dos()) - cgetc(); return 0; } From 0114a850d9387d02ce51a592dd523f506ec92146 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 31 May 2016 12:24:21 +0200 Subject: [PATCH 0072/2161] Atari, getdefdev.s: use mnemonics for 'crvec'. --- libsrc/atari/getdefdev.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/atari/getdefdev.s b/libsrc/atari/getdefdev.s index ed0d49907..a1c950dc5 100644 --- a/libsrc/atari/getdefdev.s +++ b/libsrc/atari/getdefdev.s @@ -84,7 +84,7 @@ xdos: lda XDEFDEV .data -crvec: .byte $4C,$FF,$FF ; will be set to crunch vector +crvec: jmp $FFFF ; target address will be set to crunch vector ; Default device From b7e7d1496bc3ebf90a62b75fa5ddce8ba204e1af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrycjusz=20R=2E=20=C5=81ogiewa?= <patrycjusz.logiewa@srebrnysen.com> Date: Wed, 1 Jun 2016 16:37:05 +0200 Subject: [PATCH 0073/2161] corrected all samples and samples.d64 targets --- samples/Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index d9b51e827..2542275fb 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -111,8 +111,7 @@ EXELIST = ascii \ .PHONY: all samples all: -samples: - $(EXELIST) +samples: $(EXELIST) # -------------------------------------------------------------------------- # Overlay rules. Overlays need special ld65 configuration files. Also, the @@ -131,7 +130,7 @@ ovrldemo: overlaydemo.o .PHONY: disk disk: samples.d64 -samples.d64: all +samples.d64: samples @$(C1541) -format samples,AA d64 $@ > /dev/null @for exe in $(EXELIST); do\ $(C1541) -attach $@ -write $$exe > /dev/null || exit $$?;\ From 3c8fd588f6b9d348685c0fc64c5e3b3914846277 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 1 Jun 2016 19:41:51 +0200 Subject: [PATCH 0074/2161] Don't fiddle with foreign files. No cc65 tool creates *~ files so we don't cleanup *~ files. If some other tool (like an editor) creates *~ files it's up to the user - and only him - to decide when those files are to be deleted ! --- samples/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Makefile b/samples/Makefile index 2542275fb..4560b35d0 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -171,7 +171,7 @@ mostlyclean: .PHONY: clean clean: - $(RM) *~ *.map *.o *.s *.lbl + $(RM) *.map *.o *.s *.lbl .PHONY: zap zap: clean From d455263e6661cfc0130a36978431a5c3f0aea006 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 1 Jun 2016 19:46:02 +0200 Subject: [PATCH 0075/2161] Don'r presume that the C64 is the only target. Other targets have disks too and if at some point some one is interested enough to add support for disk creation for other targets too then 'disk' is no good goal name for a C64 disk. --- samples/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index 4560b35d0..aa869b088 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -127,8 +127,8 @@ ovrldemo: overlaydemo.o # Rule to make a CBM disk with all samples. Needs the c1541 program that comes # with the VICE emulator. -.PHONY: disk -disk: samples.d64 +.PHONY: d64 +d64: samples.d64 samples.d64: samples @$(C1541) -format samples,AA d64 $@ > /dev/null From 6fca6897cd600641214c54b6aab6a31bb217322f Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 1 Jun 2016 20:59:33 +0200 Subject: [PATCH 0076/2161] Removed tab characters. The cc65 code base uses tab character only for make recipes. --- samples/Makefile | 54 ++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index aa869b088..dcae2f575 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -5,7 +5,7 @@ # # Enter the target system here -SYS = c64 +SYS = c64 # Determine the path to the executables and libraries. If the samples # directory is part of a complete source tree, use the stuff from that @@ -44,7 +44,7 @@ LD = ../bin/ld65 endif # This one comes with VICE -C1541 = c1541 +C1541 = c1541 # -------------------------------------------------------------------------- # System-dependent settings @@ -90,20 +90,20 @@ LDFLAGS_tgidemo_atari = -D __RESERVED_MEMORY__=0x2000 # List of executables. This list could be made target-dependent by checking # $(SYS). -EXELIST = ascii \ - diodemo \ - enumdevdir \ - fire \ - gunzip65 \ - hello \ - mandelbrot \ - mousetest \ - multdemo \ - nachtm \ - ovrldemo \ - plasma \ - sieve \ - tgidemo +EXELIST = ascii \ + diodemo \ + enumdevdir \ + fire \ + gunzip65 \ + hello \ + mandelbrot \ + mousetest \ + multdemo \ + nachtm \ + ovrldemo \ + plasma \ + sieve \ + tgidemo # -------------------------------------------------------------------------- # Rules to make the binaries @@ -111,26 +111,26 @@ EXELIST = ascii \ .PHONY: all samples all: -samples: $(EXELIST) +samples: $(EXELIST) # -------------------------------------------------------------------------- # Overlay rules. Overlays need special ld65 configuration files. Also, the # overlay file-names are shortenned to fit the Atari's 8.3-character limit. -multdemo: multidemo.o +multdemo: multidemo.o @$(LD) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(CLIB) -ovrldemo: overlaydemo.o +ovrldemo: overlaydemo.o @$(LD) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(CLIB) # -------------------------------------------------------------------------- # Rule to make a CBM disk with all samples. Needs the c1541 program that comes # with the VICE emulator. -.PHONY: d64 -d64: samples.d64 +.PHONY: d64 +d64: samples.d64 -samples.d64: samples +samples.d64: samples @$(C1541) -format samples,AA d64 $@ > /dev/null @for exe in $(EXELIST); do\ $(C1541) -attach $@ -write $$exe > /dev/null || exit $$?;\ @@ -144,7 +144,7 @@ samples.d64: samples INSTALL = install samplesdir = $(prefix)/share/cc65 -.PHONY: install +.PHONY: install install: $(if $(prefix),,$(error variable `prefix' must be set)) $(INSTALL) -d $(DESTDIR)$(samplesdir) @@ -159,7 +159,7 @@ install: # -------------------------------------------------------------------------- # Packaging rules -.PHONY: zip +.PHONY: zip zip: @cd .. && zip -r cc65 samples/ @@ -169,11 +169,11 @@ zip: .PHONY: mostlyclean mostlyclean: -.PHONY: clean +.PHONY: clean clean: $(RM) *.map *.o *.s *.lbl -.PHONY: zap -zap: clean +.PHONY: zap +zap: clean $(RM) $(EXELIST) samples.d64 $(RM) multdemo.? ovrldemo.? From d78b44f8c601c942274bc88ed038c2364c8f47be Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 1 Jun 2016 21:08:47 +0200 Subject: [PATCH 0077/2161] Adjusted to the cc65 Makefile style. The cc65 Makefiles have a single .PHONY target. It serves as an overview of the "interesting" goals supported by the Makfile. --- samples/Makefile | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index dcae2f575..7ab9a13e6 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -69,6 +69,8 @@ LDFLAGS_tgidemo_atari = -D __RESERVED_MEMORY__=0x2000 # -------------------------------------------------------------------------- # Generic rules +.PHONY: all mostlyclean clean install zip samples d64 zap + %: %.c %: %.s @@ -108,7 +110,6 @@ EXELIST = ascii \ # -------------------------------------------------------------------------- # Rules to make the binaries -.PHONY: all samples all: samples: $(EXELIST) @@ -127,7 +128,6 @@ ovrldemo: overlaydemo.o # Rule to make a CBM disk with all samples. Needs the c1541 program that comes # with the VICE emulator. -.PHONY: d64 d64: samples.d64 samples.d64: samples @@ -144,7 +144,7 @@ samples.d64: samples INSTALL = install samplesdir = $(prefix)/share/cc65 -.PHONY: install + install: $(if $(prefix),,$(error variable `prefix' must be set)) $(INSTALL) -d $(DESTDIR)$(samplesdir) @@ -159,21 +159,17 @@ install: # -------------------------------------------------------------------------- # Packaging rules -.PHONY: zip zip: @cd .. && zip -r cc65 samples/ # -------------------------------------------------------------------------- # Clean-up rules -.PHONY: mostlyclean mostlyclean: -.PHONY: clean clean: $(RM) *.map *.o *.s *.lbl -.PHONY: zap zap: clean $(RM) $(EXELIST) samples.d64 $(RM) multdemo.? ovrldemo.? From ec06d162bd82038de2312a7a07d6a160ab169f35 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 1 Jun 2016 22:14:30 +0200 Subject: [PATCH 0078/2161] Fixed clean goal on Windows. Now that the clean goal of the samples Makefile is part of the global clean goal it should work on Windows! BTW: Ideally the whole samples Makefile should work on Windows ;-)) --- samples/Makefile | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index 7ab9a13e6..f90cafa5a 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -7,6 +7,18 @@ # Enter the target system here SYS = c64 +ifneq ($(shell echo),) + CMD_EXE = 1 +endif + +ifdef CMD_EXE + NULLDEV = nul: + DEL = -del /f +else + NULLDEV = /dev/null + DEL = $(RM) +endif + # Determine the path to the executables and libraries. If the samples # directory is part of a complete source tree, use the stuff from that # source tree; otherwise, use the "install" directories. @@ -131,12 +143,12 @@ ovrldemo: overlaydemo.o d64: samples.d64 samples.d64: samples - @$(C1541) -format samples,AA d64 $@ > /dev/null + @$(C1541) -format samples,AA d64 $@ >$(NULLDEV) @for exe in $(EXELIST); do\ - $(C1541) -attach $@ -write $$exe > /dev/null || exit $$?;\ + $(C1541) -attach $@ -write $$exe >$(NULLDEV) || exit $$?;\ done @for mod in $(TGI) $(MOUS); do\ - $(C1541) -attach $@ -write $$mod > /dev/null || exit $$?;\ + $(C1541) -attach $@ -write $$mod >$(NULLDEV) || exit $$?;\ done # -------------------------------------------------------------------------- @@ -168,8 +180,8 @@ zip: mostlyclean: clean: - $(RM) *.map *.o *.s *.lbl + @$(DEL) *.map *.o *.s *.lbl 2>$(NULLDEV) zap: clean - $(RM) $(EXELIST) samples.d64 - $(RM) multdemo.? ovrldemo.? + @$(DEL) $(EXELIST) samples.d64 2>$(NULLDEV) + @$(DEL) multdemo.? ovrldemo.? 2>$(NULLDEV) From b75e36bba18e9a86ed45c1d9be833cfc59510526 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 1 Jun 2016 22:36:38 +0200 Subject: [PATCH 0079/2161] Don't ignore more than necessary. We know that the one and only cc65.zip we want to ignore lives in the root directory. --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index dac38c48b..ad4d26c3f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,4 @@ /target/ /testwrk/ /wrk/ -cc65.zip +/cc65.zip From 506e44fb5dbfff0aed898823256dbe79346ac8a6 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 1 Jun 2016 22:50:42 +0200 Subject: [PATCH 0080/2161] Corrected cleanup semantics. There's no zap goal in cc65 Makefiles. --- samples/Makefile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index f90cafa5a..26b0e42f4 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -81,7 +81,7 @@ LDFLAGS_tgidemo_atari = -D __RESERVED_MEMORY__=0x2000 # -------------------------------------------------------------------------- # Generic rules -.PHONY: all mostlyclean clean install zip samples d64 zap +.PHONY: all mostlyclean clean install zip samples d64 %: %.c %: %.s @@ -178,10 +178,8 @@ zip: # Clean-up rules mostlyclean: - -clean: @$(DEL) *.map *.o *.s *.lbl 2>$(NULLDEV) -zap: clean +clean: mostlyclean @$(DEL) $(EXELIST) samples.d64 2>$(NULLDEV) @$(DEL) multdemo.? ovrldemo.? 2>$(NULLDEV) From 1ab725e526d542c2ccf816f10133ff508c399c9b Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 1 Jun 2016 23:00:37 +0200 Subject: [PATCH 0081/2161] Don't hide build commands. The samples Makefile serves educational purposes. From that perspective it's counterproductive to hide the actual build commands. Apart fom that it becomes visible if an installed cc65 is used to build the samples. --- samples/Makefile | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index 26b0e42f4..2b356b384 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -87,18 +87,16 @@ LDFLAGS_tgidemo_atari = -D __RESERVED_MEMORY__=0x2000 %: %.s .c.o: - @echo $< - @$(CC) $(CFLAGS) -Oirs --codesize 500 -T -g -t $(SYS) $< - @$(AS) $(<:.c=.s) + $(CC) $(CFLAGS) -Oirs --codesize 500 -T -g -t $(SYS) $< + $(AS) $(<:.c=.s) .s.o: - @echo $< - @$(AS) $(AFLAGS) -t $(SYS) $< + $(AS) $(AFLAGS) -t $(SYS) $< .PRECIOUS: %.o .o: - @$(LD) $(LDFLAGS_$(@F)_$(SYS)) -o $@ -t $(SYS) -m $@.map $^ $(CLIB) + $(LD) $(LDFLAGS_$(@F)_$(SYS)) -o $@ -t $(SYS) -m $@.map $^ $(CLIB) # -------------------------------------------------------------------------- # List of executables. This list could be made target-dependent by checking @@ -131,10 +129,10 @@ samples: $(EXELIST) # overlay file-names are shortenned to fit the Atari's 8.3-character limit. multdemo: multidemo.o - @$(LD) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(CLIB) + $(LD) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(CLIB) ovrldemo: overlaydemo.o - @$(LD) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(CLIB) + $(LD) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(CLIB) # -------------------------------------------------------------------------- # Rule to make a CBM disk with all samples. Needs the c1541 program that comes From 38778cdeb6fc6b8f83b3631e423d63e648d86d53 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 1 Jun 2016 23:04:46 +0200 Subject: [PATCH 0082/2161] Don't cleanup files "just in case". The build doesn't create *.lbl files so we're not deleting *.lbl files. --- samples/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Makefile b/samples/Makefile index 2b356b384..fa3777000 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -176,7 +176,7 @@ zip: # Clean-up rules mostlyclean: - @$(DEL) *.map *.o *.s *.lbl 2>$(NULLDEV) + @$(DEL) *.map *.o *.s 2>$(NULLDEV) clean: mostlyclean @$(DEL) $(EXELIST) samples.d64 2>$(NULLDEV) From 24256256fb772ed34c5197bcfba109278c471052 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 1 Jun 2016 23:45:27 +0200 Subject: [PATCH 0083/2161] Removed shell for-loop. Just a few of the many reasons why shell for-loops have no place in (GNUmake) Makefiles: * They don't conform to https://www.gnu.org/software/make/manual/html_node/Utilities-in-Makefiles.html * They break Windows builds for sure * They don't fit to make's approach of working with sets * They break make parallelism --- samples/Makefile | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index fa3777000..5a75c7f4b 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -35,8 +35,8 @@ ifdef CC65_HOME installdir = $(CC65_HOME) endif -MOUS = $(installdir)/target/$(SYS)/drv/mou/$(SYS)*.mou -TGI = $(installdir)/target/$(SYS)/drv/tgi/$(SYS)*.tgi +MOUS := $(wildcard $(installdir)/target/$(SYS)/drv/mou/$(SYS)*.mou) +TGI := $(wildcard $(installdir)/target/$(SYS)/drv/tgi/$(SYS)*.tgi) CLIB = --lib $(SYS).lib CL = cl65 CC = cc65 @@ -46,8 +46,8 @@ LD = ld65 else # "samples/" is a part of a complete source tree. export CC65_HOME := $(abspath ..) -MOUS = ../target/$(SYS)/drv/mou/$(SYS)*.mou -TGI = ../target/$(SYS)/drv/tgi/$(SYS)*.tgi +MOUS := $(wildcard ../target/$(SYS)/drv/mou/$(SYS)*.mou) +TGI := $(wildcard ../target/$(SYS)/drv/tgi/$(SYS)*.tgi) CLIB = ../lib/$(SYS).lib CL = ../bin/cl65 CC = ../bin/cc65 @@ -140,14 +140,16 @@ ovrldemo: overlaydemo.o d64: samples.d64 +define D64_WRITE_recipe + +$(C1541) -attach $@ -write $(file) $(notdir $(file)) >$(NULLDEV) + +endef # D64_WRITE_recipe + samples.d64: samples @$(C1541) -format samples,AA d64 $@ >$(NULLDEV) - @for exe in $(EXELIST); do\ - $(C1541) -attach $@ -write $$exe >$(NULLDEV) || exit $$?;\ - done - @for mod in $(TGI) $(MOUS); do\ - $(C1541) -attach $@ -write $$mod >$(NULLDEV) || exit $$?;\ - done + $(foreach file,$(EXELIST),$(D64_WRITE_recipe)) + $(foreach file,$(TGI) $(MOUS),$(D64_WRITE_recipe)) # -------------------------------------------------------------------------- # Installation rules From d653054d980db55fb12f3413b20509324778de84 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 1 Jun 2016 23:48:09 +0200 Subject: [PATCH 0084/2161] Allow usage of C1541 environment variable. --- samples/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Makefile b/samples/Makefile index 5a75c7f4b..df8aab38e 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -56,7 +56,7 @@ LD = ../bin/ld65 endif # This one comes with VICE -C1541 = c1541 +C1541 ?= c1541 # -------------------------------------------------------------------------- # System-dependent settings From ce45f759873e20a839dc2997f2376856f80fd9d3 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 1 Jun 2016 23:51:43 +0200 Subject: [PATCH 0085/2161] Harmonized goal name. --- test/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Makefile b/test/Makefile index 1ad86ca98..ffdf72aa0 100644 --- a/test/Makefile +++ b/test/Makefile @@ -25,7 +25,7 @@ WORKDIR := ../testwrk CC := gcc -.PHONY: all dotests continue mostly-clean clean +.PHONY: all dotests continue mostlyclean clean all: dotests @@ -37,7 +37,7 @@ $(WORKDIR)/bdiff$(EXE): bdiff.c | $(WORKDIR) .NOTPARALLEL: -dotests: mostly-clean continue +dotests: mostlyclean continue continue: $(WORKDIR)/bdiff$(EXE) @$(MAKE) -C val all @@ -45,12 +45,12 @@ continue: $(WORKDIR)/bdiff$(EXE) @$(MAKE) -C err all @$(MAKE) -C misc all -mostly-clean: +mostlyclean: @$(MAKE) -C val clean @$(MAKE) -C ref clean @$(MAKE) -C err clean @$(MAKE) -C misc clean -clean: mostly-clean +clean: mostlyclean @$(call DEL,$(WORKDIR)/bdiff$(EXE)) @$(call RMDIR,$(WORKDIR)) From 9f01392922d47fe5062b0446df740c0165396e57 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 2 Jun 2016 20:49:10 +0200 Subject: [PATCH 0086/2161] Write overlays to d64 image. --- samples/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/samples/Makefile b/samples/Makefile index df8aab38e..c138c1c2e 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -134,6 +134,8 @@ multdemo: multidemo.o ovrldemo: overlaydemo.o $(LD) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(CLIB) +OVERLAYLIST := $(foreach I,1 2 3,multdemo.$I ovrldemo.$I) + # -------------------------------------------------------------------------- # Rule to make a CBM disk with all samples. Needs the c1541 program that comes # with the VICE emulator. @@ -149,6 +151,7 @@ endef # D64_WRITE_recipe samples.d64: samples @$(C1541) -format samples,AA d64 $@ >$(NULLDEV) $(foreach file,$(EXELIST),$(D64_WRITE_recipe)) + $(foreach file,$(OVERLAYLIST),$(D64_WRITE_recipe)) $(foreach file,$(TGI) $(MOUS),$(D64_WRITE_recipe)) # -------------------------------------------------------------------------- From 8dd003d2b3e462ca982016d64d17a01dddc8a771 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 3 Jun 2016 11:08:53 +0200 Subject: [PATCH 0087/2161] Added --print-target-path option. If cc65 is installed and used as designed there's no need whatsoever for CC65_HOME (both on *IX and Windows) from the perspective of the cc65 binaries. If the user however has to access files from the 'target' directory thenhe ends up with some assumption on the cc65 installation path nevertheless :-( In order to avoid this I added the --print-target-path option. It "exports" the logic used by the cc65 binaries to locate their files to the user thus allowing him to leverage the same logic to locate the target files in his build scripts / Makefiles. --- doc/cl65.sgml | 15 ++++- src/Makefile | 4 +- src/cl65/main.c | 120 +++++++++++++++++++++++----------------- src/common/searchpath.c | 12 ++++ src/common/searchpath.h | 5 ++ 5 files changed, 103 insertions(+), 53 deletions(-) diff --git a/doc/cl65.sgml b/doc/cl65.sgml index 6e044b8d5..6f29fa29d 100644 --- a/doc/cl65.sgml +++ b/doc/cl65.sgml @@ -103,6 +103,7 @@ Long options: --o65-model model Override the o65 model --obj file Link this object file --obj-path path Specify an object file search path + --print-target-path Print the target file path --register-space b Set space available for register variables --register-vars Enable register variables --rodata-name seg Set the name of the RODATA segment @@ -154,6 +155,14 @@ There are a few remaining options that control the behaviour of cl65: shouldn't use -o when more than one output file is created. + <tag><tt>--print-target-path</tt></tag> + + This option prints the absolute path of the target file directory and exits + then. It is supposed to be used with shell backquotes or the GNU make shell + function This way you can write build scripts or Makefiles accessing target + files without any assumption about the cc65 installation path. + + <tag><tt>-t sys, --target sys</tt></tag> The default for this option is different from the compiler and linker in the @@ -162,6 +171,7 @@ There are a few remaining options that control the behaviour of cl65: the C64 as a target system by default. This was chosen since most people seem to use cc65 to develop for the C64. + <tag><tt>-Wa options, --asm-args options</tt></tag> Pass options directly to the assembler. This may be used to pass options @@ -172,6 +182,7 @@ There are a few remaining options that control the behaviour of cl65: if cl65 supports an option by itself, do not pass this option to the assembler by means of the <tt/-Wa/ switch. + <tag><tt>-Wc options, --cc-args options</tt></tag> Pass options directly to the compiler. This may be used to pass options @@ -182,6 +193,7 @@ There are a few remaining options that control the behaviour of cl65: if cl65 supports an option by itself, do not pass this option to the compiler by means of the <tt/-Wc/ switch. + <tag><tt>-Wl options, --ld-args options</tt></tag> Pass options directly to the linker. This may be used to pass options that @@ -192,7 +204,7 @@ There are a few remaining options that control the behaviour of cl65: supports an option by itself, do not pass this option to the linker by means of the <tt/-Wl/ switch. -</descrip> +</descrip> @@ -304,4 +316,3 @@ freely, subject to the following restrictions: </article> - diff --git a/src/Makefile b/src/Makefile index f10c189b3..edb6f5aa8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -24,6 +24,7 @@ datadir := $(if $(prefix),$(prefix)/share/cc65,$(abspath ..)) CA65_INC = $(datadir)/asminc CC65_INC = $(datadir)/include +CL65_TGT = $(datadir)/target LD65_LIB = $(datadir)/lib LD65_OBJ = $(datadir)/lib LD65_CFG = $(datadir)/cfg @@ -63,8 +64,9 @@ endif CFLAGS += -MMD -MP -O -I common \ -Wall -Wextra -Wno-char-subscripts $(USER_CFLAGS) \ - -DGIT_SHA=$(GIT_SHA) -DCA65_INC=$(CA65_INC) -DCC65_INC=$(CC65_INC) \ + -DCA65_INC=$(CA65_INC) -DCC65_INC=$(CC65_INC) -DCL65_TGT=$(CL65_TGT) \ -DLD65_LIB=$(LD65_LIB) -DLD65_OBJ=$(LD65_OBJ) -DLD65_CFG=$(LD65_CFG) + -DGIT_SHA=$(GIT_SHA) LDLIBS += -lm diff --git a/src/cl65/main.c b/src/cl65/main.c index 4268a569b..654bd97b2 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -73,6 +73,7 @@ #include "filetype.h" #include "fname.h" #include "mmodel.h" +#include "searchpath.h" #include "strbuf.h" #include "target.h" #include "version.h" @@ -759,6 +760,7 @@ static void Usage (void) " --o65-model model\t\tOverride the o65 model\n" " --obj file\t\t\tLink this object file\n" " --obj-path path\t\tSpecify an object file search path\n" + " --print-target-path\t\tPrint the target file path\n" " --register-space b\t\tSet space available for register variables\n" " --register-vars\t\tEnable register variables\n" " --rodata-name seg\t\tSet the name of the RODATA segment\n" @@ -1126,6 +1128,23 @@ static void OptObjPath (const char* Opt attribute ((unused)), const char* Arg) +static void OptPrintTargetPath (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Print the target file path */ +{ + SearchPaths* TargetPath = NewSearchPath (); + AddSubSearchPathFromEnv (TargetPath, "CC65_HOME", "target"); +#if defined(CL65_TGT) && !defined(_WIN32) + AddSearchPath (TargetPath, STRINGIZE (CL65_TGT)); +#endif + AddSubSearchPathFromWinBin (TargetPath, "target"); + + printf ("%s\n", GetSearchPath (TargetPath, 0)); + exit (EXIT_SUCCESS); +} + + + static void OptRegisterSpace (const char* Opt attribute ((unused)), const char* Arg) /* Handle the --register-space option */ { @@ -1240,56 +1259,57 @@ int main (int argc, char* argv []) { /* Program long options */ static const LongOpt OptTab[] = { - { "--add-source", 0, OptAddSource }, - { "--asm-args", 1, OptAsmArgs }, - { "--asm-define", 1, OptAsmDefine }, - { "--asm-include-dir", 1, OptAsmIncludeDir }, - { "--bin-include-dir", 1, OptBinIncludeDir }, - { "--bss-label", 1, OptBssLabel }, - { "--bss-name", 1, OptBssName }, - { "--cc-args", 1, OptCCArgs }, - { "--cfg-path", 1, OptCfgPath }, - { "--check-stack", 0, OptCheckStack }, - { "--code-label", 1, OptCodeLabel }, - { "--code-name", 1, OptCodeName }, - { "--codesize", 1, OptCodeSize }, - { "--config", 1, OptConfig }, - { "--cpu", 1, OptCPU }, - { "--create-dep", 1, OptCreateDep }, - { "--create-full-dep", 1, OptCreateFullDep }, - { "--data-label", 1, OptDataLabel }, - { "--data-name", 1, OptDataName }, - { "--debug", 0, OptDebug }, - { "--debug-info", 0, OptDebugInfo }, - { "--feature", 1, OptFeature }, - { "--force-import", 1, OptForceImport }, - { "--help", 0, OptHelp }, - { "--include-dir", 1, OptIncludeDir }, - { "--ld-args", 1, OptLdArgs }, - { "--lib", 1, OptLib }, - { "--lib-path", 1, OptLibPath }, - { "--list-targets", 0, OptListTargets }, - { "--listing", 1, OptListing }, - { "--list-bytes", 1, OptListBytes }, - { "--mapfile", 1, OptMapFile }, - { "--memory-model", 1, OptMemoryModel }, - { "--module", 0, OptModule }, - { "--module-id", 1, OptModuleId }, - { "--o65-model", 1, OptO65Model }, - { "--obj", 1, OptObj }, - { "--obj-path", 1, OptObjPath }, - { "--register-space", 1, OptRegisterSpace }, - { "--register-vars", 0, OptRegisterVars }, - { "--rodata-name", 1, OptRodataName }, - { "--signed-chars", 0, OptSignedChars }, - { "--standard", 1, OptStandard }, - { "--start-addr", 1, OptStartAddr }, - { "--static-locals", 0, OptStaticLocals }, - { "--target", 1, OptTarget }, - { "--verbose", 0, OptVerbose }, - { "--version", 0, OptVersion }, - { "--zeropage-label", 1, OptZeropageLabel }, - { "--zeropage-name", 1, OptZeropageName }, + { "--add-source", 0, OptAddSource }, + { "--asm-args", 1, OptAsmArgs }, + { "--asm-define", 1, OptAsmDefine }, + { "--asm-include-dir", 1, OptAsmIncludeDir }, + { "--bin-include-dir", 1, OptBinIncludeDir }, + { "--bss-label", 1, OptBssLabel }, + { "--bss-name", 1, OptBssName }, + { "--cc-args", 1, OptCCArgs }, + { "--cfg-path", 1, OptCfgPath }, + { "--check-stack", 0, OptCheckStack }, + { "--code-label", 1, OptCodeLabel }, + { "--code-name", 1, OptCodeName }, + { "--codesize", 1, OptCodeSize }, + { "--config", 1, OptConfig }, + { "--cpu", 1, OptCPU }, + { "--create-dep", 1, OptCreateDep }, + { "--create-full-dep", 1, OptCreateFullDep }, + { "--data-label", 1, OptDataLabel }, + { "--data-name", 1, OptDataName }, + { "--debug", 0, OptDebug }, + { "--debug-info", 0, OptDebugInfo }, + { "--feature", 1, OptFeature }, + { "--force-import", 1, OptForceImport }, + { "--help", 0, OptHelp }, + { "--include-dir", 1, OptIncludeDir }, + { "--ld-args", 1, OptLdArgs }, + { "--lib", 1, OptLib }, + { "--lib-path", 1, OptLibPath }, + { "--list-targets", 0, OptListTargets }, + { "--listing", 1, OptListing }, + { "--list-bytes", 1, OptListBytes }, + { "--mapfile", 1, OptMapFile }, + { "--memory-model", 1, OptMemoryModel }, + { "--module", 0, OptModule }, + { "--module-id", 1, OptModuleId }, + { "--o65-model", 1, OptO65Model }, + { "--obj", 1, OptObj }, + { "--obj-path", 1, OptObjPath }, + { "--print-target-path", 0, OptPrintTargetPath}, + { "--register-space", 1, OptRegisterSpace }, + { "--register-vars", 0, OptRegisterVars }, + { "--rodata-name", 1, OptRodataName }, + { "--signed-chars", 0, OptSignedChars }, + { "--standard", 1, OptStandard }, + { "--start-addr", 1, OptStartAddr }, + { "--static-locals", 0, OptStaticLocals }, + { "--target", 1, OptTarget }, + { "--verbose", 0, OptVerbose }, + { "--version", 0, OptVersion }, + { "--zeropage-label", 1, OptZeropageLabel }, + { "--zeropage-name", 1, OptZeropageName }, }; char* CmdPath; diff --git a/src/common/searchpath.c b/src/common/searchpath.c index 78443f34c..ca7017e6f 100644 --- a/src/common/searchpath.c +++ b/src/common/searchpath.c @@ -238,6 +238,18 @@ void PopSearchPath (SearchPaths* P) +char* GetSearchPath (SearchPaths* P, unsigned Index) +/* Return the search path at the given index, if the index is valid, return an +** empty string otherwise. +*/ +{ + if (Index < CollCount (P)) + return CollAtUnchecked (P, Index); + return ""; +} + + + char* SearchFile (const SearchPaths* P, const char* File) /* Search for a file in a list of directories. Return a pointer to a malloced ** area that contains the complete path, if found, return 0 otherwise. diff --git a/src/common/searchpath.h b/src/common/searchpath.h index 6f5bafa7a..974886a67 100644 --- a/src/common/searchpath.h +++ b/src/common/searchpath.h @@ -94,6 +94,11 @@ int PushSearchPath (SearchPaths* P, const char* NewPath); void PopSearchPath (SearchPaths* P); /* Remove a search path from the head of an existing search path list */ +char* GetSearchPath (SearchPaths* P, unsigned Index); +/* Return the search path at the given index, if the index is valid, return an +** empty string otherwise. +*/ + char* SearchFile (const SearchPaths* P, const char* File); /* Search for a file in a list of directories. Return a pointer to a malloced ** area that contains the complete path, if found, return 0 otherwise. From 6f0b57fe514c0656c179189f73399a2a52907eee Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 3 Jun 2016 11:37:15 +0200 Subject: [PATCH 0088/2161] Added chrcvt65 to the Visual Studio project. --- src/cc65.sln | 9 +++++ src/chrcvt65.vcxproj | 87 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 src/chrcvt65.vcxproj diff --git a/src/cc65.sln b/src/cc65.sln index 9d0f2cc2e..4ae2816ad 100644 --- a/src/cc65.sln +++ b/src/cc65.sln @@ -58,6 +58,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sim65", "sim65.vcxproj", "{ {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} = {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "chrcvt65", "chrcvt65.vcxproj", "{1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC}" + ProjectSection(ProjectDependencies) = postProject + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} = {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -112,6 +117,10 @@ Global {002A366E-2863-46A8-BDDE-DDF534AAEC73}.Debug|Win32.Build.0 = Debug|Win32 {002A366E-2863-46A8-BDDE-DDF534AAEC73}.Release|Win32.ActiveCfg = Release|Win32 {002A366E-2863-46A8-BDDE-DDF534AAEC73}.Release|Win32.Build.0 = Release|Win32 + {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}.Release|Win32.ActiveCfg = Release|Win32 + {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj new file mode 100644 index 000000000..1daf7cae9 --- /dev/null +++ b/src/chrcvt65.vcxproj @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>chrcvt65</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)..\bin\</OutDir> + <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)..\bin\</OutDir> + <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG</PreprocessorDefinitions> + <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> + <TreatWarningAsError>true</TreatWarningAsError> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG</PreprocessorDefinitions> + <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> + <TreatWarningAsError>true</TreatWarningAsError> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>false</GenerateDebugInformation> + <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="chrcvt65\error.c" /> + <ClCompile Include="chrcvt65\main.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="chrcvt65\error.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file From 02b84698757753fec2019de18cb75da9d014085d Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 3 Jun 2016 21:21:22 +0200 Subject: [PATCH 0089/2161] Added full stop. --- doc/cl65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/cl65.sgml b/doc/cl65.sgml index 6f29fa29d..b9a6cd1e4 100644 --- a/doc/cl65.sgml +++ b/doc/cl65.sgml @@ -159,7 +159,7 @@ There are a few remaining options that control the behaviour of cl65: This option prints the absolute path of the target file directory and exits then. It is supposed to be used with shell backquotes or the GNU make shell - function This way you can write build scripts or Makefiles accessing target + function. This way you can write build scripts or Makefiles accessing target files without any assumption about the cc65 installation path. From d67099881477e82f6539e69df6fc2e9622480466 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 5 Jun 2016 13:00:37 +0200 Subject: [PATCH 0090/2161] Added Apple II version of doesclrscrafterexit(). The prototype and documentation is supposed to be provided together with the ATARI version. --- libsrc/apple2/doesclrscr.s | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 libsrc/apple2/doesclrscr.s diff --git a/libsrc/apple2/doesclrscr.s b/libsrc/apple2/doesclrscr.s new file mode 100644 index 000000000..2e2e7b96f --- /dev/null +++ b/libsrc/apple2/doesclrscr.s @@ -0,0 +1,21 @@ +; +; Oliver Schmidt, 2016-06-05 +; +; unsigned char doesclrscrafterexit (void); +; + + .export _doesclrscrafterexit + .import done + + .include "apple2.inc" + +_doesclrscrafterexit: + ; If the page we jump to when done equals the page + ; of the warmstart vector we'll return to BASIC so + ; there's no implicit clrscr() after exit(). + lda done+2 + sec + sbc #>DOSWARM + + ldx #>$0000 + rts From 13482984ca38c5a34a51321d0806f3e4a73122ff Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 5 Jun 2016 14:58:38 +0200 Subject: [PATCH 0091/2161] Introduced internal gotoxy that pops both parameters. About all CONIO functions offering a <...>xy variant call popa _gotoxy By providing an internal gotoxy variant that starts with a popa all those CONIO function can be shortened by 3 bytes. As soon as program calls more than one CONIO function this means an overall code size reduction. --- libsrc/apple2/cclear.s | 5 ++--- libsrc/apple2/chline.s | 5 ++--- libsrc/apple2/cputc.s | 7 +++---- libsrc/apple2/cvline.s | 5 ++--- libsrc/apple2/gotoxy.s | 5 ++++- libsrc/atari/cclear.s | 5 ++--- libsrc/atari/chline.s | 5 ++--- libsrc/atari/cputc.s | 5 ++--- libsrc/atari/cvline.s | 5 ++--- libsrc/atari/gotoxy.s | 7 +++++-- libsrc/atari5200/cputc.s | 5 ++--- libsrc/atari5200/gotoxy.s | 5 ++++- libsrc/c128/cputc.s | 5 ++--- libsrc/c16/cputc.s | 5 ++--- libsrc/c64/cputc.s | 5 ++--- libsrc/c64/soft80_cputc.s | 5 ++--- libsrc/c64/soft80mono_cputc.s | 5 ++--- libsrc/cbm/cclear.s | 9 ++------- libsrc/cbm/chline.s | 9 ++------- libsrc/cbm/cvline.s | 8 ++------ libsrc/cbm/gotoxy.s | 5 ++++- libsrc/cbm510/cputc.s | 5 ++--- libsrc/cbm610/cputc.s | 6 ++---- libsrc/conio/cputs.s | 5 ++--- libsrc/gamate/chline.s | 5 ++--- libsrc/gamate/cputc.s | 5 ++--- libsrc/gamate/cvline.s | 5 ++--- libsrc/gamate/gotoxy.s | 5 ++++- libsrc/geos-common/conio/cclear.s | 5 ++--- libsrc/geos-common/conio/chline.s | 5 ++--- libsrc/geos-common/conio/cputc.s | 6 ++---- libsrc/geos-common/conio/cvline.s | 5 ++--- libsrc/geos-common/conio/gotoxy.s | 5 ++++- libsrc/nes/cclear.s | 5 ++--- libsrc/nes/chline.s | 5 ++--- libsrc/nes/cputc.s | 5 ++--- libsrc/nes/cvline.s | 5 ++--- libsrc/nes/gotoxy.s | 10 ++++------ libsrc/osic1p/cclear.s | 5 ++--- libsrc/osic1p/chline.s | 5 ++--- libsrc/osic1p/cvline.s | 5 ++--- libsrc/osic1p/gotoxy.s | 5 ++++- libsrc/osic1p/osiscreen.inc | 5 ++--- libsrc/pce/chline.s | 5 ++--- libsrc/pce/cputc.s | 5 ++--- libsrc/pce/cvline.s | 5 ++--- libsrc/pce/gotoxy.s | 5 ++++- libsrc/pet/cputc.s | 5 ++--- libsrc/plus4/cputc.s | 5 ++--- libsrc/vic20/cputc.s | 5 ++--- 50 files changed, 120 insertions(+), 152 deletions(-) diff --git a/libsrc/apple2/cclear.s b/libsrc/apple2/cclear.s index c06cb0812..4106752eb 100644 --- a/libsrc/apple2/cclear.s +++ b/libsrc/apple2/cclear.s @@ -6,12 +6,11 @@ ; .export _cclearxy, _cclear - .import popa, _gotoxy, chlinedirect + .import gotoxy, chlinedirect _cclearxy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length and run into _cclear _cclear: diff --git a/libsrc/apple2/chline.s b/libsrc/apple2/chline.s index dba094365..6cf77de1b 100644 --- a/libsrc/apple2/chline.s +++ b/libsrc/apple2/chline.s @@ -6,15 +6,14 @@ ; .export _chlinexy, _chline, chlinedirect - .import popa, _gotoxy, cputdirect + .import gotoxy, cputdirect .include "zeropage.inc" .include "apple2.inc" _chlinexy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length and run into _chline _chline: diff --git a/libsrc/apple2/cputc.s b/libsrc/apple2/cputc.s index 2db2962f9..6607c6178 100644 --- a/libsrc/apple2/cputc.s +++ b/libsrc/apple2/cputc.s @@ -10,7 +10,7 @@ .endif .export _cputcxy, _cputc .export cputdirect, newline, putchar - .import popa, _gotoxy, VTABZ + .import gotoxy, VTABZ .include "apple2.inc" @@ -29,9 +29,8 @@ initconio: _cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy - pla ; Restore C + jsr gotoxy ; Call this one, will pop params + pla ; Restore C and run into _cputc _cputc: cmp #$0D ; Test for \r = carrage return diff --git a/libsrc/apple2/cvline.s b/libsrc/apple2/cvline.s index 1ac3fad74..a26cc7063 100644 --- a/libsrc/apple2/cvline.s +++ b/libsrc/apple2/cvline.s @@ -6,14 +6,13 @@ ; .export _cvlinexy, _cvline, cvlinedirect - .import popa, _gotoxy, putchar, newline + .import gotoxy, putchar, newline .include "zeropage.inc" _cvlinexy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length and run into _cvline _cvline: diff --git a/libsrc/apple2/gotoxy.s b/libsrc/apple2/gotoxy.s index dc96ac75e..6755af8d8 100644 --- a/libsrc/apple2/gotoxy.s +++ b/libsrc/apple2/gotoxy.s @@ -5,11 +5,14 @@ ; void __fastcall__ gotox (unsigned char x); ; - .export _gotoxy, _gotox + .export gotoxy, _gotoxy, _gotox .import popa, VTABZ .include "apple2.inc" +gotoxy: + jsr popa ; Get Y + _gotoxy: clc adc WNDTOP diff --git a/libsrc/atari/cclear.s b/libsrc/atari/cclear.s index ceb17aca5..7fe3f0f1b 100644 --- a/libsrc/atari/cclear.s +++ b/libsrc/atari/cclear.s @@ -6,13 +6,12 @@ ; .export _cclearxy, _cclear - .import popa, _gotoxy, cputdirect + .import gotoxy, cputdirect .importzp tmp1 _cclearxy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length and run into _cclear _cclear: diff --git a/libsrc/atari/chline.s b/libsrc/atari/chline.s index a096f35a0..194fe0bb3 100644 --- a/libsrc/atari/chline.s +++ b/libsrc/atari/chline.s @@ -6,7 +6,7 @@ ; .export _chlinexy, _chline - .import popa, _gotoxy, cputdirect, setcursor + .import gotoxy, cputdirect, setcursor .importzp tmp1 .ifdef __ATARI5200__ @@ -17,8 +17,7 @@ CHRCODE = $12+64 _chlinexy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length _chline: diff --git a/libsrc/atari/cputc.s b/libsrc/atari/cputc.s index cd2aefe79..a06daa691 100644 --- a/libsrc/atari/cputc.s +++ b/libsrc/atari/cputc.s @@ -7,7 +7,7 @@ .export _cputcxy, _cputc .export plot, cputdirect, putchar - .import popa, _gotoxy, mul40 + .import gotoxy, mul40 .importzp tmp4,ptr4 .import _revflag,setcursor @@ -15,8 +15,7 @@ _cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, drop x + jsr gotoxy ; Set cursor, drop x and y pla ; Restore C _cputc: diff --git a/libsrc/atari/cvline.s b/libsrc/atari/cvline.s index da6c8dca4..1b4ba0b1b 100644 --- a/libsrc/atari/cvline.s +++ b/libsrc/atari/cvline.s @@ -7,7 +7,7 @@ .include "atari.inc" .export _cvlinexy, _cvline - .import popa, _gotoxy, putchar, setcursor + .import gotoxy, putchar, setcursor .importzp tmp1 .ifdef __ATARI5200__ @@ -18,8 +18,7 @@ CHRCODE = $7C ; Vertical bar _cvlinexy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length and run into _cvline _cvline: diff --git a/libsrc/atari/gotoxy.s b/libsrc/atari/gotoxy.s index 1f00c3b23..aeaa732c0 100644 --- a/libsrc/atari/gotoxy.s +++ b/libsrc/atari/gotoxy.s @@ -6,14 +6,17 @@ .include "atari.inc" - .export _gotoxy + .export gotoxy, _gotoxy .import popa .import setcursor +gotoxy: + jsr popa ; Get Y + _gotoxy: ; Set the cursor position sta ROWCRS ; Set Y jsr popa ; Get X sta COLCRS ; Set X lda #0 - sta COLCRS+1 ; + sta COLCRS+1 jmp setcursor diff --git a/libsrc/atari5200/cputc.s b/libsrc/atari5200/cputc.s index 4bee0fba2..860eea88d 100644 --- a/libsrc/atari5200/cputc.s +++ b/libsrc/atari5200/cputc.s @@ -10,7 +10,7 @@ .export _cputcxy, _cputc .export plot, cputdirect, putchar - .import popa, _gotoxy, mul20 + .import gotoxy, mul20 .importzp ptr4 .import setcursor @@ -21,8 +21,7 @@ screen_setup = screen_setup_20x24 _cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, drop x + jsr gotoxy ; Set cursor, drop x and y pla ; Restore C _cputc: diff --git a/libsrc/atari5200/gotoxy.s b/libsrc/atari5200/gotoxy.s index a4b7c61d0..24e2c2e35 100644 --- a/libsrc/atari5200/gotoxy.s +++ b/libsrc/atari5200/gotoxy.s @@ -6,10 +6,13 @@ .include "atari5200.inc" - .export _gotoxy + .export gotoxy, _gotoxy .import popa .import setcursor +gotoxy: + jsr popa ; Get Y + _gotoxy: ; Set the cursor position sta ROWCRS_5200 ; Set Y jsr popa ; Get X diff --git a/libsrc/c128/cputc.s b/libsrc/c128/cputc.s index e906c242a..9d269a47e 100644 --- a/libsrc/c128/cputc.s +++ b/libsrc/c128/cputc.s @@ -8,7 +8,7 @@ .export _cputcxy, _cputc, cputdirect, putchar .export newline, plot - .import popa, _gotoxy + .import gotoxy .import PLOT .include "c128.inc" @@ -21,8 +21,7 @@ newline = NEWLINE _cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, drop x + jsr gotoxy ; Set cursor, drop x and y pla ; Restore C ; Plot a character - also used as internal function diff --git a/libsrc/c16/cputc.s b/libsrc/c16/cputc.s index a83a9c60b..49b3a84dd 100644 --- a/libsrc/c16/cputc.s +++ b/libsrc/c16/cputc.s @@ -7,7 +7,7 @@ .export _cputcxy, _cputc, cputdirect, putchar .export newline, plot - .import popa, _gotoxy + .import gotoxy .import PLOT .include "plus4.inc" @@ -15,8 +15,7 @@ _cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, drop x + jsr gotoxy ; Set cursor, drop x and y pla ; Restore C ; Plot a character - also used as internal function diff --git a/libsrc/c64/cputc.s b/libsrc/c64/cputc.s index 606d6f596..d6b49607a 100644 --- a/libsrc/c64/cputc.s +++ b/libsrc/c64/cputc.s @@ -7,7 +7,7 @@ .export _cputcxy, _cputc, cputdirect, putchar .export newline, plot - .import popa, _gotoxy + .import gotoxy .import PLOT .include "c64.inc" @@ -15,8 +15,7 @@ _cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, drop x + jsr gotoxy ; Set cursor, drop x and y pla ; Restore C ; Plot a character - also used as internal function diff --git a/libsrc/c64/soft80_cputc.s b/libsrc/c64/soft80_cputc.s index acbe5b560..f00f7792f 100644 --- a/libsrc/c64/soft80_cputc.s +++ b/libsrc/c64/soft80_cputc.s @@ -12,7 +12,7 @@ .export soft80_newline, soft80_plot .export soft80_checkchar - .import popa, _gotoxy + .import gotoxy .import soft80_kplot .import soft80_internal_bgcolor, soft80_internal_cellcolor @@ -25,8 +25,7 @@ soft80_cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, drop x + jsr gotoxy ; Set cursor, drop x and y pla ; Restore C ; Plot a character - also used as internal function diff --git a/libsrc/c64/soft80mono_cputc.s b/libsrc/c64/soft80mono_cputc.s index c89362cb5..252de0319 100644 --- a/libsrc/c64/soft80mono_cputc.s +++ b/libsrc/c64/soft80mono_cputc.s @@ -11,7 +11,7 @@ .export soft80mono_cputdirect, soft80mono_putchar .export soft80mono_newline, soft80mono_plot - .import popa, _gotoxy + .import gotoxy .import soft80mono_kplot .import soft80mono_internal_bgcolor, soft80mono_internal_cellcolor @@ -24,8 +24,7 @@ soft80mono_cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, drop x + jsr gotoxy ; Set cursor, drop x and y pla ; Restore C ; Plot a character - also used as internal function diff --git a/libsrc/cbm/cclear.s b/libsrc/cbm/cclear.s index 233c112c6..14b9d0e8b 100644 --- a/libsrc/cbm/cclear.s +++ b/libsrc/cbm/cclear.s @@ -6,13 +6,12 @@ ; .export _cclearxy, _cclear - .import popa, _gotoxy, cputdirect + .import gotoxy, cputdirect .importzp tmp1 _cclearxy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length and run into _cclear _cclear: @@ -24,7 +23,3 @@ L1: lda #$20 ; Blank - screen code dec tmp1 bne L1 L9: rts - - - - diff --git a/libsrc/cbm/chline.s b/libsrc/cbm/chline.s index fe7e7255d..73782f344 100644 --- a/libsrc/cbm/chline.s +++ b/libsrc/cbm/chline.s @@ -6,13 +6,12 @@ ; .export _chlinexy, _chline - .import popa, _gotoxy, cputdirect + .import gotoxy, cputdirect .importzp tmp1, chlinechar _chlinexy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length _chline: @@ -24,7 +23,3 @@ L1: lda #chlinechar ; Horizontal line, screen code dec tmp1 bne L1 L9: rts - - - - diff --git a/libsrc/cbm/cvline.s b/libsrc/cbm/cvline.s index 2cf231e98..b6d2d86e6 100644 --- a/libsrc/cbm/cvline.s +++ b/libsrc/cbm/cvline.s @@ -6,13 +6,12 @@ ; .export _cvlinexy, _cvline - .import popa, _gotoxy, putchar, newline + .import gotoxy, putchar, newline .importzp tmp1, cvlinechar _cvlinexy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length and run into _cvline _cvline: @@ -25,6 +24,3 @@ L1: lda #cvlinechar ; Vertical bar dec tmp1 bne L1 L9: rts - - - diff --git a/libsrc/cbm/gotoxy.s b/libsrc/cbm/gotoxy.s index 64c6bd21d..afc9c4d45 100644 --- a/libsrc/cbm/gotoxy.s +++ b/libsrc/cbm/gotoxy.s @@ -4,10 +4,13 @@ ; void gotoxy (unsigned char x, unsigned char y); ; - .export _gotoxy + .export gotoxy, _gotoxy .import popa, plot .importzp CURS_X, CURS_Y +gotoxy: + jsr popa ; Get Y + _gotoxy: sta CURS_Y ; Set Y jsr popa ; Get X diff --git a/libsrc/cbm510/cputc.s b/libsrc/cbm510/cputc.s index bd8c364e8..73d45b422 100644 --- a/libsrc/cbm510/cputc.s +++ b/libsrc/cbm510/cputc.s @@ -8,7 +8,7 @@ .export _cputcxy, _cputc, cputdirect, putchar .export newline, plot - .import popa, _gotoxy + .import gotoxy .import __VIDRAM_START__ .import CURS_X: zp, CURS_Y: zp, CHARCOLOR: zp, RVS: zp .import SCREEN_PTR: zp, CRAM_PTR: zp @@ -22,8 +22,7 @@ _cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, drop x + jsr gotoxy ; Set cursor, drop x and y pla ; Restore C ; Plot a character - also used as internal function diff --git a/libsrc/cbm610/cputc.s b/libsrc/cbm610/cputc.s index 831ead6d6..5888580ac 100644 --- a/libsrc/cbm610/cputc.s +++ b/libsrc/cbm610/cputc.s @@ -9,8 +9,7 @@ .export newline, plot .destructor setsyscursor - .import _gotoxy - .import popa + .import gotoxy .import PLOT .import ktmp: zp, crtc: zp, CURS_X: zp, CURS_Y: zp, RVS: zp @@ -21,8 +20,7 @@ _cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, drop x + jsr gotoxy ; Set cursor, drop x and y pla ; Restore C ; Plot a character - also used as internal function diff --git a/libsrc/conio/cputs.s b/libsrc/conio/cputs.s index 13cf84789..c9ca5df76 100644 --- a/libsrc/conio/cputs.s +++ b/libsrc/conio/cputs.s @@ -6,14 +6,13 @@ ; .export _cputsxy, _cputs - .import popa, _gotoxy, _cputc + .import gotoxy, _cputc .importzp ptr1, tmp1 _cputsxy: sta ptr1 ; Save s for later stx ptr1+1 - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, pop x + jsr gotoxy ; Set cursor, pop x and y jmp L0 ; Same as cputs... _cputs: sta ptr1 ; Save s diff --git a/libsrc/gamate/chline.s b/libsrc/gamate/chline.s index 2d96c9d2f..4d4ebe2dc 100644 --- a/libsrc/gamate/chline.s +++ b/libsrc/gamate/chline.s @@ -6,15 +6,14 @@ ; .export _chlinexy, _chline - .import popa, _gotoxy, cputdirect + .import gotoxy, cputdirect .importzp tmp1 .include "gamate.inc" _chlinexy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length _chline: diff --git a/libsrc/gamate/cputc.s b/libsrc/gamate/cputc.s index c7b11c8c9..84742cb9d 100644 --- a/libsrc/gamate/cputc.s +++ b/libsrc/gamate/cputc.s @@ -5,7 +5,7 @@ .export _cputcxy, _cputc, cputdirect, putchar .export newline, plot - .import popa, _gotoxy + .import gotoxy .import PLOT .import xsize .import fontdata @@ -19,8 +19,7 @@ _cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, drop x + jsr gotoxy ; Set cursor, drop x and y pla ; Restore C ; Plot a character - also used as internal function diff --git a/libsrc/gamate/cvline.s b/libsrc/gamate/cvline.s index b22890815..89f49219a 100644 --- a/libsrc/gamate/cvline.s +++ b/libsrc/gamate/cvline.s @@ -6,15 +6,14 @@ ; .export _cvlinexy, _cvline - .import popa, _gotoxy, putchar, newline + .import gotoxy, putchar, newline .importzp tmp1 .include "gamate.inc" _cvlinexy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length and run into _cvline _cvline: diff --git a/libsrc/gamate/gotoxy.s b/libsrc/gamate/gotoxy.s index 407da1f2f..4a4871444 100644 --- a/libsrc/gamate/gotoxy.s +++ b/libsrc/gamate/gotoxy.s @@ -2,12 +2,15 @@ ; void gotoxy (unsigned char x, unsigned char y); ; - .export _gotoxy + .export gotoxy, _gotoxy .import popa, plot .include "gamate.inc" .include "extzp.inc" +gotoxy: + jsr popa ; Get X + _gotoxy: sta CURS_Y ; Set Y jsr popa ; Get X diff --git a/libsrc/geos-common/conio/cclear.s b/libsrc/geos-common/conio/cclear.s index 9857f70e8..903b9fe92 100644 --- a/libsrc/geos-common/conio/cclear.s +++ b/libsrc/geos-common/conio/cclear.s @@ -7,7 +7,7 @@ ; void cclear (unsigned char length); .export _cclearxy, _cclear - .import popa, _gotoxy, fixcursor + .import gotoxy, fixcursor .importzp cursor_x, cursor_y, cursor_c .include "jumptab.inc" @@ -15,8 +15,7 @@ _cclearxy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length _cclear: diff --git a/libsrc/geos-common/conio/chline.s b/libsrc/geos-common/conio/chline.s index 328d01a01..1cf7a41f0 100644 --- a/libsrc/geos-common/conio/chline.s +++ b/libsrc/geos-common/conio/chline.s @@ -7,7 +7,7 @@ ; void chline (unsigned char length); .export _chlinexy, _chline - .import popa, _gotoxy, fixcursor + .import gotoxy, fixcursor .importzp cursor_x, cursor_y, cursor_c .include "jumptab.inc" @@ -15,8 +15,7 @@ _chlinexy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length _chline: diff --git a/libsrc/geos-common/conio/cputc.s b/libsrc/geos-common/conio/cputc.s index 55674d583..014c2ed0b 100644 --- a/libsrc/geos-common/conio/cputc.s +++ b/libsrc/geos-common/conio/cputc.s @@ -23,8 +23,7 @@ ; UPLINE = ?, KEY_UPARROW = GOTOY, ... .export _cputcxy, _cputc - .import _gotoxy, fixcursor - .import popa + .import gotoxy, fixcursor .import xsize,ysize .importzp cursor_x, cursor_y, cursor_c, cursor_r @@ -34,8 +33,7 @@ _cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, drop x + jsr gotoxy ; Set cursor, drop x and y pla ; Restore C ; Plot a character - also used as internal function diff --git a/libsrc/geos-common/conio/cvline.s b/libsrc/geos-common/conio/cvline.s index ade7f34c9..c12b8764b 100644 --- a/libsrc/geos-common/conio/cvline.s +++ b/libsrc/geos-common/conio/cvline.s @@ -7,7 +7,7 @@ ; void cvline (unsigned char length); .export _cvlinexy, _cvline - .import popa, _gotoxy, fixcursor + .import gotoxy, fixcursor .importzp cursor_x, cursor_y, cursor_r .include "jumptab.inc" @@ -15,8 +15,7 @@ _cvlinexy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length _cvline: diff --git a/libsrc/geos-common/conio/gotoxy.s b/libsrc/geos-common/conio/gotoxy.s index 48b413d5f..0519a7d59 100644 --- a/libsrc/geos-common/conio/gotoxy.s +++ b/libsrc/geos-common/conio/gotoxy.s @@ -8,7 +8,7 @@ ; void gotoy (unsigned char y); ; void gotoxy (unsigned char x, unsigned char y); - .export _gotox, _gotoy, _gotoxy, fixcursor + .export _gotox, _gotoy, gotoxy, _gotoxy, fixcursor .import popa .importzp cursor_x, cursor_y, cursor_c, cursor_r @@ -22,6 +22,9 @@ _gotoy: sta cursor_r jmp fixcursor +gotoxy: + jsr popa + _gotoxy: sta cursor_r jsr popa diff --git a/libsrc/nes/cclear.s b/libsrc/nes/cclear.s index 233c112c6..7a2413826 100644 --- a/libsrc/nes/cclear.s +++ b/libsrc/nes/cclear.s @@ -6,13 +6,12 @@ ; .export _cclearxy, _cclear - .import popa, _gotoxy, cputdirect + .import gotoxy, cputdirect .importzp tmp1 _cclearxy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length and run into _cclear _cclear: diff --git a/libsrc/nes/chline.s b/libsrc/nes/chline.s index 5f6e67c8f..d68a77df9 100644 --- a/libsrc/nes/chline.s +++ b/libsrc/nes/chline.s @@ -6,15 +6,14 @@ ; .export _chlinexy, _chline - .import popa, _gotoxy, cputdirect + .import gotoxy, cputdirect .importzp tmp1 .include "nes.inc" _chlinexy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length _chline: diff --git a/libsrc/nes/cputc.s b/libsrc/nes/cputc.s index 5bcdc7994..209d22db2 100644 --- a/libsrc/nes/cputc.s +++ b/libsrc/nes/cputc.s @@ -9,7 +9,7 @@ .export _cputcxy, _cputc, cputdirect, putchar .export newline .constructor initconio - .import popa, _gotoxy + .import gotoxy .import ppuinit, paletteinit, ppubuf_put .import setcursor @@ -23,8 +23,7 @@ _cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, drop x + jsr gotoxy ; Set cursor, drop x and y pla ; Restore C ; Plot a character - also used as internal function diff --git a/libsrc/nes/cvline.s b/libsrc/nes/cvline.s index 3ab93f34a..d564a25cb 100644 --- a/libsrc/nes/cvline.s +++ b/libsrc/nes/cvline.s @@ -6,15 +6,14 @@ ; .export _cvlinexy, _cvline - .import popa, _gotoxy, putchar, newline + .import gotoxy, putchar, newline .importzp tmp1 .include "nes.inc" _cvlinexy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length and run into _cvline _cvline: diff --git a/libsrc/nes/gotoxy.s b/libsrc/nes/gotoxy.s index a670962fc..3460aad19 100644 --- a/libsrc/nes/gotoxy.s +++ b/libsrc/nes/gotoxy.s @@ -4,21 +4,19 @@ ; void gotoxy (unsigned char x, unsigned char y); ; - .export _gotoxy + .export gotoxy, _gotoxy .import setcursor .import popa .include "nes.inc" -.proc _gotoxy +gotoxy: + jsr popa ; Get Y +_gotoxy: sta CURS_Y ; Set Y jsr popa ; Get X sta CURS_X ; Set X tay ldx CURS_Y jmp setcursor ; Set the cursor position - -.endproc - - diff --git a/libsrc/osic1p/cclear.s b/libsrc/osic1p/cclear.s index 2036c38e0..f7e9b2984 100644 --- a/libsrc/osic1p/cclear.s +++ b/libsrc/osic1p/cclear.s @@ -9,13 +9,12 @@ ; .export _cclearxy, _cclear - .import popa, _gotoxy, cputdirect + .import gotoxy, cputdirect .importzp tmp1 _cclearxy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length and run into _cclear _cclear: diff --git a/libsrc/osic1p/chline.s b/libsrc/osic1p/chline.s index be40d40af..ae2df5014 100644 --- a/libsrc/osic1p/chline.s +++ b/libsrc/osic1p/chline.s @@ -9,13 +9,12 @@ ; .export _chlinexy, _chline - .import popa, _gotoxy, cputdirect + .import gotoxy, cputdirect .importzp tmp1 _chlinexy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length _chline: diff --git a/libsrc/osic1p/cvline.s b/libsrc/osic1p/cvline.s index 84e5a45bf..7a393bdc8 100644 --- a/libsrc/osic1p/cvline.s +++ b/libsrc/osic1p/cvline.s @@ -8,13 +8,12 @@ ; .export _cvlinexy, _cvline - .import popa, _gotoxy, putchar, newline + .import gotoxy, putchar, newline .importzp tmp1 _cvlinexy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length and run into _cvline _cvline: diff --git a/libsrc/osic1p/gotoxy.s b/libsrc/osic1p/gotoxy.s index f76537349..b9666a722 100644 --- a/libsrc/osic1p/gotoxy.s +++ b/libsrc/osic1p/gotoxy.s @@ -6,10 +6,13 @@ ; ; void gotoxy (unsigned char x, unsigned char y); ; - .export _gotoxy + .export gotoxy, _gotoxy .import popa, plot .include "extzp.inc" +gotoxy: + jsr popa ; Get Y + _gotoxy: sta CURS_Y ; Set Y jsr popa ; Get X diff --git a/libsrc/osic1p/osiscreen.inc b/libsrc/osic1p/osiscreen.inc index 66c5e9fb0..fc8324781 100644 --- a/libsrc/osic1p/osiscreen.inc +++ b/libsrc/osic1p/osiscreen.inc @@ -73,8 +73,7 @@ ScrollLength = (ScrHeight - 1) * ScrollDist _cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, drop x + jsr gotoxy ; Set cursor, drop x and y pla ; Restore C ; Plot a character - also used as internal function @@ -157,7 +156,7 @@ putchar: .macro osi_screen_funcs ScrBase, ScrRamSize, ScrFirstChar, \ ScrWidth, ScrHeight, ScrollDist - .import popa, _gotoxy + .import gotoxy .import _memmove, _memset, pushax .importzp ptr1 diff --git a/libsrc/pce/chline.s b/libsrc/pce/chline.s index 8bf8f1626..3c6589375 100644 --- a/libsrc/pce/chline.s +++ b/libsrc/pce/chline.s @@ -6,15 +6,14 @@ ; .export _chlinexy, _chline - .import popa, _gotoxy, cputdirect + .import gotoxy, cputdirect .importzp tmp1 .include "pce.inc" _chlinexy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length _chline: diff --git a/libsrc/pce/cputc.s b/libsrc/pce/cputc.s index 8d1cec8eb..cfe6a1a27 100644 --- a/libsrc/pce/cputc.s +++ b/libsrc/pce/cputc.s @@ -5,7 +5,7 @@ .export _cputcxy, _cputc, cputdirect, putchar .export newline, plot - .import popa, _gotoxy + .import gotoxy .import PLOT .import xsize @@ -16,8 +16,7 @@ _cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, drop x + jsr gotoxy ; Set cursor, drop x and y pla ; Restore C ; Plot a character - also used as internal function diff --git a/libsrc/pce/cvline.s b/libsrc/pce/cvline.s index abd74a5c7..279c691a9 100644 --- a/libsrc/pce/cvline.s +++ b/libsrc/pce/cvline.s @@ -6,15 +6,14 @@ ; .export _cvlinexy, _cvline - .import popa, _gotoxy, putchar, newline + .import gotoxy, putchar, newline .importzp tmp1 .include "pce.inc" _cvlinexy: pha ; Save the length - jsr popa ; Get y - jsr _gotoxy ; Call this one, will pop params + jsr gotoxy ; Call this one, will pop params pla ; Restore the length and run into _cvline _cvline: diff --git a/libsrc/pce/gotoxy.s b/libsrc/pce/gotoxy.s index fb61646d1..dae9e6e43 100644 --- a/libsrc/pce/gotoxy.s +++ b/libsrc/pce/gotoxy.s @@ -2,12 +2,15 @@ ; void gotoxy (unsigned char x, unsigned char y); ; - .export _gotoxy + .export gotoxy, _gotoxy .import popa, plot .include "pce.inc" .include "extzp.inc" +gotoxy: + jsr popa ; Get Y + _gotoxy: sta CURS_Y ; Set Y jsr popa ; Get X diff --git a/libsrc/pet/cputc.s b/libsrc/pet/cputc.s index f38d2759a..9b2c22323 100644 --- a/libsrc/pet/cputc.s +++ b/libsrc/pet/cputc.s @@ -7,14 +7,13 @@ .export _cputcxy, _cputc, cputdirect, putchar .export newline, plot - .import popa, _gotoxy + .import gotoxy .include "pet.inc" _cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, drop x + jsr gotoxy ; Set cursor, drop x and y pla ; Restore C ; Plot a character - also used as internal function diff --git a/libsrc/plus4/cputc.s b/libsrc/plus4/cputc.s index a83a9c60b..49b3a84dd 100644 --- a/libsrc/plus4/cputc.s +++ b/libsrc/plus4/cputc.s @@ -7,7 +7,7 @@ .export _cputcxy, _cputc, cputdirect, putchar .export newline, plot - .import popa, _gotoxy + .import gotoxy .import PLOT .include "plus4.inc" @@ -15,8 +15,7 @@ _cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, drop x + jsr gotoxy ; Set cursor, drop x and y pla ; Restore C ; Plot a character - also used as internal function diff --git a/libsrc/vic20/cputc.s b/libsrc/vic20/cputc.s index 7a1014c1c..43aacdae3 100644 --- a/libsrc/vic20/cputc.s +++ b/libsrc/vic20/cputc.s @@ -7,7 +7,7 @@ .export _cputcxy, _cputc, cputdirect, putchar .export newline, plot - .import popa, _gotoxy + .import gotoxy .import PLOT .include "vic20.inc" @@ -15,8 +15,7 @@ _cputcxy: pha ; Save C - jsr popa ; Get Y - jsr _gotoxy ; Set cursor, drop x + jsr gotoxy ; Set cursor, drop x and y pla ; Restore C ; Plot a character - also used as internal function From 27841c7b40269cc3dbbe37f198f1177c97c2a78b Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Mon, 6 Jun 2016 22:45:20 +0200 Subject: [PATCH 0092/2161] Some Atari runtime library fixes. * libsrc/atari/ucase_fn.s: Fix handling if input parameter 'tmp2' is 0. * libsrc/atari/open.s: Set 'tmp2' parameter for 'ucase_fn' if DEFAULT_DEVICE is not defined. --- libsrc/atari/open.s | 4 +++- libsrc/atari/ucase_fn.s | 10 ++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/libsrc/atari/open.s b/libsrc/atari/open.s index 2188257cb..d5ff4ca52 100644 --- a/libsrc/atari/open.s +++ b/libsrc/atari/open.s @@ -93,8 +93,10 @@ cont: ldy #3 .ifdef UCASE_FILENAME .ifdef DEFAULT_DEVICE ldy #$80 - sty tmp2 ; set flag for ucase_fn +.else + ldy #$00 .endif + sty tmp2 ; set flag for ucase_fn jsr ucase_fn bcc ucok1 invret: lda #<EINVAL ; file name is too long diff --git a/libsrc/atari/ucase_fn.s b/libsrc/atari/ucase_fn.s index e53750e29..f7f03915d 100644 --- a/libsrc/atari/ucase_fn.s +++ b/libsrc/atari/ucase_fn.s @@ -40,7 +40,9 @@ stx ptr4+1 .ifdef DEFAULT_DEVICE - ; bit #0 of tmp2 is used as a flag whether device name is present in passed string (1 = present, 0 = not present) + lda tmp2 + beq hasdev ; don't fiddle with device part + ; bit #0 of tmp2 is used as an additional flag whether device name is present in passed string (1 = present, 0 = not present) ldy #1 inc tmp2 ; initialize flag: device present lda #':' @@ -81,11 +83,11 @@ copy_end: .ifdef DEFAULT_DEVICE lda #1 - bit tmp2 + bit tmp2 ; is a device present in the string? bne hasdev2 ; yes, don't prepend something - bpl hasdev2 + bpl hasdev2 ; check input parameter (tmp2 != $80) - ldy #128+3 ; no, prepend "D:" (or other device) + ldy #128+3 ; no, prepend "Dn:" (__defdev) sty tmp3 ; adjust stack size used ldy #3 jsr subysp ; adjust stack pointer From c7874b9f60cebee3f6ce237cebf2aa8ecfad0f36 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 7 Jun 2016 00:42:51 +0200 Subject: [PATCH 0093/2161] Add Atari version of of doesclrscrafterexit(). - Update documentation. - Update atari.h and apple2.h header files. - Adapt Atari test/target programs. - Fix a typo in "div" entry in funcref.sgml. --- doc/funcref.sgml | 58 ++++++++++++++++++++------------- include/apple2.h | 3 ++ include/atari.h | 13 ++++---- libsrc/atari/doesclrscr.s | 19 +++++++++++ libsrc/atari/is_cmdline_dos.s | 11 ++----- libsrc/atari/targetutil/w2cas.c | 2 +- testcode/lib/atari/defdev.c | 2 +- testcode/lib/atari/mem.c | 2 +- 8 files changed, 71 insertions(+), 39 deletions(-) create mode 100644 libsrc/atari/doesclrscr.s diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 9bd4a3595..5b529b822 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -949,27 +949,7 @@ id="malloc" name="malloc"> may still return <tt/NULL/. <tag/Declaration/<tt/unsigned char _is_cmdline_dos (void);/ <tag/Description/The function returns 0 if the DOS doesn't support command line arguments. It returns 1 if it does. -<tag/Notes/<itemize> -<item>Many Atari DOSes which don't support command line arguments immediately clear the screen -and display their menu after a program exits. Therefore it might be difficult to read -the last messages printed by the program prior to its exit. This function can be used -to decide if a delay or wait for a key press should be executed when then program -exits. -</itemize> <tag/Availability/cc65 (<tt/atari/ and <tt/atarixl/ platforms) -<tag/Example/<verb> -/* Hello World for Atari */ -#include <stdio.h> -#include <unistd.h> -#include <atari.h> -int main(void) -{ - printf("Hello World\n"); - if (! _is_cmdline_dos()) - sleep(5); - return 0; -} -</verb> </descrip> </quote> @@ -2572,8 +2552,8 @@ used in presence of a prototype. <descrip> <tag/Function/Divide two ints and return quotient and remainder. <tag/Header/<tt/<ref id="stdlib.h" name="stdlib.h">/ -<tag/Declaration/<tt/div_t __fastcall__ div (int numer, int denom);/ -<tag/Description/<tt/div/ divides <tt/numer/ by <tt/denom/ and returns the +<tag/Declaration/<tt/div_t __fastcall__ div (int number, int denom);/ +<tag/Description/<tt/div/ divides <tt/number/ by <tt/denom/ and returns the quotient and remainder in a <tt/div_t/ structure. <tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only @@ -2587,6 +2567,40 @@ ldiv </quote> +<sect1>doesclrscrafterexit<label id="doesclrscrafterexit"><p> + +<quote> +<descrip> +<tag/Function/Determines whether the screen is going to be cleared after program exit. +<tag/Header/<tt/<ref id="atari.h" name="atari.h">, <ref id="apple2.h" name="apple2.h">/ +<tag/Declaration/<tt/unsigned char doesclrscrafterexit (void);/ +<tag/Description/The function returns 0 if the screen won't be cleared immediately after +program termination. It returns 1 if it will. +<tag/Notes/<itemize> +<item>Some systems, maybe depending on configuration, immediately clear the screen +after a program exits. Therefore it might be difficult to read +the last messages printed by the program prior to its exit. This function can be used +to decide if a delay or wait for a key press should be executed when then program +exits. +</itemize> +<tag/Availability/cc65 (<tt/atari/, <tt/atarixl/, <tt/apple2/, and <tt/apple2enh/ platforms) +<tag/Example/<verb> +/* Hello World */ +#include <stdio.h> +#include <unistd.h> +#include <atari.h> +int main(void) +{ + printf("Hello World\n"); + if (doesclrscrafterexit()) + sleep(5); + return 0; +} +</verb> +</descrip> +</quote> + + <sect1>em_commit<label id="em_commit"><p> <quote> diff --git a/include/apple2.h b/include/apple2.h index a1b094d4d..97a2f124f 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -177,6 +177,9 @@ unsigned char get_ostype (void); void rebootafterexit (void); /* Reboot machine after program termination has completed. */ +unsigned char doesclrscrafterexit (void); +/* Will the screen automatically be cleared after program termination. */ + #define ser_apple2_slot(num) ser_ioctl (0, (void*) (num)) /* Select a slot number from 1 to 7 prior to ser_open. ** The default slot number is 2. diff --git a/include/atari.h b/include/atari.h index fa99fca20..76684c624 100644 --- a/include/atari.h +++ b/include/atari.h @@ -161,12 +161,13 @@ extern void __fastcall__ _scroll (signed char numlines); /* numlines < 0 scrolls down */ /* 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 */ +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 */ +extern unsigned char doesclrscrafterexit (void); /* will DOS clear the screen after program termination */ /* global variables */ extern unsigned char _dos_type; /* the DOS flavour */ diff --git a/libsrc/atari/doesclrscr.s b/libsrc/atari/doesclrscr.s new file mode 100644 index 000000000..c085faebf --- /dev/null +++ b/libsrc/atari/doesclrscr.s @@ -0,0 +1,19 @@ +; +; Christian Groessler, June-2016 +; +; unsigned char doesclrscr(void); +; +; returns 0/1 if after program termination the screen isn't/is cleared +; + + .export _doesclrscrafterexit + .import __dos_type + .include "atari.inc" + +_doesclrscrafterexit: + ldx #0 + lda __dos_type + cmp #MAX_DOS_WITH_CMDLINE + 1 + txa + rol a + rts diff --git a/libsrc/atari/is_cmdline_dos.s b/libsrc/atari/is_cmdline_dos.s index 71b35fbad..b85cb3ca7 100644 --- a/libsrc/atari/is_cmdline_dos.s +++ b/libsrc/atari/is_cmdline_dos.s @@ -7,14 +7,9 @@ ; .export __is_cmdline_dos - .import __dos_type - .include "atari.inc" + .import _doesclrscrafterexit __is_cmdline_dos: - ldx #0 - lda __dos_type - cmp #MAX_DOS_WITH_CMDLINE + 1 - txa - rol a - eor #$01 + jsr _doesclrscrafterexit ; currently (unless a DOS behaving differently is popping up) + eor #$01 ; we can get by with the inverse of _doesclrscrafterexit rts diff --git a/libsrc/atari/targetutil/w2cas.c b/libsrc/atari/targetutil/w2cas.c index c95ff7ba5..c1dd0cfcc 100644 --- a/libsrc/atari/targetutil/w2cas.c +++ b/libsrc/atari/targetutil/w2cas.c @@ -35,7 +35,7 @@ static struct __iocb *findfreeiocb(void) static void exitfn(void) { /* if DOS will automatically clear the screen, after the program exits, wait for a keypress... */ - if (! _is_cmdline_dos()) + if (doesclrscrafterexit()) cgetc(); } diff --git a/testcode/lib/atari/defdev.c b/testcode/lib/atari/defdev.c index 06ddb6365..851d87106 100644 --- a/testcode/lib/atari/defdev.c +++ b/testcode/lib/atari/defdev.c @@ -13,6 +13,6 @@ extern char _defdev[]; int main(void) { printf("default device: %s\n", _defdev); - if (! _is_cmdline_dos()) cgetc(); + if (doesclrscrafterexit()) cgetc(); return 0; } diff --git a/testcode/lib/atari/mem.c b/testcode/lib/atari/mem.c index a8d50cf30..04978c77e 100644 --- a/testcode/lib/atari/mem.c +++ b/testcode/lib/atari/mem.c @@ -41,6 +41,6 @@ int main(void) printf(" sp: $%04X (stack ptr)\n", getsp()); if (allocmem) free(allocmem); - if (! _is_cmdline_dos()) cgetc(); + if (doesclrscrafterexit()) cgetc(); return(0); } From 346d88a6a77fd0fa7bd5972991e101640d97f040 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 7 Jun 2016 12:05:28 +0200 Subject: [PATCH 0094/2161] Add issues from pull request #307. --- doc/funcref.sgml | 12 ++++++------ include/apple2.h | 3 --- include/atari.h | 1 - include/cc65.h | 5 +++++ libsrc/atari/targetutil/w2cas.c | 12 ++++-------- libsrc/common/doesclrscr.s | 14 ++++++++++++++ testcode/lib/atari/defdev.c | 1 + testcode/lib/atari/mem.c | 1 + 8 files changed, 31 insertions(+), 18 deletions(-) create mode 100644 libsrc/common/doesclrscr.s diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 5b529b822..ff32a2960 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -2552,8 +2552,8 @@ used in presence of a prototype. <descrip> <tag/Function/Divide two ints and return quotient and remainder. <tag/Header/<tt/<ref id="stdlib.h" name="stdlib.h">/ -<tag/Declaration/<tt/div_t __fastcall__ div (int number, int denom);/ -<tag/Description/<tt/div/ divides <tt/number/ by <tt/denom/ and returns the +<tag/Declaration/<tt/div_t __fastcall__ div (int numer, int denom);/ +<tag/Description/<tt/div/ divides <tt/numer/ by <tt/denom/ and returns the quotient and remainder in a <tt/div_t/ structure. <tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only @@ -2574,8 +2574,8 @@ ldiv <tag/Function/Determines whether the screen is going to be cleared after program exit. <tag/Header/<tt/<ref id="atari.h" name="atari.h">, <ref id="apple2.h" name="apple2.h">/ <tag/Declaration/<tt/unsigned char doesclrscrafterexit (void);/ -<tag/Description/The function returns 0 if the screen won't be cleared immediately after -program termination. It returns 1 if it will. +<tag/Description/The function returns zero if the screen won't be cleared immediately after +program termination. It returns a non-zero value if it will. <tag/Notes/<itemize> <item>Some systems, maybe depending on configuration, immediately clear the screen after a program exits. Therefore it might be difficult to read @@ -2583,12 +2583,12 @@ the last messages printed by the program prior to its exit. This function can be to decide if a delay or wait for a key press should be executed when then program exits. </itemize> -<tag/Availability/cc65 (<tt/atari/, <tt/atarixl/, <tt/apple2/, and <tt/apple2enh/ platforms) +<tag/Availability/cc65 <tag/Example/<verb> /* Hello World */ #include <stdio.h> #include <unistd.h> -#include <atari.h> +#include <cc65.h> int main(void) { printf("Hello World\n"); diff --git a/include/apple2.h b/include/apple2.h index 97a2f124f..a1b094d4d 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -177,9 +177,6 @@ unsigned char get_ostype (void); void rebootafterexit (void); /* Reboot machine after program termination has completed. */ -unsigned char doesclrscrafterexit (void); -/* Will the screen automatically be cleared after program termination. */ - #define ser_apple2_slot(num) ser_ioctl (0, (void*) (num)) /* Select a slot number from 1 to 7 prior to ser_open. ** The default slot number is 2. diff --git a/include/atari.h b/include/atari.h index 76684c624..eedd814e0 100644 --- a/include/atari.h +++ b/include/atari.h @@ -167,7 +167,6 @@ 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 */ -extern unsigned char doesclrscrafterexit (void); /* will DOS clear the screen after program termination */ /* global variables */ extern unsigned char _dos_type; /* the DOS flavour */ diff --git a/include/cc65.h b/include/cc65.h index 4f9f3067f..9b7b69a0e 100644 --- a/include/cc65.h +++ b/include/cc65.h @@ -85,6 +85,11 @@ int __fastcall__ cc65_cos (unsigned x); ** is in 8.8 fixed point format, which means that 1.0 = $100 and -1.0 = $FF00. */ +unsigned char doesclrscrafterexit (void); +/* Indicates whether the screen automatically be cleared after program +** termination. +*/ + /* End of cc65.h */ diff --git a/libsrc/atari/targetutil/w2cas.c b/libsrc/atari/targetutil/w2cas.c index c1dd0cfcc..1381a49a0 100644 --- a/libsrc/atari/targetutil/w2cas.c +++ b/libsrc/atari/targetutil/w2cas.c @@ -14,6 +14,7 @@ #include <errno.h> #include <6502.h> #include <atari.h> +#include <cc65.h> #include <conio.h> static int verbose = 1; @@ -32,13 +33,6 @@ static struct __iocb *findfreeiocb(void) return NULL; } -static void exitfn(void) -{ - /* if DOS will automatically clear the screen, after the program exits, wait for a keypress... */ - if (doesclrscrafterexit()) - cgetc(); -} - int main(int argc, char **argv) { char *filename, *x; @@ -50,7 +44,9 @@ int main(int argc, char **argv) struct __iocb *iocb = findfreeiocb(); int iocb_num; - atexit(exitfn); + /* if DOS will automatically clear the screen after the program exits, wait for a keypress... */ + if (doesclrscrafterexit()) + atexit((void (*)(void))cgetc); if (! iocb) { fprintf(stderr, "couldn't find a free iocb\n"); diff --git a/libsrc/common/doesclrscr.s b/libsrc/common/doesclrscr.s new file mode 100644 index 000000000..71f7ab70e --- /dev/null +++ b/libsrc/common/doesclrscr.s @@ -0,0 +1,14 @@ +; +; Christian Groessler, June-2016 +; +; unsigned char doesclrscr(void); +; +; returns 0/1 if after program termination the screen isn't/is cleared +; + + .export _doesclrscrafterexit + +_doesclrscrafterexit: + ldx #$00 + txa + rts diff --git a/testcode/lib/atari/defdev.c b/testcode/lib/atari/defdev.c index 851d87106..9b14e97fc 100644 --- a/testcode/lib/atari/defdev.c +++ b/testcode/lib/atari/defdev.c @@ -7,6 +7,7 @@ #include <stdio.h> #include <conio.h> #include <atari.h> +#include <cc65.h> extern char _defdev[]; diff --git a/testcode/lib/atari/mem.c b/testcode/lib/atari/mem.c index 04978c77e..bc70aded6 100644 --- a/testcode/lib/atari/mem.c +++ b/testcode/lib/atari/mem.c @@ -8,6 +8,7 @@ #include <stdlib.h> #include <conio.h> #include <atari.h> +#include <cc65.h> extern int getsp(void); /* comes from ../getsp.s */ From 308767cbae129214654c5f6c3294f0b2a0c8af38 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 7 Jun 2016 12:22:25 +0200 Subject: [PATCH 0095/2161] fix wrong header reference in doesclrscrafterexit() description --- doc/funcref.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index ff32a2960..d665ce0b9 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -2572,7 +2572,7 @@ ldiv <quote> <descrip> <tag/Function/Determines whether the screen is going to be cleared after program exit. -<tag/Header/<tt/<ref id="atari.h" name="atari.h">, <ref id="apple2.h" name="apple2.h">/ +<tag/Header/<tt/<ref id="cc65.h" name="cc65.h">/ <tag/Declaration/<tt/unsigned char doesclrscrafterexit (void);/ <tag/Description/The function returns zero if the screen won't be cleared immediately after program termination. It returns a non-zero value if it will. From 5705d0b55b433f4147b4efaeada23debb1a51e4d Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 7 Jun 2016 15:05:00 +0200 Subject: [PATCH 0096/2161] Use 'return0' for default 'doesclrscrafterexit()' implementation in libsrc/common. Fix include/atari.h formatting. --- include/atari.h | 12 ++++++------ libsrc/common/doesclrscr.s | 8 +++----- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/include/atari.h b/include/atari.h index eedd814e0..fa99fca20 100644 --- a/include/atari.h +++ b/include/atari.h @@ -161,12 +161,12 @@ extern void __fastcall__ _scroll (signed char numlines); /* numlines < 0 scrolls down */ /* 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 */ +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 */ /* global variables */ extern unsigned char _dos_type; /* the DOS flavour */ diff --git a/libsrc/common/doesclrscr.s b/libsrc/common/doesclrscr.s index 71f7ab70e..49ce2fd12 100644 --- a/libsrc/common/doesclrscr.s +++ b/libsrc/common/doesclrscr.s @@ -6,9 +6,7 @@ ; returns 0/1 if after program termination the screen isn't/is cleared ; - .export _doesclrscrafterexit + .export _doesclrscrafterexit + .import return0 -_doesclrscrafterexit: - ldx #$00 - txa - rts +_doesclrscrafterexit = return0 From 083598599956b7f26ea1555ee443cf83f1c7585a Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 8 Jun 2016 21:05:00 -0400 Subject: [PATCH 0097/2161] Updated the function reference document. * Added doesclrscrafterexit() to cc65.h's list. * Added header-file function lists for some new target platforms. --- doc/funcref.sgml | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index d665ce0b9..64e519238 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -3,7 +3,7 @@ <article> <title>cc65 function reference <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2015-07-21 +<date>2016-06-08 <abstract> cc65 is a C compiler for 6502 based systems. This function reference describes @@ -207,7 +207,7 @@ function. <sect1><tt/cc65.h/<label id="cc65.h"><p> -<!-- <itemize> --> +<itemize> <!-- <item><ref id="cc65_cos" name="cc65_cos"> --> <!-- <item><ref id="cc65_idiv32by16r16" name="cc65_idiv32by16r16"> --> <!-- <item><ref id="cc65_imul16x16r32" name="cc65_imul16x16r32"> --> @@ -217,7 +217,8 @@ function. <!-- <item><ref id="cc65_umul16x16r32" name="cc65_umul16x16r32"> --> <!-- <item><ref id="cc65_umul16x8r32" name="cc65_umul16x8r32"> --> <!-- <item><ref id="cc65_umul8x8r16" name="cc65_umul8x8r16"> --> -<!-- </itemize> --> +<item><ref id="doesclrscrafterexit" name="doesclrscrafterexit"> +</itemize> (incomplete) @@ -344,6 +345,16 @@ function. </itemize> +<sect1><tt/gamate.h/<label id="gamate.h"><p> + +<!-- <itemize> --> +<!-- <item><ref id="get_tv" name="get_tv"> --> +<!-- <item><ref id="waitvblank" name="waitvblank"> --> +<!-- </itemize> --> + +(incomplete) + + <sect1><tt/geos.h/<label id="geos.h"><p> (incomplete) @@ -430,6 +441,16 @@ url="http://www.6502.org/users/andre/o65/fileformat.html" name="the o65 format"> 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="waitvblank" name="waitvblank"> --> +<!-- </itemize> --> + +(incomplete) + + <sect1><tt/peekpoke.h/<label id="peekpoke.h"><p> <itemize> @@ -440,6 +461,16 @@ It does not declare any functions. </itemize> +<sect1><tt/pen.h/<label id="pen.h"><p> + +<!-- <itemize> --> +<!-- <item><ref id="pen_adjust" name="pen_adjust"> --> +<!-- <item><ref id="pen_calibrate" name="pen_calibrate"> --> +<!-- </itemize> --> + +(incomplete) + + <sect1><tt/pet.h/<label id="pet.h"><p> (incomplete) From 573381a340decd6a533e9f9aefaff908772b123c Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 11 Jun 2016 06:43:19 -0400 Subject: [PATCH 0098/2161] Allowed character code zero to be remapped with other character codes. --- doc/ca65.sgml | 11 ++++--- doc/cc65.sgml | 68 ++++++++++++++++++++++++------------------- src/ca65/pseudo.c | 8 ++--- src/cc65/error.c | 8 +++-- src/cc65/error.h | 3 +- src/cc65/pragma.c | 22 +++++++------- src/cc65/pragma.h | 8 ++--- src/common/tgttrans.c | 2 +- 8 files changed, 71 insertions(+), 59 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 6ea17d335..050e75628 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -4,7 +4,7 @@ <title>ca65 Users Guide <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2015-11-17 +<date>2016-06-11 <abstract> ca65 is a powerful macro assembler for the 6502, 65C02, and 65816 CPUs. It is @@ -2170,16 +2170,15 @@ Here's a list of all control commands and a description, what they do: <sect1><tt>.CHARMAP</tt><label id=".CHARMAP"><p> Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 1..255), + numbers. The first one is the index of the source character (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all - character and string constants when they generate output, and overrides a - mapping table specified with the <tt><ref id="option-t" name="-t"></tt> + character and string constants <em/when/ they generate output; and, overrides + a mapping table specified with the <tt><ref id="option-t" name="-t"></tt> command line switch. Example: - <tscreen><verb> - .charmap $41, $61 ; Map 'A' to 'a' + .charmap $41, $61 ; Map 'A' to 'a' </verb></tscreen> diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 8346bac6b..3e59d4cf0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -4,7 +4,7 @@ <title>cc65 Users Guide <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:gregdk@users.sf.net" name="Greg King"> -<date>2016-04-22 +<date>2016-06-11 <abstract> cc65 is a C compiler for 6502 targets. It supports several 6502 based home @@ -478,15 +478,15 @@ Here is a description of all the command line options: <label id="option-W"> - <tag><tt>-W name[,name]</tt></tag> + <tag><tt>-W name[,name,...]</tt></tag> This option allows to control warnings generated by the compiler. It is - followed by a comma separated list of warnings that should be enabled or + followed by a comma-separated list of warnings that should be enabled or disabled. To disable a warning, its name is prefixed by a minus sign. If no such prefix exists, or the name is prefixed by a plus sign, the warning is enabled. - The following warning names are currently recognized: + The following warning names currently are recognized: <descrip> <tag><tt/const-comparison/</tag> Warn if the result of a comparison is constant. @@ -494,10 +494,13 @@ Here is a description of all the command line options: Treat all warnings as errors. <tag><tt/no-effect/</tag> Warn about statements that don't have an effect. + <tag><tt/remap-zero/</tag> + Warn about a <tt/<ref id="pragma-charmap" name="#pragma charmap()">/ + that changes a character's code number from/to 0x00. <tag><tt/struct-param/</tag> Warn when passing structs by value. <tag><tt/unknown-pragma/</tag> - Warn about known #pragmas. + Warn about #pragmas that aren't recognized by cc65. <tag><tt/unused-label/</tag> Warn about unused labels. <tag><tt/unused-param/</tag> @@ -506,11 +509,11 @@ Here is a description of all the command line options: Warn about unused variables. </descrip> - The full list of available warning names may be retrieved by using the + The full list of available warning names can be retrieved by using the option <tt><ref id="option-list-warnings" name="--list-warnings"></tt>. - You may also use <tt><ref id="pragma-warn" name="#pragma warn"></tt> to - control this setting for smaller pieces of code from within your code. + You may use also <tt><ref id="pragma-warn" name="#pragma warn"></tt> to + control this setting, for smaller pieces of code, from within your sources. </descrip><p> @@ -931,34 +934,38 @@ parameter with the <tt/#pragma/. <sect1><tt>#pragma charmap (<index>, <code>)</tt><label id="pragma-charmap"><p> Each literal string and each literal character in the source is translated - by use of a translation table. This translation table is preset when the - compiler is started depending on the target system, for example to map - ISO-8859-1 characters into PETSCII if the target is a commodore machine. + by use of a translation table. That translation table is preset when the + compiler is started, depending on the target system; for example, to map + ISO-8859-1 characters into PETSCII if the target is a Commodore machine. This pragma allows to change entries in the translation table, so the translation for individual characters, or even the complete table may be - adjusted. + adjusted. Both arguments are assumed to be unsigned characters with a valid + range of 0-255. - Both arguments are assumed to be unsigned characters with a valid range of - 1-255. - - Beware of two pitfalls: - - <itemize> - <item>The character index is actually the code of the character in the - C source, so character mappings do always depend on the source - character set. This means that <tt/#pragma charmap/ is not - portable -- it depends on the build environment. - <item>While it is possible to use character literals as indices, the - result may be somewhat unexpected, since character literals are - itself translated. For this reason I would suggest to avoid - character literals and use numeric character codes instead. - </itemize> + Beware of some pitfalls: + <itemize> + <item>The character index is actually the code of the character in the + C source; so, character mappings do always depend on the source + character set. That means that <tt/#pragma charmap()/ is not + portable -- it depends on the build environment. + <item>While it is possible to use character literals as indices, the + result may be somewhat unexpected, since character literals are + themselves translated. For that reason, I would suggest to avoid + character literals, and use numeric character codes instead. + <item>It is risky to change index <tt/0x00/, because string functions depend + on it. If it is changed, then the <tt/'\0'/ at the end of string + literals will become non-zero. Functions that are used on those + literals won't stop at the end of them. cc65 will warn you if you do + change that code number. You can turn off that <tt/remap-zero/ warning + if you are certain that you know what you are doing (see <tt/<ref + id="pragma-warn" name="#pragma warn()">/). + </itemize> Example: <tscreen><verb> - /* Use a space wherever an 'a' occurs in ISO-8859-1 source */ - #pragma charmap (0x61, 0x20); + /* Use a space wherever an 'a' occurs in ISO-8859-1 source */ + #pragma charmap (0x61, 0x20); </verb></tscreen> @@ -1129,7 +1136,7 @@ parameter with the <tt/#pragma/. Switch compiler warnings on or off. "name" is the name of a warning (see the <tt/<ref name="-W" id="option-W">/ compiler option for a list). The name is - either followed by "pop", which restores the last pushed state, or by "on" or + followed either by "pop", which restores the last pushed state, or by "on" or "off", optionally preceeded by "push" to push the current state before changing it. @@ -1144,6 +1151,7 @@ parameter with the <tt/#pragma/. #pragma warn (unused-param, pop) </verb></tscreen> + <sect1><tt>#pragma writable-strings ([push,] on|off)</tt><label id="pragma-writable-strings"><p> Changes the storage location of string literals. For historical reasons, diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 4db780318..250ceecc9 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -618,16 +618,16 @@ static void DoCase (void) static void DoCharMap (void) -/* Allow custome character mappings */ +/* Allow custom character mappings */ { long Index; long Code; /* Read the index as numerical value */ Index = ConstExpression (); - if (Index <= 0 || Index > 255) { + if (Index < 0 || Index > 255) { /* Value out of range */ - ErrorSkip ("Range error"); + ErrorSkip ("Index range error"); return; } @@ -638,7 +638,7 @@ static void DoCharMap (void) Code = ConstExpression (); if (Code < 0 || Code > 255) { /* Value out of range */ - ErrorSkip ("Range error"); + ErrorSkip ("Code range error"); return; } diff --git a/src/cc65/error.c b/src/cc65/error.c index 5218d195c..858a80826 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -66,11 +66,12 @@ IntStack WarningsAreErrors = INTSTACK(0); /* Treat warnings as errors */ /* Warn about: */ IntStack WarnConstComparison= INTSTACK(1); /* - constant comparison results */ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ +IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ IntStack WarnStructParam = INTSTACK(1); /* - structs passed by val */ +IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -79,10 +80,11 @@ struct WarnMapEntry { const char* Name; }; static WarnMapEntry WarnMap[] = { - /* Keep sorted, even if this isn't used for now */ - { &WarningsAreErrors, "error" }, + /* Keep names sorted, even if it isn't used for now */ { &WarnConstComparison, "const-comparison" }, + { &WarningsAreErrors, "error" }, { &WarnNoEffect, "no-effect" }, + { &WarnRemapZero, "remap-zero" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, { &WarnUnusedLabel, "unused-label" }, diff --git a/src/cc65/error.h b/src/cc65/error.h index 9aec10c77..97ee09591 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -65,11 +65,12 @@ extern IntStack WarningsAreErrors; /* Treat warnings as errors */ /* Warn about: */ extern IntStack WarnConstComparison; /* - constant comparison results */ extern IntStack WarnNoEffect; /* - statements without an effect */ +extern IntStack WarnRemapZero; /* - remapping character code zero */ extern IntStack WarnStructParam; /* - structs passed by val */ +extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index f42274922..52af1e722 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -453,13 +453,14 @@ static void CharMapPragma (StrBuf* B) return; } if (Index < 1 || Index > 255) { - if (Index == 0) { - /* For groepaz */ - Error ("Remapping 0 is not allowed"); - } else { + if (Index != 0) { Error ("Character index out of range"); + return; + } + /* For groepaz and Christian */ + if (IS_Get (&WarnRemapZero)) { + Warning ("Remapping from 0 is dangerous with string functions"); } - return; } /* Comma follows */ @@ -472,13 +473,14 @@ static void CharMapPragma (StrBuf* B) return; } if (C < 1 || C > 255) { - if (C == 0) { - /* For groepaz */ - Error ("Remapping 0 is not allowed"); - } else { + if (C != 0) { Error ("Character code out of range"); + return; + } + /* For groepaz and Christian */ + if (IS_Get (&WarnRemapZero)) { + Warning ("Remapping to 0 can make string functions stop unexpectedly"); } - return; } /* Remap the character */ diff --git a/src/cc65/pragma.h b/src/cc65/pragma.h index f12dbaa83..d1b94fa23 100644 --- a/src/cc65/pragma.h +++ b/src/cc65/pragma.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@cc65.org */ +/* (C) 1998-2002, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index 95bdf8662..bd2056505 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -124,6 +124,6 @@ void TgtTranslateStrBuf (StrBuf* Buf) void TgtTranslateSet (unsigned Index, unsigned char C) /* Set the translation code for the given character */ { - CHECK (Index > 0 && Index < sizeof (Tab)); + CHECK (Index < sizeof (Tab)); Tab[Index] = C; } From 524813ff609b205ca68b0f90df43236b95a2835e Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 12 Jun 2016 22:54:23 +0200 Subject: [PATCH 0099/2161] Allow to build samples from the main Makefile. --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a10df8db0..808689c82 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: all mostlyclean clean install zip avail unavail bin lib doc +.PHONY: all mostlyclean clean install zip avail unavail bin lib doc samples .SUFFIXES: @@ -17,6 +17,9 @@ lib: doc: @$(MAKE) -C doc --no-print-directory $@ +samples: + @$(MAKE) -C samples --no-print-directory $@ + %65: @$(MAKE) -C src --no-print-directory $@ From 98973ee90127b944fe5947e97f080d0ee4d092c3 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 12 Jun 2016 22:56:26 +0200 Subject: [PATCH 0100/2161] Avoid warnings on monochrom targets (and remove unnecessary code). --- samples/hello.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/samples/hello.c b/samples/hello.c index 385112367..854e9a4b4 100644 --- a/samples/hello.c +++ b/samples/hello.c @@ -34,11 +34,10 @@ int main (void) { unsigned char XSize, YSize; - /* Set screen colors, hide the cursor */ - textcolor (COLOR_WHITE); - bordercolor (COLOR_BLACK); - bgcolor (COLOR_BLACK); - cursor (0); + /* Set screen colors */ + (void) textcolor (COLOR_WHITE); + (void) bordercolor (COLOR_BLACK); + (void) bgcolor (COLOR_BLACK); /* Clear the screen, put cursor in upper left corner */ clrscr (); From 271b65aa70d85b0d1e30c798c2fe270760538f6b Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 12 Jun 2016 23:48:19 +0200 Subject: [PATCH 0101/2161] Added hint on how to quit program. --- samples/ascii.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/ascii.c b/samples/ascii.c index fd293e213..0d191c966 100644 --- a/samples/ascii.c +++ b/samples/ascii.c @@ -58,7 +58,7 @@ int main(void) { /* This prompt fits on the VIC-20's narrow screen. */ - PRINT("Type characters to see\r\ntheir hexadecimal code\r\nnumbers:\r\n\n"); + PRINT("Type characters to see\r\ntheir hexadecimal code\r\nnumbers - 'Q' quits:\r\n\n"); screensize(&width, &height); /* get the screen's dimensions */ width /= 6; /* get number of codes on a line */ cursor(true); From 94ba9575ec4c9a0b2d164ccba93e9685d92f71f3 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Mon, 13 Jun 2016 20:40:01 +0200 Subject: [PATCH 0102/2161] Implement exec() for Atari XDOS. - Adds new ENOEXEC error code, also used by Apple2 targets. - Maximum command line length is 40, incl. program name. This is an XDOS restriction. - testcode/lib/tinyshell.c has been extended to be able to run programs. --- asminc/atari.inc | 5 + asminc/errno.inc | 1 + include/errno.h | 3 +- libsrc/apple2/oserror.s | 2 +- libsrc/atari/crt0.s | 8 +- libsrc/atari/exec.s | 207 +++++++++++++++++++++++++++++++++++++++ libsrc/atari/oserror.s | 2 +- libsrc/common/errormsg.c | 1 + testcode/lib/tinyshell.c | 44 +++++++-- 9 files changed, 260 insertions(+), 13 deletions(-) create mode 100644 libsrc/atari/exec.s diff --git a/asminc/atari.inc b/asminc/atari.inc index f7a7ab223..453c370f4 100644 --- a/asminc/atari.inc +++ b/asminc/atari.inc @@ -183,6 +183,7 @@ FNTFND = 170 ;($AA) file not found PNTINV = 171 ;($AB) point invalid BADDSK = 173 ;($AD) bad disk INCFMT = 176 ;($B0) DOS 3: incompatible file system +XNTBIN = 180 ;($B4) XDOS: file not binary ; DCB Device Bus Equates @@ -889,6 +890,10 @@ SETVBV_org = $E45C ;vector to set VBLANK parameters CIOV = $E456 ;vector to CIO SIOV = $E459 ;vector to SIO SETVBV = $E45C ;vector to set VBLANK parameters +; aliases in order not to have to sprinkle common code with .ifdefs +CIOV_org = CIOV +SIOV_org = SIOV +SETVBV_org = SETVBV .endif SYSVBV = $E45F ;vector to process immediate VBLANK XITVBV = $E462 ;vector to process deferred VBLANK diff --git a/asminc/errno.inc b/asminc/errno.inc index 83cd9a75d..6e5cce42b 100644 --- a/asminc/errno.inc +++ b/asminc/errno.inc @@ -28,6 +28,7 @@ ESPIPE ; Illegal seek ERANGE ; Range error EBADF ; Bad file number + ENOEXEC ; Exec format error EUNKNOWN ; Unknown OS specific error - must be last! EMAX = EUNKNOWN ; Highest error code diff --git a/include/errno.h b/include/errno.h index 0b3d67bc7..ae76b6c05 100644 --- a/include/errno.h +++ b/include/errno.h @@ -72,7 +72,8 @@ extern int _errno; #define ESPIPE 14 /* Illegal seek */ #define ERANGE 15 /* Range error */ #define EBADF 16 /* Bad file number */ -#define EUNKNOWN 17 /* Unknown OS specific error */ +#define ENOEXEC 17 /* Exec format error */ +#define EUNKNOWN 18 /* Unknown OS specific error */ diff --git a/libsrc/apple2/oserror.s b/libsrc/apple2/oserror.s index f16aa4960..ae3efcacc 100644 --- a/libsrc/apple2/oserror.s +++ b/libsrc/apple2/oserror.s @@ -45,7 +45,7 @@ ErrTab: .byte $01, ENOSYS ; Bad system call number .byte $47, EEXIST ; Duplicate filename .byte $48, ENOSPC ; Volume full .byte $49, ENOSPC ; Volume directory full -; .byte $4A, EUNKNOWN ; Incompatible file format + .byte $4A, ENOEXEC ; Incompatible file format .byte $4B, EINVAL ; Unsupported storage_type ; .byte $4C, EUNKNOWN ; End of file encountered .byte $4D, ESPIPE ; Position out of range diff --git a/libsrc/atari/crt0.s b/libsrc/atari/crt0.s index 87d7d036f..d14567491 100644 --- a/libsrc/atari/crt0.s +++ b/libsrc/atari/crt0.s @@ -9,7 +9,7 @@ ; .export __STARTUP__ : absolute = 1 ; Mark as startup - .export _exit, start + .export _exit, start, excexit, SP_save .import initlib, donelib .import callmain, zerobss @@ -109,12 +109,12 @@ start: ; Call the module destructors. This is also the exit() entry. -_exit: jsr donelib ; Run module destructors +_exit: ldx SP_save + txs ; Restore stack pointer ; Restore the system stuff. - ldx SP_save - txs ; Restore stack pointer +excexit:jsr donelib ; Run module destructors; 'excexit' is called from the exec routine ; Restore the left margin. diff --git a/libsrc/atari/exec.s b/libsrc/atari/exec.s new file mode 100644 index 000000000..2835a2206 --- /dev/null +++ b/libsrc/atari/exec.s @@ -0,0 +1,207 @@ +; +; Christian Groessler, 12-Jun-2016 +; +; int __fastcall__ exec (const char* progname, const char* cmdline); +; +; supports only XDOS at the moment + + .export _exec + + .import popax + .import __dos_type + .import findfreeiocb + .import incsp2 + .import __do_oserror + .import excexit ; from crt0.s + .import SP_save ; from crt0.s +.ifdef UCASE_FILENAME + .importzp tmp3 + .import ucase_fn + .import addysp +.endif + + .include "zeropage.inc" + .include "errno.inc" + .include "atari.inc" + +CMDLINE_BUFFER = $0100 ; put progname + cmdline as one single string there +CMDLINE_MAX = 40+3 ; max. length of drive + progname + cmdline + + .code + +notsupp:lda #ENOSYS ; "unsupported system call" + .byte $2C ; bit opcode, eats the next 2 bytes +noiocb: lda #EMFILE ; "too many open files" + jsr incsp2 ; clean up stack +seterr: jsr __directerrno + lda #$FF + tax + rts ; return -1 + +; entry point + +_exec: + ; save cmdline + sta ptr3 + stx ptr3+1 + + ldy __dos_type + cpy #XDOS + bne notsupp + + jsr findfreeiocb + bne noiocb + + stx tmp4 ; remember IOCB index + + ; get program name + jsr popax + +.ifdef UCASE_FILENAME +.ifdef DEFAULT_DEVICE + ldy #$80 +.else + ldy #$00 +.endif + sty tmp2 ; set flag for ucase_fn + jsr ucase_fn + bcc ucok1 +invret: lda #EINVAL ; file name is too long + bne seterr +ucok1: +.endif ; defined UCASE_FILENAME + +; copy program name and arguments to CMDLINE_BUFFER + + sta ptr4 ; ptr4: pointer to program name + stx ptr4+1 + ldy #0 + ; TODO: check stack ptr and and use min(CMDLINE_MAX,available_stack) +copyp: lda (ptr4),y + beq copypd + sta CMDLINE_BUFFER,y + iny + cpy #CMDLINE_MAX + bne copyp + + ; programe name too long + beq invret + +; file name copied, check for args + +copypd: tya ; put Y into X (index into CMDLINE_BUFFER) + tax + lda ptr3 + ora ptr3+1 ; do we have arguments? + beq copycd ; no + ldy #0 + lda (ptr3),y ; get first byte of cmdline parameter + beq copycd ; nothing there... + lda #' ' ; add a space btw. progname and cmdline + bne copyc1 + +; copy args + +copyc: lda (ptr3),y + beq copycd + iny +copyc1: sta CMDLINE_BUFFER,x + inx + cpx #CMDLINE_MAX + bne copyc + ; progname + arguments too long + beq invret + +invexe: jsr close + lda #XNTBIN + bne setmerr + +copycd: lda #ATEOL + sta CMDLINE_BUFFER,x + +; open the program file, read the first two bytes and compare them to $FF + + ldx tmp4 ; get IOCB index + lda ptr4 ; ptr4 points to progname + sta ICBAL,x + lda ptr4+1 + sta ICBAH,x + lda #OPNIN ; open for input + sta ICAX1,x + lda #OPEN + sta ICCOM,x + jsr CIOV + + tya + +.ifdef UCASE_FILENAME + ldy tmp3 ; get size + jsr addysp ; free used space on the stack + ; the following 'bpl' depends on 'addysp' restoring A as last command before 'rts' +.endif ; defined UCASE_FILENAME + + bpl openok + pha ; remember error code + jsr close ; close the IOCB (required even if open failed) + pla ; put error code back into A +setmerr:jmp __mappederrno ; update errno from OS specific error code in A + +openok: lda #>buf + sta ICBAH,x ; set buffer address + lda #<buf + sta ICBAL,x + lda #0 ; set buffer length + sta ICBLH,x + lda #2 + sta ICBLL,x + lda #GETCHR ; iocb command code + sta ICCOM,x + jsr CIOV ; read it + bmi invexe ; read operation failed, return error + + lda ICBLL,x ; # of bytes read + cmp #2 + bne invexe + lda #$FF ; check file format (need $FFFF at the beginning) + cmp buf + bne invexe + cmp buf+1 + bne invexe + + jsr close ; close program file + +; program file appears to be available and good +; here's the point of no return + + lda tmp4 ; get IOCB index + pha ; and save it ('excexit' calls destructors and they might destroy tmp4) + jsr excexit + pla + ldx SP_save + txs ; reset stack pointer + tax ; IOCB index in X + + lda #<CMDLINE_BUFFER + sta ICBAL,x ; address + lda #>CMDLINE_BUFFER + sta ICBAH,x + lda #0 + sta ICBLL,x ; length shouldn't be random, but 0 is ok + sta ICBLH,x + sta ICAX1,x + sta ICAX2,x + lda #80 ; XDOS: run DUP command + sta ICCOM,x + jmp CIOV_org ; no way to display an error message in case of failure, and we will return to DOS + + +; close IOCB, index in X +.proc close + lda #CLOSE + sta ICCOM,x + jmp CIOV ; close IOCB +.endproc + + .bss + +buf: .res 2 diff --git a/libsrc/atari/oserror.s b/libsrc/atari/oserror.s index a4ba07c0f..1d95dbc36 100644 --- a/libsrc/atari/oserror.s +++ b/libsrc/atari/oserror.s @@ -95,7 +95,7 @@ maptable: .byte EUNKNOWN ; 177 - haven't found documentation .byte EUNKNOWN ; 178 - haven't found documentation .byte EUNKNOWN ; 179 - haven't found documentation - .byte EUNKNOWN ; 180 - not a binary file + .byte ENOEXEC ; 180 - not a binary file .byte EUNKNOWN ; 181 - [MYDOS] invalid address range .byte EUNKNOWN ; 182 - [XDOS] invalid parameter diff --git a/libsrc/common/errormsg.c b/libsrc/common/errormsg.c index 162dad085..e6df34ad3 100644 --- a/libsrc/common/errormsg.c +++ b/libsrc/common/errormsg.c @@ -24,6 +24,7 @@ const char* const _sys_errlist[] = { "Illegal seek", /* ESPIPE */ "Range error", /* ERANGE */ "Bad file number", /* EBADF */ + "Exec format error", /* ENOEXEC */ "Unknown OS error code", /* EUNKNOWN */ }; diff --git a/testcode/lib/tinyshell.c b/testcode/lib/tinyshell.c index de57a3d0e..b5654983e 100644 --- a/testcode/lib/tinyshell.c +++ b/testcode/lib/tinyshell.c @@ -1,9 +1,9 @@ /* ** Simple ("tiny") shell to test filename and directory functions. -** Copyright (c) 2013, Christian Groessler, chris@groessler.org +** Copyright (c) 2013,2016 Christian Groessler, chris@groessler.org */ -#define VERSION_ASC "0.90" +#define VERSION_ASC "0.91" #ifdef __ATARI__ #define UPPERCASE /* define (e.g. for Atari) to convert filenames etc. to upper case */ @@ -18,7 +18,7 @@ #define CHECK_SP #endif -#define KEYB_BUFSZ 80 +#define KEYB_BUFSZ 127 #define PROMPT ">>> " #include <stdio.h> @@ -55,12 +55,14 @@ extern unsigned int getsp(void); /* comes from getsp.s */ #define CMD_PWD 11 #define CMD_CLS 12 #define CMD_VERBOSE 13 +#define CMD_EXEC 14 static unsigned char verbose; static unsigned char terminate; static unsigned char cmd; -static unsigned char *cmd_asc, *arg1, *arg2, *arg3; -static unsigned char keyb_buf[KEYB_BUFSZ]; +static unsigned char *cmd_asc, *arg1, *arg2, *arg3, *args; /* 'args': everything after command */ +static unsigned char keyb_buf[KEYB_BUFSZ + 1]; +static unsigned char keyb_buf2[KEYB_BUFSZ + 1]; static size_t cpbuf_sz = 4096; struct cmd_table { @@ -88,6 +90,7 @@ struct cmd_table { { "mv", CMD_RENAME }, { "ren", CMD_RENAME }, { "pwd", CMD_PWD }, + { "exec", CMD_EXEC }, #ifdef __ATARI__ { "cls", CMD_CLS }, #endif @@ -134,6 +137,17 @@ static void get_command(void) return; } + /* put everything after first string into 'args' */ + + strcpy(keyb_buf2, keyb_buf); /* use a backup copy for 'args' */ + + /* skip over the first non-whitespace item */ + cmd_asc = strtok(keyb_buf2, " \t\n"); + if (cmd_asc) + args = strtok(NULL, ""); /* get everything */ + else + *args = 0; /* no arguments */ + /* split input into cmd, arg1, arg2, arg3 */ /* get and parse command */ @@ -172,11 +186,11 @@ static void cmd_help(void) puts("cd, chdir - change directory or drive"); puts("md, mkdir - make directory or drive"); puts("rd, rmdir - remove directory or drive"); + puts("exec - run program"); #ifdef __ATARI__ puts("cls - clear screen"); #endif puts("verbose - set verbosity level"); - puts("sorry, you cannot start programs here"); } static void cmd_ls(void) @@ -340,6 +354,23 @@ static void cmd_rename(void) printf("rename failed: %s\n", strerror(errno)); } +static void cmd_exec(void) +{ + int st; + unsigned char *progname, *arguments; + + progname = strtok(args, " \t\n"); + if (! progname) { + puts("usage: exec <progname> [arguments]"); + return; + } + arguments = strtok(NULL, ""); + + /*printf("exec: %s %s\n", progname, arguments ? arguments : "");*/ + st = exec(progname, arguments); + printf("exec error: %s\n", strerror(errno)); +} + static void cmd_copy(void) { int srcfd = -1, dstfd = -1; @@ -446,6 +477,7 @@ static void run_command(void) case CMD_RMDIR: cmd_rmdir(); return; case CMD_PWD: cmd_pwd(); return; #endif + case CMD_EXEC: cmd_exec(); return; case CMD_RENAME: cmd_rename(); return; case CMD_COPY: cmd_copy(); return; #ifdef __ATARI__ From 4aa9a414c661a1e179500b02cf4f27dabf5b9272 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Mon, 13 Jun 2016 21:16:27 +0200 Subject: [PATCH 0103/2161] Fix doesclrscrafterexit() function on atarixl target. On atarixl, the screen is always cleared, regardless of the running DOS. --- libsrc/atari/doesclrscr.s | 15 ++++++++------- libsrc/atari/is_cmdline_dos.s | 11 ++++++++--- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/libsrc/atari/doesclrscr.s b/libsrc/atari/doesclrscr.s index c085faebf..2e19e4b98 100644 --- a/libsrc/atari/doesclrscr.s +++ b/libsrc/atari/doesclrscr.s @@ -7,13 +7,14 @@ ; .export _doesclrscrafterexit - .import __dos_type - .include "atari.inc" + .import __is_cmdline_dos + .import return1 +.ifdef __ATARIXL__ +_doesclrscrafterexit = return1 ; the c65 runtime always clears the screen at program termination +.else _doesclrscrafterexit: - ldx #0 - lda __dos_type - cmp #MAX_DOS_WITH_CMDLINE + 1 - txa - rol a + jsr __is_cmdline_dos ; currently (unless a DOS behaving differently is popping up) + eor #$01 ; we can get by with the inverse of __is_cmdline_dos rts +.endif diff --git a/libsrc/atari/is_cmdline_dos.s b/libsrc/atari/is_cmdline_dos.s index b85cb3ca7..71b35fbad 100644 --- a/libsrc/atari/is_cmdline_dos.s +++ b/libsrc/atari/is_cmdline_dos.s @@ -7,9 +7,14 @@ ; .export __is_cmdline_dos - .import _doesclrscrafterexit + .import __dos_type + .include "atari.inc" __is_cmdline_dos: - jsr _doesclrscrafterexit ; currently (unless a DOS behaving differently is popping up) - eor #$01 ; we can get by with the inverse of _doesclrscrafterexit + ldx #0 + lda __dos_type + cmp #MAX_DOS_WITH_CMDLINE + 1 + txa + rol a + eor #$01 rts From d0faf471b8543ffaa32346d3c673f145ead7e068 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 14 Jun 2016 20:44:57 +0200 Subject: [PATCH 0104/2161] Some improvements to Atari exec() after review. --- libsrc/atari/exec.s | 6 ++---- testcode/lib/tinyshell.c | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/libsrc/atari/exec.s b/libsrc/atari/exec.s index 2835a2206..4ae30fdbf 100644 --- a/libsrc/atari/exec.s +++ b/libsrc/atari/exec.s @@ -33,10 +33,8 @@ notsupp:lda #ENOSYS ; "unsupported system call" .byte $2C ; bit opcode, eats the next 2 bytes noiocb: lda #EMFILE ; "too many open files" jsr incsp2 ; clean up stack -seterr: jsr __directerrno - lda #$FF - tax - rts ; return -1 +seterr: jmp __directerrno + ; entry point diff --git a/testcode/lib/tinyshell.c b/testcode/lib/tinyshell.c index b5654983e..c83bd14e8 100644 --- a/testcode/lib/tinyshell.c +++ b/testcode/lib/tinyshell.c @@ -356,7 +356,6 @@ static void cmd_rename(void) static void cmd_exec(void) { - int st; unsigned char *progname, *arguments; progname = strtok(args, " \t\n"); @@ -367,7 +366,7 @@ static void cmd_exec(void) arguments = strtok(NULL, ""); /*printf("exec: %s %s\n", progname, arguments ? arguments : "");*/ - st = exec(progname, arguments); + (void)exec(progname, arguments); printf("exec error: %s\n", strerror(errno)); } From ec7751332fd72daeb8eb5be811f1e86be9adbc02 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 15 Jun 2016 23:52:16 +0200 Subject: [PATCH 0105/2161] Fix exec() for atarixl target. The final part of exec() called 'excexit' and only then restored the stack pointer to its value at program entry. 'excexit' does all cleanup (the same as '_exit()'), which means that on the atarixl target the ROM is banked in again. On big programs the 'SP_save' variable might reside at a high memory address which is no longer accessible after the ROM has been banked in. The change just moves the restoration of the stack pointer before the call to 'excexit'. Another change lets exec.s compile if UCASE_FILENAME is not defined. And some other small cleanups, also in open.s. --- libsrc/atari/exec.s | 20 +++++++++++++------- libsrc/atari/open.s | 3 +-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/libsrc/atari/exec.s b/libsrc/atari/exec.s index 4ae30fdbf..260a772b4 100644 --- a/libsrc/atari/exec.s +++ b/libsrc/atari/exec.s @@ -11,11 +11,9 @@ .import __dos_type .import findfreeiocb .import incsp2 - .import __do_oserror .import excexit ; from crt0.s .import SP_save ; from crt0.s .ifdef UCASE_FILENAME - .importzp tmp3 .import ucase_fn .import addysp .endif @@ -24,7 +22,10 @@ .include "errno.inc" .include "atari.inc" -CMDLINE_BUFFER = $0100 ; put progname + cmdline as one single string there +; area $0100 to $0128 might be in use (e.g. Hias' high speed patch) +CMDLINE_BUFFER = $0129 ; put progname + cmdline as one single string there +; alternatively: +;CMDLINE_BUFFER = $0480 ; put progname + cmdline as one single string there CMDLINE_MAX = 40+3 ; max. length of drive + progname + cmdline .code @@ -85,6 +86,11 @@ copyp: lda (ptr4),y ; programe name too long beq invret +.ifndef UCASE_FILENAME +invret: lda #EINVAL + bne seterr +.endif + ; file name copied, check for args copypd: tya ; put Y into X (index into CMDLINE_BUFFER) @@ -172,11 +178,11 @@ openok: lda #>buf ; here's the point of no return lda tmp4 ; get IOCB index - pha ; and save it ('excexit' calls destructors and they might destroy tmp4) - jsr excexit - pla ldx SP_save - txs ; reset stack pointer + txs ; reset stack pointer to what it was at program entry + pha ; and save it ('excexit' calls destructors and they might destroy tmp4) + jsr excexit ; on atarixl this will enable the ROM again, making all high variables inaccessible + pla tax ; IOCB index in X lda #<CMDLINE_BUFFER diff --git a/libsrc/atari/open.s b/libsrc/atari/open.s index d5ff4ca52..721519525 100644 --- a/libsrc/atari/open.s +++ b/libsrc/atari/open.s @@ -8,6 +8,7 @@ .include "fcntl.inc" .include "errno.inc" .include "fd.inc" + .include "zeropage.inc" .export _open .destructor closeallfiles, 5 @@ -19,9 +20,7 @@ .import incsp4 .import ldaxysp,addysp .import __oserror - .importzp tmp4,tmp2 .ifdef UCASE_FILENAME - .importzp tmp3 .import ucase_fn .endif From a9c69bb8c9fef39903b27971ed5c9c7c0f83e71b Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 16 Jun 2016 00:47:13 +0200 Subject: [PATCH 0106/2161] A small rearrangement of instructions in Atari's exec() to let the comments make sense again. --- libsrc/atari/exec.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/atari/exec.s b/libsrc/atari/exec.s index 260a772b4..16062a294 100644 --- a/libsrc/atari/exec.s +++ b/libsrc/atari/exec.s @@ -177,9 +177,9 @@ openok: lda #>buf ; program file appears to be available and good ; here's the point of no return - lda tmp4 ; get IOCB index ldx SP_save txs ; reset stack pointer to what it was at program entry + lda tmp4 ; get IOCB index pha ; and save it ('excexit' calls destructors and they might destroy tmp4) jsr excexit ; on atarixl this will enable the ROM again, making all high variables inaccessible pla From f91a7e749b869ab51c0e26ab628191d9d831e5a8 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 18 Jun 2016 13:18:26 -0400 Subject: [PATCH 0107/2161] Fixed the Plus/4 joystick driver. It chooses a stick correctly. And, it reads the fire button. --- libsrc/plus4/joy/plus4-stdjoy.s | 34 +++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/libsrc/plus4/joy/plus4-stdjoy.s b/libsrc/plus4/joy/plus4-stdjoy.s index 29316bf22..4a5132887 100644 --- a/libsrc/plus4/joy/plus4-stdjoy.s +++ b/libsrc/plus4/joy/plus4-stdjoy.s @@ -1,17 +1,15 @@ ; -; Standard joystick driver for the Plus/4. May be used multiple times when linked -; to the statically application. +; Standard joystick driver for the Plus/4 and C16. +; May be used multiple times when linked statically to an application. ; -; Ullrich von Bassewitz, 2002-12-21 +; 2002-12-21, Ullrich von Bassewitz +; 2016-06-18, Greg King ; - .include "zeropage.inc" - .include "joy-kernel.inc" .include "joy-error.inc" .include "plus4.inc" - .macpack generic .macpack module @@ -26,7 +24,7 @@ ; Driver signature - .byte $6A, $6F, $79 ; "joy" + .byte $6A, $6F, $79 ; ASCII "joy" .byte JOY_API_VERSION ; Driver API version number ; Library reference @@ -39,7 +37,7 @@ .byte $02 ; JOY_DOWN .byte $04 ; JOY_LEFT .byte $08 ; JOY_RIGHT - .byte $10 ; JOY_FIRE + .byte $80 ; JOY_FIRE .byte $00 ; JOY_FIRE2 unavailable .byte $00 ; Future expansion .byte $00 ; Future expansion @@ -98,16 +96,20 @@ COUNT: ; READ: Read a particular joystick passed in A. ; -READ: ldy #$FA ; Load index for joystick #1 +READ: ldy #%11111011 ; Load index for joystick #1 tax ; Test joystick number beq @L1 - ldy #$FB ; Load index for joystick #2 + ldy #%11111101 ; Load index for joystick #2 + ldx #>$0000 ; (Return unsigned int) @L1: sei - sty TED_KBD - lda TED_KBD + sty TED_KBD ; Read a joystick ... + lda TED_KBD ; ... and some keys -- it's unavoidable cli - ldx #$00 ; Clear high byte - and #$1F - eor #$1F - rts + eor #%11111111 +; The fire buttons are in bits 6 and 7. Both of them cannot be %1 together. +; Therefore, bit 6 can be merged with bit 7. + + clc + adc #%01000000 + rts From 9bc096d9b02255cab6d4225e28c0685714ca3ae3 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 18 Jun 2016 23:35:57 +0200 Subject: [PATCH 0108/2161] Make use of doesclrscrafterexit(). --- samples/diodemo.c | 6 ++++++ samples/enumdevdir.c | 6 ++++-- samples/gunzip65.c | 12 ++++++++++++ samples/mandelbrot.c | 29 ++++++++++++++++++----------- samples/mousetest.c | 5 ++++- samples/multidemo.c | 10 ++++++---- samples/overlaydemo.c | 6 ++++-- samples/tgidemo.c | 3 +++ 8 files changed, 57 insertions(+), 20 deletions(-) diff --git a/samples/diodemo.c b/samples/diodemo.c index 752c2f78a..3e52f2fa9 100644 --- a/samples/diodemo.c +++ b/samples/diodemo.c @@ -36,6 +36,7 @@ #include <conio.h> #include <ctype.h> #include <errno.h> +#include <cc65.h> #include <dio.h> @@ -123,6 +124,11 @@ int main (int argc, const char* argv[]) clrscr (); screensize (&ScreenX, &ScreenY); + /* Allow user to read exit messages */ + if (doesclrscrafterexit ()) { + atexit ((void (*)) cgetc); + } + cputs ("Floppy Disk Copy\r\n"); chline (16); cputs ("\r\n"); diff --git a/samples/enumdevdir.c b/samples/enumdevdir.c index f270b43af..ce2dc99ec 100644 --- a/samples/enumdevdir.c +++ b/samples/enumdevdir.c @@ -8,12 +8,12 @@ #include <stdio.h> -#include <conio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <device.h> #include <dirent.h> +#include <cc65.h> void printdir (char *newdir) @@ -97,5 +97,7 @@ void main (void) device = getnextdevice (device); } - cgetc (); + if (doesclrscrafterexit ()) { + getchar (); + } } diff --git a/samples/gunzip65.c b/samples/gunzip65.c index 2ad029467..9d21c2137 100644 --- a/samples/gunzip65.c +++ b/samples/gunzip65.c @@ -14,6 +14,11 @@ #include <string.h> #include <zlib.h> +#ifdef __CC65__ +#include <stdlib.h> +#include <cc65.h> +#endif + #ifndef __CC65__ /* ** Emulate inflatemem() if using original zlib. @@ -191,6 +196,13 @@ int main(void) FILE* fp; unsigned length; +#ifdef __CC65__ + /* allow user to read exit messages */ + if (doesclrscrafterexit()) { + atexit((void (*)) getchar); + } +#endif /* __CC65__ */ + /* read GZIP file */ puts("GZIP file name:"); fp = fopen(get_fname(), "rb"); diff --git a/samples/mandelbrot.c b/samples/mandelbrot.c index 5d3d661c9..d7291c5b5 100644 --- a/samples/mandelbrot.c +++ b/samples/mandelbrot.c @@ -10,6 +10,7 @@ #include <time.h> #include <conio.h> #include <tgi.h> +#include <cc65.h> @@ -51,7 +52,7 @@ void mandelbrot (signed short x1, signed short y1, signed short x2, register signed short xs, ys, xx, yy; register signed short x, y; - /* calc stepwidth */ + /* Calc stepwidth */ xs = ((x2 - x1) / (SCREEN_X)); ys = ((y2 - y1) / (SCREEN_Y)); @@ -61,7 +62,7 @@ void mandelbrot (signed short x1, signed short y1, signed short x2, xx = x1; for (x = 0; x < (SCREEN_X); x++) { xx += xs; - /* do iterations */ + /* Do iterations */ r = 0; i = 0; for (count = 0; (count < maxiterations) && @@ -75,12 +76,13 @@ void mandelbrot (signed short x1, signed short y1, signed short x2, if (count == maxiterations) { tgi_setcolor (0); } else { - if (MAXCOL == 2) + if (MAXCOL == 2) { tgi_setcolor (1); - else + } else { tgi_setcolor (count % MAXCOL); + } } - /* set pixel */ + /* Set pixel */ tgi_setpixel (x, y); } } @@ -107,6 +109,9 @@ int main (void) if (err != TGI_ERR_OK) { cprintf ("Error #%d initializing graphics.\r\n%s\r\n", err, tgi_geterrormsg (err)); + if (doesclrscrafterexit ()) { + cgetc (); + } exit (EXIT_FAILURE); }; cprintf ("ok.\n\r"); @@ -117,15 +122,15 @@ int main (void) t = clock (); - /* calc mandelbrot set */ + /* Calc mandelbrot set */ mandelbrot (tofp (-2), tofp (-2), tofp (2), tofp (2)); t = clock () - t; /* Fetch the character from the keyboard buffer and discard it */ - (void) cgetc (); + cgetc (); - /* shut down gfx mode and return to textmode */ + /* Shut down gfx mode and return to textmode */ tgi_done (); /* Calculate stats */ @@ -136,9 +141,11 @@ int main (void) /* Output stats */ cprintf ("time : %lu.%us\n\r", sec, sec10); - /* Wait for a key, then end */ - cputs ("Press any key when done...\n\r"); - (void) cgetc (); + if (doesclrscrafterexit ()) { + /* Wait for a key, then end */ + cputs ("Press any key when done...\n\r"); + cgetc (); + } /* Done */ return EXIT_SUCCESS; diff --git a/samples/mousetest.c b/samples/mousetest.c index 4a849cb98..3910d5a0a 100644 --- a/samples/mousetest.c +++ b/samples/mousetest.c @@ -17,6 +17,7 @@ #include <conio.h> #include <ctype.h> #include <dbg.h> +#include <cc65.h> #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) @@ -57,7 +58,9 @@ static void __fastcall__ CheckError (const char* S, unsigned char Error) /* Wait for a key-press, so that some platforms can show the error ** message before they remove the current screen. */ - cgetc(); + if (doesclrscrafterexit ()) { + cgetc (); + } exit (EXIT_FAILURE); } } diff --git a/samples/multidemo.c b/samples/multidemo.c index 74039cfd6..038b74d64 100644 --- a/samples/multidemo.c +++ b/samples/multidemo.c @@ -11,11 +11,11 @@ #include <string.h> -#include <conio.h> #include <stdio.h> #include <stdlib.h> #include <dirent.h> #include <em.h> +#include <cc65.h> #ifndef __CBM__ #include <fcntl.h> #include <unistd.h> @@ -229,7 +229,7 @@ void main (void) } log ("Press any key..."); - cgetc (); + getchar (); if (loadoverlay (1)) { log ("Calling overlay 1 from main"); @@ -254,6 +254,8 @@ void main (void) foobar (); } - log ("Press any key..."); - cgetc (); + if (doesclrscrafterexit ()) { + log ("Press any key..."); + getchar (); + } } diff --git a/samples/overlaydemo.c b/samples/overlaydemo.c index 42e757153..a4dc53931 100644 --- a/samples/overlaydemo.c +++ b/samples/overlaydemo.c @@ -10,7 +10,7 @@ #include <stdio.h> -#include <conio.h> +#include <cc65.h> #ifndef __CBM__ #include <fcntl.h> #include <unistd.h> @@ -130,5 +130,7 @@ void main (void) foobar (); } - cgetc (); + if (doesclrscrafterexit ()) { + getchar (); + } } diff --git a/samples/tgidemo.c b/samples/tgidemo.c index a08020640..d8c2a6f50 100644 --- a/samples/tgidemo.c +++ b/samples/tgidemo.c @@ -40,6 +40,9 @@ static void CheckError (const char* S) unsigned char Error = tgi_geterror (); if (Error != TGI_ERR_OK) { printf ("%s: %d\n", S, Error); + if (doesclrscrafterexit ()) { + cgetc (); + } exit (EXIT_FAILURE); } } From 64c10aa2fe36a4becf473b63cb883fb9c22b6015 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 18 Jun 2016 23:39:21 +0200 Subject: [PATCH 0109/2161] Minor simplification. --- samples/hello.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/hello.c b/samples/hello.c index 854e9a4b4..dd15128d2 100644 --- a/samples/hello.c +++ b/samples/hello.c @@ -77,7 +77,7 @@ int main (void) #else /* Wait for the user to press a key */ - (void) cgetc (); + cgetc (); #endif From 66561c23c10fe1a8e62dd276e4740fd0e5c8e4f4 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 19 Jun 2016 01:22:59 +0200 Subject: [PATCH 0110/2161] Made Makefile actually work. Supported target systems: * c64 (default) * apple2 * apple2enh * atari * atarixl --- samples/Makefile | 207 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 140 insertions(+), 67 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index c138c1c2e..bbf69c820 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -4,7 +4,7 @@ # This Makefile requires GNU make # -# Enter the target system here +# Run 'make samples SYS=<target>' to build for another target system SYS = c64 ifneq ($(shell echo),) @@ -14,74 +14,74 @@ endif ifdef CMD_EXE NULLDEV = nul: DEL = -del /f + RMDIR = rmdir /s /q else NULLDEV = /dev/null DEL = $(RM) + RMDIR = $(RM) -r endif -# Determine the path to the executables and libraries. If the samples -# directory is part of a complete source tree, use the stuff from that -# source tree; otherwise, use the "install" directories. -ifeq "$(wildcard ../src)" "" -# No source tree -installdir = /usr/lib/cc65 -ifneq "$(wildcard /usr/local/lib/cc65)" "" -installdir = /usr/local/lib/cc65 -endif -ifneq "$(wildcard /opt/local/share/cc65)" "" -installdir = /opt/local/share/cc65 -endif ifdef CC65_HOME -installdir = $(CC65_HOME) -endif - -MOUS := $(wildcard $(installdir)/target/$(SYS)/drv/mou/$(SYS)*.mou) -TGI := $(wildcard $(installdir)/target/$(SYS)/drv/tgi/$(SYS)*.tgi) -CLIB = --lib $(SYS).lib -CL = cl65 -CC = cc65 -AS = ca65 -LD = ld65 - + AS = $(CC65_HOME)/bin/ca65 + CC = $(CC65_HOME)/bin/cc65 + CL = $(CC65_HOME)/bin/cl65 + LD = $(CC65_HOME)/bin/ld65 else -# "samples/" is a part of a complete source tree. -export CC65_HOME := $(abspath ..) -MOUS := $(wildcard ../target/$(SYS)/drv/mou/$(SYS)*.mou) -TGI := $(wildcard ../target/$(SYS)/drv/tgi/$(SYS)*.tgi) -CLIB = ../lib/$(SYS).lib -CL = ../bin/cl65 -CC = ../bin/cc65 -AS = ../bin/ca65 -LD = ../bin/ld65 + 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 +TARGET_PATH := $(shell $(CL) --print-target-path) + +EMD := $(wildcard $(TARGET_PATH)/$(SYS)/drv/emd/*) +MOU := $(wildcard $(TARGET_PATH)/$(SYS)/drv/mou/*) +TGI := $(wildcard $(TARGET_PATH)/$(SYS)/drv/tgi/*) + # This one comes with VICE C1541 ?= c1541 +# For this one see http://applecommander.sourceforge.net/ +AC ?= ac.jar + +# For this one see http://www.horus.com/~hias/atari/ +DIR2ATR ?= dir2atr + +DISK_c64 = samples.d64 +DISK_apple2 = samples.dsk +DISK_apple2enh = samples.dsk +DISK_atari = samples.atr +DISK_atarixl = samples.atr + # -------------------------------------------------------------------------- # System-dependent settings # The Apple machines need the start address adjusted when using TGI -LDFLAGS_mandelbrot_apple2 = --start-addr 0x4000 -LDFLAGS_tgidemo_apple2 = --start-addr 0x4000 +LDFLAGS_mandelbrot_apple2 = --start-addr 0x4000 LDFLAGS_mandelbrot_apple2enh = --start-addr 0x4000 -LDFLAGS_tgidemo_apple2enh = --start-addr 0x4000 +LDFLAGS_tgidemo_apple2 = --start-addr 0x4000 +LDFLAGS_tgidemo_apple2enh = --start-addr 0x4000 # The Apple ][ needs the start address adjusted for the mousetest LDFLAGS_mousetest_apple2 = --start-addr 0x4000 -# The atarixl target needs the start address adjusted when using TGI -LDFLAGS_mandelbrot_atarixl = --start-addr 0x4000 -LDFLAGS_tgidemo_atarixl = --start-addr 0x4000 +# The Apple machines need the end address adjusted for large programs +LDFLAGS_gunzip65_apple2 = -D __HIMEM__=0xBF00 +LDFLAGS_gunzip65_apple2enh = -D __HIMEM__=0xBF00 # The atari target needs to reserve some memory when using TGI LDFLAGS_mandelbrot_atari = -D __RESERVED_MEMORY__=0x2000 -LDFLAGS_tgidemo_atari = -D __RESERVED_MEMORY__=0x2000 +LDFLAGS_tgidemo_atari = -D __RESERVED_MEMORY__=0x2000 + +# The atarixl target needs the start address adjusted when using TGI +LDFLAGS_mandelbrot_atarixl = --start-addr 0x4000 +LDFLAGS_tgidemo_atarixl = --start-addr 0x4000 # -------------------------------------------------------------------------- # Generic rules -.PHONY: all mostlyclean clean install zip samples d64 +.PHONY: all mostlyclean clean install zip samples disk %: %.c %: %.s @@ -96,43 +96,72 @@ LDFLAGS_tgidemo_atari = -D __RESERVED_MEMORY__=0x2000 .PRECIOUS: %.o .o: - $(LD) $(LDFLAGS_$(@F)_$(SYS)) -o $@ -t $(SYS) -m $@.map $^ $(CLIB) + $(LD) $(LDFLAGS_$(@F)_$(SYS)) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib # -------------------------------------------------------------------------- -# List of executables. This list could be made target-dependent by checking -# $(SYS). +# List of executables -EXELIST = ascii \ - diodemo \ - enumdevdir \ - fire \ - gunzip65 \ - hello \ - mandelbrot \ - mousetest \ - multdemo \ - nachtm \ - ovrldemo \ - plasma \ - sieve \ - tgidemo +EXELIST_c64 = \ + ascii \ + enumdevdir \ + fire \ + gunzip65 \ + hello \ + mandelbrot \ + mousetest \ + multdemo \ + nachtm \ + ovrldemo \ + plasma \ + sieve \ + tgidemo + +EXELIST_apple2 = \ + ascii \ + diodemo \ + enumdevdir \ + gunzip65 \ + hello \ + mandelbrot \ + mousetest \ + multdemo \ + ovrldemo \ + sieve \ + tgidemo + +EXELIST_apple2enh = $(EXELIST_apple2) + +EXELIST_atari = \ + ascii \ + gunzip65 \ + hello \ + mandelbrot \ + mousetest \ + multdemo \ + ovrldemo \ + sieve \ + tgidemo + +EXELIST_atarixl = $(EXELIST_atari) # -------------------------------------------------------------------------- -# Rules to make the binaries +# Rules to make the binaries and the disk all: -samples: $(EXELIST) +samples: $(EXELIST_$(SYS)) + +disk: $(DISK_$(SYS)) # -------------------------------------------------------------------------- # Overlay rules. Overlays need special ld65 configuration files. Also, the # overlay file-names are shortenned to fit the Atari's 8.3-character limit. multdemo: multidemo.o - $(LD) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(CLIB) + $(LD) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(SYS).lib ovrldemo: overlaydemo.o - $(LD) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(CLIB) + $(LD) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(SYS).lib OVERLAYLIST := $(foreach I,1 2 3,multdemo.$I ovrldemo.$I) @@ -140,8 +169,6 @@ OVERLAYLIST := $(foreach I,1 2 3,multdemo.$I ovrldemo.$I) # Rule to make a CBM disk with all samples. Needs the c1541 program that comes # with the VICE emulator. -d64: samples.d64 - define D64_WRITE_recipe $(C1541) -attach $@ -write $(file) $(notdir $(file)) >$(NULLDEV) @@ -150,9 +177,55 @@ endef # D64_WRITE_recipe samples.d64: samples @$(C1541) -format samples,AA d64 $@ >$(NULLDEV) - $(foreach file,$(EXELIST),$(D64_WRITE_recipe)) + $(foreach file,$(EXELIST_$(SYS)),$(D64_WRITE_recipe)) $(foreach file,$(OVERLAYLIST),$(D64_WRITE_recipe)) - $(foreach file,$(TGI) $(MOUS),$(D64_WRITE_recipe)) + $(foreach file,$(EMD) $(MOU) $(TGI),$(D64_WRITE_recipe)) + +# -------------------------------------------------------------------------- +# Rule to make an Apple II disk with all samples. Needs the Apple Commander +# program available at http://applecommander.sourceforge.net/ and a template +# disk named 'prodos.dsk'. + +define DSK_WRITE_BIN_recipe + +$(if $(findstring BF00,$(LDFLAGS_$(notdir $(file))_$(SYS))), \ + java -jar $(AC) -p $@ $(notdir $(file)).system sys <$(TARGET_PATH)/$(SYS)/util/loader.system) +java -jar $(AC) -cc65 $@ $(notdir $(file)) bin <$(file) + +endef # DSK_WRITE_BIN_recipe + +define DSK_WRITE_REL_recipe + +java -jar $(AC) -p $@ $(notdir $(file)) rel 0 <$(file) + +endef # DSK_WRITE_REL_recipe + +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)) + +# -------------------------------------------------------------------------- +# Rule to make an Atari disk with all samples. Needs the dir2atr program +# available at http://www.horus.com/~hias/atari/ and the MyDos4534 variant +# of dos.sys and dup.sys. + +define ATR_WRITE_recipe + +cp $(file) atr/$(notdir $(file)) + +endef # ATR_WRITE_recipe + +samples.atr: samples + @mkdir atr + cp dos.sys atr/dos.sys + 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)) + $(DIR2ATR) -d -b MyDos4534 3200 $@ atr + @$(RMDIR) atr # -------------------------------------------------------------------------- # Installation rules @@ -184,5 +257,5 @@ mostlyclean: @$(DEL) *.map *.o *.s 2>$(NULLDEV) clean: mostlyclean - @$(DEL) $(EXELIST) samples.d64 2>$(NULLDEV) + @$(DEL) $(EXELIST_$(SYS)) $(DISK_$(SYS)) 2>$(NULLDEV) @$(DEL) multdemo.? ovrldemo.? 2>$(NULLDEV) From 2ef43e425adf3834e4fb7b768dbba5e8d6c282ec Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 19 Jun 2016 01:39:27 +0200 Subject: [PATCH 0111/2161] Adjusted to recent change. --- samples/README | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/samples/README b/samples/README index edd06ff02..b7476e354 100644 --- a/samples/README +++ b/samples/README @@ -7,14 +7,13 @@ the supported platforms. Please note: * The supplied makefile needs GNU make. It works out of the box on Linux - and similar systems. If you're using Windows, you will have to compile - the programs manually. + and similar systems. If you're using Windows, consider installing Cygwin. - * The makefile specifies the C64 as the default target platform, because all - but one - of the programs run on this platform. When compiling for another platform, - you will have to change the line that specifies the target system at the - top of the makefile. + * The makefile specifies the C64 as the default target system, because all + but one of the programs run on this platform. When compiling for another + system, you will have to change the line that specifies the target system + at the top of the makefile or specify the system with SYS=<target> on the + make command line. List of supplied sample programs: From e47485f925375978cc95cd3ceaec1ba1a7bbd96a Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 19 Jun 2016 15:03:20 +0200 Subject: [PATCH 0112/2161] Added CONIO cursor support. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For quite some time I deliberately didn't add cursor support to the Apple II CONIO imöplementation. I consider it inappropriate to increase the size of cgetc() unduly for a rather seldom used feature. There's no hardware cursor on the Apple II so displaying a cursor during keyboard input means reading the character stored at the cursor location, writing the cursor character, reading the keyboard and finally writing back the character read initially. The naive approach is to reuse the part of cputc() that determines the memory location of the character at the cursor position in order to read the character stored there. However that means to add at least one additional JSR / RTS pair to cputc() adding 4 bytes and 12 cycles :-( Apart from that this approach means still a "too" large cgetc(). The approach implemented instead is to include all functionality required by cgetc() into cputc() - which is to read the current character before writing a new one. This may seem surprising at first glance but an LDA(),Y / TAX sequence adds only 3 bytes and 7 cycles so it cheaper than the JSR / RTS pair and allows to brings down the code increase in cgetc() down to a reasonable value. However so far the internal cputc() code in question saved the X register. Now it uses the X register to return the old character present before writing the new character for cgetc(). This requires some rather small adjustments in other functions using that internal cputc() code. --- doc/apple2.sgml | 4 ---- doc/apple2enh.sgml | 4 ---- libsrc/apple2/cgetc.s | 38 +++++++++++++++++++++++++++++++------- libsrc/apple2/chline.s | 7 ++++--- libsrc/apple2/cputc.s | 30 +++++++++++++++++------------- libsrc/apple2/cvline.s | 7 ++++--- libsrc/apple2/textframe.s | 8 ++++---- 7 files changed, 60 insertions(+), 38 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 00cd565b4..d0405b6de 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -449,10 +449,6 @@ BASIC.SYSTEM) there are some limitations for DOS 3.3: The Apple ][ has no color text mode. Therefore the functions textcolor(), bgcolor() and bordercolor() have no effect. - <tag/Cursor/ - The Apple ][ has no hardware cursor. Therefore the function cursor() has - no effect. - </descrip><p> diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 7c17c24f2..b5231b4cd 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -450,10 +450,6 @@ BASIC.SYSTEM) there are some limitations for DOS 3.3: The enhanced Apple //e has no color text mode. Therefore the functions textcolor(), bgcolor() and bordercolor() have no effect. - <tag/Cursor/ - The enhanced Apple //e has no hardware cursor. Therefore the function - cursor() has no effect. - </descrip><p> diff --git a/libsrc/apple2/cgetc.s b/libsrc/apple2/cgetc.s index 511e434df..b1bda8b91 100644 --- a/libsrc/apple2/cgetc.s +++ b/libsrc/apple2/cgetc.s @@ -6,20 +6,44 @@ ; If open_apple key is pressed then the high-bit of the key is set. ; - .export _cgetc + .export _cgetc + .import cursor, putchardirect - .include "apple2.inc" + .include "apple2.inc" _cgetc: - lda KBD - bpl _cgetc ; If < 128, no key pressed + ; Cursor on ? + lda cursor + beq :+ - ; At this time, the high bit of the key pressed is set - bit KBDSTRB ; Clear keyboard strobe + ; Show caret. + .ifdef __APPLE2ENH__ + lda #$7F | $80 ; Checkerboard, screen code + .else + lda #' ' | $40 ; Blank, flashing + .endif + jsr putchardirect ; Returns old character in X + + ; Wait for keyboard strobe. +: lda KBD + bpl :- ; If < 128, no key pressed + + ; Cursor on ? + ldy cursor + beq :+ + + ; Restore old character. + pha + txa + jsr putchardirect + pla + + ; At this time, the high bit of the key pressed is set. +: bit KBDSTRB ; Clear keyboard strobe .ifdef __APPLE2ENH__ bit BUTN0 ; Check if OpenApple is down bmi done .endif and #$7F ; If not down, then clear high bit -done: ldx #$00 +done: ldx #>$0000 rts diff --git a/libsrc/apple2/chline.s b/libsrc/apple2/chline.s index 6cf77de1b..ca1ee707c 100644 --- a/libsrc/apple2/chline.s +++ b/libsrc/apple2/chline.s @@ -26,11 +26,12 @@ _chline: ldx #'-' | $80 ; Horizontal line, screen code chlinedirect: + stx tmp1 cmp #$00 ; Is the length zero? beq done ; Jump if done - sta tmp1 -: txa ; Screen code + sta tmp2 +: lda tmp1 ; Screen code jsr cputdirect ; Direct output - dec tmp1 + dec tmp2 bne :- done: rts diff --git a/libsrc/apple2/cputc.s b/libsrc/apple2/cputc.s index 6607c6178..6f610fe92 100644 --- a/libsrc/apple2/cputc.s +++ b/libsrc/apple2/cputc.s @@ -9,7 +9,7 @@ .constructor initconio .endif .export _cputcxy, _cputc - .export cputdirect, newline, putchar + .export cputdirect, newline, putchar, putchardirect .import gotoxy, VTABZ .include "apple2.inc" @@ -62,32 +62,36 @@ newline: lda WNDTOP ; Goto top of screen sta CV : jmp VTABZ - + putchar: .ifdef __APPLE2ENH__ ldy INVFLG cpy #$FF ; Normal character display mode? - beq put + beq putchardirect cmp #$E0 ; Lowercase? bcc mask and #$7F ; Inverse lowercase - bra put + bra putchardirect .endif mask: and INVFLG ; Apply normal, inverse, flash -put: ldy CH + +putchardirect: + pha + ldy CH .ifdef __APPLE2ENH__ bit RD80VID ; In 80 column mode? - bpl col40 ; No, in 40 cols - pha + bpl put ; No, just go ahead tya lsr ; Div by 2 tay - pla - bcs col40 ; Odd cols go in 40 col memory + bcs put ; Odd cols go in main memory bit HISCR ; Assume SET80COL - sta (BASL),Y - bit LOWSCR ; Assume SET80COL - rts .endif -col40: sta (BASL),Y +put: lda (BASL),Y ; Get current character + tax ; Return old character for _cgetc + pla + sta (BASL),Y + .ifdef __APPLE2ENH__ + bit LOWSCR ; Doesn't hurt in 40 column mode + .endif rts diff --git a/libsrc/apple2/cvline.s b/libsrc/apple2/cvline.s index a26cc7063..c8ae1e269 100644 --- a/libsrc/apple2/cvline.s +++ b/libsrc/apple2/cvline.s @@ -23,12 +23,13 @@ _cvline: .endif cvlinedirect: + stx tmp1 cmp #$00 ; Is the length zero? beq done ; Jump if done - sta tmp1 -: txa ; Screen code + sta tmp2 +: lda tmp1 ; Screen code jsr putchar ; Write, no cursor advance jsr newline ; Advance cursor to next line - dec tmp1 + dec tmp2 bne :- done: rts diff --git a/libsrc/apple2/textframe.s b/libsrc/apple2/textframe.s index d5e9b80d7..55ac235b8 100644 --- a/libsrc/apple2/textframe.s +++ b/libsrc/apple2/textframe.s @@ -16,10 +16,10 @@ .include "zeropage.inc" .include "apple2.inc" -WIDTH = tmp2 -HEIGHT = tmp3 -XORIGIN = tmp4 -YORIGIN = ptr1 +WIDTH = ptr1 +HEIGHT = ptr1+1 +XORIGIN = ptr2 +YORIGIN = ptr2+1 _textframexy: sec From c9e9679a06afd86fe8caeb32177c11736b98a974 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 19 Jun 2016 18:55:00 +0200 Subject: [PATCH 0113/2161] Improved doc and samples default target. The 'all' target deliberately doesn't build the doc nor the samples. But that doesn't mean that the Makefiles in the 'doc' and 'samples' directories must default to the (empty) 'all' target. --- doc/Makefile | 42 +++++++++++++++++++++--------------------- samples/Makefile | 9 +++++---- samples/README | 4 ++-- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/doc/Makefile b/doc/Makefile index 862164e1b..96a3ba59b 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -9,11 +9,9 @@ endif htmldir = $(prefix)/share/doc/cc65$(DESTPACKAGE_SUFFIX)/html infodir = $(prefix)/share/info -all mostlyclean: - ifdef CMD_EXE -clean install zip doc: +doc clean install zip: else # CMD_EXE @@ -26,6 +24,24 @@ TOC_LEVEL = 2 INSTALL = install +doc: html info + +html: $(addprefix ../html/,$(SGMLS:.sgml=.html) doc.css doc.png) + +info: $(addprefix ../info/,$(SGMLS:.sgml=.info)) + +../html ../info: + @mkdir $@ + +../html/%.html: %.sgml header.html | ../html + @cd ../html && linuxdoc -B html -s 0 -T $(TOC_LEVEL) -H ../doc/header.html ../doc/$< + +../html/doc.%: doc.% | ../html + cp $< ../html + +../info/%.info: %.sgml | ../info + @cd ../info && linuxdoc -B info ../doc/$< + clean: $(RM) -r ../html ../info @@ -45,22 +61,6 @@ ifneq "$(wildcard ../html)" "" @cd .. && zip cc65 html/*.* endif -doc: html info - -html: $(addprefix ../html/,$(SGMLS:.sgml=.html) doc.css doc.png) - -info: $(addprefix ../info/,$(SGMLS:.sgml=.info)) - -../html ../info: - @mkdir $@ - -../html/%.html: %.sgml header.html | ../html - @cd ../html && linuxdoc -B html -s 0 -T $(TOC_LEVEL) -H ../doc/header.html ../doc/$< - -../html/doc.%: doc.% | ../html - cp $< ../html - -../info/%.info: %.sgml | ../info - @cd ../info && linuxdoc -B info ../doc/$< - endif # CMD_EXE + +all mostlyclean: diff --git a/samples/Makefile b/samples/Makefile index bbf69c820..fc88d94b7 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -4,8 +4,9 @@ # This Makefile requires GNU make # -# Run 'make samples SYS=<target>' to build for another target system -SYS = c64 +# Run 'make SYS=<target>' or set a SYS env +# var to build for another target system. +SYS ?= c64 ifneq ($(shell echo),) CMD_EXE = 1 @@ -147,12 +148,12 @@ EXELIST_atarixl = $(EXELIST_atari) # -------------------------------------------------------------------------- # Rules to make the binaries and the disk -all: - samples: $(EXELIST_$(SYS)) disk: $(DISK_$(SYS)) +all: + # -------------------------------------------------------------------------- # Overlay rules. Overlays need special ld65 configuration files. Also, the # overlay file-names are shortenned to fit the Atari's 8.3-character limit. diff --git a/samples/README b/samples/README index b7476e354..a576c4032 100644 --- a/samples/README +++ b/samples/README @@ -12,8 +12,8 @@ Please note: * The makefile specifies the C64 as the default target system, because all but one of the programs run on this platform. When compiling for another system, you will have to change the line that specifies the target system - at the top of the makefile or specify the system with SYS=<target> on the - make command line. + at the top of the makefile, specify the system with SYS=<target> on the + make command line or set a SYS env var. List of supplied sample programs: From 5d9f4dc89d01ba8f5907e2a99ef4111554058e45 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 19 Jun 2016 17:38:37 -0400 Subject: [PATCH 0114/2161] Made the overlay demo programs compile for CBM targets again. <conio.h> includes target-specific headers; so, we didn't bother to include <cbm.h> where it is needed. But, '#include <conio.h>' was removed from some files; so now, we must include <cbm.h> explicitly. --- samples/multidemo.c | 1 + samples/overlaydemo.c | 1 + 2 files changed, 2 insertions(+) diff --git a/samples/multidemo.c b/samples/multidemo.c index 038b74d64..396d7344a 100644 --- a/samples/multidemo.c +++ b/samples/multidemo.c @@ -20,6 +20,7 @@ #include <fcntl.h> #include <unistd.h> #else +#include <cbm.h> #include <device.h> #endif diff --git a/samples/overlaydemo.c b/samples/overlaydemo.c index a4dc53931..7553f3d0e 100644 --- a/samples/overlaydemo.c +++ b/samples/overlaydemo.c @@ -15,6 +15,7 @@ #include <fcntl.h> #include <unistd.h> #else +#include <cbm.h> #include <device.h> #endif From ab10bd401446b4a886d475a909e23f932e59abad Mon Sep 17 00:00:00 2001 From: Joni Lapilainen <joni.lapilainen@gmail.com> Date: Thu, 23 Jun 2016 15:41:03 +0300 Subject: [PATCH 0115/2161] Fix typo in samples makefile --- samples/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Makefile b/samples/Makefile index fc88d94b7..e7fdfd393 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -238,7 +238,7 @@ install: $(if $(prefix),,$(error variable `prefix' must be set)) $(INSTALL) -d $(DESTDIR)$(samplesdir) $(INSTALL) -d $(DESTDIR)$(samplesdir)/geos - $(INSTALL) -d $$(DESTDIR)$(samplesdir)/tutorial + $(INSTALL) -d $(DESTDIR)$(samplesdir)/tutorial $(INSTALL) -m0644 *.* $(DESTDIR)$(samplesdir) $(INSTALL) -m0644 README $(DESTDIR)$(samplesdir) $(INSTALL) -m0644 Makefile $(DESTDIR)$(samplesdir) From 90b2f5aff86d1d22816831b4441f1c2aa482e726 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 2 Jul 2016 10:26:33 -0400 Subject: [PATCH 0116/2161] Fixed some code that adjusts an index after a deletion from a collection. --- src/common/coll.c | 13 +++++++------ src/common/coll.h | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/common/coll.c b/src/common/coll.c index aa2aa6470..8fb702bdc 100644 --- a/src/common/coll.c +++ b/src/common/coll.c @@ -161,7 +161,7 @@ void CollAppend (Collection* C, void* Item) { /* Insert the item at the end of the current list */ CollInsert (C, Item, C->Count); -} +} #endif @@ -341,22 +341,23 @@ void CollReplaceExpand (Collection* C, void* Item, unsigned Index) void CollMove (Collection* C, unsigned OldIndex, unsigned NewIndex) /* Move an item from one position in the collection to another. OldIndex -** is the current position of the item, NewIndex is the new index after +** is the current position of the item, NewIndex is the new index before ** the function has done it's work. Existing entries with indices NewIndex -** and up are moved one position upwards. +** and up might be moved one position upwards. */ { - /* Get the item and remove it from the collection */ + /* Get the item; and, remove it from the collection */ void* Item = CollAt (C, OldIndex); + CollDelete (C, OldIndex); /* Correct NewIndex if needed */ - if (NewIndex >= OldIndex) { + if (NewIndex > OldIndex) { /* Position has changed with removal */ --NewIndex; } - /* Now insert it at the new position */ + /* Now, insert it at the new position */ CollInsert (C, Item, NewIndex); } diff --git a/src/common/coll.h b/src/common/coll.h index 5114862c4..99e337d7a 100644 --- a/src/common/coll.h +++ b/src/common/coll.h @@ -268,9 +268,9 @@ void CollReplaceExpand (Collection* C, void* Item, unsigned Index); void CollMove (Collection* C, unsigned OldIndex, unsigned NewIndex); /* Move an item from one position in the collection to another. OldIndex -** is the current position of the item, NewIndex is the new index after +** is the current position of the item, NewIndex is the new index before ** the function has done it's work. Existing entries with indices NewIndex -** and up are moved one position upwards. +** and up might be moved one position upwards. */ void CollMoveMultiple (Collection* C, unsigned Start, unsigned Count, unsigned Target); From 401478327523e9b99bc32f557a51230bfdcd1b36 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 3 Jul 2016 02:14:33 -0400 Subject: [PATCH 0117/2161] Made the samples Makefile run cl65 only when we want a disk image. That change avoids an error message when we "make clean" from the top-level make-file (it removes the tools before it cleans the samples). --- samples/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/samples/Makefile b/samples/Makefile index e7fdfd393..00a9ce41d 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -34,6 +34,7 @@ else LD := $(if $(wildcard ../bin/ld65*),../bin/ld65,ld65) endif +ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),) TARGET_PATH := $(shell $(CL) --print-target-path) EMD := $(wildcard $(TARGET_PATH)/$(SYS)/drv/emd/*) @@ -54,6 +55,7 @@ DISK_apple2 = samples.dsk DISK_apple2enh = samples.dsk DISK_atari = samples.atr DISK_atarixl = samples.atr +endif # -------------------------------------------------------------------------- # System-dependent settings From a6eb7d076377db051e58d3656dd9e5adcb7f5c7d Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 3 Jul 2016 07:07:09 -0400 Subject: [PATCH 0118/2161] Fixed how ca65 handles some debug info from cc65. ca65 used to claim that an assembler error/warning was found on a C code line; and, that an Assembly line is only indirectly related to it. Now, ca65 says that the Assembly line has the problem; and, that the Assembly line was produced from the C line. --- src/ca65/error.c | 2 +- src/ca65/lineinfo.c | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ca65/error.c b/src/ca65/error.c index 38195d669..69446b3fc 100644 --- a/src/ca65/error.c +++ b/src/ca65/error.c @@ -144,7 +144,7 @@ static void AddNotifications (const Collection* LineInfos) break; case LI_TYPE_EXT: - Msg = "Assembler code generated from this line"; + Msg = "Assembly code generated from this line"; break; case LI_TYPE_MACRO: diff --git a/src/ca65/lineinfo.c b/src/ca65/lineinfo.c index 92fecec58..e6707dac4 100644 --- a/src/ca65/lineinfo.c +++ b/src/ca65/lineinfo.c @@ -368,6 +368,14 @@ void NewAsmLine (void) /* Start a new line using the current line info */ AsmLineInfo = StartLine (&CurTok.Pos, LI_TYPE_ASM, 0); + + /* If the first LineInfo in the list came from a .dbg line, then we want + ** errors and warnings to show it as an additional note, not as the primary + ** line. Therefore, swap the first two LineInfo items. + */ + if (GetLineInfoType (CollAtUnchecked (&CurLineInfo, 0)) == LI_TYPE_EXT) { + CollMove (&CurLineInfo, 1, 0); + } } From 97b517a8923e028ba06b4aab3e98aa2fd8d627f1 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 5 Jul 2016 17:07:39 +0200 Subject: [PATCH 0119/2161] sim65: add command line parameter to print number of CPU cycles at exit --- doc/sim65.sgml | 11 ++++++++++- src/sim65/6502.c | 2 ++ src/sim65/6502.h | 2 ++ src/sim65/main.c | 18 +++++++++++++++++- src/sim65/paravirt.c | 3 +++ 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 24b43831c..a2ebbac25 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -4,7 +4,7 @@ <title>sim65 Users Guide <author><url url="mailto:polluks@sdf.lonestar.org" name="Stefan A. Haubenthal"> -<date>2016-01-05 +<date>2016-07-05 <abstract> sim65 is a simulator for 6502 and 65C02 CPUs. It allows to test target @@ -31,12 +31,14 @@ The simulator is called as follows: Usage: sim65 [options] file [arguments] Short options: -h Help (this text) + -c Print amount of executed CPU cycles -v Increase verbosity -V Print the simulator version number -x <num> Exit simulator after <num> cycles Long options: --help Help (this text) + --cycles Print amount of executed CPU cycles --verbose Increase verbosity --version Print the simulator version number </verb></tscreen> @@ -53,6 +55,13 @@ Here is a description of all the command line options: Print the short option summary shown above. + <tag><tt>-c, --cycles</tt></tag> + + Print the number of executed CPU cycles when the program terminates. + The cycles for the final "<tt>jmp exit</tt>" are not included in this + count. + + <tag><tt>-v, --verbose</tt></tag> Increase the simulator verbosity. diff --git a/src/sim65/6502.c b/src/sim65/6502.c index 312eb2fe1..e6f358295 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -67,6 +67,8 @@ static unsigned HaveNMIRequest; /* IRQ request active */ static unsigned HaveIRQRequest; +/* flag to print cycles at program termination */ +int PrintCycles; /*****************************************************************************/ diff --git a/src/sim65/6502.h b/src/sim65/6502.h index 2cf2d4f1e..f8e894567 100644 --- a/src/sim65/6502.h +++ b/src/sim65/6502.h @@ -99,6 +99,8 @@ unsigned ExecuteInsn (void); unsigned long GetCycles (void); /* Return the total number of clock cycles executed */ +extern int PrintCycles; +/* flag to print cycles at program termination */ /* End of 6502.h */ diff --git a/src/sim65/main.c b/src/sim65/main.c index dab9b0be8..5405af29f 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -61,7 +61,7 @@ const char* ProgramFile; /* exit simulator after MaxCycles Cycles */ -unsigned long MaxCycles = 0; +unsigned long MaxCycles; /*****************************************************************************/ /* Code */ @@ -74,12 +74,14 @@ static void Usage (void) printf ("Usage: %s [options] file [arguments]\n" "Short options:\n" " -h\t\t\tHelp (this text)\n" + " -c\t\t\tPrint amount of executed CPU cycles\n" " -v\t\t\tIncrease verbosity\n" " -V\t\t\tPrint the simulator version number\n" " -x <num>\t\tExit simulator after <num> cycles\n" "\n" "Long options:\n" " --help\t\tHelp (this text)\n" + " --cycles\t\tPrint amount of executed CPU cycles\n" " --verbose\t\tIncrease verbosity\n" " --version\t\tPrint the simulator version number\n", ProgName); @@ -106,6 +108,15 @@ static void OptVerbose (const char* Opt attribute ((unused)), +static void OptCycles (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Set flag to print amount of cycles at the end */ +{ + PrintCycles = 1; +} + + + static void OptVersion (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Print the simulator version */ @@ -166,6 +177,7 @@ 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 }, }; @@ -196,6 +208,10 @@ int main (int argc, char* argv[]) OptHelp (Arg, 0); break; + case 'c': + OptCycles (Arg, 0); + break; + case 'v': OptVerbose (Arg, 0); break; diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 56211b5c1..f4fc3e285 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -156,6 +156,9 @@ static void PVArgs (CPURegs* Regs) static void PVExit (CPURegs* Regs) { Print (stderr, 1, "PVExit ($%02X)\n", Regs->AC); + if (PrintCycles) { + Print (stdout, 0, "%lu cycles\n", GetCycles ()); + } exit (Regs->AC); } From 85d755f2140afe67db35cd2e317c0e2ecb92b4ad Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 5 Jul 2016 17:10:10 +0200 Subject: [PATCH 0120/2161] fix indentation --- src/sim65/paravirt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index f4fc3e285..a13c670a2 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -157,7 +157,7 @@ static void PVExit (CPURegs* Regs) { Print (stderr, 1, "PVExit ($%02X)\n", Regs->AC); if (PrintCycles) { - Print (stdout, 0, "%lu cycles\n", GetCycles ()); + Print (stdout, 0, "%lu cycles\n", GetCycles ()); } exit (Regs->AC); From c2945bf1ff2a0faf48af0733e14fb0315f0cff5e Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 10 Jul 2016 04:11:07 -0400 Subject: [PATCH 0121/2161] Made the zlib's inflatemem()'s source file use enhanced instructions for all 65SC02-compatible CPUs (not only the 65C02). --- libsrc/zlib/inflatemem.s | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/libsrc/zlib/inflatemem.s b/libsrc/zlib/inflatemem.s index bcf473bdd..2a0e75e8e 100644 --- a/libsrc/zlib/inflatemem.s +++ b/libsrc/zlib/inflatemem.s @@ -9,6 +9,8 @@ .import incsp2 .importzp sp, sreg, ptr1, ptr2, ptr3, ptr4, tmp1 + .macpack cpu + ; -------------------------------------------------------------------------- ; ; Constants @@ -75,7 +77,7 @@ _inflatemem: sta inputPointer stx inputPointer+1 ; outputPointer = dest -.ifpc02 +.if (.cpu & CPU_ISET_65SC02) lda (sp) ldy #1 .else @@ -106,7 +108,7 @@ inflatemem_1: ; return outputPointer - dest; lda outputPointer -.ifpc02 +.if (.cpu & CPU_ISET_65SC02) sbc (sp) ; C flag is set ldy #1 .else @@ -156,14 +158,14 @@ inflateCopyBlock: moveBlock: ldy moveBlock_len beq moveBlock_1 -.ifpc02 +.if (.cpu & CPU_ISET_65SC02) .else ldy #0 .endif inc moveBlock_len+1 moveBlock_1: lda (0,x) -.ifpc02 +.if (.cpu & CPU_ISET_65SC02) sta (outputPointer) .else sta (outputPointer),y @@ -176,7 +178,7 @@ moveBlock_2: bne moveBlock_3 inc outputPointer+1 moveBlock_3: -.ifpc02 +.if (.cpu & CPU_ISET_65SC02) dey .else dec moveBlock_len @@ -312,7 +314,7 @@ inflateCodes_1: jsr fetchPrimaryCode bcs inflateCodes_2 ; Literal code -.ifpc02 +.if (.cpu & CPU_ISET_65SC02) sta (outputPointer) .else ldy #0 @@ -512,7 +514,7 @@ getValue: getBits: cpx #0 beq getBits_ret -.ifpc02 +.if (.cpu & CPU_ISET_65SC02) stz getBits_tmp dec getBits_tmp .else @@ -542,7 +544,7 @@ getBit: lsr getBit_hold bne getBit_ret pha -.ifpc02 +.if (.cpu & CPU_ISET_65SC02) lda (inputPointer) .else sty getBit_hold @@ -554,7 +556,7 @@ getBit: bne getBit_1 inc inputPointer+1 getBit_1: - ror a ; C flag is set + ror a ; (C flag was set) sta getBit_hold pla getBit_ret: @@ -668,6 +670,3 @@ bitsPointer_h: ; Sorted codes. sortedCodes: .res 256+1+29+30+2 - - - From 32d000fb4cfa292ee34dfb8dc025518be145cf9d Mon Sep 17 00:00:00 2001 From: Brad Smith <rainwarrior@gmail.com> Date: Mon, 11 Jul 2016 20:48:47 -0400 Subject: [PATCH 0122/2161] Fix broken rand() implementation. The high 8 bits were unused, reducing it to a 24-bit implementation (while still doing all the work for a 32-bit one). The best entropy is in the unused high byte, returning these bits in A instead of bits 8-15, which had considerably lower entropy (i.e. rand() & 255 was effectively a 16-bit LCG). --- libsrc/common/rand.s | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libsrc/common/rand.s b/libsrc/common/rand.s index 48a88b7c4..8ad7bcdb4 100644 --- a/libsrc/common/rand.s +++ b/libsrc/common/rand.s @@ -44,7 +44,6 @@ _rand: clc lda rand+1 adc #$59 sta rand+1 - pha lda rand+2 adc #$41 sta rand+2 @@ -53,8 +52,7 @@ _rand: clc lda rand+3 adc #$31 sta rand+3 - pla ; return bit 8-22 in (X,A) - rts + rts ; return bit (16-22,24-31) in (X,A) _srand: sta rand+0 ; Store the seed stx rand+1 From e7e65044e607f15b7d5b4e55abf7cdcb123993a8 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 19 Jul 2016 10:42:49 -0400 Subject: [PATCH 0123/2161] Used more mundane addressing in some of the instructions in "zlib/inflatemem.s". That avoids conflicts with ca65's future .setdp feature. --- libsrc/zlib/inflatemem.s | 41 ++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/libsrc/zlib/inflatemem.s b/libsrc/zlib/inflatemem.s index 2a0e75e8e..ea550c074 100644 --- a/libsrc/zlib/inflatemem.s +++ b/libsrc/zlib/inflatemem.s @@ -1,5 +1,6 @@ ; -; Piotr Fusik, 21.09.2003 +; 2003-09-21, Piotr Fusik +; 2016-07-19, Greg King ; ; unsigned __fastcall__ inflatemem (char* dest, const char* source); ; @@ -40,30 +41,30 @@ TREES_SIZE = 2*MAX_BITS ; ; Pointer to the compressed data. -inputPointer = ptr1 ; 2 bytes +inputPointer := ptr1 ; 2 bytes ; Pointer to the uncompressed data. -outputPointer = ptr2 ; 2 bytes +outputPointer := ptr2 ; 2 bytes ; Local variables. ; As far as there is no conflict, same memory locations are used ; for different variables. -inflateDynamicBlock_cnt = ptr3 ; 1 byte -inflateCodes_src = ptr3 ; 2 bytes -buildHuffmanTree_src = ptr3 ; 2 bytes -getNextLength_last = ptr3 ; 1 byte -getNextLength_index = ptr3+1 ; 1 byte +inflateDynamicBlock_cnt := ptr3 ; 1 byte +inflateCodes_src := ptr3 ; 2 bytes +buildHuffmanTree_src := ptr3 ; 2 bytes +getNextLength_last := ptr3 ; 1 byte +getNextLength_index := ptr3+1 ; 1 byte -buildHuffmanTree_ptr = ptr4 ; 2 bytes -fetchCode_ptr = ptr4 ; 2 bytes -getBits_tmp = ptr4 ; 1 byte +buildHuffmanTree_ptr := ptr4 ; 2 bytes +fetchCode_ptr := ptr4 ; 2 bytes +getBits_tmp := ptr4 ; 1 byte -moveBlock_len = sreg ; 2 bytes -inflateDynamicBlock_np = sreg ; 1 byte -inflateDynamicBlock_nd = sreg+1 ; 1 byte +moveBlock_len := sreg ; 2 bytes +inflateDynamicBlock_np := sreg ; 1 byte +inflateDynamicBlock_nd := sreg+1 ; 1 byte -getBit_hold = tmp1 ; 1 byte +getBit_hold := tmp1 ; 1 byte ; -------------------------------------------------------------------------- @@ -138,8 +139,8 @@ inflateCopyBlock: ldy #1 sty getBit_hold ; Get 16-bit length - ldx #inputPointer - lda (0,x) + ldx #0 + lda (inputPointer,x) sta moveBlock_len lda (inputPointer),y sta moveBlock_len+1 @@ -164,15 +165,15 @@ moveBlock: .endif inc moveBlock_len+1 moveBlock_1: - lda (0,x) + lda (inputPointer,x) .if (.cpu & CPU_ISET_65SC02) sta (outputPointer) .else sta (outputPointer),y .endif - inc 0,x + inc inputPointer bne moveBlock_2 - inc 1,x + inc inputPointer+1 moveBlock_2: inc outputPointer bne moveBlock_3 From 8f0146f14ad539da109d64ba5535ebe211c67e6c Mon Sep 17 00:00:00 2001 From: "David M. Lloyd" <david.lloyd@redhat.com> Date: Thu, 28 Jul 2016 11:43:52 -0500 Subject: [PATCH 0124/2161] Add missing WDC instructions --- src/ca65/instr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 500db1985..966a5cd98 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -376,7 +376,7 @@ static const struct { /* Instruction table for the 65C02 */ static const struct { unsigned Count; - InsDesc Ins[98]; + InsDesc Ins[100]; } InsTab65C02 = { sizeof (InsTab65C02.Ins) / sizeof (InsTab65C02.Ins[0]), { @@ -467,6 +467,7 @@ static const struct { { "SMB6", 0x0000004, 0xE7, 1, PutAll }, { "SMB7", 0x0000004, 0xF7, 1, PutAll }, { "STA", 0x000A66C, 0x80, 0, PutAll }, + { "STP", 0x0000001, 0xdb, 0, PutAll }, { "STX", 0x000010c, 0x82, 1, PutAll }, { "STY", 0x000002c, 0x80, 1, PutAll }, { "STZ", 0x000006c, 0x04, 5, PutAll }, @@ -477,7 +478,8 @@ static const struct { { "TSX", 0x0000001, 0xba, 0, PutAll }, { "TXA", 0x0000001, 0x8a, 0, PutAll }, { "TXS", 0x0000001, 0x9a, 0, PutAll }, - { "TYA", 0x0000001, 0x98, 0, PutAll } + { "TYA", 0x0000001, 0x98, 0, PutAll }, + { "WAI", 0x0000001, 0xcb, 0, PutAll } } }; From 9accf983e1ceb4635493b72ed0971deeba31e2d0 Mon Sep 17 00:00:00 2001 From: Chris Cacciatore <chris.cacciatore@gmail.com> Date: Tue, 2 Aug 2016 11:31:09 -0700 Subject: [PATCH 0125/2161] Reporting sym name for incompatible pointer types. --- src/cc65/typeconv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index e4edd6a2e..78f43a50c 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -237,7 +237,7 @@ void TypeConversion (ExprDesc* Expr, Type* NewType) switch (TypeCmp (NewType, Expr->Type)) { case TC_INCOMPATIBLE: - Error ("Incompatible pointer types"); + Error ("Incompatible pointer types at '%s'", (!Expr->Sym? Expr->Sym->Name : "Unknown")); break; case TC_QUAL_DIFF: From 33b1d82791fde5e8e06bc2c06d276a4d0fafdcbb Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 2 Aug 2016 16:38:39 -0400 Subject: [PATCH 0126/2161] Added the WDC65c02S WAI and STP mnemonics to the disassembler. --- src/da65/opc65c02.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/da65/opc65c02.c b/src/da65/opc65c02.c index 00520e729..1351f5eee 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 */ - { "", 1, flIllegal, OH_Illegal, }, /* $cb */ + { "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 */ @@ -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 */ - { "", 1, flIllegal, OH_Illegal, }, /* $db */ + { "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 */ From 2c03b9a1bc0dd722d6e56b488a0e3289ecfb795f Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 7 Aug 2016 15:47:45 -0400 Subject: [PATCH 0127/2161] Added C-code interfaces for the CBM Kernal functions SCNKEY and UDTIM. --- doc/funcref.sgml | 71 +++++++++++++++++++++++++++++++++++++----- include/cbm.h | 2 ++ libsrc/cbm/c_scnkey.s | 8 +++++ libsrc/cbm/c_udtim.s | 8 +++++ libsrc/plus4/kscnkey.s | 19 +++++++++++ libsrc/plus4/kudtim.s | 19 +++++++++++ 6 files changed, 119 insertions(+), 8 deletions(-) create mode 100644 libsrc/cbm/c_scnkey.s create mode 100644 libsrc/cbm/c_udtim.s create mode 100644 libsrc/plus4/kscnkey.s create mode 100644 libsrc/plus4/kudtim.s diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 64e519238..d4c2f3fe1 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -3,7 +3,7 @@ <article> <title>cc65 function reference <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2016-06-08 +<date>2016-08-07 <abstract> cc65 is a C compiler for 6502 based systems. This function reference describes @@ -169,8 +169,11 @@ function. <item><ref id="cbm_k_open" name="cbm_k_open"> <item><ref id="cbm_k_readst" name="cbm_k_readst"> <item><ref id="cbm_k_save" name="cbm_k_save"> +<item><ref id="cbm_k_scnkey" name="cbm_k_scnkey"> <item><ref id="cbm_k_setlfs" name="cbm_k_setlfs"> <item><ref id="cbm_k_setnam" name="cbm_k_setnam"> +<item><ref id="cbm_k_talk" name="cbm_k_talk"> +<item><ref id="cbm_k_udtim" name="cbm_k_udtim"> <item><ref id="cbm_k_unlsn" name="cbm_k_unlsn"> <!-- <item><ref id="cbm_load" name="cbm_load"> --> <!-- <item><ref id="cbm_open" name="cbm_open"> --> @@ -2020,6 +2023,31 @@ only be used in presence of a prototype. </quote> +<sect1>cbm_k_scnkey<label id="cbm_k_scnkey"><p> + +<quote> +<descrip> +<tag/Function/Scan the keyboard matrix. +<tag/Header/<tt/<ref id="cbm.h" name="cbm.h">/ +<tag/Declaration/<tt/void cbm_k_scnkey (void);/ +<tag/Description/This function looks at the switches in the keyboard, to see +if any of them are being pressed. If they are, then code numbers for them are +stored in RAM. Other functions use those numbers to input text. Normally, +the keyboard is scanned by the Kernal's Interrupt Service Routine. But, if +you divert the "Jiffy interrupt" to a C-code ISR, then that ISR must call this +function, in order to provide input from the keyboard. +<tag/Availability/cc65 +<tag/See also/ +<ref id="cbm_k_getin" name="cbm_k_getin">, +<ref id="cbm_k_udtim" name="cbm_k_udtim">, +<ref id="cgetc" name="cgetc">, +<!-- <ref id="getc" name="getc"> --> +<!-- <ref id="getchar" name="getchar"> --> +<tag/Example/None. +</descrip> +</quote> + + <sect1>cbm_k_setlfs<label id="cbm_k_setlfs"><p> <quote> @@ -2085,6 +2113,27 @@ only be used in presence of a prototype. </quote> +<sect1>cbm_k_udtim<label id="cbm_k_udtim"><p> + +<quote> +<descrip> +<tag/Function/Update the Jiffy clock. +<tag/Header/<tt/<ref id="cbm.h" name="cbm.h">/ +<tag/Declaration/<tt/void cbm_k_udtim (void);/ +<tag/Description/This function adds one count to the Jiffy clock. That clock +counts sixtieths of a second. It is used by the library's <tt/clock()/ +function. Normally, the Jiffy clock is updated by the Kernal's Interrupt +Service Routine. But, if you divert the "Jiffy interrupt" to a C-code ISR, +then that ISR must call this function, in order to keep the clock valid. +<tag/Availability/cc65 +<tag/See also/ +<ref id="cbm_k_scnkey" name="cbm_k_scnkey">, +<ref id="clock" name="clock"> +<tag/Example/None. +</descrip> +</quote> + + <sect1>cbm_k_unlsn<label id="cbm_k_unlsn"><p> <quote> @@ -2164,15 +2213,18 @@ only be used in presence of a prototype. <tag/Header/<tt/<ref id="conio.h" name="conio.h">/ <tag/Declaration/<tt/char cgetc (void);/ <tag/Description/The function reads a character from the keyboard. If there is -no character available, <tt/cgetc/ waits until the user presses a key. If the +no character available, <tt/cgetc()/ waits until the user presses a key. If the cursor is enabled by use of the <tt/cursor/ function, a blinking cursor is displayed while waiting. <tag/Notes/<itemize> -<item>If the system supports a keyboard buffer, <tt/cgetc/ will fetch a key -from this buffer and wait only if the buffer is empty. +<item>If the system supports a keyboard buffer, <tt/cgetc()/ will fetch a key +from that buffer; and, wait only if the buffer is empty. +<item>The keyboard must be scanned periodically, in order for this function to +see anything that you type. (See the description of <tt/cbm_k_scnkey()/.) </itemize> <tag/Availability/cc65 <tag/See also/ +<ref id="cbm_k_scnkey" name="cbm_k_scnkey">, <ref id="cursor" name="cursor">, <ref id="kbhit" name="kbhit"> <tag/Example/None. @@ -2262,16 +2314,19 @@ used in presence of a prototype. <tag/Header/<tt/<ref id="time.h" name="time.h">/ <tag/Declaration/<tt/clock_t clock (void);/ <tag/Description/The <tt/clock/ function returns an approximaton of processor -time used by the program. The time is returned in implementation defined +time used by the program. The time is returned in implementation-defined units. It can be converted to seconds by dividing by the value of the macro <tt/CLOCKS_PER_SEC/. <tag/Notes/<itemize> -<item>Since the machines, cc65 generated programs run on, cannot run multiple -processes, the function will actually return the time since some -implementation defined point in the past. +<item>Since the machines that cc65-generated programs run on cannot run multiple +processes, the function actually will return the time since some +implementation-defined point in the past. +<item>The Jiffy clock must be "running", in order for this function to return +changing values. (See the description of <tt/cbm_k_udtim()/.) </itemize> <tag/Availability/ISO 9899 <tag/See also/ +<ref id="cbm_k_udtim" name="cbm_k_udtim">, <ref id="time" name="time"> <tag/Example/None. </descrip> diff --git a/include/cbm.h b/include/cbm.h index 701924d57..241d70a6e 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -187,10 +187,12 @@ unsigned int __fastcall__ cbm_k_load(unsigned char flag, unsigned addr); unsigned char cbm_k_open (void); unsigned char cbm_k_readst (void); unsigned char __fastcall__ cbm_k_save(unsigned int start, unsigned int end); +void cbm_k_scnkey (void); void __fastcall__ cbm_k_setlfs (unsigned char LFN, unsigned char DEV, unsigned char SA); void __fastcall__ cbm_k_setnam (const char* Name); void __fastcall__ cbm_k_talk (unsigned char dev); +void cbm_k_udtim (void); void cbm_k_unlsn (void); diff --git a/libsrc/cbm/c_scnkey.s b/libsrc/cbm/c_scnkey.s new file mode 100644 index 000000000..cdae50e7b --- /dev/null +++ b/libsrc/cbm/c_scnkey.s @@ -0,0 +1,8 @@ +; +; 2016-08-07, Greg King +; +; void cbm_k_scnkey (void); +; + + .import SCNKEY + .export _cbm_k_scnkey := SCNKEY diff --git a/libsrc/cbm/c_udtim.s b/libsrc/cbm/c_udtim.s new file mode 100644 index 000000000..b867efaba --- /dev/null +++ b/libsrc/cbm/c_udtim.s @@ -0,0 +1,8 @@ +; +; 2016-08-07, Greg King +; +; void cbm_k_udtim (void); +; + + .import UDTIM + .export _cbm_k_udtim := UDTIM diff --git a/libsrc/plus4/kscnkey.s b/libsrc/plus4/kscnkey.s new file mode 100644 index 000000000..e7e2ab986 --- /dev/null +++ b/libsrc/plus4/kscnkey.s @@ -0,0 +1,19 @@ +; +; 2002-11-22, Ullrich von Bassewitz +; 2016-08-07, Greg King +; +; SCNKEY replacement function +; + + .export SCNKEY + + .include "plus4.inc" + +.segment "LOWCODE" ; Must go into low memory + +.proc SCNKEY + sta ENABLE_ROM ; Enable the ROM + jsr $FF9F ; Call the ROM routine + sta ENABLE_RAM ; Switch back to RAM + rts ; Return to caller +.endproc diff --git a/libsrc/plus4/kudtim.s b/libsrc/plus4/kudtim.s new file mode 100644 index 000000000..d35190788 --- /dev/null +++ b/libsrc/plus4/kudtim.s @@ -0,0 +1,19 @@ +; +; 2002-11-22, Ullrich von Bassewitz +; 2016-08-07, Greg King +; +; UDTIM replacement function +; + + .export UDTIM + + .include "plus4.inc" + +.segment "LOWCODE" ; Must go into low memory + +.proc UDTIM + sta ENABLE_ROM ; Enable the ROM + jsr $FFEA ; Call the ROM routine + sta ENABLE_RAM ; Switch back to RAM + rts ; Return to caller +.endproc From f9482a1b72c33becfdb0106bf06a1a66f29dd006 Mon Sep 17 00:00:00 2001 From: Chris Cacciatore <chris.cacciatore@gmail.com> Date: Tue, 9 Aug 2016 12:46:51 -0700 Subject: [PATCH 0128/2161] Fixed test negation. (#329) Fixed test negation. --- src/cc65/typeconv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 78f43a50c..47ab993c1 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -237,7 +237,7 @@ void TypeConversion (ExprDesc* Expr, Type* NewType) switch (TypeCmp (NewType, Expr->Type)) { case TC_INCOMPATIBLE: - Error ("Incompatible pointer types at '%s'", (!Expr->Sym? Expr->Sym->Name : "Unknown")); + Error ("Incompatible pointer types at '%s'", (Expr->Sym? Expr->Sym->Name : "Unknown")); break; case TC_QUAL_DIFF: From 22d1f1da1b481bafc7247f8e2531077a1cc34c20 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 10 Aug 2016 11:38:11 +0200 Subject: [PATCH 0129/2161] Minor style fix. --- samples/Makefile | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index 00a9ce41d..3a60798da 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -35,26 +35,26 @@ else endif ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),) -TARGET_PATH := $(shell $(CL) --print-target-path) + TARGET_PATH := $(shell $(CL) --print-target-path) -EMD := $(wildcard $(TARGET_PATH)/$(SYS)/drv/emd/*) -MOU := $(wildcard $(TARGET_PATH)/$(SYS)/drv/mou/*) -TGI := $(wildcard $(TARGET_PATH)/$(SYS)/drv/tgi/*) + EMD := $(wildcard $(TARGET_PATH)/$(SYS)/drv/emd/*) + MOU := $(wildcard $(TARGET_PATH)/$(SYS)/drv/mou/*) + TGI := $(wildcard $(TARGET_PATH)/$(SYS)/drv/tgi/*) -# This one comes with VICE -C1541 ?= c1541 + # This one comes with VICE + C1541 ?= c1541 -# For this one see http://applecommander.sourceforge.net/ -AC ?= ac.jar + # For this one see http://applecommander.sourceforge.net/ + AC ?= ac.jar -# For this one see http://www.horus.com/~hias/atari/ -DIR2ATR ?= dir2atr + # For this one see http://www.horus.com/~hias/atari/ + DIR2ATR ?= dir2atr -DISK_c64 = samples.d64 -DISK_apple2 = samples.dsk -DISK_apple2enh = samples.dsk -DISK_atari = samples.atr -DISK_atarixl = samples.atr + DISK_c64 = samples.d64 + DISK_apple2 = samples.dsk + DISK_apple2enh = samples.dsk + DISK_atari = samples.atr + DISK_atarixl = samples.atr endif # -------------------------------------------------------------------------- From bad84121319ab4846de73b62e14b3cdcd19a9399 Mon Sep 17 00:00:00 2001 From: Chris Cacciatore <chris.cacciatore@gmail.com> Date: Thu, 11 Aug 2016 16:46:48 -0700 Subject: [PATCH 0130/2161] All programs print version and exit successfully. * All programs are now using the ProgName variable as well. --- src/ar65/main.c | 2 +- src/ca65/main.c | 3 ++- src/cc65/main.c | 2 +- src/chrcvt65/main.c | 1 + src/cl65/main.c | 3 ++- src/co65/main.c | 3 ++- src/da65/main.c | 3 ++- src/grc65/main.c | 3 ++- src/ld65/main.c | 3 ++- src/od65/main.c | 1 + src/sim65/main.c | 3 ++- src/sp65/main.c | 1 + 12 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/ar65/main.c b/src/ar65/main.c index 9b9097ea4..a1839bad2 100644 --- a/src/ar65/main.c +++ b/src/ar65/main.c @@ -121,7 +121,7 @@ int main (int argc, char* argv []) break; case 'V': - fprintf (stderr, "ar65 V%s\n", GetVersionAsString ()); + fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); break; default: diff --git a/src/ca65/main.c b/src/ca65/main.c index 0016c46f3..a67319747 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -619,7 +619,8 @@ static void OptVersion (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Print the assembler version */ { - fprintf (stderr, "ca65 V%s\n", GetVersionAsString ()); + fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); + exit(EXIT_SUCCESS); } diff --git a/src/cc65/main.c b/src/cc65/main.c index abe2af56e..afbec43d7 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -742,7 +742,7 @@ static void OptVersion (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Print the compiler version */ { - fprintf (stderr, "cc65 V%s\n", GetVersionAsString ()); + fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); exit (EXIT_SUCCESS); } diff --git a/src/chrcvt65/main.c b/src/chrcvt65/main.c index 8685e06b9..7e7183e0a 100644 --- a/src/chrcvt65/main.c +++ b/src/chrcvt65/main.c @@ -220,6 +220,7 @@ static void OptVersion (const char* Opt attribute ((unused)), { fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); + exit(EXIT_SUCCESS); } diff --git a/src/cl65/main.c b/src/cl65/main.c index 654bd97b2..7bdbe7a8a 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -1233,7 +1233,8 @@ static void OptVersion (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Print version number */ { - fprintf (stderr, "cl65 V%s\n", GetVersionAsString ()); + fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); + exit(EXIT_SUCCESS); } diff --git a/src/co65/main.c b/src/co65/main.c index 5e0ee2ed7..43d263516 100644 --- a/src/co65/main.c +++ b/src/co65/main.c @@ -263,7 +263,8 @@ static void OptVersion (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Print the assembler version */ { - fprintf (stderr, "co65 V%s\n", GetVersionAsString ()); + fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); + exit(EXIT_SUCCESS); } diff --git a/src/da65/main.c b/src/da65/main.c index 8c37e1ae2..0b0bf19e7 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -340,7 +340,8 @@ static void OptVersion (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Print the disassembler version */ { - fprintf (stderr, "da65 V%s\n", GetVersionAsString ()); + fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); + exit(EXIT_SUCCESS); } diff --git a/src/grc65/main.c b/src/grc65/main.c index 1b417c64d..2a1fef953 100644 --- a/src/grc65/main.c +++ b/src/grc65/main.c @@ -166,7 +166,8 @@ static void OptVersion (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Print the program version */ { - fprintf (stderr, "grc65 V%s\n", GetVersionAsString ()); + fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); + exit(EXIT_SUCCESS); } diff --git a/src/ld65/main.c b/src/ld65/main.c index 95ed14396..74511a48a 100644 --- a/src/ld65/main.c +++ b/src/ld65/main.c @@ -543,7 +543,8 @@ static void OptVersion (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Print the assembler version */ { - fprintf (stderr, "ld65 V%s\n", GetVersionAsString ()); + fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); + exit(EXIT_SUCCESS); } diff --git a/src/od65/main.c b/src/od65/main.c index 802290ffd..2d23f4202 100644 --- a/src/od65/main.c +++ b/src/od65/main.c @@ -209,6 +209,7 @@ static void OptVersion (const char* Opt attribute ((unused)), /* Print the assembler version */ { fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); + exit(EXIT_SUCCESS); } diff --git a/src/sim65/main.c b/src/sim65/main.c index 5405af29f..f7f73165a 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -121,7 +121,8 @@ static void OptVersion (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Print the simulator version */ { - fprintf (stderr, "sim65 V%s\n", GetVersionAsString ()); + fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); + exit(EXIT_SUCCESS); } static void OptQuitXIns (const char* Opt attribute ((unused)), diff --git a/src/sp65/main.c b/src/sp65/main.c index 32cc1b936..828a48fc8 100644 --- a/src/sp65/main.c +++ b/src/sp65/main.c @@ -286,6 +286,7 @@ static void OptVersion (const char* Opt attribute ((unused)), /* Print the assembler version */ { fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); + exit(EXIT_SUCCESS); } From 7f4b14ee49464b32743159408ac23e02ca1e8c07 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sun, 14 Aug 2016 19:33:09 +0200 Subject: [PATCH 0131/2161] SMC macro fixes for changed .paramcount and byte overflow behavior --- asminc/smc.inc | 52 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/asminc/smc.inc b/asminc/smc.inc index 383417c3d..8a06f3222 100644 --- a/asminc/smc.inc +++ b/asminc/smc.inc @@ -1,7 +1,7 @@ ; smc.mac ; ca65 Macro-Pack for Self Modifying Code (SMC) ; -; (c) Christian Krüger, latest change: 09-Nov-2011 +; (c) Christian Krüger, latest change: 17-Jul-2016 ; ; This software is provided 'as-is', without any expressed or implied ; warranty. In no event will the authors be held liable for any damages @@ -53,7 +53,7 @@ _SMCDesignator: statement .endmacro .macro SMC_TransferOpcode label, opcode, register -.if .paramcount = 2 .or .match ({register}, a) +.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, ) lda #opcode sta _SMCDesignator .elseif .match ({register}, x) @@ -62,44 +62,52 @@ _SMCDesignator: statement .elseif .match ({register}, y) ldy #opcode sty _SMCDesignator +.else + .error "Invalid usage of macro 'SMC_TransferOpcode'" .endif .endmacro .macro SMC_LoadOpcode label, register -.if .paramcount = 1 .or .match ({register}, a) +.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) lda _SMCDesignator .elseif .match ({register}, x) ldx _SMCDesignator .elseif .match ({register}, y) ldy _SMCDesignator +.else + .error "Invalid usage of macro 'SMC_TransferOpcode'" .endif .endmacro .macro SMC_StoreOpcode label, register -.if .paramcount = 1 .or .match ({register}, a) +.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) sta _SMCDesignator .elseif .match ({register}, x) stx _SMCDesignator .elseif .match ({register}, y) sty _SMCDesignator +.else + .error "Invalid usage of macro 'SMC_StoreOpcode'" .endif .endmacro .macro SMC_ChangeBranch label, destination, register -.if .paramcount = 2 .or .match ({register}, a) - lda #(destination - _SMCDesignator -2) +.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, ) + lda #(<(destination - _SMCDesignator -2)) sta _SMCDesignator+1 .elseif .match ({register}, x) - ldx #(destination - _SMCDesignator - 2) + ldx #(<(destination - _SMCDesignator - 2)) stx _SMCDesignator+1 .elseif .match ({register}, y) - ldy #(destination - _SMCDesignator - 2) + ldy #(<(destination - _SMCDesignator - 2)) sty _SMCDesignator+1 +.else + .error "Invalid usage of macro 'SMC_ChangeBranch'" .endif .endmacro .macro SMC_TransferValue label, value, register -.if .paramcount = 2 .or .match ({register}, a) +.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, ) lda value sta _SMCDesignator+1 .elseif .match ({register}, x) @@ -108,26 +116,32 @@ _SMCDesignator: statement .elseif .match ({register}, y) ldy value sty _SMCDesignator+1 +.else + .error "Invalid usage of macro 'SMC_TransferValue'" .endif .endmacro .macro SMC_LoadValue label, register -.if .paramcount = 1 .or .match ({register}, a) +.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) lda _SMCDesignator+1 .elseif .match ({register}, x) ldx _SMCDesignator+1 .elseif .match ({register}, y) ldy _SMCDesignator+1 +.else + .error "Invalid usage of macro 'SMC_LoadValue'" .endif .endmacro .macro SMC_StoreValue label, register -.if .paramcount = 1 .or .match ({register}, a) +.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) sta _SMCDesignator+1 .elseif .match ({register}, x) stx _SMCDesignator+1 .elseif .match ({register}, y) sty _SMCDesignator+1 +.else + .error "Invalid usage of macro 'SMC_StoreValue'" .endif .endmacro @@ -145,7 +159,7 @@ SMC_StoreValue label, register .endmacro .macro SMC_TransferHighByte label, value, register -.if .paramcount = 2 .or .match ({register}, a) +.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, ) lda value sta _SMCDesignator+2 .elseif .match ({register}, x) @@ -154,31 +168,37 @@ SMC_StoreValue label, register .elseif .match ({register}, y) ldy value sty _SMCDesignator+2 +.else + .error "Invalid usage of macro 'SMC_TransferHighByte'" .endif .endmacro .macro SMC_LoadHighByte label, register -.if .paramcount = 1 .or .match ({register}, a) +.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) lda _SMCDesignator+2 .elseif .match ({register}, x) ldx _SMCDesignator+2 .elseif .match ({register}, y) ldy _SMCDesignator+2 +.else + .error "Invalid usage of macro 'SMC_LoadHighByte'" .endif .endmacro .macro SMC_StoreHighByte label, register -.if .paramcount = 1 .or .match ({register}, a) +.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) sta _SMCDesignator+2 .elseif .match ({register}, x) stx _SMCDesignator+2 .elseif .match ({register}, y) sty _SMCDesignator+2 +.else + .error "Invalid usage of macro 'SMC_StoreHighByte'" .endif .endmacro .macro SMC_TransferAddressSingle label, address, register -.if .paramcount = 2 .or .match ((register), a) +.if .paramcount = 2 .or .match ((register), a) .or .match ({register}, ) .if (.match (.left (1, {address}), #)) ; immediate mode lda #<(.right (.tcount ({address})-1, {address})) @@ -220,6 +240,8 @@ SMC_StoreValue label, register ldy 1+(address) sty _SMCDesignator+2 .endif +.else + .error "Invalid usage of macro 'SMC_TransferAddressSingle'" .endif .endmacro From aea312746b595aad1d76097672edee4a2a2ec071 Mon Sep 17 00:00:00 2001 From: Irgendwer <C.Krueger.B@web.de> Date: Sun, 14 Aug 2016 19:35:35 +0200 Subject: [PATCH 0132/2161] Update smc.inc --- asminc/smc.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asminc/smc.inc b/asminc/smc.inc index 8a06f3222..d5752a5f5 100644 --- a/asminc/smc.inc +++ b/asminc/smc.inc @@ -1,7 +1,7 @@ ; smc.mac ; ca65 Macro-Pack for Self Modifying Code (SMC) ; -; (c) Christian Krüger, latest change: 17-Jul-2016 +; (c) Christian Krüger, latest change: 17-Jul-2016 ; ; This software is provided 'as-is', without any expressed or implied ; warranty. In no event will the authors be held liable for any damages @@ -75,7 +75,7 @@ _SMCDesignator: statement .elseif .match ({register}, y) ldy _SMCDesignator .else - .error "Invalid usage of macro 'SMC_TransferOpcode'" + .error "Invalid usage of macro 'SMC_LoadOpcode'" .endif .endmacro From 3bd3fd874994a669a554b41e3b9d3b31f3c65534 Mon Sep 17 00:00:00 2001 From: Chris Cacciatore <chris.cacciatore@gmail.com> Date: Sun, 14 Aug 2016 19:55:03 -0700 Subject: [PATCH 0133/2161] Removed check for LCURLY in switch statements. --- src/cc65/swstmt.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/cc65/swstmt.c b/src/cc65/swstmt.c index 0aefc051c..f71c3e40a 100644 --- a/src/cc65/swstmt.c +++ b/src/cc65/swstmt.c @@ -144,11 +144,6 @@ void SwitchStatement (void) /* Create a loop so we may use break. */ AddLoop (ExitLabel, 0); - /* Make sure a curly brace follows */ - if (CurTok.Tok != TOK_LCURLY) { - Error ("`{' expected"); - } - /* Parse the following statement, which will actually be a compound ** statement because of the curly brace at the current input position */ From c4823c6fd4c152c6cdf037984a804b35969114d2 Mon Sep 17 00:00:00 2001 From: Chris Cacciatore <chris.cacciatore@gmail.com> Date: Mon, 15 Aug 2016 11:26:03 -0700 Subject: [PATCH 0134/2161] Added Duff's Device to tests. --- test/val/duffs-device.c | 76 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 test/val/duffs-device.c diff --git a/test/val/duffs-device.c b/test/val/duffs-device.c new file mode 100644 index 000000000..effb33bb2 --- /dev/null +++ b/test/val/duffs-device.c @@ -0,0 +1,76 @@ +/* + !!DESCRIPTION!! Implementation of Duff's device (loop unrolling). + !!ORIGIN!! + !!LICENCE!! GPL, read COPYING.GPL +*/ + +#include <stdio.h> +#include <limits.h> + +#define ASIZE (100) + +unsigned char success=0; +unsigned char failures=0; +unsigned char dummy=0; + +#ifdef SUPPORT_BIT_TYPES +bit bit0 = 0; +#endif + +void done() +{ + dummy++; +} + +int acmp(char* a, char* b, int count) +{ + int i; + + for(i = 0; i < count; i++) { + if(a[i] != b[i]) { + return 1; + } + } + return 0; +} + +void duffit (char* to, char* from, int count) +{ + int n = (count + 7) / 8; + + switch(count % 8) { + case 0: do { *to++ = *from++; + case 7: *to++ = *from++; + case 6: *to++ = *from++; + case 5: *to++ = *from++; + case 4: *to++ = *from++; + case 3: *to++ = *from++; + case 2: *to++ = *from++; + case 1: *to++ = *from++; + } while(--n > 0); + } +} + +int main(void) +{ + char a[ASIZE] = {1}; + char b[ASIZE] = {2}; + + /* a and b should be different */ + if(!acmp(a, b, ASIZE)) { + failures++; + } + + duffit(a, b, ASIZE); + + /* a and b should be the same */ + if(acmp(a, b, ASIZE)) { + failures++; + } + + success=failures; + done(); + printf("failures: %d\n",failures); + + return failures; +} From ac4bdbd411af5cafe1062693816b806f51f3b6e7 Mon Sep 17 00:00:00 2001 From: Chris Cacciatore <chris.cacciatore@gmail.com> Date: Mon, 15 Aug 2016 11:36:50 -0700 Subject: [PATCH 0135/2161] Now testing switch statements with empty bodies. --- test/val/switch2.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 test/val/switch2.c diff --git a/test/val/switch2.c b/test/val/switch2.c new file mode 100644 index 000000000..00206b0f6 --- /dev/null +++ b/test/val/switch2.c @@ -0,0 +1,39 @@ +/* + !!DESCRIPTION!! Testing empty bodied switch statements. + !!ORIGIN!! + !!LICENCE!! GPL, read COPYING.GPL +*/ + +#include <stdio.h> + +unsigned char success=0; +unsigned char failures=0; +unsigned char dummy=0; + +void done() +{ + dummy++; +} + +void switch_no_body(void) +{ + switch(0); +} + +void switch_empty_body(void) +{ + switch(0) {}; +} + +/* only worried about this file compiling successfully */ +int main(void) +{ + switch_no_body(); + switch_empty_body(); + + success=failures; + done(); + printf("failures: %d\n",failures); + + return failures; +} From 024f66a84f48cc78193a473e2aff5bd670380797 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Fri, 19 Aug 2016 17:27:41 +0200 Subject: [PATCH 0136/2161] Allow use of different charmaps on Atari target --- include/atari_atascii_charmap.h | 304 +++++++++++++++++++++++++++++++ include/atari_screen_charmap.h | 304 +++++++++++++++++++++++++++++++ testcode/lib/atari/charmapping.c | 63 +++++++ 3 files changed, 671 insertions(+) create mode 100644 include/atari_atascii_charmap.h create mode 100644 include/atari_screen_charmap.h create mode 100644 testcode/lib/atari/charmapping.c diff --git a/include/atari_atascii_charmap.h b/include/atari_atascii_charmap.h new file mode 100644 index 000000000..78a297f4c --- /dev/null +++ b/include/atari_atascii_charmap.h @@ -0,0 +1,304 @@ +/*****************************************************************************/ +/* */ +/* atari_atascii_charmap.h */ +/* */ +/* Atari system standard string mapping (ISO-8859-1 -> AtASCII) */ +/* */ +/* */ +/* */ +/* (C) 2016 Christian Krueger */ +/* */ +/* */ +/* 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. */ +/* */ +/*****************************************************************************/ + +/* No include guard here! Multiple use in one file may be intentional. */ + +#pragma charmap (0x00, 0x00) +#pragma charmap (0x01, 0x01) +#pragma charmap (0x02, 0x02) +#pragma charmap (0x03, 0x03) +#pragma charmap (0x04, 0x04) +#pragma charmap (0x05, 0x05) +#pragma charmap (0x06, 0x06) +#pragma charmap (0x07, 0xFD) +#pragma charmap (0x08, 0x08) +#pragma charmap (0x09, 0x7F) +#pragma charmap (0x0A, 0x9B) +#pragma charmap (0x0B, 0x0B) +#pragma charmap (0x0C, 0x7D) +#pragma charmap (0x0D, 0x0D) +#pragma charmap (0x0E, 0x0E) +#pragma charmap (0x0F, 0x0F) + +#pragma charmap (0x10, 0x10) +#pragma charmap (0x11, 0x11) +#pragma charmap (0x12, 0x12) +#pragma charmap (0x13, 0x13) +#pragma charmap (0x14, 0x14) +#pragma charmap (0x15, 0x15) +#pragma charmap (0x16, 0x16) +#pragma charmap (0x17, 0x17) +#pragma charmap (0x18, 0x18) +#pragma charmap (0x19, 0x19) +#pragma charmap (0x1A, 0x1A) +#pragma charmap (0x1B, 0x1B) +#pragma charmap (0x1C, 0x1C) +#pragma charmap (0x1D, 0x1D) +#pragma charmap (0x1E, 0x1E) +#pragma charmap (0x1F, 0x1F) + +#pragma charmap (0x20, 0x20) +#pragma charmap (0x21, 0x21) +#pragma charmap (0x22, 0x22) +#pragma charmap (0x23, 0x23) +#pragma charmap (0x24, 0x24) +#pragma charmap (0x25, 0x25) +#pragma charmap (0x26, 0x26) +#pragma charmap (0x27, 0x27) +#pragma charmap (0x28, 0x28) +#pragma charmap (0x29, 0x29) +#pragma charmap (0x2A, 0x2A) +#pragma charmap (0x2B, 0x2B) +#pragma charmap (0x2C, 0x2C) +#pragma charmap (0x2D, 0x2D) +#pragma charmap (0x2E, 0x2E) +#pragma charmap (0x2F, 0x2F) + +#pragma charmap (0x30, 0x30) +#pragma charmap (0x31, 0x31) +#pragma charmap (0x32, 0x32) +#pragma charmap (0x33, 0x33) +#pragma charmap (0x34, 0x34) +#pragma charmap (0x35, 0x35) +#pragma charmap (0x36, 0x36) +#pragma charmap (0x37, 0x37) +#pragma charmap (0x38, 0x38) +#pragma charmap (0x39, 0x39) +#pragma charmap (0x3A, 0x3A) +#pragma charmap (0x3B, 0x3B) +#pragma charmap (0x3C, 0x3C) +#pragma charmap (0x3D, 0x3D) +#pragma charmap (0x3E, 0x3E) +#pragma charmap (0x3F, 0x3F) + +#pragma charmap (0x40, 0x40) +#pragma charmap (0x41, 0x41) +#pragma charmap (0x42, 0x42) +#pragma charmap (0x43, 0x43) +#pragma charmap (0x44, 0x44) +#pragma charmap (0x45, 0x45) +#pragma charmap (0x46, 0x46) +#pragma charmap (0x47, 0x47) +#pragma charmap (0x48, 0x48) +#pragma charmap (0x49, 0x49) +#pragma charmap (0x4A, 0x4A) +#pragma charmap (0x4B, 0x4B) +#pragma charmap (0x4C, 0x4C) +#pragma charmap (0x4D, 0x4D) +#pragma charmap (0x4E, 0x4E) +#pragma charmap (0x4F, 0x4F) + +#pragma charmap (0x50, 0x50) +#pragma charmap (0x51, 0x51) +#pragma charmap (0x52, 0x52) +#pragma charmap (0x53, 0x53) +#pragma charmap (0x54, 0x54) +#pragma charmap (0x55, 0x55) +#pragma charmap (0x56, 0x56) +#pragma charmap (0x57, 0x57) +#pragma charmap (0x58, 0x58) +#pragma charmap (0x59, 0x59) +#pragma charmap (0x5A, 0x5A) +#pragma charmap (0x5B, 0x5B) +#pragma charmap (0x5C, 0x5C) +#pragma charmap (0x5D, 0x5D) +#pragma charmap (0x5E, 0x5E) +#pragma charmap (0x5F, 0x5F) + +#pragma charmap (0x60, 0x60) +#pragma charmap (0x61, 0x61) +#pragma charmap (0x62, 0x62) +#pragma charmap (0x63, 0x63) +#pragma charmap (0x64, 0x64) +#pragma charmap (0x65, 0x65) +#pragma charmap (0x66, 0x66) +#pragma charmap (0x67, 0x67) +#pragma charmap (0x68, 0x68) +#pragma charmap (0x69, 0x69) +#pragma charmap (0x6A, 0x6A) +#pragma charmap (0x6B, 0x6B) +#pragma charmap (0x6C, 0x6C) +#pragma charmap (0x6D, 0x6D) +#pragma charmap (0x6E, 0x6E) +#pragma charmap (0x6F, 0x6F) + +#pragma charmap (0x70, 0x70) +#pragma charmap (0x71, 0x71) +#pragma charmap (0x72, 0x72) +#pragma charmap (0x73, 0x73) +#pragma charmap (0x74, 0x74) +#pragma charmap (0x75, 0x75) +#pragma charmap (0x76, 0x76) +#pragma charmap (0x77, 0x77) +#pragma charmap (0x78, 0x78) +#pragma charmap (0x79, 0x79) +#pragma charmap (0x7A, 0x7A) +#pragma charmap (0x7B, 0x7B) +#pragma charmap (0x7C, 0x7C) +#pragma charmap (0x7D, 0x7D) +#pragma charmap (0x7E, 0x7E) +#pragma charmap (0x7F, 0x7F) + +#pragma charmap (0x80, 0x80) +#pragma charmap (0x81, 0x81) +#pragma charmap (0x82, 0x82) +#pragma charmap (0x83, 0x83) +#pragma charmap (0x84, 0x84) +#pragma charmap (0x85, 0x85) +#pragma charmap (0x86, 0x86) +#pragma charmap (0x87, 0x87) +#pragma charmap (0x88, 0x88) +#pragma charmap (0x89, 0x89) +#pragma charmap (0x8A, 0x8A) +#pragma charmap (0x8B, 0x8B) +#pragma charmap (0x8C, 0x8C) +#pragma charmap (0x8D, 0x8D) +#pragma charmap (0x8E, 0x8E) +#pragma charmap (0x8F, 0x8F) + +#pragma charmap (0x90, 0x90) +#pragma charmap (0x91, 0x91) +#pragma charmap (0x92, 0x92) +#pragma charmap (0x93, 0x93) +#pragma charmap (0x94, 0x94) +#pragma charmap (0x95, 0x95) +#pragma charmap (0x96, 0x96) +#pragma charmap (0x97, 0x97) +#pragma charmap (0x98, 0x98) +#pragma charmap (0x99, 0x99) +#pragma charmap (0x9A, 0x9A) +#pragma charmap (0x9B, 0x9B) +#pragma charmap (0x9C, 0x9C) +#pragma charmap (0x9D, 0x9D) +#pragma charmap (0x9E, 0x9E) +#pragma charmap (0x9F, 0x9F) + +#pragma charmap (0xA0, 0xA0) +#pragma charmap (0xA1, 0xA1) +#pragma charmap (0xA2, 0xA2) +#pragma charmap (0xA3, 0xA3) +#pragma charmap (0xA4, 0xA4) +#pragma charmap (0xA5, 0xA5) +#pragma charmap (0xA6, 0xA6) +#pragma charmap (0xA7, 0xA7) +#pragma charmap (0xA8, 0xA8) +#pragma charmap (0xA9, 0xA9) +#pragma charmap (0xAA, 0xAA) +#pragma charmap (0xAB, 0xAB) +#pragma charmap (0xAC, 0xAC) +#pragma charmap (0xAD, 0xAD) +#pragma charmap (0xAE, 0xAE) +#pragma charmap (0xAF, 0xAF) + +#pragma charmap (0xB0, 0xB0) +#pragma charmap (0xB1, 0xB1) +#pragma charmap (0xB2, 0xB2) +#pragma charmap (0xB3, 0xB3) +#pragma charmap (0xB4, 0xB4) +#pragma charmap (0xB5, 0xB5) +#pragma charmap (0xB6, 0xB6) +#pragma charmap (0xB7, 0xB7) +#pragma charmap (0xB8, 0xB8) +#pragma charmap (0xB9, 0xB9) +#pragma charmap (0xBA, 0xBA) +#pragma charmap (0xBB, 0xBB) +#pragma charmap (0xBC, 0xBC) +#pragma charmap (0xBD, 0xBD) +#pragma charmap (0xBE, 0xBE) +#pragma charmap (0xBF, 0xBF) + +#pragma charmap (0xC0, 0xC0) +#pragma charmap (0xC1, 0xC1) +#pragma charmap (0xC2, 0xC2) +#pragma charmap (0xC3, 0xC3) +#pragma charmap (0xC4, 0xC4) +#pragma charmap (0xC5, 0xC5) +#pragma charmap (0xC6, 0xC6) +#pragma charmap (0xC7, 0xC7) +#pragma charmap (0xC8, 0xC8) +#pragma charmap (0xC9, 0xC9) +#pragma charmap (0xCA, 0xCA) +#pragma charmap (0xCB, 0xCB) +#pragma charmap (0xCC, 0xCC) +#pragma charmap (0xCD, 0xCD) +#pragma charmap (0xCE, 0xCE) +#pragma charmap (0xCF, 0xCF) + +#pragma charmap (0xD0, 0xD0) +#pragma charmap (0xD1, 0xD1) +#pragma charmap (0xD2, 0xD2) +#pragma charmap (0xD3, 0xD3) +#pragma charmap (0xD4, 0xD4) +#pragma charmap (0xD5, 0xD5) +#pragma charmap (0xD6, 0xD6) +#pragma charmap (0xD7, 0xD7) +#pragma charmap (0xD8, 0xD8) +#pragma charmap (0xD9, 0xD9) +#pragma charmap (0xDA, 0xDA) +#pragma charmap (0xDB, 0xDB) +#pragma charmap (0xDC, 0xDC) +#pragma charmap (0xDD, 0xDD) +#pragma charmap (0xDE, 0xDE) +#pragma charmap (0xDF, 0xDF) + +#pragma charmap (0xE0, 0xE0) +#pragma charmap (0xE1, 0xE1) +#pragma charmap (0xE2, 0xE2) +#pragma charmap (0xE3, 0xE3) +#pragma charmap (0xE4, 0xE4) +#pragma charmap (0xE5, 0xE5) +#pragma charmap (0xE6, 0xE6) +#pragma charmap (0xE7, 0xE7) +#pragma charmap (0xE8, 0xE8) +#pragma charmap (0xE9, 0xE9) +#pragma charmap (0xEA, 0xEA) +#pragma charmap (0xEB, 0xEB) +#pragma charmap (0xEC, 0xEC) +#pragma charmap (0xED, 0xED) +#pragma charmap (0xEE, 0xEE) +#pragma charmap (0xEF, 0xEF) + +#pragma charmap (0xF0, 0xF0) +#pragma charmap (0xF1, 0xF1) +#pragma charmap (0xF2, 0xF2) +#pragma charmap (0xF3, 0xF3) +#pragma charmap (0xF4, 0xF4) +#pragma charmap (0xF5, 0xF5) +#pragma charmap (0xF6, 0xF6) +#pragma charmap (0xF7, 0xF7) +#pragma charmap (0xF8, 0xF8) +#pragma charmap (0xF9, 0xF9) +#pragma charmap (0xFA, 0xFA) +#pragma charmap (0xFB, 0xFB) +#pragma charmap (0xFC, 0xFC) +#pragma charmap (0xFD, 0xFD) +#pragma charmap (0xFE, 0xFE) +#pragma charmap (0xFF, 0xFF) + diff --git a/include/atari_screen_charmap.h b/include/atari_screen_charmap.h new file mode 100644 index 000000000..4a76d479a --- /dev/null +++ b/include/atari_screen_charmap.h @@ -0,0 +1,304 @@ +/*****************************************************************************/ +/* */ +/* atari_screen_charmap.h */ +/* */ +/* Atari system internal string mapping (ISO-8859-1 -> Internal/Screen-Code) */ +/* */ +/* */ +/* */ +/* (C) 2016 Christian Krueger */ +/* */ +/* */ +/* 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. */ +/* */ +/*****************************************************************************/ + +/* No include guard here! Multiple use in one file may be intentional. */ + +#pragma charmap (0x00, 0x40) +#pragma charmap (0x01, 0x41) +#pragma charmap (0x02, 0x42) +#pragma charmap (0x03, 0x43) +#pragma charmap (0x04, 0x44) +#pragma charmap (0x05, 0x45) +#pragma charmap (0x06, 0x46) +#pragma charmap (0x07, 0xFD) +#pragma charmap (0x08, 0x48) +#pragma charmap (0x09, 0x7F) +#pragma charmap (0x0A, 0xDB) +#pragma charmap (0x0B, 0x4B) +#pragma charmap (0x0C, 0x7D) +#pragma charmap (0x0D, 0x4D) +#pragma charmap (0x0E, 0x4E) +#pragma charmap (0x0F, 0x4F) + +#pragma charmap (0x10, 0x50) +#pragma charmap (0x11, 0x51) +#pragma charmap (0x12, 0x52) +#pragma charmap (0x13, 0x53) +#pragma charmap (0x14, 0x54) +#pragma charmap (0x15, 0x55) +#pragma charmap (0x16, 0x56) +#pragma charmap (0x17, 0x57) +#pragma charmap (0x18, 0x58) +#pragma charmap (0x19, 0x59) +#pragma charmap (0x1A, 0x5A) +#pragma charmap (0x1B, 0x5B) +#pragma charmap (0x1C, 0x5C) +#pragma charmap (0x1D, 0x5D) +#pragma charmap (0x1E, 0x5E) +#pragma charmap (0x1F, 0x5F) + +#pragma charmap (0x20, 0x00) +#pragma charmap (0x21, 0x01) +#pragma charmap (0x22, 0x02) +#pragma charmap (0x23, 0x03) +#pragma charmap (0x24, 0x04) +#pragma charmap (0x25, 0x05) +#pragma charmap (0x26, 0x06) +#pragma charmap (0x27, 0x07) +#pragma charmap (0x28, 0x08) +#pragma charmap (0x29, 0x09) +#pragma charmap (0x2A, 0x0A) +#pragma charmap (0x2B, 0x0B) +#pragma charmap (0x2C, 0x0C) +#pragma charmap (0x2D, 0x0D) +#pragma charmap (0x2E, 0x0E) +#pragma charmap (0x2F, 0x0F) + +#pragma charmap (0x30, 0x10) +#pragma charmap (0x31, 0x11) +#pragma charmap (0x32, 0x12) +#pragma charmap (0x33, 0x13) +#pragma charmap (0x34, 0x14) +#pragma charmap (0x35, 0x15) +#pragma charmap (0x36, 0x16) +#pragma charmap (0x37, 0x17) +#pragma charmap (0x38, 0x18) +#pragma charmap (0x39, 0x19) +#pragma charmap (0x3A, 0x1A) +#pragma charmap (0x3B, 0x1B) +#pragma charmap (0x3C, 0x1C) +#pragma charmap (0x3D, 0x1D) +#pragma charmap (0x3E, 0x1E) +#pragma charmap (0x3F, 0x1F) + +#pragma charmap (0x40, 0x20) +#pragma charmap (0x41, 0x21) +#pragma charmap (0x42, 0x22) +#pragma charmap (0x43, 0x23) +#pragma charmap (0x44, 0x24) +#pragma charmap (0x45, 0x25) +#pragma charmap (0x46, 0x26) +#pragma charmap (0x47, 0x27) +#pragma charmap (0x48, 0x28) +#pragma charmap (0x49, 0x29) +#pragma charmap (0x4A, 0x2A) +#pragma charmap (0x4B, 0x2B) +#pragma charmap (0x4C, 0x2C) +#pragma charmap (0x4D, 0x2D) +#pragma charmap (0x4E, 0x2E) +#pragma charmap (0x4F, 0x2F) + +#pragma charmap (0x50, 0x30) +#pragma charmap (0x51, 0x31) +#pragma charmap (0x52, 0x32) +#pragma charmap (0x53, 0x33) +#pragma charmap (0x54, 0x34) +#pragma charmap (0x55, 0x35) +#pragma charmap (0x56, 0x36) +#pragma charmap (0x57, 0x37) +#pragma charmap (0x58, 0x38) +#pragma charmap (0x59, 0x39) +#pragma charmap (0x5A, 0x3A) +#pragma charmap (0x5B, 0x3B) +#pragma charmap (0x5C, 0x3C) +#pragma charmap (0x5D, 0x3D) +#pragma charmap (0x5E, 0x3E) +#pragma charmap (0x5F, 0x3F) + +#pragma charmap (0x60, 0x60) +#pragma charmap (0x61, 0x61) +#pragma charmap (0x62, 0x62) +#pragma charmap (0x63, 0x63) +#pragma charmap (0x64, 0x64) +#pragma charmap (0x65, 0x65) +#pragma charmap (0x66, 0x66) +#pragma charmap (0x67, 0x67) +#pragma charmap (0x68, 0x68) +#pragma charmap (0x69, 0x69) +#pragma charmap (0x6A, 0x6A) +#pragma charmap (0x6B, 0x6B) +#pragma charmap (0x6C, 0x6C) +#pragma charmap (0x6D, 0x6D) +#pragma charmap (0x6E, 0x6E) +#pragma charmap (0x6F, 0x6F) + +#pragma charmap (0x70, 0x70) +#pragma charmap (0x71, 0x71) +#pragma charmap (0x72, 0x72) +#pragma charmap (0x73, 0x73) +#pragma charmap (0x74, 0x74) +#pragma charmap (0x75, 0x75) +#pragma charmap (0x76, 0x76) +#pragma charmap (0x77, 0x77) +#pragma charmap (0x78, 0x78) +#pragma charmap (0x79, 0x79) +#pragma charmap (0x7A, 0x7A) +#pragma charmap (0x7B, 0x7B) +#pragma charmap (0x7C, 0x7C) +#pragma charmap (0x7D, 0x7D) +#pragma charmap (0x7E, 0x7E) +#pragma charmap (0x7F, 0x7F) + +#pragma charmap (0x80, 0xC0) +#pragma charmap (0x81, 0xC1) +#pragma charmap (0x82, 0xC2) +#pragma charmap (0x83, 0xC3) +#pragma charmap (0x84, 0xC4) +#pragma charmap (0x85, 0xC5) +#pragma charmap (0x86, 0xC6) +#pragma charmap (0x87, 0xC7) +#pragma charmap (0x88, 0xC8) +#pragma charmap (0x89, 0xC9) +#pragma charmap (0x8A, 0xCA) +#pragma charmap (0x8B, 0xCB) +#pragma charmap (0x8C, 0xCC) +#pragma charmap (0x8D, 0xCD) +#pragma charmap (0x8E, 0xCE) +#pragma charmap (0x8F, 0xCF) + +#pragma charmap (0x90, 0xD0) +#pragma charmap (0x91, 0xD1) +#pragma charmap (0x92, 0xD2) +#pragma charmap (0x93, 0xD3) +#pragma charmap (0x94, 0xD4) +#pragma charmap (0x95, 0xD5) +#pragma charmap (0x96, 0xD6) +#pragma charmap (0x97, 0xD7) +#pragma charmap (0x98, 0xD8) +#pragma charmap (0x99, 0xD9) +#pragma charmap (0x9A, 0xDA) +#pragma charmap (0x9B, 0xDB) +#pragma charmap (0x9C, 0xDC) +#pragma charmap (0x9D, 0xDD) +#pragma charmap (0x9E, 0xDE) +#pragma charmap (0x9F, 0xDF) + +#pragma charmap (0xA0, 0x80) +#pragma charmap (0xA1, 0x81) +#pragma charmap (0xA2, 0x82) +#pragma charmap (0xA3, 0x83) +#pragma charmap (0xA4, 0x84) +#pragma charmap (0xA5, 0x85) +#pragma charmap (0xA6, 0x86) +#pragma charmap (0xA7, 0x87) +#pragma charmap (0xA8, 0x88) +#pragma charmap (0xA9, 0x89) +#pragma charmap (0xAA, 0x8A) +#pragma charmap (0xAB, 0x8B) +#pragma charmap (0xAC, 0x8C) +#pragma charmap (0xAD, 0x8D) +#pragma charmap (0xAE, 0x8E) +#pragma charmap (0xAF, 0x8F) + +#pragma charmap (0xB0, 0x90) +#pragma charmap (0xB1, 0x91) +#pragma charmap (0xB2, 0x92) +#pragma charmap (0xB3, 0x93) +#pragma charmap (0xB4, 0x94) +#pragma charmap (0xB5, 0x95) +#pragma charmap (0xB6, 0x96) +#pragma charmap (0xB7, 0x97) +#pragma charmap (0xB8, 0x98) +#pragma charmap (0xB9, 0x99) +#pragma charmap (0xBA, 0x9A) +#pragma charmap (0xBB, 0x9B) +#pragma charmap (0xBC, 0x9C) +#pragma charmap (0xBD, 0x9D) +#pragma charmap (0xBE, 0x9E) +#pragma charmap (0xBF, 0x9F) + +#pragma charmap (0xC0, 0xA0) +#pragma charmap (0xC1, 0xA1) +#pragma charmap (0xC2, 0xA2) +#pragma charmap (0xC3, 0xA3) +#pragma charmap (0xC4, 0xA4) +#pragma charmap (0xC5, 0xA5) +#pragma charmap (0xC6, 0xA6) +#pragma charmap (0xC7, 0xA7) +#pragma charmap (0xC8, 0xA8) +#pragma charmap (0xC9, 0xA9) +#pragma charmap (0xCA, 0xAA) +#pragma charmap (0xCB, 0xAB) +#pragma charmap (0xCC, 0xAC) +#pragma charmap (0xCD, 0xAD) +#pragma charmap (0xCE, 0xAE) +#pragma charmap (0xCF, 0xAF) + +#pragma charmap (0xD0, 0xB0) +#pragma charmap (0xD1, 0xB1) +#pragma charmap (0xD2, 0xB2) +#pragma charmap (0xD3, 0xB3) +#pragma charmap (0xD4, 0xB4) +#pragma charmap (0xD5, 0xB5) +#pragma charmap (0xD6, 0xB6) +#pragma charmap (0xD7, 0xB7) +#pragma charmap (0xD8, 0xB8) +#pragma charmap (0xD9, 0xB9) +#pragma charmap (0xDA, 0xBA) +#pragma charmap (0xDB, 0xBB) +#pragma charmap (0xDC, 0xBC) +#pragma charmap (0xDD, 0xBD) +#pragma charmap (0xDE, 0xBE) +#pragma charmap (0xDF, 0xBF) + +#pragma charmap (0xE0, 0xE0) +#pragma charmap (0xE1, 0xE1) +#pragma charmap (0xE2, 0xE2) +#pragma charmap (0xE3, 0xE3) +#pragma charmap (0xE4, 0xE4) +#pragma charmap (0xE5, 0xE5) +#pragma charmap (0xE6, 0xE6) +#pragma charmap (0xE7, 0xE7) +#pragma charmap (0xE8, 0xE8) +#pragma charmap (0xE9, 0xE9) +#pragma charmap (0xEA, 0xEA) +#pragma charmap (0xEB, 0xEB) +#pragma charmap (0xEC, 0xEC) +#pragma charmap (0xED, 0xED) +#pragma charmap (0xEE, 0xEE) +#pragma charmap (0xEF, 0xEF) + +#pragma charmap (0xF0, 0xF0) +#pragma charmap (0xF1, 0xF1) +#pragma charmap (0xF2, 0xF2) +#pragma charmap (0xF3, 0xF3) +#pragma charmap (0xF4, 0xF4) +#pragma charmap (0xF5, 0xF5) +#pragma charmap (0xF6, 0xF6) +#pragma charmap (0xF7, 0xF7) +#pragma charmap (0xF8, 0xF8) +#pragma charmap (0xF9, 0xF9) +#pragma charmap (0xFA, 0xFA) +#pragma charmap (0xFB, 0xFB) +#pragma charmap (0xFC, 0xFC) +#pragma charmap (0xFD, 0xFD) +#pragma charmap (0xFE, 0xFE) +#pragma charmap (0xFF, 0xFF) + diff --git a/testcode/lib/atari/charmapping.c b/testcode/lib/atari/charmapping.c new file mode 100644 index 000000000..5fce663ee --- /dev/null +++ b/testcode/lib/atari/charmapping.c @@ -0,0 +1,63 @@ +/* +** testprogram for includes "atari_screen_charmap.h" and "atari_atascii_charmap.h" +** +** 19-Aug-2016, Christian Krueger +*/ + +#include <conio.h> +#include <atari.h> +#include <peekpoke.h> +#include <string.h> + + +char pcDefaultMappingString[] = "Hello Atari!"; + +#include <atari_screen_charmap.h> +char pcScreenMappingString[] = "Hello Atari!"; + +#include <atari_atascii_charmap.h> +char pcAtasciiMappingString[] = "Hello Atari!"; + +/* THIS WON'T work due to string merging/collection problems! +char* pcDefaultMappingString = "Hello Atari!"; + +#include <atari_screen_charmap.h> +char* pcScreenMappingString = "Hello Atari!"; + +#include <atari_atascii_charmap.h> +char* pcAtasciiMappingString = "Hello Atari!"; +*/ + +int +main(void) +{ + static unsigned char expectedAtasciiValues[] = { 40,101,108,108,111,0,33,116,97,114,105,1}; + + int returnValue = 0; + unsigned char* screen = (unsigned char*) PEEKW(88); + + // check default (=atascii) + clrscr(); + cputs(pcDefaultMappingString); + returnValue |= memcmp(screen, expectedAtasciiValues, sizeof(expectedAtasciiValues)); + + clrscr(); + memcpy(screen, pcScreenMappingString, sizeof(expectedAtasciiValues)); + returnValue |= memcmp(screen, expectedAtasciiValues, sizeof(expectedAtasciiValues)); + + clrscr(); + cputs(pcAtasciiMappingString); + returnValue |= memcmp(screen, expectedAtasciiValues, sizeof(expectedAtasciiValues)); + + clrscr(); + if (returnValue) + cputs("Test FAILED!"); + else + cputs("Test passed."); + + cputs("\n\rHit any key to exit..."); + cgetc(); + + return returnValue; +} + From 791981237851b289533696a0583b340a0613fb7f Mon Sep 17 00:00:00 2001 From: Chris Cacciatore <chris.cacciatore@gmail.com> Date: Fri, 19 Aug 2016 20:21:10 -0700 Subject: [PATCH 0137/2161] Updated switch statement comments. * Now comments represent the fact that there may not be curly braces. --- src/cc65/swstmt.c | 4 ++-- test/val/switch2.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc65/swstmt.c b/src/cc65/swstmt.c index f71c3e40a..e995bd0b7 100644 --- a/src/cc65/swstmt.c +++ b/src/cc65/swstmt.c @@ -144,8 +144,8 @@ void SwitchStatement (void) /* Create a loop so we may use break. */ AddLoop (ExitLabel, 0); - /* Parse the following statement, which will actually be a compound - ** statement because of the curly brace at the current input position + /* Parse the following statement, which may actually be a compound + ** statement if there is a curly brace at the current input position */ HaveBreak = Statement (&RCurlyBrace); diff --git a/test/val/switch2.c b/test/val/switch2.c index 00206b0f6..65c24eeda 100644 --- a/test/val/switch2.c +++ b/test/val/switch2.c @@ -22,7 +22,7 @@ void switch_no_body(void) void switch_empty_body(void) { - switch(0) {}; + switch(0) {} } /* only worried about this file compiling successfully */ From e9295b2a98734dc7a422f4a5b161a024d2f4ec22 Mon Sep 17 00:00:00 2001 From: Chris Cacciatore <chris.cacciatore@gmail.com> Date: Sat, 20 Aug 2016 09:42:29 -0700 Subject: [PATCH 0138/2161] Updated comment regarding curly braces. --- src/cc65/swstmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/swstmt.c b/src/cc65/swstmt.c index e995bd0b7..512f4257d 100644 --- a/src/cc65/swstmt.c +++ b/src/cc65/swstmt.c @@ -194,7 +194,7 @@ void SwitchStatement (void) /* Free the case value tree */ FreeCaseNodeColl (SwitchData.Nodes); - /* If the case statement was (correctly) terminated by a closing curly + /* If the case statement was terminated by a closing curly ** brace, skip it now. */ if (RCurlyBrace) { From 2f6fb1de1c81b147cbf25cb1c1b3e1b149eb0622 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 26 Aug 2016 11:06:58 +0200 Subject: [PATCH 0139/2161] Added -Wc to the (pseudo) output dump. --- doc/cl65.sgml | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/cl65.sgml b/doc/cl65.sgml index b9a6cd1e4..eef6a12a3 100644 --- a/doc/cl65.sgml +++ b/doc/cl65.sgml @@ -62,6 +62,7 @@ Short options: -V Print the version number -W name[,...] Supress compiler warnings -Wa options Pass options to the assembler + -Wc options Pass options to the compiler -Wl options Pass options to the linker Long options: From 1dee57bf1fc6c9781ee51c85c0cd614338266d63 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 26 Aug 2016 07:39:39 -0400 Subject: [PATCH 0140/2161] Made cc65 not warn us when we change character code 0x00 back to itself. --- src/cc65/pragma.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 52af1e722..86739ce22 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -452,15 +452,9 @@ static void CharMapPragma (StrBuf* B) if (!GetNumber (B, &Index)) { return; } - if (Index < 1 || Index > 255) { - if (Index != 0) { - Error ("Character index out of range"); - return; - } - /* For groepaz and Christian */ - if (IS_Get (&WarnRemapZero)) { - Warning ("Remapping from 0 is dangerous with string functions"); - } + if (Index < 0 || Index > 255) { + Error ("Character index out of range"); + return; } /* Comma follows */ @@ -472,13 +466,19 @@ static void CharMapPragma (StrBuf* B) if (!GetNumber (B, &C)) { return; } - if (C < 1 || C > 255) { - if (C != 0) { - Error ("Character code out of range"); - return; + if (C < 0 || C > 255) { + Error ("Character code out of range"); + return; + } + + /* Warn about remapping character code 0x00 + ** (except when remapping it back to itself). + */ + if (Index + C != 0 && IS_Get (&WarnRemapZero)) { + if (Index == 0) { + Warning ("Remapping from 0 is dangerous with string functions"); } - /* For groepaz and Christian */ - if (IS_Get (&WarnRemapZero)) { + else if (C == 0) { Warning ("Remapping to 0 can make string functions stop unexpectedly"); } } From e786d1cf4911e3c82fcf2687f5798145f2334b17 Mon Sep 17 00:00:00 2001 From: alexthissen <athissen@killer-apps.nl> Date: Sat, 27 Aug 2016 21:58:13 +0200 Subject: [PATCH 0141/2161] Update exehdr.s Fix for memory bank 1 which should be zero for almost all cartridges for emulators to work correctly. --- libsrc/lynx/exehdr.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/lynx/exehdr.s b/libsrc/lynx/exehdr.s index 4f077fb82..3be926bb3 100644 --- a/libsrc/lynx/exehdr.s +++ b/libsrc/lynx/exehdr.s @@ -12,7 +12,7 @@ .segment "EXEHDR" .byte 'L','Y','N','X' ; magic .word __BLOCKSIZE__ ; bank 0 page size - .word __BLOCKSIZE__ ; bank 1 page size + .word 0 ; bank 1 page size .word 1 ; version number .asciiz "Cart name " ; 32 bytes cart name .asciiz "Manufacturer " ; 16 bytes manufacturer From d65f587f69ff5569223b77ac6f4b2e3500512252 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sat, 27 Aug 2016 22:02:08 +0200 Subject: [PATCH 0142/2161] Internal/screen character mapping: Supressed warnings for re-map and added documentation. --- doc/atari.sgml | 52 ++++++++++++++++++++++++++++++++++ include/atari_screen_charmap.h | 8 +++++- 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/doc/atari.sgml b/doc/atari.sgml index e65a7869e..54f3aab78 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -318,6 +318,58 @@ chip registers. </descrip><p> +<sect1>Character mapping<p> + +The Atari has two representations for characters: +<enum> +<item> ATASCII is character mapping which is similar to ASCII and used +by the CIO system of the OS. This is the default mapping of cc65 when +producing code for the atari target. +<item> The internal/screen mapping represents the real value of the +screen ram when showing a character. +</enum> + +For direct memory access (simplicity and speed) enabling the internal +mapping can be useful. This can be achieved by including the +"<tt/atari_screen_charmap.h/" header. + +A word of caution: Since the <tt/0x00/ character has to be mapped in an +incompatible way to the C-standard, the usage of string functions in +conjunction with internal character mapped strings delivers unexpected +results regarding the string length. The end of strings are detected where +you may not expect them (to early or (much) to late). Internal mapped +strings typically support the "<tt/mem...()/" functions. + +<em>For assembler sources the macro "<tt/scrcode/" from the "<tt/atari.mac/" +package delivers the same feature.</em> + +You can switch back to the ATASCII mapping by including +"<tt/atari_atascii_charmap.h/". + +A final note: Since cc65 has currently some difficulties with string merging +under different mappings, defining remapped strings works only flawlessly +with static array initialization: + +<verb> +#include <atari\_screen\_charmap.h> +char pcScreenMappingString[] = "Hello Atari!"; + +#include <atari_atascii_charmap.h> +char pcAtasciiMappingString[] = "Hello Atari!"; +</verb> + +delivers correct results, while + +<verb> +#include <atari_screen_charmap.h> +char* pcScreenMappingString = "Hello Atari!"; + +#include <atari_atascii_charmap.h> +char* pcAtasciiMappingString = "Hello Atari!"; +</verb> + +does not. + <sect>Loadable drivers<p> diff --git a/include/atari_screen_charmap.h b/include/atari_screen_charmap.h index 4a76d479a..78051584f 100644 --- a/include/atari_screen_charmap.h +++ b/include/atari_screen_charmap.h @@ -30,7 +30,10 @@ /* No include guard here! Multiple use in one file may be intentional. */ +#pragma warn (remap-zero, push, off) #pragma charmap (0x00, 0x40) +#pragma warn (remap-zero, pop) + #pragma charmap (0x01, 0x41) #pragma charmap (0x02, 0x42) #pragma charmap (0x03, 0x43) @@ -64,7 +67,10 @@ #pragma charmap (0x1E, 0x5E) #pragma charmap (0x1F, 0x5F) -#pragma charmap (0x20, 0x00) +#pragma warn (remap-zero, push, off) +#pragma charmap (0x20, 0x00) +#pragma warn (remap-zero, pop) + #pragma charmap (0x21, 0x01) #pragma charmap (0x22, 0x02) #pragma charmap (0x23, 0x03) From 0538184699358b9f2f3427277cfe1c30d7c64fef Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Mon, 29 Aug 2016 10:45:18 +0200 Subject: [PATCH 0143/2161] Add 4510 support for C65/C64DX --- doc/ca65.sgml | 39 +++-- src/ca65/ea65.c | 19 ++- src/ca65/instr.c | 234 +++++++++++++++++++++++++-- src/ca65/instr.h | 6 +- src/ca65/main.c | 4 + src/ca65/scanner.c | 104 ++++++------ src/ca65/token.h | 1 + src/common/cpu.c | 2 + src/common/cpu.h | 2 + src/common/target.c | 2 + src/common/target.h | 1 + testcode/assembler/.gitignore | 9 +- testcode/assembler/4510all.ref | Bin 0 -> 564 bytes testcode/assembler/4510all.s | 278 +++++++++++++++++++++++++++++++++ testcode/assembler/Makefile | 11 +- 15 files changed, 630 insertions(+), 82 deletions(-) create mode 100644 testcode/assembler/4510all.ref create mode 100644 testcode/assembler/4510all.s diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 050e75628..f59ce44cb 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, 65SC02, 65C02, 65816, sweet16, HuC6280 + 6502, 6502X, 65SC02, 65C02, 65816, sweet16, HuC6280, 4510 <label id="option-create-dep"> @@ -434,16 +434,16 @@ The assembler accepts In 65816 mode, several aliases are accepted, in addition to the official mnemonics: -<tscreen><verb> -CPA is an alias for CMP -DEA is an alias for DEC A -INA is an alias for INC A -SWA is an alias for XBA -TAD is an alias for TCD -TAS is an alias for TCS -TDA is an alias for TDC -TSA is an alias for TSC -</verb></tscreen> +<itemize> +<item><tt>CPA</tt> is an alias for <tt>CMP</tt> +<item><tt>DEA</tt> is an alias for <tt>DEC A</tt> +<item><tt>INA</tt> is an alias for <tt>INC A</tt> +<item><tt>SWA</tt> is an alias for <tt>XBA</tt> +<item><tt>TAD</tt> is an alias for <tt>TCD</tt> +<item><tt>TAS</tt> is an alias for <tt>TCS</tt> +<item><tt>TDA</tt> is an alias for <tt>TDC</tt> +<item><tt>TSA</tt> is an alias for <tt>TSC</tt> +</itemize> <sect1>6502X mode<label id="6502X-mode"><p> @@ -473,6 +473,23 @@ from the mentioned web page, for more information, see there. </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 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 System Specification of the +Commodore C65 aka C64DX prototypes ca65 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 assember. +</itemize> +For more information about the Commodore C65/C64DX and the 4510 CPU, see +<url url="http://www.zimmers.net/anonftp/pub/cbm/c65/c65manualupdated.txt.gz">. + <sect1>sweet16 mode<label id="sweet16-mode"><p> diff --git a/src/ca65/ea65.c b/src/ca65/ea65.c index 69468c072..e146ab8c9 100644 --- a/src/ca65/ea65.c +++ b/src/ca65/ea65.c @@ -140,16 +140,27 @@ void GetEA (EffAddr* A) } else { - /* (adr) or (adr),y */ + /* (adr), (adr),y or (adr),z */ Consume (IndirectLeave, IndirectExpect); if (CurTok.Tok == TOK_COMMA) { /* (adr),y */ NextTok (); - Consume (TOK_Y, "`Y' expected"); - A->AddrModeSet = AM65_DIR_IND_Y; + switch(CurTok.Tok) { + case TOK_Z: + if (CPU == CPU_4510) { + NextTok (); + A->AddrModeSet = AM65_DIR_IND; + } + break; + default: + Consume (TOK_Y, "`Y' expected"); + A->AddrModeSet = AM65_DIR_IND_Y; + break; + } } else { /* (adr) */ - A->AddrModeSet = AM65_ABS_IND | AM65_ABS_IND_LONG | AM65_DIR_IND; + A->AddrModeSet = (CPU == CPU_4510) ? AM65_ABS_IND + : AM65_ABS_IND | AM65_ABS_IND_LONG | AM65_DIR_IND; } } diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 966a5cd98..a4365402d 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -73,6 +73,9 @@ static void PutPCRel8 (const InsDesc* Ins); static void PutPCRel16 (const InsDesc* Ins); /* Handle branches with an 16 bit distance and PER */ +static void PutPCRel4510 (const InsDesc* Ins); +/* Handle branches with a 16 bit distance for 4510 */ + static void PutBlockMove (const InsDesc* Ins); /* Handle the blockmove instructions (65816) */ @@ -125,6 +128,9 @@ static void PutRTS (const InsDesc* Ins attribute ((unused))); static void PutAll (const InsDesc* Ins); /* Handle all other instructions */ +static void Put4510 (const InsDesc* Ins); +/* Handle instructions of 4510 not matching any EATab */ + static void PutSweet16 (const InsDesc* Ins); /* Handle a generic sweet16 instruction */ @@ -483,6 +489,149 @@ static const struct { } }; +/* Instruction table for the 4510 */ +static const struct { + unsigned Count; + InsDesc Ins[133]; +} InsTab4510 = { + sizeof (InsTab4510.Ins) / sizeof (InsTab4510.Ins[0]), + { + { "ADC", 0x080A66C, 0x60, 0, PutAll }, + { "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 }, + { "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", 0x0000001, 0x00, 0, 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, 7, PutAll }, /* trial'n'error */ + { "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, 7, PutAll }, /* trial'n'error */ + { "INX", 0x0000001, 0xe8, 0, PutAll }, + { "INY", 0x0000001, 0xc8, 0, PutAll }, + { "INZ", 0x0000001, 0x1B, 0, PutAll }, + { "JMP", 0x0010808, 0x4c, 6, PutAll }, + { "JSR", 0x0010808, 0x20, 6, 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 }, + { "MAP", 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 }, + { "PHZ", 0x0000001, 0xdb, 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 }, + } +}; + /* Instruction table for the 65816 */ static const struct { unsigned Count; @@ -786,6 +935,7 @@ static const InsTable* InsTabs[CPU_COUNT] = { (const InsTable*) &InsTabSweet16, (const InsTable*) &InsTabHuC6280, 0, /* Mitsubishi 740 */ + (const InsTable*) &InsTab4510, }; const InsTable* InsTab = (const InsTable*) &InsTab6502; @@ -797,73 +947,73 @@ static unsigned char EATab[12][AM65I_COUNT] = { 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 }, { /* Table 1 */ 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, 0x80, 0x00 }, { /* Table 2 */ 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 }, { /* Table 3 */ 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 }, { /* Table 4 */ 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 }, { /* Table 5 */ 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 }, { /* Table 6 */ 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, 0x90, 0x00 }, { /* Table 7 */ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 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 }, { /* Table 9 */ 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 }, { /* Table 10 (NOPs) */ 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 }, { /* 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, 0x80, 0x00 }, }; @@ -908,6 +1058,7 @@ unsigned char ExtBytes[AM65I_COUNT] = { 2, /* Blockmove (65816) */ 7, /* Block transfer (HuC6280) */ 2, /* Absolute Indirect long */ + 2, /* Immidiate word */ }; /* Table that encodes the additional bytes for each SWEET16 instruction */ @@ -1033,7 +1184,7 @@ static int EvalEA (const InsDesc* Ins, EffAddr* A) ** limit the expression to the maximum possible value. */ if (A->AddrMode == AM65I_IMM_ACCU || A->AddrMode == AM65I_IMM_INDEX || - A->AddrMode == AM65I_IMM_IMPLICIT) { + A->AddrMode == AM65I_IMM_IMPLICIT || A->AddrMode == AM65I_IMM_IMPLICIT_WORD) { if (ForceRange && A->Expr) { A->Expr = MakeBoundedExpr (A->Expr, ExtBytes[A->AddrMode]); } @@ -1136,6 +1287,14 @@ static void PutPCRel16 (const InsDesc* Ins) +static void PutPCRel4510 (const InsDesc* Ins) +/* Handle branches with a 16 bit distance */ +{ + /* 16 bit branch opcode is 8 bit branch opcode or 0x03 */ + EmitPCRel (Ins->BaseCode, GenBranchExpr (2), 2); +} + + static void PutBlockMove (const InsDesc* Ins) /* Handle the blockmove instructions (65816) */ { @@ -1383,6 +1542,55 @@ static void PutAll (const InsDesc* Ins) +static void Put4510 (const InsDesc* Ins) +/* Handle all other instructions */ +{ + /* The 4510 uses all 256 possible opcodes, so the last ones were cramped + * 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 + * approach does not work always. In this function, the wrongly calculated + * opcode is replaced by the correct one "on the fly". Suggestions for a + * better approach are welcome. + * + * These are: + * $20 -> $22 : JSR ($1234) NEED TO CHECK FOR ADDRESSING + * $30 -> $23 : JSR ($1234,X) + * $47 -> $44 : ASR $12 + * $57 -> $54 : ASR $12,X + * $93 -> $82 : STA ($12,SP),Y + * $9c -> $8b : STY $1234,X + * $9e -> $9b : STX $1234,Y + * $af -> $ab : LDZ $1234 + * $bf -> $bb : LDZ $1234,X + * $b3 -> $e2 : LDA ($12,SP),Y + * $d0 -> $c2 : CPZ #$00 + */ + EffAddr A; + + /* Evaluate the addressing mode used */ + if (EvalEA (Ins, &A)) { + switch(A.Opcode) { + case 0x20: if(A.AddrModeBit == AM65_ABS_IND) A.Opcode = 0x22; break; + case 0x30: A.Opcode = 0x23; break; + 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; + default: /*nothing*/ break; + } + + /* No error, output code */ + EmitCode (&A); + } +} + + + /*****************************************************************************/ /* Handler functions for SWEET16 */ /*****************************************************************************/ diff --git a/src/ca65/instr.h b/src/ca65/instr.h index 1f2ce262b..0a1a5e13d 100644 --- a/src/ca65/instr.h +++ b/src/ca65/instr.h @@ -85,6 +85,7 @@ #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 */ #define AM65_SET_ZP (AM65_DIR | AM65_DIR_X | AM65_DIR_Y | AM65_DIR_IND | AM65_DIR_X_IND) @@ -102,13 +103,14 @@ #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) +#define AM65_ALL_IMM (AM65_IMM_ACCU | AM65_IMM_INDEX | AM65_IMM_IMPLICIT | AM65_IMM_IMPLICIT_WORD) /* Bit numbers and count */ #define AM65I_IMM_ACCU 21 #define AM65I_IMM_INDEX 22 #define AM65I_IMM_IMPLICIT 23 -#define AM65I_COUNT 27 +#define AM65I_IMM_IMPLICIT_WORD 27 +#define AM65I_COUNT 28 diff --git a/src/ca65/main.c b/src/ca65/main.c index a67319747..d6c364e4b 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -226,6 +226,10 @@ static void SetSys (const char* Sys) CBMSystem ("__C64__"); break; + case TGT_C65: + CBMSystem ("__C65__"); + break; + case TGT_VIC20: CBMSystem ("__VIC20__"); break; diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 799321066..4fde5ac5e 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -1109,60 +1109,76 @@ Again: /* Check for special names. Bail out if we have identified the type of ** the token. Go on if the token is an identifier. */ - if (SB_GetLen (&CurTok.SVal) == 1) { - switch (toupper (SB_AtUnchecked (&CurTok.SVal, 0))) { + switch (SB_GetLen (&CurTok.SVal)) { + case 1: + switch (toupper (SB_AtUnchecked (&CurTok.SVal, 0))) { - case 'A': - if (C == ':') { - NextChar (); - CurTok.Tok = TOK_OVERRIDE_ABS; - } else { - CurTok.Tok = TOK_A; - } - return; - - case 'F': - if (C == ':') { - NextChar (); - CurTok.Tok = TOK_OVERRIDE_FAR; + case 'A': + if (C == ':') { + NextChar (); + CurTok.Tok = TOK_OVERRIDE_ABS; + } else { + CurTok.Tok = TOK_A; + } return; - } - break; - case 'S': - if (CPU == CPU_65816) { - CurTok.Tok = TOK_S; + case 'F': + if (C == ':') { + NextChar (); + CurTok.Tok = TOK_OVERRIDE_FAR; + return; + } + break; + + case 'S': + if ((CPU == CPU_4510) || (CPU == CPU_65816)) { + CurTok.Tok = TOK_S; + return; + } + break; + + case 'X': + CurTok.Tok = TOK_X; return; - } - break; - case 'X': - CurTok.Tok = TOK_X; - return; - - case 'Y': - CurTok.Tok = TOK_Y; - return; - - case 'Z': - if (C == ':') { - NextChar (); - CurTok.Tok = TOK_OVERRIDE_ZP; + case 'Y': + CurTok.Tok = TOK_Y; return; - } - break; - default: - break; - } + case 'Z': + if (C == ':') { + NextChar (); + CurTok.Tok = TOK_OVERRIDE_ZP; + return; + } else { + if (CPU == CPU_4510) { + CurTok.Tok = TOK_Z; + return; + } + } + break; - } else if (CPU == CPU_SWEET16 && - (CurTok.IVal = Sweet16Reg (&CurTok.SVal)) >= 0) { + default: + break; + } + break; + case 2: + if ((CPU == CPU_4510) && + (toupper (SB_AtUnchecked (&CurTok.SVal, 0)) == 'S') && + (toupper (SB_AtUnchecked (&CurTok.SVal, 1)) == 'P')) { - /* A sweet16 register number in sweet16 mode */ - CurTok.Tok = TOK_REG; - return; + CurTok.Tok = TOK_S; + return; + } + /* fall through */ + default: + if (CPU == CPU_SWEET16 && + (CurTok.IVal = Sweet16Reg (&CurTok.SVal)) >= 0) { + /* A sweet16 register number in sweet16 mode */ + CurTok.Tok = TOK_REG; + return; + } } /* Check for define style macro */ diff --git a/src/ca65/token.h b/src/ca65/token.h index bfc013a3d..93dfaa092 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -66,6 +66,7 @@ typedef enum token_t { TOK_A, /* A)ccumulator */ TOK_X, /* X register */ TOK_Y, /* Y register */ + TOK_Z, /* Z register */ TOK_S, /* S register */ TOK_REG, /* Sweet16 R.. register (in sweet16 mode) */ diff --git a/src/common/cpu.c b/src/common/cpu.c index 142d55258..b055fae88 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -61,6 +61,7 @@ const char* CPUNames[CPU_COUNT] = { "sweet16", "huc6280", "m740", + "4510", }; /* Tables with CPU instruction sets */ @@ -74,6 +75,7 @@ const unsigned CPUIsets[CPU_COUNT] = { 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, }; diff --git a/src/common/cpu.h b/src/common/cpu.h index 5bdbdef8c..dcf1815db 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -56,6 +56,7 @@ typedef enum { CPU_SWEET16, CPU_HUC6280, /* Used in PC engine */ CPU_M740, /* Mitsubishi 740 series MCUs */ + CPU_4510, /* CPU of C65 */ CPU_COUNT /* Number of different CPUs */ } cpu_t; @@ -70,6 +71,7 @@ enum { CPU_ISET_SWEET16 = 1 << CPU_SWEET16, CPU_ISET_HUC6280 = 1 << CPU_HUC6280, CPU_ISET_M740 = 1 << CPU_M740, + CPU_ISET_4510 = 1 << CPU_4510, }; /* CPU used */ diff --git a/src/common/target.c b/src/common/target.c index c7b9a3d98..99a134c43 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -152,6 +152,7 @@ static const TargetEntry TargetMap[] = { { "c128", TGT_C128 }, { "c16", TGT_C16 }, { "c64", TGT_C64 }, + { "c65", TGT_C65 }, { "cbm510", TGT_CBM510 }, { "cbm610", TGT_CBM610 }, { "gamate", TGT_GAMATE }, @@ -205,6 +206,7 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "sim65c02", CPU_65C02, BINFMT_BINARY, CTNone }, { "pce", CPU_HUC6280, BINFMT_BINARY, CTNone }, { "gamate", CPU_6502, BINFMT_BINARY, CTNone }, + { "c65", CPU_4510, BINFMT_BINARY, CTPET }, }; /* Target system */ diff --git a/src/common/target.h b/src/common/target.h index 6366b725f..4115ae21a 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -80,6 +80,7 @@ typedef enum { TGT_SIM65C02, TGT_PCENGINE, TGT_GAMATE, + TGT_C65, TGT_COUNT /* Number of target systems */ } target_t; diff --git a/testcode/assembler/.gitignore b/testcode/assembler/.gitignore index de179f4f3..0f7f86d78 100644 --- a/testcode/assembler/.gitignore +++ b/testcode/assembler/.gitignore @@ -1,6 +1,3 @@ -chkillegal.bin -chklegal.bin -chkall.bin -legal.o -illegal.o -all.o +*.bin +*.o +*.lst diff --git a/testcode/assembler/4510all.ref b/testcode/assembler/4510all.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/testcode/assembler/4510all.s b/testcode/assembler/4510all.s new file mode 100644 index 000000000..997ddd05d --- /dev/null +++ b/testcode/assembler/4510all.s @@ -0,0 +1,278 @@ + .setcpu "4510" + + 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 diff --git a/testcode/assembler/Makefile b/testcode/assembler/Makefile index a9257ce75..35c34235a 100644 --- a/testcode/assembler/Makefile +++ b/testcode/assembler/Makefile @@ -1,8 +1,13 @@ -all: chklegal.bin chkillegal.bin chkall.bin +all: chklegal.bin chkillegal.bin chkall.bin chk4510.bin @# -.PHONY: chklegal.bin chkillegal.bin chkall.bin +.PHONY: chklegal.bin chkillegal.bin chkall.bin chk4510.bin + +chk4510.bin: 4510all.s + $(MAKE) -C ../../src all + ../../bin/cl65 --target none --cpu 4510 --listing 4510all.lst -o $@ $< + diff -q 4510all.ref $@ || cat 4510all.lst chklegal.bin: legal.s ../../bin/cl65 --target none --cpu 6502X -o chklegal.bin legal.s @@ -23,3 +28,5 @@ clean: rm -f legal.o chklegal.bin rm -f illegal.o chkillegal.bin rm -f all.o chkall.bin + rm -f 4510all.o chk4510.bin 4510all.lst + From 91f8e09bcc172a09da2e90177fbf6f1641c6c0dd Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Mon, 29 Aug 2016 23:29:31 +0200 Subject: [PATCH 0144/2161] 4510 support: fixed some cosmetical stuff and documentation --- doc/ca65.sgml | 12 ++++++++---- src/ca65/ea65.c | 9 ++++----- src/ca65/instr.c | 46 +++++++++++++++++++++++----------------------- src/ca65/scanner.c | 2 +- 4 files changed, 36 insertions(+), 33 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index f59ce44cb..80515fc50 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -476,10 +476,13 @@ from the mentioned web page, for more information, see there. <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 CPU, to allow +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 System Specification of the -Commodore C65 aka C64DX prototypes ca65 uses these changes: +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). @@ -488,7 +491,8 @@ 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 assember. </itemize> For more information about the Commodore C65/C64DX and the 4510 CPU, see -<url url="http://www.zimmers.net/anonftp/pub/cbm/c65/c65manualupdated.txt.gz">. +<url url="http://www.zimmers.net/anonftp/pub/cbm/c65/"> and +<url url="https://en.wikipedia.org/wiki/Commodore_65" name="Wikipedia">. <sect1>sweet16 mode<label id="sweet16-mode"><p> diff --git a/src/ca65/ea65.c b/src/ca65/ea65.c index e146ab8c9..2f7c2bfa9 100644 --- a/src/ca65/ea65.c +++ b/src/ca65/ea65.c @@ -145,12 +145,11 @@ void GetEA (EffAddr* A) if (CurTok.Tok == TOK_COMMA) { /* (adr),y */ NextTok (); - switch(CurTok.Tok) { + switch (CurTok.Tok) { case TOK_Z: - if (CPU == CPU_4510) { - NextTok (); - A->AddrModeSet = AM65_DIR_IND; - } + /* only set by scanner.c if in 4510-mode */ + NextTok (); + A->AddrModeSet = AM65_DIR_IND; break; default: Consume (TOK_Y, "`Y' expected"); diff --git a/src/ca65/instr.c b/src/ca65/instr.c index a4365402d..26722fab3 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -1290,7 +1290,7 @@ static void PutPCRel16 (const InsDesc* Ins) static void PutPCRel4510 (const InsDesc* Ins) /* Handle branches with a 16 bit distance */ { - /* 16 bit branch opcode is 8 bit branch opcode or 0x03 */ + /* 16 bit branch opcode is 8 bit branch opcode or'ed with 0x03 */ EmitPCRel (Ins->BaseCode, GenBranchExpr (2), 2); } @@ -1543,33 +1543,33 @@ static void PutAll (const InsDesc* Ins) static void Put4510 (const InsDesc* Ins) -/* Handle all other instructions */ +/* Handle all other instructions, with modifications for 4510 */ { - /* The 4510 uses all 256 possible opcodes, so the last ones were cramped - * 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 - * approach does not work always. In this function, the wrongly calculated - * opcode is replaced by the correct one "on the fly". Suggestions for a - * better approach are welcome. - * - * These are: - * $20 -> $22 : JSR ($1234) NEED TO CHECK FOR ADDRESSING - * $30 -> $23 : JSR ($1234,X) - * $47 -> $44 : ASR $12 - * $57 -> $54 : ASR $12,X - * $93 -> $82 : STA ($12,SP),Y - * $9c -> $8b : STY $1234,X - * $9e -> $9b : STX $1234,Y - * $af -> $ab : LDZ $1234 - * $bf -> $bb : LDZ $1234,X - * $b3 -> $e2 : LDA ($12,SP),Y - * $d0 -> $c2 : CPZ #$00 - */ + /* 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 + ** approach does not work always. In this function, the wrongly calculated + ** opcode is replaced by the correct one "on the fly". Suggestions for a + ** better approach are welcome. + ** + ** These are: + ** $20 -> $22 : JSR ($1234) NEED TO CHECK FOR ADDRESSING + ** $30 -> $23 : JSR ($1234,X) + ** $47 -> $44 : ASR $12 + ** $57 -> $54 : ASR $12,X + ** $93 -> $82 : STA ($12,SP),Y + ** $9c -> $8b : STY $1234,X + ** $9e -> $9b : STX $1234,Y + ** $af -> $ab : LDZ $1234 + ** $bf -> $bb : LDZ $1234,X + ** $b3 -> $e2 : LDA ($12,SP),Y + ** $d0 -> $c2 : CPZ #$00 + */ EffAddr A; /* Evaluate the addressing mode used */ if (EvalEA (Ins, &A)) { - switch(A.Opcode) { + switch (A.Opcode) { case 0x20: if(A.AddrModeBit == AM65_ABS_IND) A.Opcode = 0x22; break; case 0x30: A.Opcode = 0x23; break; case 0x47: A.Opcode = 0x44; break; diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 4fde5ac5e..f33ed5def 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -1170,7 +1170,7 @@ Again: CurTok.Tok = TOK_S; return; } - /* fall through */ + /* FALL THROUGH */ default: if (CPU == CPU_SWEET16 && (CurTok.IVal = Sweet16Reg (&CurTok.SVal)) >= 0) { From 4384603eebfa04dba9e625775d1f1f3a009e55f5 Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Tue, 30 Aug 2016 22:58:40 +0200 Subject: [PATCH 0145/2161] 4510 support: added some other small improvements: - fixed typo in doc/ca65.sgml - Greg found a way to get rid of one extra opcode handling in total --- doc/ca65.sgml | 2 +- src/ca65/instr.c | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 80515fc50..6ce5ecef6 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -488,7 +488,7 @@ name="(updated version)"> uses these changes: (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 assember. +"<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 diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 26722fab3..e2819e7cc 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -540,7 +540,7 @@ static const struct { { "CPZ", 0x080000C, 0xd0, 1, Put4510 }, { "DEA", 0x0000001, 0x00, 3, PutAll }, /* == DEC */ { "DEC", 0x000006F, 0x00, 3, PutAll }, - { "DEW", 0x0000004, 0xc3, 7, PutAll }, /* trial'n'error */ + { "DEW", 0x0000004, 0xc3, 9, PutAll }, { "DEX", 0x0000001, 0xca, 0, PutAll }, { "DEY", 0x0000001, 0x88, 0, PutAll }, { "DEZ", 0x0000001, 0x3B, 0, PutAll }, @@ -548,12 +548,12 @@ static const struct { { "EOR", 0x080A66C, 0x40, 0, PutAll }, { "INA", 0x0000001, 0x00, 4, PutAll }, /* == INC */ { "INC", 0x000006f, 0x00, 4, PutAll }, - { "INW", 0x0000004, 0xe3, 7, PutAll }, /* trial'n'error */ + { "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, 6, Put4510 }, + { "JSR", 0x0010808, 0x20, 7, Put4510 }, { "LBCC", 0x0040000, 0x93, 0, PutPCRel4510 }, { "LBCS", 0x0040000, 0xb3, 0, PutPCRel4510 }, { "LBEQ", 0x0040000, 0xf3, 0, PutPCRel4510 }, @@ -985,9 +985,9 @@ static unsigned char EATab[12][AM65I_COUNT] = { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00 }, - { /* Table 7 */ + { /* Table 7 (Subroutine opcodes) */ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -1553,8 +1553,6 @@ static void Put4510 (const InsDesc* Ins) ** better approach are welcome. ** ** These are: - ** $20 -> $22 : JSR ($1234) NEED TO CHECK FOR ADDRESSING - ** $30 -> $23 : JSR ($1234,X) ** $47 -> $44 : ASR $12 ** $57 -> $54 : ASR $12,X ** $93 -> $82 : STA ($12,SP),Y @@ -1564,14 +1562,13 @@ static void Put4510 (const InsDesc* Ins) ** $bf -> $bb : LDZ $1234,X ** $b3 -> $e2 : LDA ($12,SP),Y ** $d0 -> $c2 : CPZ #$00 + ** $fc -> $23 : JSR ($1234,X) */ EffAddr A; /* Evaluate the addressing mode used */ if (EvalEA (Ins, &A)) { switch (A.Opcode) { - case 0x20: if(A.AddrModeBit == AM65_ABS_IND) A.Opcode = 0x22; break; - case 0x30: A.Opcode = 0x23; break; case 0x47: A.Opcode = 0x44; break; case 0x57: A.Opcode = 0x54; break; case 0x93: A.Opcode = 0x82; break; @@ -1581,6 +1578,7 @@ static void Put4510 (const InsDesc* Ins) 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: /*nothing*/ break; } From 48f64de72048c0f514df2a616f34c456955333ef Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Wed, 31 Aug 2016 20:18:54 +0200 Subject: [PATCH 0146/2161] 4510 support: yet another round up little updates --- asminc/cpu.mac | 2 ++ src/ca65/instr.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/asminc/cpu.mac b/asminc/cpu.mac index 6b8aa6d7b..6a5482d1e 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -7,6 +7,7 @@ CPU_ISET_65C02 = $0010 CPU_ISET_65816 = $0020 CPU_ISET_SWEET16 = $0040 CPU_ISET_HUC6280 = $0080 +CPU_ISET_4510 = $0100 ; CPU capabilities CPU_NONE = CPU_ISET_NONE @@ -17,3 +18,4 @@ 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 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 diff --git a/src/ca65/instr.c b/src/ca65/instr.c index e2819e7cc..5e7904992 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -1579,7 +1579,7 @@ static void Put4510 (const InsDesc* Ins) case 0xB3: A.Opcode = 0xE2; break; case 0xD0: A.Opcode = 0xC2; break; case 0xFC: A.Opcode = 0x23; break; - default: /*nothing*/ break; + default: /* Keep opcode as it is */ break; } /* No error, output code */ From 579b89ad98869d13a8f65f9a37e61485243a5c38 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 31 Aug 2016 20:41:17 -0400 Subject: [PATCH 0147/2161] Skipped the bit flag for the (not implemented) Mitsubishi 740 in "cpu.mac". --- asminc/cpu.mac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asminc/cpu.mac b/asminc/cpu.mac index 6a5482d1e..93711427c 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -7,7 +7,7 @@ CPU_ISET_65C02 = $0010 CPU_ISET_65816 = $0020 CPU_ISET_SWEET16 = $0040 CPU_ISET_HUC6280 = $0080 -CPU_ISET_4510 = $0100 +CPU_ISET_4510 = $0200 ; CPU capabilities CPU_NONE = CPU_ISET_NONE From 4b2e3be2fc2211ab5e49867fcd3370e80b6a72f8 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 2 Sep 2016 14:24:29 -0400 Subject: [PATCH 0148/2161] Fixed some bugs in da65's HuC6280 section. --- src/da65/handler.c | 40 ++++++++++++++++++++++++++++++++++++---- src/da65/handler.h | 3 ++- src/da65/opchuc6280.c | 38 +++++++++++++++++++------------------- 3 files changed, 57 insertions(+), 24 deletions(-) diff --git a/src/da65/handler.c b/src/da65/handler.c index 0806301fe..c034aed14 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -36,6 +36,7 @@ #include <stdarg.h> /* common */ +#include "xmalloc.h" #include "xsprintf.h" /* da65 */ @@ -406,6 +407,8 @@ void OH_AbsoluteIndirect (const OpcDesc* D) void OH_BitBranch (const OpcDesc* D) { + char* BranchLabel; + /* Get the operands */ unsigned char TestAddr = GetCodeByte (PC+1); signed char BranchOffs = GetCodeByte (PC+2); @@ -421,8 +424,16 @@ void OH_BitBranch (const OpcDesc* D) 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), GetAddrArg (flLabel, BranchAddr)); + OneLine (D, "%s,%s", GetAddrArg (D->Flags, TestAddr), BranchLabel); + + xfree (BranchLabel); } @@ -518,8 +529,10 @@ void OH_DirectIndirectLongY (const OpcDesc* D attribute ((unused))) -void OH_BlockMove (const OpcDesc* D attribute ((unused))) +void OH_BlockMove (const OpcDesc* D) { + char* DstLabel; + /* Get source operand */ unsigned Src = GetCodeWord (PC+1); /* Get destination operand */ @@ -529,11 +542,19 @@ void OH_BlockMove (const OpcDesc* D attribute ((unused))) GenerateLabel (D->Flags, Src); GenerateLabel (D->Flags, Dst); + /* Make a copy of an operand, so that + ** the other operand can't overwrite it. + ** [GetAddrArg() uses a statically-stored buffer.] + */ + DstLabel = xstrdup (GetAddrArg (D->Flags, Dst)); + /* Output the line */ - OneLine (D, "%s%s,%s%s,#$%02X", + OneLine (D, "%s%s,%s%s,$%04X", GetAbsOverride (D->Flags, Src), GetAddrArg (D->Flags, Src), - GetAbsOverride (D->Flags, Dst), GetAddrArg (D->Flags, Dst), + GetAbsOverride (D->Flags, Dst), DstLabel, GetCodeWord (PC+5)); + + xfree (DstLabel); } @@ -662,3 +683,14 @@ void OH_JmpAbsoluteIndirect (const OpcDesc* D) } SeparatorLine (); } + + + +void OH_JmpAbsoluteXIndirect (const OpcDesc* D) +{ + OH_AbsoluteXIndirect (D); + if (NewlineAfterJMP) { + LineFeed (); + } + SeparatorLine (); +} diff --git a/src/da65/handler.h b/src/da65/handler.h index 77da618c1..433ba2594 100644 --- a/src/da65/handler.h +++ b/src/da65/handler.h @@ -94,11 +94,12 @@ void OH_AccumulatorBit (const OpcDesc*); void OH_AccumulatorBitBranch (const OpcDesc*); void OH_JmpDirectIndirect (const OpcDesc* D); void OH_SpecialPage (const OpcDesc*); - + /* Handlers for special instructions */ void OH_Rts (const OpcDesc*); void OH_JmpAbsolute (const OpcDesc*); void OH_JmpAbsoluteIndirect (const OpcDesc* D); +void OH_JmpAbsoluteXIndirect (const OpcDesc* D); diff --git a/src/da65/opchuc6280.c b/src/da65/opchuc6280.c index df6ba587b..6c5b0b1ad 100644 --- a/src/da65/opchuc6280.c +++ b/src/da65/opchuc6280.c @@ -54,7 +54,7 @@ const OpcDesc OpcTable_HuC6280[256] = { { "tsb", 2, flUseLabel, OH_Direct }, /* $04 */ { "ora", 2, flUseLabel, OH_Direct }, /* $05 */ { "asl", 2, flUseLabel, OH_Direct }, /* $06 */ - { "rmb0", 1, flUseLabel, OH_Direct, }, /* $07 */ + { "rmb0", 2, flUseLabel, OH_Direct, }, /* $07 */ { "php", 1, flNone, OH_Implicit }, /* $08 */ { "ora", 2, flNone, OH_Immediate }, /* $09 */ { "asl", 1, flNone, OH_Accumulator }, /* $0a */ @@ -70,7 +70,7 @@ const OpcDesc OpcTable_HuC6280[256] = { { "trb", 2, flUseLabel, OH_Direct }, /* $14 */ { "ora", 2, flUseLabel, OH_DirectX }, /* $15 */ { "asl", 2, flUseLabel, OH_DirectX }, /* $16 */ - { "rmb1", 1, flUseLabel, OH_Direct, }, /* $17 */ + { "rmb1", 2, flUseLabel, OH_Direct, }, /* $17 */ { "clc", 1, flNone, OH_Implicit }, /* $18 */ { "ora", 3, flUseLabel, OH_AbsoluteY }, /* $19 */ { "inc", 1, flNone, OH_Accumulator }, /* $1a */ @@ -86,7 +86,7 @@ const OpcDesc OpcTable_HuC6280[256] = { { "bit", 2, flUseLabel, OH_Direct }, /* $24 */ { "and", 2, flUseLabel, OH_Direct }, /* $25 */ { "rol", 2, flUseLabel, OH_Direct }, /* $26 */ - { "rmb2", 1, flUseLabel, OH_Direct, }, /* $27 */ + { "rmb2", 2, flUseLabel, OH_Direct, }, /* $27 */ { "plp", 1, flNone, OH_Implicit }, /* $28 */ { "and", 2, flNone, OH_Immediate }, /* $29 */ { "rol", 1, flNone, OH_Accumulator }, /* $2a */ @@ -102,7 +102,7 @@ const OpcDesc OpcTable_HuC6280[256] = { { "bit", 2, flUseLabel, OH_DirectX }, /* $34 */ { "and", 2, flUseLabel, OH_DirectX }, /* $35 */ { "rol", 2, flUseLabel, OH_DirectX }, /* $36 */ - { "rmb3", 1, flUseLabel, OH_Direct, }, /* $37 */ + { "rmb3", 2, flUseLabel, OH_Direct, }, /* $37 */ { "sec", 1, flNone, OH_Implicit }, /* $38 */ { "and", 3, flUseLabel, OH_AbsoluteY }, /* $39 */ { "dec", 1, flNone, OH_Accumulator }, /* $3a */ @@ -114,11 +114,11 @@ const OpcDesc OpcTable_HuC6280[256] = { { "rti", 1, flNone, OH_Rts }, /* $40 */ { "eor", 2, flUseLabel, OH_DirectXIndirect }, /* $41 */ { "say", 1, flNone, OH_Implicit, }, /* $42 */ - { "tmai", 2, flNone, OH_Immediate, }, /* $43 */ + { "tma", 2, flNone, OH_Immediate, }, /* $43 */ { "bsr", 2, flLabel, OH_Relative, }, /* $44 */ { "eor", 2, flUseLabel, OH_Direct }, /* $45 */ { "lsr", 2, flUseLabel, OH_Direct }, /* $46 */ - { "rmb4", 1, flUseLabel, OH_Direct, }, /* $47 */ + { "rmb4", 2, flUseLabel, OH_Direct, }, /* $47 */ { "pha", 1, flNone, OH_Implicit }, /* $48 */ { "eor", 2, flNone, OH_Immediate }, /* $49 */ { "lsr", 1, flNone, OH_Accumulator }, /* $4a */ @@ -130,11 +130,11 @@ const OpcDesc OpcTable_HuC6280[256] = { { "bvc", 2, flLabel, OH_Relative }, /* $50 */ { "eor", 2, flUseLabel, OH_DirectIndirectY }, /* $51 */ { "eor", 2, flUseLabel, OH_DirectIndirect }, /* $52 */ - { "tami", 2, flNone, OH_Immediate, }, /* $53 */ + { "tam", 2, flNone, OH_Immediate, }, /* $53 */ { "csl", 1, flNone, OH_Implicit, }, /* $54 */ { "eor", 2, flUseLabel, OH_DirectX }, /* $55 */ { "lsr", 2, flUseLabel, OH_DirectX }, /* $56 */ - { "rmb5", 1, flUseLabel, OH_Direct, }, /* $57 */ + { "rmb5", 2, flUseLabel, OH_Direct, }, /* $57 */ { "cli", 1, flNone, OH_Implicit }, /* $58 */ { "eor", 3, flUseLabel, OH_AbsoluteY }, /* $59 */ { "phy", 1, flNone, OH_Implicit }, /* $5a */ @@ -150,7 +150,7 @@ const OpcDesc OpcTable_HuC6280[256] = { { "stz", 2, flUseLabel, OH_Direct }, /* $64 */ { "adc", 2, flUseLabel, OH_Direct }, /* $65 */ { "ror", 2, flUseLabel, OH_Direct }, /* $66 */ - { "rmb6", 1, flUseLabel, OH_Direct, }, /* $67 */ + { "rmb6", 2, flUseLabel, OH_Direct, }, /* $67 */ { "pla", 1, flNone, OH_Implicit }, /* $68 */ { "adc", 2, flNone, OH_Immediate }, /* $69 */ { "ror", 1, flNone, OH_Accumulator }, /* $6a */ @@ -166,12 +166,12 @@ const OpcDesc OpcTable_HuC6280[256] = { { "stz", 2, flUseLabel, OH_DirectX }, /* $74 */ { "adc", 2, flUseLabel, OH_DirectX }, /* $75 */ { "ror", 2, flUseLabel, OH_DirectX }, /* $76 */ - { "rmb7", 1, flUseLabel, OH_Direct, }, /* $77 */ + { "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 */ + { "jmp", 3, flLabel, OH_JmpAbsoluteXIndirect }, /* $7c */ { "adc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7d */ { "ror", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7e */ { "bbr7", 3, flUseLabel, OH_BitBranch }, /* $7f */ @@ -182,7 +182,7 @@ const OpcDesc OpcTable_HuC6280[256] = { { "sty", 2, flUseLabel, OH_Direct }, /* $84 */ { "sta", 2, flUseLabel, OH_Direct }, /* $85 */ { "stx", 2, flUseLabel, OH_Direct }, /* $86 */ - { "smb0", 1, flUseLabel, OH_Direct, }, /* $87 */ + { "smb0", 2, flUseLabel, OH_Direct, }, /* $87 */ { "dey", 1, flNone, OH_Implicit }, /* $88 */ { "bit", 2, flNone, OH_Immediate }, /* $89 */ { "txa", 1, flNone, OH_Implicit }, /* $8a */ @@ -198,7 +198,7 @@ const OpcDesc OpcTable_HuC6280[256] = { { "sty", 2, flUseLabel, OH_DirectX }, /* $94 */ { "sta", 2, flUseLabel, OH_DirectX }, /* $95 */ { "stx", 2, flUseLabel, OH_DirectY }, /* $96 */ - { "smb1", 1, flUseLabel, OH_Direct, }, /* $97 */ + { "smb1", 2, flUseLabel, OH_Direct, }, /* $97 */ { "tya", 1, flNone, OH_Implicit }, /* $98 */ { "sta", 3, flUseLabel, OH_AbsoluteY }, /* $99 */ { "txs", 1, flNone, OH_Implicit }, /* $9a */ @@ -214,7 +214,7 @@ const OpcDesc OpcTable_HuC6280[256] = { { "ldy", 2, flUseLabel, OH_Direct }, /* $a4 */ { "lda", 2, flUseLabel, OH_Direct }, /* $a5 */ { "ldx", 2, flUseLabel, OH_Direct }, /* $a6 */ - { "smb2", 1, flUseLabel, OH_Direct, }, /* $a7 */ + { "smb2", 2, flUseLabel, OH_Direct, }, /* $a7 */ { "tay", 1, flNone, OH_Implicit }, /* $a8 */ { "lda", 2, flNone, OH_Immediate }, /* $a9 */ { "tax", 1, flNone, OH_Implicit }, /* $aa */ @@ -230,7 +230,7 @@ const OpcDesc OpcTable_HuC6280[256] = { { "ldy", 2, flUseLabel, OH_DirectX }, /* $b4 */ { "lda", 2, flUseLabel, OH_DirectX }, /* $b5 */ { "ldx", 2, flUseLabel, OH_DirectY }, /* $b6 */ - { "smb3", 1, flUseLabel, OH_Direct, }, /* $b7 */ + { "smb3", 2, flUseLabel, OH_Direct, }, /* $b7 */ { "clv", 1, flNone, OH_Implicit }, /* $b8 */ { "lda", 3, flUseLabel, OH_AbsoluteY }, /* $b9 */ { "tsx", 1, flNone, OH_Implicit }, /* $ba */ @@ -246,7 +246,7 @@ const OpcDesc OpcTable_HuC6280[256] = { { "cpy", 2, flUseLabel, OH_Direct }, /* $c4 */ { "cmp", 2, flUseLabel, OH_Direct }, /* $c5 */ { "dec", 2, flUseLabel, OH_Direct }, /* $c6 */ - { "smb4", 1, flUseLabel, OH_Direct, }, /* $c7 */ + { "smb4", 2, flUseLabel, OH_Direct, }, /* $c7 */ { "iny", 1, flNone, OH_Implicit }, /* $c8 */ { "cmp", 2, flNone, OH_Immediate }, /* $c9 */ { "dex", 1, flNone, OH_Implicit }, /* $ca */ @@ -262,7 +262,7 @@ const OpcDesc OpcTable_HuC6280[256] = { { "csh", 1, flNone, OH_Implicit, }, /* $d4 */ { "cmp", 2, flUseLabel, OH_DirectX }, /* $d5 */ { "dec", 2, flUseLabel, OH_DirectX }, /* $d6 */ - { "smb5", 1, flUseLabel, OH_Direct, }, /* $d7 */ + { "smb5", 2, flUseLabel, OH_Direct, }, /* $d7 */ { "cld", 1, flNone, OH_Implicit }, /* $d8 */ { "cmp", 3, flUseLabel, OH_AbsoluteY }, /* $d9 */ { "phx", 1, flNone, OH_Implicit }, /* $da */ @@ -278,7 +278,7 @@ const OpcDesc OpcTable_HuC6280[256] = { { "cpx", 2, flUseLabel, OH_Direct }, /* $e4 */ { "sbc", 2, flUseLabel, OH_Direct }, /* $e5 */ { "inc", 2, flUseLabel, OH_Direct }, /* $e6 */ - { "smb6", 1, flUseLabel, OH_Direct, }, /* $e7 */ + { "smb6", 2, flUseLabel, OH_Direct, }, /* $e7 */ { "inx", 1, flNone, OH_Implicit }, /* $e8 */ { "sbc", 2, flNone, OH_Immediate }, /* $e9 */ { "nop", 1, flNone, OH_Implicit }, /* $ea */ @@ -294,7 +294,7 @@ const OpcDesc OpcTable_HuC6280[256] = { { "set", 1, flNone, OH_Implicit, }, /* $f4 */ { "sbc", 2, flUseLabel, OH_DirectX }, /* $f5 */ { "inc", 2, flUseLabel, OH_DirectX }, /* $f6 */ - { "smb7", 1, flUseLabel, OH_Direct, }, /* $f7 */ + { "smb7", 2, flUseLabel, OH_Direct, }, /* $f7 */ { "sed", 1, flNone, OH_Implicit }, /* $f8 */ { "sbc", 3, flUseLabel, OH_AbsoluteY }, /* $f9 */ { "plx", 1, flNone, OH_Implicit }, /* $fa */ From a982e434f2f5beb905ead70e2049c052984ece10 Mon Sep 17 00:00:00 2001 From: greg-king5 <gregdk@users.sf.net> Date: Fri, 2 Sep 2016 17:55:39 -0400 Subject: [PATCH 0149/2161] Added commented placeholder for future Mitsubishi 740 CPU in "cpu.mac". --- asminc/cpu.mac | 1 + 1 file changed, 1 insertion(+) diff --git a/asminc/cpu.mac b/asminc/cpu.mac index 93711427c..a67407a4a 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -7,6 +7,7 @@ CPU_ISET_65C02 = $0010 CPU_ISET_65816 = $0020 CPU_ISET_SWEET16 = $0040 CPU_ISET_HUC6280 = $0080 +;CPU_ISET_M740 = $0100 CPU_ISET_4510 = $0200 ; CPU capabilities From 89e2bf89cb44bff9f7969a1cb5dd87b4b3579081 Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Sat, 3 Sep 2016 16:45:59 +0200 Subject: [PATCH 0150/2161] migrated opcodes tests for assembler from testcode to test for inclusion on automated testing --- test/Makefile | 2 + {testcode => test}/assembler/.gitignore | 2 +- .../assembler/4510-opcodes.ref | Bin .../assembler/4510-opcodes.s | 2 +- test/assembler/6502-opcodes.ref | Bin 0 -> 425 bytes test/assembler/6502-opcodes.s | 257 +++++++++++++++++ test/assembler/6502x-opcodes.ref | Bin 0 -> 544 bytes test/assembler/6502x-opcodes.s | 258 +++++++++++++++++ test/assembler/65c02-opcodes.ref | Bin 0 -> 501 bytes test/assembler/65c02-opcodes.s | 258 +++++++++++++++++ test/assembler/65sc02-opcodes.ref | Bin 0 -> 453 bytes test/assembler/65sc02-opcodes.s | 258 +++++++++++++++++ test/assembler/Makefile | 30 ++ test/assembler/huc6280-opcodes.ref | Bin 0 -> 547 bytes test/assembler/huc6280-opcodes.s | 258 +++++++++++++++++ test/assembler/m740-opcodes.s | 260 ++++++++++++++++++ testcode/assembler/Makefile | 32 --- testcode/assembler/all.s | 260 ------------------ testcode/assembler/illegal.ref | 1 - testcode/assembler/illegal.s | 135 --------- testcode/assembler/legal.ref | Bin 321 -> 0 bytes testcode/assembler/legal.s | 185 ------------- 22 files changed, 1583 insertions(+), 615 deletions(-) rename {testcode => test}/assembler/.gitignore (100%) rename testcode/assembler/4510all.ref => test/assembler/4510-opcodes.ref (100%) rename testcode/assembler/4510all.s => test/assembler/4510-opcodes.s (99%) create mode 100644 test/assembler/6502-opcodes.ref create mode 100644 test/assembler/6502-opcodes.s create mode 100644 test/assembler/6502x-opcodes.ref create mode 100644 test/assembler/6502x-opcodes.s create mode 100644 test/assembler/65c02-opcodes.ref create mode 100644 test/assembler/65c02-opcodes.s create mode 100644 test/assembler/65sc02-opcodes.ref create mode 100644 test/assembler/65sc02-opcodes.s create mode 100644 test/assembler/Makefile create mode 100644 test/assembler/huc6280-opcodes.ref create mode 100644 test/assembler/huc6280-opcodes.s create mode 100644 test/assembler/m740-opcodes.s delete mode 100644 testcode/assembler/Makefile delete mode 100644 testcode/assembler/all.s delete mode 100644 testcode/assembler/illegal.ref delete mode 100644 testcode/assembler/illegal.s delete mode 100644 testcode/assembler/legal.ref delete mode 100644 testcode/assembler/legal.s diff --git a/test/Makefile b/test/Makefile index ffdf72aa0..2fd252d2a 100644 --- a/test/Makefile +++ b/test/Makefile @@ -40,12 +40,14 @@ $(WORKDIR)/bdiff$(EXE): bdiff.c | $(WORKDIR) dotests: mostlyclean continue continue: $(WORKDIR)/bdiff$(EXE) + @$(MAKE) -C assembler all @$(MAKE) -C val all @$(MAKE) -C ref all @$(MAKE) -C err all @$(MAKE) -C misc all mostlyclean: + @$(MAKE) -C assembler clean @$(MAKE) -C val clean @$(MAKE) -C ref clean @$(MAKE) -C err clean diff --git a/testcode/assembler/.gitignore b/test/assembler/.gitignore similarity index 100% rename from testcode/assembler/.gitignore rename to test/assembler/.gitignore index 0f7f86d78..c0c74a35e 100644 --- a/testcode/assembler/.gitignore +++ b/test/assembler/.gitignore @@ -1,3 +1,3 @@ -*.bin *.o +*.bin *.lst diff --git a/testcode/assembler/4510all.ref b/test/assembler/4510-opcodes.ref similarity index 100% rename from testcode/assembler/4510all.ref rename to test/assembler/4510-opcodes.ref diff --git a/testcode/assembler/4510all.s b/test/assembler/4510-opcodes.s similarity index 99% rename from testcode/assembler/4510all.s rename to test/assembler/4510-opcodes.s index 997ddd05d..3d6805674 100644 --- a/testcode/assembler/4510all.s +++ b/test/assembler/4510-opcodes.s @@ -1,4 +1,4 @@ - .setcpu "4510" +.setcpu "4510" brk ora ($05,x) diff --git a/test/assembler/6502-opcodes.ref b/test/assembler/6502-opcodes.ref new file mode 100644 index 0000000000000000000000000000000000000000..c12fa8fd6a4498eef33b1db5a12634d146ce5888 GIT binary patch literal 425 zcmV~$2UrMT00dCU$mWb}C9^{6?A@Sj;-qZK-r=`58QIx;MyZrh8KLYbQuZkO%if#! za#$dzWv<-FgS=MxkiS5|LSkXDNKsP^C|;r@O2N8x8L@1+@)g92VkH~V7M1O)pem}N zdX1W}cW@MIiM7Q#PNpuLU04tG(V$@?v2l~8&BW$ni<Yh6>gMi&)@bADg|_Y5iyg#{ zVyDig3%YuD>kgrZPfyX;uUBuekJz_ge+(En$R7b1JY*<_4Id$n6i11p$C$AgH$HFz zCSsDAEKZp^ZMrx^oH=VY=FFXk`B;F3L5mhISt<sL%f#g?%u1|Uy#^szi*@Tah#NO; z-Xd<@wjDdL6T5a}5B6eT=zbgs3l|TH5n^PNIfUq#!#IMYI2Icx#veZ+o)k}s38!%e zXA_ff4(D;<;w4<Zk}O^ouZbzC<~nYq-AqRYZr#2k-o1DKf%s5-^cb1Qdh!&{@Ek8* kzC!kE@s0RaeD~gbz{gLYzu+sreg7f;{Pp{f_*eY*ACHHi+W-In literal 0 HcmV?d00001 diff --git a/test/assembler/6502-opcodes.s b/test/assembler/6502-opcodes.s new file mode 100644 index 000000000..5cb94c29f --- /dev/null +++ b/test/assembler/6502-opcodes.s @@ -0,0 +1,257 @@ +.setcpu "6502" + + brk + ora ($12,x) + .byte $02 + .byte $03 + .byte $04 + ora $12 + asl $12 + .byte $07 + php + ora #$12 + asl a + .byte $0B + .byte $0C + ora $3456 + asl $3456 + .byte $0F + bpl *+122 + ora ($12),y + .byte $12 + .byte $13 + .byte $14 + ora $12,x + asl $12,x + .byte $17 + clc + ora $3456,y + .byte $1A + .byte $1B + .byte $1C + ora $3456,x + asl $3456,x + .byte $1F + jsr $3456 + and ($12,x) + .byte $22 + .byte $23 + bit $12 + and $12 + rol $12 + .byte $27 + plp + and #$12 + rol a + .byte $2B + bit $3456 + and $3456 + rol $3456 + .byte $2F + bmi *+122 + and ($12),y + .byte $32 + .byte $33 + .byte $34 + and $12,x + rol $12,x + .byte $37 + sec + and $3456,y + .byte $3A + .byte $3B + .byte $3C + and $3456,x + rol $3456,x + .byte $3F + rti + eor ($12,x) + .byte $42 + .byte $43 + .byte $44 + eor $12 + lsr $12 + .byte $47 + pha + eor #$12 + lsr a + .byte $4B + jmp $3456 + eor $3456 + lsr $3456 + .byte $4F + bvc *+122 + eor ($12),y + .byte $52 + .byte $53 + .byte $54 + eor $12,x + lsr $12,x + .byte $57 + cli + eor $3456,y + .byte $5A + .byte $5B + .byte $5C + eor $3456,x + lsr $3456,x + .byte $5F + rts + adc ($12,x) + .byte $62 + .byte $63 + .byte $64 + adc $12 + ror $12 + .byte $67 + pla + adc #$12 + ror a + .byte $6B + jmp ($3456) + adc $3456 + ror $3456 + .byte $6F + bvs *+122 + adc ($12),y + .byte $72 + .byte $73 + .byte $74 + adc $12,x + ror $12,x + .byte $77 + sei + adc $3456,y + .byte $7A + .byte $7B + .byte $7C + adc $3456,x + ror $3456,x + .byte $7F + .byte $80 + sta ($12,x) + .byte $82 + .byte $83 + sty $12 + sta $12 + stx $12 + .byte $87 + dey + .byte $89 + txa + .byte $8B + sty $3456 + sta $3456 + stx $3456 + .byte $8F + bcc *+122 + sta ($12),y + .byte $92 + .byte $93 + sty $12,x + sta $12,x + stx $12,y + .byte $97 + tya + sta $3456,y + txs + .byte $9B + .byte $9C + sta $3456,x + .byte $9E + .byte $9F + ldy #$12 + lda ($12,x) + ldx #$12 + .byte $A3 + ldy $12 + lda $12 + ldx $12 + .byte $A7 + tay + lda #$12 + tax + .byte $AB + ldy $3456 + lda $3456 + ldx $3456 + .byte $AF + bcs *+122 + lda ($12),y + .byte $B2 + .byte $B3 + ldy $12,x + lda $12,x + ldx $12,y + .byte $B7 + clv + lda $3456,y + tsx + .byte $BB + ldy $3456,x + lda $3456,x + ldx $3456,y + .byte $BF + cpy #$12 + cmp ($12,x) + .byte $C2 + .byte $C3 + cpy $12 + cmp $12 + dec $12 + .byte $C7 + iny + cmp #$12 + dex + .byte $CB + cpy $3456 + cmp $3456 + dec $3456 + .byte $CF + bne *+122 + cmp ($12),y + .byte $D2 + .byte $D3 + .byte $D4 + cmp $12,x + dec $12,x + .byte $D7 + cld + cmp $3456,y + .byte $DA + .byte $DB + .byte $DC + cmp $3456,x + dec $3456,x + .byte $DF + cpx #$12 + sbc ($12,x) + .byte $E2 + .byte $E3 + cpx $12 + sbc $12 + inc $12 + .byte $E7 + inx + sbc #$12 + .byte $EB + cpx $3456 + sbc $3456 + inc $3456 + .byte $EF + beq *+122 + sbc ($12),y + .byte $F2 + .byte $F3 + .byte $F4 + sbc $12,x + inc $12,x + .byte $F7 + sed + sbc $3456,y + .byte $FA + .byte $FB + .byte $FC + sbc $3456,x + inc $3456,x + .byte $FF diff --git a/test/assembler/6502x-opcodes.ref b/test/assembler/6502x-opcodes.ref new file mode 100644 index 0000000000000000000000000000000000000000..f942bec76706f0b917f7c9ac38eecd9088e60707 GIT binary patch literal 544 zcmW;G0~e470EOXfzS+hyZuYW$!%ntcUv`UIwz<`^mu=g&ZJg8d3!V@m2^E?!ge4r| zi4c)Uk%?kOwW3+ktr$T}h(&DT5SMtwPhcfXWF@weSV^s9R&px^DN~V}G^8aR>3<_b z#!OabD~pxY$`)iNM@~d8a+8O=`K<f}tb$e{tFTqXDq4)+i&KJ<l%h0c%2KX86|9O@ zC9ASkC8$cZ>eQenrWUp9SatvS)u?CHw;EUt8_~E4O=(7RTF|l;t=rJnYG<{#I#?Zp zPIT@<SGv)i9t1tDUcIe8R$r^1)!!PxKn5|GAq-_0e=>XoBS$gX8e{!s{cVj6#xZ^Z z6Pd(hrZ9DyHGPIP)0$<?w&qxKna6w<u#iP8W(oiN%hF~1XDzo@SSzhn!D`m5WgY9; zz(zK0w*KE@ZMC*p+pQhePIj@IJ?v#4`#HeDLmWQBQR|p>+&W>M3{G+S3}-pVc`k7A zl6Cotb=A6NUAJynH@U@a?r@iT+~)xgAMyCfQ|p=a+<IZX3|{g24R3kJdp_{-llA$F N_0{@jeYbvCKLPd8w)X%4 literal 0 HcmV?d00001 diff --git a/test/assembler/6502x-opcodes.s b/test/assembler/6502x-opcodes.s new file mode 100644 index 000000000..5f21aeb9f --- /dev/null +++ b/test/assembler/6502x-opcodes.s @@ -0,0 +1,258 @@ +.setcpu "6502X" + + brk + ora ($12,x) + jam + slo ($12,x) + nop $12 + ora $12 + asl $12 + slo $12 + php + ora #$12 + asl a + anc #$12 + nop $3456 + ora $3456 + asl $3456 + slo $3456 + bpl *+122 + ora ($12),y + .byte $12 ; jam + slo ($12),y + nop $12,x + ora $12,x + asl $12,x + slo $12,x + clc + ora $3456,y + .byte $1a ; nop + slo $3456,y + nop $3456,x + ora $3456,x + asl $3456,x + slo $3456,x + jsr $3456 + and ($12,x) + .byte $22 ; jam + rla ($12,x) + bit $12 + and $12 + rol $12 + rla $12 + plp + and #$12 + rol a + .byte $2b ; anc #$12 + bit $3456 + and $3456 + rol $3456 + rla $3456 + bmi *+122 + and ($12),y + .byte $32 ; jam + rla ($12),y + .byte $34,$12 ; nop $12,x + and $12,x + rol $12,x + rla $12,x + sec + and $3456,y + .byte $3a ; nop + rla $3456,y + .byte $3c,$56,$34 ; nop $3456,x + and $3456,x + rol $3456,x + rla $3456,x + rti + eor ($12,x) + .byte $42 ; jam + sre ($12,x) + .byte $44,$12 ; nop $12 + eor $12 + lsr $12 + sre $12 + pha + eor #$12 + lsr a + alr #$12 + jmp $3456 + eor $3456 + lsr $3456 + sre $3456 + bvc *+122 + eor ($12),y + .byte $52 ; jam + sre ($12),y + .byte $54,$12 ; nop $12,x + eor $12,x + lsr $12,x + sre $12,x + cli + eor $3456,y + .byte $5a ; nop + sre $3456,y + nop $3456,x + eor $3456,x + lsr $3456,x + sre $3456,x + rts + adc ($12,x) + .byte $62 ; jam + rra ($12,x) + .byte $64,$12 ; nop $12 + adc $12 + ror $12 + rra $12 + pla + adc #$12 + ror a + arr #$12 + jmp ($3456) + adc $3456 + ror $3456 + rra $3456 + bvs *+122 + adc ($12),y + .byte $72 ; jam + rra ($12),y + .byte $74,$12 ; nop $12,x + adc $12,x + ror $12,x + rra $12,x + sei + adc $3456,y + .byte $7a ; nop + rra $3456,y + .byte $7c,$56,$34 ; nop $3456,x + adc $3456,x + ror $3456,x + rra $3456,x + nop #$12 + sta ($12,x) + .byte $82,$12 ; nop #$12 + sax ($12,x) + sty $12 + sta $12 + stx $12 + sax $12 + dey + .byte $89,$12 ; nop #$12 + txa + .byte $8b,$12 ; xaa #$12 + sty $3456 + sta $3456 + stx $3456 + sax $3456 + bcc *+122 + sta ($12),y + .byte $92 ; jam + .byte $93,$12 ; ahx ($12),y + sty $12,x + sta $12,x + stx $12,y + sax $12,y + tya + sta $3456,y + txs + tas $3456,y + shy $3456,x + sta $3456,x + shx $3456,y + .byte $9f,$56,$34 ; ahx $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 *+122 + lda ($12),y + .byte $b2 ; jam + 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) + .byte $c2,$12 ; nop #$12 + dcp ($12,x) + cpy $12 + cmp $12 + dec $12 + dcp $12 + iny + cmp #$12 + dex + axs #$12 + cpy $3456 + cmp $3456 + dec $3456 + dcp $3456 + bne *+122 + cmp ($12),y + .byte $d2 ; jam + dcp ($12),y + .byte $d4,$12 ; nop $12,x + cmp $12,x + dec $12,x + dcp $12,x + cld + cmp $3456,y + .byte $da ; nop + dcp $3456,y + .byte $dc,$56,$34 ; nop $3456,x + cmp $3456,x + dec $3456,x + dcp $3456,x + cpx #$12 + sbc ($12,x) + .byte $e2,$12 ; nop #$12 + isc ($12,x) + cpx $12 + sbc $12 + inc $12 + isc $12 + inx + sbc #$12 + nop + .byte $eb ; nop + cpx $3456 + sbc $3456 + inc $3456 + isc $3456 + beq *+122 + sbc ($12),y + .byte $f2 ; jam + isc ($12),y + .byte $f4,$12 ; nop $12,x + sbc $12,x + inc $12,x + isc $12,x + sed + sbc $3456,y + .byte $fa ; nop + isc $3456,y + .byte $fc,$56,$34 ; nop $3456,x + sbc $3456,x + inc $3456,x + isc $3456,x diff --git a/test/assembler/65c02-opcodes.ref b/test/assembler/65c02-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/assembler/65c02-opcodes.s b/test/assembler/65c02-opcodes.s new file mode 100644 index 000000000..09c3f04f2 --- /dev/null +++ b/test/assembler/65c02-opcodes.s @@ -0,0 +1,258 @@ +.setcpu "65C02" + + 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 + .byte $CB + 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 + .byte $DB + .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 diff --git a/test/assembler/65sc02-opcodes.ref b/test/assembler/65sc02-opcodes.ref new file mode 100644 index 0000000000000000000000000000000000000000..d22fe668821f69e5f2301bbf394cedf3c7fe3e9b GIT binary patch literal 453 zcmV~$0{~D507cPk-fUwTFMHX3Vc9l*_TrXpZnf-X+qP|6=Y$AJsL){uOE|(uh)AT! zQLLy|G%I?HASMtiHgSkcy!Z*MgozScNvxz+vgB3@Ql?5x8q$(3{cmK*n90g)WwEkm z3$l}goFW&w$&)vqmA^nitB_ULDpIr<zZWl2l2Vi|Q<ie&D_9k+N>=46K~<_zy+%z; zt=e_0x_{KGZ#A$QHfl_hrp;(h3tF~nO`EputoBw1t7E62GhOJ~jqdcIXVA;)-KVeB z&+2at7#Iv<@Q|Sl<4=Z<7|E#7W30cdzpb(3g7HjX;v^<Bg{jk~TQg?PvSwRzthw`; z&jJ=MVlhkj=ij9)`)|3m!dhvqS{<xmE$h~^fsJh1{J*tj>o#k<wZq!Ei{0$myN~@G z;NYRd965T-I&Ph?PM!)*bB43$&U1l_mo8gZu3o!t-LP)n;x>2g-s3(Gc=+fsPo6%r go?9=hm#>1?yy5M;_k7^vr_a`xuiw5~Kdhg>0HfKabpQYW literal 0 HcmV?d00001 diff --git a/test/assembler/65sc02-opcodes.s b/test/assembler/65sc02-opcodes.s new file mode 100644 index 000000000..aa539913a --- /dev/null +++ b/test/assembler/65sc02-opcodes.s @@ -0,0 +1,258 @@ +.setcpu "65SC02" + + brk + ora ($12,x) + .byte $02 + .byte $03 + tsb $12 + ora $12 + asl $12 + .byte $07 + php + ora #$12 + asl a + .byte $0B + tsb $3456 + ora $3456 + asl $3456 + .byte $0F + bpl *+122 + ora ($12),y + ora ($12) + .byte $13 + trb $12 + ora $12,x + asl $12,x + .byte $17 + clc + ora $3456,y + inc a + .byte $1B + trb $3456 + ora $3456,x + asl $3456,x + .byte $1F + jsr $3456 + and ($12,x) + .byte $22 + .byte $23 + bit $12 + and $12 + rol $12 + .byte $27 + plp + and #$12 + rol a + .byte $2B + bit $3456 + and $3456 + rol $3456 + .byte $2F + bmi *+122 + and ($12),y + and ($12) + .byte $33 + bit $12,x + and $12,x + rol $12,x + .byte $37 + sec + and $3456,y + dec a + .byte $3B + bit $3456,x + and $3456,x + rol $3456,x + .byte $3F + rti + eor ($12,x) + .byte $42 + .byte $43 + .byte $44 + eor $12 + lsr $12 + .byte $47 + pha + eor #$12 + lsr a + .byte $4B + jmp $3456 + eor $3456 + lsr $3456 + .byte $4F + bvc *+122 + eor ($12),y + eor ($12) + .byte $53 + .byte $54 + eor $12,x + lsr $12,x + .byte $57 + cli + eor $3456,y + phy + .byte $5B + .byte $5C + eor $3456,x + lsr $3456,x + .byte $5F + rts + adc ($12,x) + .byte $62 + .byte $63 + stz $12 + adc $12 + ror $12 + .byte $67 + pla + adc #$12 + ror a + .byte $6B + jmp ($3456) + adc $3456 + ror $3456 + .byte $6F + bvs *+122 + adc ($12),y + adc ($12) + .byte $73 + stz $12,x + adc $12,x + ror $12,x + .byte $77 + sei + adc $3456,y + ply + .byte $7B + jmp ($3456,x) + adc $3456,x + ror $3456,x + .byte $7F + bra *+122 + sta ($12,x) + .byte $82 + .byte $83 + sty $12 + sta $12 + stx $12 + .byte $87 + dey + bit #$12 + txa + .byte $8B + sty $3456 + sta $3456 + stx $3456 + .byte $8F + bcc *+122 + sta ($12),y + sta ($12) + .byte $93 + sty $12,x + sta $12,x + stx $12,y + .byte $97 + tya + sta $3456,y + txs + .byte $9B + stz $3456 + sta $3456,x + stz $3456,x + .byte $9F + ldy #$12 + lda ($12,x) + ldx #$12 + .byte $A3 + ldy $12 + lda $12 + ldx $12 + .byte $A7 + tay + lda #$12 + tax + .byte $AB + ldy $3456 + lda $3456 + ldx $3456 + .byte $AF + bcs *+122 + lda ($12),y + lda ($12) + .byte $B3 + ldy $12,x + lda $12,x + ldx $12,y + .byte $B7 + clv + lda $3456,y + tsx + .byte $BB + ldy $3456,x + lda $3456,x + ldx $3456,y + .byte $BF + cpy #$12 + cmp ($12,x) + .byte $C2 + .byte $C3 + cpy $12 + cmp $12 + dec $12 + .byte $C7 + iny + cmp #$12 + dex + .byte $CB + cpy $3456 + cmp $3456 + dec $3456 + .byte $CF + bne *+122 + cmp ($12),y + cmp ($12) + .byte $D3 + .byte $D4 + cmp $12,x + dec $12,x + .byte $D7 + cld + cmp $3456,y + phx + .byte $DB + .byte $DC + cmp $3456,x + dec $3456,x + .byte $DF + cpx #$12 + sbc ($12,x) + .byte $E2 + .byte $E3 + cpx $12 + sbc $12 + inc $12 + .byte $E7 + inx + sbc #$12 + nop + .byte $EB + cpx $3456 + sbc $3456 + inc $3456 + .byte $EF + beq *+122 + sbc ($12),y + sbc ($12) + .byte $F3 + .byte $F4 + sbc $12,x + inc $12,x + .byte $F7 + sed + sbc $3456,y + plx + .byte $FB + .byte $FC + sbc $3456,x + inc $3456,x + .byte $FF diff --git a/test/assembler/Makefile b/test/assembler/Makefile new file mode 100644 index 000000000..5e4d580b5 --- /dev/null +++ b/test/assembler/Makefile @@ -0,0 +1,30 @@ + +# makefile for the assembler regression tests + +BINDIR = ../../bin +#WORKDIR := ../../testwrk +WORKDIR := . + +TARGETS = 6502 6502x 65sc02 65c02 +#TARGETS += 65816 +TARGETS += 4510 +TARGETS += huc6280 +#TARGETS += m740 + +all: $(addprefix $(WORKDIR)/, $(addsuffix -opcodes.bin, $(TARGETS))) + @# + +.PHONY: $(addprefix $(WORKDIR)/, $(addsuffix -opcodes.bin, $(TARGETS))) + +clean: + rm -f *.o *.bin *.lst + +define build +$$(WORKDIR)/$(1)-opcodes.bin: $(1)-opcodes.s + @$$(BINDIR)/cl65 --cpu $(1) -t none -l $$(WORKDIR)/$(1)-opcodes.lst --obj-path $$(WORKDIR) -o $$@ $$< + @diff -q $(1)-opcodes.ref $$@ || (cat $$(WORKDIR)/$(1)-opcodes.lst ; exit 1) + @echo ca65 --cpu $(1) ok +endef + +$(foreach target,$(TARGETS),$(eval $(call build,$(target)))) + diff --git a/test/assembler/huc6280-opcodes.ref b/test/assembler/huc6280-opcodes.ref new file mode 100644 index 0000000000000000000000000000000000000000..33f5b297f1c8e04365f3c6f613a7c30b373b11bf GIT binary patch literal 547 zcmWN}g`-b*9LHfU({)~(?w&Dq-ln^|KhsR-#5K-Wch{!7ZF+2S`kL;mYq&Q2n7X<> zf4~zXCSkFN%@@QWF7e`%AYmd?Vp9@RQe3jY1HR-dl9Pgzq)Kf{lQx|xy(xn!BQBFE zGg-2djqKzgCtv5{o7{O!-<tB8^5OCa1t^Fw3h^C<DN@u_tau4iNmD6PX<V7Ilq(-r zA*e_tDpRE@)vDJp)il*I)yCBc>QayTG-!zNJ&hWhnlx?J+|<I<64&YnTDNISJKEEM zj-BY-rK_o%=|@v{T#uk9y$JXH@Nm!T%}?~9FM%`l>p#FW&@{+27&jys%CO;tMlh05 zjAqPO#*Lp~nrND2nv9zg{LC**B@~**bY?J<S+h-Z=FT(CH!UzN#4TbmOIS*18OvG0 zul%->Rjb#S)|%Ft*5iH;Hn5RDJ}-Z=iOp<b>o(K&zjl~*ns%9X<MyzZeG$GN5#f3J z`I`eA<j`S`96e?_ZaQH)i8~dX<_wX(9~tR+XU}n-3tYTpx_ss8HPdy|Ke!v*<W`jL zM@4zwZT{sy?r`@Wq5BU^|C=6~9^oDbPk2hS??*>_-m~Yt;3cnKo8G*A_ullu^bz+7 DEAPQE literal 0 HcmV?d00001 diff --git a/test/assembler/huc6280-opcodes.s b/test/assembler/huc6280-opcodes.s new file mode 100644 index 000000000..bd3ad5c79 --- /dev/null +++ b/test/assembler/huc6280-opcodes.s @@ -0,0 +1,258 @@ +.setcpu "huc6280" + + brk + ora ($12,x) + sxy + st0 #$12 + 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) + st1 #$12 + 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) + sax + st2 #$12 + 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) + say + tma #$02 + bsr *+122 + 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) + tam #$12 + csl + 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) + cla + .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) + tii $3333,$7373,$1111 + 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) + clx + tst #$12,$EA + 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) + tst #$12,$EAEA + 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 + tst #$12,$EA,x + 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) + tst #$12,$EAEA,x + 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) + cly + tdd $3333,$C3C3,$1111 + cpy $12 + cmp $12 + dec $12 + smb4 $12 + iny + cmp #$12 + dex + .byte $CB + cpy $3456 + cmp $3456 + dec $3456 + bbs4 $12,*+122 + bne *+122 + cmp ($12),y + cmp ($12) + tin $3333,$D3D3,$1111 + .byte $D4 + cmp $12,x + dec $12,x + smb5 $12 + cld + cmp $3456,y + phx + .byte $DB + .byte $DC + cmp $3456,x + dec $3456,x + bbs5 $12,*+122 + cpx #$12 + sbc ($12,x) + .byte $E2 + tia $3333,$E3E3,$1111 + 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) + tai $3333,$F3F3,$1111 + .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 diff --git a/test/assembler/m740-opcodes.s b/test/assembler/m740-opcodes.s new file mode 100644 index 000000000..df6d71488 --- /dev/null +++ b/test/assembler/m740-opcodes.s @@ -0,0 +1,260 @@ +.setcpu "65C02" +; copy of 65c02, comments note changes to the m740 according to +; http://documentation.renesas.com/doc/products/mpumcu/rej09b0322_740sm.pdf + + 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 diff --git a/testcode/assembler/Makefile b/testcode/assembler/Makefile deleted file mode 100644 index 35c34235a..000000000 --- a/testcode/assembler/Makefile +++ /dev/null @@ -1,32 +0,0 @@ - -all: chklegal.bin chkillegal.bin chkall.bin chk4510.bin - @# - -.PHONY: chklegal.bin chkillegal.bin chkall.bin chk4510.bin - -chk4510.bin: 4510all.s - $(MAKE) -C ../../src all - ../../bin/cl65 --target none --cpu 4510 --listing 4510all.lst -o $@ $< - diff -q 4510all.ref $@ || cat 4510all.lst - -chklegal.bin: legal.s - ../../bin/cl65 --target none --cpu 6502X -o chklegal.bin legal.s - diff -q legal.ref chklegal.bin || hex chklegal.bin - -chkillegal.bin: illegal.s - ../../bin/cl65 --target none --cpu 6502X -o chkillegal.bin illegal.s - diff -q illegal.ref chkillegal.bin || hex chkillegal.bin - -chkall.bin: all.s - ../../bin/cl65 --target none --cpu 6502X -o chkall.bin all.s - -ref: legal.s illegal.s - ../../bin/cl65 --target none --cpu 6502X -o legal.ref legal.s - ../../bin/cl65 --target none --cpu 6502X -o illegal.ref illegal.s - -clean: - rm -f legal.o chklegal.bin - rm -f illegal.o chkillegal.bin - rm -f all.o chkall.bin - rm -f 4510all.o chk4510.bin 4510all.lst - diff --git a/testcode/assembler/all.s b/testcode/assembler/all.s deleted file mode 100644 index 2e8f55ec7..000000000 --- a/testcode/assembler/all.s +++ /dev/null @@ -1,260 +0,0 @@ - .setcpu "6502X" - -; all legal and illegal opcodes as they would be disassembled by da65 -; note that this would not assemble into the exact same binary - - brk ; 00 - ora ($12,x) ; 01 12 - jam ; 02 - slo ($12,x) ; 03 12 - nop $12 ; 04 12 - ora $12 ; 05 12 - asl $12 ; 06 12 - slo $12 ; 07 12 - php ; 08 - ora #$12 ; 09 12 - asl a ; 0a - anc #$12 ; 0b 12 - nop $1234 ; 0c 34 12 - ora $1234 ; 0d 34 12 - asl $1234 ; 0e 34 12 - slo $1234 ; 0f 34 12 - bpl *+$14 ; 10 12 - ora ($12),y ; 11 12 - jam ; 12 - slo ($12),y ; 13 12 - nop $12,x ; 14 12 - ora $12,x ; 15 12 - asl $12,x ; 16 12 - slo $12,x ; 17 12 - clc ; 18 - ora $1234,y ; 19 34 12 - nop ; 1a - slo $1234,y ; 1b 34 12 - nop $1234,x ; 1c 34 12 - ora $1234,x ; 1d 34 12 - asl $1234,x ; 1e 34 12 - slo $1234,x ; 1f 34 12 - jsr $1234 ; 20 34 12 - and ($12,x) ; 21 12 - jam ; 22 - rla ($12,x) ; 23 12 - bit $12 ; 24 12 - and $12 ; 25 12 - rol $12 ; 26 12 - rla $12 ; 27 12 - plp ; 28 - and #$12 ; 29 12 - rol a ; 2a - anc #$12 ; 2b 12 - bit $1234 ; 2c 34 12 - and $1234 ; 2d 34 12 - rol $1234 ; 2e 34 12 - rla $1234 ; 2f 34 12 - bmi *+$14 ; 30 12 - and ($12),y ; 31 12 - jam ; 32 - rla ($12),y ; 33 12 - nop $12,x ; 34 12 - and $12,x ; 35 12 - rol $12,x ; 36 12 - rla $12,x ; 37 12 - sec ; 38 - and $1234,y ; 39 34 12 - nop ; 3a - rla $1234,y ; 3b 34 12 - nop $1234,x ; 3c 34 12 - and $1234,x ; 3d 34 12 - rol $1234,x ; 3e 34 12 - rla $1234,x ; 3f 34 12 - rti ; 40 - eor ($12,x) ; 41 12 - jam ; 42 - sre ($12,x) ; 43 12 - nop $12 ; 44 12 - eor $12 ; 45 12 - lsr $12 ; 46 12 - sre $12 ; 47 12 - pha ; 48 - eor #$12 ; 49 12 - lsr a ; 4a - alr #$12 ; 4b 12 - jmp $1234 ; 4c 34 12 - eor $1234 ; 4d 34 12 - lsr $1234 ; 4e 34 12 - sre $1234 ; 4f 34 12 - bvc *+$14 ; 50 12 - eor ($12),y ; 51 12 - jam ; 52 - sre ($12),y ; 53 12 - nop $12,x ; 54 12 - eor $12,x ; 55 12 - lsr $12,x ; 56 12 - sre $12,x ; 57 12 - cli ; 58 - eor $1234,y ; 59 34 12 - nop ; 5a - sre $1234,y ; 5b 34 12 - nop $1234,x ; 5c 34 12 - eor $1234,x ; 5d 34 12 - lsr $1234,x ; 5e 34 12 - sre $1234,x ; 5f 34 12 - rts ; 60 - adc ($12,x) ; 61 12 - jam ; 62 - rra ($12,x) ; 63 12 - nop $12 ; 64 12 - adc $12 ; 65 12 - ror $12 ; 66 12 - rra $12 ; 67 12 - pla ; 68 - adc #$12 ; 69 12 - ror a ; 6a - arr #$12 ; 6b 12 - jmp ($1234) ; 6c 34 12 - adc $1234 ; 6d 34 12 - ror $1234 ; 6e 34 12 - rra $1234 ; 6f 34 12 - bvs *+$14 ; 70 12 - adc ($12),y ; 71 12 - jam ; 72 - rra ($12),y ; 73 12 - nop $12,x ; 74 12 - adc $12,x ; 75 12 - ror $12,x ; 76 12 - rra $12,x ; 77 12 - sei ; 78 - adc $1234,y ; 79 34 12 - nop ; 7a - rra $1234,y ; 7b 34 12 - nop $1234,x ; 7c 34 12 - adc $1234,x ; 7d 34 12 - ror $1234,x ; 7e 34 12 - rra $1234,x ; 7f 34 12 - nop #$12 ; 80 12 - sta ($12,x) ; 81 12 - nop #$12 ; 82 12 - sax ($12,x) ; 83 12 - sty $12 ; 84 12 - sta $12 ; 85 12 - stx $12 ; 86 12 - sax $12 ; 87 12 - dey ; 88 - nop #$12 ; 89 12 - txa ; 8a - ane #$12 ; 8b 12 - sty $1234 ; 8c 34 12 - sta $1234 ; 8d 34 12 - stx $1234 ; 8e 34 12 - sax $1234 ; 8f 34 12 - bcc *+$14 ; 90 12 - sta ($12),y ; 91 12 - jam ; 92 - sha ($12),y ; 93 12 - sty $12,x ; 94 12 - sta $12,x ; 95 12 - stx $12,y ; 96 12 - sax $12,y ; 97 12 - tya ; 98 - sta $1234,y ; 99 34 12 - txs ; 9a - tas $1234,y ; 9b 34 12 - shy $1234,x ; 9c 34 12 - sta $1234,x ; 9d 34 12 - shx $1234,y ; 9e 34 12 - sha $1234,y ; 9f 34 12 - ldy #$12 ; a0 12 - lda ($12,x) ; a1 12 - ldx #$12 ; a2 12 - lax ($12,x) ; a3 12 - ldy $12 ; a4 12 - lda $12 ; a5 12 - ldx $12 ; a6 12 - lax $12 ; a7 12 - tay ; a8 - lda #$12 ; a9 12 - tax ; aa - lax #$12 ; ab 12 - ldy $1234 ; ac 34 12 - lda $1234 ; ad 34 12 - ldx $1234 ; ae 34 12 - lax $1234 ; af 34 12 - bcs *+$14 ; b0 12 - lda ($12),y ; b1 12 - jam ; b2 - lax ($12),y ; b3 12 - ldy $12,x ; b4 12 - lda $12,x ; b5 12 - ldx $12,y ; b6 12 - lax $12,y ; b7 12 - clv ; b8 - lda $1234,y ; b9 34 12 - tsx ; ba - las $1234,y ; bb 34 12 - ldy $1234,x ; bc 34 12 - lda $1234,x ; bd 34 12 - ldx $1234,y ; be 34 12 - lax $1234,y ; bf 34 12 - cpy #$12 ; c0 12 - cmp ($12,x) ; c1 12 - nop #$12 ; c2 12 - dcp ($12,x) ; c3 12 - cpy $12 ; c4 12 - cmp $12 ; c5 12 - dec $12 ; c6 12 - dcp $12 ; c7 12 - iny ; c8 - cmp #$12 ; c9 12 - dex ; ca - axs #$12 ; cb 12 - cpy $1234 ; cc 34 12 - cmp $1234 ; cd 34 12 - dec $1234 ; ce 34 12 - dcp $1234 ; cf 34 12 - bne *+$14 ; d0 12 - cmp ($12),y ; d1 12 - jam ; d2 - dcp ($12),y ; d3 12 - nop $12,x ; d4 12 - cmp $12,x ; d5 12 - dec $12,x ; d6 12 - dcp $12,x ; d7 12 - cld ; d8 - cmp $1234,y ; d9 34 12 - nop ; da - dcp $1234,y ; db 34 12 - nop $1234,x ; dc 34 12 - cmp $1234,x ; dd 34 12 - dec $1234,x ; de 34 12 - dcp $1234,x ; df 34 12 - cpx #$12 ; e0 12 - sbc ($12,x) ; e1 12 - nop #$12 ; e2 12 - isc ($12,x) ; e3 12 - cpx $12 ; e4 12 - sbc $12 ; e5 12 - inc $12 ; e6 12 - isc $12 ; e7 12 - inx ; e8 - sbc #$12 ; e9 12 - nop ; ea - sbc #$12 ; eb 12 - cpx $1234 ; ec 34 12 - sbc $1234 ; ed 34 12 - inc $1234 ; ee 34 12 - isc $1234 ; ef 34 12 - beq *+$14 ; f0 12 - sbc ($12),y ; f1 12 - jam ; f2 - isc ($12),y ; f3 12 - nop $12,x ; f4 12 - sbc $12,x ; f5 12 - inc $12,x ; f6 12 - isc $12,x ; f7 12 - sed ; f8 - sbc $1234,y ; f9 34 12 - isc $1234,y ; fb 34 12 - nop $1234,x ; fc 34 12 - sbc $1234,x ; fd 34 12 - inc $1234,x ; fe 34 12 - isc $1234,x ; ff 34 12 diff --git a/testcode/assembler/illegal.ref b/testcode/assembler/illegal.ref deleted file mode 100644 index c8dc208b4..000000000 --- a/testcode/assembler/illegal.ref +++ /dev/null @@ -1 +0,0 @@ -444'/4?4;4#73O4_4[4GCWSo44{4gcwsÏ4ß4Û4ÇÃ×Óï4ÿ4û4çã÷ó4‡ƒ—¯4¿4§£³· kKË 44€“Ÿ4ž4œ4›4»4«‹ \ No newline at end of file diff --git a/testcode/assembler/illegal.s b/testcode/assembler/illegal.s deleted file mode 100644 index b49b88761..000000000 --- a/testcode/assembler/illegal.s +++ /dev/null @@ -1,135 +0,0 @@ - - .setcpu "6502X" - -; all so called "illegal" opcodes. duplicated (functionally identical) ones -; are commented out - -; first all totally stable undocs: - - slo $12 ; 07 12 - slo $1234 ; 0f 34 12 - slo $1234,x ; 1f 34 12 - slo $1234,y ; 1b 34 12 - slo ($12,x) ; 03 12 - slo $12,x ; 17 12 - slo ($12),y ; 13 12 - - rla $12 ; 27 12 - rla $1234 ; 2f 34 12 - rla $1234,x ; 3f 34 12 - rla $1234,y ; 3b 34 12 - rla ($12,x) ; 23 12 - rla $12,x ; 37 12 - rla ($12),y ; 33 12 - - sre $1234 ; 4f 34 12 - sre $1234,x ; 5f 34 12 - sre $1234,y ; 5b 34 12 - sre $12 ; 47 12 - sre ($12,x) ; 43 12 - sre $12,x ; 57 12 - sre ($12),y ; 53 12 - - rra $1234 ; 6f 34 12 - rra $1234,x ; 7f 34 12 - rra $1234,y ; 7b 34 12 - rra $12 ; 67 12 - rra ($12,x) ; 63 12 - rra $12,x ; 77 12 - rra ($12),y ; 73 12 - - dcp $1234 ; cf 34 12 - dcp $1234,x ; df 34 12 - dcp $1234,y ; db 34 12 - dcp $12 ; c7 12 - dcp ($12,x) ; c3 12 - dcp $12,x ; d7 12 - dcp ($12),y ; d3 12 - - isc $1234 ; ef 34 12 - isc $1234,x ; ff 34 12 - isc $1234,y ; fb 34 12 - isc $12 ; e7 12 - isc ($12,x) ; e3 12 - isc $12,x ; f7 12 - isc ($12),y ; f3 12 - - sax $1234 ; 8f 34 12 - sax $12 ; 87 12 - sax ($12,x) ; 83 12 - sax $12,y ; 97 12 - - lax $1234 ; af 34 12 - lax $1234,y ; bf 34 12 - lax $12 ; a7 12 - lax ($12,x) ; a3 12 - lax ($12),y ; b3 12 - lax $12,y ; b7 12 - - anc #$12 ; 0b 12 - ;anc #$12 ; 2b 12 - - arr #$12 ; 6b 12 - - alr #$12 ; 4b 12 - - axs #$12 ; cb 12 - - nop $1234 ; 0c 34 12 - nop $1234,x ; 1c 34 12 - nop $12 ; 04 12 - nop $12,x ; 14 12 - nop #$12 ; 80 12 - ;nop $1234,x ; 3c 34 12 - ;nop $1234,x ; 5c 34 12 - ;nop $1234,x ; 7c 34 12 - ;nop $1234,x ; dc 34 12 - ;nop $1234,x ; fc 34 12 - ;nop $12 ; 44 12 - ;nop $12 ; 64 12 - ;nop #$12 ; 82 12 - ;nop #$12 ; 89 12 - ;nop #$12 ; c2 12 - ;nop #$12 ; e2 12 - ;nop $12,x ; 34 12 - ;nop $12,x ; 54 12 - ;nop $12,x ; 74 12 - ;nop $12,x ; d4 12 - ;nop $12,x ; f4 12 - ;nop ; 1a - ;nop ; 3a - ;nop ; 5a - ;nop ; 7a - ;nop ; da - - jam ; 02 - ;jam ; 12 - ;jam ; 22 - ;jam ; 32 - ;jam ; 42 - ;jam ; 52 - ;jam ; 62 - ;jam ; 72 - ;jam ; 92 - ;jam ; b2 - ;jam ; d2 - ;jam ; f2 - - ;sbc #$12 ; eb 12 - -; the so-called "unstable" ones: - - sha ($12),y ; 93 12 - sha $1234,y ; 9f 34 12 - - shx $1234,y ; 9e 34 12 - shy $1234,x ; 9c 34 12 - - tas $1234,y ; 9b 34 12 - las $1234,y ; bb 34 12 - -; the two so-called "highly unstable" ones: - - lax #$12 ; ab 12 - - ane #$12 ; 8b 12 diff --git a/testcode/assembler/legal.ref b/testcode/assembler/legal.ref deleted file mode 100644 index c38f2901465090f656f005ccd12e091ee55c3911..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 321 zcmV~$L1+j700q!F5XzcYmK|tn7DCjwI1mS#W#TY#u;wr!WQU0ZrI2K6D-$b)SR<3w z2#qMyCS(WVuw`W$Ar8cW_TIiY5{IMSZaXw;FxPyGVr8s|IhI*!lERoB#iq8n?S~~^ zE3(M}Wfn%k%y(Pwy^NuFAAJTq@y4L9@xezg;<2Y*#c(|H*7H-<u|2lMTI;P*W3%t^ zKR)?wtbar7jne3fhjBlyx$d$%y4{LLaYcu_Zbolha#fFwQ5)-QQT1h_DW=7&D2WMX zn67g2u6gAa$Ev8XV1FEqoetWwy6#*2i@!1Ivk|}iwEWMZrnndv;)G+`v}%r%&N&mu Mopq!0!Rhw%<3WF3zyJUM diff --git a/testcode/assembler/legal.s b/testcode/assembler/legal.s deleted file mode 100644 index 1de43b98b..000000000 --- a/testcode/assembler/legal.s +++ /dev/null @@ -1,185 +0,0 @@ - - .setcpu "6502" - - adc $1234 ; 6d 34 12 - adc $1234,x ; 7d 34 12 - adc $1234,y ; 79 34 12 - adc $12 ; 65 12 - adc #$12 ; 69 12 - adc ($12,x) ; 61 12 - adc $12,x ; 75 12 - adc ($12),y ; 71 12 - - and $12 ; 25 12 - and #$12 ; 29 12 - and $1234 ; 2d 34 12 - and $1234,x ; 3d 34 12 - and $1234,y ; 39 34 12 - and ($12,x) ; 21 12 - and $12,x ; 35 12 - and ($12),y ; 31 12 - - asl $12 ; 06 12 - asl $1234 ; 0e 34 12 - asl $1234,x ; 1e 34 12 - asl $12,x ; 16 12 - asl a ; 0a - - bcc *+$14 ; 90 12 - bcs *+$14 ; b0 12 - beq *+$14 ; f0 12 - bmi *+$14 ; 30 12 - bne *+$14 ; d0 12 - bpl *+$14 ; 10 12 - bvc *+$14 ; 50 12 - bvs *+$14 ; 70 12 - - bit $12 ; 24 12 - bit $1234 ; 2c 34 12 - - brk ; 00 - - clc ; 18 - cld ; d8 - cli ; 58 - clv ; b8 - - cmp $1234 ; cd 34 12 - cmp $1234,x ; dd 34 12 - cmp $1234,y ; d9 34 12 - cmp $12 ; c5 12 - cmp #$12 ; c9 12 - cmp ($12,x) ; c1 12 - cmp $12,x ; d5 12 - cmp ($12),y ; d1 12 - - cpx $1234 ; ec 34 12 - cpx #$12 ; e0 12 - cpx $12 ; e4 12 - - cpy $1234 ; cc 34 12 - cpy #$12 ; c0 12 - cpy $12 ; c4 12 - - dec $1234 ; ce 34 12 - dec $1234,x ; de 34 12 - dec $12 ; c6 12 - dec $12,x ; d6 12 - - dex ; ca - dey ; 88 - - eor $1234 ; 4d 34 12 - eor $1234,x ; 5d 34 12 - eor $1234,y ; 59 34 12 - eor $12 ; 45 12 - eor #$12 ; 49 12 - eor ($12,x) ; 41 12 - eor $12,x ; 55 12 - eor ($12),y ; 51 12 - - inc $1234 ; ee 34 12 - inc $1234,x ; fe 34 12 - inc $12 ; e6 12 - inc $12,x ; f6 12 - - inx ; e8 - iny ; c8 - - jmp $1234 ; 4c 34 12 - jmp ($1234) ; 6c 34 12 - - jsr $1234 ; 20 34 12 - - lda $1234 ; ad 34 12 - lda $1234,x ; bd 34 12 - lda $1234,y ; b9 34 12 - lda $12 ; a5 12 - lda #$12 ; a9 12 - lda ($12,x) ; a1 12 - lda $12,x ; b5 12 - lda ($12),y ; b1 12 - - ldx $1234 ; ae 34 12 - ldx $1234,y ; be 34 12 - ldx #$12 ; a2 12 - ldx $12 ; a6 12 - ldx $12,y ; b6 12 - - ldy $1234 ; ac 34 12 - ldy $1234,x ; bc 34 12 - ldy #$12 ; a0 12 - ldy $12 ; a4 12 - ldy $12,x ; b4 12 - - lsr $1234 ; 4e 34 12 - lsr $1234,x ; 5e 34 12 - lsr $12 ; 46 12 - lsr $12,x ; 56 12 - lsr a ; 4a - - nop ; ea - - ora $12 ; 05 12 - ora #$12 ; 09 12 - ora $1234 ; 0d 34 12 - ora $1234,x ; 1d 34 12 - ora $1234,y ; 19 34 12 - ora ($12,x) ; 01 12 - ora $12,x ; 15 12 - ora ($12),y ; 11 12 - - pha ; 48 - php ; 08 - pla ; 68 - plp ; 28 - - rol $12 ; 26 12 - rol $1234 ; 2e 34 12 - rol $1234,x ; 3e 34 12 - rol $12,x ; 36 12 - rol a ; 2a - ror $1234 ; 6e 34 12 - ror $1234,x ; 7e 34 12 - ror $12 ; 66 12 - ror $12,x ; 76 12 - ror a ; 6a - - rti ; 40 - rts ; 60 - - sbc $1234 ; ed 34 12 - sbc $1234,x ; fd 34 12 - sbc $1234,y ; f9 34 12 - sbc $12 ; e5 12 - sbc #$12 ; e9 12 - sbc ($12,x) ; e1 12 - sbc $12,x ; f5 12 - sbc ($12),y ; f1 12 - - sec ; 38 - sed ; f8 - sei ; 78 - - sta $1234 ; 8d 34 12 - sta $1234,x ; 9d 34 12 - sta $1234,y ; 99 34 12 - sta $12 ; 85 12 - sta ($12,x) ; 81 12 - sta $12,x ; 95 12 - sta ($12),y ; 91 12 - - stx $1234 ; 8e 34 12 - stx $12 ; 86 12 - stx $12,y ; 96 12 - - sty $1234 ; 8c 34 12 - sty $12 ; 84 12 - sty $12,x ; 94 12 - - tax ; aa - tay ; a8 - tsx ; ba - txa ; 8a - txs ; 9a - tya ; 98 From 896b7c1116e90e8f1bb7a8ec92fd556b7144dfdf Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 4 Sep 2016 12:22:11 +0200 Subject: [PATCH 0151/2161] Added comment about commented-out value. --- asminc/cpu.mac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asminc/cpu.mac b/asminc/cpu.mac index a67407a4a..6b9cb9947 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -7,7 +7,7 @@ CPU_ISET_65C02 = $0010 CPU_ISET_65816 = $0020 CPU_ISET_SWEET16 = $0040 CPU_ISET_HUC6280 = $0080 -;CPU_ISET_M740 = $0100 +;CPU_ISET_M740 = $0100 not actually implemented CPU_ISET_4510 = $0200 ; CPU capabilities From f007fc13d581c0056695e7854d8f9e580f4c2b7c Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Tue, 6 Sep 2016 14:54:21 +0200 Subject: [PATCH 0152/2161] added README for test/assembler --- test/assembler/Makefile | 2 +- test/assembler/README | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 test/assembler/README diff --git a/test/assembler/Makefile b/test/assembler/Makefile index 5e4d580b5..47f403469 100644 --- a/test/assembler/Makefile +++ b/test/assembler/Makefile @@ -14,7 +14,7 @@ TARGETS += huc6280 all: $(addprefix $(WORKDIR)/, $(addsuffix -opcodes.bin, $(TARGETS))) @# -.PHONY: $(addprefix $(WORKDIR)/, $(addsuffix -opcodes.bin, $(TARGETS))) +.PHONY: all clean $(addprefix $(WORKDIR)/, $(addsuffix -opcodes.bin, $(TARGETS))) clean: rm -f *.o *.bin *.lst diff --git a/test/assembler/README b/test/assembler/README new file mode 100644 index 000000000..697c24449 --- /dev/null +++ b/test/assembler/README @@ -0,0 +1,29 @@ + +Assembler Testcases +=================== + +These testcases are inspired by the ones now removed from test/assembler. +The main purpose is to have each possible opcode generated at least once, +either by an assembly instruction or a ".byte"-placeholder. Typically +generated by disassembling a binary dump that contains data in the form +of the pattern that each opcode is stated once in order followed by easy +to recognise: + +00 00 EA 00 +01 00 EA 00 +02 00 EA 00 +[...] +fe 00 EA 00 +ff 00 EA 00 + +The disassembly is then put in a better readable form by replacing the +leftover dummy opcode parameters with something more recognizable. + +The testcases for 6502, 6502x, 65sc02, 65c02, 4510, and huc6280 have been +put together by Sven Oliver ("SvOlli") Moll, as well as a template for the +m740 instructions set. + +Still to do is to find a way to implement a testcase for the 65816 +processor, since it's capable of executing instructions with an 8-bit and +a 16-bit operator alike, only distinguished by one processor flag. + From 3531bcbf3e3aac04b8967949bcc77e8e13395418 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 6 Sep 2016 15:13:44 +0200 Subject: [PATCH 0153/2161] Fix some typos. --- doc/atari.sgml | 2 +- src/ca65/scanner.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/atari.sgml b/doc/atari.sgml index 54f3aab78..a0dbe2f47 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -337,7 +337,7 @@ A word of caution: Since the <tt/0x00/ character has to be mapped in an incompatible way to the C-standard, the usage of string functions in conjunction with internal character mapped strings delivers unexpected results regarding the string length. The end of strings are detected where -you may not expect them (to early or (much) to late). Internal mapped +you may not expect them (too early or (much) too late). Internal mapped strings typically support the "<tt/mem...()/" functions. <em>For assembler sources the macro "<tt/scrcode/" from the "<tt/atari.mac/" diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index f33ed5def..994f95fba 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -408,7 +408,7 @@ static void IFNextChar (CharSource* S) /* If we come here, we have a new input line. To avoid problems ** with strange line terminators, remove all whitespace from the - ** end of the line, the add a single newline. + ** end of the line, then add a single newline. */ Len = SB_GetLen (&S->V.File.Line); while (Len > 0 && IsSpace (SB_AtUnchecked (&S->V.File.Line, Len-1))) { From ae3f9bbd778ac8525c586d77a201c0ad36db2ba5 Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Wed, 7 Sep 2016 19:21:24 +0200 Subject: [PATCH 0154/2161] Added assembler pseudo commands .P4510 and .IFP4510 together with docs and testcase --- doc/ca65.sgml | 37 ++++++++++++++++---- src/ca65/condasm.c | 11 ++++++ src/ca65/pseudo.c | 10 ++++++ src/ca65/scanner.c | 2 ++ src/ca65/token.h | 2 ++ test/assembler/4510-cpudetect.ref | Bin 0 -> 60 bytes test/assembler/6502-cpudetect.ref | Bin 0 -> 16 bytes test/assembler/6502x-cpudetect.ref | Bin 0 -> 29 bytes test/assembler/65816-cpudetect.ref | Bin 0 -> 61 bytes test/assembler/65c02-cpudetect.ref | Bin 0 -> 47 bytes test/assembler/65sc02-cpudetect.ref | Bin 0 -> 33 bytes test/assembler/Makefile | 49 ++++++++++++++++++--------- test/assembler/README | 21 +++++++++++- test/assembler/huc6280-cpudetect.ref | Bin 0 -> 62 bytes 14 files changed, 109 insertions(+), 23 deletions(-) create mode 100644 test/assembler/4510-cpudetect.ref create mode 100644 test/assembler/6502-cpudetect.ref create mode 100644 test/assembler/6502x-cpudetect.ref create mode 100644 test/assembler/65816-cpudetect.ref create mode 100644 test/assembler/65c02-cpudetect.ref create mode 100644 test/assembler/65sc02-cpudetect.ref create mode 100644 test/assembler/huc6280-cpudetect.ref diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 6ce5ecef6..baabffa7c 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -424,8 +424,10 @@ The assembler accepts <tt><ref id=".PSC02" name=".PSC02"></tt> command was given). <item>all valid 65C02 mnemonics when in 65C02 mode (after the <tt><ref id=".PC02" name=".PC02"></tt> command was given). -<item>all valid 65618 mnemonics when in 65816 mode (after the +<item>all valid 65816 mnemonics when in 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 + <tt><ref id=".P4510" name=".P4510"></tt> command was given). </itemize> @@ -3103,6 +3105,12 @@ Here's a list of all control commands and a description, what they do: (see <tt><ref id=".P02" name=".P02"></tt> command). +<sect1><tt>.IFP4510</tt><label id=".IFP4510"><p> + + Conditional assembly: Check if the assembler is currently in 4510 mode + (see <tt><ref id=".P4510" name=".P4510"></tt> command). + + <sect1><tt>.IFP816</tt><label id=".IFP816"><p> Conditional assembly: Check if the assembler is currently in 65816 mode @@ -3494,7 +3502,18 @@ Here's a list of all control commands and a description, what they do: <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> and <tt><ref id=".P816" name=".P816"></tt> + 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 + 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> <sect1><tt>.P816</tt><label id=".P816"><p> @@ -3503,7 +3522,8 @@ Here's a list of all control commands and a description, what they do: 6502 instruction sets. See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PSC02" - name=".PSC02"></tt> and <tt><ref id=".PC02" name=".PC02"></tt> + name=".PSC02"></tt>, <tt><ref id=".PC02" name=".PC02"></tt> and + <tt><ref id=".P4510" name=".P4510"></tt> <sect1><tt>.PAGELEN, .PAGELENGTH</tt><label id=".PAGELENGTH"><p> @@ -3531,7 +3551,8 @@ Here's a list of all control commands and a description, what they do: 6502 and 65SC02 instructions. See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PSC02" - name=".PSC02"></tt> and <tt><ref id=".P816" name=".P816"></tt> + name=".PSC02"></tt>, <tt><ref id=".P816" name=".P816"></tt> and + <ref id=".P4510" name=".P4510">4510</tt> <sect1><tt>.POPCPU</tt><label id=".POPCPU"><p> @@ -3604,7 +3625,8 @@ Here's a list of all control commands and a description, what they do: 6502 instructions. See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PC02" - name=".PC02"></tt> and <tt><ref id=".P816" name=".P816"></tt> + name=".PC02"></tt>, <tt><ref id=".P816" name=".P816"></tt> and + <tt><ref id=".P4510" name=".P4510"></tt> <sect1><tt>.PUSHCPU</tt><label id=".PUSHCPU"><p> @@ -3796,7 +3818,7 @@ Here's a list of all control commands and a description, what they do: 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, 65SC02, 65C02, 65816 and HuC6280. + namely: 6502, 6502X, 65SC02, 65C02, 65816, 4510 and HuC6280. See: <tt><ref id=".CPU" name=".CPU"></tt>, <tt><ref id=".IFP02" name=".IFP02"></tt>, @@ -3805,6 +3827,7 @@ Here's a list of all control commands and a description, what they do: <tt><ref id=".IFPSC02" name=".IFPSC02"></tt>, <tt><ref id=".P02" 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=".PSC02" name=".PSC02"></tt> @@ -4501,6 +4524,7 @@ each supported CPU a constant similar to CPU_65816 CPU_SWEET16 CPU_HUC6280 + CPU_4510 </verb></tscreen> is defined. These constants may be used to determine the exact type of the @@ -4514,6 +4538,7 @@ another constant is defined: CPU_ISET_65816 CPU_ISET_SWEET16 CPU_ISET_HUC6280 + CPU_ISET_4510 </verb></tscreen> The value read from the <tt/<ref id=".CPU" name=".CPU">/ pseudo variable may diff --git a/src/ca65/condasm.c b/src/ca65/condasm.c index 24cbae696..b8bda4c7d 100644 --- a/src/ca65/condasm.c +++ b/src/ca65/condasm.c @@ -386,6 +386,16 @@ void DoConditionals (void) CalcOverallIfCond (); break; + case TOK_IFP4510: + D = AllocIf (".IFP4510", 1); + NextTok (); + if (IfCond) { + SetIfCond (D, GetCPU() == CPU_4510); + } + ExpectSep (); + CalcOverallIfCond (); + break; + case TOK_IFP816: D = AllocIf (".IFP816", 1); NextTok (); @@ -457,6 +467,7 @@ int CheckConditionals (void) case TOK_IFNDEF: case TOK_IFNREF: case TOK_IFP02: + case TOK_IFP4510: case TOK_IFP816: case TOK_IFPC02: case TOK_IFPSC02: diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 250ceecc9..b44c28dd8 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1530,6 +1530,14 @@ static void DoP816 (void) +static void DoP4510 (void) +/* Switch to 4510 CPU */ +{ + SetCPU (CPU_4510); +} + + + static void DoPageLength (void) /* Set the page length for the listing */ { @@ -2033,6 +2041,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccKeepToken, DoConditionals }, /* .IFNDEF */ { ccKeepToken, DoConditionals }, /* .IFNREF */ { ccKeepToken, DoConditionals }, /* .IFP02 */ + { ccKeepToken, DoConditionals }, /* .IFP4510 */ { ccKeepToken, DoConditionals }, /* .IFP816 */ { ccKeepToken, DoConditionals }, /* .IFPC02 */ { ccKeepToken, DoConditionals }, /* .IFPSC02 */ @@ -2063,6 +2072,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoOrg }, { ccNone, DoOut }, { ccNone, DoP02 }, + { ccNone, DoP4510 }, { ccNone, DoP816 }, { ccNone, DoPageLength }, { ccNone, DoUnexpected }, /* .PARAMCOUNT */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 994f95fba..e186b19a7 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -216,6 +216,7 @@ struct DotKeyword { { ".IFNDEF", TOK_IFNDEF }, { ".IFNREF", TOK_IFNREF }, { ".IFP02", TOK_IFP02 }, + { ".IFP4510", TOK_IFP4510 }, { ".IFP816", TOK_IFP816 }, { ".IFPC02", TOK_IFPC02 }, { ".IFPSC02", TOK_IFPSC02 }, @@ -251,6 +252,7 @@ struct DotKeyword { { ".ORG", TOK_ORG }, { ".OUT", TOK_OUT }, { ".P02", TOK_P02 }, + { ".P4510", TOK_P4510 }, { ".P816", TOK_P816 }, { ".PAGELEN", TOK_PAGELENGTH }, { ".PAGELENGTH", TOK_PAGELENGTH }, diff --git a/src/ca65/token.h b/src/ca65/token.h index 93dfaa092..8998cc162 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_IFP4510, TOK_IFP816, TOK_IFPC02, TOK_IFPSC02, @@ -223,6 +224,7 @@ typedef enum token_t { TOK_ORG, TOK_OUT, TOK_P02, + TOK_P4510, TOK_P816, TOK_PAGELENGTH, TOK_PARAMCOUNT, diff --git a/test/assembler/4510-cpudetect.ref b/test/assembler/4510-cpudetect.ref new file mode 100644 index 0000000000000000000000000000000000000000..515557c854d36f3bc8310b6c2a9cc0b2b0a98ade GIT binary patch literal 60 hcmeZfa1IEK_Y8Ioi8nJfFhb@9JEQVZxF)8C1_0up55fQd literal 0 HcmV?d00001 diff --git a/test/assembler/6502-cpudetect.ref b/test/assembler/6502-cpudetect.ref new file mode 100644 index 0000000000000000000000000000000000000000..9b0aeb1f0915c5f4d81e08d02a8e223b4f6464d6 GIT binary patch literal 16 XcmZ4aiorP`G~P4VH6-55)W8S;Gr|Qt literal 0 HcmV?d00001 diff --git a/test/assembler/6502x-cpudetect.ref b/test/assembler/6502x-cpudetect.ref new file mode 100644 index 0000000000000000000000000000000000000000..3434ecbea7fb1e119879fae346989933fd09bacd GIT binary patch literal 29 ZcmZQ@4hW6+40a8PH#0RbVnE?V0042#2dMx6 literal 0 HcmV?d00001 diff --git a/test/assembler/65816-cpudetect.ref b/test/assembler/65816-cpudetect.ref new file mode 100644 index 0000000000000000000000000000000000000000..4f6e767b0b9e0d16b239976a71a01268186788b3 GIT binary patch literal 61 gcmaFO;2aPd?-}eG5^rW|V1&#Ic1Go+aV-qZ02t>Gq5uE@ literal 0 HcmV?d00001 diff --git a/test/assembler/65c02-cpudetect.ref b/test/assembler/65c02-cpudetect.ref new file mode 100644 index 0000000000000000000000000000000000000000..9f790d5ffe95736f46383b1c132407d7f96bf2b0 GIT binary patch literal 47 ecmZP<VsH)!jrR<84T(21H84Wv1v{hifm{F-u?y<} literal 0 HcmV?d00001 diff --git a/test/assembler/65sc02-cpudetect.ref b/test/assembler/65sc02-cpudetect.ref new file mode 100644 index 0000000000000000000000000000000000000000..4e11bd708c8c298112aabc639c2fe6ba710cc69c GIT binary patch literal 33 ecmb<15n^x-2#xm)b`6O)Gc_<m<^?+&7y$s1#0aSX literal 0 HcmV?d00001 diff --git a/test/assembler/Makefile b/test/assembler/Makefile index 47f403469..faefddf7a 100644 --- a/test/assembler/Makefile +++ b/test/assembler/Makefile @@ -5,26 +5,43 @@ BINDIR = ../../bin #WORKDIR := ../../testwrk WORKDIR := . -TARGETS = 6502 6502x 65sc02 65c02 -#TARGETS += 65816 -TARGETS += 4510 -TARGETS += huc6280 -#TARGETS += m740 +BASE_TARGETS = 6502 6502x 65sc02 65c02 +BASE_TARGETS += 4510 huc6280 -all: $(addprefix $(WORKDIR)/, $(addsuffix -opcodes.bin, $(TARGETS))) +OPCODE_TARGETS = $(BASE_TARGETS) +CPUDETECT_TARGETS = $(BASE_TARGETS) + +CPUDETECT_TARGETS += 65816 + +# default target defined later +all: + +# generate opcode targets and expand target list +define opcode +OPCODE_TARGETLIST += $(1)-opcodes.bin +$$(WORKDIR)/$(1)-opcodes.bin: $(1)-opcodes.s + @$$(BINDIR)/cl65 --cpu $(1) -t none -l $$(WORKDIR)/$(1)-opcodes.lst --obj-path $$(WORKDIR) -o $$@ $$< + @diff -q $(1)-opcodes.ref $$@ || (cat $$(WORKDIR)/$(1)-opcodes.lst ; exit 1) + @echo ca65 --cpu $(1) opcodes ok +endef +$(foreach target,$(OPCODE_TARGETS),$(eval $(call opcode,$(target)))) + +# generate cpudetect targets and expand target list +define cpudetect +CPUDETECT_TARGETLIST += $(1)-cpudetect.bin +$$(WORKDIR)/$(1)-cpudetect.bin: cpudetect.s + @$$(BINDIR)/cl65 --cpu $(1) -t none -l $$(WORKDIR)/$(1)-cpudetect.lst --obj-path $$(WORKDIR) -o $$@ $$< + @diff -q $(1)-cpudetect.ref $$@ || (cat $$(WORKDIR)/$(1)-cpudetect.lst ; exit 1) + @echo ca65 --cpu $(1) cpudetect ok +endef +$(foreach target,$(CPUDETECT_TARGETS),$(eval $(call cpudetect,$(target)))) + +# now that all targets have been generated, get to the manual ones +all: $(OPCODE_TARGETLIST) $(CPUDETECT_TARGETLIST) @# -.PHONY: all clean $(addprefix $(WORKDIR)/, $(addsuffix -opcodes.bin, $(TARGETS))) - clean: rm -f *.o *.bin *.lst -define build -$$(WORKDIR)/$(1)-opcodes.bin: $(1)-opcodes.s - @$$(BINDIR)/cl65 --cpu $(1) -t none -l $$(WORKDIR)/$(1)-opcodes.lst --obj-path $$(WORKDIR) -o $$@ $$< - @diff -q $(1)-opcodes.ref $$@ || (cat $$(WORKDIR)/$(1)-opcodes.lst ; exit 1) - @echo ca65 --cpu $(1) ok -endef - -$(foreach target,$(TARGETS),$(eval $(call build,$(target)))) +.PHONY: all clean $(OPCODE_TARGETLIST) $(CPUDETECT_TARGETLIST) diff --git a/test/assembler/README b/test/assembler/README index 697c24449..a2b1e9a41 100644 --- a/test/assembler/README +++ b/test/assembler/README @@ -2,6 +2,9 @@ Assembler Testcases =================== +Opcode Tests: +------------- + These testcases are inspired by the ones now removed from test/assembler. The main purpose is to have each possible opcode generated at least once, either by an assembly instruction or a ".byte"-placeholder. Typically @@ -23,7 +26,23 @@ The testcases for 6502, 6502x, 65sc02, 65c02, 4510, and huc6280 have been put together by Sven Oliver ("SvOlli") Moll, as well as a template for the m740 instructions set. -Still to do is to find a way to implement a testcase for the 65816 +Still to do is to find a way to implement an opcode testcase for the 65816 processor, since it's capable of executing instructions with an 8-bit and a 16-bit operator alike, only distinguished by one processor flag. + +CPU detect Tests +---------------- + +These tests all assemble the same file "cpudetect.s" which contains several +conditionals for several CPUs, only using every option known to the "--cpu" +commandline switch of ca65/cl65. + + +Reference (".ref") Files +------------------------ + +A hint on creating these files: when running the test, it will fail due to +the missing ".ref" file. Review the output of the ".lst" very pedantic, then +copy the ".bin" to the ".ref" file. + diff --git a/test/assembler/huc6280-cpudetect.ref b/test/assembler/huc6280-cpudetect.ref new file mode 100644 index 0000000000000000000000000000000000000000..646e0f48cfcaf4a1a191b0fe3a508d02423bf0b6 GIT binary patch literal 62 kcmZQ@4hW6+40a8PH#0RbVnE^rJEQVZxE`U-W=0kU00MFlT>t<8 literal 0 HcmV?d00001 From 7a9a7c3188bf36b278922439f957af7dab4617c2 Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Wed, 7 Sep 2016 19:41:37 +0200 Subject: [PATCH 0155/2161] test/assembler: removed WORKDIR variable, as remote assembling does only work partly --- test/assembler/Makefile | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/test/assembler/Makefile b/test/assembler/Makefile index faefddf7a..a085bc390 100644 --- a/test/assembler/Makefile +++ b/test/assembler/Makefile @@ -2,8 +2,6 @@ # makefile for the assembler regression tests BINDIR = ../../bin -#WORKDIR := ../../testwrk -WORKDIR := . BASE_TARGETS = 6502 6502x 65sc02 65c02 BASE_TARGETS += 4510 huc6280 @@ -19,9 +17,9 @@ all: # generate opcode targets and expand target list define opcode OPCODE_TARGETLIST += $(1)-opcodes.bin -$$(WORKDIR)/$(1)-opcodes.bin: $(1)-opcodes.s - @$$(BINDIR)/cl65 --cpu $(1) -t none -l $$(WORKDIR)/$(1)-opcodes.lst --obj-path $$(WORKDIR) -o $$@ $$< - @diff -q $(1)-opcodes.ref $$@ || (cat $$(WORKDIR)/$(1)-opcodes.lst ; exit 1) +$(1)-opcodes.bin: $(1)-opcodes.s + @$$(BINDIR)/cl65 --cpu $(1) -t none -l $(1)-opcodes.lst -o $$@ $$< + @diff -q $(1)-opcodes.ref $$@ || (cat $(1)-opcodes.lst ; exit 1) @echo ca65 --cpu $(1) opcodes ok endef $(foreach target,$(OPCODE_TARGETS),$(eval $(call opcode,$(target)))) @@ -29,9 +27,9 @@ $(foreach target,$(OPCODE_TARGETS),$(eval $(call opcode,$(target)))) # generate cpudetect targets and expand target list define cpudetect CPUDETECT_TARGETLIST += $(1)-cpudetect.bin -$$(WORKDIR)/$(1)-cpudetect.bin: cpudetect.s - @$$(BINDIR)/cl65 --cpu $(1) -t none -l $$(WORKDIR)/$(1)-cpudetect.lst --obj-path $$(WORKDIR) -o $$@ $$< - @diff -q $(1)-cpudetect.ref $$@ || (cat $$(WORKDIR)/$(1)-cpudetect.lst ; exit 1) +$(1)-cpudetect.bin: cpudetect.s + @$$(BINDIR)/cl65 --cpu $(1) -t none -l $(1)-cpudetect.lst -o $$@ $$< + @diff -q $(1)-cpudetect.ref $$@ || (cat $(1)-cpudetect.lst ; exit 1) @echo ca65 --cpu $(1) cpudetect ok endef $(foreach target,$(CPUDETECT_TARGETS),$(eval $(call cpudetect,$(target)))) From c0d2643952b36a593777ca673238f69a8f1d7135 Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Wed, 7 Sep 2016 19:44:11 +0200 Subject: [PATCH 0156/2161] added 4510 cpu detection to getcpu.s --- include/6502.h | 1 + libsrc/common/getcpu.s | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/6502.h b/include/6502.h index 6c104c83a..31398e5c1 100644 --- a/include/6502.h +++ b/include/6502.h @@ -50,6 +50,7 @@ typedef unsigned size_t; #define CPU_6502 0 #define CPU_65C02 1 #define CPU_65816 2 +#define CPU_4510 3 unsigned char getcpu (void); /* Detect the CPU the program is running on */ diff --git a/libsrc/common/getcpu.s b/libsrc/common/getcpu.s index b7954f52f..1e60a5d39 100644 --- a/libsrc/common/getcpu.s +++ b/libsrc/common/getcpu.s @@ -12,6 +12,7 @@ ; - carry clear and 0 in A for a NMOS 6502 CPU ; - carry set and 1 in A for some CMOS 6502 CPU ; - carry set and 2 in A for a 65816 +; - carry set and 3 in A for a 4510 ; ; This function uses a $1A opcode which is a INA on the 816 and ignored ; (interpreted as a NOP) on a NMOS 6502. There are several CMOS versions @@ -22,16 +23,24 @@ _getcpu: lda #0 - inc a ; .byte $1A + inc a ; .byte $1A ; nop on nmos, inc on every cmos cmp #1 bcc @L9 -; This is at least a 65C02, check for a 65816 +; This is at least a 65C02, check for a 4510 + + .byte $42,$ea ; neg on 4510, nop #$ea on 65c02, wdm $ea on 65816 + cmp #1 + bne @L8 + +; check for 65816; after 4510, because $eb there is row (rotate word) xba ; .byte $eb, put $01 in B accu dec a ; .byte $3a, A=$00 if 65C02 xba ; .byte $eb, get $01 back if 65816 inc a ; .byte $1a, make $01/$02 + .byte $2c ; bit instruction to skip next command +@L8: lda #3 ; CPU_4510 constant @L9: ldx #0 ; Load high byte of word rts From a5772f7dc33b10a5551e49127277ae0012392261 Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Wed, 7 Sep 2016 19:49:21 +0200 Subject: [PATCH 0157/2161] added forgotten testcase for testing cpu based conditional assembling --- test/assembler/cpudetect.s | 66 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 test/assembler/cpudetect.s diff --git a/test/assembler/cpudetect.s b/test/assembler/cpudetect.s new file mode 100644 index 000000000..adad7c1dc --- /dev/null +++ b/test/assembler/cpudetect.s @@ -0,0 +1,66 @@ + +.macpack cpu + +; step 1: try to assemble an instruction that's exclusive to this set +; (when possible) + +.ifp02 + lda #$ea +.endif + +.ifpsc02 + jmp ($1234,x) +.endif + +.ifpc02 + rmb0 $12 +.endif + +.ifp816 + xba +.endif + +.ifp4510 + taz +.endif + + +; step 2: check for bitwise compatibility of instructions sets +; (made verbose for better reading with hexdump/hd(1)) + +.if (.cpu .bitand CPU_ISET_NONE) + .byte 0,"CPU_ISET_NONE" +.endif + +.if (.cpu .bitand CPU_ISET_6502) + .byte 0,"CPU_ISET_6502" +.endif + +.if (.cpu .bitand CPU_ISET_6502X) + .byte 0,"CPU_ISET_6502X" +.endif + +.if (.cpu .bitand CPU_ISET_65SC02) + .byte 0,"CPU_ISET_65SC02" +.endif + +.if (.cpu .bitand CPU_ISET_65C02) + .byte 0,"CPU_ISET_65C02" +.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 + From ef7e9db1165b6c46ddc3eb9c4f7caf0b4c0ead28 Mon Sep 17 00:00:00 2001 From: Alex Thissen <alexthissen@hotmail.com> Date: Sun, 11 Sep 2016 22:26:52 +0200 Subject: [PATCH 0158/2161] Changed __BLOCKSIZE__ to __BANK0BLOCKSIZE__. Added __BANK1BLOCKSIZE__ which defaults to 0. --- cfg/lynx-bll.cfg | 3 ++- cfg/lynx-coll.cfg | 3 ++- cfg/lynx-uploader.cfg | 3 ++- cfg/lynx.cfg | 5 +++-- libsrc/lynx/bootldr.s | 4 ++-- libsrc/lynx/defdir.s | 8 ++++---- libsrc/lynx/exehdr.s | 7 ++++--- 7 files changed, 19 insertions(+), 14 deletions(-) diff --git a/cfg/lynx-bll.cfg b/cfg/lynx-bll.cfg index a1687b423..fbf64e8e9 100644 --- a/cfg/lynx-bll.cfg +++ b/cfg/lynx-bll.cfg @@ -1,7 +1,8 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack __STARTOFDIRECTORY__: type = weak, value = $00CB; # start just after loader - __BLOCKSIZE__: type = weak, value = $0400; # cart block size + __BANK0BLOCKSIZE__: type = weak, value = 1024; # bank 0 cart block size + __BANK1BLOCKSIZE__: type = weak, value = 0; # bank 1 block size __BLLHDR__: type = import; } MEMORY { diff --git a/cfg/lynx-coll.cfg b/cfg/lynx-coll.cfg index 9467c3c92..2be172196 100644 --- a/cfg/lynx-coll.cfg +++ b/cfg/lynx-coll.cfg @@ -1,7 +1,8 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack __STARTOFDIRECTORY__: type = weak, value = $00CB; # start just after loader - __BLOCKSIZE__: type = weak, value = $0400; # cart block size + __BANK0BLOCKSIZE__: type = weak, value = 1024; # bank 0 cart block size + __BANK1BLOCKSIZE__: type = weak, value = 0; # bank 1 block size __EXEHDR__: type = import; __BOOTLDR__: type = import; __DEFDIR__: type = import; diff --git a/cfg/lynx-uploader.cfg b/cfg/lynx-uploader.cfg index c32e3583f..ba3c13dcf 100644 --- a/cfg/lynx-uploader.cfg +++ b/cfg/lynx-uploader.cfg @@ -1,7 +1,8 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack __STARTOFDIRECTORY__: type = weak, value = $00CB; # start just after loader - __BLOCKSIZE__: type = weak, value = $0400; # cart block size + __BANK0BLOCKSIZE__: type = weak, value = 1024; # bank 0 cart block size + __BANK1BLOCKSIZE__: type = weak, value = 0; # bank 1 block size __EXEHDR__: type = import; __BOOTLDR__: type = import; __DEFDIR__: type = import; diff --git a/cfg/lynx.cfg b/cfg/lynx.cfg index 5140b342f..adcf67a98 100644 --- a/cfg/lynx.cfg +++ b/cfg/lynx.cfg @@ -1,7 +1,8 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack __STARTOFDIRECTORY__: type = weak, value = $00CB; # start just after loader - __BLOCKSIZE__: type = weak, value = 1024; # cart block size + __BANK0BLOCKSIZE__: type = weak, value = 512; # bank 0 cart block size + __BANK1BLOCKSIZE__: type = weak, value = 0; # bank 1 block size __EXEHDR__: type = import; __BOOTLDR__: type = import; __DEFDIR__: type = import; @@ -42,4 +43,4 @@ FEATURES { count = __INTERRUPTOR_COUNT__, segment = RODATA, import = __CALLIRQ__; -} +} \ No newline at end of file diff --git a/libsrc/lynx/bootldr.s b/libsrc/lynx/bootldr.s index a62d6155c..64569e6ee 100644 --- a/libsrc/lynx/bootldr.s +++ b/libsrc/lynx/bootldr.s @@ -5,7 +5,7 @@ ; .include "lynx.inc" .include "extzp.inc" - .import __BLOCKSIZE__ + .import __BANK0BLOCKSIZE__ .export __BOOTLDR__: absolute = 1 @@ -167,7 +167,7 @@ seclynxblock: lda __iodat sta IODAT stz _FileBlockByte - lda #<($100-(>__BLOCKSIZE__)) + lda #<($100-(>__BANK0BLOCKSIZE__)) sta _FileBlockByte+1 ply plx diff --git a/libsrc/lynx/defdir.s b/libsrc/lynx/defdir.s index 2930edf4b..c0fe19f4d 100644 --- a/libsrc/lynx/defdir.s +++ b/libsrc/lynx/defdir.s @@ -8,7 +8,7 @@ .import __MAIN_START__ .import __CODE_SIZE__, __DATA_SIZE__, __RODATA_SIZE__ .import __STARTUP_SIZE__, __ONCE_SIZE__, __LOWCODE_SIZE__ - .import __BLOCKSIZE__ + .import __BANK0BLOCKSIZE__ .export __DEFDIR__: absolute = 1 @@ -18,12 +18,12 @@ __DIRECTORY_START__: off0 = __STARTOFDIRECTORY__ + (__DIRECTORY_END__ - __DIRECTORY_START__) -blocka = off0 / __BLOCKSIZE__ +blocka = off0 / __BANK0BLOCKSIZE__ ; Entry 0 - first executable -block0 = off0 / __BLOCKSIZE__ +block0 = off0 / __BANK0BLOCKSIZE__ len0 = __STARTUP_SIZE__ + __ONCE_SIZE__ + __CODE_SIZE__ + __DATA_SIZE__ + __RODATA_SIZE__ + __LOWCODE_SIZE__ .byte <block0 - .word off0 & (__BLOCKSIZE__ - 1) + .word off0 & (__BANK0BLOCKSIZE__ - 1) .byte $88 .word __MAIN_START__ .word len0 diff --git a/libsrc/lynx/exehdr.s b/libsrc/lynx/exehdr.s index 3be926bb3..d63c0524d 100644 --- a/libsrc/lynx/exehdr.s +++ b/libsrc/lynx/exehdr.s @@ -3,7 +3,8 @@ ; ; This header contains data for emulators like Handy and Mednafen ; - .import __BLOCKSIZE__ + .import __BANK0BLOCKSIZE__ + .import __BANK1BLOCKSIZE__ .export __EXEHDR__: absolute = 1 @@ -11,8 +12,8 @@ ; EXE header .segment "EXEHDR" .byte 'L','Y','N','X' ; magic - .word __BLOCKSIZE__ ; bank 0 page size - .word 0 ; bank 1 page size + .word __BANK0BLOCKSIZE__ ; bank 0 page size + .word __BANK1BLOCKSIZE__ ; bank 1 page size .word 1 ; version number .asciiz "Cart name " ; 32 bytes cart name .asciiz "Manufacturer " ; 16 bytes manufacturer From 0949b2e104395954ecc93efd39ffede205491669 Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Mon, 12 Sep 2016 18:38:10 +0200 Subject: [PATCH 0159/2161] added missing ',' in documentation. --- doc/ca65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index baabffa7c..3e1b11df3 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -3827,7 +3827,7 @@ Here's a list of all control commands and a description, what they do: <tt><ref id=".IFPSC02" name=".IFPSC02"></tt>, <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".P816" name=".P816"></tt>, - <tt><ref id=".P4510" name=".P4510"></tt> + <tt><ref id=".P4510" name=".P4510"></tt>, <tt><ref id=".PC02" name=".PC02"></tt>, <tt><ref id=".PSC02" name=".PSC02"></tt> From 6198e10f6779f08c97faf5ebef6c8bb8d0bd8b90 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Mon, 12 Sep 2016 23:34:10 +0200 Subject: [PATCH 0160/2161] Atari: fix lookup of default device on XDOS. Stefan Dorndorf, author of XDOS, pointed out that retrieving the default device by looking at an undocumented memory location won't work in future XDOS versions. He also showed a way to get the default device in a compatible manner. This change implements his method and adds a version check (XDOS versions below 2.4 don't support this -- for them the behaviour will be the same as, for example, AtariDOS: no notion of a default drive). --- asminc/atari.inc | 9 ++++++++- libsrc/atari/getdefdev.s | 24 ++++++++++++++++++++---- libsrc/atari/shadow_ram_handlers.s | 20 ++++++++++++++++++++ 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/asminc/atari.inc b/asminc/atari.inc index 453c370f4..1b995e380 100644 --- a/asminc/atari.inc +++ b/asminc/atari.inc @@ -1024,9 +1024,16 @@ XFILE = $087D ; XDOS filename buffer XLINE = $0880 ; XDOS DUP input line XGLIN = $0871 ; get line XSKIP = $0874 ; skip parameter +.ifdef __ATARIXL__ +.ifndef SHRAM_HANDLERS +.import XMOVE_handler +.endif +.define XMOVE XMOVE_handler +XMOVE_org = $0877 ; move filename +.else XMOVE = $0877 ; move filename +.endif XGNUM = $087A ; get number -XDEFDEV = $0816 ; current drive * undocumented * ;------------------------------------------------------------------------- ; End of atari.inc diff --git a/libsrc/atari/getdefdev.s b/libsrc/atari/getdefdev.s index a1c950dc5..480639b4a 100644 --- a/libsrc/atari/getdefdev.s +++ b/libsrc/atari/getdefdev.s @@ -77,16 +77,33 @@ finish: lda #<__defdev ldx #>__defdev rts -; XDOS version +; XDOS default device retrieval -xdos: lda XDEFDEV +xdos: + +; check XDOS version (we need >= 2.4) + + lda XGLIN + cmp #$4C ; there needs to be a 'JMP' opcode here + bne finish ; older version, use DEFAULT_DEVICE or D1: + lda XVER ; get BCD encoded version ($24 for 2.4) + cmp #$24 + bcc finish ; too old, below 2.4 + +; good XDOS version, get default drive + + lda #ATEOL + sta XLINE ; simulate empty command line + ldy #0 + jsr XMOVE ; create an FMS filename (which in this case only contains the drive) + lda XFILE+1 bne done .data crvec: jmp $FFFF ; target address will be set to crunch vector -; Default device +; Default device string __defdev: .ifdef DEFAULT_DEVICE @@ -94,4 +111,3 @@ __defdev: .else .byte "D1:", 0 .endif - diff --git a/libsrc/atari/shadow_ram_handlers.s b/libsrc/atari/shadow_ram_handlers.s index d65e6bd68..a8ba611b6 100644 --- a/libsrc/atari/shadow_ram_handlers.s +++ b/libsrc/atari/shadow_ram_handlers.s @@ -22,6 +22,7 @@ SHRAM_HANDLERS = 1 .export CIO_handler .export SIO_handler .export SETVBV_handler + .export XMOVE_handler BUFSZ = 128 ; bounce buffer size BUFSZ_SIO = 256 @@ -1085,6 +1086,24 @@ SETVBV_handler: plp rts +;--------------------------------------------------------- + +XMOVE_handler: + + pha + lda PORTB + sta cur_XMOVE_PORTB + enable_rom + pla + jsr XMOVE_org + php + pha + disable_rom_val cur_XMOVE_PORTB + pla + plp + rts + + CIO_a: .res 1 CIO_x: .res 1 CIO_y: .res 1 @@ -1093,6 +1112,7 @@ cur_CIOV_PORTB: .res 1 cur_SIOV_PORTB: .res 1 cur_KEYBDV_PORTB: .res 1 cur_SETVBV_PORTB: .res 1 +cur_XMOVE_PORTB: .res 1 orig_ptr: .res 2 orig_len: .res 2 req_len: .res 2 From aaa26c7d57c3f94ef02f6fa0fd2a596b40a111c2 Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Tue, 13 Sep 2016 11:21:25 +0200 Subject: [PATCH 0161/2161] Revert "test/assembler: removed WORKDIR variable, as remote assembling does only work partly" This reverts commit 7a9a7c3188bf36b278922439f957af7dab4617c2. --- test/assembler/Makefile | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/test/assembler/Makefile b/test/assembler/Makefile index a085bc390..faefddf7a 100644 --- a/test/assembler/Makefile +++ b/test/assembler/Makefile @@ -2,6 +2,8 @@ # makefile for the assembler regression tests BINDIR = ../../bin +#WORKDIR := ../../testwrk +WORKDIR := . BASE_TARGETS = 6502 6502x 65sc02 65c02 BASE_TARGETS += 4510 huc6280 @@ -17,9 +19,9 @@ all: # generate opcode targets and expand target list define opcode OPCODE_TARGETLIST += $(1)-opcodes.bin -$(1)-opcodes.bin: $(1)-opcodes.s - @$$(BINDIR)/cl65 --cpu $(1) -t none -l $(1)-opcodes.lst -o $$@ $$< - @diff -q $(1)-opcodes.ref $$@ || (cat $(1)-opcodes.lst ; exit 1) +$$(WORKDIR)/$(1)-opcodes.bin: $(1)-opcodes.s + @$$(BINDIR)/cl65 --cpu $(1) -t none -l $$(WORKDIR)/$(1)-opcodes.lst --obj-path $$(WORKDIR) -o $$@ $$< + @diff -q $(1)-opcodes.ref $$@ || (cat $$(WORKDIR)/$(1)-opcodes.lst ; exit 1) @echo ca65 --cpu $(1) opcodes ok endef $(foreach target,$(OPCODE_TARGETS),$(eval $(call opcode,$(target)))) @@ -27,9 +29,9 @@ $(foreach target,$(OPCODE_TARGETS),$(eval $(call opcode,$(target)))) # generate cpudetect targets and expand target list define cpudetect CPUDETECT_TARGETLIST += $(1)-cpudetect.bin -$(1)-cpudetect.bin: cpudetect.s - @$$(BINDIR)/cl65 --cpu $(1) -t none -l $(1)-cpudetect.lst -o $$@ $$< - @diff -q $(1)-cpudetect.ref $$@ || (cat $(1)-cpudetect.lst ; exit 1) +$$(WORKDIR)/$(1)-cpudetect.bin: cpudetect.s + @$$(BINDIR)/cl65 --cpu $(1) -t none -l $$(WORKDIR)/$(1)-cpudetect.lst --obj-path $$(WORKDIR) -o $$@ $$< + @diff -q $(1)-cpudetect.ref $$@ || (cat $$(WORKDIR)/$(1)-cpudetect.lst ; exit 1) @echo ca65 --cpu $(1) cpudetect ok endef $(foreach target,$(CPUDETECT_TARGETS),$(eval $(call cpudetect,$(target)))) From 95a2f4b9ddaec624dcc9c9e1b533992cdd2fd51f Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Tue, 13 Sep 2016 11:28:11 +0200 Subject: [PATCH 0162/2161] re-adding WORKDIR to Makefile - added workaround to remove *.o files after assembling - also removed now obsolete clean target --- test/assembler/Makefile | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/test/assembler/Makefile b/test/assembler/Makefile index faefddf7a..5d38847f5 100644 --- a/test/assembler/Makefile +++ b/test/assembler/Makefile @@ -2,8 +2,7 @@ # makefile for the assembler regression tests BINDIR = ../../bin -#WORKDIR := ../../testwrk -WORKDIR := . +WORKDIR := ../../testwrk BASE_TARGETS = 6502 6502x 65sc02 65c02 BASE_TARGETS += 4510 huc6280 @@ -18,21 +17,23 @@ all: # generate opcode targets and expand target list define opcode -OPCODE_TARGETLIST += $(1)-opcodes.bin +OPCODE_TARGETLIST += $$(WORKDIR)/$(1)-opcodes.bin $$(WORKDIR)/$(1)-opcodes.bin: $(1)-opcodes.s @$$(BINDIR)/cl65 --cpu $(1) -t none -l $$(WORKDIR)/$(1)-opcodes.lst --obj-path $$(WORKDIR) -o $$@ $$< @diff -q $(1)-opcodes.ref $$@ || (cat $$(WORKDIR)/$(1)-opcodes.lst ; exit 1) @echo ca65 --cpu $(1) opcodes ok + @rm -f $(1)-opcodes.o #workaround for #168 endef $(foreach target,$(OPCODE_TARGETS),$(eval $(call opcode,$(target)))) # generate cpudetect targets and expand target list define cpudetect -CPUDETECT_TARGETLIST += $(1)-cpudetect.bin +CPUDETECT_TARGETLIST += $$(WORKDIR)/$(1)-cpudetect.bin $$(WORKDIR)/$(1)-cpudetect.bin: cpudetect.s @$$(BINDIR)/cl65 --cpu $(1) -t none -l $$(WORKDIR)/$(1)-cpudetect.lst --obj-path $$(WORKDIR) -o $$@ $$< @diff -q $(1)-cpudetect.ref $$@ || (cat $$(WORKDIR)/$(1)-cpudetect.lst ; exit 1) @echo ca65 --cpu $(1) cpudetect ok + @rm -f cpudetect.o #workaround for #168 endef $(foreach target,$(CPUDETECT_TARGETS),$(eval $(call cpudetect,$(target)))) @@ -40,8 +41,5 @@ $(foreach target,$(CPUDETECT_TARGETS),$(eval $(call cpudetect,$(target)))) all: $(OPCODE_TARGETLIST) $(CPUDETECT_TARGETLIST) @# -clean: - rm -f *.o *.bin *.lst - -.PHONY: all clean $(OPCODE_TARGETLIST) $(CPUDETECT_TARGETLIST) +.PHONY: all $(OPCODE_TARGETLIST) $(CPUDETECT_TARGETLIST) From bcdd1900209c811b495403055280b54f4fbc3227 Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Tue, 13 Sep 2016 11:54:56 +0200 Subject: [PATCH 0163/2161] removed 'make clean' invoked from test/Makefile for test/assembler/Makefile, as all artifacts are now created in testwrk and will be cleaned up out of directory --- test/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/test/Makefile b/test/Makefile index 2fd252d2a..7f95e4379 100644 --- a/test/Makefile +++ b/test/Makefile @@ -47,7 +47,6 @@ continue: $(WORKDIR)/bdiff$(EXE) @$(MAKE) -C misc all mostlyclean: - @$(MAKE) -C assembler clean @$(MAKE) -C val clean @$(MAKE) -C ref clean @$(MAKE) -C err clean From 601c6102e8a073be3572e41fc5ca06db4151ede6 Mon Sep 17 00:00:00 2001 From: Alex Thissen <alexthissen@hotmail.com> Date: Tue, 13 Sep 2016 22:02:37 +0200 Subject: [PATCH 0164/2161] Fixed last linefeed and notation convention errors. --- cfg/lynx-bll.cfg | 4 ++-- cfg/lynx-coll.cfg | 4 ++-- cfg/lynx-uploader.cfg | 4 ++-- cfg/lynx.cfg | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/cfg/lynx-bll.cfg b/cfg/lynx-bll.cfg index fbf64e8e9..adf1e7ab6 100644 --- a/cfg/lynx-bll.cfg +++ b/cfg/lynx-bll.cfg @@ -1,8 +1,8 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack __STARTOFDIRECTORY__: type = weak, value = $00CB; # start just after loader - __BANK0BLOCKSIZE__: type = weak, value = 1024; # bank 0 cart block size - __BANK1BLOCKSIZE__: type = weak, value = 0; # bank 1 block size + __BANK0BLOCKSIZE__: type = weak, value = $0400; # bank 0 cart block size + __BANK1BLOCKSIZE__: type = weak, value = $0000; # bank 1 block size __BLLHDR__: type = import; } MEMORY { diff --git a/cfg/lynx-coll.cfg b/cfg/lynx-coll.cfg index 2be172196..7c71993f8 100644 --- a/cfg/lynx-coll.cfg +++ b/cfg/lynx-coll.cfg @@ -1,8 +1,8 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack __STARTOFDIRECTORY__: type = weak, value = $00CB; # start just after loader - __BANK0BLOCKSIZE__: type = weak, value = 1024; # bank 0 cart block size - __BANK1BLOCKSIZE__: type = weak, value = 0; # bank 1 block size + __BANK0BLOCKSIZE__: type = weak, value = $0400; # bank 0 cart block size + __BANK1BLOCKSIZE__: type = weak, value = $0000; # bank 1 block size __EXEHDR__: type = import; __BOOTLDR__: type = import; __DEFDIR__: type = import; diff --git a/cfg/lynx-uploader.cfg b/cfg/lynx-uploader.cfg index ba3c13dcf..476b3c5de 100644 --- a/cfg/lynx-uploader.cfg +++ b/cfg/lynx-uploader.cfg @@ -1,8 +1,8 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack __STARTOFDIRECTORY__: type = weak, value = $00CB; # start just after loader - __BANK0BLOCKSIZE__: type = weak, value = 1024; # bank 0 cart block size - __BANK1BLOCKSIZE__: type = weak, value = 0; # bank 1 block size + __BANK0BLOCKSIZE__: type = weak, value = $0400; # bank 0 cart block size + __BANK1BLOCKSIZE__: type = weak, value = $0000; # bank 1 block size __EXEHDR__: type = import; __BOOTLDR__: type = import; __DEFDIR__: type = import; diff --git a/cfg/lynx.cfg b/cfg/lynx.cfg index adcf67a98..5c42654d7 100644 --- a/cfg/lynx.cfg +++ b/cfg/lynx.cfg @@ -1,8 +1,8 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack __STARTOFDIRECTORY__: type = weak, value = $00CB; # start just after loader - __BANK0BLOCKSIZE__: type = weak, value = 512; # bank 0 cart block size - __BANK1BLOCKSIZE__: type = weak, value = 0; # bank 1 block size + __BANK0BLOCKSIZE__: type = weak, value = $0400; # bank 0 cart block size + __BANK1BLOCKSIZE__: type = weak, value = $0000; # bank 1 block size __EXEHDR__: type = import; __BOOTLDR__: type = import; __DEFDIR__: type = import; @@ -43,4 +43,4 @@ FEATURES { count = __INTERRUPTOR_COUNT__, segment = RODATA, import = __CALLIRQ__; -} \ No newline at end of file +} From d0ed84c2d0130fa7945cfca5ecb0ddbd77c3053f Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Tue, 20 Sep 2016 17:37:10 +0200 Subject: [PATCH 0165/2161] da65: adding support for 4510 cpu of c65 --- doc/da65.sgml | 9 +- src/da65/handler.c | 55 +++++- src/da65/handler.h | 4 + src/da65/opc4510.c | 306 ++++++++++++++++++++++++++++++++ src/da65/opc4510.h | 58 ++++++ src/da65/opctable.c | 2 + test/Makefile | 1 + test/disassembler/4510-disass.s | 298 +++++++++++++++++++++++++++++++ test/disassembler/Makefile | 41 +++++ 9 files changed, 772 insertions(+), 2 deletions(-) create mode 100644 src/da65/opc4510.c create mode 100644 src/da65/opc4510.h create mode 100644 test/disassembler/4510-disass.s create mode 100644 test/disassembler/Makefile diff --git a/doc/da65.sgml b/doc/da65.sgml index df8cd7772..6d962e9d6 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -114,10 +114,12 @@ Here is a description of all the command line options: <item>65sc02 <item>65c02 <item>huc6280 + <item>4510 </itemize> 6502x is for the NMOS 6502 with unofficial opcodes. huc6280 is the CPU of - the PC engine. Support for the 65816 currently is not available. + the PC engine. 4510 is the CPU of the Commodore C65. Support for the 65816 + currently is not available. <label id="option--formfeeds"> @@ -239,6 +241,11 @@ 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. +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 disassmbled memory. This can happen when text +or binary data is processed. + While there is some code for the 65816 in the sources, it is currently unsupported. diff --git a/src/da65/handler.c b/src/da65/handler.c index c034aed14..6ba8a7eef 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -227,6 +227,13 @@ void OH_Immediate (const OpcDesc* D) +void OH_ImmediateWord (const OpcDesc* D) +{ + OneLine (D, "#$%04X", GetCodeWord (PC+1)); +} + + + void OH_Direct (const OpcDesc* D) { /* Get the operand */ @@ -349,6 +356,23 @@ void OH_RelativeLong (const OpcDesc* D attribute ((unused))) +void OH_RelativeLong4510 (const OpcDesc* D attribute ((unused))) +{ + /* Get the operand */ + signed short Offs = GetCodeWord (PC+1); + + /* Calculate the target address */ + unsigned Addr = (((int) PC+2) + Offs) & 0xFFFF; + + /* Generate a label in pass 1 */ + GenerateLabel (D->Flags, Addr); + + /* Output the line */ + OneLine (D, "%s", GetAddrArg (D->Flags, Addr)); +} + + + void OH_DirectIndirect (const OpcDesc* D) { /* Get the operand */ @@ -377,6 +401,20 @@ void OH_DirectIndirectY (const OpcDesc* D) +void OH_DirectIndirectZ (const OpcDesc* D) +{ + /* Get the operand */ + unsigned Addr = GetCodeByte (PC+1); + + /* 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 */ @@ -508,9 +546,24 @@ void OH_DirectIndirectLongX (const OpcDesc* D attribute ((unused))) +static void impl_StackRelativeIndirectY (const char *sp, const OpcDesc* D attribute ((unused))) +{ + /* Output the line */ + OneLine (D, "($%02X,%s),y", GetCodeByte (PC+1), sp); +} + + + void OH_StackRelativeIndirectY (const OpcDesc* D attribute ((unused))) { - Error ("Not implemented"); + impl_StackRelativeIndirectY( "s", D ); +} + + + +void OH_StackRelativeIndirectY4510 (const OpcDesc* D attribute ((unused))) +{ + impl_StackRelativeIndirectY( "sp", D ); } diff --git a/src/da65/handler.h b/src/da65/handler.h index 433ba2594..c0fa68e56 100644 --- a/src/da65/handler.h +++ b/src/da65/handler.h @@ -57,6 +57,7 @@ void OH_Illegal (const OpcDesc* D attribute ((unused))); void OH_Accumulator (const OpcDesc*); void OH_Implicit (const OpcDesc*); void OH_Immediate (const OpcDesc*); +void OH_ImmediateWord (const OpcDesc*); void OH_Direct (const OpcDesc*); void OH_DirectX (const OpcDesc*); void OH_DirectY (const OpcDesc*); @@ -67,8 +68,10 @@ void OH_AbsoluteLong (const OpcDesc*); void OH_AbsoluteLongX (const OpcDesc*); void OH_Relative (const OpcDesc*); void OH_RelativeLong (const OpcDesc*); +void OH_RelativeLong4510 (const OpcDesc*); void OH_DirectIndirect (const OpcDesc*); void OH_DirectIndirectY (const OpcDesc*); +void OH_DirectIndirectZ (const OpcDesc*); void OH_DirectXIndirect (const OpcDesc*); void OH_AbsoluteIndirect (const OpcDesc*); @@ -82,6 +85,7 @@ void OH_ImmediateAbsoluteX (const OpcDesc*); void OH_StackRelative (const OpcDesc*); void OH_DirectIndirectLongX (const OpcDesc*); void OH_StackRelativeIndirectY (const OpcDesc*); +void OH_StackRelativeIndirectY4510 (const OpcDesc*); void OH_DirectIndirectLong (const OpcDesc*); void OH_DirectIndirectLongY (const OpcDesc*); void OH_BlockMove (const OpcDesc*); diff --git a/src/da65/opc4510.c b/src/da65/opc4510.c new file mode 100644 index 000000000..c663b7a59 --- /dev/null +++ b/src/da65/opc4510.c @@ -0,0 +1,306 @@ +/*****************************************************************************/ +/* */ +/* opc4510.c */ +/* */ +/* 4510 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 "opc4510.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Descriptions for all opcodes */ +const OpcDesc OpcTable_4510[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 */ + { "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, 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/opc4510.h b/src/da65/opc4510.h new file mode 100644 index 000000000..10735952c --- /dev/null +++ b/src/da65/opc4510.h @@ -0,0 +1,58 @@ +/*****************************************************************************/ +/* */ +/* opc4510.h */ +/* */ +/* 4510 opcode description table */ +/* */ +/* */ +/* */ +/* (C) 2003 Ullrich von Bassewitz */ +/* Römerstrasse 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 OPC4510_H +#define OPC4510_H + + + +#include "opcdesc.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Descriptions for all opcodes */ +extern const OpcDesc OpcTable_4510[256]; + + + +/* End of opc4510.h */ + +#endif diff --git a/src/da65/opctable.c b/src/da65/opctable.c index c85805faf..031b1239b 100644 --- a/src/da65/opctable.c +++ b/src/da65/opctable.c @@ -35,6 +35,7 @@ /* da65 */ #include "error.h" +#include "opc4510.h" #include "opc6502.h" #include "opc6502x.h" #include "opc65816.h" @@ -73,6 +74,7 @@ void SetOpcTable (cpu_t CPU) case CPU_65C02: OpcTable = OpcTable_65C02; break; case CPU_HUC6280: OpcTable = OpcTable_HuC6280; break; case CPU_M740: OpcTable = OpcTable_M740; break; + case CPU_4510: OpcTable = OpcTable_4510; break; default: Error ("Unsupported CPU"); } } diff --git a/test/Makefile b/test/Makefile index 7f95e4379..f0d63f689 100644 --- a/test/Makefile +++ b/test/Makefile @@ -41,6 +41,7 @@ dotests: mostlyclean continue continue: $(WORKDIR)/bdiff$(EXE) @$(MAKE) -C assembler all + @$(MAKE) -C disassembler all @$(MAKE) -C val all @$(MAKE) -C ref all @$(MAKE) -C err all diff --git a/test/disassembler/4510-disass.s b/test/disassembler/4510-disass.s new file mode 100644 index 000000000..96ed6419d --- /dev/null +++ b/test/disassembler/4510-disass.s @@ -0,0 +1,298 @@ +.setcpu "4510" + +ZP = $12 +ABS = $2345 + +start: + brk + ora (ZP,x) + cle + see + tsb ZP + ora ZP + asl ZP + rmb0 ZP + php + ora #$01 + asl + tsy + tsb ABS + ora ABS + asl ABS + bbr0 ZP,label1 + +label1: + bpl label2 + ora (ZP),y + ora (ZP),z + lbpl start ; bpl start + trb ZP + ora ZP,x + asl ZP,x + rmb1 ZP + clc + ora ABS,y + inc + inz + trb ABS + ora ABS,x + asl ABS,x + bbr1 ZP,label2 + +label2: + jsr ABS + and (ZP,x) + jsr ($2345) + jsr ($2456,x) + bit ZP + and ZP + rol ZP + rmb2 ZP + plp + and #$01 + rol + tys + bit ABS + and ABS + rol ABS + bbr2 ZP,label3 + +label3: + bmi label4 + and (ZP),y + and (ZP),z + lbmi start ; bmi start + bit ZP,x + and ZP,x + rol ZP,x + rmb3 ZP + sec + and ABS,y + dec + dez + bit ABS,x + and ABS,x + rol ABS,x + bbr3 ZP,label4 + +label4: + rti + eor (ZP,x) + neg + asr + asr ZP + eor ZP + lsr ZP + rmb4 ZP + pha + eor #$01 + lsr + taz + jmp ABS + eor ABS + lsr ABS + bbr4 ZP,label5 + +label5: + bvc label6 + eor (ZP),y + eor (ZP),z + lbvc start ; bvc start + asr ZP,x + eor ZP,x + lsr ZP,x + rmb5 ZP + cli + eor ABS,y + phy + tab + map + eor ABS,x + lsr ABS,x + bbr5 ZP,label6 + +label6: + rts + adc (ZP,x) + rtn #$09 + bsr start + stz ZP + adc ZP + ror ZP + rmb6 ZP + pla + adc #$01 + ror + tza + jmp ($2345) + adc ABS + ror ABS + bbr6 ZP,label7 + +label7: + bvs label8 + adc (ZP),y + adc (ZP),z + lbvs start ; bvs start + stz ZP,x + adc ZP,x + ror ZP,x + rmb7 ZP + sei + adc ABS,y + ply + tba + jmp ($2456,x) + adc ABS,x + ror ABS,x + bbr7 ZP,label8 + +label8: + bra label9 + sta (ZP,x) + sta ($0f,sp),y + lbra start ; bra start + sty ZP + sta ZP + stx ZP + smb0 ZP + dey + bit #$01 + txa + sty ABS,x + sty ABS + sta ABS + stx ABS + bbs0 ZP,label9 + +label9: + bcc labelA + sta (ZP),y + sta (ZP),z + lbcc start ; bcc start + sty ZP,x + sta ZP,x + stx ZP,y + smb1 ZP + tya + sta ABS,y + txs + stx ABS,y + stz ABS + sta ABS,x + stz ABS,x + bbs1 ZP,labelA + +labelA: + ldy #$01 + lda (ZP,x) + ldx #$01 + ldz #$01 + ldy ZP + lda ZP + ldx ZP + smb2 ZP + tay + lda #$01 + tax + ldz ABS + ldy ABS + lda ABS + ldx ABS + bbs2 ZP,labelB + +labelB: + bcs labelC + lda (ZP),y + lda (ZP),z + lbcs start ; bcs start + ldy ZP,x + lda ZP,x + ldx ZP,y + smb3 ZP + clv + lda ABS,y + tsx + ldz ABS,x + ldy ABS,x + lda ABS,x + ldx ABS,y + bbs3 ZP,labelC + +labelC: + cpy #$01 + cmp (ZP,x) + cpz #$01 + dew ZP + cpy ZP + cmp ZP + dec ZP + smb4 ZP + iny + cmp #$01 + dex + asw ABS + cpy ABS + cmp ABS + dec ABS + bbs4 ZP,labelD + +labelD: + bne labelE + cmp (ZP),y + cmp (ZP),z + lbne start ; bne start + cpz ZP + cmp ZP,x + dec ZP,x + smb5 ZP + cld + cmp ABS,y + phx + phz + cpz ABS + cmp ABS,x + dec ABS,x + bbs5 ZP,labelE + +labelE: + cpx #$01 + sbc (ZP,x) + lda ($0f,sp),y + inw ZP + cpx ZP + sbc ZP + inc ZP + smb6 ZP + inx + sbc #$01 + eom + nop + row ABS + cpx ABS + sbc ABS + inc ABS + bbs6 ZP,labelF + +labelF: + beq labelG + sbc (ZP),y + sbc (ZP),z + lbeq start ; beq start + phw #$089a + sbc ZP,x + inc ZP,x + smb7 ZP + sed + sbc ABS,y + plx + plz + phd ABS + phw ABS + sbc ABS,x + inc ABS,x + bbs7 ZP,labelG + +labelG: + brk + diff --git a/test/disassembler/Makefile b/test/disassembler/Makefile new file mode 100644 index 000000000..d60b82d19 --- /dev/null +++ b/test/disassembler/Makefile @@ -0,0 +1,41 @@ + +# makefile for the disassembler regression tests + +BINDIR = ../../bin +WORKDIR := ../../testwrk + +#BASE_TARGETS = 6502 6502x 65sc02 65c02 +#BASE_TARGETS += 4510 huc6280 +BASE_TARGETS = 4510 + +START = --start-addr 0x8000 + +DISASS_TARGETS = $(BASE_TARGETS) + +# default target defined later +all: + +# generate opcode targets and expand target list +define disass +DISASS_TARGETLIST += $$(WORKDIR)/$(1)-reass.bin $$(WORKDIR)/$(1)-reass.s $$(WORKDIR)/$(1)-disass.bin + +$$(WORKDIR)/$(1)-disass.bin: $(1)-disass.s + @$$(BINDIR)/cl65 --cpu $(1) -t none $(START) --obj-path $$(WORKDIR) -o $$@ $$< + @rm -f $(1)-disass.o #workaround for #168 + +$$(WORKDIR)/$(1)-reass.s: $$(WORKDIR)/$(1)-disass.bin + @$$(BINDIR)/da65 --cpu $(1) $(START) -o $$@ $$< + +$$(WORKDIR)/$(1)-reass.bin: $$(WORKDIR)/$(1)-reass.s + @$$(BINDIR)/cl65 --cpu $(1) -t none $(START) --obj-path $$(WORKDIR) -o $$@ $$< + @cmp $$@ $$(WORKDIR)/$(1)-disass.bin + @echo da65 --cpu $(1) ok +endef +$(foreach target,$(DISASS_TARGETS),$(eval $(call disass,$(target)))) + +# now that all targets have been generated, get to the manual ones +all: $(DISASS_TARGETLIST) + @# + +.PHONY: all $(DISASS_TARGETLIST) + From 86fc0240a9deef0a1a0d140807e9793762bf5f3f Mon Sep 17 00:00:00 2001 From: Jakob Haufe <sur5r@sur5r.net> Date: Fri, 23 Sep 2016 10:39:47 +0200 Subject: [PATCH 0166/2161] Add missing tag and remove duplicate text --- doc/ca65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 3e1b11df3..78be90d15 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -3552,7 +3552,7 @@ Here's a list of all control commands and a description, what they do: See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PSC02" name=".PSC02"></tt>, <tt><ref id=".P816" name=".P816"></tt> and - <ref id=".P4510" name=".P4510">4510</tt> + <tt><ref id=".P4510" name=".P4510"></tt> <sect1><tt>.POPCPU</tt><label id=".POPCPU"><p> From 2d76d0a657f886afcb60528a47be7781ddaff362 Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Fri, 23 Sep 2016 13:10:38 +0200 Subject: [PATCH 0167/2161] da65: 4510 support - cleaned up unnecessary static function - adjusted table formatting --- src/da65/handler.c | 14 +- src/da65/opc4510.c | 508 ++++++++++++++++++++++----------------------- 2 files changed, 258 insertions(+), 264 deletions(-) diff --git a/src/da65/handler.c b/src/da65/handler.c index 6ba8a7eef..624952363 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -546,24 +546,18 @@ void OH_DirectIndirectLongX (const OpcDesc* D attribute ((unused))) -static void impl_StackRelativeIndirectY (const char *sp, const OpcDesc* D attribute ((unused))) -{ - /* Output the line */ - OneLine (D, "($%02X,%s),y", GetCodeByte (PC+1), sp); -} - - - void OH_StackRelativeIndirectY (const OpcDesc* D attribute ((unused))) { - impl_StackRelativeIndirectY( "s", D ); + /* Output the line */ + OneLine (D, "($%02X,s),y", GetCodeByte (PC+1)); } void OH_StackRelativeIndirectY4510 (const OpcDesc* D attribute ((unused))) { - impl_StackRelativeIndirectY( "sp", D ); + /* Output the line */ + OneLine (D, "($%02X,sp),y", GetCodeByte (PC+1)); } diff --git a/src/da65/opc4510.c b/src/da65/opc4510.c index c663b7a59..0356499e8 100644 --- a/src/da65/opc4510.c +++ b/src/da65/opc4510.c @@ -47,260 +47,260 @@ /* Descriptions for all opcodes */ const OpcDesc OpcTable_4510[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 */ - { "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 */ + { "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 */ + { "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 */ + { "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 */ + { "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 */ }; From 476260a6fa79320a241d8f8a26923c5aaf3b1df5 Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Tue, 27 Sep 2016 12:02:57 +0200 Subject: [PATCH 0168/2161] 4510 support for da65: fixed docs and Makefile for testcase. --- doc/da65.sgml | 2 +- test/disassembler/Makefile | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/da65.sgml b/doc/da65.sgml index 6d962e9d6..a8e32e1c8 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -243,7 +243,7 @@ manipulation and bit test-and-branch commands. 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 disassmbled memory. This can happen when text +branches point outside of the disassembled memory. This can happen when text or binary data is processed. While there is some code for the 65816 in the sources, it is currently diff --git a/test/disassembler/Makefile b/test/disassembler/Makefile index d60b82d19..2621b0c20 100644 --- a/test/disassembler/Makefile +++ b/test/disassembler/Makefile @@ -28,6 +28,7 @@ $$(WORKDIR)/$(1)-reass.s: $$(WORKDIR)/$(1)-disass.bin $$(WORKDIR)/$(1)-reass.bin: $$(WORKDIR)/$(1)-reass.s @$$(BINDIR)/cl65 --cpu $(1) -t none $(START) --obj-path $$(WORKDIR) -o $$@ $$< + @rm -f $(1)-reass.o #workaround for #168 @cmp $$@ $$(WORKDIR)/$(1)-disass.bin @echo da65 --cpu $(1) ok endef From 23cfb51e7297963b70a3c89a8c2720c817c9bb5f Mon Sep 17 00:00:00 2001 From: greg-king5 <gregdk@users.sf.net> Date: Thu, 29 Sep 2016 20:00:09 -0400 Subject: [PATCH 0169/2161] Shorten a URL. --- doc/pce.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/pce.sgml b/doc/pce.sgml index ba59c31a7..104dee526 100644 --- a/doc/pce.sgml +++ b/doc/pce.sgml @@ -5,7 +5,7 @@ <title>PC-Engine (TurboGrafx) System specific information for cc65 <author> <url url="mailto:groepaz@gmx.net" name="Groepaz/Hitmen"> -<date>2015-07-14 +<date>2016-09-29 <abstract> An overview over the PCE runtime system as it is implemented for the @@ -179,7 +179,7 @@ some useful resources on PCE coding: <itemize> <item><url url="http://blog.blockos.org/?tag=pc-engine"> <item><url url="http://pcedev.blockos.org/viewforum.php?f=5"> -<item><url url="http://www.romhacking.net/?page=documents&category=&platform=4&:game=&author=&perpage=20&level=&title=&desc=&docsearch=Go"> +<item><url url="http://www.romhacking.net/?page=documents&platform=4"> <item><url url="http://archaicpixels.com/Main_Page"> <item><url url="http://www.magicengine.com/mkit/doc.html"> From dfbd96f09e742dd46d67e4c10c55ba58ccb2a6e9 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 15 Oct 2016 15:45:17 +0200 Subject: [PATCH 0170/2161] Make use of doesclrscrafterexit(). --- samples/plasma.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/samples/plasma.c b/samples/plasma.c index 7b092ec81..ac17265f3 100644 --- a/samples/plasma.c +++ b/samples/plasma.c @@ -12,6 +12,7 @@ #include <stdlib.h> #include <time.h> #include <conio.h> +#include <cc65.h> @@ -292,12 +293,11 @@ int main (void) gotoxy (0, 1); cprintf ("frames: %lu", f); gotoxy (0, 2); cprintf ("fps : %lu.%u", fps, fps10); - /* Wait for a key, then end */ - cputsxy (0, 4, "Press any key when done..."); - (void) cgetc (); + if (doesclrscrafterexit ()) { + cputsxy (0, 4, "Press any key when done..."); + (void) cgetc (); + } /* Done */ return EXIT_SUCCESS; } - - From 79e1b25c6c10f5a12b607d201bcddc3b1d98d999 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 16 Oct 2016 13:47:31 +0200 Subject: [PATCH 0171/2161] Removed DEL as suggested by Greg. --- test/Makefile | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/Makefile b/test/Makefile index f0d63f689..4817e70e0 100644 --- a/test/Makefile +++ b/test/Makefile @@ -11,12 +11,10 @@ endif ifdef CMD_EXE EXE := .exe - DEL = -del /f $(subst /,\,$1) MKDIR = mkdir $(subst /,\,$1) RMDIR = -rmdir /s /q $(subst /,\,$1) else EXE := - DEL = $(RM) $1 MKDIR = mkdir $1 RMDIR = $(RM) -r $1 endif @@ -54,5 +52,4 @@ mostlyclean: @$(MAKE) -C misc clean clean: mostlyclean - @$(call DEL,$(WORKDIR)/bdiff$(EXE)) @$(call RMDIR,$(WORKDIR)) From 6ee1fd2a677c4ee497b5c087b4356a7b783a9b75 Mon Sep 17 00:00:00 2001 From: Alan Cox <alan@linux.intel.com> Date: Sat, 19 Nov 2016 13:02:19 +0000 Subject: [PATCH 0172/2161] scanner: Correct handling of \0101 The C language has this oddity that octal constants are 3 bytes so the sequence "\0101" is two bytes and well defined by the langage. cc65 currently misparses this as a 1 byte octal code. Add a count to fix this. Signed-off-by: Alan Cox <etchedpixels@gmail.com> --- src/cc65/scanner.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 16d43e2ea..d867c9857 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -267,6 +267,7 @@ static int ParseChar (void) { int C; int HadError; + int Count; /* Check for escape chars */ if (CurC == '\\') { @@ -337,8 +338,9 @@ static int ParseChar (void) case '7': /* Octal constant */ HadError = 0; + Count = 1; C = HexVal (CurC); - while (IsODigit (NextC)) { + while (IsODigit (NextC) && Count++ < 3) { if ((C << 3) >= 256) { if (!HadError) { Error ("Octal character constant out of range"); From e4aee2ba340d32ab9042fc86070e0bd263a50ba1 Mon Sep 17 00:00:00 2001 From: Alan Cox <alan@linux.intel.com> Date: Sun, 20 Nov 2016 18:02:45 +0000 Subject: [PATCH 0173/2161] cc65: remove un-needed logic from octal parsing We no longer need the extra error handling logic for octal parsing so simplify it as requested by Greg King. Signed-off-by: Alan Cox <etchedpixels@gmail.com> --- src/cc65/scanner.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index d867c9857..c9009bc2f 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -337,20 +337,14 @@ static int ParseChar (void) case '6': case '7': /* Octal constant */ - HadError = 0; Count = 1; C = HexVal (CurC); while (IsODigit (NextC) && Count++ < 3) { - if ((C << 3) >= 256) { - if (!HadError) { - Error ("Octal character constant out of range"); - HadError = 1; - } - } else { - C = (C << 3) | HexVal (NextC); - } + C = (C << 3) | HexVal (NextC); NextChar (); } + if (C >= 256) + Error ("Octal character constant out of range"); break; default: Error ("Illegal character constant"); From 8a0841326348c95247de8f3c7d60a141957af63b Mon Sep 17 00:00:00 2001 From: Peter Ferrie <peter.ferrie@gmail.com> Date: Sat, 3 Dec 2016 20:54:14 -0800 Subject: [PATCH 0174/2161] fix build break on da65 --- src/da65.vcxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 7810844dc..2695edc08 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -86,6 +86,7 @@ <ClCompile Include="da65\infofile.c" /> <ClCompile Include="da65\labels.c" /> <ClCompile Include="da65\main.c" /> + <ClCompile Include="da65\opc4510.c" /> <ClCompile Include="da65\opc6502.c" /> <ClCompile Include="da65\opc6502x.c" /> <ClCompile Include="da65\opc65816.c" /> @@ -109,6 +110,7 @@ <ClInclude Include="da65\handler.h" /> <ClInclude Include="da65\infofile.h" /> <ClInclude Include="da65\labels.h" /> + <ClInclude Include="da65\opc4510.h" /> <ClInclude Include="da65\opc6502.h" /> <ClInclude Include="da65\opc6502x.h" /> <ClInclude Include="da65\opc65816.h" /> From 252e4afb9c75b8f4068bfe647ae5a96c5df8f2e3 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Wed, 14 Dec 2016 21:22:10 +0100 Subject: [PATCH 0175/2161] Adding files for telemon30 --- libsrc/Makefile | 4 +- libsrc/common/fread.s | 12 +- libsrc/telemon30/_open.s | 44 +++ libsrc/telemon30/_read.s | 31 ++ libsrc/telemon30/_scrsize.s | 19 ++ libsrc/telemon30/ch376.s | 200 +++++++++++ libsrc/telemon30/crt0.s | 101 ++++++ libsrc/telemon30/ctype.s | 299 +++++++++++++++++ libsrc/telemon30/graphics.s | 51 +++ libsrc/telemon30/keyboard.s | 13 + libsrc/telemon30/mainargs.s | 137 ++++++++ libsrc/telemon30/mym.s | 626 +++++++++++++++++++++++++++++++++++ libsrc/telemon30/orixhdr.s | 36 ++ libsrc/telemon30/oserrlist.s | 75 +++++ libsrc/telemon30/oserror.s | 17 + libsrc/telemon30/print.s | 21 ++ libsrc/telemon30/sound.s | 45 +++ libsrc/telemon30/sysuname.s | 46 +++ libsrc/telemon30/write.s | 61 ++++ src/ar65.vcxproj | 6 +- src/ca65.vcxproj | 6 +- src/ca65/main.c | 17 +- src/cc65.vcxproj | 6 +- src/cc65/main.c | 10 +- src/chrcvt65.vcxproj | 6 +- src/cl65.vcxproj | 6 +- src/co65.vcxproj | 6 +- src/common.vcxproj | 6 +- src/common/target.c | 8 +- src/common/target.h | 3 +- src/da65.vcxproj | 6 +- src/grc65.vcxproj | 6 +- src/ld65.vcxproj | 6 +- src/od65.vcxproj | 6 +- src/sim65.vcxproj | 6 +- src/sp65.vcxproj | 6 +- 36 files changed, 1899 insertions(+), 55 deletions(-) create mode 100644 libsrc/telemon30/_open.s create mode 100644 libsrc/telemon30/_read.s create mode 100644 libsrc/telemon30/_scrsize.s create mode 100644 libsrc/telemon30/ch376.s create mode 100644 libsrc/telemon30/crt0.s create mode 100644 libsrc/telemon30/ctype.s create mode 100644 libsrc/telemon30/graphics.s create mode 100644 libsrc/telemon30/keyboard.s create mode 100644 libsrc/telemon30/mainargs.s create mode 100644 libsrc/telemon30/mym.s create mode 100644 libsrc/telemon30/orixhdr.s create mode 100644 libsrc/telemon30/oserrlist.s create mode 100644 libsrc/telemon30/oserror.s create mode 100644 libsrc/telemon30/print.s create mode 100644 libsrc/telemon30/sound.s create mode 100644 libsrc/telemon30/sysuname.s create mode 100644 libsrc/telemon30/write.s diff --git a/libsrc/Makefile b/libsrc/Makefile index 99f120f3a..0342a8ca4 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -30,7 +30,9 @@ TARGETS = apple2 \ pce \ sim6502 \ sim65c02 \ - supervision + supervision\ + telemon24\ + telemon30 DRVTYPES = emd \ joy \ diff --git a/libsrc/common/fread.s b/libsrc/common/fread.s index 91d692985..b87cc5cb4 100644 --- a/libsrc/common/fread.s +++ b/libsrc/common/fread.s @@ -173,13 +173,16 @@ ; Read was ok, account for the pushed back character (if any). -@L8: add pb +@L8: + add pb bcc @L9 inx ; Check for end of file. -@L9: cmp #0 ; Zero bytes read? +@L9: + + cmp #0 ; Zero bytes read? bne @L10 cpx #0 bne @L10 @@ -192,7 +195,10 @@ ; Return the number of items successfully read. Since we've checked for ; bytes == 0 above, size cannot be zero here, so the division is safe. -@L10: jsr pushax ; Push number of bytes read +@L10: + + + jsr pushax ; Push number of bytes read ldy #5 jsr ldaxysp ; Get size jsr tosudivax ; bytes / size -> a/x diff --git a/libsrc/telemon30/_open.s b/libsrc/telemon30/_open.s new file mode 100644 index 000000000..f308632d9 --- /dev/null +++ b/libsrc/telemon30/_open.s @@ -0,0 +1,44 @@ + .export _open + .import addysp,popax + .importzp sp,tmp2,tmp3,tmp1 + ; int open (const char* name, int flags, ...); /* May take a mode argument */ + .include "telemon30.inc" + +.proc _open +; Throw away any additional parameters passed through the ellipsis + + dey ; Parm count < 4 shouldn't be needed to be... + dey ; ...checked (it generates a c compiler warning) + dey + dey + beq parmok ; Branch if parameter count ok + jsr addysp ; Fix stack, throw away unused parameters + +; Parameters ok. Pop the flags and save them into tmp3 + +parmok: jsr popax ; Get flags + +; Get the filename from stack and parse it. Bail out if is not ok + + jsr popax ; Get name + + + BRK_TELEMON XOPEN + + ; jsr fnparse ; Parse it + ;tax + ;bne oserror ; Bail out if problem with name + +; Get a free file handle and remember it in tmp2 + + ; jsr freefd + ;lda #EMFILE ; Load error code + ;bcs seterrno ; Jump in case of errors + ;stx tmp2 +; + + + rts +.endproc + + \ No newline at end of file diff --git a/libsrc/telemon30/_read.s b/libsrc/telemon30/_read.s new file mode 100644 index 000000000..8f7a20a58 --- /dev/null +++ b/libsrc/telemon30/_read.s @@ -0,0 +1,31 @@ +; +; Ullrich von Bassewitz, 2003-04-13 +; + +; + + .export _read + .import popax + .importzp ptr1, ptr2, ptr3, tmp1, tmp2 + + .include "telemon30.inc" +; int read (int fd, void* buf, unsigned count); + +.proc _read + ;jsr popax ; fp pointer don't care + sta tmp1 ; count + stx tmp2 ; count + jsr popax ; get buf + ;lda #$00 + ;ldx #$a0 + sta PTR_READ_DEST + stx PTR_READ_DEST+1 + lda tmp1 ; + ldy tmp2 ; + BRK_TELEMON XFREAD + + rts + +.endproc + + diff --git a/libsrc/telemon30/_scrsize.s b/libsrc/telemon30/_scrsize.s new file mode 100644 index 000000000..a929f97b1 --- /dev/null +++ b/libsrc/telemon30/_scrsize.s @@ -0,0 +1,19 @@ +; +; 2003-04-13, Ullrich von Bassewitz +; 2013-07-16, Greg King +; +; Screen size variables +; + + .export screensize + .include "telemon30.inc" + +.proc screensize + + ldx #SCREEN_XSIZE + ldy #SCREEN_YSIZE + rts + +.endproc + + diff --git a/libsrc/telemon30/ch376.s b/libsrc/telemon30/ch376.s new file mode 100644 index 000000000..1b75c2b18 --- /dev/null +++ b/libsrc/telemon30/ch376.s @@ -0,0 +1,200 @@ + .export _ch376_set_file_name + .export _ch376_file_open + .export _ch376_ic_get_version + .export _ch376_reset + .export _ch376_check_exist + .export _ch376_disk_mount + + .import popax + .importzp sp,tmp2,tmp3,tmp1 + .include "telemon30.inc" + +; CODE FOR CH376_SET_USB_MODE ************************************************* + +CH376_SET_USB_MODE_CODE_USB_HOST_SOF_PACKAGE_AUTOMATICALLY := $06 + +CH376_USB_INT_DISK_READ := $1d +CH376_USB_INT_SUCCESS := $14 +CH376_ERR_MISS_FILE := $42 + +CH376_DATA :=$340 +CH376_COMMAND :=$341 + +CH376_GET_IC_VER := $01 +CH376_SET_BAUDRATE := $02 +CH376_GET_ENTER_SLEEP := $03 +CH376_RESET_ALL := $05 +CH376_CHECK_EXIST := $06 +CH376_GET_FILE_SIZE := $0C +CH376_SET_USB_MODE := $15 +CH376_GET_STATUS := $22 +CH376_RD_USB_DATA0 := $27 +CH376_SET_FILE_NAME := $2f +CH376_DISK_CONNECT := $30 ; check the disk connection status +CH376_DISK_MOUNT := $31 +CH376_FILE_OPEN := $32 +CH376_FILE_ENUM_GO := $33 +CH376_FILE_CLOSE := $36 +CH376_BYTE_READ := $3A +CH376_BYTE_RD_GO := $3b +CH376_BYTE_WRITE := $3C +CH376_DISK_CAPACITY := $3E +CH376_DISK_RD_GO := $55 + + + +; void ch376_set_file_name(char *filename) +.proc _ch376_set_file_name + sta tmp1 + stx tmp1+1 + lda #CH376_SET_FILE_NAME ;$2f + sta CH376_COMMAND + ldy #0 +loop: + lda (tmp1),y ; replace by bufnom + beq end ; we reached 0 value + sta CH376_DATA + iny + cpy #13 ; because we don't manage longfilename shortname =11 + bne loop +end: + sta CH376_DATA + rts +.endproc + +; void _ch376_file_open(); + +.proc _ch376_file_open + lda #CH376_FILE_OPEN ; $32 + sta CH376_COMMAND + jsr _ch376_wait_response + rts +.endproc + + ;CMD_GET_FILE_SIZE + +.proc _ch376_get_file_size + lda #CH376_GET_FILE_SIZE + sta CH376_COMMAND + lda #$68 + sta CH376_DATA + ; store file leng + lda CH376_DATA + sta tmp1 + lda CH376_DATA + sta tmp1+1 + lda CH376_DATA + sta tmp2 + lda CH376_DATA + sta tmp2+1 + rts +.endproc + +; void ch376_reset(); + +.proc _ch376_reset + lda #CH376_RESET_ALL ; 5 + sta CH376_COMMAND + ; waiting + ldy #0 + ldx #0 +loop: + nop + inx + bne loop + iny + bne loop + rts +.endproc + +; char ch376_check_exist(char value); + +.proc _ch376_check_exist + sta tmp1 + lda #CH376_CHECK_EXIST ; + sta CH376_COMMAND + lda tmp1 + sta CH376_DATA + lda CH376_DATA + rts +.endproc + +; char ch376_ic_get_version(void) +.proc _ch376_ic_get_version + lda #CH376_GET_IC_VER + sta CH376_COMMAND + lda CH376_DATA + rts +.endproc + +; void ch376_set_usb_mode(char mode) + +.proc _ch376_set_usb_mode +; CH376_SET_USB_MODE_CODE_USB_HOST_SOF_PACKAGE_AUTOMATICALLY + sta tmp1 + lda #CH376_SET_USB_MODE ; $15 + sta CH376_COMMAND + lda tmp1 + sta CH376_DATA + rts +.endproc + + +; void ch376_set_bytes_write(int value); +.proc _ch376_set_bytes_write + sta tmp1 + stx tmp1+1 + ldx #CH376_BYTE_WRITE + stx CH376_COMMAND + lda tmp1 + sta CH376_DATA + lda tmp1+1 + sta CH376_DATA + jsr _ch376_wait_response + rts +.endproc + +.proc _ch376_set_bytes_read + ldx #CH376_BYTE_READ + stx CH376_COMMAND + sta CH376_DATA + sty CH376_DATA + jsr _ch376_wait_response + rts +.endproc + +; char ch376_disk_mount(); +.proc _ch376_disk_mount + lda #CH376_DISK_MOUNT ; $31 + sta CH376_COMMAND + jsr _ch376_wait_response + ; if we read data value, we have then length of the volume name + rts +.endproc + + +; char ch376_wait_response(); +.proc _ch376_wait_response +; 1 return 1 if usb controller does not respond +; else A contains answer of the controller + ldy #$ff +loop3: + ldx #$ff ; merci de laisser une valeur importante car parfois en mode non debug, le controleur ne répond pas tout de suite +loop: + lda CH376_COMMAND + and #%10000000 + cmp #128 + bne no_error + dex + bne loop + dey + bne loop3 + ; error is here + rts +no_error: + lda #CH376_GET_STATUS + sta CH376_COMMAND + lda CH376_DATA + rts +.endproc + diff --git a/libsrc/telemon30/crt0.s b/libsrc/telemon30/crt0.s new file mode 100644 index 000000000..72bad5f24 --- /dev/null +++ b/libsrc/telemon30/crt0.s @@ -0,0 +1,101 @@ +; +; Startup code for cc65 (Oric version) +; +; By Debrune Jérôme <jede@oric.org> and Ullrich von Bassewitz <uz@cc65.org> +; 2016-03-18, Greg King +; + + .export _exit + .export __STARTUP__ : absolute = 1 ; Mark as startup + + .import initlib, donelib + .import callmain, zerobss + .import __MAIN_START__, __MAIN_SIZE__ + + .include "zeropage.inc" + .include "telemon30.inc" + +; ------------------------------------------------------------------------ +; Place the startup code in a special segment. + +.segment "STARTUP" + + tsx + stx spsave ; Save system stk ptr + +; Save space by putting some of the start-up code in a segment +; that will be re-used. + + jsr init + +; Clear the BSS variables (after the constructors have been run). + + jsr zerobss + +; Push the command-line arguments; and, call main(). + + jsr callmain + +; Call the module destructors. This is also the exit() entry. + +_exit: jsr donelib + +; Restore the system stuff. + + ldx spsave + txs +; lda stsave + ; sta STATUS + +; Copy back the zero-page stuff. + + ldx #zpspace - 1 +L2: lda zpsave,x + sta sp,x + dex + bpl L2 + +; Back to BASIC. + + rts + +; ------------------------------------------------------------------------ +; Put this code in a place that will be re-used by BSS, the heap, +; and the C stack. + +.segment "ONCE" + +; Save the zero-page area that we're about to use. + +init: ldx #zpspace - 1 +L1: lda sp,x + sta zpsave,x + dex + bpl L1 + +; Currently, color isn't supported on the text screen. +; Unprotect screen columns 0 and 1 (where each line's color codes would sit). + + ; lda STATUS + ; sta stsave + ; and #%11011111 + ; sta STATUS + +; Set up the C stack. + + lda #<(__MAIN_START__ + __MAIN_SIZE__) + ldx #>(__MAIN_START__ + __MAIN_SIZE__) + sta sp + stx sp+1 ; Set argument stack ptr + +; Call the module constructors. + + jmp initlib + +; ------------------------------------------------------------------------ + +.segment "INIT" + +spsave: .res 1 +stsave: .res 1 +zpsave: .res zpspace diff --git a/libsrc/telemon30/ctype.s b/libsrc/telemon30/ctype.s new file mode 100644 index 000000000..79edafbb2 --- /dev/null +++ b/libsrc/telemon30/ctype.s @@ -0,0 +1,299 @@ +; +; Ullrich von Bassewitz, 2003-04-13 +; +; Character specification table. +; + +; The tables are readonly, put them into the rodata segment + +.rodata + +; The following 256 byte wide table specifies attributes for the isxxx type +; of functions. Doing it by a table means some overhead in space, but it +; has major advantages: +; +; * It is fast. If it were'nt for the slow parameter passing of cc65, one +; could even define macros for the isxxx functions (this is usually +; done on other platforms). +; +; * It is highly portable. The only unportable part is the table itself, +; all real code goes into the common library. +; +; * We save some code in the isxxx functions. +; +; +; Bit assignments: +; +; 0 - Lower case char +; 1 - Upper case char +; 2 - Numeric digit +; 3 - Hex digit (both, lower and upper) +; 4 - Control character +; 5 - The space character itself +; 6 - Other whitespace (that is: '\f', '\n', '\r', '\t' and '\v') +; 7 - Space or tab character + + .export __ctype + +__ctype: + .byte $10 ; 0/00 ___ctrl_@___ + .byte $10 ; 1/01 ___ctrl_A___ + .byte $10 ; 2/02 ___ctrl_B___ + .byte $10 ; 3/03 ___ctrl_C___ + .byte $10 ; 4/04 ___ctrl_D___ + .byte $10 ; 5/05 ___ctrl_E___ + .byte $10 ; 6/06 ___ctrl_F___ + .byte $10 ; 7/07 ___ctrl_G___ + .byte $10 ; 8/08 ___ctrl_H___ + .byte $D0 ; 9/09 ___ctrl_I___ + .byte $50 ; 10/0a ___ctrl_J___ + .byte $50 ; 11/0b ___ctrl_K___ + .byte $50 ; 12/0c ___ctrl_L___ + .byte $50 ; 13/0d ___ctrl_M___ + .byte $10 ; 14/0e ___ctrl_N___ + .byte $10 ; 15/0f ___ctrl_O___ + .byte $10 ; 16/10 ___ctrl_P___ + .byte $10 ; 17/11 ___ctrl_Q___ + .byte $10 ; 18/12 ___ctrl_R___ + .byte $10 ; 19/13 ___ctrl_S___ + .byte $10 ; 20/14 ___ctrl_T___ + .byte $10 ; 21/15 ___ctrl_U___ + .byte $10 ; 22/16 ___ctrl_V___ + .byte $10 ; 23/17 ___ctrl_W___ + .byte $10 ; 24/18 ___ctrl_X___ + .byte $10 ; 25/19 ___ctrl_Y___ + .byte $10 ; 26/1a ___ctrl_Z___ + .byte $10 ; 27/1b ___ctrl_[___ + .byte $10 ; 28/1c ___ctrl_\___ + .byte $10 ; 29/1d ___ctrl_]___ + .byte $10 ; 30/1e ___ctrl_^___ + .byte $10 ; 31/1f ___ctrl_____ + .byte $A0 ; 32/20 ___SPACE___ + .byte $00 ; 33/21 _____!_____ + .byte $00 ; 34/22 _____"_____ + .byte $00 ; 35/23 _____#_____ + .byte $00 ; 36/24 _____$_____ + .byte $00 ; 37/25 _____%_____ + .byte $00 ; 38/26 _____&_____ + .byte $00 ; 39/27 _____'_____ + .byte $00 ; 40/28 _____(_____ + .byte $00 ; 41/29 _____)_____ + .byte $00 ; 42/2a _____*_____ + .byte $00 ; 43/2b _____+_____ + .byte $00 ; 44/2c _____,_____ + .byte $00 ; 45/2d _____-_____ + .byte $00 ; 46/2e _____._____ + .byte $00 ; 47/2f _____/_____ + .byte $0C ; 48/30 _____0_____ + .byte $0C ; 49/31 _____1_____ + .byte $0C ; 50/32 _____2_____ + .byte $0C ; 51/33 _____3_____ + .byte $0C ; 52/34 _____4_____ + .byte $0C ; 53/35 _____5_____ + .byte $0C ; 54/36 _____6_____ + .byte $0C ; 55/37 _____7_____ + .byte $0C ; 56/38 _____8_____ + .byte $0C ; 57/39 _____9_____ + .byte $00 ; 58/3a _____:_____ + .byte $00 ; 59/3b _____;_____ + .byte $00 ; 60/3c _____<_____ + .byte $00 ; 61/3d _____=_____ + .byte $00 ; 62/3e _____>_____ + .byte $00 ; 63/3f _____?_____ + + .byte $00 ; 64/40 _____@_____ + .byte $0A ; 65/41 _____A_____ + .byte $0A ; 66/42 _____B_____ + .byte $0A ; 67/43 _____C_____ + .byte $0A ; 68/44 _____D_____ + .byte $0A ; 69/45 _____E_____ + .byte $0A ; 70/46 _____F_____ + .byte $02 ; 71/47 _____G_____ + .byte $02 ; 72/48 _____H_____ + .byte $02 ; 73/49 _____I_____ + .byte $02 ; 74/4a _____J_____ + .byte $02 ; 75/4b _____K_____ + .byte $02 ; 76/4c _____L_____ + .byte $02 ; 77/4d _____M_____ + .byte $02 ; 78/4e _____N_____ + .byte $02 ; 79/4f _____O_____ + .byte $02 ; 80/50 _____P_____ + .byte $02 ; 81/51 _____Q_____ + .byte $02 ; 82/52 _____R_____ + .byte $02 ; 83/53 _____S_____ + .byte $02 ; 84/54 _____T_____ + .byte $02 ; 85/55 _____U_____ + .byte $02 ; 86/56 _____V_____ + .byte $02 ; 87/57 _____W_____ + .byte $02 ; 88/58 _____X_____ + .byte $02 ; 89/59 _____Y_____ + .byte $02 ; 90/5a _____Z_____ + .byte $00 ; 91/5b _____[_____ + .byte $00 ; 92/5c _____\_____ + .byte $00 ; 93/5d _____]_____ + .byte $00 ; 94/5e _____^_____ + .byte $00 ; 95/5f _UNDERLINE_ + .byte $00 ; 96/60 ___grave___ + .byte $09 ; 97/61 _____a_____ + .byte $09 ; 98/62 _____b_____ + .byte $09 ; 99/63 _____c_____ + .byte $09 ; 100/64 _____d_____ + .byte $09 ; 101/65 _____e_____ + .byte $09 ; 102/66 _____f_____ + .byte $01 ; 103/67 _____g_____ + .byte $01 ; 104/68 _____h_____ + .byte $01 ; 105/69 _____i_____ + .byte $01 ; 106/6a _____j_____ + .byte $01 ; 107/6b _____k_____ + .byte $01 ; 108/6c _____l_____ + .byte $01 ; 109/6d _____m_____ + .byte $01 ; 110/6e _____n_____ + .byte $01 ; 111/6f _____o_____ + .byte $01 ; 112/70 _____p_____ + .byte $01 ; 113/71 _____q_____ + .byte $01 ; 114/72 _____r_____ + .byte $01 ; 115/73 _____s_____ + .byte $01 ; 116/74 _____t_____ + .byte $01 ; 117/75 _____u_____ + .byte $01 ; 118/76 _____v_____ + .byte $01 ; 119/77 _____w_____ + .byte $01 ; 120/78 _____x_____ + .byte $01 ; 121/79 _____y_____ + .byte $01 ; 122/7a _____z_____ + .byte $00 ; 123/7b _____{_____ + .byte $00 ; 124/7c _____|_____ + .byte $00 ; 125/7d _____}_____ + .byte $00 ; 126/7e _____~_____ + .byte $40 ; 127/7f ____DEL____ + + .byte $00 ; 128/80 ___________ + .byte $00 ; 129/81 ___________ + .byte $00 ; 130/82 ___________ + .byte $00 ; 131/83 ___________ + .byte $00 ; 132/84 ___________ + .byte $00 ; 133/85 ___________ + .byte $00 ; 134/86 ___________ + .byte $00 ; 135/87 ___________ + .byte $00 ; 136/88 ___________ + .byte $00 ; 137/89 ___________ + .byte $00 ; 138/8a ___________ + .byte $00 ; 139/8b ___________ + .byte $00 ; 140/8c ___________ + .byte $00 ; 141/8d ___________ + .byte $00 ; 142/8e ___________ + .byte $00 ; 143/8f ___________ + .byte $00 ; 144/90 ___________ + .byte $00 ; 145/91 ___________ + .byte $00 ; 146/92 ___________ + .byte $10 ; 147/93 ___________ + .byte $00 ; 148/94 ___________ + .byte $00 ; 149/95 ___________ + .byte $00 ; 150/96 ___________ + .byte $00 ; 151/97 ___________ + .byte $00 ; 152/98 ___________ + .byte $00 ; 153/99 ___________ + .byte $00 ; 154/9a ___________ + .byte $00 ; 155/9b ___________ + .byte $00 ; 156/9c ___________ + .byte $00 ; 157/9d ___________ + .byte $00 ; 158/9e ___________ + .byte $00 ; 159/9f ___________ + + .byte $00 ; 160/a0 ___________ + .byte $00 ; 161/a1 ___________ + .byte $00 ; 162/a2 ___________ + .byte $00 ; 163/a3 ___________ + .byte $00 ; 164/a4 ___________ + .byte $00 ; 165/a5 ___________ + .byte $00 ; 166/a6 ___________ + .byte $00 ; 167/a7 ___________ + .byte $00 ; 168/a8 ___________ + .byte $00 ; 169/a9 ___________ + .byte $00 ; 170/aa ___________ + .byte $00 ; 171/ab ___________ + .byte $00 ; 172/ac ___________ + .byte $00 ; 173/ad ___________ + .byte $00 ; 174/ae ___________ + .byte $00 ; 175/af ___________ + .byte $00 ; 176/b0 ___________ + .byte $00 ; 177/b1 ___________ + .byte $00 ; 178/b2 ___________ + .byte $00 ; 179/b3 ___________ + .byte $00 ; 180/b4 ___________ + .byte $00 ; 181/b5 ___________ + .byte $00 ; 182/b6 ___________ + .byte $00 ; 183/b7 ___________ + .byte $00 ; 184/b8 ___________ + .byte $00 ; 185/b9 ___________ + .byte $00 ; 186/ba ___________ + .byte $00 ; 187/bb ___________ + .byte $00 ; 188/bc ___________ + .byte $00 ; 189/bd ___________ + .byte $00 ; 190/be ___________ + .byte $00 ; 191/bf ___________ + + .byte $02 ; 192/c0 ___________ + .byte $02 ; 193/c1 ___________ + .byte $02 ; 194/c2 ___________ + .byte $02 ; 195/c3 ___________ + .byte $02 ; 196/c4 ___________ + .byte $02 ; 197/c5 ___________ + .byte $02 ; 198/c6 ___________ + .byte $02 ; 199/c7 ___________ + .byte $02 ; 200/c8 ___________ + .byte $02 ; 201/c9 ___________ + .byte $02 ; 202/ca ___________ + .byte $02 ; 203/cb ___________ + .byte $02 ; 204/cc ___________ + .byte $02 ; 205/cd ___________ + .byte $02 ; 206/ce ___________ + .byte $02 ; 207/cf ___________ + .byte $02 ; 208/d0 ___________ + .byte $02 ; 209/d1 ___________ + .byte $02 ; 210/d2 ___________ + .byte $02 ; 211/d3 ___________ + .byte $02 ; 212/d4 ___________ + .byte $02 ; 213/d5 ___________ + .byte $02 ; 214/d6 ___________ + .byte $02 ; 215/d7 ___________ + .byte $02 ; 216/d8 ___________ + .byte $02 ; 217/d9 ___________ + .byte $02 ; 218/da ___________ + .byte $02 ; 219/db ___________ + .byte $02 ; 220/dc ___________ + .byte $02 ; 221/dd ___________ + .byte $02 ; 222/de ___________ + .byte $00 ; 223/df ___________ + .byte $01 ; 224/e0 ___________ + .byte $01 ; 225/e1 ___________ + .byte $01 ; 226/e2 ___________ + .byte $01 ; 227/e3 ___________ + .byte $01 ; 228/e4 ___________ + .byte $01 ; 229/e5 ___________ + .byte $01 ; 230/e6 ___________ + .byte $01 ; 231/e7 ___________ + .byte $01 ; 232/e8 ___________ + .byte $01 ; 233/e9 ___________ + .byte $01 ; 234/ea ___________ + .byte $01 ; 235/eb ___________ + .byte $01 ; 236/ec ___________ + .byte $01 ; 237/ed ___________ + .byte $01 ; 238/ee ___________ + .byte $01 ; 239/ef ___________ + .byte $01 ; 240/f0 ___________ + .byte $01 ; 241/f1 ___________ + .byte $01 ; 242/f2 ___________ + .byte $01 ; 243/f3 ___________ + .byte $01 ; 244/f4 ___________ + .byte $01 ; 245/f5 ___________ + .byte $01 ; 246/f6 ___________ + .byte $01 ; 247/f7 ___________ + .byte $01 ; 248/f8 ___________ + .byte $01 ; 249/f9 ___________ + .byte $01 ; 250/fa ___________ + .byte $01 ; 251/fb ___________ + .byte $01 ; 252/fc ___________ + .byte $01 ; 253/fd ___________ + .byte $01 ; 254/fe ___________ + .byte $00 ; 255/ff ___________ + diff --git a/libsrc/telemon30/graphics.s b/libsrc/telemon30/graphics.s new file mode 100644 index 000000000..1d0beefa5 --- /dev/null +++ b/libsrc/telemon30/graphics.s @@ -0,0 +1,51 @@ + .export _paper,_hires,_text,_circle,_curset, _switchOffCursor + .importzp sp,tmp2,tmp3,tmp1 + + .include "telemon30.inc" + +.proc _paper + ldx #0 ; First window + ; A contains the paper + BRK_TELEMON XPAPER + rts +.endproc + +; XINK is bugged, it corrupt memory : removing from export +.proc _ink + ldx #0 ; First window + ; A contains the ink + BRK_TELEMON XINK + rts +.endproc + +; can be optimized with a macro +.proc _hires + BRK_TELEMON XHIRES + rts +.endproc + +.proc _text + BRK_TELEMON XTEXT + rts +.endproc + +.proc _curset + sta HRSX + sty HRSY + BRK_TELEMON XCURSE + rts +.endproc + +.proc _circle + sta HRS1 + BRK_TELEMON XCIRCL + rts +.endproc + +.proc _switchOffCursor + ldx #0 + BRK_TELEMON XCOSCR + rts +.endproc + + diff --git a/libsrc/telemon30/keyboard.s b/libsrc/telemon30/keyboard.s new file mode 100644 index 000000000..974f841e6 --- /dev/null +++ b/libsrc/telemon30/keyboard.s @@ -0,0 +1,13 @@ + .export _key + .importzp sp,tmp2,tmp3,tmp1 + + .include "telemon30.inc" + + +; char key(void); + +.proc _key + BRK_TELEMON XRDW0 ; read keyboard + rts +.endproc + diff --git a/libsrc/telemon30/mainargs.s b/libsrc/telemon30/mainargs.s new file mode 100644 index 000000000..452d0d6d6 --- /dev/null +++ b/libsrc/telemon30/mainargs.s @@ -0,0 +1,137 @@ +; +; 2003-03-07, Ullrich von Bassewitz +; 2011-01-28, Stefan Haubenthal +; 2014-09-10, Greg King +; +; Set up arguments for main +; + + .constructor initmainargs, 24 + .import __argc, __argv + .import ptr1 + .include "telemon30.inc" + .macpack generic + +MAXARGS = 10 ; Maximum number of arguments allowed + + + + + +; Assume that the program was loaded, a moment ago, by the traditional LOAD +; statement. Save the "most-recent filename" as argument #0. +initmainargs: + + ldx #0 ; Limit the length + ; lda #0 ; The terminating NUL character + ; beq L1 ; Branch always +L0: lda BUFEDT,x + beq L3 + cmp #' ' + bne L1 + lda #0 + beq L3 +L1: sta name,x + inx + cpx #FNAME_LEN + bne L0 + lda #0 +L3: + sta name,x + inc __argc ; argc always is equal to, at least, 1 + + + + + + ldy #1 * 2 ; Point to second argv slot + +next: lda BUFEDT,x + beq done ; End of line reached + inx + cmp #' ' ; Skip leading spaces + beq next + + + + + +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. + + txa ; Get low byte + clc + adc #<BUFEDT + bcc L4 + inc L5+1 +L4: + ;add #<args + sta argv,y ; argv[y]=&arg +L5: + lda #>BUFEDT + ;adc #>args + sta argv+1,y + iny + iny + inc __argc ; Found another arg + +; Search for the end of the argument + + + +argloop:lda BUFEDT,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 BUFEDT-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 + + + + +done: lda #<argv + ldx #>argv + sta __argv + stx __argv + 1 + rts + + + +.segment "INIT" + +term: .res 1 + + +.data + +name: .res FNAME_LEN + 1 +args: .res SCREEN_XSIZE * 2 - 1 + +ptr_current: + .res 2 +param_found: + .res 1 +; char* argv[MAXARGS+1]={name}; +argv: + .addr name + .res MAXARGS * 2 diff --git a/libsrc/telemon30/mym.s b/libsrc/telemon30/mym.s new file mode 100644 index 000000000..f387f9d64 --- /dev/null +++ b/libsrc/telemon30/mym.s @@ -0,0 +1,626 @@ + .export _Mym_MusicStart + .importzp sp,tmp2,tmp3,tmp1,ptr1 + + .include "telemon30.inc" + +; To check: AYC +; http://cpcwiki.eu/index.php/AYC + + + + +_DecodedByte :=$D0 ; Byte being currently decoded from the MYM stream +_DecodeBitCounter :=$D2 ; Number of bits we can read in the current byte +_DecodedResult :=$D3 ; What is returned by the 'read bits' function +_CurrentAYRegister :=$D4 ; Contains the number of the register being decoded +_RegisterBufferHigh :=$D5 ; Points to the high byte of the decoded register buffer, increment to move to the next register +_BufferFrameOffset :=$D6 ; From 0 to 127, used when filling the decoded register buffer +_MusicResetCounter :=$D7 ; 2 bytes Contains the number of rows to play before reseting +_CurrentFrame :=$D9 ; From 0 to 255 and then cycles... the index of the frame to play this vbl +_PlayerVbl :=$DA +_FrameLoadBalancer :=$DB ; We depack a new frame every 9 VBLs, this way the 14 registers are evenly depacked over 128 frames + + +VIA_1 := $30f +VIA_2 := $30c + +_MusicData := $c000 + +; mym(char *buf) + + + + +; +; Current PSG values during unpacking +; + + +.proc _Mym_MusicStart + + ; The two first bytes of the MYM music is the number of rows in the music + ; We decrement that at each frame, and when we reach zero, time to start again. + sta ptr1 + stx ptr1+1 + + ldy #0 + lda (ptr1),y + sta _MusicResetCounter+0 + iny + lda (ptr1),y + tax + inx + stx _MusicResetCounter+1 + + ;ldx _MusicData+0 + ;stx _MusicResetCounter+0 + ;ldx _MusicData+1 + ;inx + ;stx _MusicResetCounter+1 + + + ; Initialize the read bit counter + ldy #2 ; should be useless because we can do iny which earn 1 byte + + lda ptr1 + clc + adc #2 + bcc next20 + inc ptr1+1 + lda ptr1+1 + sta __auto_music_ptr+2 +next20: + sta ptr1 + sta __auto_music_ptr+1 + + + + ;lda #<(_MusicData+2) + ;sta __auto_music_ptr+1 + ;lda #>(_MusicData+2) + ;sta __auto_music_ptr+2 + + lda #1 + sta _DecodeBitCounter + + ; Clear all data + lda #0 + sta _DecodedResult + sta _DecodedByte + sta _PlayerVbl + sta _PlayerRegCurrentValue + sta _BufferFrameOffset + sta _PlayerCount + sta _CurrentAYRegister + sta _CurrentFrame + + ldx #14 +loop_init: + dex + sta _PlayerRegValues,x + bne loop_init + + + ; + ; Unpack the 128 first register frames + ; + + lda #>_PlayerBuffer + sta _RegisterBufferHigh + + ldx #0 +unpack_block_loop: + stx _CurrentAYRegister + + ; Unpack that register + jsr _PlayerUnpackRegister2 + + ; Next register + ldx _CurrentAYRegister + inx + cpx #14 + bne unpack_block_loop + + + lda #128 + sta _PlayerVbl+0 + + lda #0 + sta _PlayerCount + sta _CurrentAYRegister + sta _CurrentFrame + + lda #9 + sta _FrameLoadBalancer + + lda #1 + sta _MusicPlaying + + ; + ; Install the IRQ + ; + php + sei + lda #<_Mym_PlayFrame + sta _InterruptCallBack_3+1 + lda #>_Mym_PlayFrame + sta _InterruptCallBack_3+2 + plp + + rts + + +_Mym_MusicStop: + + ; Indicate the main code that the music is finished + lda #0 + sta _MusicPlaying + + ; Disable the IRQ so it does not conflict or cause weird things + php + sei + lda #<_DoNothing + sta _InterruptCallBack_3+1 + lda #>_DoNothing + sta _InterruptCallBack_3+2 + plp + + ; Cut the sound so it does not sounds like a dying cat + + ; y=register number + ; x=value to write + ldy #7 ; Control register + ldx #$FF + jsr _PsgPlayRegister + + ldy #8 ; Volume A + ldx #0 + jsr _PsgPlayRegister + + ldy #9 ; Volume B + ldx #0 + jsr _PsgPlayRegister + + ldy #10 ; Volume C + ldx #0 + jsr _PsgPlayRegister + rts + + +_Mym_PlayFrame: + + ; + ; Check for end of music + ; CountZero: $81,$0d + dec _MusicResetCounter+0 + bne music_contines + dec _MusicResetCounter+1 + bne music_contines + +music_resets: + jmp _Mym_MusicStop + +music_contines: + + ; + ; Play a frame of 14 registers + ; + + lda _CurrentFrame + sta _auto_psg_play_read+1 + lda #>_PlayerBuffer + sta _auto_psg_play_read+2 + + ldy #0 +register_loop: + +_auto_psg_play_read: + ldx _PlayerBuffer + + ; y=register number + ; x=value to write + jsr _PsgPlayRegister + + inc _auto_psg_play_read+2 + iny + cpy #14 + bne register_loop + + + + inc _CurrentFrame + inc _PlayerCount + + lda _CurrentAYRegister + cmp #14 + bcs end_reg + + + dec _FrameLoadBalancer + bne end + + jsr _PlayerUnpackRegister + inc _CurrentAYRegister + lda #9 + sta _FrameLoadBalancer +end: + rts + + +end_reg: + + lda _PlayerCount + cmp #128 + bcc skip2 + + lda #0 + sta _CurrentAYRegister + sta _PlayerCount + lda #9 + sta _FrameLoadBalancer + + clc + lda _PlayerVbl+0 + adc #128 + sta _PlayerVbl+0 +skip2: + + + rts + + + +; y=register number +; x=value to write +_PsgPlayRegister: + + sty VIA_1 + txa + + pha + lda VIA_2 + ora #$EE ; $EE 238 11101110 + sta VIA_2 + + and #$11 ; $11 17 00010001 + ora #$CC ; $CC 204 11001100 + sta VIA_2 + + tax + pla + sta VIA_1 + txa + ora #$EC ; $EC 236 11101100 + sta VIA_2 + + and #$11 ; $11 17 00010001 + ora #$CC ; $CC 204 11001100 + sta VIA_2 + + rts + + + + +; +; Initialise X with the number of bits to read +; Y is not modifier +; +_ReadBits: + + lda #0 + sta _DecodedResult + + ; Will iterate X times (number of bits to read) +loop_read_bits: + + dec _DecodeBitCounter + beq get_next_byte + +shift_bit: + asl _DecodedByte + rol _DecodedResult + + dex + bne loop_read_bits + rts + +get_next_byte: + ; reset mask + lda #8 + sta _DecodeBitCounter + + ; fetch a new byte, and increment the adress. +__auto_music_ptr: + lda _MusicData+2 + sta _DecodedByte + + inc __auto_music_ptr+1 + bne shift_bit + inc __auto_music_ptr+2 + jmp shift_bit + + + + + +_PlayerUnpackRegister: + lda #>_PlayerBuffer + clc + adc _CurrentAYRegister + sta _RegisterBufferHigh +_PlayerUnpackRegister2: + ; + ; Init register bit count and current value + ; + ldx _CurrentAYRegister + lda _PlayerRegValues,x + sta _PlayerRegCurrentValue + + + ; + ; Check if it's packed or not + ; and call adequate routine... + ; + ldx #1 + jsr _ReadBits + ldx _DecodedResult + bne DecompressFragment + + +UnchangedFragment: + + ; + ; No change at all, just repeat '_PlayerRegCurrentValue' 128 times + ; + lda _RegisterBufferHigh ; highpart of buffer adress + register number + sta __auto_copy_unchanged_write+2 + + ldx #128 ; 128 iterations + lda _PlayerRegCurrentValue ; Value to write + + ldy _PlayerVbl + +repeat_loop: +__auto_copy_unchanged_write: + sta _PlayerBuffer,y + iny + dex + bne repeat_loop + + + jmp player_main_return + + +player_main_return: + ; Write back register current value + ldx _CurrentAYRegister + lda _PlayerRegCurrentValue + sta _PlayerRegValues,x + + ; Move to the next register buffer + inc _RegisterBufferHigh + rts + + + + +DecompressFragment: + lda _PlayerVbl ; Either 0 or 128 at this point else we have a problem... + sta _BufferFrameOffset + +decompressFragmentLoop: + +player_copy_packed_loop: + ; Check packing method + ldx #1 + jsr _ReadBits + + ldx _DecodedResult + bne PlayerNotCopyLast + +UnchangedRegister: + + ; We just copy the current value 128 times + lda _RegisterBufferHigh ; highpart of buffer adress + register number + sta __auto_player_copy_last+2 + + ldx _BufferFrameOffset ; Value between 00 and 7f + lda _PlayerRegCurrentValue ; Value to copy +__auto_player_copy_last: + sta _PlayerBuffer,x + + inc _BufferFrameOffset + + + +player_return: + + ; Check end of loop + lda _BufferFrameOffset + and #127 + bne decompressFragmentLoop + + jmp player_main_return + + +PlayerNotCopyLast: + ; Check packing method + ldx #1 + jsr _ReadBits + + ldx _DecodedResult + beq DecompressWithOffset + +ReadNewRegisterValue: + ; Read new register value (variable bit count) + ldx _CurrentAYRegister + lda _PlayerRegBits,x + tax + jsr _ReadBits + ldx _DecodedResult + stx _PlayerRegCurrentValue + + ; Copy to stream + lda _RegisterBufferHigh ; highpart of buffer adress + register number + sta __auto_player_read_new+2 + + ldx _BufferFrameOffset ; Value between 00 and 7f + lda _PlayerRegCurrentValue ; New value to write +__auto_player_read_new: + sta _PlayerBuffer,x + + inc _BufferFrameOffset + jmp player_return + + + + +DecompressWithOffset: + + ; Read Offset (0 to 127) + ldx #7 + jsr _ReadBits + + lda _RegisterBufferHigh ; highpart of buffer adress + register number + sta __auto_write+2 ; Write adress + sta __auto_read+2 ; Read adress + + ; Compute wrap around offset... + lda _BufferFrameOffset ; between 0 and 255 + clc + adc _DecodedResult ; + Offset Between 00 and 7f + sec + sbc #128 ; -128 + tay + + ; Read count (7 bits) + ldx #7 + jsr _ReadBits + + inc _DecodedResult ; 1 to 129 + + + ldx _BufferFrameOffset + +player_copy_offset_loop: + +__auto_read: + lda _PlayerBuffer,y ; Y for reading + iny + +__auto_write: + sta _PlayerBuffer,x ; X for writing + + inx + dec _DecodedResult + bne player_copy_offset_loop + + stx _BufferFrameOffset + sta _PlayerRegCurrentValue + + jmp player_return + + + + +; +; Size in bits of each PSG register +; +_PlayerRegBits: + ; Chanel A Frequency + .byt 8 + .byt 4 + + ; Chanel B Frequency + .byt 8 + .byt 4 + + ; Chanel C Frequency + .byt 8 + .byt 4 + + ; Chanel sound generator + .byt 5 + + ; select + .byt 8 + + ; Volume A,B,C + .byt 5 + .byt 5 + .byt 5 + + ; Wave period + .byt 8 + .byt 8 + + ; Wave form + .byt 8 + +_PlayerCount: + .res 1,0 ; must be equal to 0 +_MusicPlaying: + .res 1,0 ; must be equal to 0 + + +_PlayerRegValues: +_RegisterChanAFrequency: + ; Chanel A Frequency + .res 1,8 + .res 1,4 + +_RegisterChanBFrequency: + ; Chanel B Frequency + .res 1,8 + .res 1,4 + +_RegisterChanCFrequency: + ; Chanel C Frequency + .res 1,8 + .res 1,4 + +_RegisterChanNoiseFrequency: + ; Chanel sound generator + .res 1,5 + + ; select + .res 1,8 + + ; Volume A,B,C +_RegisterChanAVolume: + .res 1,5 +_RegisterChanBVolume: + .res 1,5 +_RegisterChanCVolume: + .res 1,5 + + ; Wave period + .res 1,8 + .res 1,8 + + ; Wave form + .res 1,8 + +_PlayerRegCurrentValue: + .res 1,0 +_DoNothing: + rts + +_InterruptCallBack_3: ; Used by the music player + jsr _DoNothing ; Transformed to "jsr _Mym_PlayFrame" -> 12 cycles + +; jsr MiniScrollLoading ; -> 338 cycles + + pla + tay + pla + tax + pla + + rti +_PlayerBuffer: + .res 256*14 ; About 3.5 kilobytes somewhere in memory, we put the music file in overlay memory + +.endproc + diff --git a/libsrc/telemon30/orixhdr.s b/libsrc/telemon30/orixhdr.s new file mode 100644 index 000000000..8744e86b0 --- /dev/null +++ b/libsrc/telemon30/orixhdr.s @@ -0,0 +1,36 @@ +; +; Based on code by Debrune Jérôme <jede@oric.org> +; 2016-03-17, Greg King +; + + ; The following symbol is used by the linker config. file + ; to force this module to be included into the output file. + .export __ORIXHDR__:abs = 1 + + ; These symbols, also, come from the configuration file. + .import __AUTORUN__, __PROGFLAG__ + .import __BASHEAD_START__, __MAIN_LAST__ + + +; ------------------------------------------------------------------------ +; Oric cassette-tape header + +.segment "ORIXHDR" + + .byte $01, $00 ; + + .byte "ORI" + + .byte $01 ; version + .byte $00,$00 ; mode + .byte $00,$00 ; cpu type + .byte $00,$00 ; OS + + .byte $00 ; reserved + .byte $00 ; auto + + + .word __BASHEAD_START__ ; Address of start of file + .word __MAIN_LAST__ - 1 ; Address of end of file + .word __BASHEAD_START__ ; Address of start of file + diff --git a/libsrc/telemon30/oserrlist.s b/libsrc/telemon30/oserrlist.s new file mode 100644 index 000000000..8ec41de6d --- /dev/null +++ b/libsrc/telemon30/oserrlist.s @@ -0,0 +1,75 @@ +; +; Stefan Haubenthal, 2004-05-25 +; Ullrich von Bassewitz, 18.07.2002 +; +; Defines the platform specific error list. +; +; The table is built as a list of entries +; +; .byte entrylen +; .byte errorcode +; .asciiz errormsg +; +; and terminated by an entry with length zero that is returned if the +; error code could not be found. +; + + .export __sys_oserrlist + +;---------------------------------------------------------------------------- +; Macros used to generate the list (may get moved to an include file?) + +; Regular entry +.macro sys_oserr_entry code, msg + .local Start, End +Start: .byte End - Start + .byte code + .asciiz msg +End: +.endmacro + +; Sentinel entry +.macro sys_oserr_sentinel msg + .byte 0 ; Length is always zero + .byte 0 ; Code is unused + .asciiz msg +.endmacro + +;---------------------------------------------------------------------------- +; The error message table + +.rodata + +__sys_oserrlist: + sys_oserr_entry 1, "File not found" + sys_oserr_entry 2, "Invalid command end" + sys_oserr_entry 3, "No drive number" + sys_oserr_entry 4, "Bad drive number" + sys_oserr_entry 5, "Invalid filename" + sys_oserr_entry 6, "fderr=(error number)" + sys_oserr_entry 7, "Illegal attribute" + sys_oserr_entry 8, "Wildcard(s) not allowed" + sys_oserr_entry 9, "File already exists" + sys_oserr_entry 10, "Insufficient disc space" + sys_oserr_entry 11, "File open" + sys_oserr_entry 12, "Illegal quantity" + sys_oserr_entry 13, "End address missing" + sys_oserr_entry 14, "Start address > end address" + sys_oserr_entry 15, "Missing 'to'" + sys_oserr_entry 16, "Renamed file not on same disc" + sys_oserr_entry 17, "Unknown array" + sys_oserr_entry 18, "Target drive not source drive" + sys_oserr_entry 19, "Destination not specified" + sys_oserr_entry 20, "Cannot merge and overwrite" + sys_oserr_entry 21, "Single target file illegal" + sys_oserr_entry 22, "Syntax" + sys_oserr_entry 23, "Filename missing" + sys_oserr_entry 24, "Source file missing" + sys_oserr_entry 25, "Type mismatch" + sys_oserr_entry 26, "Disc write-protected" + sys_oserr_entry 27, "Incompatible drives" + sys_oserr_entry 28, "File not open" + sys_oserr_entry 29, "File end" + sys_oserr_sentinel "Unknown error" + + diff --git a/libsrc/telemon30/oserror.s b/libsrc/telemon30/oserror.s new file mode 100644 index 000000000..37c9bd7fc --- /dev/null +++ b/libsrc/telemon30/oserror.s @@ -0,0 +1,17 @@ +; +; Stefan Haubenthal, 2011-04-18 +; +; int __fastcall__ _osmaperrno (unsigned char oserror); +; /* Map a system specific error into a system independent code */ +; + + .include "errno.inc" + .export __osmaperrno + +.proc __osmaperrno + + lda #<EUNKNOWN + ldx #>EUNKNOWN + rts + +.endproc diff --git a/libsrc/telemon30/print.s b/libsrc/telemon30/print.s new file mode 100644 index 000000000..56c513fd6 --- /dev/null +++ b/libsrc/telemon30/print.s @@ -0,0 +1,21 @@ +; +; Jede +; +; print (char * str); +; +; This function is a hack! +; + + .export _print + .import popax + .importzp tmp1 + .include "telemon30.inc" + +.proc _print + stx tmp1 + ldy tmp1 + BRK_TELEMON XWSTR0 + rts +.endproc + + diff --git a/libsrc/telemon30/sound.s b/libsrc/telemon30/sound.s new file mode 100644 index 000000000..2df18f4a0 --- /dev/null +++ b/libsrc/telemon30/sound.s @@ -0,0 +1,45 @@ + .export _kbdclick1,_oups,_ping,_explode,_shoot,_zap + .include "telemon30.inc" + +.proc _kbdclick1 + LDX #<sound_bip_keyboard + LDY #>sound_bip_keyboard + BRK_TELEMON XSONPS + rts +sound_bip_keyboard: + .byte $1f,$00,$00,$00,$00,$00,$00,$3e,$10,$00,$00,$1f,$00,$00 +.endproc + +.proc _explode + BRK_TELEMON XEXPLO + rts +.endproc + +.proc _oups + BRK_TELEMON XOUPS + rts +.endproc + +.proc _ping + BRK_TELEMON XPING + rts +.endproc + +.proc _shoot + BRK_TELEMON XSHOOT + rts +.endproc + +.proc _zap + BRK_TELEMON XZAP + rts +.endproc + + + +; XPLAY := $43 +; XSOUND := $44 +; XMUSIC := $45 + + + diff --git a/libsrc/telemon30/sysuname.s b/libsrc/telemon30/sysuname.s new file mode 100644 index 000000000..51af1d8fe --- /dev/null +++ b/libsrc/telemon30/sysuname.s @@ -0,0 +1,46 @@ +; +; 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 ((.VERSION >> 8) & $0F) + '0' + .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 $00 + + ; version + .if (.VERSION & $0F) > 9 + .byte (.VERSION & $0F) / 10 + '0' + .byte (.VERSION & $0F) .MOD 10 + '0' + .else + .byte (.VERSION & $0F) + '0' + .endif + .byte $00 + + ; machine + .asciiz "Oric Telestrat" diff --git a/libsrc/telemon30/write.s b/libsrc/telemon30/write.s new file mode 100644 index 000000000..32965fe3d --- /dev/null +++ b/libsrc/telemon30/write.s @@ -0,0 +1,61 @@ +; +; Ullrich von Bassewitz, 2003-04-13 +; +; int write (int fd, const void* buf, int count); +; +; This function is a hack! +; + + .export _write + .import popax + .importzp ptr1, ptr2, ptr3, tmp1 + + .include "telemon30.inc" + +.proc _write + + sta ptr3 + stx ptr3+1 ; save count as result + + eor #$FF + sta ptr2 + txa + eor #$FF + sta ptr2+1 ; Remember -count-1 + + jsr popax ; get buf + sta ptr1 + stx ptr1+1 + jsr popax ; get fd and discard +L1: inc ptr2 + bne L2 + inc ptr2+1 + beq L9 +L2: ldy #0 + lda (ptr1),y + tax + cpx #$0A ; Check for \n + bne L3 + BRK_TELEMON XWR0 ; Macro + lda #$0d ; return to the beggining of the line + BRK_TELEMON XWR0 ; Macro ; + + + ldx #$0D +L3: + BRK_TELEMON XWR0 ; Macro + + inc ptr1 + bne L1 + inc ptr1+1 + jmp L1 + +; No error, return count + +L9: lda ptr3 + ldx ptr3+1 + rts + +.endproc + + diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index b077134ce..003a5fa69 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index 4e02fa2a9..fb7cf2e26 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/ca65/main.c b/src/ca65/main.c index d6c364e4b..4aa60f2f0 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -226,10 +226,6 @@ static void SetSys (const char* Sys) CBMSystem ("__C64__"); break; - case TGT_C65: - CBMSystem ("__C65__"); - break; - case TGT_VIC20: CBMSystem ("__VIC20__"); break; @@ -289,7 +285,15 @@ static void SetSys (const char* Sys) case TGT_ATMOS: NewSymbol ("__ATMOS__", 1); - break; + break; + + case TGT_TELEMON24: + NewSymbol ("__TELEMON24__", 1); + break; + + case TGT_TELEMON30: + NewSymbol ("__TELEMON30__", 1); + break; case TGT_NES: NewSymbol ("__NES__", 1); @@ -623,8 +627,7 @@ static void OptVersion (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Print the assembler version */ { - fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); - exit(EXIT_SUCCESS); + fprintf (stderr, "ca65 V%s\n", GetVersionAsString ()); } diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 1c1f993fe..aa85b0936 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/cc65/main.c b/src/cc65/main.c index afbec43d7..f25a44d69 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -243,6 +243,14 @@ static void SetSys (const char* Sys) DefineNumericMacro ("__ATMOS__", 1); break; + case TGT_TELEMON24: + DefineNumericMacro ("__TELEMON24__", 1); + break; + + case TGT_TELEMON30: + DefineNumericMacro ("__TELEMON30__", 1); + break; + case TGT_NES: DefineNumericMacro ("__NES__", 1); break; @@ -742,7 +750,7 @@ static void OptVersion (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Print the compiler version */ { - fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); + fprintf (stderr, "cc65 V%s\n", GetVersionAsString ()); exit (EXIT_SUCCESS); } diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 1daf7cae9..d120399d1 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index 64c1126b1..b6ceb161a 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/co65.vcxproj b/src/co65.vcxproj index c66c8aac8..89eed36e1 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/common.vcxproj b/src/common.vcxproj index 053d23981..c466d9712 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -113,13 +113,13 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> <ConfigurationType>StaticLibrary</ConfigurationType> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/common/target.c b/src/common/target.c index 99a134c43..adbc080bf 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -147,12 +147,11 @@ static const TargetEntry TargetMap[] = { { "atari", TGT_ATARI }, { "atari5200", TGT_ATARI5200 }, { "atarixl", TGT_ATARIXL }, - { "atmos", TGT_ATMOS }, + { "atmos", TGT_ATMOS }, { "bbc", TGT_BBC }, { "c128", TGT_C128 }, { "c16", TGT_C16 }, { "c64", TGT_C64 }, - { "c65", TGT_C65 }, { "cbm510", TGT_CBM510 }, { "cbm610", TGT_CBM610 }, { "gamate", TGT_GAMATE }, @@ -171,6 +170,8 @@ static const TargetEntry TargetMap[] = { { "sim6502", TGT_SIM6502 }, { "sim65c02", TGT_SIM65C02 }, { "supervision", TGT_SUPERVISION }, + { "telemon24", TGT_TELEMON24 }, + { "telemon30", TGT_TELEMON30 }, { "vic20", TGT_VIC20 }, }; #define MAP_ENTRY_COUNT (sizeof (TargetMap) / sizeof (TargetMap[0])) @@ -199,6 +200,8 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "geos-apple", CPU_65C02, BINFMT_BINARY, CTNone }, { "lunix", CPU_6502, BINFMT_O65, CTNone }, { "atmos", CPU_6502, BINFMT_BINARY, CTNone }, + { "telemon24", CPU_6502, BINFMT_BINARY, CTNone }, + { "telemon30", CPU_6502, BINFMT_BINARY, CTNone }, { "nes", CPU_6502, BINFMT_BINARY, CTNone }, { "supervision", CPU_65SC02, BINFMT_BINARY, CTNone }, { "lynx", CPU_65SC02, BINFMT_BINARY, CTNone }, @@ -206,7 +209,6 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "sim65c02", CPU_65C02, BINFMT_BINARY, CTNone }, { "pce", CPU_HUC6280, BINFMT_BINARY, CTNone }, { "gamate", CPU_6502, BINFMT_BINARY, CTNone }, - { "c65", CPU_4510, BINFMT_BINARY, CTPET }, }; /* Target system */ diff --git a/src/common/target.h b/src/common/target.h index 4115ae21a..4bc00225d 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -73,6 +73,8 @@ typedef enum { TGT_GEOS_APPLE, TGT_LUNIX, TGT_ATMOS, + TGT_TELEMON24, + TGT_TELEMON30, TGT_NES, TGT_SUPERVISION, TGT_LYNX, @@ -80,7 +82,6 @@ typedef enum { TGT_SIM65C02, TGT_PCENGINE, TGT_GAMATE, - TGT_C65, TGT_COUNT /* Number of target systems */ } target_t; diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 7810844dc..cf297fd32 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 211ad7cce..afac0cce1 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index acb9b4240..cc5598aad 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/od65.vcxproj b/src/od65.vcxproj index c788ac961..2ace26001 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index f87b4db6b..9ba0980ba 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 8db98346c..6e7d992d4 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> From 15ac85b50c4aa6d32966cfeec5bc650c037aa0c1 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Wed, 14 Dec 2016 23:45:20 +0100 Subject: [PATCH 0176/2161] Adding ch376.h header, correcting some bugs --- include/ch376.h | 55 ++++++++++++++++++++++++++++++++++++++++ libsrc/telemon30/ch376.s | 8 +++--- 2 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 include/ch376.h diff --git a/include/ch376.h b/include/ch376.h new file mode 100644 index 000000000..9db801eaf --- /dev/null +++ b/include/ch376.h @@ -0,0 +1,55 @@ + + +/* /// "Portable types" */ + + + + +/* /// "CH376 interface commands and constants" */ + +// Chip version +#define CH376_DATA_IC_VER 3 + +// Commands +#define CH376_CMD_NONE 0x00 +#define CH376_CMD_GET_IC_VER 0x01 +#define CH376_CMD_CHECK_EXIST 0x06 +#define CH376_CMD_SET_USB_MODE 0x15 +#define CH376_CMD_GET_STATUS 0x22 +#define CH376_CMD_RD_USB_DATA0 0x27 +#define CH376_CMD_WR_REQ_DATA 0x2d +#define CH376_CMD_SET_FILE_NAME 0x2f +#define CH376_CMD_DISK_MOUNT 0x31 +#define CH376_CMD_FILE_OPEN 0x32 +#define CH376_CMD_FILE_ENUM_GO 0x33 +#define CH376_CMD_FILE_CREATE 0x34 +#define CH376_CMD_FILE_CLOSE 0x36 +#define CH376_CMD_BYTE_LOCATE 0x39 +#define CH376_CMD_BYTE_READ 0x3a +#define CH376_CMD_BYTE_RD_GO 0x3b +#define CH376_CMD_BYTE_WRITE 0x3c +#define CH376_CMD_BYTE_WR_GO 0x3d +#define CH376_CMD_DISK_QUERY 0x3f +#define CH376_CMD_DISK_RD_GO 0x55 + +#define CH376_ARG_SET_USB_MODE_INVALID 0x00 +#define CH376_ARG_SET_USB_MODE_SD_HOST 0x03 +#define CH376_ARG_SET_USB_MODE_USB_HOST 0x06 + +// Status & errors +#define CH376_ERR_OPEN_DIR 0x41 +#define CH376_ERR_MISS_FILE 0x42 + +#define CH376_RET_SUCCESS 0x51 +#define CH376_RET_ABORT 0x5f + +#define CH376_INT_SUCCESS 0x14 +#define CH376_INT_DISK_READ 0x1d +#define CH376_INT_DISK_WRITE 0x1e + + +unsigned char ch376_check_exist(unsigned char value); +unsigned char ch376_ic_get_version(void); +void ch376_set_usb_mode(unsigned char value); +unsigned char ch376_disk_mount(void); + diff --git a/libsrc/telemon30/ch376.s b/libsrc/telemon30/ch376.s index 1b75c2b18..90e2878e1 100644 --- a/libsrc/telemon30/ch376.s +++ b/libsrc/telemon30/ch376.s @@ -4,7 +4,7 @@ .export _ch376_reset .export _ch376_check_exist .export _ch376_disk_mount - + .export _ch376_set_usb_mode .import popax .importzp sp,tmp2,tmp3,tmp1 .include "telemon30.inc" @@ -123,6 +123,7 @@ loop: .proc _ch376_ic_get_version lda #CH376_GET_IC_VER sta CH376_COMMAND + ldx #0 lda CH376_DATA rts .endproc @@ -131,10 +132,10 @@ loop: .proc _ch376_set_usb_mode ; CH376_SET_USB_MODE_CODE_USB_HOST_SOF_PACKAGE_AUTOMATICALLY - sta tmp1 + pha lda #CH376_SET_USB_MODE ; $15 sta CH376_COMMAND - lda tmp1 + pla sta CH376_DATA rts .endproc @@ -169,6 +170,7 @@ loop: sta CH376_COMMAND jsr _ch376_wait_response ; if we read data value, we have then length of the volume name + ldx #0 rts .endproc From 66b30f0c7aefade9dca49b7fadf746d9a0594f8c Mon Sep 17 00:00:00 2001 From: Chris Cacciatore <chris.cacciatore@gmail.com> Date: Wed, 14 Dec 2016 16:53:55 -0800 Subject: [PATCH 0177/2161] Added 'any' to --list-opt-steps. --- src/cc65/codeopt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 9eb175105..e44bf2bf5 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -911,6 +911,8 @@ void ListOptSteps (FILE* F) /* List all optimization steps */ { unsigned I; + + fprintf (F, "any\n"); for (I = 0; I < OPTFUNC_COUNT; ++I) { fprintf (F, "%s\n", OptFuncs[I]->Name); } From 09495519c0d9f5f6ad070a27b7a6bdc717b7a554 Mon Sep 17 00:00:00 2001 From: Marshall Ward <git@marshallward.org> Date: Tue, 20 Dec 2016 22:12:08 +1100 Subject: [PATCH 0178/2161] NES memory map amend (16k prg, 8k chr default) The configuration file and runtime (crt0.s) provided for the default NES ROM layout (2x16k PRG, 8k CHR) incorrectly added interrupts (IRQ1, IRQ2, TIMERIRQ) which are not supported by the NES hardware. For example, see the NESdev wiki, which makes no reference to these interrupts. https://wiki.nesdev.com/w/index.php/CPU_memory_map The VECTORS region was also incorrectly set to 0xFFF6, which would have left the 0xFFF4 normally unspecified. This did not result in any error, however, since cc65 simply placed ROMV directly after ROM0 regardless of start address. (This layout may be due to a copy-and-paste from the PC-Engine configuration, whose interrupt registers start at 0xFFF6, begins with the three interrupts listed above, followed by NMI and START, and does not end with a final IRQ interrupt.) Despite the absence of any actual error, since START is still placed at 0xFFFC, this patch removes the nonexistent interrupts and also correctly aligns the ROM0 and ROMV regions. It also has the (admittedly very minor) benefit of freeing up 6 additional bytes for ROM0. --- cfg/nes.cfg | 4 ++-- libsrc/nes/crt0.s | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/cfg/nes.cfg b/cfg/nes.cfg index fdd992fe0..bb7d23408 100644 --- a/cfg/nes.cfg +++ b/cfg/nes.cfg @@ -12,10 +12,10 @@ MEMORY { # - code # - rodata # - data (load) - ROM0: file = %O, start = $8000, size = $7FF4, fill = yes, define = yes; + ROM0: file = %O, start = $8000, size = $7FFA, fill = yes, define = yes; # Hardware Vectors at End of 2nd 8K ROM - ROMV: file = %O, start = $FFF6, size = $000C, fill = yes; + ROMV: file = %O, start = $FFFA, size = $0006, fill = yes; # 1 8k CHR Bank ROM2: file = %O, start = $0000, size = $2000, fill = yes; diff --git a/libsrc/nes/crt0.s b/libsrc/nes/crt0.s index 4d258ff9e..a380d4dd3 100644 --- a/libsrc/nes/crt0.s +++ b/libsrc/nes/crt0.s @@ -159,9 +159,6 @@ nmi: pha ; Interrupt exit -irq2: -irq1: -timerirq: irq: rti @@ -171,9 +168,6 @@ irq: .segment "VECTORS" - .word irq2 ; $fff4 ? - .word irq1 ; $fff6 ? - .word timerirq ; $fff8 ? .word nmi ; $fffa vblank nmi .word start ; $fffc reset .word irq ; $fffe irq / brk From 1b4a7e37ce8e7fd0b8b82630da48944ccd3125cb Mon Sep 17 00:00:00 2001 From: Kyle Swanson <k@ylo.ph> Date: Tue, 27 Dec 2016 11:45:40 -0600 Subject: [PATCH 0179/2161] doc/ca65: fix typo --- doc/ca65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 78be90d15..2c43a9b50 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -3012,7 +3012,7 @@ Here's a list of all control commands and a description, what they do: Conditional assembly: Check if there are any remaining tokens in this line, and evaluate to FALSE if this is the case, and to TRUE otherwise. If the condition is not true, further lines are not assembled until an <tt><ref - id=".ELSE" name=".ESLE"></tt>, <tt><ref id=".ELSEIF" name=".ELSEIF"></tt> or + id=".ELSE" name=".ELSE"></tt>, <tt><ref id=".ELSEIF" name=".ELSEIF"></tt> or <tt><ref id=".ENDIF" name=".ENDIF"></tt> directive. This command is often used to check if a macro parameter was given. Since an From d5ba0636027feab064614b669c9196ef24ed6287 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Wed, 4 Jan 2017 20:03:19 +0100 Subject: [PATCH 0180/2161] Correcting some bugs --- include/telemon.h | 58 ++++++++++++++++++++++++++++++++++++++++ libsrc/telemon30/_open.s | 28 ++++++++++++++++--- libsrc/telemon30/ch376.s | 27 +++++++++++++++++-- 3 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 include/telemon.h diff --git a/include/telemon.h b/include/telemon.h new file mode 100644 index 000000000..70033a9ad --- /dev/null +++ b/include/telemon.h @@ -0,0 +1,58 @@ + +void print (char *); + +void hires(); +void text(); +void oups(); +void ping(); +void zap(); +void shoot(); +void explode(); + +void paper(char color); +void ink(char color); + +void kbdclick1(); + + + +void curset(char x,char y); +void circle(char rayon); + +char key(void); + + +/* PEEK, POKE, DEEK, DOKE */ + +#define POKE(addr,val) (*(unsigned char*) (addr) = (val)) + + +#define PCHN_1 001 +#define PCHN_2 002 +#define PCHN_12 003 +#define PCHN_3 004 +#define PCHN_13 005 +#define PCHN_23 006 +#define PCHN_123 007 + +#define ENV_DECAY 001 /* \_________ envelope */ +#define ENV_ATTACK_CUT 002 /* /_________ envelope */ +#define ENV_SAW_DOWN 003 /* \\\\\\\\\\ envelope */ +#define ENV_WAVE 004 /* /\/\/\/\/\ envelope */ +#define ENV_DECAY_CONT 005 /* \~~~~~~~~~ envelope */ +#define ENV_SAW_UP 006 /* ////////// envelope */ +#define ENV_ATTACK_CONT 007 /* /~~~~~~~~~ envelope */ + +#define VOL_ENVELOPE 0x0 +#define VOL_QUIETEST 0x1 +#define VOL_LOUDEST 0xe + +extern int play(int soundchanels,int noisechanels,int envelop,int volume); + + +/* Play a musical tone through the selected channel. */ + +#define CHAN_1 1 +#define CHAN_2 2 +#define CHAN_3 3 + diff --git a/libsrc/telemon30/_open.s b/libsrc/telemon30/_open.s index f308632d9..a002bbce1 100644 --- a/libsrc/telemon30/_open.s +++ b/libsrc/telemon30/_open.s @@ -3,7 +3,9 @@ .importzp sp,tmp2,tmp3,tmp1 ; int open (const char* name, int flags, ...); /* May take a mode argument */ .include "telemon30.inc" - + .include "errno.inc" + .include "fcntl.inc" + .proc _open ; Throw away any additional parameters passed through the ellipsis @@ -16,12 +18,32 @@ ; Parameters ok. Pop the flags and save them into tmp3 -parmok: jsr popax ; Get flags +parmok: jsr popax ; Get flagss + sta tmp3 ; save flags + + ;AND #O_RDONLY + ;beq READONLY + ;lda tmp3 + ;AND #O_WRONLY + ;beq WRITEONLY + ;jmp next +;READONLY: +; lda #'r' +; BRK_TELEMON XWR0 +; jmp next +;WRITEONLY: +; lda #'w' +; BRK_TELEMON XWR0 + +;next: ; Get the filename from stack and parse it. Bail out if is not ok jsr popax ; Get name - + + + ldy tmp3 ; Get flags + BRK_TELEMON XOPEN diff --git a/libsrc/telemon30/ch376.s b/libsrc/telemon30/ch376.s index 90e2878e1..24df14471 100644 --- a/libsrc/telemon30/ch376.s +++ b/libsrc/telemon30/ch376.s @@ -1,3 +1,6 @@ + + ; For XA65 compatibily in the futur + .FEATURE c_comments,labels_without_colons,pc_assignment, loose_char_term .export _ch376_set_file_name .export _ch376_file_open .export _ch376_ic_get_version @@ -5,10 +8,18 @@ .export _ch376_check_exist .export _ch376_disk_mount .export _ch376_set_usb_mode + .export _ch376_file_create + .export _ch376_fcreate + + ; High level function + .export _ch376_fcreate + .import popax .importzp sp,tmp2,tmp3,tmp1 .include "telemon30.inc" +/* +*/ ; CODE FOR CH376_SET_USB_MODE ************************************************* CH376_SET_USB_MODE_CODE_USB_HOST_SOF_PACKAGE_AUTOMATICALLY := $06 @@ -17,8 +28,7 @@ CH376_USB_INT_DISK_READ := $1d CH376_USB_INT_SUCCESS := $14 CH376_ERR_MISS_FILE := $42 -CH376_DATA :=$340 -CH376_COMMAND :=$341 + CH376_GET_IC_VER := $01 CH376_SET_BAUDRATE := $02 @@ -34,6 +44,7 @@ CH376_DISK_CONNECT := $30 ; check the disk connection status CH376_DISK_MOUNT := $31 CH376_FILE_OPEN := $32 CH376_FILE_ENUM_GO := $33 +CH376_FILE_CREATE := $34 CH376_FILE_CLOSE := $36 CH376_BYTE_READ := $3A CH376_BYTE_RD_GO := $3b @@ -41,7 +52,19 @@ CH376_BYTE_WRITE := $3C CH376_DISK_CAPACITY := $3E CH376_DISK_RD_GO := $55 +.proc _ch376_file_create + lda #CH376_FILE_CREATE + sta CH376_COMMAND + jsr _ch376_wait_response + rts +.endproc +; void _ch376_fcreate(char *filename) +.proc _ch376_fcreate + jsr _ch376_set_file_name + jsr _ch376_file_open + jsr _ch376_file_create +.endproc ; void ch376_set_file_name(char *filename) .proc _ch376_set_file_name From c1aac0de0e9c8fc92a325f2809dc9eacb489b137 Mon Sep 17 00:00:00 2001 From: Florent Flament <contact@florentflament.com> Date: Sun, 8 Jan 2017 19:12:55 +0100 Subject: [PATCH 0181/2161] Add C support for Atari 2600 (VCS) --- cfg/atari2600.cfg | 22 ++++++ include/_riot.h | 26 +++++++ include/_tia.h | 100 ++++++++++++++++++++++++ include/atari2600.h | 26 +++++++ libsrc/Makefile | 1 + libsrc/atari2600/crt0.s | 49 ++++++++++++ libsrc/atari2600/ctype.s | 162 +++++++++++++++++++++++++++++++++++++++ samples/Makefile | 3 + samples/atari2600hello.c | 56 ++++++++++++++ src/ca65/main.c | 4 + src/cc65/main.c | 4 + src/common/target.c | 2 + src/common/target.h | 1 + 13 files changed, 456 insertions(+) create mode 100644 cfg/atari2600.cfg create mode 100644 include/_riot.h create mode 100644 include/_tia.h create mode 100644 include/atari2600.h create mode 100644 libsrc/atari2600/crt0.s create mode 100644 libsrc/atari2600/ctype.s create mode 100644 samples/atari2600hello.c diff --git a/cfg/atari2600.cfg b/cfg/atari2600.cfg new file mode 100644 index 000000000..106edeb30 --- /dev/null +++ b/cfg/atari2600.cfg @@ -0,0 +1,22 @@ +# Atari VCS 2600 linker configuration file for cc65 +# +# Florent Flament (contact@florentflament.com), 2017 + +SYMBOLS { + __STACKSIZE__: type = weak, value = $0010; # 16 Bytes system stack +} + +MEMORY { + RAM: file = "", start = $0080, size = $0080 - __STACKSIZE__, define = yes; + ROM: file = %O, start = $F000, size = $1000, fill = yes, fillval = $FF; +} + +SEGMENTS { + ZEROPAGE: load = RAM, type = zp; + STARTUP: load = ROM, type = ro; + CODE: load = ROM, type = ro; + RODATA: load = ROM, type = ro, optional = yes; + DATA: load = ROM, run = RAM, type = rw, optional = yes, define = yes; + BSS: load = RAM, type = bss, optional = yes; + VECTORS: load = ROM, type = ro, start = $FFFA; +} diff --git a/include/_riot.h b/include/_riot.h new file mode 100644 index 000000000..7c431127c --- /dev/null +++ b/include/_riot.h @@ -0,0 +1,26 @@ +/*****************************************************************************/ +/* */ +/* Atari VCS 2600 RIOT registers addresses */ +/* */ +/* Source: DASM - vcs.h */ +/* */ +/* Florent Flament (contact@florentflament.com), 2017 */ +/* */ +/*****************************************************************************/ + +/* RIOT registers */ +struct __riot { + unsigned char swcha; + unsigned char swacnt; + unsigned char swchb; + unsigned char swbcnt; + unsigned char intim; + unsigned char timint; + + unsigned char unused[14]; + + unsigned char tim1t; + unsigned char tim8t; + unsigned char tim64t; + unsigned char t1024t; +}; diff --git a/include/_tia.h b/include/_tia.h new file mode 100644 index 000000000..c89c04d6c --- /dev/null +++ b/include/_tia.h @@ -0,0 +1,100 @@ +/*****************************************************************************/ +/* */ +/* Atari VCS 2600 TIA registers addresses */ +/* */ +/* Source: DASM - vcs.h */ +/* */ +/* Florent Flament (contact@florentflament.com), 2017 */ +/* */ +/*****************************************************************************/ + +/* TIA write / read registers */ +struct __tia { + union { + unsigned char vsync; + unsigned char cxm0p; + }; + union { + unsigned char vblank; + unsigned char cxm1p; + }; + union { + unsigned char wsync; + unsigned char cxp0fb; + }; + union { + unsigned char rsync; + unsigned char cxp1fb; + }; + union { + unsigned char nusiz0; + unsigned char cxm0fb; + }; + union { + unsigned char nusiz1; + unsigned char cxm1fb; + }; + union { + unsigned char colup0; + unsigned char cxblpf; + }; + union { + unsigned char colup1; + unsigned char cxppmm; + }; + union { + unsigned char colupf; + unsigned char inpt0; + }; + union { + unsigned char colubk; + unsigned char inpt1; + }; + union { + unsigned char ctrlpf; + unsigned char inpt2; + }; + union { + unsigned char refp0; + unsigned char inpt3; + }; + union { + unsigned char refp1; + unsigned char inpt4; + }; + union { + unsigned char pf0; + unsigned char inpt5; + }; + unsigned char pf1; + unsigned char pf2; + unsigned char resp0; + unsigned char resp1; + unsigned char resm0; + unsigned char resm1; + unsigned char resbl; + unsigned char audc0; + unsigned char audc1; + unsigned char audf0; + unsigned char audf1; + unsigned char audv0; + unsigned char audv1; + unsigned char grp0; + unsigned char grp1; + unsigned char enam0; + unsigned char enam1; + unsigned char enabl; + unsigned char hmp0; + unsigned char hmp1; + unsigned char hmm0; + unsigned char hmm1; + unsigned char hmbl; + unsigned char vdelp0; + unsigned char vdelp1; + unsigned char vdelbl; + unsigned char resmp0; + unsigned char resmp1; + unsigned char hmove; + unsigned char hmclr; + unsigned char cxclr; +}; diff --git a/include/atari2600.h b/include/atari2600.h new file mode 100644 index 000000000..1eb51a2dd --- /dev/null +++ b/include/atari2600.h @@ -0,0 +1,26 @@ +/*****************************************************************************/ +/* */ +/* Atari VCS 2600 TIA & RIOT registers addresses */ +/* */ +/* Source: DASM Version 1.05 - vcs.h */ +/* */ +/* Florent Flament (contact@florentflament.com), 2017 */ +/* */ +/*****************************************************************************/ + +#ifndef _ATARI2600_H +#define _ATARI2600_H + +/* Check for errors */ +#if !defined(__ATARI2600__) +# error This module may only be used when compiling for the Atari 2600! +#endif + +#include <_tia.h> +#define TIA (*(struct __tia*)0x0000) + +#include <_riot.h> +#define RIOT (*(struct __riot*)0x0280) + +/* End of atari2600.h */ +#endif /* #ifndef _ATARI2600_H */ diff --git a/libsrc/Makefile b/libsrc/Makefile index 99f120f3a..6b6a8fce8 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -19,6 +19,7 @@ TARGETS = apple2 \ apple2enh \ atari \ atarixl \ + atari2600 \ atari5200 \ atmos \ $(CBMS) \ diff --git a/libsrc/atari2600/crt0.s b/libsrc/atari2600/crt0.s new file mode 100644 index 000000000..4f09a0a5a --- /dev/null +++ b/libsrc/atari2600/crt0.s @@ -0,0 +1,49 @@ +; Atari VCS 2600 startup code for cc65 +; +; Florent Flament (contact@florentflament.com), 2017 + + .export _exit + .export __STARTUP__ : absolute = 1 + + .import __RAM_START__, __RAM_SIZE__ + .import copydata + .import _main + + .include "zeropage.inc" + + +.segment "STARTUP" +start: +; Clear decimal mode + cld + +; Initialization Loop: +; * Clears Atari 2600 whole memory (128 bytes) including BSS segment +; * Clears TIA registers +; * Sets system stack pointer to $ff (i.e top of zero-page) + ldx #0 + txa +clearLoop: + dex + txs + pha + bne clearLoop + +; Initialize data + jsr copydata + +; Initialize C stack pointer + lda #<(__RAM_START__ + __RAM_SIZE__) + ldx #>(__RAM_START__ + __RAM_SIZE__) + sta sp + stx sp+1 + +; Call main + jsr _main +_exit: jmp _exit + + +.segment "VECTORS" +.word start ; NMI +.word start ; Reset +.word start ; IRQ diff --git a/libsrc/atari2600/ctype.s b/libsrc/atari2600/ctype.s new file mode 100644 index 000000000..1892554fd --- /dev/null +++ b/libsrc/atari2600/ctype.s @@ -0,0 +1,162 @@ +; +; Ullrich von Bassewitz, 2003-10-10 +; +; Character specification table. +; + + .include "ctype.inc" + +; The tables are readonly, put them into the rodata segment + +.rodata + +; The following 256 byte wide table specifies attributes for the isxxx type +; of functions. Doing it by a table means some overhead in space, but it +; has major advantages: +; +; * It is fast. If it weren't for the slow parameter passing of cc65, one +; could even define macros for the isxxx functions (this is usually +; done on other platforms). +; +; * It is highly portable. The only unportable part is the table itself, +; all real code goes into the common library. +; +; * We save some code in the isxxx functions. + + +__ctype: + .byte CT_CTRL ; 0/00 ___ctrl_@___ + .byte CT_CTRL ; 1/01 ___ctrl_A___ + .byte CT_CTRL ; 2/02 ___ctrl_B___ + .byte CT_CTRL ; 3/03 ___ctrl_C___ + .byte CT_CTRL ; 4/04 ___ctrl_D___ + .byte CT_CTRL ; 5/05 ___ctrl_E___ + .byte CT_CTRL ; 6/06 ___ctrl_F___ + .byte CT_CTRL ; 7/07 ___ctrl_G___ + .byte CT_CTRL ; 8/08 ___ctrl_H___ + .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB + ; 9/09 ___ctrl_I___ + .byte CT_CTRL | CT_OTHER_WS ; 10/0a ___ctrl_J___ + .byte CT_CTRL | CT_OTHER_WS ; 11/0b ___ctrl_K___ + .byte CT_CTRL | CT_OTHER_WS ; 12/0c ___ctrl_L___ + .byte CT_CTRL | CT_OTHER_WS ; 13/0d ___ctrl_M___ + .byte CT_CTRL ; 14/0e ___ctrl_N___ + .byte CT_CTRL ; 15/0f ___ctrl_O___ + .byte CT_CTRL ; 16/10 ___ctrl_P___ + .byte CT_CTRL ; 17/11 ___ctrl_Q___ + .byte CT_CTRL ; 18/12 ___ctrl_R___ + .byte CT_CTRL ; 19/13 ___ctrl_S___ + .byte CT_CTRL ; 20/14 ___ctrl_T___ + .byte CT_CTRL ; 21/15 ___ctrl_U___ + .byte CT_CTRL ; 22/16 ___ctrl_V___ + .byte CT_CTRL ; 23/17 ___ctrl_W___ + .byte CT_CTRL ; 24/18 ___ctrl_X___ + .byte CT_CTRL ; 25/19 ___ctrl_Y___ + .byte CT_CTRL ; 26/1a ___ctrl_Z___ + .byte CT_CTRL ; 27/1b ___ctrl_[___ + .byte CT_CTRL ; 28/1c ___ctrl_\___ + .byte CT_CTRL ; 29/1d ___ctrl_]___ + .byte CT_CTRL ; 30/1e ___ctrl_^___ + .byte CT_CTRL ; 31/1f ___ctrl_____ + .byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___ + .byte CT_NONE ; 33/21 _____!_____ + .byte CT_NONE ; 34/22 _____"_____ + .byte CT_NONE ; 35/23 _____#_____ + .byte CT_NONE ; 36/24 _____$_____ + .byte CT_NONE ; 37/25 _____%_____ + .byte CT_NONE ; 38/26 _____&_____ + .byte CT_NONE ; 39/27 _____'_____ + .byte CT_NONE ; 40/28 _____(_____ + .byte CT_NONE ; 41/29 _____)_____ + .byte CT_NONE ; 42/2a _____*_____ + .byte CT_NONE ; 43/2b _____+_____ + .byte CT_NONE ; 44/2c _____,_____ + .byte CT_NONE ; 45/2d _____-_____ + .byte CT_NONE ; 46/2e _____._____ + .byte CT_NONE ; 47/2f _____/_____ + .byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____ + .byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____ + .byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____ + .byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____ + .byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____ + .byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____ + .byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____ + .byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____ + .byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____ + .byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____ + .byte CT_NONE ; 58/3a _____:_____ + .byte CT_NONE ; 59/3b _____;_____ + .byte CT_NONE ; 60/3c _____<_____ + .byte CT_NONE ; 61/3d _____=_____ + .byte CT_NONE ; 62/3e _____>_____ + .byte CT_NONE ; 63/3f _____?_____ + + .byte CT_NONE ; 64/40 _____@_____ + .byte CT_UPPER | CT_XDIGIT ; 65/41 _____A_____ + .byte CT_UPPER | CT_XDIGIT ; 66/42 _____B_____ + .byte CT_UPPER | CT_XDIGIT ; 67/43 _____C_____ + .byte CT_UPPER | CT_XDIGIT ; 68/44 _____D_____ + .byte CT_UPPER | CT_XDIGIT ; 69/45 _____E_____ + .byte CT_UPPER | CT_XDIGIT ; 70/46 _____F_____ + .byte CT_UPPER ; 71/47 _____G_____ + .byte CT_UPPER ; 72/48 _____H_____ + .byte CT_UPPER ; 73/49 _____I_____ + .byte CT_UPPER ; 74/4a _____J_____ + .byte CT_UPPER ; 75/4b _____K_____ + .byte CT_UPPER ; 76/4c _____L_____ + .byte CT_UPPER ; 77/4d _____M_____ + .byte CT_UPPER ; 78/4e _____N_____ + .byte CT_UPPER ; 79/4f _____O_____ + .byte CT_UPPER ; 80/50 _____P_____ + .byte CT_UPPER ; 81/51 _____Q_____ + .byte CT_UPPER ; 82/52 _____R_____ + .byte CT_UPPER ; 83/53 _____S_____ + .byte CT_UPPER ; 84/54 _____T_____ + .byte CT_UPPER ; 85/55 _____U_____ + .byte CT_UPPER ; 86/56 _____V_____ + .byte CT_UPPER ; 87/57 _____W_____ + .byte CT_UPPER ; 88/58 _____X_____ + .byte CT_UPPER ; 89/59 _____Y_____ + .byte CT_UPPER ; 90/5a _____Z_____ + .byte CT_NONE ; 91/5b _____[_____ + .byte CT_NONE ; 92/5c _____\_____ + .byte CT_NONE ; 93/5d _____]_____ + .byte CT_NONE ; 94/5e _____^_____ + .byte CT_NONE ; 95/5f _UNDERLINE_ + .byte CT_NONE ; 96/60 ___grave___ + .byte CT_LOWER | CT_XDIGIT ; 97/61 _____a_____ + .byte CT_LOWER | CT_XDIGIT ; 98/62 _____b_____ + .byte CT_LOWER | CT_XDIGIT ; 99/63 _____c_____ + .byte CT_LOWER | CT_XDIGIT ; 100/64 _____d_____ + .byte CT_LOWER | CT_XDIGIT ; 101/65 _____e_____ + .byte CT_LOWER | CT_XDIGIT ; 102/66 _____f_____ + .byte CT_LOWER ; 103/67 _____g_____ + .byte CT_LOWER ; 104/68 _____h_____ + .byte CT_LOWER ; 105/69 _____i_____ + .byte CT_LOWER ; 106/6a _____j_____ + .byte CT_LOWER ; 107/6b _____k_____ + .byte CT_LOWER ; 108/6c _____l_____ + .byte CT_LOWER ; 109/6d _____m_____ + .byte CT_LOWER ; 110/6e _____n_____ + .byte CT_LOWER ; 111/6f _____o_____ + .byte CT_LOWER ; 112/70 _____p_____ + .byte CT_LOWER ; 113/71 _____q_____ + .byte CT_LOWER ; 114/72 _____r_____ + .byte CT_LOWER ; 115/73 _____s_____ + .byte CT_LOWER ; 116/74 _____t_____ + .byte CT_LOWER ; 117/75 _____u_____ + .byte CT_LOWER ; 118/76 _____v_____ + .byte CT_LOWER ; 119/77 _____w_____ + .byte CT_LOWER ; 120/78 _____x_____ + .byte CT_LOWER ; 121/79 _____y_____ + .byte CT_LOWER ; 122/7a _____z_____ + .byte CT_NONE ; 123/7b _____{_____ + .byte CT_NONE ; 124/7c _____|_____ + .byte CT_NONE ; 125/7d _____}_____ + .byte CT_NONE ; 126/7e _____~_____ + .byte CT_OTHER_WS ; 127/7f ____DEL____ + + .res 128, CT_NONE ; 128-255 + + + diff --git a/samples/Makefile b/samples/Makefile index 3a60798da..abd304b14 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -147,6 +147,9 @@ EXELIST_atari = \ EXELIST_atarixl = $(EXELIST_atari) +EXELIST_atari2600 = \ + atari2600hello + # -------------------------------------------------------------------------- # Rules to make the binaries and the disk diff --git a/samples/atari2600hello.c b/samples/atari2600hello.c new file mode 100644 index 000000000..e4f7893b7 --- /dev/null +++ b/samples/atari2600hello.c @@ -0,0 +1,56 @@ +/*****************************************************************************/ +/* */ +/* Atari VCS 2600 sample C program */ +/* */ +/* Florent Flament (contact@florentflament.com), 2017 */ +/* */ +/*****************************************************************************/ + +#include <atari2600.h> + +// PAL Timings +// Roughly computed based on Stella Programmer's guide (Steve Wright) +// scanlines count per section. +#define VBLANK_TIM64 51 // 45 lines * 76 cycles/line / 64 cycles/tick +#define KERNAL_T1024 17 // 228 lines * 76 cycles/line / 1024 cycles/tick +#define OVERSCAN_TIM64 42 // 36 lines * 76 cycles/line / 64 cycles/tick + +// Testing memory zones +const unsigned char rodata_v[] = "Hello!"; +unsigned char data_v = 0x77; +unsigned char bss_v; + +void main(void) { + unsigned char color = 0x79; // Stack variable + bss_v = 0x88; // Testing BSS variable + + for/*ever*/(;;) { + // Vertical Sync signal + TIA.vsync = 0x02; + TIA.wsync = 0x00; + TIA.wsync = 0x00; + TIA.wsync = 0x00; + TIA.vsync = 0x00; + + // Vertical Blank timer setting + RIOT.tim64t = VBLANK_TIM64; + + // Doing frame computation during blank + TIA.colubk = color++; // Update color + + // Wait for end of Vertical Blank + while (RIOT.timint == 0) {} + TIA.wsync = 0x00; + TIA.vblank = 0x00; // Turn on beam + + // Display frame + RIOT.t1024t = KERNAL_T1024; + while (RIOT.timint == 0) {} + TIA.wsync = 0x00; + TIA.vblank = 0x02; // Turn off beam + + // Overscan + RIOT.tim64t = OVERSCAN_TIM64; + while (RIOT.timint == 0) {} + } +} diff --git a/src/ca65/main.c b/src/ca65/main.c index d6c364e4b..1317f26cc 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -205,6 +205,10 @@ static void SetSys (const char* Sys) AbEnd ("Cannot use `module' as a target for the assembler"); break; + case TGT_ATARI2600: + NewSymbol ("__ATARI2600__", 1); + break; + case TGT_ATARI5200: NewSymbol ("__ATARI5200__", 1); break; diff --git a/src/cc65/main.c b/src/cc65/main.c index afbec43d7..2a82e5302 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -161,6 +161,10 @@ static void SetSys (const char* Sys) AbEnd ("Cannot use `module' as a target for the compiler"); break; + case TGT_ATARI2600: + DefineNumericMacro ("__ATARI2600__", 1); + break; + case TGT_ATARI5200: DefineNumericMacro ("__ATARI5200__", 1); break; diff --git a/src/common/target.c b/src/common/target.c index 99a134c43..42db5dee3 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -145,6 +145,7 @@ static const TargetEntry TargetMap[] = { { "apple2", TGT_APPLE2 }, { "apple2enh", TGT_APPLE2ENH }, { "atari", TGT_ATARI }, + { "atari2600", TGT_ATARI2600 }, { "atari5200", TGT_ATARI5200 }, { "atarixl", TGT_ATARIXL }, { "atmos", TGT_ATMOS }, @@ -181,6 +182,7 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "none", CPU_6502, BINFMT_BINARY, CTNone }, { "module", CPU_6502, BINFMT_O65, CTNone }, { "atari", CPU_6502, BINFMT_BINARY, CTAtari }, + { "atari2600", CPU_6502, BINFMT_BINARY, CTNone }, { "atari5200", CPU_6502, BINFMT_BINARY, CTAtari }, { "atarixl", CPU_6502, BINFMT_BINARY, CTAtari }, { "vic20", CPU_6502, BINFMT_BINARY, CTPET }, diff --git a/src/common/target.h b/src/common/target.h index 4115ae21a..a5cb44b98 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -55,6 +55,7 @@ typedef enum { TGT_NONE, TGT_MODULE, TGT_ATARI, + TGT_ATARI2600, TGT_ATARI5200, TGT_ATARIXL, TGT_VIC20, From 3d52856dd21f52c6a9bd658df53dafcf74e63452 Mon Sep 17 00:00:00 2001 From: Florent Flament <contact@florentflament.com> Date: Fri, 13 Jan 2017 21:11:44 +0100 Subject: [PATCH 0182/2161] Add Atari2600 ASM header (.inc) files --- asminc/atari2600.inc | 7 ++++ asminc/atari2600_riot.inc | 20 ++++++++++++ asminc/atari2600_tia.inc | 69 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 asminc/atari2600.inc create mode 100644 asminc/atari2600_riot.inc create mode 100644 asminc/atari2600_tia.inc diff --git a/asminc/atari2600.inc b/asminc/atari2600.inc new file mode 100644 index 000000000..a20926d08 --- /dev/null +++ b/asminc/atari2600.inc @@ -0,0 +1,7 @@ +; Atari 2600 TIA & RIOT read / write registers +; +; Florent Flament (contact@florentflament.com), 2017 + +; TIA & RIOT registers mapping +.include "atari2600_tia.inc" +.include "atari2600_riot.inc" diff --git a/asminc/atari2600_riot.inc b/asminc/atari2600_riot.inc new file mode 100644 index 000000000..a2c6ef633 --- /dev/null +++ b/asminc/atari2600_riot.inc @@ -0,0 +1,20 @@ +; Atari 2600 RIOT read / write registers +; +; Source: DASM - vcs.h +; Details available in: Stella Programmer's Guide by Steve Wright +; +; Florent Flament (contact@florentflament.com), 2017 + +; Read registers +SWCHA := $0280 +SWACNT := $0281 +SWCHB := $0282 +SWBCNT := $0283 +INTIM := $0284 +TIMINT := $0285 + +; Write registers +TIM1T := $0294 +TIM8T := $0295 +TIM64T := $0296 +T1024T := $0297 diff --git a/asminc/atari2600_tia.inc b/asminc/atari2600_tia.inc new file mode 100644 index 000000000..57c27adba --- /dev/null +++ b/asminc/atari2600_tia.inc @@ -0,0 +1,69 @@ +; Atari 2600 TIA read / write registers +; +; Source: DASM - vcs.h +; Details available in: Stella Programmer's Guide by Steve Wright +; +; Florent Flament (contact@florentflament.com), 2017 + +; Read registers +VSYNC := $00 +VBLANK := $01 +WSYNC := $02 +RSYNC := $03 +NUSIZ0 := $04 +NUSIZ1 := $05 +COLUP0 := $06 +COLUP1 := $07 +COLUPF := $08 +COLUBK := $09 +CTRLPF := $0A +REFP0 := $0B +REFP1 := $0C +PF0 := $0D +PF1 := $0E +PF2 := $0F +RESP0 := $10 +RESP1 := $11 +RESM0 := $12 +RESM1 := $13 +RESBL := $14 +AUDC0 := $15 +AUDC1 := $16 +AUDF0 := $17 +AUDF1 := $18 +AUDV0 := $19 +AUDV1 := $1A +GRP0 := $1B +GRP1 := $1C +ENAM0 := $1D +ENAM1 := $1E +ENABL := $1F +HMP0 := $20 +HMP1 := $21 +HMM0 := $22 +HMM1 := $23 +HMBL := $24 +VDELP0 := $25 +VDELP1 := $26 +VDELBL := $27 +RESMP0 := $28 +RESMP1 := $29 +HMOVE := $2A +HMCLR := $2B +CXCLR := $2C + +; Write registers +CXM0P := $00 +CXM1P := $01 +CXP0FB := $02 +CXP1FB := $03 +CXM0FB := $04 +CXM1FB := $05 +CXBLPF := $06 +CXPPMM := $07 +INPT0 := $08 +INPT1 := $09 +INPT2 := $0A +INPT3 := $0B +INPT4 := $0C +INPT5 := $0D From 2a81eaa06e9cb5a9afc0d8aa16fdaa9b3b6b4ffd Mon Sep 17 00:00:00 2001 From: Florent Flament <contact@florentflament.com> Date: Wed, 11 Jan 2017 23:12:30 +0100 Subject: [PATCH 0183/2161] Add Atari 2600 documentation --- doc/atari2600.sgml | 124 +++++++++++++++++++++++++++++++++++++++++++++ doc/ca65.sgml | 1 + doc/cc65.sgml | 4 ++ doc/index.sgml | 3 ++ doc/intro.sgml | 29 +++++++++++ doc/ld65.sgml | 1 + 6 files changed, 162 insertions(+) create mode 100644 doc/atari2600.sgml diff --git a/doc/atari2600.sgml b/doc/atari2600.sgml new file mode 100644 index 000000000..ae1b6cb5c --- /dev/null +++ b/doc/atari2600.sgml @@ -0,0 +1,124 @@ +<!doctype linuxdoc system> + +<article> + +<title>Atari 2600 specific information for cc65 +<author> +<url url="mailto:contact@florentflament.com" name="Florent Flament"><newline> +<date>2017-01-11 + +<abstract> +An overview over the Atari 2600 runtime system as it is implemented +for the cc65 C compiler. +</abstract> + +<!-- Table of contents --> +<toc> + +<!-- Begin the document --> + +<sect>Overview<p> + +This file contains an overview of the Atari 2600 runtime system as it +comes with the cc65 C compiler. It describes the memory layout, Atari +2600 specific header files and any pitfalls specific to that platform. + +<sect>Binary format<p> + +The default binary output format generated by the linker for the Atari +2600 target is a 4K cartridge image. + +<sect>Memory layout<p> + +cc65 generated programs with the default setup can use RAM from +$0080 to $00FF - __STACKSIZE__, where __STACKSIZE__ is +the size of the system stack with a default value of 16 bytes. The +size of the system stack can be customized by defining the +__STACKSIZE__ linker variable. + +Special locations: + +<descrip> + <tag/Stack/ The C runtime stack is located at $00FF - + __STACKSIZE__ and growing downwards. + + <tag/Heap/ The C heap is located at $0080 and grows upwards. + +</descrip><p> + +<sect>Start-up condition<p> + +When powered-up, the Atari 2600 TIA registers contain random +values. During the initialization phase, the start-up code needs to +initialize the TIA registers to sound values (or else the console has +an unpredictable behavior). In this implementation, zeros are written +to all of TIA registers during the start-up phase. + +Note that RIOT registers (mostly timers) are left uninitialized, as +they don't have any consequence on the console behavior. + +<sect>Platform specific header files<p> + +Programs containing Atari 2600 specific code may use the +<tt/atari2600.h/ header file. + +The following pseudo variables declared in the <tt/atari2600.h/ header +file allow access to the Atari 2600 TIA & RIOT chips registers. + +<descrip> + + <tag><tt/TIA/</tag> The <tt/TIA/ structure allows read/write access + to the Atari 2600 TIA chip registers. See the <tt/_tia.h/ header + file located in the include directory for the declaration of the + structure. Also refer to the Stella Programmer's Guide by Steve + Wright for a detailed description of the chip and its registers. + + <tag><tt/RIOT/</tag> The <tt/RIOT/ structure allows read/write + access to the Atari 2600 RIOT chip registers. See the + <tt/_riot.h/ header file located in the include directory for the + declaration of the structure. Also refer to the Stella Programmer's + Guide by Steve Wright for a detailed description of the chip and its + registers. + +</descrip><p> + + +<sect>Loadable drivers<p> + +There are no drivers for the Atari 2600. + + +<sect>Limitations<p> + +TBD + + +<sect>Other hints<p> + +One may write a custom linker configuration file to tune the memory +layout of a program. See the <tt/atari2600.cfg/ file in the cfg +directory as a starting point. + + +<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/ca65.sgml b/doc/ca65.sgml index 2c43a9b50..da0233c62 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -4583,6 +4583,7 @@ compiler, depending on the target system selected: <itemize> <item><tt/__APPLE2__/ - Target system is <tt/apple2/ or <tt/apple2enh/ <item><tt/__APPLE2ENH__/ - Target system is <tt/apple2enh/ +<item><tt/__ATARI2600__/ - Target system is <tt/atari2600/ <item><tt/__ATARI5200__/ - Target system is <tt/atari5200/ <item><tt/__ATARI__/ - Target system is <tt/atari/ or <tt/atarixl/ <item><tt/__ATARIXL__/ - Target system is <tt/atarixl/ diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 3e59d4cf0..80dba89b8 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -752,6 +752,10 @@ The compiler defines several macros at startup: This macro is defined if the target is the enhanced Apple //e (-t apple2enh). + <tag><tt>__ATARI2600__</tt></tag> + + This macro is defined if the target is the Atari 2600 game console. + <tag><tt>__ATARI5200__</tt></tag> This macro is defined if the target is the Atari 5200 game console. diff --git a/doc/index.sgml b/doc/index.sgml index 44b58ef5e..9b7ab794e 100644 --- a/doc/index.sgml +++ b/doc/index.sgml @@ -116,6 +116,9 @@ <tag><htmlurl url="atari.html" name="atari.html"></tag> Topics specific to the Atari 8-bit machines. + <tag><htmlurl url="atari2600.html" name="atari2600.html"></tag> + Topics specific to the Atari 2600 Game Console. + <tag><htmlurl url="atari5200.html" name="atari5200.html"></tag> Topics specific to the Atari 5200 Game Console. diff --git a/doc/intro.sgml b/doc/intro.sgml index d92fd1d20..bb8965c60 100644 --- a/doc/intro.sgml +++ b/doc/intro.sgml @@ -335,6 +335,35 @@ your harddrive directly. to the DOS menu. Your C program should wait for a keypress if you want to see any output. +<sect2>Stella<p> +Available at <url +url="http://stella.sourceforge.net">: + +Stella is a multi-platform Atari 2600 VCS emulator. The latest version +is available on the emulator's website. It is also available through +the package manager of most Linux distributions (Fedora, Ubuntu, ..). + +Compile the Atari 2600 sample with + +<tscreen><verb> +make SYS=atari2600 samples +</verb></tscreen> + +Then execute it with + +<tscreen><verb> +stella samples/atari2600hello +</verb></tscreen> + +<sect2>Harmony Cartridge<p> +Available at <url +url="http://harmony.atariage.com/Site/Harmony.html">: + +The Harmony Cartridge allows running any Atari 2600 binary on real +hardware. The binary must be copied on an SD card, to be inserted in +the Harmony Cartridge. It can then be inserted on an Atari 2600 +console, and run any binary on the SD card. + <sect1>Atmos diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 448157ce0..5687aa8ab 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -156,6 +156,7 @@ Here is a description of all of the command-line options: <item>module <item>apple2 <item>apple2enh + <item>atari2600 <item>atari <item>atarixl <item>atmos From 54ff808c2ce007cdae3418a82b4affcf8e0fe2fc Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 18 Jan 2017 16:05:47 -0500 Subject: [PATCH 0184/2161] Added a way to show the default mouse pointer on C64 TGI (graphics) screens. --- doc/c64.sgml | 27 +++++++++++++++++++++------ libsrc/c64/extra/tgimousedata.s | 21 +++++++++++++++++++++ libsrc/c64/tgi/c64-hi.s | 10 +++++----- 3 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 libsrc/c64/extra/tgimousedata.s diff --git a/doc/c64.sgml b/doc/c64.sgml index 40bcb37ac..645b57491 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -3,8 +3,9 @@ <article> <title>Commodore 64-specific information for cc65 -<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2014-04-14 +<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"><newline> +<url url="mailto:greg.king5@verizon.net" name="Greg King"> +<date>2017-01-18 <abstract> An overview over the C64 runtime system as it is implemented for the cc65 C @@ -235,12 +236,22 @@ structures, accessing the struct fields will access the chip registers. The names in the parentheses denote the symbols to be used for static linking of the drivers. +<label id="graphics-drivers"> <sect1>Graphics drivers<p> <em>Note:</em> All available graphics drivers for the TGI interface will use -the space below the I/O area and kernal ROM, so you can have hires graphics in -the standard setup without any memory loss or need for a changed -configuration. +the space below the I/O area and Kernal ROM; so, you can have hires graphics in +the standard setup without any memory loss or need for a changed configuration. + +You can use a mouse driver at the same time that you use a TGI driver. But, if +you want to see the default mouse pointer on the graphics screen, then you +explicitly must link a special object file into your program. It will put the +arrow into the "high RAM" area where the bitmaps are put. It's name is +"<tt/c64-tgimousedata.o/". Example: + +<tscreen><verb> +cl65 -t c64 -o program-file main-code.c subroutines.s c64-tgimousedata.o +</verb></tscreen> <descrip> <tag><tt/c64-hi.tgi (c64_hi_tgi)/</tag> @@ -251,7 +262,8 @@ configuration. Note that the graphics drivers are incompatible with the <tt/c64-ram.emd (c64_ram_emd)/ extended memory driver and the - <tt/c64-soft80.o/ software 80 columns conio driver. + <tt/c64-soft80.o/ software 80-columns conio driver. + <sect1>Extended memory drivers<p> @@ -336,6 +348,9 @@ The default drivers, <tt/joy_stddrv (joy_static_stddrv)/, point to <tt/c64-stdjo <sect1>Mouse drivers<p> +You can use these drivers in text-mode or graphics-mode (TGI) programs. See +the description of <ref id="graphics-drivers" name="the graphics drivers">. + The default drivers, <tt/mouse_stddrv (mouse_static_stddrv)/, point to <tt/c64-1351.mou (c64_1351_mou)/. <descrip> diff --git a/libsrc/c64/extra/tgimousedata.s b/libsrc/c64/extra/tgimousedata.s new file mode 100644 index 000000000..f4087e106 --- /dev/null +++ b/libsrc/c64/extra/tgimousedata.s @@ -0,0 +1,21 @@ +; C64 sprite addresses for the TGI mouse pointer +; +; 2017-01-13, Greg King + +; In order to provide a visible mouse pointer during TGI's graphics mode, +; the object file "c64-tgimousedata.o" must be linked explicitly into +; a program file. Example: +; +; cl65 -t c64 -o program-file main-code.c subroutines.s c64-tgimousedata.o +; +; Note: Currently, a program cannot have default +; pointers for both text and graphic modes. + +; The TGI graphics mode uses VIC-II's 16K bank number three. +; +; Address of the TGI bitmap's color RAM + +COLORMAP := $D000 + + .export mcb_spritepointer := COLORMAP + $03F8 + .export mcb_spritememory := COLORMAP + $0400 diff --git a/libsrc/c64/tgi/c64-hi.s b/libsrc/c64/tgi/c64-hi.s index 6d33f00a8..580220ecc 100644 --- a/libsrc/c64/tgi/c64-hi.s +++ b/libsrc/c64/tgi/c64-hi.s @@ -1,7 +1,9 @@ ; ; Graphics driver for the 320x200x2 mode on the C64. ; -; Based on Stephen L. Judds GRLIB code +; Based on Stephen L. Judd's GRLIB code. +; +; 2017-01-13, Greg King ; .include "zeropage.inc" @@ -351,7 +353,7 @@ SETPALETTE: @L2: sta CBASE+$0000,y sta CBASE+$0100,y sta CBASE+$0200,y - sta CBASE+$0300,y + sta CBASE+$02e8,y iny bne @L2 pla @@ -872,7 +874,7 @@ TEXTSTYLE: OUTTEXT: ; Calculate a pointer to the representation of the character in the -; character ROM +; character ROM ldx #((>(CHARROM + $0800)) >> 3) ldy #0 @@ -957,5 +959,3 @@ CALC: lda Y1 lda #00 @L9: sta INRANGE rts - - From 69c293919a6c272033713ebba227aecb47fe7324 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 22 Jan 2017 12:04:21 +0100 Subject: [PATCH 0185/2161] Fixed typo. --- doc/c64.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/c64.sgml b/doc/c64.sgml index 645b57491..9ab9b96c3 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -246,7 +246,7 @@ the standard setup without any memory loss or need for a changed configuration. You can use a mouse driver at the same time that you use a TGI driver. But, if you want to see the default mouse pointer on the graphics screen, then you explicitly must link a special object file into your program. It will put the -arrow into the "high RAM" area where the bitmaps are put. It's name is +arrow into the "high RAM" area where the bitmaps are put. Its name is "<tt/c64-tgimousedata.o/". Example: <tscreen><verb> From 038ac5a65a1f56af105635ceb2065af0a1a53ec0 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 22 Jan 2017 21:41:49 +0100 Subject: [PATCH 0186/2161] Correcting doc adding telemon 2.4 primitives --- doc/telemon24.sgml | 42 +++++ doc/telemon30.sgml | 177 +++++++++++++++++++++ libsrc/telemon24/_scrsize.s | 19 +++ libsrc/telemon24/crt0.s | 101 ++++++++++++ libsrc/telemon24/ctype.s | 299 +++++++++++++++++++++++++++++++++++ libsrc/telemon24/hires.s | 22 +++ libsrc/telemon24/mainargs.s | 36 +++++ libsrc/telemon24/oserrlist.s | 75 +++++++++ libsrc/telemon24/oserror.s | 17 ++ libsrc/telemon24/print.s | 25 +++ libsrc/telemon24/sysuname.s | 46 ++++++ libsrc/telemon24/tapehdr.s | 36 +++++ libsrc/telemon24/write.s | 59 +++++++ 13 files changed, 954 insertions(+) create mode 100644 doc/telemon24.sgml create mode 100644 doc/telemon30.sgml create mode 100644 libsrc/telemon24/_scrsize.s create mode 100644 libsrc/telemon24/crt0.s create mode 100644 libsrc/telemon24/ctype.s create mode 100644 libsrc/telemon24/hires.s create mode 100644 libsrc/telemon24/mainargs.s create mode 100644 libsrc/telemon24/oserrlist.s create mode 100644 libsrc/telemon24/oserror.s create mode 100644 libsrc/telemon24/print.s create mode 100644 libsrc/telemon24/sysuname.s create mode 100644 libsrc/telemon24/tapehdr.s create mode 100644 libsrc/telemon24/write.s diff --git a/doc/telemon24.sgml b/doc/telemon24.sgml new file mode 100644 index 000000000..b4e1befa1 --- /dev/null +++ b/doc/telemon24.sgml @@ -0,0 +1,42 @@ +<!doctype linuxdoc system> + +<article> + +<title>Oric Telemon 2.4 -specific information for cc65 +<author> + +<url url="mailto:greg.king5@verizon.net" name="Greg King"> +<date>2017-01-22 + +<abstract> +An overview over the Telemon 3.0 runtime system as it is implemented for the cc65 C +compiler. +</abstract> + +<!-- Table of contents --> +<toc> + + + +<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/telemon30.sgml b/doc/telemon30.sgml new file mode 100644 index 000000000..ce9e044b4 --- /dev/null +++ b/doc/telemon30.sgml @@ -0,0 +1,177 @@ +<!doctype linuxdoc system> + +<article> + +<title>Oric Telestrat-specific information for cc65 +<author> +<url url="mailto:jede@oric.org" name="Jede">,<newline> + +<date>2017-01-22 + +<abstract> +An overview over the Telestrat (telemon 3.0 : http://orix.oric.org) runtime system as it is implemented for the cc65 C +compiler. +</abstract> + +<!-- Table of contents --> +<toc> + +<!-- Begin the document --> + +<sect>Overview<p> + +This file contains an overview of the Telestrat runtime system as it comes with the +cc65 C compiler. It describes the memory layout, Telemon3.0-specific header files, +available drivers, and any pitfalls specific to that platform. + +Please note that Telemon3.0-specific functions are just mentioned here, they are +described in detail in the separate <url url="funcref.html" name="function +reference">. Even functions marked as "platform dependent" may be available on +more than one platform. Please see the function reference for more +information. + + + +<sect>Binary format<p> + +The standard binary output format generated by the linker for the Telemon 3.0 target +is a machine language program with a 20 bytes header described here : http://orix.oric.org/doku.php?id=orix:header + + + +<sect>Memory layout<p> + +In the standard setup, cc65-generated programs use the memory from +$0801 to $9800; so, nearly 37K of memory (including the stack) is +available. ROM calls are possible without further precautions. + + + +Special locations: + +<descrip> + <tag/Stack/ + The C runtime stack is located at $97FF (or $B3FF), and grows + downwards. + + <tag/Heap/ + The C heap is located at the end of the program, and grows towards the C + runtime stack. + +</descrip><p> + + + +<sect>Platform-specific header files<p> + +Programs containing Telemon 3.0 -specific code may use the <tt/telemon.h/ header file. + + +<sect1>Telemon 3.0-specific functions<p> + +The functions listed below are special for the Telemon 3.0. See the <url +url="funcref.html" name="function reference"> for declaration and usage. + +<itemize> +<item>explode +<item>ping +<item>shoot +<item>zap +<item>oupsx +</itemize> + + +<sect1>Hardware access<p> + +The following pseudo variables declared in the <tt/atmos.h/ header file do allow +access to hardware located in the address space. Some variables are +structures; accessing the struct fields will access the chip registers. + +<descrip> + + <tag><tt/VIA/</tag> + Access to the VIA (Versatile Interface Adapter) chip is available via the + <tt/VIA/ variable. The structure behind this variable is explained in <tt/_6522.h/. + +</descrip><p> + + + +<sect>Loadable drivers<p> + +<em>Note:</em> Since the Atmos doesn't have working disk I/O +(see <ref id="limitations" name="section "Limitations"">), the +available drivers cannot be loaded at runtime (so the term "loadable drivers" +is somewhat misleading). Instead, the drivers have to be statically linked. While +this may seem overhead, it has two advantages: + + +<sect1>Extended memory drivers<p> + +No extended memory drivers are currently available for the Atmos. + + +<sect1>Joystick drivers<p> + +<descrip> + +telemon 3.0 manages joysticks but it had been handled yet. + +</descrip><p> + + +<sect1>Mouse drivers<p> + +Telemon 3.0 manages also mouse, but it had been no handled yet in this version. + +<sect1>RS232 device drivers<p> + +<descrip> + +not done + +</descrip><p> + + + +<sect>Limitations<label id="limitations"><p> + +<sect1>Disk I/O<p> + +This version handles fopen, fread, fclose primitives. Because Telemon 3.0 handles these two primitives. By the way, +it uses an extension "ch376 card" which handles sdcard and FAT 32 usb key. + +<itemize> +<item>fclose +<item>fopen +<item>fread + +</itemize> + + + +<sect>Other hints<p> + + +<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/libsrc/telemon24/_scrsize.s b/libsrc/telemon24/_scrsize.s new file mode 100644 index 000000000..305e41c46 --- /dev/null +++ b/libsrc/telemon24/_scrsize.s @@ -0,0 +1,19 @@ +; +; 2003-04-13, Ullrich von Bassewitz +; 2013-07-16, Greg King +; +; Screen size variables +; + + .export screensize + .include "telemon24.inc" + +.proc screensize + + ldx #SCREEN_XSIZE + ldy #SCREEN_YSIZE + rts + +.endproc + + diff --git a/libsrc/telemon24/crt0.s b/libsrc/telemon24/crt0.s new file mode 100644 index 000000000..a3c92a360 --- /dev/null +++ b/libsrc/telemon24/crt0.s @@ -0,0 +1,101 @@ +; +; Startup code for cc65 (Oric version) +; +; By Debrune Jérôme <jede@oric.org> and Ullrich von Bassewitz <uz@cc65.org> +; 2016-03-18, Greg King +; + + .export _exit + .export __STARTUP__ : absolute = 1 ; Mark as startup + + .import initlib, donelib + .import callmain, zerobss + .import __MAIN_START__, __MAIN_SIZE__ + + .include "zeropage.inc" + .include "telemon24.inc" + +; ------------------------------------------------------------------------ +; Place the startup code in a special segment. + +.segment "STARTUP" + + tsx + stx spsave ; Save system stk ptr + +; Save space by putting some of the start-up code in a segment +; that will be re-used. + + jsr init + +; Clear the BSS variables (after the constructors have been run). + + jsr zerobss + +; Push the command-line arguments; and, call main(). + + jsr callmain + +; Call the module destructors. This is also the exit() entry. + +_exit: jsr donelib + +; Restore the system stuff. + + ldx spsave + txs +; lda stsave + ; sta STATUS + +; Copy back the zero-page stuff. + + ldx #zpspace - 1 +L2: lda zpsave,x + sta sp,x + dex + bpl L2 + +; Back to BASIC. + + rts + +; ------------------------------------------------------------------------ +; Put this code in a place that will be re-used by BSS, the heap, +; and the C stack. + +.segment "ONCE" + +; Save the zero-page area that we're about to use. + +init: ldx #zpspace - 1 +L1: lda sp,x + sta zpsave,x + dex + bpl L1 + +; Currently, color isn't supported on the text screen. +; Unprotect screen columns 0 and 1 (where each line's color codes would sit). + + ; lda STATUS + ; sta stsave + ; and #%11011111 + ; sta STATUS + +; Set up the C stack. + + lda #<(__MAIN_START__ + __MAIN_SIZE__) + ldx #>(__MAIN_START__ + __MAIN_SIZE__) + sta sp + stx sp+1 ; Set argument stack ptr + +; Call the module constructors. + + jmp initlib + +; ------------------------------------------------------------------------ + +.segment "INIT" + +spsave: .res 1 +stsave: .res 1 +zpsave: .res zpspace diff --git a/libsrc/telemon24/ctype.s b/libsrc/telemon24/ctype.s new file mode 100644 index 000000000..79edafbb2 --- /dev/null +++ b/libsrc/telemon24/ctype.s @@ -0,0 +1,299 @@ +; +; Ullrich von Bassewitz, 2003-04-13 +; +; Character specification table. +; + +; The tables are readonly, put them into the rodata segment + +.rodata + +; The following 256 byte wide table specifies attributes for the isxxx type +; of functions. Doing it by a table means some overhead in space, but it +; has major advantages: +; +; * It is fast. If it were'nt for the slow parameter passing of cc65, one +; could even define macros for the isxxx functions (this is usually +; done on other platforms). +; +; * It is highly portable. The only unportable part is the table itself, +; all real code goes into the common library. +; +; * We save some code in the isxxx functions. +; +; +; Bit assignments: +; +; 0 - Lower case char +; 1 - Upper case char +; 2 - Numeric digit +; 3 - Hex digit (both, lower and upper) +; 4 - Control character +; 5 - The space character itself +; 6 - Other whitespace (that is: '\f', '\n', '\r', '\t' and '\v') +; 7 - Space or tab character + + .export __ctype + +__ctype: + .byte $10 ; 0/00 ___ctrl_@___ + .byte $10 ; 1/01 ___ctrl_A___ + .byte $10 ; 2/02 ___ctrl_B___ + .byte $10 ; 3/03 ___ctrl_C___ + .byte $10 ; 4/04 ___ctrl_D___ + .byte $10 ; 5/05 ___ctrl_E___ + .byte $10 ; 6/06 ___ctrl_F___ + .byte $10 ; 7/07 ___ctrl_G___ + .byte $10 ; 8/08 ___ctrl_H___ + .byte $D0 ; 9/09 ___ctrl_I___ + .byte $50 ; 10/0a ___ctrl_J___ + .byte $50 ; 11/0b ___ctrl_K___ + .byte $50 ; 12/0c ___ctrl_L___ + .byte $50 ; 13/0d ___ctrl_M___ + .byte $10 ; 14/0e ___ctrl_N___ + .byte $10 ; 15/0f ___ctrl_O___ + .byte $10 ; 16/10 ___ctrl_P___ + .byte $10 ; 17/11 ___ctrl_Q___ + .byte $10 ; 18/12 ___ctrl_R___ + .byte $10 ; 19/13 ___ctrl_S___ + .byte $10 ; 20/14 ___ctrl_T___ + .byte $10 ; 21/15 ___ctrl_U___ + .byte $10 ; 22/16 ___ctrl_V___ + .byte $10 ; 23/17 ___ctrl_W___ + .byte $10 ; 24/18 ___ctrl_X___ + .byte $10 ; 25/19 ___ctrl_Y___ + .byte $10 ; 26/1a ___ctrl_Z___ + .byte $10 ; 27/1b ___ctrl_[___ + .byte $10 ; 28/1c ___ctrl_\___ + .byte $10 ; 29/1d ___ctrl_]___ + .byte $10 ; 30/1e ___ctrl_^___ + .byte $10 ; 31/1f ___ctrl_____ + .byte $A0 ; 32/20 ___SPACE___ + .byte $00 ; 33/21 _____!_____ + .byte $00 ; 34/22 _____"_____ + .byte $00 ; 35/23 _____#_____ + .byte $00 ; 36/24 _____$_____ + .byte $00 ; 37/25 _____%_____ + .byte $00 ; 38/26 _____&_____ + .byte $00 ; 39/27 _____'_____ + .byte $00 ; 40/28 _____(_____ + .byte $00 ; 41/29 _____)_____ + .byte $00 ; 42/2a _____*_____ + .byte $00 ; 43/2b _____+_____ + .byte $00 ; 44/2c _____,_____ + .byte $00 ; 45/2d _____-_____ + .byte $00 ; 46/2e _____._____ + .byte $00 ; 47/2f _____/_____ + .byte $0C ; 48/30 _____0_____ + .byte $0C ; 49/31 _____1_____ + .byte $0C ; 50/32 _____2_____ + .byte $0C ; 51/33 _____3_____ + .byte $0C ; 52/34 _____4_____ + .byte $0C ; 53/35 _____5_____ + .byte $0C ; 54/36 _____6_____ + .byte $0C ; 55/37 _____7_____ + .byte $0C ; 56/38 _____8_____ + .byte $0C ; 57/39 _____9_____ + .byte $00 ; 58/3a _____:_____ + .byte $00 ; 59/3b _____;_____ + .byte $00 ; 60/3c _____<_____ + .byte $00 ; 61/3d _____=_____ + .byte $00 ; 62/3e _____>_____ + .byte $00 ; 63/3f _____?_____ + + .byte $00 ; 64/40 _____@_____ + .byte $0A ; 65/41 _____A_____ + .byte $0A ; 66/42 _____B_____ + .byte $0A ; 67/43 _____C_____ + .byte $0A ; 68/44 _____D_____ + .byte $0A ; 69/45 _____E_____ + .byte $0A ; 70/46 _____F_____ + .byte $02 ; 71/47 _____G_____ + .byte $02 ; 72/48 _____H_____ + .byte $02 ; 73/49 _____I_____ + .byte $02 ; 74/4a _____J_____ + .byte $02 ; 75/4b _____K_____ + .byte $02 ; 76/4c _____L_____ + .byte $02 ; 77/4d _____M_____ + .byte $02 ; 78/4e _____N_____ + .byte $02 ; 79/4f _____O_____ + .byte $02 ; 80/50 _____P_____ + .byte $02 ; 81/51 _____Q_____ + .byte $02 ; 82/52 _____R_____ + .byte $02 ; 83/53 _____S_____ + .byte $02 ; 84/54 _____T_____ + .byte $02 ; 85/55 _____U_____ + .byte $02 ; 86/56 _____V_____ + .byte $02 ; 87/57 _____W_____ + .byte $02 ; 88/58 _____X_____ + .byte $02 ; 89/59 _____Y_____ + .byte $02 ; 90/5a _____Z_____ + .byte $00 ; 91/5b _____[_____ + .byte $00 ; 92/5c _____\_____ + .byte $00 ; 93/5d _____]_____ + .byte $00 ; 94/5e _____^_____ + .byte $00 ; 95/5f _UNDERLINE_ + .byte $00 ; 96/60 ___grave___ + .byte $09 ; 97/61 _____a_____ + .byte $09 ; 98/62 _____b_____ + .byte $09 ; 99/63 _____c_____ + .byte $09 ; 100/64 _____d_____ + .byte $09 ; 101/65 _____e_____ + .byte $09 ; 102/66 _____f_____ + .byte $01 ; 103/67 _____g_____ + .byte $01 ; 104/68 _____h_____ + .byte $01 ; 105/69 _____i_____ + .byte $01 ; 106/6a _____j_____ + .byte $01 ; 107/6b _____k_____ + .byte $01 ; 108/6c _____l_____ + .byte $01 ; 109/6d _____m_____ + .byte $01 ; 110/6e _____n_____ + .byte $01 ; 111/6f _____o_____ + .byte $01 ; 112/70 _____p_____ + .byte $01 ; 113/71 _____q_____ + .byte $01 ; 114/72 _____r_____ + .byte $01 ; 115/73 _____s_____ + .byte $01 ; 116/74 _____t_____ + .byte $01 ; 117/75 _____u_____ + .byte $01 ; 118/76 _____v_____ + .byte $01 ; 119/77 _____w_____ + .byte $01 ; 120/78 _____x_____ + .byte $01 ; 121/79 _____y_____ + .byte $01 ; 122/7a _____z_____ + .byte $00 ; 123/7b _____{_____ + .byte $00 ; 124/7c _____|_____ + .byte $00 ; 125/7d _____}_____ + .byte $00 ; 126/7e _____~_____ + .byte $40 ; 127/7f ____DEL____ + + .byte $00 ; 128/80 ___________ + .byte $00 ; 129/81 ___________ + .byte $00 ; 130/82 ___________ + .byte $00 ; 131/83 ___________ + .byte $00 ; 132/84 ___________ + .byte $00 ; 133/85 ___________ + .byte $00 ; 134/86 ___________ + .byte $00 ; 135/87 ___________ + .byte $00 ; 136/88 ___________ + .byte $00 ; 137/89 ___________ + .byte $00 ; 138/8a ___________ + .byte $00 ; 139/8b ___________ + .byte $00 ; 140/8c ___________ + .byte $00 ; 141/8d ___________ + .byte $00 ; 142/8e ___________ + .byte $00 ; 143/8f ___________ + .byte $00 ; 144/90 ___________ + .byte $00 ; 145/91 ___________ + .byte $00 ; 146/92 ___________ + .byte $10 ; 147/93 ___________ + .byte $00 ; 148/94 ___________ + .byte $00 ; 149/95 ___________ + .byte $00 ; 150/96 ___________ + .byte $00 ; 151/97 ___________ + .byte $00 ; 152/98 ___________ + .byte $00 ; 153/99 ___________ + .byte $00 ; 154/9a ___________ + .byte $00 ; 155/9b ___________ + .byte $00 ; 156/9c ___________ + .byte $00 ; 157/9d ___________ + .byte $00 ; 158/9e ___________ + .byte $00 ; 159/9f ___________ + + .byte $00 ; 160/a0 ___________ + .byte $00 ; 161/a1 ___________ + .byte $00 ; 162/a2 ___________ + .byte $00 ; 163/a3 ___________ + .byte $00 ; 164/a4 ___________ + .byte $00 ; 165/a5 ___________ + .byte $00 ; 166/a6 ___________ + .byte $00 ; 167/a7 ___________ + .byte $00 ; 168/a8 ___________ + .byte $00 ; 169/a9 ___________ + .byte $00 ; 170/aa ___________ + .byte $00 ; 171/ab ___________ + .byte $00 ; 172/ac ___________ + .byte $00 ; 173/ad ___________ + .byte $00 ; 174/ae ___________ + .byte $00 ; 175/af ___________ + .byte $00 ; 176/b0 ___________ + .byte $00 ; 177/b1 ___________ + .byte $00 ; 178/b2 ___________ + .byte $00 ; 179/b3 ___________ + .byte $00 ; 180/b4 ___________ + .byte $00 ; 181/b5 ___________ + .byte $00 ; 182/b6 ___________ + .byte $00 ; 183/b7 ___________ + .byte $00 ; 184/b8 ___________ + .byte $00 ; 185/b9 ___________ + .byte $00 ; 186/ba ___________ + .byte $00 ; 187/bb ___________ + .byte $00 ; 188/bc ___________ + .byte $00 ; 189/bd ___________ + .byte $00 ; 190/be ___________ + .byte $00 ; 191/bf ___________ + + .byte $02 ; 192/c0 ___________ + .byte $02 ; 193/c1 ___________ + .byte $02 ; 194/c2 ___________ + .byte $02 ; 195/c3 ___________ + .byte $02 ; 196/c4 ___________ + .byte $02 ; 197/c5 ___________ + .byte $02 ; 198/c6 ___________ + .byte $02 ; 199/c7 ___________ + .byte $02 ; 200/c8 ___________ + .byte $02 ; 201/c9 ___________ + .byte $02 ; 202/ca ___________ + .byte $02 ; 203/cb ___________ + .byte $02 ; 204/cc ___________ + .byte $02 ; 205/cd ___________ + .byte $02 ; 206/ce ___________ + .byte $02 ; 207/cf ___________ + .byte $02 ; 208/d0 ___________ + .byte $02 ; 209/d1 ___________ + .byte $02 ; 210/d2 ___________ + .byte $02 ; 211/d3 ___________ + .byte $02 ; 212/d4 ___________ + .byte $02 ; 213/d5 ___________ + .byte $02 ; 214/d6 ___________ + .byte $02 ; 215/d7 ___________ + .byte $02 ; 216/d8 ___________ + .byte $02 ; 217/d9 ___________ + .byte $02 ; 218/da ___________ + .byte $02 ; 219/db ___________ + .byte $02 ; 220/dc ___________ + .byte $02 ; 221/dd ___________ + .byte $02 ; 222/de ___________ + .byte $00 ; 223/df ___________ + .byte $01 ; 224/e0 ___________ + .byte $01 ; 225/e1 ___________ + .byte $01 ; 226/e2 ___________ + .byte $01 ; 227/e3 ___________ + .byte $01 ; 228/e4 ___________ + .byte $01 ; 229/e5 ___________ + .byte $01 ; 230/e6 ___________ + .byte $01 ; 231/e7 ___________ + .byte $01 ; 232/e8 ___________ + .byte $01 ; 233/e9 ___________ + .byte $01 ; 234/ea ___________ + .byte $01 ; 235/eb ___________ + .byte $01 ; 236/ec ___________ + .byte $01 ; 237/ed ___________ + .byte $01 ; 238/ee ___________ + .byte $01 ; 239/ef ___________ + .byte $01 ; 240/f0 ___________ + .byte $01 ; 241/f1 ___________ + .byte $01 ; 242/f2 ___________ + .byte $01 ; 243/f3 ___________ + .byte $01 ; 244/f4 ___________ + .byte $01 ; 245/f5 ___________ + .byte $01 ; 246/f6 ___________ + .byte $01 ; 247/f7 ___________ + .byte $01 ; 248/f8 ___________ + .byte $01 ; 249/f9 ___________ + .byte $01 ; 250/fa ___________ + .byte $01 ; 251/fb ___________ + .byte $01 ; 252/fc ___________ + .byte $01 ; 253/fd ___________ + .byte $01 ; 254/fe ___________ + .byte $00 ; 255/ff ___________ + diff --git a/libsrc/telemon24/hires.s b/libsrc/telemon24/hires.s new file mode 100644 index 000000000..80d67824c --- /dev/null +++ b/libsrc/telemon24/hires.s @@ -0,0 +1,22 @@ +; +; Ullrich von Bassewitz, 2003-04-13 +; +; void hires(void); +; +; This function is a hack! +; + + .export _hires + + + .include "telemon24.inc" + + +; can be optimized with a macro +.proc _hires + brk + .byt $1a + rts +.endproc + + diff --git a/libsrc/telemon24/mainargs.s b/libsrc/telemon24/mainargs.s new file mode 100644 index 000000000..d8547e500 --- /dev/null +++ b/libsrc/telemon24/mainargs.s @@ -0,0 +1,36 @@ +; +; 2003-03-07, Ullrich von Bassewitz +; 2011-01-28, Stefan Haubenthal +; 2014-09-10, Greg King +; +; Set up arguments for main +; + + .constructor initmainargs, 24 + .import __argc, __argv + + .include "telemon24.inc" + .macpack generic + +MAXARGS = 10 ; Maximum number of arguments allowed + + +.segment "ONCE" + +.proc initmainargs + +.endproc + +.segment "INIT" + +term: .res 1 +name: .res FNAME_LEN + 1 +args: .res SCREEN_XSIZE * 2 - 1 + +.data + +; This array has zeroes when initmainargs starts. +; char* argv[MAXARGS+1]={name}; + +argv: .addr name + .res MAXARGS * 2 diff --git a/libsrc/telemon24/oserrlist.s b/libsrc/telemon24/oserrlist.s new file mode 100644 index 000000000..8ec41de6d --- /dev/null +++ b/libsrc/telemon24/oserrlist.s @@ -0,0 +1,75 @@ +; +; Stefan Haubenthal, 2004-05-25 +; Ullrich von Bassewitz, 18.07.2002 +; +; Defines the platform specific error list. +; +; The table is built as a list of entries +; +; .byte entrylen +; .byte errorcode +; .asciiz errormsg +; +; and terminated by an entry with length zero that is returned if the +; error code could not be found. +; + + .export __sys_oserrlist + +;---------------------------------------------------------------------------- +; Macros used to generate the list (may get moved to an include file?) + +; Regular entry +.macro sys_oserr_entry code, msg + .local Start, End +Start: .byte End - Start + .byte code + .asciiz msg +End: +.endmacro + +; Sentinel entry +.macro sys_oserr_sentinel msg + .byte 0 ; Length is always zero + .byte 0 ; Code is unused + .asciiz msg +.endmacro + +;---------------------------------------------------------------------------- +; The error message table + +.rodata + +__sys_oserrlist: + sys_oserr_entry 1, "File not found" + sys_oserr_entry 2, "Invalid command end" + sys_oserr_entry 3, "No drive number" + sys_oserr_entry 4, "Bad drive number" + sys_oserr_entry 5, "Invalid filename" + sys_oserr_entry 6, "fderr=(error number)" + sys_oserr_entry 7, "Illegal attribute" + sys_oserr_entry 8, "Wildcard(s) not allowed" + sys_oserr_entry 9, "File already exists" + sys_oserr_entry 10, "Insufficient disc space" + sys_oserr_entry 11, "File open" + sys_oserr_entry 12, "Illegal quantity" + sys_oserr_entry 13, "End address missing" + sys_oserr_entry 14, "Start address > end address" + sys_oserr_entry 15, "Missing 'to'" + sys_oserr_entry 16, "Renamed file not on same disc" + sys_oserr_entry 17, "Unknown array" + sys_oserr_entry 18, "Target drive not source drive" + sys_oserr_entry 19, "Destination not specified" + sys_oserr_entry 20, "Cannot merge and overwrite" + sys_oserr_entry 21, "Single target file illegal" + sys_oserr_entry 22, "Syntax" + sys_oserr_entry 23, "Filename missing" + sys_oserr_entry 24, "Source file missing" + sys_oserr_entry 25, "Type mismatch" + sys_oserr_entry 26, "Disc write-protected" + sys_oserr_entry 27, "Incompatible drives" + sys_oserr_entry 28, "File not open" + sys_oserr_entry 29, "File end" + sys_oserr_sentinel "Unknown error" + + diff --git a/libsrc/telemon24/oserror.s b/libsrc/telemon24/oserror.s new file mode 100644 index 000000000..37c9bd7fc --- /dev/null +++ b/libsrc/telemon24/oserror.s @@ -0,0 +1,17 @@ +; +; Stefan Haubenthal, 2011-04-18 +; +; int __fastcall__ _osmaperrno (unsigned char oserror); +; /* Map a system specific error into a system independent code */ +; + + .include "errno.inc" + .export __osmaperrno + +.proc __osmaperrno + + lda #<EUNKNOWN + ldx #>EUNKNOWN + rts + +.endproc diff --git a/libsrc/telemon24/print.s b/libsrc/telemon24/print.s new file mode 100644 index 000000000..a135cdd18 --- /dev/null +++ b/libsrc/telemon24/print.s @@ -0,0 +1,25 @@ +; +; Jede +; +; print (char * str); +; +; This function is a hack! +; + + .export _print + .import popax + .importzp tmp1 + .include "telemon24.inc" + +.proc _print + + jsr popax ; get buf + stx tmp1 + ldy tmp1 + brk + .byte $14 + rts + +.endproc + + diff --git a/libsrc/telemon24/sysuname.s b/libsrc/telemon24/sysuname.s new file mode 100644 index 000000000..51af1d8fe --- /dev/null +++ b/libsrc/telemon24/sysuname.s @@ -0,0 +1,46 @@ +; +; 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 ((.VERSION >> 8) & $0F) + '0' + .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 $00 + + ; version + .if (.VERSION & $0F) > 9 + .byte (.VERSION & $0F) / 10 + '0' + .byte (.VERSION & $0F) .MOD 10 + '0' + .else + .byte (.VERSION & $0F) + '0' + .endif + .byte $00 + + ; machine + .asciiz "Oric Telestrat" diff --git a/libsrc/telemon24/tapehdr.s b/libsrc/telemon24/tapehdr.s new file mode 100644 index 000000000..9b183e11e --- /dev/null +++ b/libsrc/telemon24/tapehdr.s @@ -0,0 +1,36 @@ +; +; Based on code by Debrune Jérôme <jede@oric.org> +; 2016-03-17, Greg King +; + + ; The following symbol is used by the linker config. file + ; to force this module to be included into the output file. + .export __ORIXHDR__:abs = 1 + + ; These symbols, also, come from the configuration file. + .import __AUTORUN__, __PROGFLAG__ + .import __BASHEAD_START__, __MAIN_LAST__ + + +; ------------------------------------------------------------------------ +; Oric cassette-tape header + +.segment "ORIXHDR" + + .byte $01, $00 ; + + .byte "ORI" + + .byte $01 ; version + .byte $00,$00 ; mode + .byte $00,$00 ; cpu type + .byte $00,$00 ; OS + + .byte $00 ; reserved + .byte $00 ; auto + + + .dbyt __BASHEAD_START__ ; Address of start of file + .dbyt __MAIN_LAST__ - 1 ; Address of end of file + .dbyt __BASHEAD_START__ ; Address of start of file + diff --git a/libsrc/telemon24/write.s b/libsrc/telemon24/write.s new file mode 100644 index 000000000..32bbf617c --- /dev/null +++ b/libsrc/telemon24/write.s @@ -0,0 +1,59 @@ +; +; Ullrich von Bassewitz, 2003-04-13 +; +; int write (int fd, const void* buf, int count); +; +; This function is a hack! +; + + .export _write + .import popax + .importzp ptr1, ptr2, ptr3, tmp1 + + .include "telemon24.inc" + +.proc _write + + sta ptr3 + stx ptr3+1 ; save count as result + + eor #$FF + sta ptr2 + txa + eor #$FF + sta ptr2+1 ; Remember -count-1 + + jsr popax ; get buf + sta ptr1 + stx ptr1+1 + jsr popax ; get fd and discard +L1: inc ptr2 + bne L2 + inc ptr2+1 + beq L9 +L2: ldy #0 + lda (ptr1),y + tax + cpx #$0A ; Check for \n + bne L3 + brk + .byt $10 + + ldx #$0D +L3: + brk + .byt $10 + inc ptr1 + bne L1 + inc ptr1+1 + jmp L1 + +; No error, return count + +L9: lda ptr3 + ldx ptr3+1 + rts + +.endproc + + From 6f463d60a3c9c61f35fc97a9fbf1ca52282bf5df Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 24 Jan 2017 20:21:56 +0100 Subject: [PATCH 0187/2161] Small space optimization in libsrc/atari/is_cmdline_dos.s. --- libsrc/atari/is_cmdline_dos.s | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libsrc/atari/is_cmdline_dos.s b/libsrc/atari/is_cmdline_dos.s index 71b35fbad..eb474dbfb 100644 --- a/libsrc/atari/is_cmdline_dos.s +++ b/libsrc/atari/is_cmdline_dos.s @@ -11,10 +11,9 @@ .include "atari.inc" __is_cmdline_dos: - ldx #0 lda __dos_type cmp #MAX_DOS_WITH_CMDLINE + 1 - txa + lda #0 rol a eor #$01 rts From f613ee0f5737d28392232f8cdeaa61249b5e40cc Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 24 Jan 2017 21:01:42 +0100 Subject: [PATCH 0188/2161] More optimization in libsrc/atari/is_cmdline_dos.s. Suggestion by Spiro Trikaliotis. --- libsrc/atari/is_cmdline_dos.s | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libsrc/atari/is_cmdline_dos.s b/libsrc/atari/is_cmdline_dos.s index eb474dbfb..2a9c49e38 100644 --- a/libsrc/atari/is_cmdline_dos.s +++ b/libsrc/atari/is_cmdline_dos.s @@ -11,9 +11,8 @@ .include "atari.inc" __is_cmdline_dos: - lda __dos_type - cmp #MAX_DOS_WITH_CMDLINE + 1 + lda #MAX_DOS_WITH_CMDLINE + cmp __dos_type lda #0 rol a - eor #$01 rts From bba7c980e44545cdb63bce4084f425a31ee8edec Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 26 Jan 2017 16:43:47 +0100 Subject: [PATCH 0189/2161] libsrc/c16/get_tv.s: remove code duplication Use the plus4 version of get_tv.s. --- libsrc/c16/get_tv.s | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/libsrc/c16/get_tv.s b/libsrc/c16/get_tv.s index f6d82a351..1bfe3db97 100644 --- a/libsrc/c16/get_tv.s +++ b/libsrc/c16/get_tv.s @@ -1,27 +1 @@ -; -; Ullrich von Bassewitz, 2002-12-03 -; -; unsigned char __fastcall__ get_tv (void); -; /* Return the video mode the machine is using */ -; - - .include "plus4.inc" - .include "get_tv.inc" - - -;-------------------------------------------------------------------------- -; _get_tv - -.proc _get_tv - - ldx #TV::PAL ; Assume PAL - bit TED_MULTI1 ; Test bit 6 - bvc pal - dex ; NTSC -pal: txa - ldx #0 - rts - -.endproc - - +.include "../plus4/get_tv.s" From d1b5a6632d558c0ffb9b89f1cbf239ae04533b90 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 29 Jan 2017 21:18:49 +0100 Subject: [PATCH 0190/2161] Adding telemon30 and telemon24 primitives --- asminc/telemon24.inc | 68 ++++++++ asminc/telemon30.inc | 150 ++++++++++++++++++ cfg/telemon24.cfg | 43 +++++ include/telemon30.h | 21 +++ libsrc/telemon30/_close.s | 17 ++ libsrc/telemon30/_open.s | 60 ++----- libsrc/telemon30/_read.s | 46 ++++-- libsrc/telemon30/ch376.s | 307 +++++++++++++++++++++++++++--------- libsrc/telemon30/graphics.s | 13 +- libsrc/telemon30/orixhdr.s | 15 +- libsrc/telemon30/write.s | 22 +++ 11 files changed, 616 insertions(+), 146 deletions(-) create mode 100644 asminc/telemon24.inc create mode 100644 asminc/telemon30.inc create mode 100644 cfg/telemon24.cfg create mode 100644 include/telemon30.h create mode 100644 libsrc/telemon30/_close.s diff --git a/asminc/telemon24.inc b/asminc/telemon24.inc new file mode 100644 index 000000000..0b58d63a6 --- /dev/null +++ b/asminc/telemon24.inc @@ -0,0 +1,68 @@ +; +; Oric Telemon definition +; Telemon 2.4 +; + + +; --------------------------------------------------------------------------- +; Constants + +SCREEN_XSIZE = 40 ; screen columns +SCREEN_YSIZE = 28 ; screen rows + +FUNCTKEY = $A5 + +FNAME_LEN = 11 ; maximum length of file-name + + +; --------------------------------------------------------------------------- +; Zero page + + + + +; --------------------------------------------------------------------------- +; Low memory + + + + +; --------------------------------------------------------------------------- +; I/O locations + +; 6522 +.struct VIA ; Versatile Interface Adapter + .res $0300 +PRB .byte ; Port Register B +PRA .byte ; Port Register A +DDRB .byte ; Data Direction Register B +DDRA .byte ; Data Direction Register A +T1 .word ; Timer 1 +T1L .word ; Timer 1 Latch +T2 .word ; Timer 2 +SR .byte ; Shift Register +ACR .byte ; Auxiliary Control Register +PCR .byte ; Peripheral Control Register +IFR .byte ; Interrupt Flags Register +IER .byte ; Interrupt Enable Register +PRA2 .byte ; Port Register A without handshaking +.endstruct + +; 6551 +.struct ACIA ; Asynchronous Communications Interface Adapter + .res $031C +DATA .byte +STATUS .byte +CMD .byte ; Command register +CTRL .byte ; Control register +.endstruct + +SCREEN := $BB80 + + +; --------------------------------------------------------------------------- +; ROM entries + +XWR0 := $10 +XWSTR0 := $14 + diff --git a/asminc/telemon30.inc b/asminc/telemon30.inc new file mode 100644 index 000000000..acfd7e919 --- /dev/null +++ b/asminc/telemon30.inc @@ -0,0 +1,150 @@ +; +; Oric Telemon definition +; Telemon 2.4 +; + + +; --------------------------------------------------------------------------- +; Constants + +SCREEN_XSIZE = 40 ; screen columns +SCREEN_YSIZE = 28 ; screen rows + +FUNCTKEY = $A5 + +FNAME_LEN = 11 ; maximum length of file-name + + +; --------------------------------------------------------------------------- +; Zero page + + + + +; --------------------------------------------------------------------------- +; Low memory + + + + +; --------------------------------------------------------------------------- +; I/O locations + +; 6522 +.struct VIA ; Versatile Interface Adapter + .res $0300 +PRB .byte ; Port Register B +PRA .byte ; Port Register A +DDRB .byte ; Data Direction Register B +DDRA .byte ; Data Direction Register A +T1 .word ; Timer 1 +T1L .word ; Timer 1 Latch +T2 .word ; Timer 2 +SR .byte ; Shift Register +ACR .byte ; Auxiliary Control Register +PCR .byte ; Peripheral Control Register +IFR .byte ; Interrupt Flags Register +IER .byte ; Interrupt Enable Register +PRA2 .byte ; Port Register A without handshaking +.endstruct + + +.struct VIA2 ; Versatile Interface Adapter + .res $0320 +PRB .byte ; Port Register B +PRA .byte ; Port Register A +DDRB .byte ; Data Direction Register B +DDRA .byte ; Data Direction Register A +T1 .word ; Timer 1 +T1L .word ; Timer 1 Latch +T2 .word ; Timer 2 +SR .byte ; Shift Register +ACR .byte ; Auxiliary Control Register +PCR .byte ; Peripheral Control Register +IFR .byte ; Interrupt Flags Register +IER .byte ; Interrupt Enable Register +PRA2 .byte ; Port Register A without handshaking +.endstruct + +; 6551 +.struct ACIA ; Asynchronous Communications Interface Adapter + .res $031C +DATA .byte +STATUS .byte +CMD .byte ; Command register +CTRL .byte ; Control register +.endstruct + +SCREEN := $BB80 + + +; --------------------------------------------------------------------------- +; ROM entries + +; primitives telemon 2.4 +XRD0 := $08 +XRDW0 := $0c +XWR0 := $10 +XWSTR0 := $14 +XTEXT := $19 +XHIRES := $1A +XMINMA := $1f +XFREAD := $27 ; only in TELEMON 3.0 +XOPEN := $30 ; only in TELEMON 3.0 +XCOSCR := $34 ; switch off cursor +XCSSCR := $35 ; switch on cursor +XCLOSE := $3a ; Close file +XFWRITE:= $3b ; write + +XSONPS := $40 +XOUPS := $42 +XPLAY := $43 +XSOUND := $44 +XMUSIC := $45 +XZAP := $46 +XSHOOT := $47 +XCIRCL := $8f +XCURSE := $90 +XEXPLO := $9c +XPING := $9d +XPAPER := $92 +XINK := $93 + + +; --------------------------------------------------------------------------- +; Page 00 +RES := $00 +RESB := $02 + +TR0 := $0c +TR1 := $0d + +PTR_READ_DEST := $2c ; used for XFREAD and XWRITE + +HRSX := $46 +HRSY := $47 + +HRS1 := $4D +HRS2 := $4F +HRS3 := $51 +HRS4 := $53 +HRS5 := $55 + +; --------------------------------------------------------------------------- +; Page $500 + +BUFNOM := $517 +BUFEDT := $590 + +MAX_BUFEDT_LENGTH=110 + +; Hardware +CH376_DATA :=$340 +CH376_COMMAND :=$341 + +; MACRO + + +.macro BRK_TELEMON value + .byte $00,value +.endmacro diff --git a/cfg/telemon24.cfg b/cfg/telemon24.cfg new file mode 100644 index 000000000..b76350868 --- /dev/null +++ b/cfg/telemon24.cfg @@ -0,0 +1,43 @@ +SYMBOLS { + + __ORIXHDR__: type = import; + + __STACKSIZE__: type = weak, value = $0800; # 2K stack + + __RAMEND__: type = weak, value = $9800 + $1C00 ; +} +MEMORY { + ZP: file = "", define = yes, start = $00E2, size = $001A; + ORIXHDR: file = %O, type = ro, start = $0000, size = $001F; + BASHEAD: file = %O, define = yes, start = $0801, size = $000D; + MAIN: file = %O, define = yes, start = __BASHEAD_LAST__, size = __RAMEND__ - __MAIN_START__; + BSS: file = "", start = __ONCE_RUN__, size = __RAMEND__ - __STACKSIZE__ - __ONCE_RUN__; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + ORIXHDR: load = ORIXHDR, 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; + ONCE: load = MAIN, type = ro, define = yes; + BASTAIL: load = MAIN, type = ro, optional = 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/telemon30.h b/include/telemon30.h new file mode 100644 index 000000000..73b018444 --- /dev/null +++ b/include/telemon30.h @@ -0,0 +1,21 @@ + +void print (char *); + +void hires(); +void text(); +void oups(); +void ping(); +void zap(); +void shoot(); +void explode(); + +void paper(char color); +void ink(char color); + +void kbdclick1(); + +void curset(char x,char y, char display, char display); +void circle(char rayon); + + + diff --git a/libsrc/telemon30/_close.s b/libsrc/telemon30/_close.s new file mode 100644 index 000000000..84bee3a1b --- /dev/null +++ b/libsrc/telemon30/_close.s @@ -0,0 +1,17 @@ + .export _close + .import addysp,popax + .importzp sp,tmp2,tmp3,tmp1 + + ; int open (const char* name, int flags, ...); /* May take a mode argument */ + .include "telemon30.inc" + .include "errno.inc" + .include "fcntl.inc" + +.proc _close +; Throw away any additional parameters passed through the ellipsis + + BRK_TELEMON XCLOSE ; launch primitive ROM + rts +.endproc + + \ No newline at end of file diff --git a/libsrc/telemon30/_open.s b/libsrc/telemon30/_open.s index a002bbce1..7ea2d8310 100644 --- a/libsrc/telemon30/_open.s +++ b/libsrc/telemon30/_open.s @@ -1,11 +1,12 @@ .export _open .import addysp,popax - .importzp sp,tmp2,tmp3,tmp1 - ; int open (const char* name, int flags, ...); /* May take a mode argument */ - .include "telemon30.inc" - .include "errno.inc" - .include "fcntl.inc" + .importzp sp,tmp2,tmp3,tmp1 + ; int open (const char* name, int flags, ...); /* May take a mode argument */ + .include "telemon30.inc" + .include "errno.inc" + .include "fcntl.inc" + .proc _open ; Throw away any additional parameters passed through the ellipsis @@ -13,53 +14,18 @@ dey ; ...checked (it generates a c compiler warning) dey dey - beq parmok ; Branch if parameter count ok - jsr addysp ; Fix stack, throw away unused parameters + beq parmok ; Branch if parameter count ok + jsr addysp ; Fix stack, throw away unused parameters ; Parameters ok. Pop the flags and save them into tmp3 -parmok: jsr popax ; Get flagss - sta tmp3 ; save flags - - ;AND #O_RDONLY - ;beq READONLY - ;lda tmp3 - ;AND #O_WRONLY - ;beq WRITEONLY - ;jmp next - -;READONLY: -; lda #'r' -; BRK_TELEMON XWR0 -; jmp next -;WRITEONLY: -; lda #'w' -; BRK_TELEMON XWR0 - -;next: +parmok: jsr popax ; Get flagss + sta tmp3 ; save flags ; Get the filename from stack and parse it. Bail out if is not ok - jsr popax ; Get name - - - ldy tmp3 ; Get flags - - - BRK_TELEMON XOPEN - - ; jsr fnparse ; Parse it - ;tax - ;bne oserror ; Bail out if problem with name - -; Get a free file handle and remember it in tmp2 - - ; jsr freefd - ;lda #EMFILE ; Load error code - ;bcs seterrno ; Jump in case of errors - ;stx tmp2 -; - - + jsr popax ; Get name + ldy tmp3 ; Get flags again + BRK_TELEMON XOPEN ; launch primitive ROM rts .endproc diff --git a/libsrc/telemon30/_read.s b/libsrc/telemon30/_read.s index 8f7a20a58..e8bcc3fd0 100644 --- a/libsrc/telemon30/_read.s +++ b/libsrc/telemon30/_read.s @@ -1,29 +1,45 @@ ; -; Ullrich von Bassewitz, 2003-04-13 +; jede jede@oric.org 2017-01-22 ; -; + .FEATURE c_comments,labels_without_colons,pc_assignment, loose_char_term .export _read .import popax - .importzp ptr1, ptr2, ptr3, tmp1, tmp2 - + + .include "zeropage.inc" .include "telemon30.inc" ; int read (int fd, void* buf, unsigned count); .proc _read - ;jsr popax ; fp pointer don't care - sta tmp1 ; count - stx tmp2 ; count - jsr popax ; get buf - ;lda #$00 - ;ldx #$a0 - sta PTR_READ_DEST - stx PTR_READ_DEST+1 - lda tmp1 ; - ldy tmp2 ; - BRK_TELEMON XFREAD + + sta ptr1 ; count + stx ptr1+1 ; count + jsr popax ; get buf + sta PTR_READ_DEST + stx PTR_READ_DEST+1 + sta ptr2 ; in order to calculate nb of bytes read + stx ptr2+1 ; + + ;jsr popax ; fp pointer don't care in this version + + lda ptr1 ; + ldy ptr1+1 ; + BRK_TELEMON XFREAD ; calls telemon30 routine + ; compute nb of bytes read + lda PTR_READ_DEST+1 + sec + sbc ptr2+1 + tax + lda PTR_READ_DEST + sec + sbc ptr2 + + + + ; Here A and X contains number of bytes read + rts .endproc diff --git a/libsrc/telemon30/ch376.s b/libsrc/telemon30/ch376.s index 24df14471..97245add9 100644 --- a/libsrc/telemon30/ch376.s +++ b/libsrc/telemon30/ch376.s @@ -1,5 +1,5 @@ - ; For XA65 compatibily in the futur + ; For XA65 compatibily in the future .FEATURE c_comments,labels_without_colons,pc_assignment, loose_char_term .export _ch376_set_file_name .export _ch376_file_open @@ -8,14 +8,16 @@ .export _ch376_check_exist .export _ch376_disk_mount .export _ch376_set_usb_mode - .export _ch376_file_create - .export _ch376_fcreate - + + .export _ch376_file_close + .export _ch376_seek_file + .export _ch376_file_create + .export _ch376_fwrite ; High level function - .export _ch376_fcreate + .import popax - .importzp sp,tmp2,tmp3,tmp1 + .include "zeropage.inc" .include "telemon30.inc" /* @@ -24,10 +26,27 @@ CH376_SET_USB_MODE_CODE_USB_HOST_SOF_PACKAGE_AUTOMATICALLY := $06 -CH376_USB_INT_DISK_READ := $1d -CH376_USB_INT_SUCCESS := $14 -CH376_ERR_MISS_FILE := $42 - +CH376_USB_INT_SUCCESS := $14 +CH376_USB_INT_CONNECT := $15 +CH376_USB_INT_DISCONNECT := $16 +CH376_USB_INT_BUF_OVER := $17 +CH376_USB_INT_USB_READY := $18 +CH376_USB_INT_DISK_READ := $1D +CH376_USB_INT_DISK_WRITE := $1E +CH376_USB_INT_DISK_ERR := $1F + + +CH376_ERR_OPEN_DIR := $41 +CH376_ERR_MISS_FILE := $42 +CH376_ERR_FOUND_NAME := $43 +CH376_ERR_DISK_DISCON := $82 +CH376_ERR_LARGE_SECTOR := $84 +CH376_ERR_TYPE_ERROR := $92 +CH376_ERR_BPB_ERROR := $A1 +CH376_ERR_DISK_FULL := $B1 +CH376_ERR_FDT_OVER := $B2 +CH376_ERR_FILE_CLOSE := $B4 + CH376_GET_IC_VER := $01 @@ -36,80 +55,92 @@ CH376_GET_ENTER_SLEEP := $03 CH376_RESET_ALL := $05 CH376_CHECK_EXIST := $06 CH376_GET_FILE_SIZE := $0C + CH376_SET_USB_MODE := $15 CH376_GET_STATUS := $22 CH376_RD_USB_DATA0 := $27 -CH376_SET_FILE_NAME := $2f +CH376_CMD_WR_REQ_DATA := $2d +CH376_SET_FILE_NAME := $2F + CH376_DISK_CONNECT := $30 ; check the disk connection status CH376_DISK_MOUNT := $31 CH376_FILE_OPEN := $32 CH376_FILE_ENUM_GO := $33 CH376_FILE_CREATE := $34 CH376_FILE_CLOSE := $36 +CH376_BYTE_LOCATE := $39 CH376_BYTE_READ := $3A -CH376_BYTE_RD_GO := $3b +CH376_BYTE_RD_GO := $3B CH376_BYTE_WRITE := $3C +CH376_BYTE_WR_GO := $3D CH376_DISK_CAPACITY := $3E CH376_DISK_RD_GO := $55 -.proc _ch376_file_create - lda #CH376_FILE_CREATE - sta CH376_COMMAND - jsr _ch376_wait_response - rts +.proc _ch376_file_close + lda #CH376_FILE_CLOSE + sta CH376_COMMAND + jsr _ch376_wait_response + rts .endproc -; void _ch376_fcreate(char *filename) -.proc _ch376_fcreate - jsr _ch376_set_file_name - jsr _ch376_file_open - jsr _ch376_file_create +.proc _ch376_seek_file + ldx #CH376_BYTE_LOCATE + stx CH376_COMMAND + sta CH376_DATA + sty CH376_DATA + lda #$00 ; Don't manage 32 bits length + sta CH376_DATA + sta CH376_DATA + jsr _ch376_wait_response + rts .endproc ; void ch376_set_file_name(char *filename) .proc _ch376_set_file_name - sta tmp1 - stx tmp1+1 - lda #CH376_SET_FILE_NAME ;$2f - sta CH376_COMMAND - ldy #0 + sta ptr1 + stx ptr1+1 + lda #CH376_SET_FILE_NAME ;$2f + sta CH376_COMMAND + ldy #0 loop: - lda (tmp1),y ; replace by bufnom - beq end ; we reached 0 value - sta CH376_DATA + lda (ptr1),y ; replace by bufnom + beq end ; we reached 0 value + ;BRK_TELEMON XMINMA + sta CH376_DATA iny - cpy #13 ; because we don't manage longfilename shortname =11 - bne loop + cpy #13 ; because we don't manage longfilename shortname =11 + bne loop end: - sta CH376_DATA + sta CH376_DATA rts .endproc -; void _ch376_file_open(); +; char _ch376_file_open(); .proc _ch376_file_open - lda #CH376_FILE_OPEN ; $32 - sta CH376_COMMAND - jsr _ch376_wait_response + lda #CH376_FILE_OPEN ; $32 + sta CH376_COMMAND + jsr _ch376_wait_response +; ldx #0 rts .endproc ;CMD_GET_FILE_SIZE .proc _ch376_get_file_size - lda #CH376_GET_FILE_SIZE - sta CH376_COMMAND - lda #$68 - sta CH376_DATA + lda #CH376_GET_FILE_SIZE + sta CH376_COMMAND + lda #$68 + sta CH376_DATA ; store file leng - lda CH376_DATA - sta tmp1 - lda CH376_DATA - sta tmp1+1 - lda CH376_DATA - sta tmp2 - lda CH376_DATA - sta tmp2+1 + lda CH376_DATA + sta tmp1 + lda CH376_DATA + sta tmp1+1 + lda CH376_DATA + sta tmp2 + lda CH376_DATA + sta tmp2+1 rts .endproc @@ -155,35 +186,35 @@ loop: .proc _ch376_set_usb_mode ; CH376_SET_USB_MODE_CODE_USB_HOST_SOF_PACKAGE_AUTOMATICALLY - pha - lda #CH376_SET_USB_MODE ; $15 - sta CH376_COMMAND - pla - sta CH376_DATA + ldx #CH376_SET_USB_MODE ; $15 + stx CH376_COMMAND + sta CH376_DATA rts .endproc - - + ; void ch376_set_bytes_write(int value); .proc _ch376_set_bytes_write - sta tmp1 - stx tmp1+1 - ldx #CH376_BYTE_WRITE - stx CH376_COMMAND - lda tmp1 - sta CH376_DATA - lda tmp1+1 - sta CH376_DATA - jsr _ch376_wait_response + ldy #CH376_BYTE_WRITE + sty CH376_COMMAND + sta CH376_DATA + stx CH376_DATA + lda #0 + sta CH376_DATA + sta CH376_DATA + jsr _ch376_wait_response rts .endproc .proc _ch376_set_bytes_read - ldx #CH376_BYTE_READ - stx CH376_COMMAND - sta CH376_DATA - sty CH376_DATA - jsr _ch376_wait_response + ldy #CH376_BYTE_READ + sty CH376_COMMAND + ; Storing 32 bits value + sta CH376_DATA + stx CH376_DATA + lda #0 + sta CH376_DATA + sta CH376_DATA + jsr _ch376_wait_response rts .endproc @@ -204,7 +235,7 @@ loop: ; else A contains answer of the controller ldy #$ff loop3: - ldx #$ff ; merci de laisser une valeur importante car parfois en mode non debug, le controleur ne répond pas tout de suite + ldx #$ff ; don't decrease this counter. Because ch376 won't respond if there is a lower value loop: lda CH376_COMMAND and #%10000000 @@ -223,3 +254,137 @@ no_error: rts .endproc +.proc _ch376_fread + ; use ptr1 to count bytes + jsr _ch376_set_bytes_read + +continue: + cmp #CH376_USB_INT_DISK_READ ; something to read + beq we_read + cmp #CH376_USB_INT_SUCCESS ; finished + beq finished + ; TODO in A : $ff X: $ff + lda #0 + tax + rts +we_read: + lda #CH376_RD_USB_DATA0 + sta CH376_COMMAND + + lda CH376_DATA ; contains length read + sta tmp2; Number of bytes to read + + ldy #0 +loop: + lda CH376_DATA ; read the data + sta (PTR_READ_DEST),y + + iny + cpy tmp2 + bne loop + tya + clc + adc PTR_READ_DEST + bcc next + inc PTR_READ_DEST+1 +next: + sta PTR_READ_DEST + + lda #CH376_BYTE_RD_GO + sta CH376_COMMAND + jsr _ch376_wait_response + jmp continue +finished: + ; TODO return bytes read + lda tmp1 + + ldx tmp1+1 + + rts +.endproc + +; void _ch376_fwrite(void *ptr,int number) +.proc _ch376_fwrite + ; use ptr1 to count bytes + sta ptr2 + stx ptr2+1 + + jsr popax + sta PTR_READ_DEST + stx PTR_READ_DEST+1 + + lda ptr2 + ldx ptr2+1 + jsr _ch376_set_bytes_write + ;cmp #CH376_USB_INT_SUCCESS + ;beq finished + ;jsr popax + + ;jsr _ch376_wait_response + +continue: + cmp #CH376_USB_INT_DISK_WRITE ; something to read + beq we_read + cmp #CH376_USB_INT_SUCCESS ; finished + beq finished + ; TODO in A : $ff X: $ff + lda #0 + tax + rts +we_read: + lda #CH376_CMD_WR_REQ_DATA + sta CH376_COMMAND + + lda CH376_DATA ; contains length read + sta tmp2; Number of bytes to read + + + ;ldy #0 +loop: + ;lda (PTR_READ_DEST),y + lda #65 + sta CH376_DATA ; read the data + dec tmp2 + bne loop +; dec ptr2 + ;bne continue3 + ;dec ptr2+1 + ;bne continue3 +;continue3 +; lda ptr2+1 + ;bne continue2 + ;lda ptr2 + ;beq finished +;continue2 +; iny +; cpy tmp2 +; bne loop +; tya +; clc +; adc PTR_READ_DEST +; bcc next +; inc PTR_READ_DEST+1 +;next: +; sta PTR_READ_DEST + + lda #CH376_BYTE_WR_GO + sta CH376_COMMAND + jsr _ch376_wait_response + jmp continue +finished: + ; TODO return bytes read + lda tmp1 + ;lda #<8000 + ldx tmp1+1 + ;ldx #>8000 + rts +.endproc + + + +.proc _ch376_file_create + lda #CH376_FILE_CREATE + sta CH376_COMMAND + jsr _ch376_wait_response + rts +.endproc \ No newline at end of file diff --git a/libsrc/telemon30/graphics.s b/libsrc/telemon30/graphics.s index 1d0beefa5..4f2b09162 100644 --- a/libsrc/telemon30/graphics.s +++ b/libsrc/telemon30/graphics.s @@ -1,7 +1,7 @@ - .export _paper,_hires,_text,_circle,_curset, _switchOffCursor - .importzp sp,tmp2,tmp3,tmp1 - - .include "telemon30.inc" + .export _paper,_hires,_text,_circle,_curset, _switchOffCursor + .importzp sp,tmp2,tmp3,tmp1 + .import popa + .include "telemon30.inc" .proc _paper ldx #0 ; First window @@ -30,8 +30,11 @@ .endproc .proc _curset + jsr popa ; Pixel + jsr popa sta HRSX - sty HRSY + jsr popa + sta HRSY BRK_TELEMON XCURSE rts .endproc diff --git a/libsrc/telemon30/orixhdr.s b/libsrc/telemon30/orixhdr.s index 8744e86b0..1b0351885 100644 --- a/libsrc/telemon30/orixhdr.s +++ b/libsrc/telemon30/orixhdr.s @@ -1,5 +1,5 @@ ; -; Based on code by Debrune Jérôme <jede@oric.org> +; Based on code by Debrune Jérôme <jede@oric.org> ; 2016-03-17, Greg King ; @@ -17,18 +17,17 @@ .segment "ORIXHDR" - .byte $01, $00 ; + .byte $01, $00 ; - .byte "ORI" + .byte "ori" .byte $01 ; version - .byte $00,$00 ; mode - .byte $00,$00 ; cpu type + .byte $00,%00000000 ; 6502 only + .byte $00,$00 ; Extends .byte $00,$00 ; OS - .byte $00 ; reserved - .byte $00 ; auto - + .byte $00 ; reserved + .byte $00 ; auto .word __BASHEAD_START__ ; Address of start of file .word __MAIN_LAST__ - 1 ; Address of end of file diff --git a/libsrc/telemon30/write.s b/libsrc/telemon30/write.s index 32965fe3d..d762eb92c 100644 --- a/libsrc/telemon30/write.s +++ b/libsrc/telemon30/write.s @@ -27,6 +27,28 @@ sta ptr1 stx ptr1+1 jsr popax ; get fd and discard + + ; if fd=0001 then it stdout + + + cpx #0 + beq next + jmp L1 +next: + cmp #1 + beq L1 + + ; Here it's a file opened + lda ptr1 + sta PTR_READ_DEST + lda ptr1+1 + sta PTR_READ_DEST+1 + lda ptr3 + ldy ptr3+1 + BRK_TELEMON XFWRITE + rts + + L1: inc ptr2 bne L2 inc ptr2+1 From 6ed57af9fd44a4eb80d882f26d31c268c126db81 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 29 Jan 2017 22:14:56 +0100 Subject: [PATCH 0191/2161] removing ch376.h --- include/ch376.h | 55 ------------------------------------------------- 1 file changed, 55 deletions(-) delete mode 100644 include/ch376.h diff --git a/include/ch376.h b/include/ch376.h deleted file mode 100644 index 9db801eaf..000000000 --- a/include/ch376.h +++ /dev/null @@ -1,55 +0,0 @@ - - -/* /// "Portable types" */ - - - - -/* /// "CH376 interface commands and constants" */ - -// Chip version -#define CH376_DATA_IC_VER 3 - -// Commands -#define CH376_CMD_NONE 0x00 -#define CH376_CMD_GET_IC_VER 0x01 -#define CH376_CMD_CHECK_EXIST 0x06 -#define CH376_CMD_SET_USB_MODE 0x15 -#define CH376_CMD_GET_STATUS 0x22 -#define CH376_CMD_RD_USB_DATA0 0x27 -#define CH376_CMD_WR_REQ_DATA 0x2d -#define CH376_CMD_SET_FILE_NAME 0x2f -#define CH376_CMD_DISK_MOUNT 0x31 -#define CH376_CMD_FILE_OPEN 0x32 -#define CH376_CMD_FILE_ENUM_GO 0x33 -#define CH376_CMD_FILE_CREATE 0x34 -#define CH376_CMD_FILE_CLOSE 0x36 -#define CH376_CMD_BYTE_LOCATE 0x39 -#define CH376_CMD_BYTE_READ 0x3a -#define CH376_CMD_BYTE_RD_GO 0x3b -#define CH376_CMD_BYTE_WRITE 0x3c -#define CH376_CMD_BYTE_WR_GO 0x3d -#define CH376_CMD_DISK_QUERY 0x3f -#define CH376_CMD_DISK_RD_GO 0x55 - -#define CH376_ARG_SET_USB_MODE_INVALID 0x00 -#define CH376_ARG_SET_USB_MODE_SD_HOST 0x03 -#define CH376_ARG_SET_USB_MODE_USB_HOST 0x06 - -// Status & errors -#define CH376_ERR_OPEN_DIR 0x41 -#define CH376_ERR_MISS_FILE 0x42 - -#define CH376_RET_SUCCESS 0x51 -#define CH376_RET_ABORT 0x5f - -#define CH376_INT_SUCCESS 0x14 -#define CH376_INT_DISK_READ 0x1d -#define CH376_INT_DISK_WRITE 0x1e - - -unsigned char ch376_check_exist(unsigned char value); -unsigned char ch376_ic_get_version(void); -void ch376_set_usb_mode(unsigned char value); -unsigned char ch376_disk_mount(void); - From 29881fb7c920a65004ee45a16e6769147367ce38 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 29 Jan 2017 22:28:54 +0100 Subject: [PATCH 0192/2161] Revert --- libsrc/common/fread.s | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/libsrc/common/fread.s b/libsrc/common/fread.s index b87cc5cb4..91d692985 100644 --- a/libsrc/common/fread.s +++ b/libsrc/common/fread.s @@ -173,16 +173,13 @@ ; Read was ok, account for the pushed back character (if any). -@L8: - add pb +@L8: add pb bcc @L9 inx ; Check for end of file. -@L9: - - cmp #0 ; Zero bytes read? +@L9: cmp #0 ; Zero bytes read? bne @L10 cpx #0 bne @L10 @@ -195,10 +192,7 @@ ; Return the number of items successfully read. Since we've checked for ; bytes == 0 above, size cannot be zero here, so the division is safe. -@L10: - - - jsr pushax ; Push number of bytes read +@L10: jsr pushax ; Push number of bytes read ldy #5 jsr ldaxysp ; Get size jsr tosudivax ; bytes / size -> a/x From 0f8fb4d79d4fd91bea2f8659e0eabdc1db2b2de2 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 29 Jan 2017 22:39:51 +0100 Subject: [PATCH 0193/2161] Merge with current version --- cfg/telemon30.cfg | 43 +++++++++++++++++++++++++++++++++++++++++++ src/ca65/main.c | 13 +++++++++---- src/cc65/main.c | 11 ++++++----- src/common/target.c | 2 ++ src/common/target.h | 1 + 5 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 cfg/telemon30.cfg diff --git a/cfg/telemon30.cfg b/cfg/telemon30.cfg new file mode 100644 index 000000000..b9f0b4026 --- /dev/null +++ b/cfg/telemon30.cfg @@ -0,0 +1,43 @@ +SYMBOLS { + + __ORIXHDR__: type = import; + + __STACKSIZE__: type = weak, value = $0800; # 2K stack + + __RAMEND__: type = weak, value = $9800; +} +MEMORY { + ZP: file = "", define = yes, start = $00E0, size = $001A; + ORIXHDR: file = %O, type = ro, start = $0000, size = $001F; + BASHEAD: file = %O, define = yes, start = $0801, size = $000D; + MAIN: file = %O, define = yes, start = __BASHEAD_LAST__, size = __RAMEND__ - __MAIN_START__; + BSS: file = "", start = __ONCE_RUN__, size = __RAMEND__ - __STACKSIZE__ - __ONCE_RUN__; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + ORIXHDR: load = ORIXHDR, 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; + ONCE: load = MAIN, type = ro, define = yes; + BASTAIL: load = MAIN, type = ro, optional = 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/src/ca65/main.c b/src/ca65/main.c index 4aa60f2f0..91f652811 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -222,6 +222,10 @@ static void SetSys (const char* Sys) CBMSystem ("__C16__"); break; + case TGT_C65: + CBMSystem("__C65__"); + break; + case TGT_C64: CBMSystem ("__C64__"); break; @@ -623,11 +627,12 @@ static void OptVerbose (const char* Opt attribute ((unused)), -static void OptVersion (const char* Opt attribute ((unused)), - const char* Arg attribute ((unused))) -/* Print the assembler version */ +static void OptVersion(const char* Opt attribute((unused)), + const char* Arg attribute((unused))) + /* Print the assembler version */ { - fprintf (stderr, "ca65 V%s\n", GetVersionAsString ()); + fprintf(stderr, "%s V%s\n", ProgName, GetVersionAsString()); + exit(EXIT_SUCCESS); } diff --git a/src/cc65/main.c b/src/cc65/main.c index f25a44d69..b7abf959c 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -746,12 +746,13 @@ static void OptVerbose (const char* Opt attribute ((unused)), -static void OptVersion (const char* Opt attribute ((unused)), - const char* Arg attribute ((unused))) -/* Print the compiler version */ + +static void OptVersion(const char* Opt attribute((unused)), + const char* Arg attribute((unused))) + /* Print the compiler version */ { - fprintf (stderr, "cc65 V%s\n", GetVersionAsString ()); - exit (EXIT_SUCCESS); + fprintf(stderr, "%s V%s\n", ProgName, GetVersionAsString()); + exit(EXIT_SUCCESS); } diff --git a/src/common/target.c b/src/common/target.c index adbc080bf..31274d48a 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -209,6 +209,8 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "sim65c02", CPU_65C02, BINFMT_BINARY, CTNone }, { "pce", CPU_HUC6280, BINFMT_BINARY, CTNone }, { "gamate", CPU_6502, BINFMT_BINARY, CTNone }, + { "c65", CPU_4510, BINFMT_BINARY, CTPET }, + }; /* Target system */ diff --git a/src/common/target.h b/src/common/target.h index 4bc00225d..93bcfe20d 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -82,6 +82,7 @@ typedef enum { TGT_SIM65C02, TGT_PCENGINE, TGT_GAMATE, + TGT_C65, TGT_COUNT /* Number of target systems */ } target_t; From 2697499b3c245a98871bb43380bdd068facd06c8 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 29 Jan 2017 22:53:50 +0100 Subject: [PATCH 0194/2161] Fixing old pull request --- src/ca65/main.c | 14 +++++++------- src/cc65/main.c | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ca65/main.c b/src/ca65/main.c index 91f652811..fd06f685d 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -222,14 +222,14 @@ static void SetSys (const char* Sys) CBMSystem ("__C16__"); break; - case TGT_C65: - CBMSystem("__C65__"); - break; - case TGT_C64: CBMSystem ("__C64__"); break; + case TGT_C65: + CBMSystem("__C65__"); + break; + case TGT_VIC20: CBMSystem ("__VIC20__"); break; @@ -628,11 +628,11 @@ static void OptVerbose (const char* Opt attribute ((unused)), static void OptVersion(const char* Opt attribute((unused)), - const char* Arg attribute((unused))) + const char* Arg attribute((unused))) /* Print the assembler version */ { - fprintf(stderr, "%s V%s\n", ProgName, GetVersionAsString()); - exit(EXIT_SUCCESS); + fprintf(stderr, "%s V%s\n", ProgName, GetVersionAsString()); + exit(EXIT_SUCCESS); } diff --git a/src/cc65/main.c b/src/cc65/main.c index b7abf959c..1fd670340 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -748,11 +748,11 @@ static void OptVerbose (const char* Opt attribute ((unused)), static void OptVersion(const char* Opt attribute((unused)), - const char* Arg attribute((unused))) + const char* Arg attribute((unused))) /* Print the compiler version */ { - fprintf(stderr, "%s V%s\n", ProgName, GetVersionAsString()); - exit(EXIT_SUCCESS); + fprintf(stderr, "%s V%s\n", ProgName, GetVersionAsString()); + exit(EXIT_SUCCESS); } From e21eca942b00e30c2d33c3220dbb1225e1751668 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 29 Jan 2017 22:55:35 +0100 Subject: [PATCH 0195/2161] new pull fix --- src/ca65/main.c | 6 +++--- src/cc65/main.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ca65/main.c b/src/ca65/main.c index fd06f685d..cbd514bc3 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -627,9 +627,9 @@ static void OptVerbose (const char* Opt attribute ((unused)), -static void OptVersion(const char* Opt attribute((unused)), - const char* Arg attribute((unused))) - /* Print the assembler version */ +static void OptVersion (const char* Opt attribute((unused)), + const char* Arg attribute((unused))) +/* Print the assembler version */ { fprintf(stderr, "%s V%s\n", ProgName, GetVersionAsString()); exit(EXIT_SUCCESS); diff --git a/src/cc65/main.c b/src/cc65/main.c index 1fd670340..8fc774f87 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -747,9 +747,9 @@ static void OptVerbose (const char* Opt attribute ((unused)), -static void OptVersion(const char* Opt attribute((unused)), - const char* Arg attribute((unused))) - /* Print the compiler version */ +static void OptVersion (const char* Opt attribute((unused)), + const char* Arg attribute((unused))) +/* Print the compiler version */ { fprintf(stderr, "%s V%s\n", ProgName, GetVersionAsString()); exit(EXIT_SUCCESS); From bd82bf6a7fe9b7644dadb579f1fe4b72c184e9eb Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 29 Jan 2017 22:59:53 +0100 Subject: [PATCH 0196/2161] Fix --- src/ca65/main.c | 2 +- src/cc65/main.c | 4 ++-- src/common/target.c | 8 ++++---- src/common/target.h | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ca65/main.c b/src/ca65/main.c index cbd514bc3..ff321d87d 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -631,7 +631,7 @@ static void OptVersion (const char* Opt attribute((unused)), const char* Arg attribute((unused))) /* Print the assembler version */ { - fprintf(stderr, "%s V%s\n", ProgName, GetVersionAsString()); + fprintf(stderr, "%s V%s\n", ProgName, GetVersionAsString ()); exit(EXIT_SUCCESS); } diff --git a/src/cc65/main.c b/src/cc65/main.c index 8fc774f87..e4e5ce81f 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -751,8 +751,8 @@ static void OptVersion (const char* Opt attribute((unused)), const char* Arg attribute((unused))) /* Print the compiler version */ { - fprintf(stderr, "%s V%s\n", ProgName, GetVersionAsString()); - exit(EXIT_SUCCESS); + fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); + exit (EXIT_SUCCESS); } diff --git a/src/common/target.c b/src/common/target.c index 31274d48a..dfbe4d354 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -152,6 +152,7 @@ static const TargetEntry TargetMap[] = { { "c128", TGT_C128 }, { "c16", TGT_C16 }, { "c64", TGT_C64 }, + { "c65", TGT_C65 }, { "cbm510", TGT_CBM510 }, { "cbm610", TGT_CBM610 }, { "gamate", TGT_GAMATE }, @@ -200,8 +201,8 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "geos-apple", CPU_65C02, BINFMT_BINARY, CTNone }, { "lunix", CPU_6502, BINFMT_O65, CTNone }, { "atmos", CPU_6502, BINFMT_BINARY, CTNone }, - { "telemon24", CPU_6502, BINFMT_BINARY, CTNone }, - { "telemon30", CPU_6502, BINFMT_BINARY, CTNone }, + { "telemon24", CPU_6502, BINFMT_BINARY, CTNone }, + { "telemon30", CPU_6502, BINFMT_BINARY, CTNone }, { "nes", CPU_6502, BINFMT_BINARY, CTNone }, { "supervision", CPU_65SC02, BINFMT_BINARY, CTNone }, { "lynx", CPU_65SC02, BINFMT_BINARY, CTNone }, @@ -209,8 +210,7 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "sim65c02", CPU_65C02, BINFMT_BINARY, CTNone }, { "pce", CPU_HUC6280, BINFMT_BINARY, CTNone }, { "gamate", CPU_6502, BINFMT_BINARY, CTNone }, - { "c65", CPU_4510, BINFMT_BINARY, CTPET }, - + { "c65", CPU_4510, BINFMT_BINARY, CTPET }, }; /* Target system */ diff --git a/src/common/target.h b/src/common/target.h index 93bcfe20d..2b0a4e196 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -82,7 +82,7 @@ typedef enum { TGT_SIM65C02, TGT_PCENGINE, TGT_GAMATE, - TGT_C65, + TGT_C65, TGT_COUNT /* Number of target systems */ } target_t; From db3b6603e510741faee19da56cebfaabff3d33d5 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 29 Jan 2017 23:03:01 +0100 Subject: [PATCH 0197/2161] Fix --- src/ca65/main.c | 12 ++++++------ src/cc65/main.c | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ca65/main.c b/src/ca65/main.c index ff321d87d..8022b7818 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -226,9 +226,9 @@ static void SetSys (const char* Sys) CBMSystem ("__C64__"); break; - case TGT_C65: - CBMSystem("__C65__"); - break; + case TGT_C65: + CBMSystem("__C65__"); + break; case TGT_VIC20: CBMSystem ("__VIC20__"); @@ -627,11 +627,11 @@ static void OptVerbose (const char* Opt attribute ((unused)), -static void OptVersion (const char* Opt attribute((unused)), - const char* Arg attribute((unused))) +static void OptVersion (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) /* Print the assembler version */ { - fprintf(stderr, "%s V%s\n", ProgName, GetVersionAsString ()); + fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); exit(EXIT_SUCCESS); } diff --git a/src/cc65/main.c b/src/cc65/main.c index e4e5ce81f..6847c4b14 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -747,8 +747,8 @@ static void OptVerbose (const char* Opt attribute ((unused)), -static void OptVersion (const char* Opt attribute((unused)), - const char* Arg attribute((unused))) +static void OptVersion (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) /* Print the compiler version */ { fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); From 858e95250586aa6ba9feb478a07accfd4ced42ae Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 29 Jan 2017 23:05:18 +0100 Subject: [PATCH 0198/2161] Fix --- src/ca65/main.c | 2 +- src/cc65/main.c | 1 - src/common/target.c | 4 ++-- src/common/target.h | 4 ++-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/ca65/main.c b/src/ca65/main.c index 8022b7818..1e0c5996f 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -227,7 +227,7 @@ static void SetSys (const char* Sys) break; case TGT_C65: - CBMSystem("__C65__"); + CBMSystem ("__C65__"); break; case TGT_VIC20: diff --git a/src/cc65/main.c b/src/cc65/main.c index 6847c4b14..b0c9261fe 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -746,7 +746,6 @@ static void OptVerbose (const char* Opt attribute ((unused)), - static void OptVersion (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Print the compiler version */ diff --git a/src/common/target.c b/src/common/target.c index dfbe4d354..67e4ad51b 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -147,7 +147,7 @@ static const TargetEntry TargetMap[] = { { "atari", TGT_ATARI }, { "atari5200", TGT_ATARI5200 }, { "atarixl", TGT_ATARIXL }, - { "atmos", TGT_ATMOS }, + { "atmos", TGT_ATMOS }, { "bbc", TGT_BBC }, { "c128", TGT_C128 }, { "c16", TGT_C16 }, @@ -172,7 +172,7 @@ static const TargetEntry TargetMap[] = { { "sim65c02", TGT_SIM65C02 }, { "supervision", TGT_SUPERVISION }, { "telemon24", TGT_TELEMON24 }, - { "telemon30", TGT_TELEMON30 }, + { "telemon30", TGT_TELEMON30 }, { "vic20", TGT_VIC20 }, }; #define MAP_ENTRY_COUNT (sizeof (TargetMap) / sizeof (TargetMap[0])) diff --git a/src/common/target.h b/src/common/target.h index 2b0a4e196..68c0953fe 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -73,8 +73,8 @@ typedef enum { TGT_GEOS_APPLE, TGT_LUNIX, TGT_ATMOS, - TGT_TELEMON24, - TGT_TELEMON30, + TGT_TELEMON24, + TGT_TELEMON30, TGT_NES, TGT_SUPERVISION, TGT_LYNX, From 06b2b83ab298e5a8898d2d588c0e94daea2b7308 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 29 Jan 2017 23:18:32 +0100 Subject: [PATCH 0199/2161] Correcting spaces --- libsrc/telemon30/_read.s | 36 +++--- libsrc/telemon30/ch376.s | 272 ++++++++++++++++++--------------------- 2 files changed, 139 insertions(+), 169 deletions(-) diff --git a/libsrc/telemon30/_read.s b/libsrc/telemon30/_read.s index e8bcc3fd0..ee822f1fd 100644 --- a/libsrc/telemon30/_read.s +++ b/libsrc/telemon30/_read.s @@ -12,36 +12,30 @@ ; int read (int fd, void* buf, unsigned count); .proc _read - - sta ptr1 ; count - stx ptr1+1 ; count - jsr popax ; get buf + sta ptr1 ; count + stx ptr1+1 ; count + jsr popax ; get buf - sta PTR_READ_DEST - stx PTR_READ_DEST+1 - sta ptr2 ; in order to calculate nb of bytes read - stx ptr2+1 ; + sta PTR_READ_DEST + stx PTR_READ_DEST+1 + sta ptr2 ; in order to calculate nb of bytes read + stx ptr2+1 ; - ;jsr popax ; fp pointer don't care in this version + ; jsr popax ; fp pointer don't care in this version - lda ptr1 ; - ldy ptr1+1 ; + lda ptr1 ; + ldy ptr1+1 ; BRK_TELEMON XFREAD ; calls telemon30 routine ; compute nb of bytes read - lda PTR_READ_DEST+1 + lda PTR_READ_DEST+1 sec - sbc ptr2+1 - tax - lda PTR_READ_DEST + sbc ptr2+1 + tax + lda PTR_READ_DEST sec - sbc ptr2 - - - + sbc ptr2 ; Here A and X contains number of bytes read - rts - .endproc diff --git a/libsrc/telemon30/ch376.s b/libsrc/telemon30/ch376.s index 97245add9..460a70052 100644 --- a/libsrc/telemon30/ch376.s +++ b/libsrc/telemon30/ch376.s @@ -77,108 +77,107 @@ CH376_DISK_CAPACITY := $3E CH376_DISK_RD_GO := $55 .proc _ch376_file_close - lda #CH376_FILE_CLOSE - sta CH376_COMMAND - jsr _ch376_wait_response + lda #CH376_FILE_CLOSE + sta CH376_COMMAND + jsr _ch376_wait_response rts .endproc .proc _ch376_seek_file - ldx #CH376_BYTE_LOCATE - stx CH376_COMMAND - sta CH376_DATA - sty CH376_DATA - lda #$00 ; Don't manage 32 bits length - sta CH376_DATA - sta CH376_DATA - jsr _ch376_wait_response + ldx #CH376_BYTE_LOCATE + stx CH376_COMMAND + sta CH376_DATA + sty CH376_DATA + lda #$00 ; Don't manage 32 bits length + sta CH376_DATA + sta CH376_DATA + jsr _ch376_wait_response rts .endproc ; void ch376_set_file_name(char *filename) .proc _ch376_set_file_name - sta ptr1 - stx ptr1+1 - lda #CH376_SET_FILE_NAME ;$2f - sta CH376_COMMAND - ldy #0 + sta ptr1 + stx ptr1+1 + lda #CH376_SET_FILE_NAME ;$2f + sta CH376_COMMAND + ldy #0 loop: - lda (ptr1),y ; replace by bufnom - beq end ; we reached 0 value - ;BRK_TELEMON XMINMA - sta CH376_DATA + lda (ptr1),y ; replace by bufnom + beq end ; we reached 0 value + BRK_TELEMON XMINMA + sta CH376_DATA iny - cpy #13 ; because we don't manage longfilename shortname =11 - bne loop + cpy #13 ; because we don't manage longfilename shortname =11 + bne loop end: - sta CH376_DATA + sta CH376_DATA rts .endproc ; char _ch376_file_open(); .proc _ch376_file_open - lda #CH376_FILE_OPEN ; $32 - sta CH376_COMMAND - jsr _ch376_wait_response -; ldx #0 + lda #CH376_FILE_OPEN ; $32 + sta CH376_COMMAND + jsr _ch376_wait_response rts .endproc - ;CMD_GET_FILE_SIZE + .proc _ch376_get_file_size - lda #CH376_GET_FILE_SIZE - sta CH376_COMMAND - lda #$68 - sta CH376_DATA - ; store file leng - lda CH376_DATA - sta tmp1 - lda CH376_DATA - sta tmp1+1 - lda CH376_DATA - sta tmp2 - lda CH376_DATA - sta tmp2+1 + lda #CH376_GET_FILE_SIZE + sta CH376_COMMAND + lda #$68 + sta CH376_DATA + ; store file length 32 bits + lda CH376_DATA + sta tmp1 + lda CH376_DATA + sta tmp1+1 + lda CH376_DATA + sta tmp2 + lda CH376_DATA + sta tmp2+1 rts .endproc ; void ch376_reset(); .proc _ch376_reset - lda #CH376_RESET_ALL ; 5 - sta CH376_COMMAND + lda #CH376_RESET_ALL ; 5 + sta CH376_COMMAND ; waiting - ldy #0 - ldx #0 + ldy #0 + ldx #0 loop: nop inx - bne loop + bne loop iny - bne loop + bne loop rts .endproc ; char ch376_check_exist(char value); .proc _ch376_check_exist - sta tmp1 - lda #CH376_CHECK_EXIST ; - sta CH376_COMMAND - lda tmp1 - sta CH376_DATA - lda CH376_DATA + sta tmp1 + lda #CH376_CHECK_EXIST ; + sta CH376_COMMAND + lda tmp1 + sta CH376_DATA + lda CH376_DATA rts .endproc ; char ch376_ic_get_version(void) .proc _ch376_ic_get_version - lda #CH376_GET_IC_VER - sta CH376_COMMAND - ldx #0 - lda CH376_DATA + lda #CH376_GET_IC_VER + sta CH376_COMMAND + ldx #0 + lda CH376_DATA rts .endproc @@ -186,45 +185,45 @@ loop: .proc _ch376_set_usb_mode ; CH376_SET_USB_MODE_CODE_USB_HOST_SOF_PACKAGE_AUTOMATICALLY - ldx #CH376_SET_USB_MODE ; $15 - stx CH376_COMMAND - sta CH376_DATA + ldx #CH376_SET_USB_MODE ; $15 + stx CH376_COMMAND + sta CH376_DATA rts .endproc ; void ch376_set_bytes_write(int value); .proc _ch376_set_bytes_write - ldy #CH376_BYTE_WRITE - sty CH376_COMMAND - sta CH376_DATA - stx CH376_DATA - lda #0 - sta CH376_DATA - sta CH376_DATA - jsr _ch376_wait_response + ldy #CH376_BYTE_WRITE + sty CH376_COMMAND + sta CH376_DATA + stx CH376_DATA + lda #0 + sta CH376_DATA + sta CH376_DATA + jsr _ch376_wait_response rts .endproc .proc _ch376_set_bytes_read - ldy #CH376_BYTE_READ - sty CH376_COMMAND + ldy #CH376_BYTE_READ + sty CH376_COMMAND ; Storing 32 bits value - sta CH376_DATA - stx CH376_DATA - lda #0 - sta CH376_DATA - sta CH376_DATA - jsr _ch376_wait_response + sta CH376_DATA + stx CH376_DATA + lda #0 + sta CH376_DATA + sta CH376_DATA + jsr _ch376_wait_response rts .endproc ; char ch376_disk_mount(); .proc _ch376_disk_mount - lda #CH376_DISK_MOUNT ; $31 - sta CH376_COMMAND - jsr _ch376_wait_response + lda #CH376_DISK_MOUNT ; $31 + sta CH376_COMMAND + jsr _ch376_wait_response ; if we read data value, we have then length of the volume name - ldx #0 + ldx #0 rts .endproc @@ -233,89 +232,87 @@ loop: .proc _ch376_wait_response ; 1 return 1 if usb controller does not respond ; else A contains answer of the controller - ldy #$ff + ldy #$ff loop3: - ldx #$ff ; don't decrease this counter. Because ch376 won't respond if there is a lower value + ldx #$ff ; don't decrease this counter. Because ch376 won't respond if there is a lower value loop: - lda CH376_COMMAND - and #%10000000 - cmp #128 - bne no_error + lda CH376_COMMAND + and #%10000000 + cmp #128 + bne no_error dex - bne loop + bne loop dey - bne loop3 + bne loop3 ; error is here rts no_error: - lda #CH376_GET_STATUS - sta CH376_COMMAND - lda CH376_DATA + lda #CH376_GET_STATUS + sta CH376_COMMAND + lda CH376_DATA rts .endproc .proc _ch376_fread ; use ptr1 to count bytes - jsr _ch376_set_bytes_read + jsr _ch376_set_bytes_read continue: - cmp #CH376_USB_INT_DISK_READ ; something to read - beq we_read - cmp #CH376_USB_INT_SUCCESS ; finished - beq finished + cmp #CH376_USB_INT_DISK_READ ; something to read + beq we_read + cmp #CH376_USB_INT_SUCCESS ; finished + beq finished ; TODO in A : $ff X: $ff - lda #0 + lda #0 tax rts we_read: - lda #CH376_RD_USB_DATA0 - sta CH376_COMMAND + lda #CH376_RD_USB_DATA0 + sta CH376_COMMAND - lda CH376_DATA ; contains length read - sta tmp2; Number of bytes to read + lda CH376_DATA ; contains length read + sta tmp2; Number of bytes to read ldy #0 loop: - lda CH376_DATA ; read the data - sta (PTR_READ_DEST),y + lda CH376_DATA ; read the data + sta (PTR_READ_DEST),y iny - cpy tmp2 - bne loop + cpy tmp2 + bne loop tya clc - adc PTR_READ_DEST - bcc next - inc PTR_READ_DEST+1 + adc PTR_READ_DEST + bcc next + inc PTR_READ_DEST+1 next: - sta PTR_READ_DEST + sta PTR_READ_DEST - lda #CH376_BYTE_RD_GO - sta CH376_COMMAND - jsr _ch376_wait_response - jmp continue + lda #CH376_BYTE_RD_GO + sta CH376_COMMAND + jsr _ch376_wait_response + jmp continue finished: ; TODO return bytes read - lda tmp1 - - ldx tmp1+1 - + lda tmp1 + ldx tmp1+1 rts .endproc ; void _ch376_fwrite(void *ptr,int number) .proc _ch376_fwrite - ; use ptr1 to count bytes - sta ptr2 - stx ptr2+1 + ; use ptr1 to count bytes + sta ptr2 + stx ptr2+1 - jsr popax - sta PTR_READ_DEST - stx PTR_READ_DEST+1 + jsr popax + sta PTR_READ_DEST + stx PTR_READ_DEST+1 - lda ptr2 - ldx ptr2+1 - jsr _ch376_set_bytes_write + lda ptr2 + ldx ptr2+1 + jsr _ch376_set_bytes_write ;cmp #CH376_USB_INT_SUCCESS ;beq finished ;jsr popax @@ -346,26 +343,7 @@ loop: sta CH376_DATA ; read the data dec tmp2 bne loop -; dec ptr2 - ;bne continue3 - ;dec ptr2+1 - ;bne continue3 -;continue3 -; lda ptr2+1 - ;bne continue2 - ;lda ptr2 - ;beq finished -;continue2 -; iny -; cpy tmp2 -; bne loop -; tya -; clc -; adc PTR_READ_DEST -; bcc next -; inc PTR_READ_DEST+1 -;next: -; sta PTR_READ_DEST + lda #CH376_BYTE_WR_GO sta CH376_COMMAND @@ -380,8 +358,6 @@ finished: rts .endproc - - .proc _ch376_file_create lda #CH376_FILE_CREATE sta CH376_COMMAND From b5fef66f37d3a6f8419f32177f27a01108091d48 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Tue, 31 Jan 2017 22:09:14 +0100 Subject: [PATCH 0200/2161] Merge telemon24 and telemon30 into telestrat target. Cleaning, and replace tab to spaces Converting hex lowercase value into uppercase char. Changing := and = when it was needed --- asminc/telemon24.inc | 68 ---- asminc/{telemon30.inc => telestrat.inc} | 103 +++-- cfg/telemon24.cfg | 43 -- cfg/{telemon30.cfg => telestrat.cfg} | 0 doc/telemon24.sgml | 42 -- doc/{telemon30.sgml => telestrat.sgml} | 0 include/telemon.h | 58 --- include/{telemon30.h => telestrat.h} | 0 libsrc/Makefile | 3 +- libsrc/telemon24/crt0.s | 101 ----- libsrc/telemon24/hires.s | 22 -- libsrc/telemon24/mainargs.s | 36 -- libsrc/telemon24/print.s | 25 -- libsrc/telemon24/tapehdr.s | 36 -- libsrc/telemon24/write.s | 59 --- libsrc/telemon30/_close.s | 17 - libsrc/telemon30/_read.s | 41 -- libsrc/telemon30/_scrsize.s | 19 - libsrc/telemon30/ch376.s | 366 ------------------ libsrc/telemon30/ctype.s | 299 -------------- libsrc/telemon30/graphics.s | 54 --- libsrc/telemon30/keyboard.s | 13 - libsrc/telemon30/oserrlist.s | 75 ---- libsrc/telemon30/oserror.s | 17 - libsrc/telemon30/print.s | 21 - libsrc/telemon30/sound.s | 45 --- libsrc/telemon30/sysuname.s | 46 --- libsrc/telestrat/ch376.s | 344 ++++++++++++++++ libsrc/telestrat/close.s | 18 + libsrc/{telemon30 => telestrat}/crt0.s | 12 +- libsrc/{telemon24 => telestrat}/ctype.s | 0 libsrc/telestrat/graphics.s | 58 +++ libsrc/telestrat/keyboard.s | 14 + libsrc/{telemon30 => telestrat}/mainargs.s | 29 +- libsrc/{telemon30 => telestrat}/mym.s | 2 +- .../{telemon30/_open.s => telestrat/open.s} | 21 +- libsrc/{telemon30 => telestrat}/orixhdr.s | 22 +- libsrc/{telemon24 => telestrat}/oserrlist.s | 0 libsrc/{telemon24 => telestrat}/oserror.s | 0 libsrc/telestrat/print.s | 16 + libsrc/telestrat/read.s | 43 ++ .../_scrsize.s => telestrat/scrsize.s} | 2 +- libsrc/telestrat/sound.s | 42 ++ libsrc/{telemon24 => telestrat}/sysuname.s | 0 libsrc/{telemon30 => telestrat}/write.s | 14 +- src/ca65/main.c | 8 +- src/cc65/main.c | 8 +- src/common/target.c | 6 +- src/common/target.h | 3 +- 49 files changed, 629 insertions(+), 1642 deletions(-) delete mode 100644 asminc/telemon24.inc rename asminc/{telemon30.inc => telestrat.inc} (69%) delete mode 100644 cfg/telemon24.cfg rename cfg/{telemon30.cfg => telestrat.cfg} (100%) delete mode 100644 doc/telemon24.sgml rename doc/{telemon30.sgml => telestrat.sgml} (100%) delete mode 100644 include/telemon.h rename include/{telemon30.h => telestrat.h} (100%) delete mode 100644 libsrc/telemon24/crt0.s delete mode 100644 libsrc/telemon24/hires.s delete mode 100644 libsrc/telemon24/mainargs.s delete mode 100644 libsrc/telemon24/print.s delete mode 100644 libsrc/telemon24/tapehdr.s delete mode 100644 libsrc/telemon24/write.s delete mode 100644 libsrc/telemon30/_close.s delete mode 100644 libsrc/telemon30/_read.s delete mode 100644 libsrc/telemon30/_scrsize.s delete mode 100644 libsrc/telemon30/ch376.s delete mode 100644 libsrc/telemon30/ctype.s delete mode 100644 libsrc/telemon30/graphics.s delete mode 100644 libsrc/telemon30/keyboard.s delete mode 100644 libsrc/telemon30/oserrlist.s delete mode 100644 libsrc/telemon30/oserror.s delete mode 100644 libsrc/telemon30/print.s delete mode 100644 libsrc/telemon30/sound.s delete mode 100644 libsrc/telemon30/sysuname.s create mode 100644 libsrc/telestrat/ch376.s create mode 100644 libsrc/telestrat/close.s rename libsrc/{telemon30 => telestrat}/crt0.s (85%) rename libsrc/{telemon24 => telestrat}/ctype.s (100%) create mode 100644 libsrc/telestrat/graphics.s create mode 100644 libsrc/telestrat/keyboard.s rename libsrc/{telemon30 => telestrat}/mainargs.s (90%) rename libsrc/{telemon30 => telestrat}/mym.s (99%) rename libsrc/{telemon30/_open.s => telestrat/open.s} (65%) rename libsrc/{telemon30 => telestrat}/orixhdr.s (56%) rename libsrc/{telemon24 => telestrat}/oserrlist.s (100%) rename libsrc/{telemon24 => telestrat}/oserror.s (100%) create mode 100644 libsrc/telestrat/print.s create mode 100644 libsrc/telestrat/read.s rename libsrc/{telemon24/_scrsize.s => telestrat/scrsize.s} (85%) create mode 100644 libsrc/telestrat/sound.s rename libsrc/{telemon24 => telestrat}/sysuname.s (100%) rename libsrc/{telemon30 => telestrat}/write.s (86%) diff --git a/asminc/telemon24.inc b/asminc/telemon24.inc deleted file mode 100644 index 0b58d63a6..000000000 --- a/asminc/telemon24.inc +++ /dev/null @@ -1,68 +0,0 @@ -; -; Oric Telemon definition -; Telemon 2.4 -; - - -; --------------------------------------------------------------------------- -; Constants - -SCREEN_XSIZE = 40 ; screen columns -SCREEN_YSIZE = 28 ; screen rows - -FUNCTKEY = $A5 - -FNAME_LEN = 11 ; maximum length of file-name - - -; --------------------------------------------------------------------------- -; Zero page - - - - -; --------------------------------------------------------------------------- -; Low memory - - - - -; --------------------------------------------------------------------------- -; I/O locations - -; 6522 -.struct VIA ; Versatile Interface Adapter - .res $0300 -PRB .byte ; Port Register B -PRA .byte ; Port Register A -DDRB .byte ; Data Direction Register B -DDRA .byte ; Data Direction Register A -T1 .word ; Timer 1 -T1L .word ; Timer 1 Latch -T2 .word ; Timer 2 -SR .byte ; Shift Register -ACR .byte ; Auxiliary Control Register -PCR .byte ; Peripheral Control Register -IFR .byte ; Interrupt Flags Register -IER .byte ; Interrupt Enable Register -PRA2 .byte ; Port Register A without handshaking -.endstruct - -; 6551 -.struct ACIA ; Asynchronous Communications Interface Adapter - .res $031C -DATA .byte -STATUS .byte -CMD .byte ; Command register -CTRL .byte ; Control register -.endstruct - -SCREEN := $BB80 - - -; --------------------------------------------------------------------------- -; ROM entries - -XWR0 := $10 -XWSTR0 := $14 - diff --git a/asminc/telemon30.inc b/asminc/telestrat.inc similarity index 69% rename from asminc/telemon30.inc rename to asminc/telestrat.inc index acfd7e919..fedda1946 100644 --- a/asminc/telemon30.inc +++ b/asminc/telestrat.inc @@ -1,6 +1,7 @@ ; ; Oric Telemon definition -; Telemon 2.4 +; Telemon 2.4 & Telemon 3.0 +; For telemon 3.0 check http://orix.oric.org ; @@ -18,6 +19,24 @@ FNAME_LEN = 11 ; maximum length of file-name ; --------------------------------------------------------------------------- ; Zero page +; --------------------------------------------------------------------------- +; Page 00 +RES := $00 +RESB := $02 + +TR0 := $0C +TR1 := $0D + +PTR_READ_DEST := $2D ; used for XFREAD and XWRITE only in telemon 3.0 + +HRSX := $46 +HRSY := $47 + +HRS1 := $4D +HRS2 := $4F +HRS3 := $51 +HRS4 := $53 +HRS5 := $55 @@ -82,69 +101,47 @@ SCREEN := $BB80 ; ROM entries ; primitives telemon 2.4 -XRD0 := $08 -XRDW0 := $0c -XWR0 := $10 -XWSTR0 := $14 -XTEXT := $19 -XHIRES := $1A -XMINMA := $1f -XFREAD := $27 ; only in TELEMON 3.0 -XOPEN := $30 ; only in TELEMON 3.0 -XCOSCR := $34 ; switch off cursor -XCSSCR := $35 ; switch on cursor -XCLOSE := $3a ; Close file -XFWRITE:= $3b ; write - -XSONPS := $40 -XOUPS := $42 -XPLAY := $43 -XSOUND := $44 -XMUSIC := $45 -XZAP := $46 -XSHOOT := $47 -XCIRCL := $8f -XCURSE := $90 -XEXPLO := $9c -XPING := $9d -XPAPER := $92 -XINK := $93 - - -; --------------------------------------------------------------------------- -; Page 00 -RES := $00 -RESB := $02 - -TR0 := $0c -TR1 := $0d - -PTR_READ_DEST := $2c ; used for XFREAD and XWRITE - -HRSX := $46 -HRSY := $47 - -HRS1 := $4D -HRS2 := $4F -HRS3 := $51 -HRS4 := $53 -HRS5 := $55 +XRD0 = $08 +XRDW0 = $0C +XWR0 = $10 +XWSTR0 = $14 +XTEXT = $19 +XHIRES = $1A +XMINMA = $1F +XFREAD = $27 ; only in TELEMON 3.0 +XOPEN = $30 ; only in TELEMON 3.0 +XCOSCR = $34 ; switch off cursor +XCSSCR = $35 ; switch on cursor +XCLOSE = $3A ; only in TELEMON 3.0 Close file +XFWRITE = $3B ; only in TELEMON 3.0 write file +XSONPS = $40 +XOUPS = $42 +XPLAY = $43 +XSOUND = $44 +XMUSIC = $45 +XZAP = $46 +XSHOOT = $47 +XCIRCL = $8F +XCURSE = $90 +XEXPLO = $9C +XPING = $9D +XPAPER = $92 +XINK = $93 ; --------------------------------------------------------------------------- ; Page $500 -BUFNOM := $517 -BUFEDT := $590 +BUFNOM := $517 +BUFEDT := $590 MAX_BUFEDT_LENGTH=110 ; Hardware -CH376_DATA :=$340 -CH376_COMMAND :=$341 +CH376_DATA :=$340 +CH376_COMMAND :=$341 ; MACRO - .macro BRK_TELEMON value .byte $00,value .endmacro diff --git a/cfg/telemon24.cfg b/cfg/telemon24.cfg deleted file mode 100644 index b76350868..000000000 --- a/cfg/telemon24.cfg +++ /dev/null @@ -1,43 +0,0 @@ -SYMBOLS { - - __ORIXHDR__: type = import; - - __STACKSIZE__: type = weak, value = $0800; # 2K stack - - __RAMEND__: type = weak, value = $9800 + $1C00 ; -} -MEMORY { - ZP: file = "", define = yes, start = $00E2, size = $001A; - ORIXHDR: file = %O, type = ro, start = $0000, size = $001F; - BASHEAD: file = %O, define = yes, start = $0801, size = $000D; - MAIN: file = %O, define = yes, start = __BASHEAD_LAST__, size = __RAMEND__ - __MAIN_START__; - BSS: file = "", start = __ONCE_RUN__, size = __RAMEND__ - __STACKSIZE__ - __ONCE_RUN__; -} -SEGMENTS { - ZEROPAGE: load = ZP, type = zp; - ORIXHDR: load = ORIXHDR, 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; - ONCE: load = MAIN, type = ro, define = yes; - BASTAIL: load = MAIN, type = ro, optional = 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/telemon30.cfg b/cfg/telestrat.cfg similarity index 100% rename from cfg/telemon30.cfg rename to cfg/telestrat.cfg diff --git a/doc/telemon24.sgml b/doc/telemon24.sgml deleted file mode 100644 index b4e1befa1..000000000 --- a/doc/telemon24.sgml +++ /dev/null @@ -1,42 +0,0 @@ -<!doctype linuxdoc system> - -<article> - -<title>Oric Telemon 2.4 -specific information for cc65 -<author> - -<url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2017-01-22 - -<abstract> -An overview over the Telemon 3.0 runtime system as it is implemented for the cc65 C -compiler. -</abstract> - -<!-- Table of contents --> -<toc> - - - -<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/telemon30.sgml b/doc/telestrat.sgml similarity index 100% rename from doc/telemon30.sgml rename to doc/telestrat.sgml diff --git a/include/telemon.h b/include/telemon.h deleted file mode 100644 index 70033a9ad..000000000 --- a/include/telemon.h +++ /dev/null @@ -1,58 +0,0 @@ - -void print (char *); - -void hires(); -void text(); -void oups(); -void ping(); -void zap(); -void shoot(); -void explode(); - -void paper(char color); -void ink(char color); - -void kbdclick1(); - - - -void curset(char x,char y); -void circle(char rayon); - -char key(void); - - -/* PEEK, POKE, DEEK, DOKE */ - -#define POKE(addr,val) (*(unsigned char*) (addr) = (val)) - - -#define PCHN_1 001 -#define PCHN_2 002 -#define PCHN_12 003 -#define PCHN_3 004 -#define PCHN_13 005 -#define PCHN_23 006 -#define PCHN_123 007 - -#define ENV_DECAY 001 /* \_________ envelope */ -#define ENV_ATTACK_CUT 002 /* /_________ envelope */ -#define ENV_SAW_DOWN 003 /* \\\\\\\\\\ envelope */ -#define ENV_WAVE 004 /* /\/\/\/\/\ envelope */ -#define ENV_DECAY_CONT 005 /* \~~~~~~~~~ envelope */ -#define ENV_SAW_UP 006 /* ////////// envelope */ -#define ENV_ATTACK_CONT 007 /* /~~~~~~~~~ envelope */ - -#define VOL_ENVELOPE 0x0 -#define VOL_QUIETEST 0x1 -#define VOL_LOUDEST 0xe - -extern int play(int soundchanels,int noisechanels,int envelop,int volume); - - -/* Play a musical tone through the selected channel. */ - -#define CHAN_1 1 -#define CHAN_2 2 -#define CHAN_3 3 - diff --git a/include/telemon30.h b/include/telestrat.h similarity index 100% rename from include/telemon30.h rename to include/telestrat.h diff --git a/libsrc/Makefile b/libsrc/Makefile index 0342a8ca4..8bcbe4410 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -31,8 +31,7 @@ TARGETS = apple2 \ sim6502 \ sim65c02 \ supervision\ - telemon24\ - telemon30 + telestrat DRVTYPES = emd \ joy \ diff --git a/libsrc/telemon24/crt0.s b/libsrc/telemon24/crt0.s deleted file mode 100644 index a3c92a360..000000000 --- a/libsrc/telemon24/crt0.s +++ /dev/null @@ -1,101 +0,0 @@ -; -; Startup code for cc65 (Oric version) -; -; By Debrune Jérôme <jede@oric.org> and Ullrich von Bassewitz <uz@cc65.org> -; 2016-03-18, Greg King -; - - .export _exit - .export __STARTUP__ : absolute = 1 ; Mark as startup - - .import initlib, donelib - .import callmain, zerobss - .import __MAIN_START__, __MAIN_SIZE__ - - .include "zeropage.inc" - .include "telemon24.inc" - -; ------------------------------------------------------------------------ -; Place the startup code in a special segment. - -.segment "STARTUP" - - tsx - stx spsave ; Save system stk ptr - -; Save space by putting some of the start-up code in a segment -; that will be re-used. - - jsr init - -; Clear the BSS variables (after the constructors have been run). - - jsr zerobss - -; Push the command-line arguments; and, call main(). - - jsr callmain - -; Call the module destructors. This is also the exit() entry. - -_exit: jsr donelib - -; Restore the system stuff. - - ldx spsave - txs -; lda stsave - ; sta STATUS - -; Copy back the zero-page stuff. - - ldx #zpspace - 1 -L2: lda zpsave,x - sta sp,x - dex - bpl L2 - -; Back to BASIC. - - rts - -; ------------------------------------------------------------------------ -; Put this code in a place that will be re-used by BSS, the heap, -; and the C stack. - -.segment "ONCE" - -; Save the zero-page area that we're about to use. - -init: ldx #zpspace - 1 -L1: lda sp,x - sta zpsave,x - dex - bpl L1 - -; Currently, color isn't supported on the text screen. -; Unprotect screen columns 0 and 1 (where each line's color codes would sit). - - ; lda STATUS - ; sta stsave - ; and #%11011111 - ; sta STATUS - -; Set up the C stack. - - lda #<(__MAIN_START__ + __MAIN_SIZE__) - ldx #>(__MAIN_START__ + __MAIN_SIZE__) - sta sp - stx sp+1 ; Set argument stack ptr - -; Call the module constructors. - - jmp initlib - -; ------------------------------------------------------------------------ - -.segment "INIT" - -spsave: .res 1 -stsave: .res 1 -zpsave: .res zpspace diff --git a/libsrc/telemon24/hires.s b/libsrc/telemon24/hires.s deleted file mode 100644 index 80d67824c..000000000 --- a/libsrc/telemon24/hires.s +++ /dev/null @@ -1,22 +0,0 @@ -; -; Ullrich von Bassewitz, 2003-04-13 -; -; void hires(void); -; -; This function is a hack! -; - - .export _hires - - - .include "telemon24.inc" - - -; can be optimized with a macro -.proc _hires - brk - .byt $1a - rts -.endproc - - diff --git a/libsrc/telemon24/mainargs.s b/libsrc/telemon24/mainargs.s deleted file mode 100644 index d8547e500..000000000 --- a/libsrc/telemon24/mainargs.s +++ /dev/null @@ -1,36 +0,0 @@ -; -; 2003-03-07, Ullrich von Bassewitz -; 2011-01-28, Stefan Haubenthal -; 2014-09-10, Greg King -; -; Set up arguments for main -; - - .constructor initmainargs, 24 - .import __argc, __argv - - .include "telemon24.inc" - .macpack generic - -MAXARGS = 10 ; Maximum number of arguments allowed - - -.segment "ONCE" - -.proc initmainargs - -.endproc - -.segment "INIT" - -term: .res 1 -name: .res FNAME_LEN + 1 -args: .res SCREEN_XSIZE * 2 - 1 - -.data - -; This array has zeroes when initmainargs starts. -; char* argv[MAXARGS+1]={name}; - -argv: .addr name - .res MAXARGS * 2 diff --git a/libsrc/telemon24/print.s b/libsrc/telemon24/print.s deleted file mode 100644 index a135cdd18..000000000 --- a/libsrc/telemon24/print.s +++ /dev/null @@ -1,25 +0,0 @@ -; -; Jede -; -; print (char * str); -; -; This function is a hack! -; - - .export _print - .import popax - .importzp tmp1 - .include "telemon24.inc" - -.proc _print - - jsr popax ; get buf - stx tmp1 - ldy tmp1 - brk - .byte $14 - rts - -.endproc - - diff --git a/libsrc/telemon24/tapehdr.s b/libsrc/telemon24/tapehdr.s deleted file mode 100644 index 9b183e11e..000000000 --- a/libsrc/telemon24/tapehdr.s +++ /dev/null @@ -1,36 +0,0 @@ -; -; Based on code by Debrune Jérôme <jede@oric.org> -; 2016-03-17, Greg King -; - - ; The following symbol is used by the linker config. file - ; to force this module to be included into the output file. - .export __ORIXHDR__:abs = 1 - - ; These symbols, also, come from the configuration file. - .import __AUTORUN__, __PROGFLAG__ - .import __BASHEAD_START__, __MAIN_LAST__ - - -; ------------------------------------------------------------------------ -; Oric cassette-tape header - -.segment "ORIXHDR" - - .byte $01, $00 ; - - .byte "ORI" - - .byte $01 ; version - .byte $00,$00 ; mode - .byte $00,$00 ; cpu type - .byte $00,$00 ; OS - - .byte $00 ; reserved - .byte $00 ; auto - - - .dbyt __BASHEAD_START__ ; Address of start of file - .dbyt __MAIN_LAST__ - 1 ; Address of end of file - .dbyt __BASHEAD_START__ ; Address of start of file - diff --git a/libsrc/telemon24/write.s b/libsrc/telemon24/write.s deleted file mode 100644 index 32bbf617c..000000000 --- a/libsrc/telemon24/write.s +++ /dev/null @@ -1,59 +0,0 @@ -; -; Ullrich von Bassewitz, 2003-04-13 -; -; int write (int fd, const void* buf, int count); -; -; This function is a hack! -; - - .export _write - .import popax - .importzp ptr1, ptr2, ptr3, tmp1 - - .include "telemon24.inc" - -.proc _write - - sta ptr3 - stx ptr3+1 ; save count as result - - eor #$FF - sta ptr2 - txa - eor #$FF - sta ptr2+1 ; Remember -count-1 - - jsr popax ; get buf - sta ptr1 - stx ptr1+1 - jsr popax ; get fd and discard -L1: inc ptr2 - bne L2 - inc ptr2+1 - beq L9 -L2: ldy #0 - lda (ptr1),y - tax - cpx #$0A ; Check for \n - bne L3 - brk - .byt $10 - - ldx #$0D -L3: - brk - .byt $10 - inc ptr1 - bne L1 - inc ptr1+1 - jmp L1 - -; No error, return count - -L9: lda ptr3 - ldx ptr3+1 - rts - -.endproc - - diff --git a/libsrc/telemon30/_close.s b/libsrc/telemon30/_close.s deleted file mode 100644 index 84bee3a1b..000000000 --- a/libsrc/telemon30/_close.s +++ /dev/null @@ -1,17 +0,0 @@ - .export _close - .import addysp,popax - .importzp sp,tmp2,tmp3,tmp1 - - ; int open (const char* name, int flags, ...); /* May take a mode argument */ - .include "telemon30.inc" - .include "errno.inc" - .include "fcntl.inc" - -.proc _close -; Throw away any additional parameters passed through the ellipsis - - BRK_TELEMON XCLOSE ; launch primitive ROM - rts -.endproc - - \ No newline at end of file diff --git a/libsrc/telemon30/_read.s b/libsrc/telemon30/_read.s deleted file mode 100644 index ee822f1fd..000000000 --- a/libsrc/telemon30/_read.s +++ /dev/null @@ -1,41 +0,0 @@ -; -; jede jede@oric.org 2017-01-22 -; - - - .FEATURE c_comments,labels_without_colons,pc_assignment, loose_char_term - .export _read - .import popax - - .include "zeropage.inc" - .include "telemon30.inc" -; int read (int fd, void* buf, unsigned count); - -.proc _read - sta ptr1 ; count - stx ptr1+1 ; count - jsr popax ; get buf - - sta PTR_READ_DEST - stx PTR_READ_DEST+1 - sta ptr2 ; in order to calculate nb of bytes read - stx ptr2+1 ; - - ; jsr popax ; fp pointer don't care in this version - - lda ptr1 ; - ldy ptr1+1 ; - BRK_TELEMON XFREAD ; calls telemon30 routine - ; compute nb of bytes read - lda PTR_READ_DEST+1 - sec - sbc ptr2+1 - tax - lda PTR_READ_DEST - sec - sbc ptr2 - ; Here A and X contains number of bytes read - rts -.endproc - - diff --git a/libsrc/telemon30/_scrsize.s b/libsrc/telemon30/_scrsize.s deleted file mode 100644 index a929f97b1..000000000 --- a/libsrc/telemon30/_scrsize.s +++ /dev/null @@ -1,19 +0,0 @@ -; -; 2003-04-13, Ullrich von Bassewitz -; 2013-07-16, Greg King -; -; Screen size variables -; - - .export screensize - .include "telemon30.inc" - -.proc screensize - - ldx #SCREEN_XSIZE - ldy #SCREEN_YSIZE - rts - -.endproc - - diff --git a/libsrc/telemon30/ch376.s b/libsrc/telemon30/ch376.s deleted file mode 100644 index 460a70052..000000000 --- a/libsrc/telemon30/ch376.s +++ /dev/null @@ -1,366 +0,0 @@ - - ; For XA65 compatibily in the future - .FEATURE c_comments,labels_without_colons,pc_assignment, loose_char_term - .export _ch376_set_file_name - .export _ch376_file_open - .export _ch376_ic_get_version - .export _ch376_reset - .export _ch376_check_exist - .export _ch376_disk_mount - .export _ch376_set_usb_mode - - .export _ch376_file_close - .export _ch376_seek_file - .export _ch376_file_create - .export _ch376_fwrite - ; High level function - - - .import popax - .include "zeropage.inc" - .include "telemon30.inc" -/* - -*/ -; CODE FOR CH376_SET_USB_MODE ************************************************* - -CH376_SET_USB_MODE_CODE_USB_HOST_SOF_PACKAGE_AUTOMATICALLY := $06 - -CH376_USB_INT_SUCCESS := $14 -CH376_USB_INT_CONNECT := $15 -CH376_USB_INT_DISCONNECT := $16 -CH376_USB_INT_BUF_OVER := $17 -CH376_USB_INT_USB_READY := $18 -CH376_USB_INT_DISK_READ := $1D -CH376_USB_INT_DISK_WRITE := $1E -CH376_USB_INT_DISK_ERR := $1F - - -CH376_ERR_OPEN_DIR := $41 -CH376_ERR_MISS_FILE := $42 -CH376_ERR_FOUND_NAME := $43 -CH376_ERR_DISK_DISCON := $82 -CH376_ERR_LARGE_SECTOR := $84 -CH376_ERR_TYPE_ERROR := $92 -CH376_ERR_BPB_ERROR := $A1 -CH376_ERR_DISK_FULL := $B1 -CH376_ERR_FDT_OVER := $B2 -CH376_ERR_FILE_CLOSE := $B4 - - - -CH376_GET_IC_VER := $01 -CH376_SET_BAUDRATE := $02 -CH376_GET_ENTER_SLEEP := $03 -CH376_RESET_ALL := $05 -CH376_CHECK_EXIST := $06 -CH376_GET_FILE_SIZE := $0C - -CH376_SET_USB_MODE := $15 -CH376_GET_STATUS := $22 -CH376_RD_USB_DATA0 := $27 -CH376_CMD_WR_REQ_DATA := $2d -CH376_SET_FILE_NAME := $2F - -CH376_DISK_CONNECT := $30 ; check the disk connection status -CH376_DISK_MOUNT := $31 -CH376_FILE_OPEN := $32 -CH376_FILE_ENUM_GO := $33 -CH376_FILE_CREATE := $34 -CH376_FILE_CLOSE := $36 -CH376_BYTE_LOCATE := $39 -CH376_BYTE_READ := $3A -CH376_BYTE_RD_GO := $3B -CH376_BYTE_WRITE := $3C -CH376_BYTE_WR_GO := $3D -CH376_DISK_CAPACITY := $3E -CH376_DISK_RD_GO := $55 - -.proc _ch376_file_close - lda #CH376_FILE_CLOSE - sta CH376_COMMAND - jsr _ch376_wait_response - rts -.endproc - -.proc _ch376_seek_file - ldx #CH376_BYTE_LOCATE - stx CH376_COMMAND - sta CH376_DATA - sty CH376_DATA - lda #$00 ; Don't manage 32 bits length - sta CH376_DATA - sta CH376_DATA - jsr _ch376_wait_response - rts -.endproc - -; void ch376_set_file_name(char *filename) -.proc _ch376_set_file_name - sta ptr1 - stx ptr1+1 - lda #CH376_SET_FILE_NAME ;$2f - sta CH376_COMMAND - ldy #0 -loop: - lda (ptr1),y ; replace by bufnom - beq end ; we reached 0 value - BRK_TELEMON XMINMA - sta CH376_DATA - iny - cpy #13 ; because we don't manage longfilename shortname =11 - bne loop -end: - sta CH376_DATA - rts -.endproc - -; char _ch376_file_open(); - -.proc _ch376_file_open - lda #CH376_FILE_OPEN ; $32 - sta CH376_COMMAND - jsr _ch376_wait_response - rts -.endproc - - - -.proc _ch376_get_file_size - lda #CH376_GET_FILE_SIZE - sta CH376_COMMAND - lda #$68 - sta CH376_DATA - ; store file length 32 bits - lda CH376_DATA - sta tmp1 - lda CH376_DATA - sta tmp1+1 - lda CH376_DATA - sta tmp2 - lda CH376_DATA - sta tmp2+1 - rts -.endproc - -; void ch376_reset(); - -.proc _ch376_reset - lda #CH376_RESET_ALL ; 5 - sta CH376_COMMAND - ; waiting - ldy #0 - ldx #0 -loop: - nop - inx - bne loop - iny - bne loop - rts -.endproc - -; char ch376_check_exist(char value); - -.proc _ch376_check_exist - sta tmp1 - lda #CH376_CHECK_EXIST ; - sta CH376_COMMAND - lda tmp1 - sta CH376_DATA - lda CH376_DATA - rts -.endproc - -; char ch376_ic_get_version(void) -.proc _ch376_ic_get_version - lda #CH376_GET_IC_VER - sta CH376_COMMAND - ldx #0 - lda CH376_DATA - rts -.endproc - -; void ch376_set_usb_mode(char mode) - -.proc _ch376_set_usb_mode -; CH376_SET_USB_MODE_CODE_USB_HOST_SOF_PACKAGE_AUTOMATICALLY - ldx #CH376_SET_USB_MODE ; $15 - stx CH376_COMMAND - sta CH376_DATA - rts -.endproc - -; void ch376_set_bytes_write(int value); -.proc _ch376_set_bytes_write - ldy #CH376_BYTE_WRITE - sty CH376_COMMAND - sta CH376_DATA - stx CH376_DATA - lda #0 - sta CH376_DATA - sta CH376_DATA - jsr _ch376_wait_response - rts -.endproc - -.proc _ch376_set_bytes_read - ldy #CH376_BYTE_READ - sty CH376_COMMAND - ; Storing 32 bits value - sta CH376_DATA - stx CH376_DATA - lda #0 - sta CH376_DATA - sta CH376_DATA - jsr _ch376_wait_response - rts -.endproc - -; char ch376_disk_mount(); -.proc _ch376_disk_mount - lda #CH376_DISK_MOUNT ; $31 - sta CH376_COMMAND - jsr _ch376_wait_response - ; if we read data value, we have then length of the volume name - ldx #0 - rts -.endproc - - -; char ch376_wait_response(); -.proc _ch376_wait_response -; 1 return 1 if usb controller does not respond -; else A contains answer of the controller - ldy #$ff -loop3: - ldx #$ff ; don't decrease this counter. Because ch376 won't respond if there is a lower value -loop: - lda CH376_COMMAND - and #%10000000 - cmp #128 - bne no_error - dex - bne loop - dey - bne loop3 - ; error is here - rts -no_error: - lda #CH376_GET_STATUS - sta CH376_COMMAND - lda CH376_DATA - rts -.endproc - -.proc _ch376_fread - ; use ptr1 to count bytes - jsr _ch376_set_bytes_read - -continue: - cmp #CH376_USB_INT_DISK_READ ; something to read - beq we_read - cmp #CH376_USB_INT_SUCCESS ; finished - beq finished - ; TODO in A : $ff X: $ff - lda #0 - tax - rts -we_read: - lda #CH376_RD_USB_DATA0 - sta CH376_COMMAND - - lda CH376_DATA ; contains length read - sta tmp2; Number of bytes to read - - ldy #0 -loop: - lda CH376_DATA ; read the data - sta (PTR_READ_DEST),y - - iny - cpy tmp2 - bne loop - tya - clc - adc PTR_READ_DEST - bcc next - inc PTR_READ_DEST+1 -next: - sta PTR_READ_DEST - - lda #CH376_BYTE_RD_GO - sta CH376_COMMAND - jsr _ch376_wait_response - jmp continue -finished: - ; TODO return bytes read - lda tmp1 - ldx tmp1+1 - rts -.endproc - -; void _ch376_fwrite(void *ptr,int number) -.proc _ch376_fwrite - ; use ptr1 to count bytes - sta ptr2 - stx ptr2+1 - - jsr popax - sta PTR_READ_DEST - stx PTR_READ_DEST+1 - - lda ptr2 - ldx ptr2+1 - jsr _ch376_set_bytes_write - ;cmp #CH376_USB_INT_SUCCESS - ;beq finished - ;jsr popax - - ;jsr _ch376_wait_response - -continue: - cmp #CH376_USB_INT_DISK_WRITE ; something to read - beq we_read - cmp #CH376_USB_INT_SUCCESS ; finished - beq finished - ; TODO in A : $ff X: $ff - lda #0 - tax - rts -we_read: - lda #CH376_CMD_WR_REQ_DATA - sta CH376_COMMAND - - lda CH376_DATA ; contains length read - sta tmp2; Number of bytes to read - - - ;ldy #0 -loop: - ;lda (PTR_READ_DEST),y - lda #65 - sta CH376_DATA ; read the data - dec tmp2 - bne loop - - - lda #CH376_BYTE_WR_GO - sta CH376_COMMAND - jsr _ch376_wait_response - jmp continue -finished: - ; TODO return bytes read - lda tmp1 - ;lda #<8000 - ldx tmp1+1 - ;ldx #>8000 - rts -.endproc - -.proc _ch376_file_create - lda #CH376_FILE_CREATE - sta CH376_COMMAND - jsr _ch376_wait_response - rts -.endproc \ No newline at end of file diff --git a/libsrc/telemon30/ctype.s b/libsrc/telemon30/ctype.s deleted file mode 100644 index 79edafbb2..000000000 --- a/libsrc/telemon30/ctype.s +++ /dev/null @@ -1,299 +0,0 @@ -; -; Ullrich von Bassewitz, 2003-04-13 -; -; Character specification table. -; - -; The tables are readonly, put them into the rodata segment - -.rodata - -; The following 256 byte wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it -; has major advantages: -; -; * It is fast. If it were'nt for the slow parameter passing of cc65, one -; could even define macros for the isxxx functions (this is usually -; done on other platforms). -; -; * It is highly portable. The only unportable part is the table itself, -; all real code goes into the common library. -; -; * We save some code in the isxxx functions. -; -; -; Bit assignments: -; -; 0 - Lower case char -; 1 - Upper case char -; 2 - Numeric digit -; 3 - Hex digit (both, lower and upper) -; 4 - Control character -; 5 - The space character itself -; 6 - Other whitespace (that is: '\f', '\n', '\r', '\t' and '\v') -; 7 - Space or tab character - - .export __ctype - -__ctype: - .byte $10 ; 0/00 ___ctrl_@___ - .byte $10 ; 1/01 ___ctrl_A___ - .byte $10 ; 2/02 ___ctrl_B___ - .byte $10 ; 3/03 ___ctrl_C___ - .byte $10 ; 4/04 ___ctrl_D___ - .byte $10 ; 5/05 ___ctrl_E___ - .byte $10 ; 6/06 ___ctrl_F___ - .byte $10 ; 7/07 ___ctrl_G___ - .byte $10 ; 8/08 ___ctrl_H___ - .byte $D0 ; 9/09 ___ctrl_I___ - .byte $50 ; 10/0a ___ctrl_J___ - .byte $50 ; 11/0b ___ctrl_K___ - .byte $50 ; 12/0c ___ctrl_L___ - .byte $50 ; 13/0d ___ctrl_M___ - .byte $10 ; 14/0e ___ctrl_N___ - .byte $10 ; 15/0f ___ctrl_O___ - .byte $10 ; 16/10 ___ctrl_P___ - .byte $10 ; 17/11 ___ctrl_Q___ - .byte $10 ; 18/12 ___ctrl_R___ - .byte $10 ; 19/13 ___ctrl_S___ - .byte $10 ; 20/14 ___ctrl_T___ - .byte $10 ; 21/15 ___ctrl_U___ - .byte $10 ; 22/16 ___ctrl_V___ - .byte $10 ; 23/17 ___ctrl_W___ - .byte $10 ; 24/18 ___ctrl_X___ - .byte $10 ; 25/19 ___ctrl_Y___ - .byte $10 ; 26/1a ___ctrl_Z___ - .byte $10 ; 27/1b ___ctrl_[___ - .byte $10 ; 28/1c ___ctrl_\___ - .byte $10 ; 29/1d ___ctrl_]___ - .byte $10 ; 30/1e ___ctrl_^___ - .byte $10 ; 31/1f ___ctrl_____ - .byte $A0 ; 32/20 ___SPACE___ - .byte $00 ; 33/21 _____!_____ - .byte $00 ; 34/22 _____"_____ - .byte $00 ; 35/23 _____#_____ - .byte $00 ; 36/24 _____$_____ - .byte $00 ; 37/25 _____%_____ - .byte $00 ; 38/26 _____&_____ - .byte $00 ; 39/27 _____'_____ - .byte $00 ; 40/28 _____(_____ - .byte $00 ; 41/29 _____)_____ - .byte $00 ; 42/2a _____*_____ - .byte $00 ; 43/2b _____+_____ - .byte $00 ; 44/2c _____,_____ - .byte $00 ; 45/2d _____-_____ - .byte $00 ; 46/2e _____._____ - .byte $00 ; 47/2f _____/_____ - .byte $0C ; 48/30 _____0_____ - .byte $0C ; 49/31 _____1_____ - .byte $0C ; 50/32 _____2_____ - .byte $0C ; 51/33 _____3_____ - .byte $0C ; 52/34 _____4_____ - .byte $0C ; 53/35 _____5_____ - .byte $0C ; 54/36 _____6_____ - .byte $0C ; 55/37 _____7_____ - .byte $0C ; 56/38 _____8_____ - .byte $0C ; 57/39 _____9_____ - .byte $00 ; 58/3a _____:_____ - .byte $00 ; 59/3b _____;_____ - .byte $00 ; 60/3c _____<_____ - .byte $00 ; 61/3d _____=_____ - .byte $00 ; 62/3e _____>_____ - .byte $00 ; 63/3f _____?_____ - - .byte $00 ; 64/40 _____@_____ - .byte $0A ; 65/41 _____A_____ - .byte $0A ; 66/42 _____B_____ - .byte $0A ; 67/43 _____C_____ - .byte $0A ; 68/44 _____D_____ - .byte $0A ; 69/45 _____E_____ - .byte $0A ; 70/46 _____F_____ - .byte $02 ; 71/47 _____G_____ - .byte $02 ; 72/48 _____H_____ - .byte $02 ; 73/49 _____I_____ - .byte $02 ; 74/4a _____J_____ - .byte $02 ; 75/4b _____K_____ - .byte $02 ; 76/4c _____L_____ - .byte $02 ; 77/4d _____M_____ - .byte $02 ; 78/4e _____N_____ - .byte $02 ; 79/4f _____O_____ - .byte $02 ; 80/50 _____P_____ - .byte $02 ; 81/51 _____Q_____ - .byte $02 ; 82/52 _____R_____ - .byte $02 ; 83/53 _____S_____ - .byte $02 ; 84/54 _____T_____ - .byte $02 ; 85/55 _____U_____ - .byte $02 ; 86/56 _____V_____ - .byte $02 ; 87/57 _____W_____ - .byte $02 ; 88/58 _____X_____ - .byte $02 ; 89/59 _____Y_____ - .byte $02 ; 90/5a _____Z_____ - .byte $00 ; 91/5b _____[_____ - .byte $00 ; 92/5c _____\_____ - .byte $00 ; 93/5d _____]_____ - .byte $00 ; 94/5e _____^_____ - .byte $00 ; 95/5f _UNDERLINE_ - .byte $00 ; 96/60 ___grave___ - .byte $09 ; 97/61 _____a_____ - .byte $09 ; 98/62 _____b_____ - .byte $09 ; 99/63 _____c_____ - .byte $09 ; 100/64 _____d_____ - .byte $09 ; 101/65 _____e_____ - .byte $09 ; 102/66 _____f_____ - .byte $01 ; 103/67 _____g_____ - .byte $01 ; 104/68 _____h_____ - .byte $01 ; 105/69 _____i_____ - .byte $01 ; 106/6a _____j_____ - .byte $01 ; 107/6b _____k_____ - .byte $01 ; 108/6c _____l_____ - .byte $01 ; 109/6d _____m_____ - .byte $01 ; 110/6e _____n_____ - .byte $01 ; 111/6f _____o_____ - .byte $01 ; 112/70 _____p_____ - .byte $01 ; 113/71 _____q_____ - .byte $01 ; 114/72 _____r_____ - .byte $01 ; 115/73 _____s_____ - .byte $01 ; 116/74 _____t_____ - .byte $01 ; 117/75 _____u_____ - .byte $01 ; 118/76 _____v_____ - .byte $01 ; 119/77 _____w_____ - .byte $01 ; 120/78 _____x_____ - .byte $01 ; 121/79 _____y_____ - .byte $01 ; 122/7a _____z_____ - .byte $00 ; 123/7b _____{_____ - .byte $00 ; 124/7c _____|_____ - .byte $00 ; 125/7d _____}_____ - .byte $00 ; 126/7e _____~_____ - .byte $40 ; 127/7f ____DEL____ - - .byte $00 ; 128/80 ___________ - .byte $00 ; 129/81 ___________ - .byte $00 ; 130/82 ___________ - .byte $00 ; 131/83 ___________ - .byte $00 ; 132/84 ___________ - .byte $00 ; 133/85 ___________ - .byte $00 ; 134/86 ___________ - .byte $00 ; 135/87 ___________ - .byte $00 ; 136/88 ___________ - .byte $00 ; 137/89 ___________ - .byte $00 ; 138/8a ___________ - .byte $00 ; 139/8b ___________ - .byte $00 ; 140/8c ___________ - .byte $00 ; 141/8d ___________ - .byte $00 ; 142/8e ___________ - .byte $00 ; 143/8f ___________ - .byte $00 ; 144/90 ___________ - .byte $00 ; 145/91 ___________ - .byte $00 ; 146/92 ___________ - .byte $10 ; 147/93 ___________ - .byte $00 ; 148/94 ___________ - .byte $00 ; 149/95 ___________ - .byte $00 ; 150/96 ___________ - .byte $00 ; 151/97 ___________ - .byte $00 ; 152/98 ___________ - .byte $00 ; 153/99 ___________ - .byte $00 ; 154/9a ___________ - .byte $00 ; 155/9b ___________ - .byte $00 ; 156/9c ___________ - .byte $00 ; 157/9d ___________ - .byte $00 ; 158/9e ___________ - .byte $00 ; 159/9f ___________ - - .byte $00 ; 160/a0 ___________ - .byte $00 ; 161/a1 ___________ - .byte $00 ; 162/a2 ___________ - .byte $00 ; 163/a3 ___________ - .byte $00 ; 164/a4 ___________ - .byte $00 ; 165/a5 ___________ - .byte $00 ; 166/a6 ___________ - .byte $00 ; 167/a7 ___________ - .byte $00 ; 168/a8 ___________ - .byte $00 ; 169/a9 ___________ - .byte $00 ; 170/aa ___________ - .byte $00 ; 171/ab ___________ - .byte $00 ; 172/ac ___________ - .byte $00 ; 173/ad ___________ - .byte $00 ; 174/ae ___________ - .byte $00 ; 175/af ___________ - .byte $00 ; 176/b0 ___________ - .byte $00 ; 177/b1 ___________ - .byte $00 ; 178/b2 ___________ - .byte $00 ; 179/b3 ___________ - .byte $00 ; 180/b4 ___________ - .byte $00 ; 181/b5 ___________ - .byte $00 ; 182/b6 ___________ - .byte $00 ; 183/b7 ___________ - .byte $00 ; 184/b8 ___________ - .byte $00 ; 185/b9 ___________ - .byte $00 ; 186/ba ___________ - .byte $00 ; 187/bb ___________ - .byte $00 ; 188/bc ___________ - .byte $00 ; 189/bd ___________ - .byte $00 ; 190/be ___________ - .byte $00 ; 191/bf ___________ - - .byte $02 ; 192/c0 ___________ - .byte $02 ; 193/c1 ___________ - .byte $02 ; 194/c2 ___________ - .byte $02 ; 195/c3 ___________ - .byte $02 ; 196/c4 ___________ - .byte $02 ; 197/c5 ___________ - .byte $02 ; 198/c6 ___________ - .byte $02 ; 199/c7 ___________ - .byte $02 ; 200/c8 ___________ - .byte $02 ; 201/c9 ___________ - .byte $02 ; 202/ca ___________ - .byte $02 ; 203/cb ___________ - .byte $02 ; 204/cc ___________ - .byte $02 ; 205/cd ___________ - .byte $02 ; 206/ce ___________ - .byte $02 ; 207/cf ___________ - .byte $02 ; 208/d0 ___________ - .byte $02 ; 209/d1 ___________ - .byte $02 ; 210/d2 ___________ - .byte $02 ; 211/d3 ___________ - .byte $02 ; 212/d4 ___________ - .byte $02 ; 213/d5 ___________ - .byte $02 ; 214/d6 ___________ - .byte $02 ; 215/d7 ___________ - .byte $02 ; 216/d8 ___________ - .byte $02 ; 217/d9 ___________ - .byte $02 ; 218/da ___________ - .byte $02 ; 219/db ___________ - .byte $02 ; 220/dc ___________ - .byte $02 ; 221/dd ___________ - .byte $02 ; 222/de ___________ - .byte $00 ; 223/df ___________ - .byte $01 ; 224/e0 ___________ - .byte $01 ; 225/e1 ___________ - .byte $01 ; 226/e2 ___________ - .byte $01 ; 227/e3 ___________ - .byte $01 ; 228/e4 ___________ - .byte $01 ; 229/e5 ___________ - .byte $01 ; 230/e6 ___________ - .byte $01 ; 231/e7 ___________ - .byte $01 ; 232/e8 ___________ - .byte $01 ; 233/e9 ___________ - .byte $01 ; 234/ea ___________ - .byte $01 ; 235/eb ___________ - .byte $01 ; 236/ec ___________ - .byte $01 ; 237/ed ___________ - .byte $01 ; 238/ee ___________ - .byte $01 ; 239/ef ___________ - .byte $01 ; 240/f0 ___________ - .byte $01 ; 241/f1 ___________ - .byte $01 ; 242/f2 ___________ - .byte $01 ; 243/f3 ___________ - .byte $01 ; 244/f4 ___________ - .byte $01 ; 245/f5 ___________ - .byte $01 ; 246/f6 ___________ - .byte $01 ; 247/f7 ___________ - .byte $01 ; 248/f8 ___________ - .byte $01 ; 249/f9 ___________ - .byte $01 ; 250/fa ___________ - .byte $01 ; 251/fb ___________ - .byte $01 ; 252/fc ___________ - .byte $01 ; 253/fd ___________ - .byte $01 ; 254/fe ___________ - .byte $00 ; 255/ff ___________ - diff --git a/libsrc/telemon30/graphics.s b/libsrc/telemon30/graphics.s deleted file mode 100644 index 4f2b09162..000000000 --- a/libsrc/telemon30/graphics.s +++ /dev/null @@ -1,54 +0,0 @@ - .export _paper,_hires,_text,_circle,_curset, _switchOffCursor - .importzp sp,tmp2,tmp3,tmp1 - .import popa - .include "telemon30.inc" - -.proc _paper - ldx #0 ; First window - ; A contains the paper - BRK_TELEMON XPAPER - rts -.endproc - -; XINK is bugged, it corrupt memory : removing from export -.proc _ink - ldx #0 ; First window - ; A contains the ink - BRK_TELEMON XINK - rts -.endproc - -; can be optimized with a macro -.proc _hires - BRK_TELEMON XHIRES - rts -.endproc - -.proc _text - BRK_TELEMON XTEXT - rts -.endproc - -.proc _curset - jsr popa ; Pixel - jsr popa - sta HRSX - jsr popa - sta HRSY - BRK_TELEMON XCURSE - rts -.endproc - -.proc _circle - sta HRS1 - BRK_TELEMON XCIRCL - rts -.endproc - -.proc _switchOffCursor - ldx #0 - BRK_TELEMON XCOSCR - rts -.endproc - - diff --git a/libsrc/telemon30/keyboard.s b/libsrc/telemon30/keyboard.s deleted file mode 100644 index 974f841e6..000000000 --- a/libsrc/telemon30/keyboard.s +++ /dev/null @@ -1,13 +0,0 @@ - .export _key - .importzp sp,tmp2,tmp3,tmp1 - - .include "telemon30.inc" - - -; char key(void); - -.proc _key - BRK_TELEMON XRDW0 ; read keyboard - rts -.endproc - diff --git a/libsrc/telemon30/oserrlist.s b/libsrc/telemon30/oserrlist.s deleted file mode 100644 index 8ec41de6d..000000000 --- a/libsrc/telemon30/oserrlist.s +++ /dev/null @@ -1,75 +0,0 @@ -; -; Stefan Haubenthal, 2004-05-25 -; Ullrich von Bassewitz, 18.07.2002 -; -; Defines the platform specific error list. -; -; The table is built as a list of entries -; -; .byte entrylen -; .byte errorcode -; .asciiz errormsg -; -; and terminated by an entry with length zero that is returned if the -; error code could not be found. -; - - .export __sys_oserrlist - -;---------------------------------------------------------------------------- -; Macros used to generate the list (may get moved to an include file?) - -; Regular entry -.macro sys_oserr_entry code, msg - .local Start, End -Start: .byte End - Start - .byte code - .asciiz msg -End: -.endmacro - -; Sentinel entry -.macro sys_oserr_sentinel msg - .byte 0 ; Length is always zero - .byte 0 ; Code is unused - .asciiz msg -.endmacro - -;---------------------------------------------------------------------------- -; The error message table - -.rodata - -__sys_oserrlist: - sys_oserr_entry 1, "File not found" - sys_oserr_entry 2, "Invalid command end" - sys_oserr_entry 3, "No drive number" - sys_oserr_entry 4, "Bad drive number" - sys_oserr_entry 5, "Invalid filename" - sys_oserr_entry 6, "fderr=(error number)" - sys_oserr_entry 7, "Illegal attribute" - sys_oserr_entry 8, "Wildcard(s) not allowed" - sys_oserr_entry 9, "File already exists" - sys_oserr_entry 10, "Insufficient disc space" - sys_oserr_entry 11, "File open" - sys_oserr_entry 12, "Illegal quantity" - sys_oserr_entry 13, "End address missing" - sys_oserr_entry 14, "Start address > end address" - sys_oserr_entry 15, "Missing 'to'" - sys_oserr_entry 16, "Renamed file not on same disc" - sys_oserr_entry 17, "Unknown array" - sys_oserr_entry 18, "Target drive not source drive" - sys_oserr_entry 19, "Destination not specified" - sys_oserr_entry 20, "Cannot merge and overwrite" - sys_oserr_entry 21, "Single target file illegal" - sys_oserr_entry 22, "Syntax" - sys_oserr_entry 23, "Filename missing" - sys_oserr_entry 24, "Source file missing" - sys_oserr_entry 25, "Type mismatch" - sys_oserr_entry 26, "Disc write-protected" - sys_oserr_entry 27, "Incompatible drives" - sys_oserr_entry 28, "File not open" - sys_oserr_entry 29, "File end" - sys_oserr_sentinel "Unknown error" - - diff --git a/libsrc/telemon30/oserror.s b/libsrc/telemon30/oserror.s deleted file mode 100644 index 37c9bd7fc..000000000 --- a/libsrc/telemon30/oserror.s +++ /dev/null @@ -1,17 +0,0 @@ -; -; Stefan Haubenthal, 2011-04-18 -; -; int __fastcall__ _osmaperrno (unsigned char oserror); -; /* Map a system specific error into a system independent code */ -; - - .include "errno.inc" - .export __osmaperrno - -.proc __osmaperrno - - lda #<EUNKNOWN - ldx #>EUNKNOWN - rts - -.endproc diff --git a/libsrc/telemon30/print.s b/libsrc/telemon30/print.s deleted file mode 100644 index 56c513fd6..000000000 --- a/libsrc/telemon30/print.s +++ /dev/null @@ -1,21 +0,0 @@ -; -; Jede -; -; print (char * str); -; -; This function is a hack! -; - - .export _print - .import popax - .importzp tmp1 - .include "telemon30.inc" - -.proc _print - stx tmp1 - ldy tmp1 - BRK_TELEMON XWSTR0 - rts -.endproc - - diff --git a/libsrc/telemon30/sound.s b/libsrc/telemon30/sound.s deleted file mode 100644 index 2df18f4a0..000000000 --- a/libsrc/telemon30/sound.s +++ /dev/null @@ -1,45 +0,0 @@ - .export _kbdclick1,_oups,_ping,_explode,_shoot,_zap - .include "telemon30.inc" - -.proc _kbdclick1 - LDX #<sound_bip_keyboard - LDY #>sound_bip_keyboard - BRK_TELEMON XSONPS - rts -sound_bip_keyboard: - .byte $1f,$00,$00,$00,$00,$00,$00,$3e,$10,$00,$00,$1f,$00,$00 -.endproc - -.proc _explode - BRK_TELEMON XEXPLO - rts -.endproc - -.proc _oups - BRK_TELEMON XOUPS - rts -.endproc - -.proc _ping - BRK_TELEMON XPING - rts -.endproc - -.proc _shoot - BRK_TELEMON XSHOOT - rts -.endproc - -.proc _zap - BRK_TELEMON XZAP - rts -.endproc - - - -; XPLAY := $43 -; XSOUND := $44 -; XMUSIC := $45 - - - diff --git a/libsrc/telemon30/sysuname.s b/libsrc/telemon30/sysuname.s deleted file mode 100644 index 51af1d8fe..000000000 --- a/libsrc/telemon30/sysuname.s +++ /dev/null @@ -1,46 +0,0 @@ -; -; 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 ((.VERSION >> 8) & $0F) + '0' - .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 $00 - - ; version - .if (.VERSION & $0F) > 9 - .byte (.VERSION & $0F) / 10 + '0' - .byte (.VERSION & $0F) .MOD 10 + '0' - .else - .byte (.VERSION & $0F) + '0' - .endif - .byte $00 - - ; machine - .asciiz "Oric Telestrat" diff --git a/libsrc/telestrat/ch376.s b/libsrc/telestrat/ch376.s new file mode 100644 index 000000000..fbfa16017 --- /dev/null +++ b/libsrc/telestrat/ch376.s @@ -0,0 +1,344 @@ + +; jede jede@oric.org 2017-01-22 + + ; For XA65 compatibily in the future + .FEATURE c_comments,labels_without_colons,pc_assignment, loose_char_term + .export _ch376_set_file_name + .export _ch376_file_open + .export _ch376_ic_get_version + .export _ch376_reset + .export _ch376_check_exist + .export _ch376_disk_mount + .export _ch376_set_usb_mode + .export _ch376_file_close + .export _ch376_seek_file + .export _ch376_file_create + .export _ch376_fwrite + + .import popax + .include "zeropage.inc" + .include "telestrat.inc" + + + + + +CH376_SET_USB_MODE_CODE_USB_HOST_SOF_PACKAGE_AUTOMATICALLY = $06 + +CH376_USB_INT_SUCCESS = $14 +CH376_USB_INT_CONNECT = $15 +CH376_USB_INT_DISCONNECT = $16 +CH376_USB_INT_BUF_OVER = $17 +CH376_USB_INT_USB_READY = $18 +CH376_USB_INT_DISK_READ = $1D +CH376_USB_INT_DISK_WRITE = $1E +CH376_USB_INT_DISK_ERR = $1F + + +CH376_ERR_OPEN_DIR = $41 +CH376_ERR_MISS_FILE = $42 +CH376_ERR_FOUND_NAME = $43 +CH376_ERR_DISK_DISCON = $82 +CH376_ERR_LARGE_SECTOR = $84 +CH376_ERR_TYPE_ERROR = $92 +CH376_ERR_BPB_ERROR = $A1 +CH376_ERR_DISK_FULL = $B1 +CH376_ERR_FDT_OVER = $B2 +CH376_ERR_FILE_CLOSE = $B4 + +CH376_GET_IC_VER = $01 +CH376_SET_BAUDRATE = $02 +CH376_GET_ENTER_SLEEP = $03 +CH376_RESET_ALL = $05 +CH376_CHECK_EXIST = $06 +CH376_GET_FILE_SIZE = $0C + +CH376_SET_USB_MODE = $15 +CH376_GET_STATUS = $22 +CH376_RD_USB_DATA0 = $27 +CH376_CMD_WR_REQ_DATA = $2D +CH376_SET_FILE_NAME = $2F + +CH376_DISK_CONNECT = $30 ; check the disk connection status +CH376_DISK_MOUNT = $31 +CH376_FILE_OPEN = $32 +CH376_FILE_ENUM_GO = $33 +CH376_FILE_CREATE = $34 +CH376_FILE_CLOSE = $36 +CH376_BYTE_LOCATE = $39 +CH376_BYTE_READ = $3A +CH376_BYTE_RD_GO = $3B +CH376_BYTE_WRITE = $3C +CH376_BYTE_WR_GO = $3D +CH376_DISK_CAPACITY = $3E +CH376_DISK_RD_GO = $55 + +.proc _ch376_file_close + lda #CH376_FILE_CLOSE + sta CH376_COMMAND + jsr _ch376_wait_response + rts +.endproc + +.proc _ch376_seek_file + ldx #CH376_BYTE_LOCATE + stx CH376_COMMAND + sta CH376_DATA + sty CH376_DATA + lda #$00 ; Don't manage 32 bits length + sta CH376_DATA + sta CH376_DATA + jsr _ch376_wait_response + rts +.endproc + +; void ch376_set_file_name(char *filename) +.proc _ch376_set_file_name + sta ptr1 + stx ptr1+1 + lda #CH376_SET_FILE_NAME ;$2f + sta CH376_COMMAND + ldy #0 +loop: + lda (ptr1),y ; replace by bufnom + beq end ; we reached 0 value + BRK_TELEMON XMINMA + sta CH376_DATA + iny + cpy #13 ; because we don't manage longfilename shortname =11 + bne loop +end: + sta CH376_DATA + rts +.endproc + +; char _ch376_file_open(); +.proc _ch376_file_open + lda #CH376_FILE_OPEN ; $32 + sta CH376_COMMAND + jsr _ch376_wait_response + rts +.endproc + +.proc _ch376_get_file_size + lda #CH376_GET_FILE_SIZE + sta CH376_COMMAND + lda #$68 + sta CH376_DATA + ; store file length 32 bits + lda CH376_DATA + sta tmp1 + lda CH376_DATA + sta tmp1+1 + lda CH376_DATA + sta tmp2 + lda CH376_DATA + sta tmp2+1 + rts +.endproc + +; void ch376_reset(); +.proc _ch376_reset + lda #CH376_RESET_ALL ; 5 + sta CH376_COMMAND + ; waiting + ldy #0 + ldx #0 +loop: + nop + inx + bne loop + iny + bne loop + rts +.endproc + +; char ch376_check_exist(char value); + +.proc _ch376_check_exist + sta tmp1 + lda #CH376_CHECK_EXIST ; + sta CH376_COMMAND + lda tmp1 + sta CH376_DATA + lda CH376_DATA + rts +.endproc + +; char ch376_ic_get_version(void) +.proc _ch376_ic_get_version + lda #CH376_GET_IC_VER + sta CH376_COMMAND + ldx #0 + lda CH376_DATA + rts +.endproc + +; void ch376_set_usb_mode(char mode) +.proc _ch376_set_usb_mode + ldx #CH376_SET_USB_MODE ; $15 + stx CH376_COMMAND + sta CH376_DATA + rts +.endproc + +; void ch376_set_bytes_write(int value); +.proc _ch376_set_bytes_write + ldy #CH376_BYTE_WRITE + sty CH376_COMMAND + sta CH376_DATA + stx CH376_DATA + lda #0 + sta CH376_DATA + sta CH376_DATA + jsr _ch376_wait_response + rts +.endproc + +.proc _ch376_set_bytes_read + ldy #CH376_BYTE_READ + sty CH376_COMMAND + ; Storing 32 bits value + sta CH376_DATA + stx CH376_DATA + lda #0 + sta CH376_DATA + sta CH376_DATA + jsr _ch376_wait_response + rts +.endproc + +; char ch376_disk_mount(); +.proc _ch376_disk_mount + lda #CH376_DISK_MOUNT ; $31 + sta CH376_COMMAND + jsr _ch376_wait_response + ; if we read data value, we have then length of the volume name + ldx #0 + rts +.endproc + + +; char ch376_wait_response(); +.proc _ch376_wait_response +; return 1 if usb controller does not respond +; else A contains answer of the controller + ldy #$FF ; We have to wait 35 ms, but well, this loop is broken when controler is OK +loop3: + ldx #$FF ; don't decrease this counter. Because ch376 won't respond if there is a lower value +loop: + lda CH376_COMMAND + and #%10000000 + cmp #128 + bne no_error + dex + bne loop + dey + bne loop3 + ; error is here + rts +no_error: + lda #CH376_GET_STATUS + sta CH376_COMMAND + lda CH376_DATA + rts +.endproc + +.proc _ch376_fread + ; use ptr1 to count bytes + jsr _ch376_set_bytes_read +continue: + cmp #CH376_USB_INT_DISK_READ ; something to read + beq we_read + cmp #CH376_USB_INT_SUCCESS ; finished + beq finished + ; TODO in A : $ff X: $ff + lda #0 + tax + rts +we_read: + lda #CH376_RD_USB_DATA0 + sta CH376_COMMAND + + lda CH376_DATA ; contains length read + sta tmp2; Number of bytes to read + + ldy #0 +loop: + lda CH376_DATA ; read the data + sta (PTR_READ_DEST),y + iny + cpy tmp2 + bne loop + tya + clc + adc PTR_READ_DEST + bcc next + inc PTR_READ_DEST+1 +next: + sta PTR_READ_DEST + + lda #CH376_BYTE_RD_GO + sta CH376_COMMAND + jsr _ch376_wait_response + jmp continue +finished: + ; TODO return bytes read + lda tmp1 + ldx tmp1+1 + rts +.endproc + +; void _ch376_fwrite(void *ptr,int number) +.proc _ch376_fwrite + ; use ptr1 to count bytes + sta ptr2 + stx ptr2+1 + + jsr popax + sta PTR_READ_DEST + stx PTR_READ_DEST+1 + + lda ptr2 + ldx ptr2+1 + jsr _ch376_set_bytes_write +continue: + cmp #CH376_USB_INT_DISK_WRITE ; something to read + beq we_read + cmp #CH376_USB_INT_SUCCESS ; finished + beq finished + + lda #0 + tax + rts +we_read: + lda #CH376_CMD_WR_REQ_DATA + sta CH376_COMMAND + + lda CH376_DATA ; contains length read + sta tmp2; Number of bytes to read + + ldy #0 +loop: + lda (PTR_READ_DEST),y + sta CH376_DATA ; read the data + dec tmp2 + bne loop + + + lda #CH376_BYTE_WR_GO + sta CH376_COMMAND + jsr _ch376_wait_response + jmp continue +finished: + lda tmp1 + ldx tmp1+1 + rts +.endproc + +.proc _ch376_file_create + lda #CH376_FILE_CREATE + sta CH376_COMMAND + jsr _ch376_wait_response + rts +.endproc diff --git a/libsrc/telestrat/close.s b/libsrc/telestrat/close.s new file mode 100644 index 000000000..881d0897f --- /dev/null +++ b/libsrc/telestrat/close.s @@ -0,0 +1,18 @@ +; jede jede@oric.org 2017-01-22 + + .export _close + + .import addysp,popax + + .include "zeropage.inc" + .include "telestrat.inc" + .include "errno.inc" + .include "fcntl.inc" + +; int open (const char* name, int flags, ...); /* May take a mode argument */ +.proc _close + BRK_TELEMON XCLOSE ; launch primitive ROM + rts +.endproc + + \ No newline at end of file diff --git a/libsrc/telemon30/crt0.s b/libsrc/telestrat/crt0.s similarity index 85% rename from libsrc/telemon30/crt0.s rename to libsrc/telestrat/crt0.s index 72bad5f24..59b1ea642 100644 --- a/libsrc/telemon30/crt0.s +++ b/libsrc/telestrat/crt0.s @@ -2,7 +2,6 @@ ; Startup code for cc65 (Oric version) ; ; By Debrune Jérôme <jede@oric.org> and Ullrich von Bassewitz <uz@cc65.org> -; 2016-03-18, Greg King ; .export _exit @@ -13,7 +12,7 @@ .import __MAIN_START__, __MAIN_SIZE__ .include "zeropage.inc" - .include "telemon30.inc" + .include "telestrat.inc" ; ------------------------------------------------------------------------ ; Place the startup code in a special segment. @@ -44,8 +43,6 @@ _exit: jsr donelib ldx spsave txs -; lda stsave - ; sta STATUS ; Copy back the zero-page stuff. @@ -73,13 +70,6 @@ L1: lda sp,x dex bpl L1 -; Currently, color isn't supported on the text screen. -; Unprotect screen columns 0 and 1 (where each line's color codes would sit). - - ; lda STATUS - ; sta stsave - ; and #%11011111 - ; sta STATUS ; Set up the C stack. diff --git a/libsrc/telemon24/ctype.s b/libsrc/telestrat/ctype.s similarity index 100% rename from libsrc/telemon24/ctype.s rename to libsrc/telestrat/ctype.s diff --git a/libsrc/telestrat/graphics.s b/libsrc/telestrat/graphics.s new file mode 100644 index 000000000..9984036bb --- /dev/null +++ b/libsrc/telestrat/graphics.s @@ -0,0 +1,58 @@ +; jede jede@oric.org 2017-01-22 + + .export _paper,_hires,_text,_circle,_curset, _switchOffCursor + + .include "zeropage.inc" + .include "telestrat.inc" + .import popa + + +.proc _paper + ldx #0 ; First window + ; A contains the paper + BRK_TELEMON XPAPER + rts +.endproc + +; XINK is bugged, it corrupt memory : removing from export +.proc _ink + ldx #0 ; First window + ; A contains the ink + BRK_TELEMON XINK + rts +.endproc + +; can be optimized with a macro +.proc _hires + BRK_TELEMON XHIRES + rts +.endproc + +.proc _text + BRK_TELEMON XTEXT + rts +.endproc + +.proc _curset + jsr popa ; Pixel + jsr popa + sta HRSX + jsr popa + sta HRSY + BRK_TELEMON XCURSE + rts +.endproc + +.proc _circle + sta HRS1 + BRK_TELEMON XCIRCL + rts +.endproc + +.proc _switchOffCursor + ldx #0 + BRK_TELEMON XCOSCR + rts +.endproc + + diff --git a/libsrc/telestrat/keyboard.s b/libsrc/telestrat/keyboard.s new file mode 100644 index 000000000..7069d1003 --- /dev/null +++ b/libsrc/telestrat/keyboard.s @@ -0,0 +1,14 @@ +; jede jede@oric.org 2017-01-22 + + .export _key + + .include "zeropage.inc" + .include "telestrat.inc" + +; char key(void); + +.proc _key + BRK_TELEMON XRDW0 ; read keyboard + rts +.endproc + diff --git a/libsrc/telemon30/mainargs.s b/libsrc/telestrat/mainargs.s similarity index 90% rename from libsrc/telemon30/mainargs.s rename to libsrc/telestrat/mainargs.s index 452d0d6d6..b41e2a96d 100644 --- a/libsrc/telemon30/mainargs.s +++ b/libsrc/telestrat/mainargs.s @@ -9,7 +9,7 @@ .constructor initmainargs, 24 .import __argc, __argv .import ptr1 - .include "telemon30.inc" + .include "telestrat.inc" .macpack generic MAXARGS = 10 ; Maximum number of arguments allowed @@ -23,8 +23,6 @@ MAXARGS = 10 ; Maximum number of arguments allowed initmainargs: ldx #0 ; Limit the length - ; lda #0 ; The terminating NUL character - ; beq L1 ; Branch always L0: lda BUFEDT,x beq L3 cmp #' ' @@ -40,9 +38,6 @@ L3: sta name,x inc __argc ; argc always is equal to, at least, 1 - - - ldy #1 * 2 ; Point to second argv slot @@ -52,31 +47,24 @@ next: lda BUFEDT,x cmp #' ' ; Skip leading spaces beq next - - - - 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. txa ; Get low byte - clc - adc #<BUFEDT - bcc L4 + clc + adc #<BUFEDT + bcc L4 inc L5+1 -L4: - ;add #<args +L4: sta argv,y ; argv[y]=&arg L5: lda #>BUFEDT - ;adc #>args sta argv+1,y iny iny @@ -106,8 +94,6 @@ argloop:lda BUFEDT,x cmp #MAXARGS ; Maximum number of arguments reached? bcc next ; Parse next one if not - - done: lda #<argv ldx #>argv @@ -116,7 +102,6 @@ done: lda #<argv rts - .segment "INIT" term: .res 1 @@ -127,8 +112,6 @@ term: .res 1 name: .res FNAME_LEN + 1 args: .res SCREEN_XSIZE * 2 - 1 -ptr_current: - .res 2 param_found: .res 1 ; char* argv[MAXARGS+1]={name}; diff --git a/libsrc/telemon30/mym.s b/libsrc/telestrat/mym.s similarity index 99% rename from libsrc/telemon30/mym.s rename to libsrc/telestrat/mym.s index f387f9d64..009ccf53b 100644 --- a/libsrc/telemon30/mym.s +++ b/libsrc/telestrat/mym.s @@ -1,7 +1,7 @@ .export _Mym_MusicStart .importzp sp,tmp2,tmp3,tmp1,ptr1 - .include "telemon30.inc" + .include "telestrat.inc" ; To check: AYC ; http://cpcwiki.eu/index.php/AYC diff --git a/libsrc/telemon30/_open.s b/libsrc/telestrat/open.s similarity index 65% rename from libsrc/telemon30/_open.s rename to libsrc/telestrat/open.s index 7ea2d8310..9455855da 100644 --- a/libsrc/telemon30/_open.s +++ b/libsrc/telestrat/open.s @@ -1,12 +1,13 @@ .export _open - .import addysp,popax - .importzp sp,tmp2,tmp3,tmp1 + .import addysp,popax + .importzp sp,tmp2,tmp3,tmp1 - ; int open (const char* name, int flags, ...); /* May take a mode argument */ - .include "telemon30.inc" - .include "errno.inc" - .include "fcntl.inc" - + + .include "telestrat.inc" + .include "errno.inc" + .include "fcntl.inc" + +; int open (const char* name, int flags, ...); /* May take a mode argument */ .proc _open ; Throw away any additional parameters passed through the ellipsis @@ -24,9 +25,9 @@ parmok: jsr popax ; Get flagss ; Get the filename from stack and parse it. Bail out if is not ok jsr popax ; Get name - ldy tmp3 ; Get flags again - BRK_TELEMON XOPEN ; launch primitive ROM - rts + ldy tmp3 ; Get flags again + BRK_TELEMON XOPEN ; launch primitive ROM + rts .endproc \ No newline at end of file diff --git a/libsrc/telemon30/orixhdr.s b/libsrc/telestrat/orixhdr.s similarity index 56% rename from libsrc/telemon30/orixhdr.s rename to libsrc/telestrat/orixhdr.s index 1b0351885..c2a65d9fa 100644 --- a/libsrc/telemon30/orixhdr.s +++ b/libsrc/telestrat/orixhdr.s @@ -1,6 +1,6 @@ ; -; Based on code by Debrune Jérôme <jede@oric.org> -; 2016-03-17, Greg King +; By Debrune Jérôme <jede@oric.org> + ; ; The following symbol is used by the linker config. file @@ -13,23 +13,23 @@ ; ------------------------------------------------------------------------ -; Oric cassette-tape header +; Orix header see http://orix.oric.org/doku.php?id=orix:header for specs .segment "ORIXHDR" .byte $01, $00 ; - .byte "ori" + .byte "ori" - .byte $01 ; version - .byte $00,%00000000 ; 6502 only - .byte $00,$00 ; Extends - .byte $00,$00 ; OS + .byte $01 ; version + .byte $00,%00000000 ; 6502 only + .byte $00,$00 ; Extends + .byte $00,$00 ; OS .byte $00 ; reserved .byte $00 ; auto - .word __BASHEAD_START__ ; Address of start of file - .word __MAIN_LAST__ - 1 ; Address of end of file - .word __BASHEAD_START__ ; Address of start of file + .word __BASHEAD_START__ ; Address of start of file + .word __MAIN_LAST__ - 1 ; Address of end of file + .word __BASHEAD_START__ ; Address of start of file diff --git a/libsrc/telemon24/oserrlist.s b/libsrc/telestrat/oserrlist.s similarity index 100% rename from libsrc/telemon24/oserrlist.s rename to libsrc/telestrat/oserrlist.s diff --git a/libsrc/telemon24/oserror.s b/libsrc/telestrat/oserror.s similarity index 100% rename from libsrc/telemon24/oserror.s rename to libsrc/telestrat/oserror.s diff --git a/libsrc/telestrat/print.s b/libsrc/telestrat/print.s new file mode 100644 index 000000000..9942e3ad9 --- /dev/null +++ b/libsrc/telestrat/print.s @@ -0,0 +1,16 @@ +; jede jede@oric.org 2017-01-22 + +; void print (char * str); + .export _print + .import popax + .importzp tmp1 + .include "telestrat.inc" + +.proc _print + stx tmp1 + ldy tmp1 + BRK_TELEMON XWSTR0 + rts +.endproc + + diff --git a/libsrc/telestrat/read.s b/libsrc/telestrat/read.s new file mode 100644 index 000000000..4bccbfc48 --- /dev/null +++ b/libsrc/telestrat/read.s @@ -0,0 +1,43 @@ +; +; jede jede@oric.org 2017-01-22 +; + + + .FEATURE c_comments,labels_without_colons,pc_assignment, loose_char_term + .export _read + + .import popax + + .include "zeropage.inc" + .include "telestrat.inc" + +; int read (int fd, void* buf, unsigned count); + +.proc _read + sta ptr1 ; count + stx ptr1+1 ; count + jsr popax ; get buf + + sta PTR_READ_DEST + stx PTR_READ_DEST+1 + sta ptr2 ; in order to calculate nb of bytes read + stx ptr2+1 ; + + ; jsr popax ; fp pointer don't care in this version + + lda ptr1 ; + ldy ptr1+1 ; + BRK_TELEMON XFREAD ; calls telemon30 routine + ; compute nb of bytes read + lda PTR_READ_DEST+1 + sec + sbc ptr2+1 + tax + lda PTR_READ_DEST + sec + sbc ptr2 + ; Here A and X contains number of bytes read + rts +.endproc + + diff --git a/libsrc/telemon24/_scrsize.s b/libsrc/telestrat/scrsize.s similarity index 85% rename from libsrc/telemon24/_scrsize.s rename to libsrc/telestrat/scrsize.s index 305e41c46..75bd456ce 100644 --- a/libsrc/telemon24/_scrsize.s +++ b/libsrc/telestrat/scrsize.s @@ -6,7 +6,7 @@ ; .export screensize - .include "telemon24.inc" + .include "telestrat.inc" .proc screensize diff --git a/libsrc/telestrat/sound.s b/libsrc/telestrat/sound.s new file mode 100644 index 000000000..3718debd4 --- /dev/null +++ b/libsrc/telestrat/sound.s @@ -0,0 +1,42 @@ +; +; jede jede@oric.org 2017-01-22 + + .export _kbdclick1,_oups,_ping,_explode,_shoot,_zap + .include "telestrat.inc" + +.proc _kbdclick1 + ldx #<sound_bip_keyboard + ldy #>sound_bip_keyboard + BRK_TELEMON XSONPS + rts +sound_bip_keyboard: + .byte $1f,$00,$00,$00,$00,$00,$00,$3e,$10,$00,$00,$1f,$00,$00 +.endproc + +.proc _explode + BRK_TELEMON XEXPLO + rts +.endproc + +.proc _oups + BRK_TELEMON XOUPS + rts +.endproc + +.proc _ping + BRK_TELEMON XPING + rts +.endproc + +.proc _shoot + BRK_TELEMON XSHOOT + rts +.endproc + +.proc _zap + BRK_TELEMON XZAP + rts +.endproc + + + diff --git a/libsrc/telemon24/sysuname.s b/libsrc/telestrat/sysuname.s similarity index 100% rename from libsrc/telemon24/sysuname.s rename to libsrc/telestrat/sysuname.s diff --git a/libsrc/telemon30/write.s b/libsrc/telestrat/write.s similarity index 86% rename from libsrc/telemon30/write.s rename to libsrc/telestrat/write.s index d762eb92c..1c0190531 100644 --- a/libsrc/telemon30/write.s +++ b/libsrc/telestrat/write.s @@ -1,17 +1,13 @@ ; -; Ullrich von Bassewitz, 2003-04-13 -; -; int write (int fd, const void* buf, int count); -; -; This function is a hack! -; +; jede jede@oric.org 2017-01-22 .export _write .import popax .importzp ptr1, ptr2, ptr3, tmp1 - .include "telemon30.inc" + .include "telestrat.inc" +; int write (int fd, const void* buf, int count); .proc _write sta ptr3 @@ -58,8 +54,8 @@ L2: ldy #0 tax cpx #$0A ; Check for \n bne L3 - BRK_TELEMON XWR0 ; Macro - lda #$0d ; return to the beggining of the line + BRK_TELEMON XWR0 ; Macro send char to screen (channel 0 in telemon terms) + lda #$0D ; return to the beggining of the line BRK_TELEMON XWR0 ; Macro ; diff --git a/src/ca65/main.c b/src/ca65/main.c index 1e0c5996f..471afbbe8 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -291,12 +291,8 @@ static void SetSys (const char* Sys) NewSymbol ("__ATMOS__", 1); break; - case TGT_TELEMON24: - NewSymbol ("__TELEMON24__", 1); - break; - - case TGT_TELEMON30: - NewSymbol ("__TELEMON30__", 1); + case TGT_TELESTRAT: + NewSymbol ("__TELESTRAT__", 1); break; case TGT_NES: diff --git a/src/cc65/main.c b/src/cc65/main.c index b0c9261fe..872f66aff 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -243,14 +243,10 @@ static void SetSys (const char* Sys) DefineNumericMacro ("__ATMOS__", 1); break; - case TGT_TELEMON24: - DefineNumericMacro ("__TELEMON24__", 1); + case TGT_TELESTRAT: + DefineNumericMacro ("__TELESTRAT__", 1); break; - case TGT_TELEMON30: - DefineNumericMacro ("__TELEMON30__", 1); - break; - case TGT_NES: DefineNumericMacro ("__NES__", 1); break; diff --git a/src/common/target.c b/src/common/target.c index 67e4ad51b..219afc809 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -171,8 +171,7 @@ static const TargetEntry TargetMap[] = { { "sim6502", TGT_SIM6502 }, { "sim65c02", TGT_SIM65C02 }, { "supervision", TGT_SUPERVISION }, - { "telemon24", TGT_TELEMON24 }, - { "telemon30", TGT_TELEMON30 }, + { "telestrat", TGT_TELESTRAT }, { "vic20", TGT_VIC20 }, }; #define MAP_ENTRY_COUNT (sizeof (TargetMap) / sizeof (TargetMap[0])) @@ -201,8 +200,7 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "geos-apple", CPU_65C02, BINFMT_BINARY, CTNone }, { "lunix", CPU_6502, BINFMT_O65, CTNone }, { "atmos", CPU_6502, BINFMT_BINARY, CTNone }, - { "telemon24", CPU_6502, BINFMT_BINARY, CTNone }, - { "telemon30", CPU_6502, BINFMT_BINARY, CTNone }, + { "telestrat", CPU_6502, BINFMT_BINARY, CTNone }, { "nes", CPU_6502, BINFMT_BINARY, CTNone }, { "supervision", CPU_65SC02, BINFMT_BINARY, CTNone }, { "lynx", CPU_65SC02, BINFMT_BINARY, CTNone }, diff --git a/src/common/target.h b/src/common/target.h index 68c0953fe..7409505bf 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -73,8 +73,7 @@ typedef enum { TGT_GEOS_APPLE, TGT_LUNIX, TGT_ATMOS, - TGT_TELEMON24, - TGT_TELEMON30, + TGT_TELESTRAT, TGT_NES, TGT_SUPERVISION, TGT_LYNX, From 6f58b9a22d255429aaba8c45972c09d39f2256c2 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Tue, 31 Jan 2017 22:20:19 +0100 Subject: [PATCH 0201/2161] Correcting comments alignment Correcting an address error in telestrat.inc when cleaning files which broke read.s primitive --- asminc/telestrat.inc | 14 +++++++------- libsrc/telestrat/read.s | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index fedda1946..24a1aa538 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -27,7 +27,7 @@ RESB := $02 TR0 := $0C TR1 := $0D -PTR_READ_DEST := $2D ; used for XFREAD and XWRITE only in telemon 3.0 +PTR_READ_DEST := $2C ; used for XFREAD and XWRITE only in telemon 3.0 HRSX := $46 HRSY := $47 @@ -108,12 +108,12 @@ XWSTR0 = $14 XTEXT = $19 XHIRES = $1A XMINMA = $1F -XFREAD = $27 ; only in TELEMON 3.0 -XOPEN = $30 ; only in TELEMON 3.0 -XCOSCR = $34 ; switch off cursor -XCSSCR = $35 ; switch on cursor -XCLOSE = $3A ; only in TELEMON 3.0 Close file -XFWRITE = $3B ; only in TELEMON 3.0 write file +XFREAD = $27 ; only in TELEMON 3.0 +XOPEN = $30 ; only in TELEMON 3.0 +XCOSCR = $34 ; switch off cursor +XCSSCR = $35 ; switch on cursor +XCLOSE = $3A ; only in TELEMON 3.0 Close file +XFWRITE = $3B ; only in TELEMON 3.0 write file XSONPS = $40 XOUPS = $42 XPLAY = $43 diff --git a/libsrc/telestrat/read.s b/libsrc/telestrat/read.s index 4bccbfc48..85a6132eb 100644 --- a/libsrc/telestrat/read.s +++ b/libsrc/telestrat/read.s @@ -3,13 +3,13 @@ ; - .FEATURE c_comments,labels_without_colons,pc_assignment, loose_char_term - .export _read - - .import popax - - .include "zeropage.inc" - .include "telestrat.inc" + .FEATURE c_comments,labels_without_colons,pc_assignment, loose_char_term + .export _read + + .import popax + + .include "zeropage.inc" + .include "telestrat.inc" ; int read (int fd, void* buf, unsigned count); From 37185b20dd354d22fc6591c204830d780b657610 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Tue, 31 Jan 2017 22:21:53 +0100 Subject: [PATCH 0202/2161] correcting README.md to add telestrat target --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b62ac761d..26ca98cef 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ including - the Nintendo Entertainment System (NES) console. - the Watara Supervision console. - the Oric Atmos. +- the Oric telestrat. - the Lynx console. - the Ohio Scientific Challenger 1P. From d9778994fab808b829cc15dd612fd48a18271c0f Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Tue, 31 Jan 2017 22:33:19 +0100 Subject: [PATCH 0203/2161] Correcting some spaces --- libsrc/telestrat/ch376.s | 48 ++++++++++++++++++------------------- libsrc/telestrat/close.s | 4 ++-- libsrc/telestrat/graphics.s | 2 +- libsrc/telestrat/mainargs.s | 6 ++--- libsrc/telestrat/open.s | 35 +++++++++++++-------------- 5 files changed, 47 insertions(+), 48 deletions(-) diff --git a/libsrc/telestrat/ch376.s b/libsrc/telestrat/ch376.s index fbfa16017..49aefad92 100644 --- a/libsrc/telestrat/ch376.s +++ b/libsrc/telestrat/ch376.s @@ -29,49 +29,49 @@ CH376_USB_INT_SUCCESS = $14 CH376_USB_INT_CONNECT = $15 CH376_USB_INT_DISCONNECT = $16 CH376_USB_INT_BUF_OVER = $17 -CH376_USB_INT_USB_READY = $18 -CH376_USB_INT_DISK_READ = $1D +CH376_USB_INT_USB_READY = $18 +CH376_USB_INT_DISK_READ = $1D CH376_USB_INT_DISK_WRITE = $1E CH376_USB_INT_DISK_ERR = $1F -CH376_ERR_OPEN_DIR = $41 -CH376_ERR_MISS_FILE = $42 +CH376_ERR_OPEN_DIR = $41 +CH376_ERR_MISS_FILE = $42 CH376_ERR_FOUND_NAME = $43 CH376_ERR_DISK_DISCON = $82 CH376_ERR_LARGE_SECTOR = $84 CH376_ERR_TYPE_ERROR = $92 -CH376_ERR_BPB_ERROR = $A1 -CH376_ERR_DISK_FULL = $B1 -CH376_ERR_FDT_OVER = $B2 +CH376_ERR_BPB_ERROR = $A1 +CH376_ERR_DISK_FULL = $B1 +CH376_ERR_FDT_OVER = $B2 CH376_ERR_FILE_CLOSE = $B4 -CH376_GET_IC_VER = $01 -CH376_SET_BAUDRATE = $02 +CH376_GET_IC_VER = $01 +CH376_SET_BAUDRATE = $02 CH376_GET_ENTER_SLEEP = $03 -CH376_RESET_ALL = $05 -CH376_CHECK_EXIST = $06 +CH376_RESET_ALL = $05 +CH376_CHECK_EXIST = $06 CH376_GET_FILE_SIZE = $0C CH376_SET_USB_MODE = $15 CH376_GET_STATUS = $22 CH376_RD_USB_DATA0 = $27 -CH376_CMD_WR_REQ_DATA = $2D -CH376_SET_FILE_NAME = $2F +CH376_CMD_WR_REQ_DATA = $2D +CH376_SET_FILE_NAME = $2F CH376_DISK_CONNECT = $30 ; check the disk connection status -CH376_DISK_MOUNT = $31 -CH376_FILE_OPEN = $32 -CH376_FILE_ENUM_GO = $33 -CH376_FILE_CREATE = $34 +CH376_DISK_MOUNT = $31 +CH376_FILE_OPEN = $32 +CH376_FILE_ENUM_GO = $33 +CH376_FILE_CREATE = $34 CH376_FILE_CLOSE = $36 -CH376_BYTE_LOCATE = $39 -CH376_BYTE_READ = $3A -CH376_BYTE_RD_GO = $3B -CH376_BYTE_WRITE = $3C -CH376_BYTE_WR_GO = $3D -CH376_DISK_CAPACITY = $3E -CH376_DISK_RD_GO = $55 +CH376_BYTE_LOCATE = $39 +CH376_BYTE_READ = $3A +CH376_BYTE_RD_GO = $3B +CH376_BYTE_WRITE = $3C +CH376_BYTE_WR_GO = $3D +CH376_DISK_CAPACITY = $3E +CH376_DISK_RD_GO = $55 .proc _ch376_file_close lda #CH376_FILE_CLOSE diff --git a/libsrc/telestrat/close.s b/libsrc/telestrat/close.s index 881d0897f..240ebb063 100644 --- a/libsrc/telestrat/close.s +++ b/libsrc/telestrat/close.s @@ -2,9 +2,9 @@ .export _close - .import addysp,popax + .import addysp,popax - .include "zeropage.inc" + .include "zeropage.inc" .include "telestrat.inc" .include "errno.inc" .include "fcntl.inc" diff --git a/libsrc/telestrat/graphics.s b/libsrc/telestrat/graphics.s index 9984036bb..e0b002d3c 100644 --- a/libsrc/telestrat/graphics.s +++ b/libsrc/telestrat/graphics.s @@ -4,7 +4,7 @@ .include "zeropage.inc" .include "telestrat.inc" - .import popa + .import popa .proc _paper diff --git a/libsrc/telestrat/mainargs.s b/libsrc/telestrat/mainargs.s index b41e2a96d..fa388cbfa 100644 --- a/libsrc/telestrat/mainargs.s +++ b/libsrc/telestrat/mainargs.s @@ -24,8 +24,8 @@ initmainargs: ldx #0 ; Limit the length L0: lda BUFEDT,x - beq L3 - cmp #' ' + beq L3 + cmp #' ' bne L1 lda #0 beq L3 @@ -35,7 +35,7 @@ L1: sta name,x bne L0 lda #0 L3: - sta name,x + sta name,x inc __argc ; argc always is equal to, at least, 1 diff --git a/libsrc/telestrat/open.s b/libsrc/telestrat/open.s index 9455855da..b3b390003 100644 --- a/libsrc/telestrat/open.s +++ b/libsrc/telestrat/open.s @@ -1,33 +1,32 @@ - .export _open - .import addysp,popax - .importzp sp,tmp2,tmp3,tmp1 + .export _open + .import addysp,popax + .importzp sp,tmp2,tmp3,tmp1 - .include "telestrat.inc" - .include "errno.inc" - .include "fcntl.inc" + .include "telestrat.inc" + .include "errno.inc" + .include "fcntl.inc" ; int open (const char* name, int flags, ...); /* May take a mode argument */ .proc _open ; Throw away any additional parameters passed through the ellipsis - dey ; Parm count < 4 shouldn't be needed to be... - dey ; ...checked (it generates a c compiler warning) - dey - dey - beq parmok ; Branch if parameter count ok - jsr addysp ; Fix stack, throw away unused parameters + dey ; Parm count < 4 shouldn't be needed to be... + dey ; ...checked (it generates a c compiler warning) + dey + dey + beq parmok ; Branch if parameter count ok + jsr addysp ; Fix stack, throw away unused parameters ; Parameters ok. Pop the flags and save them into tmp3 parmok: jsr popax ; Get flagss - sta tmp3 ; save flags + sta tmp3 ; save flags ; Get the filename from stack and parse it. Bail out if is not ok - - jsr popax ; Get name - ldy tmp3 ; Get flags again - BRK_TELEMON XOPEN ; launch primitive ROM - rts + jsr popax ; Get name + ldy tmp3 ; Get flags again + BRK_TELEMON XOPEN ; launch primitive ROM + rts .endproc \ No newline at end of file From 034c668b15567c3c90034b878aaeb1fbb1d864dd Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 1 Feb 2017 17:52:30 +0100 Subject: [PATCH 0204/2161] pce/memcpy.s: remove superfluous comma in comment --- libsrc/pce/memcpy.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/pce/memcpy.s b/libsrc/pce/memcpy.s index 40f831e30..14977dee0 100644 --- a/libsrc/pce/memcpy.s +++ b/libsrc/pce/memcpy.s @@ -97,7 +97,7 @@ memcpy_getparams: ; ---------------------------------------------------------------------- ; The transfer instructions use inline arguments. -; Therefore, we must build the instruction, in the DATA segment. +; Therefore, we must build the instruction in the DATA segment. .data From a08f90522459634aace3f5db9f81045bce204d38 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 1 Feb 2017 19:46:04 +0100 Subject: [PATCH 0205/2161] Cleanups for Creativision. --- cfg/creativision.cfg | 1 + libsrc/creativision/_scrsize.s | 10 +-- libsrc/creativision/boxchars.inc | 112 +++++++++++++++---------------- libsrc/creativision/cclear.s | 43 ++++++------ libsrc/creativision/cgetc.s | 25 +++---- libsrc/creativision/chline.s | 2 +- libsrc/creativision/clrscr.s | 66 +++++++++--------- libsrc/creativision/color.s | 14 ++-- libsrc/creativision/cputc.s | 54 +++++++-------- libsrc/creativision/gotox.s | 2 +- libsrc/creativision/gotoxy.s | 6 +- libsrc/creativision/joy.s | 28 ++++---- libsrc/creativision/libref.s | 4 +- libsrc/creativision/mainargs.s | 2 - libsrc/creativision/psg.s | 91 ++++++++++++------------- libsrc/creativision/sysuname.s | 3 - libsrc/creativision/wherex.s | 3 - libsrc/creativision/wherey.s | 3 - src/ca65/main.c | 28 ++++---- src/cc65/main.c | 28 ++++---- src/common/target.c | 70 ++++++++++--------- src/common/target.h | 10 +-- 22 files changed, 291 insertions(+), 314 deletions(-) diff --git a/cfg/creativision.cfg b/cfg/creativision.cfg index 9122ccd42..06e39b36f 100644 --- a/cfg/creativision.cfg +++ b/cfg/creativision.cfg @@ -12,6 +12,7 @@ SEGMENTS { VECTORS: load = ROM, run = RAM, type = rw, define = yes; DATA: load = ROM, run = RAM, type = rw, define = yes, start = $0204; BSS: load = RAM, type = bss, define = yes; + ONCE: load = ROM, type = ro, optional = yes; CODE: load = ROM, type = ro; INIT: load = ROM, type = ro; RODATA: load = ROM, type = ro; diff --git a/libsrc/creativision/_scrsize.s b/libsrc/creativision/_scrsize.s index fdcc7fc60..9e4ce53c7 100644 --- a/libsrc/creativision/_scrsize.s +++ b/libsrc/creativision/_scrsize.s @@ -2,14 +2,14 @@ ;** _scrsize.s ;* - .export screensize + .export screensize - .include "creativision.inc" + .include "creativision.inc" .proc screensize - ldx #SCREEN_COLS - ldy #SCREEN_ROWS - rts + ldx #SCREEN_COLS + ldy #SCREEN_ROWS + rts .endproc diff --git a/libsrc/creativision/boxchars.inc b/libsrc/creativision/boxchars.inc index 0916d49ce..45484a5d2 100644 --- a/libsrc/creativision/boxchars.inc +++ b/libsrc/creativision/boxchars.inc @@ -1,62 +1,62 @@ ; Boxchars boxchars: - ; Vertical Line - .byte $18 - .byte $18 - .byte $18 - .byte $18 - .byte $18 - .byte $18 - .byte $18 - .byte $18 + ; Vertical Line + .byte $18 + .byte $18 + .byte $18 + .byte $18 + .byte $18 + .byte $18 + .byte $18 + .byte $18 - ; Horizontal Line - .byte 0 - .byte 0 - .byte 0 - .byte $ff - .byte 0 - .byte 0 - .byte 0 - .byte 0 - - ; Top Left - .byte 0 - .byte 0 - .byte 0 - .byte $1f - .byte $18 - .byte $18 - .byte $18 - .byte $18 - - ; Top Right - .byte 0 - .byte 0 - .byte 0 - .byte $F8 - .byte $18 - .byte $18 - .byte $18 - .byte $18 + ; Horizontal Line + .byte $00 + .byte $00 + .byte $00 + .byte $FF + .byte $00 + .byte $00 + .byte $00 + .byte $00 - ; Bottom Left - .byte $18 - .byte $18 - .byte $18 - .byte $1F - .byte 0 - .byte 0 - .byte 0 - .byte 0 + ; Top Left + .byte $00 + .byte $00 + .byte $00 + .byte $1F + .byte $18 + .byte $18 + .byte $18 + .byte $18 - ; Bottom Right - .byte $18 - .byte $18 - .byte $18 - .byte $F8 - .byte 0 - .byte 0 - .byte 0 - .byte 0 + ; Top Right + .byte $00 + .byte $00 + .byte $00 + .byte $F8 + .byte $18 + .byte $18 + .byte $18 + .byte $18 + + ; Bottom Left + .byte $18 + .byte $18 + .byte $18 + .byte $1F + .byte $00 + .byte $00 + .byte $00 + .byte $00 + + ; Bottom Right + .byte $18 + .byte $18 + .byte $18 + .byte $F8 + .byte $00 + .byte $00 + .byte $00 + .byte $00 diff --git a/libsrc/creativision/cclear.s b/libsrc/creativision/cclear.s index 507c072bd..953ec8ce8 100644 --- a/libsrc/creativision/cclear.s +++ b/libsrc/creativision/cclear.s @@ -3,27 +3,24 @@ ;* void cclear (unsigned char length); ;* - .export _cclearxy, _cclear - .import popa, _gotoxy, cputdirect - .importzp tmp1 - -_cclearxy: - pha ; Save length - jsr popa ; get Y - jsr _gotoxy - pla - -_cclear: - cmp #0 ; Zero length? - beq L2 - sta tmp1 - -L1: - lda #$20 ; Space - jsr cputdirect - dec tmp1 - bne L1 - -L2: rts + .export _cclearxy, _cclear + .import popa, _gotoxy, cputdirect + .importzp tmp1 - +_cclearxy: + pha ; Save length + jsr popa ; get Y + jsr _gotoxy + pla + +_cclear: + cmp #0 ; Zero length? + beq L2 + sta tmp1 + +L1: lda #$20 ; Space + jsr cputdirect + dec tmp1 + bne L1 + +L2: rts diff --git a/libsrc/creativision/cgetc.s b/libsrc/creativision/cgetc.s index f1e89942a..12831b4b9 100644 --- a/libsrc/creativision/cgetc.s +++ b/libsrc/creativision/cgetc.s @@ -1,17 +1,14 @@ ;* cgetc - .export _cgetc - .include "creativision.inc" - + .export _cgetc + .include "creativision.inc" + _cgetc: - lda #$80 - -L1: - bit ZP_KEYBOARD - bpl L1 - - lda ZP_KEYBOARD - and #$7f - rts - - + lda #$80 + +L1: bit ZP_KEYBOARD + bpl L1 + + lda ZP_KEYBOARD + and #$7F + rts diff --git a/libsrc/creativision/chline.s b/libsrc/creativision/chline.s index c206180e0..bef36e1fe 100644 --- a/libsrc/creativision/chline.s +++ b/libsrc/creativision/chline.s @@ -6,7 +6,7 @@ .importzp tmp1 .include "creativision.inc" - + _chlinexy: pha ; Save the length jsr popa ; Get y diff --git a/libsrc/creativision/clrscr.s b/libsrc/creativision/clrscr.s index ef800a9bd..9e7238345 100644 --- a/libsrc/creativision/clrscr.s +++ b/libsrc/creativision/clrscr.s @@ -4,38 +4,38 @@ ;* NB: All screen functions assume Graphics Mode 1 in a default configuration. ;* Therefore, this is hard coded to use $1000-$12FF as screen VRAM. - .export _clrscr - .include "creativision.inc" - + .export _clrscr + .include "creativision.inc" + _clrscr: - sei ; Disable interrupts. Default INT handler reads VDP_STATUS - ; and would lose any setup done here. - - lda #$00 ; VRAM offset low - sta VDP_CONTROL_W - - lda #$50 ; VRAM offset high ($10 OR $40) - sta VDP_CONTROL_W - - lda #$C0 ; Space from ROM setup - - ldx #0 - ldy #3 - -L1: sta VDP_DATA_W - inx - bne L1 - dey - bne L1 - - cli ; Let interrupts go again - - lda #0 - sta CURSOR_X - sta CURSOR_Y - sta <SCREEN_PTR - lda #$10 - sta >SCREEN_PTR - - rts + sei ; Disable interrupts. Default INT handler reads VDP_STATUS + ; and would lose any setup done here. + + lda #$00 ; VRAM offset low + sta VDP_CONTROL_W + + lda #$50 ; VRAM offset high ($10 OR $40) + sta VDP_CONTROL_W + + lda #$C0 ; Space from ROM setup + + ldx #0 + ldy #3 + +L1: sta VDP_DATA_W + inx + bne L1 + dey + bne L1 + + cli ; Let interrupts go again + + lda #0 + sta CURSOR_X + sta CURSOR_Y + sta <SCREEN_PTR + lda #$10 + sta >SCREEN_PTR + + rts diff --git a/libsrc/creativision/color.s b/libsrc/creativision/color.s index b6fd360b4..8e86719d2 100644 --- a/libsrc/creativision/color.s +++ b/libsrc/creativision/color.s @@ -4,10 +4,10 @@ ;* unsigned char __fastcall__ bordercolor (unsigned char color); ;* - .export _textcolor, _bgcolor, _bordercolor - .import return0 - .include "creativision.inc" - -_bordercolor = return0; -_textcolor = return0; -_bgcolor = return0; + .export _textcolor, _bgcolor, _bordercolor + .import return0 + .include "creativision.inc" + +_bordercolor = return0; +_textcolor = return0; +_bgcolor = return0; diff --git a/libsrc/creativision/cputc.s b/libsrc/creativision/cputc.s index 902caf277..208009ebd 100644 --- a/libsrc/creativision/cputc.s +++ b/libsrc/creativision/cputc.s @@ -29,13 +29,13 @@ _cputcxy: ; Plot a character - also used as internal function -_cputc: cmp #$0d ; CR? +_cputc: cmp #$0D ; CR? bne L1 lda #0 sta CURSOR_X beq plot ; Recalculate pointers -L1: cmp #$0a ; LF? +L1: cmp #$0A ; LF? beq newline ; Recalculate pointers ; Printable char of some sort @@ -82,19 +82,19 @@ IS_UPPER: pha lda SCREEN_PTR sei - sta VDP_CONTROL_W + sta VDP_CONTROL_W lda SCREEN_PTR+1 - ora #$40 - sta VDP_CONTROL_W + ora #$40 + sta VDP_CONTROL_W pla clc - adc #160 - sta VDP_DATA_W + adc #160 + sta VDP_DATA_W cli BAD_CHAR: jmp plot - + ;----------------------------------------------------------------------------- ; Initialize the conio subsystem. Code goes into the INIT segment, which may ; be reused after startup. @@ -102,24 +102,24 @@ BAD_CHAR: .segment "INIT" initconio: - lda #$0 - sta SCREEN_PTR - lda #$10 - sta SCREEN_PTR+1 + lda #$0 + sta SCREEN_PTR + lda #$10 + sta SCREEN_PTR+1 - ; Copy box characters to slot - sei - lda #08 - sta VDP_CONTROL_W - lda #$46 - sta VDP_CONTROL_W - ldx #0 -LL: - lda boxchars,x - sta VDP_DATA_W - inx - cpx #48 - bne LL + ; Copy box characters to slot + sei + lda #08 + sta VDP_CONTROL_W + lda #$46 + sta VDP_CONTROL_W + ldx #0 - cli - jmp plot +LL: lda boxchars,x + sta VDP_DATA_W + inx + cpx #48 + bne LL + + cli + jmp plot diff --git a/libsrc/creativision/gotox.s b/libsrc/creativision/gotox.s index 6970e5d24..f65e923b5 100644 --- a/libsrc/creativision/gotox.s +++ b/libsrc/creativision/gotox.s @@ -11,7 +11,7 @@ .proc _gotox - sta CURSOR_X ; Set new position + sta CURSOR_X ; Set new position tay ldx CURSOR_Y jmp setcursor ; Set the cursor to the new position diff --git a/libsrc/creativision/gotoxy.s b/libsrc/creativision/gotoxy.s index 6c0cf932f..12ce0abea 100644 --- a/libsrc/creativision/gotoxy.s +++ b/libsrc/creativision/gotoxy.s @@ -12,9 +12,9 @@ .proc _gotoxy - sta CURSOR_Y ; Set Y - jsr popa ; Get X - sta CURSOR_X ; Set X + sta CURSOR_Y ; Set Y + jsr popa ; Get X + sta CURSOR_X ; Set X tay ldx CURSOR_Y jmp setcursor ; Set the cursor position diff --git a/libsrc/creativision/joy.s b/libsrc/creativision/joy.s index f1c9b09f7..eb0bc6594 100644 --- a/libsrc/creativision/joy.s +++ b/libsrc/creativision/joy.s @@ -1,6 +1,6 @@ ;* ;* Creativision Joystick Function -;* +;* ;* unsigned char __fastcall__ joystate(unsigned char joy); ;* ;* JOY_1 -> Return Left Joystick direction @@ -12,47 +12,47 @@ .export _joystate .include "creativision.inc" - + _joystate: cmp #1 ; Left Direction bne l1 - + lda $11 beq l5 - and #$f + and #$0F lsr a tax inx txa rts - + l1: cmp #2 ; Right Direction bne l2 - + lda $13 beq l5 - and #$f + and #$0F lsr a tax inx txa rts - + l2: cmp #3 ; Left Buttons bne l3 - + lda $16 beq l5 - and #$f + and #$0F rts - + l3: cmp #4 bne l4 - + lda $17 beq l5 - and #$f + and #$0F rts - + l4: lda #0 l5: rts diff --git a/libsrc/creativision/libref.s b/libsrc/creativision/libref.s index d947c1aa4..b642da80a 100644 --- a/libsrc/creativision/libref.s +++ b/libsrc/creativision/libref.s @@ -5,5 +5,5 @@ .export joy_libref, tgi_libref .import _exit -joy_libref := _exit -tgi_libref := _exit +joy_libref := _exit +tgi_libref := _exit diff --git a/libsrc/creativision/mainargs.s b/libsrc/creativision/mainargs.s index 7ed8d46f4..cda76d8d0 100644 --- a/libsrc/creativision/mainargs.s +++ b/libsrc/creativision/mainargs.s @@ -20,5 +20,3 @@ rts .endproc - - diff --git a/libsrc/creativision/psg.s b/libsrc/creativision/psg.s index 12b474339..a32e87f02 100644 --- a/libsrc/creativision/psg.s +++ b/libsrc/creativision/psg.s @@ -3,40 +3,37 @@ ; void __fastcall__ bios_playsound( void *b, unsigned char c); ; void psg_silence( void ); - .export _psg_outb, _psg_silence, _psg_delay - .export _bios_playsound - .import popa - .include "creativision.inc" - + .export _psg_outb, _psg_silence, _psg_delay + .export _bios_playsound + .import popa + .include "creativision.inc" + _psg_outb: - ;* Let BIOS output the value - jmp $FE77 - + ;* Let BIOS output the value + jmp $FE77 + _psg_silence: - jmp $FE54 - - + jmp $FE54 + + _psg_delay: - tay -l1: - lda #200 -l2: - sbc #1 - bne l2 - - lda #200 -l3: - sbc #1 - bne l3 - - dey - bne l1 - - rts - + tay +l1: lda #200 +l2: sbc #1 + bne l2 + + lda #200 +l3: sbc #1 + bne l3 + + dey + bne l1 + + rts + ;* Creativision Sound Player ;* @@ -46,23 +43,21 @@ l3: _bios_playsound: - pha ; Save Length Byte - - sei - - lda #$D5 ; BIOS volume table low - sta $4 - lda #$FC ; BIOS volume table high - sta $5 - - jsr popa ; Get Sound table pointer low - sta $0 - jsr popa ; Get Sound table pointer high - sta $1 - - pla - tay ; Put length in Y - dey - php - jmp $fbed ; Let BIOS do it's thing - + pha ; Save Length Byte + sei + + lda #$D5 ; BIOS volume table low + sta $4 + lda #$FC ; BIOS volume table high + sta $5 + + jsr popa ; Get Sound table pointer low + sta $0 + jsr popa ; Get Sound table pointer high + sta $1 + + pla + tay ; Put length in Y + dey + php + jmp $FBED ; Let BIOS do it's thing diff --git a/libsrc/creativision/sysuname.s b/libsrc/creativision/sysuname.s index df1a81b67..725cb2a62 100644 --- a/libsrc/creativision/sysuname.s +++ b/libsrc/creativision/sysuname.s @@ -34,6 +34,3 @@ utsdata: ; machine .asciiz "CREATIVISION" - - - diff --git a/libsrc/creativision/wherex.s b/libsrc/creativision/wherex.s index f9df2d1a1..a2e6fdfc5 100644 --- a/libsrc/creativision/wherex.s +++ b/libsrc/creativision/wherex.s @@ -5,7 +5,6 @@ ; .export _wherex - .include "creativision.inc" .proc _wherex @@ -15,5 +14,3 @@ rts .endproc - - diff --git a/libsrc/creativision/wherey.s b/libsrc/creativision/wherey.s index 6d7b056f5..fa50177c4 100644 --- a/libsrc/creativision/wherey.s +++ b/libsrc/creativision/wherey.s @@ -5,7 +5,6 @@ ; .export _wherey - .include "creativision.inc" .proc _wherey @@ -15,5 +14,3 @@ rts .endproc - - diff --git a/src/ca65/main.c b/src/ca65/main.c index 1da0ff36d..a83cab5b6 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -259,6 +259,10 @@ static void SetSys (const char* Sys) CBMSystem ("__PET__"); break; + case TGT_BBC: + NewSymbol ("__BBC__", 1); + break; + case TGT_APPLE2: NewSymbol ("__APPLE2__", 1); break; @@ -278,14 +282,6 @@ static void SetSys (const char* Sys) NewSymbol ("__GEOS_CBM__", 1); break; - case TGT_ATMOS: - NewSymbol ("__ATMOS__", 1); - break; - - case TGT_BBC: - NewSymbol ("__BBC__", 1); - break; - case TGT_CREATIVISION: NewSymbol ("__CREATIVISION__", 1); break; @@ -299,14 +295,22 @@ static void SetSys (const char* Sys) NewSymbol ("__LUNIX__", 1); break; - case TGT_LYNX: - NewSymbol ("__LYNX__", 1); + case TGT_ATMOS: + NewSymbol ("__ATMOS__", 1); break; case TGT_NES: NewSymbol ("__NES__", 1); break; + case TGT_SUPERVISION: + NewSymbol ("__SUPERVISION__", 1); + break; + + case TGT_LYNX: + NewSymbol ("__LYNX__", 1); + break; + case TGT_SIM6502: NewSymbol ("__SIM6502__", 1); break; @@ -323,10 +327,6 @@ static void SetSys (const char* Sys) NewSymbol ("__PCE__", 1); break; - case TGT_SUPERVISION: - NewSymbol ("__SUPERVISION__", 1); - break; - default: AbEnd ("Invalid target name: `%s'", Sys); diff --git a/src/cc65/main.c b/src/cc65/main.c index c273d8160..780c52b57 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -211,6 +211,10 @@ static void SetSys (const char* Sys) cbmsys ("__PET__"); break; + case TGT_BBC: + DefineNumericMacro ("__BBC__", 1); + break; + case TGT_APPLE2: DefineNumericMacro ("__APPLE2__", 1); break; @@ -230,14 +234,6 @@ static void SetSys (const char* Sys) DefineNumericMacro ("__GEOS_CBM__", 1); break; - case TGT_ATMOS: - DefineNumericMacro ("__ATMOS__", 1); - break; - - case TGT_BBC: - DefineNumericMacro ("__BBC__", 1); - break; - case TGT_CREATIVISION: DefineNumericMacro ("__CREATIVISION__", 1); break; @@ -251,14 +247,22 @@ static void SetSys (const char* Sys) DefineNumericMacro ("__LUNIX__", 1); break; - case TGT_LYNX: - DefineNumericMacro ("__LYNX__", 1); + case TGT_ATMOS: + DefineNumericMacro ("__ATMOS__", 1); break; case TGT_NES: DefineNumericMacro ("__NES__", 1); break; + case TGT_SUPERVISION: + DefineNumericMacro ("__SUPERVISION__", 1); + break; + + case TGT_LYNX: + DefineNumericMacro ("__LYNX__", 1); + break; + case TGT_SIM6502: DefineNumericMacro ("__SIM6502__", 1); break; @@ -275,10 +279,6 @@ static void SetSys (const char* Sys) DefineNumericMacro ("__PCE__", 1); break; - case TGT_SUPERVISION: - DefineNumericMacro ("__SUPERVISION__", 1); - break; - default: AbEnd ("Unknown target system type %d", Target); } diff --git a/src/common/target.c b/src/common/target.c index bf87b17e0..84559b0e7 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -142,38 +142,38 @@ struct TargetEntry { ** Allows multiple entries for one target id (target name aliases). */ static const TargetEntry TargetMap[] = { - { "apple2", TGT_APPLE2 }, - { "apple2enh", TGT_APPLE2ENH }, - { "atari", TGT_ATARI }, - { "atari2600", TGT_ATARI2600 }, - { "atari5200", TGT_ATARI5200 }, - { "atarixl", TGT_ATARIXL }, - { "atmos", TGT_ATMOS }, - { "bbc", TGT_BBC }, - { "c128", TGT_C128 }, - { "c16", TGT_C16 }, - { "c64", TGT_C64 }, - { "c65", TGT_C65 }, - { "cbm510", TGT_CBM510 }, - { "cbm610", TGT_CBM610 }, - { "creativision", TGT_CREATIVISION}, - { "gamate", TGT_GAMATE }, - { "geos", TGT_GEOS_CBM }, - { "geos-apple", TGT_GEOS_APPLE }, - { "geos-cbm", TGT_GEOS_CBM }, - { "lunix", TGT_LUNIX }, - { "lynx", TGT_LYNX }, - { "module", TGT_MODULE }, - { "nes", TGT_NES }, - { "none", TGT_NONE }, - { "osic1p", TGT_OSIC1P }, - { "pce", TGT_PCENGINE }, - { "pet", TGT_PET }, - { "plus4", TGT_PLUS4 }, - { "sim6502", TGT_SIM6502 }, - { "sim65c02", TGT_SIM65C02 }, - { "supervision", TGT_SUPERVISION }, - { "vic20", TGT_VIC20 }, + { "apple2", TGT_APPLE2 }, + { "apple2enh", TGT_APPLE2ENH }, + { "atari", TGT_ATARI }, + { "atari2600", TGT_ATARI2600 }, + { "atari5200", TGT_ATARI5200 }, + { "atarixl", TGT_ATARIXL }, + { "atmos", TGT_ATMOS }, + { "bbc", TGT_BBC }, + { "c128", TGT_C128 }, + { "c16", TGT_C16 }, + { "c64", TGT_C64 }, + { "c65", TGT_C65 }, + { "cbm510", TGT_CBM510 }, + { "cbm610", TGT_CBM610 }, + { "creativision", TGT_CREATIVISION }, + { "gamate", TGT_GAMATE }, + { "geos", TGT_GEOS_CBM }, + { "geos-apple", TGT_GEOS_APPLE }, + { "geos-cbm", TGT_GEOS_CBM }, + { "lunix", TGT_LUNIX }, + { "lynx", TGT_LYNX }, + { "module", TGT_MODULE }, + { "nes", TGT_NES }, + { "none", TGT_NONE }, + { "osic1p", TGT_OSIC1P }, + { "pce", TGT_PCENGINE }, + { "pet", TGT_PET }, + { "plus4", TGT_PLUS4 }, + { "sim6502", TGT_SIM6502 }, + { "sim65c02", TGT_SIM65C02 }, + { "supervision", TGT_SUPERVISION }, + { "vic20", TGT_VIC20 }, }; #define MAP_ENTRY_COUNT (sizeof (TargetMap) / sizeof (TargetMap[0])) @@ -195,13 +195,12 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "cbm610", CPU_6502, BINFMT_BINARY, CTPET }, { "osic1p", CPU_6502, BINFMT_BINARY, CTOSI }, { "pet", CPU_6502, BINFMT_BINARY, CTPET }, + { "bbc", CPU_6502, BINFMT_BINARY, CTNone }, { "apple2", CPU_6502, BINFMT_BINARY, CTNone }, { "apple2enh", CPU_65C02, BINFMT_BINARY, CTNone }, - { "atmos", CPU_6502, BINFMT_BINARY, CTNone }, - { "bbc", CPU_6502, BINFMT_BINARY, CTNone }, + { "geos-cbm", CPU_6502, BINFMT_BINARY, CTNone }, { "creativision", CPU_6502, BINFMT_BINARY, CTNone }, { "geos-apple", CPU_65C02, BINFMT_BINARY, CTNone }, - { "geos-cbm", CPU_6502, BINFMT_BINARY, CTNone }, { "lunix", CPU_6502, BINFMT_O65, CTNone }, { "atmos", CPU_6502, BINFMT_BINARY, CTNone }, { "nes", CPU_6502, BINFMT_BINARY, CTNone }, @@ -211,7 +210,6 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "sim65c02", CPU_65C02, BINFMT_BINARY, CTNone }, { "pce", CPU_HUC6280, BINFMT_BINARY, CTNone }, { "gamate", CPU_6502, BINFMT_BINARY, CTNone }, - { "supervision", CPU_65SC02, BINFMT_BINARY, CTNone }, { "c65", CPU_4510, BINFMT_BINARY, CTPET }, }; diff --git a/src/common/target.h b/src/common/target.h index 1e54784b1..054c4f2ba 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -67,21 +67,21 @@ typedef enum { TGT_CBM610, TGT_OSIC1P, TGT_PET, + TGT_BBC, TGT_APPLE2, TGT_APPLE2ENH, - TGT_ATMOS, - TGT_BBC, + TGT_GEOS_CBM, TGT_CREATIVISION, TGT_GEOS_APPLE, - TGT_GEOS_CBM, TGT_LUNIX, - TGT_LYNX, + TGT_ATMOS, TGT_NES, + TGT_SUPERVISION, + TGT_LYNX, TGT_SIM6502, TGT_SIM65C02, TGT_PCENGINE, TGT_GAMATE, - TGT_SUPERVISION, TGT_C65, TGT_COUNT /* Number of target systems */ } target_t; From 0e649f24eae9812bd1cfa3f9955caecb8ceb7b9e Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Wed, 1 Feb 2017 23:58:33 +0100 Subject: [PATCH 0206/2161] Correcting some code from github comments --- README.md | 2 +- asminc/telestrat.inc | 9 +- cfg/telestrat.cfg | 3 - doc/telestrat.sgml | 57 ++-- include/telestrat.h | 4 +- libsrc/telestrat/ch376.s | 344 ------------------- libsrc/telestrat/graphics.s | 58 ---- libsrc/telestrat/keyboard.s | 14 - libsrc/telestrat/mym.s | 626 ----------------------------------- libsrc/telestrat/orixhdr.s | 26 +- libsrc/telestrat/oserrlist.s | 75 ----- libsrc/telestrat/oserror.s | 17 - libsrc/telestrat/print.s | 16 - 13 files changed, 51 insertions(+), 1200 deletions(-) delete mode 100644 libsrc/telestrat/ch376.s delete mode 100644 libsrc/telestrat/graphics.s delete mode 100644 libsrc/telestrat/keyboard.s delete mode 100644 libsrc/telestrat/mym.s delete mode 100644 libsrc/telestrat/oserrlist.s delete mode 100644 libsrc/telestrat/oserror.s delete mode 100644 libsrc/telestrat/print.s diff --git a/README.md b/README.md index 26ca98cef..16e92e878 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ including - the Nintendo Entertainment System (NES) console. - the Watara Supervision console. - the Oric Atmos. -- the Oric telestrat. +- the Oric Telestrat. - the Lynx console. - the Ohio Scientific Challenger 1P. diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 24a1aa538..2c3502ba8 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -24,8 +24,8 @@ FNAME_LEN = 11 ; maximum length of file-name RES := $00 RESB := $02 -TR0 := $0C -TR1 := $0D +TR0 := $0C +TR1 := $0D PTR_READ_DEST := $2C ; used for XFREAD and XWRITE only in telemon 3.0 @@ -123,10 +123,11 @@ XZAP = $46 XSHOOT = $47 XCIRCL = $8F XCURSE = $90 -XEXPLO = $9C -XPING = $9D XPAPER = $92 XINK = $93 +XEXPLO = $9C +XPING = $9D + ; --------------------------------------------------------------------------- ; Page $500 diff --git a/cfg/telestrat.cfg b/cfg/telestrat.cfg index b9f0b4026..395a936e1 100644 --- a/cfg/telestrat.cfg +++ b/cfg/telestrat.cfg @@ -1,9 +1,6 @@ SYMBOLS { - __ORIXHDR__: type = import; - __STACKSIZE__: type = weak, value = $0800; # 2K stack - __RAMEND__: type = weak, value = $9800; } MEMORY { diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index ce9e044b4..b981fbfaf 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -10,7 +10,7 @@ <abstract> An overview over the Telestrat (telemon 3.0 : http://orix.oric.org) runtime system as it is implemented for the cc65 C -compiler. +compiler.) </abstract> <!-- Table of contents --> @@ -21,21 +21,35 @@ compiler. <sect>Overview<p> This file contains an overview of the Telestrat runtime system as it comes with the -cc65 C compiler. It describes the memory layout, Telemon3.0-specific header files, +cc65 C compiler. It describes the memory layout, Telestrat-specific header files, available drivers, and any pitfalls specific to that platform. -Please note that Telemon3.0-specific functions are just mentioned here, they are +Please note that Telestrat-specific functions are just mentioned here, they are described in detail in the separate <url url="funcref.html" name="function reference">. Even functions marked as "platform dependent" may be available on more than one platform. Please see the function reference for more information. - - <sect>Binary format<p> -The standard binary output format generated by the linker for the Telemon 3.0 target -is a machine language program with a 20 bytes header described here : http://orix.oric.org/doku.php?id=orix:header +The standard binary output format generated the linker for the Telestrat target +is a machine language program with a 20 bytes header described here : http://orix.oric.org/doku.php?id=orix:header + +This header is used for Telemon 3.0. + +Anyway, for Telemon 2.4, there is no file management, there is no TAPE routine in telemon, there is no way to load a binary easiy. + +Stratsed (the Telestrat operating system) handles files management. Stratsed is loaded to memory from floppy disk. + +There is no tool to insert a binary in a Stratsed floppy disk. + +The only way to load a binary (for Telemon 2.4) is to : +<itemize> +<item>remove the 20 bytes header +<item>download osdk : http://osdk.defence-force.org/index?page=download +<item>use Floppybuilder in OSDK to insert the binary with the tool (please read FloppyBuilder manual to insert your binary, and to start microdisc boot sector when telestrat starts) +</itemize> + @@ -64,12 +78,12 @@ Special locations: <sect>Platform-specific header files<p> -Programs containing Telemon 3.0 -specific code may use the <tt/telemon.h/ header file. +Programs containing Telestrat -specific code may use the <tt/telestrat.h/ header file. -<sect1>Telemon 3.0-specific functions<p> +<sect1>Telestrat-specific functions<p> -The functions listed below are special for the Telemon 3.0. See the <url +The functions listed below are special for the Telestrat. See the <url url="funcref.html" name="function reference"> for declaration and usage. <itemize> @@ -77,13 +91,13 @@ url="funcref.html" name="function reference"> for declaration and usage. <item>ping <item>shoot <item>zap -<item>oupsx +<item>oups </itemize> <sect1>Hardware access<p> -The following pseudo variables declared in the <tt/atmos.h/ header file do allow +The following pseudo variables declared in the <tt/telestrat.h/ header file do allow access to hardware located in the address space. Some variables are structures; accessing the struct fields will access the chip registers. @@ -99,30 +113,23 @@ structures; accessing the struct fields will access the chip registers. <sect>Loadable drivers<p> -<em>Note:</em> Since the Atmos doesn't have working disk I/O -(see <ref id="limitations" name="section "Limitations"">), the -available drivers cannot be loaded at runtime (so the term "loadable drivers" -is somewhat misleading). Instead, the drivers have to be statically linked. While -this may seem overhead, it has two advantages: - - <sect1>Extended memory drivers<p> -No extended memory drivers are currently available for the Atmos. +No extended memory drivers are currently available for the Telestrat. <sect1>Joystick drivers<p> <descrip> -telemon 3.0 manages joysticks but it had been handled yet. +telemon 2.4 & 3.0 manages joysticks but it had been handled yet. </descrip><p> <sect1>Mouse drivers<p> -Telemon 3.0 manages also mouse, but it had been no handled yet in this version. +Telestrat manages also mouse, but it had been no handled yet in this version. <sect1>RS232 device drivers<p> @@ -132,14 +139,12 @@ not done </descrip><p> - - <sect>Limitations<label id="limitations"><p> <sect1>Disk I/O<p> -This version handles fopen, fread, fclose primitives. Because Telemon 3.0 handles these two primitives. By the way, -it uses an extension "ch376 card" which handles sdcard and FAT 32 usb key. +This version handles fopen, fread, fclose primitives. Because Telemon 3.0 handles these three primitives. By the way, +it uses an extension "ch376 card" which handles sdcard and FAT 32 usb key. In the next version of Telemon, FT DOS, Sedoric, Stratsed will be handled in these 3 primitives. <itemize> <item>fclose diff --git a/include/telestrat.h b/include/telestrat.h index 73b018444..85da8df60 100644 --- a/include/telestrat.h +++ b/include/telestrat.h @@ -1,5 +1,5 @@ -void print (char *); + void hires(); void text(); @@ -14,8 +14,6 @@ void ink(char color); void kbdclick1(); -void curset(char x,char y, char display, char display); -void circle(char rayon); diff --git a/libsrc/telestrat/ch376.s b/libsrc/telestrat/ch376.s deleted file mode 100644 index 49aefad92..000000000 --- a/libsrc/telestrat/ch376.s +++ /dev/null @@ -1,344 +0,0 @@ - -; jede jede@oric.org 2017-01-22 - - ; For XA65 compatibily in the future - .FEATURE c_comments,labels_without_colons,pc_assignment, loose_char_term - .export _ch376_set_file_name - .export _ch376_file_open - .export _ch376_ic_get_version - .export _ch376_reset - .export _ch376_check_exist - .export _ch376_disk_mount - .export _ch376_set_usb_mode - .export _ch376_file_close - .export _ch376_seek_file - .export _ch376_file_create - .export _ch376_fwrite - - .import popax - .include "zeropage.inc" - .include "telestrat.inc" - - - - - -CH376_SET_USB_MODE_CODE_USB_HOST_SOF_PACKAGE_AUTOMATICALLY = $06 - -CH376_USB_INT_SUCCESS = $14 -CH376_USB_INT_CONNECT = $15 -CH376_USB_INT_DISCONNECT = $16 -CH376_USB_INT_BUF_OVER = $17 -CH376_USB_INT_USB_READY = $18 -CH376_USB_INT_DISK_READ = $1D -CH376_USB_INT_DISK_WRITE = $1E -CH376_USB_INT_DISK_ERR = $1F - - -CH376_ERR_OPEN_DIR = $41 -CH376_ERR_MISS_FILE = $42 -CH376_ERR_FOUND_NAME = $43 -CH376_ERR_DISK_DISCON = $82 -CH376_ERR_LARGE_SECTOR = $84 -CH376_ERR_TYPE_ERROR = $92 -CH376_ERR_BPB_ERROR = $A1 -CH376_ERR_DISK_FULL = $B1 -CH376_ERR_FDT_OVER = $B2 -CH376_ERR_FILE_CLOSE = $B4 - -CH376_GET_IC_VER = $01 -CH376_SET_BAUDRATE = $02 -CH376_GET_ENTER_SLEEP = $03 -CH376_RESET_ALL = $05 -CH376_CHECK_EXIST = $06 -CH376_GET_FILE_SIZE = $0C - -CH376_SET_USB_MODE = $15 -CH376_GET_STATUS = $22 -CH376_RD_USB_DATA0 = $27 -CH376_CMD_WR_REQ_DATA = $2D -CH376_SET_FILE_NAME = $2F - -CH376_DISK_CONNECT = $30 ; check the disk connection status -CH376_DISK_MOUNT = $31 -CH376_FILE_OPEN = $32 -CH376_FILE_ENUM_GO = $33 -CH376_FILE_CREATE = $34 -CH376_FILE_CLOSE = $36 -CH376_BYTE_LOCATE = $39 -CH376_BYTE_READ = $3A -CH376_BYTE_RD_GO = $3B -CH376_BYTE_WRITE = $3C -CH376_BYTE_WR_GO = $3D -CH376_DISK_CAPACITY = $3E -CH376_DISK_RD_GO = $55 - -.proc _ch376_file_close - lda #CH376_FILE_CLOSE - sta CH376_COMMAND - jsr _ch376_wait_response - rts -.endproc - -.proc _ch376_seek_file - ldx #CH376_BYTE_LOCATE - stx CH376_COMMAND - sta CH376_DATA - sty CH376_DATA - lda #$00 ; Don't manage 32 bits length - sta CH376_DATA - sta CH376_DATA - jsr _ch376_wait_response - rts -.endproc - -; void ch376_set_file_name(char *filename) -.proc _ch376_set_file_name - sta ptr1 - stx ptr1+1 - lda #CH376_SET_FILE_NAME ;$2f - sta CH376_COMMAND - ldy #0 -loop: - lda (ptr1),y ; replace by bufnom - beq end ; we reached 0 value - BRK_TELEMON XMINMA - sta CH376_DATA - iny - cpy #13 ; because we don't manage longfilename shortname =11 - bne loop -end: - sta CH376_DATA - rts -.endproc - -; char _ch376_file_open(); -.proc _ch376_file_open - lda #CH376_FILE_OPEN ; $32 - sta CH376_COMMAND - jsr _ch376_wait_response - rts -.endproc - -.proc _ch376_get_file_size - lda #CH376_GET_FILE_SIZE - sta CH376_COMMAND - lda #$68 - sta CH376_DATA - ; store file length 32 bits - lda CH376_DATA - sta tmp1 - lda CH376_DATA - sta tmp1+1 - lda CH376_DATA - sta tmp2 - lda CH376_DATA - sta tmp2+1 - rts -.endproc - -; void ch376_reset(); -.proc _ch376_reset - lda #CH376_RESET_ALL ; 5 - sta CH376_COMMAND - ; waiting - ldy #0 - ldx #0 -loop: - nop - inx - bne loop - iny - bne loop - rts -.endproc - -; char ch376_check_exist(char value); - -.proc _ch376_check_exist - sta tmp1 - lda #CH376_CHECK_EXIST ; - sta CH376_COMMAND - lda tmp1 - sta CH376_DATA - lda CH376_DATA - rts -.endproc - -; char ch376_ic_get_version(void) -.proc _ch376_ic_get_version - lda #CH376_GET_IC_VER - sta CH376_COMMAND - ldx #0 - lda CH376_DATA - rts -.endproc - -; void ch376_set_usb_mode(char mode) -.proc _ch376_set_usb_mode - ldx #CH376_SET_USB_MODE ; $15 - stx CH376_COMMAND - sta CH376_DATA - rts -.endproc - -; void ch376_set_bytes_write(int value); -.proc _ch376_set_bytes_write - ldy #CH376_BYTE_WRITE - sty CH376_COMMAND - sta CH376_DATA - stx CH376_DATA - lda #0 - sta CH376_DATA - sta CH376_DATA - jsr _ch376_wait_response - rts -.endproc - -.proc _ch376_set_bytes_read - ldy #CH376_BYTE_READ - sty CH376_COMMAND - ; Storing 32 bits value - sta CH376_DATA - stx CH376_DATA - lda #0 - sta CH376_DATA - sta CH376_DATA - jsr _ch376_wait_response - rts -.endproc - -; char ch376_disk_mount(); -.proc _ch376_disk_mount - lda #CH376_DISK_MOUNT ; $31 - sta CH376_COMMAND - jsr _ch376_wait_response - ; if we read data value, we have then length of the volume name - ldx #0 - rts -.endproc - - -; char ch376_wait_response(); -.proc _ch376_wait_response -; return 1 if usb controller does not respond -; else A contains answer of the controller - ldy #$FF ; We have to wait 35 ms, but well, this loop is broken when controler is OK -loop3: - ldx #$FF ; don't decrease this counter. Because ch376 won't respond if there is a lower value -loop: - lda CH376_COMMAND - and #%10000000 - cmp #128 - bne no_error - dex - bne loop - dey - bne loop3 - ; error is here - rts -no_error: - lda #CH376_GET_STATUS - sta CH376_COMMAND - lda CH376_DATA - rts -.endproc - -.proc _ch376_fread - ; use ptr1 to count bytes - jsr _ch376_set_bytes_read -continue: - cmp #CH376_USB_INT_DISK_READ ; something to read - beq we_read - cmp #CH376_USB_INT_SUCCESS ; finished - beq finished - ; TODO in A : $ff X: $ff - lda #0 - tax - rts -we_read: - lda #CH376_RD_USB_DATA0 - sta CH376_COMMAND - - lda CH376_DATA ; contains length read - sta tmp2; Number of bytes to read - - ldy #0 -loop: - lda CH376_DATA ; read the data - sta (PTR_READ_DEST),y - iny - cpy tmp2 - bne loop - tya - clc - adc PTR_READ_DEST - bcc next - inc PTR_READ_DEST+1 -next: - sta PTR_READ_DEST - - lda #CH376_BYTE_RD_GO - sta CH376_COMMAND - jsr _ch376_wait_response - jmp continue -finished: - ; TODO return bytes read - lda tmp1 - ldx tmp1+1 - rts -.endproc - -; void _ch376_fwrite(void *ptr,int number) -.proc _ch376_fwrite - ; use ptr1 to count bytes - sta ptr2 - stx ptr2+1 - - jsr popax - sta PTR_READ_DEST - stx PTR_READ_DEST+1 - - lda ptr2 - ldx ptr2+1 - jsr _ch376_set_bytes_write -continue: - cmp #CH376_USB_INT_DISK_WRITE ; something to read - beq we_read - cmp #CH376_USB_INT_SUCCESS ; finished - beq finished - - lda #0 - tax - rts -we_read: - lda #CH376_CMD_WR_REQ_DATA - sta CH376_COMMAND - - lda CH376_DATA ; contains length read - sta tmp2; Number of bytes to read - - ldy #0 -loop: - lda (PTR_READ_DEST),y - sta CH376_DATA ; read the data - dec tmp2 - bne loop - - - lda #CH376_BYTE_WR_GO - sta CH376_COMMAND - jsr _ch376_wait_response - jmp continue -finished: - lda tmp1 - ldx tmp1+1 - rts -.endproc - -.proc _ch376_file_create - lda #CH376_FILE_CREATE - sta CH376_COMMAND - jsr _ch376_wait_response - rts -.endproc diff --git a/libsrc/telestrat/graphics.s b/libsrc/telestrat/graphics.s deleted file mode 100644 index e0b002d3c..000000000 --- a/libsrc/telestrat/graphics.s +++ /dev/null @@ -1,58 +0,0 @@ -; jede jede@oric.org 2017-01-22 - - .export _paper,_hires,_text,_circle,_curset, _switchOffCursor - - .include "zeropage.inc" - .include "telestrat.inc" - .import popa - - -.proc _paper - ldx #0 ; First window - ; A contains the paper - BRK_TELEMON XPAPER - rts -.endproc - -; XINK is bugged, it corrupt memory : removing from export -.proc _ink - ldx #0 ; First window - ; A contains the ink - BRK_TELEMON XINK - rts -.endproc - -; can be optimized with a macro -.proc _hires - BRK_TELEMON XHIRES - rts -.endproc - -.proc _text - BRK_TELEMON XTEXT - rts -.endproc - -.proc _curset - jsr popa ; Pixel - jsr popa - sta HRSX - jsr popa - sta HRSY - BRK_TELEMON XCURSE - rts -.endproc - -.proc _circle - sta HRS1 - BRK_TELEMON XCIRCL - rts -.endproc - -.proc _switchOffCursor - ldx #0 - BRK_TELEMON XCOSCR - rts -.endproc - - diff --git a/libsrc/telestrat/keyboard.s b/libsrc/telestrat/keyboard.s deleted file mode 100644 index 7069d1003..000000000 --- a/libsrc/telestrat/keyboard.s +++ /dev/null @@ -1,14 +0,0 @@ -; jede jede@oric.org 2017-01-22 - - .export _key - - .include "zeropage.inc" - .include "telestrat.inc" - -; char key(void); - -.proc _key - BRK_TELEMON XRDW0 ; read keyboard - rts -.endproc - diff --git a/libsrc/telestrat/mym.s b/libsrc/telestrat/mym.s deleted file mode 100644 index 009ccf53b..000000000 --- a/libsrc/telestrat/mym.s +++ /dev/null @@ -1,626 +0,0 @@ - .export _Mym_MusicStart - .importzp sp,tmp2,tmp3,tmp1,ptr1 - - .include "telestrat.inc" - -; To check: AYC -; http://cpcwiki.eu/index.php/AYC - - - - -_DecodedByte :=$D0 ; Byte being currently decoded from the MYM stream -_DecodeBitCounter :=$D2 ; Number of bits we can read in the current byte -_DecodedResult :=$D3 ; What is returned by the 'read bits' function -_CurrentAYRegister :=$D4 ; Contains the number of the register being decoded -_RegisterBufferHigh :=$D5 ; Points to the high byte of the decoded register buffer, increment to move to the next register -_BufferFrameOffset :=$D6 ; From 0 to 127, used when filling the decoded register buffer -_MusicResetCounter :=$D7 ; 2 bytes Contains the number of rows to play before reseting -_CurrentFrame :=$D9 ; From 0 to 255 and then cycles... the index of the frame to play this vbl -_PlayerVbl :=$DA -_FrameLoadBalancer :=$DB ; We depack a new frame every 9 VBLs, this way the 14 registers are evenly depacked over 128 frames - - -VIA_1 := $30f -VIA_2 := $30c - -_MusicData := $c000 - -; mym(char *buf) - - - - -; -; Current PSG values during unpacking -; - - -.proc _Mym_MusicStart - - ; The two first bytes of the MYM music is the number of rows in the music - ; We decrement that at each frame, and when we reach zero, time to start again. - sta ptr1 - stx ptr1+1 - - ldy #0 - lda (ptr1),y - sta _MusicResetCounter+0 - iny - lda (ptr1),y - tax - inx - stx _MusicResetCounter+1 - - ;ldx _MusicData+0 - ;stx _MusicResetCounter+0 - ;ldx _MusicData+1 - ;inx - ;stx _MusicResetCounter+1 - - - ; Initialize the read bit counter - ldy #2 ; should be useless because we can do iny which earn 1 byte - - lda ptr1 - clc - adc #2 - bcc next20 - inc ptr1+1 - lda ptr1+1 - sta __auto_music_ptr+2 -next20: - sta ptr1 - sta __auto_music_ptr+1 - - - - ;lda #<(_MusicData+2) - ;sta __auto_music_ptr+1 - ;lda #>(_MusicData+2) - ;sta __auto_music_ptr+2 - - lda #1 - sta _DecodeBitCounter - - ; Clear all data - lda #0 - sta _DecodedResult - sta _DecodedByte - sta _PlayerVbl - sta _PlayerRegCurrentValue - sta _BufferFrameOffset - sta _PlayerCount - sta _CurrentAYRegister - sta _CurrentFrame - - ldx #14 -loop_init: - dex - sta _PlayerRegValues,x - bne loop_init - - - ; - ; Unpack the 128 first register frames - ; - - lda #>_PlayerBuffer - sta _RegisterBufferHigh - - ldx #0 -unpack_block_loop: - stx _CurrentAYRegister - - ; Unpack that register - jsr _PlayerUnpackRegister2 - - ; Next register - ldx _CurrentAYRegister - inx - cpx #14 - bne unpack_block_loop - - - lda #128 - sta _PlayerVbl+0 - - lda #0 - sta _PlayerCount - sta _CurrentAYRegister - sta _CurrentFrame - - lda #9 - sta _FrameLoadBalancer - - lda #1 - sta _MusicPlaying - - ; - ; Install the IRQ - ; - php - sei - lda #<_Mym_PlayFrame - sta _InterruptCallBack_3+1 - lda #>_Mym_PlayFrame - sta _InterruptCallBack_3+2 - plp - - rts - - -_Mym_MusicStop: - - ; Indicate the main code that the music is finished - lda #0 - sta _MusicPlaying - - ; Disable the IRQ so it does not conflict or cause weird things - php - sei - lda #<_DoNothing - sta _InterruptCallBack_3+1 - lda #>_DoNothing - sta _InterruptCallBack_3+2 - plp - - ; Cut the sound so it does not sounds like a dying cat - - ; y=register number - ; x=value to write - ldy #7 ; Control register - ldx #$FF - jsr _PsgPlayRegister - - ldy #8 ; Volume A - ldx #0 - jsr _PsgPlayRegister - - ldy #9 ; Volume B - ldx #0 - jsr _PsgPlayRegister - - ldy #10 ; Volume C - ldx #0 - jsr _PsgPlayRegister - rts - - -_Mym_PlayFrame: - - ; - ; Check for end of music - ; CountZero: $81,$0d - dec _MusicResetCounter+0 - bne music_contines - dec _MusicResetCounter+1 - bne music_contines - -music_resets: - jmp _Mym_MusicStop - -music_contines: - - ; - ; Play a frame of 14 registers - ; - - lda _CurrentFrame - sta _auto_psg_play_read+1 - lda #>_PlayerBuffer - sta _auto_psg_play_read+2 - - ldy #0 -register_loop: - -_auto_psg_play_read: - ldx _PlayerBuffer - - ; y=register number - ; x=value to write - jsr _PsgPlayRegister - - inc _auto_psg_play_read+2 - iny - cpy #14 - bne register_loop - - - - inc _CurrentFrame - inc _PlayerCount - - lda _CurrentAYRegister - cmp #14 - bcs end_reg - - - dec _FrameLoadBalancer - bne end - - jsr _PlayerUnpackRegister - inc _CurrentAYRegister - lda #9 - sta _FrameLoadBalancer -end: - rts - - -end_reg: - - lda _PlayerCount - cmp #128 - bcc skip2 - - lda #0 - sta _CurrentAYRegister - sta _PlayerCount - lda #9 - sta _FrameLoadBalancer - - clc - lda _PlayerVbl+0 - adc #128 - sta _PlayerVbl+0 -skip2: - - - rts - - - -; y=register number -; x=value to write -_PsgPlayRegister: - - sty VIA_1 - txa - - pha - lda VIA_2 - ora #$EE ; $EE 238 11101110 - sta VIA_2 - - and #$11 ; $11 17 00010001 - ora #$CC ; $CC 204 11001100 - sta VIA_2 - - tax - pla - sta VIA_1 - txa - ora #$EC ; $EC 236 11101100 - sta VIA_2 - - and #$11 ; $11 17 00010001 - ora #$CC ; $CC 204 11001100 - sta VIA_2 - - rts - - - - -; -; Initialise X with the number of bits to read -; Y is not modifier -; -_ReadBits: - - lda #0 - sta _DecodedResult - - ; Will iterate X times (number of bits to read) -loop_read_bits: - - dec _DecodeBitCounter - beq get_next_byte - -shift_bit: - asl _DecodedByte - rol _DecodedResult - - dex - bne loop_read_bits - rts - -get_next_byte: - ; reset mask - lda #8 - sta _DecodeBitCounter - - ; fetch a new byte, and increment the adress. -__auto_music_ptr: - lda _MusicData+2 - sta _DecodedByte - - inc __auto_music_ptr+1 - bne shift_bit - inc __auto_music_ptr+2 - jmp shift_bit - - - - - -_PlayerUnpackRegister: - lda #>_PlayerBuffer - clc - adc _CurrentAYRegister - sta _RegisterBufferHigh -_PlayerUnpackRegister2: - ; - ; Init register bit count and current value - ; - ldx _CurrentAYRegister - lda _PlayerRegValues,x - sta _PlayerRegCurrentValue - - - ; - ; Check if it's packed or not - ; and call adequate routine... - ; - ldx #1 - jsr _ReadBits - ldx _DecodedResult - bne DecompressFragment - - -UnchangedFragment: - - ; - ; No change at all, just repeat '_PlayerRegCurrentValue' 128 times - ; - lda _RegisterBufferHigh ; highpart of buffer adress + register number - sta __auto_copy_unchanged_write+2 - - ldx #128 ; 128 iterations - lda _PlayerRegCurrentValue ; Value to write - - ldy _PlayerVbl - -repeat_loop: -__auto_copy_unchanged_write: - sta _PlayerBuffer,y - iny - dex - bne repeat_loop - - - jmp player_main_return - - -player_main_return: - ; Write back register current value - ldx _CurrentAYRegister - lda _PlayerRegCurrentValue - sta _PlayerRegValues,x - - ; Move to the next register buffer - inc _RegisterBufferHigh - rts - - - - -DecompressFragment: - lda _PlayerVbl ; Either 0 or 128 at this point else we have a problem... - sta _BufferFrameOffset - -decompressFragmentLoop: - -player_copy_packed_loop: - ; Check packing method - ldx #1 - jsr _ReadBits - - ldx _DecodedResult - bne PlayerNotCopyLast - -UnchangedRegister: - - ; We just copy the current value 128 times - lda _RegisterBufferHigh ; highpart of buffer adress + register number - sta __auto_player_copy_last+2 - - ldx _BufferFrameOffset ; Value between 00 and 7f - lda _PlayerRegCurrentValue ; Value to copy -__auto_player_copy_last: - sta _PlayerBuffer,x - - inc _BufferFrameOffset - - - -player_return: - - ; Check end of loop - lda _BufferFrameOffset - and #127 - bne decompressFragmentLoop - - jmp player_main_return - - -PlayerNotCopyLast: - ; Check packing method - ldx #1 - jsr _ReadBits - - ldx _DecodedResult - beq DecompressWithOffset - -ReadNewRegisterValue: - ; Read new register value (variable bit count) - ldx _CurrentAYRegister - lda _PlayerRegBits,x - tax - jsr _ReadBits - ldx _DecodedResult - stx _PlayerRegCurrentValue - - ; Copy to stream - lda _RegisterBufferHigh ; highpart of buffer adress + register number - sta __auto_player_read_new+2 - - ldx _BufferFrameOffset ; Value between 00 and 7f - lda _PlayerRegCurrentValue ; New value to write -__auto_player_read_new: - sta _PlayerBuffer,x - - inc _BufferFrameOffset - jmp player_return - - - - -DecompressWithOffset: - - ; Read Offset (0 to 127) - ldx #7 - jsr _ReadBits - - lda _RegisterBufferHigh ; highpart of buffer adress + register number - sta __auto_write+2 ; Write adress - sta __auto_read+2 ; Read adress - - ; Compute wrap around offset... - lda _BufferFrameOffset ; between 0 and 255 - clc - adc _DecodedResult ; + Offset Between 00 and 7f - sec - sbc #128 ; -128 - tay - - ; Read count (7 bits) - ldx #7 - jsr _ReadBits - - inc _DecodedResult ; 1 to 129 - - - ldx _BufferFrameOffset - -player_copy_offset_loop: - -__auto_read: - lda _PlayerBuffer,y ; Y for reading - iny - -__auto_write: - sta _PlayerBuffer,x ; X for writing - - inx - dec _DecodedResult - bne player_copy_offset_loop - - stx _BufferFrameOffset - sta _PlayerRegCurrentValue - - jmp player_return - - - - -; -; Size in bits of each PSG register -; -_PlayerRegBits: - ; Chanel A Frequency - .byt 8 - .byt 4 - - ; Chanel B Frequency - .byt 8 - .byt 4 - - ; Chanel C Frequency - .byt 8 - .byt 4 - - ; Chanel sound generator - .byt 5 - - ; select - .byt 8 - - ; Volume A,B,C - .byt 5 - .byt 5 - .byt 5 - - ; Wave period - .byt 8 - .byt 8 - - ; Wave form - .byt 8 - -_PlayerCount: - .res 1,0 ; must be equal to 0 -_MusicPlaying: - .res 1,0 ; must be equal to 0 - - -_PlayerRegValues: -_RegisterChanAFrequency: - ; Chanel A Frequency - .res 1,8 - .res 1,4 - -_RegisterChanBFrequency: - ; Chanel B Frequency - .res 1,8 - .res 1,4 - -_RegisterChanCFrequency: - ; Chanel C Frequency - .res 1,8 - .res 1,4 - -_RegisterChanNoiseFrequency: - ; Chanel sound generator - .res 1,5 - - ; select - .res 1,8 - - ; Volume A,B,C -_RegisterChanAVolume: - .res 1,5 -_RegisterChanBVolume: - .res 1,5 -_RegisterChanCVolume: - .res 1,5 - - ; Wave period - .res 1,8 - .res 1,8 - - ; Wave form - .res 1,8 - -_PlayerRegCurrentValue: - .res 1,0 -_DoNothing: - rts - -_InterruptCallBack_3: ; Used by the music player - jsr _DoNothing ; Transformed to "jsr _Mym_PlayFrame" -> 12 cycles - -; jsr MiniScrollLoading ; -> 338 cycles - - pla - tay - pla - tax - pla - - rti -_PlayerBuffer: - .res 256*14 ; About 3.5 kilobytes somewhere in memory, we put the music file in overlay memory - -.endproc - diff --git a/libsrc/telestrat/orixhdr.s b/libsrc/telestrat/orixhdr.s index c2a65d9fa..6fe2fca73 100644 --- a/libsrc/telestrat/orixhdr.s +++ b/libsrc/telestrat/orixhdr.s @@ -3,13 +3,13 @@ ; - ; The following symbol is used by the linker config. file - ; to force this module to be included into the output file. - .export __ORIXHDR__:abs = 1 + ; The following symbol is used by the linker config. file + ; to force this module to be included into the output file. + .export __ORIXHDR__:abs = 1 - ; These symbols, also, come from the configuration file. - .import __AUTORUN__, __PROGFLAG__ - .import __BASHEAD_START__, __MAIN_LAST__ + ; These symbols, also, come from the configuration file. + .import __AUTORUN__, __PROGFLAG__ + .import __BASHEAD_START__, __MAIN_LAST__ ; ------------------------------------------------------------------------ @@ -17,17 +17,17 @@ .segment "ORIXHDR" - .byte $01, $00 ; + .byte $01, $00 ; non C64 marker (same as o65 format) - .byte "ori" + .byte "ori" ; magic number - .byte $01 ; version - .byte $00,%00000000 ; 6502 only - .byte $00,$00 ; Extends - .byte $00,$00 ; OS + .byte $01 ; version of the header + .byte $00,%00000000 ; 6502 only + .byte $00,$00 ; type of language + .byte $00,$00 ; OS version .byte $00 ; reserved - .byte $00 ; auto + .byte $00 ; auto or not .word __BASHEAD_START__ ; Address of start of file .word __MAIN_LAST__ - 1 ; Address of end of file diff --git a/libsrc/telestrat/oserrlist.s b/libsrc/telestrat/oserrlist.s deleted file mode 100644 index 8ec41de6d..000000000 --- a/libsrc/telestrat/oserrlist.s +++ /dev/null @@ -1,75 +0,0 @@ -; -; Stefan Haubenthal, 2004-05-25 -; Ullrich von Bassewitz, 18.07.2002 -; -; Defines the platform specific error list. -; -; The table is built as a list of entries -; -; .byte entrylen -; .byte errorcode -; .asciiz errormsg -; -; and terminated by an entry with length zero that is returned if the -; error code could not be found. -; - - .export __sys_oserrlist - -;---------------------------------------------------------------------------- -; Macros used to generate the list (may get moved to an include file?) - -; Regular entry -.macro sys_oserr_entry code, msg - .local Start, End -Start: .byte End - Start - .byte code - .asciiz msg -End: -.endmacro - -; Sentinel entry -.macro sys_oserr_sentinel msg - .byte 0 ; Length is always zero - .byte 0 ; Code is unused - .asciiz msg -.endmacro - -;---------------------------------------------------------------------------- -; The error message table - -.rodata - -__sys_oserrlist: - sys_oserr_entry 1, "File not found" - sys_oserr_entry 2, "Invalid command end" - sys_oserr_entry 3, "No drive number" - sys_oserr_entry 4, "Bad drive number" - sys_oserr_entry 5, "Invalid filename" - sys_oserr_entry 6, "fderr=(error number)" - sys_oserr_entry 7, "Illegal attribute" - sys_oserr_entry 8, "Wildcard(s) not allowed" - sys_oserr_entry 9, "File already exists" - sys_oserr_entry 10, "Insufficient disc space" - sys_oserr_entry 11, "File open" - sys_oserr_entry 12, "Illegal quantity" - sys_oserr_entry 13, "End address missing" - sys_oserr_entry 14, "Start address > end address" - sys_oserr_entry 15, "Missing 'to'" - sys_oserr_entry 16, "Renamed file not on same disc" - sys_oserr_entry 17, "Unknown array" - sys_oserr_entry 18, "Target drive not source drive" - sys_oserr_entry 19, "Destination not specified" - sys_oserr_entry 20, "Cannot merge and overwrite" - sys_oserr_entry 21, "Single target file illegal" - sys_oserr_entry 22, "Syntax" - sys_oserr_entry 23, "Filename missing" - sys_oserr_entry 24, "Source file missing" - sys_oserr_entry 25, "Type mismatch" - sys_oserr_entry 26, "Disc write-protected" - sys_oserr_entry 27, "Incompatible drives" - sys_oserr_entry 28, "File not open" - sys_oserr_entry 29, "File end" - sys_oserr_sentinel "Unknown error" - - diff --git a/libsrc/telestrat/oserror.s b/libsrc/telestrat/oserror.s deleted file mode 100644 index 37c9bd7fc..000000000 --- a/libsrc/telestrat/oserror.s +++ /dev/null @@ -1,17 +0,0 @@ -; -; Stefan Haubenthal, 2011-04-18 -; -; int __fastcall__ _osmaperrno (unsigned char oserror); -; /* Map a system specific error into a system independent code */ -; - - .include "errno.inc" - .export __osmaperrno - -.proc __osmaperrno - - lda #<EUNKNOWN - ldx #>EUNKNOWN - rts - -.endproc diff --git a/libsrc/telestrat/print.s b/libsrc/telestrat/print.s deleted file mode 100644 index 9942e3ad9..000000000 --- a/libsrc/telestrat/print.s +++ /dev/null @@ -1,16 +0,0 @@ -; jede jede@oric.org 2017-01-22 - -; void print (char * str); - .export _print - .import popax - .importzp tmp1 - .include "telestrat.inc" - -.proc _print - stx tmp1 - ldy tmp1 - BRK_TELEMON XWSTR0 - rts -.endproc - - From bbff709d9f74c783831cad0ffacc79f65772a2f8 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Thu, 2 Feb 2017 00:00:21 +0100 Subject: [PATCH 0207/2161] Correcting return line --- doc/telestrat.sgml | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index b981fbfaf..d31457fad 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -150,7 +150,6 @@ it uses an extension "ch376 card" which handles sdcard and FAT 32 usb key. In th <item>fclose <item>fopen <item>fread - </itemize> From 4b77072fed541a3635ed2b6ec7d3b5f521c5500a Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Thu, 2 Feb 2017 00:05:50 +0100 Subject: [PATCH 0208/2161] Correcting alignment --- libsrc/telestrat/close.s | 2 +- libsrc/telestrat/mainargs.s | 12 ++++++------ libsrc/telestrat/write.s | 36 +++++++++++++++++------------------- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/libsrc/telestrat/close.s b/libsrc/telestrat/close.s index 240ebb063..04d8788d1 100644 --- a/libsrc/telestrat/close.s +++ b/libsrc/telestrat/close.s @@ -6,7 +6,7 @@ .include "zeropage.inc" .include "telestrat.inc" - .include "errno.inc" + .include "errno.inc" .include "fcntl.inc" ; int open (const char* name, int flags, ...); /* May take a mode argument */ diff --git a/libsrc/telestrat/mainargs.s b/libsrc/telestrat/mainargs.s index fa388cbfa..41c3a5131 100644 --- a/libsrc/telestrat/mainargs.s +++ b/libsrc/telestrat/mainargs.s @@ -26,14 +26,14 @@ initmainargs: L0: lda BUFEDT,x beq L3 cmp #' ' - bne L1 - lda #0 - beq L3 + bne L1 + lda #0 + beq L3 L1: sta name,x inx - cpx #FNAME_LEN + cpx #FNAME_LEN bne L0 - lda #0 + lda #0 L3: sta name,x inc __argc ; argc always is equal to, at least, 1 @@ -57,7 +57,7 @@ setterm:sta term ; Set end of argument marker ; Now, store a pointer, to the argument, into the next slot. txa ; Get low byte - clc + clc adc #<BUFEDT bcc L4 inc L5+1 diff --git a/libsrc/telestrat/write.s b/libsrc/telestrat/write.s index 1c0190531..278c28c83 100644 --- a/libsrc/telestrat/write.s +++ b/libsrc/telestrat/write.s @@ -24,25 +24,23 @@ stx ptr1+1 jsr popax ; get fd and discard - ; if fd=0001 then it stdout - - - cpx #0 - beq next - jmp L1 + ; if fd=0001 then it stdout + cpx #0 + beq next + jmp L1 next: - cmp #1 - beq L1 + cmp #1 + beq L1 - ; Here it's a file opened - lda ptr1 - sta PTR_READ_DEST - lda ptr1+1 - sta PTR_READ_DEST+1 - lda ptr3 - ldy ptr3+1 - BRK_TELEMON XFWRITE - rts + ; Here it's a file opened + lda ptr1 + sta PTR_READ_DEST + lda ptr1+1 + sta PTR_READ_DEST+1 + lda ptr3 + ldy ptr3+1 + BRK_TELEMON XFWRITE + rts L1: inc ptr2 @@ -54,9 +52,9 @@ L2: ldy #0 tax cpx #$0A ; Check for \n bne L3 - BRK_TELEMON XWR0 ; Macro send char to screen (channel 0 in telemon terms) + BRK_TELEMON XWR0 ; Macro send char to screen (channel 0 in telemon terms) lda #$0D ; return to the beggining of the line - BRK_TELEMON XWR0 ; Macro ; + BRK_TELEMON XWR0 ; Macro ; ldx #$0D From 5abb40b229a3bc6a52ef70dbf1b50cd44f81c418 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Thu, 2 Feb 2017 00:11:11 +0100 Subject: [PATCH 0209/2161] Last push for tonight :) --- libsrc/telestrat/open.s | 23 +++++++++++++---------- libsrc/telestrat/read.s | 4 +--- libsrc/telestrat/write.s | 2 +- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/libsrc/telestrat/open.s b/libsrc/telestrat/open.s index b3b390003..8e94de311 100644 --- a/libsrc/telestrat/open.s +++ b/libsrc/telestrat/open.s @@ -1,6 +1,8 @@ - .export _open - .import addysp,popax - .importzp sp,tmp2,tmp3,tmp1 + .export _open + + .import addysp,popax + + .importzp sp,tmp2,tmp3,tmp1 .include "telestrat.inc" @@ -15,17 +17,18 @@ dey ; ...checked (it generates a c compiler warning) dey dey - beq parmok ; Branch if parameter count ok - jsr addysp ; Fix stack, throw away unused parameters + beq parmok ; Branch if parameter count ok + jsr addysp ; Fix stack, throw away unused parameters ; Parameters ok. Pop the flags and save them into tmp3 -parmok: jsr popax ; Get flagss - sta tmp3 ; save flags +parmok: + jsr popax ; Get flagss + sta tmp3 ; save flags ; Get the filename from stack and parse it. Bail out if is not ok - jsr popax ; Get name - ldy tmp3 ; Get flags again - BRK_TELEMON XOPEN ; launch primitive ROM + jsr popax ; Get name + ldy tmp3 ; Get flags again + BRK_TELEMON XOPEN ; launch primitive ROM rts .endproc diff --git a/libsrc/telestrat/read.s b/libsrc/telestrat/read.s index 85a6132eb..75766cda2 100644 --- a/libsrc/telestrat/read.s +++ b/libsrc/telestrat/read.s @@ -2,8 +2,6 @@ ; jede jede@oric.org 2017-01-22 ; - - .FEATURE c_comments,labels_without_colons,pc_assignment, loose_char_term .export _read .import popax @@ -11,7 +9,7 @@ .include "zeropage.inc" .include "telestrat.inc" -; int read (int fd, void* buf, unsigned count); +;int read (int fd, void* buf, unsigned count); .proc _read sta ptr1 ; count diff --git a/libsrc/telestrat/write.s b/libsrc/telestrat/write.s index 278c28c83..1d269887d 100644 --- a/libsrc/telestrat/write.s +++ b/libsrc/telestrat/write.s @@ -59,7 +59,7 @@ L2: ldy #0 ldx #$0D L3: - BRK_TELEMON XWR0 ; Macro + BRK_TELEMON XWR0 ; Macro inc ptr1 bne L1 From ad6e54c2d8c470f44d1a5ee3fe45e2ce2ba9bd0d Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Thu, 2 Feb 2017 22:44:06 +0100 Subject: [PATCH 0210/2161] Updating doc --- doc/telestrat.sgml | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index d31457fad..c04e14f54 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -9,7 +9,7 @@ <date>2017-01-22 <abstract> -An overview over the Telestrat (telemon 3.0 : http://orix.oric.org) runtime system as it is implemented for the cc65 C +An overview over the Telestrat (Telemon 3.0 : http://orix.oric.org) runtime system as it is implemented for the cc65 C compiler.) </abstract> @@ -37,7 +37,7 @@ is a machine language program with a 20 bytes header described here : http://ori This header is used for Telemon 3.0. -Anyway, for Telemon 2.4, there is no file management, there is no TAPE routine in telemon, there is no way to load a binary easiy. +Anyway, for Telemon 2.4, there is no file management, there is no TAPE routine in Telemon, there is no way to load a binary easily. Stratsed (the Telestrat operating system) handles files management. Stratsed is loaded to memory from floppy disk. @@ -47,10 +47,12 @@ The only way to load a binary (for Telemon 2.4) is to : <itemize> <item>remove the 20 bytes header <item>download osdk : http://osdk.defence-force.org/index?page=download -<item>use Floppybuilder in OSDK to insert the binary with the tool (please read FloppyBuilder manual to insert your binary, and to start microdisc boot sector when telestrat starts) +<item>use Floppybuilder in OSDK to insert the binary with the tool (please read FloppyBuilder manual to insert your binary, and to start microdisc boot sector when Telestrat starts) </itemize> +Please note also, that the binary converted into TAP file, will not produce a right stratsed file when tap2dsk and old2mfm are used. You will be in the case that Telestrat/Stratsed crashed when you do "DIR" command. +If you know the Stratsed disk format, please contact the author of this doc. <sect>Memory layout<p> @@ -60,7 +62,6 @@ In the standard setup, cc65-generated programs use the memory from available. ROM calls are possible without further precautions. - Special locations: <descrip> @@ -110,7 +111,6 @@ structures; accessing the struct fields will access the chip registers. </descrip><p> - <sect>Loadable drivers<p> <sect1>Extended memory drivers<p> @@ -124,27 +124,31 @@ No extended memory drivers are currently available for the Telestrat. telemon 2.4 & 3.0 manages joysticks but it had been handled yet. -</descrip><p> +</descrip> <sect1>Mouse drivers<p> +<descrip> + Telestrat manages also mouse, but it had been no handled yet in this version. +</descrip> + <sect1>RS232 device drivers<p> <descrip> -not done +Telestrat has a RS232 port, but it's not used -</descrip><p> +</descrip>< <sect>Limitations<label id="limitations"><p> <sect1>Disk I/O<p> -This version handles fopen, fread, fclose primitives. Because Telemon 3.0 handles these three primitives. By the way, -it uses an extension "ch376 card" which handles sdcard and FAT 32 usb key. In the next version of Telemon, FT DOS, Sedoric, Stratsed will be handled in these 3 primitives. +Telemon 3.0 handles fopen, fread, fclose primitives. It means that this function will crash the Telestrat because Telemon 2.4 did not have not these primitives. +By the way, Telemon 3.0 uses an extension "ch376 card" which handles sdcard and FAT 32 usb key. In the next version of Telemon, FT DOS, Sedoric, Stratsed will be handled in these 3 primitives (fopen, fread, fclose). <itemize> <item>fclose From d76911d38a8544c3351977e2a8edd81a3bcb75e7 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Thu, 2 Feb 2017 22:53:28 +0100 Subject: [PATCH 0211/2161] Fixing telestrat.h --- include/telestrat.h | 34 +++++++++++++++++++++++++++++----- libsrc/telestrat/close.s | 2 -- libsrc/telestrat/mainargs.s | 2 +- libsrc/telestrat/open.s | 4 +--- libsrc/telestrat/write.s | 2 +- 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/include/telestrat.h b/include/telestrat.h index 85da8df60..5a090647b 100644 --- a/include/telestrat.h +++ b/include/telestrat.h @@ -1,17 +1,41 @@ +/*****************************************************************************/ +/* */ +/* telestrat.h */ +/* */ +/* Oric Telestrat system-specific definitions */ +/* */ +/* */ +/* */ +/* (C) 2017 Debrune Jérome, <jede@oric.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. */ +/* */ +/*****************************************************************************/ -void hires(); -void text(); void oups(); void ping(); void zap(); void shoot(); void explode(); -void paper(char color); -void ink(char color); - void kbdclick1(); diff --git a/libsrc/telestrat/close.s b/libsrc/telestrat/close.s index 04d8788d1..40e2c10b3 100644 --- a/libsrc/telestrat/close.s +++ b/libsrc/telestrat/close.s @@ -14,5 +14,3 @@ BRK_TELEMON XCLOSE ; launch primitive ROM rts .endproc - - \ No newline at end of file diff --git a/libsrc/telestrat/mainargs.s b/libsrc/telestrat/mainargs.s index 41c3a5131..0c9e799da 100644 --- a/libsrc/telestrat/mainargs.s +++ b/libsrc/telestrat/mainargs.s @@ -8,7 +8,7 @@ .constructor initmainargs, 24 .import __argc, __argv - .import ptr1 + .import ptr1 .include "telestrat.inc" .macpack generic diff --git a/libsrc/telestrat/open.s b/libsrc/telestrat/open.s index 8e94de311..08910f4f2 100644 --- a/libsrc/telestrat/open.s +++ b/libsrc/telestrat/open.s @@ -27,9 +27,7 @@ parmok: sta tmp3 ; save flags ; Get the filename from stack and parse it. Bail out if is not ok jsr popax ; Get name - ldy tmp3 ; Get flags again + ldy tmp3 ; Get flags again BRK_TELEMON XOPEN ; launch primitive ROM rts .endproc - - \ No newline at end of file diff --git a/libsrc/telestrat/write.s b/libsrc/telestrat/write.s index 1d269887d..8c2bc08f7 100644 --- a/libsrc/telestrat/write.s +++ b/libsrc/telestrat/write.s @@ -53,7 +53,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 beggining of the line BRK_TELEMON XWR0 ; Macro ; From d2fc2c74fb40a8d3a02b412560e71853c19207fb Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Fri, 3 Feb 2017 21:11:37 +0100 Subject: [PATCH 0212/2161] Correcting scrsize.s into _scrsize.s --- libsrc/telestrat/{scrsize.s => _scrsize.s} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename libsrc/telestrat/{scrsize.s => _scrsize.s} (100%) diff --git a/libsrc/telestrat/scrsize.s b/libsrc/telestrat/_scrsize.s similarity index 100% rename from libsrc/telestrat/scrsize.s rename to libsrc/telestrat/_scrsize.s From 39a1a142e3ea26bcf052df9db372970cfe9214c0 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Mon, 6 Feb 2017 19:26:12 +0100 Subject: [PATCH 0213/2161] gamate, lynx, nes, pce: remove joy_stddrv.s These targets don't support dynamically loaded joystick drivers. --- libsrc/gamate/joy_stddrv.s | 13 ------------- libsrc/lynx/joy_stddrv.s | 13 ------------- libsrc/nes/joy_stddrv.s | 13 ------------- libsrc/pce/joy_stddrv.s | 13 ------------- 4 files changed, 52 deletions(-) delete mode 100644 libsrc/gamate/joy_stddrv.s delete mode 100644 libsrc/lynx/joy_stddrv.s delete mode 100644 libsrc/nes/joy_stddrv.s delete mode 100644 libsrc/pce/joy_stddrv.s diff --git a/libsrc/gamate/joy_stddrv.s b/libsrc/gamate/joy_stddrv.s deleted file mode 100644 index b830d8d86..000000000 --- a/libsrc/gamate/joy_stddrv.s +++ /dev/null @@ -1,13 +0,0 @@ -; -; Name of the standard joystick driver -; -; Oliver Schmidt, 2012-11-01 -; -; const char joy_stddrv[]; -; - - .export _joy_stddrv - -.rodata - -_joy_stddrv: .asciiz "gamate-stdjoy.joy" diff --git a/libsrc/lynx/joy_stddrv.s b/libsrc/lynx/joy_stddrv.s deleted file mode 100644 index b0d30e8d5..000000000 --- a/libsrc/lynx/joy_stddrv.s +++ /dev/null @@ -1,13 +0,0 @@ -; -; Name of the standard joystick driver -; -; Oliver Schmidt, 2012-11-01 -; -; const char joy_stddrv[]; -; - - .export _joy_stddrv - -.rodata - -_joy_stddrv: .asciiz "lynx-stdjoy.joy" diff --git a/libsrc/nes/joy_stddrv.s b/libsrc/nes/joy_stddrv.s deleted file mode 100644 index b99659746..000000000 --- a/libsrc/nes/joy_stddrv.s +++ /dev/null @@ -1,13 +0,0 @@ -; -; Name of the standard joystick driver -; -; Oliver Schmidt, 2012-11-01 -; -; const char joy_stddrv[]; -; - - .export _joy_stddrv - -.rodata - -_joy_stddrv: .asciiz "nes-stdjoy.joy" diff --git a/libsrc/pce/joy_stddrv.s b/libsrc/pce/joy_stddrv.s deleted file mode 100644 index ba397409a..000000000 --- a/libsrc/pce/joy_stddrv.s +++ /dev/null @@ -1,13 +0,0 @@ -; -; Name of the standard joystick driver -; -; Oliver Schmidt, 2012-11-01 -; -; const char joy_stddrv[]; -; - - .export _joy_stddrv - -.rodata - -_joy_stddrv: .asciiz "pce-stdjoy.joy" From e6359ec01947e75ed209d145f063da1692ee9c71 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Mon, 6 Feb 2017 20:59:52 +0100 Subject: [PATCH 0214/2161] Add initial creativision.sgml, contributed by Stefan Haubenthal. --- doc/creativision.sgml | 174 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 doc/creativision.sgml diff --git a/doc/creativision.sgml b/doc/creativision.sgml new file mode 100644 index 000000000..5b69da75a --- /dev/null +++ b/doc/creativision.sgml @@ -0,0 +1,174 @@ +<!doctype linuxdoc system> + +<article> + +<title>VTech Creativision (aka Funvision) specific information for cc65 +<author><url url="mailto:polluks+cc65@sdf.lonestar.org" name="Stefan A. Haubenthal"> +<date>2016-04-14 + +<abstract> +An overview over the Creativision runtime system as it is implemented for the +cc65 C compiler. +</abstract> + +<!-- Table of contents --> +<toc> + +<!-- Begin the document --> + +<sect>Overview<p> + +This file contains an overview of the Creativision runtime system as it comes +with the cc65 C compiler. It describes the memory layout, Creativision specific header +files, available drivers, and any pitfalls specific to that platform. + +Please note that Creativision specific functions are just mentioned here, they are +described in detail in the separate <url url="funcref.html" name="function +reference">. Even functions marked as "platform dependent" may be available on +more than one platform. Please see the function reference for more information. + + +<sect>Binary format<p> + +The standard binary output format generated by the linker for the Creativision target +is a 4 kbyte machine language program. It is of course possible to change +this behaviour by using one of the different linker configs. + +<sect>Memory layout<p> + +cc65 generated programs with the default setup run with the I/O area enabled, +which gives a usable memory range of $B000 - $BEFF. +More ROM may need additional bankswitching code. + +Special locations: + +<descrip> + <tag/Text screen/ + The text screen is located at VRAM $1000. + + <tag/Stack/ + The C runtime stack is located at $3FF and growing downwards. + + <tag/Heap/ + The C heap is located at the end of the program and grows towards the C + runtime stack. + +</descrip><p> + + + +<sect>Platform specific header files<p> + +Programs containing Creativision specific code may use the <tt/creativision.h/ header file. + + +<sect1>Creativision specific functions<p> + +<itemize> +<item>bios_playsound +<item>joystate +<item>psg_delay +<item>psg_outb +<item>psg_silence +</itemize> + + + +<!--<sect1>Hardware access<p> + +The following pseudo variables declared in the <tt/creativision.inc/ include file do +allow access to hardware located in the address space. + +<descrip> + + <tag><tt/VDP/</tag> + The <tt/VDP/ defines allow access to the video chip. + +</descrip><p> + +<descrip> + + <tag><tt/PIA/</tag> + The <tt/PIA/ defines allow access to the I/O chip. + +</descrip><p>--> + + + +<sect>Loadable drivers<p> + +<sect1>Graphics drivers<p> + +No graphics drivers are currently available for the Creativision. + + +<sect1>Extended memory drivers<p> + +No extended memory drivers are currently available for the Creativision. + + +<sect1>Joystick drivers<p> + +No joystick drivers are currently available for the Creativision but <tt/joystate()/. + + +<sect1>Mouse drivers<p> + +No mouse drivers are currently available for the Creativision. + + +<sect1>RS232 device drivers<p> + +No communication port drivers are currently available for the Creativision. + + + +<sect>Limitations<p> + +<sect1>Disk I/O<p> + +The existing library for the Creativision doesn't implement C file +I/O. There are even no hacks for the <tt/read()/ and <tt/write()/ routines. + +To be more concrete, this limitation means that you cannot use any of the +following functions (and a few others): + +<itemize> +<item>fclose +<item>fopen +<item>fread +<item>fprintf +<item>fputc +<item>fscanf +<item>fwrite +<item>... +</itemize> + + + +<sect>Other hints<p> + + + +<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> From c33383e6de5beb17931c4375307071653fb9cdd0 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Mon, 6 Feb 2017 21:06:08 +0100 Subject: [PATCH 0215/2161] Add Creativision to README.md and html index --- README.md | 1 + doc/index.sgml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index b62ac761d..359fdaa08 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ including - the NEC PC-Engine (aka TurboGrafx-16). - the Nintendo Entertainment System (NES) console. - the Watara Supervision console. +- the VTech Creativision console. - the Oric Atmos. - the Lynx console. - the Ohio Scientific Challenger 1P. diff --git a/doc/index.sgml b/doc/index.sgml index 9b7ab794e..2a5c8894f 100644 --- a/doc/index.sgml +++ b/doc/index.sgml @@ -140,6 +140,9 @@ <tag><htmlurl url="cbm610.html" name="cbm610.html"></tag> Topics specific to the Commodore 610. + <tag><htmlurl url="creativision.html" name="creativision.html"></tag> + Topics specific to the Creativision Console. + <tag><htmlurl url="lynx.html" name="lynx.html"></tag> Topics specific to the Atari Lynx Game Console. From 69e3bbea7eba3c97802cf8fa94f581432ee5300c Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 7 Feb 2017 07:33:27 -0500 Subject: [PATCH 0216/2161] Reverted 'Used more mundane addressing in some of the instructions in "zlib/inflatemem.s".' This reverted some of commit e7e65044e607f15b7d5b4e55abf7cdcb123993a8. --- libsrc/zlib/inflatemem.s | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/libsrc/zlib/inflatemem.s b/libsrc/zlib/inflatemem.s index ea550c074..b3a0510c5 100644 --- a/libsrc/zlib/inflatemem.s +++ b/libsrc/zlib/inflatemem.s @@ -1,10 +1,15 @@ ; ; 2003-09-21, Piotr Fusik -; 2016-07-19, Greg King +; 2017-02-07, Greg King ; ; unsigned __fastcall__ inflatemem (char* dest, const char* source); ; +; Two "lda (0,x)" instructions can't be assembled for the PC-Engine library +; because an implied ".setdp $2000" changes $00 into a non-zero-page address. +; Therefore, this file isn't assembled for that target. +.ifndef __PCE__ + .export _inflatemem .import incsp2 @@ -139,8 +144,8 @@ inflateCopyBlock: ldy #1 sty getBit_hold ; Get 16-bit length - ldx #0 - lda (inputPointer,x) + ldx #inputPointer + lda (0,x) sta moveBlock_len lda (inputPointer),y sta moveBlock_len+1 @@ -165,15 +170,15 @@ moveBlock: .endif inc moveBlock_len+1 moveBlock_1: - lda (inputPointer,x) + lda (0,x) .if (.cpu & CPU_ISET_65SC02) sta (outputPointer) .else sta (outputPointer),y .endif - inc inputPointer + inc 0,x bne moveBlock_2 - inc inputPointer+1 + inc 1,x moveBlock_2: inc outputPointer bne moveBlock_3 @@ -671,3 +676,5 @@ bitsPointer_h: ; Sorted codes. sortedCodes: .res 256+1+29+30+2 + +.endif From 38451fa8a4d6a1e4141f24bb50e774582ac564af Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 8 Feb 2017 14:34:35 +0100 Subject: [PATCH 0217/2161] intermediate check-in -- creativision joystick driver --- asminc/creativision.inc | 6 +- libsrc/creativision/joy/creativision-stdjoy.s | 191 ++++++++++++++++++ libsrc/creativision/joy_stat_stddrv.s | 12 ++ libsrc/creativision/libref.s | 3 +- 4 files changed, 207 insertions(+), 5 deletions(-) create mode 100644 libsrc/creativision/joy/creativision-stdjoy.s create mode 100644 libsrc/creativision/joy_stat_stddrv.s diff --git a/asminc/creativision.inc b/asminc/creativision.inc index 624b65e8f..bd30bc462 100644 --- a/asminc/creativision.inc +++ b/asminc/creativision.inc @@ -29,10 +29,10 @@ CH_URCORNER = 36 CH_LLCORNER = 37 CH_LRCORNER = 38 -;** I/O +;** I/O (Zero-page variables) ZP_KEYBOARD = $10 ZP_JOY0_DIR = $11 ZP_JOY1_DIR = $13 -ZP_JOY_LBUTTONS = $16 -ZP_JOY_RBUTTONS = $17 +ZP_JOY0_BUTTONS = $16 +ZP_JOY1_BUTTONS = $17 diff --git a/libsrc/creativision/joy/creativision-stdjoy.s b/libsrc/creativision/joy/creativision-stdjoy.s new file mode 100644 index 000000000..f24a8045b --- /dev/null +++ b/libsrc/creativision/joy/creativision-stdjoy.s @@ -0,0 +1,191 @@ +; +; Standard joystick driver for the Creativision. +; +; Christian Groessler, 2017-02-06 +; + + .include "zeropage.inc" + + .include "joy-kernel.inc" + .include "joy-error.inc" + .include "creativision.inc" + + .macpack module + + +; ------------------------------------------------------------------------ +; Header. Includes jump table + + module_header _creativisionstd_joy + +; Driver signature + + .byte $6A, $6F, $79 ; "joy" + .byte JOY_API_VERSION ; Driver API version number + +; Library reference + + .addr $0000 + +; Button state masks (8 values) + + .byte $10 ; JOY_UP + .byte $04 ; JOY_DOWN + .byte $20 ; JOY_LEFT + .byte $08 ; JOY_RIGHT + .byte $01 ; JOY_FIRE (button #1) + .byte $02 ; JOY_FIRE2 (button #2) + .byte $00 ; Future expansion + .byte $00 ; Future expansion + +; Jump table. + + .addr INSTALL + .addr UNINSTALL + .addr COUNT + .addr READJOY + .addr 0 ; IRQ entry not used + +; ------------------------------------------------------------------------ +; Constants + +JOY_COUNT = 2 ; Number of joysticks we support + +; ------------------------------------------------------------------------ +; Code + + .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 + ldx #0 +; rts ; Fall through + +; ------------------------------------------------------------------------ +; 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. +; + +READJOY: + and #1 ; fix joystick number + bne READJOY_1 ; read right joystick + +; Read left joystick + + ldx ZP_JOY0_DIR + lda ZP_JOY0_BUTTONS + jmp convert ; convert joystick state to sane cc65 values + +; Read right joystick + +READJOY_1: + + ldx ZP_JOY1_DIR + lda ZP_JOY1_BUTTONS + lsr a + lsr a + ;jmp convert ; convert joystick state to sane cc65 values + ; fall thru... + +; ------------------------------------------------------------------------ +; convert: make runtime lib compatible values +; A - buttons +; X - direction +; + +convert: + ldy #0 + sty retval ; initialize return value + +; ------ +; buttons: + ; Port values are for the left hand joystick (right hand joystick + ; values were shifted to the right to be identical). + ; Why are there two bits indicating a pressed trigger? + ; According to the "Second book of programs for the Dick Smith Wizard" + ; (pg. 88ff), the left hand fire button gives the value of + ; %00010001 and the right hand button gives %00100010 + ; Why two bits? Am I missing something? Can there be cases that just + ; one of those bits is set? + ; We just test if any of those two bits is not zero... + + tay + and #%00010001 + beq cnv_1 + + inc retval ; left button pressed + +cnv_1: tya + and #%00100010 + beq cnv_2 + + lda #$02 + ora retval + sta retval ; right button pressed + +; ------ +; direction: +cnv_2: txa + ; tested with https://sourceforge.net/projects/creativisionemulator + ; $49 - %01001001 - up + ; $41 - %01000001 - down + ; $4D - %01001101 - left + ; $45 - %01000101 - right + ; + ; are these correct? "Second book of programs for the Dick Smith Wizard" pg. 85 says something different + ; ignored for now... + ; $85 - %10000101 - up + right + ; $8D - %10001101 - down + left + ; $89 - %10001001 - up + left + ; $85 - %10000101 - down + right (emulator bug?) + + bit testbit ; bit #0 set? + beq done ; no, no direction + + and #%00001100 ; mask out other bits + tax + lda #%00000100 ; init bitmask +loop: dex + bmi done2 + asl a + bne loop + +done2: ora retval + rts + +done: lda retval + rts + +; ------------------------------------------------------------------------ +; + .data +testbit:.byte $01 + +; ------------------------------------------------------------------------ +; + .bss +retval: .res 0 diff --git a/libsrc/creativision/joy_stat_stddrv.s b/libsrc/creativision/joy_stat_stddrv.s new file mode 100644 index 000000000..fc458641c --- /dev/null +++ b/libsrc/creativision/joy_stat_stddrv.s @@ -0,0 +1,12 @@ +; +; Address of the static standard joystick driver +; +; Christian Groessler, 2017-02-06 +; +; const void joy_static_stddrv[]; +; + + .export _joy_static_stddrv + .import _creativisionstd_joy + +_joy_static_stddrv := _creativisionstd_joy diff --git a/libsrc/creativision/libref.s b/libsrc/creativision/libref.s index b642da80a..19e7e778f 100644 --- a/libsrc/creativision/libref.s +++ b/libsrc/creativision/libref.s @@ -2,8 +2,7 @@ ; Oliver Schmidt, 2013-05-31 ; - .export joy_libref, tgi_libref + .export joy_libref .import _exit joy_libref := _exit -tgi_libref := _exit From 9cde534b232572b30456b2d4574d0ef0f0ccad0b Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Thu, 9 Feb 2017 18:46:56 +0100 Subject: [PATCH 0218/2161] Rollback for *.vcxproj, telestrat.sgml modified for "don't" instead of "did not" for telemon2.4 --- doc/telestrat.sgml | 2 +- src/ar65.vcxproj | 6 +++--- src/ca65.vcxproj | 6 +++--- src/cc65.vcxproj | 6 +++--- src/chrcvt65.vcxproj | 6 +++--- src/cl65.vcxproj | 6 +++--- src/co65.vcxproj | 6 +++--- src/common.vcxproj | 6 +++--- src/da65.vcxproj | 8 +++++--- src/grc65.vcxproj | 6 +++--- src/ld65.vcxproj | 6 +++--- src/od65.vcxproj | 6 +++--- src/sim65.vcxproj | 6 +++--- src/sp65.vcxproj | 6 +++--- 14 files changed, 42 insertions(+), 40 deletions(-) diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index c04e14f54..9032156ee 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -147,7 +147,7 @@ Telestrat has a RS232 port, but it's not used <sect1>Disk I/O<p> -Telemon 3.0 handles fopen, fread, fclose primitives. It means that this function will crash the Telestrat because Telemon 2.4 did not have not these primitives. +Telemon 3.0 handles fopen, fread, fclose primitives. It means that this function will crash the Telestrat because Telemon 2.4 does not have these primitives. By the way, Telemon 3.0 uses an extension "ch376 card" which handles sdcard and FAT 32 usb key. In the next version of Telemon, FT DOS, Sedoric, Stratsed will be handled in these 3 primitives (fopen, fread, fclose). <itemize> diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index 003a5fa69..b077134ce 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index fb7cf2e26..4e02fa2a9 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index aa85b0936..1c1f993fe 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index d120399d1..1daf7cae9 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index b6ceb161a..64c1126b1 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 89eed36e1..c66c8aac8 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/common.vcxproj b/src/common.vcxproj index c466d9712..053d23981 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -113,13 +113,13 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> <ConfigurationType>StaticLibrary</ConfigurationType> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/da65.vcxproj b/src/da65.vcxproj index cf297fd32..2695edc08 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> @@ -86,6 +86,7 @@ <ClCompile Include="da65\infofile.c" /> <ClCompile Include="da65\labels.c" /> <ClCompile Include="da65\main.c" /> + <ClCompile Include="da65\opc4510.c" /> <ClCompile Include="da65\opc6502.c" /> <ClCompile Include="da65\opc6502x.c" /> <ClCompile Include="da65\opc65816.c" /> @@ -109,6 +110,7 @@ <ClInclude Include="da65\handler.h" /> <ClInclude Include="da65\infofile.h" /> <ClInclude Include="da65\labels.h" /> + <ClInclude Include="da65\opc4510.h" /> <ClInclude Include="da65\opc6502.h" /> <ClInclude Include="da65\opc6502x.h" /> <ClInclude Include="da65\opc65816.h" /> diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index afac0cce1..211ad7cce 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index cc5598aad..acb9b4240 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 2ace26001..c788ac961 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9ba0980ba..f87b4db6b 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 6e7d992d4..8db98346c 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v120</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> From 4266e712f25383a2a5dbabb0161240f8c989b9f1 Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Sun, 12 Feb 2017 11:41:11 +0100 Subject: [PATCH 0219/2161] Optimize inflatemem. The new version is 30% shorter and 10% faster. It also avoids the indirect-X addressing mode, which was a problem for PC-Engine. --- libsrc/zlib/inflatemem.s | 954 +++++++++++++++++---------------------- 1 file changed, 404 insertions(+), 550 deletions(-) diff --git a/libsrc/zlib/inflatemem.s b/libsrc/zlib/inflatemem.s index b3a0510c5..27802fbff 100644 --- a/libsrc/zlib/inflatemem.s +++ b/libsrc/zlib/inflatemem.s @@ -1,43 +1,41 @@ ; -; 2003-09-21, Piotr Fusik -; 2017-02-07, Greg King +; 2017-02-12, Piotr Fusik ; ; unsigned __fastcall__ inflatemem (char* dest, const char* source); ; - -; Two "lda (0,x)" instructions can't be assembled for the PC-Engine library -; because an implied ".setdp $2000" changes $00 into a non-zero-page address. -; Therefore, this file isn't assembled for that target. -.ifndef __PCE__ +; NOTE: Be extremely careful with modifications, because this code is heavily +; optimized for size (for example assumes certain register and flag values +; when its internal routines return). Test with the gunzip65 sample. +; .export _inflatemem .import incsp2 - .importzp sp, sreg, ptr1, ptr2, ptr3, ptr4, tmp1 - - .macpack cpu + .importzp sp, sreg, ptr1, ptr2, ptr3, ptr4 ; -------------------------------------------------------------------------- ; ; Constants ; -; Maximum length of a Huffman code. -MAX_BITS = 15 +; Argument values for getBits. +GET_1_BIT = $81 +GET_2_BITS = $82 +GET_3_BITS = $84 +GET_4_BITS = $88 +GET_5_BITS = $90 +GET_6_BITS = $a0 +GET_7_BITS = $c0 -; All Huffman trees are stored in the bitsCount, bitsPointer_l -; and bitsPointer_h arrays. There may be two trees: the literal/length tree -; and the distance tree, or just one - the temporary tree. +; Huffman trees. +TREE_SIZE = 16 +PRIMARY_TREE = 0 +DISTANCE_TREE = TREE_SIZE -; Index in the mentioned arrays for the beginning of the literal/length tree -; or the temporary tree. -PRIMARY_TREE = 0 - -; Index in the mentioned arrays for the beginning of the distance tree. -DISTANCE_TREE = MAX_BITS - -; Size of each array. -TREES_SIZE = 2*MAX_BITS +; Alphabet. +LENGTH_SYMBOLS = 1+29+2 ; EOF, 29 length symbols, two unused symbols +DISTANCE_SYMBOLS = 30 +CONTROL_SYMBOLS = LENGTH_SYMBOLS+DISTANCE_SYMBOLS ; -------------------------------------------------------------------------- @@ -46,30 +44,26 @@ TREES_SIZE = 2*MAX_BITS ; ; Pointer to the compressed data. -inputPointer := ptr1 ; 2 bytes +inputPointer := ptr1 ; 2 bytes ; Pointer to the uncompressed data. -outputPointer := ptr2 ; 2 bytes +outputPointer := ptr2 ; 2 bytes ; Local variables. ; As far as there is no conflict, same memory locations are used ; for different variables. -inflateDynamicBlock_cnt := ptr3 ; 1 byte -inflateCodes_src := ptr3 ; 2 bytes -buildHuffmanTree_src := ptr3 ; 2 bytes -getNextLength_last := ptr3 ; 1 byte -getNextLength_index := ptr3+1 ; 1 byte - -buildHuffmanTree_ptr := ptr4 ; 2 bytes -fetchCode_ptr := ptr4 ; 2 bytes -getBits_tmp := ptr4 ; 1 byte - -moveBlock_len := sreg ; 2 bytes -inflateDynamicBlock_np := sreg ; 1 byte -inflateDynamicBlock_nd := sreg+1 ; 1 byte - -getBit_hold := tmp1 ; 1 byte +inflateStored_pageCounter := ptr3 ; 1 byte +inflateDynamic_symbol := ptr3 ; 1 byte +inflateDynamic_lastLength := ptr3+1 ; 1 byte + .assert ptr4 = ptr3 + 2, error, "Need three bytes for inflateDynamic_tempCodes" +inflateDynamic_tempCodes := ptr3+1 ; 3 bytes +inflateDynamic_allCodes := inflateDynamic_tempCodes+1 ; 1 byte +inflateDynamic_primaryCodes := inflateDynamic_tempCodes+2 ; 1 byte +inflateCodes_sourcePointer := ptr3 ; 2 bytes +inflateCodes_lengthMinus2 := ptr4 ; 1 byte +getBits_base := sreg ; 1 byte +getBit_buffer := sreg+1 ; 1 byte ; -------------------------------------------------------------------------- @@ -83,45 +77,59 @@ _inflatemem: sta inputPointer stx inputPointer+1 ; outputPointer = dest -.if (.cpu & CPU_ISET_65SC02) - lda (sp) ldy #1 -.else - ldy #0 - lda (sp),y - iny -.endif - sta outputPointer lda (sp),y sta outputPointer+1 + dey + lda (sp),y + sta outputPointer -; ldy #1 - sty getBit_hold -inflatemem_1: +; ldy #0 + sty getBit_buffer + +inflate_blockLoop: ; Get a bit of EOF and two bits of block type - ldx #3 - lda #0 +; ldy #0 + sty getBits_base + lda #GET_3_BITS jsr getBits lsr a ; A and Z contain block type, C contains EOF flag ; Save EOF flag php -; Go to the routine decompressing this block - jsr callExtr - plp - bcc inflatemem_1 -; C flag is set! + bne inflateCompressed -; return outputPointer - dest; +; Decompress a 'stored' data block. +; ldy #0 + sty getBit_buffer ; ignore bits until byte boundary + jsr getWord ; skip the length we don't need + jsr getWord ; get the two's complement length + sta inflateStored_pageCounter + bcs inflateStored_firstByte ; jmp +inflateStored_copyByte: + jsr getByte +; sec +inflateStoreByte: + jsr storeByte + bcc inflateCodes_loop +inflateStored_firstByte: + inx + bne inflateStored_copyByte + inc inflateStored_pageCounter + bne inflateStored_copyByte + +; Block decompressed. +inflate_nextBlock: + plp + bcc inflate_blockLoop + +; Decompression complete. +; return outputPointer - dest lda outputPointer -.if (.cpu & CPU_ISET_65SC02) - sbc (sp) ; C flag is set - ldy #1 -.else - ldy #0 - sbc (sp),y ; C flag is set +; ldy #0 +; sec + sbc (sp),y iny -.endif pha lda outputPointer+1 sbc (sp),y @@ -130,442 +138,346 @@ inflatemem_1: ; pop dest jmp incsp2 -; -------------------------------------------------------------------------- -; Go to proper block decoding routine. - -callExtr: - bne inflateCompressedBlock - -; -------------------------------------------------------------------------- -; Decompress a 'stored' data block. - -inflateCopyBlock: -; Ignore bits until byte boundary - ldy #1 - sty getBit_hold -; Get 16-bit length - ldx #inputPointer - lda (0,x) - sta moveBlock_len - lda (inputPointer),y - sta moveBlock_len+1 -; Skip the length and one's complement of it - lda #4 - clc - adc inputPointer - sta inputPointer - bcc moveBlock - inc inputPointer+1 -; jmp moveBlock - -; -------------------------------------------------------------------------- -; Copy block of length moveBlock_len from (0,x) to the output. - -moveBlock: - ldy moveBlock_len - beq moveBlock_1 -.if (.cpu & CPU_ISET_65SC02) -.else - ldy #0 -.endif - inc moveBlock_len+1 -moveBlock_1: - lda (0,x) -.if (.cpu & CPU_ISET_65SC02) - sta (outputPointer) -.else - sta (outputPointer),y -.endif - inc 0,x - bne moveBlock_2 - inc 1,x -moveBlock_2: - inc outputPointer - bne moveBlock_3 - inc outputPointer+1 -moveBlock_3: -.if (.cpu & CPU_ISET_65SC02) - dey -.else - dec moveBlock_len -.endif - bne moveBlock_1 - dec moveBlock_len+1 - bne moveBlock_1 - rts - -; -------------------------------------------------------------------------- +inflateCompressed: ; Decompress a Huffman-coded data block -; (A = 1: fixed, A = 2: dynamic). +; A=1: fixed block, initialize with fixed codes +; A=2: dynamic block, start by clearing all code lengths +; A=3: invalid compressed data, not handled in this routine + eor #2 -inflateCompressedBlock: - lsr a - bne inflateDynamicBlock -; Note: inflateDynamicBlock may assume that A = 1 - -; -------------------------------------------------------------------------- -; Decompress a Huffman-coded data block with default Huffman trees -; (defined by the DEFLATE format): -; literalCodeLength: 144 times 8, 112 times 9 -; endCodeLength: 7 -; lengthCodeLength: 23 times 7, 6 times 8 -; distanceCodeLength: 30 times 5+DISTANCE_TREE, 2 times 8 -; (two 8-bit codes from the primary tree are not used). - -inflateFixedBlock: - ldx #159 - stx distanceCodeLength+32 - lda #8 -inflateFixedBlock_1: - sta literalCodeLength-1,x - sta literalCodeLength+159-1,x - dex - bne inflateFixedBlock_1 - ldx #112 -; lda #9 -inflateFixedBlock_2: - inc literalCodeLength+144-1,x ; sta - dex - bne inflateFixedBlock_2 - ldx #24 -; lda #7 -inflateFixedBlock_3: - dec endCodeLength-1,x ; sta - dex - bne inflateFixedBlock_3 - ldx #30 - lda #5+DISTANCE_TREE -inflateFixedBlock_4: - sta distanceCodeLength-1,x - dex - bne inflateFixedBlock_4 - beq inflateCodes ; branch always - -; -------------------------------------------------------------------------- -; Decompress a Huffman-coded data block, reading Huffman trees first. - -inflateDynamicBlock: -; numberOfPrimaryCodes = 257 + getBits(5) - ldx #5 -; lda #1 - jsr getBits - sta inflateDynamicBlock_np -; numberOfDistanceCodes = 1 + getBits(5) - ldx #5 - lda #1+29+1 - jsr getBits - sta inflateDynamicBlock_nd -; numberOfTemporaryCodes = 4 + getBits(4) - lda #4 +; ldy #0 +inflateCompressed_setCodeLengths: tax - jsr getBits - sta inflateDynamicBlock_cnt -; Get lengths of temporary codes in the order stored in tempCodeLengthOrder - txa ; lda #0 - tay -inflateDynamicBlock_1: - ldx #3 ; A = 0 - jsr getBits ; does not change Y -inflateDynamicBlock_2: - ldx tempCodeLengthOrder,y - sta literalCodeLength,x - lda #0 + beq inflateCompressed_setLiteralCodeLength +; fixed Huffman literal codes: +; 144 8-bit codes +; 112 9-bit codes + lda #4 + cpy #144 + rol a +inflateCompressed_setLiteralCodeLength: + sta literalSymbolCodeLength,y + beq inflateCompressed_setControlCodeLength +; fixed Huffman control codes: +; 24 7-bit codes +; 6 8-bit codes +; 2 meaningless 8-bit codes +; 30 5-bit distance codes + lda #5+DISTANCE_TREE + cpy #LENGTH_SYMBOLS + bcs inflateCompressed_setControlCodeLength + cpy #24 + adc #$100+2-DISTANCE_TREE +inflateCompressed_setControlCodeLength: + cpy #CONTROL_SYMBOLS + bcs inflateCompressed_noControlSymbol + sta controlSymbolCodeLength,y +inflateCompressed_noControlSymbol: iny - cpy inflateDynamicBlock_cnt - bcc inflateDynamicBlock_1 - cpy #19 - bcc inflateDynamicBlock_2 - ror literalCodeLength+19 ; C flag is set, so this will set b7 + bne inflateCompressed_setCodeLengths + + tax + beq inflateDynamic + +; Decompress a block +inflateCodes: + jsr buildHuffmanTree +inflateCodes_loop: + jsr fetchPrimaryCode + bcc inflateStoreByte + beq inflate_nextBlock +; Copy sequence from look-behind buffer +; ldy #0 + sty getBits_base + cmp #9 + bcc inflateCodes_setSequenceLength + tya +; lda #0 + cpx #1+28 + bcs inflateCodes_setSequenceLength + dex + txa + lsr a + ror getBits_base + inc getBits_base + lsr a + rol getBits_base + jsr getAMinus1BitsMax8 +; sec + adc #0 +inflateCodes_setSequenceLength: + sta inflateCodes_lengthMinus2 + ldx #DISTANCE_TREE + jsr fetchCode + cmp #4 + bcc inflateCodes_setOffsetLowByte + inc getBits_base + lsr a + jsr getAMinus1BitsMax8 +inflateCodes_setOffsetLowByte: + eor #$ff + sta inflateCodes_sourcePointer + lda getBits_base + cpx #10 + bcc inflateCodes_setOffsetHighByte + lda getNPlus1Bits_mask-10,x + jsr getBits + clc +inflateCodes_setOffsetHighByte: + eor #$ff +; clc + adc outputPointer+1 + sta inflateCodes_sourcePointer+1 + jsr copyByte + jsr copyByte +inflateCodes_copyByte: + jsr copyByte + dec inflateCodes_lengthMinus2 + bne inflateCodes_copyByte + beq inflateCodes_loop ; jmp + +inflateDynamic: +; Decompress a block reading Huffman trees first +; ldy #0 +; numberOfPrimaryCodes = 257 + getBits(5) +; numberOfDistanceCodes = 1 + getBits(5) +; numberOfTemporaryCodes = 4 + getBits(4) + ldx #3 +inflateDynamic_getHeader: + lda inflateDynamic_headerBits-1,x + jsr getBits +; sec + adc inflateDynamic_headerBase-1,x + sta inflateDynamic_tempCodes-1,x + dex + bne inflateDynamic_getHeader + +; Get lengths of temporary codes in the order stored in inflateDynamic_tempSymbols +; ldx #0 +inflateDynamic_getTempCodeLengths: + lda #GET_3_BITS + jsr getBits + ldy inflateDynamic_tempSymbols,x + sta literalSymbolCodeLength,y + ldy #0 + inx + cpx inflateDynamic_tempCodes + bcc inflateDynamic_getTempCodeLengths + ; Build the tree for temporary codes jsr buildHuffmanTree ; Use temporary codes to get lengths of literal/length and distance codes - ldx #0 - ldy #1 - stx getNextLength_last -inflateDynamicBlock_3: - jsr getNextLength - sta literalCodeLength,x - inx - bne inflateDynamicBlock_3 -inflateDynamicBlock_4: - jsr getNextLength -inflateDynamicBlock_5: - sta endCodeLength,x - inx - cpx inflateDynamicBlock_np - bcc inflateDynamicBlock_4 - lda #0 - cpx #1+29 - bcc inflateDynamicBlock_5 -inflateDynamicBlock_6: - jsr getNextLength - cmp #0 - beq inflateDynamicBlock_7 - adc #DISTANCE_TREE-1 ; C flag is set -inflateDynamicBlock_7: - sta endCodeLength,x - inx - cpx inflateDynamicBlock_nd - bcc inflateDynamicBlock_6 - ror endCodeLength,x ; C flag is set, so this will set b7 -; jmp inflateCodes - -; -------------------------------------------------------------------------- -; Decompress a data block basing on given Huffman trees. - -inflateCodes: - jsr buildHuffmanTree -inflateCodes_1: - jsr fetchPrimaryCode - bcs inflateCodes_2 -; Literal code -.if (.cpu & CPU_ISET_65SC02) - sta (outputPointer) -.else - ldy #0 - sta (outputPointer),y -.endif - inc outputPointer - bne inflateCodes_1 - inc outputPointer+1 - bcc inflateCodes_1 ; branch always -; End of block -inflateCodes_ret: - rts -inflateCodes_2: - beq inflateCodes_ret -; Restore a block from the look-behind buffer - jsr getValue - sta moveBlock_len - tya - jsr getBits - sta moveBlock_len+1 - ldx #DISTANCE_TREE - jsr fetchCode - jsr getValue - sec - eor #$ff - adc outputPointer - sta inflateCodes_src +; ldx #0 +; sec +inflateDynamic_decodeLength: +; C=1: literal codes +; C=0: control codes + stx inflateDynamic_symbol php - tya - jsr getBits - plp - eor #$ff - adc outputPointer+1 - sta inflateCodes_src+1 - ldx #inflateCodes_src - jsr moveBlock - beq inflateCodes_1 ; branch always - -; -------------------------------------------------------------------------- -; Build Huffman trees basing on code lengths (in bits). -; stored in the *CodeLength arrays. -; A byte with its highest bit set marks the end. - -buildHuffmanTree: - lda #<literalCodeLength - sta buildHuffmanTree_src - lda #>literalCodeLength - sta buildHuffmanTree_src+1 -; Clear bitsCount and bitsPointer_l - ldy #2*TREES_SIZE+1 - lda #0 -buildHuffmanTree_1: - sta bitsCount-1,y - dey - bne buildHuffmanTree_1 - beq buildHuffmanTree_3 ; branch always -; Count number of codes of each length -buildHuffmanTree_2: - tax - inc bitsPointer_l,x - iny - bne buildHuffmanTree_3 - inc buildHuffmanTree_src+1 -buildHuffmanTree_3: - lda (buildHuffmanTree_src),y - bpl buildHuffmanTree_2 -; Calculate a pointer for each length - ldx #0 - lda #<sortedCodes - ldy #>sortedCodes - clc -buildHuffmanTree_4: - sta bitsPointer_l,x - tya - sta bitsPointer_h,x - lda bitsPointer_l+1,x - adc bitsPointer_l,x ; C flag is zero - bcc buildHuffmanTree_5 - iny -buildHuffmanTree_5: - inx - cpx #TREES_SIZE - bcc buildHuffmanTree_4 - lda #>literalCodeLength - sta buildHuffmanTree_src+1 - ldy #0 - bcs buildHuffmanTree_9 ; branch always -; Put codes into their place in sorted table -buildHuffmanTree_6: - beq buildHuffmanTree_7 - tax - lda bitsPointer_l-1,x - sta buildHuffmanTree_ptr - lda bitsPointer_h-1,x - sta buildHuffmanTree_ptr+1 - tya - ldy bitsCount-1,x - inc bitsCount-1,x - sta (buildHuffmanTree_ptr),y - tay -buildHuffmanTree_7: - iny - bne buildHuffmanTree_9 - inc buildHuffmanTree_src+1 - ldx #MAX_BITS-1 -buildHuffmanTree_8: - lda bitsCount,x - sta literalCount,x - dex - bpl buildHuffmanTree_8 -buildHuffmanTree_9: - lda (buildHuffmanTree_src),y - bpl buildHuffmanTree_6 - rts - -; -------------------------------------------------------------------------- -; Decode next code length using temporary codes. - -getNextLength: - stx getNextLength_index - dey - bne getNextLength_1 ; Fetch a temporary code jsr fetchPrimaryCode ; Temporary code 0..15: put this length - ldy #1 - cmp #16 - bcc getNextLength_2 + bpl inflateDynamic_storeLengths ; Temporary code 16: repeat last length 3 + getBits(2) times ; Temporary code 17: put zero length 3 + getBits(3) times ; Temporary code 18: put zero length 11 + getBits(7) times - tay - ldx tempExtraBits-16,y - lda tempBaseValue-16,y + tax jsr getBits - cpy #17 + cpx #GET_3_BITS + bcc inflateDynamic_code16 + beq inflateDynamic_code17 +; sec + adc #7 +inflateDynamic_code17: +; ldy #0 + sty inflateDynamic_lastLength +inflateDynamic_code16: tay - txa ; lda #0 - bcs getNextLength_2 -getNextLength_1: - lda getNextLength_last -getNextLength_2: - sta getNextLength_last - ldx getNextLength_index + lda inflateDynamic_lastLength + iny + iny +inflateDynamic_storeLengths: + iny + plp + ldx inflateDynamic_symbol +inflateDynamic_storeLength: + bcc inflateDynamic_controlSymbolCodeLength + sta literalSymbolCodeLength,x + inx + cpx #1 +inflateDynamic_storeNext: + dey + bne inflateDynamic_storeLength + sta inflateDynamic_lastLength + beq inflateDynamic_decodeLength ; jmp +inflateDynamic_controlSymbolCodeLength: + cpx inflateDynamic_primaryCodes + bcc inflateDynamic_storeControl +; the code lengths we skip here were zero-initialized +; in inflateCompressed_setControlCodeLength + bne inflateDynamic_noStartDistanceTree + ldx #LENGTH_SYMBOLS +inflateDynamic_noStartDistanceTree: + ora #DISTANCE_TREE +inflateDynamic_storeControl: + sta controlSymbolCodeLength,x + inx + cpx inflateDynamic_allCodes + bcc inflateDynamic_storeNext + dey +; ldy #0 + jmp inflateCodes + +; Build Huffman trees basing on code lengths (in bits) +; stored in the *SymbolCodeLength arrays +buildHuffmanTree: +; Clear nBitCode_totalCount, nBitCode_literalCount, nBitCode_controlCount + tya +; lda #0 +buildHuffmanTree_clear: + sta nBitCode_clearFrom,y + iny + bne buildHuffmanTree_clear +; Count number of codes of each length +; ldy #0 +buildHuffmanTree_countCodeLengths: + ldx literalSymbolCodeLength,y + inc nBitCode_literalCount,x + inc nBitCode_totalCount,x + cpy #CONTROL_SYMBOLS + bcs buildHuffmanTree_noControlSymbol + ldx controlSymbolCodeLength,y + inc nBitCode_controlCount,x + inc nBitCode_totalCount,x +buildHuffmanTree_noControlSymbol: + iny + bne buildHuffmanTree_countCodeLengths +; Calculate offsets of symbols sorted by code length +; lda #0 + ldx #$100-3*TREE_SIZE +buildHuffmanTree_calculateOffsets: + sta nBitCode_literalOffset+3*TREE_SIZE-$100,x + clc + adc nBitCode_literalCount+3*TREE_SIZE-$100,x + inx + bne buildHuffmanTree_calculateOffsets +; Put symbols in their place in the sorted array +; ldy #0 +buildHuffmanTree_assignCode: + tya + ldx literalSymbolCodeLength,y + ldy nBitCode_literalOffset,x + inc nBitCode_literalOffset,x + sta codeToLiteralSymbol,y + tay + cpy #CONTROL_SYMBOLS + bcs buildHuffmanTree_noControlSymbol2 + ldx controlSymbolCodeLength,y + ldy nBitCode_controlOffset,x + inc nBitCode_controlOffset,x + sta codeToControlSymbol,y + tay +buildHuffmanTree_noControlSymbol2: + iny + bne buildHuffmanTree_assignCode rts -; -------------------------------------------------------------------------- -; Read a code basing on the primary tree. - +; Read Huffman code using the primary tree fetchPrimaryCode: ldx #PRIMARY_TREE -; jmp fetchCode - -; -------------------------------------------------------------------------- -; Read a code from input basing on the tree specified in X. +; Read a code from input using the tree specified in X. ; Return low byte of this code in A. -; For the literal/length tree, the C flag is set if the code is non-literal. - +; Return C flag reset for literal code, set for length code. fetchCode: - lda #0 -fetchCode_1: +; ldy #0 + tya +fetchCode_nextBit: jsr getBit rol a inx sec - sbc bitsCount-1,x - bcs fetchCode_1 - adc bitsCount-1,x ; C flag is zero - cmp literalCount-1,x - sta fetchCode_ptr - ldy bitsPointer_l-1,x - lda bitsPointer_h-1,x - sta fetchCode_ptr+1 - lda (fetchCode_ptr),y + sbc nBitCode_totalCount,x + bcs fetchCode_nextBit +; clc + adc nBitCode_controlCount,x + bcs fetchCode_control +; clc + adc nBitCode_literalOffset,x + tax + lda codeToLiteralSymbol,x + clc + rts +fetchCode_control: +; sec + adc nBitCode_controlOffset-1,x + tax + lda codeToControlSymbol-1,x + and #$1f ; make distance symbols zero-based + tax + sec rts -; -------------------------------------------------------------------------- -; Decode low byte of a value (length or distance), basing on the code in A. -; The result is the base value for this code plus some bits read from input. - -getValue: - tay - ldx lengthExtraBits-1,y - lda lengthBaseValue_l-1,y - pha - lda lengthBaseValue_h-1,y - tay - pla -; jmp getBits - -; -------------------------------------------------------------------------- -; Read X-bit number from the input and add it to A. -; Increment Y if overflow. -; If X > 8, read only 8 bits. -; On return X holds number of unread bits: X = (X > 8 ? X - 8 : 0); - +; Read A minus 1 bits, but no more than 8 +getAMinus1BitsMax8: + rol getBits_base + tax + cmp #9 + bcs getByte + lda getNPlus1Bits_mask-2,x getBits: - cpx #0 - beq getBits_ret -.if (.cpu & CPU_ISET_65SC02) - stz getBits_tmp - dec getBits_tmp -.else - pha - lda #$ff - sta getBits_tmp - pla -.endif -getBits_1: - jsr getBit - bcc getBits_2 - sbc getBits_tmp ; C flag is set - bcc getBits_2 - iny -getBits_2: - dex - beq getBits_ret - asl getBits_tmp - bmi getBits_1 -getBits_ret: + jsr getBits_loop +getBits_normalizeLoop: + lsr getBits_base + ror a + bcc getBits_normalizeLoop rts -; -------------------------------------------------------------------------- -; Read a single bit from input, return it in the C flag. +; Read 16 bits +getWord: + jsr getByte + tax +; Read 8 bits +getByte: + lda #$80 +getBits_loop: + jsr getBit + ror a + bcc getBits_loop + rts +; Read one bit, return in the C flag getBit: - lsr getBit_hold - bne getBit_ret + lsr getBit_buffer + bne getBit_return pha -.if (.cpu & CPU_ISET_65SC02) - lda (inputPointer) -.else - sty getBit_hold - ldy #0 +; ldy #0 lda (inputPointer),y - ldy getBit_hold -.endif inc inputPointer - bne getBit_1 + bne getBit_samePage inc inputPointer+1 -getBit_1: - ror a ; (C flag was set) - sta getBit_hold +getBit_samePage: + sec + ror a + sta getBit_buffer pla -getBit_ret: +getBit_return: + rts + +; Copy a previously written byte +copyByte: + ldy outputPointer + lda (inflateCodes_sourcePointer),y + ldy #0 +; Write a byte +storeByte: +; ldy #0 + sta (outputPointer),y + inc outputPointer + bne storeByte_return + inc outputPointer+1 + inc inflateCodes_sourcePointer+1 +storeByte_return: rts @@ -575,57 +487,17 @@ getBit_ret: ; .rodata -; -------------------------------------------------------------------------- -; Arrays for the temporary codes. -; Order, in which lengths of the temporary codes are stored. -tempCodeLengthOrder: - .byte 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 +getNPlus1Bits_mask: + .byte GET_1_BIT,GET_2_BITS,GET_3_BITS,GET_4_BITS,GET_5_BITS,GET_6_BITS,GET_7_BITS -; Base values. -tempBaseValue: - .byte 3,3,11 +inflateDynamic_tempSymbols: + .byte GET_2_BITS,GET_3_BITS,GET_7_BITS,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 -; Number of extra bits to read. -tempExtraBits: - .byte 2,3,7 - -; -------------------------------------------------------------------------- -; Arrays for the length and distance codes. - -; Base values. -lengthBaseValue_l: - .byte <3,<4,<5,<6,<7,<8,<9,<10 - .byte <11,<13,<15,<17,<19,<23,<27,<31 - .byte <35,<43,<51,<59,<67,<83,<99,<115 - .byte <131,<163,<195,<227,<258 -distanceBaseValue_l: - .byte <1,<2,<3,<4,<5,<7,<9,<13 - .byte <17,<25,<33,<49,<65,<97,<129,<193 - .byte <257,<385,<513,<769,<1025,<1537,<2049,<3073 - .byte <4097,<6145,<8193,<12289,<16385,<24577 -lengthBaseValue_h: - .byte >3,>4,>5,>6,>7,>8,>9,>10 - .byte >11,>13,>15,>17,>19,>23,>27,>31 - .byte >35,>43,>51,>59,>67,>83,>99,>115 - .byte >131,>163,>195,>227,>258 -distanceBaseValue_h: - .byte >1,>2,>3,>4,>5,>7,>9,>13 - .byte >17,>25,>33,>49,>65,>97,>129,>193 - .byte >257,>385,>513,>769,>1025,>1537,>2049,>3073 - .byte >4097,>6145,>8193,>12289,>16385,>24577 - -; Number of extra bits to read. -lengthExtraBits: - .byte 0,0,0,0,0,0,0,0 - .byte 1,1,1,1,2,2,2,2 - .byte 3,3,3,3,4,4,4,4 - .byte 5,5,5,5,0 -distanceExtraBits: - .byte 0,0,0,0,1,1,2,2 - .byte 3,3,4,4,5,5,6,6 - .byte 7,7,8,8,9,9,10,10 - .byte 11,11,12,12,13,13 +inflateDynamic_headerBits: + .byte GET_4_BITS,GET_5_BITS,GET_5_BITS +inflateDynamic_headerBase: + .byte 3,LENGTH_SYMBOLS,0 ; -------------------------------------------------------------------------- @@ -635,46 +507,28 @@ distanceExtraBits: .bss -; Number of literal codes of each length in the primary tree -; (MAX_BITS bytes, overlap with literalCodeLength). -literalCount: +; Data for building trees. -; -------------------------------------------------------------------------- -; Data for building the primary tree. - -; Lengths of literal codes. -literalCodeLength: +literalSymbolCodeLength: .res 256 -; Length of the end code. -endCodeLength: - .res 1 -; Lengths of length codes. -lengthCodeLength: - .res 29 +controlSymbolCodeLength: + .res CONTROL_SYMBOLS -; -------------------------------------------------------------------------- -; Data for building the distance tree. +; Huffman trees. -; Lengths of distance codes. -distanceCodeLength: - .res 30 -; For two unused codes in the fixed trees and an 'end' mark. - .res 3 +nBitCode_clearFrom: +nBitCode_totalCount: + .res 2*TREE_SIZE +nBitCode_literalCount: + .res TREE_SIZE +nBitCode_controlCount: + .res 2*TREE_SIZE +nBitCode_literalOffset: + .res TREE_SIZE +nBitCode_controlOffset: + .res 2*TREE_SIZE -; -------------------------------------------------------------------------- -; The Huffman trees. - -; Number of codes of each length. -bitsCount: - .res TREES_SIZE -; Pointers to sorted codes of each length. -bitsPointer_l: - .res TREES_SIZE+1 -bitsPointer_h: - .res TREES_SIZE - -; Sorted codes. -sortedCodes: - .res 256+1+29+30+2 - -.endif +codeToLiteralSymbol: + .res 256 +codeToControlSymbol: + .res CONTROL_SYMBOLS From 7e8bb7b700572a50ed4f1e87ebeea4fd35177459 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 12 Feb 2017 14:54:57 -0500 Subject: [PATCH 0220/2161] Fixed ca65's BRK instruction encoding for the 65816. BRK is two bytes on all 6502 variants; but, the 65816's maker declared officially that assemblers should support an optional operand. --- 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 5e7904992..53d3573a6 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -650,7 +650,7 @@ static const struct { { "BNE", 0x0020000, 0xd0, 0, PutPCRel8 }, { "BPL", 0x0020000, 0x10, 0, PutPCRel8 }, { "BRA", 0x0020000, 0x80, 0, PutPCRel8 }, - { "BRK", 0x0000001, 0x00, 0, PutAll }, + { "BRK", 0x0000005, 0x00, 0, PutAll }, { "BRL", 0x0040000, 0x82, 0, PutPCRel16 }, { "BVC", 0x0020000, 0x50, 0, PutPCRel8 }, { "BVS", 0x0020000, 0x70, 0, PutPCRel8 }, From 1f12a06f7cc2ae79a800fe3faed727513364091b Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Mon, 13 Feb 2017 19:41:05 +0100 Subject: [PATCH 0221/2161] Disallow global variable declarations with an initializer. E.g. extern int i = 42; --- src/cc65/compile.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 9f1ab29f5..f01ddf6c5 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -144,17 +144,14 @@ static void Parse (void) ** ** - 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. + ** or the storage class is explicitly specified as static. ** ** This means that "extern int i;" will not get storage allocated. */ if ((Decl.StorageClass & SC_FUNC) != SC_FUNC && (Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF && ((Spec.Flags & DS_DEF_STORAGE) != 0 || - (Decl.StorageClass & (SC_EXTERN|SC_STATIC)) == SC_STATIC || - ((Decl.StorageClass & SC_EXTERN) != 0 && - CurTok.Tok == TOK_ASSIGN))) { + (Decl.StorageClass & (SC_EXTERN|SC_STATIC)) == SC_STATIC)) { /* We will allocate storage */ Decl.StorageClass |= SC_STORAGE | SC_DEF; From 730d01a25f3440bd5bdca3a3cf8068287ff52f6a Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Mon, 13 Feb 2017 21:04:45 +0100 Subject: [PATCH 0222/2161] Global uninitialized variable is only a tentative definition. Closes #204 --- src/cc65/compile.c | 55 +++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index f01ddf6c5..85a2e9939 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -154,7 +154,7 @@ static void Parse (void) (Decl.StorageClass & (SC_EXTERN|SC_STATIC)) == SC_STATIC)) { /* We will allocate storage */ - Decl.StorageClass |= SC_STORAGE | SC_DEF; + Decl.StorageClass |= SC_STORAGE; } /* If this is a function declarator that is not followed by a comma @@ -187,6 +187,9 @@ static void Parse (void) /* Allow initialization */ if (CurTok.Tok == TOK_ASSIGN) { + /* This is a definition */ + Entry->Flags |= SC_DEF; + /* We cannot initialize types of unknown size, or ** void types in ISO modes. */ @@ -234,18 +237,14 @@ static void Parse (void) Entry->Flags &= ~(SC_STORAGE | SC_DEF); } - /* Allocate storage if it is still needed */ - if (Entry->Flags & SC_STORAGE) { - - /* Switch to the BSS segment */ - g_usebss (); - - /* Define a label */ - g_defgloblabel (Entry->Name); - - /* Allocate space for uninitialized variable */ - g_res (Size); - } + /* A global (including static) uninitialized variable + ** is only a tentative definition. For example, this is valid: + ** int i; + ** int i; + ** static int j; + ** static int j = 42; + ** Code for these will be generated in FinishCompile. + */ } } @@ -300,7 +299,7 @@ void Compile (const char* FileName) struct tm* TM; /* Since strftime is locale dependent, we need the abbreviated month names - ** in english. + ** in English. */ static const char MonthNames[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", @@ -397,20 +396,26 @@ void Compile (const char* FileName) void FinishCompile (void) /* Emit literals, externals, debug info, do cleanup and optimizations */ { - SymTable* SymTab; - SymEntry* Func; + SymEntry* Entry; - /* Walk over all functions, doing cleanup, optimizations ... */ - SymTab = GetGlobalSymTab (); - Func = SymTab->SymHead; - while (Func) { - if (SymIsOutputFunc (Func)) { + /* Walk over all global symbols: + ** - for functions do cleanup, optimizations ... + ** - generate code for uninitialized global variables + */ + for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) { + if (SymIsOutputFunc (Entry)) { /* Function which is defined and referenced or extern */ - MoveLiteralPool (Func->V.F.LitPool); - CS_MergeLabels (Func->V.F.Seg->Code); - RunOpt (Func->V.F.Seg->Code); + MoveLiteralPool (Entry->V.F.LitPool); + CS_MergeLabels (Entry->V.F.Seg->Code); + RunOpt (Entry->V.F.Seg->Code); + } else if ((Entry->Flags & (SC_STORAGE | SC_DEF | SC_STATIC)) == (SC_STORAGE | SC_STATIC)) { + /* Tentative definition of uninitialized global variable */ + g_usebss (); + g_defgloblabel (Entry->Name); + g_res (SizeOf (Entry->Type)); + /* Mark as defined, so that it will be exported not imported */ + Entry->Flags |= SC_DEF; } - Func = Func->NextSym; } /* Output the literal pool */ From 31f19fbc6579a57186cc44e06e8494a34b9de057 Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Mon, 13 Feb 2017 21:10:21 +0100 Subject: [PATCH 0223/2161] Issue an error for duplicate global variables. Previously it was an assembler error. --- src/cc65/compile.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 85a2e9939..9cdeaf7e5 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -188,6 +188,10 @@ static void Parse (void) if (CurTok.Tok == TOK_ASSIGN) { /* This is a definition */ + if (SymIsDef (Entry)) { + Error ("Global variable `%s' has already been defined", + Entry->Name); + } Entry->Flags |= SC_DEF; /* We cannot initialize types of unknown size, or From ccdbb2b0e64f04004b90059c00e486411153d985 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Mon, 13 Feb 2017 22:43:26 +0100 Subject: [PATCH 0224/2161] Add testcode/lib/mouse-test.c. Rename samples/mousetest.c to mousedemo.c. mouse-test.c can be use to test all available mouse drivers for a given target. Currently supported targets are Atari, C64, and C128. To avoid confusion, rename samples/mousetest.c to mousedemo.c. --- samples/Makefile | 12 +- samples/README | 4 +- samples/{mousetest.c => mousedemo.c} | 4 +- testcode/lib/mouse-test.c | 431 +++++++++++++++++++++++++++ 4 files changed, 441 insertions(+), 10 deletions(-) rename samples/{mousetest.c => mousedemo.c} (98%) create mode 100644 testcode/lib/mouse-test.c diff --git a/samples/Makefile b/samples/Makefile index abd304b14..edfeca689 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -66,8 +66,8 @@ LDFLAGS_mandelbrot_apple2enh = --start-addr 0x4000 LDFLAGS_tgidemo_apple2 = --start-addr 0x4000 LDFLAGS_tgidemo_apple2enh = --start-addr 0x4000 -# The Apple ][ needs the start address adjusted for the mousetest -LDFLAGS_mousetest_apple2 = --start-addr 0x4000 +# The Apple ][ needs the start address adjusted for the mousedemo +LDFLAGS_mousedemo_apple2 = --start-addr 0x4000 # The Apple machines need the end address adjusted for large programs LDFLAGS_gunzip65_apple2 = -D __HIMEM__=0xBF00 @@ -111,7 +111,7 @@ EXELIST_c64 = \ gunzip65 \ hello \ mandelbrot \ - mousetest \ + mousedemo \ multdemo \ nachtm \ ovrldemo \ @@ -126,7 +126,7 @@ EXELIST_apple2 = \ gunzip65 \ hello \ mandelbrot \ - mousetest \ + mousedemo \ multdemo \ ovrldemo \ sieve \ @@ -139,7 +139,7 @@ EXELIST_atari = \ gunzip65 \ hello \ mandelbrot \ - mousetest \ + mousedemo \ multdemo \ ovrldemo \ sieve \ @@ -147,7 +147,7 @@ EXELIST_atari = \ EXELIST_atarixl = $(EXELIST_atari) -EXELIST_atari2600 = \ +EXELIST_atari2600 = \ atari2600hello # -------------------------------------------------------------------------- diff --git a/samples/README b/samples/README index a576c4032..88a6021c8 100644 --- a/samples/README +++ b/samples/README @@ -69,8 +69,8 @@ Platforms: Runs on all platforms that have TGI support: Apple ][, C64, C128, Oric Atmos, Geos and Lynx. ----------------------------------------------------------------------------- -Name: mousetest -Description: Tests and shows how to use the mouse. +Name: mousedemo +Description: Shows how to use the mouse. Platforms: All systems with mouse and conio support: C64, C128, CBM510, Atari, Apple ][ diff --git a/samples/mousetest.c b/samples/mousedemo.c similarity index 98% rename from samples/mousetest.c rename to samples/mousedemo.c index 3910d5a0a..d1b48e9ee 100644 --- a/samples/mousetest.c +++ b/samples/mousedemo.c @@ -1,6 +1,6 @@ /* -** Test/demo program for mouse usage. -** Will work for the C64/C128/CBM510/Atari/Apple2. +** Demo program for mouse usage. +** Supports the C64/C128/CBM510/Atari/Apple2. ** ** 2001-09-13, Ullrich von Bassewitz ** 2013-09-05, Greg King diff --git a/testcode/lib/mouse-test.c b/testcode/lib/mouse-test.c new file mode 100644 index 000000000..2e316c4c6 --- /dev/null +++ b/testcode/lib/mouse-test.c @@ -0,0 +1,431 @@ +/* +** Test program for mouse drivers. +** Supportsthe C64/C128/CBM510/Atari/Apple2. +** +** 2001-09-13, Ullrich von Bassewitz +** 2013-09-05, Greg King +** +** Compile with "-DSTATIC_MOUSE" to statically link all available drivers. +** Compile with "-DMOUSE_DRIVER=<driver_sym>" to statically link the given driver. +** E.g., -DMOUSE_DRIVER=atrsts_mou to just link with the Atari ST mouse driver. +*/ + + + +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <mouse.h> +#include <pen.h> +#include <conio.h> +#include <ctype.h> +#include <dbg.h> +#include <cc65.h> + +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#define min(a,b) (((a) < (b)) ? (a) : (b)) + +extern int getsp(void); + +#define NO_DEBUG +#define NO_JAIL + +#ifdef __ATARI__ +extern const struct mouse_callbacks mouse_pm_callbacks; +extern const struct mouse_callbacks mouse_txt_callbacks; +//#define MOUSE_CALLBACK mouse_def_callbacks +#define MOUSE_CALLBACK mouse_pm_callbacks +//#define MOUSE_CALLBACK mouse_txt_callbacks +#else +#define MOUSE_CALLBACK mouse_def_callbacks +#endif + +#if defined(MOUSE_DRIVER) || defined(STATIC_MOUSE) + +/* A statically linked driver was named on the compiler's command line. +** Make sure that it is used instead of a dynamic one. +*/ +# undef DYN_DRV +# define DYN_DRV 0 +#else + +/* Use a dynamically loaded driver, by default. */ +# ifndef DYN_DRV +# define DYN_DRV 1 +# endif +#endif + + + +#ifdef __CBM__ + +/* Set dark-on-light colors. */ +const unsigned char mouse_def_pointercolor = COLOR_BLACK; + +#endif + + + +static void __fastcall__ CheckError (const char* S, unsigned char Error) +{ + if (Error != MOUSE_ERR_OK) { + cprintf ("\n%s: %s(%u)\r\n", S, mouse_geterrormsg (Error), Error); + + /* Wait for a key-press, so that some platforms can show the error + ** message before they remove the current screen. + */ + if (doesclrscrafterexit ()) { + cgetc (); + } + exit (EXIT_FAILURE); + } +} + + + +#if DYN_DRV + +/* Points to the dynamic driver's name. */ +static const char *mouse_name; + + +static void DoWarning (void) +/* Warn the user that a driver is needed for this program. */ +{ + cprintf ("Warning: This program needs\r\n" + "the driver with the name\r\n" + " %s\r\n" + "on a disk! Press 'y' if you have it;\r\n" + "or, any other key to exit.\r\n", mouse_stddrv); + if (tolower (cgetc ()) != 'y') { + exit (EXIT_SUCCESS); + } + cprintf ("OK. Please wait patiently...\r\n"); +} + +#else + +unsigned char *mouse_drv_use; +#endif + + +#ifdef __ATARI__ +#ifdef __ATARIXL__ +#define MSENAME_EXT "X" +#define MSESTAT_0 atrxjoy_mou +#define MSESTAT_1 atrxst_mou +#define MSESTAT_2 atrxami_mou +#define MSESTAT_3 atrxtrk_mou +#define MSESTAT_4 atrxtt_mou +#else +#define MSENAME_EXT "" +#define MSESTAT_0 atrjoy_mou +#define MSESTAT_1 atrst_mou +#define MSESTAT_2 atrami_mou +#define MSESTAT_3 atrtrk_mou +#define MSESTAT_4 atrtt_mou +#endif +#define MSENAME_0 "ATR" MSENAME_EXT "JOY.MOU" +#define MSENAME_1 "ATR" MSENAME_EXT "ST.MOU" +#define MSENAME_2 "ATR" MSENAME_EXT "AMI.MOU" +#define MSENAME_3 "ATR" MSENAME_EXT "TRK.MOU" +#define MSENAME_4 "ATR" MSENAME_EXT "TT.MOU" +#elif defined(__C64__) || defined(__C128__) +#ifdef __C64__ +#define MSENAME_EXT "c64-" +#define MSESTAT_0 c64_joy_mou +#define MSESTAT_1 c64_1351_mou +#define MSESTAT_2 c64_inkwell_mou +#define MSESTAT_3 c64_pot_mou +#else +#define MSENAME_EXT "c128-" +#define MSESTAT_0 c128_joy_mou +#define MSESTAT_1 c128_1351_mou +#define MSESTAT_2 c128_inkwell_mou +#define MSESTAT_3 c128_pot_mou +#endif +#define MSENAME_0 MSENAME_EXT "joy.mou" +#define MSENAME_1 MSENAME_EXT "1351.mou" +#define MSENAME_2 MSENAME_EXT "inkwell.mou" +#define MSENAME_3 MSENAME_EXT "pot.mou" +#endif + + +static void __fastcall__ ShowState (unsigned char Jailed, unsigned char Invisible) +/* Display jail and cursor states. */ +{ + cclearxy (0, 7, 32); + gotoxy (0, 7); + cprintf ("Pointer is %svisible%s.", Invisible? "in" : "", Jailed? " and jailed" : ""); +} + +#ifdef __ATARIXL__ +extern char _HIDDEN_RAM_SIZE__, _HIDDEN_RAM_LAST__, _HIDDEN_RAM_START__; +#endif + +#if DYN_DRV +int main (int argc, char *argv[]) +#else +int main (void) +#endif +{ + struct mouse_info info; + struct mouse_box full_box, small_box; + unsigned char width, height; + char C; + bool Invisible = true, Done = false, Jailed = false; + +#ifdef __ATARIXL__ + cprintf ("adding heap: $%04X bytes at $%04X\r\n", + &_HIDDEN_RAM_SIZE__ - (&_HIDDEN_RAM_LAST__ - &_HIDDEN_RAM_START__), + &_HIDDEN_RAM_LAST__); + + _heapadd (&_HIDDEN_RAM_LAST__, (size_t)(&_HIDDEN_RAM_SIZE__ - (&_HIDDEN_RAM_LAST__ - &_HIDDEN_RAM_START__))); + cgetc (); +#endif + +#ifndef NO_DEBUG + /* Initialize the debugger */ + DbgInit (0); +#endif + + /* Set dark-on-light colors. Clear the screen. */ +#ifdef __CBM__ + (void) bordercolor (COLOR_GRAY2); + (void) bgcolor (COLOR_WHITE); + (void) textcolor (COLOR_GRAY1); +#else + (void) bordercolor (COLOR_BLUE); + (void) bgcolor (COLOR_WHITE); + (void) textcolor (COLOR_BLACK); +#endif + cursor (0); + clrscr (); + + /* If a lightpen driver is installed, then it can get a calibration value + ** from this file (if it exists). Or, the user can adjust the pen; and, + ** the value will be put into this file, for the next time. + ** (Other drivers will ignore this.) + */ +#if defined(__C64__) || defined(__C128__) || defined(__CBM510__) + pen_adjust ("pen.dat"); +#endif + +#if DYN_DRV + /* If a dynamically loadable driver is named on the command line, + ** then use that driver instead of the standard one. + */ + if (argc > 1) { + mouse_name = argv[1]; + } else { +#if defined(__ATARI__) || defined(__C64__) || defined(__C128__) + char selection, flag = 0; + cprintf ("Select mouse driver:\r\n" + " 0 - Joystick\r\n" +#ifdef __ATARI__ + " 1 - ST Mouse\r\n" + " 2 - Amiga Mouse\r\n" + " 3 - Atari Trakball\r\n" + " 4 - Atari TouchPad\r\n" +#else + " 1 - 1351 Mouse\r\n" + " 2 - Inkwell Mouse\r\n" + " 3 - Paddle\r\n" +#endif + "Enter selection: "); + while (1) { + switch (selection = cgetc ()) { + case '0': mouse_name = MSENAME_0; flag = 1; break; + case '1': mouse_name = MSENAME_1; flag = 1; break; + case '2': mouse_name = MSENAME_2; flag = 1; break; + case '3': mouse_name = MSENAME_3; flag = 1; break; +#ifdef __ATARI__ + case '4': mouse_name = MSENAME_4; flag = 1; break; +#endif + } + if (flag) break; + } + cprintf ("%c\r\nOK, loading \"%s\",\r\nplease wait patiently...\r\n", selection, mouse_name); +#else + /* Output a warning about the standard driver that is needed. */ + DoWarning (); + mouse_name = mouse_stddrv; +#endif + } + + /* Load and install the driver. */ + CheckError ("mouse_load_driver", + mouse_load_driver (&MOUSE_CALLBACK, mouse_name)); +#else /* not DYN_DRV */ +#if !defined(MOUSE_DRIVER) && (defined(__ATARI__) || defined(__C64__) || defined(__C128__)) + { + char selection, flag = 0; + cprintf ("Select mouse driver:\r\n" + " 0 - Joystick\r\n" +#ifdef __ATARI__ + " 1 - ST Mouse\r\n" + " 2 - Amiga Mouse\r\n" + " 3 - Atari Trakball\r\n" + " 4 - Atari TouchPad\r\n" +#else + " 1 - 1351 Mouse\r\n" + " 2 - Inkwell Mouse\r\n" + " 3 - Paddle\r\n" +#endif + "Enter selection: "); + while (1) { + switch (selection = cgetc ()) { + case '0': mouse_drv_use = MSESTAT_0; flag = 1; break; + case '1': mouse_drv_use = MSESTAT_1; flag = 1; break; + case '2': mouse_drv_use = MSESTAT_2; flag = 1; break; + case '3': mouse_drv_use = MSESTAT_3; flag = 1; break; +#ifdef __ATARI__ + case '4': mouse_drv_use = MSESTAT_4; flag = 1; break; +#endif + } + if (flag) break; + } + } +#else + mouse_drv_use = mouse_static_stddrv; +#endif + + /* Install the driver. */ + CheckError ("mouse_install", + mouse_install (&MOUSE_CALLBACK, +# ifdef MOUSE_DRIVER + MOUSE_DRIVER +# else +#if defined(__ATARI__) || defined(__C64__) || defined(__C128__) + mouse_drv_use +#else + mouse_static_stddrv +#endif +# endif + )); +#endif + +#ifndef NO_JAIL + /* Get the initial bounding box. */ + mouse_getbox (&full_box); +#endif + + screensize (&width, &height); + +top: + clrscr (); + + /* Print a help line */ + cputs (" d)ebug h)ide q)uit s)how j)ail"); + + gotoxy (1, 20); + cprintf ("SP: $%04X", getsp()); + + /* Put a cross at the center of the screen. */ + gotoxy (width / 2 - 3, height / 2 - 1); +#if defined(__CBM__) + cprintf ("%3u,%3u\r\n%*s\xDB", width / 2 * 8 + 4, height / 2 * 8 + 4, + width / 2, ""); +#else + cprintf ("%3u,%3u\r\n%*s+", width / 2 * 8 + 4, height / 2 * 8 + 4, + width / 2, ""); +#endif + + /* Test loop */ + ShowState (Jailed, Invisible); + do { + /* Get the current co-ordinates and button states; and, print them. */ + mouse_info (&info); + gotoxy (0, 2); + cprintf (" X = %3d\r\n", info.pos.x); + cprintf (" Y = %3d\r\n", info.pos.y); + cprintf (" B1 = %c\r\n", (info.buttons & MOUSE_BTN_LEFT) ? +#ifdef __CBM__ + 0x5F +#else + 'v' +#endif + : '^'); + cprintf (" B2 = %c", (info.buttons & MOUSE_BTN_RIGHT) ? +#ifdef __CBM__ + 0x5F +#else + 'v' +#endif + : '^'); + + /* Handle user input */ + if (kbhit ()) { + cclearxy (1, 9, 23); + switch (tolower (C = cgetc ())) { +#ifndef NO_DEBUG + case 'd': + BREAK(); + + /* The debugger might have changed the colors. + ** Restore them. + */ +#ifdef __CBM__ + (void) bordercolor (COLOR_GRAY2); + (void) bgcolor (COLOR_WHITE); + (void) textcolor (COLOR_GRAY1); +#else + (void) bordercolor (COLOR_BLUE); + (void) bgcolor (COLOR_WHITE); + (void) textcolor (COLOR_BLACK); +#endif + + /* The debugger changed the screen; restore it. */ + goto top; +#endif + case 'h': + mouse_hide (); + ShowState (Jailed, ++Invisible); + break; + +#ifndef NO_JAIL + case 'j': + if (Jailed) { + mouse_setbox (&full_box); + Jailed = false; + } else { + small_box.minx = max (info.pos.x - 10, full_box.minx); + small_box.miny = max (info.pos.y - 10, full_box.miny); + small_box.maxx = min (info.pos.x + 10, full_box.maxx); + small_box.maxy = min (info.pos.y + 10, full_box.maxy); + mouse_setbox (&small_box); + Jailed = true; + } + ShowState (Jailed, Invisible); + break; +#endif + case 's': + mouse_show (); + if (Invisible) { + ShowState (Jailed, --Invisible); + } + break; + + case 'q': + Done = true; + break; + + default: + gotoxy (1, 9); + cprintf ("Spurious character: $%02X", C); + } + } + } while (!Done); + +#if DYN_DRV + /* Uninstall and unload the driver. */ + CheckError ("mouse_unload", mouse_unload ()); +#else + /* Uninstall the static driver. */ + CheckError ("mouse_uninstall", mouse_uninstall ()); +#endif + + /* Say goodbye */ + cputsxy (0, height / 2 + 3, "Goodbye!"); + return EXIT_SUCCESS; +} From c0803ed53ac5113b8065e07a0c91eebf507975f5 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 14 Feb 2017 23:52:44 +0100 Subject: [PATCH 0225/2161] fix indentation --- libsrc/creativision/cputc.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/creativision/cputc.s b/libsrc/creativision/cputc.s index 208009ebd..ff60494b9 100644 --- a/libsrc/creativision/cputc.s +++ b/libsrc/creativision/cputc.s @@ -50,7 +50,7 @@ advance: iny cpy #SCREEN_COLS bne L3 - inc CURSOR_Y ; new line + inc CURSOR_Y ; new line ldy #0 ; + cr L3: sty CURSOR_X jmp plot From b858b0d6230d263dedec8e741b01cd8a5602cb59 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 15 Feb 2017 15:37:06 +0100 Subject: [PATCH 0226/2161] Add joystick driver to documentation. --- doc/creativision.sgml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/creativision.sgml b/doc/creativision.sgml index 5b69da75a..64623b3b2 100644 --- a/doc/creativision.sgml +++ b/doc/creativision.sgml @@ -66,7 +66,6 @@ Programs containing Creativision specific code may use the <tt/creativision.h/ h <itemize> <item>bios_playsound -<item>joystate <item>psg_delay <item>psg_outb <item>psg_silence @@ -109,8 +108,12 @@ No extended memory drivers are currently available for the Creativision. <sect1>Joystick drivers<p> -No joystick drivers are currently available for the Creativision but <tt/joystate()/. +<descrip> + <tag><tt/creativision-stdjoy.joy (creativisionstd_joy)/</tag> + A joystick driver for the standard joystick is available. + +</descrip><p> <sect1>Mouse drivers<p> From e6530d68dd51c9c310b7a9aa346bb19d126b4910 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 15 Feb 2017 15:45:49 +0100 Subject: [PATCH 0227/2161] Fix joystick driver. Add interruptor support. Note that the joystick driver doesn't support combined movements (like left/up or right/down). This should be fixed. --- asminc/creativision.inc | 4 + include/creativision.h | 65 +++++++++------- libsrc/creativision/crt0.s | 8 +- libsrc/creativision/irq.s | 40 ++++++++++ libsrc/creativision/joy/creativision-stdjoy.s | 76 ++++++++++--------- testcode/lib/joy-test.c | 12 +-- 6 files changed, 132 insertions(+), 73 deletions(-) create mode 100644 libsrc/creativision/irq.s diff --git a/asminc/creativision.inc b/asminc/creativision.inc index bd30bc462..59b26101b 100644 --- a/asminc/creativision.inc +++ b/asminc/creativision.inc @@ -36,3 +36,7 @@ ZP_JOY1_DIR = $13 ZP_JOY0_BUTTONS = $16 ZP_JOY1_BUTTONS = $17 +;** BIOS +BIOS_IRQ1_ADDR = $FF3F +BIOS_IRQ2_ADDR = $FF52 +BIOS_NMI_RESET_ADDR = $F808 diff --git a/include/creativision.h b/include/creativision.h index adaa1caab..5cc99b7af 100644 --- a/include/creativision.h +++ b/include/creativision.h @@ -1,9 +1,38 @@ -/* CreatiVision Header */ +/*****************************************************************************/ +/* */ +/* creativision.h */ +/* */ +/* Creativision system specific definitions */ +/* */ +/* */ +/* */ +/* (C) 2013 cvemu */ +/* (C) 2017 Christian Groessler <chris@groessler.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 _CVISION_H - #define _CVISION_H +/* Character codes */ #define CH_VLINE 33 #define CH_HLINE 34 #define CH_ULCORNER 35 @@ -11,12 +40,13 @@ #define CH_LLCORNER 37 #define CH_LRCORNER 38 +/* no support for dynamically loadable drivers */ #define DYN_DRV 0 /* Colours - from TMS9918 */ #define C_TRANSPARENT 0 #define C_BLACK 1 -#define C_MED_GREEN 2 +#define C_MED_GREEN 2 #define C_LIGHT_GREEN 3 #define C_DARK_BLUE 4 #define C_LIGHT_BLUE 5 @@ -31,29 +61,10 @@ #define C_GREY 14 #define C_WHITE 15 -/* Joystick states */ -#define JOY_UP 5 -#define JOY_DOWN 1 -#define JOY_LEFT 7 -#define JOY_RIGHT 3 -#define JOY_LEFT_UP 6 -#define JOY_LEFT_DOWN 8 -#define JOY_RIGHT_UP 4 -#define JOY_RIGHT_DOWN 2 -#define JOY_LBUTTON 1 -#define JOY_RBUTTON 2 - -/* Joystick values */ -#define JOY_LEFT_DIR 1 -#define JOY_RIGHT_DIR 2 -#define JOY_LEFT_BUTTONS 3 -#define JOY_RIGHT_BUTTONS 4 - /* Protos */ -void __fastcall__ psg_outb( unsigned char b ); -void __fastcall__ psg_delay( unsigned char b ); -void psg_silence( void ); -void __fastcall__ bios_playsound( void *a, unsigned char b); -unsigned char __fastcall__ joystate( unsigned char which ); +void __fastcall__ psg_outb(unsigned char b); +void __fastcall__ psg_delay(unsigned char b); +void psg_silence(void); +void __fastcall__ bios_playsound(void *a, unsigned char b); -#endif +#endif /* #ifndef _CVISION_H */ diff --git a/libsrc/creativision/crt0.s b/libsrc/creativision/crt0.s index ccae38e81..6faec38eb 100644 --- a/libsrc/creativision/crt0.s +++ b/libsrc/creativision/crt0.s @@ -4,11 +4,13 @@ .export _exit .export __STARTUP__ : absolute = 1 ; Mark as startup + .export irq2 .import zerobss, copydata .import initlib, donelib, callmain .import __VECTORS_LOAD__, __VECTORS_RUN__, __VECTORS_SIZE__ .import __ZP_LAST__, __STACKSIZE__, __RAM_START__ + .include "creativision.inc" .include "zeropage.inc" ; ------------------------------------------------------------------------ @@ -61,8 +63,8 @@ loop: jmp loop .segment "VECTORS" -irq1: jmp $FF3F -irq2: jmp $FF52 +irq1: jmp BIOS_IRQ1_ADDR +irq2: jmp BIOS_IRQ2_ADDR ; ------------------------------------------------------------------------ ; Define CART setup values for BIOS. @@ -92,7 +94,7 @@ irq2: jmp $FF52 ; BIOS Vector after NMI or RESET ; Keeping with retail cartridges, we jump back to BIOS ROM and have it ; setup zeropage etc, and show the Creativision logo and copyright. - .addr $F808 + .addr BIOS_NMI_RESET_ADDR ; BIOS Short Interrupt Handler ; Vectored from BIOS ROM:FE2C. This should contain a pointer to the user's diff --git a/libsrc/creativision/irq.s b/libsrc/creativision/irq.s new file mode 100644 index 000000000..f154c9199 --- /dev/null +++ b/libsrc/creativision/irq.s @@ -0,0 +1,40 @@ +; +; IRQ handling (CreatiVision version) +; + + .export initirq, doneirq + .import callirq, irq2 + + .include "creativision.inc" + +; ------------------------------------------------------------------------ + +.segment "ONCE" + +initirq: + lda #<IRQStub + ldx #>IRQStub + jmp setvec + +; ------------------------------------------------------------------------ + +.code + +doneirq: + lda #<BIOS_IRQ2_ADDR + ldx #>BIOS_IRQ2_ADDR +setvec: sei + sta irq2+1 + stx irq2+2 + cli + rts + +; ------------------------------------------------------------------------ + +.segment "CODE" + +IRQStub: + cld ; Just to be sure + jsr callirq ; Call the functions + jmp BIOS_IRQ2_ADDR ; Jump to the BIOS IRQ vector + diff --git a/libsrc/creativision/joy/creativision-stdjoy.s b/libsrc/creativision/joy/creativision-stdjoy.s index f24a8045b..37b927d08 100644 --- a/libsrc/creativision/joy/creativision-stdjoy.s +++ b/libsrc/creativision/joy/creativision-stdjoy.s @@ -49,7 +49,7 @@ ; ------------------------------------------------------------------------ ; Constants -JOY_COUNT = 2 ; Number of joysticks we support +JOY_COUNT = 2 ; Number of joysticks we support ; ------------------------------------------------------------------------ ; Code @@ -66,7 +66,7 @@ JOY_COUNT = 2 ; Number of joysticks we support INSTALL: lda #JOY_ERR_OK ldx #0 -; rts ; Fall through +; rts ; Fall through ; ------------------------------------------------------------------------ ; UNINSTALL routine. Is called before the driver is removed from memory. @@ -91,14 +91,14 @@ COUNT: ; READJOY: - and #1 ; fix joystick number - bne READJOY_1 ; read right joystick + and #1 ; fix joystick number + bne READJOY_1 ; read right joystick ; Read left joystick ldx ZP_JOY0_DIR lda ZP_JOY0_BUTTONS - jmp convert ; convert joystick state to sane cc65 values + jmp convert ; convert joystick state to sane cc65 values ; Read right joystick @@ -108,8 +108,8 @@ READJOY_1: lda ZP_JOY1_BUTTONS lsr a lsr a - ;jmp convert ; convert joystick state to sane cc65 values - ; fall thru... + ;jmp convert ; convert joystick state to sane cc65 values + ; fall thru... ; ------------------------------------------------------------------------ ; convert: make runtime lib compatible values @@ -119,7 +119,7 @@ READJOY_1: convert: ldy #0 - sty retval ; initialize return value + sty retval ; initialize return value ; ------ ; buttons: @@ -127,7 +127,7 @@ convert: ; values were shifted to the right to be identical). ; Why are there two bits indicating a pressed trigger? ; According to the "Second book of programs for the Dick Smith Wizard" - ; (pg. 88ff), the left hand fire button gives the value of + ; (pg. 88ff), the left hand fire button gives the value of ; %00010001 and the right hand button gives %00100010 ; Why two bits? Am I missing something? Can there be cases that just ; one of those bits is set? @@ -137,7 +137,7 @@ convert: and #%00010001 beq cnv_1 - inc retval ; left button pressed + inc retval ; left button pressed cnv_1: tya and #%00100010 @@ -145,45 +145,47 @@ cnv_1: tya lda #$02 ora retval - sta retval ; right button pressed + sta retval ; right button pressed ; ------ ; direction: cnv_2: txa - ; tested with https://sourceforge.net/projects/creativisionemulator - ; $49 - %01001001 - up - ; $41 - %01000001 - down - ; $4D - %01001101 - left - ; $45 - %01000101 - right - ; - ; are these correct? "Second book of programs for the Dick Smith Wizard" pg. 85 says something different - ; ignored for now... - ; $85 - %10000101 - up + right - ; $8D - %10001101 - down + left - ; $89 - %10001001 - up + left - ; $85 - %10000101 - down + right (emulator bug?) + ; tested with https://sourceforge.net/projects/creativisionemulator + ; $49 - %01001001 - up + ; $41 - %01000001 - down + ; $4D - %01001101 - left + ; $45 - %01000101 - right + ; + ; are these correct? "Second book of programs for the Dick Smith Wizard" pg. 85 says something different + ; ignored for now... + ; $85 - %10000101 - up + right + ; $8D - %10001101 - down + left + ; $89 - %10001001 - up + left + ; $85 - %10000101 - down + right (emulator bug?) - bit testbit ; bit #0 set? - beq done ; no, no direction + bit testbit ; bit #0 set? + beq done ; no, no direction - and #%00001100 ; mask out other bits - tax - lda #%00000100 ; init bitmask -loop: dex - bmi done2 - asl a - bne loop + and #%00001100 ; mask out other bits + lsr a + lsr a + tax + lda #%00000100 ; init bitmask +loop: dex + bmi done2 + asl a + bne loop -done2: ora retval - rts +done2: ora retval + rts -done: lda retval - rts +done: lda retval + rts ; ------------------------------------------------------------------------ ; .data -testbit:.byte $01 +testbit:.byte $01 ; ------------------------------------------------------------------------ ; diff --git a/testcode/lib/joy-test.c b/testcode/lib/joy-test.c index 0a5c80902..fc751ebdc 100644 --- a/testcode/lib/joy-test.c +++ b/testcode/lib/joy-test.c @@ -46,7 +46,7 @@ int main (void) clrscr (); count = joy_count (); -#ifdef __ATARI5200__ +#if defined(__ATARI5200__) || defined(__CREATIVISION__) cprintf ("JOYSTICKS: %d", count); #else cprintf ("Driver supports %d joystick(s)", count); @@ -55,13 +55,13 @@ int main (void) for (i = 0; i < count; ++i) { gotoxy (0, i+1); j = joy_read (i); -#ifdef __ATARI5200__ +#if defined(__ATARI5200__) || defined(__CREATIVISION__) cprintf ("%1d:%-3s%-3s%-3s%-3s%-3s%-3s", i, - (j & joy_masks[JOY_UP])? " U " : " u ", - (j & joy_masks[JOY_DOWN])? " D " : " d ", - (j & joy_masks[JOY_LEFT])? " L " : " l ", - (j & joy_masks[JOY_RIGHT])? " R " : " r ", + (j & joy_masks[JOY_UP])? " U " : " ", + (j & joy_masks[JOY_DOWN])? " D " : " ", + (j & joy_masks[JOY_LEFT])? " L " : " ", + (j & joy_masks[JOY_RIGHT])? " R " : " ", (j & joy_masks[JOY_FIRE])? " 1 " : " ", (j & joy_masks[JOY_FIRE2])? " 2 " : " "); #else From ddae920ee9e7cbfc3b9cd7fc8319102fe8ca3a62 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 15 Feb 2017 15:53:57 +0100 Subject: [PATCH 0228/2161] remove old joystick code --- libsrc/creativision/joy.s | 58 --------------------------------------- 1 file changed, 58 deletions(-) delete mode 100644 libsrc/creativision/joy.s diff --git a/libsrc/creativision/joy.s b/libsrc/creativision/joy.s deleted file mode 100644 index eb0bc6594..000000000 --- a/libsrc/creativision/joy.s +++ /dev/null @@ -1,58 +0,0 @@ -;* -;* Creativision Joystick Function -;* -;* unsigned char __fastcall__ joystate(unsigned char joy); -;* -;* JOY_1 -> Return Left Joystick direction -;* JOY_2 -> Return Right Joystick direction -;* JOY_3 -> Return Left Joystick buttons -;* JOY_4 -> Return Right Joystick buttons -;* -;* Will only work if interrupts are enabled. - - .export _joystate - .include "creativision.inc" - -_joystate: - cmp #1 ; Left Direction - bne l1 - - lda $11 - beq l5 - and #$0F - lsr a - tax - inx - txa - rts - -l1: cmp #2 ; Right Direction - bne l2 - - lda $13 - beq l5 - and #$0F - lsr a - tax - inx - txa - rts - -l2: cmp #3 ; Left Buttons - bne l3 - - lda $16 - beq l5 - and #$0F - rts - -l3: cmp #4 - bne l4 - - lda $17 - beq l5 - and #$0F - rts - -l4: lda #0 -l5: rts From 5988ec37cdce1655b14159a3a20a5493ba5459fd Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Wed, 15 Feb 2017 18:51:27 +0100 Subject: [PATCH 0229/2161] Revert "Disallow global variable declarations with an initializer." This reverts commit 1f12a06f7cc2ae79a800fe3faed727513364091b. --- src/cc65/compile.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 9cdeaf7e5..48a5c29d3 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -144,14 +144,17 @@ static void Parse (void) ** ** - if it is not a typedef or function, ** - if we don't had a storage class given ("int i") - ** or the storage class is explicitly specified as static. + ** - 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. */ if ((Decl.StorageClass & SC_FUNC) != SC_FUNC && (Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF && ((Spec.Flags & DS_DEF_STORAGE) != 0 || - (Decl.StorageClass & (SC_EXTERN|SC_STATIC)) == SC_STATIC)) { + (Decl.StorageClass & (SC_EXTERN|SC_STATIC)) == SC_STATIC || + ((Decl.StorageClass & SC_EXTERN) != 0 && + CurTok.Tok == TOK_ASSIGN))) { /* We will allocate storage */ Decl.StorageClass |= SC_STORAGE; From 39d655278da511dee9e6acb0bc94d88ff80ac006 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 15 Feb 2017 16:09:21 -0500 Subject: [PATCH 0230/2161] Added "telestrat.html" to index. Sorted "gamate.html". --- doc/index.sgml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/doc/index.sgml b/doc/index.sgml index 2a5c8894f..99b4f10b5 100644 --- a/doc/index.sgml +++ b/doc/index.sgml @@ -3,7 +3,7 @@ <article> <title>cc65 Documentation Overview <author><url url="http://cc65.github.io/doc"> -<date> +<date>2017-02-15 <sect>Program documentation<p> @@ -58,7 +58,7 @@ <tag><htmlurl url="coding.html" name="coding.html"></tag> Contains hints on creating the most effective code with cc65. - + <tag><htmlurl url="cc65-intern.html" name="cc65-intern.html"></tag> Describes internal details of cc65, such as calling conventions. @@ -143,6 +143,9 @@ <tag><htmlurl url="creativision.html" name="creativision.html"></tag> Topics specific to the Creativision Console. + <tag><htmlurl url="gamate.html" name="gamate.html"></tag> + Topics specific to the Bit Corporation Gamate Console. + <tag><htmlurl url="lynx.html" name="lynx.html"></tag> Topics specific to the Atari Lynx Game Console. @@ -155,9 +158,6 @@ <tag><htmlurl url="pce.html" name="pce.html"></tag> Topics specific to NEC PC-Engine (TurboGrafx) Console. - <tag><htmlurl url="gamate.html" name="gamate.html"></tag> - Topics specific to Bit Corporation Gamate Console. - <tag><htmlurl url="pet.html" name="pet.html"></tag> Topics specific to the Commodore PET machines. @@ -167,6 +167,9 @@ <tag><htmlurl url="supervision.html" name="supervision.html"></tag> Topics specific to the Watara Supervision Console. + <tag><htmlurl url="telestrat.html" name="telestrat.html"></tag> + Topics specific to the Oric Telestrat. + <tag><htmlurl url="vic20.html" name="vic20.html"></tag> Topics specific to the Commodore VIC20. From bb27d8d14ec6768424755694b47d91feb0014aa4 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 22 Feb 2017 14:25:10 +0100 Subject: [PATCH 0231/2161] README.md: PC-Engine is a console --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f8914c45a..fa8c4df60 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ including - the Atari 5200 console. - GEOS for the C64, C128 and Apple //e. - the Bit Corporation Gamate console. -- the NEC PC-Engine (aka TurboGrafx-16). +- the NEC PC-Engine (aka TurboGrafx-16) console. - the Nintendo Entertainment System (NES) console. - the Watara Supervision console. - the VTech Creativision console. From ae7fa8f2ea25dbd96a062284ef77ff7b15423489 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Fri, 24 Feb 2017 00:10:02 +0100 Subject: [PATCH 0232/2161] Improved display list instruction definition for more comfortable use within void data definition. --- doc/atari.sgml | 43 ++++++++++++++++++++ include/_antic.h | 56 +++++++++++++------------- testcode/lib/atari/displaylist.c | 69 ++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+), 28 deletions(-) create mode 100644 testcode/lib/atari/displaylist.c diff --git a/doc/atari.sgml b/doc/atari.sgml index a0dbe2f47..1b084324f 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -317,6 +317,49 @@ chip registers. </descrip><p> +<sect1>Display lists<p> + +An major feature of the Atari graphics chip "ANTIC" is to +process instructions for the display generation. +cc65 supports constructing these display lists by offering defines +for the instructions. In conjunction with the "void"-variable extension +of cc65, display lists can be created quite comfortable: + +<verb> +... +unsigned char ScreenMemory[100]; + +void DisplayList = +{ + DL_BLK8, + DL_BLK8, + DL_BLK8, + DL_LMS(DL_CHR20x8x2), + ScreenMemory, + DL_CHR20x8x2, + DL_CHR20x8x2, + DL_CHR20x8x2, + DL_BLK4, + DL_CHR20x8x2, + DL_JVB +}; +... +POKEW(560,(unsigned int)&DisplayList); // SDLSTL +... +</verb> + +Please inspect the <tt/_antic.h/ header file to detemine the supported +instruction names. Modifiers on instructions can be nested without need +for an order: + +<tt/DL_LMS(DL_HSCROL(DL_VSCROL(DL_DLI(DL_MAP80x4x2))))/ + +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 neccessary. A more memory +hungry solution consists in using the "<tt/posix_memalign()/" function in +conjunction with copying your data to the allocated memory. <sect1>Character mapping<p> diff --git a/include/_antic.h b/include/_antic.h index ab0cd9664..23a72609c 100644 --- a/include/_antic.h +++ b/include/_antic.h @@ -57,42 +57,42 @@ struct __antic { /* antic instruction set */ /* absolute instructions (non mode lines) */ -#define DL_JMP 1 -#define DL_JVB 65 +#define DL_JMP (unsigned char) 1 +#define DL_JVB (unsigned char) 65 -#define DL_BLK1 0 -#define DL_BLK2 16 -#define DL_BLK3 32 -#define DL_BLK4 48 -#define DL_BLK5 64 -#define DL_BLK6 80 -#define DL_BLK7 96 -#define DL_BLK8 112 +#define DL_BLK1 (unsigned char) 0 +#define DL_BLK2 (unsigned char) 16 +#define DL_BLK3 (unsigned char) 32 +#define DL_BLK4 (unsigned char) 48 +#define DL_BLK5 (unsigned char) 64 +#define DL_BLK6 (unsigned char) 80 +#define DL_BLK7 (unsigned char) 96 +#define DL_BLK8 (unsigned char) 112 /* absolute instructions (mode lines) */ -#define DL_CHR40x8x1 2 /* monochrome, 40 character & 8 scanlines per mode line (GR. 0) */ -#define DL_CHR40x10x1 3 /* monochrome, 40 character & 10 scanlines per mode line */ -#define DL_CHR40x8x4 4 /* colour, 40 character & 8 scanlines per mode line (GR. 12) */ -#define DL_CHR40x16x4 5 /* colour, 40 character & 16 scanlines per mode line (GR. 13) */ -#define DL_CHR20x8x2 6 /* colour (duochrome per character), 20 character & 8 scanlines per mode line (GR. 1) */ -#define DL_CHR20x16x2 7 /* colour (duochrome per character), 20 character & 16 scanlines per mode line (GR. 2) */ +#define DL_CHR40x8x1 (unsigned char) 2 /* monochrome, 40 character & 8 scanlines per mode line (GR. 0) */ +#define DL_CHR40x10x1 (unsigned char) 3 /* monochrome, 40 character & 10 scanlines per mode line */ +#define DL_CHR40x8x4 (unsigned char) 4 /* colour, 40 character & 8 scanlines per mode line (GR. 12) */ +#define DL_CHR40x16x4 (unsigned char) 5 /* colour, 40 character & 16 scanlines per mode line (GR. 13) */ +#define DL_CHR20x8x2 (unsigned char) 6 /* colour (duochrome per character), 20 character & 8 scanlines per mode line (GR. 1) */ +#define DL_CHR20x16x2 (unsigned char) 7 /* colour (duochrome per character), 20 character & 16 scanlines per mode line (GR. 2) */ -#define DL_MAP40x8x4 8 /* colour, 40 pixel & 8 scanlines per mode line (GR. 3) */ -#define DL_MAP80x4x2 9 /* 'duochrome', 80 pixel & 4 scanlines per mode line (GR.4) */ -#define DL_MAP80x4x4 10 /* colour, 80 pixel & 4 scanlines per mode line (GR.5) */ -#define DL_MAP160x2x2 11 /* 'duochrome', 160 pixel & 2 scanlines per mode line (GR.6) */ -#define DL_MAP160x1x2 12 /* 'duochrome', 160 pixel & 1 scanline per mode line (GR.14) */ -#define DL_MAP160x2x4 13 /* 4 colours, 160 pixel & 2 scanlines per mode line (GR.7) */ -#define DL_MAP160x1x4 14 /* 4 colours, 160 pixel & 1 scanline per mode line (GR.15) */ -#define DL_MAP320x1x1 15 /* monochrome, 320 pixel & 1 scanline per mode line (GR.8) */ +#define DL_MAP40x8x4 (unsigned char) 8 /* colour, 40 pixel & 8 scanlines per mode line (GR. 3) */ +#define DL_MAP80x4x2 (unsigned char) 9 /* 'duochrome', 80 pixel & 4 scanlines per mode line (GR.4) */ +#define DL_MAP80x4x4 (unsigned char) 10 /* colour, 80 pixel & 4 scanlines per mode line (GR.5) */ +#define DL_MAP160x2x2 (unsigned char) 11 /* 'duochrome', 160 pixel & 2 scanlines per mode line (GR.6) */ +#define DL_MAP160x1x2 (unsigned char) 12 /* 'duochrome', 160 pixel & 1 scanline per mode line (GR.14) */ +#define DL_MAP160x2x4 (unsigned char) 13 /* 4 colours, 160 pixel & 2 scanlines per mode line (GR.7) */ +#define DL_MAP160x1x4 (unsigned char) 14 /* 4 colours, 160 pixel & 1 scanline per mode line (GR.15) */ +#define DL_MAP320x1x1 (unsigned char) 15 /* monochrome, 320 pixel & 1 scanline per mode line (GR.8) */ /* modifiers on mode lines */ -#define DL_HSCROL 16 -#define DL_VSCROL 32 -#define DL_LMS 64 +#define DL_HSCROL(x) (unsigned char)((x) | 16) +#define DL_VSCROL(x) (unsigned char)((x) | 32) +#define DL_LMS(x) (unsigned char)((x) | 64) /* general modifier */ -#define DL_DLI 128 +#define DL_DLI(x) (unsigned char)((x) | 128) /* End of _antic.h */ #endif /* #ifndef __ANTIC_H */ diff --git a/testcode/lib/atari/displaylist.c b/testcode/lib/atari/displaylist.c new file mode 100644 index 000000000..869b5bb65 --- /dev/null +++ b/testcode/lib/atari/displaylist.c @@ -0,0 +1,69 @@ +/* +** testprogram for ANTIC instructions as defined in "_antic.h" +** +** 23-Feb-2017, Christian Krueger +*/ + +#include <conio.h> +#include <atari.h> +#include <peekpoke.h> +#include <string.h> + +// code is only for testing purposes, as screen and display list are not aligned +// and jumps not set! + +unsigned char DummyScreen[400]; + +void DisplayList = { + DL_BLK1, + DL_BLK2, + DL_BLK3, + DL_BLK4, + DL_BLK5, + DL_BLK6, + DL_BLK7, + DL_DLI(DL_BLK8), + DL_LMS(DL_CHR40x8x1), + DummyScreen, + DL_HSCROL(DL_CHR40x10x1), + DL_VSCROL(DL_CHR40x8x4), + DL_CHR40x16x4, + DL_LMS(DL_HSCROL(DL_VSCROL(DL_DLI(DL_CHR20x8x2)))), + DummyScreen+120, + DL_CHR20x16x2, + DL_MAP40x8x4, + DL_MAP80x4x2, + DL_MAP80x4x4, + DL_MAP160x2x2, + DL_MAP160x1x2, + DL_MAP160x2x4, + DL_MAP160x1x4, + DL_MAP320x1x1, + DL_JVB, + DL_JMP +}; + +unsigned char dlend = 0; + + +int +main(void) +{ + // unfortunately "sizeof()" doesn't work with void data + // (Error: Size of data type is unknown) + // so we trick with the adresses at front and behind... + + int returnValue = (((unsigned int)&dlend-(unsigned int)&DisplayList) != 28); // assure only one byte per instruction! + + clrscr(); + if (returnValue) + cputs("Test FAILED!"); + else + cputs("Test passed."); + + cputs("\n\rHit any key to exit..."); + cgetc(); + + return returnValue; +} + From f55d334435a1c1d845e1850021b23d83638cae29 Mon Sep 17 00:00:00 2001 From: Irgendwer <C.Krueger.B@web.de> Date: Fri, 24 Feb 2017 11:19:33 +0100 Subject: [PATCH 0233/2161] Update atari.sgml --- doc/atari.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/atari.sgml b/doc/atari.sgml index 1b084324f..6cbff6208 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -319,7 +319,7 @@ chip registers. <sect1>Display lists<p> -An major feature of the Atari graphics chip "ANTIC" is to +A major feature of the Atari graphics chip "ANTIC" is to process instructions for the display generation. cc65 supports constructing these display lists by offering defines for the instructions. In conjunction with the "void"-variable extension From e5af45b913f2cf40cd234f7c249b23e8e79c0870 Mon Sep 17 00:00:00 2001 From: Irgendwer <C.Krueger.B@web.de> Date: Fri, 24 Feb 2017 11:21:56 +0100 Subject: [PATCH 0234/2161] Update displaylist.c --- testcode/lib/atari/displaylist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testcode/lib/atari/displaylist.c b/testcode/lib/atari/displaylist.c index 869b5bb65..04c599878 100644 --- a/testcode/lib/atari/displaylist.c +++ b/testcode/lib/atari/displaylist.c @@ -51,7 +51,7 @@ main(void) { // unfortunately "sizeof()" doesn't work with void data // (Error: Size of data type is unknown) - // so we trick with the adresses at front and behind... + // so we trick with the addresses at front and end... int returnValue = (((unsigned int)&dlend-(unsigned int)&DisplayList) != 28); // assure only one byte per instruction! From aeee5610e1cdefaeae36456499c20e7bcffa1c3f Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Fri, 24 Feb 2017 19:06:32 +0100 Subject: [PATCH 0235/2161] atari_antic.inc: use "or" instead of "plus" in the usage example --- asminc/atari_antic.inc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/asminc/atari_antic.inc b/asminc/atari_antic.inc index 1eb4c87ef..a4557c7b4 100644 --- a/asminc/atari_antic.inc +++ b/asminc/atari_antic.inc @@ -33,16 +33,16 @@ NMIRES = ANTIC + $0F ;NMI interrupt reset ; ScreenDL: ; .byte DL_BLK8 ; .byte DL_BLK8 -; .byte DL_CHR40x8x1 + DL_LMS + DL_DLI +; .byte DL_CHR40x8x1 | DL_LMS | DL_DLI ; .word ScreenAlignment -; .byte DL_BLK1 + DL_DLI -; .byte DL_MAP320x1x1 + DL_LMS +; .byte DL_BLK1 | DL_DLI +; .byte DL_MAP320x1x1 | DL_LMS ; .word Screen ; ; .repeat 99 ; .byte DL_MAP320x1x1 ; .endrepeat -; .byte DL_MAP320x1x1 + DL_LMS +; .byte DL_MAP320x1x1 | DL_LMS ; .word Screen + 40 * 100 ; 100 lines a 40 byte, 'Screen' has to be aligned correctly! ; .repeat 92 ; .byte DL_MAP320x1x1 @@ -55,6 +55,8 @@ NMIRES = ANTIC + $0F ;NMI interrupt reset DL_JMP = 1 DL_JVB = 65 +; DL_BLKn display n empty lines (just background) + DL_BLK1 = 0 DL_BLK2 = 16 DL_BLK3 = 32 From 6afcc370edbd77d494fc6378a20de0023be6981f Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sat, 25 Feb 2017 20:19:34 +0100 Subject: [PATCH 0236/2161] Optimization of two string functions (size & speed). --- libsrc/common/strcat.s | 48 ++++++++------------ libsrc/common/strchr.s | 47 ++++++++++--------- testcode/lib/strcat-test.c | 93 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+), 52 deletions(-) create mode 100644 testcode/lib/strcat-test.c diff --git a/libsrc/common/strcat.s b/libsrc/common/strcat.s index 7784d89f7..279bfe65b 100644 --- a/libsrc/common/strcat.s +++ b/libsrc/common/strcat.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 31.05.1998 +; Christian Krueger: 2013-Jul-24, minor optimization ; ; char* strcat (char* dest, const char* src); ; @@ -12,44 +13,35 @@ _strcat: sta ptr1 ; Save src stx ptr1+1 jsr popax ; Get dest - sta ptr2 - stx ptr2+1 sta tmp3 ; Remember for function return - ldy #0 + tay + lda #0 + sta ptr2 ; access from page start, y contains low byte + stx ptr2+1 -; find end of dest - -sc1: lda (ptr2),y - beq sc2 +findEndOfDest: + lda (ptr2),y + beq endOfDestFound iny - bne sc1 + bne findEndOfDest inc ptr2+1 - bne sc1 + bne findEndOfDest -; end found, get offset in y into pointer +endOfDestFound: + sty ptr2 ; advance pointer to last y position + ldy #0 ; reset new y-offset -sc2: tya - clc - adc ptr2 - sta ptr2 - bcc sc3 - inc ptr2+1 - -; copy src - -sc3: ldy #0 -sc4: lda (ptr1),y +copyByte: + lda (ptr1),y sta (ptr2),y - beq sc5 + beq done iny - bne sc4 + bne copyByte inc ptr1+1 inc ptr2+1 - bne sc4 + bne copyByte ; like bra here -; done, return pointer to dest - -sc5: lda tmp3 ; X does still contain high byte +; return pointer to dest +done: lda tmp3 ; X does still contain high byte rts - diff --git a/libsrc/common/strchr.s b/libsrc/common/strchr.s index 308381b06..0bd55d0e1 100644 --- a/libsrc/common/strchr.s +++ b/libsrc/common/strchr.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 31.05.1998 +; Christian Krueger, 2013-Aug-04, minor optimization ; ; const char* strchr (const char* s, int c); ; @@ -9,40 +10,38 @@ .importzp ptr1, tmp1 _strchr: - sta tmp1 ; Save c - jsr popax ; get s - sta ptr1 - stx ptr1+1 - ldy #0 + sta tmp1 ; Save c + jsr popax ; get s + tay ; low byte of pointer to y + stx ptr1+1 + lda #0 + sta ptr1 ; ptr access page wise -Loop: lda (ptr1),y ; Get next char - beq EOS ; Jump on end of string - cmp tmp1 ; Found? - beq Found ; Jump if yes +Loop: lda (ptr1),y ; Get next char + beq EOS ; Jump on end of string + cmp tmp1 ; Found? + beq Found ; Jump if yes iny - bne Loop - inc ptr1+1 - bne Loop ; Branch always + bne Loop + inc ptr1+1 + bne Loop ; Branch always ; End of string. Check if we're searching for the terminating zero -EOS: lda tmp1 ; Get the char we're searching for - bne NotFound ; Jump if not searching for terminator +EOS: + lda tmp1 ; Get the char we're searching for + bne NotFound ; Jump if not searching for terminator -; Found. Calculate pointer to c. +; Found. Set pointer to c. -Found: ldx ptr1+1 ; Load high byte of pointer - tya ; Low byte offset - clc - adc ptr1 - bcc Found1 - inx -Found1: rts +Found: + ldx ptr1+1 ; Load high byte of pointer + tya ; low byte is in y + rts ; Not found, return NULL NotFound: - lda #0 + lda #0 tax rts - diff --git a/testcode/lib/strcat-test.c b/testcode/lib/strcat-test.c new file mode 100644 index 000000000..edd614fc4 --- /dev/null +++ b/testcode/lib/strcat-test.c @@ -0,0 +1,93 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define SourceStringSize 257 // test correct page passing (>256) + +static char SourceString[SourceStringSize+1]; // +1 room for terminating null +static char DestinationString[2*SourceStringSize+1]; // will contain two times the source buffer + + +int main (void) +{ + unsigned i,j; + char* p; + + /* Print a header */ + printf ("strcat(): "); + + for (i=0; i < SourceStringSize; ++i) + SourceString[i] = (i%128)+1; + + SourceString[i] = 0; + + if (strlen(SourceString) != SourceStringSize) + { + printf ("Fail: Source string initialization or 'strlen()' problem!\n"); + printf ("Expected length: %u but is %u!\n", SourceStringSize, strlen(SourceString)); + exit (EXIT_FAILURE); + } + + /* Ensure empty destination string */ + DestinationString[0] = 0; + + if (strlen(DestinationString) != 0) + { + printf ("Fail: Destination string initialization or 'strlen()' problem!\n"); + printf ("Expected length: %u but is %u!\n", 0, strlen(DestinationString)); + exit (EXIT_FAILURE); + } + + /* Test concatenation to empty buffer */ + + p = strcat(DestinationString, SourceString); + + if (strlen(DestinationString) != SourceStringSize) + { + printf ("Fail: String concatenation to empty buffer!\n"); + printf ("Expected length: %u but is %u!\n", SourceStringSize, strlen(DestinationString)); + exit (EXIT_FAILURE); + } + + /* Test concatenation to non empty buffer */ + + p = strcat(DestinationString, SourceString); + + if (strlen(DestinationString) != 2*SourceStringSize) + { + printf ("Fail: String concatenation to non-empty buffer!\n"); + printf ("Expected length: %u but is %u!\n", 2*SourceStringSize, strlen(DestinationString)); + exit (EXIT_FAILURE); + } + + /* Test return value */ + + if (p != DestinationString) + { + printf ("Invalid return value!\n"); + exit (EXIT_FAILURE); + } + + /* Test contents */ + + for(j=0; j <2; ++j) + for(i=0; i < SourceStringSize; ++i) + { + unsigned position = j*SourceStringSize+i; + unsigned current = DestinationString[position]; + unsigned expected = (i%128)+1; + if (current != expected) + { + printf ("Fail: Unexpected destination buffer contents at position %u!\n", position); + printf ("Expected %u, but is %u!\n", expected, current); + exit (EXIT_FAILURE); + } + } + + /* Test passed */ + printf ("Passed\n"); + return EXIT_SUCCESS; +} + + + From f6002a149c84f9b97f9a0838c3977cff2e443d07 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 25 Feb 2017 21:32:06 +0100 Subject: [PATCH 0237/2161] adding gotoxy.s --- asminc/telestrat.inc | 5 +++++ libsrc/telestrat/gotoxy.s | 15 +++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 libsrc/telestrat/gotoxy.s diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 2c3502ba8..ab209e520 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -107,6 +107,7 @@ XWR0 = $10 XWSTR0 = $14 XTEXT = $19 XHIRES = $1A +XFILLM = $1C XMINMA = $1F XFREAD = $27 ; only in TELEMON 3.0 XOPEN = $30 ; only in TELEMON 3.0 @@ -128,6 +129,10 @@ XINK = $93 XEXPLO = $9C XPING = $9D +; --------------------------------------------------------------------------- +; Page $200 +SCRX := $220 +SCRY := $224 ; --------------------------------------------------------------------------- ; Page $500 diff --git a/libsrc/telestrat/gotoxy.s b/libsrc/telestrat/gotoxy.s new file mode 100644 index 000000000..18e010ae2 --- /dev/null +++ b/libsrc/telestrat/gotoxy.s @@ -0,0 +1,15 @@ + .export _gotoxy + + .import popa + + .importzp sp,tmp2,tmp3,tmp1 + + .include "telestrat.inc" + + +.proc _gotoxy + sta SCRY + jsr popa + sta SCRX + rts +.endproc From 4f1d007fb4cfbd20b7bf45e1bf14f41fcabd08ab Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 25 Feb 2017 21:32:42 +0100 Subject: [PATCH 0238/2161] Correcting typo --- doc/telestrat.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index 9032156ee..fda4dee86 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -141,7 +141,7 @@ Telestrat manages also mouse, but it had been no handled yet in this version. Telestrat has a RS232 port, but it's not used -</descrip>< +</descrip> <sect>Limitations<label id="limitations"><p> From 1497330cc06512aff6a6708ba2d9e053b38ca7e1 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 25 Feb 2017 22:10:13 +0100 Subject: [PATCH 0239/2161] adding clrscr.s --- asminc/telestrat.inc | 3 +++ libsrc/telestrat/clrscr.s | 31 +++++++++++++++++++++++++++++++ libsrc/telestrat/gotoxy.s | 2 ++ 3 files changed, 36 insertions(+) create mode 100644 libsrc/telestrat/clrscr.s diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index ab209e520..8a51e1c32 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -133,6 +133,9 @@ XPING = $9D ; Page $200 SCRX := $220 SCRY := $224 +ADSCRL := $218 +ADSCRH := $21C + ; --------------------------------------------------------------------------- ; Page $500 diff --git a/libsrc/telestrat/clrscr.s b/libsrc/telestrat/clrscr.s new file mode 100644 index 000000000..8c45aeeec --- /dev/null +++ b/libsrc/telestrat/clrscr.s @@ -0,0 +1,31 @@ + .export _clrscr + + .importzp sp + + .include "telestrat.inc" + +.proc _clrscr + lda #<SCREEN + ldy #>SCREEN + sta RES + sty RES+1 + + ldy #<(SCREEN+SCREEN_XSIZE*SCREEN_YSIZE) + ldx #>(SCREEN+SCREEN_XSIZE*SCREEN_YSIZE) + lda #' ' + BRK_TELEMON XFILLM + + + ; reset prompt position + lda #<(SCREEN+40) + sta ADSCRL + lda #>(SCREEN+40) + sta ADSCRH + + ; reset display position + lda #$01 + sta SCRY + lda #$02 + sta SCRX + rts +.endproc diff --git a/libsrc/telestrat/gotoxy.s b/libsrc/telestrat/gotoxy.s index 18e010ae2..fb659d968 100644 --- a/libsrc/telestrat/gotoxy.s +++ b/libsrc/telestrat/gotoxy.s @@ -8,6 +8,8 @@ .proc _gotoxy + ; This function move only cursor for display, it does not move the prompt position + ; in telemon, there is position for prompt, and another for the cursor sta SCRY jsr popa sta SCRX From 7bc3bff83f682f9c511e272e30ae3736ca3681aa Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 25 Feb 2017 22:20:17 +0100 Subject: [PATCH 0240/2161] adding gotox.s gotoy.s wherex.s wherey.s --- libsrc/telestrat/clrscr.s | 6 +++++- libsrc/telestrat/gotox.s | 16 ++++++++++++++++ libsrc/telestrat/gotoxy.s | 9 ++++++--- libsrc/telestrat/gotoy.s | 14 ++++++++++++++ libsrc/telestrat/wherex.s | 15 +++++++++++++++ libsrc/telestrat/wherey.s | 15 +++++++++++++++ 6 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 libsrc/telestrat/gotox.s create mode 100644 libsrc/telestrat/gotoy.s create mode 100644 libsrc/telestrat/wherex.s create mode 100644 libsrc/telestrat/wherey.s diff --git a/libsrc/telestrat/clrscr.s b/libsrc/telestrat/clrscr.s index 8c45aeeec..891c4162d 100644 --- a/libsrc/telestrat/clrscr.s +++ b/libsrc/telestrat/clrscr.s @@ -1,3 +1,7 @@ +; +; jede jede@oric.org 2017-02-25 +; + .export _clrscr .importzp sp @@ -25,7 +29,7 @@ ; reset display position lda #$01 sta SCRY - lda #$02 + lda #$00 sta SCRX rts .endproc diff --git a/libsrc/telestrat/gotox.s b/libsrc/telestrat/gotox.s new file mode 100644 index 000000000..d6af0e4dd --- /dev/null +++ b/libsrc/telestrat/gotox.s @@ -0,0 +1,16 @@ +; +; jede jede@oric.org 2017-02-25 +; + .export _gotox + + .import popa + + .importzp sp + + .include "telestrat.inc" + + +.proc _gotox + sta SCRX + rts +.endproc diff --git a/libsrc/telestrat/gotoxy.s b/libsrc/telestrat/gotoxy.s index fb659d968..7aa83b71d 100644 --- a/libsrc/telestrat/gotoxy.s +++ b/libsrc/telestrat/gotoxy.s @@ -1,3 +1,6 @@ +; +; jede jede@oric.org 2017-02-25 +; .export _gotoxy .import popa @@ -10,8 +13,8 @@ .proc _gotoxy ; This function move only cursor for display, it does not move the prompt position ; in telemon, there is position for prompt, and another for the cursor - sta SCRY - jsr popa - sta SCRX + sta SCRY + jsr popa + sta SCRX rts .endproc diff --git a/libsrc/telestrat/gotoy.s b/libsrc/telestrat/gotoy.s new file mode 100644 index 000000000..d71570f10 --- /dev/null +++ b/libsrc/telestrat/gotoy.s @@ -0,0 +1,14 @@ +; +; jede jede@oric.org 2017-02-25 +; + .export _gotoy + + .importzp sp + + .include "telestrat.inc" + + +.proc _gotoy + sta SCRY + rts +.endproc diff --git a/libsrc/telestrat/wherex.s b/libsrc/telestrat/wherex.s new file mode 100644 index 000000000..6d9587ba8 --- /dev/null +++ b/libsrc/telestrat/wherex.s @@ -0,0 +1,15 @@ +; +; jede jede@oric.org 2017-02-25 +; + .export _wherex + + .importzp sp + + .include "telestrat.inc" + + +.proc _wherex + ldx #$00 + lda SCRX + rts +.endproc diff --git a/libsrc/telestrat/wherey.s b/libsrc/telestrat/wherey.s new file mode 100644 index 000000000..e211ed5b9 --- /dev/null +++ b/libsrc/telestrat/wherey.s @@ -0,0 +1,15 @@ +; +; jede jede@oric.org 2017-02-25 +; + .export _wherey + + .importzp sp + + .include "telestrat.inc" + + +.proc _wherey + ldx #$00 + lda SCRY + rts +.endproc From b0e035ba2b654891c98d7bf0de912e8d4da68798 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 25 Feb 2017 22:23:46 +0100 Subject: [PATCH 0241/2161] Cleaning --- libsrc/telestrat/clrscr.s | 8 ++++---- libsrc/telestrat/gotoxy.s | 3 +-- libsrc/telestrat/gotoy.s | 1 - libsrc/telestrat/wherex.s | 1 - libsrc/telestrat/wherey.s | 1 - 5 files changed, 5 insertions(+), 9 deletions(-) diff --git a/libsrc/telestrat/clrscr.s b/libsrc/telestrat/clrscr.s index 891c4162d..f2b8fafc1 100644 --- a/libsrc/telestrat/clrscr.s +++ b/libsrc/telestrat/clrscr.s @@ -10,7 +10,7 @@ .proc _clrscr lda #<SCREEN - ldy #>SCREEN + ldy #>SCREEN sta RES sty RES+1 @@ -20,14 +20,14 @@ BRK_TELEMON XFILLM - ; reset prompt position + ; reset prompt position lda #<(SCREEN+40) sta ADSCRL lda #>(SCREEN+40) sta ADSCRH - ; reset display position - lda #$01 + ; reset display position + lda #$01 sta SCRY lda #$00 sta SCRX diff --git a/libsrc/telestrat/gotoxy.s b/libsrc/telestrat/gotoxy.s index 7aa83b71d..e0c8154e3 100644 --- a/libsrc/telestrat/gotoxy.s +++ b/libsrc/telestrat/gotoxy.s @@ -5,11 +5,10 @@ .import popa - .importzp sp,tmp2,tmp3,tmp1 + .importzp sp .include "telestrat.inc" - .proc _gotoxy ; This function move only cursor for display, it does not move the prompt position ; in telemon, there is position for prompt, and another for the cursor diff --git a/libsrc/telestrat/gotoy.s b/libsrc/telestrat/gotoy.s index d71570f10..ed7101c80 100644 --- a/libsrc/telestrat/gotoy.s +++ b/libsrc/telestrat/gotoy.s @@ -7,7 +7,6 @@ .include "telestrat.inc" - .proc _gotoy sta SCRY rts diff --git a/libsrc/telestrat/wherex.s b/libsrc/telestrat/wherex.s index 6d9587ba8..0dd5139e1 100644 --- a/libsrc/telestrat/wherex.s +++ b/libsrc/telestrat/wherex.s @@ -7,7 +7,6 @@ .include "telestrat.inc" - .proc _wherex ldx #$00 lda SCRX diff --git a/libsrc/telestrat/wherey.s b/libsrc/telestrat/wherey.s index e211ed5b9..4958f10cf 100644 --- a/libsrc/telestrat/wherey.s +++ b/libsrc/telestrat/wherey.s @@ -7,7 +7,6 @@ .include "telestrat.inc" - .proc _wherey ldx #$00 lda SCRY From c240d42a9e36f565f03d00eab80b9a2c5aa99ae3 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sun, 26 Feb 2017 20:03:05 +0100 Subject: [PATCH 0242/2161] Added "strrchr" optimizaion a matching unit test and tiny unit test framework. (Documentation for that will follow later) --- include/unittest.h | 89 +++++++++++++++++++++++++++++++++++++ libsrc/common/strrchr.s | 58 +++++++++++------------- testcode/lib/strcat-test.c | 65 ++++++--------------------- testcode/lib/strrchr-test.c | 38 ++++++++++++++++ 4 files changed, 167 insertions(+), 83 deletions(-) create mode 100644 include/unittest.h create mode 100644 testcode/lib/strrchr-test.c diff --git a/include/unittest.h b/include/unittest.h new file mode 100644 index 000000000..a58bbb937 --- /dev/null +++ b/include/unittest.h @@ -0,0 +1,89 @@ +/*****************************************************************************/ +/* */ +/* unittest.h */ +/* */ +/* Unit test helper macros */ +/* */ +/* */ +/* */ +/* (C) 2017 Christian Krueger */ +/* */ +/* 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 _UNITTEST_H +#define _UNITTEST_H + +#include <stdio.h> +#include <stdlib.h> + +#ifndef COMMA +#define COMMA , +#endif + +#define TEST int main(void) \ + {\ + printf("%s: ",__FILE__); + +#define ENDTEST printf("Passed\n"); \ + return EXIT_SUCCESS; \ + } + +#define ASSERT_IsTrue(a,b) if (!(a)) \ + {\ + printf("Fail at line %d:\n",__LINE__);\ + printf(b);\ + printf("\n");\ + printf("Expected status should be true but wasn't!\n");\ + exit(EXIT_FAILURE);\ + } + +#define ASSERT_IsFalse(a,b) if ((a)) \ + {\ + printf("Fail at line %d:\n",__LINE__);\ + printf(b);\ + printf("\n");\ + printf("Expected status should be false but wasn't!\n");\ + exit(EXIT_FAILURE);\ + } + +#define ASSERT_AreEqual(a,b,c,d) if ((a) != (b)) \ + {\ + printf("Fail at line %d:\n",__LINE__);\ + printf(d);\ + printf("\n");\ + printf("Expected value: "c", but is "c"!\n", (a), (b));\ + exit(EXIT_FAILURE);\ + } + +#define ASSERT_AreNotEqual(a,b,c,d) if ((a) == (b)) \ + {\ + printf("Fail at line %d:\n",__LINE__);\ + printf(d);\ + printf("\n");\ + printf("Expected value not: "c", but is "c"!\n", (a), (b));\ + exit(EXIT_FAILURE);\ + } + +/* End of unittest.h */ +#endif + + + + diff --git a/libsrc/common/strrchr.s b/libsrc/common/strrchr.s index bd7389e76..3e4fb0810 100644 --- a/libsrc/common/strrchr.s +++ b/libsrc/common/strrchr.s @@ -1,47 +1,41 @@ ; ; Ullrich von Bassewitz, 31.05.1998 +; Christian Krueger: 2013-Aug-01, optimization ; ; char* strrchr (const char* s, int c); ; .export _strrchr .import popax - .importzp ptr1, ptr2, tmp1 + .importzp ptr1, tmp1, tmp2 _strrchr: - sta tmp1 ; Save c - jsr popax ; get s - sta ptr1 - stx ptr1+1 - lda #0 ; function result = NULL - sta ptr2 - sta ptr2+1 - tay + sta tmp1 ; Save c + jsr popax ; get s + tay ; low byte to y + stx ptr1+1 + ldx #0 ; default function result is NULL, X is high byte... + stx tmp2 ; tmp2 is low-byte + stx ptr1 ; low-byte of source string is in Y, so clear real one... + +testChar: + lda (ptr1),y ; get char + beq finished ; jump if end of string + cmp tmp1 ; found? + bne nextChar ; jump if no -L1: lda (ptr1),y ; get next char - beq L3 ; jump if end of string - cmp tmp1 ; found? - bne L2 ; jump if no +charFound: + sty tmp2 ; y has low byte of location, save it + ldx ptr1+1 ; x holds high-byte of result -; Remember a pointer to the character +nextChar: + iny + bne testChar + inc ptr1+1 + bne testChar ; here like bra... - tya - clc - adc ptr1 - sta ptr2 - lda ptr1+1 - adc #$00 - sta ptr2+1 +; return the pointer to the last occurrence -; Next char - -L2: iny - bne L1 - inc ptr1+1 - bne L1 ; jump always - -; Return the pointer to the last occurrence - -L3: lda ptr2 - ldx ptr2+1 +finished: + lda tmp2 ; high byte in X is already correct... rts diff --git a/testcode/lib/strcat-test.c b/testcode/lib/strcat-test.c index edd614fc4..fdc987288 100644 --- a/testcode/lib/strcat-test.c +++ b/testcode/lib/strcat-test.c @@ -1,5 +1,4 @@ -#include <stdio.h> -#include <stdlib.h> +#include <unittest.h> #include <string.h> #define SourceStringSize 257 // test correct page passing (>256) @@ -8,65 +7,38 @@ static char SourceString[SourceStringSize+1]; // +1 room for terminating null static char DestinationString[2*SourceStringSize+1]; // will contain two times the source buffer -int main (void) +TEST { unsigned i,j; char* p; - - /* Print a header */ - printf ("strcat(): "); - + for (i=0; i < SourceStringSize; ++i) SourceString[i] = (i%128)+1; SourceString[i] = 0; - if (strlen(SourceString) != SourceStringSize) - { - printf ("Fail: Source string initialization or 'strlen()' problem!\n"); - printf ("Expected length: %u but is %u!\n", SourceStringSize, strlen(SourceString)); - exit (EXIT_FAILURE); - } + ASSERT_AreEqual(SourceStringSize, strlen(SourceString), "%u", "Source string initialization or 'strlen()' problem!"); /* Ensure empty destination string */ DestinationString[0] = 0; - if (strlen(DestinationString) != 0) - { - printf ("Fail: Destination string initialization or 'strlen()' problem!\n"); - printf ("Expected length: %u but is %u!\n", 0, strlen(DestinationString)); - exit (EXIT_FAILURE); - } - + ASSERT_AreEqual(0, strlen(DestinationString), "%u", "Destination string initialization or 'strlen()' problem!"); + /* Test concatenation to empty buffer */ - p = strcat(DestinationString, SourceString); - - if (strlen(DestinationString) != SourceStringSize) - { - printf ("Fail: String concatenation to empty buffer!\n"); - printf ("Expected length: %u but is %u!\n", SourceStringSize, strlen(DestinationString)); - exit (EXIT_FAILURE); - } - + strcat(DestinationString, SourceString); + + ASSERT_AreEqual(SourceStringSize, strlen(DestinationString), "%u", "Unexpected string length while string concatenation to empty buffer!"); + /* Test concatenation to non empty buffer */ p = strcat(DestinationString, SourceString); - if (strlen(DestinationString) != 2*SourceStringSize) - { - printf ("Fail: String concatenation to non-empty buffer!\n"); - printf ("Expected length: %u but is %u!\n", 2*SourceStringSize, strlen(DestinationString)); - exit (EXIT_FAILURE); - } + ASSERT_AreEqual(2*SourceStringSize, strlen(DestinationString), "%u", "Unexpected string length while string concatenation to non-empty buffer!"); /* Test return value */ - if (p != DestinationString) - { - printf ("Invalid return value!\n"); - exit (EXIT_FAILURE); - } + ASSERT_IsTrue(p == DestinationString,"Invalid return value!"); /* Test contents */ @@ -76,18 +48,9 @@ int main (void) unsigned position = j*SourceStringSize+i; unsigned current = DestinationString[position]; unsigned expected = (i%128)+1; - if (current != expected) - { - printf ("Fail: Unexpected destination buffer contents at position %u!\n", position); - printf ("Expected %u, but is %u!\n", expected, current); - exit (EXIT_FAILURE); - } + ASSERT_AreEqual(expected, current, "%u", "Unexpected destination buffer contents at position %u!\n" COMMA position); } - - /* Test passed */ - printf ("Passed\n"); - return EXIT_SUCCESS; } - +ENDTEST diff --git a/testcode/lib/strrchr-test.c b/testcode/lib/strrchr-test.c new file mode 100644 index 000000000..9c1c70032 --- /dev/null +++ b/testcode/lib/strrchr-test.c @@ -0,0 +1,38 @@ +#include <unittest.h> +#include <string.h> + +static char TestString[] = "01234567890123456789"; // two times the same string +static char Found[256]; + +TEST +{ + unsigned len; + unsigned i; + char* p; + + len = strlen(TestString)/2; // test only one half of the string, to find last appearance + + /* Search for all characters in the string, including the terminator */ + for (i = 0; i < len; ++i) + { + /* Search for this char */ + p = strrchr (TestString, TestString[i]); + ASSERT_AreEqual(i+len, p-TestString, "%u", "Unexpected location of character '%c' found!" COMMA TestString[i]); + + /* Mark the char as checked */ + Found[TestString[i]] = 1; + } + + /* Search for all other characters and make sure they aren't found */ + for (i = 0; i < 256; ++i) + { + if (!Found[i]) + { + p = strrchr (TestString, i); + ASSERT_IsFalse(p, "Unexpected location of character '%c' found!" COMMA TestString[i]); + } + } +} +ENDTEST + + From 3d28f5ca9089bd7f16ce77efeba0c66752932a07 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sun, 26 Feb 2017 22:36:19 +0100 Subject: [PATCH 0243/2161] Fixed indentation --- include/unittest.h | 78 ++++++++++++++++++------------------- libsrc/common/strcat.s | 47 +++++++++++----------- testcode/lib/strcat-test.c | 4 +- testcode/lib/strrchr-test.c | 4 +- 4 files changed, 66 insertions(+), 67 deletions(-) diff --git a/include/unittest.h b/include/unittest.h index a58bbb937..bd355bb0c 100644 --- a/include/unittest.h +++ b/include/unittest.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2017 Christian Krueger */ +/* (C) 2017 Christian Krueger */ /* */ /* This software is provided 'as-is', without any expressed or implied */ /* warranty. In no event will the authors be held liable for any damages */ @@ -37,49 +37,49 @@ #define COMMA , #endif -#define TEST int main(void) \ - {\ - printf("%s: ",__FILE__); +#define TEST int main(void) \ + {\ + printf("%s: ",__FILE__); -#define ENDTEST printf("Passed\n"); \ - return EXIT_SUCCESS; \ - } +#define ENDTEST printf("Passed\n"); \ + return EXIT_SUCCESS; \ + } -#define ASSERT_IsTrue(a,b) if (!(a)) \ - {\ - printf("Fail at line %d:\n",__LINE__);\ - printf(b);\ - printf("\n");\ - printf("Expected status should be true but wasn't!\n");\ - exit(EXIT_FAILURE);\ - } +#define ASSERT_IsTrue(a,b) if (!(a)) \ + {\ + printf("Fail at line %d:\n",__LINE__);\ + printf(b);\ + printf("\n");\ + printf("Expected status should be true but wasn't!\n");\ + exit(EXIT_FAILURE);\ + } -#define ASSERT_IsFalse(a,b) if ((a)) \ - {\ - printf("Fail at line %d:\n",__LINE__);\ - printf(b);\ - printf("\n");\ - printf("Expected status should be false but wasn't!\n");\ - exit(EXIT_FAILURE);\ - } +#define ASSERT_IsFalse(a,b) if ((a)) \ + {\ + printf("Fail at line %d:\n",__LINE__);\ + printf(b);\ + printf("\n");\ + printf("Expected status should be false but wasn't!\n");\ + exit(EXIT_FAILURE);\ + } -#define ASSERT_AreEqual(a,b,c,d) if ((a) != (b)) \ - {\ - printf("Fail at line %d:\n",__LINE__);\ - printf(d);\ - printf("\n");\ - printf("Expected value: "c", but is "c"!\n", (a), (b));\ - exit(EXIT_FAILURE);\ - } +#define ASSERT_AreEqual(a,b,c,d) if ((a) != (b)) \ + {\ + printf("Fail at line %d:\n",__LINE__);\ + printf(d);\ + printf("\n");\ + printf("Expected value: "c", but is "c"!\n", (a), (b));\ + exit(EXIT_FAILURE);\ + } -#define ASSERT_AreNotEqual(a,b,c,d) if ((a) == (b)) \ - {\ - printf("Fail at line %d:\n",__LINE__);\ - printf(d);\ - printf("\n");\ - printf("Expected value not: "c", but is "c"!\n", (a), (b));\ - exit(EXIT_FAILURE);\ - } +#define ASSERT_AreNotEqual(a,b,c,d) if ((a) == (b)) \ + {\ + printf("Fail at line %d:\n",__LINE__);\ + printf(d);\ + printf("\n");\ + printf("Expected value not: "c", but is "c"!\n", (a), (b));\ + exit(EXIT_FAILURE);\ + } /* End of unittest.h */ #endif diff --git a/libsrc/common/strcat.s b/libsrc/common/strcat.s index 279bfe65b..9be65386f 100644 --- a/libsrc/common/strcat.s +++ b/libsrc/common/strcat.s @@ -10,38 +10,37 @@ .importzp ptr1, ptr2, tmp3 _strcat: - sta ptr1 ; Save src - stx ptr1+1 - jsr popax ; Get dest - sta tmp3 ; Remember for function return - tay - lda #0 - sta ptr2 ; access from page start, y contains low byte - stx ptr2+1 + sta ptr1 ; Save src + stx ptr1+1 + jsr popax ; Get dest + sta tmp3 ; Remember for function return + tay + lda #0 + sta ptr2 ; access from page start, y contains low byte + stx ptr2+1 findEndOfDest: - lda (ptr2),y - beq endOfDestFound + lda (ptr2),y + beq endOfDestFound iny - bne findEndOfDest - inc ptr2+1 - bne findEndOfDest + bne findEndOfDest + inc ptr2+1 + bne findEndOfDest endOfDestFound: - sty ptr2 ; advance pointer to last y position - ldy #0 ; reset new y-offset + sty ptr2 ; advance pointer to last y position + ldy #0 ; reset new y-offset copyByte: - lda (ptr1),y - sta (ptr2),y - beq done + lda (ptr1),y + sta (ptr2),y + beq done iny - bne copyByte - inc ptr1+1 - inc ptr2+1 - bne copyByte ; like bra here + bne copyByte + inc ptr1+1 + inc ptr2+1 + bne copyByte ; like bra here ; return pointer to dest -done: lda tmp3 ; X does still contain high byte +done: lda tmp3 ; X does still contain high byte rts - diff --git a/testcode/lib/strcat-test.c b/testcode/lib/strcat-test.c index fdc987288..2e00b80cb 100644 --- a/testcode/lib/strcat-test.c +++ b/testcode/lib/strcat-test.c @@ -3,7 +3,7 @@ #define SourceStringSize 257 // test correct page passing (>256) -static char SourceString[SourceStringSize+1]; // +1 room for terminating null +static char SourceString[SourceStringSize+1]; // +1 room for terminating null static char DestinationString[2*SourceStringSize+1]; // will contain two times the source buffer @@ -48,7 +48,7 @@ TEST unsigned position = j*SourceStringSize+i; unsigned current = DestinationString[position]; unsigned expected = (i%128)+1; - ASSERT_AreEqual(expected, current, "%u", "Unexpected destination buffer contents at position %u!\n" COMMA position); + ASSERT_AreEqual(expected, current, "%u", "Unexpected destination buffer contents at position %u!\n" COMMA position); } } ENDTEST diff --git a/testcode/lib/strrchr-test.c b/testcode/lib/strrchr-test.c index 9c1c70032..d2c2a20e4 100644 --- a/testcode/lib/strrchr-test.c +++ b/testcode/lib/strrchr-test.c @@ -1,7 +1,7 @@ #include <unittest.h> #include <string.h> -static char TestString[] = "01234567890123456789"; // two times the same string +static char TestString[] = "01234567890123456789"; // two times the same string static char Found[256]; TEST @@ -10,7 +10,7 @@ TEST unsigned i; char* p; - len = strlen(TestString)/2; // test only one half of the string, to find last appearance + len = strlen(TestString)/2; // test only one half of the string, to find last appearance /* Search for all characters in the string, including the terminator */ for (i = 0; i < len; ++i) From 09de875330a4ca5eeabf91a21e774758c1de4417 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Tue, 28 Feb 2017 08:05:11 +0100 Subject: [PATCH 0244/2161] Changed the location of unittest.h --- testcode/lib/strcat-test.c | 2 +- testcode/lib/strrchr-test.c | 2 +- {include => testcode/lib}/unittest.h | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename {include => testcode/lib}/unittest.h (100%) diff --git a/testcode/lib/strcat-test.c b/testcode/lib/strcat-test.c index 2e00b80cb..58119e27a 100644 --- a/testcode/lib/strcat-test.c +++ b/testcode/lib/strcat-test.c @@ -1,5 +1,5 @@ -#include <unittest.h> #include <string.h> +#include "unittest.h" #define SourceStringSize 257 // test correct page passing (>256) diff --git a/testcode/lib/strrchr-test.c b/testcode/lib/strrchr-test.c index d2c2a20e4..a72c44db9 100644 --- a/testcode/lib/strrchr-test.c +++ b/testcode/lib/strrchr-test.c @@ -1,5 +1,5 @@ -#include <unittest.h> #include <string.h> +#include "unittest.h" static char TestString[] = "01234567890123456789"; // two times the same string static char Found[256]; diff --git a/include/unittest.h b/testcode/lib/unittest.h similarity index 100% rename from include/unittest.h rename to testcode/lib/unittest.h From 99f3c7d01d598061ff386a3b057b6db43e759eb0 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 1 Mar 2017 06:29:53 -0500 Subject: [PATCH 0245/2161] Fixed a makefile: "yaccdbg.c" includes "yacc.c". So, yaccdbg must depend on both of them. --- test/ref/Makefile | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/ref/Makefile b/test/ref/Makefile index 09dd96d44..6f0bd1bc1 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -1,4 +1,3 @@ - # makefile for the regression tests that generate output which has to be # compared with reference output @@ -24,7 +23,7 @@ WORKDIR := ..$S..$Stestwrk DIFF := $(WORKDIR)/bdiff CC := gcc -CFLAGS := -O2 -Wall -W -Wextra -fwrapv -fno-strict-overflow +CFLAGS := -O2 -Wall -W -Wextra -funsigned-char -fwrapv -fno-strict-overflow .PHONY: all clean @@ -34,6 +33,11 @@ TESTS := $(foreach option,. .o. .os. .osi. .osir. .oi. .oir. .or.,$(SOURCES:%.c= all: $(REFS) $(TESTS) +# "yaccdbg.c" includes "yacc.c". +# yaccdbg's built files must depend on both of them. + +$(WORKDIR)/yaccdbg.ref: yacc.c + $(WORKDIR)/%.ref: %.c $(CC) $(CFLAGS) $< -o $(WORKDIR)/$*.host $(WORKDIR)$S$*.host > $@ @@ -48,6 +52,8 @@ $(WORKDIR)/switch.%rg: CC65FLAGS += -Wc --all-cdecl $(WORKDIR)/yacc.%rg: CC65FLAGS += -Wc --all-cdecl $(WORKDIR)/yaccdbg%prg: CC65FLAGS += -Wc --all-cdecl +$(WORKDIR)/yaccdbg%prg: yacc.c + $(WORKDIR)/%.prg: %.c $(WORKDIR)/%.ref $(CL65) $(CC65FLAGS) $< -o $@ $(SIM65) $(SIM65FLAGS) $@ > $(WORKDIR)/$*.out From 8f0ea644dddfaf9c41718ff055f4b77f0b8f43ad Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 1 Mar 2017 06:36:25 -0500 Subject: [PATCH 0246/2161] Fixed a pointer-difference, comparison-with-zero expression. Some GCC C compilers can't subtract higher pointers from lower pointers properly, when those pointers must be scaled (because they point to objects that are wider than a char). The scaling is done as unsigned which makes the difference positive instead of negative. So, a broken expression was changed into a direct comparison between the two pointers. --- test/ref/yacc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ref/yacc.c b/test/ref/yacc.c index 5768f80d0..d0b9190e4 100644 --- a/test/ref/yacc.c +++ b/test/ref/yacc.c @@ -562,7 +562,7 @@ yylook() } # ifdef LEXDEBUG - if((*(lsp-1)-yysvec-1)<0) + if (*(lsp-1) < yysvec + 1) { fprintf(yyout,"yylook: stopped (end)\n"); } From 9558ebf86c60339fec73895a70c39292469173a2 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Sat, 4 Mar 2017 10:04:32 +0100 Subject: [PATCH 0247/2161] creativision/crt0.s: enable display interrupts in display controller configuration Otherwise the joystick zero page locations won't get updated. --- libsrc/creativision/crt0.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/creativision/crt0.s b/libsrc/creativision/crt0.s index 6faec38eb..420ac71ef 100644 --- a/libsrc/creativision/crt0.s +++ b/libsrc/creativision/crt0.s @@ -81,7 +81,7 @@ irq2: jmp BIOS_IRQ2_ADDR ; VDP Setup ; This sets to Graphics Mode 1 .byte $00 ; Register 0 - .byte $C0 ; Register 1 16K RAM, Active Display, Mode 1 + .byte $E0 ; Register 1 16K RAM, Active Display, Mode 1, VBI enabled .byte $04 ; Register 2 Name Table at $1000 - $12FF .byte $60 ; Register 3 Colour Table at $1800 - $181F .byte $00 ; Register 4 Pattern Table at $0000 - $07FF From 81115aa82625f2b7e773b29844a3a7af589cdb95 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sun, 5 Mar 2017 02:09:12 +0100 Subject: [PATCH 0248/2161] Added further optimizations and unit tests. --- libsrc/common/memmove.s | 11 +-- libsrc/common/strcat.s | 6 +- libsrc/common/strchr.s | 6 +- libsrc/common/strcspn.s | 78 +++++++-------- libsrc/common/strlen.s | 5 +- libsrc/common/strncat.s | 96 ++++++++++--------- libsrc/common/strspn.s | 80 ++++++++-------- libsrc/runtime/axlong.s | 16 ++-- test/val/{atoi-test.c => lib_common_atoi.c} | 0 test/val/lib_common_memmove.c | 61 ++++++++++++ .../val/lib_common_strcat.c | 2 - .../val/lib_common_strchr.c | 39 +++----- test/val/lib_common_strcspn.c | 26 +++++ test/val/lib_common_strncat.c | 54 +++++++++++ .../val/{strtol-test.c => lib_common_strol.c} | 0 .../val/lib_common_strrchr.c | 0 test/val/lib_common_strspn.c | 24 +++++ .../{strtoul-test.c => lib_common_strtoul.c} | 0 {testcode/lib => test/val}/unittest.h | 0 19 files changed, 327 insertions(+), 177 deletions(-) rename test/val/{atoi-test.c => lib_common_atoi.c} (100%) create mode 100644 test/val/lib_common_memmove.c rename testcode/lib/strcat-test.c => test/val/lib_common_strcat.c (99%) rename testcode/lib/strchr-test.c => test/val/lib_common_strchr.c (50%) create mode 100644 test/val/lib_common_strcspn.c create mode 100644 test/val/lib_common_strncat.c rename test/val/{strtol-test.c => lib_common_strol.c} (100%) rename testcode/lib/strrchr-test.c => test/val/lib_common_strrchr.c (100%) create mode 100644 test/val/lib_common_strspn.c rename test/val/{strtoul-test.c => lib_common_strtoul.c} (100%) rename {testcode/lib => test/val}/unittest.h (100%) diff --git a/libsrc/common/memmove.s b/libsrc/common/memmove.s index 9c33124f1..666447cd8 100644 --- a/libsrc/common/memmove.s +++ b/libsrc/common/memmove.s @@ -1,6 +1,6 @@ ; ; 2003-08-20, Ullrich von Bassewitz -; 2009-09-13, Christian Krueger -- performance increase (about 20%) +; 2009-09-13, Christian Krueger -- performance increase (about 20%), 2013-07-25 improved unrolling ; 2015-10-23, Greg King ; ; void* __fastcall__ memmove (void* dest, const void* src, size_t size); @@ -61,13 +61,10 @@ PageSizeCopy: ; assert Y = 0 dec ptr1+1 ; adjust base... dec ptr2+1 dey ; in entry case: 0 -> FF - lda (ptr1),y ; need to copy this 'intro byte' - sta (ptr2),y ; to 'land' later on Y=0! (as a result of the '.repeat'-block!) - dey ; FF ->FE @copyBytes: - .repeat 2 ; Unroll this a bit to make it faster... - lda (ptr1),y - sta (ptr2),y + .repeat 3 ; unroll this a bit to make it faster... + lda (ptr1),y ; important: unrolling three times gives a nice + sta (ptr2),y ; 255/3 = 85 loop which ends at 0 dey .endrepeat @copyEntry: ; in entry case: 0 -> FF diff --git a/libsrc/common/strcat.s b/libsrc/common/strcat.s index 9be65386f..74fef0759 100644 --- a/libsrc/common/strcat.s +++ b/libsrc/common/strcat.s @@ -1,6 +1,6 @@ ; ; Ullrich von Bassewitz, 31.05.1998 -; Christian Krueger: 2013-Jul-24, minor optimization +; Christian Krueger: 2013-Jul-24, minor optimizations ; ; char* strcat (char* dest, const char* src); ; @@ -15,8 +15,12 @@ _strcat: jsr popax ; Get dest sta tmp3 ; Remember for function return tay +.if (.cpu .bitand ::CPU_ISET_65SC02) + stz ptr2 +.else lda #0 sta ptr2 ; access from page start, y contains low byte +.endif stx ptr2+1 findEndOfDest: diff --git a/libsrc/common/strchr.s b/libsrc/common/strchr.s index 0bd55d0e1..48bb8822b 100644 --- a/libsrc/common/strchr.s +++ b/libsrc/common/strchr.s @@ -14,8 +14,12 @@ _strchr: jsr popax ; get s tay ; low byte of pointer to y stx ptr1+1 +.if (.cpu .bitand ::CPU_ISET_65SC02) + stz ptr1 +.else lda #0 - sta ptr1 ; ptr access page wise + sta ptr1 ; access from page start, y contains low byte +.endif Loop: lda (ptr1),y ; Get next char beq EOS ; Jump on end of string diff --git a/libsrc/common/strcspn.s b/libsrc/common/strcspn.s index 8fd567ae4..3f7b42ed1 100644 --- a/libsrc/common/strcspn.s +++ b/libsrc/common/strcspn.s @@ -1,54 +1,54 @@ ; ; Ullrich von Bassewitz, 11.06.1998 +; Christian Krueger: 05-Aug-2013, optimization ; ; size_t strcspn (const char* s1, const char* s2); ; .export _strcspn - .import popax - .importzp ptr1, ptr2, tmp1, tmp2, tmp3 + .import popax, _strlen + .importzp ptr1, ptr2, tmp1, tmp2 _strcspn: - sta ptr2 ; Save s2 - stx ptr2+1 - jsr popax ; Get s1 - sta ptr1 - stx ptr1+1 - ldx #0 ; low counter byte - stx tmp1 ; high counter byte - ldy #$00 + jsr _strlen ; get length in a/x and transfer s2 to ptr1 + ; Note: It does not make sense to + ; have more than 255 test chars, so + ; we don't support a high byte here! (ptr1+1 is + ; also unchanged in strlen then (important!)) + ; -> the original implementation also + ; ignored this case -L1: lda (ptr1),y ; get next char from s1 - beq L6 ; jump if done - sta tmp2 ; save char + sta tmp1 ; tmp1 = strlen of test chars + jsr popax ; get and save s1 + sta ptr2 ; to ptr2 + stx ptr2+1 + ldx #0 ; low counter byte + stx tmp2 ; high counter byte + +loadChar: + ldy #0 + lda (ptr2),y ; get next char from s1 + beq leave ; handly byte of s1 +advance: + inc ptr2 ; advance string position to test + bne check + inc ptr2+1 + dey ; correct next iny (faster/shorter than bne...) + +checkNext: iny - bne L2 - inc ptr1+1 -L2: sty tmp3 ; save index into s1 +check: cpy tmp1 ; compare with length of test character string + beq endOfTestChars + cmp (ptr1),y ; found matching char? + bne checkNext - ldy #0 ; get index into s2 -L3: lda (ptr2),y ; - beq L4 ; jump if done - cmp tmp2 - beq L6 - iny - bne L3 - -; The character was not found in s2. Increment the counter and start over - -L4: ldy tmp3 ; reload index - inx - bne L1 - inc tmp1 - bne L1 - -; The character was found, or we reached the end of s1. Return count of -; characters - -L6: txa ; get low counter byte - ldx tmp1 ; get high counter byte +leave: txa ; restore position of finding + ldx tmp2 ; and return rts - - +endOfTestChars: + inx + bne loadChar + inc tmp2 + bne loadChar ; like bra... diff --git a/libsrc/common/strlen.s b/libsrc/common/strlen.s index b583eea50..1a51edb11 100644 --- a/libsrc/common/strlen.s +++ b/libsrc/common/strlen.s @@ -1,6 +1,10 @@ ; ; Ullrich von Bassewitz, 31.05.1998 ; +; Note: strspn & strcspn call internally this function and rely on +; the usage of only ptr1 here! Keep in mind when appling changes +; and check the other implementations too! +; ; int strlen (const char* s); ; @@ -23,4 +27,3 @@ L1: lda (ptr1),y L9: tya ; get low byte of counter, hi's all set rts - diff --git a/libsrc/common/strncat.s b/libsrc/common/strncat.s index b7bb04b2a..42717853f 100644 --- a/libsrc/common/strncat.s +++ b/libsrc/common/strncat.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 31.05.1998 +; Christian Krueger: 12-Aug-2013, minor optimizations ; ; char* strncat (char* dest, const char* src, size_t n); ; @@ -9,64 +10,65 @@ .importzp ptr1, ptr2, ptr3, tmp1, tmp2 _strncat: - eor #$FF ; one's complement to count upwards - sta tmp1 - txa - eor #$FF - sta tmp2 - jsr popax ; get src - sta ptr1 - stx ptr1+1 - jsr popax ; get dest - sta ptr2 - stx ptr2+1 - sta ptr3 ; remember for function return - stx ptr3+1 - ldy #0 + eor #$FF ; one's complement to count upwards + sta tmp1 + txa + eor #$FF + sta tmp2 + + jsr popax ; get src + sta ptr1 + stx ptr1+1 + + 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 +.else + 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, get offset in y into pointer - -L2: tya - clc - adc ptr2 - sta ptr2 - bcc L3 - inc ptr2+1 +; end found, apply offset to dest ptr and reset y +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: inx - bne L5 - inc 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: inx + bne L5 + inc 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/common/strspn.s b/libsrc/common/strspn.s index f8b8fff2a..3316f0dab 100644 --- a/libsrc/common/strspn.s +++ b/libsrc/common/strspn.s @@ -1,56 +1,54 @@ ; ; Ullrich von Bassewitz, 11.06.1998 +; Christian Krueger: 08-Aug-2013, optimization ; ; size_t strspn (const char* s1, const char* s2); ; .export _strspn - .import popax - .importzp ptr1, ptr2, tmp1, tmp2, tmp3 + .import popax, _strlen + .importzp ptr1, ptr2, tmp1, tmp2 _strspn: - sta ptr2 ; Save s2 - stx ptr2+1 - jsr popax ; get s1 - sta ptr1 - stx ptr1+1 - ldx #0 ; low counter byte - stx tmp1 ; high counter byte - ldy #$00 + jsr _strlen ; get length in a/x and transfer s2 to ptr1 + ; Note: It does not make sense to + ; have more than 255 test chars, so + ; we don't support a high byte here! (ptr1+1 is + ; also unchanged in strlen then (important!)) + ; -> the original implementation also + ; ignored this case -L1: lda (ptr1),y ; get next char from s1 - beq L6 ; jump if done - sta tmp2 ; save char + sta tmp1 ; tmp1 = strlen of test chars + jsr popax ; get and save s1 + sta ptr2 ; to ptr2 + stx ptr2+1 + ldx #0 ; low counter byte + stx tmp2 ; high counter byte + +loadChar: + ldy #0 + lda (ptr2),y ; get next char from s1 + beq leave ; handly byte of s1 +advance: + inc ptr2 ; advance string position to test + bne check + inc ptr2+1 + dey ; correct next iny (faster/shorter than bne...) + +checkNext: iny - bne L2 - inc ptr1+1 -L2: sty tmp3 ; save index into s1 +check: cpy tmp1 ; compare with length of test character string + beq leave + cmp (ptr1),y ; found matching char? + bne checkNext - ldy #0 ; get index into s2 -L3: lda (ptr2),y ; - beq L6 ; jump if done - cmp tmp2 - beq L4 - iny - bne L3 - -; The character was found in s2. Increment the counter and start over - -L4: ldy tmp3 ; reload index +foundTestChar: inx - bne L1 - inc tmp1 - bne L1 + bne loadChar + inc tmp2 + bne loadChar ; like bra... -; The character was not found, or we reached the end of s1. Return count of -; characters - -L6: txa ; get low counter byte - ldx tmp1 ; get high counter byte +leave: txa ; restore position of finding + ldx tmp2 ; and return rts - - - - - - + \ No newline at end of file diff --git a/libsrc/runtime/axlong.s b/libsrc/runtime/axlong.s index 6d97b5025..02d0a825c 100644 --- a/libsrc/runtime/axlong.s +++ b/libsrc/runtime/axlong.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 25.10.2000 +; Christian Krueger, 02-Mar-2017, some bytes saved ; ; CC65 runtime: Convert int in ax into a long ; @@ -9,18 +10,13 @@ ; Convert AX from int to long in EAX +axlong: ldy #$ff + cpx #$80 ; Positive? + bcs store ; No, apply $FF + axulong: ldy #0 - sty sreg +store: sty sreg sty sreg+1 rts -axlong: cpx #$80 ; Positive? - bcc axulong ; Yes, handle like unsigned type - ldy #$ff - sty sreg - sty sreg+1 - rts - - - diff --git a/test/val/atoi-test.c b/test/val/lib_common_atoi.c similarity index 100% rename from test/val/atoi-test.c rename to test/val/lib_common_atoi.c diff --git a/test/val/lib_common_memmove.c b/test/val/lib_common_memmove.c new file mode 100644 index 000000000..dd5801569 --- /dev/null +++ b/test/val/lib_common_memmove.c @@ -0,0 +1,61 @@ +#include <string.h> +#include "unittest.h" + +#define BufferSize 384 // test correct page passing (>256, multiple of 128 here) + +static char Buffer[BufferSize+3]; // +1 to move up (and down) + + + +TEST +{ + unsigned i, v; + char* p; + + for (i=0; i < BufferSize; ++i) + Buffer[i+1] = (i%128); + + Buffer[0] = 255; // to check if start position is untouched + Buffer[BufferSize+2] = 255; // to check if end position is untouched + + // copy upwards + p = memmove(Buffer+2, Buffer+1, BufferSize); + + // check buffer consistency before target + ASSERT_AreEqual(255, (unsigned)Buffer[0], "%u", "Unexpected value before range!"); + + // check buffer consistency at starting point + ASSERT_AreEqual(0, (unsigned)Buffer[1], "%u", "Unexpected value at range start!"); + + // check buffer consistency after range + ASSERT_AreEqual(255, (unsigned)Buffer[BufferSize+2], "%u", "Unexpected value after range!"); + + // check buffer values + for (i=0; i < BufferSize; ++i) + { + ASSERT_AreEqual(i%128, (unsigned)Buffer[i+2], "%u", "Unexpected value in buffer at position %u!" COMMA i+2); + } + + v = Buffer[BufferSize+1]; // rember value of first untouched end-byte + + // copy downwards + p = memmove(Buffer+1, Buffer+2, BufferSize); + + // check buffer consistency before target + ASSERT_AreEqual(255, (unsigned)Buffer[0], "%u", "Unexpected value before range!"); + + // check buffer consistency at end point + ASSERT_AreEqual(v, (unsigned)Buffer[BufferSize+1], "%u", "Unexpected value at range end!"); + + // check buffer consistency after range + ASSERT_AreEqual(255, (unsigned)Buffer[BufferSize+2], "%u", "Unexpected value after range!"); + + // check buffer values + for (i=0; i < BufferSize; ++i) + { + ASSERT_AreEqual(i%128, (unsigned)Buffer[i+1], "%u", "Unexpected value in buffer at position %u!" COMMA i+1); + } +} +ENDTEST + + diff --git a/testcode/lib/strcat-test.c b/test/val/lib_common_strcat.c similarity index 99% rename from testcode/lib/strcat-test.c rename to test/val/lib_common_strcat.c index 58119e27a..1872053a4 100644 --- a/testcode/lib/strcat-test.c +++ b/test/val/lib_common_strcat.c @@ -52,5 +52,3 @@ TEST } } ENDTEST - - diff --git a/testcode/lib/strchr-test.c b/test/val/lib_common_strchr.c similarity index 50% rename from testcode/lib/strchr-test.c rename to test/val/lib_common_strchr.c index 7aba1de1e..a48d287e5 100644 --- a/testcode/lib/strchr-test.c +++ b/test/val/lib_common_strchr.c @@ -1,7 +1,5 @@ -#include <stdio.h> -#include <stdlib.h> #include <string.h> - +#include "unittest.h" /* Test string. Must NOT have duplicate characters! */ @@ -11,49 +9,34 @@ static char Found[256]; -int main (void) +TEST { unsigned Len; unsigned I; char* P; - /* Print a header */ - printf ("strchr(): "); - /* Get the length of the string */ Len = strlen (S); /* Search for all characters in the string, including the terminator */ - for (I = 0; I < Len+1; ++I) { - + for (I = 0; I < Len+1; ++I) + { /* Search for this char */ P = strchr (S, S[I]); /* Check if we found it */ - if (P == 0 || (P - S) != I) { - printf ("Failed for code 0x%02X, offset %u!\n", S[I], I); - printf ("P = %04X offset = %04X\n", P, P-S); - exit (EXIT_FAILURE); - } - + ASSERT_IsFalse(P == 0 || (P - S) != I, "For code 0x%02X, offset %u!\nP = %04X offset = %04X\n" COMMA S[I] COMMA I COMMA P COMMA P-S); /* Mark the char as checked */ Found[S[I]] = 1; } /* Search for all other characters and make sure they aren't found */ - for (I = 0; I < 256; ++I) { - if (Found[I] == 0) { - if (strchr (S, (char)I) != 0) { - printf ("Failed for code 0x%02X\n", I); - exit (EXIT_FAILURE); - } + for (I = 0; I < 256; ++I) + { + if (Found[I] == 0) + { + ASSERT_IsFalse(strchr (S, (char)I), "Failed for code 0x%02X\n" COMMA I); } } - - /* Test passed */ - printf ("Passed\n"); - return EXIT_SUCCESS; } - - - +ENDTEST diff --git a/test/val/lib_common_strcspn.c b/test/val/lib_common_strcspn.c new file mode 100644 index 000000000..10935a78e --- /dev/null +++ b/test/val/lib_common_strcspn.c @@ -0,0 +1,26 @@ +#include <string.h> +#include "unittest.h" + +#define EstimatedStringSize 384 // test correct page passing (>256) + +static char EstimatedString[EstimatedStringSize+1]; // +1 room for terminating null +static char* EmptyTestChars=""; // strlen equivalent... +static char* TestChars="1234567890"; // we like to find numbers + +TEST +{ + unsigned i; + + for (i=0; i < EstimatedStringSize; ++i) + EstimatedString[i] = (i%26)+'A'; // put ABCD... into the string to be estimated + + ASSERT_AreEqual(strlen(EstimatedString), strcspn(EstimatedString, TestChars), "%u", "Unxpected position returned for non-participant case!"); + + EstimatedString[EstimatedStringSize/2] = TestChars[strlen(TestChars-1)]; + ASSERT_AreEqual(EstimatedStringSize/2, strcspn(EstimatedString, TestChars), "%u", "Unxpected position returned for participant case!"); + + ASSERT_AreEqual(strlen(EstimatedString), strcspn(EstimatedString, EmptyTestChars), "%u", "Unxpected position returned for empty test case!"); +} +ENDTEST + + diff --git a/test/val/lib_common_strncat.c b/test/val/lib_common_strncat.c new file mode 100644 index 000000000..dd6df9147 --- /dev/null +++ b/test/val/lib_common_strncat.c @@ -0,0 +1,54 @@ +#include <string.h> +#include "unittest.h" + +#define SourceStringSize 384 // test correct page passing (>256, multiple of 128 here) + +static char SourceString[SourceStringSize+1]; // +1 room for terminating null +static char DestinationString[2*SourceStringSize+1]; // will contain two times the source buffer + + +TEST +{ + unsigned i; + char* p; + + for (i=0; i < SourceStringSize; ++i) + SourceString[i] = (i%128)+1; + + SourceString[i] = 0; + + ASSERT_AreEqual(SourceStringSize, strlen(SourceString), "%u", "Source string initialization or 'strlen()' problem!"); + + /* Ensure empty destination string */ + DestinationString[0] = 0; + + ASSERT_AreEqual(0, strlen(DestinationString), "%u", "Destination string initialization or 'strlen()' problem!"); + + /* Test "unlimted" concatenation to empty buffer */ + + strncat(DestinationString, SourceString, 1024); + + ASSERT_AreEqual(SourceStringSize, strlen(DestinationString), "%u", "Unexpected string length while string concatenation to empty buffer!"); + + /* Test limited concatenation to non empty buffer */ + + p = strncat(DestinationString, SourceString, 128); + + ASSERT_AreEqual(SourceStringSize+128, strlen(DestinationString), "%u", "Unexpected string length while string concatenation to non-empty buffer!"); + + /* Test return value */ + + ASSERT_IsTrue(p == DestinationString, "Invalid return value!"); + + /* Test contents */ + + for(i=0; i < strlen(DestinationString); ++i) + { + unsigned current = DestinationString[i]; + unsigned expected = (i%128)+1; + ASSERT_AreEqual(expected, current, "%u", "Unexpected destination buffer contents at position %u!\n" COMMA i); + } +} +ENDTEST + + diff --git a/test/val/strtol-test.c b/test/val/lib_common_strol.c similarity index 100% rename from test/val/strtol-test.c rename to test/val/lib_common_strol.c diff --git a/testcode/lib/strrchr-test.c b/test/val/lib_common_strrchr.c similarity index 100% rename from testcode/lib/strrchr-test.c rename to test/val/lib_common_strrchr.c diff --git a/test/val/lib_common_strspn.c b/test/val/lib_common_strspn.c new file mode 100644 index 000000000..96a006469 --- /dev/null +++ b/test/val/lib_common_strspn.c @@ -0,0 +1,24 @@ +#include <string.h> +#include "unittest.h" + +#define EstimatedStringSize 384 // test correct page passing (>256) + +static char EstimatedString[EstimatedStringSize+1]; // +1 room for terminating null +static char* EmptyTestChars=""; // empty test case... +static char* TestChars="1234567890"; // we like to find numbers + +TEST +{ + unsigned i; + + for (i=0; i < EstimatedStringSize; ++i) + EstimatedString[i] = (i%10)+'0'; // put 0123... into the string to be estimated + + ASSERT_AreEqual(strlen(EstimatedString), strspn(EstimatedString, TestChars), "%u", "Unxpected position returned for all participant case!"); + + EstimatedString[EstimatedStringSize/2] = 'X'; + ASSERT_AreEqual(EstimatedStringSize/2, strspn(EstimatedString, TestChars), "%u", "Unxpected position returned for breaking case!"); + + ASSERT_AreEqual(0, strspn(EstimatedString, EmptyTestChars), "%u", "Unxpected position returned for empty test case!"); +} +ENDTEST diff --git a/test/val/strtoul-test.c b/test/val/lib_common_strtoul.c similarity index 100% rename from test/val/strtoul-test.c rename to test/val/lib_common_strtoul.c diff --git a/testcode/lib/unittest.h b/test/val/unittest.h similarity index 100% rename from testcode/lib/unittest.h rename to test/val/unittest.h From 8d1b80e6fd7c4f3feef1fe7f56a321966bf59cd8 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sun, 5 Mar 2017 11:38:55 +0100 Subject: [PATCH 0249/2161] Fixed CPU-flag usage which fails on build server?! --- libsrc/common/strcat.s | 1 + libsrc/common/strchr.s | 1 + libsrc/common/strncat.s | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libsrc/common/strcat.s b/libsrc/common/strcat.s index 74fef0759..7dce2f78a 100644 --- a/libsrc/common/strcat.s +++ b/libsrc/common/strcat.s @@ -8,6 +8,7 @@ .export _strcat .import popax .importzp ptr1, ptr2, tmp3 + .macpack cpu _strcat: sta ptr1 ; Save src diff --git a/libsrc/common/strchr.s b/libsrc/common/strchr.s index 48bb8822b..15c743776 100644 --- a/libsrc/common/strchr.s +++ b/libsrc/common/strchr.s @@ -8,6 +8,7 @@ .export _strchr .import popax .importzp ptr1, tmp1 + .macpack cpu _strchr: sta tmp1 ; Save c diff --git a/libsrc/common/strncat.s b/libsrc/common/strncat.s index 42717853f..e0fa39cc0 100644 --- a/libsrc/common/strncat.s +++ b/libsrc/common/strncat.s @@ -8,7 +8,8 @@ .export _strncat .import popax .importzp ptr1, ptr2, ptr3, tmp1, tmp2 - + .macpack cpu + _strncat: eor #$FF ; one's complement to count upwards sta tmp1 From 371e8efb7966268dbb86668f15813a36dd26d32e Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Tue, 7 Mar 2017 19:16:31 +0100 Subject: [PATCH 0250/2161] temporarily disable optimizations altogether until a fine grain control is implemented on Makefile level only disabling the compiler option -Os --- test/val/lib_common_memmove.c | 4 ++++ test/val/lib_common_strcat.c | 4 ++++ test/val/lib_common_strcspn.c | 4 ++++ test/val/lib_common_strncat.c | 4 ++++ test/val/lib_common_strspn.c | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/test/val/lib_common_memmove.c b/test/val/lib_common_memmove.c index dd5801569..6c04e1951 100644 --- a/test/val/lib_common_memmove.c +++ b/test/val/lib_common_memmove.c @@ -1,3 +1,7 @@ +// temporarily disable optimizations altogether until a fine grain control +// is implemented on Makefile level only disabling the compiler option -Os +#pragma optimize (off) + #include <string.h> #include "unittest.h" diff --git a/test/val/lib_common_strcat.c b/test/val/lib_common_strcat.c index 1872053a4..6389d5651 100644 --- a/test/val/lib_common_strcat.c +++ b/test/val/lib_common_strcat.c @@ -1,3 +1,7 @@ +// temporarily disable optimizations altogether until a fine grain control +// is implemented on Makefile level only disabling the compiler option -Os +#pragma optimize (off) + #include <string.h> #include "unittest.h" diff --git a/test/val/lib_common_strcspn.c b/test/val/lib_common_strcspn.c index 10935a78e..06838c435 100644 --- a/test/val/lib_common_strcspn.c +++ b/test/val/lib_common_strcspn.c @@ -1,3 +1,7 @@ +// temporarily disable optimizations altogether until a fine grain control +// is implemented on Makefile level only disabling the compiler option -Os +#pragma optimize (off) + #include <string.h> #include "unittest.h" diff --git a/test/val/lib_common_strncat.c b/test/val/lib_common_strncat.c index dd6df9147..84d904fa0 100644 --- a/test/val/lib_common_strncat.c +++ b/test/val/lib_common_strncat.c @@ -1,3 +1,7 @@ +// temporarily disable optimizations altogether until a fine grain control +// is implemented on Makefile level only disabling the compiler option -Os +#pragma optimize (off) + #include <string.h> #include "unittest.h" diff --git a/test/val/lib_common_strspn.c b/test/val/lib_common_strspn.c index 96a006469..693a1136a 100644 --- a/test/val/lib_common_strspn.c +++ b/test/val/lib_common_strspn.c @@ -1,3 +1,7 @@ +// temporarily disable optimizations altogether until a fine grain control +// is implemented on Makefile level only disabling the compiler option -Os +#pragma optimize (off) + #include <string.h> #include "unittest.h" From 97e3472c8701c2b7b89e8d4d98f693a25277c187 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 8 Mar 2017 13:16:40 +0100 Subject: [PATCH 0251/2161] creativision.inc: add symbolic names for joystick direction values --- asminc/creativision.inc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/asminc/creativision.inc b/asminc/creativision.inc index 59b26101b..83a63ba07 100644 --- a/asminc/creativision.inc +++ b/asminc/creativision.inc @@ -36,6 +36,24 @@ ZP_JOY1_DIR = $13 ZP_JOY0_BUTTONS = $16 ZP_JOY1_BUTTONS = $17 +;** Joystick direction values (ZP_JOY0_DIR/ZP_JOY1_DIR) +JOY_N = $49 +JOY_NNE = $48 +JOY_NE = $47 +JOY_ENE = $46 +JOY_E = $45 +JOY_ESE = $44 +JOY_SE = $43 +JOY_SSE = $42 +JOY_S = $41 +JOY_SSW = $40 +JOY_SW = $4F +JOY_WSW = $4E +JOY_W = $4D +JOY_WNW = $4C +JOY_NW = $4B +JOY_NNW = $4A + ;** BIOS BIOS_IRQ1_ADDR = $FF3F BIOS_IRQ2_ADDR = $FF52 From 64c4cef90140e97e018b82ddb37760af79df5a17 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 8 Mar 2017 13:19:53 +0100 Subject: [PATCH 0252/2161] Implement diagonal direction handling in creativision joystick driver. --- libsrc/creativision/joy/creativision-stdjoy.s | 274 +++++++++++------- 1 file changed, 166 insertions(+), 108 deletions(-) diff --git a/libsrc/creativision/joy/creativision-stdjoy.s b/libsrc/creativision/joy/creativision-stdjoy.s index 37b927d08..3f167464a 100644 --- a/libsrc/creativision/joy/creativision-stdjoy.s +++ b/libsrc/creativision/joy/creativision-stdjoy.s @@ -1,60 +1,69 @@ ; ; Standard joystick driver for the Creativision. ; -; Christian Groessler, 2017-02-06 +; Christian Groessler, 2017-03-08 ; - .include "zeropage.inc" + .include "zeropage.inc" - .include "joy-kernel.inc" - .include "joy-error.inc" - .include "creativision.inc" + .include "joy-kernel.inc" + .include "joy-error.inc" + .include "creativision.inc" - .macpack module + .macpack module ; ------------------------------------------------------------------------ ; Header. Includes jump table - module_header _creativisionstd_joy + module_header _creativisionstd_joy ; Driver signature - .byte $6A, $6F, $79 ; "joy" - .byte JOY_API_VERSION ; Driver API version number + .byte $6A, $6F, $79 ; "joy" + .byte JOY_API_VERSION ; Driver API version number ; Library reference - .addr $0000 + .addr $0000 -; Button state masks (8 values) +; Symbolic names for joystick masks (similar names like the defines in joystick.h, but not related to them) - .byte $10 ; JOY_UP - .byte $04 ; JOY_DOWN - .byte $20 ; JOY_LEFT - .byte $08 ; JOY_RIGHT - .byte $01 ; JOY_FIRE (button #1) - .byte $02 ; JOY_FIRE2 (button #2) - .byte $00 ; Future expansion - .byte $00 ; Future expansion +JOY_UP = $10 +JOY_DOWN = $04 +JOY_LEFT = $20 +JOY_RIGHT = $08 +JOY_FIRE = $01 +JOY_FIRE2 = $02 + +; Joystick state masks (8 values) + + .byte JOY_UP + .byte JOY_DOWN + .byte JOY_LEFT + .byte JOY_RIGHT + .byte JOY_FIRE + .byte JOY_FIRE2 + .byte $00 ; Future expansion + .byte $00 ; Future expansion ; Jump table. - .addr INSTALL - .addr UNINSTALL - .addr COUNT - .addr READJOY - .addr 0 ; IRQ entry not used + .addr INSTALL + .addr UNINSTALL + .addr COUNT + .addr READJOY + .addr 0 ; IRQ entry not used ; ------------------------------------------------------------------------ ; Constants -JOY_COUNT = 2 ; Number of joysticks we support +JOY_COUNT = 2 ; Number of joysticks we support ; ------------------------------------------------------------------------ ; Code - .code + .code ; ------------------------------------------------------------------------ ; INSTALL routine. Is called after the driver is loaded into memory. If @@ -63,131 +72,180 @@ JOY_COUNT = 2 ; Number of joysticks we support ; Must return an JOY_ERR_xx code in a/x. ; -INSTALL: - lda #JOY_ERR_OK - ldx #0 -; rts ; Fall through +INSTALL: lda #JOY_ERR_OK + ldx #0 +; rts ; Fall through ; ------------------------------------------------------------------------ ; UNINSTALL routine. Is called before the driver is removed from memory. ; Can do cleanup or whatever. Must not return anything. ; -UNINSTALL: - rts +UNINSTALL: rts ; ------------------------------------------------------------------------ ; COUNT: Return the total number of available joysticks in a/x. ; -COUNT: - lda #<JOY_COUNT - ldx #>JOY_COUNT - rts +COUNT: lda #<JOY_COUNT + ldx #>JOY_COUNT + rts ; ------------------------------------------------------------------------ ; READ: Read a particular joystick passed in A. ; -READJOY: - and #1 ; fix joystick number - bne READJOY_1 ; read right joystick +READJOY: and #1 ; fix joystick number + bne READJOY_1 ; read right joystick ; Read left joystick - ldx ZP_JOY0_DIR - lda ZP_JOY0_BUTTONS - jmp convert ; convert joystick state to sane cc65 values + ldx ZP_JOY0_DIR + lda ZP_JOY0_BUTTONS + jmp convert ; convert joystick state to cc65 values ; Read right joystick -READJOY_1: - - ldx ZP_JOY1_DIR - lda ZP_JOY1_BUTTONS - lsr a - lsr a - ;jmp convert ; convert joystick state to sane cc65 values - ; fall thru... +READJOY_1: ldx ZP_JOY1_DIR + lda ZP_JOY1_BUTTONS + lsr a + lsr a + ;jmp convert ; convert joystick state to cc65 values + ; fall thru... ; ------------------------------------------------------------------------ ; convert: make runtime lib compatible values -; A - buttons -; X - direction +; inputs: +; A - buttons +; X - direction ; convert: - ldy #0 - sty retval ; initialize return value ; ------ ; buttons: - ; Port values are for the left hand joystick (right hand joystick - ; values were shifted to the right to be identical). - ; Why are there two bits indicating a pressed trigger? - ; According to the "Second book of programs for the Dick Smith Wizard" - ; (pg. 88ff), the left hand fire button gives the value of - ; %00010001 and the right hand button gives %00100010 - ; Why two bits? Am I missing something? Can there be cases that just - ; one of those bits is set? - ; We just test if any of those two bits is not zero... +; Port values are for the left hand joystick (right hand joystick +; values were shifted to the right to be identical). +; Why are there two bits indicating a pressed trigger? +; According to the "Second book of programs for the Dick Smith Wizard" +; (pg. 88ff), the left hand fire button gives the value of +; %00010001 and the right hand button gives %00100010 +; Why two bits? Can there be cases that just one of those bits is set? +; Until these questions have been answered, we only use the lower two +; bits and ignore the upper ones... - tay - and #%00010001 - beq cnv_1 - - inc retval ; left button pressed - -cnv_1: tya - and #%00100010 - beq cnv_2 - - lda #$02 - ora retval - sta retval ; right button pressed + and #%00000011 ; button status came in in A, strip high bits + sta retval ; initialize 'retval' with button status ; ------ ; direction: -cnv_2: txa - ; tested with https://sourceforge.net/projects/creativisionemulator - ; $49 - %01001001 - up - ; $41 - %01000001 - down - ; $4D - %01001101 - left - ; $45 - %01000101 - right - ; - ; are these correct? "Second book of programs for the Dick Smith Wizard" pg. 85 says something different - ; ignored for now... - ; $85 - %10000101 - up + right - ; $8D - %10001101 - down + left - ; $89 - %10001001 - up + left - ; $85 - %10000101 - down + right (emulator bug?) +; CV has a 16-direction joystick +; +; port values: (compass points) +; N - $49 - %01001001 +; NNE - $48 - %01001000 +; NE - $47 - %01000111 +; ENE - $46 - %01000110 +; E - $45 - %01000101 +; ESE - $44 - %01000100 +; SE - $43 - %01000011 +; SSE - $42 - %01000010 +; S - $41 - %01000001 +; SSW - $40 - %01000000 +; SW - $4F - %01001111 +; WSW - $4E - %01001110 +; W - $4D - %01001101 +; WNW - $4C - %01001100 +; NW - $4B - %01001011 +; NNW - $4A - %01001010 +; center - $00 - %00000000 +; +; mapping to cc65 definitions (4-direction joystick with 8 possible directions thru combinations) +; N, E, S, W -> JOY_UP, JOY_RIGHT, JOY_DOWN, JOY_LEFT +; NE, SE, SW, NW -> (JOY_UP | JOY_RIGHT), (JOY_DOWN | JOY_RIGHT), (JOY_DOWN | JOY_LEFT), (JOY_UP | JOY_LEFT) +; NNE, ENE, ESE, SSE, SSW, WSW, WNW, NNW: +; toggle between straight and diagonal direction for every call, e.g. +; NNE: +; call to READJOY: return JOY_UP | JOY_RIGHT +; call to READJOY: return JOY_UP +; call to READJOY: return JOY_UP | JOY_RIGHT +; call to READJOY: return JOY_UP +; call to READJOY: return JOY_UP | JOY_RIGHT +; etc... - bit testbit ; bit #0 set? - beq done ; no, no direction + txa ; move direction status into A + beq done ; center position (no bits are set), nothing to do - and #%00001100 ; mask out other bits - lsr a - lsr a - tax - lda #%00000100 ; init bitmask -loop: dex - bmi done2 - asl a - bne loop + and #$0F ; get rid of the "$40" bit + bit bit0 ; is it a "three letter" direction (NNE, ENE, etc.)? + beq special ; yes (bit #0 is zero) -done2: ora retval - rts + lsr a ; create index into table + tax + lda dirtable,x +done: ora retval ; include "button" bits + ldx #0 + rts -done: lda retval - rts +; NNE, ENE, ESE, SSE, SSW, WSW, WNW, NNW + +special: lsr a + tax + + lda toggler ; toggle the toggler + eor #$01 + sta toggler + bne spec_1 ; toggler is 1, use spectable_1 entry + + lda spectable_0,x ; toggler is 0, use spectable_0 entry + bne done ; jump always + +spec_1: lda spectable_1,x + bne done ; jump always ; ------------------------------------------------------------------------ ; - .data -testbit:.byte $01 + .rodata + + ; a mapping table of "port values" to "cc65 values" + ; port value had been shifted one bit to the right (range 0..7) +dirtable: .byte JOY_DOWN ; S + .byte JOY_DOWN | JOY_RIGHT ; SE + .byte JOY_RIGHT ; E + .byte JOY_UP | JOY_RIGHT ; NE + .byte JOY_UP ; N + .byte JOY_UP | JOY_LEFT ; NW + .byte JOY_LEFT ; W + .byte JOY_DOWN | JOY_LEFT ; SW + + ; two "special" mapping tables for three-letter directions (NNE, etc.) +spectable_0: .byte JOY_DOWN ; SSW + .byte JOY_DOWN ; SSE + .byte JOY_RIGHT ; ESE + .byte JOY_RIGHT ; ENE + .byte JOY_RIGHT ; NNE + .byte JOY_UP ; NNW + .byte JOY_LEFT ; WNW + .byte JOY_LEFT ; WSW + +spectable_1: .byte JOY_DOWN | JOY_LEFT ; SSW + .byte JOY_DOWN | JOY_RIGHT ; SSE + .byte JOY_DOWN | JOY_RIGHT ; ESE + .byte JOY_UP | JOY_RIGHT ; ENE + .byte JOY_UP | JOY_RIGHT ; NNE + .byte JOY_UP | JOY_LEFT ; NNW + .byte JOY_UP | JOY_LEFT ; WNW + .byte JOY_DOWN | JOY_LEFT ; WSW ; ------------------------------------------------------------------------ ; - .bss -retval: .res 0 +bit0: .byte $01 + +; ------------------------------------------------------------------------ +; + .bss +toggler: .res 1 +retval: .res 1 + + .end From b332064cb5f2cd42e1c495d8e1cefcfd735d088e Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 9 Mar 2017 14:39:08 +0100 Subject: [PATCH 0253/2161] Just some minor style fix. --- libsrc/Makefile | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/libsrc/Makefile b/libsrc/Makefile index 54b54860c..cb3517c7e 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -15,24 +15,24 @@ CBMS = c128 \ GEOS = geos-apple \ geos-cbm -TARGETS = apple2 \ - apple2enh \ - atari \ - atarixl \ - atari2600 \ - atari5200 \ - atmos \ +TARGETS = apple2 \ + apple2enh \ + atari \ + atarixl \ + atari2600 \ + atari5200 \ + atmos \ creativision \ - $(CBMS) \ - $(GEOS) \ - gamate \ - lynx \ - nes \ - osic1p \ - pce \ - sim6502 \ - sim65c02 \ - supervision\ + $(CBMS) \ + $(GEOS) \ + gamate \ + lynx \ + nes \ + osic1p \ + pce \ + sim6502 \ + sim65c02 \ + supervision \ telestrat DRVTYPES = emd \ @@ -41,13 +41,13 @@ DRVTYPES = emd \ ser \ tgi -OUTPUTDIRS := lib \ - asminc \ - cfg \ - include \ - $(subst ../,,$(filter-out $(wildcard ../include/*.*),$(wildcard ../include/*)))\ - $(subst ../,,$(wildcard ../target/*/drv/*))\ - $(subst ../,,$(wildcard ../target/*/util))\ +OUTPUTDIRS := lib \ + asminc \ + cfg \ + include \ + $(subst ../,,$(filter-out $(wildcard ../include/*.*),$(wildcard ../include/*))) \ + $(subst ../,,$(wildcard ../target/*/drv/*)) \ + $(subst ../,,$(wildcard ../target/*/util)) .PHONY: all mostlyclean clean install zip lib $(TARGETS) From d2c89d2ba9d0030c538257a74a5d732cbdca6a0b Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Thu, 9 Mar 2017 19:14:31 +0100 Subject: [PATCH 0254/2161] "static int n; int n;" is an error. Fixes test/err/static-4.c regression. --- 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 fdf459873..3275332c5 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -821,7 +821,7 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) } /* An extern declaration must not change the current linkage. */ - if (IsFunc || (Flags & (SC_EXTERN | SC_DEF)) == SC_EXTERN) { + if (IsFunc || (Flags & (SC_EXTERN | SC_STORAGE)) == SC_EXTERN) { Flags &= ~SC_EXTERN; } From ce0cf853867e7f1c51075499c264e7d48e845190 Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Thu, 9 Mar 2017 20:40:20 +0100 Subject: [PATCH 0255/2161] Add regression test for #204. --- test/val/static-fwd-decl.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 test/val/static-fwd-decl.c diff --git a/test/val/static-fwd-decl.c b/test/val/static-fwd-decl.c new file mode 100644 index 000000000..420640d97 --- /dev/null +++ b/test/val/static-fwd-decl.c @@ -0,0 +1,35 @@ +/* + !!DESCRIPTION!! static forward declarations + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Bob Andrews +*/ + +/* + see: https://github.com/cc65/cc65/issues/204 +*/ + +#pragma warn(error, on) + +typedef struct _DIRMENU +{ + const char *name; + struct _DIRMENU *dest; +} DIRMENU; + +static DIRMENU rmenu; + +static DIRMENU lmenu = { + "left", + &rmenu +}; + +static DIRMENU rmenu = { + "right", + &lmenu +}; + +int main(void) +{ + return lmenu.dest == &rmenu && rmenu.dest == &lmenu ? 0 : 1; +} From 6c3873316b31f86b61ea11b67055ac66b2b66ebd Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Thu, 9 Mar 2017 20:49:20 +0100 Subject: [PATCH 0256/2161] Add regression tests for duplicate global/static variables detected by the compiler. --- test/err/duplicate-global.c | 20 ++++++++++++++++++++ test/err/duplicate-static.c | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 test/err/duplicate-global.c create mode 100644 test/err/duplicate-static.c diff --git a/test/err/duplicate-global.c b/test/err/duplicate-global.c new file mode 100644 index 000000000..bd4fcc24a --- /dev/null +++ b/test/err/duplicate-global.c @@ -0,0 +1,20 @@ +/* + !!DESCRIPTION!! duplicate globals + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Piotr Fusik +*/ + +/* + see: https://github.com/cc65/cc65/issues/191 +*/ + +#pragma warn(error, on) + +int n = 0; +int n = 0; /* should give an error */ + +int main(void) +{ + return n; +} diff --git a/test/err/duplicate-static.c b/test/err/duplicate-static.c new file mode 100644 index 000000000..394cc1e09 --- /dev/null +++ b/test/err/duplicate-static.c @@ -0,0 +1,20 @@ +/* + !!DESCRIPTION!! duplicate static variables + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Piotr Fusik +*/ + +/* + see: https://github.com/cc65/cc65/issues/191 +*/ + +#pragma warn(error, on) + +static int n = 0; +static int n = 0; /* should give an error */ + +int main(void) +{ + return n; +} From 05d1b8072b580b1a68e09a76f21c9b8599af7028 Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Thu, 9 Mar 2017 21:18:48 +0100 Subject: [PATCH 0257/2161] Add regression tests for duplicate globals with different linkage. --- test/err/duplicate-global-static.c | 18 ++++++++++++++++++ test/err/duplicate-static-global.c | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 test/err/duplicate-global-static.c create mode 100644 test/err/duplicate-static-global.c diff --git a/test/err/duplicate-global-static.c b/test/err/duplicate-global-static.c new file mode 100644 index 000000000..6aa27f5b7 --- /dev/null +++ b/test/err/duplicate-global-static.c @@ -0,0 +1,18 @@ +/* + !!DESCRIPTION!! global duplicated with static variable + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Piotr Fusik +*/ + +/* + see: https://github.com/cc65/cc65/issues/191 +*/ + +int n = 0; +static int n = 0; /* should give an error */ + +int main(void) +{ + return n; +} diff --git a/test/err/duplicate-static-global.c b/test/err/duplicate-static-global.c new file mode 100644 index 000000000..6e5e70a37 --- /dev/null +++ b/test/err/duplicate-static-global.c @@ -0,0 +1,18 @@ +/* + !!DESCRIPTION!! static duplicated with global variable + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Piotr Fusik +*/ + +/* + see: https://github.com/cc65/cc65/issues/191 +*/ + +static int n = 0; +int n = 0; /* should give an error */ + +int main(void) +{ + return n; +} From 8a81f9c0c842611a9d329ca8902ec3d8ba9a221f Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Fri, 10 Mar 2017 11:21:14 +0100 Subject: [PATCH 0258/2161] Fix line endings (CRLF -> LF) on all affected files. --- asminc/opcodes.inc | 1018 +++++++++++++++++------------------ asminc/smc.inc | 534 +++++++++--------- include/osic1p.h | 94 ++-- include/zlib.h | 344 ++++++------ libsrc/c64/emd/c64-65816.s | 752 +++++++++++++------------- libsrc/osic1p/cgetc.s | 100 ++-- libsrc/osic1p/osic1p.inc | 8 +- libsrc/osic1p/osiscreen.inc | 364 ++++++------- test/ref/divmod.c | 74 +-- test/ref/init.c | 190 +++---- test/ref/pointer2.c | 224 ++++---- test/ref/switch2.c | 514 +++++++++--------- test/ref/varargs.c | 202 +++---- testcode/lib/mul-test.c | 340 ++++++------ 14 files changed, 2379 insertions(+), 2379 deletions(-) diff --git a/asminc/opcodes.inc b/asminc/opcodes.inc index 7c52871d2..96cdefb65 100644 --- a/asminc/opcodes.inc +++ b/asminc/opcodes.inc @@ -1,509 +1,509 @@ -; opcodes.inc -; ca65 6502 - opcode definitions, mainly for self modifying code -; -; Christian Krüger, latest change: 18-Sep-2010 -; -; 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. -; - -; Opcode-Table -; ------------ -; Post fix explanation: -; imm = #$00 -; zp = $00 -; zpx = $00,X -; zpy = $00,Y -; izp = ($00) -; izx = ($00,X) -; izy = ($00),Y -; abs = $0000 -; abx = $0000,X -; aby = $0000,Y -; ind = ($0000) -; iax = ($0000,X) -; rel = $0000 (PC-relative) (supressed here) - -.macpack cpu - -OPC_BRK = $00 -OPC_ORA_izx = $01 -OPC_ORA_zp = $05 -OPC_ASL_zp = $06 -OPC_PHP = $08 -OPC_ORA_imm = $09 -OPC_ASL = $0A -OPC_ORA_abs = $0D -OPC_ASL_abs = $0E - -OPC_BPL = $10 -OPC_ORA_izy = $11 -OPC_ORA_zpx = $15 -OPC_ASL_zpx = $16 -OPC_CLC = $18 -OPC_ORA_aby = $19 -OPC_ORA_abx = $1D -OPC_ASL_abx = $1E - -OPC_JSR_abs = $20 -OPC_AND_izx = $21 -OPC_BIT_zp = $24 -OPC_AND_zp = $25 -OPC_ROL_zp = $26 -OPC_PLP = $28 -OPC_AND_imm = $29 -OPC_ROL = $2A -OPC_BIT_abs = $2C -OPC_AND_abs = $2D -OPC_ROL_abs = $2E - -OPC_BMI = $30 -OPC_AND_izy = $31 -OPC_AND_zpx = $35 -OPC_ROL_zpx = $36 -OPC_SEC = $38 -OPC_AND_aby = $39 -OPC_AND_abx = $3D -OPC_ROL_abx = $3E - - -OPC_RTI = $40 -OPC_EOR_izx = $41 -OPC_EOR_zp = $45 -OPC_LSR_zp = $46 -OPC_PHA = $48 -OPC_EOR_imm = $49 -OPC_LSR = $4A -OPC_JMP_abs = $4C -OPC_EOR_abs = $4D -OPC_LSR_abs = $4E - -OPC_BVC = $50 -OPC_EOR_izy = $51 -OPC_EOR_zpx = $55 -OPC_LSR_zpx = $56 -OPC_CLI = $58 -OPC_EOR_aby = $59 -OPC_EOR_abx = $5D -OPC_LSR_abx = $5E - -OPC_RTS = $60 -OPC_ADC_izx = $61 -OPC_ADC_zp = $65 -OPC_ROR_zp = $66 -OPC_PLA = $68 -OPC_ADC_imm = $69 -OPC_ROR = $6A -OPC_JMP_ind = $6C -OPC_ADC_abs = $6D -OPC_ROR_abs = $6E - -OPC_BVS = $70 -OPC_ADC_izy = $71 -OPC_ADC_zpx = $75 -OPC_ROR_zpx = $76 -OPC_SEI = $78 -OPC_ADC_aby = $79 -OPC_ADC_abx = $7D -OPC_ROR_abx = $7E - -OPC_STA_izx = $81 -OPC_STY_zp = $84 -OPC_STA_zp = $85 -OPC_STX_zp = $86 -OPC_DEY = $88 -OPC_TXA = $8A -OPC_STY_abs = $8C -OPC_STA_abs = $8D -OPC_STX_abs = $8E - -OPC_BCC = $90 -OPC_STA_izy = $91 -OPC_STY_zpx = $94 -OPC_STA_zpx = $95 -OPC_STX_zpy = $96 -OPC_TYA = $98 -OPC_STA_aby = $99 -OPC_TXS = $9A -OPC_STA_abx = $9D - -OPC_LDY_imm = $A0 -OPC_LDA_izx = $A1 -OPC_LDX_imm = $A2 -OPC_LDY_zp = $A4 -OPC_LDA_zp = $A5 -OPC_LDX_zp = $A6 -OPC_TAY = $A8 -OPC_LDA_imm = $A9 -OPC_TAX = $AA -OPC_LDY_abs = $AC -OPC_LDA_abs = $AD -OPC_LDX_abs = $AE - -OPC_BCS = $B0 -OPC_LDA_izy = $B1 -OPC_LDY_zpx = $B4 -OPC_LDA_zpx = $B5 -OPC_LDX_zpy = $B6 -OPC_CLV = $B8 -OPC_LDA_aby = $B9 -OPC_TSX = $BA -OPC_LDY_abx = $BC -OPC_LDA_abx = $BD -OPC_LDX_aby = $BE - -OPC_CPY_imm = $C0 -OPC_CMP_izx = $C1 -OPC_CPY_zp = $C4 -OPC_CMP_zp = $C5 -OPC_DEC_zp = $C6 -OPC_INY = $C8 -OPC_CMP_imm = $C9 -OPC_DEX = $CA -OPC_CPY_abs = $CC -OPC_CMP_abs = $CD -OPC_DEC_abs = $CE - -OPC_BNE = $D0 -OPC_CMP_izy = $D1 -OPC_CMP_zpx = $D5 -OPC_DEC_zpx = $D6 -OPC_CLD = $D8 -OPC_CMP_aby = $D9 -OPC_CMP_abx = $DD -OPC_DEC_abx = $DE - -OPC_CPX_imm = $E0 -OPC_SBC_izx = $E1 -OPC_CPX_zp = $E4 -OPC_SBC_zp = $E5 -OPC_INC_zp = $E6 -OPC_INX = $E8 -OPC_SBC_imm = $E9 -OPC_NOP = $EA -OPC_CPX_abs = $EC -OPC_SBC_abs = $ED -OPC_INC_abs = $EE - - -OPC_BEQ = $F0 -OPC_SBC_izy = $F1 -OPC_SBC_zpx = $F5 -OPC_INC_zpx = $F6 -OPC_SED = $F8 -OPC_SBC_aby = $F9 -OPC_SBC_abx = $FD -OPC_INC_abx = $FE - - -.if (.cpu .bitand ::CPU_ISET_65SC02) - -; OPC_NOP = $02 ; doublet -; OPC_NOP = $03 ; doublet -OPC_TSB_zp = $04 -; OPC_NOP = $0B ; doublet -OPC_TSB_abs = $0C - -OPC_ORA_izp = $12 -; OPC_NOP = $13 ; doublet -OPC_TRB_zp = $14 -OPC_INC = $1A -; OPC_NOP = $1B ; doublet -OPC_TRB_abs = $1C - -; OPC_NOP = $22 ; doublet -; OPC_NOP = $23 ; doublet -; OPC_NOP = $2B ; doublet - -OPC_AND_izp = $32 -; OPC_NOP = $33 ; doublet -OPC_BIT_zpx = $34 -OPC_DEC = $3A -; OPC_NOP = $3B ; doublet -OPC_BIT_abx = $3C - -; OPC_NOP = $42 ; doublet -; OPC_NOP = $43 ; doublet -; OPC_NOP = $44 ; doublet -; OPC_NOP = $4B ; doublet - -OPC_EOR_izp = $52 -; OPC_NOP = $53 ; doublet -; OPC_NOP = $54 ; doublet -; OPC_NOP = $5A ; doublet -; OPC_NOP = $5B ; doublet -OPC_EOR_abx = $5C - -; OPC_NOP = $62 ; doublet -; OPC_NOP = $63 ; doublet -OPC_STZ_zp = $64 -; OPC_NOP = $6B ; doublet - -OPC_ADC_izp = $72 -; OPC_NOP = $73 ; doublet -OPC_STZ_zpx = $74 -OPC_PLY = $7A -; OPC_NOP = $7B ; doublet -OPC_JMP_iax = $7C - -OPC_BRA = $80 -; OPC_NOP = $82 ; doublet -; OPC_NOP = $83 ; doublet -OPC_BIT_imm = $89 -; OPC_NOP = $8B ; doublet - -OPC_STA_izp = $92 -; OPC_NOP = $93 ; doublet -; OPC_NOP = $9B ; doublet -OPC_STZ_abs = $9C -OPC_STZ_abx = $9E - -; OPC_NOP = $A3 ; doublet -; OPC_NOP = $AB ; doublet - -OPC_LDA_izp = $B2 -; OPC_NOP = $B3 ; doublet -; OPC_NOP = $BB ; doublet - -; OPC_NOP = $C2 ; doublet -; OPC_NOP = $C3 ; doublet -; OPC_NOP = $CB ; doublet - -OPC_CMP_izp = $D2 -; OPC_NOP = $D3 ; doublet -; OPC_NOP = $D4 ; doublet -OPC_PHX = $DA -; OPC_NOP = $DB ; doublet -; OPC_NOP = $DC ; doublet - -; OPC_NOP = $E2 ; doublet -; OPC_NOP = $E3 ; doublet -; OPC_NOP = $EB ; doublet - -OPC_SBC_izp = $F2 -; OPC_NOP = $F3 ; doublet -; OPC_NOP = $F4 ; doublet -OPC_PLX = $FA -; OPC_NOP = $FB ; doublet -; OPC_NOP = $FC ; doublet - - -.if (.cpu .bitand ::CPU_ISET_65C02) - -; bit instructions for 65C02 - -OPC_RMB0 = $07 -OPC_RMB1 = $17 -OPC_RMB2 = $27 -OPC_RMB3 = $37 -OPC_RMB4 = $47 -OPC_RMB5 = $57 -OPC_RMB6 = $67 -OPC_RMB7 = $77 - -OPC_SMB0 = $87 -OPC_SMB1 = $97 -OPC_SMB2 = $A7 -OPC_SMB3 = $B7 -OPC_SMB4 = $C7 -OPC_SMB5 = $D7 -OPC_SMB6 = $E7 -OPC_SMB7 = $F7 - -OPC_BBR0 = $0F -OPC_BBR1 = $1F -OPC_BBR2 = $2F -OPC_BBR3 = $3F -OPC_BBR4 = $4F -OPC_BBR5 = $5F -OPC_BBR6 = $6F -OPC_BBR7 = $7F - -OPC_BBS0 = $8F -OPC_BBS1 = $9F -OPC_BBS2 = $AF -OPC_BBS3 = $BF -OPC_BBS4 = $CF -OPC_BBS5 = $DF -OPC_BBS6 = $EF -OPC_BBS7 = $FF - -.else - -; no bit instructions for 65SC02 - -; OPC_NOP = $07 ; doublet -; OPC_NOP = $17 ; doublet -; OPC_NOP = $27 ; doublet -; OPC_NOP = $37 ; doublet -; OPC_NOP = $47 ; doublet -; OPC_NOP = $57 ; doublet -; OPC_NOP = $67 ; doublet -; OPC_NOP = $77 ; doublet -; OPC_NOP = $87 ; doublet -; OPC_NOP = $97 ; doublet -; OPC_NOP = $A7 ; doublet -; OPC_NOP = $B7 ; doublet -; OPC_NOP = $C7 ; doublet -; OPC_NOP = $D7 ; doublet -; OPC_NOP = $E7 ; doublet -; OPC_NOP = $F7 ; doublet -; OPC_NOP = $0F ; doublet -; OPC_NOP = $1F ; doublet -; OPC_NOP = $2F ; doublet -; OPC_NOP = $3F ; doublet -; OPC_NOP = $4F ; doublet -; OPC_NOP = $5F ; doublet -; OPC_NOP = $6F ; doublet -; OPC_NOP = $7F ; doublet -; OPC_NOP = $8F ; doublet -; OPC_NOP = $9F ; doublet -; OPC_NOP = $AF ; doublet -; OPC_NOP = $BF ; doublet -; OPC_NOP = $CF ; doublet -; OPC_NOP = $DF ; doublet -; OPC_NOP = $EF ; doublet -; OPC_NOP = $FF ; doublet - -.endif - -.elseif (.cpu .bitand ::CPU_ISET_6502X) - -; stable, undocumented opcodes - -; OPC_KIL = $02 ; unstable -OPC_SLO_izx = $03 -OPC_NOP_zp = $04 -OPC_SLO_zp = $07 -OPC_ANC_imm = $0B -OPC_NOP_abs = $0C -OPC_SLO_abs = $0F - -; OPC_KIL = $12 ; unstable -OPC_SLO_izy = $13 -OPC_NOP_zpx = $14 -OPC_SLO_zpx = $17 -;OPC_NOP = $1A -OPC_SLO_aby = $1B -OPC_NOP_abx = $1C -OPC_SLO_abx = $1F - -; OPC_KIL = $22 ; unstable -OPC_RLA_izx = $23 -OPC_RLA_zp = $27 -OPC_ANC_imm = $2B -OPC_RLA_abs = $2F - -; OPC_KIL = $32 ; unstable -OPC_RLA_izy = $33 -OPC_NOP_zpx = $34 -OPC_RLA_zpx = $37 -; OPC_NOP = $3A ; doublet -OPC_RLA_aby = $3B -OPC_NOP_abx = $3C -OPC_RLA_abx = $3F - -; OPC_KIL = $42 ; unstable -OPC_SRE_izx = $43 -OPC_NOP_zp = $44 -OPC_SRE_zp = $47 -OPC_ALR_imm = $4B -OPC_SRE_abs = $4F - -; OPC_KIL = $52 ; unstable -OPC_SRE_izy = $53 -OPC_NOP_zpx = $54 -OPC_SRE_zpx = $57 -; OPC_NOP = $5A ; doublet -OPC_SRE_aby = $5B -OPC_NOP_abx = $5C -OPC_SRE_abx = $5F - -; OPC_KIL = $62 -OPC_RRA_izx = $63 -OPC_NOP_zp = $64 -OPC_RRA_zp = $67 -OPC_ARR_imm = $6B -OPC_RRA_abs = $6F - -; OPC_KIL = $72 -OPC_RRA_izy = $73 -OPC_NOP_zpx = $74 -OPC_RRA_zpx = $77 -; OPC_NOP = $7A ; doublet -OPC_RRA_aby = $7B -OPC_NOP_abx = $7C -OPC_RRA_abx = $7F - -OPC_NOP_imm = $80 -; OPC_NOP_imm = $82 ; doublet -OPC_SAX_izx = $83 -OPC_SAX_zp = $87 -; OPC_NOP_imm = $89 ; doublet -; OPC_XAA = $8B ; unstable -OPC_SAX_abs = $8F - -; OPC_KIL = $92 ; unstable -; OPC_AHX_izy = $93 ; unstable -OPC_SAX_zpy = $97 -; OPC_TAS_aby = $9B ; unstable -; OPC_SHY_abx = $9C ; unstable -; OPC_SHX_aby = $9E ; unstable -; OPC_AHX_aby = $9F ; unstable - -OPC_LAX_izx = $A3 -OPC_LAX_zp = $A7 -; OPC_LAX_imm = $AB ; unstable -OPC_LAX_abs = $AF - -; OPC_KIL = $B2 ; unstable -OPC_LAX_izy = $B3 -OPC_LAX_zpy = $B7 -OPC_LAS_aby = $BB -OPC_LAX_aby = $BF - -; OPC_NOP_imm = $C2 ; doublet -OPC_DCP_izx = $C3 -OPC_DCP_zp = $C7 -OPC_AXS_imm = $CB -OPC_DCP_abs = $CF - -; OPC_KIL = $D2 ; unstable -OPC_DCP_izy = $D3 -OPC_NOP_zpx = $D4 -OPC_DCP_zpx = $D7 -OPC_NOP_DA = $DA -OPC_DCP_aby = $DB -OPC_NOP_abx = $DC -OPC_DCP_abx = $DF - -; OPC_NOP_imm = $E2 ; doublet -OPC_ISC_izx = $E3 -OPC_ISC_zp = $E7 -; OPC_SBC_imm = $EB ; doublet -OPC_ISC_abs = $EF - -; OPC_KIL = $F2 ; unstable -OPC_ISC_izy = $F3 -OPC_NOP_zpx = $F4 -OPC_ISC_zpx = $F7 -OPC_NOP_FA = $FA -OPC_ISC_aby = $FB -OPC_NOP_abx = $FC -OPC_ISC_abx = $FF - -.endif +; opcodes.inc +; ca65 6502 - opcode definitions, mainly for self modifying code +; +; Christian Krüger, latest change: 18-Sep-2010 +; +; 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. +; + +; Opcode-Table +; ------------ +; Post fix explanation: +; imm = #$00 +; zp = $00 +; zpx = $00,X +; zpy = $00,Y +; izp = ($00) +; izx = ($00,X) +; izy = ($00),Y +; abs = $0000 +; abx = $0000,X +; aby = $0000,Y +; ind = ($0000) +; iax = ($0000,X) +; rel = $0000 (PC-relative) (supressed here) + +.macpack cpu + +OPC_BRK = $00 +OPC_ORA_izx = $01 +OPC_ORA_zp = $05 +OPC_ASL_zp = $06 +OPC_PHP = $08 +OPC_ORA_imm = $09 +OPC_ASL = $0A +OPC_ORA_abs = $0D +OPC_ASL_abs = $0E + +OPC_BPL = $10 +OPC_ORA_izy = $11 +OPC_ORA_zpx = $15 +OPC_ASL_zpx = $16 +OPC_CLC = $18 +OPC_ORA_aby = $19 +OPC_ORA_abx = $1D +OPC_ASL_abx = $1E + +OPC_JSR_abs = $20 +OPC_AND_izx = $21 +OPC_BIT_zp = $24 +OPC_AND_zp = $25 +OPC_ROL_zp = $26 +OPC_PLP = $28 +OPC_AND_imm = $29 +OPC_ROL = $2A +OPC_BIT_abs = $2C +OPC_AND_abs = $2D +OPC_ROL_abs = $2E + +OPC_BMI = $30 +OPC_AND_izy = $31 +OPC_AND_zpx = $35 +OPC_ROL_zpx = $36 +OPC_SEC = $38 +OPC_AND_aby = $39 +OPC_AND_abx = $3D +OPC_ROL_abx = $3E + + +OPC_RTI = $40 +OPC_EOR_izx = $41 +OPC_EOR_zp = $45 +OPC_LSR_zp = $46 +OPC_PHA = $48 +OPC_EOR_imm = $49 +OPC_LSR = $4A +OPC_JMP_abs = $4C +OPC_EOR_abs = $4D +OPC_LSR_abs = $4E + +OPC_BVC = $50 +OPC_EOR_izy = $51 +OPC_EOR_zpx = $55 +OPC_LSR_zpx = $56 +OPC_CLI = $58 +OPC_EOR_aby = $59 +OPC_EOR_abx = $5D +OPC_LSR_abx = $5E + +OPC_RTS = $60 +OPC_ADC_izx = $61 +OPC_ADC_zp = $65 +OPC_ROR_zp = $66 +OPC_PLA = $68 +OPC_ADC_imm = $69 +OPC_ROR = $6A +OPC_JMP_ind = $6C +OPC_ADC_abs = $6D +OPC_ROR_abs = $6E + +OPC_BVS = $70 +OPC_ADC_izy = $71 +OPC_ADC_zpx = $75 +OPC_ROR_zpx = $76 +OPC_SEI = $78 +OPC_ADC_aby = $79 +OPC_ADC_abx = $7D +OPC_ROR_abx = $7E + +OPC_STA_izx = $81 +OPC_STY_zp = $84 +OPC_STA_zp = $85 +OPC_STX_zp = $86 +OPC_DEY = $88 +OPC_TXA = $8A +OPC_STY_abs = $8C +OPC_STA_abs = $8D +OPC_STX_abs = $8E + +OPC_BCC = $90 +OPC_STA_izy = $91 +OPC_STY_zpx = $94 +OPC_STA_zpx = $95 +OPC_STX_zpy = $96 +OPC_TYA = $98 +OPC_STA_aby = $99 +OPC_TXS = $9A +OPC_STA_abx = $9D + +OPC_LDY_imm = $A0 +OPC_LDA_izx = $A1 +OPC_LDX_imm = $A2 +OPC_LDY_zp = $A4 +OPC_LDA_zp = $A5 +OPC_LDX_zp = $A6 +OPC_TAY = $A8 +OPC_LDA_imm = $A9 +OPC_TAX = $AA +OPC_LDY_abs = $AC +OPC_LDA_abs = $AD +OPC_LDX_abs = $AE + +OPC_BCS = $B0 +OPC_LDA_izy = $B1 +OPC_LDY_zpx = $B4 +OPC_LDA_zpx = $B5 +OPC_LDX_zpy = $B6 +OPC_CLV = $B8 +OPC_LDA_aby = $B9 +OPC_TSX = $BA +OPC_LDY_abx = $BC +OPC_LDA_abx = $BD +OPC_LDX_aby = $BE + +OPC_CPY_imm = $C0 +OPC_CMP_izx = $C1 +OPC_CPY_zp = $C4 +OPC_CMP_zp = $C5 +OPC_DEC_zp = $C6 +OPC_INY = $C8 +OPC_CMP_imm = $C9 +OPC_DEX = $CA +OPC_CPY_abs = $CC +OPC_CMP_abs = $CD +OPC_DEC_abs = $CE + +OPC_BNE = $D0 +OPC_CMP_izy = $D1 +OPC_CMP_zpx = $D5 +OPC_DEC_zpx = $D6 +OPC_CLD = $D8 +OPC_CMP_aby = $D9 +OPC_CMP_abx = $DD +OPC_DEC_abx = $DE + +OPC_CPX_imm = $E0 +OPC_SBC_izx = $E1 +OPC_CPX_zp = $E4 +OPC_SBC_zp = $E5 +OPC_INC_zp = $E6 +OPC_INX = $E8 +OPC_SBC_imm = $E9 +OPC_NOP = $EA +OPC_CPX_abs = $EC +OPC_SBC_abs = $ED +OPC_INC_abs = $EE + + +OPC_BEQ = $F0 +OPC_SBC_izy = $F1 +OPC_SBC_zpx = $F5 +OPC_INC_zpx = $F6 +OPC_SED = $F8 +OPC_SBC_aby = $F9 +OPC_SBC_abx = $FD +OPC_INC_abx = $FE + + +.if (.cpu .bitand ::CPU_ISET_65SC02) + +; OPC_NOP = $02 ; doublet +; OPC_NOP = $03 ; doublet +OPC_TSB_zp = $04 +; OPC_NOP = $0B ; doublet +OPC_TSB_abs = $0C + +OPC_ORA_izp = $12 +; OPC_NOP = $13 ; doublet +OPC_TRB_zp = $14 +OPC_INC = $1A +; OPC_NOP = $1B ; doublet +OPC_TRB_abs = $1C + +; OPC_NOP = $22 ; doublet +; OPC_NOP = $23 ; doublet +; OPC_NOP = $2B ; doublet + +OPC_AND_izp = $32 +; OPC_NOP = $33 ; doublet +OPC_BIT_zpx = $34 +OPC_DEC = $3A +; OPC_NOP = $3B ; doublet +OPC_BIT_abx = $3C + +; OPC_NOP = $42 ; doublet +; OPC_NOP = $43 ; doublet +; OPC_NOP = $44 ; doublet +; OPC_NOP = $4B ; doublet + +OPC_EOR_izp = $52 +; OPC_NOP = $53 ; doublet +; OPC_NOP = $54 ; doublet +; OPC_NOP = $5A ; doublet +; OPC_NOP = $5B ; doublet +OPC_EOR_abx = $5C + +; OPC_NOP = $62 ; doublet +; OPC_NOP = $63 ; doublet +OPC_STZ_zp = $64 +; OPC_NOP = $6B ; doublet + +OPC_ADC_izp = $72 +; OPC_NOP = $73 ; doublet +OPC_STZ_zpx = $74 +OPC_PLY = $7A +; OPC_NOP = $7B ; doublet +OPC_JMP_iax = $7C + +OPC_BRA = $80 +; OPC_NOP = $82 ; doublet +; OPC_NOP = $83 ; doublet +OPC_BIT_imm = $89 +; OPC_NOP = $8B ; doublet + +OPC_STA_izp = $92 +; OPC_NOP = $93 ; doublet +; OPC_NOP = $9B ; doublet +OPC_STZ_abs = $9C +OPC_STZ_abx = $9E + +; OPC_NOP = $A3 ; doublet +; OPC_NOP = $AB ; doublet + +OPC_LDA_izp = $B2 +; OPC_NOP = $B3 ; doublet +; OPC_NOP = $BB ; doublet + +; OPC_NOP = $C2 ; doublet +; OPC_NOP = $C3 ; doublet +; OPC_NOP = $CB ; doublet + +OPC_CMP_izp = $D2 +; OPC_NOP = $D3 ; doublet +; OPC_NOP = $D4 ; doublet +OPC_PHX = $DA +; OPC_NOP = $DB ; doublet +; OPC_NOP = $DC ; doublet + +; OPC_NOP = $E2 ; doublet +; OPC_NOP = $E3 ; doublet +; OPC_NOP = $EB ; doublet + +OPC_SBC_izp = $F2 +; OPC_NOP = $F3 ; doublet +; OPC_NOP = $F4 ; doublet +OPC_PLX = $FA +; OPC_NOP = $FB ; doublet +; OPC_NOP = $FC ; doublet + + +.if (.cpu .bitand ::CPU_ISET_65C02) + +; bit instructions for 65C02 + +OPC_RMB0 = $07 +OPC_RMB1 = $17 +OPC_RMB2 = $27 +OPC_RMB3 = $37 +OPC_RMB4 = $47 +OPC_RMB5 = $57 +OPC_RMB6 = $67 +OPC_RMB7 = $77 + +OPC_SMB0 = $87 +OPC_SMB1 = $97 +OPC_SMB2 = $A7 +OPC_SMB3 = $B7 +OPC_SMB4 = $C7 +OPC_SMB5 = $D7 +OPC_SMB6 = $E7 +OPC_SMB7 = $F7 + +OPC_BBR0 = $0F +OPC_BBR1 = $1F +OPC_BBR2 = $2F +OPC_BBR3 = $3F +OPC_BBR4 = $4F +OPC_BBR5 = $5F +OPC_BBR6 = $6F +OPC_BBR7 = $7F + +OPC_BBS0 = $8F +OPC_BBS1 = $9F +OPC_BBS2 = $AF +OPC_BBS3 = $BF +OPC_BBS4 = $CF +OPC_BBS5 = $DF +OPC_BBS6 = $EF +OPC_BBS7 = $FF + +.else + +; no bit instructions for 65SC02 + +; OPC_NOP = $07 ; doublet +; OPC_NOP = $17 ; doublet +; OPC_NOP = $27 ; doublet +; OPC_NOP = $37 ; doublet +; OPC_NOP = $47 ; doublet +; OPC_NOP = $57 ; doublet +; OPC_NOP = $67 ; doublet +; OPC_NOP = $77 ; doublet +; OPC_NOP = $87 ; doublet +; OPC_NOP = $97 ; doublet +; OPC_NOP = $A7 ; doublet +; OPC_NOP = $B7 ; doublet +; OPC_NOP = $C7 ; doublet +; OPC_NOP = $D7 ; doublet +; OPC_NOP = $E7 ; doublet +; OPC_NOP = $F7 ; doublet +; OPC_NOP = $0F ; doublet +; OPC_NOP = $1F ; doublet +; OPC_NOP = $2F ; doublet +; OPC_NOP = $3F ; doublet +; OPC_NOP = $4F ; doublet +; OPC_NOP = $5F ; doublet +; OPC_NOP = $6F ; doublet +; OPC_NOP = $7F ; doublet +; OPC_NOP = $8F ; doublet +; OPC_NOP = $9F ; doublet +; OPC_NOP = $AF ; doublet +; OPC_NOP = $BF ; doublet +; OPC_NOP = $CF ; doublet +; OPC_NOP = $DF ; doublet +; OPC_NOP = $EF ; doublet +; OPC_NOP = $FF ; doublet + +.endif + +.elseif (.cpu .bitand ::CPU_ISET_6502X) + +; stable, undocumented opcodes + +; OPC_KIL = $02 ; unstable +OPC_SLO_izx = $03 +OPC_NOP_zp = $04 +OPC_SLO_zp = $07 +OPC_ANC_imm = $0B +OPC_NOP_abs = $0C +OPC_SLO_abs = $0F + +; OPC_KIL = $12 ; unstable +OPC_SLO_izy = $13 +OPC_NOP_zpx = $14 +OPC_SLO_zpx = $17 +;OPC_NOP = $1A +OPC_SLO_aby = $1B +OPC_NOP_abx = $1C +OPC_SLO_abx = $1F + +; OPC_KIL = $22 ; unstable +OPC_RLA_izx = $23 +OPC_RLA_zp = $27 +OPC_ANC_imm = $2B +OPC_RLA_abs = $2F + +; OPC_KIL = $32 ; unstable +OPC_RLA_izy = $33 +OPC_NOP_zpx = $34 +OPC_RLA_zpx = $37 +; OPC_NOP = $3A ; doublet +OPC_RLA_aby = $3B +OPC_NOP_abx = $3C +OPC_RLA_abx = $3F + +; OPC_KIL = $42 ; unstable +OPC_SRE_izx = $43 +OPC_NOP_zp = $44 +OPC_SRE_zp = $47 +OPC_ALR_imm = $4B +OPC_SRE_abs = $4F + +; OPC_KIL = $52 ; unstable +OPC_SRE_izy = $53 +OPC_NOP_zpx = $54 +OPC_SRE_zpx = $57 +; OPC_NOP = $5A ; doublet +OPC_SRE_aby = $5B +OPC_NOP_abx = $5C +OPC_SRE_abx = $5F + +; OPC_KIL = $62 +OPC_RRA_izx = $63 +OPC_NOP_zp = $64 +OPC_RRA_zp = $67 +OPC_ARR_imm = $6B +OPC_RRA_abs = $6F + +; OPC_KIL = $72 +OPC_RRA_izy = $73 +OPC_NOP_zpx = $74 +OPC_RRA_zpx = $77 +; OPC_NOP = $7A ; doublet +OPC_RRA_aby = $7B +OPC_NOP_abx = $7C +OPC_RRA_abx = $7F + +OPC_NOP_imm = $80 +; OPC_NOP_imm = $82 ; doublet +OPC_SAX_izx = $83 +OPC_SAX_zp = $87 +; OPC_NOP_imm = $89 ; doublet +; OPC_XAA = $8B ; unstable +OPC_SAX_abs = $8F + +; OPC_KIL = $92 ; unstable +; OPC_AHX_izy = $93 ; unstable +OPC_SAX_zpy = $97 +; OPC_TAS_aby = $9B ; unstable +; OPC_SHY_abx = $9C ; unstable +; OPC_SHX_aby = $9E ; unstable +; OPC_AHX_aby = $9F ; unstable + +OPC_LAX_izx = $A3 +OPC_LAX_zp = $A7 +; OPC_LAX_imm = $AB ; unstable +OPC_LAX_abs = $AF + +; OPC_KIL = $B2 ; unstable +OPC_LAX_izy = $B3 +OPC_LAX_zpy = $B7 +OPC_LAS_aby = $BB +OPC_LAX_aby = $BF + +; OPC_NOP_imm = $C2 ; doublet +OPC_DCP_izx = $C3 +OPC_DCP_zp = $C7 +OPC_AXS_imm = $CB +OPC_DCP_abs = $CF + +; OPC_KIL = $D2 ; unstable +OPC_DCP_izy = $D3 +OPC_NOP_zpx = $D4 +OPC_DCP_zpx = $D7 +OPC_NOP_DA = $DA +OPC_DCP_aby = $DB +OPC_NOP_abx = $DC +OPC_DCP_abx = $DF + +; OPC_NOP_imm = $E2 ; doublet +OPC_ISC_izx = $E3 +OPC_ISC_zp = $E7 +; OPC_SBC_imm = $EB ; doublet +OPC_ISC_abs = $EF + +; OPC_KIL = $F2 ; unstable +OPC_ISC_izy = $F3 +OPC_NOP_zpx = $F4 +OPC_ISC_zpx = $F7 +OPC_NOP_FA = $FA +OPC_ISC_aby = $FB +OPC_NOP_abx = $FC +OPC_ISC_abx = $FF + +.endif diff --git a/asminc/smc.inc b/asminc/smc.inc index d5752a5f5..0583f79e0 100644 --- a/asminc/smc.inc +++ b/asminc/smc.inc @@ -1,267 +1,267 @@ -; smc.mac -; ca65 Macro-Pack for Self Modifying Code (SMC) -; -; (c) Christian Krüger, latest change: 17-Jul-2016 -; -; 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. -; - -.define _SMCDesignator .mid(0, .tcount(label) - 1, label) .ident(.concat(.string(.right(1, label)), "_SMC")) -.define _SMCAlias .mid(0, .tcount(alias) - 1, alias) .ident(.concat(.string(.right(1, alias)), "_SMC")) -.define SMC_AbsAdr $FADE -.define SMC_ZpAdr $00 -.define SMC_Opcode nop -.define SMC_Value $42 - -.macro SMC_OperateOnValue opcode, label - opcode _SMCDesignator+1 -.endmacro - -.macro SMC_OperateOnLowByte opcode, label - SMC_OperateOnValue opcode, label -.endmacro - -.macro SMC_OperateOnHighByte opcode, label - opcode _SMCDesignator + 2 -.endmacro - -.macro SMC_Import alias -.import _SMCAlias -.endmacro - -.macro SMC_Export alias, label -.export _SMCAlias := _SMCDesignator -.endmacro - -.macro SMC label, statement -_SMCDesignator: statement -.endmacro - -.macro SMC_TransferOpcode label, opcode, register -.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, ) - lda #opcode - sta _SMCDesignator -.elseif .match ({register}, x) - ldx #opcode - stx _SMCDesignator -.elseif .match ({register}, y) - ldy #opcode - sty _SMCDesignator -.else - .error "Invalid usage of macro 'SMC_TransferOpcode'" -.endif -.endmacro - -.macro SMC_LoadOpcode label, register -.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) - lda _SMCDesignator -.elseif .match ({register}, x) - ldx _SMCDesignator -.elseif .match ({register}, y) - ldy _SMCDesignator -.else - .error "Invalid usage of macro 'SMC_LoadOpcode'" -.endif -.endmacro - -.macro SMC_StoreOpcode label, register -.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) - sta _SMCDesignator -.elseif .match ({register}, x) - stx _SMCDesignator -.elseif .match ({register}, y) - sty _SMCDesignator -.else - .error "Invalid usage of macro 'SMC_StoreOpcode'" -.endif -.endmacro - -.macro SMC_ChangeBranch label, destination, register -.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, ) - lda #(<(destination - _SMCDesignator -2)) - sta _SMCDesignator+1 -.elseif .match ({register}, x) - ldx #(<(destination - _SMCDesignator - 2)) - stx _SMCDesignator+1 -.elseif .match ({register}, y) - ldy #(<(destination - _SMCDesignator - 2)) - sty _SMCDesignator+1 -.else - .error "Invalid usage of macro 'SMC_ChangeBranch'" -.endif -.endmacro - -.macro SMC_TransferValue label, value, register -.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, ) - lda value - sta _SMCDesignator+1 -.elseif .match ({register}, x) - ldx value - stx _SMCDesignator+1 -.elseif .match ({register}, y) - ldy value - sty _SMCDesignator+1 -.else - .error "Invalid usage of macro 'SMC_TransferValue'" -.endif -.endmacro - -.macro SMC_LoadValue label, register -.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) - lda _SMCDesignator+1 -.elseif .match ({register}, x) - ldx _SMCDesignator+1 -.elseif .match ({register}, y) - ldy _SMCDesignator+1 -.else - .error "Invalid usage of macro 'SMC_LoadValue'" -.endif -.endmacro - -.macro SMC_StoreValue label, register -.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) - sta _SMCDesignator+1 -.elseif .match ({register}, x) - stx _SMCDesignator+1 -.elseif .match ({register}, y) - sty _SMCDesignator+1 -.else - .error "Invalid usage of macro 'SMC_StoreValue'" -.endif -.endmacro - - -.macro SMC_TransferLowByte label, value, register -SMC_TransferValue label, value, register -.endmacro - -.macro SMC_LoadLowByte label, register -SMC_LoadValue label, register -.endmacro - -.macro SMC_StoreLowByte label, register -SMC_StoreValue label, register -.endmacro - -.macro SMC_TransferHighByte label, value, register -.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, ) - lda value - sta _SMCDesignator+2 -.elseif .match ({register}, x) - ldx value - stx _SMCDesignator+2 -.elseif .match ({register}, y) - ldy value - sty _SMCDesignator+2 -.else - .error "Invalid usage of macro 'SMC_TransferHighByte'" -.endif -.endmacro - -.macro SMC_LoadHighByte label, register -.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) - lda _SMCDesignator+2 -.elseif .match ({register}, x) - ldx _SMCDesignator+2 -.elseif .match ({register}, y) - ldy _SMCDesignator+2 -.else - .error "Invalid usage of macro 'SMC_LoadHighByte'" -.endif -.endmacro - -.macro SMC_StoreHighByte label, register -.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) - sta _SMCDesignator+2 -.elseif .match ({register}, x) - stx _SMCDesignator+2 -.elseif .match ({register}, y) - sty _SMCDesignator+2 -.else - .error "Invalid usage of macro 'SMC_StoreHighByte'" -.endif -.endmacro - -.macro SMC_TransferAddressSingle label, address, register -.if .paramcount = 2 .or .match ((register), a) .or .match ({register}, ) - .if (.match (.left (1, {address}), #)) - ; immediate mode - lda #<(.right (.tcount ({address})-1, {address})) - sta _SMCDesignator+1 - lda #>(.right (.tcount ({address})-1, {address})) - sta _SMCDesignator+2 - .else - ; assume absolute or zero page - lda address - sta _SMCDesignator+1 - lda 1+(address) - sta _SMCDesignator+2 - .endif -.elseif .match ((register), x) - .if (.match (.left (1, {address}), #)) - ; immediate mode - ldx #<(.right (.tcount ({address})-1, {address})) - stx _SMCDesignator+1 - ldx #>(.right (.tcount ({address})-1, {address})) - stx _SMCDesignator+2 - .else - ; assume absolute or zero page - ldx address - stx _SMCDesignator+1 - ldx 1+(address) - stx _SMCDesignator+2 - .endif -.elseif .match ((register), y) - .if (.match (.left (1, {address}), #)) - ; immediate mode - ldy #<(.right (.tcount ({address})-1, {address})) - sty _SMCDesignator+1 - ldy #>(.right (.tcount ({address})-1, {address})) - sty _SMCDesignator+2 - .else - ; assume absolute or zero page - ldy address - sty _SMCDesignator+1 - ldy 1+(address) - sty _SMCDesignator+2 - .endif -.else - .error "Invalid usage of macro 'SMC_TransferAddressSingle'" -.endif -.endmacro - -.macro SMC_TransferAddress label, address -.if (.match (.left (1, {address}), #)) - ; immediate mode - lda #<(.right (.tcount ({address})-1, {address})) - sta _SMCDesignator+1 - ldx #>(.right (.tcount ({address})-1, {address})) - stx _SMCDesignator+2 -.else - ; assume absolute or zero page - lda {address} - sta _SMCDesignator+1 - ldx 1+{address} - stx _SMCDesignator)+2 -.endif -.endmacro - -.macro SMC_StoreAddress label - sta _SMCDesignator+1 - stx _SMCDesignator+2 -.endmacro +; smc.mac +; ca65 Macro-Pack for Self Modifying Code (SMC) +; +; (c) Christian Krüger, latest change: 17-Jul-2016 +; +; 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. +; + +.define _SMCDesignator .mid(0, .tcount(label) - 1, label) .ident(.concat(.string(.right(1, label)), "_SMC")) +.define _SMCAlias .mid(0, .tcount(alias) - 1, alias) .ident(.concat(.string(.right(1, alias)), "_SMC")) +.define SMC_AbsAdr $FADE +.define SMC_ZpAdr $00 +.define SMC_Opcode nop +.define SMC_Value $42 + +.macro SMC_OperateOnValue opcode, label + opcode _SMCDesignator+1 +.endmacro + +.macro SMC_OperateOnLowByte opcode, label + SMC_OperateOnValue opcode, label +.endmacro + +.macro SMC_OperateOnHighByte opcode, label + opcode _SMCDesignator + 2 +.endmacro + +.macro SMC_Import alias +.import _SMCAlias +.endmacro + +.macro SMC_Export alias, label +.export _SMCAlias := _SMCDesignator +.endmacro + +.macro SMC label, statement +_SMCDesignator: statement +.endmacro + +.macro SMC_TransferOpcode label, opcode, register +.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, ) + lda #opcode + sta _SMCDesignator +.elseif .match ({register}, x) + ldx #opcode + stx _SMCDesignator +.elseif .match ({register}, y) + ldy #opcode + sty _SMCDesignator +.else + .error "Invalid usage of macro 'SMC_TransferOpcode'" +.endif +.endmacro + +.macro SMC_LoadOpcode label, register +.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) + lda _SMCDesignator +.elseif .match ({register}, x) + ldx _SMCDesignator +.elseif .match ({register}, y) + ldy _SMCDesignator +.else + .error "Invalid usage of macro 'SMC_LoadOpcode'" +.endif +.endmacro + +.macro SMC_StoreOpcode label, register +.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) + sta _SMCDesignator +.elseif .match ({register}, x) + stx _SMCDesignator +.elseif .match ({register}, y) + sty _SMCDesignator +.else + .error "Invalid usage of macro 'SMC_StoreOpcode'" +.endif +.endmacro + +.macro SMC_ChangeBranch label, destination, register +.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, ) + lda #(<(destination - _SMCDesignator -2)) + sta _SMCDesignator+1 +.elseif .match ({register}, x) + ldx #(<(destination - _SMCDesignator - 2)) + stx _SMCDesignator+1 +.elseif .match ({register}, y) + ldy #(<(destination - _SMCDesignator - 2)) + sty _SMCDesignator+1 +.else + .error "Invalid usage of macro 'SMC_ChangeBranch'" +.endif +.endmacro + +.macro SMC_TransferValue label, value, register +.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, ) + lda value + sta _SMCDesignator+1 +.elseif .match ({register}, x) + ldx value + stx _SMCDesignator+1 +.elseif .match ({register}, y) + ldy value + sty _SMCDesignator+1 +.else + .error "Invalid usage of macro 'SMC_TransferValue'" +.endif +.endmacro + +.macro SMC_LoadValue label, register +.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) + lda _SMCDesignator+1 +.elseif .match ({register}, x) + ldx _SMCDesignator+1 +.elseif .match ({register}, y) + ldy _SMCDesignator+1 +.else + .error "Invalid usage of macro 'SMC_LoadValue'" +.endif +.endmacro + +.macro SMC_StoreValue label, register +.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) + sta _SMCDesignator+1 +.elseif .match ({register}, x) + stx _SMCDesignator+1 +.elseif .match ({register}, y) + sty _SMCDesignator+1 +.else + .error "Invalid usage of macro 'SMC_StoreValue'" +.endif +.endmacro + + +.macro SMC_TransferLowByte label, value, register +SMC_TransferValue label, value, register +.endmacro + +.macro SMC_LoadLowByte label, register +SMC_LoadValue label, register +.endmacro + +.macro SMC_StoreLowByte label, register +SMC_StoreValue label, register +.endmacro + +.macro SMC_TransferHighByte label, value, register +.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, ) + lda value + sta _SMCDesignator+2 +.elseif .match ({register}, x) + ldx value + stx _SMCDesignator+2 +.elseif .match ({register}, y) + ldy value + sty _SMCDesignator+2 +.else + .error "Invalid usage of macro 'SMC_TransferHighByte'" +.endif +.endmacro + +.macro SMC_LoadHighByte label, register +.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) + lda _SMCDesignator+2 +.elseif .match ({register}, x) + ldx _SMCDesignator+2 +.elseif .match ({register}, y) + ldy _SMCDesignator+2 +.else + .error "Invalid usage of macro 'SMC_LoadHighByte'" +.endif +.endmacro + +.macro SMC_StoreHighByte label, register +.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, ) + sta _SMCDesignator+2 +.elseif .match ({register}, x) + stx _SMCDesignator+2 +.elseif .match ({register}, y) + sty _SMCDesignator+2 +.else + .error "Invalid usage of macro 'SMC_StoreHighByte'" +.endif +.endmacro + +.macro SMC_TransferAddressSingle label, address, register +.if .paramcount = 2 .or .match ((register), a) .or .match ({register}, ) + .if (.match (.left (1, {address}), #)) + ; immediate mode + lda #<(.right (.tcount ({address})-1, {address})) + sta _SMCDesignator+1 + lda #>(.right (.tcount ({address})-1, {address})) + sta _SMCDesignator+2 + .else + ; assume absolute or zero page + lda address + sta _SMCDesignator+1 + lda 1+(address) + sta _SMCDesignator+2 + .endif +.elseif .match ((register), x) + .if (.match (.left (1, {address}), #)) + ; immediate mode + ldx #<(.right (.tcount ({address})-1, {address})) + stx _SMCDesignator+1 + ldx #>(.right (.tcount ({address})-1, {address})) + stx _SMCDesignator+2 + .else + ; assume absolute or zero page + ldx address + stx _SMCDesignator+1 + ldx 1+(address) + stx _SMCDesignator+2 + .endif +.elseif .match ((register), y) + .if (.match (.left (1, {address}), #)) + ; immediate mode + ldy #<(.right (.tcount ({address})-1, {address})) + sty _SMCDesignator+1 + ldy #>(.right (.tcount ({address})-1, {address})) + sty _SMCDesignator+2 + .else + ; assume absolute or zero page + ldy address + sty _SMCDesignator+1 + ldy 1+(address) + sty _SMCDesignator+2 + .endif +.else + .error "Invalid usage of macro 'SMC_TransferAddressSingle'" +.endif +.endmacro + +.macro SMC_TransferAddress label, address +.if (.match (.left (1, {address}), #)) + ; immediate mode + lda #<(.right (.tcount ({address})-1, {address})) + sta _SMCDesignator+1 + ldx #>(.right (.tcount ({address})-1, {address})) + stx _SMCDesignator+2 +.else + ; assume absolute or zero page + lda {address} + sta _SMCDesignator+1 + ldx 1+{address} + stx _SMCDesignator)+2 +.endif +.endmacro + +.macro SMC_StoreAddress label + sta _SMCDesignator+1 + stx _SMCDesignator+2 +.endmacro diff --git a/include/osic1p.h b/include/osic1p.h index 57fe0cd24..d6ab5fee1 100644 --- a/include/osic1p.h +++ b/include/osic1p.h @@ -1,47 +1,47 @@ -/*****************************************************************************/ -/* */ -/* osic1p.h */ -/* */ -/* Challenger 1P system specific definitions */ -/* */ -/* */ -/* */ -/* (C) 2015 Stephan Muehlstrasser */ -/* */ -/* */ -/* 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 _OSIC1P_H -#define _OSIC1P_H - -/* Check for errors */ -#if !defined(__OSIC1P__) -# error "This module may only be used when compiling for the Challenger 1P!" -#endif - -/* 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 _textcolor(color) COLOR_WHITE -#define _bgcolor(color) COLOR_BLACK -#define _bordercolor(color) COLOR_BLACK - -#endif +/*****************************************************************************/ +/* */ +/* osic1p.h */ +/* */ +/* Challenger 1P system specific definitions */ +/* */ +/* */ +/* */ +/* (C) 2015 Stephan Muehlstrasser */ +/* */ +/* */ +/* 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 _OSIC1P_H +#define _OSIC1P_H + +/* Check for errors */ +#if !defined(__OSIC1P__) +# error "This module may only be used when compiling for the Challenger 1P!" +#endif + +/* 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 _textcolor(color) COLOR_WHITE +#define _bgcolor(color) COLOR_BLACK +#define _bordercolor(color) COLOR_BLACK + +#endif diff --git a/include/zlib.h b/include/zlib.h index 8fa6a2bd1..8ced89800 100644 --- a/include/zlib.h +++ b/include/zlib.h @@ -1,172 +1,172 @@ -/*****************************************************************************/ -/* */ -/* zlib.h */ -/* */ -/* Decompression routines for the 'deflate' format */ -/* */ -/* */ -/* */ -/* (C) 2000-2015 Piotr Fusik <fox@scene.pl> */ -/* */ -/* This file is based on the zlib.h from 'zlib' general purpose compression */ -/* library, version 1.1.3, (C) 1995-1998 Jean-loup Gailly and Mark Adler. */ -/* */ -/* Jean-loup Gailly Mark Adler */ -/* jloup@gzip.org madler@alumni.caltech.edu */ -/* */ -/* 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 _ZLIB_H -#define _ZLIB_H - -#define Z_OK 0 -#define Z_DATA_ERROR (-3) -/* Return codes for uncompress() */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported) */ - -#define Z_NULL 0 - - -unsigned __fastcall__ inflatemem (char* dest, const char* source); -/* - Decompresses the source buffer into the destination buffer. - Returns the size of the uncompressed data (number of bytes written starting - from dest). - - This function expects data in the DEFLATE format, described in RFC - (Request for Comments) 1951 in the file - ftp://ds.internic.net/rfc/rfc1951.txt. - - This function does not exist in the original zlib. Its implementation - using original zlib might be following: - - unsigned inflatemem (char* dest, const char* source) - { - z_stream stream; - - stream.next_in = (Bytef*) source; - stream.avail_in = 65535; - - stream.next_out = dest; - stream.avail_out = 65535; - - stream.zalloc = (alloc_func) 0; - stream.zfree = (free_func) 0; - - inflateInit2(&stream, -MAX_WBITS); - inflate(&stream, Z_FINISH); - inflateEnd(&stream); - - return stream.total_out; - } -*/ - - -int __fastcall__ uncompress (char* dest, unsigned* destLen, - const char* source, unsigned sourceLen); -/* - Original zlib description: - - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted. - - Implementation notes: - - This function expects data in the ZLIB format, described in RFC 1950 - in the file ftp://ds.internic.net/rfc/rfc1950.txt. The ZLIB format is - essentially the DEFLATE format plus a very small header and Adler-32 - checksum. - - Z_MEM_ERROR and Z_BUF_ERROR are never returned in this implementation. -*/ - - -unsigned long __fastcall__ adler32 (unsigned long adler, const char* buf, - unsigned len); - -/* - Original zlib description: - - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is NULL, this function returns - the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. Usage example: - - unsigned long adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); - - Implementation notes: - - This function isn't actually much faster than crc32(), but it is smaller - and does not use any lookup tables. -*/ - - -unsigned long __fastcall__ crc32 (unsigned long crc, const char* buf, - unsigned len); -/* - Original zlib description: - - Update a running crc with the bytes buf[0..len-1] and return the updated - crc. If buf is NULL, this function returns the required initial value - for the crc. Pre- and post-conditioning (one's complement) is performed - within this function so it shouldn't be done by the application. - Usage example: - - unsigned long crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); - - Implementation notes: - - This function uses statically allocated 1 KB lookup table. The table is - initialised before it is used for the first time (that is, if buffer is - NULL or length is zero, then the lookup table isn't initialised). -*/ - - -/* end of zlib.h */ -#endif - - - +/*****************************************************************************/ +/* */ +/* zlib.h */ +/* */ +/* Decompression routines for the 'deflate' format */ +/* */ +/* */ +/* */ +/* (C) 2000-2015 Piotr Fusik <fox@scene.pl> */ +/* */ +/* This file is based on the zlib.h from 'zlib' general purpose compression */ +/* library, version 1.1.3, (C) 1995-1998 Jean-loup Gailly and Mark Adler. */ +/* */ +/* Jean-loup Gailly Mark Adler */ +/* jloup@gzip.org madler@alumni.caltech.edu */ +/* */ +/* 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 _ZLIB_H +#define _ZLIB_H + +#define Z_OK 0 +#define Z_DATA_ERROR (-3) +/* Return codes for uncompress() */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported) */ + +#define Z_NULL 0 + + +unsigned __fastcall__ inflatemem (char* dest, const char* source); +/* + Decompresses the source buffer into the destination buffer. + Returns the size of the uncompressed data (number of bytes written starting + from dest). + + This function expects data in the DEFLATE format, described in RFC + (Request for Comments) 1951 in the file + ftp://ds.internic.net/rfc/rfc1951.txt. + + This function does not exist in the original zlib. Its implementation + using original zlib might be following: + + unsigned inflatemem (char* dest, const char* source) + { + z_stream stream; + + stream.next_in = (Bytef*) source; + stream.avail_in = 65535; + + stream.next_out = dest; + stream.avail_out = 65535; + + stream.zalloc = (alloc_func) 0; + stream.zfree = (free_func) 0; + + inflateInit2(&stream, -MAX_WBITS); + inflate(&stream, Z_FINISH); + inflateEnd(&stream); + + return stream.total_out; + } +*/ + + +int __fastcall__ uncompress (char* dest, unsigned* destLen, + const char* source, unsigned sourceLen); +/* + Original zlib description: + + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. + + Implementation notes: + + This function expects data in the ZLIB format, described in RFC 1950 + in the file ftp://ds.internic.net/rfc/rfc1950.txt. The ZLIB format is + essentially the DEFLATE format plus a very small header and Adler-32 + checksum. + + Z_MEM_ERROR and Z_BUF_ERROR are never returned in this implementation. +*/ + + +unsigned long __fastcall__ adler32 (unsigned long adler, const char* buf, + unsigned len); + +/* + Original zlib description: + + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + unsigned long adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); + + Implementation notes: + + This function isn't actually much faster than crc32(), but it is smaller + and does not use any lookup tables. +*/ + + +unsigned long __fastcall__ crc32 (unsigned long crc, const char* buf, + unsigned len); +/* + Original zlib description: + + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: + + unsigned long crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); + + Implementation notes: + + This function uses statically allocated 1 KB lookup table. The table is + initialised before it is used for the first time (that is, if buffer is + NULL or length is zero, then the lookup table isn't initialised). +*/ + + +/* end of zlib.h */ +#endif + + + diff --git a/libsrc/c64/emd/c64-65816.s b/libsrc/c64/emd/c64-65816.s index bf44a0ecc..39f323d28 100644 --- a/libsrc/c64/emd/c64-65816.s +++ b/libsrc/c64/emd/c64-65816.s @@ -1,376 +1,376 @@ -; -; Extended memory driver for 65816 based extra RAM. Driver works without -; problems when statically linked. -; -; Marco van den Heuvel, 2015-12-01 -; - - .include "zeropage.inc" - - .include "em-kernel.inc" - .include "em-error.inc" - - - .macpack generic - .macpack module - - -; ------------------------------------------------------------------------ -; Header. Includes jump table - - module_header _c64_65816_emd - -; Driver signature - - .byte $65, $6d, $64 ; "emd" - .byte EMD_API_VERSION ; EM API version number - -; Library reference - - .addr $0000 - -; Jump table - - .addr INSTALL - .addr UNINSTALL - .addr PAGECOUNT - .addr MAP - .addr USE - .addr COMMIT - .addr COPYFROM - .addr COPYTO - -; ------------------------------------------------------------------------ -; Data. - -.bss -isnotscpu: .res 1 ; SuperCPU not present -curpage: .res 1 ; Current page number -curbank: .res 1 ; Current bank number (+1) -bankcount: .res 1 ; Number of available banks (pages = banks * 256) -window: .res 256 ; Memory "window" - -.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 EM_ERR_xx code in a/x. -; - -INSTALL: - sei - clc - sed - lda #$99 - adc #$01 ; on 65C02, 65SC02, 65CE02, 65802 and 65816 sets the zero flag correctly - cld - bne @not_present - clc -.P816 - sep #$01 ; nop #$01 on 65C02/65SC02 and lda ($01,s),y on 65CE02 -.P02 - bcc @not_present - lda $d0bc - and #$80 - sta isnotscpu - lda $07e8 - pha ; save value incase it was used somewhere else - ldx #$ff -@fillloop: ; fill from top (bank 255) to bottom - txa - pha -.P816 - plb ; pull dbr -.P02 - stx $07e8 - dex - cpx #$ff - bne @fillloop - inx -@compareloop: ; check from bottom to top - txa - pha -.P816 - plb -.P02 - cmp $07e8 - bne @found_pages -.P816 - inc -.P02 - sta $07e8 - cmp $07e8 - bne @found_pages - inx - bne @compareloop -@found_pages: - dex - lda #$00 - pha -.P816 - plb -.P02 - pla - sta $07e8 - cli - lda isnotscpu - bne @noextradex - dex -@noextradex: - stx bankcount - lda #<EM_ERR_OK - ldx #>EM_ERR_OK - rts -@not_present: - cli - lda #<EM_ERR_NO_DEVICE - ldx #>EM_ERR_NO_DEVICE -; 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 - - -; ------------------------------------------------------------------------ -; PAGECOUNT: Return the total number of available pages in a/x. -; - -PAGECOUNT: - lda #$00 ; a whole bank is either usable or not - ldx bankcount - rts - -; ------------------------------------------------------------------------ -; MAP: Map the page in a/x into memory and return a pointer to the page in -; a/x. The contents of the currently mapped page (if any) may be discarded -; by the driver. -; - -MAP: sta curpage ; Remember the new page - stx curbank ; Remember the new bank - - sta ptr2+1 ; src address low - lda #$00 - sta ptr2 ; src address high - inx - ldy isnotscpu ; check if not scpu - bne @notscpu - inx -@notscpu: - stx tmp2 ; src bank - - sta tmp1 ; dst bank - - sta ptr3+1 ; length high - lda #$ff - sta ptr3 ; length low - - lda #<window - sta ptr1 ; dst address low - ldx #>window - stx ptr1+1 ; dst address high - - jsr transfer - - rts - -; ------------------------------------------------------------------------ -; USE: Tell the driver that the window is now associated with a given page. - -USE: sta curpage ; Remember the page - stx curbank ; Remember the bank - lda #<window - ldx #>window ; Return the window - rts - -; ------------------------------------------------------------------------ -; COMMIT: Commit changes in the memory window to extended storage. - -COMMIT: lda curpage ; Get the current page - sta ptr1+1 ; dst high - ldx #$00 - stx ptr1 ; dst low - - lda #<window - sta ptr2 ; src low - lda #>window - sta ptr2+1 ; src high - - stx ptr3+1 ; length high - lda #$ff - sta ptr3 ; length low - - stx tmp2 ; src bank - ldy curbank ; Get the current bank - iny - ldx isnotscpu - bne @notascpu - iny -@notascpu: - sty tmp1 ; dst bank - - jsr transfer - - rts - -; ------------------------------------------------------------------------ -; COPYFROM: Copy from extended into linear memory. A pointer to a structure -; describing the request is passed in a/x. -; The function must not return anything. -; - -COPYFROM: - sta ptr4 - stx ptr4+1 ; Save the passed em_copy pointer - - ldy #EM_COPY::COUNT+1 ; start at the end of the struct - lda (ptr4),y ; get high byte of count - tax - dey - lda (ptr4),y ; get low byte of count - bne @nodex - dex -@nodex: -.P816 - dec -.P02 - sta ptr3 ; length low - stx ptr3+1 ; length high - dey - lda (ptr4),y ; get bank -.P816 - inc -.P02 - ldx isnotscpu - bne @notscpu64 -.P816 - inc -.P02 -@notscpu64: - sta tmp2 ; src bank - dey - lda (ptr4),y ; get page - sta ptr2+1 ; src high - dey - lda (ptr4),y ; get offset in page - sta ptr2 ; src low - dey - lda (ptr4),y ; get memory buffer high - sta ptr1+1 ; dst high - dey - lda (ptr4),y ; get memory buffer low - sta ptr1 ; dst low - lda #$00 - sta tmp1 ; dst bank - - jsr transfer - - rts - -; ------------------------------------------------------------------------ -; COPYTO: Copy from linear into extended memory. A pointer to a structure -; describing the request is passed in a/x. -; The function must not return anything. -; - -COPYTO: sta ptr4 - stx ptr4+1 ; Save the passed em_copy pointer - - ldy #EM_COPY::COUNT+1 ; start at the end of the struct - lda (ptr4),y ; get high byte of count - tax - dey - lda (ptr4),y ; get low byte of count - bne @nodex2 - dex -@nodex2: -.P816 - dec -.P02 - sta ptr3 ; length low - txa - sta ptr3+1 ; length high - dey - lda (ptr4),y ; get bank -.P816 - inc -.P02 - ldx isnotscpu - bne @notascpu64 -.P816 - inc -.P02 -@notascpu64: - sta tmp1 ; dst bank - dey - lda (ptr4),y ; get page - sta ptr1+1 ; dst high - dey - lda (ptr4),y ; get page offset - sta ptr1 ; dst low - dey - lda (ptr4),y ; get memory buffer high - sta ptr2+1 ; src low - dey - lda (ptr4),y ; get memory buffer low - sta ptr2 ; src high - lda #$00 - sta tmp2 ; src bank - - jsr transfer - - rts - -; ------------------------------------------------------------------------ -; Helper function for moving a block, the following is used: -; ptr1: dst -; ptr2: src -; ptr3: length -; tmp1: dst bank -; tmp2: src bank - -transfer: -.P816 -.A8 -.I8 - sei - pha - phx - phy - ldx tmp1 ; load srcbank - stx @move+1 ; store srcbank in move + 1 - ldy tmp2 ; load dstbank - sty @move+2 ; store dstbank in move + 2 - clc ; switch to native mode - xce - php ; save status bits - rep #%00110000 ; set A and index to 16bit -.A16 -.I16 - ldy ptr1 - ldx ptr2 - lda ptr3 -@move: - mvn 0,0 - plp ; restore status bits -.A8 -.I8 - lda #$00 - pha - plb ; restore dbr - sec - xce ; switch to emul mode - ply - plx - pla - cli - rts -.P02 +; +; Extended memory driver for 65816 based extra RAM. Driver works without +; problems when statically linked. +; +; Marco van den Heuvel, 2015-12-01 +; + + .include "zeropage.inc" + + .include "em-kernel.inc" + .include "em-error.inc" + + + .macpack generic + .macpack module + + +; ------------------------------------------------------------------------ +; Header. Includes jump table + + module_header _c64_65816_emd + +; Driver signature + + .byte $65, $6d, $64 ; "emd" + .byte EMD_API_VERSION ; EM API version number + +; Library reference + + .addr $0000 + +; Jump table + + .addr INSTALL + .addr UNINSTALL + .addr PAGECOUNT + .addr MAP + .addr USE + .addr COMMIT + .addr COPYFROM + .addr COPYTO + +; ------------------------------------------------------------------------ +; Data. + +.bss +isnotscpu: .res 1 ; SuperCPU not present +curpage: .res 1 ; Current page number +curbank: .res 1 ; Current bank number (+1) +bankcount: .res 1 ; Number of available banks (pages = banks * 256) +window: .res 256 ; Memory "window" + +.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 EM_ERR_xx code in a/x. +; + +INSTALL: + sei + clc + sed + lda #$99 + adc #$01 ; on 65C02, 65SC02, 65CE02, 65802 and 65816 sets the zero flag correctly + cld + bne @not_present + clc +.P816 + sep #$01 ; nop #$01 on 65C02/65SC02 and lda ($01,s),y on 65CE02 +.P02 + bcc @not_present + lda $d0bc + and #$80 + sta isnotscpu + lda $07e8 + pha ; save value incase it was used somewhere else + ldx #$ff +@fillloop: ; fill from top (bank 255) to bottom + txa + pha +.P816 + plb ; pull dbr +.P02 + stx $07e8 + dex + cpx #$ff + bne @fillloop + inx +@compareloop: ; check from bottom to top + txa + pha +.P816 + plb +.P02 + cmp $07e8 + bne @found_pages +.P816 + inc +.P02 + sta $07e8 + cmp $07e8 + bne @found_pages + inx + bne @compareloop +@found_pages: + dex + lda #$00 + pha +.P816 + plb +.P02 + pla + sta $07e8 + cli + lda isnotscpu + bne @noextradex + dex +@noextradex: + stx bankcount + lda #<EM_ERR_OK + ldx #>EM_ERR_OK + rts +@not_present: + cli + lda #<EM_ERR_NO_DEVICE + ldx #>EM_ERR_NO_DEVICE +; 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 + + +; ------------------------------------------------------------------------ +; PAGECOUNT: Return the total number of available pages in a/x. +; + +PAGECOUNT: + lda #$00 ; a whole bank is either usable or not + ldx bankcount + rts + +; ------------------------------------------------------------------------ +; MAP: Map the page in a/x into memory and return a pointer to the page in +; a/x. The contents of the currently mapped page (if any) may be discarded +; by the driver. +; + +MAP: sta curpage ; Remember the new page + stx curbank ; Remember the new bank + + sta ptr2+1 ; src address low + lda #$00 + sta ptr2 ; src address high + inx + ldy isnotscpu ; check if not scpu + bne @notscpu + inx +@notscpu: + stx tmp2 ; src bank + + sta tmp1 ; dst bank + + sta ptr3+1 ; length high + lda #$ff + sta ptr3 ; length low + + lda #<window + sta ptr1 ; dst address low + ldx #>window + stx ptr1+1 ; dst address high + + jsr transfer + + rts + +; ------------------------------------------------------------------------ +; USE: Tell the driver that the window is now associated with a given page. + +USE: sta curpage ; Remember the page + stx curbank ; Remember the bank + lda #<window + ldx #>window ; Return the window + rts + +; ------------------------------------------------------------------------ +; COMMIT: Commit changes in the memory window to extended storage. + +COMMIT: lda curpage ; Get the current page + sta ptr1+1 ; dst high + ldx #$00 + stx ptr1 ; dst low + + lda #<window + sta ptr2 ; src low + lda #>window + sta ptr2+1 ; src high + + stx ptr3+1 ; length high + lda #$ff + sta ptr3 ; length low + + stx tmp2 ; src bank + ldy curbank ; Get the current bank + iny + ldx isnotscpu + bne @notascpu + iny +@notascpu: + sty tmp1 ; dst bank + + jsr transfer + + rts + +; ------------------------------------------------------------------------ +; COPYFROM: Copy from extended into linear memory. A pointer to a structure +; describing the request is passed in a/x. +; The function must not return anything. +; + +COPYFROM: + sta ptr4 + stx ptr4+1 ; Save the passed em_copy pointer + + ldy #EM_COPY::COUNT+1 ; start at the end of the struct + lda (ptr4),y ; get high byte of count + tax + dey + lda (ptr4),y ; get low byte of count + bne @nodex + dex +@nodex: +.P816 + dec +.P02 + sta ptr3 ; length low + stx ptr3+1 ; length high + dey + lda (ptr4),y ; get bank +.P816 + inc +.P02 + ldx isnotscpu + bne @notscpu64 +.P816 + inc +.P02 +@notscpu64: + sta tmp2 ; src bank + dey + lda (ptr4),y ; get page + sta ptr2+1 ; src high + dey + lda (ptr4),y ; get offset in page + sta ptr2 ; src low + dey + lda (ptr4),y ; get memory buffer high + sta ptr1+1 ; dst high + dey + lda (ptr4),y ; get memory buffer low + sta ptr1 ; dst low + lda #$00 + sta tmp1 ; dst bank + + jsr transfer + + rts + +; ------------------------------------------------------------------------ +; COPYTO: Copy from linear into extended memory. A pointer to a structure +; describing the request is passed in a/x. +; The function must not return anything. +; + +COPYTO: sta ptr4 + stx ptr4+1 ; Save the passed em_copy pointer + + ldy #EM_COPY::COUNT+1 ; start at the end of the struct + lda (ptr4),y ; get high byte of count + tax + dey + lda (ptr4),y ; get low byte of count + bne @nodex2 + dex +@nodex2: +.P816 + dec +.P02 + sta ptr3 ; length low + txa + sta ptr3+1 ; length high + dey + lda (ptr4),y ; get bank +.P816 + inc +.P02 + ldx isnotscpu + bne @notascpu64 +.P816 + inc +.P02 +@notascpu64: + sta tmp1 ; dst bank + dey + lda (ptr4),y ; get page + sta ptr1+1 ; dst high + dey + lda (ptr4),y ; get page offset + sta ptr1 ; dst low + dey + lda (ptr4),y ; get memory buffer high + sta ptr2+1 ; src low + dey + lda (ptr4),y ; get memory buffer low + sta ptr2 ; src high + lda #$00 + sta tmp2 ; src bank + + jsr transfer + + rts + +; ------------------------------------------------------------------------ +; Helper function for moving a block, the following is used: +; ptr1: dst +; ptr2: src +; ptr3: length +; tmp1: dst bank +; tmp2: src bank + +transfer: +.P816 +.A8 +.I8 + sei + pha + phx + phy + ldx tmp1 ; load srcbank + stx @move+1 ; store srcbank in move + 1 + ldy tmp2 ; load dstbank + sty @move+2 ; store dstbank in move + 2 + clc ; switch to native mode + xce + php ; save status bits + rep #%00110000 ; set A and index to 16bit +.A16 +.I16 + ldy ptr1 + ldx ptr2 + lda ptr3 +@move: + mvn 0,0 + plp ; restore status bits +.A8 +.I8 + lda #$00 + pha + plb ; restore dbr + sec + xce ; switch to emul mode + ply + plx + pla + cli + rts +.P02 diff --git a/libsrc/osic1p/cgetc.s b/libsrc/osic1p/cgetc.s index 9161645c7..f05ad33e0 100644 --- a/libsrc/osic1p/cgetc.s +++ b/libsrc/osic1p/cgetc.s @@ -1,50 +1,50 @@ -; -; char cgetc (void); -; - - .constructor initcgetc - .export _cgetc - .import cursor - - .include "osic1p.inc" - .include "extzp.inc" - .include "zeropage.inc" - -; Initialize one-character buffer that is filled by kbhit() - .segment "ONCE" -initcgetc: - lda #$00 - sta CHARBUF ; No character in buffer initially - rts - -; Input routine from 65V PROM MONITOR, show cursor if enabled - .code -_cgetc: - lda CHARBUF ; character in buffer available? - beq nobuffer - tax ; save character in X - lda #$00 - sta CHARBUF ; empty buffer - beq restorex ; restore X and return -nobuffer: - lda cursor ; show cursor? - beq nocursor - ldy CURS_X - lda (SCREEN_PTR),y ; fetch current character - sta tmp1 ; save it - lda #$A1 ; full white square - sta (SCREEN_PTR),y ; store at cursor position -nocursor: - jsr INPUTC ; get input character in A - ldx cursor - beq done ; was cursor on? - tax ; save A in X - lda tmp1 ; fetch saved character - ldy CURS_X - sta (SCREEN_PTR),y ; store at cursor position - -restorex: - txa ; restore saved character from X -done: - ldx #$00 ; high byte of int return value - rts +; +; char cgetc (void); +; + + .constructor initcgetc + .export _cgetc + .import cursor + + .include "osic1p.inc" + .include "extzp.inc" + .include "zeropage.inc" + +; Initialize one-character buffer that is filled by kbhit() + .segment "ONCE" +initcgetc: + lda #$00 + sta CHARBUF ; No character in buffer initially + rts + +; Input routine from 65V PROM MONITOR, show cursor if enabled + .code +_cgetc: + lda CHARBUF ; character in buffer available? + beq nobuffer + tax ; save character in X + lda #$00 + sta CHARBUF ; empty buffer + beq restorex ; restore X and return +nobuffer: + lda cursor ; show cursor? + beq nocursor + ldy CURS_X + lda (SCREEN_PTR),y ; fetch current character + sta tmp1 ; save it + lda #$A1 ; full white square + sta (SCREEN_PTR),y ; store at cursor position +nocursor: + jsr INPUTC ; get input character in A + ldx cursor + beq done ; was cursor on? + tax ; save A in X + lda tmp1 ; fetch saved character + ldy CURS_X + sta (SCREEN_PTR),y ; store at cursor position + +restorex: + txa ; restore saved character from X +done: + ldx #$00 ; high byte of int return value + rts diff --git a/libsrc/osic1p/osic1p.inc b/libsrc/osic1p/osic1p.inc index eabeaf79e..aaa03ba61 100644 --- a/libsrc/osic1p/osic1p.inc +++ b/libsrc/osic1p/osic1p.inc @@ -1,4 +1,4 @@ -; Addresses -INPUTC := $FD00 ; Input character from keyboard -RESET := $FF00 ; Reset address, show boot prompt -KBD := $DF00 ; Polled keyboard register +; Addresses +INPUTC := $FD00 ; Input character from keyboard +RESET := $FF00 ; Reset address, show boot prompt +KBD := $DF00 ; Polled keyboard register diff --git a/libsrc/osic1p/osiscreen.inc b/libsrc/osic1p/osiscreen.inc index fc8324781..9399d7eee 100644 --- a/libsrc/osic1p/osiscreen.inc +++ b/libsrc/osic1p/osiscreen.inc @@ -1,183 +1,183 @@ -; -; Macro definitions for screen layout modules -; - - .include "extzp.inc" - -.linecont + - -; -; Internal function for screensize() -; -.macro osi_screensize ScrWidth, ScrHeight - ; Macro implementation of internal screensize - ; function for given width and height in - ; characters - - .export screensize - -.proc screensize - ldx #ScrWidth - ldy #ScrHeight - rts -.endproc -.endmacro - -; -; void clrscr (void); -; -.macro osi_clrscr ScrBase, ScrRamSize - - .export _clrscr - -.proc _clrscr - lda #<ScrBase ; Fill whole video RAM with blanks by calling - ldx #>ScrBase ; memset appropriately - jsr pushax - - lda #' ' - ldx #$00 - jsr pushax - - lda #<ScrRamSize - ldx #>ScrRamSize - jsr _memset - - lda #$00 ; Cursor in upper left corner - sta CURS_X - sta CURS_Y - - jmp plot ; Set the cursor position -.endproc - -.endmacro - -; -; cputc/cputcxy for Challenger 1P -; Based on PET/CBM implementation -; - -.macro osi_cputfuncs ScrBase, ScrFirstChar, ScrWidth, ScrHeight, \ - ScrollDist, ScrLo, ScrHi - - ; Number of characters to move for scrolling - ; by one line -ScrollLength = (ScrHeight - 1) * ScrollDist - -; -; void cputcxy (unsigned char x, unsigned char y, char c); -; void cputc (char c); -; - .export _cputcxy, _cputc, cputdirect, putchar - .export newline, plot - -_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 - -cputdirect: - jsr putchar ; Write the character to the screen - -; Advance cursor position, register Y contains horizontal position after -; putchar - - cpy #(ScrWidth - 1) ; Check whether line is full - bne L3 - jsr newline ; New line - ldy #$FF ; + cr -L3: iny - sty CURS_X - rts - -newline: - inc CURS_Y - lda CURS_Y - cmp #ScrHeight ; Screen height - bne plot - dec CURS_Y ; Bottom of screen reached, scroll - - ; Scroll destination address - lda #<(ScrBase + ScrFirstChar) - ldx #>(ScrBase + ScrFirstChar) - jsr pushax - - ; Scroll source address - lda #<(ScrBase + ScrFirstChar + ScrollDist) - ldx #>(ScrBase + ScrFirstChar + ScrollDist) - jsr pushax - - ; Number of characters to move - lda #<ScrollLength - ldx #>ScrollLength - jsr _memmove - - ; Address of first character in last line - ; of screen - lda #<(ScrBase + ScrFirstChar + ScrollLength) - sta ptr1 - lda #>(ScrBase + ScrFirstChar + ScrollLength) - sta ptr1+1 - - ldy #ScrWidth ; Fill last line with blanks - lda #' ' -clrln: sta (ptr1),y - dey - bpl clrln - -plot: ldy CURS_Y - lda ScrLo,y - sta SCREEN_PTR - lda ScrHi,y - sta SCREEN_PTR+1 - rts - -; Write one character to the screen without doing anything else, return X -; position in register Y - -putchar: - ldy CURS_X - sta (SCREEN_PTR),y ; Set char - rts - -.endmacro - -.macro osi_screen_funcs ScrBase, ScrRamSize, ScrFirstChar, \ - ScrWidth, ScrHeight, ScrollDist - - .import gotoxy - .import _memmove, _memset, pushax - .importzp ptr1 - -.rodata - -; Screen address tables - offset to real screen -ScrTabLo: - .repeat ScrHeight, I - .byte <(ScrBase + ScrFirstChar + I * ScrollDist) - .endrep - -ScrTabHi: - .repeat ScrHeight, I - .byte >(ScrBase + ScrFirstChar + I * ScrollDist) - .endrep - -.code - -osi_cputfuncs ScrBase, ScrFirstChar, ScrWidth, ScrHeight, \ - ScrollDist, ScrTabLo, ScrTabHi -osi_screensize ScrWidth, ScrHeight -osi_clrscr ScrBase, ScrRamSize - +; +; Macro definitions for screen layout modules +; + + .include "extzp.inc" + +.linecont + + +; +; Internal function for screensize() +; +.macro osi_screensize ScrWidth, ScrHeight + ; Macro implementation of internal screensize + ; function for given width and height in + ; characters + + .export screensize + +.proc screensize + ldx #ScrWidth + ldy #ScrHeight + rts +.endproc +.endmacro + +; +; void clrscr (void); +; +.macro osi_clrscr ScrBase, ScrRamSize + + .export _clrscr + +.proc _clrscr + lda #<ScrBase ; Fill whole video RAM with blanks by calling + ldx #>ScrBase ; memset appropriately + jsr pushax + + lda #' ' + ldx #$00 + jsr pushax + + lda #<ScrRamSize + ldx #>ScrRamSize + jsr _memset + + lda #$00 ; Cursor in upper left corner + sta CURS_X + sta CURS_Y + + jmp plot ; Set the cursor position +.endproc + +.endmacro + +; +; cputc/cputcxy for Challenger 1P +; Based on PET/CBM implementation +; + +.macro osi_cputfuncs ScrBase, ScrFirstChar, ScrWidth, ScrHeight, \ + ScrollDist, ScrLo, ScrHi + + ; Number of characters to move for scrolling + ; by one line +ScrollLength = (ScrHeight - 1) * ScrollDist + +; +; void cputcxy (unsigned char x, unsigned char y, char c); +; void cputc (char c); +; + .export _cputcxy, _cputc, cputdirect, putchar + .export newline, plot + +_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 + +cputdirect: + jsr putchar ; Write the character to the screen + +; Advance cursor position, register Y contains horizontal position after +; putchar + + cpy #(ScrWidth - 1) ; Check whether line is full + bne L3 + jsr newline ; New line + ldy #$FF ; + cr +L3: iny + sty CURS_X + rts + +newline: + inc CURS_Y + lda CURS_Y + cmp #ScrHeight ; Screen height + bne plot + dec CURS_Y ; Bottom of screen reached, scroll + + ; Scroll destination address + lda #<(ScrBase + ScrFirstChar) + ldx #>(ScrBase + ScrFirstChar) + jsr pushax + + ; Scroll source address + lda #<(ScrBase + ScrFirstChar + ScrollDist) + ldx #>(ScrBase + ScrFirstChar + ScrollDist) + jsr pushax + + ; Number of characters to move + lda #<ScrollLength + ldx #>ScrollLength + jsr _memmove + + ; Address of first character in last line + ; of screen + lda #<(ScrBase + ScrFirstChar + ScrollLength) + sta ptr1 + lda #>(ScrBase + ScrFirstChar + ScrollLength) + sta ptr1+1 + + ldy #ScrWidth ; Fill last line with blanks + lda #' ' +clrln: sta (ptr1),y + dey + bpl clrln + +plot: ldy CURS_Y + lda ScrLo,y + sta SCREEN_PTR + lda ScrHi,y + sta SCREEN_PTR+1 + rts + +; Write one character to the screen without doing anything else, return X +; position in register Y + +putchar: + ldy CURS_X + sta (SCREEN_PTR),y ; Set char + rts + +.endmacro + +.macro osi_screen_funcs ScrBase, ScrRamSize, ScrFirstChar, \ + ScrWidth, ScrHeight, ScrollDist + + .import gotoxy + .import _memmove, _memset, pushax + .importzp ptr1 + +.rodata + +; Screen address tables - offset to real screen +ScrTabLo: + .repeat ScrHeight, I + .byte <(ScrBase + ScrFirstChar + I * ScrollDist) + .endrep + +ScrTabHi: + .repeat ScrHeight, I + .byte >(ScrBase + ScrFirstChar + I * ScrollDist) + .endrep + +.code + +osi_cputfuncs ScrBase, ScrFirstChar, ScrWidth, ScrHeight, \ + ScrollDist, ScrTabLo, ScrTabHi +osi_screensize ScrWidth, ScrHeight +osi_clrscr ScrBase, ScrRamSize + .endmacro \ No newline at end of file diff --git a/test/ref/divmod.c b/test/ref/divmod.c index 68a0198e1..8fcc951a6 100644 --- a/test/ref/divmod.c +++ b/test/ref/divmod.c @@ -1,38 +1,38 @@ -/* - !!DESCRIPTION!! div/mod test - !!ORIGIN!! - !!LICENCE!! public domain -*/ - -#include <stdio.h> - -void printc(signed char a,signed char b){ -signed char x=a/b,y=a%b,z=a*b; - printf("%3d,%3d is %3d,%3d,%3d\n",a,b,x,y,z); -} -void prints(short a,short b){ -short x=a/b,y=a%b,z=a*b; - printf("%3d,%3d is %3d,%3d,%3d\n",a,b,x,y,z); -} -void printl(long a,long b){ -long x=a/b,y=a%b,z=a*b; - printf("%3ld,%3ld is %3ld,%3ld,%3ld\n",a,b,x,y,z); -} - -int main(void) { - printl( 3,-2); - printl(-3,-2); - printl(-3, 2); - printl( 3, 2); - printf("-\n"); - prints( 3,-2); - prints(-3,-2); - prints(-3, 2); - prints( 3, 2); - printf("-\n"); - printc( 3,-2); - printc(-3,-2); - printc(-3, 2); - printc( 3, 2); +/* + !!DESCRIPTION!! div/mod test + !!ORIGIN!! + !!LICENCE!! public domain +*/ + +#include <stdio.h> + +void printc(signed char a,signed char b){ +signed char x=a/b,y=a%b,z=a*b; + printf("%3d,%3d is %3d,%3d,%3d\n",a,b,x,y,z); +} +void prints(short a,short b){ +short x=a/b,y=a%b,z=a*b; + printf("%3d,%3d is %3d,%3d,%3d\n",a,b,x,y,z); +} +void printl(long a,long b){ +long x=a/b,y=a%b,z=a*b; + printf("%3ld,%3ld is %3ld,%3ld,%3ld\n",a,b,x,y,z); +} + +int main(void) { + printl( 3,-2); + printl(-3,-2); + printl(-3, 2); + printl( 3, 2); + printf("-\n"); + prints( 3,-2); + prints(-3,-2); + prints(-3, 2); + prints( 3, 2); + printf("-\n"); + printc( 3,-2); + printc(-3,-2); + printc(-3, 2); + printc( 3, 2); return 0; -} +} diff --git a/test/ref/init.c b/test/ref/init.c index 5a5816753..44cd544fd 100644 --- a/test/ref/init.c +++ b/test/ref/init.c @@ -1,95 +1,95 @@ -/* - !!DESCRIPTION!! variable initialization - !!ORIGIN!! LCC 4.1 Testsuite - !!LICENCE!! own, freely distributeable for non-profit. read CPYRIGHT.LCC -*/ - -#include "common.h" -/* todo: add back conditional stuff here ! */ - -typedef struct { int codes[3]; char name[6]; } Word; - -#ifdef NO_IMPLICIT_FUNC_PROTOTYPES - -#ifdef NO_OLD_FUNC_DECL -f(); -void g(Word *p); -h(); -#else -f(); -g(); -h(); -#endif - -#endif - -/* -Word words[] = { - 1, 2, 3,"if", - { { 4, 5 }, { 'f', 'o', 'r' } }, - 6, 7, 8, {"else"}, - { { 9, 10, 11,}, 'w', 'h', 'i', 'l', 'e', }, - { 0 }, -}, *wordlist = words; -*/ - -Word words[] = { - {{1, 2, 3},"if"}, - { { 4, 5 }, { 'f', 'o', 'r' } }, - {{6, 7, 8}, "else"}, - { { 9, 10, 11}, {'w', 'h', 'i', 'l', 'e', }}, - {{ 0 }}, -}, *wordlist = words; - -/*int x[][5] = { 1, 2, 3, 4, 0, { 5, 6 }, { 7 } };*/ -int x[][5] = { {1, 2, 3, 4, 0 }, { 5, 6 }, { 7 } }; -int *y[] = { x[0], x[1], x[2], 0 }; - -main() -{ - int i, j; - - for (i = 0; y[i]; i++) { - for (j = 0; y[i][j]; j++) - printf(" %d", y[i][j]); - printf("\n"); - } - f(); - g(wordlist); - return 0; -} - -f() { - static char *keywords[] = {"if", "for", "else", "while", 0, }; - char **p; - - for (p = keywords; *p; p++) - printf("%s\n", *p); -} - -#ifdef NO_OLD_FUNC_DECL -void g(Word *p) -#else -g(p) -Word *p; -#endif -{ - int i; - - for ( ; p->codes[0]; p++) { - for (i = 0; i < sizeof p->codes/sizeof(p->codes[0]); i++) - printf("%d ", p->codes[i]); - printf("%s\n", p->name); - } - h(); -} - -h() -{ - int i; - - for (i = 0; i < sizeof(words)/sizeof(Word); i++) - printf("%d %d %d %s\n", words[i].codes[0], - words[i].codes[1], words[i].codes[2], - &words[i].name[0]); -} +/* + !!DESCRIPTION!! variable initialization + !!ORIGIN!! LCC 4.1 Testsuite + !!LICENCE!! own, freely distributeable for non-profit. read CPYRIGHT.LCC +*/ + +#include "common.h" +/* todo: add back conditional stuff here ! */ + +typedef struct { int codes[3]; char name[6]; } Word; + +#ifdef NO_IMPLICIT_FUNC_PROTOTYPES + +#ifdef NO_OLD_FUNC_DECL +f(); +void g(Word *p); +h(); +#else +f(); +g(); +h(); +#endif + +#endif + +/* +Word words[] = { + 1, 2, 3,"if", + { { 4, 5 }, { 'f', 'o', 'r' } }, + 6, 7, 8, {"else"}, + { { 9, 10, 11,}, 'w', 'h', 'i', 'l', 'e', }, + { 0 }, +}, *wordlist = words; +*/ + +Word words[] = { + {{1, 2, 3},"if"}, + { { 4, 5 }, { 'f', 'o', 'r' } }, + {{6, 7, 8}, "else"}, + { { 9, 10, 11}, {'w', 'h', 'i', 'l', 'e', }}, + {{ 0 }}, +}, *wordlist = words; + +/*int x[][5] = { 1, 2, 3, 4, 0, { 5, 6 }, { 7 } };*/ +int x[][5] = { {1, 2, 3, 4, 0 }, { 5, 6 }, { 7 } }; +int *y[] = { x[0], x[1], x[2], 0 }; + +main() +{ + int i, j; + + for (i = 0; y[i]; i++) { + for (j = 0; y[i][j]; j++) + printf(" %d", y[i][j]); + printf("\n"); + } + f(); + g(wordlist); + return 0; +} + +f() { + static char *keywords[] = {"if", "for", "else", "while", 0, }; + char **p; + + for (p = keywords; *p; p++) + printf("%s\n", *p); +} + +#ifdef NO_OLD_FUNC_DECL +void g(Word *p) +#else +g(p) +Word *p; +#endif +{ + int i; + + for ( ; p->codes[0]; p++) { + for (i = 0; i < sizeof p->codes/sizeof(p->codes[0]); i++) + printf("%d ", p->codes[i]); + printf("%s\n", p->name); + } + h(); +} + +h() +{ + int i; + + for (i = 0; i < sizeof(words)/sizeof(Word); i++) + printf("%d %d %d %s\n", words[i].codes[0], + words[i].codes[1], words[i].codes[2], + &words[i].name[0]); +} diff --git a/test/ref/pointer2.c b/test/ref/pointer2.c index d8c064ef3..29f9e3de4 100644 --- a/test/ref/pointer2.c +++ b/test/ref/pointer2.c @@ -1,112 +1,112 @@ -/* - !!DESCRIPTION!! pointer test - !!ORIGIN!! - !!LICENCE!! public domain -*/ - -#include "common.h" -#include <stdio.h> - -/* - check behaviour on incompletely declared arrays -*/ - -char i1[]; - -void test1(void) { -int a; - - a=sizeof(i1[0]); - printf("%04x - ",a); - if(sizeof(i1[0])==sizeof(char)) { - /* gcc gives size of element */ - printf("sizeof(i1[0]) gives size of element\n"); - } - if(sizeof(i1[0])==sizeof(char*)) { - printf("sizeof(i1[0]) gives size of pointer to element\n"); - } -} - -/* - check behaviour on string init -*/ - -char t1[]="abcde"; -char t2[]={"abcde"}; - -char *t3="abcde"; -char *t4={"abcde"}; - -void test2(void) { -char c1,c2,c3,c4; -int i,e=0; - for(i=0;i<5;i++){ - c1=t1[i];c2=t2[i];c3=t3[i];c4=t4[i]; -/* printf("%02x %02x %02x %02x\n",c1,c2,c3,c4); */ - printf("%c %c %c %c\n",c1,c2,c3,c4); - if(!((c1==c2)&(c1==c3)&(c1==c4))) e=1; - } - if(e) printf("test2 failed.\n"); - else printf("test2 ok.\n"); -} - -/* - check behaviour on extern-declarations inside functions -*/ - -typedef struct { - char *name; - void *func; -} A3; - -#ifdef NO_SLOPPY_STRUCT_INIT -A3 a3[] = { - { "test3", (void*) NULL }, - { "test3", (void*) NULL }, -}; -#else -/*gcc warning: missing braces around initializer (near initialization for `a3[0]') - this type of struct-initialization seems to be kinda common */ -A3 a3[] = { - "test3", (void*) NULL , - "test3", (void*) NULL , -}; -#endif - -void test3a(A3 *list, int number){ - printf("%s %d\n",list->name,number); -} - -static void test31(void) -{ - extern A3 a3[]; - test3a(a3, -1); -} - -#if 0 -/* this variation compiles and works with cc65, but gives an error with gcc :=P */ -static void test32(void) -{ - extern A3 *a3; - test3a(a3, -1); -} -#endif - -static void test30(void) -{ - test3a(a3, -1); -} - -/* - todo: add test on function pointers in the form of (*func)(arg) ... - cc65 seems to have problems here aswell ;/ -*/ - -int main(void) { - test1(); - test2(); - test30(); - test31(); -/* test32(); */ - return 0; -} +/* + !!DESCRIPTION!! pointer test + !!ORIGIN!! + !!LICENCE!! public domain +*/ + +#include "common.h" +#include <stdio.h> + +/* + check behaviour on incompletely declared arrays +*/ + +char i1[]; + +void test1(void) { +int a; + + a=sizeof(i1[0]); + printf("%04x - ",a); + if(sizeof(i1[0])==sizeof(char)) { + /* gcc gives size of element */ + printf("sizeof(i1[0]) gives size of element\n"); + } + if(sizeof(i1[0])==sizeof(char*)) { + printf("sizeof(i1[0]) gives size of pointer to element\n"); + } +} + +/* + check behaviour on string init +*/ + +char t1[]="abcde"; +char t2[]={"abcde"}; + +char *t3="abcde"; +char *t4={"abcde"}; + +void test2(void) { +char c1,c2,c3,c4; +int i,e=0; + for(i=0;i<5;i++){ + c1=t1[i];c2=t2[i];c3=t3[i];c4=t4[i]; +/* printf("%02x %02x %02x %02x\n",c1,c2,c3,c4); */ + printf("%c %c %c %c\n",c1,c2,c3,c4); + if(!((c1==c2)&(c1==c3)&(c1==c4))) e=1; + } + if(e) printf("test2 failed.\n"); + else printf("test2 ok.\n"); +} + +/* + check behaviour on extern-declarations inside functions +*/ + +typedef struct { + char *name; + void *func; +} A3; + +#ifdef NO_SLOPPY_STRUCT_INIT +A3 a3[] = { + { "test3", (void*) NULL }, + { "test3", (void*) NULL }, +}; +#else +/*gcc warning: missing braces around initializer (near initialization for `a3[0]') + this type of struct-initialization seems to be kinda common */ +A3 a3[] = { + "test3", (void*) NULL , + "test3", (void*) NULL , +}; +#endif + +void test3a(A3 *list, int number){ + printf("%s %d\n",list->name,number); +} + +static void test31(void) +{ + extern A3 a3[]; + test3a(a3, -1); +} + +#if 0 +/* this variation compiles and works with cc65, but gives an error with gcc :=P */ +static void test32(void) +{ + extern A3 *a3; + test3a(a3, -1); +} +#endif + +static void test30(void) +{ + test3a(a3, -1); +} + +/* + todo: add test on function pointers in the form of (*func)(arg) ... + cc65 seems to have problems here aswell ;/ +*/ + +int main(void) { + test1(); + test2(); + test30(); + test31(); +/* test32(); */ + return 0; +} diff --git a/test/ref/switch2.c b/test/ref/switch2.c index e75cfe71e..7a9bcecd7 100644 --- a/test/ref/switch2.c +++ b/test/ref/switch2.c @@ -1,262 +1,262 @@ -/* - !!DESCRIPTION!! switch test - !!ORIGIN!! - !!LICENCE!! public domain -*/ - -/*#define STANDALONE*/ - -#include <stdio.h> - +/* + !!DESCRIPTION!! switch test + !!ORIGIN!! + !!LICENCE!! public domain +*/ + +/*#define STANDALONE*/ + +#include <stdio.h> + void testlimits(int i) { - printf("%d:",i); - + printf("%d:",i); + switch(i) { - case -1: /* works */ - /* case 0xffff: */ /* 'range error' (-1) */ - - printf("-1\n"); - break; - /* max int */ - -/* case 0x7fff: */ /* works */ - case 32767: /* works */ - /* case 32768: */ /* 'range error' (correct for that one!) */ - - printf("max\n"); - break; - /* min int */ - - case -32768: /* 'warning. constant is long' */ - /* case 0x8000: */ /* 'range error' */ - /* case -32769: */ /* 'range error' (correct for that one!) */ - printf("min\n"); - break; - } - printf("\n"); -} - -void testdefault1(unsigned char i) { -/* we want a signed char */ -#ifdef REFCC - -#ifdef REFCC_UNSIGNED_CHARS -signed char k; -#else -char k; -#endif - -#else - -#ifdef UNSIGNED_CHARS -signed char k; -#else -char k; -#endif - -#endif - - for(;i<254;) { - k = i; - printf(">%d\n",i);i++; - switch(k) { - case 1: - break; - case 2: - break; - case 3: - break; - case 4: - break; - case 5: - break; - case 6: - break; - case 7: - break; - case 8: - break; - case 9: - break; - case 10: - break; - case 11: - break; - case 12: - break; - case 13: - break; - case 14: - break; - case 15: - break; - case 17: - break; - /* triggers bug ? */ - /* gcc warning: case label value exceeds maximum value for type */ - /* cc65 error: range error */ - - /* - case 170: - break; - */ - case 18: - break; - case 19: - break; - case 20: - break; - case 21: - break; - case 22: - break; - case 23: - break; - case 24: - switch(k) { - case 1: - break; - case 2: - break; - case 3: - break; - case 4: - case 5: - break; - case 6: - case 7: - break; - case 8: - case 9: - break; - } - break; - case 100: - break; - default: - printf(">>>default\n"); - /* triggers bug if this break; is missing? */ - /* break; */ - } - } -} - -void testdefault2(unsigned char i) { -/* we want a unsigned char */ -#ifdef REFCC - -#ifdef REFCC_UNSIGNED_CHARS -char k; -#else -unsigned char k; -#endif - -#else - -#ifdef UNSIGNED_CHARS -char k; -#else -unsigned char k; -#endif - -#endif - - for(;i<254;) { - k = i; - printf(">%d\n",i);i++; - switch(k) { - case 1: - break; - case 2: - break; - case 3: - break; - case 4: - break; - case 5: - break; - case 6: - break; - case 7: - break; - case 8: - break; - case 9: - break; - case 10: - break; - case 11: - break; - case 12: - break; - case 13: - break; - case 14: - break; - case 15: - break; - case 17: - break; - /* triggers bug ? */ - - case 170: - break; - - case 18: - break; - case 19: - break; - case 20: - break; - case 21: - break; - case 22: - break; - case 23: - break; - case 24: - switch(k) { - case 1: - break; - case 2: - break; - case 3: - break; - case 4: - case 5: - break; - case 6: - case 7: - break; - case 8: - case 9: - break; - } - break; - case 100: - break; - default: - printf(">>>default\n"); - /* triggers bug if this break; is missing? */ - /* break; */ - } - } + case -1: /* works */ + /* case 0xffff: */ /* 'range error' (-1) */ + + printf("-1\n"); + break; + /* max int */ + +/* case 0x7fff: */ /* works */ + case 32767: /* works */ + /* case 32768: */ /* 'range error' (correct for that one!) */ + + printf("max\n"); + break; + /* min int */ + + case -32768: /* 'warning. constant is long' */ + /* case 0x8000: */ /* 'range error' */ + /* case -32769: */ /* 'range error' (correct for that one!) */ + printf("min\n"); + break; + } + printf("\n"); +} + +void testdefault1(unsigned char i) { +/* we want a signed char */ +#ifdef REFCC + +#ifdef REFCC_UNSIGNED_CHARS +signed char k; +#else +char k; +#endif + +#else + +#ifdef UNSIGNED_CHARS +signed char k; +#else +char k; +#endif + +#endif + + for(;i<254;) { + k = i; + printf(">%d\n",i);i++; + switch(k) { + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + break; + case 7: + break; + case 8: + break; + case 9: + break; + case 10: + break; + case 11: + break; + case 12: + break; + case 13: + break; + case 14: + break; + case 15: + break; + case 17: + break; + /* triggers bug ? */ + /* gcc warning: case label value exceeds maximum value for type */ + /* cc65 error: range error */ + + /* + case 170: + break; + */ + case 18: + break; + case 19: + break; + case 20: + break; + case 21: + break; + case 22: + break; + case 23: + break; + case 24: + switch(k) { + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + case 5: + break; + case 6: + case 7: + break; + case 8: + case 9: + break; + } + break; + case 100: + break; + default: + printf(">>>default\n"); + /* triggers bug if this break; is missing? */ + /* break; */ + } + } +} + +void testdefault2(unsigned char i) { +/* we want a unsigned char */ +#ifdef REFCC + +#ifdef REFCC_UNSIGNED_CHARS +char k; +#else +unsigned char k; +#endif + +#else + +#ifdef UNSIGNED_CHARS +char k; +#else +unsigned char k; +#endif + +#endif + + for(;i<254;) { + k = i; + printf(">%d\n",i);i++; + switch(k) { + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + break; + case 7: + break; + case 8: + break; + case 9: + break; + case 10: + break; + case 11: + break; + case 12: + break; + case 13: + break; + case 14: + break; + case 15: + break; + case 17: + break; + /* triggers bug ? */ + + case 170: + break; + + case 18: + break; + case 19: + break; + case 20: + break; + case 21: + break; + case 22: + break; + case 23: + break; + case 24: + switch(k) { + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + case 5: + break; + case 6: + case 7: + break; + case 8: + case 9: + break; + } + break; + case 100: + break; + default: + printf(">>>default\n"); + /* triggers bug if this break; is missing? */ + /* break; */ + } + } } int main(void) { - testlimits(32767); - testlimits(-32768); - testlimits(-1); - - testdefault1(1); - testdefault1(2); - testdefault1(3); - testdefault1(4); - - testdefault2(1); - testdefault2(2); - testdefault2(3); - testdefault2(4); - - return 0; -} + testlimits(32767); + testlimits(-32768); + testlimits(-1); + + testdefault1(1); + testdefault1(2); + testdefault1(3); + testdefault1(4); + + testdefault2(1); + testdefault2(2); + testdefault2(3); + testdefault2(4); + + return 0; +} diff --git a/test/ref/varargs.c b/test/ref/varargs.c index 11fd33b38..3d61fdbd0 100644 --- a/test/ref/varargs.c +++ b/test/ref/varargs.c @@ -1,105 +1,105 @@ /* - !!DESCRIPTION!! varargs test - !!ORIGIN!! - !!LICENCE!! public domain -*/ - -#include <stdlib.h> -#include <stdio.h> -#include <stdarg.h> - -void chk0(char *format,...); -void chk1(int fd,char *format,...); - -#if 0 -// old workaround for broken varargs - -void chk0(char *format,...){ - __asm__ ("pha"); // save argument size - { -//va_list ap; -char *ap; -char *_format; -static char string[0x100]; - -// va_start(ap,format); - __asm__ ("pla"); // restore argument size - __asm__ ("ldx #$00"); // clear hibyte of AX - ap=__AX__; - ap+=(char*)&format; - // get value of format - ap-=2; - _format=*((char**)ap); - -// vsprintf(string,format,ap); - vsprintf(&string[0],_format,ap); - printf("format:%s,string:%s\n",_format,string); -// va_end(ap); - - } -} - -void chk1(int fd,char *format,...){ - __asm__ ("pha"); // save argument size - { -//va_list ap; -char *ap; -char *_format; -int _fd; -static char string[0x100]; - -// va_start(ap,format); - __asm__ ("pla"); // restore argument size - __asm__ ("ldx #$00"); // clear hibyte of AX - ap=__AX__; - ap+=(char*)&format; - // get value of fd - ap-=2; - _fd=*((int*)ap); - // get value of format - ap-=2; - _format=*((char**)ap); - -// vsprintf(string,format,ap); - vsprintf(&string[0],_format,ap); - printf("fd:%d,format:%s,string:%s\n",_fd,_format,string); -// va_end(ap); - - } -} - -#endif - -void chk0(char *format,...){ -va_list ap; -static char string[0x100]; - va_start(ap,format); - vsprintf(string,format,ap); - printf("format:%s,string:%s\n",format,string); - va_end(ap); -} - -void chk1(int fd,char *format,...){ -va_list ap; -static char string[0x100]; - - va_start(ap,format); - - vsprintf(string,format,ap); - printf("fd:%d,format:%s,string:%s\n",fd,format,string); - va_end(ap); + !!DESCRIPTION!! varargs test + !!ORIGIN!! + !!LICENCE!! public domain +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> + +void chk0(char *format,...); +void chk1(int fd,char *format,...); + +#if 0 +// old workaround for broken varargs + +void chk0(char *format,...){ + __asm__ ("pha"); // save argument size + { +//va_list ap; +char *ap; +char *_format; +static char string[0x100]; + +// va_start(ap,format); + __asm__ ("pla"); // restore argument size + __asm__ ("ldx #$00"); // clear hibyte of AX + ap=__AX__; + ap+=(char*)&format; + // get value of format + ap-=2; + _format=*((char**)ap); + +// vsprintf(string,format,ap); + vsprintf(&string[0],_format,ap); + printf("format:%s,string:%s\n",_format,string); +// va_end(ap); + + } } -int main(int argc,char **argv) { - printf("varargs test\n"); - - printf("\nchk0/0:\n");chk0("chk0 %s","arg0"); - printf("\nchk0/1:\n");chk0("chk0 %s %s","arg0","arg1"); - printf("\nchk0/2:\n");chk0("chk0 %s %s %s","arg0","arg1","arg2"); - - printf("\nchk1/0:\n");chk1(0xfd,"chk1 %s","arg0"); - printf("\nchk1/1:\n");chk1(0xfd,"chk1 %s %s","arg0","arg1"); - printf("\nchk1/2:\n");chk1(0xfd,"chk1 %s %s %s","arg0","arg1","arg2"); - +void chk1(int fd,char *format,...){ + __asm__ ("pha"); // save argument size + { +//va_list ap; +char *ap; +char *_format; +int _fd; +static char string[0x100]; + +// va_start(ap,format); + __asm__ ("pla"); // restore argument size + __asm__ ("ldx #$00"); // clear hibyte of AX + ap=__AX__; + ap+=(char*)&format; + // get value of fd + ap-=2; + _fd=*((int*)ap); + // get value of format + ap-=2; + _format=*((char**)ap); + +// vsprintf(string,format,ap); + vsprintf(&string[0],_format,ap); + printf("fd:%d,format:%s,string:%s\n",_fd,_format,string); +// va_end(ap); + + } +} + +#endif + +void chk0(char *format,...){ +va_list ap; +static char string[0x100]; + va_start(ap,format); + vsprintf(string,format,ap); + printf("format:%s,string:%s\n",format,string); + va_end(ap); +} + +void chk1(int fd,char *format,...){ +va_list ap; +static char string[0x100]; + + va_start(ap,format); + + vsprintf(string,format,ap); + printf("fd:%d,format:%s,string:%s\n",fd,format,string); + va_end(ap); +} + +int main(int argc,char **argv) { + printf("varargs test\n"); + + printf("\nchk0/0:\n");chk0("chk0 %s","arg0"); + printf("\nchk0/1:\n");chk0("chk0 %s %s","arg0","arg1"); + printf("\nchk0/2:\n");chk0("chk0 %s %s %s","arg0","arg1","arg2"); + + printf("\nchk1/0:\n");chk1(0xfd,"chk1 %s","arg0"); + printf("\nchk1/1:\n");chk1(0xfd,"chk1 %s %s","arg0","arg1"); + printf("\nchk1/2:\n");chk1(0xfd,"chk1 %s %s %s","arg0","arg1","arg2"); + return 0; -} +} diff --git a/testcode/lib/mul-test.c b/testcode/lib/mul-test.c index 2daf5aa06..f9db3f641 100644 --- a/testcode/lib/mul-test.c +++ b/testcode/lib/mul-test.c @@ -1,170 +1,170 @@ -/* mul-test.c -- Test the multiplication operator. */ - -#include <time.h> -#include <conio.h> -#include <ctype.h> - - -/* Number of elements in the progress bar. Use a power of 2, to avoid the -** multiplication (which is about to be tested). -*/ -#define BAR_ELEMENTS 32U - -#if defined(__CBM__) -static const unsigned char revers_bar[8] = { - 0, 0, 0, 0, 0, 1, 1, 1 -}; -static const unsigned char small_bar[8] = { - ' ', 0xa5, 0xb4, 0xb5, 0xa1, 0xb6, 0xaa, 0xa7 -}; - -#elif defined(__ATARI__) -#endif - -/* Screen co-ordinates for the progress meter */ -static unsigned char Width, Height; -static unsigned char X, Y; - -static void ProgressMeter (unsigned Val) -/* Print the progress bar. */ -{ - gotoxy (X, Y); - cprintf (" %5lu/65536\r\n", (unsigned long) Val); - revers (1); - cclear (Val / (unsigned)(65536U / BAR_ELEMENTS)); - -/* Commodore and Atari computers can show eight times greater precision. */ -#if defined(__CBM__) - Val = (Val / (unsigned)(65536U / BAR_ELEMENTS / 8)) % 8; - revers (revers_bar[Val]); - cputc (small_bar[Val]); - -#elif defined(__ATARI__) -#endif - - revers (0); -} - - - -int main(void) -{ - char C; - - /* Clock variables */ - clock_t Ticks; - clock_t Wait; - unsigned Days; - unsigned Hours; - unsigned Minu; - unsigned Sec; - unsigned Milli; - - /* Actual test variables */ - register unsigned lhs = 0; - register unsigned rhs = 0; - register unsigned res; - - /* Clear the screen, and output an informational message. */ - clrscr (); - screensize (&Width, &Height); - cprintf ("This program does an exhaustive test of\r\n" - "the multiplication routine. It runs for\r\n" - "several days; so, please wait very\r\n" - "patiently (or, speed up your emulator).\r\n" - "\n" - "Progress: "); - - /* Remember the current position for the progress bar */ - X = wherex (); - Y = wherey (); - - /* Mark the maximum limit of the bar. */ - revers (1); - cputcxy (BAR_ELEMENTS, Y, ' '); - cputcxy (BAR_ELEMENTS, Y + 1, ' '); - revers (0); - -/* [Targets that have clock() will define CLOCKS_PER_SEC.] */ -#ifdef CLOCKS_PER_SEC - - /* Start timing the test. */ - Ticks = clock(); -#endif - - do { - - /* Update the progress bar */ - ProgressMeter (lhs); - -/* Enable this to test the progress-meter code. -** (And, run emulators at their maximun speed.) -*/ -#if 0 - continue; -#endif - - /* Do one row of tests */ - res = 0; - do { - if (lhs * rhs != res) { -#ifdef CLOCKS_PER_SEC - Wait = clock (); -#endif - gotoxy (0, Y+3); - cprintf ("Error on %u * %u: %u != %u\r\n", lhs, rhs, lhs * rhs, res); - cprintf ("Press a key -- 'Q' to quit. "); - cursor (1); - C = toupper (cgetc ()); - cclearxy (0, Y+3, Width); - cclearxy (0, Y+4, Width); - -#ifdef CLOCKS_PER_SEC - - /* Don't time the user's interaction. */ - Ticks += clock () - Wait; -#endif - - if (C == 'Q') { - goto Done; - } - } - - if (kbhit () && toupper (cgetc ()) == 'Q') { - goto Done; - } - - res += lhs; - } while (++rhs != 0); - - } while (++lhs != 0); - -Done: -#ifdef CLOCKS_PER_SEC - - /* Calculate the time used */ - Ticks = clock() - Ticks; - Milli = ((Ticks % CLOCKS_PER_SEC) * 1000) / CLOCKS_PER_SEC; - Sec = (unsigned) (Ticks / CLOCKS_PER_SEC); - Minu = Sec / 60; - Hours = Minu / 60; - Days = Hours / 24; - Hours %= 24; - Minu %= 60; - Sec %= 60; - - /* Print the time used */ - gotoxy (0, Y+3); - cprintf ("Time used:\r\n" - " %u days,\r\n" - " %u hours,\r\n" - " %u minutes,\r\n" - " %u.%03u seconds.\n", Days, Hours, Minu, Sec, Milli); -#endif - - cprintf ("\rTap a key, to exit. "); - cgetc(); - return 0; -} - - +/* mul-test.c -- Test the multiplication operator. */ + +#include <time.h> +#include <conio.h> +#include <ctype.h> + + +/* Number of elements in the progress bar. Use a power of 2, to avoid the +** multiplication (which is about to be tested). +*/ +#define BAR_ELEMENTS 32U + +#if defined(__CBM__) +static const unsigned char revers_bar[8] = { + 0, 0, 0, 0, 0, 1, 1, 1 +}; +static const unsigned char small_bar[8] = { + ' ', 0xa5, 0xb4, 0xb5, 0xa1, 0xb6, 0xaa, 0xa7 +}; + +#elif defined(__ATARI__) +#endif + +/* Screen co-ordinates for the progress meter */ +static unsigned char Width, Height; +static unsigned char X, Y; + +static void ProgressMeter (unsigned Val) +/* Print the progress bar. */ +{ + gotoxy (X, Y); + cprintf (" %5lu/65536\r\n", (unsigned long) Val); + revers (1); + cclear (Val / (unsigned)(65536U / BAR_ELEMENTS)); + +/* Commodore and Atari computers can show eight times greater precision. */ +#if defined(__CBM__) + Val = (Val / (unsigned)(65536U / BAR_ELEMENTS / 8)) % 8; + revers (revers_bar[Val]); + cputc (small_bar[Val]); + +#elif defined(__ATARI__) +#endif + + revers (0); +} + + + +int main(void) +{ + char C; + + /* Clock variables */ + clock_t Ticks; + clock_t Wait; + unsigned Days; + unsigned Hours; + unsigned Minu; + unsigned Sec; + unsigned Milli; + + /* Actual test variables */ + register unsigned lhs = 0; + register unsigned rhs = 0; + register unsigned res; + + /* Clear the screen, and output an informational message. */ + clrscr (); + screensize (&Width, &Height); + cprintf ("This program does an exhaustive test of\r\n" + "the multiplication routine. It runs for\r\n" + "several days; so, please wait very\r\n" + "patiently (or, speed up your emulator).\r\n" + "\n" + "Progress: "); + + /* Remember the current position for the progress bar */ + X = wherex (); + Y = wherey (); + + /* Mark the maximum limit of the bar. */ + revers (1); + cputcxy (BAR_ELEMENTS, Y, ' '); + cputcxy (BAR_ELEMENTS, Y + 1, ' '); + revers (0); + +/* [Targets that have clock() will define CLOCKS_PER_SEC.] */ +#ifdef CLOCKS_PER_SEC + + /* Start timing the test. */ + Ticks = clock(); +#endif + + do { + + /* Update the progress bar */ + ProgressMeter (lhs); + +/* Enable this to test the progress-meter code. +** (And, run emulators at their maximun speed.) +*/ +#if 0 + continue; +#endif + + /* Do one row of tests */ + res = 0; + do { + if (lhs * rhs != res) { +#ifdef CLOCKS_PER_SEC + Wait = clock (); +#endif + gotoxy (0, Y+3); + cprintf ("Error on %u * %u: %u != %u\r\n", lhs, rhs, lhs * rhs, res); + cprintf ("Press a key -- 'Q' to quit. "); + cursor (1); + C = toupper (cgetc ()); + cclearxy (0, Y+3, Width); + cclearxy (0, Y+4, Width); + +#ifdef CLOCKS_PER_SEC + + /* Don't time the user's interaction. */ + Ticks += clock () - Wait; +#endif + + if (C == 'Q') { + goto Done; + } + } + + if (kbhit () && toupper (cgetc ()) == 'Q') { + goto Done; + } + + res += lhs; + } while (++rhs != 0); + + } while (++lhs != 0); + +Done: +#ifdef CLOCKS_PER_SEC + + /* Calculate the time used */ + Ticks = clock() - Ticks; + Milli = ((Ticks % CLOCKS_PER_SEC) * 1000) / CLOCKS_PER_SEC; + Sec = (unsigned) (Ticks / CLOCKS_PER_SEC); + Minu = Sec / 60; + Hours = Minu / 60; + Days = Hours / 24; + Hours %= 24; + Minu %= 60; + Sec %= 60; + + /* Print the time used */ + gotoxy (0, Y+3); + cprintf ("Time used:\r\n" + " %u days,\r\n" + " %u hours,\r\n" + " %u minutes,\r\n" + " %u.%03u seconds.\n", Days, Hours, Minu, Sec, Milli); +#endif + + cprintf ("\rTap a key, to exit. "); + cgetc(); + return 0; +} + + From acb7c6130274d7c2ad91ac82c6b64b741fa47d97 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 10 Mar 2017 08:47:48 -0500 Subject: [PATCH 0259/2161] Removed a pointless cc65 command-line option from the samples makefile. "-Oi --codesize 500" is the same as "-O --codesize 200 --codesize 500". That first "--codesize" is replaced by the second one. Don't set it twice. --- samples/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Makefile b/samples/Makefile index edfeca689..949940022 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -90,7 +90,7 @@ LDFLAGS_tgidemo_atarixl = --start-addr 0x4000 %: %.s .c.o: - $(CC) $(CFLAGS) -Oirs --codesize 500 -T -g -t $(SYS) $< + $(CC) $(CFLAGS) -Ors --codesize 500 -T -g -t $(SYS) $< $(AS) $(<:.c=.s) .s.o: From 73261ea48f84ccca6ce3608fab6a9c8802ddb874 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 11 Mar 2017 15:11:15 -0500 Subject: [PATCH 0260/2161] Fixed a pointer test again -- but, it's better than in pull request #391. This time, the expression compares the pointer directly, instead of comparing the pointer's target. The new expression avoids an array underrun. --- test/ref/yacc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/ref/yacc.c b/test/ref/yacc.c index d0b9190e4..ab72e24c0 100644 --- a/test/ref/yacc.c +++ b/test/ref/yacc.c @@ -562,13 +562,13 @@ yylook() } # ifdef LEXDEBUG - if (*(lsp-1) < yysvec + 1) + if (lsp == yylstate) { fprintf(yyout,"yylook: stopped (end)\n"); } else { - fprintf(yyout,"yylook: stopped at %d with\n",*(lsp-1)-yysvec-1); + fprintf(yyout,"yylook: stopped at %d with:\n",*(lsp-1)-(yysvec+1)); } # endif while (lsp-- > yylstate) @@ -594,7 +594,7 @@ yylook() yyleng = yylastch-yytext+1; yytext[yyleng] = 0; # ifdef LEXDEBUG - fprintf(yyout,"\nyylook: match action %d\n",*yyfnd); + fprintf(yyout,"yylook: match action %d\n",*yyfnd); fprintf(yyout,"yylook: done loops: %d\n",testbreak); # endif return(*yyfnd++); From 2e8d792f9a1b55bb19942e02b91b1294dbc37e87 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 12 Mar 2017 18:13:18 +0100 Subject: [PATCH 0261/2161] Added .gitattributes to force LF line endings on commit. --- .gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..176a458f9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto From 750a527100526dfd33e31152819a87533ca95d1f Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 12 Mar 2017 12:55:31 -0400 Subject: [PATCH 0262/2161] Made C's sizeof operator work with initialized void variables. Added regression tests that check cc65's handling of void variables. --- doc/cc65.sgml | 47 +++++++++++++--------- src/cc65/datatype.c | 7 +++- src/cc65/declare.c | 10 +++-- test/err/void-empty.c | 9 +++++ test/err/void-size2.c | 11 +++++ test/val/void-size1.c | 56 ++++++++++++++++++++++++++ testcode/lib/atari/displaylist.c | 69 +++++++++++++++----------------- 7 files changed, 147 insertions(+), 62 deletions(-) create mode 100644 test/err/void-empty.c create mode 100644 test/err/void-size2.c create mode 100644 test/val/void-size1.c diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 80dba89b8..6a08cc3c3 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -4,7 +4,7 @@ <title>cc65 Users Guide <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:gregdk@users.sf.net" name="Greg King"> -<date>2016-06-11 +<date>2017-02-27 <abstract> cc65 is a C compiler for 6502 targets. It supports several 6502 based home @@ -687,30 +687,37 @@ This cc65 version has some extensions to the ISO C standard. string. <p> -<item> cc65 allows the initialization of <tt/void/ variables. This may be - used to create variable structures that are more compatible with - interfaces written for assembler languages. Here is an example: +<item> cc65 allows the initialization of <tt/void/ variables. This may be + used to create arbitrary structures that are more compatible with + interfaces written for assembler languages. Here is an example: - <tscreen><verb> - void GCmd = { (char)3, (unsigned)0x2000, (unsigned)0x3000 }; - </verb></tscreen> + <tscreen><verb> + void GCmd = { (char)3, (unsigned)0x2000, (unsigned)0x3000 }; + </verb></tscreen> - This will be translated as follows: + That will be translated as follows: - <tscreen><verb> - _GCmd: - .byte 3 - .word $2000 - .word $3000 - </verb></tscreen> + <tscreen><verb> + _GCmd: + .byte 3 + .word $2000 + .word $3000 + </verb></tscreen> - Since the variable is of type <tt/void/ you may not use it as is. - However, taking the address of the variable results in a <tt/void*/ - which may be passed to any function expecting a pointer. + Since the variable is of type <tt/void/, you may not use it as-is. + However, taking the address of the variable results in a <tt/void*/ + which may be passed to any function expecting a pointer. Also, the + <tt/sizeof/ operator will give the length of the initializer: - See the <url url="geos.html" name="GEOS library document"> for examples - on how to use this feature. - <p> + <tscreen><verb> + GLen = sizeof GCmd; + </verb></tscreen> + + will assign the value 5 to <tt/GLen/. + + See the <url url="geos.html" name="GEOS library document"> for examples + on how to use that feature. + <p> <item> cc65 implements flexible array struct members as defined in the C99 ISO standard. As an extension, these fields may be initialized. There are diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 8c9d6dcb0..2d54316cd 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -389,7 +389,10 @@ unsigned SizeOf (const Type* T) switch (UnqualifiedType (T->C)) { case T_VOID: - return 0; /* Assume voids have size zero */ + /* A void variable is a cc65 extension. + ** Get its size (in bytes). + */ + return T->A.U; /* Beware: There's a chance that this triggers problems in other parts of the compiler. The solution is to fix the callers, because calling @@ -438,7 +441,7 @@ unsigned SizeOf (const Type* T) /* Array with unspecified size */ return 0; } else { - return T->A.L * SizeOf (T + 1); + return T->A.U * SizeOf (T + 1); } default: diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 163084835..7b543aa55 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -891,6 +891,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers) case TOK_VOID: NextToken (); D->Type[0].C = T_VOID; + D->Type[0].A.U = 0; D->Type[1].C = T_END; break; @@ -2114,7 +2115,7 @@ NextMember: -static unsigned ParseVoidInit (void) +static unsigned ParseVoidInit (Type* T) /* Parse an initialization of a void variable (special cc65 extension). ** Return the number of bytes initialized. */ @@ -2181,6 +2182,9 @@ static unsigned ParseVoidInit (void) /* Closing brace */ ConsumeRCurly (); + /* Number of bytes determined by initializer */ + T->A.U = Size; + /* Return the number of bytes initialized */ return Size; } @@ -2216,8 +2220,8 @@ static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers) case T_VOID: if (IS_Get (&Standard) == STD_CC65) { - /* Special cc65 extension in non ANSI mode */ - return ParseVoidInit (); + /* Special cc65 extension in non-ANSI mode */ + return ParseVoidInit (T); } /* FALLTHROUGH */ diff --git a/test/err/void-empty.c b/test/err/void-empty.c new file mode 100644 index 000000000..900918222 --- /dev/null +++ b/test/err/void-empty.c @@ -0,0 +1,9 @@ +/* + !!DESCRIPTION!! Uninitialized void variables + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Greg King +*/ + +void test; +const void list; diff --git a/test/err/void-size2.c b/test/err/void-size2.c new file mode 100644 index 000000000..3d4f13322 --- /dev/null +++ b/test/err/void-size2.c @@ -0,0 +1,11 @@ +/* + !!DESCRIPTION!! Size of void cast + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Greg King +*/ + +unsigned test (void) +{ + return sizeof ((void)12345); +} diff --git a/test/val/void-size1.c b/test/val/void-size1.c new file mode 100644 index 000000000..0c2dccaa7 --- /dev/null +++ b/test/val/void-size1.c @@ -0,0 +1,56 @@ +/* + !!DESCRIPTION!! Getting the size of a void-type variable (cc65 extension) + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Greg King +*/ + +static const void list1 = { + (char)1, + (char)2, + (char)3, + (char)4, + (char)5, + (char)6, + (char)7, + (char)8, + (char)9, + (char)0 +}; + +static void list2 = { + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 0 +}; + +void list3 = { + (char)1, + (char)2, + (char)3, + (char)4, + &list1, + (char)6, + (char)7, + (char)8, + (char)9, + &list2 +}; + +/* We know that the expression is constant; don't tell us. */ + +#pragma warn (const-comparison, off) + +int main (void) +{ + return sizeof list1 != 10 + || sizeof list2 != 20 + || sizeof list3 != 12; +} diff --git a/testcode/lib/atari/displaylist.c b/testcode/lib/atari/displaylist.c index 04c599878..ae1931e64 100644 --- a/testcode/lib/atari/displaylist.c +++ b/testcode/lib/atari/displaylist.c @@ -1,59 +1,55 @@ /* -** testprogram for ANTIC instructions as defined in "_antic.h" +** test program for ANTIC instructions as defined in "_antic.h" ** ** 23-Feb-2017, Christian Krueger */ #include <conio.h> #include <atari.h> -#include <peekpoke.h> -#include <string.h> -// code is only for testing purposes, as screen and display list are not aligned +// code is only for testing purposes, as screen and display list are not aligned, // and jumps not set! unsigned char DummyScreen[400]; void DisplayList = { - DL_BLK1, - DL_BLK2, - DL_BLK3, - DL_BLK4, - DL_BLK5, - DL_BLK6, - DL_BLK7, - DL_DLI(DL_BLK8), - DL_LMS(DL_CHR40x8x1), - DummyScreen, - DL_HSCROL(DL_CHR40x10x1), - DL_VSCROL(DL_CHR40x8x4), - DL_CHR40x16x4, - DL_LMS(DL_HSCROL(DL_VSCROL(DL_DLI(DL_CHR20x8x2)))), - DummyScreen+120, - DL_CHR20x16x2, - DL_MAP40x8x4, - DL_MAP80x4x2, - DL_MAP80x4x4, - DL_MAP160x2x2, - DL_MAP160x1x2, - DL_MAP160x2x4, - DL_MAP160x1x4, - DL_MAP320x1x1, - DL_JVB, - DL_JMP + DL_BLK1, + DL_BLK2, + DL_BLK3, + DL_BLK4, + DL_BLK5, + DL_BLK6, + DL_BLK7, + DL_DLI(DL_BLK8), + DL_LMS(DL_CHR40x8x1), + DummyScreen, + DL_HSCROL(DL_CHR40x10x1), + DL_VSCROL(DL_CHR40x8x4), + DL_CHR40x16x4, + DL_LMS(DL_HSCROL(DL_VSCROL(DL_DLI(DL_CHR20x8x2)))), + DummyScreen+120, + DL_CHR20x16x2, + DL_MAP40x8x4, + DL_MAP80x4x2, + DL_MAP80x4x4, + DL_MAP160x2x2, + DL_MAP160x1x2, + DL_MAP160x2x4, + DL_MAP160x1x4, + DL_MAP320x1x1, + DL_JVB, + DL_JMP }; -unsigned char dlend = 0; +/* We know that the sizeof expression is constant; don't tell us. */ + +#pragma warn (const-comparison, off) int main(void) { - // unfortunately "sizeof()" doesn't work with void data - // (Error: Size of data type is unknown) - // so we trick with the addresses at front and end... - - int returnValue = (((unsigned int)&dlend-(unsigned int)&DisplayList) != 28); // assure only one byte per instruction! + int returnValue = (sizeof DisplayList != 28); // assure only one byte per instruction! clrscr(); if (returnValue) @@ -66,4 +62,3 @@ main(void) return returnValue; } - From 0de44517ac5780b59969dd92ad081d5a68b2dc47 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sun, 12 Mar 2017 23:21:43 +0100 Subject: [PATCH 0263/2161] few 6502 and some 65SC02 optimizations --- libsrc/runtime/add.s | 59 ++++++++++++++++++++++++--------------- libsrc/runtime/along.s | 17 +++++------ libsrc/runtime/laddeq.s | 12 ++++++-- libsrc/runtime/land.s | 14 +++++++++- libsrc/runtime/leave.s | 19 +++++++++++++ libsrc/runtime/lmod.s | 9 +++++- libsrc/runtime/lmul.s | 15 +++++++++- libsrc/runtime/lor.s | 16 +++++++++-- libsrc/runtime/lpop.s | 6 ++++ libsrc/runtime/lpush.s | 16 +++++++++-- libsrc/runtime/lrsub.s | 19 +++++++++++-- libsrc/runtime/lsave.s | 10 +++---- libsrc/runtime/lsub.s | 9 ++++-- libsrc/runtime/lsubeq.s | 15 +++++++--- libsrc/runtime/ludiv.s | 15 +++++++++- libsrc/runtime/lumod.s | 8 ++++++ libsrc/runtime/lxor.s | 17 +++++++++-- libsrc/runtime/makebool.s | 23 ++++++--------- libsrc/runtime/or.s | 10 ++++++- libsrc/runtime/rsub.s | 12 ++++++-- libsrc/runtime/staxspi.s | 7 +++++ libsrc/runtime/swap.s | 12 +++++++- libsrc/runtime/xor.s | 10 ++++++- 23 files changed, 272 insertions(+), 78 deletions(-) diff --git a/libsrc/runtime/add.s b/libsrc/runtime/add.s index 6fb2dacf7..e644671c0 100644 --- a/libsrc/runtime/add.s +++ b/libsrc/runtime/add.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 05.08.1998 +; Christian Krueger, 11-Mar-2017, spend two bytes for one cycle, improved 65SC02 optimization ; ; CC65 runtime: add ints ; @@ -8,32 +9,46 @@ ; called a lot! .export tosadda0, tosaddax - .importzp sp + .importzp sp, tmp1 .macpack cpu tosadda0: ldx #0 tosaddax: - clc -.if (.cpu .bitand CPU_ISET_65SC02) - adc (sp) ; 65SC02 version - saves 2 cycles - ldy #1 -.else - ldy #0 - adc (sp),y ; lo byte - iny -.endif - pha ; save it - txa - adc (sp),y ; hi byte - tax - clc - lda sp - adc #2 - sta sp - bcc L1 - inc sp+1 -L1: pla ; Restore low byte - rts + clc ; (2) +.if (.cpu .bitand ::CPU_ISET_65SC02) + + adc (sp) ; (7) + tay ; (9) + inc sp ; (14) + bne hiadd ; (17) + inc sp+1 ; (-1+5) +hiadd: txa ; (19) + adc (sp) ; (24) + tax ; (26) + inc sp ; (31) + bne done ; (34) + inc sp+1 ; (-1+5) +done: tya ; (36) + +.else + + ldy #0 ; (4) + adc (sp),y ; (9) lo byte + iny ; (11) + sta tmp1 ; (14) save it + txa ; (16) + adc (sp),y ; (21) hi byte + tax ; (23) + clc ; (25) + lda sp ; (28) + adc #2 ; (30) + sta sp ; (33) + bcc L1 ; (36) + inc sp+1 ; (-1+5) +L1: lda tmp1 ; (39) restore low byte + +.endif + rts ; (6502: 45 cycles, 26 bytes <-> 65SC02: 42 cycles, 22 bytes ) diff --git a/libsrc/runtime/along.s b/libsrc/runtime/along.s index 661b3124a..25eb78c45 100644 --- a/libsrc/runtime/along.s +++ b/libsrc/runtime/along.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 23.11.2002 +; Christian Krueger, 11-Mar-2017, saved 5 bytes ; ; CC65 runtime: Convert char in ax into a long ; @@ -9,16 +10,12 @@ ; Convert A from char to long in EAX +along: ldx #$ff + cmp #$80 ; Positive? + bcs store ; no, apply $FF + aulong: ldx #0 - stx sreg +store: stx sreg stx sreg+1 rts - -along: cmp #$80 ; Positive? - bcc aulong ; Yes, handle like unsigned type - ldx #$ff - stx sreg - stx sreg+1 - rts - - + \ No newline at end of file diff --git a/libsrc/runtime/laddeq.s b/libsrc/runtime/laddeq.s index 2632ec909..57bec0629 100644 --- a/libsrc/runtime/laddeq.s +++ b/libsrc/runtime/laddeq.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 07.04.2000 +; Christian Krueger, 12-Mar-2017, added 65SC02 optimization ; ; CC65 runtime: += operator ; @@ -10,6 +11,7 @@ .export laddeq1, laddeqa, laddeq .importzp sreg, ptr1, tmp1 + .macpack cpu laddeq1: lda #$01 @@ -20,14 +22,20 @@ laddeqa: stx sreg+1 laddeq: sty ptr1+1 ; Store high byte of address - ldy #$00 ; Address low byte clc +.if (.cpu .bitand ::CPU_ISET_65SC02) + adc (ptr1) + sta (ptr1) + ldy #$01 ; Address byte 1 +.else + ldy #$00 ; Address low byte adc (ptr1),y sta (ptr1),y + iny ; Address byte 1 +.endif pha ; Save byte 0 of result for later - iny ; Address byte 1 txa adc (ptr1),y ; Load byte 1 sta (ptr1),y diff --git a/libsrc/runtime/land.s b/libsrc/runtime/land.s index 506c071a4..6ea4e5bcb 100644 --- a/libsrc/runtime/land.s +++ b/libsrc/runtime/land.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 06.08.1998 +; Christian Krueger, 11-Mar-2017, added 65SC02 optimization ; ; CC65 runtime: and on longs ; @@ -8,17 +9,28 @@ .import addysp1 .importzp sp, sreg, tmp1 + .macpack cpu tosand0ax: +.if (.cpu .bitand ::CPU_ISET_65SC02) + stz sreg + stz sreg+1 +.else ldy #$00 sty sreg sty sreg+1 +.endif tosandeax: +.if (.cpu .bitand ::CPU_ISET_65SC02) + and (sp) ; byte 0 + ldy #1 +.else ldy #0 and (sp),y ; byte 0 - sta tmp1 iny +.endif + sta tmp1 txa and (sp),y ; byte 1 tax diff --git a/libsrc/runtime/leave.s b/libsrc/runtime/leave.s index 8f4e055f5..4a9ff7994 100644 --- a/libsrc/runtime/leave.s +++ b/libsrc/runtime/leave.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 06.08.1998 +; Christian Krueger, 11-Mar-2017, added 65SC02 optimization ; ; CC65 runtime: function epilogue ; @@ -13,6 +14,8 @@ .import addysp .importzp sp + .macpack cpu + leave00: lda #0 leave0: ldx #0 @@ -24,6 +27,20 @@ leavey0: ldx #0 ; return < 256 leavey: jsr addysp ; drop stack frame + +.if (.cpu .bitand ::CPU_ISET_65SC02) + +leave: tay ; save A a sec + lda (sp) ; that's the pushed arg size + sec ; Count the byte, the count's stored in + adc sp + sta sp + bcc L1 + inc 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 @@ -33,5 +50,7 @@ leave: pha ; save A a sec bcc L1 inc sp+1 L1: pla ; Get return value back + +.endif rts diff --git a/libsrc/runtime/lmod.s b/libsrc/runtime/lmod.s index 74deb23f0..caeb0c4f6 100644 --- a/libsrc/runtime/lmod.s +++ b/libsrc/runtime/lmod.s @@ -1,6 +1,6 @@ ; ; Ullrich von Bassewitz, 07.08.1998 -; +; Christian Krueger, 11-Mar-2017, added 65SC02 optimization ; CC65 runtime: modulo operation for long signed ints ; @@ -11,10 +11,17 @@ .import poplsargs, udiv32, negeax .importzp sreg, ptr1, ptr2, tmp1, tmp3, tmp4 + .macpack cpu + tosmod0ax: +.if (.cpu .bitand ::CPU_ISET_65SC02) + stz sreg + stz sreg+1 +.else ldy #$00 sty sreg sty sreg+1 +.endif tosmodeax: jsr poplsargs ; Get arguments from stack, adjust sign diff --git a/libsrc/runtime/lmul.s b/libsrc/runtime/lmul.s index 7ad2b2aa4..860d58cba 100644 --- a/libsrc/runtime/lmul.s +++ b/libsrc/runtime/lmul.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 13.08.1998 +; Christian Krueger, 11-Mar-2017, added 65SC02 optimization ; ; CC65 runtime: multiplication for long (unsigned) ints ; @@ -8,20 +9,32 @@ .import addysp1 .importzp sp, sreg, tmp1, tmp2, tmp3, tmp4, ptr1, ptr3, ptr4 + .macpack cpu + tosmul0ax: tosumul0ax: +.if (.cpu .bitand ::CPU_ISET_65SC02) + stz sreg + stz sreg+1 +.else ldy #$00 sty sreg sty sreg+1 +.endif tosmuleax: tosumuleax: mul32: sta ptr1 stx ptr1+1 ; op2 now in ptr1/sreg +.if (.cpu .bitand ::CPU_ISET_65SC02) + lda (sp) + ldy #1 +.else ldy #0 lda (sp),y - sta ptr3 iny +.endif + sta ptr3 lda (sp),y sta ptr3+1 iny diff --git a/libsrc/runtime/lor.s b/libsrc/runtime/lor.s index a74b33059..94ab3c890 100644 --- a/libsrc/runtime/lor.s +++ b/libsrc/runtime/lor.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 06.08.1998 +; Christian Krueger, 11-Mar-2017, added 65SC02 optimization ; ; CC65 runtime: or on longs ; @@ -8,17 +9,28 @@ .import addysp1 .importzp sp, sreg, tmp1 + .macpack cpu tosor0ax: +.if (.cpu .bitand ::CPU_ISET_65SC02) + stz sreg + stz sreg+1 +.else ldy #$00 sty sreg - sty sreg+1 + sty sreg+1 +.endif tosoreax: +.if (.cpu .bitand ::CPU_ISET_65SC02) + ora (sp) + ldy #1 +.else ldy #0 ora (sp),y ; byte 0 - sta tmp1 iny +.endif + sta tmp1 txa ora (sp),y ; byte 1 tax diff --git a/libsrc/runtime/lpop.s b/libsrc/runtime/lpop.s index 7d281db52..ffff5ffc1 100644 --- a/libsrc/runtime/lpop.s +++ b/libsrc/runtime/lpop.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 29.12.1999 +; Christian Krueger, 11-Mar-2017, added 65SC02 optimization ; ; CC65 runtime: long pop ; @@ -8,6 +9,7 @@ .import incsp4 .importzp sp, sreg + .macpack cpu popeax: ldy #3 lda (sp),y @@ -18,8 +20,12 @@ popeax: ldy #3 dey lda (sp),y tax +.if (.cpu .bitand ::CPU_ISET_65SC02) + lda (sp) +.else dey lda (sp),y +.endif jmp incsp4 diff --git a/libsrc/runtime/lpush.s b/libsrc/runtime/lpush.s index 074b4320a..4fed77f05 100644 --- a/libsrc/runtime/lpush.s +++ b/libsrc/runtime/lpush.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 06.08.1998 +; Christian Krueger, 11-Mar-2017, added 65SC02 optimization ; ; CC65 runtime: long push ; @@ -11,13 +12,20 @@ .import decsp4 .importzp sp, sreg + .macpack cpu + pushl0: lda #0 tax push0ax: - ldy #0 +.if (.cpu .bitand ::CPU_ISET_65SC02) + stz sreg + stz sreg+1 +.else + ldy #$00 sty sreg sty sreg+1 +.endif pusheax: pha ; decsp will destroy A (but not X) jsr decsp4 @@ -30,8 +38,12 @@ pusheax: dey txa sta (sp),y - dey pla +.if (.cpu .bitand ::CPU_ISET_65SC02) + sta (sp) +.else + dey sta (sp),y +.endif rts diff --git a/libsrc/runtime/lrsub.s b/libsrc/runtime/lrsub.s index fd519ca4f..928164f40 100644 --- a/libsrc/runtime/lrsub.s +++ b/libsrc/runtime/lrsub.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 05.08.1998 +; Christian Krueger, 11-Mar-2017, added 65SC02 optimization ; ; CC65 runtime: long sub reversed ; @@ -11,18 +12,30 @@ .import addysp1 .importzp sp, sreg, tmp1 + .macpack cpu + tosrsub0ax: +.if (.cpu .bitand ::CPU_ISET_65SC02) + stz sreg + stz sreg+1 +.else ldy #$00 sty sreg sty sreg+1 +.endif -tosrsubeax: - ldy #0 +tosrsubeax: sec +.if (.cpu .bitand ::CPU_ISET_65SC02) + sbc (sp) + ldy #1 +.else + ldy #0 sbc (sp),y ; byte 0 + iny +.endif sta tmp1 ; use as temp storage txa - iny sbc (sp),y ; byte 1 tax iny diff --git a/libsrc/runtime/lsave.s b/libsrc/runtime/lsave.s index fa21e463e..82703073a 100644 --- a/libsrc/runtime/lsave.s +++ b/libsrc/runtime/lsave.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 08.08.1998 +; Christian Krueger, 11-Mar-2017, optimization ; ; CC65 runtime: save ax into temp storage/restore ax from temp storage ; @@ -10,11 +11,10 @@ saveeax: sta regsave stx regsave+1 - lda sreg - sta regsave+2 - lda sreg+1 - sta regsave+3 - lda regsave + ldy sreg + sty regsave+2 + ldy sreg+1 + sty regsave+3 rts resteax: diff --git a/libsrc/runtime/lsub.s b/libsrc/runtime/lsub.s index 926d52e51..6f80491ca 100644 --- a/libsrc/runtime/lsub.s +++ b/libsrc/runtime/lsub.s @@ -1,6 +1,6 @@ ; ; Ullrich von Bassewitz, 05.08.1998 -; +; Christian Krueger, 11-Mar-2017, ímproved 65SC02 optimization ; CC65 runtime: long sub ; @@ -14,14 +14,19 @@ .macpack cpu tossub0ax: +.if (.cpu .bitand ::CPU_ISET_65SC02) + stz sreg + stz sreg+1 +.else ldy #$00 sty sreg sty sreg+1 +.endif tossubeax: sec eor #$FF -.if (.cpu .bitand CPU_ISET_65SC02) +.if (.cpu .bitand ::CPU_ISET_65SC02) adc (sp) ; 65SC02 version - saves 2 cycles ldy #1 .else diff --git a/libsrc/runtime/lsubeq.s b/libsrc/runtime/lsubeq.s index 9f5853d29..5e3d25783 100644 --- a/libsrc/runtime/lsubeq.s +++ b/libsrc/runtime/lsubeq.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 07.04.2000 +; Christian Krueger, 12-Mar-2017, added 65SC02 optimization ; ; CC65 runtime: -= operator ; @@ -10,6 +11,7 @@ .export lsubeq1, lsubeqa, lsubeq .importzp sreg, ptr1 + .macpack cpu lsubeq1: lda #$01 @@ -20,15 +22,20 @@ lsubeqa: stx sreg+1 lsubeq: sty ptr1+1 ; Store high byte of address - ldy #$00 ; Address low byte + sec - eor #$FF + .if (.cpu .bitand ::CPU_ISET_65SC02) + adc (ptr1) ; Subtract byte 0 + sta (ptr1) + ldy #$01 ; Address byte 1 + .else + ldy #$00 ; Address low byte adc (ptr1),y ; Subtract byte 0 sta (ptr1),y + iny ; Address byte 1 + .endif pha ; Save byte 0 of result for later - - iny ; Address byte 1 txa eor #$FF adc (ptr1),y ; Subtract byte 1 diff --git a/libsrc/runtime/ludiv.s b/libsrc/runtime/ludiv.s index 149c98a78..54af4780e 100644 --- a/libsrc/runtime/ludiv.s +++ b/libsrc/runtime/ludiv.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 17.08.1998 +; Christian Krueger, 11-Mar-2017, added 65SC02 optimization ; ; CC65 runtime: division for long unsigned ints ; @@ -8,10 +9,17 @@ .import addysp1 .importzp sp, sreg, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 + .macpack cpu + tosudiv0ax: +.if (.cpu .bitand ::CPU_ISET_65SC02) + stz sreg + stz sreg+1 +.else ldy #$00 sty sreg sty sreg+1 +.endif tosudiveax: jsr getlop ; Get the paramameters @@ -30,10 +38,15 @@ getlop: sta ptr3 ; Put right operand in place lda sreg+1 sta ptr4+1 +.if (.cpu .bitand ::CPU_ISET_65SC02) + lda (sp) + ldy #1 +.else ldy #0 ; Put left operand in place lda (sp),y - sta ptr1 iny +.endif + sta ptr1 lda (sp),y sta ptr1+1 iny diff --git a/libsrc/runtime/lumod.s b/libsrc/runtime/lumod.s index e290e1167..241801a90 100644 --- a/libsrc/runtime/lumod.s +++ b/libsrc/runtime/lumod.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 27.09.1998 +; Christian Krueger, 11-Mar-2017, added 65SC02 optimization ; ; CC65 runtime: modulo operation for long unsigned ints ; @@ -8,10 +9,17 @@ .import getlop, udiv32 .importzp sreg, tmp3, tmp4, ptr2 + .macpack cpu + tosumod0ax: +.if (.cpu .bitand ::CPU_ISET_65SC02) + stz sreg + stz sreg+1 +.else ldy #$00 sty sreg sty sreg+1 +.endif tosumodeax: jsr getlop ; Get the paramameters diff --git a/libsrc/runtime/lxor.s b/libsrc/runtime/lxor.s index ce21ef35b..4ec9a4129 100644 --- a/libsrc/runtime/lxor.s +++ b/libsrc/runtime/lxor.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 06.08.1998 +; Christian Krueger, 11-Mar-2017, added 65SC02 optimization ; ; CC65 runtime: xor on longs ; @@ -8,16 +9,28 @@ .import addysp1 .importzp sp, sreg, tmp1 + .macpack cpu + tosxor0ax: +.if (.cpu .bitand ::CPU_ISET_65SC02) + stz sreg + stz sreg+1 +.else ldy #$00 sty sreg sty sreg+1 +.endif -tosxoreax: +tosxoreax: +.if (.cpu .bitand ::CPU_ISET_65SC02) + eor (sp) ; byte 0 + ldy #1 +.else ldy #0 eor (sp),y ; byte 0 - sta tmp1 iny +.endif + sta tmp1 txa eor (sp),y ; byte 1 tax diff --git a/libsrc/runtime/makebool.s b/libsrc/runtime/makebool.s index a15b24b93..643f418aa 100644 --- a/libsrc/runtime/makebool.s +++ b/libsrc/runtime/makebool.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 05.10.1998 +; Christian Krueger, 11-Mar-2017, optimization ; ; CC65 runtime: Make boolean according to flags ; @@ -9,14 +10,14 @@ boolne: bne ret1 - ldx #$00 +ret0: ldx #$00 txa rts -booleq: beq ret1 - ldx #$00 - txa +booleq: bne ret0 +ret1: ldx #$00 + lda #$01 rts @@ -44,17 +45,9 @@ boolult: boolugt: - beq L1 + beq ret0 booluge: - bcs ret1 -L1: ldx #$00 + ldx #$00 txa + rol a rts - - -ret1: ldx #$00 - lda #$01 - rts - - - diff --git a/libsrc/runtime/or.s b/libsrc/runtime/or.s index 8570c0cd7..1c2c4125e 100644 --- a/libsrc/runtime/or.s +++ b/libsrc/runtime/or.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 05.08.1998 +; Christian Krueger, 11-Mar-2017, added 65SC02 optimization ; ; CC65 runtime: or on ints ; @@ -8,13 +9,20 @@ .import addysp1 .importzp sp, tmp1 + .macpack cpu + tosora0: ldx #$00 tosorax: +.if (.cpu .bitand ::CPU_ISET_65SC02) + ora (sp) + ldy #1 +.else ldy #0 ora (sp),y - sta tmp1 iny +.endif + sta tmp1 txa ora (sp),y tax diff --git a/libsrc/runtime/rsub.s b/libsrc/runtime/rsub.s index 475a69e76..69ee6da22 100644 --- a/libsrc/runtime/rsub.s +++ b/libsrc/runtime/rsub.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 05.08.1998 +; Christian Krueger, 11-Mar-2017, added 65SC02 optimization ; ; CC65 runtime: sub ints reversed ; @@ -8,6 +9,8 @@ .import addysp1 .importzp sp, tmp1 + .macpack cpu + ; ; AX = AX - TOS ; @@ -15,12 +18,17 @@ tosrsuba0: ldx #0 tosrsubax: - ldy #0 sec +.if (.cpu .bitand CPU_ISET_65SC02) + sbc (sp) + ldy #1 +.else + ldy #0 sbc (sp),y ; lo byte + iny +.endif sta tmp1 ; save lo byte txa - iny sbc (sp),y ; hi byte tax lda tmp1 diff --git a/libsrc/runtime/staxspi.s b/libsrc/runtime/staxspi.s index 90738e0d2..3114f449c 100644 --- a/libsrc/runtime/staxspi.s +++ b/libsrc/runtime/staxspi.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 26.10.2000 +; Christian Krueger, 12-Mar-2017, added 65SC02 optimization ; ; CC65 runtime: Store a/x indirect into address at top of stack with index ; @@ -8,6 +9,8 @@ .import incsp2 .importzp sp, tmp1, ptr1 + .macpack cpu + .proc staxspidx sty tmp1 ; Save Y @@ -15,8 +18,12 @@ ldy #1 lda (sp),y sta ptr1+1 +.if (.cpu .bitand ::CPU_ISET_65SC02) + lda (sp) +.else dey lda (sp),y +.endif sta ptr1 ; Address now in ptr1 ldy tmp1 ; Restore Y iny ; Address high byte diff --git a/libsrc/runtime/swap.s b/libsrc/runtime/swap.s index e91eeca31..d4a74df5f 100644 --- a/libsrc/runtime/swap.s +++ b/libsrc/runtime/swap.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 06.08.1998 +; Christian Krueger, 11-Mar-2017, added 65SC02 optimization ; ; CC65 runtime: swap ax with TOS ; @@ -7,6 +8,8 @@ .export swapstk .importzp sp, ptr4 + .macpack cpu + swapstk: sta ptr4 stx ptr4+1 @@ -15,11 +18,18 @@ swapstk: tax lda ptr4+1 sta (sp),y +.if (.cpu .bitand ::CPU_ISET_65SC02) + lda (sp) + tay + lda ptr4 + sta (sp) + tya +.else dey lda (sp),y pha lda ptr4 sta (sp),y pla +.endif rts ; whew! - diff --git a/libsrc/runtime/xor.s b/libsrc/runtime/xor.s index 825c576d1..e03922926 100644 --- a/libsrc/runtime/xor.s +++ b/libsrc/runtime/xor.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 05.08.1998 +; Christian Krueger, 11-Mar-2017, added 65SC02 optimization ; ; CC65 runtime: xor on ints ; @@ -8,13 +9,20 @@ .import addysp1 .importzp sp, tmp1 + .macpack cpu + tosxora0: ldx #$00 tosxorax: +.if (.cpu .bitand CPU_ISET_65SC02) + eor (sp) + ldy #1 +.else ldy #0 eor (sp),y - sta tmp1 iny +.endif + sta tmp1 txa eor (sp),y tax From a3d8829be92032d262cbea686c400a098e9e5242 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Fri, 17 Mar 2017 21:42:51 +0100 Subject: [PATCH 0264/2161] Creativison changes. This change includes some cleanups, removal of mainargs.s (game console programs never have arguments), and a workaround for a problem I'm seeing. The problem is that sometimes (in fact, more often than not) the clrscr() call in testcode/lib/joy-test.c writes some garbage chars on the screen (most often a "P"). Could be my hardware (I haven't seen it on MAME), but to me the root cause is still unknown. --- asminc/creativision.inc | 7 ++++--- cfg/creativision.cfg | 2 +- libsrc/creativision/clrscr.s | 6 +++--- libsrc/creativision/cputc.s | 6 +++--- libsrc/creativision/crt0.s | 15 ++++++++++----- libsrc/creativision/mainargs.s | 22 ---------------------- 6 files changed, 21 insertions(+), 37 deletions(-) delete mode 100644 libsrc/creativision/mainargs.s diff --git a/asminc/creativision.inc b/asminc/creativision.inc index 83a63ba07..49d55a342 100644 --- a/asminc/creativision.inc +++ b/asminc/creativision.inc @@ -10,10 +10,10 @@ CURSOR_X = $3C CURSOR_Y = $3D ;** VDP -VDP_CONTROL_W = $3001 -VDP_DATA_W = $3000 -VDP_STATUS_R = $2001 VDP_DATA_R = $2000 +VDP_STATUS_R = $2001 +VDP_DATA_W = $3000 +VDP_CONTROL_W = $3001 ;** PIA PIA0_DATA = $1000 @@ -58,3 +58,4 @@ JOY_NNW = $4A BIOS_IRQ1_ADDR = $FF3F BIOS_IRQ2_ADDR = $FF52 BIOS_NMI_RESET_ADDR = $F808 +BIOS_WRITE_VDP_REG = $FE1F diff --git a/cfg/creativision.cfg b/cfg/creativision.cfg index 06e39b36f..9e4ecd8ce 100644 --- a/cfg/creativision.cfg +++ b/cfg/creativision.cfg @@ -4,7 +4,7 @@ SYMBOLS { MEMORY { ZP: file = "", define = yes, start = $0020, size = $00E0; RAM: file = "", define = yes, start = $01FA, size = $0206; - ROM: file = %O, define = yes, start = $B000, size = $1000; + ROM: file = %O, define = yes, start = $B000, size = $1000, fill = yes, fillval = $FF; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; diff --git a/libsrc/creativision/clrscr.s b/libsrc/creativision/clrscr.s index 9e7238345..3c4856446 100644 --- a/libsrc/creativision/clrscr.s +++ b/libsrc/creativision/clrscr.s @@ -18,7 +18,7 @@ _clrscr: lda #$50 ; VRAM offset high ($10 OR $40) sta VDP_CONTROL_W - lda #$C0 ; Space from ROM setup + lda #$40 ; Space char from ROM setup ldx #0 ldy #3 @@ -34,8 +34,8 @@ L1: sta VDP_DATA_W lda #0 sta CURSOR_X sta CURSOR_Y - sta <SCREEN_PTR + sta SCREEN_PTR lda #$10 - sta >SCREEN_PTR + sta SCREEN_PTR+1 rts diff --git a/libsrc/creativision/cputc.s b/libsrc/creativision/cputc.s index ff60494b9..437b738b2 100644 --- a/libsrc/creativision/cputc.s +++ b/libsrc/creativision/cputc.s @@ -96,8 +96,8 @@ BAD_CHAR: jmp plot ;----------------------------------------------------------------------------- -; Initialize the conio subsystem. Code goes into the INIT segment, which may -; be reused after startup. +; Initialize the conio subsystem. "INIT" segment is nothing special on the +; Creativision, it is part of the "ROM" memory. .segment "INIT" @@ -122,4 +122,4 @@ LL: lda boxchars,x bne LL cli - jmp plot + jmp plot diff --git a/libsrc/creativision/crt0.s b/libsrc/creativision/crt0.s index 420ac71ef..5185ff237 100644 --- a/libsrc/creativision/crt0.s +++ b/libsrc/creativision/crt0.s @@ -31,9 +31,6 @@ entry: ldx #<__RAM_START__ - 1 txs - ; Start interrupts - cli - ; Clear the BSS data jsr zerobss @@ -49,13 +46,21 @@ entry: ; Call module constructors jsr initlib + ; enable vertical blank interrupts in the display controller + lda #$E0 ; 16K RAM, Active Display, Mode 1, VBI enabled + ldx #$01 ; Register 1 + jsr BIOS_WRITE_VDP_REG + + ; Start interrupts + cli + ; Call main() jsr callmain ; Call module destructors. This is also the _exit entry. _exit: jsr donelib - ; TODO: Replace with some sort of reset + ; A Creativision program isn't supposed to exit. loop: jmp loop ; ------------------------------------------------------------------------ @@ -81,7 +86,7 @@ irq2: jmp BIOS_IRQ2_ADDR ; VDP Setup ; This sets to Graphics Mode 1 .byte $00 ; Register 0 - .byte $E0 ; Register 1 16K RAM, Active Display, Mode 1, VBI enabled + .byte $C0 ; Register 1 16K RAM, Active Display, Mode 1, VBI disabled .byte $04 ; Register 2 Name Table at $1000 - $12FF .byte $60 ; Register 3 Colour Table at $1800 - $181F .byte $00 ; Register 4 Pattern Table at $0000 - $07FF diff --git a/libsrc/creativision/mainargs.s b/libsrc/creativision/mainargs.s deleted file mode 100644 index cda76d8d0..000000000 --- a/libsrc/creativision/mainargs.s +++ /dev/null @@ -1,22 +0,0 @@ -; -; Ullrich von Bassewitz, 2003-03-07 -; -; Setup arguments for main -; - - - .constructor initmainargs, 24 - .import __argc, __argv - - -;--------------------------------------------------------------------------- -; Get possible command-line arguments. Goes into the special INIT segment, -; which may be reused after the startup code is run - -.segment "INIT" - -.proc initmainargs - - rts - -.endproc From 360372420bf1592345a0f8977924ce88102d00ec Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sat, 18 Mar 2017 16:33:08 +0100 Subject: [PATCH 0265/2161] Added 65SC02 support for simulator. --- src/sim65/6502.c | 662 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 546 insertions(+), 116 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index e6f358295..b6559ee46 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -11,6 +11,7 @@ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ +/* Mar-2017, Christian Krueger, added support for 65SC02 */ /* */ /* This software is provided 'as-is', without any expressed or implied */ /* warranty. In no event will the authors be held liable for any damages */ @@ -31,7 +32,14 @@ /* */ /*****************************************************************************/ - +/* 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) + * one cycle win for fetch-modify-write instructions ignored + (e.g. ROL abs,x takes only 6 cycles if no page break occurs) + */ #include "memory.h" #include "error.h" @@ -205,7 +213,22 @@ int PrintCycles; unsigned Addr; \ Cycles = 5; \ ZPAddr = MemReadByte (Regs.PC+1); \ - Addr = MemReadZPWord (ZPAddr) + Regs.YR; \ + Addr = MemReadZPWord (ZPAddr); \ + if (PAGE_CROSS (Addr, Regs.YR)) \ + ++Cycles; \ + Addr += Regs.YR; \ + Regs.AC = Regs.AC op MemReadByte (Addr); \ + TEST_ZF (Regs.AC); \ + TEST_SF (Regs.AC); \ + 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); \ @@ -234,6 +257,8 @@ int PrintCycles; } \ TEST_CF (Regs.AC); \ SET_OF ((res < -128) || (res > 127)); \ + if (CPU!=CPU_6502) \ + ++Cycles; \ } else { \ Regs.AC += rhs + GET_CF (); \ TEST_ZF (Regs.AC); \ @@ -313,6 +338,8 @@ int PrintCycles; TEST_SF (res); \ SET_CF (res <= 0xFF); \ SET_OF (((old^rhs) & (old^res) & 0x80)); \ + if (CPU!=CPU_6502) \ + ++Cycles; \ } else { \ Regs.AC -= rhs + (!GET_CF ()); \ TEST_ZF (Regs.AC); \ @@ -362,6 +389,21 @@ 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; +} + + + static void OPC_6502_05 (void) /* Opcode $05: ORA zp */ { @@ -419,6 +461,21 @@ static void OPC_6502_0A (void) +static void OPC_65SC02_0C (void) +/* Opcode $0C: TSB abs */ +{ + unsigned Addr; + unsigned char Val; + Cycles = 6; + Addr = MemReadByte (Regs.PC+1); + Val = MemReadByte (Addr); + SET_ZF ((Val & Regs.AC) == 0); + MemWriteByte (Addr, (unsigned char) (Val | Regs.AC)); + Regs.PC += 3; +} + + + static void OPC_6502_0D (void) /* Opcode $0D: ORA abs */ { @@ -460,6 +517,29 @@ static void OPC_6502_11 (void) +static void OPC_65SC02_12 (void) +/* Opcode $12: ORA (zp) */ +{ + AC_OP_ZPIND (|); +} + + + +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; +} + + + static void OPC_6502_15 (void) /* Opcode $15: ORA zp,x */ { @@ -503,6 +583,33 @@ static void OPC_6502_19 (void) +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); + Regs.PC += 1; +} + + + +static void OPC_65SC02_1C (void) +/* Opcode $1C: TRB abs */ +{ + unsigned Addr; + unsigned char Val; + Cycles = 6; + Addr = MemReadByte (Regs.PC+1); + Val = MemReadByte (Addr); + SET_ZF ((Val & Regs.AC) == 0); + MemWriteByte (Addr, (unsigned char) (Val & ~Regs.AC)); + Regs.PC += 3; +} + + + static void OPC_6502_1D (void) /* Opcode $1D: ORA abs,x */ { @@ -675,6 +782,30 @@ static void OPC_6502_31 (void) +static void OPC_65SC02_32 (void) +/* Opcode $32: AND (zp) */ +{ + AC_OP_ZPIND (&); +} + + + +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; +} + + + static void OPC_6502_35 (void) /* Opcode $35: AND zp,x */ { @@ -716,6 +847,36 @@ static void OPC_6502_39 (void) +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); + Regs.PC += 1; +} + + + +static void OPC_65SC02_3C (void) +/* Opcode $3C: BIT abs,x */ +{ + unsigned Addr; + unsigned char Val; + Cycles = 4; + Addr = MemReadByte (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; +} + + + static void OPC_6502_3D (void) /* Opcode $3D: AND abs,x */ { @@ -758,6 +919,15 @@ static void OPC_6502_41 (void) +static void OPC_65C02_44 (void) +/* Opcode $44: 'zp' 3 cycle NOP */ +{ + Cycles = 3; + Regs.PC += 2; +} + + + static void OPC_6502_45 (void) /* Opcode $45: EOR zp */ { @@ -868,6 +1038,14 @@ static void OPC_6502_51 (void) +static void OPC_65SC02_52 (void) +/* Opcode $52: EOR (zp) */ +{ + AC_OP_ZPIND (^); +} + + + static void OPC_6502_55 (void) /* Opcode $55: EOR zp,x */ { @@ -912,6 +1090,25 @@ static void OPC_6502_59 (void) +static void OPC_65SC02_5A (void) +/* Opcode $5A: PHY */ +{ + Cycles = 3; + PUSH (Regs.YR); + Regs.PC += 1; +} + + + +static void OPC_65C02_5C (void) +/* Opcode $5C: 'Absolute' 8 cycle NOP */ +{ + Cycles = 8; + Regs.PC += 3; +} + + + static void OPC_6502_5D (void) /* Opcode $5D: EOR abs,x */ { @@ -963,6 +1160,18 @@ 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; +} + + + static void OPC_6502_65 (void) /* Opcode $65: ADC zp */ { @@ -1026,19 +1235,28 @@ static void OPC_6502_6C (void) /* Opcode $6C: JMP (ind) */ { unsigned PC, Lo, Hi; - Cycles = 5; PC = Regs.PC; Lo = MemReadWord (PC+1); - /* Emulate the 6502 bug */ - Regs.PC = MemReadByte (Lo); - Hi = (Lo & 0xFF00) | ((Lo + 1) & 0xFF); - Regs.PC |= (MemReadByte (Hi) << 8); + 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); - /* 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); + /* 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 + { + Cycles = 6; + Regs.PC = MemReadWord(Lo); } } @@ -1106,6 +1324,32 @@ 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; +} + + + +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; +} + + + static void OPC_6502_75 (void) /* Opcode $75: ADC zp,x */ { @@ -1158,6 +1402,30 @@ static void OPC_6502_79 (void) +static void OPC_65SC02_7A (void) +/* Opcode $7A: PLY */ +{ + Cycles = 4; + Regs.YR = POP (); + TEST_ZF (Regs.YR); + TEST_SF (Regs.YR); + Regs.PC += 1; +} + + + +static void OPC_65SC02_7C (void) +/* Opcode $7C: JMP (ind,X) */ +{ + unsigned PC, Adr; + Cycles = 6; + PC = Regs.PC; + Adr = MemReadWord (PC+1); + Regs.PC = MemReadWord(Adr+Regs.XR); +} + + + static void OPC_6502_7D (void) /* Opcode $7D: ADC abs,x */ { @@ -1188,6 +1456,14 @@ static void OPC_6502_7E (void) +static void OPC_65SC02_80 (void) +/* Opcode $80: BRA */ +{ + BRANCH (1); +} + + + static void OPC_6502_81 (void) /* Opcode $81: STA (zp,x) */ { @@ -1250,6 +1526,20 @@ 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; +} + + + static void OPC_6502_8A (void) /* Opcode $8A: TXA */ { @@ -1320,6 +1610,20 @@ 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; +} + + + static void OPC_6502_94 (void) /* Opcode $94: STY zp,x */ { @@ -1390,6 +1694,18 @@ static void OPC_6502_9A (void) +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; +} + + + static void OPC_6502_9D (void) /* Opcode $9D: STA abs,x */ { @@ -1402,6 +1718,18 @@ 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; +} + + + static void OPC_6502_A0 (void) /* Opcode $A0: LDY #imm */ { @@ -1589,6 +1917,22 @@ 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; +} + + + static void OPC_6502_B4 (void) /* Opcode $B4: LDY zp,x */ { @@ -1884,6 +2228,20 @@ 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; +} + + + static void OPC_6502_D5 (void) /* Opcode $D5: CMP zp,x */ { @@ -1937,6 +2295,16 @@ static void OPC_6502_D9 (void) +static void OPC_65SC02_DA (void) +/* Opcode $DA: PHX */ +{ + Cycles = 3; + PUSH (Regs.XR); + Regs.PC += 1; +} + + + static void OPC_6502_DD (void) /* Opcode $DD: CMP abs,x */ { @@ -2064,6 +2432,42 @@ static void OPC_6502_EA (void) +static void OPC_65C02_NOP11(void) +/* Opcode 'Illegal' 1 cycle NOP */ +{ + Cycles = 1; + Regs.PC += 1; +} + + + +static void OPC_65C02_NOP22 (void) +/* Opcode 'Illegal' 2 byte 2 cycle NOP */ +{ + Cycles = 2; + Regs.PC += 2; +} + + + +static void OPC_65C02_NOP24 (void) +/* Opcode 'Illegal' 2 byte 4 cycle NOP */ +{ + Cycles = 4; + Regs.PC += 2; +} + + + +static void OPC_65C02_NOP34 (void) +/* Opcode 'Illegal' 3 byte 4 cycle NOP */ +{ + Cycles = 4; + Regs.PC += 3; +} + + + static void OPC_6502_EC (void) /* Opcode $EC: CPX abs */ { @@ -2129,6 +2533,20 @@ 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; +} + + + static void OPC_6502_F5 (void) /* Opcode $F5: SBC zp,x */ { @@ -2180,6 +2598,18 @@ static void OPC_6502_F9 (void) +static void OPC_65SC02_FA (void) +/* Opcode $7A: PLX */ +{ + Cycles = 4; + Regs.XR = POP (); + TEST_ZF (Regs.XR); + TEST_SF (Regs.XR); + Regs.PC += 1; +} + + + static void OPC_6502_FD (void) /* Opcode $FD: SBC abs,x */ { @@ -2483,260 +2913,260 @@ static const OPFunc OP6502Table[256] = { static const OPFunc OP65C02Table[256] = { OPC_6502_00, OPC_6502_01, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, + OPC_65C02_NOP22, // $02 + OPC_65C02_NOP11, // $03 + OPC_65SC02_04, OPC_6502_05, OPC_6502_06, - OPC_Illegal, + OPC_Illegal, // $07: RMB0 currently unsupported OPC_6502_08, OPC_6502_09, OPC_6502_0A, - OPC_Illegal, - OPC_Illegal, + OPC_65C02_NOP11, // $0B + OPC_65SC02_0C, OPC_6502_0D, OPC_6502_0E, - OPC_Illegal, + OPC_Illegal, // $0F: BBR0 currently unsupported OPC_6502_10, OPC_6502_11, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, + OPC_65SC02_12, + OPC_65C02_NOP11, // $13 + OPC_65SC02_14, OPC_6502_15, OPC_6502_16, - OPC_Illegal, + OPC_Illegal, // $17: RMB1 currently unsupported OPC_6502_18, OPC_6502_19, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, + OPC_65SC02_1A, + OPC_65C02_NOP11, // $1B + OPC_65SC02_1C, OPC_6502_1D, OPC_6502_1E, - OPC_Illegal, + OPC_Illegal, // $1F: BBR1 currently unsupported OPC_6502_20, OPC_6502_21, - OPC_Illegal, - OPC_Illegal, + OPC_65C02_NOP22, // $22 + OPC_65C02_NOP11, // $23 OPC_6502_24, OPC_6502_25, OPC_6502_26, - OPC_Illegal, + OPC_Illegal, // $27: RMB2 currently unsupported OPC_6502_28, OPC_6502_29, OPC_6502_2A, - OPC_Illegal, + OPC_65C02_NOP11, // $2B OPC_6502_2C, OPC_6502_2D, OPC_6502_2E, - OPC_Illegal, + OPC_Illegal, // $2F: BBR2 currently unsupported OPC_6502_30, OPC_6502_31, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, + OPC_65SC02_32, + OPC_65C02_NOP11, // $33 + OPC_65SC02_34, OPC_6502_35, OPC_6502_36, - OPC_Illegal, + OPC_Illegal, // $37: RMB3 currently unsupported OPC_6502_38, OPC_6502_39, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, + OPC_65SC02_3A, + OPC_65C02_NOP11, // $3B + OPC_65SC02_3C, OPC_6502_3D, OPC_6502_3E, - OPC_Illegal, + OPC_Illegal, // $3F: BBR3 currently unsupported OPC_6502_40, OPC_6502_41, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, + OPC_65C02_NOP22, // $42 + OPC_65C02_NOP11, // $43 + OPC_65C02_44, // $44 OPC_6502_45, OPC_6502_46, - OPC_Illegal, + OPC_Illegal, // $47: RMB4 currently unsupported OPC_6502_48, OPC_6502_49, OPC_6502_4A, - OPC_Illegal, + OPC_65C02_NOP11, // $4B OPC_6502_4C, OPC_6502_4D, OPC_6502_4E, - OPC_Illegal, + OPC_Illegal, // $4F: BBR4 currently unsupported OPC_6502_50, OPC_6502_51, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, + OPC_65SC02_52, + OPC_65C02_NOP11, // $53 + OPC_65C02_NOP24, // $54 OPC_6502_55, OPC_6502_56, - OPC_Illegal, + OPC_Illegal, // $57: RMB5 currently unsupported OPC_6502_58, OPC_6502_59, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, + OPC_65SC02_5A, + OPC_65C02_NOP11, // $5B + OPC_65C02_5C, OPC_6502_5D, OPC_6502_5E, - OPC_Illegal, + OPC_Illegal, // $5F: BBR5 currently unsupported OPC_6502_60, OPC_6502_61, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, + OPC_65C02_NOP22, // $62 + OPC_65C02_NOP11, // $63 + OPC_65SC02_64, OPC_6502_65, OPC_6502_66, - OPC_Illegal, + OPC_Illegal, // $67: RMB6 currently unsupported OPC_6502_68, OPC_6502_69, OPC_6502_6A, - OPC_Illegal, + OPC_65C02_NOP11, // $6B OPC_65C02_6C, OPC_6502_6D, OPC_6502_6E, - OPC_Illegal, + OPC_Illegal, // $6F: BBR6 currently unsupported OPC_6502_70, OPC_6502_71, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, + OPC_65SC02_72, + OPC_65C02_NOP11, // $73 + OPC_65SC02_74, OPC_6502_75, OPC_6502_76, - OPC_Illegal, + OPC_Illegal, // $77: RMB7 currently unsupported OPC_6502_78, OPC_6502_79, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, + OPC_65SC02_7A, + OPC_65C02_NOP11, // $7B + OPC_65SC02_7C, OPC_6502_7D, OPC_6502_7E, - OPC_Illegal, - OPC_Illegal, + OPC_Illegal, // $7F: BBR7 currently unsupported + OPC_65SC02_80, OPC_6502_81, - OPC_Illegal, - OPC_Illegal, + OPC_65C02_NOP22, // $82 + OPC_65C02_NOP11, // $83 OPC_6502_84, OPC_6502_85, OPC_6502_86, - OPC_Illegal, + OPC_Illegal, // $87: SMB0 currently unsupported OPC_6502_88, - OPC_Illegal, + OPC_65SC02_89, OPC_6502_8A, - OPC_Illegal, + OPC_65C02_NOP11, // $8B OPC_6502_8C, OPC_6502_8D, OPC_6502_8E, - OPC_Illegal, + OPC_Illegal, // $8F: BBS0 currently unsupported OPC_6502_90, OPC_6502_91, - OPC_Illegal, - OPC_Illegal, + OPC_65SC02_92, + OPC_65C02_NOP11, // $93 OPC_6502_94, OPC_6502_95, OPC_6502_96, - OPC_Illegal, + OPC_Illegal, // $97: SMB1 currently unsupported OPC_6502_98, OPC_6502_99, OPC_6502_9A, - OPC_Illegal, - OPC_Illegal, + OPC_65C02_NOP11, // $9B + OPC_65SC02_9C, OPC_6502_9D, - OPC_Illegal, - OPC_Illegal, + OPC_65SC02_9E, + OPC_Illegal, // $9F: BBS1 currently unsupported OPC_6502_A0, OPC_6502_A1, OPC_6502_A2, - OPC_Illegal, + OPC_65C02_NOP11, // $A3 OPC_6502_A4, OPC_6502_A5, OPC_6502_A6, - OPC_Illegal, + OPC_Illegal, // $A7: SMB2 currently unsupported OPC_6502_A8, OPC_6502_A9, OPC_6502_AA, - OPC_Illegal, + OPC_65C02_NOP11, // $AB OPC_6502_AC, OPC_6502_AD, OPC_6502_AE, - OPC_Illegal, + OPC_Illegal, // $AF: BBS2 currently unsupported OPC_6502_B0, OPC_6502_B1, - OPC_Illegal, - OPC_Illegal, + OPC_65SC02_B2, + OPC_65C02_NOP11, // $B3 OPC_6502_B4, OPC_6502_B5, OPC_6502_B6, - OPC_Illegal, + OPC_Illegal, // $B7: SMB3 currently unsupported OPC_6502_B8, OPC_6502_B9, OPC_6502_BA, - OPC_Illegal, + OPC_65C02_NOP11, // $BB OPC_6502_BC, OPC_6502_BD, OPC_6502_BE, - OPC_Illegal, + OPC_Illegal, // $BF: BBS3 currently unsupported OPC_6502_C0, OPC_6502_C1, - OPC_Illegal, - OPC_Illegal, + OPC_65C02_NOP22, // $C2 + OPC_65C02_NOP11, // $C3 OPC_6502_C4, OPC_6502_C5, OPC_6502_C6, - OPC_Illegal, + OPC_Illegal, // $C7: SMB4 currently unsupported OPC_6502_C8, OPC_6502_C9, OPC_6502_CA, - OPC_Illegal, + OPC_Illegal, // $CB: WAI currently unsupported OPC_6502_CC, OPC_6502_CD, OPC_6502_CE, - OPC_Illegal, + OPC_Illegal, // $CF: BBS4 currently unsupported OPC_6502_D0, OPC_6502_D1, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, + OPC_65SC02_D2, + OPC_65C02_NOP11, // $D3 + OPC_65C02_NOP24, // $D4 OPC_6502_D5, OPC_6502_D6, - OPC_Illegal, + OPC_Illegal, // $D7: SMB5 currently unsupported OPC_6502_D8, OPC_6502_D9, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, + OPC_65SC02_DA, + OPC_Illegal, // $DB: STP currently unsupported + OPC_65C02_NOP34, // $DC OPC_6502_DD, OPC_6502_DE, - OPC_Illegal, + OPC_Illegal, // $DF: BBS5 currently unsupported OPC_6502_E0, OPC_6502_E1, - OPC_Illegal, - OPC_Illegal, + OPC_65C02_NOP22, // $E2 + OPC_65C02_NOP11, // $E3 OPC_6502_E4, OPC_6502_E5, OPC_6502_E6, - OPC_Illegal, + OPC_Illegal, // $E7: SMB6 currently unsupported OPC_6502_E8, OPC_6502_E9, OPC_6502_EA, - OPC_Illegal, + OPC_65C02_NOP11, // $EB OPC_6502_EC, OPC_6502_ED, OPC_6502_EE, - OPC_Illegal, + OPC_Illegal, // $EF: BBS6 currently unsupported OPC_6502_F0, OPC_6502_F1, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, + OPC_65SC02_F2, + OPC_65C02_NOP11, // $F3 + OPC_65C02_NOP24, // $F4 OPC_6502_F5, OPC_6502_F6, - OPC_Illegal, + OPC_Illegal, // $F7: SMB7 currently unsupported OPC_6502_F8, OPC_6502_F9, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, + OPC_65SC02_FA, + OPC_65C02_NOP11, // $FB + OPC_65C02_NOP34, // $FC OPC_6502_FD, OPC_6502_FE, - OPC_Illegal, + OPC_Illegal, // $FF: BBS7 currently unsupported }; From 4ba34f2a69b14b04a6fef142ab4174b8b1b2fe65 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sat, 18 Mar 2017 16:54:00 +0100 Subject: [PATCH 0266/2161] fixed scrambled semicolon --- 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 b6559ee46..bd5abcac7 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -865,10 +865,10 @@ static void OPC_65SC02_3C (void) unsigned Addr; unsigned char Val; Cycles = 4; - Addr = MemReadByte (Regs.PC+1) + Addr = MemReadByte (Regs.PC+1); if (PAGE_CROSS (Addr, Regs.XR)) ++Cycles; - Val = MemReadByte (Addr + Regs.XR;); + Val = MemReadByte (Addr + Regs.XR); SET_SF (Val & 0x80); SET_OF (Val & 0x40); SET_ZF ((Val & Regs.AC) == 0); From c50e4d25e20ddae2384a8d8a6a6d55e75c4836ec Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sat, 18 Mar 2017 16:56:36 +0100 Subject: [PATCH 0267/2161] additional fix for scrambled code (sorry) --- 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 bd5abcac7..af82f00f7 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -865,7 +865,7 @@ static void OPC_65SC02_3C (void) unsigned Addr; unsigned char Val; Cycles = 4; - Addr = MemReadByte (Regs.PC+1); + Addr = MemReadWord (Regs.PC+1); if (PAGE_CROSS (Addr, Regs.XR)) ++Cycles; Val = MemReadByte (Addr + Regs.XR); From 0985655ac748656b7f7d80fa3695bd21a4fdf6f9 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sat, 18 Mar 2017 17:02:22 +0100 Subject: [PATCH 0268/2161] Fixed bug in original sim65 implementation (reason for C&P error in last commit) --- 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 af82f00f7..996334295 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -1447,7 +1447,7 @@ static void OPC_6502_7E (void) unsigned Addr; unsigned Val; Cycles = 7; - Addr = MemReadByte (Regs.PC+1) + Regs.XR; + Addr = MemReadWord (Regs.PC+1) + Regs.XR; Val = MemReadByte (Addr); ROR (Val); MemWriteByte (Addr, Val); From ad003e59919028a6563d88cd8ef16c66474b2aa3 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sat, 18 Mar 2017 20:27:41 +0100 Subject: [PATCH 0269/2161] style changes --- src/sim65/6502.c | 122 +++++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 58 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index 996334295..eeaeeca22 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -215,7 +215,9 @@ int PrintCycles; ZPAddr = MemReadByte (Regs.PC+1); \ Addr = MemReadZPWord (ZPAddr); \ if (PAGE_CROSS (Addr, Regs.YR)) \ + { \ ++Cycles; \ + } \ Addr += Regs.YR; \ Regs.AC = Regs.AC op MemReadByte (Addr); \ TEST_ZF (Regs.AC); \ @@ -257,8 +259,10 @@ int PrintCycles; } \ TEST_CF (Regs.AC); \ SET_OF ((res < -128) || (res > 127)); \ - if (CPU!=CPU_6502) \ + if (CPU != CPU_6502) \ + { \ ++Cycles; \ + } \ } else { \ Regs.AC += rhs + GET_CF (); \ TEST_ZF (Regs.AC); \ @@ -338,8 +342,10 @@ int PrintCycles; TEST_SF (res); \ SET_CF (res <= 0xFF); \ SET_OF (((old^rhs) & (old^res) & 0x80)); \ - if (CPU!=CPU_6502) \ + if (CPU != CPU_6502) \ + { \ ++Cycles; \ + } \ } else { \ Regs.AC -= rhs + (!GET_CF ()); \ TEST_ZF (Regs.AC); \ @@ -396,7 +402,7 @@ static void OPC_65SC02_04 (void) unsigned char Val; Cycles = 5; ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr); + Val = MemReadByte (ZPAddr); SET_ZF ((Val & Regs.AC) == 0); MemWriteByte (ZPAddr, (unsigned char)(Val | Regs.AC)); Regs.PC += 2; @@ -419,7 +425,7 @@ static void OPC_6502_06 (void) unsigned Val; Cycles = 5; ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr) << 1; + Val = MemReadByte (ZPAddr) << 1; MemWriteByte (ZPAddr, (unsigned char) Val); TEST_ZF (Val & 0xFF); TEST_SF (Val); @@ -468,7 +474,7 @@ static void OPC_65SC02_0C (void) unsigned char Val; Cycles = 6; Addr = MemReadByte (Regs.PC+1); - Val = MemReadByte (Addr); + Val = MemReadByte (Addr); SET_ZF ((Val & Regs.AC) == 0); MemWriteByte (Addr, (unsigned char) (Val | Regs.AC)); Regs.PC += 3; @@ -491,7 +497,7 @@ static void OPC_6502_0E (void) unsigned Val; Cycles = 6; Addr = MemReadWord (Regs.PC+1); - Val = MemReadByte (Addr) << 1; + Val = MemReadByte (Addr) << 1; MemWriteByte (Addr, (unsigned char) Val); TEST_ZF (Val & 0xFF); TEST_SF (Val); @@ -532,7 +538,7 @@ static void OPC_65SC02_14 (void) unsigned char Val; Cycles = 5; ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr); + Val = MemReadByte (ZPAddr); SET_ZF ((Val & Regs.AC) == 0); MemWriteByte (ZPAddr, (unsigned char)(Val & ~Regs.AC)); Regs.PC += 2; @@ -555,7 +561,7 @@ static void OPC_6502_16 (void) unsigned Val; Cycles = 6; ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Val = MemReadByte (ZPAddr) << 1; + Val = MemReadByte (ZPAddr) << 1; MemWriteByte (ZPAddr, (unsigned char) Val); TEST_ZF (Val & 0xFF); TEST_SF (Val); @@ -602,7 +608,7 @@ static void OPC_65SC02_1C (void) unsigned char Val; Cycles = 6; Addr = MemReadByte (Regs.PC+1); - Val = MemReadByte (Addr); + Val = MemReadByte (Addr); SET_ZF ((Val & Regs.AC) == 0); MemWriteByte (Addr, (unsigned char) (Val & ~Regs.AC)); Regs.PC += 3; @@ -625,7 +631,7 @@ static void OPC_6502_1E (void) unsigned Val; Cycles = 7; Addr = MemReadWord (Regs.PC+1) + Regs.XR; - Val = MemReadByte (Addr) << 1; + Val = MemReadByte (Addr) << 1; MemWriteByte (Addr, (unsigned char) Val); TEST_ZF (Val & 0xFF); TEST_SF (Val); @@ -640,7 +646,7 @@ static void OPC_6502_20 (void) { unsigned Addr; Cycles = 6; - Addr = MemReadWord (Regs.PC+1); + Addr = MemReadWord (Regs.PC+1); Regs.PC += 2; PUSH (PCH); PUSH (PCL); @@ -666,7 +672,7 @@ static void OPC_6502_24 (void) unsigned char Val; Cycles = 3; ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr); + Val = MemReadByte (ZPAddr); SET_SF (Val & 0x80); SET_OF (Val & 0x40); SET_ZF ((Val & Regs.AC) == 0); @@ -690,7 +696,7 @@ static void OPC_6502_26 (void) unsigned Val; Cycles = 5; ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr); + Val = MemReadByte (ZPAddr); ROL (Val); MemWriteByte (ZPAddr, Val); Regs.PC += 2; @@ -734,7 +740,7 @@ static void OPC_6502_2C (void) unsigned char Val; Cycles = 4; Addr = MemReadByte (Regs.PC+1); - Val = MemReadByte (Addr); + Val = MemReadByte (Addr); SET_SF (Val & 0x80); SET_OF (Val & 0x40); SET_ZF ((Val & Regs.AC) == 0); @@ -758,7 +764,7 @@ static void OPC_6502_2E (void) unsigned Val; Cycles = 6; Addr = MemReadWord (Regs.PC+1); - Val = MemReadByte (Addr); + Val = MemReadByte (Addr); ROL (Val); MemWriteByte (Addr, Val); Regs.PC += 3; @@ -797,7 +803,7 @@ static void OPC_65SC02_34 (void) unsigned char Val; Cycles = 4; ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Val = MemReadByte (ZPAddr); + Val = MemReadByte (ZPAddr); SET_SF (Val & 0x80); SET_OF (Val & 0x40); SET_ZF ((Val & Regs.AC) == 0); @@ -821,7 +827,7 @@ static void OPC_6502_36 (void) unsigned Val; Cycles = 6; ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Val = MemReadByte (ZPAddr); + Val = MemReadByte (ZPAddr); ROL (Val); MemWriteByte (ZPAddr, Val); Regs.PC += 2; @@ -892,7 +898,7 @@ static void OPC_6502_3E (void) unsigned Val; Cycles = 7; Addr = MemReadWord (Regs.PC+1) + Regs.XR; - Val = MemReadByte (Addr); + Val = MemReadByte (Addr); ROL (Val); MemWriteByte (Addr, Val); Regs.PC += 2; @@ -943,7 +949,7 @@ static void OPC_6502_46 (void) unsigned char Val; Cycles = 5; ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr); + Val = MemReadByte (ZPAddr); SET_CF (Val & 0x01); Val >>= 1; MemWriteByte (ZPAddr, Val); @@ -1011,7 +1017,7 @@ static void OPC_6502_4E (void) unsigned char Val; Cycles = 6; Addr = MemReadWord (Regs.PC+1); - Val = MemReadByte (Addr); + Val = MemReadByte (Addr); SET_CF (Val & 0x01); Val >>= 1; MemWriteByte (Addr, Val); @@ -1061,7 +1067,7 @@ static void OPC_6502_56 (void) unsigned char Val; Cycles = 6; ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Val = MemReadByte (ZPAddr); + Val = MemReadByte (ZPAddr); SET_CF (Val & 0x01); Val >>= 1; MemWriteByte (ZPAddr, Val); @@ -1124,7 +1130,7 @@ static void OPC_6502_5E (void) unsigned char Val; Cycles = 7; Addr = MemReadWord (Regs.PC+1) + Regs.XR; - Val = MemReadByte (Addr); + Val = MemReadByte (Addr); SET_CF (Val & 0x01); Val >>= 1; MemWriteByte (Addr, Val); @@ -1153,7 +1159,7 @@ static void OPC_6502_61 (void) unsigned Addr; Cycles = 6; ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Addr = MemReadZPWord (ZPAddr); + Addr = MemReadZPWord (ZPAddr); ADC (MemReadByte (Addr)); Regs.PC += 2; } @@ -1191,7 +1197,7 @@ static void OPC_6502_66 (void) unsigned Val; Cycles = 5; ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr); + Val = MemReadByte (ZPAddr); ROR (Val); MemWriteByte (ZPAddr, Val); Regs.PC += 2; @@ -1238,7 +1244,7 @@ static void OPC_6502_6C (void) PC = Regs.PC; Lo = MemReadWord (PC+1); - if (CPU==CPU_6502) + if (CPU == CPU_6502) { /* Emulate the 6502 bug */ Cycles = 5; @@ -1369,7 +1375,7 @@ static void OPC_6502_76 (void) unsigned Val; Cycles = 6; ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Val = MemReadByte (ZPAddr); + Val = MemReadByte (ZPAddr); ROR (Val); MemWriteByte (ZPAddr, Val); Regs.PC += 2; @@ -1392,7 +1398,7 @@ static void OPC_6502_79 (void) { unsigned Addr; Cycles = 4; - Addr = MemReadWord (Regs.PC+1); + Addr = MemReadWord (Regs.PC+1); if (PAGE_CROSS (Addr, Regs.YR)) { ++Cycles; } @@ -1431,7 +1437,7 @@ static void OPC_6502_7D (void) { unsigned Addr; Cycles = 4; - Addr = MemReadWord (Regs.PC+1); + Addr = MemReadWord (Regs.PC+1); if (PAGE_CROSS (Addr, Regs.XR)) { ++Cycles; } @@ -1448,7 +1454,7 @@ static void OPC_6502_7E (void) unsigned Val; Cycles = 7; Addr = MemReadWord (Regs.PC+1) + Regs.XR; - Val = MemReadByte (Addr); + Val = MemReadByte (Addr); ROR (Val); MemWriteByte (Addr, Val); Regs.PC += 3; @@ -1471,7 +1477,7 @@ static void OPC_6502_81 (void) unsigned Addr; Cycles = 6; ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Addr = MemReadZPWord (ZPAddr); + Addr = MemReadZPWord (ZPAddr); MemWriteByte (Addr, Regs.AC); Regs.PC += 2; } @@ -1531,7 +1537,7 @@ static void OPC_65SC02_89 (void) { unsigned char Val; Cycles = 2; - Val = MemReadByte (Regs.PC+1); + Val = MemReadByte (Regs.PC+1); SET_SF (Val & 0x80); SET_OF (Val & 0x40); SET_ZF ((Val & Regs.AC) == 0); @@ -1603,7 +1609,7 @@ static void OPC_6502_91 (void) unsigned Addr; Cycles = 6; ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadZPWord (ZPAddr) + Regs.YR; + Addr = MemReadZPWord (ZPAddr) + Regs.YR; MemWriteByte (Addr, Regs.AC); Regs.PC += 2; } @@ -1617,7 +1623,7 @@ static void OPC_65SC02_92 (void) unsigned Addr; Cycles = 5; ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadZPWord (ZPAddr); + Addr = MemReadZPWord (ZPAddr); MemWriteByte (Addr, Regs.AC); Regs.PC += 2; } @@ -1677,7 +1683,7 @@ static void OPC_6502_99 (void) { unsigned Addr; Cycles = 5; - Addr = MemReadWord (Regs.PC+1) + Regs.YR; + Addr = MemReadWord (Regs.PC+1) + Regs.YR; MemWriteByte (Addr, Regs.AC); Regs.PC += 3; } @@ -1711,7 +1717,7 @@ static void OPC_6502_9D (void) { unsigned Addr; Cycles = 5; - Addr = MemReadWord (Regs.PC+1) + Regs.XR; + Addr = MemReadWord (Regs.PC+1) + Regs.XR; MemWriteByte (Addr, Regs.AC); Regs.PC += 3; } @@ -1723,7 +1729,7 @@ static void OPC_65SC02_9E (void) { unsigned Addr; Cycles = 5; - Addr = MemReadWord (Regs.PC+1) + Regs.XR; + Addr = MemReadWord (Regs.PC+1) + Regs.XR; MemWriteByte (Addr, 0); Regs.PC += 3; } @@ -1853,7 +1859,7 @@ static void OPC_6502_AC (void) { unsigned Addr; Cycles = 4; - Addr = MemReadWord (Regs.PC+1); + Addr = MemReadWord (Regs.PC+1); Regs.YR = MemReadByte (Addr); TEST_ZF (Regs.YR); TEST_SF (Regs.YR); @@ -1867,7 +1873,7 @@ static void OPC_6502_AD (void) { unsigned Addr; Cycles = 4; - Addr = MemReadWord (Regs.PC+1); + Addr = MemReadWord (Regs.PC+1); Regs.AC = MemReadByte (Addr); TEST_ZF (Regs.AC); TEST_SF (Regs.AC); @@ -1881,7 +1887,7 @@ static void OPC_6502_AE (void) { unsigned Addr; Cycles = 4; - Addr = MemReadWord (Regs.PC+1); + Addr = MemReadWord (Regs.PC+1); Regs.XR = MemReadByte (Addr); TEST_ZF (Regs.XR); TEST_SF (Regs.XR); @@ -1905,7 +1911,7 @@ static void OPC_6502_B1 (void) unsigned Addr; Cycles = 5; ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadZPWord (ZPAddr); + Addr = MemReadZPWord (ZPAddr); if (PAGE_CROSS (Addr, Regs.YR)) { ++Cycles; } @@ -1924,7 +1930,7 @@ static void OPC_65SC02_B2 (void) unsigned Addr; Cycles = 5; ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadZPWord (ZPAddr); + Addr = MemReadZPWord (ZPAddr); Regs.AC = MemReadByte (Addr); TEST_ZF (Regs.AC); TEST_SF (Regs.AC); @@ -2082,7 +2088,7 @@ static void OPC_6502_C1 (void) unsigned Addr; Cycles = 6; ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Addr = MemReadZPWord (ZPAddr); + Addr = MemReadZPWord (ZPAddr); CMP (Regs.AC, MemReadByte (Addr)); Regs.PC += 2; } @@ -2120,7 +2126,7 @@ static void OPC_6502_C6 (void) unsigned char Val; Cycles = 5; ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr) - 1; + Val = MemReadByte (ZPAddr) - 1; MemWriteByte (ZPAddr, Val); TEST_ZF (Val); TEST_SF (Val); @@ -2168,7 +2174,7 @@ static void OPC_6502_CC (void) { unsigned Addr; Cycles = 4; - Addr = MemReadWord (Regs.PC+1); + Addr = MemReadWord (Regs.PC+1); CMP (Regs.YR, MemReadByte (Addr)); Regs.PC += 3; } @@ -2180,7 +2186,7 @@ static void OPC_6502_CD (void) { unsigned Addr; Cycles = 4; - Addr = MemReadWord (Regs.PC+1); + Addr = MemReadWord (Regs.PC+1); CMP (Regs.AC, MemReadByte (Addr)); Regs.PC += 3; } @@ -2218,7 +2224,7 @@ static void OPC_6502_D1 (void) unsigned Addr; Cycles = 5; ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadWord (ZPAddr); + Addr = MemReadWord (ZPAddr); if (PAGE_CROSS (Addr, Regs.YR)) { ++Cycles; } @@ -2235,7 +2241,7 @@ static void OPC_65SC02_D2 (void) unsigned Addr; Cycles = 5; ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadWord (ZPAddr); + Addr = MemReadWord (ZPAddr); CMP (Regs.AC, MemReadByte (Addr)); Regs.PC += 2; } @@ -2327,7 +2333,7 @@ static void OPC_6502_DE (void) unsigned char Val; Cycles = 7; Addr = MemReadWord (Regs.PC+1) + Regs.XR; - Val = MemReadByte (Addr) - 1; + Val = MemReadByte (Addr) - 1; MemWriteByte (Addr, Val); TEST_ZF (Val); TEST_SF (Val); @@ -2353,7 +2359,7 @@ static void OPC_6502_E1 (void) unsigned Addr; Cycles = 6; ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Addr = MemReadZPWord (ZPAddr); + Addr = MemReadZPWord (ZPAddr); SBC (MemReadByte (Addr)); Regs.PC += 2; } @@ -2391,7 +2397,7 @@ static void OPC_6502_E6 (void) unsigned char Val; Cycles = 5; ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr) + 1; + Val = MemReadByte (ZPAddr) + 1; MemWriteByte (ZPAddr, Val); TEST_ZF (Val); TEST_SF (Val); @@ -2485,7 +2491,7 @@ static void OPC_6502_ED (void) { unsigned Addr; Cycles = 4; - Addr = MemReadWord (Regs.PC+1); + Addr = MemReadWord (Regs.PC+1); SBC (MemReadByte (Addr)); Regs.PC += 3; } @@ -2499,7 +2505,7 @@ static void OPC_6502_EE (void) unsigned char Val; Cycles = 6; Addr = MemReadWord (Regs.PC+1); - Val = MemReadByte (Addr) + 1; + Val = MemReadByte (Addr) + 1; MemWriteByte (Addr, Val); TEST_ZF (Val); TEST_SF (Val); @@ -2523,7 +2529,7 @@ static void OPC_6502_F1 (void) unsigned Addr; Cycles = 5; ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadZPWord (ZPAddr); + Addr = MemReadZPWord (ZPAddr); if (PAGE_CROSS (Addr, Regs.YR)) { ++Cycles; } @@ -2540,7 +2546,7 @@ static void OPC_65SC02_F2 (void) unsigned Addr; Cycles = 5; ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadZPWord (ZPAddr); + Addr = MemReadZPWord (ZPAddr); SBC (MemReadByte (Addr)); Regs.PC += 2; } @@ -2566,7 +2572,7 @@ static void OPC_6502_F6 (void) unsigned char Val; Cycles = 6; ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Val = MemReadByte (ZPAddr) + 1; + Val = MemReadByte (ZPAddr) + 1; MemWriteByte (ZPAddr, Val); TEST_ZF (Val); TEST_SF (Val); @@ -2588,7 +2594,7 @@ static void OPC_6502_F9 (void) { unsigned Addr; Cycles = 4; - Addr = MemReadWord (Regs.PC+1); + Addr = MemReadWord (Regs.PC+1); if (PAGE_CROSS (Addr, Regs.YR)) { ++Cycles; } @@ -2615,7 +2621,7 @@ static void OPC_6502_FD (void) { unsigned Addr; Cycles = 4; - Addr = MemReadWord (Regs.PC+1); + Addr = MemReadWord (Regs.PC+1); if (PAGE_CROSS (Addr, Regs.XR)) { ++Cycles; } @@ -2632,7 +2638,7 @@ static void OPC_6502_FE (void) unsigned char Val; Cycles = 7; Addr = MemReadWord (Regs.PC+1) + Regs.XR; - Val = MemReadByte (Addr) + 1; + Val = MemReadByte (Addr) + 1; MemWriteByte (Addr, Val); TEST_ZF (Val); TEST_SF (Val); From 2048d6cfb5c29b798bd459a31192f19f4d675219 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 18 Mar 2017 20:57:12 +0100 Subject: [PATCH 0270/2161] Removed top blank line. --- libsrc/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/libsrc/Makefile b/libsrc/Makefile index cb3517c7e..f4aa03101 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -1,4 +1,3 @@ - ifneq ($(shell echo),) CMD_EXE = 1 endif From e14e13abf4850c16bade80f3519faf2760b322d2 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sat, 18 Mar 2017 22:52:13 +0100 Subject: [PATCH 0271/2161] fixed curly brackets for single line scopes --- src/sim65/6502.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index eeaeeca22..0320dd895 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -214,8 +214,7 @@ int PrintCycles; Cycles = 5; \ ZPAddr = MemReadByte (Regs.PC+1); \ Addr = MemReadZPWord (ZPAddr); \ - if (PAGE_CROSS (Addr, Regs.YR)) \ - { \ + if (PAGE_CROSS (Addr, Regs.YR)) { \ ++Cycles; \ } \ Addr += Regs.YR; \ @@ -259,8 +258,7 @@ int PrintCycles; } \ TEST_CF (Regs.AC); \ SET_OF ((res < -128) || (res > 127)); \ - if (CPU != CPU_6502) \ - { \ + if (CPU != CPU_6502) { \ ++Cycles; \ } \ } else { \ @@ -342,8 +340,7 @@ int PrintCycles; TEST_SF (res); \ SET_CF (res <= 0xFF); \ SET_OF (((old^rhs) & (old^res) & 0x80)); \ - if (CPU != CPU_6502) \ - { \ + if (CPU != CPU_6502) { \ ++Cycles; \ } \ } else { \ From 66634ef6834438324104d6f1708a0358bd3e31ae Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 19 Mar 2017 17:48:12 +0100 Subject: [PATCH 0272/2161] Cleaned up test Makefiles. --- test/Makefile | 23 ++------ test/assembler/.gitignore | 3 - test/assembler/Makefile | 91 ++++++++++++++++++------------ test/disassembler/Makefile | 76 ++++++++++++++++--------- test/err/Makefile | 21 ++++--- test/misc/Makefile | 90 ++++++++++++++++++------------ test/ref/Makefile | 110 ++++++++++++++++--------------------- test/val/Makefile | 65 +++++++++------------- 8 files changed, 253 insertions(+), 226 deletions(-) delete mode 100644 test/assembler/.gitignore diff --git a/test/Makefile b/test/Makefile index 4817e70e0..a02bd91fb 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,43 +1,30 @@ - -# top-level makefile for the regression tests +# top-level Makefile for the regression tests # You can comment this special target when you debug the regression tests. # Then, make will give you more progress reports. .SILENT: ifneq ($(shell echo),) - CMD_EXE := 1 + CMD_EXE = 1 endif ifdef CMD_EXE - EXE := .exe - MKDIR = mkdir $(subst /,\,$1) RMDIR = -rmdir /s /q $(subst /,\,$1) else - EXE := - MKDIR = mkdir $1 RMDIR = $(RM) -r $1 endif -WORKDIR := ../testwrk - -CC := gcc +WORKDIR = ../testwrk .PHONY: all dotests continue mostlyclean clean all: dotests -$(WORKDIR): - $(call MKDIR,$(WORKDIR)) - -$(WORKDIR)/bdiff$(EXE): bdiff.c | $(WORKDIR) - $(CC) -O2 -o $@ $< - .NOTPARALLEL: dotests: mostlyclean continue -continue: $(WORKDIR)/bdiff$(EXE) +continue: @$(MAKE) -C assembler all @$(MAKE) -C disassembler all @$(MAKE) -C val all @@ -46,6 +33,8 @@ continue: $(WORKDIR)/bdiff$(EXE) @$(MAKE) -C misc all mostlyclean: + @$(MAKE) -C assembler clean + @$(MAKE) -C disassembler clean @$(MAKE) -C val clean @$(MAKE) -C ref clean @$(MAKE) -C err clean diff --git a/test/assembler/.gitignore b/test/assembler/.gitignore deleted file mode 100644 index c0c74a35e..000000000 --- a/test/assembler/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.o -*.bin -*.lst diff --git a/test/assembler/Makefile b/test/assembler/Makefile index 5d38847f5..fb840446c 100644 --- a/test/assembler/Makefile +++ b/test/assembler/Makefile @@ -1,45 +1,68 @@ +# Makefile for the assembler regression tests -# makefile for the assembler regression tests +ifneq ($(shell echo),) + CMD_EXE = 1 +endif -BINDIR = ../../bin -WORKDIR := ../../testwrk +ifdef CMD_EXE + EXE = .exe + MKDIR = mkdir $(subst /,\,$1) + RMDIR = -rmdir /s /q $(subst /,\,$1) + DEL = del /f $(subst /,\,$1) +else + EXE = + MKDIR = mkdir -p $1 + RMDIR = $(RM) -r $1 + DEL = $(RM) $1 +endif -BASE_TARGETS = 6502 6502x 65sc02 65c02 -BASE_TARGETS += 4510 huc6280 +CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) -OPCODE_TARGETS = $(BASE_TARGETS) -CPUDETECT_TARGETS = $(BASE_TARGETS) +WORKDIR = ../../testwrk/asm -CPUDETECT_TARGETS += 65816 +DIFF = $(WORKDIR)/bdiff$(EXE) -# default target defined later -all: +CC = gcc +CFLAGS = -O2 -# generate opcode targets and expand target list -define opcode -OPCODE_TARGETLIST += $$(WORKDIR)/$(1)-opcodes.bin -$$(WORKDIR)/$(1)-opcodes.bin: $(1)-opcodes.s - @$$(BINDIR)/cl65 --cpu $(1) -t none -l $$(WORKDIR)/$(1)-opcodes.lst --obj-path $$(WORKDIR) -o $$@ $$< - @diff -q $(1)-opcodes.ref $$@ || (cat $$(WORKDIR)/$(1)-opcodes.lst ; exit 1) - @echo ca65 --cpu $(1) opcodes ok - @rm -f $(1)-opcodes.o #workaround for #168 -endef -$(foreach target,$(OPCODE_TARGETS),$(eval $(call opcode,$(target)))) +.PHONY: all clean -# generate cpudetect targets and expand target list -define cpudetect -CPUDETECT_TARGETLIST += $$(WORKDIR)/$(1)-cpudetect.bin -$$(WORKDIR)/$(1)-cpudetect.bin: cpudetect.s - @$$(BINDIR)/cl65 --cpu $(1) -t none -l $$(WORKDIR)/$(1)-cpudetect.lst --obj-path $$(WORKDIR) -o $$@ $$< - @diff -q $(1)-cpudetect.ref $$@ || (cat $$(WORKDIR)/$(1)-cpudetect.lst ; exit 1) - @echo ca65 --cpu $(1) cpudetect ok - @rm -f cpudetect.o #workaround for #168 -endef -$(foreach target,$(CPUDETECT_TARGETS),$(eval $(call cpudetect,$(target)))) +OPCODE_REFS := $(wildcard *-opcodes.ref) +OPCODE_CPUS = $(foreach ref,$(OPCODE_REFS),$(ref:%-opcodes.ref=%)) +OPCODE_BINS = $(foreach cpu,$(OPCODE_CPUS),$(WORKDIR)/$(cpu)-opcodes.bin) -# now that all targets have been generated, get to the manual ones -all: $(OPCODE_TARGETLIST) $(CPUDETECT_TARGETLIST) - @# +CPUDETECT_REFS := $(wildcard *-cpudetect.ref) +CPUDETECT_CPUS = $(foreach ref,$(CPUDETECT_REFS),$(ref:%-cpudetect.ref=%)) +CPUDETECT_BINS = $(foreach cpu,$(CPUDETECT_CPUS),$(WORKDIR)/$(cpu)-cpudetect.bin) -.PHONY: all $(OPCODE_TARGETLIST) $(CPUDETECT_TARGETLIST) +all: $(OPCODE_BINS) $(CPUDETECT_BINS) +$(WORKDIR): + $(call MKDIR,$(WORKDIR)) + +$(DIFF): ../bdiff.c | $(WORKDIR) + $(CC) $(CFLAGS) -o $@ $< + +define OPCODE_template + +$(WORKDIR)/$1-opcodes.bin: $1-opcodes.s $(DIFF) + $(CL65) --cpu $1 -t none -l $(WORKDIR)/$1-opcodes.lst -o $$@ $$< + $(DIFF) $$@ $1-opcodes.ref + +endef # OPCODE_template + +$(foreach cpu,$(OPCODE_CPUS),$(eval $(call OPCODE_template,$(cpu)))) + +define CPUDETECT_template + +$(WORKDIR)/$1-cpudetect.bin: cpudetect.s $(DIFF) + $(CL65) --cpu $1 -t none -l $(WORKDIR)/$1-cpudetect.lst -o $$@ $$< + $(DIFF) $$@ $1-cpudetect.ref + +endef # CPUDETECT_template + +$(foreach cpu,$(CPUDETECT_CPUS),$(eval $(call CPUDETECT_template,$(cpu)))) + +clean: + @$(call RMDIR,$(WORKDIR)) + @$(call DEL,$(OPCODE_REFS:.ref=.o) cpudetect.o) diff --git a/test/disassembler/Makefile b/test/disassembler/Makefile index 2621b0c20..f8942ef73 100644 --- a/test/disassembler/Makefile +++ b/test/disassembler/Makefile @@ -1,42 +1,64 @@ +# Makefile for the disassembler regression tests -# makefile for the disassembler regression tests +ifneq ($(shell echo),) + CMD_EXE = 1 +endif -BINDIR = ../../bin -WORKDIR := ../../testwrk +ifdef CMD_EXE + EXE = .exe + MKDIR = mkdir $(subst /,\,$1) + RMDIR = -rmdir /s /q $(subst /,\,$1) + DEL = del /f $(subst /,\,$1) +else + EXE = + MKDIR = mkdir -p $1 + RMDIR = $(RM) -r $1 + DEL = $(RM) $1 +endif -#BASE_TARGETS = 6502 6502x 65sc02 65c02 -#BASE_TARGETS += 4510 huc6280 -BASE_TARGETS = 4510 +CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) +DA65 := $(if $(wildcard ../../bin/da65*),../../bin/da65,da65) + +WORKDIR = ../../testwrk/dasm + +DIFF = $(WORKDIR)/bdiff$(EXE) + +CC = gcc +CFLAGS = -O2 START = --start-addr 0x8000 -DISASS_TARGETS = $(BASE_TARGETS) +.PHONY: all clean + +SOURCES := $(wildcard *.s) +CPUS = $(foreach src,$(SOURCES),$(src:%-disass.s=%)) +BINS = $(foreach cpu,$(CPUS),$(WORKDIR)/$(cpu)-reass.bin) # default target defined later -all: +all: $(BINS) -# generate opcode targets and expand target list -define disass -DISASS_TARGETLIST += $$(WORKDIR)/$(1)-reass.bin $$(WORKDIR)/$(1)-reass.s $$(WORKDIR)/$(1)-disass.bin +$(WORKDIR): + $(call MKDIR,$(WORKDIR)) -$$(WORKDIR)/$(1)-disass.bin: $(1)-disass.s - @$$(BINDIR)/cl65 --cpu $(1) -t none $(START) --obj-path $$(WORKDIR) -o $$@ $$< - @rm -f $(1)-disass.o #workaround for #168 +$(DIFF): ../bdiff.c | $(WORKDIR) + $(CC) $(CFLAGS) -o $@ $< -$$(WORKDIR)/$(1)-reass.s: $$(WORKDIR)/$(1)-disass.bin - @$$(BINDIR)/da65 --cpu $(1) $(START) -o $$@ $$< +define DISASS_template -$$(WORKDIR)/$(1)-reass.bin: $$(WORKDIR)/$(1)-reass.s - @$$(BINDIR)/cl65 --cpu $(1) -t none $(START) --obj-path $$(WORKDIR) -o $$@ $$< - @rm -f $(1)-reass.o #workaround for #168 - @cmp $$@ $$(WORKDIR)/$(1)-disass.bin - @echo da65 --cpu $(1) ok -endef -$(foreach target,$(DISASS_TARGETS),$(eval $(call disass,$(target)))) +$(WORKDIR)/$1-disass.bin: $1-disass.s | $(WORKDIR) + $(CL65) --cpu $1 -t none $(START) -o $$@ $$< -# now that all targets have been generated, get to the manual ones -all: $(DISASS_TARGETLIST) - @# +$(WORKDIR)/$1-reass.s: $(WORKDIR)/$1-disass.bin + $(DA65) --cpu $1 $(START) -o $$@ $$< -.PHONY: all $(DISASS_TARGETLIST) +$(WORKDIR)/$1-reass.bin: $(WORKDIR)/$1-reass.s $(DIFF) + $(CL65) --cpu $1 -t none $(START) -o $$@ $$< + $(DIFF) $$@ $(WORKDIR)/$1-disass.bin +endef # DISASS_template + +$(foreach cpu,$(CPUS),$(eval $(call DISASS_template,$(cpu)))) + +clean: + @$(call RMDIR,$(WORKDIR)) + @$(call DEL,$(SOURCES:.s=.o)) diff --git a/test/err/Makefile b/test/err/Makefile index bc4226acb..2bcc1d264 100644 --- a/test/err/Makefile +++ b/test/err/Makefile @@ -1,24 +1,27 @@ -# makefile for the tests that MUST NOT compile +# Makefile for the tests that MUST NOT compile ifneq ($(shell echo),) - CMD_EXE := 1 + CMD_EXE = 1 endif ifdef CMD_EXE - NOT := - # Hack - DEL = -del /f $(subst /,\,$1) + NOT = - # Hack + MKDIR = mkdir $(subst /,\,$1) + RMDIR = -rmdir /s /q $(subst /,\,$1) else - NOT := ! - DEL = $(RM) $1 + NOT = ! + MKDIR = mkdir -p $1 + RMDIR = $(RM) -r $1 endif CC65 := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65) -WORKDIR := ../../testwrk +WORKDIR = ../../testwrk/err .PHONY: all clean -TESTS := $(patsubst %.c,$(WORKDIR)/%.s,$(wildcard *.c)) +SOURCES := $(wildcard *.c) +TESTS = $(patsubst %.c,$(WORKDIR)/%.s,$(SOURCES)) all: $(TESTS) @@ -26,4 +29,4 @@ $(WORKDIR)/%.s: %.c $(NOT) $(CC65) -o $@ $< clean: - @$(call DEL,$(TESTS)) + @$(call RMDIR,$(WORKDIR)) diff --git a/test/misc/Makefile b/test/misc/Makefile index 918316c6c..6512a9fd9 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -1,63 +1,85 @@ - -# makefile for the remaining tests that need special care in one way or another +# Makefile for the remaining tests that need special care in one way or another ifneq ($(shell echo),) - CMD_EXE := 1 + CMD_EXE = 1 endif ifdef CMD_EXE - S := $(subst /,\,/) - NOT := - # Hack - DEL = -del /f $(subst /,\,$1) + S = $(subst /,\,/) + NOT = - # Hack + EXE = .exe + MKDIR = mkdir $(subst /,\,$1) + RMDIR = -rmdir /s /q $(subst /,\,$1) + DEL = del /f $(subst /,\,$1) else - S := / - NOT := ! + S = / + NOT = ! + EXE = + MKDIR = mkdir -p $1 + RMDIR = $(RM) -r $1 DEL = $(RM) $1 endif -CC65FLAGS := -t sim6502 -SIM65FLAGS := -x 200000000 +CC65FLAGS = -t sim6502 +SIM65FLAGS = -x 200000000 CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65) -WORKDIR := ..$S..$Stestwrk -DIFF := $(WORKDIR)/bdiff +WORKDIR = ..$S..$Stestwrk$Smisc + +OPTIONS = g O Os Osi Osir Oi Oir Or + +DIFF = $(WORKDIR)$Sbdiff$(EXE) + +CC = gcc +CFLAGS = -O2 .PHONY: all clean SOURCES := $(wildcard *.c) -TESTS := $(foreach option,. .o. .os. .osi. .osir. .oi. .oir. .or.,$(SOURCES:%.c=$(WORKDIR)/%$(option)prg)) +TESTS = $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).prg)) all: $(TESTS) +$(WORKDIR): + $(call MKDIR,$(WORKDIR)) + +$(DIFF): ../bdiff.c | $(WORKDIR) + $(CC) $(CFLAGS) -o $@ $< + +define PRG_template + # should compile, but then hangs in an endless loop -$(WORKDIR)/endless%prg: endless.c - $(CL65) $(subst .,,$(*:.o%=-O%)) $(CC65FLAGS) $< -o $@ - $(NOT) $(SIM65) $(SIM65FLAGS) $@ +$(WORKDIR)/endless.$1.prg: endless.c | $(WORKDIR) + $(CL65) $(CC65FLAGS) -$1 -o $$@ $$< + $(NOT) $(SIM65) $(SIM65FLAGS) $$@ # these need reference data that can't be generated by a host-compiled program, # in a useful way -$(WORKDIR)/limits%prg: limits.c - $(CL65) $(subst .,,$(*:.o%=-O%)) $(CC65FLAGS) $< -o $@ - $(SIM65) $(SIM65FLAGS) $@ > $(WORKDIR)/limits.out - $(DIFF) $(WORKDIR)/limits.out limits.ref +$(WORKDIR)/limits.$1.prg: limits.c $(DIFF) + $(CL65) $(CC65FLAGS) -$1 -o $$@ $$< + $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/limits.$1.out + $(DIFF) $(WORKDIR)/limits.$1.out limits.ref # the rest are tests that fail currently for one reason or another -$(WORKDIR)/fields%prg: fields.c - @echo "FIXME: " $@ "currently will fail." - $(CL65) $(subst .,,$(*:.o%=-O%)) $(CC65FLAGS) $< -o $@ - -$(SIM65) $(SIM65FLAGS) $@ -$(WORKDIR)/sitest%prg: sitest.c - @echo "FIXME: " $@ "currently will fail." - -$(CL65) $(subst .,,$(*:.o%=-O%)) $(CC65FLAGS) $< -o $@ -# -$(SIM65) $(SIM65FLAGS) $@ -$(WORKDIR)/cc65141011%prg: cc65141011.c - @echo "FIXME: " $@ "currently can fail." - $(CL65) $(subst .,,$(*:.o%=-O%)) $(CC65FLAGS) $< -o $@ - -$(SIM65) $(SIM65FLAGS) $@ +$(WORKDIR)/fields.$1.prg: fields.c | $(WORKDIR) + @echo "FIXME: " $$@ "currently will fail." + $(CL65) $(CC65FLAGS) -$1 -o $$@ $$< + -$(SIM65) $(SIM65FLAGS) $$@ +$(WORKDIR)/sitest.$1.prg: sitest.c | $(WORKDIR) + @echo "FIXME: " $$@ "currently will fail." + -$(CL65) $(CC65FLAGS) -$1 -o $$@ $$< +# -$(SIM65) $(SIM65FLAGS) $$@ +$(WORKDIR)/cc65141011.$1.prg: cc65141011.c | $(WORKDIR) + @echo "FIXME: " $$@ "currently can fail." + $(CL65) $(CC65FLAGS) -$1 -o $$@ $$< + -$(SIM65) $(SIM65FLAGS) $$@ + +endef # PRG_template + +$(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option)))) clean: - @$(call DEL,$(TESTS)) + @$(call RMDIR,$(WORKDIR)) @$(call DEL,$(SOURCES:.c=.o)) - @$(call DEL,$(SOURCES:%.c=$(WORKDIR)/%.out)) diff --git a/test/ref/Makefile b/test/ref/Makefile index 6f0bd1bc1..7bd10cf14 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -1,102 +1,84 @@ -# makefile for the regression tests that generate output which has to be +# Makefile for the regression tests that generate output which has to be # compared with reference output ifneq ($(shell echo),) - CMD_EXE := 1 + CMD_EXE = 1 endif ifdef CMD_EXE - S := $(subst /,\,/) - DEL = -del /f $(subst /,\,$1) + S = $(subst /,\,/) + EXE = .exe + MKDIR = mkdir $(subst /,\,$1) + RMDIR = -rmdir /s /q $(subst /,\,$1) + DEL = del /f $(subst /,\,$1) else - S := / + S = / + EXE = + MKDIR = mkdir -p $1 + RMDIR = $(RM) -r $1 DEL = $(RM) $1 endif -CC65FLAGS := -t sim6502 -SIM65FLAGS := -x 200000000 +CC65FLAGS = -t sim6502 +SIM65FLAGS = -x 200000000 CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65) -WORKDIR := ..$S..$Stestwrk -DIFF := $(WORKDIR)/bdiff +WORKDIR = ..$S..$Stestwrk$Sref -CC := gcc -CFLAGS := -O2 -Wall -W -Wextra -funsigned-char -fwrapv -fno-strict-overflow +OPTIONS = g O Os Osi Osir Oi Oir Or + +DIFF = $(WORKDIR)$Sbdiff$(EXE) + +CC = gcc +CFLAGS = -O2 -Wall -W -Wextra -funsigned-char -fwrapv -fno-strict-overflow .PHONY: all clean SOURCES := $(wildcard *.c) -REFS := $(SOURCES:%.c=$(WORKDIR)/%.ref) -TESTS := $(foreach option,. .o. .os. .osi. .osir. .oi. .oir. .or.,$(SOURCES:%.c=$(WORKDIR)/%$(option)prg)) +REFS = $(SOURCES:%.c=$(WORKDIR)/%.ref) +TESTS = $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).prg)) all: $(REFS) $(TESTS) -# "yaccdbg.c" includes "yacc.c". -# yaccdbg's built files must depend on both of them. +$(WORKDIR): + $(call MKDIR,$(WORKDIR)) -$(WORKDIR)/yaccdbg.ref: yacc.c - -$(WORKDIR)/%.ref: %.c - $(CC) $(CFLAGS) $< -o $(WORKDIR)/$*.host +$(WORKDIR)/%.ref: %.c | $(WORKDIR) + $(CC) $(CFLAGS) -o $(WORKDIR)/$*.host $< $(WORKDIR)$S$*.host > $@ +$(DIFF): ../bdiff.c | $(WORKDIR) + $(CC) $(CFLAGS) -o $@ $< + # Some files have "K & R"-style syntax. Therefore, some forward # function-declarations don't match the later function definitions. # Those programs fail when fastcall is used; but, the cdecl calling convention # tolerates those conflicts. Therefore, make their functions default to cdecl. # -$(WORKDIR)/init%prg: CC65FLAGS += -Wc --all-cdecl -$(WORKDIR)/switch.%rg: CC65FLAGS += -Wc --all-cdecl -$(WORKDIR)/yacc.%rg: CC65FLAGS += -Wc --all-cdecl -$(WORKDIR)/yaccdbg%prg: CC65FLAGS += -Wc --all-cdecl +$(WORKDIR)/init.%.prg \ +$(WORKDIR)/switch.%.prg \ +$(WORKDIR)/yacc.%.prg \ +$(WORKDIR)/yaccdbg.%.prg: CC65FLAGS += -Wc --all-cdecl -$(WORKDIR)/yaccdbg%prg: yacc.c +# "yaccdbg.c" includes "yacc.c". +# yaccdbg's built files must depend on both of them. +# +$(WORKDIR)/yaccdbg.ref: yacc.c +$(WORKDIR)/yaccdbg.%.prg: yacc.c -$(WORKDIR)/%.prg: %.c $(WORKDIR)/%.ref - $(CL65) $(CC65FLAGS) $< -o $@ - $(SIM65) $(SIM65FLAGS) $@ > $(WORKDIR)/$*.out - $(DIFF) $(WORKDIR)/$*.out $(WORKDIR)/$*.ref +define PRG_template -$(WORKDIR)/%.o.prg: %.c $(WORKDIR)/%.ref - $(CL65) -O $(CC65FLAGS) $< -o $@ - $(SIM65) $(SIM65FLAGS) $@ > $(WORKDIR)/$*.out - $(DIFF) $(WORKDIR)/$*.out $(WORKDIR)/$*.ref +$(WORKDIR)/%.$1.prg: %.c $(WORKDIR)/%.ref $(DIFF) + $(CL65) $$(CC65FLAGS) -$1 -o $$@ $$< + $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/$$*.out + $(DIFF) $(WORKDIR)/$$*.out $(WORKDIR)/$$*.ref -$(WORKDIR)/%.os.prg: %.c $(WORKDIR)/%.ref - $(CL65) -Os $(CC65FLAGS) $< -o $@ - $(SIM65) $(SIM65FLAGS) $@ > $(WORKDIR)/$*.out - $(DIFF) $(WORKDIR)/$*.out $(WORKDIR)/$*.ref +endef # PRG_template -$(WORKDIR)/%.osi.prg: %.c $(WORKDIR)/%.ref - $(CL65) -Osi $(CC65FLAGS) $< -o $@ - $(SIM65) $(SIM65FLAGS) $@ > $(WORKDIR)/$*.out - $(DIFF) $(WORKDIR)/$*.out $(WORKDIR)/$*.ref - -$(WORKDIR)/%.osir.prg: %.c $(WORKDIR)/%.ref - $(CL65) -Osir $(CC65FLAGS) $< -o $@ - $(SIM65) $(SIM65FLAGS) $@ > $(WORKDIR)/$*.out - $(DIFF) $(WORKDIR)/$*.out $(WORKDIR)/$*.ref - -$(WORKDIR)/%.oi.prg: %.c $(WORKDIR)/%.ref - $(CL65) -Oi $(CC65FLAGS) $< -o $@ - $(SIM65) $(SIM65FLAGS) $@ > $(WORKDIR)/$*.out - $(DIFF) $(WORKDIR)/$*.out $(WORKDIR)/$*.ref - -$(WORKDIR)/%.oir.prg: %.c $(WORKDIR)/%.ref - $(CL65) -Oir $(CC65FLAGS) $< -o $@ - $(SIM65) $(SIM65FLAGS) $@ > $(WORKDIR)/$*.out - $(DIFF) $(WORKDIR)/$*.out $(WORKDIR)/$*.ref - -$(WORKDIR)/%.or.prg: %.c $(WORKDIR)/%.ref - $(CL65) -Or $(CC65FLAGS) $< -o $@ - $(SIM65) $(SIM65FLAGS) $@ > $(WORKDIR)/$*.out - $(DIFF) $(WORKDIR)/$*.out $(WORKDIR)/$*.ref +$(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option)))) clean: - @$(call DEL,$(TESTS)) + @$(call RMDIR,$(WORKDIR)) @$(call DEL,$(SOURCES:.c=.o)) - @$(call DEL,$(SOURCES:%.c=$(WORKDIR)/%.out)) - @$(call DEL,$(SOURCES:%.c=$(WORKDIR)/%.ref)) - @$(call DEL,$(SOURCES:%.c=$(WORKDIR)/%.host)) diff --git a/test/val/Makefile b/test/val/Makefile index 4ad8160ef..8a07045ee 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -1,70 +1,59 @@ - -# makefile for the regression tests that return an error code on failure +# Makefile for the regression tests that return an error code on failure ifneq ($(shell echo),) - CMD_EXE := 1 + CMD_EXE = 1 endif ifdef CMD_EXE - DEL = -del /f $(subst /,\,$1) + MKDIR = mkdir $(subst /,\,$1) + RMDIR = -rmdir /s /q $(subst /,\,$1) + DEL = del /f $(subst /,\,$1) else + MKDIR = mkdir -p $1 + RMDIR = $(RM) -r $1 DEL = $(RM) $1 endif -CC65FLAGS := -t sim6502 -SIM65FLAGS := -x 200000000 +CC65FLAGS = -t sim6502 +SIM65FLAGS = -x 200000000 CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) SIM65 := $(if $(wildcard ../../bin/sim65*),../../bin/sim65,sim65) -WORKDIR := ../../testwrk +WORKDIR = ../../testwrk/val + +OPTIONS = g O Os Osi Osir Oi Oir Or .PHONY: all clean SOURCES := $(wildcard *.c) -TESTS := $(foreach option,. .o. .os. .osi. .osir. .oi. .oir. .or.,$(SOURCES:%.c=$(WORKDIR)/%$(option)prg)) +TESTS = $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).prg)) all: $(TESTS) +$(WORKDIR): + $(call MKDIR,$(WORKDIR)) + # Some files have "K & R"-style syntax. Therefore, some forward # function-declarations don't match the later function definitions. # Those programs fail when fastcall is used; but, the cdecl calling convention # tolerates those conflicts. Therefore, make their functions default to cdecl. # -$(WORKDIR)/cq4%prg $(WORKDIR)/cq71.%rg $(WORKDIR)/cq81%prg $(WORKDIR)/cq84%prg: CC65FLAGS += -Wc --all-cdecl +$(WORKDIR)/cq4.%.prg \ +$(WORKDIR)/cq71.%.prg \ +$(WORKDIR)/cq81.%.prg \ +$(WORKDIR)/cq84.%.prg: CC65FLAGS += -Wc --all-cdecl -$(WORKDIR)/%.prg: %.c - $(CL65) $(CC65FLAGS) $< -o $@ - $(SIM65) $(SIM65FLAGS) $@ +define PRG_template -$(WORKDIR)/%.o.prg: %.c - $(CL65) -O $(CC65FLAGS) $< -o $@ - $(SIM65) $(SIM65FLAGS) $@ +$(WORKDIR)/%.$1.prg: %.c | $(WORKDIR) + $(CL65) $$(CC65FLAGS) -$1 -o $$@ $$< + $(SIM65) $(SIM65FLAGS) $$@ -$(WORKDIR)/%.os.prg: %.c - $(CL65) -Os $(CC65FLAGS) $< -o $@ - $(SIM65) $(SIM65FLAGS) $@ +endef # PRG_template -$(WORKDIR)/%.osi.prg: %.c - $(CL65) -Osi $(CC65FLAGS) $< -o $@ - $(SIM65) $(SIM65FLAGS) $@ - -$(WORKDIR)/%.osir.prg: %.c - $(CL65) -Osir $(CC65FLAGS) $< -o $@ - $(SIM65) $(SIM65FLAGS) $@ - -$(WORKDIR)/%.oi.prg: %.c - $(CL65) -Oi $(CC65FLAGS) $< -o $@ - $(SIM65) $(SIM65FLAGS) $@ - -$(WORKDIR)/%.oir.prg: %.c - $(CL65) -Oir $(CC65FLAGS) $< -o $@ - $(SIM65) $(SIM65FLAGS) $@ - -$(WORKDIR)/%.or.prg: %.c - $(CL65) -Or $(CC65FLAGS) $< -o $@ - $(SIM65) $(SIM65FLAGS) $@ +$(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option)))) clean: - @$(call DEL,$(TESTS)) + @$(call RMDIR,$(WORKDIR)) @$(call DEL,$(SOURCES:.c=.o)) From ff9b77b6cc96fbdfd06e7f4d6442d4b8c4dd9f86 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 19 Mar 2017 17:57:25 +0100 Subject: [PATCH 0273/2161] Shortened test subdir names. --- test/Makefile | 8 ++++---- test/{assembler => asm}/4510-cpudetect.ref | Bin test/{assembler => asm}/4510-opcodes.ref | Bin test/{assembler => asm}/4510-opcodes.s | 0 test/{assembler => asm}/6502-cpudetect.ref | Bin test/{assembler => asm}/6502-opcodes.ref | Bin test/{assembler => asm}/6502-opcodes.s | 0 test/{assembler => asm}/6502x-cpudetect.ref | Bin test/{assembler => asm}/6502x-opcodes.ref | Bin test/{assembler => asm}/6502x-opcodes.s | 0 test/{assembler => asm}/65816-cpudetect.ref | Bin test/{assembler => asm}/65c02-cpudetect.ref | Bin test/{assembler => asm}/65c02-opcodes.ref | Bin test/{assembler => asm}/65c02-opcodes.s | 0 test/{assembler => asm}/65sc02-cpudetect.ref | Bin test/{assembler => asm}/65sc02-opcodes.ref | Bin test/{assembler => asm}/65sc02-opcodes.s | 0 test/{assembler => asm}/Makefile | 0 test/{assembler => asm}/README | 0 test/{assembler => asm}/cpudetect.s | 0 test/{assembler => asm}/huc6280-cpudetect.ref | Bin test/{assembler => asm}/huc6280-opcodes.ref | Bin test/{assembler => asm}/huc6280-opcodes.s | 0 test/{assembler => asm}/m740-opcodes.s | 0 test/{disassembler => dasm}/4510-disass.s | 0 test/{disassembler => dasm}/Makefile | 0 26 files changed, 4 insertions(+), 4 deletions(-) rename test/{assembler => asm}/4510-cpudetect.ref (100%) rename test/{assembler => asm}/4510-opcodes.ref (100%) rename test/{assembler => asm}/4510-opcodes.s (100%) rename test/{assembler => asm}/6502-cpudetect.ref (100%) rename test/{assembler => asm}/6502-opcodes.ref (100%) rename test/{assembler => asm}/6502-opcodes.s (100%) rename test/{assembler => asm}/6502x-cpudetect.ref (100%) rename test/{assembler => asm}/6502x-opcodes.ref (100%) rename test/{assembler => asm}/6502x-opcodes.s (100%) rename test/{assembler => asm}/65816-cpudetect.ref (100%) rename test/{assembler => asm}/65c02-cpudetect.ref (100%) rename test/{assembler => asm}/65c02-opcodes.ref (100%) rename test/{assembler => asm}/65c02-opcodes.s (100%) rename test/{assembler => asm}/65sc02-cpudetect.ref (100%) rename test/{assembler => asm}/65sc02-opcodes.ref (100%) rename test/{assembler => asm}/65sc02-opcodes.s (100%) rename test/{assembler => asm}/Makefile (100%) rename test/{assembler => asm}/README (100%) rename test/{assembler => asm}/cpudetect.s (100%) rename test/{assembler => asm}/huc6280-cpudetect.ref (100%) rename test/{assembler => asm}/huc6280-opcodes.ref (100%) rename test/{assembler => asm}/huc6280-opcodes.s (100%) rename test/{assembler => asm}/m740-opcodes.s (100%) rename test/{disassembler => dasm}/4510-disass.s (100%) rename test/{disassembler => dasm}/Makefile (100%) diff --git a/test/Makefile b/test/Makefile index a02bd91fb..d0bee8ed8 100644 --- a/test/Makefile +++ b/test/Makefile @@ -25,16 +25,16 @@ all: dotests dotests: mostlyclean continue continue: - @$(MAKE) -C assembler all - @$(MAKE) -C disassembler all + @$(MAKE) -C asm all + @$(MAKE) -C dasm all @$(MAKE) -C val all @$(MAKE) -C ref all @$(MAKE) -C err all @$(MAKE) -C misc all mostlyclean: - @$(MAKE) -C assembler clean - @$(MAKE) -C disassembler clean + @$(MAKE) -C asm clean + @$(MAKE) -C dasm clean @$(MAKE) -C val clean @$(MAKE) -C ref clean @$(MAKE) -C err clean diff --git a/test/assembler/4510-cpudetect.ref b/test/asm/4510-cpudetect.ref similarity index 100% rename from test/assembler/4510-cpudetect.ref rename to test/asm/4510-cpudetect.ref diff --git a/test/assembler/4510-opcodes.ref b/test/asm/4510-opcodes.ref similarity index 100% rename from test/assembler/4510-opcodes.ref rename to test/asm/4510-opcodes.ref diff --git a/test/assembler/4510-opcodes.s b/test/asm/4510-opcodes.s similarity index 100% rename from test/assembler/4510-opcodes.s rename to test/asm/4510-opcodes.s diff --git a/test/assembler/6502-cpudetect.ref b/test/asm/6502-cpudetect.ref similarity index 100% rename from test/assembler/6502-cpudetect.ref rename to test/asm/6502-cpudetect.ref diff --git a/test/assembler/6502-opcodes.ref b/test/asm/6502-opcodes.ref similarity index 100% rename from test/assembler/6502-opcodes.ref rename to test/asm/6502-opcodes.ref diff --git a/test/assembler/6502-opcodes.s b/test/asm/6502-opcodes.s similarity index 100% rename from test/assembler/6502-opcodes.s rename to test/asm/6502-opcodes.s diff --git a/test/assembler/6502x-cpudetect.ref b/test/asm/6502x-cpudetect.ref similarity index 100% rename from test/assembler/6502x-cpudetect.ref rename to test/asm/6502x-cpudetect.ref diff --git a/test/assembler/6502x-opcodes.ref b/test/asm/6502x-opcodes.ref similarity index 100% rename from test/assembler/6502x-opcodes.ref rename to test/asm/6502x-opcodes.ref diff --git a/test/assembler/6502x-opcodes.s b/test/asm/6502x-opcodes.s similarity index 100% rename from test/assembler/6502x-opcodes.s rename to test/asm/6502x-opcodes.s diff --git a/test/assembler/65816-cpudetect.ref b/test/asm/65816-cpudetect.ref similarity index 100% rename from test/assembler/65816-cpudetect.ref rename to test/asm/65816-cpudetect.ref diff --git a/test/assembler/65c02-cpudetect.ref b/test/asm/65c02-cpudetect.ref similarity index 100% rename from test/assembler/65c02-cpudetect.ref rename to test/asm/65c02-cpudetect.ref diff --git a/test/assembler/65c02-opcodes.ref b/test/asm/65c02-opcodes.ref similarity index 100% rename from test/assembler/65c02-opcodes.ref rename to test/asm/65c02-opcodes.ref diff --git a/test/assembler/65c02-opcodes.s b/test/asm/65c02-opcodes.s similarity index 100% rename from test/assembler/65c02-opcodes.s rename to test/asm/65c02-opcodes.s diff --git a/test/assembler/65sc02-cpudetect.ref b/test/asm/65sc02-cpudetect.ref similarity index 100% rename from test/assembler/65sc02-cpudetect.ref rename to test/asm/65sc02-cpudetect.ref diff --git a/test/assembler/65sc02-opcodes.ref b/test/asm/65sc02-opcodes.ref similarity index 100% rename from test/assembler/65sc02-opcodes.ref rename to test/asm/65sc02-opcodes.ref diff --git a/test/assembler/65sc02-opcodes.s b/test/asm/65sc02-opcodes.s similarity index 100% rename from test/assembler/65sc02-opcodes.s rename to test/asm/65sc02-opcodes.s diff --git a/test/assembler/Makefile b/test/asm/Makefile similarity index 100% rename from test/assembler/Makefile rename to test/asm/Makefile diff --git a/test/assembler/README b/test/asm/README similarity index 100% rename from test/assembler/README rename to test/asm/README diff --git a/test/assembler/cpudetect.s b/test/asm/cpudetect.s similarity index 100% rename from test/assembler/cpudetect.s rename to test/asm/cpudetect.s diff --git a/test/assembler/huc6280-cpudetect.ref b/test/asm/huc6280-cpudetect.ref similarity index 100% rename from test/assembler/huc6280-cpudetect.ref rename to test/asm/huc6280-cpudetect.ref diff --git a/test/assembler/huc6280-opcodes.ref b/test/asm/huc6280-opcodes.ref similarity index 100% rename from test/assembler/huc6280-opcodes.ref rename to test/asm/huc6280-opcodes.ref diff --git a/test/assembler/huc6280-opcodes.s b/test/asm/huc6280-opcodes.s similarity index 100% rename from test/assembler/huc6280-opcodes.s rename to test/asm/huc6280-opcodes.s diff --git a/test/assembler/m740-opcodes.s b/test/asm/m740-opcodes.s similarity index 100% rename from test/assembler/m740-opcodes.s rename to test/asm/m740-opcodes.s diff --git a/test/disassembler/4510-disass.s b/test/dasm/4510-disass.s similarity index 100% rename from test/disassembler/4510-disass.s rename to test/dasm/4510-disass.s diff --git a/test/disassembler/Makefile b/test/dasm/Makefile similarity index 100% rename from test/disassembler/Makefile rename to test/dasm/Makefile From 4a6bca0b560ae2c1a7cfe3b14f75ee38094b9b76 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 19 Mar 2017 20:07:19 +0100 Subject: [PATCH 0274/2161] Run test for the 65C02 code generator / runtime too. Now that sim65's 65C02 support is actually functional we can run test for the 65C02 support in the compiler and the runtime. We learn the hard way this is a good idea as there are tests failing when built with optimizations for the 65C02: - val/compare7 - val/compare8 - val/compare9 - val/compare10 - val/or1 --- test/misc/Makefile | 27 ++++++++++++++------------- test/ref/Makefile | 11 ++++++----- test/val/Makefile | 18 +++++++++++++----- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/test/misc/Makefile b/test/misc/Makefile index 6512a9fd9..06ee2a84f 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -20,7 +20,6 @@ else DEL = $(RM) $1 endif -CC65FLAGS = -t sim6502 SIM65FLAGS = -x 200000000 CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) @@ -38,7 +37,8 @@ CFLAGS = -O2 .PHONY: all clean SOURCES := $(wildcard *.c) -TESTS = $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).prg)) +TESTS = $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).6502.prg)) +TESTS += $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).65c02.prg)) all: $(TESTS) @@ -51,34 +51,35 @@ $(DIFF): ../bdiff.c | $(WORKDIR) define PRG_template # should compile, but then hangs in an endless loop -$(WORKDIR)/endless.$1.prg: endless.c | $(WORKDIR) - $(CL65) $(CC65FLAGS) -$1 -o $$@ $$< +$(WORKDIR)/endless.$1.$2.prg: endless.c | $(WORKDIR) + $(CL65) -t sim$2 -$1 -o $$@ $$< $(NOT) $(SIM65) $(SIM65FLAGS) $$@ # these need reference data that can't be generated by a host-compiled program, # in a useful way -$(WORKDIR)/limits.$1.prg: limits.c $(DIFF) - $(CL65) $(CC65FLAGS) -$1 -o $$@ $$< +$(WORKDIR)/limits.$1.$2.prg: limits.c $(DIFF) + $(CL65) -t sim$2 -$1 -o $$@ $$< $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/limits.$1.out $(DIFF) $(WORKDIR)/limits.$1.out limits.ref # the rest are tests that fail currently for one reason or another -$(WORKDIR)/fields.$1.prg: fields.c | $(WORKDIR) +$(WORKDIR)/fields.$1.$2.prg: fields.c | $(WORKDIR) @echo "FIXME: " $$@ "currently will fail." - $(CL65) $(CC65FLAGS) -$1 -o $$@ $$< + $(CL65) -t sim$2 -$1 -o $$@ $$< -$(SIM65) $(SIM65FLAGS) $$@ -$(WORKDIR)/sitest.$1.prg: sitest.c | $(WORKDIR) +$(WORKDIR)/sitest.$1.$2.prg: sitest.c | $(WORKDIR) @echo "FIXME: " $$@ "currently will fail." - -$(CL65) $(CC65FLAGS) -$1 -o $$@ $$< + -$(CL65) -t sim$2 -$1 -o $$@ $$< # -$(SIM65) $(SIM65FLAGS) $$@ -$(WORKDIR)/cc65141011.$1.prg: cc65141011.c | $(WORKDIR) +$(WORKDIR)/cc65141011.$1.$2.prg: cc65141011.c | $(WORKDIR) @echo "FIXME: " $$@ "currently can fail." - $(CL65) $(CC65FLAGS) -$1 -o $$@ $$< + $(CL65) -t sim$2 -$1 -o $$@ $$< -$(SIM65) $(SIM65FLAGS) $$@ endef # PRG_template -$(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option)))) +$(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/ref/Makefile b/test/ref/Makefile index 7bd10cf14..55c859af1 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -19,7 +19,6 @@ else DEL = $(RM) $1 endif -CC65FLAGS = -t sim6502 SIM65FLAGS = -x 200000000 CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) @@ -38,7 +37,8 @@ CFLAGS = -O2 -Wall -W -Wextra -funsigned-char -fwrapv -fno-strict-overflow SOURCES := $(wildcard *.c) REFS = $(SOURCES:%.c=$(WORKDIR)/%.ref) -TESTS = $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).prg)) +TESTS = $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).6502.prg)) +TESTS += $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).65c02.prg)) all: $(REFS) $(TESTS) @@ -70,14 +70,15 @@ $(WORKDIR)/yaccdbg.%.prg: yacc.c define PRG_template -$(WORKDIR)/%.$1.prg: %.c $(WORKDIR)/%.ref $(DIFF) - $(CL65) $$(CC65FLAGS) -$1 -o $$@ $$< +$(WORKDIR)/%.$1.$2.prg: %.c $(WORKDIR)/%.ref $(DIFF) + $(CL65) -t sim$2 $$(CC65FLAGS) -$1 -o $$@ $$< $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/$$*.out $(DIFF) $(WORKDIR)/$$*.out $(WORKDIR)/$$*.ref endef # PRG_template -$(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option)))) +$(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/val/Makefile b/test/val/Makefile index 8a07045ee..425d8ace6 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -14,7 +14,6 @@ else DEL = $(RM) $1 endif -CC65FLAGS = -t sim6502 SIM65FLAGS = -x 200000000 CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) @@ -27,7 +26,15 @@ OPTIONS = g O Os Osi Osir Oi Oir Or .PHONY: all clean SOURCES := $(wildcard *.c) -TESTS = $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).prg)) +TESTS := $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).6502.prg)) +TESTS += $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).65c02.prg)) + +# FIXME: These tests fail when built with optimizations for the 65c02 +TESTS := $(filter-out $(WORKDIR)/compare7.O%.65c02.prg,$(TESTS)) +TESTS := $(filter-out $(WORKDIR)/compare8.O%.65c02.prg,$(TESTS)) +TESTS := $(filter-out $(WORKDIR)/compare9.O%.65c02.prg,$(TESTS)) +TESTS := $(filter-out $(WORKDIR)/compare10.O%.65c02.prg,$(TESTS)) +TESTS := $(filter-out $(WORKDIR)/or1.O%.65c02.prg,$(TESTS)) all: $(TESTS) @@ -46,13 +53,14 @@ $(WORKDIR)/cq84.%.prg: CC65FLAGS += -Wc --all-cdecl define PRG_template -$(WORKDIR)/%.$1.prg: %.c | $(WORKDIR) - $(CL65) $$(CC65FLAGS) -$1 -o $$@ $$< +$(WORKDIR)/%.$1.$2.prg: %.c | $(WORKDIR) + $(CL65) -t sim$2 $$(CC65FLAGS) -$1 -o $$@ $$< $(SIM65) $(SIM65FLAGS) $$@ endef # PRG_template -$(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option)))) +$(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option),6502))) +$(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option),65c02))) clean: @$(call RMDIR,$(WORKDIR)) From 50174d98601856b656ea07e03aaed7b9250752c8 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 19 Mar 2017 20:32:23 +0100 Subject: [PATCH 0275/2161] Hide stdout of tests returning an exit code. Now that we doubled our tests by running them for both 6502 and 65C02 Travis CI complains (again) about a too long build output. So let's reduce it by omitting the (useless) stdout of tests. --- test/val/Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/val/Makefile b/test/val/Makefile index 425d8ace6..2ae3e3b28 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -5,10 +5,14 @@ ifneq ($(shell echo),) endif ifdef CMD_EXE + S = $(subst /,\,/) + NULLDEV = nul: MKDIR = mkdir $(subst /,\,$1) RMDIR = -rmdir /s /q $(subst /,\,$1) DEL = del /f $(subst /,\,$1) else + S = / + NULLDEV = /dev/null MKDIR = mkdir -p $1 RMDIR = $(RM) -r $1 DEL = $(RM) $1 @@ -17,7 +21,7 @@ endif SIM65FLAGS = -x 200000000 CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) -SIM65 := $(if $(wildcard ../../bin/sim65*),../../bin/sim65,sim65) +SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65) WORKDIR = ../../testwrk/val @@ -55,7 +59,7 @@ define PRG_template $(WORKDIR)/%.$1.$2.prg: %.c | $(WORKDIR) $(CL65) -t sim$2 $$(CC65FLAGS) -$1 -o $$@ $$< - $(SIM65) $(SIM65FLAGS) $$@ + $(SIM65) $(SIM65FLAGS) $$@ >$(NULLDEV) endef # PRG_template From 1abfa982902ba04b333e42e415ec540689d5d704 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sun, 19 Mar 2017 20:51:54 +0100 Subject: [PATCH 0276/2161] minor style changes --- libsrc/runtime/along.s | 1 - libsrc/runtime/lsave.s | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/libsrc/runtime/along.s b/libsrc/runtime/along.s index 25eb78c45..bd3462915 100644 --- a/libsrc/runtime/along.s +++ b/libsrc/runtime/along.s @@ -18,4 +18,3 @@ aulong: ldx #0 store: stx sreg stx sreg+1 rts - \ No newline at end of file diff --git a/libsrc/runtime/lsave.s b/libsrc/runtime/lsave.s index 82703073a..d5f4c45b3 100644 --- a/libsrc/runtime/lsave.s +++ b/libsrc/runtime/lsave.s @@ -2,7 +2,7 @@ ; Ullrich von Bassewitz, 08.08.1998 ; Christian Krueger, 11-Mar-2017, optimization ; -; CC65 runtime: save ax into temp storage/restore ax from temp storage +; CC65 runtime: save eax into temp storage/restore eax from temp storage ; .export saveeax, resteax @@ -25,4 +25,3 @@ resteax: ldx regsave+1 lda regsave rts - From 0851e3d6942d8ebd27f13cc41dd631b6b55cf429 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 20 Mar 2017 11:22:04 +0100 Subject: [PATCH 0277/2161] Allow to control test Makefile output via QUIET (like libsrc). --- .travis.yml | 2 +- test/Makefile | 4 ---- test/asm/Makefile | 6 ++++++ test/dasm/Makefile | 5 +++++ test/err/Makefile | 14 ++++++++++++-- test/misc/Makefile | 30 ++++++++++++++++++++---------- test/ref/Makefile | 15 ++++++++++++--- test/val/Makefile | 13 ++++++++++--- 8 files changed, 66 insertions(+), 23 deletions(-) diff --git a/.travis.yml b/.travis.yml index 10ea789cf..fd2672887 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ install: script: - make bin USER_CFLAGS=-Werror - make lib QUIET=1 - - make -C test + - make -C test QUIET=1 - make -C src clean - make bin USER_CFLAGS=-Werror CROSS_COMPILE=i686-w64-mingw32- - make doc zip diff --git a/test/Makefile b/test/Makefile index d0bee8ed8..c85883517 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,9 +1,5 @@ # top-level Makefile for the regression tests -# You can comment this special target when you debug the regression tests. -# Then, make will give you more progress reports. -.SILENT: - ifneq ($(shell echo),) CMD_EXE = 1 endif diff --git a/test/asm/Makefile b/test/asm/Makefile index fb840446c..93210aaee 100644 --- a/test/asm/Makefile +++ b/test/asm/Makefile @@ -16,6 +16,10 @@ else DEL = $(RM) $1 endif +ifdef QUIET + .SILENT: +endif + CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) WORKDIR = ../../testwrk/asm @@ -46,6 +50,7 @@ $(DIFF): ../bdiff.c | $(WORKDIR) define OPCODE_template $(WORKDIR)/$1-opcodes.bin: $1-opcodes.s $(DIFF) + $(if $(QUIET),echo asm/$1-opcodes.bin) $(CL65) --cpu $1 -t none -l $(WORKDIR)/$1-opcodes.lst -o $$@ $$< $(DIFF) $$@ $1-opcodes.ref @@ -56,6 +61,7 @@ $(foreach cpu,$(OPCODE_CPUS),$(eval $(call OPCODE_template,$(cpu)))) define CPUDETECT_template $(WORKDIR)/$1-cpudetect.bin: cpudetect.s $(DIFF) + $(if $(QUIET),echo asm/$1-cpudetect.bin) $(CL65) --cpu $1 -t none -l $(WORKDIR)/$1-cpudetect.lst -o $$@ $$< $(DIFF) $$@ $1-cpudetect.ref diff --git a/test/dasm/Makefile b/test/dasm/Makefile index f8942ef73..d70711491 100644 --- a/test/dasm/Makefile +++ b/test/dasm/Makefile @@ -16,6 +16,10 @@ else DEL = $(RM) $1 endif +ifdef QUIET + .SILENT: +endif + CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) DA65 := $(if $(wildcard ../../bin/da65*),../../bin/da65,da65) @@ -52,6 +56,7 @@ $(WORKDIR)/$1-reass.s: $(WORKDIR)/$1-disass.bin $(DA65) --cpu $1 $(START) -o $$@ $$< $(WORKDIR)/$1-reass.bin: $(WORKDIR)/$1-reass.s $(DIFF) + $(if $(QUIET),echo dasm/$1-reass.bin) $(CL65) --cpu $1 -t none $(START) -o $$@ $$< $(DIFF) $$@ $(WORKDIR)/$1-disass.bin diff --git a/test/err/Makefile b/test/err/Makefile index 2bcc1d264..4b05ca5db 100644 --- a/test/err/Makefile +++ b/test/err/Makefile @@ -5,16 +5,25 @@ ifneq ($(shell echo),) 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 -CC65 := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65) +ifdef QUIET + .SILENT: + NULLERR = 2>$(NULLDEV) +endif + +CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65) WORKDIR = ../../testwrk/err @@ -26,7 +35,8 @@ TESTS = $(patsubst %.c,$(WORKDIR)/%.s,$(SOURCES)) all: $(TESTS) $(WORKDIR)/%.s: %.c - $(NOT) $(CC65) -o $@ $< + $(if $(QUIET),echo err/$*.s) + $(NOT) $(CC65) -o $@ $< $(NULLERR) clean: @$(call RMDIR,$(WORKDIR)) diff --git a/test/misc/Makefile b/test/misc/Makefile index 06ee2a84f..39a9a3868 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -8,6 +8,7 @@ ifdef CMD_EXE S = $(subst /,\,/) NOT = - # Hack EXE = .exe + NULLDEV = nul: MKDIR = mkdir $(subst /,\,$1) RMDIR = -rmdir /s /q $(subst /,\,$1) DEL = del /f $(subst /,\,$1) @@ -15,14 +16,21 @@ else S = / NOT = ! EXE = + NULLDEV = /dev/null MKDIR = mkdir -p $1 RMDIR = $(RM) -r $1 DEL = $(RM) $1 endif +ifdef QUIET + .SILENT: + NULLOUT = >$(NULLDEV) + NULLERR = 2>$(NULLDEV) +endif + SIM65FLAGS = -x 200000000 -CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) +CL65 := $(if $(wildcard ../../bin/cl65*),..$S..$Sbin$Scl65,cl65) SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65) WORKDIR = ..$S..$Stestwrk$Smisc @@ -52,29 +60,31 @@ define PRG_template # should compile, but then hangs in an endless loop $(WORKDIR)/endless.$1.$2.prg: endless.c | $(WORKDIR) - $(CL65) -t sim$2 -$1 -o $$@ $$< - $(NOT) $(SIM65) $(SIM65FLAGS) $$@ + $(if $(QUIET),echo misc/endless.$1.$2.prg) + $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(NOT) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) # these need reference data that can't be generated by a host-compiled program, # in a useful way $(WORKDIR)/limits.$1.$2.prg: limits.c $(DIFF) - $(CL65) -t sim$2 -$1 -o $$@ $$< + $(if $(QUIET),echo misc/limits.$1.$2.prg) + $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/limits.$1.out $(DIFF) $(WORKDIR)/limits.$1.out limits.ref # the rest are tests that fail currently for one reason or another $(WORKDIR)/fields.$1.$2.prg: fields.c | $(WORKDIR) @echo "FIXME: " $$@ "currently will fail." - $(CL65) -t sim$2 -$1 -o $$@ $$< - -$(SIM65) $(SIM65FLAGS) $$@ + $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + -$(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(WORKDIR)/sitest.$1.$2.prg: sitest.c | $(WORKDIR) @echo "FIXME: " $$@ "currently will fail." - -$(CL65) -t sim$2 -$1 -o $$@ $$< -# -$(SIM65) $(SIM65FLAGS) $$@ + -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) +# -$(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(WORKDIR)/cc65141011.$1.$2.prg: cc65141011.c | $(WORKDIR) @echo "FIXME: " $$@ "currently can fail." - $(CL65) -t sim$2 -$1 -o $$@ $$< - -$(SIM65) $(SIM65FLAGS) $$@ + $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + -$(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) endef # PRG_template diff --git a/test/ref/Makefile b/test/ref/Makefile index 55c859af1..c986513b8 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -8,20 +8,27 @@ endif ifdef CMD_EXE S = $(subst /,\,/) EXE = .exe + NULLDEV = nul: MKDIR = mkdir $(subst /,\,$1) RMDIR = -rmdir /s /q $(subst /,\,$1) DEL = del /f $(subst /,\,$1) else S = / EXE = + NULLDEV = /dev/null MKDIR = mkdir -p $1 RMDIR = $(RM) -r $1 DEL = $(RM) $1 endif +ifdef QUIET + .SILENT: + NULLERR = 2>$(NULLDEV) +endif + SIM65FLAGS = -x 200000000 -CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) +CL65 := $(if $(wildcard ../../bin/cl65*),..$S..$Sbin$Scl65,cl65) SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65) WORKDIR = ..$S..$Stestwrk$Sref @@ -46,7 +53,8 @@ $(WORKDIR): $(call MKDIR,$(WORKDIR)) $(WORKDIR)/%.ref: %.c | $(WORKDIR) - $(CC) $(CFLAGS) -o $(WORKDIR)/$*.host $< + $(if $(QUIET),echo ref/$*.host) + $(CC) $(CFLAGS) -o $(WORKDIR)/$*.host $< $(NULLERR) $(WORKDIR)$S$*.host > $@ $(DIFF): ../bdiff.c | $(WORKDIR) @@ -71,7 +79,8 @@ $(WORKDIR)/yaccdbg.%.prg: yacc.c define PRG_template $(WORKDIR)/%.$1.$2.prg: %.c $(WORKDIR)/%.ref $(DIFF) - $(CL65) -t sim$2 $$(CC65FLAGS) -$1 -o $$@ $$< + $(if $(QUIET),echo ref/$$*.$1.$2.prg) + $(CL65) -t sim$2 $$(CC65FLAGS) -$1 -o $$@ $$< $(NULLERR) $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/$$*.out $(DIFF) $(WORKDIR)/$$*.out $(WORKDIR)/$$*.ref diff --git a/test/val/Makefile b/test/val/Makefile index 2ae3e3b28..1981b36fe 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -18,9 +18,15 @@ else DEL = $(RM) $1 endif +ifdef QUIET + .SILENT: + NULLOUT = >$(NULLDEV) + NULLERR = 2>$(NULLDEV) +endif + SIM65FLAGS = -x 200000000 -CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) +CL65 := $(if $(wildcard ../../bin/cl65*),..$S..$Sbin$Scl65,cl65) SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65) WORKDIR = ../../testwrk/val @@ -58,8 +64,9 @@ $(WORKDIR)/cq84.%.prg: CC65FLAGS += -Wc --all-cdecl define PRG_template $(WORKDIR)/%.$1.$2.prg: %.c | $(WORKDIR) - $(CL65) -t sim$2 $$(CC65FLAGS) -$1 -o $$@ $$< - $(SIM65) $(SIM65FLAGS) $$@ >$(NULLDEV) + $(if $(QUIET),echo val/$$*.$1.$2.prg) + $(CL65) -t sim$2 $$(CC65FLAGS) -$1 -o $$@ $$< $(NULLERR) + $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) endef # PRG_template From cc82cd99923caeb3353288789208eb079c73e720 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Mon, 20 Mar 2017 21:53:07 +0100 Subject: [PATCH 0278/2161] Fixed addressing error for TSB/TSR and enabled tests again. --- src/sim65/6502.c | 4 ++-- test/val/Makefile | 7 ------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index 0320dd895..b870dd76d 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -470,7 +470,7 @@ static void OPC_65SC02_0C (void) unsigned Addr; unsigned char Val; Cycles = 6; - Addr = MemReadByte (Regs.PC+1); + Addr = MemReadWord (Regs.PC+1); Val = MemReadByte (Addr); SET_ZF ((Val & Regs.AC) == 0); MemWriteByte (Addr, (unsigned char) (Val | Regs.AC)); @@ -604,7 +604,7 @@ static void OPC_65SC02_1C (void) unsigned Addr; unsigned char Val; Cycles = 6; - Addr = MemReadByte (Regs.PC+1); + Addr = MemReadWord (Regs.PC+1); Val = MemReadByte (Addr); SET_ZF ((Val & Regs.AC) == 0); MemWriteByte (Addr, (unsigned char) (Val & ~Regs.AC)); diff --git a/test/val/Makefile b/test/val/Makefile index 1981b36fe..95522a930 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -39,13 +39,6 @@ SOURCES := $(wildcard *.c) TESTS := $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).6502.prg)) TESTS += $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).65c02.prg)) -# FIXME: These tests fail when built with optimizations for the 65c02 -TESTS := $(filter-out $(WORKDIR)/compare7.O%.65c02.prg,$(TESTS)) -TESTS := $(filter-out $(WORKDIR)/compare8.O%.65c02.prg,$(TESTS)) -TESTS := $(filter-out $(WORKDIR)/compare9.O%.65c02.prg,$(TESTS)) -TESTS := $(filter-out $(WORKDIR)/compare10.O%.65c02.prg,$(TESTS)) -TESTS := $(filter-out $(WORKDIR)/or1.O%.65c02.prg,$(TESTS)) - all: $(TESTS) $(WORKDIR): From 669113b59521c75434380d974b900550f43b0971 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 21 Mar 2017 20:45:36 +0100 Subject: [PATCH 0279/2161] Added missing line continuation. Fixes https://github.com/cc65/cc65/issues/408 --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index edb6f5aa8..f4f29b949 100644 --- a/src/Makefile +++ b/src/Makefile @@ -65,7 +65,7 @@ endif CFLAGS += -MMD -MP -O -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) + -DLD65_LIB=$(LD65_LIB) -DLD65_OBJ=$(LD65_OBJ) -DLD65_CFG=$(LD65_CFG) \ -DGIT_SHA=$(GIT_SHA) LDLIBS += -lm From 5b3611265bd97f9263dad6c931a2ae58ed06f42f Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 21 Mar 2017 20:54:55 +0100 Subject: [PATCH 0280/2161] Revert to recursively expanded var. https://github.com/cc65/cc65/commit/4a6bca0b560ae2c1a7cfe3b14f75ee38094b9b76 needed to move to a simply expanded variable but https://github.com/cc65/cc65/commit/cc82cd99923caeb3353288789208eb079c73e720 made that unnecessary again. --- test/val/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/val/Makefile b/test/val/Makefile index 95522a930..c7539c81b 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -36,7 +36,7 @@ OPTIONS = g O Os Osi Osir Oi Oir Or .PHONY: all clean SOURCES := $(wildcard *.c) -TESTS := $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).6502.prg)) +TESTS = $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).6502.prg)) TESTS += $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).65c02.prg)) all: $(TESTS) From 8e35a82c91c002f62befbfd29e637d9b1d8b0b0f Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Tue, 21 Mar 2017 22:35:25 +0100 Subject: [PATCH 0281/2161] Fix regression of #pragma bss-name Closes #409 --- cfg/sim6502.cfg | 2 +- cfg/sim65c02.cfg | 2 +- src/cc65/compile.c | 28 +++++++++++++++++++--------- src/cc65/symentry.c | 1 + src/cc65/symentry.h | 2 ++ test/err/bss-name-conflict.c | 20 ++++++++++++++++++++ test/val/bss-name-decl.c | 22 ++++++++++++++++++++++ test/val/bss-name.c | 21 +++++++++++++++++++++ 8 files changed, 87 insertions(+), 11 deletions(-) create mode 100644 test/err/bss-name-conflict.c create mode 100644 test/val/bss-name-decl.c create mode 100644 test/val/bss-name.c diff --git a/cfg/sim6502.cfg b/cfg/sim6502.cfg index b4f7738f5..530787489 100644 --- a/cfg/sim6502.cfg +++ b/cfg/sim6502.cfg @@ -3,7 +3,7 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack } MEMORY { - ZP: file = "", start = $0000, size = $001A; + ZP: file = "", start = $0000, size = $001B; HEADER: file = %O, start = $0000, size = $0001; MAIN: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; } diff --git a/cfg/sim65c02.cfg b/cfg/sim65c02.cfg index b4f7738f5..530787489 100644 --- a/cfg/sim65c02.cfg +++ b/cfg/sim65c02.cfg @@ -3,7 +3,7 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack } MEMORY { - ZP: file = "", start = $0000, size = $001A; + ZP: file = "", start = $0000, size = $001B; HEADER: file = %O, start = $0000, size = $0001; MAIN: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; } diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 48a5c29d3..4425b6aad 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -242,16 +242,24 @@ static void Parse (void) Error ("Variable `%s' has unknown size", Decl.Ident); } Entry->Flags &= ~(SC_STORAGE | SC_DEF); + } else { + /* A global (including static) uninitialized variable + ** is only a tentative definition. For example, this is valid: + ** int i; + ** int i; + ** static int j; + ** static int j = 42; + ** Code for these will be generated in FinishCompile. + ** For now, just save the BSS segment name + ** (can be set with #pragma bss-name) + */ + const char* bssName = GetSegName (SEG_BSS); + if (Entry->V.BssName && strcmp (Entry->V.BssName, bssName) != 0) { + Error ("Global variable `%s' has already been defined in `%s' segment", + Entry->Name, Entry->V.BssName); + } + Entry->V.BssName = xstrdup (bssName); } - - /* A global (including static) uninitialized variable - ** is only a tentative definition. For example, this is valid: - ** int i; - ** int i; - ** static int j; - ** static int j = 42; - ** Code for these will be generated in FinishCompile. - */ } } @@ -418,6 +426,8 @@ void FinishCompile (void) } else if ((Entry->Flags & (SC_STORAGE | SC_DEF | SC_STATIC)) == (SC_STORAGE | SC_STATIC)) { /* Tentative definition of uninitialized global variable */ g_usebss (); + SetSegName (SEG_BSS, Entry->V.BssName); + g_segname (SEG_BSS); /* TODO: skip if same as before */ g_defgloblabel (Entry->Name); g_res (SizeOf (Entry->Type)); /* Mark as defined, so that it will be exported not imported */ diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index 980ee27f2..d6e68d1bb 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -71,6 +71,7 @@ SymEntry* NewSymEntry (const char* Name, unsigned Flags) E->Type = 0; E->Attr = 0; E->AsmName = 0; + E->V.BssName = 0; memcpy (E->Name, Name, Len+1); /* Return the new entry */ diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 4fa84255b..ff136702f 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -153,6 +153,8 @@ struct SymEntry { struct LiteralPool* LitPool; /* Literal pool for this function */ } F; + /* Segment name for tentantive global definitions */ + const char* BssName; } V; char Name[1]; /* Name, dynamically allocated */ }; diff --git a/test/err/bss-name-conflict.c b/test/err/bss-name-conflict.c new file mode 100644 index 000000000..1d6cd5066 --- /dev/null +++ b/test/err/bss-name-conflict.c @@ -0,0 +1,20 @@ +/* + !!DESCRIPTION!! conflicting bss-name pragmas + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Piotr Fusik +*/ + +/* + see: https://github.com/cc65/cc65/issues/409 +*/ + +char oam_off; +#pragma bss-name (push,"ZEROPAGE") +char oam_off; +#pragma bss-name (pop) + +int main(void) +{ + return 0; +} diff --git a/test/val/bss-name-decl.c b/test/val/bss-name-decl.c new file mode 100644 index 000000000..9a535844e --- /dev/null +++ b/test/val/bss-name-decl.c @@ -0,0 +1,22 @@ +/* + !!DESCRIPTION!! bss-name pragma not affecting declarations + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Piotr Fusik +*/ + +/* + see: https://github.com/cc65/cc65/issues/409 +*/ + +#pragma bss-name (push,"ZEROPAGE") + +char n; /* only a declaration because followed by definition */ +char n = 1; /* not BSS */ + +#pragma bss-name (pop) + +int main(void) +{ + return (unsigned) &n >= 0x100 ? 0 : 1; +} diff --git a/test/val/bss-name.c b/test/val/bss-name.c new file mode 100644 index 000000000..f0ad7111e --- /dev/null +++ b/test/val/bss-name.c @@ -0,0 +1,21 @@ +/* + !!DESCRIPTION!! bss-name pragma + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Piotr Fusik +*/ + +/* + see: https://github.com/cc65/cc65/issues/409 +*/ + +#pragma bss-name (push,"ZEROPAGE") + +char zp_var; + +#pragma bss-name (pop) + +int main(void) +{ + return (unsigned) &zp_var < 0x100 ? 0 : 1; +} From 01f5baf03defacf5b4bed9536883559b7aeca8b6 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 21 Mar 2017 21:23:48 -0400 Subject: [PATCH 0282/2161] Fixed SGML typo. --- doc/cc65.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 6a08cc3c3..2a0fa0260 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -4,7 +4,7 @@ <title>cc65 Users Guide <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:gregdk@users.sf.net" name="Greg King"> -<date>2017-02-27 +<date>2017-03-21 <abstract> cc65 is a C compiler for 6502 targets. It supports several 6502 based home @@ -1276,7 +1276,7 @@ that function). As a shortcut, you can put the <tt/volatile/ qualifier in your <tt/asm/ statements. It will disable optimization for the functions in which those <tt/asm volatile/ statements sit. The effect is the same as though you put -</#pragma optimize(push, off)/ above those functions, and </#pragma +<tt/#pragma optimize(push, off)/ above those functions, and <tt/#pragma optimize(pop)/ below those functions. The string literal may contain format specifiers from the following list. For From 170d96898f3d744f131aa9c3a3cff8cf0463078c Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Thu, 30 Mar 2017 12:17:29 +0200 Subject: [PATCH 0283/2161] Fixed SED --- src/sim65/6502.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index 0320dd895..87cef2db6 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -39,6 +39,8 @@ 6502) * one cycle win for fetch-modify-write instructions ignored (e.g. ROL abs,x takes only 6 cycles if no page break occurs) + * BRK, IRQ, NMI and RESET are not different from 6502 which they are in + reality (e.g. D-flag handling) */ #include "memory.h" @@ -2581,7 +2583,9 @@ static void OPC_6502_F6 (void) static void OPC_6502_F8 (void) /* Opcode $F8: SED */ { + Cycles = 2; SET_DF (1); + Regs.PC += 1; } From 02daf9f8b5c1ae2267561ee05ce67b2d0393c12d Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 3 Apr 2017 23:20:26 +0200 Subject: [PATCH 0284/2161] So far the built-in inlining of several known standard function was always (!) enabled and the option -Os enabled additional, potentially unsafe inlining of some of those functions. There were two aspects of this behavior that were considered undesirable: - Although the safe inlining is in general desirable it should only be enabled if asked for it - like any other optimization. - The option name -Os implies that it is a safe option, the potentially unsafe inlining should have a more explicit name. So now: - The option -Os enables the safe inlining. - The new option --eagerly-inline-funcs enables the potentially unsafe inlining (including the safe inlining). Additionally was added: - The option --inline-stdfuncs that does like -Os enable the safe inlining but doesn't enable optimizations. - The pragma inline-stdfuncs that works identical to --inline-stdfuncs. - The pragma allow-eager-inline that enables the potentially unsafe inlining but doesn't include the safe inlining. That means that by itself it only marks code as safe for potentially unsafe inlining but doesn't actually enable any inlining. --- doc/cc65.sgml | 294 +++++---- doc/cl65.sgml | 4 +- include/ctype.h | 4 +- src/cc65/compile.c | 19 +- src/cc65/global.c | 3 +- src/cc65/global.h | 3 +- src/cc65/main.c | 91 +-- src/cc65/pragma.c | 62 +- src/cc65/stdfunc.c | 1421 +++++++++++++++++++++++--------------------- 9 files changed, 1033 insertions(+), 868 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 2a0fa0260..9322a2d44 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -58,7 +58,7 @@ Short options: -O Optimize code -Oi Optimize code, inline more code -Or Enable register variables - -Os Inline some known functions + -Os Inline some standard functions -T Include source as comment -V Print the compiler version number -W warning[,...] Suppress warnings @@ -88,9 +88,11 @@ Long options: --debug-opt name Debug optimization steps --dep-target target Use this dependency target --disable-opt name Disable an optimization step + --eagerly-inline-funcs Eagerly inline some known functions --enable-opt name Enable an optimization step --help Help (this text) --include-dir dir Set an include directory search path + --inline-stdfuncs Inline some standard functions --list-opt-steps List all optimizer steps and exit --list-warnings List available warning types for -W --local-strings Emit string literals immediately @@ -219,11 +221,53 @@ Here is a description of all the command line options: symbols in a special section in the object file. + <label id="option-eagerly-inline-funcs"> + <tag><tt>--eagerly-inline-funcs</tt></tag> + + Have the compiler eagerly inline these functions from the C library: + <itemize> + <item><tt/memcpy()/ + <item><tt/memset()/ + <item><tt/strcmp()/ + <item><tt/strcpy()/ + <item><tt/strlen()/ + <item>most of the functions declared in <tt/<ctype.h>/ + </itemize> + + Note: This has two consequences: + <itemize> + <item>You may not use names of standard C functions for your own functions. + If you do that, your program is not standard-compliant anyway; but, + using <tt/--eagerly-inline-funcs/ actually will break things. + <p> + <item>The inlined string and memory functions will not handle strings or + memory areas larger than 255 bytes. Similarly, the inlined <tt/is..()/ + functions will not work with values outside the char. range (such as + <tt/EOF/). + <p> + </itemize> + + <tt/--eagerly-inline-funcs/ implies the <tt/<ref id="option-inline-stdfuncs" + name="--inline-stdfuncs"/ command line option. + + See also <tt/<ref id="pragma-allow-eager-inline" name="#pragma allow-eager-inline">/. + + <tag><tt>-h, --help</tt></tag> Print the short option summary shown above. + <label id="option-inline-stdfuncs"> + <tag><tt>--inline-stdfuncs</tt></tag> + + Allow the compiler to inline some standard functions from the C library like + strlen. This will not only remove the overhead for a function call, but will + make the code visible for the optimizer. See also the <tt/<ref id="option-O" + name="-Os"/ command line option and <tt/<ref id="pragma-inline-stdfuncs" + name="#pragma inline-stdfuncs">/. + + <label id="option-list-warnings"> <tag><tt>--list-warnings</tt></tag> @@ -392,22 +436,22 @@ Here is a description of all the command line options: using <tscreen><verb> - void f (void) - { - unsigned a = 1; - ... - } + void f (void) + { + unsigned a = 1; + ... + } </verb></tscreen> the variable <tt/a/ will always have the value <tt/1/ when entering the function and using <tt/-Cl/, while in <tscreen><verb> - void f (void) - { - static unsigned a = 1; - .... - } + void f (void) + { + static unsigned a = 1; + .... + } </verb></tscreen> the variable <tt/a/ will have the value <tt/1/ only the first time that the @@ -444,23 +488,13 @@ Here is a description of all the command line options: name="--register-vars">/ command line option, and the <ref id="register-vars" name="discussion of register variables"> below. - Using <tt/-Os/ will force the compiler to inline some known functions from - the C library like strlen. Note: This has two consequences: - <p> - <itemize> - <item>You may not use names of standard C functions in your own code. If you - do that, your program is not standard compliant anyway, but using - <tt/-Os/ will actually break things. - <p> - <item>The inlined string and memory functions will not handle strings or - memory areas larger than 255 bytes. Similarly, the inlined <tt/is..()/ - functions will not work with values outside the char. range (such as - <tt/EOF/). - <p> - </itemize> - <p> + Using <tt/-Os/ will allow the compiler to inline some standard functions + from the C library like strlen. This will not only remove the overhead + for a function call, but will make the code visible for the optimizer. + See also <tt/<ref id="option-inline-stdfuncs" name="--inline-stdfuncs"/. + It is possible to concatenate the modifiers for <tt/-O/. For example, to - enable register variables and inlining of known functions, you may use + enable register variables and inlining of standard functions, you may use <tt/-Ors/. @@ -518,6 +552,7 @@ Here is a description of all the command line options: </descrip><p> + <sect>Input and output<p> The compiler will accept one C file per invocation and create a file with @@ -556,21 +591,21 @@ and the one defined by the ISO standard: <itemize> -<item> The datatypes "float" and "double" are not available. - <p> -<item> C Functions may not return structs (or unions), and structs may not +<item> The datatypes "float" and "double" are not available. + <p> +<item> C Functions may not return structs (or unions), and structs may not be passed as parameters by value. However, struct assignment *is* - possible. - <p> -<item> Most of the C library is available with only the fastcall calling - convention (<ref id="extension-fastcall" name="see below">). It means - that you must not mix pointers to those functions with pointers to - user-written, cdecl functions (the calling conventions are incompatible). - <p> -<item> The <tt/volatile/ keyword has almost no effect. That is not as bad + possible. + <p> +<item> Most of the C library is available with only the fastcall calling + convention (<ref id="extension-fastcall" name="see below">). It means + that you must not mix pointers to those functions with pointers to + user-written, cdecl functions (the calling conventions are incompatible). + <p> +<item> The <tt/volatile/ keyword has almost no effect. That is not as bad as it sounds, since the 6502 has so few registers that it isn't possible to keep values in registers anyway. - <p> + <p> </itemize> There may be some more minor differences I'm currently not aware of. The @@ -585,49 +620,48 @@ This cc65 version has some extensions to the ISO C standard. <itemize> -<item> The compiler allows to insert assembler statements into the output - file. The syntax is +<item> The compiler allows to insert assembler statements into the output + file. The syntax is - <tscreen><verb> - asm [optional volatile] (<string literal>[, optional parameters]) ; - </verb></tscreen> - or - <tscreen><verb> + <tscreen><verb> + asm [optional volatile] (<string literal>[, optional parameters]) ; + </verb></tscreen> + or + <tscreen><verb> __asm__ [optional volatile] (<string literal>[, optional parameters]) ; - </verb></tscreen> + </verb></tscreen> - The first form is in the user namespace; and, is disabled if the <tt/-A/ - switch is given. + The first form is in the user namespace; and, is disabled if the <tt/-A/ + switch is given. - There is a whole section covering inline assembler statements, - <ref id="inline-asm" name="see there">. - <p> + There is a whole section covering inline assembler statements, + <ref id="inline-asm" name="see there">. + <p> <label id="extension-fastcall"> -<item> The normal calling convention -- for non-variadic functions -- is - named "fastcall". The syntax for a function declaration that - <em/explicitly/ uses fastcall is +<item> The normal calling convention -- for non-variadic functions -- is + named "fastcall". The syntax for a function declaration that + <em/explicitly/ uses fastcall is - <tscreen><verb> - <return type> fastcall <function name> (<parameter list>) - </verb></tscreen> - or - <tscreen><verb> - <return type> __fastcall__ <function name> (<parameter list>) - </verb></tscreen> - An example is - <tscreen><verb> - void __fastcall__ f (unsigned char c) - </verb></tscreen> - The first form of the fastcall keyword is in the user namespace and can - therefore be disabled with the <tt><ref id="option--standard" + <tscreen><verb> + <return type> fastcall <function name> (<parameter list>) + </verb></tscreen> + or + <tscreen><verb> + <return type> __fastcall__ <function name> (<parameter list>) + </verb></tscreen> + An example is + <tscreen><verb> + void __fastcall__ f (unsigned char c) + </verb></tscreen> + The first form of the fastcall keyword is in the user namespace and can + therefore be disabled with the <tt><ref id="option--standard" name="--standard"></tt> command line option. - For functions that are <tt/fastcall/, the rightmost parameter is not - pushed on the stack but left in the primary register when the function - is called. That significantly reduces the cost of calling those functions. - <newline><newline> - <p> + For functions that are <tt/fastcall/, the rightmost parameter is not + pushed on the stack but left in the primary register when the function + is called. That significantly reduces the cost of calling those functions. + <p> <item> There is another calling convention named "cdecl". Variadic functions (their prototypes have an ellipsis [<tt/.../]) always use that @@ -652,40 +686,40 @@ This cc65 version has some extensions to the ISO C standard. For functions that are <tt/cdecl/, the rightmost parameter is pushed onto the stack before the function is called. That increases the cost of calling those functions, especially when they are called from many - places.<newline><newline> + places. <p> -<item> There are two pseudo variables named <tt/__AX__/ and <tt/__EAX__/. - Both refer to the primary register that is used by the compiler to - evaluate expressions or return function results. <tt/__AX__/ is of - type <tt/unsigned int/ and <tt/__EAX__/ of type <tt/long unsigned int/ - respectively. The pseudo variables may be used as lvalue and rvalue as - every other variable. They are most useful together with short - sequences of assembler code. For example, the macro +<item> There are two pseudo variables named <tt/__AX__/ and <tt/__EAX__/. + Both refer to the primary register that is used by the compiler to + evaluate expressions or return function results. <tt/__AX__/ is of + type <tt/unsigned int/ and <tt/__EAX__/ of type <tt/long unsigned int/ + respectively. The pseudo variables may be used as lvalue and rvalue as + every other variable. They are most useful together with short + sequences of assembler code. For example, the macro - <tscreen><verb> - #define hi(x) \ + <tscreen><verb> + #define hi(x) \ (__AX__ = (x), \ asm ("txa"), \ asm ("ldx #$00"), \ __AX__) - </verb></tscreen> + </verb></tscreen> - will give the high byte of any unsigned value. - <p> + will give the high byte of any unsigned value. + <p> -<item> Inside a function, the identifier <tt/__func__/ gives the name of the - current function as a string. Outside of functions, <tt/__func__/ is - undefined. - Example: +<item> Inside a function, the identifier <tt/__func__/ gives the name of the + current function as a string. Outside of functions, <tt/__func__/ is + undefined. + Example: - <tscreen><verb> - #define PRINT_DEBUG(s) printf ("%s: %s\n", __func__, s); - </verb></tscreen> + <tscreen><verb> + #define PRINT_DEBUG(s) printf ("%s: %s\n", __func__, s); + </verb></tscreen> - The macro will print the name of the current function plus a given - string. - <p> + The macro will print the name of the current function plus a given + string. + <p> <item> cc65 allows the initialization of <tt/void/ variables. This may be used to create arbitrary structures that are more compatible with @@ -825,6 +859,11 @@ The compiler defines several macros at startup: This macro expands to the date of translation of the preprocessing translation unit in the form "Mmm dd yyyy". + <tag><tt>__EAGERLY_INLINE_FUNCS__</tt></tag> + + Is defined if the compiler was called with the <tt/<ref id="option-eagerly-inline-funcs" + name="--eagerly-inline-funcs"/ command line option. + <tag><tt>__FILE__</tt></tag> This macro expands to a string containing the name of the C source file. @@ -912,6 +951,7 @@ The compiler defines several macros at startup: </descrip> + <sect>#pragmas<label id="pragmas"><p> The compiler understands some pragmas that may be used to change code @@ -920,6 +960,19 @@ 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/. + +<sect1><tt>#pragma allow-eager-inline ([push,] on|off)</tt><label id="pragma-allow-eager-inline"><p> + + Allow eager inlining of known functions. If the argument is "off", eager + inlining is disabled, otherwise it is enabled. Please note that (in contrast + to the <tt/<ref id="option-eagerly-inline-funcs" name="--eagerly-inline-funcs"/ + command line option) this pragma does not imply the <tt/<ref id="option-inline-stdfuncs" + name="--inline-stdfuncs"/ command line option. Rather it marks code to be safe for + eager inlining of known functions if inlining of standard functions is enabled. + + The <tt/#pragma/ understands the push and pop parameters as explained above. + + <sect1><tt>#pragma bss-name ([push,] <name>)</tt><label id="pragma-bss-name"><p> This pragma changes the name used for the BSS segment (the BSS segment @@ -938,7 +991,7 @@ parameter with the <tt/#pragma/. Example: <tscreen><verb> - #pragma bss-name ("MyBSS") + #pragma bss-name ("MyBSS") </verb></tscreen> @@ -993,6 +1046,7 @@ parameter with the <tt/#pragma/. The <tt/#pragma/ understands the push and pop parameters as explained above. + <sect1><tt>#pragma code-name ([push,] <name>)</tt><label id="pragma-code-name"><p> This pragma changes the name used for the CODE segment (the CODE segment @@ -1007,7 +1061,7 @@ parameter with the <tt/#pragma/. Example: <tscreen><verb> - #pragma code-name ("MyCODE") + #pragma code-name ("MyCODE") </verb></tscreen> @@ -1035,10 +1089,21 @@ parameter with the <tt/#pragma/. Example: <tscreen><verb> - #pragma data-name ("MyDATA") + #pragma data-name ("MyDATA") </verb></tscreen> +<sect1><tt>#pragma inline-stdfuncs ([push,] on|off)</tt><label id="pragma-inline-stdfuncs"><p> + + Allow the compiler to inline some standard functions from the C library like + strlen. If the argument is "off", inlining is disabled, otherwise it is enabled. + + See also the the <tt/<ref id="option-inline-stdfuncs" name="--inline-stdfuncs"/ + command line option. + + The <tt/#pragma/ understands the push and pop parameters as explained above. + + <sect1><tt>#pragma local-strings ([push,] on|off)</tt><label id="pragma-local-strings"><p> When "on", emit string literals to the data segment when they're encountered @@ -1083,7 +1148,7 @@ parameter with the <tt/#pragma/. Example: <tscreen><verb> - #pragma rodata-name ("MyRODATA") + #pragma rodata-name ("MyRODATA") </verb></tscreen> @@ -1105,9 +1170,9 @@ parameter with the <tt/#pragma/. Example: <tscreen><verb> - #pragma regvaraddr(on) /* Allow taking the address - * of register variables - */ + #pragma regvaraddr(on) /* Allow taking the address + * of register variables + */ </verb></tscreen> @@ -1154,7 +1219,7 @@ parameter with the <tt/#pragma/. Example: <tscreen><verb> /* Don't warn about the unused parameter in function func */ - #pragma warn (unused-param, push, off) + #pragma warn (unused-param, push, off) static int func (int unused) { return 0; @@ -1187,13 +1252,12 @@ parameter with the <tt/#pragma/. Example: <tscreen><verb> - extern int foo; - #pragma zpsym ("foo"); /* foo is in the zeropage */ + extern int foo; + #pragma zpsym ("foo"); /* foo is in the zeropage */ </verb></tscreen> - <sect>Register variables<label id="register-vars"><p> The runtime for all supported platforms has 6 bytes of zero page space @@ -1450,14 +1514,14 @@ 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. +<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/cl65.sgml b/doc/cl65.sgml index eef6a12a3..ffeba2321 100644 --- a/doc/cl65.sgml +++ b/doc/cl65.sgml @@ -54,9 +54,9 @@ Short options: -L path Specify a library search path -Ln name Create a VICE label file -O Optimize code - -Oi Optimize code, inline functions + -Oi Optimize code, inline more code -Or Optimize code, honour the register keyword - -Os Optimize code, inline known C funtions + -Os Optimize code, inline standard funtions -S Compile but don't assemble and link -T Include source as comment -V Print the version number diff --git a/include/ctype.h b/include/ctype.h index b440bfb70..17cbafe9f 100644 --- a/include/ctype.h +++ b/include/ctype.h @@ -89,9 +89,9 @@ unsigned char __fastcall__ toascii (unsigned char c); ** #undef'ing the macroes. ** Please note that the following macroes do NOT handle EOF correctly, as ** stated in the manual. If you need correct behaviour for EOF, don't -** use -Os, or #undefine the following macroes. +** use --eagerly-inline-funcs, or #undefine the following macroes. */ -#ifdef __OPT_s__ +#ifdef __EAGERLY_INLINE_FUNCS__ #define isalnum(c) (__AX__ = (c), \ __asm__ ("tay"), \ diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 4425b6aad..3c1042154 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -335,17 +335,22 @@ void Compile (const char* FileName) ** changes using #pragma later. */ if (IS_Get (&Optimize)) { - long CodeSize = IS_Get (&CodeSizeFactor); DefineNumericMacro ("__OPT__", 1); + } + { + long CodeSize = IS_Get (&CodeSizeFactor); if (CodeSize > 100) { DefineNumericMacro ("__OPT_i__", CodeSize); } - if (IS_Get (&EnableRegVars)) { - DefineNumericMacro ("__OPT_r__", 1); - } - if (IS_Get (&InlineStdFuncs)) { - DefineNumericMacro ("__OPT_s__", 1); - } + } + if (IS_Get (&EnableRegVars)) { + DefineNumericMacro ("__OPT_r__", 1); + } + if (IS_Get (&InlineStdFuncs)) { + DefineNumericMacro ("__OPT_s__", 1); + } + if (IS_Get (&EagerlyInlineFuncs)) { + DefineNumericMacro ("__EAGERLY_INLINE_FUNCS__", 1); } /* __TIME__ and __DATE__ macros */ diff --git a/src/cc65/global.c b/src/cc65/global.c index dbdd72f3c..a337549fe 100644 --- a/src/cc65/global.c +++ b/src/cc65/global.c @@ -53,7 +53,8 @@ unsigned RegisterSpace = 6; /* Space available for register vars */ /* Stackable options */ IntStack WritableStrings = INTSTACK(0); /* Literal strings are r/w */ IntStack LocalStrings = INTSTACK(0); /* Emit string literals immediately */ -IntStack InlineStdFuncs = INTSTACK(0); /* Inline some known functions */ +IntStack InlineStdFuncs = INTSTACK(0); /* Inline some standard functions */ +IntStack EagerlyInlineFuncs = INTSTACK(0); /* Eagerly inline some known functions */ IntStack EnableRegVars = INTSTACK(0); /* Enable register variables */ IntStack AllowRegVarAddr = INTSTACK(0); /* Allow taking addresses of register vars */ IntStack RegVarsToCallStack = INTSTACK(0); /* Save reg variables on call stack */ diff --git a/src/cc65/global.h b/src/cc65/global.h index 8b0af5a83..4ffc84a39 100644 --- a/src/cc65/global.h +++ b/src/cc65/global.h @@ -61,7 +61,8 @@ extern unsigned RegisterSpace; /* Space available for register /* Stackable options */ extern IntStack WritableStrings; /* Literal strings are r/w */ extern IntStack LocalStrings; /* Emit string literals immediately */ -extern IntStack InlineStdFuncs; /* Inline some known functions */ +extern IntStack InlineStdFuncs; /* Inline some standard functions */ +extern IntStack EagerlyInlineFuncs; /* Eagerly inline some known functions */ extern IntStack EnableRegVars; /* Enable register variables */ extern IntStack AllowRegVarAddr; /* Allow taking addresses of register vars */ extern IntStack RegVarsToCallStack; /* Save reg variables on call stack */ diff --git a/src/cc65/main.c b/src/cc65/main.c index 9ed19b90c..d3d298876 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -88,7 +88,7 @@ static void Usage (void) " -O\t\t\t\tOptimize code\n" " -Oi\t\t\t\tOptimize code, inline more code\n" " -Or\t\t\t\tEnable register variables\n" - " -Os\t\t\t\tInline some known functions\n" + " -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" @@ -118,9 +118,11 @@ static void Usage (void) " --debug-opt name\t\tDebug optimization steps\n" " --dep-target target\t\tUse this dependency target\n" " --disable-opt name\t\tDisable an optimization step\n" + " --eagerly-inline-funcs\t\tEagerly inline some known functions\n" " --enable-opt name\t\tEnable an optimization step\n" " --help\t\t\tHelp (this text)\n" " --include-dir dir\t\tSet an include directory search path\n" + " --inline-stdfuncs\t\tInline some standard functions\n" " --list-opt-steps\t\tList all optimizer steps and exit\n" " --list-warnings\t\tList available warning types for -W\n" " --local-strings\t\tEmit string literals immediately\n" @@ -581,6 +583,16 @@ static void OptDisableOpt (const char* Opt attribute ((unused)), const char* Arg +static void OptEagerlyInlineFuncs (const char* Opt attribute((unused)), + const char* Arg attribute((unused))) +/* Eagerly inline some known functions */ +{ + IS_Set (&InlineStdFuncs, 1); + IS_Set (&EagerlyInlineFuncs, 1); +} + + + static void OptEnableOpt (const char* Opt attribute ((unused)), const char* Arg) /* Enable an optimization step */ { @@ -608,6 +620,15 @@ static void OptIncludeDir (const char* Opt attribute ((unused)), const char* Arg +static void OptInlineStdFuncs (const char* Opt attribute((unused)), + const char* Arg attribute((unused))) +/* Inline some standard functions */ +{ + IS_Set (&InlineStdFuncs, 1); +} + + + static void OptListOptSteps (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* List all optimizer steps */ @@ -819,39 +840,41 @@ int main (int argc, char* argv[]) { /* Program long options */ static const LongOpt OptTab[] = { - { "--add-source", 0, OptAddSource }, - { "--all-cdecl", 0, OptAllCDecl }, - { "--bss-name", 1, OptBssName }, - { "--check-stack", 0, OptCheckStack }, - { "--code-name", 1, OptCodeName }, - { "--codesize", 1, OptCodeSize }, - { "--cpu", 1, OptCPU }, - { "--create-dep", 1, OptCreateDep }, - { "--create-full-dep", 1, OptCreateFullDep }, - { "--data-name", 1, OptDataName }, - { "--debug", 0, OptDebug }, - { "--debug-info", 0, OptDebugInfo }, - { "--debug-opt", 1, OptDebugOpt }, - { "--debug-opt-output", 0, OptDebugOptOutput }, - { "--dep-target", 1, OptDepTarget }, - { "--disable-opt", 1, OptDisableOpt }, - { "--enable-opt", 1, OptEnableOpt }, - { "--help", 0, OptHelp }, - { "--include-dir", 1, OptIncludeDir }, - { "--list-opt-steps", 0, OptListOptSteps }, - { "--list-warnings", 0, OptListWarnings }, - { "--local-strings", 0, OptLocalStrings }, - { "--memory-model", 1, OptMemoryModel }, - { "--register-space", 1, OptRegisterSpace }, - { "--register-vars", 0, OptRegisterVars }, - { "--rodata-name", 1, OptRodataName }, - { "--signed-chars", 0, OptSignedChars }, - { "--standard", 1, OptStandard }, - { "--static-locals", 0, OptStaticLocals }, - { "--target", 1, OptTarget }, - { "--verbose", 0, OptVerbose }, - { "--version", 0, OptVersion }, - { "--writable-strings", 0, OptWritableStrings }, + { "--add-source", 0, OptAddSource }, + { "--all-cdecl", 0, OptAllCDecl }, + { "--bss-name", 1, OptBssName }, + { "--check-stack", 0, OptCheckStack }, + { "--code-name", 1, OptCodeName }, + { "--codesize", 1, OptCodeSize }, + { "--cpu", 1, OptCPU }, + { "--create-dep", 1, OptCreateDep }, + { "--create-full-dep", 1, OptCreateFullDep }, + { "--data-name", 1, OptDataName }, + { "--debug", 0, OptDebug }, + { "--debug-info", 0, OptDebugInfo }, + { "--debug-opt", 1, OptDebugOpt }, + { "--debug-opt-output", 0, OptDebugOptOutput }, + { "--dep-target", 1, OptDepTarget }, + { "--disable-opt", 1, OptDisableOpt }, + { "--eagerly-inline-funcs", 0, OptEagerlyInlineFuncs }, + { "--enable-opt", 1, OptEnableOpt }, + { "--help", 0, OptHelp }, + { "--include-dir", 1, OptIncludeDir }, + { "--inline-stdfuncs", 0, OptInlineStdFuncs }, + { "--list-opt-steps", 0, OptListOptSteps }, + { "--list-warnings", 0, OptListWarnings }, + { "--local-strings", 0, OptLocalStrings }, + { "--memory-model", 1, OptMemoryModel }, + { "--register-space", 1, OptRegisterSpace }, + { "--register-vars", 0, OptRegisterVars }, + { "--rodata-name", 1, OptRodataName }, + { "--signed-chars", 0, OptSignedChars }, + { "--standard", 1, OptStandard }, + { "--static-locals", 0, OptStaticLocals }, + { "--target", 1, OptTarget }, + { "--verbose", 0, OptVerbose }, + { "--version", 0, OptVersion }, + { "--writable-strings", 0, OptWritableStrings }, }; unsigned I; diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 86739ce22..707546e1d 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -64,6 +64,7 @@ typedef enum { PRAGMA_ILLEGAL = -1, PRAGMA_ALIGN, + PRAGMA_ALLOW_EAGER_INLINE, PRAGMA_BSS_NAME, PRAGMA_BSSSEG, /* obsolete */ PRAGMA_CHARMAP, @@ -74,6 +75,7 @@ typedef enum { PRAGMA_CODESIZE, PRAGMA_DATA_NAME, PRAGMA_DATASEG, /* obsolete */ + PRAGMA_INLINE_STDFUNCS, PRAGMA_LOCAL_STRINGS, PRAGMA_OPTIMIZE, PRAGMA_REGVARADDR, @@ -96,31 +98,33 @@ static const struct Pragma { const char* Key; /* Keyword */ pragma_t Tok; /* Token */ } Pragmas[PRAGMA_COUNT] = { - { "align", PRAGMA_ALIGN }, - { "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 */ - { "local-strings", PRAGMA_LOCAL_STRINGS }, - { "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 }, - { "writable-strings", PRAGMA_WRITABLE_STRINGS }, - { "zpsym", PRAGMA_ZPSYM }, + { "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 }, + { "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 }, + { "writable-strings", PRAGMA_WRITABLE_STRINGS }, + { "zpsym", PRAGMA_ZPSYM }, }; /* Result of ParsePushPop */ @@ -703,6 +707,10 @@ static void ParsePragma (void) IntPragma (&B, &DataAlignment, 1, 4096); break; + case PRAGMA_ALLOW_EAGER_INLINE: + FlagPragma (&B, &EagerlyInlineFuncs); + break; + case PRAGMA_BSSSEG: Warning ("#pragma bssseg is obsolete, please use #pragma bss-name instead"); /* FALLTHROUGH */ @@ -739,6 +747,10 @@ static void ParsePragma (void) SegNamePragma (&B, SEG_DATA); break; + case PRAGMA_INLINE_STDFUNCS: + FlagPragma (&B, &InlineStdFuncs); + break; + case PRAGMA_LOCAL_STRINGS: FlagPragma (&B, &LocalStrings); break; diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 720e6db15..7a0450146 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -261,262 +261,277 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) goto ExitPoint; } - /* We've generated the complete code for the function now and know the - ** types of all parameters. Check for situations where better code can - ** be generated. If such a situation is detected, throw away the - ** generated, and emit better code. - */ - if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 && - ((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) || - (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) && - ((ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) || - (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr)))) { + if (IS_Get (&InlineStdFuncs)) { - int Reg1 = ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr); - int Reg2 = ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr); - - /* Drop the generated code */ - RemoveCode (&Arg1.Expr.Start); - - /* We need a label */ - Label = GetLocalLabel (); - - /* Generate memcpy code */ - if (Arg3.Expr.IVal <= 127) { - - AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal-1)); - g_defcodelabel (Label); - if (Reg2) { - AddCodeLine ("lda (%s),y", ED_GetLabelName (&Arg2.Expr, 0)); - } else { - AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, 0)); - } - if (Reg1) { - AddCodeLine ("sta (%s),y", ED_GetLabelName (&Arg1.Expr, 0)); - } else { - AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0)); - } - AddCodeLine ("dey"); - AddCodeLine ("bpl %s", LocalLabelName (Label)); - - } else { - - AddCodeLine ("ldy #$00"); - g_defcodelabel (Label); - if (Reg2) { - AddCodeLine ("lda (%s),y", ED_GetLabelName (&Arg2.Expr, 0)); - } else { - AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, 0)); - } - if (Reg1) { - AddCodeLine ("sta (%s),y", ED_GetLabelName (&Arg1.Expr, 0)); - } else { - AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0)); - } - AddCodeLine ("iny"); - AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal); - AddCodeLine ("bne %s", LocalLabelName (Label)); - - } - - /* memcpy returns the address, so the result is actually identical - ** to the first argument. + /* We've generated the complete code for the function now and know the + ** types of all parameters. Check for situations where better code can + ** be generated. If such a situation is detected, throw away the + ** generated, and emit better code. */ - *Expr = Arg1.Expr; + if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 && + ((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) || + (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) && + ((ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) || + (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr)))) { - } else if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 && - ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr) && - ED_IsRVal (&Arg1.Expr) && ED_IsLocStack (&Arg1.Expr) && - (Arg1.Expr.IVal - StackPtr) + Arg3.Expr.IVal < 256) { + int Reg1 = ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr); + int Reg2 = ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr); - /* It is possible to just use one index register even if the stack - ** offset is not zero, by adjusting the offset to the constant - ** address accordingly. But we cannot do this if the data in - ** question is in the register space or at an absolute address less - ** than 256. Register space is zero page, which means that the - ** address calculation could overflow in the linker. - */ - int AllowOneIndex = !ED_IsLocRegister (&Arg2.Expr) && - !(ED_IsLocAbs (&Arg2.Expr) && Arg2.Expr.IVal < 256); + /* Drop the generated code */ + RemoveCode (&Arg1.Expr.Start); - /* Calculate the real stack offset */ - Offs = ED_GetStackOffs (&Arg1.Expr, 0); + /* We need a label */ + Label = GetLocalLabel (); - /* Drop the generated code */ - RemoveCode (&Arg1.Expr.Start); + /* Generate memcpy code */ + if (Arg3.Expr.IVal <= 127) { - /* We need a label */ - Label = GetLocalLabel (); - - /* Generate memcpy code */ - if (Arg3.Expr.IVal <= 127 && !AllowOneIndex) { - - if (Offs == 0) { - AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1)); + AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal-1)); g_defcodelabel (Label); - AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs)); - AddCodeLine ("sta (sp),y"); + if (Reg2) { + AddCodeLine ("lda (%s),y", ED_GetLabelName (&Arg2.Expr, 0)); + } else { + AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, 0)); + } + if (Reg1) { + AddCodeLine ("sta (%s),y", ED_GetLabelName (&Arg1.Expr, 0)); + } else { + AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0)); + } AddCodeLine ("dey"); AddCodeLine ("bpl %s", LocalLabelName (Label)); + } else { - AddCodeLine ("ldx #$%02X", (unsigned char) (Arg3.Expr.IVal-1)); - AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1)); + + AddCodeLine ("ldy #$00"); g_defcodelabel (Label); - AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0)); - AddCodeLine ("sta (sp),y"); - AddCodeLine ("dey"); - AddCodeLine ("dex"); - AddCodeLine ("bpl %s", LocalLabelName (Label)); + if (Reg2) { + AddCodeLine ("lda (%s),y", ED_GetLabelName (&Arg2.Expr, 0)); + } else { + AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, 0)); + } + if (Reg1) { + AddCodeLine ("sta (%s),y", ED_GetLabelName (&Arg1.Expr, 0)); + } else { + AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0)); + } + AddCodeLine ("iny"); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal); + AddCodeLine ("bne %s", LocalLabelName (Label)); + } - } else { - - if (Offs == 0 || AllowOneIndex) { - AddCodeLine ("ldy #$%02X", (unsigned char) Offs); - g_defcodelabel (Label); - AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs)); - AddCodeLine ("sta (sp),y"); - AddCodeLine ("iny"); - AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); - AddCodeLine ("bne %s", LocalLabelName (Label)); - } else { - AddCodeLine ("ldx #$00"); - AddCodeLine ("ldy #$%02X", (unsigned char) Offs); - g_defcodelabel (Label); - AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0)); - AddCodeLine ("sta (sp),y"); - AddCodeLine ("iny"); - AddCodeLine ("inx"); - AddCmpCodeIfSizeNot256 ("cpx #$%02X", Arg3.Expr.IVal); - AddCodeLine ("bne %s", LocalLabelName (Label)); - } + /* memcpy returns the address, so the result is actually identical + ** to the first argument. + */ + *Expr = Arg1.Expr; + /* Bail out, no need for further processing */ + goto ExitPoint; } - /* memcpy returns the address, so the result is actually identical - ** to the first argument. - */ - *Expr = Arg1.Expr; + if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 && + ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr) && + ED_IsRVal (&Arg1.Expr) && ED_IsLocStack (&Arg1.Expr) && + (Arg1.Expr.IVal - StackPtr) + Arg3.Expr.IVal < 256) { - } else if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 && - ED_IsRVal (&Arg2.Expr) && ED_IsLocStack (&Arg2.Expr) && - (Arg2.Expr.IVal - StackPtr) + Arg3.Expr.IVal < 256 && - ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) { + /* It is possible to just use one index register even if the stack + ** offset is not zero, by adjusting the offset to the constant + ** address accordingly. But we cannot do this if the data in + ** question is in the register space or at an absolute address less + ** than 256. Register space is zero page, which means that the + ** address calculation could overflow in the linker. + */ + int AllowOneIndex = !ED_IsLocRegister (&Arg2.Expr) && + !(ED_IsLocAbs (&Arg2.Expr) && Arg2.Expr.IVal < 256); - /* It is possible to just use one index register even if the stack - ** offset is not zero, by adjusting the offset to the constant - ** address accordingly. But we cannot do this if the data in - ** question is in the register space or at an absolute address less - ** than 256. Register space is zero page, which means that the - ** address calculation could overflow in the linker. - */ - int AllowOneIndex = !ED_IsLocRegister (&Arg1.Expr) && - !(ED_IsLocAbs (&Arg1.Expr) && Arg1.Expr.IVal < 256); + /* Calculate the real stack offset */ + Offs = ED_GetStackOffs (&Arg1.Expr, 0); - /* Calculate the real stack offset */ - Offs = ED_GetStackOffs (&Arg2.Expr, 0); + /* Drop the generated code */ + RemoveCode (&Arg1.Expr.Start); - /* Drop the generated code */ - RemoveCode (&Arg1.Expr.Start); + /* We need a label */ + Label = GetLocalLabel (); - /* We need a label */ - Label = GetLocalLabel (); + /* Generate memcpy code */ + if (Arg3.Expr.IVal <= 127 && !AllowOneIndex) { - /* Generate memcpy code */ - if (Arg3.Expr.IVal <= 127 && !AllowOneIndex) { + if (Offs == 0) { + 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 ("dey"); + AddCodeLine ("bpl %s", LocalLabelName (Label)); + } else { + AddCodeLine ("ldx #$%02X", (unsigned char) (Arg3.Expr.IVal-1)); + 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 ("dey"); + AddCodeLine ("dex"); + AddCodeLine ("bpl %s", LocalLabelName (Label)); + } - if (Offs == 0) { + } else { + + if (Offs == 0 || AllowOneIndex) { + AddCodeLine ("ldy #$%02X", (unsigned char) Offs); + g_defcodelabel (Label); + AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs)); + AddCodeLine ("sta (sp),y"); + AddCodeLine ("iny"); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); + AddCodeLine ("bne %s", LocalLabelName (Label)); + } else { + AddCodeLine ("ldx #$00"); + AddCodeLine ("ldy #$%02X", (unsigned char) Offs); + g_defcodelabel (Label); + AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0)); + AddCodeLine ("sta (sp),y"); + AddCodeLine ("iny"); + AddCodeLine ("inx"); + AddCmpCodeIfSizeNot256 ("cpx #$%02X", Arg3.Expr.IVal); + AddCodeLine ("bne %s", LocalLabelName (Label)); + } + + } + + /* memcpy returns the address, so the result is actually identical + ** to the first argument. + */ + *Expr = Arg1.Expr; + + /* Bail out, no need for further processing */ + goto ExitPoint; + } + + if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 && + ED_IsRVal (&Arg2.Expr) && ED_IsLocStack (&Arg2.Expr) && + (Arg2.Expr.IVal - StackPtr) + Arg3.Expr.IVal < 256 && + ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) { + + /* It is possible to just use one index register even if the stack + ** offset is not zero, by adjusting the offset to the constant + ** address accordingly. But we cannot do this if the data in + ** question is in the register space or at an absolute address less + ** than 256. Register space is zero page, which means that the + ** address calculation could overflow in the linker. + */ + int AllowOneIndex = !ED_IsLocRegister (&Arg1.Expr) && + !(ED_IsLocAbs (&Arg1.Expr) && Arg1.Expr.IVal < 256); + + /* Calculate the real stack offset */ + Offs = ED_GetStackOffs (&Arg2.Expr, 0); + + /* Drop the generated code */ + RemoveCode (&Arg1.Expr.Start); + + /* We need a label */ + Label = GetLocalLabel (); + + /* Generate memcpy code */ + if (Arg3.Expr.IVal <= 127 && !AllowOneIndex) { + + if (Offs == 0) { + AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal - 1)); + g_defcodelabel (Label); + AddCodeLine ("lda (sp),y"); + AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0)); + AddCodeLine ("dey"); + AddCodeLine ("bpl %s", LocalLabelName (Label)); + } else { + 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 ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0)); + AddCodeLine ("dey"); + AddCodeLine ("dex"); + AddCodeLine ("bpl %s", LocalLabelName (Label)); + } + + } else { + + if (Offs == 0 || AllowOneIndex) { + AddCodeLine ("ldy #$%02X", (unsigned char) Offs); + g_defcodelabel (Label); + AddCodeLine ("lda (sp),y"); + AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, -Offs)); + AddCodeLine ("iny"); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); + AddCodeLine ("bne %s", LocalLabelName (Label)); + } else { + AddCodeLine ("ldx #$00"); + AddCodeLine ("ldy #$%02X", (unsigned char) Offs); + g_defcodelabel (Label); + AddCodeLine ("lda (sp),y"); + AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0)); + AddCodeLine ("iny"); + AddCodeLine ("inx"); + AddCmpCodeIfSizeNot256 ("cpx #$%02X", Arg3.Expr.IVal); + AddCodeLine ("bne %s", LocalLabelName (Label)); + } + + } + + /* memcpy returns the address, so the result is actually identical + ** to the first argument. + */ + *Expr = Arg1.Expr; + + /* Bail out, no need for further processing */ + goto ExitPoint; + } + + if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 && + ED_IsRVal (&Arg2.Expr) && ED_IsLocStack (&Arg2.Expr) && + (Offs = ED_GetStackOffs (&Arg2.Expr, 0)) == 0) { + + /* Drop the generated code but leave the load of the first argument*/ + RemoveCode (&Arg1.Push); + + /* We need a label */ + Label = GetLocalLabel (); + + /* Generate memcpy code */ + AddCodeLine ("sta ptr1"); + AddCodeLine ("stx ptr1+1"); + if (Arg3.Expr.IVal <= 127) { AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal - 1)); g_defcodelabel (Label); AddCodeLine ("lda (sp),y"); - AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0)); + AddCodeLine ("sta (ptr1),y"); AddCodeLine ("dey"); AddCodeLine ("bpl %s", LocalLabelName (Label)); } else { - AddCodeLine ("ldx #$%02X", (unsigned char) (Arg3.Expr.IVal-1)); - AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1)); + AddCodeLine ("ldy #$00"); g_defcodelabel (Label); AddCodeLine ("lda (sp),y"); - AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0)); - AddCodeLine ("dey"); - AddCodeLine ("dex"); - AddCodeLine ("bpl %s", LocalLabelName (Label)); - } - - } else { - - if (Offs == 0 || AllowOneIndex) { - AddCodeLine ("ldy #$%02X", (unsigned char) Offs); - g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); - AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, -Offs)); + AddCodeLine ("sta (ptr1),y"); AddCodeLine ("iny"); - AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); - AddCodeLine ("bne %s", LocalLabelName (Label)); - } else { - AddCodeLine ("ldx #$00"); - AddCodeLine ("ldy #$%02X", (unsigned char) Offs); - g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); - AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0)); - AddCodeLine ("iny"); - AddCodeLine ("inx"); - AddCmpCodeIfSizeNot256 ("cpx #$%02X", Arg3.Expr.IVal); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal); AddCodeLine ("bne %s", LocalLabelName (Label)); } + /* Reload result - X hasn't changed by the code above */ + AddCodeLine ("lda ptr1"); + + /* The function result is an rvalue in the primary register */ + ED_MakeRValExpr (Expr); + Expr->Type = GetFuncReturn (Expr->Type); + + /* Bail out, no need for further processing */ + goto ExitPoint; } - - /* memcpy returns the address, so the result is actually identical - ** to the first argument. - */ - *Expr = Arg1.Expr; - - } else if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 && - ED_IsRVal (&Arg2.Expr) && ED_IsLocStack (&Arg2.Expr) && - (Offs = ED_GetStackOffs (&Arg2.Expr, 0)) == 0) { - - /* Drop the generated code but leave the load of the first argument*/ - RemoveCode (&Arg1.Push); - - /* We need a label */ - Label = GetLocalLabel (); - - /* Generate memcpy code */ - AddCodeLine ("sta ptr1"); - AddCodeLine ("stx ptr1+1"); - if (Arg3.Expr.IVal <= 127) { - AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal - 1)); - g_defcodelabel (Label); - AddCodeLine ("lda (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 ("sta (ptr1),y"); - AddCodeLine ("iny"); - AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal); - AddCodeLine ("bne %s", LocalLabelName (Label)); - } - - /* Reload result - X hasn't changed by the code above */ - AddCodeLine ("lda ptr1"); - - /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); - Expr->Type = GetFuncReturn (Expr->Type); - - } else { - - /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); - Expr->Type = GetFuncReturn (Expr->Type); - } + /* The function result is an rvalue in the primary register */ + ED_MakeRValExpr (Expr); + Expr->Type = GetFuncReturn (Expr->Type); + ExitPoint: /* We expect the closing brace */ ConsumeRParen (); @@ -595,140 +610,151 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) goto ExitPoint; } - /* We've generated the complete code for the function now and know the - ** types of all parameters. Check for situations where better code can - ** be generated. If such a situation is detected, throw away the - ** generated, and emit better code. - ** Note: Lots of improvements would be possible here, but I will - ** concentrate on the most common case: memset with arguments 2 and 3 - ** being constant numerical values. Some checks have shown that this - ** covers nearly 90% of all memset calls. - */ - if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 && - ED_IsConstAbsInt (&Arg2.Expr) && - ((ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) || - (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr)))) { + if (IS_Get (&InlineStdFuncs)) { - int Reg = ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr); + /* We've generated the complete code for the function now and know the + ** types of all parameters. Check for situations where better code can + ** be generated. If such a situation is detected, throw away the + ** generated, and emit better code. + ** Note: Lots of improvements would be possible here, but I will + ** concentrate on the most common case: memset with arguments 2 and 3 + ** being constant numerical values. Some checks have shown that this + ** covers nearly 90% of all memset calls. + */ + if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 && + ED_IsConstAbsInt (&Arg2.Expr) && + ((ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) || + (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr)))) { - /* Drop the generated code */ - RemoveCode (&Arg1.Expr.Start); + int Reg = ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr); - /* We need a label */ - Label = GetLocalLabel (); + /* Drop the generated code */ + RemoveCode (&Arg1.Expr.Start); - /* Generate memset code */ - if (Arg3.Expr.IVal <= 127) { + /* We need a label */ + Label = GetLocalLabel (); + + /* Generate memset code */ + if (Arg3.Expr.IVal <= 127) { + + AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal-1)); + AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal); + g_defcodelabel (Label); + if (Reg) { + AddCodeLine ("sta (%s),y", ED_GetLabelName (&Arg1.Expr, 0)); + } else { + AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0)); + } + AddCodeLine ("dey"); + AddCodeLine ("bpl %s", LocalLabelName (Label)); - AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal-1)); - AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal); - g_defcodelabel (Label); - if (Reg) { - AddCodeLine ("sta (%s),y", ED_GetLabelName (&Arg1.Expr, 0)); } else { - AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0)); + + AddCodeLine ("ldy #$00"); + AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal); + g_defcodelabel (Label); + if (Reg) { + AddCodeLine ("sta (%s),y", ED_GetLabelName (&Arg1.Expr, 0)); + } else { + AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0)); + } + AddCodeLine ("iny"); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal); + AddCodeLine ("bne %s", LocalLabelName (Label)); + } - AddCodeLine ("dey"); - AddCodeLine ("bpl %s", LocalLabelName (Label)); - } else { - - AddCodeLine ("ldy #$00"); - AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal); - g_defcodelabel (Label); - if (Reg) { - AddCodeLine ("sta (%s),y", ED_GetLabelName (&Arg1.Expr, 0)); - } else { - AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0)); - } - AddCodeLine ("iny"); - AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal); - AddCodeLine ("bne %s", LocalLabelName (Label)); + /* memset returns the address, so the result is actually identical + ** to the first argument. + */ + *Expr = Arg1.Expr; + /* Bail out, no need for further processing */ + goto ExitPoint; } - /* memset returns the address, so the result is actually identical - ** to the first argument. - */ - *Expr = Arg1.Expr; + if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 && + ED_IsConstAbsInt (&Arg2.Expr) && + ED_IsRVal (&Arg1.Expr) && ED_IsLocStack (&Arg1.Expr) && + (Arg1.Expr.IVal - StackPtr) + Arg3.Expr.IVal < 256) { - } else if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 && - ED_IsConstAbsInt (&Arg2.Expr) && - ED_IsRVal (&Arg1.Expr) && ED_IsLocStack (&Arg1.Expr) && - (Arg1.Expr.IVal - StackPtr) + Arg3.Expr.IVal < 256) { + /* Calculate the real stack offset */ + int Offs = ED_GetStackOffs (&Arg1.Expr, 0); - /* Calculate the real stack offset */ - int Offs = ED_GetStackOffs (&Arg1.Expr, 0); + /* Drop the generated code */ + RemoveCode (&Arg1.Expr.Start); - /* Drop the generated code */ - RemoveCode (&Arg1.Expr.Start); + /* We need a label */ + Label = GetLocalLabel (); - /* We need a label */ - Label = GetLocalLabel (); - - /* Generate memset code */ - AddCodeLine ("ldy #$%02X", (unsigned char) Offs); - AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal); - g_defcodelabel (Label); - AddCodeLine ("sta (sp),y"); - AddCodeLine ("iny"); - AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); - AddCodeLine ("bne %s", LocalLabelName (Label)); - - /* memset returns the address, so the result is actually identical - ** to the first argument. - */ - *Expr = Arg1.Expr; - - } else if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 && - ED_IsConstAbsInt (&Arg2.Expr) && - (Arg2.Expr.IVal != 0 || IS_Get (&CodeSizeFactor) > 200)) { - - /* Remove all of the generated code but the load of the first - ** argument. - */ - RemoveCode (&Arg1.Push); - - /* We need a label */ - Label = GetLocalLabel (); - - /* Generate code */ - AddCodeLine ("sta ptr1"); - AddCodeLine ("stx ptr1+1"); - if (Arg3.Expr.IVal <= 127) { - AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal-1)); + /* Generate memset code */ + AddCodeLine ("ldy #$%02X", (unsigned char) Offs); AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal); g_defcodelabel (Label); - AddCodeLine ("sta (ptr1),y"); - AddCodeLine ("dey"); - AddCodeLine ("bpl %s", LocalLabelName (Label)); - } else { - AddCodeLine ("ldy #$00"); - AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal); - g_defcodelabel (Label); - AddCodeLine ("sta (ptr1),y"); + AddCodeLine ("sta (sp),y"); AddCodeLine ("iny"); - AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); AddCodeLine ("bne %s", LocalLabelName (Label)); + + /* memset returns the address, so the result is actually identical + ** to the first argument. + */ + *Expr = Arg1.Expr; + + /* Bail out, no need for further processing */ + goto ExitPoint; } - /* Load the function result pointer into a/x (x is still valid). This - ** code will get removed by the optimizer if it is not used later. - */ - AddCodeLine ("lda ptr1"); + if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 && + ED_IsConstAbsInt (&Arg2.Expr) && + (Arg2.Expr.IVal != 0 || IS_Get (&CodeSizeFactor) > 200)) { - /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); - Expr->Type = GetFuncReturn (Expr->Type); + /* Remove all of the generated code but the load of the first + ** argument. + */ + RemoveCode (&Arg1.Push); - } else { + /* We need a label */ + Label = GetLocalLabel (); - /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); - Expr->Type = GetFuncReturn (Expr->Type); + /* Generate code */ + AddCodeLine ("sta ptr1"); + AddCodeLine ("stx ptr1+1"); + if (Arg3.Expr.IVal <= 127) { + AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal-1)); + AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal); + g_defcodelabel (Label); + AddCodeLine ("sta (ptr1),y"); + AddCodeLine ("dey"); + AddCodeLine ("bpl %s", LocalLabelName (Label)); + } else { + AddCodeLine ("ldy #$00"); + AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal); + g_defcodelabel (Label); + AddCodeLine ("sta (ptr1),y"); + AddCodeLine ("iny"); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal); + AddCodeLine ("bne %s", LocalLabelName (Label)); + } + /* Load the function result pointer into a/x (x is still valid). This + ** code will get removed by the optimizer if it is not used later. + */ + AddCodeLine ("lda ptr1"); + + /* The function result is an rvalue in the primary register */ + ED_MakeRValExpr (Expr); + Expr->Type = GetFuncReturn (Expr->Type); + + /* Bail out, no need for further processing */ + goto ExitPoint; + } } + /* The function result is an rvalue in the primary register */ + ED_MakeRValExpr (Expr); + Expr->Type = GetFuncReturn (Expr->Type); + ExitPoint: /* We expect the closing brace */ ConsumeRParen (); @@ -790,142 +816,142 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ECount1 = ECount2; } - /* If the second argument is the empty string literal, we can generate - ** more efficient code. - */ - if (ED_IsLocLiteral (&Arg2.Expr) && - IS_Get (&WritableStrings) == 0 && - GetLiteralSize (Arg2.Expr.LVal) == 1 && - GetLiteralStr (Arg2.Expr.LVal)[0] == '\0') { + if (IS_Get (&InlineStdFuncs)) { - /* Drop the generated code so we have the first argument in the - ** primary + /* If the second argument is the empty string literal, we can generate + ** more efficient code. */ - RemoveCode (&Arg1.Push); + if (ED_IsLocLiteral (&Arg2.Expr) && + IS_Get (&WritableStrings) == 0 && + GetLiteralSize (Arg2.Expr.LVal) == 1 && + GetLiteralStr (Arg2.Expr.LVal)[0] == '\0') { - /* We don't need the literal any longer */ - ReleaseLiteral (Arg2.Expr.LVal); - - /* We do now have Arg1 in the primary. Load the first character from - ** this string and cast to int. This is the function result. - */ - IsArray = IsTypeArray (Arg1.Type) && ED_IsRVal (&Arg1.Expr); - if (IsArray && ED_IsLocStack (&Arg1.Expr) && - (Offs = ED_GetStackOffs (&Arg1.Expr, 0) < 256)) { - /* Drop the generated code */ - RemoveCode (&Arg1.Load); - - /* Generate code */ - AddCodeLine ("ldy #$%02X", Offs); - AddCodeLine ("ldx #$00"); - AddCodeLine ("lda (sp),y"); - } else if (IsArray && ED_IsLocConst (&Arg1.Expr)) { - /* Drop the generated code */ - RemoveCode (&Arg1.Load); - - /* Generate code */ - AddCodeLine ("ldx #$00"); - AddCodeLine ("lda %s", ED_GetLabelName (&Arg1.Expr, 0)); - } else { - /* Drop part of the generated code so we have the first argument - ** in the primary + /* Drop the generated code so we have the first argument in the + ** primary */ RemoveCode (&Arg1.Push); - /* Fetch the first char */ - g_getind (CF_CHAR | CF_UNSIGNED, 0); + /* We don't need the literal any longer */ + ReleaseLiteral (Arg2.Expr.LVal); + + /* We do now have Arg1 in the primary. Load the first character from + ** this string and cast to int. This is the function result. + */ + IsArray = IsTypeArray (Arg1.Type) && ED_IsRVal (&Arg1.Expr); + if (IsArray && ED_IsLocStack (&Arg1.Expr) && + (Offs = ED_GetStackOffs (&Arg1.Expr, 0) < 256)) { + /* Drop the generated code */ + RemoveCode (&Arg1.Load); + + /* Generate code */ + AddCodeLine ("ldy #$%02X", Offs); + AddCodeLine ("ldx #$00"); + AddCodeLine ("lda (sp),y"); + } else if (IsArray && ED_IsLocConst (&Arg1.Expr)) { + /* Drop the generated code */ + RemoveCode (&Arg1.Load); + + /* Generate code */ + AddCodeLine ("ldx #$00"); + AddCodeLine ("lda %s", ED_GetLabelName (&Arg1.Expr, 0)); + } else { + /* Drop part of the generated code so we have the first argument + ** in the primary + */ + RemoveCode (&Arg1.Push); + + /* Fetch the first char */ + g_getind (CF_CHAR | CF_UNSIGNED, 0); + } + + } else if ((IS_Get (&CodeSizeFactor) >= 165) && + ((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) || + (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) && + ((ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) || + (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr))) && + (IS_Get (&EagerlyInlineFuncs) || (ECount1 > 0 && ECount1 < 256))) { + + unsigned Entry, Loop, Fin; /* Labels */ + const char* Load; + const char* Compare; + + if (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr)) { + Load = "lda (%s),y"; + } else { + Load = "lda %s,y"; + } + if (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr)) { + Compare = "cmp (%s),y"; + } else { + Compare = "cmp %s,y"; + } + + /* Drop the generated code */ + RemoveCode (&Arg1.Expr.Start); + + /* We need labels */ + Entry = GetLocalLabel (); + Loop = GetLocalLabel (); + Fin = GetLocalLabel (); + + /* Generate strcmp code */ + AddCodeLine ("ldy #$00"); + AddCodeLine ("beq %s", LocalLabelName (Entry)); + g_defcodelabel (Loop); + AddCodeLine ("tax"); + AddCodeLine ("beq %s", LocalLabelName (Fin)); + AddCodeLine ("iny"); + g_defcodelabel (Entry); + AddCodeLine (Load, ED_GetLabelName (&Arg1.Expr, 0)); + AddCodeLine (Compare, ED_GetLabelName (&Arg2.Expr, 0)); + AddCodeLine ("beq %s", LocalLabelName (Loop)); + AddCodeLine ("ldx #$01"); + AddCodeLine ("bcs %s", LocalLabelName (Fin)); + AddCodeLine ("ldx #$FF"); + g_defcodelabel (Fin); + + } else if ((IS_Get (&CodeSizeFactor) > 190) && + ((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) || + (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) && + (IS_Get (&EagerlyInlineFuncs) || (ECount1 > 0 && ECount1 < 256))) { + + unsigned Entry, Loop, Fin; /* Labels */ + const char* Compare; + + if (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr)) { + Compare = "cmp (%s),y"; + } else { + Compare = "cmp %s,y"; + } + + /* Drop the generated code */ + RemoveCode (&Arg1.Push); + + /* We need labels */ + Entry = GetLocalLabel (); + Loop = GetLocalLabel (); + Fin = GetLocalLabel (); + + /* Store Arg1 into ptr1 */ + AddCodeLine ("sta ptr1"); + AddCodeLine ("stx ptr1+1"); + + /* Generate strcmp code */ + AddCodeLine ("ldy #$00"); + AddCodeLine ("beq %s", LocalLabelName (Entry)); + g_defcodelabel (Loop); + AddCodeLine ("tax"); + AddCodeLine ("beq %s", LocalLabelName (Fin)); + AddCodeLine ("iny"); + g_defcodelabel (Entry); + AddCodeLine ("lda (ptr1),y"); + AddCodeLine (Compare, ED_GetLabelName (&Arg2.Expr, 0)); + AddCodeLine ("beq %s", LocalLabelName (Loop)); + AddCodeLine ("ldx #$01"); + AddCodeLine ("bcs %s", LocalLabelName (Fin)); + AddCodeLine ("ldx #$FF"); + g_defcodelabel (Fin); } - - } else if ((IS_Get (&CodeSizeFactor) >= 165) && - ((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) || - (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) && - ((ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) || - (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr))) && - (IS_Get (&InlineStdFuncs) || (ECount1 > 0 && ECount1 < 256))) { - - - unsigned Entry, Loop, Fin; /* Labels */ - const char* Load; - const char* Compare; - - if (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr)) { - Load = "lda (%s),y"; - } else { - Load = "lda %s,y"; - } - if (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr)) { - Compare = "cmp (%s),y"; - } else { - Compare = "cmp %s,y"; - } - - /* Drop the generated code */ - RemoveCode (&Arg1.Expr.Start); - - /* We need labels */ - Entry = GetLocalLabel (); - Loop = GetLocalLabel (); - Fin = GetLocalLabel (); - - /* Generate strcmp code */ - AddCodeLine ("ldy #$00"); - AddCodeLine ("beq %s", LocalLabelName (Entry)); - g_defcodelabel (Loop); - AddCodeLine ("tax"); - AddCodeLine ("beq %s", LocalLabelName (Fin)); - AddCodeLine ("iny"); - g_defcodelabel (Entry); - AddCodeLine (Load, ED_GetLabelName (&Arg1.Expr, 0)); - AddCodeLine (Compare, ED_GetLabelName (&Arg2.Expr, 0)); - AddCodeLine ("beq %s", LocalLabelName (Loop)); - AddCodeLine ("ldx #$01"); - AddCodeLine ("bcs %s", LocalLabelName (Fin)); - AddCodeLine ("ldx #$FF"); - g_defcodelabel (Fin); - - } else if ((IS_Get (&CodeSizeFactor) > 190) && - ((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) || - (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) && - (IS_Get (&InlineStdFuncs) || (ECount1 > 0 && ECount1 < 256))) { - - - unsigned Entry, Loop, Fin; /* Labels */ - const char* Compare; - - if (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr)) { - Compare = "cmp (%s),y"; - } else { - Compare = "cmp %s,y"; - } - - /* Drop the generated code */ - RemoveCode (&Arg1.Push); - - /* We need labels */ - Entry = GetLocalLabel (); - Loop = GetLocalLabel (); - Fin = GetLocalLabel (); - - /* Store Arg1 into ptr1 */ - AddCodeLine ("sta ptr1"); - AddCodeLine ("stx ptr1+1"); - - /* Generate strcmp code */ - AddCodeLine ("ldy #$00"); - AddCodeLine ("beq %s", LocalLabelName (Entry)); - g_defcodelabel (Loop); - AddCodeLine ("tax"); - AddCodeLine ("beq %s", LocalLabelName (Fin)); - AddCodeLine ("iny"); - g_defcodelabel (Entry); - AddCodeLine ("lda (ptr1),y"); - AddCodeLine (Compare, ED_GetLabelName (&Arg2.Expr, 0)); - AddCodeLine ("beq %s", LocalLabelName (Loop)); - AddCodeLine ("ldx #$01"); - AddCodeLine ("bcs %s", LocalLabelName (Fin)); - AddCodeLine ("ldx #$FF"); - g_defcodelabel (Fin); - } /* The function result is an rvalue in the primary register */ @@ -983,142 +1009,154 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Get the element count of argument 1 if it is an array */ ECount = ArrayElementCount (&Arg1); - /* We've generated the complete code for the function now and know the - ** types of all parameters. Check for situations where better code can - ** be generated. If such a situation is detected, throw away the - ** generated, and emit better code. - */ - if (((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) || - (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) && - ((ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) || - (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr))) && - (IS_Get (&InlineStdFuncs) || - (ECount != UNSPECIFIED && ECount < 256))) { + if (IS_Get (&InlineStdFuncs)) { - const char* Load; - const char* Store; - if (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr)) { - Load = "lda (%s),y"; - } else { - Load = "lda %s,y"; - } - if (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr)) { - Store = "sta (%s),y"; - } else { - Store = "sta %s,y"; - } - - /* Drop the generated code */ - RemoveCode (&Arg1.Expr.Start); - - /* We need labels */ - L1 = GetLocalLabel (); - - /* Generate strcpy code */ - AddCodeLine ("ldy #$FF"); - g_defcodelabel (L1); - AddCodeLine ("iny"); - AddCodeLine (Load, ED_GetLabelName (&Arg2.Expr, 0)); - AddCodeLine (Store, ED_GetLabelName (&Arg1.Expr, 0)); - AddCodeLine ("bne %s", LocalLabelName (L1)); - - /* strcpy returns argument #1 */ - *Expr = Arg1.Expr; - - } else if (ED_IsRVal (&Arg2.Expr) && ED_IsLocStack (&Arg2.Expr) && - StackPtr >= -255 && - ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) { - - /* It is possible to just use one index register even if the stack - ** offset is not zero, by adjusting the offset to the constant - ** address accordingly. But we cannot do this if the data in - ** question is in the register space or at an absolute address less - ** than 256. Register space is zero page, which means that the - ** address calculation could overflow in the linker. + /* We've generated the complete code for the function now and know the + ** types of all parameters. Check for situations where better code can + ** be generated. If such a situation is detected, throw away the + ** generated, and emit better code. */ - int AllowOneIndex = !ED_IsLocRegister (&Arg1.Expr) && - !(ED_IsLocAbs (&Arg1.Expr) && Arg1.Expr.IVal < 256); + if (((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) || + (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) && + ((ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) || + (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr))) && + (IS_Get (&EagerlyInlineFuncs) || + (ECount != UNSPECIFIED && ECount < 256))) { - /* Calculate the real stack offset */ - int Offs = ED_GetStackOffs (&Arg2.Expr, 0); + const char* Load; + const char* Store; + if (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr)) { + Load = "lda (%s),y"; + } else { + Load = "lda %s,y"; + } + if (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr)) { + Store = "sta (%s),y"; + } else { + Store = "sta %s,y"; + } - /* Drop the generated code */ - RemoveCode (&Arg1.Expr.Start); + /* Drop the generated code */ + RemoveCode (&Arg1.Expr.Start); - /* We need labels */ - L1 = GetLocalLabel (); + /* We need labels */ + L1 = GetLocalLabel (); - /* Generate strcpy code */ - AddCodeLine ("ldy #$%02X", (unsigned char) (Offs - 1)); - if (Offs == 0 || AllowOneIndex) { + /* Generate strcpy code */ + AddCodeLine ("ldy #$FF"); g_defcodelabel (L1); AddCodeLine ("iny"); - AddCodeLine ("lda (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 ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0)); + AddCodeLine (Load, ED_GetLabelName (&Arg2.Expr, 0)); + AddCodeLine (Store, ED_GetLabelName (&Arg1.Expr, 0)); + AddCodeLine ("bne %s", LocalLabelName (L1)); + + /* strcpy returns argument #1 */ + *Expr = Arg1.Expr; + + /* Bail out, no need for further processing */ + goto ExitPoint; } - AddCodeLine ("bne %s", LocalLabelName (L1)); - /* strcpy returns argument #1 */ - *Expr = Arg1.Expr; + if (ED_IsRVal (&Arg2.Expr) && ED_IsLocStack (&Arg2.Expr) && + StackPtr >= -255 && + ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) { - } else if (ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr) && - ED_IsRVal (&Arg1.Expr) && ED_IsLocStack (&Arg1.Expr) && - StackPtr >= -255) { + /* It is possible to just use one index register even if the stack + ** offset is not zero, by adjusting the offset to the constant + ** address accordingly. But we cannot do this if the data in + ** question is in the register space or at an absolute address less + ** than 256. Register space is zero page, which means that the + ** address calculation could overflow in the linker. + */ + int AllowOneIndex = !ED_IsLocRegister (&Arg1.Expr) && + !(ED_IsLocAbs (&Arg1.Expr) && Arg1.Expr.IVal < 256); - /* It is possible to just use one index register even if the stack - ** offset is not zero, by adjusting the offset to the constant - ** address accordingly. But we cannot do this if the data in - ** question is in the register space or at an absolute address less - ** than 256. Register space is zero page, which means that the - ** address calculation could overflow in the linker. - */ - int AllowOneIndex = !ED_IsLocRegister (&Arg2.Expr) && - !(ED_IsLocAbs (&Arg2.Expr) && Arg2.Expr.IVal < 256); + /* Calculate the real stack offset */ + int Offs = ED_GetStackOffs (&Arg2.Expr, 0); - /* Calculate the real stack offset */ - int Offs = ED_GetStackOffs (&Arg1.Expr, 0); + /* Drop the generated code */ + RemoveCode (&Arg1.Expr.Start); - /* Drop the generated code */ - RemoveCode (&Arg1.Expr.Start); + /* We need labels */ + L1 = GetLocalLabel (); - /* We need labels */ - L1 = GetLocalLabel (); + /* Generate strcpy code */ + AddCodeLine ("ldy #$%02X", (unsigned char) (Offs - 1)); + if (Offs == 0 || AllowOneIndex) { + g_defcodelabel (L1); + AddCodeLine ("iny"); + AddCodeLine ("lda (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 ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0)); + } + AddCodeLine ("bne %s", LocalLabelName (L1)); - /* Generate strcpy code */ - AddCodeLine ("ldy #$%02X", (unsigned char) (Offs - 1)); - if (Offs == 0 || AllowOneIndex) { - g_defcodelabel (L1); - AddCodeLine ("iny"); - AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs)); - AddCodeLine ("sta (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"); + /* strcpy returns argument #1 */ + *Expr = Arg1.Expr; + + /* Bail out, no need for further processing */ + goto ExitPoint; } - AddCodeLine ("bne %s", LocalLabelName (L1)); - /* strcpy returns argument #1 */ - *Expr = Arg1.Expr; + if (ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr) && + ED_IsRVal (&Arg1.Expr) && ED_IsLocStack (&Arg1.Expr) && + StackPtr >= -255) { - } else { + /* It is possible to just use one index register even if the stack + ** offset is not zero, by adjusting the offset to the constant + ** address accordingly. But we cannot do this if the data in + ** question is in the register space or at an absolute address less + ** than 256. Register space is zero page, which means that the + ** address calculation could overflow in the linker. + */ + int AllowOneIndex = !ED_IsLocRegister (&Arg2.Expr) && + !(ED_IsLocAbs (&Arg2.Expr) && Arg2.Expr.IVal < 256); - /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); - Expr->Type = GetFuncReturn (Expr->Type); + /* Calculate the real stack offset */ + int Offs = ED_GetStackOffs (&Arg1.Expr, 0); + /* Drop the generated code */ + RemoveCode (&Arg1.Expr.Start); + + /* We need labels */ + L1 = GetLocalLabel (); + + /* Generate strcpy code */ + AddCodeLine ("ldy #$%02X", (unsigned char) (Offs - 1)); + if (Offs == 0 || AllowOneIndex) { + g_defcodelabel (L1); + AddCodeLine ("iny"); + AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs)); + AddCodeLine ("sta (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 ("bne %s", LocalLabelName (L1)); + + /* strcpy returns argument #1 */ + *Expr = Arg1.Expr; + + /* Bail out, no need for further processing */ + goto ExitPoint; + } } + /* The function result is an rvalue in the primary register */ + ED_MakeRValExpr (Expr); + Expr->Type = GetFuncReturn (Expr->Type); + +ExitPoint: /* We expect the closing brace */ ConsumeRParen (); } @@ -1142,8 +1180,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) long ECount; unsigned L; - - /* Setup the argument type string */ ArgType[1].C = GetDefaultChar () | T_QUAL_CONST; @@ -1175,125 +1211,148 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Do type conversion */ TypeConversion (&Arg, ArgType); - /* If the expression is a literal, and if string literals are read - ** only, we can calculate the length of the string and remove it - ** from the literal pool. Otherwise we have to calculate the length - ** at runtime. - */ - if (ED_IsLocLiteral (&Arg) && IS_Get (&WritableStrings) == 0) { + if (IS_Get (&Optimize)) { - /* Constant string literal */ - ED_MakeConstAbs (Expr, GetLiteralSize (Arg.LVal) - 1, type_size_t); + /* If the expression is a literal, and if string literals are read + ** only, we can calculate the length of the string and remove it + ** from the literal pool. Otherwise we have to calculate the length + ** at runtime. + */ + if (ED_IsLocLiteral (&Arg) && IS_Get (&WritableStrings) == 0) { - /* We don't need the literal any longer */ - ReleaseLiteral (Arg.LVal); + /* Constant string literal */ + ED_MakeConstAbs (Expr, GetLiteralSize (Arg.LVal) - 1, type_size_t); - /* We will inline strlen for arrays with constant addresses, if either the - ** inlining was forced on the command line, or the array is smaller than - ** 256, so the inlining is considered safe. - */ - } else if (ED_IsLocConst (&Arg) && IsArray && - (IS_Get (&InlineStdFuncs) || IsByteIndex)) { - - /* Generate the strlen code */ - L = GetLocalLabel (); - AddCodeLine ("ldy #$FF"); - g_defcodelabel (L); - AddCodeLine ("iny"); - AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg, 0)); - AddCodeLine ("bne %s", LocalLabelName (L)); - AddCodeLine ("tax"); - AddCodeLine ("tya"); - - /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); - Expr->Type = type_size_t; - - /* We will inline strlen for arrays on the stack, if the array is - ** completely within the reach of a byte sized index register. - */ - } else if (ED_IsLocStack (&Arg) && IsArray && IsByteIndex && - (Arg.IVal - StackPtr) + ECount < 256) { - - /* Calculate the true stack offset */ - int Offs = ED_GetStackOffs (&Arg, 0); - - /* Generate the strlen code */ - L = GetLocalLabel (); - AddCodeLine ("ldx #$FF"); - AddCodeLine ("ldy #$%02X", (unsigned char) (Offs-1)); - g_defcodelabel (L); - AddCodeLine ("inx"); - AddCodeLine ("iny"); - AddCodeLine ("lda (sp),y"); - AddCodeLine ("bne %s", LocalLabelName (L)); - AddCodeLine ("txa"); - AddCodeLine ("ldx #$00"); - - /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); - Expr->Type = type_size_t; - - /* strlen for a string that is pointed to by a register variable will only - ** get inlined if requested on the command line, since we cannot know how - ** big the buffer actually is, so inlining is not always safe. - */ - } else if (ED_IsLocRegister (&Arg) && ED_IsLVal (&Arg) && IsPtr && - IS_Get (&InlineStdFuncs)) { - - /* Generate the strlen code */ - L = GetLocalLabel (); - AddCodeLine ("ldy #$FF"); - g_defcodelabel (L); - AddCodeLine ("iny"); - AddCodeLine ("lda (%s),y", ED_GetLabelName (&Arg, 0)); - AddCodeLine ("bne %s", LocalLabelName (L)); - AddCodeLine ("tax"); - AddCodeLine ("tya"); - - /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); - Expr->Type = type_size_t; - - /* Last check: We will inline a generic strlen routine if inlining was - ** requested on the command line, and the code size factor is more than - ** 400 (code is 13 bytes vs. 3 for a jsr call). - */ - } else if (IS_Get (&CodeSizeFactor) > 400 && IS_Get (&InlineStdFuncs)) { - - /* Load the expression into the primary */ - LoadExpr (CF_NONE, &Arg); - - /* Inline the function */ - L = GetLocalLabel (); - AddCodeLine ("sta ptr1"); - AddCodeLine ("stx ptr1+1"); - AddCodeLine ("ldy #$FF"); - g_defcodelabel (L); - AddCodeLine ("iny"); - AddCodeLine ("lda (ptr1),y"); - AddCodeLine ("bne %s", LocalLabelName (L)); - AddCodeLine ("tax"); - AddCodeLine ("tya"); - - /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); - Expr->Type = type_size_t; - - } else { - - /* Load the expression into the primary */ - LoadExpr (CF_NONE, &Arg); - - /* Call the strlen function */ - AddCodeLine ("jsr _%s", Func_strlen); - - /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); - Expr->Type = type_size_t; + /* We don't need the literal any longer */ + ReleaseLiteral (Arg.LVal); + /* Bail out, no need for further improvements */ + goto ExitPoint; + } } + if (IS_Get (&InlineStdFuncs)) { + + /* We will inline strlen for arrays with constant addresses, if either + ** requested on the command line, or the array is smaller than 256, + ** so the inlining is considered safe. + */ + if (ED_IsLocConst (&Arg) && IsArray && + (IS_Get (&EagerlyInlineFuncs) || IsByteIndex)) { + + /* Generate the strlen code */ + L = GetLocalLabel (); + AddCodeLine ("ldy #$FF"); + g_defcodelabel (L); + AddCodeLine ("iny"); + AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg, 0)); + AddCodeLine ("bne %s", LocalLabelName (L)); + AddCodeLine ("tax"); + AddCodeLine ("tya"); + + /* The function result is an rvalue in the primary register */ + ED_MakeRValExpr (Expr); + Expr->Type = type_size_t; + + /* Bail out, no need for further processing */ + goto ExitPoint; + } + + /* We will inline strlen for arrays on the stack, if the array is + ** completely within the reach of a byte sized index register. + */ + if (ED_IsLocStack (&Arg) && IsArray && IsByteIndex && + (Arg.IVal - StackPtr) + ECount < 256) { + + /* Calculate the true stack offset */ + int Offs = ED_GetStackOffs (&Arg, 0); + + /* Generate the strlen code */ + L = GetLocalLabel (); + AddCodeLine ("ldx #$FF"); + AddCodeLine ("ldy #$%02X", (unsigned char) (Offs-1)); + g_defcodelabel (L); + AddCodeLine ("inx"); + AddCodeLine ("iny"); + AddCodeLine ("lda (sp),y"); + AddCodeLine ("bne %s", LocalLabelName (L)); + AddCodeLine ("txa"); + AddCodeLine ("ldx #$00"); + + /* The function result is an rvalue in the primary register */ + ED_MakeRValExpr (Expr); + Expr->Type = type_size_t; + + /* Bail out, no need for further processing */ + goto ExitPoint; + } + + /* strlen for a string that is pointed to by a register variable will only + ** get inlined if requested on the command line, since we cannot know how + ** big the buffer actually is, so inlining is not always safe. + */ + if (ED_IsLocRegister (&Arg) && ED_IsLVal (&Arg) && IsPtr && + IS_Get (&EagerlyInlineFuncs)) { + + /* Generate the strlen code */ + L = GetLocalLabel (); + AddCodeLine ("ldy #$FF"); + g_defcodelabel (L); + AddCodeLine ("iny"); + AddCodeLine ("lda (%s),y", ED_GetLabelName (&Arg, 0)); + AddCodeLine ("bne %s", LocalLabelName (L)); + AddCodeLine ("tax"); + AddCodeLine ("tya"); + + /* The function result is an rvalue in the primary register */ + ED_MakeRValExpr (Expr); + Expr->Type = type_size_t; + + /* Bail out, no need for further processing */ + goto ExitPoint; + } + + /* Last check: We will inline a generic strlen routine if inlining was + ** requested on the command line, and the code size factor is more than + ** 400 (code is 13 bytes vs. 3 for a jsr call). + */ + if (IS_Get (&CodeSizeFactor) > 400 && IS_Get (&EagerlyInlineFuncs)) { + + /* Load the expression into the primary */ + LoadExpr (CF_NONE, &Arg); + + /* Inline the function */ + L = GetLocalLabel (); + AddCodeLine ("sta ptr1"); + AddCodeLine ("stx ptr1+1"); + AddCodeLine ("ldy #$FF"); + g_defcodelabel (L); + AddCodeLine ("iny"); + AddCodeLine ("lda (ptr1),y"); + AddCodeLine ("bne %s", LocalLabelName (L)); + AddCodeLine ("tax"); + AddCodeLine ("tya"); + + /* The function result is an rvalue in the primary register */ + ED_MakeRValExpr (Expr); + Expr->Type = type_size_t; + + /* Bail out, no need for further processing */ + goto ExitPoint; + } + } + + /* Load the expression into the primary */ + LoadExpr (CF_NONE, &Arg); + + /* Call the strlen function */ + AddCodeLine ("jsr _%s", Func_strlen); + + /* The function result is an rvalue in the primary register */ + ED_MakeRValExpr (Expr); + Expr->Type = type_size_t; + +ExitPoint: /* We expect the closing brace */ ConsumeRParen (); } From 9b345099569af702175cf89f3ef29838c4eeac46 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 4 Apr 2017 00:41:40 +0200 Subject: [PATCH 0285/2161] Use the more explicit tag style for recently added internal links. --- doc/cc65.sgml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 9322a2d44..827b63c80 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -247,10 +247,10 @@ Here is a description of all the command line options: <p> </itemize> - <tt/--eagerly-inline-funcs/ implies the <tt/<ref id="option-inline-stdfuncs" - name="--inline-stdfuncs"/ command line option. + <tt/--eagerly-inline-funcs/ implies the <tt><ref id="option-inline-stdfuncs" + name="--inline-stdfuncs"></tt> command line option. - See also <tt/<ref id="pragma-allow-eager-inline" name="#pragma allow-eager-inline">/. + See also <tt><ref id="pragma-allow-eager-inline" name="#pragma allow-eager-inline"></tt>. <tag><tt>-h, --help</tt></tag> @@ -263,9 +263,9 @@ Here is a description of all the command line options: Allow the compiler to inline some standard functions from the C library like strlen. This will not only remove the overhead for a function call, but will - make the code visible for the optimizer. See also the <tt/<ref id="option-O" - name="-Os"/ command line option and <tt/<ref id="pragma-inline-stdfuncs" - name="#pragma inline-stdfuncs">/. + make the code visible for the optimizer. See also the <tt><ref id="option-O" + name="-Os"></tt> command line option and <tt><ref id="pragma-inline-stdfuncs" + name="#pragma inline-stdfuncs"></tt>. <label id="option-list-warnings"> @@ -861,8 +861,8 @@ The compiler defines several macros at startup: <tag><tt>__EAGERLY_INLINE_FUNCS__</tt></tag> - Is defined if the compiler was called with the <tt/<ref id="option-eagerly-inline-funcs" - name="--eagerly-inline-funcs"/ command line option. + Is defined if the compiler was called with the <tt><ref id="option-eagerly-inline-funcs" + name="--eagerly-inline-funcs"></tt> command line option. <tag><tt>__FILE__</tt></tag> @@ -965,9 +965,9 @@ parameter with the <tt/#pragma/. Allow eager inlining of known functions. If the argument is "off", eager inlining is disabled, otherwise it is enabled. Please note that (in contrast - to the <tt/<ref id="option-eagerly-inline-funcs" name="--eagerly-inline-funcs"/ - command line option) this pragma does not imply the <tt/<ref id="option-inline-stdfuncs" - name="--inline-stdfuncs"/ command line option. Rather it marks code to be safe for + to the <tt><ref id="option-eagerly-inline-funcs" name="--eagerly-inline-funcs"></tt> + command line option) this pragma does not imply the <tt><ref id="option-inline-stdfuncs" + name="--inline-stdfuncs"></tt> command line option. Rather it marks code to be safe for eager inlining of known functions if inlining of standard functions is enabled. The <tt/#pragma/ understands the push and pop parameters as explained above. From 3b17c3a411a6e1b2099124a76f581fe5d1d79870 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 4 Apr 2017 07:23:05 -0400 Subject: [PATCH 0286/2161] Fixed 2 typoes. Warning messages from nsgmls usually mean a typing mistake a few lines above the first line that's named by nsgmls. --- doc/cc65.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 827b63c80..653a917db 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -491,7 +491,7 @@ Here is a description of all the command line options: Using <tt/-Os/ will allow the compiler to inline some standard functions from the C library like strlen. This will not only remove the overhead for a function call, but will make the code visible for the optimizer. - See also <tt/<ref id="option-inline-stdfuncs" name="--inline-stdfuncs"/. + See also <tt/<ref id="option-inline-stdfuncs" name="--inline-stdfuncs">/. It is possible to concatenate the modifiers for <tt/-O/. For example, to enable register variables and inlining of standard functions, you may use @@ -1098,7 +1098,7 @@ parameter with the <tt/#pragma/. Allow the compiler to inline some standard functions from the C library like strlen. If the argument is "off", inlining is disabled, otherwise it is enabled. - See also the the <tt/<ref id="option-inline-stdfuncs" name="--inline-stdfuncs"/ + See also the the <tt/<ref id="option-inline-stdfuncs" name="--inline-stdfuncs">/ command line option. The <tt/#pragma/ understands the push and pop parameters as explained above. From 4e856546c17603b772b4b239d8cc5caec8d88833 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 4 Apr 2017 13:42:57 +0200 Subject: [PATCH 0287/2161] Minor language update. --- doc/cc65.sgml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 653a917db..24b37133e 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -491,7 +491,8 @@ Here is a description of all the command line options: Using <tt/-Os/ will allow the compiler to inline some standard functions from the C library like strlen. This will not only remove the overhead for a function call, but will make the code visible for the optimizer. - See also <tt/<ref id="option-inline-stdfuncs" name="--inline-stdfuncs">/. + See also the <tt/<ref id="option-inline-stdfuncs" name="--inline-stdfuncs">/ + command line option. It is possible to concatenate the modifiers for <tt/-O/. For example, to enable register variables and inlining of standard functions, you may use @@ -1098,7 +1099,7 @@ parameter with the <tt/#pragma/. Allow the compiler to inline some standard functions from the C library like strlen. If the argument is "off", inlining is disabled, otherwise it is enabled. - See also the the <tt/<ref id="option-inline-stdfuncs" name="--inline-stdfuncs">/ + See also the <tt/<ref id="option-inline-stdfuncs" name="--inline-stdfuncs">/ command line option. The <tt/#pragma/ understands the push and pop parameters as explained above. From 275b27647ed4eeb9da98bd3227002046a52291df Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 4 Apr 2017 15:43:56 +0200 Subject: [PATCH 0288/2161] Removed superfluous final linefeed. --- libsrc/runtime/axlong.s | 1 - 1 file changed, 1 deletion(-) diff --git a/libsrc/runtime/axlong.s b/libsrc/runtime/axlong.s index 02d0a825c..1fbd53ef0 100644 --- a/libsrc/runtime/axlong.s +++ b/libsrc/runtime/axlong.s @@ -19,4 +19,3 @@ axulong: store: sty sreg sty sreg+1 rts - From 14268510f59211d4b491d3eec937ea703a83bf0d Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 4 Apr 2017 15:45:24 +0200 Subject: [PATCH 0289/2161] Removed workaround. --- test/val/lib_common_memmove.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/test/val/lib_common_memmove.c b/test/val/lib_common_memmove.c index 6c04e1951..6b2273e78 100644 --- a/test/val/lib_common_memmove.c +++ b/test/val/lib_common_memmove.c @@ -1,7 +1,3 @@ -// temporarily disable optimizations altogether until a fine grain control -// is implemented on Makefile level only disabling the compiler option -Os -#pragma optimize (off) - #include <string.h> #include "unittest.h" @@ -10,7 +6,6 @@ static char Buffer[BufferSize+3]; // +1 to move up (and down) - TEST { unsigned i, v; @@ -61,5 +56,3 @@ TEST } } ENDTEST - - From 3789174162b5a5e81703fdb3f2a8e584d428f885 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 4 Apr 2017 15:51:00 +0200 Subject: [PATCH 0290/2161] Removed workaround. --- test/val/lib_common_strcat.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/val/lib_common_strcat.c b/test/val/lib_common_strcat.c index 6389d5651..1872053a4 100644 --- a/test/val/lib_common_strcat.c +++ b/test/val/lib_common_strcat.c @@ -1,7 +1,3 @@ -// temporarily disable optimizations altogether until a fine grain control -// is implemented on Makefile level only disabling the compiler option -Os -#pragma optimize (off) - #include <string.h> #include "unittest.h" From cd27fef6a8b2b58db36eaef767cda1a09ee2ac8c Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 4 Apr 2017 15:52:01 +0200 Subject: [PATCH 0291/2161] Removed workaround. --- test/val/lib_common_strcspn.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/test/val/lib_common_strcspn.c b/test/val/lib_common_strcspn.c index 06838c435..f289ddb95 100644 --- a/test/val/lib_common_strcspn.c +++ b/test/val/lib_common_strcspn.c @@ -1,7 +1,3 @@ -// temporarily disable optimizations altogether until a fine grain control -// is implemented on Makefile level only disabling the compiler option -Os -#pragma optimize (off) - #include <string.h> #include "unittest.h" @@ -11,6 +7,7 @@ static char EstimatedString[EstimatedStringSize+1]; // +1 room for terminati static char* EmptyTestChars=""; // strlen equivalent... static char* TestChars="1234567890"; // we like to find numbers + TEST { unsigned i; @@ -26,5 +23,3 @@ TEST ASSERT_AreEqual(strlen(EstimatedString), strcspn(EstimatedString, EmptyTestChars), "%u", "Unxpected position returned for empty test case!"); } ENDTEST - - From 93193727be4bcebfa1d728b2b948a0ebba116e43 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 4 Apr 2017 15:52:37 +0200 Subject: [PATCH 0292/2161] Removed workaround. --- test/val/lib_common_strncat.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/val/lib_common_strncat.c b/test/val/lib_common_strncat.c index 84d904fa0..a6f92ac05 100644 --- a/test/val/lib_common_strncat.c +++ b/test/val/lib_common_strncat.c @@ -1,7 +1,3 @@ -// temporarily disable optimizations altogether until a fine grain control -// is implemented on Makefile level only disabling the compiler option -Os -#pragma optimize (off) - #include <string.h> #include "unittest.h" @@ -54,5 +50,3 @@ TEST } } ENDTEST - - From e8065155416c060da83b03007ad17e9a837df2aa Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 4 Apr 2017 15:53:14 +0200 Subject: [PATCH 0293/2161] Removed workaround. --- test/val/lib_common_strspn.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/val/lib_common_strspn.c b/test/val/lib_common_strspn.c index 693a1136a..96a006469 100644 --- a/test/val/lib_common_strspn.c +++ b/test/val/lib_common_strspn.c @@ -1,7 +1,3 @@ -// temporarily disable optimizations altogether until a fine grain control -// is implemented on Makefile level only disabling the compiler option -Os -#pragma optimize (off) - #include <string.h> #include "unittest.h" From dce5783dc96bbf9165e8815c9df1314818241cb7 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 4 Apr 2017 13:23:44 -0400 Subject: [PATCH 0294/2161] Fixed the simulations of the stack pointer and the "break" and decimal-mode flags. * The pointer wraps around the stack page. * The break flag exists on only the stack, and only after an interrupt. * 65C02 interrupts clear the decimal-mode flag. --- src/sim65/6502.c | 57 +++++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index 81caff4da..1febef657 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -34,14 +34,12 @@ /* 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 + BBRx, BBSx, RMBx, SMBx, WAI, and STP are unsupported * BCD flag handling equals 6502 (unchecked if bug is simulated or wrong for 6502) * one cycle win for fetch-modify-write instructions ignored - (e.g. ROL abs,x takes only 6 cycles if no page break occurs) - * BRK, IRQ, NMI and RESET are not different from 6502 which they are in - reality (e.g. D-flag handling) - */ + (e.g., ROL abs,x takes only 6 cycles if no page break occurs) +*/ #include "memory.h" #include "error.h" @@ -87,12 +85,11 @@ int PrintCycles; -/* Return the flags as a boolean value (0/1) */ +/* Return the flags as boolean values (0/1) */ #define GET_CF() ((Regs.SR & CF) != 0) #define GET_ZF() ((Regs.SR & ZF) != 0) #define GET_IF() ((Regs.SR & IF) != 0) #define GET_DF() ((Regs.SR & DF) != 0) -#define GET_BF() ((Regs.SR & BF) != 0) #define GET_OF() ((Regs.SR & OF) != 0) #define GET_SF() ((Regs.SR & SF) != 0) @@ -103,7 +100,6 @@ int PrintCycles; #define SET_ZF(f) do { if (f) { Regs.SR |= ZF; } else { Regs.SR &= ~ZF; } } while (0) #define SET_IF(f) do { if (f) { Regs.SR |= IF; } else { Regs.SR &= ~IF; } } while (0) #define SET_DF(f) do { if (f) { Regs.SR |= DF; } else { Regs.SR &= ~DF; } } while (0) -#define SET_BF(f) do { if (f) { Regs.SR |= BF; } else { Regs.SR &= ~BF; } } while (0) #define SET_OF(f) do { if (f) { Regs.SR |= OF; } else { Regs.SR &= ~OF; } } while (0) #define SET_SF(f) do { if (f) { Regs.SR |= SF; } else { Regs.SR &= ~SF; } } while (0) @@ -119,8 +115,8 @@ int PrintCycles; #define PCH ((Regs.PC >> 8) & 0xFF) /* Stack operations */ -#define PUSH(Val) MemWriteByte (0x0100 + Regs.SP--, Val) -#define POP() MemReadByte (0x0100 + ++Regs.SP) +#define PUSH(Val) MemWriteByte (0x0100 | (Regs.SP-- & 0xFF), Val) +#define POP() MemReadByte (0x0100 | (++Regs.SP & 0xFF)) /* Test for page cross */ #define PAGE_CROSS(addr,offs) ((((addr) & 0xFF) + offs) >= 0x100) @@ -376,11 +372,14 @@ static void OPC_6502_00 (void) { Cycles = 7; Regs.PC += 2; - SET_BF (1); PUSH (PCH); PUSH (PCL); PUSH (Regs.SR); SET_IF (1); + if (CPU != CPU_6502) + { + SET_DF (0); + } Regs.PC = MemReadWord (0xFFFE); } @@ -403,7 +402,7 @@ static void OPC_65SC02_04 (void) ZPAddr = MemReadByte (Regs.PC+1); Val = MemReadByte (ZPAddr); SET_ZF ((Val & Regs.AC) == 0); - MemWriteByte (ZPAddr, (unsigned char)(Val | Regs.AC)); + MemWriteByte (ZPAddr, (unsigned char)(Val | Regs.AC)); Regs.PC += 2; } @@ -438,7 +437,7 @@ static void OPC_6502_08 (void) /* Opcode $08: PHP */ { Cycles = 3; - PUSH (Regs.SR & ~BF); + PUSH (Regs.SR); Regs.PC += 1; } @@ -475,7 +474,7 @@ static void OPC_65SC02_0C (void) Addr = MemReadWord (Regs.PC+1); Val = MemReadByte (Addr); SET_ZF ((Val & Regs.AC) == 0); - MemWriteByte (Addr, (unsigned char) (Val | Regs.AC)); + MemWriteByte (Addr, (unsigned char) (Val | Regs.AC)); Regs.PC += 3; } @@ -539,7 +538,7 @@ static void OPC_65SC02_14 (void) ZPAddr = MemReadByte (Regs.PC+1); Val = MemReadByte (ZPAddr); SET_ZF ((Val & Regs.AC) == 0); - MemWriteByte (ZPAddr, (unsigned char)(Val & ~Regs.AC)); + MemWriteByte (ZPAddr, (unsigned char)(Val & ~Regs.AC)); Regs.PC += 2; } @@ -609,7 +608,7 @@ static void OPC_65SC02_1C (void) Addr = MemReadWord (Regs.PC+1); Val = MemReadByte (Addr); SET_ZF ((Val & Regs.AC) == 0); - MemWriteByte (Addr, (unsigned char) (Val & ~Regs.AC)); + MemWriteByte (Addr, (unsigned char) (Val & ~Regs.AC)); Regs.PC += 3; } @@ -707,7 +706,9 @@ static void OPC_6502_28 (void) /* Opcode $28: PLP */ { Cycles = 4; - Regs.SR = (POP () & ~BF); + + /* Bits 5 and 4 aren't used, and always are 1! */ + Regs.SR = (POP () | 0x30); Regs.PC += 1; } @@ -909,7 +910,9 @@ static void OPC_6502_40 (void) /* Opcode $40: RTI */ { Cycles = 6; - Regs.SR = POP (); + + /* Bits 5 and 4 aren't used, and always are 1! */ + Regs.SR = POP () | 0x30; Regs.PC = POP (); /* PCL */ Regs.PC |= (POP () << 8); /* PCH */ } @@ -2011,7 +2014,7 @@ static void OPC_6502_BA (void) /* Opcode $BA: TSX */ { Cycles = 2; - Regs.XR = Regs.SP; + Regs.XR = Regs.SP & 0xFF; TEST_ZF (Regs.XR); TEST_SF (Regs.XR); Regs.PC += 1; @@ -3213,7 +3216,9 @@ void Reset (void) /* Reset the CPU */ HaveIRQRequest = 0; HaveNMIRequest = 0; - Regs.SR = 0; + + /* Bits 5 and 4 aren't used, and always are 1! */ + Regs.SR = 0x30; Regs.PC = MemReadWord (0xFFFC); } @@ -3228,8 +3233,12 @@ unsigned ExecuteInsn (void) HaveNMIRequest = 0; PUSH (PCH); PUSH (PCL); - PUSH (Regs.SR); + PUSH (Regs.SR & ~BF); SET_IF (1); + if (CPU != CPU_6502) + { + SET_DF (0); + } Regs.PC = MemReadWord (0xFFFA); Cycles = 7; @@ -3238,8 +3247,12 @@ unsigned ExecuteInsn (void) HaveIRQRequest = 0; PUSH (PCH); PUSH (PCL); - PUSH (Regs.SR); + PUSH (Regs.SR & ~BF); SET_IF (1); + if (CPU != CPU_6502) + { + SET_DF (0); + } Regs.PC = MemReadWord (0xFFFE); Cycles = 7; From be772c0198f2d978171e0f35b5e1f71d27c414f6 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 6 Apr 2017 12:22:39 +0200 Subject: [PATCH 0295/2161] Bumped version. As suggested the incompatibility resulting from https://github.com/cc65/cc65/commit/02daf9f8b5c1ae2267561ee05ce67b2d0393c12d makes a new version appropriate. --- src/common/version.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/version.c b/src/common/version.c index 4e61a5f83..bf0a6bf71 100644 --- a/src/common/version.c +++ b/src/common/version.c @@ -47,7 +47,7 @@ #define VER_MAJOR 2U -#define VER_MINOR 15U +#define VER_MINOR 16U From e43dbe1c24a14416b8a2802af17ecd237deef25d Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 6 Apr 2017 17:53:57 +0200 Subject: [PATCH 0296/2161] Just some white space fixes of recently contributed code. --- libsrc/common/strcat.s | 4 ++-- libsrc/common/strchr.s | 4 ++-- libsrc/common/strcspn.s | 5 ++--- libsrc/common/strncat.s | 2 -- libsrc/common/strspn.s | 5 ++--- 5 files changed, 8 insertions(+), 12 deletions(-) diff --git a/libsrc/common/strcat.s b/libsrc/common/strcat.s index 7dce2f78a..f9cd94633 100644 --- a/libsrc/common/strcat.s +++ b/libsrc/common/strcat.s @@ -21,7 +21,7 @@ _strcat: .else lda #0 sta ptr2 ; access from page start, y contains low byte -.endif +.endif stx ptr2+1 findEndOfDest: @@ -33,7 +33,7 @@ findEndOfDest: bne findEndOfDest endOfDestFound: - sty ptr2 ; advance pointer to last y position + sty ptr2 ; advance pointer to last y position ldy #0 ; reset new y-offset copyByte: diff --git a/libsrc/common/strchr.s b/libsrc/common/strchr.s index 15c743776..206b5160e 100644 --- a/libsrc/common/strchr.s +++ b/libsrc/common/strchr.s @@ -20,7 +20,7 @@ _strchr: .else lda #0 sta ptr1 ; access from page start, y contains low byte -.endif +.endif Loop: lda (ptr1),y ; Get next char beq EOS ; Jump on end of string @@ -29,7 +29,7 @@ Loop: lda (ptr1),y ; Get next char iny bne Loop inc ptr1+1 - bne Loop ; Branch always + bne Loop ; Branch always ; End of string. Check if we're searching for the terminating zero diff --git a/libsrc/common/strcspn.s b/libsrc/common/strcspn.s index 3f7b42ed1..c9122dc90 100644 --- a/libsrc/common/strcspn.s +++ b/libsrc/common/strcspn.s @@ -40,7 +40,7 @@ checkNext: check: cpy tmp1 ; compare with length of test character string beq endOfTestChars cmp (ptr1),y ; found matching char? - bne checkNext + bne checkNext leave: txa ; restore position of finding ldx tmp2 ; and return @@ -50,5 +50,4 @@ endOfTestChars: inx bne loadChar inc tmp2 - bne loadChar ; like bra... - + bne loadChar ; like bra... diff --git a/libsrc/common/strncat.s b/libsrc/common/strncat.s index e0fa39cc0..457e39e25 100644 --- a/libsrc/common/strncat.s +++ b/libsrc/common/strncat.s @@ -71,5 +71,3 @@ L6: lda #0 L7: lda ptr3 ldx ptr3+1 rts - - diff --git a/libsrc/common/strspn.s b/libsrc/common/strspn.s index 3316f0dab..079b935ee 100644 --- a/libsrc/common/strspn.s +++ b/libsrc/common/strspn.s @@ -40,15 +40,14 @@ checkNext: check: cpy tmp1 ; compare with length of test character string beq leave cmp (ptr1),y ; found matching char? - bne checkNext + bne checkNext foundTestChar: inx bne loadChar inc tmp2 - bne loadChar ; like bra... + bne loadChar ; like bra... leave: txa ; restore position of finding ldx tmp2 ; and return rts - \ No newline at end of file From 1aab28718915964b33ae87a70617966719364663 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 7 Apr 2017 09:26:58 -0400 Subject: [PATCH 0297/2161] Fixed the handling of "while (0) {}". It's a corner case; but, conditional macroes might create it -- better safe than sorry. --- src/cc65/stmt.c | 6 +-- test/val/while.c | 116 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 88 insertions(+), 34 deletions(-) diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 84b516dc3..c6167fa78 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -273,9 +273,6 @@ static void WhileStatement (void) /* Remember the current position */ GetCodePos (&CondCodeStart); - /* Emit the code position label */ - g_defcodelabel (CondLabel); - /* Test the loop condition */ TestInParens (LoopLabel, 1); @@ -288,6 +285,9 @@ static void WhileStatement (void) /* Loop body */ Statement (&PendingToken); + /* Emit the while condition label */ + g_defcodelabel (CondLabel); + /* Move the test code here */ GetCodePos (&Here); MoveCode (&CondCodeStart, &CondCodeEnd, &Here); diff --git a/test/val/while.c b/test/val/while.c index cf2147052..b86b1fba5 100644 --- a/test/val/while.c +++ b/test/val/while.c @@ -1,53 +1,107 @@ /* - !!DESCRIPTION!! + !!DESCRIPTION!! while-condition tests !!ORIGIN!! SDCC regression tests !!LICENCE!! GPL, read COPYING.GPL */ #include <stdio.h> -#include <limits.h> -unsigned char success = 0; -unsigned char failures = 0; -unsigned char dummy = 0; +static unsigned char failures = 0x00; +static unsigned char achar0 = 0; -#ifdef SUPPORT_BIT_TYPES -bit bit0 = 0; -#endif -unsigned int aint0 = 0; -unsigned int aint1 = 0; -unsigned char achar0 = 0; -unsigned char achar1 = 0; - -void -done () -{ - dummy++; -} - -void +static void while1 (void) { unsigned char i = 10; - do - { - achar0++; - } - while (--i); + do { + ++achar0; + } while (--i); - if (achar0 != 10) - failures++; + if (achar0 != 10) { + failures |= 0x01; + } +} + +static void +while2 (void) +{ + unsigned char i = 10; + + achar0 = 0; + while (--i) { + ++achar0; + } + + if (achar0 != 10 - 1) { + failures |= 0x02; + } +} + +static void +while3 (void) +{ + achar0 = 0; + do { + if (++achar0 == (unsigned char)0) { + return; + } + } while (1); + + failures |= 0x04; +} + +static void +while4 (void) +{ + achar0 = 0; + while (1) { + if (++achar0 == (unsigned char)0) { + return; + } + } + + failures |= 0x08; +} + +static void +while5 (void) +{ + achar0 = 0; + do { + ++achar0; + } while (0); + + if (achar0 != 1) { + failures |= 0x10; + } +} + +static void +while6 (void) +{ + achar0 = 0; + while (0) { + ++achar0; + } + + if (achar0 != 1 - 1) { + failures |= 0x20; + } } int main (void) { while1 (); + while2 (); + while3 (); + while4 (); + while5 (); + while6 (); - success = failures; - done (); - printf("failures: %d\n",failures); - + if (failures) { + printf("failures: 0x%02X\n", failures); + } return failures; } From 18b0aaf9f20229812ad09b87684fe5bc7e06c319 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 15 Apr 2017 23:12:19 +0200 Subject: [PATCH 0298/2161] Removed help for non-existent option. --- src/ca65/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ca65/main.c b/src/ca65/main.c index 3c3daf7f7..fbca2beac 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -123,7 +123,6 @@ static void Usage (void) " --large-alignment\t\tDon't warn about large alignments\n" " --listing name\t\tCreate a listing file if assembly was ok\n" " --list-bytes n\t\tMaximum number of bytes per listing line\n" - " --macpack-dir dir\t\tSet a macro package directory\n" " --memory-model model\t\tSet the memory model\n" " --pagelength n\t\tSet the page length for the listing\n" " --relax-checks\t\tRelax some checks (see docs)\n" From 82e62209d696dcb082bd67e227dd5fe30256c776 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Mon, 1 May 2017 19:50:01 +0300 Subject: [PATCH 0299/2161] Document pragma trampoline --- doc/cc65.sgml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24b37133e..99ddfc82d 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1209,6 +1209,31 @@ parameter with the <tt/#pragma/. The <tt/#pragma/ understands the push and pop parameters as explained above. +<sect1><tt>#pragma trampoline (<push&rt;, <name>, <value>)</tt><label id="pragma-trampoline"><p> + + This pragma sets a trampoline for functions. The name is either + a function returning void and taking no parameters, or the address + of an array in memory (for a RAM trampoline). The value is an + 8-bit number that's set to tmp4. + + The address of the function is passed in ptr4. + + This is useful for example with banked memory, to automatically + switch banks to where this function resides, and then restore + the bank when it returns. + + The <tt/#pragma/ requires the push and pop parameters as explained above. + + Example: + <tscreen><verb> + void mytrampoline(void); + + #pragma trampoline (push, mytrampoline, 0) + void somefunc(void); + #pragma trampoline (pop) + </verb></tscreen> + + <sect1><tt>#pragma warn (name, [push,] on|off)</tt><label id="pragma-warn"><p> Switch compiler warnings on or off. "name" is the name of a warning (see the From a84463a3dfb74b200fc208ab30f89de54631a846 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Mon, 1 May 2017 20:12:18 +0300 Subject: [PATCH 0300/2161] callptr4 --- libsrc/runtime/callptr4.s | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 libsrc/runtime/callptr4.s diff --git a/libsrc/runtime/callptr4.s b/libsrc/runtime/callptr4.s new file mode 100644 index 000000000..9a15609aa --- /dev/null +++ b/libsrc/runtime/callptr4.s @@ -0,0 +1,10 @@ +; +; CC65 runtime: call function via pointer in ptr4 +; + + .export callptr4 + .importzp ptr4 + +callptr4: + jmp (ptr4) ; jump there + From 679bfb0ae9353646e78a981941d525ea86b44e88 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Mon, 1 May 2017 20:46:06 +0300 Subject: [PATCH 0301/2161] Add IntPtrStack --- src/common/intptrstack.c | 90 +++++++++++++++++++++++++++++ src/common/intptrstack.h | 121 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 src/common/intptrstack.c create mode 100644 src/common/intptrstack.h diff --git a/src/common/intptrstack.c b/src/common/intptrstack.c new file mode 100644 index 000000000..de02c09e7 --- /dev/null +++ b/src/common/intptrstack.c @@ -0,0 +1,90 @@ +/*****************************************************************************/ +/* */ +/* intptrstack.c */ +/* */ +/* Integer+ptr stack used for program settings */ +/* */ +/* */ +/* */ +/* (C) 2017, Mega Cat Studios */ +/* */ +/* */ +/* 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. */ +/* */ +/*****************************************************************************/ + + + +/* common */ +#include "check.h" +#include "intptrstack.h" + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +void IPS_Get (const IntPtrStack* S, long *Val, void **Ptr) +/* Get the value on top of an int stack */ +{ + PRECONDITION (S->Count > 0); + if (Val) *Val = S->Stack[S->Count-1].val; + if (Ptr) *Ptr = S->Stack[S->Count-1].ptr; +} + + + +void IPS_Set (IntPtrStack* S, long Val, void *Ptr) +/* Set the value on top of an int stack */ +{ + PRECONDITION (S->Count > 0); + S->Stack[S->Count-1].val = Val; + S->Stack[S->Count-1].ptr = Ptr; +} + + + +void IPS_Drop (IntPtrStack* S) +/* Drop a value from an int stack */ +{ + PRECONDITION (S->Count > 0); + --S->Count; +} + + + +void IPS_Push (IntPtrStack* S, long Val, void *Ptr) +/* Push a value onto an int stack */ +{ + PRECONDITION (S->Count < sizeof (S->Stack) / sizeof (S->Stack[0])); + S->Stack[S->Count].val = Val; + S->Stack[S->Count++].ptr = Ptr; +} + + + +void IPS_Pop (IntPtrStack* S, long *Val, void **Ptr) +/* Pop a value from an int stack */ +{ + PRECONDITION (S->Count > 0); + if (Val) *Val = S->Stack[--S->Count].val; + if (Ptr) *Ptr = S->Stack[S->Count].ptr; +} diff --git a/src/common/intptrstack.h b/src/common/intptrstack.h new file mode 100644 index 000000000..a7b1c6683 --- /dev/null +++ b/src/common/intptrstack.h @@ -0,0 +1,121 @@ +/*****************************************************************************/ +/* */ +/* intptrstack.h */ +/* */ +/* Integer+ptr stack used for program settings */ +/* */ +/* */ +/* */ +/* (C) 2017, Mega Cat Studios */ +/* */ +/* */ +/* 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 INTPTRSTACK_H +#define INTPTRSTACK_H + + + +#include "inline.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +typedef struct IntPtrStack IntPtrStack; +struct IntPtrInner { + long val; + void *ptr; +}; +struct IntPtrStack { + unsigned Count; + struct IntPtrInner Stack[8]; +}; + +/* An initializer for an empty int stack */ +#define STATIC_INTPTRSTACK_INITIALIZER { 0, { 0, 0 }, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0} } } + +/* Declare an int stack with the given value as first element */ +#define INTPTRSTACK(Val, Ptr) { 1, { {Val, Ptr}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0} } } + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +#if defined(HAVE_INLINE) +INLINE int IPS_IsFull (const IntPtrStack* S) +/* Return true if there is no space left on the given int stack */ +{ + return (S->Count >= sizeof (S->Stack) / sizeof (S->Stack[0])); +} +#else +# define IPS_IsFull(S) ((S)->Count >= sizeof ((S)->Stack) / sizeof ((S)->Stack[0])) +#endif + +#if defined(HAVE_INLINE) +INLINE int IPS_IsEmpty (const IntPtrStack* S) +/* Return true if there are no values on the given int stack */ +{ + return (S->Count == 0); +} +#else +# define IPS_IsEmpty(S) ((S)->Count == 0) +#endif + +#if defined(HAVE_INLINE) +INLINE unsigned IPS_GetCount (const IntPtrStack* S) +/* Return the number of elements on the given int stack */ +{ + return S->Count; +} +#else +# define IPS_GetCount(S) (S)->Count +#endif + +void IPS_Get (const IntPtrStack* S, long *Val, void **Ptr); +/* Get the value on top of an int stack */ + +void IPS_Set (IntPtrStack* S, long Val, void *Ptr); +/* Set the value on top of an int stack */ + +void IPS_Drop (IntPtrStack* S); +/* Drop a value from an int stack */ + +void IPS_Push (IntPtrStack* S, long Val, void *Ptr); +/* Push a value onto an int stack */ + +void IPS_Pop (IntPtrStack* S, long *Val, void **Ptr); +/* Pop a value from an int stack */ + + + +/* End of IntPtrStack.h */ + +#endif From d091a57e918244f0d6a7b651b908f7f08a2cee95 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Mon, 1 May 2017 21:00:28 +0300 Subject: [PATCH 0302/2161] Trampoline stack --- src/cc65/trampoline.c | 102 ++++++++++++++++++++++++++++++++++++++++++ src/cc65/trampoline.h | 65 +++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 src/cc65/trampoline.c create mode 100644 src/cc65/trampoline.h diff --git a/src/cc65/trampoline.c b/src/cc65/trampoline.c new file mode 100644 index 000000000..1f35a0f3c --- /dev/null +++ b/src/cc65/trampoline.c @@ -0,0 +1,102 @@ +/*****************************************************************************/ +/* */ +/* trampoline.c */ +/* */ +/* Trampoline management */ +/* */ +/* */ +/* */ +/* (C) 2017, Mega Cat Studios */ +/* */ +/* */ +/* 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 <stdarg.h> +#include <string.h> + +/* common */ +#include "chartype.h" +#include "check.h" +#include "coll.h" +#include "scanner.h" +#include "intptrstack.h" +#include "xmalloc.h" + +/* cc65 */ +#include "codeent.h" +#include "error.h" +#include "trampoline.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + +/* Trampolines */ +static IntPtrStack Trampolines; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +void PushTrampoline (void *Ptr, unsigned char Val) +/* Push the current trampoline */ +{ + if (IPS_IsFull (&Trampolines)) { + Error ("Trampoline stack overflow"); + } else { + IPS_Push (&Trampolines, Val, Ptr); + } +} + + + +void PopTrampoline (void) +/* Remove the current trampoline */ +{ + if (IPS_GetCount (&Trampolines) < 1) { + Error ("Trampoline stack is empty"); + } else { + IPS_Drop (&Trampolines); + } +} + + + +void GetTrampoline (void **Ptr, unsigned char *Val) +/* Get the current trampoline */ +{ + if (IPS_GetCount (&Trampolines) < 1) { + *Ptr = NULL; + *Val = 0; + } else { + long Temp; + IPS_Get (&Trampolines, &Temp, Ptr); + *Val = Temp; + } +} diff --git a/src/cc65/trampoline.h b/src/cc65/trampoline.h new file mode 100644 index 000000000..f110bd42e --- /dev/null +++ b/src/cc65/trampoline.h @@ -0,0 +1,65 @@ +/*****************************************************************************/ +/* */ +/* trampoline.h */ +/* */ +/* Trampoline management */ +/* */ +/* */ +/* */ +/* (C) 2017, Mega Cat Studios */ +/* */ +/* */ +/* 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 TRAMPOLINE_H +#define TRAMPOLINE_H + + + +#include <stdio.h> + +/* common */ +#include "attrib.h" + +/* cc65 */ +#include "opcodes.h" + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +void PushTrampoline (void *Ptr, unsigned char Val); +/* Push the current trampoline */ + +void PopTrampoline (void); +/* Pop the current trampoline */ + +void GetTrampoline (void **Ptr, unsigned char *Val); +/* Get the current trampoline, if any */ + + +/* End of trampoline.h */ + +#endif From 9c86c03a96e9885ac7aedd62b099ba43526aef4f Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Tue, 2 May 2017 18:48:31 +0300 Subject: [PATCH 0303/2161] Add test case --- test/val/trampoline.c | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 test/val/trampoline.c diff --git a/test/val/trampoline.c b/test/val/trampoline.c new file mode 100644 index 000000000..b5df1a22b --- /dev/null +++ b/test/val/trampoline.c @@ -0,0 +1,53 @@ +/* + !!DESCRIPTION!! trampoline pragma + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Lauri Kasanen +*/ + +static unsigned char flag; + +static void trampoline_set() { + asm("ldy tmp4"); + asm("sty %v", flag); + asm("jsr callptr4"); +} + +void trampoline_inc() { + asm("inc %v", flag); + asm("jsr callptr4"); +} + +void func3() { + +} + +unsigned char array[30]; +#pragma trampoline(push, array, 0) +#pragma trampoline(pop) + +#pragma trampoline(push, trampoline_inc, 0) + +void func2() { + func3(); +} + +#pragma trampoline(push, trampoline_set, 4) + +void func1(void); + +#pragma trampoline(pop) +#pragma trampoline(pop) + +void func1() { + func2(); +} + +int main(void) +{ + flag = 0; + + func1(); + + return flag == 5 ? 0 : 1; +} From 2890b3a810219ad512f9fdd2432811f94c0b121e Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Tue, 2 May 2017 19:06:19 +0300 Subject: [PATCH 0304/2161] Pragma trampoline --- src/cc65/declare.c | 21 +++++++++++ src/cc65/expr.c | 46 +++++++++++++++++++++++- src/cc65/funcdesc.c | 2 ++ src/cc65/funcdesc.h | 2 ++ src/cc65/pragma.c | 85 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 155 insertions(+), 1 deletion(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 7b543aa55..2ebc09b14 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -58,6 +58,7 @@ #include "scanner.h" #include "standard.h" #include "symtab.h" +#include "trampoline.h" #include "typeconv.h" @@ -1315,6 +1316,8 @@ static FuncDesc* ParseFuncDecl (void) { unsigned Offs; SymEntry* Sym; + SymEntry* Trampoline; + unsigned char TrampolineData; /* Create a new function descriptor */ FuncDesc* F = NewFuncDesc (); @@ -1380,6 +1383,13 @@ static FuncDesc* ParseFuncDecl (void) /* Leave the lexical level remembering the symbol tables */ RememberFunctionLevel (F); + /* Did we have a trampoline for this function? */ + GetTrampoline((void **) &Trampoline, &TrampolineData); + if (Trampoline) { + F->Trampoline = Trampoline; + F->TrampolineData = TrampolineData; + } + /* Return the function descriptor */ return F; } @@ -1447,6 +1457,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Function declaration */ FuncDesc* F; + SymEntry* PrevEntry; /* Skip the opening paren */ NextToken (); @@ -1460,6 +1471,16 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) Qualifiers &= ~T_QUAL_FASTCALL; } + /* Was there a previous entry? If so, copy trampoline info from it */ + PrevEntry = FindGlobalSym (D->Ident); + if (PrevEntry && PrevEntry->Flags & SC_FUNC) { + FuncDesc* D = PrevEntry->V.F.Func; + if (D->Trampoline && !F->Trampoline) { + F->Trampoline = D->Trampoline; + F->TrampolineData = D->TrampolineData; + } + } + /* 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 34cf550a2..fb1232fc1 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -536,6 +536,10 @@ static void FunctionCall (ExprDesc* Expr) /* Special handling for function pointers */ if (IsFuncPtr) { + if (Func->Trampoline) { + Warning("Calling a trampolined function via a pointer, trampoline will not be used"); + } + /* If the function is not a fastcall function, load the pointer to ** the function into the primary. */ @@ -584,7 +588,47 @@ static void FunctionCall (ExprDesc* Expr) } else { /* Normal function */ - g_call (TypeOf (Expr->Type), (const char*) Expr->Name, ParamSize); + if (Func->Trampoline) { + char tmp[64]; + StrBuf S = AUTO_STRBUF_INITIALIZER; + + /* Store the trampoline data in tmp4 */ + sprintf(tmp, "ldy #%u", Func->TrampolineData); + SB_AppendStr (&S, tmp); + g_asmcode (&S); + SB_Clear(&S); + + SB_AppendStr (&S, "sty tmp4"); + g_asmcode (&S); + SB_Clear(&S); + + /* Store the original function address in ptr4 */ + SB_AppendStr (&S, "ldy #<(_"); + SB_AppendStr (&S, (const char*) Expr->Name); + SB_AppendChar (&S, ')'); + g_asmcode (&S); + SB_Clear(&S); + + SB_AppendStr (&S, "sty ptr4"); + g_asmcode (&S); + SB_Clear(&S); + + SB_AppendStr (&S, "ldy #>(_"); + SB_AppendStr (&S, (const char*) Expr->Name); + SB_AppendChar (&S, ')'); + g_asmcode (&S); + SB_Clear(&S); + + SB_AppendStr (&S, "sty ptr4+1"); + g_asmcode (&S); + SB_Clear(&S); + + SB_Done (&S); + + g_call (TypeOf (Expr->Type), Func->Trampoline->Name, ParamSize); + } else { + g_call (TypeOf (Expr->Type), (const char*) Expr->Name, ParamSize); + } } diff --git a/src/cc65/funcdesc.c b/src/cc65/funcdesc.c index b9561a97c..607094acd 100644 --- a/src/cc65/funcdesc.c +++ b/src/cc65/funcdesc.c @@ -60,6 +60,8 @@ FuncDesc* NewFuncDesc (void) F->ParamCount = 0; F->ParamSize = 0; F->LastParam = 0; + F->Trampoline = 0; + F->TrampolineData = 0; /* Return the new struct */ return F; diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h index b79c6a055..b83cfa362 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -67,6 +67,8 @@ struct FuncDesc { unsigned ParamCount; /* Number of parameters */ unsigned ParamSize; /* Size of the parameters */ struct SymEntry* LastParam; /* Pointer to last parameter */ + struct SymEntry* Trampoline; /* Pointer to the trampoline */ + unsigned char TrampolineData; /* The trampoline's user data */ }; diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 707546e1d..c36811f35 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -51,6 +51,7 @@ #include "scanstrbuf.h" #include "symtab.h" #include "pragma.h" +#include "trampoline.h" @@ -87,6 +88,7 @@ typedef enum { PRAGMA_SIGNEDCHARS, /* obsolete */ PRAGMA_STATIC_LOCALS, PRAGMA_STATICLOCALS, /* obsolete */ + PRAGMA_TRAMPOLINE, PRAGMA_WARN, PRAGMA_WRITABLE_STRINGS, PRAGMA_ZPSYM, @@ -122,6 +124,7 @@ static const struct Pragma { { "signedchars", PRAGMA_SIGNEDCHARS }, /* obsolete */ { "static-locals", PRAGMA_STATIC_LOCALS }, { "staticlocals", PRAGMA_STATICLOCALS }, /* obsolete */ + { "trampoline", PRAGMA_TRAMPOLINE }, { "warn", PRAGMA_WARN }, { "writable-strings", PRAGMA_WRITABLE_STRINGS }, { "zpsym", PRAGMA_ZPSYM }, @@ -446,6 +449,84 @@ ExitPoint: } +static void TrampolinePragma (StrBuf* B) +/* Handle the trampoline pragma */ +{ + StrBuf S = AUTO_STRBUF_INITIALIZER; + const char *Name; + long Val; + SymEntry *Entry; + + /* Check for the "push" or "pop" keywords */ + switch (ParsePushPop (B)) { + + case PP_NONE: + Error ("Push or pop required"); + break; + + case PP_PUSH: + break; + + case PP_POP: + PopTrampoline(); + + /* Done */ + goto ExitPoint; + + case PP_ERROR: + /* Bail out */ + goto ExitPoint; + + default: + Internal ("Invalid result from ParsePushPop"); + + } + + /* A symbol argument must follow */ + if (!SB_GetSym (B, &S, NULL)) { + goto ExitPoint; + } + + /* Skip the following comma */ + if (!GetComma (B)) { + /* Error already flagged by GetComma */ + Error ("Value required for trampoline data"); + goto ExitPoint; + } + + if (!GetNumber (B, &Val)) { + Error ("Value required for trampoline data"); + goto ExitPoint; + } + + if (Val < 0 || Val > 255) { + Error ("Value must be between 0-255"); + goto ExitPoint; + } + + /* Get the string */ + Name = SB_GetConstBuf (&S); + Entry = FindSym(Name); + + /* Check if the name is valid */ + if (Entry && Entry->Flags & (SC_FUNC | SC_STORAGE)) { + + PushTrampoline(Entry, Val); + Entry->Flags |= SC_REF; + + } else { + + /* Segment name is invalid */ + Error ("Trampoline does not exist or is not a function or array"); + + } + +ExitPoint: + /* Call the string buf destructor */ + SB_Done (&S); +} + + static void CharMapPragma (StrBuf* B) /* Change the character map */ @@ -791,6 +872,10 @@ static void ParsePragma (void) FlagPragma (&B, &StaticLocals); break; + case PRAGMA_TRAMPOLINE: + TrampolinePragma(&B); + break; + case PRAGMA_WARN: WarnPragma (&B); break; From 767f093ff86604314a9ee42c25842c79905f3248 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Sat, 6 May 2017 13:20:55 +0300 Subject: [PATCH 0305/2161] Add fast path for char postinc --- src/cc65/expr.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 34cf550a2..502fd7a8e 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1534,26 +1534,35 @@ static void PostInc (ExprDesc* Expr) /* Get the data type */ Flags = TypeOf (Expr->Type); - /* Push the address if needed */ - PushAddr (Expr); + /* Fast path: char */ + if ((Flags & CF_CHAR) == CF_CHAR && ED_GetLoc(Expr) & (E_LOC_GLOBAL | E_LOC_STATIC)) { - /* Fetch the value and save it (since it's the result of the expression) */ - LoadExpr (CF_NONE, Expr); - g_save (Flags | CF_FORCECHAR); + LoadExpr (CF_NONE, Expr); + AddCodeLine ("inc %s", ED_GetLabelName(Expr, 0)); - /* If we have a pointer expression, increment by the size of the type */ - if (IsTypePtr (Expr->Type)) { - g_inc (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1)); } else { - g_inc (Flags | CF_CONST | CF_FORCECHAR, 1); + + /* Push the address if needed */ + PushAddr (Expr); + + /* Fetch the value and save it (since it's the result of the expression) */ + LoadExpr (CF_NONE, Expr); + g_save (Flags | CF_FORCECHAR); + + /* If we have a pointer expression, increment by the size of the type */ + if (IsTypePtr (Expr->Type)) { + g_inc (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1)); + } else { + g_inc (Flags | CF_CONST | CF_FORCECHAR, 1); + } + + /* Store the result back */ + Store (Expr, 0); + + /* Restore the original value in the primary register */ + g_restore (Flags | CF_FORCECHAR); } - /* Store the result back */ - Store (Expr, 0); - - /* Restore the original value in the primary register */ - g_restore (Flags | CF_FORCECHAR); - /* The result is always an expression, no reference */ ED_MakeRValExpr (Expr); } From ead0338c0def811cb251090cc0851899a0cbdf8e Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Sat, 6 May 2017 13:23:50 +0300 Subject: [PATCH 0306/2161] Add fast path for char postdec --- src/cc65/expr.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 502fd7a8e..e5c1a17b9 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1590,26 +1590,35 @@ static void PostDec (ExprDesc* Expr) /* Get the data type */ Flags = TypeOf (Expr->Type); - /* Push the address if needed */ - PushAddr (Expr); + /* Fast path: char */ + if ((Flags & CF_CHAR) == CF_CHAR && ED_GetLoc(Expr) & (E_LOC_GLOBAL | E_LOC_STATIC)) { - /* Fetch the value and save it (since it's the result of the expression) */ - LoadExpr (CF_NONE, Expr); - g_save (Flags | CF_FORCECHAR); + LoadExpr (CF_NONE, Expr); + AddCodeLine ("dec %s", ED_GetLabelName(Expr, 0)); - /* If we have a pointer expression, increment by the size of the type */ - if (IsTypePtr (Expr->Type)) { - g_dec (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1)); } else { - g_dec (Flags | CF_CONST | CF_FORCECHAR, 1); + + /* Push the address if needed */ + PushAddr (Expr); + + /* Fetch the value and save it (since it's the result of the expression) */ + LoadExpr (CF_NONE, Expr); + g_save (Flags | CF_FORCECHAR); + + /* If we have a pointer expression, increment by the size of the type */ + if (IsTypePtr (Expr->Type)) { + g_dec (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1)); + } else { + g_dec (Flags | CF_CONST | CF_FORCECHAR, 1); + } + + /* Store the result back */ + Store (Expr, 0); + + /* Restore the original value in the primary register */ + g_restore (Flags | CF_FORCECHAR); } - /* Store the result back */ - Store (Expr, 0); - - /* Restore the original value in the primary register */ - g_restore (Flags | CF_FORCECHAR); - /* The result is always an expression, no reference */ ED_MakeRValExpr (Expr); } From a2f61c667ab49cd99632cbd958ef79057d80ac77 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Sun, 7 May 2017 20:31:41 +0300 Subject: [PATCH 0307/2161] Update comments and location checks according to Greg --- src/cc65/expr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index e5c1a17b9..e87b02ffc 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1534,8 +1534,8 @@ static void PostInc (ExprDesc* Expr) /* Get the data type */ Flags = TypeOf (Expr->Type); - /* Fast path: char */ - if ((Flags & CF_CHAR) == CF_CHAR && ED_GetLoc(Expr) & (E_LOC_GLOBAL | E_LOC_STATIC)) { + /* Emit smaller code if a char variable is at a constant location */ + if ((Flags & CF_CHAR) == CF_CHAR && ED_IsLocConst(Expr)) { LoadExpr (CF_NONE, Expr); AddCodeLine ("inc %s", ED_GetLabelName(Expr, 0)); @@ -1590,8 +1590,8 @@ static void PostDec (ExprDesc* Expr) /* Get the data type */ Flags = TypeOf (Expr->Type); - /* Fast path: char */ - if ((Flags & CF_CHAR) == CF_CHAR && ED_GetLoc(Expr) & (E_LOC_GLOBAL | E_LOC_STATIC)) { + /* Emit smaller code if a char variable is at a constant location */ + if ((Flags & CF_CHAR) == CF_CHAR && ED_IsLocConst(Expr)) { LoadExpr (CF_NONE, Expr); AddCodeLine ("dec %s", ED_GetLabelName(Expr, 0)); From 7adcde1707eb7ab81bc1f15099ad91276f0f11eb Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Sun, 7 May 2017 20:35:49 +0300 Subject: [PATCH 0308/2161] Add explicit postinc/dec testcase --- test/val/postincdec.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 test/val/postincdec.c diff --git a/test/val/postincdec.c b/test/val/postincdec.c new file mode 100644 index 000000000..19a6eb2a7 --- /dev/null +++ b/test/val/postincdec.c @@ -0,0 +1,23 @@ +/* + !!DESCRIPTION!! char-sized post-increment and -decrement + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Lauri Kasanen +*/ + + +static unsigned char val, array[2]; + +int main() { + + val = 0; + array[0] = array[1] = 10; + + array[val++] = 2; + array[val++] = 2; + --val; + array[val--] = 0; + array[val--] = 0; + + return (array[0] == array[1] && array[0] == 0) ? 0 : 1; +} From 077b14ccfa5f8b4defc2f98b01cf17e0f2a70922 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Mon, 8 May 2017 10:19:26 +0300 Subject: [PATCH 0309/2161] test/val/postincdec: Test for the final val value --- test/val/postincdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/val/postincdec.c b/test/val/postincdec.c index 19a6eb2a7..6d3e9593c 100644 --- a/test/val/postincdec.c +++ b/test/val/postincdec.c @@ -19,5 +19,5 @@ int main() { array[val--] = 0; array[val--] = 0; - return (array[0] == array[1] && array[0] == 0) ? 0 : 1; + return (array[0] == array[1] && array[0] == 0 && val == 0xff) ? 0 : 1; } From 4cbfb4e199bf019c0f4c917c6c189fe93867a05a Mon Sep 17 00:00:00 2001 From: mc78 <mc78@outlook.de> Date: Fri, 12 May 2017 12:19:40 +0200 Subject: [PATCH 0310/2161] added -E switch to cl65 for >>stop after the preprocessing stage<<. added compilation and assemblation disable after -Wc -E also with -E beeing part of a comma separated list of arguments --- src/cl65/main.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index 7bdbe7a8a..58a1fe0c2 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -706,6 +706,7 @@ static void Usage (void) " -C name\t\t\tUse linker config file\n" " -Cl\t\t\t\tMake local variables static\n" " -D sym[=defn]\t\t\tDefine a preprocessor symbol\n" + " -E Stop after the preprocessing stage\n" " -I dir\t\t\tSet a compiler include directory path\n" " -L path\t\t\tSpecify a library search path\n" " -Ln name\t\t\tCreate a VICE label file\n" @@ -1411,14 +1412,41 @@ int main (int argc, char* argv []) /* Print version number */ OptVersion (Arg, 0); break; - + + case 'E': + /*Forward -E to compiler*/ + CmdAddArg (&CC65, Arg); + DoAssemble = 0; + DoLink = 0; + break; case 'W': if (Arg[2] == 'a' && Arg[3] == '\0') { /* -Wa: Pass options to assembler */ OptAsmArgs (Arg, GetArg (&I, 3)); - } else if (Arg[2] == 'c' && Arg[3] == '\0') { + } + else if (Arg[2] == 'c' && Arg[3] == '\0') { /* -Wc: Pass options to compiler */ - OptCCArgs (Arg, GetArg (&I, 3)); + + /* Get argument succeeding -Wc switch */ + const char* WcSubArgs = GetArg (&I, 3); + + /* Remember -Wc sub arguments in cc65 arg struct */ + OptCCArgs (Arg, WcSubArgs); + /* Check for isolated -E switch given after -Wc*/ + if (!strcmp("-E", WcSubArgs)){ + /*If both -Wc and -E given, then prevent assembling + and linking */ + DoAssemble = 0; + DoLink = 0; + }else{ + /* Check for -E beeing part of comma separated arg + list given after -Wc*/ + if ( (NULL!=strstr(WcSubArgs, "-E,")) || + (NULL!=strstr(WcSubArgs, ",-E"))){ + DoAssemble = 0; + DoLink = 0; + } + } } else if (Arg[2] == 'l' && Arg[3] == '\0') { /* -Wl: Pass options to linker */ OptLdArgs (Arg, GetArg (&I, 3)); From 691df09a1f4a6b0f95b0d6eb7fd7320eb28df2b6 Mon Sep 17 00:00:00 2001 From: mc78 <mc78@outlook.de> Date: Tue, 16 May 2017 13:13:09 +0200 Subject: [PATCH 0311/2161] According to recent comments on my recent pull request, -Wc checking for -E flag has been removed again. Intead, -E flag has been added to cl65 without need of -Wc. Two functions have been introduced to disable compile, link or both. These function remove assigment repetions to DoAssemble and DoLink for litte overhead, having the maintainability in mind. --- src/cl65/main.c | 46 +++++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index 58a1fe0c2..2172700ae 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -156,7 +156,21 @@ static char* TargetLib = 0; # endif #endif +/*****************************************************************************/ +/* Credential functions */ +/*****************************************************************************/ +void DisableAssembling(void){ + DoAssemble = 0; +} +void DisableLinking(void){ + DoLink = 0; +} + +void DisableAssemblingAndLinking(void){ + DisableAssembling(); + DisableLinking(); +} /*****************************************************************************/ /* Command structure handling */ @@ -1399,8 +1413,7 @@ int main (int argc, char* argv []) case 'S': /* Dont assemble and link the created files */ - DoAssemble = 0; - DoLink = 0; + DisableAssemblingAndLinking(); break; case 'T': @@ -1416,37 +1429,16 @@ int main (int argc, char* argv []) case 'E': /*Forward -E to compiler*/ CmdAddArg (&CC65, Arg); - DoAssemble = 0; - DoLink = 0; + DisableAssemblingAndLinking(); break; case 'W': if (Arg[2] == 'a' && Arg[3] == '\0') { /* -Wa: Pass options to assembler */ OptAsmArgs (Arg, GetArg (&I, 3)); - } - else if (Arg[2] == 'c' && Arg[3] == '\0') { + } else if (Arg[2] == 'c' && Arg[3] == '\0') { /* -Wc: Pass options to compiler */ - - /* Get argument succeeding -Wc switch */ - const char* WcSubArgs = GetArg (&I, 3); - /* Remember -Wc sub arguments in cc65 arg struct */ - OptCCArgs (Arg, WcSubArgs); - /* Check for isolated -E switch given after -Wc*/ - if (!strcmp("-E", WcSubArgs)){ - /*If both -Wc and -E given, then prevent assembling - and linking */ - DoAssemble = 0; - DoLink = 0; - }else{ - /* Check for -E beeing part of comma separated arg - list given after -Wc*/ - if ( (NULL!=strstr(WcSubArgs, "-E,")) || - (NULL!=strstr(WcSubArgs, ",-E"))){ - DoAssemble = 0; - DoLink = 0; - } - } + OptCCArgs (Arg, GetArg (&I, 3)); } else if (Arg[2] == 'l' && Arg[3] == '\0') { /* -Wl: Pass options to linker */ OptLdArgs (Arg, GetArg (&I, 3)); @@ -1458,7 +1450,7 @@ int main (int argc, char* argv []) case 'c': /* Don't link the resulting files */ - DoLink = 0; + DisableLinking(); break; case 'd': From d70a9507a7c731e9b95dd615328df975a3cff58c Mon Sep 17 00:00:00 2001 From: mc78 <mc78@outlook.de> Date: Tue, 16 May 2017 13:31:10 +0200 Subject: [PATCH 0312/2161] replaced tabs with spaces which accidently were introduced. --- src/cl65/main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index 2172700ae..e428c96ac 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -157,19 +157,19 @@ static char* TargetLib = 0; #endif /*****************************************************************************/ -/* Credential functions */ +/* Credential functions */ /*****************************************************************************/ void DisableAssembling(void){ - DoAssemble = 0; + DoAssemble = 0; } void DisableLinking(void){ - DoLink = 0; + DoLink = 0; } void DisableAssemblingAndLinking(void){ - DisableAssembling(); - DisableLinking(); + DisableAssembling(); + DisableLinking(); } /*****************************************************************************/ From ca41af41c2d555355ea45dd0c83a5fa3508ddd1a Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Tue, 16 May 2017 20:10:24 +0300 Subject: [PATCH 0313/2161] Rename pragma trampoline to wrapped-call, value to identifier --- doc/cc65.sgml | 50 +++++++++++++++++++++---------------------- src/cc65/pragma.c | 20 ++++++++--------- test/val/trampoline.c | 12 +++++------ 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 99ddfc82d..a9b88c2b4 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1209,31 +1209,6 @@ parameter with the <tt/#pragma/. The <tt/#pragma/ understands the push and pop parameters as explained above. -<sect1><tt>#pragma trampoline (<push&rt;, <name>, <value>)</tt><label id="pragma-trampoline"><p> - - This pragma sets a trampoline for functions. The name is either - a function returning void and taking no parameters, or the address - of an array in memory (for a RAM trampoline). The value is an - 8-bit number that's set to tmp4. - - The address of the function is passed in ptr4. - - This is useful for example with banked memory, to automatically - switch banks to where this function resides, and then restore - the bank when it returns. - - The <tt/#pragma/ requires the push and pop parameters as explained above. - - Example: - <tscreen><verb> - void mytrampoline(void); - - #pragma trampoline (push, mytrampoline, 0) - void somefunc(void); - #pragma trampoline (pop) - </verb></tscreen> - - <sect1><tt>#pragma warn (name, [push,] on|off)</tt><label id="pragma-warn"><p> Switch compiler warnings on or off. "name" is the name of a warning (see the @@ -1254,6 +1229,31 @@ parameter with the <tt/#pragma/. </verb></tscreen> +<sect1><tt>#pragma wrapped-call (<push&rt;, <name>, <identifier>)</tt><label id="pragma-trampoline"><p> + + This pragma sets a wrapper for functions, often used for trampolines. + The name is either a function returning void and taking no parameters, + or the address of an array in memory (for a RAM trampoline). The identifier + is an 8-bit number that's set to tmp4. + + The address of the function is passed in ptr4. + + This is useful for example with banked memory, to automatically + switch banks to where this function resides, and then restore + the bank when it returns. + + The <tt/#pragma/ requires the push and pop parameters as explained above. + + Example: + <tscreen><verb> + void mytrampoline(void); + + #pragma wrapped-call (push, mytrampoline, 0) + void somefunc(void); + #pragma wrapped-call (pop) + </verb></tscreen> + + <sect1><tt>#pragma writable-strings ([push,] on|off)</tt><label id="pragma-writable-strings"><p> Changes the storage location of string literals. For historical reasons, diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index c36811f35..6ec2df3a3 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -88,8 +88,8 @@ typedef enum { PRAGMA_SIGNEDCHARS, /* obsolete */ PRAGMA_STATIC_LOCALS, PRAGMA_STATICLOCALS, /* obsolete */ - PRAGMA_TRAMPOLINE, PRAGMA_WARN, + PRAGMA_WRAPPED_CALL, PRAGMA_WRITABLE_STRINGS, PRAGMA_ZPSYM, PRAGMA_COUNT @@ -124,8 +124,8 @@ static const struct Pragma { { "signedchars", PRAGMA_SIGNEDCHARS }, /* obsolete */ { "static-locals", PRAGMA_STATIC_LOCALS }, { "staticlocals", PRAGMA_STATICLOCALS }, /* obsolete */ - { "trampoline", PRAGMA_TRAMPOLINE }, { "warn", PRAGMA_WARN }, + { "wrapped-call", PRAGMA_WRAPPED_CALL }, { "writable-strings", PRAGMA_WRITABLE_STRINGS }, { "zpsym", PRAGMA_ZPSYM }, }; @@ -449,8 +449,8 @@ ExitPoint: } -static void TrampolinePragma (StrBuf* B) -/* Handle the trampoline pragma */ +static void WrappedCallPragma (StrBuf* B) +/* Handle the wrapped-call pragma */ { StrBuf S = AUTO_STRBUF_INITIALIZER; const char *Name; @@ -490,17 +490,17 @@ static void TrampolinePragma (StrBuf* B) /* Skip the following comma */ if (!GetComma (B)) { /* Error already flagged by GetComma */ - Error ("Value required for trampoline data"); + Error ("Value required for wrapped-call identifier"); goto ExitPoint; } if (!GetNumber (B, &Val)) { - Error ("Value required for trampoline data"); + Error ("Value required for wrapped-call identifier"); goto ExitPoint; } if (Val < 0 || Val > 255) { - Error ("Value must be between 0-255"); + Error ("Identifier must be between 0-255"); goto ExitPoint; } @@ -517,7 +517,7 @@ static void TrampolinePragma (StrBuf* B) } else { /* Segment name is invalid */ - Error ("Trampoline does not exist or is not a function or array"); + Error ("Wrapped-call target does not exist or is not a function or array"); } @@ -872,8 +872,8 @@ static void ParsePragma (void) FlagPragma (&B, &StaticLocals); break; - case PRAGMA_TRAMPOLINE: - TrampolinePragma(&B); + case PRAGMA_WRAPPED_CALL: + WrappedCallPragma(&B); break; case PRAGMA_WARN: diff --git a/test/val/trampoline.c b/test/val/trampoline.c index b5df1a22b..aad4c96ea 100644 --- a/test/val/trampoline.c +++ b/test/val/trampoline.c @@ -23,21 +23,21 @@ void func3() { } unsigned char array[30]; -#pragma trampoline(push, array, 0) -#pragma trampoline(pop) +#pragma wrapped-call(push, array, 0) +#pragma wrapped-call(pop) -#pragma trampoline(push, trampoline_inc, 0) +#pragma wrapped-call(push, trampoline_inc, 0) void func2() { func3(); } -#pragma trampoline(push, trampoline_set, 4) +#pragma wrapped-call(push, trampoline_set, 4) void func1(void); -#pragma trampoline(pop) -#pragma trampoline(pop) +#pragma wrapped-call(pop) +#pragma wrapped-call(pop) void func1() { func2(); From ac7a0e21ac0211df2594dff303da973e88a4faee Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Tue, 16 May 2017 20:14:19 +0300 Subject: [PATCH 0314/2161] Correct missed doc label --- doc/cc65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index a9b88c2b4..d87fa47a7 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1229,7 +1229,7 @@ parameter with the <tt/#pragma/. </verb></tscreen> -<sect1><tt>#pragma wrapped-call (<push&rt;, <name>, <identifier>)</tt><label id="pragma-trampoline"><p> +<sect1><tt>#pragma wrapped-call (<push&rt;, <name>, <identifier>)</tt><label id="pragma-wrapped-call"><p> This pragma sets a wrapper for functions, often used for trampolines. The name is either a function returning void and taking no parameters, From 6011bdb2f63c86424fbd6e321d3eee3408b61b62 Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Wed, 17 May 2017 10:00:35 +0200 Subject: [PATCH 0315/2161] Optimize the inlined strlen. --- src/cc65/stdfunc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 7a0450146..f658f0dcb 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -1245,9 +1245,8 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldy #$FF"); g_defcodelabel (L); AddCodeLine ("iny"); - AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg, 0)); + AddCodeLine ("ldx %s,y", ED_GetLabelName (&Arg, 0)); AddCodeLine ("bne %s", LocalLabelName (L)); - AddCodeLine ("tax"); AddCodeLine ("tya"); /* The function result is an rvalue in the primary register */ From 675dd3c9637e0f4a73ae549fefa4e312b8c4bbf5 Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Wed, 17 May 2017 10:08:08 +0200 Subject: [PATCH 0316/2161] Optimize the inlined memcpy/memset for the sizes of 128/129. --- src/cc65/stdfunc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index f658f0dcb..2d4317ef8 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -284,7 +284,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) Label = GetLocalLabel (); /* Generate memcpy code */ - if (Arg3.Expr.IVal <= 127) { + if (Arg3.Expr.IVal <= 129) { AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal-1)); g_defcodelabel (Label); @@ -355,7 +355,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) Label = GetLocalLabel (); /* Generate memcpy code */ - if (Arg3.Expr.IVal <= 127 && !AllowOneIndex) { + if (Arg3.Expr.IVal <= 129 && !AllowOneIndex) { if (Offs == 0) { AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1)); @@ -433,7 +433,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) Label = GetLocalLabel (); /* Generate memcpy code */ - if (Arg3.Expr.IVal <= 127 && !AllowOneIndex) { + if (Arg3.Expr.IVal <= 129 && !AllowOneIndex) { if (Offs == 0) { AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal - 1)); @@ -499,7 +499,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Generate memcpy code */ AddCodeLine ("sta ptr1"); AddCodeLine ("stx ptr1+1"); - if (Arg3.Expr.IVal <= 127) { + if (Arg3.Expr.IVal <= 129) { AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal - 1)); g_defcodelabel (Label); AddCodeLine ("lda (sp),y"); @@ -635,7 +635,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) Label = GetLocalLabel (); /* Generate memset code */ - if (Arg3.Expr.IVal <= 127) { + if (Arg3.Expr.IVal <= 129) { AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal-1)); AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal); @@ -720,7 +720,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Generate code */ AddCodeLine ("sta ptr1"); AddCodeLine ("stx ptr1+1"); - if (Arg3.Expr.IVal <= 127) { + if (Arg3.Expr.IVal <= 129) { AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal-1)); AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal); g_defcodelabel (Label); From 298dda0e71646112f0d0a57146acbb3a62a145fd Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 17 May 2017 18:30:12 +0200 Subject: [PATCH 0317/2161] Increased GCC optimization level. --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index f4f29b949..3ce4b676a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -62,7 +62,7 @@ else endif endif -CFLAGS += -MMD -MP -O -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 f151142e6a9935f53fb36b5c54d1031572f50d0c Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 17 May 2017 19:39:02 +0200 Subject: [PATCH 0318/2161] Keep GCC from complaining about 'List' may be used uninitialized in this function. --- src/ca65/pseudo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index b44c28dd8..f84f21d7f 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1388,7 +1388,7 @@ static void DoList (void) /* Enable/disable the listing */ { /* Get the setting */ - unsigned char List; + unsigned char List = 0; SetBoolOption (&List); /* Manage the counter */ From 73f1c0e11d0162b1dbad8e1ef21a9f90f4c4f032 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 17 May 2017 20:56:21 +0200 Subject: [PATCH 0319/2161] Migrate 'encrypted variables' variables to 'repository settings'. The GitHub token used for GitHub Pages deployment was revoked (see https://blog.travis-ci.com/2017-05-08-security-advisory) so I took the opportunity to make use of the "new" repository settings feature instead of fiddling with variable encryption again. --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index fd2672887..c84eb0cc2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,3 @@ script: - make doc zip after_success: - make -f Makefile.travis -env: - global: - - secure: "h+hoQdEHGPLNwaqGKmSaM8NBRDLc2X+W05VsnNG2Feq/wPv/AiBjONNlzN7jRf6D6f3aoPXaQ2Lc3bYWdxGvFRCmwiofdxkJI9n5L8HPHLZ2lf37MQsXmGJzoTFOvjPLj73H6HlbI9Ux0El3zO6hvalxiXj6TfoZ41dbhNyvpYk=" - - secure: "A4hMEe5RRfUtYjFGbT7QAvT1Tyo434N+/TiuQeQ4q0L46c79LnXuGQzbFLOFZshZiplLkJr7lFg466CoI1bf2L0cQOew/LesMhE75v0HQ7tZnExWhdpAk0ri6nWixbjn/dmQ0+HxjzJ48A44DMMBYcvSIsO4vflvuJ8etfSg42k=" From c6cab0bb2747d26e710a0c048b74a3475d070df5 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Thu, 18 May 2017 12:59:03 +0200 Subject: [PATCH 0320/2161] VIC's kernal does not support CTRL+[ --- doc/vic20.sgml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/doc/vic20.sgml b/doc/vic20.sgml index b1a08ac83..889cc266e 100644 --- a/doc/vic20.sgml +++ b/doc/vic20.sgml @@ -2,11 +2,11 @@ <article> -<title>Commodore VIC20 (aka VC20) specific information for cc65 +<title>Commodore VIC20 (aka VC20 aka VIC1001) 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"> -<date>2014-04-12 +<date>2017-05-18 <abstract> An overview over the VIC20 runtime system as it is implemented for the cc65 C @@ -188,7 +188,7 @@ No VIC1011 drivers are currently available for the VIC20. <sect1>Escape code<p> -For an Esc, press CTRL and the <tt/[/ key. +For an Esc, pressing CTRL and the <tt/[/ key is not supported. <sect1>Passing arguments to the program<p> @@ -219,8 +219,7 @@ The program return code (low byte) is passed back to BASIC by use of the <sect1>Using extended memory<p> -The extended memory at $A000 may be added to the heap by using the following -code: +BLK5 memory may be added to the heap by using the following code: <tscreen><verb> /* Check for the existence of RAM */ From a590b99f5be4af391811d0e79520ea07852b763f Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Thu, 18 May 2017 14:21:43 +0300 Subject: [PATCH 0321/2161] Align with spaces instead of tabs here --- src/cc65/pragma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 6ec2df3a3..27015285e 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -125,7 +125,7 @@ static const struct Pragma { { "static-locals", PRAGMA_STATIC_LOCALS }, { "staticlocals", PRAGMA_STATICLOCALS }, /* obsolete */ { "warn", PRAGMA_WARN }, - { "wrapped-call", PRAGMA_WRAPPED_CALL }, + { "wrapped-call", PRAGMA_WRAPPED_CALL }, { "writable-strings", PRAGMA_WRITABLE_STRINGS }, { "zpsym", PRAGMA_ZPSYM }, }; From 7feced88627dc3f07fe1580e80670c234bd0a984 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Thu, 18 May 2017 15:54:47 +0300 Subject: [PATCH 0322/2161] More tabs to spaces --- src/cc65/pragma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 27015285e..fe7101d97 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -125,7 +125,7 @@ static const struct Pragma { { "static-locals", PRAGMA_STATIC_LOCALS }, { "staticlocals", PRAGMA_STATICLOCALS }, /* obsolete */ { "warn", PRAGMA_WARN }, - { "wrapped-call", PRAGMA_WRAPPED_CALL }, + { "wrapped-call", PRAGMA_WRAPPED_CALL }, { "writable-strings", PRAGMA_WRITABLE_STRINGS }, { "zpsym", PRAGMA_ZPSYM }, }; From f6fa74a6367f6aa8f803c867c61be9f6071bb614 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Thu, 18 May 2017 16:00:04 +0300 Subject: [PATCH 0323/2161] Rename trampoline to wrappedcall everywhere --- src/cc65/declare.c | 24 +++++++-------- src/cc65/expr.c | 12 ++++---- src/cc65/funcdesc.c | 4 +-- src/cc65/funcdesc.h | 4 +-- src/cc65/pragma.c | 6 ++-- src/cc65/{trampoline.c => wrappedcall.c} | 38 ++++++++++++------------ src/cc65/{trampoline.h => wrappedcall.h} | 22 +++++++------- 7 files changed, 55 insertions(+), 55 deletions(-) rename src/cc65/{trampoline.c => wrappedcall.c} (79%) rename src/cc65/{trampoline.h => wrappedcall.h} (85%) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 2ebc09b14..a6b232905 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -58,7 +58,7 @@ #include "scanner.h" #include "standard.h" #include "symtab.h" -#include "trampoline.h" +#include "wrappedcall.h" #include "typeconv.h" @@ -1316,8 +1316,8 @@ static FuncDesc* ParseFuncDecl (void) { unsigned Offs; SymEntry* Sym; - SymEntry* Trampoline; - unsigned char TrampolineData; + SymEntry* WrappedCall; + unsigned char WrappedCallData; /* Create a new function descriptor */ FuncDesc* F = NewFuncDesc (); @@ -1383,11 +1383,11 @@ static FuncDesc* ParseFuncDecl (void) /* Leave the lexical level remembering the symbol tables */ RememberFunctionLevel (F); - /* Did we have a trampoline for this function? */ - GetTrampoline((void **) &Trampoline, &TrampolineData); - if (Trampoline) { - F->Trampoline = Trampoline; - F->TrampolineData = TrampolineData; + /* Did we have a WrappedCall for this function? */ + GetWrappedCall((void **) &WrappedCall, &WrappedCallData); + if (WrappedCall) { + F->WrappedCall = WrappedCall; + F->WrappedCallData = WrappedCallData; } /* Return the function descriptor */ @@ -1471,13 +1471,13 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) Qualifiers &= ~T_QUAL_FASTCALL; } - /* Was there a previous entry? If so, copy trampoline info from it */ + /* Was there a previous entry? If so, copy WrappedCall info from it */ PrevEntry = FindGlobalSym (D->Ident); if (PrevEntry && PrevEntry->Flags & SC_FUNC) { FuncDesc* D = PrevEntry->V.F.Func; - if (D->Trampoline && !F->Trampoline) { - F->Trampoline = D->Trampoline; - F->TrampolineData = D->TrampolineData; + if (D->WrappedCall && !F->WrappedCall) { + F->WrappedCall = D->WrappedCall; + F->WrappedCallData = D->WrappedCallData; } } diff --git a/src/cc65/expr.c b/src/cc65/expr.c index fb1232fc1..467c30da2 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -536,8 +536,8 @@ static void FunctionCall (ExprDesc* Expr) /* Special handling for function pointers */ if (IsFuncPtr) { - if (Func->Trampoline) { - Warning("Calling a trampolined function via a pointer, trampoline will not be used"); + 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 @@ -588,12 +588,12 @@ static void FunctionCall (ExprDesc* Expr) } else { /* Normal function */ - if (Func->Trampoline) { + if (Func->WrappedCall) { char tmp[64]; StrBuf S = AUTO_STRBUF_INITIALIZER; - /* Store the trampoline data in tmp4 */ - sprintf(tmp, "ldy #%u", Func->TrampolineData); + /* Store the WrappedCall data in tmp4 */ + sprintf(tmp, "ldy #%u", Func->WrappedCallData); SB_AppendStr (&S, tmp); g_asmcode (&S); SB_Clear(&S); @@ -625,7 +625,7 @@ static void FunctionCall (ExprDesc* Expr) SB_Done (&S); - g_call (TypeOf (Expr->Type), Func->Trampoline->Name, ParamSize); + g_call (TypeOf (Expr->Type), Func->WrappedCall->Name, ParamSize); } else { g_call (TypeOf (Expr->Type), (const char*) Expr->Name, ParamSize); } diff --git a/src/cc65/funcdesc.c b/src/cc65/funcdesc.c index 607094acd..273263dec 100644 --- a/src/cc65/funcdesc.c +++ b/src/cc65/funcdesc.c @@ -60,8 +60,8 @@ FuncDesc* NewFuncDesc (void) F->ParamCount = 0; F->ParamSize = 0; F->LastParam = 0; - F->Trampoline = 0; - F->TrampolineData = 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 b83cfa362..966aff573 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -67,8 +67,8 @@ struct FuncDesc { unsigned ParamCount; /* Number of parameters */ unsigned ParamSize; /* Size of the parameters */ struct SymEntry* LastParam; /* Pointer to last parameter */ - struct SymEntry* Trampoline; /* Pointer to the trampoline */ - unsigned char TrampolineData; /* The trampoline's user data */ + struct SymEntry* WrappedCall; /* Pointer to the WrappedCall */ + unsigned char WrappedCallData; /* The WrappedCall's user data */ }; diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index fe7101d97..98f1a20d0 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -51,7 +51,7 @@ #include "scanstrbuf.h" #include "symtab.h" #include "pragma.h" -#include "trampoline.h" +#include "wrappedcall.h" @@ -468,7 +468,7 @@ static void WrappedCallPragma (StrBuf* B) break; case PP_POP: - PopTrampoline(); + PopWrappedCall(); /* Done */ goto ExitPoint; @@ -511,7 +511,7 @@ static void WrappedCallPragma (StrBuf* B) /* Check if the name is valid */ if (Entry && Entry->Flags & (SC_FUNC | SC_STORAGE)) { - PushTrampoline(Entry, Val); + PushWrappedCall(Entry, Val); Entry->Flags |= SC_REF; } else { diff --git a/src/cc65/trampoline.c b/src/cc65/wrappedcall.c similarity index 79% rename from src/cc65/trampoline.c rename to src/cc65/wrappedcall.c index 1f35a0f3c..2d11245fd 100644 --- a/src/cc65/trampoline.c +++ b/src/cc65/wrappedcall.c @@ -1,8 +1,8 @@ /*****************************************************************************/ /* */ -/* trampoline.c */ +/* wrappedcall.c */ /* */ -/* Trampoline management */ +/* WrappedCall management */ /* */ /* */ /* */ @@ -44,7 +44,7 @@ /* cc65 */ #include "codeent.h" #include "error.h" -#include "trampoline.h" +#include "wrappedcall.h" @@ -53,8 +53,8 @@ /*****************************************************************************/ -/* Trampolines */ -static IntPtrStack Trampolines; +/* WrappedCalls */ +static IntPtrStack WrappedCalls; @@ -64,39 +64,39 @@ static IntPtrStack Trampolines; -void PushTrampoline (void *Ptr, unsigned char Val) -/* Push the current trampoline */ +void PushWrappedCall (void *Ptr, unsigned char Val) +/* Push the current WrappedCall */ { - if (IPS_IsFull (&Trampolines)) { - Error ("Trampoline stack overflow"); + if (IPS_IsFull (&WrappedCalls)) { + Error ("WrappedCall stack overflow"); } else { - IPS_Push (&Trampolines, Val, Ptr); + IPS_Push (&WrappedCalls, Val, Ptr); } } -void PopTrampoline (void) -/* Remove the current trampoline */ +void PopWrappedCall (void) +/* Remove the current WrappedCall */ { - if (IPS_GetCount (&Trampolines) < 1) { - Error ("Trampoline stack is empty"); + if (IPS_GetCount (&WrappedCalls) < 1) { + Error ("WrappedCall stack is empty"); } else { - IPS_Drop (&Trampolines); + IPS_Drop (&WrappedCalls); } } -void GetTrampoline (void **Ptr, unsigned char *Val) -/* Get the current trampoline */ +void GetWrappedCall (void **Ptr, unsigned char *Val) +/* Get the current WrappedCall */ { - if (IPS_GetCount (&Trampolines) < 1) { + if (IPS_GetCount (&WrappedCalls) < 1) { *Ptr = NULL; *Val = 0; } else { long Temp; - IPS_Get (&Trampolines, &Temp, Ptr); + IPS_Get (&WrappedCalls, &Temp, Ptr); *Val = Temp; } } diff --git a/src/cc65/trampoline.h b/src/cc65/wrappedcall.h similarity index 85% rename from src/cc65/trampoline.h rename to src/cc65/wrappedcall.h index f110bd42e..3517c2465 100644 --- a/src/cc65/trampoline.h +++ b/src/cc65/wrappedcall.h @@ -1,8 +1,8 @@ /*****************************************************************************/ /* */ -/* trampoline.h */ +/* wrappedcall.h */ /* */ -/* Trampoline management */ +/* Wrapped-call management */ /* */ /* */ /* */ @@ -30,8 +30,8 @@ -#ifndef TRAMPOLINE_H -#define TRAMPOLINE_H +#ifndef WRAPPEDCALL_H +#define WRAPPEDCALL_H @@ -50,16 +50,16 @@ -void PushTrampoline (void *Ptr, unsigned char Val); -/* Push the current trampoline */ +void PushWrappedCall (void *Ptr, unsigned char Val); +/* Push the current WrappedCall */ -void PopTrampoline (void); -/* Pop the current trampoline */ +void PopWrappedCall (void); +/* Pop the current WrappedCall */ -void GetTrampoline (void **Ptr, unsigned char *Val); -/* Get the current trampoline, if any */ +void GetWrappedCall (void **Ptr, unsigned char *Val); +/* Get the current WrappedCall, if any */ -/* End of trampoline.h */ +/* End of wrappedcall.h */ #endif From 4c05c46cd15ade6c282bb4bf51686a07bf0b4ca3 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Thu, 18 May 2017 16:11:39 +0300 Subject: [PATCH 0324/2161] Remove RAM-trampoline array support --- doc/cc65.sgml | 5 ++--- src/cc65/pragma.c | 2 +- test/val/trampoline.c | 4 ---- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index d87fa47a7..2e480e4c3 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1232,9 +1232,8 @@ parameter with the <tt/#pragma/. <sect1><tt>#pragma wrapped-call (<push&rt;, <name>, <identifier>)</tt><label id="pragma-wrapped-call"><p> This pragma sets a wrapper for functions, often used for trampolines. - The name is either a function returning void and taking no parameters, - or the address of an array in memory (for a RAM trampoline). The identifier - is an 8-bit number that's set to tmp4. + The name is a function returning void and taking no parameters. + The identifier is an 8-bit number that's set to tmp4. The address of the function is passed in ptr4. diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 98f1a20d0..2cd510ff8 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -509,7 +509,7 @@ static void WrappedCallPragma (StrBuf* B) Entry = FindSym(Name); /* Check if the name is valid */ - if (Entry && Entry->Flags & (SC_FUNC | SC_STORAGE)) { + if (Entry && Entry->Flags & SC_FUNC) { PushWrappedCall(Entry, Val); Entry->Flags |= SC_REF; diff --git a/test/val/trampoline.c b/test/val/trampoline.c index aad4c96ea..6723df9b3 100644 --- a/test/val/trampoline.c +++ b/test/val/trampoline.c @@ -22,10 +22,6 @@ void func3() { } -unsigned char array[30]; -#pragma wrapped-call(push, array, 0) -#pragma wrapped-call(pop) - #pragma wrapped-call(push, trampoline_inc, 0) void func2() { From 219b239a347fd07742e09628599f5d7e4f987253 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Thu, 18 May 2017 17:14:26 +0300 Subject: [PATCH 0325/2161] Adjustments in response to latest comments --- src/cc65/funcdesc.h | 4 ++-- src/cc65/pragma.c | 2 +- test/val/trampoline.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h index 966aff573..040f6e97c 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -67,8 +67,8 @@ struct FuncDesc { unsigned ParamCount; /* Number of parameters */ unsigned ParamSize; /* Size of the parameters */ struct SymEntry* LastParam; /* Pointer to last parameter */ - struct SymEntry* WrappedCall; /* Pointer to the WrappedCall */ - unsigned char WrappedCallData; /* The WrappedCall's user data */ + struct SymEntry* WrappedCall; /* Pointer to the WrappedCall */ + unsigned char WrappedCallData;/* The WrappedCall's user data */ }; diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2cd510ff8..8d5dfd8b1 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -517,7 +517,7 @@ static void WrappedCallPragma (StrBuf* B) } else { /* Segment name is invalid */ - Error ("Wrapped-call target does not exist or is not a function or array"); + Error ("Wrapped-call target does not exist or is not a function"); } diff --git a/test/val/trampoline.c b/test/val/trampoline.c index 6723df9b3..63741b590 100644 --- a/test/val/trampoline.c +++ b/test/val/trampoline.c @@ -1,5 +1,5 @@ /* - !!DESCRIPTION!! trampoline pragma + !!DESCRIPTION!! wrapped-call pragma used for trampolines !!ORIGIN!! cc65 regression tests !!LICENCE!! Public Domain !!AUTHOR!! Lauri Kasanen From 70b541b81ea01561f8e8d19a8f195ef55e76bc6d Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Thu, 18 May 2017 21:21:02 +0200 Subject: [PATCH 0326/2161] Changed section --- doc/vic20.sgml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/vic20.sgml b/doc/vic20.sgml index 889cc266e..26a4aa558 100644 --- a/doc/vic20.sgml +++ b/doc/vic20.sgml @@ -182,13 +182,14 @@ No VIC1011 drivers are currently available for the VIC20. <sect>Limitations<p> - -<sect>Other hints<p> - - <sect1>Escape code<p> -For an Esc, pressing CTRL and the <tt/[/ key is not supported. +The CTRL key cannot be used to type most control characters, +entering an Esc is not possible. + + + +<sect>Other hints<p> <sect1>Passing arguments to the program<p> From 16a2beaaca0b05b47417a396048003121e51c9ea Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 18 May 2017 22:40:18 +0200 Subject: [PATCH 0327/2161] Adjusted VS project files to commit https://github.com/cc65/cc65/commit/11b01b908d321c39d86de1dd12102eaa6f4053e9 --- src/cc65.vcxproj | 2 ++ src/common.vcxproj | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 1c1f993fe..70f43dc73 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -145,6 +145,7 @@ <ClInclude Include="cc65\typecmp.h" /> <ClInclude Include="cc65\typeconv.h" /> <ClInclude Include="cc65\util.h" /> + <ClInclude Include="cc65\wrappedcall.h" /> </ItemGroup> <ItemGroup> <ClCompile Include="cc65\anonname.c" /> @@ -218,6 +219,7 @@ <ClCompile Include="cc65\typecmp.c" /> <ClCompile Include="cc65\typeconv.c" /> <ClCompile Include="cc65\util.c" /> + <ClCompile Include="cc65\wrappedcall.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> diff --git a/src/common.vcxproj b/src/common.vcxproj index 053d23981..39fea35e5 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -38,6 +38,7 @@ <ClInclude Include="common\hashtab.h" /> <ClInclude Include="common\hlldbgsym.h" /> <ClInclude Include="common\inline.h" /> + <ClInclude Include="common\intptrstack.h" /> <ClInclude Include="common\intstack.h" /> <ClInclude Include="common\inttypes.h" /> <ClInclude Include="common\libdefs.h" /> @@ -87,6 +88,7 @@ <ClCompile Include="common\gentype.c" /> <ClCompile Include="common\hashfunc.c" /> <ClCompile Include="common\hashtab.c" /> + <ClCompile Include="common\intptrstack.c" /> <ClCompile Include="common\intstack.c" /> <ClCompile Include="common\matchpat.c" /> <ClCompile Include="common\mmodel.c" /> From 75028e41087b0d0efeb1e8b75ea31cb1f3fb8521 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Thu, 18 May 2017 23:58:10 +0200 Subject: [PATCH 0328/2161] shorter code --- libsrc/c128/joy/c128-stdjoy.s | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/libsrc/c128/joy/c128-stdjoy.s b/libsrc/c128/joy/c128-stdjoy.s index 119d3784f..a2caead1a 100644 --- a/libsrc/c128/joy/c128-stdjoy.s +++ b/libsrc/c128/joy/c128-stdjoy.s @@ -104,7 +104,7 @@ joy1: lda #$7F sei sta CIA1_PRA lda CIA1_PRB - cli +back: cli and #$1F eor #$1F rts @@ -118,9 +118,4 @@ joy2: ldx #0 sta CIA1_DDRA lda CIA1_PRA sty CIA1_DDRA - cli - and #$1F - eor #$1F - rts - - + jmp back From 80e6afd33522d4583f0753b85e4b75da0b79ebee Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Fri, 19 May 2017 14:20:04 +0300 Subject: [PATCH 0329/2161] Add two new trampoline test cases --- test/val/trampoline-params.c | 32 +++++++++++++++++++++++ test/val/trampoline-varargs.c | 48 +++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 test/val/trampoline-params.c create mode 100644 test/val/trampoline-varargs.c diff --git a/test/val/trampoline-params.c b/test/val/trampoline-params.c new file mode 100644 index 000000000..890e43e5f --- /dev/null +++ b/test/val/trampoline-params.c @@ -0,0 +1,32 @@ +/* + !!DESCRIPTION!! wrapped-call pragma w/ many params + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Lauri Kasanen +*/ + +#include <stdarg.h> + +static unsigned char flag; + +static void trampoline_set() { + asm("ldy tmp4"); + asm("sty %v", flag); + asm("jsr callptr4"); +} + +#pragma wrapped-call(push, trampoline_set, 4) +long adder(long in); +#pragma wrapped-call(pop) + +long adder(long in) { + + return in + 7; +} + +int main() { + + flag = 0; + + return adder(70436) == 70436 + 7 && flag == 4 ? 0 : 1; +} diff --git a/test/val/trampoline-varargs.c b/test/val/trampoline-varargs.c new file mode 100644 index 000000000..5d3377c68 --- /dev/null +++ b/test/val/trampoline-varargs.c @@ -0,0 +1,48 @@ +/* + !!DESCRIPTION!! wrapped-call pragma w/ varags + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Lauri Kasanen +*/ + +#include <stdarg.h> + +static unsigned char flag; + +static void trampoline_set() { + // The Y register is used for variadics - save and restore + asm("sty tmp3"); + + asm("ldy tmp4"); + asm("sty %v", flag); + + asm("ldy tmp3"); + asm("jsr callptr4"); +} + +#pragma wrapped-call(push, trampoline_set, 4) +unsigned adder(unsigned char num, ...); +#pragma wrapped-call(pop) + +unsigned adder(unsigned char num, ...) { + + unsigned char i; + unsigned sum = 0; + va_list ap; + va_start(ap, num); + + for (i = 0; i < num; i++) { + sum += va_arg(ap, unsigned); + } + + va_end(ap); + + return sum; +} + +int main() { + + flag = 0; + + return adder(3, 0, 5, 500) == 505 && flag == 4 ? 0 : 1; +} From 901ac80026f3defad4c143d2336558384bd763ad Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Fri, 19 May 2017 15:20:36 +0300 Subject: [PATCH 0330/2161] Wrapper functions use all registers --- src/cc65/codeinfo.c | 4 ++++ src/cc65/funcdesc.h | 3 ++- src/cc65/pragma.c | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index de51781a6..06c66baf4 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -401,6 +401,10 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) */ if ((D->Flags & FD_VARIADIC) != 0) { *Use = REG_Y; + } else if (D->Flags & FD_CALL_WRAPPER) { + /* Wrappers may go to any functions, so mark them as using all + registers */ + *Use = REG_EAXY; } else if (D->ParamCount > 0 && (AutoCDecl ? IsQualFastcall (E->Type) : diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h index 040f6e97c..a04ffb14a 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -52,9 +52,10 @@ #define FD_OLDSTYLE 0x0010U /* Old style (K&R) function */ #define FD_OLDSTYLE_INTRET 0x0020U /* K&R func has implicit int return */ #define FD_UNNAMED_PARAMS 0x0040U /* Function has unnamed params */ +#define FD_CALL_WRAPPER 0x0080U /* This function is used as a wrapper */ /* Bits that must be ignored when comparing funcs */ -#define FD_IGNORE (FD_OLDSTYLE | FD_OLDSTYLE_INTRET | FD_UNNAMED_PARAMS) +#define FD_IGNORE (FD_OLDSTYLE | FD_OLDSTYLE_INTRET | FD_UNNAMED_PARAMS | FD_CALL_WRAPPER) diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 8d5dfd8b1..3dfc62668 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -513,6 +513,7 @@ static void WrappedCallPragma (StrBuf* B) PushWrappedCall(Entry, Val); Entry->Flags |= SC_REF; + Entry->V.F.Func->Flags |= FD_CALL_WRAPPER; } else { From e8a735492de02f1ab7dc5f28a24dc1c5022c0d82 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Fri, 19 May 2017 15:38:50 +0300 Subject: [PATCH 0331/2161] Correct comment style --- src/cc65/codeinfo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 06c66baf4..e9d98f5b8 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -403,7 +403,8 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) *Use = REG_Y; } else if (D->Flags & FD_CALL_WRAPPER) { /* Wrappers may go to any functions, so mark them as using all - registers */ + ** registers. + */ *Use = REG_EAXY; } else if (D->ParamCount > 0 && (AutoCDecl ? From 39e55bdb77bc6a2ba6ea7748e5c02c814685f0c0 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 20 May 2017 01:41:49 -0400 Subject: [PATCH 0332/2161] Added more info to the documentation of "#pragma wrapped-call". --- doc/cc65.sgml | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 2e480e4c3..3689c0b35 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -4,7 +4,7 @@ <title>cc65 Users Guide <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:gregdk@users.sf.net" name="Greg King"> -<date>2017-03-21 +<date>2017-05-20 <abstract> cc65 is a C compiler for 6502 targets. It supports several 6502 based home @@ -1229,27 +1229,36 @@ parameter with the <tt/#pragma/. </verb></tscreen> -<sect1><tt>#pragma wrapped-call (<push&rt;, <name>, <identifier>)</tt><label id="pragma-wrapped-call"><p> +<sect1><tt>#pragma wrapped-call (push, <name>, <identifier>)</tt><label id="pragma-wrapped-call"><p> This pragma sets a wrapper for functions, often used for trampolines. - The name is a function returning void and taking no parameters. - The identifier is an 8-bit number that's set to tmp4. - The address of the function is passed in ptr4. + The name is a function returning <tt/void/, and taking no parameters. + It must preserve the CPU's <tt/A/ and <tt/X/ registers if it wraps any + <tt/__fastcall__/ functions that have parameters. It must preserve + the <tt/Y/ register if it wraps any variadic functions (they have "<tt/.../" + in their prototypes). - This is useful for example with banked memory, to automatically - switch banks to where this function resides, and then restore - the bank when it returns. + The identifier is an 8-bit number that's set into <tt/tmp4/. - The <tt/#pragma/ requires the push and pop parameters as explained above. + The address of a wrapped function is passed in <tt/ptr4/. The wrapper can + call that function by using "<tt/jsr callptr4/". + + This feature is useful, for example, with banked memory, to switch banks + automatically to where a wrapped function resides, and then to restore the + previous bank when it returns. + + The <tt/#pragma/ requires the push or pop argument as explained above. Example: <tscreen><verb> - void mytrampoline(void); +/* Note that this code can be in a header. */ +void mytrampoline(void); /* Doesn't corrupt __AX__ */ - #pragma wrapped-call (push, mytrampoline, 0) - void somefunc(void); - #pragma wrapped-call (pop) +#pragma wrapped-call (push, mytrampoline, 5) +void somefunc1(void); +void somefunc2(int, char *); +#pragma wrapped-call (pop) </verb></tscreen> From 05b73276c2ff1b6ea88735c1d78a9da8e1d8cabc Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Sat, 20 May 2017 09:53:30 +0300 Subject: [PATCH 0333/2161] Update test description --- test/val/trampoline-varargs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/val/trampoline-varargs.c b/test/val/trampoline-varargs.c index 5d3377c68..d154a3da0 100644 --- a/test/val/trampoline-varargs.c +++ b/test/val/trampoline-varargs.c @@ -1,5 +1,5 @@ /* - !!DESCRIPTION!! wrapped-call pragma w/ varags + !!DESCRIPTION!! wrapped-call pragma w/ variadic function !!ORIGIN!! cc65 regression tests !!LICENCE!! Public Domain !!AUTHOR!! Lauri Kasanen From 3157e4be1ec7f2a5ac61ca45b232cd07c5e30483 Mon Sep 17 00:00:00 2001 From: mc78 <mc78@outlook.de> Date: Mon, 22 May 2017 23:07:31 +0200 Subject: [PATCH 0334/2161] added empty lines and spaces according to olivers comments. Made local functions static. --- src/cl65/main.c | 55 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index e428c96ac..6926199f9 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -156,22 +156,36 @@ static char* TargetLib = 0; # endif #endif + + /*****************************************************************************/ /* Credential functions */ /*****************************************************************************/ -void DisableAssembling(void){ + + + +static void DisableAssembling (void) +{ DoAssemble = 0; } -void DisableLinking(void){ + + +static void DisableLinking (void) +{ DoLink = 0; } -void DisableAssemblingAndLinking(void){ + + +static void DisableAssemblingAndLinking (void) +{ DisableAssembling(); DisableLinking(); } + + /*****************************************************************************/ /* Command structure handling */ /*****************************************************************************/ @@ -1427,22 +1441,33 @@ int main (int argc, char* argv []) break; case 'E': - /*Forward -E to compiler*/ + /* Forward -E to compiler */ CmdAddArg (&CC65, Arg); DisableAssemblingAndLinking(); break; + case 'W': - if (Arg[2] == 'a' && Arg[3] == '\0') { - /* -Wa: Pass options to assembler */ - OptAsmArgs (Arg, GetArg (&I, 3)); - } else if (Arg[2] == 'c' && Arg[3] == '\0') { - /* -Wc: Pass options to compiler */ - /* Remember -Wc sub arguments in cc65 arg struct */ - OptCCArgs (Arg, GetArg (&I, 3)); - } else if (Arg[2] == 'l' && Arg[3] == '\0') { - /* -Wl: Pass options to linker */ - OptLdArgs (Arg, GetArg (&I, 3)); - } else { + /* avoid && with'\0' in if clauses */ + if (Arg[3] == '\0') { + switch (Arg[2]) { + case 'a': + /* -Wa: Pass options to assembler */ + OptAsmArgs (Arg, GetArg (&I, 3)); + break; + case 'c': + /* -Wc: Pass options to compiler + ** Remember -Wc sub arguments in cc65 arg struct + */ + OptCCArgs (Arg, GetArg (&I, 3)); + break; + case 'l': + /* -Wl: Pass options to linker */ + OptLdArgs (Arg, GetArg (&I, 3)); + break; + default: + break; + } + }else { /* Anything else: Suppress warnings (compiler) */ CmdAddArg2 (&CC65, "-W", GetArg (&I, 2)); } From 21b1add98464367bef7819654f1643337c65260b Mon Sep 17 00:00:00 2001 From: mc78 <mc78@outlook.de> Date: Mon, 22 May 2017 23:21:55 +0200 Subject: [PATCH 0335/2161] added four escaped tabs to -E Stop after .... description --- 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 6926199f9..8252b61ff 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -734,7 +734,7 @@ static void Usage (void) " -C name\t\t\tUse linker config file\n" " -Cl\t\t\t\tMake local variables static\n" " -D sym[=defn]\t\t\tDefine a preprocessor symbol\n" - " -E Stop after the preprocessing stage\n" + " -E\t\t\t\tStop after the preprocessing stage\n" " -I dir\t\t\tSet a compiler include directory path\n" " -L path\t\t\tSpecify a library search path\n" " -Ln name\t\t\tCreate a VICE label file\n" From d9a8c300538f7778e5823350a9f0e8eccc7b88cd Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 22 May 2017 23:53:51 +0200 Subject: [PATCH 0336/2161] typo --- doc/funcref.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index d4c2f3fe1..d160082bf 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -3710,7 +3710,7 @@ fastcall function, so it may only be used in presence of a prototype. <quote> <descrip> -<tag/Function/Check if a given character is a a white-space character. +<tag/Function/Check if a given character is a white-space character. <tag/Header/<tt/<ref id="ctype.h" name="ctype.h">/ <tag/Declaration/<tt/int __fastcall__ isspace (int c);/ <tag/Description/The function returns a non zero value if the given argument From 355696d17da9147d12f63de855ec5ff089f0c285 Mon Sep 17 00:00:00 2001 From: Brad Smith <rainwarrior@gmail.com> Date: Mon, 22 May 2017 21:33:02 -0400 Subject: [PATCH 0337/2161] ca65 documentation of .define macros, making note that parentheses in ca65 macros are problematic especially when thinking of them as "C style", replacing unclear example with an example showing how accidental parentheses can cause a problem. --- doc/ca65.sgml | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 6ce5ecef6..74e081985 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -4282,6 +4282,12 @@ different: some things may be done with both macro types, each type has special usages. The types complement each other. +<item> Parentheses work differently from C macros. + The common practice of wrapping C macros in parentheses may cause + unintended problems here, such as accidentally implying an + indirect addressing mode. While the definition of a macro requires + parentheses around its argument list, when invoked they should not be included. + </itemize> Let's look at a few examples to make the advantages and disadvantages @@ -4314,20 +4320,18 @@ Macros with parameters may also be useful: DEBUG "Assembling include file #3" </verb></tscreen> -Note that, while formal parameters have to be placed in braces, this is -not true for the actual parameters. Beware: Since the assembler cannot -detect the end of one parameter, only the first token is used. If you -don't like that, use classic macros instead: +Note that, while formal parameters have to be placed in braces, +the actual parameters used when invoking the macro should not use braces. +The invoked parameters are separated by commas only, if parentheses are +used by accident they will become part of the replaced token: <tscreen><verb> -.macro DEBUG message - .out message -.endmacro +.define COMBINE(ta,tb,tc) ta+tb*10+tc*100 + + COMBINE 5,6,7 ; 5+6*10+7*100 = 765 correct + COMBINE(5,6,7) ; (5+6*10+7)*100 = 7200 incorrect! </verb></tscreen> -(That is an example where a problem can be solved with both macro types). - - <sect1>Characters in macros<p> When using the <ref id="option-t" name="-t"> option, characters are translated From f87a575d4d32f0f2386ebd7c24dc73953eed2bef Mon Sep 17 00:00:00 2001 From: mc78 <mc78@outlook.de> Date: Tue, 23 May 2017 22:57:27 +0200 Subject: [PATCH 0338/2161] added missing spaces before braces. added unknown option msg if not given -Wc|l|a when passing options to subprocess --- src/cl65/main.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index 8252b61ff..b209cb21d 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -180,8 +180,8 @@ static void DisableLinking (void) static void DisableAssemblingAndLinking (void) { - DisableAssembling(); - DisableLinking(); + DisableAssembling (); + DisableLinking (); } @@ -1427,7 +1427,7 @@ int main (int argc, char* argv []) case 'S': /* Dont assemble and link the created files */ - DisableAssemblingAndLinking(); + DisableAssemblingAndLinking (); break; case 'T': @@ -1443,7 +1443,7 @@ int main (int argc, char* argv []) case 'E': /* Forward -E to compiler */ CmdAddArg (&CC65, Arg); - DisableAssemblingAndLinking(); + DisableAssemblingAndLinking (); break; case 'W': @@ -1465,9 +1465,10 @@ int main (int argc, char* argv []) OptLdArgs (Arg, GetArg (&I, 3)); break; default: + UnknownOption (Arg); break; } - }else { + } else { /* Anything else: Suppress warnings (compiler) */ CmdAddArg2 (&CC65, "-W", GetArg (&I, 2)); } @@ -1475,7 +1476,7 @@ int main (int argc, char* argv []) case 'c': /* Don't link the resulting files */ - DisableLinking(); + DisableLinking (); break; case 'd': From 051cf11ce69ce147ff747c44e2732bf75a982c79 Mon Sep 17 00:00:00 2001 From: Brad Smith <rainwarrior@gmail.com> Date: Tue, 23 May 2017 17:07:45 -0400 Subject: [PATCH 0339/2161] expanding macro examples, trying to adhere to style guidelines --- doc/ca65.sgml | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 74e081985..d0a3d80e7 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -4286,7 +4286,8 @@ different: The common practice of wrapping C macros in parentheses may cause unintended problems here, such as accidentally implying an indirect addressing mode. While the definition of a macro requires - parentheses around its argument list, when invoked they should not be included. + parentheses around its argument list, when invoked they should not be + included. </itemize> @@ -4320,18 +4321,44 @@ Macros with parameters may also be useful: DEBUG "Assembling include file #3" </verb></tscreen> -Note that, while formal parameters have to be placed in braces, -the actual parameters used when invoking the macro should not use braces. -The invoked parameters are separated by commas only, if parentheses are -used by accident they will become part of the replaced token: +Note that, while formal parameters have to be placed in parentheses, +the actual argument used when invoking the macro should not be. +The invoked arguments are separated by commas only, if parentheses are +used by accident they will become part of the replaced token. + +If you wish to have an expression follow the macro invocation, the +last parameter can be enclosed in curly braces {} to indicate the end of that +argument. + +Examples: <tscreen><verb> .define COMBINE(ta,tb,tc) ta+tb*10+tc*100 - COMBINE 5,6,7 ; 5+6*10+7*100 = 765 correct - COMBINE(5,6,7) ; (5+6*10+7)*100 = 7200 incorrect! +.word COMBINE 5,6,7 ; 5+6*10+7*100 = 765 +.word COMBINE(5,6,7) ; (5+6*10+7)*100 = 7200 ; incorrect use of parentheses +.word COMBINE 5,6,7+1 ; 5+6*10+7+1*100 = 172 +.word COMBINE 5,6,{7}+1 ; 5+6*10+7*100+1 = 766 ; {} encloses the argument +.word COMBINE 5,6-2,7 ; 5+6-2*10+7*100 = 691 +.word COMBINE 5,(6-2),7 ; 5+(6-2)*10+7*100 = 745 +.word COMBINE 5,6,7+COMBINE 0,1,2 ; 5+6*10+7+0+1*10+2*100*100 = 20082 +.word COMBINE 5,6,{7}+COMBINE 0,1,2 ; 5+6*10+7*100+0+1*10+2*100 = 975 </verb></tscreen> +With C macros it is common to enclose the results in parentheses to +prevent unintended interactions with the text of the arguments, but +additional care must be taken in this assembly context where parentheses +may alter the meaning of a statement. In particular, indirect addressing modes +may be accidentally implied: + +<tscreen><verb> +.define DUO(ta,tb) (ta+(tb*10)) + + lda DUO(5,4), Y ; LDA (indirect), Y + lda 0+DUO(5,4), Y ; LDA absolute indexed, Y +</verb></tscreen> + + <sect1>Characters in macros<p> When using the <ref id="option-t" name="-t"> option, characters are translated From 87a9e0ce4f88a69b2db2c047074894f05c4b8f56 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 24 May 2017 00:04:52 +0200 Subject: [PATCH 0340/2161] clean-up --- doc/telestrat.sgml | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index fda4dee86..243097a84 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -4,13 +4,14 @@ <title>Oric Telestrat-specific information for cc65 <author> -<url url="mailto:jede@oric.org" name="Jede">,<newline> +<url url="mailto:jede@oric.org" name="Jede"> <date>2017-01-22 <abstract> -An overview over the Telestrat (Telemon 3.0 : http://orix.oric.org) runtime system as it is implemented for the cc65 C -compiler.) +An overview over the Telestrat (<url name="Telemon 3.0" +url="http://orix.oric.org">) runtime system as it is implemented for the +cc65 C compiler. </abstract> <!-- Table of contents --> @@ -32,25 +33,28 @@ information. <sect>Binary format<p> -The standard binary output format generated the linker for the Telestrat target -is a machine language program with a 20 bytes header described here : http://orix.oric.org/doku.php?id=orix:header +The standard binary output format generated the linker for the Telestrat +target is a machine language program with a 20 bytes header described <url +name="here" url="http://orix.oric.org/doku.php?id=orix:header"> -This header is used for Telemon 3.0. +This header is used for Telemon 3.0. -Anyway, for Telemon 2.4, there is no file management, there is no TAPE routine in Telemon, there is no way to load a binary easily. +Anyway, for Telemon 2.4, there is no file management, there is no TAPE routine in Telemon, there is no way to load a binary easily. -Stratsed (the Telestrat operating system) handles files management. Stratsed is loaded to memory from floppy disk. +Stratsed (the Telestrat operating system) handles files management. Stratsed is loaded to memory from floppy disk. -There is no tool to insert a binary in a Stratsed floppy disk. +There is no tool to insert a binary in a Stratsed floppy disk. -The only way to load a binary (for Telemon 2.4) is to : +The only way to load a binary (for Telemon 2.4) is to: <itemize> <item>remove the 20 bytes header -<item>download osdk : http://osdk.defence-force.org/index?page=download +<item>download <url name="osdk" url="http://osdk.defence-force.org/index?page=download"> <item>use Floppybuilder in OSDK to insert the binary with the tool (please read FloppyBuilder manual to insert your binary, and to start microdisc boot sector when Telestrat starts) </itemize> -Please note also, that the binary converted into TAP file, will not produce a right stratsed file when tap2dsk and old2mfm are used. You will be in the case that Telestrat/Stratsed crashed when you do "DIR" command. +Please note also, that the binary converted into TAP file, will not produce +a right stratsed file when tap2dsk and old2mfm are used. You will be in the +case that Telestrat/Stratsed crashed when you do "DIR" command. If you know the Stratsed disk format, please contact the author of this doc. @@ -79,7 +83,7 @@ Special locations: <sect>Platform-specific header files<p> -Programs containing Telestrat -specific code may use the <tt/telestrat.h/ header file. +Programs containing Telestrat-specific code may use the <tt/telestrat.h/ header file. <sect1>Telestrat-specific functions<p> @@ -147,8 +151,12 @@ Telestrat has a RS232 port, but it's not used <sect1>Disk I/O<p> -Telemon 3.0 handles fopen, fread, fclose primitives. It means that this function will crash the Telestrat because Telemon 2.4 does not have these primitives. -By the way, Telemon 3.0 uses an extension "ch376 card" which handles sdcard and FAT 32 usb key. In the next version of Telemon, FT DOS, Sedoric, Stratsed will be handled in these 3 primitives (fopen, fread, fclose). +Telemon 3.0 handles fopen, fread, fclose primitives. It means that this +function will crash the Telestrat because Telemon 2.4 does not have these +primitives. By the way, Telemon 3.0 uses an extension "ch376 card" which +handles sdcard and FAT 32 usb key. In the next version of Telemon, FT DOS, +Sedoric, Stratsed will be handled in these 3 primitives (fopen, fread, +fclose). <itemize> <item>fclose From ca1b9deb592e25889f75cc0a9f32b198e8de011c Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 24 May 2017 16:47:12 -0400 Subject: [PATCH 0341/2161] Added a description of the "-E" command-line option to cl65's document. Improved other descriptions, to make them more consistent and accurate. --- doc/cl65.sgml | 91 +++++++++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 40 deletions(-) diff --git a/doc/cl65.sgml b/doc/cl65.sgml index ffeba2321..8b3c02cbb 100644 --- a/doc/cl65.sgml +++ b/doc/cl65.sgml @@ -2,8 +2,9 @@ <article> <title>cl65 Users Guide -<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>01.08.2000, 27.11.2000, 02.10.2001 +<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> +<url url="mailto:greg.king5@verizon.net" name="Greg King"> +<date>2017-05-24 <abstract> cl65 is the compile & link utility for cc65, the 6502 C compiler. It was @@ -50,6 +51,7 @@ Short options: -C name Use linker config file -Cl Make local variables static -D sym[=defn] Define a preprocessor symbol + -E Stop after the preprocessing stage -I dir Set a compiler include directory path -L path Specify a library search path -Ln name Create a VICE label file @@ -120,56 +122,66 @@ Long options: --------------------------------------------------------------------------- </verb></tscreen> -Most of the options have the same meaning than the corresponding compiler, -assembler or linker option. See the documentation for these tools for an +Most of the options have the same meanings as the corresponding compiler, +assembler, and linker options. See the documentation for those tools for an explanation. If an option is available for more than one of the tools, it -is set for all tools, where it is available. One example for this is <tt/-v/: -The compiler, the assembler and the linker are all called with the <tt/-v/ +is set for all tools where it is available. One example for that is <tt/-v/: +The compiler, the assembler, and the linker are all called with the <tt/-v/ switch. There are a few remaining options that control the behaviour of cl65: <descrip> + <tag><tt>-E</tt></tag> + + This option is passed to the cc65 compiler; and, it forces cl65 to stop + before the assembly step. That means that C-level preprocessor directives + are obeyed; and, macroes are expanded. But, the C source isn't compiled. + If the <tt/-o/ option isn't used, then the C code results are written into + files with a ".i" suffix on their base names. Assembler files, object + files, and libraries given on the command line are ignored. + + <tag><tt>-S</tt></tag> - This option forces cl65 to stop after the assembly step. This means that - C files are translated into assembler files, but nothing more is done. - Assembler files, object files and libraries given on the command line + This option forces cl65 to stop before the assembly step. That means that + C files are translated into assembler files; but, nothing more is done. + Assembler files, object files, and libraries given on the command line are ignored. <tag><tt>-c</tt></tag> - This options forces cl65 to stop after the assembly step. This means + This option forces cl65 to stop after the assembly step. That means that C and assembler files given on the command line are translated into - object files, but there is no link step, and object files and libraries + object files; but, there is no link step. Object files and libraries given on the command line are ignored. <tag><tt>-o name</tt></tag> - The -o option is used for the target name in the final step. This causes - problems, if the linker will not be called, and there are several input - files on the command line. In this case, the name given with -o will be + The -o option is used for the target name in the final step. That causes + problems if the linker will not be called, and there are several input + files on the command line. In that case, the name given with -o will be used for all of them, which makes the option pretty useless. You - shouldn't use -o when more than one output file is created. + shouldn't use <tt/-o/ when more than one output file is created. <tag><tt>--print-target-path</tt></tag> - This option prints the absolute path of the target file directory and exits + This option prints the absolute path of the target file directory, and exits then. It is supposed to be used with shell backquotes or the GNU make shell - function. This way you can write build scripts or Makefiles accessing target + function. That way, you can write build scripts or Makefiles accessing target files without any assumption about the cc65 installation path. <tag><tt>-t sys, --target sys</tt></tag> - The default for this option is different from the compiler and linker in the - case that the option is missing: While the other tools (compiler, assembler + The default for this option is different from the compiler and linker, in the + case that the option is missing: While the other tools (compiler, assembler, and linker) will use the "none" system settings by default, cl65 will use - the C64 as a target system by default. This was chosen since most people + "c64" as a target system by default. That was chosen because most people seem to use cc65 to develop for the C64. @@ -177,10 +189,10 @@ There are a few remaining options that control the behaviour of cl65: Pass options directly to the assembler. This may be used to pass options that aren't directly supported by cl65. Several options may be separated by - commas, the commas are replaced by spaces when passing them to the - assembler. Beware: Passing arguments directly to the assembler may interfere - with some of the defaults, because cl65 doesn't parse the options passed. So - if cl65 supports an option by itself, do not pass this option to the + commas; the commas are replaced by spaces when passing them to the + assembler. Beware: Passing arguments directly to the assembler might interfere + with some of the defaults because cl65 doesn't parse the options passed. So, + if cl65 supports an option by itself, do not pass that option to the assembler by means of the <tt/-Wa/ switch. @@ -188,10 +200,10 @@ There are a few remaining options that control the behaviour of cl65: Pass options directly to the compiler. This may be used to pass options that aren't directly supported by cl65. Several options may be separated by - commas, the commas are replaced by spaces when passing them to the - compiler. Beware: Passing arguments directly to the compiler may interfere - with some of the defaults, because cl65 doesn't parse the options passed. So - if cl65 supports an option by itself, do not pass this option to the + commas; the commas are replaced by spaces when passing them to the + compiler. Beware: Passing arguments directly to the compiler might interfere + with some of the defaults because cl65 doesn't parse the options passed. So, + if cl65 supports an option by itself, do not pass that option to the compiler by means of the <tt/-Wc/ switch. @@ -199,10 +211,10 @@ There are a few remaining options that control the behaviour of cl65: Pass options directly to the linker. This may be used to pass options that aren't directly supported by cl65. Several options may be separated by - commas, the commas are replaced by spaces when passing them to the linker. - Beware: Passing arguments directly to the linker may interfere with some of - the defaults, because cl65 doesn't parse the options passed. So if cl65 - supports an option by itself, do not pass this option to the linker by means + commas; the commas are replaced by spaces when passing them to the linker. + Beware: Passing arguments directly to the linker might interfere with some of + the defaults because cl65 doesn't parse the options passed. So, if cl65 + supports an option by itself, do not pass that option to the linker by means of the <tt/-Wl/ switch. </descrip> @@ -211,7 +223,7 @@ There are a few remaining options that control the behaviour of cl65: <sect>More usage<p> -Since cl65 was created to simplify the use of the cc65 development +Because cl65 was created to simplify the use of the cc65 development package, it tries to be smart about several things. <itemize> @@ -219,15 +231,14 @@ package, it tries to be smart about several things. <item> If you don't give a target system on the command line, cl65 defaults to the C64. -<item> When linking, cl65 will supply the names of the startup file and - library for the target system to the linker, so you don't have to do - that. +<item> When linking, cl65 will supply the name of the library file for + the target system to the linker; so, you don't have to do that. <item> If the final step is the linker, and the name of the output file was not explicitly given, cl65 will use the name of the first input file - without the extension, provided that the name of this file has an - extension. So you don't need to name the executable name in most - cases, just give the name of your "main" file as first input file. + without the extension, provided that the name of that file has an + extension. So, you don't need to give the executable name in most + cases; just give the name of your "main" file as the first input file. </itemize> The command line is parsed from left to right, and the actual processing tool @@ -248,7 +259,7 @@ The type of an input file is derived from its extension: <itemize> <item>C files: <tt/.c/ <item>Assembler files: <tt/.s/, <tt/.asm/, <tt/.a65/ -<item>Object files: <tt/.o/ <tt/.obj/ +<item>Object files: <tt/.o/, <tt/.obj/ <item>Libraries: <tt/.a/, <tt/.lib/ <item>GEOS resource files: <tt/.grc/ <item>o65 files: <tt/.o65/, <tt/.emd/, <tt/.joy/, <tt/.tgi/ From e31133c804ebb50ea89198445aec93d85584a7f8 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 24 May 2017 18:49:02 -0400 Subject: [PATCH 0342/2161] Added "html" and "info" goals to the top-level Makefile. They are for people who don't want to build both types of documents at the same time. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 808689c82..206f853fc 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: all mostlyclean clean install zip avail unavail bin lib doc samples +.PHONY: all mostlyclean clean install zip avail unavail bin lib doc html info samples .SUFFIXES: @@ -14,7 +14,7 @@ avail unavail bin: lib: @$(MAKE) -C libsrc --no-print-directory $@ -doc: +doc html info: @$(MAKE) -C doc --no-print-directory $@ samples: From 1602aab6e9aa4d89098404993526938c512d282a Mon Sep 17 00:00:00 2001 From: Brad Smith <rainwarrior@gmail.com> Date: Thu, 25 May 2017 03:01:25 -0400 Subject: [PATCH 0343/2161] forgot to update comments from earlier #323 rand.s change --- libsrc/common/rand.s | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/libsrc/common/rand.s b/libsrc/common/rand.s index 8ad7bcdb4..38d525b6b 100644 --- a/libsrc/common/rand.s +++ b/libsrc/common/rand.s @@ -2,6 +2,7 @@ ; Randum number generator ; ; Written and donated by Sidney Cadot - sidney@ch.twi.tudelft.nl +; 2016-11-07, modified by Brad Smith ; ; May be distributed with the cc65 runtime using the same license. ; @@ -13,10 +14,14 @@ ; Multiplier must be 1 (mod 4) ; Added value must be 1 (mod 2) ; This guarantees max. period (2**32) -; Bits 8-22 are returned (positive 2-byte int) -; where 0 is LSB, 31 is MSB. -; This is better as lower bits exhibit easily -; detectable patterns. +; The lowest bits have poor entropy and +; exhibit easily detectabl patterns, so +; only the upper bits 16-22 and 24-31 of the +; 4-byte state are returned. +; +; The best 8 bits, 24-31 are returned in the +; low byte A to provide the best entropy in the +; most commonly used part of the return value. ; .export _rand, _srand From 950d65e8ed4c95d8ada5540601b35cda35823a77 Mon Sep 17 00:00:00 2001 From: Brad Smith <rainwarrior@gmail.com> Date: Thu, 25 May 2017 03:20:11 -0400 Subject: [PATCH 0344/2161] detectabl > detectable --- libsrc/common/rand.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/common/rand.s b/libsrc/common/rand.s index 38d525b6b..102dd5be2 100644 --- a/libsrc/common/rand.s +++ b/libsrc/common/rand.s @@ -15,7 +15,7 @@ ; Added value must be 1 (mod 2) ; This guarantees max. period (2**32) ; The lowest bits have poor entropy and -; exhibit easily detectabl patterns, so +; exhibit easily detectable patterns, so ; only the upper bits 16-22 and 24-31 of the ; 4-byte state are returned. ; From 3b33af88cf4c3b6fff6e8b032fe5d5f9304ab599 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Fri, 26 May 2017 01:44:33 +0200 Subject: [PATCH 0345/2161] Oricutron mentioned --- doc/ld65.sgml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 5687aa8ab..8f9dd7093 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -247,10 +247,11 @@ Here is a description of all of the command-line options: <tag><tt>-Ln</tt></tag> This option allows you to create a file that contains all global labels and - may be loaded into the VICE emulator using the <tt/ll/ (load label) command. You + may be loaded into the VICE emulator using the <tt/ll/ (load label) command + or into the Oricutron emulator using the <tt/sl/ (symbols load) command. You may use this to debug your code with VICE. Note: Older versions had some bugs in the label code. If you have problems, please get the latest <url - url="http://vice-emu.sourceforge.net/" name="VICE"> version. + url="http://vice-emu.sourceforge.net" name="VICE"> version. <label id="option-S"> From ff339393859558323553aea89c1ecc90fcf55d01 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sun, 28 May 2017 00:29:53 +0200 Subject: [PATCH 0346/2161] Use verbosity --- src/ar65/list.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ar65/list.c b/src/ar65/list.c index 656299860..496bbcde0 100644 --- a/src/ar65/list.c +++ b/src/ar65/list.c @@ -36,6 +36,9 @@ #include <stdio.h> #include <stdlib.h> +/* common */ +#include "print.h" + /* ar65 */ #include "error.h" #include "library.h" @@ -73,6 +76,10 @@ void ListObjFiles (int argc, char* argv []) /* Get the entry */ O = CollConstAt (&ObjPool, I); + /* Print the size */ + if (Verbosity > 0) { + printf ("%5ld ", O->Size); + } /* Print the name */ printf ("%s\n", O->Name); From 9bdcb0a31bd5d164d7aa027e975e6c4b0da611af Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sun, 28 May 2017 00:35:38 +0200 Subject: [PATCH 0347/2161] More POSIX.2, staying compatible --- src/ar65/main.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ar65/main.c b/src/ar65/main.c index a1839bad2..9985f1f71 100644 --- a/src/ar65/main.c +++ b/src/ar65/main.c @@ -64,8 +64,8 @@ static void Usage (void) "Operations are some of:\n" "\ta\tAdd modules\n" "\td\tDelete modules\n" - "\tl\tList library contents\n" - "\tv\tIncrease verbosity (put before other operation)\n" + "\tt\tList library table\n" + "\tv\tIncrease verbosity (put after other operation)\n" "\tx\tExtract modules\n" "\tV\tPrint the archiver version\n", ProgName); @@ -94,10 +94,6 @@ int main (int argc, char* argv []) /* Get the argument */ const char* Arg = ArgVec [I]; - /* Check for an option */ - if (strlen (Arg) != 1) { - Usage (); - } switch (Arg [0]) { case 'a': @@ -108,7 +104,11 @@ int main (int argc, char* argv []) DelObjFiles (ArgCount - I - 1, &ArgVec [I+1]); break; - case 'l': + case 't': /* POSIX.2 */ + case 'l': /* staying compatible */ + if (Arg [1] == 'v') { + ++Verbosity; + } ListObjFiles (ArgCount - I - 1, &ArgVec [I+1]); break; From 843c5442b149ca12db80dcb5f55dc61da9feaa42 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sun, 28 May 2017 13:13:53 +0200 Subject: [PATCH 0348/2161] Update list.c --- src/ar65/list.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ar65/list.c b/src/ar65/list.c index 496bbcde0..e307e70a8 100644 --- a/src/ar65/list.c +++ b/src/ar65/list.c @@ -78,7 +78,7 @@ void ListObjFiles (int argc, char* argv []) /* Print the size */ if (Verbosity > 0) { - printf ("%5ld ", O->Size); + Print (stdout, 1, "%5lu ", O->Size); } /* Print the name */ printf ("%s\n", O->Name); From c9c2562c14aa296c69548bd089f5ba689abf2156 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sun, 28 May 2017 15:13:43 +0200 Subject: [PATCH 0349/2161] Update list.c --- src/ar65/list.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ar65/list.c b/src/ar65/list.c index e307e70a8..d65ad51e5 100644 --- a/src/ar65/list.c +++ b/src/ar65/list.c @@ -76,10 +76,8 @@ void ListObjFiles (int argc, char* argv []) /* Get the entry */ O = CollConstAt (&ObjPool, I); - /* Print the size */ - if (Verbosity > 0) { - Print (stdout, 1, "%5lu ", O->Size); - } + /* Print the size if verbose */ + Print (stdout, 1, "%5lu ", O->Size); /* Print the name */ printf ("%s\n", O->Name); From ea9430e28edc6b47a20bf3a94d05267a4c383569 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sun, 28 May 2017 15:22:33 +0200 Subject: [PATCH 0350/2161] Update list.c --- src/ar65/list.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ar65/list.c b/src/ar65/list.c index d65ad51e5..367c950dc 100644 --- a/src/ar65/list.c +++ b/src/ar65/list.c @@ -79,7 +79,7 @@ void ListObjFiles (int argc, char* argv []) /* Print the size if verbose */ Print (stdout, 1, "%5lu ", O->Size); /* Print the name */ - printf ("%s\n", O->Name); + puts (O->Name); } From 49e22f566fa04cfaf841797732c7bb9b08a96c01 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sun, 28 May 2017 15:29:49 +0200 Subject: [PATCH 0351/2161] Update main.c --- src/ar65/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ar65/main.c b/src/ar65/main.c index 9985f1f71..9fb5d6cf8 100644 --- a/src/ar65/main.c +++ b/src/ar65/main.c @@ -65,7 +65,7 @@ static void Usage (void) "\ta\tAdd modules\n" "\td\tDelete modules\n" "\tt\tList library table\n" - "\tv\tIncrease verbosity (put after other operation)\n" + "\tv\tIncrease verbosity (put before other operation)\n" "\tx\tExtract modules\n" "\tV\tPrint the archiver version\n", ProgName); From ed65eaf682f84abcf59739d8774d61f382e5ca04 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sun, 28 May 2017 16:12:02 +0200 Subject: [PATCH 0352/2161] Verbosity was missing; POSIX operations --- doc/ar65.sgml | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/doc/ar65.sgml b/doc/ar65.sgml index 136defd40..fa11cddb0 100644 --- a/doc/ar65.sgml +++ b/doc/ar65.sgml @@ -32,16 +32,17 @@ for the cc65 compiler. ar65 is part of this suite. The archiver is called as follows: <tscreen><verb> - Usage: ar65 <operation> lib file|module ... - Operation is one of: - a Add modules - d Delete modules - l List library contents - x Extract modules - V Print the archiver version + Usage: ar65 <operation ...> lib file|module ... + Operations are some of: + r Add modules + d Delete modules + t List library table + v Increase verbosity (put before other operation) + x Extract modules + V Print the archiver version </verb></tscreen> -You may add modules to a library using the `a' command. If the library +You may add modules to a library using the `r' command. If the library does not exist, it is created (and a warning message is printed which you may ignore if creation of the library was your intention). You may specify any number of modules on the command line following the library. @@ -53,7 +54,7 @@ has a newer timestamp than the one to add. Here's an example: <tscreen><verb> - ar65 a mysubs.lib sub1.o sub2.o + ar65 r mysubs.lib sub1.o sub2.o </verb></tscreen> This will add two modules to the library `mysubs.lib' creating the @@ -63,10 +64,10 @@ sub2.o, they are replaced by the new ones. Modules names in the library are stored without the path, so, using <tscreen><verb> - ar65 a mysubs.lib ofiles/sub1.o ofiles/sub2.o + ar65 v v r mysubs.lib ofiles/sub1.o ofiles/sub2.o </verb></tscreen> -will add two modules named `sub1.o' and `sub2.o' to the library. +will verbose add two modules named `sub1.o' and `sub2.o' to the library. Deleting modules from a library is done with the `d' command. You may not give a path when naming the modules. @@ -81,13 +82,13 @@ This will delete the module named `sub1.o' from the library, printing an error if the library does not contain that module. -The `l' command prints a list of all modules in the library. Any module +The `t' command prints a table of all modules in the library. Any module names on the command line are ignored. Example: <tscreen><verb> - ar65 l mysubs.lib + ar65 tv mysubs.lib </verb></tscreen> From 80feb80168eccc8b8097b9150c13deb848a8eb45 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sun, 28 May 2017 16:17:34 +0200 Subject: [PATCH 0353/2161] Update main.c --- src/ar65/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ar65/main.c b/src/ar65/main.c index 9fb5d6cf8..48561027f 100644 --- a/src/ar65/main.c +++ b/src/ar65/main.c @@ -62,7 +62,7 @@ static void Usage (void) { fprintf (stderr, "Usage: %s <operation ...> lib file|module ...\n" "Operations are some of:\n" - "\ta\tAdd modules\n" + "\tr\tAdd modules\n" "\td\tDelete modules\n" "\tt\tList library table\n" "\tv\tIncrease verbosity (put before other operation)\n" @@ -96,7 +96,8 @@ int main (int argc, char* argv []) switch (Arg [0]) { - case 'a': + case 'r': /* POSIX.2 */ + case 'a': /* staying compatible */ AddObjFiles (ArgCount - I - 1, &ArgVec[I+1]); break; From 0a011c31eab6ac137025b017c44677f929941df6 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sun, 28 May 2017 16:22:34 +0200 Subject: [PATCH 0354/2161] Update ar65.sgml --- doc/ar65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ar65.sgml b/doc/ar65.sgml index fa11cddb0..0a55a08c0 100644 --- a/doc/ar65.sgml +++ b/doc/ar65.sgml @@ -4,7 +4,7 @@ <title>ar65 Users Guide <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>19.07.2000 +<date>2017-05-28 <abstract> ar65 is an archiver for object files generated by ca65. It allows to create From 52642f6c8f8a2a8f687fff71661e403b0218bbdc Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 30 May 2017 02:05:35 +0200 Subject: [PATCH 0355/2161] Deprecated commands mentioned --- doc/ar65.sgml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/ar65.sgml b/doc/ar65.sgml index 0a55a08c0..2e01025ca 100644 --- a/doc/ar65.sgml +++ b/doc/ar65.sgml @@ -42,7 +42,7 @@ The archiver is called as follows: V Print the archiver version </verb></tscreen> -You may add modules to a library using the `r' command. If the library +You may add modules to a library using the `r' command (`a' is deprecated). If the library does not exist, it is created (and a warning message is printed which you may ignore if creation of the library was your intention). You may specify any number of modules on the command line following the library. @@ -82,8 +82,8 @@ This will delete the module named `sub1.o' from the library, printing an error if the library does not contain that module. -The `t' command prints a table of all modules in the library. Any module -names on the command line are ignored. +The `t' command prints a table of all modules in the library (`l' is deprecated). +Any module names on the command line are ignored. Example: From e75a59d7a8d9bce24a3c9731924ad3abd1ab109e Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Tue, 6 Jun 2017 18:48:25 +0300 Subject: [PATCH 0356/2161] Add LZ4 decompression support --- include/lz4.h | 44 +++ libsrc/common/lz4.s | 283 +++++++++++++++++++ test/val/lz4.c | 669 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 996 insertions(+) create mode 100644 include/lz4.h create mode 100644 libsrc/common/lz4.s create mode 100644 test/val/lz4.c diff --git a/include/lz4.h b/include/lz4.h new file mode 100644 index 000000000..d6bf1b17c --- /dev/null +++ b/include/lz4.h @@ -0,0 +1,44 @@ +/*****************************************************************************/ +/* */ +/* lz4.h */ +/* */ +/* Decompression routine for the 'lz4' format */ +/* */ +/* */ +/* */ +/* (C) 2017 Mega Cat Studios */ +/* */ +/* 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 _LZ4_H +#define _LZ4_H + +void __fastcall__ decompress_lz4 (const unsigned char* src, unsigned char* dst, + const unsigned short uncompressed_size); +/* + Decompresses the source buffer into the destination buffer. + The size of the decompressed data must be known in advance, LZ4 + does not include any terminator in-stream. +*/ + +/* end of lz4.h */ +#endif diff --git a/libsrc/common/lz4.s b/libsrc/common/lz4.s new file mode 100644 index 000000000..ee215d4da --- /dev/null +++ b/libsrc/common/lz4.s @@ -0,0 +1,283 @@ +; +; Lauri Kasanen, 6 Jun 2017 +; (C) Mega Cat Studios +; An optimized LZ4 decompressor +; + + .importzp sp, sreg, regsave, regbank + .importzp tmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 + .macpack longbranch + .import memcpy_upwards,pushax,popax + .export _decompress_lz4 + +_out = regsave +_written = regsave + 2 +_tmp = tmp1 +_token = tmp2 +_offset = ptr3 +_in = sreg +_outlen = ptr4 + +; --------------------------------------------------------------- +; void decompress_lz4 (const u8 *in, u8 * const out, const u16 outlen) +; --------------------------------------------------------------- + +.segment "CODE" + +.proc _decompress_lz4: near + + sta _outlen + stx _outlen+1 + + jsr popax + sta _out + stx _out+1 + + jsr popax + sta _in + stx _in+1 + +; +; written = 0; +; + lda #$00 + sta _written +; +; while (written < outlen) { +; + jmp L0046 +; +; token = *in++; +; +L0004: ldy #0 + lda (_in),y + sta _token + + inc _in + bne L000A + inc _in+1 +L000A: +; +; offset = token >> 4; +; + ldx #$00 + lsr a + lsr a + lsr a + lsr a + sta _offset + stx _offset+1 +; +; token &= 0xf; +; token += 4; // Minmatch +; + lda _token + and #$0F + clc + adc #4 + sta _token +; +; if (offset == 15) { +; + lda _offset + cmp #$0F +L0013: bne L001A +; +; tmp = *in++; +; + ldy #0 + lda (_in),y + sta _tmp + + inc _in + bne L0017 + inc _in+1 +L0017: +; +; offset += tmp; +; + clc + adc _offset + sta _offset + lda #$00 + adc _offset+1 + sta _offset+1 +; +; if (tmp == 255) +; + lda _tmp + cmp #$FF +; +; goto moreliterals; +; + jmp L0013 +; +; if (offset) { +; +L001A: lda _offset + ora _offset+1 + beq L001C +; +; memcpy(&out[written], in, offset); +; + lda _out + clc + adc _written + sta ptr2 + lda _out+1 + adc _written+1 + tax + lda ptr2 + stx ptr2+1 + jsr pushax + lda _in + ldx _in+1 + sta ptr1 + stx ptr1+1 + ldy #0 + jsr memcpy_upwards +; +; written += offset; +; + lda _offset + clc + adc _written + sta _written + lda _offset+1 + adc _written+1 + sta _written+1 +; +; in += offset; +; + lda _offset + clc + adc _in + sta _in + lda _offset+1 + adc _in+1 + sta _in+1 +; +; if (written >= outlen) +; +L001C: lda _written + cmp _outlen + lda _written+1 + sbc _outlen+1 +; +; return; +; + bcc L0047 + rts +; +; memcpy(&offset, in, 2); +; +L0047: ldy #0 + lda (_in),y + sta _offset + iny + lda (_in),y + sta _offset+1 +; +; in += 2; +; + lda #$02 + clc + adc _in + sta _in + bcc L002F + inc _in+1 +; +; copysrc = out + written - offset; +; +L002F: lda _out + clc + adc _written + pha + lda _out+1 + adc _written+1 + tax + pla + sec + sbc _offset + sta ptr1 + txa + sbc _offset+1 + sta ptr1+1 +; +; offset = token; +; + lda #$00 + sta _offset+1 + lda _token + sta _offset +; +; if (token == 19) { +; + cmp #$13 +L0045: bne L003C +; +; tmp = *in++; +; + ldy #0 + lda (_in),y + sta _tmp + + inc _in + bne L0039 + inc _in+1 +L0039: +; +; offset += tmp; +; + clc + adc _offset + sta _offset + tya + adc _offset+1 + sta _offset+1 +; +; if (tmp == 255) +; + lda _tmp + cmp #$FF +; +; goto morematches; +; + jmp L0045 +; +; memcpy(&out[written], copysrc, offset); +; +L003C: lda _out + clc + adc _written + sta ptr2 + lda _out+1 + adc _written+1 + tax + lda ptr2 + stx ptr2+1 + jsr pushax + jsr memcpy_upwards +; +; written += offset; +; + lda _offset + clc + adc _written + sta _written + lda _offset+1 + adc _written+1 +L0046: sta _written+1 +; +; while (written < outlen) { +; + lda _written + cmp _outlen + lda _written+1 + sbc _outlen+1 + jcc L0004 + + rts + +.endproc + diff --git a/test/val/lz4.c b/test/val/lz4.c new file mode 100644 index 000000000..dceefbfcc --- /dev/null +++ b/test/val/lz4.c @@ -0,0 +1,669 @@ +/* + !!DESCRIPTION!! lz4 decompression + !!ORIGIN!! cc65 regression tests + !!LICENCE!! BSD 2-clause + !!AUTHOR!! Lauri Kasanen +*/ + +#include <zlib.h> +#include <stdio.h> +#include <lz4.h> + +/* The sample data is the original lz4.h, compressed with lz4 hc */ +static const unsigned char compressed[] = { +0xf0, 0x1a, 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, 0x27, 0x00, 0xb0, 0x48, 0x65, +0x61, 0x64, 0x65, 0x72, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x0f, 0x00, 0xf0, +0x17, 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, 0x20, 0x43, 0x6f, 0x6c, 0x6c, 0x65, +0x74, 0x2e, 0x0a, 0x2a, 0x00, 0xf2, 0x22, 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, 0x23, 0x00, 0x63, 0x73, +0x2f, 0x62, 0x73, 0x64, 0x2d, 0x0d, 0x00, 0x51, 0x2e, 0x70, 0x68, 0x70, +0x29, 0x4e, 0x00, 0xb1, 0x52, 0x65, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, +0x62, 0x75, 0x74, 0xa3, 0x00, 0x30, 0x6e, 0x64, 0x20, 0x58, 0x00, 0x32, +0x69, 0x6e, 0x20, 0x43, 0x00, 0x01, 0x12, 0x00, 0xf1, 0x06, 0x62, 0x69, +0x6e, 0x61, 0x72, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x2c, 0x20, +0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x72, 0x08, 0x00, 0x30, 0x6f, 0x75, +0x74, 0x46, 0x00, 0x80, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, +0x44, 0x00, 0xf0, 0x22, 0x2c, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x65, +0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x20, 0x70, 0x72, 0x6f, 0x76, +0x69, 0x64, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, +0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, +0x63, 0x6f, 0x6e, 0x64, 0x69, 0x35, 0x00, 0x10, 0x73, 0x35, 0x00, 0x01, +0x4a, 0x00, 0x31, 0x65, 0x74, 0x3a, 0x99, 0x00, 0x00, 0x01, 0x00, 0x1b, +0x2a, 0x9f, 0x00, 0x44, 0x73, 0x20, 0x6f, 0x66, 0x98, 0x00, 0xf1, 0x01, +0x63, 0x6f, 0x64, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x72, 0x65, +0x74, 0x61, 0x69, 0x6e, 0x5a, 0x00, 0x40, 0x61, 0x62, 0x6f, 0x76, 0x1b, +0x00, 0x03, 0x4c, 0x01, 0x00, 0x48, 0x00, 0xf0, 0x02, 0x6e, 0x6f, 0x74, +0x69, 0x63, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6c, 0x69, +0x73, 0x74, 0x44, 0x00, 0x08, 0x78, 0x00, 0x2b, 0x6e, 0x64, 0x95, 0x00, +0xbf, 0x64, 0x69, 0x73, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x72, 0x2e, +0x89, 0x00, 0x07, 0x28, 0x69, 0x6e, 0x16, 0x01, 0x04, 0x89, 0x00, 0x76, +0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x8c, 0x00, 0x00, 0x41, 0x00, +0x05, 0x8f, 0x00, 0x0f, 0x8c, 0x00, 0x2a, 0x00, 0x4a, 0x00, 0x03, 0xe6, +0x00, 0x94, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0xb3, +0x01, 0xf6, 0x04, 0x2f, 0x6f, 0x72, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, +0x20, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x77, 0x01, +0x01, 0xaf, 0x01, 0x21, 0x74, 0x68, 0x8b, 0x00, 0x08, 0xc4, 0x00, 0x02, +0x4e, 0x02, 0xf0, 0x34, 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, 0x47, +0x00, 0x71, 0x22, 0x41, 0x53, 0x20, 0x49, 0x53, 0x22, 0x1c, 0x00, 0xf1, +0x26, 0x41, 0x4e, 0x59, 0x20, 0x45, 0x58, 0x50, 0x52, 0x45, 0x53, 0x53, +0x20, 0x4f, 0x52, 0x20, 0x49, 0x4d, 0x50, 0x4c, 0x49, 0x45, 0x44, 0x20, +0x57, 0x41, 0x52, 0x52, 0x41, 0x4e, 0x54, 0x49, 0x45, 0x53, 0x2c, 0x20, +0x49, 0x4e, 0x43, 0x4c, 0x55, 0x44, 0x49, 0x4e, 0x47, 0x2c, 0x20, 0x42, +0x55, 0x54, 0x20, 0x4e, 0x4f, 0x54, 0x3a, 0x03, 0xa1, 0x49, 0x4d, 0x49, +0x54, 0x45, 0x44, 0x20, 0x54, 0x4f, 0x2c, 0x7b, 0x00, 0x0e, 0x3a, 0x00, +0xf1, 0x04, 0x20, 0x4f, 0x46, 0x20, 0x4d, 0x45, 0x52, 0x43, 0x48, 0x41, +0x4e, 0x54, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x73, 0x00, 0x40, +0x46, 0x49, 0x54, 0x4e, 0x6f, 0x00, 0x30, 0x46, 0x4f, 0x52, 0x49, 0x00, +0xf0, 0x06, 0x41, 0x20, 0x50, 0x41, 0x52, 0x54, 0x49, 0x43, 0x55, 0x4c, +0x41, 0x52, 0x20, 0x50, 0x55, 0x52, 0x50, 0x4f, 0x53, 0x45, 0x20, 0xe0, +0x00, 0xfa, 0x0e, 0x44, 0x49, 0x53, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x45, +0x44, 0x2e, 0x20, 0x49, 0x4e, 0x20, 0x4e, 0x4f, 0x20, 0x45, 0x56, 0x45, +0x4e, 0x54, 0x20, 0x53, 0x48, 0x41, 0x4c, 0x4c, 0xef, 0x00, 0x00, 0x48, +0x00, 0x50, 0x4f, 0x57, 0x4e, 0x45, 0x52, 0xc4, 0x00, 0x08, 0xef, 0x00, +0xa0, 0x20, 0x42, 0x45, 0x20, 0x4c, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x6f, +0x00, 0x01, 0xee, 0x00, 0x60, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0xd7, +0x00, 0x06, 0x0a, 0x00, 0x90, 0x43, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x41, +0x4c, 0x2c, 0x49, 0x00, 0xf3, 0x04, 0x53, 0x50, 0x45, 0x43, 0x49, 0x41, +0x4c, 0x2c, 0x20, 0x45, 0x58, 0x45, 0x4d, 0x50, 0x4c, 0x41, 0x52, 0x59, +0x2c, 0x57, 0x00, 0xff, 0x05, 0x53, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x54, +0x49, 0x41, 0x4c, 0x20, 0x44, 0x41, 0x4d, 0x41, 0x47, 0x45, 0x53, 0x20, +0x28, 0x1e, 0x01, 0x0f, 0x80, 0x50, 0x52, 0x4f, 0x43, 0x55, 0x52, 0x45, +0x4d, 0xbc, 0x00, 0xf1, 0x03, 0x4f, 0x46, 0x20, 0x53, 0x55, 0x42, 0x53, +0x54, 0x49, 0x54, 0x55, 0x54, 0x45, 0x20, 0x47, 0x4f, 0x4f, 0x44, 0x77, +0x01, 0xd1, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x53, 0x3b, 0x20, +0x4c, 0x4f, 0x53, 0x39, 0x01, 0x31, 0x55, 0x53, 0x45, 0x8d, 0x00, 0x41, +0x44, 0x41, 0x54, 0x41, 0x7f, 0x00, 0x80, 0x50, 0x52, 0x4f, 0x46, 0x49, +0x54, 0x53, 0x3b, 0x0c, 0x00, 0x41, 0x42, 0x55, 0x53, 0x49, 0x43, 0x01, +0xf1, 0x0d, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x52, 0x55, 0x50, 0x54, 0x49, +0x4f, 0x4e, 0x29, 0x20, 0x48, 0x4f, 0x57, 0x45, 0x56, 0x45, 0x52, 0x20, +0x43, 0x41, 0x55, 0x53, 0x45, 0x44, 0x6c, 0x01, 0x20, 0x4f, 0x4e, 0xf4, +0x00, 0x02, 0x3c, 0x02, 0x40, 0x45, 0x4f, 0x52, 0x59, 0x5b, 0x00, 0x23, +0x4c, 0x49, 0x8e, 0x01, 0x90, 0x2c, 0x20, 0x57, 0x48, 0x45, 0x54, 0x48, +0x45, 0x52, 0x5f, 0x01, 0x01, 0x36, 0x01, 0x10, 0x41, 0x0f, 0x01, 0x68, +0x53, 0x54, 0x52, 0x49, 0x43, 0x54, 0x27, 0x00, 0x61, 0x4f, 0x52, 0x20, +0x54, 0x4f, 0x52, 0xd9, 0x00, 0x06, 0xf0, 0x00, 0xb0, 0x20, 0x4e, 0x45, +0x47, 0x4c, 0x49, 0x47, 0x45, 0x4e, 0x43, 0x45, 0x21, 0x00, 0x10, 0x4f, +0x49, 0x00, 0xa0, 0x57, 0x49, 0x53, 0x45, 0x29, 0x20, 0x41, 0x52, 0x49, +0x53, 0x21, 0x00, 0x11, 0x49, 0x7d, 0x00, 0x71, 0x20, 0x57, 0x41, 0x59, +0x20, 0x4f, 0x55, 0xfc, 0x00, 0x00, 0xb5, 0x01, 0x31, 0x55, 0x53, 0x45, +0xaf, 0x01, 0x1a, 0x46, 0xcf, 0x02, 0x11, 0x2c, 0xde, 0x01, 0x80, 0x20, +0x49, 0x46, 0x20, 0x41, 0x44, 0x56, 0x49, 0xc0, 0x00, 0x03, 0x30, 0x00, +0x53, 0x50, 0x4f, 0x53, 0x53, 0x49, 0x3f, 0x02, 0x01, 0x3f, 0x01, 0x23, +0x43, 0x48, 0x7e, 0x01, 0x02, 0x15, 0x03, 0x70, 0x59, 0x6f, 0x75, 0x20, +0x63, 0x61, 0x6e, 0x9b, 0x03, 0x32, 0x74, 0x61, 0x63, 0xb5, 0x04, 0xb0, +0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x20, 0x61, 0x74, 0x20, 0x3a, 0x23, +0x00, 0x11, 0x2d, 0xe8, 0x05, 0x03, 0x8c, 0x04, 0xd0, 0x72, 0x65, 0x70, +0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x3a, 0x20, 0x8a, 0x05, +0xf6, 0x0c, 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, 0x3d, 0x00, 0x60, 0x70, 0x75, 0x62, 0x6c, +0x69, 0x63, 0x40, 0x04, 0x28, 0x75, 0x6d, 0x38, 0x00, 0xc1, 0x72, 0x6f, +0x75, 0x70, 0x73, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3f, 0x00, +0x01, 0x22, 0x00, 0x32, 0x2f, 0x23, 0x21, 0x08, 0x00, 0xf0, 0x1b, 0x6c, +0x7a, 0x34, 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, 0x04, 0x00, 0xf0, 0x08, 0x29, 0x0a, 0x65, +0x78, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x22, 0x43, 0x22, 0x20, 0x7b, 0x0a, +0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0a, 0x0a, 0xab, 0x06, 0x74, 0x2a, +0x20, 0x6c, 0x7a, 0x34, 0x2e, 0x68, 0x2a, 0x04, 0x79, 0x73, 0x20, 0x62, +0x6c, 0x6f, 0x63, 0x6b, 0xb2, 0x06, 0x41, 0x66, 0x75, 0x6e, 0x63, 0x9b, +0x04, 0x11, 0x2c, 0x9c, 0x04, 0xf1, 0x02, 0x67, 0x69, 0x76, 0x65, 0x73, +0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, +0x22, 0x01, 0x60, 0x72, 0x6f, 0x6c, 0x20, 0x74, 0x6f, 0x47, 0x00, 0x42, +0x67, 0x72, 0x61, 0x6d, 0x37, 0x05, 0xb0, 0x2a, 0x20, 0x49, 0x66, 0x20, +0x79, 0x6f, 0x75, 0x20, 0x6e, 0x65, 0xfa, 0x05, 0x90, 0x6f, 0x20, 0x67, +0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x5a, 0x06, 0xc5, 0x74, 0x65, 0x72, +0x2d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x6e, 0x00, 0xf0, +0x01, 0x65, 0x64, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x28, 0x72, 0x65, +0x73, 0x70, 0x65, 0x63, 0x74, 0xfd, 0x04, 0x00, 0x25, 0x01, 0x60, 0x66, +0x72, 0x61, 0x6d, 0x65, 0x20, 0x13, 0x00, 0x05, 0x61, 0x06, 0x20, 0x29, +0x2c, 0x60, 0x00, 0x00, 0x90, 0x00, 0x00, 0xa4, 0x01, 0x22, 0x6c, 0x65, +0xa0, 0x01, 0x40, 0x6c, 0x69, 0x62, 0x72, 0x8f, 0x05, 0xf1, 0x0e, 0x68, +0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x77, +0x6e, 0x20, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x2c, 0x20, 0x70, 0x6c, +0x65, 0x61, 0x73, 0x65, 0xdc, 0x06, 0x31, 0x6c, 0x7a, 0x34, 0x56, 0x00, +0xb0, 0x2e, 0x68, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, 0x2e, +0x50, 0x01, 0x3f, 0x0a, 0x2f, 0x2a, 0x01, 0x00, 0x12, 0x70, 0x0a, 0x2a, +0x20, 0x20, 0x56, 0x65, 0x72, 0x20, 0x01, 0x1f, 0x0a, 0x32, 0x00, 0x13, +0x32, 0x2f, 0x0a, 0x23, 0x9b, 0x01, 0x00, 0xd2, 0x00, 0xe0, 0x5f, 0x56, +0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x41, 0x4a, 0x4f, 0x52, +0x5d, 0x06, 0x10, 0x31, 0x05, 0x00, 0x20, 0x2f, 0x2a, 0x09, 0x02, 0x60, +0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0xfc, 0x00, 0x01, 0x27, 0x01, 0x20, +0x66, 0x61, 0xe9, 0x06, 0x8f, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x20, +0x20, 0x48, 0x00, 0x05, 0x22, 0x49, 0x4e, 0x48, 0x00, 0x17, 0x37, 0x48, +0x00, 0x94, 0x6e, 0x65, 0x77, 0x20, 0x28, 0x6e, 0x6f, 0x6e, 0x2d, 0x51, +0x00, 0x18, 0x29, 0x52, 0x00, 0xbf, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, +0x69, 0x74, 0x69, 0x65, 0x73, 0x56, 0x00, 0x05, 0x7a, 0x52, 0x45, 0x4c, +0x45, 0x41, 0x53, 0x45, 0x9e, 0x00, 0xf0, 0x03, 0x74, 0x77, 0x65, 0x61, +0x6b, 0x73, 0x2c, 0x20, 0x62, 0x75, 0x67, 0x2d, 0x66, 0x69, 0x78, 0x65, +0x73, 0x2c, 0x08, 0x08, 0x70, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, +0x92, 0x06, 0x0f, 0x4e, 0x00, 0x05, 0x8e, 0x4e, 0x55, 0x4d, 0x42, 0x45, +0x52, 0x20, 0x28, 0x00, 0x01, 0x40, 0x2a, 0x31, 0x30, 0x30, 0x04, 0x00, +0x2f, 0x20, 0x2b, 0xd5, 0x00, 0x00, 0x0e, 0x19, 0x00, 0x04, 0x98, 0x00, +0x51, 0x29, 0x0a, 0x69, 0x6e, 0x74, 0x19, 0x00, 0x12, 0x76, 0x8b, 0x01, +0xef, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x28, 0x76, 0x6f, 0x69, +0x64, 0x29, 0x3b, 0xcd, 0x01, 0x1a, 0x30, 0x54, 0x75, 0x6e, 0x72, 0x01, +0x20, 0x70, 0x61, 0x15, 0x02, 0x3f, 0x74, 0x65, 0x72, 0xd6, 0x01, 0x16, +0x02, 0x45, 0x03, 0x00, 0x85, 0x00, 0xc0, 0x4d, 0x45, 0x4d, 0x4f, 0x52, +0x59, 0x5f, 0x55, 0x53, 0x41, 0x47, 0x45, 0x20, 0x04, 0x31, 0x2a, 0x20, +0x4d, 0x78, 0x02, 0x61, 0x20, 0x75, 0x73, 0x61, 0x67, 0x65, 0x23, 0x08, +0xf0, 0x1d, 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, 0x0b, 0x00, +0x80, 0x34, 0x4b, 0x42, 0x20, 0x3b, 0x20, 0x31, 0x36, 0x0c, 0x00, 0x20, +0x36, 0x34, 0x18, 0x00, 0x12, 0x32, 0x23, 0x00, 0x91, 0x4d, 0x42, 0x3b, +0x20, 0x65, 0x74, 0x63, 0x2e, 0x29, 0x66, 0x03, 0x60, 0x6e, 0x63, 0x72, +0x65, 0x61, 0x73, 0xc0, 0x00, 0x18, 0x6d, 0x72, 0x00, 0x20, 0x69, 0x6d, +0xd6, 0x03, 0x29, 0x65, 0x73, 0xce, 0x03, 0x10, 0x72, 0x3f, 0x03, 0x12, +0x0a, 0xcd, 0x08, 0x4a, 0x75, 0x63, 0x65, 0x64, 0x33, 0x00, 0x00, 0x4d, +0x03, 0x03, 0x37, 0x00, 0x00, 0x70, 0x03, 0x70, 0x65, 0x64, 0x2c, 0x20, +0x64, 0x75, 0x65, 0xbc, 0x03, 0xc0, 0x63, 0x61, 0x63, 0x68, 0x65, 0x20, +0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x3f, 0x00, 0xf1, 0x05, 0x44, 0x65, +0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, +0x69, 0x73, 0x20, 0x31, 0x34, 0x2c, 0x20, 0x02, 0xf0, 0x05, 0x31, 0x36, +0x4b, 0x42, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6e, 0x69, +0x63, 0x65, 0x6c, 0x79, 0x20, 0x66, 0x89, 0x03, 0xf2, 0x02, 0x69, 0x6e, +0x74, 0x6f, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x6c, 0x20, 0x78, 0x38, 0x36, +0x20, 0x4c, 0x31, 0x53, 0x00, 0x1c, 0x0a, 0x2f, 0x02, 0x09, 0x47, 0x01, +0x3f, 0x31, 0x34, 0x0a, 0xc7, 0x01, 0x1a, 0x20, 0x53, 0x69, 0x4c, 0x01, +0x24, 0x20, 0x46, 0xb3, 0x04, 0x0f, 0xc7, 0x01, 0x16, 0x05, 0x4b, 0x02, +0x04, 0x2c, 0x01, 0x22, 0x5f, 0x64, 0xe1, 0x00, 0x60, 0x28, 0x63, 0x6f, +0x6e, 0x73, 0x74, 0x81, 0x03, 0x23, 0x72, 0x2a, 0xeb, 0x05, 0x13, 0x2c, +0x0e, 0x00, 0x50, 0x64, 0x65, 0x73, 0x74, 0x2c, 0xd8, 0x00, 0x03, 0x18, +0x00, 0x42, 0x53, 0x69, 0x7a, 0x65, 0x10, 0x00, 0x70, 0x6d, 0x61, 0x78, +0x44, 0x65, 0x73, 0x74, 0x11, 0x00, 0x25, 0x29, 0x3b, 0x5b, 0x00, 0x25, +0x64, 0x65, 0x5d, 0x00, 0x5f, 0x73, 0x61, 0x66, 0x65, 0x20, 0x5b, 0x00, +0x12, 0x06, 0x1c, 0x05, 0x0b, 0x5f, 0x00, 0x0a, 0x19, 0x00, 0x02, 0xef, +0x02, 0x1f, 0x0a, 0xc2, 0x00, 0x02, 0x12, 0x29, 0xae, 0x06, 0x24, 0x20, +0x43, 0x32, 0x00, 0x36, 0x73, 0x20, 0x27, 0xb2, 0x00, 0x31, 0x27, 0x20, +0x62, 0x89, 0x02, 0x44, 0x66, 0x72, 0x6f, 0x6d, 0xd2, 0x05, 0x03, 0x1f, +0x00, 0x11, 0x27, 0x37, 0x00, 0x01, 0xb9, 0x01, 0xe0, 0x61, 0x6c, 0x72, +0x65, 0x61, 0x64, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0xd3, +0x0b, 0x10, 0x27, 0xa4, 0x00, 0x14, 0x27, 0x32, 0x00, 0x00, 0x94, 0x0b, +0x57, 0x69, 0x7a, 0x65, 0x20, 0x27, 0xfb, 0x00, 0x29, 0x27, 0x2e, 0x77, +0x00, 0x00, 0x7e, 0x02, 0xa3, 0x69, 0x73, 0x20, 0x67, 0x75, 0x61, 0x72, +0x61, 0x6e, 0x74, 0x13, 0x06, 0x40, 0x73, 0x75, 0x63, 0x63, 0x0b, 0x00, +0x2a, 0x69, 0x66, 0x3b, 0x00, 0x39, 0x20, 0x3e, 0x3d, 0x8f, 0x01, 0x66, +0x42, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0xb6, 0x00, 0x12, 0x29, 0x5c, 0x00, +0xf0, 0x11, 0x49, 0x74, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x72, 0x75, +0x6e, 0x73, 0x20, 0x66, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2c, 0x20, 0x73, +0x6f, 0x20, 0x69, 0x74, 0x27, 0x73, 0x20, 0x61, 0x20, 0x72, 0x26, 0x01, +0x30, 0x6d, 0x65, 0x6e, 0x03, 0x0b, 0x30, 0x73, 0x65, 0x74, 0x51, 0x06, +0x03, 0x38, 0x00, 0x12, 0x66, 0x64, 0x0b, 0x03, 0xdb, 0x06, 0x00, 0xf8, +0x02, 0x26, 0x6e, 0x6f, 0x6d, 0x01, 0x05, 0x01, 0x01, 0x03, 0xfd, 0x00, +0x40, 0x20, 0x6d, 0x6f, 0x72, 0x5e, 0x06, 0x29, 0x6d, 0x69, 0xfa, 0x00, +0x41, 0x64, 0x67, 0x65, 0x74, 0x4e, 0x09, 0x09, 0x62, 0x03, 0xf2, 0x04, +0x73, 0x74, 0x6f, 0x70, 0x73, 0x20, 0x2a, 0x69, 0x6d, 0x6d, 0x65, 0x64, +0x69, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x2a, 0x3a, 0x07, 0x09, 0x72, 0x00, +0x30, 0x72, 0x65, 0x73, 0x3f, 0x03, 0x72, 0x69, 0x73, 0x20, 0x7a, 0x65, +0x72, 0x6f, 0x96, 0x00, 0x10, 0x41, 0xb4, 0x00, 0x00, 0x15, 0x02, 0x50, +0x65, 0x71, 0x75, 0x65, 0x6e, 0x0e, 0x02, 0x03, 0x6b, 0x00, 0x00, 0x62, +0x07, 0x21, 0x65, 0x6e, 0x2e, 0x00, 0x21, 0x6e, 0x6f, 0x74, 0x03, 0x22, +0x69, 0x64, 0x33, 0x00, 0x10, 0x54, 0x46, 0x0c, 0x05, 0x55, 0x00, 0x90, +0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x77, 0x72, 0x69, 0xd1, 0x01, 0x7a, +0x6f, 0x75, 0x74, 0x73, 0x69, 0x64, 0x65, 0xa9, 0x01, 0x60, 0x2c, 0x20, +0x6e, 0x6f, 0x72, 0x20, 0xcc, 0x01, 0x06, 0x20, 0x00, 0x04, 0xec, 0x00, +0x02, 0x22, 0x00, 0x05, 0xf0, 0x0c, 0x07, 0xd6, 0x02, 0xe0, 0x20, 0x20, +0x3a, 0x20, 0x4d, 0x61, 0x78, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, +0x04, 0x01, 0x05, 0xf7, 0x03, 0x01, 0xb3, 0x03, 0xe5, 0x41, 0x58, 0x5f, +0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x41, +0x00, 0x07, 0xd1, 0x01, 0x22, 0x20, 0x3a, 0x33, 0x08, 0x20, 0x6f, 0x72, +0x64, 0x05, 0x42, 0x74, 0x69, 0x61, 0x6c, 0x30, 0x02, 0x25, 0x6f, 0x66, +0x74, 0x02, 0x02, 0xa7, 0x00, 0x12, 0x28, 0x3a, 0x04, 0x01, 0x4c, 0x0d, +0x2e, 0x62, 0x65, 0x78, 0x02, 0x15, 0x29, 0x5e, 0x00, 0x81, 0x72, 0x65, +0x74, 0x75, 0x72, 0x6e, 0x20, 0x3a, 0x58, 0x01, 0x12, 0x6e, 0xfb, 0x05, +0x23, 0x6f, 0x66, 0xce, 0x02, 0x00, 0x04, 0x01, 0x32, 0x74, 0x65, 0x6e, +0xc0, 0x01, 0x0b, 0x62, 0x00, 0xe0, 0x6e, 0x65, 0x63, 0x65, 0x73, 0x73, +0x61, 0x72, 0x69, 0x6c, 0x79, 0x20, 0x3c, 0x3d, 0xa6, 0x00, 0x52, 0x4f, +0x75, 0x74, 0x70, 0x75, 0xaf, 0x03, 0x29, 0x0a, 0x20, 0x01, 0x00, 0x40, +0x6f, 0x72, 0x20, 0x30, 0x9d, 0x02, 0x09, 0x11, 0x09, 0x6f, 0x61, 0x69, +0x6c, 0x73, 0x0a, 0x0a, 0xd3, 0x03, 0x00, 0x05, 0x6b, 0x03, 0x0a, 0x9d, +0x03, 0x20, 0x20, 0x3a, 0x2a, 0x01, 0x00, 0xa7, 0x00, 0x72, 0x70, 0x72, +0x65, 0x63, 0x69, 0x73, 0x65, 0x0c, 0x01, 0x04, 0x01, 0x01, 0x29, 0x74, +0x68, 0x03, 0x09, 0x01, 0x82, 0x09, 0x02, 0x86, 0x01, 0x0e, 0xe9, 0x03, +0x07, 0x4c, 0x00, 0x04, 0x3f, 0x00, 0x00, 0xd6, 0x00, 0x22, 0x69, 0x6e, +0x08, 0x0e, 0x04, 0xe5, 0x01, 0x0f, 0x45, 0x01, 0x0c, 0x2f, 0x2e, 0x0a, +0x41, 0x01, 0x0e, 0x17, 0x64, 0x78, 0x00, 0x02, 0x46, 0x01, 0x0e, 0x68, +0x00, 0x0e, 0x4b, 0x01, 0x0f, 0x99, 0x04, 0x00, 0x0a, 0x51, 0x01, 0x1f, +0x49, 0xb0, 0x00, 0x01, 0x04, 0xd8, 0x02, 0xd1, 0x6c, 0x61, 0x72, 0x67, +0x65, 0x20, 0x65, 0x6e, 0x6f, 0x75, 0x67, 0x68, 0x2c, 0x82, 0x00, 0x10, +0x64, 0xd5, 0x06, 0x41, 0x77, 0x69, 0x6c, 0x6c, 0x56, 0x03, 0x01, 0x46, +0x03, 0x11, 0x6f, 0xac, 0x01, 0x92, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x72, +0x72, 0x6f, 0x72, 0x04, 0x10, 0x5d, 0x28, 0x3c, 0x30, 0x29, 0x2e, 0x6a, +0x00, 0x01, 0x26, 0x01, 0x02, 0x9e, 0x0b, 0x60, 0x73, 0x74, 0x72, 0x65, +0x61, 0x6d, 0x69, 0x00, 0x50, 0x64, 0x65, 0x74, 0x65, 0x63, 0xc3, 0x02, +0x30, 0x6d, 0x61, 0x6c, 0x94, 0x07, 0x00, 0xe4, 0x06, 0x09, 0x9a, 0x03, +0x06, 0x6f, 0x00, 0x05, 0x82, 0x00, 0x00, 0x78, 0x00, 0x03, 0x2e, 0x01, +0xa3, 0x61, 0x20, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0xc3, +0x03, 0x0b, 0x77, 0x00, 0x0a, 0x91, 0x03, 0x11, 0x69, 0x84, 0x0f, 0x03, +0x71, 0x00, 0x30, 0x61, 0x67, 0x61, 0x6c, 0x0a, 0x05, 0x33, 0x05, 0xf0, +0x01, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x20, 0x65, 0x78, 0x70, +0x6c, 0x6f, 0x69, 0x74, 0x73, 0xdd, 0x05, 0x31, 0x63, 0x6c, 0x75, 0x72, +0x00, 0x92, 0x6d, 0x61, 0x6c, 0x69, 0x63, 0x69, 0x6f, 0x75, 0x73, 0x12, +0x0b, 0x7c, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0xe3, 0x00, 0x1f, +0x74, 0xf2, 0x03, 0x03, 0x03, 0x23, 0x01, 0x0c, 0xf2, 0x03, 0x06, 0x21, +0x00, 0x26, 0x69, 0x6e, 0x20, 0x00, 0x02, 0xf8, 0x0a, 0x0f, 0x65, 0x07, +0x19, 0x50, 0x41, 0x64, 0x76, 0x61, 0x6e, 0x3b, 0x08, 0x0e, 0x67, 0x07, +0x0f, 0x04, 0x0b, 0x19, 0x06, 0x36, 0x04, 0x44, 0x53, 0x49, 0x5a, 0x45, +0xd4, 0x00, 0x51, 0x30, 0x78, 0x37, 0x45, 0x30, 0x01, 0x00, 0x02, 0x73, +0x0a, 0xd3, 0x32, 0x20, 0x31, 0x31, 0x33, 0x20, 0x39, 0x32, 0x39, 0x20, +0x32, 0x31, 0x36, 0x9c, 0x02, 0x0b, 0xaf, 0x0a, 0x31, 0x43, 0x4f, 0x4d, +0x69, 0x10, 0x70, 0x42, 0x4f, 0x55, 0x4e, 0x44, 0x28, 0x69, 0x18, 0x03, +0xe4, 0x29, 0x20, 0x20, 0x28, 0x28, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, +0x65, 0x64, 0x29, 0x14, 0x00, 0x26, 0x3e, 0x20, 0x14, 0x00, 0x0f, 0x82, +0x00, 0x00, 0x64, 0x3f, 0x20, 0x30, 0x20, 0x3a, 0x20, 0x2d, 0x00, 0x33, +0x2b, 0x20, 0x28, 0x0b, 0x00, 0x40, 0x2f, 0x32, 0x35, 0x35, 0x10, 0x00, +0x3d, 0x31, 0x36, 0x29, 0x65, 0x07, 0x02, 0x98, 0x06, 0x04, 0xf7, 0x03, +0x14, 0x50, 0x46, 0x0d, 0x00, 0x51, 0x02, 0x72, 0x6d, 0x61, 0x78, 0x69, +0x6d, 0x75, 0x6d, 0xa8, 0x03, 0x01, 0xf8, 0x12, 0x00, 0xcc, 0x0c, 0x08, +0x49, 0x04, 0x34, 0x6d, 0x61, 0x79, 0xac, 0x01, 0x10, 0x69, 0x5a, 0x02, +0x40, 0x22, 0x77, 0x6f, 0x72, 0x11, 0x08, 0xf2, 0x00, 0x61, 0x73, 0x65, +0x22, 0x20, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x20, 0x28, +0xae, 0x01, 0x01, 0x08, 0x02, 0x08, 0xa5, 0x06, 0x33, 0x69, 0x62, 0x6c, +0x5e, 0x03, 0x0f, 0x74, 0x02, 0x00, 0x22, 0x69, 0x6d, 0x95, 0x03, 0x61, +0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x99, 0x09, 0x03, 0xe9, 0x09, 0x03, +0x05, 0x04, 0x00, 0x2a, 0x00, 0x50, 0x70, 0x75, 0x72, 0x70, 0x6f, 0x0f, +0x08, 0x1f, 0x28, 0x94, 0x03, 0x00, 0x16, 0x73, 0x66, 0x07, 0x5f, 0x4d, +0x61, 0x63, 0x72, 0x6f, 0x6b, 0x01, 0x00, 0x10, 0x29, 0x6c, 0x00, 0x01, +0x80, 0x07, 0x05, 0x69, 0x12, 0x11, 0x66, 0x92, 0x03, 0x41, 0x6d, 0x70, +0x69, 0x6c, 0x4d, 0x00, 0x70, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x65, +0x2e, 0x06, 0x02, 0x5d, 0x00, 0x6f, 0x28, 0x73, 0x74, 0x61, 0x63, 0x6b, +0x8c, 0x00, 0x00, 0x00, 0x39, 0x00, 0x03, 0x0b, 0x0b, 0x03, 0x76, 0x00, +0x36, 0x4e, 0x6f, 0x74, 0x38, 0x01, 0x0f, 0xd6, 0x08, 0x01, 0x05, 0xae, +0x07, 0x02, 0xf9, 0x07, 0x51, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x5e, 0x04, +0x08, 0xc3, 0x00, 0x00, 0xa3, 0x00, 0x0f, 0x4c, 0x08, 0x03, 0x2a, 0x72, +0x63, 0xa0, 0x04, 0x01, 0x67, 0x01, 0x04, 0xee, 0x06, 0x1f, 0x6d, 0xee, +0x06, 0x11, 0x00, 0x36, 0x02, 0x0e, 0x8f, 0x06, 0x04, 0xf8, 0x01, 0x03, +0xda, 0x01, 0x02, 0x85, 0x00, 0x0f, 0xdf, 0x01, 0x06, 0x0f, 0x70, 0x06, +0x00, 0x10, 0x2c, 0x71, 0x06, 0x26, 0x69, 0x6e, 0x3d, 0x00, 0x53, 0x73, +0x20, 0x74, 0x6f, 0x6f, 0x1e, 0x05, 0x3f, 0x28, 0x20, 0x3e, 0x86, 0x00, +0x00, 0x10, 0x29, 0xc5, 0x03, 0x0c, 0xc3, 0x0a, 0x02, 0xe8, 0x00, 0x00, +0x16, 0x00, 0x05, 0xdb, 0x00, 0x0f, 0x27, 0x0a, 0x01, 0x00, 0x3e, 0x01, +0x05, 0xc2, 0x02, 0x10, 0x53, 0x6a, 0x0f, 0x2f, 0x61, 0x73, 0x73, 0x01, +0x04, 0x00, 0xf6, 0x0d, 0x11, 0x74, 0xb6, 0x01, 0x21, 0x77, 0x73, 0xbe, +0x09, 0x41, 0x65, 0x6c, 0x65, 0x63, 0x8c, 0x05, 0x81, 0x22, 0x61, 0x63, +0x63, 0x65, 0x6c, 0x65, 0x72, 0xcd, 0x01, 0x84, 0x22, 0x20, 0x66, 0x61, +0x63, 0x74, 0x6f, 0x72, 0xa3, 0x08, 0x12, 0x65, 0xbc, 0x00, 0x12, 0x72, +0x44, 0x11, 0x07, 0x29, 0x00, 0x02, 0x59, 0x01, 0x03, 0x80, 0x05, 0x02, +0xc5, 0x01, 0x01, 0x23, 0x00, 0x04, 0x24, 0x17, 0x04, 0x70, 0x00, 0x22, +0x73, 0x6f, 0xdf, 0x0f, 0x00, 0x56, 0x06, 0x19, 0x72, 0x30, 0x07, 0x01, +0xc4, 0x14, 0x02, 0x0a, 0x0a, 0x01, 0xf2, 0x09, 0xa0, 0x74, 0x72, 0x61, +0x64, 0x65, 0x2d, 0x6f, 0x66, 0x66, 0x2e, 0x1e, 0x05, 0x00, 0xcf, 0x0c, +0x31, 0x62, 0x65, 0x20, 0x2a, 0x04, 0x53, 0x74, 0x75, 0x6e, 0x65, 0x64, +0xb9, 0x16, 0x42, 0x65, 0x61, 0x63, 0x68, 0x7b, 0x0a, 0x20, 0x73, 0x73, +0xca, 0x05, 0x02, 0xe0, 0x01, 0x02, 0xc5, 0x02, 0x00, 0x7e, 0x05, 0x10, +0x72, 0x82, 0x06, 0x71, 0x6c, 0x79, 0x20, 0x2b, 0x7e, 0x33, 0x25, 0xe8, +0x00, 0x00, 0x0b, 0x0d, 0x03, 0xa4, 0x09, 0x1f, 0x6e, 0xc2, 0x00, 0x00, +0x00, 0x37, 0x07, 0x35, 0x22, 0x31, 0x22, 0x9a, 0x07, 0x03, 0x45, 0x01, +0x7f, 0x72, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x4d, 0x01, 0x04, 0x01, +0x4f, 0x00, 0x10, 0x56, 0x3f, 0x00, 0x10, 0x73, 0x3c, 0x07, 0x12, 0x30, +0x79, 0x06, 0x11, 0x62, 0x4a, 0x12, 0x20, 0x6c, 0x61, 0x60, 0x05, 0xb0, +0x62, 0x79, 0x20, 0x41, 0x43, 0x43, 0x45, 0x4c, 0x45, 0x52, 0x41, 0x8a, +0x13, 0xc1, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x28, +0x73, 0x65, 0xc2, 0x10, 0x34, 0x2e, 0x63, 0x29, 0xeb, 0x07, 0x00, 0x81, +0x0d, 0x1f, 0x2e, 0x05, 0x02, 0x01, 0x01, 0xdf, 0x01, 0x1f, 0x20, 0xc6, +0x0c, 0x2d, 0x02, 0x11, 0x00, 0x08, 0xf9, 0x00, 0x00, 0x4a, 0x02, 0x0f, +0x4b, 0x02, 0x02, 0x9a, 0x5f, 0x65, 0x78, 0x74, 0x53, 0x74, 0x61, 0x74, +0x65, 0x54, 0x02, 0x0f, 0x52, 0x12, 0x01, 0x30, 0x2c, 0x20, 0x6a, 0xa2, +0x08, 0x22, 0x75, 0x73, 0x64, 0x07, 0x12, 0x20, 0xa6, 0x12, 0x38, 0x61, +0x6c, 0x6c, 0x68, 0x0c, 0x03, 0x2b, 0x04, 0x41, 0x73, 0x70, 0x61, 0x63, +0x89, 0x0e, 0x20, 0x73, 0x74, 0x8c, 0x0b, 0x0a, 0x71, 0x0b, 0x32, 0x61, +0x74, 0x65, 0x9e, 0x01, 0x22, 0x55, 0x73, 0x13, 0x06, 0x00, 0x38, 0x03, +0x24, 0x6f, 0x66, 0x87, 0x00, 0xf4, 0x01, 0x74, 0x6f, 0x20, 0x6b, 0x6e, +0x6f, 0x77, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x6d, 0x75, 0x63, 0x68, 0x54, +0x00, 0x06, 0x20, 0x09, 0x03, 0x6d, 0x00, 0x02, 0xcd, 0x0b, 0x00, 0xee, +0x07, 0x04, 0x13, 0x00, 0x92, 0x20, 0x69, 0x74, 0x20, 0x6f, 0x6e, 0x20, +0x38, 0x2d, 0x7a, 0x06, 0x10, 0x62, 0x53, 0x03, 0x20, 0x61, 0x72, 0x34, +0x11, 0x33, 0x28, 0x75, 0x73, 0xa9, 0x07, 0x30, 0x6c, 0x6f, 0x63, 0x65, +0x00, 0x40, 0x79, 0x70, 0x69, 0x63, 0xbc, 0x00, 0x15, 0x29, 0xf7, 0x02, +0x24, 0x6e, 0x2c, 0x19, 0x05, 0x00, 0x47, 0x00, 0x40, 0x61, 0x73, 0x20, +0x27, 0x9a, 0x10, 0x12, 0x2a, 0xb1, 0x00, 0x11, 0x27, 0x56, 0x0f, 0x0f, +0x16, 0x01, 0x00, 0x09, 0xc7, 0x01, 0x08, 0xc9, 0x00, 0x03, 0xd7, 0x10, +0x04, 0x4f, 0x0e, 0x0f, 0x76, 0x01, 0x03, 0x27, 0x20, 0x28, 0x64, 0x00, +0x2f, 0x2c, 0x20, 0xf8, 0x01, 0x11, 0x05, 0x1e, 0x04, 0x0f, 0xf7, 0x01, +0x25, 0x13, 0x64, 0x2f, 0x00, 0x05, 0xf2, 0x01, 0x10, 0x52, 0x96, 0x08, +0x12, 0x73, 0x03, 0x19, 0x60, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x2c, 0xcc, +0x02, 0x05, 0xed, 0x00, 0x00, 0xee, 0x01, 0x12, 0x73, 0x8a, 0x01, 0x01, +0xd6, 0x06, 0x52, 0x61, 0x73, 0x20, 0x70, 0x6f, 0xd1, 0x06, 0x02, 0x87, +0x0e, 0x0b, 0x93, 0x0c, 0x0f, 0x87, 0x0e, 0x09, 0x0a, 0xdc, 0x0b, 0x05, +0x87, 0x0e, 0x10, 0x74, 0x71, 0x04, 0x1b, 0x74, 0x8a, 0x0e, 0x0a, 0x2d, +0x0d, 0x21, 0x65, 0x69, 0x2e, 0x19, 0x16, 0x63, 0x16, 0x0f, 0x00, 0xaf, +0x00, 0x57, 0x65, 0x6e, 0x74, 0x69, 0x72, 0x15, 0x0d, 0x05, 0x7b, 0x0d, +0x00, 0x7f, 0x00, 0x03, 0x66, 0x00, 0x22, 0x69, 0x66, 0x61, 0x0e, 0x09, +0xb0, 0x0a, 0x13, 0x0a, 0xbf, 0x05, 0x10, 0x66, 0xc6, 0x03, 0x0a, 0x1d, +0x0f, 0x00, 0x63, 0x00, 0x20, 0x6c, 0x65, 0x0a, 0x0e, 0x02, 0x7f, 0x04, +0x0f, 0xfd, 0x00, 0x13, 0x06, 0xed, 0x09, 0x16, 0x2a, 0x9a, 0x03, 0x55, +0x50, 0x74, 0x72, 0x20, 0x3a, 0x2a, 0x04, 0x02, 0x73, 0x1b, 0x02, 0x4a, +0x0f, 0x41, 0x69, 0x6e, 0x64, 0x69, 0xb2, 0x02, 0x01, 0xe6, 0x02, 0x34, +0x61, 0x6e, 0x79, 0x0a, 0x0d, 0x42, 0x68, 0x65, 0x72, 0x65, 0xf2, 0x0d, +0x0a, 0x5c, 0x01, 0x28, 0x74, 0x6f, 0xac, 0x00, 0x0b, 0x5b, 0x0a, 0x08, +0x01, 0x00, 0x36, 0x4e, 0x65, 0x77, 0x02, 0x07, 0x0b, 0xf2, 0x0b, 0x23, +0x6f, 0x6c, 0x1e, 0x07, 0x1e, 0x2e, 0x09, 0x07, 0x2f, 0x4e, 0x62, 0x8d, +0x0d, 0x01, 0x0f, 0x86, 0x0d, 0x04, 0x0a, 0xb1, 0x01, 0x0f, 0x87, 0x0d, +0x17, 0x0e, 0xf3, 0x04, 0x06, 0x90, 0x02, 0x0f, 0xf7, 0x04, 0x12, 0x29, +0x2a, 0x20, 0x5e, 0x01, 0x02, 0xf3, 0x02, 0x0b, 0x8e, 0x00, 0x07, 0xf5, +0x02, 0x2f, 0x64, 0x65, 0x39, 0x07, 0x03, 0x8a, 0x6f, 0x72, 0x69, 0x67, +0x69, 0x6e, 0x61, 0x6c, 0xa4, 0x0d, 0x04, 0x16, 0x00, 0x04, 0x00, 0x10, +0x30, 0x72, 0x65, 0x66, 0xbe, 0x04, 0x27, 0x75, 0x6e, 0x5d, 0x0d, 0x00, +0xb1, 0x02, 0x0f, 0x90, 0x0d, 0x0f, 0x06, 0xc1, 0x01, 0x07, 0xd6, 0x0c, +0x04, 0x87, 0x0d, 0x23, 0x69, 0x6e, 0xfb, 0x1b, 0x6c, 0x77, 0x6f, 0x72, +0x64, 0x73, 0x2c, 0x52, 0x0e, 0x01, 0xcb, 0x09, 0x0f, 0x1e, 0x0d, 0x72, +0x1e, 0x44, 0x68, 0x0a, 0x0f, 0xa5, 0x0e, 0x07, 0x42, 0x20, 0x49, 0x74, +0x73, 0xcf, 0x03, 0x05, 0x24, 0x00, 0x42, 0x20, 0x6d, 0x69, 0x6e, 0x5d, +0x09, 0x38, 0x66, 0x20, 0x27, 0x73, 0x01, 0x03, 0xc6, 0x12, 0x02, 0x6f, +0x00, 0x10, 0x6e, 0x3a, 0x0a, 0x1b, 0x3a, 0xef, 0x03, 0x00, 0x73, 0x0f, +0x23, 0x79, 0x20, 0x5a, 0x18, 0x04, 0x02, 0x06, 0x07, 0xd0, 0x05, 0x00, +0x81, 0x0a, 0x20, 0x70, 0x72, 0x94, 0x18, 0x12, 0x6c, 0xd0, 0x1d, 0x2c, +0x65, 0x64, 0x99, 0x18, 0x2a, 0x2e, 0x0a, 0x7d, 0x0d, 0x00, 0xfe, 0x0a, +0x46, 0x20, 0x62, 0x69, 0x74, 0xbc, 0x08, 0x3f, 0x61, 0x6e, 0x20, 0x17, +0x10, 0x02, 0x09, 0x3a, 0x00, 0x30, 0x48, 0x6f, 0x77, 0x20, 0x05, 0x10, +0x2c, 0x15, 0x06, 0x32, 0x64, 0x6f, 0x65, 0xfc, 0x0e, 0x04, 0x29, 0x06, +0x00, 0xb9, 0x03, 0x03, 0x33, 0x0e, 0x01, 0xd9, 0x1d, 0x03, 0x34, 0x0e, +0x11, 0x69, 0x86, 0x04, 0x22, 0x69, 0x6f, 0x1e, 0x07, 0x05, 0xf8, 0x03, +0x01, 0x42, 0x04, 0x03, 0xbe, 0x01, 0x16, 0x28, 0x34, 0x0e, 0x01, 0xd2, +0x05, 0x0a, 0x75, 0x00, 0x00, 0x1a, 0x07, 0x1a, 0x74, 0x28, 0x0c, 0x60, +0x6e, 0x20, 0x74, 0x72, 0x75, 0x73, 0xed, 0x01, 0x71, 0x65, 0x6e, 0x76, +0x69, 0x72, 0x6f, 0x6e, 0xbe, 0x17, 0x61, 0x6f, 0x6e, 0x6c, 0x79, 0x20, +0x28, 0x59, 0x00, 0x22, 0x74, 0x6f, 0xe5, 0x01, 0x01, 0x4d, 0x02, 0x04, +0x23, 0x14, 0x15, 0x61, 0x36, 0x00, 0x02, 0x3d, 0x02, 0x19, 0x29, 0xb0, +0x06, 0x2f, 0x64, 0x65, 0x79, 0x08, 0x20, 0x08, 0xc9, 0x01, 0x2f, 0x29, +0x3b, 0x6b, 0x03, 0x01, 0x00, 0x46, 0x01, 0x13, 0x5f, 0x39, 0x12, 0x05, +0x73, 0x03, 0x0a, 0xcf, 0x05, 0x06, 0x2e, 0x00, 0x2d, 0x20, 0x61, 0x4f, +0x11, 0x06, 0x19, 0x06, 0x0a, 0x9e, 0x10, 0x10, 0x27, 0xcc, 0x1b, 0x01, +0xb8, 0x1b, 0x00, 0x43, 0x00, 0x0e, 0xf7, 0x14, 0x0e, 0xf4, 0x10, 0x0d, +0x6a, 0x06, 0x0f, 0xf4, 0x10, 0x00, 0x05, 0x6f, 0x06, 0x07, 0x38, 0x03, +0x11, 0x74, 0x65, 0x02, 0x26, 0x74, 0x6f, 0x3c, 0x03, 0x06, 0x0d, 0x07, +0x24, 0x6f, 0x70, 0x4e, 0x0a, 0x52, 0x61, 0x73, 0x20, 0x73, 0x6f, 0x08, +0x00, 0x03, 0xc3, 0x06, 0x06, 0x9b, 0x12, 0x90, 0x27, 0x20, 0x68, 0x61, +0x73, 0x20, 0x62, 0x65, 0x65, 0x3d, 0x14, 0x00, 0x3b, 0x17, 0x03, 0xaf, +0x08, 0x10, 0x72, 0xc9, 0x17, 0x01, 0x28, 0x20, 0x18, 0x65, 0x1f, 0x05, +0x00, 0x7a, 0x0d, 0x0f, 0xe8, 0x11, 0x14, 0x00, 0xb9, 0x0d, 0x04, 0x57, +0x20, 0x0f, 0xe5, 0x11, 0x2b, 0x12, 0x4e, 0x7a, 0x03, 0x01, 0x69, 0x02, +0x03, 0x6a, 0x00, 0x03, 0x84, 0x0b, 0x1f, 0x3c, 0xd1, 0x00, 0x01, 0x6f, +0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x01, 0x13, 0x02, 0x07, 0x7d, 0x02, +0x40, 0x62, 0x65, 0x20, 0x73, 0x67, 0x09, 0x2b, 0x65, 0x72, 0x4e, 0x04, +0x65, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x80, 0x1c, 0x0c, 0xf9, 0x06, +0x00, 0xf8, 0x06, 0x03, 0xdf, 0x00, 0x0f, 0x1c, 0x12, 0x81, 0x0f, 0xbb, +0x11, 0x03, 0x1c, 0x66, 0xbe, 0x11, 0x00, 0x60, 0x00, 0x02, 0x2b, 0x00, +0x0a, 0xc4, 0x11, 0x2a, 0x6f, 0x66, 0xc7, 0x11, 0x03, 0x91, 0x04, 0x06, +0x65, 0x06, 0x0e, 0x79, 0x12, 0x0f, 0x55, 0x12, 0x03, 0x0e, 0xbf, 0x03, +0x0d, 0x73, 0x03, 0x0f, 0xab, 0x18, 0x27, 0x0c, 0xf4, 0x01, 0x0f, 0xc1, +0x18, 0x0a, 0x0e, 0x85, 0x12, 0x0f, 0xf3, 0x19, 0x11, 0x01, 0xbe, 0x01, +0x00, 0x8a, 0x01, 0x08, 0x69, 0x18, 0x0f, 0x9b, 0x12, 0x00, 0x0f, 0xa4, +0x12, 0x21, 0x60, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x62, 0x0f, 0xdc, +0x5f, 0x55, 0x36, 0x34, 0x20, 0x28, 0x28, 0x31, 0x20, 0x3c, 0x3c, 0x20, +0x28, 0xa8, 0x1a, 0x30, 0x2d, 0x33, 0x29, 0x21, 0x12, 0x2f, 0x34, 0x29, +0x3d, 0x00, 0x04, 0x01, 0xfe, 0x01, 0x1f, 0x28, 0x51, 0x00, 0x00, 0x22, +0x2a, 0x20, 0xe1, 0x0b, 0x60, 0x28, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x05, +0x00, 0x27, 0x29, 0x29, 0x53, 0x1c, 0x02, 0x9a, 0x02, 0x11, 0x5f, 0x71, +0x1b, 0x20, 0x69, 0x6e, 0x92, 0x02, 0x02, 0x9a, 0x03, 0x81, 0x73, 0x74, +0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x11, 0x0d, 0x20, 0x74, 0x72, 0x52, +0x11, 0x02, 0x7a, 0x06, 0x03, 0xcc, 0x02, 0x01, 0x7d, 0x1f, 0x20, 0x69, +0x6d, 0xbe, 0x10, 0x30, 0x61, 0x6e, 0x74, 0x8f, 0x08, 0x32, 0x6e, 0x69, +0x74, 0x96, 0x03, 0x06, 0x3b, 0x00, 0x04, 0xda, 0x0a, 0x12, 0x62, 0x2f, +0x02, 0x31, 0x66, 0x69, 0x72, 0x8c, 0x0d, 0x30, 0x65, 0x20, 0x21, 0x3e, +0x00, 0x03, 0x44, 0x07, 0x29, 0x6f, 0x6e, 0x8d, 0x0d, 0x82, 0x64, 0x69, +0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x3f, 0x03, 0x05, 0x4b, 0x00, 0x12, +0x69, 0xe8, 0x1f, 0x00, 0xf4, 0x25, 0x00, 0x78, 0x0c, 0x02, 0x08, 0x0d, +0x53, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0xc3, 0x1f, 0x00, 0x52, 0x00, 0x06, +0x7c, 0x03, 0x04, 0x2c, 0x00, 0x02, 0x42, 0x0d, 0x60, 0x6c, 0x69, 0x62, +0x6c, 0x7a, 0x34, 0xf3, 0x04, 0x59, 0x61, 0x20, 0x44, 0x4c, 0x4c, 0xa7, +0x1f, 0x20, 0x62, 0x65, 0x21, 0x15, 0x01, 0x7d, 0x02, 0x00, 0x6c, 0x00, +0x01, 0x35, 0x13, 0x66, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0xb7, 0x1f, +0x00, 0x0f, 0x14, 0x73, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x93, +0x00, 0x35, 0x20, 0x7b, 0x20, 0x50, 0x01, 0x20, 0x20, 0x74, 0x63, 0x20, +0x1e, 0x5b, 0x7c, 0x01, 0x49, 0x5d, 0x3b, 0x20, 0x7d, 0x65, 0x01, 0x27, +0x3b, 0x0a, 0x7a, 0x01, 0x52, 0x72, 0x65, 0x73, 0x65, 0x74, 0x5b, 0x02, +0x00, 0x13, 0x00, 0x0e, 0x3e, 0x07, 0x22, 0x74, 0x6f, 0x55, 0x01, 0x27, +0x61, 0x6e, 0x1f, 0x01, 0x08, 0x4f, 0x00, 0x06, 0x1f, 0x01, 0x01, 0xa2, +0x00, 0x00, 0x96, 0x0d, 0x0c, 0x5a, 0x00, 0x28, 0x20, 0x28, 0x31, 0x00, +0x13, 0x2a, 0xbd, 0x01, 0x49, 0x50, 0x74, 0x72, 0x29, 0x8c, 0x00, 0x00, +0xde, 0x1d, 0x23, 0x74, 0x65, 0x33, 0x00, 0x01, 0x82, 0x04, 0x05, 0x9e, +0x0e, 0x00, 0x1d, 0x04, 0x00, 0x87, 0x00, 0x30, 0x69, 0x61, 0x6c, 0x8d, +0x06, 0x2f, 0x61, 0x6e, 0x83, 0x00, 0x07, 0x01, 0x1a, 0x00, 0x34, 0x66, +0x72, 0x65, 0x49, 0x00, 0x21, 0x72, 0x65, 0x67, 0x01, 0x11, 0x73, 0x26, +0x21, 0x02, 0x0f, 0x09, 0x02, 0xb4, 0x21, 0x02, 0x09, 0x06, 0x01, 0x1e, +0x02, 0x11, 0x78, 0x9d, 0x26, 0x01, 0x97, 0x01, 0x22, 0x20, 0x28, 0xa8, +0x01, 0x19, 0x29, 0xa0, 0x01, 0x55, 0x74, 0x68, 0x65, 0x73, 0x65, 0x93, +0x01, 0x44, 0x72, 0x61, 0x74, 0x68, 0x07, 0x09, 0x24, 0x74, 0x68, 0x0c, +0x02, 0x03, 0x86, 0x00, 0x01, 0x5d, 0x00, 0x41, 0x54, 0x68, 0x65, 0x79, +0xfb, 0x01, 0x01, 0x51, 0x1b, 0x42, 0x66, 0x75, 0x74, 0x75, 0xa9, 0x04, +0x20, 0x6f, 0x66, 0x19, 0x04, 0x01, 0x1b, 0x13, 0x02, 0x72, 0x00, 0x02, +0xf1, 0x20, 0x00, 0x0c, 0x00, 0x0a, 0xd1, 0x00, 0x32, 0x69, 0x7a, 0x65, +0xf2, 0x01, 0x0a, 0x3a, 0x01, 0x0c, 0x27, 0x01, 0x08, 0x2c, 0x0f, 0x06, +0x01, 0x00, 0x0b, 0x02, 0x01, 0x0f, 0x7e, 0x01, 0x13, 0x8f, 0x6c, 0x6f, +0x61, 0x64, 0x44, 0x69, 0x63, 0x74, 0x07, 0x02, 0x06, 0x00, 0x21, 0x00, +0x24, 0x20, 0x61, 0xed, 0x00, 0x21, 0x64, 0x69, 0x19, 0x00, 0x00, 0x86, +0x22, 0x01, 0x42, 0x08, 0x06, 0x64, 0x00, 0x01, 0x95, 0x03, 0x11, 0x41, +0xdf, 0x09, 0x26, 0x65, 0x76, 0x86, 0x05, 0x04, 0xcc, 0x0d, 0x50, 0x66, +0x6f, 0x72, 0x67, 0x6f, 0x27, 0x0d, 0x12, 0x2c, 0x75, 0x03, 0x16, 0x27, +0x4a, 0x00, 0x12, 0x27, 0x25, 0x00, 0x30, 0x72, 0x65, 0x6d, 0xe4, 0x28, +0x28, 0x69, 0x6e, 0xaf, 0x01, 0x32, 0x4c, 0x6f, 0x61, 0x87, 0x06, 0x05, +0x10, 0x1a, 0x12, 0x30, 0x96, 0x15, 0x31, 0x6c, 0x6f, 0x77, 0xf8, 0x06, +0x00, 0xea, 0x1f, 0x03, 0x00, 0x08, 0x07, 0x9c, 0x00, 0x13, 0x73, 0x8c, +0x05, 0x03, 0x2c, 0x07, 0x0c, 0xe4, 0x07, 0x50, 0x36, 0x34, 0x20, 0x4b, +0x42, 0x5d, 0x20, 0x06, 0x1b, 0x06, 0x04, 0x08, 0x01, 0x0f, 0x37, 0x01, +0x06, 0x0a, 0x6d, 0x10, 0x06, 0x6c, 0x00, 0x02, 0xf3, 0x05, 0x00, 0x10, +0x00, 0x07, 0xe0, 0x09, 0x2f, 0x20, 0x2a, 0xc4, 0x10, 0x00, 0x00, 0x74, +0x02, 0x31, 0x69, 0x6e, 0x75, 0xae, 0x02, 0x04, 0xcd, 0x05, 0x08, 0x65, +0x24, 0x00, 0xae, 0x04, 0x63, 0x27, 0x73, 0x72, 0x63, 0x27, 0x2c, 0x3b, +0x04, 0x01, 0x41, 0x01, 0x01, 0x96, 0x0a, 0x04, 0x54, 0x01, 0x2d, 0x6c, +0x79, 0x4a, 0x08, 0x10, 0x73, 0x5b, 0x04, 0x07, 0xfb, 0x00, 0x25, 0x74, +0x6f, 0xe3, 0x20, 0x0d, 0x19, 0x21, 0x02, 0x02, 0x03, 0x07, 0x39, 0x05, +0x19, 0x50, 0xac, 0x01, 0x04, 0x50, 0x00, 0x10, 0x72, 0xdf, 0x13, 0x33, +0x73, 0x75, 0x6d, 0xc4, 0x1e, 0x13, 0x74, 0xc3, 0x01, 0x00, 0x4c, 0x00, +0x00, 0xa4, 0x00, 0x01, 0x41, 0x2b, 0x15, 0x6e, 0xa5, 0x0b, 0x01, 0x50, +0x05, 0x27, 0x27, 0x64, 0x11, 0x10, 0x0f, 0x99, 0x1b, 0x09, 0x01, 0x36, +0x25, 0x00, 0x21, 0x07, 0x03, 0xc4, 0x0e, 0x0f, 0xbd, 0x16, 0x0a, 0x00, +0x74, 0x01, 0x0f, 0x5e, 0x1f, 0x0f, 0x02, 0x45, 0x08, 0x07, 0x24, 0x1f, +0x04, 0x67, 0x00, 0x32, 0x6e, 0x6f, 0x74, 0x1c, 0x00, 0x2d, 0x69, 0x66, +0x85, 0x25, 0x03, 0x13, 0x1f, 0x25, 0x66, 0x69, 0xfc, 0x10, 0x07, 0xc1, +0x00, 0x02, 0x3f, 0x02, 0x0d, 0xf6, 0x1e, 0x02, 0x4d, 0x00, 0x07, 0xe4, +0x1e, 0x00, 0x79, 0x02, 0x00, 0xd8, 0x05, 0x03, 0xe4, 0x1e, 0x07, 0x4f, +0x02, 0x0f, 0xfa, 0x01, 0x03, 0x0f, 0x5d, 0x02, 0x14, 0x35, 0x73, 0x72, +0x63, 0x7f, 0x08, 0x05, 0xbe, 0x14, 0x2a, 0x72, 0x63, 0x61, 0x08, 0x0f, +0xc3, 0x12, 0x09, 0x07, 0x63, 0x07, 0x34, 0x61, 0x76, 0x65, 0xdf, 0x03, +0x2f, 0x49, 0x66, 0x48, 0x02, 0x04, 0x06, 0xfd, 0x01, 0x04, 0xab, 0x1c, +0x0a, 0x68, 0x01, 0x03, 0x9a, 0x03, 0x51, 0x61, 0x76, 0x61, 0x69, 0x6c, +0xd2, 0x26, 0x27, 0x61, 0x74, 0x57, 0x05, 0x14, 0x20, 0xe5, 0x18, 0x00, +0x64, 0x00, 0x00, 0x70, 0x00, 0x14, 0x20, 0x54, 0x01, 0x20, 0x61, 0x20, +0x66, 0x09, 0x21, 0x72, 0x20, 0xf0, 0x15, 0x23, 0x20, 0x28, 0xdd, 0x00, +0x41, 0x61, 0x66, 0x65, 0x42, 0x67, 0x01, 0x01, 0xde, 0x23, 0x03, 0x53, +0x0b, 0x00, 0x34, 0x07, 0x55, 0x64, 0x6f, 0x6e, 0x27, 0x74, 0x4e, 0x27, +0x00, 0x65, 0x07, 0x09, 0x9a, 0x03, 0xa0, 0x28, 0x29, 0x20, 0x61, 0x66, +0x74, 0x65, 0x72, 0x77, 0x61, 0x05, 0x10, 0x07, 0x73, 0x07, 0x08, 0x94, +0x04, 0x27, 0x73, 0x20, 0x99, 0x20, 0x00, 0xf6, 0x23, 0x63, 0x62, 0x6c, +0x65, 0x2c, 0x20, 0x79, 0xed, 0x28, 0x06, 0x3e, 0x0a, 0x05, 0x5e, 0x00, +0x0f, 0xa9, 0x01, 0x03, 0x29, 0x28, 0x29, 0x5a, 0x04, 0x00, 0xd6, 0x00, +0x1c, 0x64, 0x60, 0x04, 0x0f, 0x5f, 0x04, 0x07, 0x05, 0x0d, 0x04, 0x15, +0x2c, 0xda, 0x11, 0x01, 0xcd, 0x1d, 0x09, 0x22, 0x02, 0x04, 0x9a, 0x01, +0x0f, 0x71, 0x04, 0x09, 0x0b, 0x31, 0x01, 0x0e, 0x6b, 0x04, 0x0e, 0x53, +0x0a, 0x0f, 0x54, 0x0a, 0x1b, 0x06, 0xa7, 0x0a, 0x0f, 0x56, 0x0a, 0x2a, +0x00, 0x63, 0x1d, 0x0e, 0x1b, 0x0a, 0x65, 0x44, 0x45, 0x43, 0x4f, 0x44, +0x45, 0x0d, 0x0a, 0x2f, 0x20, 0x34, 0x24, 0x00, 0x0a, 0x0c, 0x45, 0x0a, +0x0b, 0x3e, 0x00, 0x05, 0x4b, 0x0a, 0x04, 0xe3, 0x1c, 0x18, 0x20, 0x54, +0x0a, 0x0d, 0x21, 0x09, 0x0e, 0x26, 0x00, 0x0d, 0x2a, 0x09, 0x0a, 0x61, +0x00, 0x0b, 0x30, 0x09, 0x11, 0x44, 0x59, 0x0d, 0x00, 0x36, 0x09, 0x0c, +0xaf, 0x0a, 0x04, 0x1a, 0x00, 0x0f, 0xb5, 0x0a, 0x23, 0x0f, 0xa9, 0x0a, +0x08, 0x23, 0x75, 0x73, 0x4e, 0x0a, 0x15, 0x5f, 0x42, 0x09, 0x02, 0x6c, +0x00, 0x12, 0x20, 0xde, 0x1c, 0x20, 0x73, 0x65, 0x03, 0x03, 0x0f, 0xcf, +0x0a, 0x02, 0x0f, 0xd9, 0x08, 0x11, 0x04, 0xd8, 0x08, 0x30, 0x70, 0x72, +0x65, 0x94, 0x03, 0x02, 0x11, 0x27, 0x2f, 0x6f, 0x66, 0x7e, 0x0a, 0x03, +0x01, 0x99, 0x0a, 0x0f, 0xd3, 0x08, 0x2f, 0x04, 0x2c, 0x01, 0x05, 0x30, +0x03, 0x24, 0x74, 0x68, 0x44, 0x00, 0x1f, 0x2e, 0xff, 0x09, 0x01, 0x03, +0xf0, 0x00, 0x0f, 0x05, 0x0a, 0x17, 0x06, 0x61, 0x00, 0x0f, 0x0b, 0x0a, +0x07, 0x03, 0x55, 0x00, 0x0f, 0x11, 0x0a, 0x04, 0x2e, 0x2f, 0x0a, 0x4e, +0x00, 0x0f, 0x99, 0x00, 0x05, 0x0e, 0x77, 0x09, 0x0f, 0x7d, 0x09, 0x05, +0x03, 0x74, 0x00, 0x1f, 0x28, 0x5c, 0x00, 0x05, 0x02, 0x14, 0x00, 0x0b, +0xab, 0x05, 0x0a, 0xf6, 0x01, 0x0f, 0x98, 0x0b, 0x08, 0x03, 0xe6, 0x02, +0x02, 0xfb, 0x16, 0x01, 0xe8, 0x16, 0x03, 0x7f, 0x25, 0x06, 0xa2, 0x04, +0x01, 0x5f, 0x01, 0x12, 0x53, 0x14, 0x26, 0x0f, 0x3d, 0x09, 0x04, 0x21, +0x20, 0x28, 0xc9, 0x1b, 0x02, 0xf4, 0x28, 0x02, 0xd0, 0x1b, 0x4a, 0x73, +0x65, 0x74, 0x29, 0x54, 0x09, 0x10, 0x31, 0xbd, 0x04, 0x3f, 0x4f, 0x4b, +0x2c, 0xc6, 0x04, 0x06, 0x2f, 0x65, 0x74, 0xf2, 0x00, 0x19, 0x02, 0x14, +0x00, 0x0f, 0x4b, 0x09, 0x1a, 0x17, 0x2a, 0x95, 0x05, 0x05, 0x1a, 0x13, +0x00, 0x97, 0x0b, 0x05, 0xa3, 0x10, 0x05, 0xc2, 0x2d, 0x02, 0xda, 0x00, +0x0b, 0x29, 0x12, 0x80, 0x6f, 0x66, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, +0x39, 0x29, 0x03, 0xe1, 0x08, 0x54, 0x69, 0x6e, 0x20, 0x22, 0x73, 0x04, +0x05, 0x10, 0x22, 0x6f, 0x14, 0x03, 0x4b, 0x12, 0x16, 0x50, 0x1f, 0x07, +0x04, 0x39, 0x12, 0x03, 0x64, 0x09, 0x10, 0x2a, 0xd4, 0x08, 0x1f, 0x2a, +0x0a, 0x07, 0x02, 0x01, 0x0d, 0x21, 0x02, 0x0a, 0x07, 0x05, 0x6b, 0x13, +0x03, 0x9b, 0x01, 0x00, 0x3c, 0x03, 0x08, 0xa8, 0x11, 0x40, 0x20, 0x28, +0x75, 0x70, 0xb1, 0x01, 0x04, 0x80, 0x0a, 0x25, 0x20, 0x20, 0xb7, 0x03, +0x05, 0x48, 0x03, 0x10, 0x72, 0xd3, 0x00, 0x02, 0x88, 0x08, 0x17, 0x73, +0x26, 0x24, 0x0b, 0x5b, 0x09, 0x03, 0xde, 0x19, 0x02, 0x10, 0x01, 0x51, +0x2d, 0x20, 0x45, 0x78, 0x61, 0xb8, 0x0e, 0x01, 0xd2, 0x01, 0x01, 0x3a, +0x25, 0x59, 0x61, 0x73, 0x20, 0x65, 0x6e, 0x3c, 0x00, 0x03, 0x1d, 0x1e, +0x01, 0x23, 0x00, 0x30, 0x75, 0x70, 0x64, 0x5b, 0x03, 0x62, 0x72, 0x75, +0x6c, 0x65, 0x20, 0x28, 0xfa, 0x07, 0x07, 0x2c, 0x16, 0x22, 0x61, 0x74, +0x26, 0x00, 0x04, 0xcf, 0x00, 0x14, 0x73, 0x01, 0x13, 0x23, 0x49, 0x6e, +0x90, 0x1d, 0x00, 0xaf, 0x00, 0x02, 0x3c, 0x12, 0x05, 0x86, 0x01, 0x16, +0x26, 0x70, 0x00, 0x07, 0xc3, 0x00, 0x01, 0x77, 0x07, 0x32, 0x68, 0x61, +0x76, 0xfa, 0x15, 0x04, 0x97, 0x0b, 0x04, 0x07, 0x24, 0x42, 0x76, 0x65, +0x72, 0x79, 0xfd, 0x12, 0x30, 0x20, 0x6f, 0x6e, 0x49, 0x07, 0x23, 0x20, +0x3c, 0x1c, 0x01, 0x13, 0x2e, 0xd9, 0x00, 0x14, 0x4c, 0x5a, 0x1f, 0x2e, +0x61, 0x6e, 0xd0, 0x00, 0x2a, 0x62, 0x79, 0x33, 0x17, 0x40, 0x6d, 0x61, +0x78, 0x42, 0xcc, 0x00, 0x01, 0x59, 0x0a, 0x01, 0xb0, 0x04, 0x07, 0x36, +0x17, 0x1a, 0x20, 0x1f, 0x00, 0x01, 0x2a, 0x08, 0x36, 0x70, 0x6c, 0x65, +0x65, 0x34, 0x30, 0x64, 0x65, 0x70, 0x4b, 0x29, 0x32, 0x6e, 0x74, 0x2e, +0x6e, 0x1f, 0x0d, 0xe5, 0x22, 0x00, 0x46, 0x08, 0x01, 0xa9, 0x16, 0x18, +0x64, 0xdc, 0x1c, 0x05, 0xeb, 0x08, 0x34, 0x69, 0x6e, 0x67, 0x63, 0x02, +0x1f, 0x2e, 0x30, 0x01, 0x03, 0x27, 0x65, 0x6e, 0x55, 0x13, 0x0b, 0xda, +0x01, 0x41, 0x73, 0x20, 0x64, 0x6f, 0x7b, 0x09, 0x04, 0x00, 0x09, 0x00, +0x17, 0x14, 0x94, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, +0x0d, 0x15, 0x02, 0xbe, 0x1d, 0x0f, 0x69, 0x01, 0x1f, 0x0f, 0x64, 0x01, +0x0a, 0x40, 0x5f, 0x41, 0x74, 0x20, 0x1c, 0x05, 0x22, 0x74, 0x5f, 0x19, +0x00, 0x43, 0x20, 0x2b, 0x20, 0x38, 0xda, 0x08, 0x19, 0x2b, 0x35, 0x01, +0x0f, 0xd7, 0x00, 0x7e, 0x17, 0x6c, 0x1e, 0x02, 0x0b, 0x79, 0x00, 0x02, +0xac, 0x00, 0x32, 0x57, 0x68, 0x65, 0x5d, 0x14, 0x02, 0xca, 0x0f, 0x0a, +0x8c, 0x37, 0x02, 0x99, 0x18, 0x03, 0x9d, 0x1c, 0x12, 0x2c, 0xbb, 0x0a, +0x01, 0xd3, 0x1d, 0x00, 0xda, 0x17, 0x00, 0x90, 0x2e, 0x02, 0x7f, 0x28, +0x02, 0xba, 0x03, 0x01, 0x24, 0x0b, 0x07, 0xd6, 0x0a, 0x04, 0x85, 0x02, +0x05, 0x53, 0x1f, 0x05, 0xa1, 0x1c, 0x02, 0xfc, 0x03, 0x11, 0x69, 0xaf, +0x14, 0x02, 0x39, 0x0a, 0x0f, 0xda, 0x07, 0x06, 0x2f, 0x28, 0x29, 0x9e, +0x14, 0x09, 0x0e, 0x36, 0x0c, 0x0f, 0x55, 0x05, 0x0b, 0x0f, 0x70, 0x2d, +0x3b, 0x0f, 0xf3, 0x18, 0x04, 0x0f, 0x96, 0x00, 0x42, 0x0c, 0x22, 0x19, +0x00, 0xf8, 0x05, 0x05, 0x87, 0x27, 0x0f, 0xe8, 0x05, 0x00, 0x41, 0x3a, +0x0a, 0x2a, 0x5f, 0x55, 0x01, 0x03, 0x18, 0x0c, 0x0f, 0x17, 0x06, 0x0c, +0x48, 0x77, 0x6f, 0x72, 0x6b, 0xba, 0x22, 0x02, 0xb4, 0x01, 0x00, 0x0c, +0x01, 0x14, 0x62, 0x0d, 0x18, 0x2f, 0x6f, 0x66, 0xa0, 0x01, 0x03, 0x03, +0xa8, 0x38, 0x02, 0xae, 0x22, 0x0b, 0x0f, 0x01, 0x19, 0x78, 0x2f, 0x0c, +0x26, 0x20, 0x20, 0x2c, 0x09, 0xc2, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x2d, +0x61, 0x6c, 0x6f, 0x6e, 0x65, 0x2e, 0x16, 0x00, 0x07, 0xdc, 0x0c, 0x00, +0xb0, 0x28, 0x03, 0x80, 0x05, 0x0f, 0xcc, 0x08, 0x0c, 0x1f, 0x2e, 0x1e, +0x02, 0x09, 0x05, 0x00, 0x01, 0x0f, 0x69, 0x2f, 0x3a, 0x0e, 0x9b, 0x07, +0x5d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x9a, 0x07, 0x0f, 0x1e, 0x02, 0x05, +0x0e, 0x96, 0x00, 0x0f, 0x1b, 0x1b, 0x12, 0x0f, 0x7b, 0x00, 0x19, 0x0f, +0xce, 0x29, 0x1b, 0x40, 0x4f, 0x62, 0x73, 0x6f, 0x9d, 0x20, 0x0f, 0xce, +0x29, 0x20, 0x10, 0x2f, 0x07, 0x32, 0x00, 0xd3, 0x2c, 0x00, 0xab, 0x01, +0x30, 0x57, 0x61, 0x72, 0x43, 0x33, 0x22, 0x73, 0x20, 0x19, 0x00, 0x15, +0x53, 0xdb, 0x19, 0x44, 0x73, 0x65, 0x20, 0x77, 0x1c, 0x00, 0x10, 0x6d, +0x06, 0x0e, 0x00, 0xc9, 0x34, 0x01, 0xcd, 0x1d, 0x71, 0x70, 0x72, 0x6f, +0x62, 0x6c, 0x65, 0x6d, 0x23, 0x04, 0x02, 0x0f, 0x04, 0x02, 0x22, 0x36, +0x00, 0x3d, 0x16, 0x05, 0x14, 0x21, 0x00, 0x08, 0x1a, 0x11, 0x69, 0xa7, +0x0e, 0x00, 0x4d, 0x00, 0x02, 0x2d, 0x00, 0x01, 0xa8, 0x07, 0x64, 0x2d, +0x57, 0x6e, 0x6f, 0x2d, 0x64, 0x80, 0x00, 0x72, 0x64, 0x2d, 0x64, 0x65, +0x63, 0x6c, 0x61, 0xe3, 0x0f, 0x02, 0xce, 0x1d, 0x42, 0x67, 0x63, 0x63, +0x0a, 0x3c, 0x20, 0x70, 0x5f, 0x43, 0x52, 0x54, 0x5f, 0x53, 0x45, 0x2f, +0x39, 0xc0, 0x5f, 0x4e, 0x4f, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, +0x47, 0x53, 0xe8, 0x08, 0x68, 0x56, 0x69, 0x73, 0x75, 0x61, 0x6c, 0x7f, +0x28, 0x18, 0x2e, 0xfe, 0x37, 0x01, 0x7c, 0x26, 0x07, 0x95, 0x0d, 0x94, +0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x45, 0x00, 0x00, +0x95, 0x25, 0x61, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x2e, 0x97, 0x2a, 0x30, +0x69, 0x66, 0x6e, 0x67, 0x0d, 0x0f, 0x2b, 0x00, 0x0b, 0x3e, 0x0a, 0x23, +0x20, 0x54, 0x00, 0x0f, 0x29, 0x00, 0x10, 0x34, 0x47, 0x43, 0x43, 0x04, +0x35, 0x00, 0xe0, 0x37, 0x92, 0x47, 0x4e, 0x55, 0x43, 0x5f, 0x5f, 0x20, +0x2a, 0x20, 0x22, 0x35, 0x03, 0x11, 0x00, 0x01, 0x36, 0x35, 0x30, 0x5f, +0x5f, 0x29, 0x3c, 0x00, 0x4c, 0x69, 0x66, 0x20, 0x28, 0x39, 0x00, 0xa4, +0x3e, 0x3d, 0x20, 0x34, 0x30, 0x35, 0x29, 0x20, 0x7c, 0x7c, 0x2c, 0x38, +0x00, 0x2b, 0x38, 0x43, 0x6c, 0x61, 0x6e, 0x67, 0x35, 0x00, 0x0f, 0x9c, +0x00, 0x03, 0x23, 0x44, 0x28, 0xbc, 0x01, 0x62, 0x29, 0x20, 0x5f, 0x5f, +0x61, 0x74, 0x42, 0x3c, 0x56, 0x65, 0x5f, 0x5f, 0x28, 0x28, 0x83, 0x01, +0x05, 0x23, 0x00, 0x11, 0x29, 0x49, 0x00, 0x2f, 0x65, 0x6c, 0x80, 0x00, +0x04, 0x3f, 0x33, 0x30, 0x31, 0x6a, 0x00, 0x2c, 0x07, 0x61, 0x00, 0x05, +0xc5, 0x00, 0x21, 0x4d, 0x53, 0x65, 0x00, 0x0f, 0x5a, 0x00, 0x15, 0x00, +0x2f, 0x02, 0x00, 0x0c, 0x20, 0x0f, 0xc0, 0x00, 0x02, 0x02, 0x5e, 0x00, +0x22, 0x73, 0x65, 0x4c, 0x00, 0x03, 0x65, 0x39, 0x03, 0x1e, 0x00, 0x23, +0x28, 0x22, 0xa7, 0x01, 0x37, 0x3a, 0x20, 0x59, 0xdd, 0x38, 0x05, 0x2d, +0x09, 0x0b, 0x74, 0x00, 0x02, 0x35, 0x37, 0x00, 0xa4, 0x0c, 0x02, 0x18, +0x2b, 0x3f, 0x65, 0x72, 0x22, 0xa3, 0x00, 0x12, 0x01, 0x83, 0x00, 0x01, +0xa9, 0x39, 0x02, 0xb0, 0x39, 0x00, 0x0d, 0x2d, 0x0f, 0x2e, 0x02, 0x0b, +0x12, 0x20, 0xc1, 0x38, 0x06, 0xd2, 0x03, 0x0f, 0xc6, 0x39, 0x02, 0x03, +0xa0, 0x03, 0x02, 0x0c, 0x06, 0x07, 0x1a, 0x0c, 0x00, 0xb6, 0x0e, 0x44, +0x6c, 0x61, 0x6e, 0x6e, 0xd4, 0x14, 0x36, 0x61, 0x72, 0x74, 0xb1, 0x39, +0x05, 0xc1, 0x03, 0xf2, 0x01, 0x62, 0x79, 0x20, 0x72, 0x31, 0x33, 0x31, +0x20, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x6d, 0x47, 0x12, 0x0f, +0xd8, 0x13, 0x00, 0x0b, 0xfe, 0x0d, 0x0f, 0x81, 0x28, 0x1c, 0x0f, 0xe7, +0x26, 0x01, 0x03, 0x7f, 0x33, 0x02, 0x4c, 0x1c, 0x0f, 0xd2, 0x28, 0x26, +0x07, 0xeb, 0x31, 0x0f, 0x64, 0x00, 0x00, 0x00, 0x59, 0x04, 0x02, 0x47, +0x27, 0x0b, 0xbf, 0x00, 0x0f, 0x55, 0x27, 0x27, 0x0f, 0xcb, 0x00, 0x0e, +0x07, 0x75, 0x00, 0x0f, 0xbc, 0x27, 0x31, 0x0f, 0xe1, 0x00, 0x0b, 0x05, +0x9d, 0x08, 0x0c, 0xe1, 0x00, 0x0e, 0x50, 0x19, 0x0e, 0x7c, 0x15, 0x0f, +0xf1, 0x00, 0x35, 0x06, 0x85, 0x00, 0x0f, 0x77, 0x00, 0x38, 0x0f, 0x01, +0x01, 0x03, 0x09, 0x10, 0x03, 0x2f, 0x64, 0x65, 0x12, 0x03, 0x17, 0x30, +0x20, 0x6e, 0x61, 0xf3, 0x22, 0x13, 0x61, 0x6c, 0x2a, 0x03, 0xbf, 0x27, +0x06, 0x2c, 0x04, 0x01, 0xd3, 0x0a, 0x01, 0x6d, 0x0e, 0x21, 0x6e, 0x6f, +0x3f, 0x13, 0x41, 0x65, 0x72, 0x20, 0x62, 0x15, 0x1b, 0x02, 0x6d, 0x20, +0x05, 0xeb, 0x08, 0x01, 0xcd, 0x19, 0x05, 0x20, 0x2f, 0x01, 0xfb, 0x0a, +0x04, 0x25, 0x2f, 0x31, 0x61, 0x74, 0x69, 0x83, 0x3b, 0x03, 0x17, 0x28, +0x20, 0x6f, 0x6c, 0x0d, 0x44, 0x03, 0x43, 0x3d, 0x15, 0x73, 0xe1, 0x0d, +0x36, 0x5a, 0x34, 0x5f, 0x30, 0x26, 0x0c, 0x63, 0x2c, 0x0f, 0x63, 0x08, +0x00, 0x0f, 0x38, 0x00, 0x02, 0x30, 0x5f, 0x75, 0x6e, 0x03, 0x2b, 0x16, +0x6e, 0x1d, 0x01, 0x0f, 0x4a, 0x00, 0x0c, 0x00, 0x43, 0x09, 0x03, 0xc8, +0x00, 0x08, 0x16, 0x01, 0x00, 0x55, 0x20, 0x10, 0x6f, 0x4d, 0x14, 0x04, +0x21, 0x0c, 0x14, 0x77, 0x9e, 0x07, 0x22, 0x64, 0x3b, 0xd7, 0x26, 0x01, +0x03, 0x05, 0x00, 0xaa, 0x07, 0x02, 0xfa, 0x00, 0x03, 0x1b, 0x1e, 0x21, +0x72, 0x65, 0xd6, 0x07, 0x02, 0x2d, 0x05, 0x20, 0x68, 0x65, 0xed, 0x13, +0x04, 0x43, 0x25, 0x21, 0x68, 0x69, 0x6c, 0x2d, 0x08, 0xac, 0x37, 0x04, +0x27, 0x23, 0x02, 0x18, 0x0c, 0x02, 0x44, 0x08, 0x08, 0x7a, 0x00, 0x00, +0x7b, 0x01, 0x21, 0x69, 0x67, 0x9a, 0x04, 0x30, 0x74, 0x6f, 0x20, 0x72, +0x10, 0x21, 0x74, 0x61, 0xf6, 0x3e, 0x01, 0xc1, 0x0d, 0x02, 0xcf, 0x01, +0x04, 0x84, 0x02, 0x07, 0x3c, 0x01, 0x0f, 0x72, 0x09, 0x13, 0x07, 0x3f, +0x02, 0x0e, 0x4b, 0x00, 0x0f, 0x4f, 0x01, 0x01, 0x0f, 0x6c, 0x28, 0x17, +0x3f, 0x20, 0x69, 0x73, 0xaa, 0x02, 0x05, 0x0d, 0xbd, 0x05, 0x05, 0x80, +0x11, 0x06, 0xa8, 0x0b, 0x11, 0x3b, 0xd0, 0x14, 0x00, 0xd7, 0x3d, 0x06, +0x1d, 0x00, 0x06, 0x24, 0x3e, 0x14, 0x77, 0xcb, 0x0d, 0x05, 0x3b, 0x09, +0x03, 0xbc, 0x13, 0x07, 0x5d, 0x06, 0x11, 0x22, 0x30, 0x46, 0x0c, 0x2d, +0x1d, 0x14, 0x29, 0x4d, 0x1f, 0x32, 0x22, 0x29, 0x20, 0x82, 0x04, 0x06, +0xdf, 0x13, 0x04, 0x96, 0x18, 0x01, 0x68, 0x03, 0x03, 0x97, 0x18, 0x1f, +0x3b, 0x57, 0x00, 0x1f, 0x02, 0x12, 0x14, 0x08, 0xd2, 0x2c, 0x00, 0x23, +0x00, 0x09, 0xd8, 0x2c, 0x0f, 0x54, 0x00, 0x05, 0x07, 0x31, 0x1f, 0x09, +0x53, 0x00, 0x07, 0x54, 0x00, 0x07, 0x23, 0x00, 0x06, 0x53, 0x00, 0x06, +0x48, 0x05, 0x0f, 0xc1, 0x00, 0x18, 0x04, 0x75, 0x18, 0x0a, 0x6a, 0x00, +0x23, 0x20, 0x20, 0x45, 0x00, 0x01, 0x23, 0x00, 0x56, 0x6c, 0x69, 0x64, +0x65, 0x49, 0x4e, 0x00, 0x09, 0xb6, 0x05, 0x2f, 0x29, 0x3b, 0xc6, 0x01, +0x05, 0x0f, 0x77, 0x0d, 0x00, 0x0f, 0xa0, 0x01, 0x03, 0x0f, 0xcd, 0x0c, +0x0b, 0x0d, 0x56, 0x01, 0x0f, 0xfb, 0x0c, 0x01, 0x00, 0x4f, 0x04, 0xbf, +0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x36, 0x34, 0x6b, 0x20, 0x28, 0x3b, +0x1b, 0x0d, 0x0f, 0xfb, 0x0c, 0x05, 0x05, 0xfe, 0x2a, 0x0f, 0xa6, 0x00, +0x10, 0x0a, 0xdd, 0x0c, 0x0f, 0xa6, 0x00, 0x0d, 0x01, 0x2e, 0x00, 0x0f, +0xa6, 0x00, 0x1c, 0x0d, 0x04, 0x0f, 0x0f, 0xef, 0x42, 0x07, 0x90, 0x7d, +0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0a, +}; + +static unsigned char buf[18830]; + +int main() { + + unsigned long cksum = adler32(0, NULL, 0); + + decompress_lz4(compressed, buf, 18830); + cksum = adler32(cksum, buf, 18830); + + return cksum == 0xf748269d ? 0 : 1; +} From ee49ecdf432fd17a706032530cc2e3b34f0074c8 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Tue, 6 Jun 2017 19:31:16 +0300 Subject: [PATCH 0357/2161] Expand tabs to spaces in lz4.s --- libsrc/common/lz4.s | 328 ++++++++++++++++++++++---------------------- 1 file changed, 164 insertions(+), 164 deletions(-) diff --git a/libsrc/common/lz4.s b/libsrc/common/lz4.s index ee215d4da..5a07a42ed 100644 --- a/libsrc/common/lz4.s +++ b/libsrc/common/lz4.s @@ -4,11 +4,11 @@ ; An optimized LZ4 decompressor ; - .importzp sp, sreg, regsave, regbank - .importzp tmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 - .macpack longbranch - .import memcpy_upwards,pushax,popax - .export _decompress_lz4 + .importzp sp, sreg, regsave, regbank + .importzp tmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 + .macpack longbranch + .import memcpy_upwards,pushax,popax + .export _decompress_lz4 _out = regsave _written = regsave + 2 @@ -22,262 +22,262 @@ _outlen = ptr4 ; void decompress_lz4 (const u8 *in, u8 * const out, const u16 outlen) ; --------------------------------------------------------------- -.segment "CODE" +.segment "CODE" -.proc _decompress_lz4: near +.proc _decompress_lz4: near - sta _outlen - stx _outlen+1 + sta _outlen + stx _outlen+1 - jsr popax - sta _out - stx _out+1 + jsr popax + sta _out + stx _out+1 - jsr popax - sta _in - stx _in+1 + jsr popax + sta _in + stx _in+1 ; ; written = 0; ; - lda #$00 - sta _written + lda #$00 + sta _written ; ; while (written < outlen) { ; - jmp L0046 + jmp L0046 ; ; token = *in++; ; -L0004: ldy #0 - lda (_in),y - sta _token +L0004: ldy #0 + lda (_in),y + sta _token - inc _in - bne L000A - inc _in+1 + inc _in + bne L000A + inc _in+1 L000A: ; ; offset = token >> 4; ; - ldx #$00 - lsr a - lsr a - lsr a - lsr a - sta _offset - stx _offset+1 + ldx #$00 + lsr a + lsr a + lsr a + lsr a + sta _offset + stx _offset+1 ; ; token &= 0xf; ; token += 4; // Minmatch ; - lda _token - and #$0F - clc - adc #4 - sta _token + lda _token + and #$0F + clc + adc #4 + sta _token ; ; if (offset == 15) { ; - lda _offset - cmp #$0F -L0013: bne L001A + lda _offset + cmp #$0F +L0013: bne L001A ; ; tmp = *in++; ; - ldy #0 - lda (_in),y - sta _tmp + ldy #0 + lda (_in),y + sta _tmp - inc _in - bne L0017 - inc _in+1 + inc _in + bne L0017 + inc _in+1 L0017: ; ; offset += tmp; ; - clc - adc _offset - sta _offset - lda #$00 - adc _offset+1 - sta _offset+1 + clc + adc _offset + sta _offset + lda #$00 + adc _offset+1 + sta _offset+1 ; ; if (tmp == 255) ; - lda _tmp - cmp #$FF + lda _tmp + cmp #$FF ; ; goto moreliterals; ; - jmp L0013 + jmp L0013 ; ; if (offset) { ; -L001A: lda _offset - ora _offset+1 - beq L001C +L001A: lda _offset + ora _offset+1 + beq L001C ; ; memcpy(&out[written], in, offset); ; - lda _out - clc - adc _written - sta ptr2 - lda _out+1 - adc _written+1 - tax - lda ptr2 - stx ptr2+1 - jsr pushax - lda _in - ldx _in+1 - sta ptr1 - stx ptr1+1 - ldy #0 - jsr memcpy_upwards + lda _out + clc + adc _written + sta ptr2 + lda _out+1 + adc _written+1 + tax + lda ptr2 + stx ptr2+1 + jsr pushax + lda _in + ldx _in+1 + sta ptr1 + stx ptr1+1 + ldy #0 + jsr memcpy_upwards ; ; written += offset; ; - lda _offset - clc - adc _written - sta _written - lda _offset+1 - adc _written+1 - sta _written+1 + lda _offset + clc + adc _written + sta _written + lda _offset+1 + adc _written+1 + sta _written+1 ; ; in += offset; ; - lda _offset - clc - adc _in - sta _in - lda _offset+1 - adc _in+1 - sta _in+1 + lda _offset + clc + adc _in + sta _in + lda _offset+1 + adc _in+1 + sta _in+1 ; ; if (written >= outlen) ; -L001C: lda _written - cmp _outlen - lda _written+1 - sbc _outlen+1 +L001C: lda _written + cmp _outlen + lda _written+1 + sbc _outlen+1 ; ; return; ; - bcc L0047 - rts + bcc L0047 + rts ; ; memcpy(&offset, in, 2); ; -L0047: ldy #0 - lda (_in),y - sta _offset - iny - lda (_in),y - sta _offset+1 +L0047: ldy #0 + lda (_in),y + sta _offset + iny + lda (_in),y + sta _offset+1 ; ; in += 2; ; - lda #$02 - clc - adc _in - sta _in - bcc L002F - inc _in+1 + lda #$02 + clc + adc _in + sta _in + bcc L002F + inc _in+1 ; ; copysrc = out + written - offset; ; -L002F: lda _out - clc - adc _written - pha - lda _out+1 - adc _written+1 - tax - pla - sec - sbc _offset - sta ptr1 - txa - sbc _offset+1 - sta ptr1+1 +L002F: lda _out + clc + adc _written + pha + lda _out+1 + adc _written+1 + tax + pla + sec + sbc _offset + sta ptr1 + txa + sbc _offset+1 + sta ptr1+1 ; ; offset = token; ; - lda #$00 - sta _offset+1 - lda _token - sta _offset + lda #$00 + sta _offset+1 + lda _token + sta _offset ; ; if (token == 19) { ; - cmp #$13 -L0045: bne L003C + cmp #$13 +L0045: bne L003C ; ; tmp = *in++; ; - ldy #0 - lda (_in),y - sta _tmp + ldy #0 + lda (_in),y + sta _tmp - inc _in - bne L0039 - inc _in+1 + inc _in + bne L0039 + inc _in+1 L0039: ; ; offset += tmp; ; - clc - adc _offset - sta _offset - tya - adc _offset+1 - sta _offset+1 + clc + adc _offset + sta _offset + tya + adc _offset+1 + sta _offset+1 ; ; if (tmp == 255) ; - lda _tmp - cmp #$FF + lda _tmp + cmp #$FF ; ; goto morematches; ; - jmp L0045 + jmp L0045 ; ; memcpy(&out[written], copysrc, offset); ; -L003C: lda _out - clc - adc _written - sta ptr2 - lda _out+1 - adc _written+1 - tax - lda ptr2 - stx ptr2+1 - jsr pushax - jsr memcpy_upwards +L003C: lda _out + clc + adc _written + sta ptr2 + lda _out+1 + adc _written+1 + tax + lda ptr2 + stx ptr2+1 + jsr pushax + jsr memcpy_upwards ; ; written += offset; ; - lda _offset - clc - adc _written - sta _written - lda _offset+1 - adc _written+1 -L0046: sta _written+1 + lda _offset + clc + adc _written + sta _written + lda _offset+1 + adc _written+1 +L0046: sta _written+1 ; ; while (written < outlen) { ; - lda _written - cmp _outlen - lda _written+1 - sbc _outlen+1 - jcc L0004 + lda _written + cmp _outlen + lda _written+1 + sbc _outlen+1 + jcc L0004 - rts + rts .endproc From a397a8c1a18a51e8c2bc7ac7a4d70e7599a75b36 Mon Sep 17 00:00:00 2001 From: greg-king5 <greg.king5@verizon.net> Date: Wed, 7 Jun 2017 10:20:20 -0400 Subject: [PATCH 0358/2161] Added missing -O configuration. --- test/val/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/val/Makefile b/test/val/Makefile index c7539c81b..fe194d892 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -31,7 +31,7 @@ SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65) WORKDIR = ../../testwrk/val -OPTIONS = g O Os Osi Osir Oi Oir Or +OPTIONS = g O Os Osi Osir Osr Oi Oir Or .PHONY: all clean From e24bb372d0e54201da8905d15ccf81e0c99cb890 Mon Sep 17 00:00:00 2001 From: greg-king5 <greg.king5@verizon.net> Date: Wed, 7 Jun 2017 10:26:34 -0400 Subject: [PATCH 0359/2161] Added a missing -O configuration. --- test/ref/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ref/Makefile b/test/ref/Makefile index c986513b8..3c2e582e4 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -33,7 +33,7 @@ SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65) WORKDIR = ..$S..$Stestwrk$Sref -OPTIONS = g O Os Osi Osir Oi Oir Or +OPTIONS = g O Os Osi Osir Osr Oi Oir Or DIFF = $(WORKDIR)$Sbdiff$(EXE) From 06c3cd830747c0049ada4a5a0eef2b1ad3fd29e7 Mon Sep 17 00:00:00 2001 From: greg-king5 <greg.king5@verizon.net> Date: Wed, 7 Jun 2017 10:31:09 -0400 Subject: [PATCH 0360/2161] Added a missing -O configuration. --- test/misc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/misc/Makefile b/test/misc/Makefile index 39a9a3868..330c9d500 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -35,7 +35,7 @@ SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65) WORKDIR = ..$S..$Stestwrk$Smisc -OPTIONS = g O Os Osi Osir Oi Oir Or +OPTIONS = g O Os Osi Osir Osr Oi Oir Or DIFF = $(WORKDIR)$Sbdiff$(EXE) From e85796e028b152c68c7451c4bc73a06aa6be3749 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Fri, 9 Jun 2017 10:35:16 +0300 Subject: [PATCH 0361/2161] Edit comment style, add second const --- include/lz4.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/include/lz4.h b/include/lz4.h index d6bf1b17c..fd11c3e2a 100644 --- a/include/lz4.h +++ b/include/lz4.h @@ -32,12 +32,11 @@ #ifndef _LZ4_H #define _LZ4_H -void __fastcall__ decompress_lz4 (const unsigned char* src, unsigned char* dst, +void __fastcall__ decompress_lz4 (const unsigned char* src, unsigned char* const dst, const unsigned short uncompressed_size); -/* - Decompresses the source buffer into the destination buffer. - The size of the decompressed data must be known in advance, LZ4 - does not include any terminator in-stream. +/* Decompresses the source buffer into the destination buffer. +** The size of the decompressed data must be known in advance, LZ4 +** does not include any terminator in-stream. */ /* end of lz4.h */ From cd460a81602851655dc83543a94609118dae976f Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Fri, 9 Jun 2017 10:37:50 +0300 Subject: [PATCH 0362/2161] Remove _ from internal vars --- libsrc/common/lz4.s | 190 ++++++++++++++++++++++---------------------- 1 file changed, 95 insertions(+), 95 deletions(-) diff --git a/libsrc/common/lz4.s b/libsrc/common/lz4.s index 5a07a42ed..922cb2eba 100644 --- a/libsrc/common/lz4.s +++ b/libsrc/common/lz4.s @@ -10,13 +10,13 @@ .import memcpy_upwards,pushax,popax .export _decompress_lz4 -_out = regsave -_written = regsave + 2 -_tmp = tmp1 -_token = tmp2 -_offset = ptr3 -_in = sreg -_outlen = ptr4 +out = regsave +written = regsave + 2 +tmp = tmp1 +token = tmp2 +offset = ptr3 +in = sreg +outlen = ptr4 ; --------------------------------------------------------------- ; void decompress_lz4 (const u8 *in, u8 * const out, const u16 outlen) @@ -26,22 +26,22 @@ _outlen = ptr4 .proc _decompress_lz4: near - sta _outlen - stx _outlen+1 + sta outlen + stx outlen+1 jsr popax - sta _out - stx _out+1 + sta out + stx out+1 jsr popax - sta _in - stx _in+1 + sta in + stx in+1 ; ; written = 0; ; lda #$00 - sta _written + sta written ; ; while (written < outlen) { ; @@ -50,12 +50,12 @@ _outlen = ptr4 ; token = *in++; ; L0004: ldy #0 - lda (_in),y - sta _token + lda (in),y + sta token - inc _in + inc in bne L000A - inc _in+1 + inc in+1 L000A: ; ; offset = token >> 4; @@ -65,47 +65,47 @@ L000A: lsr a lsr a lsr a - sta _offset - stx _offset+1 + sta offset + stx offset+1 ; ; token &= 0xf; ; token += 4; // Minmatch ; - lda _token + lda token and #$0F clc adc #4 - sta _token + sta token ; ; if (offset == 15) { ; - lda _offset + lda offset cmp #$0F L0013: bne L001A ; ; tmp = *in++; ; ldy #0 - lda (_in),y - sta _tmp + lda (in),y + sta tmp - inc _in + inc in bne L0017 - inc _in+1 + inc in+1 L0017: ; ; offset += tmp; ; clc - adc _offset - sta _offset + adc offset + sta offset lda #$00 - adc _offset+1 - sta _offset+1 + adc offset+1 + sta offset+1 ; ; if (tmp == 255) ; - lda _tmp + lda tmp cmp #$FF ; ; goto moreliterals; @@ -114,24 +114,24 @@ L0017: ; ; if (offset) { ; -L001A: lda _offset - ora _offset+1 +L001A: lda offset + ora offset+1 beq L001C ; ; memcpy(&out[written], in, offset); ; - lda _out + lda out clc - adc _written + adc written sta ptr2 - lda _out+1 - adc _written+1 + lda out+1 + adc written+1 tax lda ptr2 stx ptr2+1 jsr pushax - lda _in - ldx _in+1 + lda in + ldx in+1 sta ptr1 stx ptr1+1 ldy #0 @@ -139,30 +139,30 @@ L001A: lda _offset ; ; written += offset; ; - lda _offset + lda offset clc - adc _written - sta _written - lda _offset+1 - adc _written+1 - sta _written+1 + adc written + sta written + lda offset+1 + adc written+1 + sta written+1 ; ; in += offset; ; - lda _offset + lda offset clc - adc _in - sta _in - lda _offset+1 - adc _in+1 - sta _in+1 + adc in + sta in + lda offset+1 + adc in+1 + sta in+1 ; ; if (written >= outlen) ; -L001C: lda _written - cmp _outlen - lda _written+1 - sbc _outlen+1 +L001C: lda written + cmp outlen + lda written+1 + sbc outlen+1 ; ; return; ; @@ -172,44 +172,44 @@ L001C: lda _written ; memcpy(&offset, in, 2); ; L0047: ldy #0 - lda (_in),y - sta _offset + lda (in),y + sta offset iny - lda (_in),y - sta _offset+1 + lda (in),y + sta offset+1 ; ; in += 2; ; lda #$02 clc - adc _in - sta _in + adc in + sta in bcc L002F - inc _in+1 + inc in+1 ; ; copysrc = out + written - offset; ; -L002F: lda _out +L002F: lda out clc - adc _written + adc written pha - lda _out+1 - adc _written+1 + lda out+1 + adc written+1 tax pla sec - sbc _offset + sbc offset sta ptr1 txa - sbc _offset+1 + sbc offset+1 sta ptr1+1 ; ; offset = token; ; lda #$00 - sta _offset+1 - lda _token - sta _offset + sta offset+1 + lda token + sta offset ; ; if (token == 19) { ; @@ -219,26 +219,26 @@ L0045: bne L003C ; tmp = *in++; ; ldy #0 - lda (_in),y - sta _tmp + lda (in),y + sta tmp - inc _in + inc in bne L0039 - inc _in+1 + inc in+1 L0039: ; ; offset += tmp; ; clc - adc _offset - sta _offset + adc offset + sta offset tya - adc _offset+1 - sta _offset+1 + adc offset+1 + sta offset+1 ; ; if (tmp == 255) ; - lda _tmp + lda tmp cmp #$FF ; ; goto morematches; @@ -247,12 +247,12 @@ L0039: ; ; memcpy(&out[written], copysrc, offset); ; -L003C: lda _out +L003C: lda out clc - adc _written + adc written sta ptr2 - lda _out+1 - adc _written+1 + lda out+1 + adc written+1 tax lda ptr2 stx ptr2+1 @@ -261,20 +261,20 @@ L003C: lda _out ; ; written += offset; ; - lda _offset + lda offset clc - adc _written - sta _written - lda _offset+1 - adc _written+1 -L0046: sta _written+1 + adc written + sta written + lda offset+1 + adc written+1 +L0046: sta written+1 ; ; while (written < outlen) { ; - lda _written - cmp _outlen - lda _written+1 - sbc _outlen+1 + lda written + cmp outlen + lda written+1 + sbc outlen+1 jcc L0004 rts From bba961e54deb382509425ec5544e68f59ed036c3 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Fri, 9 Jun 2017 10:40:17 +0300 Subject: [PATCH 0363/2161] Use hex immediates --- libsrc/common/lz4.s | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libsrc/common/lz4.s b/libsrc/common/lz4.s index 922cb2eba..4901d1a3c 100644 --- a/libsrc/common/lz4.s +++ b/libsrc/common/lz4.s @@ -49,7 +49,7 @@ outlen = ptr4 ; ; token = *in++; ; -L0004: ldy #0 +L0004: ldy #$00 lda (in),y sta token @@ -74,7 +74,7 @@ L000A: lda token and #$0F clc - adc #4 + adc #$04 sta token ; ; if (offset == 15) { @@ -85,7 +85,7 @@ L0013: bne L001A ; ; tmp = *in++; ; - ldy #0 + ldy #$00 lda (in),y sta tmp @@ -134,7 +134,7 @@ L001A: lda offset ldx in+1 sta ptr1 stx ptr1+1 - ldy #0 + ldy #$00 jsr memcpy_upwards ; ; written += offset; @@ -171,7 +171,7 @@ L001C: lda written ; ; memcpy(&offset, in, 2); ; -L0047: ldy #0 +L0047: ldy #$00 lda (in),y sta offset iny @@ -218,7 +218,7 @@ L0045: bne L003C ; ; tmp = *in++; ; - ldy #0 + ldy #$00 lda (in),y sta tmp From c444ed5e4fbda9c011d5b2502ba4fabd9e37628c Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Fri, 9 Jun 2017 10:42:24 +0300 Subject: [PATCH 0364/2161] Mention the optimizations in a comment --- libsrc/common/lz4.s | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libsrc/common/lz4.s b/libsrc/common/lz4.s index 4901d1a3c..a750f4bf8 100644 --- a/libsrc/common/lz4.s +++ b/libsrc/common/lz4.s @@ -2,6 +2,9 @@ ; Lauri Kasanen, 6 Jun 2017 ; (C) Mega Cat Studios ; An optimized LZ4 decompressor +; +; Almost 7 times faster, uses no RAM (vs 14 bytes BSS), and takes 1/4 the space +; vs the official C source. ; .importzp sp, sreg, regsave, regbank From 135041ac3cc809a1cc38e4567a559bdcf0f0c1dc Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Fri, 9 Jun 2017 10:54:50 +0300 Subject: [PATCH 0365/2161] Add lz4 doc --- doc/funcref.sgml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index d160082bf..3e74b2785 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -398,6 +398,13 @@ function. (incomplete) +<sect1><tt/lz4.h/<label id="lz4.h"><p> + +<itemize> +<item><ref id="decompress_lz4" name="decompress_lz4"> +</itemize> + + <sect1><tt/modload.h/<label id="modload.h"><p> <itemize> @@ -2632,6 +2639,23 @@ used in presence of a prototype. </quote> +<sect1>decompress_lz4<label id="decompress_lz4"><p> + +<quote> +<descrip> +<tag/Function/Uncompress a LZ4-compressed buffer. +<tag/Header/<tt/<ref id="lz4.h" name="lz4.h">/ +<tag/Declaration/<tt/void decompress_lz4 (const unsigned char* src, unsigned char* const dst, const unsigned short uncompressed_size);/ +<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. +</itemize> +<tag/Availability/cc65 +<tag/Example/None. +</descrip> +</quote> + + <sect1>div<label id="div"><p> <quote> From 4235e569d20cf64e52a26267149f4cf4ca1d4c89 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Fri, 9 Jun 2017 16:57:47 +0300 Subject: [PATCH 0366/2161] Small lz4 optimizations --- libsrc/common/lz4.s | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libsrc/common/lz4.s b/libsrc/common/lz4.s index a750f4bf8..4702137bc 100644 --- a/libsrc/common/lz4.s +++ b/libsrc/common/lz4.s @@ -137,7 +137,7 @@ L001A: lda offset ldx in+1 sta ptr1 stx ptr1+1 - ldy #$00 +; ldy #$00 - not needed as pushax zeroes Y jsr memcpy_upwards ; ; written += offset; @@ -195,11 +195,11 @@ L0047: ldy #$00 L002F: lda out clc adc written - pha + tay lda out+1 adc written+1 tax - pla + tya sec sbc offset sta ptr1 From 30f941ba39def8d3e3e654f3e9f6fc9dd5eadac6 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 15 Jun 2017 16:44:46 -0400 Subject: [PATCH 0367/2161] Added a missing label to some conio cursor movement functions. It had prevented other functions, e.g. cputs(), from being linked into a program. --- libsrc/atmos/gotoxy.s | 10 ++++++---- libsrc/creativision/gotoxy.s | 8 ++++++-- libsrc/gamate/gotoxy.s | 6 ++---- libsrc/telestrat/gotoxy.s | 35 +++++++++++++++++++++-------------- 4 files changed, 35 insertions(+), 24 deletions(-) diff --git a/libsrc/atmos/gotoxy.s b/libsrc/atmos/gotoxy.s index 80d4d5251..6652c9419 100644 --- a/libsrc/atmos/gotoxy.s +++ b/libsrc/atmos/gotoxy.s @@ -1,14 +1,18 @@ ; -; Ullrich von Bassewitz, 2003-04-13 +; 2003-04-13, Ullrich von Bassewitz +; 2017-06-15, Greg King ; ; void gotoxy (unsigned char x, unsigned char y); ; - .export _gotoxy + .export gotoxy, _gotoxy + .import popa .include "atmos.inc" +gotoxy: jsr popa ; Get Y + .proc _gotoxy sta CURS_Y ; Set Y @@ -17,5 +21,3 @@ rts .endproc - - diff --git a/libsrc/creativision/gotoxy.s b/libsrc/creativision/gotoxy.s index 12ce0abea..588dd83a0 100644 --- a/libsrc/creativision/gotoxy.s +++ b/libsrc/creativision/gotoxy.s @@ -1,15 +1,19 @@ ; -; Ullrich von Bassewitz, 06.08.1998 +; 1998-08-06, Ullrich von Bassewitz +; 2017-06-15, Greg King ; ; void gotoxy (unsigned char x, unsigned char y); ; - .export _gotoxy + .export gotoxy, _gotoxy + .import setcursor .import popa .include "creativision.inc" +gotoxy: jsr popa ; Get Y + .proc _gotoxy sta CURSOR_Y ; Set Y diff --git a/libsrc/gamate/gotoxy.s b/libsrc/gamate/gotoxy.s index 4a4871444..d49bd2967 100644 --- a/libsrc/gamate/gotoxy.s +++ b/libsrc/gamate/gotoxy.s @@ -9,7 +9,7 @@ .include "extzp.inc" gotoxy: - jsr popa ; Get X + jsr popa ; Get Y _gotoxy: sta CURS_Y ; Set Y @@ -20,6 +20,4 @@ _gotoxy: ;------------------------------------------------------------------------------- ; force the init constructor to be imported - .import initconio -conio_init = initconio - + .forceimport initconio diff --git a/libsrc/telestrat/gotoxy.s b/libsrc/telestrat/gotoxy.s index e0c8154e3..e1470f848 100644 --- a/libsrc/telestrat/gotoxy.s +++ b/libsrc/telestrat/gotoxy.s @@ -1,19 +1,26 @@ ; -; jede jede@oric.org 2017-02-25 +; 2017-02-25, jede <jede@oric.org> +; 2017-06-15, Greg King +; +; void gotoxy (unsigned char x, unsigned char y); ; - .export _gotoxy - - .import popa - - .importzp sp - .include "telestrat.inc" + .export gotoxy, _gotoxy + + .import popa + .importzp sp + + .include "telestrat.inc" + +gotoxy: jsr popa ; Get Y .proc _gotoxy - ; This function move only cursor for display, it does not move the prompt position - ; in telemon, there is position for prompt, and another for the cursor - sta SCRY - jsr popa - sta SCRX - rts -.endproc + +; This function moves only the display cursor; it does not move the prompt position. +; In telemon, there is a position for the prompt, and another for the cursor. + + sta SCRY + jsr popa + sta SCRX + rts +.endproc From 035621aa95e2be6a6f5f0fc091e9fc4c7df2047d Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 17 Jun 2017 02:26:54 +0200 Subject: [PATCH 0368/2161] fixed code a bit so it compiles again :) --- libsrc/c128/waitvblank.s | 15 ++++----------- libsrc/c64/waitvblank.s | 15 ++++----------- libsrc/cbm510/waitvblank.s | 27 ++++++++------------------- libsrc/vic20/waitvblank.s | 7 ++++++- 4 files changed, 22 insertions(+), 42 deletions(-) diff --git a/libsrc/c128/waitvblank.s b/libsrc/c128/waitvblank.s index a3904d858..54699286c 100644 --- a/libsrc/c128/waitvblank.s +++ b/libsrc/c128/waitvblank.s @@ -1,20 +1,13 @@ .export _waitvblank - .include "c128/c128.inc" + .include "c128.inc" _waitvblank: - lda PALFLAG - beq @ntsc - ldx #(312-24)-256 - .byte $2c -@ntsc: - ldx #(262-4)-256 @l1: lda VIC_CTRL1 - and #$80 - beq @l1 + bpl @l1 @l2: - cpx VIC_HLINE - bcs @l2 + lda VIC_CTRL1 + bmi @l2 rts diff --git a/libsrc/c64/waitvblank.s b/libsrc/c64/waitvblank.s index 09570f873..606f41681 100644 --- a/libsrc/c64/waitvblank.s +++ b/libsrc/c64/waitvblank.s @@ -1,20 +1,13 @@ .export _waitvblank - .include "c64/c64.inc" + .include "c64.inc" _waitvblank: - lda PALFLAG - beq @ntsc - ldx #(312-24)-256 - .byte $2c -@ntsc: - ldx #(262-4)-256 @l1: lda VIC_CTRL1 - and #$80 - beq @l1 + bpl @l1 @l2: - cpx VIC_HLINE - bcs @l2 + lda VIC_CTRL1 + bmi @l2 rts diff --git a/libsrc/cbm510/waitvblank.s b/libsrc/cbm510/waitvblank.s index 30cbf072f..975861f2c 100644 --- a/libsrc/cbm510/waitvblank.s +++ b/libsrc/cbm510/waitvblank.s @@ -5,33 +5,22 @@ .importzp vic - .include "cbm510/cbm510.inc" + .include "cbm510.inc" _waitvblank: rts ; FIXME jsr sys_bank ; Switch to the system bank - lda PALFLAG - beq ntsc - ldx #(312-24)-256 - .byte $2c -ntsc: - ldx #(262-2)-256 - sei - ldy #VIC_CTRL1 -l1: - lda (vic),y - and #$80 - beq l1 -;?!? -; ldy #VIC_HLINE -; txa -;l2: -; cmp (vic),y -; bcs l2 + ldy #VIC_CTRL1 +@l1: + lda (vic),y + bpl @l1 +@l2: + lda (vic),y + bmi @l2 cli jmp restore_bank diff --git a/libsrc/vic20/waitvblank.s b/libsrc/vic20/waitvblank.s index b99c74bed..246c44640 100644 --- a/libsrc/vic20/waitvblank.s +++ b/libsrc/vic20/waitvblank.s @@ -1,6 +1,11 @@ .export _waitvblank - .include "vic20/vic20.inc" + .include "vic20.inc" + +; FIXME +; this flag doesnt work on vic20!!! +; it will have to be filled by a get_tv() constructor or so +PALFLAG = $2A6 ; $01 = PAL, $00 = NTSC _waitvblank: lda PALFLAG From a42feca228d589e3d3ae3bb80da7c668c1db028f Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 17 Jun 2017 02:37:34 +0200 Subject: [PATCH 0369/2161] fixed some stuff, compiles again :) --- asminc/c128.inc | 4 ++++ asminc/c64.inc | 3 +++ asminc/pet.inc | 5 +++++ asminc/plus4.inc | 5 +++++ asminc/vic20.inc | 3 +++ libsrc/c128/kbrepeat.s | 2 +- libsrc/c64/kbrepeat.s | 2 +- libsrc/pet/kbrepeat.s | 2 +- libsrc/plus4/kbrepeat.s | 2 +- libsrc/vic20/kbrepeat.s | 2 +- 10 files changed, 25 insertions(+), 5 deletions(-) diff --git a/asminc/c128.inc b/asminc/c128.inc index e6c89b07b..9e9acc5a8 100644 --- a/asminc/c128.inc +++ b/asminc/c128.inc @@ -38,6 +38,10 @@ INIT_STATUS := $A04 ; Flags: Reset/Restore initiation status FKEY_LEN := $1000 ; Function key lengths FKEY_TEXT := $100A ; Function key texts +KBDREPEAT := $28a +KBDREPEATRATE := $28b +KBDREPEATDELAY := $28c + ; --------------------------------------------------------------------------- ; Kernal routines diff --git a/asminc/c64.inc b/asminc/c64.inc index ababb1ea0..00b66a64f 100644 --- a/asminc/c64.inc +++ b/asminc/c64.inc @@ -33,6 +33,9 @@ CHARCOLOR := $286 CURS_COLOR := $287 ; Color under the cursor PALFLAG := $2A6 ; $01 = PAL, $00 = NTSC +KBDREPEAT := $28a +KBDREPEATRATE := $28b +KBDREPEATDELAY := $28c ; --------------------------------------------------------------------------- ; Kernal routines diff --git a/asminc/pet.inc b/asminc/pet.inc index a745a89c8..ea6eef2e0 100644 --- a/asminc/pet.inc +++ b/asminc/pet.inc @@ -31,6 +31,11 @@ BASIC_BUF_LEN = 81 ; Maximum length of command-line KEY_BUF := $26F ; Keyboard buffer +;FIXME: these are wrong? +KBDREPEAT := $28a +KBDREPEATRATE := $28b +KBDREPEATDELAY := $28c + ;---------------------------------------------------------------------------- ; PET ROM type detection diff --git a/asminc/plus4.inc b/asminc/plus4.inc index 69b2298a3..42ed314bd 100644 --- a/asminc/plus4.inc +++ b/asminc/plus4.inc @@ -33,6 +33,11 @@ FKEY_COUNT := $55D ; Characters for function key FKEY_SPACE := $55F ; Function key definitions FKEY_ORIG := $F3D2 ; Original definitions +;FIXME: he?! these ok? :o) +KBDREPEAT := $28a +KBDREPEATRATE := $28b +KBDREPEATDELAY := $28c + ; --------------------------------------------------------------------------- ; Kernal routines diff --git a/asminc/vic20.inc b/asminc/vic20.inc index 12424dc11..d882eb1ad 100644 --- a/asminc/vic20.inc +++ b/asminc/vic20.inc @@ -31,6 +31,9 @@ BASIC_BUF_LEN = 89 ; Maximum length of command-line CHARCOLOR := $286 CURS_COLOR := $287 ; Color under the cursor +KBDREPEAT := $28a +KBDREPEATRATE := $28b +KBDREPEATDELAY := $28c ; --------------------------------------------------------------------------- ; Screen size diff --git a/libsrc/c128/kbrepeat.s b/libsrc/c128/kbrepeat.s index f515e4ca3..c32e8c017 100644 --- a/libsrc/c128/kbrepeat.s +++ b/libsrc/c128/kbrepeat.s @@ -1,7 +1,7 @@ .export _kbrepeat, _kbrepeatdelay, _kbrepeatrate - .include "c128/c128.inc" + .include "c128.inc" _kbrepeat: ldx KBDREPEAT ; get old value diff --git a/libsrc/c64/kbrepeat.s b/libsrc/c64/kbrepeat.s index b6c33250b..f59c8a6da 100644 --- a/libsrc/c64/kbrepeat.s +++ b/libsrc/c64/kbrepeat.s @@ -1,7 +1,7 @@ .export _kbrepeat, _kbrepeatdelay, _kbrepeatrate - .include "c64/c64.inc" + .include "c64.inc" _kbrepeat: ldx KBDREPEAT ; get old value diff --git a/libsrc/pet/kbrepeat.s b/libsrc/pet/kbrepeat.s index 44d60575f..0a29d7420 100644 --- a/libsrc/pet/kbrepeat.s +++ b/libsrc/pet/kbrepeat.s @@ -1,7 +1,7 @@ .export _kbrepeat, _kbrepeatdelay, _kbrepeatrate - .include "pet/pet.inc" + .include "pet.inc" _kbrepeat: ldx KBDREPEAT ; get old value diff --git a/libsrc/plus4/kbrepeat.s b/libsrc/plus4/kbrepeat.s index 8636d0e33..927b99e5b 100644 --- a/libsrc/plus4/kbrepeat.s +++ b/libsrc/plus4/kbrepeat.s @@ -1,7 +1,7 @@ .export _kbrepeat, _kbrepeatdelay, _kbrepeatrate - .include "plus4/plus4.inc" + .include "plus4.inc" _kbrepeat: ldx KBDREPEAT ; get old value diff --git a/libsrc/vic20/kbrepeat.s b/libsrc/vic20/kbrepeat.s index 5a4ad96f6..5115c852e 100644 --- a/libsrc/vic20/kbrepeat.s +++ b/libsrc/vic20/kbrepeat.s @@ -1,7 +1,7 @@ .export _kbrepeat, _kbrepeatdelay, _kbrepeatrate - .include "vic20/vic20.inc" + .include "vic20.inc" _kbrepeat: ldx KBDREPEAT ; get old value From d3ccc289c1a09d290e77935c13ac94972b18ca4c Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 16 Jun 2017 21:53:50 -0400 Subject: [PATCH 0370/2161] Stopped cc65 from putting redundant .segment directives into its Assembly output. --- src/cc65/compile.c | 25 +++++++++++++++---------- src/cc65/pragma.c | 20 ++++++++++++++++---- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 3c1042154..d79ef350b 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -243,19 +243,20 @@ static void Parse (void) } Entry->Flags &= ~(SC_STORAGE | SC_DEF); } else { - /* A global (including static) uninitialized variable - ** is only a tentative definition. For example, this is valid: + /* A global (including static) uninitialized variable is + ** only a tentative definition. For example, this is valid: ** int i; ** int i; ** static int j; ** static int j = 42; - ** Code for these will be generated in FinishCompile. + ** Code for them will be generated by FinishCompile(). ** For now, just save the BSS segment name - ** (can be set with #pragma bss-name) + ** (can be set by #pragma bss-name). */ const char* bssName = GetSegName (SEG_BSS); + if (Entry->V.BssName && strcmp (Entry->V.BssName, bssName) != 0) { - Error ("Global variable `%s' has already been defined in `%s' segment", + Error ("Global variable `%s' already was defined in the `%s' segment.", Entry->Name, Entry->V.BssName); } Entry->V.BssName = xstrdup (bssName); @@ -419,7 +420,7 @@ void FinishCompile (void) SymEntry* Entry; /* Walk over all global symbols: - ** - for functions do cleanup, optimizations ... + ** - for functions, do clean-up and optimizations ** - generate code for uninitialized global variables */ for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) { @@ -429,13 +430,17 @@ void FinishCompile (void) CS_MergeLabels (Entry->V.F.Seg->Code); RunOpt (Entry->V.F.Seg->Code); } else if ((Entry->Flags & (SC_STORAGE | SC_DEF | SC_STATIC)) == (SC_STORAGE | SC_STATIC)) { - /* Tentative definition of uninitialized global variable */ + /* Assembly definition of uninitialized global variable */ + + /* Set the segment name only when it changes */ + if (strcmp (GetSegName (SEG_BSS), Entry->V.BssName) != 0) { + SetSegName (SEG_BSS, Entry->V.BssName); + g_segname (SEG_BSS); + } g_usebss (); - SetSegName (SEG_BSS, Entry->V.BssName); - g_segname (SEG_BSS); /* TODO: skip if same as before */ g_defgloblabel (Entry->Name); g_res (SizeOf (Entry->Type)); - /* Mark as defined, so that it will be exported not imported */ + /* Mark as defined; so that it will be exported, not imported */ Entry->Flags |= SC_DEF; } } diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 3dfc62668..de1979c12 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -386,11 +386,11 @@ static void StringPragma (StrBuf* B, void (*Func) (const char*)) static void SegNamePragma (StrBuf* B, segment_t Seg) /* Handle a pragma that expects a segment name parameter */ { - StrBuf S = AUTO_STRBUF_INITIALIZER; const char* Name; + StrBuf S = AUTO_STRBUF_INITIALIZER; + int Push = 0; /* Check for the "push" or "pop" keywords */ - int Push = 0; switch (ParsePushPop (B)) { case PP_NONE: @@ -403,7 +403,13 @@ static void SegNamePragma (StrBuf* B, segment_t Seg) case PP_POP: /* Pop the old value and output it */ PopSegName (Seg); - g_segname (Seg); + + /* 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); + } /* Done */ goto ExitPoint; @@ -434,7 +440,13 @@ static void SegNamePragma (StrBuf* B, segment_t Seg) } else { SetSegName (Seg, Name); } - g_segname (Seg); + + /* 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); + } } else { From 49aad01bf105fb731270a964c6130c3f52165c0d Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 21 Jun 2017 23:18:00 +0200 Subject: [PATCH 0371/2161] dont trash akku if possible, use VDC register when in 80column mode --- libsrc/c128/waitvblank.s | 16 ++++++++++++++-- libsrc/c64/waitvblank.s | 4 ++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/libsrc/c128/waitvblank.s b/libsrc/c128/waitvblank.s index 54699286c..e0a469d0e 100644 --- a/libsrc/c128/waitvblank.s +++ b/libsrc/c128/waitvblank.s @@ -4,10 +4,22 @@ .include "c128.inc" _waitvblank: + + lda MODE + bmi @c80 + @l1: - lda VIC_CTRL1 + bit VIC_CTRL1 bpl @l1 @l2: - lda VIC_CTRL1 + bit VIC_CTRL1 bmi @l2 rts + +@c80: + ;FIXME: do we have to switch banks? +@l3: + lda VDC_INDEX + and #$20 + beq @l3 + rts diff --git a/libsrc/c64/waitvblank.s b/libsrc/c64/waitvblank.s index 606f41681..dd9087841 100644 --- a/libsrc/c64/waitvblank.s +++ b/libsrc/c64/waitvblank.s @@ -5,9 +5,9 @@ _waitvblank: @l1: - lda VIC_CTRL1 + bit VIC_CTRL1 bpl @l1 @l2: - lda VIC_CTRL1 + bit VIC_CTRL1 bmi @l2 rts From e985e0beb424f0146c1755aa8d7a310ebb90783b Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 22 Jun 2017 00:04:42 +0200 Subject: [PATCH 0372/2161] fixed zp locations provided by polluks :) --- asminc/pet.inc | 15 +++++++++++---- asminc/plus4.inc | 7 +++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/asminc/pet.inc b/asminc/pet.inc index ea6eef2e0..8f2f469e0 100644 --- a/asminc/pet.inc +++ b/asminc/pet.inc @@ -31,10 +31,17 @@ BASIC_BUF_LEN = 81 ; Maximum length of command-line KEY_BUF := $26F ; Keyboard buffer -;FIXME: these are wrong? -KBDREPEAT := $28a -KBDREPEATRATE := $28b -KBDREPEATDELAY := $28c +;FIXME: we must somehow handle the difference between the two - how? + +; 40-Column PETs +;KBDREPEAT := $3ee +;KBDREPEATRATE := $3ea +;KBDREPEATDELAY := $3e9 + +; 80-Column PETs +KBDREPEAT := $e4 +KBDREPEATRATE := $e5 +KBDREPEATDELAY := $e6 ;---------------------------------------------------------------------------- ; PET ROM type detection diff --git a/asminc/plus4.inc b/asminc/plus4.inc index 42ed314bd..3b2f08c54 100644 --- a/asminc/plus4.inc +++ b/asminc/plus4.inc @@ -33,10 +33,9 @@ FKEY_COUNT := $55D ; Characters for function key FKEY_SPACE := $55F ; Function key definitions FKEY_ORIG := $F3D2 ; Original definitions -;FIXME: he?! these ok? :o) -KBDREPEAT := $28a -KBDREPEATRATE := $28b -KBDREPEATDELAY := $28c +KBDREPEAT := $540 +KBDREPEATRATE := $541 +KBDREPEATDELAY := $542 ; --------------------------------------------------------------------------- ; Kernal routines From 3ff4a1333c374c0092abe227523f940e6f1d4ea6 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 22 Jun 2017 00:19:39 +0200 Subject: [PATCH 0373/2161] use BIT so akku wont get trashed at least in 40 cols mode --- libsrc/c128/waitvblank.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/c128/waitvblank.s b/libsrc/c128/waitvblank.s index e0a469d0e..c144e11c2 100644 --- a/libsrc/c128/waitvblank.s +++ b/libsrc/c128/waitvblank.s @@ -5,7 +5,7 @@ _waitvblank: - lda MODE + bit MODE bmi @c80 @l1: From bd883327ace3f7de952a48b394a8ce6b53636595 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 26 Jun 2017 02:34:23 -0400 Subject: [PATCH 0374/2161] Added two functions that make it easier to write portable programs for Ohio Scientific computers. --- libsrc/osic1p/doesclrscr.s | 14 ++++++++++++++ libsrc/osic1p/revers.s | 9 +++++++++ 2 files changed, 23 insertions(+) create mode 100644 libsrc/osic1p/doesclrscr.s create mode 100644 libsrc/osic1p/revers.s diff --git a/libsrc/osic1p/doesclrscr.s b/libsrc/osic1p/doesclrscr.s new file mode 100644 index 000000000..3d15e8ade --- /dev/null +++ b/libsrc/osic1p/doesclrscr.s @@ -0,0 +1,14 @@ +; +; 2016-06, Christian Groessler +; 2017-06-26, Greg King +; +; unsigned char doesclrscrafterexit (void); +; +; Returns 0/1 if, after program termination, the screen isn't/is cleared. +; + + .import return1 + +; cc65's OSI programs return to the monitor ROM which clears the screen. + + .export _doesclrscrafterexit := return1 diff --git a/libsrc/osic1p/revers.s b/libsrc/osic1p/revers.s new file mode 100644 index 000000000..bb178f647 --- /dev/null +++ b/libsrc/osic1p/revers.s @@ -0,0 +1,9 @@ +; +; 2017-06-26, Greg King +; +; unsigned char __fastcall__ revers (unsigned char onoff) +; + + .import return0 + + .export _revers := return0 ; no attribute From d1501731e4234354c21907a7ee42011d8d7aaf99 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 28 Jun 2017 05:51:46 -0400 Subject: [PATCH 0375/2161] Added a makefile dependency for the libraries' "extra" files. Some of the files in "libsrc/*/extra/" include other library files. But, the "lib/*.o" files weren't rebuilt when those other files changed. The new dependency rules must be "bootstrapped". You must force a rebuild of all of the extra library object files (it will create the dependency files). Use these commands: rm lib/*.o make lib --- libsrc/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libsrc/Makefile b/libsrc/Makefile index f4aa03101..e106aa239 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -196,6 +196,7 @@ DEPS = $(OBJS:.o=.d) EXTRA_SRCPAT = $(SRCDIR)/extra/%.s EXTRA_OBJPAT = ../lib/$(TARGET)-%.o EXTRA_OBJS := $(patsubst $(EXTRA_SRCPAT),$(EXTRA_OBJPAT),$(wildcard $(SRCDIR)/extra/*.s)) +DEPS += $(EXTRA_OBJS:../lib/%.o=../libwrk/$(TARGET)/%.d) ZPOBJ = ../libwrk/$(TARGET)/zeropage.o ifeq ($(TARGET),$(filter $(TARGET),$(EXTZP))) @@ -281,7 +282,7 @@ endef # COMPILE_recipe $(EXTRA_OBJPAT): $(EXTRA_SRCPAT) | ../lib @echo $(TARGET) - $(<F) - @$(CA65) -t $(TARGET) $(CA65FLAGS) -o $@ $< + @$(CA65) -t $(TARGET) $(CA65FLAGS) --create-dep $(@:../lib/%.o=../libwrk/$(TARGET)/%.d) -o $@ $< ../lib/$(TARGET).lib: $(OBJS) | ../lib $(AR65) a $@ $? From b31ae57be106d7586b1af740505a863779933ecd Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Wed, 28 Jun 2017 20:43:31 +0200 Subject: [PATCH 0376/2161] Make some arrays const. --- libsrc/common/strftime.c | 4 +- libsrc/conio/cputs.s | 4 +- libsrc/dbg/dbg.c | 40 ++++++++-------- libsrc/geos-common/dlgbox/messagebox.c | 10 ++-- src/ca65/dbginfo.c | 4 +- src/ca65/feature.c | 2 +- src/ca65/pseudo.c | 10 ++-- src/ca65/scanner.c | 2 +- src/ca65/scanner.h | 2 +- src/cc65/codegen.c | 66 +++++++++++++------------- src/cc65/coptstop.c | 2 +- src/cc65/standard.c | 2 +- src/co65/model.c | 2 +- src/da65/labels.c | 4 +- src/grc65/main.c | 13 ++--- src/sp65/attr.c | 2 +- src/sp65/attr.h | 2 +- src/sp65/main.c | 6 +-- 18 files changed, 87 insertions(+), 90 deletions(-) diff --git a/libsrc/common/strftime.c b/libsrc/common/strftime.c index 25cfd0606..38ea4850e 100644 --- a/libsrc/common/strftime.c +++ b/libsrc/common/strftime.c @@ -53,11 +53,11 @@ size_t __fastcall__ strftime (char* buf, size_t bufsize, const char* format, const struct tm* tm) { - static const char* days[7] = { + static const char* const days[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; - static const char* months[12] = { + static const char* const months[12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; diff --git a/libsrc/conio/cputs.s b/libsrc/conio/cputs.s index c9ca5df76..ef7c65462 100644 --- a/libsrc/conio/cputs.s +++ b/libsrc/conio/cputs.s @@ -1,8 +1,8 @@ ; ; Ullrich von Bassewitz, 06.08.1998 ; -; void cputsxy (unsigned char x, unsigned char y, char* s); -; void cputs (char* s); +; void cputsxy (unsigned char x, unsigned char y, const char* s); +; void cputs (const char* s); ; .export _cputsxy, _cputs diff --git a/libsrc/dbg/dbg.c b/libsrc/dbg/dbg.c index 8b09484f6..60b452799 100644 --- a/libsrc/dbg/dbg.c +++ b/libsrc/dbg/dbg.c @@ -32,7 +32,7 @@ static char DumpHandler (void); static char HelpHandler (void); /* Forwards for other functions */ -static void DisplayPrompt (char* s); +static void DisplayPrompt (const char* s); static void SingleStep (char StepInto); static void RedrawStatic (char Frame); static void Redraw (char Frame); @@ -166,7 +166,7 @@ extern unsigned DbgHI; /* High 16 bit of primary reg */ typedef struct { unsigned char x; unsigned char y; - char* text; + const char* text; } TextDesc; /* Window descriptor */ @@ -181,13 +181,13 @@ typedef struct { unsigned char fd_visible; /* Is the window currently visible? */ char (*fd_func) (void); /* Handler function */ unsigned char fd_textcount; /* Number of text lines to print */ - TextDesc* fd_text; /* Static text in the window */ + const TextDesc* fd_text; /* Static text in the window */ } FrameDesc; /* Texts for the windows */ -static TextDesc RegText [] = { +static const TextDesc RegText [] = { { 1, 0, "PC" }, { 1, 1, "SR" }, { 1, 2, "A" }, @@ -197,7 +197,7 @@ static TextDesc RegText [] = { { 1, 6, "CS" }, { 1, 7, "HI" } }; -static TextDesc HelpText [] = { +static const TextDesc HelpText [] = { { 1, 0, "F1, ? Help" }, { 1, 1, "F2, t Toggle breakpoint" }, { 1, 2, "F3, u Run until subroutine returns" }, @@ -220,7 +220,7 @@ static TextDesc HelpText [] = { /* Window data */ -static FrameDesc AsmFrame = { +static const FrameDesc AsmFrame = { CH_ULCORNER, CH_TTEE, CH_LTEE, CH_CROSS, 0, 0, MAX_X - 10, 15, MAX_X - 11, 14, @@ -228,7 +228,7 @@ static FrameDesc AsmFrame = { AsmHandler, 0, 0 }; -static FrameDesc RegFrame = { +static const FrameDesc RegFrame = { CH_TTEE, CH_URCORNER, CH_LTEE, CH_RTEE, MAX_X - 10, 0, MAX_X - 1, 9, 8, 8, @@ -236,7 +236,7 @@ static FrameDesc RegFrame = { RegHandler, sizeof (RegText) / sizeof (RegText [0]), RegText }; -static FrameDesc StackFrame = { +static const FrameDesc StackFrame = { CH_LTEE, CH_RTEE, CH_CROSS, CH_RTEE, MAX_X - 10, 9, MAX_X - 1, 15, 8, 5, @@ -244,7 +244,7 @@ static FrameDesc StackFrame = { StackHandler, 0, 0 }; -static FrameDesc CStackFrame = { +static const FrameDesc CStackFrame = { CH_CROSS, CH_RTEE, CH_BTEE, CH_LRCORNER, MAX_X - 10, 15, MAX_X - 1, MAX_Y - 1, 8, MAX_Y - 17, @@ -252,7 +252,7 @@ static FrameDesc CStackFrame = { CStackHandler, 0, 0 }; -static FrameDesc DumpFrame = { +static const FrameDesc DumpFrame = { CH_LTEE, CH_CROSS, CH_LLCORNER, CH_BTEE, 0, 15, MAX_X - 10, MAX_Y-1, MAX_X - 11, MAX_Y - 17, @@ -260,7 +260,7 @@ static FrameDesc DumpFrame = { DumpHandler, 0, 0 }; -static FrameDesc HelpFrame = { +static const FrameDesc HelpFrame = { CH_ULCORNER, CH_URCORNER, CH_LLCORNER, CH_LRCORNER, 0, 0, MAX_X - 1, MAX_Y-1, MAX_X - 2, MAX_Y - 2, @@ -268,7 +268,7 @@ static FrameDesc HelpFrame = { HelpHandler, sizeof (HelpText) / sizeof (HelpText [0]), HelpText }; -static FrameDesc* Frames [] = { +static const FrameDesc* const Frames [] = { &AsmFrame, &RegFrame, &StackFrame, @@ -297,7 +297,7 @@ static unsigned char StackAddr; /* Start address of output */ /* Prompt line data */ -static char* ActivePrompt = 0; /* Last prompt line displayed */ +static const char* ActivePrompt = 0; /* Last prompt line displayed */ static char PromptColor; /* Color behind prompt */ static char PromptLength; /* Length of current prompt string */ @@ -346,10 +346,10 @@ BreakPoint* DbgIsBreak (unsigned Addr); -static void DrawFrame (register FrameDesc* F, char Active) +static void DrawFrame (register const FrameDesc* F, char Active) /* Draw one window frame */ { - TextDesc* T; + const TextDesc* T; unsigned char Count; unsigned char tl, tr, bl, br; unsigned char x1, y1, width; @@ -410,7 +410,7 @@ static void DrawFrames (void) /* Draw all frames */ { unsigned char I; - FrameDesc* F; + const FrameDesc* F; /* Build the frame layout of the screen */ for (I = 0; I < sizeof (Frames) / sizeof (Frames [0]); ++I) { @@ -427,7 +427,7 @@ static void ActivateFrame (int Num, unsigned char Clear) /* Activate a new frame, deactivate the old one */ { unsigned char y; - register FrameDesc* F; + register const FrameDesc* F; if (ActiveFrame != Num) { @@ -462,7 +462,7 @@ static void ActivateFrame (int Num, unsigned char Clear) -static void DisplayPrompt (char* s) +static void DisplayPrompt (const char* s) /* Display a prompt */ { unsigned char OldColor; @@ -626,11 +626,11 @@ static char InputHex (char* Prompt, unsigned* Val) -static void ErrorPrompt (char* Msg) +static void ErrorPrompt (const char* Msg) /* Display an error message and wait for a key */ { /* Save the current prompt */ - char* OldPrompt = ActivePrompt; + const char* OldPrompt = ActivePrompt; /* Display the new one */ DisplayPrompt (Msg); diff --git a/libsrc/geos-common/dlgbox/messagebox.c b/libsrc/geos-common/dlgbox/messagebox.c index 533267be1..fd4a5cd11 100644 --- a/libsrc/geos-common/dlgbox/messagebox.c +++ b/libsrc/geos-common/dlgbox/messagebox.c @@ -10,21 +10,21 @@ void _mbprintout(void); -static dlgBoxStr _mbdlg_EMPTY = { +static const dlgBoxStr _mbdlg_EMPTY = { DB_DEFPOS(1), DB_OPVEC(&RstrFrmDialogue), DB_USRROUT(&_mbprintout), DB_END, }; -static dlgBoxStr _mbdlg_OK = { +static const dlgBoxStr _mbdlg_OK = { DB_DEFPOS(1), DB_USRROUT(&_mbprintout), DB_ICON(OK, DBI_X_1, DBI_Y_2), DB_END, }; -static dlgBoxStr _mbdlg_OKCANCEL = { +static const dlgBoxStr _mbdlg_OKCANCEL = { DB_DEFPOS(1), DB_USRROUT(&_mbprintout), DB_ICON(OK, DBI_X_0, DBI_Y_2), @@ -32,7 +32,7 @@ static dlgBoxStr _mbdlg_OKCANCEL = { DB_END, }; -static dlgBoxStr _mbdlg_YESNO = { +static const dlgBoxStr _mbdlg_YESNO = { DB_DEFPOS(1), DB_USRROUT(&_mbprintout), DB_ICON(YES, DBI_X_0, DBI_Y_2), @@ -40,7 +40,7 @@ static dlgBoxStr _mbdlg_YESNO = { DB_END, }; -static dlgBoxStr *_mbboxes[] = { +static const dlgBoxStr * const _mbboxes[] = { &_mbdlg_EMPTY, &_mbdlg_OK, &_mbdlg_OKCANCEL, diff --git a/src/ca65/dbginfo.c b/src/ca65/dbginfo.c index 8a55f9ddc..135739fb5 100644 --- a/src/ca65/dbginfo.c +++ b/src/ca65/dbginfo.c @@ -211,7 +211,7 @@ void DbgInfoFile (void) void DbgInfoFunc (void) /* Parse and handle func subcommand of the .dbg pseudo instruction */ { - static const char* StorageKeys[] = { + static const char* const StorageKeys[] = { "EXTERN", "STATIC", }; @@ -352,7 +352,7 @@ void DbgInfoLine (void) void DbgInfoSym (void) /* Parse and handle SYM subcommand of the .dbg pseudo instruction */ { - static const char* StorageKeys[] = { + static const char* const StorageKeys[] = { "AUTO", "EXTERN", "REGISTER", diff --git a/src/ca65/feature.c b/src/ca65/feature.c index 35bdf4b98..0fb766b6f 100644 --- a/src/ca65/feature.c +++ b/src/ca65/feature.c @@ -48,7 +48,7 @@ /* Names of the features */ -static const char* FeatureKeys[FEAT_COUNT] = { +static const char* const FeatureKeys[FEAT_COUNT] = { "dollar_is_pc", "labels_without_colons", "loose_string_term", diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index f84f21d7f..5dd67af90 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -151,7 +151,7 @@ static unsigned char OptionalAddrSize (void) static void SetBoolOption (unsigned char* Flag) /* Read a on/off/+/- option and set flag accordingly */ { - static const char* Keys[] = { + static const char* const Keys[] = { "OFF", "ON", }; @@ -451,7 +451,7 @@ static void DoASCIIZ (void) static void DoAssert (void) /* Add an assertion */ { - static const char* ActionTab [] = { + static const char* const ActionTab [] = { "WARN", "WARNING", "ERROR", "LDWARN", "LDWARNING", @@ -659,7 +659,7 @@ static void DoCode (void) static void DoConDes (void) /* Export a symbol as constructor/destructor */ { - static const char* Keys[] = { + static const char* const Keys[] = { "CONSTRUCTOR", "DESTRUCTOR", "INTERRUPTOR", @@ -744,7 +744,7 @@ static void DoData (void) static void DoDbg (void) /* Add debug information from high level code */ { - static const char* Keys[] = { + static const char* const Keys[] = { "FILE", "FUNC", "LINE", @@ -1039,7 +1039,7 @@ static void DoFileOpt (void) if (CurTok.Tok == TOK_IDENT) { /* Option given as keyword */ - static const char* Keys [] = { + static const char* const Keys [] = { "AUTHOR", "COMMENT", "COMPILER" }; diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index e186b19a7..7c291666c 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -1477,7 +1477,7 @@ CharAgain: -int GetSubKey (const char** Keys, unsigned Count) +int GetSubKey (const char* const* Keys, unsigned Count) /* Search for a subkey in a table of keywords. The current token must be an ** identifier and all keys must be in upper case. The identifier will be ** uppercased in the process. The function returns the index of the keyword, diff --git a/src/ca65/scanner.h b/src/ca65/scanner.h index c445aefa6..4fd9041c1 100644 --- a/src/ca65/scanner.h +++ b/src/ca65/scanner.h @@ -84,7 +84,7 @@ void UpcaseSVal (void); void NextRawTok (void); /* Read the next raw token from the input stream */ -int GetSubKey (const char** Keys, unsigned Count); +int GetSubKey (const char* const* Keys, unsigned Count); /* Search for a subkey in a table of keywords. The current token must be an ** identifier and all keys must be in upper case. The identifier will be ** uppercased in the process. The function returns the index of the keyword, diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index bf0251813..d9074e539 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -2211,7 +2211,7 @@ void g_cmp (unsigned flags, unsigned long val) -static void oper (unsigned Flags, unsigned long Val, const char** Subs) +static void oper (unsigned Flags, unsigned long Val, const char* const* Subs) /* Encode a binary operation. subs is a pointer to four strings: ** 0 --> Operate on ints ** 1 --> Operate on unsigneds @@ -2499,7 +2499,7 @@ void g_stackcheck (void) void g_add (unsigned flags, unsigned long val) /* Primary = TOS + Primary */ { - static const char* ops[12] = { + static const char* const ops[4] = { "tosaddax", "tosaddax", "tosaddeax", "tosaddeax" }; @@ -2515,8 +2515,8 @@ void g_add (unsigned flags, unsigned long val) void g_sub (unsigned flags, unsigned long val) /* Primary = TOS - Primary */ { - static const char* ops[12] = { - "tossubax", "tossubax", "tossubeax", "tossubeax", + static const char* const ops[4] = { + "tossubax", "tossubax", "tossubeax", "tossubeax" }; if (flags & CF_CONST) { @@ -2531,8 +2531,8 @@ void g_sub (unsigned flags, unsigned long val) void g_rsub (unsigned flags, unsigned long val) /* Primary = Primary - TOS */ { - static const char* ops[12] = { - "tosrsubax", "tosrsubax", "tosrsubeax", "tosrsubeax", + static const char* const ops[4] = { + "tosrsubax", "tosrsubax", "tosrsubeax", "tosrsubeax" }; oper (flags, val, ops); } @@ -2542,8 +2542,8 @@ void g_rsub (unsigned flags, unsigned long val) void g_mul (unsigned flags, unsigned long val) /* Primary = TOS * Primary */ { - static const char* ops[12] = { - "tosmulax", "tosumulax", "tosmuleax", "tosumuleax", + static const char* const ops[4] = { + "tosmulax", "tosumulax", "tosmuleax", "tosumuleax" }; int p2; @@ -2649,8 +2649,8 @@ void g_mul (unsigned flags, unsigned long val) void g_div (unsigned flags, unsigned long val) /* Primary = TOS / Primary */ { - static const char* ops[12] = { - "tosdivax", "tosudivax", "tosdiveax", "tosudiveax", + static const char* const ops[4] = { + "tosdivax", "tosudivax", "tosdiveax", "tosudiveax" }; /* Do strength reduction if the value is constant and a power of two */ @@ -2674,8 +2674,8 @@ void g_div (unsigned flags, unsigned long val) void g_mod (unsigned flags, unsigned long val) /* Primary = TOS % Primary */ { - static const char* ops[12] = { - "tosmodax", "tosumodax", "tosmodeax", "tosumodeax", + static const char* const ops[4] = { + "tosmodax", "tosumodax", "tosmodeax", "tosumodeax" }; int p2; @@ -2699,8 +2699,8 @@ void g_mod (unsigned flags, unsigned long val) void g_or (unsigned flags, unsigned long val) /* Primary = TOS | Primary */ { - static const char* ops[12] = { - "tosorax", "tosorax", "tosoreax", "tosoreax", + static const char* const ops[4] = { + "tosorax", "tosorax", "tosoreax", "tosoreax" }; /* If the right hand side is const, the lhs is not on stack but still @@ -2769,8 +2769,8 @@ void g_or (unsigned flags, unsigned long val) void g_xor (unsigned flags, unsigned long val) /* Primary = TOS ^ Primary */ { - static const char* ops[12] = { - "tosxorax", "tosxorax", "tosxoreax", "tosxoreax", + static const char* const ops[4] = { + "tosxorax", "tosxorax", "tosxoreax", "tosxoreax" }; @@ -2837,8 +2837,8 @@ void g_xor (unsigned flags, unsigned long val) void g_and (unsigned Flags, unsigned long Val) /* Primary = TOS & Primary */ { - static const char* ops[12] = { - "tosandax", "tosandax", "tosandeax", "tosandeax", + static const char* const ops[4] = { + "tosandax", "tosandax", "tosandeax", "tosandeax" }; /* If the right hand side is const, the lhs is not on stack but still @@ -2929,8 +2929,8 @@ void g_and (unsigned Flags, unsigned long Val) void g_asr (unsigned flags, unsigned long val) /* Primary = TOS >> Primary */ { - static const char* ops[12] = { - "tosasrax", "tosshrax", "tosasreax", "tosshreax", + static const char* const ops[4] = { + "tosasrax", "tosshrax", "tosasreax", "tosshreax" }; /* If the right hand side is const, the lhs is not on stack but still @@ -3060,8 +3060,8 @@ void g_asr (unsigned flags, unsigned long val) void g_asl (unsigned flags, unsigned long val) /* Primary = TOS << Primary */ { - static const char* ops[12] = { - "tosaslax", "tosshlax", "tosasleax", "tosshleax", + static const char* const ops[4] = { + "tosaslax", "tosshlax", "tosasleax", "tosshleax" }; @@ -3438,8 +3438,8 @@ void g_dec (unsigned flags, unsigned long val) void g_eq (unsigned flags, unsigned long val) /* Test for equal */ { - static const char* ops[12] = { - "toseqax", "toseqax", "toseqeax", "toseqeax", + static const char* const ops[4] = { + "toseqax", "toseqax", "toseqeax", "toseqeax" }; unsigned L; @@ -3492,8 +3492,8 @@ void g_eq (unsigned flags, unsigned long val) void g_ne (unsigned flags, unsigned long val) /* Test for not equal */ { - static const char* ops[12] = { - "tosneax", "tosneax", "tosneeax", "tosneeax", + static const char* const ops[4] = { + "tosneax", "tosneax", "tosneeax", "tosneeax" }; unsigned L; @@ -3546,7 +3546,7 @@ void g_ne (unsigned flags, unsigned long val) void g_lt (unsigned flags, unsigned long val) /* Test for less than */ { - static const char* ops[12] = { + static const char* const ops[4] = { "tosltax", "tosultax", "toslteax", "tosulteax", }; @@ -3708,8 +3708,8 @@ void g_lt (unsigned flags, unsigned long val) void g_le (unsigned flags, unsigned long val) /* Test for less than or equal to */ { - static const char* ops[12] = { - "tosleax", "tosuleax", "tosleeax", "tosuleeax", + static const char* const ops[4] = { + "tosleax", "tosuleax", "tosleeax", "tosuleeax" }; @@ -3823,8 +3823,8 @@ void g_le (unsigned flags, unsigned long val) void g_gt (unsigned flags, unsigned long val) /* Test for greater than */ { - static const char* ops[12] = { - "tosgtax", "tosugtax", "tosgteax", "tosugteax", + static const char* const ops[4] = { + "tosgtax", "tosugtax", "tosgteax", "tosugteax" }; @@ -3954,8 +3954,8 @@ void g_gt (unsigned flags, unsigned long val) void g_ge (unsigned flags, unsigned long val) /* Test for greater than or equal to */ { - static const char* ops[12] = { - "tosgeax", "tosugeax", "tosgeeax", "tosugeeax", + static const char* const ops[4] = { + "tosgeax", "tosugeax", "tosgeeax", "tosugeeax" }; unsigned Label; diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index cf6392bd3..41d928750 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -1711,7 +1711,7 @@ static int HarmlessCall (const char* Name) ** the pushax/op sequence when encountered. */ { - static const char* Tab[] = { + static const char* const Tab[] = { "aslax1", "aslax2", "aslax3", diff --git a/src/cc65/standard.c b/src/cc65/standard.c index 36897a059..f26b63c20 100644 --- a/src/cc65/standard.c +++ b/src/cc65/standard.c @@ -50,7 +50,7 @@ IntStack Standard = INTSTACK(STD_UNKNOWN); /* Table mapping names to standards, sorted by standard. */ -static const char* StdNames[STD_COUNT] = { +static const char* const StdNames[STD_COUNT] = { "c89", "c99", "cc65" }; diff --git a/src/co65/model.c b/src/co65/model.c index 87a6966b7..bb815cd15 100644 --- a/src/co65/model.c +++ b/src/co65/model.c @@ -52,7 +52,7 @@ O65Model Model = O65_MODEL_NONE; /* Name table */ -static const char* NameTable[O65_MODEL_COUNT] = { +static const char* const NameTable[O65_MODEL_COUNT] = { "none", "os/a65", "lunix", diff --git a/src/da65/labels.c b/src/da65/labels.c index 547a79869..6aa7f38cf 100644 --- a/src/da65/labels.c +++ b/src/da65/labels.c @@ -264,11 +264,11 @@ const char* GetLabel (unsigned Addr, unsigned RefFrom) ** of unnamed labels, to determine the name. */ { - static const char* FwdLabels[] = { + static const char* const FwdLabels[] = { ":+", ":++", ":+++", ":++++", ":+++++", ":++++++", ":+++++++", ":++++++++", ":+++++++++", ":++++++++++" }; - static const char* BackLabels[] = { + static const char* const BackLabels[] = { ":-", ":--", ":---", ":----", ":-----", ":------", ":-------", ":--------", ":---------", ":----------" }; diff --git a/src/grc65/main.c b/src/grc65/main.c index 2a1fef953..d36f039e6 100644 --- a/src/grc65/main.c +++ b/src/grc65/main.c @@ -226,18 +226,15 @@ static void openSFile (void) } -static int findToken (const char **tokenTbl, const char *token) +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 a = 0; - - while (strlen (tokenTbl[a]) != 0) { - if (strcmp (tokenTbl[a], token) == 0) break; - a++; + int i; + for (i = 0; tokenTbl[i][0]; i++) { + if (strcmp (tokenTbl[i], token) == 0) return i; } - if (strlen (tokenTbl[a]) == 0) a = -1; - return a; + return -1; } diff --git a/src/sp65/attr.c b/src/sp65/attr.c index db026af48..e57b86973 100644 --- a/src/sp65/attr.c +++ b/src/sp65/attr.c @@ -240,7 +240,7 @@ void SplitAddAttr (Collection* C, const char* Combined, const char* Name) -Collection* ParseAttrList (const char* List, const char** NameList, unsigned NameCount) +Collection* ParseAttrList (const char* List, const char* const* NameList, unsigned NameCount) /* Parse a list containing name/value pairs into a sorted collection. Some ** attributes may not need a name, so NameList contains these names. If there ** were no errors, the function returns a alphabetically sorted collection diff --git a/src/sp65/attr.h b/src/sp65/attr.h index 2b7ce68b9..e93bcd937 100644 --- a/src/sp65/attr.h +++ b/src/sp65/attr.h @@ -111,7 +111,7 @@ void SplitAddAttr (Collection* C, const char* Combined, const char* Name); ** Name is NULL, terminate with an error. */ -Collection* ParseAttrList (const char* List, const char** NameList, unsigned NameCount); +Collection* ParseAttrList (const char* List, const char* const* NameList, unsigned NameCount); /* Parse a list containing name/value pairs into a sorted collection. Some ** attributes may not need a name, so NameList contains these names. If there ** were no errors, the function returns a alphabetically sorted collection diff --git a/src/sp65/main.c b/src/sp65/main.c index 828a48fc8..5c9724a8a 100644 --- a/src/sp65/main.c +++ b/src/sp65/main.c @@ -141,7 +141,7 @@ static void SetOutputData (StrBuf* N) static void OptConvertTo (const char* Opt attribute ((unused)), const char* Arg) /* Convert the bitmap into a target format */ { - static const char* NameList[] = { + static const char* const NameList[] = { "format" }; @@ -220,7 +220,7 @@ static void OptPop (const char* Opt attribute ((unused)), static void OptRead (const char* Opt attribute ((unused)), const char* Arg) /* Read an input file */ { - static const char* NameList[] = { + static const char* const NameList[] = { "name", "format" }; @@ -294,7 +294,7 @@ static void OptVersion (const char* Opt attribute ((unused)), static void OptWrite (const char* Opt attribute ((unused)), const char* Arg) /* Write an output file */ { - static const char* NameList[] = { + static const char* const NameList[] = { "name", "format" }; From 141c25b42b4df1c32ceb36e2661cddb48ac9c0e0 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 29 Jun 2017 13:34:10 -0400 Subject: [PATCH 0377/2161] Added the extra dependency file's directory as an order-only prerequisite. The extra dependency files are put into different places than the extra object files' location. Therefore, the rule must pre-make two directories. --- libsrc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/Makefile b/libsrc/Makefile index e106aa239..89d4b7752 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -280,7 +280,7 @@ endef # COMPILE_recipe ../libwrk/$(TARGET)/%.o: %.c | ../libwrk/$(TARGET) $(COMPILE_recipe) -$(EXTRA_OBJPAT): $(EXTRA_SRCPAT) | ../lib +$(EXTRA_OBJPAT): $(EXTRA_SRCPAT) | ../libwrk/$(TARGET) ../lib @echo $(TARGET) - $(<F) @$(CA65) -t $(TARGET) $(CA65FLAGS) --create-dep $(@:../lib/%.o=../libwrk/$(TARGET)/%.d) -o $@ $< From c0812670c11411ed99404cc3f936a2cd9259bc14 Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Fri, 30 Jun 2017 07:35:21 +0200 Subject: [PATCH 0378/2161] Fix coding style. --- src/cc65/codegen.c | 2 +- src/grc65/main.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index d9074e539..dfc06fccc 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -3547,7 +3547,7 @@ void g_lt (unsigned flags, unsigned long val) /* Test for less than */ { static const char* const ops[4] = { - "tosltax", "tosultax", "toslteax", "tosulteax", + "tosltax", "tosultax", "toslteax", "tosulteax" }; unsigned Label; diff --git a/src/grc65/main.c b/src/grc65/main.c index d36f039e6..a53801a39 100644 --- a/src/grc65/main.c +++ b/src/grc65/main.c @@ -230,8 +230,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 (strcmp (tokenTbl[i], token) == 0) { + return i; + } } return -1; From 6de78c536f78bc47129a7d4da4ad10f7e3a27b8f Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 30 Jun 2017 09:50:28 +0200 Subject: [PATCH 0379/2161] Made DOS 3.3 IRQ statement more general. I recently came across that the question if a driver is compatible with DOS 3.3 isn't about the fact if it actually uses IRQs but if it potentially could use IRQs as the driver kernel pulls in the IRQ handler anyway. This is especially suboptimal in the scenario of statically linked drivers where it is concpetually totally clear at link time they use IRQs or not. Apart from that it might make sense to be able to define on a per-target basis if _any_ of the drivers of a certain class uses IRQs. If that isn't the cases the driver kernel for that driver class for that target could omit IRQ handling too. I'm aware that Uz imagined drivers being loaded which weren't known when the program was linked - but I don't see this. --- doc/apple2.sgml | 2 +- doc/apple2enh.sgml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index d0405b6de..3089a04c4 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -435,7 +435,7 @@ BASIC.SYSTEM) there are some limitations for DOS 3.3: <tag/Interrupts/ There's no <tt/interruptor/ support. Any attempt to use it yields the message 'FAILED TO ALLOC INTERRUPT' on program startup. This implicitly means that - <tt/a2.stdmou.mou/ and <tt/a2.ssc.ser/ are not functional as they depend on + joystick, mouse and RS232 device drivers are not functional as they depend on interrupts. </descrip><p> diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index b5231b4cd..5e4626fbc 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -436,7 +436,7 @@ BASIC.SYSTEM) there are some limitations for DOS 3.3: <tag/Interrupts/ There's no <tt/interruptor/ support. Any attempt to use it yields the message 'Failed to alloc interrupt' on program startup. This implicitly means that - <tt/a2e.stdmou.mou/ and <tt/a2e.ssc.ser/ are not functional as they depend on + joystick, mouse and RS232 device drivers are not functional as they depend on interrupts. </descrip><p> From ea7f4d748942ad0fd34f68502531db6c0b15aca5 Mon Sep 17 00:00:00 2001 From: Pascal de Bruijn <pmjdebruijn@pcode.nl> Date: Mon, 17 Jul 2017 19:43:11 +0200 Subject: [PATCH 0380/2161] pragma: bring pragma_t enum in line with Pragmas struct fixes an inconsequential inconsistency, might prevent some confusion in the future. --- src/cc65/pragma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index de1979c12..d50d151a7 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -79,8 +79,8 @@ typedef enum { PRAGMA_INLINE_STDFUNCS, PRAGMA_LOCAL_STRINGS, PRAGMA_OPTIMIZE, - PRAGMA_REGVARADDR, PRAGMA_REGISTER_VARS, + PRAGMA_REGVARADDR, PRAGMA_REGVARS, /* obsolete */ PRAGMA_RODATA_NAME, PRAGMA_RODATASEG, /* obsolete */ From 1abce3a2a1d7df81a580e9120a34e1d697085b3e Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 17 Jul 2017 23:15:05 +0200 Subject: [PATCH 0381/2161] rename all waitvblank() to waitvsync() --- doc/funcref.sgml | 2 +- doc/nes.sgml | 4 ++-- doc/pce.sgml | 2 +- doc/supervision.sgml | 2 +- include/gamate.h | 4 ++-- include/nes.h | 4 ++-- include/pce.h | 4 ++-- libsrc/c128/{waitvblank.s => waitvsync.s} | 4 ++-- libsrc/c64/{waitvblank.s => waitvsync.s} | 4 ++-- libsrc/cbm510/{waitvblank.s => waitvsync.s} | 4 ++-- libsrc/gamate/{waitvblank.s => waitvsync.s} | 6 +++--- libsrc/nes/{waitvblank.s => waitvsync.s} | 6 +++--- libsrc/pce/{waitvblank.s => waitvsync.s} | 6 +++--- libsrc/vic20/{waitvblank.s => waitvsync.s} | 4 ++-- testcode/lib/conio.c | 4 ++-- testcode/lib/gamate/ctest.c | 2 +- testcode/lib/pce/conio.c | 2 +- 17 files changed, 32 insertions(+), 32 deletions(-) rename libsrc/c128/{waitvblank.s => waitvsync.s} (87%) rename libsrc/c64/{waitvblank.s => waitvsync.s} (75%) rename libsrc/cbm510/{waitvblank.s => waitvsync.s} (88%) rename libsrc/gamate/{waitvblank.s => waitvsync.s} (74%) rename libsrc/nes/{waitvblank.s => waitvsync.s} (73%) rename libsrc/pce/{waitvblank.s => waitvsync.s} (71%) rename libsrc/vic20/{waitvblank.s => waitvsync.s} (88%) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index a2ccf6c73..b5295a63b 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -415,7 +415,7 @@ function. <!-- <itemize> --> <!-- <item><ref id="get_tv" name="get_tv"> --> -<!-- <item><ref id="waitvblank" name="waitvblank"> --> +<!-- <item><ref id="waitvsync" name="waitvsync"> --> <!-- </itemize> --> (incomplete) diff --git a/doc/nes.sgml b/doc/nes.sgml index 98c25b6af..31d1aa396 100644 --- a/doc/nes.sgml +++ b/doc/nes.sgml @@ -1,4 +1,4 @@ -<!doctype linuxdoc system> +<!-- <!doctype linuxdoc system> //--> <article> @@ -69,7 +69,7 @@ Programs containing NES specific code may use the <tt/nes.h/ header file. <sect1>NES specific functions<p> <itemize> -<item>waitvblank - wait until the start of vblank +<item>waitvsync - wait until the start of the next frame <item>get_tv </itemize> diff --git a/doc/pce.sgml b/doc/pce.sgml index ba59c31a7..124cb329e 100644 --- a/doc/pce.sgml +++ b/doc/pce.sgml @@ -77,7 +77,7 @@ Programs containing PCE specific code may use the <tt/pce.h/ header file. <sect1>PCE specific functions<p> <itemize> -<item>waitvblank</item> +<item>waitvsync</item> <item>get_tv (since all PCE systems are NTSC, this always returns TV_NTSC)</item> </itemize> diff --git a/doc/supervision.sgml b/doc/supervision.sgml index 97495dea5..2466aa480 100644 --- a/doc/supervision.sgml +++ b/doc/supervision.sgml @@ -66,7 +66,7 @@ Programs containing Supervision specific code may use the <tt/supervision.h/ hea <sect1>Supervision specific functions<p> <itemize> -<item>waitvblank +<item>waitvsync </itemize> diff --git a/include/gamate.h b/include/gamate.h index 82bca08b1..96c70c9bc 100644 --- a/include/gamate.h +++ b/include/gamate.h @@ -188,8 +188,8 @@ extern void gamate_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ #define JOY_START 6 #define JOY_SELECT 7 -void waitvblank (void); -/* Wait for the vertical blanking */ +void waitvsync (void); +/* Wait for start of next frame */ /* NOTE: all Gamate are "NTSC" */ #define get_tv() TV_NTSC diff --git a/include/nes.h b/include/nes.h index a472a0f3c..95e2fe93b 100644 --- a/include/nes.h +++ b/include/nes.h @@ -163,8 +163,8 @@ extern void nes_64_56_2_tgi[]; /* Referred to by tgi_static_stddrv[] */ -void waitvblank (void); -/* Wait for the vertical blanking */ +void waitvsync (void); +/* Wait for start of the next frame */ unsigned char get_tv (void); /* Return the video mode the machine is using. */ diff --git a/include/pce.h b/include/pce.h index 7700654c8..856a2fa1d 100644 --- a/include/pce.h +++ b/include/pce.h @@ -83,8 +83,8 @@ extern void pce_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ #define JOY_SELECT 6 #define JOY_RUN 7 -void waitvblank (void); -/* Wait for the vertical blanking */ +void waitvsync (void); +/* Wait for start of the next frame */ /* NOTE: all PCE are NTSC */ #define get_tv() TV_NTSC diff --git a/libsrc/c128/waitvblank.s b/libsrc/c128/waitvsync.s similarity index 87% rename from libsrc/c128/waitvblank.s rename to libsrc/c128/waitvsync.s index c144e11c2..1597e5fa0 100644 --- a/libsrc/c128/waitvblank.s +++ b/libsrc/c128/waitvsync.s @@ -1,9 +1,9 @@ - .export _waitvblank + .export _waitvsync .include "c128.inc" -_waitvblank: +_waitvsync: bit MODE bmi @c80 diff --git a/libsrc/c64/waitvblank.s b/libsrc/c64/waitvsync.s similarity index 75% rename from libsrc/c64/waitvblank.s rename to libsrc/c64/waitvsync.s index dd9087841..15ef61bb7 100644 --- a/libsrc/c64/waitvblank.s +++ b/libsrc/c64/waitvsync.s @@ -1,9 +1,9 @@ - .export _waitvblank + .export _waitvsync .include "c64.inc" -_waitvblank: +_waitvsync: @l1: bit VIC_CTRL1 bpl @l1 diff --git a/libsrc/cbm510/waitvblank.s b/libsrc/cbm510/waitvsync.s similarity index 88% rename from libsrc/cbm510/waitvblank.s rename to libsrc/cbm510/waitvsync.s index 975861f2c..bd631e4d6 100644 --- a/libsrc/cbm510/waitvblank.s +++ b/libsrc/cbm510/waitvsync.s @@ -1,5 +1,5 @@ - .export _waitvblank + .export _waitvsync .import PALFLAG .import sys_bank, restore_bank @@ -7,7 +7,7 @@ .include "cbm510.inc" -_waitvblank: +_waitvsync: rts ; FIXME jsr sys_bank ; Switch to the system bank diff --git a/libsrc/gamate/waitvblank.s b/libsrc/gamate/waitvsync.s similarity index 74% rename from libsrc/gamate/waitvblank.s rename to libsrc/gamate/waitvsync.s index 66686c08a..9b1199055 100644 --- a/libsrc/gamate/waitvblank.s +++ b/libsrc/gamate/waitvsync.s @@ -1,16 +1,16 @@ ; -; void waitvblank (void); +; void waitvsync (void); ; .include "gamate.inc" .include "extzp.inc" .forceimport ticktock - .export _waitvblank + .export _waitvsync ; FIXME: is this actually correct? -.proc _waitvblank +.proc _waitvsync lda tickcount @lp: cmp tickcount diff --git a/libsrc/nes/waitvblank.s b/libsrc/nes/waitvsync.s similarity index 73% rename from libsrc/nes/waitvblank.s rename to libsrc/nes/waitvsync.s index 408646904..11a231ac4 100644 --- a/libsrc/nes/waitvblank.s +++ b/libsrc/nes/waitvsync.s @@ -2,14 +2,14 @@ ; Written by Groepaz/Hitmen <groepaz@gmx.net> ; Cleanup by Ullrich von Bassewitz <uz@cc65.org> ; -; void waitvblank(void); +; void waitvsync(void); ; - .export _waitvblank + .export _waitvsync .include "nes.inc" -.proc _waitvblank +.proc _waitvsync wait: lda PPU_STATUS bpl wait diff --git a/libsrc/pce/waitvblank.s b/libsrc/pce/waitvsync.s similarity index 71% rename from libsrc/pce/waitvblank.s rename to libsrc/pce/waitvsync.s index b9f0f902f..f1eab36f8 100644 --- a/libsrc/pce/waitvblank.s +++ b/libsrc/pce/waitvsync.s @@ -1,14 +1,14 @@ ; -; void waitvblank (void); +; void waitvsync (void); ; .include "pce.inc" .include "extzp.inc" .forceimport ticktock - .export _waitvblank + .export _waitvsync -.proc _waitvblank +.proc _waitvsync lda tickcount @lp: cmp tickcount diff --git a/libsrc/vic20/waitvblank.s b/libsrc/vic20/waitvsync.s similarity index 88% rename from libsrc/vic20/waitvblank.s rename to libsrc/vic20/waitvsync.s index 246c44640..9f0d50565 100644 --- a/libsrc/vic20/waitvblank.s +++ b/libsrc/vic20/waitvsync.s @@ -1,4 +1,4 @@ - .export _waitvblank + .export _waitvsync .include "vic20.inc" @@ -7,7 +7,7 @@ ; it will have to be filled by a get_tv() constructor or so PALFLAG = $2A6 ; $01 = PAL, $00 = NTSC -_waitvblank: +_waitvsync: lda PALFLAG beq @ntsc ldx #(312-8)/2 diff --git a/testcode/lib/conio.c b/testcode/lib/conio.c index fe977ec08..13188d1cd 100644 --- a/testcode/lib/conio.c +++ b/testcode/lib/conio.c @@ -117,8 +117,8 @@ void main(void) gotoxy(7 + inpos,1); #if defined(__NES__) || defined(__PCE__) || defined(__GAMATE__) - /* not all targets have waitvblank */ - waitvblank(); + /* not all targets have waitvsync */ + waitvsync(); /* for targets that do not have a keyboard, read the first joystick */ joy = joy_read(JOY_1); diff --git a/testcode/lib/gamate/ctest.c b/testcode/lib/gamate/ctest.c index dfebd9bef..793770cee 100644 --- a/testcode/lib/gamate/ctest.c +++ b/testcode/lib/gamate/ctest.c @@ -41,7 +41,7 @@ int main(int argc, char *argv[]) break; } - waitvblank(); + waitvsync(); (*((unsigned char*)LCD_XPOS)) = x; (*((unsigned char*)LCD_YPOS)) = y; diff --git a/testcode/lib/pce/conio.c b/testcode/lib/pce/conio.c index a4bd63b15..00ae3c157 100644 --- a/testcode/lib/pce/conio.c +++ b/testcode/lib/pce/conio.c @@ -123,7 +123,7 @@ void main(void) p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]); } - waitvblank(); + waitvsync(); ++n; } } From d965601a5e56a04c14ba6ba7abd6f56a459a7238 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 17 Jul 2017 23:31:01 +0200 Subject: [PATCH 0382/2161] fix sgml --- doc/nes.sgml | 4 ++-- doc/supervision.sgml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/nes.sgml b/doc/nes.sgml index 31d1aa396..e806d753f 100644 --- a/doc/nes.sgml +++ b/doc/nes.sgml @@ -69,8 +69,8 @@ Programs containing NES specific code may use the <tt/nes.h/ header file. <sect1>NES specific functions<p> <itemize> -<item>waitvsync - wait until the start of the next frame -<item>get_tv +<item>waitvsync - wait until the start of the next frame</item> +<item>get_tv</item> </itemize> diff --git a/doc/supervision.sgml b/doc/supervision.sgml index 2466aa480..cf2af7967 100644 --- a/doc/supervision.sgml +++ b/doc/supervision.sgml @@ -66,7 +66,7 @@ Programs containing Supervision specific code may use the <tt/supervision.h/ hea <sect1>Supervision specific functions<p> <itemize> -<item>waitvsync +<item>waitvsync</item> </itemize> From 33791c6efdae474ac2ee9fc35e4dfc942e2a6bd5 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 17 Jul 2017 23:43:08 +0200 Subject: [PATCH 0383/2161] added prototype to cbm.h --- include/cbm.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/cbm.h b/include/cbm.h index 701924d57..4bbd278e3 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -153,7 +153,10 @@ struct cbm_dirent { unsigned char get_tv (void); /* Return the video mode the machine is using. */ - +#if !defined(__PLUS4__) && !defined(__C16__) && !defined(__CBM610__) && !defined(__PET__) +void waitvsync (void); +/* wait for the start of the next frame */ +#endif /*****************************************************************************/ /* CBM kernal functions */ From fe850fece8d6352f695586e9c34830ae94f52ae3 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 17 Jul 2017 23:55:18 +0200 Subject: [PATCH 0384/2161] implement waitvsync for plus4/c16 --- include/cbm.h | 2 +- libsrc/plus4/waitvsync.s | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 libsrc/plus4/waitvsync.s diff --git a/include/cbm.h b/include/cbm.h index 4bbd278e3..f35f83828 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -153,7 +153,7 @@ struct cbm_dirent { unsigned char get_tv (void); /* Return the video mode the machine is using. */ -#if !defined(__PLUS4__) && !defined(__C16__) && !defined(__CBM610__) && !defined(__PET__) +#if !defined(__CBM610__) && !defined(__PET__) void waitvsync (void); /* wait for the start of the next frame */ #endif diff --git a/libsrc/plus4/waitvsync.s b/libsrc/plus4/waitvsync.s new file mode 100644 index 000000000..84654d996 --- /dev/null +++ b/libsrc/plus4/waitvsync.s @@ -0,0 +1,12 @@ + + .export _waitvsync + + .include "plus4.inc" + +_waitvsync: +@l1: + lda TED_VLINEHI + and #$01 + ora TED_VLINELO + bne @l1 + rts From cbdad764f0eff850d37bf0a0520a33c69c840c66 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 18 Jul 2017 00:01:15 +0200 Subject: [PATCH 0385/2161] oops --- doc/nes.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/nes.sgml b/doc/nes.sgml index e806d753f..8f4374e05 100644 --- a/doc/nes.sgml +++ b/doc/nes.sgml @@ -1,4 +1,4 @@ -<!-- <!doctype linuxdoc system> //--> +<!doctype linuxdoc system> <article> From c24080f28931976f8919fd1d2d65e931d0d91fa0 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 18 Jul 2017 00:41:54 +0200 Subject: [PATCH 0386/2161] do banking --- libsrc/cbm510/waitvsync.s | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libsrc/cbm510/waitvsync.s b/libsrc/cbm510/waitvsync.s index bd631e4d6..db6c16179 100644 --- a/libsrc/cbm510/waitvsync.s +++ b/libsrc/cbm510/waitvsync.s @@ -8,10 +8,7 @@ .include "cbm510.inc" _waitvsync: - rts ; FIXME - - jsr sys_bank ; Switch to the system bank - + jsr sys_bank ; Switch to the system bank sei ldy #VIC_CTRL1 From 8eee51913a43e1f5614033e745e6f3c1bf11000a Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 18 Jul 2017 01:04:53 +0200 Subject: [PATCH 0387/2161] add headers/fix formatting --- libsrc/c128/waitvsync.s | 5 +++++ libsrc/c64/waitvsync.s | 5 +++++ libsrc/cbm510/waitvsync.s | 19 ++++++++++++------- libsrc/gamate/waitvsync.s | 2 ++ libsrc/nes/waitvsync.s | 2 +- libsrc/pce/waitvsync.s | 2 ++ libsrc/plus4/waitvsync.s | 5 +++++ libsrc/vic20/waitvsync.s | 6 ++++++ 8 files changed, 38 insertions(+), 8 deletions(-) diff --git a/libsrc/c128/waitvsync.s b/libsrc/c128/waitvsync.s index 1597e5fa0..e4bbbf7c9 100644 --- a/libsrc/c128/waitvsync.s +++ b/libsrc/c128/waitvsync.s @@ -1,3 +1,8 @@ +; +; Written by Groepaz <groepaz@gmx.net> +; +; void waitvsync (void); +; .export _waitvsync diff --git a/libsrc/c64/waitvsync.s b/libsrc/c64/waitvsync.s index 15ef61bb7..a4bf13080 100644 --- a/libsrc/c64/waitvsync.s +++ b/libsrc/c64/waitvsync.s @@ -1,3 +1,8 @@ +; +; Written by Groepaz <groepaz@gmx.net> +; +; void waitvsync (void); +; .export _waitvsync diff --git a/libsrc/cbm510/waitvsync.s b/libsrc/cbm510/waitvsync.s index db6c16179..ed7300f7c 100644 --- a/libsrc/cbm510/waitvsync.s +++ b/libsrc/cbm510/waitvsync.s @@ -1,3 +1,8 @@ +; +; Written by Groepaz <groepaz@gmx.net> +; +; void waitvsync (void); +; .export _waitvsync .import PALFLAG @@ -8,16 +13,16 @@ .include "cbm510.inc" _waitvsync: - jsr sys_bank ; Switch to the system bank + jsr sys_bank ; Switch to the system bank sei - ldy #VIC_CTRL1 + ldy #VIC_CTRL1 @l1: - lda (vic),y - bpl @l1 + lda (vic),y + bpl @l1 @l2: - lda (vic),y - bmi @l2 + lda (vic),y + bmi @l2 cli - jmp restore_bank + jmp restore_bank diff --git a/libsrc/gamate/waitvsync.s b/libsrc/gamate/waitvsync.s index 9b1199055..dee83400d 100644 --- a/libsrc/gamate/waitvsync.s +++ b/libsrc/gamate/waitvsync.s @@ -1,4 +1,6 @@ ; +; Written by Groepaz <groepaz@gmx.net> +; ; void waitvsync (void); ; diff --git a/libsrc/nes/waitvsync.s b/libsrc/nes/waitvsync.s index 11a231ac4..4bdf9a9d0 100644 --- a/libsrc/nes/waitvsync.s +++ b/libsrc/nes/waitvsync.s @@ -1,5 +1,5 @@ ; -; Written by Groepaz/Hitmen <groepaz@gmx.net> +; Written by Groepaz <groepaz@gmx.net> ; Cleanup by Ullrich von Bassewitz <uz@cc65.org> ; ; void waitvsync(void); diff --git a/libsrc/pce/waitvsync.s b/libsrc/pce/waitvsync.s index f1eab36f8..c6435dabd 100644 --- a/libsrc/pce/waitvsync.s +++ b/libsrc/pce/waitvsync.s @@ -1,4 +1,6 @@ ; +; Written by Groepaz <groepaz@gmx.net> +; ; void waitvsync (void); ; diff --git a/libsrc/plus4/waitvsync.s b/libsrc/plus4/waitvsync.s index 84654d996..32b81b52b 100644 --- a/libsrc/plus4/waitvsync.s +++ b/libsrc/plus4/waitvsync.s @@ -1,3 +1,8 @@ +; +; Written by Groepaz <groepaz@gmx.net> +; +; void waitvsync (void); +; .export _waitvsync diff --git a/libsrc/vic20/waitvsync.s b/libsrc/vic20/waitvsync.s index 9f0d50565..b5861ada3 100644 --- a/libsrc/vic20/waitvsync.s +++ b/libsrc/vic20/waitvsync.s @@ -1,3 +1,9 @@ +; +; Written by Groepaz <groepaz@gmx.net> +; +; void waitvsync (void); +; + .export _waitvsync .include "vic20.inc" From b6d3d32e88468eff8c10939efb8653833702512d Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 18 Jul 2017 01:06:20 +0200 Subject: [PATCH 0388/2161] wait for line 0 instead of last line --- libsrc/vic20/waitvsync.s | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/libsrc/vic20/waitvsync.s b/libsrc/vic20/waitvsync.s index b5861ada3..1c76f2497 100644 --- a/libsrc/vic20/waitvsync.s +++ b/libsrc/vic20/waitvsync.s @@ -8,20 +8,9 @@ .include "vic20.inc" -; FIXME -; this flag doesnt work on vic20!!! -; it will have to be filled by a get_tv() constructor or so -PALFLAG = $2A6 ; $01 = PAL, $00 = NTSC - _waitvsync: - lda PALFLAG - beq @ntsc - ldx #(312-8)/2 - .byte $2c -@ntsc: - ldx #(262-8)/2 @l2: - cpx VIC_HLINE - bcs @l2 + lda VIC_HLINE + bne @l2 rts From 6e93c1ba7332c55eb2067d7be6d20050912ef27d Mon Sep 17 00:00:00 2001 From: Pascal de Bruijn <pmjdebruijn@pcode.nl> Date: Tue, 18 Jul 2017 18:12:19 +0200 Subject: [PATCH 0389/2161] pragma: add minimalist message pragma implementation for example: #pragma message ("in a bottle") results in: hello.c(207): Note: in a bottle --- src/cc65/pragma.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index d50d151a7..25bc29d43 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -78,6 +78,7 @@ typedef enum { PRAGMA_DATASEG, /* obsolete */ PRAGMA_INLINE_STDFUNCS, PRAGMA_LOCAL_STRINGS, + PRAGMA_MESSAGE, PRAGMA_OPTIMIZE, PRAGMA_REGISTER_VARS, PRAGMA_REGVARADDR, @@ -114,6 +115,7 @@ static const struct Pragma { { "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 }, @@ -750,6 +752,13 @@ static void IntPragma (StrBuf* B, IntStack* Stack, long Low, long High) +static void MakeMessage (const char* Message) +{ + fprintf (stderr, "%s(%u): Note: %s\n", GetInputName (CurTok.LI), GetInputLine (CurTok.LI), Message); +} + + + static void ParsePragma (void) /* Parse the contents of the _Pragma statement */ { @@ -849,6 +858,10 @@ static void ParsePragma (void) FlagPragma (&B, &LocalStrings); break; + case PRAGMA_MESSAGE: + StringPragma (&B, MakeMessage); + break; + case PRAGMA_OPTIMIZE: FlagPragma (&B, &Optimize); break; From 2d9922a46e6112ed901dc675d37a6bfc4f928c4d Mon Sep 17 00:00:00 2001 From: Pascal de Bruijn <pmjdebruijn@pcode.nl> Date: Wed, 19 Jul 2017 18:02:13 +0200 Subject: [PATCH 0390/2161] nes: remove semiredundant KEY_ defines There are already JOY_ defines for most of these, and this should be expanded upon instead. --- include/nes.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/include/nes.h b/include/nes.h index 95e2fe93b..2687e2626 100644 --- a/include/nes.h +++ b/include/nes.h @@ -90,16 +90,6 @@ /* No support for dynamically loadable drivers */ #define DYN_DRV 0 -/* The joystick keys - all keys are supported */ -#define KEY_A 0x01 -#define KEY_B 0x02 -#define KEY_SELECT 0x04 -#define KEY_START 0x08 -#define KEY_UP 0x10 -#define KEY_DOWN 0x20 -#define KEY_LEFT 0x40 -#define KEY_RIGHT 0x80 - /* Define hardware */ /* Picture Processing Unit */ From d277055b5a06ee314fd3c93a562fd494cefbd767 Mon Sep 17 00:00:00 2001 From: Pascal de Bruijn <pmjdebruijn@pcode.nl> Date: Wed, 19 Jul 2017 18:14:44 +0200 Subject: [PATCH 0391/2161] nes: add system specific joy_masks array indices and macros --- include/nes.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/nes.h b/include/nes.h index 2687e2626..3e139e00c 100644 --- a/include/nes.h +++ b/include/nes.h @@ -90,6 +90,17 @@ /* No support for dynamically loadable drivers */ #define DYN_DRV 0 +/* Expanding upon joystick.h */ +#define JOY_A 4 +#define JOY_B 5 +#define JOY_SELECT 6 +#define JOY_START 7 + +#define JOY_BTN_A(v) ((v) & joy_masks[JOY_A]) +#define JOY_BTN_B(v) ((v) & joy_masks[JOY_B]) +#define JOY_BTN_SELECT(v) ((v) & joy_masks[JOY_SELECT]) +#define JOY_BTN_START(v) ((v) & joy_masks[JOY_START]) + /* Define hardware */ /* Picture Processing Unit */ From 8ad72fc9ca78b8018ec1ef223eb1911bbd8965d5 Mon Sep 17 00:00:00 2001 From: Pascal de Bruijn <pmjdebruijn@pcode.nl> Date: Wed, 19 Jul 2017 18:29:35 +0200 Subject: [PATCH 0392/2161] pce: add system specific joy_masks array indices and macros --- include/pce.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/pce.h b/include/pce.h index 856a2fa1d..ac6b2503f 100644 --- a/include/pce.h +++ b/include/pce.h @@ -76,6 +76,17 @@ /* No support for dynamically loadable drivers */ #define DYN_DRV 0 +/* Expanding upon joystick.h */ +#define JOY_I 4 +#define JOY_II 5 +#define JOY_SELECT 6 +#define JOY_RUN 7 + +#define JOY_BTN_I(v) ((v) & joy_masks[JOY_I]) +#define JOY_BTN_II(v) ((v) & joy_masks[JOY_II]) +#define JOY_BTN_SELECT(v) ((v) & joy_masks[JOY_SELECT]) +#define JOY_BTN_RUN(v) ((v) & joy_masks[JOY_RUN]) + /* The addresses of the static drivers */ extern void pce_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ From 80b27bde5e4eff1ed11dc6c84e3fbe99ae34f038 Mon Sep 17 00:00:00 2001 From: Pascal de Bruijn <pmjdebruijn@pcode.nl> Date: Thu, 20 Jul 2017 18:13:39 +0200 Subject: [PATCH 0393/2161] pragma: add minimalist message pragma documentation documents 6e93c1ba7332c55eb2067d7be6d20050912ef27d --- doc/cc65.sgml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 3689c0b35..cd94f50ac 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1119,6 +1119,23 @@ parameter with the <tt/#pragma/. remembered and output as a whole when translation is finished. +<sect1><tt>#pragma message (<message>)</tt><label id="pragma-message"><p> + + This pragma is used to display informational messages at compile-time. + + The message intented to be displayed must be a string literal. + + Example: + <tscreen><verb> + #pragma message ("in a bottle") + </verb></tscreen> + + Results in the compiler outputting the following to stderr: + <tscreen><verb> + example.c(42): Note: in a bottle + </verb></tscreen> + + <sect1><tt>#pragma optimize ([push,] on|off)</tt><label id="pragma-optimize"><p> Switch optimization on or off. If the argument is "off", optimization is From 64581b65b037b09e0ba80198c092a976a2d49076 Mon Sep 17 00:00:00 2001 From: Pascal de Bruijn <pmjdebruijn@pcode.nl> Date: Sat, 22 Jul 2017 16:33:42 +0200 Subject: [PATCH 0394/2161] samples: install to subdirectory --- samples/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Makefile b/samples/Makefile index 949940022..eb2b78f1c 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -237,7 +237,7 @@ samples.atr: samples # Installation rules INSTALL = install -samplesdir = $(prefix)/share/cc65 +samplesdir = $(prefix)/share/cc65/samples install: $(if $(prefix),,$(error variable `prefix' must be set)) From 19f6ae1d54da28dc6d4c13828262a9ea3cd1c5cc Mon Sep 17 00:00:00 2001 From: Pascal de Bruijn <pmjdebruijn@pcode.nl> Date: Sat, 22 Jul 2017 16:38:50 +0200 Subject: [PATCH 0395/2161] make: change uppercase prefix var --- doc/Makefile | 6 +++--- libsrc/Makefile | 4 ++-- samples/Makefile | 4 ++-- src/Makefile | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/Makefile b/doc/Makefile index 96a3ba59b..33b5c2686 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -6,8 +6,8 @@ endif .SUFFIXES: -htmldir = $(prefix)/share/doc/cc65$(DESTPACKAGE_SUFFIX)/html -infodir = $(prefix)/share/info +htmldir = $(PREFIX)/share/doc/cc65$(DESTPACKAGE_SUFFIX)/html +infodir = $(PREFIX)/share/info ifdef CMD_EXE @@ -46,7 +46,7 @@ clean: $(RM) -r ../html ../info install: - $(if $(prefix),,$(error variable `prefix' must be set)) + $(if $(PREFIX),,$(error variable `PREFIX' must be set)) ifeq ($(wildcard ../html),../html) $(INSTALL) -d $(DESTDIR)$(htmldir) $(INSTALL) -m0644 ../html/*.* $(DESTDIR)$(htmldir) diff --git a/libsrc/Makefile b/libsrc/Makefile index 89d4b7752..0583b6761 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -72,7 +72,7 @@ endif ifndef TARGET -datadir = $(prefix)/share/cc65 +datadir = $(PREFIX)/share/cc65 all lib: $(TARGETS) @@ -92,7 +92,7 @@ INSTALL = install define INSTALL_recipe -$(if $(prefix),,$(error variable `prefix' must be set)) +$(if $(PREFIX),,$(error variable `PREFIX' must be set)) $(INSTALL) -d $(DESTDIR)$(datadir)/$(dir) $(INSTALL) -m0644 ../$(dir)/*.* $(DESTDIR)$(datadir)/$(dir) diff --git a/samples/Makefile b/samples/Makefile index eb2b78f1c..59841d655 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -237,10 +237,10 @@ samples.atr: samples # Installation rules INSTALL = install -samplesdir = $(prefix)/share/cc65/samples +samplesdir = $(PREFIX)/share/cc65/samples install: - $(if $(prefix),,$(error variable `prefix' must be set)) + $(if $(PREFIX),,$(error variable `PREFIX' must be set)) $(INSTALL) -d $(DESTDIR)$(samplesdir) $(INSTALL) -d $(DESTDIR)$(samplesdir)/geos $(INSTALL) -d $(DESTDIR)$(samplesdir)/tutorial diff --git a/src/Makefile b/src/Makefile index 3ce4b676a..8b41ceb9c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -19,8 +19,8 @@ PROGS = ar65 \ .SUFFIXES: -bindir := $(prefix)/bin -datadir := $(if $(prefix),$(prefix)/share/cc65,$(abspath ..)) +bindir := $(PREFIX)/bin +datadir := $(if $(PREFIX),$(PREFIX)/share/cc65,$(abspath ..)) CA65_INC = $(datadir)/asminc CC65_INC = $(datadir)/include @@ -107,7 +107,7 @@ $(RM) /usr/local/bin/$(prog) endef # UNAVAIL_recipe install: - $(if $(prefix),,$(error variable `prefix' must be set)) + $(if $(PREFIX),,$(error variable `PREFIX' must be set)) $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL) ../bin/* $(DESTDIR)$(bindir) From c802c9c946376801a0bbf5c501f5f73716c2b00f Mon Sep 17 00:00:00 2001 From: Pascal de Bruijn <pmjdebruijn@pcode.nl> Date: Sat, 22 Jul 2017 15:49:34 +0200 Subject: [PATCH 0396/2161] joy: refactor generic joy_masks array indices and macros --- include/cbm.h | 7 +++++++ include/gamate.h | 26 +++++++++++--------------- include/joystick.h | 32 ++++++++++++++++++-------------- include/lynx.h | 9 +++++++++ include/nes.h | 16 ++++++++-------- include/pce.h | 20 ++++++++------------ 6 files changed, 61 insertions(+), 49 deletions(-) diff --git a/include/cbm.h b/include/cbm.h index 226a09793..27e82f9f3 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -75,6 +75,13 @@ +/* Expanding upon joystick.h */ +#define JOY_FIRE_IDX 4 + +#define JOY_FIRE(v) ((v) & joy_masks[JOY_FIRE_IDX]) + + + /*****************************************************************************/ /* Variables */ /*****************************************************************************/ diff --git a/include/gamate.h b/include/gamate.h index 96c70c9bc..7355ede84 100644 --- a/include/gamate.h +++ b/include/gamate.h @@ -80,17 +80,6 @@ bit 3: */ -#define JOY_DATA 0x4400 - -#define JOY_DATA_UP 0x01 -#define JOY_DATA_DOWN 0x02 -#define JOY_DATA_LEFT 0x04 -#define JOY_DATA_RIGHT 0x08 -#define JOY_DATA_FIRE_A 0x10 -#define JOY_DATA_FIRE_B 0x20 -#define JOY_DATA_START 0x40 -#define JOY_DATA_SELECT 0x80 - /* LCD resolution 160x152 in 4 greys/greens @@ -181,13 +170,20 @@ /* No support for dynamically loadable drivers */ #define DYN_DRV 0 +/* Expanding upon joystick.h */ +#define JOY_BTN_A_IDX 4 +#define JOY_BTN_B_IDX 5 +#define JOY_START_IDX 6 +#define JOY_SELECT_IDX 7 + +#define JOY_BTN_A(v) ((v) & joy_masks[JOY_BTN_A_IDX]) +#define JOY_BTN_B(v) ((v) & joy_masks[JOY_BTN_B_IDX]) +#define JOY_START(v) ((v) & joy_masks[JOY_START_IDX]) +#define JOY_SELECT(v) ((v) & joy_masks[JOY_SELECT_IDX]) + /* The addresses of the static drivers */ extern void gamate_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ -#define JOY_FIRE_B 5 -#define JOY_START 6 -#define JOY_SELECT 7 - void waitvsync (void); /* Wait for start of next frame */ diff --git a/include/joystick.h b/include/joystick.h index 710d9b5a6..f08dd432a 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -52,27 +52,31 @@ #define JOY_ERR_NO_DEVICE 4 /* Device (hardware) not found */ /* Argument for the joy_read function */ -#define JOY_1 0 -#define JOY_2 1 +#define JOY_1 0 +#define JOY_2 1 /* The following codes are *indices* into the joy_masks array */ -#define JOY_UP 0 -#define JOY_DOWN 1 -#define JOY_LEFT 2 -#define JOY_RIGHT 3 -#define JOY_FIRE 4 -#define JOY_FIRE2 5 /* Second fire button if available */ +#define JOY_UP_IDX 0 +#define JOY_DOWN_IDX 1 +#define JOY_LEFT_IDX 2 +#define JOY_RIGHT_IDX 3 +#define JOY_BTN_1_IDX 4 /* Universally available */ +#define JOY_BTN_2_IDX 5 /* Second fire button if available */ +#define JOY_BTN_3_IDX 6 /* Third fire button if available */ +#define JOY_BTN_4_IDX 7 /* Fourth fire button if available */ /* Array of masks used to check the return value of joy_read for a state */ extern const unsigned char joy_masks[8]; /* Macros that evaluate the return code of joy_read */ -#define JOY_BTN_UP(v) ((v) & joy_masks[JOY_UP]) -#define JOY_BTN_DOWN(v) ((v) & joy_masks[JOY_DOWN]) -#define JOY_BTN_LEFT(v) ((v) & joy_masks[JOY_LEFT]) -#define JOY_BTN_RIGHT(v) ((v) & joy_masks[JOY_RIGHT]) -#define JOY_BTN_FIRE(v) ((v) & joy_masks[JOY_FIRE]) -#define JOY_BTN_FIRE2(v) ((v) & joy_masks[JOY_FIRE2]) +#define JOY_UP(v) ((v) & joy_masks[JOY_UP_IDX]) +#define JOY_DOWN(v) ((v) & joy_masks[JOY_DOWN_IDX]) +#define JOY_LEFT(v) ((v) & joy_masks[JOY_LEFT_IDX]) +#define JOY_RIGHT(v) ((v) & joy_masks[JOY_RIGHT_IDX]) +#define JOY_BTN_1(v) ((v) & joy_masks[JOY_BTN_1_IDX]) +#define JOY_BTN_2(v) ((v) & joy_masks[JOY_BTN_2_IDX]) +#define JOY_BTN_3(v) ((v) & joy_masks[JOY_BTN_3_IDX]) +#define JOY_BTN_4(v) ((v) & joy_masks[JOY_BTN_4_IDX]) /* The name of the standard joystick driver for a platform */ extern const char joy_stddrv[]; diff --git a/include/lynx.h b/include/lynx.h index 72f3d5bfd..c30ca6265 100644 --- a/include/lynx.h +++ b/include/lynx.h @@ -92,6 +92,15 @@ +/* Expanding upon joystick.h */ +#define JOY_BTN_A_IDX 4 +#define JOY_BTN_B_IDX 5 + +#define JOY_BTN_A(v) ((v) & joy_masks[JOY_BTN_A_IDX]) +#define JOY_BTN_B(v) ((v) & joy_masks[JOY_BTN_B_IDX]) + + + /*****************************************************************************/ /* Variables */ /*****************************************************************************/ diff --git a/include/nes.h b/include/nes.h index 3e139e00c..0b65cdbe4 100644 --- a/include/nes.h +++ b/include/nes.h @@ -91,15 +91,15 @@ #define DYN_DRV 0 /* Expanding upon joystick.h */ -#define JOY_A 4 -#define JOY_B 5 -#define JOY_SELECT 6 -#define JOY_START 7 +#define JOY_BTN_A_IDX 4 +#define JOY_BTN_B_IDX 5 +#define JOY_SELECT_IDX 6 +#define JOY_START_IDX 7 -#define JOY_BTN_A(v) ((v) & joy_masks[JOY_A]) -#define JOY_BTN_B(v) ((v) & joy_masks[JOY_B]) -#define JOY_BTN_SELECT(v) ((v) & joy_masks[JOY_SELECT]) -#define JOY_BTN_START(v) ((v) & joy_masks[JOY_START]) +#define JOY_BTN_A(v) ((v) & joy_masks[JOY_BTN_A_IDX]) +#define JOY_BTN_B(v) ((v) & joy_masks[JOY_BTN_B_IDX]) +#define JOY_SELECT(v) ((v) & joy_masks[JOY_SELECT_IDX]) +#define JOY_START(v) ((v) & joy_masks[JOY_START_IDX]) /* Define hardware */ diff --git a/include/pce.h b/include/pce.h index ac6b2503f..12b596cf9 100644 --- a/include/pce.h +++ b/include/pce.h @@ -77,23 +77,19 @@ #define DYN_DRV 0 /* Expanding upon joystick.h */ -#define JOY_I 4 -#define JOY_II 5 -#define JOY_SELECT 6 -#define JOY_RUN 7 +#define JOY_BTN_I_IDX 4 +#define JOY_BTN_II_IDX 5 +#define JOY_SELECT_IDX 6 +#define JOY_RUN_IDX 7 -#define JOY_BTN_I(v) ((v) & joy_masks[JOY_I]) -#define JOY_BTN_II(v) ((v) & joy_masks[JOY_II]) -#define JOY_BTN_SELECT(v) ((v) & joy_masks[JOY_SELECT]) -#define JOY_BTN_RUN(v) ((v) & joy_masks[JOY_RUN]) +#define JOY_BTN_I(v) ((v) & joy_masks[JOY_BTN_I_IDX]) +#define JOY_BTN_II(v) ((v) & joy_masks[JOY_BTN_II_IDX]) +#define JOY_SELECT(v) ((v) & joy_masks[JOY_SELECT_IDX]) +#define JOY_RUN(v) ((v) & joy_masks[JOY_RUN_IDX]) /* The addresses of the static drivers */ extern void pce_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ -#define JOY_FIRE_B 5 -#define JOY_SELECT 6 -#define JOY_RUN 7 - void waitvsync (void); /* Wait for start of the next frame */ From a623169477d5925a1a4e43085f34d0f589804353 Mon Sep 17 00:00:00 2001 From: Bill Chatfield <bill_chatfield@yahoo.com> Date: Wed, 26 Jul 2017 11:15:49 -0400 Subject: [PATCH 0397/2161] Added ProDOS file type definitions --- .gitignore | 3 + include/apple2.h | 1 + include/apple2_filetype.h | 254 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 258 insertions(+) create mode 100644 include/apple2_filetype.h diff --git a/.gitignore b/.gitignore index ad4d26c3f..39d5b59fa 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ /testwrk/ /wrk/ /cc65.zip + +# Vim swap files +.*.swp diff --git a/include/apple2.h b/include/apple2.h index a1b094d4d..a2150c173 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -42,6 +42,7 @@ #endif +#include <apple2_filetype.h> /*****************************************************************************/ /* Data */ diff --git a/include/apple2_filetype.h b/include/apple2_filetype.h new file mode 100644 index 000000000..51e7d3e51 --- /dev/null +++ b/include/apple2_filetype.h @@ -0,0 +1,254 @@ +/*****************************************************************************/ +/* */ +/* apple2_filetype.h */ +/* */ +/* Apple ][ file type definitions */ +/* */ +/* */ +/* */ +/* (C) 2000 Kevin Ruland, <kevin@rodin.wustl.edu> */ +/* (C) 2003 Ullrich von Bassewitz, <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 _APPLE2_FILETYPE_H +#define _APPLE2_FILETYPE_H + + + +/* Check for errors */ +#if !defined(__APPLE2__) +# error This module may only be used when compiling for the Apple ][! +#endif + + +/* ProDOS general file types */ +#define PRODOS_FILE_TYPE_UNK 0x00 /* Unknown */ +#define PRODOS_FILE_TYPE_BAD 0x01 /* Bad blocks */ +#define PRODOS_FILE_TYPE_PCD 0x02 /* Pascal code */ +#define PRODOS_FILE_TYPE_PTX 0x03 /* Pascal text */ +#define PRODOS_FILE_TYPE_TXT 0x04 /* ASCII text */ +#define PRODOS_FILE_TYPE_PDA 0x05 /* Pascal data */ +#define PRODOS_FILE_TYPE_BIN 0x06 /* Binary */ +#define PRODOS_FILE_TYPE_FNT 0x07 /* Apple III font */ +#define PRODOS_FILE_TYPE_FOT 0x08 /* Hi-res, dbl hi-res graphics */ +#define PRODOS_FILE_TYPE_BA3 0x09 /* Apple III BASIC program */ +#define PRODOS_FILE_TYPE_DA3 0x09 /* Apple III BASIC data */ +#define PRODOS_FILE_TYPE_WPF 0x0A /* Generic word processing */ +#define PRODOS_FILE_TYPE_SOS 0x0B /* SOS system */ +#define PRODOS_FILE_TYPE_DIR 0x0F /* ProDOS directory */ + +/* ProDOS productivity file types */ +#define PRODOS_FILE_TYPE_RPD 0x10 /* RPS data */ +#define PRODOS_FILE_TYPE_RPI 0x11 /* RPS index */ +#define PRODOS_FILE_TYPE_AFD 0x12 /* AppleFile discard */ +#define PRODOS_FILE_TYPE_AFM 0x13 /* AppleFile model */ +#define PRODOS_FILE_TYPE_AFR 0x14 /* AppleFile report */ +#define PRODOS_FILE_TYPE_SCL 0x15 /* Screen library */ +#define PRODOS_FILE_TYPE_PFS 0x16 /* PFS document */ +#define PRODOS_FILE_TYPE_ADB 0x19 /* AppleWorks database */ +#define PRODOS_FILE_TYPE_AWP 0x1A /* AppleWorks word processing */ +#define PRODOS_FILE_TYPE_ASP 0x1B /* AppleWorks spreadsheet */ + +/* ProDOS code file types */ +#define PRODOS_FILE_TYPE_TDM 0x20 /* Desktop Manager */ +#define PRODOS_FILE_TYPE_IPS 0x21 /* Instant Pascal source */ +#define PRODOS_FILE_TYPE_UPV 0x22 /* USCD Pascal volume */ +#define PRODOS_FILE_TYPE_3SD 0x29 /* SOS directory */ +#define PRODOS_FILE_TYPE_8SC 0x2A /* Source code */ +#define PRODOS_FILE_TYPE_8OB 0x2B /* Object code */ +#define PRODOS_FILE_TYPE_8IC 0x2C /* Interpreted code */ +#define PRODOS_FILE_TYPE_8LD 0x2D /* Language data */ +#define PRODOS_FILE_TYPE_P8C 0x2E /* ProDOS 8 code module */ + +/* ProDOS miscellaneous file types */ +#define PRODOS_FILE_TYPE_OCR 0x41 /* Optical char recognition */ +#define PRODOS_FILE_TYPE_FTD 0x42 /* File type definitions */ + +/* ProDOS Apple IIgs general file types */ +#define PRODOS_FILE_TYPE_GWP 0x50 /* Apple IIgs word processing */ +#define PRODOS_FILE_TYPE_GSS 0x51 /* Apple IIgs spreadsheet */ +#define PRODOS_FILE_TYPE_GDB 0x52 /* Apple IIgs database */ +#define PRODOS_FILE_TYPE_DRW 0x53 /* Object oriented graphics */ +#define PRODOS_FILE_TYPE_GDP 0x54 /* Apple IIgs desktop publish */ +#define PRODOS_FILE_TYPE_HMD 0x55 /* HyperMedia */ +#define PRODOS_FILE_TYPE_EDU 0x56 /* Educational program data */ +#define PRODOS_FILE_TYPE_STN 0x57 /* Stationary */ +#define PRODOS_FILE_TYPE_HLP 0x58 /* Help */ +#define PRODOS_FILE_TYPE_COM 0x59 /* Communications */ +#define PRODOS_FILE_TYPE_CFG 0x5A /* Configuration */ +#define PRODOS_FILE_TYPE_ANM 0x5B /* Animation */ +#define PRODOS_FILE_TYPE_MUM 0x5C /* Multimedia */ +#define PRODOS_FILE_TYPE_ENT 0x5D /* Entertainment */ +#define PRODOS_FILE_TYPE_DVU 0x5E /* Development utility */ + +/* ProDOS PC Transporter file types */ +#define PRODOS_FILE_TYPE_PRE 0x60 /* PC pre-boot */ +#define PRODOS_FILE_TYPE_BIO 0x6B /* PC BIOS */ +#define PRODOS_FILE_TYPE_NCF 0x66 /* ProDOS File Nav command file */ +#define PRODOS_FILE_TYPE_DVR 0x6D /* PC driver */ +#define PRODOS_FILE_TYPE_PRE2 0x6E /* PC pre-boot */ +#define PRODOS_FILE_TYPE_HDV 0x6F /* PC hard disk image */ + +/* ProDOS Kreative Software file types */ +#define PRODOS_FILE_TYPE_SN2 0x70 /* Sabine's Notebook 2.0 */ +#define PRODOS_FILE_TYPE_KMT 0x71 +#define PRODOS_FILE_TYPE_DSR 0x72 +#define PRODOS_FILE_TYPE_BAN 0x73 +#define PRODOS_FILE_TYPE_CG7 0x74 +#define PRODOS_FILE_TYPE_TNJ 0x75 +#define PRODOS_FILE_TYPE_SA7 0x76 +#define PRODOS_FILE_TYPE_KES 0x77 +#define PRODOS_FILE_TYPE_JAP 0x78 +#define PRODOS_FILE_TYPE_CSL 0x79 +#define PRODOS_FILE_TYPE_TME 0x7A +#define PRODOS_FILE_TYPE_TLB 0x7B +#define PRODOS_FILE_TYPE_MR7 0x7C +#define PRODOS_FILE_TYPE_MLR 0x7D /* Mika City */ +#define PRODOS_FILE_TYPE_MMM 0x7E +#define PRODOS_FILE_TYPE_JCP 0x7F + +/* ProDOS GEOS file types */ +#define PRODOS_FILE_TYPE_GES 0x80 /* GEOS system file */ +#define PRODOS_FILE_TYPE_GEA 0x81 /* GEOS desk accessory */ +#define PRODOS_FILE_TYPE_GEO 0x82 /* GEOS application */ +#define PRODOS_FILE_TYPE_GED 0x83 /* GEOS document */ +#define PRODOS_FILE_TYPE_GEF 0x84 /* GEOS font */ +#define PRODOS_FILE_TYPE_GEP 0x85 /* GEOS printer driver */ +#define PRODOS_FILE_TYPE_GEI 0x86 /* GEOS input driver */ +#define PRODOS_FILE_TYPE_GEX 0x87 /* GEOS auxiliary driver */ +#define PRODOS_FILE_TYPE_GEV 0x89 /* GEOS swap file */ +#define PRODOS_FILE_TYPE_GEC 0x8B /* GEOS clock driver */ +#define PRODOS_FILE_TYPE_GEK 0x8C /* GEOS interface card driver */ +#define PRODOS_FILE_TYPE_GEW 0x8D /* GEOS formatting data */ + +/* ProDOS Apple IIgs BASIC file types */ +#define PRODOS_FILE_TYPE_WP 0xA0 /* WordPerfect */ +#define PRODOS_FILE_TYPE_GSB 0xAB /* Apple IIgs BASIC program */ +#define PRODOS_FILE_TYPE_TDF 0xAB /* Apple IIgs BASIC TDF */ +#define PRODOS_FILE_TYPE_BDF 0xAB /* Apple IIgs BASIC data */ + +/* ProDOS Apple IIgs system file types */ +#define PRODOS_FILE_TYPE_SRC 0xB0 /* Apple IIgs source code */ +#define PRODOS_FILE_TYPE_OBJ 0xB1 /* Apple IIgs object code */ +#define PRODOS_FILE_TYPE_LIB 0xB2 /* Apple IIgs library */ +#define PRODOS_FILE_TYPE_S16 0xB3 /* Apple IIgs application pgm */ +#define PRODOS_FILE_TYPE_RTL 0xB4 /* Apple IIgs runtime library */ +#define PRODOS_FILE_TYPE_EXE 0xB5 /* Apple IIgs shell script */ +#define PRODOS_FILE_TYPE_PIF 0xB6 /* Apple IIgs permanent init */ +#define PRODOS_FILE_TYPE_TIF 0xB7 /* Apple IIgs temporary init */ +#define PRODOS_FILE_TYPE_NDA 0xB8 /* Apple IIgs new desk accesry */ +#define PRODOS_FILE_TYPE_CDA 0xB9 /* Apple IIgs classic desk aces */ +#define PRODOS_FILE_TYPE_TOL 0xBA /* Apple IIgs tool */ +#define PRODOS_FILE_TYPE_DRV 0xBB /* Apple IIgs device driver */ +#define PRODOS_FILE_TYPE_LDF 0xBC /* Apple IIgs generic load file */ +#define PRODOS_FILE_TYPE_FST 0xBD /* Apple IIgs file sys translat */ +#define PRODOS_FILE_TYPE_DOC 0xBF /* Apple IIgs document */ + +/* ProDOS graphics file types */ +#define PRODOS_FILE_TYPE_PNT 0xC0 /* Apple IIgs packed sup hi-res */ +#define PRODOS_FILE_TYPE_PIC 0xC1 /* Apple IIgs super hi-res */ +#define PRODOS_FILE_TYPE_ANI 0xC2 /* PaintWorks animation */ +#define PRODOS_FILE_TYPE_PAL 0xC3 /* PaintWorks palette */ +#define PRODOS_FILE_TYPE_OOG 0xC5 /* Object-oriented graphics */ +#define PRODOS_FILE_TYPE_SCR 0xC6 /* Script */ +#define PRODOS_FILE_TYPE_CDV 0xC7 /* Apple IIgs control panel */ +#define PRODOS_FILE_TYPE_FON 0xC8 /* Apple IIgs font */ +#define PRODOS_FILE_TYPE_FND 0xC9 /* Apple IIgs Finder data */ +#define PRODOS_FILE_TYPE_ICN 0xCA /* Apple IIgs icon */ + +/* ProDOS audio file types */ +#define PRODOS_FILE_TYPE_MUS 0xD5 /* Music */ +#define PRODOS_FILE_TYPE_INS 0xD6 /* Instrument */ +#define PRODOS_FILE_TYPE_MID 0xD7 /* MIDI */ +#define PRODOS_FILE_TYPE_SND 0xD8 /* Apple IIgs audio */ +#define PRODOS_FILE_TYPE_DBM 0xDB /* DB master document */ + +/* ProDOS miscellaneous file types */ +#define PRODOS_FILE_TYPE_LBR 0xE0 /* Archive */ +#define PRODOS_FILE_TYPE_ATK 0xE2 /* AppleTalk data */ +#define PRODOS_FILE_TYPE_R16 0xEE /* EDASM 816 relocatable code */ +#define PRODOS_FILE_TYPE_PAR 0xEF /* Pascal area */ + +/* ProDOS system file types */ +#define PRODOS_FILE_TYPE_CMD 0xF0 /* ProDOS command file */ +#define PRODOS_T_OVL 0xF1 /* User defined 1 */ +#define PRODOS_FILE_TYPE_UD2 0xF2 /* User defined 2 */ +#define PRODOS_FILE_TYPE_UD3 0xF3 /* User defined 3 */ +#define PRODOS_FILE_TYPE_UD4 0xF4 /* User defined 4 */ +#define PRODOS_FILE_TYPE_BAT 0xF5 /* User defined 5 */ +#define PRODOS_FILE_TYPE_UD6 0xF6 /* User defined 6 */ +#define PRODOS_FILE_TYPE_UD7 0xF7 /* User defined 7 */ +#define PRODOS_FILE_TYPE_PRG 0xF8 /* User defined 8 */ +#define PRODOS_FILE_TYPE_P16 0xF9 /* ProDOS-16 system file */ +#define PRODOS_FILE_TYPE_INT 0xFA /* Integer BASIC program */ +#define PRODOS_FILE_TYPE_IVR 0xFB /* Integer BASIC variables */ +#define PRODOS_FILE_TYPE_BAS 0xFC /* Applesoft BASIC program */ +#define PRODOS_FILE_TYPE_VAR 0xFD /* Applesoft BASIC variables */ +#define PRODOS_FILE_TYPE_REL 0xFE /* EDASM relocatable code */ +#define PRODOS_FILE_TYPE_SYS 0xFF /* ProDOS-8 system file */ + +/* The auxiliary type of a text file specifies its record length. +** A record length of 0 indicates a sequential text file, which is +** equivalent to text files of other operating systems like MacOS +** or Windows, except that lines are delimited by carriage returns +** only. An auxiliary type value greater than 0 for a text file, +** which is the record length, indicates a random access text file +** with fixed-length lines. +*/ +#define PRODOS_AUX_T_TXT_SEQ 0x0000 /* Sequential text */ + +/* 8IC auxiliary type */ +#define PRODOS_AUX_T_8IC_APEX_PGM 0x8003 /* Apex program */ + +/* GWP auxiliary types */ +#define PRODOS_AUX_T_GWP_TEACH 0x5445 /* Teach */ +#define PRODOS_AUX_T_GWP_DELUXEWRITE 0x8001 /* DeluxeWrite */ +#define PRODOS_AUX_T_GWP_APPLEWORKS_GS 0x8010 /* AppleWorks GS */ + +/* GSS auxiliary type */ +#define PRODOS_AUX_T_GSS_APPLEWORKS_GS 0x8010 /* AppleWorks GS */ + +/* GDB auxiliary types */ +#define PRODOS_GDB_AUX_TYPE_APLWRKSGS 0x8010 /* AppleWorks GS DB */ +#define PRODOS_GDB_AUX_TYPE_AWGS_TMPL 0x8011 /* AWGS template */ +#define PRODOS_GDB_AUX_TYPE_GSAS 0x8013 + +/* DRW auxiliary type */ +#define PRODOS_DRW_AUX_TYPE_APLWRKSGS 0x8013 /* AWGS O-O graphics */ + +/* GDP auxiliary types */ +#define PRODOS_GDP_AUX_TYPE_GRFCWRTR 0x8002 /* AWGS GraphicWriter */ +#define PRODOS_GDP_AUX_TYPE_APLWRKSGS 0x8010 /* AWGS */ + +/* HMD auxiliary types */ +#define PRODOS_HMD_AUX_TYPE_HYPRCRDGS 0x0001 /* HyperCard GS */ +#define PRODOS_HMD_AUX_TYPE_TUTORTECH 0x8001 /* Tutor-Tech */ +#define PRODOS_HMD_AUX_TYPE_HYPRSTDIO 0x8002 /* HyperStudio */ +#define PRODOS_HMD_AUX_TYPE_NEXUS 0x8003 /* Nexus */ + +/* COM auxiliary type */ +#define PRODOS_COM_AUX_TYPE_APLWRKSGS 0x8003 /* AppleWorks GS */ + +/* End of apple2_filetypes.h */ +#endif From e64e11d2c5e43962967b6bc9664fd67e113c38fd Mon Sep 17 00:00:00 2001 From: Bill Chatfield <bill_chatfield@yahoo.com> Date: Thu, 27 Jul 2017 14:44:02 -0400 Subject: [PATCH 0398/2161] Finished adding all types and comments --- include/apple2_filetype.h | 372 ++++++++++++++++++++++---------------- 1 file changed, 213 insertions(+), 159 deletions(-) diff --git a/include/apple2_filetype.h b/include/apple2_filetype.h index 51e7d3e51..96cf49581 100644 --- a/include/apple2_filetype.h +++ b/include/apple2_filetype.h @@ -42,171 +42,178 @@ #endif + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + /* ProDOS general file types */ -#define PRODOS_FILE_TYPE_UNK 0x00 /* Unknown */ -#define PRODOS_FILE_TYPE_BAD 0x01 /* Bad blocks */ -#define PRODOS_FILE_TYPE_PCD 0x02 /* Pascal code */ -#define PRODOS_FILE_TYPE_PTX 0x03 /* Pascal text */ -#define PRODOS_FILE_TYPE_TXT 0x04 /* ASCII text */ -#define PRODOS_FILE_TYPE_PDA 0x05 /* Pascal data */ -#define PRODOS_FILE_TYPE_BIN 0x06 /* Binary */ -#define PRODOS_FILE_TYPE_FNT 0x07 /* Apple III font */ -#define PRODOS_FILE_TYPE_FOT 0x08 /* Hi-res, dbl hi-res graphics */ -#define PRODOS_FILE_TYPE_BA3 0x09 /* Apple III BASIC program */ -#define PRODOS_FILE_TYPE_DA3 0x09 /* Apple III BASIC data */ -#define PRODOS_FILE_TYPE_WPF 0x0A /* Generic word processing */ -#define PRODOS_FILE_TYPE_SOS 0x0B /* SOS system */ -#define PRODOS_FILE_TYPE_DIR 0x0F /* ProDOS directory */ +#define PRODOS_T_UNK 0x00 /* Unknown */ +#define PRODOS_T_BAD 0x01 /* Bad blocks */ +#define PRODOS_T_PCD 0x02 /* Pascal code */ +#define PRODOS_T_PTX 0x03 /* Pascal text */ +#define PRODOS_T_TXT 0x04 /* ASCII text */ +#define PRODOS_T_PDA 0x05 /* Pascal data */ +#define PRODOS_T_BIN 0x06 /* Binary */ +#define PRODOS_T_FNT 0x07 /* Apple III font */ +#define PRODOS_T_FOT 0x08 /* Hi-res, dbl hi-res graphics */ +#define PRODOS_T_BA3 0x09 /* Apple III BASIC program */ +#define PRODOS_T_DA3 0x09 /* Apple III BASIC data */ +#define PRODOS_T_WPF 0x0A /* Generic word processing */ +#define PRODOS_T_SOS 0x0B /* SOS system */ +#define PRODOS_T_DIR 0x0F /* ProDOS directory */ /* ProDOS productivity file types */ -#define PRODOS_FILE_TYPE_RPD 0x10 /* RPS data */ -#define PRODOS_FILE_TYPE_RPI 0x11 /* RPS index */ -#define PRODOS_FILE_TYPE_AFD 0x12 /* AppleFile discard */ -#define PRODOS_FILE_TYPE_AFM 0x13 /* AppleFile model */ -#define PRODOS_FILE_TYPE_AFR 0x14 /* AppleFile report */ -#define PRODOS_FILE_TYPE_SCL 0x15 /* Screen library */ -#define PRODOS_FILE_TYPE_PFS 0x16 /* PFS document */ -#define PRODOS_FILE_TYPE_ADB 0x19 /* AppleWorks database */ -#define PRODOS_FILE_TYPE_AWP 0x1A /* AppleWorks word processing */ -#define PRODOS_FILE_TYPE_ASP 0x1B /* AppleWorks spreadsheet */ +#define PRODOS_T_RPD 0x10 /* RPS data */ +#define PRODOS_T_RPI 0x11 /* RPS index */ +#define PRODOS_T_AFD 0x12 /* AppleFile discard */ +#define PRODOS_T_AFM 0x13 /* AppleFile model */ +#define PRODOS_T_AFR 0x14 /* AppleFile report */ +#define PRODOS_T_SCL 0x15 /* Screen library */ +#define PRODOS_T_PFS 0x16 /* PFS document */ +#define PRODOS_T_ADB 0x19 /* AppleWorks database */ +#define PRODOS_T_AWP 0x1A /* AppleWorks word processing */ +#define PRODOS_T_ASP 0x1B /* AppleWorks spreadsheet */ /* ProDOS code file types */ -#define PRODOS_FILE_TYPE_TDM 0x20 /* Desktop Manager */ -#define PRODOS_FILE_TYPE_IPS 0x21 /* Instant Pascal source */ -#define PRODOS_FILE_TYPE_UPV 0x22 /* USCD Pascal volume */ -#define PRODOS_FILE_TYPE_3SD 0x29 /* SOS directory */ -#define PRODOS_FILE_TYPE_8SC 0x2A /* Source code */ -#define PRODOS_FILE_TYPE_8OB 0x2B /* Object code */ -#define PRODOS_FILE_TYPE_8IC 0x2C /* Interpreted code */ -#define PRODOS_FILE_TYPE_8LD 0x2D /* Language data */ -#define PRODOS_FILE_TYPE_P8C 0x2E /* ProDOS 8 code module */ +#define PRODOS_T_TDM 0x20 /* Desktop Manager */ +#define PRODOS_T_IPS 0x21 /* Instant Pascal source */ +#define PRODOS_T_UPV 0x22 /* USCD Pascal volume */ +#define PRODOS_T_3SD 0x29 /* SOS directory */ +#define PRODOS_T_8SC 0x2A /* Source code */ +#define PRODOS_T_8OB 0x2B /* Object code */ +#define PRODOS_T_8IC 0x2C /* Interpreted code */ +#define PRODOS_T_8LD 0x2D /* Language data */ +#define PRODOS_T_P8C 0x2E /* ProDOS 8 code module */ /* ProDOS miscellaneous file types */ -#define PRODOS_FILE_TYPE_OCR 0x41 /* Optical char recognition */ -#define PRODOS_FILE_TYPE_FTD 0x42 /* File type definitions */ +#define PRODOS_T_OCR 0x41 /* Optical char recognition */ +#define PRODOS_T_FTD 0x42 /* File type definitions */ /* ProDOS Apple IIgs general file types */ -#define PRODOS_FILE_TYPE_GWP 0x50 /* Apple IIgs word processing */ -#define PRODOS_FILE_TYPE_GSS 0x51 /* Apple IIgs spreadsheet */ -#define PRODOS_FILE_TYPE_GDB 0x52 /* Apple IIgs database */ -#define PRODOS_FILE_TYPE_DRW 0x53 /* Object oriented graphics */ -#define PRODOS_FILE_TYPE_GDP 0x54 /* Apple IIgs desktop publish */ -#define PRODOS_FILE_TYPE_HMD 0x55 /* HyperMedia */ -#define PRODOS_FILE_TYPE_EDU 0x56 /* Educational program data */ -#define PRODOS_FILE_TYPE_STN 0x57 /* Stationary */ -#define PRODOS_FILE_TYPE_HLP 0x58 /* Help */ -#define PRODOS_FILE_TYPE_COM 0x59 /* Communications */ -#define PRODOS_FILE_TYPE_CFG 0x5A /* Configuration */ -#define PRODOS_FILE_TYPE_ANM 0x5B /* Animation */ -#define PRODOS_FILE_TYPE_MUM 0x5C /* Multimedia */ -#define PRODOS_FILE_TYPE_ENT 0x5D /* Entertainment */ -#define PRODOS_FILE_TYPE_DVU 0x5E /* Development utility */ +#define PRODOS_T_GWP 0x50 /* Apple IIgs word processing */ +#define PRODOS_T_GSS 0x51 /* Apple IIgs spreadsheet */ +#define PRODOS_T_GDB 0x52 /* Apple IIgs database */ +#define PRODOS_T_DRW 0x53 /* Object oriented graphics */ +#define PRODOS_T_GDP 0x54 /* Apple IIgs desktop publish */ +#define PRODOS_T_HMD 0x55 /* HyperMedia */ +#define PRODOS_T_EDU 0x56 /* Educational program data */ +#define PRODOS_T_STN 0x57 /* Stationary */ +#define PRODOS_T_HLP 0x58 /* Help */ +#define PRODOS_T_COM 0x59 /* Communications */ +#define PRODOS_T_CFG 0x5A /* Configuration */ +#define PRODOS_T_ANM 0x5B /* Animation */ +#define PRODOS_T_MUM 0x5C /* Multimedia */ +#define PRODOS_T_ENT 0x5D /* Entertainment */ +#define PRODOS_T_DVU 0x5E /* Development utility */ /* ProDOS PC Transporter file types */ -#define PRODOS_FILE_TYPE_PRE 0x60 /* PC pre-boot */ -#define PRODOS_FILE_TYPE_BIO 0x6B /* PC BIOS */ -#define PRODOS_FILE_TYPE_NCF 0x66 /* ProDOS File Nav command file */ -#define PRODOS_FILE_TYPE_DVR 0x6D /* PC driver */ -#define PRODOS_FILE_TYPE_PRE2 0x6E /* PC pre-boot */ -#define PRODOS_FILE_TYPE_HDV 0x6F /* PC hard disk image */ +#define PRODOS_T_PRE 0x60 /* PC pre-boot */ +#define PRODOS_T_BIO 0x6B /* PC BIOS */ +#define PRODOS_T_NCF 0x66 /* ProDOS File Nav command file */ +#define PRODOS_T_DVR 0x6D /* PC driver */ +#define PRODOS_T_PRE2 0x6E /* PC pre-boot */ +#define PRODOS_T_HDV 0x6F /* PC hard disk image */ /* ProDOS Kreative Software file types */ -#define PRODOS_FILE_TYPE_SN2 0x70 /* Sabine's Notebook 2.0 */ -#define PRODOS_FILE_TYPE_KMT 0x71 -#define PRODOS_FILE_TYPE_DSR 0x72 -#define PRODOS_FILE_TYPE_BAN 0x73 -#define PRODOS_FILE_TYPE_CG7 0x74 -#define PRODOS_FILE_TYPE_TNJ 0x75 -#define PRODOS_FILE_TYPE_SA7 0x76 -#define PRODOS_FILE_TYPE_KES 0x77 -#define PRODOS_FILE_TYPE_JAP 0x78 -#define PRODOS_FILE_TYPE_CSL 0x79 -#define PRODOS_FILE_TYPE_TME 0x7A -#define PRODOS_FILE_TYPE_TLB 0x7B -#define PRODOS_FILE_TYPE_MR7 0x7C -#define PRODOS_FILE_TYPE_MLR 0x7D /* Mika City */ -#define PRODOS_FILE_TYPE_MMM 0x7E -#define PRODOS_FILE_TYPE_JCP 0x7F +#define PRODOS_T_SN2 0x70 /* Sabine's Notebook 2.0 */ +#define PRODOS_T_KMT 0x71 +#define PRODOS_T_DSR 0x72 +#define PRODOS_T_BAN 0x73 +#define PRODOS_T_CG7 0x74 +#define PRODOS_T_TNJ 0x75 +#define PRODOS_T_SA7 0x76 +#define PRODOS_T_KES 0x77 +#define PRODOS_T_JAP 0x78 +#define PRODOS_T_CSL 0x79 +#define PRODOS_T_TME 0x7A +#define PRODOS_T_TLB 0x7B +#define PRODOS_T_MR7 0x7C +#define PRODOS_T_MLR 0x7D /* Mika City */ +#define PRODOS_T_MMM 0x7E +#define PRODOS_T_JCP 0x7F /* ProDOS GEOS file types */ -#define PRODOS_FILE_TYPE_GES 0x80 /* GEOS system file */ -#define PRODOS_FILE_TYPE_GEA 0x81 /* GEOS desk accessory */ -#define PRODOS_FILE_TYPE_GEO 0x82 /* GEOS application */ -#define PRODOS_FILE_TYPE_GED 0x83 /* GEOS document */ -#define PRODOS_FILE_TYPE_GEF 0x84 /* GEOS font */ -#define PRODOS_FILE_TYPE_GEP 0x85 /* GEOS printer driver */ -#define PRODOS_FILE_TYPE_GEI 0x86 /* GEOS input driver */ -#define PRODOS_FILE_TYPE_GEX 0x87 /* GEOS auxiliary driver */ -#define PRODOS_FILE_TYPE_GEV 0x89 /* GEOS swap file */ -#define PRODOS_FILE_TYPE_GEC 0x8B /* GEOS clock driver */ -#define PRODOS_FILE_TYPE_GEK 0x8C /* GEOS interface card driver */ -#define PRODOS_FILE_TYPE_GEW 0x8D /* GEOS formatting data */ +#define PRODOS_T_GES 0x80 /* GEOS system file */ +#define PRODOS_T_GEA 0x81 /* GEOS desk accessory */ +#define PRODOS_T_GEO 0x82 /* GEOS application */ +#define PRODOS_T_GED 0x83 /* GEOS document */ +#define PRODOS_T_GEF 0x84 /* GEOS font */ +#define PRODOS_T_GEP 0x85 /* GEOS printer driver */ +#define PRODOS_T_GEI 0x86 /* GEOS input driver */ +#define PRODOS_T_GEX 0x87 /* GEOS auxiliary driver */ +#define PRODOS_T_GEV 0x89 /* GEOS swap file */ +#define PRODOS_T_GEC 0x8B /* GEOS clock driver */ +#define PRODOS_T_GEK 0x8C /* GEOS interface card driver */ +#define PRODOS_T_GEW 0x8D /* GEOS formatting data */ /* ProDOS Apple IIgs BASIC file types */ -#define PRODOS_FILE_TYPE_WP 0xA0 /* WordPerfect */ -#define PRODOS_FILE_TYPE_GSB 0xAB /* Apple IIgs BASIC program */ -#define PRODOS_FILE_TYPE_TDF 0xAB /* Apple IIgs BASIC TDF */ -#define PRODOS_FILE_TYPE_BDF 0xAB /* Apple IIgs BASIC data */ +#define PRODOS_T_WP 0xA0 /* WordPerfect */ +#define PRODOS_T_GSB 0xAB /* Apple IIgs BASIC program */ +#define PRODOS_T_TDF 0xAB /* Apple IIgs BASIC TDF */ +#define PRODOS_T_BDF 0xAB /* Apple IIgs BASIC data */ /* ProDOS Apple IIgs system file types */ -#define PRODOS_FILE_TYPE_SRC 0xB0 /* Apple IIgs source code */ -#define PRODOS_FILE_TYPE_OBJ 0xB1 /* Apple IIgs object code */ -#define PRODOS_FILE_TYPE_LIB 0xB2 /* Apple IIgs library */ -#define PRODOS_FILE_TYPE_S16 0xB3 /* Apple IIgs application pgm */ -#define PRODOS_FILE_TYPE_RTL 0xB4 /* Apple IIgs runtime library */ -#define PRODOS_FILE_TYPE_EXE 0xB5 /* Apple IIgs shell script */ -#define PRODOS_FILE_TYPE_PIF 0xB6 /* Apple IIgs permanent init */ -#define PRODOS_FILE_TYPE_TIF 0xB7 /* Apple IIgs temporary init */ -#define PRODOS_FILE_TYPE_NDA 0xB8 /* Apple IIgs new desk accesry */ -#define PRODOS_FILE_TYPE_CDA 0xB9 /* Apple IIgs classic desk aces */ -#define PRODOS_FILE_TYPE_TOL 0xBA /* Apple IIgs tool */ -#define PRODOS_FILE_TYPE_DRV 0xBB /* Apple IIgs device driver */ -#define PRODOS_FILE_TYPE_LDF 0xBC /* Apple IIgs generic load file */ -#define PRODOS_FILE_TYPE_FST 0xBD /* Apple IIgs file sys translat */ -#define PRODOS_FILE_TYPE_DOC 0xBF /* Apple IIgs document */ +#define PRODOS_T_SRC 0xB0 /* Apple IIgs source code */ +#define PRODOS_T_OBJ 0xB1 /* Apple IIgs object code */ +#define PRODOS_T_LIB 0xB2 /* Apple IIgs library */ +#define PRODOS_T_S16 0xB3 /* Apple IIgs application pgm */ +#define PRODOS_T_RTL 0xB4 /* Apple IIgs runtime library */ +#define PRODOS_T_EXE 0xB5 /* Apple IIgs shell script */ +#define PRODOS_T_PIF 0xB6 /* Apple IIgs permanent init */ +#define PRODOS_T_TIF 0xB7 /* Apple IIgs temporary init */ +#define PRODOS_T_NDA 0xB8 /* Apple IIgs new desk accesry */ +#define PRODOS_T_CDA 0xB9 /* Apple IIgs classic desk aces */ +#define PRODOS_T_TOL 0xBA /* Apple IIgs tool */ +#define PRODOS_T_DRV 0xBB /* Apple IIgs device driver */ +#define PRODOS_T_LDF 0xBC /* Apple IIgs generic load file */ +#define PRODOS_T_FST 0xBD /* Apple IIgs file sys translat */ +#define PRODOS_T_DOC 0xBF /* Apple IIgs document */ /* ProDOS graphics file types */ -#define PRODOS_FILE_TYPE_PNT 0xC0 /* Apple IIgs packed sup hi-res */ -#define PRODOS_FILE_TYPE_PIC 0xC1 /* Apple IIgs super hi-res */ -#define PRODOS_FILE_TYPE_ANI 0xC2 /* PaintWorks animation */ -#define PRODOS_FILE_TYPE_PAL 0xC3 /* PaintWorks palette */ -#define PRODOS_FILE_TYPE_OOG 0xC5 /* Object-oriented graphics */ -#define PRODOS_FILE_TYPE_SCR 0xC6 /* Script */ -#define PRODOS_FILE_TYPE_CDV 0xC7 /* Apple IIgs control panel */ -#define PRODOS_FILE_TYPE_FON 0xC8 /* Apple IIgs font */ -#define PRODOS_FILE_TYPE_FND 0xC9 /* Apple IIgs Finder data */ -#define PRODOS_FILE_TYPE_ICN 0xCA /* Apple IIgs icon */ +#define PRODOS_T_PNT 0xC0 /* Apple IIgs packed sup hi-res */ +#define PRODOS_T_PIC 0xC1 /* Apple IIgs super hi-res */ +#define PRODOS_T_ANI 0xC2 /* PaintWorks animation */ +#define PRODOS_T_PAL 0xC3 /* PaintWorks palette */ +#define PRODOS_T_OOG 0xC5 /* Object-oriented graphics */ +#define PRODOS_T_SCR 0xC6 /* Script */ +#define PRODOS_T_CDV 0xC7 /* Apple IIgs control panel */ +#define PRODOS_T_FON 0xC8 /* Apple IIgs font */ +#define PRODOS_T_FND 0xC9 /* Apple IIgs Finder data */ +#define PRODOS_T_ICN 0xCA /* Apple IIgs icon */ /* ProDOS audio file types */ -#define PRODOS_FILE_TYPE_MUS 0xD5 /* Music */ -#define PRODOS_FILE_TYPE_INS 0xD6 /* Instrument */ -#define PRODOS_FILE_TYPE_MID 0xD7 /* MIDI */ -#define PRODOS_FILE_TYPE_SND 0xD8 /* Apple IIgs audio */ -#define PRODOS_FILE_TYPE_DBM 0xDB /* DB master document */ +#define PRODOS_T_MUS 0xD5 /* Music */ +#define PRODOS_T_INS 0xD6 /* Instrument */ +#define PRODOS_T_MID 0xD7 /* MIDI */ +#define PRODOS_T_SND 0xD8 /* Apple IIgs audio */ +#define PRODOS_T_DBM 0xDB /* DB master document */ /* ProDOS miscellaneous file types */ -#define PRODOS_FILE_TYPE_LBR 0xE0 /* Archive */ -#define PRODOS_FILE_TYPE_ATK 0xE2 /* AppleTalk data */ -#define PRODOS_FILE_TYPE_R16 0xEE /* EDASM 816 relocatable code */ -#define PRODOS_FILE_TYPE_PAR 0xEF /* Pascal area */ +#define PRODOS_T_LBR 0xE0 /* Archive */ +#define PRODOS_T_ATK 0xE2 /* AppleTalk data */ +#define PRODOS_T_R16 0xEE /* EDASM 816 relocatable code */ +#define PRODOS_T_PAR 0xEF /* Pascal area */ /* ProDOS system file types */ -#define PRODOS_FILE_TYPE_CMD 0xF0 /* ProDOS command file */ +#define PRODOS_T_CMD 0xF0 /* ProDOS command file */ #define PRODOS_T_OVL 0xF1 /* User defined 1 */ -#define PRODOS_FILE_TYPE_UD2 0xF2 /* User defined 2 */ -#define PRODOS_FILE_TYPE_UD3 0xF3 /* User defined 3 */ -#define PRODOS_FILE_TYPE_UD4 0xF4 /* User defined 4 */ -#define PRODOS_FILE_TYPE_BAT 0xF5 /* User defined 5 */ -#define PRODOS_FILE_TYPE_UD6 0xF6 /* User defined 6 */ -#define PRODOS_FILE_TYPE_UD7 0xF7 /* User defined 7 */ -#define PRODOS_FILE_TYPE_PRG 0xF8 /* User defined 8 */ -#define PRODOS_FILE_TYPE_P16 0xF9 /* ProDOS-16 system file */ -#define PRODOS_FILE_TYPE_INT 0xFA /* Integer BASIC program */ -#define PRODOS_FILE_TYPE_IVR 0xFB /* Integer BASIC variables */ -#define PRODOS_FILE_TYPE_BAS 0xFC /* Applesoft BASIC program */ -#define PRODOS_FILE_TYPE_VAR 0xFD /* Applesoft BASIC variables */ -#define PRODOS_FILE_TYPE_REL 0xFE /* EDASM relocatable code */ -#define PRODOS_FILE_TYPE_SYS 0xFF /* ProDOS-8 system file */ +#define PRODOS_T_UD2 0xF2 /* User defined 2 */ +#define PRODOS_T_UD3 0xF3 /* User defined 3 */ +#define PRODOS_T_UD4 0xF4 /* User defined 4 */ +#define PRODOS_T_BAT 0xF5 /* User defined 5 */ +#define PRODOS_T_UD6 0xF6 /* User defined 6 */ +#define PRODOS_T_UD7 0xF7 /* User defined 7 */ +#define PRODOS_T_PRG 0xF8 /* User defined 8 */ +#define PRODOS_T_P16 0xF9 /* ProDOS-16 system file */ +#define PRODOS_T_INT 0xFA /* Integer BASIC program */ +#define PRODOS_T_IVR 0xFB /* Integer BASIC variables */ +#define PRODOS_T_BAS 0xFC /* Applesoft BASIC program */ +#define PRODOS_T_VAR 0xFD /* Applesoft BASIC variables */ +#define PRODOS_T_REL 0xFE /* EDASM relocatable code */ +#define PRODOS_T_SYS 0xFF /* ProDOS-8 system file */ /* The auxiliary type of a text file specifies its record length. ** A record length of 0 indicates a sequential text file, which is @@ -216,39 +223,86 @@ ** which is the record length, indicates a random access text file ** with fixed-length lines. */ -#define PRODOS_AUX_T_TXT_SEQ 0x0000 /* Sequential text */ +#define PRODOS_AUX_T_TXT_SEQ 0x0000 /* Sequential text */ -/* 8IC auxiliary type */ -#define PRODOS_AUX_T_8IC_APEX_PGM 0x8003 /* Apex program */ +/* 8IC auxiliary types */ +#define PRODOS_AUX_T_8IC_APEX_PGM 0x8003 /* Apex program */ /* GWP auxiliary types */ -#define PRODOS_AUX_T_GWP_TEACH 0x5445 /* Teach */ -#define PRODOS_AUX_T_GWP_DELUXEWRITE 0x8001 /* DeluxeWrite */ -#define PRODOS_AUX_T_GWP_APPLEWORKS_GS 0x8010 /* AppleWorks GS */ +#define PRODOS_AUX_T_GWP_TEACH 0x5445 /* Teach */ +#define PRODOS_AUX_T_GWP_DELUXEWRITE 0x8001 /* DeluxeWrite */ +#define PRODOS_AUX_T_GWP_APPLEWORKS_GS 0x8010 /* AppleWorks GS */ -/* GSS auxiliary type */ -#define PRODOS_AUX_T_GSS_APPLEWORKS_GS 0x8010 /* AppleWorks GS */ +/* GSS auxiliary types */ +#define PRODOS_AUX_T_GSS_APPLEWORKS_GS 0x8010 /* AppleWorks GS */ /* GDB auxiliary types */ -#define PRODOS_GDB_AUX_TYPE_APLWRKSGS 0x8010 /* AppleWorks GS DB */ -#define PRODOS_GDB_AUX_TYPE_AWGS_TMPL 0x8011 /* AWGS template */ -#define PRODOS_GDB_AUX_TYPE_GSAS 0x8013 +#define PRODOS_AUX_T_GDB_APPLEWORKS_GS 0x8010 /* AppleWorks GS DB */ +#define PRODOS_AUX_T_GDB_AWGS_TMPL 0x8011 /* AWGS template */ +#define PRODOS_AUX_T_GDB_GSAS 0x8013 -/* DRW auxiliary type */ -#define PRODOS_DRW_AUX_TYPE_APLWRKSGS 0x8013 /* AWGS O-O graphics */ +/* DRW auxiliary types */ +#define PRODOS_AUX_T_DRW_OO_GRAPHICS 0x8013 /* AWGS O-O graphics */ /* GDP auxiliary types */ -#define PRODOS_GDP_AUX_TYPE_GRFCWRTR 0x8002 /* AWGS GraphicWriter */ -#define PRODOS_GDP_AUX_TYPE_APLWRKSGS 0x8010 /* AWGS */ +#define PRODOS_AUX_T_GDP_GRAPHICWRITER 0x8002 /* A2gs GraphicWriter */ +#define PRODOS_AUX_T_GDP_APPLEWORKS_GS 0x8010 /* A2gs AWGS */ /* HMD auxiliary types */ -#define PRODOS_HMD_AUX_TYPE_HYPRCRDGS 0x0001 /* HyperCard GS */ -#define PRODOS_HMD_AUX_TYPE_TUTORTECH 0x8001 /* Tutor-Tech */ -#define PRODOS_HMD_AUX_TYPE_HYPRSTDIO 0x8002 /* HyperStudio */ -#define PRODOS_HMD_AUX_TYPE_NEXUS 0x8003 /* Nexus */ +#define PRODOS_AUX_T_HMD_HYPERCARD_GS 0x0001 /* HyperCard GS */ +#define PRODOS_AUX_T_HMD_TUTOR_TECH 0x8001 /* Tutor-Tech */ +#define PRODOS_AUX_T_HMD_HYPERSTUDIO 0x8002 /* HyperStudio */ +#define PRODOS_AUX_T_HMD_NEXUS 0x8003 /* Nexus */ -/* COM auxiliary type */ -#define PRODOS_COM_AUX_TYPE_APLWRKSGS 0x8003 /* AppleWorks GS */ +/* COM auxiliary types */ +#define PRODOS_AUX_T_COM_APPLEWORKS_GS 0x8003 /* AppleWorks GS */ -/* End of apple2_filetypes.h */ +/* MLR auxiliary types */ +#define PRODOS_AUX_T_MLR_SCRIPT 0x005C /* Mika City script */ +#define PRODOS_AUX_T_MLR_COLOR_TABLE 0xC7AB /* Mika City color table */ +#define PRODOS_AUX_T_MLR_CHARACTER_DEF 0xCDEF /* Mika City character def */ + +/* LDF auxiliary types */ +#define PRODOS_AUX_T_LDF_NIFTY_LIST_MOD 0x4001 /* Nifty list module */ +#define PRODOS_AUX_T_LDF_SUPER_INFO_MOD 0x4002 /* Super info module */ +#define PRODOS_AUX_T_LDF_TWILIGHT_MOD 0x4004 /* Twilight module */ +#define PRODOS_AUX_T_LDF_MARINETTI_LLM 0x4004 /* Marinetti link layer mod */ + +/* PNT auxiliary types */ +#define PRODOS_AUX_T_PNT_PK_SUPER_HIRES 0x0001 /* Packed super hi-res */ +#define PRODOS_AUX_T_PNT_APPLE_PREF 0x0002 /* Apple preferred format */ +#define PRODOS_AUX_T_PNT_PK_QUICKDRAWII 0x0003 /* Packed QuickDraw II */ + +/* PIC auxiliary types */ +#define PRODOS_AUX_T_PIC_QUICKDRAW 0x0001 /* QuickDraw image */ +#define PRODOS_AUX_T_PIC_SHIRES_3200 0x0002 /* Super hi-res 3200 */ + +/* FON auxiliary types */ +#define PRODOS_AUX_T_FON_QUICKDRAW_BIT 0x0000 /* QuickDraw bitmap font */ +#define PRODOS_AUX_T_FON_POINTLESS_TT 0x0001 /* Pointless TrueType font */ + +/* SND auxiliary types */ +#define PRODOS_AUX_T_SND_AIFF 0x0000 /* AIFF */ +#define PRODOS_AUX_T_SND_AIFF_C 0x0001 /* AIFF-C */ +#define PRODOS_AUX_T_SND_ASIF_INSTR 0x0002 /* ASIF instrument */ +#define PRODOS_AUX_T_SND_SOUND_RSRC 0x0003 /* Sound resource */ +#define PRODOS_AUX_T_SND_MIDI_SYNTH_WAV 0x0004 /* MIDI synth wave */ +#define PRODOS_AUX_T_SND_HYPERSTUDIO 0x8001 /* HyperStudio sound */ + +/* LBR auxiliary types */ +#define PRODOS_AUX_T_LBR_ALU 0x0000 /* ALU */ +#define PRODOS_AUX_T_LBR_APPLE_SINGLE 0x0001 /* AppleSingle */ +#define PRODOS_AUX_T_LBR_APPLEDBL_HDR 0x0002 /* AppleDouble header */ +#define PRODOS_AUX_T_LBR_APPLEDBL_DATA 0x0003 /* AppleDouble data */ +#define PRODOS_AUX_T_LBR_BINARY_II 0x8000 /* Binary II */ +#define PRODOS_AUX_T_LBR_APPLELINK_ACU 0x8001 /* AppleLink ACU */ +#define PRODOS_AUX_T_LBR_SHRINKIT 0x8002 /* ShrinkIt */ + +/* LBR auxiliary types */ +#define PRODOS_AUX_T_ATK_EASYMNT_ALIAS 0x0000 /* EasyMount alias */ + +/* BAS auxiliary types */ +#define PRODOS_AUX_T_BAS_PGM_LOAD_ADDR 0x0801 /* Applesoft pgm load addr */ + +/* End of apple2_filetype.h */ #endif From 91d06596635980e3ba4110faa702b1972e9b0f81 Mon Sep 17 00:00:00 2001 From: Bill Chatfield <bill_chatfield@yahoo.com> Date: Fri, 28 Jul 2017 11:29:11 -0400 Subject: [PATCH 0399/2161] Rolled back changes to exclude vim swap files Only files generated by the tools in the project are to be ignored --- .gitignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index 39d5b59fa..ad4d26c3f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,3 @@ /testwrk/ /wrk/ /cc65.zip - -# Vim swap files -.*.swp From 9459f11688542104c2dbb4d32d9b6e0ec59ecc25 Mon Sep 17 00:00:00 2001 From: Bill Chatfield <bill_chatfield@yahoo.com> Date: Fri, 28 Jul 2017 12:01:57 -0400 Subject: [PATCH 0400/2161] Corrected copyright and moved file type globals The file type globals., _filetype and _auxtype, were moved from apple2.h to this file. --- include/apple2_filetype.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/include/apple2_filetype.h b/include/apple2_filetype.h index 96cf49581..bdfa93093 100644 --- a/include/apple2_filetype.h +++ b/include/apple2_filetype.h @@ -6,8 +6,7 @@ /* */ /* */ /* */ -/* (C) 2000 Kevin Ruland, <kevin@rodin.wustl.edu> */ -/* (C) 2003 Ullrich von Bassewitz, <uz@cc65.org> */ +/* (C) 2017 Bill Chatfield, <bill_chatfield@yahoo.com> */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -304,5 +303,12 @@ /* BAS auxiliary types */ #define PRODOS_AUX_T_BAS_PGM_LOAD_ADDR 0x0801 /* Applesoft pgm load addr */ +/* The file stream implementation and the POSIX I/O functions will use the +** following variables to determine the file type and auxiliary type to use. +** This applies specifically to the fopen and open functions. +*/ +extern unsigned char _filetype; /* Default: PRODOS_T_BIN */ +extern unsigned int _auxtype; /* Default: 0 */ + /* End of apple2_filetype.h */ #endif From abb2e8034b4ead55364f75938ae894826339f54e Mon Sep 17 00:00:00 2001 From: Bill Chatfield <bill_chatfield@yahoo.com> Date: Fri, 28 Jul 2017 12:09:58 -0400 Subject: [PATCH 0401/2161] Moved file type variables to apple2_filetype.h --- include/apple2.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/apple2.h b/include/apple2.h index a2150c173..e73023693 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -137,11 +137,9 @@ extern unsigned char _dos_type; /* The file stream implementation and the POSIX I/O functions will use the -** following variables to determine the file type, aux type and creation time -** stamp to use. +** following struct to set the date and time stamp on files. This specificially +** applies to the open and fopen functions. */ -extern unsigned char _filetype; /* Default: 6 */ -extern unsigned int _auxtype; /* Default: 0 */ extern struct { struct { unsigned day :5; From f40bb936777ecc223723b6f502e9a94eccd09541 Mon Sep 17 00:00:00 2001 From: Bill Chatfield <bill_chatfield@yahoo.com> Date: Fri, 28 Jul 2017 12:12:18 -0400 Subject: [PATCH 0402/2161] Added Variables section comment per convention --- include/apple2_filetype.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/apple2_filetype.h b/include/apple2_filetype.h index bdfa93093..be17274fa 100644 --- a/include/apple2_filetype.h +++ b/include/apple2_filetype.h @@ -303,6 +303,14 @@ /* BAS auxiliary types */ #define PRODOS_AUX_T_BAS_PGM_LOAD_ADDR 0x0801 /* Applesoft pgm load addr */ + + +/*****************************************************************************/ +/* Variables */ +/*****************************************************************************/ + + + /* The file stream implementation and the POSIX I/O functions will use the ** following variables to determine the file type and auxiliary type to use. ** This applies specifically to the fopen and open functions. From 80c1c94a87aca1b0b7a4b0521d140493d20ba4b0 Mon Sep 17 00:00:00 2001 From: Bill Chatfield <bill_chatfield@yahoo.com> Date: Fri, 28 Jul 2017 12:16:55 -0400 Subject: [PATCH 0403/2161] Corrected comment formatting --- include/apple2_filetype.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/apple2_filetype.h b/include/apple2_filetype.h index be17274fa..83a44f532 100644 --- a/include/apple2_filetype.h +++ b/include/apple2_filetype.h @@ -316,7 +316,7 @@ ** This applies specifically to the fopen and open functions. */ extern unsigned char _filetype; /* Default: PRODOS_T_BIN */ -extern unsigned int _auxtype; /* Default: 0 */ +extern unsigned int _auxtype; /* Default: 0 */ /* End of apple2_filetype.h */ #endif From 375ee571c235250bebd3ea10af5830b38d870747 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 28 Jul 2017 19:19:11 +0200 Subject: [PATCH 0404/2161] Removed 'fire'. --- include/joystick.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/joystick.h b/include/joystick.h index f08dd432a..27c4af81a 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -61,9 +61,9 @@ #define JOY_LEFT_IDX 2 #define JOY_RIGHT_IDX 3 #define JOY_BTN_1_IDX 4 /* Universally available */ -#define JOY_BTN_2_IDX 5 /* Second fire button if available */ -#define JOY_BTN_3_IDX 6 /* Third fire button if available */ -#define JOY_BTN_4_IDX 7 /* Fourth fire button if available */ +#define JOY_BTN_2_IDX 5 /* Second button if available */ +#define JOY_BTN_3_IDX 6 /* Third button if available */ +#define JOY_BTN_4_IDX 7 /* Fourth button if available */ /* Array of masks used to check the return value of joy_read for a state */ extern const unsigned char joy_masks[8]; From 2c7b757b4caf152e26f9bb0bbb3fb0dba0b69f6c Mon Sep 17 00:00:00 2001 From: Bill Chatfield <bill_chatfield@yahoo.com> Date: Fri, 28 Jul 2017 17:44:13 -0400 Subject: [PATCH 0405/2161] Documented _filetype and _auxtype --- doc/apple2.sgml | 98 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 3089a04c4..fe5c98767 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -511,6 +511,104 @@ url="ca65.html" name="assembler manual">. </descrip><p> +<sect1>Specifying ProDOS File Types<p> + +<descrip> + + <tag>Problem Explanation</tag> + + ProDOS associates a file type and an auxiliary type with each file. + These type specifications are separate from the file's name, unlike + Windows and UNIX-like systems which use the file name's suffix (a.k.a. + extension) to specify the file type. For example, .exe, .doc, or .bat. + The ProDOS low-level + Machine-Language Interface (MLI) functions for creating and opening + files require these types to be specified. And if they don't match + with the file being opened, the operation may fail. + + In contrast, the ISO C function <tt/fopen()/ and the POSIX function + <tt/open()/ have no parameter to specify either a file type or an + auxiliary type. Therefore, some additional mechanism for specifying + the file types is needed. + + <tag>Solution</tag> + + There are two global variables provided that allow the file type + and auxiliary type to be specified before a call to <tt/fopen()/ + or <tt/open/. They are defined in <tt/apple2_filetype.h/: + + <quote> + <verb> + extern unsigned char _filetype; /* Default: PRODOS_T_BIN */ + extern unsigned int _auxtype; /* Default: 0 */ + </verb> + </quote> + + The header file <tt/apple2_filetype.h/ also defines many values + that can be used to set these variables. It is included in + <tt/apple2.h/, which is in turn included in <tt/apple2enh.h/. + So it + not necessary to include it directly. Just + include one of <tt/apple2.h/ or <tt/apple2enh.h/. + + <tag>Example</tag> + + A text file cannot be created with just the + standard C functions because they default to the binary type + <tt/PRODOS_T_BIN/. The <tt/_filetype/ variable must be set to + <tt/PRODOS_T_TXT/ to create a text file. + + For a text file, + <tt/_auxtype/ specifies the record length. A zero record + length text file is referred to as a sequential text file. + This is equivalent to text files on + other operating systems, except that the line terminator is a + carriage return instead of a new line (Linux/BSD/MacOS) or + carriage return, new line pair (Windows). + + The "sequential" text file terminology is in contrast to a + "random-access" text file which would + have a fixed-length, non-zero record length, so that the + file position of any individual record can be calculated. + + For this example, the + <tt/_auxtype/ does not need to be set because it defaults to + the desired value, which is zero. To be more explicit, + <tt/_auxtype/ can also be set to <tt/PRODOS_AUX_T_TXT_SEQ/ + which is defined as zero. + + <quote> + <verb> + #include <stdio.h> + #include <string.h> + #include <errno.h> + #include <apple2.h> + void main() + { + FILE *out; + char *name = "MY.FAVS"; + + _filetype = PRODOS_T_TXT; + _auxtype = PRODOS_AUX_T_TXT_SEQ; + + if ((out = fopen(name, "w")) != NULL) { + fputs("Jorah Mormont\r", out); + fputs("Brienne of Tarth\r", out); + fputs("Daenerys Targaryen\r", out); + fputs("Sandor Clegane\r", out); + if (fclose(out) == EOF) { + fprintf(stderr, "fclose failed for %s: %s", name, strerror(errno)); + } + } + else { + fprintf(stderr, "fopen failed for %s: %s", name, strerror(errno)); + } + } + </verb> + </quote> + +</descrip><p> + <sect>License<p> From 9d89613bb2d5f8817cd38886acdb92fa1f5395c5 Mon Sep 17 00:00:00 2001 From: Bill Chatfield <bill_chatfield@yahoo.com> Date: Sat, 29 Jul 2017 01:25:07 -0400 Subject: [PATCH 0406/2161] Added documentation for setting the file type for fopen. --- doc/apple2.sgml | 27 ++++++++++++++++----------- doc/apple2enh.sgml | 8 ++++++++ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index fe5c98767..4ed2af48c 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -511,11 +511,11 @@ url="ca65.html" name="assembler manual">. </descrip><p> -<sect1>Specifying ProDOS File Types<p> +<sect1>Specifying file types for fopen<p> <descrip> - <tag>Problem Explanation</tag> + <tag>Explanation of File Types</tag> ProDOS associates a file type and an auxiliary type with each file. These type specifications are separate from the file's name, unlike @@ -531,18 +531,18 @@ url="ca65.html" name="assembler manual">. auxiliary type. Therefore, some additional mechanism for specifying the file types is needed. - <tag>Solution</tag> + <tag>Specifying the File Type and Auxiliary Type</tag> There are two global variables provided that allow the file type and auxiliary type to be specified before a call to <tt/fopen()/ or <tt/open/. They are defined in <tt/apple2_filetype.h/: - <quote> + <tscreen> <verb> extern unsigned char _filetype; /* Default: PRODOS_T_BIN */ extern unsigned int _auxtype; /* Default: 0 */ </verb> - </quote> + </tscreen> The header file <tt/apple2_filetype.h/ also defines many values that can be used to set these variables. It is included in @@ -577,20 +577,25 @@ url="ca65.html" name="assembler manual">. <tt/_auxtype/ can also be set to <tt/PRODOS_AUX_T_TXT_SEQ/ which is defined as zero. - <quote> + <tscreen> <verb> - #include <stdio.h> - #include <string.h> - #include <errno.h> - #include <apple2.h> + #include <stdio.h> + #include <string.h> + #include <errno.h> + #include <apple2.h> + void main() { FILE *out; char *name = "MY.FAVS"; + /*-----------------------------*/ + _filetype = PRODOS_T_TXT; _auxtype = PRODOS_AUX_T_TXT_SEQ; + /*-----------------------------*/ + if ((out = fopen(name, "w")) != NULL) { fputs("Jorah Mormont\r", out); fputs("Brienne of Tarth\r", out); @@ -605,7 +610,7 @@ url="ca65.html" name="assembler manual">. } } </verb> - </quote> + </tscreen> </descrip><p> diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 5e4626fbc..672f5d6aa 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -517,6 +517,14 @@ url="ca65.html" name="assembler manual">. </descrip><p> +<sect1>Specifying file types for fopen<p> + +See section +<url url="apple2.html#ss9.4" name="Specifying file types for fopen"> +in the apple2 docoumentation. + + + <sect>License<p> From 85e572f4e12e071ef61fb5846b8839b6e2781df8 Mon Sep 17 00:00:00 2001 From: Bill Chatfield <bill_chatfield@yahoo.com> Date: Sun, 30 Jul 2017 19:49:20 -0400 Subject: [PATCH 0407/2161] Made corrections according to review comments --- doc/apple2.sgml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 4ed2af48c..33a878223 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -519,8 +519,9 @@ url="ca65.html" name="assembler manual">. ProDOS associates a file type and an auxiliary type with each file. These type specifications are separate from the file's name, unlike - Windows and UNIX-like systems which use the file name's suffix (a.k.a. - extension) to specify the file type. For example, .exe, .doc, or .bat. + Windows which uses the file name's suffix (a.k.a. + extension) to specify the file type. For example, <tt/.exe/, + <tt/.doc/, or <tt/.bat/. The ProDOS low-level Machine-Language Interface (MLI) functions for creating and opening files require these types to be specified. And if they don't match @@ -535,7 +536,7 @@ url="ca65.html" name="assembler manual">. There are two global variables provided that allow the file type and auxiliary type to be specified before a call to <tt/fopen()/ - or <tt/open/. They are defined in <tt/apple2_filetype.h/: + or <tt/open()/. They are defined in <tt/apple2_filetype.h/: <tscreen> <verb> @@ -547,8 +548,7 @@ url="ca65.html" name="assembler manual">. The header file <tt/apple2_filetype.h/ also defines many values that can be used to set these variables. It is included in <tt/apple2.h/, which is in turn included in <tt/apple2enh.h/. - So it - not necessary to include it directly. Just + So it isn't necessary to include it directly. Just include one of <tt/apple2.h/ or <tt/apple2enh.h/. <tag>Example</tag> @@ -563,8 +563,8 @@ url="ca65.html" name="assembler manual">. length text file is referred to as a sequential text file. This is equivalent to text files on other operating systems, except that the line terminator is a - carriage return instead of a new line (Linux/BSD/MacOS) or - carriage return, new line pair (Windows). + carriage return instead of a line-feed (Linux/BSD/MacOS) or + carriage return, line-feed pair (Windows). The "sequential" text file terminology is in contrast to a "random-access" text file which would @@ -584,7 +584,7 @@ url="ca65.html" name="assembler manual">. #include <errno.h> #include <apple2.h> - void main() + void main(void) { FILE *out; char *name = "MY.FAVS"; From 0bd5a8a3314b1b6b8047dc31113bd5ead59d706e Mon Sep 17 00:00:00 2001 From: Bill Chatfield <bill_chatfield@yahoo.com> Date: Sun, 30 Jul 2017 19:51:23 -0400 Subject: [PATCH 0408/2161] Made corrections according to review comments --- doc/apple2enh.sgml | 105 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 102 insertions(+), 3 deletions(-) diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 672f5d6aa..c7be9b474 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -519,9 +519,108 @@ url="ca65.html" name="assembler manual">. <sect1>Specifying file types for fopen<p> -See section -<url url="apple2.html#ss9.4" name="Specifying file types for fopen"> -in the apple2 docoumentation. +<descrip> + + <tag>Explanation of File Types</tag> + + ProDOS associates a file type and an auxiliary type with each file. + These type specifications are separate from the file's name, unlike + Windows which uses the file name's suffix (a.k.a. + extension) to specify the file type. For example, <tt/.exe/, + <tt/.doc/, or <tt/.bat/. + The ProDOS low-level + Machine-Language Interface (MLI) functions for creating and opening + files require these types to be specified. And if they don't match + with the file being opened, the operation may fail. + + In contrast, the ISO C function <tt/fopen()/ and the POSIX function + <tt/open()/ have no parameter to specify either a file type or an + auxiliary type. Therefore, some additional mechanism for specifying + the file types is needed. + + <tag>Specifying the File Type and Auxiliary Type</tag> + + There are two global variables provided that allow the file type + and auxiliary type to be specified before a call to <tt/fopen()/ + or <tt/open()/. They are defined in <tt/apple2_filetype.h/: + + <tscreen> + <verb> + extern unsigned char _filetype; /* Default: PRODOS_T_BIN */ + extern unsigned int _auxtype; /* Default: 0 */ + </verb> + </tscreen> + + The header file <tt/apple2_filetype.h/ also defines many values + that can be used to set these variables. It is included in + <tt/apple2.h/, which is in turn included in <tt/apple2enh.h/. + So it isn't necessary to include it directly. Just + include one of <tt/apple2.h/ or <tt/apple2enh.h/. + + <tag>Example</tag> + + A text file cannot be created with just the + standard C functions because they default to the binary type + <tt/PRODOS_T_BIN/. The <tt/_filetype/ variable must be set to + <tt/PRODOS_T_TXT/ to create a text file. + + For a text file, + <tt/_auxtype/ specifies the record length. A zero record + length text file is referred to as a sequential text file. + This is equivalent to text files on + other operating systems, except that the line terminator is a + carriage return instead of a line-feed (Linux/BSD/MacOS) or + carriage return, line-feed pair (Windows). + + The "sequential" text file terminology is in contrast to a + "random-access" text file which would + have a fixed-length, non-zero record length, so that the + file position of any individual record can be calculated. + + For this example, the + <tt/_auxtype/ does not need to be set because it defaults to + the desired value, which is zero. To be more explicit, + <tt/_auxtype/ can also be set to <tt/PRODOS_AUX_T_TXT_SEQ/ + which is defined as zero. + + <tscreen> + <verb> + #include <stdio.h> + #include <string.h> + #include <errno.h> + #include <apple2.h> + + void main(void) + { + FILE *out; + char *name = "MY.FAVS"; + + /*-----------------------------*/ + + _filetype = PRODOS_T_TXT; + _auxtype = PRODOS_AUX_T_TXT_SEQ; + + /*-----------------------------*/ + + if ((out = fopen(name, "w")) != NULL) { + fputs("Jorah Mormont\r", out); + fputs("Brienne of Tarth\r", out); + fputs("Daenerys Targaryen\r", out); + fputs("Sandor Clegane\r", out); + if (fclose(out) == EOF) { + fprintf(stderr, "fclose failed for %s: %s", name, strerror(errno)); + } + } + else { + fprintf(stderr, "fopen failed for %s: %s", name, strerror(errno)); + } + } + </verb> + </tscreen> + +</descrip><p> + + From 92ff854bff8cd3b93b37acebc4048626b93a83fc Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 31 Jul 2017 13:50:27 +0200 Subject: [PATCH 0409/2161] Removed undesirable empty lines. --- doc/apple2enh.sgml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index c7be9b474..4f5202543 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -621,10 +621,6 @@ url="ca65.html" name="assembler manual">. </descrip><p> - - - - <sect>License<p> This software is provided 'as-is', without any expressed or implied From f9c59a0976ff3eb654a7152ef31c4e1af59aa06b Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 2 Aug 2017 23:56:52 +0200 Subject: [PATCH 0410/2161] atari5200.inc: fix formatting --- asminc/atari5200.inc | 107 +++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/asminc/atari5200.inc b/asminc/atari5200.inc index b67c9a8db..91fae4a9a 100644 --- a/asminc/atari5200.inc +++ b/asminc/atari5200.inc @@ -8,42 +8,42 @@ ; ATASCII CHARACTER DEFS ;------------------------------------------------------------------------- -ATEOL = $9B ;END-OF-LINE, used by CONIO +ATEOL = $9B ; END-OF-LINE, used by CONIO ;------------------------------------------------------------------------- ; Zero Page ;------------------------------------------------------------------------- -POKMSK = $00 ;Mask for Pokey IRQ enable -RTCLOK = $01 ;60 hz. clock +POKMSK = $00 ; Mask for Pokey IRQ enable +RTCLOK = $01 ; 60 hz. clock JUMP = $01 -CRITIC = $03 ;Critical section -ATRACT = $04 ;Attract Mode +CRITIC = $03 ; Critical section +ATRACT = $04 ; Attract Mode -SDLSTL = $05 ;DLISTL Shadow -SDLSTH = $06 ;DLISTH " -SDMCTL = $07 ;DMACTL " +SDLSTL = $05 ; DLISTL Shadow +SDLSTH = $06 ; DLISTH " +SDMCTL = $07 ; DMACTL " -PCOLR0 = $08 ;COLPM0 Shadow -PCOLR1 = $09 ;COLPM1 " -PCOLR2 = $0A ;COLPM2 " -PCOLR3 = $0B ;COLPM3 " +PCOLR0 = $08 ; COLPM0 Shadow +PCOLR1 = $09 ; COLPM1 " +PCOLR2 = $0A ; COLPM2 " +PCOLR3 = $0B ; COLPM3 " -COLOR0 = $0C ;COLPF0 Shadow -COLOR1 = $0D ;COLPF1 " -COLOR2 = $0E ;COLPF2 " -COLOR3 = $0F ;COLPF3 " -COLOR4 = $10 ;COLBK " +COLOR0 = $0C ; COLPF0 Shadow +COLOR1 = $0D ; COLPF1 " +COLOR2 = $0E ; COLPF2 " +COLOR3 = $0F ; COLPF3 " +COLOR4 = $10 ; COLBK " -PADDL0 = $11 ;POT0 Shadow -PADDL1 = $12 ;POT1 " -PADDL2 = $13 ;POT2 " -PADDL3 = $14 ;POT3 " -PADDL4 = $15 ;POT4 " -PADDL5 = $16 ;POT5 " -PADDL6 = $17 ;POT6 " -PADDL7 = $18 ;POT7 " +PADDL0 = $11 ; POT0 Shadow +PADDL1 = $12 ; POT1 " +PADDL2 = $13 ; POT2 " +PADDL3 = $14 ; POT3 " +PADDL4 = $15 ; POT4 " +PADDL5 = $16 ; POT5 " +PADDL6 = $17 ; POT6 " +PADDL7 = $18 ; POT7 " ; cc65 runtime zero page variables @@ -57,26 +57,26 @@ SAVMSC = $1B ; pointer to screen memory (conio) ;Interrupt Vectors -VIMIRQ = $0200 ;Immediate IRQ - ;Preset $FC03 (SYSIRQ) -VVBLKI = $0202 ;Vblank immediate - ;Preset $FCB8 (SYSVBL) -VVBLKD = $0204 ;Vblank deferred - ;Preset $FCB2 (XITVBL) -VDSLST = $0206 ;Display List - ;Preset $FEA1 (OSDLI) -VKYBDI = $0208 ;Keyboard immediate - ;Preset $FD02 (SYSKBD) -VKYBDF = $020A ;Deferred Keyboard - ;Preset $FCB2 (XITVBL) -VTRIGR = $020C ;Soft Trigger -VBRKOP = $020E ;BRK Opcode -VSERIN = $0210 ;Serial in Ready -VSEROR = $0212 ;Serial Out Ready -VSEROC = $0214 ;Serial Output complete -VTIMR1 = $0216 ;Pokey Timer 1 -VTIMR2 = $0218 ;Pokey Timer 2 -VTIMR4 = $021A ;Pokey Timer 4 +VIMIRQ = $0200 ; Immediate IRQ + ; Preset $FC03 (SYSIRQ) +VVBLKI = $0202 ; Vblank immediate + ; Preset $FCB8 (SYSVBL) +VVBLKD = $0204 ; Vblank deferred + ; Preset $FCB2 (XITVBL) +VDSLST = $0206 ; Display List + ; Preset $FEA1 (OSDLI) +VKYBDI = $0208 ; Keyboard immediate + ; Preset $FD02 (SYSKBD) +VKYBDF = $020A ; Deferred Keyboard + ; Preset $FCB2 (XITVBL) +VTRIGR = $020C ; Soft Trigger +VBRKOP = $020E ; BRK Opcode +VSERIN = $0210 ; Serial in Ready +VSEROR = $0212 ; Serial Out Ready +VSEROC = $0214 ; Serial Output complete +VTIMR1 = $0216 ; Pokey Timer 1 +VTIMR2 = $0218 ; Pokey Timer 2 +VTIMR4 = $021A ; Pokey Timer 4 @@ -84,21 +84,21 @@ VTIMR4 = $021A ;Pokey Timer 4 ; CTIA/GTIA Address Equates ;------------------------------------------------------------------------- -GTIA = $C000 ;CTIA/GTIA area +GTIA = $C000 ; CTIA/GTIA area .include "atari_gtia.inc" ;------------------------------------------------------------------------- ; ANTIC Address Equates ;------------------------------------------------------------------------- -ANTIC = $D400 ;ANTIC area +ANTIC = $D400 ; ANTIC area .include "atari_antic.inc" ;------------------------------------------------------------------------- ; POKEY Address Equates ;------------------------------------------------------------------------- -POKEY = $E800 ;POKEY area +POKEY = $E800 ; POKEY area .include "atari_pokey.inc" @@ -106,11 +106,10 @@ POKEY = $E800 ;POKEY area ; Cartridge Parameters ;------------------------------------------------------------------------- -CARTNM = $BFE8 ;Cartridge Name Area -COPYD = $BFFC ;Copyright Decade in Cart -COPYR = $BFFD ;Copyright Year in Cart +CARTNM = $BFE8 ; Cartridge Name Area +COPYD = $BFFC ; Copyright Decade in Cart +COPYR = $BFFD ; Copyright Year in Cart ; $FF=Diagnostic Cart -GOCART = $BFFE ;Cartridge Start Vector +GOCART = $BFFE ; Cartridge Start Vector - -CHRORG = $F800 ;Character Generator Base +CHRORG = $F800 ; Character Generator Base From bd9208879e723cc663f67559b54d1cb50dd6fa91 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 6 Aug 2017 18:09:40 +0200 Subject: [PATCH 0411/2161] added prototypes and proposed constants --- include/cbm.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/cbm.h b/include/cbm.h index 701924d57..5bb860e4f 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -153,7 +153,13 @@ struct cbm_dirent { unsigned char get_tv (void); /* Return the video mode the machine is using. */ +#define KBDREPEAT_CURSOR 0x00 +#define KBDREPEAT_NONE 0x40 +#define KBDREPEAT_ALL 0x80 +unsigned char kbrepeat(unsigned char); +unsigned char kbrepeatdelay(unsigned char); +unsigned char kbrepeatrate(unsigned char); /*****************************************************************************/ /* CBM kernal functions */ From dafe3c1e3cc3316ff187e4adfd756097865d2ae4 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 6 Aug 2017 20:15:35 +0200 Subject: [PATCH 0412/2161] added documentation for the kbrepeat... functions --- doc/funcref.sgml | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index a2ccf6c73..d7c477958 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -179,6 +179,9 @@ function. <!-- <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="kbrepeat" name="kbrepeat"> +<item><ref id="kbrepeatdelay" name="kbrepeatdelay"> +<item><ref id="kbrepeatrate" name="kbrepeatrate"> </itemize> (incomplete) @@ -2063,6 +2066,70 @@ to get off the serial bus so it can be used for other purposes. </descrip> </quote> +<sect1>kbrepeat<label id="kbrepeat"><p> + +<quote> +<descrip> +<tag/Function/Set keyboard repeat mode +<tag/Header/<tt/<ref id="cbm.h" name="cbm.h">/ +<tag/Declaration/<tt/unsigned char kbrepeat (unsigned char);/ +<tag/Description/This function changes what keys will have automatic repeat when +being hold down for a certain time. Possible values are KBDREPEAT_CURSOR (repeat +only cursor-related keys), KBDREPEAT_NONE (no repeat for any keys) and +KBDREPEAT_ALL (repeat all keys). +The old mode is returned so it can be restored later. +<tag/Notes/<itemize> +<item> +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="kbrepeatdelay" name="kbrepeatdelay"> +<ref id="kbrepeatrate" name="kbrepeatrate"> +<tag/Example/None. +</descrip> +</quote> + +<sect1>kbrepeatdelay<label id="kbrepeatdelay"><p> + +<quote> +<descrip> +<tag/Function/Set keyboard repeat delay +<tag/Header/<tt/<ref id="cbm.h" name="cbm.h">/ +<tag/Declaration/<tt/unsigned char kbrepeatdelay (unsigned char);/ +<tag/Description/This function changes the delay until a keypress is being +repeated automatically. +The old value is returned so it can be restored later. +<tag/Notes/<itemize> +<item> +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="kbrepeat" name="kbrepeat"> +<ref id="kbrepeatrate" name="kbrepeatrate"> +<tag/Example/None. +</descrip> +</quote> + +<sect1>kbrepeatrate<label id="kbrepeatrate"><p> + +<quote> +<descrip> +<tag/Function/Set keyboard repeat rate +<tag/Header/<tt/<ref id="cbm.h" name="cbm.h">/ +<tag/Declaration/<tt/unsigned char kbrepeatrate (unsigned char);/ +<tag/Description/This function changes the keyboard repeat rate (the time between +repeated keypresses). +The old value is returned so it can be restored later. +<tag/Notes/<itemize> +<item> +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="kbrepeat" name="kbrepeat"> +<ref id="kbrepeatdelay" name="kbrepeatdelay"> +<tag/Example/None. +</descrip> +</quote> <sect1>cclear<label id="cclear"><p> From 99e6dd18d680382c7780f0569329a89be386493d Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 6 Aug 2017 20:20:22 +0200 Subject: [PATCH 0413/2161] resolve conflict --- include/cbm.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/cbm.h b/include/cbm.h index 5bb860e4f..cdbd7b886 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -161,6 +161,11 @@ unsigned char kbrepeat(unsigned char); unsigned char kbrepeatdelay(unsigned char); unsigned char kbrepeatrate(unsigned char); +#if !defined(__CBM610__) && !defined(__PET__) +void waitvsync (void); +/* wait for the start of the next frame */ +#endif + /*****************************************************************************/ /* CBM kernal functions */ /*****************************************************************************/ From 7f52a770d9c6a43dde67689032bb3a4848eb6b30 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 19 Aug 2017 19:11:28 +0200 Subject: [PATCH 0414/2161] Removed joy_masks array. So far the joy_masks array allowed several joystick drivers for a single target to each have different joy_read return values. However this meant that every call to joy_read implied an additional joy_masks lookup to post-process the return value. Given that almost all targets only come with a single joystick driver this seems an inappropriate overhead. Therefore now the target header files contain constants matching the return value of the joy_read of the joystick driver(s) on that target. If there indeed are several joystick drivers for a single target they must agree on a common return value for joy_read. In some cases this was alredy the case as there's a "natural" return value for joy_read. However a few joystick drivers need to be adjusted. This may cause some overhead inside the driver. But that is for sure smaller than the overhead introduced by the joy_masks lookup before. !!! ToDo !!! The following three joystick drivers become broken with this commit and need to be adjusted: - atrmj8.s - c64-numpad.s - vic20-stdjoy.s --- asminc/joy-kernel.inc | 1 - include/apple2.h | 8 +++++ include/atari.h | 9 ++++- include/atari5200.h | 9 ++++- include/atmos.h | 9 +++++ include/c128.h | 7 ++++ include/c64.h | 7 ++++ include/cbm.h | 6 ++-- include/cbm264.h | 11 +++++++ include/cbm510.h | 7 ++++ include/creativision.h | 8 +++++ include/em/em-kernel.h | 1 + include/gamate.h | 27 ++++++++++----- include/geos.h | 6 ++++ include/joystick.h | 29 +++++----------- include/joystick/joy-kernel.h | 7 +--- include/lynx.h | 23 ++++++++----- include/nes.h | 31 ++++++++++------- include/pce.h | 33 ++++++++++++------- include/pet.h | 7 ++++ include/vic20.h | 9 +++++ libsrc/apple2/joy/a2.stdjoy.s | 17 ++-------- libsrc/atari/joy/atrstd.s | 11 ------- libsrc/atari5200/joy/atr5200std.s | 13 +------- libsrc/atmos/joy/atmos-pase.s | 11 ------- libsrc/c128/joy/c128-ptvjoy.s | 11 ------- libsrc/c128/joy/c128-stdjoy.s | 11 ------- libsrc/c64/joy/c64-hitjoy.s | 11 ------- libsrc/c64/joy/c64-ptvjoy.s | 11 ------- libsrc/c64/joy/c64-stdjoy.s | 11 ------- libsrc/cbm510/joy/cbm510-std.s | 21 +++--------- libsrc/creativision/joy/creativision-stdjoy.s | 29 +++++----------- libsrc/gamate/joy/gamate-stdjoy.s | 11 ------- libsrc/geos-cbm/joy/geos-stdjoy.s | 11 ------- libsrc/joystick/joy-kernel.s | 22 +++---------- libsrc/lynx/joy/lynx-stdjoy.s | 12 ------- libsrc/nes/joy/nes-stdjoy.s | 11 ------- libsrc/pce/joy/pce-stdjoy.s | 11 ------- libsrc/pet/joy/pet-ptvjoy.s | 11 ------- libsrc/pet/joy/pet-stdjoy.s | 11 ------- libsrc/plus4/joy/plus4-stdjoy.s | 13 +------- libsrc/vic20/joy/vic20-ptvjoy.s | 12 ------- testcode/lib/joy-test.c | 22 ++++++------- testcode/lib/pce/conio.c | 17 +++++----- 44 files changed, 222 insertions(+), 354 deletions(-) diff --git a/asminc/joy-kernel.inc b/asminc/joy-kernel.inc index 4fe5572cf..ba969da1d 100644 --- a/asminc/joy-kernel.inc +++ b/asminc/joy-kernel.inc @@ -43,7 +43,6 @@ ID .byte 3 ; $6A, $6F, $79 ("joy") VERSION .byte 1 ; Interface version LIBREF .addr ; Library reference - MASKS .byte 8 ; Joystick state mask array JUMPTAB .struct INSTALL .addr ; INSTALL routine UNINSTALL .addr ; UNINSTALL routine diff --git a/include/apple2.h b/include/apple2.h index e73023693..421b5db6c 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -91,6 +91,14 @@ #define CH_RTEE '+' #define CH_CROSS '+' +/* 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 APPLE_UNKNOWN 0x00 #define APPLE_II 0x10 /* Apple ][ */ diff --git a/include/atari.h b/include/atari.h index fa99fca20..ca4b2ef26 100644 --- a/include/atari.h +++ b/include/atari.h @@ -149,6 +149,13 @@ #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 +#define JOY_LEFT_MASK 0x04 +#define JOY_RIGHT_MASK 0x08 +#define JOY_BTN_1_MASK 0x10 + /* color register functions */ extern void __fastcall__ _setcolor (unsigned char color_reg, unsigned char hue, unsigned char luminace); extern void __fastcall__ _setcolor_low (unsigned char color_reg, unsigned char color_value); @@ -346,4 +353,4 @@ struct __iocb { #define IOCB_FORMAT 0xFE /* format */ /* End of atari.h */ -#endif /* #ifndef _ATARI_H */ +#endif diff --git a/include/atari5200.h b/include/atari5200.h index 4bd5bc0fd..12c2bb349 100644 --- a/include/atari5200.h +++ b/include/atari5200.h @@ -87,6 +87,13 @@ extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */ #define COLOR_LIGHTBLUE _gtia_mkcolor(HUE_BLUE,6) #define COLOR_GRAY3 _gtia_mkcolor(HUE_GREY,5) +/* 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 + /* get_tv return values */ #define AT_NTSC 0 #define AT_PAL 1 @@ -104,4 +111,4 @@ extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */ #define ANTIC (*(struct __antic*)0xD400) /* End of atari5200.h */ -#endif /* #ifndef _ATARI5200_H */ +#endif diff --git a/include/atmos.h b/include/atmos.h index 72388c974..c642f9e2a 100644 --- a/include/atmos.h +++ b/include/atmos.h @@ -113,6 +113,15 @@ +/* Masks for joy_read */ +#define JOY_UP_MASK 0x10 +#define JOY_DOWN_MASK 0x08 +#define JOY_LEFT_MASK 0x01 +#define JOY_RIGHT_MASK 0x02 +#define JOY_BTN_1_MASK 0x20 + + + /* No support for dynamically loadable drivers */ #define DYN_DRV 0 diff --git a/include/c128.h b/include/c128.h index 565fbc9ce..356140d41 100644 --- a/include/c128.h +++ b/include/c128.h @@ -91,6 +91,13 @@ #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 +#define JOY_LEFT_MASK 0x04 +#define JOY_RIGHT_MASK 0x08 +#define JOY_BTN_1_MASK 0x10 + /* Video mode defines */ #define VIDEOMODE_40x25 0x00 #define VIDEOMODE_80x25 0x80 diff --git a/include/c64.h b/include/c64.h index adf3840b9..eb10600d6 100644 --- a/include/c64.h +++ b/include/c64.h @@ -99,6 +99,13 @@ #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 +#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) diff --git a/include/cbm.h b/include/cbm.h index 27e82f9f3..129b0295b 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -75,10 +75,8 @@ -/* Expanding upon joystick.h */ -#define JOY_FIRE_IDX 4 - -#define JOY_FIRE(v) ((v) & joy_masks[JOY_FIRE_IDX]) +#define JOY_FIRE_MASK JOY_BTN_1_MASK +#define JOY_FIRE(v) ((v) & JOY_FIRE_MASK) diff --git a/include/cbm264.h b/include/cbm264.h index ff7468d30..46fa64050 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -112,6 +112,17 @@ #define COLOR_LIGHTBLUE (BCOLOR_LIGHTBLUE | CATTR_LUMA7) #define COLOR_GRAY3 (BCOLOR_WHITE | CATTR_LUMA5) + + +/* 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 0x80 + + + /* Define hardware */ #include <_ted.h> #define TED (*(struct __ted*)0xFF00) diff --git a/include/cbm510.h b/include/cbm510.h index 25ea07540..3d6ccd209 100644 --- a/include/cbm510.h +++ b/include/cbm510.h @@ -92,6 +92,13 @@ #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*)0xD800) diff --git a/include/creativision.h b/include/creativision.h index 5cc99b7af..a97109029 100644 --- a/include/creativision.h +++ b/include/creativision.h @@ -40,6 +40,14 @@ #define CH_LLCORNER 37 #define CH_LRCORNER 38 +/* Masks for joy_read */ +#define JOY_UP_MASK 0x10 +#define JOY_DOWN_MASK 0x04 +#define JOY_LEFT_MASK 0x20 +#define JOY_RIGHT_MASK 0x08 +#define JOY_BTN_1_MASK 0x01 +#define JOY_BTN_2_MASK 0x02 + /* no support for dynamically loadable drivers */ #define DYN_DRV 0 diff --git a/include/em/em-kernel.h b/include/em/em-kernel.h index e5df80321..a1ce9a253 100644 --- a/include/em/em-kernel.h +++ b/include/em/em-kernel.h @@ -52,6 +52,7 @@ typedef struct { /* Driver header */ char id[3]; /* Contains 0x65, 0x6d, 0x64 ("emd") */ unsigned char version; /* Interface version */ + void* /* Library reference */ /* Jump vectors. Note that these are not C callable */ void* install; /* INSTALL routine */ diff --git a/include/gamate.h b/include/gamate.h index 7355ede84..0af21623d 100644 --- a/include/gamate.h +++ b/include/gamate.h @@ -170,16 +170,25 @@ /* No support for dynamically loadable drivers */ #define DYN_DRV 0 -/* Expanding upon joystick.h */ -#define JOY_BTN_A_IDX 4 -#define JOY_BTN_B_IDX 5 -#define JOY_START_IDX 6 -#define JOY_SELECT_IDX 7 +/* 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 JOY_BTN_2_MASK 0x20 +#define JOY_BTN_3_MASK 0x40 +#define JOY_BTN_4_MASK 0x80 -#define JOY_BTN_A(v) ((v) & joy_masks[JOY_BTN_A_IDX]) -#define JOY_BTN_B(v) ((v) & joy_masks[JOY_BTN_B_IDX]) -#define JOY_START(v) ((v) & joy_masks[JOY_START_IDX]) -#define JOY_SELECT(v) ((v) & joy_masks[JOY_SELECT_IDX]) +#define JOY_BTN_A_MASK JOY_BTN_1_MASK +#define JOY_BTN_B_MASk JOY_BTN_2_MASK +#define JOY_START_MASK JOY_BTN_3_MASK +#define JOY_SELECT_MASK JOY_BTN_4_MASK + +#define JOY_BTN_A(v) ((v) & JOY_BTN_A_MASK) +#define JOY_BTN_B(v) ((v) & JOY_BTN_B_MASK) +#define JOY_START(v) ((v) & JOY_START_MASK) +#define JOY_SELECT(v) ((v) & JOY_SELECT_MASK) /* The addresses of the static drivers */ extern void gamate_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ diff --git a/include/geos.h b/include/geos.h index 65b85cd59..ae356d679 100644 --- a/include/geos.h +++ b/include/geos.h @@ -133,6 +133,12 @@ #define TGI_COLOR_LIGHTBLUE COLOR_LIGHTBLUE #define TGI_COLOR_GRAY3 COLOR_GRAY3 +#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 + /* End of geos.h */ #endif diff --git a/include/joystick.h b/include/joystick.h index 27c4af81a..26f339fe4 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -55,28 +55,15 @@ #define JOY_1 0 #define JOY_2 1 -/* The following codes are *indices* into the joy_masks array */ -#define JOY_UP_IDX 0 -#define JOY_DOWN_IDX 1 -#define JOY_LEFT_IDX 2 -#define JOY_RIGHT_IDX 3 -#define JOY_BTN_1_IDX 4 /* Universally available */ -#define JOY_BTN_2_IDX 5 /* Second button if available */ -#define JOY_BTN_3_IDX 6 /* Third button if available */ -#define JOY_BTN_4_IDX 7 /* Fourth button if available */ - -/* Array of masks used to check the return value of joy_read for a state */ -extern const unsigned char joy_masks[8]; - /* Macros that evaluate the return code of joy_read */ -#define JOY_UP(v) ((v) & joy_masks[JOY_UP_IDX]) -#define JOY_DOWN(v) ((v) & joy_masks[JOY_DOWN_IDX]) -#define JOY_LEFT(v) ((v) & joy_masks[JOY_LEFT_IDX]) -#define JOY_RIGHT(v) ((v) & joy_masks[JOY_RIGHT_IDX]) -#define JOY_BTN_1(v) ((v) & joy_masks[JOY_BTN_1_IDX]) -#define JOY_BTN_2(v) ((v) & joy_masks[JOY_BTN_2_IDX]) -#define JOY_BTN_3(v) ((v) & joy_masks[JOY_BTN_3_IDX]) -#define JOY_BTN_4(v) ((v) & joy_masks[JOY_BTN_4_IDX]) +#define JOY_UP(v) ((v) & JOY_UP_MASK) +#define JOY_DOWN(v) ((v) & JOY_DOWN_MASK) +#define JOY_LEFT(v) ((v) & JOY_LEFT_MASK) +#define JOY_RIGHT(v) ((v) & JOY_RIGHT_MASK) +#define JOY_BTN_1(v) ((v) & JOY_BTN_1_MASK) /* Universally available */ +#define JOY_BTN_2(v) ((v) & JOY_BTN_2_MASK) /* Second button if available */ +#define JOY_BTN_3(v) ((v) & JOY_BTN_3_MASK) /* Third button if available */ +#define JOY_BTN_4(v) ((v) & JOY_BTN_4_MASK) /* Fourth button if available */ /* The name of the standard joystick driver for a platform */ extern const char joy_stddrv[]; diff --git a/include/joystick/joy-kernel.h b/include/joystick/joy-kernel.h index bb571de3d..cec2633ab 100644 --- a/include/joystick/joy-kernel.h +++ b/include/joystick/joy-kernel.h @@ -52,9 +52,7 @@ typedef struct { /* Driver header */ char id[3]; /* Contains 0x6a, 0x6f, 0x79 ("joy") */ unsigned char version; /* Interface version */ - - /* Bitmasks for the joystick states. See joystick.h for indices */ - unsigned char masks[8]; + void* /* Library reference */ /* Jump vectors. Note that these are not C callable */ void* install; /* INSTALL routine */ @@ -85,6 +83,3 @@ void joy_clear_ptr (void); /* End of joy-kernel.h */ #endif - - - diff --git a/include/lynx.h b/include/lynx.h index c30ca6265..3629f322e 100644 --- a/include/lynx.h +++ b/include/lynx.h @@ -87,20 +87,25 @@ #define TGI_COLOR_LIGHTBLUE COLOR_LIGHTBLUE #define TGI_COLOR_WHITE COLOR_WHITE +/* Masks for joy_read */ +#define JOY_UP_MASK 0x80 +#define JOY_DOWN_MASK 0x40 +#define JOY_LEFT_MASK 0x20 +#define JOY_RIGHT_MASK 0x10 +#define JOY_BTN_1_MASK 0x01 +#define JOY_BTN_2_MASK 0x02 + +#define JOY_BTN_A_MASK JOY_BTN_1_MASK +#define JOY_BTN_B_MASK JOY_BTN_2_MASK + +#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 -/* Expanding upon joystick.h */ -#define JOY_BTN_A_IDX 4 -#define JOY_BTN_B_IDX 5 - -#define JOY_BTN_A(v) ((v) & joy_masks[JOY_BTN_A_IDX]) -#define JOY_BTN_B(v) ((v) & joy_masks[JOY_BTN_B_IDX]) - - - /*****************************************************************************/ /* Variables */ /*****************************************************************************/ diff --git a/include/nes.h b/include/nes.h index 0b65cdbe4..217a90779 100644 --- a/include/nes.h +++ b/include/nes.h @@ -82,6 +82,26 @@ #define COLOR_LIGHTBLUE 0x0E #define COLOR_GRAY3 0x0F +/* Masks for joy_read */ +#define JOY_UP_MASK 0x10 +#define JOY_DOWN_MASK 0x20 +#define JOY_LEFT_MASK 0x40 +#define JOY_RIGHT_MASK 0x80 +#define JOY_BTN_1_MASK 0x01 +#define JOY_BTN_2_MASK 0x02 +#define JOY_BTN_3_MASK 0x04 +#define JOY_BTN_4_MASK 0x08 + +#define JOY_BTN_A_MASK JOY_BTN_1_MASK +#define JOY_BTN_B_MASK JOY_BTN_2_MASK +#define JOY_SELECT_MASK JOY_BTN_3_MASK +#define JOY_START_MASK JOY_BTN_4_MASK + +#define JOY_BTN_A(v) ((v) & JOY_BTN_A_MASK) +#define JOY_BTN_B(v) ((v) & JOY_BTN_B_MASK) +#define JOY_SELECT(v) ((v) & JOY_SELECT_MASK) +#define JOY_START(v) ((v) & JOY_START_MASK) + /* Return codes of get_tv */ #define TV_NTSC 0 #define TV_PAL 1 @@ -90,17 +110,6 @@ /* No support for dynamically loadable drivers */ #define DYN_DRV 0 -/* Expanding upon joystick.h */ -#define JOY_BTN_A_IDX 4 -#define JOY_BTN_B_IDX 5 -#define JOY_SELECT_IDX 6 -#define JOY_START_IDX 7 - -#define JOY_BTN_A(v) ((v) & joy_masks[JOY_BTN_A_IDX]) -#define JOY_BTN_B(v) ((v) & joy_masks[JOY_BTN_B_IDX]) -#define JOY_SELECT(v) ((v) & joy_masks[JOY_SELECT_IDX]) -#define JOY_START(v) ((v) & joy_masks[JOY_START_IDX]) - /* Define hardware */ /* Picture Processing Unit */ diff --git a/include/pce.h b/include/pce.h index 12b596cf9..7744d0148 100644 --- a/include/pce.h +++ b/include/pce.h @@ -73,19 +73,28 @@ #define TV_PAL 1 #define TV_OTHER 2 +/* Masks for joy_read */ +#define JOY_UP_MASK 0x10 +#define JOY_DOWN_MASK 0x40 +#define JOY_LEFT_MASK 0x80 +#define JOY_RIGHT_MASK 0x20 +#define JOY_BTN_1_MASK 0x01 +#define JOY_BTN_2_MASK 0x02 +#define JOY_BTN_3_MASK 0x04 +#define JOY_BTN_4_MASK 0x08 + +#define JOY_BTN_I_MASK JOY_BTN_1_MASK +#define JOY_BTN_II_MASK JOY_BTN_2_MASK +#define JOY_SELECT_MASK JOY_BTN_3_MASK +#define JOY_RUN_MASK JOY_BTN_4_MASK + +#define JOY_BTN_I(v) ((v) & JOY_BTN_I_MASK) +#define JOY_BTN_II(v) ((v) & JOY_BTN_II_MASK) +#define JOY_SELECT(v) ((v) & JOY_SELECT_MASK) +#define JOY_RUN(v) ((v) & JOY_RUN_MASK) + /* No support for dynamically loadable drivers */ -#define DYN_DRV 0 - -/* Expanding upon joystick.h */ -#define JOY_BTN_I_IDX 4 -#define JOY_BTN_II_IDX 5 -#define JOY_SELECT_IDX 6 -#define JOY_RUN_IDX 7 - -#define JOY_BTN_I(v) ((v) & joy_masks[JOY_BTN_I_IDX]) -#define JOY_BTN_II(v) ((v) & joy_masks[JOY_BTN_II_IDX]) -#define JOY_SELECT(v) ((v) & joy_masks[JOY_SELECT_IDX]) -#define JOY_RUN(v) ((v) & joy_masks[JOY_RUN_IDX]) +#define DYN_DRV 0 /* The addresses of the static drivers */ extern void pce_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ diff --git a/include/pet.h b/include/pet.h index 720e40a78..e9659d524 100644 --- a/include/pet.h +++ b/include/pet.h @@ -55,6 +55,13 @@ #define COLOR_BLACK 0x00 #define COLOR_WHITE 0x01 +/* 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 <_pia.h> #define PIA1 (*(struct __pia*)0xE810) diff --git a/include/vic20.h b/include/vic20.h index c675de6d2..c6ad9632d 100644 --- a/include/vic20.h +++ b/include/vic20.h @@ -77,6 +77,15 @@ +/* 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 <_vic.h> #define VIC (*(struct __vic*)0x9000) diff --git a/libsrc/apple2/joy/a2.stdjoy.s b/libsrc/apple2/joy/a2.stdjoy.s index e4097e043..ed2083255 100644 --- a/libsrc/apple2/joy/a2.stdjoy.s +++ b/libsrc/apple2/joy/a2.stdjoy.s @@ -46,17 +46,6 @@ PREAD := $FB1E ; Read paddle in X, return AD conv. value in Y .addr $0000 -; Button state masks (8 values) - - .byte $10 - .byte $20 - .byte $04 - .byte $08 - .byte $40 - .byte $80 - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table .addr INSTALL @@ -119,7 +108,7 @@ READJOY: lda BUTN0-1,x ; Check button (1, 3) asl tya - ror ; FIRE DOWN !UP RIGHT !LEFT 0 0 0 + ror ; BTN DOWN !UP RIGHT !LEFT 0 0 0 ; Read secondary button tay @@ -130,10 +119,10 @@ READJOY: lda BUTN0-1,x ; Check button (2, 0) asl tya - ror ; FIRE2 FIRE DOWN !UP RIGHT !LEFT 0 0 + ror ; BTN2 BTN DOWN !UP RIGHT !LEFT 0 0 ; Finalize - eor #%00010100 ; FIRE2 FIRE DOWN UP RIGHT LEFT 0 0 + eor #%00010100 ; BTN2 BTN DOWN UP RIGHT LEFT 0 0 ldx #$00 bit $C080 ; Switch in LC bank 2 for R/O rts diff --git a/libsrc/atari/joy/atrstd.s b/libsrc/atari/joy/atrstd.s index fc7aa55f4..0c8799e21 100644 --- a/libsrc/atari/joy/atrstd.s +++ b/libsrc/atari/joy/atrstd.s @@ -34,17 +34,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $01 ; JOY_UP - .byte $02 ; JOY_DOWN - .byte $04 ; JOY_LEFT - .byte $08 ; JOY_RIGHT - .byte $10 ; JOY_FIRE - .byte $00 ; JOY_FIRE2 not available - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL diff --git a/libsrc/atari5200/joy/atr5200std.s b/libsrc/atari5200/joy/atr5200std.s index 3483cc11a..0b8b93b63 100644 --- a/libsrc/atari5200/joy/atr5200std.s +++ b/libsrc/atari5200/joy/atr5200std.s @@ -27,17 +27,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $01 ; JOY_UP - .byte $02 ; JOY_DOWN - .byte $04 ; JOY_LEFT - .byte $08 ; JOY_RIGHT - .byte $10 ; JOY_FIRE - .byte $20 ; JOY_FIRE2 - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL @@ -99,7 +88,7 @@ READJOY: lda #0 ; Initialize return value cmp TRIG0,y bne @notrg - lda #$10 ; JOY_FIRE + lda #$10 ; JOY_BTN ; Read joystick diff --git a/libsrc/atmos/joy/atmos-pase.s b/libsrc/atmos/joy/atmos-pase.s index 26d7c74d8..637571c04 100644 --- a/libsrc/atmos/joy/atmos-pase.s +++ b/libsrc/atmos/joy/atmos-pase.s @@ -28,17 +28,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $10 ; JOY_UP - .byte $08 ; JOY_DOWN - .byte $01 ; JOY_LEFT - .byte $02 ; JOY_RIGHT - .byte $20 ; JOY_FIRE - .byte $00 ; Future expansion - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL diff --git a/libsrc/c128/joy/c128-ptvjoy.s b/libsrc/c128/joy/c128-ptvjoy.s index 6f65ce5eb..c9ae39a47 100644 --- a/libsrc/c128/joy/c128-ptvjoy.s +++ b/libsrc/c128/joy/c128-ptvjoy.s @@ -30,17 +30,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $01 ; JOY_UP - .byte $02 ; JOY_DOWN - .byte $04 ; JOY_LEFT - .byte $08 ; JOY_RIGHT - .byte $10 ; JOY_FIRE - .byte $00 ; JOY_FIRE2 unavailable - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL diff --git a/libsrc/c128/joy/c128-stdjoy.s b/libsrc/c128/joy/c128-stdjoy.s index a2caead1a..943361da5 100644 --- a/libsrc/c128/joy/c128-stdjoy.s +++ b/libsrc/c128/joy/c128-stdjoy.s @@ -30,17 +30,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $01 ; JOY_UP - .byte $02 ; JOY_DOWN - .byte $04 ; JOY_LEFT - .byte $08 ; JOY_RIGHT - .byte $10 ; JOY_FIRE - .byte $00 ; JOY_FIRE2 unavailable - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL diff --git a/libsrc/c64/joy/c64-hitjoy.s b/libsrc/c64/joy/c64-hitjoy.s index a798100a7..10c936399 100644 --- a/libsrc/c64/joy/c64-hitjoy.s +++ b/libsrc/c64/joy/c64-hitjoy.s @@ -29,17 +29,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $01 ; JOY_UP - .byte $02 ; JOY_DOWN - .byte $04 ; JOY_LEFT - .byte $08 ; JOY_RIGHT - .byte $10 ; JOY_FIRE - .byte $00 ; JOY_FIRE2 unavailable - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL diff --git a/libsrc/c64/joy/c64-ptvjoy.s b/libsrc/c64/joy/c64-ptvjoy.s index 31850488c..e916d887a 100644 --- a/libsrc/c64/joy/c64-ptvjoy.s +++ b/libsrc/c64/joy/c64-ptvjoy.s @@ -29,17 +29,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $01 ; JOY_UP - .byte $02 ; JOY_DOWN - .byte $04 ; JOY_LEFT - .byte $08 ; JOY_RIGHT - .byte $10 ; JOY_FIRE - .byte $00 ; JOY_FIRE2 unavailable - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL diff --git a/libsrc/c64/joy/c64-stdjoy.s b/libsrc/c64/joy/c64-stdjoy.s index 2932c77fd..930ad6227 100644 --- a/libsrc/c64/joy/c64-stdjoy.s +++ b/libsrc/c64/joy/c64-stdjoy.s @@ -29,17 +29,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $01 ; JOY_UP - .byte $02 ; JOY_DOWN - .byte $04 ; JOY_LEFT - .byte $08 ; JOY_RIGHT - .byte $10 ; JOY_FIRE - .byte $00 ; JOY_FIRE2 unavailable - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL diff --git a/libsrc/cbm510/joy/cbm510-std.s b/libsrc/cbm510/joy/cbm510-std.s index 7133f9379..0c2efc12d 100644 --- a/libsrc/cbm510/joy/cbm510-std.s +++ b/libsrc/cbm510/joy/cbm510-std.s @@ -30,17 +30,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $01 ; JOY_UP - .byte $02 ; JOY_DOWN - .byte $04 ; JOY_LEFT - .byte $08 ; JOY_RIGHT - .byte $10 ; JOY_FIRE - .byte $00 ; JOY_FIRE2 unavailable - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL @@ -105,7 +94,7 @@ READ: ldx #$0F ; Switch to the system bank lda (cia2),y ; Read joystick inputs sta tmp1 -; Get the fire bits +; Get the push button bits ldy #CIA::PRA lda (cia2),y @@ -115,12 +104,12 @@ READ: ldx #$0F ; Switch to the system bank cpx #$00 ; Joystick 0? bne @L1 ; Jump if no -; Joystick 1, fire is in bit 6, direction in bit 0-3 +; Joystick 1, push button is in bit 6, direction in bit 0-3 asl a jmp @L2 -; Joystick 2, fire is in bit 7, direction in bit 5-7 +; Joystick 2, push button is in bit 7, direction in bit 5-7 @L1: ldx #$00 ; High byte of return value lsr tmp1 @@ -128,9 +117,9 @@ READ: ldx #$0F ; Switch to the system bank lsr tmp1 lsr tmp1 -; Mask the relavant bits, get the fire bit +; Mask the relavant bits, get the push button bit -@L2: asl a ; Fire bit into carry +@L2: asl a ; push button bit into carry lda tmp1 and #$0F bcc @L3 diff --git a/libsrc/creativision/joy/creativision-stdjoy.s b/libsrc/creativision/joy/creativision-stdjoy.s index 3f167464a..9a5afc42b 100644 --- a/libsrc/creativision/joy/creativision-stdjoy.s +++ b/libsrc/creativision/joy/creativision-stdjoy.s @@ -27,26 +27,6 @@ .addr $0000 -; Symbolic names for joystick masks (similar names like the defines in joystick.h, but not related to them) - -JOY_UP = $10 -JOY_DOWN = $04 -JOY_LEFT = $20 -JOY_RIGHT = $08 -JOY_FIRE = $01 -JOY_FIRE2 = $02 - -; Joystick state masks (8 values) - - .byte JOY_UP - .byte JOY_DOWN - .byte JOY_LEFT - .byte JOY_RIGHT - .byte JOY_FIRE - .byte JOY_FIRE2 - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL @@ -60,6 +40,13 @@ JOY_FIRE2 = $02 JOY_COUNT = 2 ; Number of joysticks we support +; Symbolic names for joystick masks (similar names like the defines in joystick.h, but not related to them) + +JOY_UP = $10 +JOY_DOWN = $04 +JOY_LEFT = $20 +JOY_RIGHT = $08 + ; ------------------------------------------------------------------------ ; Code @@ -129,7 +116,7 @@ convert: ; values were shifted to the right to be identical). ; Why are there two bits indicating a pressed trigger? ; According to the "Second book of programs for the Dick Smith Wizard" -; (pg. 88ff), the left hand fire button gives the value of +; (pg. 88ff), the left hand button gives the value of ; %00010001 and the right hand button gives %00100010 ; Why two bits? Can there be cases that just one of those bits is set? ; Until these questions have been answered, we only use the lower two diff --git a/libsrc/gamate/joy/gamate-stdjoy.s b/libsrc/gamate/joy/gamate-stdjoy.s index 8b18bae7a..d10eb6f41 100644 --- a/libsrc/gamate/joy/gamate-stdjoy.s +++ b/libsrc/gamate/joy/gamate-stdjoy.s @@ -24,17 +24,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $01 ; JOY_UP - .byte $02 ; JOY_DOWN - .byte $04 ; JOY_LEFT - .byte $08 ; JOY_RIGHT - .byte $10 ; JOY_FIRE_A - .byte $20 ; JOY_FIRE_B - .byte $80 ; JOY_SELECT - .byte $40 ; JOY_START - ; Jump table. .addr INSTALL diff --git a/libsrc/geos-cbm/joy/geos-stdjoy.s b/libsrc/geos-cbm/joy/geos-stdjoy.s index 6afe46092..2787cb594 100644 --- a/libsrc/geos-cbm/joy/geos-stdjoy.s +++ b/libsrc/geos-cbm/joy/geos-stdjoy.s @@ -28,17 +28,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $01 ; JOY_UP - .byte $02 ; JOY_DOWN - .byte $04 ; JOY_LEFT - .byte $08 ; JOY_RIGHT - .byte $10 ; JOY_FIRE - .byte $00 ; Future expansion - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .word INSTALL diff --git a/libsrc/joystick/joy-kernel.s b/libsrc/joystick/joy-kernel.s index 2b1dcf884..0746709e9 100644 --- a/libsrc/joystick/joy-kernel.s +++ b/libsrc/joystick/joy-kernel.s @@ -19,8 +19,6 @@ .bss _joy_drv: .res 2 ; Pointer to driver -_joy_masks: .res .sizeof(JOY_HDR::MASKS) - ; Jump table for the driver functions. .data joy_vectors: @@ -65,38 +63,28 @@ _joy_install: lda #>joy_libref sta (ptr1),y -; Copy the mask array - - ldy #JOY_HDR::MASKS + .sizeof(JOY_HDR::MASKS) - 1 - ldx #.sizeof(JOY_HDR::MASKS)-1 -@L1: lda (ptr1),y - sta _joy_masks,x - dey - dex - bpl @L1 - ; Copy the jump vectors ldy #JOY_HDR::JUMPTAB ldx #0 -@L2: inx ; Skip the JMP opcode +@L1: inx ; Skip the JMP opcode jsr copy ; Copy one byte jsr copy ; Copy one byte cpy #(JOY_HDR::JUMPTAB + .sizeof(JOY_HDR::JUMPTAB)) - bne @L2 + bne @L1 jsr joy_install ; Call driver install routine tay ; Test error code - bne @L3 ; Bail out if install had errors + bne @L2 ; Bail out if install had errors ; Install the IRQ vector if the driver needs it. A/X contains the error code ; from joy_install, so don't use it. ldy joy_irq+2 ; Check high byte of IRQ vector - beq @L3 ; Jump if vector invalid + beq @L2 ; Jump if vector invalid ldy #$4C ; JMP opcode sty joy_irq ; Activate IRQ routine -@L3: rts +@L2: rts ; Driver signature invalid diff --git a/libsrc/lynx/joy/lynx-stdjoy.s b/libsrc/lynx/joy/lynx-stdjoy.s index 114647072..2e91cc43b 100644 --- a/libsrc/lynx/joy/lynx-stdjoy.s +++ b/libsrc/lynx/joy/lynx-stdjoy.s @@ -31,18 +31,6 @@ .addr $0000 -; Button state masks (8 values) - -joy_mask: - .byte $80 ; JOY_UP - .byte $40 ; JOY_DOWN - .byte $20 ; JOY_LEFT - .byte $10 ; JOY_RIGHT - .byte $01 ; JOY_FIRE - .byte $02 ; JOY_FIRE1 - .byte $00 ; - .byte $00 ; - ; Jump table. .addr INSTALL diff --git a/libsrc/nes/joy/nes-stdjoy.s b/libsrc/nes/joy/nes-stdjoy.s index b5e653c16..3032e9330 100644 --- a/libsrc/nes/joy/nes-stdjoy.s +++ b/libsrc/nes/joy/nes-stdjoy.s @@ -29,17 +29,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $10 ; JOY_UP - .byte $20 ; JOY_DOWN - .byte $40 ; JOY_LEFT - .byte $80 ; JOY_RIGHT - .byte $01 ; JOY_FIRE (A) - .byte $02 ; JOY_FIRE2 (B) - .byte $04 ; (Select) - .byte $08 ; (Start) - ; Jump table. .addr INSTALL diff --git a/libsrc/pce/joy/pce-stdjoy.s b/libsrc/pce/joy/pce-stdjoy.s index 746929dd2..ab25134dd 100644 --- a/libsrc/pce/joy/pce-stdjoy.s +++ b/libsrc/pce/joy/pce-stdjoy.s @@ -24,17 +24,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $10 ; JOY_UP - .byte $40 ; JOY_DOWN - .byte $80 ; JOY_LEFT - .byte $20 ; JOY_RIGHT - .byte $01 ; JOY_FIRE_A - .byte $02 ; JOY_FIRE_B - .byte $04 ; JOY_SELECT - .byte $08 ; JOY_RUN - ; Jump table. .addr INSTALL diff --git a/libsrc/pet/joy/pet-ptvjoy.s b/libsrc/pet/joy/pet-ptvjoy.s index 229055fcb..3bb368355 100644 --- a/libsrc/pet/joy/pet-ptvjoy.s +++ b/libsrc/pet/joy/pet-ptvjoy.s @@ -28,17 +28,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $01 ; JOY_UP - .byte $02 ; JOY_DOWN - .byte $04 ; JOY_LEFT - .byte $08 ; JOY_RIGHT - .byte $10 ; JOY_FIRE - .byte $00 ; JOY_FIRE2 unavailable - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL diff --git a/libsrc/pet/joy/pet-stdjoy.s b/libsrc/pet/joy/pet-stdjoy.s index 5847c2b09..29c6de627 100644 --- a/libsrc/pet/joy/pet-stdjoy.s +++ b/libsrc/pet/joy/pet-stdjoy.s @@ -27,17 +27,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $01 ; JOY_UP - .byte $02 ; JOY_DOWN - .byte $04 ; JOY_LEFT - .byte $08 ; JOY_RIGHT - .byte $10 ; JOY_FIRE - .byte $00 ; JOY_FIRE2 unavailable - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL diff --git a/libsrc/plus4/joy/plus4-stdjoy.s b/libsrc/plus4/joy/plus4-stdjoy.s index 4a5132887..d998b2699 100644 --- a/libsrc/plus4/joy/plus4-stdjoy.s +++ b/libsrc/plus4/joy/plus4-stdjoy.s @@ -31,17 +31,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $01 ; JOY_UP - .byte $02 ; JOY_DOWN - .byte $04 ; JOY_LEFT - .byte $08 ; JOY_RIGHT - .byte $80 ; JOY_FIRE - .byte $00 ; JOY_FIRE2 unavailable - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL @@ -107,7 +96,7 @@ READ: ldy #%11111011 ; Load index for joystick #1 cli eor #%11111111 -; The fire buttons are in bits 6 and 7. Both of them cannot be %1 together. +; The push buttons are in bits 6 and 7. Both of them cannot be %1 together. ; Therefore, bit 6 can be merged with bit 7. clc diff --git a/libsrc/vic20/joy/vic20-ptvjoy.s b/libsrc/vic20/joy/vic20-ptvjoy.s index cdd4c274f..07c979443 100644 --- a/libsrc/vic20/joy/vic20-ptvjoy.s +++ b/libsrc/vic20/joy/vic20-ptvjoy.s @@ -30,17 +30,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $01 ; JOY_UP - .byte $02 ; JOY_DOWN - .byte $04 ; JOY_LEFT - .byte $08 ; JOY_RIGHT - .byte $10 ; JOY_FIRE - .byte $00 ; JOY_FIRE2 unavailable - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL @@ -152,4 +141,3 @@ joy3: lda #$00 ; via port B read/write ldx #0 rts - diff --git a/testcode/lib/joy-test.c b/testcode/lib/joy-test.c index fc751ebdc..fdd83bb4e 100644 --- a/testcode/lib/joy-test.c +++ b/testcode/lib/joy-test.c @@ -58,21 +58,19 @@ int main (void) #if defined(__ATARI5200__) || defined(__CREATIVISION__) cprintf ("%1d:%-3s%-3s%-3s%-3s%-3s%-3s", i, - (j & joy_masks[JOY_UP])? " U " : " ", - (j & joy_masks[JOY_DOWN])? " D " : " ", - (j & joy_masks[JOY_LEFT])? " L " : " ", - (j & joy_masks[JOY_RIGHT])? " R " : " ", - (j & joy_masks[JOY_FIRE])? " 1 " : " ", - (j & joy_masks[JOY_FIRE2])? " 2 " : " "); + JOY_UP(j)? " U " : " - ", + JOY_DOWN(j)? " D " : " - ", + JOY_LEFT(j)? " L " : " - ", + JOY_RIGHT(j)? " R " : " - ", + JOY_BTN_1(j)? " 1 " : " - "); #else cprintf ("%2d: %-6s%-6s%-6s%-6s%-6s%-6s", i, - (j & joy_masks[JOY_UP])? " up " : " ---- ", - (j & joy_masks[JOY_DOWN])? " down " : " ---- ", - (j & joy_masks[JOY_LEFT])? " left " : " ---- ", - (j & joy_masks[JOY_RIGHT])? "right " : " ---- ", - (j & joy_masks[JOY_FIRE])? " fire " : " ---- ", - (j & joy_masks[JOY_FIRE2])? "fire2 " : " ---- "); + JOY_UP(j)? " up " : " ---- ", + JOY_DOWN(j)? " down " : " ---- ", + JOY_LEFT(j)? " left " : " ---- ", + JOY_RIGHT(j)? "right " : " ---- ", + JOY_BTN_1(j)? "button" : " ---- "); #endif } } diff --git a/testcode/lib/pce/conio.c b/testcode/lib/pce/conio.c index 00ae3c157..ed3f86240 100644 --- a/testcode/lib/pce/conio.c +++ b/testcode/lib/pce/conio.c @@ -1,3 +1,4 @@ +#include <pce.h> #include <conio.h> #include <time.h> #include <joystick.h> @@ -97,14 +98,14 @@ void main(void) j = joy_read (i); cprintf ("pad %d: %02x %-6s%-6s%-6s%-6s%-6s%-6s%-6s%-6s", i, j, - (j & joy_masks[JOY_UP])? " up " : " ---- ", - (j & joy_masks[JOY_DOWN])? " down " : " ---- ", - (j & joy_masks[JOY_LEFT])? " left " : " ---- ", - (j & joy_masks[JOY_RIGHT])? "right " : " ---- ", - (j & joy_masks[JOY_FIRE])? " fire " : " ---- ", - (j & joy_masks[JOY_FIRE2])? "fire2 " : " ---- ", - (j & joy_masks[JOY_SELECT])? "select" : " ---- ", - (j & joy_masks[JOY_RUN])? " run " : " ---- "); + JOY_UP(j)? " up " : " ---- ", + JOY_DOWN(j)? " down " : " ---- ", + JOY_LEFT(j)? " left " : " ---- ", + JOY_RIGHT(j)? "right " : " ---- ", + JOY_BTN_I(j)? "btn I " : " ---- ", + JOY_BTN_II(j)? "btn II" : " ---- ", + JOY_SELECT(j)? "select" : " ---- ", + JOY_RUN(j)? " run " : " ---- "); } gotoxy(xsize - 10, 3); From 960957075ff828c51d0150a8bd5d6da213db431e Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 19 Aug 2017 19:14:24 +0200 Subject: [PATCH 0415/2161] use fastcall --- include/cbm.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/cbm.h b/include/cbm.h index d15ec5381..a1734d41a 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -164,9 +164,9 @@ unsigned char get_tv (void); #define KBDREPEAT_NONE 0x40 #define KBDREPEAT_ALL 0x80 -unsigned char kbrepeat(unsigned char); -unsigned char kbrepeatdelay(unsigned char); -unsigned char kbrepeatrate(unsigned char); +unsigned char __fastcall__ kbrepeat(unsigned char); +unsigned char __fastcall__ kbrepeatdelay(unsigned char); +unsigned char __fastcall__ kbrepeatrate(unsigned char); #if !defined(__CBM610__) && !defined(__PET__) void waitvsync (void); From 3c3558892e75a7a44a36eaf566fbad3fb903b221 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 19 Aug 2017 19:16:31 +0200 Subject: [PATCH 0416/2161] add note on fastcall --- doc/funcref.sgml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 8e6b1b153..f866dea5f 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -2181,7 +2181,8 @@ only cursor-related keys), KBDREPEAT_NONE (no repeat for any keys) and KBDREPEAT_ALL (repeat all keys). The old mode is returned so it can be restored later. <tag/Notes/<itemize> -<item> +<item>The function is available only as a fastcall function; so, it may be used +only in the presence of a prototype. </itemize> <tag/Availability/cc65 <tag/See also/ @@ -2202,7 +2203,8 @@ The old mode is returned so it can be restored later. repeated automatically. The old value is returned so it can be restored later. <tag/Notes/<itemize> -<item> +<item>The function is available only as a fastcall function; so, it may be used +only in the presence of a prototype. </itemize> <tag/Availability/cc65 <tag/See also/ @@ -2223,7 +2225,8 @@ The old value is returned so it can be restored later. repeated keypresses). The old value is returned so it can be restored later. <tag/Notes/<itemize> -<item> +<item>The function is available only as a fastcall function; so, it may be used +only in the presence of a prototype. </itemize> <tag/Availability/cc65 <tag/See also/ From 0c54a19a0b482e5498c0c95ab1588731d34623d4 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 20 Aug 2017 11:49:02 +0200 Subject: [PATCH 0417/2161] Adjusted to recent driver interface change. The change is inspired by the code of the standard joystick driver. It is however absolutely untested. Note: Sites like http://raster.atariportal.cz/english.htm state that there needs to be a delay when reading joysticks via the MultiJoy adapter. There's no such delay in the driver. But I don't dare to decide to add it. --- libsrc/atari/joy/atrmj8.s | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/libsrc/atari/joy/atrmj8.s b/libsrc/atari/joy/atrmj8.s index 46766070b..0e8cd2a0a 100644 --- a/libsrc/atari/joy/atrmj8.s +++ b/libsrc/atari/joy/atrmj8.s @@ -35,17 +35,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $02 ; JOY_UP - .byte $04 ; JOY_DOWN - .byte $08 ; JOY_LEFT - .byte $10 ; JOY_RIGHT - .byte $01 ; JOY_FIRE - .byte $00 ; JOY_FIRE2 not available - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL @@ -115,10 +104,12 @@ READJOY: ; Read joystick - lda PORTA ; get position - and #%00001111 + lda STRIG0 ; get button asl a - ora TRIG0 ; add button information - eor #%00011111 + asl a + asl a + asl a + ora PORTA ; add position information + eor #$1F ldx #0 ; fix X rts From a817da7c6bc0db40cbe23866b4b7a04b280ab612 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 20 Aug 2017 14:25:02 +0200 Subject: [PATCH 0418/2161] Adjusted to recent driver interface change. Please note that this change is absolutely untested! --- libsrc/c64/joy/c64-numpad.s | 70 +++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/libsrc/c64/joy/c64-numpad.s b/libsrc/c64/joy/c64-numpad.s index 5f6464215..5ed7af187 100644 --- a/libsrc/c64/joy/c64-numpad.s +++ b/libsrc/c64/joy/c64-numpad.s @@ -30,17 +30,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $02 ; JOY_UP "8" - .byte $10 ; JOY_DOWN "2" - .byte $20 ; JOY_LEFT "4" - .byte $08 ; JOY_RIGHT "6" - .byte $04 ; JOY_FIRE "5" ENTER - .byte $00 ; JOY_FIRE2 unavailable - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL @@ -58,6 +47,49 @@ JOY_COUNT = 1 ; Number of joysticks we support ; ------------------------------------------------------------------------ ; Data. +.rodata + +; <U>p '8' key +; <D>own '2' key +; <L>eft '4' key +; <R>ight '6' key +; <B>utton '5' or ENTER key + +masktable: + ; Input: LDRBU + ; Output: BRLDU + .byte %00000000 ; $00 + .byte %00000001 ; $01 + .byte %00010000 ; $02 + .byte %00010001 ; $03 + .byte %00001000 ; $04 + .byte %00001001 ; $05 + .byte %00011000 ; $06 + .byte %00011001 ; $07 + .byte %00000010 ; $08 + .byte %00000011 ; $09 + .byte %00010010 ; $0A + .byte %00010011 ; $0B + .byte %00001010 ; $0C + .byte %00001011 ; $0D + .byte %00011010 ; $0E + .byte %00011011 ; $0F + .byte %00000100 ; $10 + .byte %00000101 ; $11 + .byte %00010100 ; $12 + .byte %00010101 ; $13 + .byte %00001100 ; $14 + .byte %00001101 ; $15 + .byte %00011100 ; $16 + .byte %00011101 ; $17 + .byte %00000110 ; $18 + .byte %00000111 ; $19 + .byte %00010110 ; $1A + .byte %00010111 ; $1B + .byte %00001110 ; $1C + .byte %00001111 ; $1D + .byte %00011110 ; $1E + .byte %00011111 ; $1F .code @@ -100,21 +132,23 @@ COUNT: lda #JOY_COUNT ; READ: tax ; Clear high byte - lda #$FD - ldy #$FE + lda #$FD ; For ENTER and '6' + ldy #$FE ; For '8', '5', '2', '4' sei sta VIC_KBD_128 lda CIA1_PRB and #%00110000 eor #%00110000 - lsr - lsr + lsr ; Map ENTER ... + lsr ; ... onto '5' sty VIC_KBD_128 eor CIA1_PRB iny sty VIC_KBD_128 ; Reset to $FF cli - and #%11111110 - eor #%11111110 + and #%00111110 + eor #%00111110 + lsr + tay + lda masktable,y ; Convert LDRBU to BRLDU rts - From 20c85c8a1c35004f83ea5ba621dcd73145caf377 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 20 Aug 2017 14:53:40 +0200 Subject: [PATCH 0419/2161] Minor style adjustment. --- libsrc/c64/joy/c64-ptvjoy.s | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libsrc/c64/joy/c64-ptvjoy.s b/libsrc/c64/joy/c64-ptvjoy.s index e916d887a..af5c27e13 100644 --- a/libsrc/c64/joy/c64-ptvjoy.s +++ b/libsrc/c64/joy/c64-ptvjoy.s @@ -122,8 +122,8 @@ joy3: sta CIA2_PRB ; (output one at PB7) lda CIA2_PRB ; cia 2 port B read/write - and #$1f ; get bit 4-0 (PB4-PB0) - eor #$1f + and #$1F ; get bit 4-0 (PB4-PB0) + eor #$1F rts ; Read joystick 4 @@ -132,14 +132,14 @@ joy4: lda #$00 ; cia 2 port B read/write sta CIA2_PRB ; (output zero at PB7) lda CIA2_PRB ; cia 2 port B read/write - and #$0f ; get bit 3-0 (PB3-PB0) + and #$0F ; get bit 3-0 (PB3-PB0) sta tmp1 ; joy 4 directions lda CIA2_PRB ; cia 2 port B read/write and #%00100000 ; get bit 5 (PB5) lsr ora tmp1 - eor #$1f + eor #$1F ldx #0 rts From acf831658f591675b890c9c191fcc540094ae77e Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 20 Aug 2017 16:39:07 +0200 Subject: [PATCH 0420/2161] Adjusted to recent driver interface change. Please note that this change is absolutely untested! Apart from the recent driver interface change: - vic20-stdjoy.s was "slightly broken" because it didn't clear x on return from joy_read. - vic20-ptvjoy.s was "heavily broken" because it returned a totally different set of bits of the first joystick. --- libsrc/vic20/joy/vic20-ptvjoy.s | 25 ++++++++++++++++++------- libsrc/vic20/joy/vic20-stdjoy.s | 17 ++++++++++++++--- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/libsrc/vic20/joy/vic20-ptvjoy.s b/libsrc/vic20/joy/vic20-ptvjoy.s index 07c979443..3b1db402a 100644 --- a/libsrc/vic20/joy/vic20-ptvjoy.s +++ b/libsrc/vic20/joy/vic20-ptvjoy.s @@ -102,10 +102,21 @@ joy1: lda #$7F ; mask for VIA2 JOYBIT: sw3 sty VIA1_DDRA ; restore the state of DDRA cli ; necessary? - ror ; Shift sw3 into bit 7 - and #$9E ; Mask relevant bits - eor #$9E ; Active states are inverted + php ; Save sw3 in carry + lsr ; Shift sw0,sw1,sw2,sw4 into bits 1-4 + tax ; Save sw0,sw1,sw2 + and #$10 ; Extract sw4 in bit 4 + sta tmp1 ; Save sw4 in bit 4 + txa ; Restore sw0,sw1,sw2 + lsr ; Shift sw0,sw1,sw2 into bits 0-2 + and #$07 ; Mask bits 0-2 + plp ; Restore sw3 in carry + bcc @L0 ; Is sw3 set? + ora #$08 ; Yes: Add sw3 in bit 3 +@L0: ora tmp1 ; Add sw4 in bit 4 + eor #$1F ; Active states are inverted + ldx #0 rts ; Read joystick 2 @@ -120,8 +131,8 @@ joy2: lda #%10000000 ; via port B Data-Direction sta VIA1_PRB ; (output one at PB7) lda VIA1_PRB ; via port B read/write - and #$1f ; get bit 4-0 (PB4-PB0) - eor #$1f + and #$1F ; get bit 4-0 (PB4-PB0) + eor #$1F rts ; Read joystick 3 @@ -130,14 +141,14 @@ joy3: lda #$00 ; via port B read/write sta VIA1_PRB ; (output zero at PB7) lda VIA1_PRB ; via port B read/write - and #$0f ; get bit 3-0 (PB3-PB0) + and #$0F ; get bit 3-0 (PB3-PB0) sta tmp1 ; joy 4 directions lda VIA1_PRB ; via port B read/write and #%00100000 ; get bit 5 (PB5) lsr ora tmp1 - eor #$1f + eor #$1F ldx #0 rts diff --git a/libsrc/vic20/joy/vic20-stdjoy.s b/libsrc/vic20/joy/vic20-stdjoy.s index 56fb35ae4..bf10acce5 100644 --- a/libsrc/vic20/joy/vic20-stdjoy.s +++ b/libsrc/vic20/joy/vic20-stdjoy.s @@ -112,10 +112,21 @@ READ: lda #$7F ; mask for VIA2 JOYBIT: sw3 sty VIA1_DDRA ; restore the state of DDRA cli ; necessary? - ror ; Shift sw3 into bit 7 - and #$9E ; Mask relevant bits - eor #$9E ; Active states are inverted + php ; Save sw3 in carry + lsr ; Shift sw0,sw1,sw2,sw4 into bits 1-4 + tax ; Save sw0,sw1,sw2 + and #$10 ; Extract sw4 in bit 4 + sta tmp1 ; Save sw4 in bit 4 + txa ; Restore sw0,sw1,sw2 + lsr ; Shift sw0,sw1,sw2 into bits 0-2 + and #$07 ; Mask bits 0-2 + plp ; Restore sw3 in carry + bcc @L0 ; Is sw3 set? + ora #$08 ; Yes: Add sw3 in bit 3 +@L0: ora tmp1 ; Add sw4 in bit 4 + eor #$1F ; Active states are inverted + ldx #0 rts From 7a1f5358df2817809464ceeebfd34844c5a2a04e Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 23 Aug 2017 01:46:57 -0400 Subject: [PATCH 0421/2161] Fixed missing name and semicolon in two device structs. --- include/em/em-kernel.h | 5 +---- include/joystick/joy-kernel.h | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/include/em/em-kernel.h b/include/em/em-kernel.h index a1ce9a253..ffc6e131a 100644 --- a/include/em/em-kernel.h +++ b/include/em/em-kernel.h @@ -52,7 +52,7 @@ typedef struct { /* Driver header */ char id[3]; /* Contains 0x65, 0x6d, 0x64 ("emd") */ unsigned char version; /* Interface version */ - void* /* Library reference */ + void* libreference; /* Library reference */ /* Jump vectors. Note that these are not C callable */ void* install; /* INSTALL routine */ @@ -75,6 +75,3 @@ extern em_drv_header* em_drv; /* Pointer to driver */ /* End of em-kernel.h */ #endif - - - diff --git a/include/joystick/joy-kernel.h b/include/joystick/joy-kernel.h index cec2633ab..e984291f7 100644 --- a/include/joystick/joy-kernel.h +++ b/include/joystick/joy-kernel.h @@ -52,7 +52,7 @@ typedef struct { /* Driver header */ char id[3]; /* Contains 0x6a, 0x6f, 0x79 ("joy") */ unsigned char version; /* Interface version */ - void* /* Library reference */ + void* libreference; /* Library reference */ /* Jump vectors. Note that these are not C callable */ void* install; /* INSTALL routine */ From 4aa19494f5346a79d4c940903ad93f06be79915e Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 30 Aug 2017 16:37:31 +0200 Subject: [PATCH 0422/2161] Removed dysfunctional kbrepeatdelay() and kbrepeatrate(). As discussed in https://github.com/cc65/cc65/pull/452 after my premature merge the two functions in question don't work as expected. Additionally I adjusted several style deviations in the pull request in question. --- doc/funcref.sgml | 61 ++++------------------------------------- include/cbm.h | 13 ++++----- libsrc/c128/kbrepeat.s | 18 ++++-------- libsrc/c64/kbrepeat.s | 18 ++++-------- libsrc/pet/kbrepeat.s | 18 ++++-------- libsrc/plus4/kbrepeat.s | 18 ++++-------- libsrc/vic20/kbrepeat.s | 18 ++++-------- 7 files changed, 37 insertions(+), 127 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index f866dea5f..5ef773b95 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -184,8 +184,6 @@ function. <!-- <item><ref id="cbm_write" name="cbm_write"> --> <!-- <item><ref id="get_tv" name="get_tv"> --> <item><ref id="kbrepeat" name="kbrepeat"> -<item><ref id="kbrepeatdelay" name="kbrepeatdelay"> -<item><ref id="kbrepeatrate" name="kbrepeatrate"> </itemize> (incomplete) @@ -2174,64 +2172,17 @@ to get off the serial bus so it can be used for other purposes. <descrip> <tag/Function/Set keyboard repeat mode <tag/Header/<tt/<ref id="cbm.h" name="cbm.h">/ -<tag/Declaration/<tt/unsigned char kbrepeat (unsigned char);/ -<tag/Description/This function changes what keys will have automatic repeat when -being hold down for a certain time. Possible values are KBDREPEAT_CURSOR (repeat -only cursor-related keys), KBDREPEAT_NONE (no repeat for any keys) and -KBDREPEAT_ALL (repeat all keys). -The old mode is returned so it can be restored later. +<tag/Declaration/<tt/unsigned char __fastcall__ kbrepeat (unsigned char mode);/ +<tag/Description/This function changes which keys have automatic repeat when +being hold down for a certain time. Possible values are KBREPEAT_CURSOR (repeat +only cursor-related keys), KBREPEAT_NONE (no repeat for any keys) and +KBREPEAT_ALL (repeat all keys). The old mode is returned so it can be restored +later. <tag/Notes/<itemize> <item>The function is available only as a fastcall function; so, it may be used only in the presence of a prototype. </itemize> <tag/Availability/cc65 -<tag/See also/ -<ref id="kbrepeatdelay" name="kbrepeatdelay"> -<ref id="kbrepeatrate" name="kbrepeatrate"> -<tag/Example/None. -</descrip> -</quote> - -<sect1>kbrepeatdelay<label id="kbrepeatdelay"><p> - -<quote> -<descrip> -<tag/Function/Set keyboard repeat delay -<tag/Header/<tt/<ref id="cbm.h" name="cbm.h">/ -<tag/Declaration/<tt/unsigned char kbrepeatdelay (unsigned char);/ -<tag/Description/This function changes the delay until a keypress is being -repeated automatically. -The old value is returned so it can be restored later. -<tag/Notes/<itemize> -<item>The function is available only as a fastcall function; so, it may be used -only in the presence of a prototype. -</itemize> -<tag/Availability/cc65 -<tag/See also/ -<ref id="kbrepeat" name="kbrepeat"> -<ref id="kbrepeatrate" name="kbrepeatrate"> -<tag/Example/None. -</descrip> -</quote> - -<sect1>kbrepeatrate<label id="kbrepeatrate"><p> - -<quote> -<descrip> -<tag/Function/Set keyboard repeat rate -<tag/Header/<tt/<ref id="cbm.h" name="cbm.h">/ -<tag/Declaration/<tt/unsigned char kbrepeatrate (unsigned char);/ -<tag/Description/This function changes the keyboard repeat rate (the time between -repeated keypresses). -The old value is returned so it can be restored later. -<tag/Notes/<itemize> -<item>The function is available only as a fastcall function; so, it may be used -only in the presence of a prototype. -</itemize> -<tag/Availability/cc65 -<tag/See also/ -<ref id="kbrepeat" name="kbrepeat"> -<ref id="kbrepeatdelay" name="kbrepeatdelay"> <tag/Example/None. </descrip> </quote> diff --git a/include/cbm.h b/include/cbm.h index c1762b1a9..a4b232406 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -158,17 +158,16 @@ struct cbm_dirent { unsigned char get_tv (void); /* Return the video mode the machine is using. */ -#define KBDREPEAT_CURSOR 0x00 -#define KBDREPEAT_NONE 0x40 -#define KBDREPEAT_ALL 0x80 +#define KBREPEAT_CURSOR 0x00 +#define KBREPEAT_NONE 0x40 +#define KBREPEAT_ALL 0x80 -unsigned char __fastcall__ kbrepeat(unsigned char); -unsigned char __fastcall__ kbrepeatdelay(unsigned char); -unsigned char __fastcall__ kbrepeatrate(unsigned char); +unsigned char __fastcall__ kbrepeat (unsigned char mode); +/* Changes which keys have automatic repeat. */ #if !defined(__CBM610__) && !defined(__PET__) void waitvsync (void); -/* wait for the start of the next frame */ +/* Wait for the start of the next frame */ #endif /*****************************************************************************/ diff --git a/libsrc/c128/kbrepeat.s b/libsrc/c128/kbrepeat.s index c32e8c017..4b9bc22af 100644 --- a/libsrc/c128/kbrepeat.s +++ b/libsrc/c128/kbrepeat.s @@ -1,5 +1,8 @@ +; +; unsigned char __fastcall__ kbrepeat (unsigned char mode); +; - .export _kbrepeat, _kbrepeatdelay, _kbrepeatrate + .export _kbrepeat .include "c128.inc" @@ -7,16 +10,5 @@ _kbrepeat: ldx KBDREPEAT ; get old value sta KBDREPEAT ; store new value txa ; return old value - rts - -_kbrepeatdelay: - ldx KBDREPEATDELAY ; get old value - sta KBDREPEATDELAY ; store new value - txa ; return old value - rts - -_kbrepeatrate: - ldx KBDREPEATRATE ; get old value - sta KBDREPEATRATE ; store new value - txa ; return old value + ldx #0 rts diff --git a/libsrc/c64/kbrepeat.s b/libsrc/c64/kbrepeat.s index f59c8a6da..0df13e58d 100644 --- a/libsrc/c64/kbrepeat.s +++ b/libsrc/c64/kbrepeat.s @@ -1,5 +1,8 @@ +; +; unsigned char __fastcall__ kbrepeat (unsigned char mode); +; - .export _kbrepeat, _kbrepeatdelay, _kbrepeatrate + .export _kbrepeat .include "c64.inc" @@ -7,16 +10,5 @@ _kbrepeat: ldx KBDREPEAT ; get old value sta KBDREPEAT ; store new value txa ; return old value - rts - -_kbrepeatdelay: - ldx KBDREPEATDELAY ; get old value - sta KBDREPEATDELAY ; store new value - txa ; return old value - rts - -_kbrepeatrate: - ldx KBDREPEATRATE ; get old value - sta KBDREPEATRATE ; store new value - txa ; return old value + ldx #0 rts diff --git a/libsrc/pet/kbrepeat.s b/libsrc/pet/kbrepeat.s index 0a29d7420..8299f5103 100644 --- a/libsrc/pet/kbrepeat.s +++ b/libsrc/pet/kbrepeat.s @@ -1,5 +1,8 @@ +; +; unsigned char __fastcall__ kbrepeat (unsigned char mode); +; - .export _kbrepeat, _kbrepeatdelay, _kbrepeatrate + .export _kbrepeat .include "pet.inc" @@ -7,16 +10,5 @@ _kbrepeat: ldx KBDREPEAT ; get old value sta KBDREPEAT ; store new value txa ; return old value - rts - -_kbrepeatdelay: - ldx KBDREPEATDELAY ; get old value - sta KBDREPEATDELAY ; store new value - txa ; return old value - rts - -_kbrepeatrate: - ldx KBDREPEATRATE ; get old value - sta KBDREPEATRATE ; store new value - txa ; return old value + ldx #0 rts diff --git a/libsrc/plus4/kbrepeat.s b/libsrc/plus4/kbrepeat.s index 927b99e5b..9c0dc6855 100644 --- a/libsrc/plus4/kbrepeat.s +++ b/libsrc/plus4/kbrepeat.s @@ -1,5 +1,8 @@ +; +; unsigned char __fastcall__ kbrepeat (unsigned char mode); +; - .export _kbrepeat, _kbrepeatdelay, _kbrepeatrate + .export _kbrepeat .include "plus4.inc" @@ -7,16 +10,5 @@ _kbrepeat: ldx KBDREPEAT ; get old value sta KBDREPEAT ; store new value txa ; return old value - rts - -_kbrepeatdelay: - ldx KBDREPEATDELAY ; get old value - sta KBDREPEATDELAY ; store new value - txa ; return old value - rts - -_kbrepeatrate: - ldx KBDREPEATRATE ; get old value - sta KBDREPEATRATE ; store new value - txa ; return old value + ldx #0 rts diff --git a/libsrc/vic20/kbrepeat.s b/libsrc/vic20/kbrepeat.s index 5115c852e..dce4949fb 100644 --- a/libsrc/vic20/kbrepeat.s +++ b/libsrc/vic20/kbrepeat.s @@ -1,5 +1,8 @@ +; +; unsigned char __fastcall__ kbrepeat (unsigned char mode); +; - .export _kbrepeat, _kbrepeatdelay, _kbrepeatrate + .export _kbrepeat .include "vic20.inc" @@ -7,16 +10,5 @@ _kbrepeat: ldx KBDREPEAT ; get old value sta KBDREPEAT ; store new value txa ; return old value - rts - -_kbrepeatdelay: - ldx KBDREPEATDELAY ; get old value - sta KBDREPEATDELAY ; store new value - txa ; return old value - rts - -_kbrepeatrate: - ldx KBDREPEATRATE ; get old value - sta KBDREPEATRATE ; store new value - txa ; return old value + ldx #0 rts From 929553dc8df122916d89d97afb4adc2ccb141e29 Mon Sep 17 00:00:00 2001 From: Phil Smith <phil.h.smith@gmail.com> Date: Fri, 1 Sep 2017 23:11:54 -0700 Subject: [PATCH 0423/2161] At most 256 bytes will be reserved --- doc/ca65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 33acc0a80..cb4fbb500 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1695,7 +1695,7 @@ either a string or an expression. Example: <tscreen><verb> - ; Reserve space for some data, but 256 bytes minimum + ; Reserve space for some data, but 256 bytes maximum savearea: .min (.sizeof (foo), 256) </verb></tscreen> From ded1c201904e8a0b8f2ffb792438226a977f0fab Mon Sep 17 00:00:00 2001 From: Phil Smith <phil.h.smith@gmail.com> Date: Sat, 2 Sep 2017 19:25:49 -0700 Subject: [PATCH 0424/2161] Reserve space in examples with .res --- doc/ca65.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index cb4fbb500..715ecd89e 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1636,7 +1636,7 @@ either a string or an expression. <tscreen><verb> ; Reserve space for the larger of two data blocks - savearea: .max (.sizeof (foo), .sizeof (bar)) + savearea: .res .max (.sizeof (foo), .sizeof (bar)) </verb></tscreen> See: <tt><ref id=".MIN" name=".MIN"></tt> @@ -1696,7 +1696,7 @@ either a string or an expression. <tscreen><verb> ; Reserve space for some data, but 256 bytes maximum - savearea: .min (.sizeof (foo), 256) + savearea: .res .min (.sizeof (foo), 256) </verb></tscreen> See: <tt><ref id=".MAX" name=".MAX"></tt> From 0deeccebf8bc0e7658213b12875efaad3abf216f Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 4 Sep 2017 09:41:19 +0200 Subject: [PATCH 0425/2161] Added JOY_FIRE. According to https://en.wikipedia.org/wiki/Atari_8-bit_computer_peripherals it seems appropriate to add a JOY_FIRE definition for the ATARI. --- include/atari.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/atari.h b/include/atari.h index ca4b2ef26..bf1af7d7b 100644 --- a/include/atari.h +++ b/include/atari.h @@ -156,6 +156,9 @@ #define JOY_RIGHT_MASK 0x08 #define JOY_BTN_1_MASK 0x10 +#define JOY_FIRE_MASK JOY_BTN_1_MASK +#define JOY_FIRE(v) ((v) & JOY_FIRE_MASK) + /* color register functions */ extern void __fastcall__ _setcolor (unsigned char color_reg, unsigned char hue, unsigned char luminace); extern void __fastcall__ _setcolor_low (unsigned char color_reg, unsigned char color_value); From 3c0b8c4e862de0b54e547aa3ad0dfa7e6fd668f2 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 5 Sep 2017 03:40:34 -0400 Subject: [PATCH 0426/2161] Made the CBM Pet kbrepeat() work on both 40-column and 80-column machines. Put the kbrepeat() description in an alphabetical position in the function document. --- asminc/pet.inc | 23 +++++++++------------ doc/funcref.sgml | 47 +++++++++++++++++++++++-------------------- libsrc/pet/kbrepeat.s | 25 ++++++++++++++++++----- 3 files changed, 55 insertions(+), 40 deletions(-) diff --git a/asminc/pet.inc b/asminc/pet.inc index 8f2f469e0..43d52a5d5 100644 --- a/asminc/pet.inc +++ b/asminc/pet.inc @@ -26,22 +26,21 @@ SCR_LINELEN := $D5 ; Screen line length CURS_Y := $D8 ; Cursor row FNADR := $DA ; Pointer to file name +; 80-Column CBMs +KBDREPEAT80 := $E4 +KBDRPTRATE80 := $E5 +KBDRPTDELAY80 := $E6 + BASIC_BUF := $200 ; Location of command-line BASIC_BUF_LEN = 81 ; Maximum length of command-line KEY_BUF := $26F ; Keyboard buffer -;FIXME: we must somehow handle the difference between the two - how? - -; 40-Column PETs -;KBDREPEAT := $3ee -;KBDREPEATRATE := $3ea -;KBDREPEATDELAY := $3e9 - -; 80-Column PETs -KBDREPEAT := $e4 -KBDREPEATRATE := $e5 -KBDREPEATDELAY := $e6 +; 40-Column PETs/CBMs +KBDRPTDELAY40 := $3E9 +KBDRPTRATE40 := $3EA +KBDREPEAT40 := $3EE +KBDREPEAT40B := $3F8 ;---------------------------------------------------------------------------- ; PET ROM type detection @@ -67,5 +66,3 @@ VIA_PRB := $E840 VIA_PRA := $E841 VIA_DDRB := $E842 VIA_DDRA := $E843 - - diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 5ef773b95..1d5ee7c19 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -2,8 +2,9 @@ <article> <title>cc65 function reference -<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2016-08-07 +<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> +<url url="mailto:greg.king5@verizon.net" name="Greg King"> +<date>2017-09-02 <abstract> cc65 is a C compiler for 6502 based systems. This function reference describes @@ -2166,26 +2167,6 @@ to get off the serial bus so it can be used for other purposes. </descrip> </quote> -<sect1>kbrepeat<label id="kbrepeat"><p> - -<quote> -<descrip> -<tag/Function/Set keyboard repeat mode -<tag/Header/<tt/<ref id="cbm.h" name="cbm.h">/ -<tag/Declaration/<tt/unsigned char __fastcall__ kbrepeat (unsigned char mode);/ -<tag/Description/This function changes which keys have automatic repeat when -being hold down for a certain time. Possible values are KBREPEAT_CURSOR (repeat -only cursor-related keys), KBREPEAT_NONE (no repeat for any keys) and -KBREPEAT_ALL (repeat all keys). The old mode is returned so it can be restored -later. -<tag/Notes/<itemize> -<item>The function is available only as a fastcall function; so, it may be used -only in the presence of a prototype. -</itemize> -<tag/Availability/cc65 -<tag/Example/None. -</descrip> -</quote> <sect1>cclear<label id="cclear"><p> @@ -4062,6 +4043,28 @@ do), the function is rather useless. </quote> +<sect1>kbrepeat<label id="kbrepeat"><p> + +<quote> +<descrip> +<tag/Function/Set the keyboard repeat mode. +<tag/Header/<tt/<ref id="cbm.h" name="cbm.h">/ +<tag/Declaration/<tt/unsigned char __fastcall__ kbrepeat (unsigned char mode);/ +<tag/Description/This function changes which keys have automatic repeat when +being held down for a certain time. Possible values are <tt/KBREPEAT_CURSOR/ +(repeat only cursor-related keys), <tt/KBREPEAT_NONE/ (no repeat for any +keys), and <tt/KBREPEAT_ALL/ (repeat all keys). The old mode is returned, so +it can be restored later. +<tag/Notes/<itemize> +<item>The function is available only as a fastcall function; so, it may be used +only in the presence of a prototype. +</itemize> +<tag/Availability/cc65 +<tag/Example/None. +</descrip> +</quote> + + <sect1>labs<label id="labs"><p> <quote> diff --git a/libsrc/pet/kbrepeat.s b/libsrc/pet/kbrepeat.s index 8299f5103..100d8502a 100644 --- a/libsrc/pet/kbrepeat.s +++ b/libsrc/pet/kbrepeat.s @@ -1,14 +1,29 @@ ; ; unsigned char __fastcall__ kbrepeat (unsigned char mode); +; +; 2017-06-16, Groepaz +; 2017-09-05, Greg King ; - .export _kbrepeat + .export _kbrepeat .include "pet.inc" _kbrepeat: - ldx KBDREPEAT ; get old value - sta KBDREPEAT ; store new value - txa ; return old value - ldx #0 + ldx #>$0000 + ldy SCR_LINELEN + cpy #40 + 1 + bcc L1 ; branch if screen is 40 columns wide + + ldy KBDREPEAT80 ; get old value + sta KBDREPEAT80 ; store new value + tya ; return old value + rts + +L1: tay + lda KBDREPEAT40B ; get REPEAT-key flag (used by some editor ROMs) + lsr a ; move bit 0 into bit 7 + ror a + ora KBDREPEAT40 ; combine with old key-REPEAT flags + sty KBDREPEAT40 rts From 51765c6e5c01cacda99621809e97dcd45ce295ff Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 5 Sep 2017 16:56:20 -0400 Subject: [PATCH 0427/2161] Removed an unwanted button mask table from a VIC-20 joystick driver. It had put the jump table at the wrong place. Programs crashed as soon as they tried to initiate the driver. --- libsrc/vic20/joy/vic20-stdjoy.s | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/libsrc/vic20/joy/vic20-stdjoy.s b/libsrc/vic20/joy/vic20-stdjoy.s index bf10acce5..67299cc1a 100644 --- a/libsrc/vic20/joy/vic20-stdjoy.s +++ b/libsrc/vic20/joy/vic20-stdjoy.s @@ -30,17 +30,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $02 ; JOY_UP - .byte $04 ; JOY_DOWN - .byte $08 ; JOY_LEFT - .byte $80 ; JOY_RIGHT - .byte $10 ; JOY_FIRE - .byte $00 ; JOY_FIRE2 unavailable - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL @@ -128,5 +117,3 @@ READ: lda #$7F ; mask for VIA2 JOYBIT: sw3 ldx #0 rts - - From 5802b0963fcd222eb2352525428789a857b23bda Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 10 Sep 2017 12:27:57 -0400 Subject: [PATCH 0428/2161] Made <conio.h> include <atari5200.h> when we compile for the Atari 5200 console. atari5200.lib has some conio functions. --- include/conio.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/conio.h b/include/conio.h index 9eb68e565..4f414105c 100644 --- a/include/conio.h +++ b/include/conio.h @@ -63,6 +63,8 @@ # include <apple2enh.h> #elif defined(__APPLE2__) # include <apple2.h> +#elif defined(__ATARI5200__) +# include <atari5200.h> #elif defined(__ATARI__) # include <atari.h> #elif defined(__ATMOS__) @@ -225,6 +227,3 @@ void __fastcall__ cputhex16 (unsigned val); /* End of conio.h */ #endif - - - From 7623d4ea83ab9f64f5b66c9781e6a607a625038b Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 12 Sep 2017 21:57:16 +0200 Subject: [PATCH 0429/2161] conio.h: include 'creativision.h' when compiling for this target. --- include/conio.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/conio.h b/include/conio.h index 4f414105c..baf55dd08 100644 --- a/include/conio.h +++ b/include/conio.h @@ -71,6 +71,8 @@ # include <atmos.h> #elif defined(__CBM__) # include <cbm.h> +#elif defined(__CREATIVISION__) +# include <creativision.h> #elif defined(__GAMATE__) # include <gamate.h> #elif defined(__GEOS__) From 945dcfd63ad23d1ac93edab8112cec0798bfccdd Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 13 Sep 2017 23:51:07 +0200 Subject: [PATCH 0430/2161] Fixed address See cbm510.cfg --- doc/cbm510.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/cbm510.sgml b/doc/cbm510.sgml index c24eba142..b171c2ce3 100644 --- a/doc/cbm510.sgml +++ b/doc/cbm510.sgml @@ -67,7 +67,7 @@ Special locations: <descrip> <tag/Stack/ - The C runtime stack is located at $FF81, and grows downwards. + The C runtime stack is located at $FEC2, and grows downwards. <tag/Heap/ The C heap is located at the end of the program, and grows towards the C From 1c7c44e12c14255987014954692d0ab3b5f1e11a Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 24 Sep 2017 11:46:52 +0200 Subject: [PATCH 0431/2161] adding some vars --- asminc/telestrat.inc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 8a51e1c32..d630c9fb3 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -26,6 +26,15 @@ RESB := $02 TR0 := $0C TR1 := $0D +TR2 := $0E +TR3 := $0F +TR4 := $10 +TR5 := $11 +TR6 := $12 +TR7 := $13 + + + PTR_READ_DEST := $2C ; used for XFREAD and XWRITE only in telemon 3.0 @@ -109,6 +118,7 @@ XTEXT = $19 XHIRES = $1A XFILLM = $1C XMINMA = $1F +XVARS = $24 ; only in TELEMON 3.0, in telemon 2.4, it's XNOMFI ($24) XFREAD = $27 ; only in TELEMON 3.0 XOPEN = $30 ; only in TELEMON 3.0 XCOSCR = $34 ; switch off cursor @@ -146,8 +156,8 @@ BUFEDT := $590 MAX_BUFEDT_LENGTH=110 ; Hardware -CH376_DATA :=$340 -CH376_COMMAND :=$341 +CH376_DATA := $340 +CH376_COMMAND := $341 ; MACRO From c640619db5e9a1965a6f3a2631d8bb771b578ea3 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 24 Sep 2017 11:55:37 +0200 Subject: [PATCH 0432/2161] Add some bytes in ZP block in order to able to link with o65 files --- cfg/telestrat.cfg | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cfg/telestrat.cfg b/cfg/telestrat.cfg index 395a936e1..35fd5a984 100644 --- a/cfg/telestrat.cfg +++ b/cfg/telestrat.cfg @@ -4,7 +4,7 @@ SYMBOLS { __RAMEND__: type = weak, value = $9800; } MEMORY { - ZP: file = "", define = yes, start = $00E0, size = $001A; + ZP: file = "", define = yes, start = $00B0, size = $003A; ORIXHDR: file = %O, type = ro, start = $0000, size = $001F; BASHEAD: file = %O, define = yes, start = $0801, size = $000D; MAIN: file = %O, define = yes, start = __BASHEAD_LAST__, size = __RAMEND__ - __MAIN_START__; @@ -38,3 +38,5 @@ FEATURES { segment = RODATA, import = __CALLIRQ__; } + + From fdd789edd8c2c5780aa3ad7ef9908f042308fd35 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 24 Sep 2017 11:56:55 +0200 Subject: [PATCH 0433/2161] correcting some return lines --- cfg/telestrat.cfg | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cfg/telestrat.cfg b/cfg/telestrat.cfg index 35fd5a984..2b26f4d6e 100644 --- a/cfg/telestrat.cfg +++ b/cfg/telestrat.cfg @@ -37,6 +37,4 @@ FEATURES { count = __INTERRUPTOR_COUNT__, segment = RODATA, import = __CALLIRQ__; -} - - +} \ No newline at end of file From d4c6c995ba70f95b1692677e5acf04ecbba19ef3 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 24 Sep 2017 11:57:52 +0200 Subject: [PATCH 0434/2161] Correcting missing return line :/ --- cfg/telestrat.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/telestrat.cfg b/cfg/telestrat.cfg index 2b26f4d6e..42e8d2cb5 100644 --- a/cfg/telestrat.cfg +++ b/cfg/telestrat.cfg @@ -37,4 +37,4 @@ FEATURES { count = __INTERRUPTOR_COUNT__, segment = RODATA, import = __CALLIRQ__; -} \ No newline at end of file +} From 60e41e3110f881975f3dd075bfdb34595d4bb973 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 24 Sep 2017 19:22:43 +0200 Subject: [PATCH 0435/2161] Adding XVARS primitive --- asminc/telestrat.inc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index d630c9fb3..48e3a9347 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -15,6 +15,7 @@ FUNCTKEY = $A5 FNAME_LEN = 11 ; maximum length of file-name +FILENAME_MAX = 100 ; --------------------------------------------------------------------------- ; Zero page @@ -139,6 +140,11 @@ XINK = $93 XEXPLO = $9C XPING = $9D +; --------------------------------------------------------------------------- +; ROM entries variables + +PWD_PTR = $00 + ; --------------------------------------------------------------------------- ; Page $200 SCRX := $220 From fabb6acf3ffb53e4a20b4e163941c58d66dbdf39 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 24 Sep 2017 19:23:44 +0200 Subject: [PATCH 0436/2161] Initcwd is now working for telestrat --- libsrc/telestrat/initcwd.s | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 libsrc/telestrat/initcwd.s diff --git a/libsrc/telestrat/initcwd.s b/libsrc/telestrat/initcwd.s new file mode 100644 index 000000000..84ab3fb35 --- /dev/null +++ b/libsrc/telestrat/initcwd.s @@ -0,0 +1,28 @@ +; +; Oliver Schmidt, 18.04.2005 +; + + .export initcwd + .import __cwd + + .include "zeropage.inc" + .include "telestrat.inc" + + +initcwd: + ldx #PWD_PTR + BRK_TELEMON XVARS + sta tmp1 + sty tmp1+1 + + ldy #$00 +loop: + lda (tmp1),y + beq done + sta __cwd,y + iny + bne loop + +done: + sta (tmp2),y + rts From 5bbb27c8af558be6ed5b88f67bec972023c940de Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 24 Sep 2017 20:04:50 +0200 Subject: [PATCH 0437/2161] Fixing bug for cwd --- libsrc/telestrat/initcwd.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/telestrat/initcwd.s b/libsrc/telestrat/initcwd.s index 84ab3fb35..ae25817d9 100644 --- a/libsrc/telestrat/initcwd.s +++ b/libsrc/telestrat/initcwd.s @@ -24,5 +24,5 @@ loop: bne loop done: - sta (tmp2),y + sta _cwd,y rts From 86741cb1ddea6da58eb3462e5e120929c6928ea5 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 24 Sep 2017 20:07:02 +0200 Subject: [PATCH 0438/2161] correcting missing _ --- libsrc/telestrat/initcwd.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/telestrat/initcwd.s b/libsrc/telestrat/initcwd.s index ae25817d9..df2ceb63b 100644 --- a/libsrc/telestrat/initcwd.s +++ b/libsrc/telestrat/initcwd.s @@ -24,5 +24,5 @@ loop: bne loop done: - sta _cwd,y + sta __cwd,y rts From d8904c550bb7c4fabe5e80737e542aa5c88eb206 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 25 Sep 2017 21:39:57 +0200 Subject: [PATCH 0439/2161] Fixing buffer overflow with cwd command (FILENAME_MAX must be at 50 +1 bytes) --- asminc/stdio.inc | 2 ++ asminc/telestrat.inc | 3 ++- include/stdio.h | 2 ++ libsrc/telestrat/initcwd.s | 13 ++++++++----- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/asminc/stdio.inc b/asminc/stdio.inc index 18a7541e0..3b22c47f6 100644 --- a/asminc/stdio.inc +++ b/asminc/stdio.inc @@ -47,6 +47,8 @@ FILENAME_MAX = 64+1 FILENAME_MAX = 12+1 .elseif .defined(__LUNIX__) FILENAME_MAX = 80+1 +.elseif .defined(__TELESTRAT__) +FILENAME_MAX = 50+1 .else FILENAME_MAX = 16+1 .endif diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 48e3a9347..ffe78ad6e 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -15,7 +15,7 @@ FUNCTKEY = $A5 FNAME_LEN = 11 ; maximum length of file-name -FILENAME_MAX = 100 +FILENAME_MAX = 200 ; --------------------------------------------------------------------------- ; Zero page @@ -151,6 +151,7 @@ SCRX := $220 SCRY := $224 ADSCRL := $218 ADSCRH := $21C +IRQVECTOR := $2FA ; --------------------------------------------------------------------------- diff --git a/include/stdio.h b/include/stdio.h index c2c735cb0..a3facd513 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -75,6 +75,8 @@ extern FILE* stderr; # define FILENAME_MAX (12+1) #elif defined(__LUNIX__) # define FILENAME_MAX (80+1) +#elif defined(__TELESTRAT__) +# define FILENAME_MAX (50+1) #else # define FILENAME_MAX (16+1) #endif diff --git a/libsrc/telestrat/initcwd.s b/libsrc/telestrat/initcwd.s index df2ceb63b..f359ebeb4 100644 --- a/libsrc/telestrat/initcwd.s +++ b/libsrc/telestrat/initcwd.s @@ -1,5 +1,5 @@ ; -; Oliver Schmidt, 18.04.2005 +; Jede (jede@oric.org) 24.09.2017 ; .export initcwd @@ -10,14 +10,17 @@ initcwd: + ldx #PWD_PTR BRK_TELEMON XVARS - sta tmp1 - sty tmp1+1 - + + sta ptr1 + sty ptr1+1 + ldy #$00 + loop: - lda (tmp1),y + lda (ptr1),y beq done sta __cwd,y iny From 95a88a787d413553912a58770e045e7631744eb1 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 25 Sep 2017 21:47:05 +0200 Subject: [PATCH 0440/2161] remove FILENAME_MAX --- asminc/telestrat.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index ffe78ad6e..8e6a66bbd 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -15,7 +15,7 @@ FUNCTKEY = $A5 FNAME_LEN = 11 ; maximum length of file-name -FILENAME_MAX = 200 + ; --------------------------------------------------------------------------- ; Zero page From a1c8860f63132f34258053bb90884b35ff264022 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 1 Oct 2017 23:23:03 +0200 Subject: [PATCH 0441/2161] telestrat : cgetc add for conio --- libsrc/telestrat/cgetc.s | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 libsrc/telestrat/cgetc.s diff --git a/libsrc/telestrat/cgetc.s b/libsrc/telestrat/cgetc.s new file mode 100644 index 000000000..85ea4fccb --- /dev/null +++ b/libsrc/telestrat/cgetc.s @@ -0,0 +1,15 @@ +; +; jede jede@oric.org 2017-10-01 +; + .export _cgetc + + .include "telestrat.inc" + +.proc _cgetc +loop: + BRK_TELEMON XRD0 + bcc key_pressed + jmp loop +key_pressed: + rts +.endproc From 56360ea0542bffc8f3143b770180dca6ed78401e Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 2 Oct 2017 12:20:52 +0200 Subject: [PATCH 0442/2161] optimize --- libsrc/telestrat/cgetc.s | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libsrc/telestrat/cgetc.s b/libsrc/telestrat/cgetc.s index 85ea4fccb..591f966bc 100644 --- a/libsrc/telestrat/cgetc.s +++ b/libsrc/telestrat/cgetc.s @@ -8,8 +8,6 @@ .proc _cgetc loop: BRK_TELEMON XRD0 - bcc key_pressed - jmp loop -key_pressed: + bcs loop rts .endproc From ca4ed290d5964dbe833224d967d3707e20972278 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Tue, 3 Oct 2017 18:46:39 +0300 Subject: [PATCH 0443/2161] cl65: Add support for --all-cdecl --- src/cl65/main.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/cl65/main.c b/src/cl65/main.c index b209cb21d..565f20b45 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -752,6 +752,7 @@ static void Usage (void) "\n" "Long options:\n" " --add-source\t\t\tInclude source as comment\n" + " --all-cdecl\t\t\tMake functions default to __cdecl__\n" " --asm-args options\t\tPass options to the assembler\n" " --asm-define sym[=v]\t\tDefine an assembler symbol\n" " --asm-include-dir dir\t\tSet an assembler include directory\n" @@ -815,6 +816,14 @@ static void OptAddSource (const char* Opt attribute ((unused)), } +static void OptAllCDecl (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Make functions default to __cdecl__ */ +{ + CmdAddArg (&CC65, "--all-cdecl"); +} + + static void OptAsmArgs (const char* Opt attribute ((unused)), const char* Arg) /* Pass arguments to the assembler */ @@ -1290,6 +1299,7 @@ int main (int argc, char* argv []) /* Program long options */ static const LongOpt OptTab[] = { { "--add-source", 0, OptAddSource }, + { "--all-cdecl", 0, OptAllCDecl }, { "--asm-args", 1, OptAsmArgs }, { "--asm-define", 1, OptAsmDefine }, { "--asm-include-dir", 1, OptAsmIncludeDir }, From a084ea8e42487602fdf6bb475fe44ce6edb01739 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 3 Oct 2017 21:58:52 +0200 Subject: [PATCH 0444/2161] Atari: split "setcursor" function out of cgetc.s source file into setcursor.s. This function is used by many other CONIO functions, and the user program not necessarily uses 'cgetc'. Having "setcursor" in a different object file saves space in this case and also allows the user program to override it (e.g. when not using GRAPHICS 0 mode). --- libsrc/atari/cgetc.s | 44 ++---------------------------------- libsrc/atari/setcursor.s | 48 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 42 deletions(-) create mode 100644 libsrc/atari/setcursor.s diff --git a/libsrc/atari/cgetc.s b/libsrc/atari/cgetc.s index 2e9ebcb31..f8d938dfb 100644 --- a/libsrc/atari/cgetc.s +++ b/libsrc/atari/cgetc.s @@ -6,9 +6,9 @@ ; .include "atari.inc" - .export _cgetc,setcursor + .export _cgetc + .import setcursor .import KEYBDV_handler - .import cursor,mul40 _cgetc: jsr setcursor @@ -29,43 +29,3 @@ _cgetc: pha rts .endif - -.proc setcursor - - ldy #0 - lda OLDCHR - sta (OLDADR),y - - lda ROWCRS - jsr mul40 - clc - adc SAVMSC ; add start of screen memory - sta OLDADR - txa - adc SAVMSC+1 - sta OLDADR+1 - lda COLCRS - adc OLDADR - sta OLDADR - bcc nc - inc OLDADR+1 -nc: lda (OLDADR),y - sta OLDCHR - - ldx cursor ; current cursor setting as requested by the user - beq off - ldx #0 - beq cont - -off: inx -cont: stx CRSINH ; update system variable - - beq turnon - and #$7f ; clear high bit / inverse flag -finish: sta (OLDADR),y ; update on-screen display - rts - -turnon: ora #$80 ; set high bit / inverse flag - bne finish - -.endproc diff --git a/libsrc/atari/setcursor.s b/libsrc/atari/setcursor.s new file mode 100644 index 000000000..cf596d4fe --- /dev/null +++ b/libsrc/atari/setcursor.s @@ -0,0 +1,48 @@ +; +; Christian Groessler, November-2002 +; +; cursor handling, internal function + + .include "atari.inc" + .import cursor,mul40 + .export setcursor + +.proc setcursor + + ldy #0 + lda OLDCHR + sta (OLDADR),y + + lda ROWCRS + jsr mul40 + clc + adc SAVMSC ; add start of screen memory + sta OLDADR + txa + adc SAVMSC+1 + sta OLDADR+1 + lda COLCRS + adc OLDADR + sta OLDADR + bcc nc + inc OLDADR+1 +nc: lda (OLDADR),y + sta OLDCHR + + ldx cursor ; current cursor setting as requested by the user + beq off + ldx #0 + beq cont + +off: inx +cont: stx CRSINH ; update system variable + + beq turnon + and #$7f ; clear high bit / inverse flag +finish: sta (OLDADR),y ; update on-screen display + rts + +turnon: ora #$80 ; set high bit / inverse flag + bne finish + +.endproc From ff12835ee2f59ff147b67f9e8d194b46fea02f94 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 8 Oct 2017 18:11:09 +0200 Subject: [PATCH 0445/2161] Adding cgetc --- libsrc/telestrat/cgetc.s | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/libsrc/telestrat/cgetc.s b/libsrc/telestrat/cgetc.s index 591f966bc..9bdbf4818 100644 --- a/libsrc/telestrat/cgetc.s +++ b/libsrc/telestrat/cgetc.s @@ -3,9 +3,24 @@ ; .export _cgetc + .import cursor + + .include "telestrat.inc" .proc _cgetc + ; this routine could be quicker if we wrote in page 2 variables, but it's better to use telemon routine in that case, because telemon can manage 4 I/O + lda cursor ; if cursor equal to 0, then switch off cursor + beq switchoff_cursor + + ldx #$00 ; x is the first screen + BRK_TELEMON(XCSSCR) ; display cursor + jmp loop ; could be replaced by a bne/beq but 'jmp' is cleaner than a bne/beq which could expect some + +switchoff_cursor: + ldx #$00 ; x is the first screen + BRK_TELEMON(XCOSCR) ; switch off cursor + loop: BRK_TELEMON XRD0 bcs loop From a01c8c238c44195f3e13226c9d3ca9efd10d7fc6 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 8 Oct 2017 18:14:26 +0200 Subject: [PATCH 0446/2161] Correcting comments --- libsrc/telestrat/cgetc.s | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libsrc/telestrat/cgetc.s b/libsrc/telestrat/cgetc.s index 9bdbf4818..2b0fc7758 100644 --- a/libsrc/telestrat/cgetc.s +++ b/libsrc/telestrat/cgetc.s @@ -4,25 +4,25 @@ .export _cgetc .import cursor - .include "telestrat.inc" .proc _cgetc - ; this routine could be quicker if we wrote in page 2 variables, but it's better to use telemon routine in that case, because telemon can manage 4 I/O - lda cursor ; if cursor equal to 0, then switch off cursor + ; this routine could be quicker if we wrote in page 2 variables, + ; but it's better to use telemon routine in that case, because telemon can manage 4 I/O + lda cursor ; if cursor equal to 0, then switch off cursor beq switchoff_cursor ldx #$00 ; x is the first screen BRK_TELEMON(XCSSCR) ; display cursor - jmp loop ; could be replaced by a bne/beq but 'jmp' is cleaner than a bne/beq which could expect some + jmp loop ; could be replaced by a bne/beq but 'jmp' is cleaner than a bne/beq which could expect some matters switchoff_cursor: ldx #$00 ; x is the first screen BRK_TELEMON(XCOSCR) ; switch off cursor loop: - BRK_TELEMON XRD0 + BRK_TELEMON XRD0 ; waits until key is pressed bcs loop rts .endproc From bea5364b978b69125ec65adaa4f906ce062364a5 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 16 Oct 2017 09:39:33 -0400 Subject: [PATCH 0447/2161] Added commit ca4ed290d5964dbe833224d967d3707e20972278's command-line option to the cl65 document. --- doc/cl65.sgml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/cl65.sgml b/doc/cl65.sgml index 8b3c02cbb..ca5f9d2af 100644 --- a/doc/cl65.sgml +++ b/doc/cl65.sgml @@ -4,7 +4,7 @@ <title>cl65 Users Guide <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2017-05-24 +<date>2017-10-16 <abstract> cl65 is the compile & link utility for cc65, the 6502 C compiler. It was @@ -69,6 +69,7 @@ Short options: Long options: --add-source Include source as comment + --all-cdecl Make functions default to __cdecl__ --asm-args options Pass options to the assembler --asm-define sym[=v] Define an assembler symbol --asm-include-dir dir Set an assembler include directory From 256ba6bddf50dacd4c6c87ab54be6d4dca514dd2 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 16 Oct 2017 16:06:18 +0200 Subject: [PATCH 0448/2161] Adding XSOUT : Send A register to RS232 --- asminc/telestrat.inc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 8e6a66bbd..71240b38b 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -119,13 +119,13 @@ XTEXT = $19 XHIRES = $1A XFILLM = $1C XMINMA = $1F -XVARS = $24 ; only in TELEMON 3.0, in telemon 2.4, it's XNOMFI ($24) -XFREAD = $27 ; only in TELEMON 3.0 -XOPEN = $30 ; only in TELEMON 3.0 +XVARS = $24 ; only in TELEMON 3.x, in telemon 2.4, it's XNOMFI ($24) +XFREAD = $27 ; only in TELEMON 3.x +XOPEN = $30 ; only in TELEMON 3.x XCOSCR = $34 ; switch off cursor XCSSCR = $35 ; switch on cursor -XCLOSE = $3A ; only in TELEMON 3.0 Close file -XFWRITE = $3B ; only in TELEMON 3.0 write file +XCLOSE = $3A ; only in TELEMON 3.x Close file +XFWRITE = $3B ; only in TELEMON 3.x write file XSONPS = $40 XOUPS = $42 XPLAY = $43 @@ -133,6 +133,7 @@ XSOUND = $44 XMUSIC = $45 XZAP = $46 XSHOOT = $47 +XSOUT = $67 ; Send A register to RS232, available in telemon 2.4 & 3.x XCIRCL = $8F XCURSE = $90 XPAPER = $92 From 2ee7cf03779916eb27874f0c5f85fc3054883e48 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 16 Oct 2017 16:11:37 +0200 Subject: [PATCH 0449/2161] I/O identifiers added --- asminc/telestrat.inc | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 71240b38b..64d127625 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -1,7 +1,7 @@ ; ; Oric Telemon definition -; Telemon 2.4 & Telemon 3.0 -; For telemon 3.0 check http://orix.oric.org +; Telemon 2.4 & Telemon 3.x +; For telemon 3.x check http://orix.oric.org ; @@ -15,6 +15,15 @@ FUNCTKEY = $A5 FNAME_LEN = 11 ; maximum length of file-name +; --------------------------------------------------------------------------- +; I/O Identifier +; this identifers are used for channel management +; + +XKBD = $80 ; Keyboard +XRSE = $83 ; RS232 in +XSCR = $88 ; Screen +XRSS = $90 ; RS232 out ; --------------------------------------------------------------------------- @@ -34,10 +43,7 @@ TR5 := $11 TR6 := $12 TR7 := $13 - - - -PTR_READ_DEST := $2C ; used for XFREAD and XWRITE only in telemon 3.0 +PTR_READ_DEST := $2C ; used for XFREAD and XWRITE only in telemon 3.x HRSX := $46 HRSY := $47 From db1319de4c92865cafa0a0b65f6ea254a416c8bd Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 16 Oct 2017 17:28:00 +0200 Subject: [PATCH 0450/2161] clrscr.s switch to text mode --- libsrc/telestrat/clrscr.s | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libsrc/telestrat/clrscr.s b/libsrc/telestrat/clrscr.s index f2b8fafc1..31c8ee205 100644 --- a/libsrc/telestrat/clrscr.s +++ b/libsrc/telestrat/clrscr.s @@ -9,6 +9,9 @@ .include "telestrat.inc" .proc _clrscr + ; Switch to text mode + BRK_TELEMON(XTEXT) + lda #<SCREEN ldy #>SCREEN sta RES From 7107019d6fc340e7a52c1d74a848d38eca868e64 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 16 Oct 2017 17:33:10 +0200 Subject: [PATCH 0451/2161] Adding IRQVec --- asminc/telestrat.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 64d127625..b52e8ae37 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -58,7 +58,7 @@ HRS5 := $55 ; --------------------------------------------------------------------------- ; Low memory - +IRQVec := $02fb ; "fast" interrupt vector From 7b742647202f32447bd6617f194b14a0bd29325f Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 16 Oct 2017 17:34:32 +0200 Subject: [PATCH 0452/2161] irq.s added --- libsrc/telestrat/irq.s | 59 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 libsrc/telestrat/irq.s diff --git a/libsrc/telestrat/irq.s b/libsrc/telestrat/irq.s new file mode 100644 index 000000000..9027f263e --- /dev/null +++ b/libsrc/telestrat/irq.s @@ -0,0 +1,59 @@ +; +; IRQ handling (Oric version) +; + + .export initirq, doneirq + .import callirq + + .include "telestrat.inc" + +; ------------------------------------------------------------------------ + +.segment "ONCE" + +initirq: + lda IRQVec + ldx IRQVec+1 + sta IRQInd+1 + stx IRQInd+2 + lda #<IRQStub + ldx #>IRQStub + jmp setvec + +; ------------------------------------------------------------------------ + +.code + +doneirq: + lda IRQInd+1 + ldx IRQInd+2 +setvec: sei + sta IRQVec + stx IRQVec+1 + cli + rts + +; ------------------------------------------------------------------------ + +.segment "LOWCODE" + +IRQStub: + cld ; Just to be sure + pha + txa + pha + tya + pha + jsr callirq ; Call the functions + pla + tay + pla + tax + pla + jmp IRQInd ; Jump to the saved IRQ vector + +; ------------------------------------------------------------------------ + +.data + +IRQInd: jmp $0000 From 18c94e123fabd3863341b2ed7093128f59d1916a Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 16 Oct 2017 18:08:48 +0200 Subject: [PATCH 0453/2161] tgi_clear, tgi_init, tgi_done, tgi_getmaxx, tgi_getmaxy are working --- libsrc/telestrat/libref.s | 8 + libsrc/telestrat/tgi/telestrat-228-200-3.s | 320 +++++++++++++++++++++ libsrc/telestrat/tgi/telestrat-240-200-2.s | 315 ++++++++++++++++++++ libsrc/telestrat/tgi_colors.s | 8 + libsrc/telestrat/tgi_stat_stddrv.s | 14 + 5 files changed, 665 insertions(+) create mode 100644 libsrc/telestrat/libref.s create mode 100644 libsrc/telestrat/tgi/telestrat-228-200-3.s create mode 100644 libsrc/telestrat/tgi/telestrat-240-200-2.s create mode 100644 libsrc/telestrat/tgi_colors.s create mode 100644 libsrc/telestrat/tgi_stat_stddrv.s diff --git a/libsrc/telestrat/libref.s b/libsrc/telestrat/libref.s new file mode 100644 index 000000000..bdd0a671a --- /dev/null +++ b/libsrc/telestrat/libref.s @@ -0,0 +1,8 @@ +; +; Jede (jede@oric.org), 2017-10-16 +; + + .export tgi_libref + .import _exit + +tgi_libref := _exit diff --git a/libsrc/telestrat/tgi/telestrat-228-200-3.s b/libsrc/telestrat/tgi/telestrat-228-200-3.s new file mode 100644 index 000000000..1e6a6fb5a --- /dev/null +++ b/libsrc/telestrat/tgi/telestrat-228-200-3.s @@ -0,0 +1,320 @@ +; +; Graphics driver for the 228x200x3 palette mode on the Atmos +; +; Stefan Haubenthal <polluks@sdf.lonestar.org> +; 2014-09-10, Greg King <gregdk@users.sf.net> +; + + .include "zeropage.inc" + + .include "tgi-kernel.inc" + .include "tgi-error.inc" + .include "telestrat.inc" + + .macpack generic + .macpack module + +XSIZE = 6 ; System font width +YSIZE = 8 ; System font height + +; ------------------------------------------------------------------------ +; Header. Includes jump table and constants. + + module_header _telestrat_228_200_3_tgi + +; The first part of the header is a structure that has a signature, +; and defines the capabilities of the driver. + + .byte "tgi" + .byte TGI_API_VERSION ; TGI API version number + .addr $0000 ; Library reference + .word 228 ; x resolution + .word 200 ; y resolution + .byte 3 ; Number of drawing colors + .byte 1 ; Number of screens available + .byte XSIZE ; System font x size + .byte YSIZE ; System font y size + .word $011C ; Aspect ratio (based on 4/3 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 + .addr 0 ; IRQ entry is unused + +; ------------------------------------------------------------------------ +; Data. + +; Variables mapped to the zero-page segment variables. These are +; used for passing parameters to the driver. + +X1 := ptr1 +Y1 := ptr2 +X2 := ptr3 +Y2 := ptr4 + +; Absolute variables used in the code + +.bss + +ERROR: .res 1 ; Error code +MODE: .res 1 ; Graphics mode +PALETTE: .res 2 + +; Constant table + +.rodata + +; Default colors: black background, white foreground +; (The third "color" actually flips a pixel +; between the foreground and background colors.) +; +DEFPALETTE: .byte 0, 1 + +.code + +; ------------------------------------------------------------------------ +; 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 initialize variables and so on must go here. Setting palette and +; clearing the screen are not needed because they are called by the graphics +; kernel later. +; The graphics kernel never will 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: + +; Switch into graphics mode. + BRK_TELEMON(XHIRES) + rts + +; Done, reset the error code. + +; ------------------------------------------------------------------------ +; GETERROR: Return the error code in A, and clear it. + +GETERROR: + ldx #TGI_ERR_OK + lda ERROR + stx ERROR + rts +; ------------------------------------------------------------------------ +; 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: + +; ------------------------------------------------------------------------ +; UNINSTALL routine. Is called before the driver is removed from memory. May +; clean up anything done by INSTALL, but probably is empty most of the time. +; +; Must set an error code: NO +; + +UNINSTALL: + 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: + BRK_TELEMON(XTEXT) + rts +; ------------------------------------------------------------------------ +; CONTROL: Platform-/driver-specific entry point. +; +; Must set an error code: YES +; + +CONTROL: + ; not done yet + rts + +; ------------------------------------------------------------------------ +; CLEAR: Clears the screen. +; +; Must set an error code: NO +; + +CLEAR: + ; not done yet + rts + +; ------------------------------------------------------------------------ +; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n). +; 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: + +; ------------------------------------------------------------------------ +; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n). +; 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 + +; ------------------------------------------------------------------------ +; SETCOLOR: Set the drawing color (in A). The new color already is checked +; to be in a valid range (0..maxcolor-1). +; +; Must set an error code: NO (will be called only if color OK) +; + +SETCOLOR: + ; not done yet + 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: + ; not done yet + rts + +flipcolor: + ; not done yet + 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: + ; not done yet + rts + +; ------------------------------------------------------------------------ +; GETDEFPALETTE: Return the default palette for the driver in A/X. All +; drivers should return something reasonable here, even drivers that don't +; support palettes; otherwise, the caller has no way to determine the colors +; of the (not changeable) palette. +; +; Must set an error code: NO (all drivers must have a default palette) +; + +GETDEFPALETTE: + lda #<DEFPALETTE + ldx #>DEFPALETTE + rts + +; ------------------------------------------------------------------------ +; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing +; color. The co-ordinates 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: + ; not done yet + rts + +; ------------------------------------------------------------------------ +; GETPIXEL: Read the color value of a pixel, and return it in A/X. The +; co-ordinates passed to this function are never outside the visible screen +; area, so there is no need for clipping inside this function. + +GETPIXEL: + ; not done yet + 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. +; +; Must set an error code: NO +; + +LINE: + ; not done yet + 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: + ; not done yet + rts + +; ------------------------------------------------------------------------ +; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in the x +; and y directions is passed in X/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 its address in ptr3. +; +; Must set an error code: NO +; + +OUTTEXT: + ; not done yet + rts diff --git a/libsrc/telestrat/tgi/telestrat-240-200-2.s b/libsrc/telestrat/tgi/telestrat-240-200-2.s new file mode 100644 index 000000000..0424fb6f7 --- /dev/null +++ b/libsrc/telestrat/tgi/telestrat-240-200-2.s @@ -0,0 +1,315 @@ +; +; Graphics driver for the 240x200x2 monochrome mode on the Atmos +; +; Stefan Haubenthal <polluks@sdf.lonestar.org> +; 2014-09-10, Greg King <gregdk@users.sf.net> +; + + .include "zeropage.inc" + + .include "tgi-kernel.inc" + .include "tgi-error.inc" + .include "telestrat.inc" + + .macpack generic + .macpack module + +XSIZE = 6 ; System font width +YSIZE = 8 ; System font height + +; ------------------------------------------------------------------------ +; Header. Includes jump table and constants. + + module_header _telestrat_240_200_2_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 240 ; X resolution + .word 200 ; Y resolution + .byte 2 ; Number of drawing colors + .byte 1 ; Number of screens available + .byte XSIZE ; System font X size + .byte YSIZE ; System font Y size + .word $011C ; Aspect ratio (based on 4/3 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 + .addr 0 ; IRQ entry is unused + +; ------------------------------------------------------------------------ +; 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 + +; Absolute variables used in the code + +.bss + +ERROR: .res 1 ; Error code +MODE: .res 1 ; Graphics mode + +; Constant table + +.rodata + +DEFPALETTE: .byte 0, 1 + +.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: + +; ------------------------------------------------------------------------ +; 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: + +; Switch into graphics mode + + BRK_TELEMON(XHIRES) + rts +; 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: + BRK_TELEMON(XTEXT) + 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: + ; not done yet + rts + +; ------------------------------------------------------------------------ +; CLEAR: Clears the screen. +; +; Must set an error code: NO +; + +CLEAR: + ; not done yet + 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: + +; ------------------------------------------------------------------------ +; 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: + ;not done yet + 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: + lda #TGI_ERR_INV_FUNC ; This resolution has no palette + 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: + +; ------------------------------------------------------------------------ +; 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: + ; not done yet + 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: + ; not done yet + 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: + ; not done yet + 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. +; +; Must set an error code: NO +; + +LINE: + ; not done yet + 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 +; + +BAR: + ; not done yet + 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: + 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: + ; Not done yet + rts diff --git a/libsrc/telestrat/tgi_colors.s b/libsrc/telestrat/tgi_colors.s new file mode 100644 index 000000000..6ef3729b4 --- /dev/null +++ b/libsrc/telestrat/tgi_colors.s @@ -0,0 +1,8 @@ +; +; Target-specific black & white values for use by the target-shared TGI kernel +; + + .include "tgi-kernel.inc" + + .export tgi_color_black:zp = $00 + .export tgi_color_white:zp = $01 diff --git a/libsrc/telestrat/tgi_stat_stddrv.s b/libsrc/telestrat/tgi_stat_stddrv.s new file mode 100644 index 000000000..2b0d96761 --- /dev/null +++ b/libsrc/telestrat/tgi_stat_stddrv.s @@ -0,0 +1,14 @@ +; +; Address of the static standard tgi driver +; +; Jede (jede@oric.org), 2017-10-15 +; +; const void tgi_static_stddrv[]; +; + + .export _tgi_static_stddrv + .import _telestrat_240_200_2_tgi + +.rodata + +_tgi_static_stddrv := _telestrat_240_200_2_tgi From 195b5f0a07e4efaf4675437aca0426be8006c69f Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 16 Oct 2017 18:15:53 +0200 Subject: [PATCH 0454/2161] Optimizing (from Polluks tip) --- libsrc/telestrat/cgetc.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/telestrat/cgetc.s b/libsrc/telestrat/cgetc.s index 2b0fc7758..6a6b23318 100644 --- a/libsrc/telestrat/cgetc.s +++ b/libsrc/telestrat/cgetc.s @@ -10,7 +10,7 @@ .proc _cgetc ; this routine could be quicker if we wrote in page 2 variables, ; but it's better to use telemon routine in that case, because telemon can manage 4 I/O - lda cursor ; if cursor equal to 0, then switch off cursor + ldx cursor ; if cursor equal to 0, then switch off cursor beq switchoff_cursor ldx #$00 ; x is the first screen @@ -18,7 +18,7 @@ jmp loop ; could be replaced by a bne/beq but 'jmp' is cleaner than a bne/beq which could expect some matters switchoff_cursor: - ldx #$00 ; x is the first screen + ; at this step X is equal to $00, X must be set, because it's the id of the screen (telestrat can handle 4 virtuals screen) BRK_TELEMON(XCOSCR) ; switch off cursor loop: From f964fdbe56bd9f92a2c714df6e4351861993cc2f Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 16 Oct 2017 18:18:36 +0200 Subject: [PATCH 0455/2161] Correction : authors --- libsrc/telestrat/tgi/telestrat-228-200-3.s | 6 ++---- libsrc/telestrat/tgi/telestrat-240-200-2.s | 5 ++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/libsrc/telestrat/tgi/telestrat-228-200-3.s b/libsrc/telestrat/tgi/telestrat-228-200-3.s index 1e6a6fb5a..1e42f2ede 100644 --- a/libsrc/telestrat/tgi/telestrat-228-200-3.s +++ b/libsrc/telestrat/tgi/telestrat-228-200-3.s @@ -1,9 +1,7 @@ ; -; Graphics driver for the 228x200x3 palette mode on the Atmos -; -; Stefan Haubenthal <polluks@sdf.lonestar.org> -; 2014-09-10, Greg King <gregdk@users.sf.net> +; Graphics driver for the 228x200x3 palette mode on the Telestrat ; +; Jede (jede@oric.org), 2017-10-15 .include "zeropage.inc" diff --git a/libsrc/telestrat/tgi/telestrat-240-200-2.s b/libsrc/telestrat/tgi/telestrat-240-200-2.s index 0424fb6f7..3dc90525a 100644 --- a/libsrc/telestrat/tgi/telestrat-240-200-2.s +++ b/libsrc/telestrat/tgi/telestrat-240-200-2.s @@ -1,9 +1,8 @@ ; ; Graphics driver for the 240x200x2 monochrome mode on the Atmos ; -; Stefan Haubenthal <polluks@sdf.lonestar.org> -; 2014-09-10, Greg King <gregdk@users.sf.net> -; +; Jede (jede@oric.org), 2017-10-15 + .include "zeropage.inc" From 351a5ab20a658c46b14f4c14e91aae263308da4e Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Fri, 20 Oct 2017 21:03:30 +0200 Subject: [PATCH 0456/2161] Now setPixel works in TGI. --- asminc/telestrat.inc | 48 ++++++++++++++- include/telestrat.h | 70 ++++++++++++++++++++++ libsrc/telestrat/tgi/telestrat-228-200-3.s | 24 +++++++- libsrc/telestrat/tgi/telestrat-240-200-2.s | 23 +++++-- 4 files changed, 155 insertions(+), 10 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index b52e8ae37..7b6e52283 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -54,11 +54,43 @@ HRS3 := $51 HRS4 := $53 HRS5 := $55 +HRSFB := $57 +; RS232T +; b0-b3 : speed +; 1111 => 19200 bps (please note that telestrat can't handle this speed with stopping all IRQ except ACIA's one) +; 1100 => 9600 bps (default from telemon) +; 1110 => 4800 bps +; 1010 => 2400 bps +; 1000 => 1200 bps +; 0111 => 600 bps +; 0110 => 300 bps +; 0101 => 150 bps +; 0010 => 75 bps + +; b4 : 0 external clock, 1 internal clock +; b6-b5 : 00 8 bits +; 01 7 bits +; 10 6 bits +; 11 5 bits +; b7 : 0 a stop + +RS232T := $59 + +; RS232C +; b0-b3 : 0 +; b4 : 1 if echo +; b5 : 1 if parity +; b7-b6 : 00 in/out parity odd +; : 01 on/out parity even +; : 10 parity sent, answer not tested +; : 11 SPACE SENT, reception not tested + +RS232C := $5A ; --------------------------------------------------------------------------- ; Low memory -IRQVec := $02fb ; "fast" interrupt vector +IRQVec := $02FB ; "fast" interrupt vector @@ -84,7 +116,7 @@ PRA2 .byte ; Port Register A without handshaking .endstruct -.struct VIA2 ; Versatile Interface Adapter +.struct VIA2 ; Versatile Interface Adapter .res $0320 PRB .byte ; Port Register B PRA .byte ; Port Register A @@ -116,7 +148,7 @@ SCREEN := $BB80 ; --------------------------------------------------------------------------- ; ROM entries -; primitives telemon 2.4 +; telemon primitives (2.4 & 3.x) XRD0 = $08 XRDW0 = $0C XWR0 = $10 @@ -140,10 +172,19 @@ XMUSIC = $45 XZAP = $46 XSHOOT = $47 XSOUT = $67 ; Send A register to RS232, available in telemon 2.4 & 3.x +XHRSSE = $8C ; Put in X and Y +XDRAWA = $8D ; Draw a line +XDRAWR = $8E ; Draw a line XCIRCL = $8F XCURSE = $90 +XCURMO = $91 XPAPER = $92 XINK = $93 +XBOX = $94 +XABOX = $95 +XFILL = $96 +XCHAR = $97 +XSCHAR = $98 ; Draw a string XEXPLO = $9C XPING = $9D @@ -158,6 +199,7 @@ SCRX := $220 SCRY := $224 ADSCRL := $218 ADSCRH := $21C +HRSPAT := $2AA ; Hires pattern : it's used to draw pattern for a line or a circle IRQVECTOR := $2FA diff --git a/include/telestrat.h b/include/telestrat.h index 5a090647b..1865f19a0 100644 --- a/include/telestrat.h +++ b/include/telestrat.h @@ -30,6 +30,76 @@ + +/* 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 + +/* TGI color defines */ +/* White and red are swapped, so that the pallete +** driver is compatible with black-and-white drivers. +*/ +#define TGI_COLOR_BLACK COLOR_BLACK +#define TGI_COLOR_WHITE 1 +#define TGI_COLOR_GREEN COLOR_GREEN +#define TGI_COLOR_YELLOW COLOR_YELLOW +#define TGI_COLOR_BLUE COLOR_BLUE +#define TGI_COLOR_MAGENTA COLOR_MAGENTA +#define TGI_COLOR_CYAN COLOR_CYAN +#define TGI_COLOR_RED 7 + + +extern void telestrat_228_200_3_tgi[]; +extern void telestrat_240_200_2_tgi[]; /* Referred to by tgi_static_stddrv[] */ + +/* Define hardware */ +#include <_6522.h> +#define VIA (*(struct __6522*)0x300) + + + +/* These are defined to be FUNCT + 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 + + + +/* Character codes */ +#define CH_ULCORNER '+' +#define CH_URCORNER '+' +#define CH_LLCORNER '+' +#define CH_LRCORNER '+' +#define CH_TTEE '+' +#define CH_BTEE '+' +#define CH_LTEE '+' +#define CH_RTEE '+' +#define CH_CROSS '+' +#define CH_CURS_UP 11 +#define CH_CURS_DOWN 10 +#define CH_CURS_LEFT 8 +#define CH_CURS_RIGHT 9 +#define CH_DEL 127 +#define CH_ENTER 13 +#define CH_STOP 3 +#define CH_LIRA 95 +#define CH_ESC 27 + + + void oups(); void ping(); void zap(); diff --git a/libsrc/telestrat/tgi/telestrat-228-200-3.s b/libsrc/telestrat/tgi/telestrat-228-200-3.s index 1e42f2ede..e20c2c877 100644 --- a/libsrc/telestrat/tgi/telestrat-228-200-3.s +++ b/libsrc/telestrat/tgi/telestrat-228-200-3.s @@ -55,6 +55,7 @@ YSIZE = 8 ; System font height .addr GETPIXEL .addr LINE .addr BAR + .addr CIRCLE .addr TEXTSTYLE .addr OUTTEXT .addr 0 ; IRQ entry is unused @@ -107,10 +108,13 @@ INIT: ; Switch into graphics mode. BRK_TELEMON(XHIRES) - rts - + ; Done, reset the error code. + lda #TGI_ERR_OK + sta ERROR + rts + ; ------------------------------------------------------------------------ ; GETERROR: Return the error code in A, and clear it. @@ -251,7 +255,17 @@ GETDEFPALETTE: ; SETPIXEL: - ; not done yet + + lda X1 + sta HRS1 + lda Y1 + sta HRS2 + + lda #$80 + sta HRSFB + + BRK_TELEMON(XCURSE) + rts ; ------------------------------------------------------------------------ @@ -274,6 +288,10 @@ LINE: ; not done yet rts +CIRCLE: + ; not done yet + 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. diff --git a/libsrc/telestrat/tgi/telestrat-240-200-2.s b/libsrc/telestrat/tgi/telestrat-240-200-2.s index 3dc90525a..fcc1ce3f2 100644 --- a/libsrc/telestrat/tgi/telestrat-240-200-2.s +++ b/libsrc/telestrat/tgi/telestrat-240-200-2.s @@ -125,7 +125,7 @@ INIT: ; Switch into graphics mode BRK_TELEMON(XHIRES) - rts + ; Done, reset the error code lda #TGI_ERR_OK @@ -248,7 +248,17 @@ GETDEFPALETTE: ; SETPIXEL: - ; not done yet + + lda X1 + sta HRS1 + lda Y1 + sta HRS2 + + lda #$80 ; curset on + sta HRSFB + + BRK_TELEMON(XCURSE) + rts ; ------------------------------------------------------------------------ @@ -268,8 +278,13 @@ GETPIXEL: ; LINE: - ; not done yet - rts + ; not done yet + rts + +CIRCLE: + ; not done yet + 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. From 2b7d4fff5a69599d29281cfaf1b350fb9c342c06 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Fri, 20 Oct 2017 21:29:16 +0200 Subject: [PATCH 0457/2161] comment correction --- asminc/telestrat.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 7b6e52283..424047725 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -58,7 +58,7 @@ HRSFB := $57 ; RS232T ; b0-b3 : speed -; 1111 => 19200 bps (please note that telestrat can't handle this speed with stopping all IRQ except ACIA's one) +; 1111 => 19200 bps (please note that telestrat can't handle this speed without stopping all IRQ except ACIA's one) ; 1100 => 9600 bps (default from telemon) ; 1110 => 4800 bps ; 1010 => 2400 bps From 93f202850ab2350da3e32a6a790248ca618c9a08 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 22 Oct 2017 23:06:56 +0200 Subject: [PATCH 0458/2161] toascii.s added, doc updated, tgi_line & tgi_outtext are available --- asminc/telestrat.inc | 8 ++-- doc/telestrat.sgml | 19 ++++++++- libsrc/telestrat/tgi/telestrat-228-200-3.s | 40 +++++++++++++++++- libsrc/telestrat/tgi/telestrat-240-200-2.s | 49 +++++++++++++++++++--- libsrc/telestrat/toascii.s | 14 +++++++ 5 files changed, 117 insertions(+), 13 deletions(-) create mode 100644 libsrc/telestrat/toascii.s diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 424047725..352aa0657 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -152,7 +152,7 @@ SCREEN := $BB80 XRD0 = $08 XRDW0 = $0C XWR0 = $10 -XWSTR0 = $14 +XWSTR0 = $14 ; write a string in text mode XTEXT = $19 XHIRES = $1A XFILLM = $1C @@ -165,14 +165,14 @@ XCSSCR = $35 ; switch on cursor XCLOSE = $3A ; only in TELEMON 3.x Close file XFWRITE = $3B ; only in TELEMON 3.x write file XSONPS = $40 -XOUPS = $42 +XOUPS = $42 ; sends Oups sound into PSG XPLAY = $43 XSOUND = $44 XMUSIC = $45 XZAP = $46 XSHOOT = $47 XSOUT = $67 ; Send A register to RS232, available in telemon 2.4 & 3.x -XHRSSE = $8C ; Put in X and Y +XHRSSE = $8C ; Set hires position cursor XDRAWA = $8D ; Draw a line XDRAWR = $8E ; Draw a line XCIRCL = $8F @@ -184,7 +184,7 @@ XBOX = $94 XABOX = $95 XFILL = $96 XCHAR = $97 -XSCHAR = $98 ; Draw a string +XSCHAR = $98 ; Draw a string in hires XEXPLO = $9C XPING = $9D diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index fda4dee86..0c85c68c5 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -9,7 +9,7 @@ <date>2017-01-22 <abstract> -An overview over the Telestrat (Telemon 3.0 : http://orix.oric.org) runtime system as it is implemented for the cc65 C +An overview over the Telestrat (Telemon 2.4 & Telemon 3.x : http://orix.oric.org) runtime system as it is implemented for the cc65 C compiler.) </abstract> @@ -113,6 +113,21 @@ structures; accessing the struct fields will access the chip registers. <sect>Loadable drivers<p> +<sect1>TGI<p> + +TGI drivers is available on Oric Telestrat with some functions : + +<itemize> +<item> +<item>tgi_install +<item>tgi_init +<item>tgi_clear +<item>tgi_setpixel +<item>tgi_getmaxx +<item>tgi_getmaxy +</itemize> + + <sect1>Extended memory drivers<p> No extended memory drivers are currently available for the Telestrat. @@ -139,7 +154,7 @@ Telestrat manages also mouse, but it had been no handled yet in this version. <descrip> -Telestrat has a RS232 port, but it's not used +Telestrat has a RS232 port, but it's not usable in cc65. </descrip> diff --git a/libsrc/telestrat/tgi/telestrat-228-200-3.s b/libsrc/telestrat/tgi/telestrat-228-200-3.s index e20c2c877..a4313b092 100644 --- a/libsrc/telestrat/tgi/telestrat-228-200-3.s +++ b/libsrc/telestrat/tgi/telestrat-228-200-3.s @@ -286,9 +286,27 @@ GETPIXEL: LINE: ; not done yet + lda X1 + sta HRS1 + lda Y1 + sta HRS2 + + lda X2 + sta HRS3 + lda Y2 + sta HRS4 + + lda #$ff + sta HRSPAT + + BRK_TELEMON(XDRAWA) + rts + + CIRCLE: + ; not done yet rts @@ -332,5 +350,25 @@ TEXTSTYLE: ; OUTTEXT: - ; not done yet + ; put hires cursor in X & Y + lda #$00 + jsr SETPIXELSETMODE + + + ; count the length of the string + ldy #$00 +loop: + lda (ptr3),y + beq out + iny + bne loop +out: + ; XSCHAR routine from telemon needs to have the length of the string in X register + ; copy Y register to X register. It could be optimized in 65C02 with TYX + tya + tax + + lda ptr3 ; XSCHAR needs in A and Y the adress of the string + ldy ptr3+1 + BRK_TELEMON(XSCHAR) rts diff --git a/libsrc/telestrat/tgi/telestrat-240-200-2.s b/libsrc/telestrat/tgi/telestrat-240-200-2.s index fcc1ce3f2..8a30ddd45 100644 --- a/libsrc/telestrat/tgi/telestrat-240-200-2.s +++ b/libsrc/telestrat/tgi/telestrat-240-200-2.s @@ -125,7 +125,7 @@ INIT: ; Switch into graphics mode BRK_TELEMON(XHIRES) - + ; Done, reset the error code lda #TGI_ERR_OK @@ -248,14 +248,16 @@ GETDEFPALETTE: ; SETPIXEL: + lda #$80 ; curset on +SETPIXELSETMODE: + sta HRSFB lda X1 sta HRS1 lda Y1 sta HRS2 - lda #$80 ; curset on - sta HRSFB + BRK_TELEMON(XCURSE) @@ -278,9 +280,24 @@ GETPIXEL: ; LINE: - ; not done yet - rts + lda X1 + sta HRS1 + lda Y1 + sta HRS2 + + lda X2 + sta HRS3 + lda Y2 + sta HRS4 + + lda #$ff + sta HRSPAT + + BRK_TELEMON(XDRAWA) + + rts + CIRCLE: ; not done yet rts @@ -325,5 +342,25 @@ TEXTSTYLE: ; OUTTEXT: - ; Not done yet + ; put hires cursor in X & Y + lda #$00 + jsr SETPIXELSETMODE + + + ; count the length of the string + ldy #$00 +loop: + lda (ptr3),y + beq out + iny + bne loop +out: + ; XSCHAR routine from telemon needs to have the length of the string in X register + ; copy Y register to X register. It could be optimized in 65C02 with TYX + tya + tax + + lda ptr3 ; XSCHAR needs in A and Y the adress of the string + ldy ptr3+1 + BRK_TELEMON(XSCHAR) rts diff --git a/libsrc/telestrat/toascii.s b/libsrc/telestrat/toascii.s new file mode 100644 index 000000000..77f050021 --- /dev/null +++ b/libsrc/telestrat/toascii.s @@ -0,0 +1,14 @@ +; +; char __fastcall__ toascii (char c); +; /* Convert a target-specific character to ASCII. */ +; + +.export _toascii + +.proc _toascii + +; .X must be zero, on return. + ldx #>$0000 + rts + +.endproc From 0517a2c2ab75de45e3a3d80894edf2dff1f8e935 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 22 Oct 2017 23:12:12 +0200 Subject: [PATCH 0459/2161] removing extra spaces --- libsrc/telestrat/tgi/telestrat-228-200-3.s | 2 -- 1 file changed, 2 deletions(-) diff --git a/libsrc/telestrat/tgi/telestrat-228-200-3.s b/libsrc/telestrat/tgi/telestrat-228-200-3.s index a4313b092..1ce4fc927 100644 --- a/libsrc/telestrat/tgi/telestrat-228-200-3.s +++ b/libsrc/telestrat/tgi/telestrat-228-200-3.s @@ -300,13 +300,11 @@ LINE: sta HRSPAT BRK_TELEMON(XDRAWA) - rts CIRCLE: - ; not done yet rts From c8d6ca908db019dfeacb924cfe44ffff73c823dc Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 23 Oct 2017 18:22:51 +0200 Subject: [PATCH 0460/2161] Minor style fix. --- 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 acfd95fed..dfd5366bb 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -537,7 +537,7 @@ static void FunctionCall (ExprDesc* Expr) if (IsFuncPtr) { if (Func->WrappedCall) { - Warning("Calling a wrapped function via a pointer, wrapped-call will not be used"); + 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 From bd9b4ef60c9de6c4b2f0bad2a50d624daf066536 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 23 Oct 2017 18:35:06 +0200 Subject: [PATCH 0461/2161] Replaced three (logically) identical files with a single file. --- libsrc/atmos/toascii.s | 14 -------------- libsrc/{apple2 => common}/toascii.s | 2 +- libsrc/lynx/toascii.s | 16 ---------------- 3 files changed, 1 insertion(+), 31 deletions(-) delete mode 100644 libsrc/atmos/toascii.s rename libsrc/{apple2 => common}/toascii.s (87%) delete mode 100644 libsrc/lynx/toascii.s diff --git a/libsrc/atmos/toascii.s b/libsrc/atmos/toascii.s deleted file mode 100644 index 77f050021..000000000 --- a/libsrc/atmos/toascii.s +++ /dev/null @@ -1,14 +0,0 @@ -; -; char __fastcall__ toascii (char c); -; /* Convert a target-specific character to ASCII. */ -; - -.export _toascii - -.proc _toascii - -; .X must be zero, on return. - ldx #>$0000 - rts - -.endproc diff --git a/libsrc/apple2/toascii.s b/libsrc/common/toascii.s similarity index 87% rename from libsrc/apple2/toascii.s rename to libsrc/common/toascii.s index a3f946e64..5b1943aca 100644 --- a/libsrc/apple2/toascii.s +++ b/libsrc/common/toascii.s @@ -6,5 +6,5 @@ .export _toascii _toascii: - ldx #$00 + ldx #>$0000 rts diff --git a/libsrc/lynx/toascii.s b/libsrc/lynx/toascii.s deleted file mode 100644 index 2a2088688..000000000 --- a/libsrc/lynx/toascii.s +++ /dev/null @@ -1,16 +0,0 @@ -; -; unsigned char __fastcall__ toascii (unsigned char c); -; /* Convert a target specific character to ascii */ -; - -.export _toascii - -.proc _toascii - -; X must be zero on return - ldx #0 - -; Done! - rts - -.endproc From c0ce20e9ccb3eb0dfd57d7be8db7b00dafde7471 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 23 Oct 2017 18:57:28 +0200 Subject: [PATCH 0462/2161] Save/restore jmpvec as it is used by generated code - see g_callind(). --- libsrc/common/interrupt.s | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/libsrc/common/interrupt.s b/libsrc/common/interrupt.s index 950d3d787..6bdbb5fe4 100644 --- a/libsrc/common/interrupt.s +++ b/libsrc/common/interrupt.s @@ -8,7 +8,7 @@ .export _set_irq, _reset_irq .interruptor clevel_irq, 1 ; Export as low priority IRQ handler - .import popax, __ZP_START__ + .import popax, __ZP_START__, jmpvec .include "zeropage.inc" @@ -84,6 +84,12 @@ zpsave: .res zpsavespace dex bpl @L2 + ; Save jmpvec + lda jmpvec+1 + pha + lda jmpvec+2 + pha + ; Set C level interrupt stack lda irqsp ldx irqsp+1 @@ -93,15 +99,21 @@ zpsave: .res zpsavespace ; Call C level interrupt request handler jsr irqvec - ; Copy back our zero page content + ; Mark interrupt handled / not handled + lsr + + ; Restore our zero page content ldx #.sizeof(::zpsave)-1 -@L3: ldy zpsave,x - sty <__ZP_START__,x +@L3: lda zpsave,x + sta <__ZP_START__,x dex bpl @L3 - ; Mark interrupt handled / not handled and return - lsr + ; Restore jmpvec and return + pla + sta jmpvec+2 + pla + sta jmpvec+1 rts .endproc From 1403d797f0bd1818cbafb8f5311e745762098f5e Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 23 Oct 2017 20:52:22 +0200 Subject: [PATCH 0463/2161] Remove toascii.s --- libsrc/telestrat/toascii.s | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 libsrc/telestrat/toascii.s diff --git a/libsrc/telestrat/toascii.s b/libsrc/telestrat/toascii.s deleted file mode 100644 index 77f050021..000000000 --- a/libsrc/telestrat/toascii.s +++ /dev/null @@ -1,14 +0,0 @@ -; -; char __fastcall__ toascii (char c); -; /* Convert a target-specific character to ASCII. */ -; - -.export _toascii - -.proc _toascii - -; .X must be zero, on return. - ldx #>$0000 - rts - -.endproc From ed4458c1621d340b948acd08e431f3fb066b1a7c Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 23 Oct 2017 23:00:43 +0200 Subject: [PATCH 0464/2161] Comment correction --- asminc/telestrat.inc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 352aa0657..9b2202110 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -20,9 +20,9 @@ FNAME_LEN = 11 ; maximum length of file-name ; this identifers are used for channel management ; -XKBD = $80 ; Keyboard +XKBD = $80 ; keyboard XRSE = $83 ; RS232 in -XSCR = $88 ; Screen +XSCR = $88 ; screen XRSS = $90 ; RS232 out @@ -165,16 +165,16 @@ XCSSCR = $35 ; switch on cursor XCLOSE = $3A ; only in TELEMON 3.x Close file XFWRITE = $3B ; only in TELEMON 3.x write file XSONPS = $40 -XOUPS = $42 ; sends Oups sound into PSG +XOUPS = $42 ; send Oups sound into PSG XPLAY = $43 XSOUND = $44 XMUSIC = $45 XZAP = $46 XSHOOT = $47 -XSOUT = $67 ; Send A register to RS232, available in telemon 2.4 & 3.x -XHRSSE = $8C ; Set hires position cursor -XDRAWA = $8D ; Draw a line -XDRAWR = $8E ; Draw a line +XSOUT = $67 ; send A register to RS232, available in telemon 2.4 & 3.x +XHRSSE = $8C ; set hires position cursor +XDRAWA = $8D ; draw a line +XDRAWR = $8E ; draw a line XCIRCL = $8F XCURSE = $90 XCURMO = $91 @@ -184,7 +184,7 @@ XBOX = $94 XABOX = $95 XFILL = $96 XCHAR = $97 -XSCHAR = $98 ; Draw a string in hires +XSCHAR = $98 ; draw a string in hires XEXPLO = $9C XPING = $9D @@ -199,7 +199,7 @@ SCRX := $220 SCRY := $224 ADSCRL := $218 ADSCRH := $21C -HRSPAT := $2AA ; Hires pattern : it's used to draw pattern for a line or a circle +HRSPAT := $2AA ; hires pattern : it's used to draw pattern for a line or a circle IRQVECTOR := $2FA From ebfd218f62e94b91f80f8e9effef1e658926163a Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 23 Oct 2017 23:02:54 +0200 Subject: [PATCH 0465/2161] Comment correction --- asminc/telestrat.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 9b2202110..737c4b6ae 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -17,7 +17,7 @@ FNAME_LEN = 11 ; maximum length of file-name ; --------------------------------------------------------------------------- ; I/O Identifier -; this identifers are used for channel management +; theses identifers are used for channel management ; XKBD = $80 ; keyboard From 3bc0843afc7ed291ca3c8278631d159f9387013c Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 23 Oct 2017 23:25:08 +0200 Subject: [PATCH 0466/2161] FIX label for setpixelmode --- libsrc/telestrat/tgi/telestrat-228-200-3.s | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libsrc/telestrat/tgi/telestrat-228-200-3.s b/libsrc/telestrat/tgi/telestrat-228-200-3.s index 1ce4fc927..09c308e26 100644 --- a/libsrc/telestrat/tgi/telestrat-228-200-3.s +++ b/libsrc/telestrat/tgi/telestrat-228-200-3.s @@ -255,14 +255,16 @@ GETDEFPALETTE: ; SETPIXEL: + lda #$80 +SETPIXELSETMODE: + sta HRSFB lda X1 sta HRS1 lda Y1 sta HRS2 - lda #$80 - sta HRSFB + BRK_TELEMON(XCURSE) From 7435c2f3ca932a9945757cb0ec755ba6613b6157 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Thu, 26 Oct 2017 22:00:12 +0200 Subject: [PATCH 0467/2161] Fix doc/telestrat.sgml --- doc/telestrat.sgml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index 2d05f8985..d85dac2a3 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -9,10 +9,7 @@ <date>2017-01-22 <abstract> - -An overview over the Telestrat (Telemon 2.4 & Telemon 3.x : http://orix.oric.org) runtime system as it is implemented for the cc65 C -compiler.) - +An overview over the Telestrat (Telemon 2.4 & Telemon 3.x : http://orix.oric.org) runtime system as it is implemented for the cc65 C compiler. </abstract> <!-- Table of contents --> From 807b55862d7f51a8d1106a501d4be82d9c15e9de Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 28 Oct 2017 00:37:47 +0200 Subject: [PATCH 0468/2161] Now mkdir is working --- asminc/telestrat.inc | 1 + libsrc/telestrat/oserror.s | 17 +++++++++++++++++ libsrc/telestrat/sysmkdir.s | 30 ++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 libsrc/telestrat/oserror.s create mode 100644 libsrc/telestrat/sysmkdir.s diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 737c4b6ae..cb28919c2 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -171,6 +171,7 @@ XSOUND = $44 XMUSIC = $45 XZAP = $46 XSHOOT = $47 +XMKDIR = $4B ; create a folder. Only available in telemon 3.x XSOUT = $67 ; send A register to RS232, available in telemon 2.4 & 3.x XHRSSE = $8C ; set hires position cursor XDRAWA = $8D ; draw a line diff --git a/libsrc/telestrat/oserror.s b/libsrc/telestrat/oserror.s new file mode 100644 index 000000000..e3b9e619a --- /dev/null +++ b/libsrc/telestrat/oserror.s @@ -0,0 +1,17 @@ +; +; Jede, 2017-10-27 +; +; int __fastcall__ _osmaperrno (unsigned char oserror); +; /* Map a system specific error into a system independent code */ +; + + .include "errno.inc" + .export __osmaperrno + +.proc __osmaperrno + + lda #<EUNKNOWN + ldx #>EUNKNOWN + rts + +.endproc diff --git a/libsrc/telestrat/sysmkdir.s b/libsrc/telestrat/sysmkdir.s new file mode 100644 index 000000000..26d97c4b0 --- /dev/null +++ b/libsrc/telestrat/sysmkdir.s @@ -0,0 +1,30 @@ +; +; Jede (jede@oric.org), 2017-10-27 +; +; unsigned char _sysmkdir (const char* name, ...); +; + + .export __sysmkdir + .import addysp, popax + + .include "telestrat.inc" + .include "zeropage.inc" + + +__sysmkdir: + ; Throw away all parameters except the name + dey + dey + jsr addysp + + ; Get name + jsr popax + + ; Call telemon primitive + + BRK_TELEMON(XMKDIR) + + rts + + + From eae485dc64c0ea1aab567fe7500122beda9b9eb0 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 28 Oct 2017 00:40:56 +0200 Subject: [PATCH 0469/2161] Empty item removed --- doc/telestrat.sgml | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index d85dac2a3..b640e5aa8 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -120,7 +120,6 @@ structures; accessing the struct fields will access the chip registers. TGI drivers is available on Oric Telestrat with some functions : <itemize> -<item> <item>tgi_install <item>tgi_init <item>tgi_clear From de1f80571aa0d4c45fbcc67b184d70da65bee0a3 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 31 Oct 2017 00:45:17 -0400 Subject: [PATCH 0470/2161] Fixed the way that the disassembler looks for the end of a segment. It checks only the bytes that actually were printed. It won't show a bad error message when disassembling address $0000. Fixes #506 on cc65's Github project. --- src/da65/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/da65/main.c b/src/da65/main.c index 0b0bf19e7..1454d01fb 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -350,6 +350,7 @@ static void OneOpcode (unsigned RemainingBytes) /* Disassemble one opcode */ { unsigned I; + unsigned OldPC = PC; /* Get the opcode from the current address */ unsigned char OPC = GetCodeByte (PC); @@ -476,7 +477,7 @@ static void OneOpcode (unsigned RemainingBytes) /* Change back to the default CODE segment if ** a named segment stops at the current address. */ - for (I = D->Size; I >= 1; --I) { + for (I = PC - OldPC; I > 0; --I) { if (IsSegmentEnd (PC - I)) { EndSegment (); break; From 9ee443199454323c497753ce16ebf1c381f56bea Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Thu, 2 Nov 2017 21:11:08 +0100 Subject: [PATCH 0471/2161] Add files via upload Alternative joystick interface --- libsrc/atmos/joy/atmos-ijk.s | 146 +++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 libsrc/atmos/joy/atmos-ijk.s diff --git a/libsrc/atmos/joy/atmos-ijk.s b/libsrc/atmos/joy/atmos-ijk.s new file mode 100644 index 000000000..f59f6b96a --- /dev/null +++ b/libsrc/atmos/joy/atmos-ijk.s @@ -0,0 +1,146 @@ +; +; IJK joystick driver for the Atmos +; Can be used multiple times when statically linked to the application. +; +; 2002-12-20, Based on Ullrich von Bassewitz's code. +; 2017-11-01, Stefan Haubenthal +; + + .include "joy-kernel.inc" + .include "joy-error.inc" + .include "atmos.inc" + + .macpack module + + +; ------------------------------------------------------------------------ +; Header. Includes jump table + + module_header _atmos_ijk_joy + +; Driver signature + + .byte $6A, $6F, $79 ; "joy" + .byte JOY_API_VERSION ; Driver API version number + +; Library reference + + .addr $0000 + +; Button state masks (8 values) + + .byte $10 ; JOY_UP + .byte $08 ; JOY_DOWN + .byte $01 ; JOY_LEFT + .byte $02 ; JOY_RIGHT + .byte $20 ; JOY_FIRE + .byte $00 ; Future expansion + .byte $00 ; Future expansion + .byte $00 ; Future expansion + +; Jump table. + + .addr INSTALL + .addr UNINSTALL + .addr COUNT + .addr READ + .addr 0 ; IRQ entry unused + +; ------------------------------------------------------------------------ +; Constants + +JOY_COUNT = 2 ; Number of joysticks we support + +.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 #%11000000 + sta VIA::DDRA + sta VIA::PRA + lda VIA::PRA + and #%00100000 + bne ijkPresent + lda #<JOY_ERR_NO_DEVICE + .byte $2C ; Skip next opcode +ijkPresent: + lda #<JOY_ERR_OK + ldx #>JOY_ERR_OK +; 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: + bne right + + ; Ensure Printer Strobe is set to Output + lda #%10110111 + sta VIA::DDRB + ; Set Strobe Low + lda #%00000000 + sta VIA::PRB + ; Set Top two bits of PortA to Output and rest as Input + lda #%11000000 + sta VIA::DDRA + + ; Select Left Joystick + lda #%01111111 + sta VIA::PRA + ; Read back Left Joystick state + lda VIA::PRA + ; Mask out unused bits + and #%00011111 + ; Invert Bits + eor #%00011111 + ; Index table to conform to Generic Format + tax + lda GenericIJKBits,X + bne L1 + +right: + ; Select Right Joystick + lda #%10111111 + sta VIA::PRA + ; Read back Right Joystick state and rejig bits + lda VIA::PRA + and #%00011111 + eor #%00011111 + tax + lda GenericIJKBits,X + + ; Restore VIA PortA state +L1: ldx #%11111111 + stx VIA::DDRA + inx ; x=0 + rts + +.rodata +GenericIJKBits: + .byte 0,2,1,3,32,34,33,0,8,10,9,0,40,42,41,0 + .byte 16,18,17,0,48,50,49,0,0,0,0,0,0,0,0,0 From e64c42f224d62d514dabfc6842fb385cb502e884 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Fri, 3 Nov 2017 20:49:49 +0100 Subject: [PATCH 0472/2161] Update atmos.sgml --- doc/atmos.sgml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/atmos.sgml b/doc/atmos.sgml index 68f7f9d65..9e61fbd1c 100644 --- a/doc/atmos.sgml +++ b/doc/atmos.sgml @@ -159,7 +159,10 @@ No extended memory drivers are currently available for the Atmos. <descrip> <tag><tt/atmos-pase.joy (atmos_pase_joy)/</tag> - Supports two standard joysticks connected to the P.A.S.E. interface of the Atmos. + Supports two standard joysticks connected to a P.A.S.E. / Altai interface of the Atmos. + + <tag><tt/atmos-ijk.joy (atmos_ijk_joy)/</tag> + Supports two standard joysticks connected to an IJK interface of the Atmos. </descrip><p> From d3451bb299d726651b3fd002d1d314563e7a16b2 Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Mon, 6 Nov 2017 19:46:26 +0100 Subject: [PATCH 0473/2161] Fix 256 codes of same length --- libsrc/zlib/inflatemem.s | 44 ++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/libsrc/zlib/inflatemem.s b/libsrc/zlib/inflatemem.s index 27802fbff..f49c5fc79 100644 --- a/libsrc/zlib/inflatemem.s +++ b/libsrc/zlib/inflatemem.s @@ -1,5 +1,5 @@ ; -; 2017-02-12, Piotr Fusik +; 2017-11-06, Piotr Fusik ; ; unsigned __fastcall__ inflatemem (char* dest, const char* source); ; @@ -103,7 +103,7 @@ inflate_blockLoop: ; ldy #0 sty getBit_buffer ; ignore bits until byte boundary jsr getWord ; skip the length we don't need - jsr getWord ; get the two's complement length + jsr getWord ; get the one's complement length sta inflateStored_pageCounter bcs inflateStored_firstByte ; jmp inflateStored_copyByte: @@ -332,7 +332,7 @@ inflateDynamic_storeControl: ; Build Huffman trees basing on code lengths (in bits) ; stored in the *SymbolCodeLength arrays buildHuffmanTree: -; Clear nBitCode_totalCount, nBitCode_literalCount, nBitCode_controlCount +; Clear nBitCode_literalCount, nBitCode_controlCount tya ; lda #0 buildHuffmanTree_clear: @@ -344,22 +344,20 @@ buildHuffmanTree_clear: buildHuffmanTree_countCodeLengths: ldx literalSymbolCodeLength,y inc nBitCode_literalCount,x - inc nBitCode_totalCount,x cpy #CONTROL_SYMBOLS bcs buildHuffmanTree_noControlSymbol ldx controlSymbolCodeLength,y inc nBitCode_controlCount,x - inc nBitCode_totalCount,x buildHuffmanTree_noControlSymbol: iny bne buildHuffmanTree_countCodeLengths ; Calculate offsets of symbols sorted by code length ; lda #0 - ldx #$100-3*TREE_SIZE + ldx #$100-4*TREE_SIZE buildHuffmanTree_calculateOffsets: - sta nBitCode_literalOffset+3*TREE_SIZE-$100,x + sta nBitCode_literalOffset+4*TREE_SIZE-$100,x clc - adc nBitCode_literalCount+3*TREE_SIZE-$100,x + adc nBitCode_literalCount+4*TREE_SIZE-$100,x inx bne buildHuffmanTree_calculateOffsets ; Put symbols in their place in the sorted array @@ -397,26 +395,26 @@ fetchCode_nextBit: rol a inx sec - sbc nBitCode_totalCount,x + sbc nBitCode_literalCount,x + bcc fetchCode_literal +; sec + sbc nBitCode_controlCount,x bcs fetchCode_nextBit ; clc - adc nBitCode_controlCount,x - bcs fetchCode_control + adc nBitCode_controlOffset,x + tax + lda codeToControlSymbol,x + and #$1f ; make distance symbols zero-based + tax +; sec + rts +fetchCode_literal: ; clc adc nBitCode_literalOffset,x tax lda codeToLiteralSymbol,x clc rts -fetchCode_control: -; sec - adc nBitCode_controlOffset-1,x - tax - lda codeToControlSymbol-1,x - and #$1f ; make distance symbols zero-based - tax - sec - rts ; Read A minus 1 bits, but no more than 8 getAMinus1BitsMax8: @@ -517,14 +515,12 @@ controlSymbolCodeLength: ; Huffman trees. nBitCode_clearFrom: -nBitCode_totalCount: - .res 2*TREE_SIZE nBitCode_literalCount: - .res TREE_SIZE + .res 2*TREE_SIZE nBitCode_controlCount: .res 2*TREE_SIZE nBitCode_literalOffset: - .res TREE_SIZE + .res 2*TREE_SIZE nBitCode_controlOffset: .res 2*TREE_SIZE From afcfba935594879742d85469d3cb1c38a25fa6f4 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 6 Nov 2017 21:02:14 +0100 Subject: [PATCH 0474/2161] Use macro actually defined in cbm_filetype.h. --- include/dirent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dirent.h b/include/dirent.h index b5e1be135..124c7f224 100644 --- a/include/dirent.h +++ b/include/dirent.h @@ -107,7 +107,7 @@ struct dirent { #define _DE_ISREG(t) (((t) & _CBM_T_REG) != 0) #define _DE_ISDIR(t) ((t) == _CBM_T_DIR) -#define _DE_ISLBL(t) ((t) == _CBM_T_HDR) +#define _DE_ISLBL(t) ((t) == _CBM_T_HEADER) #define _DE_ISLNK(t) ((t) == _CBM_T_LNK) #elif defined(__LYNX__) From 84edf4cbfd22e5e20670769ea00adaeb27d12a6f Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Tue, 7 Nov 2017 20:10:19 +0100 Subject: [PATCH 0475/2161] Fix more than 256 codes of same length. Fix all 256 literal codes of same length. --- libsrc/zlib/inflatemem.s | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/libsrc/zlib/inflatemem.s b/libsrc/zlib/inflatemem.s index f49c5fc79..bc89f2016 100644 --- a/libsrc/zlib/inflatemem.s +++ b/libsrc/zlib/inflatemem.s @@ -1,5 +1,5 @@ ; -; 2017-11-06, Piotr Fusik +; 2017-11-07, Piotr Fusik ; ; unsigned __fastcall__ inflatemem (char* dest, const char* source); ; @@ -344,6 +344,9 @@ buildHuffmanTree_clear: buildHuffmanTree_countCodeLengths: ldx literalSymbolCodeLength,y inc nBitCode_literalCount,x + bne buildHuffmanTree_notAllLiterals + stx allLiteralsCodeLength +buildHuffmanTree_notAllLiterals: cpy #CONTROL_SYMBOLS bcs buildHuffmanTree_noControlSymbol ldx controlSymbolCodeLength,y @@ -394,12 +397,33 @@ fetchCode_nextBit: jsr getBit rol a inx + bcs fetchCode_ge256 +; are all 256 literal codes of this length? + cpx allLiteralsCodeLength + beq fetchCode_allLiterals +; is it literal code of length X? sec sbc nBitCode_literalCount,x - bcc fetchCode_literal + bcs fetchCode_notLiteral +; literal code +; clc + adc nBitCode_literalOffset,x + tax + lda codeToLiteralSymbol,x +fetchCode_allLiterals: + clc + rts +; code >= 256, must be control +fetchCode_ge256: +; sec + sbc nBitCode_literalCount,x + sec +; is it control code of length X? +fetchCode_notLiteral: ; sec sbc nBitCode_controlCount,x bcs fetchCode_nextBit +; control code ; clc adc nBitCode_controlOffset,x tax @@ -408,13 +432,6 @@ fetchCode_nextBit: tax ; sec rts -fetchCode_literal: -; clc - adc nBitCode_literalOffset,x - tax - lda codeToLiteralSymbol,x - clc - rts ; Read A minus 1 bits, but no more than 8 getAMinus1BitsMax8: @@ -523,6 +540,8 @@ nBitCode_literalOffset: .res 2*TREE_SIZE nBitCode_controlOffset: .res 2*TREE_SIZE +allLiteralsCodeLength: + .res 1 codeToLiteralSymbol: .res 256 From e4a235b23370d3842ce1c048ecbcf23d4498cfe2 Mon Sep 17 00:00:00 2001 From: "U-AMAIISDOM\\fcaruso" <fcaruso@NCEL46741.iis.amadeus.net> Date: Thu, 9 Nov 2017 13:51:04 +0100 Subject: [PATCH 0476/2161] Correct bits in gamate joystick detection --- libsrc/gamate/joy/gamate-stdjoy.s | 1 + 1 file changed, 1 insertion(+) diff --git a/libsrc/gamate/joy/gamate-stdjoy.s b/libsrc/gamate/joy/gamate-stdjoy.s index d10eb6f41..f6b303dba 100644 --- a/libsrc/gamate/joy/gamate-stdjoy.s +++ b/libsrc/gamate/joy/gamate-stdjoy.s @@ -79,6 +79,7 @@ COUNT: READJOY: lda JOY_DATA + eor #$ff ldx #0 rts From bf0ae229691ccbdb17b57e0b865f30445f6b0b3e Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <Fabrizio_Caruso@hotmail.com> Date: Thu, 9 Nov 2017 16:36:06 +0100 Subject: [PATCH 0477/2161] Update gamate-stdjoy.s --- libsrc/gamate/joy/gamate-stdjoy.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/gamate/joy/gamate-stdjoy.s b/libsrc/gamate/joy/gamate-stdjoy.s index f6b303dba..a5bd24ef2 100644 --- a/libsrc/gamate/joy/gamate-stdjoy.s +++ b/libsrc/gamate/joy/gamate-stdjoy.s @@ -79,7 +79,7 @@ COUNT: READJOY: lda JOY_DATA - eor #$ff + eor #$ff ldx #0 rts From 0a61b061c70d538453c1ffe3f846f06f078c9b71 Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <Fabrizio_Caruso@hotmail.com> Date: Thu, 9 Nov 2017 16:42:52 +0100 Subject: [PATCH 0478/2161] Update gamate-stdjoy.s --- libsrc/gamate/joy/gamate-stdjoy.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/gamate/joy/gamate-stdjoy.s b/libsrc/gamate/joy/gamate-stdjoy.s index a5bd24ef2..801b40acd 100644 --- a/libsrc/gamate/joy/gamate-stdjoy.s +++ b/libsrc/gamate/joy/gamate-stdjoy.s @@ -79,7 +79,7 @@ COUNT: READJOY: lda JOY_DATA - eor #$ff + eor #$FF ldx #0 rts From 2fd99e9dece66a09336f50c9a67a04a81be18824 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Thu, 9 Nov 2017 17:36:21 +0100 Subject: [PATCH 0479/2161] Missing declaration --- include/atmos.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/atmos.h b/include/atmos.h index c642f9e2a..d9f6d103b 100644 --- a/include/atmos.h +++ b/include/atmos.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2002 Debrune Jérome, <jede@oric.org> */ +/* (C) 2002 Debrune Jérome, <jede@oric.org> */ /* (C) 2003-2013 Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ @@ -129,6 +129,7 @@ /* The addresses of the static drivers */ extern void atmos_pase_joy[]; /* Referred to by joy_static_stddrv[] */ +extern void atmos_ijk_joy[]; extern void atmos_acia_ser[]; extern void atmos_228_200_3_tgi[]; extern void atmos_240_200_2_tgi[]; /* Referred to by tgi_static_stddrv[] */ From 64ed0a1937fe9ab172c7a12bfe06d9f06130470a Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Fri, 10 Nov 2017 10:58:01 +0100 Subject: [PATCH 0480/2161] Doc modified --- doc/telestrat.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index b640e5aa8..76b3cdd30 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -120,12 +120,12 @@ structures; accessing the struct fields will access the chip registers. TGI drivers is available on Oric Telestrat with some functions : <itemize> +<item>tgi_done <item>tgi_install <item>tgi_init <item>tgi_clear +<item>tgi_line <item>tgi_setpixel -<item>tgi_getmaxx -<item>tgi_getmaxy </itemize> From 3c97a04b252df1903f03ef3b9883f2eed675d496 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 12 Nov 2017 10:42:09 +0100 Subject: [PATCH 0481/2161] Fix cc65 doc for telestrat target --- doc/cc65.sgml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index cd94f50ac..11a5937b2 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -407,6 +407,7 @@ Here is a description of all the command line options: <item>sim6502 <item>sim65c02 <item>supervision + <item>telestrat <item>vic20 </itemize> @@ -941,6 +942,10 @@ The compiler defines several macros at startup: This macro is defined if the target is the Supervision (-t supervision). + <tag><tt>__TELESTRAT__</tt></tag> + + This macro is defined if the target is the Telestrat (-t telestrat). + <tag><tt>__TIME__</tt></tag> This macro expands to the time of translation of the preprocessing From 06794b221d0bd26c90baad71fbbd23ad5301fe16 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 13 Nov 2017 20:38:22 +0100 Subject: [PATCH 0482/2161] Made cbm_k_untlk() available. --- include/cbm.h | 1 + libsrc/cbm/c_untlk.s | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/cbm.h b/include/cbm.h index a4b232406..da63375b2 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -209,6 +209,7 @@ void __fastcall__ cbm_k_setnam (const char* Name); void __fastcall__ cbm_k_talk (unsigned char dev); void cbm_k_udtim (void); void cbm_k_unlsn (void); +void cbm_k_untlk (void); diff --git a/libsrc/cbm/c_untlk.s b/libsrc/cbm/c_untlk.s index 1d71c168b..3865564cd 100644 --- a/libsrc/cbm/c_untlk.s +++ b/libsrc/cbm/c_untlk.s @@ -1,11 +1,11 @@ ; ; Ullrich von Bassewitz, 03.06.1999 ; -; void cbm_untlk (void); +; void cbm_k_untlk (void); ; - .export _cbm_untlk + .export _cbm_k_untlk .import UNTLK -_cbm_untlk = UNTLK +_cbm_k_untlk = UNTLK From 4e0958eae6a8ff3361506aea09c1fb356ac46e93 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Tue, 14 Nov 2017 22:04:57 +0100 Subject: [PATCH 0483/2161] Bug corrected : Fwrite did not return number of byte written. --- libsrc/telestrat/write.s | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/libsrc/telestrat/write.s b/libsrc/telestrat/write.s index 8c2bc08f7..4e059a311 100644 --- a/libsrc/telestrat/write.s +++ b/libsrc/telestrat/write.s @@ -17,7 +17,7 @@ sta ptr2 txa eor #$FF - sta ptr2+1 ; Remember -count-1 + sta ptr2+1 ; remember -count-1 jsr popax ; get buf sta ptr1 @@ -32,7 +32,7 @@ next: cmp #1 beq L1 - ; Here it's a file opened + ; here it's a file opened lda ptr1 sta PTR_READ_DEST lda ptr1+1 @@ -40,6 +40,16 @@ next: lda ptr3 ldy ptr3+1 BRK_TELEMON XFWRITE + ; compute nb of bytes written + + + lda PTR_READ_DEST+1 + sec + sbc ptr1+1 + tax + lda PTR_READ_DEST + sec + sbc ptr1 rts @@ -50,23 +60,23 @@ L1: inc ptr2 L2: ldy #0 lda (ptr1),y tax - cpx #$0A ; Check for \n + 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 - BRK_TELEMON XWR0 ; Macro ; + BRK_TELEMON XWR0 ; macro send char to screen (channel 0 in telemon terms) + lda #$0D ; return to the beggining of the line + BRK_TELEMON XWR0 ; macro ldx #$0D L3: - BRK_TELEMON XWR0 ; Macro + BRK_TELEMON XWR0 ; macro inc ptr1 bne L1 inc ptr1+1 jmp L1 -; No error, return count + ; No error, return count L9: lda ptr3 ldx ptr3+1 From 9ead405938848f3ff8b1f4a8450dcd21e6bc68ec Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 15 Nov 2017 00:13:06 +0100 Subject: [PATCH 0484/2161] Creativision documentation enhancements. --- doc/creativision.sgml | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/doc/creativision.sgml b/doc/creativision.sgml index 64623b3b2..29653ce0f 100644 --- a/doc/creativision.sgml +++ b/doc/creativision.sgml @@ -4,7 +4,7 @@ <title>VTech Creativision (aka Funvision) specific information for cc65 <author><url url="mailto:polluks+cc65@sdf.lonestar.org" name="Stefan A. Haubenthal"> -<date>2016-04-14 +<date>2017-11-15 <abstract> An overview over the Creativision runtime system as it is implemented for the @@ -31,14 +31,16 @@ more than one platform. Please see the function reference for more information. <sect>Binary format<p> The standard binary output format generated by the linker for the Creativision target -is a 4 kbyte machine language program. It is of course possible to change -this behaviour by using one of the different linker configs. +is a 4 KB ROM image. To create an 8 KB ROM a custom linker script has +to be used. <sect>Memory layout<p> -cc65 generated programs with the default setup run with the I/O area enabled, -which gives a usable memory range of $B000 - $BEFF. -More ROM may need additional bankswitching code. +cc65 generated programs with the default setup are 4 KB in size, +occupying $B000 - $BFFF. Usable memory space for the +user program is $B000 - $BEFF. $BF00 - +$BFFF is reserved for the runtime and cartridge configuration +area. Special locations: @@ -47,11 +49,15 @@ Special locations: The text screen is located at VRAM $1000. <tag/Stack/ - The C runtime stack is located at $3FF and growing downwards. + The C runtime stack is located at $03FF and growing downwards. + + <tag/RAM/ + The available RAM for cc65 programs of an unexpanded Creativision + starts at $01FA and ends at $03FF. <tag/Heap/ - The C heap is located at the end of the program and grows towards the C - runtime stack. + The C heap is located at the end of the program's data area and + grows towards the C runtime stack. </descrip><p> From 12bfed04b1cc7cf224e95afebe13d75d7978730f Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 21 Nov 2017 06:53:26 +0100 Subject: [PATCH 0485/2161] Create supervision-stdjoy.s --- libsrc/supervision/joy/supervision-stdjoy.s | 93 +++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 libsrc/supervision/joy/supervision-stdjoy.s diff --git a/libsrc/supervision/joy/supervision-stdjoy.s b/libsrc/supervision/joy/supervision-stdjoy.s new file mode 100644 index 000000000..2d89aa6cb --- /dev/null +++ b/libsrc/supervision/joy/supervision-stdjoy.s @@ -0,0 +1,93 @@ +; +; Standard joystick driver for the Supervision +; + + .include "joy-kernel.inc" + .include "joy-error.inc" + .include "supervision.inc" + + .macpack module + + +; ------------------------------------------------------------------------ +; Header. Includes jump table + + module_header _supervision_stdjoy_joy + +; Driver signature + + .byte $6A, $6F, $79 ; "joy" + .byte JOY_API_VERSION ; Driver API version number + +; Library reference + + .addr $0000 + +; Button state masks (8 values) + + .byte $08 ; JOY_UP + .byte $04 ; JOY_DOWN + .byte $02 ; JOY_LEFT + .byte $01 ; JOY_RIGHT + .byte $20 ; JOY_FIRE_A + .byte $10 ; JOY_FIRE_B + .byte $40 ; JOY_SELECT + .byte $80 ; JOY_START + +; Jump table. + + .addr INSTALL + .addr UNINSTALL + .addr COUNT + .addr READJOY + .addr 0 ; IRQ entry unused + +; ------------------------------------------------------------------------ +; Constants + +JOY_COUNT = 1 ; Number of joysticks we support + + +.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 + ldx #>JOY_ERR_OK + +; rts ; Run into UNINSTALL instead + +; ------------------------------------------------------------------------ +; DEINSTALL 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. +; +;unsigned char __fastcall__ joy_count (void); + +COUNT: + lda #<JOY_COUNT + ldx #>JOY_COUNT + rts + +; ------------------------------------------------------------------------ +; READ: Read a particular joystick passed in A. +; +;unsigned char __fastcall__ joy_read (unsigned char joystick); + +READJOY: + lda sv_control + ldx #0 + rts From 949c2aa76f9bd0178567786530afbcbde6f45320 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 21 Nov 2017 06:57:02 +0100 Subject: [PATCH 0486/2161] Add files via upload --- libsrc/supervision/joy_stat_stddrv.s | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 libsrc/supervision/joy_stat_stddrv.s diff --git a/libsrc/supervision/joy_stat_stddrv.s b/libsrc/supervision/joy_stat_stddrv.s new file mode 100644 index 000000000..345b5f164 --- /dev/null +++ b/libsrc/supervision/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 _supervision_stdjoy_joy + +.rodata + +_joy_static_stddrv := _supervision_stdjoy_joy From e9c16e62e76ab0e9fde2e836451be72418234350 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 21 Nov 2017 09:51:35 +0100 Subject: [PATCH 0487/2161] Fix docs for #453 --- doc/funcref.sgml | 37 +++++++++++++++++++++++++++---------- doc/gamate.sgml | 7 +++++++ doc/supervision.sgml | 19 ++++++------------- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 1d5ee7c19..e634a4f6f 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -4,7 +4,7 @@ <title>cc65 function reference <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2017-09-02 +<date>2017-11-21 <abstract> cc65 is a C compiler for 6502 based systems. This function reference describes @@ -352,10 +352,10 @@ function. <sect1><tt/gamate.h/<label id="gamate.h"><p> -<!-- <itemize> --> +<itemize> <!-- <item><ref id="get_tv" name="get_tv"> --> -<!-- <item><ref id="waitvblank" name="waitvblank"> --> -<!-- </itemize> --> +<item><ref id="waitvsync" name="waitvsync"> +</itemize> (incomplete) @@ -437,10 +437,10 @@ function. <sect1><tt/nes.h/<label id="nes.h"><p> -<!-- <itemize> --> +<itemize> <!-- <item><ref id="get_tv" name="get_tv"> --> -<!-- <item><ref id="waitvsync" name="waitvsync"> --> -<!-- </itemize> --> +<item><ref id="waitvsync" name="waitvsync"> +</itemize> (incomplete) @@ -455,10 +455,10 @@ It does not declare any functions. <sect1><tt/pce.h/<label id="pce.h"><p> -<!-- <itemize> --> +<itemize> <!-- <item><ref id="get_tv" name="get_tv"> --> -<!-- <item><ref id="waitvblank" name="waitvblank"> --> -<!-- </itemize> --> +<item><ref id="waitvsync" name="waitvsync"> +</itemize> (incomplete) @@ -7612,6 +7612,23 @@ used in presence of a prototype. </quote> +<sect1>waitvsync<label id="waitvsync"><p> + +<quote> +<descrip> +<tag/Function/Wait until the start of the next frame. +<tag/Header/ +<tt/<ref id="gamate.h" name="gamate.h">/, +<tt/<ref id="nes.h" name="nes.h">/, +<tt/<ref id="pce.h" name="pce.h">/ +<tag/Declaration/<tt/void waitvsync (void);/ +<tag/Description/Wait for vertical sync to reduce flickering. +<tag/Availability/Platforms above +<tag/Example/None. +</descrip> +</quote> + + <sect1>wherex<label id="wherex"><p> <quote> diff --git a/doc/gamate.sgml b/doc/gamate.sgml index 14b1a27e9..0948c20c4 100644 --- a/doc/gamate.sgml +++ b/doc/gamate.sgml @@ -44,6 +44,13 @@ by an external program. Such an utility is provided in util/gamate/gamate-fixcar Programs containing Gamate specific code may use the <tt/gamate.h/ header file. +<sect1>Gamate specific functions<p> + +<itemize> +<item>waitvsync</item> +</itemize> + + <sect1>Hardware access<p> The following pseudo variables declared in the <tt/gamate.inc/ include file do diff --git a/doc/supervision.sgml b/doc/supervision.sgml index cf2af7967..c2ed425dd 100644 --- a/doc/supervision.sgml +++ b/doc/supervision.sgml @@ -63,14 +63,6 @@ Special locations: Programs containing Supervision specific code may use the <tt/supervision.h/ header file. -<sect1>Supervision specific functions<p> - -<itemize> -<item>waitvsync</item> -</itemize> - - - <sect1>Hardware access<p> The following pseudo variables declared in the <tt/supervision.inc/ include file do @@ -102,11 +94,12 @@ No extended memory drivers are currently available for the Supervision. <sect1>Joystick drivers<p> -No joystick drivers are currently available for the Supervision. -<!--A joystick driver for the standard buttons is available, but must be -statically linked, because no file I/O is available. See the documentation for -the <url url="co65.html" name="co65 utility"> for information on how to do -that.--> +<descrip> + + <tag><tt/supervision-stdjoy.joy (supervision_stdjoy_joy)/</tag> + A joystick driver for the standard two buttons joypad is available. + +</descrip><p> <sect1>Mouse drivers<p> From 40f960f7336b306c4d4d44fc88bed428a5a3ff19 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 21 Nov 2017 09:59:31 +0100 Subject: [PATCH 0488/2161] Date --- doc/supervision.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/supervision.sgml b/doc/supervision.sgml index c2ed425dd..153746025 100644 --- a/doc/supervision.sgml +++ b/doc/supervision.sgml @@ -4,7 +4,7 @@ <title>Watara Supervision specific information for cc65 <author><url url="mailto:polluks@sdf.lonestar.org" name="Stefan A. Haubenthal"> -<date>2014-04-12 +<date>2017-11-21 <abstract> An overview over the Supervision runtime system as it is implemented for the From f9b4e0b574e290a13ffa9e4ea580a2dcff48acab Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 21 Nov 2017 10:12:35 +0100 Subject: [PATCH 0489/2161] Update supervision.h --- include/supervision.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/supervision.h b/include/supervision.h index ffece4ecb..464c59e05 100644 --- a/include/supervision.h +++ b/include/supervision.h @@ -105,9 +105,10 @@ extern unsigned char sv_nmi_counter; extern unsigned char sv_timer_irq_counter; extern unsigned char sv_timer_dma_counter; +/* The addresses of the static drivers */ +extern void supervision_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ + /* End of supervision.h */ #endif - - From e49744ecd065a958efd9d8ed90993f60b6fdf656 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 21 Nov 2017 10:22:53 +0100 Subject: [PATCH 0490/2161] New API --- include/supervision.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/include/supervision.h b/include/supervision.h index 464c59e05..492346492 100644 --- a/include/supervision.h +++ b/include/supervision.h @@ -105,6 +105,26 @@ extern unsigned char sv_nmi_counter; extern unsigned char sv_timer_irq_counter; extern unsigned char sv_timer_dma_counter; +/* Masks for joy_read */ +#define JOY_UP_MASK 0x08 +#define JOY_DOWN_MASK 0x04 +#define JOY_LEFT_MASK 0x02 +#define JOY_RIGHT_MASK 0x01 +#define JOY_BTN_1_MASK 0x20 +#define JOY_BTN_2_MASK 0x10 +#define JOY_BTN_3_MASK 0x80 +#define JOY_BTN_4_MASK 0x40 + +#define JOY_BTN_A_MASK JOY_BTN_1_MASK +#define JOY_BTN_B_MASk JOY_BTN_2_MASK +#define JOY_START_MASK JOY_BTN_3_MASK +#define JOY_SELECT_MASK JOY_BTN_4_MASK + +#define JOY_BTN_A(v) ((v) & JOY_BTN_A_MASK) +#define JOY_BTN_B(v) ((v) & JOY_BTN_B_MASK) +#define JOY_START(v) ((v) & JOY_START_MASK) +#define JOY_SELECT(v) ((v) & JOY_SELECT_MASK) + /* The addresses of the static drivers */ extern void supervision_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ From f8f464846aff3fd1c1fbedb2cb4a05073fe14541 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 21 Nov 2017 10:27:08 +0100 Subject: [PATCH 0491/2161] directive removed --- libsrc/supervision/joy_stat_stddrv.s | 2 -- 1 file changed, 2 deletions(-) diff --git a/libsrc/supervision/joy_stat_stddrv.s b/libsrc/supervision/joy_stat_stddrv.s index 345b5f164..4daa13e34 100644 --- a/libsrc/supervision/joy_stat_stddrv.s +++ b/libsrc/supervision/joy_stat_stddrv.s @@ -9,6 +9,4 @@ .export _joy_static_stddrv .import _supervision_stdjoy_joy -.rodata - _joy_static_stddrv := _supervision_stdjoy_joy From c4baf9588e1ef203bc49fe34a8cfc83a8c5942b5 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 21 Nov 2017 10:29:35 +0100 Subject: [PATCH 0492/2161] directive removed --- libsrc/gamate/joy_stat_stddrv.s | 2 -- 1 file changed, 2 deletions(-) diff --git a/libsrc/gamate/joy_stat_stddrv.s b/libsrc/gamate/joy_stat_stddrv.s index 75016450a..94537b210 100644 --- a/libsrc/gamate/joy_stat_stddrv.s +++ b/libsrc/gamate/joy_stat_stddrv.s @@ -9,6 +9,4 @@ .export _joy_static_stddrv .import _gamate_stdjoy_joy -.rodata - _joy_static_stddrv := _gamate_stdjoy_joy From 7d1c92dc129da98ec113817095f169d7266049ee Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 21 Nov 2017 10:33:48 +0100 Subject: [PATCH 0493/2161] New API --- libsrc/supervision/joy/supervision-stdjoy.s | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/libsrc/supervision/joy/supervision-stdjoy.s b/libsrc/supervision/joy/supervision-stdjoy.s index 2d89aa6cb..f6a325740 100644 --- a/libsrc/supervision/joy/supervision-stdjoy.s +++ b/libsrc/supervision/joy/supervision-stdjoy.s @@ -23,17 +23,6 @@ .addr $0000 -; Button state masks (8 values) - - .byte $08 ; JOY_UP - .byte $04 ; JOY_DOWN - .byte $02 ; JOY_LEFT - .byte $01 ; JOY_RIGHT - .byte $20 ; JOY_FIRE_A - .byte $10 ; JOY_FIRE_B - .byte $40 ; JOY_SELECT - .byte $80 ; JOY_START - ; Jump table. .addr INSTALL From f2e12b4715519787214639f718a442708f142e25 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 21 Nov 2017 10:56:35 +0100 Subject: [PATCH 0494/2161] defined DYN_DRV --- include/supervision.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/supervision.h b/include/supervision.h index 492346492..f3ae1c25e 100644 --- a/include/supervision.h +++ b/include/supervision.h @@ -125,6 +125,9 @@ extern unsigned char sv_timer_dma_counter; #define JOY_START(v) ((v) & JOY_START_MASK) #define JOY_SELECT(v) ((v) & JOY_SELECT_MASK) +/* No support for dynamically loadable drivers */ +#define DYN_DRV 0 + /* The addresses of the static drivers */ extern void supervision_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ From 6034b68f0681c2edcf999a7f71cbb006f3b6e3e8 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 21 Nov 2017 22:42:43 +0100 Subject: [PATCH 0495/2161] Bumped API version. Removal of the joy_masks array with https://github.com/cc65/cc65/commit/7f52a770d9c6a43dde67689032bb3a4848eb6b30 was exactly the very type of change asking for a new API version. --- asminc/joy-kernel.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asminc/joy-kernel.inc b/asminc/joy-kernel.inc index ba969da1d..c8cc29820 100644 --- a/asminc/joy-kernel.inc +++ b/asminc/joy-kernel.inc @@ -55,7 +55,7 @@ ;------------------------------------------------------------------------------ ; The JOY API version, stored in JOY_HDR::VERSION -JOY_API_VERSION = $03 +JOY_API_VERSION = $04 ;------------------------------------------------------------------------------ ; Variables From ab54f920245c1ba0447cff1e3c6b93253438f043 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 21 Nov 2017 23:03:50 +0100 Subject: [PATCH 0496/2161] Make use of C library waitvsync(). --- samples/fire.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/samples/fire.c b/samples/fire.c index 44eb07c88..40eff0707 100644 --- a/samples/fire.c +++ b/samples/fire.c @@ -17,6 +17,7 @@ #include <string.h> /* for memset */ #include <time.h> #include <conio.h> +#include <cbm.h> @@ -60,9 +61,9 @@ #ifdef DOVSYNC -# define waitvsync() while ((signed char)VIC.ctrl1 >= 0) +# define WAITVSYNC() waitvsync() #else -# define waitvsync() +# define WAITVSYNC() #endif @@ -203,12 +204,12 @@ int main (void) while (!kbhit()) { /* Build page 1, then make it visible */ fire (SCREEN1); - waitvsync (); + WAITVSYNC (); outb (&VIC.addr, PAGE1); /* Build page 2, then make it visible */ fire (SCREEN2); - waitvsync (); + WAITVSYNC (); outb (&VIC.addr, PAGE2); /* Count frames */ From 44b13c1ca08c31289c2509d6626aa8bc56b601b6 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 22 Nov 2017 01:02:02 +0100 Subject: [PATCH 0497/2161] Subversion fallback If you use don't use Git to access the repository, you will still get a revision number. --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 8b41ceb9c..b70a3ffab 100644 --- a/src/Makefile +++ b/src/Makefile @@ -55,7 +55,7 @@ endif ifdef GIT_SHA $(info GIT_SHA: $(GIT_SHA)) else - GIT_SHA := $(shell git rev-parse --short HEAD 2>$(NULLDEV)) + GIT_SHA := $(shell git rev-parse --short HEAD 2>$(NULLDEV) || svnversion -n) ifneq ($(words $(GIT_SHA)),1) GIT_SHA := N/A $(info GIT_SHA: N/A) From 61b2264327c1756d2f883c9beb59aed3ae7c9c01 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 22 Nov 2017 01:35:42 +0100 Subject: [PATCH 0498/2161] Fix docs for #526 funcref.sgml is still growing and growing, how about outsourcing all TGI functions into tgi.sgml? --- doc/funcref.sgml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index e634a4f6f..e1ae5f8d8 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -184,6 +184,7 @@ function. <!-- <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="waitvsync" name="waitvsync"> <item><ref id="kbrepeat" name="kbrepeat"> </itemize> @@ -362,7 +363,7 @@ function. <sect1><tt/geos.h/<label id="geos.h"><p> -(incomplete) +<url url="geos.html" name="GEOS API">. <sect1><tt/joystick.h/<label id="joystick.h"><p> @@ -7618,6 +7619,7 @@ used in presence of a prototype. <descrip> <tag/Function/Wait until the start of the next frame. <tag/Header/ +<tt/<ref id="cbm.h" name="cbm.h">/, <tt/<ref id="gamate.h" name="gamate.h">/, <tt/<ref id="nes.h" name="nes.h">/, <tt/<ref id="pce.h" name="pce.h">/ From 7e4db1fdd6c417d7f9919cf0f1f6ec4c699709df Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 22 Nov 2017 18:17:43 +0100 Subject: [PATCH 0499/2161] Option removed --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index b70a3ffab..5d45180a0 100644 --- a/src/Makefile +++ b/src/Makefile @@ -55,7 +55,7 @@ endif ifdef GIT_SHA $(info GIT_SHA: $(GIT_SHA)) else - GIT_SHA := $(shell git rev-parse --short HEAD 2>$(NULLDEV) || svnversion -n) + GIT_SHA := $(shell git rev-parse --short HEAD 2>$(NULLDEV) || svnversion) ifneq ($(words $(GIT_SHA)),1) GIT_SHA := N/A $(info GIT_SHA: N/A) From 19122872311ef46a13d5bbbe33417ae133c96e4a Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 25 Nov 2017 13:25:01 -0500 Subject: [PATCH 0500/2161] Added missing names for the CIA registers in the C64/C128. --- asminc/c128.inc | 30 ++++++++++++++++++------------ asminc/c64.inc | 30 ++++++++++++++++++------------ 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/asminc/c128.inc b/asminc/c128.inc index 9e9acc5a8..745a3ad6d 100644 --- a/asminc/c128.inc +++ b/asminc/c128.inc @@ -171,30 +171,36 @@ VDC_INDEX := $D600 VDC_DATA := $D601 ; --------------------------------------------------------------------------- -; I/O: CIAs +; I/O: Complex Interface Adapters CIA1 := $DC00 -CIA1_PRA := $DC00 -CIA1_PRB := $DC01 -CIA1_DDRA := $DC02 -CIA1_DDRB := $DC03 -CIA1_TOD10 := $DC08 -CIA1_TODSEC := $DC09 -CIA1_TODMIN := $DC0A -CIA1_TODHR := $DC0B -CIA1_ICR := $DC0D -CIA1_CRA := $DC0E -CIA1_CRB := $DC0F +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 diff --git a/asminc/c64.inc b/asminc/c64.inc index 00b66a64f..c12f8e64b 100644 --- a/asminc/c64.inc +++ b/asminc/c64.inc @@ -165,30 +165,36 @@ VDC_INDEX := $D600 VDC_DATA := $D601 ; --------------------------------------------------------------------------- -; I/O: CIAs +; I/O: Complex Interface Adapters CIA1 := $DC00 -CIA1_PRA := $DC00 -CIA1_PRB := $DC01 -CIA1_DDRA := $DC02 -CIA1_DDRB := $DC03 -CIA1_TOD10 := $DC08 -CIA1_TODSEC := $DC09 -CIA1_TODMIN := $DC0A -CIA1_TODHR := $DC0B -CIA1_ICR := $DC0D -CIA1_CRA := $DC0E -CIA1_CRB := $DC0F +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 From 41df21855af7de8d6dde7be632dfc8e7af2cda6b Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 25 Nov 2017 19:31:36 +0100 Subject: [PATCH 0501/2161] Splitting of funcref --- doc/funcref.sgml | 1021 +-------------------------------------------- doc/index.sgml | 3 + doc/tgi.sgml | 1037 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1042 insertions(+), 1019 deletions(-) create mode 100644 doc/tgi.sgml diff --git a/doc/funcref.sgml b/doc/funcref.sgml index e634a4f6f..f74630ae3 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -676,52 +676,8 @@ communication. <sect1><tt/tgi.h/<label id="tgi.h"><p> -<itemize> -<item><ref id="tgi_arc" name="tgi_arc"> -<item><ref id="tgi_bar" name="tgi_bar"> -<item><ref id="tgi_circle" name="tgi_circle"> -<item><ref id="tgi_clear" name="tgi_clear"> -<item><ref id="tgi_done" name="tgi_done"> -<item><ref id="tgi_ellipse" name="tgi_ellipse"> -<item><ref id="tgi_free_vectorfont" name="tgi_free_vectorfont"> -<item><ref id="tgi_getaspectratio" name="tgi_getaspectratio"> -<item><ref id="tgi_getcolor" name="tgi_getcolor"> -<item><ref id="tgi_getcolorcount" name="tgi_getcolorcount"> -<item><ref id="tgi_getdefpalette" name="tgi_getdefpalette"> -<item><ref id="tgi_geterror" name="tgi_geterror"> -<item><ref id="tgi_geterrormsg" name="tgi_geterrormsg"> -<item><ref id="tgi_getmaxcolor" name="tgi_getmaxcolor"> -<item><ref id="tgi_getmaxx" name="tgi_getmaxx"> -<item><ref id="tgi_getmaxy" name="tgi_getmaxy"> -<item><ref id="tgi_getpagecount" name="tgi_getpagecount"> -<item><ref id="tgi_getpalette" name="tgi_getpalette"> -<item><ref id="tgi_getpixel" name="tgi_getpixel"> -<item><ref id="tgi_gettextheight" name="tgi_gettextheight"> -<item><ref id="tgi_gettextwidth" name="tgi_gettextwidth"> -<item><ref id="tgi_getxres" name="tgi_getxres"> -<item><ref id="tgi_getyres" name="tgi_getyres"> -<item><ref id="tgi_gotoxy" name="tgi_gotoxy"> -<item><ref id="tgi_init" name="tgi_init"> -<item><ref id="tgi_install" name="tgi_install"> -<item><ref id="tgi_install_vectorfont" name="tgi_install_vectorfont"> -<item><ref id="tgi_ioctl" name="tgi_ioctl"> -<item><ref id="tgi_line" name="tgi_line"> -<item><ref id="tgi_lineto" name="tgi_lineto"> -<item><ref id="tgi_load_driver" name="tgi_load_driver"> -<item><ref id="tgi_load_vectorfont" name="tgi_load_vectorfont"> -<item><ref id="tgi_outtext" name="tgi_outtext"> -<item><ref id="tgi_outtextxy" name="tgi_outtextxy"> -<item><ref id="tgi_setaspectratio" name="tgi_setaspectratio"> -<item><ref id="tgi_setcolor" name="tgi_setcolor"> -<item><ref id="tgi_setdrawpage" name="tgi_setdrawpage"> -<item><ref id="tgi_setpalette" name="tgi_setpalette"> -<item><ref id="tgi_setpixel" name="tgi_setpixel"> -<item><ref id="tgi_setviewpage" name="tgi_setviewpage"> -<item><ref id="tgi_settextscale" name="tgi_settextscale"> -<item><ref id="tgi_settextstyle" name="tgi_settextstyle"> -<item><ref id="tgi_uninstall" name="tgi_uninstall"> -<item><ref id="tgi_unload" name="tgi_unload"> -</itemize> +<url url="tgi.html" name="Tiny Graphics Interface">. + <sect1><tt/time.h/<label id="time.h"><p> @@ -6389,979 +6345,6 @@ be used in presence of a prototype. </quote> -<sect1>tgi_arc<label id="tgi_arc"><p> - -<quote> -<descrip> -<tag/Function/Draw an elliptic arc in the current color. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_arc (int x, int y, -unsigned char rx, unsigned char ry, unsigned sa, unsigned ea);/ -<tag/Description/The function draws an elliptic arc with center at x/y and -radii rx/ry using the current drawing color. The arc covers the angle -between sa and ea (startangle and endangle), which must be in the range -0..360. -<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 function behaves unexpectedly or may crash if the angles are out -of range. -</itemize> -<tag/Availability/cc65 -<tag/See also/ -<ref id="tgi_bar" name="tgi_bar">, -<ref id="tgi_circle" name="tgi_circle">, -<ref id="tgi_ellipse" name="tgi_ellipse">, -<ref id="tgi_pieslice" name="tgi_pieslice">, -<ref id="tgi_setcolor" name="tgi_setcolor"> -<tag/Example/<verb> -/* Draw the upper half of an ellipse */ -tgi_setcolor(TGI_COLOR_BLUE); -tgi_arc (50, 50, 40, 20, 0, 180); -</verb> -</descrip> -</quote> - - -<sect1>tgi_bar<label id="tgi_bar"><p> - -<quote> -<descrip> -<tag/Function/The function fills a rectangle on the drawpage with the current -color. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_bar (int x1, int y1, int x2, int y2);/ -<tag/Description/The function fills a rectangle on the drawpage with the current -color. -<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 function -<tag/Example/<verb> -tgi_setcolor(TGI_COLOR_GREEN); -tgi_bar(10, 10, 100, 60); -</verb> -</descrip> -</quote> - - -<sect1>tgi_circle<label id="tgi_circle"><p> - -<quote> -<descrip> -<tag/Function/The function draws a circle in the current color. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_circle (int x, int y, unsigned char radius);/ -<tag/Description/The function draws a circle in the current color. -<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/ -<ref id="tgi_arc" name="tgi_arc">, -<ref id="tgi_bar" name="tgi_bar">, -<ref id="tgi_ellipse" name="tgi_ellipse">, -<ref id="tgi_pieslice" name="tgi_pieslice">, -<ref id="tgi_setcolor" name="tgi_setcolor"> -<tag/Example/<verb> -tgi_setcolor(TGI_COLOR_BLACK); -tgi_circle(50, 40, 40); -</verb> -</descrip> -</quote> - - -<sect1>tgi_clear<label id="tgi_clear"><p> - -<quote> -<descrip> -<tag/Function/Clear the drawpage -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void tgi_clear (void);/ -<tag/Description/Clear the drawpage -<tag/Availability/cc65 -<tag/See also/Other tgi functions -<tag/Example/None. -</descrip> -</quote> - - -<sect1>tgi_done<label id="tgi_done"><p> - -<quote> -<descrip> -<tag/Function/End graphics mode, switch back to text mode. -Will NOT uninstall or unload the driver! -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void tgi_done (void);/ -<tag/Description/End graphics mode, switch back to text mode. -Will NOT uninstall or unload the driver! -<tag/Availability/cc65 -<tag/See also/Other tgi functions -<tag/Example/None. -</descrip> -</quote> - - -<sect1>tgi_ellipse<label id="tgi_ellipse"><p> - -<quote> -<descrip> -<tag/Function/The function draws an ellipse in the current color. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_ellipse (int x, int y, unsigned char rx, unsigned char ry);/ -<tag/Description/The function draws an ellipse at position x/y with radii -rx and ry, using the current drawing color. -<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/ -<ref id="tgi_arc" name="tgi_arc">, -<ref id="tgi_bar" name="tgi_bar">, -<ref id="tgi_circle" name="tgi_circle">, -<ref id="tgi_pieslice" name="tgi_pieslice">, -<ref id="tgi_setcolor" name="tgi_setcolor"> -<tag/Example/<verb> -tgi_setcolor(TGI_COLOR_RED); -tgi_ellipse (50, 40, 40, 20); -</verb> -</descrip> -</quote> - - -<sect1>tgi_free_vectorfont<label id="tgi_free_vectorfont"><p> - -<quote> -<descrip> -<tag/Function/Free a vector font that was previously loaded into memory. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_free_vectorfont (const tgi_vectorfont* font);/ -<tag/Description/Free a vector font that was previously loaded into memory. -<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/ -<ref id="tgi_load_vectorfont" name="tgi_load_vectorfont">, -<ref id="tgi_install_vectorfont" name="tgi_install_vectorfont"> -<tag/Example/None. -</descrip> -</quote> - - -<sect1>tgi_getaspectratio<label id="tgi_getaspectratio"><p> - -<quote> <descrip> <tag/Function/Return the pixel aspect ratio. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/unsigned tgi_getaspectratio (void);/ -<tag/Description/The function returns the pixel aspect ratio for the current -driver and display as an 8.8 fixed point value. It may be used to correct -geometric shapes so they look correct on the display. As an example, a circle -with a radius of 100 pixels may look elliptic on some driver/display -combinations if the aspect ratio is not 1.00. -<tag/Notes/<itemize> -<item>The aspect ratio is encoded in the TGI driver which assumes a "standard" -monitor for the given platform. The aspect ratio may be wrong if another -monitor is used. -<item>No TGI function will use the aspect ratio. It is up to the programmer to -make use of it. -<item>The <ref id="tgi_setaspectratio" name="tgi_setaspectratio"> function can -be used to change the aspect ratio for a loaded driver. The value is not reset -by <ref id="tgi_init" name="tgi_init">, so if a driver is linked statically to -an application, switching into and out of graphics mode will not restore the -original aspect ratio. -</itemize> -<tag/Availability/cc65 -<tag/See also/ -<ref id="tgi_setaspectratio" name="tgi_setaspectratio"> -<tag/Example/None. -</descrip> -</quote> - - -<sect1>tgi_getcolor<label id="tgi_getcolor"><p> - -<quote> -<descrip> -<tag/Function/Return the current drawing color. -<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. -<tag/Availability/cc65 -<tag/See also/Other tgi functions -<tag/Example/<verb> -color = tgi_getcolor(); -</verb> -</descrip> -</quote> - - -<sect1>tgi_getcolorcount<label id="tgi_getcolorcount"><p> - -<quote> -<descrip> -<tag/Function/Get the number of available colors. -<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 -returns the number of entries we can use in the palette. -<tag/Availability/cc65 -<tag/See also/Other tgi functions -<tag/Example/<verb> -if (tgi_getcolorcount() == 2) { - printf("Only monochrome graphics is supported\n"); -} -</verb> -</descrip> -</quote> - - -<sect1>tgi_getdefpalette<label id="tgi_getdefpalette"><p> - -<quote> -<descrip> -<tag/Function/Get the palette installed by default. -<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. -</descrip> -</quote> - - -<sect1>tgi_geterror<label id="tgi_geterror"><p> - -<quote> -<descrip> -<tag/Function/Return the error code for the last operation. -This will also clear the error. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/unsigned char tgi_geterror (void);/ -<tag/Description/Return the error code for the last operation. -This will also clear the error. -<tag/Availability/cc65 -<tag/See also/Other tgi functions -<tag/Example/None. -</descrip> -</quote> - - -<sect1>tgi_geterrormsg<label id="tgi_geterrormsg"><p> - -<quote> -<descrip> -<tag/Function/Get an error message describing the error. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/const char* __fastcall__ tgi_geterrormsg (unsigned char code);/ -<tag/Description/Get an error message describing the error. -<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/Example/None. -</descrip> -</quote> - - -<sect1>tgi_getmaxcolor<label id="tgi_getmaxcolor"><p> - -<quote> -<descrip> -<tag/Function/Get the highest index of the palette. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/unsigned char tgi_getmaxcolor (void);/ -<tag/Description/Get the highest index of the palette. -<tag/Availability/cc65 -<tag/See also/Other tgi functions -<tag/Example/None. -</descrip> -</quote> - - -<sect1>tgi_getmaxx<label id="tgi_getmaxx"><p> - -<quote> -<descrip> -<tag/Function/Get the maximum x coordinate that can be used on this screen. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/unsigned tgi_getmaxx (void);/ -<tag/Description/Get the maximum x coordinate that can be used on this screen. -<tag/Availability/cc65 -<tag/See also/Other tgi functions -<tag/Example/None. -</descrip> -</quote> - - -<sect1>tgi_getmaxy<label id="tgi_getmaxy"><p> - -<quote> -<descrip> -<tag/Function/Get the maximum y coordinate that can be used on this screen. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/unsigned tgi_getmaxy (void);/ -<tag/Description/Get the maximum y coordinate that can be used on this screen. -<tag/Availability/cc65 -<tag/See also/Other tgi functions -<tag/Example/None. -</descrip> -</quote> - - -<sect1>tgi_getpagecount<label id="tgi_getpagecount"><p> - -<quote> -<descrip> -<tag/Function/Return the number of screen pages available. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/unsigned tgi_getpagecount (void);/ -<tag/Description/Return the number of screen pages available. -<tag/Availability/cc65 -<tag/See also/ -<ref id="tgi_setdrawpage" name="tgi_setdrawpage">, -<ref id="tgi_setviewpage" name="tgi_setviewpage"> -<tag/Example/None. -</descrip> -</quote> - - -<sect1>tgi_getpalette<label id="tgi_getpalette"><p> - -<quote> -<descrip> -<tag/Function/Get the palette installed. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/const unsigned char* tgi_getpalette (void);/ -<tag/Description/Get the palette installed. -<tag/Availability/cc65 -<tag/See also/Other tgi functions -<tag/Example/None. -</descrip> -</quote> - - -<sect1>tgi_getpixel<label id="tgi_getpixel"><p> - -<quote> -<descrip> -<tag/Function/Get the color 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/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/Example/None. -</descrip> -</quote> - - -<sect1>tgi_getxres<label id="tgi_getxres"><p> - -<quote> -<descrip> -<tag/Function/Get number of horisontal 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. -This is same as tgi_maxx()+1. -<tag/Availability/cc65 -<tag/See also/Other tgi functions. -<tag/Example/None. -</descrip> -</quote> - - -<sect1>tgi_getyres<label id="tgi_getyres"><p> - -<quote> -<descrip> -<tag/Function/Get number of vertical pixels on the screen. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/unsigned tgi_getyres (void);/ -<tag/Description/Get number of vertical pixels on the screen. -This is same as tgi_maxy()+1. -<tag/Availability/cc65 -<tag/See also/Other tgi functions. -<tag/Example/None. -</descrip> -</quote> - - -<sect1>tgi_gotoxy<label id="tgi_gotoxy"><p> - -<quote> -<descrip> -<tag/Function/Set graphics cursor at x, y. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_gotoxy (int x, int y);/ -<tag/Description/Set graphics cursor at x, y. -<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/Example/None. -</descrip> -</quote> - - -<sect1>tgi_init<label id="tgi_init"><p> - -<quote> -<descrip> -<tag/Function/Initialize the already loaded graphics driver. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void tgi_init (void);/ -<tag/Description/The tgi_init function will set the default palette to the -hardware. -<tag/Notes/<itemize> -<item><tt/tgi_init/ will not clear the screen. This allows switching between -text and graphics mode on platforms that have separate memory areas for the -screens. If you want the screen cleared, call <tt/<ref id="tgi_clear" -name="tgi_clear">/ after <tt/tgi_init/. -</itemize> -<tag/Availability/cc65 -<tag/See also/Other tgi functions. -<tag/Example/<verb> -tgi_install(tgi_static_stddrv); //Include the driver statically instead of loading it. -tgi_init(); //Set up the default palette and clear the screen. -</verb> -</descrip> -</quote> - - -<sect1>tgi_install<label id="tgi_install"><p> - -<quote> -<descrip> -<tag/Function/Install an already loaded driver and return an error code. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/unsigned char __fastcall__ tgi_install (void* driver);/ -<tag/Description/The function installs a driver that was already loaded into -memory (or linked statically to the program). It returns an error code -(<tt/TGI_ERR_OK/ in case of success). -<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/ -<ref id="tgi_load_driver" name="tgi_load_driver">, -<ref id="tgi_uninstall" name="tgi_uninstall">, -<ref id="tgi_unload" name="tgi_unload"> -<tag/Example/<verb> -tgi_install(tgi_static_stddrv); //Include the driver statically instead of loading it. -tgi_init(); //Set up the default palette and clear the screen. -</verb> -</descrip> -</quote> - - -<sect1>tgi_install_vectorfont<label id="tgi_install_vectorfont"><p> - -<quote> -<descrip> -<tag/Function/Install an already loaded driver and return an error code. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_install_vectorfont (const tgi_vectorfont* font);/ -<tag/Description/ -Install a vector font for use. More than one vector font can be loaded, -but only one can be active. This function is used to tell which one. Call -with a NULL pointer to uninstall the currently installed font. -<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/ -<ref id="tgi_load_vectorfont" name="tgi_load_vectorfont">, -<ref id="tgi_free_vectorfont" name="tgi_free_vectorfont"> -<tag/Example/None. -</descrip> -</quote> - - -<sect1>tgi_ioctl<label id="tgi_ioctl"><p> - -<quote> -<descrip> -<tag/Function/Platform dependent code extensions. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/unsigned __fastcall__ tgi_ioctl (unsigned char code, void* data);/ -<tag/Description/Some platforms have extra display hardware that is not -supported by standard tgi functions. You can extend the driver to support -this extra hardware using tgi_ioctl functions. -<tag/Notes/<itemize> -<item>The function is only available as fastcall function, so it may only -be used in presence of a prototype. -<item>These functions are not easily portable to other cc65 platforms. -</itemize> -<tag/Availability/cc65 -<tag/See also/Other tgi functions. -<tag/Example/<verb> -#define tgi_sprite(spr) tgi_ioctl(0, (void*)(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) -if (!tgi_busy()) { - tgi_sprite(&background); - tgi_setcolor(TGI_COLOR_BLUE); - tgi_outttextxy(20,40,"Hello World"); - tgi_updatedisplay(); -} -</verb> -</descrip> -</quote> - - -<sect1>tgi_line<label id="tgi_line"><p> - -<quote> -<descrip> -<tag/Function/Draw a line in the current drawing color. -The graphics cursor will be set to x2/y2 by this call. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_line (int x1, int y1, int x2, int y2);/ -<tag/Description/Draw a line in the current drawing color. -The graphics cursor will be set to x2/y2 by this call. -<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/Example/None. -</descrip> -</quote> - - -<sect1>tgi_lineto<label id="tgi_lineto"><p> - -<quote> -<descrip> -<tag/Function/Draw a line in the current drawing color from the graphics -cursor to the new end point. The graphics cursor will be updated to x2/y2. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_lineto (int x2, int y2);/ -<tag/Description/Draw a line in the current drawing color from the graphics -cursor to the new end point. The graphics cursor will be updated to x2/y2. -<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/Example/None. -</descrip> -</quote> - - -<sect1>tgi_load_driver<label id="tgi_load_driver"><p> - -<quote> -<descrip> -<tag/Function/Load and install the given driver. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_load_driver (const char *name);/ -<tag/Description/Load and install the driver by name. -Will just load the driver and check if loading was successful. -Will not switch to graphics mode. -<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/Example/None. -</descrip> -</quote> - - -<sect1>tgi_load_vectorfont<label id="tgi_load_vectorfont"><p> - -<quote> -<descrip> -<tag/Function/Load the given vector font. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/const tgi_vectorfont* __fastcall__ tgi_load_vectorfont (const char* name);/ -<tag/Description/ -Load a vector font into memory and return it. In case of errors, NULL is -returned and an error is set, which can be retrieved using tgi_geterror. -To use the font, it has to be installed using tgi_install_vectorfont. -<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/ -<ref id="tgi_install_vectorfont" name="tgi_install_vectorfont">, -<ref id="tgi_free_vectorfont" name="tgi_free_vectorfont"> -<tag/Example/None. -</descrip> -</quote> - - -<sect1>tgi_outtext<label id="tgi_outtext"><p> - -<quote> -<descrip> -<tag/Function/Output text at the current graphics cursor position. -The graphics cursor is moved to the end of the text. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_outtext (const char* s);/ -<tag/Description/Output text at the current graphics cursor position. -The graphics cursor is moved to the end of the text. -<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/Example/None. -</descrip> -</quote> - - -<sect1>tgi_outtextxy<label id="tgi_outtextxy"><p> - -<quote> -<descrip> -<tag/Function/Output text at the given cursor position. -The graphics cursor is moved to the end of the text. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_outtextxy (int x, int y, const char* s);/ -<tag/Description/Output text at the given cursor position. -The graphics cursor is moved to the end of the text. -<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/Example/None. -</descrip> -</quote> - - -<sect1>tgi_pieslice<label id="tgi_pieslice"><p> - -<quote> -<descrip> -<tag/Function/Draw an elliptic pie slice in the current color. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_pie slice (int x, int y, -unsigned char rx, unsigned char ry, unsigned sa, unsigned ea);/ -<tag/Description/The function draws an elliptic pie slice with center at x/y -and radii rx/ry using the current drawing color. The pie slice covers the angle -between sa and ea (startangle and endangle), which must be in the range -0..360. -<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 function behaves unexpectedly or may crash if the angles are out -of range. -</itemize> -<tag/Availability/cc65 -<tag/See also/ -<ref id="tgi_bar" name="tgi_arc">, -<ref id="tgi_bar" name="tgi_bar">, -<ref id="tgi_circle" name="tgi_circle">, -<ref id="tgi_ellipse" name="tgi_ellipse">, -<ref id="tgi_setcolor" name="tgi_setcolor"> -<tag/Example/<verb> -/* Draw the closed upper half of an ellipse */ -tgi_setcolor(TGI_COLOR_BLUE); -tgi_pieslice (50, 50, 40, 20, 0, 180); -</verb> -</descrip> -</quote> - - -<sect1>tgi_setaspectratio<label id="tgi_setaspectratio"><p> - -<quote> <descrip> <tag/Function/Set the pixel aspect ratio. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_setaspectratio (unsigned ratio);/ -<tag/Description/The function sets the pixel aspect ratio for the current -driver and display. The argument is an 8.8 fixed point value. The aspect ratio -may be used to correct geometric shapes so they look correct on a given -display. As an example, a circle with a radius of 100 pixels may look elliptic -on some driver/display combinations if the aspect ratio is not 1.00. -<tag/Notes/<itemize> -<item>The aspect ratio is encoded in the TGI driver which assumes a "standard" -monitor for the given platform. The aspect ratio may be wrong if another -monitor is used. -<item>No TGI function will use the aspect ratio. It is up to the programmer to -make use of it. -<item>The <tt/tgi_setaspectratio/ function can be used to change the aspect -ratio for a loaded driver. The value is not reset by <ref id="tgi_init" -name="tgi_init">, so if a driver is linked statically to an application, -switching into and out of graphics mode will not restore the original aspect -ratio. -<item>The function is available only as a fastcall function; so, it may be used -only in the presence of a prototype. -</itemize> -<tag/Availability/cc65 -<tag/See also/ -<ref id="tgi_getaspectratio" name="tgi_getaspectratio"> -<tag/Example/None. -</descrip> -</quote> - - -<sect1>tgi_setcolor<label id="tgi_setcolor"><p> - -<quote> -<descrip> -<tag/Function/Set color 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/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/Example/<verb> -tgi_setcolor(TGI_COLOR_BLACK); -tgi_bar(0,0,30,30); -tgi_setcolor(TGI_COLOR_WHITE); -tgi_bar(10,10,20,20); -</verb> -</descrip> -</quote> - -<sect1>tgi_setdrawpage<label id="tgi_setdrawpage"><p> - -<quote> -<descrip> -<tag/Function/Set the page for drawing. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_setdrawpage (unsigned char page);/ -<tag/Description/If the drawpage and the viewpage are the same then all drawing -is seen immediately as it is drawn. For double buffered games you can set the -drawpage to a different page than the viewpage. This lets you draw the next -screen in the background and when the screen is ready you display it. -<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/Example/<verb> -tgi_setdrawpage(1); -tgi_outtextxy(10, 10, "Hello World"); -tgi_setviewpage(1); // Show page 1 -tgi_setdrawpage(0); -tgi_outtextxy(10, 10, "Creating next frame"); -... -tgi_setviewpage(0); // Show page 0 -</verb> -</descrip> -</quote> - -<sect1>tgi_setpalette<label id="tgi_setpalette"><p> - -<quote> -<descrip> -<tag/Function/Set the palette (not available with all drivers/hardware). -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. -<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/Example/None. -</descrip> -</quote> - -<sect1>tgi_setpixel<label id="tgi_setpixel"><p> - -<quote> -<descrip> -<tag/Function/Plot a pixel on the drawpage with the current color. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_setpixel (int x, int y);/ -<tag/Description/Plot a pixel on the drawpage with the current color. -<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/Example/None. -</descrip> -</quote> - -<sect1>tgi_setviewpage<label id="tgi_setviewpage"><p> - -<quote> -<descrip> -<tag/Function/Set page to be visible on screen. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_setviewpage (unsigned char page);/ -<tag/Description/If the drawpage and the viewpage are the same then all drawing -is seen immediately as it is drawn. For double buffered games you can set the -drawpage to a different page than the viewpage. This lets you draw the next -screen in the background and when the screen is ready you display it. -<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/Example/<verb> -tgi_setdrawpage(1); -tgi_outtextxy(10, 10, "Hello World"); -tgi_setviewpage(1); // Show page 1 -tgi_setdrawpage(0); -tgi_outtextxy(10, 10, "Creating next frame"); -... -tgi_setviewpage(0); // Show page 0 -</verb> -</descrip> -</quote> - -<sect1>tgi_gettextheight<label id="tgi_gettextheight"><p> - -<quote> -<descrip> -<tag/Function/Calculate the height of the text in pixels according to -the current text style. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/unsigned __fastcall__ tgi_gettextheight (const char* s);/ -<tag/Description/Calculate the height of the text in pixels according to -the current text style. -<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/Example/None. -</descrip> -</quote> - -<sect1>tgi_settextscale<label id="tgi_settextscale"><p> - -<quote> -<descrip> -<tag/Function/Set the scaling for text output. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_settextscale (unsigned width, unsigned height);/ -<tag/Description/ -Set the scaling for text output. The scaling factors for width and height -are 8.8 fixed point values. This means that $100 = 1 $200 = 2 etc. -<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/ -<ref id="tgi_settextstyle" name="tgi_settextstyle"> -<tag/Example/None. -</descrip> -</quote> - -<sect1>tgi_settextstyle<label id="tgi_settextstyle"><p> - -<quote> -<descrip> -<tag/Function/Set the style for text output. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_settextstyle (unsigned char magx, unsigned char magy, unsigned char dir, unsigned char font);/ -<tag/Description/Set the style for text output. -<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/ -<ref id="tgi_settextscale" name="tgi_settextscale"> -<tag/Example/None. -</descrip> -</quote> - -<sect1>tgi_gettextwidth<label id="tgi_gettextwidth"><p> - -<quote> -<descrip> -<tag/Function/Calculate the width of the text in pixels according to the current text style. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/unsigned __fastcall__ tgi_gettextwidth (const char* s);/ -<tag/Description/Calculate the width of the text in pixels according to the current text style. -<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/Example/None. -</descrip> -</quote> - -<sect1>tgi_uninstall<label id="tgi_uninstall"><p> - -<quote> -<descrip> -<tag/Function/Uninstall the currently loaded driver but do not unload it. -Will call tgi_done if necessary. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void tgi_uninstall (void);/ -<tag/Description/Uninstall the currently loaded driver but do not unload it. -Will call tgi_done if necessary. -<tag/Availability/cc65 -<tag/See also/Other tgi functions. -<tag/Example/None. -</descrip> -</quote> - -<sect1>tgi_unload<label id="tgi_unload"><p> - -<quote> -<descrip> -<tag/Function/Uninstall, then unload the currently loaded driver. -Will call tgi_done if necessary. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void tgi_unload (void);/ -<tag/Description/Uninstall, then unload the currently loaded driver. -Will call tgi_done if necessary. -<tag/Availability/cc65 -<tag/See also/Other tgi functions. -<tag/Example/None. -</descrip> -</quote> - <sect1>time<label id="time"><p> <quote> diff --git a/doc/index.sgml b/doc/index.sgml index 99b4f10b5..a7aa06037 100644 --- a/doc/index.sgml +++ b/doc/index.sgml @@ -85,6 +85,9 @@ <tag><htmlurl url="dio.html" name="dio.html"></tag> Low-level disk I/O API. + <tag><htmlurl url="tgi.html" name="tgi.html"></tag> + Tiny Graphics Interface. + <tag><htmlurl url="geos.html" name="geos.html"></tag> The GEOSLib manual. diff --git a/doc/tgi.sgml b/doc/tgi.sgml new file mode 100644 index 000000000..3bab58f57 --- /dev/null +++ b/doc/tgi.sgml @@ -0,0 +1,1037 @@ +<!doctype linuxdoc system> + +<article> +<title>Tiny Graphics Interface +<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> +<date>2017-11-23 + +<abstract> +The cc65 library provides functions for platform independent graphics. +Include the tgi.h header file to get the necessary definitions. +</abstract> + +<!-- Table of contents --> +<itemize> +<item><ref id="tgi_arc" name="tgi_arc"> +<item><ref id="tgi_bar" name="tgi_bar"> +<item><ref id="tgi_circle" name="tgi_circle"> +<item><ref id="tgi_clear" name="tgi_clear"> +<item><ref id="tgi_done" name="tgi_done"> +<item><ref id="tgi_ellipse" name="tgi_ellipse"> +<item><ref id="tgi_free_vectorfont" name="tgi_free_vectorfont"> +<item><ref id="tgi_getaspectratio" name="tgi_getaspectratio"> +<item><ref id="tgi_getcolor" name="tgi_getcolor"> +<item><ref id="tgi_getcolorcount" name="tgi_getcolorcount"> +<item><ref id="tgi_getdefpalette" name="tgi_getdefpalette"> +<item><ref id="tgi_geterror" name="tgi_geterror"> +<item><ref id="tgi_geterrormsg" name="tgi_geterrormsg"> +<item><ref id="tgi_getmaxcolor" name="tgi_getmaxcolor"> +<item><ref id="tgi_getmaxx" name="tgi_getmaxx"> +<item><ref id="tgi_getmaxy" name="tgi_getmaxy"> +<item><ref id="tgi_getpagecount" name="tgi_getpagecount"> +<item><ref id="tgi_getpalette" name="tgi_getpalette"> +<item><ref id="tgi_getpixel" name="tgi_getpixel"> +<item><ref id="tgi_gettextheight" name="tgi_gettextheight"> +<item><ref id="tgi_gettextwidth" name="tgi_gettextwidth"> +<item><ref id="tgi_getxres" name="tgi_getxres"> +<item><ref id="tgi_getyres" name="tgi_getyres"> +<item><ref id="tgi_gotoxy" name="tgi_gotoxy"> +<item><ref id="tgi_init" name="tgi_init"> +<item><ref id="tgi_install" name="tgi_install"> +<item><ref id="tgi_install_vectorfont" name="tgi_install_vectorfont"> +<item><ref id="tgi_ioctl" name="tgi_ioctl"> +<item><ref id="tgi_line" name="tgi_line"> +<item><ref id="tgi_lineto" name="tgi_lineto"> +<item><ref id="tgi_load_driver" name="tgi_load_driver"> +<item><ref id="tgi_load_vectorfont" name="tgi_load_vectorfont"> +<item><ref id="tgi_outtext" name="tgi_outtext"> +<item><ref id="tgi_outtextxy" name="tgi_outtextxy"> +<item><ref id="tgi_setaspectratio" name="tgi_setaspectratio"> +<item><ref id="tgi_setcolor" name="tgi_setcolor"> +<item><ref id="tgi_setdrawpage" name="tgi_setdrawpage"> +<item><ref id="tgi_setpalette" name="tgi_setpalette"> +<item><ref id="tgi_setpixel" name="tgi_setpixel"> +<item><ref id="tgi_setviewpage" name="tgi_setviewpage"> +<item><ref id="tgi_settextscale" name="tgi_settextscale"> +<item><ref id="tgi_settextstyle" name="tgi_settextstyle"> +<item><ref id="tgi_uninstall" name="tgi_uninstall"> +<item><ref id="tgi_unload" name="tgi_unload"> +</itemize> + +<!-- Begin the document --> + +<sect1>tgi_arc<label id="tgi_arc"><p> + +<quote> +<descrip> +<tag/Function/Draw an elliptic arc in the current color. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_arc (int x, int y, +unsigned char rx, unsigned char ry, unsigned sa, unsigned ea);/ +<tag/Description/The function draws an elliptic arc with center at x/y and +radii rx/ry using the current drawing color. The arc covers the angle +between sa and ea (startangle and endangle), which must be in the range +0..360. +<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 function behaves unexpectedly or may crash if the angles are out +of range. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="tgi_bar" name="tgi_bar">, +<ref id="tgi_circle" name="tgi_circle">, +<ref id="tgi_ellipse" name="tgi_ellipse">, +<ref id="tgi_pieslice" name="tgi_pieslice">, +<ref id="tgi_setcolor" name="tgi_setcolor"> +<tag/Example/<verb> +/* Draw the upper half of an ellipse */ +tgi_setcolor(TGI_COLOR_BLUE); +tgi_arc (50, 50, 40, 20, 0, 180); +</verb> +</descrip> +</quote> + + +<sect1>tgi_bar<label id="tgi_bar"><p> + +<quote> +<descrip> +<tag/Function/The function fills a rectangle on the drawpage with the current +color. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_bar (int x1, int y1, int x2, int y2);/ +<tag/Description/The function fills a rectangle on the drawpage with the current +color. +<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 function +<tag/Example/<verb> +tgi_setcolor(TGI_COLOR_GREEN); +tgi_bar(10, 10, 100, 60); +</verb> +</descrip> +</quote> + + +<sect1>tgi_circle<label id="tgi_circle"><p> + +<quote> +<descrip> +<tag/Function/The function draws a circle in the current color. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_circle (int x, int y, unsigned char radius);/ +<tag/Description/The function draws a circle in the current color. +<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/ +<ref id="tgi_arc" name="tgi_arc">, +<ref id="tgi_bar" name="tgi_bar">, +<ref id="tgi_ellipse" name="tgi_ellipse">, +<ref id="tgi_pieslice" name="tgi_pieslice">, +<ref id="tgi_setcolor" name="tgi_setcolor"> +<tag/Example/<verb> +tgi_setcolor(TGI_COLOR_BLACK); +tgi_circle(50, 40, 40); +</verb> +</descrip> +</quote> + + +<sect1>tgi_clear<label id="tgi_clear"><p> + +<quote> +<descrip> +<tag/Function/Clear the drawpage +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void tgi_clear (void);/ +<tag/Description/Clear the drawpage +<tag/Availability/cc65 +<tag/See also/Other tgi functions +<tag/Example/None. +</descrip> +</quote> + + +<sect1>tgi_done<label id="tgi_done"><p> + +<quote> +<descrip> +<tag/Function/End graphics mode, switch back to text mode. +Will NOT uninstall or unload the driver! +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void tgi_done (void);/ +<tag/Description/End graphics mode, switch back to text mode. +Will NOT uninstall or unload the driver! +<tag/Availability/cc65 +<tag/See also/Other tgi functions +<tag/Example/None. +</descrip> +</quote> + + +<sect1>tgi_ellipse<label id="tgi_ellipse"><p> + +<quote> +<descrip> +<tag/Function/The function draws an ellipse in the current color. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_ellipse (int x, int y, unsigned char rx, unsigned char ry);/ +<tag/Description/The function draws an ellipse at position x/y with radii +rx and ry, using the current drawing color. +<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/ +<ref id="tgi_arc" name="tgi_arc">, +<ref id="tgi_bar" name="tgi_bar">, +<ref id="tgi_circle" name="tgi_circle">, +<ref id="tgi_pieslice" name="tgi_pieslice">, +<ref id="tgi_setcolor" name="tgi_setcolor"> +<tag/Example/<verb> +tgi_setcolor(TGI_COLOR_RED); +tgi_ellipse (50, 40, 40, 20); +</verb> +</descrip> +</quote> + + +<sect1>tgi_free_vectorfont<label id="tgi_free_vectorfont"><p> + +<quote> +<descrip> +<tag/Function/Free a vector font that was previously loaded into memory. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_free_vectorfont (const tgi_vectorfont* font);/ +<tag/Description/Free a vector font that was previously loaded into memory. +<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/ +<ref id="tgi_load_vectorfont" name="tgi_load_vectorfont">, +<ref id="tgi_install_vectorfont" name="tgi_install_vectorfont"> +<tag/Example/None. +</descrip> +</quote> + + +<sect1>tgi_getaspectratio<label id="tgi_getaspectratio"><p> + +<quote> <descrip> <tag/Function/Return the pixel aspect ratio. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/unsigned tgi_getaspectratio (void);/ +<tag/Description/The function returns the pixel aspect ratio for the current +driver and display as an 8.8 fixed point value. It may be used to correct +geometric shapes so they look correct on the display. As an example, a circle +with a radius of 100 pixels may look elliptic on some driver/display +combinations if the aspect ratio is not 1.00. +<tag/Notes/<itemize> +<item>The aspect ratio is encoded in the TGI driver which assumes a "standard" +monitor for the given platform. The aspect ratio may be wrong if another +monitor is used. +<item>No TGI function will use the aspect ratio. It is up to the programmer to +make use of it. +<item>The <ref id="tgi_setaspectratio" name="tgi_setaspectratio"> function can +be used to change the aspect ratio for a loaded driver. The value is not reset +by <ref id="tgi_init" name="tgi_init">, so if a driver is linked statically to +an application, switching into and out of graphics mode will not restore the +original aspect ratio. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="tgi_setaspectratio" name="tgi_setaspectratio"> +<tag/Example/None. +</descrip> +</quote> + + +<sect1>tgi_getcolor<label id="tgi_getcolor"><p> + +<quote> +<descrip> +<tag/Function/Return the current drawing color. +<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. +<tag/Availability/cc65 +<tag/See also/Other tgi functions +<tag/Example/<verb> +color = tgi_getcolor(); +</verb> +</descrip> +</quote> + + +<sect1>tgi_getcolorcount<label id="tgi_getcolorcount"><p> + +<quote> +<descrip> +<tag/Function/Get the number of available colors. +<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 +returns the number of entries we can use in the palette. +<tag/Availability/cc65 +<tag/See also/Other tgi functions +<tag/Example/<verb> +if (tgi_getcolorcount() == 2) { + printf("Only monochrome graphics is supported\n"); +} +</verb> +</descrip> +</quote> + + +<sect1>tgi_getdefpalette<label id="tgi_getdefpalette"><p> + +<quote> +<descrip> +<tag/Function/Get the palette installed by default. +<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. +</descrip> +</quote> + + +<sect1>tgi_geterror<label id="tgi_geterror"><p> + +<quote> +<descrip> +<tag/Function/Return the error code for the last operation. +This will also clear the error. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/unsigned char tgi_geterror (void);/ +<tag/Description/Return the error code for the last operation. +This will also clear the error. +<tag/Availability/cc65 +<tag/See also/Other tgi functions +<tag/Example/None. +</descrip> +</quote> + + +<sect1>tgi_geterrormsg<label id="tgi_geterrormsg"><p> + +<quote> +<descrip> +<tag/Function/Get an error message describing the error. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/const char* __fastcall__ tgi_geterrormsg (unsigned char code);/ +<tag/Description/Get an error message describing the error. +<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/Example/None. +</descrip> +</quote> + + +<sect1>tgi_getmaxcolor<label id="tgi_getmaxcolor"><p> + +<quote> +<descrip> +<tag/Function/Get the highest index of the palette. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/unsigned char tgi_getmaxcolor (void);/ +<tag/Description/Get the highest index of the palette. +<tag/Availability/cc65 +<tag/See also/Other tgi functions +<tag/Example/None. +</descrip> +</quote> + + +<sect1>tgi_getmaxx<label id="tgi_getmaxx"><p> + +<quote> +<descrip> +<tag/Function/Get the maximum x coordinate that can be used on this screen. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/unsigned tgi_getmaxx (void);/ +<tag/Description/Get the maximum x coordinate that can be used on this screen. +<tag/Availability/cc65 +<tag/See also/Other tgi functions +<tag/Example/None. +</descrip> +</quote> + + +<sect1>tgi_getmaxy<label id="tgi_getmaxy"><p> + +<quote> +<descrip> +<tag/Function/Get the maximum y coordinate that can be used on this screen. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/unsigned tgi_getmaxy (void);/ +<tag/Description/Get the maximum y coordinate that can be used on this screen. +<tag/Availability/cc65 +<tag/See also/Other tgi functions +<tag/Example/None. +</descrip> +</quote> + + +<sect1>tgi_getpagecount<label id="tgi_getpagecount"><p> + +<quote> +<descrip> +<tag/Function/Return the number of screen pages available. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/unsigned tgi_getpagecount (void);/ +<tag/Description/Return the number of screen pages available. +<tag/Availability/cc65 +<tag/See also/ +<ref id="tgi_setdrawpage" name="tgi_setdrawpage">, +<ref id="tgi_setviewpage" name="tgi_setviewpage"> +<tag/Example/None. +</descrip> +</quote> + + +<sect1>tgi_getpalette<label id="tgi_getpalette"><p> + +<quote> +<descrip> +<tag/Function/Get the palette installed. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/const unsigned char* tgi_getpalette (void);/ +<tag/Description/Get the palette installed. +<tag/Availability/cc65 +<tag/See also/Other tgi functions +<tag/Example/None. +</descrip> +</quote> + + +<sect1>tgi_getpixel<label id="tgi_getpixel"><p> + +<quote> +<descrip> +<tag/Function/Get the color 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/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/Example/None. +</descrip> +</quote> + + +<sect1>tgi_getxres<label id="tgi_getxres"><p> + +<quote> +<descrip> +<tag/Function/Get number of horisontal 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. +This is same as tgi_maxx()+1. +<tag/Availability/cc65 +<tag/See also/Other tgi functions. +<tag/Example/None. +</descrip> +</quote> + + +<sect1>tgi_getyres<label id="tgi_getyres"><p> + +<quote> +<descrip> +<tag/Function/Get number of vertical pixels on the screen. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/unsigned tgi_getyres (void);/ +<tag/Description/Get number of vertical pixels on the screen. +This is same as tgi_maxy()+1. +<tag/Availability/cc65 +<tag/See also/Other tgi functions. +<tag/Example/None. +</descrip> +</quote> + + +<sect1>tgi_gotoxy<label id="tgi_gotoxy"><p> + +<quote> +<descrip> +<tag/Function/Set graphics cursor at x, y. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_gotoxy (int x, int y);/ +<tag/Description/Set graphics cursor at x, y. +<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/Example/None. +</descrip> +</quote> + + +<sect1>tgi_init<label id="tgi_init"><p> + +<quote> +<descrip> +<tag/Function/Initialize the already loaded graphics driver. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void tgi_init (void);/ +<tag/Description/The tgi_init function will set the default palette to the +hardware. +<tag/Notes/<itemize> +<item><tt/tgi_init/ will not clear the screen. This allows switching between +text and graphics mode on platforms that have separate memory areas for the +screens. If you want the screen cleared, call <tt/<ref id="tgi_clear" +name="tgi_clear">/ after <tt/tgi_init/. +</itemize> +<tag/Availability/cc65 +<tag/See also/Other tgi functions. +<tag/Example/<verb> +tgi_install(tgi_static_stddrv); //Include the driver statically instead of loading it. +tgi_init(); //Set up the default palette and clear the screen. +</verb> +</descrip> +</quote> + + +<sect1>tgi_install<label id="tgi_install"><p> + +<quote> +<descrip> +<tag/Function/Install an already loaded driver and return an error code. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/unsigned char __fastcall__ tgi_install (void* driver);/ +<tag/Description/The function installs a driver that was already loaded into +memory (or linked statically to the program). It returns an error code +(<tt/TGI_ERR_OK/ in case of success). +<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/ +<ref id="tgi_load_driver" name="tgi_load_driver">, +<ref id="tgi_uninstall" name="tgi_uninstall">, +<ref id="tgi_unload" name="tgi_unload"> +<tag/Example/<verb> +tgi_install(tgi_static_stddrv); //Include the driver statically instead of loading it. +tgi_init(); //Set up the default palette and clear the screen. +</verb> +</descrip> +</quote> + + +<sect1>tgi_install_vectorfont<label id="tgi_install_vectorfont"><p> + +<quote> +<descrip> +<tag/Function/Install an already loaded driver and return an error code. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_install_vectorfont (const tgi_vectorfont* font);/ +<tag/Description/ +Install a vector font for use. More than one vector font can be loaded, +but only one can be active. This function is used to tell which one. Call +with a NULL pointer to uninstall the currently installed font. +<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/ +<ref id="tgi_load_vectorfont" name="tgi_load_vectorfont">, +<ref id="tgi_free_vectorfont" name="tgi_free_vectorfont"> +<tag/Example/None. +</descrip> +</quote> + + +<sect1>tgi_ioctl<label id="tgi_ioctl"><p> + +<quote> +<descrip> +<tag/Function/Platform dependent code extensions. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/unsigned __fastcall__ tgi_ioctl (unsigned char code, void* data);/ +<tag/Description/Some platforms have extra display hardware that is not +supported by standard tgi functions. You can extend the driver to support +this extra hardware using tgi_ioctl functions. +<tag/Notes/<itemize> +<item>The function is only available as fastcall function, so it may only +be used in presence of a prototype. +<item>These functions are not easily portable to other cc65 platforms. +</itemize> +<tag/Availability/cc65 +<tag/See also/Other tgi functions. +<tag/Example/<verb> +#define tgi_sprite(spr) tgi_ioctl(0, (void*)(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) +if (!tgi_busy()) { + tgi_sprite(&background); + tgi_setcolor(TGI_COLOR_BLUE); + tgi_outttextxy(20,40,"Hello World"); + tgi_updatedisplay(); +} +</verb> +</descrip> +</quote> + + +<sect1>tgi_line<label id="tgi_line"><p> + +<quote> +<descrip> +<tag/Function/Draw a line in the current drawing color. +The graphics cursor will be set to x2/y2 by this call. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_line (int x1, int y1, int x2, int y2);/ +<tag/Description/Draw a line in the current drawing color. +The graphics cursor will be set to x2/y2 by this call. +<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/Example/None. +</descrip> +</quote> + + +<sect1>tgi_lineto<label id="tgi_lineto"><p> + +<quote> +<descrip> +<tag/Function/Draw a line in the current drawing color from the graphics +cursor to the new end point. The graphics cursor will be updated to x2/y2. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_lineto (int x2, int y2);/ +<tag/Description/Draw a line in the current drawing color from the graphics +cursor to the new end point. The graphics cursor will be updated to x2/y2. +<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/Example/None. +</descrip> +</quote> + + +<sect1>tgi_load_driver<label id="tgi_load_driver"><p> + +<quote> +<descrip> +<tag/Function/Load and install the given driver. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_load_driver (const char *name);/ +<tag/Description/Load and install the driver by name. +Will just load the driver and check if loading was successful. +Will not switch to graphics mode. +<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/Example/None. +</descrip> +</quote> + + +<sect1>tgi_load_vectorfont<label id="tgi_load_vectorfont"><p> + +<quote> +<descrip> +<tag/Function/Load the given vector font. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/const tgi_vectorfont* __fastcall__ tgi_load_vectorfont (const char* name);/ +<tag/Description/ +Load a vector font into memory and return it. In case of errors, NULL is +returned and an error is set, which can be retrieved using tgi_geterror. +To use the font, it has to be installed using tgi_install_vectorfont. +<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/ +<ref id="tgi_install_vectorfont" name="tgi_install_vectorfont">, +<ref id="tgi_free_vectorfont" name="tgi_free_vectorfont"> +<tag/Example/None. +</descrip> +</quote> + + +<sect1>tgi_outtext<label id="tgi_outtext"><p> + +<quote> +<descrip> +<tag/Function/Output text at the current graphics cursor position. +The graphics cursor is moved to the end of the text. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_outtext (const char* s);/ +<tag/Description/Output text at the current graphics cursor position. +The graphics cursor is moved to the end of the text. +<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/Example/None. +</descrip> +</quote> + + +<sect1>tgi_outtextxy<label id="tgi_outtextxy"><p> + +<quote> +<descrip> +<tag/Function/Output text at the given cursor position. +The graphics cursor is moved to the end of the text. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_outtextxy (int x, int y, const char* s);/ +<tag/Description/Output text at the given cursor position. +The graphics cursor is moved to the end of the text. +<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/Example/None. +</descrip> +</quote> + + +<sect1>tgi_pieslice<label id="tgi_pieslice"><p> + +<quote> +<descrip> +<tag/Function/Draw an elliptic pie slice in the current color. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_pie slice (int x, int y, +unsigned char rx, unsigned char ry, unsigned sa, unsigned ea);/ +<tag/Description/The function draws an elliptic pie slice with center at x/y +and radii rx/ry using the current drawing color. The pie slice covers the angle +between sa and ea (startangle and endangle), which must be in the range +0..360. +<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 function behaves unexpectedly or may crash if the angles are out +of range. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="tgi_bar" name="tgi_arc">, +<ref id="tgi_bar" name="tgi_bar">, +<ref id="tgi_circle" name="tgi_circle">, +<ref id="tgi_ellipse" name="tgi_ellipse">, +<ref id="tgi_setcolor" name="tgi_setcolor"> +<tag/Example/<verb> +/* Draw the closed upper half of an ellipse */ +tgi_setcolor(TGI_COLOR_BLUE); +tgi_pieslice (50, 50, 40, 20, 0, 180); +</verb> +</descrip> +</quote> + + +<sect1>tgi_setaspectratio<label id="tgi_setaspectratio"><p> + +<quote> <descrip> <tag/Function/Set the pixel aspect ratio. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_setaspectratio (unsigned ratio);/ +<tag/Description/The function sets the pixel aspect ratio for the current +driver and display. The argument is an 8.8 fixed point value. The aspect ratio +may be used to correct geometric shapes so they look correct on a given +display. As an example, a circle with a radius of 100 pixels may look elliptic +on some driver/display combinations if the aspect ratio is not 1.00. +<tag/Notes/<itemize> +<item>The aspect ratio is encoded in the TGI driver which assumes a "standard" +monitor for the given platform. The aspect ratio may be wrong if another +monitor is used. +<item>No TGI function will use the aspect ratio. It is up to the programmer to +make use of it. +<item>The <tt/tgi_setaspectratio/ function can be used to change the aspect +ratio for a loaded driver. The value is not reset by <ref id="tgi_init" +name="tgi_init">, so if a driver is linked statically to an application, +switching into and out of graphics mode will not restore the original aspect +ratio. +<item>The function is available only as a fastcall function; so, it may be used +only in the presence of a prototype. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="tgi_getaspectratio" name="tgi_getaspectratio"> +<tag/Example/None. +</descrip> +</quote> + + +<sect1>tgi_setcolor<label id="tgi_setcolor"><p> + +<quote> +<descrip> +<tag/Function/Set color 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/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/Example/<verb> +tgi_setcolor(TGI_COLOR_BLACK); +tgi_bar(0,0,30,30); +tgi_setcolor(TGI_COLOR_WHITE); +tgi_bar(10,10,20,20); +</verb> +</descrip> +</quote> + +<sect1>tgi_setdrawpage<label id="tgi_setdrawpage"><p> + +<quote> +<descrip> +<tag/Function/Set the page for drawing. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_setdrawpage (unsigned char page);/ +<tag/Description/If the drawpage and the viewpage are the same then all drawing +is seen immediately as it is drawn. For double buffered games you can set the +drawpage to a different page than the viewpage. This lets you draw the next +screen in the background and when the screen is ready you display it. +<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/Example/<verb> +tgi_setdrawpage(1); +tgi_outtextxy(10, 10, "Hello World"); +tgi_setviewpage(1); // Show page 1 +tgi_setdrawpage(0); +tgi_outtextxy(10, 10, "Creating next frame"); +... +tgi_setviewpage(0); // Show page 0 +</verb> +</descrip> +</quote> + +<sect1>tgi_setpalette<label id="tgi_setpalette"><p> + +<quote> +<descrip> +<tag/Function/Set the palette (not available with all drivers/hardware). +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. +<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/Example/None. +</descrip> +</quote> + +<sect1>tgi_setpixel<label id="tgi_setpixel"><p> + +<quote> +<descrip> +<tag/Function/Plot a pixel on the drawpage with the current color. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_setpixel (int x, int y);/ +<tag/Description/Plot a pixel on the drawpage with the current color. +<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/Example/None. +</descrip> +</quote> + +<sect1>tgi_setviewpage<label id="tgi_setviewpage"><p> + +<quote> +<descrip> +<tag/Function/Set page to be visible on screen. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_setviewpage (unsigned char page);/ +<tag/Description/If the drawpage and the viewpage are the same then all drawing +is seen immediately as it is drawn. For double buffered games you can set the +drawpage to a different page than the viewpage. This lets you draw the next +screen in the background and when the screen is ready you display it. +<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/Example/<verb> +tgi_setdrawpage(1); +tgi_outtextxy(10, 10, "Hello World"); +tgi_setviewpage(1); // Show page 1 +tgi_setdrawpage(0); +tgi_outtextxy(10, 10, "Creating next frame"); +... +tgi_setviewpage(0); // Show page 0 +</verb> +</descrip> +</quote> + +<sect1>tgi_gettextheight<label id="tgi_gettextheight"><p> + +<quote> +<descrip> +<tag/Function/Calculate the height of the text in pixels according to +the current text style. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/unsigned __fastcall__ tgi_gettextheight (const char* s);/ +<tag/Description/Calculate the height of the text in pixels according to +the current text style. +<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/Example/None. +</descrip> +</quote> + +<sect1>tgi_settextscale<label id="tgi_settextscale"><p> + +<quote> +<descrip> +<tag/Function/Set the scaling for text output. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_settextscale (unsigned width, unsigned height);/ +<tag/Description/ +Set the scaling for text output. The scaling factors for width and height +are 8.8 fixed point values. This means that $100 = 1 $200 = 2 etc. +<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/ +<ref id="tgi_settextstyle" name="tgi_settextstyle"> +<tag/Example/None. +</descrip> +</quote> + +<sect1>tgi_settextstyle<label id="tgi_settextstyle"><p> + +<quote> +<descrip> +<tag/Function/Set the style for text output. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void __fastcall__ tgi_settextstyle (unsigned char magx, unsigned char magy, unsigned char dir, unsigned char font);/ +<tag/Description/Set the style for text output. +<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/ +<ref id="tgi_settextscale" name="tgi_settextscale"> +<tag/Example/None. +</descrip> +</quote> + +<sect1>tgi_gettextwidth<label id="tgi_gettextwidth"><p> + +<quote> +<descrip> +<tag/Function/Calculate the width of the text in pixels according to the current text style. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/unsigned __fastcall__ tgi_gettextwidth (const char* s);/ +<tag/Description/Calculate the width of the text in pixels according to the current text style. +<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/Example/None. +</descrip> +</quote> + +<sect1>tgi_uninstall<label id="tgi_uninstall"><p> + +<quote> +<descrip> +<tag/Function/Uninstall the currently loaded driver but do not unload it. +Will call tgi_done if necessary. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void tgi_uninstall (void);/ +<tag/Description/Uninstall the currently loaded driver but do not unload it. +Will call tgi_done if necessary. +<tag/Availability/cc65 +<tag/See also/Other tgi functions. +<tag/Example/None. +</descrip> +</quote> + +<sect1>tgi_unload<label id="tgi_unload"><p> + +<quote> +<descrip> +<tag/Function/Uninstall, then unload the currently loaded driver. +Will call tgi_done if necessary. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/void tgi_unload (void);/ +<tag/Description/Uninstall, then unload the currently loaded driver. +Will call tgi_done if necessary. +<tag/Availability/cc65 +<tag/See also/Other tgi functions. +<tag/Example/None. +</descrip> +</quote> + + +</article> From aa30f50fbef509caf5a5d034d60c2217f888aef4 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 25 Nov 2017 22:39:41 +0100 Subject: [PATCH 0502/2161] Update tgi.sgml Fixed toc. --- doc/tgi.sgml | 47 +---------------------------------------------- 1 file changed, 1 insertion(+), 46 deletions(-) diff --git a/doc/tgi.sgml b/doc/tgi.sgml index 3bab58f57..d9253cf09 100644 --- a/doc/tgi.sgml +++ b/doc/tgi.sgml @@ -11,52 +11,7 @@ Include the tgi.h header file to get the necessary definitions. </abstract> <!-- Table of contents --> -<itemize> -<item><ref id="tgi_arc" name="tgi_arc"> -<item><ref id="tgi_bar" name="tgi_bar"> -<item><ref id="tgi_circle" name="tgi_circle"> -<item><ref id="tgi_clear" name="tgi_clear"> -<item><ref id="tgi_done" name="tgi_done"> -<item><ref id="tgi_ellipse" name="tgi_ellipse"> -<item><ref id="tgi_free_vectorfont" name="tgi_free_vectorfont"> -<item><ref id="tgi_getaspectratio" name="tgi_getaspectratio"> -<item><ref id="tgi_getcolor" name="tgi_getcolor"> -<item><ref id="tgi_getcolorcount" name="tgi_getcolorcount"> -<item><ref id="tgi_getdefpalette" name="tgi_getdefpalette"> -<item><ref id="tgi_geterror" name="tgi_geterror"> -<item><ref id="tgi_geterrormsg" name="tgi_geterrormsg"> -<item><ref id="tgi_getmaxcolor" name="tgi_getmaxcolor"> -<item><ref id="tgi_getmaxx" name="tgi_getmaxx"> -<item><ref id="tgi_getmaxy" name="tgi_getmaxy"> -<item><ref id="tgi_getpagecount" name="tgi_getpagecount"> -<item><ref id="tgi_getpalette" name="tgi_getpalette"> -<item><ref id="tgi_getpixel" name="tgi_getpixel"> -<item><ref id="tgi_gettextheight" name="tgi_gettextheight"> -<item><ref id="tgi_gettextwidth" name="tgi_gettextwidth"> -<item><ref id="tgi_getxres" name="tgi_getxres"> -<item><ref id="tgi_getyres" name="tgi_getyres"> -<item><ref id="tgi_gotoxy" name="tgi_gotoxy"> -<item><ref id="tgi_init" name="tgi_init"> -<item><ref id="tgi_install" name="tgi_install"> -<item><ref id="tgi_install_vectorfont" name="tgi_install_vectorfont"> -<item><ref id="tgi_ioctl" name="tgi_ioctl"> -<item><ref id="tgi_line" name="tgi_line"> -<item><ref id="tgi_lineto" name="tgi_lineto"> -<item><ref id="tgi_load_driver" name="tgi_load_driver"> -<item><ref id="tgi_load_vectorfont" name="tgi_load_vectorfont"> -<item><ref id="tgi_outtext" name="tgi_outtext"> -<item><ref id="tgi_outtextxy" name="tgi_outtextxy"> -<item><ref id="tgi_setaspectratio" name="tgi_setaspectratio"> -<item><ref id="tgi_setcolor" name="tgi_setcolor"> -<item><ref id="tgi_setdrawpage" name="tgi_setdrawpage"> -<item><ref id="tgi_setpalette" name="tgi_setpalette"> -<item><ref id="tgi_setpixel" name="tgi_setpixel"> -<item><ref id="tgi_setviewpage" name="tgi_setviewpage"> -<item><ref id="tgi_settextscale" name="tgi_settextscale"> -<item><ref id="tgi_settextstyle" name="tgi_settextstyle"> -<item><ref id="tgi_uninstall" name="tgi_uninstall"> -<item><ref id="tgi_unload" name="tgi_unload"> -</itemize> +<toc> <!-- Begin the document --> From 9725c4493401faac39d1f302569c4461f3bb11f5 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 25 Nov 2017 23:09:19 +0100 Subject: [PATCH 0503/2161] Update tgi.sgml I should take more attention of Travis. --- doc/tgi.sgml | 90 ++++++++++++++++++++++++++-------------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/doc/tgi.sgml b/doc/tgi.sgml index d9253cf09..722583893 100644 --- a/doc/tgi.sgml +++ b/doc/tgi.sgml @@ -15,7 +15,7 @@ Include the tgi.h header file to get the necessary definitions. <!-- Begin the document --> -<sect1>tgi_arc<label id="tgi_arc"><p> +<sect>tgi_arc<label id="tgi_arc"><p> <quote> <descrip> @@ -49,7 +49,7 @@ tgi_arc (50, 50, 40, 20, 0, 180); </quote> -<sect1>tgi_bar<label id="tgi_bar"><p> +<sect>tgi_bar<label id="tgi_bar"><p> <quote> <descrip> @@ -73,7 +73,7 @@ tgi_bar(10, 10, 100, 60); </quote> -<sect1>tgi_circle<label id="tgi_circle"><p> +<sect>tgi_circle<label id="tgi_circle"><p> <quote> <descrip> @@ -100,7 +100,7 @@ tgi_circle(50, 40, 40); </quote> -<sect1>tgi_clear<label id="tgi_clear"><p> +<sect>tgi_clear<label id="tgi_clear"><p> <quote> <descrip> @@ -115,7 +115,7 @@ tgi_circle(50, 40, 40); </quote> -<sect1>tgi_done<label id="tgi_done"><p> +<sect>tgi_done<label id="tgi_done"><p> <quote> <descrip> @@ -132,7 +132,7 @@ Will NOT uninstall or unload the driver! </quote> -<sect1>tgi_ellipse<label id="tgi_ellipse"><p> +<sect>tgi_ellipse<label id="tgi_ellipse"><p> <quote> <descrip> @@ -160,7 +160,7 @@ tgi_ellipse (50, 40, 40, 20); </quote> -<sect1>tgi_free_vectorfont<label id="tgi_free_vectorfont"><p> +<sect>tgi_free_vectorfont<label id="tgi_free_vectorfont"><p> <quote> <descrip> @@ -181,7 +181,7 @@ be used in presence of a prototype. </quote> -<sect1>tgi_getaspectratio<label id="tgi_getaspectratio"><p> +<sect>tgi_getaspectratio<label id="tgi_getaspectratio"><p> <quote> <descrip> <tag/Function/Return the pixel aspect ratio. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ @@ -211,7 +211,7 @@ original aspect ratio. </quote> -<sect1>tgi_getcolor<label id="tgi_getcolor"><p> +<sect>tgi_getcolor<label id="tgi_getcolor"><p> <quote> <descrip> @@ -233,7 +233,7 @@ color = tgi_getcolor(); </quote> -<sect1>tgi_getcolorcount<label id="tgi_getcolorcount"><p> +<sect>tgi_getcolorcount<label id="tgi_getcolorcount"><p> <quote> <descrip> @@ -253,7 +253,7 @@ if (tgi_getcolorcount() == 2) { </quote> -<sect1>tgi_getdefpalette<label id="tgi_getdefpalette"><p> +<sect>tgi_getdefpalette<label id="tgi_getdefpalette"><p> <quote> <descrip> @@ -270,7 +270,7 @@ palette to work correctly. </quote> -<sect1>tgi_geterror<label id="tgi_geterror"><p> +<sect>tgi_geterror<label id="tgi_geterror"><p> <quote> <descrip> @@ -287,7 +287,7 @@ This will also clear the error. </quote> -<sect1>tgi_geterrormsg<label id="tgi_geterrormsg"><p> +<sect>tgi_geterrormsg<label id="tgi_geterrormsg"><p> <quote> <descrip> @@ -306,7 +306,7 @@ be used in presence of a prototype. </quote> -<sect1>tgi_getmaxcolor<label id="tgi_getmaxcolor"><p> +<sect>tgi_getmaxcolor<label id="tgi_getmaxcolor"><p> <quote> <descrip> @@ -321,7 +321,7 @@ be used in presence of a prototype. </quote> -<sect1>tgi_getmaxx<label id="tgi_getmaxx"><p> +<sect>tgi_getmaxx<label id="tgi_getmaxx"><p> <quote> <descrip> @@ -336,7 +336,7 @@ be used in presence of a prototype. </quote> -<sect1>tgi_getmaxy<label id="tgi_getmaxy"><p> +<sect>tgi_getmaxy<label id="tgi_getmaxy"><p> <quote> <descrip> @@ -351,7 +351,7 @@ be used in presence of a prototype. </quote> -<sect1>tgi_getpagecount<label id="tgi_getpagecount"><p> +<sect>tgi_getpagecount<label id="tgi_getpagecount"><p> <quote> <descrip> @@ -368,7 +368,7 @@ be used in presence of a prototype. </quote> -<sect1>tgi_getpalette<label id="tgi_getpalette"><p> +<sect>tgi_getpalette<label id="tgi_getpalette"><p> <quote> <descrip> @@ -383,7 +383,7 @@ be used in presence of a prototype. </quote> -<sect1>tgi_getpixel<label id="tgi_getpixel"><p> +<sect>tgi_getpixel<label id="tgi_getpixel"><p> <quote> <descrip> @@ -402,7 +402,7 @@ be used in presence of a prototype. </quote> -<sect1>tgi_getxres<label id="tgi_getxres"><p> +<sect>tgi_getxres<label id="tgi_getxres"><p> <quote> <descrip> @@ -418,7 +418,7 @@ This is same as tgi_maxx()+1. </quote> -<sect1>tgi_getyres<label id="tgi_getyres"><p> +<sect>tgi_getyres<label id="tgi_getyres"><p> <quote> <descrip> @@ -434,7 +434,7 @@ This is same as tgi_maxy()+1. </quote> -<sect1>tgi_gotoxy<label id="tgi_gotoxy"><p> +<sect>tgi_gotoxy<label id="tgi_gotoxy"><p> <quote> <descrip> @@ -453,7 +453,7 @@ be used in presence of a prototype. </quote> -<sect1>tgi_init<label id="tgi_init"><p> +<sect>tgi_init<label id="tgi_init"><p> <quote> <descrip> @@ -478,7 +478,7 @@ tgi_init(); //Set up the default palette and clear the screen. </quote> -<sect1>tgi_install<label id="tgi_install"><p> +<sect>tgi_install<label id="tgi_install"><p> <quote> <descrip> @@ -505,7 +505,7 @@ tgi_init(); //Set up the default palette and clear the screen. </quote> -<sect1>tgi_install_vectorfont<label id="tgi_install_vectorfont"><p> +<sect>tgi_install_vectorfont<label id="tgi_install_vectorfont"><p> <quote> <descrip> @@ -529,7 +529,7 @@ used in presence of a prototype. </quote> -<sect1>tgi_ioctl<label id="tgi_ioctl"><p> +<sect>tgi_ioctl<label id="tgi_ioctl"><p> <quote> <descrip> @@ -564,7 +564,7 @@ if (!tgi_busy()) { </quote> -<sect1>tgi_line<label id="tgi_line"><p> +<sect>tgi_line<label id="tgi_line"><p> <quote> <descrip> @@ -585,7 +585,7 @@ be used in presence of a prototype. </quote> -<sect1>tgi_lineto<label id="tgi_lineto"><p> +<sect>tgi_lineto<label id="tgi_lineto"><p> <quote> <descrip> @@ -606,7 +606,7 @@ be used in presence of a prototype. </quote> -<sect1>tgi_load_driver<label id="tgi_load_driver"><p> +<sect>tgi_load_driver<label id="tgi_load_driver"><p> <quote> <descrip> @@ -627,7 +627,7 @@ be used in presence of a prototype. </quote> -<sect1>tgi_load_vectorfont<label id="tgi_load_vectorfont"><p> +<sect>tgi_load_vectorfont<label id="tgi_load_vectorfont"><p> <quote> <descrip> @@ -651,7 +651,7 @@ be used in presence of a prototype. </quote> -<sect1>tgi_outtext<label id="tgi_outtext"><p> +<sect>tgi_outtext<label id="tgi_outtext"><p> <quote> <descrip> @@ -672,7 +672,7 @@ be used in presence of a prototype. </quote> -<sect1>tgi_outtextxy<label id="tgi_outtextxy"><p> +<sect>tgi_outtextxy<label id="tgi_outtextxy"><p> <quote> <descrip> @@ -693,7 +693,7 @@ be used in presence of a prototype. </quote> -<sect1>tgi_pieslice<label id="tgi_pieslice"><p> +<sect>tgi_pieslice<label id="tgi_pieslice"><p> <quote> <descrip> @@ -727,7 +727,7 @@ tgi_pieslice (50, 50, 40, 20, 0, 180); </quote> -<sect1>tgi_setaspectratio<label id="tgi_setaspectratio"><p> +<sect>tgi_setaspectratio<label id="tgi_setaspectratio"><p> <quote> <descrip> <tag/Function/Set the pixel aspect ratio. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ @@ -759,7 +759,7 @@ only in the presence of a prototype. </quote> -<sect1>tgi_setcolor<label id="tgi_setcolor"><p> +<sect>tgi_setcolor<label id="tgi_setcolor"><p> <quote> <descrip> @@ -782,7 +782,7 @@ tgi_bar(10,10,20,20); </descrip> </quote> -<sect1>tgi_setdrawpage<label id="tgi_setdrawpage"><p> +<sect>tgi_setdrawpage<label id="tgi_setdrawpage"><p> <quote> <descrip> @@ -811,7 +811,7 @@ tgi_setviewpage(0); // Show page 0 </descrip> </quote> -<sect1>tgi_setpalette<label id="tgi_setpalette"><p> +<sect>tgi_setpalette<label id="tgi_setpalette"><p> <quote> <descrip> @@ -831,7 +831,7 @@ be used in presence of a prototype. </descrip> </quote> -<sect1>tgi_setpixel<label id="tgi_setpixel"><p> +<sect>tgi_setpixel<label id="tgi_setpixel"><p> <quote> <descrip> @@ -849,7 +849,7 @@ be used in presence of a prototype. </descrip> </quote> -<sect1>tgi_setviewpage<label id="tgi_setviewpage"><p> +<sect>tgi_setviewpage<label id="tgi_setviewpage"><p> <quote> <descrip> @@ -878,7 +878,7 @@ tgi_setviewpage(0); // Show page 0 </descrip> </quote> -<sect1>tgi_gettextheight<label id="tgi_gettextheight"><p> +<sect>tgi_gettextheight<label id="tgi_gettextheight"><p> <quote> <descrip> @@ -898,7 +898,7 @@ be used in presence of a prototype. </descrip> </quote> -<sect1>tgi_settextscale<label id="tgi_settextscale"><p> +<sect>tgi_settextscale<label id="tgi_settextscale"><p> <quote> <descrip> @@ -919,7 +919,7 @@ be used in presence of a prototype. </descrip> </quote> -<sect1>tgi_settextstyle<label id="tgi_settextstyle"><p> +<sect>tgi_settextstyle<label id="tgi_settextstyle"><p> <quote> <descrip> @@ -938,7 +938,7 @@ be used in presence of a prototype. </descrip> </quote> -<sect1>tgi_gettextwidth<label id="tgi_gettextwidth"><p> +<sect>tgi_gettextwidth<label id="tgi_gettextwidth"><p> <quote> <descrip> @@ -956,7 +956,7 @@ be used in presence of a prototype. </descrip> </quote> -<sect1>tgi_uninstall<label id="tgi_uninstall"><p> +<sect>tgi_uninstall<label id="tgi_uninstall"><p> <quote> <descrip> @@ -972,7 +972,7 @@ Will call tgi_done if necessary. </descrip> </quote> -<sect1>tgi_unload<label id="tgi_unload"><p> +<sect>tgi_unload<label id="tgi_unload"><p> <quote> <descrip> From fa9a1cf2dc0e8fd654ecc4a694e92deeac6a7c6d Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 25 Nov 2017 23:32:52 +0100 Subject: [PATCH 0504/2161] Update tgi.sgml Added missing ref. --- doc/tgi.sgml | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/tgi.sgml b/doc/tgi.sgml index 722583893..23b5ce6ae 100644 --- a/doc/tgi.sgml +++ b/doc/tgi.sgml @@ -11,6 +11,7 @@ Include the tgi.h header file to get the necessary definitions. </abstract> <!-- Table of contents --> +<tt/tgi.h/<label id="tgi.h"><p> <toc> <!-- Begin the document --> From a029c006605b5e124069d22fb1efcd956ec81b43 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 30 Nov 2017 11:38:12 -0500 Subject: [PATCH 0505/2161] Fixed a Table-Of-Contents bug in the TGI document. The <toc> tag can't be put inside of a section. It isn't needed, anyway; we can get a TOC by putting the header as a section, and the functions as subsections. --- doc/tgi.sgml | 112 ++++++++++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 51 deletions(-) diff --git a/doc/tgi.sgml b/doc/tgi.sgml index 23b5ce6ae..fc60653a3 100644 --- a/doc/tgi.sgml +++ b/doc/tgi.sgml @@ -2,21 +2,21 @@ <article> <title>Tiny Graphics Interface -<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2017-11-23 +<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:greg.king5@verizon.net" name="Greg King"> +<date>2017-11-26 <abstract> The cc65 library provides functions for platform independent graphics. Include the tgi.h header file to get the necessary definitions. </abstract> -<!-- Table of contents --> -<tt/tgi.h/<label id="tgi.h"><p> -<toc> - <!-- Begin the document --> -<sect>tgi_arc<label id="tgi_arc"><p> +<sect>tgi.h<label id="tgi.h"> + +<sect1>tgi_arc<label id="tgi_arc"><p> <quote> <descrip> @@ -50,7 +50,7 @@ tgi_arc (50, 50, 40, 20, 0, 180); </quote> -<sect>tgi_bar<label id="tgi_bar"><p> +<sect1>tgi_bar<label id="tgi_bar"><p> <quote> <descrip> @@ -74,7 +74,7 @@ tgi_bar(10, 10, 100, 60); </quote> -<sect>tgi_circle<label id="tgi_circle"><p> +<sect1>tgi_circle<label id="tgi_circle"><p> <quote> <descrip> @@ -101,7 +101,7 @@ tgi_circle(50, 40, 40); </quote> -<sect>tgi_clear<label id="tgi_clear"><p> +<sect1>tgi_clear<label id="tgi_clear"><p> <quote> <descrip> @@ -116,7 +116,7 @@ tgi_circle(50, 40, 40); </quote> -<sect>tgi_done<label id="tgi_done"><p> +<sect1>tgi_done<label id="tgi_done"><p> <quote> <descrip> @@ -133,7 +133,7 @@ Will NOT uninstall or unload the driver! </quote> -<sect>tgi_ellipse<label id="tgi_ellipse"><p> +<sect1>tgi_ellipse<label id="tgi_ellipse"><p> <quote> <descrip> @@ -161,7 +161,7 @@ tgi_ellipse (50, 40, 40, 20); </quote> -<sect>tgi_free_vectorfont<label id="tgi_free_vectorfont"><p> +<sect1>tgi_free_vectorfont<label id="tgi_free_vectorfont"><p> <quote> <descrip> @@ -182,7 +182,7 @@ be used in presence of a prototype. </quote> -<sect>tgi_getaspectratio<label id="tgi_getaspectratio"><p> +<sect1>tgi_getaspectratio<label id="tgi_getaspectratio"><p> <quote> <descrip> <tag/Function/Return the pixel aspect ratio. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ @@ -212,7 +212,7 @@ original aspect ratio. </quote> -<sect>tgi_getcolor<label id="tgi_getcolor"><p> +<sect1>tgi_getcolor<label id="tgi_getcolor"><p> <quote> <descrip> @@ -234,7 +234,7 @@ color = tgi_getcolor(); </quote> -<sect>tgi_getcolorcount<label id="tgi_getcolorcount"><p> +<sect1>tgi_getcolorcount<label id="tgi_getcolorcount"><p> <quote> <descrip> @@ -254,7 +254,7 @@ if (tgi_getcolorcount() == 2) { </quote> -<sect>tgi_getdefpalette<label id="tgi_getdefpalette"><p> +<sect1>tgi_getdefpalette<label id="tgi_getdefpalette"><p> <quote> <descrip> @@ -271,7 +271,7 @@ palette to work correctly. </quote> -<sect>tgi_geterror<label id="tgi_geterror"><p> +<sect1>tgi_geterror<label id="tgi_geterror"><p> <quote> <descrip> @@ -288,7 +288,7 @@ This will also clear the error. </quote> -<sect>tgi_geterrormsg<label id="tgi_geterrormsg"><p> +<sect1>tgi_geterrormsg<label id="tgi_geterrormsg"><p> <quote> <descrip> @@ -307,7 +307,7 @@ be used in presence of a prototype. </quote> -<sect>tgi_getmaxcolor<label id="tgi_getmaxcolor"><p> +<sect1>tgi_getmaxcolor<label id="tgi_getmaxcolor"><p> <quote> <descrip> @@ -322,7 +322,7 @@ be used in presence of a prototype. </quote> -<sect>tgi_getmaxx<label id="tgi_getmaxx"><p> +<sect1>tgi_getmaxx<label id="tgi_getmaxx"><p> <quote> <descrip> @@ -337,7 +337,7 @@ be used in presence of a prototype. </quote> -<sect>tgi_getmaxy<label id="tgi_getmaxy"><p> +<sect1>tgi_getmaxy<label id="tgi_getmaxy"><p> <quote> <descrip> @@ -352,7 +352,7 @@ be used in presence of a prototype. </quote> -<sect>tgi_getpagecount<label id="tgi_getpagecount"><p> +<sect1>tgi_getpagecount<label id="tgi_getpagecount"><p> <quote> <descrip> @@ -369,7 +369,7 @@ be used in presence of a prototype. </quote> -<sect>tgi_getpalette<label id="tgi_getpalette"><p> +<sect1>tgi_getpalette<label id="tgi_getpalette"><p> <quote> <descrip> @@ -384,7 +384,7 @@ be used in presence of a prototype. </quote> -<sect>tgi_getpixel<label id="tgi_getpixel"><p> +<sect1>tgi_getpixel<label id="tgi_getpixel"><p> <quote> <descrip> @@ -403,7 +403,7 @@ be used in presence of a prototype. </quote> -<sect>tgi_getxres<label id="tgi_getxres"><p> +<sect1>tgi_getxres<label id="tgi_getxres"><p> <quote> <descrip> @@ -419,7 +419,7 @@ This is same as tgi_maxx()+1. </quote> -<sect>tgi_getyres<label id="tgi_getyres"><p> +<sect1>tgi_getyres<label id="tgi_getyres"><p> <quote> <descrip> @@ -435,7 +435,7 @@ This is same as tgi_maxy()+1. </quote> -<sect>tgi_gotoxy<label id="tgi_gotoxy"><p> +<sect1>tgi_gotoxy<label id="tgi_gotoxy"><p> <quote> <descrip> @@ -454,7 +454,7 @@ be used in presence of a prototype. </quote> -<sect>tgi_init<label id="tgi_init"><p> +<sect1>tgi_init<label id="tgi_init"><p> <quote> <descrip> @@ -479,7 +479,7 @@ tgi_init(); //Set up the default palette and clear the screen. </quote> -<sect>tgi_install<label id="tgi_install"><p> +<sect1>tgi_install<label id="tgi_install"><p> <quote> <descrip> @@ -506,7 +506,7 @@ tgi_init(); //Set up the default palette and clear the screen. </quote> -<sect>tgi_install_vectorfont<label id="tgi_install_vectorfont"><p> +<sect1>tgi_install_vectorfont<label id="tgi_install_vectorfont"><p> <quote> <descrip> @@ -530,7 +530,7 @@ used in presence of a prototype. </quote> -<sect>tgi_ioctl<label id="tgi_ioctl"><p> +<sect1>tgi_ioctl<label id="tgi_ioctl"><p> <quote> <descrip> @@ -565,7 +565,7 @@ if (!tgi_busy()) { </quote> -<sect>tgi_line<label id="tgi_line"><p> +<sect1>tgi_line<label id="tgi_line"><p> <quote> <descrip> @@ -586,7 +586,7 @@ be used in presence of a prototype. </quote> -<sect>tgi_lineto<label id="tgi_lineto"><p> +<sect1>tgi_lineto<label id="tgi_lineto"><p> <quote> <descrip> @@ -607,7 +607,7 @@ be used in presence of a prototype. </quote> -<sect>tgi_load_driver<label id="tgi_load_driver"><p> +<sect1>tgi_load_driver<label id="tgi_load_driver"><p> <quote> <descrip> @@ -628,7 +628,7 @@ be used in presence of a prototype. </quote> -<sect>tgi_load_vectorfont<label id="tgi_load_vectorfont"><p> +<sect1>tgi_load_vectorfont<label id="tgi_load_vectorfont"><p> <quote> <descrip> @@ -652,7 +652,7 @@ be used in presence of a prototype. </quote> -<sect>tgi_outtext<label id="tgi_outtext"><p> +<sect1>tgi_outtext<label id="tgi_outtext"><p> <quote> <descrip> @@ -673,7 +673,7 @@ be used in presence of a prototype. </quote> -<sect>tgi_outtextxy<label id="tgi_outtextxy"><p> +<sect1>tgi_outtextxy<label id="tgi_outtextxy"><p> <quote> <descrip> @@ -694,7 +694,7 @@ be used in presence of a prototype. </quote> -<sect>tgi_pieslice<label id="tgi_pieslice"><p> +<sect1>tgi_pieslice<label id="tgi_pieslice"><p> <quote> <descrip> @@ -728,7 +728,7 @@ tgi_pieslice (50, 50, 40, 20, 0, 180); </quote> -<sect>tgi_setaspectratio<label id="tgi_setaspectratio"><p> +<sect1>tgi_setaspectratio<label id="tgi_setaspectratio"><p> <quote> <descrip> <tag/Function/Set the pixel aspect ratio. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ @@ -760,7 +760,7 @@ only in the presence of a prototype. </quote> -<sect>tgi_setcolor<label id="tgi_setcolor"><p> +<sect1>tgi_setcolor<label id="tgi_setcolor"><p> <quote> <descrip> @@ -783,7 +783,8 @@ tgi_bar(10,10,20,20); </descrip> </quote> -<sect>tgi_setdrawpage<label id="tgi_setdrawpage"><p> + +<sect1>tgi_setdrawpage<label id="tgi_setdrawpage"><p> <quote> <descrip> @@ -812,7 +813,8 @@ tgi_setviewpage(0); // Show page 0 </descrip> </quote> -<sect>tgi_setpalette<label id="tgi_setpalette"><p> + +<sect1>tgi_setpalette<label id="tgi_setpalette"><p> <quote> <descrip> @@ -832,7 +834,8 @@ be used in presence of a prototype. </descrip> </quote> -<sect>tgi_setpixel<label id="tgi_setpixel"><p> + +<sect1>tgi_setpixel<label id="tgi_setpixel"><p> <quote> <descrip> @@ -850,7 +853,8 @@ be used in presence of a prototype. </descrip> </quote> -<sect>tgi_setviewpage<label id="tgi_setviewpage"><p> + +<sect1>tgi_setviewpage<label id="tgi_setviewpage"><p> <quote> <descrip> @@ -879,7 +883,8 @@ tgi_setviewpage(0); // Show page 0 </descrip> </quote> -<sect>tgi_gettextheight<label id="tgi_gettextheight"><p> + +<sect1>tgi_gettextheight<label id="tgi_gettextheight"><p> <quote> <descrip> @@ -899,7 +904,8 @@ be used in presence of a prototype. </descrip> </quote> -<sect>tgi_settextscale<label id="tgi_settextscale"><p> + +<sect1>tgi_settextscale<label id="tgi_settextscale"><p> <quote> <descrip> @@ -920,7 +926,8 @@ be used in presence of a prototype. </descrip> </quote> -<sect>tgi_settextstyle<label id="tgi_settextstyle"><p> + +<sect1>tgi_settextstyle<label id="tgi_settextstyle"><p> <quote> <descrip> @@ -939,7 +946,8 @@ be used in presence of a prototype. </descrip> </quote> -<sect>tgi_gettextwidth<label id="tgi_gettextwidth"><p> + +<sect1>tgi_gettextwidth<label id="tgi_gettextwidth"><p> <quote> <descrip> @@ -957,7 +965,8 @@ be used in presence of a prototype. </descrip> </quote> -<sect>tgi_uninstall<label id="tgi_uninstall"><p> + +<sect1>tgi_uninstall<label id="tgi_uninstall"><p> <quote> <descrip> @@ -973,7 +982,8 @@ Will call tgi_done if necessary. </descrip> </quote> -<sect>tgi_unload<label id="tgi_unload"><p> + +<sect1>tgi_unload<label id="tgi_unload"><p> <quote> <descrip> From ad9b7c0bfa4e80b4fe2f634720bcffd00225d103 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 30 Nov 2017 11:56:38 -0500 Subject: [PATCH 0506/2161] Fixed the sort order of the function descriptions in the TGI document. --- doc/tgi.sgml | 114 +++++++++++++++++++++++++-------------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/doc/tgi.sgml b/doc/tgi.sgml index fc60653a3..cf90fd198 100644 --- a/doc/tgi.sgml +++ b/doc/tgi.sgml @@ -5,7 +5,7 @@ <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:greg.king5@verizon.net" name="Greg King"> -<date>2017-11-26 +<date>2017-11-30 <abstract> The cc65 library provides functions for platform independent graphics. @@ -403,6 +403,46 @@ be used in presence of a prototype. </quote> +<sect1>tgi_gettextheight<label id="tgi_gettextheight"><p> + +<quote> +<descrip> +<tag/Function/Calculate the height of the text in pixels according to +the current text style. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/unsigned __fastcall__ tgi_gettextheight (const char* s);/ +<tag/Description/Calculate the height of the text in pixels according to +the current text style. +<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/Example/None. +</descrip> +</quote> + + +<sect1>tgi_gettextwidth<label id="tgi_gettextwidth"><p> + +<quote> +<descrip> +<tag/Function/Calculate the width of the text in pixels according to the current text style. +<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ +<tag/Declaration/<tt/unsigned __fastcall__ tgi_gettextwidth (const char* s);/ +<tag/Description/Calculate the width of the text in pixels according to the current text style. +<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/Example/None. +</descrip> +</quote> + + <sect1>tgi_getxres<label id="tgi_getxres"><p> <quote> @@ -854,57 +894,6 @@ be used in presence of a prototype. </quote> -<sect1>tgi_setviewpage<label id="tgi_setviewpage"><p> - -<quote> -<descrip> -<tag/Function/Set page to be visible on screen. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_setviewpage (unsigned char page);/ -<tag/Description/If the drawpage and the viewpage are the same then all drawing -is seen immediately as it is drawn. For double buffered games you can set the -drawpage to a different page than the viewpage. This lets you draw the next -screen in the background and when the screen is ready you display it. -<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/Example/<verb> -tgi_setdrawpage(1); -tgi_outtextxy(10, 10, "Hello World"); -tgi_setviewpage(1); // Show page 1 -tgi_setdrawpage(0); -tgi_outtextxy(10, 10, "Creating next frame"); -... -tgi_setviewpage(0); // Show page 0 -</verb> -</descrip> -</quote> - - -<sect1>tgi_gettextheight<label id="tgi_gettextheight"><p> - -<quote> -<descrip> -<tag/Function/Calculate the height of the text in pixels according to -the current text style. -<tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/unsigned __fastcall__ tgi_gettextheight (const char* s);/ -<tag/Description/Calculate the height of the text in pixels according to -the current text style. -<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/Example/None. -</descrip> -</quote> - - <sect1>tgi_settextscale<label id="tgi_settextscale"><p> <quote> @@ -947,21 +936,32 @@ be used in presence of a prototype. </quote> -<sect1>tgi_gettextwidth<label id="tgi_gettextwidth"><p> +<sect1>tgi_setviewpage<label id="tgi_setviewpage"><p> <quote> <descrip> -<tag/Function/Calculate the width of the text in pixels according to the current text style. +<tag/Function/Set page to be visible on screen. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/unsigned __fastcall__ tgi_gettextwidth (const char* s);/ -<tag/Description/Calculate the width of the text in pixels according to the current text style. +<tag/Declaration/<tt/void __fastcall__ tgi_setviewpage (unsigned char page);/ +<tag/Description/If the drawpage and the viewpage are the same then all drawing +is seen immediately as it is drawn. For double buffered games you can set the +drawpage to a different page than the viewpage. This lets you draw the next +screen in the background and when the screen is ready you display it. <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/Example/None. +<tag/Example/<verb> +tgi_setdrawpage(1); +tgi_outtextxy(10, 10, "Hello World"); +tgi_setviewpage(1); // Show page 1 +tgi_setdrawpage(0); +tgi_outtextxy(10, 10, "Creating next frame"); +... +tgi_setviewpage(0); // Show page 0 +</verb> </descrip> </quote> From e485e96de09b3913465af5e942488e202327c7ad Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 30 Nov 2017 19:17:45 +0100 Subject: [PATCH 0507/2161] Suppress potential svnversion error output. --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 5d45180a0..524651428 100644 --- a/src/Makefile +++ b/src/Makefile @@ -55,7 +55,7 @@ endif ifdef GIT_SHA $(info GIT_SHA: $(GIT_SHA)) else - GIT_SHA := $(shell git rev-parse --short HEAD 2>$(NULLDEV) || svnversion) + GIT_SHA := $(shell git rev-parse --short HEAD 2>$(NULLDEV) || svnversion 2>$(NULLDEV)) ifneq ($(words $(GIT_SHA)),1) GIT_SHA := N/A $(info GIT_SHA: N/A) From 563185998fd071e48682d1abb8f2a7925505ba76 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 2 Dec 2017 11:04:59 +0100 Subject: [PATCH 0508/2161] Removed CBM chartype table. --- libsrc/osic1p/ctype.s | 418 +++++++++++++++--------------------------- 1 file changed, 144 insertions(+), 274 deletions(-) diff --git a/libsrc/osic1p/ctype.s b/libsrc/osic1p/ctype.s index fa901c189..35968f982 100644 --- a/libsrc/osic1p/ctype.s +++ b/libsrc/osic1p/ctype.s @@ -1,289 +1,159 @@ ; +; Ullrich von Bassewitz, 2003-10-10 +; ; Character specification table. ; -; Ullrich von Bassewitz, 02.06.1998 -; 2003-05-02, Greg King -; -; Copied from cbm/ctype.s -; The following 256-byte-wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it + .include "ctype.inc" + +; The tables are readonly, put them into the rodata segment + +.rodata + +; The following 256 byte wide table specifies attributes for the isxxx type +; of functions. Doing it by a table means some overhead in space, but it ; has major advantages: ; -; * It is fast. If it weren't for the slow parameter-passing of cc65, -; one even could define C-language macroes for the isxxx functions -; (as it usually is done, on other platforms). +; * It is fast. If it weren't for the slow parameter passing of cc65, one +; could even define macros for the isxxx functions (this is usually +; done on other platforms). ; -; * It is highly portable. The only unportable part is the table itself; +; * It is highly portable. The only unportable part is the table itself, ; all real code goes into the common library. ; ; * We save some code in the isxxx functions. -; This table is taken from Craig S. Bruce's technical docs. for the ACE OS. - - .include "ctype.inc" - -; The table is read-only, put it into the RODATA segment. - - .rodata __ctype: - .byte CT_CTRL ; 0/00 ___rvs_@___ - .byte CT_CTRL ; 1/01 ___rvs_a___ - .byte CT_CTRL ; 2/02 ___rvs_b___ - .byte CT_CTRL ; 3/03 ___rvs_c___ - .byte CT_CTRL ; 4/04 ___rvs_d___ - .byte CT_CTRL ; 5/05 ___rvs_e___ - .byte CT_CTRL ; 6/06 ___rvs_f___ - .byte CT_CTRL ; 7/07 _BEL/rvs_g_ - .byte CT_CTRL ; 8/08 ___rvs_h___ - .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB ; 9/09 _TAB/rvs_i_ - .byte CT_CTRL | CT_OTHER_WS ; 10/0a _BOL/rvs_j_ - .byte CT_CTRL ; 11/0b ___rvs_k___ - .byte CT_CTRL ; 12/0c ___rvs_l___ - .byte CT_CTRL | CT_OTHER_WS ; 13/0d _CR_/rvs_m_ - .byte CT_CTRL ; 14/0e ___rvs_n___ - .byte CT_CTRL ; 15/0f ___rvs_o___ - .byte CT_CTRL ; 16/10 ___rvs_p___ - .byte CT_CTRL | CT_OTHER_WS ; 17/11 _VT_/rvs_q_ - .byte CT_CTRL ; 18/12 ___rvs_r___ - .byte CT_CTRL | CT_OTHER_WS ; 19/13 HOME/rvs_s_ - .byte CT_CTRL | CT_OTHER_WS ; 20/14 _BS_/rvs_t_ - .byte CT_CTRL ; 21/15 ___rvs_u___ - .byte CT_CTRL ; 22/16 ___rvs_v___ - .byte CT_CTRL ; 23/17 ___rvs_w___ - .byte CT_CTRL ; 24/18 ___rvs_x___ - .byte CT_CTRL ; 25/19 ___rvs_y___ - .byte CT_CTRL ; 26/1a ___rvs_z___ - .byte CT_CTRL ; 27/1b ___rvs_[___ - .byte CT_CTRL ; 28/1c ___rvs_\___ - .byte CT_CTRL | CT_OTHER_WS ; 29/1d cursr-right - .byte CT_CTRL ; 30/1e ___rvs_^___ - .byte CT_CTRL ; 31/1f _rvs_under_ - .byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___ - .byte $00 ; 33/21 _____!_____ - .byte $00 ; 34/22 _____"_____ - .byte $00 ; 35/23 _____#_____ - .byte $00 ; 36/24 _____$_____ - .byte $00 ; 37/25 _____%_____ - .byte $00 ; 38/26 _____&_____ - .byte $00 ; 39/27 _____'_____ - .byte $00 ; 40/28 _____(_____ - .byte $00 ; 41/29 _____)_____ - .byte $00 ; 42/2a _____*_____ - .byte $00 ; 43/2b _____+_____ - .byte $00 ; 44/2c _____,_____ - .byte $00 ; 45/2d _____-_____ - .byte $00 ; 46/2e _____._____ - .byte $00 ; 47/2f _____/_____ - .byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____ - .byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____ - .byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____ - .byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____ - .byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____ - .byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____ - .byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____ - .byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____ - .byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____ - .byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____ - .byte $00 ; 58/3a _____:_____ - .byte $00 ; 59/3b _____;_____ - .byte $00 ; 60/3c _____<_____ - .byte $00 ; 61/3d _____=_____ - .byte $00 ; 62/3e _____>_____ - .byte $00 ; 63/3f _____?_____ + .byte CT_CTRL ; 0/00 ___ctrl_@___ + .byte CT_CTRL ; 1/01 ___ctrl_A___ + .byte CT_CTRL ; 2/02 ___ctrl_B___ + .byte CT_CTRL ; 3/03 ___ctrl_C___ + .byte CT_CTRL ; 4/04 ___ctrl_D___ + .byte CT_CTRL ; 5/05 ___ctrl_E___ + .byte CT_CTRL ; 6/06 ___ctrl_F___ + .byte CT_CTRL ; 7/07 ___ctrl_G___ + .byte CT_CTRL ; 8/08 ___ctrl_H___ + .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB + ; 9/09 ___ctrl_I___ + .byte CT_CTRL | CT_OTHER_WS ; 10/0a ___ctrl_J___ + .byte CT_CTRL | CT_OTHER_WS ; 11/0b ___ctrl_K___ + .byte CT_CTRL | CT_OTHER_WS ; 12/0c ___ctrl_L___ + .byte CT_CTRL | CT_OTHER_WS ; 13/0d ___ctrl_M___ + .byte CT_CTRL ; 14/0e ___ctrl_N___ + .byte CT_CTRL ; 15/0f ___ctrl_O___ + .byte CT_CTRL ; 16/10 ___ctrl_P___ + .byte CT_CTRL ; 17/11 ___ctrl_Q___ + .byte CT_CTRL ; 18/12 ___ctrl_R___ + .byte CT_CTRL ; 19/13 ___ctrl_S___ + .byte CT_CTRL ; 20/14 ___ctrl_T___ + .byte CT_CTRL ; 21/15 ___ctrl_U___ + .byte CT_CTRL ; 22/16 ___ctrl_V___ + .byte CT_CTRL ; 23/17 ___ctrl_W___ + .byte CT_CTRL ; 24/18 ___ctrl_X___ + .byte CT_CTRL ; 25/19 ___ctrl_Y___ + .byte CT_CTRL ; 26/1a ___ctrl_Z___ + .byte CT_CTRL ; 27/1b ___ctrl_[___ + .byte CT_CTRL ; 28/1c ___ctrl_\___ + .byte CT_CTRL ; 29/1d ___ctrl_]___ + .byte CT_CTRL ; 30/1e ___ctrl_^___ + .byte CT_CTRL ; 31/1f ___ctrl_____ + .byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___ + .byte CT_NONE ; 33/21 _____!_____ + .byte CT_NONE ; 34/22 _____"_____ + .byte CT_NONE ; 35/23 _____#_____ + .byte CT_NONE ; 36/24 _____$_____ + .byte CT_NONE ; 37/25 _____%_____ + .byte CT_NONE ; 38/26 _____&_____ + .byte CT_NONE ; 39/27 _____'_____ + .byte CT_NONE ; 40/28 _____(_____ + .byte CT_NONE ; 41/29 _____)_____ + .byte CT_NONE ; 42/2a _____*_____ + .byte CT_NONE ; 43/2b _____+_____ + .byte CT_NONE ; 44/2c _____,_____ + .byte CT_NONE ; 45/2d _____-_____ + .byte CT_NONE ; 46/2e _____._____ + .byte CT_NONE ; 47/2f _____/_____ + .byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____ + .byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____ + .byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____ + .byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____ + .byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____ + .byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____ + .byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____ + .byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____ + .byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____ + .byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____ + .byte CT_NONE ; 58/3a _____:_____ + .byte CT_NONE ; 59/3b _____;_____ + .byte CT_NONE ; 60/3c _____<_____ + .byte CT_NONE ; 61/3d _____=_____ + .byte CT_NONE ; 62/3e _____>_____ + .byte CT_NONE ; 63/3f _____?_____ - .byte $00 ; 64/40 _____@_____ - .byte CT_LOWER | CT_XDIGIT ; 65/41 _____a_____ - .byte CT_LOWER | CT_XDIGIT ; 66/42 _____b_____ - .byte CT_LOWER | CT_XDIGIT ; 67/43 _____c_____ - .byte CT_LOWER | CT_XDIGIT ; 68/44 _____d_____ - .byte CT_LOWER | CT_XDIGIT ; 69/45 _____e_____ - .byte CT_LOWER | CT_XDIGIT ; 70/46 _____f_____ - .byte CT_LOWER ; 71/47 _____g_____ - .byte CT_LOWER ; 72/48 _____h_____ - .byte CT_LOWER ; 73/49 _____i_____ - .byte CT_LOWER ; 74/4a _____j_____ - .byte CT_LOWER ; 75/4b _____k_____ - .byte CT_LOWER ; 76/4c _____l_____ - .byte CT_LOWER ; 77/4d _____m_____ - .byte CT_LOWER ; 78/4e _____n_____ - .byte CT_LOWER ; 79/4f _____o_____ - .byte CT_LOWER ; 80/50 _____p_____ - .byte CT_LOWER ; 81/51 _____q_____ - .byte CT_LOWER ; 82/52 _____r_____ - .byte CT_LOWER ; 83/53 _____s_____ - .byte CT_LOWER ; 84/54 _____t_____ - .byte CT_LOWER ; 85/55 _____u_____ - .byte CT_LOWER ; 86/56 _____v_____ - .byte CT_LOWER ; 87/57 _____w_____ - .byte CT_LOWER ; 88/58 _____x_____ - .byte CT_LOWER ; 89/59 _____y_____ - .byte CT_LOWER ; 90/5a _____z_____ - .byte $00 ; 91/5b _____[_____ - .byte $00 ; 92/5c _____\_____ - .byte $00 ; 93/5d _____]_____ - .byte $00 ; 94/5e _____^_____ - .byte $00 ; 95/5f _UNDERLINE_ - .byte $00 ; 96/60 _A`_grave__ - .byte $00 ; 97/61 _A'_acute__ - .byte $00 ; 98/62 _A^_circum_ - .byte $00 ; 99/63 _A~_tilde__ - .byte $00 ; 100/64 _A"_dieres_ - .byte $00 ; 101/65 _A__ring___ - .byte $00 ; 102/66 _AE________ - .byte $00 ; 103/67 _C,cedilla_ - .byte $00 ; 104/68 _E`_grave__ - .byte $00 ; 105/69 _E'_acute__ - .byte $00 ; 106/6a _E^_circum_ - .byte $00 ; 107/6b _E"_dieres_ - .byte $00 ; 108/6c _I`_grave__ - .byte $00 ; 109/6d _I'_acute__ - .byte $00 ; 110/6e _I^_circum_ - .byte $00 ; 111/6f _I"_dieres_ - .byte $00 ; 112/70 _D-_Eth_lr_ - .byte $00 ; 113/71 _N~_tilde__ - .byte $00 ; 114/72 _O`_grave__ - .byte $00 ; 115/73 _O'_acute__ - .byte $00 ; 116/74 _O^_circum_ - .byte $00 ; 117/75 _O~_tilde__ - .byte $00 ; 118/76 _O"_dieres_ - .byte $00 ; 119/77 __multiply_ - .byte $00 ; 120/78 _O/_slash__ - .byte $00 ; 121/79 _U`_grave__ - .byte $00 ; 122/7a _U'_acute__ - .byte $00 ; 123/7b _U^_circum_ - .byte $00 ; 124/7c _U"_dieres_ - .byte $00 ; 125/7d _Y'_acute__ - .byte $00 ; 126/7e _cap_thorn_ - .byte $00 ; 127/7f _Es-sed_B__ + .byte CT_NONE ; 64/40 _____@_____ + .byte CT_UPPER | CT_XDIGIT ; 65/41 _____A_____ + .byte CT_UPPER | CT_XDIGIT ; 66/42 _____B_____ + .byte CT_UPPER | CT_XDIGIT ; 67/43 _____C_____ + .byte CT_UPPER | CT_XDIGIT ; 68/44 _____D_____ + .byte CT_UPPER | CT_XDIGIT ; 69/45 _____E_____ + .byte CT_UPPER | CT_XDIGIT ; 70/46 _____F_____ + .byte CT_UPPER ; 71/47 _____G_____ + .byte CT_UPPER ; 72/48 _____H_____ + .byte CT_UPPER ; 73/49 _____I_____ + .byte CT_UPPER ; 74/4a _____J_____ + .byte CT_UPPER ; 75/4b _____K_____ + .byte CT_UPPER ; 76/4c _____L_____ + .byte CT_UPPER ; 77/4d _____M_____ + .byte CT_UPPER ; 78/4e _____N_____ + .byte CT_UPPER ; 79/4f _____O_____ + .byte CT_UPPER ; 80/50 _____P_____ + .byte CT_UPPER ; 81/51 _____Q_____ + .byte CT_UPPER ; 82/52 _____R_____ + .byte CT_UPPER ; 83/53 _____S_____ + .byte CT_UPPER ; 84/54 _____T_____ + .byte CT_UPPER ; 85/55 _____U_____ + .byte CT_UPPER ; 86/56 _____V_____ + .byte CT_UPPER ; 87/57 _____W_____ + .byte CT_UPPER ; 88/58 _____X_____ + .byte CT_UPPER ; 89/59 _____Y_____ + .byte CT_UPPER ; 90/5a _____Z_____ + .byte CT_NONE ; 91/5b _____[_____ + .byte CT_NONE ; 92/5c _____\_____ + .byte CT_NONE ; 93/5d _____]_____ + .byte CT_NONE ; 94/5e _____^_____ + .byte CT_NONE ; 95/5f _UNDERLINE_ + .byte CT_NONE ; 96/60 ___grave___ + .byte CT_LOWER | CT_XDIGIT ; 97/61 _____a_____ + .byte CT_LOWER | CT_XDIGIT ; 98/62 _____b_____ + .byte CT_LOWER | CT_XDIGIT ; 99/63 _____c_____ + .byte CT_LOWER | CT_XDIGIT ; 100/64 _____d_____ + .byte CT_LOWER | CT_XDIGIT ; 101/65 _____e_____ + .byte CT_LOWER | CT_XDIGIT ; 102/66 _____f_____ + .byte CT_LOWER ; 103/67 _____g_____ + .byte CT_LOWER ; 104/68 _____h_____ + .byte CT_LOWER ; 105/69 _____i_____ + .byte CT_LOWER ; 106/6a _____j_____ + .byte CT_LOWER ; 107/6b _____k_____ + .byte CT_LOWER ; 108/6c _____l_____ + .byte CT_LOWER ; 109/6d _____m_____ + .byte CT_LOWER ; 110/6e _____n_____ + .byte CT_LOWER ; 111/6f _____o_____ + .byte CT_LOWER ; 112/70 _____p_____ + .byte CT_LOWER ; 113/71 _____q_____ + .byte CT_LOWER ; 114/72 _____r_____ + .byte CT_LOWER ; 115/73 _____s_____ + .byte CT_LOWER ; 116/74 _____t_____ + .byte CT_LOWER ; 117/75 _____u_____ + .byte CT_LOWER ; 118/76 _____v_____ + .byte CT_LOWER ; 119/77 _____w_____ + .byte CT_LOWER ; 120/78 _____x_____ + .byte CT_LOWER ; 121/79 _____y_____ + .byte CT_LOWER ; 122/7a _____z_____ + .byte CT_NONE ; 123/7b _____{_____ + .byte CT_NONE ; 124/7c _____|_____ + .byte CT_NONE ; 125/7d _____}_____ + .byte CT_NONE ; 126/7e _____~_____ + .byte CT_OTHER_WS ; 127/7f ____DEL____ - .byte CT_CTRL ; 128/80 __bullet___ - .byte CT_CTRL ; 129/81 __v_line___ - .byte CT_CTRL ; 130/82 __h_line___ - .byte CT_CTRL ; 131/83 ___cross___ - .byte CT_CTRL ; 132/84 _tl_corner_ - .byte CT_CTRL ; 133/85 _tr_corner_ - .byte CT_CTRL ; 134/86 _bl_corner_ - .byte CT_CTRL ; 135/87 _br_corner_ - .byte CT_CTRL ; 136/88 ___l_tee___ - .byte CT_CTRL ; 137/89 ___r_tee___ - .byte CT_CTRL ; 138/8a ___t_tee___ - .byte CT_CTRL ; 139/8b ___b_tee___ - .byte CT_CTRL ; 140/8c ___heart___ - .byte CT_CTRL | CT_OTHER_WS ; 141/8d _CR/diamond - .byte CT_CTRL ; 142/8e ___club____ - .byte CT_CTRL ; 143/8f ___spade___ - .byte CT_CTRL ; 144/90 _s_circle__ - .byte CT_CTRL | CT_OTHER_WS ; 145/91 _cursor-up_ - .byte CT_CTRL ; 146/92 ___pound___ - .byte CT_CTRL | CT_OTHER_WS ; 147/93 _CLS/check_ - .byte CT_CTRL | CT_OTHER_WS ; 148/94 __INSert___ - .byte CT_CTRL ; 149/95 ____+/-____ - .byte CT_CTRL ; 150/96 __divide___ - .byte CT_CTRL ; 151/97 __degree___ - .byte CT_CTRL ; 152/98 _c_checker_ - .byte CT_CTRL ; 153/99 _f_checker_ - .byte CT_CTRL ; 154/9a _solid_sq__ - .byte CT_CTRL ; 155/9b __cr_char__ - .byte CT_CTRL ; 156/9c _up_arrow__ - .byte CT_CTRL | CT_OTHER_WS ; 157/9d cursor-left - .byte CT_CTRL ; 158/9e _left_arro_ - .byte CT_CTRL ; 159/9f _right_arr_ - .byte CT_SPACE | CT_SPACE_TAB ; 160/a0 _req space_ - .byte $00 ; 161/a1 _!_invertd_ - .byte $00 ; 162/a2 ___cent____ - .byte $00 ; 163/a3 ___pound___ - .byte $00 ; 164/a4 __currency_ - .byte $00 ; 165/a5 ____yen____ - .byte $00 ; 166/a6 _|_broken__ - .byte $00 ; 167/a7 __section__ - .byte $00 ; 168/a8 __umulaut__ - .byte $00 ; 169/a9 _copyright_ - .byte $00 ; 170/aa __fem_ord__ - .byte $00 ; 171/ab _l_ang_quo_ - .byte $00 ; 172/ac ____not____ - .byte $00 ; 173/ad _syl_hyphn_ - .byte $00 ; 174/ae _registerd_ - .byte $00 ; 175/af _overline__ - .byte $00 ; 176/b0 __degrees__ - .byte $00 ; 177/b1 ____+/-____ - .byte $00 ; 178/b2 _2_supersc_ - .byte $00 ; 179/b3 _3_supersc_ - .byte $00 ; 180/b4 ___acute___ - .byte $00 ; 181/b5 ____mu_____ - .byte $00 ; 182/b6 _paragraph_ - .byte $00 ; 183/b7 __mid_dot__ - .byte $00 ; 184/b8 __cedilla__ - .byte $00 ; 185/b9 _1_supersc_ - .byte $00 ; 186/ba __mas_ord__ - .byte $00 ; 187/bb _r_ang_quo_ - .byte $00 ; 188/bc ____1/4____ - .byte $00 ; 189/bd ____1/2____ - .byte $00 ; 190/be ____3/4____ - .byte $00 ; 191/bf _?_invertd_ - - .byte $00 ; 192/c0 _____`_____ - .byte CT_UPPER | CT_XDIGIT ; 193/c1 _____A_____ - .byte CT_UPPER | CT_XDIGIT ; 194/c2 _____B_____ - .byte CT_UPPER | CT_XDIGIT ; 195/c3 _____C_____ - .byte CT_UPPER | CT_XDIGIT ; 196/c4 _____D_____ - .byte CT_UPPER | CT_XDIGIT ; 197/c5 _____E_____ - .byte CT_UPPER | CT_XDIGIT ; 198/c6 _____F_____ - .byte CT_UPPER ; 199/c7 _____G_____ - .byte CT_UPPER ; 200/c8 _____H_____ - .byte CT_UPPER ; 201/c9 _____I_____ - .byte CT_UPPER ; 202/ca _____J_____ - .byte CT_UPPER ; 203/cb _____K_____ - .byte CT_UPPER ; 204/cc _____L_____ - .byte CT_UPPER ; 205/cd _____M_____ - .byte CT_UPPER ; 206/ce _____N_____ - .byte CT_UPPER ; 207/cf _____O_____ - .byte CT_UPPER ; 208/d0 _____P_____ - .byte CT_UPPER ; 209/d1 _____Q_____ - .byte CT_UPPER ; 210/d2 _____R_____ - .byte CT_UPPER ; 211/d3 _____S_____ - .byte CT_UPPER ; 212/d4 _____T_____ - .byte CT_UPPER ; 213/d5 _____U_____ - .byte CT_UPPER ; 214/d6 _____V_____ - .byte CT_UPPER ; 215/d7 _____W_____ - .byte CT_UPPER ; 216/d8 _____X_____ - .byte CT_UPPER ; 217/d9 _____Y_____ - .byte CT_UPPER ; 218/da _____Z_____ - .byte $00 ; 219/db _____{_____ - .byte $00 ; 220/dc _____|_____ - .byte $00 ; 221/dd _____}_____ - .byte $00 ; 222/de _____~_____ - .byte $00 ; 223/df ___HOUSE___ - .byte $00 ; 224/e0 _a`_grave__ - .byte $00 ; 225/e1 _a'_acute__ - .byte $00 ; 226/e2 _a^_circum_ - .byte $00 ; 227/e3 _a~_tilde__ - .byte $00 ; 228/e4 _a"_dieres_ - .byte $00 ; 229/e5 _a__ring___ - .byte $00 ; 230/e6 _ae________ - .byte $00 ; 231/e7 _c,cedilla_ - .byte $00 ; 232/e8 _e`_grave__ - .byte $00 ; 233/e9 _e'_acute__ - .byte $00 ; 234/ea _e^_circum_ - .byte $00 ; 235/eb _e"_dieres_ - .byte $00 ; 236/ec _i`_grave__ - .byte $00 ; 237/ed _i'_acute__ - .byte $00 ; 238/ee _i^_circum_ - .byte $00 ; 239/ef _i"_dieres_ - .byte $00 ; 240/f0 _o^x_Eth_s_ - .byte $00 ; 241/f1 _n~_tilda__ - .byte $00 ; 242/f2 _o`_grave__ - .byte $00 ; 243/f3 _o'_acute__ - .byte $00 ; 244/f4 _o^_circum_ - .byte $00 ; 245/f5 _o~_tilde__ - .byte $00 ; 246/f6 _o"_dieres_ - .byte $00 ; 247/f7 __divide___ - .byte $00 ; 248/f8 _o/_slash__ - .byte $00 ; 249/f9 _u`_grave__ - .byte $00 ; 250/fa _u'_acute__ - .byte $00 ; 251/fb _u^_circum_ - .byte $00 ; 252/fc _u"_dieres_ - .byte $00 ; 253/fd _y'_acute__ - .byte $00 ; 254/fe _sm_thorn__ - .byte $00 ; 255/ff _y"_dieres_ + .res 128, CT_NONE ; 128-255 From 947b09ad96902cc2a4d775660c77fd496a3bedbd Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 7 Dec 2017 20:39:28 +0100 Subject: [PATCH 0509/2161] Removed OPC_EOR_abx duplicate. --- asminc/opcodes.inc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/asminc/opcodes.inc b/asminc/opcodes.inc index 96cdefb65..aa7a65f00 100644 --- a/asminc/opcodes.inc +++ b/asminc/opcodes.inc @@ -241,12 +241,11 @@ OPC_BIT_abx = $3C ; OPC_NOP = $44 ; doublet ; OPC_NOP = $4B ; doublet -OPC_EOR_izp = $52 +OPC_EOR_izp = $52 ; OPC_NOP = $53 ; doublet ; OPC_NOP = $54 ; doublet ; OPC_NOP = $5A ; doublet ; OPC_NOP = $5B ; doublet -OPC_EOR_abx = $5C ; OPC_NOP = $62 ; doublet ; OPC_NOP = $63 ; doublet From 8902730756f7dc6037cea35ea08c7511eb89cb4b Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 11 Dec 2017 19:49:14 +0100 Subject: [PATCH 0510/2161] cbm stuff from greggs pull request --- asminc/c128.inc | 12 ++- doc/funcref.sgml | 121 +++++++++++++++++++++++- include/cbm610.h | 4 +- include/conio.h | 20 ++++ include/pet.h | 1 + libsrc/c128/cpeekc.s | 65 +++++++++++++ libsrc/c128/cpeekcolor.s | 56 ++++++++++++ libsrc/c128/cpeekrevers.s | 51 +++++++++++ libsrc/c128/cpeeks.s | 15 +++ libsrc/cbm/cpeekc.s | 53 +++++++++++ libsrc/cbm/cpeekcolor.s | 28 ++++++ libsrc/cbm/cpeekrevers.s | 35 +++++++ libsrc/cbm/cpeeks.s | 93 +++++++++++++++++++ libsrc/cbm510/cpeekcolor.s | 24 +++++ libsrc/cbm510/doesclrscr.s | 16 ++++ libsrc/cbm610/cpeekc.s | 45 +++++++++ libsrc/cbm610/cpeekcolor.s | 8 ++ libsrc/cbm610/cpeekrevers.s | 29 ++++++ libsrc/cbm610/cpeeks.s | 82 +++++++++++++++++ libsrc/pet/cpeekcolor.s | 8 ++ testcode/lib/cpeek-test.c | 177 ++++++++++++++++++++++++++++++++++++ 21 files changed, 936 insertions(+), 7 deletions(-) create mode 100644 libsrc/c128/cpeekc.s create mode 100644 libsrc/c128/cpeekcolor.s create mode 100644 libsrc/c128/cpeekrevers.s create mode 100644 libsrc/c128/cpeeks.s create mode 100644 libsrc/cbm/cpeekc.s create mode 100644 libsrc/cbm/cpeekcolor.s create mode 100644 libsrc/cbm/cpeekrevers.s create mode 100644 libsrc/cbm/cpeeks.s create mode 100644 libsrc/cbm510/cpeekcolor.s create mode 100644 libsrc/cbm510/doesclrscr.s create mode 100644 libsrc/cbm610/cpeekc.s create mode 100644 libsrc/cbm610/cpeekcolor.s create mode 100644 libsrc/cbm610/cpeekrevers.s create mode 100644 libsrc/cbm610/cpeeks.s create mode 100644 libsrc/pet/cpeekcolor.s create mode 100644 testcode/lib/cpeek-test.c diff --git a/asminc/c128.inc b/asminc/c128.inc index 745a3ad6d..45ac3935b 100644 --- a/asminc/c128.inc +++ b/asminc/c128.inc @@ -15,7 +15,7 @@ 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 flag +MODE := $D7 ; 40-/80-column mode (bit 7: 80 columns) CURS_X := $EC ; Cursor column CURS_Y := $EB ; Cursor row SCREEN_PTR := $E0 ; Pointer to current char in text screen @@ -167,8 +167,14 @@ SID_Read3 := $D41C ; --------------------------------------------------------------------------- ; I/O: VDC (128 only) -VDC_INDEX := $D600 -VDC_DATA := $D601 +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 diff --git a/doc/funcref.sgml b/doc/funcref.sgml index d997e0a8f..b198adcf8 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -4,7 +4,7 @@ <title>cc65 function reference <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2017-11-21 +<date>2017-12-09 <abstract> cc65 is a C compiler for 6502 based systems. This function reference describes @@ -240,6 +240,10 @@ function. <item><ref id="chline" name="chline"> <item><ref id="chlinexy" name="chlinexy"> <item><ref id="clrscr" name="clrscr"> +<item><ref id="cpeekc" name="cpeekc"> +<item><ref id="cpeekcolor" name="cpeekcolor"> +<item><ref id="cpeekrevers" name="cpeekrevers"> +<item><ref id="cpeeks" name="cpeeks"> <item><ref id="cprintf" name="cprintf"> <item><ref id="cputc" name="cputc"> <item><ref id="cputcxy" name="cputcxy"> @@ -2363,6 +2367,121 @@ be used in presence of a prototype. </quote> +<sect1>cpeekc<label id="cpeekc"><p> + +<quote> +<descrip> +<tag/Function/Get a character from the display memory. +<tag/Header/<tt/<ref id="conio.h" name="conio.h">/ +<tag/Declaration/<tt/char cpeekc (void);/ +<tag/Description/The function gets the character that's at the current location +of the cursor in the display screen RAM. That character is converted, if +needed, into the encoding that can be passed to <tt/cputc()/. +<tag/Notes/<itemize> +<item>Conio peek functions don't have <tt/cpeek...xy()/ versions. That was +done to make it obvious that peeking doesn't move the cursor in any way. Your +program must place the cursor where it wants to peek before it calls any of +those functions. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="cpeekcolor" name="cpeekcolor">, +<ref id="cpeekrevers" name="cpeekrevers">, +<ref id="cpeeks" name="cpeeks">, +<ref id="cputc" name="cputc"> +<tag/Example/None. +</descrip> +</quote> + + +<sect1>cpeekcolor<label id="cpeekcolor"><p> + +<quote> +<descrip> +<tag/Function/Get a color from the display memory. +<tag/Header/<tt/<ref id="conio.h" name="conio.h">/ +<tag/Declaration/<tt/unsigned char cpeekcolor (void);/ +<tag/Description/The function gets the color number that's at the current +location of the cursor in the display screen RAM. That number can be passed to +<tt/textcolor()/. +<tag/Notes/<itemize> +<item>Conio peek functions don't have <tt/cpeek...xy()/ versions. That was +done to make it obvious that peeking doesn't move the cursor in any way. Your +program must place the cursor where it wants to peek before it calls any of +those functions. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="cpeekc" name="cpeekc">, +<ref id="cpeekrevers" name="cpeekrevers">, +<ref id="cpeeks" name="cpeeks">, +<ref id="cputc" name="cputc">, +<ref id="textcolor" name="textcolor"> +<tag/Example/None. +</descrip> +</quote> + + +<sect1>cpeekrevers<label id="cpeekrevers"><p> + +<quote> +<descrip> +<tag/Function/Get a reverse-character attribute from the display memory. +<tag/Header/<tt/<ref id="conio.h" name="conio.h">/ +<tag/Declaration/<tt/unsigned char cpeekrevers (void);/ +<tag/Description/The function gets the "reverse-mode" attribute of the +character that's at the current location of the cursor in the display screen +RAM. It returns a boolean value (0/1) that can be passed to <tt/revers()/. +<tag/Notes/<itemize> +<item>Conio peek functions don't have <tt/cpeek...xy()/ versions. That was +done to make it obvious that peeking doesn't move the cursor in any way. Your +program must place the cursor where it wants to peek before it calls any of +those functions. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="cpeekc" name="cpeekc">, +<ref id="cpeekcolor" name="cpeekcolor">, +<ref id="cpeeks" name="cpeeks">, +<ref id="cputc" name="cputc">, +<ref id="revers" name="revers"> +<tag/Example/None. +</descrip> +</quote> + + +<sect1>cpeeks<label id="cpeeks"><p> + +<quote> +<descrip> +<tag/Function/Get a string from the display memory. +<tag/Header/<tt/<ref id="conio.h" name="conio.h">/ +<tag/Declaration/<tt/void __fastcall__ cpeeks (char* s, unsigned length);/ +<tag/Description/The function gets a fixed-length string ('\0'-terminated) of +characters that start at the current location of the cursor in the display +screen RAM. Those characters are converted, if needed, into the encoding that +can be passed to <tt/cputs()/. The first argument must point to a RAM area +that's large enough to hold "length + 1" bytes. +<tag/Notes/<itemize> +<item>Conio peek functions don't have <tt/cpeek...xy()/ versions. That was +done to make it obvious that peeking doesn't move the cursor in any way. Your +program must place the cursor where it wants to peek before it calls any of +those functions. +<item>The function is available as only a fastcall function; +so, it may be used only in the presence of a prototype. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="cpeekc" name="cpeekc">, +<ref id="cpeekcolor" name="cpeekcolor">, +<ref id="cpeekrevers" name="cpeekrevers">, +<ref id="cputc" name="cputc">, +<ref id="cputs" name="cputs"> +<tag/Example/None. +</descrip> +</quote> + + <sect1>creat<label id="creat"><p> <quote> diff --git a/include/cbm610.h b/include/cbm610.h index 79d498431..b0486044b 100644 --- a/include/cbm610.h +++ b/include/cbm610.h @@ -144,11 +144,9 @@ void __fastcall__ pokewsys (unsigned addr, unsigned val); #define _textcolor(color) COLOR_WHITE #define _bgcolor(color) COLOR_BLACK #define _bordercolor(color) COLOR_BLACK +#define _cpeekcolor(color) COLOR_WHITE /* End of cbm610.h */ #endif - - - diff --git a/include/conio.h b/include/conio.h index baf55dd08..9cd505766 100644 --- a/include/conio.h +++ b/include/conio.h @@ -148,6 +148,23 @@ int cscanf (const char* format, ...); int __fastcall__ vcscanf (const char* format, va_list ap); /* Like vscanf(), but uses direct keyboard input */ +char cpeekc (void); +/* Return the character from the current cursor position */ + +unsigned char cpeekcolor (void); +/* Return the color from the current cursor position */ + +unsigned char cpeekrevers (void); +/* Return the reverse attribute from the current cursor position. +** If the character is reversed, then return 1; return 0 otherwise. +*/ + +void __fastcall__ cpeeks (char* s, unsigned int length); +/* Return a string of the characters that start at the current cursor position. +** Put the string into the buffer to which "s" points. The string will have +** "length" characters, then will be '\0'-terminated. +*/ + unsigned char __fastcall__ cursor (unsigned char onoff); /* If onoff is 1, a cursor is displayed when waiting for keyboard input. If ** onoff is 0, the cursor is hidden when waiting for keyboard input. The @@ -224,6 +241,9 @@ void __fastcall__ cputhex16 (unsigned val); #if defined(_bordercolor) # define bordercolor(x) _bordercolor(x) #endif +#if defined(_cpeekcolor) +# define cpeekcolor(x) _cpeekcolor(x) +#endif diff --git a/include/pet.h b/include/pet.h index e9659d524..249d8b608 100644 --- a/include/pet.h +++ b/include/pet.h @@ -105,6 +105,7 @@ extern void pet_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ #define _textcolor(color) COLOR_WHITE #define _bgcolor(color) COLOR_BLACK #define _bordercolor(color) COLOR_BLACK +#define _cpeekcolor(color) COLOR_WHITE diff --git a/libsrc/c128/cpeekc.s b/libsrc/c128/cpeekc.s new file mode 100644 index 000000000..ce6bb4ff5 --- /dev/null +++ b/libsrc/c128/cpeekc.s @@ -0,0 +1,65 @@ +; +; 2016-02-28, Groepaz +; 2017-06-26, Greg King +; +; char cpeekc (void); +; + + .export _cpeekc + + .import plot, popa + + .include "zeropage.inc" + .include "c128.inc" + + +_cpeekc: + lda MODE + bmi @c80 + + ldy CURS_X + lda (SCREEN_PTR),y ; get char + +@return: + and #<~$80 ; remove reverse flag + +; Convert the screen code into a PetSCII code. +; $00 - $1F: +$40 +; $20 - $3F +; $40 - $7F: +$80 + + cmp #$20 + bcs @sk1 ;(bge) + ora #$40 + rts + +@sk1: cmp #$40 + bcc @end ;(blt) + ora #$80 +@end: ldx #0 + rts + +@c80: + lda SCREEN_PTR + ldy SCREEN_PTR+1 + clc + adc CURS_X + bcc @s + iny + + ; get byte from VDC mem +@s: ldx #VDC_DATA_LO + stx VDC_INDEX +@L0: bit VDC_INDEX + bpl @L0 + sta VDC_DATA + dex + stx VDC_INDEX + sty VDC_DATA + + ldx #VDC_RAM_RW + stx VDC_INDEX +@L1: bit VDC_INDEX + bpl @L1 ; wait for blanking + lda VDC_DATA + jmp @return diff --git a/libsrc/c128/cpeekcolor.s b/libsrc/c128/cpeekcolor.s new file mode 100644 index 000000000..9a8c3bfdc --- /dev/null +++ b/libsrc/c128/cpeekcolor.s @@ -0,0 +1,56 @@ +; +; 2016-02-28, Groepaz +; 2017-06-26, Greg King +; +; unsigned char cpeekcolor (void); +; + + .export _cpeekcolor + + .include "c128.inc" + + +_cpeekcolor: + bit MODE + bmi @c80 + + ldy CURS_X + lda (CRAM_PTR),y ; get color + and #$0F + ldx #>$0000 + rts + +@c80: lda CRAM_PTR + ldy CRAM_PTR+1 + clc + adc CURS_X + bcc @s + iny + + ; get byte from VDC mem +@s: ldx #VDC_DATA_LO + stx VDC_INDEX +@L0: bit VDC_INDEX + bpl @L0 + sta VDC_DATA + dex + stx VDC_INDEX + sty VDC_DATA + + ldx #VDC_RAM_RW + stx VDC_INDEX +@L1: bit VDC_INDEX + bpl @L1 ; wait for blanking + lda VDC_DATA + and #$0F + +; translate VDC->VIC colour + +vdctovic: + ldy #$0F + 1 +@L2: dey + cmp $CE5C,y + bne @L2 + tya + ldx #>$0000 + rts diff --git a/libsrc/c128/cpeekrevers.s b/libsrc/c128/cpeekrevers.s new file mode 100644 index 000000000..c36e4ac44 --- /dev/null +++ b/libsrc/c128/cpeekrevers.s @@ -0,0 +1,51 @@ +; +; 2016-02-28, Groepaz +; 2017-06-26, Greg King +; +; unsigned char cpeekrevers (void); +; + + .export _cpeekrevers + + .include "zeropage.inc" + .include "c128.inc" + + +_cpeekrevers: + lda MODE + bmi @c80 + + ldy CURS_X + lda (SCREEN_PTR),y ; get char + +@return: + and #$80 ; get reverse flag + asl a + tax ; ldx #>$0000 + rol a ; return boolean value + rts + +@c80: + lda SCREEN_PTR + ldy SCREEN_PTR+1 + clc + adc CURS_X + bcc @s + iny + + ; get byte from VDC mem +@s: ldx #VDC_DATA_LO + stx VDC_INDEX +@L0: bit VDC_INDEX + bpl @L0 + sta VDC_DATA + dex + stx VDC_INDEX + sty VDC_DATA + + ldx #VDC_RAM_RW + stx VDC_INDEX +@L1: bit VDC_INDEX + bpl @L1 ; wait for blanking + lda VDC_DATA + jmp @return diff --git a/libsrc/c128/cpeeks.s b/libsrc/c128/cpeeks.s new file mode 100644 index 000000000..c9d806ef3 --- /dev/null +++ b/libsrc/c128/cpeeks.s @@ -0,0 +1,15 @@ +; +; 2017-11-23, Greg King +; +; void cpeeks (char* s, unsigned length); +; +; C128 can't use "cbm/cpeeks.s" because both 40 and 80 columns must be handled. +; Stub file, for now, so that its library can be built. + + .export _cpeeks + + .import popax + + +_cpeeks: + jmp popax ; pop s diff --git a/libsrc/cbm/cpeekc.s b/libsrc/cbm/cpeekc.s new file mode 100644 index 000000000..05c7fc718 --- /dev/null +++ b/libsrc/cbm/cpeekc.s @@ -0,0 +1,53 @@ +; +; 2016-02-28, Groepaz +; 2017-06-22, Greg King +; +; char cpeekc (void); +; + + .export _cpeekc + +; Get a system-specific file. +; Note: The cbm610, and c128 targets need special +; versions that handle RAM banking and the 80-column VDC. + +.if .def(__C16__) + .include "plus4.inc" ; both C16 and Plus4 +.elseif .def(__C64__) + .include "c64.inc" +.elseif .def(__CBM510__) + .import CURS_X: zp, SCREEN_PTR: zp + .include "cbm510.inc" +.elseif .def(__PET__) + .include "pet.inc" +.elseif .def(__VIC20__) + .include "vic20.inc" +.endif + + +_cpeekc: + ldy CURS_X + lda (SCREEN_PTR),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/cbm/cpeekcolor.s b/libsrc/cbm/cpeekcolor.s new file mode 100644 index 000000000..9c961b771 --- /dev/null +++ b/libsrc/cbm/cpeekcolor.s @@ -0,0 +1,28 @@ +; +; 2016-02-28, Groepaz +; 2017-06-22, Greg King +; +; unsigned char cpeekcolor (void); +; + + .export _cpeekcolor + +; Get a system-specific file. +; Note: The cbm510, cbm610, c128, and Pet targets need special +; versions that handle RAM banking, the 80-column VDC, and monochrome. + +.if .def(__C16__) + .include "plus4.inc" ; both C16 and Plus4 +.elseif .def(__C64__) + .include "c64.inc" +.elseif .def(__VIC20__) + .include "vic20.inc" +.endif + + +_cpeekcolor: + ldy CURS_X + lda (CRAM_PTR),y ; get color + and #$0F + ldx #>$0000 + rts diff --git a/libsrc/cbm/cpeekrevers.s b/libsrc/cbm/cpeekrevers.s new file mode 100644 index 000000000..e8e210167 --- /dev/null +++ b/libsrc/cbm/cpeekrevers.s @@ -0,0 +1,35 @@ +; +; 2016-02-28, Groepaz +; 2017-06-15, Greg King +; +; unsigned char cpeekrevers (void); +; + + .export _cpeekrevers + +; Get a system-specific file. +; Note: The cbm610, and c128 targets need special +; versions that handle RAM banking and the 80-column VDC. + +.if .def(__C16__) + .include "plus4.inc" ; both C16 and Plus4 +.elseif .def(__C64__) + .include "c64.inc" +.elseif .def(__CBM510__) + .import CURS_X: zp, SCREEN_PTR: zp + .include "cbm510.inc" +.elseif .def(__PET__) + .include "pet.inc" +.elseif .def(__VIC20__) + .include "vic20.inc" +.endif + + +_cpeekrevers: + ldy CURS_X + lda (SCREEN_PTR),y ; get screen code + and #$80 ; get reverse bit + asl a + tax ; ldx #>$0000 + rol a ; return boolean value + rts diff --git a/libsrc/cbm/cpeeks.s b/libsrc/cbm/cpeeks.s new file mode 100644 index 000000000..215998e37 --- /dev/null +++ b/libsrc/cbm/cpeeks.s @@ -0,0 +1,93 @@ +; +; 2017-07-05, Greg King +; +; void cpeeks (char* s, unsigned length); +; + + .export _cpeeks + + .import popax + .importzp ptr1, ptr2, ptr3, tmp1, tmp2 + + .macpack generic + +; Get a system-specific file. +; Note: The cbm610, and c128 targets need special +; versions that handle RAM banking and the 80-column VDC. + +.if .def(__C16__) + .include "plus4.inc" ; both C16 and Plus4 +.elseif .def(__C64__) + .include "c64.inc" +.elseif .def(__CBM510__) + .import CURS_X: zp, SCREEN_PTR: zp + .include "cbm510.inc" +.elseif .def(__PET__) + .include "pet.inc" +.elseif .def(__VIC20__) + .include "vic20.inc" +.endif + + +_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 + ldx SCREEN_PTR+1 + sta ptr2 + stx 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/cbm510/cpeekcolor.s b/libsrc/cbm510/cpeekcolor.s new file mode 100644 index 000000000..44c0a1595 --- /dev/null +++ b/libsrc/cbm510/cpeekcolor.s @@ -0,0 +1,24 @@ +; +; 2016-02-28, Groepaz +; 2017-06-19, Greg King +; +; unsigned char cpeekcolor (void); +; + + .export _cpeekcolor + + .import CURS_X: zp, CRAM_PTR: zp + + .include "cbm510.inc" + + +_cpeekcolor: + ldx IndReg + lda #$0F + sta IndReg + ldy CURS_X + lda (CRAM_PTR),y ; get color + stx IndReg + and #$0F + ldx #>$0000 + rts diff --git a/libsrc/cbm510/doesclrscr.s b/libsrc/cbm510/doesclrscr.s new file mode 100644 index 000000000..e0f57374c --- /dev/null +++ b/libsrc/cbm510/doesclrscr.s @@ -0,0 +1,16 @@ +; +; 2016-06, Christian Groessler +; 2017-07-05, Greg King +; +; unsigned char doesclrscrafterexit (void); +; +; Returns 0/1 if, after program termination, the screen isn't/is cleared. +; + + .import return1 + +; cc65's CBM510 programs switch to a display screen in the program RAM bank; +; then, they switch back to the system bank when they exit. +; The screen is cleared. + + .export _doesclrscrafterexit := return1 diff --git a/libsrc/cbm610/cpeekc.s b/libsrc/cbm610/cpeekc.s new file mode 100644 index 000000000..295d096f3 --- /dev/null +++ b/libsrc/cbm610/cpeekc.s @@ -0,0 +1,45 @@ +; +; 2016-02-28, Groepaz +; 2017-06-19, Greg King +; +; char cpeekc (void); +; + + .export _cpeekc + + .import CURS_X: zp, CharPtr: zp + + .include "cbm610.inc" + + +_cpeekc: + ldx IndReg + ldy #$0F + sty IndReg + + ldy CURS_X + lda (CharPtr),y ; get char from system bank + stx IndReg + 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/cbm610/cpeekcolor.s b/libsrc/cbm610/cpeekcolor.s new file mode 100644 index 000000000..ed275ec95 --- /dev/null +++ b/libsrc/cbm610/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/cbm610/cpeekrevers.s b/libsrc/cbm610/cpeekrevers.s new file mode 100644 index 000000000..52e166e85 --- /dev/null +++ b/libsrc/cbm610/cpeekrevers.s @@ -0,0 +1,29 @@ +; +; 2016-02-28, Groepaz +; 2017-06-19, Greg King +; +; unsigned char cpeekrevers (void); +; + + .export _cpeekrevers + + .import plot + .import CURS_X: zp, CharPtr: zp + + .include "cbm610.inc" + + +_cpeekrevers: + ldx IndReg + ldy #$0F + sty IndReg + + ldy CURS_X + lda (CharPtr),y ; get char from system bank + stx IndReg + ldx #>$0000 + and #$80 ; get reverse bit + asl a + tax ; ldx #>$0000 + rol a ; return boolean value + rts diff --git a/libsrc/cbm610/cpeeks.s b/libsrc/cbm610/cpeeks.s new file mode 100644 index 000000000..91aae8957 --- /dev/null +++ b/libsrc/cbm610/cpeeks.s @@ -0,0 +1,82 @@ +; +; 2017-07-05, Greg King +; +; void cpeeks (char* s, unsigned length); +; + + .export _cpeeks + + .import popax + .importzp ptr1, ptr2, ptr3, tmp1, tmp2 + .importzp CURS_X, SCREEN_PTR + + .include "cbm610.inc" + .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 + ldx SCREEN_PTR+1 + sta ptr2 + stx ptr2+1 + ldy CURS_X + sty tmp2 + + jsr popax + sta tmp1 ; (will be a .Y index) + stx ptr1+1 + ldx IndReg + ldy #<$0000 + sty ptr1 + bze L3 ; branch always + +L4: ldy #$0F + sty IndReg + ldy tmp2 + lda (ptr2),y ; get char from system bank + stx IndReg + 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 + + lda #$00 ; terminate the string + ldy tmp1 + sta (ptr1),y + rts diff --git a/libsrc/pet/cpeekcolor.s b/libsrc/pet/cpeekcolor.s new file mode 100644 index 000000000..ed275ec95 --- /dev/null +++ b/libsrc/pet/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/testcode/lib/cpeek-test.c b/testcode/lib/cpeek-test.c new file mode 100644 index 000000000..27923432b --- /dev/null +++ b/testcode/lib/cpeek-test.c @@ -0,0 +1,177 @@ +/* Test that the cpeek...() functions are the inverses of cputc(), +** revers(), and textcolor() for the full range of character codes. +** +** 2017-07-15, Greg King +*/ + +#include <conio.h> +#include <cc65.h> + +/* Standard location of the screen */ + +#if defined(__C128__) || defined(__C64__) +/* only 40-column screen */ +# define SCREEN_RAM ((unsigned char*)0x0400) +#elif defined(__C16__) /* Plus4 also */ +# define SCREEN_RAM ((unsigned char*)0x0C00) +#elif defined(__CBM510__) +# define SCREEN_RAM ((unsigned char*)0xF000) +#elif defined(__CBM610__) +# define SCREEN_RAM ((unsigned char*)0xD000) +#elif defined(__PET__) +# define SCREEN_RAM ((unsigned char*)0x0800) +#elif defined(__VIC20__) +# define SCREEN_RAM ((unsigned char*)0x1000) +#else +# error This program cannot test that target. +# define SCREEN_RAM ((unsigned char*)0) +#endif + +static unsigned char width; + + +/* Move the cursor backward one char with +** the recognition of a row change. +*/ +static void chBack (void) +{ + unsigned char y = wherey (); + unsigned char x = wherex (); + + if (x == 0) { + x = width; + --y; + } + --x; + + gotoxy (x, y); +} + + +/* Move the cursor forward one char with +** the recognition of a row change. +*/ +static void chForth (void) +{ + unsigned char y = wherey (); + unsigned char x = wherex (); + + if (++x >= width) { + x = 0; + ++y; + } + + gotoxy (x, y); +} + + +/* A hack to get an unmodified byte from the +** screen memory at the current cursor position. +*/ +static unsigned char peekChWithoutTranslation (void) +{ +#if defined(__CBM610__) + return peekbsys ((unsigned)&SCREEN_RAM[wherey () * width + wherex ()]); +#else + return SCREEN_RAM[wherey () * width + wherex ()]; +#endif +} + + +/* A test which outputs the given char, reads it back from +** screen memory, outputs the returned char at the next position, +** then compares the two screen memory bytes for identity. +** +** Note: cpeekc() must be tested indirectly because some platforms "fold" their +** character code-set into a smaller screen code-set. Therefore, cpeekc() might +** return an equivalent, but not equal, character to the one that was cputc(). +*/ +static unsigned char testCPeekC (char ch) +{ + unsigned char ch2_a, ch2_b, ch2_c; + + /* Test the given char-code, but not the + ** special characters NEWLINE and RETURN + ** (they don't put anything on the screen). + */ + if (('\n' == ch) || ('\r' == ch) + ) { + return 1; + } + + /* Output the char to the screen. */ + cputc (ch); + + /* Move the cursor pos. to the previous output. */ + chBack (); + + /* Get back the written char without any translation. */ + ch2_b = peekChWithoutTranslation (); + + /* Get back the written char, + ** including the translation, screen-code -> text. + */ + ch2_a = cpeekc (); + + /* Move the cursor to the following writing position. */ + chForth (); + + /* Output again the char which was read back by cpeekc(). */ + cputc (ch2_a); + + /* Move the cursor pos. to the second output. */ + chBack (); + + /* Get back the second written char without any translation; + ** and, compare it to the first untranslated char. + */ + ch2_c = peekChWithoutTranslation (); + if (ch2_c != ch2_b) { + /* The test was NOT succesful. + ** Output a diagnostic; and, return FAILURE. + */ + revers(0); + cprintf ("\r\nError on char: %#x was %#x instead.", ch, ch2_a); + cprintf ("\r\nRaw screen codes: %#x, %#x.", ch2_b, ch2_c); + return 0; + } + + /* The test was succesful. + ** Move the cursor to the following writing position. + */ + chForth (); + return 1; +} + + +/* The main code initiates the screen for the tests, and sets the reverse flag. +** Then, it calls testCPeekC() for every char within 0..255. +** Returns zero for success, one for failure. +*/ +int main (void) +{ + unsigned char i; + int ret = 0; + + clrscr (); + revers (1); + screensize (&width, &i); + +#if defined(__VIC20__) + /* The VIC-20's screen is too small to hold the full test. */ + i = 2; +#else + i = 0; +#endif + do { + if (!testCPeekC (i)) { + ret = 1; + break; + } + } while (++i != 0); /* will wrap around when finished */ + + if (doesclrscrafterexit()) { + cgetc(); + } + return ret; +} From a54b4bebde59962594734e89c9765b4dd3d4eb74 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 11 Dec 2017 21:15:29 +0100 Subject: [PATCH 0511/2161] PET screen memory is at $8000, not $0800 --- testcode/lib/cpeek-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testcode/lib/cpeek-test.c b/testcode/lib/cpeek-test.c index 27923432b..86bdc74ee 100644 --- a/testcode/lib/cpeek-test.c +++ b/testcode/lib/cpeek-test.c @@ -19,7 +19,7 @@ #elif defined(__CBM610__) # define SCREEN_RAM ((unsigned char*)0xD000) #elif defined(__PET__) -# define SCREEN_RAM ((unsigned char*)0x0800) +# define SCREEN_RAM ((unsigned char*)0x8000) #elif defined(__VIC20__) # define SCREEN_RAM ((unsigned char*)0x1000) #else From 9a609f6766f62ff0b609c6174bbaf24b8e2b8eb8 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 11 Dec 2017 21:53:00 +0100 Subject: [PATCH 0512/2161] fix petscii conversion for C128 --- libsrc/c128/cpeekc.s | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/libsrc/c128/cpeekc.s b/libsrc/c128/cpeekc.s index ce6bb4ff5..9d64388a4 100644 --- a/libsrc/c128/cpeekc.s +++ b/libsrc/c128/cpeekc.s @@ -26,7 +26,8 @@ _cpeekc: ; Convert the screen code into a PetSCII code. ; $00 - $1F: +$40 ; $20 - $3F -; $40 - $7F: +$80 +; $40 - $5f: +$20 +; $60 - $7F: +$40 cmp #$20 bcs @sk1 ;(bge) @@ -35,9 +36,13 @@ _cpeekc: @sk1: cmp #$40 bcc @end ;(blt) - ora #$80 -@end: ldx #0 - rts + cmp #$60 + bcc @sk2 ;(blt) + ;sec + adc #$20 - $01 +@sk2: ;clc ; both above cmp and adc clear carry flag + adc #$20 +@end: rts @c80: lda SCREEN_PTR From 74b5540f76c8e8ab09c219e871e7cae826d59731 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 12 Dec 2017 03:48:43 +0100 Subject: [PATCH 0513/2161] copy cpeeks from generic version, this at least makes it work for 40 columns --- libsrc/c128/cpeeks.s | 72 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 4 deletions(-) diff --git a/libsrc/c128/cpeeks.s b/libsrc/c128/cpeeks.s index c9d806ef3..e0723e694 100644 --- a/libsrc/c128/cpeeks.s +++ b/libsrc/c128/cpeeks.s @@ -1,15 +1,79 @@ ; -; 2017-11-23, Greg King +; 2017-07-05, Greg King ; ; void cpeeks (char* s, unsigned length); ; -; C128 can't use "cbm/cpeeks.s" because both 40 and 80 columns must be handled. -; Stub file, for now, so that its library can be built. .export _cpeeks .import popax + .importzp ptr1, ptr2, ptr3, tmp1, tmp2 + .macpack generic + +; FIXME c128 needs special version that handles the 80-column VDC. + + .include "c128.inc" _cpeeks: - jmp popax ; pop s + eor #<$FFFF ; counting a word upward is faster + sta ptr3 ; so, we use -(length + 1) + txa + eor #>$FFFF + sta ptr3+1 + + lda SCREEN_PTR + ldx SCREEN_PTR+1 + sta ptr2 + stx 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 From 4d95e578f45d3ab0df41237ab67c4eab04f7e345 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 12 Dec 2017 03:49:07 +0100 Subject: [PATCH 0514/2161] added missing tests --- testcode/lib/cpeek-test.c | 99 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 2 deletions(-) diff --git a/testcode/lib/cpeek-test.c b/testcode/lib/cpeek-test.c index 86bdc74ee..d02972202 100644 --- a/testcode/lib/cpeek-test.c +++ b/testcode/lib/cpeek-test.c @@ -16,6 +16,7 @@ # define SCREEN_RAM ((unsigned char*)0x0C00) #elif defined(__CBM510__) # define SCREEN_RAM ((unsigned char*)0xF000) +# define COLOR_RAM ((unsigned char*)0xd400) #elif defined(__CBM610__) # define SCREEN_RAM ((unsigned char*)0xD000) #elif defined(__PET__) @@ -77,6 +78,18 @@ static unsigned char peekChWithoutTranslation (void) #endif } +/* as above, but for color ram */ +static unsigned char peekColWithoutTranslation (void) +{ +#if defined(__CBM610__) || defined (__PET__) + return COLOR_WHITE; +#elif defined(__C128__) || defined(__C64__) || defined(__VIC20__) || defined(__CBM510__) + return COLOR_RAM[wherey () * width + wherex ()] & 0x0f; +#else + return COLOR_RAM[wherey () * width + wherex ()]; +#endif +} + /* A test which outputs the given char, reads it back from ** screen memory, outputs the returned char at the next position, @@ -133,6 +146,7 @@ static unsigned char testCPeekC (char ch) revers(0); cprintf ("\r\nError on char: %#x was %#x instead.", ch, ch2_a); cprintf ("\r\nRaw screen codes: %#x, %#x.", ch2_b, ch2_c); + cprintf ("\r\nscreen width: %#d", width); return 0; } @@ -143,18 +157,70 @@ static unsigned char testCPeekC (char ch) return 1; } +static unsigned char testCPeekCol (char ch) +{ + unsigned char ch2_a, ch2_b, ch2_c; + + /* Output the char to the screen. */ + textcolor (ch); + cputc ('*'); + + /* Move the cursor pos. to the previous output. */ + chBack (); + + /* Get back the written char without any translation. */ + ch2_b = peekColWithoutTranslation (); + + /* Get back the written char, + ** including the translation, screen-code -> text. + */ + ch2_a = cpeekcolor (); + + /* Move the cursor to the following writing position. */ + chForth (); + + /* Output again the char which was read back by cpeekc(). */ + textcolor (ch2_a); + cputc ('x'); + + /* Move the cursor pos. to the second output. */ + chBack (); + + /* Get back the second written char without any translation; + ** and, compare it to the first untranslated char. + */ + ch2_c = peekColWithoutTranslation (); + if (ch2_c != ch2_b) { + /* The test was NOT succesful. + ** Output a diagnostic; and, return FAILURE. + */ + revers(0); + cprintf ("\r\nError on color: %#x was %#x instead.", ch, ch2_a); + cprintf ("\r\nRaw color codes: %#x, %#x.", ch2_b, ch2_c); + return 0; + } + + /* The test was succesful. + ** Move the cursor to the following writing position. + */ + chForth (); + return 1; +} /* The main code initiates the screen for the tests, and sets the reverse flag. ** Then, it calls testCPeekC() for every char within 0..255. +** Then, it calls testCPeekCol() for each color ** Returns zero for success, one for failure. */ int main (void) { - unsigned char i; + unsigned char i, c1, c2; + char s[10]; int ret = 0; clrscr (); revers (1); + textcolor(1); screensize (&width, &i); #if defined(__VIC20__) @@ -166,10 +232,39 @@ int main (void) do { if (!testCPeekC (i)) { ret = 1; - break; + goto exiterror; } } while (++i != 0); /* will wrap around when finished */ + /* test colors */ + clrscr (); + revers (0); +#if defined (__CBM610__) || defined (__PET__) + cprintf("no COLOR_RAM\n\r"); +#else + cprintf("COLOR_RAM at $%04x\n\r", COLOR_RAM); +#endif + do { + if (!testCPeekCol (i)) { + ret = 1; + goto exiterror; + } + } while (++i != 16); /* max 16 colors */ + + /* test revers */ + textcolor(1); cputc('\n'); cputc('\r'); + revers(0); cputc('*'); chBack (); c1 = cpeekrevers(); chForth(); + revers(1); cputc('*'); chBack (); c2 = cpeekrevers(); chForth(); + cputc('\n'); cputc('\r'); + revers(c1); cputc('*'); + revers(c2); cputc('*'); + + /* test cpeeks() */ + revers(0); + cprintf("\n\rtest1234"); gotox(0); cpeeks(s, 8); cputs("\n"); + cputs(s); + +exiterror: if (doesclrscrafterexit()) { cgetc(); } From 4da22fc6a095258e8ee16a6659ca4a90585c18f1 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 12 Dec 2017 04:32:39 +0100 Subject: [PATCH 0515/2161] fix cpeeks for CBM610 --- libsrc/cbm610/cpeeks.s | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libsrc/cbm610/cpeeks.s b/libsrc/cbm610/cpeeks.s index 91aae8957..352521bcc 100644 --- a/libsrc/cbm610/cpeeks.s +++ b/libsrc/cbm610/cpeeks.s @@ -8,7 +8,7 @@ .import popax .importzp ptr1, ptr2, ptr3, tmp1, tmp2 - .importzp CURS_X, SCREEN_PTR + .importzp CURS_X, CharPtr .include "cbm610.inc" .macpack generic @@ -21,8 +21,8 @@ _cpeeks: eor #>$FFFF sta ptr3+1 - lda SCREEN_PTR - ldx SCREEN_PTR+1 + lda CharPtr + ldx CharPtr+1 sta ptr2 stx ptr2+1 ldy CURS_X From 892732f3403e187026d518bdeb690de66408b8eb Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 12 Dec 2017 17:05:24 +0100 Subject: [PATCH 0516/2161] fix cpeeks() for C128 VDC --- libsrc/c128/cpeeks.s | 80 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/libsrc/c128/cpeeks.s b/libsrc/c128/cpeeks.s index e0723e694..12c3349e4 100644 --- a/libsrc/c128/cpeeks.s +++ b/libsrc/c128/cpeeks.s @@ -1,5 +1,6 @@ ; ; 2017-07-05, Greg King +; 2017-12-12, Groepaz ; ; void cpeeks (char* s, unsigned length); ; @@ -22,6 +23,9 @@ _cpeeks: eor #>$FFFF sta ptr3+1 + lda MODE + bmi c80 + lda SCREEN_PTR ldx SCREEN_PTR+1 sta ptr2 @@ -77,3 +81,79 @@ L3: inc ptr3 ; count length ldy tmp1 sta (ptr1),y rts + + ;----------------------------------------------------------- +c80: + lda SCREEN_PTR + clc + adc CURS_X + sta ptr2 + lda SCREEN_PTR+1 + adc #0 + sta ptr2+1 + + jsr popax + sta tmp1 ; (will be a .Y index) + stx ptr1+1 + ldx #<$0000 + stx ptr1 + bze L3a ; branch always + +L4a: + lda ptr2 + ldy ptr2+1 + inc ptr2 + bne @s + inc ptr2+1 +@s: + ; get byte from VDC mem + ldx #VDC_DATA_LO + stx VDC_INDEX +@L0: bit VDC_INDEX + bpl @L0 + sta VDC_DATA + dex + stx VDC_INDEX + sty VDC_DATA + + ldx #VDC_RAM_RW + stx VDC_INDEX +@L1: bit VDC_INDEX + bpl @L1 ; wait for blanking + lda VDC_DATA + + 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 L5a + cmp #$60 + blt @sk2 ;(bcc) + clc +@sk1: adc #$20 +@sk2: ;clc ; both above cmp and adc clear carry flag + adc #$20 + +L5a: ldy tmp1 + sta (ptr1),y + iny + bnz L1a + inc ptr1+1 +L1a: sty tmp1 + +L3a: inc ptr3 ; count length + bnz L4a + inc ptr3+1 + bnz L4a + + lda #0 ; terminate the string + ldy tmp1 + sta (ptr1),y + rts From 2957acd133c6eb7436a984d704575b1c2b77d0f3 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 12 Dec 2017 17:05:52 +0100 Subject: [PATCH 0517/2161] some tweaks to testprog --- testcode/lib/cpeek-test.c | 53 +++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/testcode/lib/cpeek-test.c b/testcode/lib/cpeek-test.c index d02972202..5f3bfc524 100644 --- a/testcode/lib/cpeek-test.c +++ b/testcode/lib/cpeek-test.c @@ -2,6 +2,7 @@ ** revers(), and textcolor() for the full range of character codes. ** ** 2017-07-15, Greg King +** 2017-12-12, Groepaz */ #include <conio.h> @@ -139,7 +140,12 @@ static unsigned char testCPeekC (char ch) ** and, compare it to the first untranslated char. */ ch2_c = peekChWithoutTranslation (); - if (ch2_c != ch2_b) { + if ((ch2_c != ch2_b) +#if defined(__C128__) + /* VDC memory is not accessable */ + && (width == 40) +#endif + ){ /* The test was NOT succesful. ** Output a diagnostic; and, return FAILURE. */ @@ -190,7 +196,12 @@ static unsigned char testCPeekCol (char ch) ** and, compare it to the first untranslated char. */ ch2_c = peekColWithoutTranslation (); - if (ch2_c != ch2_b) { + if ((ch2_c != ch2_b) +#if defined(__C128__) + /* VDC memory is not accessable */ + && (width == 40) +#endif + ){ /* The test was NOT succesful. ** Output a diagnostic; and, return FAILURE. */ @@ -221,6 +232,7 @@ int main (void) clrscr (); revers (1); textcolor(1); + bgcolor(0); screensize (&width, &i); #if defined(__VIC20__) @@ -236,14 +248,29 @@ int main (void) } } while (++i != 0); /* will wrap around when finished */ - /* test colors */ - clrscr (); - revers (0); -#if defined (__CBM610__) || defined (__PET__) - cprintf("no COLOR_RAM\n\r"); -#else - cprintf("COLOR_RAM at $%04x\n\r", COLOR_RAM); +#if defined(__VIC20__) + cgetc(); #endif + + /* test colors */ +#if defined(__VIC20__) + clrscr (); +#endif + revers (0); + textcolor(1); + +#if defined (__CBM610__) || defined (__PET__) + cprintf("\n\rno COLOR_RAM\n\r"); +#elif defined (__C128__) + if (width == 40) { + cprintf("\n\rCOLOR_RAM at $%04x\n\r", COLOR_RAM); + } else { + cprintf("\n\rno COLOR_RAM\n\r"); + } +#else + cprintf("\n\rCOLOR_RAM at $%04x\n\r", COLOR_RAM); +#endif + do { if (!testCPeekCol (i)) { ret = 1; @@ -253,11 +280,11 @@ int main (void) /* test revers */ textcolor(1); cputc('\n'); cputc('\r'); - revers(0); cputc('*'); chBack (); c1 = cpeekrevers(); chForth(); - revers(1); cputc('*'); chBack (); c2 = cpeekrevers(); chForth(); + revers(0); cputc('x'); chBack (); c1 = cpeekrevers(); chForth(); + revers(1); cputc('X'); chBack (); c2 = cpeekrevers(); chForth(); cputc('\n'); cputc('\r'); - revers(c1); cputc('*'); - revers(c2); cputc('*'); + revers(c1); cputc('o'); + revers(c2); cputc('O'); /* test cpeeks() */ revers(0); From 6faef87b49a7c310b8bb939f89b565ed28da7776 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Fri, 15 Dec 2017 23:51:39 +0100 Subject: [PATCH 0518/2161] Fixed Oric-1 compatibility #550 --- asminc/atmos.inc | 6 ++ doc/funcref.sgml | 172 +++++++++++++++++++++++++++++++++++++++++-- libsrc/atmos/atmos.s | 47 ++++++++++-- 3 files changed, 211 insertions(+), 14 deletions(-) diff --git a/asminc/atmos.inc b/asminc/atmos.inc index 4c3c442fa..8edcf7dc2 100644 --- a/asminc/atmos.inc +++ b/asminc/atmos.inc @@ -104,8 +104,14 @@ PRINT := $F77C ; Sound Effects PING := $FA9F +PING1 := $FA85 SHOOT := $FAB5 +SHOOT1 := $FA9B EXPLODE := $FACB +EXPLODE1 := $FAB1 ZAP := $FAE1 +ZAP1 := $FAC7 TICK := $FB14 +TICK1 := $FAFA TOCK := $FB2A +TOCK1 := $FB10 diff --git a/doc/funcref.sgml b/doc/funcref.sgml index f74630ae3..62413d6af 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -115,18 +115,16 @@ function. <sect1><tt/atmos.h/<label id="atmos.h"><p> <itemize> +<item><ref id="atmos_explode" name="atmos_explode"> <item><ref id="atmos_load" name="atmos_load"> +<item><ref id="atmos_ping" name="atmos_ping"> <item><ref id="atmos_save" name="atmos_save"> -<!-- <item><ref id="atmos_explode" name="atmos_explode"> --> -<!-- <item><ref id="atmos_ping" name="atmos_ping"> --> -<!-- <item><ref id="atmos_shoot" name="atmos_shoot"> --> -<!-- <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="atmos_shoot" name="atmos_shoot"> +<item><ref id="atmos_tick" name="atmos_tick"> +<item><ref id="atmos_tock" name="atmos_tock"> +<item><ref id="atmos_zap" name="atmos_zap"> </itemize> -(incomplete) - <sect1><tt/c128.h/<label id="c128.h"><p> @@ -674,6 +672,20 @@ communication. (incomplete) +<sect1><tt/telestrat.h/<label id="telestrat.h"><p> + +<itemize> +<item><ref id="atmos_explode" name="explode"> +<item><ref id="atmos_ping" name="ping"> +<item><ref id="atmos_shoot" name="shoot"> +<item><ref id="atmos_zap" name="zap"> +<!-- <item><ref id="kbdclick1" name="kbdclick1"> --> +<!-- <item><ref id="oups" name="oups"> --> +</itemize> + +(incomplete) + + <sect1><tt/tgi.h/<label id="tgi.h"><p> <url url="tgi.html" name="Tiny Graphics Interface">. @@ -1333,6 +1345,30 @@ used in presence of a prototype. </quote> +<sect1>atmos_explode<label id="atmos_explode"><p> + +<quote> +<descrip> +<tag/Function/Bomb sound effect. +<tag/Header/<tt/<ref id="atmos.h" name="atmos.h">/ +<tag/Declaration/<tt/void __fastcall__ atmos_explode(void);/ +<tag/Description/<tt/atmos_explode/ plays the BASIC sound. +<tag/Notes/<itemize> +<item>The function is available only as a fastcall function; so, it may be used +only in the presence of a prototype. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="atmos_ping" name="atmos_ping">, +<ref id="atmos_shoot" name="atmos_shoot">, +<ref id="atmos_tick" name="atmos_tick">, +<ref id="atmos_tock" name="atmos_tock">, +<ref id="atmos_zap" name="atmos_zap"> +<tag/Example/None. +</descrip> +</quote> + + <sect1>atmos_load<label id="atmos_load"><p> <quote> @@ -1353,6 +1389,30 @@ only in the presence of a prototype. </quote> +<sect1>atmos_ping<label id="atmos_ping"><p> + +<quote> +<descrip> +<tag/Function/Bell or ricochet sound effect. +<tag/Header/<tt/<ref id="atmos.h" name="atmos.h">/ +<tag/Declaration/<tt/void __fastcall__ atmos_ping(void);/ +<tag/Description/<tt/atmos_ping/ plays the BASIC sound. +<tag/Notes/<itemize> +<item>The function is available only as a fastcall function; so, it may be used +only in the presence of a prototype. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="atmos_explode" name="atmos_explode">, +<ref id="atmos_shoot" name="atmos_shoot">, +<ref id="atmos_tick" name="atmos_tick">, +<ref id="atmos_tock" name="atmos_tock">, +<ref id="atmos_zap" name="atmos_zap"> +<tag/Example/None. +</descrip> +</quote> + + <sect1>atmos_save<label id="atmos_save"><p> <quote> @@ -1375,6 +1435,102 @@ atmos_save("hires", 0xa000, 0xc000); </quote> +<sect1>atmos_shoot<label id="atmos_shoot"><p> + +<quote> +<descrip> +<tag/Function/Pistol sound effect. +<tag/Header/<tt/<ref id="atmos.h" name="atmos.h">/ +<tag/Declaration/<tt/void __fastcall__ atmos_shoot(void);/ +<tag/Description/<tt/atmos_shoot/ plays the BASIC sound. +<tag/Notes/<itemize> +<item>The function is available only as a fastcall function; so, it may be used +only in the presence of a prototype. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="atmos_explode" name="atmos_explode">, +<ref id="atmos_ping" name="atmos_ping">, +<ref id="atmos_tick" name="atmos_tick">, +<ref id="atmos_tock" name="atmos_tock">, +<ref id="atmos_zap" name="atmos_zap"> +<tag/Example/None. +</descrip> +</quote> + + +<sect1>atmos_tick<label id="atmos_tick"><p> + +<quote> +<descrip> +<tag/Function/High-pitch click. +<tag/Header/<tt/<ref id="atmos.h" name="atmos.h">/ +<tag/Declaration/<tt/void __fastcall__ atmos_tick(void);/ +<tag/Description/<tt/atmos_tick/ plays the system sound. +<tag/Notes/<itemize> +<item>The function is available only as a fastcall function; so, it may be used +only in the presence of a prototype. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="atmos_explode" name="atmos_explode">, +<ref id="atmos_ping" name="atmos_ping">, +<ref id="atmos_shoot" name="atmos_shoot">, +<ref id="atmos_tock" name="atmos_tock">, +<ref id="atmos_zap" name="atmos_zap"> +<tag/Example/None. +</descrip> +</quote> + + +<sect1>atmos_tock<label id="atmos_tock"><p> + +<quote> +<descrip> +<tag/Function/Low-pitch click. +<tag/Header/<tt/<ref id="atmos.h" name="atmos.h">/ +<tag/Declaration/<tt/void __fastcall__ atmos_tock(void);/ +<tag/Description/<tt/atmos_tock/ plays the system sound. +<tag/Notes/<itemize> +<item>The function is available only as a fastcall function; so, it may be used +only in the presence of a prototype. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="atmos_explode" name="atmos_explode">, +<ref id="atmos_ping" name="atmos_ping">, +<ref id="atmos_shoot" name="atmos_shoot">, +<ref id="atmos_tick" name="atmos_tick">, +<ref id="atmos_zap" name="atmos_zap"> +<tag/Example/None. +</descrip> +</quote> + + +<sect1>atmos_zap<label id="atmos_zap"><p> + +<quote> +<descrip> +<tag/Function/Raygun sound effect. +<tag/Header/<tt/<ref id="atmos.h" name="atmos.h">/ +<tag/Declaration/<tt/void __fastcall__ atmos_zap(void);/ +<tag/Description/<tt/atmos_zap/ plays the BASIC sound. +<tag/Notes/<itemize> +<item>The function is available only as a fastcall function; so, it may be used +only in the presence of a prototype. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="atmos_explode" name="atmos_explode">, +<ref id="atmos_ping" name="atmos_ping">, +<ref id="atmos_shoot" name="atmos_shoot">, +<ref id="atmos_tick" name="atmos_tick">, +<ref id="atmos_tock" name="atmos_tock"> +<tag/Example/None. +</descrip> +</quote> + + <sect1>atoi<label id="atoi"><p> <quote> diff --git a/libsrc/atmos/atmos.s b/libsrc/atmos/atmos.s index 6b5a4a49c..c50204fa5 100644 --- a/libsrc/atmos/atmos.s +++ b/libsrc/atmos/atmos.s @@ -7,9 +7,44 @@ .include "atmos.inc" -_atmos_ping := PING -_atmos_shoot := SHOOT -_atmos_explode := EXPLODE -_atmos_zap := ZAP -_atmos_tick := TICK -_atmos_tock := TOCK +.proc _atmos_ping + bit $31 + bvs L1 ; Atmos? + jmp PING +L1: jmp PING1 +.endproc + +.proc _atmos_shoot + lda $31 + bvs L1 ; Atmos? + jmp SHOOT +L1: jmp SHOOT1 +.endproc + +.proc _atmos_explode + lda $31 + bvs L1 ; Atmos? + jmp EXPLODE +L1: jmp EXPLODE1 +.endproc + +.proc _atmos_zap + lda $31 + bvs L1 ; Atmos? + jmp ZAP +L1: jmp ZAP1 +.endproc + +.proc _atmos_tick + lda $31 + bvs L1 ; Atmos? + jmp TICK +L1: jmp TICK1 +.endproc + +.proc _atmos_tock + lda $31 + bvs L1 ; Atmos? + jmp TOCK +L1: jmp TOCK1 +.endproc From 41fab61253493516efb48f722f409dcbd317be3f Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 16 Dec 2017 00:41:00 +0100 Subject: [PATCH 0519/2161] Fixed memory config #551 --- cfg/c16.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/c16.cfg b/cfg/c16.cfg index b67c66b96..9f54730af 100644 --- a/cfg/c16.cfg +++ b/cfg/c16.cfg @@ -7,7 +7,7 @@ MEMORY { ZP: file = "", define = yes, start = $0002, size = $001A; LOADADDR: file = %O, start = $0FFF, size = $0002; HEADER: file = %O, start = $1001, size = $000C; - MAIN: file = %O, start = $100D, size = $6FF3 - __STACKSIZE__; + MAIN: file = %O, start = $100D, size = $3FF3 - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; From 6452fbac89d85b538a80bf535674d15346cb92d7 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 16 Dec 2017 01:04:05 +0100 Subject: [PATCH 0520/2161] Added new config #551 --- cfg/c16-32k.cfg | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 cfg/c16-32k.cfg diff --git a/cfg/c16-32k.cfg b/cfg/c16-32k.cfg new file mode 100644 index 000000000..f2ce53d05 --- /dev/null +++ b/cfg/c16-32k.cfg @@ -0,0 +1,39 @@ +SYMBOLS { + __LOADADDR__: type = import; + __EXEHDR__: type = import; + __STACKSIZE__: type = weak, value = $0800; # 2k stack +} +MEMORY { + ZP: file = "", define = yes, start = $0002, size = $001A; + LOADADDR: file = %O, start = $0FFF, size = $0002; + HEADER: file = %O, start = $1001, size = $000C; + MAIN: file = %O, start = $100D, size = $7FF3 - __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; + ONCE: 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 = bss; + 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 afb758bd6c7fff09386515e023dda16d76cf9d84 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 16 Dec 2017 02:35:00 +0100 Subject: [PATCH 0521/2161] Update c16-32k.cfg --- cfg/c16-32k.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/c16-32k.cfg b/cfg/c16-32k.cfg index f2ce53d05..b67c66b96 100644 --- a/cfg/c16-32k.cfg +++ b/cfg/c16-32k.cfg @@ -7,7 +7,7 @@ MEMORY { ZP: file = "", define = yes, start = $0002, size = $001A; LOADADDR: file = %O, start = $0FFF, size = $0002; HEADER: file = %O, start = $1001, size = $000C; - MAIN: file = %O, start = $100D, size = $7FF3 - __STACKSIZE__; + MAIN: file = %O, start = $100D, size = $6FF3 - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; From b4fe03e49ff27b787ce287d3333935c3cab7dab7 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 16 Dec 2017 02:36:31 +0100 Subject: [PATCH 0522/2161] Update c16.cfg --- cfg/c16.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/c16.cfg b/cfg/c16.cfg index 9f54730af..8016c6d0f 100644 --- a/cfg/c16.cfg +++ b/cfg/c16.cfg @@ -7,7 +7,7 @@ MEMORY { ZP: file = "", define = yes, start = $0002, size = $001A; LOADADDR: file = %O, start = $0FFF, size = $0002; HEADER: file = %O, start = $1001, size = $000C; - MAIN: file = %O, start = $100D, size = $3FF3 - __STACKSIZE__; + MAIN: file = %O, start = $100D, size = $2FF3 - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; From 6497da262a72790e748df1214e95a99cbf814ba5 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sun, 17 Dec 2017 18:45:57 +0100 Subject: [PATCH 0523/2161] oops I made a mistake. --- libsrc/atmos/atmos.s | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libsrc/atmos/atmos.s b/libsrc/atmos/atmos.s index c50204fa5..5822be8d9 100644 --- a/libsrc/atmos/atmos.s +++ b/libsrc/atmos/atmos.s @@ -15,35 +15,35 @@ L1: jmp PING1 .endproc .proc _atmos_shoot - lda $31 + bit $31 bvs L1 ; Atmos? jmp SHOOT L1: jmp SHOOT1 .endproc .proc _atmos_explode - lda $31 + bit $31 bvs L1 ; Atmos? jmp EXPLODE L1: jmp EXPLODE1 .endproc .proc _atmos_zap - lda $31 + bit $31 bvs L1 ; Atmos? jmp ZAP L1: jmp ZAP1 .endproc .proc _atmos_tick - lda $31 + bit $31 bvs L1 ; Atmos? jmp TICK L1: jmp TICK1 .endproc .proc _atmos_tock - lda $31 + bit $31 bvs L1 ; Atmos? jmp TOCK L1: jmp TOCK1 From 98e2b79ef4f25aa1c8158c95e5f14f1733fb74be Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 18 Dec 2017 19:19:59 +0100 Subject: [PATCH 0524/2161] Optimizing the stack size --- cfg/c16.cfg | 2 +- cfg/creativision.cfg | 2 +- cfg/vic20-32k.cfg | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cfg/c16.cfg b/cfg/c16.cfg index 8016c6d0f..41545d473 100644 --- a/cfg/c16.cfg +++ b/cfg/c16.cfg @@ -1,7 +1,7 @@ SYMBOLS { __LOADADDR__: type = import; __EXEHDR__: type = import; - __STACKSIZE__: type = weak, value = $0800; # 2k stack + __STACKSIZE__: type = weak, value = $0400; # 1k stack } MEMORY { ZP: file = "", define = yes, start = $0002, size = $001A; diff --git a/cfg/creativision.cfg b/cfg/creativision.cfg index 9e4ecd8ce..289984df0 100644 --- a/cfg/creativision.cfg +++ b/cfg/creativision.cfg @@ -3,7 +3,7 @@ SYMBOLS { } MEMORY { ZP: file = "", define = yes, start = $0020, size = $00E0; - RAM: file = "", define = yes, start = $01FA, size = $0206; + RAM: file = "", define = yes, start = $01FA, size = $0206 - __STACKSIZE__; ROM: file = %O, define = yes, start = $B000, size = $1000, fill = yes, fillval = $FF; } SEGMENTS { diff --git a/cfg/vic20-32k.cfg b/cfg/vic20-32k.cfg index 28dd661ad..fe53d46ab 100644 --- a/cfg/vic20-32k.cfg +++ b/cfg/vic20-32k.cfg @@ -3,7 +3,7 @@ SYMBOLS { __LOADADDR__: type = import; __EXEHDR__: type = import; - __STACKSIZE__: type = weak, value = $0400; # 1k stack + __STACKSIZE__: type = weak, value = $0800; # 2k stack } MEMORY { ZP: file = "", define = yes, start = $0002, size = $001A; From c8dd88efad29864da56aa3663318f810dcf88c36 Mon Sep 17 00:00:00 2001 From: greg-king5 <greg.king5@verizon.net> Date: Mon, 18 Dec 2017 17:09:06 -0500 Subject: [PATCH 0525/2161] Added missing "break;" statements to a "switch" statement. --- src/common/xsprintf.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/common/xsprintf.c b/src/common/xsprintf.c index d50ad7a68..a7d26d5ef 100644 --- a/src/common/xsprintf.c +++ b/src/common/xsprintf.c @@ -352,14 +352,14 @@ 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; - case lmShort: *va_arg (P->ap, int*) = P->BufFill; - case lmInt: *va_arg (P->ap, int*) = P->BufFill; - case lmLong: *va_arg (P->ap, long*) = P->BufFill; - case lmIntMax: *va_arg (P->ap, intmax_t*) = P->BufFill; - case lmSizeT: *va_arg (P->ap, size_t*) = P->BufFill; - case lmPtrDiffT: *va_arg (P->ap, ptrdiff_t*) = P->BufFill; - default: FAIL ("Invalid size modifier for %n format spec in xvsnprintf"); + case lmChar: *va_arg (P->ap, int*) = P->BufFill; break; + case lmShort: *va_arg (P->ap, int*) = 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; + case lmSizeT: *va_arg (P->ap, size_t*) = P->BufFill; break; + case lmPtrDiffT: *va_arg (P->ap, ptrdiff_t*) = P->BufFill; break; + default: FAIL ("Invalid size modifier for %n format spec. in xvsnprintf()"); } } From 0543ecabe2624e0ec73df1e090f386c6d96a3a1e Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 28 Dec 2017 01:58:03 +0100 Subject: [PATCH 0526/2161] added peek functions for soft80 --- libsrc/c64/extra/soft80.s | 19 ++++ libsrc/c64/extra/soft80mono.s | 19 ++++ libsrc/c64/soft80_cpeekc.s | 168 +++++++++++++++++++++++++++++ libsrc/c64/soft80_cpeekcolor.s | 19 ++++ libsrc/c64/soft80_cpeekrevers.s | 10 ++ libsrc/c64/soft80_cpeeks.s | 71 ++++++++++++ libsrc/c64/soft80mono_cpeekcolor.s | 17 +++ 7 files changed, 323 insertions(+) create mode 100644 libsrc/c64/soft80_cpeekc.s create mode 100644 libsrc/c64/soft80_cpeekcolor.s create mode 100644 libsrc/c64/soft80_cpeekrevers.s create mode 100644 libsrc/c64/soft80_cpeeks.s create mode 100644 libsrc/c64/soft80mono_cpeekcolor.s diff --git a/libsrc/c64/extra/soft80.s b/libsrc/c64/extra/soft80.s index d445c85c0..0ea28cfaf 100644 --- a/libsrc/c64/extra/soft80.s +++ b/libsrc/c64/extra/soft80.s @@ -15,6 +15,22 @@ .export _textcolor := soft80_textcolor ; color.s .export _bgcolor := soft80_bgcolor ; color.s + ; soft80_cpeekc.s + .import soft80_cpeekc + .export _cpeekc := soft80_cpeekc ; cpeekc.s + + ; soft80_cpeekcolor.s + .import soft80_cpeekcolor + .export _cpeekcolor := soft80_cpeekcolor ; cpeekcolor.s + + ; soft80_cpeekrevers.s + .import soft80_cpeekrevers + .export _cpeekrevers := soft80_cpeekrevers ; cpeekrevers.s + + ; soft80_cpeeks.s + .import soft80_cpeeks + .export _cpeeks := soft80_cpeeks ; cpeeks.s + ; soft80_cputc.s .import soft80_cputc .import soft80_cputcxy @@ -50,3 +66,6 @@ ; Chars used by chline () and cvline () .exportzp chlinechar = CH_HLINE .exportzp cvlinechar = CH_VLINE + + .import return1 + .export _doesclrscrafterexit := return1 diff --git a/libsrc/c64/extra/soft80mono.s b/libsrc/c64/extra/soft80mono.s index 6fd2c687c..700cbcb6c 100644 --- a/libsrc/c64/extra/soft80mono.s +++ b/libsrc/c64/extra/soft80mono.s @@ -18,6 +18,22 @@ .export _textcolor := soft80mono_textcolor ; color.s .export _bgcolor := soft80mono_bgcolor ; color.s + ; soft80mono_cpeekc.s + .import soft80_cpeekc + .export _cpeekc := soft80_cpeekc ; cpeekc.s + + ; soft80mono_cpeekcolor.s + .import soft80mono_cpeekcolor + .export _cpeekcolor := soft80mono_cpeekcolor ; cpeekcolor.s + + ; soft80mono_cpeekrevers.s + .import soft80_cpeekrevers + .export _cpeekrevers := soft80_cpeekrevers ; cpeekrevers.s + + ; soft80mono_cpeeks.s + .import soft80_cpeeks + .export _cpeeks := soft80_cpeeks ; cpeeks.s + ; soft80mono_cputc.s .import soft80mono_cputc .import soft80mono_cputcxy @@ -53,3 +69,6 @@ ; Chars used by chline () and cvline () .exportzp chlinechar = CH_HLINE .exportzp cvlinechar = CH_VLINE + + .import return1 + .export _doesclrscrafterexit := return1 diff --git a/libsrc/c64/soft80_cpeekc.s b/libsrc/c64/soft80_cpeekc.s new file mode 100644 index 000000000..2801ade97 --- /dev/null +++ b/libsrc/c64/soft80_cpeekc.s @@ -0,0 +1,168 @@ + + .export soft80_cpeekc, soft80_cpeekchar + + .include "c64.inc" + .include "soft80.inc" + + .macpack longbranch + + .segment "CODE" + +soft80_cpeekc: + jsr soft80_cpeekchar + ldx #0 + rts + +soft80_cpeekchar: + + sei + ;;dec $01 ;; assumed = $36 + ;;dec $01 ;; assumed = $36 + lda #$34 + sta $01 + + lda CURS_X + and #$01 + + jne @l1a + + ; test non-inverted character (left side) + + 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 ; return char in A + ; sec +; sbc #$20 + ldx #$00 ; revers flag +;inc $d020 + rts +@l2b: +;jmp * + inx + cpx #$80 + jne @l2aa + + ; test inverted character (left side) + + ldx #0 +@l2aa2: + ldy #0 + +;; stx $d020 + + .repeat 8,line +;; jsr readdirect + lda (SCREEN_PTR),y + and #$f0 + eor #$f0 + cmp soft80_hi_charset+(line*$80),x +; cmp #0 + bne @l2b2 + .if (line < 7) + iny + .endif + .endrepeat + +@backokrevers: +;inc $d020 +; inc $01 +; inc $01 + lda #$36 + sta $01 + cli + txa ; return char in A + ; sec +; sbc #$20 + ldx #$01 ; revers flag +;inc $d020 + rts + +@l2b2: + inx + cpx #$80 + jne @l2aa2 + +@backerr: +;inc $d020 + ;; inc $01 +;; inc $01 + lda #$36 + sta $01 + cli + ldx #0 + txa + + rts + + ; test non-inverted character (right side) + +@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 + + ; test inverted character (right side) + + ldx #0 +@l1aa2: + ldy #0 + .repeat 8,line +;; jsr readdirect + lda (SCREEN_PTR),y + and #$0f + eor #$0f + eor soft80_lo_charset+(line*$80),x + bne @l2bb2 + .if line < 7 + iny + .endif + .endrepeat + jmp @backokrevers +@l2bb2: + inx + cpx #$80 + bne @l1aa2 + + + jmp @backerr + diff --git a/libsrc/c64/soft80_cpeekcolor.s b/libsrc/c64/soft80_cpeekcolor.s new file mode 100644 index 000000000..c8f1c6e43 --- /dev/null +++ b/libsrc/c64/soft80_cpeekcolor.s @@ -0,0 +1,19 @@ +; +; 2017-12-27, Groepaz +; +; unsigned char cpeekcolor (void); +; + + .export soft80_cpeekcolor + + .include "c64.inc" + .include "soft80.inc" + + .segment "CODE" + +soft80_cpeekcolor: + ldy #0 + lda (CRAM_PTR),y + and #$0f + ldx #0 + rts diff --git a/libsrc/c64/soft80_cpeekrevers.s b/libsrc/c64/soft80_cpeekrevers.s new file mode 100644 index 000000000..6fc0c166a --- /dev/null +++ b/libsrc/c64/soft80_cpeekrevers.s @@ -0,0 +1,10 @@ + + .import soft80_cpeekchar + + .export soft80_cpeekrevers + +soft80_cpeekrevers: + jsr soft80_cpeekchar + txa + ldx #0 + rts diff --git a/libsrc/c64/soft80_cpeeks.s b/libsrc/c64/soft80_cpeeks.s new file mode 100644 index 000000000..837afef1e --- /dev/null +++ b/libsrc/c64/soft80_cpeeks.s @@ -0,0 +1,71 @@ +; +; 2017-12-27, groepaz +; +; void cpeeks (char* s, unsigned length); +; + .export soft80_cpeeks + .import soft80_cpeekc, soft80_kplot, popax + + .importzp ptr1, ptr2 + + .include "c64.inc" + .include "soft80.inc" + +soft80_cpeeks: + eor #<$FFFF ; counting a word upward is faster + sta ptr2 ; so, we use -(length + 1) + txa + eor #>$FFFF + sta ptr2+1 + + jsr popax + sta ptr1 + stx ptr1+1 + + ; save current cursor position + lda CURS_X + pha + lda CURS_Y + pha + + ; get the string +@lp: + jsr soft80_cpeekc + ldy #0 + sta (ptr1),y + + ; advance cursor position + ldy CURS_X + ldx CURS_Y + iny + cpy #charsperline + bne @sk2 + ldy #0 + inx +@sk2: + sty CURS_X + stx CURS_Y + clc + jsr soft80_kplot + + inc ptr1 + bne @sk + inc ptr1+1 +@sk: + inc ptr2 + bne @lp + inc ptr2+1 + bne @lp + + ; terminate the string + lda #0 + ldy #0 + sta (ptr1),y + + ; restore the cursor position + pla + tax ; CURS_Y + pla + tay ; CURS_X + clc + jmp soft80_kplot diff --git a/libsrc/c64/soft80mono_cpeekcolor.s b/libsrc/c64/soft80mono_cpeekcolor.s new file mode 100644 index 000000000..a03875a74 --- /dev/null +++ b/libsrc/c64/soft80mono_cpeekcolor.s @@ -0,0 +1,17 @@ +; +; 2017-12-27, Groepaz +; +; unsigned char cpeekcolor (void); +; + + .export soft80mono_cpeekcolor + + .include "c64.inc" + .include "soft80.inc" + + .segment "CODE" + +soft80mono_cpeekcolor: + lda CHARCOLOR + ldx #0 + rts From 142ba126348839e6a01bf160b61628a30ac4ba94 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 28 Dec 2017 01:58:58 +0100 Subject: [PATCH 0527/2161] updated testprog --- testcode/lib/cpeek-test.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/testcode/lib/cpeek-test.c b/testcode/lib/cpeek-test.c index 5f3bfc524..ffcdb8bf1 100644 --- a/testcode/lib/cpeek-test.c +++ b/testcode/lib/cpeek-test.c @@ -113,6 +113,17 @@ static unsigned char testCPeekC (char ch) return 1; } + /* toggle revers mode every few chars so cpeekc gets tested for both */ + revers ((ch >> 3) & 1); + + /* output additional space every now and then, that way not only even or only + odd half of the character cell will be tested */ +#if defined(__C64__) + if ((width == 80) && ((ch % 17) == 0)) { + cputc(' '); + } +#endif + /* Output the char to the screen. */ cputc (ch); @@ -141,8 +152,8 @@ static unsigned char testCPeekC (char ch) */ ch2_c = peekChWithoutTranslation (); if ((ch2_c != ch2_b) -#if defined(__C128__) - /* VDC memory is not accessable */ +#if defined(__C128__) || defined(__C64__) + /* VDC memory is not accessable, soft80 has no "videoram" */ && (width == 40) #endif ){ @@ -230,7 +241,7 @@ int main (void) int ret = 0; clrscr (); - revers (1); + revers (0); textcolor(1); bgcolor(0); screensize (&width, &i); @@ -261,7 +272,7 @@ int main (void) #if defined (__CBM610__) || defined (__PET__) cprintf("\n\rno COLOR_RAM\n\r"); -#elif defined (__C128__) +#elif defined (__C128__) || defined (__C64__) if (width == 40) { cprintf("\n\rCOLOR_RAM at $%04x\n\r", COLOR_RAM); } else { From f207a60365c7a226f907b3218f73e3163be1223d Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 28 Dec 2017 02:26:23 +0100 Subject: [PATCH 0528/2161] some cleanup --- libsrc/c64/soft80_cpeekc.s | 57 +++++++++------------------------ libsrc/c64/soft80_cpeekrevers.s | 5 +++ 2 files changed, 20 insertions(+), 42 deletions(-) diff --git a/libsrc/c64/soft80_cpeekc.s b/libsrc/c64/soft80_cpeekc.s index 2801ade97..63ad635e7 100644 --- a/libsrc/c64/soft80_cpeekc.s +++ b/libsrc/c64/soft80_cpeekc.s @@ -1,3 +1,8 @@ +; +; 2017-12-28, Groepaz +; +; char cpeekc (void); +; .export soft80_cpeekc, soft80_cpeekchar @@ -16,8 +21,6 @@ soft80_cpeekc: soft80_cpeekchar: sei - ;;dec $01 ;; assumed = $36 - ;;dec $01 ;; assumed = $36 lda #$34 sta $01 @@ -32,105 +35,77 @@ soft80_cpeekchar: @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 ; return char in A - ; sec -; sbc #$20 ldx #$00 ; revers flag -;inc $d020 rts @l2b: -;jmp * inx cpx #$80 jne @l2aa ; test inverted character (left side) - + ldx #0 @l2aa2: ldy #0 -;; stx $d020 - .repeat 8,line -;; jsr readdirect lda (SCREEN_PTR),y and #$f0 eor #$f0 cmp soft80_hi_charset+(line*$80),x -; cmp #0 bne @l2b2 .if (line < 7) iny .endif .endrepeat - + @backokrevers: -;inc $d020 -; inc $01 -; inc $01 lda #$36 sta $01 cli txa ; return char in A - ; sec -; sbc #$20 ldx #$01 ; revers flag -;inc $d020 rts - + @l2b2: inx cpx #$80 jne @l2aa2 - + @backerr: -;inc $d020 - ;; inc $01 -;; inc $01 lda #$36 sta $01 cli ldx #0 txa - rts ; test non-inverted character (right side) - + @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 + bne @l2bb .if line < 7 iny .endif @@ -140,19 +115,18 @@ soft80_cpeekchar: inx cpx #$80 bne @l1aa - + ; test inverted character (right side) - + ldx #0 @l1aa2: ldy #0 .repeat 8,line -;; jsr readdirect lda (SCREEN_PTR),y and #$0f eor #$0f eor soft80_lo_charset+(line*$80),x - bne @l2bb2 + bne @l2bb2 .if line < 7 iny .endif @@ -162,7 +136,6 @@ soft80_cpeekchar: inx cpx #$80 bne @l1aa2 - - + jmp @backerr diff --git a/libsrc/c64/soft80_cpeekrevers.s b/libsrc/c64/soft80_cpeekrevers.s index 6fc0c166a..779636ed5 100644 --- a/libsrc/c64/soft80_cpeekrevers.s +++ b/libsrc/c64/soft80_cpeekrevers.s @@ -1,3 +1,8 @@ +; +; 2017-12-28, Groepaz +; +; unsigned char cpeekrevers (void); +; .import soft80_cpeekchar From 30c6018887060df7286ac6d411182c4996da96a2 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 28 Dec 2017 04:54:18 +0100 Subject: [PATCH 0529/2161] Implementation of getfirstdevice/getnextdevice for Atari. --- libsrc/atari/getdevice.s | 78 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 libsrc/atari/getdevice.s diff --git a/libsrc/atari/getdevice.s b/libsrc/atari/getdevice.s new file mode 100644 index 000000000..e0e700436 --- /dev/null +++ b/libsrc/atari/getdevice.s @@ -0,0 +1,78 @@ +; +; Oliver Schmidt, 2012-09-04 +; Christian Groessler, 2017-12-28 +; +; unsigned char getfirstdevice (void); +; unsigned char __fastcall__ getnextdevice (unsigned char device); +; + + .include "atari.inc" + .export _getfirstdevice + .export _getnextdevice + +MAX_DIO_DEVICES = 8 + +;------------------------------------------------------------------------------ +; _getfirstdevice + +_getfirstdevice: + lda #$FF + ; Fall through + +;------------------------------------------------------------------------------ +; _getnextdevice + +_getnextdevice: + tax +next: inx + cpx #MAX_DIO_DEVICES + beq none + + jsr check_device + bmi next + +done: txa + ldx #$00 + rts + +none: ldx #255 ; INVALID_DEVICE (see include/device.h) + bne done ; jump always + +;------------------------------------------------------------------------------ +; check_device - checks if a disk device is present +; input: X - device id (0 = D1, 1 = D2, ...) +; output: NF - 0/1 for detected/not detected +; X register preserved + +check_device: + txa + pha + lda #SIO_STAT + sta DCOMND ; set command into DCB + lda #%01000000 ; direction value, "receive data" + sta DSTATS ; set data flow directon + lda #15 + sta DTIMLO ; value got from DOS source + lda #4 + sta DAUX1 ; set sector # (dummy: 4) + sta DBYTLO ; # of bytes to transfer + lda #0 + sta DAUX2 + sta DBYTHI + lda #>DVSTAT + sta DBUFHI + lda #<DVSTAT + sta DBUFLO ; set buffer address into DCB + lda #DISKID ; SIO bus ID of diskette drive + sta DDEVIC + inx + stx DUNIT ; unit number (1-based) + + jsr SIOV ; execute SIO command + + pla + tax + lda DSTATS + rts + + .end From 783408080cd89ec954b5bab65d56625e90b9294e Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 28 Dec 2017 17:52:27 +0100 Subject: [PATCH 0530/2161] convert to petscii --- libsrc/c64/soft80_cpeekc.s | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libsrc/c64/soft80_cpeekc.s b/libsrc/c64/soft80_cpeekc.s index 63ad635e7..576d50fc1 100644 --- a/libsrc/c64/soft80_cpeekc.s +++ b/libsrc/c64/soft80_cpeekc.s @@ -15,6 +15,13 @@ soft80_cpeekc: jsr soft80_cpeekchar + ; 0-1F -> A0-BF + ; 20-7F -> 20-7F + cmp #$20 + bcs @sk + ;clc + adc #$a0 +@sk: ldx #0 rts From b08839cac4ba6386b2227782131f1f264dbe5719 Mon Sep 17 00:00:00 2001 From: bauen1 <j2468h@gmail.com> Date: Sun, 31 Dec 2017 15:49:17 +0100 Subject: [PATCH 0531/2161] Added libray to none target --- doc/customizing.sgml | 41 +++++++++++++++++++---------------------- libsrc/Makefile | 3 ++- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/doc/customizing.sgml b/doc/customizing.sgml index e502f2e9d..d8f6ef6be 100644 --- a/doc/customizing.sgml +++ b/doc/customizing.sgml @@ -302,23 +302,20 @@ also forcing a BRK instruction into the CPU. <sect>Custom Run-Time Library Creation<p> The next step in customizing the cc65 toolset is creating a run-time -library for the targeted hardware. The easiest way to do this is to -modify a standard library from the cc65 distribution. In this example, -there is no console I/O, mouse, joystick, etc. in the system, so it is -most appropriate to use the simplest library as the base, which is for -the Watara Supervision and is named "supervision.lib" in the -lib directory of the distribution. +library for the targeted hardware. The recommended way to do this is to +modify the platform-independent standard library of the cc65 distribution. +It is named "none.lib" in the lib directory of the distribution. -The only modification required is to replace the <tt>crt0</tt> module in -the supervision.lib library with custom startup code. This is simply -done by first copying the library and giving it a new name, compiling -the startup code with ca65, and finally using the ar65 archiver to -replace the module in the new library. The steps are shown below: +When using "none.lib" we need to supply our own <tt>crt0<tt> +module with custom startup code. This is simply done by first copying the +the library and giving it a new name, compiling the startup code with ca65, +and finally using the ar65 archiver to add the module to the new library. +The steps are shown below: <tscreen><verb> -$ copy "C:\Program Files\cc65\lib\supervision.lib" sbc.lib -$ ca65 crt0.s -$ ar65 a sbc.lib crt0.o + cp /usr/local/share/cc65/lib/none.lib sbc.lib + ca65 crt0.s + ar65 a sbc.lib crt0.o </verb></tscreen> <sect>Interrupt Service Routine Definition<p> @@ -706,14 +703,14 @@ that can be used as the initialization data for the Xilinx Block RAM used for code storage: <tscreen><verb> -$ cc65 -t none -O --cpu 65sc02 main.c -$ ca65 --cpu 65sc02 main.s -$ ca65 --cpu 65sc02 rs232_tx.s -$ ca65 --cpu 65sc02 interrupt.s -$ ca65 --cpu 65sc02 vectors.s -$ ca65 --cpu 65sc02 wait.s -$ ld65 -C sbc.cfg -m main.map interrupt.o vectors.o wait.o rs232_tx.o - main.o sbc.lib + cc65 -t none -O --cpu 65sc02 main.c + ca65 --cpu 65sc02 main.s + ca65 --cpu 65sc02 rs232_tx.s + ca65 --cpu 65sc02 interrupt.s + ca65 --cpu 65sc02 vectors.s + ca65 --cpu 65sc02 wait.s + ld65 -C sbc.cfg -m main.map interrupt.o vectors.o wait.o + rs232_tx.o main.o sbc.lib </verb></tscreen> During the C-level code compilation phase (<tt>cc65</tt>), assumptions diff --git a/libsrc/Makefile b/libsrc/Makefile index 0583b6761..2ac0c78f0 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -32,7 +32,8 @@ TARGETS = apple2 \ sim6502 \ sim65c02 \ supervision \ - telestrat + telestrat \ + none DRVTYPES = emd \ joy \ From d9ba279e8935e61181249fd088af33b9c021fb70 Mon Sep 17 00:00:00 2001 From: bauen1 <j2468h@gmail.com> Date: Mon, 1 Jan 2018 01:34:53 +0100 Subject: [PATCH 0532/2161] Fixed a typo in doc/customizing.sqml --- doc/customizing.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/customizing.sgml b/doc/customizing.sgml index d8f6ef6be..1ae49f3c0 100644 --- a/doc/customizing.sgml +++ b/doc/customizing.sgml @@ -306,7 +306,7 @@ library for the targeted hardware. The recommended way to do this is to modify the platform-independent standard library of the cc65 distribution. It is named "none.lib" in the lib directory of the distribution. -When using "none.lib" we need to supply our own <tt>crt0<tt> +When using "none.lib" we need to supply our own <tt>crt0</tt> module with custom startup code. This is simply done by first copying the the library and giving it a new name, compiling the startup code with ca65, and finally using the ar65 archiver to add the module to the new library. From 4abe12c729330dda3822b0356dbdf0737829d097 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 1 Jan 2018 14:01:25 +0100 Subject: [PATCH 0533/2161] fix spelling --- testcode/lib/cpeek-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testcode/lib/cpeek-test.c b/testcode/lib/cpeek-test.c index ffcdb8bf1..aef4cb4e3 100644 --- a/testcode/lib/cpeek-test.c +++ b/testcode/lib/cpeek-test.c @@ -153,7 +153,7 @@ static unsigned char testCPeekC (char ch) ch2_c = peekChWithoutTranslation (); if ((ch2_c != ch2_b) #if defined(__C128__) || defined(__C64__) - /* VDC memory is not accessable, soft80 has no "videoram" */ + /* VDC memory is not accessible, soft80 has no "videoram" */ && (width == 40) #endif ){ From 040134e7750f81a6a3b54856c4a1bf38d9244b5c Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 2 Jan 2018 13:48:30 +0100 Subject: [PATCH 0534/2161] Fixed typo. --- testcode/lib/cpeek-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testcode/lib/cpeek-test.c b/testcode/lib/cpeek-test.c index aef4cb4e3..1777bce4a 100644 --- a/testcode/lib/cpeek-test.c +++ b/testcode/lib/cpeek-test.c @@ -209,7 +209,7 @@ static unsigned char testCPeekCol (char ch) ch2_c = peekColWithoutTranslation (); if ((ch2_c != ch2_b) #if defined(__C128__) - /* VDC memory is not accessable */ + /* VDC memory is not accessible */ && (width == 40) #endif ){ From 26350714ee3a78771061b77b6d20a472f1e40585 Mon Sep 17 00:00:00 2001 From: bauen1 <j2468h@gmail.com> Date: Tue, 2 Jan 2018 15:15:27 +0100 Subject: [PATCH 0535/2161] Renamed none.lib to no-platform.lib --- doc/customizing.sgml | 9 ++++----- libsrc/Makefile | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/doc/customizing.sgml b/doc/customizing.sgml index 1ae49f3c0..29c525e00 100644 --- a/doc/customizing.sgml +++ b/doc/customizing.sgml @@ -81,7 +81,6 @@ SEGMENTS { ZEROPAGE: load = ZP, type = zp, define = yes; DATA: load = ROM, type = rw, define = yes, run = RAM; BSS: load = RAM, type = bss, define = yes; - HEAP: load = RAM, type = bss, optional = yes; STARTUP: load = ROM, type = ro; ONCE: load = ROM, type = ro, optional = yes; CODE: load = ROM, type = ro; @@ -95,7 +94,6 @@ The meaning of each of these segments is as follows. <p><tt> ZEROPAGE: </tt>Data in page 0, defined by ZP as starting at $0 with length $100 <p><tt> DATA: </tt>Initialized data that can be modified by the program, stored in RAM <p><tt> BSS: </tt>Uninitialized data stored in RAM (used for variable storage) -<p><tt> HEAP: </tt>Uninitialized C-level heap storage in RAM, optional <p><tt> STARTUP: </tt>The program initialization code, stored in ROM <p><tt> ONCE: </tt>The code run once to initialize the system, stored in ROM <p><tt> CODE: </tt>The program code, stored in ROM @@ -304,16 +302,17 @@ also forcing a BRK instruction into the CPU. The next step in customizing the cc65 toolset is creating a run-time library for the targeted hardware. The recommended way to do this is to modify the platform-independent standard library of the cc65 distribution. -It is named "none.lib" in the lib directory of the distribution. +It is named "no-platform.lib" in the lib directory of the +cc65 distribution. -When using "none.lib" we need to supply our own <tt>crt0</tt> +When using "no-platform.lib" we need to supply our own <tt>crt0</tt> module with custom startup code. This is simply done by first copying the the library and giving it a new name, compiling the startup code with ca65, and finally using the ar65 archiver to add the module to the new library. The steps are shown below: <tscreen><verb> - cp /usr/local/share/cc65/lib/none.lib sbc.lib + cp /usr/local/share/cc65/lib/no-platform.lib sbc.lib ca65 crt0.s ar65 a sbc.lib crt0.o </verb></tscreen> diff --git a/libsrc/Makefile b/libsrc/Makefile index 2ac0c78f0..c742ad0c7 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -33,7 +33,7 @@ TARGETS = apple2 \ sim65c02 \ supervision \ telestrat \ - none + no-platform DRVTYPES = emd \ joy \ From 72bb32fcda47e24b584e13666ab675d19d9d4a8b Mon Sep 17 00:00:00 2001 From: bauen1 <j2468h@gmail.com> Date: Tue, 2 Jan 2018 15:32:27 +0100 Subject: [PATCH 0536/2161] Revert "Renamed none.lib to no-platform.lib" This reverts commit 26350714ee3a78771061b77b6d20a472f1e40585. It breaks the build --- doc/customizing.sgml | 7 +++---- libsrc/Makefile | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/doc/customizing.sgml b/doc/customizing.sgml index 29c525e00..5eb73b648 100644 --- a/doc/customizing.sgml +++ b/doc/customizing.sgml @@ -302,17 +302,16 @@ also forcing a BRK instruction into the CPU. The next step in customizing the cc65 toolset is creating a run-time library for the targeted hardware. The recommended way to do this is to modify the platform-independent standard library of the cc65 distribution. -It is named "no-platform.lib" in the lib directory of the -cc65 distribution. +It is named "none.lib" in the lib directory of the distribution. -When using "no-platform.lib" we need to supply our own <tt>crt0</tt> +When using "none.lib" we need to supply our own <tt>crt0</tt> module with custom startup code. This is simply done by first copying the the library and giving it a new name, compiling the startup code with ca65, and finally using the ar65 archiver to add the module to the new library. The steps are shown below: <tscreen><verb> - cp /usr/local/share/cc65/lib/no-platform.lib sbc.lib + cp /usr/local/share/cc65/lib/none.lib sbc.lib ca65 crt0.s ar65 a sbc.lib crt0.o </verb></tscreen> diff --git a/libsrc/Makefile b/libsrc/Makefile index c742ad0c7..2ac0c78f0 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -33,7 +33,7 @@ TARGETS = apple2 \ sim65c02 \ supervision \ telestrat \ - no-platform + none DRVTYPES = emd \ joy \ From 14909f12fed0a2f5687ca4152116404234308d09 Mon Sep 17 00:00:00 2001 From: bauen1 <j2468h@gmail.com> Date: Thu, 4 Jan 2018 11:17:20 +0100 Subject: [PATCH 0537/2161] Implemented the requested changes. Moved none to its alphabetic place in the Makefile Reverted all changes to doc/customizing.sgml --- doc/customizing.sgml | 43 ++++++++++++++++++++++++------------------- libsrc/Makefile | 4 ++-- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/doc/customizing.sgml b/doc/customizing.sgml index 5eb73b648..e502f2e9d 100644 --- a/doc/customizing.sgml +++ b/doc/customizing.sgml @@ -81,6 +81,7 @@ SEGMENTS { ZEROPAGE: load = ZP, type = zp, define = yes; DATA: load = ROM, type = rw, define = yes, run = RAM; BSS: load = RAM, type = bss, define = yes; + HEAP: load = RAM, type = bss, optional = yes; STARTUP: load = ROM, type = ro; ONCE: load = ROM, type = ro, optional = yes; CODE: load = ROM, type = ro; @@ -94,6 +95,7 @@ The meaning of each of these segments is as follows. <p><tt> ZEROPAGE: </tt>Data in page 0, defined by ZP as starting at $0 with length $100 <p><tt> DATA: </tt>Initialized data that can be modified by the program, stored in RAM <p><tt> BSS: </tt>Uninitialized data stored in RAM (used for variable storage) +<p><tt> HEAP: </tt>Uninitialized C-level heap storage in RAM, optional <p><tt> STARTUP: </tt>The program initialization code, stored in ROM <p><tt> ONCE: </tt>The code run once to initialize the system, stored in ROM <p><tt> CODE: </tt>The program code, stored in ROM @@ -300,20 +302,23 @@ also forcing a BRK instruction into the CPU. <sect>Custom Run-Time Library Creation<p> The next step in customizing the cc65 toolset is creating a run-time -library for the targeted hardware. The recommended way to do this is to -modify the platform-independent standard library of the cc65 distribution. -It is named "none.lib" in the lib directory of the distribution. +library for the targeted hardware. The easiest way to do this is to +modify a standard library from the cc65 distribution. In this example, +there is no console I/O, mouse, joystick, etc. in the system, so it is +most appropriate to use the simplest library as the base, which is for +the Watara Supervision and is named "supervision.lib" in the +lib directory of the distribution. -When using "none.lib" we need to supply our own <tt>crt0</tt> -module with custom startup code. This is simply done by first copying the -the library and giving it a new name, compiling the startup code with ca65, -and finally using the ar65 archiver to add the module to the new library. -The steps are shown below: +The only modification required is to replace the <tt>crt0</tt> module in +the supervision.lib library with custom startup code. This is simply +done by first copying the library and giving it a new name, compiling +the startup code with ca65, and finally using the ar65 archiver to +replace the module in the new library. The steps are shown below: <tscreen><verb> - cp /usr/local/share/cc65/lib/none.lib sbc.lib - ca65 crt0.s - ar65 a sbc.lib crt0.o +$ copy "C:\Program Files\cc65\lib\supervision.lib" sbc.lib +$ ca65 crt0.s +$ ar65 a sbc.lib crt0.o </verb></tscreen> <sect>Interrupt Service Routine Definition<p> @@ -701,14 +706,14 @@ that can be used as the initialization data for the Xilinx Block RAM used for code storage: <tscreen><verb> - cc65 -t none -O --cpu 65sc02 main.c - ca65 --cpu 65sc02 main.s - ca65 --cpu 65sc02 rs232_tx.s - ca65 --cpu 65sc02 interrupt.s - ca65 --cpu 65sc02 vectors.s - ca65 --cpu 65sc02 wait.s - ld65 -C sbc.cfg -m main.map interrupt.o vectors.o wait.o - rs232_tx.o main.o sbc.lib +$ cc65 -t none -O --cpu 65sc02 main.c +$ ca65 --cpu 65sc02 main.s +$ ca65 --cpu 65sc02 rs232_tx.s +$ ca65 --cpu 65sc02 interrupt.s +$ ca65 --cpu 65sc02 vectors.s +$ ca65 --cpu 65sc02 wait.s +$ ld65 -C sbc.cfg -m main.map interrupt.o vectors.o wait.o rs232_tx.o + main.o sbc.lib </verb></tscreen> During the C-level code compilation phase (<tt>cc65</tt>), assumptions diff --git a/libsrc/Makefile b/libsrc/Makefile index 2ac0c78f0..0d0cd320b 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -27,13 +27,13 @@ TARGETS = apple2 \ gamate \ lynx \ nes \ + none \ osic1p \ pce \ sim6502 \ sim65c02 \ supervision \ - telestrat \ - none + telestrat DRVTYPES = emd \ joy \ From 98b2b2544db2390978c0532040a7922ed7d55bc2 Mon Sep 17 00:00:00 2001 From: bauen1 <j2468h@gmail.com> Date: Thu, 4 Jan 2018 12:07:35 +0100 Subject: [PATCH 0538/2161] Added crt0 to none.lib --- cfg/none.cfg | 1 + libsrc/none/crt0.s | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 libsrc/none/crt0.s diff --git a/cfg/none.cfg b/cfg/none.cfg index 6742da7c8..44bbcdfec 100644 --- a/cfg/none.cfg +++ b/cfg/none.cfg @@ -7,6 +7,7 @@ MEMORY { } 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; diff --git a/libsrc/none/crt0.s b/libsrc/none/crt0.s new file mode 100644 index 000000000..fb26fb2af --- /dev/null +++ b/libsrc/none/crt0.s @@ -0,0 +1,25 @@ + .export _exit + .export __STARTUP__ : absolute = 1 ; Mark as startup + .import zerobss, _main + .import initlib, donelib + .import __MAIN_START__, __MAIN_SIZE__ ; Linker generated + .import __STACKSIZE__ ; Linker generated + + .include "zeropage.inc" + + .segment "STARTUP" + + cld + ldx #$FF + txs + lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) + ldx #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) + sta sp + stx sp+1 + jsr zerobss + jsr initlib + jsr _main +_exit: pha + jsr donelib + pla + brk From 884dfcf3c15672fc7caa9b0b709d49b3f2672ca6 Mon Sep 17 00:00:00 2001 From: bauen1 <j2468h@gmail.com> Date: Thu, 4 Jan 2018 12:22:42 +0100 Subject: [PATCH 0539/2161] Fixed none.lib missing symbols --- cfg/none.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/none.cfg b/cfg/none.cfg index 44bbcdfec..cb8dbd400 100644 --- a/cfg/none.cfg +++ b/cfg/none.cfg @@ -3,7 +3,7 @@ SYMBOLS { } MEMORY { ZP: file = "", define = yes, start = $0000, size = $0001F; - MAIN: file = %O, start = %S, size = $10000 - __STACKSIZE__; + MAIN: file = %O, start = %S, size = $10000 - __STACKSIZE__, define = yes; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; From 4759d3956e50d18b85c1a650777d0b6bd0bda90f Mon Sep 17 00:00:00 2001 From: bauen1 <j2468h@gmail.com> Date: Thu, 4 Jan 2018 13:54:00 +0100 Subject: [PATCH 0540/2161] Removed initialization of the stack from none.lib --- libsrc/none/crt0.s | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libsrc/none/crt0.s b/libsrc/none/crt0.s index fb26fb2af..7858ad839 100644 --- a/libsrc/none/crt0.s +++ b/libsrc/none/crt0.s @@ -9,9 +9,6 @@ .segment "STARTUP" - cld - ldx #$FF - txs lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) sta sp @@ -22,4 +19,4 @@ _exit: pha jsr donelib pla - brk + rts From 60c68b11113f40da67b5ddae379c0b571d4f2bc7 Mon Sep 17 00:00:00 2001 From: bauen1 <j2468h@gmail.com> Date: Thu, 4 Jan 2018 17:11:44 +0100 Subject: [PATCH 0541/2161] cl65 now links against none.lib when using --target none --- src/cl65/main.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index 565f20b45..5a2103b24 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -380,19 +380,14 @@ static void CmdPrint (CmdDesc* Cmd, FILE* F) static void SetTargetFiles (void) /* Set the target system files */ { - /* Determine the names of the target specific library file */ - if (Target != TGT_NONE) { + /* Get a pointer to the system name and its length */ + const char* TargetName = GetTargetName (Target); + unsigned TargetNameLen = strlen (TargetName); - /* Get a pointer to the system name and its length */ - const char* TargetName = GetTargetName (Target); - unsigned TargetNameLen = strlen (TargetName); - - /* Set the library file */ - TargetLib = xmalloc (TargetNameLen + 4 + 1); - memcpy (TargetLib, TargetName, TargetNameLen); - strcpy (TargetLib + TargetNameLen, ".lib"); - - } + /* Set the library file */ + TargetLib = xmalloc (TargetNameLen + 4 + 1); + memcpy (TargetLib, TargetName, TargetNameLen); + strcpy (TargetLib + TargetNameLen, ".lib"); } From ef993f2fcf0fde941a40e0fd6022596b6558e0a9 Mon Sep 17 00:00:00 2001 From: bauen1 <j2468h@gmail.com> Date: Thu, 4 Jan 2018 21:29:58 +0100 Subject: [PATCH 0542/2161] none.cfg consistency changes --- cfg/none.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/none.cfg b/cfg/none.cfg index cb8dbd400..f82e9707f 100644 --- a/cfg/none.cfg +++ b/cfg/none.cfg @@ -3,7 +3,7 @@ SYMBOLS { } MEMORY { ZP: file = "", define = yes, start = $0000, size = $0001F; - MAIN: file = %O, start = %S, size = $10000 - __STACKSIZE__, define = yes; + MAIN: file = %O, define = yes, start = %S, size = $10000 - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; From cea833208454a9667eebc2361df56cfd4184822c Mon Sep 17 00:00:00 2001 From: bauen1 <j2468h@gmail.com> Date: Thu, 4 Jan 2018 22:01:44 +0100 Subject: [PATCH 0543/2161] Fixed none.cfg --- cfg/none.cfg | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/cfg/none.cfg b/cfg/none.cfg index f82e9707f..26f5379cd 100644 --- a/cfg/none.cfg +++ b/cfg/none.cfg @@ -1,9 +1,14 @@ +FEATURES { + STARTADDRESS: default = $1000; +} SYMBOLS { - __STACKSIZE__: type = weak, value = $0800; # 2k stack + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __STACKSTART__: type = weak, value = $8000; + __ZPSTART__: type = weak, value = $0080; } MEMORY { - ZP: file = "", define = yes, start = $0000, size = $0001F; - MAIN: file = %O, define = yes, start = %S, size = $10000 - __STACKSIZE__; + ZP: file = "", define = yes, start = __ZPSTART__, size = $001F; + MAIN: file = %O, define = yes, start = %S, size = __STACKSTART__ - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; From 45482b4fb1fdf69d149cbdd5aa7aafdbc816020d Mon Sep 17 00:00:00 2001 From: bauen1 <j2468h@gmail.com> Date: Thu, 4 Jan 2018 22:14:01 +0100 Subject: [PATCH 0544/2161] Fixed none/crt0.s to respect none.cfg --- libsrc/none/crt0.s | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libsrc/none/crt0.s b/libsrc/none/crt0.s index 7858ad839..a90f60d26 100644 --- a/libsrc/none/crt0.s +++ b/libsrc/none/crt0.s @@ -2,15 +2,14 @@ .export __STARTUP__ : absolute = 1 ; Mark as startup .import zerobss, _main .import initlib, donelib - .import __MAIN_START__, __MAIN_SIZE__ ; Linker generated - .import __STACKSIZE__ ; Linker generated + .import __STACKSTART__, __STACKSIZE__ ; Linker generated .include "zeropage.inc" .segment "STARTUP" - lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - ldx #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) + lda #<__STACKSTART__ + lda #>__STACKSTART__ sta sp stx sp+1 jsr zerobss From aa34aed7dd87984dda900f3b171a87da3d361095 Mon Sep 17 00:00:00 2001 From: bauen1 <j2468h@gmail.com> Date: Thu, 4 Jan 2018 22:27:39 +0100 Subject: [PATCH 0545/2161] Fixed unused import and export of none.cfg and none/crt0.s --- cfg/none.cfg | 2 +- libsrc/none/crt0.s | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cfg/none.cfg b/cfg/none.cfg index 26f5379cd..cedd2d839 100644 --- a/cfg/none.cfg +++ b/cfg/none.cfg @@ -8,7 +8,7 @@ SYMBOLS { } MEMORY { ZP: file = "", define = yes, start = __ZPSTART__, size = $001F; - MAIN: file = %O, define = yes, start = %S, size = __STACKSTART__ - __STACKSIZE__; + MAIN: file = %O, start = %S, size = __STACKSTART__ - __STACKSIZE__ - %S; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; diff --git a/libsrc/none/crt0.s b/libsrc/none/crt0.s index a90f60d26..288d0dc29 100644 --- a/libsrc/none/crt0.s +++ b/libsrc/none/crt0.s @@ -2,7 +2,7 @@ .export __STARTUP__ : absolute = 1 ; Mark as startup .import zerobss, _main .import initlib, donelib - .import __STACKSTART__, __STACKSIZE__ ; Linker generated + .import __STACKSTART__ ; Linker generated .include "zeropage.inc" From 94077404f9ecd6fd6d4354509bfbd3f34a1a63a5 Mon Sep 17 00:00:00 2001 From: bauen1 <j2468h@gmail.com> Date: Fri, 5 Jan 2018 10:39:23 +0100 Subject: [PATCH 0546/2161] Added ctype.s to none.lib as suggested by oliverschmidt --- libsrc/none/ctype.s | 159 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 libsrc/none/ctype.s diff --git a/libsrc/none/ctype.s b/libsrc/none/ctype.s new file mode 100644 index 000000000..35968f982 --- /dev/null +++ b/libsrc/none/ctype.s @@ -0,0 +1,159 @@ +; +; Ullrich von Bassewitz, 2003-10-10 +; +; Character specification table. +; + + .include "ctype.inc" + +; The tables are readonly, put them into the rodata segment + +.rodata + +; The following 256 byte wide table specifies attributes for the isxxx type +; of functions. Doing it by a table means some overhead in space, but it +; has major advantages: +; +; * It is fast. If it weren't for the slow parameter passing of cc65, one +; could even define macros for the isxxx functions (this is usually +; done on other platforms). +; +; * It is highly portable. The only unportable part is the table itself, +; all real code goes into the common library. +; +; * We save some code in the isxxx functions. + + +__ctype: + .byte CT_CTRL ; 0/00 ___ctrl_@___ + .byte CT_CTRL ; 1/01 ___ctrl_A___ + .byte CT_CTRL ; 2/02 ___ctrl_B___ + .byte CT_CTRL ; 3/03 ___ctrl_C___ + .byte CT_CTRL ; 4/04 ___ctrl_D___ + .byte CT_CTRL ; 5/05 ___ctrl_E___ + .byte CT_CTRL ; 6/06 ___ctrl_F___ + .byte CT_CTRL ; 7/07 ___ctrl_G___ + .byte CT_CTRL ; 8/08 ___ctrl_H___ + .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB + ; 9/09 ___ctrl_I___ + .byte CT_CTRL | CT_OTHER_WS ; 10/0a ___ctrl_J___ + .byte CT_CTRL | CT_OTHER_WS ; 11/0b ___ctrl_K___ + .byte CT_CTRL | CT_OTHER_WS ; 12/0c ___ctrl_L___ + .byte CT_CTRL | CT_OTHER_WS ; 13/0d ___ctrl_M___ + .byte CT_CTRL ; 14/0e ___ctrl_N___ + .byte CT_CTRL ; 15/0f ___ctrl_O___ + .byte CT_CTRL ; 16/10 ___ctrl_P___ + .byte CT_CTRL ; 17/11 ___ctrl_Q___ + .byte CT_CTRL ; 18/12 ___ctrl_R___ + .byte CT_CTRL ; 19/13 ___ctrl_S___ + .byte CT_CTRL ; 20/14 ___ctrl_T___ + .byte CT_CTRL ; 21/15 ___ctrl_U___ + .byte CT_CTRL ; 22/16 ___ctrl_V___ + .byte CT_CTRL ; 23/17 ___ctrl_W___ + .byte CT_CTRL ; 24/18 ___ctrl_X___ + .byte CT_CTRL ; 25/19 ___ctrl_Y___ + .byte CT_CTRL ; 26/1a ___ctrl_Z___ + .byte CT_CTRL ; 27/1b ___ctrl_[___ + .byte CT_CTRL ; 28/1c ___ctrl_\___ + .byte CT_CTRL ; 29/1d ___ctrl_]___ + .byte CT_CTRL ; 30/1e ___ctrl_^___ + .byte CT_CTRL ; 31/1f ___ctrl_____ + .byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___ + .byte CT_NONE ; 33/21 _____!_____ + .byte CT_NONE ; 34/22 _____"_____ + .byte CT_NONE ; 35/23 _____#_____ + .byte CT_NONE ; 36/24 _____$_____ + .byte CT_NONE ; 37/25 _____%_____ + .byte CT_NONE ; 38/26 _____&_____ + .byte CT_NONE ; 39/27 _____'_____ + .byte CT_NONE ; 40/28 _____(_____ + .byte CT_NONE ; 41/29 _____)_____ + .byte CT_NONE ; 42/2a _____*_____ + .byte CT_NONE ; 43/2b _____+_____ + .byte CT_NONE ; 44/2c _____,_____ + .byte CT_NONE ; 45/2d _____-_____ + .byte CT_NONE ; 46/2e _____._____ + .byte CT_NONE ; 47/2f _____/_____ + .byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____ + .byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____ + .byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____ + .byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____ + .byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____ + .byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____ + .byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____ + .byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____ + .byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____ + .byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____ + .byte CT_NONE ; 58/3a _____:_____ + .byte CT_NONE ; 59/3b _____;_____ + .byte CT_NONE ; 60/3c _____<_____ + .byte CT_NONE ; 61/3d _____=_____ + .byte CT_NONE ; 62/3e _____>_____ + .byte CT_NONE ; 63/3f _____?_____ + + .byte CT_NONE ; 64/40 _____@_____ + .byte CT_UPPER | CT_XDIGIT ; 65/41 _____A_____ + .byte CT_UPPER | CT_XDIGIT ; 66/42 _____B_____ + .byte CT_UPPER | CT_XDIGIT ; 67/43 _____C_____ + .byte CT_UPPER | CT_XDIGIT ; 68/44 _____D_____ + .byte CT_UPPER | CT_XDIGIT ; 69/45 _____E_____ + .byte CT_UPPER | CT_XDIGIT ; 70/46 _____F_____ + .byte CT_UPPER ; 71/47 _____G_____ + .byte CT_UPPER ; 72/48 _____H_____ + .byte CT_UPPER ; 73/49 _____I_____ + .byte CT_UPPER ; 74/4a _____J_____ + .byte CT_UPPER ; 75/4b _____K_____ + .byte CT_UPPER ; 76/4c _____L_____ + .byte CT_UPPER ; 77/4d _____M_____ + .byte CT_UPPER ; 78/4e _____N_____ + .byte CT_UPPER ; 79/4f _____O_____ + .byte CT_UPPER ; 80/50 _____P_____ + .byte CT_UPPER ; 81/51 _____Q_____ + .byte CT_UPPER ; 82/52 _____R_____ + .byte CT_UPPER ; 83/53 _____S_____ + .byte CT_UPPER ; 84/54 _____T_____ + .byte CT_UPPER ; 85/55 _____U_____ + .byte CT_UPPER ; 86/56 _____V_____ + .byte CT_UPPER ; 87/57 _____W_____ + .byte CT_UPPER ; 88/58 _____X_____ + .byte CT_UPPER ; 89/59 _____Y_____ + .byte CT_UPPER ; 90/5a _____Z_____ + .byte CT_NONE ; 91/5b _____[_____ + .byte CT_NONE ; 92/5c _____\_____ + .byte CT_NONE ; 93/5d _____]_____ + .byte CT_NONE ; 94/5e _____^_____ + .byte CT_NONE ; 95/5f _UNDERLINE_ + .byte CT_NONE ; 96/60 ___grave___ + .byte CT_LOWER | CT_XDIGIT ; 97/61 _____a_____ + .byte CT_LOWER | CT_XDIGIT ; 98/62 _____b_____ + .byte CT_LOWER | CT_XDIGIT ; 99/63 _____c_____ + .byte CT_LOWER | CT_XDIGIT ; 100/64 _____d_____ + .byte CT_LOWER | CT_XDIGIT ; 101/65 _____e_____ + .byte CT_LOWER | CT_XDIGIT ; 102/66 _____f_____ + .byte CT_LOWER ; 103/67 _____g_____ + .byte CT_LOWER ; 104/68 _____h_____ + .byte CT_LOWER ; 105/69 _____i_____ + .byte CT_LOWER ; 106/6a _____j_____ + .byte CT_LOWER ; 107/6b _____k_____ + .byte CT_LOWER ; 108/6c _____l_____ + .byte CT_LOWER ; 109/6d _____m_____ + .byte CT_LOWER ; 110/6e _____n_____ + .byte CT_LOWER ; 111/6f _____o_____ + .byte CT_LOWER ; 112/70 _____p_____ + .byte CT_LOWER ; 113/71 _____q_____ + .byte CT_LOWER ; 114/72 _____r_____ + .byte CT_LOWER ; 115/73 _____s_____ + .byte CT_LOWER ; 116/74 _____t_____ + .byte CT_LOWER ; 117/75 _____u_____ + .byte CT_LOWER ; 118/76 _____v_____ + .byte CT_LOWER ; 119/77 _____w_____ + .byte CT_LOWER ; 120/78 _____x_____ + .byte CT_LOWER ; 121/79 _____y_____ + .byte CT_LOWER ; 122/7a _____z_____ + .byte CT_NONE ; 123/7b _____{_____ + .byte CT_NONE ; 124/7c _____|_____ + .byte CT_NONE ; 125/7d _____}_____ + .byte CT_NONE ; 126/7e _____~_____ + .byte CT_OTHER_WS ; 127/7f ____DEL____ + + .res 128, CT_NONE ; 128-255 From e7aabce8e9724ed6493abfac1329f9c8a4634a54 Mon Sep 17 00:00:00 2001 From: prandeamus <prandeamus@btinternet.com> Date: Sun, 7 Jan 2018 18:57:48 +0000 Subject: [PATCH 0547/2161] Complain if unsupported flags are provided after -O --- src/cc65/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cc65/main.c b/src/cc65/main.c index d3d298876..f8361f41c 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -986,6 +986,9 @@ int main (int argc, char* argv[]) case 's': IS_Set (&InlineStdFuncs, 1); break; + default: + UnknownOption (Arg); + break; } } break; From da22c90d33fcd4466f770f54755dbb886530f6ee Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 9 Jan 2018 04:48:39 -0500 Subject: [PATCH 0548/2161] Shrank Telestrat initcwd.s by 3 bytes. Changing when a loop test is done allowed the removal of an extra STA instruction. --- libsrc/telestrat/initcwd.s | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/libsrc/telestrat/initcwd.s b/libsrc/telestrat/initcwd.s index f359ebeb4..dc3c53257 100644 --- a/libsrc/telestrat/initcwd.s +++ b/libsrc/telestrat/initcwd.s @@ -10,22 +10,19 @@ initcwd: - ldx #PWD_PTR BRK_TELEMON XVARS - + sta ptr1 sty ptr1+1 - + ldy #$00 - -loop: +loop: lda (ptr1),y - beq done sta __cwd,y + beq done iny bne loop - -done: - sta __cwd,y + +done: rts From c67e90dd19497286f02e02f9c0d2641a509ddaa6 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 8 Jan 2018 12:47:00 -0500 Subject: [PATCH 0549/2161] Changed the type of a compiler variable that holds either integers or pointers. The change allows cc65 to be compiled on 64-bit Windows, without getting warnings. That OS is actually 32 bits with 64-bit pointers. Its pointers are "long long" instead of "long". The change uses type-names that are configured for the actual pointer width. --- src/cc65/codegen.c | 19 ++++++++++--------- src/cc65/codegen.h | 13 +++++++------ src/cc65/expr.c | 10 +++++----- src/cc65/exprdesc.c | 3 +-- src/cc65/exprdesc.h | 3 ++- src/common/inttypes.h | 21 ++++++++++----------- 6 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index dfc06fccc..9e5102728 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -40,6 +40,7 @@ /* common */ #include "check.h" #include "cpu.h" +#include "inttypes.h" #include "strbuf.h" #include "xmalloc.h" #include "xsprintf.h" @@ -92,7 +93,7 @@ static void CheckLocalOffs (unsigned Offs) -static const char* GetLabelName (unsigned Flags, unsigned long Label, long Offs) +static const char* GetLabelName (unsigned Flags, uintptr_t Label, long Offs) { static char Buf [256]; /* Label name */ @@ -119,7 +120,7 @@ static const char* GetLabelName (unsigned Flags, unsigned long Label, long Offs) case CF_ABSOLUTE: /* Absolute address */ - xsprintf (Buf, sizeof (Buf), "$%04X", (int)((Label+Offs) & 0xFFFF)); + xsprintf (Buf, sizeof (Buf), "$%04X", (unsigned)((Label+Offs) & 0xFFFF)); break; case CF_REGVAR: @@ -729,7 +730,7 @@ void g_getimmed (unsigned Flags, unsigned long Val, long Offs) -void g_getstatic (unsigned flags, unsigned long label, long offs) +void g_getstatic (unsigned flags, uintptr_t label, long offs) /* Fetch an static memory cell into the primary register */ { /* Create the correct label name */ @@ -1008,7 +1009,7 @@ void g_leavariadic (int Offs) -void g_putstatic (unsigned flags, unsigned long label, long offs) +void g_putstatic (unsigned flags, uintptr_t label, long offs) /* Store the primary register into the specified static memory cell */ { /* Create the correct label name */ @@ -1584,7 +1585,7 @@ void g_addlocal (unsigned flags, int offs) -void g_addstatic (unsigned flags, unsigned long label, long offs) +void g_addstatic (unsigned flags, uintptr_t label, long offs) /* Add a static variable to ax */ { unsigned L; @@ -1634,7 +1635,7 @@ void g_addstatic (unsigned flags, unsigned long label, long offs) -void g_addeqstatic (unsigned flags, unsigned long label, long offs, +void g_addeqstatic (unsigned flags, uintptr_t label, long offs, unsigned long val) /* Emit += for a static variable */ { @@ -1857,7 +1858,7 @@ void g_addeqind (unsigned flags, unsigned offs, unsigned long val) -void g_subeqstatic (unsigned flags, unsigned long label, long offs, +void g_subeqstatic (unsigned flags, uintptr_t label, long offs, unsigned long val) /* Emit -= for a static variable */ { @@ -2093,7 +2094,7 @@ void g_addaddr_local (unsigned flags attribute ((unused)), int offs) -void g_addaddr_static (unsigned flags, unsigned long label, long offs) +void g_addaddr_static (unsigned flags, uintptr_t label, long offs) /* Add the address of a static variable to ax */ { /* Create the correct label name */ @@ -4276,7 +4277,7 @@ void g_initstatic (unsigned InitLabel, unsigned VarLabel, unsigned Size) g_getimmed (CF_STATIC, InitLabel, 0); AddCodeLine ("jsr pushax"); g_getimmed (CF_INT | CF_UNSIGNED | CF_CONST, Size, 0); - AddCodeLine ("jsr %s", GetLabelName (CF_EXTERNAL, (unsigned long) "memcpy", 0)); + AddCodeLine ("jsr %s", GetLabelName (CF_EXTERNAL, (uintptr_t) "memcpy", 0)); } } diff --git a/src/cc65/codegen.h b/src/cc65/codegen.h index 4ad375618..bbad0f125 100644 --- a/src/cc65/codegen.h +++ b/src/cc65/codegen.h @@ -40,6 +40,7 @@ /* common */ #include "coll.h" +#include "inttypes.h" /* cc65 */ #include "segments.h" @@ -266,7 +267,7 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes); void g_getimmed (unsigned Flags, unsigned long Val, long Offs); /* Load a constant into the primary register */ -void g_getstatic (unsigned Flags, unsigned long Label, long Offs); +void g_getstatic (unsigned Flags, uintptr_t Label, long Offs); /* Fetch an static memory cell into the primary register */ void g_getlocal (unsigned Flags, int Offs); @@ -293,7 +294,7 @@ void g_leavariadic (int Offs); -void g_putstatic (unsigned flags, unsigned long label, long offs); +void g_putstatic (unsigned flags, uintptr_t label, long offs); /* Store the primary register into the specified static memory cell */ void g_putlocal (unsigned Flags, int Offs, long Val); @@ -315,7 +316,7 @@ void g_putind (unsigned flags, unsigned offs); void g_addlocal (unsigned flags, int offs); /* Add a local variable to ax */ -void g_addstatic (unsigned flags, unsigned long label, long offs); +void g_addstatic (unsigned flags, uintptr_t label, long offs); /* Add a static variable to ax */ @@ -326,7 +327,7 @@ void g_addstatic (unsigned flags, unsigned long label, long offs); -void g_addeqstatic (unsigned flags, unsigned long label, long offs, +void g_addeqstatic (unsigned flags, uintptr_t label, long offs, unsigned long val); /* Emit += for a static variable */ @@ -336,7 +337,7 @@ void g_addeqlocal (unsigned flags, int offs, unsigned long val); void g_addeqind (unsigned flags, unsigned offs, unsigned long val); /* Emit += for the location with address in ax */ -void g_subeqstatic (unsigned flags, unsigned long label, long offs, +void g_subeqstatic (unsigned flags, uintptr_t label, long offs, unsigned long val); /* Emit -= for a static variable */ @@ -357,7 +358,7 @@ void g_subeqind (unsigned flags, unsigned offs, unsigned long val); void g_addaddr_local (unsigned flags, int offs); /* Add the address of a local variable to ax */ -void g_addaddr_static (unsigned flags, unsigned long label, long offs); +void g_addaddr_static (unsigned flags, uintptr_t label, long offs); /* Add the address of a static variable to ax */ diff --git a/src/cc65/expr.c b/src/cc65/expr.c index dfd5366bb..43971caae 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1,7 +1,7 @@ /* expr.c ** ** 1998-06-21, Ullrich von Bassewitz -** 2015-06-26, Greg King +** 2017-12-05, Greg King */ @@ -731,7 +731,7 @@ static void Primary (ExprDesc* E) } else if ((Sym->Flags & SC_FUNC) == SC_FUNC) { /* Function */ E->Flags = E_LOC_GLOBAL | E_RTYPE_LVAL; - E->Name = (unsigned long) Sym->Name; + E->Name = (uintptr_t) Sym->Name; } else if ((Sym->Flags & SC_AUTO) == SC_AUTO) { /* Local variable. If this is a parameter for a variadic ** function, we have to add some address calculations, and the @@ -754,7 +754,7 @@ static void Primary (ExprDesc* E) /* Static variable */ if (Sym->Flags & (SC_EXTERN | SC_STORAGE)) { E->Flags = E_LOC_GLOBAL | E_RTYPE_LVAL; - E->Name = (unsigned long) Sym->Name; + E->Name = (uintptr_t) Sym->Name; } else { E->Flags = E_LOC_STATIC | E_RTYPE_LVAL; E->Name = Sym->V.Label; @@ -798,7 +798,7 @@ static void Primary (ExprDesc* E) Sym = AddGlobalSym (Ident, GetImplicitFuncType(), SC_EXTERN | SC_REF | SC_FUNC); E->Type = Sym->Type; E->Flags = E_LOC_GLOBAL | E_RTYPE_RVAL; - E->Name = (unsigned long) Sym->Name; + E->Name = (uintptr_t) Sym->Name; } else { /* Undeclared Variable */ Sym = AddLocalSym (Ident, type_int, SC_AUTO | SC_REF, 0); @@ -1308,7 +1308,7 @@ static void hie11 (ExprDesc *Expr) ** Since we don't have a name, invent one. */ ED_MakeConstAbs (Expr, 0, GetImplicitFuncType ()); - Expr->Name = (long) IllegalFunc; + Expr->Name = (uintptr_t) IllegalFunc; } /* Call the function */ FunctionCall (Expr); diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index 405c277a0..46377ac6b 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -44,7 +44,6 @@ #include "exprdesc.h" #include "stackptr.h" #include "symentry.h" -#include "exprdesc.h" @@ -361,7 +360,7 @@ void PrintExprDesc (FILE* F, ExprDesc* E) if (Sep != '(') { fputc (')', F); } - fprintf (F, "\nName: 0x%08lX\n", E->Name); + fprintf (F, "\nName: 0x%08lX\n", (unsigned long)E->Name); } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index 99a17313e..e86534902 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -43,6 +43,7 @@ /* common */ #include "fp.h" #include "inline.h" +#include "inttypes.h" /* cc65 */ #include "asmcode.h" @@ -98,7 +99,7 @@ struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ Type* Type; /* Type array of expression */ unsigned Flags; - unsigned long Name; /* Name or label number */ + uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ Double FVal; /* Floating point value */ struct Literal* LVal; /* Literal value */ diff --git a/src/common/inttypes.h b/src/common/inttypes.h index 0d9cb75fc..29ac778ef 100644 --- a/src/common/inttypes.h +++ b/src/common/inttypes.h @@ -38,29 +38,28 @@ -/* If we have stdint.h, include it, otherwise try some quesswork on types. +/* If we have <stdint.h>, include it; otherwise, adapt types from <stddef.h>. ** gcc and msvc don't define __STDC_VERSION__ without special flags, so check -** for them explicitly. Undefined symbols are replaced by zero, so a check for -** defined(__GNUC__) or defined(_MSC_VER) is not necessary. +** for them explicitly. Undefined symbols are replaced by zero; so, checks for +** defined(__GNUC__) and defined(_MSC_VER) aren't necessary. */ #if (__STDC_VERSION__ >= 199901) || (__GNUC__ >= 3) || (_MSC_VER >= 1600) #include <stdint.h> #else -/* Assume long is the largest type available, and assume that pointers can be -** safely converted into this type and back. +/* Assume that ptrdiff_t and size_t are wide enough to hold pointers. +** Assume that they are the widest type. */ -typedef long intptr_t; -typedef unsigned long uintptr_t; -typedef long intmax_t; -typedef unsigned long uintmax_t; - +#include <stddef.h> +typedef ptrdiff_t intptr_t; +typedef size_t uintptr_t; +typedef ptrdiff_t intmax_t; +typedef size_t uintmax_t; #endif /* End of inttypes.h */ - #endif From f0708db792504dc0639d170a51d72b9379f64624 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 11 Jan 2018 13:15:19 +0100 Subject: [PATCH 0550/2161] crt0.s ("none" target): fix initialization of sp variable. --- libsrc/none/crt0.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/none/crt0.s b/libsrc/none/crt0.s index 288d0dc29..596fbcd46 100644 --- a/libsrc/none/crt0.s +++ b/libsrc/none/crt0.s @@ -9,7 +9,7 @@ .segment "STARTUP" lda #<__STACKSTART__ - lda #>__STACKSTART__ + ldx #>__STACKSTART__ sta sp stx sp+1 jsr zerobss From c23f264fe456c27ecef382d6d1e3e579eb40c7cd Mon Sep 17 00:00:00 2001 From: prandeamus <prandeamus@btinternet.com> Date: Sat, 13 Jan 2018 18:30:53 +0000 Subject: [PATCH 0551/2161] Call ParaVirtHooks on JMP (indirect) --- src/sim65/6502.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index 1febef657..bf8033f40 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -1266,6 +1266,8 @@ static void OPC_6502_6C (void) Cycles = 6; Regs.PC = MemReadWord(Lo); } + + ParaVirtHooks (&Regs); } From 009f56afb6b26e12b18aeb8e38cf9521590d5ebf Mon Sep 17 00:00:00 2001 From: prandeamus <prandeamus@btinternet.com> Date: Sat, 13 Jan 2018 22:42:39 +0000 Subject: [PATCH 0552/2161] 65C02 version too. --- src/sim65/6502.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index bf8033f40..e1d313f93 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -1278,6 +1278,8 @@ static void OPC_65C02_6C (void) /* 6502 bug fixed here */ Cycles = 5; Regs.PC = MemReadWord (MemReadWord (Regs.PC+1)); + + ParaVirtHooks (&Regs); } From 1a95be9c3a28c0f5423f39564d968effd48351cb Mon Sep 17 00:00:00 2001 From: prandeamus <prandeamus@btinternet.com> Date: Sun, 14 Jan 2018 19:42:29 +0000 Subject: [PATCH 0553/2161] 65C02 JMP (ind,x) opcode 7C --- src/sim65/6502.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index e1d313f93..0d0adbf8b 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -1434,6 +1434,8 @@ static void OPC_65SC02_7C (void) PC = Regs.PC; Adr = MemReadWord (PC+1); Regs.PC = MemReadWord(Adr+Regs.XR); + + ParaVirtHooks (&Regs); } From 811424cc1b28d4f19882b6b7c59afffbae0f12d6 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 18 Jan 2018 12:37:21 +0100 Subject: [PATCH 0554/2161] Added recently published ProDOS version. --- include/apple2.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/apple2.h b/include/apple2.h index 421b5db6c..31e56a95a 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -134,6 +134,7 @@ extern unsigned char _dos_type; ** ProDOS 8 2.0.1 - 0x21 ** ProDOS 8 2.0.2 - 0x22 ** ProDOS 8 2.0.3 - 0x23 +** ProDOS 8 2.4.x - 0x24 */ From 2ef6514e47629357da7cd336de8489e8f1e548c4 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Fri, 19 Jan 2018 15:18:43 +0100 Subject: [PATCH 0555/2161] atari5200: put default display list into its own memory area This avoids 1K boundary crossing of the display list. Fix for issue #560. --- cfg/atari5200.cfg | 15 +++++++++------ libsrc/atari5200/conioscreen.s | 5 ++++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/cfg/atari5200.cfg b/cfg/atari5200.cfg index 3db8765d6..14d5faa98 100644 --- a/cfg/atari5200.cfg +++ b/cfg/atari5200.cfg @@ -1,16 +1,18 @@ SYMBOLS { __CARTSIZE__: type = weak, value = $4000; # possible values: $4000 and $8000 + __DLISTSIZE__: type = weak, value = $0000; __CART_ENTRY__: type = import; __STACKSIZE__: type = weak, value = $0400; # 4 pages stack __RESERVED_MEMORY__: type = export, value = $01E0; # space for 20x24 screen buffer (default display list is in ROM) } MEMORY { - ZP: file = "", start = $001D, size = $00E3, define = yes; - RAM: file = "", start = $021C, size = $4000 - __STACKSIZE__ - __RESERVED_MEMORY__ - $021C, define = yes; - ROM: file = %O, start = $C000 - __CARTSIZE__, size = __CARTSIZE__ - $18, define = yes, fill = yes, fillval = $FF; - CARTNAME: file = %O, start = $BFE8, size = $0014 fill = yes, fillval = $40; - CARTYEAR: file = %O, start = $BFFC, size = $0002 fill = yes, fillval = $59; - CARTENTRY: file = %O, start = $BFFE, size = $0002; + ZP: file = "", start = $001D, size = $00E3, define = yes; + RAM: file = "", start = $021C, size = $4000 - __STACKSIZE__ - __RESERVED_MEMORY__ - $021C, define = yes; + ROM: file = %O, start = $C000 - __CARTSIZE__, size = __CARTSIZE__ - __DLISTSIZE__ - $18, define = yes, fill = yes, fillval = $FF; + DLIST: file = %O, start = $BFE8 - __DLISTSIZE__, size = __DLISTSIZE__; + CARTNAME: file = %O, start = $BFE8, size = $0014 fill = yes, fillval = $40; + CARTYEAR: file = %O, start = $BFFC, size = $0002 fill = yes, fillval = $59; + CARTENTRY: file = %O, start = $BFFE, size = $0002; } SEGMENTS { ZEROPAGE: load = ZP, type = zp, optional = yes; @@ -22,6 +24,7 @@ SEGMENTS { RODATA: load = ROM, type = ro, optional = yes; DATA: load = ROM, run = RAM, type = rw, define = yes, optional = yes; BSS: load = RAM, type = bss, define = yes, optional = yes; + DLIST: load = DLIST, type = ro, define = yes, optional = yes; CARTNAME: load = CARTNAME, type = ro, define = yes; CARTYEAR: load = CARTYEAR, type = ro, define = yes; CARTENTRY: load = CARTENTRY, type = ro, define = yes; diff --git a/libsrc/atari5200/conioscreen.s b/libsrc/atari5200/conioscreen.s index 2e86001c2..4bd6d51e2 100644 --- a/libsrc/atari5200/conioscreen.s +++ b/libsrc/atari5200/conioscreen.s @@ -58,7 +58,7 @@ clrscr: sta (SAVMSC),y rts - .segment "RODATA" + .segment "DLIST" ; display list for 20x24 text mode @@ -78,6 +78,9 @@ dlist: .repeat 3 ; end of display list +.export __DLISTSIZE__ +__DLISTSIZE__ = * - dlist + .assert ((* >> 10) = (dlist >> 10)), error, "Display list crosses 1K boundary" .end From 643152fb38d576d0115a7ec01895e8f92fe6730e Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Sun, 21 Jan 2018 15:40:22 +0100 Subject: [PATCH 0556/2161] Fix last change, put display list at beginning of ROM. --- cfg/atari5200.cfg | 12 +++++------- libsrc/atari5200/conioscreen.s | 3 --- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/cfg/atari5200.cfg b/cfg/atari5200.cfg index 14d5faa98..b1f863d21 100644 --- a/cfg/atari5200.cfg +++ b/cfg/atari5200.cfg @@ -1,6 +1,5 @@ SYMBOLS { __CARTSIZE__: type = weak, value = $4000; # possible values: $4000 and $8000 - __DLISTSIZE__: type = weak, value = $0000; __CART_ENTRY__: type = import; __STACKSIZE__: type = weak, value = $0400; # 4 pages stack __RESERVED_MEMORY__: type = export, value = $01E0; # space for 20x24 screen buffer (default display list is in ROM) @@ -8,8 +7,7 @@ SYMBOLS { MEMORY { ZP: file = "", start = $001D, size = $00E3, define = yes; RAM: file = "", start = $021C, size = $4000 - __STACKSIZE__ - __RESERVED_MEMORY__ - $021C, define = yes; - ROM: file = %O, start = $C000 - __CARTSIZE__, size = __CARTSIZE__ - __DLISTSIZE__ - $18, define = yes, fill = yes, fillval = $FF; - DLIST: file = %O, start = $BFE8 - __DLISTSIZE__, size = __DLISTSIZE__; + ROM: file = %O, start = $C000 - __CARTSIZE__, size = __CARTSIZE__ - $18, define = yes, fill = yes, fillval = $FF; CARTNAME: file = %O, start = $BFE8, size = $0014 fill = yes, fillval = $40; CARTYEAR: file = %O, start = $BFFC, size = $0002 fill = yes, fillval = $59; CARTENTRY: file = %O, start = $BFFE, size = $0002; @@ -17,6 +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; 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; @@ -24,10 +23,9 @@ SEGMENTS { RODATA: load = ROM, type = ro, optional = yes; DATA: load = ROM, run = RAM, type = rw, define = yes, optional = yes; BSS: load = RAM, type = bss, define = yes, optional = yes; - DLIST: load = DLIST, type = ro, define = yes, optional = yes; - CARTNAME: load = CARTNAME, type = ro, define = yes; - CARTYEAR: load = CARTYEAR, type = ro, define = yes; - CARTENTRY: load = CARTENTRY, type = ro, define = yes; + CARTNAME: load = CARTNAME, type = ro; + CARTYEAR: load = CARTYEAR, type = ro; + CARTENTRY: load = CARTENTRY, type = ro; } FEATURES { CONDES: type = constructor, diff --git a/libsrc/atari5200/conioscreen.s b/libsrc/atari5200/conioscreen.s index 4bd6d51e2..30c0e0788 100644 --- a/libsrc/atari5200/conioscreen.s +++ b/libsrc/atari5200/conioscreen.s @@ -78,9 +78,6 @@ dlist: .repeat 3 ; end of display list -.export __DLISTSIZE__ -__DLISTSIZE__ = * - dlist - .assert ((* >> 10) = (dlist >> 10)), error, "Display list crosses 1K boundary" .end From 356c73f2cff0131fc9e04d160bdd6a6b923c7108 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Sun, 21 Jan 2018 15:42:12 +0100 Subject: [PATCH 0557/2161] atari5200.cfg: fix formatting --- cfg/atari5200.cfg | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cfg/atari5200.cfg b/cfg/atari5200.cfg index b1f863d21..e8f6d44a5 100644 --- a/cfg/atari5200.cfg +++ b/cfg/atari5200.cfg @@ -5,12 +5,12 @@ SYMBOLS { __RESERVED_MEMORY__: type = export, value = $01E0; # space for 20x24 screen buffer (default display list is in ROM) } MEMORY { - ZP: file = "", start = $001D, size = $00E3, define = yes; - RAM: file = "", start = $021C, size = $4000 - __STACKSIZE__ - __RESERVED_MEMORY__ - $021C, define = yes; - ROM: file = %O, start = $C000 - __CARTSIZE__, size = __CARTSIZE__ - $18, define = yes, fill = yes, fillval = $FF; - CARTNAME: file = %O, start = $BFE8, size = $0014 fill = yes, fillval = $40; - CARTYEAR: file = %O, start = $BFFC, size = $0002 fill = yes, fillval = $59; - CARTENTRY: file = %O, start = $BFFE, size = $0002; + ZP: file = "", start = $001D, size = $00E3, define = yes; + RAM: file = "", start = $021C, size = $4000 - __STACKSIZE__ - __RESERVED_MEMORY__ - $021C, define = yes; + ROM: file = %O, start = $C000 - __CARTSIZE__, size = __CARTSIZE__ - $18, define = yes, fill = yes, fillval = $FF; + CARTNAME: file = %O, start = $BFE8, size = $0014 fill = yes, fillval = $40; + CARTYEAR: file = %O, start = $BFFC, size = $0002 fill = yes, fillval = $59; + CARTENTRY: file = %O, start = $BFFE, size = $0002; } SEGMENTS { ZEROPAGE: load = ZP, type = zp, optional = yes; From caa40866c3ebdf3d2540b072aac1462d6afe9b33 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 23 Jan 2018 13:02:47 +0100 Subject: [PATCH 0558/2161] Moved initcgetc to initcputc --- libsrc/atmos/cgetc.s | 12 ------------ libsrc/atmos/cputc.s | 11 +++++++++++ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/libsrc/atmos/cgetc.s b/libsrc/atmos/cgetc.s index f1d727a50..72cd9407a 100644 --- a/libsrc/atmos/cgetc.s +++ b/libsrc/atmos/cgetc.s @@ -6,7 +6,6 @@ ; .export _cgetc - .constructor initcgetc .import cursor .forceimport disable_caps @@ -53,14 +52,3 @@ @L3: rts .endproc - -; ------------------------------------------------------------------------ -; Switch the cursor off. Code goes into the ONCE segment, -; which will be reused after it is run. - -.segment "ONCE" - -initcgetc: - lsr STATUS - asl STATUS ; Clear bit zero - rts diff --git a/libsrc/atmos/cputc.s b/libsrc/atmos/cputc.s index a0ef14b70..f1ce5f2b7 100644 --- a/libsrc/atmos/cputc.s +++ b/libsrc/atmos/cputc.s @@ -8,6 +8,7 @@ .export _cputcxy, _cputc .export setscrptr, putchar + .constructor initcputc .import rvs .import popax .importzp ptr2 @@ -95,3 +96,13 @@ ScrTabHi: .byte >(SCREEN + Line * SCREEN_XSIZE) .endrep +; ------------------------------------------------------------------------ +; Switch the cursor off. Code goes into the ONCE segment, +; which will be reused after it is run. + +.segment "ONCE" + +initcputc: + lsr STATUS + asl STATUS ; Clear bit zero + rts From 855aceaba8f78f66cf5134ae707b4cee11c6e9e9 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 29 Jan 2018 17:46:36 +0100 Subject: [PATCH 0559/2161] Added Apple II linker configs for programs including a hires screen. The Apple II hires screen buffer is located at $2000 (and can't be moved). The usual way to get along with this is to load the cc65 program above the hires screen buffer at $4000. However, that means that it becomes difficult to make good use of the memory below the hires screen buffer. The simplest approach is to add that memory to the heap. But there are programs containing just lots of code and not much data. One could think of moving the code to the area below the hires screen after loading (like it is done with the code for the language card). But if the program is really large (and already contains code to be moved to the language card) it won't just fit into memory in the first place. The alternative is to load the program at the usual $803 and have it "cover" the hires screen buffer. Of course the part of the program that actually "covers" the hires screen buffer mustn't contain anything necessary for the program. The downside of this approach is that the program file on disk contains 8kB that can't be used by the program. But instead of just containing zeros the program can as well contain a hires screen picture that can be displayed right after startup. Now the user can have code loaded below the hires screen buffer by setting the code-name to LOWCODE. However, he needs to explicitly do so. Otherwise the memory below the hires screen is totally wasted. Trivia: Allowing to do this hires screen buffer "covering" was the very reason to change tgi_init() to not clear the hires screen anymore. --- cfg/apple2-hgr.cfg | 52 +++++++++++++++++++++++++++++++++ cfg/apple2enh-hgr.cfg | 52 +++++++++++++++++++++++++++++++++ testcode/lib/apple2/hgrtest.c | 26 +++++++++++++++++ testcode/lib/apple2/werner.pic | Bin 0 -> 8184 bytes testcode/lib/apple2/werner.s | 2 ++ 5 files changed, 132 insertions(+) create mode 100644 cfg/apple2-hgr.cfg create mode 100644 cfg/apple2enh-hgr.cfg create mode 100644 testcode/lib/apple2/hgrtest.c create mode 100644 testcode/lib/apple2/werner.pic create mode 100644 testcode/lib/apple2/werner.s diff --git a/cfg/apple2-hgr.cfg b/cfg/apple2-hgr.cfg new file mode 100644 index 000000000..540578b25 --- /dev/null +++ b/cfg/apple2-hgr.cfg @@ -0,0 +1,52 @@ +# Configuration for programs including a hires screen (with 6KB LOWCODE) + +FEATURES { + STARTADDRESS: default = $0803; +} +SYMBOLS { + __EXEHDR__: type = import; + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __HIMEM__: type = weak, value = $9600; # Presumed RAM end + __LCADDR__: type = weak, value = $D400; # Behind quit code + __LCSIZE__: type = weak, value = $0C00; # Rest of bank two + __MAIN_START__: type = export, value = %S; + __MAIN_LAST__: type = export, value = __HIGH_LAST__; +} +MEMORY { + ZP: file = "", define = yes, start = $0080, size = $001A; + HEADER: file = %O, start = %S - 4, size = $0004; + LOW: file = %O, fill = yes, start = %S, size = $2000 - %S; + HGR: file = %O, fill = yes, start = $2000, size = $2000; + HIGH: file = %O, define = yes, start = $4000, size = __HIMEM__ - $4000; + BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__; + LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXEHDR: load = HEADER, type = ro; + STARTUP: load = LOW, type = ro; + LOWCODE: load = LOW, type = ro, optional = yes; + HGR: load = HGR, type = rw, optional = yes; + CODE: load = HIGH, type = ro; + RODATA: load = HIGH, type = ro; + DATA: load = HIGH, type = rw; + INIT: load = HIGH, type = rw; + ONCE: load = HIGH, type = ro, define = yes; + LC: load = HIGH, run = LC, type = ro, optional = 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/apple2enh-hgr.cfg b/cfg/apple2enh-hgr.cfg new file mode 100644 index 000000000..540578b25 --- /dev/null +++ b/cfg/apple2enh-hgr.cfg @@ -0,0 +1,52 @@ +# Configuration for programs including a hires screen (with 6KB LOWCODE) + +FEATURES { + STARTADDRESS: default = $0803; +} +SYMBOLS { + __EXEHDR__: type = import; + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __HIMEM__: type = weak, value = $9600; # Presumed RAM end + __LCADDR__: type = weak, value = $D400; # Behind quit code + __LCSIZE__: type = weak, value = $0C00; # Rest of bank two + __MAIN_START__: type = export, value = %S; + __MAIN_LAST__: type = export, value = __HIGH_LAST__; +} +MEMORY { + ZP: file = "", define = yes, start = $0080, size = $001A; + HEADER: file = %O, start = %S - 4, size = $0004; + LOW: file = %O, fill = yes, start = %S, size = $2000 - %S; + HGR: file = %O, fill = yes, start = $2000, size = $2000; + HIGH: file = %O, define = yes, start = $4000, size = __HIMEM__ - $4000; + BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__; + LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXEHDR: load = HEADER, type = ro; + STARTUP: load = LOW, type = ro; + LOWCODE: load = LOW, type = ro, optional = yes; + HGR: load = HGR, type = rw, optional = yes; + CODE: load = HIGH, type = ro; + RODATA: load = HIGH, type = ro; + DATA: load = HIGH, type = rw; + INIT: load = HIGH, type = rw; + ONCE: load = HIGH, type = ro, define = yes; + LC: load = HIGH, run = LC, type = ro, optional = 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/testcode/lib/apple2/hgrtest.c b/testcode/lib/apple2/hgrtest.c new file mode 100644 index 000000000..7323cbb73 --- /dev/null +++ b/testcode/lib/apple2/hgrtest.c @@ -0,0 +1,26 @@ +// cl65 -t apple2 -C apple2-hgr.cfg hgrtest.c werner.s + +#include <tgi.h> +#include <conio.h> + +#pragma code-name (push, "LOWCODE") + +void say (const char* text) +{ + tgi_setcolor (TGI_COLOR_BLACK); + tgi_outtextxy (41, 33, text); +} + +#pragma code-name (pop) + +void main (void) +{ + tgi_install (a2_hi_tgi); + tgi_init (); + cgetc (); + + say ("Hi Dude !"); + cgetc (); + + tgi_uninstall (); +} diff --git a/testcode/lib/apple2/werner.pic b/testcode/lib/apple2/werner.pic new file mode 100644 index 0000000000000000000000000000000000000000..2405e2409470d0de0e017194f6f81e9b058511e1 GIT binary patch literal 8184 zcmbVQ-EQN?6{bLRnG3JkyL#cDaS#*>wCGw!fZ7|{9vcRt1%j9hBn7&_%9NmXl?z9t zSIClzC?35=Zrdm6gXE@9kVoiuh9YOQB1cV*1aUNT=A1b{-^>{j{dy81<}8T%K{mC_ z9uwV?@SMF*&I?K={U9-zofR2fM$@~e__8CrCvo@qM4lX<#Ks_+dnAeCe$dI+`^|qT zQO5!6z<DK$)3m^tr^mhX)4#sH`Sx4YBQiYvm8_A}TurUC6!Td+>AQPP3{~F@=9BLf zQ_AiFbUxxAuR@VwKPxZEClbYYY;!6&AcomR;yT@0UMXPxSF+oOw>0hrKVn33*ed#Y z`M2fI_z=yiE<BkdJcH+KG$$It`$C>=(N7DJ7E>(ta-!s6Voln9vp44P`RQz6E~=hW zH42i&G|z%l5(6YzJMo}=O_Y}6OkQn2$7Mw@e=e`G!yq?PwHmFTg6M|6;y_@oT5>(~ zQ6qN~YL2G1pQpGviEGLcO)u$D<eurA_(&rD799WRF&70*h2vNtusOHxNtZ8{2g@%I z|6fn?2y=k{AWfQ$D@DRHE{P|@y+jfX`vF}Ws@Cl{2L7++X9Yy|gVeF)KjR-7&mCun zibQ3gh99NNe=q;D{BLRhjZ#|vQYbA#!I+jP_OPKjR{T$C0Qfukn6e#)6hI^DU}^ge zb==It*p5F~j>z-g>TkneCLa2u9>u+YC#bODspyyGPfH&k709ZSBDBOd{3GT);6I|> zhf9{*P74?`N3vc%C>}FewEbo;BlKo5y|^|zH{|Ce^Ov(xngBGA-cBKg#NUa=CH|3+ zHTkgr7ktnGV^#$9vm}phQpbirK6^&8r|_StEwh@x@npTtTbZ_BP3kyE)dgqAY)aDG zt@C6<B;z0P53(7YJM|}hy?r(CwstwoKP{c*zsmgI;PO5c9h|>O7w0cNgRbd1q6>r_ zD@-Skwm8B2F3B%P&lvyT1S$S$`pAAgu(c%zd{#?}f^_oA!i`|MV9h$tE?qtJnNw)D zn)a`{s|OrxqqG#`zYb8^*cf|QspoXFkRHG0?FV@#>%7wT3quChHxl7i{7beYBk3I5 zm+CrigRw_pI9GgEh9<2a8+lC;TJr2e{lBq+<-wFVil6q8f;L*fl{25{Wr=^&F0J3} z<@P}_Jn#^_b^@aE{Cy|>j^wp<1yD`iTdZ|cmeybHriuelx*W`++qkniLHGEmx<+(I z0=~*A(gT|<z(d7qbHvbJ56(Cgi;U9U9S(3Cq5R3o%R3i2&BA_wSo{WR(yzs&KNRuh zLY|zwK=sWZGf3E@uslQ_dyftOs7!$WC*ys_|K}*cJtJG}`t?dSTf#wKCUN>t`ZoL{ z=q})vxsE7~-l{57!;eh;DAN@U`FA7>oAYs)lqi-g;rHdl=3n1Q6#fN0KIQF)&2PYe zXv{`t`|^I>*~YMHBI7xyWFZEfE%@Je;3SWPKUE;VYV^MvS}BR}l<&6SAJ_!2;wbuR zE)0n)5$0n?IprRT>e8d8UE2R9)H$7wvVRu7*=b5tZNxG!{&=tlsU2u&rxOgi_uKGa z2Zh~wnM_0P-aM%`#E*J8lHh9+#9Ie`+X-g0jBES#>^YYT&kBkUtwlY`pA2_U=a}&y zq(}A`Xz^>UCjFYB#{XYriGTBwMl_uv{kQ;sv=krWDkHa$I}<UGn1T~fz`qsQ^;cX? z&rn^|<rjc|V8cIf#lX(|0q~FNgGpcOO#Kxok=2~qxrqqwTBmp=#)Swg{w1nN&q)$o zRu9>KyzbgxTECg<>b!Vs;$&U7`UlTr#RArOTkt=Bo=(2^N&2P4ywU%rwGk_LcyIVg zX<Yw-W8tZg<nt7lRvXP}CJJv0{voa=06^Y7{-dy;|M1dz;gW-w8eU6zT}liQ?`z19 zYXx;f`@c*R9)MMJne{yX!aS+!DOF=8G8#wf{*M`=>TY`C!r5!;r?vB^;+S%lAZMds zP^DxwWIhqFgvNqz{&|>AE^WN#ytTGz|Js21<GrA`GsKIxKYx1O#RprBNq9pgd6{Wa z=d(FnwnG$2Zb3Ww5%4d+!>Xl*U!(n-GMakgQp^Xy{|`3&ixvI__Nra=`VVg*YJrCR z*u+bcY^5v~ybZS#lBpDfyS)|vsL{whOa_#Xo-qJJ1ghRgwSE)r+@2kpJq_!?D&h7B zng4Vf{^LnM2L6vqiKby%{|5fQ|4}d!S}9UVA5r?Q5Vh|bx#u*x<%FJ=DQeoK^$TMv zUW0YR;o!rqxhWdsWfOzX@G_G@>b1OHD;c9(ydgxq!VM8?`6pJ{Ex@)&#I;PU_wNP6 zue|?5Fi&cyMDO_POxk|kpK|#F<ASrqmVy|=0+4-~%zeBB*Ga8KZEZE_*OSsd-oJDG z|9n;d*LkaWP@YL31^0i;I>*>gJHUT-a4pGK1vswb6@8@Nb&Ro!r};T9;rD<Gz^)Dd zvf$LCYnjXZZh|bwmpe)_^y?j3?Pl3*-PmeI^+e1|F^vCe>!=3Tp3E6M4rw;p=lg%e z;jKvPH+wnlr!P&MRQ$#hc3`0)<<b5Y{PXp2?4zW9r>2{RY5fpaQ^c(W_29d95=eTk zd*k84uWRQ<_9^)pUX@d7!@r>mO`N_?cfu%Wr<mvs-@mcQ9$v?`lkjslgQ#eeMca=t zED_{O{2-yTbYMMGa~y1Adcw#@>cG7g^4co-HT^3AV-<dWua;SG#b?NndcL!lg@w2e z(kB-EtwT-vHFJ&slg9hMyd%lW>_1v+j}+HbT-6Vfy;l-AVBs2mYx}RdsQdK>0MRx| zOEGV7wf)^EHpZM8r9(5|zYj+E)T{Xo`!xXB|1?!)Sk1W6h$=Cjv*rD}AUaLo-_mrv z&nJvf;#cytesi}$X4Cj{TS|igc3{b|ECP26{ue0GQY7dBZ$C!yfwtCfrdr5s-j`G2 z^|ldEDhuzbh`s^5weuR-l_A&2lv0Ojm)39S60l5&t`x<nL0a8~Rlec-H+C*YVmrwz z$Keek+GH{GBQl)E;+Wr$OtG!RH-ROuN!9f6r-dk>914CDt?6G$2s!+4Rou@kbu|b7 VhJ3ty9*hckkxri4g4MRT{{gd9*mnQ` literal 0 HcmV?d00001 diff --git a/testcode/lib/apple2/werner.s b/testcode/lib/apple2/werner.s new file mode 100644 index 000000000..6456ade13 --- /dev/null +++ b/testcode/lib/apple2/werner.s @@ -0,0 +1,2 @@ +.segment "HGR" +.incbin "werner.pic" From 80b09ba9fc42f65b84f91ea2d170325abe84fac1 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 31 Jan 2018 08:54:48 +0100 Subject: [PATCH 0560/2161] Significantly simplified recently added linker config files. I just forgot about the 'start' segment attribute - which makes the scenario at hand dead easy. --- cfg/apple2-hgr.cfg | 34 +++++++++++++++------------------- cfg/apple2enh-hgr.cfg | 34 +++++++++++++++------------------- 2 files changed, 30 insertions(+), 38 deletions(-) diff --git a/cfg/apple2-hgr.cfg b/cfg/apple2-hgr.cfg index 540578b25..536491c67 100644 --- a/cfg/apple2-hgr.cfg +++ b/cfg/apple2-hgr.cfg @@ -4,35 +4,31 @@ FEATURES { STARTADDRESS: default = $0803; } SYMBOLS { - __EXEHDR__: type = import; - __STACKSIZE__: type = weak, value = $0800; # 2k stack - __HIMEM__: type = weak, value = $9600; # Presumed RAM end - __LCADDR__: type = weak, value = $D400; # Behind quit code - __LCSIZE__: type = weak, value = $0C00; # Rest of bank two - __MAIN_START__: type = export, value = %S; - __MAIN_LAST__: type = export, value = __HIGH_LAST__; + __EXEHDR__: type = import; + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __HIMEM__: type = weak, value = $9600; # Presumed RAM end + __LCADDR__: type = weak, value = $D400; # Behind quit code + __LCSIZE__: type = weak, value = $0C00; # Rest of bank two } MEMORY { ZP: file = "", define = yes, start = $0080, size = $001A; HEADER: file = %O, start = %S - 4, size = $0004; - LOW: file = %O, fill = yes, start = %S, size = $2000 - %S; - HGR: file = %O, fill = yes, start = $2000, size = $2000; - HIGH: file = %O, define = yes, start = $4000, size = __HIMEM__ - $4000; + 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__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; EXEHDR: load = HEADER, type = ro; - STARTUP: load = LOW, type = ro; - LOWCODE: load = LOW, type = ro, optional = yes; - HGR: load = HGR, type = rw, optional = yes; - CODE: load = HIGH, type = ro; - RODATA: load = HIGH, type = ro; - DATA: load = HIGH, type = rw; - INIT: load = HIGH, type = rw; - ONCE: load = HIGH, type = ro, define = yes; - LC: load = HIGH, run = LC, type = ro, optional = yes; + STARTUP: load = MAIN, type = ro; + LOWCODE: load = MAIN, type = ro, optional = yes; + HGR: load = MAIN, type = rw, optional = yes, start = $2000; + CODE: load = MAIN, type = ro start = $4000; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = rw; + ONCE: load = MAIN, type = ro, define = yes; + LC: load = MAIN, run = LC, type = ro, optional = yes; BSS: load = BSS, type = bss, define = yes; } FEATURES { diff --git a/cfg/apple2enh-hgr.cfg b/cfg/apple2enh-hgr.cfg index 540578b25..536491c67 100644 --- a/cfg/apple2enh-hgr.cfg +++ b/cfg/apple2enh-hgr.cfg @@ -4,35 +4,31 @@ FEATURES { STARTADDRESS: default = $0803; } SYMBOLS { - __EXEHDR__: type = import; - __STACKSIZE__: type = weak, value = $0800; # 2k stack - __HIMEM__: type = weak, value = $9600; # Presumed RAM end - __LCADDR__: type = weak, value = $D400; # Behind quit code - __LCSIZE__: type = weak, value = $0C00; # Rest of bank two - __MAIN_START__: type = export, value = %S; - __MAIN_LAST__: type = export, value = __HIGH_LAST__; + __EXEHDR__: type = import; + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __HIMEM__: type = weak, value = $9600; # Presumed RAM end + __LCADDR__: type = weak, value = $D400; # Behind quit code + __LCSIZE__: type = weak, value = $0C00; # Rest of bank two } MEMORY { ZP: file = "", define = yes, start = $0080, size = $001A; HEADER: file = %O, start = %S - 4, size = $0004; - LOW: file = %O, fill = yes, start = %S, size = $2000 - %S; - HGR: file = %O, fill = yes, start = $2000, size = $2000; - HIGH: file = %O, define = yes, start = $4000, size = __HIMEM__ - $4000; + 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__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; EXEHDR: load = HEADER, type = ro; - STARTUP: load = LOW, type = ro; - LOWCODE: load = LOW, type = ro, optional = yes; - HGR: load = HGR, type = rw, optional = yes; - CODE: load = HIGH, type = ro; - RODATA: load = HIGH, type = ro; - DATA: load = HIGH, type = rw; - INIT: load = HIGH, type = rw; - ONCE: load = HIGH, type = ro, define = yes; - LC: load = HIGH, run = LC, type = ro, optional = yes; + STARTUP: load = MAIN, type = ro; + LOWCODE: load = MAIN, type = ro, optional = yes; + HGR: load = MAIN, type = rw, optional = yes, start = $2000; + CODE: load = MAIN, type = ro start = $4000; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = rw; + ONCE: load = MAIN, type = ro, define = yes; + LC: load = MAIN, run = LC, type = ro, optional = yes; BSS: load = BSS, type = bss, define = yes; } FEATURES { From 38049d22ba54945e33d3b392fd4bb46b4b14773e Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 31 Jan 2018 14:53:31 +0100 Subject: [PATCH 0561/2161] Provide symbole for RAM memory area. The RAM memory area symbols are referred by the startup code. The 64k and 128k variant say "for assembler" so it may be not necessary to do that there. However given the "limited" state of documentation for the target I don't assign too much value to those statements. Additionally it's unclear to me why two variants provide symbols for the ROM memory. --- cfg/supervision-128k.cfg | 4 ++-- cfg/supervision-16k.cfg | 6 +++--- cfg/supervision-64k.cfg | 4 ++-- cfg/supervision.cfg | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cfg/supervision-128k.cfg b/cfg/supervision-128k.cfg index 0304e2c02..a03ab0e1b 100644 --- a/cfg/supervision-128k.cfg +++ b/cfg/supervision-128k.cfg @@ -2,13 +2,13 @@ # for assembler # ld65 config file -# ld65 --config supervision.cfg -o <prog>.bin <prog>.o +# ld65 --config supervision-128k.cfg -o <prog>.bin <prog>.o SYMBOLS { __STACKSIZE__: type = weak, value = $0100; # 1 page stack } MEMORY { - RAM: file = "", start = $0000, size = $2000 - __STACKSIZE__; + RAM: file = "", start = $0000, size = $2000 - __STACKSIZE__, define = yes; VRAM: file = "", start = $4000, size = $2000; BANKROM1: file = %O, start = $8000, size = $4000, fill = yes, fillval = $FF; BANKROM2: file = %O, start = $8000, size = $4000, fill = yes, fillval = $FF; diff --git a/cfg/supervision-16k.cfg b/cfg/supervision-16k.cfg index 86c8fface..e0b54be23 100644 --- a/cfg/supervision-16k.cfg +++ b/cfg/supervision-16k.cfg @@ -1,7 +1,7 @@ # supervision 16kbyte cartridge # ld65 config file -# ld65 --config supervision16.cfg -o <prog>.bin <prog>.o +# ld65 --config supervision-16k.cfg -o <prog>.bin <prog>.o SYMBOLS { __STACKSIZE__: type = weak, value = $0100; # 1 page stack @@ -9,9 +9,9 @@ SYMBOLS { MEMORY { ZP: file = "", start = $0000, size = $0100; CPUSTACK: file = "", start = $0100, size = $0100; - RAM: file = "", start = $0200, size = $1E00 - __STACKSIZE__; + RAM: file = "", start = $0200, size = $1E00 - __STACKSIZE__, define = yes; VRAM: file = "", start = $4000, size = $2000; - ROM: file = %O, start = $C000, size = $4000, fill = yes, fillval = $ff, define=yes; + ROM: file = %O, start = $C000, size = $4000, fill = yes, fillval = $FF, define = yes; } SEGMENTS { ZEROPAGE: load = ZP, type = zp, define = yes; diff --git a/cfg/supervision-64k.cfg b/cfg/supervision-64k.cfg index 8a7665c30..9d5f15e45 100644 --- a/cfg/supervision-64k.cfg +++ b/cfg/supervision-64k.cfg @@ -2,13 +2,13 @@ # for assembler # ld65 config file -# ld65 --config supervision.cfg -o <prog>.bin <prog>.o +# ld65 --config supervision-64k.cfg -o <prog>.bin <prog>.o SYMBOLS { __STACKSIZE__: type = weak, value = $0100; # 1 page stack } MEMORY { - RAM: file = "", start = $0000, size = $2000 - __STACKSIZE__; + RAM: file = "", start = $0000, size = $2000 - __STACKSIZE__, define = yes; VRAM: file = "", start = $4000, size = $2000; BANKROM1: file = %O, start = $8000, size = $4000, fill = yes, fillval = $FF; BANKROM2: file = %O, start = $8000, size = $4000, fill = yes, fillval = $FF; diff --git a/cfg/supervision.cfg b/cfg/supervision.cfg index 2d20e3461..d9f189f2b 100644 --- a/cfg/supervision.cfg +++ b/cfg/supervision.cfg @@ -8,7 +8,7 @@ SYMBOLS { MEMORY { ZP: file = "", start = $0000, size = $0100; CPUSTACK: file = "", start = $0100, size = $0100; - RAM: file = "", start = $0200, size = $1E00 - __STACKSIZE__; + RAM: file = "", start = $0200, size = $1E00 - __STACKSIZE__, define = yes; VRAM: file = "", start = $4000, size = $2000; ROM: file = %O, start = $8000, size = $8000, fill = yes, fillval = $FF, define = yes; } From 19ed94fe25fb834bb002ece6a0201173fc709027 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 31 Jan 2018 15:06:37 +0100 Subject: [PATCH 0562/2161] Adjust alternative ProDOS 8 I/O buffer allocation module to linker configs. The Apple II linker configs don't define symbols for the STARTP segment anymore. There refer to the load/start address in the same way the executable file header does. --- libsrc/apple2/extra/iobuf-0800.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/apple2/extra/iobuf-0800.s b/libsrc/apple2/extra/iobuf-0800.s index 0ad7a751f..7ed832ed3 100644 --- a/libsrc/apple2/extra/iobuf-0800.s +++ b/libsrc/apple2/extra/iobuf-0800.s @@ -7,7 +7,7 @@ .constructor initiobuf .export iobuf_alloc, iobuf_free - .import __STARTUP_RUN__ + .import __MAIN_START__ .import incsp2, popax .include "zeropage.inc" @@ -18,7 +18,7 @@ initiobuf: ; Convert end address highbyte to table index - lda #>__STARTUP_RUN__ + lda #>__MAIN_START__ sec sbc #>$0800 lsr From 58bfe28244d1edc96d73c43dd9716ee05fafad5f Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 31 Jan 2018 23:52:08 +0100 Subject: [PATCH 0563/2161] Updated AppleCommander URL. --- doc/apple2.sgml | 2 +- doc/apple2enh.sgml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 33a878223..05b4ef9ba 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -39,7 +39,7 @@ containing the load address and load length. The default load address is $803. <bf/AppleCommander 1.3.5/ or later (available at <url -url="http://applecommander.sourceforge.net/">) includes the option <tt/-cc65/ +url="https://applecommander.github.io/">) includes the option <tt/-cc65/ that allows to put binary files with a DOS 3.3 header onto disk images containing DOS 3.3 as well as ProDOS 8. diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 4f5202543..136f074b5 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -39,7 +39,7 @@ containing the load address and load length. The default load address is $803. <bf/AppleCommander 1.3.5/ or later (available at <url -url="http://applecommander.sourceforge.net/">) includes the option <tt/-cc65/ +url="https://applecommander.github.io/">) includes the option <tt/-cc65/ that allows to put binary files with a DOS 3.3 header onto disk images containing DOS 3.3 as well as ProDOS 8. From ef5461a32c144ee82c95f46bbe41de894babaa4b Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 1 Feb 2018 00:18:07 +0100 Subject: [PATCH 0564/2161] Mention the recently added linker configs. --- doc/apple2.sgml | 39 +++++++++++++++++++++++++++++++++++++-- doc/apple2enh.sgml | 39 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 05b4ef9ba..822dd564e 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -168,9 +168,44 @@ Parameters: </descrip><p> +<sect1><tt/apple2-hgr.cfg/<p> + +Configuration for a program including a hires page. See <tt>testcode/lib/apple/hgrtest.c</tt> +for an example of such a program. + +Parameters: + +<descrip> + + <tag><tt/STARTADDRESS:/ Program start address</tag> + Default: $803. Use <tt/-S <addr>/ to set a different start address. + + <tag><tt/__EXEHDR__:/ Executable file header</tag> + Default: DOS 3.3 header (address and length). Use <tt/-D __EXEHDR__=0/ to omit + the header. + + <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> + Default: $800. Use <tt/-D __STACKSIZE__=<size>/ to set a different + stack size. + + <tag><tt/__HIMEM__:/ Highest usable memory address presumed at link time</tag> + Default: $9600. Use <tt/-D __HIMEM__=<addr>/ to set a different + highest usable address. + + <tag><tt/__LCADDR__:/ Address of code in the Language Card</tag> + Default: $D400. Use <tt/-D __LCADDR__=<addr>/ to set a different + code address. + + <tag><tt/__LCSIZE__:/ Size of code in the Language Card</tag> + Default: $C00. Use <tt/-D __LCSIZE__=<size>/ to set a different + code size. + +</descrip><p> + + <sect1><tt/apple2-overlay.cfg/<p> -Configuration for overlay programs with the up to nine overlays. The overlay files +Configuration for an overlay program with up to nine overlays. The overlay files don't include the DOS 3.3 header. See <tt>samples/overlaydemo.c</tt> for more information on overlays. @@ -210,7 +245,7 @@ Parameters: <sect1><tt/apple2-asm.cfg/<p> -Configuration for a assembler programs which don't need a special setup. +Configuration for an assembler program that doesn't need a special setup. Parameters: diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 136f074b5..3a53b6b8c 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -168,9 +168,44 @@ Parameters: </descrip><p> +<sect1><tt/apple2enh-hgr.cfg/<p> + +Configuration for a program including a hires page. See <tt>testcode/lib/apple/hgrtest.c</tt> +for an example of such a program. + +Parameters: + +<descrip> + + <tag><tt/STARTADDRESS:/ Program start address</tag> + Default: $803. Use <tt/-S <addr>/ to set a different start address. + + <tag><tt/__EXEHDR__:/ Executable file header</tag> + Default: DOS 3.3 header (address and length). Use <tt/-D __EXEHDR__=0/ to omit + the header. + + <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> + Default: $800. Use <tt/-D __STACKSIZE__=<size>/ to set a different + stack size. + + <tag><tt/__HIMEM__:/ Highest usable memory address presumed at link time</tag> + Default: $9600. Use <tt/-D __HIMEM__=<addr>/ to set a different + highest usable address. + + <tag><tt/__LCADDR__:/ Address of code in the Language Card</tag> + Default: $D400. Use <tt/-D __LCADDR__=<addr>/ to set a different + code address. + + <tag><tt/__LCSIZE__:/ Size of code in the Language Card</tag> + Default: $C00. Use <tt/-D __LCSIZE__=<size>/ to set a different + code size. + +</descrip><p> + + <sect1><tt/apple2enh-overlay.cfg/<p> -Configuration for overlay programs with the up to nine overlays. The overlay files +Configuration for an overlay program with up to nine overlays. The overlay files don't include the DOS 3.3 header. See <tt>samples/overlaydemo.c</tt> for more information on overlays. @@ -210,7 +245,7 @@ Parameters: <sect1><tt/apple2enh-asm.cfg/<p> -Configuration for a assembler programs which don't need a special setup. +Configuration for an assembler program that doesn't need a special setup. Parameters: From 5145235b978e42ffe49641477ef6427de51c1cc0 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 1 Feb 2018 21:46:56 +0100 Subject: [PATCH 0565/2161] Updated AppleCommander URL. --- samples/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Makefile b/samples/Makefile index 59841d655..2bcfa08c3 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -44,7 +44,7 @@ ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),) # This one comes with VICE C1541 ?= c1541 - # For this one see http://applecommander.sourceforge.net/ + # For this one see https://applecommander.github.io/ AC ?= ac.jar # For this one see http://www.horus.com/~hias/atari/ From 9031320dff93ea93c97f82b3890d79558086ec79 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 1 Feb 2018 21:50:54 +0100 Subject: [PATCH 0566/2161] Added Makefile for recently added linker config test program. --- testcode/lib/apple2/Makefile | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 testcode/lib/apple2/Makefile diff --git a/testcode/lib/apple2/Makefile b/testcode/lib/apple2/Makefile new file mode 100644 index 000000000..87dadcbe7 --- /dev/null +++ b/testcode/lib/apple2/Makefile @@ -0,0 +1,12 @@ +# For this one see https://applecommander.github.io/ +AC ?= ac.jar + +CL = cl65 +CLFLAGS = -t apple2 -C apple2-hgr.cfg -Oirs + +hgrtest.dsk: hgrtest + cp prodos.dsk $@ + java -jar $(AC) -cc65 $@ hgrtest bin <hgrtest + +hgrtest: hgrtest.c werner.s + $(CL) $(CLFLAGS) -m hgrtest.map $^ From 27dacca4d38b54b7a44e9d0b1a7e4fc948c14df8 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 1 Feb 2018 22:06:59 +0100 Subject: [PATCH 0567/2161] Added missing dummy libref. --- libsrc/supervision/libref.s | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 libsrc/supervision/libref.s diff --git a/libsrc/supervision/libref.s b/libsrc/supervision/libref.s new file mode 100644 index 000000000..e4afa7eb1 --- /dev/null +++ b/libsrc/supervision/libref.s @@ -0,0 +1,8 @@ +; +; Oliver Schmidt, 2013-05-31 +; + + .export joy_libref + .import _exit + +joy_libref := _exit From 1976d6cd32f909babc5f6f26c9c068f47abb95bc Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 1 Feb 2018 22:38:36 +0100 Subject: [PATCH 0568/2161] Removed IRQ support from joystick drivers. All but one joystick drivers didn't use IRQs. Espsecially when the joystick driver kernel was the only .interruptor this meant quite some unnecessary overhead because it pulled in the whole IRQ infrastructure. I was told that the one driver using IRQs (the DXS/HIT-4 Player joystick driver for the C64) can be reworked to not do it. Until this is done that driver is defunct. --- asminc/joy-kernel.inc | 3 +-- libsrc/apple2/joy/a2.stdjoy.s | 1 - libsrc/atari/joy/atrmj8.s | 1 - libsrc/atari/joy/atrstd.s | 1 - libsrc/atari5200/joy/atr5200std.s | 1 - libsrc/atmos/joy/atmos-ijk.s | 12 ------------ libsrc/atmos/joy/atmos-pase.s | 1 - libsrc/c128/joy/c128-ptvjoy.s | 1 - libsrc/c128/joy/c128-stdjoy.s | 1 - libsrc/c64/joy/c64-hitjoy.s | 1 - libsrc/c64/joy/c64-numpad.s | 1 - libsrc/c64/joy/c64-ptvjoy.s | 1 - libsrc/c64/joy/c64-stdjoy.s | 1 - libsrc/cbm510/joy/cbm510-std.s | 1 - libsrc/creativision/joy/creativision-stdjoy.s | 1 - libsrc/gamate/joy/gamate-stdjoy.s | 1 - libsrc/joystick/joy-kernel.s | 18 +----------------- libsrc/joystick/joy_read.s | 2 -- libsrc/lynx/joy/lynx-stdjoy.s | 1 - libsrc/nes/joy/nes-stdjoy.s | 1 - libsrc/pce/joy/pce-stdjoy.s | 1 - libsrc/pet/joy/pet-ptvjoy.s | 1 - libsrc/pet/joy/pet-stdjoy.s | 1 - libsrc/plus4/joy/plus4-stdjoy.s | 1 - libsrc/supervision/joy/supervision-stdjoy.s | 1 - libsrc/vic20/joy/vic20-ptvjoy.s | 1 - libsrc/vic20/joy/vic20-stdjoy.s | 1 - 27 files changed, 2 insertions(+), 56 deletions(-) diff --git a/asminc/joy-kernel.inc b/asminc/joy-kernel.inc index c8cc29820..ef729fe3c 100644 --- a/asminc/joy-kernel.inc +++ b/asminc/joy-kernel.inc @@ -48,14 +48,13 @@ UNINSTALL .addr ; UNINSTALL routine COUNT .addr ; COUNT routine READ .addr ; READ routine - IRQ .addr ; IRQ routine .endstruct .endstruct ;------------------------------------------------------------------------------ ; The JOY API version, stored in JOY_HDR::VERSION -JOY_API_VERSION = $04 +JOY_API_VERSION = $05 ;------------------------------------------------------------------------------ ; Variables diff --git a/libsrc/apple2/joy/a2.stdjoy.s b/libsrc/apple2/joy/a2.stdjoy.s index ed2083255..7e90f7b98 100644 --- a/libsrc/apple2/joy/a2.stdjoy.s +++ b/libsrc/apple2/joy/a2.stdjoy.s @@ -52,7 +52,6 @@ PREAD := $FB1E ; Read paddle in X, return AD conv. value in Y .addr UNINSTALL .addr COUNT .addr READJOY - .addr 0 ; IRQ not used ; ------------------------------------------------------------------------ diff --git a/libsrc/atari/joy/atrmj8.s b/libsrc/atari/joy/atrmj8.s index 0e8cd2a0a..9b02485d6 100644 --- a/libsrc/atari/joy/atrmj8.s +++ b/libsrc/atari/joy/atrmj8.s @@ -41,7 +41,6 @@ .addr UNINSTALL .addr COUNT .addr READJOY - .addr 0 ; IRQ entry not used ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/atari/joy/atrstd.s b/libsrc/atari/joy/atrstd.s index 0c8799e21..0c49499f8 100644 --- a/libsrc/atari/joy/atrstd.s +++ b/libsrc/atari/joy/atrstd.s @@ -40,7 +40,6 @@ .addr UNINSTALL .addr COUNT .addr READJOY - .addr 0 ; IRQ entry not used ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/atari5200/joy/atr5200std.s b/libsrc/atari5200/joy/atr5200std.s index 0b8b93b63..041dc6830 100644 --- a/libsrc/atari5200/joy/atr5200std.s +++ b/libsrc/atari5200/joy/atr5200std.s @@ -33,7 +33,6 @@ .addr UNINSTALL .addr COUNT .addr READJOY - .addr 0 ; IRQ entry not used .code diff --git a/libsrc/atmos/joy/atmos-ijk.s b/libsrc/atmos/joy/atmos-ijk.s index f59f6b96a..6e75a3e0b 100644 --- a/libsrc/atmos/joy/atmos-ijk.s +++ b/libsrc/atmos/joy/atmos-ijk.s @@ -27,24 +27,12 @@ .addr $0000 -; Button state masks (8 values) - - .byte $10 ; JOY_UP - .byte $08 ; JOY_DOWN - .byte $01 ; JOY_LEFT - .byte $02 ; JOY_RIGHT - .byte $20 ; JOY_FIRE - .byte $00 ; Future expansion - .byte $00 ; Future expansion - .byte $00 ; Future expansion - ; Jump table. .addr INSTALL .addr UNINSTALL .addr COUNT .addr READ - .addr 0 ; IRQ entry unused ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/atmos/joy/atmos-pase.s b/libsrc/atmos/joy/atmos-pase.s index 637571c04..fd64901c9 100644 --- a/libsrc/atmos/joy/atmos-pase.s +++ b/libsrc/atmos/joy/atmos-pase.s @@ -34,7 +34,6 @@ .addr UNINSTALL .addr COUNT .addr READ - .addr 0 ; IRQ entry unused ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/c128/joy/c128-ptvjoy.s b/libsrc/c128/joy/c128-ptvjoy.s index c9ae39a47..180f7667d 100644 --- a/libsrc/c128/joy/c128-ptvjoy.s +++ b/libsrc/c128/joy/c128-ptvjoy.s @@ -36,7 +36,6 @@ .addr UNINSTALL .addr COUNT .addr READ - .addr 0 ; IRQ entry unused ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/c128/joy/c128-stdjoy.s b/libsrc/c128/joy/c128-stdjoy.s index 943361da5..bf2e2fea7 100644 --- a/libsrc/c128/joy/c128-stdjoy.s +++ b/libsrc/c128/joy/c128-stdjoy.s @@ -36,7 +36,6 @@ .addr UNINSTALL .addr COUNT .addr READ - .addr 0 ; IRQ entry not used ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/c64/joy/c64-hitjoy.s b/libsrc/c64/joy/c64-hitjoy.s index 10c936399..9f6c0b4dd 100644 --- a/libsrc/c64/joy/c64-hitjoy.s +++ b/libsrc/c64/joy/c64-hitjoy.s @@ -35,7 +35,6 @@ .addr UNINSTALL .addr COUNT .addr READ - .addr IRQ ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/c64/joy/c64-numpad.s b/libsrc/c64/joy/c64-numpad.s index 5ed7af187..0ccdc4fcd 100644 --- a/libsrc/c64/joy/c64-numpad.s +++ b/libsrc/c64/joy/c64-numpad.s @@ -36,7 +36,6 @@ .addr UNINSTALL .addr COUNT .addr READ - .addr 0 ; IRQ entry unused ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/c64/joy/c64-ptvjoy.s b/libsrc/c64/joy/c64-ptvjoy.s index af5c27e13..a772fb5f6 100644 --- a/libsrc/c64/joy/c64-ptvjoy.s +++ b/libsrc/c64/joy/c64-ptvjoy.s @@ -35,7 +35,6 @@ .addr UNINSTALL .addr COUNT .addr READ - .addr 0 ; IRQ entry unused ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/c64/joy/c64-stdjoy.s b/libsrc/c64/joy/c64-stdjoy.s index 930ad6227..c983d81bb 100644 --- a/libsrc/c64/joy/c64-stdjoy.s +++ b/libsrc/c64/joy/c64-stdjoy.s @@ -35,7 +35,6 @@ .addr UNINSTALL .addr COUNT .addr READ - .addr 0 ; IRQ entry unused ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/cbm510/joy/cbm510-std.s b/libsrc/cbm510/joy/cbm510-std.s index 0c2efc12d..4e47fc1a0 100644 --- a/libsrc/cbm510/joy/cbm510-std.s +++ b/libsrc/cbm510/joy/cbm510-std.s @@ -36,7 +36,6 @@ .addr UNINSTALL .addr COUNT .addr READ - .addr 0 ; IRQ entry unused ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/creativision/joy/creativision-stdjoy.s b/libsrc/creativision/joy/creativision-stdjoy.s index 9a5afc42b..5cf46c39f 100644 --- a/libsrc/creativision/joy/creativision-stdjoy.s +++ b/libsrc/creativision/joy/creativision-stdjoy.s @@ -33,7 +33,6 @@ .addr UNINSTALL .addr COUNT .addr READJOY - .addr 0 ; IRQ entry not used ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/gamate/joy/gamate-stdjoy.s b/libsrc/gamate/joy/gamate-stdjoy.s index 801b40acd..8f927cdf5 100644 --- a/libsrc/gamate/joy/gamate-stdjoy.s +++ b/libsrc/gamate/joy/gamate-stdjoy.s @@ -30,7 +30,6 @@ .addr UNINSTALL .addr COUNT .addr READJOY - .addr 0 ; IRQ entry unused ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/joystick/joy-kernel.s b/libsrc/joystick/joy-kernel.s index 0746709e9..c2d50c8d8 100644 --- a/libsrc/joystick/joy-kernel.s +++ b/libsrc/joystick/joy-kernel.s @@ -6,7 +6,6 @@ .import joy_libref .importzp ptr1 - .interruptor joy_irq ; Export as IRQ handler .include "joy-kernel.inc" .include "joy-error.inc" @@ -26,7 +25,6 @@ joy_install: jmp $0000 joy_uninstall: jmp $0000 joy_count: jmp $0000 joy_read: jmp $0000 -joy_irq: .byte $60, $00, $00 ; RTS plus two dummy bytes ; Driver header signature .rodata @@ -73,18 +71,7 @@ _joy_install: cpy #(JOY_HDR::JUMPTAB + .sizeof(JOY_HDR::JUMPTAB)) bne @L1 - jsr joy_install ; Call driver install routine - tay ; Test error code - bne @L2 ; Bail out if install had errors - -; Install the IRQ vector if the driver needs it. A/X contains the error code -; from joy_install, so don't use it. - - ldy joy_irq+2 ; Check high byte of IRQ vector - beq @L2 ; Jump if vector invalid - ldy #$4C ; JMP opcode - sty joy_irq ; Activate IRQ routine -@L2: rts + jmp joy_install ; Call driver install routine ; Driver signature invalid @@ -108,9 +95,6 @@ copy: lda (ptr1),y ; */ _joy_uninstall: - lda #$60 ; RTS opcode - sta joy_irq ; Disable IRQ entry point - jsr joy_uninstall ; Call the driver routine _joy_clear_ptr: ; External entry point diff --git a/libsrc/joystick/joy_read.s b/libsrc/joystick/joy_read.s index f76d9dfb7..151600aee 100644 --- a/libsrc/joystick/joy_read.s +++ b/libsrc/joystick/joy_read.s @@ -8,5 +8,3 @@ .include "joy-kernel.inc" _joy_read = joy_read ; Use driver entry - - diff --git a/libsrc/lynx/joy/lynx-stdjoy.s b/libsrc/lynx/joy/lynx-stdjoy.s index 2e91cc43b..c81a97dbf 100644 --- a/libsrc/lynx/joy/lynx-stdjoy.s +++ b/libsrc/lynx/joy/lynx-stdjoy.s @@ -37,7 +37,6 @@ .addr UNINSTALL .addr COUNT .addr READ - .addr 0 ; IRQ entry unused ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/nes/joy/nes-stdjoy.s b/libsrc/nes/joy/nes-stdjoy.s index 3032e9330..63caf364b 100644 --- a/libsrc/nes/joy/nes-stdjoy.s +++ b/libsrc/nes/joy/nes-stdjoy.s @@ -35,7 +35,6 @@ .addr UNINSTALL .addr COUNT .addr READJOY - .addr 0 ; IRQ entry unused ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/pce/joy/pce-stdjoy.s b/libsrc/pce/joy/pce-stdjoy.s index ab25134dd..c0f338f90 100644 --- a/libsrc/pce/joy/pce-stdjoy.s +++ b/libsrc/pce/joy/pce-stdjoy.s @@ -30,7 +30,6 @@ .addr UNINSTALL .addr COUNT .addr READJOY - .addr 0 ; IRQ entry unused ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/pet/joy/pet-ptvjoy.s b/libsrc/pet/joy/pet-ptvjoy.s index 3bb368355..7620013be 100644 --- a/libsrc/pet/joy/pet-ptvjoy.s +++ b/libsrc/pet/joy/pet-ptvjoy.s @@ -34,7 +34,6 @@ .addr UNINSTALL .addr COUNT .addr READ - .addr 0 ; IRQ entry unused ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/pet/joy/pet-stdjoy.s b/libsrc/pet/joy/pet-stdjoy.s index 29c6de627..85b742302 100644 --- a/libsrc/pet/joy/pet-stdjoy.s +++ b/libsrc/pet/joy/pet-stdjoy.s @@ -33,7 +33,6 @@ .addr UNINSTALL .addr COUNT .addr READ - .addr 0 ; IRQ entry unused ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/plus4/joy/plus4-stdjoy.s b/libsrc/plus4/joy/plus4-stdjoy.s index d998b2699..e8e85fedc 100644 --- a/libsrc/plus4/joy/plus4-stdjoy.s +++ b/libsrc/plus4/joy/plus4-stdjoy.s @@ -37,7 +37,6 @@ .addr UNINSTALL .addr COUNT .addr READ - .addr 0 ; IRQ entry unused ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/supervision/joy/supervision-stdjoy.s b/libsrc/supervision/joy/supervision-stdjoy.s index f6a325740..d233a8600 100644 --- a/libsrc/supervision/joy/supervision-stdjoy.s +++ b/libsrc/supervision/joy/supervision-stdjoy.s @@ -29,7 +29,6 @@ .addr UNINSTALL .addr COUNT .addr READJOY - .addr 0 ; IRQ entry unused ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/vic20/joy/vic20-ptvjoy.s b/libsrc/vic20/joy/vic20-ptvjoy.s index 3b1db402a..bf0ff128e 100644 --- a/libsrc/vic20/joy/vic20-ptvjoy.s +++ b/libsrc/vic20/joy/vic20-ptvjoy.s @@ -36,7 +36,6 @@ .addr UNINSTALL .addr COUNT .addr READ - .addr 0 ; IRQ entry unused ; ------------------------------------------------------------------------ ; Constants diff --git a/libsrc/vic20/joy/vic20-stdjoy.s b/libsrc/vic20/joy/vic20-stdjoy.s index 67299cc1a..e5539c653 100644 --- a/libsrc/vic20/joy/vic20-stdjoy.s +++ b/libsrc/vic20/joy/vic20-stdjoy.s @@ -36,7 +36,6 @@ .addr UNINSTALL .addr COUNT .addr READ - .addr 0 ; IRQ entry unused ; ------------------------------------------------------------------------ ; Constants From f15cd3e468f68454706b44ff167570f7fea5886b Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 2 Feb 2018 12:02:52 +0100 Subject: [PATCH 0569/2161] Removed IRQ support from joystick drivers. --- include/joystick/joy-kernel.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/joystick/joy-kernel.h b/include/joystick/joy-kernel.h index e984291f7..783508247 100644 --- a/include/joystick/joy-kernel.h +++ b/include/joystick/joy-kernel.h @@ -59,7 +59,6 @@ typedef struct { void* uninstall; /* UNINSTALL routine */ void* count; /* COUNT routine */ void* read; /* READ routine */ - void* irq; /* IRQ routine */ } joy_drv_header; From 935f68f686ae13b93522d73bb0f9996eb9527489 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 2 Feb 2018 12:28:22 +0100 Subject: [PATCH 0570/2161] Harmonized the style of including headers from headers. We surely don't care about some file I/O on host machines in 2018 ;-) --- include/ace.h | 2 -- include/apple2.h | 3 ++- include/apple2enh.h | 5 +---- include/atari.h | 2 ++ include/atari2600.h | 8 +++++++- include/c16.h | 2 -- include/cbm.h | 5 +---- include/geos.h | 37 ++----------------------------------- include/geos/gdisk.h | 2 -- include/geos/gfile.h | 2 -- include/geos/ggraph.h | 2 -- include/geos/gmemory.h | 2 -- include/geos/gmenu.h | 2 -- include/geos/gprocess.h | 2 -- include/geos/gsym.h | 2 -- include/lynx.h | 5 +++++ include/plus4.h | 2 -- include/stdio.h | 11 ++--------- 18 files changed, 22 insertions(+), 74 deletions(-) diff --git a/include/ace.h b/include/ace.h index fba672227..8ce86e18f 100644 --- a/include/ace.h +++ b/include/ace.h @@ -45,9 +45,7 @@ -#ifndef _STDDEF_H #include <stddef.h> -#endif diff --git a/include/apple2.h b/include/apple2.h index 31e56a95a..f217ad04c 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -41,9 +41,10 @@ # error This module may only be used when compiling for the Apple ][! #endif - #include <apple2_filetype.h> + + /*****************************************************************************/ /* Data */ /*****************************************************************************/ diff --git a/include/apple2enh.h b/include/apple2enh.h index cc62f70b7..77328b5ed 100644 --- a/include/apple2enh.h +++ b/include/apple2enh.h @@ -42,10 +42,7 @@ -/* If not already done, include the apple2.h header file */ -#if !defined(_APPLE2_H) -# include <apple2.h> -#endif +#include <apple2.h> diff --git a/include/atari.h b/include/atari.h index bf1af7d7b..4bed8d7a7 100644 --- a/include/atari.h +++ b/include/atari.h @@ -355,5 +355,7 @@ struct __iocb { #define IOCB_GETCWD 0x30 /* get current directory (MyDOS/SpartaDOS) */ #define IOCB_FORMAT 0xFE /* format */ + + /* End of atari.h */ #endif diff --git a/include/atari2600.h b/include/atari2600.h index 1eb51a2dd..a6b5cda47 100644 --- a/include/atari2600.h +++ b/include/atari2600.h @@ -8,9 +8,13 @@ /* */ /*****************************************************************************/ + + #ifndef _ATARI2600_H #define _ATARI2600_H + + /* Check for errors */ #if !defined(__ATARI2600__) # error This module may only be used when compiling for the Atari 2600! @@ -22,5 +26,7 @@ #include <_riot.h> #define RIOT (*(struct __riot*)0x0280) + + /* End of atari2600.h */ -#endif /* #ifndef _ATARI2600_H */ +#endif diff --git a/include/c16.h b/include/c16.h index d49ca6fd4..c039218f9 100644 --- a/include/c16.h +++ b/include/c16.h @@ -47,9 +47,7 @@ /* Include the base header file for the 264 series. include file. */ -#ifndef _CBM264_H #include <cbm264.h> -#endif diff --git a/include/cbm.h b/include/cbm.h index da63375b2..1395f700f 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -46,10 +46,7 @@ /* We need NULL. */ - -#if !defined(_STDDEF_H) -# include <stddef.h> -#endif +#include <stddef.h> /* Load the system-specific files here, if needed. */ #if defined(__C64__) && !defined(_C64_H) diff --git a/include/geos.h b/include/geos.h index ae356d679..3f760b6ad 100644 --- a/include/geos.h +++ b/include/geos.h @@ -19,53 +19,19 @@ -#ifndef _GCONST_H #include <geos/gconst.h> -#endif - -#ifndef _GSTRUCT_H #include <geos/gstruct.h> -#endif - -#ifndef _GSYM_H #include <geos/gsym.h> -#endif - -#ifndef _GDISK_H #include <geos/gdisk.h> -#endif - -#ifndef _GFILE_H #include <geos/gfile.h> -#endif - -#ifndef _GPROCESS_H #include <geos/gprocess.h> -#endif - -#ifndef _GGRAPH_H #include <geos/ggraph.h> -#endif - -#ifndef _GMENU_H #include <geos/gmenu.h> -#endif - -#ifndef _GSPRITE_H #include <geos/gsprite.h> -#endif - -#ifndef _GMEMORY_H #include <geos/gmemory.h> -#endif - -#ifndef _GSYS_H #include <geos/gsys.h> -#endif - -#ifndef _GDLGBOX_H #include <geos/gdlgbox.h> -#endif + #define CH_ULCORNER '+' @@ -140,5 +106,6 @@ #define JOY_BTN_1_MASK 0x10 + /* End of geos.h */ #endif diff --git a/include/geos/gdisk.h b/include/geos/gdisk.h index f65d7d301..30305a2fc 100644 --- a/include/geos/gdisk.h +++ b/include/geos/gdisk.h @@ -7,9 +7,7 @@ #ifndef _GDISK_H #define _GDISK_H -#ifndef _GSTRUCT_H #include <geos/gstruct.h> -#endif char __fastcall__ ReadBuff(struct tr_se *myTrSe); char __fastcall__ WriteBuff(struct tr_se *myTrSe); diff --git a/include/geos/gfile.h b/include/geos/gfile.h index d7667d8ec..ec7a75bbc 100644 --- a/include/geos/gfile.h +++ b/include/geos/gfile.h @@ -7,9 +7,7 @@ #ifndef _GFILE_H #define _GFILE_H -#ifndef _GSTRUCT_H #include <geos/gstruct.h> -#endif struct filehandle *Get1stDirEntry(void); struct filehandle *GetNxtDirEntry(void); diff --git a/include/geos/ggraph.h b/include/geos/ggraph.h index 961ec2d80..35e02c198 100644 --- a/include/geos/ggraph.h +++ b/include/geos/ggraph.h @@ -7,9 +7,7 @@ #ifndef _GGRAPH_H #define _GGRAPH_H -#ifndef _GSTRUCT_H #include <geos/gstruct.h> -#endif void __fastcall__ SetPattern(char newpattern); diff --git a/include/geos/gmemory.h b/include/geos/gmemory.h index 3fba5cb5b..ba8e9f211 100644 --- a/include/geos/gmemory.h +++ b/include/geos/gmemory.h @@ -7,9 +7,7 @@ #ifndef _GMEMORY_H #define _GMEMORY_H -#ifndef _GSTRUCT_H #include <geos/gstruct.h> -#endif void __fastcall__ CopyString(char *dest, const char *source); char __fastcall__ CmpString(const char *dest, const char *source); diff --git a/include/geos/gmenu.h b/include/geos/gmenu.h index 3175b6cf3..89caa2c02 100644 --- a/include/geos/gmenu.h +++ b/include/geos/gmenu.h @@ -7,9 +7,7 @@ #ifndef _GMENU_H #define _GMENU_H -#ifndef _GSTRUCT_H #include <geos/gstruct.h> -#endif void __fastcall__ DoMenu(struct menu *myMenu); void ReDoMenu(void); diff --git a/include/geos/gprocess.h b/include/geos/gprocess.h index 6fab2ecfa..000003f32 100644 --- a/include/geos/gprocess.h +++ b/include/geos/gprocess.h @@ -7,9 +7,7 @@ #ifndef _GPROCESS_H #define _GPROCESS_H -#ifndef _GSTRUCT_H #include <geos/gstruct.h> -#endif void __fastcall__ InitProcesses(char number, struct process *proctab); void __fastcall__ RestartProcess(char number); diff --git a/include/geos/gsym.h b/include/geos/gsym.h index 085046674..2b2c8fbb2 100644 --- a/include/geos/gsym.h +++ b/include/geos/gsym.h @@ -7,9 +7,7 @@ #ifndef _GSYM_H #define _GSYM_H -#ifndef _GSTRUCT_H #include <geos/gstruct.h> -#endif #define r0 (*(unsigned*)(R_BASE + 0x00)) #define r0L (*(char*)(R_BASE + 0x00)) diff --git a/include/lynx.h b/include/lynx.h index 3629f322e..4b0390a13 100644 --- a/include/lynx.h +++ b/include/lynx.h @@ -123,6 +123,8 @@ extern void lynx_160_102_16_tgi[]; /* Referred to by tgi_static_stddrv[] */ /* Sound support */ /*****************************************************************************/ + + void lynx_snd_init (void); /* Initialize the sound driver */ @@ -144,6 +146,8 @@ void __fastcall__ lynx_snd_stop_channel (unsigned char channel); unsigned char lynx_snd_active(void); /* Show which channels are active */ + + /*****************************************************************************/ /* Accessing the cart */ /*****************************************************************************/ @@ -209,5 +213,6 @@ unsigned __fastcall__ lynx_eewrite (unsigned cell, unsigned val); #define SUZY (*(struct __suzy*)0xFC00) + /* End of lynx.h */ #endif diff --git a/include/plus4.h b/include/plus4.h index 840e8b342..81e3c5286 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -47,9 +47,7 @@ /* Include the base header file for the 264 series. include file. */ -#ifndef _CBM264_H #include <cbm264.h> -#endif /* Define hardware */ #include <_6551.h> diff --git a/include/stdio.h b/include/stdio.h index a3facd513..73dc05bdb 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -38,12 +38,8 @@ -#ifndef _STDDEF_H -# include <stddef.h> -#endif -#ifndef _STDARG_H -# include <stdarg.h> -#endif +#include <stddef.h> +#include <stdarg.h> @@ -147,6 +143,3 @@ void __fastcall__ _poserror (const char* msg); /* cc65 */ /* End of stdio.h */ #endif - - - From 2cf1bb89be0fec491d3c24cd238325651d0e55fb Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 2 Feb 2018 12:35:40 +0100 Subject: [PATCH 0571/2161] Removed ACE header. There's no code in the tool chain to set __ACE__ nor is there an ace.lib C library. --- include/ace.h | 117 -------------------------------------------------- 1 file changed, 117 deletions(-) delete mode 100644 include/ace.h diff --git a/include/ace.h b/include/ace.h deleted file mode 100644 index 8ce86e18f..000000000 --- a/include/ace.h +++ /dev/null @@ -1,117 +0,0 @@ -/*****************************************************************************/ -/* */ -/* ace.h */ -/* */ -/* ACE system-specific definitions */ -/* */ -/* */ -/* */ -/* (C) 1998-2015, 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 _ACE_H -#define _ACE_H - - - -/* Check for errors */ -#if !defined(__ACE__) -# error This module may only be used when compiling for the ACE os! -#endif - - - -#include <stddef.h> - - - -struct aceDirentBuf { - unsigned long ad_size; /* Size in bytes */ - unsigned char ad_date [8]; /* YY:YY:MM:DD:HH:MM:SS:TW */ - char ad_type [4]; /* File type as ASCIIZ string */ - unsigned char ad_flags; /* File flags */ - unsigned char ad_usage; /* More flags */ - unsigned char ad_namelen; /* Length of name */ - char ad_name [17]; /* Name itself, ASCIIZ */ -}; - -int __cdecl__ aceDirOpen (char* dir); -int __cdecl__ aceDirClose (int handle); -int __cdecl__ aceDirRead (int handle, struct aceDirentBuf* buf); - -/* Type of an ACE key. Key in low byte, shift mask in high byte */ -typedef unsigned int aceKey; - -/* #defines for the shift mask returned by aceConGetKey */ -#define aceSH_KEY 0x00FF /* Mask key itself */ -#define aceSH_MASK 0xFF00 /* Mask shift mask */ -#define aceSH_EXT 0x2000 /* Extended key */ -#define aceSH_CAPS 0x1000 /* Caps lock key */ -#define aceSH_ALT 0x0800 /* Alternate key */ -#define aceSH_CTRL 0x0400 /* Ctrl key */ -#define aceSH_CBM 0x0200 /* Commodore key */ -#define aceSH_SHIFT 0x0100 /* Shift key */ - -/* #defines for the options in aceConSetOpt/aceConGetOpt */ -#define aceOP_PUTMASK 1 /* Console put mask */ -#define aceOP_CHARCOLOR 2 /* Character color */ -#define aceOP_CHARATTR 3 /* Character attribute */ -#define aceOP_FILLCOLOR 4 /* Fill color */ -#define aceOP_FILLATTR 5 /* Fill attribute */ -#define aceOP_CRSCOLOR 6 /* Cursor color */ -#define aceOP_CRSWRAP 7 /* Force cursor wrap */ -#define aceOP_SHSCROLL 8 /* Shift keys for scrolling */ -#define aceOP_MOUSCALE 9 /* Mouse scaling */ -#define aceOP_RPTDELAY 10 /* Key repeat delay */ -#define aceOP_RPTRATE 11 /* Key repeat rate */ - -/* Console functions */ -void __cdecl__ aceConWrite (char* buf, size_t count); -void __cdecl__ aceConPutLit (int c); -void __cdecl__ aceConPos (unsigned x, unsigned y); -void __cdecl__ aceConGetPos (unsigned* x, unsigned* y); -unsigned aceConGetX (void); -unsigned aceConGetY (void); -char __cdecl__* aceConInput (char* buf, unsigned initial); -int aceConStopKey (void); -aceKey aceConGetKey (void); -int __cdecl__ aceConKeyAvail (aceKey* key); -void __cdecl__ aceConKeyMat (char* matrix); -void __cdecl__ aceConSetOpt (unsigned char opt, unsigned char val); -int __cdecl__ aceConGetOpt (unsigned char opt); - -/* Misc stuff */ -int __cdecl__ aceMiscIoPeek (unsigned addr); -void __cdecl__ aceMiscIoPoke (unsigned addr, unsigned char val); - - - -/* End of ace.h */ -#endif - - - From d7afadb2fe62a2154ad5bcb949644da17e4ac7c6 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 2 Feb 2018 12:59:05 +0100 Subject: [PATCH 0572/2161] Factored out target specific inclusion of target header. So far conio.h included the target header to get the CH_... and COLOR_... macros. However tgi.h never did the same to get the TGI_COLOR_... macros. And some time ago the JOY_..._MASK macros moved from joystick.h into the target header yet joystick.h didn't include the target header. Why wasn't that issue detected so far? Because about every program using TGI and/or the joystick uses CONIO too and therefore includes the target header that way. However, conceptually it's clean to factor out the target header inclusion and have tgi.h and joystick.h do it like conio.h. Apart from that user code may make direct use of target.h too. --- include/conio.h | 44 ++++------------------------ include/joystick.h | 7 +++-- include/target.h | 73 ++++++++++++++++++++++++++++++++++++++++++++++ include/tgi.h | 6 +--- 4 files changed, 84 insertions(+), 46 deletions(-) create mode 100644 include/target.h diff --git a/include/conio.h b/include/conio.h index 9cd505766..72421af86 100644 --- a/include/conio.h +++ b/include/conio.h @@ -54,40 +54,8 @@ -#if !defined(_STDARG_H) -# include <stdarg.h> -#endif - -/* Include the correct machine-specific file */ -#if defined(__APPLE2ENH__) -# include <apple2enh.h> -#elif defined(__APPLE2__) -# include <apple2.h> -#elif defined(__ATARI5200__) -# include <atari5200.h> -#elif defined(__ATARI__) -# include <atari.h> -#elif defined(__ATMOS__) -# include <atmos.h> -#elif defined(__CBM__) -# include <cbm.h> -#elif defined(__CREATIVISION__) -# include <creativision.h> -#elif defined(__GAMATE__) -# include <gamate.h> -#elif defined(__GEOS__) -# include <geos.h> -#elif defined(__LUNIX__) -# include <lunix.h> -#elif defined(__LYNX__) -# include <lynx.h> -#elif defined(__NES__) -# include <nes.h> -#elif defined(__OSIC1P__) -# include <osic1p.h> -#elif defined(__PCE__) -# include <pce.h> -#endif +#include <stdarg.h> +#include <target.h> @@ -232,16 +200,16 @@ void __fastcall__ cputhex16 (unsigned val); ** the macro will give access to the actual function. */ -#if defined(_textcolor) +#ifdef _textcolor # define textcolor(x) _textcolor(x) #endif -#if defined(_bgcolor) +#ifdef _bgcolor # define bgcolor(x) _bgcolor(x) #endif -#if defined(_bordercolor) +#ifdef _bordercolor # define bordercolor(x) _bordercolor(x) #endif -#if defined(_cpeekcolor) +#ifdef _cpeekcolor # define cpeekcolor(x) _cpeekcolor(x) #endif diff --git a/include/joystick.h b/include/joystick.h index 26f339fe4..b6771c381 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -38,6 +38,10 @@ +#include <target.h> + + + /*****************************************************************************/ /* Definitions */ /*****************************************************************************/ @@ -103,6 +107,3 @@ unsigned char __fastcall__ joy_read (unsigned char joystick); /* End of joystick.h */ #endif - - - diff --git a/include/target.h b/include/target.h new file mode 100644 index 000000000..af401ec35 --- /dev/null +++ b/include/target.h @@ -0,0 +1,73 @@ +/*****************************************************************************/ +/* */ +/* target.h */ +/* */ +/* Target specific definitions */ +/* */ +/* */ +/* */ +/* 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 _TARGET_H +#define _TARGET_H + + + +/* Include the correct target specific file */ +#if defined(__APPLE2ENH__) +# include <apple2enh.h> +#elif defined(__APPLE2__) +# include <apple2.h> +#elif defined(__ATARI__) +# include <atari.h> +#elif defined(__ATARI2600__) +# include <atari2600.h> +#elif defined(__ATARI5200__) +# include <atari5200.h> +#elif defined(__ATMOS__) +# include <atmos.h> +#elif defined(__CBM__) +# include <cbm.h> +#elif defined(__CREATIVISION__) +# include <creativision.h> +#elif defined(__GAMATE__) +# include <gamate.h> +#elif defined(__GEOS__) +# include <geos.h> +#elif defined(__LYNX__) +# include <lynx.h> +#elif defined(__NES__) +# include <nes.h> +#elif defined(__OSIC1P__) +# include <osic1p.h> +#elif defined(__PCE__) +# include <pce.h> +#elif defined(__SUPERVISION__) +# include <supervision.h> +#elif defined(__TELESTRAT__) +# include <telestrat.h> +#endif + + + +/* End of target.h */ +#endif diff --git a/include/tgi.h b/include/tgi.h index 02dff8868..f458180c5 100644 --- a/include/tgi.h +++ b/include/tgi.h @@ -38,9 +38,8 @@ -#ifndef _TGI_ERROR_H #include <tgi/tgi-error.h> -#endif +#include <target.h> @@ -284,6 +283,3 @@ int __fastcall__ tgi_imulround (int rhs, int lhs); /* End of tgi.h */ #endif - - - From 7521ae888a5a0f40273d554fb06355fc3572f57d Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 2 Feb 2018 14:46:57 +0100 Subject: [PATCH 0573/2161] Marked Apple II EXEHDR segment as optional. The docs say "Use -D __EXEHDR__=0 to omit the header." so it should work without generating a linker warning. --- cfg/apple2-hgr.cfg | 2 +- cfg/apple2-overlay.cfg | 2 +- cfg/apple2.cfg | 2 +- cfg/apple2enh-hgr.cfg | 2 +- cfg/apple2enh-overlay.cfg | 2 +- cfg/apple2enh.cfg | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cfg/apple2-hgr.cfg b/cfg/apple2-hgr.cfg index 536491c67..b11dd12bc 100644 --- a/cfg/apple2-hgr.cfg +++ b/cfg/apple2-hgr.cfg @@ -19,7 +19,7 @@ MEMORY { } SEGMENTS { ZEROPAGE: load = ZP, type = zp; - EXEHDR: load = HEADER, type = ro; + EXEHDR: load = HEADER, type = ro, optional = yes; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; HGR: load = MAIN, type = rw, optional = yes, start = $2000; diff --git a/cfg/apple2-overlay.cfg b/cfg/apple2-overlay.cfg index e6a5ae25c..d5476d264 100644 --- a/cfg/apple2-overlay.cfg +++ b/cfg/apple2-overlay.cfg @@ -36,7 +36,7 @@ MEMORY { } SEGMENTS { ZEROPAGE: load = ZP, type = zp; - EXEHDR: load = HEADER, type = ro; + EXEHDR: load = HEADER, type = ro, optional = yes; STARTUP: load = MAIN, type = ro, define = yes; LOWCODE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; diff --git a/cfg/apple2.cfg b/cfg/apple2.cfg index eba2a0e66..bbe45839d 100644 --- a/cfg/apple2.cfg +++ b/cfg/apple2.cfg @@ -19,7 +19,7 @@ MEMORY { } SEGMENTS { ZEROPAGE: load = ZP, type = zp; - EXEHDR: load = HEADER, type = ro; + EXEHDR: load = HEADER, type = ro, optional = yes; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; diff --git a/cfg/apple2enh-hgr.cfg b/cfg/apple2enh-hgr.cfg index 536491c67..b11dd12bc 100644 --- a/cfg/apple2enh-hgr.cfg +++ b/cfg/apple2enh-hgr.cfg @@ -19,7 +19,7 @@ MEMORY { } SEGMENTS { ZEROPAGE: load = ZP, type = zp; - EXEHDR: load = HEADER, type = ro; + EXEHDR: load = HEADER, type = ro, optional = yes; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; HGR: load = MAIN, type = rw, optional = yes, start = $2000; diff --git a/cfg/apple2enh-overlay.cfg b/cfg/apple2enh-overlay.cfg index e6a5ae25c..d5476d264 100644 --- a/cfg/apple2enh-overlay.cfg +++ b/cfg/apple2enh-overlay.cfg @@ -36,7 +36,7 @@ MEMORY { } SEGMENTS { ZEROPAGE: load = ZP, type = zp; - EXEHDR: load = HEADER, type = ro; + EXEHDR: load = HEADER, type = ro, optional = yes; STARTUP: load = MAIN, type = ro, define = yes; LOWCODE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; diff --git a/cfg/apple2enh.cfg b/cfg/apple2enh.cfg index eba2a0e66..bbe45839d 100644 --- a/cfg/apple2enh.cfg +++ b/cfg/apple2enh.cfg @@ -19,7 +19,7 @@ MEMORY { } SEGMENTS { ZEROPAGE: load = ZP, type = zp; - EXEHDR: load = HEADER, type = ro; + EXEHDR: load = HEADER, type = ro, optional = yes; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; From dacee3b9edd1167a050add3dc5be4e661d1d877c Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 2 Feb 2018 18:15:45 +0100 Subject: [PATCH 0574/2161] Removed IRQ support from TGI drivers. All but one TGI drivers didn't use IRQs. Especially when the TGI driver kernel was the only .interruptor this meant quite some unnecessary overhead because it pulled in the whole IRQ infrastructure. The one driver using IRQs (the graphics driver for the 160x102x16 mode on the Lynx) now uses a library reference to set up a JMP to its IRQ handler. --- asminc/tgi-kernel.inc | 3 +-- libsrc/apple2/tgi/a2.hi.s | 1 - libsrc/apple2/tgi/a2.lo.s | 1 - libsrc/atari/tgi/atari_tgi_common.inc | 1 - libsrc/atmos/tgi/atmos-228-200-3.s | 1 - libsrc/atmos/tgi/atmos-240-200-2.s | 1 - libsrc/c128/tgi/c128-vdc.s | 1 - libsrc/c128/tgi/c128-vdc2.s | 1 - libsrc/c64/tgi/c64-hi.s | 1 - libsrc/geos-cbm/tgi/geos-tgi.s | 1 - libsrc/lynx/libref.s | 3 +-- libsrc/lynx/tgi/lynx-160-102-16.s | 30 +++++++++++++++------- libsrc/lynx/tgi_irq.s | 11 ++++++++ libsrc/nes/tgi/nes-64-56-2.s | 1 - libsrc/telestrat/tgi/telestrat-228-200-3.s | 1 - libsrc/telestrat/tgi/telestrat-240-200-2.s | 1 - libsrc/tgi/tgi-kernel.s | 18 +++---------- 17 files changed, 37 insertions(+), 40 deletions(-) create mode 100644 libsrc/lynx/tgi_irq.s diff --git a/asminc/tgi-kernel.inc b/asminc/tgi-kernel.inc index e9f2f6aa9..fba78afff 100644 --- a/asminc/tgi-kernel.inc +++ b/asminc/tgi-kernel.inc @@ -70,14 +70,13 @@ BAR .addr ; BAR routine TEXTSTYLE .addr ; TEXTSTYLE routine OUTTEXT .addr ; OUTTEXT routine - IRQ .addr ; IRQ routine .endstruct .endstruct ;------------------------------------------------------------------------------ ; The TGI API version, stored at TGI_HDR_VERSION -TGI_API_VERSION = $05 +TGI_API_VERSION = $06 ;------------------------------------------------------------------------------ ; Bitmapped tgi driver flags, stored in TGI_HDR::VARS::FLAGS. diff --git a/libsrc/apple2/tgi/a2.hi.s b/libsrc/apple2/tgi/a2.hi.s index 18f5724b5..e06b4a617 100644 --- a/libsrc/apple2/tgi/a2.hi.s +++ b/libsrc/apple2/tgi/a2.hi.s @@ -115,7 +115,6 @@ pages: .byte 2 ; Number of screens available .addr BAR .addr TEXTSTYLE .addr OUTTEXT - .addr 0 ; IRQ entry is unused ; ------------------------------------------------------------------------ diff --git a/libsrc/apple2/tgi/a2.lo.s b/libsrc/apple2/tgi/a2.lo.s index 045b0044f..7238463a9 100644 --- a/libsrc/apple2/tgi/a2.lo.s +++ b/libsrc/apple2/tgi/a2.lo.s @@ -85,7 +85,6 @@ Y2 := ptr4 .addr BAR .addr TEXTSTYLE .addr OUTTEXT - .addr 0 ; IRQ entry is unused ; ------------------------------------------------------------------------ diff --git a/libsrc/atari/tgi/atari_tgi_common.inc b/libsrc/atari/tgi/atari_tgi_common.inc index f4ef68165..cd486d91b 100644 --- a/libsrc/atari/tgi/atari_tgi_common.inc +++ b/libsrc/atari/tgi/atari_tgi_common.inc @@ -68,7 +68,6 @@ libref: .addr $0000 ; Library reference .addr BAR .addr TEXTSTYLE .addr OUTTEXT - .addr 0 ; IRQ entry is unused ; ****************************************************************************** diff --git a/libsrc/atmos/tgi/atmos-228-200-3.s b/libsrc/atmos/tgi/atmos-228-200-3.s index ae9b0f775..98d2cef96 100644 --- a/libsrc/atmos/tgi/atmos-228-200-3.s +++ b/libsrc/atmos/tgi/atmos-228-200-3.s @@ -59,7 +59,6 @@ YSIZE = 8 ; System font height .addr BAR .addr TEXTSTYLE .addr OUTTEXT - .addr 0 ; IRQ entry is unused ; ------------------------------------------------------------------------ ; Data. diff --git a/libsrc/atmos/tgi/atmos-240-200-2.s b/libsrc/atmos/tgi/atmos-240-200-2.s index 943ec5389..2643e08fd 100644 --- a/libsrc/atmos/tgi/atmos-240-200-2.s +++ b/libsrc/atmos/tgi/atmos-240-200-2.s @@ -59,7 +59,6 @@ YSIZE = 8 ; System font height .addr BAR .addr TEXTSTYLE .addr OUTTEXT - .addr 0 ; IRQ entry is unused ; ------------------------------------------------------------------------ ; Data. diff --git a/libsrc/c128/tgi/c128-vdc.s b/libsrc/c128/tgi/c128-vdc.s index 5100f7f7d..f48b530f6 100644 --- a/libsrc/c128/tgi/c128-vdc.s +++ b/libsrc/c128/tgi/c128-vdc.s @@ -88,7 +88,6 @@ pages: .byte 1 ; Number of screens available .addr BAR .addr TEXTSTYLE .addr OUTTEXT - .addr 0 ; IRQ entry is unused ; ------------------------------------------------------------------------ ; Data. diff --git a/libsrc/c128/tgi/c128-vdc2.s b/libsrc/c128/tgi/c128-vdc2.s index a7238e877..4b7b17c57 100644 --- a/libsrc/c128/tgi/c128-vdc2.s +++ b/libsrc/c128/tgi/c128-vdc2.s @@ -89,7 +89,6 @@ pages: .byte 0 ; Number of screens available .addr BAR .addr TEXTSTYLE .addr OUTTEXT - .addr 0 ; IRQ entry is unused ; ------------------------------------------------------------------------ ; Data. diff --git a/libsrc/c64/tgi/c64-hi.s b/libsrc/c64/tgi/c64-hi.s index 580220ecc..8368c6ba2 100644 --- a/libsrc/c64/tgi/c64-hi.s +++ b/libsrc/c64/tgi/c64-hi.s @@ -57,7 +57,6 @@ .addr BAR .addr TEXTSTYLE .addr OUTTEXT - .addr 0 ; IRQ entry is unused ; ------------------------------------------------------------------------ ; Data. diff --git a/libsrc/geos-cbm/tgi/geos-tgi.s b/libsrc/geos-cbm/tgi/geos-tgi.s index 5a1af65e4..08927e6c1 100644 --- a/libsrc/geos-cbm/tgi/geos-tgi.s +++ b/libsrc/geos-cbm/tgi/geos-tgi.s @@ -74,7 +74,6 @@ aspect: .word $00D4 ; Aspect ratio (based on 4/3 display) .addr BAR .addr TEXTSTYLE .addr OUTTEXT - .addr 0 ; IRQ entry is unused ; ------------------------------------------------------------------------ ; Data. diff --git a/libsrc/lynx/libref.s b/libsrc/lynx/libref.s index 62c78b8c5..0bda1e7e8 100644 --- a/libsrc/lynx/libref.s +++ b/libsrc/lynx/libref.s @@ -2,9 +2,8 @@ ; Oliver Schmidt, 2013-05-31 ; - .export joy_libref, ser_libref, tgi_libref + .export joy_libref, ser_libref .import _exit joy_libref := _exit ser_libref := _exit -tgi_libref := _exit diff --git a/libsrc/lynx/tgi/lynx-160-102-16.s b/libsrc/lynx/tgi/lynx-160-102-16.s index e6659631b..04bdaae04 100644 --- a/libsrc/lynx/tgi/lynx-160-102-16.s +++ b/libsrc/lynx/tgi/lynx-160-102-16.s @@ -29,7 +29,7 @@ .byte $74, $67, $69 ; "tgi" .byte TGI_API_VERSION ; TGI API version number - .addr $0000 ; Library reference +libref: .addr $0000 ; Library reference .word 160 ; X resolution .word 102 ; Y resolution .byte 16 ; Number of drawing colors @@ -64,7 +64,6 @@ .addr BAR .addr TEXTSTYLE .addr OUTTEXT - .addr IRQ ; ------------------------------------------------------------------------ @@ -164,6 +163,18 @@ INSTALL: stz BGINDEX stz DRAWPAGE stz SWAPREQUEST + lda libref + ldx libref+1 + sta ptr1 + stx ptr1+1 + ldy #1 + lda #<irq + sta (ptr1),y + iny + lda #>irq + sta (ptr1),y + lda #$4C ; Jump opcode + sta (ptr1) ; Activate IRQ routine rts @@ -175,6 +186,12 @@ INSTALL: ; UNINSTALL: + lda libref + ldx libref+1 + sta ptr1 + stx ptr1+1 + lda #$60 ; RTS opcode + sta (ptr1) ; Disable IRQ routine rts @@ -466,14 +483,10 @@ SETDRAWPAGE: stx DRAWPAGEH rts -; ------------------------------------------------------------------------ -; IRQ: VBL interrupt handler -; - -IRQ: +irq: lda INTSET ; Poll all pending interrupts and #VBL_INTERRUPT - beq IRQEND ; Exit if not a VBL interrupt + beq @L0 ; Exit if not a VBL interrupt lda SWAPREQUEST beq @L0 @@ -485,7 +498,6 @@ IRQ: jsr SETDRAWPAGE stz SWAPREQUEST @L0: -IRQEND: clc rts diff --git a/libsrc/lynx/tgi_irq.s b/libsrc/lynx/tgi_irq.s new file mode 100644 index 000000000..3968dc0b5 --- /dev/null +++ b/libsrc/lynx/tgi_irq.s @@ -0,0 +1,11 @@ +; +; Oliver Schmidt, 2018-02-02 +; + + .export tgi_libref + .interruptor tgi_irq ; Export as IRQ handler + + .data + +tgi_libref: +tgi_irq: .byte $60, $00, $00 ; RTS plus two dummy bytes diff --git a/libsrc/nes/tgi/nes-64-56-2.s b/libsrc/nes/tgi/nes-64-56-2.s index 70e23e119..e4dcb56ce 100644 --- a/libsrc/nes/tgi/nes-64-56-2.s +++ b/libsrc/nes/tgi/nes-64-56-2.s @@ -60,7 +60,6 @@ yres: .word 56 ; Max Y resolution .addr BAR .addr TEXTSTYLE .addr OUTTEXT - .addr 0 ; IRQ entry is unused ; ------------------------------------------------------------------------ ; Data. diff --git a/libsrc/telestrat/tgi/telestrat-228-200-3.s b/libsrc/telestrat/tgi/telestrat-228-200-3.s index 09c308e26..ce501f0bf 100644 --- a/libsrc/telestrat/tgi/telestrat-228-200-3.s +++ b/libsrc/telestrat/tgi/telestrat-228-200-3.s @@ -58,7 +58,6 @@ YSIZE = 8 ; System font height .addr CIRCLE .addr TEXTSTYLE .addr OUTTEXT - .addr 0 ; IRQ entry is unused ; ------------------------------------------------------------------------ ; Data. diff --git a/libsrc/telestrat/tgi/telestrat-240-200-2.s b/libsrc/telestrat/tgi/telestrat-240-200-2.s index 8a30ddd45..3ee918c4f 100644 --- a/libsrc/telestrat/tgi/telestrat-240-200-2.s +++ b/libsrc/telestrat/tgi/telestrat-240-200-2.s @@ -58,7 +58,6 @@ YSIZE = 8 ; System font height .addr BAR .addr TEXTSTYLE .addr OUTTEXT - .addr 0 ; IRQ entry is unused ; ------------------------------------------------------------------------ ; Data. diff --git a/libsrc/tgi/tgi-kernel.s b/libsrc/tgi/tgi-kernel.s index ed65760af..3a388b6dc 100644 --- a/libsrc/tgi/tgi-kernel.s +++ b/libsrc/tgi/tgi-kernel.s @@ -6,7 +6,6 @@ .import tgi_libref .importzp ptr1 - .interruptor tgi_irq ; Export as IRQ handler .include "tgi-kernel.inc" .include "tgi-error.inc" @@ -81,7 +80,6 @@ tgi_line: jmp $0000 tgi_bar: jmp $0000 tgi_textstyle: jmp $0000 tgi_outtext: jmp $0000 -tgi_irq: .byte $60, $00, $00 ; RTS plus two dummy bytes ; Driver header signature .rodata @@ -144,20 +142,13 @@ _tgi_install: dex bpl @L3 -; Install the IRQ vector if the driver needs it. - - lda tgi_irq+2 ; Check high byte of IRQ vector - beq @L4 ; Jump if vector invalid - lda #$4C ; Jump opcode - sta tgi_irq ; Activate IRQ routine - ; Initialize some other variables lda #$00 -@L4: ldx #csize-1 -@L5: sta cstart,x ; Clear error/mode/curx/cury/... + ldx #csize-1 +@L4: sta cstart,x ; Clear error/mode/curx/cury/... dex - bpl @L5 + bpl @L4 rts @@ -206,9 +197,6 @@ _tgi_uninstall: jsr tgi_uninstall ; Allow the driver to clean up - lda #$60 ; RTS opcode - sta tgi_irq ; Disable IRQ entry point - ; Clear driver pointer and error code tgi_clear_ptr: From ae4e9fab8c1156a15b6db2250ad23356f1909611 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Fri, 2 Feb 2018 18:28:52 +0100 Subject: [PATCH 0575/2161] Atari: CONSOL port of GTIA is readable and writable. Adjust include/_gtia.h accordingly. --- include/_gtia.h | 108 ++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 53 deletions(-) diff --git a/include/_gtia.h b/include/_gtia.h index 424628f19..0542efa2f 100644 --- a/include/_gtia.h +++ b/include/_gtia.h @@ -34,63 +34,65 @@ /* Define a structure with the gtia register offsets */ struct __gtia_write { - unsigned char hposp0; /* horizontal position player 0 */ - unsigned char hposp1; /* horizontal position player 1 */ - unsigned char hposp2; /* horizontal position player 2 */ - unsigned char hposp3; /* horizontal position player 3 */ - unsigned char hposm0; /* horizontal position missile 0 */ - unsigned char hposm1; /* horizontal position missile 1 */ - unsigned char hposm2; /* horizontal position missile 2 */ - unsigned char hposm3; /* horizontal position missile 3 */ - unsigned char sizep0; /* size of player 0 */ - unsigned char sizep1; /* size of player 1 */ - unsigned char sizep2; /* size of player 2 */ - unsigned char sizep3; /* size of player 3 */ - unsigned char sizem; /* size of missiles */ - unsigned char grafp0; /* graphics shape player 0 */ - unsigned char grafp1; /* graphics shape player 1 */ - unsigned char grafp2; /* graphics shape player 2 */ - unsigned char grafp3; /* graphics shape player 3 */ - unsigned char grafm; /* graphics shape missiles */ - unsigned char colpm0; /* color player and missile 0 */ - unsigned char colpm1; /* color player and missile 1 */ - unsigned char colpm2; /* color player and missile 2 */ - unsigned char colpm3; /* color player and missile 3 */ - unsigned char colpf0; /* color playfield 0 */ - unsigned char colpf1; /* color playfield 1 */ - unsigned char colpf2; /* color playfield 2 */ - unsigned char colpf3; /* color playfield 3 */ - unsigned char colbk; /* color background */ - unsigned char prior; /* priority selection */ - unsigned char vdelay; /* vertical delay */ - unsigned char gractl; /* stick/paddle latch, p/m control */ - unsigned char hitclr; /* clear p/m collision */ - unsigned char consol; /* console buttons */ + unsigned char hposp0; /* 0x00: horizontal position player 0 */ + unsigned char hposp1; /* 0x01: horizontal position player 1 */ + unsigned char hposp2; /* 0x02: horizontal position player 2 */ + unsigned char hposp3; /* 0x03: horizontal position player 3 */ + unsigned char hposm0; /* 0x04: horizontal position missile 0 */ + unsigned char hposm1; /* 0x05: horizontal position missile 1 */ + unsigned char hposm2; /* 0x06: horizontal position missile 2 */ + unsigned char hposm3; /* 0x07: horizontal position missile 3 */ + unsigned char sizep0; /* 0x08: size of player 0 */ + unsigned char sizep1; /* 0x09: size of player 1 */ + unsigned char sizep2; /* 0x0A: size of player 2 */ + unsigned char sizep3; /* 0x0B: size of player 3 */ + unsigned char sizem; /* 0x0C: size of missiles */ + unsigned char grafp0; /* 0x0D: graphics shape player 0 */ + unsigned char grafp1; /* 0x0E: graphics shape player 1 */ + unsigned char grafp2; /* 0x0F: graphics shape player 2 */ + unsigned char grafp3; /* 0x10: graphics shape player 3 */ + unsigned char grafm; /* 0x11: graphics shape missiles */ + unsigned char colpm0; /* 0x12: color player and missile 0 */ + unsigned char colpm1; /* 0x13: color player and missile 1 */ + unsigned char colpm2; /* 0x14: color player and missile 2 */ + unsigned char colpm3; /* 0x15: color player and missile 3 */ + unsigned char colpf0; /* 0x16: color playfield 0 */ + unsigned char colpf1; /* 0x17: color playfield 1 */ + unsigned char colpf2; /* 0x18: color playfield 2 */ + unsigned char colpf3; /* 0x19: color playfield 3 */ + unsigned char colbk; /* 0x1A: color background */ + unsigned char prior; /* 0x1B: priority selection */ + unsigned char vdelay; /* 0x1C: vertical delay */ + unsigned char gractl; /* 0x1D: stick/paddle latch, p/m control */ + unsigned char hitclr; /* 0x1E: clear p/m collision */ + unsigned char consol; /* 0x1F: builtin speaker */ }; /* Define a structure with the gtia register offsets */ struct __gtia_read { - unsigned char m0pf; /* missile 0 to playfield collision */ - unsigned char m1pf; /* missile 1 to playfield collision */ - unsigned char m2pf; /* missile 2 to playfield collision */ - unsigned char m3pf; /* missile 3 to playfield collision */ - unsigned char p0pf; /* player 0 to playfield collision */ - unsigned char p1pf; /* player 1 to playfield collision */ - unsigned char p2pf; /* player 2 to playfield collision */ - unsigned char p3pf; /* player 3 to playfield collision */ - unsigned char m0pl; /* missile 0 to player collision */ - unsigned char m1pl; /* missile 1 to player collision */ - unsigned char m2pl; /* missile 2 to player collision */ - unsigned char m3pl; /* missile 3 to player collision */ - unsigned char p0pl; /* player 0 to player collision */ - unsigned char p1pl; /* player 1 to player collision */ - unsigned char p2pl; /* player 2 to player collision */ - unsigned char p3pl; /* player 3 to player collision */ - unsigned char trig0; /* joystick trigger 0 */ - unsigned char trig1; /* joystick trigger 1 */ - unsigned char trig2; /* joystick trigger 2 */ - unsigned char trig3; /* joystick trigger 3 */ - unsigned char pal; /* pal/ntsc flag */ + unsigned char m0pf; /* 0x00: missile 0 to playfield collision */ + unsigned char m1pf; /* 0x01: missile 1 to playfield collision */ + unsigned char m2pf; /* 0x02: missile 2 to playfield collision */ + unsigned char m3pf; /* 0x03: missile 3 to playfield collision */ + unsigned char p0pf; /* 0x04: player 0 to playfield collision */ + unsigned char p1pf; /* 0x05: player 1 to playfield collision */ + unsigned char p2pf; /* 0x06: player 2 to playfield collision */ + unsigned char p3pf; /* 0x07: player 3 to playfield collision */ + unsigned char m0pl; /* 0x08: missile 0 to player collision */ + unsigned char m1pl; /* 0x09: missile 1 to player collision */ + unsigned char m2pl; /* 0x0A: missile 2 to player collision */ + unsigned char m3pl; /* 0x0B: missile 3 to player collision */ + unsigned char p0pl; /* 0x0C: player 0 to player collision */ + unsigned char p1pl; /* 0x0D: player 1 to player collision */ + unsigned char p2pl; /* 0x0E: player 2 to player collision */ + unsigned char p3pl; /* 0x0F: player 3 to player collision */ + unsigned char trig0; /* 0x10: joystick trigger 0 */ + unsigned char trig1; /* 0x11: joystick trigger 1 */ + unsigned char trig2; /* 0x12: joystick trigger 2 */ + unsigned char trig3; /* 0x13: joystick trigger 3 */ + unsigned char pal; /* 0x14: pal/ntsc flag */ + unsigned char unused[10]; + unsigned char consol; /* 0x1F: console buttons */ }; /* End of _gtia.h */ From e9cbd42b18510e0de5c7f6c563a6eed643db33ff Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 6 Feb 2018 08:52:36 -0500 Subject: [PATCH 0576/2161] Normalized the definitions of structs in <supervision.h>. The change matches the way that I/O register structures are defined in other headers. The names are defined as "struct", instead of as "pointer to struct". --- include/supervision.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/supervision.h b/include/supervision.h index f3ae1c25e..cce037910 100644 --- a/include/supervision.h +++ b/include/supervision.h @@ -54,28 +54,28 @@ struct __sv_lcd { unsigned char xpos; unsigned char ypos; }; -#define SV_LCD ((struct __sv_lcd*)0x2000) +#define SV_LCD (*(struct __sv_lcd*)0x2000) struct __sv_tone { unsigned delay; unsigned char control; unsigned char timer; }; -#define SV_RIGHT ((struct __sv_tone*)0x2010) -#define SV_LEFT ((struct __sv_tone*)0x2014) +#define SV_RIGHT (*(struct __sv_tone*)0x2010) +#define SV_LEFT (*(struct __sv_tone*)0x2014) struct __sv_noise { unsigned char volume; /* and frequency */ unsigned char timer; unsigned char control; }; -#define SV_NOISE ((struct __sv_noise*)0x2028) +#define SV_NOISE (*(struct __sv_noise*)0x2028) struct __io_port { unsigned char in; unsigned char out; }; -#define IO_PORT ((struct __io_port*)(0x2021) +#define IO_PORT (*(struct __io_port*)0x2021) struct __sv_dma { unsigned start; @@ -83,7 +83,7 @@ struct __sv_dma { unsigned char control; unsigned char on; }; -#define SV_DMA ((struct __sv_dma*)0x2018) +#define SV_DMA (*(struct __sv_dma*)0x2018) #define SV_CONTROL (*(unsigned char*)0x2020) From a227089ba1b71edf2fc46080faea3fc8fa0e3a2d Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 7 Feb 2018 00:11:55 +0100 Subject: [PATCH 0577/2161] Added missing documentation of header --- doc/funcref.sgml | 185 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 177 insertions(+), 8 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 15830b2a2..7a7bdb1ee 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -4,7 +4,7 @@ <title>cc65 function reference <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2017-12-09 +<date>2018-02-06 <abstract> cc65 is a C compiler for 6502 based systems. This function reference describes @@ -293,6 +293,16 @@ function. (incomplete) +<sect1><tt/device.h/<label id="device.h"><p> + +<itemize> +<item><ref id="getcurrentdevice" name="getcurrentdevice"> +<item><ref id="getdevicedir" name="getdevicedir"> +<item><ref id="getfirstdevice" name="getfirstdevice"> +<item><ref id="getnextdevice" name="getnextdevice"> +</itemize> + + <sect1><tt/dio.h/<label id="dio.h"><p> <url url="dio.html" name="Low-level disk I/O API">. @@ -313,8 +323,6 @@ function. <item><ref id="telldir" name="telldir"> </itemize> -(incomplete) - <sect1><tt/em.h/<label id="em.h"><p> @@ -661,9 +669,11 @@ communication. <item><ref id="strlen" name="strlen"> <item><ref id="strlower" name="strlower"> <item><ref id="strlwr" name="strlwr"> +<item><ref id="strncasecmp" name="strncasecmp"> <item><ref id="strncat" name="strncat"> <item><ref id="strncmp" name="strncmp"> <item><ref id="strncpy" name="strncpy"> +<item><ref id="strnicmp" name="strnicmp"> <item><ref id="strqtok" name="strqtok"> <item><ref id="strrchr" name="strrchr"> <item><ref id="strspn" name="strspn"> @@ -674,8 +684,6 @@ communication. <item><ref id="strupr" name="strupr"> </itemize> -(incomplete) - <sect1><tt/telestrat.h/<label id="telestrat.h"><p> @@ -2930,9 +2938,9 @@ exits. <tag/Availability/cc65 <tag/Example/<verb> /* Hello World */ -#include <stdio.h> -#include <unistd.h> -#include <cc65.h> +#include <stdio.h> +#include <unistd.h> +#include <cc65.h> int main(void) { printf("Hello World\n"); @@ -3450,6 +3458,111 @@ returns one of the constants<itemize> </quote> +<sect1>getcurrentdevice<label id="getcurrentdevice"><p> + +<quote> +<descrip> +<tag/Function/Get current device. +<tag/Header/<tt/<ref id="device.h" name="device.h">/ +<tag/Declaration/<tt/unsigned char getcurrentdevice (void);/ +<tag/Description/The function returns the current device. +<tag/Notes/<itemize> +<item> +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="getdevicedir" name="getdevicedir">, +<ref id="getfirstdevice" name="getfirstdevice">, +<ref id="getnextdevice" name="getnextdevice"> +<tag/Example/<verb> +puts (getdevicedir (getcurrentdevice (), buf, sizeof buf)); +</verb> +</descrip> +</quote> + + +<sect1>getdevicedir<label id="getdevicedir"><p> + +<quote> +<descrip> +<tag/Function/Get device directory. +<tag/Header/<tt/<ref id="device.h" name="device.h">/ +<tag/Declaration/<tt/char* __fastcall__ getdevicedir (unsigned char device, char* buf, size_t size);/ +<tag/Description/The function returns the current directory of <tt/device/. +<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/ +<ref id="getcwd" name="getcwd">, +<ref id="getcurrentdevice" name="getcurrentdevice">, +<ref id="getfirstdevice" name="getfirstdevice">, +<ref id="getnextdevice" name="getnextdevice"> +<tag/Example/<verb> +puts (getdevicedir (getcurrentdevice (), buf, sizeof buf)); +</verb> +</descrip> +</quote> + + +<sect1>getfirstdevice<label id="getfirstdevice"><p> + +<quote> +<descrip> +<tag/Function/Get first device. +<tag/Header/<tt/<ref id="device.h" name="device.h">/ +<tag/Declaration/<tt/unsigned char getfirstdevice (void);/ +<tag/Description/The function returns the first device. +The value 255 indicates no device. +<tag/Notes/<itemize> +<item> +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="getcurrentdevice" name="getcurrentdevice">, +<ref id="getdevicedir" name="getdevicedir">, +<ref id="getnextdevice" name="getnextdevice"> +<tag/Example/<verb> +unsigned char dev = getfirstdevice (); +while (dev != 255) { + printf ("%d\n", dev); + dev = getnextdevice (dev); + } +</verb> +</descrip> +</quote> + + +<sect1>getnextdevice<label id="getnextdevice"><p> + +<quote> +<descrip> +<tag/Function/Get next device. +<tag/Header/<tt/<ref id="device.h" name="device.h">/ +<tag/Declaration/<tt/unsigned char __fastcall__ getnextdevice (unsigned char device);/ +<tag/Description/The function returns the next device after <tt/device/. +The value 255 indicates no further device. +<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/ +<ref id="getcurrentdevice" name="getcurrentdevice">, +<ref id="getdevicedir" name="getdevicedir">, +<ref id="getfirstdevice" name="getfirstdevice"> +<tag/Example/<verb> +unsigned char dev = getfirstdevice (); +while (dev != 255) { + printf ("%d\n", dev); + dev = getnextdevice (dev); + } +</verb> +</descrip> +</quote> + + <sect1>getenv<label id="getenv"><p> <quote> @@ -6284,6 +6397,34 @@ See <tt/strlower/. </quote> +<sect1>strncasecmp<label id="strncasecmp"><p> + +<quote> +<descrip> +<tag/Function/Compare two strings case insensitive. +<tag/Header/<tt/<ref id="string.h" name="string.h">/ +<tag/Declaration/<tt/int __fastcall__ strncasecmp (const char* s1, const char* s2, size_t count);/ +<tag/Description/The <tt/strncasecmp/ function compares the two strings passed +as parameters without case sensitivity. It returns a value that is less than +zero if <tt/s1/ is less than <tt/s2/, zero if <tt/s1/ is the same as <tt/s2/, +and a value greater than zero if <tt/s1/ is greater than <tt/s2/. +<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 function is not available in strict ANSI mode. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="strcmp" name="strcmp">, +<ref id="strcoll" name="strcoll">, +<ref id="stricmp" name="stricmp">, +<ref id="strncmp" name="strncmp">, +<ref id="strxfrm" name="strxfrm"> +<tag/Example/None. +</descrip> +</quote> + + <sect1>strncat<label id="strncat"><p> <quote> @@ -6377,6 +6518,34 @@ strncpy (hello, "Hello world!\n", sizeof hello - 1)[5] = '\0'; </quote> +<sect1>strnicmp<label id="strnicmp"><p> + +<quote> +<descrip> +<tag/Function/Compare two strings case insensitive. +<tag/Header/<tt/<ref id="string.h" name="string.h">/ +<tag/Declaration/<tt/int __fastcall__ strnicmp (const char* s1, const char* s2, size_t count);/ +<tag/Description/The <tt/strnicmp/ function compares the two strings passed as +parameters without case sensitivity. It returns a value that is less than zero +if <tt/s1/ is less than <tt/s2/, zero if <tt/s1/ is the same as <tt/s2/, and a +value greater than zero if <tt/s1/ is greater than <tt/s2/. +<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 function is not available in strict ANSI mode. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="strcasecmp" name="strcasecmp">, +<ref id="strcmp" name="strcmp">, +<ref id="strcoll" name="strcoll">, +<ref id="strncmp" name="strncmp">, +<ref id="strxfrm" name="strxfrm"> +<tag/Example/None. +</descrip> +</quote> + + <sect1>strqtok<label id="strqtok"><p> <quote> From a48f998162aa6d2c3134821de00c2c1c72dc5e11 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 7 Feb 2018 01:55:56 +0100 Subject: [PATCH 0578/2161] Added missing function --- doc/funcref.sgml | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 7a7bdb1ee..a442f5e08 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -4,7 +4,7 @@ <title>cc65 function reference <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2018-02-06 +<date>2018-02-07 <abstract> cc65 is a C compiler for 6502 based systems. This function reference describes @@ -726,7 +726,7 @@ communication. <itemize> <!-- <item><ref id="chdir" name="chdir"> --> <item><ref id="exec" name="exec"> -<!-- <item><ref id="getcwd" name="getcwd"> --> +<item><ref id="getcwd" name="getcwd"> <item><ref id="getopt" name="getopt"> <!-- <item><ref id="lseek" name="lseek"> --> <!-- <item><ref id="mkdir" name="mkdir"> --> @@ -3481,6 +3481,24 @@ puts (getdevicedir (getcurrentdevice (), buf, sizeof buf)); </quote> +<sect1>getcwd<label id="getcwd"><p> + +<quote> +<descrip> +<tag/Function/Get current working directory. +<tag/Header/<tt/<ref id="unistd.h" name="unistd.h">/ +<tag/Declaration/<tt/char* __fastcall__ getcwd (char* buf, size_t size);/ +<tag/Description/The function will return the current working directory. +<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/Example/None. +</descrip> +</quote> + + <sect1>getdevicedir<label id="getdevicedir"><p> <quote> From b69ee802fde17ea8126144dbab9f5cc51dca42a4 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 7 Feb 2018 03:07:30 +0100 Subject: [PATCH 0579/2161] Sorted --- doc/funcref.sgml | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index a442f5e08..83fc36a6b 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -3524,6 +3524,29 @@ puts (getdevicedir (getcurrentdevice (), buf, sizeof buf)); </quote> +<sect1>getenv<label id="getenv"><p> + +<quote> +<descrip> +<tag/Function/Return a value from the environment. +<tag/Header/<tt/<ref id="stdlib.h" name="stdlib.h">/ +<tag/Declaration/<tt/char* __fastcall__ getenv (const char* name);/ +<tag/Description/The function searches the environment for an entry that +matches <tt/name/ and returns its value. The environment consists of a list +of strings in the form <tt/name=value/. If there is no match, <tt/getenv/ +returns <tt/NULL/. +<tag/Notes/<itemize> +<item>What exactly is stored in the environment depends on the machine the +program is running on. +<item>The function is only available as fastcall function, so it may only +be used in presence of a prototype. +</itemize> +<tag/Availability/ISO 9899 +<tag/Example/None. +</descrip> +</quote> + + <sect1>getfirstdevice<label id="getfirstdevice"><p> <quote> @@ -3581,29 +3604,6 @@ while (dev != 255) { </quote> -<sect1>getenv<label id="getenv"><p> - -<quote> -<descrip> -<tag/Function/Return a value from the environment. -<tag/Header/<tt/<ref id="stdlib.h" name="stdlib.h">/ -<tag/Declaration/<tt/char* __fastcall__ getenv (const char* name);/ -<tag/Description/The function searches the environment for an entry that -matches <tt/name/ and returns its value. The environment consists of a list -of strings in the form <tt/name=value/. If there is no match, <tt/getenv/ -returns <tt/NULL/. -<tag/Notes/<itemize> -<item>What exactly is stored in the environment depends on the machine the -program is running on. -<item>The function is only available as fastcall function, so it may only -be used in presence of a prototype. -</itemize> -<tag/Availability/ISO 9899 -<tag/Example/None. -</descrip> -</quote> - - <sect1>getopt<label id="getopt"><p> <quote> From 4d7098f2f223934ab50787c2e7923e16d160c4b8 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 7 Feb 2018 16:23:49 +0100 Subject: [PATCH 0580/2161] Requested changes --- doc/funcref.sgml | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 83fc36a6b..c083f467e 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -3466,6 +3466,9 @@ returns one of the constants<itemize> <tag/Header/<tt/<ref id="device.h" name="device.h">/ <tag/Declaration/<tt/unsigned char getcurrentdevice (void);/ <tag/Description/The function returns the current device. +It allows to access the current device with the <ref id="dio.h" +name="Low-level disk I/O API"> or <ref id="cbm.h" name="cbm_* I/O +functions"> requiring a 'device' parameter. <tag/Notes/<itemize> <item> </itemize> @@ -3475,7 +3478,7 @@ returns one of the constants<itemize> <ref id="getfirstdevice" name="getfirstdevice">, <ref id="getnextdevice" name="getnextdevice"> <tag/Example/<verb> -puts (getdevicedir (getcurrentdevice (), buf, sizeof buf)); +dio_open (getcurrentdevice ()); </verb> </descrip> </quote> @@ -3506,7 +3509,9 @@ be used in presence of a prototype. <tag/Function/Get device directory. <tag/Header/<tt/<ref id="device.h" name="device.h">/ <tag/Declaration/<tt/char* __fastcall__ getdevicedir (unsigned char device, char* buf, size_t size);/ -<tag/Description/The function returns the current directory of <tt/device/. +<tag/Description/The function returns the directory representing <tt/device/. +It allows to access the device on filesystem level by calling chdir() with +the directory returned. <tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. @@ -3518,7 +3523,7 @@ be used in presence of a prototype. <ref id="getfirstdevice" name="getfirstdevice">, <ref id="getnextdevice" name="getnextdevice"> <tag/Example/<verb> -puts (getdevicedir (getcurrentdevice (), buf, sizeof buf)); +chdir (getdevicedir (device, buf, sizeof buf)); </verb> </descrip> </quote> @@ -3555,7 +3560,7 @@ be used in presence of a prototype. <tag/Header/<tt/<ref id="device.h" name="device.h">/ <tag/Declaration/<tt/unsigned char getfirstdevice (void);/ <tag/Description/The function returns the first device. -The value 255 indicates no device. +The constant <tt/INVALID_DEVICE/ indicates no device. <tag/Notes/<itemize> <item> </itemize> @@ -3566,7 +3571,7 @@ The value 255 indicates no device. <ref id="getnextdevice" name="getnextdevice"> <tag/Example/<verb> unsigned char dev = getfirstdevice (); -while (dev != 255) { +while (dev != INVALID_DEVICE) { printf ("%d\n", dev); dev = getnextdevice (dev); } @@ -3583,7 +3588,7 @@ while (dev != 255) { <tag/Header/<tt/<ref id="device.h" name="device.h">/ <tag/Declaration/<tt/unsigned char __fastcall__ getnextdevice (unsigned char device);/ <tag/Description/The function returns the next device after <tt/device/. -The value 255 indicates no further device. +The constant <tt/INVALID_DEVICE/ indicates no further device. <tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. @@ -3595,7 +3600,7 @@ be used in presence of a prototype. <ref id="getfirstdevice" name="getfirstdevice"> <tag/Example/<verb> unsigned char dev = getfirstdevice (); -while (dev != 255) { +while (dev != INVALID_DEVICE) { printf ("%d\n", dev); dev = getnextdevice (dev); } From 54f8dea29b8ef5398749845037c73ecb88905f11 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 7 Feb 2018 17:23:23 +0100 Subject: [PATCH 0581/2161] Added note --- doc/funcref.sgml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index c083f467e..90185a261 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -3513,6 +3513,8 @@ be used in presence of a prototype. It allows to access the device on filesystem level by calling chdir() with the directory returned. <tag/Notes/<itemize> +<item>Calling getdevicedir() <em/does/ check for a (formatted) disk in a +floppy-disk-type device and returns NULL if that check fails. <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -3525,6 +3527,7 @@ be used in presence of a prototype. <tag/Example/<verb> chdir (getdevicedir (device, buf, sizeof buf)); </verb> +cf. <tt/samples/enumdevdir.c/ </descrip> </quote> From 46bdc016dbff1b4e8a10375f41a8f572b7b2934c Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 7 Feb 2018 18:08:40 +0100 Subject: [PATCH 0582/2161] Removed empty notes --- doc/funcref.sgml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 90185a261..c3d8f9869 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -3469,9 +3469,6 @@ returns one of the constants<itemize> It allows to access the current device with the <ref id="dio.h" name="Low-level disk I/O API"> or <ref id="cbm.h" name="cbm_* I/O functions"> requiring a 'device' parameter. -<tag/Notes/<itemize> -<item> -</itemize> <tag/Availability/cc65 <tag/See also/ <ref id="getdevicedir" name="getdevicedir">, @@ -3564,9 +3561,6 @@ be used in presence of a prototype. <tag/Declaration/<tt/unsigned char getfirstdevice (void);/ <tag/Description/The function returns the first device. The constant <tt/INVALID_DEVICE/ indicates no device. -<tag/Notes/<itemize> -<item> -</itemize> <tag/Availability/cc65 <tag/See also/ <ref id="getcurrentdevice" name="getcurrentdevice">, From 89799cd02eb950e89e757b2db66b972b5be4a003 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 10 Feb 2018 00:08:28 +0100 Subject: [PATCH 0583/2161] More notes --- doc/funcref.sgml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index c3d8f9869..bbab694fa 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -3561,6 +3561,10 @@ be used in presence of a prototype. <tag/Declaration/<tt/unsigned char getfirstdevice (void);/ <tag/Description/The function returns the first device. The constant <tt/INVALID_DEVICE/ indicates no device. +<tag/Notes/<itemize> +<item>Calling getfirstdevice() does <em/not/ turn on the motor of a +drive-type device and does <em/not/ check for a disk in the drive. +</itemize> <tag/Availability/cc65 <tag/See also/ <ref id="getcurrentdevice" name="getcurrentdevice">, @@ -3587,6 +3591,8 @@ while (dev != INVALID_DEVICE) { <tag/Description/The function returns the next device after <tt/device/. The constant <tt/INVALID_DEVICE/ indicates no further device. <tag/Notes/<itemize> +<item>Calling getnextdevice() does <em/not/ turn on the motor of a +drive-type device and does <em/not/ check for a disk in the drive. <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> From b65981fc3a0d4a7903c9b2800b03959c9f368b89 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 10 Feb 2018 11:29:50 +0100 Subject: [PATCH 0584/2161] Reduced default stack size to a reasonable value. The unexpanded Creativision has only $206 bytes of RAM available to cc65 programs. So it's a bad idea(tm) to reserve $180 bytes for the software stack. $40 bytes seems a much better default (aka guess). --- cfg/creativision.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/creativision.cfg b/cfg/creativision.cfg index 289984df0..2eb9ac427 100644 --- a/cfg/creativision.cfg +++ b/cfg/creativision.cfg @@ -1,5 +1,5 @@ SYMBOLS { - __STACKSIZE__: type = weak, value = $0180; + __STACKSIZE__: type = weak, value = $0040; } MEMORY { ZP: file = "", define = yes, start = $0020, size = $00E0; From 6f6fd33caef12e2ecd14d5e15fb200f6cda47529 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 10 Feb 2018 11:45:50 +0100 Subject: [PATCH 0585/2161] Added size_t. --- include/device.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/device.h b/include/device.h index 68b1c807a..b0a5f5e76 100644 --- a/include/device.h +++ b/include/device.h @@ -35,6 +35,13 @@ +#ifndef _HAVE_size_t +typedef unsigned size_t; +#define _HAVE_size_t +#endif + + + /*****************************************************************************/ /* Data */ /*****************************************************************************/ From 33f05d1162d987b653ce03f0edf427c779ef1a53 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 10 Feb 2018 16:14:53 -0500 Subject: [PATCH 0586/2161] Added a definition for the CBM610's first CIA chip. --- include/cbm610.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/cbm610.h b/include/cbm610.h index b0486044b..de7aa50f8 100644 --- a/include/cbm610.h +++ b/include/cbm610.h @@ -85,7 +85,8 @@ #define SID (*(struct __sid*)0xDA00) #include <_6526.h> -#define CIA (*(struct __6526*)0xDC00) +#define CIA1 (*(struct __6526*)0xDB00) +#define CIA2 (*(struct __6526*)0xDC00) #include <_6551.h> #define ACIA (*(struct __6551*)0xDD00) From d93f84f4bc079e9ea20542a492101bf4dc3730ec Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Tue, 13 Feb 2018 19:19:40 -0800 Subject: [PATCH 0587/2161] Improved GeOS version detection. --- include/geos/gsys.h | 2 + libsrc/geos-cbm/geossym2.inc | 2 + libsrc/geos-cbm/system/get_ostype.s | 18 ++++++++- samples/geos/geosver.c | 58 +++++++++++++++++++++++++++++ samples/geos/geosverres.grc | 8 ++++ 5 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 samples/geos/geosver.c create mode 100644 samples/geos/geosverres.grc diff --git a/include/geos/gsys.h b/include/geos/gsys.h index 284c38b63..b60c9884b 100644 --- a/include/geos/gsys.h +++ b/include/geos/gsys.h @@ -31,6 +31,8 @@ char get_ostype(void); #define GEOS4 0x04 /* plus4 geos is not or'ed with version */ #define GEOS128 0x80 /* version flags */ +#define MEGAPATCH3 0x03 +#define GATEWAY 0x08 #define GEOS_V10 0x10 #define GEOS_V11 0x11 #define GEOS_V12 0x12 /* ??? not sure */ diff --git a/libsrc/geos-cbm/geossym2.inc b/libsrc/geos-cbm/geossym2.inc index cdcbc24dc..c756280a9 100644 --- a/libsrc/geos-cbm/geossym2.inc +++ b/libsrc/geos-cbm/geossym2.inc @@ -4,8 +4,10 @@ ;4-2-99 bootName = $c006 +gatewayFlag = $c007 version = $c00f nationality = $c010 sysFlgCopy = $c012 c128Flag = $c013 +mp3Flag = $c014 dateCopy = $c018 \ No newline at end of file diff --git a/libsrc/geos-cbm/system/get_ostype.s b/libsrc/geos-cbm/system/get_ostype.s index 492ce132d..827630f0b 100644 --- a/libsrc/geos-cbm/system/get_ostype.s +++ b/libsrc/geos-cbm/system/get_ostype.s @@ -3,8 +3,8 @@ ; ; 10.09.2001 ; -; Plus4 and GEOS 1.1 detection by -; Marco van den Heuvel, 2010-02-02 +; Plus4, Gateway, MP3 and GEOS 1.1 detection by +; Marco van den Heuvel, 2018-02-07 ; ; unsigned char get_ostype (void); @@ -26,6 +26,12 @@ _get_ostype: and #%11110000 cmp #$10 beq geos10 + lda gatewayFlag + cmp #$41 + beq gateway + lda mp3Flag + cmp #$4d + beq megapatch3 lda c128Flag ; we're on at least 2.0 cmp #$18 beq geos_on_plus4 @@ -40,6 +46,14 @@ geos11: geos_on_plus4: lda #$04 rts +gateway: + lda #$08 + ora c128Flag + rts +megapatch3: + lda #$03 + ora c128Flag + rts _get_tv: jsr _get_ostype diff --git a/samples/geos/geosver.c b/samples/geos/geosver.c new file mode 100644 index 000000000..673b7e1f7 --- /dev/null +++ b/samples/geos/geosver.c @@ -0,0 +1,58 @@ +#include <geos.h> +#include <conio.h> + +// Let's define the window we're operating +struct window wholeScreen = {0, SC_PIX_HEIGHT-1, 0, SC_PIX_WIDTH-1}; + + +void main (void) +{ + unsigned char os = get_ostype(); + unsigned char *machine = NULL; + unsigned char *version = NULL; + unsigned char good = 1; + + SetPattern(0); + InitDrawWindow(&wholeScreen); + Rectangle(); + gotoxy(0, 4); + if (os == GEOS4) { + machine = "plus4"; + version = "GeOS v3.5"; + } else { + if ((os & GEOS128) == GEOS128) { + machine = "c128"; + } else { + machine = "c64"; + } + os &= 0x7f; + if (os == GEOS_V10) { + version = "GeOS v1.0"; + } else if (os == GEOS_V11) { + version = "GeOS v1.1"; + } else if (os == GEOS_V12) { + version = "GeOS v1.2"; + } else if (os == GEOS_V20) { + version = "GeOS v2.0"; + } else if (os == MEGAPATCH3) { + version = "MegaPatch 3"; + } else if (os == GATEWAY) { + version = "GateWay"; + } else if ((os & WHEELS) == WHEELS) { + version = "Wheels"; + } else { + version = "Unknown GeOS version"; + good = 0; + } + } + + if (good) { + cprintf("%s (%s)", version, machine); + } else { + cprintf("%s (%s) (%d)", version, machine, os); + } + + Sleep(10*50); + + return; +} diff --git a/samples/geos/geosverres.grc b/samples/geos/geosverres.grc new file mode 100644 index 000000000..cac9ed698 --- /dev/null +++ b/samples/geos/geosverres.grc @@ -0,0 +1,8 @@ + +; this is the resource file for geosver.c, a GEOS application example + +HEADER APPLICATION "geosver" "GeOSver" "V1.0" { +dostype USR +author "Marco van den Heuvel" +info "This is a C prog compiled with cc65 and GEOSLib." +} From e17b9177dea44ed453a1ad77e0c9a2ea9569938d Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Wed, 14 Feb 2018 10:22:10 -0800 Subject: [PATCH 0588/2161] Fixed GeOS -> GEOS and added newline to geossym2.inc. --- libsrc/geos-cbm/geossym2.inc | 3 ++- samples/geos/geosver.c | 12 ++++++------ samples/geos/geosverres.grc | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/libsrc/geos-cbm/geossym2.inc b/libsrc/geos-cbm/geossym2.inc index c756280a9..02a2fd44b 100644 --- a/libsrc/geos-cbm/geossym2.inc +++ b/libsrc/geos-cbm/geossym2.inc @@ -10,4 +10,5 @@ nationality = $c010 sysFlgCopy = $c012 c128Flag = $c013 mp3Flag = $c014 -dateCopy = $c018 \ No newline at end of file +dateCopy = $c018 + diff --git a/samples/geos/geosver.c b/samples/geos/geosver.c index 673b7e1f7..77a15ada7 100644 --- a/samples/geos/geosver.c +++ b/samples/geos/geosver.c @@ -18,7 +18,7 @@ void main (void) gotoxy(0, 4); if (os == GEOS4) { machine = "plus4"; - version = "GeOS v3.5"; + version = "GEOS v3.5"; } else { if ((os & GEOS128) == GEOS128) { machine = "c128"; @@ -27,13 +27,13 @@ void main (void) } os &= 0x7f; if (os == GEOS_V10) { - version = "GeOS v1.0"; + version = "GEOS v1.0"; } else if (os == GEOS_V11) { - version = "GeOS v1.1"; + version = "GEOS v1.1"; } else if (os == GEOS_V12) { - version = "GeOS v1.2"; + version = "GEOS v1.2"; } else if (os == GEOS_V20) { - version = "GeOS v2.0"; + version = "GEOS v2.0"; } else if (os == MEGAPATCH3) { version = "MegaPatch 3"; } else if (os == GATEWAY) { @@ -41,7 +41,7 @@ void main (void) } else if ((os & WHEELS) == WHEELS) { version = "Wheels"; } else { - version = "Unknown GeOS version"; + version = "Unknown GEOS version"; good = 0; } } diff --git a/samples/geos/geosverres.grc b/samples/geos/geosverres.grc index cac9ed698..9a3d72a26 100644 --- a/samples/geos/geosverres.grc +++ b/samples/geos/geosverres.grc @@ -1,7 +1,7 @@ ; this is the resource file for geosver.c, a GEOS application example -HEADER APPLICATION "geosver" "GeOSver" "V1.0" { +HEADER APPLICATION "geosver" "GEOSver" "V1.0" { dostype USR author "Marco van den Heuvel" info "This is a C prog compiled with cc65 and GEOSLib." From b0ef67d14cf90c1ec12dea7f79f97884ea708981 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Thu, 15 Feb 2018 15:24:58 -0800 Subject: [PATCH 0589/2161] Added GEOS 1.3 and 1.5 detection. --- include/geos/gsys.h | 4 +++- libsrc/geos-cbm/system/get_ostype.s | 10 ++++++++++ samples/geos/geosver.c | 4 ++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/geos/gsys.h b/include/geos/gsys.h index b60c9884b..1753492e5 100644 --- a/include/geos/gsys.h +++ b/include/geos/gsys.h @@ -35,7 +35,9 @@ char get_ostype(void); #define GATEWAY 0x08 #define GEOS_V10 0x10 #define GEOS_V11 0x11 -#define GEOS_V12 0x12 /* ??? not sure */ +#define GEOS_V12 0x12 +#define GEOS_V13 0x13 +#define GEOS_V15 0x15 #define GEOS_V20 0x20 #define WHEELS 0x40 /* only Wheels? */ diff --git a/libsrc/geos-cbm/system/get_ostype.s b/libsrc/geos-cbm/system/get_ostype.s index 827630f0b..6e6731952 100644 --- a/libsrc/geos-cbm/system/get_ostype.s +++ b/libsrc/geos-cbm/system/get_ostype.s @@ -26,6 +26,8 @@ _get_ostype: and #%11110000 cmp #$10 beq geos10 + cmp #$13 ; either 1.3 or 1.5 + beq geos13check lda gatewayFlag cmp #$41 beq gateway @@ -37,6 +39,7 @@ _get_ostype: beq geos_on_plus4 ora version rts +geos13: geos10: lda version rts @@ -54,6 +57,13 @@ megapatch3: lda #$03 ora c128Flag rts +geos13check: + lda mp3Flag + cmp #$03 + bne geos13 +geos15: + lda #$15 + rts _get_tv: jsr _get_ostype diff --git a/samples/geos/geosver.c b/samples/geos/geosver.c index 77a15ada7..1402d148e 100644 --- a/samples/geos/geosver.c +++ b/samples/geos/geosver.c @@ -32,6 +32,10 @@ void main (void) version = "GEOS v1.1"; } else if (os == GEOS_V12) { version = "GEOS v1.2"; + } else if (os == GEOS_V13) { + version = "GEOS v1.3"; + } else if (os == GEOS_V15) { + version = "GEOS v1.5"; } else if (os == GEOS_V20) { version = "GEOS v2.0"; } else if (os == MEGAPATCH3) { From 83890e56eb61933ee45985de368d5f80d56eab77 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 22 Feb 2018 13:30:50 +0100 Subject: [PATCH 0590/2161] Update dio.sgml --- doc/dio.sgml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/dio.sgml b/doc/dio.sgml index c85992a4a..39aac251c 100644 --- a/doc/dio.sgml +++ b/doc/dio.sgml @@ -25,8 +25,7 @@ released with the <tt>dio_close</tt> function. dhandle_t __fastcall__ dio_open (unsigned char device); </verb></tscreen> -The <tt>device</tt> specifies the device to access, with 0 being the first -device, 1 the second, and so on. +The <tt>device</tt> specifies the device to access. <tscreen><verb> unsigned char __fastcall__ dio_close (dhandle_t handle); From 3a0506ccb3582ea4677c000d9a4a581c46e3914f Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 23 Feb 2018 16:06:49 -0500 Subject: [PATCH 0591/2161] Changed the PC-Engine's configuration file, so that the command line can build 8K, 16K, and 32K carts. Adjusted the PCE's document, the start-up code, and the PCE library test makefile. That makefile shows how to post-process the linker's output file. --- cfg/pce.cfg | 43 +++++++++++-------------- doc/pce.sgml | 61 +++++++++++++++++++++++++---------- libsrc/pce/crt0.s | 68 +++++++++++++++++---------------------- testcode/lib/pce/Makefile | 25 +++++++++++--- testcode/lib/pce/conio.c | 2 +- 5 files changed, 115 insertions(+), 84 deletions(-) diff --git a/cfg/pce.cfg b/cfg/pce.cfg index 6332f8eff..77f8c5c97 100644 --- a/cfg/pce.cfg +++ b/cfg/pce.cfg @@ -1,34 +1,29 @@ -# linker config to produce simple NEC PC-Engine cartridge (.pce) - +# linker config. to produce a NEC PC-Engine 8K, 16K, or 32K image (.bin) SYMBOLS { + __CARTSIZE__: type = weak, value = $2000; # $2000, $4000, or $8000 __STACKSIZE__: type = weak, value = $0300; # 3 pages stack } - MEMORY { - # FIXME: is this correct? the first 3? bytes cant be used? - ZP: file = "", start = $0003, size = $00FD, type = rw, define = yes; - - # reset-bank and hardware vectors - ROM0: file = %O, start = $E000, size = $1FF6, fill = yes, define = yes; - ROMV: file = %O, start = $FFF6, size = $000A, fill = yes; - - # first RAM page (also contains stack and zeropage) - RAM: file = "", start = $2200, size = $1e00, define = yes; + ZP: file = "", start = $0000, size = $0100, define = yes; + # RAM bank + MAIN: file = "", start = $2200, size = $1E00 - __STACKSIZE__, define = yes; + # ROM banks, before swapping, and after mapping + ROM: file = %O, start = $10000 - __CARTSIZE__, size = __CARTSIZE__, fill = yes, fillval = $FF; } - SEGMENTS { - ZEROPAGE: load = ZP, type = zp, define = yes; - EXTZP: load = ZP, type = zp, define = yes, optional = yes; - APPZP: load = ZP, type = zp, define = yes, optional = yes; - STARTUP: load = ROM0, type = ro, define = yes; - ONCE: load = ROM0, type = ro, optional = yes; - CODE: load = ROM0, type = ro, define = yes; - RODATA: load = ROM0, type = ro, define = yes; - DATA: load = ROM0, run = RAM, type = rw, define = yes; - BSS: load = RAM, type = bss, define = yes; - VECTORS: load = ROMV, type = rw, define = yes; + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; + APPZP: load = ZP, type = zp, optional = yes; + DATA: load = ROM, run = MAIN, type = rw, define = yes; + INIT: load = MAIN, type = bss, optional = yes; + BSS: load = MAIN, type = bss, define = yes; + RODATA: load = ROM, type = ro; + CODE: load = ROM, type = ro; + LOWCODE: load = ROM, type = ro, optional = yes; + ONCE: load = ROM, type = ro, optional = yes; + STARTUP: load = ROM, type = ro, start = $FFF6 - $0066; + VECTORS: load = ROM, type = ro, start = $FFF6; } - FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, diff --git a/doc/pce.sgml b/doc/pce.sgml index 927df8f5c..bc7dcf5c8 100644 --- a/doc/pce.sgml +++ b/doc/pce.sgml @@ -3,9 +3,9 @@ <article> <title>PC-Engine (TurboGrafx) System specific information for cc65 -<author> -<url url="mailto:groepaz@gmx.net" name="Groepaz/Hitmen"> -<date>2016-09-29 +<author><url url="mailto:groepaz@gmx.net" name="Groepaz/Hitmen">,<newline> +<url url="mailto:greg.king5@verizon.net" name="Greg King"> +<date>2018-02-12 <abstract> An overview over the PCE runtime system as it is implemented for the @@ -30,11 +30,36 @@ more than one platform. Please see the function reference for more information. + <sect>Binary format<p> -The standard binary output format generated by the linker for the PCE target -is a cartridge image with no header. It is of course possible to change this -behaviour by using a modified startup file and linker config. +The binary output file generated by the linker, for the PCE target, is an +image, with no header, that has 8K bytes in the wrong place. That file must be +post-processed; the 8K at the end must be moved to the front of the image. + +On POSIX systems, the <tt/dd/ command and the shell give a convenient way to do +it. Here is an example of their use: +<tscreen><verb> +dd if=conio.bin bs=8K skip=3 > conio.pce +dd if=conio.bin bs=8K count=3 >> conio.pce +</verb></tscreen> +The first command grabs the last 8K of a 32K file, and writes it as the first +part of a new file. The second command reads all but the last part of the old +file, and appends it to the new file. +<tscreen><verb> ++--------+--------+--------+--------+ +| Bank 1 | Bank 2 | Bank 3 | Bank 0 | <-- "conio.bin" ++--------+--------+--------+--------+ + ++--------+--------+--------+--------+ +| Bank 0 | Bank 1 | Bank 2 | Bank 3 | <-- "conio.pce" ++--------+--------+--------+--------+ +</verb></tscreen> +<em/Note/: That <tt/.pce/ file shows the format of the ROM cartridge that is +plugged into a PC-Engine. But, that <tt/.bin/ file shows what programs +actually see when they execute the code in that cartridge. + + <sect>Memory layout<p> @@ -52,19 +77,23 @@ Special locations: <tag/Stack/ The C runtime stack is located in system RAM at $3FFF and growing downwards. - <tag/BSS and Data/ - - The BSS (uninitialized variables) and Data (initialized variables) sections are - placed one after the other into system RAM at $2000. + <tag/Data and BSS/ + The Data (initialized variables) and BSS (uninitialized variables) sections are + placed one after the other into system RAM at $2200. <tag/Heap/ - The C heap is located after the end of the Data section and grows towards the C + The C heap is located after the end of the BSS section; and, grows towards the C runtime stack. <tag/Code/ - The startup code is located at $E000 in the System/Hardware bank. Further - code can be placed in other ROM banks, this must be done manually however. + In an 8K ROM cartridge, code and read-only data are located between + $E000 and $FFF5 in the System bank. + In a 16K cartridge, code and read-only data are located between $C000 + and $FFF5. + + In a 32K cartridge, code and read-only data are located between $8000 + and $FFF5. </descrip><p> @@ -171,7 +200,8 @@ following functions (and a few others): <sect>Other hints<p> <itemize> -<item>a good emulator to use for PC-Engine is "mednafen" (<url url="http://mednafen.fobby.net/">) +<item><url url="https://mednafen.github.io/" name= "Mednafen"> is a good +emulator to use for the PC-Engine. </itemize> some useful resources on PCE coding: @@ -210,6 +240,3 @@ freely, subject to the following restrictions: </enum> </article> - - - diff --git a/libsrc/pce/crt0.s b/libsrc/pce/crt0.s index 80b32c089..75ffb7f05 100644 --- a/libsrc/pce/crt0.s +++ b/libsrc/pce/crt0.s @@ -4,33 +4,26 @@ ; by Groepaz/Hitmen <groepaz@gmx.net> ; based on code by Ullrich von Bassewitz <uz@cc65.org> ; -; This must be the *first* file on the linker command line +; 2018-02-11, Greg King ; .export _exit .export __STARTUP__ : absolute = 1 ; Mark as startup .import initlib, donelib - .import push0, _main, zerobss - .import initheap + .import push0, _main .import IRQStub - ; Linker generated - .import __RAM_START__, __RAM_SIZE__ - .import __ROM0_START__, __ROM0_SIZE__ - .import __ROM_START__, __ROM_SIZE__ - .import __STARTUP_LOAD__,__STARTUP_RUN__, __STARTUP_SIZE__ - .import __CODE_LOAD__,__CODE_RUN__, __CODE_SIZE__ - .import __RODATA_LOAD__,__RODATA_RUN__, __RODATA_SIZE__ - .import __DATA_LOAD__,__DATA_RUN__, __DATA_SIZE__ - .import __BSS_SIZE__ + ; Linker-generated + .import __CARTSIZE__ + .import __DATA_LOAD__, __DATA_RUN__, __DATA_SIZE__ + .import __BSS_RUN__, __BSS_SIZE__ + .import __MAIN_START__, __MAIN_SIZE__, __STACKSIZE__ .include "pce.inc" .include "extzp.inc" .importzp sp - .importzp ptr1,ptr2 - .importzp tmp1,tmp2,tmp3 ; ------------------------------------------------------------------------ ; Place the startup code in a special segment. @@ -53,29 +46,27 @@ start: ldx #$FF ; Stack top ($21FF) txs - ; At startup all MPRs are set to 0, so init them - lda #$ff - tam #%00000001 ; 0000-1FFF = Hardware page + ; At power-on, most MPRs have random values; so, initiate them. + lda #$FF + tam #%00000001 ; $0000-$1FFF = Hardware bank lda #$F8 - tam #%00000010 ; 2000-3FFF = Work RAM - - ; FIXME: setup a larger block of memory to use with C-code + tam #%00000010 ; $2000-$3FFF = Work RAM ;lda #$F7 - ;tam #%00000100 ; 4000-5FFF = Save RAM - ;lda #1 - ;tam #%00001000 ; 6000-7FFF Page 2 - ;lda #2 - ;tam #%00010000 ; 8000-9FFF Page 3 - ;lda #3 - ;tam #%00100000 ; A000-BFFF Page 4 + ;tam #%00000100 ; $4000-$47FF = 2K Battery-backed RAM ;lda #4 - ;tam #%01000000 ; C000-DFFF Page 5 - ;lda #0 - ;tam #%10000000 ; e000-fFFF hucard/syscard bank 0 + ;tam #%00001000 ; $6000-$7FFF - ; Clear work RAM (2000-3FFF) - stz <$00 - tii $2000, $2001, $1FFF + lda #$01 + ldx #>$8000 + cpx #>__CARTSIZE__ + bcc @L1 ;(blt) + tam #%00010000 ; $8000-$9FFF = ROM bank 1 (32K block of ROM) + inc a + tam #%00100000 ; $A000-$BFFF = ROM bank 2 + inc a +@L1: tam #%01000000 ; $C000-$DFFF = ROM bank 3 (32K) or 1 (16K) + ;lda #$00 ; (The reset default) + ;tam #%10000000 ; $E000-$FFFF hucard/syscard bank 0 ; Initialize hardware stz TIMER_CTRL ; Timer off @@ -91,15 +82,16 @@ start: lda #$05 sta IRQ_MASK ; IRQ1=on - ; Clear the BSS data - jsr zerobss - ; Copy the .data segment to RAM tii __DATA_LOAD__, __DATA_RUN__, __DATA_SIZE__ + ; Clear the .bss segment + stz __BSS_RUN__ + tii __BSS_RUN__, __BSS_RUN__ + 1, __BSS_SIZE__ - 1 + ; Set up the stack - lda #<(__RAM_START__+__RAM_SIZE__) - ldx #>(__RAM_START__+__RAM_SIZE__) + lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) + ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) sta sp stx sp + 1 diff --git a/testcode/lib/pce/Makefile b/testcode/lib/pce/Makefile index 9a4dd7506..a4a495c9a 100644 --- a/testcode/lib/pce/Makefile +++ b/testcode/lib/pce/Makefile @@ -1,12 +1,29 @@ .PHONY: all clean test +# Size of cartridge to generate. +# Possible values: +# 8K = 0x2000 +# 16K = 0x4000 +# 32K = 0x8000 +CARTSIZE := 0x2000 + +ifeq (${CARTSIZE},0x8000) +COUNT := 3 +else +COUNT := 1 +endif + all: conio.pce -conio.pce: conio.c - ../../../bin/cl65 -t pce conio.c --mapfile conio.map -o conio.pce +%.pce: %.bin + dd if=$< bs=8K skip=${COUNT} > $@ + dd if=$< bs=8K count=${COUNT} >> $@ + +%.bin: %.c ../../../lib/pce.lib + ../../../bin/cl65 -t pce $< -Wl -D__CARTSIZE__=${CARTSIZE} -m $*.map -o $@ clean: - $(RM) conio.o conio.pce conio.map + $(RM) conio.o conio.??? test: conio.pce - mednafen -force_module pce conio.pce + mednafen -force_module pce $< diff --git a/testcode/lib/pce/conio.c b/testcode/lib/pce/conio.c index ed3f86240..858f01918 100644 --- a/testcode/lib/pce/conio.c +++ b/testcode/lib/pce/conio.c @@ -45,7 +45,7 @@ void main(void) p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15] ); } - memcpy(p, main, 0); /* test that a zero length doesn't copy 64K */ + memcpy(p, main, i = 0); /* test that a zero length doesn't copy 64K */ gotoxy(0,ysize - 1); for (i = 0; i < xsize; ++i) { From 8476360e9f5f3737eb740e8faffdeece2e4847aa Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 24 Aug 2015 02:53:47 -0400 Subject: [PATCH 0592/2161] Fixed bugs in geos-cbm's dio_open(). * Trying to open an unused drive would leave a byte on the hardware stack. * Too high device numbers weren't caught. --- libsrc/geos-cbm/disk/dio_openclose.s | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libsrc/geos-cbm/disk/dio_openclose.s b/libsrc/geos-cbm/disk/dio_openclose.s index ec5aa8795..72e3e32e9 100644 --- a/libsrc/geos-cbm/disk/dio_openclose.s +++ b/libsrc/geos-cbm/disk/dio_openclose.s @@ -1,8 +1,8 @@ ; -; Maciej 'YTM/Elysium' Witkowiak +; 2001-07-02, Maciej 'YTM/Elysium' Witkowiak +; 2015-08-24, Greg King ; ; based on Atari version by Christian Groessler -; 2.7.2001 ; ; dhandle_t __fastcall__ dio_open (unsigned char device); ; unsigned char __fastcall__ dio_close (dhandle_t handle); @@ -27,11 +27,13 @@ sectsizetab: .code _dio_open: - pha + cmp #4 + bcs _inv_drive tax lda driveType,x ; check if there's a device beq _inv_drive txa + pha clc adc #8 ; normalize devnum sta curDevice From 6fd56bf9b6b594a722bc508b6dfc7c1f21fdc3b4 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 27 Aug 2015 04:02:26 -0400 Subject: [PATCH 0593/2161] Fixed bugs in the geos-cbm DIO sector-number converter functions. * The 16-bit comparison code actually didn't compare the high byte. * This implementation supports only the 1541, 1571, and 1581; but, it didn't exclude the other drive types that GEOS supports. * Two error code numbers were swapped. * A 1571 converter didn't catch sector numbers that are too high. * A 1581 converter didn't catch sector numbers that are too high. --- libsrc/geos-cbm/disk/dio_cts.s | 10 +++++----- libsrc/geos-cbm/disk/dio_stc.s | 23 ++++++++++++----------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/libsrc/geos-cbm/disk/dio_cts.s b/libsrc/geos-cbm/disk/dio_cts.s index 8be343641..043e1f8d8 100644 --- a/libsrc/geos-cbm/disk/dio_cts.s +++ b/libsrc/geos-cbm/disk/dio_cts.s @@ -1,6 +1,6 @@ ; -; Maciej 'YTM/Elysium' Witkowiak -; 2.7.2001 +; 2001-07-02, Maciej 'YTM/Elysium' Witkowiak +; 2015-08-26, Greg King ; ; ; unsigned char __fastcall__ dio_phys_to_log (dhandle_t handle, @@ -59,7 +59,7 @@ _dio_phys_to_log: lda (ptr3),y tay lda driveType,y - and #%00000011 ; this is for RamDrive compatibility + and #%00001111 ; remove ramDisk flags cmp #DRV_1541 beq dio_cts1541 cmp #DRV_1571 @@ -67,7 +67,7 @@ _dio_phys_to_log: cmp #DRV_1581 beq dio_cts1581 - lda #DEV_NOT_FOUND ; unknown device + lda #INCOMPATIBLE ; unsupported device ldx #0 beq ret @@ -91,7 +91,7 @@ _inv_data: lda #INV_TRACK .byte $2c _inv_hand: - lda #INCOMPATIBLE + lda #DEV_NOT_FOUND ldx #0 beq ret diff --git a/libsrc/geos-cbm/disk/dio_stc.s b/libsrc/geos-cbm/disk/dio_stc.s index 586e3f3db..7398edb63 100644 --- a/libsrc/geos-cbm/disk/dio_stc.s +++ b/libsrc/geos-cbm/disk/dio_stc.s @@ -1,6 +1,6 @@ ; -; Maciej 'YTM/Elysium' Witkowiak -; 2.7.2001 +; 2001-07-02, Maciej 'YTM/Elysium' Witkowiak +; 2015-08-27, Greg King ; ; unsigned char __fastcall__ dio_log_to_phys (dhandle_t handle, ; unsigned *sectnum, /* input */ @@ -55,7 +55,7 @@ _dio_log_to_phys: lda (ptr3),y tay lda driveType,y - and #%00000011 ; this is for RamDrive compatibility + and #%00001111 ; remove ramDisk flags cmp #DRV_1541 beq dio_stc1541 cmp #DRV_1571 @@ -63,7 +63,7 @@ _dio_log_to_phys: cmp #DRV_1581 beq dio_stc1581 - lda #DEV_NOT_FOUND ; unknown device + lda #INCOMPATIBLE ; unsupported device ldx #0 beq _ret @@ -86,7 +86,7 @@ _inv_data: lda #INV_TRACK .byte $2c _inv_hand: - lda #INCOMPATIBLE + lda #DEV_NOT_FOUND ldx #0 beq _ret @@ -102,8 +102,8 @@ _loop41: bne _nxt lda tmp1 cmp sectab_1541_l+1,x - bcc _found -_nxt: inx +_nxt: bcc _found + inx cpx #35 bne _loop41 beq _inv_data @@ -124,12 +124,11 @@ dio_stc1571: ; - fall down to 1541 lda tmp2 cmp #>683 - bne _cnt71 + bne _if71 lda tmp1 cmp #<683 - bcc dio_stc1541 +_if71: bcc dio_stc1541 -_cnt71: lda tmp1 sec sbc #<683 @@ -138,6 +137,8 @@ _cnt71: sbc #>683 sta tmp2 jsr dio_stc1541 ; will fall through here + tay + bne _ret ; result beyond track 70 ldy #diopp_track lda (ptr1),y @@ -166,7 +167,7 @@ _sub81: lda tmp1 sbc #0 sta tmp2 inx - cpx #81 + cpx #80 bne _loop81 beq _inv_data From 39b4b6838ff3a72432ae2b0d9af4de360c344672 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 27 Aug 2015 05:10:01 -0400 Subject: [PATCH 0594/2161] Made dio_read(), dio_write(), and dio_write_verify() catch sector number conversion errors. --- libsrc/geos-cbm/disk/dio_read.s | 8 +++++--- libsrc/geos-cbm/disk/dio_write.s | 8 ++++++-- libsrc/geos-cbm/disk/dio_writev.s | 8 +++++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/libsrc/geos-cbm/disk/dio_read.s b/libsrc/geos-cbm/disk/dio_read.s index db46c9b69..ac19f9afa 100644 --- a/libsrc/geos-cbm/disk/dio_read.s +++ b/libsrc/geos-cbm/disk/dio_read.s @@ -1,6 +1,6 @@ ; -; Maciej 'YTM/Elysium' Witkowiak -; 2.7.2001 +; 2001-07-02, Maciej 'YTM/Elysium' Witkowiak +; 2015-08-27, Greg King ; ; this file provides the _dio_read function ; @@ -15,7 +15,9 @@ _dio_read: jsr dio_params + tay + bne err jsr ReadBlock stx __oserror txa - rts +err: rts diff --git a/libsrc/geos-cbm/disk/dio_write.s b/libsrc/geos-cbm/disk/dio_write.s index 14267803a..a5f747519 100644 --- a/libsrc/geos-cbm/disk/dio_write.s +++ b/libsrc/geos-cbm/disk/dio_write.s @@ -1,6 +1,6 @@ ; -; Maciej 'YTM/Elysium' Witkowiak -; 2.7.2001 +; 2001-07-02, Maciej 'YTM/Elysium' Witkowiak +; 2015-08-27, Greg King ; ; this file provides the _dio_write function ; @@ -15,5 +15,9 @@ _dio_write: jsr dio_params + tay + bne err jsr WriteBlock jmp setoserror + +err: rts diff --git a/libsrc/geos-cbm/disk/dio_writev.s b/libsrc/geos-cbm/disk/dio_writev.s index 7cb9b029f..9b36ed096 100644 --- a/libsrc/geos-cbm/disk/dio_writev.s +++ b/libsrc/geos-cbm/disk/dio_writev.s @@ -1,6 +1,6 @@ ; -; Maciej 'YTM/Elysium' Witkowiak -; 2.7.2001 +; 2001-07-02, Maciej 'YTM/Elysium' Witkowiak +; 2015-08-27, Greg King ; ; this file provides the _dio_write function ; @@ -15,7 +15,9 @@ _dio_write_verify: jsr dio_params + tay + bne err jsr VerWriteBlock stx __oserror txa - rts +err: rts From 924364d73d08d1b4b8c5162b8667f682133a6e9a Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sun, 25 Feb 2018 22:38:58 +0000 Subject: [PATCH 0595/2161] Small typo --- doc/atari.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/atari.sgml b/doc/atari.sgml index 6cbff6208..459e8e745 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -394,7 +394,7 @@ under different mappings, defining remapped strings works only flawlessly with static array initialization: <verb> -#include <atari\_screen\_charmap.h> +#include <atari_screen_charmap.h> char pcScreenMappingString[] = "Hello Atari!"; #include <atari_atascii_charmap.h> From 33f602f9ad5582e8df7e1c0bd89433301f35b79f Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 26 Feb 2018 15:07:13 -0500 Subject: [PATCH 0596/2161] Shortenned the CBM close() by a byte and a cycle. --- libsrc/cbm/close.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/cbm/close.s b/libsrc/cbm/close.s index 004b88df9..b43c07b57 100644 --- a/libsrc/cbm/close.s +++ b/libsrc/cbm/close.s @@ -40,7 +40,7 @@ lda #LFN_CLOSED sta fdtab,x - lda tmp2 ; Get the handle + txa ; Get handle clc adc #LFN_OFFS ; Make LFN from handle jsr CLOSE From 122def9f124f82ccb6af1b7269b040429e0e88b7 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Mon, 26 Feb 2018 19:19:13 -0800 Subject: [PATCH 0597/2161] Added proper 65sc02, 65ce02 and 4510 detection. --- include/6502.h | 2 ++ libsrc/common/getcpu.s | 34 ++++++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/include/6502.h b/include/6502.h index 31398e5c1..55083b036 100644 --- a/include/6502.h +++ b/include/6502.h @@ -51,6 +51,8 @@ typedef unsigned size_t; #define CPU_65C02 1 #define CPU_65816 2 #define CPU_4510 3 +#define CPU_65SC02 4 +#define CPU_65CE02 5 unsigned char getcpu (void); /* Detect the CPU the program is running on */ diff --git a/libsrc/common/getcpu.s b/libsrc/common/getcpu.s index 1e60a5d39..764e73a84 100644 --- a/libsrc/common/getcpu.s +++ b/libsrc/common/getcpu.s @@ -10,9 +10,11 @@ ; Subroutine to detect an 816. Returns ; ; - carry clear and 0 in A for a NMOS 6502 CPU -; - carry set and 1 in A for some CMOS 6502 CPU +; - carry set and 1 in A for a 65c02 ; - carry set and 2 in A for a 65816 ; - carry set and 3 in A for a 4510 +; - carry set and 4 in A for a 65sc02 +; - carry set and 5 in A for a 65ce02 ; ; This function uses a $1A opcode which is a INA on the 816 and ignored ; (interpreted as a NOP) on a NMOS 6502. There are several CMOS versions @@ -27,20 +29,40 @@ _getcpu: cmp #1 bcc @L9 -; This is at least a 65C02, check for a 4510 +; This is at least a 65C02, check for a 65ce02/4510 - .byte $42,$ea ; neg on 4510, nop #$ea on 65c02, wdm $ea on 65816 + .byte $42,$ea ; neg on 65ce02/4510, nop #$ea on 65c02, wdm $ea on 65816 cmp #1 - bne @L8 + beq @L6 + +; check for 4510 + + lda #5 ; CPU_65CE02 constant + .byte $5c ; map on 4510, aug on 65ce02 (acts like 4 byte nop) + lda #3 ; CPU_4510 constant + nop + bne @L9 + +; check for 65sc02 + +@L6: ldy $f7 + ldx #$00 + stx $f7 + .byte $f7,$f7 ; nop nop on 65sc02, smb7 $f7 on 65c02 and 65816 + ldx $f7 + sty $f7 + cpx #$00 + bne @L7 + lda #4 ; CPU_65SC02 constant + bne @L9 ; check for 65816; after 4510, because $eb there is row (rotate word) - xba ; .byte $eb, put $01 in B accu +@L7: xba ; .byte $eb, put $01 in B accu dec a ; .byte $3a, A=$00 if 65C02 xba ; .byte $eb, get $01 back if 65816 inc a ; .byte $1a, make $01/$02 .byte $2c ; bit instruction to skip next command -@L8: lda #3 ; CPU_4510 constant @L9: ldx #0 ; Load high byte of word rts From e3779978b2a894eaa1ffa7682b8ccf20b9cf4ce5 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Mon, 26 Feb 2018 19:19:13 -0800 Subject: [PATCH 0598/2161] Added proper 65sc02, 65ce02 and 4510 detection. --- include/6502.h | 2 ++ libsrc/common/getcpu.s | 34 ++++++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/include/6502.h b/include/6502.h index 31398e5c1..55083b036 100644 --- a/include/6502.h +++ b/include/6502.h @@ -51,6 +51,8 @@ typedef unsigned size_t; #define CPU_65C02 1 #define CPU_65816 2 #define CPU_4510 3 +#define CPU_65SC02 4 +#define CPU_65CE02 5 unsigned char getcpu (void); /* Detect the CPU the program is running on */ diff --git a/libsrc/common/getcpu.s b/libsrc/common/getcpu.s index 1e60a5d39..764e73a84 100644 --- a/libsrc/common/getcpu.s +++ b/libsrc/common/getcpu.s @@ -10,9 +10,11 @@ ; Subroutine to detect an 816. Returns ; ; - carry clear and 0 in A for a NMOS 6502 CPU -; - carry set and 1 in A for some CMOS 6502 CPU +; - carry set and 1 in A for a 65c02 ; - carry set and 2 in A for a 65816 ; - carry set and 3 in A for a 4510 +; - carry set and 4 in A for a 65sc02 +; - carry set and 5 in A for a 65ce02 ; ; This function uses a $1A opcode which is a INA on the 816 and ignored ; (interpreted as a NOP) on a NMOS 6502. There are several CMOS versions @@ -27,20 +29,40 @@ _getcpu: cmp #1 bcc @L9 -; This is at least a 65C02, check for a 4510 +; This is at least a 65C02, check for a 65ce02/4510 - .byte $42,$ea ; neg on 4510, nop #$ea on 65c02, wdm $ea on 65816 + .byte $42,$ea ; neg on 65ce02/4510, nop #$ea on 65c02, wdm $ea on 65816 cmp #1 - bne @L8 + beq @L6 + +; check for 4510 + + lda #5 ; CPU_65CE02 constant + .byte $5c ; map on 4510, aug on 65ce02 (acts like 4 byte nop) + lda #3 ; CPU_4510 constant + nop + bne @L9 + +; check for 65sc02 + +@L6: ldy $f7 + ldx #$00 + stx $f7 + .byte $f7,$f7 ; nop nop on 65sc02, smb7 $f7 on 65c02 and 65816 + ldx $f7 + sty $f7 + cpx #$00 + bne @L7 + lda #4 ; CPU_65SC02 constant + bne @L9 ; check for 65816; after 4510, because $eb there is row (rotate word) - xba ; .byte $eb, put $01 in B accu +@L7: xba ; .byte $eb, put $01 in B accu dec a ; .byte $3a, A=$00 if 65C02 xba ; .byte $eb, get $01 back if 65816 inc a ; .byte $1a, make $01/$02 .byte $2c ; bit instruction to skip next command -@L8: lda #3 ; CPU_4510 constant @L9: ldx #0 ; Load high byte of word rts From e79e779aba9aa463b7d4c5fa1f0beaf6016d5793 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Mon, 26 Feb 2018 19:30:25 -0800 Subject: [PATCH 0599/2161] Removed bit opcode, not needed anymore. --- libsrc/common/getcpu.s | 1 - 1 file changed, 1 deletion(-) diff --git a/libsrc/common/getcpu.s b/libsrc/common/getcpu.s index 764e73a84..f7ac3c170 100644 --- a/libsrc/common/getcpu.s +++ b/libsrc/common/getcpu.s @@ -62,7 +62,6 @@ _getcpu: dec a ; .byte $3a, A=$00 if 65C02 xba ; .byte $eb, get $01 back if 65816 inc a ; .byte $1a, make $01/$02 - .byte $2c ; bit instruction to skip next command @L9: ldx #0 ; Load high byte of word rts From 5d029af79ee46d4e57aa583c6d47cab333be5c02 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Tue, 27 Feb 2018 11:44:34 -0800 Subject: [PATCH 0600/2161] Fixed the 65816/65802 detection. --- libsrc/common/getcpu.s | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/libsrc/common/getcpu.s b/libsrc/common/getcpu.s index f7ac3c170..05a6d0143 100644 --- a/libsrc/common/getcpu.s +++ b/libsrc/common/getcpu.s @@ -35,7 +35,7 @@ _getcpu: cmp #1 beq @L6 -; check for 4510 +; This is at least a 65ce02, check for 4510 lda #5 ; CPU_65CE02 constant .byte $5c ; map on 4510, aug on 65ce02 (acts like 4 byte nop) @@ -43,25 +43,26 @@ _getcpu: nop bne @L9 +; Check for 65816/65802 +@L6: xba ; .byte $eb, put $01 in B accu (nop on 65c02/65sc02) + dec a ; .byte $3a, A=$00 + xba ; .byte $eb, A=$01 if 65816/65802 and A=$00 if 65c02/65sc02 + inc a ; .byte $1a, A=$02 if 65816/65802 and A=$01 if 65c02/65sc02 + cmp #2 + beq @L9 + ; check for 65sc02 -@L6: ldy $f7 - ldx #$00 + ldy $f7 + ldx #0 stx $f7 - .byte $f7,$f7 ; nop nop on 65sc02, smb7 $f7 on 65c02 and 65816 + .byte $f7,$f7 ; nop nop on 65sc02, smb7 $f7 on 65c02 ldx $f7 sty $f7 cpx #$00 - bne @L7 - lda #4 ; CPU_65SC02 constant bne @L9 + lda #4 ; CPU_65SC02 constant -; check for 65816; after 4510, because $eb there is row (rotate word) - -@L7: xba ; .byte $eb, put $01 in B accu - dec a ; .byte $3a, A=$00 if 65C02 - xba ; .byte $eb, get $01 back if 65816 - inc a ; .byte $1a, make $01/$02 @L9: ldx #0 ; Load high byte of word rts From 85467231ab1ec3d707c80ca1edbe353b492ae573 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 28 Feb 2018 00:24:28 +0000 Subject: [PATCH 0601/2161] Update More conio targets --- doc/library.sgml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/doc/library.sgml b/doc/library.sgml index 9b923c308..c36605844 100644 --- a/doc/library.sgml +++ b/doc/library.sgml @@ -4,7 +4,7 @@ <title>cc65 Library Overview <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2014-04-12 +<date>2018-02-28 <abstract> An overview over the runtime and C libraries that come with the cc65 compiler, @@ -43,7 +43,7 @@ Functions that are <em/not/ available: <itemize> <item><tt>tmpfile/tmpnam</tt> <p> - <item><tt>system</tt> + <item><tt>system</tt> (cc65 alternative <tt>exec</tt>) <p> <item>All functions that handle floating point numbers in some manner. <p> @@ -172,10 +172,15 @@ portable. conio implementations exist for the following targets: <item>plus4 (or expanded c16/c116) <item>cbm510 (40 column video) <item>cbm610 (all CBM series-II computers with 80 column video) + <item>creativision + <item>gamate <item>geos-apple <item>geos-cbm <item>nes + <item>osic1p + <item>pce <item>pet (all CBM PET systems except the 2001) + <item>telestrat <item>vic20 </itemize> @@ -204,6 +209,7 @@ the following targets: <item>atarixl <item>c64 <item>c128 + <item>cbm510 </itemize> The available functions are declared in <tt/mouse.h/. @@ -235,6 +241,3 @@ freely, subject to the following restrictions: </enum> </article> - - - From 549f09db9c83b4720af04c44b68b324a108849ef Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 28 Feb 2018 14:59:52 -0500 Subject: [PATCH 0602/2161] Made two indirect jumps through the zero-page go through page $20 on the PC-Engine. --- libsrc/pce/call.s | 16 ++++++++++++++++ libsrc/pce/callptr4.s | 14 ++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 libsrc/pce/call.s create mode 100644 libsrc/pce/callptr4.s diff --git a/libsrc/pce/call.s b/libsrc/pce/call.s new file mode 100644 index 000000000..f99879866 --- /dev/null +++ b/libsrc/pce/call.s @@ -0,0 +1,16 @@ +; +; CC65 runtime: call function via pointer in ax +; +; 1998-08-06, Ullrich von Bassewitz +; 2018-02-28, Greg King +; + + .export callax + .importzp ptr1 + +callax: sta ptr1 + stx ptr1+1 + +; The PC-Engine puts the zero-page at $2000. + + jmp (ptr1 + $2000) ; go there diff --git a/libsrc/pce/callptr4.s b/libsrc/pce/callptr4.s new file mode 100644 index 000000000..7829cdb8e --- /dev/null +++ b/libsrc/pce/callptr4.s @@ -0,0 +1,14 @@ +; +; CC65 runtime: call function via pointer in ptr4 +; +; 2018-02-28, Greg King +; + + .export callptr4 + .importzp ptr4 + +callptr4: + +; The PC-Engine puts the zero-page at $2000. + + jmp (ptr4 + $2000) From 102d486207ddbcab5b136cab8eb475cdf13cb4a6 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Thu, 1 Mar 2018 08:55:29 -0800 Subject: [PATCH 0603/2161] Updated getcpu() function documentation. --- doc/funcref.sgml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index bbab694fa..de7bd31a2 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -3448,6 +3448,9 @@ returns one of the constants<itemize> <item><tt/CPU_6502/ <item><tt/CPU_65C02/ <item><tt/CPU_65816/ +<item><tt/CPU_4510/ +<item><tt/CPU_65SC02/ +<item><tt/CPU_65CE02/ </itemize> <tag/Notes/<itemize> <item>Other, more exotic CPU types are not disinguished. From 5a9d908007b255c2d6896cdc73a50e5cad20bb25 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Thu, 1 Mar 2018 14:57:42 -0800 Subject: [PATCH 0604/2161] Added 2a03/2a07 and HuC6280 detection. --- doc/funcref.sgml | 2 ++ include/6502.h | 2 ++ libsrc/common/getcpu.s | 50 ++++++++++++++++++++++++++++++------------ 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index de7bd31a2..235a0d40f 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -3451,6 +3451,8 @@ returns one of the constants<itemize> <item><tt/CPU_4510/ <item><tt/CPU_65SC02/ <item><tt/CPU_65CE02/ +<item><tt/CPU_HUC6280/ +<item><tt/CPU_2A0x/ </itemize> <tag/Notes/<itemize> <item>Other, more exotic CPU types are not disinguished. diff --git a/include/6502.h b/include/6502.h index 55083b036..642a608a8 100644 --- a/include/6502.h +++ b/include/6502.h @@ -53,6 +53,8 @@ typedef unsigned size_t; #define CPU_4510 3 #define CPU_65SC02 4 #define CPU_65CE02 5 +#define CPU_HUC6280 6 +#define CPU_2A0x 7 unsigned char getcpu (void); /* Detect the CPU the program is running on */ diff --git a/libsrc/common/getcpu.s b/libsrc/common/getcpu.s index 05a6d0143..bc71a4340 100644 --- a/libsrc/common/getcpu.s +++ b/libsrc/common/getcpu.s @@ -10,11 +10,13 @@ ; Subroutine to detect an 816. Returns ; ; - carry clear and 0 in A for a NMOS 6502 CPU -; - carry set and 1 in A for a 65c02 +; - carry set and 1 in A for a 65C02 ; - carry set and 2 in A for a 65816 ; - carry set and 3 in A for a 4510 -; - carry set and 4 in A for a 65sc02 -; - carry set and 5 in A for a 65ce02 +; - carry set and 4 in A for a 65SC02 +; - carry set and 5 in A for a 65CE02 +; - carry set and 6 in A for a HuC6280 +; - carry clear and 7 in A for a 2a03/2a07 ; ; This function uses a $1A opcode which is a INA on the 816 and ignored ; (interpreted as a NOP) on a NMOS 6502. There are several CMOS versions @@ -27,40 +29,60 @@ _getcpu: lda #0 inc a ; .byte $1A ; nop on nmos, inc on every cmos cmp #1 - bcc @L9 + bcc @L8 -; This is at least a 65C02, check for a 65ce02/4510 +; This is at least a 65C02, check for a 65CE02/4510 - .byte $42,$ea ; neg on 65ce02/4510, nop #$ea on 65c02, wdm $ea on 65816 + .byte $42,$ea ; neg on 65CE02/4510, nop #$ea on 65C02, wdm $ea on 65816 cmp #1 beq @L6 -; This is at least a 65ce02, check for 4510 +; This is at least a 65CE02, check for 4510 lda #5 ; CPU_65CE02 constant - .byte $5c ; map on 4510, aug on 65ce02 (acts like 4 byte nop) + .byte $5c ; map on 4510, aug on 65CE02 (acts like 4 byte nop) lda #3 ; CPU_4510 constant nop bne @L9 +; 6502 type of cpu, check for a 2a03/2a07 +@L8: + sed ; set decimal mode, no decimal mode on the 2a03/2a07 + lda #9 + clc + adc #1 ; $01+$09 = $10 on 6502, $01+$09 = $0a on 2a03/2a07 + cld + cmp #10 + bne @L5 + lda #0 ; CPU_6502 constant + beq @L9 +@L5: + lda #7 ; CPU_2A0x constant + bne @L9 + +; 65C02 cpu type, check for HuC6280 +@L4: ldx #6 ; CPU_HUC6280 constant + .byte $22,$ea ; sax nop on HuC6280 (A=$06, X=$01), nop #$ea on 65C02 (A=$01, X=$06) + bne @L9 + ; Check for 65816/65802 -@L6: xba ; .byte $eb, put $01 in B accu (nop on 65c02/65sc02) +@L6: xba ; .byte $eb, put $01 in B accu (nop on 65C02/65SC02) dec a ; .byte $3a, A=$00 - xba ; .byte $eb, A=$01 if 65816/65802 and A=$00 if 65c02/65sc02 - inc a ; .byte $1a, A=$02 if 65816/65802 and A=$01 if 65c02/65sc02 + xba ; .byte $eb, A=$01 if 65816/65802 and A=$00 if 65C02/65SC02 + inc a ; .byte $1a, A=$02 if 65816/65802 and A=$01 if 65C02/65SC02 cmp #2 beq @L9 -; check for 65sc02 +; check for 65SC02 ldy $f7 ldx #0 stx $f7 - .byte $f7,$f7 ; nop nop on 65sc02, smb7 $f7 on 65c02 + .byte $f7,$f7 ; nop nop on 65SC02, smb7 $f7 on 65C02 ldx $f7 sty $f7 cpx #$00 - bne @L9 + bne @L4 lda #4 ; CPU_65SC02 constant @L9: ldx #0 ; Load high byte of word From 57abfcd581abd5c674e42cfdd8857b574efcaa9d Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 2 Mar 2018 22:16:59 +0100 Subject: [PATCH 0605/2161] Joystick drivers don't depend on interrupts anymore. --- doc/apple2.sgml | 3 +-- doc/apple2enh.sgml | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 822dd564e..43651c7fa 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -470,8 +470,7 @@ BASIC.SYSTEM) there are some limitations for DOS 3.3: <tag/Interrupts/ There's no <tt/interruptor/ support. Any attempt to use it yields the message 'FAILED TO ALLOC INTERRUPT' on program startup. This implicitly means that - joystick, mouse and RS232 device drivers are not functional as they depend on - interrupts. + mouse and RS232 device drivers are not functional as they depend on interrupts. </descrip><p> diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 3a53b6b8c..3f335d028 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -471,8 +471,7 @@ BASIC.SYSTEM) there are some limitations for DOS 3.3: <tag/Interrupts/ There's no <tt/interruptor/ support. Any attempt to use it yields the message 'Failed to alloc interrupt' on program startup. This implicitly means that - joystick, mouse and RS232 device drivers are not functional as they depend on - interrupts. + mouse and RS232 device drivers are not functional as they depend on interrupts. </descrip><p> From b37e06da8fc1fbbf57fcbcbb4744879c14c6a20a Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Fri, 2 Mar 2018 14:09:02 -0800 Subject: [PATCH 0606/2161] Fixed hex digits case. --- libsrc/common/getcpu.s | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/libsrc/common/getcpu.s b/libsrc/common/getcpu.s index bc71a4340..7fe002f65 100644 --- a/libsrc/common/getcpu.s +++ b/libsrc/common/getcpu.s @@ -33,14 +33,14 @@ _getcpu: ; This is at least a 65C02, check for a 65CE02/4510 - .byte $42,$ea ; neg on 65CE02/4510, nop #$ea on 65C02, wdm $ea on 65816 + .byte $42,$EA ; neg on 65CE02/4510, nop #$EA on 65C02, wdm $EA on 65816 cmp #1 beq @L6 ; This is at least a 65CE02, check for 4510 lda #5 ; CPU_65CE02 constant - .byte $5c ; map on 4510, aug on 65CE02 (acts like 4 byte nop) + .byte $5C ; map on 4510, aug on 65CE02 (acts like 4 byte nop) lda #3 ; CPU_4510 constant nop bne @L9 @@ -50,7 +50,7 @@ _getcpu: sed ; set decimal mode, no decimal mode on the 2a03/2a07 lda #9 clc - adc #1 ; $01+$09 = $10 on 6502, $01+$09 = $0a on 2a03/2a07 + adc #1 ; $01+$09 = $10 on 6502, $01+$09 = $0A on 2a03/2a07 cld cmp #10 bne @L5 @@ -62,25 +62,25 @@ _getcpu: ; 65C02 cpu type, check for HuC6280 @L4: ldx #6 ; CPU_HUC6280 constant - .byte $22,$ea ; sax nop on HuC6280 (A=$06, X=$01), nop #$ea on 65C02 (A=$01, X=$06) + .byte $22,$EA ; sax nop on HuC6280 (A=$06, X=$01), nop #$EA on 65C02 (A=$01, X=$06) bne @L9 ; Check for 65816/65802 -@L6: xba ; .byte $eb, put $01 in B accu (nop on 65C02/65SC02) - dec a ; .byte $3a, A=$00 - xba ; .byte $eb, A=$01 if 65816/65802 and A=$00 if 65C02/65SC02 - inc a ; .byte $1a, A=$02 if 65816/65802 and A=$01 if 65C02/65SC02 +@L6: xba ; .byte $EB, put $01 in B accu (nop on 65C02/65SC02) + dec a ; .byte $3A, A=$00 + xba ; .byte $EB, A=$01 if 65816/65802 and A=$00 if 65C02/65SC02 + inc a ; .byte $1A, A=$02 if 65816/65802 and A=$01 if 65C02/65SC02 cmp #2 beq @L9 ; check for 65SC02 - ldy $f7 + ldy $F7 ldx #0 - stx $f7 - .byte $f7,$f7 ; nop nop on 65SC02, smb7 $f7 on 65C02 - ldx $f7 - sty $f7 + stx $F7 + .byte $F7,$F7 ; nop nop on 65SC02, smb7 $F7 on 65C02 + ldx $F7 + sty $F7 cpx #$00 bne @L4 lda #4 ; CPU_65SC02 constant From c3610aa971d2894c9eeded09552320bf7fb03a82 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 5 Mar 2018 20:08:17 +0100 Subject: [PATCH 0607/2161] Updated from Visual Studio 2013 to Visual Studio 2015. --- src/.gitignore | 2 ++ src/ar65.vcxproj | 6 +++--- src/ca65.vcxproj | 6 +++--- src/cc65.vcxproj | 6 +++--- src/chrcvt65.vcxproj | 6 +++--- src/cl65.vcxproj | 6 +++--- src/co65.vcxproj | 6 +++--- src/common.vcxproj | 6 +++--- src/da65.vcxproj | 6 +++--- src/grc65.vcxproj | 6 +++--- src/ld65.vcxproj | 6 +++--- src/od65.vcxproj | 6 +++--- src/sim65.vcxproj | 6 +++--- src/sp65.vcxproj | 6 +++--- 14 files changed, 41 insertions(+), 39 deletions(-) diff --git a/src/.gitignore b/src/.gitignore index d2b9fe751..a2c8bb5d4 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -2,5 +2,7 @@ ipch/ *.suo *.sdf *.opensdf +*.VC.db +*.VC.VC.opendb *.vcxproj.filters *.vcxproj.user diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index b077134ce..003a5fa69 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index 4e02fa2a9..fb7cf2e26 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 70f43dc73..12573e862 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 1daf7cae9..d120399d1 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index 64c1126b1..b6ceb161a 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/co65.vcxproj b/src/co65.vcxproj index c66c8aac8..89eed36e1 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/common.vcxproj b/src/common.vcxproj index 39fea35e5..644d6da85 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -115,13 +115,13 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> <ConfigurationType>StaticLibrary</ConfigurationType> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 2695edc08..06af7505d 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 211ad7cce..afac0cce1 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index acb9b4240..cc5598aad 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/od65.vcxproj b/src/od65.vcxproj index c788ac961..2ace26001 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index f87b4db6b..9ba0980ba 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 8db98346c..6e7d992d4 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -18,12 +18,12 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v120</PlatformToolset> + <PlatformToolset>v140</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> From 19f3229f45262da83c910650c382f5bdd510d022 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 5 Mar 2018 20:44:32 +0100 Subject: [PATCH 0608/2161] Made 'wrapped call' code build with VS 2015. --- src/cc65/pragma.c | 2 +- src/cc65/wrappedcall.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 25bc29d43..64ea4a1aa 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -525,7 +525,7 @@ static void WrappedCallPragma (StrBuf* B) /* Check if the name is valid */ if (Entry && Entry->Flags & SC_FUNC) { - PushWrappedCall(Entry, Val); + PushWrappedCall(Entry, (unsigned char) Val); Entry->Flags |= SC_REF; Entry->V.F.Func->Flags |= FD_CALL_WRAPPER; diff --git a/src/cc65/wrappedcall.c b/src/cc65/wrappedcall.c index 2d11245fd..18cb507ac 100644 --- a/src/cc65/wrappedcall.c +++ b/src/cc65/wrappedcall.c @@ -97,6 +97,6 @@ void GetWrappedCall (void **Ptr, unsigned char *Val) } else { long Temp; IPS_Get (&WrappedCalls, &Temp, Ptr); - *Val = Temp; + *Val = (unsigned char) Temp; } } From bc58bf572cf317f54580018cf12968693768228d Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 5 Mar 2018 22:31:10 +0100 Subject: [PATCH 0609/2161] Fixed -W cmdline option handling. Reverted part of https://github.com/cc65/cc65/commit/3157e4be1ec7f2a5ac61ca45b232cd07c5e30483 as it actually introduced a regression. It doesn't make sense to check for Arg[3] == '\0' _before_ checking Arg[2] != '\0'. This made the Win32 builds fail to correctly parse e.g. cl65 -W unused-var test.c --- src/cl65/main.c | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index 5a2103b24..afd3e97e3 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -1444,35 +1444,24 @@ int main (int argc, char* argv []) /* Print version number */ OptVersion (Arg, 0); break; - + case 'E': /* Forward -E to compiler */ CmdAddArg (&CC65, Arg); DisableAssemblingAndLinking (); break; - + case 'W': - /* avoid && with'\0' in if clauses */ - if (Arg[3] == '\0') { - switch (Arg[2]) { - case 'a': - /* -Wa: Pass options to assembler */ - OptAsmArgs (Arg, GetArg (&I, 3)); - break; - case 'c': - /* -Wc: Pass options to compiler - ** Remember -Wc sub arguments in cc65 arg struct - */ - OptCCArgs (Arg, GetArg (&I, 3)); - break; - case 'l': - /* -Wl: Pass options to linker */ - OptLdArgs (Arg, GetArg (&I, 3)); - break; - default: - UnknownOption (Arg); - break; - } + if (Arg[2] == 'a' && Arg[3] == '\0') { + /* -Wa: Pass options to assembler */ + OptAsmArgs (Arg, GetArg (&I, 3)); + } else if (Arg[2] == 'c' && Arg[3] == '\0') { + /* -Wc: Pass options to compiler */ + /* Remember -Wc sub arguments in cc65 arg struct */ + OptCCArgs (Arg, GetArg (&I, 3)); + } else if (Arg[2] == 'l' && Arg[3] == '\0') { + /* -Wl: Pass options to linker */ + OptLdArgs (Arg, GetArg (&I, 3)); } else { /* Anything else: Suppress warnings (compiler) */ CmdAddArg2 (&CC65, "-W", GetArg (&I, 2)); From 40e93dd931a9d9893f29490a434d28a64b830289 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Mon, 5 Mar 2018 15:01:55 -0800 Subject: [PATCH 0610/2161] Improved reu size detection. --- libsrc/c128/emd/c128-reu.s | 59 ++++++++++++++++++++++++++++++------- libsrc/c64/emd/c64-reu.s | 60 +++++++++++++++++++++++++++++++------- 2 files changed, 99 insertions(+), 20 deletions(-) diff --git a/libsrc/c128/emd/c128-reu.s b/libsrc/c128/emd/c128-reu.s index a858c591e..3b191c666 100644 --- a/libsrc/c128/emd/c128-reu.s +++ b/libsrc/c128/emd/c128-reu.s @@ -92,17 +92,56 @@ INSTALL: cmp REU_REUADDR ; Check for presence of REU bne nodevice - ldy #>(128*4) ; Assume 128KB - lda REU_STATUS - and #$10 ; Check size bit - beq @L1 - ldy #>(256*4) ; 256KB when size bit is set -@L1: sty pagecount+1 - +; determine the size + php + sei ldy #$FF - sty curpage - sty curpage+1 ; Invalidate the current page - txa ; X = A = EM_ERR_OK +loop: + sty window + jsr reu_size_check_common + ldx #%10110000 + stx REU_COMMAND + dey + cpy #$FF + bne loop + iny +size_loop: + jsr reu_size_check_common + ldx #%10110001 + stx REU_COMMAND + cpy window + bne size_found + iny + bne size_loop +size_found: + plp + ldx #$00 + cpy #$00 ; too many pages, shave off 2 + bne pagecount_ok + dex + dex + dey +pagecount_ok: + stx pagecount + sty pagecount+1 + lda #<EM_ERR_OK + ldx #>EM_ERR_OK + rts + +; common REU setup for size check +reu_size_check_common: + sty REU_REUADDR+2 + ldx #<window + stx REU_C64ADDR + ldx #>window + stx REU_C64ADDR+1 + ldx #$00 + stx REU_REUADDR + stx REU_REUADDR+1 + stx REU_COUNT+1 + stx REU_CONTROL + inx + stx REU_COUNT rts ; No REU found diff --git a/libsrc/c64/emd/c64-reu.s b/libsrc/c64/emd/c64-reu.s index 0779505be..5bbed2f3a 100644 --- a/libsrc/c64/emd/c64-reu.s +++ b/libsrc/c64/emd/c64-reu.s @@ -92,19 +92,59 @@ INSTALL: cmp REU_REUADDR ; Check for presence of REU bne nodevice - ldy #>(128*4) ; Assume 128KB - lda REU_STATUS - and #$10 ; Check size bit - beq @L1 - ldy #>(256*4) ; 256KB when size bit is set -@L1: sty pagecount+1 - +; determine the size + php + sei ldy #$FF - sty curpage - sty curpage+1 ; Invalidate the current page - txa ; X = A = EM_ERR_OK +loop: + sty window + jsr reu_size_check_common + ldx #%10110000 + stx REU_COMMAND + dey + cpy #$FF + bne loop + iny +size_loop: + jsr reu_size_check_common + ldx #%10110001 + stx REU_COMMAND + cpy window + bne size_found + iny + bne size_loop +size_found: + plp + ldx #$00 + cpy #$00 ; too many pages, shave off 2 + bne pagecount_ok + dex + dex + dey +pagecount_ok: + stx pagecount + sty pagecount+1 + lda #<EM_ERR_OK + ldx #>EM_ERR_OK rts +; common REU setup for size check +reu_size_check_common: + sty REU_REUADDR+2 + ldx #<window + stx REU_C64ADDR + ldx #>window + stx REU_C64ADDR+1 + ldx #$00 + stx REU_REUADDR + stx REU_REUADDR+1 + stx REU_COUNT+1 + stx REU_CONTROL + inx + stx REU_COUNT + rts + + ; No REU found nodevice: From b78328057722e68df7d110056af016abbe9c9f7e Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Mon, 5 Mar 2018 17:46:51 -0800 Subject: [PATCH 0611/2161] Replaced reu commands with defined constants. --- libsrc/c128/emd/c128-reu.s | 6 ++++-- libsrc/c64/emd/c64-reu.s | 7 +++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/libsrc/c128/emd/c128-reu.s b/libsrc/c128/emd/c128-reu.s index 3b191c666..3ded00d67 100644 --- a/libsrc/c128/emd/c128-reu.s +++ b/libsrc/c128/emd/c128-reu.s @@ -55,6 +55,8 @@ REU_TRIGGER = $FF00 ; REU command trigger OP_COPYFROM = $ED OP_COPYTO = $EC +OP_COPYFROM_ALOAD = $B1 +OP_COPYTO_ALOAD = $B0 ; ------------------------------------------------------------------------ ; Data. @@ -99,7 +101,7 @@ INSTALL: loop: sty window jsr reu_size_check_common - ldx #%10110000 + ldx #OP_COPYTO_ALOAD stx REU_COMMAND dey cpy #$FF @@ -107,7 +109,7 @@ loop: iny size_loop: jsr reu_size_check_common - ldx #%10110001 + ldx #OP_COPYFROM_ALOAD stx REU_COMMAND cpy window bne size_found diff --git a/libsrc/c64/emd/c64-reu.s b/libsrc/c64/emd/c64-reu.s index 5bbed2f3a..bf7bb4fb0 100644 --- a/libsrc/c64/emd/c64-reu.s +++ b/libsrc/c64/emd/c64-reu.s @@ -55,6 +55,9 @@ REU_TRIGGER = $FF00 ; REU command trigger OP_COPYFROM = $ED OP_COPYTO = $EC +OP_COPYFROM_ALOAD = $B1 +OP_COPYTO_ALOAD = $B0 + ; ------------------------------------------------------------------------ ; Data. @@ -99,7 +102,7 @@ INSTALL: loop: sty window jsr reu_size_check_common - ldx #%10110000 + ldx #OP_COPYTO_ALOAD stx REU_COMMAND dey cpy #$FF @@ -107,7 +110,7 @@ loop: iny size_loop: jsr reu_size_check_common - ldx #%10110001 + ldx #OP_COPYFROM_ALOAD stx REU_COMMAND cpy window bne size_found From 223750cde9abc860549dc6b28c6f4d2c577e0d19 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 6 Mar 2018 20:43:08 +0100 Subject: [PATCH 0612/2161] CC65_HOME is gone for quite some time by now. --- doc/using-make.sgml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/doc/using-make.sgml b/doc/using-make.sgml index 0c3c13a6e..e0e99a99c 100644 --- a/doc/using-make.sgml +++ b/doc/using-make.sgml @@ -58,7 +58,7 @@ SOURCES = foo.c bar.c PROGRAM = foobar ifdef CC65_TARGET -CC = $(CC65_HOME)/bin/cl65 +CC = cl65 CFLAGS = -t $(CC65_TARGET) --create-dep $(<:.c=.d) -O LDFLAGS = -t $(CC65_TARGET) -m $(PROGRAM).map else @@ -104,12 +104,6 @@ best done on the GNU Make command line like this: make CC65_TARGET=c64 </verb></tscreen> -The sample Makefile presumes the variable <tt/CC65_HOME/ to point to the -directory cc65 is located in. Again there are several ways to define this -variable but as its value typically won't change often it is best done as an -environment variable. On Windows the cc65 .exe installer package takes care -of creating a <tt/CC65_HOME/ environment variable. - <sect1>Understanding the sample Makefile<p> From c0d8021fd5795b9ed58c11dbf9a376bdbcbc367a Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 6 Mar 2018 23:36:11 +0100 Subject: [PATCH 0613/2161] add comment on linking, tweak a bit for easier debugging --- testcode/lib/joy-test.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/testcode/lib/joy-test.c b/testcode/lib/joy-test.c index fdd83bb4e..51cbb53e2 100644 --- a/testcode/lib/joy-test.c +++ b/testcode/lib/joy-test.c @@ -5,7 +5,6 @@ #include <conio.h> #include <joystick.h> - #ifdef JOYSTICK_DRIVER /* A statically linked driver was named on the compiler's command line. @@ -13,6 +12,22 @@ */ # undef DYN_DRV # define DYN_DRV 0 + +/* + * link existing drivers like this: + * + * cl65 -DJOYSTICK_DRIVER=c64_hitjoy_joy -o joy-test.prg joy-test.c + * + * for testing a new driver you will have to uncomment the define below, and + * link your driver like this: + * + * co65 ../../target/c64/drv/joy/c64-hitjoy.joy -o hitjoy.s --code-label _hitjoy + * cl65 -DJOYSTICK_DRIVER=hitjoy -o joy-test.prg joy-test.c hitjoy.s + * +*/ + +/* extern char JOYSTICK_DRIVER; */ + #else /* Use a dynamically loaded driver, by default. */ @@ -27,13 +42,16 @@ int main (void) unsigned char j; unsigned char count; unsigned char i; + unsigned char Res; + + clrscr (); #if DYN_DRV - unsigned char Res = joy_load_driver (joy_stddrv); + Res = joy_load_driver (joy_stddrv); #elif defined(JOYSTICK_DRIVER) - unsigned char Res = joy_install (&JOYSTICK_DRIVER); + Res = joy_install (&JOYSTICK_DRIVER); #else - unsigned char Res = joy_install (&joy_static_stddrv); + Res = joy_install (&joy_static_stddrv); #endif if (Res != JOY_ERR_OK) { @@ -44,7 +62,6 @@ int main (void) exit (EXIT_FAILURE); } - clrscr (); count = joy_count (); #if defined(__ATARI5200__) || defined(__CREATIVISION__) cprintf ("JOYSTICKS: %d", count); @@ -56,21 +73,21 @@ int main (void) gotoxy (0, i+1); j = joy_read (i); #if defined(__ATARI5200__) || defined(__CREATIVISION__) - cprintf ("%1d:%-3s%-3s%-3s%-3s%-3s%-3s", + cprintf ("%1d:%-3s%-3s%-3s%-3s%-3s %02x", i, JOY_UP(j)? " U " : " - ", JOY_DOWN(j)? " D " : " - ", JOY_LEFT(j)? " L " : " - ", JOY_RIGHT(j)? " R " : " - ", - JOY_BTN_1(j)? " 1 " : " - "); + JOY_BTN_1(j)? " 1 " : " - ", j); #else - cprintf ("%2d: %-6s%-6s%-6s%-6s%-6s%-6s", + cprintf ("%2d: %-6s%-6s%-6s%-6s%-6s %02x", i, JOY_UP(j)? " up " : " ---- ", JOY_DOWN(j)? " down " : " ---- ", JOY_LEFT(j)? " left " : " ---- ", JOY_RIGHT(j)? "right " : " ---- ", - JOY_BTN_1(j)? "button" : " ---- "); + JOY_BTN_1(j)? "button" : " ---- ", j); #endif } } From 38fedfd78bdc81032495365e7cd76665d7b3b14f Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 7 Mar 2018 00:19:14 +0100 Subject: [PATCH 0614/2161] also show pressed key, so we can verify keyboard works with the joystick driver --- testcode/lib/joy-test.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/testcode/lib/joy-test.c b/testcode/lib/joy-test.c index 51cbb53e2..167534137 100644 --- a/testcode/lib/joy-test.c +++ b/testcode/lib/joy-test.c @@ -43,6 +43,7 @@ int main (void) unsigned char count; unsigned char i; unsigned char Res; + unsigned char ch, kb; clrscr (); @@ -90,6 +91,14 @@ int main (void) JOY_BTN_1(j)? "button" : " ---- ", j); #endif } + + /* show pressed key, so we can verify keyboard is working */ + kb = kbhit(); + ch = kb ? cgetc() : ' '; + gotoxy (1, i+2); + revers(kb); + cprintf("kbd: %c", ch); + revers(0); } return 0; } From 3afbed48e068f5c467d122229c80c48fe21063c4 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 7 Mar 2018 00:20:42 +0100 Subject: [PATCH 0615/2161] tweak driver to no more use IRQ --- libsrc/c64/joy/c64-hitjoy.s | 48 ++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/libsrc/c64/joy/c64-hitjoy.s b/libsrc/c64/joy/c64-hitjoy.s index 9f6c0b4dd..3b4a0b909 100644 --- a/libsrc/c64/joy/c64-hitjoy.s +++ b/libsrc/c64/joy/c64-hitjoy.s @@ -73,13 +73,22 @@ UNINSTALL: rts ; ------------------------------------------------------------------------ -; IRQ entry point. Is called from the C layer as a subroutine in the -; interrupt. The routine MUST return carry set if the interrupt has been -; 'handled' - which means that the interrupt source is gone. Otherwise it -; MUST return carry clear. +; COUNT: Return the total number of available joysticks in a/x. +; -IRQ: ; cia 2 setup +COUNT: lda #<JOY_COUNT + ldx #>JOY_COUNT + rts +; ------------------------------------------------------------------------ +; READ: Read a particular joystick passed in A. +; + +readadapter: + + sei + + ; cia 2 setup ldy #$00 ; port b direction sty $dd03 ; => input @@ -143,32 +152,24 @@ IRQ: ; cia 2 setup sta temp4 fire: - ; Default Value: $40/64 on PAL - ; $42/66 on NTSC + ; FIXME: to be really 100% correct this should restore the correct timer + ; values for the respective machine (PAL: $4025, NTSC: $4295) + ; however, this should hardly be a problem in a real world program + lda #$41 sta $dc05 - ; Default Value: $25/37 on PAL - ; $95/149 on NTSC lda #0 sta $dc04 - ; We do never "handle" the interrupt, we use it just as a timer. - clc + cli rts -; ------------------------------------------------------------------------ -; COUNT: Return the total number of available joysticks in a/x. -; +READ: + pha + jsr readadapter + pla -COUNT: lda #<JOY_COUNT - ldx #>JOY_COUNT - rts - -; ------------------------------------------------------------------------ -; READ: Read a particular joystick passed in A. -; - -READ: tax ; Joystick number into X + tax ; Joystick number into X bne joy2 ; Read joystick 1 @@ -214,4 +215,3 @@ joy4: lda temp4 eor #$1F ldx #0 rts - From 2418c0e0af7d070e0748c58cfa0f77ab54bff4a2 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Tue, 6 Mar 2018 18:00:36 -0800 Subject: [PATCH 0616/2161] Updated documentation for the reu emd. --- doc/c128.sgml | 6 ++---- doc/c64.sgml | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/doc/c128.sgml b/doc/c128.sgml index 460621be0..f133d8d4c 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -221,10 +221,8 @@ missing on VDC, and are translated to the two colors missing from the VIC palett Will test the hardware for the available RAM. <tag><tt/c128-reu.emd (c128_reu_emd)/</tag> - A driver for the CBM REUs. The driver will determine from the connected REU - if it supports 128KB of RAM or more. In the latter case, 256KB are assumed, - but since there are no range checks, the application can use more memory if - it has better knowledge about the hardware than the driver. + A driver for the CBM REUs. The driver will test the connected REU to find + out how much RAM is present. <tag><tt/c128-vdc.emd (c128_vdc_emd)/</tag> A driver for the VDC memory of the C128, written and contributed by Maciej diff --git a/doc/c64.sgml b/doc/c64.sgml index 9ab9b96c3..7cca1aa09 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -300,10 +300,8 @@ Note that the graphics drivers are incompatible with the Will test the hardware for the available RAM. <tag><tt/c64-reu.emd (c64_reu_emd)/</tag> - A driver for the CBM REUs. The driver will determine from the connected REU - if it supports 128KB of RAM or more. In the latter case, 256KB are assumed, - but since there are no range checks, the application can use more memory if - it has better knowledge about the hardware than the driver. + A driver for the CBM REUs. The driver will test the connected REU to find + out how much RAM is present. <tag><tt/c64-vdc.emd (c64_vdc_emd)/</tag> A driver for the VDC memory of the C128. Written and contributed by Maciej From a32c50a6bc4e8e23e9f8e3178304fc4c9717aaa6 Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Wed, 7 Mar 2018 20:45:50 +0100 Subject: [PATCH 0617/2161] Optimize deceaxy. --- libsrc/runtime/ldec.s | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/libsrc/runtime/ldec.s b/libsrc/runtime/ldec.s index 53b60095d..ee7ed3fd4 100644 --- a/libsrc/runtime/ldec.s +++ b/libsrc/runtime/ldec.s @@ -1,5 +1,6 @@ ; -; Ullrich von Bassewitz, 29.12.1999 +; Piotr Fusik, 07.03.2018 +; originally by Ullrich von Bassewitz ; ; CC65 runtime: Decrement eax by value in Y ; @@ -11,16 +12,13 @@ deceaxy: sty tmp1 sec sbc tmp1 - sta tmp1 - txa - sbc #0 - tax - lda sreg - sbc #0 - sta sreg - lda sreg+1 - sbc #0 - sta sreg+1 - lda tmp1 - rts + bcs @L9 + dex + cpx #$ff + bne @L9 + dec sreg + cpx sreg + bne @L9 + dec sreg+1 +@L9: rts From 5251b67d73c2977412aaed6da2d3769b6be57003 Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Wed, 7 Mar 2018 21:01:29 +0100 Subject: [PATCH 0618/2161] Fix comment typos. --- libsrc/runtime/incaxy.s | 2 +- libsrc/runtime/incsp2.s | 2 +- libsrc/runtime/jmpvec.s | 2 +- libsrc/runtime/mulax3.s | 2 +- libsrc/runtime/mulax5.s | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libsrc/runtime/incaxy.s b/libsrc/runtime/incaxy.s index 0ee7d879f..faeacf709 100644 --- a/libsrc/runtime/incaxy.s +++ b/libsrc/runtime/incaxy.s @@ -1,7 +1,7 @@ ; ; Ullrich von Bassewitz, 05.08.1998 ; -; CC65 runtime: Increment ax by valie in y +; CC65 runtime: Increment ax by value in y ; .export incaxy, incax4 diff --git a/libsrc/runtime/incsp2.s b/libsrc/runtime/incsp2.s index 067154b86..0ed0ffcdf 100644 --- a/libsrc/runtime/incsp2.s +++ b/libsrc/runtime/incsp2.s @@ -2,7 +2,7 @@ ; Ullrich von Bassewitz, 25.10.2000 ; ; CC65 runtime: Increment the stackpointer by 2. For performance reasons, -; this modules does also contain the popax function. +; this module also contains the popax function. .export popax, incsp2 .importzp sp diff --git a/libsrc/runtime/jmpvec.s b/libsrc/runtime/jmpvec.s index ed77a0789..29a18b1db 100644 --- a/libsrc/runtime/jmpvec.s +++ b/libsrc/runtime/jmpvec.s @@ -1,7 +1,7 @@ ; ; Ullrich von Bassewitz, 2002-12-26 ; -; CC65 runtime: Jump vector that resides in the data segment so it's address +; CC65 runtime: Jump vector that resides in the data segment so its address ; may be patched at runtime. ; diff --git a/libsrc/runtime/mulax3.s b/libsrc/runtime/mulax3.s index c35b05dcc..472bc60ec 100644 --- a/libsrc/runtime/mulax3.s +++ b/libsrc/runtime/mulax3.s @@ -1,7 +1,7 @@ ; ; Ullrich von Bassewitz, 04.10.2001 ; -; CC65 runtime: Multiply the primary register +; CC65 runtime: Multiply the primary register by 3 ; .export mulax3 diff --git a/libsrc/runtime/mulax5.s b/libsrc/runtime/mulax5.s index 9af599806..7e5ed11d9 100644 --- a/libsrc/runtime/mulax5.s +++ b/libsrc/runtime/mulax5.s @@ -1,7 +1,7 @@ ; ; Ullrich von Bassewitz, 04.10.2001 ; -; CC65 runtime: Multiply the primary register +; CC65 runtime: Multiply the primary register by 5 ; .export mulax5 From 8e759067376d6c45e5d11d5af274eaea42ca9403 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 7 Mar 2018 23:04:33 +0100 Subject: [PATCH 0619/2161] Switched Apple II output format to AppleSingle. Although the primary target OS for the Apple II for sure isn't DOS 3.3 but ProDOS 8 the Apple II binary files contained a DOS 3.3 4-byte header. Recently I was made aware of the AppleSingle file format. That format is a much better way to transport Apple II meta data from the cc65 toolchain to the ProDOS 8 file system. Therefore I asked AppleCommander to support the AppleSingle file format. Now that there's an AppleCommander BETA with AppleSingle support it's the right time for this change. I bumped version to 2.17 because of this from the perspective of Apple II users of course incompatible change. --- cfg/apple2-asm.cfg | 5 +++- cfg/apple2-hgr.cfg | 3 ++- cfg/apple2-overlay.cfg | 13 ++++++----- cfg/apple2-system.cfg | 14 ++++++++---- cfg/apple2.cfg | 3 ++- cfg/apple2enh-asm.cfg | 5 +++- cfg/apple2enh-hgr.cfg | 3 ++- cfg/apple2enh-overlay.cfg | 13 ++++++----- cfg/apple2enh-system.cfg | 14 ++++++++---- cfg/apple2enh.cfg | 3 ++- doc/apple2.sgml | 48 +++++++++++++++++---------------------- doc/apple2enh.sgml | 48 +++++++++++++++++---------------------- doc/intro.sgml | 13 +++++------ libsrc/apple2/exehdr.s | 32 ++++++++++++++++++++++---- samples/Makefile | 8 +++---- src/common/version.c | 2 +- 16 files changed, 129 insertions(+), 98 deletions(-) diff --git a/cfg/apple2-asm.cfg b/cfg/apple2-asm.cfg index 8e5abefc5..76bca1b86 100644 --- a/cfg/apple2-asm.cfg +++ b/cfg/apple2-asm.cfg @@ -3,9 +3,12 @@ FEATURES { STARTADDRESS: default = $0803; } +SYMBOLS { + __FILETYPE__: type = weak, value = $0006; # ProDOS file type +} MEMORY { ZP: file = "", start = $0000, size = $00FF; - HEADER: file = %O, start = %S - 4, size = $0004; + HEADER: file = %O, start = %S - $003A, size = $003A; MAIN: file = %O, define = yes, start = %S, size = $C000 - %S; BSS: file = "", start = __MAIN_LAST__, size = $C000 - __MAIN_LAST__; } diff --git a/cfg/apple2-hgr.cfg b/cfg/apple2-hgr.cfg index b11dd12bc..3ccf7b6f3 100644 --- a/cfg/apple2-hgr.cfg +++ b/cfg/apple2-hgr.cfg @@ -5,6 +5,7 @@ FEATURES { } SYMBOLS { __EXEHDR__: type = import; + __FILETYPE__: type = weak, value = $0006; # ProDOS file type __STACKSIZE__: type = weak, value = $0800; # 2k stack __HIMEM__: type = weak, value = $9600; # Presumed RAM end __LCADDR__: type = weak, value = $D400; # Behind quit code @@ -12,7 +13,7 @@ SYMBOLS { } MEMORY { ZP: file = "", define = yes, start = $0080, size = $001A; - HEADER: file = %O, start = %S - 4, size = $0004; + 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__; LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; diff --git a/cfg/apple2-overlay.cfg b/cfg/apple2-overlay.cfg index d5476d264..a0b7678c1 100644 --- a/cfg/apple2-overlay.cfg +++ b/cfg/apple2-overlay.cfg @@ -1,10 +1,10 @@ # Configuration for overlay programs (overlays located below main program) -# The overlay files don't include the 4 byte DOS 3.3 header so use AppleCommander like this: -# java -jar ac.jar -cc65 mydisk.dsk myprog bin < myprog -# java -jar ac.jar -p mydisk.dsk myprog.1 bin < myprog.1 -# java -jar ac.jar -p mydisk.dsk myprog.2 bin < myprog.2 -# java -jar ac.jar -p mydisk.dsk myprog.3 bin < myprog.3 +# The overlay files are raw binary files so use AppleCommander like this: +# java -jar ac.jar -as mydisk.dsk myprog < myprog +# java -jar ac.jar -p mydisk.dsk myprog.1 bin < myprog.1 +# java -jar ac.jar -p mydisk.dsk myprog.2 bin < myprog.2 +# java -jar ac.jar -p mydisk.dsk myprog.3 bin < myprog.3 # ... FEATURES { @@ -12,6 +12,7 @@ FEATURES { } SYMBOLS { __EXEHDR__: type = import; + __FILETYPE__: type = weak, value = $0006; # ProDOS file type __STACKSIZE__: type = weak, value = $0800; # 2k stack __HIMEM__: type = weak, value = $9600; # Presumed RAM end __LCADDR__: type = weak, value = $D400; # Behind quit code @@ -20,7 +21,7 @@ SYMBOLS { } MEMORY { ZP: file = "", define = yes, start = $0080, size = $001A; - HEADER: file = %O, start = %S - 4, size = $0004; + HEADER: file = %O, start = %S - $003A, size = $003A; 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__; diff --git a/cfg/apple2-system.cfg b/cfg/apple2-system.cfg index f4684d9c2..0170feb93 100644 --- a/cfg/apple2-system.cfg +++ b/cfg/apple2-system.cfg @@ -1,18 +1,22 @@ -# Configuration for ProDOS 8 system programs (without the header) +# Configuration for ProDOS 8 system programs (allowing for 3KB in LC) SYMBOLS { + __EXEHDR__: type = import; + __FILETYPE__: type = weak, value = $00FF; # ProDOS file type __STACKSIZE__: type = weak, value = $0800; # 2k stack __LCADDR__: type = weak, value = $D400; # Behind quit code __LCSIZE__: type = weak, value = $0C00; # Rest of bank two } MEMORY { - ZP: file = "", define = yes, start = $0080, size = $001A; - MAIN: file = %O, start = $2000, size = $BF00 - $2000; - BSS: file = "", start = __ONCE_RUN__, size = $BF00 - __STACKSIZE__ - __ONCE_RUN__; - LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; + ZP: file = "", define = yes, start = $0080, size = $001A; + HEADER: file = %O, start = $2000 - $003A, size = $003A; + 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__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; + EXEHDR: load = HEADER, type = ro, optional = yes; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; diff --git a/cfg/apple2.cfg b/cfg/apple2.cfg index bbe45839d..a6809cf89 100644 --- a/cfg/apple2.cfg +++ b/cfg/apple2.cfg @@ -5,6 +5,7 @@ FEATURES { } SYMBOLS { __EXEHDR__: type = import; + __FILETYPE__: type = weak, value = $0006; # ProDOS file type __STACKSIZE__: type = weak, value = $0800; # 2k stack __HIMEM__: type = weak, value = $9600; # Presumed RAM end __LCADDR__: type = weak, value = $D400; # Behind quit code @@ -12,7 +13,7 @@ SYMBOLS { } MEMORY { ZP: file = "", define = yes, start = $0080, size = $001A; - HEADER: file = %O, start = %S - 4, size = $0004; + 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__; LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; diff --git a/cfg/apple2enh-asm.cfg b/cfg/apple2enh-asm.cfg index 8e5abefc5..76bca1b86 100644 --- a/cfg/apple2enh-asm.cfg +++ b/cfg/apple2enh-asm.cfg @@ -3,9 +3,12 @@ FEATURES { STARTADDRESS: default = $0803; } +SYMBOLS { + __FILETYPE__: type = weak, value = $0006; # ProDOS file type +} MEMORY { ZP: file = "", start = $0000, size = $00FF; - HEADER: file = %O, start = %S - 4, size = $0004; + HEADER: file = %O, start = %S - $003A, size = $003A; MAIN: file = %O, define = yes, start = %S, size = $C000 - %S; BSS: file = "", start = __MAIN_LAST__, size = $C000 - __MAIN_LAST__; } diff --git a/cfg/apple2enh-hgr.cfg b/cfg/apple2enh-hgr.cfg index b11dd12bc..3ccf7b6f3 100644 --- a/cfg/apple2enh-hgr.cfg +++ b/cfg/apple2enh-hgr.cfg @@ -5,6 +5,7 @@ FEATURES { } SYMBOLS { __EXEHDR__: type = import; + __FILETYPE__: type = weak, value = $0006; # ProDOS file type __STACKSIZE__: type = weak, value = $0800; # 2k stack __HIMEM__: type = weak, value = $9600; # Presumed RAM end __LCADDR__: type = weak, value = $D400; # Behind quit code @@ -12,7 +13,7 @@ SYMBOLS { } MEMORY { ZP: file = "", define = yes, start = $0080, size = $001A; - HEADER: file = %O, start = %S - 4, size = $0004; + 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__; LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; diff --git a/cfg/apple2enh-overlay.cfg b/cfg/apple2enh-overlay.cfg index d5476d264..a0b7678c1 100644 --- a/cfg/apple2enh-overlay.cfg +++ b/cfg/apple2enh-overlay.cfg @@ -1,10 +1,10 @@ # Configuration for overlay programs (overlays located below main program) -# The overlay files don't include the 4 byte DOS 3.3 header so use AppleCommander like this: -# java -jar ac.jar -cc65 mydisk.dsk myprog bin < myprog -# java -jar ac.jar -p mydisk.dsk myprog.1 bin < myprog.1 -# java -jar ac.jar -p mydisk.dsk myprog.2 bin < myprog.2 -# java -jar ac.jar -p mydisk.dsk myprog.3 bin < myprog.3 +# The overlay files are raw binary files so use AppleCommander like this: +# java -jar ac.jar -as mydisk.dsk myprog < myprog +# java -jar ac.jar -p mydisk.dsk myprog.1 bin < myprog.1 +# java -jar ac.jar -p mydisk.dsk myprog.2 bin < myprog.2 +# java -jar ac.jar -p mydisk.dsk myprog.3 bin < myprog.3 # ... FEATURES { @@ -12,6 +12,7 @@ FEATURES { } SYMBOLS { __EXEHDR__: type = import; + __FILETYPE__: type = weak, value = $0006; # ProDOS file type __STACKSIZE__: type = weak, value = $0800; # 2k stack __HIMEM__: type = weak, value = $9600; # Presumed RAM end __LCADDR__: type = weak, value = $D400; # Behind quit code @@ -20,7 +21,7 @@ SYMBOLS { } MEMORY { ZP: file = "", define = yes, start = $0080, size = $001A; - HEADER: file = %O, start = %S - 4, size = $0004; + HEADER: file = %O, start = %S - $003A, size = $003A; 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__; diff --git a/cfg/apple2enh-system.cfg b/cfg/apple2enh-system.cfg index f4684d9c2..0170feb93 100644 --- a/cfg/apple2enh-system.cfg +++ b/cfg/apple2enh-system.cfg @@ -1,18 +1,22 @@ -# Configuration for ProDOS 8 system programs (without the header) +# Configuration for ProDOS 8 system programs (allowing for 3KB in LC) SYMBOLS { + __EXEHDR__: type = import; + __FILETYPE__: type = weak, value = $00FF; # ProDOS file type __STACKSIZE__: type = weak, value = $0800; # 2k stack __LCADDR__: type = weak, value = $D400; # Behind quit code __LCSIZE__: type = weak, value = $0C00; # Rest of bank two } MEMORY { - ZP: file = "", define = yes, start = $0080, size = $001A; - MAIN: file = %O, start = $2000, size = $BF00 - $2000; - BSS: file = "", start = __ONCE_RUN__, size = $BF00 - __STACKSIZE__ - __ONCE_RUN__; - LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; + ZP: file = "", define = yes, start = $0080, size = $001A; + HEADER: file = %O, start = $2000 - $003A, size = $003A; + 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__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; + EXEHDR: load = HEADER, type = ro, optional = yes; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; diff --git a/cfg/apple2enh.cfg b/cfg/apple2enh.cfg index bbe45839d..a6809cf89 100644 --- a/cfg/apple2enh.cfg +++ b/cfg/apple2enh.cfg @@ -5,6 +5,7 @@ FEATURES { } SYMBOLS { __EXEHDR__: type = import; + __FILETYPE__: type = weak, value = $0006; # ProDOS file type __STACKSIZE__: type = weak, value = $0800; # 2k stack __HIMEM__: type = weak, value = $9600; # Presumed RAM end __LCADDR__: type = weak, value = $D400; # Behind quit code @@ -12,7 +13,7 @@ SYMBOLS { } MEMORY { ZP: file = "", define = yes, start = $0080, size = $001A; - HEADER: file = %O, start = %S - 4, size = $0004; + 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__; LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 43651c7fa..eef0eed3d 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -34,20 +34,14 @@ more information. <sect>Binary format<p> The standard binary file format generated by the linker for the -Apple ][ target is a binary program with a 4 byte DOS 3.3 header -containing the load address and load length. The default load address is -$803. +Apple ][ target is an <url name="AppleSingle" +url="http://kaiser-edv.de/documents/AppleSingle_AppleDouble.pdf"> file. +The default load address is $803. -<bf/AppleCommander 1.3.5/ or later (available at <url -url="https://applecommander.github.io/">) includes the option <tt/-cc65/ -that allows to put binary files with a DOS 3.3 header onto disk images -containing DOS 3.3 as well as ProDOS 8. - -For ProDOS 8 system programs the load address is fixed to $2000 so there -is no need for a header. Thus the linker configuration -<ref id="apple-sys-cfg" name="apple2-system.cfg"> for those programs -omits the DOS 3.3 header. The right AppleCommander option to put system files -without a header on a ProDOS 8 disk image is <tt/-p/. +<bf/AppleCommander 1.4.0/ or later (available at <url +url="https://applecommander.github.io/">) includes the option <tt/-as/ that +allows to put AppleSingle files onto disk images containing DOS 3.3 as well +as ProDOS 8. <sect>Memory layout<p> @@ -121,9 +115,8 @@ Parameters: <tag><tt/STARTADDRESS:/ Program start address</tag> Default: $803. Use <tt/-S <addr>/ to set a different start address. - <tag><tt/__EXEHDR__:/ Executable file header</tag> - Default: DOS 3.3 header (address and length). Use <tt/-D __EXEHDR__=0/ to omit - the header. + <tag><tt/__EXEHDR__:/ AppleSingle executable file header</tag> + Default: Yes. Use <tt/-D __EXEHDR__=0/ to omit the AppleSingle header. <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> Default: $800. Use <tt/-D __STACKSIZE__=<size>/ to set a different @@ -153,6 +146,9 @@ Parameters: <descrip> + <tag><tt/__EXEHDR__:/ AppleSingle executable file header</tag> + Default: Yes. Use <tt/-D __EXEHDR__=0/ to omit the AppleSingle header. + <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> Default: $800. Use <tt/-D __STACKSIZE__=<size>/ to set a different stack size. @@ -180,9 +176,8 @@ Parameters: <tag><tt/STARTADDRESS:/ Program start address</tag> Default: $803. Use <tt/-S <addr>/ to set a different start address. - <tag><tt/__EXEHDR__:/ Executable file header</tag> - Default: DOS 3.3 header (address and length). Use <tt/-D __EXEHDR__=0/ to omit - the header. + <tag><tt/__EXEHDR__:/ AppleSingle executable file header</tag> + Default: Yes. Use <tt/-D __EXEHDR__=0/ to omit the AppleSingle header. <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> Default: $800. Use <tt/-D __STACKSIZE__=<size>/ to set a different @@ -206,7 +201,7 @@ Parameters: <sect1><tt/apple2-overlay.cfg/<p> Configuration for an overlay program with up to nine overlays. The overlay files -don't include the DOS 3.3 header. See <tt>samples/overlaydemo.c</tt> for more +don't include the AppleSingle header. See <tt>samples/overlaydemo.c</tt> for more information on overlays. Parameters: @@ -216,9 +211,8 @@ Parameters: <tag><tt/STARTADDRESS:/ Program start address</tag> Default: $803. Use <tt/-S <addr>/ to set a different start address. - <tag><tt/__EXEHDR__:/ Executable file header</tag> - Default: DOS 3.3 header (address and length). Use <tt/-D __EXEHDR__=0/ to omit - the header. + <tag><tt/__EXEHDR__:/ AppleSingle executable file header</tag> + Default: Yes. Use <tt/-D __EXEHDR__=0/ to omit the AppleSingle header. <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> Default: $800. Use <tt/-D __STACKSIZE__=<size>/ to set a different @@ -254,9 +248,8 @@ Parameters: <tag><tt/STARTADDRESS:/ Program start address</tag> Default: $803. Use <tt/-S <addr>/ to set a different start address. - <tag><tt/__EXEHDR__:/ Executable file header</tag> - Default: No header. Use <tt/-u __EXEHDR__ apple2.lib/ to add a DOS 3.3 header - (address and length). + <tag><tt/__EXEHDR__:/ AppleSingle executable file header</tag> + Default: No. Use <tt/-u __EXEHDR__ apple2.lib/ to add the AppleSingle header. </descrip><p> @@ -281,7 +274,8 @@ program (i.e. quits to the ProDOS dispatcher). Using LOADER.SYSTEM is as simple as copying it to the ProDOS 8 directory of the program to load under name <program>.SYSTEM as a system program. For -example the program <tt/MYPROG/ is loaded by <tt/MYPROG.SYSTEM/. +example the program <tt/MYPROG/ is loaded by <tt/MYPROG.SYSTEM/. The right +AppleCommander option to put LOADER.SYSTEM on a ProDOS 8 disk image is <tt/-p/. <sect1>Heap<p> diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 3f335d028..b40523aba 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -34,20 +34,14 @@ more information. <sect>Binary format<p> The standard binary file format generated by the linker for the -enhanced Apple //e target is a binary program with a 4 byte DOS 3.3 header -containing the load address and load length. The default load address is -$803. +enhanced Apple //e target is an <url name="AppleSingle" +url="http://kaiser-edv.de/documents/AppleSingle_AppleDouble.pdf"> file. +The default load address is $803. -<bf/AppleCommander 1.3.5/ or later (available at <url -url="https://applecommander.github.io/">) includes the option <tt/-cc65/ -that allows to put binary files with a DOS 3.3 header onto disk images -containing DOS 3.3 as well as ProDOS 8. - -For ProDOS 8 system programs the load address is fixed to $2000 so there -is no need for a header. Thus the linker configuration -<ref id="apple-sys-cfg" name="apple2enh-system.cfg"> for those programs -omits the DOS 3.3 header. The right AppleCommander option to put system files -without a header on a ProDOS 8 disk image is <tt/-p/. +<bf/AppleCommander 1.4.0/ or later (available at <url +url="https://applecommander.github.io/">) includes the option <tt/-as/ that +allows to put AppleSingle files onto disk images containing DOS 3.3 as well +as ProDOS 8. <sect>Memory layout<p> @@ -121,9 +115,8 @@ Parameters: <tag><tt/STARTADDRESS:/ Program start address</tag> Default: $803. Use <tt/-S <addr>/ to set a different start address. - <tag><tt/__EXEHDR__:/ Executable file header</tag> - Default: DOS 3.3 header (address and length). Use <tt/-D __EXEHDR__=0/ to omit - the header. + <tag><tt/__EXEHDR__:/ AppleSingle executable file header</tag> + Default: Yes. Use <tt/-D __EXEHDR__=0/ to omit the AppleSingle header. <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> Default: $800. Use <tt/-D __STACKSIZE__=<size>/ to set a different @@ -153,6 +146,9 @@ Parameters: <descrip> + <tag><tt/__EXEHDR__:/ AppleSingle executable file header</tag> + Default: Yes. Use <tt/-D __EXEHDR__=0/ to omit the AppleSingle header. + <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> Default: $800. Use <tt/-D __STACKSIZE__=<size>/ to set a different stack size. @@ -180,9 +176,8 @@ Parameters: <tag><tt/STARTADDRESS:/ Program start address</tag> Default: $803. Use <tt/-S <addr>/ to set a different start address. - <tag><tt/__EXEHDR__:/ Executable file header</tag> - Default: DOS 3.3 header (address and length). Use <tt/-D __EXEHDR__=0/ to omit - the header. + <tag><tt/__EXEHDR__:/ AppleSingle executable file header</tag> + Default: Yes. Use <tt/-D __EXEHDR__=0/ to omit the AppleSingle header. <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> Default: $800. Use <tt/-D __STACKSIZE__=<size>/ to set a different @@ -206,7 +201,7 @@ Parameters: <sect1><tt/apple2enh-overlay.cfg/<p> Configuration for an overlay program with up to nine overlays. The overlay files -don't include the DOS 3.3 header. See <tt>samples/overlaydemo.c</tt> for more +don't include the AppleSingle header. See <tt>samples/overlaydemo.c</tt> for more information on overlays. Parameters: @@ -216,9 +211,8 @@ Parameters: <tag><tt/STARTADDRESS:/ Program start address</tag> Default: $803. Use <tt/-S <addr>/ to set a different start address. - <tag><tt/__EXEHDR__:/ Executable file header</tag> - Default: DOS 3.3 header (address and length). Use <tt/-D __EXEHDR__=0/ to omit - the header. + <tag><tt/__EXEHDR__:/ AppleSingle executable file header</tag> + Default: Yes. Use <tt/-D __EXEHDR__=0/ to omit the AppleSingle header. <tag><tt/__STACKSIZE__:/ C runtime stack size</tag> Default: $800. Use <tt/-D __STACKSIZE__=<size>/ to set a different @@ -254,9 +248,8 @@ Parameters: <tag><tt/STARTADDRESS:/ Program start address</tag> Default: $803. Use <tt/-S <addr>/ to set a different start address. - <tag><tt/__EXEHDR__:/ Executable file header</tag> - Default: No header. Use <tt/-u __EXEHDR__ apple2enh.lib/ to add a DOS 3.3 header - (address and length). + <tag><tt/__EXEHDR__:/ AppleSingle executable file header</tag> + Default: No. Use <tt/-u __EXEHDR__ apple2enh.lib/ to add the AppleSingle header. </descrip><p> @@ -281,7 +274,8 @@ program (i.e. quits to the ProDOS dispatcher). Using LOADER.SYSTEM is as simple as copying it to the ProDOS 8 directory of the program to load under name <program>.SYSTEM as a system program. For -example the program <tt/MYPROG/ is loaded by <tt/MYPROG.SYSTEM/. +example the program <tt/MYPROG/ is loaded by <tt/MYPROG.SYSTEM/. The right +AppleCommander option to put LOADER.SYSTEM on a ProDOS 8 disk image is <tt/-p/. <sect1>Heap<p> diff --git a/doc/intro.sgml b/doc/intro.sgml index bb8965c60..47516e671 100644 --- a/doc/intro.sgml +++ b/doc/intro.sgml @@ -246,13 +246,13 @@ varies in its start and exit conditions. <sect2>AppleWin<p> Available at <url -url="http://applewin.berlios.de/">: +url="https://github.com/AppleWin/AppleWin">: Emulates Apple ][/enhanced Apple //e computers, with sound, video, joysticks, serial port, and disk images. Includes monitor. Only for Windows. The package comes with a DOS 3.3 disk (called "master.dsk") image; -however, you will need <bf/AppleCommander 1.3.5/ or later (available at <url -url="http://applecommander.sourceforge.net/">). +however, you will need <bf/AppleCommander 1.4.0/ or later (available at <url +url="https://applecommander.github.io/">). Compile the tutorial with @@ -270,14 +270,13 @@ the <tt/master.dsk/ which comes with <bf/AppleWin/, and rename it to <tt/cc65.dsk/, then use <bf/AppleCommander/: <tscreen><verb> -java -jar ac.jar -cc65 cc65.dsk test B < hello +java -jar ac.jar -as cc65.dsk test < hello </verb></tscreen> Note that a convention in the Apple world is that "hello" is the file which is run automatically upon booting a DOS disk, sort of like the "autoexec.bat" of -the MSDOS/Windows world. We've avoided that in the example, however. Also, -the <tt/B/ parameter must be in caps., and "test" is the name of the program as -it will appear on the Apple disk. +the MSDOS/Windows world. We've avoided that in the example, however by using +"test" as the name of the program as it will appear on the Apple disk. Start the emulator, click on the <bf/Disk 1/ icon, and point to <bf/cc65.dsk/; then, click the big Apple logo, to boot the system. Then, type this on the diff --git a/libsrc/apple2/exehdr.s b/libsrc/apple2/exehdr.s index 778eee903..72ea390e9 100644 --- a/libsrc/apple2/exehdr.s +++ b/libsrc/apple2/exehdr.s @@ -1,16 +1,40 @@ ; ; Oliver Schmidt, 2012-06-10 ; -; This module supplies a 4 byte DOS 3.3 header -; containing the load address and load length. +; 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" - .addr __MAIN_START__ ; Load address - .word __MAIN_LAST__ - __MAIN_START__ ; Load length +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/samples/Makefile b/samples/Makefile index 2bcfa08c3..6a6d93bc1 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -188,15 +188,15 @@ samples.d64: samples $(foreach file,$(EMD) $(MOU) $(TGI),$(D64_WRITE_recipe)) # -------------------------------------------------------------------------- -# Rule to make an Apple II disk with all samples. Needs the Apple Commander -# program available at http://applecommander.sourceforge.net/ and a template -# disk named 'prodos.dsk'. +# Rule to make an Apple II disk with all samples. Needs the AppleCommander +# program available at https://applecommander.github.io/ and a template disk +# named 'prodos.dsk'. define DSK_WRITE_BIN_recipe $(if $(findstring BF00,$(LDFLAGS_$(notdir $(file))_$(SYS))), \ java -jar $(AC) -p $@ $(notdir $(file)).system sys <$(TARGET_PATH)/$(SYS)/util/loader.system) -java -jar $(AC) -cc65 $@ $(notdir $(file)) bin <$(file) +java -jar $(AC) -as $@ $(notdir $(file)) <$(file) endef # DSK_WRITE_BIN_recipe diff --git a/src/common/version.c b/src/common/version.c index bf0a6bf71..1f1e8093e 100644 --- a/src/common/version.c +++ b/src/common/version.c @@ -47,7 +47,7 @@ #define VER_MAJOR 2U -#define VER_MINOR 16U +#define VER_MINOR 17U From 85e480db3d0623c5b313c5eb3c5976cc3d6f89d7 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 8 Mar 2018 04:05:10 +0100 Subject: [PATCH 0620/2161] style fixes --- testcode/lib/joy-test.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/testcode/lib/joy-test.c b/testcode/lib/joy-test.c index 167534137..3d584bf9d 100644 --- a/testcode/lib/joy-test.c +++ b/testcode/lib/joy-test.c @@ -14,16 +14,16 @@ # define DYN_DRV 0 /* - * link existing drivers like this: - * - * cl65 -DJOYSTICK_DRIVER=c64_hitjoy_joy -o joy-test.prg joy-test.c - * - * for testing a new driver you will have to uncomment the define below, and - * link your driver like this: - * - * co65 ../../target/c64/drv/joy/c64-hitjoy.joy -o hitjoy.s --code-label _hitjoy - * cl65 -DJOYSTICK_DRIVER=hitjoy -o joy-test.prg joy-test.c hitjoy.s - * +** link existing drivers like this: +** +** cl65 -DJOYSTICK_DRIVER=c64_hitjoy_joy -o joy-test.prg joy-test.c +** +** for testing a new driver you will have to uncomment the define below, and +** link your driver like this: +** +** co65 ../../target/c64/drv/joy/c64-hitjoy.joy -o hitjoy.s --code-label _hitjoy +** cl65 -DJOYSTICK_DRIVER=hitjoy -o joy-test.prg joy-test.c hitjoy.s +** */ /* extern char JOYSTICK_DRIVER; */ @@ -93,12 +93,12 @@ int main (void) } /* show pressed key, so we can verify keyboard is working */ - kb = kbhit(); - ch = kb ? cgetc() : ' '; + kb = kbhit (); + ch = kb ? cgetc () : ' '; gotoxy (1, i+2); - revers(kb); - cprintf("kbd: %c", ch); - revers(0); + revers (kb); + cprintf ("kbd: %c", ch); + revers (0); } return 0; } From 970c5f6184ca48a6db7118063ce284855cc63787 Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Thu, 8 Mar 2018 22:10:11 +0100 Subject: [PATCH 0621/2161] Add comments. --- libsrc/runtime/ldec.s | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libsrc/runtime/ldec.s b/libsrc/runtime/ldec.s index ee7ed3fd4..e7e891119 100644 --- a/libsrc/runtime/ldec.s +++ b/libsrc/runtime/ldec.s @@ -13,12 +13,15 @@ deceaxy: sec sbc tmp1 bcs @L9 +; borrow from X dex cpx #$ff bne @L9 +; X wrapped from zero to $ff, borrow from sreg dec sreg cpx sreg bne @L9 +; sreg wrapped from zero to $ff, borrow from sreg+1 dec sreg+1 @L9: rts From 22d4b0d497e72779bcc328987fc69bca4a402178 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Thu, 8 Mar 2018 16:06:33 -0800 Subject: [PATCH 0622/2161] Improved tv timing detection for the c64. --- asminc/get_tv.inc | 2 ++ include/cbm.h | 4 +++- libsrc/c64/get_tv.s | 43 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/asminc/get_tv.inc b/asminc/get_tv.inc index 47e0d9c2a..2d4b5b253 100644 --- a/asminc/get_tv.inc +++ b/asminc/get_tv.inc @@ -11,6 +11,8 @@ .enum TV NTSC PAL + NTSC_OLD + PAL_N OTHER .endenum diff --git a/include/cbm.h b/include/cbm.h index 1395f700f..b121050af 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -150,7 +150,9 @@ struct cbm_dirent { #define TV_NTSC 0 #define TV_PAL 1 -#define TV_OTHER 2 +#define TV_NTSC_OLD 2 +#define TV_PAL_N 3 +#define TV_OTHER 4 unsigned char get_tv (void); /* Return the video mode the machine is using. */ diff --git a/libsrc/c64/get_tv.s b/libsrc/c64/get_tv.s index 4f46b8d64..8c73f6fa4 100644 --- a/libsrc/c64/get_tv.s +++ b/libsrc/c64/get_tv.s @@ -3,6 +3,11 @@ ; ; unsigned char get_tv (void); ; /* Return the video mode the machine is using */ +; +; Changed to actually detect the mode instead of using a flag +; Marco van den Heuvel, 2018-03-08 +; +; The detection goes wrong on accelerated machines for now. ; .include "c64.inc" @@ -13,8 +18,42 @@ .proc _get_tv - lda PALFLAG - ldx #0 + php + sei +timing_loop_0: + lda VIC_HLINE +timing_loop_1: + cmp VIC_HLINE + beq timing_loop_1 + bmi timing_loop_0 + and #$03 + cmp #$01 + bne check_ntsc + lda #TV::NTSC_OLD ; NTSC OLD constant + bne detected +check_ntsc: + cmp #$03 + bcc ntsc + +; check for PAL and PAL-N + + ldx #$00 + lda #$10 +timing_loop_2: + inx + cmp VIC_HLINE + bne timing_loop_2 + lda #TV::PAL ; PAL constant + cpx #$70 + bcc detected + lda #TV::PAL_N ; PAL-N constant +detected: + ldx #$00 + plp rts +ntsc: + lda #TV::NTSC ; NTSC constant + beq detected + .endproc From 18ada212e7dda94d30e7df9b00f58f856bb8fc50 Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Fri, 9 Mar 2018 18:48:24 +0100 Subject: [PATCH 0623/2161] Fix coding style. --- libsrc/runtime/ldec.s | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/libsrc/runtime/ldec.s b/libsrc/runtime/ldec.s index e7e891119..f8e59d5c0 100644 --- a/libsrc/runtime/ldec.s +++ b/libsrc/runtime/ldec.s @@ -1,5 +1,5 @@ ; -; Piotr Fusik, 07.03.2018 +; Piotr Fusik, 09.03.2018 ; originally by Ullrich von Bassewitz ; ; CC65 runtime: Decrement eax by value in Y @@ -13,15 +13,24 @@ deceaxy: sec sbc tmp1 bcs @L9 -; borrow from X + +; Borrow from X. + dex - cpx #$ff + cpx #$FF bne @L9 -; X wrapped from zero to $ff, borrow from sreg + +; X wrapped from zero to $FF, borrow from sreg. + dec sreg cpx sreg bne @L9 -; sreg wrapped from zero to $ff, borrow from sreg+1 + +; sreg wrapped from zero to $FF, borrow from sreg+1. + dec sreg+1 + +; Done. + @L9: rts From 0eb1eb625fac71db5c0bfd79e6847a29be867d22 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Fri, 9 Mar 2018 10:46:02 -0800 Subject: [PATCH 0624/2161] Undo my previous commit. --- asminc/get_tv.inc | 2 -- include/cbm.h | 4 +--- libsrc/c64/get_tv.s | 43 ++----------------------------------------- 3 files changed, 3 insertions(+), 46 deletions(-) diff --git a/asminc/get_tv.inc b/asminc/get_tv.inc index 2d4b5b253..47e0d9c2a 100644 --- a/asminc/get_tv.inc +++ b/asminc/get_tv.inc @@ -11,8 +11,6 @@ .enum TV NTSC PAL - NTSC_OLD - PAL_N OTHER .endenum diff --git a/include/cbm.h b/include/cbm.h index b121050af..1395f700f 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -150,9 +150,7 @@ struct cbm_dirent { #define TV_NTSC 0 #define TV_PAL 1 -#define TV_NTSC_OLD 2 -#define TV_PAL_N 3 -#define TV_OTHER 4 +#define TV_OTHER 2 unsigned char get_tv (void); /* Return the video mode the machine is using. */ diff --git a/libsrc/c64/get_tv.s b/libsrc/c64/get_tv.s index 8c73f6fa4..4f46b8d64 100644 --- a/libsrc/c64/get_tv.s +++ b/libsrc/c64/get_tv.s @@ -3,11 +3,6 @@ ; ; unsigned char get_tv (void); ; /* Return the video mode the machine is using */ -; -; Changed to actually detect the mode instead of using a flag -; Marco van den Heuvel, 2018-03-08 -; -; The detection goes wrong on accelerated machines for now. ; .include "c64.inc" @@ -18,42 +13,8 @@ .proc _get_tv - php - sei -timing_loop_0: - lda VIC_HLINE -timing_loop_1: - cmp VIC_HLINE - beq timing_loop_1 - bmi timing_loop_0 - and #$03 - cmp #$01 - bne check_ntsc - lda #TV::NTSC_OLD ; NTSC OLD constant - bne detected -check_ntsc: - cmp #$03 - bcc ntsc - -; check for PAL and PAL-N - - ldx #$00 - lda #$10 -timing_loop_2: - inx - cmp VIC_HLINE - bne timing_loop_2 - lda #TV::PAL ; PAL constant - cpx #$70 - bcc detected - lda #TV::PAL_N ; PAL-N constant -detected: - ldx #$00 - plp + lda PALFLAG + ldx #0 rts -ntsc: - lda #TV::NTSC ; NTSC constant - beq detected - .endproc From 789ce59fb5489c73739412e6954674523203e466 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sun, 11 Mar 2018 00:49:40 +0100 Subject: [PATCH 0625/2161] Added missing PCE conio functions. --- libsrc/pce/cclear.s | 25 +++++++++++++++++++++++++ libsrc/pce/color.s | 10 ++++------ libsrc/pce/wherex.s | 24 ++++++++++++++++++++++++ libsrc/pce/wherey.s | 24 ++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 libsrc/pce/cclear.s create mode 100644 libsrc/pce/wherex.s create mode 100644 libsrc/pce/wherey.s diff --git a/libsrc/pce/cclear.s b/libsrc/pce/cclear.s new file mode 100644 index 000000000..14b9d0e8b --- /dev/null +++ b/libsrc/pce/cclear.s @@ -0,0 +1,25 @@ +; +; Ullrich von Bassewitz, 08.08.1998 +; +; void cclearxy (unsigned char x, unsigned char y, unsigned char length); +; void cclear (unsigned char length); +; + + .export _cclearxy, _cclear + .import gotoxy, cputdirect + .importzp tmp1 + +_cclearxy: + pha ; Save the length + jsr gotoxy ; Call this one, will pop params + pla ; Restore the length and run into _cclear + +_cclear: + cmp #0 ; Is the length zero? + beq L9 ; Jump if done + sta tmp1 +L1: lda #$20 ; Blank - screen code + jsr cputdirect ; Direct output + dec tmp1 + bne L1 +L9: rts diff --git a/libsrc/pce/color.s b/libsrc/pce/color.s index 0ff991a2e..1223d2936 100644 --- a/libsrc/pce/color.s +++ b/libsrc/pce/color.s @@ -5,11 +5,14 @@ ; - .export _textcolor, _bgcolor, _bordercolor + .export _textcolor, _bgcolor, _bordercolor + .import return0 .include "pce.inc" .include "extzp.inc" +_bordercolor = return0 + _textcolor: ldx CHARCOLOR ; get old value sta CHARCOLOR ; set new value @@ -32,11 +35,6 @@ _bgcolor: txa rts -_bordercolor: - lda #0 - tax - rts - .rodata .export colors diff --git a/libsrc/pce/wherex.s b/libsrc/pce/wherex.s new file mode 100644 index 000000000..3abe49cb6 --- /dev/null +++ b/libsrc/pce/wherex.s @@ -0,0 +1,24 @@ +; +; Ullrich von Bassewitz, 2003-05-02 +; +; unsigned char wherex (void); +; + + .export _wherex + + .include "pce.inc" + .include "extzp.inc" + +.proc _wherex + + lda CURS_X + ldx #$00 + rts + +.endproc + +;------------------------------------------------------------------------------- +; force the init constructor to be imported + + .import initconio +conio_init = initconio diff --git a/libsrc/pce/wherey.s b/libsrc/pce/wherey.s new file mode 100644 index 000000000..7061790ab --- /dev/null +++ b/libsrc/pce/wherey.s @@ -0,0 +1,24 @@ +; +; Ullrich von Bassewitz, 2003-05-02 +; +; unsigned char wherey (void); +; + + .export _wherey + + .include "pce.inc" + .include "extzp.inc" + +.proc _wherey + + lda CURS_Y + ldx #$00 + rts + +.endproc + +;------------------------------------------------------------------------------- +; force the init constructor to be imported + + .import initconio +conio_init = initconio From 8b3e12d632f22bfd3c3722d88195dc3ce4acc90a Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 12 Mar 2018 12:14:25 +0100 Subject: [PATCH 0626/2161] Added missing ror absolute override. Fixes https://github.com/cc65/cc65/issues/489 as suggested by EtchedPixels. --- src/da65/opc65c02.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/da65/opc65c02.c b/src/da65/opc65c02.c index 1351f5eee..8133bccae 100644 --- a/src/da65/opc65c02.c +++ b/src/da65/opc65c02.c @@ -157,7 +157,7 @@ const OpcDesc OpcTable_65C02[256] = { { "", 1, flIllegal, OH_Illegal, }, /* $6b */ { "jmp", 3, flLabel, OH_JmpAbsoluteIndirect }, /* $6c */ { "adc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $6d */ - { "ror", 3, flUseLabel, OH_Absolute }, /* $6e */ + { "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 */ From 7efd9940f223c84c1ada30294dfd746c5e40604f Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 13 Mar 2018 22:19:19 +0000 Subject: [PATCH 0627/2161] Added console --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index fa8c4df60..6704eec9b 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ including - newer PET machines (not 2001). - the Apple ]\[+ and successors. - the Atari 8 bit machines. +- the Atari 2600 console. - the Atari 5200 console. - GEOS for the C64, C128 and Apple //e. - the Bit Corporation Gamate console. From 0c7496f08b8a450dc5e963602c72b737687ba544 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Fri, 16 Mar 2018 14:23:52 -0700 Subject: [PATCH 0628/2161] Added vic20 - ram emd. --- include/vic20.h | 2 +- libsrc/vic20/emd/vic20-rama.s | 258 ++++++++++++++++++++++++++++++++++ libsrc/vic20/libref.s | 2 + 3 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 libsrc/vic20/emd/vic20-rama.s diff --git a/include/vic20.h b/include/vic20.h index c6ad9632d..1e8c4ceb5 100644 --- a/include/vic20.h +++ b/include/vic20.h @@ -105,7 +105,7 @@ extern void vic20_ptvjoy_joy[]; extern void vic20_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ - +extern void vic20_rama_emd[]; /* End of vic20.h */ #endif diff --git a/libsrc/vic20/emd/vic20-rama.s b/libsrc/vic20/emd/vic20-rama.s new file mode 100644 index 000000000..a48959c13 --- /dev/null +++ b/libsrc/vic20/emd/vic20-rama.s @@ -0,0 +1,258 @@ +; +; Extended memory driver for the VIC20 $A000-$BFFF RAM. Driver works without +; problems when statically linked. +; +; Marco van den Heuvel, 2018-03-16 +; + + .include "zeropage.inc" + + .include "em-kernel.inc" + .include "em-error.inc" + + + .macpack generic + .macpack module + + +; ------------------------------------------------------------------------ +; Header. Includes jump table + + module_header _vic20_rama_emd + +; Driver signature + + .byte $65, $6d, $64 ; "emd" + .byte EMD_API_VERSION ; EM API version number + +; Library reference + + .addr $0000 + +; Jump table + + .addr INSTALL + .addr UNINSTALL + .addr PAGECOUNT + .addr MAP + .addr USE + .addr COMMIT + .addr COPYFROM + .addr COPYTO + +; ------------------------------------------------------------------------ +; Constants + +BASE = $A000 +PAGES = ($C000 - BASE) / 256 + +; ------------------------------------------------------------------------ +; Data. + +.bss +curpage: .res 1 ; Current page number +window: .res 256 ; Memory "window" + +.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 EM_ERR_xx code in a/x. +; + +INSTALL: + lda $A000 ; see what is at address $A000 + inc $A000 ; see if it can be changed + cmp $A000 ; did it stick ? + beq nomem + dec $A000 + + ldx #$FF + stx curpage ; Invalidate the current page + inx ; X = 0 + txa ; A = X = EM_ERR_OK + rts + +nomem: ldx #>EM_ERR_NO_DEVICE + lda #<EM_ERR_NO_DEVICE +; 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 + + +; ------------------------------------------------------------------------ +; PAGECOUNT: Return the total number of available pages in a/x. +; + +PAGECOUNT: + lda #<PAGES + ldx #>PAGES + rts + +; ------------------------------------------------------------------------ +; MAP: Map the page in a/x into memory and return a pointer to the page in +; a/x. The contents of the currently mapped page (if any) may be discarded +; by the driver. +; + +MAP: sta curpage ; Remember the new page + + clc + adc #>BASE + sta ptr1+1 + ldy #$00 + sty ptr1 + + lda #<window + sta ptr2 + lda #>window + sta ptr2+1 + +; Transfer one page + + jsr transfer ; Transfer one page + +; Return the memory window + + lda #<window + ldx #>window ; Return the window address + rts + +; ------------------------------------------------------------------------ +; USE: Tell the driver that the window is now associated with a given page. + +USE: sta curpage ; Remember the page + lda #<window + ldx #>window ; Return the window + rts + +; ------------------------------------------------------------------------ +; COMMIT: Commit changes in the memory window to extended storage. + +COMMIT: lda curpage ; Get the current page + bmi done ; Jump if no page mapped + + clc + adc #>BASE + sta ptr2+1 + ldy #$00 + sty ptr2 + + lda #<window + sta ptr1 + lda #>window + sta ptr1+1 + +; Transfer one page. Y must be zero on entry + +transfer: + +; Unroll the following loop + +loop: .repeat 8 + lda (ptr1),y + sta (ptr2),y + iny + .endrepeat + + bne loop + +; Done + +done: rts + +; ------------------------------------------------------------------------ +; COPYFROM: Copy from extended into linear memory. A pointer to a structure +; describing the request is passed in a/x. +; The function must not return anything. +; + +COPYFROM: + sta ptr3 + stx ptr3+1 ; Save the passed em_copy pointer + + ldy #EM_COPY::OFFS + lda (ptr3),y + sta ptr1 + ldy #EM_COPY::PAGE + lda (ptr3),y + clc + adc #>BASE + sta ptr1+1 ; From + + ldy #EM_COPY::BUF + lda (ptr3),y + sta ptr2 + iny + lda (ptr3),y + sta ptr2+1 ; To + +common: ldy #EM_COPY::COUNT+1 + lda (ptr3),y ; Get number of pages + beq @L2 ; Skip if no full pages + sta tmp1 + +; Copy full pages allowing interrupts after each page copied + + ldy #$00 +@L1: jsr transfer + inc ptr1+1 + inc ptr2+1 + dec tmp1 + bne @L1 + +; Copy the remainder of the page + +@L2: ldy #EM_COPY::COUNT + lda (ptr3),y ; Get bytes in last page + beq @L4 + tax + +; Transfer the bytes in the last page + + ldy #$00 +@L3: lda (ptr1),y + sta (ptr2),y + iny + dex + bne @L3 + +; Done + +@L4: rts + +; ------------------------------------------------------------------------ +; COPYTO: Copy from linear into extended memory. A pointer to a structure +; describing the request is passed in a/x. +; The function must not return anything. +; + +COPYTO: sta ptr3 + stx ptr3+1 ; Save the passed em_copy pointer + + ldy #EM_COPY::OFFS + lda (ptr3),y + sta ptr2 + ldy #EM_COPY::PAGE + lda (ptr3),y + clc + adc #>BASE + sta ptr2+1 ; To + + ldy #EM_COPY::BUF + lda (ptr3),y + sta ptr1 + iny + lda (ptr3),y + sta ptr1+1 ; From + + jmp common + diff --git a/libsrc/vic20/libref.s b/libsrc/vic20/libref.s index e4afa7eb1..468c540f1 100644 --- a/libsrc/vic20/libref.s +++ b/libsrc/vic20/libref.s @@ -3,6 +3,8 @@ ; .export joy_libref + .export em_libref .import _exit joy_libref := _exit +em_libref := _exit From 12f72a5ed70ec45d5e037089a4eea6d08d037dee Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Sat, 17 Mar 2018 09:25:42 -0700 Subject: [PATCH 0629/2161] Added vic20 emd documentation. --- doc/vic20.sgml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/vic20.sgml b/doc/vic20.sgml index 26a4aa558..9f96cd388 100644 --- a/doc/vic20.sgml +++ b/doc/vic20.sgml @@ -147,7 +147,9 @@ No graphics drivers are currently available for the VIC20. <sect1>Extended memory drivers<p> -No extended memory drivers are currently available for the VIC20. + <tag><tt/vic20-rama.emd (vic20_rama_emd)/</tag> + A driver for any RAM at $A000-$BFFF. Supports 32 256 byte pages. + Written and contributed by Marco van den Heuvel. <sect1>Joystick drivers<p> From 4fdc2d7209612ffe94df4c4bf5acca52122e6fbe Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Sun, 18 Mar 2018 12:06:43 -0700 Subject: [PATCH 0630/2161] Fix documentation building issue. --- doc/vic20.sgml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/vic20.sgml b/doc/vic20.sgml index 9f96cd388..13f2a5cc8 100644 --- a/doc/vic20.sgml +++ b/doc/vic20.sgml @@ -147,10 +147,14 @@ No graphics drivers are currently available for the VIC20. <sect1>Extended memory drivers<p> +<descrip> + <tag><tt/vic20-rama.emd (vic20_rama_emd)/</tag> A driver for any RAM at $A000-$BFFF. Supports 32 256 byte pages. Written and contributed by Marco van den Heuvel. +</descrip><p> + <sect1>Joystick drivers<p> From 2533cc8d751400daea6cfd4b694b2c5a76cd6cd7 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Mon, 19 Mar 2018 11:34:41 -0700 Subject: [PATCH 0631/2161] Added the vic20 georam emd. --- doc/vic20.sgml | 6 + include/vic20.h | 1 + libsrc/vic20/emd/vic20-georam.s | 352 ++++++++++++++++++++++++++++++++ 3 files changed, 359 insertions(+) create mode 100755 libsrc/vic20/emd/vic20-georam.s diff --git a/doc/vic20.sgml b/doc/vic20.sgml index 13f2a5cc8..1a8f9dfef 100644 --- a/doc/vic20.sgml +++ b/doc/vic20.sgml @@ -153,6 +153,12 @@ No graphics drivers are currently available for the VIC20. A driver for any RAM at $A000-$BFFF. Supports 32 256 byte pages. Written and contributed by Marco van den Heuvel. + <tag><tt/vic20-georam.emd (vic20_georam_emd)/</tag> + A driver for the Berkeley Softworks GeoRam cartridge connected by means of + the MasC=erade c64 cartridge adapter. The driver will determine the + available RAM from the connected cartridge. It supports 64KB + up to 2048KB of RAM. + </descrip><p> diff --git a/include/vic20.h b/include/vic20.h index 1e8c4ceb5..44512b3fd 100644 --- a/include/vic20.h +++ b/include/vic20.h @@ -106,6 +106,7 @@ extern void vic20_ptvjoy_joy[]; extern void vic20_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ extern void vic20_rama_emd[]; +extern void vic20_georam_emd[]; /* End of vic20.h */ #endif diff --git a/libsrc/vic20/emd/vic20-georam.s b/libsrc/vic20/emd/vic20-georam.s new file mode 100755 index 000000000..a960e9a1a --- /dev/null +++ b/libsrc/vic20/emd/vic20-georam.s @@ -0,0 +1,352 @@ +; +; Extended memory driver for the GEORAM cartridge through the masC=erade +; c64 cartridge adapter. Driver works without problems when statically +; linked. +; +; Marco van den Heuvel, 2018-03-18 +; + + .include "zeropage.inc" + + .include "em-kernel.inc" + .include "em-error.inc" + + + .macpack generic + .macpack module + + +; ------------------------------------------------------------------------ +; Header. Includes jump table + + module_header _vic20_georam_emd + +; Driver signature + + .byte $65, $6d, $64 ; "emd" + .byte EMD_API_VERSION ; EM API version number + +; Library reference + + .addr $0000 + +; Jump table + + .addr INSTALL + .addr UNINSTALL + .addr PAGECOUNT + .addr MAP + .addr USE + .addr COMMIT + .addr COPYFROM + .addr COPYTO + +; ------------------------------------------------------------------------ +; Constants + +GR_WINDOW = $9800 ; Address of GEORAM window +GR_PAGE_LO = $9CFE ; Page register low +GR_PAGE_HI = $9CFF ; Page register high + +; ------------------------------------------------------------------------ +; Data. + +.data + +pagecount: .res 2 ; Number of available pages + +.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 EM_ERR_xx code in a/x. +; + +INSTALL: + ldx GR_WINDOW + cpx GR_WINDOW + bne @notpresent + inc GR_WINDOW + cpx GR_WINDOW + beq @notpresent + + lda #4 + jsr check + cpy GR_WINDOW + beq @has64k + lda #8 + jsr check + cpy GR_WINDOW + beq @has128k + lda #16 + jsr check + cpy GR_WINDOW + beq @has256k + lda #32 + jsr check + cpy GR_WINDOW + beq @has512k + lda #64 + jsr check + cpy GR_WINDOW + beq @has1024k + lda #128 + jsr check + cpy GR_WINDOW + beq @has2048k + ldx #>16384 + bne @setok + +@has64k: + ldx #>256 + bne @setok +@has128k: + ldx #>512 + bne @setok +@has256k: + ldx #>1024 + bne @setok +@has512k: + ldx #>2048 + bne @setok +@has1024k: + ldx #>4096 + bne @setok +@has2048k: + ldx #>8192 + bne @setok + +@notpresent: + lda #<EM_ERR_NO_DEVICE + ldx #>EM_ERR_NO_DEVICE + rts + +@setok: + lda #0 + sta pagecount + stx pagecount+1 + lda #<EM_ERR_OK + ldx #>EM_ERR_OK + rts + +check: + ldx #0 + stx GR_PAGE_LO + stx GR_PAGE_HI + ldy GR_WINDOW + iny + sta GR_PAGE_HI + sty GR_WINDOW + ldx #0 + stx GR_PAGE_HI +; 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 + + +; ------------------------------------------------------------------------ +; PAGECOUNT: Return the total number of available pages in a/x. +; + +PAGECOUNT: + lda pagecount + ldx pagecount+1 + rts + +; ------------------------------------------------------------------------ +; USE: Tell the driver that the window is now associated with a given page. +; The GeoRAM cartridge does not copy but actually map the window, so USE is +; identical to MAP. + +USE = MAP + +; ------------------------------------------------------------------------ +; MAP: Map the page in a/x into memory and return a pointer to the page in +; a/x. The contents of the currently mapped page (if any) may be discarded +; by the driver. +; + +MAP: sta tmp1 + txa + asl tmp1 + rol a + asl tmp1 + rol a + + sta GR_PAGE_HI + lda tmp1 + lsr a + lsr a + sta GR_PAGE_LO + + lda #<GR_WINDOW + ldx #>GR_WINDOW + +; Use the RTS from COMMIT below to save a precious byte of storage + +; ------------------------------------------------------------------------ +; COMMIT: Commit changes in the memory window to extended storage. + +COMMIT: rts + +; ------------------------------------------------------------------------ +; COPYFROM: Copy from extended into linear memory. A pointer to a structure +; describing the request is passed in a/x. +; The function must not return anything. +; + +COPYFROM: + jsr setup + +; Setup is: +; +; - ptr1 contains the struct pointer +; - ptr2 contains the linear memory buffer +; - ptr3 contains -(count-1) +; - tmp1 contains the low page register value +; - tmp2 contains the high page register value +; - X contains the page offset +; - Y contains zero + + jmp @L5 + +@L1: lda GR_WINDOW,x + sta (ptr2),y + iny + bne @L2 + inc ptr2+1 +@L2: inx + beq @L4 + +; Bump count and repeat + +@L3: inc ptr3 + bne @L1 + inc ptr3+1 + bne @L1 + rts + +; Bump page register + +@L4: inc tmp1 ; Bump low page register + bit tmp1 ; Check for overflow in bit 6 + bvc @L6 ; Jump if no overflow + inc tmp2 +@L5: lda tmp2 + sta GR_PAGE_HI +@L6: lda tmp1 + sta GR_PAGE_LO + jmp @L3 + +; ------------------------------------------------------------------------ +; COPYTO: Copy from linear into extended memory. A pointer to a structure +; describing the request is passed in a/x. +; The function must not return anything. +; + +COPYTO: + jsr setup + +; Setup is: +; +; - ptr1 contains the struct pointer +; - ptr2 contains the linear memory buffer +; - ptr3 contains -(count-1) +; - tmp1 contains the low page register value +; - tmp2 contains the high page register value +; - X contains the page offset +; - Y contains zero + + jmp @L5 + +@L1: lda (ptr2),y + sta GR_WINDOW,x + iny + bne @L2 + inc ptr2+1 +@L2: inx + beq @L4 + +; Bump count and repeat + +@L3: inc ptr3 + bne @L1 + inc ptr3+1 + bne @L1 + rts + +; Bump page register + +@L4: inc tmp1 ; Bump low page register + bit tmp1 ; Check for overflow in bit 6 + bvc @L6 ; Jump if no overflow + inc tmp2 +@L5: lda tmp2 + sta GR_PAGE_HI +@L6: lda tmp1 + sta GR_PAGE_LO + jmp @L3 + +; ------------------------------------------------------------------------ +; Helper function for COPYFROM and COPYTO: Store the pointer to the request +; structure and prepare data for the copy + +setup: sta ptr1 + stx ptr1+1 ; Save passed pointer + +; Get the page number from the struct and adjust it so that it may be used +; with the hardware. That is: lower 6 bits in tmp1, high bits in tmp2. + + ldy #EM_COPY::PAGE+1 + lda (ptr1),y + sta tmp2 + dey + lda (ptr1),y + asl a + rol tmp2 + asl a + rol tmp2 + lsr a + lsr a + sta tmp1 + +; Get the buffer pointer into ptr2 + + ldy #EM_COPY::BUF + lda (ptr1),y + sta ptr2 + iny + lda (ptr1),y + sta ptr2+1 + +; Get the count, calculate -(count-1) and store it into ptr3 + + ldy #EM_COPY::COUNT + lda (ptr1),y + eor #$FF + sta ptr3 + iny + lda (ptr1),y + eor #$FF + sta ptr3+1 + +; Get the page offset into X and clear Y + + ldy #EM_COPY::OFFS + lda (ptr1),y + tax + ldy #$00 + +; Done + + rts + + From 5d4116f05fa311fb4611a932218cb9ef073d147a Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Tue, 20 Mar 2018 13:11:24 -0700 Subject: [PATCH 0632/2161] Added isfast function which returns a 1 when the C128 is in 2MHz mode. --- doc/c128.sgml | 1 + doc/funcref.sgml | 27 +++++++++++++++++++++++++++ include/c128.h | 3 ++- libsrc/c128/isfast.s | 20 ++++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 libsrc/c128/isfast.s diff --git a/doc/c128.sgml b/doc/c128.sgml index f133d8d4c..14c874998 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -87,6 +87,7 @@ url="funcref.html" name="function reference"> for declaration and usage. <item>c64mode <item>fast <item>slow +<item>isfast </itemize> diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 235a0d40f..193a10c52 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -131,6 +131,7 @@ function. <itemize> <item><ref id="c64mode" name="c64mode"> <item><ref id="fast" name="fast"> +<item><ref id="isfast" name="isfast"> <item><ref id="slow" name="slow"> <item><ref id="toggle_videomode" name="toggle_videomode"> <item><ref id="videomode" name="videomode"> @@ -3302,6 +3303,7 @@ will nearly double the speed compared to slow mode. </itemize> <tag/Availability/C128 <tag/See also/ +<ref id="isfast" name="isfast">, <ref id="slow" name="slow">, <ref id="toggle_videomode" name="toggle_videomode">, <ref id="videomode" name="videomode"> @@ -3954,6 +3956,28 @@ fastcall function, so it may only be used in presence of a prototype. </quote> +<sect1>isfast<label id="isfast"><p> + +<quote> +<descrip> +<tag/Function/Check if the C128 is in 2MHz mode. +<tag/Header/<tt/<ref id="c128.h" name="c128.h">/ +<tag/Declaration/<tt/unsigned char isfast (void);/ +<tag/Description/The function returns a 1 if the C128 is in 2MHz mode. +<tag/Notes/<itemize> +<item>The function is specific to the C128. +</itemize> +<tag/Availability/C128 +<tag/See also/ +<ref id="fast" name="fast">, +<ref id="slow" name="slow">, +<ref id="toggle_videomode" name="toggle_videomode">, +<ref id="videomode" name="videomode"> +<tag/Example/None. +</descrip> +</quote> + + <sect1>isgraph<label id="isgraph"><p> <quote> @@ -6073,6 +6097,7 @@ will halve the speed compared to fast mode. <tag/Availability/C128 <tag/See also/ <ref id="fast" name="fast">, +<ref id="isfast" name="isfast">, <ref id="toggle_videomode" name="toggle_videomode">, <ref id="videomode" name="videomode"> <tag/Example/None. @@ -6864,6 +6889,7 @@ name="videomode"> instead! <tag/Availability/C128 <tag/See also/ <ref id="fast" name="fast">, +<ref id="isfast" name="isfast">, <ref id="slow" name="slow">, <ref id="videomode" name="videomode"> <tag/Example/None. @@ -7064,6 +7090,7 @@ used in presence of a prototype. <tag/Availability/C128 and enhanced Apple //e <tag/See also/ <ref id="fast" name="fast">, +<ref id="isfast" name="isfast">, <ref id="slow" name="slow">, <ref id="toggle_videomode" name="toggle_videomode"> <tag/Example/None. diff --git a/include/c128.h b/include/c128.h index 356140d41..99e050a9b 100644 --- a/include/c128.h +++ b/include/c128.h @@ -167,7 +167,8 @@ void fast (void); void slow (void); /* Switch the CPU into 1MHz mode. */ - +unsigned char isfast (void); +/* Returns 1 if the CPU is in 2MHz mode. */ /* End of c128.h */ #endif diff --git a/libsrc/c128/isfast.s b/libsrc/c128/isfast.s new file mode 100644 index 000000000..01b597371 --- /dev/null +++ b/libsrc/c128/isfast.s @@ -0,0 +1,20 @@ +; +; Marco van den Heuvel, 2018-03-19 +; +; unsigned char isfast (void); +; /* Returns 1 if the CPU is in 2MHz mode. */ +; + + .export _isfast + + .include "c128.inc" + + +.proc _isfast + + lda VIC_CLK_128 + and #$01 + rts + +.endproc + From d34c93a464b09109d2226fefb3bb6cf701049905 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Tue, 20 Mar 2018 14:05:55 -0700 Subject: [PATCH 0633/2161] Set X register to 0 so that 16bit promotion works as expected. --- libsrc/c128/isfast.s | 1 + 1 file changed, 1 insertion(+) diff --git a/libsrc/c128/isfast.s b/libsrc/c128/isfast.s index 01b597371..d40e2c7e9 100644 --- a/libsrc/c128/isfast.s +++ b/libsrc/c128/isfast.s @@ -14,6 +14,7 @@ lda VIC_CLK_128 and #$01 + ldx #$00 rts .endproc From 03ba3f74730e0898dabba33cff6ded1ebecb7d2c Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Fri, 23 Mar 2018 14:27:15 -0700 Subject: [PATCH 0634/2161] Added c16/plus4 fast(), isfast() and slow() functions, and updated the documentation accordingly. --- asminc/plus4.inc | 1 + doc/c128.sgml | 16 +++++++++--- doc/c16.sgml | 12 +++++++++ doc/funcref.sgml | 59 +++++++++++++++++++++++++------------------ doc/plus4.sgml | 13 ++++++++++ include/plus4.h | 8 ++++++ libsrc/plus4/fast.s | 22 ++++++++++++++++ libsrc/plus4/isfast.s | 22 ++++++++++++++++ libsrc/plus4/slow.s | 22 ++++++++++++++++ 9 files changed, 148 insertions(+), 27 deletions(-) create mode 100644 libsrc/plus4/fast.s create mode 100644 libsrc/plus4/isfast.s create mode 100644 libsrc/plus4/slow.s diff --git a/asminc/plus4.inc b/asminc/plus4.inc index 3b2f08c54..5ea4dcf88 100644 --- a/asminc/plus4.inc +++ b/asminc/plus4.inc @@ -73,6 +73,7 @@ TED_CURSLO := $FF0D TED_V1FRQLO := $FF0E TED_V2FRQLO := $FF0F TED_V2FRQHI := $FF10 +TED_CLK := $FF13 TED_BGCOLOR := $FF15 TED_COLOR1 := $FF16 TED_COLOR2 := $FF17 diff --git a/doc/c128.sgml b/doc/c128.sgml index 14c874998..2bfb37a3d 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -85,9 +85,6 @@ url="funcref.html" name="function reference"> for declaration and usage. <itemize> <item>videomode <item>c64mode -<item>fast -<item>slow -<item>isfast </itemize> @@ -123,6 +120,19 @@ declaration and usage. </itemize> +<sect1>CBM specific CPU functions<p> + +Some CPU related functions are available for some of the Commodore +machines. See the <url url="funcref.html" name="function reference"> for +declaration and usage. + +<itemize> +<item>fast +<item>slow +<item>isfast +</itemize> + + <sect1>Hardware access<p> The following pseudo variables declared in the <tt/c128.h/ header file do diff --git a/doc/c16.sgml b/doc/c16.sgml index 1614516b7..27938ff1e 100644 --- a/doc/c16.sgml +++ b/doc/c16.sgml @@ -126,6 +126,18 @@ declaration and usage. </itemize> +<sect1>CBM specific CPU functions<p> + +Some CPU related functions are available for some of the Commodore +machines. See the <url url="funcref.html" name="function reference"> for +declaration and usage. + +<itemize> +<item>fast +<item>slow +<item>isfast +</itemize> + <sect1>Hardware access<p> The following pseudo variables declared in the <tt/c16.h/ header file do diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 193a10c52..5f90cfd3e 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -140,6 +140,12 @@ function. <sect1><tt/c16.h/<label id="c16.h"><p> +<itemize> +<item><ref id="fast" name="fast"> +<item><ref id="isfast" name="isfast"> +<item><ref id="slow" name="slow"> +</itemize> + (incomplete) @@ -502,6 +508,12 @@ It does not declare any functions. <sect1><tt/plus4.h/<label id="plus4.h"><p> +<itemize> +<item><ref id="fast" name="fast"> +<item><ref id="isfast" name="isfast"> +<item><ref id="slow" name="slow"> +</itemize> + (incomplete) @@ -3292,21 +3304,21 @@ program, it may not be able to read it. <quote> <descrip> -<tag/Function/Switch the C128 into 2MHz mode. -<tag/Header/<tt/<ref id="c128.h" name="c128.h">/ +<tag/Function/Switch the CPU into fast mode (C128: 2MHz mode, C16/Plus4: double clock mode). +<tag/Header/<tt/<ref id="c128.h" name="c128.h">, +<ref id="c16.h" name="c16.h">, <ref id="plus4.h" name="plus4.h">/ <tag/Declaration/<tt/void fast (void);/ -<tag/Description/The function will switch the clock of the C128 to 2MHz. This -will nearly double the speed compared to slow mode. +<tag/Description/The function will switch the clock of the CPU to fast mode. For the C128 +target it means switching the CPU into 2MHz mode. For the C16/Plus4 target it means +switching the CPU into double clock mode. <tag/Notes/<itemize> -<item>The function is specific to the C128. -<item>2MHz clock will not work in 40 column mode. +<item>The function is specific to the C128, C16 and Plus4. +<item>On the C128 the 2MHz clock will not work in 40 column mode. </itemize> -<tag/Availability/C128 +<tag/Availability/cc65 (not all platforms) <tag/See also/ <ref id="isfast" name="isfast">, <ref id="slow" name="slow">, -<ref id="toggle_videomode" name="toggle_videomode">, -<ref id="videomode" name="videomode"> <tag/Example/None. </descrip> </quote> @@ -3960,19 +3972,18 @@ fastcall function, so it may only be used in presence of a prototype. <quote> <descrip> -<tag/Function/Check if the C128 is in 2MHz mode. -<tag/Header/<tt/<ref id="c128.h" name="c128.h">/ +<tag/Function/Check if the CPU is in fast mode (C128: 2MHz mode, C16/Plus4: double clock mode). +<tag/Header/<tt/<ref id="c128.h" name="c128.h">, +<ref id="c16.h" name="c16.h">, <ref id="plus4.h" name="plus4.h">/ <tag/Declaration/<tt/unsigned char isfast (void);/ -<tag/Description/The function returns a 1 if the C128 is in 2MHz mode. +<tag/Description/The function returns a 1 if the CPU is in fast mode (C128: 2MHz mode, C16/Plus4: double clock mode). <tag/Notes/<itemize> -<item>The function is specific to the C128. +<item>The function is specific to the C128, C16 and Plus4. </itemize> -<tag/Availability/C128 +<tag/Availability/cc65 (not all platforms) <tag/See also/ <ref id="fast" name="fast">, <ref id="slow" name="slow">, -<ref id="toggle_videomode" name="toggle_videomode">, -<ref id="videomode" name="videomode"> <tag/Example/None. </descrip> </quote> @@ -6086,20 +6097,20 @@ be used in presence of a prototype. <quote> <descrip> -<tag/Function/Switch the C128 into 1MHz mode. -<tag/Header/<tt/<ref id="c128.h" name="c128.h">/ +<tag/Function/Switch the CPU into slow mode (C128: 1MHz mode, C16/Plus4: single clock mode). +<tag/Header/<tt/<ref id="c128.h" name="c128.h">, +<ref id="c16.h" name="c16.h">, <ref id="plus4.h" name="plus4.h">/ <tag/Declaration/<tt/void slow (void);/ -<tag/Description/The function will switch the clock of the C128 to 1MHz. This -will halve the speed compared to fast mode. +<tag/Description/The function will switch the clock of the CPU to slow mode. for the C128 +target it means switching the CPU into 1MHz mode. for the C16/Plus4 target it means +switching the CPU into single clock mode. <tag/Notes/<itemize> -<item>The function is specific to the C128. +<item>The function is specific to the C128, C16 and Plus4. </itemize> -<tag/Availability/C128 +<tag/Availability/cc65 (not all platforms) <tag/See also/ <ref id="fast" name="fast">, <ref id="isfast" name="isfast">, -<ref id="toggle_videomode" name="toggle_videomode">, -<ref id="videomode" name="videomode"> <tag/Example/None. </descrip> </quote> diff --git a/doc/plus4.sgml b/doc/plus4.sgml index 36d53e753..c1b6165f6 100644 --- a/doc/plus4.sgml +++ b/doc/plus4.sgml @@ -124,6 +124,19 @@ declaration and usage. </itemize> +<sect1>CBM specific CPU functions<p> + +Some CPU related functions are available for some of the Commodore +machines. See the <url url="funcref.html" name="function reference"> for +declaration and usage. + +<itemize> +<item>fast +<item>slow +<item>isfast +</itemize> + + <sect1>Hardware access<p> The following pseudo variables declared in the <tt/plus4.h/ header file do diff --git a/include/plus4.h b/include/plus4.h index 81e3c5286..6edb947e5 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -59,6 +59,14 @@ extern void plus4_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ extern void plus4_stdser_ser[]; +void fast (void); +/* Switch the CPU into double clock mode. */ + +void slow (void); +/* Switch the CPU into single clock mode. */ + +unsigned char isfast (void); +/* Returns 1 if the CPU is in double clock mode. */ /* End of plus4.h */ diff --git a/libsrc/plus4/fast.s b/libsrc/plus4/fast.s new file mode 100644 index 000000000..e48813969 --- /dev/null +++ b/libsrc/plus4/fast.s @@ -0,0 +1,22 @@ +; +; Marco van den Heuvel, 2018-03-20 +; +; void fast (void); +; /* Switch the CPU into double clock mode. */ +; + + .export _fast + + .include "plus4.inc" + + +.proc _fast + + lda TED_CLK + and #%11111101 + sta TED_CLK + rts + +.endproc + + diff --git a/libsrc/plus4/isfast.s b/libsrc/plus4/isfast.s new file mode 100644 index 000000000..ff104d97f --- /dev/null +++ b/libsrc/plus4/isfast.s @@ -0,0 +1,22 @@ +; +; Marco van den Heuvel, 2018-03-20 +; +; unsigned char isfast (void); +; /* Returns 1 if the CPU is in double clock mode. */ +; + + .export _isfast + + .include "plus4.inc" + + +.proc _isfast + + lda TED_CLK + lsr + and #$01 + ldx #$00 + rts + +.endproc + diff --git a/libsrc/plus4/slow.s b/libsrc/plus4/slow.s new file mode 100644 index 000000000..18b8c231c --- /dev/null +++ b/libsrc/plus4/slow.s @@ -0,0 +1,22 @@ +; +; Marco van den Heuvel, 2018-03-28 +; +; void slow (void); +; /* Switch the CPU into single clock mode. */ +; + + .export _slow + + .include "plus4.inc" + + +.proc _slow + + lda TED_CLK + ora #%00000010 + sta TED_CLK + rts + +.endproc + + From 8424286a3ea42dfc53b1f1d30c1af3e229b18301 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Fri, 23 Mar 2018 14:31:53 -0700 Subject: [PATCH 0635/2161] Add c16 files as well. --- libsrc/c16/fast.s | 22 ++++++++++++++++++++++ libsrc/c16/isfast.s | 22 ++++++++++++++++++++++ libsrc/c16/slow.s | 22 ++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 libsrc/c16/fast.s create mode 100644 libsrc/c16/isfast.s create mode 100644 libsrc/c16/slow.s diff --git a/libsrc/c16/fast.s b/libsrc/c16/fast.s new file mode 100644 index 000000000..e48813969 --- /dev/null +++ b/libsrc/c16/fast.s @@ -0,0 +1,22 @@ +; +; Marco van den Heuvel, 2018-03-20 +; +; void fast (void); +; /* Switch the CPU into double clock mode. */ +; + + .export _fast + + .include "plus4.inc" + + +.proc _fast + + lda TED_CLK + and #%11111101 + sta TED_CLK + rts + +.endproc + + diff --git a/libsrc/c16/isfast.s b/libsrc/c16/isfast.s new file mode 100644 index 000000000..ff104d97f --- /dev/null +++ b/libsrc/c16/isfast.s @@ -0,0 +1,22 @@ +; +; Marco van den Heuvel, 2018-03-20 +; +; unsigned char isfast (void); +; /* Returns 1 if the CPU is in double clock mode. */ +; + + .export _isfast + + .include "plus4.inc" + + +.proc _isfast + + lda TED_CLK + lsr + and #$01 + ldx #$00 + rts + +.endproc + diff --git a/libsrc/c16/slow.s b/libsrc/c16/slow.s new file mode 100644 index 000000000..18b8c231c --- /dev/null +++ b/libsrc/c16/slow.s @@ -0,0 +1,22 @@ +; +; Marco van den Heuvel, 2018-03-28 +; +; void slow (void); +; /* Switch the CPU into single clock mode. */ +; + + .export _slow + + .include "plus4.inc" + + +.proc _slow + + lda TED_CLK + ora #%00000010 + sta TED_CLK + rts + +.endproc + + From 155f3ade4140fd471ec6dfa77ec8c1cedce3785c Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 26 Mar 2018 07:24:37 -0400 Subject: [PATCH 0636/2161] C64 TGI: LINE: Optimization: Don't check boundaries; LINE always is called by tgi_clippedline(). Submitted in Pull Request #611 by Sven Michael Klose. --- libsrc/c64/tgi/c64-hi.s | 125 ++++++++-------------------------------- 1 file changed, 24 insertions(+), 101 deletions(-) diff --git a/libsrc/c64/tgi/c64-hi.s b/libsrc/c64/tgi/c64-hi.s index 8368c6ba2..aeb334404 100644 --- a/libsrc/c64/tgi/c64-hi.s +++ b/libsrc/c64/tgi/c64-hi.s @@ -4,6 +4,7 @@ ; Based on Stephen L. Judd's GRLIB code. ; ; 2017-01-13, Greg King +; 2018-03-13, Sven Klose ; .include "zeropage.inc" @@ -70,12 +71,9 @@ X2 := ptr3 Y2 := ptr4 TEXT := ptr3 -ROW := tmp2 ; Bitmap row... -COL := tmp3 ; ...and column, both set by PLOT TEMP := tmp4 TEMP2 := sreg POINT := regsave -INRANGE := regsave+2 ; PLOT variable, $00 = coordinates in range CHUNK := X2 ; Used in the line routine OLDCHUNK := X2+1 ; Dito @@ -454,11 +452,6 @@ GETPIXEL: ; 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. ; -; To deal with off-screen coordinates, the current row -; and column (40x25) is kept track of. These are set -; negative when the point is off the screen, and made -; positive when the point is within the visible screen. -; ; X1,X2 etc. are set up above (x2=LINNUM in particular) ; Format is LINE x2,y2,x1,y1 ; @@ -513,7 +506,7 @@ LINE: stx YINCDEC stx XINCDEC - jsr CALC ; Set up .X,.Y,POINT, and INRANGE + jsr CALC ; Set up .X, .Y, and POINT lda BITCHUNK,X sta OLDCHUNK sta CHUNK @@ -556,15 +549,11 @@ STEPINY: ; YLOOP: sta TEMP - lda INRANGE ;Range check - bne @SKIP - - lda (POINT),y ;Otherwise plot + lda (POINT),y eor BITMASK and CHUNK eor (POINT),y sta (POINT),y -@SKIP: YINCDEC: iny ;Advance Y coordinate cpy #8 @@ -581,7 +570,7 @@ YCONT2: lda (POINT),y ;Plot endpoint and CHUNK eor (POINT),y sta (POINT),y -YDONE: lda #$36 + lda #$36 sta $01 cli rts @@ -592,23 +581,12 @@ YFIXX: ;x=x+1 bne YCONT ;If we pass a column boundary... ror CHUNK ;then reset CHUNK to $80 sta TEMP2 - lda COL - bmi @C1 ;Skip if column is negative - cmp #39 ;End if move past end of screen - bcs YDONE -@C1: lda POINT ;And add 8 to POINT + lda POINT ;And add 8 to POINT adc #8 sta POINT bcc @CONT inc POINT+1 -@CONT: inc COL ;Increment column - bne @C2 - lda ROW ;Range check - cmp #25 - bcs @C2 - lda #00 ;Passed into col 0 - sta INRANGE -@C2: lda TEMP2 +@CONT: lda TEMP2 dex bne YLOOP beq YCONT2 @@ -647,7 +625,7 @@ XCONT2: dex dec COUNTHI ;High bits set? bpl XLOOP -XDONE: lsr CHUNK ;Advance to last point + lsr CHUNK ;Advance to last point jsr LINEPLOT ;Plot the last chunk EXIT: lda #$36 sta $01 @@ -662,25 +640,14 @@ XFIXC: sta TEMP lda #$FF sta CHUNK sta OLDCHUNK - lda COL - bmi @C1 ;Skip if column is negative - cmp #39 ;End if move past end of screen - bcs EXIT -@C1: lda POINT + lda POINT + clc adc #8 sta POINT - bcc @CONT + lda TEMP + bcc XCONT1 inc POINT+1 -@CONT: inc COL - bne @C2 - lda ROW - cmp #25 - bcs @C2 - lda #00 - sta INRANGE -@C2: lda TEMP - sec - bcs XCONT1 + jmp XCONT1 ; ; Check to make sure there isn't a high bit, plot chunk, ; and update Y-coordinate. @@ -712,17 +679,14 @@ XINCDEC: ; room, gray hair, etc.) ; LINEPLOT: ; Plot the line chunk - lda INRANGE - bne @SKIP - - lda (POINT),Y ; Otherwise plot + lda (POINT),Y eor BITMASK ora CHUNK and OLDCHUNK eor CHUNK eor (POINT),Y sta (POINT),Y -@SKIP: rts + rts ; ; Subroutine to fix up pointer when Y decreases through @@ -730,23 +694,16 @@ LINEPLOT: ; Plot the line chunk ; FIXY: cpy #255 ;Y=255 or Y=8 beq @DECPTR + @INCPTR: ;Add 320 to pointer ldy #0 ;Y increased through 7 - lda ROW - bmi @C1 ;If negative, then don't update - cmp #24 - bcs @TOAST ;If at bottom of screen then quit -@C1: lda POINT + lda POINT adc #<320 sta POINT lda POINT+1 adc #>320 sta POINT+1 -@CONT1: inc ROW - bne @DONE - lda COL - bpl @CLEAR -@DONE: rts + rts @DECPTR: ;Okay, subtract 320 then ldy #7 ;Y decreased through 0 @@ -757,21 +714,8 @@ FIXY: cpy #255 ;Y=255 or Y=8 lda POINT+1 sbc #>320 sta POINT+1 -@CONT2: dec ROW - bmi @TOAST - lda ROW - cmp #24 - bne @DONE - lda COL - bmi @DONE -@CLEAR: lda #00 - sta INRANGE rts -@TOAST: pla ;Remove old return address - pla - jmp EXIT ;Restore interrupts, etc. - ; ------------------------------------------------------------------------ ; 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. @@ -896,48 +840,36 @@ OUTTEXT: rts ; ------------------------------------------------------------------------ -; Calculate all variables to plot the pixel at X1/Y1. If the point is out -; of range, a carry is returned and INRANGE is set to a value !0 zero. If -; the coordinates are valid, INRANGE is zero and the carry clear. +; Calculate all variables to plot the pixel at X1/Y1. CALC: lda Y1 - sta ROW + sta TEMP2 and #7 tay lda Y1+1 lsr ; Neg is possible - ror ROW + ror TEMP2 lsr - ror ROW + ror TEMP2 lsr - ror ROW + ror TEMP2 lda #00 sta POINT - lda ROW + lda TEMP2 cmp #$80 ror ror POINT cmp #$80 ror ror POINT ; row*64 - adc ROW ; +row*256 + adc TEMP2 ; +row*256 clc adc #>VBASE ; +bitmap base sta POINT+1 lda X1 tax - sta COL - lda X1+1 - lsr - ror COL - lsr - ror COL - lsr - ror COL - - txa and #$F8 clc adc POINT ; +(X AND #$F8) @@ -948,13 +880,4 @@ CALC: lda Y1 txa and #7 tax - - lda ROW - cmp #25 - bcs @L9 - lda COL - cmp #40 - bcs @L9 - lda #00 -@L9: sta INRANGE rts From b8445721595f70f9011f9b4a381a2fc2233b9cba Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 27 Mar 2018 07:13:14 -0400 Subject: [PATCH 0637/2161] Moved most of the tgi_colors.s files into the libsrc/common/ directory. Only the Apple2 and Lynx platforms use different codes for the white color; they have their own files. --- libsrc/atmos/tgi_colors.s | 8 -------- libsrc/c128/tgi_colors.s | 8 -------- libsrc/c64/tgi_colors.s | 8 -------- libsrc/{atari => common}/tgi_colors.s | 0 libsrc/geos-common/system/tgi_colors.s | 8 -------- libsrc/nes/tgi_colors.s | 8 -------- libsrc/telestrat/tgi_colors.s | 8 -------- 7 files changed, 48 deletions(-) delete mode 100644 libsrc/atmos/tgi_colors.s delete mode 100644 libsrc/c128/tgi_colors.s delete mode 100644 libsrc/c64/tgi_colors.s rename libsrc/{atari => common}/tgi_colors.s (100%) delete mode 100644 libsrc/geos-common/system/tgi_colors.s delete mode 100644 libsrc/nes/tgi_colors.s delete mode 100644 libsrc/telestrat/tgi_colors.s diff --git a/libsrc/atmos/tgi_colors.s b/libsrc/atmos/tgi_colors.s deleted file mode 100644 index 6ef3729b4..000000000 --- a/libsrc/atmos/tgi_colors.s +++ /dev/null @@ -1,8 +0,0 @@ -; -; Target-specific black & white values for use by the target-shared TGI kernel -; - - .include "tgi-kernel.inc" - - .export tgi_color_black:zp = $00 - .export tgi_color_white:zp = $01 diff --git a/libsrc/c128/tgi_colors.s b/libsrc/c128/tgi_colors.s deleted file mode 100644 index 6ef3729b4..000000000 --- a/libsrc/c128/tgi_colors.s +++ /dev/null @@ -1,8 +0,0 @@ -; -; Target-specific black & white values for use by the target-shared TGI kernel -; - - .include "tgi-kernel.inc" - - .export tgi_color_black:zp = $00 - .export tgi_color_white:zp = $01 diff --git a/libsrc/c64/tgi_colors.s b/libsrc/c64/tgi_colors.s deleted file mode 100644 index 6ef3729b4..000000000 --- a/libsrc/c64/tgi_colors.s +++ /dev/null @@ -1,8 +0,0 @@ -; -; Target-specific black & white values for use by the target-shared TGI kernel -; - - .include "tgi-kernel.inc" - - .export tgi_color_black:zp = $00 - .export tgi_color_white:zp = $01 diff --git a/libsrc/atari/tgi_colors.s b/libsrc/common/tgi_colors.s similarity index 100% rename from libsrc/atari/tgi_colors.s rename to libsrc/common/tgi_colors.s diff --git a/libsrc/geos-common/system/tgi_colors.s b/libsrc/geos-common/system/tgi_colors.s deleted file mode 100644 index 0d404294c..000000000 --- a/libsrc/geos-common/system/tgi_colors.s +++ /dev/null @@ -1,8 +0,0 @@ -; -; Target-specific black & white values, for use by the target-shared TGI kernel -; - - .include "tgi-kernel.inc" - -tgi_color_black = $00 -tgi_color_white = $01 diff --git a/libsrc/nes/tgi_colors.s b/libsrc/nes/tgi_colors.s deleted file mode 100644 index 6ef3729b4..000000000 --- a/libsrc/nes/tgi_colors.s +++ /dev/null @@ -1,8 +0,0 @@ -; -; Target-specific black & white values for use by the target-shared TGI kernel -; - - .include "tgi-kernel.inc" - - .export tgi_color_black:zp = $00 - .export tgi_color_white:zp = $01 diff --git a/libsrc/telestrat/tgi_colors.s b/libsrc/telestrat/tgi_colors.s deleted file mode 100644 index 6ef3729b4..000000000 --- a/libsrc/telestrat/tgi_colors.s +++ /dev/null @@ -1,8 +0,0 @@ -; -; Target-specific black & white values for use by the target-shared TGI kernel -; - - .include "tgi-kernel.inc" - - .export tgi_color_black:zp = $00 - .export tgi_color_white:zp = $01 From a2a486882585b0e2c3c4ecbc5ea19afda015289f Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 30 Mar 2018 00:07:56 +0200 Subject: [PATCH 0638/2161] Added HGR and DHGR slide show programs. The DHGR program is sort of a hack as it first switches to double (aka 80 col) text mode to prepare for double graphics mode. Therefore only one additional soft switch access is necessary after using TGI to generally switch to hires. --- testcode/lib/apple2/Makefile | 35 ++++++++++++-- testcode/lib/apple2/astronaut.hgr | Bin 0 -> 8184 bytes testcode/lib/apple2/catface.dhgr | Bin 0 -> 16384 bytes testcode/lib/apple2/chips.hgr | Bin 0 -> 8184 bytes testcode/lib/apple2/dhgrshow.c | 45 ++++++++++++++++++ testcode/lib/apple2/gatsby.dhgr | Bin 0 -> 16384 bytes testcode/lib/apple2/girl.dhgr | Bin 0 -> 16384 bytes testcode/lib/apple2/hgrshow.c | 37 ++++++++++++++ testcode/lib/apple2/macrometer.hgr | Bin 0 -> 8184 bytes testcode/lib/apple2/mariner.hgr | Bin 0 -> 8184 bytes testcode/lib/apple2/monarch.dhgr | Bin 0 -> 16384 bytes testcode/lib/apple2/rose.hgr | Bin 0 -> 8184 bytes testcode/lib/apple2/superman.dhgr | Bin 0 -> 16384 bytes testcode/lib/apple2/venice.dhgr | Bin 0 -> 16384 bytes .../lib/apple2/{werner.pic => werner.hgr} | Bin testcode/lib/apple2/werner.s | 2 +- testcode/lib/apple2/winston.hgr | Bin 0 -> 8184 bytes 17 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 testcode/lib/apple2/astronaut.hgr create mode 100644 testcode/lib/apple2/catface.dhgr create mode 100644 testcode/lib/apple2/chips.hgr create mode 100644 testcode/lib/apple2/dhgrshow.c create mode 100644 testcode/lib/apple2/gatsby.dhgr create mode 100644 testcode/lib/apple2/girl.dhgr create mode 100644 testcode/lib/apple2/hgrshow.c create mode 100644 testcode/lib/apple2/macrometer.hgr create mode 100644 testcode/lib/apple2/mariner.hgr create mode 100644 testcode/lib/apple2/monarch.dhgr create mode 100644 testcode/lib/apple2/rose.hgr create mode 100644 testcode/lib/apple2/superman.dhgr create mode 100644 testcode/lib/apple2/venice.dhgr rename testcode/lib/apple2/{werner.pic => werner.hgr} (100%) create mode 100644 testcode/lib/apple2/winston.hgr diff --git a/testcode/lib/apple2/Makefile b/testcode/lib/apple2/Makefile index 87dadcbe7..9d551aa62 100644 --- a/testcode/lib/apple2/Makefile +++ b/testcode/lib/apple2/Makefile @@ -1,12 +1,37 @@ # For this one see https://applecommander.github.io/ AC ?= ac.jar -CL = cl65 -CLFLAGS = -t apple2 -C apple2-hgr.cfg -Oirs +CL ?= cl65 -hgrtest.dsk: hgrtest +all: hgr.dsk dhgr.dsk + +hgr.dsk: hgrshow hgrtest cp prodos.dsk $@ - java -jar $(AC) -cc65 $@ hgrtest bin <hgrtest + java -jar $(AC) -as $@ hgrshow <hgrshow + java -jar $(AC) -as $@ hgrtest <hgrtest + java -jar $(AC) -p $@ astronaut.hgr bin 0x2000 <astronaut.hgr + java -jar $(AC) -p $@ chips.hgr bin 0x2000 <chips.hgr + java -jar $(AC) -p $@ macrometer.hgr bin 0x2000 <macrometer.hgr + java -jar $(AC) -p $@ mariner.hgr bin 0x2000 <mariner.hgr + java -jar $(AC) -p $@ rose.hgr bin 0x2000 <rose.hgr + java -jar $(AC) -p $@ werner.hgr bin 0x2000 <werner.hgr + java -jar $(AC) -p $@ winston.hgr bin 0x2000 <winston.hgr + +hgrshow: hgrshow.c + $(CL) -Oirs -t apple2 --start-addr 0x4000 -m hgrshow.map $^ hgrtest: hgrtest.c werner.s - $(CL) $(CLFLAGS) -m hgrtest.map $^ + $(CL) -Oirs -t apple2 -C apple2-hgr.cfg -m hgrtest.map $^ + +dhgr.dsk: dhgrshow + cp prodos.dsk $@ + java -jar $(AC) -as $@ dhgrshow <dhgrshow + java -jar $(AC) -p $@ catface.dhgr bin 0x2000 <catface.dhgr + java -jar $(AC) -p $@ gatsby.dhgr bin 0x2000 <gatsby.dhgr + java -jar $(AC) -p $@ girl.dhgr bin 0x2000 <girl.dhgr + java -jar $(AC) -p $@ monarch.dhgr bin 0x2000 <monarch.dhgr + java -jar $(AC) -p $@ superman.dhgr bin 0x2000 <superman.dhgr + java -jar $(AC) -p $@ venice.dhgr bin 0x2000 <venice.dhgr + +dhgrshow: dhgrshow.c + $(CL) -Oirs -t apple2enh --start-addr 0x4000 -m dhgrshow.map $^ diff --git a/testcode/lib/apple2/astronaut.hgr b/testcode/lib/apple2/astronaut.hgr new file mode 100644 index 0000000000000000000000000000000000000000..f19f0099a7f6546bee1920be8b92f85738a42b4d GIT binary patch literal 8184 zcmb7JU1%Fu7G6oVEKID8VMXJ5UA!)IjS4|q2W+et1$*nVb*M`t+Cl_2yYY7WApGET zUe8#LMij+L*flHFajg0wHF;7|!QLd`$-1ymRFa22#xUxF)_pNrTGkF2&wl6L8A)Tw zCAmgF9?i^m&bjA1-??{)tfAXq?9YPr<;XNm`xt*7?C-9W)Y_3dbS`tZievIfJQh~? zMMf!Cq*5-HAj4FvxPv$x?;^!Njo*J^joN*hzF7Fj+ZFSfS;r&V-+fSR{GU9)U$w56 z_<F8bNyob?i*%(|@xlRfyPxrgQyYhwKgGfw&yT-O#|3J_U!%w<-|!{6(i!Mv|H}zt zi}_fgQp%a?Ts+nrS)xkm2M)<4ysm`DQV*Yev-atzGTYMs`x8Awvy(GyFGdHxtCasb zrLHeFMhE^M<p!fc{!`B5-Ocz`MB=eA6~1Tj+Ka7JmkLSD*MkGnR}}B1@G#}e^by<B z0)KyXdeTLhv#Kf$$QWYgQ@0w?Mf`Pb;N4&}&K3lIRM~$!{%*{B!blVRR;N4~G5)Ou z&KaVq&v)XN)C*#Yn(^VogM<AWl{6I*zhXr<w~sMzPHg-)IkTE?BcJqNSm3^^)y{gO zLfM4)FHL$c0bet0d|Iyp+e2e5{TKL43E+!y{5bdHe_G(ro}t@$qK6UpRf@p>%bk>9 zPCSs8A%1218$MIrq#3H<3~?Nnx)7H%xZv<V$ye|_{*{xq^Z%x{^TombYL>s(N61Tb zn{7PyL<ge5DK|aVbodkN-TZ_DOB{P~KfLG1eMLG*()~@$Kl!@zM8#}6$@$rUe*(eA zviZ-sP`8Q*v$Rx{2z=@t%8r$v;F!FQP2m?a5LF_n;LPe8|0WKHJ<C&J4}NdJmlrm@ zTlj|=WBahiKPJNcgZ(21{~3SNx?bRefykoK;p}ai_s2ZqCoVeizV(gc%yqEw`SDYa z))wzL@PPkcjV`-s1b&Q82Loile?!KIL6E)4BlT%m@xQkMCgyQkxC5{Gc=y8gcmG_A z#ABXT{_FcRJJ~ZdE!k&klRaZd>|5)4%Hb~iZ}VTU;13-Cn*W6)7>F58Y$;26LeDX) zc5|hr*sGp+%(d~1MB!?Ie}D7bQ2roUtPpX{H_gX*!K=KZ`iS_0|2F>uH06f>cKpY< z@`4eREhgvuX;hQl2RkW|GnMMzlW@n)UylycRJa)*K1c=#_Hz}%yj%R2v6U_ky|$Th zkq`C9Jq7+ngYA*>4a<9?F)%1?WvA{Z(sMWR5+A1|pI~}^SDD0IoPxiiTMX3AjG?#S zf27AlU!}l*>byz<zjHA|Phq<~M;yP}SZ`y#aAjM%nb%Q~`2PA#D||lhM*UjD)Y26k zJHbw_(1<P3VPXn3&_%{$jjNjCzkP*spE&k%ETa0jt!l<c2F77`NloBIm1h5~tMDN` zvG@lKFwIQ;NBXHj|2?ACu>PLZ|3U>7;I)oyjQfJa3?+pAD)IdC9N6~)`foV+&vqc1 z)toTsta!KdU;53Vh_{1*MmpYST%cI*yjPqh@P||R<HR!9_{q=tFYjvkzpk%6(j5F} ze2t>PYr*I!vd_|A=syqOyI8+a^-z=NmQZU|QF%rcKkNVYcU3Kd*=mKaKLGooFUVRB z`Wp0qjrIRlEB(JLa$m4e=zm$j6RM9|NFqZjX`}BmJ!$EG3i>~N@i&ThBg-b9&>zA) zlD@y{MQs1geVf1+{BN9jB2fwUb{|;$k4YP-LI3?+c_>W<qoh9RT}%~g`d`ZZ6*1}i z+XeJx^G^K}rc3=-E%qaZW%PZg>OYMKqeMZ4`A>Pxcxve{SAJ{eNcZTZHtIjmNf>(7 z<Ubq0_?uL)7^s6MJ1zJhnuY%I*=pz2kl_EP<&3zt$Yow({Rcbkfyyn|&-_TK3l!)3 z7m<ri^PlJQc4S`j)fH1K+{Ll_5pmDZn_(C0HyN3Tdwd|^p5D=TKH-<tf5cwu|5gXB zv;NmAfUg_#$I1<EWSj79i))`Y|G5im%mN*?3>jt(9SX(z+pPZyWI$gMmdSD=^f%VK zu^b6^%)NmAQxpGLf5kn~0|y3Shlll7XbzDGMTh8sN0oC^Dp<$KO(gKU(9P$UA<-W^ zxBn?{-Ei=q^;hHmJFJ|4#2t92Q~zhUdqwucl&J()0y$8Lp#Pcg9uoAww-tVMDFprZ zV0L!||MC3}>pxZi_D%Rx>VG@64=SPqk2>`KrD77fi!QvFACA+4t^fK`AEEQ_y>|!I z2iek$&l(QBf&N1yFy~VL8)x1!VheMfWc?p~-{QZ)%#q`5*8gmQbhVhQp3wh7<w<xL z`ahPt(ul9iE2aMLh~5Q9P{Ex1w_`BmW&MBkSHXaOQB>fIksnw)<z3Kk0b738p?PiD z2K^_@2^fy_Ys8l)6Y?6X7-*vy$bO>){-5+e(nHYy1oOY$gBm;-bsIPbbMi>gkXIZ# zwyD5htm!|kFQ#Zj2XoWe7X1%mc(7kcN)>?#6>}}k$1MF9lZJ_#obmJA_JjY_i5@g! z>c8drL{5u|1-|7^yuCsH4IJzr$6HB#XmD(s=ij=FKl1!$-RE!{9RRPwYL=l+$tVe> z0{?~nTR#g^#2OeKcygG~l+5z=rnJ(3Z~2{g?86t(|Ap<tOuheS!=(NaufD>_K=;g$ zSpP}`1U?wJQ%-*ro0+4omm^-jh=l%6pqt;g4x8qF)_-w<<^MYOLk|7}|40S@uYrB) z26!O#w}y}CVuq4BOqsX!7xiE9_l=AhndOJ*ex3Sn=j-kY>wg6LTV?v0q1iLwKkL6R z$bMt|+#rRhU#P!@Z{-~KKD-7L`ahCLvi|P=;~+(!;qnp1zi|iE2iel-zqDNH?{1l^ zS31cn0Pg=!=0EPTx0|4(yWW2U2s&jOC-tB6gY_R;Q`2Ac1$pSN>q5K$RcORV?}76r z{+H+*g*{LYC;u&k>B*i|bk!cze)0yRozdV~+G6dLzl&KD>XbInE2p|^`22ffzYpv| z{7>NXZ#wR=$(=RE8K`E4b~LO4#Q*g-ssCxJYQD2{IoKT>?_~ai<(i-&`z`gCuhD%D z{YUKZ8)JOr^dF}R{jaNqUN+YXe9WF#De_9_O|i0`QL!i0kIUxP3Q}3YGoDz1kK?3= z|BjBI>|TUp+P%Ql3H=fBvk9NCaf}-OQHLG7FsOBP5BZXaWBn=8i`T&JQtrmWd_49? z&Smq@!U4~{<;<uu{Q~-*+CF@&I`}8_m&n&f*W$6)qi$Eo)_>R{>LeHl{TWfb?<E%f zJIF!|VOAHq`FjTH|A(jge{N`&Pd81=f9$^L8vHl-s2D<jp?tC6`@!}+^WUNW%mA(c zbRP+^!s}no&V!{`?{K{9`^<8NI8j>QW9^NOzh|hD7V2x7V?9IQ|4rz>4Q=CB)xjB$ zA^3moJPCa3lyC<+yljFsf|O~M7=LqbH}~~YCi~7_ES$RYmIzTZzSQ3XQN0od!G_lS z4{aTgD+%7&e*vGdyJB~lZ%g)qfd%M4(lGb!7xwy}u>M#4T`!kfu74%Ip0j&P?4guf z^#A9EykDhU^veMFe=dj)ptFq?!LC4J@1Y*9b*KKTTf^9wnD@8PUt;`KtRCdZ&^DDc zI&@|_b{|>)p@q8Ef0?2KzxQGG6MNWc-2YZ2IQv~^@y!9TUnb_C*+?%l`?yDGiod1* zw(0t_&?}`f{1UZnLFP3QXHs<ksH&(y)Xuwvaz6(@d3a(OU)<w=@m1{jp^8$zjmV9j zPU=7UQLZ3O_%?9u^Hl!B8@sB=lh3gJT79mdnOFm-QRlVPl~-B+F{J*#dGGo*EFDpv z8-F2j{P>xJ|G+=e&eYs?Uwq?){+|c?j#&Ra5mdVpo;jdKiL9SMH~;A|zE7Wq&kU?; zZ19gg9<Bsfe?PKnuoW7{&xuX+SU4c~&-k_VKX<@f0calyft8YAKkL7@Yjha;pAq%C z1^(XdjMRV8{lfy!?3rWCR_Ye&cEbRERYPLYVD$C&j{_9p{$tfTA&%aMkj1b;opNc= zU*4HIAlCn}&y~2oCM#hxzSQ4UR1Rb}_D@dZf8;N#{cY$yvHvgE{{i=1+}|30=(psM zo_i8*)PFGZv!Af?ned}Bx6ogSpH6b`fRWX6)fVe-!ZV87(ErTkL1e$ELEYSa+xp+I z-sO(9LH{FklQaYS@41-gwEYLo(tkF<RCoBXf@BjP5QF#MZ-P~b<GaCeAMZXK(-yk# zye8J)y!T=6KN5}m3bplr#OKNr*5gtgn&L0@zih$4|IjN!|3x!o$rlnT<dxTV(U|E$ z_n+a_q{wZ>&tI6`d=DeW`rpR>q`C)S2XaE{KPm)b(1c$Dw!fUpe?<FB`y}zn>;Fyb zh-C`v57v2Un)f>N-*vCdPvRmku>VfSJI(sPM)a}ew!2;GpA3|!fvEAOid`Q6SORNd z-lh*v;58q2tsg!5X6-FJBx~(|7wfNhUWm>You&uTyR}|$J^>T@kN!V~jdY=b_5J@e z>a<(1A1uQD`_o4K_e{k5zE512_O!s?IzaC+*;A;<?%y=uap@+)y8g8z+MMm!e@hZS z{R;#YUFH3UTKvI$egcO0)13DPKE?jKsxP5eL{f}tXHVJxm--6^Bt?gbXSSIWJ3rEl z(8#9GMV;7xf8ARDJNMs#Z;fgk-Dt!9yPm`|k@zJ~8gtR?zraTyVI}-=qSBK8=Z3KU zc2PPqa5V(}cXkJn>~;Mwsl~<}b5x4j`aiGJ?S%=f%znbEv>BiG@cHSZH4IZNX?SXe z4y<vo{udA<us%8%7`P1dq^R`XRcrs<W*}e1`|oVqDq+uL06L87fc=S9`g=nEf%{6N vrvFx7EA(He3s%;2EY~IimeanM6P^1DMn*}h>HoN|djP8{q5u3FSCIb$b=Uaw literal 0 HcmV?d00001 diff --git a/testcode/lib/apple2/catface.dhgr b/testcode/lib/apple2/catface.dhgr new file mode 100644 index 0000000000000000000000000000000000000000..1f373d9d0b2b2c73fd1f9df4d25b35c97b69c01f GIT binary patch literal 16384 zcmY+Lk5k)7w(naSWvZ3pzLI2IV{eMOvXDI>JITc!@J_r8T9?8Kuft<l%ft}FyMDH_ zL%_Z}v)Hxq8vX0<(*}}xT@^4!R(GF1-yi3QM0RAwK@dc?AwFs1Rm*B;qHVt#?fq3; zJG^VR?5Gggk=?2qw$Q}&w7w=HA-s02T{9fPxJfUyun_IE8*2q2LRV_Sipnj1Bkf6= zZW^0uI%z~)8y8~xog-bTKDHW$ZCI_K<-~UMv!4+j^JMrecQ))GFjzs$d0sGVzZ{o? zok)`+I#8buy*1{Sp1R2-Bkj1>E?<^oN4Qbhu%zhd!sESKyK#RIrfK6?z1|eM*b|;` z+uCY!zQmi>Gd~b&M{XFjMCi1fsN61u)@_;HipY%`ksj;qYEZZgDz>nVSA5Ks>h1-@ zGx#CYBGy@1RGhXgwYVCUL)$3C^VsEe?egIKK+P`e(z|wqCJTNhewzO2yFC%^-~YFD z?}To=6YUs!yf}7!O@8xgQ&?Q2wQG?UZr@hhg~%1U;R@IA);6Wij#y1lt?X5HgtcZ9 z`EAb2ioA0oD|G4nRF?<s0_)Y{%%$iQBGxT9r^n%h)`y0uO@#PkYxAZdgppx>H%^Vs zYwrE37N>1ji1zBF<MPWO(xoR|)>&YF5nAd5qdiWHbr64I7M2aK<3_&_@z0kBt!hyI z)HrT@sC_CJ;@pkj5Y4CA`FvcJ2Wz$KjA*oLodfB}9r8;5dtKE0hWN2nxUWYUPDe!5 zC=)xCKo*GnrsSl_J~yn!wb+YyDjA~?IiVn0j@b6?m&E6~{HN_!{W`s0T$F?DmqDxW zS62Pf7F%DY7eeK=m1f%IakZ^S4dF=6Di*_f$oE%eV{z=X%g;sZkZ+l`vtE##1uLwz z>*~A8u{B*5+8N(#@3cMg!;#wtm=QsA{Zl<%q-lDPruXyxdfOI1M;Un%>mccIgkH;w zoH(6k$ZEG!Ug0Vu9peD>IB_G@qe8pfb|Yua1|v4>sJ2&`Eq`0h-e?!vRcRSSK;^B_ zLQVV^D+qiMW`g;W>D9PTU+smiD8v~<#H*}*SOBL-_O{Bwv$$~WiM^KFwx4fTs>Z99 zd+xCh#}By1@$I18QrY%%+K@VD?X+t*wY3NQ9lQoNQ8_3ZdML;VSJ<~za>y0VO`5Ws z^k7mGPOLJ=3JQkG*~byt^1p+6;BZGPa6&t-lIc4)3i*Y$z2z9Cpc*}k^-8(5cWlS% z?scwJ5#NES3W^IR3N_`*n@M#|Gqf8g(hTpV#a!I$rZGK;(y79Kb<L9n@v~tWdPJ5! zjL0_hpezOV6k_MOCcwvfwVe^pWi5nl+QP3sC&zEf>-Hxyh`ih5N?ka{CYUAz!C)aS zR5G7lw+fuPZtS!jBM`1%Ua?Yba&W$2cCK!Fa$&fjv&?56$Ky&euS9rq?A|-VGBWK< ztclMr-HI+Ut)10{)^Qo`+y3ibYZWQpbL1v@Z>fAIR@GLy1$%-&*LRE^x$BB|_1KYG zv~yo?&n6i|BkJW2XB~fz9Qh^xU_dcxh>XI2u=(!=rv%4H;U9=iFzJ?R@qwC?+*SDA zKHoE3Nz9}M!#VJf9`Ze^-&7T+u{W2mPUO7P#mk^^ytrSq%a!T}@ZYWl86kXhBDSJ0 z`xkI~biY;$%HfMv?e7ctdowD4zeZfGfd960Ulu#un+$L77=>1K#k^H=%!B<M&N#D{ ziL0noCWc=^5$WM}r_d78dKtXT+)O9wZ91v9%CF0T-LgXagJKTW`Zx+vCKPEVs<ps> ze4v=Nm63V}PF&kLtcmnLtT@vWu*(h%v|5|WQCOnUUOeDG77-Y3)s8aYkH`qmFPu9f zFv{1{`v>@?)ASPjfD&{TJ#n9=hkr6HTcp#PQ4nGnhywH13{4zxAGf`j3S%c~pru}% zi5z0?#hdYFR6DN0N3hRL%|MCCUyrzE+IA?myb%70y)D*JS==8e_DK(>^_ROsi*3Ur z_f!r&4kG9NIe1xZ6*TQ!7uQCivJ=60(WjPp<3z!F(6W7}Rah_j4Ps1w-ZvyDT(NMC zJVom#>2p_-gOx@kxI1U-mqDfzfhhDp6aF3j&wwmc$k4-JrD#v{Z${SE=VP+VDEP3a zW(RNpn8%g0yjYKM0WFOjsiGrfdaMh@jO2e@JBC@9&AkEF@L%nAHS0?lPHd|@6q}q> zW0FSceFLsStxz`c67Ep3ei(3@6_im;r5r(kUbc6l8j-dqRrV&Px<v8F|61Fr)FXI3 zwiV|{<v*$qOcs)xtzR$q+6DZNYizzL1fH;NJ;|Ky+GW~W>3>{3E(qrxh>dqy;p5<5 zE-#h-I>%zVDLnK!v*w0r+q)sUB|Hl#XZ{M=^QW?pH&}hN5LaV3mbkG>VnlYc3*t!B zGDgN1QA2{?sCN4X6|TX{HmmgHo}sY$br6edv~DcG+JpY@L_{z;5Y_8%q$t&*)PM(J zHs%UT<Qq8%Yq_#&ctSG@u#XnKsW@sK((#3%|Izjf#+C^D`<uP#y#0xjn@{TKrNizr zI7<A?mj#eh#y#$;5i@`Lzz`rSBVC-xCis8T*3vRp5GCTW6WK=@1B7se2fJ#qC(wU< zm{Y+Upsg_T7FZ!uSnun-SKF7b?+@<l`;F`BW%Xs@2ONsOsW|Uxgm&OWZVHkrwKZ5r zcqn_#P_K64TA+6Cf_xM^f|m`u?GOvDfPEJ?d`evn8bBYpL5>J7bVF^6ECz$Y?P7&K z#Q_Jm4TF85Ao|zr<Miz9YE&?ONgHjClSX&gPfh9}PE72y(^mp#`I-}ee+(}Uz^_sg zaF6~e4q{Fml!!8@59@?|aec6b?Yq+U7xyp^{}xw^N+5LbgEEEN>bi%4Q?-okpd6hV z&SyskZ5ve$S`8z3E-IO=;#Ps$pb#sE%Zw_jw~IBR9Ij4b4Ob||Bqb;9=nei`!*h~p zuh?b0vxZMW|I6YU{40J#0m&OXa#h|w4Dd(x1_geyQ2YN@EUzLR3s#`s#qpt8`0v*B z4SH`_WG3Um|Hod){5N*!z|rMf{2A+1dh}XlScp$0Qj4H5A!6i;5Wlr_UtPU&v+6z( zD_Xb7OR=RqR0015i$=J&OEgpHQ+N%%a*nH&Lhy!6B-c1KoRm~P>>-YBv|U;J)L?D= zF0|k6pgzt^5u;1(+GG)=%KxvS9c_CEVpyM=`e`s*SOtGpOTUL3V;d%S<3-yW>I#3t zR+({A<1<d{O}iYEZRCS4H`hG!U6XKcW$~&C0`ZFIBrFiw|8YWQa_4sKz8p^{s#2=P zo0YQoB`RDJn=ga;It{7#=f@VO#p$um*d3-qd2%P<J+x1tY%t9#Q!KRuFyyRlf+Gu; z;l{I9pa|{rp2Kf}b8gFByi0w5aaE7@ZeRP2+s0+tC^Kt0&K#31U*>nW3dZN-ol3)f z(cbJFXgYC)e?H*<!9VUc&7gqzbn-HT%gcnyiPuyvp@p@0v%N$9J8%H}#&uR?8QQzQ z8QZX8^=0*T?`n$so%YM0f>#cVvEuLNU#2IfsMtMfuTYQvTkW0Womiv(sIF~RGEs_$ zqLz)lHL|jee&T<W;(DU?uJ%*~6Ols1S+@%=h!*-g)&mB2FQ4Qe0{HZa%&}Ui$8+Vy z9!L0XuuazBkQI*%m4^e{YmNl}QEie^v3SvMEz58~KU~?jWmWC}rqO1;o5#8quYHO? z$dD-_+Kxdd7={P7Ufsd~>A`(EnYI+t3*cXqE3fvj0D~;|gUbNEvd+CQh{&ET>hB1x zXi<BE%?#(SUNul=l&}FuGdKl&ipoI!lBmJT<w@BfzJ?X<afKTNu|xJ#d&_?*{~zO) zaaI=9>X+TK+Mf-_f6eu}bd5k#0l;hJR#_J4L8$B8;LUR?>`H)+5MP|r3jg?j_y{F; z=|7O0s%P-ZYvInxf`V^L@{zSUMy7L6Id}<sOAkJ9J~;6nkyJZa4IGi>gBoA_(=v+h zsPCD5XRRQ9nSO)HiByBxK-mrc+i#!;I5^?*Q77KSQNR#tmUz4M<`Op$Q-8%jM|-f~ zE+?(J61CfUW$_N42LGAJGwRgMc8fbdj1afXu9W|_TH1XL|4;@0x<LO`{e8GYX5yRG z{Gt$)pO@8Y_`PF*XNlViakIf2>T<Z5OoAE0opaaNC6B;HyOCC-;I={L{!e>z>&MV} zXXCTJ4n1_X$o{b=-hlsxpl8u$U&908fq(08^X7n>7SD=P7opRxk^@d$2$jaDPR@!E zi9R(0zqdF^@mzoT$;iZZ`}L%;pJ_EN8?C*|`R$wNCr<yzsM^uOuk#oD?fCZCt^7FL zZg1jQtO$Km{y(g>e>56xD@7IYmE;n<gjzph4*aY4xQfV97qBb*C2o*x(W70J=dIwc z)AP^wi|Jz8_^JN6epLwZi4m;kf1RJqHpHT_(s7IW-^B@_)A)atVK%!j#Khhxtl|G- zcD|-X;D5~%i%Z-B*Whf?|BUKk(Vam}U7?VJH-33h|3U!ui!y5>`i9;L$eG6x)7hfV zv(m;T`2T<d=FF7;uc2M^u3!_b)o804Q&n9BR^ln-A2*Jx#^$6kS!I^OAJM78Ixaj2 z6B~u+VAZJZqy3XbTHmj?99H==_k*G0r|I!^v52cLYn5lQ7C08QetX-X{*S7L7T}{= z+jQsb*xCA2sq@_x;=F-JL;s>0{)bbi{%+8902ljpHFKzUl)Abv3yP<XnOnd>N`b-M zT;&J8^vj5g^5>w@QYZq${ML@j_<y>R{u@?FC$F^^kz=h|u>I;yh5p(~|J{fB1D=FA z@Sk41ee?NZdtD<pt8MM28!DHn)~Qv}^OSxbnyG3MW5?Kzm7jbZA*#tq6$0@O)cX~c z1XUgkB6cq|I&S(D&rWQuo9c7j$H~GKYQR>i4l@+Ta5nTl>Ys4qMAsGnh&W$*V1<YZ zwO#v=Mn91yn{;V*jRuv86L}RCp@(58jtCY0w^|-Lq*4DXq#djku3-uKe`NZq{vaAY zbj+!0%z_J8gS+8$J1%^vpO;Y=PFBzZi<QH7I`%6y>-^FQ{(-xMd+~4A2HH&j;c0fx z$tZ*ehQfcNRmBNdvP%C##Nh9Sx(NI)Likdh3~{s1VP=?*9u7>;Tp^iH7L?hMT9rmc zUVxkTgyR<c;GE7wu=q5slrLXb4%UAGUDt-Kc=gMm_hj51JC(*Y`1ezxx;D1d@!z%f zo7RhVbxK6Y1h8&6(P^u?!X^5DY@<2U;bfV|2~>|jqN+!whLd|k7tXDGI$vB;{VNYX zS=^RC(NBppD*L$K)A-ikiLC2`$ZF$eI(4OM@Q)tRiQv@qo5r7UfNf$L*CJ+&3d(hX ze@Fa=3sLw-={aW`H-h_o?uMREOnvgo*!|P*`fs;&qiPi3FKg?o`w?We<AcZh^tNWW zs;=RV%B${B^EJ{bNOo}JB6OLZ(<b7o=Ygx8!vB+%{?mVSs1B$&A`}CZllQUxob!l& zx!l`7xT@bSP$y33IW7YKud3$9VQd>#L{_z&KRba<W#CkB8I>}#xh;E(TKrFCTy>#R zYrXNwH=+BfLXXmR;*B#E?xfDSQUOigDE}|DcT_7>&6{g#okSn}FTg*3ik=MoAhwOK z^V6}Q!ceQxw*v6w_?d`aCb+Mux>smEtib7%Tfe+4uewn5-@q5u_2c{~DBMW@UG?9H z`zDy6TMX9qh|{=Pv>L|_86v3Gm{)ljbo+4_+DeQH*XaNMa#SZV%2aITS>a!NGvyuj z>mI|c)N`yLMsxYFs_v`siyQL11NNWamN^A57}n3ZrnAj^I{s+qauFTiTsCoxTk$W3 z^$r~QPt&XKJM>1C|K4hSvs95p|9Fa!(!XY&QVk7+WyyY4K~Jm})7fSX3Wdsx(vJ@H zR{15mEOc^l8$|E4wnP2ec}FH4FK+))3GPve<Jv2m$kWf1|M=bX^j747tT7k;H~hbD z&<l%Q@K*)@K`V3LAi8`&F+ANNdc1OneJTc4dRvHhaFw+djIH_v<lGi941CRZDm&Mo zD#5$@r2aC1<M)nM3<WD@)cqcZ?c34yRBQhMCG%qRH>y=?Qdj=J{f9Bt-~mrW;5_vV zYR4$T%qsK1{f8P%UsGLJIx>#GLw&G=PO1}hP;7AK&u+`Nb5(rbr&phUYMg8Af777* zLad&Ksw=b(&p0A{JNm!EA17KT$E${O51+w9=xJo*;Ot1DTy+2()>m6`5!ban<xSvM zb|`hK3n%u-vEce()&Exvba44vY)iX?LPzlC(=Z%*U1aJx9YCsho}(!}h+%b3b3yG) zRTI#6Lg8VRklr=j2Bp2}J*<PTSFymuRjA3xHnlH3geBlB)*`mg>$mlvUSGbx4#<67 z)z4hxg5$>#I_s8y{c78IX1Mr5o-wpD_<!&pJ1Bq2-!9YtLSchokNt7~E&6{9)qktS ztDQ{BWR2}t>AxxezYFTDs18eQuGJ=u^gvPruui&h(jBTC@FMqddioa9^6BV@s2k4L z!v84!wPoQ(xdA+kPcEV2)pl@8m(p;_5jC7Oe9{AsIZZONRS$?ki#u|{g>#%dU0Yjb zCh2v0!xKVg+6GBv$fc?x9tW(bUOOf6$CG30HiQ45{~PJz%{xv*Y@)xcBGzwkX-4%G z{vYjt<2Z*Z&ryg6(XgVb-zcljP(d+cYg1@1af;7f_GI6DHWn}y6=UqR3-9z{2HpG; zf1**C)K>L>(Axa>0gjqXMt=@ub%p=Uxbcn^v{f`j6rl4OS%5;S`PEtS)v0`5`G3Kk zdBS4c8FYBw{j6{@Nnbi`=dy7_2lTQa-FJ8u#gAVGoMog&?fM&P?M>ya$Y%Hk|GydF zR$80)4P%9W<!*U8%9&FGs8duqjxS%^#4qf$cHmpO-`qElwvid?&+YT-d9_l#Y+Svj zJ5hagjnmd8y<{BNm+3?2$df120{9PB&)?{_Q~z5-dJ=J&_x|<TifR$FQ75VFWQS`i z=W927J?8sLi@h~_eVgkXu@#EvTOo=C{;RFe6#u9{qj5W<ySqo%G~ism#@`Nhr1&AF zC&AkP{+fOU{KJ!ghR|VboBEIak_qGmb(w?uZ?4%9e5z(9$7^j%!tE7>V^x!|Qcl5M zr^_Xrb2b0Nm|wh+I82a?rmYaPib3oJW%WFcP8}+*_={a}{=%c?OQ(3LC^LD*{&lrx zsT4(hZs#~nsXA0&4Hgo@ZPgV6Da9l^v`FF84e0|^KL0dD{i$g<GdPZnfdSC1$6=k4 zm&K$geR=vq#Ag<)A_u)<oQm+QDLwOay~sNRGwJehO&r}{jfG(f^DsZo56n<A#Gs#M z4J)+nlEf66%79S%>m&7OO8xFXBl|v`Z<I(n-SXwFbS>X}nqHW`>2|IXPY*3OtIN06 znEA%pqS>@Y$?&LYCH=(IO_A@ePk9ftoqrS|n;fj>*O_H_r8eEo-t8BqFq?n$G$H*9 zVGiwKe!QQiAJ5bNd}B;g%&`0;;;MP9>~XL+|DtQ@L{&dYwuI&NM!At}iqj2d6TWbN z7;%l>8=0evuIX9f$upHaX44+$hbtpzSWOkR{adriU3}TxYRZH)jIDu;^0WSQInR&T z=h*g^P2$yjq3--RERK~&C|xODq;k?H5prE~U<x@m{SEQYUrnH@=F5&u-5T{1sXiMr zf0RG8eY}e+L)q*l{i|$~xN<_dBG=rmyZMPa3vImozBkYMHYu@wYI@o5pC!xvI=_l! z|J!_*6RGFJ^n2m6FOsz1wMu;<?o6XMm98dwO|=d=>L1FcWFBEyW80U86={a)Uz}y% z@}8SBvbtt$c}IqJZ6(>W-fTI2Kgti5vyE|n%)WiI`M#*u|7G~G_s_Z6eJ7H?nPT}D z5!z$f)ZFyj{J5`cXZgX^GfpEUu7iA&oi?pz{xHuwW|QpW^vzP<vqr?%<2vGhB&_C! zZ=Q<NY%$;6onFk&X8WUjw>LFC;aaDx^X=FDlaZdb+;H=|y%CS$io(y2vxio=)U9zo zNyai2zB%GNn&u$al!vCSu3!b@9y?OsIa@&_O1;uLuS`Rp2=|4bZHngm$;B7{e>LwX ze-Kv5^0bn0zw92jo(!buruo%5FAd8h{)eWx_*Sh^rrA&qlSJV!KOoP1i*wI6)y%BV z$T7PZ<cDNT(Hxs4PBE0H8aN|ALy<hpzf7;vs|k@Sn%+9(AOAl8{cplJ*}b)Ot8*rf z5_!s9yk6<(O1OR9j$|<@5nGXO?vFrjDDL|o$pk|TnY(GbV0ySrO>!_d-d9<KFbLPY zz3@z3hUQ?I9z-?_m{)mA>z#cVQdb%MFs!0*vx&*7wwp-^j*3~&EcQyoF=4&FIY^3@ z3$8~;qr4}4E1WSuk%?3c5GH23Ff2Vc=uIw)CiqR7FwH5i6hg+mc{-h?3W3B;XiW)= znSSnZcBI=7Ubd(hP3WAnYYj~A$TOQ_w4t);)C`j%c`vf1>?!z%S&nqFQQaM!n4vl) z%_TR-7jUQg$@KfpBof|5(=KsFv;FCO+EZ&KzqU)9Wb?hpW&hu>S+7j(UoUh^<r!Rg zlyV;t|BuQGvQ})2;lA$0=)_}Zh8YUQKPskRKzPaMhf&rSp6Lqr=Lnn>`S-mvWMs`Q zM(^kO&}x#$rSFV$FYc;UJ`GLr-(h|)E3A3mO}pezGgmUh<;UFk1NhIo{VPEvh)Bpf zy1gPX^5LS$9_Ay9t1VA7liP&7V@w2WWSlq8J&{<YjcIST=*m%&oJ}`AZgl_C7vY90 z&p5rO={YaEbTZe*eevNgFVYgF-s-;Tv)tjkX9E1EO_0q#^QD|;b`vr}F_iE%l*1&$ zY?$5ZvfmPGB>UFkitMRk<fNPJUd*uG)3dv5H@n0Vl3}n$@yqnWJcT#!HjMmUZ)}U@ zTP-q)EBkL+hxu-{)SGL~JP|Vw6~3frd#nW1+2bE4FH}zPk4G-U++cl>8=FS#YR%Xn zhvCNT^aA-`lKuRfopn1P(u`1C{de<sIBoxjv|j?RBGomOS7Y1gagFWwQq!<YSvCJ4 zH_WL>sB>4dj<s>#SKnE0Wco+ltd}owvab1-?DXTJEl&L1d-dl>DK*gY3T7@^L$cRB z@xS6v7KPX8Cds-dJn{{NBa&S-c!uKpu@}F~wrt{0_K%gmS$793{Gq=ywR7$?T+Bg; z-@DsK^SQ#cj7E|CP_Z7vJ(0x<Ug%^;gbKN_r}E@!z}ennw7QSqb9G<hD&CKJo@L0> z6V@a<y%G5)dZW&~2hK@JH9t{NkykN;r(hQNeRg)peLHXly1}a^^NsV<tE<Jl|FNf3 z%}}}yMj}}JahT6#bC;M%xZz|13wY}=sWilG57!}nHC;F{G({F>>=%_<aC(NOt8>V4 zN5Klf>}fJvf`9I-+b{?i?POhBozJX4TjD-=HDG0T7V0TWU*pd*LMig6yfZhiuizFq zn*Da>!dny8Kf%AxUW{G>*Ca43nh(#YXb#DHV$Ev&UKf9$yaQfj9Ypg7AlF-^yr0!` z)AaCYnpgXc?8yfad*&UxQ>^kZT+6*Gk?H&m0{Z`vtHvh!zx>{Yf53mZoLjyya@@fp zKXylGE;<BT4)aaC3rb@}@4G$aMPN~zSY{ReO22sjV&_-M`sGD(G3$NoC;#O7ADa1F z`0HtQGF3LiRE*z=4+;1$3bZX(LWzz1IQjnMEI+#nQD{7yInE6&FKgHeA-;8}MLg=$ z?L%CcZ+1=2Ca?0^H4XUt&U{8xlKkjmdXZku_ouzl0x!e)5EJY4%k%=jSF+Bpl%j$< z_=i{7A+PW^`BDDx{aku^^p~?Np|ZY&^HDys>Brgrc%=ekEo23!nWD|Q*LC?!>S(B; zxm(lvbcH|i|01m?yFy;)aMxLP<&sy6K(BDEa(RX85$+XkT4joDY<){KK@Yk-?46;d zP5chrZTjq&`Fms5=jZWNxv{Ncahl^5JZV_P6XVYwO+`Mld)uF*{mg%mzzZGj00*N5 zUk16W)EaF!!wV57c-GUCLB4d9;1y9uGwI<uB@c&_B-`Y4&r_6$dko>76=#XTG68G; z(OIHAf5@$G(Wl57X?||pPl+V+Z-708E0A%kF!MCb=9YIi1(Tda0-Knpx#BupX1U2Y zt2~i+fj5@M`z{Q3irR$O6y_Hy3d7ZG{tJ}J9A)QO)+s*bN;2HS1CR@$Io=pA@nHFn ztQFT{cC8Q>`n&z(MLeaPI1JCa%kni>S})~vZMLDf>~mhkr(jI<y8JN(l>myfTDs=L z!YlsM42dr0Z};JL#Ue!TmI&S1Mou}^kBi$2<$i~}cJs~e4BIoO{QhZ3<`ua;DyO+Q zzH0J$c-9g>%*6ox#s70ZU5Gp!DLe4=DbWb|u&?k(mcfbA+r3n^muTW^I`D-5ovW3S z@e4FMH{bWnSszbF9-nUOR2n7Rz|-v9$0F<VgN+dX@1|&x$?01tG5#A)0{>J;D_)29 z%+U*&o%Mz2*r5$C;Cyl3y{@VcI0a&?xn$}{>br-X>2kJTOu)&H)BUUE;HYWo+vNY( z$#DXBt&`Lqztj8Re_3K*9!#zL|1kOP=>O(t2i%YKD*TmX7xW$~^jTx&JJfgelQ@Ml zoAy9mXNh%RcKOWpMbe}8TFw{g1um>V$*SLYe|TWj$3@6at|&U`1ODNk6`~I<H`Rr@ zv%WkNQI3qq;T=k!=)jFO7`2T&nj#bz9V#`lOGju|PFD^$>&lMfod_#g&cNPkTum3_ zBf}mzK8)#qjR2=IMz5AvQ|==+gf`4~mH(IDTKJ5sxr$In;flC`?Ll7PyHJ%L*^>8H zx`zMJLQbJ6**|qSzFXCVtl8~N4`9D#+MlA{-)cj0O-H-P_NQTbnx8OiaM%|oBQlx# zGdW!!DISlD*-^HG;}h>oKaQ!hLg6h}`md=|XyOB5tgF9}8D4hWSowd=h>K)_kA@RL zoDa{k@&BIM0bdQWME|OPD2bmvTVcvgJdjk%dYrPSx$ursH}4|ZMxA@z^%)vRmhFC2 z{(&kGOrd$8Jnw46KAG})aa6RMmit06gv;-kvCrdQVrAeJLK}`j0bv(@w;DLuwLDp) z6kdRTmH+t6P|Wh^@)`KIxmxufa<FN3lvBA#e9<1_Z&Uw(MlaXBo1Trpm<x~1-WRzm z7$=X1`PuU7V#ZoIr60n+*d}Yu>#y+_298Hi^DC?k52$eRpwZ&wR`^H%@tqO)SFG#3 z7~xh8t;we%8~mZUI#Kd3M!ga&!FdQOSgT}S3;j<6uBGZ-3{KMiSi;w~mwzj+WwWn8 zZk}(-&n!RYyBi|>+sc1)0%lVSm!*6O{+Z|f^bF4-n7wJzr$|bcs%vyk@i1?YV|Y(9 z%6()m?nZvlM?$Mh+jJX#Ap3T^Ki+<q99{M23#t-TwUenhg{Kw3zMf3YaZ>Dm#DA>N z26n@=nHwha&d5yr?1w*Pp}yoKMi-%~wTS#UAL5l&6-*wYnuFe$I}6R#-1Td#NN3_Y znPq27^#FdFPA|F_FeInf{NWkZ%+vJ3Y#t3vH&s<Mk3iG6N~IM3mb#`ChK`8V%&GdD zQ&HNDr^NBD@IQWWxWYf$mmkXJ`!3D}4%9-^w@#0mxPTGr_cZ4HQ5eE@5qYV9J%4=S zDSU93QlSdbf2b>A7fv$FQ@c`g4e*|Vo)!4PJCao@oB9g>!~R2EixV;jxKEEWaFxcg z3(qu6Ke@Y@@F&3Y#e6@po=J5Nl|RqE&d-@V?<Bj4@=s@I-75P_z0pZgJ57o|cR2Ab zwUo$rl2M-ORfJax|1MRU@+m5g!}J*q$AP@-Q-8B=mnzmnMGjZ%Ow+e3{U@q<Ul#fA z2}Tx<ej3sf?rx&=MXasARn93}ibtF%o_3W{u+xM8wr`UXiWA0vQJ*FIId|p{>5chP z&n53?iVqT>GX}rb2$zcImEr!?)lBU`hSX1V6|^(3^E5rqLJ&1RA-<c7NkW#t$LCSY z(vgwI{lEDN8Z7D$)6LF$0~J@rEZjqN6j$?W&GkVtzbL}&M8+&#c+&Wxh*N0VLwnZm z{(DL!4(X+MKfaY`^l;R5Ps5et4cG-ntmjYrZ{esx&bN*CbLwaGKX2q`T#f%%-U6NN zDt(8MBeSF)xxx4BAi2s8$bBC_@RsZv$mGxdcVvn3UwtaI{<t@=X8Gu(3nThlzr(-c zjL+j7_&@n=)&DchA$5(LzRe9k;7Rh$w8$9=9Jq_BQ2*mNsB=}{hiWdw`Kfr{Wl<;8 zK<z4#o!Co+*}1sw_p_tj*+n;ddy(QLRow%-`~lv08nU@w(iHx`?~ih-{#U$yNd2wn z50m)^@c)8-5T`dVPZf709x+w9q&&c5j=}hYEe~vgTX8BwEjjXz43T7K$?Od8sjA<L zS$&jsw{+<p4N!}x>4iMSYpS}3dkV4S45@25e;#r(k2y^FgvvzvLIdva;g``m@Gs<S z<6BlhXV-3W5+z)+Is>}y+Nn9(ZW68JY*qa$3b<PC7B!u_H#MR7^l4Bzmf(cWa^463 zocJKOnqPb?+}?Z%+nNKMC3%MbgZVjeA65C-Pl>=VrLyHaS<7|4c}U*6M|9H3541s@ z*OJ<2Io-cRom2;?slA1x-+s+M+xst%uI>nCX}$<04lD1&WL^5C@J@ErNnjt8Fq_a# zDcMaS7VsoYuTEh|?y+Ker9@xeQpdwz@>=;*c?C0bN-$t?3lD+==4X2bKj^H2k39?( z(SMEj&l(^nAwN(<FPFfe)J0rDxBRTD@+vzvXB%De+yCYJ)%%Kn$baq>@_V>3OAf+6 zA+^`7rFYOlyt6L-{yd%INQobHCADhqM*cqjx^z|TVTz4ZySq@YirEtSO~-Owq`#`z z(nrI8@Hb&+bYgrpI~V}l%760{?jbuuYfyHaG8|7mp?}xR(Ho#kP&ydBndVe1eCv$v zV}~q(p`V7X6GuH?MHA=w|8qtC%NaCH@!_LY`Vfj=v-nJ6CN@+T(xX!gS86U@zozPw zv3pnHZ}*NT17I=dqW&RWhPR#2yrkwpC$gRG+x>Y@#mm?3sOp<$>1p=W&i(GkT$kR@ z*+c)$9-tA*|Cc`KtC|2!<aBVDR#U@&s0x%UR(Yu7d=(z?+nj~E3SJP;MDq7$HnNK^ zyn45%D)4EqySqF(<Jpg4-ST|o>-6}od{LzNVQ;=RV*c+}ea#{Le?2#RuP~8P)s;9` z6>Ux#c3)vXKcOGE$}q6#i-CQ*PKL1p_)nC!n(y&3y}QOVrT(P{oh~Q)Nft$fzv;jI z4*wnYC6-kAHfNc>rH7()%~<L@VHs-U)R4pXR5Q#^4F!iEsvJ_Nw?6j1<?P@>JOMsa zvNn}*v9D1z$6i*PbQ^Hb!&pv}w`2!yM+<Xw=$?kz>=p4&Zi+`k@!^^Lc%#IVD$v?b zuRK;f?kim3R5beU3OTlyo9(CB!~C!5ya%hJLIdWH*c%>EJq1BeJ7l76clWP||JB(P z-uB3uriR{9NqiYx9o^9<1v?(k%sgV<HAhKF`gF=p-@|0Rk!(7mSE38S{WW7rO#<!? z>5kyj1eN#!C^HB2-;`pzrov|!>#IJE!vFX0;b5{)=|%G*<TKQ;PXj!iCW+>%pOb_& z4`TYA=>O>pm8G8Q;@IE?{Yw(uH-9DcmO2Ri<Bn)5SQO0OB(HhCgBOnA0`{5@QE`_~ zjxXp!sZK@CHz(kg-TyxS&DG3syZF!4no$MQB`3#>lhlmX#r?1O)$j4&=<ZSfqNHl4 z6?>`ro5+I$LvhuMX|Ji=nb13Q2{iA>e=*>sBH2y5$&9QS+B!W|p0>UqOV-)i;~;l8 z=rnV3b<+j^F1@6o5T8HFA#M=;r_%G8Uumb`>1LJwDx~@LAt-#P=KTJQE*9^ZdQ9wL zK)Qg|9ZL3bf1d3omshI_B&!p7|A&&Tx{Xi6klx)#i(Y^Hx4Z%V{M;cvDqKE;J9Ic{ zkm}SKWE6D)*+H&S58JSe>b~)0W{6rx_6Qf>R0y)d6FN}4P21ImNs+?xlFEO2!Hc7= zq$-iu=$QUAxvD?nfml-O|JFgr@QU1>OhJFqkKaCwEuMqqPnmrzOSzH*7vo?Q?pIF~ z`3?eYG9OMV<pwGS<VLg8{DZE&O|F)giw6YGae?@(6*^Eru6rDIF@Gw^Y4m}2u5`J| zD@*+Q89K$&lMUA%yr-LN9}-m`k1=FE^#mZY#xKaO{0#I{iJ7flDXaQ#diDekD&a|u zKM$76C;VT{lM>Gz;YFSc{0@JeQ@UF4=5Bfcdu2hB+7Y@+{lT+yr9OB*)`qGpHKSe! zb8tesftu1+qdMdd1O441Spk#L|24RR>p)3pohB2U&t?6N=aJN1bX$G;Rl~3Q|9{MS B>>mIC literal 0 HcmV?d00001 diff --git a/testcode/lib/apple2/chips.hgr b/testcode/lib/apple2/chips.hgr new file mode 100644 index 0000000000000000000000000000000000000000..c8302db4da7395d96bd34e637ae32930be350ec0 GIT binary patch literal 8184 zcmai3U2EIQ7QIp&j!>bop(Zc)5}~|^G1RXIUx=q5(^nZJ{Bn&=pNtEqDMTc=m1lnX zU28sM$#I%7wxpS@y=H&R-h0NQFpq|*)Iq4DVZv)Js{Kl>L}flfIM7<lm`}J7*J%~w ziuS1PbSbWrQmAPak42tcr#Y@=G)i-=6GNnNA1wvBt;ti@>N*a>QvAy`j(5M6Xw=3a zTl|Xi(^BIp9$J?8l}B|Y!L5vg1aE+TEUHMSi?|YHX847JNGFDORvqhUCF)5ft|@`R zyMzx;zcvpJ*UlldJS=`;CEuyJ&Z?OBXkvYEy3&vH%HS_MGL6$*)Kkn*HNcn0yW|@4 z%%gLBpsJqaQ#B39-^vhS9P=LNLR~{*;&V{zPj;U8z20t&{G9)ScE~DYkLvLJy%LIY zX*nM!1Iiz__^{VfRL5psDZYu%eskFDZ!LSRCe}XCE8o)+I;1Cz?08n~m8cGUPaan- zKA%gmOc$_A{R<T4bDiAjvDW0%%8z+Q1!VXBR*Po3nOf$>{!XtT2lZJA&O_3EdKkLN zVK(Gk@9{SLw@6EeWbyDD^UnK|JZ|(jH1f3aW1i5Yd+)e8t`6`KwxgOre|US5QD5-y zXq2EIvg;Nf*zm0C2<`9GqySxuj5qPw2bd#$bZoq(42Q4qjU_?b2=!wF=4e}`f~*pw zbOD($H|Vv+PcUxrqY>5$b&EMbh8*-|Y*2}8Kjel+`7pzqLeuxaS9tr|@&0d;e^B=W zeOhjMYg`dj!%#+!7y`o$88%vH>9c8{lKeANnN{~Pk_RW^Tliu1(#-QH&|JPPhgUbv z{92Dw+dZ85VTP&;Em83pYBcWShcDqL2rKgq%$y?(N~pAz)xTw~g}T*+@L2L;>E@x6 zRgca;j8gT0ufWnvnj6=9j-Tc`b*QIY8YA!vlCMYSh@OqTCMwhd;k9jp$Sp-IZrS#B zZla&R>Ui{78TVaV*U`F*pU6o4T4iH{J%}FX^>le<IY{+ahZS$T*m%s;e3U#Z`p55k zj-NNVtLKX-NCy#oXWowX@bhS$O2`ene_K3^A3POoz>xiihR_v_wu_HJqO;3n&?lBI z@dN$aYrii)UPRi9hROfpCPjcU?f2aJymZeOFHx1QqGeiQNlJBTrdV)XN73lCZY-m& z{G>_q<K6zN17V=L?0b&DUGf)&wSq9KIaj}4{k2OA-6C~#Y<Y&?p@mAt3K5MFyh^Q5 zMaT>fB19#xpht!L3-gp>JzrY4H70b+%!LWKCzhUKZb6hDZ<~1_B&q_B-wQK(D5`n= z!^G>@MKCNwHbzjW*|+1y<X@^5m4(2PrHbcv`M})9&80E>2t2{dWND}=f~$1#VRi}g zVIGiJwY5h+yM_Feeh7Nvvl8K*eldX$t~tPi6wi1M;Vm9(`Pt)lugtEH=sR*$Tpa&` zsZeE|<Tv<1iYSf>1vKU}7S*(IOV#R=nE-NOku(1Xkk`z`Wv-=Ih+wNAR~~n<d0!nA z@^fRVFP+hPU3}<`*gsC#)uA~kVVz%V^#MH0^04z@{`c5mm6!~4RQGwTUn=59CR5?+ z=7Idr%7>p|r}QVh!=>)+Pdb~$Ee-Rj_pmY=>$R091YKezj;=9(--^AWZRgOhZYCuv zS!U{zp$s9PyqWpjC)URm?R<_;JzJXN=CiM>U}aNr<ihd+FAM7QZXcNW>DNX!A%S1U z=*euxM#Y5u&&JA=QWd}&(pOLNW4`nvSZH2P3^9IC`(-CR4nU805;NMtm&p8U-~%y6 zO#u9pytWcvdWPT+?SClX|9yN<(7A#r?ku&=2yVR^P^2K+B_<o}yutdUr>EfzQCdHJ zfS@mTw%gnPL}c!ye*X3qZvI~T9S7QAV-AZ}C9bwOds%MBSgM6t%<a%c{PCd?baUcA zx(wL9(cV0wFh50S=|UujFGXI+99NS;R<Wo}l;`>i|I;kr-O@c$3v}xOpM5(0vf}FM z=XBr6t|xNb$s@A<OXZR6SRa2|f3GJD%c#2a)9k0qeQ>JJC;mOA{$a-|%sQ^b>@T#J zdgpnRm-D|KQEu21blEM#F<WAO`&Khu-5)6wDz!B{OCLJftwUmLVrDkbze#6XUw(}x zrsYFD$L7qnq78w*=hC&FjC5&qgur}(;L-IlRrD&9Gkh$|S<~uCKU5cZUFb3ur^WCa zwhL6~LTJK<-P-{j9)ARN2ce0Iydr{eH)k?1Vg_QdF^6RSqeEug`>_?em@xkbx}4RB zc--qTE8&WWO*dk*k*hi&N|_8i*3A_Ae?+qupOKAUgc4+;J$8cJQMDi9Gn=C)X7n^I zhJr%GOf3<)>;IA(88CcQ3seKd2fxtq#U8GnVE=u<evT$hu91B&;4@Q98@~s3^#af! z(+GMYzFV5xjop98%m~=Ky7?jqW)=3*3q*A4!Qf|%$jlEFcWPm&ZWC4?ukc0n(1@Po zQ&)KrAM}t5*8yq_xBqs!@aQJKr;Cj9L<SVJgS|4dFvFwz!hG>H{7(9(&T6&kNUlT! zO0?}A^ltI3JaA(y$dU5_P}u$N9{xfbr8skFEys!tnGlr+v~NDaK>?px>Lfqs+0Fl~ z)eN?Nx&k(;q7FV~W<c<Mpvyhyy+H;ZC(X17`}jl+PV<TNZpARu!)K-@SJ3Vie1tl} za(M_|IDgm?Bdh=@zo{w{414^fI>M?moPWWylo*}iL;k&8a#$w`DwMFm%V+qo7w|a$ zU$x_VtJkw2Sr9*?uK0b8FQYH;D$IL^Z(Ph5JXecw-~9m3G}u8ORBS3F^2@yaJwbbw zNqwJx942i?|0Z>hS-}0bsRq`*uTOb;3ZJk?l;*5Jzqmcl8~8u(pQq#0hmW^1DmEQh z3a%jAu4zCvl$RIVx5djSeVUFD=4b%ZF5m}ZwX2M};pV%aQ<s7K8}2G$EQHHeW~u*U z&4!RC&uH!A(j1}HGq}R;jr<=Cx2wOG6JO*%A?&z#o^)ciVTXlg@f_9$S<_?}{pgO( z`jbHDPB+*HsSkEj<VL&lCxhMQ^UAmxs-I|yFlwouZZt#YpBm0qMq<^Tz`Q1vJ2k_R z9dv^V@QwW6x+UhY_SKDDI)BdpQSpFk@qzP|*jja3t0Nn3=+CIyyr-P<pL+#GakBhg zAMEniy3s}aj^ub#M!#o^2*DHb>CE|~pM=w)dE`2Y^s&RStACK7`q=pmUvYy(@`f*Y z=JuLL^(5ahEpTh~#|E00ZiRA&-@c28>(62l84-cq2u@+Kd^Dn%X-Q+w-&rIrkH|P? z*&rN*j8>=Ri@l!a=_jIORwMt8_2UF?h&_nMmySO#$ODI!IniVc<G$4A0-RtXeB{ok z<sITR_TLM>gu;4lTzAPZW9ET5Bp3-%%_O)-{;v^<H;B>_MIwyQ!)NsaY(z+f9T+jI z7+LE(4(!lRw_z(YRspy<P#&Oi$Awm86;Iar?+0DL<9Du0WG7NE|3Bf7=nUUg7tQ3P z_nhbHAITk#coiVb+N@#bi3Nd3ZwFzIlII#ccgXb129<?5r8oL;bIIJfK6qk=+<#O4 zwADZGS@|G?`_Dhm_MZnVDdhi{a${fZ&Qvt8JN7ko(t3u>54K#!@RR--1WrF7x%o)s zf5>3?d3@LhJJ%K){G5kn>Wa22V<QLb=w$X+%7OZmXA8{~8@xnKP~@W8LPZgw@^Lx{ zSUK7c>{ZfcuklU(ulMS^avOvvp1;$Ez=a<gULM~7+aLV<0p6^B1S>&<4?kk&hQIQC zN6gLVb)r5XOt`ZYFF)stPK@K9F-r}tvtC#_T<V`X=!I`XiS;5@Mgy!Y1I&T)qoP4S z{1xlhtOG+^3Y=)fukkHp_xGS~hQ_tKo#*!@Vp;Awy{n$noSujLQ)O$#b87VRpNM#u zJ>4i|*LNEJ7Aj6|&@L6d+gyHe7yOL@f&7p>`Cae@{7*Q>TF^bn<)1Iz)6x##CX}5g z-kK$K*4KS}6w7=33B(+UBRbc5_%O@gBV<yY*l_cBC7lIiH)ohvxmWJCVxslGO$X0c zF0|wsd(>BzR1Y8jTp-+VSxc?It$z5uWQ|PJhMEhk*;QO=q=q*JO?TPWB~5#$d-$vl z7*31H)6Gw3q0;I99sC`}Guj=0j9!=o_$E2CvkT)bNe`dBquCc#`Ew5hs`u9bUP?^y wezb|=9ls5G70MaD#2<6M;(IpvAGY}Tj_ev<5(WDer+@M+K3#0mg>^Idf5Po?;s5{u literal 0 HcmV?d00001 diff --git a/testcode/lib/apple2/dhgrshow.c b/testcode/lib/apple2/dhgrshow.c new file mode 100644 index 000000000..147ee01d6 --- /dev/null +++ b/testcode/lib/apple2/dhgrshow.c @@ -0,0 +1,45 @@ +// cl65 -t apple2enh --start-addr 0x4000 dhgrshow.c + +#include <tgi.h> +#include <conio.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <dirent.h> +#include <peekpoke.h> + +void main (void) +{ + unsigned old; + DIR *dir; + struct dirent *ent; + + old = videomode (VIDEOMODE_80x24); + tgi_install (a2e_hi_tgi); + tgi_init (); + POKE (0xC05E, 0); + + dir = opendir ("."); + while (ent = readdir (dir)) { + char *ext; + int hgr; + + ext = strrchr (ent->d_name, '.'); + if (!ext || strcasecmp (ext, ".dhgr")) + continue; + + hgr = open(ent->d_name, O_RDONLY); + POKE (0xC055, 0); + read(hgr, (void*)0x2000, 0x2000); + POKE (0xC054, 0); + read(hgr, (void*)0x2000, 0x2000); + close(hgr); + + if (cgetc () == '\r') + break; + } + closedir (dir); + + tgi_uninstall (); + videomode (old); +} diff --git a/testcode/lib/apple2/gatsby.dhgr b/testcode/lib/apple2/gatsby.dhgr new file mode 100644 index 0000000000000000000000000000000000000000..dc3750e668e26f84de1eaf6a1a573d873e69f1ea GIT binary patch literal 16384 zcma)CjdvQ!k?)xud;@vD3>cEj?%PW<fn7A%(ps^k_e3PMxN(BmT?Y{cA`u|*tr9F5 z@orB*P8`g?e!uFTFC;madR9+=R99D5*H<@Y7W-!*<;Iv}$8jB}YHT^G&(!espA{Wu z5tc!{R?QLF;<M7Y>ia%*D9{>)2<r-y=7t~~=b%=V^TVzuzs`Zbp4PtGY0{{WDB}~; z|0QF2G%;UjlcQ?$lx?}&#>eFPY*+<vaz<1{>$OUL-?^!}*=UF=2CJxcF6uU%X0E!` z*rJ&S_`@DP)?A;R=9r~P@}f38aGsrB8y3@+JJH03hAGi{QMalHt#s}>&1~aY#GokB zP_TZ4Zdos0O^+7M94L)RxZJR&Y<(h7b%dP!&HSczvvcjpwXkJ^Ln<_8ynI2G#~=)` z_sS_<H|4(K@!~M9%bLMj&8)L*X0h)H_Aj_)U0c3xYzx+c007n8<k!udB_w`OfDK}& zAvWckKq*ykmXn=#IY=!8njyjleYtFZbHY-Bgt`8LI>l1I-x1=*$umPE{QI0yY+yN> zPJbI9Ig~wyzA;d$4*mY&<qN|wf<-l!TYpYC;uM8si^ys0mB2@WB%foB>sl`4tuc+z zcHC{H2mw~&qfRL7$fd#>%axq(iv4}JC}Ix9a%4mPQqu`>?^{btozk3-wZQzSTd-W~ z)N;4n7PSE5CAOAV^+fqV7PP5N*osyP`h%l5k6B{Y%Y)MX<-X%I^*~GzvY)e|=b&#$ z4aiQa)`yx?+WOY_r_mCEH4=29?yw?uC-=wu`G15WQA_vhlm1Eb{ySg>$m6Q%PjULp zQVMu{T&-!A#XcD0r2Xr+kL^EPok6Foi<;xcCqhFe`yeqA$9B5wyl{#}(WQM$ePqM0 z$36~$k!}-9)!$TKX5AaoqveU5PeqD`@_|UBURi<Uv{DN8&+-ZTAXKffiHTO#sSWR& z<dDWhy!cEE+4^giZy8(pB4PgkJ9>o^BC6m@!o5^rojI}I2#m*IvF#hjabD)ksLz5q zS*xfiD{vv~TWkB^yJwjFk(`^Q@qgvM(W<e$=3;$~RnLb`qpapxFa+9%tC}gHzK=@I zoaJy)TRI8<0~e=^IK&n>VAP9J>{x&J6FIWff7~&$myTQm2=_%d>xQ}k43c{U=TXg) zwjDGDEA3v-j~A0%gO*Sr_y~k>#&jrP1)hNht(R&Tr97P+yz6Pp{Xmiv_%lwLI2iZ> z)E_~-K8CP|5Q?RJH+Q|`wvrKOIo(||5n8e~d&PLAp2?@g_D+0`jGK-nto+ug1r~_~ zY5!6hA@%5+*xaV31B2f><W(PmNOoFK66fgP<$)7#ujT8z|IS24>KJzATso}cJ9)DI zSpQ*7aTHaHh=hzvj<Y>++<-yxh>Ng8?5>u>lV+8Cm99F+RoB09*(nS1i}mzioilQ5 z%V;I+U$EQH)lr6|lHXKwdV7f6Cf*f|3S+F0f|aP@xY>7EH%mtkMI>17jD17AWjGVW z0KuxwoSSoY=q&C|B8i{Dn}|=Hib$2TA~ab1B@#9^0En8@kg)S{A9+e-|D_DyX8yMZ zG(Kz4nHqNoM>l`kb#_f?s}_j-4g<pA8``DFsZubuJYG0II=hJl4bH@E5=*hOlfB$- zlBNvE{sk*K+}GGPI}NP+c<Z`a+9FS}0T$YZ*pzPqp|pQg8~V=c$U_RA(i#bONUnxR zS}t@-N_DO5f5CR0Q^Rp^{&LATnrj6%BN7WJexl<bZH!M<Xr-IWottU3m`^Ba(O2tB zY7i!^jzvPIEJpGcTsRgxcdy|gltQ00z+t@maLbbUXGxAuTTv_LAosjH$fu-B3A+6c zHstT3bxM<8RiC}Ng^rrV`&$xy06HtC@~7@~o^a@|wZ_Kk;c&zW4M~pWh=?T-VBXZK z8{SEw1%uJ2dGM-wyK^}WogkKK`1SunoX0-@f*g>sEyt-lKJs7K|2mpzvT;JRQFmBz zvO`25$z#wJ$}PlDUvV>C+%8m}YOAjCPQ%CPQ~pQu#nSgzIy+}uOeE|dz7r|SBd-@w zKQHYZPMcd=c($q=JgW+J8N!Fs*0yt2aj}rHf4=(SqmR@F{zl1k-`OhJmj}elH}N@< zY^}3mNan#eThd*4mZbNm{aZ<OP*V<_>!V$nCty{^><s+QI>V~WC<==d@NmApi%70^ z5(x2)3`bVe_|*EWu|GO#?!QXJUwAUc9@sxNC{Bt_wV8#t|A>4FU^}}bmg+O5QG(sP zzH~Be>|V&>sF3@4q;+aoW2KuL|F-(Q47fltv3J8V75gMf0_i;js|D7DT~lX`?S9B- zooZehC}VGOjUpuu!PX%Y1+pEVuW`zFFoKU(s!nRd+V@uS1h|ijL<mAA9~+xeD`*Vy z*T~=ImHT1rxTH>9u^lom>1^D8tVFhJH*<NqS7%+QS|B82`IEyS|Cb)faoTUz&h2T% znJ$&;$vq;;YeDyOr=(#L4#60L5kPS$tCFfvRT_C@2{${{ToPZRJ~}Vl{dP}kP7V1# z9RuyI;fq~(JXbLeJHYM0@oU9YbDgk1!9Ic~A*nu5I3H?D<O~4=f&YFA|GK|3Ir(l2 zs|9;x<7&hIZ5}T2l;~P)y<SdVh%>UrME+q=wwBDVH<+;A>|fuzIinRH7g#Yu`;Tx1 zb6$R!>>6YzjfL#CMwzuwnZ=gE63EV9IupN%^%M3_^0u6W)MHs|Fg4uZvRFUXPbJ-V z(aNf#LA!R}IS!rF1VU%UF~qRSu$rc&kiEbG9M+n2M*$^i!E)Y>###&>@H9z(gS1%O zE?+I1FJi7Ztk2rsM52~|UUJ+q_WyUK=62<^uUp3gLlpF_rQ__Dl&hD*q=5($`;Yo$ z1^4fRqw1?%gNOaN`;0%A6i#KAy4;~k+a^%<&z9P2$2~8>{(%gczs}{cikztMk|o9i zXzB987PPd+{*6D{Zd&qwjZUbyu{#A1A!x=#`4kcM1lpNnpJQ3qf#}tu$8R8*r`H$p z`alV@U36}ha!#@7G;*N@&?0zOyJZI1LJ@z~o#WiCoA)eR^L<?CLJ%T{xPkWvcsfPi z1#(S<;~U>-{YU&+$BWyI_$%i<LVLM0xgQ=}&Xs?WILLl~{H1(xkf$yx*UqWq`;L>@ zc>iO!c&~}pS6s!~*1U(a*a;;P@f@rl<FV>(ZLm)-Jj_t>hf(~myOz-kXzm<MmpS&9 z-p&&CZ_<&tJfgf=c}Dk|X3J1cp2mbk7|SwQ>^iTJgOUHCG!MYn#v1v5itSOxjfp$2 zs?OrZ|DNiIRRN?B(+sl8#~>KXg8y74)vyzzP<U<A{%G*1;q<F`fk6DF^=-#`$8g;_ z7DiTG87^rjIf^3$N^&)sj$7~CbJhE}bZaaBcKUMj{Y|JF?k4s!SIQX`#NLlz%K_*5 zN1wH7h6@i&u!J^#mr`}CAD+1CNF1a@4hqgn2b1Y=;e16=Tp{U98>>6|sl>wlTTtcn zST?bK#-tkJf0N$dTxD|x|4(=ynTmxx1o-rM8`pIakBeOCaCkgfxY?wI{^;kRLvA=_ zFM|nq;sQIxun%9(a<~(?j)vGFDX!l@F=N^xsuV=h|7Am81I^eg<<4@YU*l~(I5&=I ze(G0aW<k<QA|EbuuYZ%D2<tlet_Gc}8+dzhV%3G-o!2r-YT@emh9@DrL}EZzKMe2t zxXAo}@aq0}dUN=v<;#Fi;E#QCIhFT+ycmJi*>x^&-P}5dh>OdJp26w;ExCWNDWYL_ zXSzJDg;E0@0zr8oeZzj#cL&bl0+ABcz_`YEe;0YYNYe`q<{aD{41Z;`aRW%&e~Sox zGXCY97bUzYs7H6g3|<!=+dp!fW;KJ?X8HaHJX`}1{}Epu7%T+nE{D6{!$&qr2?7@d zG!m`#y^T`A##?~M=Ev~iS@%O?r-I{6CPWXv+DEs#efaVmcz+`M|K=Ix|GGHQ@;bd; zAw5RyFO?glGqk2GPIQLoz#XCDa!4%kEnVO2)DDpUM-0eRJZec)y2G<&PGsFJXysaM z?y&jeilv5G5m37?Hk?dwfI*l1&|D!ol1(AYs3_fE-rp==zLthdy@q8JZ$B5PDW(m~ zr2uQO(EeRrTC>A;Gp8vxcS<|fG{#??NiR!N0nrX5OR@hI&<2Sh3%yjmyuP`2&y^2V z1NTS8j}ev-$g-p`F_?J$V)=#x1<lKhl;&Bh``}j=wb_UPjESUNQc;$Rw|#hQ;Z{p_ zQ(*`l*vpK4%~~#MbZlDXW1Cm-%DZ*wPoZ!Cq5fz}-Vv>sc(H;zIC_&n!i(1@T#+2! zzL~D8r^z0w%cz;`g#9m92aeKiH84Ig=y$FLBa0J^{m;=KT;^_-rkT}=;#1;TPyGHC zQMSbW@%GJqC@Zc8tib*goZ<np`u(AsBdL)713n`D8+d<_+KKk`=KeV6wp|cQ#(#27 zVN{g!l0~ru4-Wg6O0Nb;T#xgAQGK`HJb1YU#}vl@6<dK53onDxy1uy|&W{fU%M9sb zVE-gnXoKY>><^<6;A!haGlgH)qH#{L7uF;~kre@NYh)+;GXAUl-$b5+2cH|<AOx*w zRg15je3n*}AeTY@53sJIUNx2|O9#Wn@ZNcWQw)G(i?Q`kC*3DBc8Aw?&4DeDKL^yF z9q#0<n*4o(c6kp!R+1yCh)o{tg#VW;MR+CWxHhS7M=!t_5Y}xLhrpPmhP#cRh7eIs zq!EX3e}_gsYiykcQ9@K5+{ENW8je6vEwO$yKoz_4-%j>;>E;><jO9)i_wUF`C-CS{ z31P8DH8>|)CC7@Iaq2o*1I~xw;}Z5SLjf9_yTsfW(h+5xs#7(y?u$}3d{+aS@SC}J z%%B`dp4&Hv_=Oj;bq=Qqy++c(;TVyB!1_WcIe1SG8{t>OdeQoL4ErZR$5BTxzbH5C ze!I|3t1hB<;qyhBg;=I}wRq0#hIckw`F=T?smE(mpFFx~kg>a-x9FE2_9hTimG6!G z>7x7QZ<T0>pA;{AkF^=&w(MN2>^w8eoe}r_#A&)CXa$d^J*arI!L08+Sl{FWi5Bh+ zjmDMtK5d)r&lp=3<e=++w(6OU3=8)9X43O6_}vVH+>fNpNm7|Kms1`T2FvpTZ(s+e z9&rFnodxSB@c;K}Fds}BWD-7jV0G3ljIm9gF>Ol9nb}{|rv1sROOwV_0B~A5MBXmM z=MiZFjhmb;yt>!<MV(pzj1tFlPc;+e!1DSN6TC8?bfCmK>~6$(mRC6Aw9I+C1|6Xp z(dPdSOs=yZm?ce_#vZ~K)5Yp&>c!(`Nz=`U0-=KfmCz}JYQghstIO7!$vqo;knnRm zU5+;wbOs8i#{@TaW|{@BHy=z3W!e)Kp+9r}Wt|$5m}v&gaQF}!W}FN9n!4rjO55~w zY60fW4zw;hN7Wg0e9G!t=0(r6S68|nGYA2je;a@eNr5wcii&M!OtUe=`*sLi_e^ec zvmCC^78G=Wz(bVy8w>Oif3TRxOv{-`Iuozl^H$!)m6DU3F_@au=M?)1IAb2pqIKqd zwwn8XPj<>e#D@}hMzyZDTzRo}KFK{HUrd(%pnTQ^F^j9&{^`K~BNP!LqK<~Ym=yFz z*&MJF|6ddel`d?#!sGTv&EA{A19*C@e;9@ZDEm*$YIuc7+D^A2zrg<MBh5ds{=<&! z-z#_pdp;m$V*6)BG;RDn33)rs8g_+~4&xs|nq*tQP>r~pxA#WNZUvP13Tj5ymm1^u zH%v3+>FVCPHyd2_r7YhEN2)wk-A>mdN<6BelIN}I((@)>f<wW?Q}(~Acs<X&#DcUc zMBYiw`^-uQ(q}x~8I;XUPYP^eL}#DUf5!K^z4_7n7dFuZ;CSn%l$mPF5+neye@@@P z{@YzRBHipgSG|mXS-0vYSGa^1fKFeMZvf8&(a2_=^{2~Of9BD-Mlkm{)#HL%4Cl<{ z7al-<t&(0LD-5E<oqhL|{Yz9s&5-rvf9^7E=)T?eET~)rme23{f&CL(v$W|I>b7aW zA1#UzmdVa58F+<E6gzwbI@5>{l9ky0r8ts92mt8^omiB5lD)I#w12f~!v@q`8e5G_ zAJW%=S)typmvJvWj}4Oc&n>axan<y=^t{z*@DDK*ZfD^S53cgiFOCjDol9-y{~Ots zv>yKF>Bz^gQDxm@t3>|6>U}VnJYJd`f_>>NMxGt{(6C?q|Cc!aoAqvbP$-!m&S|Cc zw>#t+Kc%(bs!92-*Y0F`(({og4uIp!t)wi&5q$G{+CKB56QmKH<ZeHZ2xoU~Z+djq zr~^YLH)Q|sv5aXWyO7lP7X7Z*8`wldPyzTk5D=?{C3|I;#FaG^re2v0x)<Gxg#V-a z(%m0I4E5#s?=@-L>zTxtw142F{ShycK1kg)({}$WWJqd)JSA07M`Hb8JVf(mN26Z1 zP>;Kj{Y3Xa*~=B3we)P*+llNw?=invu~#yBan9H;?Fx2**>ZTZsKlLK5+Tno5dC}e zLd3TL3Jb5KVSYF#jLr0tt3b)n`i$$m(G9(OqkIoF+7NGmj@Xp!j(n8Pguu$}UfJZ8 z2$xxi|0mJvxYwTPBM%;+d^hR^GT^}0&voQJ4IX9Ss}a*9+A+D!T9Oet!h5p<-^6*M zHSuNzuYc8_r(?!eJ+?;1A7Q^A*p0z#R=N0LBmS32XC5sZ%;JUFV6jN#Z4tExmHcGo z^}D(579yk~##hCae~$GtilxeEiT5}&#mN3s@$@>@kNscVFKfI9{Wt9g9#H4;`=y$| z&2Hh=v%k55c?R+S?nL-M*AUr)Gda6Tf916y6rPO#I_WabNs-wsb(Y8Z*FD{|Vh2UW zWQx`%Cez2|i<wtWlby=s;&<#$8~fbEgPg9s%h|;9F1#-`Bn|tA@wq%5@c4i#SiM{L zBX5zkzdDfq`urg#`(xU^=pwfY;(v+FG-P@0bOu^T$UKW!cBb?%v=i!={Fs8OPeA5k zzM3q(LMI+8Y5YqyN%e)6F%QnPu6%O~_Rmdw54Izn92=DoiOuBFG0n(E=&dUD>bT?Y zc?YATktuH$0lw+~#15wtImixVbv>4$hF;4!$D!fAEA<a}@5?xtPprRj{%Iqm&V=sS zo_AE%>xyq^3l{Uuy8+8c8ITv6dTivKc@=NrFXFhs**UxhKSNd$L@y7g&G#bO8x<b5 z9?9pjKlOs8LL7V}{Ge}gG4v*j_R**iBdvaKQT#`TjnZUqSGmq=;hPuleP8`VBysCU z_z+eMJgT<RxYe${irSy_6rFj$hy3$B1k{pJ!ZYA!E5Bv7KwI)Zp05@ou9tD2Stav- zfhimEPb}832i|gq_#1OXqb656MyC-#WA+QL@1;F0%KzsB;df2lkoFI;cDg3+M+@A) zb(V<#bdK#$<==1UUe`8xVqE^1=sr3oQT7I~FB|O0`}d4>wD*XF1@y?<i=OtpE8IW= zex*n#{)3x4-6X&96zHAFV!k&aDj`tS-L!v5SZ@`$SGJ&kLdAb`k;3Z>UN%e}G6AIP z7iD;Z2S=@%$WopLzK8$Qa<sTejO%7y-6=!q!^1%woU&^IF_NG2pRs91Z&ChCdt_{c z3|WqBa=@vt64P&~bVXt2IrM6{!VNoIjQagJ9iS%mjKE4aGZYCphu&mbJv~@o{EkkY zIN1PBEnAjU1LR_6Soxw|usyp$K9tU!{w&}6TOTolaEaW^L;SDfZnauL;vtZp0Hyw% zM@ym!ulN8s(U7#{K;^+O8>|++1VhnqL{;|uxVP};tE&~_e+2%18um|frAOu6QM)r3 zta`AEg#B}uVkwViZB|;1p}!bKo;C7}#Z5G1%98_c^|d^hcAyBpwi;P)>Yy#nx8a{m zm!{Fv%ldsH{-;Skk9Hl9cQZ4X6~;xh9w~w)l>JAYu!u>)yLfAorwZc#d?fq=olsec z>Sv4eRRM2_z~Jk6CdsE=i0v;CeJKC8JiIE{9l}b$UlU@cZmdx5%)h)%6P~nx55G_U z8J2+D%}}R%*2Np`#yu8yV(?;W9jU$v@=?`fhok-o_Xe5p%5J>B$vb$2Lx+bI_y~Hs zh1~`BZwvAFh0ZB+!aty-p`mzxRm{Y*W&2b4m&x(|HtfyMl(x%Rb=W_rntE%e&?^;q z9NPa0M+a-|u^z9ScQSAe(gTe+d9jDf6Cw0+`JrM%vL@b@p#L6T4k82y_<0=%8v(on zrv?w-<kSd1#~c&!Uk*YpUz7byX~=J~*w}yajl{#tLw(QglmfOi%tHP@!@D-B94qMT zw#V?YQsx8vx0<ARr%5pI9P-AfR?}MpCAFj=KtxJRqLAn|V7~Bihk6LaM-tlJu)kh< zJ-YvgqVfyp$iF$zAa{JbzRlY+yb{9xe;QAAM<7NRPeJ>Qe=s;nN<?CDvLd1xLC0Ht z)h}1<Ej$IP!x78W>i1^8#B9(9yqS(hBi5nl@W<HxIsN}_lH-%m;RSt<?%zBbmiB2s zw10ix_1@>dI(rMefcX3mcz=g>in2Q0{h{YAx(j-(Wpg?j37j_3PQI@N1Nb2SXJ!{~ zzZvzS5Rcp?^-p!<?!6qPTM&wjza8dkKVYwEL`M=7=jp3oB<|mGQV<P(tC{tf_GWE1 zKbZ~|(fdCJUHn062~g7WGoXTV5p<r=QrJJTKSX>;7f~P9XSSuYP0U193WD>fGp@<5 z{(J?WS!k2~EAP*l8|43Tsw@cg&p1c=>H|bR*nh$7WlRsA)23b=i*14*h0bM9Tu_V- z06BYDh4t{g-fF$<M(>8$nvPek(w8A6;K~yP-4<(8J{5q;TAc1aW!yT{qOgA+8Hef$ zkvCfBmAHB3br^qB-*|s)`R4EN%oQQ^Jhn%-OtODv7ev;gdxvQ@o>#&}@NIZ>Lx^U| zkuWPtpe3q}5&ZAt-`^e@OzUEPv^etmqxhU)2cG|BVEdq`&!CRTzk4&5jQ^~D0-<h1 zy~Of%ce<J`ysb@^b(wQ*%xZMMXwTlZ;HUM#{`rZvJirOEI_Poa-}B||K<^CDvSRy} z{+{cb^dkoH_Lq9cwlE%Tm^R4doh8DeO4sZ6_Pnf(Du^TKvU&MEeu=Ye0iQs#SJOea z-#elk0=vUs1Ul@WcvL_XBEYXpL*)PVo*k_Z{nOd}3Hwh^R?_~}``aDv|95>ohx|Lp zZqjY9T%h0QVrYR3cHT+mzws#5Y;U?+;CGV*S5)OR_5gf6O}E`J{-6Jz1fgRly}w`; zypDdA4#I!D8$~LigTe1binz}Ew@1^1$weIm0x;N}{0)WWWFM!J<4=U|Z*6&|_+KA* zw{7EP1A~M!x3eJzTAL8Q(aYWha}9m3TbLYqjZ&f$`9JR8JfMJINO8VUJI>jlm(XMU z@&~PH(fvbB9wGkYG#-HLsD#vLFp75Ycik`W+svh1@LsEFv=P|<95F+6pqvbB=tSlW b_P<ER{~}>@5}E_j=bguwc^mTKgiG*$(iM}r literal 0 HcmV?d00001 diff --git a/testcode/lib/apple2/girl.dhgr b/testcode/lib/apple2/girl.dhgr new file mode 100644 index 0000000000000000000000000000000000000000..af332edbe7c5bde96ba79dbfb8661715a35ad5c1 GIT binary patch literal 16384 zcmYkj3s75Uo-cT$h+YYD`|5!#W9%KFNHTf{$&xG!0oD~+JrHdabg(2OI=UPskvKYI z(MSuYK~7ihR%cSTDv8_UxII(b?M*xr<43i<m~ms0-mYY8g6-bD={9bxpxo=*cxu`a zR6AwZgqvo6#|iWtintuh=X?GCzt@Kev5)5y`y{?TwZy0M8G?qmlV($;WX_lqw5aty z9zirpg3{e$f!OyQmhemWxT%3uDWsrF33qZdS@dw9cJ7JnmHjUSF<vfr+Tu<l+x~pY z8FFODQ*Az3&}u5g-Mx&-885^oJt{$6R}1m&Bj)iA`y_j<!Cba2SxS{OZ6lVHJH=9? zMqAL@WAG`v#C~fJuUkq;J>|o~oFRozrJT!O);4QjRc9-k?{CyLmS-=%Wh`_F2tm1n z?c8Gxjv5tlXKIwT1`6HUK{o6hESVh1u}{yx_g`N9IU(g?Ro^^5DOTUNM;9!_U(VVF zOK}UG8+1}7+Gf(}^hQIsv`#E+=^4#BIy6FYz%a<t7H)r*H>$Jq8@09NYt`B1QwzVi zFdb9~2%fk+#gr{=J+`<lXc;MloZ**~rLfI!ecDQw=+edM58r(CRpHL+38IVVleE5I zv?K>o1?;4ga!_ORgh?8Zs^$I{)COZ)zsx7?(vCPy<0fZP5#N<^q?|d&=c~(`E1T8L z%53E_X7KRChusE(?d%&WV+I38LogRIBprjcerKItVD%RQx#UD#zwocGe)8)7)}i$Y zw%0F6`z3L0oDDhJ*%XshB(b(&T|j4y7}G(#C9bHGH}VAfp+btS%{<(!&DJ(Uj+}$e zg~usW3Vy#)`QqYqKpTt*BnOU7mZ!=L6B-LSJ0|wF)U^m+5WEm<+pEztDRxlNt>^K& zzAs>c#qII^Esgr{XiAYXP^F|h>K;)vw)prs$nOjL;?B5Dt?>8Z{QJsm`$X*;*1NHM zDr$dtt#<js?7}9_VfNm}=d-u2EWCT+O+ibjul(fM+PwM2y;J7>L95Z3bOuyDCh2T< z2lw~aiFpEESIb}O&nN9E7!RR>xz&%-xxFoo#G#i64K4MJQl*qFxZhatYkK(Q(H^FD zxAtXqv$o+eR3Cl*=mJJf8N#{V!iDLNPu{w6`~UDs^mW+&&T@HcYx>&4ENuyo_Q;y{ z`%B@8aDg@il;R^@VzE>p@vFAikIv%>q=HCmuANONdTsrN{+Fl9WsA>lMwOc!rd)TM zTJBSonV_O~fVL#tl57^$SNr1P?9zKZh7p4~cjM~9`JY}{c*~~~w3M;?494I3;KFpu zHfS&!;yF_>g{}!}{V!ltabt^6)g#*;Um$Lj`fy5WLs%cMnTqYl!d9b!cAKqnt6v(h z;v|RwP@o4j+eHi!k+EPdc_?8pvMCEakUB&;s~eTC{y4qx3!_v{bY(lI$~p9sBkW9$ zCv(XX>PM>^7<8K)9(UXjb_Q*}h=50kcgAlKD1|LPL%S7-V+a|-=u=ZE>kL~oS<Jl< zkc!1VonAV)OCZTv40%s6=`>lA?85r{8}FkQQGavQ*@fv3r;R1<rNEzZ5O2bFA*jHw zGQZX2?68_GK{n66bM?cs|NIG2hedt+2zY`Pfz)R+ThLvM*%~fz<0qZQEdIVVX!S{m z7JrLRAI^mpK**xrkeW!95{8AV=)T$N=IZ7L_^#bu_)||C2P&P+6w@h-X9u%`js)g8 zf*vvM->VJmPa4AR3s?T;&9`3>NV!jb^XwJ~Tk384g4vn0jFd137U);%1|A1@X`JC) zP$tm%>wIk{8mQ+87U`0QF_lv6@@93Tx-q{|{R;Rucl%nnt;Z_S>3L7e-)*uc3r4${ z4a$0eJ^ugLvwyF{=roO9IPu{t$B*ykC3hxpnCFZ53LQ+lE$8$&vp^u)AdvV}fwsn7 zt=6P9VD&vKQ2IwL7L(&5R$N)DUK?SDSYy#sN-+s$d96D4o4I>eE?m8Eg{KLyliUP4 zhZII@uoSRj?EQXgOct;XTEh-gp|wTu9dTWkRB&i}{qkKs)+`Wp#E~?NFdYL1Ntc*k z$E)LgM<5BhO}emEt`SK4r9<|R6WxEUhIP|yb@RfNo6|R@>GA4Ux92X-UOe^b)rDV3 zA{{MgzA{(;7ao58RouG!nPhHHVNY9=BV`K}f)bo|7momrOLxYX#C4{ei47`fAbXFq zTOJU11{*~kEr%^hhY1z5$KbQ6`#KFK>%H0KYuNFt!{fEN%H@xz?>safYj?yA3;(ci z^__os=RHB6FVe|A8UKU-=jx4z@lo2cSLH)L8Eqq$q*WmE*ENEqc;81=ef#M88g;&I zzr;6|aHdM0T-YkGb+W8Xz{FXajoXZd9@*2!g1pYM(V8p`0-Z;S$%#vsFJ7)b`pt=W zF;PUFIg+D2hP_gOw9Cpcm_T{!&s$sPub7yWGjYu9h`Tus(ir4oF(LMK@#THKo%Q=A z=x;DTPG~e}A2jrg>T?OyKW#A@>gx9D8|%d4o|YbIorK`2`}jo5%O)$wzi~x^W9wX! z#fePcesu9%K*1-7BW1R%Fe*lziR`eV-PVis_}h%m5PB=+pjorks0I4f@s!)^_lvvg z8zqg$x*fq|S+{8{l}qJDTuC<R?lpuB-3Fi|;eRH;%jW#5#FV=;%%<|Rv!irlvvv*a zi?8b1%9quvx6gJT!_M+>_}D39VXrl$@HoPwMxD_xQW&(*ZE;0Xar@eZH-GYq?{L@l z@PwZ@e8h*wp|O(G1kJ>qgQMVgXUG<m4=UohK}qATMyaqZ?mVRTM@%_mk#^GKbg6oI zd3I%^He30ic5Qj~#?=caj0UN=>je&f$_}6@a2dN~P2>``z_D(tpfBW16n^vYcW-@o zyo=fyp6J5*TXln+>MA71v9klo60P%P`nATs9%;X|r!8(3v=EA*EzYhye1EQbxw;7j z;;7#J90~|*G+X-$9QcKCf80PwgW@vFq5uXhSzA08SMAmKwNFc*ZaJE(bI{Jg!ufM= zzwyfPE}|^oo`Fvyl;|y#6YR&P*rbAD<6}@nyBZ}vNu6O33aFk!jqDmK#B<9VE9+J8 zeX=yA2)VOt(wSm`K6mG@-J1UBZ*QL$6nqm?Q{^eP{K2(*(-&tO_wS7atc{UDNBs*S zL&6!fcFX)?fd3Hzy)%BFTAyU2qaoB(!WnjkC4xGFV@a`3(_S3JDtvu{mVl;gXwR*j zs;<pnTlq4Xn}2lk@~4kJ+DIzyd{KS;>Ax=g;-mBbJT2gj9K-0K&#ey@t}L9Q4L#Hz zThD&~{vH|nPhmve`@v#|Td<?wJ_4~HJDauAV{vN=6=0P1D<{#UhCU<eV8pqnt*7AE z_wdRV^d7p89*>&Bw&mH+AKhEOc!hQca~kKxE9cMs-O2xaqR~;;QtspsVC&D*e_Z%w zYCK-(DTp+2YtVvjQ3SPJVuA-Who0UZANo^zxWy-K1Vguvr=0rSpku1jvMYGV<VYw| zmS7=h_vKQ&^3<TA9g3P_L(Y_<wo%($IQ8i{qoLiFvW?)J^jcqEtCRr$qX4l3EaS5b zI_a@?)boflHJ-8zw)lC3pbHAXFYVE6k1zPn(Fhn&Wz5A5Muo|4ve3@3+nkHHX{>`1 zpA3J85LnfRkG32pCcYy%^21V`H91GvOKY{wW%K|z@LFx7diT~<V}$4uh%vquxH;Ox zCas}tzk4u;+BPIhz1D6fRf-#e(nc{Lc;^vF1WKX>x;lrM=2A9|HC#j&Fu4-C*kQER zAK@w0$BZo|2Vb0Jr<e{0ZA-EA_{Fu#=4aR5pRKM}(0{kzTeuP^@o=^*+Ao;fV-6bH z*<QB8TyG5)qLu`ke7<WU>%4Gv;lCaKnO`EtHhlBo{H20EV=-toqxuGIv?XLo7PC3M z#Mc(I4(fw1p!$`5naNDsG*Y83?o2R1YRknhfj*nn^{+Roo7Gd5%M0iAZ6QJ94;VDy zQ~?^Q7`JA}M{;H-t*hJbf8MX^U`O1`=l|22$B#F<8~>tz_&!OGMh|R66>_-Cnw<$* zzqH<<*S1On2KDm-O{3CpMQ`M*Gq>+9Z$6w&6^B^LnJ9HQfdiY>tACijc;08|v3B(d z6uBn_ptl-xVMEv&i0m!2?)Mj-*7$SriJW2Ktq<Qk{{Ir<@~)lr*B#biojEYSgJz&@ zoMG8+iBaN*>gg#2N4t;p8w4#qR>op>KRosRT5av(bbi89!dd0aY|>HNyfb(6>cuO! z{&ZnlA{CS;J3CQ-f1bYh6*P&}*VZHR@81U%;VBy7$r_(@HzDzNZjV3M5*QtUQ%Sl_ z=&e-Fh;9&wi6eCcPa3i%ay`&B{)kalhNfIzpNHRD-bgtrbDv&WIraJU$Y||yZF=GA zh2P%#VtKK#<%iNT3V<!IZQWbDI2&^AwFa_+NRKo=mY6V?x-|kN(8nieIl9BYeyLAy zv?mqq?iAy3nw)hS^!m#!k(8vL+Y3Wjs#XM~0ix{GJ4{868BA;kQ{A{Xw{UggxA77U zkNWAuTMsW>{q#@1ae<WMUzT0l`s~!jFHBAoqtWyf!le;w*d1^4Ne*-Ur-a_$8NWvY zRVfxo4!2RRkTZH{k0WSEF!mPTK%5<6y9;{_gQJ2&<-T%f&>DhHNjchWrc!mTvT<Sa z&eix>?>NPn$Ah-8A*ko~@iZuZ&VVrGLjkMVV0MSxCa(HRSev2|{lSCY^|h&Y^nYUu zUmTSCazO`>2B#Wl2d&V6P@$-OiMr4z6$pINfFKA&p2!O74zNZ&oPX}qFRPcqKYzlR zY%FhHm^*ncDCLR8%1);IvN0EgS{k&pD@@SP&_AWr1gB;O+b&%D^dCO_`HuKT5%^TT zdVyYT4cdZ^Zs&-3&=R*%EH$1y)@{)D1r7ameyBBd19;#&CUed)m`gG=5b$?T#;-kE z-dx>S-uTTI7appQLDd5%I~ik}(Wcf03-suq)2MA%gxL{mPmA9c9$&b)^tT`Wr^dR! z%s|ZR68Kw!2AZL>=sjqf)M$!HS%WX|w2hh`+aU1SFRgcsuqk9CK^q0`hfZ^T`UN^~ zwz9=B@XF?eN1uMtvulXUKREfN7=)8Cu_i@|b3yy}7WQiQ+C~&f!@Ym_$5(#x3a|W^ z@w<))(cR%(GDkbWz#IZFwAC+Bw+%|_a>2H+Hi)_ryc{kZasu_gMCz~>Ep;fu4xk|G zDRcgNdE@rgWFep@9R3pEpP4FSeA|J7{{{au-Oq>$Pg?_{e)k||rSB7@QGvRS61M)y z<45fo8O+rYh5yc#C`Z5Ku+*o5mes3qiv0?o)hBM%ca9F)t2pTj^mkHG{pydipU&0p zc9g28s<WTtR2NQtbVblI$WE1}O3>e5EKI+@IhYRU1J3$m#_V2guOX!f8~iFC^shkG z&u)+Jds)3JRHAcq5$vj<+`*RJ95#MOkJPE%2|tztX2^r8G8|`htqQeK{bGbm9o8<a z-`s#Ff%duhw+mO^xpM0YzwU=NPJV%Zx6qH9?S+71?|wL-Q6o^5Zc|GF=sN)qh_Brl zzi;;oK7-L2c4Vy~mIB^3ip$?^d?~65LJOq|{i8jSV5z6B%nlk-Y{EjZsH(P=FMo6G z;<f6zu)f_AcYJj9r*AHt|L`rLy^G`DC*xn9T{xdA^}>P275xQZo0HaeONB7eVxIp6 zW82R7sz3{3BdI`#lXucN<FW1+J+8q%6H=a((=*yFK?O27QJK{^N9?Hq6B{z844m>@ zxN_^9k);($q$DQm9yn#e{{;T+!0?^;p6Z6KN)}UN;Qmqva4RSkVrRt!@{|^lVSD_; zQon>JRqHtRH@Xeh-j`D)_+NP7ZksW;XP1u$#EAI#gAswRqd|To=g7f*rW}{xy-|y^ zE3;6fvz05ieqrSLkC>Wbt=)#?7}O_gg6=WO{5ib=julx(j#;>R{=E-R9{xA{-^k-B z{Zcsnm&3LZS7Nlcz+r64nRO2WJB)BX#1Y>ypQ_iPk*L|kE@VQ^<OFi3jb)^Nz#!D* z>fDX#3+ID2pxY6wyxjeKP#2JSEb$3*F3Dwq#VB~i2fn;@^`oD^dfZR`oBTluKO%+O zX9t}~Ees=Wno9x<fn7+3tk5gqf1kwvOxTbt8jFW=;nLIud=*=}T=^z_n62DJ8Z&)< z+IZ{`>_;c^m$FswXfFnHgA-93l0<1>e?S&!F+pYC`o*nJe)Vc<s(X9;2||MW#Skwd z)noHcic{6Lq@?i$Bo}Qy;F!_od*1h*Mvb{dvz(@$Ut67lPKOH1Dw2*NC-P6s<Btz} z48~D`wSOG=i?c_LV-BPC_gbHh_*;%XGpP3sm~m=7Er%sY^U8;I_{S%W!P~@<BZUn> zHYoaJi?8mm_%I*ITrmg@Q7;8!SUZ9GwaY8lKHsR!Cb0YPeDDGxw)WNSyZ64hck-uK zZoMTSJ7{kI%gp9`pRV7#9NN`0YJ~a-+XAB|D-@0{DB+I2OVU-|-T?XY!6MFS!fZgc zRSGNQz}v1qVpmea(;x*>7&T#Sm&7P#9dRqtp3UknmoK|Z)wP93_paXi*Ay}(lV#!R z()4@N@0{=xQxX>FH--MMJiNJ{VuH^E+Wh<X?l&6HCC<HiKHMZvDX8n&(cj2AcKNVA zXfJjI2}`&wkj>>)QwfQYO<0lHSdCVnL=FFKDj*l*G7k&f-^TpI52r7_HR24Ff}^$R z+gC1par;ko1%U$M2mHIawe|SZS=5ZeG>YUy0Vgnl^N|X;(iaOff}Q@`BNK?bx&+Fj z)_%5Q9Qs$$4ZP`=#bwANa=n%wo8IsPsanfSeJ{IjAa08q+Dq|bb@Tm)$a1C==mqQ? zgYGr>BweB>`v1uhl-d8;rgvm*z?6~+j2X@uB|eV#cs!|Kzi$VB1YJ=762A?(zs%$q zu>@_vltU@!NY123{yrLj|350(OLR+ii*uG1-6WLy2=ejTS_Mw*4^Q&Y+LxctR!)Uq z=3b7$6{cfc{%$NJCC1U9c8?W4#2G9mOD6Y)^A}FM{qx<@uI=L|4h#IeuD-+2M?oa^ zMmPLtjvnI@xNe2f5>%*n3F>xBbOvCV)YleAsz*<BI1>(NZ*V{j`S<&?%Ns!8tAQ-R zgR_PDN+R_QI)jCjBI<?)Lb4RL*0sbYX!pJI@0|bDD_$9d(6^6Y+=zr`58jw6no3;q zkz{Gc+}GF_kQ|0~(J2Id0;RwjN6r(<4ca)Diu@g^Cu(4}`qlE<*R$2>d&q(ViuPS< z%M<Sf*KEwuqahnudIA~nXirNclFeSry;H9q|M44TUH6XuZ&dmud#oB6G|w(%o26s{ zE-B&zQw1Y?w833_cJ<hW;x5DYCPJLnpM3}g%;g^`D>$V@7da-Z-u?7y@L2b*F8y$U zTR$9-Av_vCCa^xO@;`&r$qEO86>6+|<c(Ojznm>>uV2_A*kydV*U7yt0Y%Ym6V&+& zLY@G+pxe@J#SM@~B;6}7I}+o|o6B%r$lnz2Z(cy^So<=ixHmh0?cyn<f7AD-c`X*n zH{`Q*>gM#Pv+d8skm~NW_G|swLB@0pofJXdLv$&9f8qaKP(BLUiItbk@V`JPUgJx| z_c}CCMMaMj3h?<xYoM-t%*fuGt^Do7jZ2#;_sZ<@+=Xiwu2PO(cieXS+QM76u6%r@ zj+g-d0s)ynuU)!wW3$_BGVFck>6V^jq0tf6Z1BAxkP>3t07(7T?e#<5weTc9eK6NP z5ON|lmimsB^L-uNQgCM}b!<=($OZM#|K%Q3adN`L(#|+CuiDk+&D*C;h4yii{`S@L z4?nu{yEoBC)+g$_yoFSF`C%5AGves6#F2uh6d{RE=|hVMR9vpUGd^xR&^AQZ%ccUY zpe*517`G4_hZ!6U9bSlQdZZJC5U6gk#T_Hae`$C{eA~jxdek`-Cf6&+g2%wWDgyhD z2NtBW_>^hT*=vcjP?f0Z4tH3~$$vu7$n*8}WOv3F6Vlz%?p;PlIP#5ZPdMUG04aOi z0akv3n03!<jtsU4<db>zbDeFpJ28<ooS*%A3&}sU=kjdj#KrR;UQv${$km3}aw(uN z+T(>@^Z<uTa07+@oC%41)_L>l!nu#%67Y7)ANOBK09txV?Kz_(Ig#L!f<tj=?Nn~i z8nh;l?ZsV<Pb!e3qj^4!uT5|7C?y!0y>xkg4Y~u|S6N&6s`_x@-9amX+CuS9h4#nw zMqQFMu_G_X*|;G)X3QbOcgAHOUHQA8|6j+uk92J>pAZ}&Bz3!jU?&q2N8D<#Ko@8H z7&P|_xI^3@lm;}1TXsw1&(o!LM>dDOXA}6;#jCaH>Kd2BtZv?3zcl^RE5<h8#AJQh z(pfH-;<!aHGRU(nU}052D{%A_a9d`*@QdI7{MA=-vb{Uw^TYz^&+ynFTm|K(C-Ro0 zCEOzD(`y1!f1A<TbF6i=Tj@V$0PfGvBJISkd)Og&H%^|LD>U&nF!2?mt;fo18yuU& z`pab#GUu=}5b+}i^{e)l{K(&d!8xO<>j)v{l?Qk5-<S2bX`G&M>^YbsRZQtQM}T7y z9ai<=48vBR%qNNNXJkQOUJVI&?aL0_x>c^+`&Z1wS)2RK)rCjzp1Adkg>!;PqJ^=r zOlRlT?1k$Wze*OK9te&?dyPJA%}%5g-BJNx0CNvdxsyNiNYrjF7c%3<lm-d~clFdA z=pdv+1A<(KA(%C`1?|ZHB@9yTW!!Zj>zoc3mp3or*X8LX+YY6Q+lMdCpSW;Rz=QvP zvVQRYsf!O&*698~!Cye1FdfdQRV~A9HYl*G1$U+2KJq#_=@%bX84rcVM#iDqG<Ahe z*1!lO&{u}ABB(Ng2M5LFP7@N8juMhmsKh(hs+SiYUix{QO_bs|gIiZ_ow{|UQAtQU zx%d(KW9ygauRy03;#QNj$BpVL4cc(;g9_z|eG=bJ{^ry0@P7^*Q7cBEDxo$eG?tEH zGUqeoa9?ghs-uo}5JU&dq+af^B`gU?_<5rNX>D#$YRqNbbS`ThF^s@l)k%30@sS+E zB7((Z@fC2d!Epq-KM$1Pas~`f2#+Ao+wuQ|lHd#ZVzp2u=@zQ@WbJu7?an8P9#XCn zs$wd1s!G%?Bt(F&mm*I^c2OSg&(n4WpBZZ>V?|FsM9C>vzkGxc5~lK`i$0oaCf#)C z#bn-{_e8~1h#oI0@`_?2AER8|em>sm-QItpTCC)I1EeC;tcj%?iY`Wx^3c&@f@-E> z(MB__f>pwZjEL0}k;&+RNkwWPpD-l`<{!=edGpfEwb|9m`t+ld?_R$h{dZW~56b1C zOpMl%@_a0Bk0huA-k9EA^w4rD#&}Fii>Kdt?MHB7|K{Oi^{)J6+Ld=F?UW+#E{2!{ zX^%FOF;Y$*=n|?$L7^bVh*Tm~D``(97;b;=)NX!OS+A^ry;fP9Uz@po@_s{7NeH>E zFS*FZu$<nLV#hqRrx+^8Nqa=3P86J((~EEY?6sfq_{yE}#r1>|vn?jf<3(3C!LW?G z$fiZ!R+TKG%gD)wZgE(sK5A|ra~Jn9{mdl3LJVuFtlwCjTb*B@$LKfjp1kza-^tbX zawkzn0#GKKvD=D)!6AG2AlcO0WONPhE++Fa^7VIK`_=JZ1(f`q@d<(-JW3fbvOVu9 zc$ju`A}#jvBQbA4CCSJ$yUC{K#Om00$0<*7Zf$zC^4aYABxac?Viy>9s<KvD`TgqY z#eg>El?;mphRS6?P(#{I#mr65;mg-F?9Mc0nlsI2c^0RQky}l~PW~Y54Ui$q!+4lP zp?%1cYW522@exc=G#q1GVOd0+CiHTm0jIIKHj5p<vF2em|K-f;ncDoN5cPkqEiInB zJhS-v;`J4xB%7KnO_qnsTlZ%kU0-V+mi5}0-IP7kls-7*rgp2usCGh$S*W)+K&XnQ z611maPdkh4g&4`5a+G)}9`&^r6ImVAK*dx-vXMV&Run7ibJf|!=|?Wh=IWQLXD(K5 zd&U%*0rK>Nw|}#A_O<`}pts43-N&=FwX{C7=1%QW%Q8*9a&jOwS+J9>T<V}Cx`f77 zYI}T{>e+~pFY0m?-1&AUN{h|nsd8yZBc>CnP%)N~4L5|FNFh<S$g>F&J;&_JG#5~L zD@*HdFCJphhxz&1%;M7R6YmlN;V_oZjsNxC|2}icK6EJMCQ-+DbI2T3@zJ1oR3fi9 zx;=iYSLhXc8@#f7$b29g%QQz41BoF!ouFcRp*kAW@r7#Pu$U04RQ#!W;@=q}^5SIC zV@c#Ehn!@Ljxv??<<;w}udT#>h<6T@%koTu8Xt?2%_%z>EjDCgq>IFr*#NL$Ku*cc z^~!?;v9tdozF#E_3aMC9o_FS5WV8@_F_CvO?Wk6J279mMcgZLbKPo`{Kh!-IE4G(B zMNfKjwX!<DHd~$Fm_-LxR$pIidWx^)XHou9xi&$`Nt`OvY!+$bK#~L#BhlHJleLe} z{`kkwZZ96citBk^T~JQDwVr`!hD}Y5B^kUQ2oU3Hm}=0AR6_4Tm7TPE#r?5#GgC@M z$2`pZ+T04pug$K`ug)!=esKNV!4zMq;x@l5563bG$;mN{X*Mu!v%I_SIdK{_9<8jr z_RjHN5%pYsfAa|WLa&I5p#t|Z1014eJUA<Bzcd)oid4IY59*s#Vy{@^!alNN3DSuh zUk|M)o_ug~z4EwH+ghzG&efLhyQrh}!ZA6&JULk^136<r;O1fZb26%LSmu>!MFZ|J zPvrEk-+1RAe<oCkwudLgUSWTLjF~-Su`%3i<U?b2v&eYVEKj2kqDRR<(2kCftAJ3< z{H4mq{OabK0+^r7BuV&{;{5vb>fFkmk51O^ToUSq<;fw8Up|0OJ1Lz}G%V4IGxA=S zH#sy(#k5U)krK_FCX(9|5ULK)?vy>7z@8>Dv7$@;tQQ_xNhrl?#39<F8Ie|(ZsmI@ zJ2Sib^=Ftv)t&#}t6#3nEY7XD$>qhFmFxFUzx($6GnWXnh}(Vuz{aIBi<Jina}(J_ z#fF>IF>``Wnsq@Du!S!btAvNQ$A5PCVAPXu&U3ZmVw`C(p;AM%PP$dQnaLO3WRq6z z6^CU+8Nu(&XF&TuR@R#HvyV?L&a9tYbOV)Q`I*J{?!Ufr;yidlT^<?&1#NB3-#POj zO1Uz9z4o+=ax)4h9u?u#u`rb=EjDkDFH$#n#aOF66B~#X(W}u0Xnm)uA>#qU8lp|) zL5;j$MhxL+E$js+9Yy#ynFs1GR%)-W#Bd7eRH~7bYXfRgy-<U}u?1UOm(MQMVwu2; z`{)?u9t)tNo4i8)6XNj-)rQRW_(Z)<#qSrA(da=H*d}VvcrrSC+6C^D>tiZR*ei?* z35l8zvPyoWGs9XEbSQ6ULUcUq&K%0l*5>Xm-(OmkPXJtp%0mj$m2Y@4R&*C#bTgUI zG<3_0o`HRt<bZ295e)z%TmKFJE9=Ew;(j}jt$}n=z&3Mp3f*65KnKgIJ!UcgS&nsy zW)(q|CkKYO3$g@bD9+b5!N2qCK!NqS2miG4`xQAK==RrGKINiakr-t!#!~il(})YU z(vxyi2kCa^&f<wbyzw(3(Y3RDrBbLAs{&x)hD;(AE5<B|F|2RQPBruk&GP<d)ktjB zqVMiwVi9$uA^&m#tT&a&&VYF<HIDl?*KVxM+&O)_VG1uDnw%_8#z<LIo_A#w%s8;5 zostYU1)GLLrE%@aci#B*kA8%nS8h*0sTLb0P!&;zjeE?Ye5e>Iy3Kx-KO$2%Qg%~= zwpAlii!z2G1zlOaUb_d(gG#Ves^FsP{GThIZLZ%~zkXgs%2YgWtD2+#azvi7GqKFe zxWMV_ZR&37-8~$m6HF-c@!8jYbo}hIS?)(QzI{}pOmn`OiDsN;XYmlU%{~<$>Z7fH z_pmE(Hv>8JL|3dn2L8VZ+k5x3$~_O><)+=}ad#f`SYKK^v$%Bs`dOjsd9L{IEY+@8 zm)4q|bE)wbsE>wWPE|!Is2%W+P$`OR4=+>4$aY{_!W?2eLy8wgUJ<zA$@C)Q*t-UG zlUhtRC>8lc9yq_gxi+`nUff(ib!lm3{!u$qd2nX^<b#tBW-gsPE6g_xaq6Q~-dcNH zn_06zCmoje%6cWwfhVCpWzd>ne<h)oa52b}M^|4@H5A!_=Hd?-1-e<(&5vm64@}9s z>;;24M(KL(sz6#K>?GwGPc~F=qbr>QH`cyfsXSQvqbm>HN-eD{eRBQ5$#=y6QKaJb zALDO*_TX_1YYsOJH}%F+9x%Bp!&jj~`KTwK+`B!#J@~9jSkL#0EgV02DEY9TE|mv- zahhe?ndXc=-O&GRzMfwmI!MNV0q$ayk~5W!X{`947lGJN0GM|sM(y?<A^6X6=*vMs z1HYM6BymQ0Fqg$`PUIW3SUo}1i`35sg{tlGkD$YaDjh1uK)R`>OcN=GYE2ZKbSx_N z$~919{UWb~5b~8>Who&_SmeM;w-#Cm-S_u*mw}0QxZQs@)`8Vc4V9DW0GUWBv_E8$ z87D1Q@6NaeqFI)<XF_IZ1FcTIhamLZ<BPij;1?m#Mnow{13D&2MT;@8e*zp9(-@RO zZ&Rd+A4}`VfuRx=8ybM>Y&I{g&#wZF*S<zY+;}{<_}fK!i;}O*0{kuV;TTraoOe?R ztw9r|qA$v+dUdRrAm>(ILkB>A>^!Ijuc$v(Wa(I{eayMv3GACJy0tF7FnyFdm}yWw zs}87ynsL$@PMB?Eg6YI3JjF9r4t>5}uT+7=>!%<5_CXU+QmDZ0mj}{E%`q*`%8aUI zIQ5Gk<|W;E1^xT`uf6li@t5FKwjW@!x-pu>r{Ir(lg&^q9tsRih0=XMz^0%pty8r| z<n(0bm!I8Tp9khZf8|lnP&F(wTZ0l=t2~gAM>S$2_@CpSOf1<<+R203-QYe+zi8M+ z+A>MFiTBRF@w4N{ML+l+*N0CYahEUxwFb;dg8h@lM8U2St7U1SR$32KOuN!zt=Jpq z%gt^Yh{v7!8e8-f<e3nD7IU(M-y?!ty7Sh#ljrzp(a;n8DW6(gKKJ!wDFyxAD@i9v z36vrnrMaPt8<f{|ApK-;{6~nD8JOe%JQ_O7lWH&$d_K{t6bgkIkEO|ckZjcp`$hZ# zGB)-#=XTa_tU!s>{=fB^#ovPeuUFq&ow;=4cdy<5{qKZQ*jx?(%3F6&KBzqMP&%z^ z*rh%=+?-D2_obojh0tCE>TRd~g<he`6@}-eoAa0>rHc@Gh4McPHK^fM$DHIrN~AhK z9^ga03~`=kfbnQ!`O5n2>dD%v2T^i-$WFe#`1)^NTYP&#tkv!4|Gx(&ddTLC8|qh1 zu|v)=gI<hc!@`seYTfYm`lT9Cy;vzUif9+7fXp%SP%+6gsh~kq&Dmr`t`(}r%MC=S zoS+S)2Rg<*6wA-9E!EE4e{E%-*^N$V&fBBtAGHM7%GDqD3^Dz*3n*=eV&-(3XF&9g zvx4H2d7F0h2cZ^uiJtmlR8ty0m6T`4E$Fbk2kP5Sy0A||^^r&`p;HseQY#Vh<k^8x zu{}Ruy>WT^((L*s9NB#J%(<m=b_>>&ESEaXKrM2dcBPu(`(wcfxG<4FSmY{usrKWA zH~zDZ;QO}MFF<G~R6kE0VgdtLe|{fn$LQ{&lXL+w8+w5$YI#sDRG5WnwmcN|6b}`g zaEo)R(EZiT$CcH}qnnpzR!;xHRriGdOXVS3q#+!m#-jF=oQ~yP#pV>NZ}J{soaD*H zAAk79&k|gTefx;(g(|65PQx!0n=#L$VBkc45O^W#ZiqBSkE(@UqD!Q0rsAZWwo^b< zdVo$?=2xy&@4|P?Kd!9JEml^3e8HYp5@LC&Tq-GW;&R55bumZBJjH!paM*K_5&KX( zdGhR=XOEwaJ<my%?MJ5yQ1HG*;606<g%1wZ>w0YA-I`{#jf|><-Qun$Ejn|k@@Ni; z$NXvn{L8r%H%_*)cJtB4_h;@LP20aKQVpn{*guOL$Qx73hGox5GfloeQkLFLyP1Pj z6ZeDvLg8e?&ieT(S#JZdiR*lB{}UFGS{Q7FBNb}V5!CLWFs$s4sa-fdob=-S>dp0b zW^1*wJXf2;OprdTE-n7#!O7L7cZJ_QIQC8T&9BU@U0;k1A0!)wn@HEND6dF`@^Uy` zZg?Soa>sv4Ia~&-qW(<K;FOTBd%9KC71!~_bTpr!8q%WYB<ZN~uZnK6a_R2l+1kyj zp-{Pd=8sDce)=f+;+d7o{iO$Y7JhsF^|KQ1zeoK;0!)6kb^XrF>NqJGmITGUl3^Wi z*kEb$5=u+}i3@7}+lQ|d_1A;<Cz<h*v*<EQ)S}4&`GK-fg*wc{GV*@cb3zsR4_)Rl zgZT;u?8Mw^<<8Q-EPaw-xILO%xqj}>;>ok3?}^Qje>j4Tjmpa7)hK1BUA;)2NUV^F zJtySzxWcO!dL=vgU#s_790{RpCJ((B8gpkFw0lT*veg^Ph8QP<9>_<1#b~FpTyDY) z3^?)0yn?B~f81HTw}?(*6nPgMKupybY$b%f-|RmUgwj#c1I$Mfmj`B;k<qE1BB1}d z6VS?c@CPT-uTx7%9ceea@g8?3ngw2rHD~3~hT&Kcn!(#J3}zD$%5r_HxI7lkxM?sc zm%Ke*T0=b|0s69b;<oFr5HCz&eBelPTAoo*aLaJO@?qD2CmkZesu}d@**D%f2pHVn zf3eE1YE?DS`$+geDoW-!&j2K7ru)s&s0@Bg^nIZ^#{XX_iP|0wrK5CmD4B9+?;v&H zod5h|`0sV-&vSCFsQ<b&IaF@QxPW9XuBOOPG?AU8<QZA;C^%?l<?XZYo&Dj?=-3NB zPc00`fH?LSCkH%3?lBkRDK&s0T2)7>CQ4K<HNq2`?5QN3NH?e2=@QPsLtkG<-&a5Q zYy*t+_qF#HPv37+HwgXUU+e%*obx})yc1f*Ff2)nhk@?U82@zV$G`g7e~s__^a(*c z)g=r{$*4Io0R6|{3+iGII7vi`f+9*3mQ&(>Azy?9v6*vykLRm%cQJmk0iT|P`kP&y zgCaijK%|wcj-(a!fFIny$KYfdyrSns{Y~m7?e6fwUg&x<K{j%EF8|q*OtroLNOz#O zux_YL)XBiUG?X5flR+iMigq%j)sZ4^l%F7@so6DnuE+Ch&8f=b_4Q95+}!Y_HsQZ! zS59AA`ef!d@qJMq`U5-g!Q!0<cUGajhux$-Z_|p+<LK>!>1UO#z+SPkY}y_lDML01 z-1Q7W(G)y+uoRz=4;LC$Ldrd0hyOmR7xv2eNh(RtKAv0Mgz5tStu9|WSv!5nosZ_5 z@-v^jeeU$iYqt-0o!%$-2mO8O!SbRaFM{)t4U2-!q-V@ciHw~87ZT5UkEnOX2fpu) zM1lX#R3e>tQJzK(AL$+w2i?WVp#$VmDjI3dNQiPe1_X`5?IV{WKZfs|sV-fTQ_+IL zd~)&5A5YwW<JW{-q<SJhF#gw{{N(W=rX7h_oU}t*B=d5;t_!0oTfJhHXr}^18WA@o zWh=GM+?<axE=EV$RYI;7QVFQyMyiQFq{O{aiF063lSp1;Bu;(h%&+19#|DwAA!UP7 zdluQMSXF`p<up*|kdBVg&Y>uS(=8%h$?Lor9U~#nPD{z{_3M;yCEiAA54x385}ssp zahy)T4<bL;G;(#K5=V4=xsu41q)$Z$%$}5!Nl-KEUw<}-1bVItR$703<tO(W{yk2v z0Q3WI+w;w-@gnpD_tq%%JpKmePcJQ=c;~gVe(b{b_(FnTFIGq4J)jYwSDK6VA~LQ* zJK3CVG9!yp^3{@bgFsH!chzges9_dZKDmGXVr2s=Y#kiDcB3}G^7=|t3v|zN?ROMi z(|~$GijfEUAy;vQo77Nm<kF?r-udz8asb8714KNck`E-a$rLh(V!OptNTl3q9dfby zaFA?Pxx6}6UnGW|x044bxKz%CF?VX{MYxao^_!O~YiCww?%2Hpe762c{6xxtVs=ep zY?7WV?pE*i$;=Wsux8}%@11?+^M;-7!z^(70RG2J$KgBL3zMc$QKyuu4p9*}V<cio zA#^^eCYBjvrWbE=h_`MSO5|B2hKVt@Q2DH~_;;)Sc*i}0yBc)^@*f~jNltp;U7EbH zUI}{8mT6K)DVB**BA=4a7rc}b?wr3!<w9O#7>gAW*m+OhZIXETN*=mYq=tH;T)kqP zKN2)3pBvR1>oco2A34E)ryiVH2LChjcfo_JGxtwCc>Aod*fjNx{{LX*@2h9-Hfaxr zJ(=;LSg)%nFF*<79*IyYmHhgNo&38o-AbaSp?q+!WR4C1kBHX4dg-MG{t-G^Y@+17 zQm;5-Cpt-Y5&MnI<;*1{A!{>G9dm0yEXqzTJ(xinICD0pZcqb#Fa_lA7q72-C@7%b zrsrf@`&a||w$Y0O9DF9M7j<u+Kd1jhKA{#}1zz13iD_`x9{qtu7)jzL#FgGn%7<Gc z4g8^qg0zpZs7(braBgMh?&$|7?<a~lw-<l8a{9r?AD#Ri?%&nee;mNp*4DYD2gsB1 z=wUMyIBLcK{zv~|2ZY1I@b>t!=Wzd}geK@`fiG@SUN}G|($CYe0*CGi3O(R85M%tw zAvxDYg+wIrJw=`!N<?(p7_C5B6-(~}YrFg5ZU|y{h?~HZM?zwzd3OPx0cpA`Dyqky zqw<j^t6S6C<Ks4<UZ~y;uN_CGH$H$Il0v>qy2(Hk%Ec(+3w@$t5h3*w{bf=25jX7~ zgPY*8m>S&Zqh)l#{Myp$(u1a_u(T}dKVm1F(f7`w=3%5#T2UrJJ4p}M)tMPCe?Kn% zOZyW@KGY4W#)upYn9S@0wt)-Kxrwm=6~&E>2<f*_-K0v;u6nVz9_P)mpCUg8|Idv) z_h)2)56(O|ed!>lKYj@MFE>ywvI+hLj9Nr$lXnMY;9%U8(0AT_?{D6C2bi<7d_K}W zd77o|MK?zEK=UTh;c$pXk+(_PM8(uXt(XrtPDV-GN#Y;p;d4NWxyx|f>$7XKYjdmr zWA*xjrIjYl50hmA{4+F}4&ZEJ$a8>Zj4tzh227l{4~)^*&;ICdjz6*=Zrzzct5TGf zBOe-o|3DvL#-0IG<S>vwT_24_<msoNMTA;KDiHzq;>Rv4HOyelJ`iP`m@86{^-cJX z22Io~)I6msJyGC5@RSGYSElClv%KH#WpQgEC;O1S5z3>T_=lX^kFqg~)FJQ8bEuM_ zLR#*2td*-$)dY!KH>x2o^a=U69i(yJu=YPbn|lx|E<gVA^7RLmb>tv$|CRfvZ~xQn zj~9t4Ay;|mzptyflc*VjqG2S(-;;Tt&nGg0e2CO};d}&yH@cJmiF=!&KkOW;4ggov zLgc~!LH^eh4NABYCfV!4U8soK&G9b@ug4_-$Uo*6fw=#2avjx5Hl=S~Jn@H<w@-g! zSJ$by`>#@YV{2xmf^@7Yy;}|anQh8oZ^IHK?R;SuZWzR>?d8M&D^=<vswi$h-6WgA zevOrrthqJsE_sGL<^bu^9-&&5r5B+m^ZV!oJuzlyzW(eC_<wE{Rh!voe(h4_laq`8 z{A=I}hrgiTueY{pmAlZNxY-#;^&{CUH0r@+fIr-~nGf#tAI?_Tip~@vUrZDyX;c6+ z3AYT6MV;e5jB5HmpYO+e-K3MU=W+j)at|a>*TSG2O56o3aHn)+y%xDCR2z2yPmZAM fkHkn%A)0rVkbaMaGBU2_;Jt+EhG5f<{`mg^&&!S% literal 0 HcmV?d00001 diff --git a/testcode/lib/apple2/hgrshow.c b/testcode/lib/apple2/hgrshow.c new file mode 100644 index 000000000..5d839b5fa --- /dev/null +++ b/testcode/lib/apple2/hgrshow.c @@ -0,0 +1,37 @@ +// cl65 -t apple2 --start-addr 0x4000 hgrshow.c + +#include <tgi.h> +#include <conio.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <dirent.h> + +void main (void) +{ + DIR *dir; + struct dirent *ent; + + tgi_install (a2_hi_tgi); + tgi_init (); + + dir = opendir ("."); + while (ent = readdir (dir)) { + char *ext; + int hgr; + + ext = strrchr (ent->d_name, '.'); + if (!ext || strcasecmp (ext, ".hgr")) + continue; + + hgr = open(ent->d_name, O_RDONLY); + read(hgr, (void*)0x2000, 0x2000); + close(hgr); + + if (cgetc () == '\r') + break; + } + closedir (dir); + + tgi_uninstall (); +} diff --git a/testcode/lib/apple2/macrometer.hgr b/testcode/lib/apple2/macrometer.hgr new file mode 100644 index 0000000000000000000000000000000000000000..925df6e417d71bb2966da737e2c90b57ce2697aa GIT binary patch literal 8184 zcmZu$O>5)G7JYUcTFB6`VN5n}h){2Y4AHi69xVlIvX#L?n=vvoo5lerffjC@maBgH zJLlGioSC_yWqnlDsk(LUSM@YrCRJLc(|8$7^b&W~LS<Dt!(FR-srOGw$Hx;d-TN_J z1sd|Iwr9Rks$pOJZ8+Y$ibq;U_@|3x8gKA^tLsBI9>g4_3IAhdIu!hHIvioVf+H-B zs#?^zlVR=UcvvMBkeai4SMQB^n?3@+`Dq^51AWfj!%?X#t(U+a{WSCBmt`=Gt07({ z)m|xwug+%e1AG8}z?MfPW1&?q^`2j_F31soR-V;ajn|?n`R?YN4RnF=Mq1jZn0s2J zQ(XXmlvHuC@c0}rCbp3^P};NTQZ#LG^lV5S;@biGo40wVWH%JFkyrOinfE%T&g4Dt zb;1#UaCh?S1kVxYFu*=fF^<FUUKCclvgn0;YY)I5ZY(r@vO-T&9dK^=r|MIcw^^4d z^lk2|w9A_GZMX~!KHAS^IN?W`Zq*<n544`dMF4#A!{b+qGr$^B?mzY>-C&JsJR81x z{5sw|NPojma20!ocGzoGe^~~v`7d>=F~4|4{ok;ym$W*Wy~P{o6>H}nKDhN)acBAa zlvmt`{TBPP3f9A44nLpmw<*V)@`Aa~fIW+JFu~gD`%R!Sl@Ig=JQvQ6Cv4{=u1>dP z9cAZ+?D<!vP5)9=A@^+!+j@KUujkYk-h;o~JLoB@pr?@@U`JbgyFIB)gNM^}ncf+s z{<`nfEqha<tsm5_UtSly8i|Bvnuap@)3;XY%j!zgAaZdE&u@8U+V50qi3qh9dLUG$ z8M^_^?<B_7LOom_+h1See`s1@X~(b(v0S?`GK;h&f#nSd_zmws{A;{Z*;*Q?u?z!b z{O#?6b(zXMu{DN*@;)l|ox^{xVV0Ld7of)F5Ogx*nrm8sz8o8-Kknvs&1(J7Da=CS z*=+K|@vwb3zJQKK7WJV@uQe&be+FOc(&3-mmu6wxnjfscz0qkAcmk5r+>dw(+R=H{ zK{r<<NUjtNG5rla`43|7)hF{L2DN>t&D^4EgO6_$ho8Wqd-Io0pkGV(5%kOdB+iWP z5w2WUbLc3p_RR@>vroZqi|hNDI2-iO>42T~IUe{V!{QRz8~!@{Vf#X7+RV-VFl4|) z&lsUMmMd__cGWNe+=^?NByetD&@#F^)8UK2`OoaF{Yk{>%fpX!hHz9Z+I{8mM_=ta z|7wJ@U>@b`$g96`ERqihXG7>g?%@o^{|)r%NqMu&)wj#lqgl}7gN+Y0`El_0>FBfL z66P`XeRogZ{m=Bu;Tcq3Be?}v9}~K&nf_(w;PfD$dD)~}V;Q)IT>`s%SBJ)}e-x0` zYok^}@x6Me_KaAU@xR*NMtp800%Gg)D&p|3s<vj@z$=RJ@p_<9Scx{=(h!jYQ3Ynj z_L;-4f=R^4Y`0%btWz@?$!?7NH2XokF)GQsd}}`C5~X7EaGNec-9{-!NT{JC{0?h@ zOXAG9Wot2nGOW%HzsVcWzjpzW0sTw-uR?4d)+L+u^C(&X?z@8D1syQ686w--&PCCH z1Pd&B>E^RkhZ-K6@qda)K8PK@qQO{2@kj9Cl&ZiuJG(YeU?Mu<t|0cGfNS*rUY+W% z$f80<2aoS*ut7GZ#%4FlbU;@mQN-c@aXu={Pv$Dqz`iqktMo<uAM5WrKt{uF=`7vO zt36QB6MPuY?%NxcZ8c4ED(kn-PsS{e%{Wq*V!E;pzy6h_c@xq-GDjg#)Nll5IjMv8 zo*xTfa0W|Vf-keQg6Y;EH{(AXp2N@B)=SU_1N~DWTWP7c7q@<7FAhf4A!eG?Q58&w zKSE1uaFrR09}o8{@QfP8`$Mys?bKf?$0PNR{KLBf(<P`5pTu3^F`~wdc>EBy<RnuD z2fBXEeA_uW!NKT$!2|s2;f8b7&<3)D!CBpmFx_kL*y)<>Da8VN#OzNO-&_DCoWqw! zmltf$9%jYOvx&9LF09~%p{f_EYn}f(G{#Tv)cl7uKng+$#msu2FE8C?%J{Fvj2*sH zjcWoW!B~gl<^2u-Abmp%iM~qxslMP%epC%+3Dtj>2^h*lRaA;|KQ<GI9?fhm%1mz@ z{x@uAkIg&acQ9$XwhLi@Y%j)MsPhWs=eJHF5oZ>ni?d>1t?##KyWc)s#$T9>F$L2C z*Xd9@{H#0G9~0JSleBY2I3Iw-ow4%-w5M@&i>Gs?;Es_xS5Y}%<C}G$5?!_z5g0Q* z3<RGecyahYtGqk+5enZU(2aDK(#2>1$*t`O6USK7=sI~!OS-?CK`@GDr#i6>fZu*V z1E1_CoBgmL?ANbLQ%t?ss2$)p5W4s3ze1e#V@&$dlj<Z9b9Z;P*_YP9_qmtp6ZL&d z6NdKCiCcf5VIWp+#CXKibkb*^w{SNX9El2y>%&!8>hko+@<XIJZ2S3{S5dEBvXT3N z48Y?LZhA+1xA5k>tC?+6P+AP&4*y-20om8V{edk$&R@2L!}~1HoCnai3&~I&KB56U z8a!THpp|&|IqLrtBG83rgrD870-q0Lj6JBOu++Z(cJ)7(xXlOA661{|aVaG;pm(gs zG%v2o;lup!e&Z4x&IR9j<!>*?6EYIiGL*(ShL<L+lnTwf>U7rkfhxG3Q6%$>vGG_V zA{b_jdF}i9^Z3%_vkMnM+}6bZ-Y;VlDl^97NNf~AUKeLIM^c=$sNF8`5&ww~BW87* zZBv+Fg5)!Vd5Ifw>&N_Zx-lo5Y0LUQzKs9ZdL5hS3*F)jrp@ViFtSpM>bv^05*_yV zjT=sv)LBfDKoC8#FQ_3mzW&BKFpkNNpd0W28aS))L;W8wO^L#9_``nTiV_6Ud|8HX zh`(D#C%or7Lt;Z&tj9hhBa`d{P8?C#tslE=a;Z#eU%0mwF~Eo3{%7&l*8e)7et4cV zh>DO5Mg5Oh$=Ihccfn`w)eGux|BQfETMqU37j9N~(2aRk^wzTv{4nuX#sPn4)C2b{ zt`^O{{)T{*>j?O=evfA65Lc+b?Q|lf-d1{iZ|L~a-k3}jXBwGjnAHDL`-}dO!4VsF zBYExpQa{4<nSm-~AQs90FgV{ywzAPE9{+(a4QZ-Q=%Z?l`d8~q1NhQj=?GMk_^-bH zp}I^w_D*GXqf8V-Z~j@rNzLm<rh5_PP_=ITzNK#!fD&ODqcxg&k@_FB<BPndQQ`NP zUB~o~qAC;r7eGgi<M0a{Byyf5lEz+Oh7LbhCpq?UAF+)vz_1(^`b|L0g-19jK)AMj z^NceOP>zBOz|@<OjsK?pKKLV_gxWA?45CxPDUzAPM<&sIi2nuML#AULK-*62>|mY| z-Qp_Peo=c=-!D8kE7KKcXW9t9kA{fm#CMCcM_7Dx_>p>Ul)5*xlXk%%tyshM>PI%< zVkp7|nSlg!iKzef&O&Dp-TktOtJcqmE^OfiZp+`BJI-k8@Q2HjS?8UhE~9lUd(~&3 zj9Y$;r6j&)wVQp%(k8h(dl!oJ|L)t$&Bywi*)4VC@Z-_{oRU?(Vh6*~UBCOcdXqB4 zazfY6&<DZpZqD`M)hGQEp9#3uXyc19*p}so$B&jb$fKNOj<<T(?CneN+k{b$h@(M2 zFmHGsgR<g$jXX;Ar#^iftoNe+$9#{6Mxo?%>qko-E5(KBA{5`|P!gJ65D<QI5N#Oy zB=$1>J!TcQtdIXSP9JAdk03>cdSnw5wxLPUyCc(}+ENw(4!?sZEl|@~fp=wuyTz3U zUA>@+gZGo#4e`{}Mh))Z5Qa->iTWEJ*!Gya0Wr^eM1HL15!j6X8s_jLcKGW3m~BJX z+ME>NfHB4TFWui&#X}(e;ehGsjQZPr<^M+HsL2o^d4^)@U(CU8<c1#CoRxsua6E7$ z%(xsr*6>pI@FoL0HK@NY;y)+=&n~)wbD#sn;ahV?UzqMJ*&<>U<H^wDqrH<dZCz@O zR};DdnWw|It8}z7*~tl!<RbnyK`He&`$Gfxwn4^&Z0sHJ_i8XK5&!S(xR}ueI$b`> z4?CG+feZ*-*ygogKi!!~UL_<yas+S%M{Irhlk+T!LyYhb<Dvd8`5cXqbv@zS;Ma}h z9Fo~!EK`WG0|oWJH>w20e>dFm>*tA)6A5W$xD2P!>$7{QGG-)ZFpj4YvY-Wdf#0M} z@jp<R{&@?xP~zy=w=_3Ndr|*e{$gm4zrS^7Ml7eiqkGLI)NvBXDtP80_5=HJ+N292 zCvjH5!)F%3`5^im`fdyU-P!DVqI;Wi_<w7UN4kKaoPzcq7?Ws$iz(e8UCKKsym_xf zwC>~oW&JI6K8G%mbVFiZAdy^o0^sm%ZEW7l75|CT4e31k07NCc;SI<y>07hoViit~ zpHiV4jqw8iqW(szSz(?<a)E$b|Njrq^|!X)TsC6;ixch-^}nGs6FkuGn3X^4vusbU z)SId$_F5NqUoCjT`?3Bv6(Gm767}Z~?cASTn~%g73S&)HU|jaw2!%ksXOg@&MM!=< zEMPJ^vb4b2!|^b4?ePnpT|D_)r+@5e16_V-gA;O$MjacuK^EaV+Q<hz73unf`X6_{ zpA@-3`DgtNSLQ_YAQ_3Tzma8{F!L!iXADMH=;7Jd@Z8!BVYn2T#|bhu829&2?({|Q zz3xq;NY1k4-n#Jn?V@$-5A?l1Xj6@}qMOk>tj!9J)#5_F_{-2f!zGt-_4yT1|Cj7p zac}p*H%0E^bi;LE?>^Mu`thn@_{yn;`s~lCc8zz8{ZP#2yfd?}5z@d(<RrZf^gKi6 P0{)x&pY5spx#0gFP~C1| literal 0 HcmV?d00001 diff --git a/testcode/lib/apple2/mariner.hgr b/testcode/lib/apple2/mariner.hgr new file mode 100644 index 0000000000000000000000000000000000000000..2024a75961e828a9a0a7f44ead789284ada14ca4 GIT binary patch literal 8184 zcma)BeQX@X74O+`;<_OQk!w>W<Ss!X&ZZKf{iEii@unpN+?E`QujUU_pGYhrRETYw z+KDf>@9caSgGeIPO{Ave6t%@{R4$?*r2%{wnhJ!}#ui>I1lFBeqSAw6gL;Z_?c4s| z%zob4N#Dt{vv1y;-^`oY_uh<&98#4ie)~c}tw&3=)jNEDMQz?G<Qlt|5v`SNEBqpq z4@cvPbqP(g`DzvQR4>8Xl2t0yKwq&)yvQQ5U)zWggrm*98=}hto)&LaZSL*d(X6%Y z(liXQhsD%tuK?<?AMWbbG>wt+c2lj&qL8d=WR?#<oMBev(U!Z|0{jcCAqp>NZW+ZM zS`+Q+MdzTV9!*<K)VRxsA0uk%Kx?@H!M7-ek$CYV>)+s(7Diqp@Vj<P?WMMg`)pBy zT3hE{Edlu3qsoD0wWO%po+f7uKW{n~(KMg=o+YZq&r2@8s*KNymgwW%7(x5?_6^al zC#C+4+;G^d*C@u=rFCL)<99(Su{F?86R)PVHsZZnFmBhqn*O?rKUz2<n_9G1<;QG; z_!1>3Srzl|*c5#<(XbEZ4H0#G4N|c-6!%DRQAV`rX3y&)RTtkD*d#2^_{~iXJb~MZ zD(1o8$nFDsH0=gfQ@BVF)#K+-Olz%jUKXvC<IhmTos6vn8@A96IUliO{XJlPHtg%v z9+0aYu0iXTRV>os$|c(B+!vyg-WR7{jxQU+LCXHMaJ7)rb1yiezREc=&K7k;H(oc7 z61^_lp7V(irN;I7S)*iTl6J!&%_Vss4G++1!CL@7YxdGmANT#)34L-vs-ClZu%9Vo zYBGJrygF<00Hzrs+b<g3iSBOwqX`<ab@=(tMHXe5kNMSy-ypt!T2FUTRv+ULoS*C? zdPVlj;ts`LG%n2l*UVscW^P7|VPM4Cz)~nrq<;x?!_nbNiaayHNWAz_MSTCsx*@6_ zXLP;z$z`Gaysr;_8P$!ctNNcz6Jz)?W9akgc^bZWc0P^qO8O{0^r>n7(tfp{2Q7nI z?;d=`kTA!3Is!EQx7_Cwy78&B-6>n!c|L;Cy<afRqM4()v&JBm{+y(txn$n4RW@y$ zWK&<8T>SBZlwK284u)&SFO2E)zb(EfdCsKl&hC%uuZ~>8+MDSlO{a$jD4UrklItgh z#!TZ)cPoJBF}&T4-~NKD-g^9`Zlu`y<_DM;=vcO59>d%|Y45Gq*h(eJzD1{OFL{u% z<^;6ia<575{2ej$jNjnoOEfYmm|5SxVpdi+3Rg--ruekfI)q1t7s<Q0r3qcOUaMRH zKO%hJ&7t;CuuZ##UCRQLqPn}gb}GSIt$Q`qc1Q`~radzrZix2uY)p7Upn_C^r5dP8 z`Zhm)mYqVUwwL2Seu)i1>EIR^K%{F|cT-pI0S>_M{>vaz;V0GR)w0>v$9|~V8W3+w zD8_yJ@aq_!Fn`4Vo8pMWRS&KK<1sl1_FE3+BML&FwwwD8CE5~<ALGo%p%~H1HY5iQ z!>WXx=T^iAFMd>?=QiMWwTbyh?fAdS((yc^&AT=R0p5%Fe|NB|V@EwHTU&psI0oC@ z6kNj5v5c11`WP<0T4%tKf})87h=D8aYYIiH_DN$^W<cLUgj%}|_<)FSx``<MgFv_@ zPI0IA-CEEccHUu^Rb2d0nSIc9YwpU{RXcySQi`*6ee@$_2h_~)^|1ThXj7XK%hd0= zLTW^7Ro&OcYA(Jd(Q&KXdzhd0brJY$Z&WE?rZ2w{dvz7IQi3;BqbsK({yU4|vQf)> z-pcV0lU#WvxS@u6ZjqAZc{SEZ+1J^#-ASyYkPET3y^9<7$A1r~r&^BBO@nJ`N#D7N z!hFFT$t~(bjL+UXYZRu;;%k%=;g?A6AGi09IsQ+~=F*atN8C4_BX;Jg<Po@QkRN{r zJ!G3`kdD929(MMGo)aEei293E@wGAYAD_Sln<kVP+V7_G*ch$zXw9&9bg1v5tUh}( z%Wl<&zg|wDidN9*g<|Ga{mQc@Mk@rJ4rC>TndCk(1pH}~Li3ncXc}I64)F=-uIES* zowtNi#F>Z(KOEF^R$EU9@g2Y7tmODQ7BX4Ac)^gfPtPF!7f-WM&(5Fix4Iz2|B{)u z-<;=R*FSU3#g8b4)NKhNZy!HwVC{`BWd3l_QMW5U!RRg{{^!ioG?zB|Xzne<|5H|0 z$5NLv#&x5g7k}JJa-M3{lMMl${U7w1L6`{SOiH|=xXsW@Ixj98KA%R8mCclr9&{T1 z+{CD^OYZzF(F7fb?K%Dr7t<WUL3vSn3laY(kb8-}b)L&o|4fqda=a|c@xNl+-abUV z0-s|$|K9m<fTpeeP@Y$_%<QB&QOa2}<ox3_mJ{pbF7M2Qoej9W{{x@Y$6MipR)lKW zw9uU!0u?G2LrEkM|FxD!GzwdXdD~6f`+cS%8sEKPU$>_Zcq+vIFa@ea`1R~R?sg8J zWLDlQuouQj$PFQ7<H%+b_wT|D1rz$O$LZf6|6>7CSK#i!lYMX(;dQd3T2&m@y!KZW z@f8c-uEaZcR7IO_2(fg%RPmLOW>_aK;P+_J{X%Xt5$6k%@Dc#LZ4;YK&WzL;cwYQ% z`mb3E@qhnn83oq&ECkI$6s`JZRlBxJ+oRRTHw7t%0W<{Kwlq0L*xfV~m&gCSP_TE# za`}dm!-|U^Szk<wroD=`e6JE*vF{e#z(`?VVk1}>Upwv|v^GpIz6lG^vm+1=Huh9= ztJrTbEw~w;FE7LwEnNIjYnONM?vuZ5-w@qZUhLq=9bC~aj1Opa6L;UVjABhLP6Y8k z=DsdgbMY;S?}Tmi=>8UKH7omxC^brOd#|;(#5F;p9=VU))S@d@YpbeS4A$XS;8TOd zZ|_Eix=bEgoGoLkg>m=P`Gl4byAI5i01AnP4K&&^q=v2!PnGyMM1<+!Kx#raGr0>B zXYfVxzBuXhYgKUaP2-GInlP!4@ZExBX|?0=wo#a$%IWjZxGcCNIK}Dgp<^<t`tj$` zrUtT{b4V{ZINq0cmA$o@%Ogeh|4bO)hq=rBuH-pLV$>;vLqyuEMk)906slf)wc#i? zsyy6Fr6Oi$=)%KR9>3{LeJnFEWv1T%z*RF>$UvuW8XgQ!>29s~UzR_eqhpYel)}S< z->|J9@NwXzwTMA48~VRz-xZ>+j?@(Af1D9N(C4Sjqlmxy@eCzXho+8F9wroYX-{yD zvzKz>(dC)>G8ZnsDo-CoM#`+)JYFzo5&wTL;u}8Wa>D&YA&0r=%oB+J<3uy3lXU2u z>B@~}3|<DNN_ELc>Ed6qcF#TI*mCPc47_mJvL4S#TGdiSd>+Nk3kWmJrVpXS3QS`G zEXwY`i1^PNx038(af^#D<?<oAB(Qbk%=D4>MErlnt02X&Gm3?)i2nj%n9I`hya%im zL=Ev@U%>oQ-zm%Sd1WWX-Z!6-SuI3)qxxu6FMe_5U#2->abbTtDhzbUGuDIGhp(7F zI*KTJrT^`^c|&mV_}|>5?cf;DtyRPMh=HKuqlcAt+>!45wvS1WihX}oSVmR<{131p zW&D+1@TS}FJ(hPXx|^GN@L>@EP;Aw3@A+^OBEE-W+!F_A4-cI=Zvk;z?8T2Lr@58! z@xPA;I1dSmiQVrgIhFos*N(29-j)3Sg{PXL3P;-7m{u(#E{k<klPa#K9UWP*j<iI} z!(e#umFR3gi}3yb9r#P|{rfWJ_>OggL9wXvAY`KPC$#GLrWzuR0*}@FVuc%l?nV5s zm%_essr|N=D=vPEo{=rl{o2~LjqRaWeem|1CCkx~uPC=f#r+53KSDpp-wwq8nnn*` zhZc0C7q7VZ(_-?-O61COnW)CZ)O8E&0IZQX{mbhW5&toeMt28<L%4q@--cLl5H7xK zo<8ct|E;k*x&?FdW=l11J>?zElihaw4>L}p=c~wTg;AxL*;ZF+H>U@yQjSmfXO8&a zPy2yoq*~@&Uam#au8z)XH@S?|B3D>W$Z410?pDy@3Y`TR75I=+zY8yvf)|1ZyHXav z+)j+l{8`+=7v|0W0r?MrthIuUOph^p6)u|Z&>iaM_@D1Tmrsr`&yRmVh^3x}!Dalv zFgZwhdnzIiu{%nS>0=@Qp!mY%&PF_kFG%Ha+weZ(zkNpXI7Z<qlZU4v<;9OEzv151 zIuxY>M}e_Ij)3k1W)YD7my!7r&d7*DMH6`tW;L8Q-{PmFkB%OD+x5^k*W=6wQeb-U z>mHg-vKXR2M**Df^xu7Uf;nLMq8~UNIG>IW;|6%j>__|`OqP<#fkQ7HA^S5zR2-U< z*@Ni9DQs)XE?xW<-HKh~$Yk#uKQme|^$Gow7?Pu7_Y!N>k^lV@w#Ny0COwp*e2yrI z6R<;w|0(BX(Ta<I-jZ25)R!9K^LOFh%;*^~Us%BYeEy#L&lFadwMK@p!%U**WlqU! zkG#>Gc+)c+tM~GUi!WRF3~vk?-2c&wQ&+{#_3Ru=ozLi#vsW{Gv&DHPXGx_rC+n}f z0NOS0-}6$i9G_On|NIz#H;@ngN(xoPf873*c=t0d6YP{fBDTmc^Uem8O}?^nBmWOB CdLAPH literal 0 HcmV?d00001 diff --git a/testcode/lib/apple2/monarch.dhgr b/testcode/lib/apple2/monarch.dhgr new file mode 100644 index 0000000000000000000000000000000000000000..8812c4b2d7417154b750dcc86499142668a496aa GIT binary patch literal 16384 zcmZ{rjb9pP*7wf<>R?bo;|78>2(B?U>xwi%N_soGBOxug@rmt&4MY|R=E;YQMz-Kx zBlE96-!q8OZTIRYfG}LI=l62XP?4LqIeIlcdU5Ny5p9^MU{ZXhT)M|qx89%HFwds5 z<!sq6=_}a@I<gaU{BqA(*x@>Hr?MA)^LM%^c-^F@pV!@xJ8dSz<9R1|tLxFr!ux15 zxGc^>J09}hYyafDY7f6H4Ktb7etp8Y{i&4MpV>Ie?iD&&hihx%3r>p_<#pUySdON` zKB=e7-={V{rTKV0v{5>)Z<W$@*B4w`Sssme_c^#cza-AR$4{CM*YaX6nLEKHb2PpL zS7q5uN~0gr9!30ee{6G4Sbr|$m-8!0%1(8U50d(6WT$j=Ih8(gKOG<S>$#%`7yVGL z-aloYORVu$+jR2HxRYOwJB9?4o2kiEI2BwqeR@f7HM|_ZzBanbn#8JG@}lFtHC>R1 z<9Gaf{#sVft8P-7_m)hFrDRN;l^rwr#qCeIS7~!&s&BetitEa<j{oG`f8D1(Z9Wd3 z-)ja_W;5J0mo}G!OJQFyX|O)On5!!(_I22rhGkylW;SLvLfz?&PS)~I7Y?K&j+8~t z-R=xA(8@PrI!}jKSqjrj*k=a%pA6A)!#gJb{?an<j4vk(>}zl*#%Hl5Vcsjubv=}o z7o0&j6?0^{^h=C6M15u>$E>83wF({KpWm?p1&y!J_cOU<*b08kJNKIr#t$w>SG_sx zOt!*1!KRMCk}_Ln>fuMTeZ8XL(+SrySH>c?Wmg7U)qhw8i=EZ8TqdUe%J+F~`pjRh zN@<Nvi+^RmljRIpn|wRnyJFru4_7zW;*Xz<o04BPiRH=WljV3bc>cXeYVsrFH&>Q} zk6F>zHf=iW{cvn?>$#Hax~KGA%kE`$t-cs%`LLO%hyRxfaz*;*ZgrJ8q~-f^VUH`! z?@Qg8-YIiUMVtBeS+DQ)<^w0uj<0PF<2R}28$6H8_ScdB@ahKtx92yysu66&S{fN5 zxufTUetn~qmUR#RSy|WBw>ib8Umo>>oMuqIyXueSswuFc>v&<Em%2w=)&4Y5;@fma zQ9bHjpX0xpsmWENeb`*^VlKYM$-HCb+8RM$bP4uJTJ`jYel=U&s-}e#*eguSnN%f7 z)Fq#AvibH;k0UUJRnLW*_4K=3H5tm5vQy99bSV2}OBi2I^N-DnHi<B2;XL}Q$xc1l zA!1X})b;psZ`o`x{#mZ%n-SJ7@{fZ}(3b;!*|X*q2eFjUd3$@r_*ebv#=xC!f_}HU zSaVC+x_b)y?M!~WJ@_W4lyAN|3AW=BPE}7<b|x9Onv^q(zrB<9F5g@>S-(|*dG<DV zCksOE!+r%P>ty9P)E8-neK84wAX%Q&YhBmO9ra7;naeBKK`y4nH<@HjYZ|kows{^~ z^B6N_eiR?fxdYR|G{lqc)#}3D^_3~J5gsTj5cQmUAqoCp8;-CC@;W#8ea2i`*||4V ziQdCiJp(;2@7q4+ZYcu<S2t4+AKxBddPL?f2rPnv9UT=EN_V;dtFV{NV4KfV8ZR-< zm{r0Hg%Yf<82uz;g;4fPN`1HBgDq3>wV1MWJJx)XGWlE2Fqk4X>3cHuguOSL5AVkJ zd9(@BgI+WF+Gj3bT=l1R%2_MhQS=2<jGr_$V%DNdRUgVz@}KdStas$yCioBYSF>{L zvbV71!{z)rD&l(!`lBgx8AL9dkAuvO*iJF0=0Y!id;GSp--H>(XNX%phOzsubo{Dp z0&6G3IzA}2dVhh%-1_qm{ZOi8$%dsY$Q(=kP``3~8s^&Ia{L|dXnUM!zw(r2_;+lT z`K)dJy#4ca8(wwi5jFGL<{f^7U9~m928iH9-7PnbrlmvAr7J{#xgg29v16kD(G$PK z*PfsuL=aK$PNhPibB6Dix&A6Q<xa68G=79CukY)Jd{Z@U-Qm2adFyqalgTe%k8h!k z#b7cl7e^Z(`tLTb(o>NJ-hy315o>5A(OP9^@3Crjlk2jj-|HKnj{kOUrpwtY*WD=f zkG6D2@96K%43ZH=So_t-C(U11H)WFO<@9^k<IBBOA~PwCG;x_NZ<HDKK%7FOyH{vr zC3VG$cg&|E_fxz=E9B_%Q~J|oiM?|Bp^Ymy^!=3!0)wk78cjFt0-k>Lcme&-Ct2e; z`rp7KjOztN&5iyGp2n0fQ|o8aVGiZ=^u_c+gY`FZ;J;fso@V~5s{boK(TEm#=i)#5 z)toZW5Q)hZjl}kKjCga{Tnn~efiV5gA5i_*by^zZXNsQEC|Vn`Y^Wy6hNP#nHC4!h z#XEZi=Y{<4>HlO3{l{a-nu(@K3MBhX9T`SZ1bS#(T0kXkwY3CV?R}<<A!cfYN7zmA zp9~inKjmB1cnPv5*Cd)Oe;NFj3yp#U{-@EcvEQ%If7ByC_zNm!Ch-&=lYwgd6!_g? z-<Kb*K1n@%y>chMnX6t4Gcred0%28uxlksqW?-Wo*kUJ0T+7E`k@2hPDcE;LX4dzl zv+fimC1M?;|I9TNTn+w}_}@YQ88euQK7P_ZbYk!6C-so=qmP5jG3S48@4sWNMRd=1 z*d^&tf$q9{B^5#0veKVnPMqZ=csW}m{^hcsHr@KS)5M_^U;xx0^q|_G>YbXCuun5T zI<4kgC*LNfLTnr@%-EZ~7(x5r+vfFm+10Pj8sR@E>duHN_jsy#bv(6EN}a)yl^i>@ zuB&g$(i2uzXg>tSrdV!&W~<ahuPoiKP`BExXRGk{PVgh#{dI(!S8;Wlfjr#3peNM8 zIo;O3@%tVE@JJW%KWM(S7*iw4Tnh5Nyc2&%^vM?(s#!@_b3dm4_PloNZdDhjx>sB1 z?|;$%Bzi&Q;?fRQ&f^V@qA1ZbVyZ$a=;OWDM4)`%$?o|Z4SN&hgFsf3hIh@S1s^W8 z$VoP%ORWE0&iq#><+?}nrQ^Z>t!Ix=Vc2I9Ci&Vnn?XDWYX#}(z9NB0s&av!zhlkO z3Cc2ipZra}o$*g+J4v#Rb;lANJKHFnrDu9GF&HQ&X7PT~B+@~l<6gl4_5Kl_5+u?k zYeN6YG`_aYX6z%{&{PK=+(Cym61mntv#w{gly8srYceJ1KhD#_@$3~s;GYZx|FI`l zZg4qc{<>0(Hb808>^($lO_)G+P4~moU;Ke;bo8$NbKdBmo=X7zzuuedbgs-;zF;%o zHdm|oF?M!Ik{82xE@h`z$_3TGT~#fADd%np?9!~RMVE=w#yya(Y%{rp4_RFqXZ%#K z2@`x=S)RNd--tKk7mcLH?u>#4hcv6pG7`#*_N%vLE~zLAjqf#6T!jbekoP#>!G`|O zhU!0iwUUZ0=bMbbTW~(;o}Q~3#ft0!=!X%`<Ec%uy<7Xg=65{L#hy=!TS{M{|5N_X zP}y7<NO84-{%@upq$Kt4ncSrN&ukSJruxrJ<ild<vUGd|5h=syJKEM1{kM?Z&J$<( z*V{iI@Q=sgRd*h*a|J2%^pw5UDLCXV+8R;iU(HjFa@EV3T=kfJU<S2rg;`wZ|55ZI z{um|E2pV%MzfEoYbNF@X<jOrX+jBI_qng0=XV*`8Jux4yzxhf}X!!}ckRRqR{25Gv zfF$Qr&tAYeM``n*;kWqUNB)Hhs?9{U*Rw|KUoVc%&C8?b)qW*gOV@fci?wXE`>sGl z-qrv6e4TH#m7~#sUTpPAb8>Y73~{2V6*zO)?s4pVPTu9WveVypcn+)!*(Ynx%Ky~- zd_TtL_gRBDPuM5-6S;Ra{hK?MuJ+vDj$j{+=+?@e{CCqyG=Cxo#_Nom<o{?<!)%3R z-6H;QZRYfFd{K775%LhqR@OV&>CJ`&)O%<Koc-r9E{iB@M2S<zR}_nf{3BSv-BJ`P zvoz`Rw*JVbW8$z)b>FFnOP+4CmoFI9529d0CwzX*fkkt`=#%O^amSN|&brJuGy@_3 zzdD}QJQ@A}7%2*w+vJkz1MQ3pqx`Dqz=6}><Wlg?`qe8$mts0MpT-UIyeiD#Xeux& zY=y5(%|F(N48nj`N#}+3%R2wae}6`YB{?>@()|yj|MMS%JEoOT_rF8F&3@v%$vVBU zn`nJgv&66M-kLfe<~gZbds#U)pI7N02Jo&S{~p%0s8cjxfAlxS9Pt0s>mU5AJSkE- zb~XPG7jgJb+<7%d9pxO?fBwn|_TD~b_cXRR%Tj9L{MFj#ZT~Z%7PiCQ>poFiO1Yfb z6d6?rZz*H~zTgQS<RmZE6Y2`di~8|X5MXYI#$H-poJnotS87W~X3|JaYMo%%nlKMN z+_Xka>uRs9vHP#LWqWKG^*5h-FQ`O$k@0qISVLfq>L7*}HCB9Dq2Yw;$1?-8HFc2_ zqK`bqf35#i%vf1I6<rPLDc1jWG$?ha(SF#nQQN5X-BhWcBoA!f9e4ECt5q0A)b%HN zyw?K>P4i|&Xshm$p1?akolZ~9S$NSOzvU!eG&C>dT28j$lMe2A`J$e#4eG}s_`H(4 zqFVT2aq9A_@CW_h4B<wIVHiZKZbSolED=G64fG?0yYyOqc~Z!MUgHZbs$aM>YDFQ> zeS*;39+^cm@AC<sA!*<!g_F!x@JZGA5Y@`l*Zd6%am5c)#&w_iwAp+0IB{N0q5n?U z_tQrrUN!RU+ox0!Q)bhvDd>f%pvZf#{xuEq_CP=b_bcSTAu6!wKYN~vzYZ2*DKY`} zN-hw7S0l<Tc*x@XR$<ALyW_|3S!Odr6mFvb9s<YxXO@n+Gr5{*6UnTQMs?JWlhe#Q zTk(go&c*c47A{=%chGB~lgkgu|22z>D)LlwJwFj%Ru<6wSgWtmHLthPLl0M6oLBVg zwUe5;ZNaF8GGoD(<ln1?#~51GwWa_m_@}1SDNHjqIT-9yN`n+Vw<y`CuHmPTnroZO zlOOSrA65UUt9*ogsKDLh8(-U#9_VLYWGhK(f72-w{jU}FhW<nK|9&#q=Csjvs=rfY zo*|!DbdWBqPJd^L*>g4jH(T`m3%a`;rm9*!fBSf)U4q>~p^vO)xk_BWS_6e%7Ii&? zwI@z2rOL`$&$dkUYsXXTopoK|**RuYtFk726qfIChSpK8wD`}gnHI6Kcn>i8Azg8+ znkfX6`LFta0{ZW)Gk=aBcy0ac;r~zdABXFJoCYhno?O9Mcz?|yjeE)AEM?~T9ywAe z<>t`;oH}7il7FL9z91{Rhr^0;nnIrb16hJ!G?&a)slCtePt3rIV(U*@FlFG}RR5!E ze5+}uf(Pn+hK<@b$l?U**(rUec@!}{p0aRiuiYtBZyBwSEO8%CS-y*--qhvHM%6v) zT^%2}rQ>%S)tsv?{jUCRIt699cKm=GY+1;^(f^MNf|J6jo4wIq#8Y9kPwJ{f%6i!| zzZiR)>eR||Hu$i``0=F3JS-JlGkwOHOTFW{2~(DiYi@<|yP}X9xw));jM^sEKM<&H zvCTaWul}z3j~%3<#(UG(SFVPW(YEp&wQ&c3YWW+u-%w$1vrIMUpVZ$$%Vq-y@995G zoiy<OhEf3QR&S*YAxm1N{o2;oHkap{Fb$tS40wC2)eFtp*sGNkXlZkAho)<K4wq~7 zQ>$aJ(DZA~K5!(zyPDZi+i%}%1{ojZr4;SVNmWDhZ;uVgFsL_t9i3Oy>NWok2FSrh z#_>2;eoM9eAFBUae@}_(f8&XT{#VlaWj^=qkq5mlShDxx?AY}3Z#3Tgjami~K>m$? zd<YAnM#~S$q_~%pqWTBRs!H6n2J_)ew0ee0lO;Cm8>;^u7)~$J`nyl>2Qkkvvw=f@ z=b?{}zVG<o`OlKm>(t-1vWv!(f5+STVpKLkTfS+6c8_g-0TY~W@MhSX7t~M9BFgF$ zUwCkA;{NN;&2<O-heVWB*n8hYDm-s}_$g+19Qw;uS8JZ4`j53BuKP7k-^=W7Mrh(& z?zY#3wjce+|D*qRKN|iOUk;}DR_7<@TJxO5IXT1d!^RU|T&om#{qzh~5S+@f=Dr|- z3qCOVxEatpE7Y>voTf&JIjCk=hJ1Y-LW9i>@Xv~xe>OV#T?*|aPceU0AF-*fY?q4C z^~DQ2vIdWy^{M+?GeqH4*erx(FI(<T`{j5B8crq{-_K4K#^(cH>bctUtNy!R@GE_) zZ@qdN{pU<~ylU>v6v%prh_@e!iljLfCI6p1AnKFc0aN{Nj`W|(SQ18hhjxZGx${H( zi&np-v$@CkA@skM_dS$IQLA>;-vutO<f=I{J=HIP4n-jdMC0!2Z!=Eyj~euHjD3lw zK+0s;2m8p5r~mm8{>Ot7xyV^7XX`ihcmL0#3{;Vs^wIa|f4KSZHEx#NWm4U*FW7Jc zg8K)d$~+z#xuf+T`S&X{5%gOiWT^joWYcgfj50|r#!M}ERnYseuZKP|Z*qQE(C>uV z1!~i!+|0mZi%AF6QLiT2ar)%@No9er`VSi057%xsUtct-lkWtTeUoA3r-obip>5Q_ zHC9rv#qx?WRs&xl7gXOYPy6_stdBbo;AE74b9Zk!(bPJ@+mGg7aU#ngG8Ltw$of(+ z5==wA<K))(PlNBT^Y4`D`*PI}UAk#g>+iXm|IA3D|FE)o&JMQe_ci(dr(p$f1K%~Q zzo$d}e{yFR|M;XGYZp56+}+-MjG~<6!4LkDxlgvV8u%ym_m0`1F0o@IxysF%eKOWG z`VYUC^{%Ss|J3#I<%Q<MrSP~6+(}h4c$hs>{Y!s3-s9d9XQgu;sTEF*&;HO}<NW_? z{txwfP0jZo+HRzl4$PK}fV?PP7PkhOVyq=?ZnU&xBE?4%$SfFvOpQv=!D1j|8NZ$u zp1MU+L0Ra@g_gx)y~~&RfrLvDJ6G%eVF0l*cEmP9XSL6}s&d=|s?6CN)DOK@k64jF zxWqk@c*{Lav_7B4TicT89rle2Z~S#@(VkzB+JoBXa)#?pW39+(>}f$))sD3?#jU52 z;?@Lx>|b~JA5RB!V-ZU#517R~6|GDu5?Hk(qwz21#gMQimk#TtHINkPGyX}u7nSH> zTP(xQLJrI^u##L1xCJND*&0MX76ye=*N(ff_W!yGL&w*MxM_c<f|9G{%ek5nn3cR8 zIanN<KlrTI1ZEHB?BQMz;|F|KeveN`gHg0iBz65~i8E&8X8Mw>FhAzKFYESVKndrx z;JoFW-kxp|o?qNVxXc*#8+-Wu;Ui~ZXY9Fh#C|h1D{sd1jKd|?M~XOGiga?Li*2JU zTME7&H;CHod#@&w{a9bekM<&t7=cJ_?tO%LuJ64G%v#1h9239Ia1(qh5VjVHpG7-- zFh^v6ZMoW9d7k-3N{fL9)*G(Vb@rld*3Vvbaz>;)_f(_VACO0Z1}_dLV!gyzY@&W* ztXlnAU#!?5GeQ6J_UGL!eTDZpL-vvR+q#~4`s8(G-cIk%A9OwcIGTZuA1Td^g-gi* z=Z^*WlA-^YBy{}6-Av3F%PerUo#tE}LX_7DVyfQQ?k`Lrh!S>U&ZDrkZ%4}ApB~tA ztbud1=XNvpewn{*!&=<sZ`L{2VZZtIO)H<(bdJpVz-XKnI{T;Yz-YfcBd#tQ#8hB@ z!LY%V%-N|>`0}(++;Zk$^7WJG_@UH?vF$_#2G>?Hc9(aw^@*v^l?Qv>x<_`U{YuX6 z+AB%l@MBrIe!l%QinRW9eBJ&`_KZ&vlUZ8EyI$OOi}4QF#u_FR|E)*i(wq@4<tt*n zY0Z|>8hw{9-A?=^YnW)zQ>+&$UbZe>qGZ<US4Lyq8pE19nA@HGuK#{+&tnHGw?`F* zm3ysj1U8g?h;(+~ZE>p;vE{6OqNM_(5f|%oKuY<9fTp<><|%HWc+ZU#<1IsAf@1uO zTP(CLCoDsr-5T`P%O5i^*GetIDdlZF?Qkh$KdUK!(5yFOVVm){TCBGbYs<y!Rp}o# z5>CFqaB<Hu46fIC^F2!@=Pmd0lzlpl{r>rMYp`D2`g`W&hk?QV*<Lhxo$5n@lPY|g zv%Bn_Va(b4L_?&KWmOXzeK$<W-YBaX(ir0Z-`0dky^$aWApJqX4b0Z|1M+k(@HgwM z4Eh4@mUDUfLpxK<^xpPax69Z>X(fVoe{J2)v%NPqY*(JGEm{#pKS+YHxmg60+n-0# z5D*)wr}d+~a63M+O)X~<_BjOq;nUcF_0QQ4_R?cv##c16R<0g?9VCH3{pa_h`Rn+7 z*k_;Xb>I9T(2#k{FYN{5s?7Cver(;&?6Ovi&jv;PVoYKu#`xhx{VcI!^{ok`k-?_I zmiv_q$j?~vK69|YJ8LTg><8BEh{3b{?0|6&-c;`He_xTxclo|3I*6P21PsHzmX!gz ziIvivBDOrsJ@=Qf-N<lBy+qOIS)j|fIP7Ik9~m}l_$gP;+q0Gs%b9Wprh8T^l;Jzj z9VzQNGj_h5RW=#5?FQp73g=~qzo4pDgG<+F*HM<3B*$gej3i)8ROtKiTuEM>ChW_T z!{3Yv>FrOzfEUtw+l2j2w_h{Hn{w{DZ_xiKTgzAaL#{zvQJB4z)tfdN|JL*9q`O0f zyY&e#ca7R&$X7CK+4>SuZ7W7vu(T69;p*ZR`Y%RV_5Z=%Tu3AJ%U1iW82k4q0P-*6 z&Smit`ft6FM%_dB-4U$JkD1aUm9#fhxoGe*d^XaGtBfeGf`EiwaAJ0$82dtK_2Ih- zfD@J+JIKzWqi@gvt}EE8|8XbQ2K}AO(|fIm<4zEP5m@9;8d^JNoq<H+!REAyR$iBh zJZ;uI-Xv^=w_f5m@DoJAD*Pjd?L_|&v-$|Ml$F)8tlc;;Y|vLIx@(ayTZ6(*?91g& zym#palqKfw=udX<^ZU8l9H{UIW&@u=KMZMS5MT+-5;Y^He4vO5aKqbZ8^uHm6FV+G zMSo)a@FF?LxXB25?VrT^5b<0~^%&;4Jl*QNJ^kS^e-nkOg9n9OUC^lI_V(Xr?FeHo zR>HCfdiMk2&;)yXu{~?Psi>#%8VE7AE|^zu69zb(FwV9oR^_l!2mi5N#zFs{ss6M6 zbs}BY5e^V9G<Jk_?<)h0joF_^p33W1Szg&<7X3A3&U??0UX{3FzWe3uc4YTkRRIfz z_~PMzpYaS`w<MBQpM5CC2Kxj7i0|6ZY<vRyId6O8+4H5y?laN;_jl*<J}~MK6W&N# zxh2j_vB%gOUqGyv@lHk(6S47yiBJSjnORs5L=;u_q7{DOWDc$^_RB;sak}W84skX} zz;I)k7wG>Q-U|gm_tE1B@swZCxkZR27@_lE@BH@pFNosB<h%}Gw|Ga-%xH72Cvi#Q z+P>;PyE$tO-WIQ%*g;H;lNbz`kcPe0&NIF-E5<H(xyG*E^}<)yN72)T^*^^(Jcheo z_#d90U2{e5_Wpn`uhonW5keH56$WwT$QDjW-LG>f-?Sb@tnPN$)3EL?C}yt3%hPW= zk>80PMNp&A&O5IC)<r`z=+<an*S+ggHCM*{CA&CCkBKUogEzbLdh*(85qUsF8J4Ts zAG71O(HKT%RK97v6&rT2KcgA^+O{@_dq(?Xc!eLFO#86K*iYBdL07C~;Mt$!KY(Tg ze%p(bBSh~6^W;Q{=n?+k1O#VmY~eRz?L*WlmYN)|lik!g1!=os#_!WJSqfRiER|g6 z2RpM9dwS`TMx44%;e;9)2;AKmt;t(h_Y)Zl8aP+ZS&POT9%L3KnUnE`So>qoZuGwk zGR1P(%C@wOcC058#%gV%K3+RX$o3#MkPLclu!nPUW<TS#{NP@?KMV@a4};5bqFd2F zuTJ#t_-LgvE#rdlc}1-(G76KUkBHqh=Dm4}y<S59zZsX4815WT-`Jj5!3o1aq6n}+ znhl$1jM!+Jj%V{v*GyKF1c^FE2EQ}xaQN7N|G-X9!VJn@fsF1Rt-U~=#rU(t!tDM3 zqbgvbk?Mamn~V`Zhw_8elY(1qv@)mPf{uelJ9{t}ij-tGau6At$Mw#_0-1x)jIUYM zo84!ia-@+u4%y6mkjb9wytQ*DQ;chdLH=QBHrK7sm*x}&<&CGtWie)JPD|?<77TDA zfriBX9dXF)$ksHIdp~Ps<iWu#anyxv^6%#iFO#c0Lt%1z-OAr@ufH7L_4b~#mH%-v zHfnL&V0UY%O41dWvCbS|%q{yF%=)s>dV3Pvh0MqIVF2b~Gv7gmpA@jZ?oGC+?mt)S z-zfQdt?)iqTUqr@ssrHBTf^OlbY1(CYWM5>>Z-3^BWgGeW^jT2lc%8nwoD|P!}eS9 zZ&sKwj53jBJ+t@6ypwVVg_p5^4>5{MDJBMF4T^vW9sUXaYx_SDeLs471fm2d2Np+K z@nv4J8XI4n1o>?23+&_jmk^ro=g)*lAo`7Rj#E03-YyPo>=fNUjdjl2@lL*-z*+s! ziJ!WhL@Dye>SvWG0vWSbw?*Wl9sU5hvW@<BM)=Ph7}mTczrJi-?1Mh^VP$fn*0<Op z3;n-@Svn^N%mV}oC|2!dk0R;;IH838P4+>QuyMCq?nS<mg>`0Y-GJu*o^INiZ&+Js z7FHPT6sM2=IhK6WmY4iU`h?wIwP4^Hd3f?mM)PkF^dtKq>x{t}@B?7gfBvcOQ3jwk z@JIcBgYVKDc#*KeF?&exCTO9V<=m_5eBFX!AMpb@Svu^;dUzf&`bl41>J!EV4wURd zBk=t!XbSJ4|5gT1!JKqlT{jLKl$W0kYa2H^p!%OlF7mm7`&a!xyP}@32?qEcjIzDI z8`g*<8wd+|ZiClkeT_t;Ize=vX#EHM4_mKs`yfu4r!t4$s@slKo|Qm7Of-M6Z)Xl7 zl}wo|@oTfr&|mc*I!AtF>ryX?G!p!b-18qW;IOU*r?LJkCt}B1jL5jS*pmd_LmCl> z{7>il?4XOwPBBk1*S$BLId%Uv*asg0^OVVKTdK=nhv%36#JQ*cmciKlOR`(=-)4Om zNzE#sjq?8_`zj#)+tXN)6;Pvyo^S@8d+kHj|L}oSvi8VVYyN+o`ws{E5oY=c{hy=; zkkmZqk4-C4yjz>Q$q&iXM_f=_^c=BIE;2n%8y>uJW&H3Y;cy16M^ZwcO5`ckF4Z@7 zO3v1I;>8F*Nb{QW6CC}hMIO2s*x;SU@a@}=o$LzEoN5$Nw7^|1+|vG!&qi~pk=H7+ zww$=GUSjq(KgX)RpZ|p_q<o$b5Nj6<{!gHQ)aL>#n#aWkg<{@`731xK8|xJ8g6jWb z;Mw%;VZj$Hms{Zb=s(#<B~psCCako~sdKEc$J(qnxMM1Z3-Zl`R{at!3ci~E^@)Uw zWbqPa*_!~_X*`TU^nb?5f&N(Qd#?f)q#gkKXe4AtYw|ko5*6fxL<jm!-Ut$yqaVwR z{@=>~KZ8sejNgAvA-ab{>=}Ks-xC<<#1g8Vntw0uPVCLuv(_2;JgB2seCpl(<L7_$ zsg+6k-n~11zm@q;a~{Tpy*&N5j0V*Q)~pQJ9h={SS7{k*nE(4=zmvr4Y6BGd>f`l^ zhGb4-?j-w%zGYa4ptI<$dMHJ{wJ%|FQPIzPpLabs?e(Y+ntw;|9gL6uud{4-OQI(W z_(~8TIp`YUr~9h^<!5+=(_uUv_N8%XEleD81}My0#)&b`!QyW2yL_2C0sEOLgE$<& zG6C_3m*X{K@sH@bX|=OfhS~!xrT)r2eWYjBAhRI<W>jigiTRRdEbA@$b)ERX<3;A6 zs$kW7L}FXnCvv*Y_{0mSt9%QKJ+QyG=k`8V=E%XvB^lU&jk5OVR(3Cc*Z<g=_ZuVj z*=p^dk~KQtaK5qeni!zE6qy?4|M?2cj;es8LVJJw8`(dhvJUnl?ZR5-RM=}fd!rVL z{;%rKWl5N+=HY);@&9M~pZ!FQ5H#eq+M>-;7cqQ^qqW$jQpCE5xAq;}e{t&z3ZzIN z|4)Re`72jy{T(eqdp?k(lYb-j<dV^+kzWb}ek@A;-CVrx@;{zxkzE|5)=NFt4<Z7b z*l2wG|9W6n!mg8`ra*HSS1oUz2`4JtSD?mf=fMApCFP84*q;7Vr99<l4^F{_qgDUI z0UyzJd*r^NpHn*)qFuT~h(=0QuOa%s>aW(dGxtT!OZBAQKRnr%$%di6fqgdG=>KB* zfkl<7WK0^MiSm1)1M7GmV9Ql4c72KlBJlS3>KOH&0~vrZOa0r^{}S$+i)N`-4Y4P( zg7;e88jrrG>T+VV^L?XV$NgF-Mh~ohi8$If4pXa`>j(71-{-E2?|=f{lAS2REb@D0 z>06Ebm$5x|x5ELwhWiKl`8SMDwJ^86`2K;17?=(Hr>Xwe`9Wx+FDWt*7&P9?!0hZ> zmorQU463NgC?2YHUP8a6#VOTb{Ku5n%k_ii-?Jt4{RVY%FlY@fFJisgNlZNp6~%31 z%*z6I(Z7JB`~MC3xz(sQs(7zSZl)SLv9{*lsvLG!E4SPOf>l@-Ik!Hu?s>EyM&R$y zsvo0PCs*N2U`Kotwf{#bJo-=l9hB=iqW`vLOyNCGeIj<gH4pl@qouVEF^a}hG+8UV zcpmh>U+I<&>Eea8vWp8>#^N)o%I`;m-g>Tt_vQk#CVf*1rus)_-T9^s{!uj<>OYEs zub$)n+lK94{u28VEACS&iBW}R9@OF9zAOybIlr>cb=N5OkSV_oMcqU3zv}7#pVa@Y zzvIj@0fDowd#QbH{f(7-t)3>b*`>fmp?FDUEAr*CNF;FgD?$DrH>@sPSs-sIeEOCM z^aak)X=?s@UO1#;zH^BNUruOL414^~M?I;4QO{S{;$6+7Gn^<ZAGX>XTTjR+^kNfe zt}7SZ`{`*enr}yC{Zz>RO4JP&&{*kO^X4G)lKlTPKA`^2oyT}DOm1}qOO&}wc&kw* z0sXkLDZRV+VDAlec67|bq8vnS=`V=F{C>z>VE6eyd8z5h>KS*x`d$U}CCnzZMO%_+ zO-L&9R`?yxJ9C<E5q{2FH*m)P2f*BLz#2_oTX)xEOnVNew<wAl^#~%rSlrRt&DdVa zoy(J;!MGG-+~`F++;{11<IPN1KshLU66;vFd+zw8@d?DV>i>6gNk+$yfBWQ-pin&k zIr7b(dXwnC&w>)YXM_HF*Nu^(v8O~Wj7a@|mb;UBDa^FR6X+ZF^naq>qXGd^Wdi-z z$|~7{I)AFg)Y@$j&wGm@PyZF2_9E=Czk4_T?z2Wv#@TB99~_{;7gRUNe_@V{`bsOW zjB$NecTBbSQ0})6E$LS$_{oq&+2Kc;+0plR`Ca-d&mDZ$Y8%LXLseR1bAQMNdvm*- z-PdNHdE<x0AS-k)oh|pR9ck-*otSJZ0~R#@XZ>3h82HMGKaCgnTYSG4rt(oo|06HG z`g>Tyw(5Vsp5^p%cE0kU*6my)@<)`c{NT^(?|NTN&q}l6t=84)qfVwMy>0N1uOX|a z_TVwL6;WRr_`p5&9jfoJ0~z2rwGgV>TPL5jvP|}Ib6>3+`ntrguQdN(N#4o-|35|9 Beq{gv literal 0 HcmV?d00001 diff --git a/testcode/lib/apple2/rose.hgr b/testcode/lib/apple2/rose.hgr new file mode 100644 index 0000000000000000000000000000000000000000..d18fd83f0ecbc0f19ebcba7abc056898c3c04cb2 GIT binary patch literal 8184 zcmbVRZ)h9onLoP;JB(nlz(RMhg<<Z?FfO`$G*Y3;B7Ny62{fn$>COlWL03e4#MQOE zJzgtTE##0`uyekCNNtoa;?<%JdtZ#SL~@YW(jI#@cve~PZ0y`FE!sn|d#frJ?D&4~ zXlC@s$*s9D9!WFvzR&;X_dL%Ka`|H+$T>YR&i&8&@6KtXuF=*<*$=hyrWD|p#Q5Bl zwUh8&314L=)$rFKf9QT*?sxSvkppv!a=;gs@#J5ahqdN%pV!=Cg#USEr=I<^Ro<XG zrEgxgs4fP0SHd;9gW!}E-kH>E?PA=gb*_8UsW9gh1C075=|3TRnaOR*b~}IY_z!ni zj?eFr+#cDdXX1|~r^lAwSl~~_IhP!uD&5a(GW6hy@k%l{XYck#`Tgc2eiBUXlzJ5+ zk4m;nTig9gqr3{*zwWdjt{0oMCk7m08OsF4XL8|POa^(UCjh<zlFKveb9;i0Xe#~& z`eEKFXlw_z$M6{;zSeu&q&{ujCF@knpZur(`}1O>v~qg3rGBtadvZ{oO2vI?G3GFy zlH-oW1avLOd8ZuoLg(}DR9te)v7wKQ%g;x}*xXet_Iqy8{@2=FvJiJn@q`~x#W@w1 z6-GnW${U$iYa3m?(SM-P!j|^3KtsG!ob|b|hy6SW$%;J1g=N@5oFZwgbtQv7#gv1L z)0f=hb&g4TtE<yqMKAZd@p(5Hp-*D-OOPR&P)hBho>wca`X1HFg>9YN%SRmWYc8F# zcOS4J1RSmeVg|qbsko5#D88uWCnNNk&C;o>!p-T^vP#Iqr-+(es=ow%qR0U$${E`U zpzl}&51>o6N+Vb3=(+ulUel%(ZqXBWI4#+X$8lN+O3=Nn6Y$`RrkIv-jL;ukxXjrN zOFG4OzTbY_qsQPvEw0?tI`<J(K|Vc*D`T6WaSky)GrRw#*ZLIy`38G#&Y6H+{-5*- ziD8de`KZ#ovr+kE`-nDb8rAuwL{J)y5`(-Dl&_0{YQL+M`l+Xn5Rty?u#z(HsY}Vf zyVcBJ(95Zw*~~O^yZ`<4_OFV~%pN`C;91`B_z(Hsl7f7cYB{Z_@X&)V?1}jnE$d&9 zf0wt``)w=wy}L#Ic2qPiW-zi_Ej)f&JE8}7Nb!Jfey~#8qdjR684$OnC2N0JIw-{) zPH_tV`21-c89+hw*wT#2AFKqwb27LmxIOkWg0rLFHh-C1?Upp!yw}eh<o{gE)|X4# z9nkk)P5#)&q9e_?AY@v>ca~|>?<#!Q6LExZAo^25Y0+cLGDe?>k?D}k?)iQ1RnE>4 z|JTx~vG_;!M)V^Bw2GE{@nGdnp`qV~UUOQtRSk*o3r~D5J>;FtNV8-{L}Z9@ppmf_ z>lK4RoW|)33O6OrLW6%-Zo_LgirPze3LZ6(+K}p2Lh&gH7w@L6T$?tL{dW<CE9d7$ zZ7n3nxW(z1k45arA-F{rf!LS$z0n2m;E7pLGNkXnN^Yi*B^I31uj<(xd7;rg`WfwY z{t6h1>xuY4t0d-2C)ge>7FV^^VzauDIjHq3s^CIg;@|chlLrAdfczFmei{1nnid$+ zw{BnJlW7_MKh-k5{BQDFUHfS7qy6%x9N?j4OET=kBqn4=2A^cN*6)5*>UZ`0j2v({ zA*q2?m!ofapRpf1-SkAbG~HPv|IsRGoz>EEt;z7;>q=gXe<x~%Fx{tWSNFY_{{q&( zDk-v=qc27OAh*|9wrLN(G(JZDCntA$^*<kO<_mY5!2bZS){5W3Q?MwHOb1J~m=)+( zsUV_1X5sUs|B;5_{cNp&umL+u%~JnRf%gs%;D7GCdxY9&C3l}LpJs~;e`8#j+5U!& z@7}Zr^u>Vm6a1rQns);q5TOHnX4{R)AE7RBe-Qr*BQ=T;uN`Gf+NN)<7m@WV2f4$$ z2j!!W2vxUG|8x}ZLQ3J>!~MN!;D0z3=i!yeK(i7&Z_b?v`rZ)#e0Vxw)Hxx~-&VD* z{^3tNfpPr55%(=ZhiQ4g+AcO~tFP4G_ty;kuR5t8_2(5SowVgQnMVC1$0R4>2lRdJ zWN<!e-WivlkR>rd;6Xo#b{VQQZ}%SQKFgybhG$27QPee2PoT5`ofn=h6L|O9PCZcS z<wJZ}jPW6lwZbGK1Q5Lg{3nu2K=uI&n0_*%|DPq|K()Yk!u)47^-nuB4UzpBB7B*I zL|m7nrtWX0lzAqH3a{$H{)KLqAg*ev801_D#Su31ge4;IAN$6J{v#-I`Ze_J=fCyK zO%XZB^Un7-j(h*EKWgUGXRWH%(K(kV&PNCSGqOj7)2JfvgTr)Luk|t!M2UiGEW-F4 zk$+^#<kw7N@(Rm`<&(^pwT)uyw;RPQ@b8RU5`*&-x`*xp^NJXOzqU&4R6NNvmqtBh zK6fel{{ruxjQ_)~e!KnnleJ#`prle0{}Yq=AMw3~tmvfs`8_G%4bzr`Rp7Sv$K@BU z5Wii&_=gg6YUh5*Ii}ZLc;`WFuW~?D@}xx0mvit1-YqI@6{3Ey7?s{!5V;@KH|I>k zGYtF>_)L6e4~@w`OBG^tWym>E535(%@t49Nj~hQs-(vW`^6^Qrnd@)uWcHEY_d5Ev z!e2ps5ty_0N3G?QQSH7R;KE|Wadm;=f861=s?Q1f!~+Bw#Q!g!!e9Dj&4<XDCY(W= zotWpdu4ZlzNK&9*ZmX}(82*>EM*#!>nT$4lbD2wyAp^z0JMO{$(Nx^pa7=z=UG55r zki)O_vQ}(uYj?k)XEv`!y$XMd`4CN<v#4*kX)8nE8@<Yly0fF_;cHw}^v_NBpn?Bx z@g0*U>MwLL7vujO><e4H9pJyAEA{odmQ#WMT6dMqO1N%!6%ijYIQ9s_26|Q90{&N^ ztBNWjrhv==!4l5=H1MBgKl>2k76MJkZ$I&We(`hY0DSJ}>b6SG>xJTHnF8?jDSC{k z7&o)jaD!QJh1$2)PsPja&i#gq1m>fV)Ii`%(Qn*dxA4c>_Iv2FI!DMnpXa{%)BUnq z+h_Pc@4SHjk-r9BaAD{QJbDM38{zRX^cyN_jLG<aQtxM;KGg1>o^QO!mI_;}{s?>R zyl(P&D|MCOzqD7}m%|<xdUVBs%w=hR-2VlY5NgHRu>L1pv%1;|j@pl)=FI(1ce!4m z*$(>P`g$2&2#jZ*7qa{N5U>i_hjj%;#}>HeMs@5=zDfR>5;En$Gj9Zedkv;_pIZo7 zTDLl3K|ww}dDvV#daRd@SuH@&fp)^vPI%^G(ylLnbzy!9)i!D{;QtlD&G28253}^R z{`oNPH}Ll6FSMH0?Ums(tp6UyKlozNpZ4rmPby7vR99>LqE;<z_3jmbzwk?R3|6IV zu^r^$my#Qvc?<lxlkqp={|urZ@n7vDqbygn>NixgDrMA+EN1<fW1zxMDS6Z<RLwVY zdsJWhTx^!w`4ATd&QA@yn*jp?>JMDEx`LZ51HA@+Z?fozoo4v`wXdG*w2*0(VCU*8 z!TbuyVr7*O>IcZ^Q-J@_e6CPgVRdya3-k*ol=-k|$!&fP@PEvIYy=wD|HQ&K{ai3O z{im8*Q9o_JY?U|j&6j%&|C2$<s#1n)nN*6@>*{Muz<>37ierZLqT=P_|1i^>jQ?wh zB53HWy8i6w(Z++#0seaw%UU-1Tc~`1J<!w&)7Ko+TpFHW9^Wp%;3BKV{pw`=|LRn~ z{o-+J?X3Qry1LaO@B#_B*O+WYc(cAmo@My&l3S&y9C5g0&F2>5^S1UU;vciO(u~R2 zNc>9$(%3dCdy8up|HaeV>Zwk%FI&gwAHIJN_z#?SO;3>!YO}$EH&KmG8JQM%1^VFx zq7T*ch>gbN4;7W^@Sp?nE~b=sPwuf!>xvW_>Pt3uPP(AW*26;a%YW-vzrg%$fd4z< z74kDr%xmK>dfl+3AcL^}bBO<G)>99TG5VMc^E0B6!|FYX2^`fCY4|;ie*xKCLJc*y z*J;%XnZpm&?)@#T(k%5JH1o5Gpu_p@n0*Z@;go{zhxNq~AL|a#KU+JF)5p`H=?FPy zkzH(ltW{5G@9#}p%4P?Kng-bGTcii&9@X+}^4c%%vMC%oTSTgO#qQxu8G-)+$(^uz z9@qyp49g`rM(Fzy69LYhxc-ZN^`NHV=5p}~MR$t{HfmUpr87U9fuM(1fJ)$VtC?HH z^si5|0?R&8D}x)`8z%$*t?V<n{JQ#MxZqpA8JzySlHFE6ZFSm}gM6>rV)zda`|gFs z==~(8%s7nwjYhLl+H;-dInL0)i2N58+7}v`<;nOL0>A8cKF{k#^ghq;Z*SDu{9T!w zy^wq3qMJ?ofR}sl*`9}4&&H=Q{oCZmzsNI(J2{PxUpzj4dfcx($sacQ_fDScWCQqr z1`ju88YF0W0JA(FM*T5$L*bS%e^<nyH=4AyKTcmz1cE8yfYM0J2`i-F8K3H`!}CtM z`f-o$<ktVFuf1Pk_#Y7!WUHl=)w@Sfjk9+h=*h(ho4;RkGyF}w3I9Vp!+++de$RXL z^bh-Yi60qEGUs26F~bWLZ?vSLM{VT_hdL&JKp|AYo1GorIsGHNUr?<1f}kXw%u~Tb z1l`$H%)Wuca_mj`Kkt;TV_pZG{u-TPr$>9JCE&THPH;m&?=LD|m)N3er<Gf-WNWLy zNOkLs&EJu=f*kBS%vX$Ofz@270r3^s3x47bdzx~=|9-?rrh)pjnIp&o2OaGPM%)UR zV9IPWqXR(&9>fGvH=f(0dJb8j+Rlf0%r=l|&Db^`$H|z#$L8($2Ling|Iz)-<J}4O zRzlBz0bF1C;Qd?y?-n*Om1I+6EB*;GkV4Q^VK%@juS3#c@6~EqA%;39fb45OIp6?U zcqHQ**CN8j{A00uiBDADn5dMqkFuYt^ponZ^QSM-i*QRx<k<_$nMMK<ILt3S(&;km z361*U^6`KC8vIZHgHHby^Y`^bwYL68^$zR*7f~fyS~l5`(hG_l7LDp3*3x{7z(5Nh z@yrGLPqOcqT@ROwn8J*9!DP3(`K*okdy~8>?!QtqWSh<3k?9N{vAcj9K{+U+Cljae zz9h!EP|c>r_?$AFPmj@eiY`vI;(x^F8<l;_rlw~D|LN&=|1tFWQR7AbwpwBI711>x zl~I8Y)(UtZ!ZNkA^g~RB82&FX{Ey=ujV<LEeLv>!1N`^TEk2KT&hN5`*%UVt|6bG% zEQ0u6xAoipvuwTnyQheM%->&rQe8%-okH|4+WXH+VL3kM0{$;S{wdT$$N-ptqNg7m zWAupxq%h{>G4!*DYE<8D_C|N83*z!1BX|^_tJA^+Zsmj4s~t9fr}rN;*TSBF&p8bm z*6sru0%{L)Uvxx<{bLq~<Ma{TQ-k==q57`1@&2v-%E*VZOH>AHFo8^af<8B!K*9>d z!2f;p>3UufWAY-p98)&ygW)e~7Aq_G4g5F#bd>%z)Q_;&m4EDK&S(~I%J;S!xnAeK u#A>&tA+iBMuab}ln1;Wd$IB1<?7dp0A*C_rKy5QQe~>Zlp3F%WZ~qICVY+qz literal 0 HcmV?d00001 diff --git a/testcode/lib/apple2/superman.dhgr b/testcode/lib/apple2/superman.dhgr new file mode 100644 index 0000000000000000000000000000000000000000..4886227c2884fac1259275dee49ac34c37a08443 GIT binary patch literal 16384 zcmZu&jepYC-ao;tJMp33q|DDH?bAC547<9`Lh9vOo-T+HGjCd3*V?(3#*3KYOJUBo znIfEj{rUb*62N(r4*|-_@BRCGIZ?wk(z9Pw@mVeQjec>VxIPke++u7(?^i8u@fu!M zw&vjzUM2cw<8Hs^+q`Y-S<4s05tff88Tu_bui1W)(ZLzBvQ1^JGdi8fKj1>NSDJ=f z^$j%#&bfZoU+z~Iir3cHJ0o#Lf2gqEv1S-kTgqBqO`h@hKWxu-dF_oebh4$o&p(LK z5UVH7l)JU%=iH2M)0yQKiPyx6l>e=QSE8T1lGLtSY#Tc^E2_&2MqzglJa%a*QOt3x z-x!XvcGmW4u_cH{)vv1bo^^J&4DLa9$m+lXg3LB?hWBlEsabV%(6FkqSM}4_t|@=v z2nY0HZRpx0Nprr9^|pQR&jazRLi#tN$!IbfIs=>A;Fhk>7}=uFEg#>#jM9~^A_=gP zPT_3%hHJB`Yk=<32|tYj5EGNpjQ=FHEzuY~Y>XT5mmlre{<~~;G8CPgbVq5e5d|5k zxAeP|xW@e|uQnmSt+v?eIo5$IY3|@7xKCa~3ts_$+g04(Yv3<M98T>&ROWQI{v3U1 zOx|s%MK$N<a2Ib(Cc7Xd`42>@_4K{@NcVNd422nNsV~4A@#nzmxZ>MLc(A0ZOc2HD zUGb>qy@vi{k}cI=#x-KuD<Q5+p7C&h$AFd@_=?s1d-}uCL+0U*2JZQsKWG0?H+;jt zVlhw24nK$`tb+dF>_E}cBUW@3hM07i#f5Kq@4!32YpOqK?^%ex5=AvUd26Rmf73a0 z?^?c(NV1ytpA=Wn3BMF(_VQe&G)IFggNAA?xpwx~cf$rn2~Jpo^dI^KR+Cn_X7L81 zq(suq^Dp+dc5}cyuCCEu?&sX)_EvjqcWWVz)2mE>L+i;-)2J(Dr!ipr1<ymsA`=u~ zH%D@H612vC>f7Waz@KNJUsKUf8)sAfLE2FZDzZq<E&A)K;V-+ncF|pawY=UKj;|Ep zhYc)>DS9~$KV?f^oPjLf&AGOkt^L`UIKE~3*^h{MME7t+yqfD|E1*f$Rr>@&s=PKj z12OPS{Vy5_P^k|x3v%06>RaD#8n4zDc;?MOtX~!4F5!RJ;MPD4Mjp5mRe7y>UBj)Z zkjC=1hK-!sC)(g1N8bQG6T3FDYSqtq8?No~H!=U=41WkM=mZMM$sj4^3Q9_~gUP|S z%`1efEuc9d>yqx!Uaqe37DKLpWJO5evp*mwMV~}I`FS$3{c6)-)ojMI)#89pM&oEq zF*?;B@(xmO*1Y=n^^XnM)PDylkS{@RCkH}e>)MtW7bNdgQoMV9)zy7?Wr=(GBD5xr z34J&T0mFYocU3_?wY{AC!RCnmh+=uhpGi#;n*Gs-`mm0gf{I{xMU_tuMmxk_Y`toX zKgVD5p6(mXva5KRCgC3oM*~<%W&n73NS0>`s+jJ!#I+KC9ivZ7?H}WxkSEWAS}nhJ z@p;K-3_j4AbCU5g68~aS0*aHmm#k;Rq3A0XbC=v(xwFT}`#}59A^nHWE;Eq*C?~2G zAIJD3ZD#QYI;bXys>A}kwrfyql~v~QEqC{Wb5?BHeMjCU60XVGHJ@czV{&C+GYeVX zKe**Y!v+w5_=~gP4?B#40v5T(vNwGzYg2R*t<?XpvrE;<P^<2;TFs*Rt2uRf&FF7Q zmQ2Y|xfIAB(-WBr@$UgIRR3%48sXozb*!MJ(DoBgA@|q7&i3zF%vxJ0>SuL#hCd-P z90>HN?@*0)5%25$+}hS!Y5nG9aHWbn3I7wxy_X~W!9G*OAWFR~D)V3@@jsUQ9YOZC z#Auf!MBSBWqWWKx{>SgB{z4GY{93ja_cK{_3$-`bFS4xt=7;gcH8DW~r@97u(2cV6 z)K?a70jo{2ga3NaP#7T<mM0s)|Aa=6cQZ|NH|`Q%?pZXh<JX!0g%}9BU!I6Ux4+c^ ze>WH7Uz}$iW<G#w3ABb-JD$tE$U=`}{J%l|<*tJ6C*@2?1pWlo@+vBsg8s@_<!8|; zh~e+4{=jO(P5E1IUhgy}b;N{ES;$_@{`kFfwoZ4fzgl<BsP?3}0{0+eBDXT1BR4X2 zV^Qi$=yo70Sz#ppU4!?5B%bq2OxRx1f6VDmG}E*6=EI~O<j`O-3tn4N)ycm{zD@zV z^#)g3mm*c()4WnZcZbdfXf^u7n-uksf|@*eov1lK*JR=c;NKOyrR*y~5rQMtpW=jc zqUw*z!kRz(bwWAw5V1S<hFbqs@eqLE?hMfbBIilY^a&>$upDd){G)~Z(fIB)@P}GN z^_QaHQFBRUdtf*EpF;Ky>P$^CpW{zdl6XQ?BNIRs`kSsYkB@er7b9W$r8V3^ISo}U zBXf}CPFk}@i2Bd0Le^Gy8pFD*`&db<g>wrlMwE>Nx|o|jG7Uu~9jX3RRHq_pE|Ax+ z_R;<NC3NA-YH>~C-(hY}q4hKT1AkNl6TARjK0>vmTGd6@@?do=9!-i=f0J|9_6^27 z`{W&b*T0$5Pa4fBe=&Mk@X$Z{C3GLuf3ywcf#p8pZT)!QETH_e0!YU7e{vJ{FL|~P z+OgH(eV3Q~#-Nccq5i|@1FW7nk1W0v=OJ*HJvESu`d>fA&xp=c{~-!AI(nJSVv2Ry zednxZ(JzklW#lJHfD^<x^%V^G!x`&_xIyM@didtq16yGqfNb&r@sKenhQPnlTyk^h zZ0zR4v(ae;^i8Jv4;#V(wYaK7r_<pg?x1X5b&bM-_^`BdSH}OP?CTo4up#kF&W9QQ z3ibbY@LeTGk=MbQurIq1nk9_phKD@ST>72|^?+oX)j!B<OsQG@ce~ESR<Ihe54Unr zc20h#8%q7sWuuUwe~Lli-`zOz8i-0(T_lhsxOYf@)V&AQtnKPRAMzRSkNPl1{h!xA z)kMCZ)F<{}AGTtKms8;{A?gPfWz`bOI`A)N&zZdJ$_Df|n2j(oK8n|`h`&U??7~KZ zl_>U{AuDiSJhb@FQGosjN9uo~<xwWHQ30p}S9U0uT1_l~4K}a7{#Dk0a32YY{~32= z2{u8u#QYZF-|zkW(1!QP`ji79$1P^4O!m)zW8Rr>ahraoW1hdHNSaB{dh!a7Vfq=A z?u||{-FcLKKy{usVh_Cq+Zr&c|KP9gBKHt)>OLs~z~5&GUW$dQ1&l(No#VKi@khU{ z<`$~$qMys=@Of)(xs5KMy}Yn>35^~7mvt(C;&0MF;7?Yf89ez8RC%cXcLvs4r@jV% zIRnZ)ah1qOc_A6*fB)T%jV|@vDYBjV`n3NN4TjkZ^%t04Z=(m<Evdy_%>Vu6^_#<S zMp0N(;=e$&hIJr?YIRbFye^{D%hvox-2cN)N!>%fcn>SUm#Bb9FO;WpE`MG}djuQI z_&Y;Xe<^3IQH@sG&39JygqM!@p?pTi9jKT(nrCsfhF)b>h3=uQGY@)k;J+X(g{e#0 z9#?n+_21K*Rdk22uy=Lx+58XhNPWN^d7u`E9UvAp8`s>1FUG?Y1MJ26K-9^vY+hE2 z-)AxY8@Sh35&c+-NEtZzL=ofIptGcIAV!y1@fM$mGom*0zi@zxm?pAX|MiX|o)>+F z{Db=M^U>JZ>C^hHwXHz|GRD!F*sJ78Nn`xmU&OH``yW}Y5P`dx{M8MnQ}$z`g!x~h zZ^j>adhYCx#_xi+h-zdEgBMlhM^XQ-_Al^X2ma$8aDF|@ptFL0z&I;<;=>kspQ>+s z1@2)>w=fczLAXGDdM*UzpIQGw)L0D_h30S4Pxb4-sg)=EckF-d-h6nanW3%%+Mot} za$?P(f!u>ho$!Bf`%#qO4~T;l;#L#*|44|qRp57g<QHO22X2)I=*^-TQBA!q@z7o7 zdJVT`IJdAOOSgcY>{g~Sd`0-zo9sIU`1fq~sD9dzx+DIOdmG>n{KuVW7LAe*+A=@Q z@n2pq-72Ctq&@(h|L!vSfaQhiwbFWVfVB;Fa#cokTK_%bj_MCNr5wP&3)O-6Y{&NF zy+V*jolZ{=k+j5gzrIrkhCc}AHUX$qf1#k805uN?;;#(CeY=X+^1}N1_m={7h4Cf` zqNA|*onZqRnyP=oo%Y{sm-5j-&i}waG62=o3H*(_;4vTovxl6hv-~+A3`@@O7wAe! zf+?;jSLFP6@V<KG!#7L}uMmGR;+xdfUZWa;wZI#lt(w2VJV=wZ2RWS*1r=*}pR5l1 zIRoF$R;mB@YKT<-RL=j%(Np~$>aC!Cg2G2)2NMPAKhUQXR7BmW#D8x06r=M1dqW9l z$=|!LOZ=<$uC<10jU&$g_(1)K5ZG103GH3h%zeuTsDHG^N%_;h#_UA@FNXhQekQ?x zwjso+%otm{>%hO1Gv51<clprC@bTBjKnu1?Dd!M%=<mSFBY{cAR;!HB4(uCI@+Ly= zzs>ruzu^DFxE}0F*{}zQU5g80?_gJ%>OU@sADmO)1Gx(Hig%Y?9s6(JLu=v<2^_2! z)Sc(Nb1`8`feU!<@n7?gqzLcfq&>ir*T_Z`+XV;#&#nCst>>DET95->TJ6p3g|1`Z z7^u{)r6X!KE^h&U$h|WAf&J)~tEf6GfsD-f7U7SiqC@J4OUysXs-#&mT~ht`us8M9 z%kK#p<TF?|MPYnbmGDmo=4$R%b>P3ASf5too`3j?DkpwNwS3I~;QyETe+xxw*+u`4 z9XCV@o&hYku?L78uugMdgPmp=g>>Sl40Wo$?0@4p#BA>)d!qmLPH6v~;vV^KE~?g0 z0hMOWub<Ek!RYiK&BDuB{(S`OqWTl6(C1*^552#!P{sVe{%UJ5YGstKsD+99f9Djt z{6H%BCthgfsH=xwgN9$rsmPOrI%qC3J?z#YW1>S?lK4j?X8F(9|DxZg_Qy){{4B0A zgnwE6cCM5@u6-|tnF7{NoZW52RrELTo*~df|F37gDn*5t+n|Nydy0LBJU|^7X8C4S zEy75}H(AubPwNlmim6viyuRz~tfQhx3Ema50;qpWRJYbJ$BhDoa?e~0`q(M=vsTl7 zV;K_vs5@i>$^y7+i26^tXGx_hRV?v9=0E%r2M%NNnVOgWe22$A?~qd<ElnX@jGZ$X zN~HyR;LNO)V8HX0lO-1txq8!<$(MLj?W1@_4f+CfyxiV3PjPbsUEw6||7ZNCx=V_` z{PV27b6YPkmhqNYHLK{8*M5QUf0Lx38t}=<lp64l=Nkp4>RIvnp#*ANd&vg3XgbeA znkzsE_TRIp|M8LPAJc=mX<rGny&ns<hxZM}nzr??Y_RpH)U17sZ*q9y6aM!Z`=Rlb zyW#oP21sn$x6od~`?3R+NB}}*P&l_3-v-^!`v19#PLVa;TdHCH$HZRZ4E>o63y@D~ zs-2yP>_iLTKdUa$zItv52NMD?tBT=h-Opqxbq$<s;XB&@|AWj(uT+106xjFc<C&X} z%Ij7!gBRD9v+HZ?>mx_x3TQ59{`w*2OZh6T{xT9_IG5YsjRp-o0i@?|h<}QHtV?XQ zi3q@E+Q~aqLT)+GM1f=}|7(Oks=$Q7k_RcO{UvpIx46Eges?*3e7FBfWhCSk_y+gl zYN3xxt#A+V?NaUT33W^2pZH@B0A6U2=DT~q9p-=9QA7X#unxD7B~$*$)i>dHWL}Bt z0&5z61e%Cj-!2{0P&<?jus?RjgsIUZTdqs_w~AgB^Eb|#_n)N#X->8$8&muZ#g9H7 zSu|@dcEH`GlkCtrlMTYu{#31~!y_8ds{Z|C0L(H!I-wpUyA_DtO|TbR{bSHWEJ$AR ziceX8LoHGNgPus;S(CPx_#^C%==lRC4?lw(VFMr48t~U4YIE~H?8*~QajPG_YKR8< zL39kL+sG(4#filK`n4^3{w6ae<V;R)H`6I{W|iHNTkR8FS}fy_^cNF!Qh5IM=ii#B z(vw@Ir2l|*Qu}|3f3N!8>(hS%tIaCYvHyOBb#CvVa-$G|@bDAer3`Gz)3LLW!~Q$) z?@WG%)--id76yOJ-!4<}4LfAq0h+Lf`}zEj%9BJCW`NqsJEDyJH@9SG{o&<luGt_2 zz@l?iE#}TxuQ9;WjV!XS?U(E5|8Y<UAn}UbAB8CtH{ucS4=$he|A?lTH)NBalKO($ z?otxw%_Vq;G9XnHM9S=ZnBrePSNHUdVRY6fzYFY!%RazaQWca$LIk(opmy?ipn`8R z{Lje2xr>{7n~SBr&AoevhljLE2#nwI9n-<=Y@66GG+bQEp<dQHq3N1t*fZSsSW6o$ z+H9?Bm>~qj(Nvxp?l*d-`)$~n`k#nr_@-uob0y#9n|rmr%3f<#N-zxA0a_ed6LY`o znmvQglz!gQLd^)l^M&!hA*WV(9CgI_#&m@nnr+t0hj&6VY#C4BpubNd5vB2`;m^>e zXS6}NZSs5hOLKwWUOhO>xEF(9aw)E}OA-Ja5!hcEJt;xT-wd?{jd*p0S?)fg=%)fd z76Ae+z{BS2W|(JK)y;R!%C>n7|Hu$b`C~0CIj0d18(|(o;pDyGuoJCH{R7Y(!LoBJ zNrtOfs~CUiJ;T)$S_n%(JA5Dsa8K7P>-dKOd6vhp^5T7PiJU}7${&(O(vwo7A1_}% z5sQ{W+$-k5z57H&tMvFmTpUJ_gfyK$Uz*qg(^p;XH(d!4C}XS)5*fzy&8+YWZ|SXk zSMTY8`_w_ZNypUwU(eI)ZAW6fQVBJtSz1N!vf_*5ONuG*??gh0?L_v9Pxvcb!Oovn zV7Nnar?r86fqQhDSIm~)j54gH{V5QyR2Srt>Yq?b{GTshzq}seZ#+b69x6Ip8)yp@ zRb<j2<vV?6NQt4@H0k+v_x(?oNAUhwj#y;Zv0(X7Z~hqw@ulAT=?3_df#mTS|Ac1# z#R|o48-uTDbl+;%C!L;2lND(<7u6(pMq}(_G-jPkL+zPeWenqjyL<&efr#$GGO<^5 z_f8Lf{upzg`TvI2+B;vR>*jtN`0M7|T1#v3R)T-XDQ`*a1g<jvC0g*eatKeY0{@0t z!Ef&qA6&=h^xQ}EleXQK0sL?3h2FQQfvNr=e#FX!y-n>rkMU@AlXtTR`xko$dk2Sg zl!<a8Kuql;@psL(nZ`i=nO4!v5SV|U{UekEctG+ZrVaO`Mc2?oj*xf?UE_p)B#TV> zw+#9bHjX)T7YAmz(%!q*G@9Rbg6Ld)E%86bP7Wgb2JlDOE?I5lLoK7}__i;umn$uh zhW+V~836AAv~QYS4Y|#<o|?|(HjThD`va}NNzPIu&^-)SVAFgBGH2Z2==v8czhJot zhR7zvK*YH!mKC<pky#AnBuJohbnCQIN`OxhAR|JvWvaZQG04z*@fQE2LQ<RJkD@f8 z1_^@U%U9xBO9%E>y7@tiy@-BWk@#<|9!>sET9cfq_1%|dg%ymBYh)BQ0REvj=t&N- z1&~~kNqE=Hm<0x`k7$gCj8ps1M~dMhIZjq96+AF#=PSVA-6IiFTOq^&l+k8(Pwf8- zGNsBxf*&X22a;=Sd(!MaG_mqcvB1ju?}UF;zlo%m`d{kaODxb+nAU~JuE8o;5Tf?1 zT|mM=<Sn1$UuDsK7MjmYuCaXU_uEgNCK3el9bV42Sb+=@G1q(m{`mZ9{!KW?Htm`1 zpI(tK4HtPeZ$_qeC{}<tqJS9x3;qixV<%Ck&<PE-n{VxnFQ0-w<=r&;o|_p?@ql=5 zzN9Gm4F6r^XY>GhYY`P{(OSHLI()vkxq7iDbq?4b+9w>4iM$R8KZ$^B$ScNm!haU% z>g~&{7euRxe@K(JCUPldQ&aC5y+C76jxXo&-(kR0*`mH<vAtJ9E-LZO#Z7b|7oA{= z|G1+FdL)PRkmO*(T@}=SWWC?CgOHgr_Ynqxhk_75W;sL!jPZ{Q^y_7;)-?V^1oX!` zNs84)<O^hs8^|%M->eM#VpXSz36Q-yD4xhY$Umf)JUQyWPM^%EQ?AH7jkOX3@B%9F z81fPNd%S0c+s1KpECrbI4@83hgrW|_Vm*ZFY74z1p*{OmX5!I=&>uwFjCT)w!M|t1 zE68;F)9g1E9Y`Q?ctrV`9vK&4g=a6`kLjrp{gTE%J{~cmgwu2#aXtvHl{L#m7Bs`V zdpAZyiYXx;?AL_`|HbR#^@jUWYir?32Qsa(0sZ?3!asNi_=JtdXsmTPB7`BnOojd3 z-N$51@juJIpLB}IKf!qAn+iQV))ATPt{4w=N%y>SnRb<lv?RkXh$=vqw>Z<wXcEAc ztWF-FtN0f2QRe63OV;8qfq&DH{ns4-M3cDt!@t!tcW*yIG^@ZLke%rtT$(K<L-QQW zAZ?WDj(5hQZARHm=Pk3acm44l=tg{TpbMb-Z)uEdf?aR(0W3_m#B?&Ve@u;{Dz>c= z>e9n))c>bZ-W*5Qfm@;(z*BR)Axqa}>VfDKwviVsvoanJ?nuqC64Daa-%O?xOXOSk zJ<<J;#KqMA*6Jqk*4=C4YUS_cH~I5?DPK9fu}Iyf_!2or=KoJQC$hT6S7Cl3PxaGi zhxE*bc){}XUEO_C=4VtC74ai@rn~au<CH%#V+d+Jv)n=~b$J`p$NAx=cJHUdor{5B z=!0YfBJ0FKK-dfCWFf5RM(>nRR1O*P4`oV7!AKU$LkFmU@FblT;2%HHnkoN4Na^G3 z2AdjK+cgV3<7V8|-q%OZL`Oc<aK1D?kVUXs`X`Y=3ylR1-?`>RC%e#&sU!ZW_eT~A zq6@Q&35ihH)vROGKN61oksO4WR3Awv8kiK%6{>9RkvRTlr9yXHMk6uC#)2+uAgz=q z@5=hGp@;a^B<qv*<N<0}frWZkE8|gCMeAu6>xFM=I+VYq{KsOones>djV{iD>*y5B zuz~vfZ0*K)xI$FLMLrrTb1UUNz4uxOdvzipfrT_A$M%nN07*ib45KvipUHoL54UM= zgpQOydiuF@`$&kDCl)JnoLZM$e`H9j9&ShC(_Vq@%LD%f4fzG+;yOhV5c;K=qauFK zXcO@tW+`t4JQp*c<1e`**CPVsGrTRUEC}*}S?T{dI4&E~1Mt+Gr1Cyhxj0;fZMm+a zZO|Ksx52vu-ZX<kl8BjQg~><&{$Idr5=$gRs{g$9sH{D+5c?JynH^z#H5p>OXiw-C z_zl*Y&0yso>VGo|_EwSo%RC&9&b}Q}|4*5Ra&QnKJMQ6~?(AIvH|7MN<&pA7zrEO6 zY{fN~SI_}q5?DM$_f0`0zBqp>|NT<hBT5TM1jMyqIYg%lOhjf66L!m>EJ?iQEcM$R zbf2ti4jKzUdh~_$c=gFl|8a(L2dvOG9^b<h(BjWm@9nh?F##ObJM#IT#QzFWjK;*3 z{FGua-_k6O+81?R80BtZKjsdNVJXUiuCWa4p$i16^I_BI#QpD#e~f>be`A?}JH!ku z8x~FAzn|cLe1qr(m+(%?+l4IXzbge~nV$J%`)Z8;7<mCCq2o8x;+SN$HdeNd_vsk| z{yM9F0<zA<z`=F|in;|Euy5d=i_YQdeWLT=jG}5h1kagm+Xl)-S2KDHIYiZ@_HpEc zDtRLKIz)z0wXPoWCckXIjrSiwDfNF4@i}^dxD2-|)GZ)eYGLzkAciKf7w3nU7oTF4 z<am#LjnH`djl@3~1~@x1{sP>CZ?Jqt$rPHHLiiZ<7ki@<`en)=d3x?_9KjzI^vtZK zBck=D7$atIgZK?E*!eH#0jwJ4Gpq@9LQo~k#xK%;EQ;v-GKimV@dT3UKk~2SKl48* zs(7I}lX2K)gG1m1v$e#3_-ZrSZkx|Y0{B(tzZjoV5>@%V^LJ$6ypB9G;M&D;%wKjN zh?Yn()nxw+wtInlKI^}U4rL#_$8m-D#%C3CuQ^7&KgW)btp5_zw0e5}FVKzStKZR= zxrnmK@!1{JchaA_AF?u5?4u&!Ud0te7g~^&X8N}dqs3Bw6S%Jc_buMa-_Q;YTZ{J& zFNhTDeJvlP&tjCY7m^L69j=B(MbpEVQOAAJ2#W@MPI?RcZ;w>YbGiSA>~JTn80{!v z><Y3VNlwQqqyqZTft&7OzO`7QorwH{`~mg<XQQJ6D`zNTWJe)Hi>!gwDRtCJ^#5%m z3JCwrmx<<M)QWRtLh*p`U(Sa(;U{KnQ~yno5p!n@^-pR8iZNA*|F*fH4@|SS^6R-+ zk@bHRF`%F7|CBe$fc`t=9s1N>RWk<=6xIe`dMCV!8>XdH(En$6m@jwsw<nG?{~Ujb ze^>!$&-mjwLha>{82tik-;Tr+Q%+(B*oy$3GQ=s(0q_8_Ujg$!zoZWEeQbT{f2^e_ zgmR#Roiy}d`lS7SbV;(|Nc9()L~r7c`ah{0SGw9W%0GI@3Ktkh<oW}oSjk(iqqTIt z&ttyVkU=!ecXAz20{(R18g+obio(VWJ#wDvZ{x4~Z~8pFcBir(t;liFLcbDn<uW*9 zF8O~B|Gktuo=@tuw-f8q9b-fwtzm@#caXjAVftVU^C)`LaYXrt_T};0RDVf}(2oeD z&$nMKOAn*|<_B(gc05@@yn`I{nXhW{KBnw-qB6QGiGQ<0`)`sv_ycD^o!R2g@Hc$I zCJ-Y1zu`aDhpxRivI$vTs{iO1)Jxi*B8!qfk}H0dCn7u6oZ_LSRW3)}JL3Snz*~BM zEU@A&$xii9kbd-qR!sH3=!gy`nEZLZm4B|4^3PHKyZKF2-@`Ln);fy&?}R7Oz-wAB zmn*1jd78i5)kdi0C2w#*M}i4l%83f7BRW<vQNqR`$*G{H@yCFD)blv|UVWagELM06 z*$DGLe|H*yd;A{|31dIe6dwC3Mr#lIZ^i=R-#9>hcDr{m07}hqB_@!@06sGyk9}y< z+BdcVVH~si16zgj2rw}HqwhoY9jq9=ulL5{SW*fEiyYi1b5)%C=t?__*sLOLO`iD} z5N&WJ<deSwz^BbJv<n6NTR*=I(8lBUnf}O?RF{%-e{wv$$cGF$08>cCJw&^*a)LX= zdB?$hatCg@+Hm(Z)Jn}zPcZ#F)1+!L>(CwG9|fyjRM7%-uP6m=(%z5zf5?^Ee++7~ zTpb8e*{;wX(qgQ56bzpdG4WtE>de-q@;;@>rij@CIfm*lMLHc4h4}V0b`mNGpp0HN ze~I_s{?h-al;Zc*8{5Ksf=wTe{XF1bf3os~sS{9ynIhDH-lyx?V{|qYU)cZeeK;I= z;7=BfuOcd9N1Ng|V2Z@Q;r!SAw*+^HgI?#0J0bCC0sjkOcyT=Zzqa{+1OQz`bsW>N z6bhbEc0`$VnGPvJ<5+A<?~??0LH{E5-(?*F{^TC>f5ZQrKa*OBzaVSM=W5Tn?wXe$ zrCrCgpEWy?7-BDyRWJpeJw3cWrd?l(JRlNMba~-DYys(67*OAg&#{M6|I_ne?EA^b zim1FlA&+Rc7dIDgFCO9-!NM;-!N06N$WpxoGr)hvl+WKnvw`O&33Zuk5=r47j(&Cp z7HS(6?EYx9qnq+a|A!xd0O)`khUwoj3#$ivhl`uds1pQFjx>e*zl~r2FWP<(<8NvO zRLKSO|JYZIjB>A;L?4BVj78LWRMU)EK|Kxg;hx!%^Y0x0KnUa?*d6rozs{O?S}C8_ z;ku&tg3Ji@AIqWFZM;U2PW?xmedr2Qhs?nAjlWVefi-jnWOF(q?D}Ij3$wow;+e{R z0~_4Z2dVzFDAt{H>WKHDSjIdn_umHX!z0YYhqPvMe>@yNVesKpcdUO2{4?x7{t_Db zZjz^<yW~K3jgiMf{tUYbUDnk^8~w+4Le`nuzoX&_IVi=agMOn?LCwUz8Fp6K-AQL4 z*^38<QIM{hy%YWmm`F1k`Ws@1xTpAoA*2-B$RqeqGT>%$dj4i&_mB4fX8C7Ei$1N~ zZ(Kfo0(tZdW&kt-ee(#F8+U+QQh(zb8Q;gE3hmP286fh{pD&*TSOu+<9&8*b`HGpL z9Wd1YkLaf3UWV4B_6HrRXM~L&(L5eJ9Z)Qw|HgBj-+n(94P*zp19b1lT+^$D=YyT- zkhPu}=x-{T5XYoHR!R#%%OZk;?2UQ@9=PvZDuNYr{3-V13X-4z>(mf4SO>T$a{S-e zUL+|Z#?_QJ-sN*Oq`syC%2#;%)$MQvu}6^~TVF&L@4iPS5aT13^#Aw`a?SYvKP<RK A*8l(j literal 0 HcmV?d00001 diff --git a/testcode/lib/apple2/venice.dhgr b/testcode/lib/apple2/venice.dhgr new file mode 100644 index 0000000000000000000000000000000000000000..9d3cb4c85fa213095c6b72c9bfbe01a03fbeec3e GIT binary patch literal 16384 zcmYj&jbGYm6D?A76Rcf=Mg?mNF(7#&Pz0nT<wFb>5G-H<0)}*5wHPF9)sQVI<X^wT z-mCAGpSW7vc|K;&IddlK7B=dHu;Czz8v@}V>O_$cj)njGNi2RcSReSSgn;gki@SU= zk{hM8!vXuiYvFT#Q*hJk)kh&(*{Z}I;x~;0LW?=@uv(d^+EB^HH5NtCRC7P@4}7sh z?~Kj4bxPbg<zKef59II){$k?vc;H?{KJ^RkQ)1wEcpcuVzmmR5S7Yb?L4Y|JW*SAp znz8FAezR|ms_So=%9h5L++Mb#oU`gvWrExSlPAKlfLZk?{vG0eEE`ps2peFj6^aY6 znmOkw7ed|WOZX+<J(txo8gJ$_4($xQCBNVw_;0wC^^$+EF08M_1i!E&RPP;saD(vr zXbbVxJHhXuBm~Ej(s;EY{CTrfb)Cl%i-_-pz+M@@`2t3z`1@=qryVh9WN{jgJSzVq zJ<oJQg-|g45?`><Tf?!I8_lyEuW~CF?@$O0P=tRV9DdDG{qQrEp#<T+v>g6rpDUco z2wOs2hzE{Nex2|1pXO+J_#i*<!i6wE=)pZQlvpjN=4M0A%5rnB$_57|2Hp{}##WX` z_a|{`={3GfsBgIVsbY?dd2VLSqT?|iL5S5TjUAv8`{0NlQ?yU~$A_a|%OB4#(0<h= zJXT{QS8}6NpAWm12~CagZ&8KyAIdQYukj<kpqgH!O(Me)WPsoyBg}y(;?>OH4!u;O zmLFf@`#;&7s8J|$h@WcX`Pj^jt$EZ+<;<+cYdd@Isl40gEBX(}JdTpfrs^ziRGDzH z_)|=s^U{vCT6sj~$UNr-|FLs}kngLF12&Jc;c1uKOm$H=$RIc6Mb08~{#oPiJa99< zkpCsVILbF74JX47&^s3GMOaOVn$gkJ9P`tX%TX5yIxcRaO?CC06C1+O6td)$L`=7i zmb+}*jF{7{oCP1bn)?Q;5EYw`AVL9F9dQUbDKtc=pJRq$geWZHRYQmfdJ*;#-DVRL zrN)P0ku}G|Xf|q@*?#4m*HYTWy5K5tqg0ju9Y2r+tXS&CqVtxX<uo*OBL;DZDR_da z<DZ#%7LC@eT=9>{dN(8xwmUx-?x?@!Ej7e_pt=+?Ipjn*d^**T;D!9cg0Cwe>&Jq- zv?S0jqI4{5Kw=YRq72oy;vM)`paS71>!<z|;Tq0~C=TJmN9?<}#+`o{9l4K>DzUCR zKYd77*=n2~c3mTPiO6#HDTlJzJ-@~eM_mSOA~q67F(GB;#vf}d@>)OgdIC${L9Fa` z5K!+#$vc3r_5Z%B00x}G8cx^YeeYCYD(>4h!h8K{+(B?EA1Swl802BR?yhZBtgBQv zPM;mngP4N||5DS)jiR|Iat=9;8&=q~HlP@^GtP~pXz6xzH+zZib!Epxb2#nK=O&N* zD-d&KUEowUlwRQ-{(*PEKxS|Z9kUUUm^YbCMUnz3u+@h6s}d{5AL8_qZNKV2cUR+Z zyYA3+EtZU3WrZSw98$+wcG!>fO;%%}sCr}G$|1(9K1^QXJ6w4q+pr9aA6oqg(!4j` zb2QjPyow&soEO#w{{tG>T$g0s*{4oSZCGPy!twKM45f=t-MGeI+!xKFQjKo76Za5e zJ<HEy5mPgVTq-miL12X7E)O`0X>!@L77bh|kH@d|@AuPAVM&F$v#haUnTj>b4WaUQ zm7nq}D8xBSeg{^rA2206a<pllZ5_lOh_|M2LEj655~=YOLRb=(`h>s;Oo7qvOX&x5 zzO~WM4vt1VtOzkF+Xk+BgGgl~%mY_+Irf(KUiL3Awq<d-u*62P<6LT(&5dW~*y;lg znPV0e<8LXNEcrLwLhKm-@T+K?BRWPCbb~%@^!g9QKee8^RpI+kGVk4DBkww2*Zcxe zK<bB-liluZrqG^q8b(JdgK$6sCgP6Z$d-@4#6Qprjf|^!&%cAhI_E3g6iu^pbF3W= zwT+e1(o)^wpb62}N8M#%E6eB1VYHh<tV*aVib<*d$N5mTEYsqvgov|l!B!yhOwb$j z?vD_H3S2;G|Az&+!CY^4y($Wz;DCAwZ!0qX;z7DNO+9ehaLUh3^Azwmpw|3FVl!G{ z&$({A=<3wrd`;D)x#>6;jrdD3z;jL`!+eC8^2Lw2Gixs3>XF10mftqrSSu8a@`!(j zR1UH4(1(473Q^7i1F@0nz4lToFAMNDi4ue=5rW$Re82b#FJb`Ix3XT1LG8iIv0il$ zmBPVKk~K!A21!?m1LT{GKxkW#jr*0eYOE5k{4A_=f7<ZKGy27C4#!#d)jH1wdm8hW zd)SFQc0bN7OA%asqWk~z|B4st%&!6SuMiIR0KQg1aSZ(D>jOdn1cG;uqe9SZfIDEa zTY~>>yc9bMJC*=Z*0ra4yfTcK53Crk9ab9kM!u0?YF26EW<DgT?d%vu`{z%5e+PMk z=G@eH$rZZS%$NOt`A$!vK%*u<oDU;Am7V|gPK5Y#;(>E|D={Gk>o~3mA>UH?pB48x zdB9&0Lae%4W+Jf&P*l}T_e7igX%s&Qq0r6GF1q58RdL3LSuWKdPP3@1nOvVoD9C5C zV;+Shr~j4z3pU%Yxvg*Y$K%Ox%xl~`?k=|C4<U8^l#B2y=?b?}YdKu#KIAMWS@Rp$ z|0%>H@oGE3^@r7+(bL2FJL6nFPt%9=;Gj9bSNZ-wDnIX~bhAJ8>d`FI9U<n91^gf0 z@h0CotRC*TUiObL$BN(*p!%}>%+hjmO93dz%>e;4_5pBqP<3w*ZrdP`Uj_b;YO&%} za20>nh=X`#vtVlM)e7x?AZnl9u6LQxmW=Z8bIT&A2nw6%sGIWgn(8VsXbWuyxgn=9 zG=?40uLVFgY=3lJb~k?xcnKH`8Ipr)0yNU5!|>ZZsH#oB9jzQNORH$>4<7UvSN$bO zg{RMK&GQA~fB6|PYnc&GuL};x)`J>Z5}LG=QoCVQQ^$a!2kiFVy~YNe>W;=i)gs!K zKYZCg4g6a>^b)4F=Zr`A2#abFemu|R##*${fKqS?O%$vUaOdvZ!`snq^k{&_D0ao& zn2ybnRZTteWuX5B|BFuGLRVpVV?({?Mkbm9Q>r2A-kMr`Hq<1Mx61@kaO2vUe+h59 zOb88@UEVbNfItJJWuwLHd}LoM`AcqrSJ~>H4^MQ%z4XQTz>HI6>-M8*_F8t}Se2`6 zsws_#<jxeUVp+vMx~PwY2IizTXs3!%p&&MNs*$5X@E(Ewp+Yxs0_r`WAcjIO3qbDw zst$C%zv!-SI5x_l`9YBb7Ql<ViJd|=4!nZk0&T@Eb5KAJ<~gUa_d=g1L}2~evco(# zD-8Fft_t<<v>gv~6}^hG(X7qk=fWzAfKHFFH>;I6BzVeUQ#VJ`m-tJ5PJ;?R-9ZrL z2GqtWd@Xu~_0x4nY=t`oJ{Gulu`>q)+NzC`4@CFyU{8pJIDr_&gr{nJ(5(Gg+bQz> zC#j5>@49UXq@Veg;f5(rMP}sgUsc-&F{wtnI~G6Ap}OEzvM=%T%~2GzrlHMqMpoq> zVk#2+?|?Ny^>Z4x0w{FquXvqeGQV_2EDwiq`bqH9j{<SP-3*})<5$b#mVoy^RpSDV zTm$0f*Ms@N6x1OakB8wLgQ9`RoW14Lt{T<g_=3*tNH}_le{AzDjh5!7WzDP{x5z(# z$UE2p4dNf53HPuLFXYaz+{Ap&$iM3ojiqA;sCrmpB&PaU**fRd`{GbluA&?MD;#ZV zL@_su^;4R=_fdo6R;JVkG>DO)JsDt(sKy0iZ~b)nCB6`<5I#p<9h&1Ytik~GZOy0i z@jS{!`BN0);W+Y$cHR8+;o;aHmP`Z=i|!y%x<}?MQ{2&ZuIg3S6#@I_s*HV08>(o; zYfFJyiiNC0DswdDaVj0WSGT*-pqXVOm}Bqi6@Tb^|5C~2--r+PBEx77w3ud&a+;x; zN-q1Wx>|J)8o>5waGNJ0=4jpr6@iEf>EYD%+wk=_jlVIS{5k0VqMI&lY*yGJktezg z4|&Ip`R*`$<b|5&kT($Oawr<XuW^d7z2XmjUnsKfW!4(=59|PL9Gz*y=x{!oDo!Eg z05w}(uP|NTSyOP2Qj%#-LD>H~M-`MX1hU0b;oDp#H+NfBb@_(wI_NsxAV6zhqb#$( z&5!o5zrDssiy3-R>4v0O^>YiM?bq-&nmI0hh^?@^79Vhscf)zt;Cn^ttzU4_<I4I2 z-;IY{p#Oa+mE{WQ)O@I&1J8l3ih^9^4_2$`$j9-fl@*rNqW~i;VM~-Zh*1cAKq^{P zKD^*N;C~UPxJa4y2A$Na{@?Mr2Yw+0Z2w>XUnG3~BGltT`8&KJ_!Qs(R{TX&K6Z)e zGc~8A`k+(}Qhh;7Ef-lW-mO=LwU1TyHh$$^TDiOjYzkF=AvBy0v65@pLTS}W`9plf zBM>ya9JUDAAHU?E%Lh9-MOZAd1D!wU4hQty4q}CQ@DDtoLe>}jUs_)&G691A8DaaZ z8m}H!_loPsn*|)jHM9Olg^lE@(T8|(9WjHB1DHuoc~AXYa~74gE?5wK6Y36aqv-sX zmFt!<W|n-3?_fD=o*T|{knzKa_tY!;S9Uah3Yr;8%OBdgNr!gcm3$(D5g-0}lkU6U zZe6im;9rv2n*#o(DrF&h?s;GmaoW`-#72b8#KRey&6=rS+38S8g}d*#U+3)UCzSrN zlQWCrc$I$DAC)DCyX(+$<D3HAm($P#w?YhJRd3ZTuv7MwJLl9eaoiB^Ls%`jV)o<3 z`|3_*y}BhNqikfc)Xg)t3OZ5vLu8=#8ulNWSxwK^EuH7Iw0W<p`$fVPVIoNVl{Lp{ z!43Lp^JV`brc|c<euj@^tYHrNe{*aq(ae;Muqp?tjNf$F1)B)y@53WW($w&LS`ISM zoeJJoIPmd&y;QzjeIWXt;{92pf>)SGyl<T^1vPW3-h-pjXUU+$9a49I|Gk=1+X-UZ zhb7-j{6x}5^#6ix4RN4(GTAwFZO{z?pPEs5z3Q&w)veMp^#4qLiQmlfLk^{(<M4H# zzQoQl7pvp=6?-1l+*&T+r)>paKj~O<U_maZAtmJuI*(MOfd}9W0y_s$<ntYmyakv2 zHGU~sBEk&Gfan0lgWesDPT)v$CiqOmu~~&&6ZQ~67X=48>Q5tES&oBuz%^D)J1`L> znr>C1mT2XK<tw=V{F1P|0a~B$?+rL~<fTFgX}`3c2%<IuAr%X<Gy~Q7vVB|SS!jfr zUFi5(b#I~8waxiBTZ{>DM-%7IjcQbTDpAOtCFa)XU+3(Xl{I&sstGNM7?r!>&Ua`& z9JT%d{&#nsqv7$Vl8tiThN!oD%w8Dk9$bjO5f9Z5`roaFpcb77-d`4A$NhqLumoP) zaebrcuOBbiA2`@wgx(u;KT(YV7OXqM{)$ToePE4+GGw@x8Nt;vw6Oyx<fhx_)<dfM zRPc50zw7zsgK1@&RkKqKPzE}s2;ykB-G3Z|oLLfF4jXh(+)I3i4@erVgYw}9>)-(_ z^gmO9_@~en0QUHA)>q;;u?IUd@E@pvhll;Ta9E9%{9dLO059%o!1USL^op;>Bdf@t zj{#2{{kEFEL3HSi+^3>PABS2h3cQO{SUNaRM5)_<_5VspHb>?-I^>`=*SJt@Wjz#w zU)-s#hgig)$Ikc8;{z{Ng8VCf+Kj$S-Ne9)J1iLiPS_~05AkrIWIlX6kBRHFn|5nd zkJtXGSmmgxsvm~ol%}fGsoM$Ck_@o(skTGo=AXx}`rmHbcF?Y|F*5;zpg)1WU*k@_ z!PxgS0+luJ)7*J$so=X|{P>5@JLU)-Fjvb$Ofa!Q_h)rWGjF2M738XX#eMJz9cm4S zshCyc{Ck$OBCM8G*(h=_2;_*j`=_>(MQF*f{#JWAfBL)NK5k$HHy%!NW2pVqEH$^Z zEvQ_y^KOsP0;Q&tDEn>#$Ezs4VhIf)efq2B8u)~dH)(Q9BdYG=VFlAZRmtwA@F&!4 z`i3t$c_vcHMzoJv1PwJ#p~xYHqcGSu>)?L*tN3gDfvt!t8}9f!a9I#LUWorJD4`*E zm6aIg1_U4oV2uH|N1&bzurm%(h%R3r4*rPnw|{ENO}59&=0p74O=A`8a?3%4oL#TE zW1!&(QtRCj(?ZjG6e_rG7|jVN=<GUe_LunLAm0ebNY<KaIY58`t3mE+=6F5@06rQ; ztEv7IV#_YUr7}{yo4fr}jiTWViMWVcD8tROy1D+*+5-P=xw{ha2^eaE4*Zp6)DP%> zh`4u%F%=`JI-&paB2M)LoYzkOEC13RYUzM2a^{GCN4?v7h^yg<Ij#Zn9T1hxTSx)$ z)f%*~))=KfCM(?SG!;JDs{Z1-umYxUYV8M5OjZ>755LNEkMa~&q8NzbO)^IV%E^VG z^Jk#uOVD?Q0(cM=an(aHFZ*}9yet1{{S{*67}(w`Km|J1;YEN3_uu$WiHF!t?7Ya( zE5|GOBWtvn0I*O<Ev*VYkrr<@z2k~fWyL2i+>_XFFkc2Izxsq4%{lX~Yy?4%=67x2 z!Zvczn}tn>?F+}f>Tj1Hf#&59X9S?n0QJ9cAaA^modx%U{`U&$^YlvhwD^y2-I>lt zzn~H8U2=ei6=TA%|ER@F?CtcNU+}-Wb-;XQm;4cv%Ym;x<)bRH<|+zK7yN$!{Xg&u zfAgt&|M}H_@cFc;G6wBE)}|wkQmH}g9NhOYaNj9dc0rha47knW67cWxZhd+3jjzS7 z)~gr7&%m_!FWP~e#5aCab|1Jx{N`Q?^$s<57OQ{*z(PGi|If4D-ikjm<ke0P@Mj#C zoMWZ%zy5PMzvNh*f$KdsXJEmB1E5kc+Cb-^Jwje#=Ph$ntkb@O0L(S?mE71};7YjQ zu0CFV*0#Fq8n2sL^wd1hRjC_9tG!q$uB8fmu{=cTy&4AnJ3s=F)`0yGH)Mf-?E+Qo zzubR`v28BQK<GR{|Ig>p|670r;2xm}+)BK<RNWK5i%Y=2ctkIn6}ONMCnGMJ2ziTS za7Tkoz1q?~o<}Q9k*UNgj}l)sg-~{`Mu$^$w9iKFq2K%r-A4#KKrYB$BM0@?@e*HP zj+Zhw6`Bw2Ega7YKg~|Z(0^p3rWt}1#Hi9w+TU><pun$Dift(1pdoiPmRNsC)xay9 z^Ut#z3+^ylT^F&64g7ClU=+^Ir$abNX6hY!t?&?ffUdIuvyi|}5cu~cy3Iy^I{xbe zQyf@Pn8NVTCZdxOtR&LAuP!;j=IW<!;^5rYk?&ww`88(2Pf2I_9-n1tFwF8>*)2VH z5zP&(dGQaGlo}7Xu<XYpJ9o-aDA-3Bh3&N>Q??s~I)vUI9LT^nXoA-jgnY-#ACk+9 zLCOO^I8?cJJ1YCJ8ZX76-%V9nfd9DQE;DnYzZsb>&vZD|XtesIvUlJPbU_KCLjX<a z+BON~jND@`dP((y+YjD1a;^`k6;uKb68Im!$4^0-G#4Jk<;w}=eNc4{*b2C8@VVkI z5rV(;876Sh_X8iVSJwrY#0gy@jJ)?7L~3j_hu+kP(+bcV2`T7$*Q@3zQ%S3F!5L_N z*D>PY^ShLn;H;^Wat(j&BXt1ogKG)A$1D%J#i3dcul@gqA1pC2$A?x%W6z=X9o_-V z|Ek<MOdkLPVwLrq^#?zqLpJAuj(%PJQ)NV624ALW(%|`2pAJ&Ht0LrfmCqzA&C*|a z?mqosi8g;ro2I}lVW&ei1w)IwPoV$#F>q7WQ`vgi|5Bs-YrfFlh6y>hbIvUM{}7t) zt$0J=e!Wc#I|IMdZKoL@XlRnxCg)5sR*hBJ059BEwjOx-55YXQDoNT;<MgR|-(!`Z zA51ZqVuvdD|Dz*l(@4(|S0Qe8p#Hc>)Vo>vU;pcHI7)ioSomIw3G<05cmN>m{44OQ z&=JO0FjZJ819$nBJ|zDz`uBx&b-5gHY?TiCX_&N`?>0>{oU3N4>j)P@+P#gHdCl4& z_E65rdb6!tFS_y95u-A9VQ}DnAsh6TqnG_R^n9bVOf@)&%g=Kr)ZR2_4d)sdCZI&( zRUa53gis&+JZ8iE);QA0n|Ep955fQa<3pJKQ(KR;VE>s>`oNuE6;cmQZOb0ddxKI6 z1;c2h9)JpdcgRFI)k(7|tO9hXy;^^Xe-N|dl}}y<pfMCzL77HmE0@bzxoI|9T87A= zFOHF&5*uN*&(PdB72ytu!e;f*b}yvwAfJAJoUvMZZq*Ly6{qW=L6-#rre934d&KbG z08HM7D2swPup%4euQzCndR4zR+rg;NfVtvPZl0Uw=Fs_TyNG%R-uYgMprhyP!;$=? z611)R9o;{05=?1^)@>sag&FcDO}Ytj|G_MNjFJoek0hBmb2%;q;w}WOd6-AkfDHiy zkLCzIoHw75CkO@;!V0hT-~B`v5wile2mcPv02Dw(<BzJ$TYo>cv06J^%+*k{Tj{$b ze-?Z-&di2czMSZDfe74bG_q6hOF(N@O7?>!XKf9~1|V%HB?ce35RDyUhi*6Q7*s&0 z8A1yd@N{wNHUD55iiP0M?JyOE-@@#R@BaIw;48Hj#1h+kbqY&T8$PU6${4*Lva#E0 zh>eHcA3<jT50riNYtMwd^JqM^<6r~7T{g?MXUT?aH`?7<>`ayeWqnt2-lSle%EVP$ z6*pe{Pa7?*h3a;!5Q1nBr%*q^3-uuO_uBPZqP~YwICV*F2R3%3<>sn0bY;vuGgosW zPd?i2Jg9uI3lkK{>iif*Jb_9x6bQRTm&=j^7&2yxTU2Hj&x$11B!M{7YnEcj6I|{o zXVOdlVU(fFT83=tGpW6nz$xsc9;oj%PSz6JPo>AwSLyowkD4eR*+2X2EnoXmPX{V7 zPoaD$YM<5ebtjl{mF%8>U^V+&(z<)=<npMb^#07PwJrH#X2=(Y(aTKq_Rny*0)6el zq|^!hwf;JPwmDM3xB%cIOPNVhO(gfFM5C?f^+(c}rM4;0vwT>@eD7VTV4u_{y*BwH ze1``!!_H5}7glAX!ANG$7=Iw@(su_fO=c5JYW$eV6XTma>lso@x=?~`xh*9tkFqWw zd8Qb?tiJ5OE*5N<Jew<UH#tk0&nyFOt}RIoLryhr>yu+5Xru73?B?k=N=Qkz@W3j< z3wT7-(^Ri5Pf$J-ZtEG{Be@!@;mn)uTaPij6{LwYl8of@MXk5I?YP+JIZ0WOj@s>I znh1L2m-sz=;M}m;eFj`jTWK5MK+K@|9xI9=wPnvKcC*@&j-AaU>fO9CLPLqV3Sbkw z@r|yvGt}Tf-mIZPPS$6AkFVsjH@7FdzIs8tm?^XHS);fsH6&Ppn2{v$;z~b*b%H|3 zdx9_VKl=_b+r$nztxE<Rk1n;Wwq;G)x*^%^ln<jk!O}Gz=ta(ISaW8{hw=s4+-{xy zgH6(ruF})l#~GZRW#I2tMVGW}3sEIWR#HT<CrCy^>{X3+PE6IvGqRKv!!lVUio{EF zo9)t{DA^|1Y@!>m`}WAt?;E1r?ri%)s1oQ*c8|74tG-ZR70mqdQAdaK87FVkk{s^n zY^2;Q&*k6$UPJfa#;GK<{rH;4CLAV`&pojxUOY?1#@D3StA$IAYNMDeHmb=QA;OsN zWd#W@?XzPgsIw5D678ehc9*?=vQ~iVgBqxx)c;;9;3sP(YSs5<jLpWf(SdW?{UMcQ zLo87qs#qvBJ-3;=-Byw+QELRZVYBcbP*qQ>+6=+DKS|e}c1Obe;^KA<?9tiGzt*3v zkbvq>I3L#%Ycxi?5_kfm*Zx_f>Iv5g9;~0d74iMji96Jmo|6<in@i;NGA;GS`nGT5 zuyWL)SW2`yxBboCd$Lt-?wo+NVDNw9%~?A`2vb8J=~o%ksJO+H4Dl_)(ZwHkUJaPM zBlFnSXZlQOL*D=W9?)m)ajhVy)~;*f?mkZADg0#j4TUe2^R|n6*fZK~;}Mc3DjU~H zs`JBBSf-Ah_%$}^XcD#Tl--#To7!kk>qgSZz-cL>q$&U~?XwF=FGEgZQptDv`uqd# zD?MiVGgz598_H5W(0Hy(bxCfo?bQw4EdSW}n@PG|RMIWefU8Qol?-^a-Rtxrsg^g+ zo@J|?sPLW1x0Xlr`0%y0ac}0@+m2WnxPe?dGs=v514&BCNdOl^R^-32=4#XNx_=Vc zZ7!;<n?`RuGt5O9{)YgIYJ4VB(q7S3C{YQDCw>=fW6UB0%k9<Y&NXxBiIkcf!Cuxw z*&Ms7Z9+&fTBLSXwp-qbQYq;M+3v}`8C0I+w98_v*nk3yUXenc&;V2Z-v{U4##~@6 z|B%|yg;`_8P{#1GX4c|9h&uvsHE~i7B>htw>t7mIWV)S3_}l4E@~#v7(Uh|nM?(Yf zVuIUkz7Umc?NF;!sVz!hW1<9^FGKz}Y8T?+vLs!|y;>A&V2<s(m-wVVQMZk38AJXG z2=FYoWmBH%@EC+*1O%tuiMb%B0%9OxU{s>nF_efXUA0MRRg%A#qOioE^w?hbm1BZ- zHf>?Xw@um6*+o^JCw0J`aab}(x}}R3rAASzhR-B%U3_I<n{C7IdHZHm0{mI**V5Z^ zSN<Ul<n0?bm>lU_N$Xrlejw)iM5{MMa4Iu}q%d8A6bZHEAFjvtO#JJM(f+tiOOG4x z-q;D75EkTirk1Rc-*%;>D18GoKO>7V_&e}#iHqk~UhDq^{^>U^sK5mRxG0RyQ*Rf{ z|9`8$fG_GXu@<b`3RfljV@WYGlim;M2O!j0XY)7|>|C!pi)?4|$FwuaG_m|D@jJh) z+a@)=tt?+>S~EQ?B?29tBqe+X*`?fJX!UXFmH&M!L#X_{`iX17{M6b)0qnu+sJ>T9 zY&QV`_TN8lKa(4@6p%;!Y)rX=c)?XL0yv7@pAC0yU;SOZx8VPVC?!$Y{_L|^393%( zPlhDva!+bs^+f$j5&_^Lep|fU8K(j-_kZG?^`Z6`ma`6M?M!SWLcvR2IjK{1X{}j* zd|wcc>IvU;>5~te*c4BbzjdP32p-vJdz|Sza<bw3<dPq;J5MB2U$!T&|24iSwjihp zWv0lPank6iyKVg{S(Ee`oPb{3EKobI@qKTXwDv>+`EMC*V4vr;lg4%9?}pS6)^ugK zR%nRffi1M=arFvzqpp0Gwk7t~b6P&de$?NaE!l{(XT9DJX#dK+x69Pd#4t)N@|)6! z{m7!+x;RTxa<VN!MO?9lAx2%-o}l<z|B_g8+I-JSP62H;2ls7m0SN*g0$2_kUmM1E z+-|p*QLn*@Z;VokY?623YodimB!g{+qOwu}iMI1kXoBB{{2~9<o_8S->$)=Q{Z@)n z5qP&nIbvrQXXI5<dXkQ$yobh4U(P@24CTSF>WY$~8>58{3hZy01^}X-+V|YK=(Tp) zU2l4*F!29BN;xbARw>u_wR=eMcO6w8%ayVL_^El`Vm`VlUT-_LT_t&bF(IFKT1WZ? zl!_$5->N0UNzni?1qkGNt^bZc;dAH?Ytm`UU!|{*BEJ>TAr|BW{RspyRlvTNr46TC z!0x5t=bZFcJK38Aq${Z{g*U~C9Ju)X8!pc>wxRy9z#C8@fQyGx2A&p7jwFdlW@O8{ zkQ(ratzRT-jiM}&uk!yt{&yH9Wg<UIEg*=QHRu`g(yfPfR8TYh<E-V`Bz<@QZ><`c zwhiQ2TbJ`o5M9)vnvLDlnf{zmEHUbFUWM-ixQ*}?0q<I{X``{I{u;bXq#zZ^%9bd} zsJ32d{IC8KK0p8`Xn&vG2f7~z{a+3N?=LU_UM^~*Anh-(!S15$k@9Tb8_UnT?cTH8 z*xjO>;oXVL7kEnlJqvp7&uF`^NB#0)mTg#(B;^}z)6Zl{kpeEQ(~^StqA8fTrf1Fk zYyR5`Czr{30TX4=`t_62iE9rBrx<%)qd<cc-k+>J0xG<zlM;r`9(!#*a(RshJvRn! zA0@k>h^R9pwn@F++7-XFaQ}|~vmMiAav9X)EGZ~PyRA!^nIT<>?cWRi@mTs48eJ7% z@(&8bP@p3K{jaol_W^_ct^;i7sqI_Pj)mR5($~(9cNOQxQX&uhH)%I_Z#|S;NpE>n z(k-Vvqm4qL!Cx1Xo$%`S)wQj5@969f|8w2}2Ae?|D>Z2d{690q$14N!Do~sow%@P% zAM@Fz)dzD7R}a=(TbAS$zK@G**YEc|hP+o#)t}*cp?ot%%xK%Bl<KtK6otP!cj<^r z$F^(Fa)0?C@znY8(DF1lD$9YC@%e{+4{KX`Liv^)C%*xv1VU~}1_qLiT59$ecH=pH z<9pfvzX99ZkRA93)@lL+D@G2004e~~=-K<WTr9XK@%S)6x_h)8^uMRjxjjSM!DWiM z?zBLEA9bB2`|fq=j*vb}_cR%lCo^mHyO_~)L#fqkN#Byo0mq0u5_JKDWBEc@a@~Y( zUgCple@i(_9isz;rhr^hau%$>0#8;+-e7mwwKqumRs%_5+O+khi7b(ACW85|9+N-P zn;})XO<n7-cxys9S8cW?If3CiO8k_Pt=_kzZ!&0r<ny6;D1}>ucu~6m93&k!{5AfT z?{gjlU2DnD_2&j?6!~8Nj|(REPK@f%fR@c99dcv7N=tf_riL=ob0evBCUqzj?2bKm z;i>cp`g_aeTz#x>F8f@0OcF>9Dju{iaFU=ySCgxeWioLgT}VHLSh10R*}jeRC-e3Z zP-ExE?ky-LLx-n{<n4gxri4n9PIRZW8}3nw0Oa(z*tT1<%&aF<E@`Agf``R+&!3v< z*HHhU|E1fV06ZLO7fDbW7Z0#=sD4S@)#YLm_@v>Gib)ayCMS!p`6sL-Tm`7~0x&NP z)lcDXusv4+r|Zyv<Isg;0qmOG!=MN8ZRnQ^MVtB7n?NC#<fOY4?EC-)o4fpvf1Nn! z|0T{2^*@m$&@wicJiCDULwMveoD92YPXI62ntW^NRsT6o+tLXhAa$~^eS#%i6kt!{ zJ*=j_?*i^GB`)_b_v^v6jobLh)y+&iWAYR$ID<G{`UzPv^7zj-yOyW@d*T@;M`>xR z@a*g5X8Ra6RG_xAiab(Ay^4`JI$Nl3khRWFp`YDX|F1NXM=9v{dJ7F8iEBrfC%6c| zcD-h=>(B)R@x)rQnXq}6LN?oD$PnF~ee4cDWjO3n-jGI}N77gFWNwQeaMW{S8@p=8 z`eG3vecPbsEIHMbQUjTkWT|!m($bJ0g>Di*dDZ_myMto?U1Yp9Ua+oSza}36eG{do zOOlI#fhWwm%Sn;G8D$@blr;$|EVA8__Z^e%10F4wT2i(~S04y*2VW+4BbSe%=4zYl z0bMATGG$vjj!_D<^kHBOT~0bqJ$KKq_`6EF@;0AMnkkuC4&0d>^p`WpKm(*xs=>+z zjXM*^SRm6dX`4|pNSeI8Ji^@^qHmK_F_MXb-X(S>ZzkIlhPn)7ZasJM6Q<6TmfTvX zpNt;Xo28T_6)$Sil_HW7;kYRmUJ8I*0xY5eyI*&o0d)a>phKJ)^4PR`*1=uq+D7C1 z2^gJwDE?ad(NlU-Qd(`6-1X~>)Co#x7POT6QD-boww-v>CVk%8_F+;jI_g1%ge9pB zHD7DgV4_x$YAN_hs@9-wF5!Ri6QW(Wfd>O>Y4<A}XGxxc#wJD{+zy%sqp?=H_Qr=b zK|PPy`3!C{qsUTuKQlfn{5Ez24d}lW>y1K)V$&ADNsK5RicceXcrm$XleeB)&$7bd zHYpw!kAQ#MfI`G;c-y6K1H;;-%y_pAO|mNKqbc<G+tBx%QOWV;57-xz@Z*7HwWs54 z7qEXjE304H?Jc+>&`cQxJOR+P(kAAt^+EUE;_l*wNE92%p57<|;(!8!sa%mMCab`K z;)R%mNy+-l{%!faw~2ZHPt<Af{y+z~D7=8}VQ+A1`|m|9*1-wD5@eF1ou68v*?&DP zh^|(z+`|iJiCwZpd(AWb+otES<ilLNbLzGmp%aOO3|PwR?acFq?1yI=C`Sfh##y3l z&5T}p?f>%>RH-D^4e2PK0L~9$g|~&${&o>~{{%m*@8j2t|Ej0=S?N9)7+sD;subM5 z*$&{(yA$bXmtw<bPqJ|Z3Ik+LAoC_cNs8QB&bN(m^ou#WkaVd7*Lo|Zem?=P>@Sb- zo1@qGSo=t^fU)3DMl<rMQCK@#gZlrFC>=>U`CLDFe_c<kE&CGwq|ZKfD0tz`?dp+y z*FovquhsJPu0;}sUPm{!JO|0jvQq+&t@li{ez(W^M44Hml%WrOpgZ;Q;SBn~_P+B; zYHq&9hs<)y4~x!w@z85qZtqHP;$IsHyda%Q`<;}hwYHoOQ9Be2)u8@*)cUnE$iM@2 zrO9q+6zNTRMpEw>#vJe;Uv+L3FYn~wReKe3__waZ`PVK2yM>?9VT}~q?Nlv*-4VfZ z@8$k`ZW`=xyxE4@gH?d`HeeMg1>~djEUk`Gb`PDT5^HJymnNZvD333F+qv%T%5H2F ze^>6xcM?-#XSaIGMO`A)+-R>w<e}~H85|npqAia=0XQT9I#1{TQxXfeLD+5x-)ns8 zGYlW=a*_PHD*~m-&^Rb#%gX6FeO15#>piX28ZIS|ui#oGSf|u3|3%UsJ-VO#c>65h zSmCK5-zj5{bG2@hF7uy!_J9ay-&Vxla}N}_)Pn9`(yQxd`juX5K>rI)!Aty0I_bm4 zHb6>{@K92QK9CK)J$s|zb@3RiF66mebz^~$+yM<)n^}}(bo)I?1|j0~m0Ib@+4SFQ zxViSWc-9O#Pbdt-0%6ihib-7-NudFqfN~axi7_ebwPXmif%yN`KSA^2n^tKCjyClD zdgH6~TQPJ@*ro|oYD%LS_)SS#YC0ylEtg?~G_}T;Emu>PbU2PHz+!UYRsdjcyVoBj z$#MF|CAw=D&%40$y8<DSUqOR>B}F&5et==M!vjEo|M9<Vr2w9H9V>vPOF6-Tdz*lk zE3uY%pU8tBzkRY6s8i)a>2s~zEK#N2Trq%IjEk`}3~!SqwR5}dt39QED3M(ntKrQx z|ChXdo(~)bLCq21EVs|Hu-{{wGo;gm(5w)l?o2v<<sVxCND1ypR&M3}?Lz6Kz6bjE zdM&t3)tlfvHs7CY7XTkx;cgQjckV796VUlX2e7w&-MO8OI&YE_r~zd*@o1z(Hn*tm z2usbr9yw;Ra#2*;dh0^Zw1CWNBVa#c))wzPe<`p1FZKxSmLdc5!c!XZej^2r=Lz(S z@Xt4%r8a(4PpwH!`_g9{II^I>J=8`qq-|fr?BRLjVkP-;ohd)T!?S(7OxE8}Qq%%B zm-sQu!2RgZ(<)WzW(_uY!ClLiY+Z#v&(~cmulfsf+o?epW?t}`O)SHJ9yA4rbMjsX z27Y}1Ea~?l-*Py)lyTcYe|Li9Elx9(d>E>9r0%V3DUg{x@V~a3Ok+8c`D0_;iTB#B zEX2NOwV&H<IZ(Gt(yf%NrR4Ehc=?71HZm{y|HWS3C{Yvz!U!B2i2t7#F$3@5E4W6^ zJN!G$RqR-E%WVoUe`u3buANTtE#BXoBnwZ^a;<k*0OO+8#(kHvDwUg_z1>9quW_>7 z`zEUwlA>QkK?93Y@lYJqbh#<|ZKurZ`IG*T({>I0hb%Sph6E@y2lEeX8p}{z*Z2)V zd%*il1f(VdNVod<TdLi5$c-9F%ZJI}Nmnj(CP{EFXA}JGDwS{T0*TqAv#qh-`uR;R zh8HTNm4Pn6z3_m}E<lIuiAy%e%l;*QBL7CGpn+JZC0K>b$iS-#dF@&&Hq*Cn&N~eW z2D^Aa2_EmIH6t=@OkbFq(sGClo$l_p9~b;zj1t$3YWKOwZE!oviY|?%T2kL_gBBk@ z$t?*<jaoo5!r;gYWMSzwej{1Obnw-Z#_sb%1vP4NuJ5|TuhBv277w1?dHRxnBe1Ic z&f6?((ZR}>w`8~77IpF>IoVa@@o#8YtT7&36+5lE!$t}hQuteJ(h&Wk3lIPoE`a~x zSsj|FtxEy;{~azw_e*?RA>cY$quhxNaNMB_fG+&)9(Zuj5kM6}4^V$xgI*j*TNf1O z!}Kwf%d@P*9B|<C9Go5QwnR$Ibqwpn_VIwa2yNM+|5osm&<$ii;m`rmjW$^#;IX7O zB(yHK^GQiRd)5CoJ4hn9{r0>KzBlL)P~3&>ME#=v6)<3bqktWikG9{qJCyEQ`UyIk zl8Vkd@j6u5c-(;p{&%l?QOp;*?%nRTI?XbjvHxx-6*(aLB$$1*_1|(0QuNG%*;8@` z2J7sidYA4e!Y})GQ5glecMP)^SZn3|^_sZ$EEywdEeLZM1N^wVj&xw7cxp!3l)O^& zC2zZv9n{HsMrZHOo;%h73;Wl{n?!TRz3N__D36%_IWkieIHQ)LNcu&Ybi=;G7f}P8 z;?%b8BI*5?_{S2=Uv%&ZCXj-_z6*;)TKl{66^QagqNEejBiiu<Mfw-|yPop+$bDz9 zM0HqE|2zvrlTn^*8J+g*j!=2J9bf}60gKFj*m~c(VrC|v$rG|z-viw*N|OHVX_o^3 zJxILnpIqAT*<F}x;VXj&vUvOl)&i9vwSoM|JA&T+h6;#E`wyW1C>d$r_8mVCkR}R` z`FBN>`Sz>Xelnr|-gYJmm$xD~R~<^2C1>9hc#|gJdm3cnLf#Vtpi4pQ6)$Yx@%+pF zQ+_6owQcgGF#!i2_}BUkPRs(2WouzTff5E@J!|exGDd=yMvDq&<+4;_Je2q`W5@-j z-%@f)dvZywHkTw9;I#e80oYfS+Qex_Po7z$Mc)tq7lGK2Q=q=(#RTvrKIuzhShSS0 z!1bTaX1R%cFaH2W@&uO)&D+kcG}#R&k5`?g$Fw^&PFS#k$JL0`ZiB{lk~T`VQqzAA zKg0aZL-U9BwSXUYVPlc_mXVTeNod@_3<6xZh2{^47YXSMw71YWc=g|V{?Fe*k<K)E zB7JS#%EqqIc)rES&P@oNwB(Uz0$mP;H(9+4{;#bES!$HQdzg$MIgc*ea?|@$Hb4Lv tSa1~{Z?fg{4e?OC&_VSJ{{7t>aF9U@kd;6&Ab=ksB{5JYwO9TBe*jc`E`R_4 literal 0 HcmV?d00001 diff --git a/testcode/lib/apple2/werner.pic b/testcode/lib/apple2/werner.hgr similarity index 100% rename from testcode/lib/apple2/werner.pic rename to testcode/lib/apple2/werner.hgr diff --git a/testcode/lib/apple2/werner.s b/testcode/lib/apple2/werner.s index 6456ade13..f9200f694 100644 --- a/testcode/lib/apple2/werner.s +++ b/testcode/lib/apple2/werner.s @@ -1,2 +1,2 @@ .segment "HGR" -.incbin "werner.pic" +.incbin "werner.hgr" diff --git a/testcode/lib/apple2/winston.hgr b/testcode/lib/apple2/winston.hgr new file mode 100644 index 0000000000000000000000000000000000000000..074ff178dafd641584342c249b06d3bc5712eea8 GIT binary patch literal 8184 zcmZvh&1>7r-p8-igc=7<VmKz7=Mv$w5i;0!S!}3Ou(?|YJa}`2%3TE&oF1rgNn+3Z z>CfjoBgt~p5wVrgXuiMqm$8YK{m0Y{hN(#p<GgRGy{*S$7`wzU-(FQQ*`Ms}K3P@G zBL6)z&gf=l23mVKalhj)%hQp|lgAhPQ;%(CKJ^?UE?)mt4-;L1zv>Hr6z6mQu3yaR zG{3~(6%(GnKE$gRYs(iq<9T&_wRSszF5w4Sb+3`F7bg0_^Dqvn`Rwr_p}`-e%Le21 zKHjuz^~N?`xt8~^^TgVteQ?X9=id6mv9QJY_Vu6_p2O;cc(>P}<XJDxp$1x^W|XdO z#J)y@Z^lOQ=PK+d_EOZ#8n1`((pjEBcett&e0FoWdyC$z{p&3{&NNfJlqZ`(%S0=g z2q4bA+&gqQKH7sVdGdEN-{KF)%YN9sSoALOt%d)$=OW$L`1@TM<TGAj1>oDpR*KIC zE)TX?_`RkrjO&SWjnpKgPv`lD|K4~L@T=qPU1H{8as4?3-xf7Ga@ZB&!I-a!@Wr!m z%g@`LWK#-%F*?I==XIL(qP+h-IzMRehvTb&zdPQz*!calryuFkt-<g-r5)P-V)idq zJlE@NIdG>Uwb@bl^D_!}9y3SB*FVukJI?st{^r}tX1~gR3;z9A_zM!4V`CG^8M}Y6 zk+2(k*<z2_nO}Dtv>?q*oIC6_YiwWB4Suu4ImEz%bd$=c8K(l$^K{dH94}dQ<=j|; z*jp2=BZFEClvQSShtUmOx}O#k6ZOW+<T1q=J)sY7E%uWi*`xNHY@`1KywtqI-z0{$ z>@NnN%j~ez|1Msp1{FbBzZb+XHMjWy1>F8vT)SbP=ZpQo#rtQBuYWhzJ7yOQ<H3zm z_vDRq0j=p5_kRKZSN?J3O$uHD{?0;cG1*Rw)bGXIikm#?jScr(f~DW&X(*ZqKsf3^ zashwPLtg8YxlHcw9N|wqI286=M4PXz3cCEqgh*stAbm3r!J}Mkr)I(i^A+;E?)M_( z>g8{D#e(@yIM(ZbpZLV_p=olggAe%ged~Z5$<VncJF(MVeEo<2Paj=;w{%1HR;Wgn z(!CsOYUc3pbDI*L(-HUz(Iz7RFY?IPdxi9<@Os^+7=P`k%fWgacn?^c>5+xyM4bN_ zru5mxkDXHpymsq8{0m)USIp7KPZ{+Jy<#82R|3j<*vQ8xEh-oGRGtHrR(Lx)17QvG z{mjd~6Mio6v2xz4uKC8M8>ikC@`v~+e0PUkvk$TteZBZ-zaWRL5A?;$LA0a0Euq#V zm*J<O<WKkgLvzpf1^+AI?|ARY%TqFy|FNr!@+r^I5B8ZJs!^%{@X?vfkq9kxFkZLm z9a}=dK<io?>%ejQ^3eUi!N;{@MIcXtT>Kn?$?6DCq~U^?2Y>q+5odOtY`s!FxCqGZ zodN<*?@hGOoJQuvf{6T||9@g?6>N4be&5BLbQs~r7~r~U-{l1yE#MDoDi+)HNWghW z4w&1+lf7|OIS}&wc-`P@Z4e;%`Lsw{Dy>OIpBou8_<4V*5TgqNAaHa>K~$C4jduaR zCe>~wqIPbtu;=o*X0|&YG=26Ru^x&%P(HnWx_4An5vyja^q=64JZtbbGHs8sKlPlH zTaTGNDIovtp9O4H0s-Ge_QvNwUk?xfUbbZ90z*KGRjI5WMiN|cZ@2a^evI1r7T>uc zAz%9+rbxSL;Q2nuY2OrFnrjja-n#oV<p2AyJ~N;H=7l2_lV964^iN^Oa&Q;9bNK1t zy9mQo;JYFGcJZ;NYxmvnIr96eit)oCg&RpC3}X+KVI9xqEW2*_!7ZlyQ;FQ~+*>0R zz8m?I)~M!$PySDQ@@clU#Q^!ANN|Cx%FA9)KahSt@SO!3j+XrsGWg60UuomlG2T!i zeC*7&_@o}aL*SW_{#tC^Nd8xZxf1(hjqqpQKX0*nC;Z2H{npnUJ~^fP4ode{`=3XH zU(YQ26iN`D4}1oCwa=6?dWPxd^_mc+A!I<jd@5$PDu{q&y`8xsb7B0W$gvMk7bpTJ zB>&4rFzPR4<O3P@N7yTVpa1Vt!@ClNGRz@mZ|^LRWK<u~;w!01*X{b{x-#h+_xO<w zH5;ud-44@$ub^?*kr{~kqrQ9bM)M4Q-$iW(y5yfGgzOgS%|aRY6<R}{?~ley%z%M( zDA0Lc=l}T@-l&U`1GI3-QO4K(p(9gOO#!}%*7KaGe*I(@D?*{(@Z$oX?9yikUttww zv?JM9WiPl>B6{MYD`g;67AY+ll&tN?Ppk`V2W`)Of*wQ#_^fIjF!x~V#o-T{sW=p) z@9_!0;E#mgl-SSkDSYz3NqRAE64x1cZl^BIt9$S<M+Ho9|4dr^bQybjc^GA-{RzYM zjgOqI9vA#mnXre?p_R{oY+BB@N*-U!bO}!m{e&=O7Pjgohh1;3N{E(#b!L)}OK~s$ zCC7`gNgqSlO*+#T_|7+h%KxS+rnOHkBxme8*a7nAP62+Q{J-B(gY5o2KRnZNR7HB_ zYlu<2!JVP{{lK>0TCMQ-0)IFr{mw-<Ef$q8fox~dCwxnr(o7%!0NeO<_uw{vxEJIe z8P?;6KL5*mWFzmv{mi@@ep-Ap&dC65tt+Ac>|~(PxOKUD#W5p7X7_PH=U3Kp($_Xb z&Y6)JhZ0`XnNu-D2V-yaFXj^Zf0wuY|0DP&-3)k-zHOr{-VX42rps3+ls+mm>HkwZ z**}-bHriPGO$M|5^pEHc_=6^kQ%__jZnv|TSet<w`Ae-e|1a0S;9JyM8=a^Sjlw6a zIr=Hi0ivt;E><2!YNFgnfA}ZZ1Q*C(M!rn78D;fslzwk@)8Ny84<5BU0pwl(NB(;Y z&%$SQ^yR0GkdyDfMU6&rB4|>Y(}HOwoYaG+A@?+wR1=T?Yv)`2yO@x#cdFtR{CU`~ z{uI7HH}EUcZCV8VMD*GneER;+WUdUS^+9OgRyk1d73bGL&%ew6!&tpBGONhHPbTwg zn~&*+{9ijZ4$@3pfA&%D8*r0<2tzggYd8Er0Y&*rm8|O)z-ReW0V=3-{@}i%rOr5@ z|6}FbD@n-X`(*L~yVDs&*3dxzFFTuU2%03rcY_Ku%59gf2A}jo0xRaSk6yevd!Oi- zUc0-BZ=r{(mf#>9mp-7G`|7{-`ojBFj(?!Xcj#fl-gX}}`0ZTY9}zk3)c-P$^g+0; zyNk`>(f8l<zhplYwIlyS^5OQ#VI1GjCiMS02S^+)OUxwOYnKOiH&Cvk97cE;XIp}8 zF7SEBAtGPydwe20y_U>qyd?T9edbh-pa(<1IY)&ibp!fZYx-mXXheWSN7nbjua4Q_ zn~WVEg2{5GPz-X{I=}_K>-*mN1E!+tL$ptnRoH-x@`xGS#mm7kRxqHl(Y$k25fq(( zMey4D{u_0=5rL{Hv^P<%jCQh>{WglO&K>9leooY;$Cjze5Hz$W?nnO*<`vlB`wXbc zMoy*vm!e-|woQ+dAJ4w|BAk#hJb~eZ^Bk6##fC;JKhIy_Z|eRVy@qOuH^{8$%l(x5 zQ5~s?k^B|h7SQ<$euhq|KooQ~*hP_|8#0;f=sfbus7di5p_73w@O||~`?VJTwMh#f z{=Z`U91&9efK33>^Q@N?uU~LXUjc!8NL`G){Dr*E;GMgC&<#KC0$+QtD$YOTWMp4I zIQWz;D>$wCvO|wA{_V%O$msvAebU-;0lsshw{PN=s;1wK_}HE8;`?(Y{EFuW&DRys zvsr-K|A8HhYW@xWMyd&Qb#nZW-}+Yfbvsc1uL>SnT}a<ghmVW)qve0Y!yJ{#v<>dx z_Rg5qYCuF1`}`55{MmqcJ<RU=j}TEx04W4RGMN}RE7kuGMq_^#;OAWhQ_BB7Ta;<r zf5#2~O9I4l;8nN708X{=$@1#|oBq3|4?1wR(*rJ^)8||{oW&nBZeKjzp#&zQ3tT3* z<{+$gC?-tu<z4>Ili?UA*HwL_{A%&-;Z%a(^xs}S!dGAH1xnZF$mcQpFSe(WgE*DU z{`zK{Qjbh5{JrHp<k=oSw({rbjnFsJdz?*3x$W4M6o79yms$aj&jFO-G3O6D{zUHe zT4bU(DIo)X=LCA$9H^!Andjrj7GJCc-u8ds*2*^LfhoT=Jv}=^$F4*#HXc>>2K;)^ z`s^^;S<$TZ@~J;KnAI}uAj%u5@aSLl;5Mr96@EMNhfny=eNXS@;{%z8{IEXx{=3HK zE6NF&$XNWN^Y<f9M)B|RzgFVfl}X5|@rC^9|ItWAn-TQG{sezv-hl7;&Zs&xGFnH6 zJc6ElsC!Sr_uuA!(hK&wm)~)&Hf)kr*q4;>cknB(*MeDJ0cY-s+V*t)^&!|xR{yf{ zY0J9NduTs%>`4DY{`GpYyf=kc^&Uju(EqzfiYI<t(4wR^FNuXNoQ%UHS$}HAE_vi| zZWOEkXO5roju;Ak3Tu`B%cmp#G5xw8YjpIle{*m`|IOKfPV$L*q0gp3)&k7r3Ke<^ z*ps1dPSpr37Xv<Z<}l_&US}9&@zS%4FjSZ=EI$uvzcvG1;*(*B^Bm%AD)!kG%D!Ae z7*aqhqTf;3C>N0J0{)z+pTO_SLH+lX-i)WC{!r$;XmY?0jDfZzJyb`sS<g#{&3@%S zf`2J)j3LUwIQ@oy^}j!rQG5Il<l?JfhA$k{x&7(>=fQFix+5UccKqPvUikb1!Wm3^ z$^p<iRmpmQhda0S(Ej6+|5*J$#ioOQ4^J=yABukB^c<0jf29E~&Q<dHdUu`pGa?*c zvf2#%Gp!wywYmeHah9W*PWW+`_+I|>-yA^7ZW!2r?8Ui~J@rla5_)RB`TqO#g%(I> zRs2#zV3L%Tp@k3CzZrKf?-sxp_`PJ4ewoWwz@Hryuuj59{v;ZI4iftRbVcQ(^Y{H{ z&flMln6r(=w(^!j1v2z{Y;^w%5phTx^=ua(*>f#c5%S+1UloMWtK^R^We219%2&eh in?6#Zg>$uyThBJg3;B;pL=0&4CvG*y<=4vvUH=c;+V0u_ literal 0 HcmV?d00001 From e2b38c96f887b75f0bf7d0a4854683e9c775b9cd Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 30 Mar 2018 00:10:55 +0200 Subject: [PATCH 0639/2161] Adjusted style. --- testcode/lib/apple2/hgrshow.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testcode/lib/apple2/hgrshow.c b/testcode/lib/apple2/hgrshow.c index 5d839b5fa..518395715 100644 --- a/testcode/lib/apple2/hgrshow.c +++ b/testcode/lib/apple2/hgrshow.c @@ -24,9 +24,9 @@ void main (void) if (!ext || strcasecmp (ext, ".hgr")) continue; - hgr = open(ent->d_name, O_RDONLY); - read(hgr, (void*)0x2000, 0x2000); - close(hgr); + hgr = open (ent->d_name, O_RDONLY); + read (hgr, (void*)0x2000, 0x2000); + close (hgr); if (cgetc () == '\r') break; From a7ae8e0a188d1e45033afa50040e2ebb1b961090 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 30 Mar 2018 00:11:40 +0200 Subject: [PATCH 0640/2161] Adjusted style. --- testcode/lib/apple2/dhgrshow.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/testcode/lib/apple2/dhgrshow.c b/testcode/lib/apple2/dhgrshow.c index 147ee01d6..f0b37e461 100644 --- a/testcode/lib/apple2/dhgrshow.c +++ b/testcode/lib/apple2/dhgrshow.c @@ -28,12 +28,12 @@ void main (void) if (!ext || strcasecmp (ext, ".dhgr")) continue; - hgr = open(ent->d_name, O_RDONLY); + hgr = open (ent->d_name, O_RDONLY); POKE (0xC055, 0); - read(hgr, (void*)0x2000, 0x2000); + read (hgr, (void*)0x2000, 0x2000); POKE (0xC054, 0); - read(hgr, (void*)0x2000, 0x2000); - close(hgr); + read (hgr, (void*)0x2000, 0x2000); + close (hgr); if (cgetc () == '\r') break; From 9db6f059ace9ea2dd6538a48e150fe4ca4e76a5a Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Sat, 31 Mar 2018 18:59:15 -0700 Subject: [PATCH 0641/2161] Fixed cpu detection. --- libsrc/common/getcpu.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/common/getcpu.s b/libsrc/common/getcpu.s index 7fe002f65..2acff0635 100644 --- a/libsrc/common/getcpu.s +++ b/libsrc/common/getcpu.s @@ -53,7 +53,7 @@ _getcpu: adc #1 ; $01+$09 = $10 on 6502, $01+$09 = $0A on 2a03/2a07 cld cmp #10 - bne @L5 + beq @L5 lda #0 ; CPU_6502 constant beq @L9 @L5: From 098a30725f67e12ff030252ad4b983b39e2a55e3 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 1 Apr 2018 15:47:48 -0400 Subject: [PATCH 0642/2161] Moved declarations that are common to the C16 and the Plus4 libraries over to their common header. --- include/c16.h | 3 +-- include/cbm264.h | 13 +++++++++---- include/plus4.h | 11 +---------- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/include/c16.h b/include/c16.h index c039218f9..beb2caa56 100644 --- a/include/c16.h +++ b/include/c16.h @@ -45,8 +45,7 @@ -/* Include the base header file for the 264 series. include file. - */ +/* Include the base header file for the 264 series. */ #include <cbm264.h> diff --git a/include/cbm264.h b/include/cbm264.h index 46fa64050..5e8a242a7 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -136,11 +136,16 @@ /* Code */ /*****************************************************************************/ +void fast (void); +/* Switch the CPU into double-clock mode. */ + +void slow (void); +/* Switch the CPU into single-clock mode. */ + +unsigned char isfast (void); +/* Returns 1 if the CPU is in double-clock mode. */ + /* End of cbm264.h */ #endif - - - - diff --git a/include/plus4.h b/include/plus4.h index 6edb947e5..c8aaf2eaf 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -45,8 +45,7 @@ -/* Include the base header file for the 264 series. include file. - */ +/* Include the base header file for the 264 series. */ #include <cbm264.h> /* Define hardware */ @@ -59,14 +58,6 @@ extern void plus4_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ extern void plus4_stdser_ser[]; -void fast (void); -/* Switch the CPU into double clock mode. */ - -void slow (void); -/* Switch the CPU into single clock mode. */ - -unsigned char isfast (void); -/* Returns 1 if the CPU is in double clock mode. */ /* End of plus4.h */ From 61e5b9d218c2893f38fe65878b95f933f3b5ed89 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Sun, 1 Apr 2018 13:14:44 -0700 Subject: [PATCH 0643/2161] Changed #10 to #-basha for clarity. --- libsrc/common/getcpu.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/common/getcpu.s b/libsrc/common/getcpu.s index 2acff0635..169c56bbd 100644 --- a/libsrc/common/getcpu.s +++ b/libsrc/common/getcpu.s @@ -52,7 +52,7 @@ _getcpu: clc adc #1 ; $01+$09 = $10 on 6502, $01+$09 = $0A on 2a03/2a07 cld - cmp #10 + cmp #$0a beq @L5 lda #0 ; CPU_6502 constant beq @L9 From 89c3ed6d7f82de68fb909978529261ac2d88c09a Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Mon, 9 Apr 2018 19:36:53 -0700 Subject: [PATCH 0644/2161] Added C64/C128 SuperCPU accelerator functions and started on a generic framework for accelerators. --- asminc/accelerator.inc | 34 ++++++++++++ doc/c128.sgml | 12 ++++ doc/c64.sgml | 12 ++++ doc/funcref.sgml | 73 ++++++++++++++++++++++++ include/accelerator.h | 102 ++++++++++++++++++++++++++++++++++ libsrc/c128/acc_detect_scpu.s | 34 ++++++++++++ libsrc/c128/acc_scpu_speed.s | 59 ++++++++++++++++++++ libsrc/c64/acc_detect_scpu.s | 34 ++++++++++++ libsrc/c64/acc_scpu_speed.s | 59 ++++++++++++++++++++ 9 files changed, 419 insertions(+) create mode 100644 asminc/accelerator.inc create mode 100644 include/accelerator.h create mode 100755 libsrc/c128/acc_detect_scpu.s create mode 100755 libsrc/c128/acc_scpu_speed.s create mode 100644 libsrc/c64/acc_detect_scpu.s create mode 100644 libsrc/c64/acc_scpu_speed.s diff --git a/asminc/accelerator.inc b/asminc/accelerator.inc new file mode 100644 index 000000000..1bc8fb11e --- /dev/null +++ b/asminc/accelerator.inc @@ -0,0 +1,34 @@ +; +; Accelerator definitions. +; + +; --------------------------------------------------------------------------- +; Speed definitions for all accelerator, to be used as input for the 'set' +; functions. + + +SPEED_SLOW := $00 +SPEED_FAST := $FF + +SPEED_1X := SPEED_SLOW +SPEED_2X := 2 - 1 +SPEED_3X := 3 - 1 +SPEED_4X := 4 - 1 +SPEED_5X := 5 - 1 +SPEED_6X := 6 - 1 +SPEED_7X := 7 - 1 +SPEED_8X := 8 - 1 +SPEED_10X := 10 - 1 +SPEED_12X := 12 - 1 +SPEED_16X := 16 - 1 +SPEED_20X := 20 - 1 + + +; --------------------------------------------------------------------------- +; C64/C128 Super CPU cartridge + +SuperCPU_Slow := $D07A +SuperCPU_Fast := $D07B +SuperCPU_Speed_Mode := $D0B8 +SuperCPU_Detect := $D0BC + diff --git a/doc/c128.sgml b/doc/c128.sgml index 2bfb37a3d..9af66d62b 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -88,6 +88,18 @@ url="funcref.html" name="function reference"> for declaration and usage. </itemize> +<sect1>C128-specific accelerator functions<p> + +The functions listed below are accelerator functions for the C128. See the <url +url="funcref.html" name="function reference"> for declaration and usage. + +<itemize> +<item>detect_scpu +<item>scpu_get_speed +<item>scpu_set_speed +</itemize> + + <sect1>CBM-specific functions<p> Some functions are available for all (or at least most) of the Commodore diff --git a/doc/c64.sgml b/doc/c64.sgml index 7cca1aa09..05b87a22b 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -169,6 +169,18 @@ url="funcref.html" name="function reference"> for declaration and usage. </itemize> +<sect1>C64-specific accelerator functions<p> + +The functions listed below are accelerator functions for the C64. See the <url +url="funcref.html" name="function reference"> for declaration and usage. + +<itemize> +<item>detect_scpu +<item>scpu_get_speed +<item>scpu_set_speed +</itemize> + + <sect1>CBM-specific functions<p> Some functions are available for all (or at least most) of the Commodore diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 5f90cfd3e..e47a0c0a9 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -65,6 +65,15 @@ function. </itemize> +<sect1><tt/accelerator.h/<label id="accelerator.h"><p> + +<itemize> +<item><ref id="detect_scpu" name="detect_scpu"> +<item><ref id="get_scpu_speed" name="get_scpu_speed"> +<item><ref id="set_scpu_speed" name="set_scpu_speed"> +</itemize> + + <sect1><tt/apple2.h/<label id="apple2.h"><p> <itemize> @@ -2911,6 +2920,26 @@ used in presence of a prototype. </quote> +<sect1>detect_scpu<label id="detect_scpu"><p> + +<quote> +<descrip> +<tag/Function/Check for the presence of the C64/C128 SuperCPU cartridge. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char detect_scpu (void);/ +<tag/Description/The function returns a 1 if a SuperCPU cartridge has been detected. +<tag/Notes/<itemize> +<item>The function is specific to the C128 and C64. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="get_scpu_speed" name="get_scpu_speed">, +<ref id="set_scpu_speed" name="set_scpu_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>div<label id="div"><p> <quote> @@ -3450,6 +3479,28 @@ header files define constants that can be used to check the return code. </quote> +<sect1>get_scpu_speed<label id="get_scpu_speed"><p> + +<quote> +<descrip> +<tag/Function/Get the current speed of the C64/C128 SuperCPU cartridge. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char get_scpu_speed (void);/ +<tag/Description/The function returns the current speed of the SuperCPU cartridge. +<tag/Notes/<itemize> +<item>The function is specific to the C128 and C64. +<item>The function does not check for the presence of the cartridge. +<item>See the accelerator.h header for the speed definitions. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="detect_scpu" name="detect_scpu">, +<ref id="set_scpu_speed" name="set_scpu_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>getcpu<label id="getcpu"><p> <quote> @@ -6001,6 +6052,28 @@ clean-up when exitting the program. </quote> +<sect1>set_scpu_speed<label id="set_scpu_speed"><p> + +<quote> +<descrip> +<tag/Function/Set the current speed of the C64/C128 SuperCPU cartridge. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char set_scpu_speed (unsigned char speed);/ +<tag/Description/The function returns the speed after trying to set the speed of the SuperCPU cartridge. +<tag/Notes/<itemize> +<item>The function is specific to the C128 and C64. +<item>The function does not check for the presence of the cartridge. +<item>See the accelerator.h header for the speed definitions. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="detect_scpu" name="detect_scpu">, +<ref id="get_scpu_speed" name="get_scpu_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>setjmp<label id="setjmp"><p> <quote> diff --git a/include/accelerator.h b/include/accelerator.h new file mode 100644 index 000000000..7d1244233 --- /dev/null +++ b/include/accelerator.h @@ -0,0 +1,102 @@ +/*****************************************************************************/ +/* */ +/* accelerator.h */ +/* */ +/* Accelerator specific definitions */ +/* */ +/* */ +/* */ +/* (C) 2018 Marco van den Heuvel */ +/* EMail: blackystardust68@yahoo.com */ +/* */ +/* */ +/* 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 _ACCELERATOR_H +#define _ACCELERATOR_H + +/*****************/ +/* Speed defines */ +/*****************/ + +#define SPEED_SLOW 0x00 +#define SPEED_FAST 0xFF + +#define SPEED_1X SPEED_SLOW +#define SPEED_2X 2 - 1 /* C64 Chameleon, C64DTV, C128, PET 65816, Apple2 Fast Chip, Apple2 TransWarp, Apple2 Zip Chip */ +#define SPEED_3X 3 - 1 /* C64 Chameleon, C65, PET 65816, Apple2 Booster, Apple 2 Fast Chip, Apple2 Titan, Apple2 TransWarp, Apple2 Zip Chip */ +#define SPEED_4X 4 - 1 /* C64 Chameleon, C64 TurboMaster, C64 TurboProcess, PET 65816, Apple2 Fast Chip, Apple2 Zip Chip */ +#define SPEED_5X 5 - 1 /* C64 Chameleon, PET 65816, Apple2 Fast Chip */ +#define SPEED_6X 6 - 1 /* C64 Chameleon, PET 65816, Apple2 Fast Chip */ +#define SPEED_7X 7 - 1 /* PET 65816, Apple2 Fast Chip */ +#define SPEED_8X 8 - 1 /* C64 Flash8, PET 65816, Apple 2 Fast Chip */ +#define SPEED_10X 10 - 1 /* PET 65816, Apple2 Fast Chip */ +#define SPEED_12X 12 - 1 /* Apple2 Fast Chip */ +#define SPEED_16X 16 - 1 /* Apple2 Fast Chip */ +#define SPEED_20X 20 - 1 /* C64/C128 SuperCPU */ + +/***********************************/ +/* Accelerator function prototypes */ +/***********************************/ + +/* C64/C128 SuperCPU cartridge */ + +extern unsigned char __fastcall__ set_scpu_speed (unsigned char speed); + +/* Set the speed of the SuperCPU cartridge, using SPEED_SLOW will switch to + * 1 Mhz mode, SPEED_20X or SPEED_FAST will switch to 20 Mhz mode. + * + * Note that any value lower than SPEED_20X will switch to 1 Mhz mode, and + * any value higher or equal to SPEED_20X will switch to 20 Mhz mode. + * + * This function will return the actual speed the CPU is at after trying + * to set the requested speed, if this is not the speed that was requested + * then possibly the hardware speed switch prevented any software speed + * switching. + * + * This function does not check for the presence of the SuperCPU cartridge, + * make sure you use 'detect_scpu();' before using. + */ + +extern unsigned char get_scpu_speed (void); + +/* Get the speed of the SuperCPU cartridge. + * + * Possible return values: + * SPEED_1X : 1 Mhz mode + * SPEED_20X : 20 Mhz mode + * + * This function does not check for the presence of the SuperCPU cartridge, + * make sure you use 'detect_scpu();' before using. + */ + +extern unsigned char detect_scpu (void); + +/* Check for the presence of the SuperCPU cartridge. + * + * Possible return values: + * 0x00 : SuperCPU cartridge not present + * 0x01 : SuperCPU cartridge present + */ + +/* End of accelerator.h */ +#endif diff --git a/libsrc/c128/acc_detect_scpu.s b/libsrc/c128/acc_detect_scpu.s new file mode 100755 index 000000000..e42d90548 --- /dev/null +++ b/libsrc/c128/acc_detect_scpu.s @@ -0,0 +1,34 @@ +; +; Marco van den Heuvel, 2018-04-08 +; + +; unsigned char detect_scpu (void); +; +;/* Check for the presence of the SuperCPU cartridge. +; * +; * Possible return values: +; * 0x00 : SuperCPU cartridge not present +; * 0x01 : SuperCPU cartridge present +; */ + + .export _detect_scpu + + .include "accelerator.inc" +_detect_scpu: + ldx #$00 + txa + +; Make sure the current CPU is a 65816 + clc + .byte $E2,$01 ; NOP #$01 on 6510 and 65(S)C02, LDA $(01,S),Y on 65CE02 and 4510, SEP #$01 on 65816 + bcc not_found ; carry will be set on 65816 + +; 65816 has been detected, make sure it's the SuperCPU cartridge + + lda SuperCPU_Detect + asl + bcs not_found +found: + lda #$01 +not_found: + rts diff --git a/libsrc/c128/acc_scpu_speed.s b/libsrc/c128/acc_scpu_speed.s new file mode 100755 index 000000000..4bd142bbb --- /dev/null +++ b/libsrc/c128/acc_scpu_speed.s @@ -0,0 +1,59 @@ +; +; Marco van den Heuvel, 2018-04-09 +; + +; extern unsigned char __fastcall__ set_scpu_speed (unsigned char speed); +; +;/* Set the speed of the SuperCPU cartridge, using SPEED_SLOW will switch to +; * 1 Mhz mode, SPEED_20X or SPEED_FAST will switch to 20 Mhz mode. +; * +; * Note that any value lower than SPEED_20X will switch to 1 Mhz mode, and +; * any value higher or equal to SPEED_20X will switch to 20 Mhz mode. +; * +; * This function will return the actual speed the CPU is at after trying +; * to set the requested speed, if this is not the speed that was requested +; * then possibly the hardware speed switch prevented any software speed +; * switching. +; * +; * This function does not check for the presence of the SuperCPU cartridge, +; * make sure you use 'detect_scpu();' before using. +; */ + +; extern unsigned char get_scpu_speed (void); +; +;/* Get the speed of the SuperCPU cartridge. +; * +; * Possible return values: +; * SPEED_1X : 1 Mhz mode +; * SPEED_20X : 20 Mhz mode +; * +; * This function does not check for the presence of the SuperCPU cartridge, +; * make sure you use 'detect_scpu();' before using. +; */ + + .export _set_scpu_speed + .export _get_scpu_speed + + .include "accelerator.inc" + +_set_scpu_speed: + cmp #SPEED_20X + bcs high_speed +low_speed: + sta SuperCPU_Slow + jmp _get_scpu_speed + +high_speed: + sta SuperCPU_Fast + +_get_scpu_speed: + ldx #$00 + lda SuperCPU_Speed_Mode + asl + asl + bcc is_fast_speed + lda #SPEED_1X + rts +is_fast_speed: + lda #SPEED_20X + rts diff --git a/libsrc/c64/acc_detect_scpu.s b/libsrc/c64/acc_detect_scpu.s new file mode 100644 index 000000000..e42d90548 --- /dev/null +++ b/libsrc/c64/acc_detect_scpu.s @@ -0,0 +1,34 @@ +; +; Marco van den Heuvel, 2018-04-08 +; + +; unsigned char detect_scpu (void); +; +;/* Check for the presence of the SuperCPU cartridge. +; * +; * Possible return values: +; * 0x00 : SuperCPU cartridge not present +; * 0x01 : SuperCPU cartridge present +; */ + + .export _detect_scpu + + .include "accelerator.inc" +_detect_scpu: + ldx #$00 + txa + +; Make sure the current CPU is a 65816 + clc + .byte $E2,$01 ; NOP #$01 on 6510 and 65(S)C02, LDA $(01,S),Y on 65CE02 and 4510, SEP #$01 on 65816 + bcc not_found ; carry will be set on 65816 + +; 65816 has been detected, make sure it's the SuperCPU cartridge + + lda SuperCPU_Detect + asl + bcs not_found +found: + lda #$01 +not_found: + rts diff --git a/libsrc/c64/acc_scpu_speed.s b/libsrc/c64/acc_scpu_speed.s new file mode 100644 index 000000000..4bd142bbb --- /dev/null +++ b/libsrc/c64/acc_scpu_speed.s @@ -0,0 +1,59 @@ +; +; Marco van den Heuvel, 2018-04-09 +; + +; extern unsigned char __fastcall__ set_scpu_speed (unsigned char speed); +; +;/* Set the speed of the SuperCPU cartridge, using SPEED_SLOW will switch to +; * 1 Mhz mode, SPEED_20X or SPEED_FAST will switch to 20 Mhz mode. +; * +; * Note that any value lower than SPEED_20X will switch to 1 Mhz mode, and +; * any value higher or equal to SPEED_20X will switch to 20 Mhz mode. +; * +; * This function will return the actual speed the CPU is at after trying +; * to set the requested speed, if this is not the speed that was requested +; * then possibly the hardware speed switch prevented any software speed +; * switching. +; * +; * This function does not check for the presence of the SuperCPU cartridge, +; * make sure you use 'detect_scpu();' before using. +; */ + +; extern unsigned char get_scpu_speed (void); +; +;/* Get the speed of the SuperCPU cartridge. +; * +; * Possible return values: +; * SPEED_1X : 1 Mhz mode +; * SPEED_20X : 20 Mhz mode +; * +; * This function does not check for the presence of the SuperCPU cartridge, +; * make sure you use 'detect_scpu();' before using. +; */ + + .export _set_scpu_speed + .export _get_scpu_speed + + .include "accelerator.inc" + +_set_scpu_speed: + cmp #SPEED_20X + bcs high_speed +low_speed: + sta SuperCPU_Slow + jmp _get_scpu_speed + +high_speed: + sta SuperCPU_Fast + +_get_scpu_speed: + ldx #$00 + lda SuperCPU_Speed_Mode + asl + asl + bcc is_fast_speed + lda #SPEED_1X + rts +is_fast_speed: + lda #SPEED_20X + rts From a50d214ffb2dd82055ae7117d33fa441a902722c Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 10 Apr 2018 18:37:10 +0000 Subject: [PATCH 0645/2161] Simpler get_tv You don't have to count the beam, just check the KERNAL. --- libsrc/vic20/get_tv.s | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/libsrc/vic20/get_tv.s b/libsrc/vic20/get_tv.s index 7182c0df7..9194a2c55 100644 --- a/libsrc/vic20/get_tv.s +++ b/libsrc/vic20/get_tv.s @@ -1,12 +1,11 @@ ; -; Stefan Haubenthal, 2004-10-07 -; Based on code from Pu-239 +; Stefan Haubenthal, 2018-04-10 +; Based on code by Mike ; ; unsigned char get_tv (void); ; /* Return the video mode the machine is using */ ; - .include "vic20.inc" .include "get_tv.inc" ;-------------------------------------------------------------------------- @@ -14,18 +13,13 @@ .proc _get_tv -NTSC_LINES = 261 ; detect the system lda #TV::NTSC tax -@L0: ldy VIC_HLINE - cpy #1 - bne @L0 ; wait for line 1 -@L1: ldy VIC_HLINE - beq @L2 ; line 0 reached -> NTSC - cpy #NTSC_LINES/2+2 - bne @L1 + ldy $EDE4 ; VIC init table + cpy #5 + beq @L0 lda #TV::PAL -@L2: rts ; system detected: 0 for NTSC, 1 for PAL +@L0: rts ; system detected: 0 for NTSC, 1 for PAL .endproc From e2cf4987cf297d3a8a6d5cfb1b5bf7c6f7fca644 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Tue, 10 Apr 2018 15:24:15 -0700 Subject: [PATCH 0646/2161] Added some accelerator test code. --- testcode/lib/accelerator/Makefile | 9 +++ testcode/lib/accelerator/c64-c128-scpu-test.c | 8 +++ testcode/lib/accelerator/turbo-test.c | 57 +++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 testcode/lib/accelerator/Makefile create mode 100755 testcode/lib/accelerator/c64-c128-scpu-test.c create mode 100644 testcode/lib/accelerator/turbo-test.c diff --git a/testcode/lib/accelerator/Makefile b/testcode/lib/accelerator/Makefile new file mode 100644 index 000000000..ece54ec36 --- /dev/null +++ b/testcode/lib/accelerator/Makefile @@ -0,0 +1,9 @@ +CL ?= cl65 + +all: c64-scpu-test.prg c128-scpu-test.prg + +c64-scpu-test.prg: c64-c128-scpu-test.c + $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg + +c128-scpu-test.prg: c64-c128-scpu-test.c + $(CL) -t c128 c64-c128-scpu-test.c -o c128-scpu-test.prg diff --git a/testcode/lib/accelerator/c64-c128-scpu-test.c b/testcode/lib/accelerator/c64-c128-scpu-test.c new file mode 100755 index 000000000..975244df5 --- /dev/null +++ b/testcode/lib/accelerator/c64-c128-scpu-test.c @@ -0,0 +1,8 @@ +/* C64/C128 SuperCPU accelerator test code. */ + +#define ACC_DETECT detect_scpu +#define ACC_GET_SPEED get_scpu_speed +#define ACC_SET_SPEED set_scpu_speed +#define ACC_NAME "SuperCPU" + +#include "turbo-test.c" diff --git a/testcode/lib/accelerator/turbo-test.c b/testcode/lib/accelerator/turbo-test.c new file mode 100644 index 000000000..8c854c00c --- /dev/null +++ b/testcode/lib/accelerator/turbo-test.c @@ -0,0 +1,57 @@ +/* Accelerator test code. */ + +#ifndef ACC_DETECT +#error This file cannot be used directly (yet) +#endif + +#include <time.h> +#include <accelerator.h> +#include <stdio.h> +#include <conio.h> +#include <stdlib.h> + +static void print_time_taken(void) +{ + clock_t curtime = clock(); + clock_t newtime; + unsigned long i; + char buffer[10]; + + printf("Doing a speed test, please wait\n"); + for (i = 0; i < 0x1000; i++) { } + newtime = clock() - curtime; + ultoa(newtime, buffer, 10); + printf("Time taken : %s\n", buffer); +} + +static void print_current_speed(void) +{ + unsigned char status; + + status = ACC_GET_SPEED(); + printf("Current "ACC_NAME" speed : %d\n", status + 1); +} + +void main(void) +{ + unsigned char status; + unsigned char speed = 0; + + status = ACC_DETECT(); + clrscr(); + if (status == 0) { + printf("No "ACC_NAME" detected\n"); + } else { + status = ACC_GET_SPEED(); + print_current_speed(); + + /* cycle through all the speeds */ + for (speed = SPEED_1X; speed <= SPEED_20X; ++speed) { + printf("Setting "ACC_NAME" speed to %d\n", speed + 1); + ACC_SET_SPEED(speed); + print_current_speed(); + print_time_taken(); + } + ACC_SET_SPEED(status); + } +} From 165b98bba551c33e99523cb1ab3068a17ef87b9e Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Wed, 11 Apr 2018 22:38:23 +0300 Subject: [PATCH 0647/2161] Added missing VIA registers. Register names from the COMPUTE!'s book 'Mapping the VIC' --- asminc/vic20.inc | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/asminc/vic20.inc b/asminc/vic20.inc index d882eb1ad..a428ee76f 100644 --- a/asminc/vic20.inc +++ b/asminc/vic20.inc @@ -66,16 +66,43 @@ VIC_COLOR := $900F ; Border and background color ; --------------------------------------------------------------------------- ; I/O: 6522 VIA1 -VIA1 := $9110 -VIA1_JOY := $9111 -VIA1_DDRB := $9112 -VIA1_DDRA := $9113 +VIA1 := $9110 ; *** Deprecated *** +VIA1_JOY := $9111 ; *** Deprecated *** +VIA1_PB := $9110 ; Port register B +VIA1_PA1 := $9111 ; Port register A +VIA1_DDRB := $9112 ; Data direction register B +VIA1_DDRA := $9113 ; Data direction register A +VIA1_T1CL := $9114 ; Timer 1, low byte +VIA1_T1CH := $9115 ; Timer 1, high byte +VIA1_T1LL := $9116 ; Timer 1 latch, low byte +VIA1_T1LH := $9117 ; Timer 1 latch, high byte +VIA1_T2CL := $9118 ; Timer 2, low byte +VIA1_T2CH := $9119 ; Timer 2, high byte +VIA1_SR := $911A ; Shift register +VIA1_CR := $911B ; Auxiliary control register +VIA1_PCR := $911C ; Peripheral control register +VIA1_IFR := $911D ; Interrupt flag register +VIA1_IER := $911E ; Interrupt enable register +VIA1_PA2 := $911F ; Port register A w/o handshake ; --------------------------------------------------------------------------- ; I/O: 6522 VIA2 -VIA2 := $9120 -VIA2_JOY := $9120 -VIA2_DDRB := $9122 -VIA2_DDRA := $9123 - +VIA2 := $9120 ; *** Deprecated *** +VIA2_JOY := $9120 ; *** Deprecated *** +VIA2_PB := $9120 ; Port register B +VIA2_PA1 := $9121 ; Port register A +VIA2_DDRB := $9122 ; Data direction register B +VIA2_DDRA := $9123 ; Data direction register A +VIA2_T1CL := $9124 ; Timer 1, low byte +VIA2_T1CH := $9125 ; Timer 1, high byte +VIA2_T1LL := $9126 ; Timer 1 latch, low byte +VIA2_T1LH := $9127 ; Timer 1 latch, high byte +VIA2_T2CL := $9128 ; Timer 2, low byte +VIA2_T2CH := $9129 ; Timer 2, high byte +VIA2_SR := $912A ; Shift register +VIA2_CR := $912B ; Auxiliary control register +VIA2_PCR := $912C ; Peripheral control register +VIA2_IFR := $912D ; Interrupt flag register +VIA2_IER := $912E ; Interrupt enable register +VIA2_PA2 := $912F ; Port register A w/o handshake From 79433ddb60a9d55d3bd0195d24f97238b0b90540 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Wed, 11 Apr 2018 22:40:46 +0300 Subject: [PATCH 0648/2161] Updated to use the new VIA register names. --- libsrc/vic20/joy/vic20-ptvjoy.s | 15 +++++++-------- libsrc/vic20/joy/vic20-stdjoy.s | 4 ++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/libsrc/vic20/joy/vic20-ptvjoy.s b/libsrc/vic20/joy/vic20-ptvjoy.s index bf0ff128e..496653e9d 100644 --- a/libsrc/vic20/joy/vic20-ptvjoy.s +++ b/libsrc/vic20/joy/vic20-ptvjoy.s @@ -40,7 +40,6 @@ ; ------------------------------------------------------------------------ ; Constants -VIA1_PRB := VIA1 ; User port register JOY_COUNT = 3 ; Number of joysticks we support @@ -91,13 +90,13 @@ joy1: lda #$7F ; mask for VIA2 JOYBIT: sw3 ldy VIA2_DDRB ; remember the date of DDRB sta VIA2_DDRB ; set JOYBITS on this VIA for input - lda VIA2_JOY ; read JOYBIT: sw3 + lda VIA2_PB ; read JOYBIT: sw3 sty VIA2_DDRB ; restore the state of DDRB asl ; Shift sw3 into carry ldy VIA1_DDRA ; remember the state of DDRA stx VIA1_DDRA ; set JOYBITS on this VIA for input - lda VIA1_JOY ; read JOYBITS: sw0,sw1,sw2,sw4 + lda VIA1_PA1 ; read JOYBITS: sw0,sw1,sw2,sw4 sty VIA1_DDRA ; restore the state of DDRA cli ; necessary? @@ -127,9 +126,9 @@ joy2: lda #%10000000 ; via port B Data-Direction bne joy3 lda #$80 ; via port B read/write - sta VIA1_PRB ; (output one at PB7) + sta VIA1_PB ; (output one at PB7) - lda VIA1_PRB ; via port B read/write + lda VIA1_PB ; via port B read/write and #$1F ; get bit 4-0 (PB4-PB0) eor #$1F rts @@ -137,13 +136,13 @@ joy2: lda #%10000000 ; via port B Data-Direction ; Read joystick 3 joy3: lda #$00 ; via port B read/write - sta VIA1_PRB ; (output zero at PB7) + sta VIA1_PB ; (output zero at PB7) - lda VIA1_PRB ; via port B read/write + lda VIA1_PB ; via port B read/write and #$0F ; get bit 3-0 (PB3-PB0) sta tmp1 ; joy 4 directions - lda VIA1_PRB ; via port B read/write + lda VIA1_PB ; via port B read/write and #%00100000 ; get bit 5 (PB5) lsr ora tmp1 diff --git a/libsrc/vic20/joy/vic20-stdjoy.s b/libsrc/vic20/joy/vic20-stdjoy.s index e5539c653..ee8dc93d7 100644 --- a/libsrc/vic20/joy/vic20-stdjoy.s +++ b/libsrc/vic20/joy/vic20-stdjoy.s @@ -90,13 +90,13 @@ READ: lda #$7F ; mask for VIA2 JOYBIT: sw3 ldy VIA2_DDRB ; remember the date of DDRB sta VIA2_DDRB ; set JOYBITS on this VIA for input - lda VIA2_JOY ; read JOYBIT: sw3 + lda VIA2_PB ; read JOYBIT: sw3 sty VIA2_DDRB ; restore the state of DDRB asl ; Shift sw3 into carry ldy VIA1_DDRA ; remember the state of DDRA stx VIA1_DDRA ; set JOYBITS on this VIA for input - lda VIA1_JOY ; read JOYBITS: sw0,sw1,sw2,sw4 + lda VIA1_PA1 ; read JOYBITS: sw0,sw1,sw2,sw4 sty VIA1_DDRA ; restore the state of DDRA cli ; necessary? From 859422f357b16198e17505d729f8b3166326bdf9 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Thu, 12 Apr 2018 09:35:02 -0700 Subject: [PATCH 0649/2161] Fixed non-address constants. --- asminc/accelerator.inc | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/asminc/accelerator.inc b/asminc/accelerator.inc index 1bc8fb11e..f86ce8b2d 100644 --- a/asminc/accelerator.inc +++ b/asminc/accelerator.inc @@ -7,21 +7,21 @@ ; functions. -SPEED_SLOW := $00 -SPEED_FAST := $FF +SPEED_SLOW = $00 +SPEED_FAST = $FF -SPEED_1X := SPEED_SLOW -SPEED_2X := 2 - 1 -SPEED_3X := 3 - 1 -SPEED_4X := 4 - 1 -SPEED_5X := 5 - 1 -SPEED_6X := 6 - 1 -SPEED_7X := 7 - 1 -SPEED_8X := 8 - 1 -SPEED_10X := 10 - 1 -SPEED_12X := 12 - 1 -SPEED_16X := 16 - 1 -SPEED_20X := 20 - 1 +SPEED_1X = SPEED_SLOW +SPEED_2X = 2 - 1 +SPEED_3X = 3 - 1 +SPEED_4X = 4 - 1 +SPEED_5X = 5 - 1 +SPEED_6X = 6 - 1 +SPEED_7X = 7 - 1 +SPEED_8X = 8 - 1 +SPEED_10X = 10 - 1 +SPEED_12X = 12 - 1 +SPEED_16X = 16 - 1 +SPEED_20X = 20 - 1 ; --------------------------------------------------------------------------- From 59cb7da334955a391b754c12dcb1c3c1e6162c35 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Sat, 14 Apr 2018 08:39:30 +0300 Subject: [PATCH 0650/2161] VIA1 and VIA2 no longer marked deprecated --- asminc/vic20.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asminc/vic20.inc b/asminc/vic20.inc index a428ee76f..9c8ca8a35 100644 --- a/asminc/vic20.inc +++ b/asminc/vic20.inc @@ -66,7 +66,7 @@ VIC_COLOR := $900F ; Border and background color ; --------------------------------------------------------------------------- ; I/O: 6522 VIA1 -VIA1 := $9110 ; *** Deprecated *** +VIA1 := $9110 ; VIA1 base address VIA1_JOY := $9111 ; *** Deprecated *** VIA1_PB := $9110 ; Port register B VIA1_PA1 := $9111 ; Port register A @@ -88,7 +88,7 @@ VIA1_PA2 := $911F ; Port register A w/o handshake ; --------------------------------------------------------------------------- ; I/O: 6522 VIA2 -VIA2 := $9120 ; *** Deprecated *** +VIA2 := $9120 ; VIA2 base address VIA2_JOY := $9120 ; *** Deprecated *** VIA2_PB := $9120 ; Port register B VIA2_PA1 := $9121 ; Port register A From 7b1db91d36a3f703b2ad6de2c23e11b46ee800bd Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Sat, 14 Apr 2018 18:45:15 +0300 Subject: [PATCH 0651/2161] Changed register addresses relative to the base address --- asminc/vic20.inc | 68 ++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/asminc/vic20.inc b/asminc/vic20.inc index 9c8ca8a35..6ac7ef35c 100644 --- a/asminc/vic20.inc +++ b/asminc/vic20.inc @@ -67,42 +67,42 @@ VIC_COLOR := $900F ; Border and background color ; I/O: 6522 VIA1 VIA1 := $9110 ; VIA1 base address -VIA1_JOY := $9111 ; *** Deprecated *** -VIA1_PB := $9110 ; Port register B -VIA1_PA1 := $9111 ; Port register A -VIA1_DDRB := $9112 ; Data direction register B -VIA1_DDRA := $9113 ; Data direction register A -VIA1_T1CL := $9114 ; Timer 1, low byte -VIA1_T1CH := $9115 ; Timer 1, high byte -VIA1_T1LL := $9116 ; Timer 1 latch, low byte -VIA1_T1LH := $9117 ; Timer 1 latch, high byte -VIA1_T2CL := $9118 ; Timer 2, low byte -VIA1_T2CH := $9119 ; Timer 2, high byte -VIA1_SR := $911A ; Shift register -VIA1_CR := $911B ; Auxiliary control register -VIA1_PCR := $911C ; Peripheral control register -VIA1_IFR := $911D ; Interrupt flag register -VIA1_IER := $911E ; Interrupt enable register -VIA1_PA2 := $911F ; Port register A w/o handshake +VIA1_JOY := VIA1+$0 ; *** Deprecated *** +VIA1_PB := VIA1+$0 ; Port register B +VIA1_PA1 := VIA1+$1 ; Port register A +VIA1_DDRB := VIA1+$2 ; Data direction register B +VIA1_DDRA := VIA1+$3 ; Data direction register A +VIA1_T1CL := VIA1+$4 ; Timer 1, low byte +VIA1_T1CH := VIA1+$5 ; Timer 1, high byte +VIA1_T1LL := VIA1+$6 ; Timer 1 latch, low byte +VIA1_T1LH := VIA1+$7 ; Timer 1 latch, high byte +VIA1_T2CL := VIA1+$8 ; Timer 2, low byte +VIA1_T2CH := VIA1+$9 ; Timer 2, high byte +VIA1_SR := VIA1+$A ; Shift register +VIA1_CR := VIA1+$B ; Auxiliary control register +VIA1_PCR := VIA1+$C ; Peripheral control register +VIA1_IFR := VIA1+$D ; Interrupt flag register +VIA1_IER := VIA1+$E ; Interrupt enable register +VIA1_PA2 := VIA1+$F ; Port register A w/o handshake ; --------------------------------------------------------------------------- ; I/O: 6522 VIA2 VIA2 := $9120 ; VIA2 base address -VIA2_JOY := $9120 ; *** Deprecated *** -VIA2_PB := $9120 ; Port register B -VIA2_PA1 := $9121 ; Port register A -VIA2_DDRB := $9122 ; Data direction register B -VIA2_DDRA := $9123 ; Data direction register A -VIA2_T1CL := $9124 ; Timer 1, low byte -VIA2_T1CH := $9125 ; Timer 1, high byte -VIA2_T1LL := $9126 ; Timer 1 latch, low byte -VIA2_T1LH := $9127 ; Timer 1 latch, high byte -VIA2_T2CL := $9128 ; Timer 2, low byte -VIA2_T2CH := $9129 ; Timer 2, high byte -VIA2_SR := $912A ; Shift register -VIA2_CR := $912B ; Auxiliary control register -VIA2_PCR := $912C ; Peripheral control register -VIA2_IFR := $912D ; Interrupt flag register -VIA2_IER := $912E ; Interrupt enable register -VIA2_PA2 := $912F ; Port register A w/o handshake +VIA2_JOY := VIA2+$0 ; *** Deprecated *** +VIA2_PB := VIA2+$0 ; Port register B +VIA2_PA1 := VIA2+$1 ; Port register A +VIA2_DDRB := VIA2+$2 ; Data direction register B +VIA2_DDRA := VIA2+$3 ; Data direction register A +VIA2_T1CL := VIA2+$4 ; Timer 1, low byte +VIA2_T1CH := VIA2+$5 ; Timer 1, high byte +VIA2_T1LL := VIA2+$6 ; Timer 1 latch, low byte +VIA2_T1LH := VIA2+$7 ; Timer 1 latch, high byte +VIA2_T2CL := VIA2+$8 ; Timer 2, low byte +VIA2_T2CH := VIA2+$9 ; Timer 2, high byte +VIA2_SR := VIA2+$A ; Shift register +VIA2_CR := VIA2+$B ; Auxiliary control register +VIA2_PCR := VIA2+$C ; Peripheral control register +VIA2_IFR := VIA2+$D ; Interrupt flag register +VIA2_IER := VIA2+$E ; Interrupt enable register +VIA2_PA2 := VIA2+$F ; Port register A w/o handshake From 6076316f38a6d72081f6b90998ced0b7b7abe209 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Sat, 14 Apr 2018 10:40:13 -0700 Subject: [PATCH 0652/2161] Added c64dtv accelerator code and documentation. --- asminc/accelerator.inc | 8 +++ doc/c64.sgml | 7 ++- doc/funcref.sgml | 67 ++++++++++++++++++++++++++ include/accelerator.h | 38 +++++++++++++++ libsrc/c64/acc_c64dtv_speed.s | 64 ++++++++++++++++++++++++ libsrc/c64/acc_detect_c64dtv.s | 43 +++++++++++++++++ testcode/lib/accelerator/Makefile | 6 ++- testcode/lib/accelerator/c64dtv-test.c | 8 +++ 8 files changed, 238 insertions(+), 3 deletions(-) create mode 100755 libsrc/c64/acc_c64dtv_speed.s create mode 100755 libsrc/c64/acc_detect_c64dtv.s create mode 100755 testcode/lib/accelerator/c64dtv-test.c diff --git a/asminc/accelerator.inc b/asminc/accelerator.inc index f86ce8b2d..1008b49c1 100644 --- a/asminc/accelerator.inc +++ b/asminc/accelerator.inc @@ -32,3 +32,11 @@ SuperCPU_Fast := $D07B SuperCPU_Speed_Mode := $D0B8 SuperCPU_Detect := $D0BC + +; --------------------------------------------------------------------------- +; C64DTV + +C64DTV_Extended_Regs := $D03F + +C64DTV_Slow = $00 +C64DTV_Fast = $03 diff --git a/doc/c64.sgml b/doc/c64.sgml index 05b87a22b..f1e678c72 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -175,9 +175,12 @@ The functions listed below are accelerator functions for the C64. See the <url url="funcref.html" name="function reference"> for declaration and usage. <itemize> +<item>detect_c64dtv <item>detect_scpu -<item>scpu_get_speed -<item>scpu_set_speed +<item>get_c64dtv_speed +<item>get_scpu_speed +<item>set_c64dtv_speed +<item>set_scpu_speed </itemize> diff --git a/doc/funcref.sgml b/doc/funcref.sgml index e47a0c0a9..4dfbf29e0 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -68,8 +68,11 @@ function. <sect1><tt/accelerator.h/<label id="accelerator.h"><p> <itemize> +<item><ref id="detect_c64dtv" name="detect_c64dtv"> <item><ref id="detect_scpu" name="detect_scpu"> +<item><ref id="get_c64dtv_speed" name="get_c64dtv_speed"> <item><ref id="get_scpu_speed" name="get_scpu_speed"> +<item><ref id="set_c64dtv_speed" name="set_c64dtv_speed"> <item><ref id="set_scpu_speed" name="set_scpu_speed"> </itemize> @@ -2920,6 +2923,26 @@ used in presence of a prototype. </quote> +<sect1>detect_c64dtv<label id="detect_c64dtv"><p> + +<quote> +<descrip> +<tag/Function/Check for the presence of the C64DTV. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char detect_c64dtv (void);/ +<tag/Description/The function returns a 1 if a C64DTV has been detected. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="get_scpu_speed" name="get_c64dtv_speed">, +<ref id="set_scpu_speed" name="set_c64dtv_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>detect_scpu<label id="detect_scpu"><p> <quote> @@ -3479,6 +3502,28 @@ header files define constants that can be used to check the return code. </quote> +<sect1>get_c64dtv_speed<label id="get_c64dtv_speed"><p> + +<quote> +<descrip> +<tag/Function/Get the current speed of the C64DTV. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char get_c64dtv_speed (void);/ +<tag/Description/The function returns the current speed of the C64DTV. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +<item>The function does not check for the presence of the cartridge. +<item>See the accelerator.h header for the speed definitions. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="detect_c64dtv" name="detect_c64dtv">, +<ref id="set_c64dtv_speed" name="set_c64dtv_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>get_scpu_speed<label id="get_scpu_speed"><p> <quote> @@ -6052,6 +6097,28 @@ clean-up when exitting the program. </quote> +<sect1>set_c64dtv_speed<label id="set_c64dtv_speed"><p> + +<quote> +<descrip> +<tag/Function/Set the current speed of the C64DTV. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char set_c64dtv_speed (unsigned char speed);/ +<tag/Description/The function returns the speed after trying to set the speed of the C64DTV. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +<item>The function does not check for the presence of the C64DTV. +<item>See the accelerator.h header for the speed definitions. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="detect_c64dtv" name="detect_c64dtv">, +<ref id="get_c64dtv_speed" name="get_c64dtv_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>set_scpu_speed<label id="set_scpu_speed"><p> <quote> diff --git a/include/accelerator.h b/include/accelerator.h index 7d1244233..336bbb036 100644 --- a/include/accelerator.h +++ b/include/accelerator.h @@ -98,5 +98,43 @@ extern unsigned char detect_scpu (void); * 0x01 : SuperCPU cartridge present */ + +/* C64DTV */ + +extern unsigned char __fastcall__ set_c64dtv_speed (unsigned char speed); + +/* Set the speed of the C64DTV, using SPEED_SLOW will switch to + * slow mode, SPEED_2X or SPEED_FAST will switch to fast mode. + * + * Note that any value higher or equal to SPEED_2X will switch to fast mode. + * + * This function will return the actual speed the CPU is at after trying + * to set the requested speed, to my knowledge the switch should not fail. + * + * This function does not check for the presence of the C64DTV, + * make sure you use 'detect_c64dtv();' before using. + */ + +extern unsigned char get_c64dtv_speed (void); + +/* Get the speed of the C64DTV. + * + * Possible return values: + * SPEED_1X : slow mode + * SPEED_2X : fast mode + * + * This function does not check for the presence of the C64DTV, + * make sure you use 'detect_c64dtv();' before using. + */ + +extern unsigned char detect_c64dtv (void); + +/* Check for the presence of the C64DTV. + * + * Possible return values: + * 0x00 : C64DTV not present + * 0x01 : C64DTV present + */ + /* End of accelerator.h */ #endif diff --git a/libsrc/c64/acc_c64dtv_speed.s b/libsrc/c64/acc_c64dtv_speed.s new file mode 100755 index 000000000..9cf49673e --- /dev/null +++ b/libsrc/c64/acc_c64dtv_speed.s @@ -0,0 +1,64 @@ +; +; Marco van den Heuvel, 2018-04-14 +; + +; extern unsigned char __fastcall__ set_c64dtv_speed (unsigned char speed); +; +;/* Set the speed of the C64DTV, using SPEED_SLOW will switch to +; * slow mode, SPEED_2X or SPEED_FAST will switch to fast mode. +; * +; * Note that any value higher or equal to SPEED_2X will switch to fast mode. +; * +; * This function will return the actual speed the CPU is at after trying +; * to set the requested speed, to my knowledge this should not happen. +; * +; * This function does not check for the presence of the C64DTV, +; * make sure you use 'detect_c64dtv();' before using. +; */ + +; extern unsigned char get_c64dtv_speed (void); +; +;/* Get the speed of the C64DTV. +; * +; * Possible return values: +; * SPEED_1X : slow mode +; * SPEED_2X : fast mode +; * +; * This function does not check for the presence of the C64DTV, +; * make sure you use 'detect_c64dtv();' before using. +; */ + + .export _set_c64dtv_speed + .export _get_c64dtv_speed + + .include "accelerator.inc" + +_set_c64dtv_speed: + cmp #SPEED_2X + bcs high_speed +low_speed: + ldx #C64DTV_Slow +set_speed: + .byte $32,$99 ; SAC #$99 set accumulator to reg 9 (cpu control) + txa ; (re)set skip and burst bits + .byte $32,$00 ; SAC #$99 set accumulator back to reg 0 + jmp _get_c64dtv_speed + +high_speed: + ldx #C64DTV_Fast + bne set_speed + + +_get_c64dtv_speed: + .byte $32,$99 ; SAC #$99 set accumulator to reg 9 (cpu control) + tax + .byte $32,$00 ; SAC #$99 set accumulator back to reg 0 + txa + and #C64DTV_Fast + bne in_fast_mode + lda #$00 + .byte $2C +in_fast_mode: + lda #$01 + ldx #$00 + rts diff --git a/libsrc/c64/acc_detect_c64dtv.s b/libsrc/c64/acc_detect_c64dtv.s new file mode 100755 index 000000000..ce30806db --- /dev/null +++ b/libsrc/c64/acc_detect_c64dtv.s @@ -0,0 +1,43 @@ +; +; Marco van den Heuvel, 2018-04-14 +; + +; unsigned char detect_c64dtv (void); +; +;/* Check for the presence of the C64DTV. +; * +; * Possible return values: +; * 0x00 : C64DTV not present +; * 0x01 : C64DTV present +; */ + + .export _detect_c64dtv + + .include "accelerator.inc" + +_detect_c64dtv: + ldy C64DTV_Extended_Regs + lda #$00 + tax + +; Make sure the CPU is a 6510 + .byte $1A ; NOP on 8502, INA on 65(S)C(E)02, 4510 and 65816 + bne not_found + lda #$01 + sta C64DTV_Extended_Regs + +; Check if $D000 is mirrored at $D040 + lda $D040 + cmp $D000 + bne found + inc $D040 + cmp $D000 + bne not_found +found: + lda #$01 + .byte $2C +not_found: + lda #$00 + sty C64DTV_Extended_Regs + rts + diff --git a/testcode/lib/accelerator/Makefile b/testcode/lib/accelerator/Makefile index ece54ec36..a9fe5f78d 100644 --- a/testcode/lib/accelerator/Makefile +++ b/testcode/lib/accelerator/Makefile @@ -1,9 +1,13 @@ CL ?= cl65 -all: c64-scpu-test.prg c128-scpu-test.prg +all: c64-scpu-test.prg c128-scpu-test.prg c64dtv-test.prg c64-scpu-test.prg: c64-c128-scpu-test.c $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg c128-scpu-test.prg: c64-c128-scpu-test.c $(CL) -t c128 c64-c128-scpu-test.c -o c128-scpu-test.prg + +c64dtv-test.prg: c64dtv-test.c + $(CL) -t c64 c64dtv-test.c -o c64dtv-test.prg + diff --git a/testcode/lib/accelerator/c64dtv-test.c b/testcode/lib/accelerator/c64dtv-test.c new file mode 100755 index 000000000..34f0410d9 --- /dev/null +++ b/testcode/lib/accelerator/c64dtv-test.c @@ -0,0 +1,8 @@ +/* C64DTV accelerator test code. */ + +#define ACC_DETECT detect_c64dtv +#define ACC_GET_SPEED get_c64dtv_speed +#define ACC_SET_SPEED set_c64dtv_speed +#define ACC_NAME "C64DTV" + +#include "turbo-test.c" From cb04bc54655c0b6e66e54cf924a9cee017872af9 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Sat, 14 Apr 2018 11:31:28 -0700 Subject: [PATCH 0653/2161] Fixed an issue with the changing the d040 value while detecting. --- libsrc/c64/acc_detect_c64dtv.s | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libsrc/c64/acc_detect_c64dtv.s b/libsrc/c64/acc_detect_c64dtv.s index ce30806db..1734095b1 100755 --- a/libsrc/c64/acc_detect_c64dtv.s +++ b/libsrc/c64/acc_detect_c64dtv.s @@ -18,7 +18,7 @@ _detect_c64dtv: ldy C64DTV_Extended_Regs lda #$00 - tax + ldx $D000 ; Make sure the CPU is a 6510 .byte $1A ; NOP on 8502, INA on 65(S)C(E)02, 4510 and 65816 @@ -27,17 +27,18 @@ _detect_c64dtv: sta C64DTV_Extended_Regs ; Check if $D000 is mirrored at $D040 - lda $D040 - cmp $D000 + cpx $D040 bne found - inc $D040 - cmp $D000 + inc $D000 + cpx $D040 bne not_found found: lda #$01 .byte $2C not_found: lda #$00 + stx $D000 + ldx #$00 sty C64DTV_Extended_Regs rts From e34ef0fc17378df795a1fa01c2cefae0abb34d09 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 14 Apr 2018 21:52:11 +0200 Subject: [PATCH 0654/2161] add cputc & remove --- asminc/telestrat.inc | 3 ++- libsrc/telestrat/cputc.s | 16 ++++++++++++++++ libsrc/telestrat/sysremove.s | 16 ++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 libsrc/telestrat/cputc.s create mode 100644 libsrc/telestrat/sysremove.s diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index cb28919c2..956d31be3 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -172,7 +172,8 @@ XMUSIC = $45 XZAP = $46 XSHOOT = $47 XMKDIR = $4B ; create a folder. Only available in telemon 3.x -XSOUT = $67 ; send A register to RS232, available in telemon 2.4 & 3.x +XRM = $4D ; remove a folder or a file. Only available in telemon 3.x +XSOUT = $67 ; send accumulator value (A) to RS232, available in telemon 2.4 & 3.x : if RS232 buffer is full, the Oric Telestrat freezes XHRSSE = $8C ; set hires position cursor XDRAWA = $8D ; draw a line XDRAWR = $8E ; draw a line diff --git a/libsrc/telestrat/cputc.s b/libsrc/telestrat/cputc.s new file mode 100644 index 000000000..d107446c3 --- /dev/null +++ b/libsrc/telestrat/cputc.s @@ -0,0 +1,16 @@ +; 2018-04-13, Jede (jede@oric.org) +; + +; void cputc (char c); +; + + .export _cputc + + + .include "telestrat.inc" + +.proc _cputc + BRK_TELEMON XWR0 ; macro send char to screen (channel 0 in telemon terms) + rts +.endproc + diff --git a/libsrc/telestrat/sysremove.s b/libsrc/telestrat/sysremove.s new file mode 100644 index 000000000..565dfc111 --- /dev/null +++ b/libsrc/telestrat/sysremove.s @@ -0,0 +1,16 @@ +; +; Jede, 10.11.2017 +; +; unsigned char __fastcall__ _sysremove (const char* name); +; + + .export __sysremove + + + .include "zeropage.inc" + .include "telestrat.inc" + +__sysremove: + ; Push name + BRK_TELEMON(XRM) + rts From 626fed88b7b3bd30390be7b6e8da31581b6e8a9c Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 14 Apr 2018 22:05:03 +0200 Subject: [PATCH 0655/2161] chline added --- libsrc/telestrat/chline.s | 22 ++++++++++++++++++++++ libsrc/telestrat/cputc.s | 1 - 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 libsrc/telestrat/chline.s diff --git a/libsrc/telestrat/chline.s b/libsrc/telestrat/chline.s new file mode 100644 index 000000000..16e57d5fd --- /dev/null +++ b/libsrc/telestrat/chline.s @@ -0,0 +1,22 @@ +; +; jede jede@oric.org 2018-04-17 +; + +; void chline (unsigned char length); +; + + .export _chline + .include "telestrat.inc" + .include "zeropage.inc" + + +.proc _chline + sta tmp1 +@loop: + lda #'-' ; Horizontal line screen code + BRK_TELEMON XWR0 ; macro send char to screen (channel 0 in telemon terms) + dec tmp1 + bne @loop + rts +.endproc + diff --git a/libsrc/telestrat/cputc.s b/libsrc/telestrat/cputc.s index d107446c3..b4f2966a4 100644 --- a/libsrc/telestrat/cputc.s +++ b/libsrc/telestrat/cputc.s @@ -5,7 +5,6 @@ ; .export _cputc - .include "telestrat.inc" From 5f6d024804e08f858029094fa91b9c18d1f8c156 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 14 Apr 2018 18:09:13 -0400 Subject: [PATCH 0656/2161] Made the samples Makefile be able to build the samples for targets other than the ones named explicitly in that file. --- samples/Makefile | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index 6a6d93bc1..8bb6d25ae 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -4,8 +4,8 @@ # This Makefile requires GNU make # -# Run 'make SYS=<target>' or set a SYS env -# var to build for another target system. +# Run 'make SYS=<target>'; or, set a SYS env. +# var. to build for another target system. SYS ?= c64 ifneq ($(shell echo),) @@ -41,13 +41,14 @@ ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),) MOU := $(wildcard $(TARGET_PATH)/$(SYS)/drv/mou/*) TGI := $(wildcard $(TARGET_PATH)/$(SYS)/drv/tgi/*) - # This one comes with VICE + # This one comes with the VICE emulator. + # See http://vice-emu.sourceforge.net/ C1541 ?= c1541 - # For this one see https://applecommander.github.io/ + # For this one, see https://applecommander.github.io/ AC ?= ac.jar - # For this one see http://www.horus.com/~hias/atari/ + # For this one, see http://www.horus.com/~hias/atari/ DIR2ATR ?= dir2atr DISK_c64 = samples.d64 @@ -59,6 +60,8 @@ endif # -------------------------------------------------------------------------- # System-dependent settings +# For convenience, these groups and lines are sorted alphabetically, first +# by target-machine group, then by mission, then by program and sub-target. # The Apple machines need the start address adjusted when using TGI LDFLAGS_mandelbrot_apple2 = --start-addr 0x4000 @@ -94,15 +97,19 @@ LDFLAGS_tgidemo_atarixl = --start-addr 0x4000 $(AS) $(<:.c=.s) .s.o: - $(AS) $(AFLAGS) -t $(SYS) $< + $(AS) $(ASFLAGS) -t $(SYS) $< .PRECIOUS: %.o .o: - $(LD) $(LDFLAGS_$(@F)_$(SYS)) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib +ifeq ($(SYS),vic20) + $(LD) $(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 +endif # -------------------------------------------------------------------------- -# List of executables +# Lists of executables EXELIST_c64 = \ ascii \ @@ -150,6 +157,13 @@ EXELIST_atarixl = $(EXELIST_atari) EXELIST_atari2600 = \ atari2600hello +# Unlisted targets will try to build everything. +# That lets us learn what they cannot build, and what settings +# we need to use for programs that can be built and run. +ifndef EXELIST_$(SYS) +EXELIST_$(SYS) := ${patsubst %.c,%,$(wildcard *.c)} +endif + # -------------------------------------------------------------------------- # Rules to make the binaries and the disk @@ -164,10 +178,10 @@ all: # overlay file-names are shortenned to fit the Atari's 8.3-character limit. multdemo: multidemo.o - $(LD) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(SYS).lib + $(LD) $(LDFLAGS) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(SYS).lib ovrldemo: overlaydemo.o - $(LD) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(SYS).lib + $(LD) $(LDFLAGS) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(SYS).lib OVERLAYLIST := $(foreach I,1 2 3,multdemo.$I ovrldemo.$I) @@ -189,7 +203,7 @@ samples.d64: samples # -------------------------------------------------------------------------- # Rule to make an Apple II disk with all samples. Needs the AppleCommander -# program available at https://applecommander.github.io/ and a template disk +# program, available at https://applecommander.github.io/, and a template disk # named 'prodos.dsk'. define DSK_WRITE_BIN_recipe @@ -260,7 +274,7 @@ zip: # Clean-up rules mostlyclean: - @$(DEL) *.map *.o *.s 2>$(NULLDEV) + @$(DEL) *.lbl *.map *.o *.s 2>$(NULLDEV) clean: mostlyclean @$(DEL) $(EXELIST_$(SYS)) $(DISK_$(SYS)) 2>$(NULLDEV) From c5f15fa1d54fd476e9b3a852bb6699ccd57183a0 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Sun, 15 Apr 2018 11:55:58 -0700 Subject: [PATCH 0657/2161] Fixed some comment and documentation errors. --- doc/funcref.sgml | 10 +++++----- libsrc/c64/acc_c64dtv_speed.s | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 4dfbf29e0..268c210fe 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -2936,8 +2936,8 @@ used in presence of a prototype. </itemize> <tag/Availability/cc65 (not all platforms) <tag/See also/ -<ref id="get_scpu_speed" name="get_c64dtv_speed">, -<ref id="set_scpu_speed" name="set_c64dtv_speed">, +<ref id="get_c64dtv_speed" name="get_c64dtv_speed">, +<ref id="set_c64dtv_speed" name="set_c64dtv_speed">, <tag/Example/None. </descrip> </quote> @@ -3512,7 +3512,7 @@ header files define constants that can be used to check the return code. <tag/Description/The function returns the current speed of the C64DTV. <tag/Notes/<itemize> <item>The function is specific to the C64. -<item>The function does not check for the presence of the cartridge. +<item>The function does not check for the presence of the C64DTV. <item>See the accelerator.h header for the speed definitions. </itemize> <tag/Availability/cc65 (not all platforms) @@ -6103,7 +6103,7 @@ clean-up when exitting the program. <descrip> <tag/Function/Set the current speed of the C64DTV. <tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ -<tag/Declaration/<tt/unsigned char set_c64dtv_speed (unsigned char speed);/ +<tag/Declaration/<tt/unsigned char __fastcall__ set_c64dtv_speed (unsigned char speed);/ <tag/Description/The function returns the speed after trying to set the speed of the C64DTV. <tag/Notes/<itemize> <item>The function is specific to the C64. @@ -6125,7 +6125,7 @@ clean-up when exitting the program. <descrip> <tag/Function/Set the current speed of the C64/C128 SuperCPU cartridge. <tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ -<tag/Declaration/<tt/unsigned char set_scpu_speed (unsigned char speed);/ +<tag/Declaration/<tt/unsigned char __fastcall__ set_scpu_speed (unsigned char speed);/ <tag/Description/The function returns the speed after trying to set the speed of the SuperCPU cartridge. <tag/Notes/<itemize> <item>The function is specific to the C128 and C64. diff --git a/libsrc/c64/acc_c64dtv_speed.s b/libsrc/c64/acc_c64dtv_speed.s index 9cf49673e..03bff8aa6 100755 --- a/libsrc/c64/acc_c64dtv_speed.s +++ b/libsrc/c64/acc_c64dtv_speed.s @@ -41,7 +41,7 @@ low_speed: set_speed: .byte $32,$99 ; SAC #$99 set accumulator to reg 9 (cpu control) txa ; (re)set skip and burst bits - .byte $32,$00 ; SAC #$99 set accumulator back to reg 0 + .byte $32,$00 ; SAC #$00 set accumulator back to reg 0 jmp _get_c64dtv_speed high_speed: From 0aa2735d4e12017de3dc834f3504da5116f0716a Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Sun, 15 Apr 2018 12:15:19 -0700 Subject: [PATCH 0658/2161] Fixed another comment. --- libsrc/c64/acc_c64dtv_speed.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/c64/acc_c64dtv_speed.s b/libsrc/c64/acc_c64dtv_speed.s index 03bff8aa6..ff86751a5 100755 --- a/libsrc/c64/acc_c64dtv_speed.s +++ b/libsrc/c64/acc_c64dtv_speed.s @@ -10,7 +10,7 @@ ; * Note that any value higher or equal to SPEED_2X will switch to fast mode. ; * ; * This function will return the actual speed the CPU is at after trying -; * to set the requested speed, to my knowledge this should not happen. +; * to set the requested speed, to my knowlegde the switching should not fail. ; * ; * This function does not check for the presence of the C64DTV, ; * make sure you use 'detect_c64dtv();' before using. From ef73310ccef82ec6ed4e2b48fcc354c747468423 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Mon, 16 Apr 2018 11:05:52 -0700 Subject: [PATCH 0659/2161] Fixed more comments. --- libsrc/c64/acc_c64dtv_speed.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/c64/acc_c64dtv_speed.s b/libsrc/c64/acc_c64dtv_speed.s index ff86751a5..6a8371a9c 100755 --- a/libsrc/c64/acc_c64dtv_speed.s +++ b/libsrc/c64/acc_c64dtv_speed.s @@ -10,7 +10,7 @@ ; * Note that any value higher or equal to SPEED_2X will switch to fast mode. ; * ; * This function will return the actual speed the CPU is at after trying -; * to set the requested speed, to my knowlegde the switching should not fail. +; * to set the requested speed, to my knowledge the switching should not fail. ; * ; * This function does not check for the presence of the C64DTV, ; * make sure you use 'detect_c64dtv();' before using. @@ -52,7 +52,7 @@ high_speed: _get_c64dtv_speed: .byte $32,$99 ; SAC #$99 set accumulator to reg 9 (cpu control) tax - .byte $32,$00 ; SAC #$99 set accumulator back to reg 0 + .byte $32,$00 ; SAC #$00 set accumulator back to reg 0 txa and #C64DTV_Fast bne in_fast_mode From cc2b5af6014a2ab60ed8cf446eca382039ffd727 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 16 Apr 2018 21:51:15 +0200 Subject: [PATCH 0660/2161] Fix comment --- libsrc/telestrat/chline.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/telestrat/chline.s b/libsrc/telestrat/chline.s index 16e57d5fd..6ead10eee 100644 --- a/libsrc/telestrat/chline.s +++ b/libsrc/telestrat/chline.s @@ -13,7 +13,7 @@ .proc _chline sta tmp1 @loop: - lda #'-' ; Horizontal line screen code + lda #'-' ; horizontal line screen code BRK_TELEMON XWR0 ; macro send char to screen (channel 0 in telemon terms) dec tmp1 bne @loop From e235ac2a0ed8f9b4a413796fe10832d783b206e3 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 17 Apr 2018 16:53:10 -0400 Subject: [PATCH 0661/2161] Added a preprocessor guard to tgidemo.c that avoids a compiler warning. DoWarning() is compiled only if it will be used. --- samples/tgidemo.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/samples/tgidemo.c b/samples/tgidemo.c index d8c2a6f50..6f3b86abc 100644 --- a/samples/tgidemo.c +++ b/samples/tgidemo.c @@ -49,8 +49,9 @@ static void CheckError (const char* S) +#if DYN_DRV static void DoWarning (void) -/* Warn the user that the TGI driver is needed for this program */ +/* Warn the user that the dynamic TGI driver is needed for this program */ { printf ("Warning: This program needs the TGI\n" "driver on disk! Press 'y' if you have\n" @@ -58,8 +59,9 @@ static void DoWarning (void) if (tolower (cgetc ()) != 'y') { exit (EXIT_SUCCESS); } - printf ("Ok. Please wait patiently...\n"); + printf ("OK. Please wait patiently...\n"); } +#endif From 7292b571deff92def83cc53a71cde488cad68ecf Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Fri, 20 Apr 2018 21:24:37 +0300 Subject: [PATCH 0662/2161] Added missing VIA register names. --- asminc/pet.inc | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/asminc/pet.inc b/asminc/pet.inc index 43d52a5d5..d165bb336 100644 --- a/asminc/pet.inc +++ b/asminc/pet.inc @@ -61,8 +61,22 @@ NMIVec := $0094 ; --------------------------------------------------------------------------- ; I/O: 6522 VIA2 -VIA := $E840 -VIA_PRB := $E840 -VIA_PRA := $E841 -VIA_DDRB := $E842 -VIA_DDRA := $E843 +VIA := $E840 ; VIA base address +VIA_PB := VIA+$0 ; Port register B +VIA_PA1 := VIA+$1 ; Port register A +VIA_PRB := VIA+$0 ; *** Deprecated *** +VIA_PRA := VIA+$1 ; *** Deprecated *** +VIA_DDRB := VIA+$2 ; Data direction register B +VIA_DDRA := VIA+$3 ; Data direction register A +VIA_T1CL := VIA+$4 ; Timer 1, low byte +VIA_T1CH := VIA+$5 ; Timer 1, high byte +VIA_T1LL := VIA+$6 ; Timer 1 latch, low byte +VIA_T1LH := VIA+$7 ; Timer 1 latch, high byte +VIA_T2CL := VIA+$8 ; Timer 2, low byte +VIA_T2CH := VIA+$9 ; Timer 2, high byte +VIA_SR := VIA+$A ; Shift register +VIA_CR := VIA+$B ; Auxiliary control register +VIA_PCR := VIA+$C ; Peripheral control register +VIA_IFR := VIA+$D ; Interrupt flag register +VIA_IER := VIA+$E ; Interrupt enable register +VIA_PA2 := VIA+$F ; Port register A w/o handshake From c2adade8a881d49f09b6b21dfb5223ee9f12aaa7 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Fri, 20 Apr 2018 21:25:43 +0300 Subject: [PATCH 0663/2161] Updated to use the new VIA register names --- libsrc/pet/joy/pet-ptvjoy.s | 15 ++++++--------- libsrc/pet/joy/pet-stdjoy.s | 4 ++-- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/libsrc/pet/joy/pet-ptvjoy.s b/libsrc/pet/joy/pet-ptvjoy.s index 7620013be..c098072fb 100644 --- a/libsrc/pet/joy/pet-ptvjoy.s +++ b/libsrc/pet/joy/pet-ptvjoy.s @@ -10,6 +10,7 @@ .include "joy-kernel.inc" .include "joy-error.inc" + .include "pet.inc" .macpack module @@ -40,10 +41,6 @@ JOY_COUNT = 2 ; Number of joysticks we support -VIA_PRA := $E841 ; Port register A -VIA_DDRA := $E843 ; Data direction register A - - .code ; ------------------------------------------------------------------------ @@ -89,9 +86,9 @@ READ: lda #%10000000 ; via port A Data-Direction ; Read joystick 1 joy1: lda #$80 ; via port A read/write - sta VIA_PRA ; (output one at PA7) + sta VIA_PA1 ; (output one at PA7) - lda VIA_PRA ; via port A read/write + lda VIA_PA1 ; via port A read/write and #$1f ; get bit 4-0 (PA4-PA0) eor #$1f rts @@ -99,13 +96,13 @@ joy1: lda #$80 ; via port A read/write ; Read joystick 2 joy2: lda #$00 ; via port A read/write - sta VIA_PRA ; (output zero at PA7) + sta VIA_PA1 ; (output zero at PA7) - lda VIA_PRA ; via port A read/write + lda VIA_PA1 ; via port A read/write and #$0f ; get bit 3-0 (PA3-PA0) sta tmp1 ; joy 4 directions - lda VIA_PRA ; via port A read/write + lda VIA_PA1 ; via port A read/write and #%00100000 ; get bit 5 (PA5) lsr ora tmp1 diff --git a/libsrc/pet/joy/pet-stdjoy.s b/libsrc/pet/joy/pet-stdjoy.s index 85b742302..75b9f7465 100644 --- a/libsrc/pet/joy/pet-stdjoy.s +++ b/libsrc/pet/joy/pet-stdjoy.s @@ -85,7 +85,7 @@ READ: joy1: lda #0 sta VIA_DDRA - lda VIA_PRA + lda VIA_PA1 and #$0f cmp #$0c bne @notc1 @@ -102,7 +102,7 @@ joy1: joy2: lda #0 sta VIA_DDRA - lda VIA_PRA + lda VIA_PA1 lsr lsr lsr From 3f5683b39139bd7f211fd72822c562863014e6cb Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Fri, 20 Apr 2018 12:08:28 -0700 Subject: [PATCH 0664/2161] Added C128 in C64 mode accelerator code and documentation. --- asminc/accelerator.inc | 7 +++ doc/c64.sgml | 3 ++ doc/funcref.sgml | 67 ++++++++++++++++++++++++ include/accelerator.h | 39 ++++++++++++++ libsrc/c64/acc_c128_speed.s | 53 +++++++++++++++++++ libsrc/c64/acc_detect_c128.s | 33 ++++++++++++ testcode/lib/accelerator/Makefile | 4 +- testcode/lib/accelerator/c64-c128-test.c | 8 +++ 8 files changed, 213 insertions(+), 1 deletion(-) create mode 100755 libsrc/c64/acc_c128_speed.s create mode 100755 libsrc/c64/acc_detect_c128.s create mode 100755 testcode/lib/accelerator/c64-c128-test.c diff --git a/asminc/accelerator.inc b/asminc/accelerator.inc index 1008b49c1..86d27b3f2 100644 --- a/asminc/accelerator.inc +++ b/asminc/accelerator.inc @@ -40,3 +40,10 @@ C64DTV_Extended_Regs := $D03F C64DTV_Slow = $00 C64DTV_Fast = $03 + + +; --------------------------------------------------------------------------- +; C128 in C64 mode + +C128_VICIIE_CLK := $D030 + diff --git a/doc/c64.sgml b/doc/c64.sgml index f1e678c72..03a03974c 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -176,10 +176,13 @@ url="funcref.html" name="function reference"> for declaration and usage. <itemize> <item>detect_c64dtv +<item>detect_c128 <item>detect_scpu <item>get_c64dtv_speed +<item>get_c128_speed <item>get_scpu_speed <item>set_c64dtv_speed +<item>set_c128_speed <item>set_scpu_speed </itemize> diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 268c210fe..17a42b103 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -69,10 +69,13 @@ function. <itemize> <item><ref id="detect_c64dtv" name="detect_c64dtv"> +<item><ref id="detect_c128" name="detect_c128"> <item><ref id="detect_scpu" name="detect_scpu"> <item><ref id="get_c64dtv_speed" name="get_c64dtv_speed"> +<item><ref id="get_c128_speed" name="get_c128_speed"> <item><ref id="get_scpu_speed" name="get_scpu_speed"> <item><ref id="set_c64dtv_speed" name="set_c64dtv_speed"> +<item><ref id="set_c128_speed" name="set_c64dtv_speed"> <item><ref id="set_scpu_speed" name="set_scpu_speed"> </itemize> @@ -2943,6 +2946,26 @@ used in presence of a prototype. </quote> +<sect1>detect_c128<label id="detect_c128"><p> + +<quote> +<descrip> +<tag/Function/Check for the presence of a C128 in C64 mode. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char detect_c128 (void);/ +<tag/Description/The function returns a 1 if a C128 in C64 mode has been detected. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="get_c128_speed" name="get_c128_speed">, +<ref id="set_c128_speed" name="set_c128_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>detect_scpu<label id="detect_scpu"><p> <quote> @@ -3524,6 +3547,28 @@ header files define constants that can be used to check the return code. </quote> +<sect1>get_c128_speed<label id="get_c128_speed"><p> + +<quote> +<descrip> +<tag/Function/Get the current speed of the C128 in C64 mode. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char get_c128_speed (void);/ +<tag/Description/The function returns the current speed of the C128 in C64 mode. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +<item>The function does not check for the presence of a C128 in C64 mode. +<item>See the accelerator.h header for the speed definitions. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="detect_c128" name="detect_c128">, +<ref id="set_c128_speed" name="set_c128_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>get_scpu_speed<label id="get_scpu_speed"><p> <quote> @@ -6119,6 +6164,28 @@ clean-up when exitting the program. </quote> +<sect1>set_c128_speed<label id="set_c128_speed"><p> + +<quote> +<descrip> +<tag/Function/Set the current speed of a C128 in C64 mode. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char __fastcall__ set_c128_speed (unsigned char speed);/ +<tag/Description/The function returns the speed after trying to set the speed of the C128 in C64 mode. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +<item>The function does not check for the presence of a C128 in C64 mode. +<item>See the accelerator.h header for the speed definitions. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="detect_c128" name="detect_c128">, +<ref id="get_c128_speed" name="get_c128_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>set_scpu_speed<label id="set_scpu_speed"><p> <quote> diff --git a/include/accelerator.h b/include/accelerator.h index 336bbb036..0e3ba6e36 100644 --- a/include/accelerator.h +++ b/include/accelerator.h @@ -136,5 +136,44 @@ extern unsigned char detect_c64dtv (void); * 0x01 : C64DTV present */ + +/* C128 in C64 mode */ + +extern unsigned char __fastcall__ set_c128_speed (unsigned char speed); + +/* Set the speed of the C128 CPU, using SPEED_SLOW will switch to + * 1 Mhz (slow) mode, SPEED_2X or SPEED_FAST will switch to 2Mhz (fast) mode. + * + * Note that any value higher or equal to SPEED_2X will switch to fast mode. + * + * This function will return the actual speed the CPU is at after trying + * to set the requested speed, to my knowledge the switching should not fail. + * + * This function does not check for the presence of a C128 in C64 mode, + * make sure you use 'detect_c128();' before using. + */ + +extern unsigned char get_c128_speed (void); + +/* Get the speed of the C128 CPU. + * + * Possible return values: + * SPEED_SLOW : Slow mode + * SPEED_2X : Fast mode + * + * This function does not check for the presence of a C128 in C64 mode, + * make sure you use 'detect_c128();' before using. + */ + +extern unsigned char detect_c128 (void); + +/* Check for the presence of a C128 in C64 mode. + * + * Possible return values: + * 0x00 : C128 in C64 mode not present + * 0x01 : C128 in C64 mode present + */ + /* End of accelerator.h */ #endif + diff --git a/libsrc/c64/acc_c128_speed.s b/libsrc/c64/acc_c128_speed.s new file mode 100755 index 000000000..4ec23b1da --- /dev/null +++ b/libsrc/c64/acc_c128_speed.s @@ -0,0 +1,53 @@ +; +; Marco van den Heuvel, 2018-04-20 +; + +; extern unsigned char __fastcall__ set_c128_speed (unsigned char speed); +; +;/* Set the speed of the C128 CPU, using SPEED_SLOW will switch to +; * 1 Mhz (slow) mode, SPEED_2X or SPEED_FAST will switch to 2Mhz (fast) mode. +; * +; * Note that any value higher or equal to SPEED_2X will switch to fast mode. +; * +; * This function will return the actual speed the CPU is at after trying +; * to set the requested speed, to my knowledge the switching should not fail. +; * +; * This function does not check for the presence of a C128 in C64 mode, +; * make sure you use 'detect_c128();' before using. +; */ + +; extern unsigned char get_c128_speed (void); +; +;/* Get the speed of the C128 CPU. +; * +; * Possible return values: +; * SPEED_SLOW : Slow mode +; * SPEED_2X : Fast mode +; * +; * This function does not check for the presence of a C128 in C64 mode, +; * make sure you use 'detect_c128();' before using. +; */ + + .export _set_c128_speed + .export _get_c128_speed + + .include "accelerator.inc" + +_set_c128_speed: + cmp #SPEED_2X + bcs high_speed +store_speed: + sta C128_VICIIE_CLK + jmp _get_c128_speed + +high_speed: + lda #$01 + bne store_speed + + +_get_c128_speed: + lda C128_VICIIE_CLK + and #$01 + ldx #$00 + rts + diff --git a/libsrc/c64/acc_detect_c128.s b/libsrc/c64/acc_detect_c128.s new file mode 100755 index 000000000..591ff6c59 --- /dev/null +++ b/libsrc/c64/acc_detect_c128.s @@ -0,0 +1,33 @@ +; +; Marco van den Heuvel, 2018-04-20 +; + +; unsigned char detect_c128 (void); +; +;/* Check for the presence of a C128 in C64 mode. +; * +; * Possible return values: +; * 0x00 : C128 in C64 mode not present +; * 0x01 : C128 in C64 mode present +; */ + + .export _detect_c128 + + .include "accelerator.inc" + +_detect_c128: + lda #$00 + tax + +; Make sure the CPU is a 8502 + .byte $1A ; NOP on 8502, INA on 65(S)C(E)02, 4510 and 65816 + bne not_found + +; Make sure a C128 VICIIe is present + ldy C128_VICIIE_CLK + cpy #$FF + beq not_found +found: + lda #$01 +not_found: + rts diff --git a/testcode/lib/accelerator/Makefile b/testcode/lib/accelerator/Makefile index a9fe5f78d..c6423e44f 100644 --- a/testcode/lib/accelerator/Makefile +++ b/testcode/lib/accelerator/Makefile @@ -1,6 +1,6 @@ CL ?= cl65 -all: c64-scpu-test.prg c128-scpu-test.prg c64dtv-test.prg +all: c64-scpu-test.prg c128-scpu-test.prg c64dtv-test.prg c64-c128-test.prg c64-scpu-test.prg: c64-c128-scpu-test.c $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg @@ -11,3 +11,5 @@ c128-scpu-test.prg: c64-c128-scpu-test.c c64dtv-test.prg: c64dtv-test.c $(CL) -t c64 c64dtv-test.c -o c64dtv-test.prg +c64-c128-test.prg: c64-c128-test.c + $(CL) -t c64 c64-c128-test.c -o c64-c128-test.prg diff --git a/testcode/lib/accelerator/c64-c128-test.c b/testcode/lib/accelerator/c64-c128-test.c new file mode 100755 index 000000000..fd20a665e --- /dev/null +++ b/testcode/lib/accelerator/c64-c128-test.c @@ -0,0 +1,8 @@ +/* C128 in C64 mode accelerator test code. */ + +#define ACC_DETECT detect_c128 +#define ACC_GET_SPEED get_c128_speed +#define ACC_SET_SPEED set_c128_speed +#define ACC_NAME "C128 in C64 mode" + +#include "turbo-test.c" From 30aed2330d07d11372d5c75b7f1f5a8a80cc2c00 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 21 Apr 2018 04:30:56 -0400 Subject: [PATCH 0665/2161] Updated a joystick adapter URL. --- doc/vic20.sgml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/vic20.sgml b/doc/vic20.sgml index 1a8f9dfef..a61691733 100644 --- a/doc/vic20.sgml +++ b/doc/vic20.sgml @@ -6,7 +6,7 @@ <author> <url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:polluks@sdf.lonestar.org" name="Stefan A. Haubenthal"> -<date>2017-05-18 +<date>2018-04-20 <abstract> An overview over the VIC20 runtime system as it is implemented for the cc65 C @@ -173,8 +173,8 @@ The default drivers, <tt/joy_stddrv (joy_static_stddrv)/, point to <tt/vic20-std <tag><tt/vic20-ptvjoy.joy (vic20_ptvjoy_joy)/</tag> Driver for the Protovision 4-player adapter contributed by Groepaz. See - <url url="http://www.protovision-online.de/hardw/4_player.php?language=en" - name="Protovision shop"> for prices and building instructions. Up to three + <url url="https://www.protovision.games/hardw/4_player.php" + name="the Protovision shop"> for prices and building instructions. Up to three joysticks are supported. </descrip><p> From 28f26991ac66cc2e0aee4a222d8b2b8701fb3077 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Sat, 21 Apr 2018 09:52:50 -0700 Subject: [PATCH 0666/2161] Updated c128 accelerator code and documentation. --- doc/c64.sgml | 6 +- doc/funcref.sgml | 134 +++++++++++++++++------------------ libsrc/c64/acc_c128_speed.s | 3 +- libsrc/c64/acc_detect_c128.s | 7 +- 4 files changed, 76 insertions(+), 74 deletions(-) diff --git a/doc/c64.sgml b/doc/c64.sgml index 03a03974c..c2c9551b4 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -175,14 +175,14 @@ The functions listed below are accelerator functions for the C64. See the <url url="funcref.html" name="function reference"> for declaration and usage. <itemize> -<item>detect_c64dtv <item>detect_c128 +<item>detect_c64dtv <item>detect_scpu -<item>get_c64dtv_speed <item>get_c128_speed +<item>get_c64dtv_speed <item>get_scpu_speed -<item>set_c64dtv_speed <item>set_c128_speed +<item>set_c64dtv_speed <item>set_scpu_speed </itemize> diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 17a42b103..75028b7b6 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -68,14 +68,14 @@ function. <sect1><tt/accelerator.h/<label id="accelerator.h"><p> <itemize> -<item><ref id="detect_c64dtv" name="detect_c64dtv"> <item><ref id="detect_c128" name="detect_c128"> +<item><ref id="detect_c64dtv" name="detect_c64dtv"> <item><ref id="detect_scpu" name="detect_scpu"> -<item><ref id="get_c64dtv_speed" name="get_c64dtv_speed"> <item><ref id="get_c128_speed" name="get_c128_speed"> +<item><ref id="get_c64dtv_speed" name="get_c64dtv_speed"> <item><ref id="get_scpu_speed" name="get_scpu_speed"> +<item><ref id="set_c128_speed" name="set_c128_speed"> <item><ref id="set_c64dtv_speed" name="set_c64dtv_speed"> -<item><ref id="set_c128_speed" name="set_c64dtv_speed"> <item><ref id="set_scpu_speed" name="set_scpu_speed"> </itemize> @@ -2926,26 +2926,6 @@ used in presence of a prototype. </quote> -<sect1>detect_c64dtv<label id="detect_c64dtv"><p> - -<quote> -<descrip> -<tag/Function/Check for the presence of the C64DTV. -<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ -<tag/Declaration/<tt/unsigned char detect_c64dtv (void);/ -<tag/Description/The function returns a 1 if a C64DTV has been detected. -<tag/Notes/<itemize> -<item>The function is specific to the C64. -</itemize> -<tag/Availability/cc65 (not all platforms) -<tag/See also/ -<ref id="get_c64dtv_speed" name="get_c64dtv_speed">, -<ref id="set_c64dtv_speed" name="set_c64dtv_speed">, -<tag/Example/None. -</descrip> -</quote> - - <sect1>detect_c128<label id="detect_c128"><p> <quote> @@ -2966,6 +2946,26 @@ used in presence of a prototype. </quote> +<sect1>detect_c64dtv<label id="detect_c64dtv"><p> + +<quote> +<descrip> +<tag/Function/Check for the presence of the C64DTV. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char detect_c64dtv (void);/ +<tag/Description/The function returns a 1 if a C64DTV has been detected. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="get_c64dtv_speed" name="get_c64dtv_speed">, +<ref id="set_c64dtv_speed" name="set_c64dtv_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>detect_scpu<label id="detect_scpu"><p> <quote> @@ -3525,28 +3525,6 @@ header files define constants that can be used to check the return code. </quote> -<sect1>get_c64dtv_speed<label id="get_c64dtv_speed"><p> - -<quote> -<descrip> -<tag/Function/Get the current speed of the C64DTV. -<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ -<tag/Declaration/<tt/unsigned char get_c64dtv_speed (void);/ -<tag/Description/The function returns the current speed of the C64DTV. -<tag/Notes/<itemize> -<item>The function is specific to the C64. -<item>The function does not check for the presence of the C64DTV. -<item>See the accelerator.h header for the speed definitions. -</itemize> -<tag/Availability/cc65 (not all platforms) -<tag/See also/ -<ref id="detect_c64dtv" name="detect_c64dtv">, -<ref id="set_c64dtv_speed" name="set_c64dtv_speed">, -<tag/Example/None. -</descrip> -</quote> - - <sect1>get_c128_speed<label id="get_c128_speed"><p> <quote> @@ -3569,6 +3547,28 @@ header files define constants that can be used to check the return code. </quote> +<sect1>get_c64dtv_speed<label id="get_c64dtv_speed"><p> + +<quote> +<descrip> +<tag/Function/Get the current speed of the C64DTV. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char get_c64dtv_speed (void);/ +<tag/Description/The function returns the current speed of the C64DTV. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +<item>The function does not check for the presence of the C64DTV. +<item>See the accelerator.h header for the speed definitions. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="detect_c64dtv" name="detect_c64dtv">, +<ref id="set_c64dtv_speed" name="set_c64dtv_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>get_scpu_speed<label id="get_scpu_speed"><p> <quote> @@ -6142,28 +6142,6 @@ clean-up when exitting the program. </quote> -<sect1>set_c64dtv_speed<label id="set_c64dtv_speed"><p> - -<quote> -<descrip> -<tag/Function/Set the current speed of the C64DTV. -<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ -<tag/Declaration/<tt/unsigned char __fastcall__ set_c64dtv_speed (unsigned char speed);/ -<tag/Description/The function returns the speed after trying to set the speed of the C64DTV. -<tag/Notes/<itemize> -<item>The function is specific to the C64. -<item>The function does not check for the presence of the C64DTV. -<item>See the accelerator.h header for the speed definitions. -</itemize> -<tag/Availability/cc65 (not all platforms) -<tag/See also/ -<ref id="detect_c64dtv" name="detect_c64dtv">, -<ref id="get_c64dtv_speed" name="get_c64dtv_speed">, -<tag/Example/None. -</descrip> -</quote> - - <sect1>set_c128_speed<label id="set_c128_speed"><p> <quote> @@ -6186,6 +6164,28 @@ clean-up when exitting the program. </quote> +<sect1>set_c64dtv_speed<label id="set_c64dtv_speed"><p> + +<quote> +<descrip> +<tag/Function/Set the current speed of the C64DTV. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char __fastcall__ set_c64dtv_speed (unsigned char speed);/ +<tag/Description/The function returns the speed after trying to set the speed of the C64DTV. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +<item>The function does not check for the presence of the C64DTV. +<item>See the accelerator.h header for the speed definitions. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="detect_c64dtv" name="detect_c64dtv">, +<ref id="get_c64dtv_speed" name="get_c64dtv_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>set_scpu_speed<label id="set_scpu_speed"><p> <quote> diff --git a/libsrc/c64/acc_c128_speed.s b/libsrc/c64/acc_c128_speed.s index 4ec23b1da..4cb2630fa 100755 --- a/libsrc/c64/acc_c128_speed.s +++ b/libsrc/c64/acc_c128_speed.s @@ -38,13 +38,12 @@ _set_c128_speed: bcs high_speed store_speed: sta C128_VICIIE_CLK - jmp _get_c128_speed + .byte $2C ; skip over the lda #$01 high_speed: lda #$01 bne store_speed - _get_c128_speed: lda C128_VICIIE_CLK and #$01 diff --git a/libsrc/c64/acc_detect_c128.s b/libsrc/c64/acc_detect_c128.s index 591ff6c59..71996730e 100755 --- a/libsrc/c64/acc_detect_c128.s +++ b/libsrc/c64/acc_detect_c128.s @@ -21,13 +21,16 @@ _detect_c128: ; Make sure the CPU is a 8502 .byte $1A ; NOP on 8502, INA on 65(S)C(E)02, 4510 and 65816 - bne not_found + beq found + .byte $3A ; decrement A again, so a #$00 can be returned + rts + +found: ; Make sure a C128 VICIIe is present ldy C128_VICIIE_CLK cpy #$FF beq not_found -found: lda #$01 not_found: rts From cc2bcb8a4db2b659a9a173c53761b77e8c603fb6 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Mon, 23 Apr 2018 19:25:11 -0700 Subject: [PATCH 0667/2161] Changed c128 accelerator code and documention to include both C64 and C128 support. --- doc/c128.sgml | 7 ++- doc/funcref.sgml | 22 +++++----- include/accelerator.h | 20 ++++----- libsrc/c128/acc_c128_speed.s | 56 ++++++++++++++++++++++++ libsrc/c128/acc_detect_c128.s | 24 ++++++++++ libsrc/c64/acc_c128_speed.s | 50 +-------------------- testcode/lib/accelerator/Makefile | 6 ++- testcode/lib/accelerator/c64-c128-test.c | 2 +- 8 files changed, 114 insertions(+), 73 deletions(-) create mode 100755 libsrc/c128/acc_c128_speed.s create mode 100755 libsrc/c128/acc_detect_c128.s diff --git a/doc/c128.sgml b/doc/c128.sgml index 9af66d62b..1bdcf01f5 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -94,9 +94,12 @@ The functions listed below are accelerator functions for the C128. See the <url url="funcref.html" name="function reference"> for declaration and usage. <itemize> +<item>detect_c128 <item>detect_scpu -<item>scpu_get_speed -<item>scpu_set_speed +<item>get_c128_speed +<item>get_scpu_speed +<item>set_c128_speed +<item>set_scpu_speed </itemize> diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 75028b7b6..55701cf55 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -2930,12 +2930,12 @@ used in presence of a prototype. <quote> <descrip> -<tag/Function/Check for the presence of a C128 in C64 mode. +<tag/Function/Check if a C128 CPU is the current CPU. <tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ <tag/Declaration/<tt/unsigned char detect_c128 (void);/ -<tag/Description/The function returns a 1 if a C128 in C64 mode has been detected. +<tag/Description/The function returns a 1 if a C128 CPU is the current CPU. <tag/Notes/<itemize> -<item>The function is specific to the C64. +<item>The function is specific to the C64 and C128. </itemize> <tag/Availability/cc65 (not all platforms) <tag/See also/ @@ -3529,13 +3529,13 @@ header files define constants that can be used to check the return code. <quote> <descrip> -<tag/Function/Get the current speed of the C128 in C64 mode. +<tag/Function/Get the current speed of the C128 CPU. <tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ <tag/Declaration/<tt/unsigned char get_c128_speed (void);/ -<tag/Description/The function returns the current speed of the C128 in C64 mode. +<tag/Description/The function returns the current speed of the C128 CPU. <tag/Notes/<itemize> -<item>The function is specific to the C64. -<item>The function does not check for the presence of a C128 in C64 mode. +<item>The function is specific to the C64 and C128. +<item>The function does not check if the C128 CPU is the current CPU. <item>See the accelerator.h header for the speed definitions. </itemize> <tag/Availability/cc65 (not all platforms) @@ -6146,13 +6146,13 @@ clean-up when exitting the program. <quote> <descrip> -<tag/Function/Set the current speed of a C128 in C64 mode. +<tag/Function/Set the current speed of a C128 CPU. <tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ <tag/Declaration/<tt/unsigned char __fastcall__ set_c128_speed (unsigned char speed);/ -<tag/Description/The function returns the speed after trying to set the speed of the C128 in C64 mode. +<tag/Description/The function returns the speed after trying to set the speed of the C128 CPU. <tag/Notes/<itemize> -<item>The function is specific to the C64. -<item>The function does not check for the presence of a C128 in C64 mode. +<item>The function is specific to the C64 and C128. +<item>The function does not check if the C128 CPU is the current CPU. <item>See the accelerator.h header for the speed definitions. </itemize> <tag/Availability/cc65 (not all platforms) diff --git a/include/accelerator.h b/include/accelerator.h index 0e3ba6e36..0fa202bc6 100644 --- a/include/accelerator.h +++ b/include/accelerator.h @@ -137,11 +137,11 @@ extern unsigned char detect_c64dtv (void); */ -/* C128 in C64 mode */ +/* C128 8502 CPU */ extern unsigned char __fastcall__ set_c128_speed (unsigned char speed); -/* Set the speed of the C128 CPU, using SPEED_SLOW will switch to +/* Set the speed of the C128 8502 CPU, using SPEED_SLOW will switch to * 1 Mhz (slow) mode, SPEED_2X or SPEED_FAST will switch to 2Mhz (fast) mode. * * Note that any value higher or equal to SPEED_2X will switch to fast mode. @@ -149,29 +149,29 @@ extern unsigned char __fastcall__ set_c128_speed (unsigned char speed); * This function will return the actual speed the CPU is at after trying * to set the requested speed, to my knowledge the switching should not fail. * - * This function does not check for the presence of a C128 in C64 mode, - * make sure you use 'detect_c128();' before using. + * This function does not check if the C128 CPU is the current CPU, make sure + * you use 'detect_c128();' before using. */ extern unsigned char get_c128_speed (void); -/* Get the speed of the C128 CPU. +/* Get the speed of the C128 8502 CPU. * * Possible return values: * SPEED_SLOW : Slow mode * SPEED_2X : Fast mode * - * This function does not check for the presence of a C128 in C64 mode, - * make sure you use 'detect_c128();' before using. + * This function does not check if the C128 CPU is the current CPU, make sure + * you use 'detect_c128();' before using. */ extern unsigned char detect_c128 (void); -/* Check for the presence of a C128 in C64 mode. +/* Check if the C128 CPU is the current CPU. * * Possible return values: - * 0x00 : C128 in C64 mode not present - * 0x01 : C128 in C64 mode present + * 0x00 : C128 CPU is not the current CPU + * 0x01 : C128 CPU is the current CPU */ /* End of accelerator.h */ diff --git a/libsrc/c128/acc_c128_speed.s b/libsrc/c128/acc_c128_speed.s new file mode 100755 index 000000000..c3012b2c8 --- /dev/null +++ b/libsrc/c128/acc_c128_speed.s @@ -0,0 +1,56 @@ +; +; Marco van den Heuvel, 2018-04-23 +; + +; extern unsigned char __fastcall__ set_c128_speed (unsigned char speed); +; +;/* Set the speed of the C128 8502 CPU, using SPEED_SLOW will switch to +; * 1 Mhz (slow) mode, SPEED_2X or SPEED_FAST will switch to 2Mhz (fast) mode. +; * +; * Note that any value higher or equal to SPEED_2X will switch to fast mode. +; * +; * This function will return the actual speed the CPU is at after trying +; * to set the requested speed, to my knowledge the switching should not fail. +; * +; * For C64 programs a check for a C128 in C64 mode is needed, make sure you +; * use 'detect_c128();' before using. +; * +; * For C128 programs no detect function call is needed. +; */ + +; extern unsigned char get_c128_speed (void); +; +;/* Get the speed of the C128 8502 CPU. +; * +; * Possible return values: +; * SPEED_SLOW : Slow mode +; * SPEED_2X : Fast mode +; * +; * For C64 programs a check for a C128 in C64 mode is needed, make sure you +; * use 'detect_c128();' before using. +; * +; * For C128 programs no detect function call is needed. +; */ + + .export _set_c128_speed + .export _get_c128_speed + + .include "accelerator.inc" + +_set_c128_speed: + cmp #SPEED_2X + bcs high_speed +store_speed: + sta C128_VICIIE_CLK + + .byte $2C ; skip over the lda #$01 +high_speed: + lda #$01 + bne store_speed + +_get_c128_speed: + lda C128_VICIIE_CLK + and #$01 + ldx #$00 + rts + diff --git a/libsrc/c128/acc_detect_c128.s b/libsrc/c128/acc_detect_c128.s new file mode 100755 index 000000000..f40fe395a --- /dev/null +++ b/libsrc/c128/acc_detect_c128.s @@ -0,0 +1,24 @@ +; +; Marco van den Heuvel, 2018-04-23 +; + +; unsigned char detect_c128 (void); +; +;/* Check if the C128 8502 CPU is the current CPU. +; * +; * Possible return values: +; * 0x00 : C128 8502 is not the current CPU +; * 0x01 : C128 8502 is the current CPU +; */ + + .export _detect_c128 + + .include "accelerator.inc" + +_detect_c128: + ldx #$00 + lda #$01 + +; Make sure the CPU is a 8502 + .byte $3A ; NOP on 8502, DEA on 65(S)C(E)02, 4510 and 65816 + rts diff --git a/libsrc/c64/acc_c128_speed.s b/libsrc/c64/acc_c128_speed.s index 4cb2630fa..bdd559412 100755 --- a/libsrc/c64/acc_c128_speed.s +++ b/libsrc/c64/acc_c128_speed.s @@ -1,52 +1,6 @@ ; -; Marco van den Heuvel, 2018-04-20 +; Marco van den Heuvel, 2018-04-23 ; -; extern unsigned char __fastcall__ set_c128_speed (unsigned char speed); -; -;/* Set the speed of the C128 CPU, using SPEED_SLOW will switch to -; * 1 Mhz (slow) mode, SPEED_2X or SPEED_FAST will switch to 2Mhz (fast) mode. -; * -; * Note that any value higher or equal to SPEED_2X will switch to fast mode. -; * -; * This function will return the actual speed the CPU is at after trying -; * to set the requested speed, to my knowledge the switching should not fail. -; * -; * This function does not check for the presence of a C128 in C64 mode, -; * make sure you use 'detect_c128();' before using. -; */ - -; extern unsigned char get_c128_speed (void); -; -;/* Get the speed of the C128 CPU. -; * -; * Possible return values: -; * SPEED_SLOW : Slow mode -; * SPEED_2X : Fast mode -; * -; * This function does not check for the presence of a C128 in C64 mode, -; * make sure you use 'detect_c128();' before using. -; */ - - .export _set_c128_speed - .export _get_c128_speed - - .include "accelerator.inc" - -_set_c128_speed: - cmp #SPEED_2X - bcs high_speed -store_speed: - sta C128_VICIIE_CLK - - .byte $2C ; skip over the lda #$01 -high_speed: - lda #$01 - bne store_speed - -_get_c128_speed: - lda C128_VICIIE_CLK - and #$01 - ldx #$00 - rts +.include "../c128/acc_c128_speed.s" diff --git a/testcode/lib/accelerator/Makefile b/testcode/lib/accelerator/Makefile index c6423e44f..121ad57b8 100644 --- a/testcode/lib/accelerator/Makefile +++ b/testcode/lib/accelerator/Makefile @@ -1,6 +1,7 @@ CL ?= cl65 -all: c64-scpu-test.prg c128-scpu-test.prg c64dtv-test.prg c64-c128-test.prg +all: c64-scpu-test.prg c128-scpu-test.prg c64dtv-test.prg \ + c64-c128-test.prg c128-test.prg c64-scpu-test.prg: c64-c128-scpu-test.c $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg @@ -13,3 +14,6 @@ c64dtv-test.prg: c64dtv-test.c c64-c128-test.prg: c64-c128-test.c $(CL) -t c64 c64-c128-test.c -o c64-c128-test.prg + +c128-test.prg: c64-c128-test.c + $(CL) -t c128 c64-c128-test.c -o c128-test.prg diff --git a/testcode/lib/accelerator/c64-c128-test.c b/testcode/lib/accelerator/c64-c128-test.c index fd20a665e..ba212e03d 100755 --- a/testcode/lib/accelerator/c64-c128-test.c +++ b/testcode/lib/accelerator/c64-c128-test.c @@ -3,6 +3,6 @@ #define ACC_DETECT detect_c128 #define ACC_GET_SPEED get_c128_speed #define ACC_SET_SPEED set_c128_speed -#define ACC_NAME "C128 in C64 mode" +#define ACC_NAME "C128 CPU" #include "turbo-test.c" From f2e46f0fdf5d54b7e5de8a1be8dd95925c606b92 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Wed, 25 Apr 2018 12:53:29 -0700 Subject: [PATCH 0668/2161] Added C64 Chameleon accelerator code and documentation. --- asminc/accelerator.inc | 15 +++- doc/c64.sgml | 3 + doc/funcref.sgml | 67 +++++++++++++++ include/accelerator.h | 52 +++++++++++ libsrc/c64/acc_chameleon_speed.s | 100 ++++++++++++++++++++++ libsrc/c64/acc_detect_chameleon.s | 39 +++++++++ testcode/lib/accelerator/Makefile | 5 +- testcode/lib/accelerator/chameleon-test.c | 8 ++ 8 files changed, 287 insertions(+), 2 deletions(-) create mode 100755 libsrc/c64/acc_chameleon_speed.s create mode 100755 libsrc/c64/acc_detect_chameleon.s create mode 100755 testcode/lib/accelerator/chameleon-test.c diff --git a/asminc/accelerator.inc b/asminc/accelerator.inc index 86d27b3f2..0c687b2ad 100644 --- a/asminc/accelerator.inc +++ b/asminc/accelerator.inc @@ -43,7 +43,20 @@ C64DTV_Fast = $03 ; --------------------------------------------------------------------------- -; C128 in C64 mode +; C128 native and C128 in C64 mode C128_VICIIE_CLK := $D030 + +; --------------------------------------------------------------------------- +; C64 Chameleon cartridge + +CHAMELEON_CFGTUR := $D0F3 +CHAMELEON_CFGENA := $D0FE + +CHAMELEON_ENABLE_REGS = $2A +CHAMELEON_DISABLE_REGS = $FF + +CHAMELEON_CFGTUR_LIMIT_1MHZ = %00001100 +CHAMELEON_CFGTUR_LIMIT_NONE = %10000000 + diff --git a/doc/c64.sgml b/doc/c64.sgml index c2c9551b4..c037b1e0e 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -177,12 +177,15 @@ url="funcref.html" name="function reference"> for declaration and usage. <itemize> <item>detect_c128 <item>detect_c64dtv +<item>detect_chameleon <item>detect_scpu <item>get_c128_speed <item>get_c64dtv_speed +<item>get_chameleon_speed <item>get_scpu_speed <item>set_c128_speed <item>set_c64dtv_speed +<item>set_chameleon_speed <item>set_scpu_speed </itemize> diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 55701cf55..09ee27e4a 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -70,12 +70,15 @@ function. <itemize> <item><ref id="detect_c128" name="detect_c128"> <item><ref id="detect_c64dtv" name="detect_c64dtv"> +<item><ref id="detect_chameleon" name="detect_chameleon"> <item><ref id="detect_scpu" name="detect_scpu"> <item><ref id="get_c128_speed" name="get_c128_speed"> <item><ref id="get_c64dtv_speed" name="get_c64dtv_speed"> +<item><ref id="get_chameleon_speed" name="get_chameleon_speed"> <item><ref id="get_scpu_speed" name="get_scpu_speed"> <item><ref id="set_c128_speed" name="set_c128_speed"> <item><ref id="set_c64dtv_speed" name="set_c64dtv_speed"> +<item><ref id="set_chameleon_speed" name="set_chameleon_speed"> <item><ref id="set_scpu_speed" name="set_scpu_speed"> </itemize> @@ -2966,6 +2969,26 @@ used in presence of a prototype. </quote> +<sect1>detect_chameleon<label id="detect_chameleon"><p> + +<quote> +<descrip> +<tag/Function/Check for the presence of the C64 Chameleon cartridge. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char detect_chameleon (void);/ +<tag/Description/The function returns a 1 if a C64 Chameleon cartridge has been detected. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="get_chameleon_speed" name="get_chameleon_speed">, +<ref id="set_chameleon_speed" name="set_chameleon_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>detect_scpu<label id="detect_scpu"><p> <quote> @@ -3569,6 +3592,28 @@ header files define constants that can be used to check the return code. </quote> +<sect1>get_chameleon_speed<label id="get_chameleon_speed"><p> + +<quote> +<descrip> +<tag/Function/Get the current speed of the C64 Chameleon cartridge. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char get_chameleon_speed (void);/ +<tag/Description/The function returns the current speed of the C64 Chameleon cartridge. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +<item>The function does not check for the presence of the C64 Chameleon cartridge. +<item>See the accelerator.h header for the speed definitions. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="detect_chameleon" name="detect_chameleon">, +<ref id="set_chameleon_speed" name="set_chameleon_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>get_scpu_speed<label id="get_scpu_speed"><p> <quote> @@ -6186,6 +6231,28 @@ clean-up when exitting the program. </quote> +<sect1>set_chameleon_speed<label id="set_chameleon_speed"><p> + +<quote> +<descrip> +<tag/Function/Set the current speed of the C64 Chameleon cartridge. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char __fastcall__ set_chameleon_speed (unsigned char speed);/ +<tag/Description/The function returns the speed after trying to set the speed of the C64 Chameleon cartridge. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +<item>The function does not check for the presence of the C64 Chameleon cartridge. +<item>See the accelerator.h header for the speed definitions. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="detect_chameleon" name="detect_chameleon">, +<ref id="get_chameleon_speed" name="get_chameleon_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>set_scpu_speed<label id="set_scpu_speed"><p> <quote> diff --git a/include/accelerator.h b/include/accelerator.h index 0fa202bc6..5797cb36c 100644 --- a/include/accelerator.h +++ b/include/accelerator.h @@ -174,6 +174,58 @@ extern unsigned char detect_c128 (void); * 0x01 : C128 CPU is the current CPU */ + +/* C64 Chameleon cartridge */ + +extern unsigned char __fastcall__ set_chameleon_speed (unsigned char speed); + +/* Set the speed of the C64 Chameleon cartridge, the following inputs + * are accepted: + * SPEED_SLOW : 1 Mhz mode + * SPEED_1X : 1 Mhz mode + * SPEED_2X : 2 Mhz mode + * SPEED_3X : 3 Mhz mode + * SPEED_4X : 4 Mhz mode + * SPEED_5X : 5 Mhz mode + * SPEED_6X : 6 Mhz mode + * SPEED_FAST : Maximum speed mode + * + * Note that any value higher or equal to SPEED_7X will switch to maximum + * speed mode. + * + * This function will return the actual speed the CPU is at after trying + * to set the requested speed, to my knowledge the switching should not fail. + * + * This function does not check for the presence of the C64 Chameleon cartridge, + * make sure you use 'detect_chameleon();' before using. + */ + +extern unsigned char get_chameleon_speed (void); + +;/* Get the speed of the C64 Chameleon cartridge. +; * +; * Possible return values: +; * SPEED_SLOW : Slow mode +; * SPEED_2X : 2Mhz mode +; * SPEED_3X : 3Mhz mode +; * SPEED_4X : 4Mhz mode +; * SPEED_5X : 5Mhz mode +; * SPEED_6X : 6Mhz mode +; * SPEED_FAST : Maximum speed mode +; * +; * This function does not check for the presence of the C64 Chameleon cartridge, +; * make sure you use 'detect_chameleon();' before using. +; */ + +extern unsigned char detect_chameleon (void); + +/* Check for the presence of the C64 Chameleon cartridge. + * + * Possible return values: + * 0x00 : C64 Chameleon cartridge not present + * 0x01 : C64 Chameleon cartridge present + */ + /* End of accelerator.h */ #endif diff --git a/libsrc/c64/acc_chameleon_speed.s b/libsrc/c64/acc_chameleon_speed.s new file mode 100755 index 000000000..0e3e1320f --- /dev/null +++ b/libsrc/c64/acc_chameleon_speed.s @@ -0,0 +1,100 @@ +; +; Marco van den Heuvel, 2018-04-25 +; + +; extern unsigned char __fastcall__ set_chameleon_speed (unsigned char speed); +; +;/* Set the speed of the Chameleon cartridge, the following inputs +; * are accepted: +; * SPEED_SLOW : 1 Mhz mode +; * SPEED_1X : 1 Mhz mode +; * SPEED_2X : 2 Mhz mode +; * SPEED_3X : 3 Mhz mode +; * SPEED_4X : 4 Mhz mode +; * SPEED_5X : 5 Mhz mode +; * SPEED_6X : 6 Mhz mode +; * SPEED_FAST : Maximum speed mode +; * +; * Note that any value higher or equal to SPEED_7X will switch to maximum +; * speed mode. +; * +; * This function will return the actual speed the CPU is at after trying +; * to set the requested speed, to my knowledge the switching should not fail. +; * +; * This function does not check for the presence of the Chameleon cartridge, +; * make sure you use 'detect_chameleon();' before using. +; */ + +; extern unsigned char get_chameleon_speed (void); +; +;/* Get the speed of the Chameleon cartridge. +; * +; * Possible return values: +; * SPEED_SLOW : Slow mode +; * SPEED_2X : 2Mhz mode +; * SPEED_3X : 3Mhz mode +; * SPEED_4X : 4Mhz mode +; * SPEED_5X : 5Mhz mode +; * SPEED_6X : 6Mhz mode +; * SPEED_FAST : Maximum speed mode +; * +; * This function does not check for the presence of the Chameleon cartridge, +; * make sure you use 'detect_chameleon();' before using. +; */ + + .export _set_chameleon_speed + .export _get_chameleon_speed + + .include "accelerator.inc" + +_set_chameleon_speed: + cmp #SPEED_7X + bcs maximum_speed + cmp #SPEED_1X + beq low_speed + ora #$80 +set_speed: + jsr activate_regs + sta CHAMELEON_CFGTUR + jmp return_speed + +low_speed: + lda #CHAMELEON_CFGTUR_LIMIT_1MHZ + bne set_speed + +maximum_speed: + lda #CHAMELEON_CFGTUR_LIMIT_NONE + bne set_speed + +_get_chameleon_speed: + jsr activate_regs +return_speed: + ldx #$00 + lda CHAMELEON_CFGTUR + tay + and #%10000000 + beq return_value + tya + and #%00001000 + bne is_slow_mode + tya + and #%00000111 + beq is_max_mode +return_value: + ldy #CHAMELEON_DISABLE_REGS + sty CHAMELEON_CFGENA + rts + +is_slow_mode: + txa + bne return_value + +is_max_mode: + lda #SPEED_FAST + bne return_value + +activate_regs: + ldy #CHAMELEON_ENABLE_REGS + sty CHAMELEON_CFGENA + rts + diff --git a/libsrc/c64/acc_detect_chameleon.s b/libsrc/c64/acc_detect_chameleon.s new file mode 100755 index 000000000..4b90c6ea9 --- /dev/null +++ b/libsrc/c64/acc_detect_chameleon.s @@ -0,0 +1,39 @@ +; +; Marco van den Heuvel, 2018-04-25 +; + +; unsigned char detect_chameleon (void); +; +;/* Check for the presence of the Chameleon cartridge. +; * +; * Possible return values: +; * 0x00 : Chameleon cartridge not present +; * 0x01 : Chameleon cartridge present +; */ + + .export _detect_chameleon + + .include "accelerator.inc" + +_detect_chameleon: + lda #$00 + tax + +; Make sure the CPU is a 6510 + .byte $1A ; NOP on 6510, INA on 65(S)C(E)02, 4510 and 65816 + bne not_found + + ldy CHAMELEON_CFGENA + lda #CHAMELEON_ENABLE_REGS + sta CHAMELEON_CFGENA + lda CHAMELEON_CFGENA + sty CHAMELEON_CFGENA + cmp #$FF + beq not_found +found: + lda #$01 + .byte $2C +not_found: + lda #$00 + rts + diff --git a/testcode/lib/accelerator/Makefile b/testcode/lib/accelerator/Makefile index 121ad57b8..e9bd61881 100644 --- a/testcode/lib/accelerator/Makefile +++ b/testcode/lib/accelerator/Makefile @@ -1,7 +1,7 @@ CL ?= cl65 all: c64-scpu-test.prg c128-scpu-test.prg c64dtv-test.prg \ - c64-c128-test.prg c128-test.prg + c64-c128-test.prg c128-test.prg chameleon-test.prg c64-scpu-test.prg: c64-c128-scpu-test.c $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg @@ -17,3 +17,6 @@ c64-c128-test.prg: c64-c128-test.c c128-test.prg: c64-c128-test.c $(CL) -t c128 c64-c128-test.c -o c128-test.prg + +chameleon-test.prg: chameleon-test.c + $(CL) -t c64 chameleon-test.c -o chameleon-test.prg diff --git a/testcode/lib/accelerator/chameleon-test.c b/testcode/lib/accelerator/chameleon-test.c new file mode 100755 index 000000000..ffc1539b5 --- /dev/null +++ b/testcode/lib/accelerator/chameleon-test.c @@ -0,0 +1,8 @@ +/* C64 Chameleon accelerator test code. */ + +#define ACC_DETECT detect_chameleon +#define ACC_GET_SPEED get_chameleon_speed +#define ACC_SET_SPEED set_chameleon_speed +#define ACC_NAME "Chameleon cartridge" + +#include "turbo-test.c" From c92a3c5bd53724d13194930beeb310fb49c3757b Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 26 Apr 2018 05:37:27 -0400 Subject: [PATCH 0669/2161] Improved the accelerator code. Fixed an infinite loop. Removed the execute permissions from some files. --- libsrc/c128/acc_c128_speed.s | 29 ++++++++----------- libsrc/c128/acc_detect_c128.s | 0 libsrc/c128/acc_detect_scpu.s | 0 libsrc/c128/acc_scpu_speed.s | 0 libsrc/c64/acc_c128_speed.s | 1 - libsrc/c64/acc_c64dtv_speed.s | 0 libsrc/c64/acc_detect_c128.s | 25 +++++++--------- libsrc/c64/acc_detect_c64dtv.s | 0 testcode/lib/accelerator/c64-c128-scpu-test.c | 0 testcode/lib/accelerator/c64-c128-test.c | 0 testcode/lib/accelerator/c64dtv-test.c | 0 11 files changed, 23 insertions(+), 32 deletions(-) mode change 100755 => 100644 libsrc/c128/acc_c128_speed.s mode change 100755 => 100644 libsrc/c128/acc_detect_c128.s mode change 100755 => 100644 libsrc/c128/acc_detect_scpu.s mode change 100755 => 100644 libsrc/c128/acc_scpu_speed.s mode change 100755 => 100644 libsrc/c64/acc_c128_speed.s mode change 100755 => 100644 libsrc/c64/acc_c64dtv_speed.s mode change 100755 => 100644 libsrc/c64/acc_detect_c128.s mode change 100755 => 100644 libsrc/c64/acc_detect_c64dtv.s mode change 100755 => 100644 testcode/lib/accelerator/c64-c128-scpu-test.c mode change 100755 => 100644 testcode/lib/accelerator/c64-c128-test.c mode change 100755 => 100644 testcode/lib/accelerator/c64dtv-test.c diff --git a/libsrc/c128/acc_c128_speed.s b/libsrc/c128/acc_c128_speed.s old mode 100755 new mode 100644 index c3012b2c8..a104aad1a --- a/libsrc/c128/acc_c128_speed.s +++ b/libsrc/c128/acc_c128_speed.s @@ -1,21 +1,22 @@ ; -; Marco van den Heuvel, 2018-04-23 +; 2018-04-23, Marco van den Heuvel +; 2018-04-26, Greg King ; ; extern unsigned char __fastcall__ set_c128_speed (unsigned char speed); ; -;/* Set the speed of the C128 8502 CPU, using SPEED_SLOW will switch to +;/* Set the speed of the C128 8502 CPU; using SPEED_SLOW will switch to ; * 1 Mhz (slow) mode, SPEED_2X or SPEED_FAST will switch to 2Mhz (fast) mode. ; * ; * Note that any value higher or equal to SPEED_2X will switch to fast mode. ; * -; * This function will return the actual speed the CPU is at after trying -; * to set the requested speed, to my knowledge the switching should not fail. +; * This function will return the actual speed the CPU is at, after trying +; * to set the requested speed; to my knowledge, the switching should not fail. ; * -; * For C64 programs a check for a C128 in C64 mode is needed, make sure you +; * For C64 programs, a check for a C128 in C64 mode is needed; make sure you ; * use 'detect_c128();' before using. ; * -; * For C128 programs no detect function call is needed. +; * For C128 programs, no detect function call is needed. ; */ ; extern unsigned char get_c128_speed (void); @@ -26,10 +27,10 @@ ; * SPEED_SLOW : Slow mode ; * SPEED_2X : Fast mode ; * -; * For C64 programs a check for a C128 in C64 mode is needed, make sure you +; * For C64 programs, a check for a C128 in C64 mode is needed; make sure you ; * use 'detect_c128();' before using. ; * -; * For C128 programs no detect function call is needed. +; * For C128 programs, no detect function call is needed. ; */ .export _set_c128_speed @@ -39,18 +40,12 @@ _set_c128_speed: cmp #SPEED_2X - bcs high_speed -store_speed: + lda #$00 ; clear VIC-IIe test bit + rol a ; carry flag is speed bit sta C128_VICIIE_CLK - .byte $2C ; skip over the lda #$01 -high_speed: - lda #$01 - bne store_speed - _get_c128_speed: lda C128_VICIIE_CLK and #$01 - ldx #$00 + ldx #>$0000 rts - diff --git a/libsrc/c128/acc_detect_c128.s b/libsrc/c128/acc_detect_c128.s old mode 100755 new mode 100644 diff --git a/libsrc/c128/acc_detect_scpu.s b/libsrc/c128/acc_detect_scpu.s old mode 100755 new mode 100644 diff --git a/libsrc/c128/acc_scpu_speed.s b/libsrc/c128/acc_scpu_speed.s old mode 100755 new mode 100644 diff --git a/libsrc/c64/acc_c128_speed.s b/libsrc/c64/acc_c128_speed.s old mode 100755 new mode 100644 index bdd559412..678f52d0c --- a/libsrc/c64/acc_c128_speed.s +++ b/libsrc/c64/acc_c128_speed.s @@ -3,4 +3,3 @@ ; .include "../c128/acc_c128_speed.s" - diff --git a/libsrc/c64/acc_c64dtv_speed.s b/libsrc/c64/acc_c64dtv_speed.s old mode 100755 new mode 100644 diff --git a/libsrc/c64/acc_detect_c128.s b/libsrc/c64/acc_detect_c128.s old mode 100755 new mode 100644 index 71996730e..12817001a --- a/libsrc/c64/acc_detect_c128.s +++ b/libsrc/c64/acc_detect_c128.s @@ -1,5 +1,6 @@ ; -; Marco van den Heuvel, 2018-04-20 +; 2018-04-20, Marco van den Heuvel +; 2018-04-26, Greg King ; ; unsigned char detect_c128 (void); @@ -16,21 +17,17 @@ .include "accelerator.inc" _detect_c128: - lda #$00 - tax + ldx #>$0001 + lda #<$0001 -; Make sure the CPU is a 8502 - .byte $1A ; NOP on 8502, INA on 65(S)C(E)02, 4510 and 65816 - beq found - .byte $3A ; decrement A again, so a #$00 can be returned - rts +; Make sure the CPU is an 8502. + .byte $3A ; NOP on 8502, DEA on 65(S)C(E)02, 4510, and 65816 + beq detect_end -found: - -; Make sure a C128 VICIIe is present +; Make sure a C128 VIC-IIe is present. ldy C128_VICIIE_CLK cpy #$FF - beq not_found - lda #$01 -not_found: + bne detect_end + txa ; return zero when not VIC-IIe +detect_end: rts diff --git a/libsrc/c64/acc_detect_c64dtv.s b/libsrc/c64/acc_detect_c64dtv.s old mode 100755 new mode 100644 diff --git a/testcode/lib/accelerator/c64-c128-scpu-test.c b/testcode/lib/accelerator/c64-c128-scpu-test.c old mode 100755 new mode 100644 diff --git a/testcode/lib/accelerator/c64-c128-test.c b/testcode/lib/accelerator/c64-c128-test.c old mode 100755 new mode 100644 diff --git a/testcode/lib/accelerator/c64dtv-test.c b/testcode/lib/accelerator/c64dtv-test.c old mode 100755 new mode 100644 From 14280151583c4ddf5cad6ecb794db4d1b651a6bb Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Thu, 26 Apr 2018 09:18:54 -0700 Subject: [PATCH 0670/2161] Optimized the code a bit as suggested by Greg. --- libsrc/c64/acc_detect_chameleon.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/c64/acc_detect_chameleon.s b/libsrc/c64/acc_detect_chameleon.s index 4b90c6ea9..a16a264e7 100755 --- a/libsrc/c64/acc_detect_chameleon.s +++ b/libsrc/c64/acc_detect_chameleon.s @@ -32,8 +32,8 @@ _detect_chameleon: beq not_found found: lda #$01 - .byte $2C + .byte $24 not_found: - lda #$00 + txa rts From 97e69952c4bccac2994a2ce923502380297258c0 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Fri, 27 Apr 2018 09:16:25 -0700 Subject: [PATCH 0671/2161] Removed extern keyword from function prototypes. --- include/accelerator.h | 22 +++++++++++----------- libsrc/c128/acc_c128_speed.s | 4 ++-- libsrc/c128/acc_scpu_speed.s | 4 ++-- libsrc/c64/acc_c64dtv_speed.s | 4 ++-- libsrc/c64/acc_chameleon_speed.s | 4 ++-- libsrc/c64/acc_scpu_speed.s | 4 ++-- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/include/accelerator.h b/include/accelerator.h index 5797cb36c..d29b73467 100644 --- a/include/accelerator.h +++ b/include/accelerator.h @@ -77,7 +77,7 @@ extern unsigned char __fastcall__ set_scpu_speed (unsigned char speed); * make sure you use 'detect_scpu();' before using. */ -extern unsigned char get_scpu_speed (void); +unsigned char get_scpu_speed (void); /* Get the speed of the SuperCPU cartridge. * @@ -89,7 +89,7 @@ extern unsigned char get_scpu_speed (void); * make sure you use 'detect_scpu();' before using. */ -extern unsigned char detect_scpu (void); +unsigned char detect_scpu (void); /* Check for the presence of the SuperCPU cartridge. * @@ -101,7 +101,7 @@ extern unsigned char detect_scpu (void); /* C64DTV */ -extern unsigned char __fastcall__ set_c64dtv_speed (unsigned char speed); +unsigned char __fastcall__ set_c64dtv_speed (unsigned char speed); /* Set the speed of the C64DTV, using SPEED_SLOW will switch to * slow mode, SPEED_2X or SPEED_FAST will switch to fast mode. @@ -115,7 +115,7 @@ extern unsigned char __fastcall__ set_c64dtv_speed (unsigned char speed); * make sure you use 'detect_c64dtv();' before using. */ -extern unsigned char get_c64dtv_speed (void); +unsigned char get_c64dtv_speed (void); /* Get the speed of the C64DTV. * @@ -127,7 +127,7 @@ extern unsigned char get_c64dtv_speed (void); * make sure you use 'detect_c64dtv();' before using. */ -extern unsigned char detect_c64dtv (void); +unsigned char detect_c64dtv (void); /* Check for the presence of the C64DTV. * @@ -139,7 +139,7 @@ extern unsigned char detect_c64dtv (void); /* C128 8502 CPU */ -extern unsigned char __fastcall__ set_c128_speed (unsigned char speed); +unsigned char __fastcall__ set_c128_speed (unsigned char speed); /* Set the speed of the C128 8502 CPU, using SPEED_SLOW will switch to * 1 Mhz (slow) mode, SPEED_2X or SPEED_FAST will switch to 2Mhz (fast) mode. @@ -153,7 +153,7 @@ extern unsigned char __fastcall__ set_c128_speed (unsigned char speed); * you use 'detect_c128();' before using. */ -extern unsigned char get_c128_speed (void); +unsigned char get_c128_speed (void); /* Get the speed of the C128 8502 CPU. * @@ -165,7 +165,7 @@ extern unsigned char get_c128_speed (void); * you use 'detect_c128();' before using. */ -extern unsigned char detect_c128 (void); +unsigned char detect_c128 (void); /* Check if the C128 CPU is the current CPU. * @@ -177,7 +177,7 @@ extern unsigned char detect_c128 (void); /* C64 Chameleon cartridge */ -extern unsigned char __fastcall__ set_chameleon_speed (unsigned char speed); +unsigned char __fastcall__ set_chameleon_speed (unsigned char speed); /* Set the speed of the C64 Chameleon cartridge, the following inputs * are accepted: @@ -200,7 +200,7 @@ extern unsigned char __fastcall__ set_chameleon_speed (unsigned char speed); * make sure you use 'detect_chameleon();' before using. */ -extern unsigned char get_chameleon_speed (void); +unsigned char get_chameleon_speed (void); ;/* Get the speed of the C64 Chameleon cartridge. ; * @@ -217,7 +217,7 @@ extern unsigned char get_chameleon_speed (void); ; * make sure you use 'detect_chameleon();' before using. ; */ -extern unsigned char detect_chameleon (void); +unsigned char detect_chameleon (void); /* Check for the presence of the C64 Chameleon cartridge. * diff --git a/libsrc/c128/acc_c128_speed.s b/libsrc/c128/acc_c128_speed.s index c3012b2c8..3f2017de9 100755 --- a/libsrc/c128/acc_c128_speed.s +++ b/libsrc/c128/acc_c128_speed.s @@ -2,7 +2,7 @@ ; Marco van den Heuvel, 2018-04-23 ; -; extern unsigned char __fastcall__ set_c128_speed (unsigned char speed); +; unsigned char __fastcall__ set_c128_speed (unsigned char speed); ; ;/* Set the speed of the C128 8502 CPU, using SPEED_SLOW will switch to ; * 1 Mhz (slow) mode, SPEED_2X or SPEED_FAST will switch to 2Mhz (fast) mode. @@ -18,7 +18,7 @@ ; * For C128 programs no detect function call is needed. ; */ -; extern unsigned char get_c128_speed (void); +; unsigned char get_c128_speed (void); ; ;/* Get the speed of the C128 8502 CPU. ; * diff --git a/libsrc/c128/acc_scpu_speed.s b/libsrc/c128/acc_scpu_speed.s index 4bd142bbb..9f932aecd 100755 --- a/libsrc/c128/acc_scpu_speed.s +++ b/libsrc/c128/acc_scpu_speed.s @@ -2,7 +2,7 @@ ; Marco van den Heuvel, 2018-04-09 ; -; extern unsigned char __fastcall__ set_scpu_speed (unsigned char speed); +; unsigned char __fastcall__ set_scpu_speed (unsigned char speed); ; ;/* Set the speed of the SuperCPU cartridge, using SPEED_SLOW will switch to ; * 1 Mhz mode, SPEED_20X or SPEED_FAST will switch to 20 Mhz mode. @@ -19,7 +19,7 @@ ; * make sure you use 'detect_scpu();' before using. ; */ -; extern unsigned char get_scpu_speed (void); +; unsigned char get_scpu_speed (void); ; ;/* Get the speed of the SuperCPU cartridge. ; * diff --git a/libsrc/c64/acc_c64dtv_speed.s b/libsrc/c64/acc_c64dtv_speed.s index 6a8371a9c..d6cf8b994 100755 --- a/libsrc/c64/acc_c64dtv_speed.s +++ b/libsrc/c64/acc_c64dtv_speed.s @@ -2,7 +2,7 @@ ; Marco van den Heuvel, 2018-04-14 ; -; extern unsigned char __fastcall__ set_c64dtv_speed (unsigned char speed); +; unsigned char __fastcall__ set_c64dtv_speed (unsigned char speed); ; ;/* Set the speed of the C64DTV, using SPEED_SLOW will switch to ; * slow mode, SPEED_2X or SPEED_FAST will switch to fast mode. @@ -16,7 +16,7 @@ ; * make sure you use 'detect_c64dtv();' before using. ; */ -; extern unsigned char get_c64dtv_speed (void); +; unsigned char get_c64dtv_speed (void); ; ;/* Get the speed of the C64DTV. ; * diff --git a/libsrc/c64/acc_chameleon_speed.s b/libsrc/c64/acc_chameleon_speed.s index 0e3e1320f..ce51b9dde 100755 --- a/libsrc/c64/acc_chameleon_speed.s +++ b/libsrc/c64/acc_chameleon_speed.s @@ -2,7 +2,7 @@ ; Marco van den Heuvel, 2018-04-25 ; -; extern unsigned char __fastcall__ set_chameleon_speed (unsigned char speed); +; unsigned char __fastcall__ set_chameleon_speed (unsigned char speed); ; ;/* Set the speed of the Chameleon cartridge, the following inputs ; * are accepted: @@ -25,7 +25,7 @@ ; * make sure you use 'detect_chameleon();' before using. ; */ -; extern unsigned char get_chameleon_speed (void); +; unsigned char get_chameleon_speed (void); ; ;/* Get the speed of the Chameleon cartridge. ; * diff --git a/libsrc/c64/acc_scpu_speed.s b/libsrc/c64/acc_scpu_speed.s index 4bd142bbb..9f932aecd 100644 --- a/libsrc/c64/acc_scpu_speed.s +++ b/libsrc/c64/acc_scpu_speed.s @@ -2,7 +2,7 @@ ; Marco van den Heuvel, 2018-04-09 ; -; extern unsigned char __fastcall__ set_scpu_speed (unsigned char speed); +; unsigned char __fastcall__ set_scpu_speed (unsigned char speed); ; ;/* Set the speed of the SuperCPU cartridge, using SPEED_SLOW will switch to ; * 1 Mhz mode, SPEED_20X or SPEED_FAST will switch to 20 Mhz mode. @@ -19,7 +19,7 @@ ; * make sure you use 'detect_scpu();' before using. ; */ -; extern unsigned char get_scpu_speed (void); +; unsigned char get_scpu_speed (void); ; ;/* Get the speed of the SuperCPU cartridge. ; * From 11629bcf990bcc91326f33cb668749a9fa79c9eb Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Fri, 27 Apr 2018 14:22:41 -0700 Subject: [PATCH 0672/2161] Added C65/C64DX accelerator code and documentation. --- asminc/accelerator.inc | 9 ++++ doc/c64.sgml | 3 ++ doc/funcref.sgml | 67 +++++++++++++++++++++++++++ include/accelerator.h | 37 +++++++++++++++ libsrc/c64/acc_c65_speed.s | 70 +++++++++++++++++++++++++++++ libsrc/c64/acc_detect_c65.s | 55 +++++++++++++++++++++++ testcode/lib/accelerator/Makefile | 6 ++- testcode/lib/accelerator/c65-test.c | 8 ++++ 8 files changed, 254 insertions(+), 1 deletion(-) create mode 100755 libsrc/c64/acc_c65_speed.s create mode 100755 libsrc/c64/acc_detect_c65.s create mode 100644 testcode/lib/accelerator/c65-test.c diff --git a/asminc/accelerator.inc b/asminc/accelerator.inc index 0c687b2ad..a92b65ff9 100644 --- a/asminc/accelerator.inc +++ b/asminc/accelerator.inc @@ -60,3 +60,12 @@ CHAMELEON_DISABLE_REGS = $FF CHAMELEON_CFGTUR_LIMIT_1MHZ = %00001100 CHAMELEON_CFGTUR_LIMIT_NONE = %10000000 + +; --------------------------------------------------------------------------- +; C65/C64DX in C64 mode + +C65_VICIII_KEY := $D02F +C65_VICIII_CTRL_B := $D031 + +C65_VICIII_UNLOCK_1 = $A5 +C65_VICIII_UNLOCK_2 = $96 diff --git a/doc/c64.sgml b/doc/c64.sgml index c037b1e0e..800314fec 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -177,14 +177,17 @@ url="funcref.html" name="function reference"> for declaration and usage. <itemize> <item>detect_c128 <item>detect_c64dtv +<item>detect_c65 <item>detect_chameleon <item>detect_scpu <item>get_c128_speed <item>get_c64dtv_speed +<item>get_c65_speed <item>get_chameleon_speed <item>get_scpu_speed <item>set_c128_speed <item>set_c64dtv_speed +<item>set_c65_speed <item>set_chameleon_speed <item>set_scpu_speed </itemize> diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 09ee27e4a..edca7745e 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -70,14 +70,17 @@ function. <itemize> <item><ref id="detect_c128" name="detect_c128"> <item><ref id="detect_c64dtv" name="detect_c64dtv"> +<item><ref id="detect_c65" name="detect_c65"> <item><ref id="detect_chameleon" name="detect_chameleon"> <item><ref id="detect_scpu" name="detect_scpu"> <item><ref id="get_c128_speed" name="get_c128_speed"> <item><ref id="get_c64dtv_speed" name="get_c64dtv_speed"> +<item><ref id="get_c65_speed" name="get_c65_speed"> <item><ref id="get_chameleon_speed" name="get_chameleon_speed"> <item><ref id="get_scpu_speed" name="get_scpu_speed"> <item><ref id="set_c128_speed" name="set_c128_speed"> <item><ref id="set_c64dtv_speed" name="set_c64dtv_speed"> +<item><ref id="set_c65_speed" name="set_c65_speed"> <item><ref id="set_chameleon_speed" name="set_chameleon_speed"> <item><ref id="set_scpu_speed" name="set_scpu_speed"> </itemize> @@ -2969,6 +2972,26 @@ used in presence of a prototype. </quote> +<sect1>detect_c65<label id="detect_c65"><p> + +<quote> +<descrip> +<tag/Function/Check for the presence of a C65/C64DX in C64 mode. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char detect_c65 (void);/ +<tag/Description/The function returns a 1 if a C65/C64DX in C64 mode has been detected. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="get_c65_speed" name="get_c65_speed">, +<ref id="set_c65_speed" name="set_c65_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>detect_chameleon<label id="detect_chameleon"><p> <quote> @@ -3592,6 +3615,28 @@ header files define constants that can be used to check the return code. </quote> +<sect1>get_c65_speed<label id="get_c65_speed"><p> + +<quote> +<descrip> +<tag/Function/Get the current speed of the C65/C64DX in C64 mode. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char get_c65_speed (void);/ +<tag/Description/The function returns the current speed of the C65/C64DX in C64 mode. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +<item>The function does not check for the presence of a C65/C64DX in C64 mode. +<item>See the accelerator.h header for the speed definitions. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="detect_c65" name="detect_c65">, +<ref id="set_c65_speed" name="set_c65_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>get_chameleon_speed<label id="get_chameleon_speed"><p> <quote> @@ -6231,6 +6276,28 @@ clean-up when exitting the program. </quote> +<sect1>set_c65_speed<label id="set_c65_speed"><p> + +<quote> +<descrip> +<tag/Function/Set the current speed of the C65/C64DX in C64 mode. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char __fastcall__ set_c65_speed (unsigned char speed);/ +<tag/Description/The function returns the speed after trying to set the speed of the C65/C64DX in C64 mode. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +<item>The function does not check for the presence of a C65/C64DX in C64 mode. +<item>See the accelerator.h header for the speed definitions. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="detect_c65" name="detect_c65">, +<ref id="get_c65_speed" name="get_c65_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>set_chameleon_speed<label id="set_chameleon_speed"><p> <quote> diff --git a/include/accelerator.h b/include/accelerator.h index d29b73467..a5e6dbb28 100644 --- a/include/accelerator.h +++ b/include/accelerator.h @@ -226,6 +226,43 @@ unsigned char detect_chameleon (void); * 0x01 : C64 Chameleon cartridge present */ + +/* C65/C64DX in C64 mode */ + +unsigned char __fastcall__ set_c65_speed (unsigned char speed); + +/* Set the speed of the C65/C64DX CPU, using SPEED_SLOW will switch to + * 1 Mhz mode, SPEED_3X or SPEED_FAST will switch to 3.5 Mhz (fast) mode. + * + * Note that any value higher or equal to SPEED_3X will switch to fast mode. + * + * This function will return the actual speed the CPU is at after trying + * to set the requested speed, to my knowledge the switching should not fail. + * + * This function does not check for the presence of a C65/C64DX in C64 mode, + * make sure you use 'detect_c65();' before using. + */ + +unsigned char get_c65_speed (void); + +/* Get the speed of the C65/C64DX CPU. + * + * Possible return values: + * SPEED_SLOW : Slow mode + * SPEED_3X : Fast mode + * + * This function does not check for the presence of a C65/C64DX in C64 mode, + * make sure you use 'detect_c65();' before using. + */ + +unsigned char detect_c65 (void); + +/* Check for the presence of a C65/C64DX in C64 mode. + * + * Possible return values: + * 0x00 : C65/C64DX in C64 mode not present + * 0x01 : C65/C64DX in C64 mode present + */ /* End of accelerator.h */ #endif diff --git a/libsrc/c64/acc_c65_speed.s b/libsrc/c64/acc_c65_speed.s new file mode 100755 index 000000000..94fa50e91 --- /dev/null +++ b/libsrc/c64/acc_c65_speed.s @@ -0,0 +1,70 @@ +; +; Marco van den Heuvel, 2018-04-27 +; + +; unsigned char __fastcall__ set_c65_speed (unsigned char speed); +; +;/* Set the speed of the C65 CPU, using SPEED_SLOW will switch to +; * 1 Mhz mode, SPEED_3X or SPEED_FAST will switch to 3.5 Mhz (fast) mode. +; * +; * Note that any value higher or equal to SPEED_3X will switch to fast mode. +; * +; * This function will return the actual speed the CPU is at after trying +; * to set the requested speed, to my knowledge the switching should not fail. +; * +; * This function does not check for the presence of a C65/C64DX in C64 mode, +; * make sure you use 'detect_c65();' before using. +; */ + +; unsigned char get_c65_speed (void); +; +;/* Get the speed of the C65 CPU. +; * +; * Possible return values: +; * SPEED_SLOW : 1 Mhz mode +; * SPEED_3X : 3.5 Mhz mode +; * +; * This function does not check for the presence of a C65/C64DX in C64 mode, +; * make sure you use 'detect_c65();' before using. +; */ + + .export _set_c65_speed + .export _get_c65_speed + + .include "accelerator.inc" + +_set_c65_speed: + tay + jsr activate_new_vic_mode + cpy #SPEED_3X + bcs high_speed +low_speed: + and #$BF +store_speed: + sta C65_VICIII_CTRL_B + lda C65_VICIII_CTRL_B + jmp return_c65_speed + +high_speed: + ora #$40 + bne store_speed + +_get_c65_speed: + jsr activate_new_vic_mode +return_c65_speed: + sta C65_VICIII_KEY + and #$40 + beq speed_is_slow + lda #SPEED_3X + .byte $2C +speed_is_slow: + ldx #$00 + rts + +activate_new_vic_mode: + lda #C65_VICIII_UNLOCK_1 + sta C65_VICIII_KEY + lda #C65_VICIII_UNLOCK_2 + sta C65_VICIII_KEY + lda C65_VICIII_CTRL_B + rts diff --git a/libsrc/c64/acc_detect_c65.s b/libsrc/c64/acc_detect_c65.s new file mode 100755 index 000000000..8e9f9b9ec --- /dev/null +++ b/libsrc/c64/acc_detect_c65.s @@ -0,0 +1,55 @@ +; +; Marco van den Heuvel, 2018-04-27 +; + +; unsigned char detect_c65 (void); +; +;/* Check for the presence of a C65/C64DX in C64 mode. +; * +; * Possible return values: +; * 0x00 : C65/C64DX in C64 mode not present +; * 0x01 : C65/C64DX in C64 mode present +; */ + + .export _detect_c65 + + .include "accelerator.inc" + +_detect_c65: + ldy $D000 + +; Make sure the CPU is not a 65816 + clc + .byte $E2,$01 ; NOP #$01 on 6510 and 65(S)C02, LDA $(01,S),Y on 65CE02 and 4510, SEP #$01 on 65816 + lda #$00 + tax + bcs not_found ; carry will be set on 65816 + +; Make sure the CPU is not a 6510 + .byte $1A ; NOP on 6510, INA on 65(S)C(E)02 + beq not_found + txa + +; Make sure the CPU is a 65CE02/4510 + .byte $A3,$A3 ; NOP NOP on 65(S)C02, LDZ #$A3 on 65CE02 and 4510 + .byte $6B ; NOP on 65(S)C02, TZA on 65CE02 and 4510 + cmp #$A3 + bne not_found + +; Switch to VICIII mode and check if $D040 is a mirror of $D000 + ldy #C65_VICIII_UNLOCK_1 + sty C65_VICIII_KEY + ldy #C65_VICIII_UNLOCK_2 + sty C65_VICIII_KEY + cpy $D040 + bne found + inc $D000 + cpy $D040 + beq not_found + +found: + lda #$01 +not_found: + sty $D000 + sta C65_VICIII_KEY + rts diff --git a/testcode/lib/accelerator/Makefile b/testcode/lib/accelerator/Makefile index e9bd61881..9ff4d96b4 100644 --- a/testcode/lib/accelerator/Makefile +++ b/testcode/lib/accelerator/Makefile @@ -1,7 +1,8 @@ CL ?= cl65 all: c64-scpu-test.prg c128-scpu-test.prg c64dtv-test.prg \ - c64-c128-test.prg c128-test.prg chameleon-test.prg + c64-c128-test.prg c128-test.prg chameleon-test.prg \ + c65-test.prg c64-scpu-test.prg: c64-c128-scpu-test.c $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg @@ -20,3 +21,6 @@ c128-test.prg: c64-c128-test.c chameleon-test.prg: chameleon-test.c $(CL) -t c64 chameleon-test.c -o chameleon-test.prg + +c65-test.prg: c65-test.c + $(CL) -t c64 c65-test.c -o c65-test.prg diff --git a/testcode/lib/accelerator/c65-test.c b/testcode/lib/accelerator/c65-test.c new file mode 100644 index 000000000..02e322625 --- /dev/null +++ b/testcode/lib/accelerator/c65-test.c @@ -0,0 +1,8 @@ +/* C65/C64DX in C64 mode accelerator test code. */ + +#define ACC_DETECT detect_c65 +#define ACC_GET_SPEED get_c65_speed +#define ACC_SET_SPEED set_c65_speed +#define ACC_NAME "C65" + +#include "turbo-test.c" From a012fab090a1ad681094ba23867a444eb603cc98 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Sat, 28 Apr 2018 13:25:16 -0700 Subject: [PATCH 0673/2161] Added a comment to make the situation more clear. --- libsrc/c64/acc_c65_speed.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/c64/acc_c65_speed.s b/libsrc/c64/acc_c65_speed.s index 94fa50e91..1c218f0b5 100755 --- a/libsrc/c64/acc_c65_speed.s +++ b/libsrc/c64/acc_c65_speed.s @@ -54,7 +54,7 @@ _get_c65_speed: return_c65_speed: sta C65_VICIII_KEY and #$40 - beq speed_is_slow + beq speed_is_slow ; when this branch is taken then register A is already set to SPEED_SLOW lda #SPEED_3X .byte $2C speed_is_slow: From d0088fbc0fa99732c7d34c293c2d454b3b69f22e Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Sat, 28 Apr 2018 13:26:20 -0700 Subject: [PATCH 0674/2161] Fixed a wrong branch. --- libsrc/c64/acc_detect_c65.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/c64/acc_detect_c65.s b/libsrc/c64/acc_detect_c65.s index 8e9f9b9ec..6d8af3c01 100755 --- a/libsrc/c64/acc_detect_c65.s +++ b/libsrc/c64/acc_detect_c65.s @@ -45,7 +45,7 @@ _detect_c65: bne found inc $D000 cpy $D040 - beq not_found + bne not_found found: lda #$01 From a482b54ed72e4c194fed57631266ca75b8aadc48 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 29 Apr 2018 13:50:09 +0200 Subject: [PATCH 0675/2161] Removed extern keyword from function prototype. --- include/accelerator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/accelerator.h b/include/accelerator.h index d29b73467..d25195455 100644 --- a/include/accelerator.h +++ b/include/accelerator.h @@ -60,7 +60,7 @@ /* C64/C128 SuperCPU cartridge */ -extern unsigned char __fastcall__ set_scpu_speed (unsigned char speed); +unsigned char __fastcall__ set_scpu_speed (unsigned char speed); /* Set the speed of the SuperCPU cartridge, using SPEED_SLOW will switch to * 1 Mhz mode, SPEED_20X or SPEED_FAST will switch to 20 Mhz mode. From 63cad26656bb83d4269c53a642d9f8b8187760ae Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Sun, 29 Apr 2018 12:12:13 -0700 Subject: [PATCH 0676/2161] Merge branch 'master', remote-tracking branch 'origin' From 5b4929ef98e2a6ba28ab4e6528037a9ad5d14fed Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Sun, 29 Apr 2018 12:13:52 -0700 Subject: [PATCH 0677/2161] Removed obsolete bit opcode. --- libsrc/c64/acc_c65_speed.s | 1 - 1 file changed, 1 deletion(-) diff --git a/libsrc/c64/acc_c65_speed.s b/libsrc/c64/acc_c65_speed.s index 1c218f0b5..92f2bac06 100755 --- a/libsrc/c64/acc_c65_speed.s +++ b/libsrc/c64/acc_c65_speed.s @@ -56,7 +56,6 @@ return_c65_speed: and #$40 beq speed_is_slow ; when this branch is taken then register A is already set to SPEED_SLOW lda #SPEED_3X - .byte $2C speed_is_slow: ldx #$00 rts From ad7b339c449bb680e58ba240d37db8581015a60c Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Mon, 30 Apr 2018 14:30:35 -0700 Subject: [PATCH 0678/2161] Added C64 Turbo Master accelerator code and documentation. --- asminc/accelerator.inc | 9 ++++ doc/c64.sgml | 3 ++ doc/funcref.sgml | 67 +++++++++++++++++++++++++++++ include/accelerator.h | 41 ++++++++++++++++++ libsrc/c64/acc_detect_turbomaster.s | 47 ++++++++++++++++++++ libsrc/c64/acc_turbomaster_speed.s | 63 +++++++++++++++++++++++++++ testcode/lib/accelerator/Makefile | 5 ++- 7 files changed, 234 insertions(+), 1 deletion(-) create mode 100755 libsrc/c64/acc_detect_turbomaster.s create mode 100755 libsrc/c64/acc_turbomaster_speed.s diff --git a/asminc/accelerator.inc b/asminc/accelerator.inc index a92b65ff9..23a9686c7 100644 --- a/asminc/accelerator.inc +++ b/asminc/accelerator.inc @@ -69,3 +69,12 @@ C65_VICIII_CTRL_B := $D031 C65_VICIII_UNLOCK_1 = $A5 C65_VICIII_UNLOCK_2 = $96 + + +; --------------------------------------------------------------------------- +; C64 Turbo Master cartridge + +TURBOMASTER_DETECT := $BF53 + +TURBOMASTER_SPEED_REG := $00 + diff --git a/doc/c64.sgml b/doc/c64.sgml index 800314fec..98008ef41 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -180,16 +180,19 @@ url="funcref.html" name="function reference"> for declaration and usage. <item>detect_c65 <item>detect_chameleon <item>detect_scpu +<item>detect_turbomaster <item>get_c128_speed <item>get_c64dtv_speed <item>get_c65_speed <item>get_chameleon_speed <item>get_scpu_speed +<item>get_turbomaster_speed <item>set_c128_speed <item>set_c64dtv_speed <item>set_c65_speed <item>set_chameleon_speed <item>set_scpu_speed +<item>set_turbomaster_speed </itemize> diff --git a/doc/funcref.sgml b/doc/funcref.sgml index edca7745e..946b88159 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -73,16 +73,19 @@ function. <item><ref id="detect_c65" name="detect_c65"> <item><ref id="detect_chameleon" name="detect_chameleon"> <item><ref id="detect_scpu" name="detect_scpu"> +<item><ref id="detect_turbomaster" name="detect_turbomaster"> <item><ref id="get_c128_speed" name="get_c128_speed"> <item><ref id="get_c64dtv_speed" name="get_c64dtv_speed"> <item><ref id="get_c65_speed" name="get_c65_speed"> <item><ref id="get_chameleon_speed" name="get_chameleon_speed"> <item><ref id="get_scpu_speed" name="get_scpu_speed"> +<item><ref id="get_turbomaster_speed" name="get_turbomaster_speed"> <item><ref id="set_c128_speed" name="set_c128_speed"> <item><ref id="set_c64dtv_speed" name="set_c64dtv_speed"> <item><ref id="set_c65_speed" name="set_c65_speed"> <item><ref id="set_chameleon_speed" name="set_chameleon_speed"> <item><ref id="set_scpu_speed" name="set_scpu_speed"> +<item><ref id="set_turbomaster_speed" name="set_turbomaster_speed"> </itemize> @@ -3032,6 +3035,26 @@ used in presence of a prototype. </quote> +<sect1>detect_turbomaster<label id="detect_turbomaster"><p> + +<quote> +<descrip> +<tag/Function/Check for the presence of the C64 Turbo Master cartridge. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char detect_turbomaster (void);/ +<tag/Description/The function returns a 1 if a C64 Turbo Master cartridge has been detected. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="get_turbomaster_speed" name="get_turbomaster_speed">, +<ref id="set_turbomaster_speed" name="set_turbomaster_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>div<label id="div"><p> <quote> @@ -3659,6 +3682,28 @@ header files define constants that can be used to check the return code. </quote> +<sect1>get_turbomaster_speed<label id="get_turbomaster_speed"><p> + +<quote> +<descrip> +<tag/Function/Get the current speed of the C64 Turbo Master cartridge. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char get_turbomaster_speed (void);/ +<tag/Description/The function returns the current speed of the C64 Turbo Master cartridge. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +<item>The function does not check for the presence of the C64 Turbo master cartridge. +<item>See the accelerator.h header for the speed definitions. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="detect_turbomaster" name="detect_turbomaster">, +<ref id="set_turbomaster_speed" name="set_turbomaster_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>get_scpu_speed<label id="get_scpu_speed"><p> <quote> @@ -6320,6 +6365,28 @@ clean-up when exitting the program. </quote> +<sect1>set_turbomaster_speed<label id="set_turbomaster_speed"><p> + +<quote> +<descrip> +<tag/Function/Set the current speed of the C64 Turbo Master cartridge. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char __fastcall__ set_turbomaster_speed (unsigned char speed);/ +<tag/Description/The function returns the speed after trying to set the speed of the C64 Turbo Master cartridge. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +<item>The function does not check for the presence of the C64 Turbo Master cartridge. +<item>See the accelerator.h header for the speed definitions. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="detect_turbomaster" name="detect_turbomaster">, +<ref id="get_turbomaster_speed" name="get_turbomaster_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>set_scpu_speed<label id="set_scpu_speed"><p> <quote> diff --git a/include/accelerator.h b/include/accelerator.h index 50ff5c35e..fdd2ebaf7 100644 --- a/include/accelerator.h +++ b/include/accelerator.h @@ -263,6 +263,47 @@ unsigned char detect_c65 (void); * 0x00 : C65/C64DX in C64 mode not present * 0x01 : C65/C64DX in C64 mode present */ + + +/* C64 Turbo Master cartridge */ + +unsigned char __fastcall__ set_turbomaster_speed (unsigned char speed); + +/* Set the speed of the Turbo Master cartridge, using SPEED_SLOW will switch to + * 1 Mhz mode, SPEED_4X or SPEED_FAST will switch to 4 Mhz mode. + * + * Note that any value higher or equal to SPEED_4X will switch to 4 Mhz mode, + * any value lower than SPEED_4X will switch to 1 Mhz mode. + * + * This function will return the actual speed the CPU is at after trying + * to set the requested speed, if the speed is different it might indicate + * that the hardware switch has locked the speed. + * + * This function does not check for the presence of a Turbo Master cartridge, + * make sure you use 'detect_turbomaster();' before using. + */ + +unsigned char get_turbomaster_speed (void); + +/* Get the speed of the Turbo Master cartridge. + * + * Possible return values: + * SPEED_SLOW : 1 Mhz mode + * SPEED_4X : 4 Mhz mode + * + * This function does not check for the presence of a Turbo Master cartridge, + * make sure you use 'detect_turbomaster();' before using. + */ + +unsigned char detect_turbomaster (void); + +/* Check for the presence of a C64 Turbo Master cartridge. + * + * Possible return values: + * 0x00 : C64 Turbo Master cartridge not present + * 0x01 : C64 Turbo Master cartridge present + */ + /* End of accelerator.h */ #endif diff --git a/libsrc/c64/acc_detect_turbomaster.s b/libsrc/c64/acc_detect_turbomaster.s new file mode 100755 index 000000000..0af9c3af7 --- /dev/null +++ b/libsrc/c64/acc_detect_turbomaster.s @@ -0,0 +1,47 @@ +; +; Marco van den Heuvel, 2018-04-30 +; + +; unsigned char detect_turbomaster (void); +; +;/* Check for the presence of a Turbo Master cartridge. +; * +; * Possible return values: +; * 0x00 : TurboMaster cartridge not present +; * 0x01 : TurboMaster cartridge present +; */ + + .export _detect_turbomaster + + .include "accelerator.inc" + +_detect_turbomaster: + lda #$00 + tax + +; Make sure the current CPU is not a 6510 + .byte $1A ; NOP on 8502, INA on 65(S)C(E)02, 4510 and 65816 + beq not_found + +; Make sure the current CPU is not a 65816 + clc + .byte $E2,$01 ; NOP #$01 on 65(S)C02, LDA $(01,S),Y on 65CE02 and 4510, SEP #$01 on 65816 + bcs not_found ; carry will be set on 65816 + +; Make sure the current CPU is not a 65CE02/4510 + .byte $A3,$A3 ; NOP NOP on 65(S)C02 and LDZ #$00 on 65CE02 and 4510 + .byte $6B ; NOP on 65(S)C02 and TZA on 65CE02 and 4510 + cmp #$A3 + beq not_found + +; Check for turbo master basic replacement + ldy TURBOMASTER_DETECT + cpy #$A2 + bne not_found +found: + lda #$01 + .byte $24 +not_found: + txa + rts + diff --git a/libsrc/c64/acc_turbomaster_speed.s b/libsrc/c64/acc_turbomaster_speed.s new file mode 100755 index 000000000..679003b03 --- /dev/null +++ b/libsrc/c64/acc_turbomaster_speed.s @@ -0,0 +1,63 @@ +; +; Marco van den Heuvel, 2018-04-30 +; + +; unsigned char __fastcall__ set_turbomaster_speed (unsigned char speed); +; +;/* Set the speed of the Turbo Master cartridge, using SPEED_SLOW will switch to +; * 1 Mhz mode, SPEED_4X or SPEED_FAST will switch to 4 Mhz mode. +; * +; * Note that any value higher or equal to SPEED_4X will switch to 4 Mhz mode, +; * any value lower than SPEED_4X will switch to 1 Mhz mode. +; * +; * This function will return the actual speed the CPU is at after trying +; * to set the requested speed, if the speed is different it might indicate +; * that the hardware switch has locked the speed. +; * +; * This function does not check for the presence of a Turbo Master cartridge, +; * make sure you use 'detect_turbomaster();' before using. +; */ + +; unsigned char get_turbomaster_speed (void); +; +;/* Get the speed of the Turbo Master cartridge. +; * +; * Possible return values: +; * SPEED_SLOW : 1 Mhz mode +; * SPEED_4X : 4 Mhz mode +; * +; * This function does not check for the presence of a Turbo Master cartridge, +; * make sure you use 'detect_turbomaster();' before using. +; */ + + .export _set_turbomaster_speed + .export _get_turbomaster_speed + + .include "accelerator.inc" + +_set_turbomaster_speed: + tay + lda TURBOMASTER_SPEED_REG + cpy #SPEED_4X + bcs high_speed +low_speed: + and #$7F +store_speed: + sta TURBOMASTER_SPEED_REG + jmp _get_turbomaster_speed + +high_speed: + ora #$80 + bne store_speed + + +_get_turbomaster_speed: + ldx #$00 + lda TURBOMASTER_SPEED_REG + and #$80 + beq is_slow_speed +is_high_speed: + lda #SPEED_4X +is_slow_speed: + rts + diff --git a/testcode/lib/accelerator/Makefile b/testcode/lib/accelerator/Makefile index 9ff4d96b4..6b90a9556 100644 --- a/testcode/lib/accelerator/Makefile +++ b/testcode/lib/accelerator/Makefile @@ -2,7 +2,7 @@ CL ?= cl65 all: c64-scpu-test.prg c128-scpu-test.prg c64dtv-test.prg \ c64-c128-test.prg c128-test.prg chameleon-test.prg \ - c65-test.prg + c65-test.prg turbomaster-test.prg c64-scpu-test.prg: c64-c128-scpu-test.c $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg @@ -24,3 +24,6 @@ chameleon-test.prg: chameleon-test.c c65-test.prg: c65-test.c $(CL) -t c64 c65-test.c -o c65-test.prg + +turbomaster-test.prg: turbomaster-test.c + $(CL) -t c64 turbomaster-test.c -o turbomaster-test.prg From b12678e90d66e5c371f84947dd445ab2ae342699 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Mon, 30 Apr 2018 14:34:46 -0700 Subject: [PATCH 0679/2161] Fixed a typo. --- doc/funcref.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 946b88159..c23ffb72c 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -3692,7 +3692,7 @@ header files define constants that can be used to check the return code. <tag/Description/The function returns the current speed of the C64 Turbo Master cartridge. <tag/Notes/<itemize> <item>The function is specific to the C64. -<item>The function does not check for the presence of the C64 Turbo master cartridge. +<item>The function does not check for the presence of the C64 Turbo Master cartridge. <item>See the accelerator.h header for the speed definitions. </itemize> <tag/Availability/cc65 (not all platforms) From 21e6f25e700d70f9fea4ab0bfea2e6a858c43a62 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Tue, 1 May 2018 14:44:23 -0700 Subject: [PATCH 0680/2161] Added missing file. --- testcode/lib/accelerator/turbomaster-test.c | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100755 testcode/lib/accelerator/turbomaster-test.c diff --git a/testcode/lib/accelerator/turbomaster-test.c b/testcode/lib/accelerator/turbomaster-test.c new file mode 100755 index 000000000..207465efa --- /dev/null +++ b/testcode/lib/accelerator/turbomaster-test.c @@ -0,0 +1,8 @@ +/* C64 Turbo Master accelerator test code. */ + +#define ACC_DETECT detect_turbomaster +#define ACC_GET_SPEED get_turbomaster_speed +#define ACC_SET_SPEED set_turbomaster_speed +#define ACC_NAME "Turbo Master cartridge" + +#include "turbo-test.c" From b1c3daca3a847741e3fc0226e19ca92a502aa03e Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Tue, 1 May 2018 14:45:51 -0700 Subject: [PATCH 0681/2161] Fixed the order of some functions. --- doc/funcref.sgml | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index c23ffb72c..88581c361 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -3682,28 +3682,6 @@ header files define constants that can be used to check the return code. </quote> -<sect1>get_turbomaster_speed<label id="get_turbomaster_speed"><p> - -<quote> -<descrip> -<tag/Function/Get the current speed of the C64 Turbo Master cartridge. -<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ -<tag/Declaration/<tt/unsigned char get_turbomaster_speed (void);/ -<tag/Description/The function returns the current speed of the C64 Turbo Master cartridge. -<tag/Notes/<itemize> -<item>The function is specific to the C64. -<item>The function does not check for the presence of the C64 Turbo Master cartridge. -<item>See the accelerator.h header for the speed definitions. -</itemize> -<tag/Availability/cc65 (not all platforms) -<tag/See also/ -<ref id="detect_turbomaster" name="detect_turbomaster">, -<ref id="set_turbomaster_speed" name="set_turbomaster_speed">, -<tag/Example/None. -</descrip> -</quote> - - <sect1>get_scpu_speed<label id="get_scpu_speed"><p> <quote> @@ -3726,6 +3704,27 @@ header files define constants that can be used to check the return code. </quote> +<sect1>get_turbomaster_speed<label id="get_turbomaster_speed"><p> + +<quote> +<descrip> +<tag/Function/Get the current speed of the C64 Turbo Master cartridge. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char get_turbomaster_speed (void);/ +<tag/Description/The function returns the current speed of the C64 Turbo Master cartridge. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +<item>The function does not check for the presence of the C64 Turbo Master cartridge. +<item>See the accelerator.h header for the speed definitions. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="detect_turbomaster" name="detect_turbomaster">, +<ref id="set_turbomaster_speed" name="set_turbomaster_speed">, +<tag/Example/None. +</descrip> +</quote> + <sect1>getcpu<label id="getcpu"><p> <quote> From e88ac62d06e228739686df4b710f00070ce4e3fb Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Tue, 1 May 2018 14:46:57 -0700 Subject: [PATCH 0682/2161] Optimized the code a bit, thanks to Greg for the suggestions/comments. --- libsrc/c64/acc_detect_turbomaster.s | 6 ++---- libsrc/c64/acc_turbomaster_speed.s | 11 ++--------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/libsrc/c64/acc_detect_turbomaster.s b/libsrc/c64/acc_detect_turbomaster.s index 0af9c3af7..2f8fb2294 100755 --- a/libsrc/c64/acc_detect_turbomaster.s +++ b/libsrc/c64/acc_detect_turbomaster.s @@ -37,11 +37,9 @@ _detect_turbomaster: ; Check for turbo master basic replacement ldy TURBOMASTER_DETECT cpy #$A2 - bne not_found -found: - lda #$01 - .byte $24 + beq found not_found: txa +found: rts diff --git a/libsrc/c64/acc_turbomaster_speed.s b/libsrc/c64/acc_turbomaster_speed.s index 679003b03..7ef6b0540 100755 --- a/libsrc/c64/acc_turbomaster_speed.s +++ b/libsrc/c64/acc_turbomaster_speed.s @@ -38,18 +38,11 @@ _set_turbomaster_speed: tay lda TURBOMASTER_SPEED_REG + asl cpy #SPEED_4X - bcs high_speed -low_speed: - and #$7F + ror store_speed: sta TURBOMASTER_SPEED_REG - jmp _get_turbomaster_speed - -high_speed: - ora #$80 - bne store_speed - _get_turbomaster_speed: ldx #$00 From 04675fca2a181270fc36d9f9c204d4064c5f2dfd Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Wed, 2 May 2018 11:23:43 -0700 Subject: [PATCH 0683/2161] Order fix. --- doc/funcref.sgml | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 88581c361..f10379c93 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -6364,28 +6364,6 @@ clean-up when exitting the program. </quote> -<sect1>set_turbomaster_speed<label id="set_turbomaster_speed"><p> - -<quote> -<descrip> -<tag/Function/Set the current speed of the C64 Turbo Master cartridge. -<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ -<tag/Declaration/<tt/unsigned char __fastcall__ set_turbomaster_speed (unsigned char speed);/ -<tag/Description/The function returns the speed after trying to set the speed of the C64 Turbo Master cartridge. -<tag/Notes/<itemize> -<item>The function is specific to the C64. -<item>The function does not check for the presence of the C64 Turbo Master cartridge. -<item>See the accelerator.h header for the speed definitions. -</itemize> -<tag/Availability/cc65 (not all platforms) -<tag/See also/ -<ref id="detect_turbomaster" name="detect_turbomaster">, -<ref id="get_turbomaster_speed" name="get_turbomaster_speed">, -<tag/Example/None. -</descrip> -</quote> - - <sect1>set_scpu_speed<label id="set_scpu_speed"><p> <quote> @@ -6408,6 +6386,28 @@ clean-up when exitting the program. </quote> +<sect1>set_turbomaster_speed<label id="set_turbomaster_speed"><p> + +<quote> +<descrip> +<tag/Function/Set the current speed of the C64 Turbo Master cartridge. +<tag/Header/<tt/<ref id="accelerator.h" name="accelerator.h">/ +<tag/Declaration/<tt/unsigned char __fastcall__ set_turbomaster_speed (unsigned char speed);/ +<tag/Description/The function returns the speed after trying to set the speed of the C64 Turbo Master cartridge. +<tag/Notes/<itemize> +<item>The function is specific to the C64. +<item>The function does not check for the presence of the C64 Turbo Master cartridge. +<item>See the accelerator.h header for the speed definitions. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/See also/ +<ref id="detect_turbomaster" name="detect_turbomaster">, +<ref id="get_turbomaster_speed" name="get_turbomaster_speed">, +<tag/Example/None. +</descrip> +</quote> + + <sect1>setjmp<label id="setjmp"><p> <quote> From cdebf6baa754af0e446a2dd5242ec71e783c1491 Mon Sep 17 00:00:00 2001 From: Marco van den Heuvel <blackystardust68@yahoo.com> Date: Thu, 3 May 2018 09:11:20 -0700 Subject: [PATCH 0684/2161] Harmonized the comments (as in added 1 space) ;) --- libsrc/c64/acc_detect_turbomaster.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/c64/acc_detect_turbomaster.s b/libsrc/c64/acc_detect_turbomaster.s index 2f8fb2294..431985a47 100755 --- a/libsrc/c64/acc_detect_turbomaster.s +++ b/libsrc/c64/acc_detect_turbomaster.s @@ -20,7 +20,7 @@ _detect_turbomaster: tax ; Make sure the current CPU is not a 6510 - .byte $1A ; NOP on 8502, INA on 65(S)C(E)02, 4510 and 65816 + .byte $1A ; NOP on 8502, INA on 65(S)C(E)02, 4510 and 65816 beq not_found ; Make sure the current CPU is not a 65816 From cdce753a09ea815d55936b78e6a1d57849a9a175 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 9 May 2018 23:31:42 +0000 Subject: [PATCH 0685/2161] NMI friendly c64-hi Don't clear all vectors, see #639. --- libsrc/c64/tgi/c64-hi.s | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libsrc/c64/tgi/c64-hi.s b/libsrc/c64/tgi/c64-hi.s index aeb334404..fd7a25478 100644 --- a/libsrc/c64/tgi/c64-hi.s +++ b/libsrc/c64/tgi/c64-hi.s @@ -131,7 +131,7 @@ VBASE := $E000 ; Video memory base address ; INSTALL: - rts +; rts ; fall through ; ------------------------------------------------------------------------ @@ -272,9 +272,12 @@ CLEAR: ldy #$00 sta VBASE+$1C00,y sta VBASE+$1D00,y sta VBASE+$1E00,y - sta VBASE+$1F00,y iny bne @L1 +@L2: sta VBASE+$1F00,y + iny + cpy #$40 + bne @L2 rts ; ------------------------------------------------------------------------ @@ -285,7 +288,7 @@ CLEAR: ldy #$00 ; SETVIEWPAGE: - rts +; rts ; fall through ; ------------------------------------------------------------------------ ; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n). From b81a04f157975ac117866473f5cecdf7d6015801 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 9 May 2018 23:52:52 +0000 Subject: [PATCH 0686/2161] Update c64-hi.s --- libsrc/c64/tgi/c64-hi.s | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libsrc/c64/tgi/c64-hi.s b/libsrc/c64/tgi/c64-hi.s index fd7a25478..ad453fd5a 100644 --- a/libsrc/c64/tgi/c64-hi.s +++ b/libsrc/c64/tgi/c64-hi.s @@ -272,12 +272,9 @@ CLEAR: ldy #$00 sta VBASE+$1C00,y sta VBASE+$1D00,y sta VBASE+$1E00,y + sta VBASE+$1F40,y ; preserve vectors iny bne @L1 -@L2: sta VBASE+$1F00,y - iny - cpy #$40 - bne @L2 rts ; ------------------------------------------------------------------------ From b449ded1764c134ed1a103adf5ec4f5ba1486814 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 9 May 2018 23:56:35 +0000 Subject: [PATCH 0687/2161] Update c64-hi.s --- libsrc/c64/tgi/c64-hi.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/c64/tgi/c64-hi.s b/libsrc/c64/tgi/c64-hi.s index ad453fd5a..e2c3bca9f 100644 --- a/libsrc/c64/tgi/c64-hi.s +++ b/libsrc/c64/tgi/c64-hi.s @@ -272,7 +272,7 @@ CLEAR: ldy #$00 sta VBASE+$1C00,y sta VBASE+$1D00,y sta VBASE+$1E00,y - sta VBASE+$1F40,y ; preserve vectors + sta VBASE+$1E40,y ; preserve vectors iny bne @L1 rts From ca31e3af1effb268d36235495a11c2580b938682 Mon Sep 17 00:00:00 2001 From: greg-king5 <greg.king5@verizon.net> Date: Sat, 12 May 2018 13:46:16 -0400 Subject: [PATCH 0688/2161] Fixed a bug that didn't preserve the accumulator's value when a simple 16-bit fetch-and-store is optimized. (#637) Fix a 16-bit fetch-and-store cc65 optimizer bug. --- src/cc65/coptstore.c | 45 +++++++++++++++++++++--------------------- test/val/assign-use1.c | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 23 deletions(-) create mode 100644 test/val/assign-use1.c diff --git a/src/cc65/coptstore.c b/src/cc65/coptstore.c index 56343c95b..b0dfe3b6d 100644 --- a/src/cc65/coptstore.c +++ b/src/cc65/coptstore.c @@ -380,48 +380,48 @@ unsigned OptStore5 (CodeSeg* S) ** sta something ** stx something-else ** -** and replace it by +** and, replace it by ** -** lda foo -** sta something ** lda bar ** sta something-else +** lda foo +** sta something ** -** if X is not used later. This replacement doesn't save any cycles or bytes, -** but it keeps the value of X, which may be reused later. +** if the new value of X is not used later. That replacement doesn't save any +** cycles or bytes; but, it keeps the old value of X, which may be reused later. */ { unsigned Changes = 0; + unsigned I = 0; /* Walk over the entries */ - unsigned I = 0; while (I < CS_GetEntryCount (S)) { - CodeEntry* L[4]; /* Get next entry */ L[0] = CS_GetEntry (S, I); /* Check for the sequence */ - if (L[0]->OPC == OP65_LDA && - !CS_RangeHasLabel (S, I+1, 3) && - CS_GetEntries (S, L+1, I+1, 3) && - L[1]->OPC == OP65_LDX && - L[2]->OPC == OP65_STA && - L[3]->OPC == OP65_STX && + if (L[0]->OPC == OP65_LDA && + !CS_RangeHasLabel (S, I+1, 3) && + CS_GetEntries (S, L+1, I+1, 3) && + L[1]->OPC == OP65_LDX && + L[2]->OPC == OP65_STA && + L[3]->OPC == OP65_STX && !RegXUsed (S, I+4)) { - CodeEntry* X; + CodeEntry* E = CS_GetEntry (S, I+1); - /* Insert the code after the sequence */ - X = NewCodeEntry (OP65_LDA, L[1]->AM, L[1]->Arg, 0, L[1]->LI); - CS_InsertEntry (S, X, I+4); - X = NewCodeEntry (OP65_STA, L[3]->AM, L[3]->Arg, 0, L[3]->LI); - CS_InsertEntry (S, X, I+5); + /* Move the high-byte code to the beginning of the sequence */ + CS_MoveEntry (S, I+1, I); + CS_MoveEntry (S, I+3, I+1); - /* Delete the old code */ - CS_DelEntry (S, I+3); - CS_DelEntry (S, I+1); + /* Change from the X register to the A register */ + CE_ReplaceOPC (E, OP65_LDA); + CE_ReplaceOPC (CS_GetEntry (S, I+1), OP65_STA); + + /* Move labels from the old first entry to the new first entry */ + CS_MoveLabels (S, CS_GetEntry (S, I+2), E); /* Remember, we had changes */ ++Changes; @@ -429,7 +429,6 @@ unsigned OptStore5 (CodeSeg* S) /* Next entry */ ++I; - } /* Return the number of changes made */ diff --git a/test/val/assign-use1.c b/test/val/assign-use1.c new file mode 100644 index 000000000..744023530 --- /dev/null +++ b/test/val/assign-use1.c @@ -0,0 +1,36 @@ +/* + !!DESCRIPTION!! Assign an int; then, do an operation that depends directly on that assignment. + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Greg King +*/ + +#include <stdio.h> + +static unsigned char failures = 0; + +static unsigned int result; +static const unsigned int buffer = 0xABCD; + +int main(void) +{ + result = buffer; + + /* Shift doesn't use high byte (X register); previous assignment should be optimized. */ + result <<= 8; + if (result != 0xCD00) { + ++failures; + printf("assign-use1: left shift is $%X, not $CD00.\n", result); + } + + result = buffer; + + /* Shift does use high byte; previous assignment shouldn't be optimized by OptStore5(). */ + result >>= 8; + if (result != 0x00AB) { + ++failures; + printf("assign-use1: right shift is $%X, not $00AB.\n", result); + } + + return failures; +} From 5ecd902fbfbf7199ca489cf6d1d7add9758c0758 Mon Sep 17 00:00:00 2001 From: Michael Kohn <mike@mikekohn.net> Date: Sun, 13 May 2018 06:31:05 -0500 Subject: [PATCH 0689/2161] The opcode for BS should be 0x0C. --- 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 53d3573a6..37217203a 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -758,7 +758,7 @@ static const struct { { "BNZ", AMSW16_BRA, 0x07, 0, PutSweet16Branch }, { "BP", AMSW16_BRA, 0x04, 0, PutSweet16Branch }, { "BR", AMSW16_BRA, 0x01, 0, PutSweet16Branch }, - { "BS", AMSW16_BRA, 0x0B, 0, PutSweet16Branch }, + { "BS", AMSW16_BRA, 0x0C, 0, PutSweet16Branch }, { "BZ", AMSW16_BRA, 0x06, 0, PutSweet16Branch }, { "CPR", AMSW16_REG, 0xD0, 0, PutSweet16 }, { "DCR", AMSW16_REG, 0xF0, 0, PutSweet16 }, From 362b6afacff5ce936531713c76010367af6db42f Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 13 May 2018 04:21:42 -0400 Subject: [PATCH 0690/2161] Made a C union declaration know the sizes of anonymous struct/union members when it determines its size. The bug was located, and the fix was written, by Francesco. --- src/cc65/declare.c | 7 +- test/val/anon-struct1.c | 111 +++++++++++++++++++++++++++++ test/val/anon-struct2.c | 152 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 268 insertions(+), 2 deletions(-) create mode 100644 test/val/anon-struct1.c create mode 100644 test/val/anon-struct2.c diff --git a/src/cc65/declare.c b/src/cc65/declare.c index a6b232905..19100781c 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -656,13 +656,16 @@ static SymEntry* ParseUnionDecl (const char* Name) /* Check for fields without a name */ if (Decl.Ident[0] == '\0') { /* In cc65 mode, we allow anonymous structs/unions within - ** a struct. + ** a union. */ if (IS_Get (&Standard) >= STD_CC65 && IsClassStruct (Decl.Type)) { /* This is an anonymous struct or union. Copy the fields ** into the current level. */ - CopyAnonStructFields (&Decl, 0); + FieldSize = CopyAnonStructFields (&Decl, 0); + if (FieldSize > UnionSize) { + UnionSize = FieldSize; + } } else { /* A non bit-field without a name is legal but useless */ diff --git a/test/val/anon-struct1.c b/test/val/anon-struct1.c new file mode 100644 index 000000000..9a737adca --- /dev/null +++ b/test/val/anon-struct1.c @@ -0,0 +1,111 @@ +/* + !!DESCRIPTION!! Make sure that structs/unions know the sizes of anonymous struct/union members + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Greg King +*/ + +/* + see https://github.com/cc65/cc65/issues/641 +*/ + +#include <stdio.h> + +static unsigned char fails = 0; + +typedef struct { + short s1; + struct { + int i1; + long l1; + char c1; + }; + char c2; +} s1_t; + +typedef struct { + short s1; + union { + int i1; + long l1; + char c1; + }; + char c2; +} s2_t; + +typedef union { + short s1; + struct { + int i1; + long l1; + char c1; + }; + char c2; +} u1_t; + +typedef union { + short s1; + union { + int i1; + long l1; + char c1; + }; + char c2; +} u2_t; + +static s1_t s1; +static s2_t s2; +static u1_t u1; +static u2_t u2; + +/* We use "variables" in the comparisons, so that we can avoid "constant +** comparison" and "Unreachable code" warnings (the second one currently +** can't be suppressed). +*/ + +static size_t const four = 4; +static size_t const seven = 7; +static size_t const ten = 10; + +int main(void) +{ + /* Check the types' sizes. */ + + if (sizeof (s1_t) != ten) { + printf("s1_t size is %u; it should be 10.\n", sizeof (s1_t)); + ++fails; + } + if (sizeof (s2_t) != seven) { + printf("s2_t size is %u; it should be 7.\n", sizeof (s2_t)); + ++fails; + } + if (sizeof (u1_t) != seven) { + printf("u1_t size is %u; it should be 7.\n", sizeof (u1_t)); + ++fails; + } + if (sizeof (u2_t) != four) { + printf("u2_t size is %u; it should be 4.\n", sizeof (u2_t)); + ++fails; + } + + /* Check the variables' sizes. */ + + if (sizeof s1 != ten) { + printf("s1 size is %u; it should be 10.\n", sizeof s1); + ++fails; + } + if (sizeof s2 != seven) { + printf("s2 size is %u; it should be 7.\n", sizeof s2); + ++fails; + } + if (sizeof u1 != seven) { + printf("u1 size is %u; it should be 7.\n", sizeof u1); + ++fails; + } + if (sizeof u2 != four) { + printf("u2 size is %u; it should be 4.\n", sizeof u2); + ++fails; + } + + return fails; +} diff --git a/test/val/anon-struct2.c b/test/val/anon-struct2.c new file mode 100644 index 000000000..bdaddc823 --- /dev/null +++ b/test/val/anon-struct2.c @@ -0,0 +1,152 @@ +/* + !!DESCRIPTION!! Make sure that the fields of anonymous structs/unions can be reached properly. + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Greg King +*/ + +#include <stddef.h> +#include <stdio.h> + +static unsigned char fails = 0; + +typedef struct { + short s1; + struct { + char c1; + int i1; + long l1; + }; + char c2; +} s1_t; + +typedef struct { + char c2; + union { + int i1; + char c1; + long l1; + }; + short s1; +} s2_t; + +typedef union { + short s1; + struct { + int i1; + long l1; + char c1; + }; + char c2; +} u1_t; + +typedef union { + short s1; + union { + long l1; + char c1; + int i1; + }; + char c2; +} u2_t; + +typedef struct { + union { + short s1; + struct { + int i1; + long l1; + char c1; + }; + char c2; + }; + short s2; +} s3_t; + +static s1_t s1; +static s2_t s2; +static u1_t u1; +static u2_t u2; + +static long l2; +static int i2; + +/* We use "variables" in the comparisons, so that we can avoid "constant +** comparison" and "Unreachable code" warnings (the second one currently +** can't be suppressed). +*/ + +static size_t const zero = 0; +static size_t const one = 1; +static size_t const three = 3; +static size_t const five = 5; +static size_t const six = 6; +static size_t const seven = 7; +static size_t const nine = 9; + +int main(void) +{ + /* Can cc65 see the names of members of anonymous structs/unions? */ + + l2 = s1.l1; + l2 = s2.l1; + l2 = u1.l1; + l2 = u2.l1; + + i2 = s1.c1; + i2 = s1.c2; + i2 = s2.c1; + i2 = s2.c2; + i2 = u1.c1; + i2 = u1.c2; + i2 = u2.c1; + i2 = u2.c2; + + /* Does cc65 use the correct offsets of + ** the members of anonymous structs/unions? + */ + + if (offsetof(s1_t, i1) != three) { + printf("The offset of s1.i1 is %u; it should be 3.\n", offsetof(s1_t, i1)); + ++fails; + } + if (offsetof(s2_t, l1) != one) { + printf("The offset of s2.l1 is %u; it should be 1.\n", offsetof(s2_t, l1)); + ++fails; + } + if (offsetof(u1_t, c1) != six) { + printf("The offset of u1.c1 is %u; it should be 6.\n", offsetof(u1_t, c1)); + ++fails; + } + if (offsetof(u2_t, i1) != zero) { + printf("The offset of u2.i1 is %u; it should be 0.\n", offsetof(u2_t, i1)); + ++fails; + } + + /* Does cc65 use the correct offset of a member + ** that's later than an anonymous struct/union? + */ + + if (offsetof(s1_t, c2) != nine) { + printf("The offset of s1.c2 is %u; it should be 9.\n", offsetof(s1_t, c2)); + ++fails; + } + if (offsetof(s2_t, s1) != five) { + printf("The offset of s2.s1 is %u; it should be 5.\n", offsetof(s2_t, s1)); + ++fails; + } + if (offsetof(u1_t, c2) != zero) { + printf("The offset of u1.c2 is %u; it should be 0.\n", offsetof(u1_t, c2)); + ++fails; + } + if (offsetof(u2_t, c2) != zero) { + printf("The offset of u2.c2 is %u; it should be 0.\n", offsetof(u2_t, c2)); + ++fails; + } + if (offsetof(s3_t, s2) != seven) { + printf("The offset of s3.s2 is %u; it should be 7.\n", offsetof(s3_t, s2)); + ++fails; + } + + return fails; +} From df79409f761e0e51ea39e2407a86537baf6b0321 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 14 May 2018 14:17:09 +0000 Subject: [PATCH 0691/2161] Update c64.sgml soft80 is NMI ready --- doc/c64.sgml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/c64.sgml b/doc/c64.sgml index 98008ef41..96260b48e 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -5,7 +5,7 @@ <title>Commodore 64-specific information for cc65 <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"><newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2017-01-18 +<date>2018-05-14 <abstract> An overview over the C64 runtime system as it is implemented for the cc65 C @@ -122,8 +122,8 @@ since the program must be loaded to the BASIC start address. <sect1>80 Columns conio driver<p> The C64 package comes with an alternative software driven 80 columns -module <tt/c64-soft80.o/ which uses the memory under I/O between $d000 -and $ffff. +module <tt/c64-soft80.o/ which uses the memory under I/O between $D000 +and $FF3F. In memory constrained situations the memory from $400 to $7FF can be made available to a program by calling <tt/_heapadd ((void *) 0x0400, 0x0400);/ From b3358c462ed4a24bf8cb2b646e46cf86d544b299 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 14 May 2018 23:10:34 +0000 Subject: [PATCH 0692/2161] Update c64.sgml Do not use last page! --- doc/c64.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/c64.sgml b/doc/c64.sgml index 96260b48e..a18ce359f 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -318,7 +318,7 @@ Note that the graphics drivers are incompatible with the bytes each. Written and contributed by Marco van den Heuvel. <tag><tt/c64-ram.emd (c64_ram_emd)/</tag> - A driver for the hidden RAM below the I/O area and kernal ROM. Supports 48 + A driver for the hidden RAM below the I/O area and kernal ROM. Supports 47 256 byte pages. Please note that this driver is incompatible with any of the graphics drivers, or the soft80 conio driver! From 472a10735835ba9fc175c50a36ff59c8e0e5f4d0 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 14 May 2018 23:22:09 +0000 Subject: [PATCH 0693/2161] Make NMI ready --- libsrc/c64/emd/c64-ram.s | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libsrc/c64/emd/c64-ram.s b/libsrc/c64/emd/c64-ram.s index f8a4a1819..b41f932e6 100644 --- a/libsrc/c64/emd/c64-ram.s +++ b/libsrc/c64/emd/c64-ram.s @@ -44,7 +44,7 @@ ; Constants BASE = $D000 -PAGES = ($10000 - BASE) / 256 +PAGES = ($FF00 - BASE) / 256 ; ------------------------------------------------------------------------ ; Data. @@ -267,5 +267,3 @@ COPYTO: sta ptr3 sta ptr1+1 ; From jmp common - - From a795a27689e0bb06773f0ee0608354bdceb19286 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 17 May 2018 11:11:40 +0200 Subject: [PATCH 0694/2161] There's no 'closeallstreams' (anymore ?). --- libsrc/cbm/open.s | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libsrc/cbm/open.s b/libsrc/cbm/open.s index 4e57f5efc..5c97aff56 100644 --- a/libsrc/cbm/open.s +++ b/libsrc/cbm/open.s @@ -2,10 +2,6 @@ ; Ullrich von Bassewitz, 16.11.2002 ; ; int open (const char* name, int flags, ...); /* May take a mode argument */ -; -; Be sure to keep the value priority of closeallfiles lower than that of -; closeallstreams (which is the high level C file I/O counterpart and must be -; called before closeallfiles). .export _open From c95ed4b8b5e3aa0313f19789333b63c6aaa2d2df Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sun, 20 May 2018 15:30:18 +0200 Subject: [PATCH 0695/2161] Added "popptr1" which is of common use to save some bytes. --- libsrc/apple2/devicedir.s | 6 ++--- libsrc/apple2/extra/iobuf-0800.s | 6 ++--- libsrc/apple2/lseek.s | 6 ++--- libsrc/apple2/rwcommon.s | 6 ++--- libsrc/atari/dio_stc.s | 6 ++--- libsrc/atari/siocall.s | 6 ++--- libsrc/atmos/read.s | 6 ++--- libsrc/atmos/write.s | 6 ++--- libsrc/cbm/c_save.s | 6 ++--- libsrc/cbm/sysrename.s | 8 +++---- libsrc/common/_swap.s | 8 +++---- libsrc/common/getcwd.s | 8 +++---- libsrc/common/longjmp.s | 8 +++---- libsrc/common/memchr.s | 9 ++++---- libsrc/common/memcmp.s | 8 +++---- libsrc/common/memcpy.s | 9 ++++---- libsrc/common/strcmp.s | 8 +++---- libsrc/common/stricmp.s | 8 +++---- libsrc/common/strncat.s | 6 ++--- libsrc/common/strncmp.s | 8 +++---- libsrc/common/strncpy.s | 6 ++--- libsrc/common/strnicmp.s | 8 +++---- libsrc/common/strpbrk.s | 8 +++---- libsrc/common/strstr.s | 8 +++---- libsrc/conio/vcprintf.s | 6 ++--- libsrc/dbg/dbgsupp.s | 6 ++--- libsrc/geos-common/drivers/fio_module.s | 6 ++--- libsrc/pce/memcpy.s | 8 +++---- libsrc/runtime/popptr1.s | 29 +++++++++++++++++++++++++ libsrc/runtime/steaxspi.s | 6 ++--- libsrc/telestrat/write.s | 6 ++--- libsrc/tgi/tgi_bar.s | 6 ++--- libsrc/tgi/tgi_popxy.s | 7 ++---- libsrc/zlib/adler32.s | 6 ++--- libsrc/zlib/crc32.s | 6 ++--- 35 files changed, 113 insertions(+), 151 deletions(-) create mode 100644 libsrc/runtime/popptr1.s diff --git a/libsrc/apple2/devicedir.s b/libsrc/apple2/devicedir.s index dea2ba8c5..de6bad5f2 100644 --- a/libsrc/apple2/devicedir.s +++ b/libsrc/apple2/devicedir.s @@ -5,7 +5,7 @@ ; .export _getdevicedir - .import popax, popa + .import popptr1, popa .include "zeropage.inc" .include "errno.inc" @@ -17,9 +17,7 @@ _getdevicedir: stx ptr2+1 ; Save buf - jsr popax - sta ptr1 - stx ptr1+1 + jsr popptr1 ; Set buf sta mliparam + MLI::ON_LINE::DATA_BUFFER diff --git a/libsrc/apple2/extra/iobuf-0800.s b/libsrc/apple2/extra/iobuf-0800.s index 0ad7a751f..c7a9dae2e 100644 --- a/libsrc/apple2/extra/iobuf-0800.s +++ b/libsrc/apple2/extra/iobuf-0800.s @@ -8,7 +8,7 @@ .constructor initiobuf .export iobuf_alloc, iobuf_free .import __STARTUP_RUN__ - .import incsp2, popax + .import incsp2, popptr1 .include "zeropage.inc" .include "errno.inc" @@ -41,9 +41,7 @@ initiobuf: iobuf_alloc: ; Get and save "memptr" jsr incsp2 - jsr popax - sta ptr1 - stx ptr1+1 + jsr popptr1 ; Search table for free entry ldx #$00 diff --git a/libsrc/apple2/lseek.s b/libsrc/apple2/lseek.s index 73f4136be..22bcbee30 100644 --- a/libsrc/apple2/lseek.s +++ b/libsrc/apple2/lseek.s @@ -5,7 +5,7 @@ ; .export _lseek - .import popax + .import popax, popptr1 .include "zeropage.inc" .include "errno.inc" @@ -18,9 +18,7 @@ _lseek: stx tmp2 ; Get and save offset - jsr popax - sta ptr1 - stx ptr1+1 + jsr popptr1 jsr popax sta ptr2 diff --git a/libsrc/apple2/rwcommon.s b/libsrc/apple2/rwcommon.s index 3180a875d..e5fd9ae90 100644 --- a/libsrc/apple2/rwcommon.s +++ b/libsrc/apple2/rwcommon.s @@ -3,7 +3,7 @@ ; .export rwprolog, rwcommon, rwepilog - .import popax + .import popax, popptr1 .include "zeropage.inc" .include "errno.inc" @@ -17,9 +17,7 @@ rwprolog: stx ptr2+1 ; Get and save buf - jsr popax - sta ptr1 - stx ptr1+1 + jsr popptr1 ; Get and process fd jsr popax diff --git a/libsrc/atari/dio_stc.s b/libsrc/atari/dio_stc.s index 52b3af4a6..70dd16088 100644 --- a/libsrc/atari/dio_stc.s +++ b/libsrc/atari/dio_stc.s @@ -17,16 +17,14 @@ .export _dio_log_to_phys .include "atari.inc" .importzp ptr1,ptr2,ptr3 - .import popax,__oserror + .import popax, popptr1, __oserror .proc _dio_log_to_phys sta ptr2 stx ptr2+1 ; pointer to output structure - jsr popax - sta ptr1 - stx ptr1+1 ; save pointer to input data + jsr popptr1 ; save pointer to input data jsr popax sta ptr3 diff --git a/libsrc/atari/siocall.s b/libsrc/atari/siocall.s index 3db37753f..0465a6a3e 100644 --- a/libsrc/atari/siocall.s +++ b/libsrc/atari/siocall.s @@ -16,7 +16,7 @@ .export __sio_call .include "atari.inc" - .import popa,popax + .import popa, popax, popptr1 .import sectsizetab,__oserror .importzp ptr1 @@ -31,9 +31,7 @@ sta DAUX1 ; set sector # stx DAUX2 - jsr popax - sta ptr1 - stx ptr1+1 + jsr popptr1 ldy #sst_flag lda (ptr1),y diff --git a/libsrc/atmos/read.s b/libsrc/atmos/read.s index c44dc8584..83aa8024e 100644 --- a/libsrc/atmos/read.s +++ b/libsrc/atmos/read.s @@ -9,7 +9,7 @@ .export _read .constructor initstdin - .import popax + .import popax, popptr1 .importzp ptr1, ptr2, ptr3 .forceimport disable_caps @@ -26,9 +26,7 @@ eor #$FF sta ptr2+1 ; Remember -count-1 - jsr popax ; get buf - sta ptr1 - stx ptr1+1 + jsr popptr1 ; get buf jsr popax ; get fd and discard L1: inc ptr2 diff --git a/libsrc/atmos/write.s b/libsrc/atmos/write.s index c6399f2bf..7865b5698 100644 --- a/libsrc/atmos/write.s +++ b/libsrc/atmos/write.s @@ -7,7 +7,7 @@ ; .export _write - .import popax + .import popax, popptr1 .importzp ptr1, ptr2, ptr3, tmp1 .include "atmos.inc" @@ -23,9 +23,7 @@ eor #$FF sta ptr2+1 ; Remember -count-1 - jsr popax ; get buf - sta ptr1 - stx ptr1+1 + jsr popptr1 ; get buf jsr popax ; get fd and discard L1: inc ptr2 bne L2 diff --git a/libsrc/cbm/c_save.s b/libsrc/cbm/c_save.s index dfdb7df42..0597e9401 100644 --- a/libsrc/cbm/c_save.s +++ b/libsrc/cbm/c_save.s @@ -6,16 +6,14 @@ .export _cbm_k_save .import SAVE - .import popax + .import popptr1 .importzp ptr1, tmp1 _cbm_k_save: sta tmp1 ; store end address stx tmp1+1 - jsr popax ; pop start address - sta ptr1 - stx ptr1+1 + jsr popptr1 ; pop start address lda #ptr1 ldx tmp1 ldy tmp1+1 diff --git a/libsrc/cbm/sysrename.s b/libsrc/cbm/sysrename.s index 86cb37011..f79bf720a 100644 --- a/libsrc/cbm/sysrename.s +++ b/libsrc/cbm/sysrename.s @@ -9,7 +9,7 @@ .import fnparse, fnadd, fnparsename .import opencmdchannel, closecmdchannel .import writefndiskcmd, readdiskerror - .import popax + .import popptr1 .import fncmd, fnunit .importzp ptr1 @@ -26,10 +26,8 @@ lda #'=' jsr fnadd - jsr popax - sta ptr1 - stx ptr1+1 - ldy #0 + jsr popptr1 + ; ldy #0 Y=0 guaranteed by popptr1 jsr fnparsename ; Parse second filename bne done diff --git a/libsrc/common/_swap.s b/libsrc/common/_swap.s index a16aecc52..9ad771de1 100644 --- a/libsrc/common/_swap.s +++ b/libsrc/common/_swap.s @@ -5,7 +5,7 @@ ; .export __swap - .import popax + .import popax, popptr1 .importzp ptr1, ptr2, ptr3 @@ -19,13 +19,11 @@ __swap: eor #$FF sta ptr2 stx ptr2+1 - jsr popax ; Get p - sta ptr1 - stx ptr1+1 + jsr popptr1 ; Get p ; Prepare for swap - ldy #$00 + ; ldy #$00 is guaranteed by popptr1 ; Swap loop diff --git a/libsrc/common/getcwd.s b/libsrc/common/getcwd.s index b3cfbefcf..c14df63a1 100644 --- a/libsrc/common/getcwd.s +++ b/libsrc/common/getcwd.s @@ -6,7 +6,7 @@ .export _getcwd - .import popax + .import popptr1 .import __cwd .importzp ptr1, ptr2 @@ -25,13 +25,11 @@ eor #$FF sta ptr2+1 - jsr popax ; Get buf - sta ptr1 - stx ptr1+1 ; Save buf + jsr popptr1 ; Get buf to ptr1 ; Copy __cwd to the given buffer checking the length - ldy #$00 + ; ldy #$00 is guaranteed by popptr10 loop: inc ptr2 bne @L1 inc ptr2+1 diff --git a/libsrc/common/longjmp.s b/libsrc/common/longjmp.s index e9bac42e6..91606a442 100644 --- a/libsrc/common/longjmp.s +++ b/libsrc/common/longjmp.s @@ -6,7 +6,7 @@ ; .export _longjmp - .import popax + .import popptr1 .importzp sp, ptr1, ptr2 _longjmp: @@ -16,10 +16,8 @@ _longjmp: bne @L1 inc ptr2 ; 0 is illegal, according to the standard ... ; ... and, must be replaced by 1 -@L1: jsr popax ; get buf - sta ptr1 - stx ptr1+1 - ldy #0 +@L1: jsr popptr1 ; get buf + ; ldy #0 is guaranteed by popptr1 ; Get the old parameter stack diff --git a/libsrc/common/memchr.s b/libsrc/common/memchr.s index 1b60cbf73..de39a04f9 100644 --- a/libsrc/common/memchr.s +++ b/libsrc/common/memchr.s @@ -5,7 +5,7 @@ ; .export _memchr - .import popax, return0 + .import popax, popptr1 return0 .importzp ptr1, ptr2 @@ -18,11 +18,10 @@ sta ptr2+1 ; Save ones complement of n jsr popax ; get c pha - jsr popax ; get p - sta ptr1 - stx ptr1+1 - ldy #$00 + jsr popptr1 ; get p + + ; ldy #$00 is guaranteed by popptr1 pla ; Get c ldx ptr2 ; Use X as low counter byte diff --git a/libsrc/common/memcmp.s b/libsrc/common/memcmp.s index 25628127a..93a2c28dc 100644 --- a/libsrc/common/memcmp.s +++ b/libsrc/common/memcmp.s @@ -5,7 +5,7 @@ ; .export _memcmp - .import popax, return0 + .import popax, popptr1, return0 .importzp ptr1, ptr2, ptr3 _memcmp: @@ -24,14 +24,12 @@ _memcmp: jsr popax ; Get p2 sta ptr2 stx ptr2+1 - jsr popax ; Get p1 - sta ptr1 - stx ptr1+1 + jsr popptr1 ; Get p1 ; Loop initialization + ;ldy #$00 ; Initialize pointer (Y=0 guaranteed by popptr1) ldx ptr3 ; Load low counter byte into X - ldy #$00 ; Initialize pointer ; Head of compare loop: Test for the end condition diff --git a/libsrc/common/memcpy.s b/libsrc/common/memcpy.s index c0c5e56d0..1ee53be07 100644 --- a/libsrc/common/memcpy.s +++ b/libsrc/common/memcpy.s @@ -11,7 +11,7 @@ ; .export _memcpy, memcpy_upwards, memcpy_getparams - .import popax + .import popax, popptr1 .importzp sp, ptr1, ptr2, ptr3 ; ---------------------------------------------------------------------- @@ -64,12 +64,11 @@ memcpy_getparams: ; IMPORTANT! Function has to leave with Y=0! sta ptr3 stx ptr3+1 ; save n to ptr3 - jsr popax - sta ptr1 - stx ptr1+1 ; save src to ptr1 + jsr popptr1 ; save src to ptr1 ; save dest to ptr2 - ldy #1 ; (direct stack access is three cycles faster + 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 tax diff --git a/libsrc/common/strcmp.s b/libsrc/common/strcmp.s index 189ce8fa7..8939163b1 100644 --- a/libsrc/common/strcmp.s +++ b/libsrc/common/strcmp.s @@ -5,16 +5,14 @@ ; .export _strcmp - .import popax + .import popptr1 .importzp ptr1, ptr2 _strcmp: sta ptr2 ; Save s2 stx ptr2+1 - jsr popax ; Get s1 - sta ptr1 - stx ptr1+1 - ldy #0 + jsr popptr1 ; Get s1 + ;ldy #0 ; Y=0 guaranteed by popptr1 loop: lda (ptr1),y cmp (ptr2),y diff --git a/libsrc/common/stricmp.s b/libsrc/common/stricmp.s index 501d0b625..384e78e31 100644 --- a/libsrc/common/stricmp.s +++ b/libsrc/common/stricmp.s @@ -6,7 +6,7 @@ ; .export _stricmp, _strcasecmp - .import popax + .import popptr1 .import __ctype .importzp ptr1, ptr2, tmp1 @@ -16,10 +16,8 @@ _stricmp: _strcasecmp: sta ptr2 ; Save s2 stx ptr2+1 - jsr popax ; get s1 - sta ptr1 - stx ptr1+1 - ldy #0 + jsr popptr1 ; get s1 + ; ldy #0 ; Y=0 guaranteed by popptr1 loop: lda (ptr2),y ; get char from second string tax diff --git a/libsrc/common/strncat.s b/libsrc/common/strncat.s index 457e39e25..caa6804fc 100644 --- a/libsrc/common/strncat.s +++ b/libsrc/common/strncat.s @@ -6,7 +6,7 @@ ; .export _strncat - .import popax + .import popax, popptr1 .importzp ptr1, ptr2, ptr3, tmp1, tmp2 .macpack cpu @@ -17,9 +17,7 @@ _strncat: eor #$FF sta tmp2 - jsr popax ; get src - sta ptr1 - stx ptr1+1 + jsr popptr1 ; get src jsr popax ; get dest sta ptr3 ; remember for function return diff --git a/libsrc/common/strncmp.s b/libsrc/common/strncmp.s index 1035e15b8..bff1f0911 100644 --- a/libsrc/common/strncmp.s +++ b/libsrc/common/strncmp.s @@ -5,7 +5,7 @@ ; .export _strncmp - .import popax + .import popax, popptr1 .importzp ptr1, ptr2, ptr3 @@ -28,13 +28,11 @@ _strncmp: jsr popax ; get s2 sta ptr2 stx ptr2+1 - jsr popax ; get s1 - sta ptr1 - stx ptr1+1 + jsr popptr1 ; get s1 ; Loop setup - ldy #0 + ;ldy #0 Y=0 guaranteed by popptr1 ; Start of compare loop. Check the counter. diff --git a/libsrc/common/strncpy.s b/libsrc/common/strncpy.s index 042f9e28b..e6cafd990 100644 --- a/libsrc/common/strncpy.s +++ b/libsrc/common/strncpy.s @@ -5,7 +5,7 @@ ; .export _strncpy - .import popax + .import popptr1 .importzp ptr1, ptr2, tmp1, tmp2, tmp3 .proc _strncpy @@ -16,9 +16,7 @@ eor #$FF sta tmp2 ; Store -size - 1 - jsr popax ; get src - sta ptr1 - stx ptr1+1 + jsr popptr1 ; get src jsr popax ; get dest sta ptr2 stx ptr2+1 diff --git a/libsrc/common/strnicmp.s b/libsrc/common/strnicmp.s index b1f973e3a..6a5de09e4 100644 --- a/libsrc/common/strnicmp.s +++ b/libsrc/common/strnicmp.s @@ -7,7 +7,7 @@ ; .export _strnicmp, _strncasecmp - .import popax, __ctype + .import popax, popptr1, __ctype .importzp ptr1, ptr2, ptr3, tmp1 .include "ctype.inc" @@ -32,13 +32,11 @@ _strncasecmp: jsr popax ; get s2 sta ptr2 stx ptr2+1 - jsr popax ; get s1 - sta ptr1 - stx ptr1+1 + jsr popptr1 ; get s1 ; Loop setup - ldy #0 + ; ldy #0 Y=0 guaranteed by popptr1 ; Start of compare loop. Check the counter. diff --git a/libsrc/common/strpbrk.s b/libsrc/common/strpbrk.s index 5d1482913..afe90ecab 100644 --- a/libsrc/common/strpbrk.s +++ b/libsrc/common/strpbrk.s @@ -5,17 +5,15 @@ ; .export _strpbrk - .import popax, return0 + .import popax, popptr1, return0 .importzp ptr1, ptr2, tmp1, tmp2, tmp3 _strpbrk: jsr popax ; get s2 sta ptr2 stx ptr2+1 - jsr popax ; get s1 - sta ptr1 - stx ptr1+1 - ldy #$00 + jsr popptr1 ; get s1 + ; ldy #$00 Y=0 guaranteed by popptr1 L1: lda (ptr1),y ; get next char from s1 beq L9 ; jump if done diff --git a/libsrc/common/strstr.s b/libsrc/common/strstr.s index 55e2def03..84f633245 100644 --- a/libsrc/common/strstr.s +++ b/libsrc/common/strstr.s @@ -5,7 +5,7 @@ ; .export _strstr - .import popax + .import popptr1 .importzp ptr1, ptr2, ptr3, ptr4, tmp1 _strstr: @@ -13,13 +13,11 @@ _strstr: stx ptr2+1 sta ptr4 ; Setup temp copy for later - jsr popax ; Get haystack - sta ptr1 - stx ptr1+1 ; Save haystack + jsr popptr1 ; Get haystack to ptr1 ; If needle is empty, return haystack - ldy #$00 + ; ldy #$00 Y=0 guaranteed by popptr1 lda (ptr2),y ; Get first byte of needle beq @Found ; Needle is empty --> we're done diff --git a/libsrc/conio/vcprintf.s b/libsrc/conio/vcprintf.s index 06eab4421..3a9ddf9d7 100644 --- a/libsrc/conio/vcprintf.s +++ b/libsrc/conio/vcprintf.s @@ -5,7 +5,7 @@ ; .export _vcprintf - .import pushax, popax + .import pushax, popax, popptr1 .import __printf, _cputc .importzp sp, ptr1, ptr2, ptr3, tmp1 @@ -54,9 +54,7 @@ out: jsr popax ; count eor #$FF sta outdesc+7 - jsr popax ; buf - sta ptr1 - stx ptr1+1 + jsr popptr1 ; buf jsr popax ; d sta ptr3 diff --git a/libsrc/dbg/dbgsupp.s b/libsrc/dbg/dbgsupp.s index 9f044c728..07ab9e25a 100644 --- a/libsrc/dbg/dbgsupp.s +++ b/libsrc/dbg/dbgsupp.s @@ -6,7 +6,7 @@ .export _DbgInit .export _DbgSP, _DbgCS, _DbgHI - .import popax, return0, _DbgEntry, _set_brk, _end_brk + .import popptr1, return0, _DbgEntry, _set_brk, _end_brk .import _DbgBreaks .import _brk_pc .import __ZP_START__ ; Linker generated @@ -170,9 +170,7 @@ L12: ldy #1 ; Force != 0 .export _DbgIsBreak _DbgIsBreak: - jsr popax ; Get address - sta ptr1 - stx ptr1+1 + jsr popptr1 ; Get address ldx #0 L20: lda _DbgBreaks+3,x ; Get bk_use beq L21 ; Jump if not set diff --git a/libsrc/geos-common/drivers/fio_module.s b/libsrc/geos-common/drivers/fio_module.s index b757e6bd8..e655f0cec 100644 --- a/libsrc/geos-common/drivers/fio_module.s +++ b/libsrc/geos-common/drivers/fio_module.s @@ -13,7 +13,7 @@ FILEDES = 3 ; first free to use file descriptor .importzp ptr1, ptr2, ptr3, tmp1 - .import addysp, popax + .import addysp, popax, poptr1 .import __oserror .import _FindFile, _ReadByte .export _open, _close, _read @@ -37,9 +37,7 @@ _open: @parmok: jsr popax ; Get flags sta tmp1 - jsr popax ; Get name - sta ptr1 - stx ptr1+1 + jsr popptr1 ; Get name lda filedesc ; is there a file already open? bne @alreadyopen diff --git a/libsrc/pce/memcpy.s b/libsrc/pce/memcpy.s index 14977dee0..98db6a964 100644 --- a/libsrc/pce/memcpy.s +++ b/libsrc/pce/memcpy.s @@ -17,7 +17,7 @@ .export _memcpy .export memcpy_increment, memcpy_transfer, memcpy_getparams - .import incsp2, popax + .import incsp2, popax, popptr1 .importzp sp, ptr1, ptr2, ptr3 @@ -81,13 +81,11 @@ memcpy_getparams: jsr incsp2 ; drop src address jmp popax ; get pointer; return it as result -@L1: jsr popax - sta ptr1 - stx ptr1+1 ; save src +@L1: jsr popptr1 ; save src ; (Direct stack access is six cycles faster [total cycle count].) - ldy #1 ; save dest + iny ; (Y=0 by popptr1, need '1' here) save dest lda (sp),y ; get high byte tax lda (sp) ; get low byte diff --git a/libsrc/runtime/popptr1.s b/libsrc/runtime/popptr1.s new file mode 100644 index 000000000..64da308a8 --- /dev/null +++ b/libsrc/runtime/popptr1.s @@ -0,0 +1,29 @@ +; +; Christian Kruger, 20-May-2018 +; +; CC65 runtime: Pop registers on stack to ptr1 or ptr2 and ptr1. +; X is untouched, low byte in A, Y is defined to be 0! + + .export popptr1 + .import incsp2 + .importzp sp, ptr1 + + .macpack cpu + +.proc popptr1 ; 14 bytes, + + ldy #1 + lda (sp),y ; get hi byte + sta ptr+1 ; into ptr hi + dey ; note: apply even for 65C02 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/steaxspi.s b/libsrc/runtime/steaxspi.s index b85725050..9686e5c35 100644 --- a/libsrc/runtime/steaxspi.s +++ b/libsrc/runtime/steaxspi.s @@ -6,7 +6,7 @@ .export steaxspidx - .import popax + .import popptr1 .importzp sreg, ptr1, tmp1, tmp2, tmp3 @@ -15,9 +15,7 @@ sta tmp1 stx tmp2 sty tmp3 - jsr popax ; get the pointer - sta ptr1 - stx ptr1+1 + jsr popptr1 ; get the pointer ldy tmp3 lda tmp1 sta (ptr1),y diff --git a/libsrc/telestrat/write.s b/libsrc/telestrat/write.s index 8c2bc08f7..30eac9532 100644 --- a/libsrc/telestrat/write.s +++ b/libsrc/telestrat/write.s @@ -2,7 +2,7 @@ ; jede jede@oric.org 2017-01-22 .export _write - .import popax + .import popax, popptr1 .importzp ptr1, ptr2, ptr3, tmp1 .include "telestrat.inc" @@ -19,9 +19,7 @@ eor #$FF sta ptr2+1 ; Remember -count-1 - jsr popax ; get buf - sta ptr1 - stx ptr1+1 + jsr popptr1 ; get buf jsr popax ; get fd and discard ; if fd=0001 then it stdout diff --git a/libsrc/tgi/tgi_bar.s b/libsrc/tgi/tgi_bar.s index 476f9d7a4..0e424c1f0 100644 --- a/libsrc/tgi/tgi_bar.s +++ b/libsrc/tgi/tgi_bar.s @@ -8,7 +8,7 @@ .include "tgi-kernel.inc" .importzp ptr1, ptr2, ptr3, ptr4 - .import popax + .import popax, popptr1 .proc _tgi_bar @@ -24,9 +24,7 @@ sta ptr2 ; Y1 stx ptr2+1 - jsr popax - sta ptr1 ; X1 - stx ptr1+1 + jsr popptr1 ; X1 ; Make sure X1 is less than X2. Swap both if not. diff --git a/libsrc/tgi/tgi_popxy.s b/libsrc/tgi/tgi_popxy.s index 55b259dab..40655d413 100644 --- a/libsrc/tgi/tgi_popxy.s +++ b/libsrc/tgi/tgi_popxy.s @@ -6,17 +6,14 @@ .include "tgi-kernel.inc" - .import popax + .import popptr1 .importzp ptr1, ptr2 .proc tgi_popxy sta ptr2 ; Y stx ptr2+1 - jsr popax - sta ptr1 ; X - stx ptr1+1 - rts + jmp popptr1 ; X .endproc diff --git a/libsrc/zlib/adler32.s b/libsrc/zlib/adler32.s index e54e25e77..ccfe2f167 100644 --- a/libsrc/zlib/adler32.s +++ b/libsrc/zlib/adler32.s @@ -7,7 +7,7 @@ .export _adler32 - .import incsp2, incsp4, popax, popeax + .import incsp2, incsp4, popptr1, popeax .importzp sreg, ptr1, ptr2, tmp1 BASE = 65521 ; largest prime smaller than 65536 @@ -20,9 +20,7 @@ _adler32: @L1: sta ptr2 stx ptr2+1 ; ptr1 = buf - jsr popax - sta ptr1 - stx ptr1+1 + jsr popptr1 ; if (buf == NULL) return 1L; ora ptr1+1 beq @L0 diff --git a/libsrc/zlib/crc32.s b/libsrc/zlib/crc32.s index 26955dbed..7f06dd383 100644 --- a/libsrc/zlib/crc32.s +++ b/libsrc/zlib/crc32.s @@ -7,7 +7,7 @@ .export _crc32 - .import compleax, incsp2, incsp4, popax, popeax + .import compleax, incsp2, incsp4, popptr1, popeax .importzp sreg, ptr1, ptr2, tmp1, tmp2 POLYNOMIAL = $EDB88320 @@ -67,9 +67,7 @@ _crc32: @L1: sta ptr2 stx ptr2+1 ; ptr1 = buf - jsr popax - sta ptr1 - stx ptr1+1 + jsr popptr1 ; if (buf == NULL) return 0; ora ptr1+1 beq @L0 From 911b86de67db870a393447d5ad5b61da3c78f59a Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sun, 20 May 2018 15:38:48 +0200 Subject: [PATCH 0696/2161] Fixed formatting and two import issues. --- libsrc/common/memchr.s | 2 +- libsrc/common/strncpy.s | 2 +- libsrc/runtime/popptr1.s | 20 +++++++------------- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/libsrc/common/memchr.s b/libsrc/common/memchr.s index de39a04f9..c11a467d0 100644 --- a/libsrc/common/memchr.s +++ b/libsrc/common/memchr.s @@ -5,7 +5,7 @@ ; .export _memchr - .import popax, popptr1 return0 + .import popax, popptr1, return0 .importzp ptr1, ptr2 diff --git a/libsrc/common/strncpy.s b/libsrc/common/strncpy.s index e6cafd990..56387f880 100644 --- a/libsrc/common/strncpy.s +++ b/libsrc/common/strncpy.s @@ -5,7 +5,7 @@ ; .export _strncpy - .import popptr1 + .import popax, popptr1 .importzp ptr1, ptr2, tmp1, tmp2, tmp3 .proc _strncpy diff --git a/libsrc/runtime/popptr1.s b/libsrc/runtime/popptr1.s index 64da308a8..2167717ce 100644 --- a/libsrc/runtime/popptr1.s +++ b/libsrc/runtime/popptr1.s @@ -5,25 +5,19 @@ ; X is untouched, low byte in A, Y is defined to be 0! .export popptr1 - .import incsp2 + .import incsp2 .importzp sp, ptr1 - .macpack cpu - -.proc popptr1 ; 14 bytes, + .macpack cpu +.proc popptr1 ; 14 bytes (four usages = at least 2 bytes saved) ldy #1 lda (sp),y ; get hi byte - sta ptr+1 ; into ptr hi - dey ; note: apply even for 65C02 to have Y=0 at exit! -.if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) ; get lo byte -.else + sta ptr1+1 ; into ptr hi + dey ; no optimization for 65C02 here to have Y=0 at exit! lda (sp),y ; get lo byte -.endif - sta ptr1 ; to ptr lo - - jmp incsp2 + sta ptr1 ; to ptr lo + jmp incsp2 .endproc From 839aa93198e25b4fd48204c3c55f2149a095e9b8 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Mon, 21 May 2018 13:07:26 +0200 Subject: [PATCH 0697/2161] Resolved conflict and removed adaptation for strpbrk for time being. --- libsrc/apple2/extra/iobuf-0800.s | 4 ++-- libsrc/common/strpbrk.s | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libsrc/apple2/extra/iobuf-0800.s b/libsrc/apple2/extra/iobuf-0800.s index c7a9dae2e..694b91fdb 100644 --- a/libsrc/apple2/extra/iobuf-0800.s +++ b/libsrc/apple2/extra/iobuf-0800.s @@ -7,7 +7,7 @@ .constructor initiobuf .export iobuf_alloc, iobuf_free - .import __STARTUP_RUN__ + .import __MAIN_START__ .import incsp2, popptr1 .include "zeropage.inc" @@ -18,7 +18,7 @@ initiobuf: ; Convert end address highbyte to table index - lda #>__STARTUP_RUN__ + lda #>__MAIN_START__ sec sbc #>$0800 lsr diff --git a/libsrc/common/strpbrk.s b/libsrc/common/strpbrk.s index afe90ecab..5d1482913 100644 --- a/libsrc/common/strpbrk.s +++ b/libsrc/common/strpbrk.s @@ -5,15 +5,17 @@ ; .export _strpbrk - .import popax, popptr1, return0 + .import popax, return0 .importzp ptr1, ptr2, tmp1, tmp2, tmp3 _strpbrk: jsr popax ; get s2 sta ptr2 stx ptr2+1 - jsr popptr1 ; get s1 - ; ldy #$00 Y=0 guaranteed by popptr1 + jsr popax ; get s1 + sta ptr1 + stx ptr1+1 + ldy #$00 L1: lda (ptr1),y ; get next char from s1 beq L9 ; jump if done From 166425f807e6ddf7e648df853611dbb642c80152 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Mon, 21 May 2018 14:33:44 +0200 Subject: [PATCH 0698/2161] Converted unintentionally introduced tabs to spaces. --- libsrc/tgi/tgi_popxy.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/tgi/tgi_popxy.s b/libsrc/tgi/tgi_popxy.s index 40655d413..33ccc57f9 100644 --- a/libsrc/tgi/tgi_popxy.s +++ b/libsrc/tgi/tgi_popxy.s @@ -13,7 +13,7 @@ sta ptr2 ; Y stx ptr2+1 - jmp popptr1 ; X + jmp popptr1 ; X .endproc From d4081b43a6561a25a91299863f99264c1c57ab1b Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Mon, 21 May 2018 14:41:12 +0200 Subject: [PATCH 0699/2161] Fixed comments. --- libsrc/common/getcwd.s | 2 +- libsrc/runtime/popptr1.s | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/common/getcwd.s b/libsrc/common/getcwd.s index c14df63a1..22b6ceded 100644 --- a/libsrc/common/getcwd.s +++ b/libsrc/common/getcwd.s @@ -29,7 +29,7 @@ ; Copy __cwd to the given buffer checking the length - ; ldy #$00 is guaranteed by popptr10 + ; ldy #$00 is guaranteed by popptr1 loop: inc ptr2 bne @L1 inc ptr2+1 diff --git a/libsrc/runtime/popptr1.s b/libsrc/runtime/popptr1.s index 2167717ce..48725efa3 100644 --- a/libsrc/runtime/popptr1.s +++ b/libsrc/runtime/popptr1.s @@ -1,7 +1,7 @@ ; ; Christian Kruger, 20-May-2018 ; -; CC65 runtime: Pop registers on stack to ptr1 or ptr2 and ptr1. +; CC65 runtime: Pop 2 bytes from stack to ptr1. ; X is untouched, low byte in A, Y is defined to be 0! .export popptr1 From c40ae4d774ef2a1e325e51524170a35eaad266c0 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Mon, 21 May 2018 16:21:45 +0200 Subject: [PATCH 0700/2161] Saved 6 bytes by using popptr1. --- libsrc/cbm/read.s | 10 +++++----- libsrc/cbm/rwcommon.s | 17 +++++++---------- libsrc/cbm/write.s | 10 +++++----- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/libsrc/cbm/read.s b/libsrc/cbm/read.s index 87a2c7037..9de4980ce 100644 --- a/libsrc/cbm/read.s +++ b/libsrc/cbm/read.s @@ -88,10 +88,10 @@ ldy #0 lda tmp1 - sta (ptr2),y - inc ptr2 + sta (ptr1),y + inc ptr1 bne @L1 - inc ptr2+1 ; *buf++ = A; + inc ptr1+1 ; *buf++ = A; ; Increment the byte count @@ -107,9 +107,9 @@ ; Decrement the count -@L3: inc ptr1 +@L3: inc ptr2 bne @L0 - inc ptr1+1 + inc ptr2+1 bne @L0 beq done ; Branch always diff --git a/libsrc/cbm/rwcommon.s b/libsrc/cbm/rwcommon.s index c044b6c38..0168a78d0 100644 --- a/libsrc/cbm/rwcommon.s +++ b/libsrc/cbm/rwcommon.s @@ -6,7 +6,7 @@ .export rwcommon - .import popax + .import popax, popptr1 .importzp ptr1, ptr2, ptr3, tmp2 .include "errno.inc" @@ -22,18 +22,15 @@ .proc rwcommon eor #$FF - sta ptr1 + sta ptr2 txa eor #$FF - sta ptr1+1 ; Remember -count-1 + sta ptr2+1 ; Remember -count-1 - jsr popax ; Get buf - sta ptr2 - stx ptr2+1 - - lda #$00 - sta ptr3 - sta ptr3+1 ; Clear ptr3 + jsr popptr1 ; Get buf + ; Y=0 by popptr1 + sty ptr3 + sty ptr3+1 ; Clear ptr3 jsr popax ; Get the handle cpx #$01 diff --git a/libsrc/cbm/write.s b/libsrc/cbm/write.s index 20999d2ac..dddec0792 100644 --- a/libsrc/cbm/write.s +++ b/libsrc/cbm/write.s @@ -61,10 +61,10 @@ ; Output the next character from the buffer @L0: ldy #0 - lda (ptr2),y - inc ptr2 + lda (ptr1),y + inc ptr1 bne @L1 - inc ptr2+1 ; A = *buf++; + inc ptr1+1 ; A = *buf++; @L1: jsr BSOUT ; Check the status @@ -84,9 +84,9 @@ ; Decrement count -@L2: inc ptr1 +@L2: inc ptr2 bne @L0 - inc ptr1+1 + inc ptr2+1 bne @L0 ; Wrote all chars or disk full. Close the output channel From d7da827be8dc5d02f1b1206b7c61b82f6e187b5c Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Mon, 21 May 2018 18:18:01 +0200 Subject: [PATCH 0701/2161] Apply faster popptr1 to functions and/or use register instead of stack to save accu. --- libsrc/runtime/mul.s | 24 ++++++++++++------------ libsrc/runtime/mul8.s | 20 ++++++++++---------- libsrc/runtime/mulax3.s | 4 ++-- libsrc/runtime/mulax5.s | 4 ++-- libsrc/runtime/mulax7.s | 4 ++-- libsrc/runtime/mulax9.s | 4 ++-- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/libsrc/runtime/mul.s b/libsrc/runtime/mul.s index 6344e3a32..a9b53293b 100644 --- a/libsrc/runtime/mul.s +++ b/libsrc/runtime/mul.s @@ -6,8 +6,8 @@ .export tosumulax, tosmulax .import mul8x16, mul8x16a ; in mul8.s - .import popsreg - .importzp sreg, tmp1, ptr4 + .import popptr1 + .importzp tmp1, ptr1, ptr4 ;--------------------------------------------------------------------------- @@ -19,12 +19,12 @@ tosumulax: txa ; High byte zero beq @L3 ; Do 8x16 multiplication if high byte zero stx ptr4+1 ; Save right operand - jsr popsreg ; Get left operand + jsr popptr1 ; Get left operand (Y=0 by popptr1) -; Do ptr4:ptr4+1 * sreg:sreg+1 --> AX +; Do ptr4:ptr4+1 * ptr1:ptr1+1 --> AX - lda #0 - ldx sreg+1 ; Get high byte into register for speed + tya ; A = 0 + ldx ptr1+1 ; check if lhs is 8 bit only beq @L4 ; -> we can do 8x16 after swap sta tmp1 ldy #16 ; Number of bits @@ -34,12 +34,12 @@ tosumulax: @L0: bcc @L1 clc - adc sreg - pha - txa ; hi byte of left op + adc ptr1 + tax + lda ptr1+1 ; hi byte of left op adc tmp1 sta tmp1 - pla + txa @L1: ror tmp1 ror a @@ -59,9 +59,9 @@ tosumulax: ; If the high byte of rhs is zero, swap the operands and use the 8x16 ; routine. On entry, A and X are zero -@L4: ldy sreg ; Save right operand (8 bit) +@L4: ldy ptr1 ; Save right operand (8 bit) ldx ptr4 ; Copy left 16 bit operand to right - stx sreg + stx ptr1 ldx ptr4+1 ; Don't store, this is done later sty ptr4 ; Copy low 8 bit of right op to left ldy #8 diff --git a/libsrc/runtime/mul8.s b/libsrc/runtime/mul8.s index 9d4dfcbf4..395d64a4c 100644 --- a/libsrc/runtime/mul8.s +++ b/libsrc/runtime/mul8.s @@ -6,8 +6,8 @@ .export tosumula0, tosmula0 .export mul8x16, mul8x16a - .import popsreg - .importzp sreg, ptr4 + .import popptr1 + .importzp ptr1, ptr4 ;--------------------------------------------------------------------------- @@ -16,11 +16,11 @@ tosmula0: tosumula0: sta ptr4 -mul8x16:jsr popsreg ; Get left operand +mul8x16:jsr popptr1 ; Get left operand (Y=0 by popptr1) - lda #0 ; Clear byte 1 + tya ; Clear byte 1 ldy #8 ; Number of bits - ldx sreg+1 ; Get into register for speed + ldx ptr1+1 ; check if lhs is 8 bit only beq mul8x8 ; Do 8x8 multiplication if high byte zero mul8x16a: sta ptr4+1 ; Clear byte 2 @@ -29,12 +29,12 @@ mul8x16a: @L0: bcc @L1 clc - adc sreg - pha - txa ; hi byte of left op + adc ptr1 + tax + lda ptr1+1 ; hi byte of left op adc ptr4+1 sta ptr4+1 - pla + txa @L1: ror ptr4+1 ror a @@ -52,7 +52,7 @@ mul8x8: lsr ptr4 ; Get first bit into carry @L0: bcc @L1 clc - adc sreg + adc ptr1 @L1: ror ror ptr4 dey diff --git a/libsrc/runtime/mulax3.s b/libsrc/runtime/mulax3.s index 472bc60ec..82cc033c3 100644 --- a/libsrc/runtime/mulax3.s +++ b/libsrc/runtime/mulax3.s @@ -15,11 +15,11 @@ rol ptr1+1 clc adc ptr1 - pha + tay txa adc ptr1+1 tax - pla + tya rts .endproc diff --git a/libsrc/runtime/mulax5.s b/libsrc/runtime/mulax5.s index 7e5ed11d9..bf5eaefe8 100644 --- a/libsrc/runtime/mulax5.s +++ b/libsrc/runtime/mulax5.s @@ -17,11 +17,11 @@ rol ptr1+1 clc adc ptr1 - pha + tay txa adc ptr1+1 tax - pla + tya rts .endproc diff --git a/libsrc/runtime/mulax7.s b/libsrc/runtime/mulax7.s index 90313180c..3414ebc9e 100644 --- a/libsrc/runtime/mulax7.s +++ b/libsrc/runtime/mulax7.s @@ -20,12 +20,12 @@ rol ptr1+1 ; * 8 sec sbc ptr1 - pha + tay txa eor #$ff adc ptr1+1 ; * (8 - 1) tax - pla + tya rts .endproc diff --git a/libsrc/runtime/mulax9.s b/libsrc/runtime/mulax9.s index d2dd89529..d175d55aa 100644 --- a/libsrc/runtime/mulax9.s +++ b/libsrc/runtime/mulax9.s @@ -20,11 +20,11 @@ rol ptr1+1 ; * 8 clc adc ptr1 ; * (8+1) - pha + tay txa adc ptr1+1 tax - pla + tya rts .endproc From 99e13eeaa2671c56d4754ffe6760c85756dda261 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Mon, 21 May 2018 18:19:39 +0200 Subject: [PATCH 0702/2161] Fix typo for import. --- libsrc/geos-common/drivers/fio_module.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/geos-common/drivers/fio_module.s b/libsrc/geos-common/drivers/fio_module.s index e655f0cec..0be5015a7 100644 --- a/libsrc/geos-common/drivers/fio_module.s +++ b/libsrc/geos-common/drivers/fio_module.s @@ -13,7 +13,7 @@ FILEDES = 3 ; first free to use file descriptor .importzp ptr1, ptr2, ptr3, tmp1 - .import addysp, popax, poptr1 + .import addysp, popax, popptr1 .import __oserror .import _FindFile, _ReadByte .export _open, _close, _read From 95b4a6f881d1ef7f57aac788cbd27344524eb157 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Tue, 22 May 2018 11:25:26 +0200 Subject: [PATCH 0703/2161] Beautified comment. --- libsrc/cbm/rwcommon.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/cbm/rwcommon.s b/libsrc/cbm/rwcommon.s index 0168a78d0..a1f92be8c 100644 --- a/libsrc/cbm/rwcommon.s +++ b/libsrc/cbm/rwcommon.s @@ -27,8 +27,8 @@ eor #$FF sta ptr2+1 ; Remember -count-1 - jsr popptr1 ; Get buf - ; Y=0 by popptr1 + jsr popptr1 ; Get buf to ptr1, Y=0 by call + sty ptr3 sty ptr3+1 ; Clear ptr3 From 30ada4945881be83affbc8a102e2c4d8c26c26e8 Mon Sep 17 00:00:00 2001 From: compyx <b.wassink@ziggo.nl> Date: Tue, 22 May 2018 14:16:00 +0200 Subject: [PATCH 0704/2161] Add CBM kernal call TKSA to CBM library This adds the CBM kernal call TKSA as cbm_k_tksa() to the CBM library. --- doc/c128.sgml | 1 + doc/c16.sgml | 1 + doc/c64.sgml | 1 + doc/cbm510.sgml | 1 + doc/cbm610.sgml | 1 + doc/funcref.sgml | 23 +++++++++++++++++++++++ doc/pet.sgml | 1 + doc/plus4.sgml | 1 + doc/vic20.sgml | 1 + include/cbm.h | 1 + libsrc/cbm/c_tksa.s | 12 ++++++++++++ 11 files changed, 44 insertions(+) create mode 100644 libsrc/cbm/c_tksa.s diff --git a/doc/c128.sgml b/doc/c128.sgml index 1bdcf01f5..feda1cbba 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -124,6 +124,7 @@ declaration and usage. <item>cbm_k_basin <item>cbm_k_bsout <item>cbm_k_clrch +<item>cbm_k_tksa <item>cbm_load <item>cbm_open <item>cbm_opendir diff --git a/doc/c16.sgml b/doc/c16.sgml index 27938ff1e..6375a7898 100644 --- a/doc/c16.sgml +++ b/doc/c16.sgml @@ -115,6 +115,7 @@ declaration and usage. <item>cbm_k_basin <item>cbm_k_bsout <item>cbm_k_clrch +<item>cbm_k_tksa <item>cbm_load <item>cbm_open <item>cbm_opendir diff --git a/doc/c64.sgml b/doc/c64.sgml index a18ce359f..b04b40508 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -217,6 +217,7 @@ declaration and usage. <item>cbm_k_basin <item>cbm_k_bsout <item>cbm_k_clrch +<item>cbm_k_tksa <item>cbm_load <item>cbm_open <item>cbm_opendir diff --git a/doc/cbm510.sgml b/doc/cbm510.sgml index b171c2ce3..1e6a4e07b 100644 --- a/doc/cbm510.sgml +++ b/doc/cbm510.sgml @@ -118,6 +118,7 @@ declaration and usage. <item>cbm_k_basin <item>cbm_k_bsout <item>cbm_k_clrch +<item>cbm_k_tksa <item>cbm_load <item>cbm_open <item>cbm_opendir diff --git a/doc/cbm610.sgml b/doc/cbm610.sgml index 790983b3d..9f963dbd5 100644 --- a/doc/cbm610.sgml +++ b/doc/cbm610.sgml @@ -121,6 +121,7 @@ declaration and usage. <item>cbm_k_basin <item>cbm_k_bsout <item>cbm_k_clrch +<item>cbm_k_tksa <item>cbm_load <item>cbm_open <item>cbm_opendir diff --git a/doc/funcref.sgml b/doc/funcref.sgml index f10379c93..0fe1ce847 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -203,6 +203,7 @@ function. <item><ref id="cbm_k_setlfs" name="cbm_k_setlfs"> <item><ref id="cbm_k_setnam" name="cbm_k_setnam"> <item><ref id="cbm_k_talk" name="cbm_k_talk"> +<item><ref id="cbm_k_tksa" name="cbm_k_tksa"> <item><ref id="cbm_k_udtim" name="cbm_k_udtim"> <item><ref id="cbm_k_unlsn" name="cbm_k_unlsn"> <!-- <item><ref id="cbm_load" name="cbm_load"> --> @@ -2284,6 +2285,28 @@ only be used in presence of a prototype. </quote> +<sect1>cbm_k_tksa<label id="cbm_k_tksa"><p> + +<quote> +<descrip> +<tag/Function/Send TALK secondary address to serial bus +<tag/Header/<tt/<ref id="cbm.h" name="cbm.h">/ +<tag/Declaration/<tt/void __fastcall__ cbm_k_tksa (unsigned char addr);/ +<tag/Description/This function transmits a secondary address on the serial bus for a TALK device. +<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 function can only be called after a call to TALK. +<item>The function will not work after a LISTEN. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="cbm_k_talk" name="cbm_k_talk"> +<tag/Example/None. +</descrip> +</quote> + + <sect1>cbm_k_udtim<label id="cbm_k_udtim"><p> <quote> diff --git a/doc/pet.sgml b/doc/pet.sgml index fd61716dd..fef2d14ec 100644 --- a/doc/pet.sgml +++ b/doc/pet.sgml @@ -99,6 +99,7 @@ declaration and usage. <item>cbm_k_basin <item>cbm_k_bsout <item>cbm_k_clrch +<item>cbm_k_tksa <item>cbm_load <item>cbm_open <item>cbm_opendir diff --git a/doc/plus4.sgml b/doc/plus4.sgml index c1b6165f6..333bd879a 100644 --- a/doc/plus4.sgml +++ b/doc/plus4.sgml @@ -113,6 +113,7 @@ declaration and usage. <item>cbm_k_basin <item>cbm_k_bsout <item>cbm_k_clrch +<item>cbm_k_tksa <item>cbm_load <item>cbm_open <item>cbm_opendir diff --git a/doc/vic20.sgml b/doc/vic20.sgml index a61691733..1744a2b90 100644 --- a/doc/vic20.sgml +++ b/doc/vic20.sgml @@ -99,6 +99,7 @@ declaration and usage. <item>cbm_k_basin <item>cbm_k_bsout <item>cbm_k_clrch +<item>cbm_k_tksa <item>cbm_load <item>cbm_open <item>cbm_opendir diff --git a/include/cbm.h b/include/cbm.h index 1395f700f..fbf8d555a 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -204,6 +204,7 @@ void __fastcall__ cbm_k_setlfs (unsigned char LFN, unsigned char DEV, unsigned char SA); void __fastcall__ cbm_k_setnam (const char* Name); void __fastcall__ cbm_k_talk (unsigned char dev); +void __fastcall__ cbm_k_tksa (unsigned char addr); void cbm_k_udtim (void); void cbm_k_unlsn (void); void cbm_k_untlk (void); diff --git a/libsrc/cbm/c_tksa.s b/libsrc/cbm/c_tksa.s new file mode 100644 index 000000000..b818d7205 --- /dev/null +++ b/libsrc/cbm/c_tksa.s @@ -0,0 +1,12 @@ +; +; Bas Wassink, 22.05.2018 +; +; void __fastcall__ cbm_k_tksa (unsigned char addr) +; + + + .import TKSA + .export _cbm_k_tksa + +_cbm_k_tksa = TKSA + From ba2c6d9008d931cd2fcf83d4e01fa3f2c2972f7b Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Tue, 22 May 2018 15:59:05 +0200 Subject: [PATCH 0705/2161] Further optimizations in common/conio. --- libsrc/common/ltoa.s | 92 +++++++++++++++++++---------------------- libsrc/common/strcspn.s | 19 ++++----- libsrc/common/strlen.s | 12 +++--- libsrc/common/strspn.s | 19 ++++----- libsrc/conio/scrsize.s | 27 ++++++------ 5 files changed, 81 insertions(+), 88 deletions(-) diff --git a/libsrc/common/ltoa.s b/libsrc/common/ltoa.s index 5dc215bd1..54b693ecc 100644 --- a/libsrc/common/ltoa.s +++ b/libsrc/common/ltoa.s @@ -6,11 +6,11 @@ ; .export _ltoa, _ultoa - .import popax + .import popax, popptr1, negeax .import __hextab, __longminstr .importzp sreg, ptr1, ptr2, ptr3, tmp1 - + .macpack cpu .code @@ -19,17 +19,15 @@ ; dopop: sta tmp1 ; will loose high byte - jsr popax ; get s - sta ptr1 - stx ptr1+1 - sta sreg ; save for return - stx sreg+1 - jsr popax ; get low word of value + jsr popax ; get s to ptr2 sta ptr2 stx ptr2+1 - jsr popax ; get high word of value - sta ptr3 + sta ptr3 ; save for return stx ptr3+1 + jsr popptr1 ; get low word of value to ptr1 + jsr popax ; get high word of value to sreg + sta sreg + stx sreg+1 rts ; @@ -41,20 +39,20 @@ _ltoa: jsr dopop ; pop the arguments ; We must handle $80000000 in a special way, since it is the only negative ; number that has no positive 32-bit counterpart - ldx ptr3+1 ; get high byte + ldx sreg+1 ; get high byte ldy tmp1 ; get radix cpy #10 bne ultoa - lda ptr3 - ora ptr2+1 - ora ptr2 + lda sreg + ora ptr1+1 + ora ptr1 bne L2 cpx #$80 bne L2 ldy #11 L1: lda __longminstr,y ; copy -2147483648 - sta (ptr1),y + sta (ptr2),y dey bpl L1 jmp L10 @@ -65,29 +63,25 @@ L1: lda __longminstr,y ; copy -2147483648 L2: txa ; get high byte bpl ultoa lda #'-' - ldy #0 - sta (ptr1),y ; store sign - inc ptr1 - bne L3 - inc ptr1+1 -L3: lda ptr2 ; negate val - eor #$FF - clc - adc #$01 - sta ptr2 - lda ptr2+1 - eor #$FF - adc #$00 - sta ptr2+1 - lda ptr3 - eor #$FF - adc #$00 - sta ptr3 - lda ptr3+1 - eor #$FF - adc #$00 - sta ptr3+1 +.if (.cpu .bitand CPU_ISET_65SC02) + sta (ptr2) +.else + ldy #0 + sta (ptr2),y ; store sign +.endif + + inc ptr2 + bne L3 + inc ptr2+1 + +L3: lda ptr1 ; negate val + ldx ptr1+1 + + jsr negeax + + sta ptr1 + stx ptr1+1 jmp ultoa ; @@ -105,15 +99,15 @@ ultoa: lda #$00 L5: ldy #32 ; 32 bit lda #0 ; remainder -L6: asl ptr2 - rol ptr2+1 - rol ptr3 - rol ptr3+1 +L6: asl ptr1 + rol ptr1+1 + rol sreg + rol sreg+1 rol a cmp tmp1 bcc L7 sbc tmp1 - inc ptr2 + inc ptr1 L7: dey bne L6 @@ -121,25 +115,25 @@ L7: dey lda __hextab,y ; get hex character pha ; save char value on stack - lda ptr2 - ora ptr2+1 - ora ptr3 - ora ptr3+1 + lda ptr1 + ora ptr1+1 + ora sreg + ora sreg+1 bne L5 ; Get the characters from the stack into the string ldy #0 L9: pla - sta (ptr1),y + sta (ptr2),y beq L10 ; jump if sentinel iny bne L9 ; jump always ; Done! Return the target string -L10: lda sreg - ldx sreg+1 +L10: lda ptr3 + ldx ptr3+1 rts diff --git a/libsrc/common/strcspn.s b/libsrc/common/strcspn.s index c9122dc90..9cf159218 100644 --- a/libsrc/common/strcspn.s +++ b/libsrc/common/strcspn.s @@ -6,40 +6,39 @@ ; .export _strcspn - .import popax, _strlen + .import popptr1, _strlen .importzp ptr1, ptr2, tmp1, tmp2 _strcspn: - jsr _strlen ; get length in a/x and transfer s2 to ptr1 + jsr _strlen ; get length in a/x and transfer s2 to ptr2 ; Note: It does not make sense to ; have more than 255 test chars, so - ; we don't support a high byte here! (ptr1+1 is + ; we don't support a high byte here! (ptr2+1 is ; also unchanged in strlen then (important!)) ; -> the original implementation also ; ignored this case sta tmp1 ; tmp1 = strlen of test chars - jsr popax ; get and save s1 - sta ptr2 ; to ptr2 - stx ptr2+1 + jsr popptr1 ; get and save s1 to ptr1 + ldx #0 ; low counter byte stx tmp2 ; high counter byte loadChar: ldy #0 - lda (ptr2),y ; get next char from s1 + lda (ptr1),y ; get next char from s1 beq leave ; handly byte of s1 advance: - inc ptr2 ; advance string position to test + inc ptr1 ; advance string position to test bne check - inc ptr2+1 + inc ptr1+1 dey ; correct next iny (faster/shorter than bne...) checkNext: iny check: cpy tmp1 ; compare with length of test character string beq endOfTestChars - cmp (ptr1),y ; found matching char? + cmp (ptr2),y ; found matching char? bne checkNext leave: txa ; restore position of finding diff --git a/libsrc/common/strlen.s b/libsrc/common/strlen.s index 1a51edb11..e89039179 100644 --- a/libsrc/common/strlen.s +++ b/libsrc/common/strlen.s @@ -2,26 +2,26 @@ ; Ullrich von Bassewitz, 31.05.1998 ; ; Note: strspn & strcspn call internally this function and rely on -; the usage of only ptr1 here! Keep in mind when appling changes +; the usage of only ptr2 here! Keep in mind when appling changes ; and check the other implementations too! ; ; int strlen (const char* s); ; .export _strlen - .importzp ptr1 + .importzp ptr2 _strlen: - sta ptr1 ; Save s - stx ptr1+1 + sta ptr2 ; Save s + stx ptr2+1 ldx #0 ; YX used as counter ldy #0 -L1: lda (ptr1),y +L1: lda (ptr2),y beq L9 iny bne L1 - inc ptr1+1 + inc ptr2+1 inx bne L1 diff --git a/libsrc/common/strspn.s b/libsrc/common/strspn.s index 079b935ee..6fda716be 100644 --- a/libsrc/common/strspn.s +++ b/libsrc/common/strspn.s @@ -6,40 +6,39 @@ ; .export _strspn - .import popax, _strlen + .import popptr1, _strlen .importzp ptr1, ptr2, tmp1, tmp2 _strspn: - jsr _strlen ; get length in a/x and transfer s2 to ptr1 + jsr _strlen ; get length in a/x and transfer s2 to ptr2 ; Note: It does not make sense to ; have more than 255 test chars, so - ; we don't support a high byte here! (ptr1+1 is + ; we don't support a high byte here! (ptr2+1 is ; also unchanged in strlen then (important!)) ; -> the original implementation also ; ignored this case sta tmp1 ; tmp1 = strlen of test chars - jsr popax ; get and save s1 - sta ptr2 ; to ptr2 - stx ptr2+1 + jsr popptr1 ; get and save s1 to ptr1 + ldx #0 ; low counter byte stx tmp2 ; high counter byte loadChar: ldy #0 - lda (ptr2),y ; get next char from s1 + lda (ptr1),y ; get next char from s1 beq leave ; handly byte of s1 advance: - inc ptr2 ; advance string position to test + inc ptr1 ; advance string position to test bne check - inc ptr2+1 + inc ptr1+1 dey ; correct next iny (faster/shorter than bne...) checkNext: iny check: cpy tmp1 ; compare with length of test character string beq leave - cmp (ptr1),y ; found matching char? + cmp (ptr2),y ; found matching char? bne checkNext foundTestChar: diff --git a/libsrc/conio/scrsize.s b/libsrc/conio/scrsize.s index 6582568d7..014b6f08b 100644 --- a/libsrc/conio/scrsize.s +++ b/libsrc/conio/scrsize.s @@ -6,29 +6,30 @@ .export _screensize - .import popsreg + .import popptr1 .import screensize - .importzp ptr1, sreg + .importzp ptr1, ptr2 + + .macpack cpu .proc _screensize - sta ptr1 ; Store the y pointer - stx ptr1+1 - jsr popsreg ; Get the x pointer into sreg + sta ptr2 ; Store the y pointer + stx ptr2+1 + jsr popptr1 ; Get the x pointer into ptr1 jsr screensize ; Get screensize into X/Y tya ; Get Y size into A -.IFP02 - ldy #0 - sta (ptr1),y +.if (.cpu .bitand ::CPU_ISET_65SC02) + sta (ptr2) txa - sta (sreg),y -.ELSE sta (ptr1) +.else + ldy #0 + sta (ptr2),y txa - sta (sreg) -.ENDIF - + sta (ptr1),y +.endif rts .endproc From 808d3ab4714c2bf393b0befddafe2a7ea7897289 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Tue, 22 May 2018 18:35:05 +0200 Subject: [PATCH 0706/2161] Fix for 8x16 multiplication if operants are swapped. --- libsrc/runtime/mul.s | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libsrc/runtime/mul.s b/libsrc/runtime/mul.s index a9b53293b..769cf9d8e 100644 --- a/libsrc/runtime/mul.s +++ b/libsrc/runtime/mul.s @@ -62,7 +62,8 @@ tosumulax: @L4: ldy ptr1 ; Save right operand (8 bit) ldx ptr4 ; Copy left 16 bit operand to right stx ptr1 - ldx ptr4+1 ; Don't store, this is done later + ldx ptr4+1 ; swap high-byte too + stx ptr1+1 sty ptr4 ; Copy low 8 bit of right op to left ldy #8 jmp mul8x16a From e3a8cfcdb0f931c707062fc406e924eb26ec8c70 Mon Sep 17 00:00:00 2001 From: compyx <b.wassink@ziggo.nl> Date: Tue, 22 May 2018 18:48:43 +0200 Subject: [PATCH 0707/2161] cbm_k_tksa() from the PET docs --- doc/pet.sgml | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/pet.sgml b/doc/pet.sgml index fef2d14ec..fd61716dd 100644 --- a/doc/pet.sgml +++ b/doc/pet.sgml @@ -99,7 +99,6 @@ declaration and usage. <item>cbm_k_basin <item>cbm_k_bsout <item>cbm_k_clrch -<item>cbm_k_tksa <item>cbm_load <item>cbm_open <item>cbm_opendir From 6175271651d769610d5aa3fbd46b6ad61ee56056 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Tue, 22 May 2018 19:10:07 +0200 Subject: [PATCH 0708/2161] Removed optimizations which break the compiler ones. --- libsrc/runtime/mulax3.s | 4 ++-- libsrc/runtime/mulax5.s | 5 +++-- libsrc/runtime/mulax7.s | 5 +++-- libsrc/runtime/mulax9.s | 5 +++-- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/libsrc/runtime/mulax3.s b/libsrc/runtime/mulax3.s index 82cc033c3..472bc60ec 100644 --- a/libsrc/runtime/mulax3.s +++ b/libsrc/runtime/mulax3.s @@ -15,11 +15,11 @@ rol ptr1+1 clc adc ptr1 - tay + pha txa adc ptr1+1 tax - tya + pla rts .endproc diff --git a/libsrc/runtime/mulax5.s b/libsrc/runtime/mulax5.s index bf5eaefe8..99f0ffce0 100644 --- a/libsrc/runtime/mulax5.s +++ b/libsrc/runtime/mulax5.s @@ -3,6 +3,7 @@ ; ; CC65 runtime: Multiply the primary register by 5 ; +; Don't touch the Y-register here, the optimizer relies on it! .export mulax5 .importzp ptr1 @@ -17,11 +18,11 @@ rol ptr1+1 clc adc ptr1 - tay + pha txa adc ptr1+1 tax - tya + pla rts .endproc diff --git a/libsrc/runtime/mulax7.s b/libsrc/runtime/mulax7.s index 3414ebc9e..6f2b2bf61 100644 --- a/libsrc/runtime/mulax7.s +++ b/libsrc/runtime/mulax7.s @@ -4,6 +4,7 @@ ; ; CC65 runtime: Multiply the primary register by 7 ; +; Don't touch the Y-register here, the optimizer relies on it! .export mulax7 .importzp ptr1 @@ -20,12 +21,12 @@ rol ptr1+1 ; * 8 sec sbc ptr1 - tay + pha txa eor #$ff adc ptr1+1 ; * (8 - 1) tax - tya + pla rts .endproc diff --git a/libsrc/runtime/mulax9.s b/libsrc/runtime/mulax9.s index d175d55aa..064eb458b 100644 --- a/libsrc/runtime/mulax9.s +++ b/libsrc/runtime/mulax9.s @@ -4,6 +4,7 @@ ; ; CC65 runtime: Multiply the primary register by 9 ; +; Don't touch the Y-register here, the optimizer relies on it! .export mulax9 .importzp ptr1 @@ -20,11 +21,11 @@ rol ptr1+1 ; * 8 clc adc ptr1 ; * (8+1) - tay + pha txa adc ptr1+1 tax - tya + pla rts .endproc From b945beb6a7c4688747de73d6f35eb890b257fdaf Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 22 May 2018 21:18:10 +0000 Subject: [PATCH 0709/2161] Indicate a dummy outtext --- libsrc/apple2/tgi/a2.lo.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/apple2/tgi/a2.lo.s b/libsrc/apple2/tgi/a2.lo.s index 7238463a9..2f5485e02 100644 --- a/libsrc/apple2/tgi/a2.lo.s +++ b/libsrc/apple2/tgi/a2.lo.s @@ -58,8 +58,8 @@ Y2 := ptr4 .word 48 ; Y resolution .byte 16 ; Number of drawing colors .byte 1 ; Number of screens available - .byte 8 ; System font X size - .byte 8 ; System font Y size + .byte 0 ; System font X size + .byte 0 ; System font Y size .word $0198 ; Aspect ratio (based on 4/3 display) .byte 0 ; TGI driver flags From a4c06f25725476b10311c5b09be0c354a97e79cf Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 22 May 2018 22:32:50 +0000 Subject: [PATCH 0710/2161] Clean-up because of tgidrv_line.inc --- libsrc/nes/tgi/nes-64-56-2.s | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/libsrc/nes/tgi/nes-64-56-2.s b/libsrc/nes/tgi/nes-64-56-2.s index e4dcb56ce..e6b7c5437 100644 --- a/libsrc/nes/tgi/nes-64-56-2.s +++ b/libsrc/nes/tgi/nes-64-56-2.s @@ -79,12 +79,6 @@ TEMP2 = tmp4 TEMP3 = sreg TEMP4 = sreg+1 -; Line routine stuff (must be on zpage) -PB = ptr3 ; (2) LINE -UB = ptr4 ; (2) LINE -ERR = regsave ; (2) LINE -NX = regsave+2 ; (2) LINE - ; Absolute variables used in the code .bss @@ -95,17 +89,6 @@ ERROR: .res 1 ; Error code COLOR: .res 1 ; Current color PALETTE: .res 2 ; The current palette -; Line routine stuff - -OGora: -COUNT: .res 2 -OUkos: -NY: .res 2 -Y3: -DX: .res 1 -DY: .res 1 -AY: .res 1 - ; Constants and tables .rodata @@ -242,6 +225,7 @@ SETCOLOR: ; SETVIEWPAGE: +; rts ; ------------------------------------------------------------------------ ; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n). From 37e6b05b4a29a64ff6a9465f633731dee9a60779 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 23 May 2018 01:51:54 +0000 Subject: [PATCH 0711/2161] Fixed typos and added references for #655 --- doc/funcref.sgml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index f10379c93..a5ee689f5 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -357,6 +357,9 @@ function. <sect1><tt/em.h/<label id="em.h"><p> +This header file contains definitions for extended memory access, +see also <tt/testcode/lib/em-test.c/ and <tt/samples/multidemo.c/. + <itemize> <item><ref id="em_commit" name="em_commit"> <item><ref id="em_copyfrom" name="em_copyfrom"> @@ -543,8 +546,8 @@ It does not declare any functions. <sect1><tt/serial.h/<label id="serial.h"><p> -The <tt/serial.h/ header file contains definitions for initializing serial -communication. +This header file contains definitions for initializing serial +communication, see also <tt/testcode/lib/ser-test.c/. <itemize> <item><ref id="ser_close" name="ser_close"> @@ -5843,7 +5846,7 @@ if (rename (OLDNAME, NEWNAME) == 0) { before a call to <tt/set_brk/. <tag/Notes/<itemize> <item>The break vector is reset on program termination, so it's not strictly -necessary to call this function as a part of your clean-up when exitting the program. +necessary to call this function as a part of your clean-up when exiting the program. </itemize> <tag/Availability/cc65 <tag/See also/ @@ -5865,7 +5868,7 @@ necessary to call this function as a part of your clean-up when exitting the pro <tag/Description/<tt/reset_irq/ resets the C level interrupt request vector. <tag/Notes/<itemize> <item>The interrupt vector is reset on program termination, so it's not strictly -necessary to call this function as a part of your clean-up when exitting the program. +necessary to call this function as a part of your clean-up when exiting the program. </itemize> <tag/Availability/cc65 <tag/See also/ @@ -6226,7 +6229,7 @@ the continue with the interrupted code, you have to adjust <tt/brk_pc/, otherwise the <tt/BRK/ instruction will get executed over and over again. <item>The break vector is reset on program termination, so it's not strictly necessary to call <tt/<ref id="reset_brk" name="reset_brk">/ as a part of your -clean-up when exitting the program. +clean-up when exiting the program. </itemize> <tag/Availability/cc65 <tag/See also/ @@ -6264,7 +6267,7 @@ enable stack checks for the handler function or any other function called from it. <item>The interrupt vector is reset on program termination, so it's not strictly necessary to call <tt/<ref id="reset_irq" name="reset_irq">/ as a part of your -clean-up when exitting the program. +clean-up when exiting the program. </itemize> <tag/Availability/cc65 <tag/See also/ From 9e4833e21fd7043f5279c5fc42ba1c9598f4253c Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 23 May 2018 04:27:05 +0000 Subject: [PATCH 0712/2161] Added documentation of cbm_k_untlk --- doc/funcref.sgml | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index a5ee689f5..a2014323e 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -205,6 +205,7 @@ function. <item><ref id="cbm_k_talk" name="cbm_k_talk"> <item><ref id="cbm_k_udtim" name="cbm_k_udtim"> <item><ref id="cbm_k_unlsn" name="cbm_k_unlsn"> +<item><ref id="cbm_k_untlk" name="cbm_k_untlk"> <!-- <item><ref id="cbm_load" name="cbm_load"> --> <!-- <item><ref id="cbm_open" name="cbm_open"> --> <!-- <item><ref id="cbm_opendir" name="cbm_opendir"> --> @@ -2090,7 +2091,7 @@ only be used in presence of a prototype. </itemize> <tag/Availability/cc65 <tag/See also/ -<ref id="cbm_k_unlsn" name="cbm_k_unlsn">, +<ref id="cbm_k_unlsn" name="cbm_k_unlsn"> <tag/Example/None. </descrip> </quote> @@ -2322,9 +2323,6 @@ bus. Only devices previously commanded to LISTEN are affected. This function is normally used after the host computer is finished sending data to external devices. Sending the UNLISTEN commands the listening devices to get off the serial bus so it can be used for other purposes. -<tag/Notes/<itemize> -<item> -</itemize> <tag/Availability/cc65 <tag/See also/ <ref id="cbm_k_listen" name="cbm_k_listen"> @@ -2333,6 +2331,28 @@ to get off the serial bus so it can be used for other purposes. </quote> +<sect1>cbm_k_untlk<label id="cbm_k_untlk"><p> + +<quote> +<descrip> +<tag/Function/Send an UNTALK command +<tag/Header/<tt/<ref id="cbm.h" name="cbm.h">/ +<tag/Declaration/<tt/void cbm_k_untlk (void);/ +<tag/Description/This function commands all devices on the serial bus to +stop sending data to the host computer (i.e., UNTALK). Calling this +function results in an UNTALK command being transmitted on the serial +bus. Only devices previously commanded to TALK are affected. This +function is normally used after the host computer is finished listening data +to external devices. Sending the UNTALK commands the sending devices +to get off the serial bus so it can be used for other purposes. +<tag/Availability/cc65 +<tag/See also/ +<ref id="cbm_k_talk" name="cbm_k_talk"> +<tag/Example/None. +</descrip> +</quote> + + <sect1>cclear<label id="cclear"><p> <quote> From 1dcd4a19ea88fda760fae6bc9415966109d6a95a Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 23 May 2018 04:51:32 +0000 Subject: [PATCH 0713/2161] More references --- doc/tgi.sgml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/tgi.sgml b/doc/tgi.sgml index cf90fd198..0fef963f3 100644 --- a/doc/tgi.sgml +++ b/doc/tgi.sgml @@ -9,7 +9,8 @@ <abstract> The cc65 library provides functions for platform independent graphics. -Include the tgi.h header file to get the necessary definitions. +Include the tgi.h header file to get the necessary definitions, see also +<tt/samples/tgidemo.c/ and <tt/samples/mandelbrot.c/. </abstract> <!-- Begin the document --> From 0a1e68d7a92a0d83301d5cfd6e7daef0cdbd4780 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 23 May 2018 13:30:57 +0000 Subject: [PATCH 0714/2161] Update funcref.sgml --- doc/funcref.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index a2014323e..786f54cbd 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -359,7 +359,7 @@ function. <sect1><tt/em.h/<label id="em.h"><p> This header file contains definitions for extended memory access, -see also <tt/testcode/lib/em-test.c/ and <tt/samples/multidemo.c/. +see also <tt>testcode/lib/em-test.c</tt> and <tt>samples/multidemo.c</tt>. <itemize> <item><ref id="em_commit" name="em_commit"> From 714a347dc9371fd8017ffd1d5e37042bad3e9ef1 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 23 May 2018 13:32:17 +0000 Subject: [PATCH 0715/2161] Update funcref.sgml --- doc/funcref.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 786f54cbd..81da3ce80 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -548,7 +548,7 @@ It does not declare any functions. <sect1><tt/serial.h/<label id="serial.h"><p> This header file contains definitions for initializing serial -communication, see also <tt/testcode/lib/ser-test.c/. +communication, see also <tt>testcode/lib/ser-test.c</tt>. <itemize> <item><ref id="ser_close" name="ser_close"> From 21a69c8affc6e39a1042d4a34ca9d7210f488daf Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 23 May 2018 13:34:37 +0000 Subject: [PATCH 0716/2161] Update tgi.sgml --- doc/tgi.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tgi.sgml b/doc/tgi.sgml index 0fef963f3..d20df40d1 100644 --- a/doc/tgi.sgml +++ b/doc/tgi.sgml @@ -10,7 +10,7 @@ <abstract> The cc65 library provides functions for platform independent graphics. Include the tgi.h header file to get the necessary definitions, see also -<tt/samples/tgidemo.c/ and <tt/samples/mandelbrot.c/. +<tt>samples/tgidemo.c</tt> and <tt>samples/mandelbrot.c</tt>. </abstract> <!-- Begin the document --> From d28fce082d1c8c2573b3725de7c08ec60af1f62e Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 23 May 2018 13:40:14 +0000 Subject: [PATCH 0717/2161] Update funcref.sgml --- doc/funcref.sgml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 81da3ce80..be6e92ebd 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -4,7 +4,7 @@ <title>cc65 function reference <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2018-02-07 +<date>2018-05-23 <abstract> cc65 is a C compiler for 6502 based systems. This function reference describes @@ -2342,8 +2342,8 @@ to get off the serial bus so it can be used for other purposes. stop sending data to the host computer (i.e., UNTALK). Calling this function results in an UNTALK command being transmitted on the serial bus. Only devices previously commanded to TALK are affected. This -function is normally used after the host computer is finished listening data -to external devices. Sending the UNTALK commands the sending devices +function is normally used after the host computer is finished listening to data +from an external device. Sending the UNTALK commands the sending devices to get off the serial bus so it can be used for other purposes. <tag/Availability/cc65 <tag/See also/ From 8ffe623e74c1eba90d580d0cad5abe00a90e1d3a Mon Sep 17 00:00:00 2001 From: compyx <b.wassink@ziggo.nl> Date: Wed, 23 May 2018 17:32:02 +0200 Subject: [PATCH 0718/2161] Add CBM kernal call SECOND to CBM library (see issue #525) --- doc/c128.sgml | 1 + doc/c16.sgml | 1 + doc/c64.sgml | 1 + doc/cbm510.sgml | 1 + doc/cbm610.sgml | 1 + doc/funcref.sgml | 26 ++++++++++++++++++++++++++ doc/plus4.sgml | 1 + doc/vic20.sgml | 1 + libsrc/cbm/c_second.s | 12 ++++++++++++ 9 files changed, 45 insertions(+) create mode 100644 libsrc/cbm/c_second.s diff --git a/doc/c128.sgml b/doc/c128.sgml index feda1cbba..abb9dbf25 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -125,6 +125,7 @@ declaration and usage. <item>cbm_k_bsout <item>cbm_k_clrch <item>cbm_k_tksa +<item>cbm_k_second <item>cbm_load <item>cbm_open <item>cbm_opendir diff --git a/doc/c16.sgml b/doc/c16.sgml index 6375a7898..aaf497d42 100644 --- a/doc/c16.sgml +++ b/doc/c16.sgml @@ -116,6 +116,7 @@ declaration and usage. <item>cbm_k_bsout <item>cbm_k_clrch <item>cbm_k_tksa +<item>cbm_k_second <item>cbm_load <item>cbm_open <item>cbm_opendir diff --git a/doc/c64.sgml b/doc/c64.sgml index b04b40508..a0043d3ad 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -218,6 +218,7 @@ declaration and usage. <item>cbm_k_bsout <item>cbm_k_clrch <item>cbm_k_tksa +<item>cbm_k_second <item>cbm_load <item>cbm_open <item>cbm_opendir diff --git a/doc/cbm510.sgml b/doc/cbm510.sgml index 1e6a4e07b..d38d35d29 100644 --- a/doc/cbm510.sgml +++ b/doc/cbm510.sgml @@ -119,6 +119,7 @@ declaration and usage. <item>cbm_k_bsout <item>cbm_k_clrch <item>cbm_k_tksa +<item>cbm_k_second <item>cbm_load <item>cbm_open <item>cbm_opendir diff --git a/doc/cbm610.sgml b/doc/cbm610.sgml index 9f963dbd5..44c9155a5 100644 --- a/doc/cbm610.sgml +++ b/doc/cbm610.sgml @@ -122,6 +122,7 @@ declaration and usage. <item>cbm_k_bsout <item>cbm_k_clrch <item>cbm_k_tksa +<item>cbm_k_second <item>cbm_load <item>cbm_open <item>cbm_opendir diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 4a6e13c5e..85e75b43f 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -200,6 +200,7 @@ function. <item><ref id="cbm_k_readst" name="cbm_k_readst"> <item><ref id="cbm_k_save" name="cbm_k_save"> <item><ref id="cbm_k_scnkey" name="cbm_k_scnkey"> +<item><ref id="cbm_k_second" name="cbm_k_second"> <item><ref id="cbm_k_setlfs" name="cbm_k_setlfs"> <item><ref id="cbm_k_setnam" name="cbm_k_setnam"> <item><ref id="cbm_k_talk" name="cbm_k_talk"> @@ -2224,6 +2225,31 @@ function, in order to provide input from the keyboard. </quote> +<sect1>cmb_k_second<label id="cbm_k_second"><p> + +<quote> +<descrip> +<tag/Function/Send secondary address for LISTEN. +<tag/Header/<tt/<ref id="cbm.h" name="cbm.h">/ +<tag/Declaration/<tt/void cbm_k_second (unsigned char addr);/ +<tag/Description/This function is used to send a secondary address to an I/O +device after a call to LISTEN is made, and the device is commanded to LISTEN. +<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 function can only be called after a call to LISTEN. +<item>The function will not work after a TALK. +<item>When a secondary address is to be sent to a device on the serial bus, +the address must first be ORed with $60. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="cbm_k_listen" name="cbm_k_listen"> +<tag/Exampe/None. +</descrip> +</quote> + + <sect1>cbm_k_setlfs<label id="cbm_k_setlfs"><p> <quote> diff --git a/doc/plus4.sgml b/doc/plus4.sgml index 333bd879a..ed5fa3d4e 100644 --- a/doc/plus4.sgml +++ b/doc/plus4.sgml @@ -114,6 +114,7 @@ declaration and usage. <item>cbm_k_bsout <item>cbm_k_clrch <item>cbm_k_tksa +<item>cbm_k_second <item>cbm_load <item>cbm_open <item>cbm_opendir diff --git a/doc/vic20.sgml b/doc/vic20.sgml index 1744a2b90..79c2fb898 100644 --- a/doc/vic20.sgml +++ b/doc/vic20.sgml @@ -100,6 +100,7 @@ declaration and usage. <item>cbm_k_bsout <item>cbm_k_clrch <item>cbm_k_tksa +<item>cbm_k_second <item>cbm_load <item>cbm_open <item>cbm_opendir diff --git a/libsrc/cbm/c_second.s b/libsrc/cbm/c_second.s new file mode 100644 index 000000000..b5cc98c80 --- /dev/null +++ b/libsrc/cbm/c_second.s @@ -0,0 +1,12 @@ +; +; Bas Wassink, 23.05.2018 +; +; void __fastcall__ cbm_k_second (unsigned char addr) +; + + + .import SECOND + .export _cbm_k_second + +_cbm_k_second = SECOND + From dade099b9d927fb84bbe2da2f5f8bdb5ba223099 Mon Sep 17 00:00:00 2001 From: compyx <b.wassink@ziggo.nl> Date: Wed, 23 May 2018 17:37:48 +0200 Subject: [PATCH 0719/2161] CBM kernal call SECOND, update cbm.h --- include/cbm.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/cbm.h b/include/cbm.h index fbf8d555a..0a2d64694 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -200,6 +200,7 @@ unsigned char cbm_k_open (void); unsigned char cbm_k_readst (void); unsigned char __fastcall__ cbm_k_save(unsigned int start, unsigned int end); void cbm_k_scnkey (void); +void __fastcall__ cbm_k_second (unsigned char addr); void __fastcall__ cbm_k_setlfs (unsigned char LFN, unsigned char DEV, unsigned char SA); void __fastcall__ cbm_k_setnam (const char* Name); From dd411efd1c60e83505a74d57d9ef5065b322b9be Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Thu, 24 May 2018 03:55:40 +0200 Subject: [PATCH 0720/2161] Adapted div & mod for popptr1. --- libsrc/common/abs.s | 16 ----------- libsrc/runtime/absvaludiv.s | 22 +++++++++++++++ libsrc/runtime/div.s | 40 +++++++++++--------------- libsrc/runtime/mod.s | 41 ++++++++++++--------------- libsrc/runtime/mulax3.s | 1 + libsrc/runtime/{neg.s => negabs.s} | 7 ++++- libsrc/runtime/shelp.s | 30 -------------------- libsrc/runtime/udiv.s | 45 +++++++++++++++--------------- libsrc/runtime/umod.s | 12 ++++---- 9 files changed, 92 insertions(+), 122 deletions(-) delete mode 100644 libsrc/common/abs.s create mode 100644 libsrc/runtime/absvaludiv.s rename libsrc/runtime/{neg.s => negabs.s} (59%) delete mode 100644 libsrc/runtime/shelp.s diff --git a/libsrc/common/abs.s b/libsrc/common/abs.s deleted file mode 100644 index 5daa8a14a..000000000 --- a/libsrc/common/abs.s +++ /dev/null @@ -1,16 +0,0 @@ -; -; Ullrich von Bassewitz, 17.06.1998 -; -; int abs (int x); -; - - .export _abs - .import negax - -_abs: cpx #$00 ; test hi byte - bpl L1 - jmp negax ; Negate if negative -L1: rts - - - diff --git a/libsrc/runtime/absvaludiv.s b/libsrc/runtime/absvaludiv.s new file mode 100644 index 000000000..d23b8c00e --- /dev/null +++ b/libsrc/runtime/absvaludiv.s @@ -0,0 +1,22 @@ +; +; Christian Krueger, 23-May-2018 +; +; CC65 runtime: helper call for mod/div with signed ints +; +; When negating values, we will ignore the possibility here, that one of the +; values is $8000, in which case the negate will fail. + + .export absvaludiv + .import _abs, popax, udiv16 + .importzp ptr1, ptr4 + + +absvaludiv: + jsr _abs + sta ptr4 + stx ptr4+1 ; Save right absolute operand + jsr popax + jsr _abs + sta ptr1 + stx ptr1+1 ; Save left absolute operand + jmp udiv16 diff --git a/libsrc/runtime/div.s b/libsrc/runtime/div.s index cdd340272..54da0c7e4 100644 --- a/libsrc/runtime/div.s +++ b/libsrc/runtime/div.s @@ -1,37 +1,29 @@ ; -; Ullrich von Bassewitz, 07.08.1998 +; Christian Krueger, 24-May-2018 ; ; CC65 runtime: division for signed ints ; ; When negating values, we will ignore the possibility here, that one of the -; values if $8000, in which case the negate will fail. +; values is $8000, in which case the negate will fail. .export tosdiva0, tosdivax - .import popsargs, udiv16, negax - .importzp sreg, tmp1, tmp2 + .import absvaludiv, negax + .importzp sp, ptr1, tmp1 tosdiva0: ldx #0 tosdivax: - jsr popsargs ; Get arguments from stack, adjust sign - jsr udiv16 ; Do the division - ldx sreg+1 ; Load high byte of result - -; Adjust the sign of the result. tmp1 contains the high byte of the left -; operand, tmp2 contains the high byte of the right operand. - - lda tmp1 - eor tmp2 - bpl Pos ; Jump if sign of result positive - -; Result is negative - - lda sreg ; Load low byte of result - jmp negax ; Adjust the sign - -; Result is positive - -Pos: lda sreg + pha ; check if high-bytes indicate + txa ; different sign, so that we + ldy #1 ; negate the result after the operation + eor (sp),y ; eor with lhs high byte + sta tmp1 ; save post negation indicator to tmp1 + pla ; back to entry accu + jsr absvaludiv + ldx ptr1+1 + lda ptr1 + ldy tmp1 ; fetch idicator + bmi negate rts - +negate: jmp negax diff --git a/libsrc/runtime/mod.s b/libsrc/runtime/mod.s index c4331ed85..b3a818fda 100644 --- a/libsrc/runtime/mod.s +++ b/libsrc/runtime/mod.s @@ -1,37 +1,32 @@ ; -; Ullrich von Bassewitz, 07.08.1998 +; Christian Krueger, 24-May-2018 ; ; CC65 runtime: modulo operation for signed ints ; ; When negating values, we will ignore the possibility here, that one of the -; values if $8000, in which case the negate will fail. +; values is $8000, in which case the negate will fail. .export tosmoda0, tosmodax - .import popsargs, udiv16, negax - .importzp ptr1, tmp1 + .import absvaludiv, negax + .importzp sp, sreg, tmp1 tosmoda0: ldx #0 tosmodax: - jsr popsargs ; Get arguments from stack, adjust sign - jsr udiv16 ; Do the division - lda ptr1 ; Load low byte of result - ldx ptr1+1 ; Load high byte of result -; Adjust the sign of the result. tmp1 contains the high byte of the left -; operand, tmp2 contains the high byte of the right operand. The sign of -; the result of the modulo operation is the same as that of the left -; operand - - bit tmp1 - bpl Pos ; Jump if sign of result positive - -; Result is negative - - jmp negax ; Adjust the sign - -; Result is positive - -Pos: rts +; Prepare adjustment of the sign of the result. The sign of the result of the +; modulo operation is the same as that of the left operand. + pha + ldy #1 ; prepare lhs operant hi-byte fetch + lda (sp),y + sta tmp1 ; save post negation indicator to tmp1 + pla ; back to entry accu + jsr absvaludiv + ldx sreg+1 ; remainder to return registers + lda sreg + ldy tmp1 ; fetch idicator + bmi negate + rts +negate: jmp negax diff --git a/libsrc/runtime/mulax3.s b/libsrc/runtime/mulax3.s index 472bc60ec..513ba723e 100644 --- a/libsrc/runtime/mulax3.s +++ b/libsrc/runtime/mulax3.s @@ -3,6 +3,7 @@ ; ; CC65 runtime: Multiply the primary register by 3 ; +; Don't touch the Y-register here, the optimizer relies on it! .export mulax3 .importzp ptr1 diff --git a/libsrc/runtime/neg.s b/libsrc/runtime/negabs.s similarity index 59% rename from libsrc/runtime/neg.s rename to libsrc/runtime/negabs.s index a428fd1e4..5a9ca6e01 100644 --- a/libsrc/runtime/neg.s +++ b/libsrc/runtime/negabs.s @@ -1,11 +1,16 @@ ; ; Ullrich von Bassewitz, 05.08.1998 ; +; int abs (int x); +; and ; CC65 runtime: negation on ints ; .export negax + .export _abs +_abs: cpx #$00 ; test hi byte + bpl L1 ; don't touch if positive negax: clc eor #$FF adc #1 @@ -15,7 +20,7 @@ negax: clc adc #0 tax pla - rts + L1: rts diff --git a/libsrc/runtime/shelp.s b/libsrc/runtime/shelp.s deleted file mode 100644 index b1ebeb798..000000000 --- a/libsrc/runtime/shelp.s +++ /dev/null @@ -1,30 +0,0 @@ -; -; Ullrich von Bassewitz, 07.08.1998 -; -; CC65 runtime: helper stuff for mod/div/mul with signed ints -; - -; When negating values, we will ignore the possibility here, that one of the -; values if $8000, in which case the negate will fail. - - .export popsargs - .import negax, popax - .importzp sreg, tmp1, tmp2, ptr4 - -popsargs: - stx tmp2 ; Remember sign - cpx #0 - bpl L1 - jsr negax ; Negate accumulator -L1: sta ptr4 - stx ptr4+1 ; Save right operand - - jsr popax - stx tmp1 ; Remember sign - cpx #0 - bpl L2 - jsr negax -L2: sta sreg - stx sreg+1 - rts - diff --git a/libsrc/runtime/udiv.s b/libsrc/runtime/udiv.s index 93548d049..4115382c8 100644 --- a/libsrc/runtime/udiv.s +++ b/libsrc/runtime/udiv.s @@ -3,9 +3,10 @@ ; ; CC65 runtime: division for unsigned ints ; +; Don't use tmp1 here, the signed division tunnels data with it! .export tosudiva0, tosudivax, udiv16 - .import popsreg + .import popptr1 .importzp sreg, ptr1, ptr4 @@ -14,50 +15,50 @@ tosudiva0: tosudivax: sta ptr4 stx ptr4+1 ; Save right operand - jsr popsreg ; Get left operand + jsr popptr1 ; Get left operand ; Do the division jsr udiv16 -; Result is in sreg, remainder in ptr1 +; Result is in ptr1, remainder in sreg - lda sreg - ldx sreg+1 + lda ptr1 + ldx ptr1+1 rts ;--------------------------------------------------------------------------- -; 16by16 division. Divide sreg by ptr4. Result is in sreg, remainder in ptr1 +; 16by16 division. Divide ptr1 by ptr4. Result is in ptr1, remainder in sreg ; (see mult-div.s from "The Fridge"). ; This is also the entry point for the signed division udiv16: lda #0 - sta ptr1+1 + sta sreg+1 ldy #16 ldx ptr4+1 beq udiv16by8a -L0: asl sreg - rol sreg+1 - rol a +L0: asl ptr1 rol ptr1+1 + rol a + rol sreg+1 - pha + tax cmp ptr4 - lda ptr1+1 + lda sreg+1 sbc ptr4+1 bcc L1 - sta ptr1+1 - pla + sta sreg+1 + txa sbc ptr4 - pha - inc sreg + tax + inc ptr1 -L1: pla +L1: txa dey bne L0 - sta ptr1 + sta sreg rts @@ -65,18 +66,18 @@ L1: pla ; 16by8 division udiv16by8a: -@L0: asl sreg - rol sreg+1 +@L0: asl ptr1 + rol ptr1+1 rol a bcs @L1 cmp ptr4 bcc @L2 @L1: sbc ptr4 - inc sreg + inc ptr1 @L2: dey bne @L0 - sta ptr1 + sta sreg rts diff --git a/libsrc/runtime/umod.s b/libsrc/runtime/umod.s index 92ebb5f91..5788d569e 100644 --- a/libsrc/runtime/umod.s +++ b/libsrc/runtime/umod.s @@ -5,24 +5,24 @@ ; .export tosumoda0, tosumodax - .import popsreg, udiv16 - .importzp ptr1, ptr4 + .import popptr1, udiv16 + .importzp sreg, ptr4 tosumoda0: ldx #0 tosumodax: sta ptr4 stx ptr4+1 ; Save right operand - jsr popsreg ; Get right operand + jsr popptr1 ; Get right operand ; Do the division jsr udiv16 -; Result is in sreg, remainder in ptr1 +; Result is in ptr1, remainder in sreg - lda ptr1 - ldx ptr1+1 + lda sreg + ldx sreg+1 rts From 9c1cb0801c79e7a87f6b17a667b304624b896e9d Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Thu, 24 May 2018 11:31:43 +0200 Subject: [PATCH 0721/2161] Changed naming absvaludiv -> absvaludiv16. --- libsrc/runtime/absvaludiv.s | 4 ++-- libsrc/runtime/div.s | 6 +++--- libsrc/runtime/mod.s | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libsrc/runtime/absvaludiv.s b/libsrc/runtime/absvaludiv.s index d23b8c00e..59c2914b1 100644 --- a/libsrc/runtime/absvaludiv.s +++ b/libsrc/runtime/absvaludiv.s @@ -6,12 +6,12 @@ ; When negating values, we will ignore the possibility here, that one of the ; values is $8000, in which case the negate will fail. - .export absvaludiv + .export absvaludiv16 .import _abs, popax, udiv16 .importzp ptr1, ptr4 -absvaludiv: +absvaludiv16: jsr _abs sta ptr4 stx ptr4+1 ; Save right absolute operand diff --git a/libsrc/runtime/div.s b/libsrc/runtime/div.s index 54da0c7e4..b33d852db 100644 --- a/libsrc/runtime/div.s +++ b/libsrc/runtime/div.s @@ -8,7 +8,7 @@ ; values is $8000, in which case the negate will fail. .export tosdiva0, tosdivax - .import absvaludiv, negax + .import absvaludiv16, negax .importzp sp, ptr1, tmp1 tosdiva0: @@ -20,10 +20,10 @@ tosdivax: eor (sp),y ; eor with lhs high byte sta tmp1 ; save post negation indicator to tmp1 pla ; back to entry accu - jsr absvaludiv + jsr absvaludiv16 ldx ptr1+1 lda ptr1 - ldy tmp1 ; fetch idicator + ldy tmp1 ; fetch indicator bmi negate rts negate: jmp negax diff --git a/libsrc/runtime/mod.s b/libsrc/runtime/mod.s index b3a818fda..eb120377b 100644 --- a/libsrc/runtime/mod.s +++ b/libsrc/runtime/mod.s @@ -8,7 +8,7 @@ ; values is $8000, in which case the negate will fail. .export tosmoda0, tosmodax - .import absvaludiv, negax + .import absvaludiv16, negax .importzp sp, sreg, tmp1 tosmoda0: @@ -23,10 +23,10 @@ tosmodax: lda (sp),y sta tmp1 ; save post negation indicator to tmp1 pla ; back to entry accu - jsr absvaludiv + jsr absvaludiv16 ldx sreg+1 ; remainder to return registers lda sreg - ldy tmp1 ; fetch idicator + ldy tmp1 ; fetch indicator bmi negate rts negate: jmp negax From 71420223bcfed2176edb385dfbd231713b234ca9 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Thu, 24 May 2018 11:37:17 +0200 Subject: [PATCH 0722/2161] Changed the name of the file too. --- libsrc/runtime/{absvaludiv.s => absvaludiv16.s} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename libsrc/runtime/{absvaludiv.s => absvaludiv16.s} (100%) diff --git a/libsrc/runtime/absvaludiv.s b/libsrc/runtime/absvaludiv16.s similarity index 100% rename from libsrc/runtime/absvaludiv.s rename to libsrc/runtime/absvaludiv16.s From b98517f90b9404576a24fd5614ebf1df8da83d5b Mon Sep 17 00:00:00 2001 From: Bas Wassink <b.wassink@ziggo.nl> Date: Fri, 25 May 2018 13:17:12 +0200 Subject: [PATCH 0723/2161] Add __fastcall__ to cbm_k_second() documentation --- doc/funcref.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 85e75b43f..4e35ebb7e 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -2231,7 +2231,7 @@ function, in order to provide input from the keyboard. <descrip> <tag/Function/Send secondary address for LISTEN. <tag/Header/<tt/<ref id="cbm.h" name="cbm.h">/ -<tag/Declaration/<tt/void cbm_k_second (unsigned char addr);/ +<tag/Declaration/<tt/void __fastcall__ cbm_k_second (unsigned char addr);/ <tag/Description/This function is used to send a secondary address to an I/O device after a call to LISTEN is made, and the device is commanded to LISTEN. <tag/Notes/<itemize> From 0b323f717b9d1e4caa1c307044953527c71fe905 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 25 May 2018 14:48:20 +0200 Subject: [PATCH 0724/2161] Update symbols.txt --- libsrc/geos-common/symbols.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/geos-common/symbols.txt b/libsrc/geos-common/symbols.txt index 1be491f62..d1893e376 100644 --- a/libsrc/geos-common/symbols.txt +++ b/libsrc/geos-common/symbols.txt @@ -1,5 +1,5 @@ Source: The Hitchhiker's Guide To GEOS -http://lyonlabs.org/commodore/onrequest/geos-manuals/The_Hitchhikers_Guide_to_GEOS.pdf +https://archive.org/details/The_Hitchhikers_Guide_to_GEOS GEOS Variables From ba5b580368bc248a1c66ff5026a5d6fb13bac0e1 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Fri, 25 May 2018 16:10:16 +0200 Subject: [PATCH 0725/2161] Fixed first letter of comments (should be upper case). --- libsrc/runtime/div.s | 14 +++++++------- libsrc/runtime/mod.s | 10 +++++----- libsrc/runtime/negabs.s | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/libsrc/runtime/div.s b/libsrc/runtime/div.s index b33d852db..a67799fdf 100644 --- a/libsrc/runtime/div.s +++ b/libsrc/runtime/div.s @@ -14,16 +14,16 @@ tosdiva0: ldx #0 tosdivax: - pha ; check if high-bytes indicate - txa ; different sign, so that we - ldy #1 ; negate the result after the operation - eor (sp),y ; eor with lhs high byte - sta tmp1 ; save post negation indicator to tmp1 - pla ; back to entry accu + pha ; Check if high-bytes indicate + txa ; different sign, so that we have to + ldy #1 ; negate the result after the operation. + eor (sp),y ; Eor with lhs high byte + sta tmp1 ; Save post negation indicator to tmp1 + pla ; Back to entry accu jsr absvaludiv16 ldx ptr1+1 lda ptr1 - ldy tmp1 ; fetch indicator + ldy tmp1 ; Fetch indicator bmi negate rts negate: jmp negax diff --git a/libsrc/runtime/mod.s b/libsrc/runtime/mod.s index eb120377b..0706ba315 100644 --- a/libsrc/runtime/mod.s +++ b/libsrc/runtime/mod.s @@ -19,14 +19,14 @@ tosmodax: ; modulo operation is the same as that of the left operand. pha - ldy #1 ; prepare lhs operant hi-byte fetch + ldy #1 ; Prepare lhs operant hi-byte fetch lda (sp),y - sta tmp1 ; save post negation indicator to tmp1 - pla ; back to entry accu + sta tmp1 ; Save post negation indicator to tmp1 + pla ; Back to entry accu jsr absvaludiv16 - ldx sreg+1 ; remainder to return registers + ldx sreg+1 ; Remainder to return registers lda sreg - ldy tmp1 ; fetch indicator + ldy tmp1 ; Fetch indicator bmi negate rts negate: jmp negax diff --git a/libsrc/runtime/negabs.s b/libsrc/runtime/negabs.s index 5a9ca6e01..ef660f1da 100644 --- a/libsrc/runtime/negabs.s +++ b/libsrc/runtime/negabs.s @@ -9,8 +9,8 @@ .export negax .export _abs -_abs: cpx #$00 ; test hi byte - bpl L1 ; don't touch if positive +_abs: cpx #$00 ; Test hi byte + bpl L1 ; Don't touch if positive negax: clc eor #$FF adc #1 From 8a5d1b967473c9acd07dde67778e2cfc1ac17aa1 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Fri, 25 May 2018 23:18:26 +0200 Subject: [PATCH 0726/2161] Reestablished entry state of signed operation and optimized that (again). --- libsrc/runtime/absvaludiv16.s | 22 -------------------- libsrc/runtime/div.s | 38 ++++++++++++++++++++-------------- libsrc/runtime/mod.s | 39 ++++++++++++++++++++--------------- libsrc/runtime/shelp.s | 29 ++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 54 deletions(-) delete mode 100644 libsrc/runtime/absvaludiv16.s create mode 100644 libsrc/runtime/shelp.s diff --git a/libsrc/runtime/absvaludiv16.s b/libsrc/runtime/absvaludiv16.s deleted file mode 100644 index 59c2914b1..000000000 --- a/libsrc/runtime/absvaludiv16.s +++ /dev/null @@ -1,22 +0,0 @@ -; -; Christian Krueger, 23-May-2018 -; -; CC65 runtime: helper call for mod/div with signed ints -; -; When negating values, we will ignore the possibility here, that one of the -; values is $8000, in which case the negate will fail. - - .export absvaludiv16 - .import _abs, popax, udiv16 - .importzp ptr1, ptr4 - - -absvaludiv16: - jsr _abs - sta ptr4 - stx ptr4+1 ; Save right absolute operand - jsr popax - jsr _abs - sta ptr1 - stx ptr1+1 ; Save left absolute operand - jmp udiv16 diff --git a/libsrc/runtime/div.s b/libsrc/runtime/div.s index a67799fdf..e10ebc57d 100644 --- a/libsrc/runtime/div.s +++ b/libsrc/runtime/div.s @@ -1,5 +1,5 @@ ; -; Christian Krueger, 24-May-2018 +; Ullrich von Bassewitz, 07.08.1998 ; ; CC65 runtime: division for signed ints ; @@ -8,22 +8,30 @@ ; values is $8000, in which case the negate will fail. .export tosdiva0, tosdivax - .import absvaludiv16, negax - .importzp sp, ptr1, tmp1 + .import popsargsudiv16, negax + .importzp ptr1, tmp1, tmp2 tosdiva0: ldx #0 tosdivax: - pha ; Check if high-bytes indicate - txa ; different sign, so that we have to - ldy #1 ; negate the result after the operation. - eor (sp),y ; Eor with lhs high byte - sta tmp1 ; Save post negation indicator to tmp1 - pla ; Back to entry accu - jsr absvaludiv16 - ldx ptr1+1 - lda ptr1 - ldy tmp1 ; Fetch indicator - bmi negate + jsr popsargsudiv16 ; Get arguments from stack, adjust sign + ; and do the division + ldx ptr1+1 ; Load high byte of result + +; Adjust the sign of the result. tmp1 contains the high byte of the left +; operand, tmp2 contains the high byte of the right operand. + + lda tmp1 + eor tmp2 + bpl Pos ; Jump if sign of result positive + +; Result is negative + + lda ptr1 ; Load low byte of result + jmp negax ; Adjust the sign + +; Result is positive + +Pos: lda ptr1 ; Load low byte of result rts -negate: jmp negax + diff --git a/libsrc/runtime/mod.s b/libsrc/runtime/mod.s index 0706ba315..58e740575 100644 --- a/libsrc/runtime/mod.s +++ b/libsrc/runtime/mod.s @@ -1,5 +1,5 @@ ; -; Christian Krueger, 24-May-2018 +; Ullrich von Bassewitz, 07.08.1998 ; ; CC65 runtime: modulo operation for signed ints ; @@ -8,25 +8,30 @@ ; values is $8000, in which case the negate will fail. .export tosmoda0, tosmodax - .import absvaludiv16, negax - .importzp sp, sreg, tmp1 + .import popsargsudiv16, negax + .importzp sreg, tmp1 tosmoda0: ldx #0 tosmodax: + jsr popsargsudiv16 ; Get arguments from stack, adjust sign + ; and do the division + lda sreg ; Load low byte of result + ldx sreg+1 ; Load high byte of result -; Prepare adjustment of the sign of the result. The sign of the result of the -; modulo operation is the same as that of the left operand. +; Adjust the sign of the result. tmp1 contains the high byte of the left +; operand, tmp2 contains the high byte of the right operand. The sign of +; the result of the modulo operation is the same as that of the left +; operand + + bit tmp1 + bpl Pos ; Jump if sign of result positive + +; Result is negative + + jmp negax ; Adjust the sign + +; Result is positive + +Pos: rts - pha - ldy #1 ; Prepare lhs operant hi-byte fetch - lda (sp),y - sta tmp1 ; Save post negation indicator to tmp1 - pla ; Back to entry accu - jsr absvaludiv16 - ldx sreg+1 ; Remainder to return registers - lda sreg - ldy tmp1 ; Fetch indicator - bmi negate - rts -negate: jmp negax diff --git a/libsrc/runtime/shelp.s b/libsrc/runtime/shelp.s new file mode 100644 index 000000000..9762dbf44 --- /dev/null +++ b/libsrc/runtime/shelp.s @@ -0,0 +1,29 @@ +; +; Ullrich von Bassewitz, 07.08.1998 +; +; CC65 runtime: helper stuff for mod/div with signed ints +; + +; When negating values, we will ignore the possibility here, that one of the +; values is $8000, in which case the negate will fail. + + .export popsargsudiv16 + .import negax, popax, udiv16 + .importzp tmp1, tmp2, ptr1, ptr4 + +popsargsudiv16: + stx tmp2 ; Remember sign + cpx #0 + bpl L1 + jsr negax ; Negate accumulator +L1: sta ptr4 + stx ptr4+1 ; Save right operand + + jsr popax + stx tmp1 ; Remember sign + cpx #0 + bpl L2 + jsr negax +L2: sta ptr1 + stx ptr1+1 + jmp udiv16 ; Call the division From ea463d95e37602be8d7b659aac0dbde045deb214 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sat, 26 May 2018 16:33:19 +0200 Subject: [PATCH 0727/2161] 1 byte code size donation for Fabrizio ;) --- libsrc/vic20/cgetc.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/vic20/cgetc.s b/libsrc/vic20/cgetc.s index 4d3a30ea2..9371805d2 100644 --- a/libsrc/vic20/cgetc.s +++ b/libsrc/vic20/cgetc.s @@ -40,8 +40,8 @@ L3: jsr KBDREAD ; Read char and return in A bne seton ; Go set it on lda CURS_FLAG ; Is the cursor currently off? bne crs9 ; Jump if yes - lda #1 - sta CURS_FLAG ; Mark it as off + inx ; X is now 1 + stx CURS_FLAG ; Mark it as off lda CURS_STATE ; Cursor currently displayed? beq crs8 ; Jump if no ldy CURS_X ; Get the character column From e77ac8a230279ad29081fe50b5602ccfba17f203 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sat, 26 May 2018 16:37:03 +0200 Subject: [PATCH 0728/2161] 1 byte donation for Fabrizio ;) --- libsrc/vic20/cgetc.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/vic20/cgetc.s b/libsrc/vic20/cgetc.s index 4d3a30ea2..05f2f68dc 100644 --- a/libsrc/vic20/cgetc.s +++ b/libsrc/vic20/cgetc.s @@ -40,8 +40,8 @@ L3: jsr KBDREAD ; Read char and return in A bne seton ; Go set it on lda CURS_FLAG ; Is the cursor currently off? bne crs9 ; Jump if yes - lda #1 - sta CURS_FLAG ; Mark it as off + inx ; X is now 1 + stx CURS_FLAG ; Mark it as off lda CURS_STATE ; Cursor currently displayed? beq crs8 ; Jump if no ldy CURS_X ; Get the character column From 49a9b887343a91e2ed87da4c2c15df1c0f99b873 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sat, 26 May 2018 19:53:44 +0200 Subject: [PATCH 0729/2161] Saved even one more byte. --- libsrc/vic20/cgetc.s | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libsrc/vic20/cgetc.s b/libsrc/vic20/cgetc.s index 05f2f68dc..d5af9a9f6 100644 --- a/libsrc/vic20/cgetc.s +++ b/libsrc/vic20/cgetc.s @@ -40,8 +40,7 @@ L3: jsr KBDREAD ; Read char and return in A bne seton ; Go set it on lda CURS_FLAG ; Is the cursor currently off? bne crs9 ; Jump if yes - inx ; X is now 1 - stx CURS_FLAG ; Mark it as off + inc CURS_FLAG ; Mark it as off lda CURS_STATE ; Cursor currently displayed? beq crs8 ; Jump if no ldy CURS_X ; Get the character column From 30a679ba360c5b80dcc472fab3886347aaed9e75 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sat, 26 May 2018 20:25:51 +0200 Subject: [PATCH 0730/2161] Saved 3 bytes for the C16 target. --- libsrc/c16/cgetc.s | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libsrc/c16/cgetc.s b/libsrc/c16/cgetc.s index 3ee31a757..a61373ac7 100644 --- a/libsrc/c16/cgetc.s +++ b/libsrc/c16/cgetc.s @@ -60,8 +60,10 @@ L2: jsr KBDREAD ; Read char and return in A .proc initkbd - ldy #15 + ldy #7 @L1: lda fnkeys,y + sta FKEY_SPACE+8,y + lda #$01 ; Lower 8 places are all $01 sta FKEY_SPACE,y dey bpl @L1 @@ -69,8 +71,7 @@ L2: jsr KBDREAD ; Read char and return in A .endproc -fnkeys: .byte $01, $01, $01, $01, $01, $01, $01, $01 - .byte 133, 137, 134, 138, 135, 139, 136, 140 +fnkeys: .byte 133, 137, 134, 138, 135, 139, 136, 140 .code From f55b564ca19fbf0f4da69688b7b2a8e13a82e1a7 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sun, 27 May 2018 00:10:58 +0200 Subject: [PATCH 0731/2161] Save the three bytes for the plus4 too. --- libsrc/plus4/cgetc.s | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libsrc/plus4/cgetc.s b/libsrc/plus4/cgetc.s index 784bac267..fcbc66064 100644 --- a/libsrc/plus4/cgetc.s +++ b/libsrc/plus4/cgetc.s @@ -63,8 +63,10 @@ L2: sta ENABLE_ROM ; Bank in the ROM .proc initkbd - ldy #15 + ldy #7 @L1: lda fnkeys,y + sta FKEY_SPACE+8,y + lda #$01 ; Lower 8 places are all $01 sta FKEY_SPACE,y dey bpl @L1 @@ -72,8 +74,7 @@ L2: sta ENABLE_ROM ; Bank in the ROM .endproc -fnkeys: .byte $01, $01, $01, $01, $01, $01, $01, $01 - .byte 133, 137, 134, 138, 135, 139, 136, 140 +fnkeys: .byte 133, 137, 134, 138, 135, 139, 136, 140 .segment "LOWCODE" ; Accesses the ROM - must go into low mem From 465a651090a11bc982be71f953adc01c31396061 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Tue, 29 May 2018 01:47:04 +0200 Subject: [PATCH 0732/2161] Free 2 bytes again. --- libsrc/runtime/mul.s | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libsrc/runtime/mul.s b/libsrc/runtime/mul.s index 769cf9d8e..087e639fc 100644 --- a/libsrc/runtime/mul.s +++ b/libsrc/runtime/mul.s @@ -19,12 +19,12 @@ tosumulax: txa ; High byte zero beq @L3 ; Do 8x16 multiplication if high byte zero stx ptr4+1 ; Save right operand - jsr popptr1 ; Get left operand (Y=0 by popptr1) + jsr popptr1 ; Get left operand (Y=0, X untouched by popptr1) ; Do ptr4:ptr4+1 * ptr1:ptr1+1 --> AX - tya ; A = 0 - ldx ptr1+1 ; check if lhs is 8 bit only + tya ; A = 0 + ldy ptr1+1 ; check if lhs is 8 bit only beq @L4 ; -> we can do 8x16 after swap sta tmp1 ldy #16 ; Number of bits @@ -36,7 +36,7 @@ tosumulax: clc adc ptr1 tax - lda ptr1+1 ; hi byte of left op + lda ptr1+1 ; Hi byte of left op adc tmp1 sta tmp1 txa @@ -56,15 +56,15 @@ tosumulax: @L3: jmp mul8x16 -; If the high byte of rhs is zero, swap the operands and use the 8x16 -; routine. On entry, A and X are zero +; If the high byte of lhs is zero, swap the operands in ptr1/4 and +; use the 8x16 routine. On entry, A and Y are zero and X has the value +; of ptr4+1 -@L4: ldy ptr1 ; Save right operand (8 bit) +@L4: stx ptr1+1 ; Store hi-byte from ptr4 + ldy ptr1 ; Save right operand (8 bit) ldx ptr4 ; Copy left 16 bit operand to right stx ptr1 - ldx ptr4+1 ; swap high-byte too - stx ptr1+1 sty ptr4 ; Copy low 8 bit of right op to left ldy #8 - jmp mul8x16a + jmp mul8x16a ; There, ptr4+1 will be also cleared From 6d87370881b0b5ac2e8a054dacd1c1bf0c671253 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 29 May 2018 14:29:50 -0400 Subject: [PATCH 0733/2161] Fixed strpbrk(). Added its prototype. Documented it. --- doc/funcref.sgml | 35 ++++++++++++++++++-- include/string.h | 1 + libsrc/common/strpbrk.s | 65 +++++++++++++++++-------------------- testcode/lib/strpbrk-test.c | 26 +++++++++++++++ 4 files changed, 88 insertions(+), 39 deletions(-) create mode 100644 testcode/lib/strpbrk-test.c diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 4e35ebb7e..edb510e37 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -4,7 +4,7 @@ <title>cc65 function reference <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2018-05-23 +<date>2018-05-29 <abstract> cc65 is a C compiler for 6502 based systems. This function reference describes @@ -717,6 +717,7 @@ communication, see also <tt>testcode/lib/ser-test.c</tt>. <item><ref id="strncmp" name="strncmp"> <item><ref id="strncpy" name="strncpy"> <item><ref id="strnicmp" name="strnicmp"> +<item><ref id="strpbrk" name="strpbrk"> <item><ref id="strqtok" name="strqtok"> <item><ref id="strrchr" name="strrchr"> <item><ref id="strspn" name="strspn"> @@ -6802,6 +6803,7 @@ be used in presence of a prototype. </itemize> <tag/Availability/ISO 9899 <tag/See also/ +<ref id="strpbrk" name="strpbrk">, <ref id="strqtok" name="strqtok">, <ref id="strspn" name="strspn">, <ref id="strstr" name="strstr">, @@ -7092,6 +7094,32 @@ be used in presence of a prototype. </quote> +<sect1>strpbrk<label id="strpbrk"><p> + +<quote> +<descrip> +<tag/Function/Find a character in a string, from a set of characters. +<tag/Header/<tt/<ref id="string.h" name="string.h">/ +<tag/Declaration/<tt/char* __fastcall__ strpbrk (const char* str, const char* set);/ +<tag/Description/<tt/strpbrk()/ searches within <tt/str/ for the first +occurance of any character from <tt/set/. It returns a pointer to that +character if found; otherwise, it returns <tt/NULL/. +<tag/Notes/<itemize> +<item>The function is available only as a fastcall function; +so, it should be used only in the presence of a prototype. +</itemize> +<tag/Availability/ISO 9899 +<tag/See also/ +<ref id="strchr" name="strchr">, +<ref id="strcspn" name="strcspn">, +<ref id="strqtok" name="strqtok">, +<ref id="strspn" name="strspn">, +<ref id="strtok" name="strtok"> +<tag/Example/None. +</descrip> +</quote> + + <sect1>strqtok<label id="strqtok"><p> <quote> @@ -7116,7 +7144,7 @@ a second <tt/s1/ string before it finishes the first one. <tag/Availability/cc65 <tag/See also/ <ref id="strcspn" name="strcspn">, -<!-- <ref id="strpbrk" name="strpbrk">, --> +<ref id="strpbrk" name="strpbrk">, <ref id="strspn" name="strspn">, <ref id="strtok" name="strtok"> <tag/Example/None. @@ -7164,6 +7192,7 @@ be used in presence of a prototype. <tag/Availability/ISO 9899 <tag/See also/ <ref id="strcspn" name="strcspn">, +<ref id="strpbrk" name="strpbrk">, <ref id="strstr" name="strstr"> <tag/Example/None. </descrip> @@ -7216,7 +7245,7 @@ a second <tt/s1/ string before it finishes the first one. <tag/Availability/ISO 9899 <tag/See also/ <ref id="strcspn" name="strcspn">, -<!-- <ref id="strpbrk" name="strpbrk">, --> +<ref id="strpbrk" name="strpbrk">, <ref id="strqtok" name="strqtok">, <ref id="strspn" name="strspn"> <tag/Example/None. diff --git a/include/string.h b/include/string.h index 46095a525..2f5953196 100644 --- a/include/string.h +++ b/include/string.h @@ -53,6 +53,7 @@ size_t __fastcall__ strlen (const char* s); char* __fastcall__ strncat (char* s1, const char* s2, size_t count); int __fastcall__ strncmp (const char* s1, const char* s2, size_t count); char* __fastcall__ strncpy (char* dest, const char* src, size_t count); +char* __fastcall__ strpbrk (const char* str, const char* set); char* __fastcall__ strrchr (const char* s, int c); size_t __fastcall__ strspn (const char* s1, const char* s2); char* __fastcall__ strstr (const char* str, const char* substr); diff --git a/libsrc/common/strpbrk.s b/libsrc/common/strpbrk.s index 5d1482913..a7060415e 100644 --- a/libsrc/common/strpbrk.s +++ b/libsrc/common/strpbrk.s @@ -1,60 +1,53 @@ -; -; Ullrich von Bassewitz, 11.06.1998 ; -; char* strpbrk (const char* s1, const char* s2); +; 1998-06-11, Ullrich von Bassewitz +; 2018-05-29, Greg King +; +; char* __fastcall__ strpbrk (const char* str, const char* set); ; .export _strpbrk - .import popax, return0 - .importzp ptr1, ptr2, tmp1, tmp2, tmp3 + + .import popax + .importzp ptr1, ptr2, tmp2, tmp3 _strpbrk: - jsr popax ; get s2 - sta ptr2 + sta ptr2 ; store set stx ptr2+1 - jsr popax ; get s1 - sta ptr1 - stx ptr1+1 - ldy #$00 + jsr popax + stx ptr1+1 ; store str's high byte + ldx #<$0000 + stx ptr1 + tay ; use str's low byte as index -L1: lda (ptr1),y ; get next char from s1 +L1: lda (ptr1),y ; get next char from str beq L9 ; jump if done sta tmp2 ; save char - iny - bne L2 - inc ptr1+1 -L2: sty tmp3 ; save index into s1 + sty tmp3 ; save index into str - ldy #0 ; get index into s2 -L3: lda (ptr2),y ; + ldy #$00 +L3: lda (ptr2),y ; look at each char in set beq L4 ; jump if done cmp tmp2 - beq L6 + beq L6 ; break out of loops if something found iny bne L3 -; The character was not found in s2. Increment the counter and start over +; The character was not found in set. Increment the counter; and start over. L4: ldy tmp3 ; reload index - inx - bne L1 - inc tmp1 + iny bne L1 + inc ptr1+1 + bne L1 ; branch always -; A character was found. Calculate a pointer to this char in s1 and return it. +; A character was found. Return its str pointer. L6: ldx ptr1+1 - lda tmp3 ; get y offset - clc - adc ptr1 - bcc L7 - inx -L7: rts - -; None of the characters in s2 was found - return NULL - -L9: jmp return0 - - + lda tmp3 ; get .Y offset + rts +; None of the characters in set was found -- return NULL. +L9: ;ldx #>$0000 ; (set by prolog) + ;lda #<$0000 ; (set by '\0' at end of str) + rts diff --git a/testcode/lib/strpbrk-test.c b/testcode/lib/strpbrk-test.c new file mode 100644 index 000000000..25c2c2fbe --- /dev/null +++ b/testcode/lib/strpbrk-test.c @@ -0,0 +1,26 @@ +#include <stdio.h> +#include <string.h> + +static const char fox[] = "The quick brown fox jumped over the lazy dogs."; + +void main (void) +{ + printf ("Testing strpbrk():\n"); + if (strpbrk (fox, "qwerty") != &fox[2]) { + printf ("\nThe first 'e' wasn't found.\n"); + } + if (strpbrk (fox, "QWERTY") != &fox[0]) { + printf ("The 'T' wasn't found.\n"); + } + if (strpbrk (fox, "asdfg") != &fox[16]) { + printf ("The 'f' wasn't found.\n"); + } + if (strpbrk (fox, "nxv,zmb") != &fox[10]) { + printf ("The 'b' wasn't found.\n"); + } + if (strpbrk (fox, "!@#$%^&*()-+=[];:',/?<>.") != &fox[45]) { + printf ("The '.' wasn't found.\n"); + } + + printf ("\nFinished.\n"); +} From 1f245fbc0b25974992ad8c162d1f217ffc7162b2 Mon Sep 17 00:00:00 2001 From: Ben <bengdahl341@gmail.com> Date: Mon, 4 Jun 2018 21:27:04 -0400 Subject: [PATCH 0734/2161] Fix `make` failing in parent directories containing spaces --- src/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Makefile b/src/Makefile index 524651428..81adb804a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -64,8 +64,8 @@ endif 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) \ + -DCA65_INC="$(CA65_INC)" -DCC65_INC="$(CC65_INC)" -DCL65_TGT="$(CL65_TGT)" \ + -DLD65_LIB="$(LD65_LIB)" -DLD65_OBJ="$(LD65_OBJ)" -DLD65_CFG="$(LD65_CFG)" \ -DGIT_SHA=$(GIT_SHA) LDLIBS += -lm @@ -148,7 +148,7 @@ endef # PROG_template ../wrk/%.o: %.c @echo $< - @$(CC) -c $(CFLAGS) -o $@ $< + $(CC) -c $(CFLAGS) -o $@ $< ../bin: @$(call MKDIR,$@) From 4fd17161ebe2f7dd64b1acc3fca36e29cce14dbb Mon Sep 17 00:00:00 2001 From: existensialMemory <bengdahl341@gmail.com> Date: Mon, 4 Jun 2018 22:17:25 -0400 Subject: [PATCH 0735/2161] Update Makefile --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 81adb804a..c1f11ff58 100644 --- a/src/Makefile +++ b/src/Makefile @@ -148,7 +148,7 @@ endef # PROG_template ../wrk/%.o: %.c @echo $< - $(CC) -c $(CFLAGS) -o $@ $< + @$(CC) -c $(CFLAGS) -o $@ $< ../bin: @$(call MKDIR,$@) From e99a5ff1fe2d4b0e65d0109fec2701227a799ae7 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 6 Jun 2018 18:59:25 +0200 Subject: [PATCH 0736/2161] Fixed usage indentation. --- src/cc65/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/main.c b/src/cc65/main.c index f8361f41c..7783587aa 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -118,7 +118,7 @@ static void Usage (void) " --debug-opt name\t\tDebug optimization steps\n" " --dep-target target\t\tUse this dependency target\n" " --disable-opt name\t\tDisable an optimization step\n" - " --eagerly-inline-funcs\t\tEagerly inline some known functions\n" + " --eagerly-inline-funcs\tEagerly inline some known functions\n" " --enable-opt name\t\tEnable an optimization step\n" " --help\t\t\tHelp (this text)\n" " --include-dir dir\t\tSet an include directory search path\n" From e626180b28882d8880e87433b253c1e0c81474fa Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Wed, 6 Jun 2018 21:11:17 +0200 Subject: [PATCH 0737/2161] Fix joystick for the Supervision target --- libsrc/supervision/joy/supervision-stdjoy.s | 1 + 1 file changed, 1 insertion(+) diff --git a/libsrc/supervision/joy/supervision-stdjoy.s b/libsrc/supervision/joy/supervision-stdjoy.s index d233a8600..5d6e23bc0 100644 --- a/libsrc/supervision/joy/supervision-stdjoy.s +++ b/libsrc/supervision/joy/supervision-stdjoy.s @@ -77,5 +77,6 @@ COUNT: READJOY: lda sv_control + eor #$FF ldx #0 rts From 9af2d6b4a1aa64d0ec4167f57904fd222e5e622c Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Wed, 6 Jun 2018 21:18:47 +0200 Subject: [PATCH 0738/2161] spaces instead of tab --- libsrc/supervision/joy/supervision-stdjoy.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/supervision/joy/supervision-stdjoy.s b/libsrc/supervision/joy/supervision-stdjoy.s index 5d6e23bc0..ef790ec0b 100644 --- a/libsrc/supervision/joy/supervision-stdjoy.s +++ b/libsrc/supervision/joy/supervision-stdjoy.s @@ -77,6 +77,6 @@ COUNT: READJOY: lda sv_control - eor #$FF + eor #$FF ldx #0 rts From d861be8ad569d3928727a8c8162fc843835035db Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 7 Jun 2018 17:10:33 +0200 Subject: [PATCH 0739/2161] Escape spaces in target path. cc65 escapes spaces in paths it writes to dependency files (see WriteEscaped() in cc65/input.c). Given that the output of OptPrintTargetPath() is supposed to be used in Makefiles in pretty much the same way it is appropriate to escape spaces here too. --- src/cl65/main.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index afd3e97e3..f8acb57a0 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -1165,19 +1165,28 @@ static void OptPrintTargetPath (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Print the target file path */ { - SearchPaths* TargetPath = NewSearchPath (); - AddSubSearchPathFromEnv (TargetPath, "CC65_HOME", "target"); -#if defined(CL65_TGT) && !defined(_WIN32) - AddSearchPath (TargetPath, STRINGIZE (CL65_TGT)); -#endif - AddSubSearchPathFromWinBin (TargetPath, "target"); + char* TargetPath; - printf ("%s\n", GetSearchPath (TargetPath, 0)); + SearchPaths* TargetPaths = NewSearchPath (); + AddSubSearchPathFromEnv (TargetPaths, "CC65_HOME", "target"); +#if defined(CL65_TGT) && !defined(_WIN32) + AddSearchPath (TargetPaths, STRINGIZE (CL65_TGT)); +#endif + AddSubSearchPathFromWinBin (TargetPaths, "target"); + + TargetPath = GetSearchPath (TargetPaths, 0); + while (*TargetPath) { + if (*TargetPath == ' ') { + /* Escape spaces */ + putchar ('\\'); + } + putchar (*TargetPath++); + } + putchar ('\n'); exit (EXIT_SUCCESS); } - static void OptRegisterSpace (const char* Opt attribute ((unused)), const char* Arg) /* Handle the --register-space option */ { From 9877042450f9c4c282ad18c947e46a3a7cb211ea Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 8 Jun 2018 18:58:36 +0200 Subject: [PATCH 0740/2161] Use --print-target-path only as last resort. --print-target-path may return a path with (escaped) spaces. We'll use that path with $(wildcard ...), that's fine. But then we use the outcome with $(foreach ...) and there things fail badly and there's nothing to do about it. Therefore we a) try to avoid --print-target-path in the first place and b) explicitly bail out if we end up with spaces. --- samples/Makefile | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/samples/Makefile b/samples/Makefile index 8bb6d25ae..a62a38069 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -35,7 +35,15 @@ else endif ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),) - TARGET_PATH := $(shell $(CL) --print-target-path) + ifdef CC65_HOME + TARGET_PATH = $(CC65_HOME)/target + else + TARGET_PATH := $(if $(wildcard ../target),../target,$(shell $(CL) --print-target-path)) + endif + + ifneq ($(words $(TARGET_PATH)),1) + $(error No space chars allowed in "$(TARGET_PATH)") + endif EMD := $(wildcard $(TARGET_PATH)/$(SYS)/drv/emd/*) MOU := $(wildcard $(TARGET_PATH)/$(SYS)/drv/mou/*) From b74ab9de899edd35738cd6b08693f3f2a9a17dae Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 8 Jun 2018 19:16:18 +0200 Subject: [PATCH 0741/2161] Allow spaces in path names. The Microsoft C Library needs to have spawnvp() parameters with spaces quoted manually. We do this only if actually necessary to limit issues with parameters already containing double quotes. --- src/cl65/main.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index f8acb57a0..118acfb03 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -192,6 +192,38 @@ static void DisableAssemblingAndLinking (void) +static char* CmdAllocArg (const char* Arg, unsigned Len) +/* Alloc (potentially quoted) argument */ +{ + char* Alloc; + +/* The Microsoft docs say on spawnvp(): +** Spaces embedded in strings may cause unexpected behavior; for example, +** passing _spawn the string "hi there" will result in the new process getting +** two arguments, "hi" and "there". If the intent was to have the new process +** open a file named "hi there", the process would fail. You can avoid this by +** quoting the string: "\"hi there\"". +*/ +#if defined(_WIN32) + /* Quote argument if it contains space(s) */ + if (memchr (Arg, ' ', Len)) { + Alloc = xmalloc (Len + 3); + Alloc[0] = '"'; + memcpy (Alloc + 1, Arg, Len); + Alloc[Len + 1] = '"'; + Alloc[Len + 2] = '\0'; + } else +#endif + { + Alloc = xmalloc (Len + 1); + memcpy (Alloc, Arg, Len); + Alloc[Len] = '\0'; + } + return Alloc; +} + + + static void CmdExpand (CmdDesc* Cmd) /* Expand the argument vector */ { @@ -215,7 +247,7 @@ static void CmdAddArg (CmdDesc* Cmd, const char* Arg) /* Add a copy of the new argument, allow a NULL pointer */ if (Arg) { - Cmd->Args[Cmd->ArgCount++] = xstrdup (Arg); + Cmd->Args[Cmd->ArgCount++] = CmdAllocArg (Arg, strlen (Arg)); } else { Cmd->Args[Cmd->ArgCount++] = 0; } @@ -250,9 +282,7 @@ static void CmdAddArgList (CmdDesc* Cmd, const char* ArgList) } /* Add the new argument */ - Cmd->Args[Cmd->ArgCount] = memcpy (xmalloc (Len + 1), Arg, Len); - Cmd->Args[Cmd->ArgCount][Len] = '\0'; - ++Cmd->ArgCount; + Cmd->Args[Cmd->ArgCount++] = CmdAllocArg (Arg, Len); /* If the argument was terminated by a comma, skip it, otherwise ** we're done. @@ -1187,6 +1217,7 @@ static void OptPrintTargetPath (const char* Opt attribute ((unused)), } + static void OptRegisterSpace (const char* Opt attribute ((unused)), const char* Arg) /* Handle the --register-space option */ { From 9283e9ca982e32da39ffc83d324f883d13d5df49 Mon Sep 17 00:00:00 2001 From: AIDA Shinra <shinra@j10n.org> Date: Sun, 10 Jun 2018 18:09:11 +0900 Subject: [PATCH 0742/2161] Support for "virtual operands" of subroutines like this: jsr SomeProc .byte $00, $01 ; argument to SomeProc ; return here from SomeProc bit $3F --- doc/da65.sgml | 12 ++++++++++++ src/da65/handler.c | 30 ++++++++++++++++++++++++++++++ src/da65/handler.h | 2 ++ src/da65/infofile.c | 17 +++++++++++++++++ src/da65/opc6502.c | 2 +- src/da65/opc65816.c | 2 +- src/da65/opc65c02.c | 2 +- src/da65/opc65sc02.c | 2 +- src/da65/scanner.h | 1 + 9 files changed, 66 insertions(+), 4 deletions(-) diff --git a/doc/da65.sgml b/doc/da65.sgml index a8e32e1c8..c2d87ac92 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -542,6 +542,18 @@ code. The following attributes are recognized: range, where <tt/label/ is the label name given with the <tt/NAME/ attribute, and <tt/offs/ is the offset within the data. + <tag><tt>VOPERAND</tt></tag> + This optional attribute is followed by a numerical value. It tells the + assembler that subroutine calls to this label follow "virtual operands" + of the given bytes like this: + +<tscreen><verb> + JSR LabelWith2BytesOfVoperand + .byte $00, $10 ; virtual operands + ; return here + BIT $0F +</verb></tscreen> + </descrip> diff --git a/src/da65/handler.c b/src/da65/handler.c index 624952363..19b8946de 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -51,6 +51,8 @@ +static unsigned short SubroutineVOperandSize[0x10000]; + /*****************************************************************************/ /* Helper functions */ /*****************************************************************************/ @@ -741,3 +743,31 @@ void OH_JmpAbsoluteXIndirect (const OpcDesc* D) } SeparatorLine (); } + + + +void OH_JsrAbsolute (const OpcDesc* D) +{ + unsigned VOperandSize = SubroutineVOperandSize[GetCodeWord(PC+1)]; + OH_Absolute (D); + if (VOperandSize > 0) { + unsigned RemainingBytes; + PC += D->Size; + RemainingBytes = GetRemainingBytes(); + if (RemainingBytes < VOperandSize) { + VOperandSize = RemainingBytes; + } + if (VOperandSize > 0) { + DataByteLine (VOperandSize); /* FIXME: follow BytesPerLine */ + PC += VOperandSize; + } + PC -= D->Size; + } +} + + + +void SetSubroutineVOperand (unsigned Addr, unsigned Size) +{ + SubroutineVOperandSize[Addr] = Size; +} diff --git a/src/da65/handler.h b/src/da65/handler.h index c0fa68e56..96b73f2c7 100644 --- a/src/da65/handler.h +++ b/src/da65/handler.h @@ -104,7 +104,9 @@ void OH_Rts (const OpcDesc*); void OH_JmpAbsolute (const OpcDesc*); void OH_JmpAbsoluteIndirect (const OpcDesc* D); void OH_JmpAbsoluteXIndirect (const OpcDesc* D); +void OH_JsrAbsolute (const OpcDesc*); +void SetSubroutineVOperand (unsigned Addr, unsigned Size); /* End of handler.h */ diff --git a/src/da65/infofile.c b/src/da65/infofile.c index e8ce66cf7..3bfa15f51 100644 --- a/src/da65/infofile.c +++ b/src/da65/infofile.c @@ -59,6 +59,7 @@ #include "opctable.h" #include "scanner.h" #include "segment.h" +#include "handler.h" @@ -380,6 +381,7 @@ static void LabelSection (void) { "ADDR", INFOTOK_ADDR }, { "NAME", INFOTOK_NAME }, { "SIZE", INFOTOK_SIZE }, + { "VOPERAND", INFOTOK_VOPERAND }, }; /* Locals - initialize to avoid gcc warnings */ @@ -387,6 +389,7 @@ static void LabelSection (void) char* Comment = 0; long Value = -1; long Size = -1; + long VOperand = -1; /* Skip the token */ InfoNextTok (); @@ -448,6 +451,17 @@ static void LabelSection (void) InfoNextTok (); break; + case INFOTOK_VOPERAND: + InfoNextTok (); + if (VOperand >= 0) { + InfoError ("VOperand already given"); + } + InfoAssureInt (); + InfoRangeCheck (1, 0x10000); + VOperand = InfoIVal; + InfoNextTok (); + break; + default: Internal ("Unexpected token: %u", InfoTok); } @@ -484,6 +498,9 @@ static void LabelSection (void) } else { AddExtLabelRange ((unsigned) Value, Name, Size); } + if (VOperand >= 0) { + SetSubroutineVOperand ((unsigned) Value, (unsigned) VOperand); + } /* Define the comment */ if (Comment) { diff --git a/src/da65/opc6502.c b/src/da65/opc6502.c index 27f734d56..8fc6f6aea 100644 --- a/src/da65/opc6502.c +++ b/src/da65/opc6502.c @@ -79,7 +79,7 @@ const OpcDesc OpcTable_6502[256] = { { "ora", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1d */ { "asl", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1e */ { "", 1, flIllegal, OH_Illegal, }, /* $1f */ - { "jsr", 3, flLabel, OH_Absolute }, /* $20 */ + { "jsr", 3, flLabel, OH_JsrAbsolute }, /* $20 */ { "and", 2, flUseLabel, OH_DirectXIndirect }, /* $21 */ { "", 1, flIllegal, OH_Illegal, }, /* $22 */ { "", 1, flIllegal, OH_Illegal, }, /* $23 */ diff --git a/src/da65/opc65816.c b/src/da65/opc65816.c index 2cd2aaee8..b7775d2e2 100644 --- a/src/da65/opc65816.c +++ b/src/da65/opc65816.c @@ -79,7 +79,7 @@ const OpcDesc OpcTable_65816[256] = { { "ora", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1d */ { "asl", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1e */ { "ora", 4, flUseLabel, OH_AbsoluteLongX }, /* $1f */ - { "jsr", 3, flLabel, OH_Absolute }, /* $20 */ + { "jsr", 3, flLabel, OH_JsrAbsolute }, /* $20 */ { "and", 2, flUseLabel, OH_DirectXIndirect }, /* $21 */ { "jsl", 3, flLabel, OH_AbsoluteLong }, /* $22 */ { "and", 2, flNone, OH_StackRelative }, /* $23 */ diff --git a/src/da65/opc65c02.c b/src/da65/opc65c02.c index 8133bccae..b69558f2a 100644 --- a/src/da65/opc65c02.c +++ b/src/da65/opc65c02.c @@ -79,7 +79,7 @@ const OpcDesc OpcTable_65C02[256] = { { "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 */ + { "jsr", 3, flLabel, OH_JsrAbsolute }, /* $20 */ { "and", 2, flUseLabel, OH_DirectXIndirect }, /* $21 */ { "", 1, flIllegal, OH_Illegal, }, /* $22 */ { "", 1, flIllegal, OH_Illegal, }, /* $23 */ diff --git a/src/da65/opc65sc02.c b/src/da65/opc65sc02.c index 90549d00f..82e10bd96 100644 --- a/src/da65/opc65sc02.c +++ b/src/da65/opc65sc02.c @@ -79,7 +79,7 @@ const OpcDesc OpcTable_65SC02[256] = { { "ora", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1d */ { "asl", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1e */ { "", 1, flIllegal, OH_Illegal, }, /* $1f */ - { "jsr", 3, flLabel, OH_Absolute }, /* $20 */ + { "jsr", 3, flLabel, OH_JsrAbsolute }, /* $20 */ { "and", 2, flUseLabel, OH_DirectXIndirect }, /* $21 */ { "", 1, flIllegal, OH_Illegal, }, /* $22 */ { "", 1, flIllegal, OH_Illegal, }, /* $23 */ diff --git a/src/da65/scanner.h b/src/da65/scanner.h index f7f090fad..14a3ef679 100644 --- a/src/da65/scanner.h +++ b/src/da65/scanner.h @@ -105,6 +105,7 @@ typedef enum token_t { INFOTOK_COMMENT, INFOTOK_ADDR, INFOTOK_SIZE, + INFOTOK_VOPERAND, /* ASMINC section */ INFOTOK_FILE, From 535088fe733b2865448179288d43544e6abdb0e8 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 10 Jun 2018 18:12:09 +0200 Subject: [PATCH 0743/2161] Support --print-target-path with spaces. Don't try this at home ;-)) --- samples/Makefile | 56 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index a62a38069..601d19d76 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -8,6 +8,13 @@ # var. to build for another target system. SYS ?= c64 +# Just the usual way to define a variable +# containing a single space character. +SPACE := +SPACE += + +# Just the usual way to find out if we're +# using cmd.exe to execute make rules. ifneq ($(shell echo),) CMD_EXE = 1 endif @@ -41,14 +48,41 @@ ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),) TARGET_PATH := $(if $(wildcard ../target),../target,$(shell $(CL) --print-target-path)) endif - ifneq ($(words $(TARGET_PATH)),1) - $(error No space chars allowed in "$(TARGET_PATH)") - endif + # If TARGET_PATH contains spaces then it is presumed to contain escaped spaces. GNU make + # has very limited support for paths containing spaces. $(wildcard) is the only function + # that is aware of escaped spaces. However, $(wildcard) never returns paths with escaped + # spaces !!! So if it e.g. finds in a path with 2 spaces 4 files then one ends up with a + # return value consisting of 12 plain words :-(( + # + # Fortunately we can work around that behaviour here because we know that the files we + # are looking for have known extensions. So we can $(filter) the in our example above 12 + # words for file extensions so we come up with 4 path fragments. Then we remove those + # path fragments with $(notdir) from the file names. + # + # So far so good. But here we want to process files from different paths in a single + # recipe further down below and therefore want to prepend the paths to the files with + # $(addprefix). However, $(foreach) isn't aware of escaped spaces (only $(wildcard) is). + # Therefore, we need to replace the spaces with some other character temporarily in order + # to have $(foreach) generate one invocation per file. We use the character '?' for that + # purpose here, just because it is known to not be part of file names. + # + # Inside the recipe generated per file we then replace the '?' again with a space. As we + # want to be compatible with cmd.exe for execution we're not using an escaped space but + # rather double-quote the whole path. + # + # Note: The "strange" $(wildcard) further down below just serves the purpose to unescape + # spaces for cmd.exe. This could have as well been done with another $(subst). + + SUBST_TARGET_PATH := $(subst \$(SPACE),?,$(TARGET_PATH)) EMD := $(wildcard $(TARGET_PATH)/$(SYS)/drv/emd/*) MOU := $(wildcard $(TARGET_PATH)/$(SYS)/drv/mou/*) TGI := $(wildcard $(TARGET_PATH)/$(SYS)/drv/tgi/*) + 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)))) + # This one comes with the VICE emulator. # See http://vice-emu.sourceforge.net/ C1541 ?= c1541 @@ -199,12 +233,12 @@ OVERLAYLIST := $(foreach I,1 2 3,multdemo.$I ovrldemo.$I) define D64_WRITE_recipe -$(C1541) -attach $@ -write $(file) $(notdir $(file)) >$(NULLDEV) +$(C1541) -attach $@ -write "$(subst ?,$(SPACE),$(file))" $(notdir $(file)) >$(NULLDEV) endef # D64_WRITE_recipe samples.d64: samples - @$(C1541) -format samples,AA d64 $@ >$(NULLDEV) + @$(C1541) -format samples,AA d64 $@ >$(NULLDEV) $(foreach file,$(EXELIST_$(SYS)),$(D64_WRITE_recipe)) $(foreach file,$(OVERLAYLIST),$(D64_WRITE_recipe)) $(foreach file,$(EMD) $(MOU) $(TGI),$(D64_WRITE_recipe)) @@ -217,14 +251,14 @@ samples.d64: samples define DSK_WRITE_BIN_recipe $(if $(findstring BF00,$(LDFLAGS_$(notdir $(file))_$(SYS))), \ - java -jar $(AC) -p $@ $(notdir $(file)).system sys <$(TARGET_PATH)/$(SYS)/util/loader.system) -java -jar $(AC) -as $@ $(notdir $(file)) <$(file) + java -jar $(AC) -p $@ $(notdir $(file)).system sys <"$(wildcard $(TARGET_PATH)/$(SYS)/util/loader.system)") +java -jar $(AC) -as $@ $(notdir $(file)) <"$(file)" endef # DSK_WRITE_BIN_recipe define DSK_WRITE_REL_recipe -java -jar $(AC) -p $@ $(notdir $(file)) rel 0 <$(file) +java -jar $(AC) -p $@ $(notdir $(file)) rel 0 <"$(subst ?,$(SPACE),$(file))" endef # DSK_WRITE_REL_recipe @@ -241,14 +275,14 @@ samples.dsk: samples define ATR_WRITE_recipe -cp $(file) atr/$(notdir $(file)) +cp "$(subst ?,$(SPACE),$(file))" atr/$(notdir $(file)) endef # ATR_WRITE_recipe samples.atr: samples @mkdir atr - cp dos.sys atr/dos.sys - cp dup.sys atr/dup.sys + cp "dos.sys" atr/dos.sys + 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)) From 335a8972b92e2328a2395952be739363cc7d945d Mon Sep 17 00:00:00 2001 From: AIDA Shinra <shinra@j10n.org> Date: Mon, 11 Jun 2018 01:53:35 +0900 Subject: [PATCH 0744/2161] Support for preprocessing info file via cpp or m4. --- doc/da65.sgml | 20 +++- src/da65/main.c | 16 +++ src/da65/scanner.c | 245 ++++++++++++++++++++++++++++++++++++++------- src/da65/scanner.h | 2 + 4 files changed, 245 insertions(+), 38 deletions(-) diff --git a/doc/da65.sgml b/doc/da65.sgml index a8e32e1c8..df4b05060 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -53,6 +53,7 @@ Short options: -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 -V Print the disassembler version @@ -70,6 +71,7 @@ Long options: --mnemonic-column n Specify mnemonic start column --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 --text-column n Specify text start column --verbose Increase verbosity --version Print the disassembler version @@ -205,6 +207,17 @@ Here is a description of all the command line options: start address is specified, $10000 minus the size of the input file is used. + <label id="option--sync-lines"> + <tag><tt>-s, --sync-lines</tt></tag> + + Accept line markers in the info file in the following syntax: +<tscreen><verb> +#line <lineno> ["<filename>"] +# <lineno> "<filename>" [<flag>] ... +</verb></tscreen> + This option is intended for preprocessing info files with "cpp" or "m4". + + <label id="option--text-column"> <tag><tt>--text-column n</tt></tag> @@ -299,9 +312,10 @@ anything). Each attribute is terminated by a semicolon. <sect1>Comments<p> -Comments start with a hash mark (<tt/#/); and, extend from the position of -the mark to the end of the current line. Hash marks inside of strings will -<em/not/ start a comment, of course. +Comments start with a hash mark (<tt/#/) or a double slashe (<tt>//</tt>); +and, extend from the position of the mark to the end of the current line. +Hash marks or double slashes inside of strings will <em/not/ start a comment, +of course. <sect1>Specifying global options<label id="global-options"><p> diff --git a/src/da65/main.c b/src/da65/main.c index 1454d01fb..6ce5f32af 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -82,6 +82,7 @@ static void Usage (void) " -v\t\t\tIncrease verbosity\n" " -F\t\t\tAdd formfeeds to the output\n" " -S addr\t\tSet the start/load address\n" + " -s\t\t\tAccept line markers in the info file\n" " -V\t\t\tPrint the disassembler version\n" "\n" "Long options:\n" @@ -98,6 +99,7 @@ static void Usage (void) " --mnemonic-column n\tSpecify mnemonic start column\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" " --text-column n\tSpecify text start column\n" " --verbose\t\tIncrease verbosity\n" " --version\t\tPrint the disassembler version\n", @@ -312,6 +314,15 @@ static void OptStartAddr (const char* Opt, const char* Arg) +static void OptSyncLines (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Handle the --sync-lines option */ +{ + InfoSyncLines = 1; +} + + + static void OptTextColumn (const char* Opt, const char* Arg) /* Handle the --text-column option */ { @@ -539,6 +550,7 @@ int main (int argc, char* argv []) { "--mnemonic-column", 1, OptMnemonicColumn }, { "--pagelength", 1, OptPageLength }, { "--start-addr", 1, OptStartAddr }, + { "--sync-lines", 0, OptSyncLines }, { "--text-column", 1, OptTextColumn }, { "--verbose", 0, OptVerbose }, { "--version", 0, OptVersion }, @@ -589,6 +601,10 @@ int main (int argc, char* argv []) OptStartAddr (Arg, GetArg (&I, 2)); break; + case 's': + OptSyncLines (Arg, 0); + break; + case 'V': OptVersion (Arg, 0); break; diff --git a/src/da65/scanner.c b/src/da65/scanner.c index 8dc8d393a..567b51348 100644 --- a/src/da65/scanner.c +++ b/src/da65/scanner.c @@ -41,6 +41,8 @@ /* common */ #include "chartype.h" #include "xsprintf.h" +#include "xmalloc.h" +#include "strbuf.h" /* ld65 */ #include "global.h" @@ -72,7 +74,10 @@ static int C = ' '; static unsigned InputLine = 1; static unsigned InputCol = 0; static FILE* InputFile = 0; +static char* InputSrcName = 0; +/* Options */ +unsigned char InfoSyncLines = 0; /*****************************************************************************/ @@ -91,7 +96,8 @@ void InfoWarning (const char* Format, ...) xvsprintf (Buf, sizeof (Buf), Format, ap); va_end (ap); - Warning ("%s(%u): %s", InfoFile, InfoErrorLine, Buf); + fprintf (stderr, "%s(%u): Warning: %s\n", + InputSrcName, InfoErrorLine, Buf); } @@ -106,7 +112,9 @@ void InfoError (const char* Format, ...) xvsprintf (Buf, sizeof (Buf), Format, ap); va_end (ap); - Error ("%s(%u): %s", InfoFile, InfoErrorLine, Buf); + fprintf (stderr, "%s(%u): Error: %s\n", + InputSrcName, InfoErrorLine, Buf); + exit (EXIT_FAILURE); } @@ -149,17 +157,171 @@ static unsigned DigitVal (int C) +static void SkipBlanks (int SingleLine) +{ + while (C != EOF && (!SingleLine || C != '\n') && IsSpace (C)) { + NextChar (); + } +} + +static long GetDecimalToken () +{ + long Value = 0; + + while (C != EOF && IsDigit (C)) { + Value = Value * 10 + DigitVal (C); + NextChar (); + } + return Value; +} + +static int GetEncodedChar (char *Buf, unsigned *IPtr, unsigned Size) +{ + char Decoded = 0; + int Count; + + if (C == EOF) { + return -1; + } else if (C != '\\') { + Decoded = C; + NextChar (); + goto Store; + } + NextChar (); /* consume '\\' */ + if (C == EOF) { + return -1; + } else if (IsODigit (C)) { + Count = 3; + do { + Decoded = Decoded * 8 + DigitVal (C); + NextChar (); + --Count; + } while (Count > 0 && C != EOF && IsODigit (C)); + } else if (C == 'x') { + NextChar (); /* consume 'x' */ + Count = 2; + while (Count > 0 && C != EOF && IsXDigit (C)) { + Decoded = Decoded * 16 + DigitVal (C); + NextChar (); + --Count; + } + } else { + switch (C) { + case '"': case '\'': case '\\': + Decoded = C; break; + case 't': Decoded = '\t'; break; + case 'r': Decoded = '\r'; break; + case 'n': Decoded = '\n'; break; + default: return -1; + } + NextChar (); + } +Store: + if (*IPtr < Size - 1) { + Buf [(*IPtr)++] = Decoded; + } + Buf [*IPtr] = 0; + return 0; +} + +static void LineMarkerOrComment () +/* Handle a line beginning with '#'. Possible interpretations are: + * - #line <lineno> ["<filename>"] (C preprocessor input) + * - # <lineno> "<filename>" [<flag>]... (gcc preprocessor output) + * - #<comment> + */ +{ + unsigned long LineNo = 0; + int LineDirective = 0; + StrBuf SrcNameBuf = AUTO_STRBUF_INITIALIZER; + + /* Skip the first "# " */ + NextChar (); + SkipBlanks (1); + + /* Check "line" */ + if (C == 'l') { + char MaybeLine [6]; + unsigned I; + for (I = 0; I < sizeof MaybeLine - 1 && C != EOF && IsAlNum (C); ++I) { + MaybeLine [I] = C; + NextChar (); + } + MaybeLine [I] = 0; + if (strcmp (MaybeLine, "line") != 0) { + goto NotMarker; + } + LineDirective = 1; + SkipBlanks (1); + } + + /* Get line number */ + if (C == EOF || !IsDigit (C)) { + goto NotMarker; + } + LineNo = GetDecimalToken (); + SkipBlanks (1); + + /* Get the source file name */ + if (C != '\"') { + /* The source file name is missing */ + if (LineDirective && C == '\n') { + /* got #line <lineno> */ + NextChar (); + InputLine = LineNo; + goto Last; + } else { + goto NotMarker; + } + } + NextChar (); + while (C != EOF && C != '\n' && C != '\"') { + char DecodeBuf [2]; + unsigned I = 0; + if (GetEncodedChar (DecodeBuf, &I, sizeof DecodeBuf) < 0) { + goto BadMarker; + } + SB_AppendBuf (&SrcNameBuf, DecodeBuf, I); + } + if (C != '\"') { + goto BadMarker; + } + NextChar (); + + /* Ignore until the end of line */ + while (C != EOF && C != '\n') { + NextChar (); + } + + /* Accepted a line marker */ + SB_Terminate (&SrcNameBuf); + xfree (InputSrcName); + InputSrcName = SB_GetBuf (&SrcNameBuf); + SB_Init (&SrcNameBuf); + InputLine = (unsigned)LineNo; + NextChar (); + goto Last; + +BadMarker: + InfoWarning ("Bad line marker"); +NotMarker: + while (C != EOF && C != '\n') { + NextChar (); + } + NextChar (); +Last: + SB_Done (&SrcNameBuf); +} + void InfoNextTok (void) /* Read the next token from the input stream */ { unsigned I; - int Esc; + char DecodeBuf [2]; Again: /* Skip whitespace */ - while (IsSpace (C)) { - NextChar (); - } + SkipBlanks (0); /* Remember the current position */ InfoErrorLine = InputLine; @@ -198,11 +360,7 @@ Again: /* Decimal number? */ if (IsDigit (C)) { - InfoIVal = 0; - while (IsDigit (C)) { - InfoIVal = InfoIVal * 10 + DigitVal (C); - NextChar (); - } + InfoIVal = GetDecimalToken (); InfoTok = INFOTOK_INTCON; return; } @@ -248,38 +406,31 @@ Again: case '\"': NextChar (); I = 0; - while (C != '\"') { - Esc = (C == '\\'); - if (Esc) { - NextChar (); - } - if (C == EOF || C == '\n') { - InfoError ("Unterminated string"); - } - if (Esc) { - switch (C) { - case '\"': C = '\"'; break; - case '\'': C = '\''; break; - default: InfoError ("Invalid escape char: %c", C); + while (C != EOF && C != '\"') { + if (GetEncodedChar (InfoSVal, &I, sizeof InfoSVal) < 0) { + if (C == EOF) { + InfoError ("Unterminated string"); + } else { + InfoError ("Invalid escape char: %c", C); } } - if (I < CFG_MAX_IDENT_LEN) { - InfoSVal [I++] = C; - } - NextChar (); } - NextChar (); - InfoSVal [I] = '\0'; + if (C != '\"') { + InfoError ("Unterminated string"); + } + NextChar (); InfoTok = INFOTOK_STRCON; break; case '\'': NextChar (); - if (C == EOF || IsControl (C)) { + if (C == EOF || IsControl (C) || C == '\'') { InfoError ("Invalid character constant"); } - InfoIVal = C; - NextChar (); + if (GetEncodedChar (DecodeBuf, &I, sizeof DecodeBuf) < 0 || I != 1) { + InfoError ("Invalid character constant"); + } + InfoIVal = DecodeBuf [0]; if (C != '\'') { InfoError ("Unterminated character constant"); } @@ -288,8 +439,13 @@ Again: break; case '#': - /* Comment */ - while (C != '\n' && C != EOF) { + /* # lineno "sourcefile" or # comment */ + if (InfoSyncLines && InputCol == 1) { + LineMarkerOrComment (); + } else { + do { + NextChar (); + } while (C != EOF && C != '\n'); NextChar (); } if (C != EOF) { @@ -298,6 +454,21 @@ Again: InfoTok = INFOTOK_EOF; break; + case '/': + /* C++ style comment */ + NextChar (); + if (C != '/') { + InfoError ("Invalid token `/'"); + } + do { + NextChar (); + } while (C != '\n' && C != EOF); + if (C != EOF) { + goto Again; + } + InfoTok = INFOTOK_EOF; + break; + case EOF: InfoTok = INFOTOK_EOF; break; @@ -484,15 +655,19 @@ void InfoSetName (const char* Name) /* Set a name for a config file */ { InfoFile = Name; + xfree(InputSrcName); + InputSrcName = xstrdup(Name); } +#ifdef unused const char* InfoGetName (void) /* Get the name of the config file */ { return InfoFile? InfoFile : ""; } +#endif /* unused */ diff --git a/src/da65/scanner.h b/src/da65/scanner.h index f7f090fad..1dcecf68f 100644 --- a/src/da65/scanner.h +++ b/src/da65/scanner.h @@ -137,6 +137,8 @@ extern long InfoIVal; extern unsigned InfoErrorLine; extern unsigned InfoErrorCol; +/* Options */ +extern unsigned char InfoSyncLines; /*****************************************************************************/ From 03bb2f6a48ffdb67f350a7ae189b3e3bb96175eb Mon Sep 17 00:00:00 2001 From: AIDA Shinra <shinra@j10n.org> Date: Tue, 12 Jun 2018 00:18:11 +0900 Subject: [PATCH 0745/2161] Followed discussions in the Pull reequest #681. In particular, renamed "virtual operands" to "inline parameters". --- doc/da65.sgml | 12 ++++++------ src/da65/handler.c | 24 ++++++++++++++---------- src/da65/handler.h | 2 +- src/da65/infofile.c | 16 ++++++++-------- src/da65/scanner.h | 2 +- 5 files changed, 30 insertions(+), 26 deletions(-) diff --git a/doc/da65.sgml b/doc/da65.sgml index c2d87ac92..15ce7c424 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -542,16 +542,16 @@ code. The following attributes are recognized: range, where <tt/label/ is the label name given with the <tt/NAME/ attribute, and <tt/offs/ is the offset within the data. - <tag><tt>VOPERAND</tt></tag> + <tag><tt>PARAMSIZE</tt></tag> This optional attribute is followed by a numerical value. It tells the - assembler that subroutine calls to this label follow "virtual operands" + assembler that subroutine calls to this label follow "inline parameters" of the given bytes like this: <tscreen><verb> - JSR LabelWith2BytesOfVoperand - .byte $00, $10 ; virtual operands - ; return here - BIT $0F + JSR LabelWithParamSize2 + .byte $00, $10 + (return here) + code... </verb></tscreen> </descrip> diff --git a/src/da65/handler.c b/src/da65/handler.c index 19b8946de..a5adb413e 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -51,7 +51,7 @@ -static unsigned short SubroutineVOperandSize[0x10000]; +static unsigned short SubroutineParamSize[0x10000]; /*****************************************************************************/ /* Helper functions */ @@ -748,18 +748,22 @@ void OH_JmpAbsoluteXIndirect (const OpcDesc* D) void OH_JsrAbsolute (const OpcDesc* D) { - unsigned VOperandSize = SubroutineVOperandSize[GetCodeWord(PC+1)]; + unsigned ParamSize = SubroutineParamSize[GetCodeWord(PC+1)]; OH_Absolute (D); - if (VOperandSize > 0) { + if (ParamSize > 0) { unsigned RemainingBytes; + unsigned BytesLeft; PC += D->Size; RemainingBytes = GetRemainingBytes(); - if (RemainingBytes < VOperandSize) { - VOperandSize = RemainingBytes; + if (RemainingBytes < ParamSize) { + ParamSize = RemainingBytes; } - if (VOperandSize > 0) { - DataByteLine (VOperandSize); /* FIXME: follow BytesPerLine */ - PC += VOperandSize; + BytesLeft = ParamSize; + while (BytesLeft > 0) { + unsigned Chunk = (BytesLeft > BytesPerLine)? BytesPerLine : BytesLeft; + DataByteLine (Chunk); + BytesLeft -= Chunk; + PC += Chunk; } PC -= D->Size; } @@ -767,7 +771,7 @@ void OH_JsrAbsolute (const OpcDesc* D) -void SetSubroutineVOperand (unsigned Addr, unsigned Size) +void SetSubroutineParamSize (unsigned Addr, unsigned Size) { - SubroutineVOperandSize[Addr] = Size; + SubroutineParamSize[Addr] = Size; } diff --git a/src/da65/handler.h b/src/da65/handler.h index 96b73f2c7..eaa66e7fd 100644 --- a/src/da65/handler.h +++ b/src/da65/handler.h @@ -106,7 +106,7 @@ void OH_JmpAbsoluteIndirect (const OpcDesc* D); void OH_JmpAbsoluteXIndirect (const OpcDesc* D); void OH_JsrAbsolute (const OpcDesc*); -void SetSubroutineVOperand (unsigned Addr, unsigned Size); +void SetSubroutineParamSize (unsigned Addr, unsigned Size); /* End of handler.h */ diff --git a/src/da65/infofile.c b/src/da65/infofile.c index 3bfa15f51..c5040e82a 100644 --- a/src/da65/infofile.c +++ b/src/da65/infofile.c @@ -381,7 +381,7 @@ static void LabelSection (void) { "ADDR", INFOTOK_ADDR }, { "NAME", INFOTOK_NAME }, { "SIZE", INFOTOK_SIZE }, - { "VOPERAND", INFOTOK_VOPERAND }, + { "PARAMSIZE", INFOTOK_PARAMSIZE }, }; /* Locals - initialize to avoid gcc warnings */ @@ -389,7 +389,7 @@ static void LabelSection (void) char* Comment = 0; long Value = -1; long Size = -1; - long VOperand = -1; + long ParamSize = -1; /* Skip the token */ InfoNextTok (); @@ -451,14 +451,14 @@ static void LabelSection (void) InfoNextTok (); break; - case INFOTOK_VOPERAND: + case INFOTOK_PARAMSIZE: InfoNextTok (); - if (VOperand >= 0) { - InfoError ("VOperand already given"); + if (ParamSize >= 0) { + InfoError ("ParamSize already given"); } InfoAssureInt (); InfoRangeCheck (1, 0x10000); - VOperand = InfoIVal; + ParamSize = InfoIVal; InfoNextTok (); break; @@ -498,8 +498,8 @@ static void LabelSection (void) } else { AddExtLabelRange ((unsigned) Value, Name, Size); } - if (VOperand >= 0) { - SetSubroutineVOperand ((unsigned) Value, (unsigned) VOperand); + if (ParamSize >= 0) { + SetSubroutineParamSize ((unsigned) Value, (unsigned) ParamSize); } /* Define the comment */ diff --git a/src/da65/scanner.h b/src/da65/scanner.h index 14a3ef679..d4e38177b 100644 --- a/src/da65/scanner.h +++ b/src/da65/scanner.h @@ -105,7 +105,7 @@ typedef enum token_t { INFOTOK_COMMENT, INFOTOK_ADDR, INFOTOK_SIZE, - INFOTOK_VOPERAND, + INFOTOK_PARAMSIZE, /* ASMINC section */ INFOTOK_FILE, From 8899d71cad4d67bd2ecb81cdb5c8da63fa3a6d83 Mon Sep 17 00:00:00 2001 From: AIDA Shinra <shinra@j10n.org> Date: Tue, 12 Jun 2018 02:06:01 +0900 Subject: [PATCH 0746/2161] Followed the discussions in the Pull request #682. * Fixed a misspelling * Fixed styles * Added sample codes --- doc/da65.sgml | 2 +- src/da65/global.c | 1 + src/da65/global.h | 1 + src/da65/main.c | 2 +- src/da65/scanner.c | 17 ++++++++--------- src/da65/scanner.h | 2 -- testcode/disasm/.gitignore | 2 ++ testcode/disasm/bank0.da | 16 ++++++++++++++++ testcode/disasm/bank0.dai | 33 +++++++++++++++++++++++++++++++++ testcode/disasm/bank1.da | 16 ++++++++++++++++ testcode/disasm/bank1.dai | 33 +++++++++++++++++++++++++++++++++ testcode/disasm/fixed.da | 30 ++++++++++++++++++++++++++++++ testcode/disasm/fixed.dai | 25 +++++++++++++++++++++++++ testcode/disasm/sample-unix.mk | 28 ++++++++++++++++++++++++++++ 14 files changed, 195 insertions(+), 13 deletions(-) create mode 100644 testcode/disasm/.gitignore create mode 100644 testcode/disasm/bank0.da create mode 100644 testcode/disasm/bank0.dai create mode 100644 testcode/disasm/bank1.da create mode 100644 testcode/disasm/bank1.dai create mode 100644 testcode/disasm/fixed.da create mode 100644 testcode/disasm/fixed.dai create mode 100644 testcode/disasm/sample-unix.mk diff --git a/doc/da65.sgml b/doc/da65.sgml index df4b05060..0af1918c6 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -312,7 +312,7 @@ anything). Each attribute is terminated by a semicolon. <sect1>Comments<p> -Comments start with a hash mark (<tt/#/) or a double slashe (<tt>//</tt>); +Comments start with a hash mark (<tt/#/) or a double slash (<tt>//</tt>); and, extend from the position of the mark to the end of the current line. Hash marks or double slashes inside of strings will <em/not/ start a comment, of course. diff --git a/src/da65/global.c b/src/da65/global.c index e2b1fd144..7df1bd977 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -59,6 +59,7 @@ 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 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 14b113399..c85c7a79e 100644 --- a/src/da65/global.h +++ b/src/da65/global.h @@ -60,6 +60,7 @@ 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 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/main.c b/src/da65/main.c index 6ce5f32af..b0a784dd8 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -318,7 +318,7 @@ static void OptSyncLines (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Handle the --sync-lines option */ { - InfoSyncLines = 1; + SyncLines = 1; } diff --git a/src/da65/scanner.c b/src/da65/scanner.c index 567b51348..a579939f9 100644 --- a/src/da65/scanner.c +++ b/src/da65/scanner.c @@ -76,8 +76,6 @@ static unsigned InputCol = 0; static FILE* InputFile = 0; static char* InputSrcName = 0; -/* Options */ -unsigned char InfoSyncLines = 0; /*****************************************************************************/ @@ -119,6 +117,7 @@ void InfoError (const char* Format, ...) + /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -164,7 +163,7 @@ static void SkipBlanks (int SingleLine) } } -static long GetDecimalToken () +static long GetDecimalToken (void) { long Value = 0; @@ -226,15 +225,15 @@ Store: static void LineMarkerOrComment () /* Handle a line beginning with '#'. Possible interpretations are: - * - #line <lineno> ["<filename>"] (C preprocessor input) - * - # <lineno> "<filename>" [<flag>]... (gcc preprocessor output) - * - #<comment> - */ +** - #line <lineno> ["<filename>"] (C preprocessor input) +** - # <lineno> "<filename>" [<flag>]... (gcc preprocessor output) +** - #<comment> +*/ { unsigned long LineNo = 0; int LineDirective = 0; StrBuf SrcNameBuf = AUTO_STRBUF_INITIALIZER; - + /* Skip the first "# " */ NextChar (); SkipBlanks (1); @@ -440,7 +439,7 @@ Again: case '#': /* # lineno "sourcefile" or # comment */ - if (InfoSyncLines && InputCol == 1) { + if (SyncLines && InputCol == 1) { LineMarkerOrComment (); } else { do { diff --git a/src/da65/scanner.h b/src/da65/scanner.h index 1dcecf68f..f7f090fad 100644 --- a/src/da65/scanner.h +++ b/src/da65/scanner.h @@ -137,8 +137,6 @@ extern long InfoIVal; extern unsigned InfoErrorLine; extern unsigned InfoErrorCol; -/* Options */ -extern unsigned char InfoSyncLines; /*****************************************************************************/ diff --git a/testcode/disasm/.gitignore b/testcode/disasm/.gitignore new file mode 100644 index 000000000..46c4eca80 --- /dev/null +++ b/testcode/disasm/.gitignore @@ -0,0 +1,2 @@ +*.s +image.bin diff --git a/testcode/disasm/bank0.da b/testcode/disasm/bank0.da new file mode 100644 index 000000000..4fb96ce93 --- /dev/null +++ b/testcode/disasm/bank0.da @@ -0,0 +1,16 @@ +// Da65 input file before preprocessed by cpp +// Bank0 ROM map + +#define TARGET_BANK 0 +global { + inputoffs $00010; + inputsize $4000; + startaddr $8000; + cpu "6502"; +}; + +#include "fixed.da" + +label { addr $8000; name "Bank0ProcA"; }; +label { addr $8123; name "Bank0ProcB"; }; +range { start $A000; end $BFFF; name "Bank0Data"; type ByteTable; }; diff --git a/testcode/disasm/bank0.dai b/testcode/disasm/bank0.dai new file mode 100644 index 000000000..2d865e77c --- /dev/null +++ b/testcode/disasm/bank0.dai @@ -0,0 +1,33 @@ +# 1 "bank0.da" +# 1 "<built-in>" +# 1 "<command-line>" +# 1 "bank0.da" + + + + +global { + inputoffs $00010; + inputsize $4000; + startaddr $8000; + cpu "6502"; +}; + +# 1 "fixed.da" 1 +# 18 "fixed.da" +label { addr $00; name "VariableA"; }; +label { addr $01; name "VariableB"; }; +label { addr $0100; name "Stack"; size $0100; }; + + + + + +label { addr $C000; name "CommonProcA"; }; +label { addr $C123; name "CommonProcB"; }; +range { start $E123; end $FFFF; name "CommonData"; type ByteTable; }; +# 13 "bank0.da" 2 + +label { addr $8000; name "Bank0ProcA"; }; +label { addr $8123; name "Bank0ProcB"; }; +range { start $A000; end $BFFF; name "Bank0Data"; type ByteTable; }; diff --git a/testcode/disasm/bank1.da b/testcode/disasm/bank1.da new file mode 100644 index 000000000..fd5e324a9 --- /dev/null +++ b/testcode/disasm/bank1.da @@ -0,0 +1,16 @@ +// Da65 input file before preprocessed by cpp +// Bank1 ROM map + +#define TARGET_BANK 1 +global { + inputoffs $04010; + inputsize $4000; + startaddr $8000; + cpu "6502"; +}; + +#include "fixed.da" + +range { start $8000; end $AFFF; name "Bank1Data"; type ByteTable; }; +label { addr $B000; name "Bank1ProcA"; }; +label { addr $B123; name "Bank1ProcB"; }; diff --git a/testcode/disasm/bank1.dai b/testcode/disasm/bank1.dai new file mode 100644 index 000000000..2b5b68532 --- /dev/null +++ b/testcode/disasm/bank1.dai @@ -0,0 +1,33 @@ +# 1 "bank1.da" +# 1 "<built-in>" +# 1 "<command-line>" +# 1 "bank1.da" + + + + +global { + inputoffs $04010; + inputsize $4000; + startaddr $8000; + cpu "6502"; +}; + +# 1 "fixed.da" 1 +# 18 "fixed.da" +label { addr $00; name "VariableA"; }; +label { addr $01; name "VariableB"; }; +label { addr $0100; name "Stack"; size $0100; }; + + + + + +label { addr $C000; name "CommonProcA"; }; +label { addr $C123; name "CommonProcB"; }; +range { start $E123; end $FFFF; name "CommonData"; type ByteTable; }; +# 13 "bank1.da" 2 + +range { start $8000; end $AFFF; name "Bank1Data"; type ByteTable; }; +label { addr $B000; name "Bank1ProcA"; }; +label { addr $B123; name "Bank1ProcB"; }; diff --git a/testcode/disasm/fixed.da b/testcode/disasm/fixed.da new file mode 100644 index 000000000..e8aa03427 --- /dev/null +++ b/testcode/disasm/fixed.da @@ -0,0 +1,30 @@ +// Da65 input file before preprocessed by cpp +// RAM and Fixed ROM map + +#ifndef FIXED_DA_INCLUDED +#define FIXED_DA_INCLUDED + +#ifndef TARGET_BANK +#define TARGET_BANK -1 +global { + inputoffs $1C010; + inputsize $4000; + startaddr $C000; + cpu "6502"; +}; +#endif /* !defined(TARGET_BANK) */ + +// ---- RAM map ---- +label { addr $00; name "VariableA"; }; +label { addr $01; name "VariableB"; }; +label { addr $0100; name "Stack"; size $0100; }; +#if defined(TEST_ERROR) && TARGET_BANK == 0 +erroneous_line; +#endif + +// ---- Fixed ROM map ---- +label { addr $C000; name "CommonProcA"; }; +label { addr $C123; name "CommonProcB"; }; +range { start $E123; end $FFFF; name "CommonData"; type ByteTable; }; + +#endif /* !defined(FIXED_DA_INCLUDED) */ diff --git a/testcode/disasm/fixed.dai b/testcode/disasm/fixed.dai new file mode 100644 index 000000000..d73155cf0 --- /dev/null +++ b/testcode/disasm/fixed.dai @@ -0,0 +1,25 @@ +# 1 "fixed.da" +# 1 "<built-in>" +# 1 "<command-line>" +# 1 "fixed.da" +# 9 "fixed.da" +global { + inputoffs $1C010; + inputsize $4000; + startaddr $C000; + cpu "6502"; +}; + + + +label { addr $00; name "VariableA"; }; +label { addr $01; name "VariableB"; }; +label { addr $0100; name "Stack"; size $0100; }; + + + + + +label { addr $C000; name "CommonProcA"; }; +label { addr $C123; name "CommonProcB"; }; +range { start $E123; end $FFFF; name "CommonData"; type ByteTable; }; diff --git a/testcode/disasm/sample-unix.mk b/testcode/disasm/sample-unix.mk new file mode 100644 index 000000000..0ef64a5e5 --- /dev/null +++ b/testcode/disasm/sample-unix.mk @@ -0,0 +1,28 @@ +# Sample makefile using a preprocessor against info files +# and the --sync-lines option + +CPP = env LANG=C cpp +CPPFLAGS = # -DTEST_ERROR + +ASMS = fixed.s bank0.s bank1.s +DAIS = fixed.dai bank0.dai bank1.dai + +.SUFFIXES: .da .dai .s +.PHONY: all clean maintainer-clean +.SECONDARY: $(DAIS) + +.da.dai: + $(CPP) -o $@ $(CPPFLAGS) $< + +.dai.s: + da65 --sync-lines -o $@ -i $< image.bin + +all: $(ASMS) + +clean: + rm -f $(ASMS) + +maintainer-clean: clean + rm -f $(DAIS) + +$(DAIS): fixed.da From a3ab3cb4587c0cbb12509c0cbcfea196904abd6c Mon Sep 17 00:00:00 2001 From: AIDA Shinra <shinra@j10n.org> Date: Wed, 13 Jun 2018 01:23:01 +0900 Subject: [PATCH 0747/2161] Changed the wording of the doc/da65.sgml. --- doc/da65.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/da65.sgml b/doc/da65.sgml index 15ce7c424..54a341615 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -544,8 +544,8 @@ code. The following attributes are recognized: <tag><tt>PARAMSIZE</tt></tag> This optional attribute is followed by a numerical value. It tells the - assembler that subroutine calls to this label follow "inline parameters" - of the given bytes like this: + assembler that subroutine calls to this label are followed by + "inline parameters" with the given number of bytes, like this: <tscreen><verb> JSR LabelWithParamSize2 From 75c4972021b2935ac48988f57ecfe94b9858eb95 Mon Sep 17 00:00:00 2001 From: AIDA Shinra <shinra@j10n.org> Date: Wed, 13 Jun 2018 21:24:34 +0900 Subject: [PATCH 0748/2161] Style and alignment fixes. --- src/da65/handler.c | 8 ++++---- src/da65/infofile.c | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/da65/handler.c b/src/da65/handler.c index a5adb413e..f8a778b22 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -748,19 +748,19 @@ void OH_JmpAbsoluteXIndirect (const OpcDesc* D) void OH_JsrAbsolute (const OpcDesc* D) { - unsigned ParamSize = SubroutineParamSize[GetCodeWord(PC+1)]; + unsigned ParamSize = SubroutineParamSize[GetCodeWord (PC+1)]; OH_Absolute (D); if (ParamSize > 0) { unsigned RemainingBytes; - unsigned BytesLeft; + unsigned BytesLeft; PC += D->Size; - RemainingBytes = GetRemainingBytes(); + RemainingBytes = GetRemainingBytes (); if (RemainingBytes < ParamSize) { ParamSize = RemainingBytes; } BytesLeft = ParamSize; while (BytesLeft > 0) { - unsigned Chunk = (BytesLeft > BytesPerLine)? BytesPerLine : BytesLeft; + unsigned Chunk = (BytesLeft > BytesPerLine) ? BytesPerLine : BytesLeft; DataByteLine (Chunk); BytesLeft -= Chunk; PC += Chunk; diff --git a/src/da65/infofile.c b/src/da65/infofile.c index c5040e82a..6db82cb36 100644 --- a/src/da65/infofile.c +++ b/src/da65/infofile.c @@ -377,19 +377,19 @@ static void LabelSection (void) /* Parse a label section */ { static const IdentTok LabelDefs[] = { - { "COMMENT", INFOTOK_COMMENT }, - { "ADDR", INFOTOK_ADDR }, - { "NAME", INFOTOK_NAME }, - { "SIZE", INFOTOK_SIZE }, - { "PARAMSIZE", INFOTOK_PARAMSIZE }, + { "COMMENT", INFOTOK_COMMENT }, + { "ADDR", INFOTOK_ADDR }, + { "NAME", INFOTOK_NAME }, + { "SIZE", INFOTOK_SIZE }, + { "PARAMSIZE", INFOTOK_PARAMSIZE }, }; /* Locals - initialize to avoid gcc warnings */ - char* Name = 0; - char* Comment = 0; - long Value = -1; - long Size = -1; - long ParamSize = -1; + char* Name = 0; + char* Comment = 0; + long Value = -1; + long Size = -1; + long ParamSize = -1; /* Skip the token */ InfoNextTok (); From 2b2532942353fc2b7e7ce76c008d2c294ee16f8a Mon Sep 17 00:00:00 2001 From: AIDA Shinra <shinra@j10n.org> Date: Mon, 11 Jun 2018 01:53:35 +0900 Subject: [PATCH 0749/2161] Support for preprocessing info file via cpp or m4. --- doc/da65.sgml | 20 +++- src/da65/main.c | 16 +++ src/da65/scanner.c | 245 ++++++++++++++++++++++++++++++++++++++------- src/da65/scanner.h | 2 + 4 files changed, 245 insertions(+), 38 deletions(-) diff --git a/doc/da65.sgml b/doc/da65.sgml index 54a341615..c59840389 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -53,6 +53,7 @@ Short options: -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 -V Print the disassembler version @@ -70,6 +71,7 @@ Long options: --mnemonic-column n Specify mnemonic start column --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 --text-column n Specify text start column --verbose Increase verbosity --version Print the disassembler version @@ -205,6 +207,17 @@ Here is a description of all the command line options: start address is specified, $10000 minus the size of the input file is used. + <label id="option--sync-lines"> + <tag><tt>-s, --sync-lines</tt></tag> + + Accept line markers in the info file in the following syntax: +<tscreen><verb> +#line <lineno> ["<filename>"] +# <lineno> "<filename>" [<flag>] ... +</verb></tscreen> + This option is intended for preprocessing info files with "cpp" or "m4". + + <label id="option--text-column"> <tag><tt>--text-column n</tt></tag> @@ -299,9 +312,10 @@ anything). Each attribute is terminated by a semicolon. <sect1>Comments<p> -Comments start with a hash mark (<tt/#/); and, extend from the position of -the mark to the end of the current line. Hash marks inside of strings will -<em/not/ start a comment, of course. +Comments start with a hash mark (<tt/#/) or a double slashe (<tt>//</tt>); +and, extend from the position of the mark to the end of the current line. +Hash marks or double slashes inside of strings will <em/not/ start a comment, +of course. <sect1>Specifying global options<label id="global-options"><p> diff --git a/src/da65/main.c b/src/da65/main.c index 1454d01fb..6ce5f32af 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -82,6 +82,7 @@ static void Usage (void) " -v\t\t\tIncrease verbosity\n" " -F\t\t\tAdd formfeeds to the output\n" " -S addr\t\tSet the start/load address\n" + " -s\t\t\tAccept line markers in the info file\n" " -V\t\t\tPrint the disassembler version\n" "\n" "Long options:\n" @@ -98,6 +99,7 @@ static void Usage (void) " --mnemonic-column n\tSpecify mnemonic start column\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" " --text-column n\tSpecify text start column\n" " --verbose\t\tIncrease verbosity\n" " --version\t\tPrint the disassembler version\n", @@ -312,6 +314,15 @@ static void OptStartAddr (const char* Opt, const char* Arg) +static void OptSyncLines (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Handle the --sync-lines option */ +{ + InfoSyncLines = 1; +} + + + static void OptTextColumn (const char* Opt, const char* Arg) /* Handle the --text-column option */ { @@ -539,6 +550,7 @@ int main (int argc, char* argv []) { "--mnemonic-column", 1, OptMnemonicColumn }, { "--pagelength", 1, OptPageLength }, { "--start-addr", 1, OptStartAddr }, + { "--sync-lines", 0, OptSyncLines }, { "--text-column", 1, OptTextColumn }, { "--verbose", 0, OptVerbose }, { "--version", 0, OptVersion }, @@ -589,6 +601,10 @@ int main (int argc, char* argv []) OptStartAddr (Arg, GetArg (&I, 2)); break; + case 's': + OptSyncLines (Arg, 0); + break; + case 'V': OptVersion (Arg, 0); break; diff --git a/src/da65/scanner.c b/src/da65/scanner.c index 8dc8d393a..567b51348 100644 --- a/src/da65/scanner.c +++ b/src/da65/scanner.c @@ -41,6 +41,8 @@ /* common */ #include "chartype.h" #include "xsprintf.h" +#include "xmalloc.h" +#include "strbuf.h" /* ld65 */ #include "global.h" @@ -72,7 +74,10 @@ static int C = ' '; static unsigned InputLine = 1; static unsigned InputCol = 0; static FILE* InputFile = 0; +static char* InputSrcName = 0; +/* Options */ +unsigned char InfoSyncLines = 0; /*****************************************************************************/ @@ -91,7 +96,8 @@ void InfoWarning (const char* Format, ...) xvsprintf (Buf, sizeof (Buf), Format, ap); va_end (ap); - Warning ("%s(%u): %s", InfoFile, InfoErrorLine, Buf); + fprintf (stderr, "%s(%u): Warning: %s\n", + InputSrcName, InfoErrorLine, Buf); } @@ -106,7 +112,9 @@ void InfoError (const char* Format, ...) xvsprintf (Buf, sizeof (Buf), Format, ap); va_end (ap); - Error ("%s(%u): %s", InfoFile, InfoErrorLine, Buf); + fprintf (stderr, "%s(%u): Error: %s\n", + InputSrcName, InfoErrorLine, Buf); + exit (EXIT_FAILURE); } @@ -149,17 +157,171 @@ static unsigned DigitVal (int C) +static void SkipBlanks (int SingleLine) +{ + while (C != EOF && (!SingleLine || C != '\n') && IsSpace (C)) { + NextChar (); + } +} + +static long GetDecimalToken () +{ + long Value = 0; + + while (C != EOF && IsDigit (C)) { + Value = Value * 10 + DigitVal (C); + NextChar (); + } + return Value; +} + +static int GetEncodedChar (char *Buf, unsigned *IPtr, unsigned Size) +{ + char Decoded = 0; + int Count; + + if (C == EOF) { + return -1; + } else if (C != '\\') { + Decoded = C; + NextChar (); + goto Store; + } + NextChar (); /* consume '\\' */ + if (C == EOF) { + return -1; + } else if (IsODigit (C)) { + Count = 3; + do { + Decoded = Decoded * 8 + DigitVal (C); + NextChar (); + --Count; + } while (Count > 0 && C != EOF && IsODigit (C)); + } else if (C == 'x') { + NextChar (); /* consume 'x' */ + Count = 2; + while (Count > 0 && C != EOF && IsXDigit (C)) { + Decoded = Decoded * 16 + DigitVal (C); + NextChar (); + --Count; + } + } else { + switch (C) { + case '"': case '\'': case '\\': + Decoded = C; break; + case 't': Decoded = '\t'; break; + case 'r': Decoded = '\r'; break; + case 'n': Decoded = '\n'; break; + default: return -1; + } + NextChar (); + } +Store: + if (*IPtr < Size - 1) { + Buf [(*IPtr)++] = Decoded; + } + Buf [*IPtr] = 0; + return 0; +} + +static void LineMarkerOrComment () +/* Handle a line beginning with '#'. Possible interpretations are: + * - #line <lineno> ["<filename>"] (C preprocessor input) + * - # <lineno> "<filename>" [<flag>]... (gcc preprocessor output) + * - #<comment> + */ +{ + unsigned long LineNo = 0; + int LineDirective = 0; + StrBuf SrcNameBuf = AUTO_STRBUF_INITIALIZER; + + /* Skip the first "# " */ + NextChar (); + SkipBlanks (1); + + /* Check "line" */ + if (C == 'l') { + char MaybeLine [6]; + unsigned I; + for (I = 0; I < sizeof MaybeLine - 1 && C != EOF && IsAlNum (C); ++I) { + MaybeLine [I] = C; + NextChar (); + } + MaybeLine [I] = 0; + if (strcmp (MaybeLine, "line") != 0) { + goto NotMarker; + } + LineDirective = 1; + SkipBlanks (1); + } + + /* Get line number */ + if (C == EOF || !IsDigit (C)) { + goto NotMarker; + } + LineNo = GetDecimalToken (); + SkipBlanks (1); + + /* Get the source file name */ + if (C != '\"') { + /* The source file name is missing */ + if (LineDirective && C == '\n') { + /* got #line <lineno> */ + NextChar (); + InputLine = LineNo; + goto Last; + } else { + goto NotMarker; + } + } + NextChar (); + while (C != EOF && C != '\n' && C != '\"') { + char DecodeBuf [2]; + unsigned I = 0; + if (GetEncodedChar (DecodeBuf, &I, sizeof DecodeBuf) < 0) { + goto BadMarker; + } + SB_AppendBuf (&SrcNameBuf, DecodeBuf, I); + } + if (C != '\"') { + goto BadMarker; + } + NextChar (); + + /* Ignore until the end of line */ + while (C != EOF && C != '\n') { + NextChar (); + } + + /* Accepted a line marker */ + SB_Terminate (&SrcNameBuf); + xfree (InputSrcName); + InputSrcName = SB_GetBuf (&SrcNameBuf); + SB_Init (&SrcNameBuf); + InputLine = (unsigned)LineNo; + NextChar (); + goto Last; + +BadMarker: + InfoWarning ("Bad line marker"); +NotMarker: + while (C != EOF && C != '\n') { + NextChar (); + } + NextChar (); +Last: + SB_Done (&SrcNameBuf); +} + void InfoNextTok (void) /* Read the next token from the input stream */ { unsigned I; - int Esc; + char DecodeBuf [2]; Again: /* Skip whitespace */ - while (IsSpace (C)) { - NextChar (); - } + SkipBlanks (0); /* Remember the current position */ InfoErrorLine = InputLine; @@ -198,11 +360,7 @@ Again: /* Decimal number? */ if (IsDigit (C)) { - InfoIVal = 0; - while (IsDigit (C)) { - InfoIVal = InfoIVal * 10 + DigitVal (C); - NextChar (); - } + InfoIVal = GetDecimalToken (); InfoTok = INFOTOK_INTCON; return; } @@ -248,38 +406,31 @@ Again: case '\"': NextChar (); I = 0; - while (C != '\"') { - Esc = (C == '\\'); - if (Esc) { - NextChar (); - } - if (C == EOF || C == '\n') { - InfoError ("Unterminated string"); - } - if (Esc) { - switch (C) { - case '\"': C = '\"'; break; - case '\'': C = '\''; break; - default: InfoError ("Invalid escape char: %c", C); + while (C != EOF && C != '\"') { + if (GetEncodedChar (InfoSVal, &I, sizeof InfoSVal) < 0) { + if (C == EOF) { + InfoError ("Unterminated string"); + } else { + InfoError ("Invalid escape char: %c", C); } } - if (I < CFG_MAX_IDENT_LEN) { - InfoSVal [I++] = C; - } - NextChar (); } - NextChar (); - InfoSVal [I] = '\0'; + if (C != '\"') { + InfoError ("Unterminated string"); + } + NextChar (); InfoTok = INFOTOK_STRCON; break; case '\'': NextChar (); - if (C == EOF || IsControl (C)) { + if (C == EOF || IsControl (C) || C == '\'') { InfoError ("Invalid character constant"); } - InfoIVal = C; - NextChar (); + if (GetEncodedChar (DecodeBuf, &I, sizeof DecodeBuf) < 0 || I != 1) { + InfoError ("Invalid character constant"); + } + InfoIVal = DecodeBuf [0]; if (C != '\'') { InfoError ("Unterminated character constant"); } @@ -288,8 +439,13 @@ Again: break; case '#': - /* Comment */ - while (C != '\n' && C != EOF) { + /* # lineno "sourcefile" or # comment */ + if (InfoSyncLines && InputCol == 1) { + LineMarkerOrComment (); + } else { + do { + NextChar (); + } while (C != EOF && C != '\n'); NextChar (); } if (C != EOF) { @@ -298,6 +454,21 @@ Again: InfoTok = INFOTOK_EOF; break; + case '/': + /* C++ style comment */ + NextChar (); + if (C != '/') { + InfoError ("Invalid token `/'"); + } + do { + NextChar (); + } while (C != '\n' && C != EOF); + if (C != EOF) { + goto Again; + } + InfoTok = INFOTOK_EOF; + break; + case EOF: InfoTok = INFOTOK_EOF; break; @@ -484,15 +655,19 @@ void InfoSetName (const char* Name) /* Set a name for a config file */ { InfoFile = Name; + xfree(InputSrcName); + InputSrcName = xstrdup(Name); } +#ifdef unused const char* InfoGetName (void) /* Get the name of the config file */ { return InfoFile? InfoFile : ""; } +#endif /* unused */ diff --git a/src/da65/scanner.h b/src/da65/scanner.h index d4e38177b..b1dc75279 100644 --- a/src/da65/scanner.h +++ b/src/da65/scanner.h @@ -138,6 +138,8 @@ extern long InfoIVal; extern unsigned InfoErrorLine; extern unsigned InfoErrorCol; +/* Options */ +extern unsigned char InfoSyncLines; /*****************************************************************************/ From fd67284b4d1cc3b759da4a00ae175f68c01bd00f Mon Sep 17 00:00:00 2001 From: AIDA Shinra <shinra@j10n.org> Date: Tue, 12 Jun 2018 02:06:01 +0900 Subject: [PATCH 0750/2161] Followed the discussions in the Pull request #682. * Fixed a misspelling * Fixed styles * Added sample codes --- doc/da65.sgml | 2 +- src/da65/global.c | 1 + src/da65/global.h | 1 + src/da65/main.c | 2 +- src/da65/scanner.c | 17 ++++++++--------- src/da65/scanner.h | 2 -- testcode/disasm/.gitignore | 2 ++ testcode/disasm/bank0.da | 16 ++++++++++++++++ testcode/disasm/bank0.dai | 33 +++++++++++++++++++++++++++++++++ testcode/disasm/bank1.da | 16 ++++++++++++++++ testcode/disasm/bank1.dai | 33 +++++++++++++++++++++++++++++++++ testcode/disasm/fixed.da | 30 ++++++++++++++++++++++++++++++ testcode/disasm/fixed.dai | 25 +++++++++++++++++++++++++ testcode/disasm/sample-unix.mk | 28 ++++++++++++++++++++++++++++ 14 files changed, 195 insertions(+), 13 deletions(-) create mode 100644 testcode/disasm/.gitignore create mode 100644 testcode/disasm/bank0.da create mode 100644 testcode/disasm/bank0.dai create mode 100644 testcode/disasm/bank1.da create mode 100644 testcode/disasm/bank1.dai create mode 100644 testcode/disasm/fixed.da create mode 100644 testcode/disasm/fixed.dai create mode 100644 testcode/disasm/sample-unix.mk diff --git a/doc/da65.sgml b/doc/da65.sgml index c59840389..05154ffd8 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -312,7 +312,7 @@ anything). Each attribute is terminated by a semicolon. <sect1>Comments<p> -Comments start with a hash mark (<tt/#/) or a double slashe (<tt>//</tt>); +Comments start with a hash mark (<tt/#/) or a double slash (<tt>//</tt>); and, extend from the position of the mark to the end of the current line. Hash marks or double slashes inside of strings will <em/not/ start a comment, of course. diff --git a/src/da65/global.c b/src/da65/global.c index e2b1fd144..7df1bd977 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -59,6 +59,7 @@ 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 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 14b113399..c85c7a79e 100644 --- a/src/da65/global.h +++ b/src/da65/global.h @@ -60,6 +60,7 @@ 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 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/main.c b/src/da65/main.c index 6ce5f32af..b0a784dd8 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -318,7 +318,7 @@ static void OptSyncLines (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Handle the --sync-lines option */ { - InfoSyncLines = 1; + SyncLines = 1; } diff --git a/src/da65/scanner.c b/src/da65/scanner.c index 567b51348..a579939f9 100644 --- a/src/da65/scanner.c +++ b/src/da65/scanner.c @@ -76,8 +76,6 @@ static unsigned InputCol = 0; static FILE* InputFile = 0; static char* InputSrcName = 0; -/* Options */ -unsigned char InfoSyncLines = 0; /*****************************************************************************/ @@ -119,6 +117,7 @@ void InfoError (const char* Format, ...) + /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -164,7 +163,7 @@ static void SkipBlanks (int SingleLine) } } -static long GetDecimalToken () +static long GetDecimalToken (void) { long Value = 0; @@ -226,15 +225,15 @@ Store: static void LineMarkerOrComment () /* Handle a line beginning with '#'. Possible interpretations are: - * - #line <lineno> ["<filename>"] (C preprocessor input) - * - # <lineno> "<filename>" [<flag>]... (gcc preprocessor output) - * - #<comment> - */ +** - #line <lineno> ["<filename>"] (C preprocessor input) +** - # <lineno> "<filename>" [<flag>]... (gcc preprocessor output) +** - #<comment> +*/ { unsigned long LineNo = 0; int LineDirective = 0; StrBuf SrcNameBuf = AUTO_STRBUF_INITIALIZER; - + /* Skip the first "# " */ NextChar (); SkipBlanks (1); @@ -440,7 +439,7 @@ Again: case '#': /* # lineno "sourcefile" or # comment */ - if (InfoSyncLines && InputCol == 1) { + if (SyncLines && InputCol == 1) { LineMarkerOrComment (); } else { do { diff --git a/src/da65/scanner.h b/src/da65/scanner.h index b1dc75279..d4e38177b 100644 --- a/src/da65/scanner.h +++ b/src/da65/scanner.h @@ -138,8 +138,6 @@ extern long InfoIVal; extern unsigned InfoErrorLine; extern unsigned InfoErrorCol; -/* Options */ -extern unsigned char InfoSyncLines; /*****************************************************************************/ diff --git a/testcode/disasm/.gitignore b/testcode/disasm/.gitignore new file mode 100644 index 000000000..46c4eca80 --- /dev/null +++ b/testcode/disasm/.gitignore @@ -0,0 +1,2 @@ +*.s +image.bin diff --git a/testcode/disasm/bank0.da b/testcode/disasm/bank0.da new file mode 100644 index 000000000..4fb96ce93 --- /dev/null +++ b/testcode/disasm/bank0.da @@ -0,0 +1,16 @@ +// Da65 input file before preprocessed by cpp +// Bank0 ROM map + +#define TARGET_BANK 0 +global { + inputoffs $00010; + inputsize $4000; + startaddr $8000; + cpu "6502"; +}; + +#include "fixed.da" + +label { addr $8000; name "Bank0ProcA"; }; +label { addr $8123; name "Bank0ProcB"; }; +range { start $A000; end $BFFF; name "Bank0Data"; type ByteTable; }; diff --git a/testcode/disasm/bank0.dai b/testcode/disasm/bank0.dai new file mode 100644 index 000000000..2d865e77c --- /dev/null +++ b/testcode/disasm/bank0.dai @@ -0,0 +1,33 @@ +# 1 "bank0.da" +# 1 "<built-in>" +# 1 "<command-line>" +# 1 "bank0.da" + + + + +global { + inputoffs $00010; + inputsize $4000; + startaddr $8000; + cpu "6502"; +}; + +# 1 "fixed.da" 1 +# 18 "fixed.da" +label { addr $00; name "VariableA"; }; +label { addr $01; name "VariableB"; }; +label { addr $0100; name "Stack"; size $0100; }; + + + + + +label { addr $C000; name "CommonProcA"; }; +label { addr $C123; name "CommonProcB"; }; +range { start $E123; end $FFFF; name "CommonData"; type ByteTable; }; +# 13 "bank0.da" 2 + +label { addr $8000; name "Bank0ProcA"; }; +label { addr $8123; name "Bank0ProcB"; }; +range { start $A000; end $BFFF; name "Bank0Data"; type ByteTable; }; diff --git a/testcode/disasm/bank1.da b/testcode/disasm/bank1.da new file mode 100644 index 000000000..fd5e324a9 --- /dev/null +++ b/testcode/disasm/bank1.da @@ -0,0 +1,16 @@ +// Da65 input file before preprocessed by cpp +// Bank1 ROM map + +#define TARGET_BANK 1 +global { + inputoffs $04010; + inputsize $4000; + startaddr $8000; + cpu "6502"; +}; + +#include "fixed.da" + +range { start $8000; end $AFFF; name "Bank1Data"; type ByteTable; }; +label { addr $B000; name "Bank1ProcA"; }; +label { addr $B123; name "Bank1ProcB"; }; diff --git a/testcode/disasm/bank1.dai b/testcode/disasm/bank1.dai new file mode 100644 index 000000000..2b5b68532 --- /dev/null +++ b/testcode/disasm/bank1.dai @@ -0,0 +1,33 @@ +# 1 "bank1.da" +# 1 "<built-in>" +# 1 "<command-line>" +# 1 "bank1.da" + + + + +global { + inputoffs $04010; + inputsize $4000; + startaddr $8000; + cpu "6502"; +}; + +# 1 "fixed.da" 1 +# 18 "fixed.da" +label { addr $00; name "VariableA"; }; +label { addr $01; name "VariableB"; }; +label { addr $0100; name "Stack"; size $0100; }; + + + + + +label { addr $C000; name "CommonProcA"; }; +label { addr $C123; name "CommonProcB"; }; +range { start $E123; end $FFFF; name "CommonData"; type ByteTable; }; +# 13 "bank1.da" 2 + +range { start $8000; end $AFFF; name "Bank1Data"; type ByteTable; }; +label { addr $B000; name "Bank1ProcA"; }; +label { addr $B123; name "Bank1ProcB"; }; diff --git a/testcode/disasm/fixed.da b/testcode/disasm/fixed.da new file mode 100644 index 000000000..e8aa03427 --- /dev/null +++ b/testcode/disasm/fixed.da @@ -0,0 +1,30 @@ +// Da65 input file before preprocessed by cpp +// RAM and Fixed ROM map + +#ifndef FIXED_DA_INCLUDED +#define FIXED_DA_INCLUDED + +#ifndef TARGET_BANK +#define TARGET_BANK -1 +global { + inputoffs $1C010; + inputsize $4000; + startaddr $C000; + cpu "6502"; +}; +#endif /* !defined(TARGET_BANK) */ + +// ---- RAM map ---- +label { addr $00; name "VariableA"; }; +label { addr $01; name "VariableB"; }; +label { addr $0100; name "Stack"; size $0100; }; +#if defined(TEST_ERROR) && TARGET_BANK == 0 +erroneous_line; +#endif + +// ---- Fixed ROM map ---- +label { addr $C000; name "CommonProcA"; }; +label { addr $C123; name "CommonProcB"; }; +range { start $E123; end $FFFF; name "CommonData"; type ByteTable; }; + +#endif /* !defined(FIXED_DA_INCLUDED) */ diff --git a/testcode/disasm/fixed.dai b/testcode/disasm/fixed.dai new file mode 100644 index 000000000..d73155cf0 --- /dev/null +++ b/testcode/disasm/fixed.dai @@ -0,0 +1,25 @@ +# 1 "fixed.da" +# 1 "<built-in>" +# 1 "<command-line>" +# 1 "fixed.da" +# 9 "fixed.da" +global { + inputoffs $1C010; + inputsize $4000; + startaddr $C000; + cpu "6502"; +}; + + + +label { addr $00; name "VariableA"; }; +label { addr $01; name "VariableB"; }; +label { addr $0100; name "Stack"; size $0100; }; + + + + + +label { addr $C000; name "CommonProcA"; }; +label { addr $C123; name "CommonProcB"; }; +range { start $E123; end $FFFF; name "CommonData"; type ByteTable; }; diff --git a/testcode/disasm/sample-unix.mk b/testcode/disasm/sample-unix.mk new file mode 100644 index 000000000..0ef64a5e5 --- /dev/null +++ b/testcode/disasm/sample-unix.mk @@ -0,0 +1,28 @@ +# Sample makefile using a preprocessor against info files +# and the --sync-lines option + +CPP = env LANG=C cpp +CPPFLAGS = # -DTEST_ERROR + +ASMS = fixed.s bank0.s bank1.s +DAIS = fixed.dai bank0.dai bank1.dai + +.SUFFIXES: .da .dai .s +.PHONY: all clean maintainer-clean +.SECONDARY: $(DAIS) + +.da.dai: + $(CPP) -o $@ $(CPPFLAGS) $< + +.dai.s: + da65 --sync-lines -o $@ -i $< image.bin + +all: $(ASMS) + +clean: + rm -f $(ASMS) + +maintainer-clean: clean + rm -f $(DAIS) + +$(DAIS): fixed.da From 23534beaa6f719811c0bcb91d2d0f1396fb7f665 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Thu, 21 Jun 2018 00:25:33 +0000 Subject: [PATCH 0751/2161] Smaller driver code --- libsrc/c64/tgi/c64-hi.s | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libsrc/c64/tgi/c64-hi.s b/libsrc/c64/tgi/c64-hi.s index e2c3bca9f..1b3cedd08 100644 --- a/libsrc/c64/tgi/c64-hi.s +++ b/libsrc/c64/tgi/c64-hi.s @@ -570,10 +570,7 @@ YCONT2: lda (POINT),y ;Plot endpoint and CHUNK eor (POINT),y sta (POINT),y - lda #$36 - sta $01 - cli - rts + jmp EXIT YFIXX: ;x=x+1 adc DY From 4980fade7413f43f3822bf3e8955c5a876897b3c Mon Sep 17 00:00:00 2001 From: greg-king5 <gregdk@users.sf.net> Date: Thu, 21 Jun 2018 08:18:53 -0400 Subject: [PATCH 0752/2161] Made LINE plot single-point lines correctly. --- libsrc/c64/tgi/c64-hi.s | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libsrc/c64/tgi/c64-hi.s b/libsrc/c64/tgi/c64-hi.s index e2c3bca9f..8543345a5 100644 --- a/libsrc/c64/tgi/c64-hi.s +++ b/libsrc/c64/tgi/c64-hi.s @@ -541,8 +541,7 @@ STEPINY: eor CHUNK sta CHUNK txa - bne @CONT ;If dy=0 it's just a point - inx + beq YCONT2 ;If dy=0, it's just a point @CONT: lsr ;Init counter to dy/2 ; ; Main loop From a22e19a90232615bc72ea2be513563fd4e6afba6 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Thu, 21 Jun 2018 18:32:38 +0300 Subject: [PATCH 0753/2161] Added asminc/cbmkernal.inc --- asminc/cbmkernal.inc | 74 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 asminc/cbmkernal.inc diff --git a/asminc/cbmkernal.inc b/asminc/cbmkernal.inc new file mode 100644 index 000000000..eea49322e --- /dev/null +++ b/asminc/cbmkernal.inc @@ -0,0 +1,74 @@ +; +; Olli Savia <ops@iki.fi> +; +; Commodore kernal functions +; + +.if .def(__C64__) || .def(__C128__) || .def(__C16__) + CINT := $FF81 + IOINIT := $FF84 + RAMTAS := $FF87 +.elseif .def(__VIC20__) + CINT := $E518 ; No entries are in the kernal jump table of the Vic20 for these three (3) functions. + IOINIT := $FDF9 ; The entries for these functions have been set to point directly to the functions + RAMTAS := $FD8D ; in the kernal to maintain compatibility with the other Commodore platforms. +.elseif .def(__CBM510__) || .def(__CBM610__) + IOINIT := $FF7B + CINT := $FF7E + VECTOR := $FF84 + RESTOR := $FF87 +.endif + +.if .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) + RESTOR := $FF8A + VECTOR := $FF8D +.endif + +.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) + SETMSG := $FF90 + SECOND := $FF93 + TKSA := $FF96 + MEMTOP := $FF99 + MEMBOT := $FF9C + SCNKEY := $FF9F + SETTMO := $FFA2 + ACPTR := $FFA5 + CIOUT := $FFA8 + UNTLK := $FFAB + UNLSN := $FFAE + LISTEN := $FFB1 + TALK := $FFB4 + READST := $FFB7 + SETLFS := $FFBA + SETNAM := $FFBD + OPEN := $FFC0 + CLOSE := $FFC3 +.endif + +; Available on all platforms including PET +CHKIN := $FFC6 +CKOUT := $FFC9 +CLRCH := $FFCC +BASIN := $FFCF +CHRIN := $FFCF +BSOUT := $FFD2 +CHROUT := $FFD2 + +.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) + LOAD := $FFD5 + SAVE := $FFD8 + SETTIM := $FFDB + RDTIM := $FFDE +.endif + +; Available on all platforms including PET +STOP := $FFE1 +GETIN := $FFE4 +CLALL := $FFE7 +UDTIM := $FFEA + +.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) + SCREEN := $FFED + PLOT := $FFF0 + IOBASE := $FFF3 +.endif From 6a70d1dab10741dc1e30fd382369cc5decae58de Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Thu, 21 Jun 2018 20:30:14 +0000 Subject: [PATCH 0754/2161] Removed unused label --- libsrc/c64/tgi/c64-hi.s | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libsrc/c64/tgi/c64-hi.s b/libsrc/c64/tgi/c64-hi.s index 1b3cedd08..251efa1e1 100644 --- a/libsrc/c64/tgi/c64-hi.s +++ b/libsrc/c64/tgi/c64-hi.s @@ -570,7 +570,10 @@ YCONT2: lda (POINT),y ;Plot endpoint and CHUNK eor (POINT),y sta (POINT),y - jmp EXIT + lda #$36 + sta $01 + cli + rts YFIXX: ;x=x+1 adc DY @@ -624,7 +627,7 @@ XCONT2: dex lsr CHUNK ;Advance to last point jsr LINEPLOT ;Plot the last chunk -EXIT: lda #$36 + lda #$36 sta $01 cli rts From accfc14fb1a82f639d2489e7dbc4361614aa9157 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Fri, 22 Jun 2018 11:21:00 +0300 Subject: [PATCH 0755/2161] RESTOR and VECTOR moved under own ifdef/endif block --- asminc/cbmkernal.inc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/asminc/cbmkernal.inc b/asminc/cbmkernal.inc index eea49322e..d5e7216c2 100644 --- a/asminc/cbmkernal.inc +++ b/asminc/cbmkernal.inc @@ -15,13 +15,14 @@ .elseif .def(__CBM510__) || .def(__CBM610__) IOINIT := $FF7B CINT := $FF7E - VECTOR := $FF84 - RESTOR := $FF87 .endif .if .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) - RESTOR := $FF8A - VECTOR := $FF8D + RESTOR := $FF8A + VECTOR := $FF8D +.elseif .def(__CBM510__) || .def(__CBM610__) + VECTOR := $FF84 + RESTOR := $FF87 .endif .if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) From 8c4a0768cc4130971ed157c4538709e756bea6b9 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Fri, 22 Jun 2018 11:29:03 +0300 Subject: [PATCH 0756/2161] TAB to space conversion --- asminc/cbmkernal.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asminc/cbmkernal.inc b/asminc/cbmkernal.inc index d5e7216c2..44c721f6f 100644 --- a/asminc/cbmkernal.inc +++ b/asminc/cbmkernal.inc @@ -70,6 +70,6 @@ UDTIM := $FFEA .if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) SCREEN := $FFED - PLOT := $FFF0 + PLOT := $FFF0 IOBASE := $FFF3 .endif From 31fdec2e2eb4d89574b1142d68495259e1b72da4 Mon Sep 17 00:00:00 2001 From: AIDA Shinra <shinra@j10n.org> Date: Mon, 25 Jun 2018 23:50:46 +0900 Subject: [PATCH 0757/2161] Style fix --- src/da65/scanner.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/da65/scanner.c b/src/da65/scanner.c index a579939f9..143bb2636 100644 --- a/src/da65/scanner.c +++ b/src/da65/scanner.c @@ -163,6 +163,8 @@ static void SkipBlanks (int SingleLine) } } + + static long GetDecimalToken (void) { long Value = 0; @@ -174,7 +176,9 @@ static long GetDecimalToken (void) return Value; } -static int GetEncodedChar (char *Buf, unsigned *IPtr, unsigned Size) + + +static int GetEncodedChar (char* Buf, unsigned* IPtr, unsigned Size) { char Decoded = 0; int Count; @@ -207,11 +211,11 @@ static int GetEncodedChar (char *Buf, unsigned *IPtr, unsigned Size) } else { switch (C) { case '"': case '\'': case '\\': - Decoded = C; break; - case 't': Decoded = '\t'; break; - case 'r': Decoded = '\r'; break; - case 'n': Decoded = '\n'; break; - default: return -1; + Decoded = C; break; + case 't': Decoded = '\t'; break; + case 'r': Decoded = '\r'; break; + case 'n': Decoded = '\n'; break; + default: return -1; } NextChar (); } @@ -223,9 +227,11 @@ Store: return 0; } + + static void LineMarkerOrComment () /* Handle a line beginning with '#'. Possible interpretations are: -** - #line <lineno> ["<filename>"] (C preprocessor input) +** - #line <lineno> ["<filename>"] (C preprocessor input) ** - # <lineno> "<filename>" [<flag>]... (gcc preprocessor output) ** - #<comment> */ @@ -312,6 +318,8 @@ Last: SB_Done (&SrcNameBuf); } + + void InfoNextTok (void) /* Read the next token from the input stream */ { @@ -417,7 +425,7 @@ Again: if (C != '\"') { InfoError ("Unterminated string"); } - NextChar (); + NextChar (); InfoTok = INFOTOK_STRCON; break; @@ -660,16 +668,6 @@ void InfoSetName (const char* Name) -#ifdef unused -const char* InfoGetName (void) -/* Get the name of the config file */ -{ - return InfoFile? InfoFile : ""; -} -#endif /* unused */ - - - int InfoAvail () /* Return true if we have an info file given */ { From f7fbac4c6b409182a09b1c1ac493d04d8e1d6fe8 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Wed, 27 Jun 2018 21:39:24 +0300 Subject: [PATCH 0758/2161] Use common include file cbmkernal.inc --- libsrc/c128/kernal.s | 46 +++---------------------------------- libsrc/c16/kernal.s | 47 ++------------------------------------ libsrc/c64/kernal.s | 46 ++----------------------------------- libsrc/cbm510/kernal.s | 51 +++--------------------------------------- libsrc/cbm610/kernal.s | 51 +++--------------------------------------- libsrc/vic20/kernal.s | 46 ++----------------------------------- 6 files changed, 15 insertions(+), 272 deletions(-) diff --git a/libsrc/c128/kernal.s b/libsrc/c128/kernal.s index f3b78d00b..d4038e4cd 100644 --- a/libsrc/c128/kernal.s +++ b/libsrc/c128/kernal.s @@ -4,6 +4,8 @@ ; C128 kernal functions ; + .include "cbmkernal.inc" + .export C64MODE .export SWAPPER .export SETBNK @@ -51,50 +53,8 @@ ;----------------------------------------------------------------------------- ; All functions are available in the kernal jump table - + ; Extended jump table C64MODE = $FF4D SWAPPER = $FF5F SETBNK = $FF68 - -; -CINT = $FF81 -IOINIT = $FF84 -RAMTAS = $FF87 -RESTOR = $FF8A -VECTOR = $FF8D -SETMSG = $FF90 -SECOND = $FF93 -TKSA = $FF96 -MEMTOP = $FF99 -MEMBOT = $FF9C -SCNKEY = $FF9F -SETTMO = $FFA2 -ACPTR = $FFA5 -CIOUT = $FFA8 -UNTLK = $FFAB -UNLSN = $FFAE -LISTEN = $FFB1 -TALK = $FFB4 -READST = $FFB7 -SETLFS = $FFBA -SETNAM = $FFBD -OPEN = $FFC0 -CLOSE = $FFC3 -CHKIN = $FFC6 -CKOUT = $FFC9 -CLRCH = $FFCC -BASIN = $FFCF -BSOUT = $FFD2 -LOAD = $FFD5 -SAVE = $FFD8 -SETTIM = $FFDB -RDTIM = $FFDE -STOP = $FFE1 -GETIN = $FFE4 -CLALL = $FFE7 -UDTIM = $FFEA -SCREEN = $FFED -PLOT = $FFF0 -IOBASE = $FFF3 - diff --git a/libsrc/c16/kernal.s b/libsrc/c16/kernal.s index 7ba27b62c..5fe1cfce8 100644 --- a/libsrc/c16/kernal.s +++ b/libsrc/c16/kernal.s @@ -4,6 +4,8 @@ ; C16 kernal functions ; + .include "cbmkernal.inc" + .export CINT .export IOINIT .export RAMTAS @@ -42,48 +44,3 @@ .export SCREEN .export PLOT .export IOBASE - - -;----------------------------------------------------------------------------- -; All functions are available in the kernal jump table - -CINT = $FF81 -IOINIT = $FF84 -RAMTAS = $FF87 -RESTOR = $FF8A -VECTOR = $FF8D -SETMSG = $FF90 -SECOND = $FF93 -TKSA = $FF96 -MEMTOP = $FF99 -MEMBOT = $FF9C -SCNKEY = $FF9F -SETTMO = $FFA2 -ACPTR = $FFA5 -CIOUT = $FFA8 -UNTLK = $FFAB -UNLSN = $FFAE -LISTEN = $FFB1 -TALK = $FFB4 -READST = $FFB7 -SETLFS = $FFBA -SETNAM = $FFBD -OPEN = $FFC0 -;CLOSE = $FFC3 -CHKIN = $FFC6 -CKOUT = $FFC9 -CLRCH = $FFCC -BASIN = $FFCF -BSOUT = $FFD2 -LOAD = $FFD5 -SAVE = $FFD8 -SETTIM = $FFDB -RDTIM = $FFDE -STOP = $FFE1 -GETIN = $FFE4 -CLALL = $FFE7 -UDTIM = $FFEA -SCREEN = $FFED -PLOT = $FFF0 -IOBASE = $FFF3 - diff --git a/libsrc/c64/kernal.s b/libsrc/c64/kernal.s index a4eaad0d7..eb1e3c37f 100644 --- a/libsrc/c64/kernal.s +++ b/libsrc/c64/kernal.s @@ -4,6 +4,8 @@ ; C64 kernal functions ; + .include "cbmkernal.inc" + .export CINT .export IOINIT .export RAMTAS @@ -42,47 +44,3 @@ .export UDTIM .export SCREEN .export IOBASE - - -;----------------------------------------------------------------------------- -; All functions are available in the kernal jump table - -CINT = $FF81 -IOINIT = $FF84 -RAMTAS = $FF87 -RESTOR = $FF8A -VECTOR = $FF8D -SETMSG = $FF90 -SECOND = $FF93 -TKSA = $FF96 -MEMTOP = $FF99 -MEMBOT = $FF9C -SCNKEY = $FF9F -SETTMO = $FFA2 -ACPTR = $FFA5 -CIOUT = $FFA8 -UNTLK = $FFAB -UNLSN = $FFAE -LISTEN = $FFB1 -TALK = $FFB4 -READST = $FFB7 -SETLFS = $FFBA -SETNAM = $FFBD -OPEN = $FFC0 -CLOSE = $FFC3 -CHKIN = $FFC6 -CKOUT = $FFC9 -CLRCH = $FFCC -BASIN = $FFCF -BSOUT = $FFD2 -LOAD = $FFD5 -SAVE = $FFD8 -SETTIM = $FFDB -RDTIM = $FFDE -STOP = $FFE1 -GETIN = $FFE4 -CLALL = $FFE7 -UDTIM = $FFEA -SCREEN = $FFED -IOBASE = $FFF3 - diff --git a/libsrc/cbm510/kernal.s b/libsrc/cbm510/kernal.s index 9ea4f0e96..b4078b350 100644 --- a/libsrc/cbm510/kernal.s +++ b/libsrc/cbm510/kernal.s @@ -4,9 +4,11 @@ ; CBM610 kernal functions ; + .include "cbmkernal.inc" + .export CINT .export IOINIT - .export RAMTAS +; .export RAMTAS ; not available??? .export RESTOR .export VECTOR .export SETMSG @@ -34,50 +36,3 @@ .export GETIN .export CLALL .export PLOT - - -;----------------------------------------------------------------------------- -; All functions are available in the kernal jump table. Functions having -; replacements (usually short ones where the overhead of the cross bank call -; is not worth the trouble) are commented out. - -CINT = $FF81 -IOINIT = $FF84 -RAMTAS = $FF87 -RESTOR = $FF8A -VECTOR = $FF8D -SETMSG = $FF90 -SECOND = $FF93 -TKSA = $FF96 -MEMTOP = $FF99 -MEMBOT = $FF9C -SCNKEY = $FF9F -SETTMO = $FFA2 -ACPTR = $FFA5 -CIOUT = $FFA8 -UNTLK = $FFAB -UNLSN = $FFAE -LISTEN = $FFB1 -TALK = $FFB4 -;READST = $FFB7 -SETLFS = $FFBA -;SETNAM = $FFBD -;OPEN = $FFC0 -;CLOSE = $FFC3 -CHKIN = $FFC6 -CKOUT = $FFC9 -CLRCH = $FFCC -BASIN = $FFCF -BSOUT = $FFD2 -LOAD = $FFD5 -SAVE = $FFD8 -;SETTIM = $FFDB -;RDTIM = $FFDE -STOP = $FFE1 -GETIN = $FFE4 -CLALL = $FFE7 -;UDTIM = $FFEA -;SCREEN = $FFED -PLOT = $FFF0 -;IOBASE = $FFF3 - diff --git a/libsrc/cbm610/kernal.s b/libsrc/cbm610/kernal.s index 9ea4f0e96..b4078b350 100644 --- a/libsrc/cbm610/kernal.s +++ b/libsrc/cbm610/kernal.s @@ -4,9 +4,11 @@ ; CBM610 kernal functions ; + .include "cbmkernal.inc" + .export CINT .export IOINIT - .export RAMTAS +; .export RAMTAS ; not available??? .export RESTOR .export VECTOR .export SETMSG @@ -34,50 +36,3 @@ .export GETIN .export CLALL .export PLOT - - -;----------------------------------------------------------------------------- -; All functions are available in the kernal jump table. Functions having -; replacements (usually short ones where the overhead of the cross bank call -; is not worth the trouble) are commented out. - -CINT = $FF81 -IOINIT = $FF84 -RAMTAS = $FF87 -RESTOR = $FF8A -VECTOR = $FF8D -SETMSG = $FF90 -SECOND = $FF93 -TKSA = $FF96 -MEMTOP = $FF99 -MEMBOT = $FF9C -SCNKEY = $FF9F -SETTMO = $FFA2 -ACPTR = $FFA5 -CIOUT = $FFA8 -UNTLK = $FFAB -UNLSN = $FFAE -LISTEN = $FFB1 -TALK = $FFB4 -;READST = $FFB7 -SETLFS = $FFBA -;SETNAM = $FFBD -;OPEN = $FFC0 -;CLOSE = $FFC3 -CHKIN = $FFC6 -CKOUT = $FFC9 -CLRCH = $FFCC -BASIN = $FFCF -BSOUT = $FFD2 -LOAD = $FFD5 -SAVE = $FFD8 -;SETTIM = $FFDB -;RDTIM = $FFDE -STOP = $FFE1 -GETIN = $FFE4 -CLALL = $FFE7 -;UDTIM = $FFEA -;SCREEN = $FFED -PLOT = $FFF0 -;IOBASE = $FFF3 - diff --git a/libsrc/vic20/kernal.s b/libsrc/vic20/kernal.s index 040dbf5e5..a3134367a 100644 --- a/libsrc/vic20/kernal.s +++ b/libsrc/vic20/kernal.s @@ -4,6 +4,8 @@ ; VIC20 kernal functions ; + .include "cbmkernal.inc" + .export CINT .export IOINIT .export RAMTAS @@ -42,47 +44,3 @@ .export UDTIM .export SCREEN .export IOBASE - - -;----------------------------------------------------------------------------- -; All functions are available in the kernal jump table - -CINT = $E518 ; No entries are in the kernal jump table of the Vic20 for these three (3) functions. -IOINIT = $FDF9 ; The entries for these functions have been set to point directly to the functions -RAMTAS = $FD8D ; in the kernal to maintain compatibility with the other Commodore platforms. -RESTOR = $FF8A -VECTOR = $FF8D -SETMSG = $FF90 -SECOND = $FF93 -TKSA = $FF96 -MEMTOP = $FF99 -MEMBOT = $FF9C -SCNKEY = $FF9F -SETTMO = $FFA2 -ACPTR = $FFA5 -CIOUT = $FFA8 -UNTLK = $FFAB -UNLSN = $FFAE -LISTEN = $FFB1 -TALK = $FFB4 -READST = $FFB7 -SETLFS = $FFBA -SETNAM = $FFBD -OPEN = $FFC0 -CLOSE = $FFC3 -CHKIN = $FFC6 -CKOUT = $FFC9 -CLRCH = $FFCC -BASIN = $FFCF -BSOUT = $FFD2 -LOAD = $FFD5 -SAVE = $FFD8 -SETTIM = $FFDB -RDTIM = $FFDE -STOP = $FFE1 -GETIN = $FFE4 -CLALL = $FFE7 -UDTIM = $FFEA -SCREEN = $FFED -IOBASE = $FFF3 - From f185e28892e3589620f5540b51b1e999e58b5e10 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Fri, 29 Jun 2018 16:14:00 +0300 Subject: [PATCH 0759/2161] cbmkernal.inc -> cbm_kernal.inc --- asminc/{cbmkernal.inc => cbm_kernal.inc} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename asminc/{cbmkernal.inc => cbm_kernal.inc} (100%) diff --git a/asminc/cbmkernal.inc b/asminc/cbm_kernal.inc similarity index 100% rename from asminc/cbmkernal.inc rename to asminc/cbm_kernal.inc From 96e6a0a114b7ba07809ec23f736d754bf1206425 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Fri, 29 Jun 2018 22:58:16 +0300 Subject: [PATCH 0760/2161] Common include file is now cbm_kernal.inc --- libsrc/c128/kernal.s | 2 +- libsrc/c16/kernal.s | 2 +- libsrc/c64/kernal.s | 2 +- libsrc/cbm510/kernal.s | 2 +- libsrc/cbm610/kernal.s | 2 +- libsrc/vic20/kernal.s | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libsrc/c128/kernal.s b/libsrc/c128/kernal.s index d4038e4cd..98a802b9e 100644 --- a/libsrc/c128/kernal.s +++ b/libsrc/c128/kernal.s @@ -4,7 +4,7 @@ ; C128 kernal functions ; - .include "cbmkernal.inc" + .include "cbm_kernal.inc" .export C64MODE .export SWAPPER diff --git a/libsrc/c16/kernal.s b/libsrc/c16/kernal.s index 5fe1cfce8..f6bd531b4 100644 --- a/libsrc/c16/kernal.s +++ b/libsrc/c16/kernal.s @@ -4,7 +4,7 @@ ; C16 kernal functions ; - .include "cbmkernal.inc" + .include "cbm_kernal.inc" .export CINT .export IOINIT diff --git a/libsrc/c64/kernal.s b/libsrc/c64/kernal.s index eb1e3c37f..076480357 100644 --- a/libsrc/c64/kernal.s +++ b/libsrc/c64/kernal.s @@ -4,7 +4,7 @@ ; C64 kernal functions ; - .include "cbmkernal.inc" + .include "cbm_kernal.inc" .export CINT .export IOINIT diff --git a/libsrc/cbm510/kernal.s b/libsrc/cbm510/kernal.s index b4078b350..8d873aa6a 100644 --- a/libsrc/cbm510/kernal.s +++ b/libsrc/cbm510/kernal.s @@ -4,7 +4,7 @@ ; CBM610 kernal functions ; - .include "cbmkernal.inc" + .include "cbm_kernal.inc" .export CINT .export IOINIT diff --git a/libsrc/cbm610/kernal.s b/libsrc/cbm610/kernal.s index b4078b350..8d873aa6a 100644 --- a/libsrc/cbm610/kernal.s +++ b/libsrc/cbm610/kernal.s @@ -4,7 +4,7 @@ ; CBM610 kernal functions ; - .include "cbmkernal.inc" + .include "cbm_kernal.inc" .export CINT .export IOINIT diff --git a/libsrc/vic20/kernal.s b/libsrc/vic20/kernal.s index a3134367a..9f02102a9 100644 --- a/libsrc/vic20/kernal.s +++ b/libsrc/vic20/kernal.s @@ -4,7 +4,7 @@ ; VIC20 kernal functions ; - .include "cbmkernal.inc" + .include "cbm_kernal.inc" .export CINT .export IOINIT From d5bc751f54fcd537f2a31b2bcfd72421da1c2380 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Fri, 29 Jun 2018 22:59:53 +0300 Subject: [PATCH 0761/2161] Removed RAMTAS --- libsrc/cbm510/kernal.s | 1 - libsrc/cbm610/kernal.s | 1 - 2 files changed, 2 deletions(-) diff --git a/libsrc/cbm510/kernal.s b/libsrc/cbm510/kernal.s index 8d873aa6a..46ba8df20 100644 --- a/libsrc/cbm510/kernal.s +++ b/libsrc/cbm510/kernal.s @@ -8,7 +8,6 @@ .export CINT .export IOINIT -; .export RAMTAS ; not available??? .export RESTOR .export VECTOR .export SETMSG diff --git a/libsrc/cbm610/kernal.s b/libsrc/cbm610/kernal.s index 8d873aa6a..46ba8df20 100644 --- a/libsrc/cbm610/kernal.s +++ b/libsrc/cbm610/kernal.s @@ -8,7 +8,6 @@ .export CINT .export IOINIT -; .export RAMTAS ; not available??? .export RESTOR .export VECTOR .export SETMSG From 635a99c0836d7e60966cfac1ab9fe60a3bc2c53d Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Sat, 30 Jun 2018 16:25:43 +0300 Subject: [PATCH 0762/2161] TAB to space conversion --- libsrc/c128/kernal.s | 2 +- libsrc/c16/kernal.s | 2 +- libsrc/c64/kernal.s | 2 +- libsrc/cbm510/kernal.s | 2 +- libsrc/cbm610/kernal.s | 2 +- libsrc/vic20/kernal.s | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libsrc/c128/kernal.s b/libsrc/c128/kernal.s index 98a802b9e..266f86911 100644 --- a/libsrc/c128/kernal.s +++ b/libsrc/c128/kernal.s @@ -4,7 +4,7 @@ ; C128 kernal functions ; - .include "cbm_kernal.inc" + .include "cbm_kernal.inc" .export C64MODE .export SWAPPER diff --git a/libsrc/c16/kernal.s b/libsrc/c16/kernal.s index f6bd531b4..f814b2c1f 100644 --- a/libsrc/c16/kernal.s +++ b/libsrc/c16/kernal.s @@ -4,7 +4,7 @@ ; C16 kernal functions ; - .include "cbm_kernal.inc" + .include "cbm_kernal.inc" .export CINT .export IOINIT diff --git a/libsrc/c64/kernal.s b/libsrc/c64/kernal.s index 076480357..acbf22370 100644 --- a/libsrc/c64/kernal.s +++ b/libsrc/c64/kernal.s @@ -4,7 +4,7 @@ ; C64 kernal functions ; - .include "cbm_kernal.inc" + .include "cbm_kernal.inc" .export CINT .export IOINIT diff --git a/libsrc/cbm510/kernal.s b/libsrc/cbm510/kernal.s index 46ba8df20..921bf524e 100644 --- a/libsrc/cbm510/kernal.s +++ b/libsrc/cbm510/kernal.s @@ -4,7 +4,7 @@ ; CBM610 kernal functions ; - .include "cbm_kernal.inc" + .include "cbm_kernal.inc" .export CINT .export IOINIT diff --git a/libsrc/cbm610/kernal.s b/libsrc/cbm610/kernal.s index 46ba8df20..921bf524e 100644 --- a/libsrc/cbm610/kernal.s +++ b/libsrc/cbm610/kernal.s @@ -4,7 +4,7 @@ ; CBM610 kernal functions ; - .include "cbm_kernal.inc" + .include "cbm_kernal.inc" .export CINT .export IOINIT diff --git a/libsrc/vic20/kernal.s b/libsrc/vic20/kernal.s index 9f02102a9..ff16a019c 100644 --- a/libsrc/vic20/kernal.s +++ b/libsrc/vic20/kernal.s @@ -4,7 +4,7 @@ ; VIC20 kernal functions ; - .include "cbm_kernal.inc" + .include "cbm_kernal.inc" .export CINT .export IOINIT From 4c45de2c45f0cb63f17c7c562bb694ceee4262b9 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Sun, 1 Jul 2018 09:54:39 +0300 Subject: [PATCH 0763/2161] Updated comment --- libsrc/cbm510/kernal.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/cbm510/kernal.s b/libsrc/cbm510/kernal.s index 921bf524e..7908c40ec 100644 --- a/libsrc/cbm510/kernal.s +++ b/libsrc/cbm510/kernal.s @@ -1,7 +1,7 @@ ; ; Ullrich von Bassewitz, 2003-12-20 ; -; CBM610 kernal functions +; CBM510 kernal functions ; .include "cbm_kernal.inc" From 820c0efcb39b70946b3fca995f81e7b87dbd953d Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Sun, 1 Jul 2018 09:56:37 +0300 Subject: [PATCH 0764/2161] Use common include file cbm_kernal.inc --- libsrc/pet/kernal.s | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/libsrc/pet/kernal.s b/libsrc/pet/kernal.s index 1a9dd6f67..ba66c4653 100644 --- a/libsrc/pet/kernal.s +++ b/libsrc/pet/kernal.s @@ -4,25 +4,11 @@ ; PET kernal functions ; + .include "cbm_kernal.inc" + .export CLRCH .export BASIN .export STOP .export GETIN .export CLALL .export UDTIM - - - - - - -;----------------------------------------------------------------------------- -; Functions that are available in the kernal jump table - -CLRCH = $FFCC -BASIN = $FFCF -STOP = $FFE1 -GETIN = $FFE4 -CLALL = $FFE7 -UDTIM = $FFEA - From 3e94f7f55cad78700f58250cd3c98983c1a78c11 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Sun, 1 Jul 2018 09:58:39 +0300 Subject: [PATCH 0765/2161] Moved C128 specific definitions to cbm_kernal.inc --- asminc/cbm_kernal.inc | 7 +++++++ libsrc/c128/kernal.s | 9 --------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/asminc/cbm_kernal.inc b/asminc/cbm_kernal.inc index 44c721f6f..52c1c16ad 100644 --- a/asminc/cbm_kernal.inc +++ b/asminc/cbm_kernal.inc @@ -4,6 +4,13 @@ ; Commodore kernal functions ; +.if .def(__C128__) + ; C128 Extended jump table + C64MODE := $FF4D + SWAPPER := $FF5F + SETBNK := $FF68 +.endif + .if .def(__C64__) || .def(__C128__) || .def(__C16__) CINT := $FF81 IOINIT := $FF84 diff --git a/libsrc/c128/kernal.s b/libsrc/c128/kernal.s index 266f86911..f74ab3b1a 100644 --- a/libsrc/c128/kernal.s +++ b/libsrc/c128/kernal.s @@ -49,12 +49,3 @@ .export SCREEN .export PLOT .export IOBASE - - -;----------------------------------------------------------------------------- -; All functions are available in the kernal jump table - -; Extended jump table -C64MODE = $FF4D -SWAPPER = $FF5F -SETBNK = $FF68 From 032a3877e0de2c43b43434254fb76524596df9ea Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Tue, 3 Jul 2018 22:44:59 +0300 Subject: [PATCH 0766/2161] Added .import for std kernal entries --- libsrc/cbm/cbm.inc | 85 ++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 41 deletions(-) diff --git a/libsrc/cbm/cbm.inc b/libsrc/cbm/cbm.inc index 0e513ffe8..4fdcb67a7 100644 --- a/libsrc/cbm/cbm.inc +++ b/libsrc/cbm/cbm.inc @@ -7,46 +7,51 @@ ; Subroutines available in the CBM jump table ; -;CINT = $FF81 -;IOINIT = $FF84 -;RAMTAS = $FF87 -;RESTOR = $FF8A -;VECTOR = $FF8D -;SETMSG = $FF90 -;SECOND = $FF93 -;TKSA = $FF96 -;MEMTOP = $FF99 -;MEMBOT = $FF9C -;SCNKEY = $FF9F -;SETTMO = $FFA2 -;ACPTR = $FFA5 -;CIOUT = $FFA8 -;UNTLK = $FFAB -;UNLSN = $FFAE -;LISTEN = $FFB1 -;TALK = $FFB4 -;READST = $FFB7 -;SETLFS = $FFBA -;SETNAM = $FFBD -;OPEN = $FFC0 -;CLOSE = $FFC3 -;CHKIN = $FFC6 -;CKOUT = $FFC9 -;CLRCH = $FFCC -;BASIN = $FFCF -;BSOUT = $FFD2 -;LOAD = $FFD5 -;SAVE = $FFD8 -;SETTIM = $FFDB -;RDTIM = $FFDE -;STOP = $FFE1 -;GETIN = $FFE4 -;CLALL = $FFE7 -;UDTIM = $FFEA -;SCREEN = $FFED -;PLOT = $FFF0 -;IOBASE = $FFF3 +.import C64MODE +.import SWAPPER +.import SETBNK +.import CINT +.import IOINIT +.import RAMTAS +.import VECTOR +.import RESTOR +.import SETMSG +.import SECOND +.import TKSA +.import MEMTOP +.import MEMBOT +.import SCNKEY +.import SETTMO +.import ACPTR +.import CIOUT +.import UNTLK +.import UNLSN +.import LISTEN +.import TALK +.import READST +.import SETLFS +.import SETNAM +.import OPEN +.import CLOSE +.import LOAD +.import SAVE +.import SETTIM +.import RDTIM +.import SCREEN +.import PLOT +.import IOBASE +.import CHKIN +.import CKOUT +.import CLRCH +.import BASIN +.import CHRIN +.import BSOUT +.import CHROUT +.import STOP +.import GETIN +.import CLALL +.import UDTIM ;----------------------------------------------------------------------------- ; Device numbers @@ -63,5 +68,3 @@ CBMDEV_SCREEN = 3 MAX_DRIVES = 23 FIRST_DRIVE = 8 - - From f7636fe8f2de6e457fe1c3b0a55856513dca3ef1 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Tue, 3 Jul 2018 22:47:42 +0300 Subject: [PATCH 0767/2161] Removed .import for std kernal entries. Added .include "cbm.inc" --- libsrc/cbm/c_acptr.s | 2 +- libsrc/cbm/c_basin.s | 2 +- libsrc/cbm/c_bsout.s | 2 +- libsrc/cbm/c_chkin.s | 3 ++- libsrc/cbm/c_ciout.s | 5 ++--- libsrc/cbm/c_ckout.s | 2 +- libsrc/cbm/c_clall.s | 2 +- libsrc/cbm/c_close.s | 6 ++---- libsrc/cbm/c_clrch.s | 2 +- libsrc/cbm/c_getin.s | 2 +- libsrc/cbm/c_iobase.s | 4 ++-- libsrc/cbm/c_listen.s | 7 +------ libsrc/cbm/c_load.s | 3 +-- libsrc/cbm/c_open.s | 2 +- libsrc/cbm/c_readst.s | 2 +- libsrc/cbm/c_save.s | 2 +- libsrc/cbm/c_scnkey.s | 2 +- libsrc/cbm/c_second.s | 6 ++---- libsrc/cbm/c_setlfs.s | 6 ++---- libsrc/cbm/c_setnam.s | 5 ++--- libsrc/cbm/c_talk.s | 9 +-------- libsrc/cbm/c_tksa.s | 6 ++---- libsrc/cbm/c_udtim.s | 2 +- libsrc/cbm/c_unlsn.s | 2 +- libsrc/cbm/c_untlk.s | 3 +-- libsrc/cbm/cbm_read.s | 1 - libsrc/cbm/cbm_write.s | 3 +-- libsrc/cbm/clock.s | 4 +--- libsrc/cbm/close.s | 7 +------ libsrc/cbm/diskcmd.s | 2 -- libsrc/cbm/filename.s | 2 +- libsrc/cbm/open.s | 2 +- libsrc/cbm/read.s | 1 - libsrc/cbm/write.s | 1 - 34 files changed, 38 insertions(+), 74 deletions(-) diff --git a/libsrc/cbm/c_acptr.s b/libsrc/cbm/c_acptr.s index 87f063a07..0c1363c8c 100644 --- a/libsrc/cbm/c_acptr.s +++ b/libsrc/cbm/c_acptr.s @@ -4,8 +4,8 @@ ; unsigned char cbm_k_acptr (void); ; + .include "cbm.inc" .export _cbm_k_acptr - .import ACPTR _cbm_k_acptr: diff --git a/libsrc/cbm/c_basin.s b/libsrc/cbm/c_basin.s index 15d7e7f5c..9e3befee0 100644 --- a/libsrc/cbm/c_basin.s +++ b/libsrc/cbm/c_basin.s @@ -4,8 +4,8 @@ ; unsigned char cbm_k_basin (void); ; + .include "cbm.inc" .export _cbm_k_basin - .import BASIN _cbm_k_basin: diff --git a/libsrc/cbm/c_bsout.s b/libsrc/cbm/c_bsout.s index 8b9f44037..043efd7d3 100644 --- a/libsrc/cbm/c_bsout.s +++ b/libsrc/cbm/c_bsout.s @@ -4,7 +4,7 @@ ; void __fastcall__ cbm_k_bsout (unsigned char C); ; + .include "cbm.inc" .export _cbm_k_bsout - .import BSOUT _cbm_k_bsout = BSOUT diff --git a/libsrc/cbm/c_chkin.s b/libsrc/cbm/c_chkin.s index 4ed8c1bff..39bc2222e 100644 --- a/libsrc/cbm/c_chkin.s +++ b/libsrc/cbm/c_chkin.s @@ -4,8 +4,9 @@ ; unsigned char __fastcall__ cbm_k_chkin (unsigned char FN); ; + .include "cbm.inc" .export _cbm_k_chkin - .import CHKIN + _cbm_k_chkin: tax diff --git a/libsrc/cbm/c_ciout.s b/libsrc/cbm/c_ciout.s index 9906e0658..5ef59c5b7 100644 --- a/libsrc/cbm/c_ciout.s +++ b/libsrc/cbm/c_ciout.s @@ -4,7 +4,6 @@ ; void __fastcall__ cbm_k_ciout (unsigned char C); ; - .import CIOUT + + .include "cbm.inc" .export _cbm_k_ciout := CIOUT - - diff --git a/libsrc/cbm/c_ckout.s b/libsrc/cbm/c_ckout.s index 380d7170a..9efbb7343 100644 --- a/libsrc/cbm/c_ckout.s +++ b/libsrc/cbm/c_ckout.s @@ -4,8 +4,8 @@ ; unsigned char __fastcall__ cbm_k_ckout (unsigned char FN); ; + .include "cbm.inc" .export _cbm_k_ckout - .import CKOUT _cbm_k_ckout: diff --git a/libsrc/cbm/c_clall.s b/libsrc/cbm/c_clall.s index cdd7d4ddc..1bc7bf747 100644 --- a/libsrc/cbm/c_clall.s +++ b/libsrc/cbm/c_clall.s @@ -4,5 +4,5 @@ ; void cbm_k_clall (void); ; - .import CLALL + .include "cbm.inc" .export _cbm_k_clall := CLALL diff --git a/libsrc/cbm/c_close.s b/libsrc/cbm/c_close.s index 9582baca2..db19f34c6 100644 --- a/libsrc/cbm/c_close.s +++ b/libsrc/cbm/c_close.s @@ -4,11 +4,9 @@ ; void __fastcall__ cbm_k_close (unsigned char FN); ; + .include "cbm.inc" .export _cbm_k_close - .import CLOSE _cbm_k_close: - clc + clc jmp CLOSE - - diff --git a/libsrc/cbm/c_clrch.s b/libsrc/cbm/c_clrch.s index 7c0506a1c..b0db2be4e 100644 --- a/libsrc/cbm/c_clrch.s +++ b/libsrc/cbm/c_clrch.s @@ -4,7 +4,7 @@ ; void cbm_k_clrch (void); ; + .include "cbm.inc" .export _cbm_k_clrch - .import CLRCH _cbm_k_clrch = CLRCH diff --git a/libsrc/cbm/c_getin.s b/libsrc/cbm/c_getin.s index b4cb34f76..23c1edc74 100644 --- a/libsrc/cbm/c_getin.s +++ b/libsrc/cbm/c_getin.s @@ -4,8 +4,8 @@ ; unsigned char cbm_k_getin (void); ; + .include "cbm.inc" .export _cbm_k_getin - .import GETIN _cbm_k_getin: diff --git a/libsrc/cbm/c_iobase.s b/libsrc/cbm/c_iobase.s index 254879017..58b66fd0b 100644 --- a/libsrc/cbm/c_iobase.s +++ b/libsrc/cbm/c_iobase.s @@ -4,10 +4,10 @@ ; unsigned cbm_k_iobase (void); ; + .include "cbm.inc" .export _cbm_k_iobase - .import IOBASE -_cbm_k_iobase: +_cbm_k_iobase: jsr IOBASE txa pha diff --git a/libsrc/cbm/c_listen.s b/libsrc/cbm/c_listen.s index 85ef8b7fa..38908a60b 100644 --- a/libsrc/cbm/c_listen.s +++ b/libsrc/cbm/c_listen.s @@ -4,10 +4,5 @@ ; void __fastcall__ cbm_k_listen (unsigned char dev); ; - .import LISTEN + .include "cbm.inc" .export _cbm_k_listen := LISTEN - - - - - diff --git a/libsrc/cbm/c_load.s b/libsrc/cbm/c_load.s index f2b5b0c89..c9bd55ca0 100644 --- a/libsrc/cbm/c_load.s +++ b/libsrc/cbm/c_load.s @@ -4,8 +4,8 @@ ; unsigned int __fastcall__ cbm_k_load (unsigned char flag, unsigned addr); ; + .include "cbm.inc" .export _cbm_k_load - .import LOAD .import __oserror .import popa .importzp ptr1 @@ -27,4 +27,3 @@ _cbm_k_load: tax pla rts - diff --git a/libsrc/cbm/c_open.s b/libsrc/cbm/c_open.s index 6461ffedf..63249a57f 100644 --- a/libsrc/cbm/c_open.s +++ b/libsrc/cbm/c_open.s @@ -4,8 +4,8 @@ ; unsigned char cbm_k_open (void); ; + .include "cbm.inc" .export _cbm_k_open - .import OPEN _cbm_k_open: diff --git a/libsrc/cbm/c_readst.s b/libsrc/cbm/c_readst.s index 301cd9b42..e6243cef0 100644 --- a/libsrc/cbm/c_readst.s +++ b/libsrc/cbm/c_readst.s @@ -4,8 +4,8 @@ ; unsigned char cbm_k_readst (void); ; + .include "cbm.inc" .export _cbm_k_readst - .import READST _cbm_k_readst: diff --git a/libsrc/cbm/c_save.s b/libsrc/cbm/c_save.s index 0597e9401..6d05e6344 100644 --- a/libsrc/cbm/c_save.s +++ b/libsrc/cbm/c_save.s @@ -4,8 +4,8 @@ ; unsigned char __fastcall__ cbm_k_save(unsigned int start, unsigned int end); ; + .include "cbm.inc" .export _cbm_k_save - .import SAVE .import popptr1 .importzp ptr1, tmp1 diff --git a/libsrc/cbm/c_scnkey.s b/libsrc/cbm/c_scnkey.s index cdae50e7b..38e3f4cec 100644 --- a/libsrc/cbm/c_scnkey.s +++ b/libsrc/cbm/c_scnkey.s @@ -4,5 +4,5 @@ ; void cbm_k_scnkey (void); ; - .import SCNKEY + .include "cbm.inc" .export _cbm_k_scnkey := SCNKEY diff --git a/libsrc/cbm/c_second.s b/libsrc/cbm/c_second.s index b5cc98c80..2670e1cd4 100644 --- a/libsrc/cbm/c_second.s +++ b/libsrc/cbm/c_second.s @@ -4,9 +4,7 @@ ; void __fastcall__ cbm_k_second (unsigned char addr) ; - - .import SECOND - .export _cbm_k_second + .include "cbm.inc" + .export _cbm_k_second _cbm_k_second = SECOND - diff --git a/libsrc/cbm/c_setlfs.s b/libsrc/cbm/c_setlfs.s index 00ebfae7a..b93d80c09 100644 --- a/libsrc/cbm/c_setlfs.s +++ b/libsrc/cbm/c_setlfs.s @@ -6,11 +6,11 @@ ; unsigned char SA); ; + .include "cbm.inc" .export _cbm_k_setlfs - .import SETLFS .import popa .importzp tmp1 - + _cbm_k_setlfs: sta tmp1 ; Save SA @@ -19,5 +19,3 @@ _cbm_k_setlfs: jsr popa ; Get LFN ldy tmp1 ; Get SA jmp SETLFS - - diff --git a/libsrc/cbm/c_setnam.s b/libsrc/cbm/c_setnam.s index 3249d8539..5b6b90c64 100644 --- a/libsrc/cbm/c_setnam.s +++ b/libsrc/cbm/c_setnam.s @@ -4,10 +4,10 @@ ; void __fastcall__ cbm_k_setnam (const char* Name); ; + .include "cbm.inc" .export _cbm_k_setnam - .import SETNAM .importzp ptr1 - + _cbm_k_setnam: sta ptr1 ; Store pointer to file name @@ -21,4 +21,3 @@ _cbm_k_setnam: ldx ptr1 ldy ptr1+1 jmp SETNAM - diff --git a/libsrc/cbm/c_talk.s b/libsrc/cbm/c_talk.s index ff80b3499..01ab376d1 100644 --- a/libsrc/cbm/c_talk.s +++ b/libsrc/cbm/c_talk.s @@ -4,12 +4,5 @@ ; void __fastcall__ cbm_k_talk (unsigned char dev); ; - .import TALK + .include "cbm.inc" .export _cbm_k_talk := TALK - - - - - - - diff --git a/libsrc/cbm/c_tksa.s b/libsrc/cbm/c_tksa.s index b818d7205..c59c7f5a0 100644 --- a/libsrc/cbm/c_tksa.s +++ b/libsrc/cbm/c_tksa.s @@ -4,9 +4,7 @@ ; void __fastcall__ cbm_k_tksa (unsigned char addr) ; - - .import TKSA - .export _cbm_k_tksa + .include "cbm.inc" + .export _cbm_k_tksa _cbm_k_tksa = TKSA - diff --git a/libsrc/cbm/c_udtim.s b/libsrc/cbm/c_udtim.s index b867efaba..ba12d1e35 100644 --- a/libsrc/cbm/c_udtim.s +++ b/libsrc/cbm/c_udtim.s @@ -4,5 +4,5 @@ ; void cbm_k_udtim (void); ; - .import UDTIM + .include "cbm.inc" .export _cbm_k_udtim := UDTIM diff --git a/libsrc/cbm/c_unlsn.s b/libsrc/cbm/c_unlsn.s index fd6b1b074..5a525374b 100644 --- a/libsrc/cbm/c_unlsn.s +++ b/libsrc/cbm/c_unlsn.s @@ -4,5 +4,5 @@ ; void cbm_k_unlsn (void); ; - .import UNLSN + .include "cbm.inc" .export _cbm_k_unlsn := UNLSN diff --git a/libsrc/cbm/c_untlk.s b/libsrc/cbm/c_untlk.s index 3865564cd..dfde77e3f 100644 --- a/libsrc/cbm/c_untlk.s +++ b/libsrc/cbm/c_untlk.s @@ -4,8 +4,7 @@ ; void cbm_k_untlk (void); ; + .include "cbm.inc" .export _cbm_k_untlk - .import UNTLK - _cbm_k_untlk = UNTLK diff --git a/libsrc/cbm/cbm_read.s b/libsrc/cbm/cbm_read.s index c84ff65aa..b010966a3 100644 --- a/libsrc/cbm/cbm_read.s +++ b/libsrc/cbm/cbm_read.s @@ -39,7 +39,6 @@ .include "cbm.inc" .export _cbm_read - .import CHKIN, READST, BASIN, CLRCH .importzp ptr1, ptr2, ptr3, tmp1 .import popax, popa .import __oserror diff --git a/libsrc/cbm/cbm_write.s b/libsrc/cbm/cbm_write.s index 0b709dff8..2d932d04a 100644 --- a/libsrc/cbm/cbm_write.s +++ b/libsrc/cbm/cbm_write.s @@ -31,11 +31,10 @@ .include "cbm.inc" .export _cbm_write - .import CKOUT, READST, BSOUT, CLRCH .importzp ptr1, ptr2, ptr3 .import popax, popa .import __oserror - + _cbm_write: sta ptr3 diff --git a/libsrc/cbm/clock.s b/libsrc/cbm/clock.s index ce36e3af5..0c8ba9c45 100644 --- a/libsrc/cbm/clock.s +++ b/libsrc/cbm/clock.s @@ -4,12 +4,11 @@ ; clock_t clock (void); ; + .include "cbm.inc" .export _clock - .import RDTIM .importzp sreg - .proc _clock lda #0 ; Byte 3 is always zero @@ -19,4 +18,3 @@ rts .endproc - diff --git a/libsrc/cbm/close.s b/libsrc/cbm/close.s index b43c07b57..7fc600e87 100644 --- a/libsrc/cbm/close.s +++ b/libsrc/cbm/close.s @@ -6,7 +6,6 @@ .export _close - .import CLOSE .import readdiskerror, closecmdchannel .importzp tmp2 @@ -17,7 +16,7 @@ ;-------------------------------------------------------------------------- ; _close - + .proc _close ; Check if we have a valid handle @@ -64,7 +63,3 @@ invalidfd: jmp __directerrno ; Set _errno, clear _oserror, return -1 .endproc - - - - diff --git a/libsrc/cbm/diskcmd.s b/libsrc/cbm/diskcmd.s index d090afe14..dbc15efbe 100644 --- a/libsrc/cbm/diskcmd.s +++ b/libsrc/cbm/diskcmd.s @@ -11,8 +11,6 @@ .export writediskcmd .export writefndiskcmd - .import SETLFS, SETNAM, OPEN, CLOSE, BSOUT, BASIN - .import CHKIN, CKOUT, CLRCH .import fncmd, fnlen, fnunit .importzp tmp1, ptr1 diff --git a/libsrc/cbm/filename.s b/libsrc/cbm/filename.s index a2b8aab5a..413b88d2a 100644 --- a/libsrc/cbm/filename.s +++ b/libsrc/cbm/filename.s @@ -8,11 +8,11 @@ .export fnadd, fnaddmode, fncomplete, fndefunit .export fnunit, fnlen, fnisfile, fncmd, fnbuf - .import SETNAM .import curunit, __filetype .importzp ptr1, tmp1 .include "ctype.inc" + .include "cbm.inc" ;------------------------------------------------------------------------------ diff --git a/libsrc/cbm/open.s b/libsrc/cbm/open.s index 5c97aff56..f23e97383 100644 --- a/libsrc/cbm/open.s +++ b/libsrc/cbm/open.s @@ -7,7 +7,6 @@ .export _open .destructor closeallfiles, 5 - .import SETLFS, OPEN, CLOSE .import addysp, popax .import scratch, fnparse, fnaddmode, fncomplete, fnset .import opencmdchannel, closecmdchannel, readdiskerror @@ -18,6 +17,7 @@ .include "errno.inc" .include "fcntl.inc" .include "filedes.inc" + .include "cbm.inc" ;-------------------------------------------------------------------------- diff --git a/libsrc/cbm/read.s b/libsrc/cbm/read.s index 9de4980ce..ee01596aa 100644 --- a/libsrc/cbm/read.s +++ b/libsrc/cbm/read.s @@ -8,7 +8,6 @@ .export _read .constructor initstdin - .import SETLFS, OPEN, CHKIN, BASIN, CLRCH, BSOUT, READST .import rwcommon .import popax .importzp ptr1, ptr2, ptr3, tmp1, tmp2, tmp3 diff --git a/libsrc/cbm/write.s b/libsrc/cbm/write.s index dddec0792..7a27f0044 100644 --- a/libsrc/cbm/write.s +++ b/libsrc/cbm/write.s @@ -7,7 +7,6 @@ .export _write .constructor initstdout - .import SETLFS, OPEN, CKOUT, BSOUT, READST, CLRCH .import rwcommon .importzp sp, ptr1, ptr2, ptr3 From fdce8fb34d9917033f1fdd008a771ec37119a66e Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Wed, 4 Jul 2018 17:40:28 +0300 Subject: [PATCH 0768/2161] Added a blank line between .include statements and .import/.export statements --- libsrc/cbm/c_acptr.s | 1 + libsrc/cbm/c_basin.s | 1 + libsrc/cbm/c_bsout.s | 1 + libsrc/cbm/c_chkin.s | 1 + libsrc/cbm/c_ciout.s | 1 + libsrc/cbm/c_ckout.s | 1 + libsrc/cbm/c_clall.s | 1 + libsrc/cbm/c_close.s | 1 + libsrc/cbm/c_clrch.s | 1 + libsrc/cbm/c_getin.s | 2 +- libsrc/cbm/c_iobase.s | 1 + libsrc/cbm/c_listen.s | 1 + libsrc/cbm/c_load.s | 1 + libsrc/cbm/c_open.s | 1 + libsrc/cbm/c_readst.s | 1 + libsrc/cbm/c_save.s | 1 + libsrc/cbm/c_scnkey.s | 1 + libsrc/cbm/c_second.s | 1 + libsrc/cbm/c_setlfs.s | 1 + libsrc/cbm/c_setnam.s | 1 + libsrc/cbm/c_talk.s | 1 + libsrc/cbm/c_tksa.s | 1 + libsrc/cbm/c_udtim.s | 1 + libsrc/cbm/c_unlsn.s | 1 + libsrc/cbm/c_untlk.s | 1 + libsrc/cbm/clock.s | 1 + 26 files changed, 26 insertions(+), 1 deletion(-) diff --git a/libsrc/cbm/c_acptr.s b/libsrc/cbm/c_acptr.s index 0c1363c8c..b060b614e 100644 --- a/libsrc/cbm/c_acptr.s +++ b/libsrc/cbm/c_acptr.s @@ -5,6 +5,7 @@ ; .include "cbm.inc" + .export _cbm_k_acptr diff --git a/libsrc/cbm/c_basin.s b/libsrc/cbm/c_basin.s index 9e3befee0..da925a1a4 100644 --- a/libsrc/cbm/c_basin.s +++ b/libsrc/cbm/c_basin.s @@ -5,6 +5,7 @@ ; .include "cbm.inc" + .export _cbm_k_basin diff --git a/libsrc/cbm/c_bsout.s b/libsrc/cbm/c_bsout.s index 043efd7d3..104878453 100644 --- a/libsrc/cbm/c_bsout.s +++ b/libsrc/cbm/c_bsout.s @@ -5,6 +5,7 @@ ; .include "cbm.inc" + .export _cbm_k_bsout _cbm_k_bsout = BSOUT diff --git a/libsrc/cbm/c_chkin.s b/libsrc/cbm/c_chkin.s index 39bc2222e..490adcefc 100644 --- a/libsrc/cbm/c_chkin.s +++ b/libsrc/cbm/c_chkin.s @@ -5,6 +5,7 @@ ; .include "cbm.inc" + .export _cbm_k_chkin diff --git a/libsrc/cbm/c_ciout.s b/libsrc/cbm/c_ciout.s index 5ef59c5b7..baf9e4735 100644 --- a/libsrc/cbm/c_ciout.s +++ b/libsrc/cbm/c_ciout.s @@ -6,4 +6,5 @@ .include "cbm.inc" + .export _cbm_k_ciout := CIOUT diff --git a/libsrc/cbm/c_ckout.s b/libsrc/cbm/c_ckout.s index 9efbb7343..46a5804dd 100644 --- a/libsrc/cbm/c_ckout.s +++ b/libsrc/cbm/c_ckout.s @@ -5,6 +5,7 @@ ; .include "cbm.inc" + .export _cbm_k_ckout diff --git a/libsrc/cbm/c_clall.s b/libsrc/cbm/c_clall.s index 1bc7bf747..406d4f5cc 100644 --- a/libsrc/cbm/c_clall.s +++ b/libsrc/cbm/c_clall.s @@ -5,4 +5,5 @@ ; .include "cbm.inc" + .export _cbm_k_clall := CLALL diff --git a/libsrc/cbm/c_close.s b/libsrc/cbm/c_close.s index db19f34c6..50d35b67c 100644 --- a/libsrc/cbm/c_close.s +++ b/libsrc/cbm/c_close.s @@ -5,6 +5,7 @@ ; .include "cbm.inc" + .export _cbm_k_close _cbm_k_close: diff --git a/libsrc/cbm/c_clrch.s b/libsrc/cbm/c_clrch.s index b0db2be4e..e537f4553 100644 --- a/libsrc/cbm/c_clrch.s +++ b/libsrc/cbm/c_clrch.s @@ -5,6 +5,7 @@ ; .include "cbm.inc" + .export _cbm_k_clrch _cbm_k_clrch = CLRCH diff --git a/libsrc/cbm/c_getin.s b/libsrc/cbm/c_getin.s index 23c1edc74..43009e91a 100644 --- a/libsrc/cbm/c_getin.s +++ b/libsrc/cbm/c_getin.s @@ -5,8 +5,8 @@ ; .include "cbm.inc" - .export _cbm_k_getin + .export _cbm_k_getin _cbm_k_getin: jsr GETIN diff --git a/libsrc/cbm/c_iobase.s b/libsrc/cbm/c_iobase.s index 58b66fd0b..9c77506e2 100644 --- a/libsrc/cbm/c_iobase.s +++ b/libsrc/cbm/c_iobase.s @@ -5,6 +5,7 @@ ; .include "cbm.inc" + .export _cbm_k_iobase _cbm_k_iobase: diff --git a/libsrc/cbm/c_listen.s b/libsrc/cbm/c_listen.s index 38908a60b..43859944f 100644 --- a/libsrc/cbm/c_listen.s +++ b/libsrc/cbm/c_listen.s @@ -5,4 +5,5 @@ ; .include "cbm.inc" + .export _cbm_k_listen := LISTEN diff --git a/libsrc/cbm/c_load.s b/libsrc/cbm/c_load.s index c9bd55ca0..d81430a03 100644 --- a/libsrc/cbm/c_load.s +++ b/libsrc/cbm/c_load.s @@ -5,6 +5,7 @@ ; .include "cbm.inc" + .export _cbm_k_load .import __oserror .import popa diff --git a/libsrc/cbm/c_open.s b/libsrc/cbm/c_open.s index 63249a57f..a4462ff47 100644 --- a/libsrc/cbm/c_open.s +++ b/libsrc/cbm/c_open.s @@ -5,6 +5,7 @@ ; .include "cbm.inc" + .export _cbm_k_open diff --git a/libsrc/cbm/c_readst.s b/libsrc/cbm/c_readst.s index e6243cef0..85211dd2f 100644 --- a/libsrc/cbm/c_readst.s +++ b/libsrc/cbm/c_readst.s @@ -5,6 +5,7 @@ ; .include "cbm.inc" + .export _cbm_k_readst diff --git a/libsrc/cbm/c_save.s b/libsrc/cbm/c_save.s index 6d05e6344..bd2e32bc4 100644 --- a/libsrc/cbm/c_save.s +++ b/libsrc/cbm/c_save.s @@ -5,6 +5,7 @@ ; .include "cbm.inc" + .export _cbm_k_save .import popptr1 .importzp ptr1, tmp1 diff --git a/libsrc/cbm/c_scnkey.s b/libsrc/cbm/c_scnkey.s index 38e3f4cec..0fb74a46e 100644 --- a/libsrc/cbm/c_scnkey.s +++ b/libsrc/cbm/c_scnkey.s @@ -5,4 +5,5 @@ ; .include "cbm.inc" + .export _cbm_k_scnkey := SCNKEY diff --git a/libsrc/cbm/c_second.s b/libsrc/cbm/c_second.s index 2670e1cd4..6902a2a68 100644 --- a/libsrc/cbm/c_second.s +++ b/libsrc/cbm/c_second.s @@ -5,6 +5,7 @@ ; .include "cbm.inc" + .export _cbm_k_second _cbm_k_second = SECOND diff --git a/libsrc/cbm/c_setlfs.s b/libsrc/cbm/c_setlfs.s index b93d80c09..47ef213c3 100644 --- a/libsrc/cbm/c_setlfs.s +++ b/libsrc/cbm/c_setlfs.s @@ -7,6 +7,7 @@ ; .include "cbm.inc" + .export _cbm_k_setlfs .import popa .importzp tmp1 diff --git a/libsrc/cbm/c_setnam.s b/libsrc/cbm/c_setnam.s index 5b6b90c64..d13394835 100644 --- a/libsrc/cbm/c_setnam.s +++ b/libsrc/cbm/c_setnam.s @@ -5,6 +5,7 @@ ; .include "cbm.inc" + .export _cbm_k_setnam .importzp ptr1 diff --git a/libsrc/cbm/c_talk.s b/libsrc/cbm/c_talk.s index 01ab376d1..7b1d7d6ce 100644 --- a/libsrc/cbm/c_talk.s +++ b/libsrc/cbm/c_talk.s @@ -5,4 +5,5 @@ ; .include "cbm.inc" + .export _cbm_k_talk := TALK diff --git a/libsrc/cbm/c_tksa.s b/libsrc/cbm/c_tksa.s index c59c7f5a0..8576375be 100644 --- a/libsrc/cbm/c_tksa.s +++ b/libsrc/cbm/c_tksa.s @@ -5,6 +5,7 @@ ; .include "cbm.inc" + .export _cbm_k_tksa _cbm_k_tksa = TKSA diff --git a/libsrc/cbm/c_udtim.s b/libsrc/cbm/c_udtim.s index ba12d1e35..19447d6f4 100644 --- a/libsrc/cbm/c_udtim.s +++ b/libsrc/cbm/c_udtim.s @@ -5,4 +5,5 @@ ; .include "cbm.inc" + .export _cbm_k_udtim := UDTIM diff --git a/libsrc/cbm/c_unlsn.s b/libsrc/cbm/c_unlsn.s index 5a525374b..39d8eea71 100644 --- a/libsrc/cbm/c_unlsn.s +++ b/libsrc/cbm/c_unlsn.s @@ -5,4 +5,5 @@ ; .include "cbm.inc" + .export _cbm_k_unlsn := UNLSN diff --git a/libsrc/cbm/c_untlk.s b/libsrc/cbm/c_untlk.s index dfde77e3f..68fba208f 100644 --- a/libsrc/cbm/c_untlk.s +++ b/libsrc/cbm/c_untlk.s @@ -5,6 +5,7 @@ ; .include "cbm.inc" + .export _cbm_k_untlk _cbm_k_untlk = UNTLK diff --git a/libsrc/cbm/clock.s b/libsrc/cbm/clock.s index 0c8ba9c45..b5fa6e89b 100644 --- a/libsrc/cbm/clock.s +++ b/libsrc/cbm/clock.s @@ -5,6 +5,7 @@ ; .include "cbm.inc" + .export _clock .importzp sreg From eeb1b927cee5fefe6910201447a23781ef4ea720 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 15 Jun 2018 11:01:14 -0400 Subject: [PATCH 0769/2161] Fixed the order in which the 65816's block-move instructions' operands are written and assembled. The source bank number is written first; but, assembled second. The destination bank is written second; but, assembled first. --- src/ca65/instr.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 37217203a..8d1e96705 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -1298,10 +1298,16 @@ static void PutPCRel4510 (const InsDesc* Ins) static void PutBlockMove (const InsDesc* Ins) /* Handle the blockmove instructions (65816) */ { + ExprNode* Arg1 = Expression (); + Emit0 (Ins->BaseCode); - EmitByte (Expression ()); ConsumeComma (); + + /* The operands are written in Assembly code as source, destination; + ** but, they're assembled as <destination> <source>. + */ EmitByte (Expression ()); + EmitByte (Arg1); } From 1981af0bbdc75d89c84ed08d6b5554bd200fb9ae Mon Sep 17 00:00:00 2001 From: Scott Hutter <scott.hutter@gmail.com> Date: Mon, 23 Jul 2018 15:54:15 -0500 Subject: [PATCH 0770/2161] tgi driver for c128 VIC-II --- libsrc/c128/tgi/c128-hi.s | 884 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 884 insertions(+) create mode 100644 libsrc/c128/tgi/c128-hi.s diff --git a/libsrc/c128/tgi/c128-hi.s b/libsrc/c128/tgi/c128-hi.s new file mode 100644 index 000000000..2286ee210 --- /dev/null +++ b/libsrc/c128/tgi/c128-hi.s @@ -0,0 +1,884 @@ +; +; Graphics driver for the 320x200x2 mode on the C128. +; +; Based on Stephen L. Judd's GRLIB code. +; +; 2017-01-13, Greg King +; 2018-03-13, Sven Klose +; 2018-07-22, Scott Hutter +; + + .include "zeropage.inc" + + .include "tgi-kernel.inc" + .include "tgi-error.inc" + + .macpack generic + .macpack module + + +; ------------------------------------------------------------------------ +; Header. Includes jump table and constants. + + module_header _c128_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 + +; INIT/DONE +OLDD018: .res 1 ; Old register value + +; 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, $01 ; 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 +CBASE := $5C00 ; Color memory base address +VBASE := $6000 ; Video memory base address + ; BASE + $4000 for each bank above VIC bank 0 + ; $2000 = VIC bank 0 (base) + ; $6000 = VIC bank 1 + ; $A000 = VIC bank 2 + ; $E000 = VIC bank 3 + + +.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 + + ; select video bank + ; bank 0=3 ($0-$3FFF) (default) + ; bank 1=2 ($4000-$7FFF) * + ; bank 2=1 ($8000-$BFFF) + ; bank 3=0 ($C000-$FFFF) + lda $DD00 + and #$FC + ora #$02 ; bank number 1 ($4000) + sta $DD00 + + ; Switch to bitmap mode + lda $D8 + ora #$20 + sta $D8 + +DONE1: 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: ; select video bank + lda $DD00 + and #$FC + ora #$03 ; bank 0=3 ($0-$3FFF), 1=2 ($4000-$7FFF), 2=1 ($8000-$BFFF), 3=0 ($C000-$FFFF) + sta $DD00 + + lda $0A2D ; change screen ram location + AND #$0F + ORA #$10 ; $0400 + STA $0A2D + + LDA #$00 ; switch back to text mode + STA $D8 + 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 ; preserve vectors + 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 + and #$0F ; Make a valid color + sta PALETTE,y + dey + bpl @L1 + +; Get the color entries from the palette + + lda PALETTE+1 ; Foreground color + asl a + asl a + asl a + asl a + ora PALETTE ; Background color + tax + +; Initialize the color map with the new color settings (it is below the +; I/O area) + + ldy #$00 + sei + lda $01 ; Get ROM config + pha ; Save it + and #%11111100 ; Clear bit 0 and 1 + sta $01 + txa ; Load color code +@L2: sta CBASE+$0000,y + sta CBASE+$0100,y + sta CBASE+$0200,y + sta CBASE+$02e8,y + iny + bne @L2 + pla + sta $01 + cli + +; Done, reset the error code + + lda #TGI_ERR_OK + sta ERROR + rts + +; ------------------------------------------------------------------------ +; GETPALETTE: Return the current palette in A/X. Even drivers that cannot +; set the palette should return the default palette here, so there's no +; way for this function to fail. +; +; Must set an error code: NO +; + +GETPALETTE: + lda #<PALETTE + ldx #>PALETTE + rts + +; ------------------------------------------------------------------------ +; GETDEFPALETTE: Return the default palette for the driver in A/X. All +; drivers should return something reasonable here, even drivers that don't +; support palettes, otherwise the caller has no way to determine the colors +; of the (not changeable) palette. +; +; Must set an error code: NO (all drivers must have a default palette) +; + +GETDEFPALETTE: + lda #<DEFPALETTE + ldx #>DEFPALETTE + rts + +; ------------------------------------------------------------------------ +; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing +; color. The coordinates passed to this function are never outside the +; visible screen area, so there is no need for clipping inside this function. +; +; Must set an error code: NO +; + +SETPIXEL: + jsr CALC ; Calculate coordinates + + sei ; Get underneath ROM + lda $01 + pha + lda #$34 + sta $01 + + lda (POINT),Y + eor BITMASK + and BITTAB,X + eor (POINT),Y + sta (POINT),Y + + pla + sta $01 + cli + +@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 + + sei ; Get underneath ROM + lda $01 + pha + lda #$34 + sta $01 + + lda (POINT),Y + ldy #$00 + and BITTAB,X + beq @L1 + iny + +@L1: pla + sta $01 + cli + + tya ; Get color value into A + ldx #$00 ; Clear high byte + rts + +; ------------------------------------------------------------------------ +; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and +; X2/Y2 = ptr3/ptr4 using the current drawing color. +; +; X1,X2 etc. are set up above (x2=LINNUM in particular) +; Format is LINE x2,y2,x1,y1 +; +; Must set an error code: NO +; + +LINE: + +@CHECK: lda X2 ;Make sure x1<x2 + sec + sbc X1 + tax + lda X2+1 + sbc X1+1 + bpl @CONT + lda Y2 ;If not, swap P1 and P2 + ldy Y1 + sta Y1 + sty Y2 + lda Y2+1 + ldy Y1+1 + sta Y1+1 + sty Y2+1 + lda X1 + ldy X2 + sty X1 + sta X2 + lda X2+1 + ldy X1+1 + sta X1+1 + sty X2+1 + bcc @CHECK + +@CONT: sta DX+1 + stx DX + + ldx #$C8 ;INY + lda Y2 ;Calculate dy + sec + sbc Y1 + tay + lda Y2+1 + sbc Y1+1 + bpl @DYPOS ;Is y2>=y1? + lda Y1 ;Otherwise dy=y1-y2 + sec + sbc Y2 + tay + ldx #$88 ;DEY + +@DYPOS: sty DY ; 8-bit DY -- FIX ME? + stx YINCDEC + stx XINCDEC + + jsr CALC ; Set up .X, .Y, and POINT + lda BITCHUNK,X + sta OLDCHUNK + sta CHUNK + + sei ; Get underneath ROM + lda #$34 + sta $01 + + 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 + lda #$36 + sta $01 + cli + 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 + jsr LINEPLOT ;Plot the last chunk + lda #$36 + sta $01 + cli + rts +; +; 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 From b04028b5d8ea4ab9984f9ab648791013004dcefb Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 24 Jul 2018 03:25:49 +0200 Subject: [PATCH 0771/2161] Added test for mktime() and gmtime(). A recent regression makes gmtime()/localtime() fail. So it's obviously desirable to have a test for that code. --- test/val/time.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 test/val/time.c diff --git a/test/val/time.c b/test/val/time.c new file mode 100644 index 000000000..11b0dcf91 --- /dev/null +++ b/test/val/time.c @@ -0,0 +1,36 @@ +#include <time.h> +#include <stdio.h> + +int main(void) +{ + int failures = 0; + + struct tm timeinfo; + time_t rawtime; + struct tm *p_timeinfo; + + timeinfo.tm_year = 2020 - 1900; + timeinfo.tm_mon = 12 - 1; + timeinfo.tm_mday = 24; + timeinfo.tm_hour = 10; + timeinfo.tm_min = 30; + timeinfo.tm_sec = 50; + timeinfo.tm_isdst = 0; + + rawtime = mktime(&timeinfo); + + failures += !(rawtime == 1608805850); + + p_timeinfo = gmtime(&rawtime); + + failures += !(p_timeinfo->tm_year == timeinfo.tm_year); + failures += !(p_timeinfo->tm_mon == timeinfo.tm_mon); + failures += !(p_timeinfo->tm_mday == timeinfo.tm_mday); + failures += !(p_timeinfo->tm_hour == timeinfo.tm_hour); + failures += !(p_timeinfo->tm_min == timeinfo.tm_min); + failures += !(p_timeinfo->tm_sec == timeinfo.tm_sec); + + printf("%lu\n%s%d\n", rawtime, asctime(p_timeinfo), failures); + + return failures; +} From c9869c1a26a5be1f3e3c789ed31e56568fa69059 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Wed, 25 Jul 2018 22:38:29 +0200 Subject: [PATCH 0772/2161] Quick fix for missing _div() adaptation after 95223be. --- libsrc/common/divt.s | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libsrc/common/divt.s b/libsrc/common/divt.s index b532f6f95..f1291c86f 100644 --- a/libsrc/common/divt.s +++ b/libsrc/common/divt.s @@ -18,10 +18,12 @@ .importzp sreg, ptr1, tmp1 _div: jsr tosdivax ; Division-operator does most of the work - sta sreg ; Quotient is in sreg - stx sreg+1 - lda ptr1 ; Unsigned remainder is in ptr1 - ldx ptr1+1 + lda sreg ; Unsigned remainder is in sreg + ldx sreg+1 + ldy ptr1 ; transfer quotient to sreg + sty sreg + ldy ptr1+1 + sty sreg+1 ; Adjust the sign of the remainder. ; It must be the same as the sign of the dividend. From 97be359d4af9cb15be23cea7e885b39488226964 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 26 Jul 2018 13:09:21 +0200 Subject: [PATCH 0773/2161] Updated comment. --- include/ctype.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/ctype.h b/include/ctype.h index 17cbafe9f..103f6cc22 100644 --- a/include/ctype.h +++ b/include/ctype.h @@ -84,7 +84,7 @@ unsigned char __fastcall__ toascii (unsigned char c); -/* When inlining-of-known-functions is enabled, overload most of the above +/* When --eagerly-inline-funcs is enabled, overload most of the above ** functions by macroes. The function prototypes are available again after ** #undef'ing the macroes. ** Please note that the following macroes do NOT handle EOF correctly, as From e949a3e64283e65b00ba8311bc9cec7fcb6ff681 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 26 Jul 2018 14:31:17 +0200 Subject: [PATCH 0774/2161] Fixed regression introduced by https://github.com/cc65/cc65/pull/652. --- libsrc/apple2/devicedir.s | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libsrc/apple2/devicedir.s b/libsrc/apple2/devicedir.s index de6bad5f2..79f4c60de 100644 --- a/libsrc/apple2/devicedir.s +++ b/libsrc/apple2/devicedir.s @@ -20,6 +20,7 @@ _getdevicedir: jsr popptr1 ; Set buf + ldx ptr1+1 sta mliparam + MLI::ON_LINE::DATA_BUFFER stx mliparam + MLI::ON_LINE::DATA_BUFFER+1 @@ -62,7 +63,7 @@ oserr: jsr __mappederrno lda (ptr1),y and #15 ; Max volume name length sta tmp1 - + ; Add leading slash lda #'/' sta (ptr1),y From e86a7db18b2a46dcc0c6a2ddfb4ad1f323a7b1c9 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 26 Jul 2018 14:35:26 +0200 Subject: [PATCH 0775/2161] Some minor cleanups. --- libsrc/atari/dio_stc.s | 4 ++-- libsrc/atari/siocall.s | 2 +- libsrc/runtime/popptr1.s | 8 ++------ 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/libsrc/atari/dio_stc.s b/libsrc/atari/dio_stc.s index 70dd16088..768aca085 100644 --- a/libsrc/atari/dio_stc.s +++ b/libsrc/atari/dio_stc.s @@ -17,14 +17,14 @@ .export _dio_log_to_phys .include "atari.inc" .importzp ptr1,ptr2,ptr3 - .import popax, popptr1, __oserror + .import popax,popptr1,__oserror .proc _dio_log_to_phys sta ptr2 stx ptr2+1 ; pointer to output structure - jsr popptr1 ; save pointer to input data + jsr popptr1 ; save pointer to input data jsr popax sta ptr3 diff --git a/libsrc/atari/siocall.s b/libsrc/atari/siocall.s index 0465a6a3e..e4fc505e3 100644 --- a/libsrc/atari/siocall.s +++ b/libsrc/atari/siocall.s @@ -16,7 +16,7 @@ .export __sio_call .include "atari.inc" - .import popa, popax, popptr1 + .import popa,popax,popptr1 .import sectsizetab,__oserror .importzp ptr1 diff --git a/libsrc/runtime/popptr1.s b/libsrc/runtime/popptr1.s index 48725efa3..1d04330ab 100644 --- a/libsrc/runtime/popptr1.s +++ b/libsrc/runtime/popptr1.s @@ -8,16 +8,12 @@ .import incsp2 .importzp sp, ptr1 - .macpack cpu - -.proc popptr1 ; 14 bytes (four usages = at least 2 bytes saved) +.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 ; no optimization for 65C02 here to have Y=0 at exit! lda (sp),y ; get lo byte sta ptr1 ; to ptr lo jmp incsp2 .endproc - - From e6fc904e3c43776692a2bb27b1c7bb4f2bbb1bf5 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 27 Jul 2018 09:07:40 -0400 Subject: [PATCH 0776/2161] Fixed some code, to adapt to register-use changes caused by pull request #652. --- libsrc/tgi/tgi_getset.s | 17 +++++++++-------- libsrc/tgi/tgi_popxy.s | 8 ++++---- libsrc/zlib/adler32.s | 4 +++- libsrc/zlib/crc32.s | 6 +++--- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/libsrc/tgi/tgi_getset.s b/libsrc/tgi/tgi_getset.s index aded19d71..152470503 100644 --- a/libsrc/tgi/tgi_getset.s +++ b/libsrc/tgi/tgi_getset.s @@ -1,8 +1,9 @@ ; -; Ullrich von Bassewitz, 22.06.2002 +; 2002-06-22, Ullrich von Bassewitz +; 2018-07-27, Greg King ; -; Helper function for getpixel/setpixel. Load X/Y from stack and check if -; the coordinates are valid. Return carry clear if so. +; Helper function for getpixel/setpixel. Load X/Y from arguments; +; and, check if the co-ordinates are valid. Return carry clear if so. ; .include "tgi-kernel.inc" @@ -15,13 +16,14 @@ jsr tgi_popxy ; Pop X/Y into ptr1/ptr2 -; Are the coordinates out of range? First check if any coord is negative. +; Are the co-ordinates out of range? First, check if any coord is negative. - txa - ora ptr2+1 + txa ; (.X = ptr2+1 from tgi_popxy) + ora ptr1+1 + sec ; Return carry set if number is negative bmi @L9 ; Bail out if negative -; Check if X is larger than the maximum x coord. If so, bail out +; Check if X is larger than the maximum x coord. If so, bail out. lda ptr1 cmp _tgi_xres @@ -38,4 +40,3 @@ @L9: rts .endproc - diff --git a/libsrc/tgi/tgi_popxy.s b/libsrc/tgi/tgi_popxy.s index 33ccc57f9..2d9ac5d05 100644 --- a/libsrc/tgi/tgi_popxy.s +++ b/libsrc/tgi/tgi_popxy.s @@ -1,13 +1,14 @@ ; -; Ullrich von Bassewitz, 02.10.2002 +; 2002-10-02, Ullrich von Bassewitz +; 2018-05-20, Christian Kruger ; -; Helper function for tgi functions. Pops X/Y from stack into ptr1/ptr2 +; Helper function for TGI functions. Pops X/Y from arguments into ptr1/ptr2. ; .include "tgi-kernel.inc" .import popptr1 - .importzp ptr1, ptr2 + .importzp ptr2 .proc tgi_popxy @@ -16,4 +17,3 @@ jmp popptr1 ; X .endproc - diff --git a/libsrc/zlib/adler32.s b/libsrc/zlib/adler32.s index ccfe2f167..8aa641a13 100644 --- a/libsrc/zlib/adler32.s +++ b/libsrc/zlib/adler32.s @@ -1,5 +1,6 @@ ; -; Piotr Fusik, 18.11.2001 +; 2001-11-18, Piotr Fusik +; 2018-05-20, Christian Kruger ; ; unsigned long __fastcall__ adler32 (unsigned long adler, unsigned char* buf, ; unsigned len); @@ -78,6 +79,7 @@ _adler32: ; return 1L @L0: sta sreg sta sreg+1 + tax ; (popptr1 doesn't set .X) lda #1 ; ignore adler jmp incsp4 diff --git a/libsrc/zlib/crc32.s b/libsrc/zlib/crc32.s index 7f06dd383..f019736ad 100644 --- a/libsrc/zlib/crc32.s +++ b/libsrc/zlib/crc32.s @@ -1,5 +1,6 @@ ; -; Piotr Fusik, 14.11.2001 +; 2001-11-14, Piotr Fusik +; 2018-05-20, Christian Kruger ; ; unsigned long __fastcall__ crc32 (unsigned long crc, unsigned char* buf, ; unsigned len); @@ -116,6 +117,7 @@ _crc32: ; return 0L @L0: sta sreg sta sreg+1 + tax ; (popptr1 doesn't set .X) ; ignore crc jmp incsp4 @@ -128,5 +130,3 @@ table_0: .res 256 table_1: .res 256 table_2: .res 256 table_3: .res 256 - - From ad6c2dbe7b2215314edbb19b2828b0f1067619b2 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 29 Jul 2018 03:50:02 -0400 Subject: [PATCH 0777/2161] Added code to make the 65816's MVN and MVP instructions handle both immediate (bank) and far-address operands. --- src/ca65/instr.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 8d1e96705..eb005289c 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -1295,18 +1295,38 @@ static void PutPCRel4510 (const InsDesc* Ins) } + static void PutBlockMove (const InsDesc* Ins) /* Handle the blockmove instructions (65816) */ { - ExprNode* Arg1 = Expression (); + ExprNode* Arg1; + ExprNode* Arg2; Emit0 (Ins->BaseCode); + + if (CurTok.Tok == TOK_HASH) { + /* The operand is a bank-byte expression. */ + NextTok (); + Arg1 = Expression (); + } else { + /* The operand is a far-address expression. + ** Use only its bank part. + */ + Arg1 = FuncBankByte (); + } ConsumeComma (); + if (CurTok.Tok == TOK_HASH) { + NextTok (); + Arg2 = Expression (); + } else { + Arg2 = FuncBankByte (); + } + /* The operands are written in Assembly code as source, destination; ** but, they're assembled as <destination> <source>. */ - EmitByte (Expression ()); + EmitByte (Arg2); EmitByte (Arg1); } From 5e67eee36247b4392fd109ca8def77b886b7a5f1 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 29 Jul 2018 18:00:58 -0400 Subject: [PATCH 0778/2161] Made the VIC-IIe TGI driver put its bitmap behind the ROMs. --- asminc/c128.inc | 25 +++-- include/c128.h | 1 + libsrc/c128/tgi/c128-hi.s | 206 +++++++++++++++++++------------------- 3 files changed, 116 insertions(+), 116 deletions(-) diff --git a/asminc/c128.inc b/asminc/c128.inc index 45ac3935b..7a98d770c 100644 --- a/asminc/c128.inc +++ b/asminc/c128.inc @@ -16,6 +16,8 @@ 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 @@ -25,22 +27,23 @@ CHARCOLOR := $F1 RVS := $F3 ; Reverse output flag SCROLL := $F8 ; Disable scrolling flag -BASIC_BUF := $200 ; Location of command-line +BASIC_BUF := $0200 ; Location of command-line BASIC_BUF_LEN = 162 ; Maximum length of command-line -FETCH := $2A2 ; Fetch subroutine in RAM -FETVEC := $2AA ; Vector patch location for FETCH -STASH := $2AF ; Stash routine in RAM -STAVEC := $2B9 ; Vector patch location for STASH -IRQInd := $2FD ; JMP $0000 -- used as indirect IRQ vector -PALFLAG := $A03 ; $FF=PAL, $00=NTSC -INIT_STATUS := $A04 ; Flags: Reset/Restore initiation status +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 := $28a -KBDREPEATRATE := $28b -KBDREPEATDELAY := $28c +KBDREPEAT := $028a +KBDREPEATRATE := $028b +KBDREPEATDELAY := $028c ; --------------------------------------------------------------------------- ; Kernal routines diff --git a/include/c128.h b/include/c128.h index 99e050a9b..fe1dd4317 100644 --- a/include/c128.h +++ b/include/c128.h @@ -141,6 +141,7 @@ extern void c128_joy_mou[]; extern void c128_inkwell_mou[]; extern void c128_pot_mou[]; extern void c128_swlink_ser[]; +extern void c128_hi_tgi[]; extern void c128_vdc_tgi[]; /* Referred to by tgi_static_stddrv[] */ extern void c128_vdc2_tgi[]; diff --git a/libsrc/c128/tgi/c128-hi.s b/libsrc/c128/tgi/c128-hi.s index 2286ee210..ef68ccd68 100644 --- a/libsrc/c128/tgi/c128-hi.s +++ b/libsrc/c128/tgi/c128-hi.s @@ -3,15 +3,16 @@ ; ; Based on Stephen L. Judd's GRLIB code. ; -; 2017-01-13, Greg King ; 2018-03-13, Sven Klose ; 2018-07-22, Scott Hutter +; 2018-07-28, Greg King ; .include "zeropage.inc" .include "tgi-kernel.inc" .include "tgi-error.inc" + .include "c128.inc" .macpack generic .macpack module @@ -77,7 +78,7 @@ TEMP2 := sreg POINT := regsave CHUNK := X2 ; Used in the line routine -OLDCHUNK := X2+1 ; Dito +OLDCHUNK := X2+1 ; Ditto ; Absolute variables used in the code @@ -88,18 +89,15 @@ PALETTE: .res 2 ; The current palette BITMASK: .res 1 ; $00 = clear, $FF = set pixels -; INIT/DONE -OLDD018: .res 1 ; Old register value - ; Line routine stuff DX: .res 2 DY: .res 2 ; BAR variables X1SAVE: .res 2 -Y1SAVE: .res 2 +Y1SAVE: .res 1 X2SAVE: .res 2 -Y2SAVE: .res 2 +Y2SAVE: .res 1 ; Text output stuff TEXTMAGX: .res 1 @@ -116,15 +114,10 @@ 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 -CBASE := $5C00 ; Color memory base address -VBASE := $6000 ; Video memory base address - ; BASE + $4000 for each bank above VIC bank 0 - ; $2000 = VIC bank 0 (base) - ; $6000 = VIC bank 1 - ; $A000 = VIC bank 2 - ; $E000 = VIC bank 3 +CHARROM := $D000 ; Character ROM base address +VBASE := $C000 ; Video memory base address +CBASE := $E000 ; Color memory base address .code @@ -166,28 +159,38 @@ UNINSTALL: ; INIT: -; Initialize variables - ldx #$FF + +; Initialize variables. + + ldx #$FF ; Foreground color stx BITMASK -; Switch into graphics mode +; Switch into graphics mode. - ; select video bank - ; bank 0=3 ($0-$3FFF) (default) - ; bank 1=2 ($4000-$7FFF) * - ; bank 2=1 ($8000-$BFFF) - ; bank 3=0 ($C000-$FFFF) - lda $DD00 - and #$FC - ora #$02 ; bank number 1 ($4000) - sta $DD00 +; Select a video bank: +; bank 0 = $03 ($0000-$3FFF) (default) +; bank 1 = $02 ($4000-$7FFF) +; bank 2 = $01 ($8000-$BFFF) +; bank 3 = $00 ($C000-$FFFF) (TGI) - ; Switch to bitmap mode - lda $D8 - ora #$20 - sta $D8 - -DONE1: lda #TGI_ERR_OK + lda CIA2_PRA + and #<~$03 ; Bank 3 + sta CIA2_PRA + + lda #$80 ; color-map at $E000, bitmap at $C000 + sta VM2 + +; Make the VIC-IIe read RAM instead of the font ROM. + + lda #%00000100 + sta CHARDIS + +; Switch to bitmap mode. + + lda #%00100000 + sta GRAPHM + + lda #TGI_ERR_OK sta ERROR rts @@ -199,19 +202,26 @@ DONE1: lda #TGI_ERR_OK ; Must set an error code: NO ; -DONE: ; select video bank - lda $DD00 - and #$FC - ora #$03 ; bank 0=3 ($0-$3FFF), 1=2 ($4000-$7FFF), 2=1 ($8000-$BFFF), 3=0 ($C000-$FFFF) - sta $DD00 +DONE: - lda $0A2D ; change screen ram location - AND #$0F - ORA #$10 ; $0400 - STA $0A2D +; Select the text video bank. - LDA #$00 ; switch back to text mode - STA $D8 + lda CIA2_PRA + ora #$03 ; Bank 0 + sta CIA2_PRA + +; Make the VIC-IIe read the font ROM instead of RAM. + + lda #%00000000 + sta CHARDIS + + ;lda #%00000000 ; Switch back to text mode + sta GRAPHM + +; Restore a value that's needed by BASIC's GRAPHIC 1 statement. + + lda #$78 ; color-map at $1C00, bitmap at $2000 + sta VM2 rts ; ------------------------------------------------------------------------ @@ -240,9 +250,12 @@ CONTROL: ; Must set an error code: NO ; -CLEAR: - ldy #$00 +CLEAR: + ldy #$00 tya + ldx #MMU_CFG_RAM0 + sei + stx MMU_CR @L1: sta VBASE+$0000,y sta VBASE+$0100,y sta VBASE+$0200,y @@ -274,9 +287,12 @@ CLEAR: sta VBASE+$1C00,y sta VBASE+$1D00,y sta VBASE+$1E00,y - sta VBASE+$1E40,y ; preserve vectors + sta VBASE+$1F00,y iny bne @L1 + ldx #MMU_CFG_CC65 + stx MMU_CR + cli rts ; ------------------------------------------------------------------------ @@ -337,26 +353,22 @@ SETPALETTE: asl a asl a ora PALETTE ; Background color - tax ; Initialize the color map with the new color settings (it is below the -; I/O area) +; Kernal ROM). ldy #$00 + ldx #MMU_CFG_RAM0 sei - lda $01 ; Get ROM config - pha ; Save it - and #%11111100 ; Clear bit 0 and 1 - sta $01 - txa ; Load color code + stx MMU_CR @L2: sta CBASE+$0000,y sta CBASE+$0100,y sta CBASE+$0200,y sta CBASE+$02e8,y iny bne @L2 - pla - sta $01 + ldx #MMU_CFG_CC65 + stx MMU_CR cli ; Done, reset the error code @@ -403,11 +415,9 @@ GETDEFPALETTE: SETPIXEL: jsr CALC ; Calculate coordinates - sei ; Get underneath ROM - lda $01 - pha - lda #$34 - sta $01 + lda #MMU_CFG_RAM0 ; Work behind ROMs + sei + sta MMU_CR lda (POINT),Y eor BITMASK @@ -415,11 +425,11 @@ SETPIXEL: eor (POINT),Y sta (POINT),Y - pla - sta $01 + ldx #MMU_CFG_CC65 + stx MMU_CR cli -@L9: rts + rts ; ------------------------------------------------------------------------ ; GETPIXEL: Read the color value of a pixel and return it in A/X. The @@ -430,23 +440,18 @@ SETPIXEL: GETPIXEL: jsr CALC ; Calculate coordinates - sei ; Get underneath ROM - lda $01 - pha - lda #$34 - sta $01 + lda #MMU_CFG_RAM0 ; Work behind ROMs + sei + sta MMU_CR lda (POINT),Y - ldy #$00 and BITTAB,X beq @L1 - iny + lda #$01 ; Foreground color -@L1: pla - sta $01 +@L1: ldy #MMU_CFG_CC65 + sty MMU_CR cli - - tya ; Get color value into A ldx #$00 ; Clear high byte rts @@ -513,9 +518,9 @@ LINE: sta OLDCHUNK sta CHUNK - sei ; Get underneath ROM - lda #$34 - sta $01 + lda #MMU_CFG_RAM0 ; Work behind ROMs + sei + sta MMU_CR ldx DY cpx DX ;Who's bigger: dy or dx? @@ -571,8 +576,8 @@ YCONT2: lda (POINT),y ;Plot endpoint and CHUNK eor (POINT),y sta (POINT),y - lda #$36 - sta $01 + ldx #MMU_CFG_CC65 + stx MMU_CR cli rts @@ -628,8 +633,8 @@ XCONT2: dex lsr CHUNK ;Advance to last point jsr LINEPLOT ;Plot the last chunk - lda #$36 - sta $01 + ldx #MMU_CFG_CC65 + stx MMU_CR cli rts ; @@ -737,47 +742,35 @@ FIXY: cpy #255 ;Y=255 or Y=8 ; 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 - +BAR: lda X2 sta X2SAVE lda X2+1 sta X2SAVE+1 - lda Y1 - sta Y1SAVE - lda Y1+1 - sta Y1SAVE+1 + lda Y2 + sta Y2SAVE lda X1 sta X1SAVE lda X1+1 sta X1SAVE+1 -@L1: lda Y1 - sta Y2 - lda Y1+1 + lda Y1 + sta Y1SAVE + +@L1: sta Y2 + lda #>200 + sta 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 + inc Y1SAVE lda X1SAVE sta X1 @@ -788,6 +781,9 @@ BAR: lda Y2 sta X2 lda X2SAVE+1 sta X2+1 + + lda Y1SAVE + sta Y1 jmp @L1 @L4: rts From 3e8c6bf4bdf9c513dd71a31c484769e9719576c7 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 30 Jul 2018 15:33:52 +0000 Subject: [PATCH 0779/2161] c128-hi.tgi doc --- doc/c128.sgml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/doc/c128.sgml b/doc/c128.sgml index abb9dbf25..db93e854c 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -200,13 +200,13 @@ memory drivers using the VDC memory! <descrip> <tag><tt/c128-vdc.tgi (c128_vdc_tgi)/</tag> This driver was written by Maciej Witkowiak. It uses the 80-column display, - and features a resolution of 640*200 with two colors and an adjustable + and features a resolution of 640×200 with two colors and an adjustable palette (that means that the two colors can be chosen out of the 16 VDC colors). <tag><tt/c128-vdc2.tgi (c128_vdc2_tgi)/</tag> This driver was written by Maciej Witkowiak. This driver uses the 80-column - display, and features a resolution of 640*480 with two colors and an + display, and features a resolution of 640×480 with two colors and an adjustable palette (that means that the two colors can be chosen out of the 16 VDC colors). The driver requires 64KB VDC RAM. </descrip><p> @@ -215,6 +215,15 @@ Note: The colors are translated from definitions in headers to correct VDC value so, please use definitions or VIC color numbers only. Colors <tt/GRAY3/ and <tt/BROWN/ are missing on VDC, and are translated to the two colors missing from the VIC palette. +<descrip> + <tag><tt/c128-hi.tgi (c128_hi_tgi)/</tag> + This driver features a resolution of 320×200 with two colors and an + adjustable palette (that means that the two colors can be chosen out of a + palette of the 16 VIC colors). Unlike BASIC 7.0 this driver put its graphics + data into the RAM behind the ROMs. +</descrip><p> + + <sect1>Extended memory drivers<p> <descrip> From 753b48647ff2951ab1694e578fe75faf61d23b5a Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 2 Aug 2018 15:45:57 +0200 Subject: [PATCH 0780/2161] Increased consistency. The test program works as-is only if the timezone isn't set (to something different than UTC). However, using localtime() instead of gmtime() makes it at least consistent in that the original time (given to mktime()) is identical to the time retrieved. --- test/val/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/val/time.c b/test/val/time.c index 11b0dcf91..e1c33495a 100644 --- a/test/val/time.c +++ b/test/val/time.c @@ -21,7 +21,7 @@ int main(void) failures += !(rawtime == 1608805850); - p_timeinfo = gmtime(&rawtime); + p_timeinfo = localtime(&rawtime); failures += !(p_timeinfo->tm_year == timeinfo.tm_year); failures += !(p_timeinfo->tm_mon == timeinfo.tm_mon); From a9ce4dc76cbc338ea1812bd37663593e658f8f1e Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 2 Aug 2018 17:12:12 +0200 Subject: [PATCH 0781/2161] "Inverted" time_t value handling. So far time_t values were interpreted as local time values. However, usually time_t values are to be interpreted as "seconds since 1 Jan 1970 in UTC". Therefore all logic handling time_t values has to be changed. - So far gmtime() called localtime() with an adjusted time_t, now localtime() calls gmtime() with an adjusted time_t. - mktime() has to do "the opposite" of localtime(), to keep it that way mktime() does now the inverse adjustment made by localtime(). - All currently present time() implementations internally call mktime() so they don't require individual adjustments. --- libsrc/common/gmtime.c | 28 +++++++++++++++++++--------- libsrc/common/localtime.c | 27 ++++++--------------------- libsrc/common/mktime.c | 3 ++- 3 files changed, 27 insertions(+), 31 deletions(-) diff --git a/libsrc/common/gmtime.c b/libsrc/common/gmtime.c index 1a2536c5f..85e9de3d0 100644 --- a/libsrc/common/gmtime.c +++ b/libsrc/common/gmtime.c @@ -45,19 +45,29 @@ struct tm* __fastcall__ gmtime (const time_t* timep) { + static struct tm timebuf; time_t t; - /* Check for a valid time spec */ - if (timep == 0) { + /* Check the argument */ + if (timep == 0 || (long) (t = *timep) < 0) { + /* Invalid arg */ return 0; } - /* Get the time and correct for the time zone offset */ - t = *timep + _tz.timezone; + /* 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 */ - /* Use localtime for conversion */ - return localtime (&t); + /* Call mktime to do the final conversion */ + mktime (&timebuf); + + /* Return the result */ + return &timebuf; } - - - diff --git a/libsrc/common/localtime.c b/libsrc/common/localtime.c index cc6298f8c..48931ea62 100644 --- a/libsrc/common/localtime.c +++ b/libsrc/common/localtime.c @@ -45,31 +45,16 @@ struct tm* __fastcall__ localtime (const time_t* timep) { - static struct tm timebuf; time_t t; - /* Check the argument */ - if (timep == 0 || (long) (t = *timep) < 0) { - /* Invalid arg */ + /* Check for a valid time spec */ + if (timep == 0) { 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. - */ - 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 */ + /* Get the time and correct for the time zone offset */ + t = *timep + _tz.timezone; - /* Call mktime to do the final conversion */ - mktime (&timebuf); - - /* Return the result */ - return &timebuf; + /* Use gmtime for conversion */ + return gmtime (&t); } - - diff --git a/libsrc/common/mktime.c b/libsrc/common/mktime.c index 423727751..275589dbb 100644 --- a/libsrc/common/mktime.c +++ b/libsrc/common/mktime.c @@ -180,7 +180,8 @@ time_t __fastcall__ mktime (register struct tm* TM) return DayCount * 86400UL + ((unsigned) TM->tm_hour) * 3600UL + ((unsigned) TM->tm_min) * 60U + - ((unsigned) TM->tm_sec); + ((unsigned) TM->tm_sec) - + _tz.timezone; Error: /* Error exit */ From 5cdaa96e4c65854b30fa837d0cc52f4644aeae0a Mon Sep 17 00:00:00 2001 From: Patrick Pelletier <code@funwithsoftware.org> Date: Fri, 10 Aug 2018 12:58:48 -0700 Subject: [PATCH 0782/2161] sim65: Fix "$2C: BIT abs" to access the correct address. Bug is documented here: http://forum.6502.org/viewtopic.php?f=2&t=5242 --- 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 0d0adbf8b..bfbfbd78c 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -739,7 +739,7 @@ static void OPC_6502_2C (void) unsigned Addr; unsigned char Val; Cycles = 4; - Addr = MemReadByte (Regs.PC+1); + Addr = MemReadWord (Regs.PC+1); Val = MemReadByte (Addr); SET_SF (Val & 0x80); SET_OF (Val & 0x40); From e6e9c72f66685cd1cdbec9a968c20baf936a1455 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Tue, 14 Aug 2018 21:09:03 +0300 Subject: [PATCH 0783/2161] Added CHKOUT and CLRCHN --- asminc/cbm_kernal.inc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asminc/cbm_kernal.inc b/asminc/cbm_kernal.inc index 52c1c16ad..4e2e927e4 100644 --- a/asminc/cbm_kernal.inc +++ b/asminc/cbm_kernal.inc @@ -56,7 +56,9 @@ ; Available on all platforms including PET CHKIN := $FFC6 CKOUT := $FFC9 +CHKOUT := $FFC9 CLRCH := $FFCC +CLRCHN := $FFCC BASIN := $FFCF CHRIN := $FFCF BSOUT := $FFD2 From bbed9fdb63de808a4b2cb63babd28e6feb18cd12 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 14 Aug 2018 15:54:57 +0200 Subject: [PATCH 0784/2161] Fixed typo. --- libsrc/cbm510/banking.s | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libsrc/cbm510/banking.s b/libsrc/cbm510/banking.s index 8ed72d02b..b9dce2b6f 100644 --- a/libsrc/cbm510/banking.s +++ b/libsrc/cbm510/banking.s @@ -1,7 +1,7 @@ ; ; Ullrich von Bassewitz, 28.09.1998 ; -; Banking routines for the 610. +; Banking routines for the 510. ; .export set_bank, sys_bank, restore_bank @@ -37,5 +37,3 @@ pla rts .endproc - - From 55a07c1dcde6920b36688263aa3eddfbb7a0ebdd Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 14 Aug 2018 16:00:09 +0200 Subject: [PATCH 0785/2161] Removed stray /t char. --- libsrc/cbm510/waitvsync.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/cbm510/waitvsync.s b/libsrc/cbm510/waitvsync.s index ed7300f7c..0bb765e4a 100644 --- a/libsrc/cbm510/waitvsync.s +++ b/libsrc/cbm510/waitvsync.s @@ -25,4 +25,4 @@ _waitvsync: bmi @l2 cli - jmp restore_bank + jmp restore_bank From 842c151edd04385901220c5506ecf8c7f9060c26 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 15 Aug 2018 15:59:11 +0200 Subject: [PATCH 0786/2161] Replaced _systime with clock_gettime. We want to add the capability to not only get the time but also set the time, but there's no "setter" for the "getter" time(). The first ones that come into mind are gettimeofday() and settimeofday(). However, they take a struct timezone argument that doesn't make sense - even the man pages says "The use of the timezone structure is obsolete; the tz argument should normally be specified as NULL." And POSIX says "Applications should use the clock_gettime() function instead of the obsolescent gettimeofday() function." The ...timeofday() functions work with microseconds while the clock_...time() functions work with nanoseconds. Given that we expect our targets to support only 1/10 of seconds the microseconds look preferable at first sight. However, already microseconds require the cc65 data type 'long' so it's not such a relevant difference to nanoseconds. Additionally clock_getres() seems useful. In order to avoid code duplication clock_gettime() takes over the role of the actual time getter from _systime(). So time() now calls clock_gettime() instead of _systime(). For some reason beyond my understanding _systime() was mentioned in time.h. _systime() worked exactly like e.g. _sysremove() and those _sys...() functions are all considered internal. The only reason I could see would be a performance gain of bypassing the time() wrapper. However, all known _systime() implementations internally called mktime(). And mktime() is implemented in C using an iterative algorithm so I really can't see what would be left to gain here. From that perspective I decided to just remove _systime(). --- asminc/time.inc | 13 ++- doc/funcref.sgml | 2 +- include/time.h | 24 +++-- libsrc/apple2/gettime.s | 92 +++++++++++++++++++ libsrc/apple2/systime.s | 63 ------------- libsrc/atari/systime.s | 28 ------ libsrc/atmos/systime.s | 28 ------ libsrc/c128/{systime.s => gettime.s} | 51 +++++++--- libsrc/c16/systime.s | 28 ------ libsrc/c64/{systime.s => gettime.s} | 51 +++++++--- libsrc/cbm510/{systime.s => gettime.s} | 55 ++++++----- libsrc/cbm610/{systime.s => gettime.s} | 54 ++++++----- libsrc/common/time.s | 37 ++++++-- .../system/{systime.c => gettime.c} | 11 ++- libsrc/plus4/systime.s | 28 ------ 15 files changed, 295 insertions(+), 270 deletions(-) create mode 100644 libsrc/apple2/gettime.s delete mode 100644 libsrc/apple2/systime.s delete mode 100644 libsrc/atari/systime.s delete mode 100644 libsrc/atmos/systime.s rename libsrc/c128/{systime.s => gettime.s} (66%) delete mode 100644 libsrc/c16/systime.s rename libsrc/c64/{systime.s => gettime.s} (66%) rename libsrc/cbm510/{systime.s => gettime.s} (66%) rename libsrc/cbm610/{systime.s => gettime.s} (66%) rename libsrc/geos-common/system/{systime.c => gettime.c} (81%) delete mode 100644 libsrc/plus4/systime.s diff --git a/asminc/time.inc b/asminc/time.inc index 16858471d..5783232c7 100644 --- a/asminc/time.inc +++ b/asminc/time.inc @@ -49,10 +49,21 @@ .endstruct +;------------------------------------------------------------------------------ +; Struct timespec - must match the struct defined in time.h + +.struct timespec + tv_sec .dword + tv_nsec .dword +.endstruct + + ;------------------------------------------------------------------------------ ; Exported functions -.global __systime +.global _clock_getres +.global _clock_gettime +.global _clock_settime .global _mktime diff --git a/doc/funcref.sgml b/doc/funcref.sgml index edb510e37..247689b8a 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -7375,7 +7375,7 @@ be used in presence of a prototype. <tag/Description/The function returns the time since the 1970-01-01 00:00:00 measured in seconds. If the pointer <tt/t/ is not <tt/NULL/, the function result will also be stored there. If no time is available, <tt/(time_t)-1/ is -returned and <tt/errno/ is set to <tt/ENOSYS/. +returned and an error code is stored in <tt/errno/. <tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. diff --git a/include/time.h b/include/time.h index 22e24a56e..4ee658da9 100644 --- a/include/time.h +++ b/include/time.h @@ -52,9 +52,10 @@ typedef unsigned size_t; typedef unsigned long time_t; typedef unsigned long clock_t; +typedef unsigned char clockid_t; /* Structure for broken down time */ -struct tm { +struct tm { int tm_sec; int tm_min; int tm_hour; @@ -66,6 +67,12 @@ struct tm { int tm_isdst; }; +/* Structure for seconds and nanoseconds */ +struct timespec { + time_t tv_sec; + long tv_nsec; +}; + /* Timezone representation, default is UTC */ extern struct _timezone { char daylight; /* True if daylight savings time active */ @@ -116,16 +123,10 @@ extern clock_t _clk_tck (void); # define CLK_TCK _clk_tck() # define CLOCKS_PER_SEC _clk_tck() #endif +#define CLOCK_REALTIME 0 -time_t _systime (void); -/* Similar to time(), but: -** - Is not ISO C -** - Does not take the additional pointer -** - Does not set errno when returning -1 -*/ - /* ISO C function prototypes */ char* __fastcall__ asctime (const struct tm* timep); clock_t clock (void); @@ -138,6 +139,13 @@ time_t __fastcall__ time (time_t* t); +/* POSIX function prototypes */ +int __fastcall__ clock_getres (clockid_t clock_id, struct timespec *res); +int __fastcall__ clock_gettime (clockid_t clock_id, struct timespec *tp); +int __fastcall__ clock_settime (clockid_t clock_id, const struct timespec *tp); + + + /* End of time.h */ #endif diff --git a/libsrc/apple2/gettime.s b/libsrc/apple2/gettime.s new file mode 100644 index 000000000..6bb541548 --- /dev/null +++ b/libsrc/apple2/gettime.s @@ -0,0 +1,92 @@ +; +; Oliver Schmidt, 14.08.2018 +; +; int clock_gettime (clockid_t clk_id, struct timespec *tp); +; + + .import pushax, steaxspidx, incsp1, incsp3, return0 + + .include "time.inc" + .include "zeropage.inc" + .include "errno.inc" + .include "mli.inc" + +_clock_gettime: + jsr pushax + + ; Clear tv_nsec (+ tv_sec) + sta ptr1 + stx ptr1+1 + lda #$00 + ldy #.sizeof(timespec)-1 +: sta (ptr1),y + dey + bpl :- + + ; Update date + time + lda #GET_TIME_CALL + ldx #GET_TIME_COUNT + 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 + + ; Get time + lda TIMELO+1 + sta TM + tm::tm_hour + lda TIMELO + sta TM + tm::tm_min + + ; Make time_t + lda #<TM + ldx #>TM + jsr _mktime + + ; Store tv_sec + ldy #timespec::tv_sec + jsr steaxspidx + + ; Return success + jsr incsp1 + 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/systime.s b/libsrc/apple2/systime.s deleted file mode 100644 index 9bf4fe904..000000000 --- a/libsrc/apple2/systime.s +++ /dev/null @@ -1,63 +0,0 @@ -; -; Oliver Schmidt, 22.08.2006 -; -; time_t _systime (void); -; /* Similar to time(), but: -; ** - Is not ISO C -; ** - Does not take the additional pointer -; ** - Does not set errno when returning -1 -; */ -; - - .include "time.inc" - .include "zeropage.inc" - .include "mli.inc" - -__systime: - ; Update time - lda #GET_TIME_CALL - ldx #GET_TIME_COUNT - jsr callmli - bcs err - - 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 err ; [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 - - lda TIMELO+1 - sta TM + tm::tm_hour - lda TIMELO - sta TM + tm::tm_min - - lda #<TM - ldx #>TM - jmp _mktime - -err: lda #$FF - tax - sta sreg - sta sreg+1 - rts ; Return -1 - - .bss - -TM: .tag tm diff --git a/libsrc/atari/systime.s b/libsrc/atari/systime.s deleted file mode 100644 index 273e394a4..000000000 --- a/libsrc/atari/systime.s +++ /dev/null @@ -1,28 +0,0 @@ -; -; Ullrich von Bassewitz, 12.11.2002 -; -; time_t _systime (void); -; /* Similar to time(), but: -; ** - Is not ISO C -; ** - Does not take the additional pointer -; ** - Does not set errno when returning -1 -; */ -; - - .export __systime - - .importzp sreg - -.code - -.proc __systime - - lda #$FF - tax - sta sreg - sta sreg+1 - rts ; Return -1 - -.endproc - - diff --git a/libsrc/atmos/systime.s b/libsrc/atmos/systime.s deleted file mode 100644 index 273e394a4..000000000 --- a/libsrc/atmos/systime.s +++ /dev/null @@ -1,28 +0,0 @@ -; -; Ullrich von Bassewitz, 12.11.2002 -; -; time_t _systime (void); -; /* Similar to time(), but: -; ** - Is not ISO C -; ** - Does not take the additional pointer -; ** - Does not set errno when returning -1 -; */ -; - - .export __systime - - .importzp sreg - -.code - -.proc __systime - - lda #$FF - tax - sta sreg - sta sreg+1 - rts ; Return -1 - -.endproc - - diff --git a/libsrc/c128/systime.s b/libsrc/c128/gettime.s similarity index 66% rename from libsrc/c128/systime.s rename to libsrc/c128/gettime.s index b2a7f8721..b59789117 100644 --- a/libsrc/c128/systime.s +++ b/libsrc/c128/gettime.s @@ -1,27 +1,27 @@ ; ; Stefan Haubenthal, 27.7.2009 +; Oliver Schmidt, 14.8.2018 ; -; time_t _systime (void); -; /* Similar to time(), but: -; ** - Is not ISO C -; ** - Does not take the additional pointer -; ** - Does not set errno when returning -1 -; */ +; int clock_gettime (clockid_t clk_id, struct timespec *tp); ; .include "time.inc" .include "c128.inc" .include "get_tv.inc" - .constructor initsystime - .importzp tmp1, tmp2 + .constructor inittime + .importzp sreg, tmp1, tmp2 + .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1, return0 .import _get_tv ;---------------------------------------------------------------------------- .code -.proc __systime +.proc _clock_gettime + + jsr pushax + jsr pushax lda CIA1_TODHR bpl AM @@ -38,13 +38,38 @@ AM: jsr BCD2dec lda CIA1_TODSEC jsr BCD2dec sta TM + tm::tm_sec - lda CIA1_TOD10 ; Dummy read to unfreeze lda #<TM ldx #>TM - jmp _mktime + jsr _mktime + ldy #timespec::tv_sec + jsr steaxspidx ; Pops address pushed by 2. pushax + + lda #<(100 * 1000 * 1000 / $10000) + ldx #>(100 * 1000 * 1000 / $10000) + sta sreg + stx sreg+1 + lda #<(100 * 1000 * 1000) + ldx #>(100 * 1000 * 1000) + 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)) -BCD2dec:tax + +.proc BCD2dec + + tax and #%00001111 sta tmp1 txa @@ -65,7 +90,7 @@ BCD2dec:tax ; and write it again, ignoring a possible change in between. .segment "ONCE" -.proc initsystime +.proc inittime lda CIA1_TOD10 sta CIA1_TOD10 diff --git a/libsrc/c16/systime.s b/libsrc/c16/systime.s deleted file mode 100644 index 273e394a4..000000000 --- a/libsrc/c16/systime.s +++ /dev/null @@ -1,28 +0,0 @@ -; -; Ullrich von Bassewitz, 12.11.2002 -; -; time_t _systime (void); -; /* Similar to time(), but: -; ** - Is not ISO C -; ** - Does not take the additional pointer -; ** - Does not set errno when returning -1 -; */ -; - - .export __systime - - .importzp sreg - -.code - -.proc __systime - - lda #$FF - tax - sta sreg - sta sreg+1 - rts ; Return -1 - -.endproc - - diff --git a/libsrc/c64/systime.s b/libsrc/c64/gettime.s similarity index 66% rename from libsrc/c64/systime.s rename to libsrc/c64/gettime.s index c28ace32e..61c5115ae 100644 --- a/libsrc/c64/systime.s +++ b/libsrc/c64/gettime.s @@ -1,27 +1,27 @@ ; ; Stefan Haubenthal, 27.7.2009 +; Oliver Schmidt, 14.8.2018 ; -; time_t _systime (void); -; /* Similar to time(), but: -; ** - Is not ISO C -; ** - Does not take the additional pointer -; ** - Does not set errno when returning -1 -; */ +; int clock_gettime (clockid_t clk_id, struct timespec *tp); ; .include "time.inc" .include "c64.inc" .include "get_tv.inc" - .constructor initsystime - .importzp tmp1, tmp2 + .constructor inittime + .importzp sreg, tmp1, tmp2 + .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1, return0 .import _get_tv, _get_ostype ;---------------------------------------------------------------------------- .code -.proc __systime +.proc _clock_gettime + + jsr pushax + jsr pushax lda CIA1_TODHR bpl AM @@ -38,13 +38,38 @@ AM: jsr BCD2dec lda CIA1_TODSEC jsr BCD2dec sta TM + tm::tm_sec - lda CIA1_TOD10 ; Dummy read to unfreeze lda #<TM ldx #>TM - jmp _mktime + jsr _mktime + ldy #timespec::tv_sec + jsr steaxspidx ; Pops address pushed by 2. pushax + + lda #<(100 * 1000 * 1000 / $10000) + ldx #>(100 * 1000 * 1000 / $10000) + sta sreg + stx sreg+1 + lda #<(100 * 1000 * 1000) + ldx #>(100 * 1000 * 1000) + 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)) -BCD2dec:tax + +.proc BCD2dec + + tax and #%00001111 sta tmp1 txa @@ -65,7 +90,7 @@ BCD2dec:tax ; and write it again, ignoring a possible change in between. .segment "ONCE" -.proc initsystime +.proc inittime lda CIA1_TOD10 sta CIA1_TOD10 diff --git a/libsrc/cbm510/systime.s b/libsrc/cbm510/gettime.s similarity index 66% rename from libsrc/cbm510/systime.s rename to libsrc/cbm510/gettime.s index daac36d8d..3ad162e3b 100644 --- a/libsrc/cbm510/systime.s +++ b/libsrc/cbm510/gettime.s @@ -1,33 +1,28 @@ ; ; Stefan Haubenthal, 2009-07-27 ; Ullrich von Bassewitz, 2009-09-24 +; Oliver Schmidt, 2018-08-14 ; -; time_t _systime (void); -; /* Similar to time(), but: -; ** - Is not ISO C -; ** - Does not take the additional pointer -; ** - Does not set errno when returning -1 -; */ +; int clock_gettime (clockid_t clk_id, struct timespec *tp); ; .include "time.inc" .include "cbm510.inc" .include "extzp.inc" + .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1 .import sys_bank, restore_bank - .importzp tmp1, tmp2 + .importzp sreg, tmp1, tmp2 ;---------------------------------------------------------------------------- .code -.proc __systime - -; Switch to the system bank +.proc _clock_gettime jsr sys_bank - -; Read the clock + jsr pushax + jsr pushax ldy #CIA::TODHR lda (cia2),y @@ -47,18 +42,33 @@ AM: jsr BCD2dec lda (cia2),y jsr BCD2dec sta TM + tm::tm_sec - ldy #CIA::TOD10 - lda (cia2),y ; Dummy read to unfreeze - -; Restore the bank - - jsr restore_bank - -; Convert to a time - lda #<TM ldx #>TM - jmp _mktime + jsr _mktime + + ldy #timespec::tv_sec + jsr steaxspidx ; Pops address pushed by 2. pushax + + lda #<(100 * 1000 * 1000 / $10000) + ldx #>(100 * 1000 * 1000 / $10000) + sta sreg + stx sreg+1 + lda #<(100 * 1000 * 1000) + ldx #>(100 * 1000 * 1000) + jsr pusheax + ldy #CIA::TOD10 + lda (cia2),y + ldx #>$0000 + jsr tosmul0ax + + ldy #timespec::tv_nsec + jsr steaxspidx ; Pops address pushed by 1. pushax + + jsr incsp1 + + lda #0 + tax + jmp restore_bank .endproc @@ -95,4 +105,3 @@ TM: .word 0 ; tm_sec .word 0 ; tm_wday .word 0 ; tm_yday .word 0 ; tm_isdst - diff --git a/libsrc/cbm610/systime.s b/libsrc/cbm610/gettime.s similarity index 66% rename from libsrc/cbm610/systime.s rename to libsrc/cbm610/gettime.s index be2bedf6f..30226213d 100644 --- a/libsrc/cbm610/systime.s +++ b/libsrc/cbm610/gettime.s @@ -1,33 +1,28 @@ ; ; Stefan Haubenthal, 2009-07-27 ; Ullrich von Bassewitz, 2009-09-24 +; Oliver Schmidt, 2018-08-14 ; -; time_t _systime (void); -; /* Similar to time(), but: -; ** - Is not ISO C -; ** - Does not take the additional pointer -; ** - Does not set errno when returning -1 -; */ +; int clock_gettime (clockid_t clk_id, struct timespec *tp); ; .include "time.inc" .include "cbm610.inc" .include "extzp.inc" + .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1 .import sys_bank, restore_bank - .importzp tmp1, tmp2 + .importzp sreg, tmp1, tmp2 ;---------------------------------------------------------------------------- .code -.proc __systime - -; Switch to the system bank +.proc _clock_gettime jsr sys_bank - -; Read the clock + jsr pushax + jsr pushax ldy #CIA::TODHR lda (cia),y @@ -47,18 +42,33 @@ AM: jsr BCD2dec lda (cia),y jsr BCD2dec sta TM + tm::tm_sec - ldy #CIA::TOD10 - lda (cia),y ; Dummy read to unfreeze - -; Restore the bank - - jsr restore_bank - -; Convert to a time - lda #<TM ldx #>TM - jmp _mktime + jsr _mktime + + ldy #timespec::tv_sec + jsr steaxspidx ; Pops address pushed by 2. pushax + + lda #<(100 * 1000 * 1000 / $10000) + ldx #>(100 * 1000 * 1000 / $10000) + sta sreg + stx sreg+1 + lda #<(100 * 1000 * 1000) + ldx #>(100 * 1000 * 1000) + jsr pusheax + ldy #CIA::TOD10 + lda (cia),y + ldx #>$0000 + jsr tosmul0ax + + ldy #timespec::tv_nsec + jsr steaxspidx ; Pops address pushed by 1. pushax + + jsr incsp1 + + lda #0 + tax + jmp restore_bank .endproc diff --git a/libsrc/common/time.s b/libsrc/common/time.s index 140d47e2c..9b297d4d3 100644 --- a/libsrc/common/time.s +++ b/libsrc/common/time.s @@ -6,10 +6,10 @@ .export _time - .import __systime - .importzp ptr1, sreg, tmp1 + .import decsp1 + .importzp ptr1, sreg, tmp1, tmp2 - .include "errno.inc" + .include "time.inc" .code @@ -20,8 +20,19 @@ txa pha ; Save timep - jsr __systime ; Get the time (machine dependent) +; Get the time (machine dependent) + jsr decsp1 + lda #<time + ldx #>time + jsr _clock_gettime + sta tmp2 + lda time + timespec::tv_sec+2 + ldx time + timespec::tv_sec+3 + sta sreg + stx sreg+1 + lda time + timespec::tv_sec + ldx time + timespec::tv_sec+1 sta tmp1 ; Save low byte of result ; Restore timep and check if it is NULL @@ -48,13 +59,15 @@ lda tmp1 sta (ptr1),y -; If the result is less than zero, set ERRNO +; If the result is != 0, return -1 -@L1: ldy sreg+1 - bpl @L2 - - lda #ENOSYS ; Function not implemented - jsr __seterrno ; Set __errno +@L1: lda tmp2 + beq @L2 + + tax + sta sreg + sta sreg+1 + rts ; Reload the low byte of the result and return @@ -63,4 +76,8 @@ .endproc +; ------------------------------------------------------------------------ +; Data +.bss +time: .tag timespec diff --git a/libsrc/geos-common/system/systime.c b/libsrc/geos-common/system/gettime.c similarity index 81% rename from libsrc/geos-common/system/systime.c rename to libsrc/geos-common/system/gettime.c index 5eb87fef8..d695787c3 100644 --- a/libsrc/geos-common/system/systime.c +++ b/libsrc/geos-common/system/gettime.c @@ -1,5 +1,5 @@ /* -** systime.c +** gettime.c ** ** Maciej 'YTM/Elysium' Witkowiak, 22.11.2002 */ @@ -7,7 +7,7 @@ #include <time.h> #include <geos.h> -time_t _systime(void) +clock_t clock(void) { struct tm currentTime; @@ -25,7 +25,10 @@ time_t _systime(void) return mktime(¤tTime); } -clock_t clock(void) +int clock_gettime(clockid_t, struct timespec *tp) { - return _systime(); + tp->tv_sec = clock(); + tp->tv_nsec = 0; + + return 0; } diff --git a/libsrc/plus4/systime.s b/libsrc/plus4/systime.s deleted file mode 100644 index 273e394a4..000000000 --- a/libsrc/plus4/systime.s +++ /dev/null @@ -1,28 +0,0 @@ -; -; Ullrich von Bassewitz, 12.11.2002 -; -; time_t _systime (void); -; /* Similar to time(), but: -; ** - Is not ISO C -; ** - Does not take the additional pointer -; ** - Does not set errno when returning -1 -; */ -; - - .export __systime - - .importzp sreg - -.code - -.proc __systime - - lda #$FF - tax - sta sreg - sta sreg+1 - rts ; Return -1 - -.endproc - - From 59a81495569826337bfa7c7de162412399147070 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 15 Aug 2018 19:40:27 +0200 Subject: [PATCH 0787/2161] Added clock_getres() for CBMs. All CBMs have a clock (CIA TOD) resolution of 1/10 second. --- libsrc/cbm/getres.s | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 libsrc/cbm/getres.s diff --git a/libsrc/cbm/getres.s b/libsrc/cbm/getres.s new file mode 100644 index 000000000..d216a1b6a --- /dev/null +++ b/libsrc/cbm/getres.s @@ -0,0 +1,37 @@ +; +; Oliver Schmidt, 15.8.2018 +; +; int clock_getres (clockid_t clk_id, struct timespec *res); +; + + .include "time.inc" + + .importzp ptr1 + .import incsp1, return0 + + +;---------------------------------------------------------------------------- +.code + +.proc _clock_getres + + sta ptr1 + stx ptr1+1 + + ldy #.sizeof(timespec)-1 +@L1: lda time,y + sta (ptr1),y + dey + bpl @L1 + + jsr incsp1 + jmp return0 + +.endproc + +;---------------------------------------------------------------------------- +; timespec struct with tv_nsec set to 1/10 second +.rodata + +time: .dword 0 + .dword 100 * 1000 * 1000 From 326ca263c9e09266aaa278ad33808eb15112c7e6 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 15 Aug 2018 19:40:56 +0200 Subject: [PATCH 0788/2161] Minor style fix. --- libsrc/apple2/gettime.s | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libsrc/apple2/gettime.s b/libsrc/apple2/gettime.s index 6bb541548..a11032af5 100644 --- a/libsrc/apple2/gettime.s +++ b/libsrc/apple2/gettime.s @@ -68,8 +68,10 @@ _clock_gettime: ldy #timespec::tv_sec jsr steaxspidx - ; Return success + ; Cleanup stack jsr incsp1 + + ; Return success jmp return0 ; Load errno code From f40dcb5883fd1c94c982fd7e56a7828799ded5d2 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 15 Aug 2018 21:34:35 +0200 Subject: [PATCH 0789/2161] Added clock_getres() / clock_settime() for the Apple II. The situation on the Apple II is rather special: There are several types of RTCs. It's not desirable to have specific code for all of them. As the OS supports file timestamps RTC owners usually use OS drivers for their RTC. Those drivers read the RTC and write the result in a "date/time location" in RAM. The OS reads the date/time from the RAM location. If there's no RTC the RAM location keeps containing zeros. The OS uses those zeros as timestamps and the files show up in a directory as "<NO DATE>". There's no common interface to set RTCs so if an RTC _IS_ present there's just nothing to do. However, if there's _NO_ RTC present the user might very well be interest to "manually" set the RAM location in order to have timestamps. But he surely doesn't want to manually set the RAM location over an over again. Rather he wants to set it just once after booting the OS. From that perspective it makes most sense to not set both the date and the time but rather only set the date and have the time just stay zero. Then files show up in a directory as "DD-MON-YY 0:00". So clock_settime() checks if the current time equals 0:00. If it does _NOT_ then an RTC is supposed to be active and clock_settime() fails with ERANGE. Otherwise clock_settime() ignores sets the date - and completely ignores the time provided as parameter. clock_getres() too checks if the current time equals 0:00. If it does _NOT_ then an RTC is supposed to be active and clock_getres() returns a time resolution of one minute. Otherwise clock_getres() presumes that the only one who sets the RAM location is clock_settime() and therefore returns a time resolution of one day. --- asminc/time.inc | 4 +-- libsrc/apple2/getres.s | 63 +++++++++++++++++++++++++++++++++++++ libsrc/apple2/settime.s | 70 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 libsrc/apple2/getres.s create mode 100644 libsrc/apple2/settime.s diff --git a/asminc/time.inc b/asminc/time.inc index 5783232c7..6064b4ba3 100644 --- a/asminc/time.inc +++ b/asminc/time.inc @@ -64,7 +64,5 @@ .global _clock_getres .global _clock_gettime .global _clock_settime +.global _localtime .global _mktime - - - diff --git a/libsrc/apple2/getres.s b/libsrc/apple2/getres.s new file mode 100644 index 000000000..777a5df3f --- /dev/null +++ b/libsrc/apple2/getres.s @@ -0,0 +1,63 @@ +; +; Oliver Schmidt, 15.08.2018 +; +; int clock_getres (clockid_t clk_id, struct timespec *res); +; + + .import __dos_type + .import incsp1, return0 + + .include "time.inc" + .include "zeropage.inc" + .include "errno.inc" + .include "mli.inc" + +_clock_getres: + sta ptr1 + stx ptr1+1 + + ; Cleanup stack + jsr incsp1 + + ; Check for ProDOS 8 + lda __dos_type + beq enosys + + ; Presume day resolution + ldx #<day_res + ldy #>day_res + + ; Check for existing minutes or hours + lda TIMELO + ora TIMELO+1 + beq :+ + + ; Switch to minute resolution + ldx #<min_res + ldy #>min_res + + ; Copy timespec +: stx ptr2 + sty ptr2+1 + ldy #.sizeof(timespec)-1 +: lda (ptr2),y + sta (ptr1),y + dey + bpl :- + + ; Return success + jmp return0 + + ; Load errno code +enosys: lda #ENOSYS + + ; Set __errno + jmp __directerrno + + .rodata + +min_res:.dword 60 + .dword 0 + +day_res:.dword 60 * 60 * 24 + .dword 0 diff --git a/libsrc/apple2/settime.s b/libsrc/apple2/settime.s new file mode 100644 index 000000000..a71e113c5 --- /dev/null +++ b/libsrc/apple2/settime.s @@ -0,0 +1,70 @@ +; +; Oliver Schmidt, 15.08.2018 +; +; int clock_settime (clockid_t clk_id, const struct timespec *tp); +; + + .import __dos_type + .import incsp1, return0 + + .include "time.inc" + .include "zeropage.inc" + .include "errno.inc" + .include "mli.inc" + +_clock_settime: + + ; Cleanup stack + jsr incsp1 ; Preserves A + + ; Check for ProDOS 8 + ldy __dos_type + beq enosys + + ; Check for existing minutes or hours + tay ; Save A + lda TIMELO + ora TIMELO+1 + bne erange + tya ; Restore A + + ; Get tm + jsr _localtime + sta ptr1 + stx ptr1+1 + + ; Set date + ldy #tm::tm_mon + lda (ptr1),y + clc + adc #$01 ; Move [0..11] to [1..12] + asl + asl + asl + asl + asl + php ; Save month msb + ldy #tm::tm_mday + ora (ptr1),y + sta DATELO + ldy #tm::tm_year + lda (ptr1),y + cmp #100 ; Year since 1900 < 100? + bcc :+ ; Yes, leave alone + sbc #100 ; Move 20xx to 19xx +: plp ; Restore month msb + rol + sta DATELO+1 + + ; Return success + jmp return0 + + ; Load errno code +enosys: lda #ENOSYS + bne errno ; Always + + ; Load errno code +erange: lda #ERANGE + + ; Set __errno +errno: jmp __directerrno From d13d068e71fb7cc08734e2c17e67e83f48d28d77 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 16 Aug 2018 23:51:04 -0400 Subject: [PATCH 0790/2161] Fixed the generation of the opcode byte when BRK is given an operand, in 65816 CPU mode. The bug was created by commit 7e8bb7b700572a50ed4f1e87ebeea4fd35177459. --- 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 eb005289c..912e45867 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -650,7 +650,7 @@ static const struct { { "BNE", 0x0020000, 0xd0, 0, PutPCRel8 }, { "BPL", 0x0020000, 0x10, 0, PutPCRel8 }, { "BRA", 0x0020000, 0x80, 0, PutPCRel8 }, - { "BRK", 0x0000005, 0x00, 0, PutAll }, + { "BRK", 0x0000005, 0x00, 6, PutAll }, { "BRL", 0x0040000, 0x82, 0, PutPCRel16 }, { "BVC", 0x0020000, 0x50, 0, PutPCRel8 }, { "BVS", 0x0020000, 0x70, 0, PutPCRel8 }, From d602572bbec53fe9ca906029d7bac436f65d915f Mon Sep 17 00:00:00 2001 From: Patrick Pelletier <code@funwithsoftware.org> Date: Thu, 16 Aug 2018 23:39:31 -0700 Subject: [PATCH 0791/2161] Fix permissions for files created by sim65. Files created by my programs running under sim65 had really weird permissions: --w-r--r-x 1 ppelleti staff 19 Aug 16 23:22 json.test.print.tmp So, for example, my program running under sim65 was not able to read the file it had just written. This is because the third argument to open (mode) was not being specified in paravirt.c, so it was just picking up random crud off the stack to use as the mode. I added a mode of 0666, and now my program runs correctly. --- src/sim65/paravirt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index a13c670a2..f210efd57 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -209,7 +209,7 @@ static void PVOpen (CPURegs* Regs) /* Avoid gcc warning */ (void) Mode; - RetVal = open (Path, OFlag); + RetVal = open (Path, OFlag, (mode_t) 0666); SetAX (Regs, RetVal); } From aba320eadea576037fc2130a208b68d0c56c21e7 Mon Sep 17 00:00:00 2001 From: Patrick Pelletier <code@funwithsoftware.org> Date: Fri, 17 Aug 2018 10:43:14 -0700 Subject: [PATCH 0792/2161] Allow "mode" argument to open() to be passed from 6502 code. Implements this suggestion: https://github.com/cc65/cc65/pull/719#issuecomment-413809096 --- asminc/stat.inc | 3 ++ include/sys/stat.h | 65 ++++++++++++++++++++++++++++++++++++++++++ libsrc/common/_fopen.s | 6 +++- src/sim65/paravirt.c | 12 +++++--- 4 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 asminc/stat.inc create mode 100644 include/sys/stat.h diff --git a/asminc/stat.inc b/asminc/stat.inc new file mode 100644 index 000000000..d9c74aeaa --- /dev/null +++ b/asminc/stat.inc @@ -0,0 +1,3 @@ +; File mode constants, must match the values in the C headers +S_IREAD = $0100 ; octal 0400 +S_IWRITE = $0080 ; octal 0200 diff --git a/include/sys/stat.h b/include/sys/stat.h new file mode 100644 index 000000000..e49c370f9 --- /dev/null +++ b/include/sys/stat.h @@ -0,0 +1,65 @@ +/*****************************************************************************/ +/* */ +/* stat.h */ +/* */ +/* Constants for the mode argument of open */ +/* */ +/* */ +/* */ +/* (C) 2003 Ullrich von Bassewitz */ +/* Römerstrasse 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 _STAT_H +#define _STAT_H + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* These are the values for the traditional UNIX mode bits: +** https://en.wikipedia.org/wiki/File_system_permissions#Numeric_notation +** (S_IREAD and S_IWRITE are aliases for S_IRUSR and S_IWUSR) +** +** Must match the values in asminc/stat.inc and src/sim65/paravirt.c +*/ + +#define S_IREAD 0400 +#define S_IWRITE 0200 + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +/* End of stat.h */ +#endif diff --git a/libsrc/common/_fopen.s b/libsrc/common/_fopen.s index 29f1c4cd9..0154858dd 100644 --- a/libsrc/common/_fopen.s +++ b/libsrc/common/_fopen.s @@ -15,6 +15,7 @@ .include "errno.inc" .include "fcntl.inc" .include "_file.inc" + .include "stat.inc" ; ------------------------------------------------------------------------ @@ -82,7 +83,10 @@ modeok: ldy #$00 tya iny sta (sp),y - ldy #4 ; Size of arguments in bytes + lda #<(S_IREAD|S_IWRITE) + ldx #>(S_IREAD|S_IWRITE) + jsr pushax ; Push the "mode" argument onto the stack + ldy #6 ; Size of arguments in bytes jsr _open ; Will cleanup the stack ; Check the result of the open() call diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index f210efd57..0c634dc0d 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -169,7 +169,7 @@ static void PVOpen (CPURegs* Regs) { char Path[1024]; int OFlag = O_INITIAL; - unsigned RetVal, I = 0; + unsigned RetVal, I = 0, OMode = 0; unsigned Mode = PopParam (Regs->YR - 4); unsigned Flags = PopParam (2); @@ -206,10 +206,14 @@ static void PVOpen (CPURegs* Regs) OFlag |= O_EXCL; } - /* Avoid gcc warning */ - (void) Mode; + if (Mode & 0400) { + OMode |= S_IREAD; + } + if (Mode & 0200) { + OMode |= S_IWRITE; + } - RetVal = open (Path, OFlag, (mode_t) 0666); + RetVal = open (Path, OFlag, OMode); SetAX (Regs, RetVal); } From 974188796c3f8a8817f1d2ef9623beb894accc2b Mon Sep 17 00:00:00 2001 From: Patrick Pelletier <code@funwithsoftware.org> Date: Fri, 17 Aug 2018 10:50:16 -0700 Subject: [PATCH 0793/2161] sim65: If mode argument is omitted, use a reasonable default. --- src/sim65/paravirt.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 0c634dc0d..fda2839af 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -175,6 +175,13 @@ static void PVOpen (CPURegs* Regs) unsigned Flags = PopParam (2); unsigned Name = PopParam (2); + if (Regs->YR - 4 < 2) { + /* If the caller did not supply the mode argument, + ** use a reasonable default. + */ + Mode = 0400 | 0200; + } + do { Path[I] = MemReadByte (Name++); } From 12fbdbf4187e908b859458fba7a448e854b8ed5f Mon Sep 17 00:00:00 2001 From: Patrick Pelletier <code@funwithsoftware.org> Date: Fri, 17 Aug 2018 11:20:34 -0700 Subject: [PATCH 0794/2161] sim65: S_IREAD and S_IWRITE are nonstandard. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Linux build was failing with: sim65/paravirt.c: In function ‘PVOpen’: sim65/paravirt.c:217:18: error: ‘S_IREAD’ undeclared (first use in this function) OMode |= S_IREAD; ^ sim65/paravirt.c:217:18: note: each undeclared identifier is reported only once for each function it appears in sim65/paravirt.c:220:18: error: ‘S_IWRITE’ undeclared (first use in this function) OMode |= S_IWRITE; ^ make[1]: *** [../wrk/sim65/paravirt.o] Error 1 --- src/sim65/paravirt.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index fda2839af..1c431fdc9 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -48,6 +48,12 @@ /* Anyone else */ # include <unistd.h> #endif +#ifndef S_IREAD +# define S_IREAD S_IRUSR +#endif +#ifndef S_IWRITE +# define S_IWRITE S_IWUSR +#endif /* common */ #include "cmdline.h" From a7d158e077e8f76be2b8aa993606c2bf09919074 Mon Sep 17 00:00:00 2001 From: Patrick Pelletier <code@funwithsoftware.org> Date: Fri, 17 Aug 2018 11:53:19 -0700 Subject: [PATCH 0795/2161] sim65: Build was failing on Windows, too. Microsoft loves putting underscores in front of everything! --- src/sim65/paravirt.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 1c431fdc9..dd8bc3127 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -49,10 +49,18 @@ # include <unistd.h> #endif #ifndef S_IREAD -# define S_IREAD S_IRUSR +# ifdef _WIN32 +# define S_IREAD _S_IREAD +# else +# define S_IREAD S_IRUSR +# endif #endif #ifndef S_IWRITE -# define S_IWRITE S_IWUSR +# ifdef _WIN32 +# define S_IWRITE _S_IWRITE +# else +# define S_IWRITE S_IWUSR +# endif #endif /* common */ From b30f7905877e9b1674fb5c4b2ae9add014c7e874 Mon Sep 17 00:00:00 2001 From: Patrick Pelletier <code@funwithsoftware.org> Date: Fri, 17 Aug 2018 12:09:20 -0700 Subject: [PATCH 0796/2161] sim65: Blindly guessing to get Travis build to pass. --- src/sim65/paravirt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index dd8bc3127..dd65520a5 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -36,6 +36,8 @@ #include <string.h> #include <stdlib.h> #include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> #if defined(_WIN32) # define O_INITIAL O_BINARY #else From f72d355b18a873b1f379b4ea8fb6feeddd357314 Mon Sep 17 00:00:00 2001 From: Patrick Pelletier <code@funwithsoftware.org> Date: Fri, 17 Aug 2018 13:17:38 -0700 Subject: [PATCH 0797/2161] sim65: Use mode_t for OMode. --- src/sim65/paravirt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index dd65520a5..63ee57829 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -185,7 +185,8 @@ static void PVOpen (CPURegs* Regs) { char Path[1024]; int OFlag = O_INITIAL; - unsigned RetVal, I = 0, OMode = 0; + unsigned RetVal, I = 0; + mode_t OMode = 0; unsigned Mode = PopParam (Regs->YR - 4); unsigned Flags = PopParam (2); From 411a5a9483143443c17286d11bde19140ea45868 Mon Sep 17 00:00:00 2001 From: Patrick Pelletier <code@funwithsoftware.org> Date: Fri, 17 Aug 2018 13:24:08 -0700 Subject: [PATCH 0798/2161] Don't pass mode argument to open() from _fopen(). It isn't necessary, since paravirt.c has a default if the mode isn't pushed onto the stack. --- asminc/stat.inc | 3 --- include/sys/stat.h | 2 +- libsrc/common/_fopen.s | 6 +----- 3 files changed, 2 insertions(+), 9 deletions(-) delete mode 100644 asminc/stat.inc diff --git a/asminc/stat.inc b/asminc/stat.inc deleted file mode 100644 index d9c74aeaa..000000000 --- a/asminc/stat.inc +++ /dev/null @@ -1,3 +0,0 @@ -; File mode constants, must match the values in the C headers -S_IREAD = $0100 ; octal 0400 -S_IWRITE = $0080 ; octal 0200 diff --git a/include/sys/stat.h b/include/sys/stat.h index e49c370f9..ece324f0b 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -48,7 +48,7 @@ ** https://en.wikipedia.org/wiki/File_system_permissions#Numeric_notation ** (S_IREAD and S_IWRITE are aliases for S_IRUSR and S_IWUSR) ** -** Must match the values in asminc/stat.inc and src/sim65/paravirt.c +** Must match the values in src/sim65/paravirt.c */ #define S_IREAD 0400 diff --git a/libsrc/common/_fopen.s b/libsrc/common/_fopen.s index 0154858dd..29f1c4cd9 100644 --- a/libsrc/common/_fopen.s +++ b/libsrc/common/_fopen.s @@ -15,7 +15,6 @@ .include "errno.inc" .include "fcntl.inc" .include "_file.inc" - .include "stat.inc" ; ------------------------------------------------------------------------ @@ -83,10 +82,7 @@ modeok: ldy #$00 tya iny sta (sp),y - lda #<(S_IREAD|S_IWRITE) - ldx #>(S_IREAD|S_IWRITE) - jsr pushax ; Push the "mode" argument onto the stack - ldy #6 ; Size of arguments in bytes + ldy #4 ; Size of arguments in bytes jsr _open ; Will cleanup the stack ; Check the result of the open() call From e549e23a87d8fc2f966aaae6dcf097bb392822c1 Mon Sep 17 00:00:00 2001 From: Patrick Pelletier <code@funwithsoftware.org> Date: Fri, 17 Aug 2018 13:39:15 -0700 Subject: [PATCH 0799/2161] Use non-POSIX values for S_IREAD and S_IWRITE. (As requested in the PR.) --- include/sys/stat.h | 11 +++-------- src/sim65/paravirt.c | 6 +++--- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/include/sys/stat.h b/include/sys/stat.h index ece324f0b..ab0640150 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -44,15 +44,10 @@ -/* These are the values for the traditional UNIX mode bits: -** https://en.wikipedia.org/wiki/File_system_permissions#Numeric_notation -** (S_IREAD and S_IWRITE are aliases for S_IRUSR and S_IWUSR) -** -** Must match the values in src/sim65/paravirt.c -*/ +/* Must match the values in src/sim65/paravirt.c */ -#define S_IREAD 0400 -#define S_IWRITE 0200 +#define S_IREAD 0x1 +#define S_IWRITE 0x2 /*****************************************************************************/ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 63ee57829..3e43f26ea 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -196,7 +196,7 @@ static void PVOpen (CPURegs* Regs) /* If the caller did not supply the mode argument, ** use a reasonable default. */ - Mode = 0400 | 0200; + Mode = 0x1 | 0x2; } do { @@ -230,10 +230,10 @@ static void PVOpen (CPURegs* Regs) OFlag |= O_EXCL; } - if (Mode & 0400) { + if (Mode & 0x1) { OMode |= S_IREAD; } - if (Mode & 0200) { + if (Mode & 0x2) { OMode |= S_IWRITE; } From cb7ec508f650e79e1d2527bd3b5fdb86e390f9ed Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 18 Aug 2018 00:13:38 +0200 Subject: [PATCH 0800/2161] Fixed 12 AM/PM handling. Midnight is 12 AM and noon is 12 PM (see https://en.wikipedia.org/wiki/12-hour_clock). Therefore we need to subtract 12 hours in exactly those two hours. --- libsrc/c128/gettime.s | 13 +++++++++---- libsrc/c64/gettime.s | 13 +++++++++---- libsrc/cbm510/gettime.s | 13 +++++++++---- libsrc/cbm610/gettime.s | 13 +++++++++---- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/libsrc/c128/gettime.s b/libsrc/c128/gettime.s index b59789117..81f49c640 100644 --- a/libsrc/c128/gettime.s +++ b/libsrc/c128/gettime.s @@ -24,13 +24,18 @@ jsr pushax lda CIA1_TODHR - bpl AM - and #%01111111 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 - cld -AM: jsr BCD2dec +@L2: cld + jsr BCD2dec sta TM + tm::tm_hour lda CIA1_TODMIN jsr BCD2dec diff --git a/libsrc/c64/gettime.s b/libsrc/c64/gettime.s index 61c5115ae..8973e0e33 100644 --- a/libsrc/c64/gettime.s +++ b/libsrc/c64/gettime.s @@ -24,13 +24,18 @@ jsr pushax lda CIA1_TODHR - bpl AM - and #%01111111 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 - cld -AM: jsr BCD2dec +@L2: cld + jsr BCD2dec sta TM + tm::tm_hour lda CIA1_TODMIN jsr BCD2dec diff --git a/libsrc/cbm510/gettime.s b/libsrc/cbm510/gettime.s index 3ad162e3b..b89b9b16b 100644 --- a/libsrc/cbm510/gettime.s +++ b/libsrc/cbm510/gettime.s @@ -26,13 +26,18 @@ ldy #CIA::TODHR lda (cia2),y - bpl AM - and #%01111111 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 - cld -AM: jsr BCD2dec +@L2: cld + jsr BCD2dec sta TM + tm::tm_hour ldy #CIA::TODMIN lda (cia2),y diff --git a/libsrc/cbm610/gettime.s b/libsrc/cbm610/gettime.s index 30226213d..cfd2a9fe9 100644 --- a/libsrc/cbm610/gettime.s +++ b/libsrc/cbm610/gettime.s @@ -26,13 +26,18 @@ ldy #CIA::TODHR lda (cia),y - bpl AM - and #%01111111 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 - cld -AM: jsr BCD2dec +@L2: cld + jsr BCD2dec sta TM + tm::tm_hour ldy #CIA::TODMIN lda (cia),y From eb9872c684c88d5df64e0efb2352378e47cd4428 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 18 Aug 2018 01:13:02 +0200 Subject: [PATCH 0801/2161] Added clock_settime() for some CBMs. The CIA TOD only stores the time but not the date. Therefore the date set by clock_settime() ist just stored inside the C library for retrieval via clock_gettime(). The "very special" handling of 12AM/PM is based on https://groups.google.com/d/msg/comp.sys.cbm/ysVYSX4AMbc/vHrXCWEhCOUJ saying: ========== 24hr: Wr => Rd => Nx -------------------- 0 : 92 => 12 => 01 <= Switch from 00 to 01 (24-hour notation) 1 : 01 => 01 => 02 2 : 02 => 02 => 03 11 : 11 => 11 => 92 12 : 12 => 92 => 81 <= Switch from 12 to 13 (24-hour notation) 13 : 81 => 81 => 82 14 : 82 => 82 => 83 23 : 91 => 91 => 12 1. column ("24hr"): hour to be tested (decimal) 2. column ("Wr"): hour written to TOD register (BCD) 3. column ("Rd"): hour read from TOD register (BCD) immediately after writing the value in column 2 to see the conversion between AM/PM, if any 4. column ("Nx"): next hour (BCD) after the hour switch ========== Thanks Paul! --- libsrc/c128/gettime.s | 45 +------------------ libsrc/c128/settime.s | 83 +++++++++++++++++++++++++++++++++++ libsrc/c128/tmcommon.s | 64 +++++++++++++++++++++++++++ libsrc/c64/gettime.s | 48 +-------------------- libsrc/c64/settime.s | 83 +++++++++++++++++++++++++++++++++++ libsrc/c64/tmcommon.s | 67 +++++++++++++++++++++++++++++ libsrc/cbm510/gettime.s | 22 +--------- libsrc/cbm510/settime.s | 93 ++++++++++++++++++++++++++++++++++++++++ libsrc/cbm510/tmcommon.s | 41 ++++++++++++++++++ libsrc/cbm610/gettime.s | 23 +--------- libsrc/cbm610/settime.s | 93 ++++++++++++++++++++++++++++++++++++++++ libsrc/cbm610/tmcommon.s | 41 ++++++++++++++++++ 12 files changed, 573 insertions(+), 130 deletions(-) create mode 100644 libsrc/c128/settime.s create mode 100644 libsrc/c128/tmcommon.s create mode 100644 libsrc/c64/settime.s create mode 100644 libsrc/c64/tmcommon.s create mode 100644 libsrc/cbm510/settime.s create mode 100644 libsrc/cbm510/tmcommon.s create mode 100644 libsrc/cbm610/settime.s create mode 100644 libsrc/cbm610/tmcommon.s diff --git a/libsrc/c128/gettime.s b/libsrc/c128/gettime.s index 81f49c640..ba0068aa7 100644 --- a/libsrc/c128/gettime.s +++ b/libsrc/c128/gettime.s @@ -7,12 +7,10 @@ .include "time.inc" .include "c128.inc" - .include "get_tv.inc" - .constructor inittime .importzp sreg, tmp1, tmp2 .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1, return0 - .import _get_tv + .import TM, load_tenth ;---------------------------------------------------------------------------- @@ -50,12 +48,7 @@ ldy #timespec::tv_sec jsr steaxspidx ; Pops address pushed by 2. pushax - lda #<(100 * 1000 * 1000 / $10000) - ldx #>(100 * 1000 * 1000 / $10000) - sta sreg - stx sreg+1 - lda #<(100 * 1000 * 1000) - ldx #>(100 * 1000 * 1000) + jsr load_tenth jsr pusheax lda CIA1_TOD10 ldx #>$0000 @@ -88,37 +81,3 @@ 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/c128/settime.s b/libsrc/c128/settime.s new file mode 100644 index 000000000..afe9c0693 --- /dev/null +++ b/libsrc/c128/settime.s @@ -0,0 +1,83 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; int clock_settime (clockid_t clk_id, const struct timespec *tp); +; + + .include "time.inc" + .include "c128.inc" + + .importzp sreg, ptr1 + .import pushax, pusheax, ldax0sp, ldeaxidx + .import tosdiveax, incsp3, return0 + .import TM, load_tenth + + +;---------------------------------------------------------------------------- +.code + +.proc _clock_settime + + jsr pushax + + 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/c128/tmcommon.s b/libsrc/c128/tmcommon.s new file mode 100644 index 000000000..f9a53c2a3 --- /dev/null +++ b/libsrc/c128/tmcommon.s @@ -0,0 +1,64 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; Common stuff for the clock routines +; + + .include "c128.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/c64/gettime.s b/libsrc/c64/gettime.s index 8973e0e33..ddb865c8f 100644 --- a/libsrc/c64/gettime.s +++ b/libsrc/c64/gettime.s @@ -7,12 +7,10 @@ .include "time.inc" .include "c64.inc" - .include "get_tv.inc" - .constructor inittime .importzp sreg, tmp1, tmp2 .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1, return0 - .import _get_tv, _get_ostype + .import TM, load_tenth ;---------------------------------------------------------------------------- @@ -50,12 +48,7 @@ ldy #timespec::tv_sec jsr steaxspidx ; Pops address pushed by 2. pushax - lda #<(100 * 1000 * 1000 / $10000) - ldx #>(100 * 1000 * 1000 / $10000) - sta sreg - stx sreg+1 - lda #<(100 * 1000 * 1000) - ldx #>(100 * 1000 * 1000) + jsr load_tenth jsr pusheax lda CIA1_TOD10 ldx #>$0000 @@ -88,40 +81,3 @@ 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 - jsr _get_ostype - cmp #$43 - beq @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/c64/settime.s b/libsrc/c64/settime.s new file mode 100644 index 000000000..b60cb7172 --- /dev/null +++ b/libsrc/c64/settime.s @@ -0,0 +1,83 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; int clock_settime (clockid_t clk_id, const struct timespec *tp); +; + + .include "time.inc" + .include "c64.inc" + + .importzp sreg, ptr1 + .import pushax, pusheax, ldax0sp, ldeaxidx + .import tosdiveax, incsp3, return0 + .import TM, load_tenth + + +;---------------------------------------------------------------------------- +.code + +.proc _clock_settime + + jsr pushax + + 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/c64/tmcommon.s b/libsrc/c64/tmcommon.s new file mode 100644 index 000000000..ca824946f --- /dev/null +++ b/libsrc/c64/tmcommon.s @@ -0,0 +1,67 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; Common stuff for the clock routines +; + + .include "c64.inc" + .include "get_tv.inc" + + .export TM, load_tenth + + .constructor inittime + .importzp sreg + .import _get_tv, _get_ostype + + +;---------------------------------------------------------------------------- +.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 + jsr _get_ostype + cmp #$43 + beq @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/cbm510/gettime.s b/libsrc/cbm510/gettime.s index b89b9b16b..5a0a172e4 100644 --- a/libsrc/cbm510/gettime.s +++ b/libsrc/cbm510/gettime.s @@ -12,6 +12,7 @@ .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1 .import sys_bank, restore_bank + .import TM, load_tenth .importzp sreg, tmp1, tmp2 @@ -54,12 +55,7 @@ ldy #timespec::tv_sec jsr steaxspidx ; Pops address pushed by 2. pushax - lda #<(100 * 1000 * 1000 / $10000) - ldx #>(100 * 1000 * 1000 / $10000) - sta sreg - stx sreg+1 - lda #<(100 * 1000 * 1000) - ldx #>(100 * 1000 * 1000) + jsr load_tenth jsr pusheax ldy #CIA::TOD10 lda (cia2),y @@ -96,17 +92,3 @@ 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/cbm510/settime.s b/libsrc/cbm510/settime.s new file mode 100644 index 000000000..6e425eaff --- /dev/null +++ b/libsrc/cbm510/settime.s @@ -0,0 +1,93 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; int clock_settime (clockid_t clk_id, const struct timespec *tp); +; + + .include "time.inc" + .include "cbm510.inc" + .include "extzp.inc" + + .importzp sreg, ptr1 + .import pushax, pusheax, ldax0sp, ldeaxidx + .import sys_bank, restore_bank + .import tosdiveax, incsp3, return0 + .import TM, load_tenth + + +;---------------------------------------------------------------------------- +.code + +.proc _clock_settime + + jsr sys_bank + jsr pushax + + 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: ldy #CIA::TODHR + sta (cia2),y + lda TM + tm::tm_min + jsr dec2BCD + ldy #CIA::TODMIN + sta (cia2),y + lda TM + tm::tm_sec + jsr dec2BCD + ldy #CIA::TODSEC + sta (cia2),y + + jsr ldax0sp + ldy #3+timespec::tv_nsec + jsr ldeaxidx + jsr pusheax + jsr load_tenth + jsr tosdiveax + ldy #CIA::TOD10 + sta (cia2),y + + jsr incsp3 + + lda #0 + tax + jmp restore_bank + +.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/cbm510/tmcommon.s b/libsrc/cbm510/tmcommon.s new file mode 100644 index 000000000..9f0ed9c56 --- /dev/null +++ b/libsrc/cbm510/tmcommon.s @@ -0,0 +1,41 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; Common stuff for the clock routines +; + + .include "cbm510.inc" + + .export TM, load_tenth + + .importzp sreg + + +;---------------------------------------------------------------------------- +.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 + +;---------------------------------------------------------------------------- +; 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/cbm610/gettime.s b/libsrc/cbm610/gettime.s index cfd2a9fe9..7adf5a14d 100644 --- a/libsrc/cbm610/gettime.s +++ b/libsrc/cbm610/gettime.s @@ -12,6 +12,7 @@ .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1 .import sys_bank, restore_bank + .import TM, load_tenth .importzp sreg, tmp1, tmp2 @@ -54,12 +55,7 @@ ldy #timespec::tv_sec jsr steaxspidx ; Pops address pushed by 2. pushax - lda #<(100 * 1000 * 1000 / $10000) - ldx #>(100 * 1000 * 1000 / $10000) - sta sreg - stx sreg+1 - lda #<(100 * 1000 * 1000) - ldx #>(100 * 1000 * 1000) + jsr load_tenth jsr pusheax ldy #CIA::TOD10 lda (cia),y @@ -96,18 +92,3 @@ 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/cbm610/settime.s b/libsrc/cbm610/settime.s new file mode 100644 index 000000000..e540c07d0 --- /dev/null +++ b/libsrc/cbm610/settime.s @@ -0,0 +1,93 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; int clock_settime (clockid_t clk_id, const struct timespec *tp); +; + + .include "time.inc" + .include "cbm610.inc" + .include "extzp.inc" + + .importzp sreg, ptr1 + .import pushax, pusheax, ldax0sp, ldeaxidx + .import sys_bank, restore_bank + .import tosdiveax, incsp3, return0 + .import TM, load_tenth + + +;---------------------------------------------------------------------------- +.code + +.proc _clock_settime + + jsr sys_bank + jsr pushax + + 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: ldy #CIA::TODHR + sta (cia),y + lda TM + tm::tm_min + jsr dec2BCD + ldy #CIA::TODMIN + sta (cia),y + lda TM + tm::tm_sec + jsr dec2BCD + ldy #CIA::TODSEC + sta (cia),y + + jsr ldax0sp + ldy #3+timespec::tv_nsec + jsr ldeaxidx + jsr pusheax + jsr load_tenth + jsr tosdiveax + ldy #CIA::TOD10 + sta (cia),y + + jsr incsp3 + + lda #0 + tax + jmp restore_bank + +.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/cbm610/tmcommon.s b/libsrc/cbm610/tmcommon.s new file mode 100644 index 000000000..21dc55494 --- /dev/null +++ b/libsrc/cbm610/tmcommon.s @@ -0,0 +1,41 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; Common stuff for the clock routines +; + + .include "cbm610.inc" + + .export TM, load_tenth + + .importzp sreg + + +;---------------------------------------------------------------------------- +.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 + +;---------------------------------------------------------------------------- +; 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 From fe5af26f9fc2b36dc91b646a60da0090accb98c4 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 18 Aug 2018 01:28:30 +0200 Subject: [PATCH 0802/2161] Express assumption about struct timespec. We basically cast a struct timespec pointer to a time_t pointer when we pass the clock_settime() paramter to localtime(). Explicitly express that in the source code. --- libsrc/apple2/settime.s | 1 + libsrc/c128/settime.s | 1 + libsrc/c64/settime.s | 1 + libsrc/cbm510/settime.s | 1 + libsrc/cbm610/settime.s | 1 + 5 files changed, 5 insertions(+) diff --git a/libsrc/apple2/settime.s b/libsrc/apple2/settime.s index a71e113c5..2235d1a3f 100644 --- a/libsrc/apple2/settime.s +++ b/libsrc/apple2/settime.s @@ -29,6 +29,7 @@ _clock_settime: tya ; Restore A ; Get tm + .assert timespec::tv_sec = 0, error jsr _localtime sta ptr1 stx ptr1+1 diff --git a/libsrc/c128/settime.s b/libsrc/c128/settime.s index afe9c0693..0d95a3958 100644 --- a/libsrc/c128/settime.s +++ b/libsrc/c128/settime.s @@ -20,6 +20,7 @@ jsr pushax + .assert timespec::tv_sec = 0, error jsr _localtime sta ptr1 stx ptr1+1 diff --git a/libsrc/c64/settime.s b/libsrc/c64/settime.s index b60cb7172..c72d535bc 100644 --- a/libsrc/c64/settime.s +++ b/libsrc/c64/settime.s @@ -20,6 +20,7 @@ jsr pushax + .assert timespec::tv_sec = 0, error jsr _localtime sta ptr1 stx ptr1+1 diff --git a/libsrc/cbm510/settime.s b/libsrc/cbm510/settime.s index 6e425eaff..0c377eb63 100644 --- a/libsrc/cbm510/settime.s +++ b/libsrc/cbm510/settime.s @@ -23,6 +23,7 @@ jsr sys_bank jsr pushax + .assert timespec::tv_sec = 0, error jsr _localtime sta ptr1 stx ptr1+1 diff --git a/libsrc/cbm610/settime.s b/libsrc/cbm610/settime.s index e540c07d0..a42f451cf 100644 --- a/libsrc/cbm610/settime.s +++ b/libsrc/cbm610/settime.s @@ -23,6 +23,7 @@ jsr sys_bank jsr pushax + .assert timespec::tv_sec = 0, error jsr _localtime sta ptr1 stx ptr1+1 From 250e4ed9e0f2829ca48a895151f32b0fca249f90 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 18 Aug 2018 01:36:56 +0200 Subject: [PATCH 0803/2161] Added dummy clock_settime() for the Atari. Allow to build ip65/date65. --- libsrc/atari/settime.s | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 libsrc/atari/settime.s diff --git a/libsrc/atari/settime.s b/libsrc/atari/settime.s new file mode 100644 index 000000000..698aa2a29 --- /dev/null +++ b/libsrc/atari/settime.s @@ -0,0 +1,8 @@ +; +; int clock_settime (clockid_t clk_id, const struct timespec *tp); +; + .include "errno.inc" + .export _clock_settime +_clock_settime: + lda #ENOSYS + jmp __directerrno From 3598fb505d92891de36f3a283f90ab7b013a19c6 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 19 Aug 2018 00:01:40 +0200 Subject: [PATCH 0804/2161] Fixed Visual C++ build (and some style adjustments). --- include/sys/stat.h | 7 +++---- src/sim65/paravirt.c | 25 ++++++++----------------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/include/sys/stat.h b/include/sys/stat.h index ab0640150..c7e003808 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -2,7 +2,7 @@ /* */ /* stat.h */ /* */ -/* Constants for the mode argument of open */ +/* Constants for the mode argument of open and creat */ /* */ /* */ /* */ @@ -44,10 +44,9 @@ -/* Must match the values in src/sim65/paravirt.c */ +#define S_IREAD 0x01 +#define S_IWRITE 0x02 -#define S_IREAD 0x1 -#define S_IWRITE 0x2 /*****************************************************************************/ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 3e43f26ea..55caeeb94 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -36,7 +36,6 @@ #include <string.h> #include <stdlib.h> #include <fcntl.h> -#include <sys/types.h> #include <sys/stat.h> #if defined(_WIN32) # define O_INITIAL O_BINARY @@ -51,18 +50,10 @@ # include <unistd.h> #endif #ifndef S_IREAD -# ifdef _WIN32 -# define S_IREAD _S_IREAD -# else -# define S_IREAD S_IRUSR -# endif +# define S_IREAD S_IRUSR #endif #ifndef S_IWRITE -# ifdef _WIN32 -# define S_IWRITE _S_IWRITE -# else -# define S_IWRITE S_IWUSR -# endif +# define S_IWRITE S_IWUSR #endif /* common */ @@ -185,18 +176,18 @@ static void PVOpen (CPURegs* Regs) { char Path[1024]; int OFlag = O_INITIAL; + int OMode = 0; unsigned RetVal, I = 0; - mode_t OMode = 0; unsigned Mode = PopParam (Regs->YR - 4); unsigned Flags = PopParam (2); unsigned Name = PopParam (2); if (Regs->YR - 4 < 2) { - /* If the caller did not supply the mode argument, - ** use a reasonable default. + /* If the caller didn't supply the mode + ** argument, use a reasonable default. */ - Mode = 0x1 | 0x2; + Mode = 0x01 | 0x02; } do { @@ -230,10 +221,10 @@ static void PVOpen (CPURegs* Regs) OFlag |= O_EXCL; } - if (Mode & 0x1) { + if (Mode & 0x01) { OMode |= S_IREAD; } - if (Mode & 0x2) { + if (Mode & 0x02) { OMode |= S_IWRITE; } From 03a99569e3e20b1e887b1fc5cd36917c0b39b753 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 19 Aug 2018 14:35:30 +0200 Subject: [PATCH 0805/2161] Optimize for size. --- libsrc/common/time.s | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libsrc/common/time.s b/libsrc/common/time.s index 9b297d4d3..40b470f5b 100644 --- a/libsrc/common/time.s +++ b/libsrc/common/time.s @@ -6,7 +6,7 @@ .export _time - .import decsp1 + .import decsp1, ldeaxi .importzp ptr1, sreg, tmp1, tmp2 .include "time.inc" @@ -27,12 +27,10 @@ ldx #>time jsr _clock_gettime sta tmp2 - lda time + timespec::tv_sec+2 - ldx time + timespec::tv_sec+3 - sta sreg - stx sreg+1 - lda time + timespec::tv_sec - ldx time + timespec::tv_sec+1 + lda #<time + ldx #>time + .assert timespec::tv_sec = 0, error + jsr ldeaxi sta tmp1 ; Save low byte of result ; Restore timep and check if it is NULL From b93b88211cc5330f714c23f2da7f1791a09e1dc4 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sun, 19 Aug 2018 16:29:25 +0200 Subject: [PATCH 0806/2161] WDM support (#721) WDM support --- src/ca65/instr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 912e45867..532a8748e 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -635,7 +635,7 @@ static const struct { /* Instruction table for the 65816 */ static const struct { unsigned Count; - InsDesc Ins[99]; + InsDesc Ins[100]; } InsTab65816 = { sizeof (InsTab65816.Ins) / sizeof (InsTab65816.Ins[0]), { @@ -736,6 +736,7 @@ static const struct { { "TYA", 0x0000001, 0x98, 0, PutAll }, { "TYX", 0x0000001, 0xbb, 0, PutAll }, { "WAI", 0x0000001, 0xcb, 0, PutAll }, + { "WDM", 0x0000004, 0x42, 6, PutAll }, { "XBA", 0x0000001, 0xeb, 0, PutAll }, { "XCE", 0x0000001, 0xfb, 0, PutAll } } From 7b8d4b28c7ec175cae2d8d71ba322f34aaa90094 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 19 Aug 2018 17:12:54 -0400 Subject: [PATCH 0807/2161] Fixed the system banking in the cbm510 and the cbm610 targets' versions of clock_gettime() and clock_settime(). Their library function calls must run in the execution bank. --- libsrc/cbm510/gettime.s | 22 ++++++++++++---------- libsrc/cbm510/settime.s | 15 +++++++++------ libsrc/cbm610/gettime.s | 22 ++++++++++++---------- libsrc/cbm610/settime.s | 15 +++++++++------ 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/libsrc/cbm510/gettime.s b/libsrc/cbm510/gettime.s index 5a0a172e4..c767c1f33 100644 --- a/libsrc/cbm510/gettime.s +++ b/libsrc/cbm510/gettime.s @@ -1,7 +1,8 @@ ; -; Stefan Haubenthal, 2009-07-27 -; Ullrich von Bassewitz, 2009-09-24 -; Oliver Schmidt, 2018-08-14 +; 2009-07-27, Stefan Haubenthal +; 2009-09-24, Ullrich von Bassewitz +; 2018-08-18, Oliver Schmidt +; 2018-08-19, Greg King ; ; int clock_gettime (clockid_t clk_id, struct timespec *tp); ; @@ -21,10 +22,10 @@ .proc _clock_gettime - jsr sys_bank jsr pushax jsr pushax + jsr sys_bank ldy #CIA::TODHR lda (cia2),y sed @@ -48,6 +49,10 @@ lda (cia2),y jsr BCD2dec sta TM + tm::tm_sec + ldy #CIA::TOD10 + lda (cia2),y + jsr restore_bank + pha lda #<TM ldx #>TM jsr _mktime @@ -57,19 +62,16 @@ jsr load_tenth jsr pusheax - ldy #CIA::TOD10 - lda (cia2),y + pla ldx #>$0000 jsr tosmul0ax ldy #timespec::tv_nsec jsr steaxspidx ; Pops address pushed by 1. pushax - jsr incsp1 - - lda #0 + lda #$00 tax - jmp restore_bank + jmp incsp1 .endproc diff --git a/libsrc/cbm510/settime.s b/libsrc/cbm510/settime.s index 0c377eb63..6eb08a1ac 100644 --- a/libsrc/cbm510/settime.s +++ b/libsrc/cbm510/settime.s @@ -1,5 +1,6 @@ ; -; Oliver Schmidt, 16.8.2018 +; 2018-08-18, Oliver Schmidt +; 2018-08-19, Greg King ; ; int clock_settime (clockid_t clk_id, const struct timespec *tp); ; @@ -20,7 +21,6 @@ .proc _clock_settime - jsr sys_bank jsr pushax .assert timespec::tv_sec = 0, error @@ -33,6 +33,7 @@ dey bpl @L1 + jsr sys_bank lda TM + tm::tm_hour jsr dec2BCD tax ; Force flags @@ -55,6 +56,7 @@ jsr dec2BCD ldy #CIA::TODSEC sta (cia2),y + jsr restore_bank jsr ldax0sp ldy #3+timespec::tv_nsec @@ -62,14 +64,15 @@ jsr pusheax jsr load_tenth jsr tosdiveax + + jsr sys_bank ldy #CIA::TOD10 sta (cia2),y + jsr restore_bank - jsr incsp3 - - lda #0 + lda #$00 tax - jmp restore_bank + jmp incsp3 .endproc diff --git a/libsrc/cbm610/gettime.s b/libsrc/cbm610/gettime.s index 7adf5a14d..4c66f7747 100644 --- a/libsrc/cbm610/gettime.s +++ b/libsrc/cbm610/gettime.s @@ -1,7 +1,8 @@ ; -; Stefan Haubenthal, 2009-07-27 -; Ullrich von Bassewitz, 2009-09-24 -; Oliver Schmidt, 2018-08-14 +; 2009-07-27, Stefan Haubenthal +; 2009-09-24, Ullrich von Bassewitz +; 2018-08-18, Oliver Schmidt +; 2018-08-19, Greg King ; ; int clock_gettime (clockid_t clk_id, struct timespec *tp); ; @@ -21,10 +22,10 @@ .proc _clock_gettime - jsr sys_bank jsr pushax jsr pushax + jsr sys_bank ldy #CIA::TODHR lda (cia),y sed @@ -48,6 +49,10 @@ lda (cia),y jsr BCD2dec sta TM + tm::tm_sec + ldy #CIA::TOD10 + lda (cia),y + jsr restore_bank + pha lda #<TM ldx #>TM jsr _mktime @@ -57,19 +62,16 @@ jsr load_tenth jsr pusheax - ldy #CIA::TOD10 - lda (cia),y + pla ldx #>$0000 jsr tosmul0ax ldy #timespec::tv_nsec jsr steaxspidx ; Pops address pushed by 1. pushax - jsr incsp1 - - lda #0 + lda #$00 tax - jmp restore_bank + jmp incsp1 .endproc diff --git a/libsrc/cbm610/settime.s b/libsrc/cbm610/settime.s index a42f451cf..3d2a24af9 100644 --- a/libsrc/cbm610/settime.s +++ b/libsrc/cbm610/settime.s @@ -1,5 +1,6 @@ ; -; Oliver Schmidt, 16.8.2018 +; 2018-08-18, Oliver Schmidt +; 2018-08-19, Greg King ; ; int clock_settime (clockid_t clk_id, const struct timespec *tp); ; @@ -20,7 +21,6 @@ .proc _clock_settime - jsr sys_bank jsr pushax .assert timespec::tv_sec = 0, error @@ -33,6 +33,7 @@ dey bpl @L1 + jsr sys_bank lda TM + tm::tm_hour jsr dec2BCD tax ; Force flags @@ -55,6 +56,7 @@ jsr dec2BCD ldy #CIA::TODSEC sta (cia),y + jsr restore_bank jsr ldax0sp ldy #3+timespec::tv_nsec @@ -62,14 +64,15 @@ jsr pusheax jsr load_tenth jsr tosdiveax + + jsr sys_bank ldy #CIA::TOD10 sta (cia),y + jsr restore_bank - jsr incsp3 - - lda #0 + lda #$00 tax - jmp restore_bank + jmp incsp3 .endproc From f8c6c58373426551eed096dcfab4eab137fc0430 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 19 Aug 2018 23:40:50 +0200 Subject: [PATCH 0808/2161] Made Apple II CONIO more flexible. Originally the Apple II had a 64 char set and used the upper two bits to control inverse and blinking. The Apple //e brought then an alternate char set without blinking but more individual chars. However, it does _not_ contain 128 chars and use the upper bit to control inverse as one would assume. Rather it contains more than 128 chars - the MouseText chars. And because Apple wanted to provide as much backward compatibility as possible with the original char set, the alternate char set has a rather weird layout for chars > 128 with the inverse lowercase chars _not_ at (normal lowercase char + 128). So far the Apple II CONIO implementation mapped chars 128-255 to chars 0-127 (with the exception of \r and \n). It made use of alternate chars > 128 transparently for the user via reverse(1). The user didn't have direct access to the MouseText chars, they were only used interally for things like chline() and cvline(). Now the mapping of chars 128-255 to 0-127 is removed. Using chars > 128 gives the user direct access to the "raw" alternate chars > 128. This especially give the use direct access to the MouseText chars. But this clashes with the exsisting (and still desirable) revers(1) logic. Combining reverse(1) with chars > 128 just doesn't result in anything usable! What motivated this change? When I worked on the VT100 line drawing support for Telnet65 on the Apple //e (not using CONIO at all) I finally understood how MouseText is intended to be used to draw arbitrary grids with just three chars: A special "L" type char, the underscore and a vertical bar at the left side of the char box. I notice that with those chars it is possible to follow the CONIO approach to boxes and grids: Combining chline()/cvline() with special CH_... char constants for edges and intersections. But in order to actually do so I needed to be able to define CH_... constants that when fed into the ordinary cputc() pipeline end up as MouseText chars. The obvious approach was to allow chars > 128 to directly access MouseText chars :-) Now that the native CONIO box/grid approach works I deleted the Apple //e proprietary textframe() function that I added as replacement quite some years ago. Again: Please note that chline()/cvline() and the CH... constants don't work with reverse(1)! --- doc/funcref.sgml | 2 - include/apple2.h | 106 ++++++++++++++++++------------------ include/apple2enh.h | 41 +++++++------- libsrc/apple2/chline.s | 8 ++- libsrc/apple2/cputc.s | 2 +- libsrc/apple2/cvline.s | 7 ++- libsrc/apple2/mcbdefault.s | 2 +- libsrc/apple2/textframe.s | 108 ------------------------------------- 8 files changed, 82 insertions(+), 194 deletions(-) delete mode 100644 libsrc/apple2/textframe.s diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 247689b8a..589fbb75d 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -104,8 +104,6 @@ function. <item>_dos_type <item><ref id="get_ostype" name="get_ostype"> <item>rebootafterexit -<item>textframe -<item>textframexy <item><ref id="videomode" name="videomode"> </itemize> diff --git a/include/apple2.h b/include/apple2.h index f217ad04c..f205fdcb9 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -52,45 +52,49 @@ /* Color defines */ -#define COLOR_BLACK 0x00 -#define COLOR_WHITE 0x01 +#define COLOR_BLACK 0x00 +#define COLOR_WHITE 0x01 /* TGI color defines */ -#define TGI_COLOR_BLACK 0x00 -#define TGI_COLOR_GREEN 0x01 -#define TGI_COLOR_VIOLET 0x02 -#define TGI_COLOR_WHITE 0x03 -#define TGI_COLOR_BLACK2 0x04 -#define TGI_COLOR_ORANGE 0x05 -#define TGI_COLOR_BLUE 0x06 -#define TGI_COLOR_WHITE2 0x07 +#define TGI_COLOR_BLACK 0x00 +#define TGI_COLOR_GREEN 0x01 +#define TGI_COLOR_VIOLET 0x02 +#define TGI_COLOR_WHITE 0x03 +#define TGI_COLOR_BLACK2 0x04 +#define TGI_COLOR_ORANGE 0x05 +#define TGI_COLOR_BLUE 0x06 +#define TGI_COLOR_WHITE2 0x07 -#define TGI_COLOR_MAGENTA TGI_COLOR_BLACK2 -#define TGI_COLOR_DARKBLUE TGI_COLOR_WHITE2 -#define TGI_COLOR_DARKGREEN 0x08 -#define TGI_COLOR_GRAY 0x09 -#define TGI_COLOR_CYAN 0x0A -#define TGI_COLOR_BROWN 0x0B -#define TGI_COLOR_GRAY2 0x0C -#define TGI_COLOR_PINK 0x0D -#define TGI_COLOR_YELLOW 0x0E -#define TGI_COLOR_AQUA 0x0F +#define TGI_COLOR_MAGENTA TGI_COLOR_BLACK2 +#define TGI_COLOR_DARKBLUE TGI_COLOR_WHITE2 +#define TGI_COLOR_DARKGREEN 0x08 +#define TGI_COLOR_GRAY 0x09 +#define TGI_COLOR_CYAN 0x0A +#define TGI_COLOR_BROWN 0x0B +#define TGI_COLOR_GRAY2 0x0C +#define TGI_COLOR_PINK 0x0D +#define TGI_COLOR_YELLOW 0x0E +#define TGI_COLOR_AQUA 0x0F /* Characters codes */ -#define CH_ENTER 0x0D -#define CH_ESC 0x1B -#define CH_CURS_LEFT 0x08 -#define CH_CURS_RIGHT 0x15 +#define CH_ENTER 0x0D +#define CH_ESC 0x1B +#define CH_CURS_LEFT 0x08 +#define CH_CURS_RIGHT 0x15 -#define CH_ULCORNER '+' -#define CH_URCORNER '+' -#define CH_LLCORNER '+' -#define CH_LRCORNER '+' -#define CH_TTEE '+' -#define CH_BTEE '+' -#define CH_LTEE '+' -#define CH_RTEE '+' -#define CH_CROSS '+' +#if !defined(__APPLE2ENH__) +#define CH_HLINE '-' +#define CH_VLINE '!' +#define CH_ULCORNER '+' +#define CH_URCORNER '+' +#define CH_LLCORNER '+' +#define CH_LRCORNER '+' +#define CH_TTEE '+' +#define CH_BTEE '+' +#define CH_LTEE '+' +#define CH_RTEE '+' +#define CH_CROSS '+' +#endif /* Masks for joy_read */ #define JOY_UP_MASK 0x10 @@ -101,21 +105,21 @@ #define JOY_BTN_2_MASK 0x80 /* Return codes for get_ostype */ -#define APPLE_UNKNOWN 0x00 -#define APPLE_II 0x10 /* Apple ][ */ -#define APPLE_IIPLUS 0x11 /* Apple ][+ */ -#define APPLE_IIIEM 0x20 /* Apple /// (emulation) */ -#define APPLE_IIE 0x30 /* Apple //e */ -#define APPLE_IIEENH 0x31 /* Apple //e (enhanced) */ -#define APPLE_IIECARD 0x40 /* Apple //e Option Card */ -#define APPLE_IIC 0x50 /* Apple //c */ -#define APPLE_IIC35 0x51 /* Apple //c (3.5 ROM) */ -#define APPLE_IICEXP 0x53 /* Apple //c (Mem. Exp.) */ -#define APPLE_IICREV 0x54 /* Apple //c (Rev. Mem. Exp.) */ -#define APPLE_IICPLUS 0x55 /* Apple //c Plus */ -#define APPLE_IIGS 0x80 /* Apple IIgs */ -#define APPLE_IIGS1 0x81 /* Apple IIgs (ROM 1) */ -#define APPLE_IIGS3 0x83 /* Apple IIgs (ROM 3) */ +#define APPLE_UNKNOWN 0x00 +#define APPLE_II 0x10 /* Apple ][ */ +#define APPLE_IIPLUS 0x11 /* Apple ][+ */ +#define APPLE_IIIEM 0x20 /* Apple /// (emulation) */ +#define APPLE_IIE 0x30 /* Apple //e */ +#define APPLE_IIEENH 0x31 /* Apple //e (enhanced) */ +#define APPLE_IIECARD 0x40 /* Apple //e Option Card */ +#define APPLE_IIC 0x50 /* Apple //c */ +#define APPLE_IIC35 0x51 /* Apple //c (3.5 ROM) */ +#define APPLE_IICEXP 0x53 /* Apple //c (Mem. Exp.) */ +#define APPLE_IICREV 0x54 /* Apple //c (Rev. Mem. Exp.) */ +#define APPLE_IICPLUS 0x55 /* Apple //c Plus */ +#define APPLE_IIGS 0x80 /* Apple IIgs */ +#define APPLE_IIGS1 0x81 /* Apple IIgs (ROM 1) */ +#define APPLE_IIGS3 0x83 /* Apple IIgs (ROM 3) */ extern unsigned char _dos_type; /* Valid _dos_type values: @@ -200,9 +204,9 @@ void rebootafterexit (void); ** to be overlaid by macros with the same names, saving the function call ** overhead. */ -#define _textcolor(color) COLOR_WHITE -#define _bgcolor(color) COLOR_BLACK -#define _bordercolor(color) COLOR_BLACK +#define _textcolor(color) COLOR_WHITE +#define _bgcolor(color) COLOR_BLACK +#define _bordercolor(color) COLOR_BLACK diff --git a/include/apple2enh.h b/include/apple2enh.h index 77328b5ed..3dd8cffc0 100644 --- a/include/apple2enh.h +++ b/include/apple2enh.h @@ -53,9 +53,21 @@ /* Characters codes */ -#define CH_DEL 0x7F -#define CH_CURS_UP 0x0B -#define CH_CURS_DOWN 0x0A +#define CH_DEL 0x7F +#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 @@ -69,15 +81,11 @@ #define CH_F9 0xB9 #define CH_F10 0xB0 -/* Styles for textframe */ -#define TEXTFRAME_WIDE 0x00 -#define TEXTFRAME_TALL 0x04 - /* Video modes */ -#define VIDEOMODE_40x24 0x0011 -#define VIDEOMODE_80x24 0x0012 -#define VIDEOMODE_40COL VIDEOMODE_40x24 -#define VIDEOMODE_80COL VIDEOMODE_80x24 +#define VIDEOMODE_40x24 0x0011 +#define VIDEOMODE_80x24 0x0012 +#define VIDEOMODE_40COL VIDEOMODE_40x24 +#define VIDEOMODE_80COL VIDEOMODE_80x24 @@ -103,17 +111,6 @@ extern void a2e_lo_tgi[]; -void __fastcall__ textframe (unsigned char width, unsigned char height, - unsigned char style); -/* Output a frame on the text screen with the given width and height -** starting at the current cursor position and using the given style. -*/ - -void __fastcall__ textframexy (unsigned char x, unsigned char y, - unsigned char width, unsigned char height, - unsigned char style); -/* Same as "gotoxy (x, y); textframe (width, height, style);" */ - unsigned __fastcall__ videomode (unsigned mode); /* Set the video mode, return the old mode. Call with one of the VIDEOMODE_xx ** constants. diff --git a/libsrc/apple2/chline.s b/libsrc/apple2/chline.s index ca1ee707c..be157ca9e 100644 --- a/libsrc/apple2/chline.s +++ b/libsrc/apple2/chline.s @@ -18,12 +18,10 @@ _chlinexy: _chline: .ifdef __APPLE2ENH__ - ldx #'S' ; MouseText character - ldy INVFLG - cpy #$FF ; Normal character display mode? - beq chlinedirect + ldx #'_' | $80 ; Underscore, screen code + .else + ldx #'-' | $80 ; Minus, screen code .endif - ldx #'-' | $80 ; Horizontal line, screen code chlinedirect: stx tmp1 diff --git a/libsrc/apple2/cputc.s b/libsrc/apple2/cputc.s index 6f610fe92..348fa4af9 100644 --- a/libsrc/apple2/cputc.s +++ b/libsrc/apple2/cputc.s @@ -37,7 +37,7 @@ _cputc: beq left cmp #$0A ; Test for \n = line feed beq newline - ora #$80 ; Turn on high bit + eor #$80 ; Invert high bit .ifndef __APPLE2ENH__ cmp #$E0 ; Test for lowercase bcc cputdirect diff --git a/libsrc/apple2/cvline.s b/libsrc/apple2/cvline.s index c8ae1e269..86bbf11f4 100644 --- a/libsrc/apple2/cvline.s +++ b/libsrc/apple2/cvline.s @@ -5,7 +5,7 @@ ; void __fastcall__ cvline (unsigned char length); ; - .export _cvlinexy, _cvline, cvlinedirect + .export _cvlinexy, _cvline .import gotoxy, putchar, newline .include "zeropage.inc" @@ -17,12 +17,11 @@ _cvlinexy: _cvline: .ifdef __APPLE2ENH__ - ldx #'|' | $80 ; Vertical line, screen code + ldx #$5F ; Left vertical line MouseText character .else - ldx #'!' | $80 ; Vertical line, screen code + ldx #'!' | $80 ; Exclamation mark, screen code .endif -cvlinedirect: stx tmp1 cmp #$00 ; Is the length zero? beq done ; Jump if done diff --git a/libsrc/apple2/mcbdefault.s b/libsrc/apple2/mcbdefault.s index cada4173a..c24c5df56 100644 --- a/libsrc/apple2/mcbdefault.s +++ b/libsrc/apple2/mcbdefault.s @@ -36,7 +36,7 @@ _mouse_def_callbacks: .data .ifdef __APPLE2ENH__ -cursor = 'B' ; MouseText character +cursor = $42 ; Pointer MouseText character .else cursor = '+' | $40 ; Flashing crosshair .endif diff --git a/libsrc/apple2/textframe.s b/libsrc/apple2/textframe.s deleted file mode 100644 index 55ac235b8..000000000 --- a/libsrc/apple2/textframe.s +++ /dev/null @@ -1,108 +0,0 @@ -; -; Oliver Schmidt, 10.03.2004 -; -; void __fastcall__ textframexy (unsigned char x, unsigned char y, -; unsigned char width, unsigned char height, -; unsigned char style); -; void __fastcall__ textframe (unsigned char width, unsigned char height, -; unsigned char style); -; - .ifdef __APPLE2ENH__ - - .export _textframexy, _textframe - .import popa, pusha, _gotoxy - .import chlinedirect, cvlinedirect - - .include "zeropage.inc" - .include "apple2.inc" - -WIDTH = ptr1 -HEIGHT = ptr1+1 -XORIGIN = ptr2 -YORIGIN = ptr2+1 - -_textframexy: - sec - bra :+ - -_textframe: - clc -: ldx INVFLG - phx ; Save character display mode - ldx #$FF - stx INVFLG ; Set normal character display mode - pha ; Save index - jsr popa ; Get height - sta HEIGHT - jsr popa ; Get width - sta WIDTH - lda CH - ldx CV - bcc noxy - jsr popa ; Get y - tax - jsr popa ; Get x -noxy: sta XORIGIN - stx YORIGIN - plx ; Restore index -loop: lda XOFFS,x - clc - bpl :+ ; Relative to left edge? - adc WIDTH -: adc XORIGIN - jsr pusha - lda YOFFS,x - clc - bpl :+ ; Relative to top? - adc HEIGHT -: adc YORIGIN - jsr _gotoxy ; Call this one, will pop params - txa - tay - lsr ; Get bit 0 (vline) into carry - lda LENGTH,x - phx ; Save index - ldx CHAR,y - bcc hline - clc - adc HEIGHT - jsr cvlinedirect - bra next -hline: adc WIDTH - jsr chlinedirect -next: plx ; Restore index - inx - txa - and #$03 ; Mask style - bne loop - pla - sta INVFLG ; Restore character display mode - rts - - .rodata - -; 2 styles with 4 lines each make up 8 entries per table -; - even entry numbers mean horizontal lines -; - odd entry numbers mean vertical lines - -; x offset for the line starting point -; - a positive value means relative to the frame left edge -; - a negative value menas relative to the frame right edge -XOFFS: .byte 0, 0, 0, <-2, 1, 0, 1, <-2 - -; y offset for the line starting point -; - a positive value means relative to the frame top -; - a negative value menas relative to the frame bottom -YOFFS: .byte 0, 1, <-2, 1, 0, 0, <-2, 0 - -; length of the line relative to the frame size -; - a negative value for hlines means shorter than the width -; - a negative value for vlines menas shorter than the height -LENGTH: .byte 0, <-2, 0, <-2, <-2, 0, <-2, 0 - -; character to use for drawing the line -; - hibit set means normal printable character -; - hibit clear means MouseText character -CHAR: .byte '_'|$80, '_', 'L', 'Z', 'L', 'Z', '_'|$80, '_' - - .endif ; __APPLE2ENH__ From 1644bcdf035aca1ccf1b6c93543c0b8c96231ecf Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 20 Aug 2018 00:22:45 +0200 Subject: [PATCH 0809/2161] Implemented line wrap. According to https://github.com/cc65/wiki/wiki/Direct-console-IO it is undefined what happens when the end of the sceen is reached. But it is _not_ undefined what happens when the end of the line is reached. So implement the usual thing - which was easy enough to do after all. --- libsrc/apple2/cputc.s | 1 + 1 file changed, 1 insertion(+) diff --git a/libsrc/apple2/cputc.s b/libsrc/apple2/cputc.s index 348fa4af9..30383fcfe 100644 --- a/libsrc/apple2/cputc.s +++ b/libsrc/apple2/cputc.s @@ -50,6 +50,7 @@ cputdirect: lda CH cmp WNDWDTH bcc :+ + jsr newline left: lda #$00 ; Goto left edge of screen sta CH : rts From 13790bdbf09912b412ab47b68e6cb6cea79f0500 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 20 Aug 2018 00:29:29 +0200 Subject: [PATCH 0810/2161] Improved CONIO test in several ways. - Use more consistent source code style. - Don't presume that CH_F... constants are present. - Allow to quit the program via 'Enter'. --- testcode/lib/conio.c | 68 ++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/testcode/lib/conio.c b/testcode/lib/conio.c index 13188d1cd..672be88fd 100644 --- a/testcode/lib/conio.c +++ b/testcode/lib/conio.c @@ -25,11 +25,11 @@ #endif static char grid[5][5] = { - { CH_ULCORNER, CH_HLINE, CH_TTEE, CH_HLINE, CH_URCORNER }, - { CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE }, - { CH_LTEE, CH_HLINE, CH_CROSS, CH_HLINE, CH_RTEE }, - { CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE }, - { CH_LLCORNER, CH_HLINE, CH_BTEE, CH_HLINE, CH_LRCORNER }, + {CH_ULCORNER, CH_HLINE, CH_TTEE, CH_HLINE, CH_URCORNER}, + {CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE }, + {CH_LTEE, CH_HLINE, CH_CROSS, CH_HLINE, CH_RTEE }, + {CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE }, + {CH_LLCORNER, CH_HLINE, CH_BTEE, CH_HLINE, CH_LRCORNER} }; void main(void) @@ -50,35 +50,36 @@ void main(void) tcol = textcolor(0); /* remember original textcolor */ bgcol = bgcolor(0); /* remember original background color */ bcol = bordercolor(0); /* remember original border color */ - bgcolor(bgcol);bordercolor(bcol); + (void)bgcolor(bgcol); + (void)bordercolor(bcol); for (i = 0; i < 3; ++i) { - gotoxy(i,3 + i); + gotoxy(i, 3 + i); for (j = 0; j < NUMCOLS; ++j) { - textcolor(j); + (void)textcolor(j); cputc('X'); } } - textcolor(tcol); + (void)textcolor(tcol); - cprintf("\n\n\r Screensize: %dx%d", xsize, ysize ); + cprintf("\n\n\r Screensize: %dx%d", xsize, ysize); - chlinexy(0,6,xsize); - cvlinexy(0,6,3); - chlinexy(0,8,xsize); - cvlinexy(xsize-1,6,3); - cputcxy(0,6,CH_ULCORNER); - cputcxy(xsize-1,6,CH_URCORNER); - cputcxy(0,8,CH_LLCORNER); - cputcxy(xsize-1,8,CH_LRCORNER); + chlinexy(0, 6, xsize); + cvlinexy(0, 6, 3); + chlinexy(0, 8, xsize); + cvlinexy(xsize - 1, 6, 3); + cputcxy(0, 6, CH_ULCORNER); + cputcxy(xsize - 1, 6, CH_URCORNER); + cputcxy(0, 8, CH_LLCORNER); + cputcxy(xsize - 1, 8, CH_LRCORNER); for (i = 0; i < 5; ++i) { - gotoxy(xsize - 5,i); + gotoxy(xsize - 5, i); for (j = 0; j < 5; ++j) { cputc(grid[i][j]); } } - gotoxy(0,ysize - 2 - ((NUMCHARS + xsize) / xsize)); + gotoxy(0, ysize - 2 - ((NUMCHARS + xsize) / xsize)); revers(1); for (i = 0; i < xsize; ++i) { cputc('0' + i % 10); @@ -112,9 +113,9 @@ void main(void) revers(j ^ 1); cputs(" rvs"); revers(0); - textcolor(i); + (void)textcolor(i); - gotoxy(7 + inpos,1); + gotoxy(7 + inpos, 1); #if defined(__NES__) || defined(__PCE__) || defined(__GAMATE__) /* not all targets have waitvsync */ @@ -125,24 +126,35 @@ void main(void) cprintf("%02x", joy); #else i = cgetc(); - if ((i >= '0') && (i<='9')) { - textcolor(i - '0'); + if ((i >= '0') && (i <= '9')) { + (void)textcolor(i - '0'); + } else if (i == CH_ENTER) { + clrscr(); + return; } else if (i == CH_CURS_LEFT) { inpos = (inpos - 1) & 7; } else if (i == CH_CURS_RIGHT) { inpos = (inpos + 1) & 7; +#ifdef CH_F5 } else if (i == CH_F5) { bgcol = (bgcol + 1) & 0x0f; - bordercolor(bgcol); + (void)bordercolor(bgcol); +#endif +#ifdef CH_F6 } else if (i == CH_F6) { bgcol = (bgcol - 1) & 0x0f; - bordercolor(bgcol); + (void)bordercolor(bgcol); +#endif +#ifdef CH_F7 } else if (i == CH_F7) { bgcol = (bgcol + 1) & 0x0f; - bgcolor(bgcol); + (void)bgcolor(bgcol); +#endif +#ifdef CH_F8 } else if (i == CH_F8) { bgcol = (bgcol - 1) & 0x0f; - bgcolor(bgcol); + (void)bgcolor(bgcol); +#endif } else { cputc(i); inpos = (inpos + 1) & 7; From 9fee605e65ed9fb82c6de088159043d636f43bb0 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 20 Aug 2018 14:42:41 -0400 Subject: [PATCH 0811/2161] Added more source-code improvements to the conio test program. Also, made the f6/f5 function keys change the border color instead of the background color. --- testcode/lib/conio.c | 81 ++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/testcode/lib/conio.c b/testcode/lib/conio.c index 672be88fd..49434595b 100644 --- a/testcode/lib/conio.c +++ b/testcode/lib/conio.c @@ -1,5 +1,5 @@ /* - * conio api test program + * conio API test program * * keys: * @@ -29,12 +29,12 @@ static char grid[5][5] = { {CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE }, {CH_LTEE, CH_HLINE, CH_CROSS, CH_HLINE, CH_RTEE }, {CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE }, - {CH_LLCORNER, CH_HLINE, CH_BTEE, CH_HLINE, CH_LRCORNER} + {CH_LLCORNER, CH_HLINE, CH_BTEE, CH_HLINE, CH_LRCORNER} }; void main(void) { - int i, j, n; + unsigned int i, j, n; unsigned char xsize, ysize, tcol, bgcol, bcol, inpos = 0; #if defined(__NES__) || defined(__PCE__) || defined(__GAMATE__) unsigned char joy; @@ -44,14 +44,15 @@ void main(void) clrscr(); screensize(&xsize, &ysize); cputs("cc65 conio test\n\r"); - cputs("Input:[ ]"); + cputs("Input:[ ]"); /* 8 spaces */ + + tcol = textcolor(0); /* memorize original textcolor */ + bgcol = bgcolor(0); /* memorize original background color */ + bcol = bordercolor(0); /* memorize original border color */ + (void)bordercolor(bcol); + (void)bgcolor(bgcol); cputsxy(0, 2, "Colors:" ); - tcol = textcolor(0); /* remember original textcolor */ - bgcol = bgcolor(0); /* remember original background color */ - bcol = bordercolor(0); /* remember original border color */ - (void)bgcolor(bgcol); - (void)bordercolor(bcol); for (i = 0; i < 3; ++i) { gotoxy(i, 3 + i); for (j = 0; j < NUMCOLS; ++j) { @@ -61,7 +62,7 @@ void main(void) } (void)textcolor(tcol); - cprintf("\n\n\r Screensize: %dx%d", xsize, ysize); + cprintf("\n\n\r Screensize: %ux%u", xsize, ysize); chlinexy(0, 6, xsize); cvlinexy(0, 6, 3); @@ -103,11 +104,10 @@ void main(void) cursor(1); for (;;) { - /* do the "rvs" blinking */ i = textcolor(COLOR_BLACK); gotoxy(8, 2); - j = n >> 4 & 1; + j = (++n / 16) & 1; revers(j); cputc(j ? 'R' : ' '); revers(j ^ 1); @@ -126,40 +126,47 @@ void main(void) cprintf("%02x", joy); #else i = cgetc(); - if ((i >= '0') && (i <= '9')) { - (void)textcolor(i - '0'); - } else if (i == CH_ENTER) { - clrscr(); - return; - } else if (i == CH_CURS_LEFT) { - inpos = (inpos - 1) & 7; - } else if (i == CH_CURS_RIGHT) { - inpos = (inpos + 1) & 7; + switch (i) { + case CH_ENTER: + clrscr(); + return; + case CH_CURS_LEFT: + inpos = (inpos - 1) % 8; + break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + (void)textcolor(i - '0'); + break; #ifdef CH_F5 - } else if (i == CH_F5) { - bgcol = (bgcol + 1) & 0x0f; - (void)bordercolor(bgcol); + case CH_F5: + bcol = (bcol + 1) & 0x0f; + (void)bordercolor(bcol); + break; #endif #ifdef CH_F6 - } else if (i == CH_F6) { - bgcol = (bgcol - 1) & 0x0f; - (void)bordercolor(bgcol); + case CH_F6: + bcol = (bcol - 1) & 0x0f; + (void)bordercolor(bcol); + break; #endif #ifdef CH_F7 - } else if (i == CH_F7) { - bgcol = (bgcol + 1) & 0x0f; - (void)bgcolor(bgcol); + case CH_F7: + bgcol = (bgcol + 1) & 0x0f; + (void)bgcolor(bgcol); + break; #endif #ifdef CH_F8 - } else if (i == CH_F8) { - bgcol = (bgcol - 1) & 0x0f; - (void)bgcolor(bgcol); + case CH_F8: + bgcol = (bgcol - 1) & 0x0f; + (void)bgcolor(bgcol); + break; #endif - } else { - cputc(i); - inpos = (inpos + 1) & 7; + default: + cputc(i); + /* fallthrough */ + case CH_CURS_RIGHT: + inpos = (inpos + 1) % 8; } #endif - ++n; } } From 68a115cacf588b64a5e098497d2e6a2c2139f33e Mon Sep 17 00:00:00 2001 From: Patrick Pelletier <code@funwithsoftware.org> Date: Sun, 19 Aug 2018 16:04:42 -0700 Subject: [PATCH 0812/2161] Fix ftell() on Apple II to return the correct value. Fixes this issue: https://github.com/cc65/cc65/issues/722 ftell() returns the value returned by lseek(), and lseek() for the Apple II wasn't returning a value. --- libsrc/apple2/lseek.s | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libsrc/apple2/lseek.s b/libsrc/apple2/lseek.s index 22bcbee30..b1b7b6afb 100644 --- a/libsrc/apple2/lseek.s +++ b/libsrc/apple2/lseek.s @@ -84,6 +84,14 @@ seek_common: jsr callmli bcs oserr + ; Need to return the position in EAX + lda #0 + sta sreg+1 + lda mliparam + MLI::MARK::POSITION+2 + sta sreg + ldx mliparam + MLI::MARK::POSITION+1 + lda mliparam + MLI::MARK::POSITION + rts ; Load errno code From 8cb930b50e93647cd28debfc40f39fcf6507797b Mon Sep 17 00:00:00 2001 From: Patrick Pelletier <code@funwithsoftware.org> Date: Mon, 20 Aug 2018 00:10:51 -0700 Subject: [PATCH 0813/2161] lseek: use STZ for APPLE2ENH (As suggested in pull request.) --- libsrc/apple2/lseek.s | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libsrc/apple2/lseek.s b/libsrc/apple2/lseek.s index b1b7b6afb..6d5eba8a2 100644 --- a/libsrc/apple2/lseek.s +++ b/libsrc/apple2/lseek.s @@ -85,8 +85,12 @@ seek_common: bcs oserr ; Need to return the position in EAX + .ifdef __APPLE2ENH__ + stz sreg+1 + .else lda #0 sta sreg+1 + .endif lda mliparam + MLI::MARK::POSITION+2 sta sreg ldx mliparam + MLI::MARK::POSITION+1 From 59a4ab877886a57334060b0e0366fbb69aa6e493 Mon Sep 17 00:00:00 2001 From: Patrick Pelletier <code@funwithsoftware.org> Date: Mon, 20 Aug 2018 00:56:01 -0700 Subject: [PATCH 0814/2161] lseek: Implement additional feedback from PR #723. * Check CPU_ISET_65SC02 rather than APPLE2ENH. * Set sreg and sreg+1 to $FF on error, to return -1 as a long. --- libsrc/apple2/lseek.s | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/libsrc/apple2/lseek.s b/libsrc/apple2/lseek.s index 6d5eba8a2..d1633c32c 100644 --- a/libsrc/apple2/lseek.s +++ b/libsrc/apple2/lseek.s @@ -6,6 +6,7 @@ .export _lseek .import popax, popptr1 + .macpack cpu .include "zeropage.inc" .include "errno.inc" @@ -85,12 +86,12 @@ seek_common: bcs oserr ; Need to return the position in EAX - .ifdef __APPLE2ENH__ +.if (.cpu .bitand ::CPU_ISET_65SC02) stz sreg+1 - .else - lda #0 +.else + lda #$00 sta sreg+1 - .endif +.endif lda mliparam + MLI::MARK::POSITION+2 sta sreg ldx mliparam + MLI::MARK::POSITION+1 @@ -102,7 +103,13 @@ seek_common: einval: lda #EINVAL ; Set __errno -errno: jmp __directerrno +errno: ldx #$FF + stx sreg + stx sreg+1 + jmp __directerrno ; Set __oserror -oserr: jmp __mappederrno +oserr: ldx #$FF + stx sreg + stx sreg+1 + jmp __mappederrno From b37d0a444c4e87758ea6c8d104b6cdf11bd4c5dc Mon Sep 17 00:00:00 2001 From: Patrick Pelletier <code@funwithsoftware.org> Date: Mon, 20 Aug 2018 08:45:40 -0700 Subject: [PATCH 0815/2161] lseek: Return EINVAL if new position is less than 0 or greater than 2^24 - 1. Also, implemented @greg-king5's suggestion to save a byte on error paths. --- libsrc/apple2/lseek.s | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/libsrc/apple2/lseek.s b/libsrc/apple2/lseek.s index d1633c32c..b6c31515e 100644 --- a/libsrc/apple2/lseek.s +++ b/libsrc/apple2/lseek.s @@ -22,6 +22,7 @@ _lseek: jsr popptr1 jsr popax sta ptr2 + stx ptr2+1 ; Get and process fd jsr popax @@ -78,6 +79,9 @@ seek_common: tya adc ptr2 sta mliparam + MLI::MARK::POSITION+2 + lda #$00 + adc ptr2+1 + bne einval ; less than 0 or greater than 2^24 - 1 ; Set file pointer lda #SET_MARK_CALL @@ -103,13 +107,13 @@ seek_common: einval: lda #EINVAL ; Set __errno -errno: ldx #$FF - stx sreg +errno: jsr __directerrno ; leaves -1 in AX + stx sreg ; extend return value to 32 bits stx sreg+1 - jmp __directerrno + rts ; Set __oserror -oserr: ldx #$FF - stx sreg +oserr: jsr __mappederrno ; leaves -1 in AX + stx sreg ; extend return value to 32 bits stx sreg+1 - jmp __mappederrno + rts From 0a7702626f20a1a00a233a2ef10b9f58500c8e09 Mon Sep 17 00:00:00 2001 From: Patrick Pelletier <code@funwithsoftware.org> Date: Mon, 20 Aug 2018 10:10:10 -0700 Subject: [PATCH 0816/2161] seek test: remove trailing newline from filename Looks like no one ever tried this? fopen was returning EINVAL because fgets was leaving a trailing newline at the end of the filename. (Which is what fgets is documented to do.) --- testcode/lib/seek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/testcode/lib/seek.c b/testcode/lib/seek.c index 0cb1c6ad6..59603a795 100644 --- a/testcode/lib/seek.c +++ b/testcode/lib/seek.c @@ -23,6 +23,7 @@ int main(int argc, char **argv) if (!x) { return(0); } + x[strcspn(x, "\r\n")] = 0; filename = x; } else { From 357d94e834c33ff09d2e993b7a930ebb7819919c Mon Sep 17 00:00:00 2001 From: Patrick Pelletier <code@funwithsoftware.org> Date: Mon, 20 Aug 2018 10:53:35 -0700 Subject: [PATCH 0817/2161] seek test: Test some additional error cases. --- testcode/lib/seek.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/testcode/lib/seek.c b/testcode/lib/seek.c index 59603a795..200f344c2 100644 --- a/testcode/lib/seek.c +++ b/testcode/lib/seek.c @@ -173,6 +173,35 @@ int main(int argc, char **argv) } else { printf("NOT OK, no error\n"); + fclose(file); + return(1); + } + + /* ProDOS on the Apple II only supports 24-bit file offsets, + ** so anything beyond that should be an error. I don't know + ** about other platforms, but I'm guessing no 6502-based + ** operating systems support 32-bit offsets? + */ + printf("seeking to position 2^24:\n\t"); + pos = lseek(fd, 0x1000000L, SEEK_SET); + if (pos == -1) { + printf("Ok, error %s\n", strerror(errno)); + } + else { + printf("NOT OK, returned %ld but expected -1\n", pos); + fclose(file); + return(1); + } + + printf("trying invalid value for whence:\n\t"); + pos = lseek(fd, 0L, 3); + if (pos == -1) { + printf("Ok, error %s\n", strerror(errno)); + } + else { + printf("NOT OK, returned %ld but expected -1\n", pos); + fclose(file); + return(1); } fclose(file); From e335b50ed148659ccf7caff50e1e26c416d09af6 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 20 Aug 2018 16:45:52 +0200 Subject: [PATCH 0818/2161] CMOS optimisation The Lynx CPU always cleared the flag. --- libsrc/lynx/crt0.s | 1 - 1 file changed, 1 deletion(-) diff --git a/libsrc/lynx/crt0.s b/libsrc/lynx/crt0.s index c924f742f..da2162b47 100644 --- a/libsrc/lynx/crt0.s +++ b/libsrc/lynx/crt0.s @@ -47,7 +47,6 @@ MikeyInitData: .byte $9e,$18,$68,$1f,$00,$00,$00,$00,$00,$ff,$1a,$1b,$04,$0d,$2 ; Set up the system. sei - cld ldx #$FF txs From 199226d089e495fa74902167f041b65db712d202 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 20 Aug 2018 16:55:36 +0200 Subject: [PATCH 0819/2161] Update irq.s --- libsrc/lynx/irq.s | 1 - 1 file changed, 1 deletion(-) diff --git a/libsrc/lynx/irq.s b/libsrc/lynx/irq.s index d3b7976e0..515335919 100644 --- a/libsrc/lynx/irq.s +++ b/libsrc/lynx/irq.s @@ -36,7 +36,6 @@ IRQStub: phy phx pha - cld jsr callirq lda INTSET sta INTRST From a76dcdc4193f566bc7f8a3e14dd26d0ed0951074 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 20 Aug 2018 17:51:22 -0400 Subject: [PATCH 0820/2161] Removed the compiler's recovery code for illegal escaped characters. It caused the error cascade that it was supposed to prevent. --- src/cc65/scanner.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index c9009bc2f..90c0f73f6 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -347,16 +347,8 @@ static int ParseChar (void) Error ("Octal character constant out of range"); break; default: - Error ("Illegal character constant"); - C = ' '; - /* Try to do error recovery, otherwise the compiler will spit - ** out thousands of errors in this place and abort. - */ - if (CurC != '\'' && CurC != '\0') { - while (NextC != '\'' && NextC != '\"' && NextC != '\0') { - NextChar (); - } - } + Error ("Illegal escaped character"); + C = CurC; break; } } else { From 3ae5161636cc248e6ccc8eeb81e189f50c8b26f7 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 20 Aug 2018 21:56:16 +0000 Subject: [PATCH 0821/2161] CMOS optimisation 3rd "The decimal flag D is cleared" [...] http://shu.emuunlim.com/download/pcedocs/pce_cpu.html --- libsrc/pce/crt0.s | 1 - 1 file changed, 1 deletion(-) diff --git a/libsrc/pce/crt0.s b/libsrc/pce/crt0.s index 75ffb7f05..c9a8e8c8f 100644 --- a/libsrc/pce/crt0.s +++ b/libsrc/pce/crt0.s @@ -39,7 +39,6 @@ start: nop csh ; Set high speed CPU mode nop - cld nop ; Set up stack and memory mapping From f3ef819b43448617d825cc023dd4003d01986b16 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 21 Aug 2018 09:06:59 +0200 Subject: [PATCH 0822/2161] Update crt0.s --- libsrc/pce/crt0.s | 1 - 1 file changed, 1 deletion(-) diff --git a/libsrc/pce/crt0.s b/libsrc/pce/crt0.s index c9a8e8c8f..16e69fc4d 100644 --- a/libsrc/pce/crt0.s +++ b/libsrc/pce/crt0.s @@ -39,7 +39,6 @@ start: nop csh ; Set high speed CPU mode nop - nop ; Set up stack and memory mapping ldx #$FF ; Stack top ($21FF) From 31461aaf0204aaaf9807008c2bd1a7fde6097f3b Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 21 Aug 2018 08:55:49 -0400 Subject: [PATCH 0823/2161] Made cc65's "Illegal escaped character" diagnostic show which code was escaped. --- 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 90c0f73f6..8605f55a5 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -347,8 +347,8 @@ static int ParseChar (void) Error ("Octal character constant out of range"); break; default: - Error ("Illegal escaped character"); C = CurC; + Error ("Illegal escaped character: 0x%02X", CurC); break; } } else { From 2d4210b3094c7153f6c2cf10a64bff58dc88fd9c Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Fri, 24 Aug 2018 17:04:31 +0200 Subject: [PATCH 0824/2161] Atari5200 joystick driver: enable POT input. The "Atari800" emulator doesn't emulate this aspect, therefore the problem wasn't noticed before. --- libsrc/atari5200/joy/atr5200std.s | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libsrc/atari5200/joy/atr5200std.s b/libsrc/atari5200/joy/atr5200std.s index 041dc6830..002ffdaaf 100644 --- a/libsrc/atari5200/joy/atr5200std.s +++ b/libsrc/atari5200/joy/atr5200std.s @@ -44,6 +44,8 @@ ; INSTALL: + lda #$04 ; enable POT input from the joystick ports, see section "GTIA" in + sta CONSOL ; http://www.atarimuseum.com/videogames/consoles/5200/conv_to_5200.html lda #JOY_ERR_OK ldx #0 ; rts ; Run into UNINSTALL instead From 8b584cb89fe4fa598c3fb16fb7ee215dffa20dea Mon Sep 17 00:00:00 2001 From: Laubzega <mileksmyk@gmail.com> Date: Sat, 25 Aug 2018 10:18:23 -0700 Subject: [PATCH 0825/2161] Add segment type "overlay". --- src/ld65/bin.c | 9 +++++-- src/ld65/config.c | 63 ++++++++++++++++++++++++++++++++++++---------- src/ld65/config.h | 1 + src/ld65/scanner.h | 1 + 4 files changed, 59 insertions(+), 15 deletions(-) diff --git a/src/ld65/bin.c b/src/ld65/bin.c index c3efd9cd1..927719016 100644 --- a/src/ld65/bin.c +++ b/src/ld65/bin.c @@ -193,8 +193,13 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M) NewAddr += M->Start; } if (DoWrite || (M->Flags & MF_FILL) != 0) { - WriteMult (D->F, M->FillVal, NewAddr-Addr); - PrintNumVal ("SF_OFFSET", NewAddr - Addr); + /* Seek back for "overlay" segments */ + if (NewAddr < Addr) { + fseek(D->F, NewAddr - M->Start, SEEK_SET); + } else { + WriteMult (D->F, M->FillVal, NewAddr-Addr); + PrintNumVal ("SF_OFFSET", NewAddr - Addr); + } } Addr = NewAddr; } diff --git a/src/ld65/config.c b/src/ld65/config.c index 5959067b2..f6603d628 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -653,6 +653,7 @@ static void ParseSegments (void) { "RW", CFGTOK_RW }, { "BSS", CFGTOK_BSS }, { "ZP", CFGTOK_ZP }, + { "OVERLAY", CFGTOK_OVERLAY }, }; unsigned Count; @@ -757,6 +758,7 @@ static void ParseSegments (void) case CFGTOK_RW: /* Default */ break; case CFGTOK_BSS: S->Flags |= SF_BSS; break; case CFGTOK_ZP: S->Flags |= (SF_BSS | SF_ZP); break; + case CFGTOK_OVERLAY: S->Flags |= SF_OVERLAY; break; default: Internal ("Unexpected token: %d", CfgTok); } CfgNextTok (); @@ -1795,6 +1797,7 @@ unsigned CfgProcess (void) for (I = 0; I < CollCount (&MemoryAreas); ++I) { unsigned J; unsigned long Addr; + unsigned Overlays = 0; /* Get the next memory area */ MemoryArea* M = CollAtUnchecked (&MemoryAreas, I); @@ -1848,6 +1851,29 @@ unsigned CfgProcess (void) /* Remember the start address before handling this segment */ unsigned long StartAddr = Addr; + /* Take note of overlayed segments and make sure there are no other + ** segment types following them in current memory region. + */ + if (S->Flags & SF_OVERLAY) { + { + if (S->Flags & (SF_OFFSET | SF_START)) { + ++Overlays; + } else { + CfgError (GetSourcePos (M->LI), + "Segment `%s' of type `overlay' requires either" + " `Start' or `Offset' argument to be specified.", + GetString (S->Name)); + } + } + } else { + if (Overlays > 0) { + CfgError (GetSourcePos (M->LI), + "Segment `%s' is preceded by at least one segment" + " of type `overlay'", + GetString (S->Name)); + } + } + /* Some actions depend on whether this is the load or run memory ** area. */ @@ -1896,22 +1922,33 @@ unsigned CfgProcess (void) /* An offset was given, no address, make an address */ NewAddr += M->Start; } - if (NewAddr < Addr) { - /* Offset already too large */ - ++Overflows; - if (S->Flags & SF_OFFSET) { - CfgWarning (GetSourcePos (S->LI), - "Segment `%s' offset is too small in `%s' by %lu byte%c", - GetString (S->Name), GetString (M->Name), - Addr - NewAddr, (Addr - NewAddr == 1) ? ' ' : 's'); + + if (S->Flags & SF_OVERLAY) { + if (NewAddr < M->Start) { + CfgError (GetSourcePos (S->LI), + "Segment `%s' begins before memory area `%s'.", + GetString (S->Name), GetString (M->Name)); } else { - CfgWarning (GetSourcePos (S->LI), - "Segment `%s' start address is too low in `%s' by %lu byte%c", - GetString (S->Name), GetString (M->Name), - Addr - NewAddr, (Addr - NewAddr == 1) ? ' ' : 's'); + Addr = NewAddr; } } else { - Addr = NewAddr; + if (NewAddr < Addr) { + /* Offset already too large */ + ++Overflows; + if (S->Flags & SF_OFFSET) { + CfgWarning (GetSourcePos (S->LI), + "Segment `%s' offset is too small in `%s' by %lu byte%c", + GetString (S->Name), GetString (M->Name), + Addr - NewAddr, (Addr - NewAddr == 1) ? ' ' : 's'); + } else { + CfgWarning (GetSourcePos (S->LI), + "Segment `%s' start address is too low in `%s' by %lu byte%c", + GetString (S->Name), GetString (M->Name), + Addr - NewAddr, (Addr - NewAddr == 1) ? ' ' : 's'); + } + } else { + Addr = NewAddr; + } } } diff --git a/src/ld65/config.h b/src/ld65/config.h index 6a36af6cc..a60580da3 100644 --- a/src/ld65/config.h +++ b/src/ld65/config.h @@ -96,6 +96,7 @@ struct SegDesc { #define SF_RUN_DEF 0x0200 /* RUN symbols already defined */ #define SF_LOAD_DEF 0x0400 /* LOAD symbols already defined */ #define SF_FILLVAL 0x0800 /* Segment has separate fill value */ +#define SF_OVERLAY 0x1000 /* Segment can be overlayed on another one */ diff --git a/src/ld65/scanner.h b/src/ld65/scanner.h index 006ccfceb..e994c0547 100644 --- a/src/ld65/scanner.h +++ b/src/ld65/scanner.h @@ -105,6 +105,7 @@ typedef enum { CFGTOK_RW, CFGTOK_BSS, CFGTOK_ZP, + CFGTOK_OVERLAY, CFGTOK_O65, CFGTOK_BIN, From 1b0e2cf783751a0f3505b1986dcee13bed83db3e Mon Sep 17 00:00:00 2001 From: Laubzega <mileksmyk@gmail.com> Date: Sat, 25 Aug 2018 20:21:12 -0700 Subject: [PATCH 0826/2161] Fix for multiple overlay segments. --- src/ld65/bin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ld65/bin.c b/src/ld65/bin.c index 927719016..f4d241add 100644 --- a/src/ld65/bin.c +++ b/src/ld65/bin.c @@ -193,8 +193,8 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M) NewAddr += M->Start; } if (DoWrite || (M->Flags & MF_FILL) != 0) { - /* Seek back for "overlay" segments */ - if (NewAddr < Addr) { + /* Seek in "overlay" segments */ + if (S->Flags & SF_OVERLAY) { fseek(D->F, NewAddr - M->Start, SEEK_SET); } else { WriteMult (D->F, M->FillVal, NewAddr-Addr); From f2d2f3c1935233cef8a96b5a2b1a88e7d199fb23 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 29 Aug 2018 12:13:58 -0400 Subject: [PATCH 0827/2161] Moved the NES font into its own object module. It can be replaced by a custom font when a program is built. --- libsrc/nes/crt0.s | 25 +- libsrc/nes/{neschar.inc => neschar.s} | 4106 +++++++++++++------------ 2 files changed, 2068 insertions(+), 2063 deletions(-) rename libsrc/nes/{neschar.inc => neschar.s} (51%) diff --git a/libsrc/nes/crt0.s b/libsrc/nes/crt0.s index a380d4dd3..19e97bb12 100644 --- a/libsrc/nes/crt0.s +++ b/libsrc/nes/crt0.s @@ -1,5 +1,5 @@ ; -; Startup code for cc65 (NES version) +; Start-up code for cc65 (NES version) ; ; by Groepaz/Hitmen <groepaz@gmx.net> ; based on code by Ullrich von Bassewitz <uz@cc65.org> @@ -7,11 +7,12 @@ .export _exit .export __STARTUP__ : absolute = 1 ; Mark as startup + .import initlib, donelib, callmain .import push0, _main, zerobss, copydata .import ppubuf_flush - ; Linker generated symbols + ; Linker-generated symbols .import __RAM_START__, __RAM_SIZE__ .import __SRAM_START__, __SRAM_SIZE__ .import __ROM0_START__, __ROM0_SIZE__ @@ -19,12 +20,17 @@ .import __CODE_LOAD__,__CODE_RUN__, __CODE_SIZE__ .import __RODATA_LOAD__,__RODATA_RUN__, __RODATA_SIZE__ +; ------------------------------------------------------------------------ +; Character data +; ------------------------------------------------------------------------ + .forceimport NESfont + .include "zeropage.inc" .include "nes.inc" ; ------------------------------------------------------------------------ -; 16 bytes INES header +; 16-byte INES header .segment "HEADER" @@ -162,8 +168,9 @@ nmi: pha irq: rti + ; ------------------------------------------------------------------------ -; hardware vectors +; Hardware vectors ; ------------------------------------------------------------------------ .segment "VECTORS" @@ -171,13 +178,3 @@ irq: .word nmi ; $fffa vblank nmi .word start ; $fffc reset .word irq ; $fffe irq / brk - -; ------------------------------------------------------------------------ -; character data -; ------------------------------------------------------------------------ - -.segment "CHARS" - - .include "neschar.inc" - - diff --git a/libsrc/nes/neschar.inc b/libsrc/nes/neschar.s similarity index 51% rename from libsrc/nes/neschar.inc rename to libsrc/nes/neschar.s index 15401868c..e3372c031 100644 --- a/libsrc/nes/neschar.inc +++ b/libsrc/nes/neschar.s @@ -1,218 +1,227 @@ - .byte %00000000 ; 0000 1-00: - .byte %00000000 ; 0001 1-00: - .byte %00000000 ; 0002 1-00: - .byte %00000000 ; 0003 1-00: - .byte %00000000 ; 0004 1-00: - .byte %00000000 ; 0005 1-00: - .byte %00000000 ; 0006 1-00: - .byte %00000000 ; 0007 1-00: +; ------------------------------------------------------------------------ +; Character data +; ------------------------------------------------------------------------ - .byte %00000000 ; 0008 1-01: - .byte %00000000 ; 0009 1-01: - .byte %00000000 ; 000A 1-01: - .byte %00000000 ; 000B 1-01: - .byte %00000000 ; 000C 1-01: - .byte %00000000 ; 000D 1-01: - .byte %00000000 ; 000E 1-01: - .byte %00000000 ; 000F 1-01: + .export NESfont - .byte %11001100 ; 0010 1-02: ** ** - .byte %11001100 ; 0011 1-02: ** ** +.segment "CHARS" + +NESfont: + .byte %00000000 ; 0000 1-00: + .byte %00000000 ; 0001 1-00: + .byte %00000000 ; 0002 1-00: + .byte %00000000 ; 0003 1-00: + .byte %00000000 ; 0004 1-00: + .byte %00000000 ; 0005 1-00: + .byte %00000000 ; 0006 1-00: + .byte %00000000 ; 0007 1-00: + + .byte %00000000 ; 0008 1-01: + .byte %00000000 ; 0009 1-01: + .byte %00000000 ; 000A 1-01: + .byte %00000000 ; 000B 1-01: + .byte %00000000 ; 000C 1-01: + .byte %00000000 ; 000D 1-01: + .byte %00000000 ; 000E 1-01: + .byte %00000000 ; 000F 1-01: + + .byte %11001100 ; 0010 1-02: ** ** + .byte %11001100 ; 0011 1-02: ** ** .byte %00110011 ; 0012 1-02: ** ** .byte %00110011 ; 0013 1-02: ** ** - .byte %11001100 ; 0014 1-02: ** ** - .byte %11001100 ; 0015 1-02: ** ** + .byte %11001100 ; 0014 1-02: ** ** + .byte %11001100 ; 0015 1-02: ** ** .byte %00110011 ; 0016 1-02: ** ** .byte %00110011 ; 0017 1-02: ** ** - .byte %11001100 ; 0018 1-03: ** ** - .byte %11001100 ; 0019 1-03: ** ** + .byte %11001100 ; 0018 1-03: ** ** + .byte %11001100 ; 0019 1-03: ** ** .byte %00110011 ; 001A 1-03: ** ** .byte %00110011 ; 001B 1-03: ** ** - .byte %11001100 ; 001C 1-03: ** ** - .byte %11001100 ; 001D 1-03: ** ** + .byte %11001100 ; 001C 1-03: ** ** + .byte %11001100 ; 001D 1-03: ** ** .byte %00110011 ; 001E 1-03: ** ** .byte %00110011 ; 001F 1-03: ** ** - .byte %00000000 ; 0020 1-04: - .byte %00011000 ; 0021 1-04: ** - .byte %00111100 ; 0022 1-04: **** - .byte %01111110 ; 0023 1-04: ****** - .byte %00011000 ; 0024 1-04: ** - .byte %00011000 ; 0025 1-04: ** - .byte %00011000 ; 0026 1-04: ** - .byte %00011000 ; 0027 1-04: ** + .byte %00000000 ; 0020 1-04: + .byte %00011000 ; 0021 1-04: ** + .byte %00111100 ; 0022 1-04: **** + .byte %01111110 ; 0023 1-04: ****** + .byte %00011000 ; 0024 1-04: ** + .byte %00011000 ; 0025 1-04: ** + .byte %00011000 ; 0026 1-04: ** + .byte %00011000 ; 0027 1-04: ** - .byte %00000000 ; 0028 1-05: - .byte %00011000 ; 0029 1-05: ** - .byte %00111100 ; 002A 1-05: **** - .byte %01111110 ; 002B 1-05: ****** - .byte %00011000 ; 002C 1-05: ** - .byte %00011000 ; 002D 1-05: ** - .byte %00011000 ; 002E 1-05: ** - .byte %00011000 ; 002F 1-05: ** + .byte %00000000 ; 0028 1-05: + .byte %00011000 ; 0029 1-05: ** + .byte %00111100 ; 002A 1-05: **** + .byte %01111110 ; 002B 1-05: ****** + .byte %00011000 ; 002C 1-05: ** + .byte %00011000 ; 002D 1-05: ** + .byte %00011000 ; 002E 1-05: ** + .byte %00011000 ; 002F 1-05: ** - .byte %00000000 ; 0030 1-06: - .byte %00010000 ; 0031 1-06: * - .byte %00110000 ; 0032 1-06: ** + .byte %00000000 ; 0030 1-06: + .byte %00010000 ; 0031 1-06: * + .byte %00110000 ; 0032 1-06: ** .byte %01111111 ; 0033 1-06: ******* .byte %01111111 ; 0034 1-06: ******* - .byte %00110000 ; 0035 1-06: ** - .byte %00010000 ; 0036 1-06: * - .byte %00000000 ; 0037 1-06: + .byte %00110000 ; 0035 1-06: ** + .byte %00010000 ; 0036 1-06: * + .byte %00000000 ; 0037 1-06: - .byte %00000000 ; 0038 1-07: - .byte %00010000 ; 0039 1-07: * - .byte %00110000 ; 003A 1-07: ** + .byte %00000000 ; 0038 1-07: + .byte %00010000 ; 0039 1-07: * + .byte %00110000 ; 003A 1-07: ** .byte %01111111 ; 003B 1-07: ******* .byte %01111111 ; 003C 1-07: ******* - .byte %00110000 ; 003D 1-07: ** - .byte %00010000 ; 003E 1-07: * - .byte %00000000 ; 003F 1-07: + .byte %00110000 ; 003D 1-07: ** + .byte %00010000 ; 003E 1-07: * + .byte %00000000 ; 003F 1-07: - .byte %00001100 ; 0040 1-08: ** - .byte %00010010 ; 0041 1-08: * * - .byte %00110000 ; 0042 1-08: ** - .byte %01111100 ; 0043 1-08: ***** - .byte %00110000 ; 0044 1-08: ** - .byte %01100010 ; 0045 1-08: ** * - .byte %11111100 ; 0046 1-08: ****** - .byte %00000000 ; 0047 1-08: + .byte %00001100 ; 0040 1-08: ** + .byte %00010010 ; 0041 1-08: * * + .byte %00110000 ; 0042 1-08: ** + .byte %01111100 ; 0043 1-08: ***** + .byte %00110000 ; 0044 1-08: ** + .byte %01100010 ; 0045 1-08: ** * + .byte %11111100 ; 0046 1-08: ****** + .byte %00000000 ; 0047 1-08: - .byte %00001100 ; 0048 1-09: ** - .byte %00010010 ; 0049 1-09: * * - .byte %00110000 ; 004A 1-09: ** - .byte %01111100 ; 004B 1-09: ***** - .byte %00110000 ; 004C 1-09: ** - .byte %01100010 ; 004D 1-09: ** * - .byte %11111100 ; 004E 1-09: ****** - .byte %00000000 ; 004F 1-09: + .byte %00001100 ; 0048 1-09: ** + .byte %00010010 ; 0049 1-09: * * + .byte %00110000 ; 004A 1-09: ** + .byte %01111100 ; 004B 1-09: ***** + .byte %00110000 ; 004C 1-09: ** + .byte %01100010 ; 004D 1-09: ** * + .byte %11111100 ; 004E 1-09: ****** + .byte %00000000 ; 004F 1-09: - .byte %00000000 ; 0050 1-0a: - .byte %00000000 ; 0051 1-0a: + .byte %00000000 ; 0050 1-0a: + .byte %00000000 ; 0051 1-0a: .byte %00000011 ; 0052 1-0a: ** - .byte %00111110 ; 0053 1-0a: ***** - .byte %01110110 ; 0054 1-0a: *** ** - .byte %00110110 ; 0055 1-0a: ** ** - .byte %00110110 ; 0056 1-0a: ** ** - .byte %00000000 ; 0057 1-0a: + .byte %00111110 ; 0053 1-0a: ***** + .byte %01110110 ; 0054 1-0a: *** ** + .byte %00110110 ; 0055 1-0a: ** ** + .byte %00110110 ; 0056 1-0a: ** ** + .byte %00000000 ; 0057 1-0a: - .byte %00000000 ; 0058 1-0b: - .byte %00000000 ; 0059 1-0b: + .byte %00000000 ; 0058 1-0b: + .byte %00000000 ; 0059 1-0b: .byte %00000011 ; 005A 1-0b: ** - .byte %00111110 ; 005B 1-0b: ***** - .byte %01110110 ; 005C 1-0b: *** ** - .byte %00110110 ; 005D 1-0b: ** ** - .byte %00110110 ; 005E 1-0b: ** ** - .byte %00000000 ; 005F 1-0b: + .byte %00111110 ; 005B 1-0b: ***** + .byte %01110110 ; 005C 1-0b: *** ** + .byte %00110110 ; 005D 1-0b: ** ** + .byte %00110110 ; 005E 1-0b: ** ** + .byte %00000000 ; 005F 1-0b: .byte %01111111 ; 0060 1-0c: ******* .byte %01111111 ; 0061 1-0c: ******* - .byte %00000000 ; 0062 1-0c: - .byte %00000000 ; 0063 1-0c: - .byte %00000000 ; 0064 1-0c: - .byte %00000000 ; 0065 1-0c: - .byte %00000000 ; 0066 1-0c: - .byte %00000000 ; 0067 1-0c: + .byte %00000000 ; 0062 1-0c: + .byte %00000000 ; 0063 1-0c: + .byte %00000000 ; 0064 1-0c: + .byte %00000000 ; 0065 1-0c: + .byte %00000000 ; 0066 1-0c: + .byte %00000000 ; 0067 1-0c: .byte %01111111 ; 0068 1-0d: ******* .byte %01111111 ; 0069 1-0d: ******* - .byte %00000000 ; 006A 1-0d: - .byte %00000000 ; 006B 1-0d: - .byte %00000000 ; 006C 1-0d: - .byte %00000000 ; 006D 1-0d: - .byte %00000000 ; 006E 1-0d: - .byte %00000000 ; 006F 1-0d: + .byte %00000000 ; 006A 1-0d: + .byte %00000000 ; 006B 1-0d: + .byte %00000000 ; 006C 1-0d: + .byte %00000000 ; 006D 1-0d: + .byte %00000000 ; 006E 1-0d: + .byte %00000000 ; 006F 1-0d: - .byte %11100000 ; 0070 1-0e: *** - .byte %11100000 ; 0071 1-0e: *** - .byte %01100000 ; 0072 1-0e: ** - .byte %01100000 ; 0073 1-0e: ** - .byte %01100000 ; 0074 1-0e: ** - .byte %01100000 ; 0075 1-0e: ** - .byte %01100000 ; 0076 1-0e: ** - .byte %01100000 ; 0077 1-0e: ** + .byte %11100000 ; 0070 1-0e: *** + .byte %11100000 ; 0071 1-0e: *** + .byte %01100000 ; 0072 1-0e: ** + .byte %01100000 ; 0073 1-0e: ** + .byte %01100000 ; 0074 1-0e: ** + .byte %01100000 ; 0075 1-0e: ** + .byte %01100000 ; 0076 1-0e: ** + .byte %01100000 ; 0077 1-0e: ** - .byte %11100000 ; 0078 1-0f: *** - .byte %11100000 ; 0079 1-0f: *** - .byte %01100000 ; 007A 1-0f: ** - .byte %01100000 ; 007B 1-0f: ** - .byte %01100000 ; 007C 1-0f: ** - .byte %01100000 ; 007D 1-0f: ** - .byte %01100000 ; 007E 1-0f: ** - .byte %01100000 ; 007F 1-0f: ** + .byte %11100000 ; 0078 1-0f: *** + .byte %11100000 ; 0079 1-0f: *** + .byte %01100000 ; 007A 1-0f: ** + .byte %01100000 ; 007B 1-0f: ** + .byte %01100000 ; 007C 1-0f: ** + .byte %01100000 ; 007D 1-0f: ** + .byte %01100000 ; 007E 1-0f: ** + .byte %01100000 ; 007F 1-0f: ** - .byte %00011000 ; 0080 1-10: ** - .byte %00011000 ; 0081 1-10: ** - .byte %00011000 ; 0082 1-10: ** - .byte %11111000 ; 0083 1-10: ***** - .byte %11111000 ; 0084 1-10: ***** - .byte %00000000 ; 0085 1-10: - .byte %00000000 ; 0086 1-10: - .byte %00000000 ; 0087 1-10: + .byte %00011000 ; 0080 1-10: ** + .byte %00011000 ; 0081 1-10: ** + .byte %00011000 ; 0082 1-10: ** + .byte %11111000 ; 0083 1-10: ***** + .byte %11111000 ; 0084 1-10: ***** + .byte %00000000 ; 0085 1-10: + .byte %00000000 ; 0086 1-10: + .byte %00000000 ; 0087 1-10: - .byte %00011000 ; 0088 1-11: ** - .byte %00011000 ; 0089 1-11: ** - .byte %00011000 ; 008A 1-11: ** - .byte %11111000 ; 008B 1-11: ***** - .byte %11111000 ; 008C 1-11: ***** - .byte %00000000 ; 008D 1-11: - .byte %00000000 ; 008E 1-11: - .byte %00000000 ; 008F 1-11: + .byte %00011000 ; 0088 1-11: ** + .byte %00011000 ; 0089 1-11: ** + .byte %00011000 ; 008A 1-11: ** + .byte %11111000 ; 008B 1-11: ***** + .byte %11111000 ; 008C 1-11: ***** + .byte %00000000 ; 008D 1-11: + .byte %00000000 ; 008E 1-11: + .byte %00000000 ; 008F 1-11: - .byte %11001100 ; 0090 1-12: ** ** + .byte %11001100 ; 0090 1-12: ** ** .byte %10011001 ; 0091 1-12: * ** * .byte %00110011 ; 0092 1-12: ** ** - .byte %01100110 ; 0093 1-12: ** ** - .byte %11001100 ; 0094 1-12: ** ** + .byte %01100110 ; 0093 1-12: ** ** + .byte %11001100 ; 0094 1-12: ** ** .byte %10011001 ; 0095 1-12: * ** * .byte %00110011 ; 0096 1-12: ** ** - .byte %01100110 ; 0097 1-12: ** ** + .byte %01100110 ; 0097 1-12: ** ** - .byte %11001100 ; 0098 1-13: ** ** + .byte %11001100 ; 0098 1-13: ** ** .byte %10011001 ; 0099 1-13: * ** * .byte %00110011 ; 009A 1-13: ** ** - .byte %01100110 ; 009B 1-13: ** ** - .byte %11001100 ; 009C 1-13: ** ** + .byte %01100110 ; 009B 1-13: ** ** + .byte %11001100 ; 009C 1-13: ** ** .byte %10011001 ; 009D 1-13: * ** * .byte %00110011 ; 009E 1-13: ** ** - .byte %01100110 ; 009F 1-13: ** ** + .byte %01100110 ; 009F 1-13: ** ** .byte %00110011 ; 00A0 1-14: ** ** .byte %10011001 ; 00A1 1-14: * ** * - .byte %11001100 ; 00A2 1-14: ** ** - .byte %01100110 ; 00A3 1-14: ** ** + .byte %11001100 ; 00A2 1-14: ** ** + .byte %01100110 ; 00A3 1-14: ** ** .byte %00110011 ; 00A4 1-14: ** ** .byte %10011001 ; 00A5 1-14: * ** * - .byte %11001100 ; 00A6 1-14: ** ** - .byte %01100110 ; 00A7 1-14: ** ** + .byte %11001100 ; 00A6 1-14: ** ** + .byte %01100110 ; 00A7 1-14: ** ** .byte %00110011 ; 00A8 1-15: ** ** .byte %10011001 ; 00A9 1-15: * ** * - .byte %11001100 ; 00AA 1-15: ** ** - .byte %01100110 ; 00AB 1-15: ** ** + .byte %11001100 ; 00AA 1-15: ** ** + .byte %01100110 ; 00AB 1-15: ** ** .byte %00110011 ; 00AC 1-15: ** ** .byte %10011001 ; 00AD 1-15: * ** * - .byte %11001100 ; 00AE 1-15: ** ** - .byte %01100110 ; 00AF 1-15: ** ** + .byte %11001100 ; 00AE 1-15: ** ** + .byte %01100110 ; 00AF 1-15: ** ** - .byte %00000000 ; 00B0 1-16: - .byte %00000000 ; 00B1 1-16: - .byte %00000000 ; 00B2 1-16: + .byte %00000000 ; 00B0 1-16: + .byte %00000000 ; 00B1 1-16: + .byte %00000000 ; 00B2 1-16: .byte %11111111 ; 00B3 1-16: ******** .byte %11111111 ; 00B4 1-16: ******** - .byte %00000000 ; 00B5 1-16: - .byte %00000000 ; 00B6 1-16: - .byte %00000000 ; 00B7 1-16: + .byte %00000000 ; 00B5 1-16: + .byte %00000000 ; 00B6 1-16: + .byte %00000000 ; 00B7 1-16: - .byte %00000000 ; 00B8 1-17: - .byte %00000000 ; 00B9 1-17: - .byte %00000000 ; 00BA 1-17: + .byte %00000000 ; 00B8 1-17: + .byte %00000000 ; 00B9 1-17: + .byte %00000000 ; 00BA 1-17: .byte %11111111 ; 00BB 1-17: ******** .byte %11111111 ; 00BC 1-17: ******** - .byte %00000000 ; 00BD 1-17: - .byte %00000000 ; 00BE 1-17: - .byte %00000000 ; 00BF 1-17: + .byte %00000000 ; 00BD 1-17: + .byte %00000000 ; 00BE 1-17: + .byte %00000000 ; 00BF 1-17: .byte %00000011 ; 00C0 1-18: ** .byte %00000011 ; 00C1 1-18: ** @@ -232,1157 +241,1157 @@ .byte %00000011 ; 00CE 1-19: ** .byte %00000011 ; 00CF 1-19: ** - .byte %00000000 ; 00D0 1-1a: - .byte %00000000 ; 00D1 1-1a: - .byte %00000000 ; 00D2 1-1a: - .byte %00000000 ; 00D3 1-1a: - .byte %11001100 ; 00D4 1-1a: ** ** - .byte %11001100 ; 00D5 1-1a: ** ** + .byte %00000000 ; 00D0 1-1a: + .byte %00000000 ; 00D1 1-1a: + .byte %00000000 ; 00D2 1-1a: + .byte %00000000 ; 00D3 1-1a: + .byte %11001100 ; 00D4 1-1a: ** ** + .byte %11001100 ; 00D5 1-1a: ** ** .byte %00110011 ; 00D6 1-1a: ** ** .byte %00110011 ; 00D7 1-1a: ** ** - .byte %00000000 ; 00D8 1-1b: - .byte %00000000 ; 00D9 1-1b: - .byte %00000000 ; 00DA 1-1b: - .byte %00000000 ; 00DB 1-1b: - .byte %11001100 ; 00DC 1-1b: ** ** - .byte %11001100 ; 00DD 1-1b: ** ** + .byte %00000000 ; 00D8 1-1b: + .byte %00000000 ; 00D9 1-1b: + .byte %00000000 ; 00DA 1-1b: + .byte %00000000 ; 00DB 1-1b: + .byte %11001100 ; 00DC 1-1b: ** ** + .byte %11001100 ; 00DD 1-1b: ** ** .byte %00110011 ; 00DE 1-1b: ** ** .byte %00110011 ; 00DF 1-1b: ** ** - .byte %00011000 ; 00E0 1-1c: ** - .byte %00011000 ; 00E1 1-1c: ** - .byte %00011000 ; 00E2 1-1c: ** - .byte %00011000 ; 00E3 1-1c: ** - .byte %00011000 ; 00E4 1-1c: ** - .byte %00011000 ; 00E5 1-1c: ** - .byte %00011000 ; 00E6 1-1c: ** - .byte %00011000 ; 00E7 1-1c: ** + .byte %00011000 ; 00E0 1-1c: ** + .byte %00011000 ; 00E1 1-1c: ** + .byte %00011000 ; 00E2 1-1c: ** + .byte %00011000 ; 00E3 1-1c: ** + .byte %00011000 ; 00E4 1-1c: ** + .byte %00011000 ; 00E5 1-1c: ** + .byte %00011000 ; 00E6 1-1c: ** + .byte %00011000 ; 00E7 1-1c: ** - .byte %00011000 ; 00E8 1-1d: ** - .byte %00011000 ; 00E9 1-1d: ** - .byte %00011000 ; 00EA 1-1d: ** - .byte %00011000 ; 00EB 1-1d: ** - .byte %00011000 ; 00EC 1-1d: ** - .byte %00011000 ; 00ED 1-1d: ** - .byte %00011000 ; 00EE 1-1d: ** - .byte %00011000 ; 00EF 1-1d: ** + .byte %00011000 ; 00E8 1-1d: ** + .byte %00011000 ; 00E9 1-1d: ** + .byte %00011000 ; 00EA 1-1d: ** + .byte %00011000 ; 00EB 1-1d: ** + .byte %00011000 ; 00EC 1-1d: ** + .byte %00011000 ; 00ED 1-1d: ** + .byte %00011000 ; 00EE 1-1d: ** + .byte %00011000 ; 00EF 1-1d: ** - .byte %00011000 ; 00F0 1-1e: ** - .byte %00011000 ; 00F1 1-1e: ** - .byte %00011000 ; 00F2 1-1e: ** + .byte %00011000 ; 00F0 1-1e: ** + .byte %00011000 ; 00F1 1-1e: ** + .byte %00011000 ; 00F2 1-1e: ** .byte %00011111 ; 00F3 1-1e: ***** .byte %00011111 ; 00F4 1-1e: ***** - .byte %00011000 ; 00F5 1-1e: ** - .byte %00011000 ; 00F6 1-1e: ** - .byte %00011000 ; 00F7 1-1e: ** + .byte %00011000 ; 00F5 1-1e: ** + .byte %00011000 ; 00F6 1-1e: ** + .byte %00011000 ; 00F7 1-1e: ** - .byte %00011000 ; 00F8 1-1f: ** - .byte %00011000 ; 00F9 1-1f: ** - .byte %00011000 ; 00FA 1-1f: ** + .byte %00011000 ; 00F8 1-1f: ** + .byte %00011000 ; 00F9 1-1f: ** + .byte %00011000 ; 00FA 1-1f: ** .byte %00011111 ; 00FB 1-1f: ***** .byte %00011111 ; 00FC 1-1f: ***** - .byte %00011000 ; 00FD 1-1f: ** - .byte %00011000 ; 00FE 1-1f: ** - .byte %00011000 ; 00FF 1-1f: ** + .byte %00011000 ; 00FD 1-1f: ** + .byte %00011000 ; 00FE 1-1f: ** + .byte %00011000 ; 00FF 1-1f: ** - .byte %00011000 ; 0100 1-20: ** - .byte %00011000 ; 0101 1-20: ** - .byte %00011000 ; 0102 1-20: ** + .byte %00011000 ; 0100 1-20: ** + .byte %00011000 ; 0101 1-20: ** + .byte %00011000 ; 0102 1-20: ** .byte %11111111 ; 0103 1-20: ******** .byte %11111111 ; 0104 1-20: ******** - .byte %00011000 ; 0105 1-20: ** - .byte %00011000 ; 0106 1-20: ** - .byte %00011000 ; 0107 1-20: ** + .byte %00011000 ; 0105 1-20: ** + .byte %00011000 ; 0106 1-20: ** + .byte %00011000 ; 0107 1-20: ** - .byte %00011000 ; 0108 1-21: ** - .byte %00011000 ; 0109 1-21: ** - .byte %00011000 ; 010A 1-21: ** + .byte %00011000 ; 0108 1-21: ** + .byte %00011000 ; 0109 1-21: ** + .byte %00011000 ; 010A 1-21: ** .byte %11111111 ; 010B 1-21: ******** .byte %11111111 ; 010C 1-21: ******** - .byte %00011000 ; 010D 1-21: ** - .byte %00011000 ; 010E 1-21: ** - .byte %00011000 ; 010F 1-21: ** + .byte %00011000 ; 010D 1-21: ** + .byte %00011000 ; 010E 1-21: ** + .byte %00011000 ; 010F 1-21: ** - .byte %00011000 ; 0110 1-22: ** - .byte %00011000 ; 0111 1-22: ** - .byte %00011000 ; 0112 1-22: ** + .byte %00011000 ; 0110 1-22: ** + .byte %00011000 ; 0111 1-22: ** + .byte %00011000 ; 0112 1-22: ** .byte %00011111 ; 0113 1-22: ***** .byte %00011111 ; 0114 1-22: ***** - .byte %00000000 ; 0115 1-22: - .byte %00000000 ; 0116 1-22: - .byte %00000000 ; 0117 1-22: + .byte %00000000 ; 0115 1-22: + .byte %00000000 ; 0116 1-22: + .byte %00000000 ; 0117 1-22: - .byte %00011000 ; 0118 1-23: ** - .byte %00011000 ; 0119 1-23: ** - .byte %00011000 ; 011A 1-23: ** + .byte %00011000 ; 0118 1-23: ** + .byte %00011000 ; 0119 1-23: ** + .byte %00011000 ; 011A 1-23: ** .byte %00011111 ; 011B 1-23: ***** .byte %00011111 ; 011C 1-23: ***** - .byte %00000000 ; 011D 1-23: - .byte %00000000 ; 011E 1-23: - .byte %00000000 ; 011F 1-23: + .byte %00000000 ; 011D 1-23: + .byte %00000000 ; 011E 1-23: + .byte %00000000 ; 011F 1-23: - .byte %00000000 ; 0120 1-24: - .byte %00000000 ; 0121 1-24: - .byte %00000000 ; 0122 1-24: - .byte %11111000 ; 0123 1-24: ***** - .byte %11111000 ; 0124 1-24: ***** - .byte %00011000 ; 0125 1-24: ** - .byte %00011000 ; 0126 1-24: ** - .byte %00011000 ; 0127 1-24: ** + .byte %00000000 ; 0120 1-24: + .byte %00000000 ; 0121 1-24: + .byte %00000000 ; 0122 1-24: + .byte %11111000 ; 0123 1-24: ***** + .byte %11111000 ; 0124 1-24: ***** + .byte %00011000 ; 0125 1-24: ** + .byte %00011000 ; 0126 1-24: ** + .byte %00011000 ; 0127 1-24: ** - .byte %00000000 ; 0128 1-25: - .byte %00000000 ; 0129 1-25: - .byte %00000000 ; 012A 1-25: - .byte %11111000 ; 012B 1-25: ***** - .byte %11111000 ; 012C 1-25: ***** - .byte %00011000 ; 012D 1-25: ** - .byte %00011000 ; 012E 1-25: ** - .byte %00011000 ; 012F 1-25: ** + .byte %00000000 ; 0128 1-25: + .byte %00000000 ; 0129 1-25: + .byte %00000000 ; 012A 1-25: + .byte %11111000 ; 012B 1-25: ***** + .byte %11111000 ; 012C 1-25: ***** + .byte %00011000 ; 012D 1-25: ** + .byte %00011000 ; 012E 1-25: ** + .byte %00011000 ; 012F 1-25: ** - .byte %00000000 ; 0130 1-26: - .byte %00000000 ; 0131 1-26: - .byte %00000000 ; 0132 1-26: - .byte %00000000 ; 0133 1-26: - .byte %00000000 ; 0134 1-26: - .byte %00000000 ; 0135 1-26: + .byte %00000000 ; 0130 1-26: + .byte %00000000 ; 0131 1-26: + .byte %00000000 ; 0132 1-26: + .byte %00000000 ; 0133 1-26: + .byte %00000000 ; 0134 1-26: + .byte %00000000 ; 0135 1-26: .byte %11111111 ; 0136 1-26: ******** .byte %11111111 ; 0137 1-26: ******** - .byte %00000000 ; 0138 1-27: - .byte %00000000 ; 0139 1-27: - .byte %00000000 ; 013A 1-27: - .byte %00000000 ; 013B 1-27: - .byte %00000000 ; 013C 1-27: - .byte %00000000 ; 013D 1-27: + .byte %00000000 ; 0138 1-27: + .byte %00000000 ; 0139 1-27: + .byte %00000000 ; 013A 1-27: + .byte %00000000 ; 013B 1-27: + .byte %00000000 ; 013C 1-27: + .byte %00000000 ; 013D 1-27: .byte %11111111 ; 013E 1-27: ******** .byte %11111111 ; 013F 1-27: ******** - .byte %00000000 ; 0140 1-28: - .byte %00000000 ; 0141 1-28: - .byte %00000000 ; 0142 1-28: + .byte %00000000 ; 0140 1-28: + .byte %00000000 ; 0141 1-28: + .byte %00000000 ; 0142 1-28: .byte %00011111 ; 0143 1-28: ***** .byte %00011111 ; 0144 1-28: ***** - .byte %00011000 ; 0145 1-28: ** - .byte %00011000 ; 0146 1-28: ** - .byte %00011000 ; 0147 1-28: ** + .byte %00011000 ; 0145 1-28: ** + .byte %00011000 ; 0146 1-28: ** + .byte %00011000 ; 0147 1-28: ** - .byte %00000000 ; 0148 1-29: - .byte %00000000 ; 0149 1-29: - .byte %00000000 ; 014A 1-29: + .byte %00000000 ; 0148 1-29: + .byte %00000000 ; 0149 1-29: + .byte %00000000 ; 014A 1-29: .byte %00011111 ; 014B 1-29: ***** .byte %00011111 ; 014C 1-29: ***** - .byte %00011000 ; 014D 1-29: ** - .byte %00011000 ; 014E 1-29: ** - .byte %00011000 ; 014F 1-29: ** + .byte %00011000 ; 014D 1-29: ** + .byte %00011000 ; 014E 1-29: ** + .byte %00011000 ; 014F 1-29: ** - .byte %00011000 ; 0150 1-2a: ** - .byte %00011000 ; 0151 1-2a: ** - .byte %00011000 ; 0152 1-2a: ** + .byte %00011000 ; 0150 1-2a: ** + .byte %00011000 ; 0151 1-2a: ** + .byte %00011000 ; 0152 1-2a: ** .byte %11111111 ; 0153 1-2a: ******** .byte %11111111 ; 0154 1-2a: ******** - .byte %00000000 ; 0155 1-2a: - .byte %00000000 ; 0156 1-2a: - .byte %00000000 ; 0157 1-2a: + .byte %00000000 ; 0155 1-2a: + .byte %00000000 ; 0156 1-2a: + .byte %00000000 ; 0157 1-2a: - .byte %00011000 ; 0158 1-2b: ** - .byte %00011000 ; 0159 1-2b: ** - .byte %00011000 ; 015A 1-2b: ** + .byte %00011000 ; 0158 1-2b: ** + .byte %00011000 ; 0159 1-2b: ** + .byte %00011000 ; 015A 1-2b: ** .byte %11111111 ; 015B 1-2b: ******** .byte %11111111 ; 015C 1-2b: ******** - .byte %00000000 ; 015D 1-2b: - .byte %00000000 ; 015E 1-2b: - .byte %00000000 ; 015F 1-2b: + .byte %00000000 ; 015D 1-2b: + .byte %00000000 ; 015E 1-2b: + .byte %00000000 ; 015F 1-2b: - .byte %00000000 ; 0160 1-2c: - .byte %00000000 ; 0161 1-2c: - .byte %00000000 ; 0162 1-2c: + .byte %00000000 ; 0160 1-2c: + .byte %00000000 ; 0161 1-2c: + .byte %00000000 ; 0162 1-2c: .byte %11111111 ; 0163 1-2c: ******** .byte %11111111 ; 0164 1-2c: ******** - .byte %00011000 ; 0165 1-2c: ** - .byte %00011000 ; 0166 1-2c: ** - .byte %00011000 ; 0167 1-2c: ** + .byte %00011000 ; 0165 1-2c: ** + .byte %00011000 ; 0166 1-2c: ** + .byte %00011000 ; 0167 1-2c: ** - .byte %00000000 ; 0168 1-2d: - .byte %00000000 ; 0169 1-2d: - .byte %00000000 ; 016A 1-2d: + .byte %00000000 ; 0168 1-2d: + .byte %00000000 ; 0169 1-2d: + .byte %00000000 ; 016A 1-2d: .byte %11111111 ; 016B 1-2d: ******** .byte %11111111 ; 016C 1-2d: ******** - .byte %00011000 ; 016D 1-2d: ** - .byte %00011000 ; 016E 1-2d: ** - .byte %00011000 ; 016F 1-2d: ** + .byte %00011000 ; 016D 1-2d: ** + .byte %00011000 ; 016E 1-2d: ** + .byte %00011000 ; 016F 1-2d: ** - .byte %00011000 ; 0170 1-2e: ** - .byte %00011000 ; 0171 1-2e: ** - .byte %00011000 ; 0172 1-2e: ** - .byte %11111000 ; 0173 1-2e: ***** - .byte %11111000 ; 0174 1-2e: ***** - .byte %00011000 ; 0175 1-2e: ** - .byte %00011000 ; 0176 1-2e: ** - .byte %00011000 ; 0177 1-2e: ** + .byte %00011000 ; 0170 1-2e: ** + .byte %00011000 ; 0171 1-2e: ** + .byte %00011000 ; 0172 1-2e: ** + .byte %11111000 ; 0173 1-2e: ***** + .byte %11111000 ; 0174 1-2e: ***** + .byte %00011000 ; 0175 1-2e: ** + .byte %00011000 ; 0176 1-2e: ** + .byte %00011000 ; 0177 1-2e: ** - .byte %00011000 ; 0178 1-2f: ** - .byte %00011000 ; 0179 1-2f: ** - .byte %00011000 ; 017A 1-2f: ** - .byte %11111000 ; 017B 1-2f: ***** - .byte %11111000 ; 017C 1-2f: ***** - .byte %00011000 ; 017D 1-2f: ** - .byte %00011000 ; 017E 1-2f: ** - .byte %00011000 ; 017F 1-2f: ** + .byte %00011000 ; 0178 1-2f: ** + .byte %00011000 ; 0179 1-2f: ** + .byte %00011000 ; 017A 1-2f: ** + .byte %11111000 ; 017B 1-2f: ***** + .byte %11111000 ; 017C 1-2f: ***** + .byte %00011000 ; 017D 1-2f: ** + .byte %00011000 ; 017E 1-2f: ** + .byte %00011000 ; 017F 1-2f: ** - .byte %11110000 ; 0180 1-30: **** - .byte %11110000 ; 0181 1-30: **** - .byte %11110000 ; 0182 1-30: **** - .byte %11110000 ; 0183 1-30: **** - .byte %11110000 ; 0184 1-30: **** - .byte %11110000 ; 0185 1-30: **** - .byte %11110000 ; 0186 1-30: **** - .byte %11110000 ; 0187 1-30: **** + .byte %11110000 ; 0180 1-30: **** + .byte %11110000 ; 0181 1-30: **** + .byte %11110000 ; 0182 1-30: **** + .byte %11110000 ; 0183 1-30: **** + .byte %11110000 ; 0184 1-30: **** + .byte %11110000 ; 0185 1-30: **** + .byte %11110000 ; 0186 1-30: **** + .byte %11110000 ; 0187 1-30: **** - .byte %11110000 ; 0188 1-31: **** - .byte %11110000 ; 0189 1-31: **** - .byte %11110000 ; 018A 1-31: **** - .byte %11110000 ; 018B 1-31: **** - .byte %11110000 ; 018C 1-31: **** - .byte %11110000 ; 018D 1-31: **** - .byte %11110000 ; 018E 1-31: **** - .byte %11110000 ; 018F 1-31: **** + .byte %11110000 ; 0188 1-31: **** + .byte %11110000 ; 0189 1-31: **** + .byte %11110000 ; 018A 1-31: **** + .byte %11110000 ; 018B 1-31: **** + .byte %11110000 ; 018C 1-31: **** + .byte %11110000 ; 018D 1-31: **** + .byte %11110000 ; 018E 1-31: **** + .byte %11110000 ; 018F 1-31: **** - .byte %00000000 ; 0190 1-32: - .byte %00000000 ; 0191 1-32: - .byte %00000000 ; 0192 1-32: - .byte %00000000 ; 0193 1-32: + .byte %00000000 ; 0190 1-32: + .byte %00000000 ; 0191 1-32: + .byte %00000000 ; 0192 1-32: + .byte %00000000 ; 0193 1-32: .byte %11111111 ; 0194 1-32: ******** .byte %11111111 ; 0195 1-32: ******** .byte %11111111 ; 0196 1-32: ******** .byte %11111111 ; 0197 1-32: ******** - .byte %00000000 ; 0198 1-33: - .byte %00000000 ; 0199 1-33: - .byte %00000000 ; 019A 1-33: - .byte %00000000 ; 019B 1-33: + .byte %00000000 ; 0198 1-33: + .byte %00000000 ; 0199 1-33: + .byte %00000000 ; 019A 1-33: + .byte %00000000 ; 019B 1-33: .byte %11111111 ; 019C 1-33: ******** .byte %11111111 ; 019D 1-33: ******** .byte %11111111 ; 019E 1-33: ******** .byte %11111111 ; 019F 1-33: ******** - .byte %00000000 ; 01A0 1-34: - .byte %00000000 ; 01A1 1-34: - .byte %00000000 ; 01A2 1-34: - .byte %00000000 ; 01A3 1-34: - .byte %11110000 ; 01A4 1-34: **** - .byte %11110000 ; 01A5 1-34: **** - .byte %11110000 ; 01A6 1-34: **** - .byte %11110000 ; 01A7 1-34: **** + .byte %00000000 ; 01A0 1-34: + .byte %00000000 ; 01A1 1-34: + .byte %00000000 ; 01A2 1-34: + .byte %00000000 ; 01A3 1-34: + .byte %11110000 ; 01A4 1-34: **** + .byte %11110000 ; 01A5 1-34: **** + .byte %11110000 ; 01A6 1-34: **** + .byte %11110000 ; 01A7 1-34: **** - .byte %00000000 ; 01A8 1-35: - .byte %00000000 ; 01A9 1-35: - .byte %00000000 ; 01AA 1-35: - .byte %00000000 ; 01AB 1-35: - .byte %11110000 ; 01AC 1-35: **** - .byte %11110000 ; 01AD 1-35: **** - .byte %11110000 ; 01AE 1-35: **** - .byte %11110000 ; 01AF 1-35: **** + .byte %00000000 ; 01A8 1-35: + .byte %00000000 ; 01A9 1-35: + .byte %00000000 ; 01AA 1-35: + .byte %00000000 ; 01AB 1-35: + .byte %11110000 ; 01AC 1-35: **** + .byte %11110000 ; 01AD 1-35: **** + .byte %11110000 ; 01AE 1-35: **** + .byte %11110000 ; 01AF 1-35: **** - .byte %11000000 ; 01B0 1-36: ** - .byte %11000000 ; 01B1 1-36: ** - .byte %00110000 ; 01B2 1-36: ** - .byte %00110000 ; 01B3 1-36: ** - .byte %11000000 ; 01B4 1-36: ** - .byte %11000000 ; 01B5 1-36: ** - .byte %00110000 ; 01B6 1-36: ** - .byte %00110000 ; 01B7 1-36: ** + .byte %11000000 ; 01B0 1-36: ** + .byte %11000000 ; 01B1 1-36: ** + .byte %00110000 ; 01B2 1-36: ** + .byte %00110000 ; 01B3 1-36: ** + .byte %11000000 ; 01B4 1-36: ** + .byte %11000000 ; 01B5 1-36: ** + .byte %00110000 ; 01B6 1-36: ** + .byte %00110000 ; 01B7 1-36: ** - .byte %11000000 ; 01B8 1-37: ** - .byte %11000000 ; 01B9 1-37: ** - .byte %00110000 ; 01BA 1-37: ** - .byte %00110000 ; 01BB 1-37: ** - .byte %11000000 ; 01BC 1-37: ** - .byte %11000000 ; 01BD 1-37: ** - .byte %00110000 ; 01BE 1-37: ** - .byte %00110000 ; 01BF 1-37: ** + .byte %11000000 ; 01B8 1-37: ** + .byte %11000000 ; 01B9 1-37: ** + .byte %00110000 ; 01BA 1-37: ** + .byte %00110000 ; 01BB 1-37: ** + .byte %11000000 ; 01BC 1-37: ** + .byte %11000000 ; 01BD 1-37: ** + .byte %00110000 ; 01BE 1-37: ** + .byte %00110000 ; 01BF 1-37: ** .byte %00001111 ; 01C0 1-38: **** .byte %00001111 ; 01C1 1-38: **** .byte %00001111 ; 01C2 1-38: **** .byte %00001111 ; 01C3 1-38: **** - .byte %00000000 ; 01C4 1-38: - .byte %00000000 ; 01C5 1-38: - .byte %00000000 ; 01C6 1-38: - .byte %00000000 ; 01C7 1-38: + .byte %00000000 ; 01C4 1-38: + .byte %00000000 ; 01C5 1-38: + .byte %00000000 ; 01C6 1-38: + .byte %00000000 ; 01C7 1-38: .byte %00001111 ; 01C8 1-39: **** .byte %00001111 ; 01C9 1-39: **** .byte %00001111 ; 01CA 1-39: **** .byte %00001111 ; 01CB 1-39: **** - .byte %00000000 ; 01CC 1-39: - .byte %00000000 ; 01CD 1-39: - .byte %00000000 ; 01CE 1-39: - .byte %00000000 ; 01CF 1-39: + .byte %00000000 ; 01CC 1-39: + .byte %00000000 ; 01CD 1-39: + .byte %00000000 ; 01CE 1-39: + .byte %00000000 ; 01CF 1-39: - .byte %00000000 ; 01D0 1-3a: - .byte %00000000 ; 01D1 1-3a: - .byte %00000000 ; 01D2 1-3a: - .byte %00000000 ; 01D3 1-3a: + .byte %00000000 ; 01D0 1-3a: + .byte %00000000 ; 01D1 1-3a: + .byte %00000000 ; 01D2 1-3a: + .byte %00000000 ; 01D3 1-3a: .byte %00001111 ; 01D4 1-3a: **** .byte %00001111 ; 01D5 1-3a: **** .byte %00001111 ; 01D6 1-3a: **** .byte %00001111 ; 01D7 1-3a: **** - .byte %00000000 ; 01D8 1-3b: - .byte %00000000 ; 01D9 1-3b: - .byte %00000000 ; 01DA 1-3b: - .byte %00000000 ; 01DB 1-3b: + .byte %00000000 ; 01D8 1-3b: + .byte %00000000 ; 01D9 1-3b: + .byte %00000000 ; 01DA 1-3b: + .byte %00000000 ; 01DB 1-3b: .byte %00001111 ; 01DC 1-3b: **** .byte %00001111 ; 01DD 1-3b: **** .byte %00001111 ; 01DE 1-3b: **** .byte %00001111 ; 01DF 1-3b: **** - .byte %11110000 ; 01E0 1-3c: **** - .byte %11110000 ; 01E1 1-3c: **** - .byte %11110000 ; 01E2 1-3c: **** - .byte %11110000 ; 01E3 1-3c: **** - .byte %00000000 ; 01E4 1-3c: - .byte %00000000 ; 01E5 1-3c: - .byte %00000000 ; 01E6 1-3c: - .byte %00000000 ; 01E7 1-3c: + .byte %11110000 ; 01E0 1-3c: **** + .byte %11110000 ; 01E1 1-3c: **** + .byte %11110000 ; 01E2 1-3c: **** + .byte %11110000 ; 01E3 1-3c: **** + .byte %00000000 ; 01E4 1-3c: + .byte %00000000 ; 01E5 1-3c: + .byte %00000000 ; 01E6 1-3c: + .byte %00000000 ; 01E7 1-3c: - .byte %11110000 ; 01E8 1-3d: **** - .byte %11110000 ; 01E9 1-3d: **** - .byte %11110000 ; 01EA 1-3d: **** - .byte %11110000 ; 01EB 1-3d: **** - .byte %00000000 ; 01EC 1-3d: - .byte %00000000 ; 01ED 1-3d: - .byte %00000000 ; 01EE 1-3d: - .byte %00000000 ; 01EF 1-3d: + .byte %11110000 ; 01E8 1-3d: **** + .byte %11110000 ; 01E9 1-3d: **** + .byte %11110000 ; 01EA 1-3d: **** + .byte %11110000 ; 01EB 1-3d: **** + .byte %00000000 ; 01EC 1-3d: + .byte %00000000 ; 01ED 1-3d: + .byte %00000000 ; 01EE 1-3d: + .byte %00000000 ; 01EF 1-3d: - .byte %11110000 ; 01F0 1-3e: **** - .byte %11110000 ; 01F1 1-3e: **** - .byte %11110000 ; 01F2 1-3e: **** - .byte %11110000 ; 01F3 1-3e: **** + .byte %11110000 ; 01F0 1-3e: **** + .byte %11110000 ; 01F1 1-3e: **** + .byte %11110000 ; 01F2 1-3e: **** + .byte %11110000 ; 01F3 1-3e: **** .byte %00001111 ; 01F4 1-3e: **** .byte %00001111 ; 01F5 1-3e: **** .byte %00001111 ; 01F6 1-3e: **** .byte %00001111 ; 01F7 1-3e: **** - .byte %11110000 ; 01F8 1-3f: **** - .byte %11110000 ; 01F9 1-3f: **** - .byte %11110000 ; 01FA 1-3f: **** - .byte %11110000 ; 01FB 1-3f: **** + .byte %11110000 ; 01F8 1-3f: **** + .byte %11110000 ; 01F9 1-3f: **** + .byte %11110000 ; 01FA 1-3f: **** + .byte %11110000 ; 01FB 1-3f: **** .byte %00001111 ; 01FC 1-3f: **** .byte %00001111 ; 01FD 1-3f: **** .byte %00001111 ; 01FE 1-3f: **** .byte %00001111 ; 01FF 1-3f: **** - .byte %00000000 ; 0200 1-40: - .byte %00000000 ; 0201 1-40: - .byte %00000000 ; 0202 1-40: - .byte %00000000 ; 0203 1-40: - .byte %00000000 ; 0204 1-40: - .byte %00000000 ; 0205 1-40: - .byte %00000000 ; 0206 1-40: - .byte %00000000 ; 0207 1-40: + .byte %00000000 ; 0200 1-40: + .byte %00000000 ; 0201 1-40: + .byte %00000000 ; 0202 1-40: + .byte %00000000 ; 0203 1-40: + .byte %00000000 ; 0204 1-40: + .byte %00000000 ; 0205 1-40: + .byte %00000000 ; 0206 1-40: + .byte %00000000 ; 0207 1-40: - .byte %00000000 ; 0208 1-41: - .byte %00000000 ; 0209 1-41: - .byte %00000000 ; 020A 1-41: - .byte %00000000 ; 020B 1-41: - .byte %00000000 ; 020C 1-41: - .byte %00000000 ; 020D 1-41: - .byte %00000000 ; 020E 1-41: - .byte %00000000 ; 020F 1-41: + .byte %00000000 ; 0208 1-41: + .byte %00000000 ; 0209 1-41: + .byte %00000000 ; 020A 1-41: + .byte %00000000 ; 020B 1-41: + .byte %00000000 ; 020C 1-41: + .byte %00000000 ; 020D 1-41: + .byte %00000000 ; 020E 1-41: + .byte %00000000 ; 020F 1-41: - .byte %00011000 ; 0210 1-42: ** - .byte %00011000 ; 0211 1-42: ** - .byte %00011000 ; 0212 1-42: ** - .byte %00011000 ; 0213 1-42: ** - .byte %00000000 ; 0214 1-42: - .byte %00000000 ; 0215 1-42: - .byte %00011000 ; 0216 1-42: ** - .byte %00000000 ; 0217 1-42: + .byte %00011000 ; 0210 1-42: ** + .byte %00011000 ; 0211 1-42: ** + .byte %00011000 ; 0212 1-42: ** + .byte %00011000 ; 0213 1-42: ** + .byte %00000000 ; 0214 1-42: + .byte %00000000 ; 0215 1-42: + .byte %00011000 ; 0216 1-42: ** + .byte %00000000 ; 0217 1-42: - .byte %00011000 ; 0218 1-43: ** - .byte %00011000 ; 0219 1-43: ** - .byte %00011000 ; 021A 1-43: ** - .byte %00011000 ; 021B 1-43: ** - .byte %00000000 ; 021C 1-43: - .byte %00000000 ; 021D 1-43: - .byte %00011000 ; 021E 1-43: ** - .byte %00000000 ; 021F 1-43: + .byte %00011000 ; 0218 1-43: ** + .byte %00011000 ; 0219 1-43: ** + .byte %00011000 ; 021A 1-43: ** + .byte %00011000 ; 021B 1-43: ** + .byte %00000000 ; 021C 1-43: + .byte %00000000 ; 021D 1-43: + .byte %00011000 ; 021E 1-43: ** + .byte %00000000 ; 021F 1-43: - .byte %01100110 ; 0220 1-44: ** ** - .byte %01100110 ; 0221 1-44: ** ** - .byte %01100110 ; 0222 1-44: ** ** - .byte %00000000 ; 0223 1-44: - .byte %00000000 ; 0224 1-44: - .byte %00000000 ; 0225 1-44: - .byte %00000000 ; 0226 1-44: - .byte %00000000 ; 0227 1-44: + .byte %01100110 ; 0220 1-44: ** ** + .byte %01100110 ; 0221 1-44: ** ** + .byte %01100110 ; 0222 1-44: ** ** + .byte %00000000 ; 0223 1-44: + .byte %00000000 ; 0224 1-44: + .byte %00000000 ; 0225 1-44: + .byte %00000000 ; 0226 1-44: + .byte %00000000 ; 0227 1-44: - .byte %01100110 ; 0228 1-45: ** ** - .byte %01100110 ; 0229 1-45: ** ** - .byte %01100110 ; 022A 1-45: ** ** - .byte %00000000 ; 022B 1-45: - .byte %00000000 ; 022C 1-45: - .byte %00000000 ; 022D 1-45: - .byte %00000000 ; 022E 1-45: - .byte %00000000 ; 022F 1-45: + .byte %01100110 ; 0228 1-45: ** ** + .byte %01100110 ; 0229 1-45: ** ** + .byte %01100110 ; 022A 1-45: ** ** + .byte %00000000 ; 022B 1-45: + .byte %00000000 ; 022C 1-45: + .byte %00000000 ; 022D 1-45: + .byte %00000000 ; 022E 1-45: + .byte %00000000 ; 022F 1-45: - .byte %01100110 ; 0230 1-46: ** ** - .byte %01100110 ; 0231 1-46: ** ** + .byte %01100110 ; 0230 1-46: ** ** + .byte %01100110 ; 0231 1-46: ** ** .byte %11111111 ; 0232 1-46: ******** - .byte %01100110 ; 0233 1-46: ** ** + .byte %01100110 ; 0233 1-46: ** ** .byte %11111111 ; 0234 1-46: ******** - .byte %01100110 ; 0235 1-46: ** ** - .byte %01100110 ; 0236 1-46: ** ** - .byte %00000000 ; 0237 1-46: + .byte %01100110 ; 0235 1-46: ** ** + .byte %01100110 ; 0236 1-46: ** ** + .byte %00000000 ; 0237 1-46: - .byte %01100110 ; 0238 1-47: ** ** - .byte %01100110 ; 0239 1-47: ** ** + .byte %01100110 ; 0238 1-47: ** ** + .byte %01100110 ; 0239 1-47: ** ** .byte %11111111 ; 023A 1-47: ******** - .byte %01100110 ; 023B 1-47: ** ** + .byte %01100110 ; 023B 1-47: ** ** .byte %11111111 ; 023C 1-47: ******** - .byte %01100110 ; 023D 1-47: ** ** - .byte %01100110 ; 023E 1-47: ** ** - .byte %00000000 ; 023F 1-47: + .byte %01100110 ; 023D 1-47: ** ** + .byte %01100110 ; 023E 1-47: ** ** + .byte %00000000 ; 023F 1-47: - .byte %00011000 ; 0240 1-48: ** - .byte %00111110 ; 0241 1-48: ***** - .byte %01100000 ; 0242 1-48: ** - .byte %00111100 ; 0243 1-48: **** - .byte %00000110 ; 0244 1-48: ** - .byte %01111100 ; 0245 1-48: ***** - .byte %00011000 ; 0246 1-48: ** - .byte %00000000 ; 0247 1-48: + .byte %00011000 ; 0240 1-48: ** + .byte %00111110 ; 0241 1-48: ***** + .byte %01100000 ; 0242 1-48: ** + .byte %00111100 ; 0243 1-48: **** + .byte %00000110 ; 0244 1-48: ** + .byte %01111100 ; 0245 1-48: ***** + .byte %00011000 ; 0246 1-48: ** + .byte %00000000 ; 0247 1-48: - .byte %00011000 ; 0248 1-49: ** - .byte %00111110 ; 0249 1-49: ***** - .byte %01100000 ; 024A 1-49: ** - .byte %00111100 ; 024B 1-49: **** - .byte %00000110 ; 024C 1-49: ** - .byte %01111100 ; 024D 1-49: ***** - .byte %00011000 ; 024E 1-49: ** - .byte %00000000 ; 024F 1-49: + .byte %00011000 ; 0248 1-49: ** + .byte %00111110 ; 0249 1-49: ***** + .byte %01100000 ; 024A 1-49: ** + .byte %00111100 ; 024B 1-49: **** + .byte %00000110 ; 024C 1-49: ** + .byte %01111100 ; 024D 1-49: ***** + .byte %00011000 ; 024E 1-49: ** + .byte %00000000 ; 024F 1-49: - .byte %00000000 ; 0250 1-4a: - .byte %01100110 ; 0251 1-4a: ** ** - .byte %00001100 ; 0252 1-4a: ** - .byte %00011000 ; 0253 1-4a: ** - .byte %00110000 ; 0254 1-4a: ** - .byte %01100110 ; 0255 1-4a: ** ** - .byte %01000110 ; 0256 1-4a: * ** - .byte %00000000 ; 0257 1-4a: + .byte %00000000 ; 0250 1-4a: + .byte %01100110 ; 0251 1-4a: ** ** + .byte %00001100 ; 0252 1-4a: ** + .byte %00011000 ; 0253 1-4a: ** + .byte %00110000 ; 0254 1-4a: ** + .byte %01100110 ; 0255 1-4a: ** ** + .byte %01000110 ; 0256 1-4a: * ** + .byte %00000000 ; 0257 1-4a: - .byte %00000000 ; 0258 1-4b: - .byte %01100110 ; 0259 1-4b: ** ** - .byte %00001100 ; 025A 1-4b: ** - .byte %00011000 ; 025B 1-4b: ** - .byte %00110000 ; 025C 1-4b: ** - .byte %01100110 ; 025D 1-4b: ** ** - .byte %01000110 ; 025E 1-4b: * ** - .byte %00000000 ; 025F 1-4b: + .byte %00000000 ; 0258 1-4b: + .byte %01100110 ; 0259 1-4b: ** ** + .byte %00001100 ; 025A 1-4b: ** + .byte %00011000 ; 025B 1-4b: ** + .byte %00110000 ; 025C 1-4b: ** + .byte %01100110 ; 025D 1-4b: ** ** + .byte %01000110 ; 025E 1-4b: * ** + .byte %00000000 ; 025F 1-4b: - .byte %00111100 ; 0260 1-4c: **** - .byte %01100110 ; 0261 1-4c: ** ** - .byte %00111100 ; 0262 1-4c: **** - .byte %00111000 ; 0263 1-4c: *** + .byte %00111100 ; 0260 1-4c: **** + .byte %01100110 ; 0261 1-4c: ** ** + .byte %00111100 ; 0262 1-4c: **** + .byte %00111000 ; 0263 1-4c: *** .byte %01100111 ; 0264 1-4c: ** *** - .byte %01100110 ; 0265 1-4c: ** ** + .byte %01100110 ; 0265 1-4c: ** ** .byte %00111111 ; 0266 1-4c: ****** - .byte %00000000 ; 0267 1-4c: + .byte %00000000 ; 0267 1-4c: - .byte %00111100 ; 0268 1-4d: **** - .byte %01100110 ; 0269 1-4d: ** ** - .byte %00111100 ; 026A 1-4d: **** - .byte %00111000 ; 026B 1-4d: *** + .byte %00111100 ; 0268 1-4d: **** + .byte %01100110 ; 0269 1-4d: ** ** + .byte %00111100 ; 026A 1-4d: **** + .byte %00111000 ; 026B 1-4d: *** .byte %01100111 ; 026C 1-4d: ** *** - .byte %01100110 ; 026D 1-4d: ** ** + .byte %01100110 ; 026D 1-4d: ** ** .byte %00111111 ; 026E 1-4d: ****** - .byte %00000000 ; 026F 1-4d: + .byte %00000000 ; 026F 1-4d: - .byte %00000110 ; 0270 1-4e: ** - .byte %00001100 ; 0271 1-4e: ** - .byte %00011000 ; 0272 1-4e: ** - .byte %00000000 ; 0273 1-4e: - .byte %00000000 ; 0274 1-4e: - .byte %00000000 ; 0275 1-4e: - .byte %00000000 ; 0276 1-4e: - .byte %00000000 ; 0277 1-4e: + .byte %00000110 ; 0270 1-4e: ** + .byte %00001100 ; 0271 1-4e: ** + .byte %00011000 ; 0272 1-4e: ** + .byte %00000000 ; 0273 1-4e: + .byte %00000000 ; 0274 1-4e: + .byte %00000000 ; 0275 1-4e: + .byte %00000000 ; 0276 1-4e: + .byte %00000000 ; 0277 1-4e: - .byte %00000110 ; 0278 1-4f: ** - .byte %00001100 ; 0279 1-4f: ** - .byte %00011000 ; 027A 1-4f: ** - .byte %00000000 ; 027B 1-4f: - .byte %00000000 ; 027C 1-4f: - .byte %00000000 ; 027D 1-4f: - .byte %00000000 ; 027E 1-4f: - .byte %00000000 ; 027F 1-4f: + .byte %00000110 ; 0278 1-4f: ** + .byte %00001100 ; 0279 1-4f: ** + .byte %00011000 ; 027A 1-4f: ** + .byte %00000000 ; 027B 1-4f: + .byte %00000000 ; 027C 1-4f: + .byte %00000000 ; 027D 1-4f: + .byte %00000000 ; 027E 1-4f: + .byte %00000000 ; 027F 1-4f: - .byte %00001100 ; 0280 1-50: ** - .byte %00011000 ; 0281 1-50: ** - .byte %00110000 ; 0282 1-50: ** - .byte %00110000 ; 0283 1-50: ** - .byte %00110000 ; 0284 1-50: ** - .byte %00011000 ; 0285 1-50: ** - .byte %00001100 ; 0286 1-50: ** - .byte %00000000 ; 0287 1-50: + .byte %00001100 ; 0280 1-50: ** + .byte %00011000 ; 0281 1-50: ** + .byte %00110000 ; 0282 1-50: ** + .byte %00110000 ; 0283 1-50: ** + .byte %00110000 ; 0284 1-50: ** + .byte %00011000 ; 0285 1-50: ** + .byte %00001100 ; 0286 1-50: ** + .byte %00000000 ; 0287 1-50: - .byte %00001100 ; 0288 1-51: ** - .byte %00011000 ; 0289 1-51: ** - .byte %00110000 ; 028A 1-51: ** - .byte %00110000 ; 028B 1-51: ** - .byte %00110000 ; 028C 1-51: ** - .byte %00011000 ; 028D 1-51: ** - .byte %00001100 ; 028E 1-51: ** - .byte %00000000 ; 028F 1-51: + .byte %00001100 ; 0288 1-51: ** + .byte %00011000 ; 0289 1-51: ** + .byte %00110000 ; 028A 1-51: ** + .byte %00110000 ; 028B 1-51: ** + .byte %00110000 ; 028C 1-51: ** + .byte %00011000 ; 028D 1-51: ** + .byte %00001100 ; 028E 1-51: ** + .byte %00000000 ; 028F 1-51: - .byte %00110000 ; 0290 1-52: ** - .byte %00011000 ; 0291 1-52: ** - .byte %00001100 ; 0292 1-52: ** - .byte %00001100 ; 0293 1-52: ** - .byte %00001100 ; 0294 1-52: ** - .byte %00011000 ; 0295 1-52: ** - .byte %00110000 ; 0296 1-52: ** - .byte %00000000 ; 0297 1-52: + .byte %00110000 ; 0290 1-52: ** + .byte %00011000 ; 0291 1-52: ** + .byte %00001100 ; 0292 1-52: ** + .byte %00001100 ; 0293 1-52: ** + .byte %00001100 ; 0294 1-52: ** + .byte %00011000 ; 0295 1-52: ** + .byte %00110000 ; 0296 1-52: ** + .byte %00000000 ; 0297 1-52: - .byte %00110000 ; 0298 1-53: ** - .byte %00011000 ; 0299 1-53: ** - .byte %00001100 ; 029A 1-53: ** - .byte %00001100 ; 029B 1-53: ** - .byte %00001100 ; 029C 1-53: ** - .byte %00011000 ; 029D 1-53: ** - .byte %00110000 ; 029E 1-53: ** - .byte %00000000 ; 029F 1-53: + .byte %00110000 ; 0298 1-53: ** + .byte %00011000 ; 0299 1-53: ** + .byte %00001100 ; 029A 1-53: ** + .byte %00001100 ; 029B 1-53: ** + .byte %00001100 ; 029C 1-53: ** + .byte %00011000 ; 029D 1-53: ** + .byte %00110000 ; 029E 1-53: ** + .byte %00000000 ; 029F 1-53: - .byte %00000000 ; 02A0 1-54: - .byte %01100110 ; 02A1 1-54: ** ** - .byte %00111100 ; 02A2 1-54: **** + .byte %00000000 ; 02A0 1-54: + .byte %01100110 ; 02A1 1-54: ** ** + .byte %00111100 ; 02A2 1-54: **** .byte %11111111 ; 02A3 1-54: ******** - .byte %00111100 ; 02A4 1-54: **** - .byte %01100110 ; 02A5 1-54: ** ** - .byte %00000000 ; 02A6 1-54: - .byte %00000000 ; 02A7 1-54: + .byte %00111100 ; 02A4 1-54: **** + .byte %01100110 ; 02A5 1-54: ** ** + .byte %00000000 ; 02A6 1-54: + .byte %00000000 ; 02A7 1-54: - .byte %00000000 ; 02A8 1-55: - .byte %01100110 ; 02A9 1-55: ** ** - .byte %00111100 ; 02AA 1-55: **** + .byte %00000000 ; 02A8 1-55: + .byte %01100110 ; 02A9 1-55: ** ** + .byte %00111100 ; 02AA 1-55: **** .byte %11111111 ; 02AB 1-55: ******** - .byte %00111100 ; 02AC 1-55: **** - .byte %01100110 ; 02AD 1-55: ** ** - .byte %00000000 ; 02AE 1-55: - .byte %00000000 ; 02AF 1-55: + .byte %00111100 ; 02AC 1-55: **** + .byte %01100110 ; 02AD 1-55: ** ** + .byte %00000000 ; 02AE 1-55: + .byte %00000000 ; 02AF 1-55: - .byte %00000000 ; 02B0 1-56: - .byte %00011000 ; 02B1 1-56: ** - .byte %00011000 ; 02B2 1-56: ** - .byte %01111110 ; 02B3 1-56: ****** - .byte %00011000 ; 02B4 1-56: ** - .byte %00011000 ; 02B5 1-56: ** - .byte %00000000 ; 02B6 1-56: - .byte %00000000 ; 02B7 1-56: + .byte %00000000 ; 02B0 1-56: + .byte %00011000 ; 02B1 1-56: ** + .byte %00011000 ; 02B2 1-56: ** + .byte %01111110 ; 02B3 1-56: ****** + .byte %00011000 ; 02B4 1-56: ** + .byte %00011000 ; 02B5 1-56: ** + .byte %00000000 ; 02B6 1-56: + .byte %00000000 ; 02B7 1-56: - .byte %00000000 ; 02B8 1-57: - .byte %00011000 ; 02B9 1-57: ** - .byte %00011000 ; 02BA 1-57: ** - .byte %01111110 ; 02BB 1-57: ****** - .byte %00011000 ; 02BC 1-57: ** - .byte %00011000 ; 02BD 1-57: ** - .byte %00000000 ; 02BE 1-57: - .byte %00000000 ; 02BF 1-57: + .byte %00000000 ; 02B8 1-57: + .byte %00011000 ; 02B9 1-57: ** + .byte %00011000 ; 02BA 1-57: ** + .byte %01111110 ; 02BB 1-57: ****** + .byte %00011000 ; 02BC 1-57: ** + .byte %00011000 ; 02BD 1-57: ** + .byte %00000000 ; 02BE 1-57: + .byte %00000000 ; 02BF 1-57: - .byte %00000000 ; 02C0 1-58: - .byte %00000000 ; 02C1 1-58: - .byte %00000000 ; 02C2 1-58: - .byte %00000000 ; 02C3 1-58: - .byte %00000000 ; 02C4 1-58: - .byte %00011000 ; 02C5 1-58: ** - .byte %00011000 ; 02C6 1-58: ** - .byte %00110000 ; 02C7 1-58: ** + .byte %00000000 ; 02C0 1-58: + .byte %00000000 ; 02C1 1-58: + .byte %00000000 ; 02C2 1-58: + .byte %00000000 ; 02C3 1-58: + .byte %00000000 ; 02C4 1-58: + .byte %00011000 ; 02C5 1-58: ** + .byte %00011000 ; 02C6 1-58: ** + .byte %00110000 ; 02C7 1-58: ** - .byte %00000000 ; 02C8 1-59: - .byte %00000000 ; 02C9 1-59: - .byte %00000000 ; 02CA 1-59: - .byte %00000000 ; 02CB 1-59: - .byte %00000000 ; 02CC 1-59: - .byte %00011000 ; 02CD 1-59: ** - .byte %00011000 ; 02CE 1-59: ** - .byte %00110000 ; 02CF 1-59: ** + .byte %00000000 ; 02C8 1-59: + .byte %00000000 ; 02C9 1-59: + .byte %00000000 ; 02CA 1-59: + .byte %00000000 ; 02CB 1-59: + .byte %00000000 ; 02CC 1-59: + .byte %00011000 ; 02CD 1-59: ** + .byte %00011000 ; 02CE 1-59: ** + .byte %00110000 ; 02CF 1-59: ** - .byte %00000000 ; 02D0 1-5a: - .byte %00000000 ; 02D1 1-5a: - .byte %00000000 ; 02D2 1-5a: - .byte %01111110 ; 02D3 1-5a: ****** - .byte %00000000 ; 02D4 1-5a: - .byte %00000000 ; 02D5 1-5a: - .byte %00000000 ; 02D6 1-5a: - .byte %00000000 ; 02D7 1-5a: + .byte %00000000 ; 02D0 1-5a: + .byte %00000000 ; 02D1 1-5a: + .byte %00000000 ; 02D2 1-5a: + .byte %01111110 ; 02D3 1-5a: ****** + .byte %00000000 ; 02D4 1-5a: + .byte %00000000 ; 02D5 1-5a: + .byte %00000000 ; 02D6 1-5a: + .byte %00000000 ; 02D7 1-5a: - .byte %00000000 ; 02D8 1-5b: - .byte %00000000 ; 02D9 1-5b: - .byte %00000000 ; 02DA 1-5b: - .byte %01111110 ; 02DB 1-5b: ****** - .byte %00000000 ; 02DC 1-5b: - .byte %00000000 ; 02DD 1-5b: - .byte %00000000 ; 02DE 1-5b: - .byte %00000000 ; 02DF 1-5b: + .byte %00000000 ; 02D8 1-5b: + .byte %00000000 ; 02D9 1-5b: + .byte %00000000 ; 02DA 1-5b: + .byte %01111110 ; 02DB 1-5b: ****** + .byte %00000000 ; 02DC 1-5b: + .byte %00000000 ; 02DD 1-5b: + .byte %00000000 ; 02DE 1-5b: + .byte %00000000 ; 02DF 1-5b: - .byte %00000000 ; 02E0 1-5c: - .byte %00000000 ; 02E1 1-5c: - .byte %00000000 ; 02E2 1-5c: - .byte %00000000 ; 02E3 1-5c: - .byte %00000000 ; 02E4 1-5c: - .byte %00011000 ; 02E5 1-5c: ** - .byte %00011000 ; 02E6 1-5c: ** - .byte %00000000 ; 02E7 1-5c: + .byte %00000000 ; 02E0 1-5c: + .byte %00000000 ; 02E1 1-5c: + .byte %00000000 ; 02E2 1-5c: + .byte %00000000 ; 02E3 1-5c: + .byte %00000000 ; 02E4 1-5c: + .byte %00011000 ; 02E5 1-5c: ** + .byte %00011000 ; 02E6 1-5c: ** + .byte %00000000 ; 02E7 1-5c: - .byte %00000000 ; 02E8 1-5d: - .byte %00000000 ; 02E9 1-5d: - .byte %00000000 ; 02EA 1-5d: - .byte %00000000 ; 02EB 1-5d: - .byte %00000000 ; 02EC 1-5d: - .byte %00011000 ; 02ED 1-5d: ** - .byte %00011000 ; 02EE 1-5d: ** - .byte %00000000 ; 02EF 1-5d: + .byte %00000000 ; 02E8 1-5d: + .byte %00000000 ; 02E9 1-5d: + .byte %00000000 ; 02EA 1-5d: + .byte %00000000 ; 02EB 1-5d: + .byte %00000000 ; 02EC 1-5d: + .byte %00011000 ; 02ED 1-5d: ** + .byte %00011000 ; 02EE 1-5d: ** + .byte %00000000 ; 02EF 1-5d: - .byte %00000000 ; 02F0 1-5e: + .byte %00000000 ; 02F0 1-5e: .byte %00000011 ; 02F1 1-5e: ** - .byte %00000110 ; 02F2 1-5e: ** - .byte %00001100 ; 02F3 1-5e: ** - .byte %00011000 ; 02F4 1-5e: ** - .byte %00110000 ; 02F5 1-5e: ** - .byte %01100000 ; 02F6 1-5e: ** - .byte %00000000 ; 02F7 1-5e: + .byte %00000110 ; 02F2 1-5e: ** + .byte %00001100 ; 02F3 1-5e: ** + .byte %00011000 ; 02F4 1-5e: ** + .byte %00110000 ; 02F5 1-5e: ** + .byte %01100000 ; 02F6 1-5e: ** + .byte %00000000 ; 02F7 1-5e: - .byte %00000000 ; 02F8 1-5f: + .byte %00000000 ; 02F8 1-5f: .byte %00000011 ; 02F9 1-5f: ** - .byte %00000110 ; 02FA 1-5f: ** - .byte %00001100 ; 02FB 1-5f: ** - .byte %00011000 ; 02FC 1-5f: ** - .byte %00110000 ; 02FD 1-5f: ** - .byte %01100000 ; 02FE 1-5f: ** - .byte %00000000 ; 02FF 1-5f: + .byte %00000110 ; 02FA 1-5f: ** + .byte %00001100 ; 02FB 1-5f: ** + .byte %00011000 ; 02FC 1-5f: ** + .byte %00110000 ; 02FD 1-5f: ** + .byte %01100000 ; 02FE 1-5f: ** + .byte %00000000 ; 02FF 1-5f: - .byte %00111100 ; 0300 1-60: **** - .byte %01100110 ; 0301 1-60: ** ** - .byte %01101110 ; 0302 1-60: ** *** - .byte %01110110 ; 0303 1-60: *** ** - .byte %01100110 ; 0304 1-60: ** ** - .byte %01100110 ; 0305 1-60: ** ** - .byte %00111100 ; 0306 1-60: **** - .byte %00000000 ; 0307 1-60: + .byte %00111100 ; 0300 1-60: **** + .byte %01100110 ; 0301 1-60: ** ** + .byte %01101110 ; 0302 1-60: ** *** + .byte %01110110 ; 0303 1-60: *** ** + .byte %01100110 ; 0304 1-60: ** ** + .byte %01100110 ; 0305 1-60: ** ** + .byte %00111100 ; 0306 1-60: **** + .byte %00000000 ; 0307 1-60: - .byte %00111100 ; 0308 1-61: **** - .byte %01100110 ; 0309 1-61: ** ** - .byte %01101110 ; 030A 1-61: ** *** - .byte %01110110 ; 030B 1-61: *** ** - .byte %01100110 ; 030C 1-61: ** ** - .byte %01100110 ; 030D 1-61: ** ** - .byte %00111100 ; 030E 1-61: **** - .byte %00000000 ; 030F 1-61: + .byte %00111100 ; 0308 1-61: **** + .byte %01100110 ; 0309 1-61: ** ** + .byte %01101110 ; 030A 1-61: ** *** + .byte %01110110 ; 030B 1-61: *** ** + .byte %01100110 ; 030C 1-61: ** ** + .byte %01100110 ; 030D 1-61: ** ** + .byte %00111100 ; 030E 1-61: **** + .byte %00000000 ; 030F 1-61: - .byte %00011000 ; 0310 1-62: ** - .byte %00011000 ; 0311 1-62: ** - .byte %00111000 ; 0312 1-62: *** - .byte %00011000 ; 0313 1-62: ** - .byte %00011000 ; 0314 1-62: ** - .byte %00011000 ; 0315 1-62: ** - .byte %01111110 ; 0316 1-62: ****** - .byte %00000000 ; 0317 1-62: + .byte %00011000 ; 0310 1-62: ** + .byte %00011000 ; 0311 1-62: ** + .byte %00111000 ; 0312 1-62: *** + .byte %00011000 ; 0313 1-62: ** + .byte %00011000 ; 0314 1-62: ** + .byte %00011000 ; 0315 1-62: ** + .byte %01111110 ; 0316 1-62: ****** + .byte %00000000 ; 0317 1-62: - .byte %00011000 ; 0318 1-63: ** - .byte %00011000 ; 0319 1-63: ** - .byte %00111000 ; 031A 1-63: *** - .byte %00011000 ; 031B 1-63: ** - .byte %00011000 ; 031C 1-63: ** - .byte %00011000 ; 031D 1-63: ** - .byte %01111110 ; 031E 1-63: ****** - .byte %00000000 ; 031F 1-63: + .byte %00011000 ; 0318 1-63: ** + .byte %00011000 ; 0319 1-63: ** + .byte %00111000 ; 031A 1-63: *** + .byte %00011000 ; 031B 1-63: ** + .byte %00011000 ; 031C 1-63: ** + .byte %00011000 ; 031D 1-63: ** + .byte %01111110 ; 031E 1-63: ****** + .byte %00000000 ; 031F 1-63: - .byte %00111100 ; 0320 1-64: **** - .byte %01100110 ; 0321 1-64: ** ** - .byte %00000110 ; 0322 1-64: ** - .byte %00001100 ; 0323 1-64: ** - .byte %00110000 ; 0324 1-64: ** - .byte %01100000 ; 0325 1-64: ** - .byte %01111110 ; 0326 1-64: ****** - .byte %00000000 ; 0327 1-64: + .byte %00111100 ; 0320 1-64: **** + .byte %01100110 ; 0321 1-64: ** ** + .byte %00000110 ; 0322 1-64: ** + .byte %00001100 ; 0323 1-64: ** + .byte %00110000 ; 0324 1-64: ** + .byte %01100000 ; 0325 1-64: ** + .byte %01111110 ; 0326 1-64: ****** + .byte %00000000 ; 0327 1-64: - .byte %00111100 ; 0328 1-65: **** - .byte %01100110 ; 0329 1-65: ** ** - .byte %00000110 ; 032A 1-65: ** - .byte %00001100 ; 032B 1-65: ** - .byte %00110000 ; 032C 1-65: ** - .byte %01100000 ; 032D 1-65: ** - .byte %01111110 ; 032E 1-65: ****** - .byte %00000000 ; 032F 1-65: + .byte %00111100 ; 0328 1-65: **** + .byte %01100110 ; 0329 1-65: ** ** + .byte %00000110 ; 032A 1-65: ** + .byte %00001100 ; 032B 1-65: ** + .byte %00110000 ; 032C 1-65: ** + .byte %01100000 ; 032D 1-65: ** + .byte %01111110 ; 032E 1-65: ****** + .byte %00000000 ; 032F 1-65: - .byte %00111100 ; 0330 1-66: **** - .byte %01100110 ; 0331 1-66: ** ** - .byte %00000110 ; 0332 1-66: ** - .byte %00011100 ; 0333 1-66: *** - .byte %00000110 ; 0334 1-66: ** - .byte %01100110 ; 0335 1-66: ** ** - .byte %00111100 ; 0336 1-66: **** - .byte %00000000 ; 0337 1-66: + .byte %00111100 ; 0330 1-66: **** + .byte %01100110 ; 0331 1-66: ** ** + .byte %00000110 ; 0332 1-66: ** + .byte %00011100 ; 0333 1-66: *** + .byte %00000110 ; 0334 1-66: ** + .byte %01100110 ; 0335 1-66: ** ** + .byte %00111100 ; 0336 1-66: **** + .byte %00000000 ; 0337 1-66: - .byte %00111100 ; 0338 1-67: **** - .byte %01100110 ; 0339 1-67: ** ** - .byte %00000110 ; 033A 1-67: ** - .byte %00011100 ; 033B 1-67: *** - .byte %00000110 ; 033C 1-67: ** - .byte %01100110 ; 033D 1-67: ** ** - .byte %00111100 ; 033E 1-67: **** - .byte %00000000 ; 033F 1-67: + .byte %00111100 ; 0338 1-67: **** + .byte %01100110 ; 0339 1-67: ** ** + .byte %00000110 ; 033A 1-67: ** + .byte %00011100 ; 033B 1-67: *** + .byte %00000110 ; 033C 1-67: ** + .byte %01100110 ; 033D 1-67: ** ** + .byte %00111100 ; 033E 1-67: **** + .byte %00000000 ; 033F 1-67: - .byte %00000110 ; 0340 1-68: ** - .byte %00001110 ; 0341 1-68: *** - .byte %00011110 ; 0342 1-68: **** - .byte %01100110 ; 0343 1-68: ** ** + .byte %00000110 ; 0340 1-68: ** + .byte %00001110 ; 0341 1-68: *** + .byte %00011110 ; 0342 1-68: **** + .byte %01100110 ; 0343 1-68: ** ** .byte %01111111 ; 0344 1-68: ******* - .byte %00000110 ; 0345 1-68: ** - .byte %00000110 ; 0346 1-68: ** - .byte %00000000 ; 0347 1-68: + .byte %00000110 ; 0345 1-68: ** + .byte %00000110 ; 0346 1-68: ** + .byte %00000000 ; 0347 1-68: - .byte %00000110 ; 0348 1-69: ** - .byte %00001110 ; 0349 1-69: *** - .byte %00011110 ; 034A 1-69: **** - .byte %01100110 ; 034B 1-69: ** ** + .byte %00000110 ; 0348 1-69: ** + .byte %00001110 ; 0349 1-69: *** + .byte %00011110 ; 034A 1-69: **** + .byte %01100110 ; 034B 1-69: ** ** .byte %01111111 ; 034C 1-69: ******* - .byte %00000110 ; 034D 1-69: ** - .byte %00000110 ; 034E 1-69: ** - .byte %00000000 ; 034F 1-69: + .byte %00000110 ; 034D 1-69: ** + .byte %00000110 ; 034E 1-69: ** + .byte %00000000 ; 034F 1-69: - .byte %01111110 ; 0350 1-6a: ****** - .byte %01100000 ; 0351 1-6a: ** - .byte %01111100 ; 0352 1-6a: ***** - .byte %00000110 ; 0353 1-6a: ** - .byte %00000110 ; 0354 1-6a: ** - .byte %01100110 ; 0355 1-6a: ** ** - .byte %00111100 ; 0356 1-6a: **** - .byte %00000000 ; 0357 1-6a: + .byte %01111110 ; 0350 1-6a: ****** + .byte %01100000 ; 0351 1-6a: ** + .byte %01111100 ; 0352 1-6a: ***** + .byte %00000110 ; 0353 1-6a: ** + .byte %00000110 ; 0354 1-6a: ** + .byte %01100110 ; 0355 1-6a: ** ** + .byte %00111100 ; 0356 1-6a: **** + .byte %00000000 ; 0357 1-6a: - .byte %01111110 ; 0358 1-6b: ****** - .byte %01100000 ; 0359 1-6b: ** - .byte %01111100 ; 035A 1-6b: ***** - .byte %00000110 ; 035B 1-6b: ** - .byte %00000110 ; 035C 1-6b: ** - .byte %01100110 ; 035D 1-6b: ** ** - .byte %00111100 ; 035E 1-6b: **** - .byte %00000000 ; 035F 1-6b: + .byte %01111110 ; 0358 1-6b: ****** + .byte %01100000 ; 0359 1-6b: ** + .byte %01111100 ; 035A 1-6b: ***** + .byte %00000110 ; 035B 1-6b: ** + .byte %00000110 ; 035C 1-6b: ** + .byte %01100110 ; 035D 1-6b: ** ** + .byte %00111100 ; 035E 1-6b: **** + .byte %00000000 ; 035F 1-6b: - .byte %00111100 ; 0360 1-6c: **** - .byte %01100110 ; 0361 1-6c: ** ** - .byte %01100000 ; 0362 1-6c: ** - .byte %01111100 ; 0363 1-6c: ***** - .byte %01100110 ; 0364 1-6c: ** ** - .byte %01100110 ; 0365 1-6c: ** ** - .byte %00111100 ; 0366 1-6c: **** - .byte %00000000 ; 0367 1-6c: + .byte %00111100 ; 0360 1-6c: **** + .byte %01100110 ; 0361 1-6c: ** ** + .byte %01100000 ; 0362 1-6c: ** + .byte %01111100 ; 0363 1-6c: ***** + .byte %01100110 ; 0364 1-6c: ** ** + .byte %01100110 ; 0365 1-6c: ** ** + .byte %00111100 ; 0366 1-6c: **** + .byte %00000000 ; 0367 1-6c: - .byte %00111100 ; 0368 1-6d: **** - .byte %01100110 ; 0369 1-6d: ** ** - .byte %01100000 ; 036A 1-6d: ** - .byte %01111100 ; 036B 1-6d: ***** - .byte %01100110 ; 036C 1-6d: ** ** - .byte %01100110 ; 036D 1-6d: ** ** - .byte %00111100 ; 036E 1-6d: **** - .byte %00000000 ; 036F 1-6d: + .byte %00111100 ; 0368 1-6d: **** + .byte %01100110 ; 0369 1-6d: ** ** + .byte %01100000 ; 036A 1-6d: ** + .byte %01111100 ; 036B 1-6d: ***** + .byte %01100110 ; 036C 1-6d: ** ** + .byte %01100110 ; 036D 1-6d: ** ** + .byte %00111100 ; 036E 1-6d: **** + .byte %00000000 ; 036F 1-6d: - .byte %01111110 ; 0370 1-6e: ****** - .byte %01100110 ; 0371 1-6e: ** ** - .byte %00001100 ; 0372 1-6e: ** - .byte %00011000 ; 0373 1-6e: ** - .byte %00011000 ; 0374 1-6e: ** - .byte %00011000 ; 0375 1-6e: ** - .byte %00011000 ; 0376 1-6e: ** - .byte %00000000 ; 0377 1-6e: + .byte %01111110 ; 0370 1-6e: ****** + .byte %01100110 ; 0371 1-6e: ** ** + .byte %00001100 ; 0372 1-6e: ** + .byte %00011000 ; 0373 1-6e: ** + .byte %00011000 ; 0374 1-6e: ** + .byte %00011000 ; 0375 1-6e: ** + .byte %00011000 ; 0376 1-6e: ** + .byte %00000000 ; 0377 1-6e: - .byte %01111110 ; 0378 1-6f: ****** - .byte %01100110 ; 0379 1-6f: ** ** - .byte %00001100 ; 037A 1-6f: ** - .byte %00011000 ; 037B 1-6f: ** - .byte %00011000 ; 037C 1-6f: ** - .byte %00011000 ; 037D 1-6f: ** - .byte %00011000 ; 037E 1-6f: ** - .byte %00000000 ; 037F 1-6f: + .byte %01111110 ; 0378 1-6f: ****** + .byte %01100110 ; 0379 1-6f: ** ** + .byte %00001100 ; 037A 1-6f: ** + .byte %00011000 ; 037B 1-6f: ** + .byte %00011000 ; 037C 1-6f: ** + .byte %00011000 ; 037D 1-6f: ** + .byte %00011000 ; 037E 1-6f: ** + .byte %00000000 ; 037F 1-6f: - .byte %00111100 ; 0380 1-70: **** - .byte %01100110 ; 0381 1-70: ** ** - .byte %01100110 ; 0382 1-70: ** ** - .byte %00111100 ; 0383 1-70: **** - .byte %01100110 ; 0384 1-70: ** ** - .byte %01100110 ; 0385 1-70: ** ** - .byte %00111100 ; 0386 1-70: **** - .byte %00000000 ; 0387 1-70: + .byte %00111100 ; 0380 1-70: **** + .byte %01100110 ; 0381 1-70: ** ** + .byte %01100110 ; 0382 1-70: ** ** + .byte %00111100 ; 0383 1-70: **** + .byte %01100110 ; 0384 1-70: ** ** + .byte %01100110 ; 0385 1-70: ** ** + .byte %00111100 ; 0386 1-70: **** + .byte %00000000 ; 0387 1-70: - .byte %00111100 ; 0388 1-71: **** - .byte %01100110 ; 0389 1-71: ** ** - .byte %01100110 ; 038A 1-71: ** ** - .byte %00111100 ; 038B 1-71: **** - .byte %01100110 ; 038C 1-71: ** ** - .byte %01100110 ; 038D 1-71: ** ** - .byte %00111100 ; 038E 1-71: **** - .byte %00000000 ; 038F 1-71: + .byte %00111100 ; 0388 1-71: **** + .byte %01100110 ; 0389 1-71: ** ** + .byte %01100110 ; 038A 1-71: ** ** + .byte %00111100 ; 038B 1-71: **** + .byte %01100110 ; 038C 1-71: ** ** + .byte %01100110 ; 038D 1-71: ** ** + .byte %00111100 ; 038E 1-71: **** + .byte %00000000 ; 038F 1-71: - .byte %00111100 ; 0390 1-72: **** - .byte %01100110 ; 0391 1-72: ** ** - .byte %01100110 ; 0392 1-72: ** ** - .byte %00111110 ; 0393 1-72: ***** - .byte %00000110 ; 0394 1-72: ** - .byte %01100110 ; 0395 1-72: ** ** - .byte %00111100 ; 0396 1-72: **** - .byte %00000000 ; 0397 1-72: + .byte %00111100 ; 0390 1-72: **** + .byte %01100110 ; 0391 1-72: ** ** + .byte %01100110 ; 0392 1-72: ** ** + .byte %00111110 ; 0393 1-72: ***** + .byte %00000110 ; 0394 1-72: ** + .byte %01100110 ; 0395 1-72: ** ** + .byte %00111100 ; 0396 1-72: **** + .byte %00000000 ; 0397 1-72: - .byte %00111100 ; 0398 1-73: **** - .byte %01100110 ; 0399 1-73: ** ** - .byte %01100110 ; 039A 1-73: ** ** - .byte %00111110 ; 039B 1-73: ***** - .byte %00000110 ; 039C 1-73: ** - .byte %01100110 ; 039D 1-73: ** ** - .byte %00111100 ; 039E 1-73: **** - .byte %00000000 ; 039F 1-73: + .byte %00111100 ; 0398 1-73: **** + .byte %01100110 ; 0399 1-73: ** ** + .byte %01100110 ; 039A 1-73: ** ** + .byte %00111110 ; 039B 1-73: ***** + .byte %00000110 ; 039C 1-73: ** + .byte %01100110 ; 039D 1-73: ** ** + .byte %00111100 ; 039E 1-73: **** + .byte %00000000 ; 039F 1-73: - .byte %00000000 ; 03A0 1-74: - .byte %00000000 ; 03A1 1-74: - .byte %00011000 ; 03A2 1-74: ** - .byte %00000000 ; 03A3 1-74: - .byte %00000000 ; 03A4 1-74: - .byte %00011000 ; 03A5 1-74: ** - .byte %00000000 ; 03A6 1-74: - .byte %00000000 ; 03A7 1-74: + .byte %00000000 ; 03A0 1-74: + .byte %00000000 ; 03A1 1-74: + .byte %00011000 ; 03A2 1-74: ** + .byte %00000000 ; 03A3 1-74: + .byte %00000000 ; 03A4 1-74: + .byte %00011000 ; 03A5 1-74: ** + .byte %00000000 ; 03A6 1-74: + .byte %00000000 ; 03A7 1-74: - .byte %00000000 ; 03A8 1-75: - .byte %00000000 ; 03A9 1-75: - .byte %00011000 ; 03AA 1-75: ** - .byte %00000000 ; 03AB 1-75: - .byte %00000000 ; 03AC 1-75: - .byte %00011000 ; 03AD 1-75: ** - .byte %00000000 ; 03AE 1-75: - .byte %00000000 ; 03AF 1-75: + .byte %00000000 ; 03A8 1-75: + .byte %00000000 ; 03A9 1-75: + .byte %00011000 ; 03AA 1-75: ** + .byte %00000000 ; 03AB 1-75: + .byte %00000000 ; 03AC 1-75: + .byte %00011000 ; 03AD 1-75: ** + .byte %00000000 ; 03AE 1-75: + .byte %00000000 ; 03AF 1-75: - .byte %00000000 ; 03B0 1-76: - .byte %00000000 ; 03B1 1-76: - .byte %00011000 ; 03B2 1-76: ** - .byte %00000000 ; 03B3 1-76: - .byte %00000000 ; 03B4 1-76: - .byte %00011000 ; 03B5 1-76: ** - .byte %00011000 ; 03B6 1-76: ** - .byte %00110000 ; 03B7 1-76: ** + .byte %00000000 ; 03B0 1-76: + .byte %00000000 ; 03B1 1-76: + .byte %00011000 ; 03B2 1-76: ** + .byte %00000000 ; 03B3 1-76: + .byte %00000000 ; 03B4 1-76: + .byte %00011000 ; 03B5 1-76: ** + .byte %00011000 ; 03B6 1-76: ** + .byte %00110000 ; 03B7 1-76: ** - .byte %00000000 ; 03B8 1-77: - .byte %00000000 ; 03B9 1-77: - .byte %00011000 ; 03BA 1-77: ** - .byte %00000000 ; 03BB 1-77: - .byte %00000000 ; 03BC 1-77: - .byte %00011000 ; 03BD 1-77: ** - .byte %00011000 ; 03BE 1-77: ** - .byte %00110000 ; 03BF 1-77: ** + .byte %00000000 ; 03B8 1-77: + .byte %00000000 ; 03B9 1-77: + .byte %00011000 ; 03BA 1-77: ** + .byte %00000000 ; 03BB 1-77: + .byte %00000000 ; 03BC 1-77: + .byte %00011000 ; 03BD 1-77: ** + .byte %00011000 ; 03BE 1-77: ** + .byte %00110000 ; 03BF 1-77: ** - .byte %00001110 ; 03C0 1-78: *** - .byte %00011000 ; 03C1 1-78: ** - .byte %00110000 ; 03C2 1-78: ** - .byte %01100000 ; 03C3 1-78: ** - .byte %00110000 ; 03C4 1-78: ** - .byte %00011000 ; 03C5 1-78: ** - .byte %00001110 ; 03C6 1-78: *** - .byte %00000000 ; 03C7 1-78: + .byte %00001110 ; 03C0 1-78: *** + .byte %00011000 ; 03C1 1-78: ** + .byte %00110000 ; 03C2 1-78: ** + .byte %01100000 ; 03C3 1-78: ** + .byte %00110000 ; 03C4 1-78: ** + .byte %00011000 ; 03C5 1-78: ** + .byte %00001110 ; 03C6 1-78: *** + .byte %00000000 ; 03C7 1-78: - .byte %00001110 ; 03C8 1-79: *** - .byte %00011000 ; 03C9 1-79: ** - .byte %00110000 ; 03CA 1-79: ** - .byte %01100000 ; 03CB 1-79: ** - .byte %00110000 ; 03CC 1-79: ** - .byte %00011000 ; 03CD 1-79: ** - .byte %00001110 ; 03CE 1-79: *** - .byte %00000000 ; 03CF 1-79: + .byte %00001110 ; 03C8 1-79: *** + .byte %00011000 ; 03C9 1-79: ** + .byte %00110000 ; 03CA 1-79: ** + .byte %01100000 ; 03CB 1-79: ** + .byte %00110000 ; 03CC 1-79: ** + .byte %00011000 ; 03CD 1-79: ** + .byte %00001110 ; 03CE 1-79: *** + .byte %00000000 ; 03CF 1-79: - .byte %00000000 ; 03D0 1-7a: - .byte %00000000 ; 03D1 1-7a: - .byte %01111110 ; 03D2 1-7a: ****** - .byte %00000000 ; 03D3 1-7a: - .byte %01111110 ; 03D4 1-7a: ****** - .byte %00000000 ; 03D5 1-7a: - .byte %00000000 ; 03D6 1-7a: - .byte %00000000 ; 03D7 1-7a: + .byte %00000000 ; 03D0 1-7a: + .byte %00000000 ; 03D1 1-7a: + .byte %01111110 ; 03D2 1-7a: ****** + .byte %00000000 ; 03D3 1-7a: + .byte %01111110 ; 03D4 1-7a: ****** + .byte %00000000 ; 03D5 1-7a: + .byte %00000000 ; 03D6 1-7a: + .byte %00000000 ; 03D7 1-7a: - .byte %00000000 ; 03D8 1-7b: - .byte %00000000 ; 03D9 1-7b: - .byte %01111110 ; 03DA 1-7b: ****** - .byte %00000000 ; 03DB 1-7b: - .byte %01111110 ; 03DC 1-7b: ****** - .byte %00000000 ; 03DD 1-7b: - .byte %00000000 ; 03DE 1-7b: - .byte %00000000 ; 03DF 1-7b: + .byte %00000000 ; 03D8 1-7b: + .byte %00000000 ; 03D9 1-7b: + .byte %01111110 ; 03DA 1-7b: ****** + .byte %00000000 ; 03DB 1-7b: + .byte %01111110 ; 03DC 1-7b: ****** + .byte %00000000 ; 03DD 1-7b: + .byte %00000000 ; 03DE 1-7b: + .byte %00000000 ; 03DF 1-7b: - .byte %01110000 ; 03E0 1-7c: *** - .byte %00011000 ; 03E1 1-7c: ** - .byte %00001100 ; 03E2 1-7c: ** - .byte %00000110 ; 03E3 1-7c: ** - .byte %00001100 ; 03E4 1-7c: ** - .byte %00011000 ; 03E5 1-7c: ** - .byte %01110000 ; 03E6 1-7c: *** - .byte %00000000 ; 03E7 1-7c: + .byte %01110000 ; 03E0 1-7c: *** + .byte %00011000 ; 03E1 1-7c: ** + .byte %00001100 ; 03E2 1-7c: ** + .byte %00000110 ; 03E3 1-7c: ** + .byte %00001100 ; 03E4 1-7c: ** + .byte %00011000 ; 03E5 1-7c: ** + .byte %01110000 ; 03E6 1-7c: *** + .byte %00000000 ; 03E7 1-7c: - .byte %01110000 ; 03E8 1-7d: *** - .byte %00011000 ; 03E9 1-7d: ** - .byte %00001100 ; 03EA 1-7d: ** - .byte %00000110 ; 03EB 1-7d: ** - .byte %00001100 ; 03EC 1-7d: ** - .byte %00011000 ; 03ED 1-7d: ** - .byte %01110000 ; 03EE 1-7d: *** - .byte %00000000 ; 03EF 1-7d: + .byte %01110000 ; 03E8 1-7d: *** + .byte %00011000 ; 03E9 1-7d: ** + .byte %00001100 ; 03EA 1-7d: ** + .byte %00000110 ; 03EB 1-7d: ** + .byte %00001100 ; 03EC 1-7d: ** + .byte %00011000 ; 03ED 1-7d: ** + .byte %01110000 ; 03EE 1-7d: *** + .byte %00000000 ; 03EF 1-7d: - .byte %00111100 ; 03F0 1-7e: **** - .byte %01100110 ; 03F1 1-7e: ** ** - .byte %00000110 ; 03F2 1-7e: ** - .byte %00001100 ; 03F3 1-7e: ** - .byte %00011000 ; 03F4 1-7e: ** - .byte %00000000 ; 03F5 1-7e: - .byte %00011000 ; 03F6 1-7e: ** - .byte %00000000 ; 03F7 1-7e: + .byte %00111100 ; 03F0 1-7e: **** + .byte %01100110 ; 03F1 1-7e: ** ** + .byte %00000110 ; 03F2 1-7e: ** + .byte %00001100 ; 03F3 1-7e: ** + .byte %00011000 ; 03F4 1-7e: ** + .byte %00000000 ; 03F5 1-7e: + .byte %00011000 ; 03F6 1-7e: ** + .byte %00000000 ; 03F7 1-7e: - .byte %00111100 ; 03F8 1-7f: **** - .byte %01100110 ; 03F9 1-7f: ** ** - .byte %00000110 ; 03FA 1-7f: ** - .byte %00001100 ; 03FB 1-7f: ** - .byte %00011000 ; 03FC 1-7f: ** - .byte %00000000 ; 03FD 1-7f: - .byte %00011000 ; 03FE 1-7f: ** - .byte %00000000 ; 03FF 1-7f: + .byte %00111100 ; 03F8 1-7f: **** + .byte %01100110 ; 03F9 1-7f: ** ** + .byte %00000110 ; 03FA 1-7f: ** + .byte %00001100 ; 03FB 1-7f: ** + .byte %00011000 ; 03FC 1-7f: ** + .byte %00000000 ; 03FD 1-7f: + .byte %00011000 ; 03FE 1-7f: ** + .byte %00000000 ; 03FF 1-7f: - .byte %00111100 ; 0400 1-80: **** - .byte %01100110 ; 0401 1-80: ** ** - .byte %01101110 ; 0402 1-80: ** *** - .byte %01101110 ; 0403 1-80: ** *** - .byte %01100000 ; 0404 1-80: ** - .byte %01100010 ; 0405 1-80: ** * - .byte %00111100 ; 0406 1-80: **** - .byte %00000000 ; 0407 1-80: + .byte %00111100 ; 0400 1-80: **** + .byte %01100110 ; 0401 1-80: ** ** + .byte %01101110 ; 0402 1-80: ** *** + .byte %01101110 ; 0403 1-80: ** *** + .byte %01100000 ; 0404 1-80: ** + .byte %01100010 ; 0405 1-80: ** * + .byte %00111100 ; 0406 1-80: **** + .byte %00000000 ; 0407 1-80: - .byte %00111100 ; 0408 1-81: **** - .byte %01100110 ; 0409 1-81: ** ** - .byte %01101110 ; 040A 1-81: ** *** - .byte %01101110 ; 040B 1-81: ** *** - .byte %01100000 ; 040C 1-81: ** - .byte %01100010 ; 040D 1-81: ** * - .byte %00111100 ; 040E 1-81: **** - .byte %00000000 ; 040F 1-81: + .byte %00111100 ; 0408 1-81: **** + .byte %01100110 ; 0409 1-81: ** ** + .byte %01101110 ; 040A 1-81: ** *** + .byte %01101110 ; 040B 1-81: ** *** + .byte %01100000 ; 040C 1-81: ** + .byte %01100010 ; 040D 1-81: ** * + .byte %00111100 ; 040E 1-81: **** + .byte %00000000 ; 040F 1-81: - .byte %00011000 ; 0410 1-82: ** - .byte %00111100 ; 0411 1-82: **** - .byte %01100110 ; 0412 1-82: ** ** - .byte %01111110 ; 0413 1-82: ****** - .byte %01100110 ; 0414 1-82: ** ** - .byte %01100110 ; 0415 1-82: ** ** - .byte %01100110 ; 0416 1-82: ** ** - .byte %00000000 ; 0417 1-82: + .byte %00011000 ; 0410 1-82: ** + .byte %00111100 ; 0411 1-82: **** + .byte %01100110 ; 0412 1-82: ** ** + .byte %01111110 ; 0413 1-82: ****** + .byte %01100110 ; 0414 1-82: ** ** + .byte %01100110 ; 0415 1-82: ** ** + .byte %01100110 ; 0416 1-82: ** ** + .byte %00000000 ; 0417 1-82: - .byte %00011000 ; 0418 1-83: ** - .byte %00111100 ; 0419 1-83: **** - .byte %01100110 ; 041A 1-83: ** ** - .byte %01111110 ; 041B 1-83: ****** - .byte %01100110 ; 041C 1-83: ** ** - .byte %01100110 ; 041D 1-83: ** ** - .byte %01100110 ; 041E 1-83: ** ** - .byte %00000000 ; 041F 1-83: + .byte %00011000 ; 0418 1-83: ** + .byte %00111100 ; 0419 1-83: **** + .byte %01100110 ; 041A 1-83: ** ** + .byte %01111110 ; 041B 1-83: ****** + .byte %01100110 ; 041C 1-83: ** ** + .byte %01100110 ; 041D 1-83: ** ** + .byte %01100110 ; 041E 1-83: ** ** + .byte %00000000 ; 041F 1-83: - .byte %01111100 ; 0420 1-84: ***** - .byte %01100110 ; 0421 1-84: ** ** - .byte %01100110 ; 0422 1-84: ** ** - .byte %01111100 ; 0423 1-84: ***** - .byte %01100110 ; 0424 1-84: ** ** - .byte %01100110 ; 0425 1-84: ** ** - .byte %01111100 ; 0426 1-84: ***** - .byte %00000000 ; 0427 1-84: + .byte %01111100 ; 0420 1-84: ***** + .byte %01100110 ; 0421 1-84: ** ** + .byte %01100110 ; 0422 1-84: ** ** + .byte %01111100 ; 0423 1-84: ***** + .byte %01100110 ; 0424 1-84: ** ** + .byte %01100110 ; 0425 1-84: ** ** + .byte %01111100 ; 0426 1-84: ***** + .byte %00000000 ; 0427 1-84: - .byte %01111100 ; 0428 1-85: ***** - .byte %01100110 ; 0429 1-85: ** ** - .byte %01100110 ; 042A 1-85: ** ** - .byte %01111100 ; 042B 1-85: ***** - .byte %01100110 ; 042C 1-85: ** ** - .byte %01100110 ; 042D 1-85: ** ** - .byte %01111100 ; 042E 1-85: ***** - .byte %00000000 ; 042F 1-85: + .byte %01111100 ; 0428 1-85: ***** + .byte %01100110 ; 0429 1-85: ** ** + .byte %01100110 ; 042A 1-85: ** ** + .byte %01111100 ; 042B 1-85: ***** + .byte %01100110 ; 042C 1-85: ** ** + .byte %01100110 ; 042D 1-85: ** ** + .byte %01111100 ; 042E 1-85: ***** + .byte %00000000 ; 042F 1-85: - .byte %00111100 ; 0430 1-86: **** - .byte %01100110 ; 0431 1-86: ** ** - .byte %01100000 ; 0432 1-86: ** - .byte %01100000 ; 0433 1-86: ** - .byte %01100000 ; 0434 1-86: ** - .byte %01100110 ; 0435 1-86: ** ** - .byte %00111100 ; 0436 1-86: **** - .byte %00000000 ; 0437 1-86: + .byte %00111100 ; 0430 1-86: **** + .byte %01100110 ; 0431 1-86: ** ** + .byte %01100000 ; 0432 1-86: ** + .byte %01100000 ; 0433 1-86: ** + .byte %01100000 ; 0434 1-86: ** + .byte %01100110 ; 0435 1-86: ** ** + .byte %00111100 ; 0436 1-86: **** + .byte %00000000 ; 0437 1-86: - .byte %00111100 ; 0438 1-87: **** - .byte %01100110 ; 0439 1-87: ** ** - .byte %01100000 ; 043A 1-87: ** - .byte %01100000 ; 043B 1-87: ** - .byte %01100000 ; 043C 1-87: ** - .byte %01100110 ; 043D 1-87: ** ** - .byte %00111100 ; 043E 1-87: **** - .byte %00000000 ; 043F 1-87: + .byte %00111100 ; 0438 1-87: **** + .byte %01100110 ; 0439 1-87: ** ** + .byte %01100000 ; 043A 1-87: ** + .byte %01100000 ; 043B 1-87: ** + .byte %01100000 ; 043C 1-87: ** + .byte %01100110 ; 043D 1-87: ** ** + .byte %00111100 ; 043E 1-87: **** + .byte %00000000 ; 043F 1-87: - .byte %01111000 ; 0440 1-88: **** - .byte %01101100 ; 0441 1-88: ** ** - .byte %01100110 ; 0442 1-88: ** ** - .byte %01100110 ; 0443 1-88: ** ** - .byte %01100110 ; 0444 1-88: ** ** - .byte %01101100 ; 0445 1-88: ** ** - .byte %01111000 ; 0446 1-88: **** - .byte %00000000 ; 0447 1-88: + .byte %01111000 ; 0440 1-88: **** + .byte %01101100 ; 0441 1-88: ** ** + .byte %01100110 ; 0442 1-88: ** ** + .byte %01100110 ; 0443 1-88: ** ** + .byte %01100110 ; 0444 1-88: ** ** + .byte %01101100 ; 0445 1-88: ** ** + .byte %01111000 ; 0446 1-88: **** + .byte %00000000 ; 0447 1-88: - .byte %01111000 ; 0448 1-89: **** - .byte %01101100 ; 0449 1-89: ** ** - .byte %01100110 ; 044A 1-89: ** ** - .byte %01100110 ; 044B 1-89: ** ** - .byte %01100110 ; 044C 1-89: ** ** - .byte %01101100 ; 044D 1-89: ** ** - .byte %01111000 ; 044E 1-89: **** - .byte %00000000 ; 044F 1-89: + .byte %01111000 ; 0448 1-89: **** + .byte %01101100 ; 0449 1-89: ** ** + .byte %01100110 ; 044A 1-89: ** ** + .byte %01100110 ; 044B 1-89: ** ** + .byte %01100110 ; 044C 1-89: ** ** + .byte %01101100 ; 044D 1-89: ** ** + .byte %01111000 ; 044E 1-89: **** + .byte %00000000 ; 044F 1-89: - .byte %01111110 ; 0450 1-8a: ****** - .byte %01100000 ; 0451 1-8a: ** - .byte %01100000 ; 0452 1-8a: ** - .byte %01111000 ; 0453 1-8a: **** - .byte %01100000 ; 0454 1-8a: ** - .byte %01100000 ; 0455 1-8a: ** - .byte %01111110 ; 0456 1-8a: ****** - .byte %00000000 ; 0457 1-8a: + .byte %01111110 ; 0450 1-8a: ****** + .byte %01100000 ; 0451 1-8a: ** + .byte %01100000 ; 0452 1-8a: ** + .byte %01111000 ; 0453 1-8a: **** + .byte %01100000 ; 0454 1-8a: ** + .byte %01100000 ; 0455 1-8a: ** + .byte %01111110 ; 0456 1-8a: ****** + .byte %00000000 ; 0457 1-8a: - .byte %01111110 ; 0458 1-8b: ****** - .byte %01100000 ; 0459 1-8b: ** - .byte %01100000 ; 045A 1-8b: ** - .byte %01111000 ; 045B 1-8b: **** - .byte %01100000 ; 045C 1-8b: ** - .byte %01100000 ; 045D 1-8b: ** - .byte %01111110 ; 045E 1-8b: ****** - .byte %00000000 ; 045F 1-8b: + .byte %01111110 ; 0458 1-8b: ****** + .byte %01100000 ; 0459 1-8b: ** + .byte %01100000 ; 045A 1-8b: ** + .byte %01111000 ; 045B 1-8b: **** + .byte %01100000 ; 045C 1-8b: ** + .byte %01100000 ; 045D 1-8b: ** + .byte %01111110 ; 045E 1-8b: ****** + .byte %00000000 ; 045F 1-8b: - .byte %01111110 ; 0460 1-8c: ****** - .byte %01100000 ; 0461 1-8c: ** - .byte %01100000 ; 0462 1-8c: ** - .byte %01111000 ; 0463 1-8c: **** - .byte %01100000 ; 0464 1-8c: ** - .byte %01100000 ; 0465 1-8c: ** - .byte %01100000 ; 0466 1-8c: ** - .byte %00000000 ; 0467 1-8c: + .byte %01111110 ; 0460 1-8c: ****** + .byte %01100000 ; 0461 1-8c: ** + .byte %01100000 ; 0462 1-8c: ** + .byte %01111000 ; 0463 1-8c: **** + .byte %01100000 ; 0464 1-8c: ** + .byte %01100000 ; 0465 1-8c: ** + .byte %01100000 ; 0466 1-8c: ** + .byte %00000000 ; 0467 1-8c: - .byte %01111110 ; 0468 1-8d: ****** - .byte %01100000 ; 0469 1-8d: ** - .byte %01100000 ; 046A 1-8d: ** - .byte %01111000 ; 046B 1-8d: **** - .byte %01100000 ; 046C 1-8d: ** - .byte %01100000 ; 046D 1-8d: ** - .byte %01100000 ; 046E 1-8d: ** - .byte %00000000 ; 046F 1-8d: + .byte %01111110 ; 0468 1-8d: ****** + .byte %01100000 ; 0469 1-8d: ** + .byte %01100000 ; 046A 1-8d: ** + .byte %01111000 ; 046B 1-8d: **** + .byte %01100000 ; 046C 1-8d: ** + .byte %01100000 ; 046D 1-8d: ** + .byte %01100000 ; 046E 1-8d: ** + .byte %00000000 ; 046F 1-8d: - .byte %00111100 ; 0470 1-8e: **** - .byte %01100110 ; 0471 1-8e: ** ** - .byte %01100000 ; 0472 1-8e: ** - .byte %01101110 ; 0473 1-8e: ** *** - .byte %01100110 ; 0474 1-8e: ** ** - .byte %01100110 ; 0475 1-8e: ** ** - .byte %00111100 ; 0476 1-8e: **** - .byte %00000000 ; 0477 1-8e: + .byte %00111100 ; 0470 1-8e: **** + .byte %01100110 ; 0471 1-8e: ** ** + .byte %01100000 ; 0472 1-8e: ** + .byte %01101110 ; 0473 1-8e: ** *** + .byte %01100110 ; 0474 1-8e: ** ** + .byte %01100110 ; 0475 1-8e: ** ** + .byte %00111100 ; 0476 1-8e: **** + .byte %00000000 ; 0477 1-8e: - .byte %00111100 ; 0478 1-8f: **** - .byte %01100110 ; 0479 1-8f: ** ** - .byte %01100000 ; 047A 1-8f: ** - .byte %01101110 ; 047B 1-8f: ** *** - .byte %01100110 ; 047C 1-8f: ** ** - .byte %01100110 ; 047D 1-8f: ** ** - .byte %00111100 ; 047E 1-8f: **** - .byte %00000000 ; 047F 1-8f: + .byte %00111100 ; 0478 1-8f: **** + .byte %01100110 ; 0479 1-8f: ** ** + .byte %01100000 ; 047A 1-8f: ** + .byte %01101110 ; 047B 1-8f: ** *** + .byte %01100110 ; 047C 1-8f: ** ** + .byte %01100110 ; 047D 1-8f: ** ** + .byte %00111100 ; 047E 1-8f: **** + .byte %00000000 ; 047F 1-8f: - .byte %01100110 ; 0480 1-90: ** ** - .byte %01100110 ; 0481 1-90: ** ** - .byte %01100110 ; 0482 1-90: ** ** - .byte %01111110 ; 0483 1-90: ****** - .byte %01100110 ; 0484 1-90: ** ** - .byte %01100110 ; 0485 1-90: ** ** - .byte %01100110 ; 0486 1-90: ** ** - .byte %00000000 ; 0487 1-90: + .byte %01100110 ; 0480 1-90: ** ** + .byte %01100110 ; 0481 1-90: ** ** + .byte %01100110 ; 0482 1-90: ** ** + .byte %01111110 ; 0483 1-90: ****** + .byte %01100110 ; 0484 1-90: ** ** + .byte %01100110 ; 0485 1-90: ** ** + .byte %01100110 ; 0486 1-90: ** ** + .byte %00000000 ; 0487 1-90: - .byte %01100110 ; 0488 1-91: ** ** - .byte %01100110 ; 0489 1-91: ** ** - .byte %01100110 ; 048A 1-91: ** ** - .byte %01111110 ; 048B 1-91: ****** - .byte %01100110 ; 048C 1-91: ** ** - .byte %01100110 ; 048D 1-91: ** ** - .byte %01100110 ; 048E 1-91: ** ** - .byte %00000000 ; 048F 1-91: + .byte %01100110 ; 0488 1-91: ** ** + .byte %01100110 ; 0489 1-91: ** ** + .byte %01100110 ; 048A 1-91: ** ** + .byte %01111110 ; 048B 1-91: ****** + .byte %01100110 ; 048C 1-91: ** ** + .byte %01100110 ; 048D 1-91: ** ** + .byte %01100110 ; 048E 1-91: ** ** + .byte %00000000 ; 048F 1-91: - .byte %00111100 ; 0490 1-92: **** - .byte %00011000 ; 0491 1-92: ** - .byte %00011000 ; 0492 1-92: ** - .byte %00011000 ; 0493 1-92: ** - .byte %00011000 ; 0494 1-92: ** - .byte %00011000 ; 0495 1-92: ** - .byte %00111100 ; 0496 1-92: **** - .byte %00000000 ; 0497 1-92: + .byte %00111100 ; 0490 1-92: **** + .byte %00011000 ; 0491 1-92: ** + .byte %00011000 ; 0492 1-92: ** + .byte %00011000 ; 0493 1-92: ** + .byte %00011000 ; 0494 1-92: ** + .byte %00011000 ; 0495 1-92: ** + .byte %00111100 ; 0496 1-92: **** + .byte %00000000 ; 0497 1-92: - .byte %00111100 ; 0498 1-93: **** - .byte %00011000 ; 0499 1-93: ** - .byte %00011000 ; 049A 1-93: ** - .byte %00011000 ; 049B 1-93: ** - .byte %00011000 ; 049C 1-93: ** - .byte %00011000 ; 049D 1-93: ** - .byte %00111100 ; 049E 1-93: **** - .byte %00000000 ; 049F 1-93: + .byte %00111100 ; 0498 1-93: **** + .byte %00011000 ; 0499 1-93: ** + .byte %00011000 ; 049A 1-93: ** + .byte %00011000 ; 049B 1-93: ** + .byte %00011000 ; 049C 1-93: ** + .byte %00011000 ; 049D 1-93: ** + .byte %00111100 ; 049E 1-93: **** + .byte %00000000 ; 049F 1-93: - .byte %00011110 ; 04A0 1-94: **** - .byte %00001100 ; 04A1 1-94: ** - .byte %00001100 ; 04A2 1-94: ** - .byte %00001100 ; 04A3 1-94: ** - .byte %00001100 ; 04A4 1-94: ** - .byte %01101100 ; 04A5 1-94: ** ** - .byte %00111000 ; 04A6 1-94: *** - .byte %00000000 ; 04A7 1-94: + .byte %00011110 ; 04A0 1-94: **** + .byte %00001100 ; 04A1 1-94: ** + .byte %00001100 ; 04A2 1-94: ** + .byte %00001100 ; 04A3 1-94: ** + .byte %00001100 ; 04A4 1-94: ** + .byte %01101100 ; 04A5 1-94: ** ** + .byte %00111000 ; 04A6 1-94: *** + .byte %00000000 ; 04A7 1-94: - .byte %00011110 ; 04A8 1-95: **** - .byte %00001100 ; 04A9 1-95: ** - .byte %00001100 ; 04AA 1-95: ** - .byte %00001100 ; 04AB 1-95: ** - .byte %00001100 ; 04AC 1-95: ** - .byte %01101100 ; 04AD 1-95: ** ** - .byte %00111000 ; 04AE 1-95: *** - .byte %00000000 ; 04AF 1-95: + .byte %00011110 ; 04A8 1-95: **** + .byte %00001100 ; 04A9 1-95: ** + .byte %00001100 ; 04AA 1-95: ** + .byte %00001100 ; 04AB 1-95: ** + .byte %00001100 ; 04AC 1-95: ** + .byte %01101100 ; 04AD 1-95: ** ** + .byte %00111000 ; 04AE 1-95: *** + .byte %00000000 ; 04AF 1-95: - .byte %01100110 ; 04B0 1-96: ** ** - .byte %01101100 ; 04B1 1-96: ** ** - .byte %01111000 ; 04B2 1-96: **** - .byte %01110000 ; 04B3 1-96: *** - .byte %01111000 ; 04B4 1-96: **** - .byte %01101100 ; 04B5 1-96: ** ** - .byte %01100110 ; 04B6 1-96: ** ** - .byte %00000000 ; 04B7 1-96: + .byte %01100110 ; 04B0 1-96: ** ** + .byte %01101100 ; 04B1 1-96: ** ** + .byte %01111000 ; 04B2 1-96: **** + .byte %01110000 ; 04B3 1-96: *** + .byte %01111000 ; 04B4 1-96: **** + .byte %01101100 ; 04B5 1-96: ** ** + .byte %01100110 ; 04B6 1-96: ** ** + .byte %00000000 ; 04B7 1-96: - .byte %01100110 ; 04B8 1-97: ** ** - .byte %01101100 ; 04B9 1-97: ** ** - .byte %01111000 ; 04BA 1-97: **** - .byte %01110000 ; 04BB 1-97: *** - .byte %01111000 ; 04BC 1-97: **** - .byte %01101100 ; 04BD 1-97: ** ** - .byte %01100110 ; 04BE 1-97: ** ** - .byte %00000000 ; 04BF 1-97: + .byte %01100110 ; 04B8 1-97: ** ** + .byte %01101100 ; 04B9 1-97: ** ** + .byte %01111000 ; 04BA 1-97: **** + .byte %01110000 ; 04BB 1-97: *** + .byte %01111000 ; 04BC 1-97: **** + .byte %01101100 ; 04BD 1-97: ** ** + .byte %01100110 ; 04BE 1-97: ** ** + .byte %00000000 ; 04BF 1-97: - .byte %01100000 ; 04C0 1-98: ** - .byte %01100000 ; 04C1 1-98: ** - .byte %01100000 ; 04C2 1-98: ** - .byte %01100000 ; 04C3 1-98: ** - .byte %01100000 ; 04C4 1-98: ** - .byte %01100000 ; 04C5 1-98: ** - .byte %01111110 ; 04C6 1-98: ****** - .byte %00000000 ; 04C7 1-98: + .byte %01100000 ; 04C0 1-98: ** + .byte %01100000 ; 04C1 1-98: ** + .byte %01100000 ; 04C2 1-98: ** + .byte %01100000 ; 04C3 1-98: ** + .byte %01100000 ; 04C4 1-98: ** + .byte %01100000 ; 04C5 1-98: ** + .byte %01111110 ; 04C6 1-98: ****** + .byte %00000000 ; 04C7 1-98: - .byte %01100000 ; 04C8 1-99: ** - .byte %01100000 ; 04C9 1-99: ** - .byte %01100000 ; 04CA 1-99: ** - .byte %01100000 ; 04CB 1-99: ** - .byte %01100000 ; 04CC 1-99: ** - .byte %01100000 ; 04CD 1-99: ** - .byte %01111110 ; 04CE 1-99: ****** - .byte %00000000 ; 04CF 1-99: + .byte %01100000 ; 04C8 1-99: ** + .byte %01100000 ; 04C9 1-99: ** + .byte %01100000 ; 04CA 1-99: ** + .byte %01100000 ; 04CB 1-99: ** + .byte %01100000 ; 04CC 1-99: ** + .byte %01100000 ; 04CD 1-99: ** + .byte %01111110 ; 04CE 1-99: ****** + .byte %00000000 ; 04CF 1-99: .byte %01100011 ; 04D0 1-9a: ** ** .byte %01110111 ; 04D1 1-9a: *** *** @@ -1391,7 +1400,7 @@ .byte %01100011 ; 04D4 1-9a: ** ** .byte %01100011 ; 04D5 1-9a: ** ** .byte %01100011 ; 04D6 1-9a: ** ** - .byte %00000000 ; 04D7 1-9a: + .byte %00000000 ; 04D7 1-9a: .byte %01100011 ; 04D8 1-9b: ** ** .byte %01110111 ; 04D9 1-9b: *** *** @@ -1400,169 +1409,169 @@ .byte %01100011 ; 04DC 1-9b: ** ** .byte %01100011 ; 04DD 1-9b: ** ** .byte %01100011 ; 04DE 1-9b: ** ** - .byte %00000000 ; 04DF 1-9b: + .byte %00000000 ; 04DF 1-9b: - .byte %01100110 ; 04E0 1-9c: ** ** - .byte %01110110 ; 04E1 1-9c: *** ** - .byte %01111110 ; 04E2 1-9c: ****** - .byte %01111110 ; 04E3 1-9c: ****** - .byte %01101110 ; 04E4 1-9c: ** *** - .byte %01100110 ; 04E5 1-9c: ** ** - .byte %01100110 ; 04E6 1-9c: ** ** - .byte %00000000 ; 04E7 1-9c: + .byte %01100110 ; 04E0 1-9c: ** ** + .byte %01110110 ; 04E1 1-9c: *** ** + .byte %01111110 ; 04E2 1-9c: ****** + .byte %01111110 ; 04E3 1-9c: ****** + .byte %01101110 ; 04E4 1-9c: ** *** + .byte %01100110 ; 04E5 1-9c: ** ** + .byte %01100110 ; 04E6 1-9c: ** ** + .byte %00000000 ; 04E7 1-9c: - .byte %01100110 ; 04E8 1-9d: ** ** - .byte %01110110 ; 04E9 1-9d: *** ** - .byte %01111110 ; 04EA 1-9d: ****** - .byte %01111110 ; 04EB 1-9d: ****** - .byte %01101110 ; 04EC 1-9d: ** *** - .byte %01100110 ; 04ED 1-9d: ** ** - .byte %01100110 ; 04EE 1-9d: ** ** - .byte %00000000 ; 04EF 1-9d: + .byte %01100110 ; 04E8 1-9d: ** ** + .byte %01110110 ; 04E9 1-9d: *** ** + .byte %01111110 ; 04EA 1-9d: ****** + .byte %01111110 ; 04EB 1-9d: ****** + .byte %01101110 ; 04EC 1-9d: ** *** + .byte %01100110 ; 04ED 1-9d: ** ** + .byte %01100110 ; 04EE 1-9d: ** ** + .byte %00000000 ; 04EF 1-9d: - .byte %00111100 ; 04F0 1-9e: **** - .byte %01100110 ; 04F1 1-9e: ** ** - .byte %01100110 ; 04F2 1-9e: ** ** - .byte %01100110 ; 04F3 1-9e: ** ** - .byte %01100110 ; 04F4 1-9e: ** ** - .byte %01100110 ; 04F5 1-9e: ** ** - .byte %00111100 ; 04F6 1-9e: **** - .byte %00000000 ; 04F7 1-9e: + .byte %00111100 ; 04F0 1-9e: **** + .byte %01100110 ; 04F1 1-9e: ** ** + .byte %01100110 ; 04F2 1-9e: ** ** + .byte %01100110 ; 04F3 1-9e: ** ** + .byte %01100110 ; 04F4 1-9e: ** ** + .byte %01100110 ; 04F5 1-9e: ** ** + .byte %00111100 ; 04F6 1-9e: **** + .byte %00000000 ; 04F7 1-9e: - .byte %00111100 ; 04F8 1-9f: **** - .byte %01100110 ; 04F9 1-9f: ** ** - .byte %01100110 ; 04FA 1-9f: ** ** - .byte %01100110 ; 04FB 1-9f: ** ** - .byte %01100110 ; 04FC 1-9f: ** ** - .byte %01100110 ; 04FD 1-9f: ** ** - .byte %00111100 ; 04FE 1-9f: **** - .byte %00000000 ; 04FF 1-9f: + .byte %00111100 ; 04F8 1-9f: **** + .byte %01100110 ; 04F9 1-9f: ** ** + .byte %01100110 ; 04FA 1-9f: ** ** + .byte %01100110 ; 04FB 1-9f: ** ** + .byte %01100110 ; 04FC 1-9f: ** ** + .byte %01100110 ; 04FD 1-9f: ** ** + .byte %00111100 ; 04FE 1-9f: **** + .byte %00000000 ; 04FF 1-9f: - .byte %01111100 ; 0500 1-a0: ***** - .byte %01100110 ; 0501 1-a0: ** ** - .byte %01100110 ; 0502 1-a0: ** ** - .byte %01111100 ; 0503 1-a0: ***** - .byte %01100000 ; 0504 1-a0: ** - .byte %01100000 ; 0505 1-a0: ** - .byte %01100000 ; 0506 1-a0: ** - .byte %00000000 ; 0507 1-a0: + .byte %01111100 ; 0500 1-a0: ***** + .byte %01100110 ; 0501 1-a0: ** ** + .byte %01100110 ; 0502 1-a0: ** ** + .byte %01111100 ; 0503 1-a0: ***** + .byte %01100000 ; 0504 1-a0: ** + .byte %01100000 ; 0505 1-a0: ** + .byte %01100000 ; 0506 1-a0: ** + .byte %00000000 ; 0507 1-a0: - .byte %01111100 ; 0508 1-a1: ***** - .byte %01100110 ; 0509 1-a1: ** ** - .byte %01100110 ; 050A 1-a1: ** ** - .byte %01111100 ; 050B 1-a1: ***** - .byte %01100000 ; 050C 1-a1: ** - .byte %01100000 ; 050D 1-a1: ** - .byte %01100000 ; 050E 1-a1: ** - .byte %00000000 ; 050F 1-a1: + .byte %01111100 ; 0508 1-a1: ***** + .byte %01100110 ; 0509 1-a1: ** ** + .byte %01100110 ; 050A 1-a1: ** ** + .byte %01111100 ; 050B 1-a1: ***** + .byte %01100000 ; 050C 1-a1: ** + .byte %01100000 ; 050D 1-a1: ** + .byte %01100000 ; 050E 1-a1: ** + .byte %00000000 ; 050F 1-a1: - .byte %00111100 ; 0510 1-a2: **** - .byte %01100110 ; 0511 1-a2: ** ** - .byte %01100110 ; 0512 1-a2: ** ** - .byte %01100110 ; 0513 1-a2: ** ** - .byte %01100110 ; 0514 1-a2: ** ** - .byte %00111100 ; 0515 1-a2: **** - .byte %00001110 ; 0516 1-a2: *** - .byte %00000000 ; 0517 1-a2: + .byte %00111100 ; 0510 1-a2: **** + .byte %01100110 ; 0511 1-a2: ** ** + .byte %01100110 ; 0512 1-a2: ** ** + .byte %01100110 ; 0513 1-a2: ** ** + .byte %01100110 ; 0514 1-a2: ** ** + .byte %00111100 ; 0515 1-a2: **** + .byte %00001110 ; 0516 1-a2: *** + .byte %00000000 ; 0517 1-a2: - .byte %00111100 ; 0518 1-a3: **** - .byte %01100110 ; 0519 1-a3: ** ** - .byte %01100110 ; 051A 1-a3: ** ** - .byte %01100110 ; 051B 1-a3: ** ** - .byte %01100110 ; 051C 1-a3: ** ** - .byte %00111100 ; 051D 1-a3: **** - .byte %00001110 ; 051E 1-a3: *** - .byte %00000000 ; 051F 1-a3: + .byte %00111100 ; 0518 1-a3: **** + .byte %01100110 ; 0519 1-a3: ** ** + .byte %01100110 ; 051A 1-a3: ** ** + .byte %01100110 ; 051B 1-a3: ** ** + .byte %01100110 ; 051C 1-a3: ** ** + .byte %00111100 ; 051D 1-a3: **** + .byte %00001110 ; 051E 1-a3: *** + .byte %00000000 ; 051F 1-a3: - .byte %01111100 ; 0520 1-a4: ***** - .byte %01100110 ; 0521 1-a4: ** ** - .byte %01100110 ; 0522 1-a4: ** ** - .byte %01111100 ; 0523 1-a4: ***** - .byte %01111000 ; 0524 1-a4: **** - .byte %01101100 ; 0525 1-a4: ** ** - .byte %01100110 ; 0526 1-a4: ** ** - .byte %00000000 ; 0527 1-a4: + .byte %01111100 ; 0520 1-a4: ***** + .byte %01100110 ; 0521 1-a4: ** ** + .byte %01100110 ; 0522 1-a4: ** ** + .byte %01111100 ; 0523 1-a4: ***** + .byte %01111000 ; 0524 1-a4: **** + .byte %01101100 ; 0525 1-a4: ** ** + .byte %01100110 ; 0526 1-a4: ** ** + .byte %00000000 ; 0527 1-a4: - .byte %01111100 ; 0528 1-a5: ***** - .byte %01100110 ; 0529 1-a5: ** ** - .byte %01100110 ; 052A 1-a5: ** ** - .byte %01111100 ; 052B 1-a5: ***** - .byte %01111000 ; 052C 1-a5: **** - .byte %01101100 ; 052D 1-a5: ** ** - .byte %01100110 ; 052E 1-a5: ** ** - .byte %00000000 ; 052F 1-a5: + .byte %01111100 ; 0528 1-a5: ***** + .byte %01100110 ; 0529 1-a5: ** ** + .byte %01100110 ; 052A 1-a5: ** ** + .byte %01111100 ; 052B 1-a5: ***** + .byte %01111000 ; 052C 1-a5: **** + .byte %01101100 ; 052D 1-a5: ** ** + .byte %01100110 ; 052E 1-a5: ** ** + .byte %00000000 ; 052F 1-a5: - .byte %00111100 ; 0530 1-a6: **** - .byte %01100110 ; 0531 1-a6: ** ** - .byte %01100000 ; 0532 1-a6: ** - .byte %00111100 ; 0533 1-a6: **** - .byte %00000110 ; 0534 1-a6: ** - .byte %01100110 ; 0535 1-a6: ** ** - .byte %00111100 ; 0536 1-a6: **** - .byte %00000000 ; 0537 1-a6: + .byte %00111100 ; 0530 1-a6: **** + .byte %01100110 ; 0531 1-a6: ** ** + .byte %01100000 ; 0532 1-a6: ** + .byte %00111100 ; 0533 1-a6: **** + .byte %00000110 ; 0534 1-a6: ** + .byte %01100110 ; 0535 1-a6: ** ** + .byte %00111100 ; 0536 1-a6: **** + .byte %00000000 ; 0537 1-a6: - .byte %00111100 ; 0538 1-a7: **** - .byte %01100110 ; 0539 1-a7: ** ** - .byte %01100000 ; 053A 1-a7: ** - .byte %00111100 ; 053B 1-a7: **** - .byte %00000110 ; 053C 1-a7: ** - .byte %01100110 ; 053D 1-a7: ** ** - .byte %00111100 ; 053E 1-a7: **** - .byte %00000000 ; 053F 1-a7: + .byte %00111100 ; 0538 1-a7: **** + .byte %01100110 ; 0539 1-a7: ** ** + .byte %01100000 ; 053A 1-a7: ** + .byte %00111100 ; 053B 1-a7: **** + .byte %00000110 ; 053C 1-a7: ** + .byte %01100110 ; 053D 1-a7: ** ** + .byte %00111100 ; 053E 1-a7: **** + .byte %00000000 ; 053F 1-a7: - .byte %01111110 ; 0540 1-a8: ****** - .byte %00011000 ; 0541 1-a8: ** - .byte %00011000 ; 0542 1-a8: ** - .byte %00011000 ; 0543 1-a8: ** - .byte %00011000 ; 0544 1-a8: ** - .byte %00011000 ; 0545 1-a8: ** - .byte %00011000 ; 0546 1-a8: ** - .byte %00000000 ; 0547 1-a8: + .byte %01111110 ; 0540 1-a8: ****** + .byte %00011000 ; 0541 1-a8: ** + .byte %00011000 ; 0542 1-a8: ** + .byte %00011000 ; 0543 1-a8: ** + .byte %00011000 ; 0544 1-a8: ** + .byte %00011000 ; 0545 1-a8: ** + .byte %00011000 ; 0546 1-a8: ** + .byte %00000000 ; 0547 1-a8: - .byte %01111110 ; 0548 1-a9: ****** - .byte %00011000 ; 0549 1-a9: ** - .byte %00011000 ; 054A 1-a9: ** - .byte %00011000 ; 054B 1-a9: ** - .byte %00011000 ; 054C 1-a9: ** - .byte %00011000 ; 054D 1-a9: ** - .byte %00011000 ; 054E 1-a9: ** - .byte %00000000 ; 054F 1-a9: + .byte %01111110 ; 0548 1-a9: ****** + .byte %00011000 ; 0549 1-a9: ** + .byte %00011000 ; 054A 1-a9: ** + .byte %00011000 ; 054B 1-a9: ** + .byte %00011000 ; 054C 1-a9: ** + .byte %00011000 ; 054D 1-a9: ** + .byte %00011000 ; 054E 1-a9: ** + .byte %00000000 ; 054F 1-a9: - .byte %01100110 ; 0550 1-aa: ** ** - .byte %01100110 ; 0551 1-aa: ** ** - .byte %01100110 ; 0552 1-aa: ** ** - .byte %01100110 ; 0553 1-aa: ** ** - .byte %01100110 ; 0554 1-aa: ** ** - .byte %01100110 ; 0555 1-aa: ** ** - .byte %00111100 ; 0556 1-aa: **** - .byte %00000000 ; 0557 1-aa: + .byte %01100110 ; 0550 1-aa: ** ** + .byte %01100110 ; 0551 1-aa: ** ** + .byte %01100110 ; 0552 1-aa: ** ** + .byte %01100110 ; 0553 1-aa: ** ** + .byte %01100110 ; 0554 1-aa: ** ** + .byte %01100110 ; 0555 1-aa: ** ** + .byte %00111100 ; 0556 1-aa: **** + .byte %00000000 ; 0557 1-aa: - .byte %01100110 ; 0558 1-ab: ** ** - .byte %01100110 ; 0559 1-ab: ** ** - .byte %01100110 ; 055A 1-ab: ** ** - .byte %01100110 ; 055B 1-ab: ** ** - .byte %01100110 ; 055C 1-ab: ** ** - .byte %01100110 ; 055D 1-ab: ** ** - .byte %00111100 ; 055E 1-ab: **** - .byte %00000000 ; 055F 1-ab: + .byte %01100110 ; 0558 1-ab: ** ** + .byte %01100110 ; 0559 1-ab: ** ** + .byte %01100110 ; 055A 1-ab: ** ** + .byte %01100110 ; 055B 1-ab: ** ** + .byte %01100110 ; 055C 1-ab: ** ** + .byte %01100110 ; 055D 1-ab: ** ** + .byte %00111100 ; 055E 1-ab: **** + .byte %00000000 ; 055F 1-ab: - .byte %01100110 ; 0560 1-ac: ** ** - .byte %01100110 ; 0561 1-ac: ** ** - .byte %01100110 ; 0562 1-ac: ** ** - .byte %01100110 ; 0563 1-ac: ** ** - .byte %01100110 ; 0564 1-ac: ** ** - .byte %00111100 ; 0565 1-ac: **** - .byte %00011000 ; 0566 1-ac: ** - .byte %00000000 ; 0567 1-ac: + .byte %01100110 ; 0560 1-ac: ** ** + .byte %01100110 ; 0561 1-ac: ** ** + .byte %01100110 ; 0562 1-ac: ** ** + .byte %01100110 ; 0563 1-ac: ** ** + .byte %01100110 ; 0564 1-ac: ** ** + .byte %00111100 ; 0565 1-ac: **** + .byte %00011000 ; 0566 1-ac: ** + .byte %00000000 ; 0567 1-ac: - .byte %01100110 ; 0568 1-ad: ** ** - .byte %01100110 ; 0569 1-ad: ** ** - .byte %01100110 ; 056A 1-ad: ** ** - .byte %01100110 ; 056B 1-ad: ** ** - .byte %01100110 ; 056C 1-ad: ** ** - .byte %00111100 ; 056D 1-ad: **** - .byte %00011000 ; 056E 1-ad: ** - .byte %00000000 ; 056F 1-ad: + .byte %01100110 ; 0568 1-ad: ** ** + .byte %01100110 ; 0569 1-ad: ** ** + .byte %01100110 ; 056A 1-ad: ** ** + .byte %01100110 ; 056B 1-ad: ** ** + .byte %01100110 ; 056C 1-ad: ** ** + .byte %00111100 ; 056D 1-ad: **** + .byte %00011000 ; 056E 1-ad: ** + .byte %00000000 ; 056F 1-ad: .byte %01100011 ; 0570 1-ae: ** ** .byte %01100011 ; 0571 1-ae: ** ** @@ -1571,7 +1580,7 @@ .byte %01111111 ; 0574 1-ae: ******* .byte %01110111 ; 0575 1-ae: *** *** .byte %01100011 ; 0576 1-ae: ** ** - .byte %00000000 ; 0577 1-ae: + .byte %00000000 ; 0577 1-ae: .byte %01100011 ; 0578 1-af: ** ** .byte %01100011 ; 0579 1-af: ** ** @@ -1580,727 +1589,727 @@ .byte %01111111 ; 057C 1-af: ******* .byte %01110111 ; 057D 1-af: *** *** .byte %01100011 ; 057E 1-af: ** ** - .byte %00000000 ; 057F 1-af: + .byte %00000000 ; 057F 1-af: - .byte %01100110 ; 0580 1-b0: ** ** - .byte %01100110 ; 0581 1-b0: ** ** - .byte %00111100 ; 0582 1-b0: **** - .byte %00011000 ; 0583 1-b0: ** - .byte %00111100 ; 0584 1-b0: **** - .byte %01100110 ; 0585 1-b0: ** ** - .byte %01100110 ; 0586 1-b0: ** ** - .byte %00000000 ; 0587 1-b0: + .byte %01100110 ; 0580 1-b0: ** ** + .byte %01100110 ; 0581 1-b0: ** ** + .byte %00111100 ; 0582 1-b0: **** + .byte %00011000 ; 0583 1-b0: ** + .byte %00111100 ; 0584 1-b0: **** + .byte %01100110 ; 0585 1-b0: ** ** + .byte %01100110 ; 0586 1-b0: ** ** + .byte %00000000 ; 0587 1-b0: - .byte %01100110 ; 0588 1-b1: ** ** - .byte %01100110 ; 0589 1-b1: ** ** - .byte %00111100 ; 058A 1-b1: **** - .byte %00011000 ; 058B 1-b1: ** - .byte %00111100 ; 058C 1-b1: **** - .byte %01100110 ; 058D 1-b1: ** ** - .byte %01100110 ; 058E 1-b1: ** ** - .byte %00000000 ; 058F 1-b1: + .byte %01100110 ; 0588 1-b1: ** ** + .byte %01100110 ; 0589 1-b1: ** ** + .byte %00111100 ; 058A 1-b1: **** + .byte %00011000 ; 058B 1-b1: ** + .byte %00111100 ; 058C 1-b1: **** + .byte %01100110 ; 058D 1-b1: ** ** + .byte %01100110 ; 058E 1-b1: ** ** + .byte %00000000 ; 058F 1-b1: - .byte %01100110 ; 0590 1-b2: ** ** - .byte %01100110 ; 0591 1-b2: ** ** - .byte %01100110 ; 0592 1-b2: ** ** - .byte %00111100 ; 0593 1-b2: **** - .byte %00011000 ; 0594 1-b2: ** - .byte %00011000 ; 0595 1-b2: ** - .byte %00011000 ; 0596 1-b2: ** - .byte %00000000 ; 0597 1-b2: + .byte %01100110 ; 0590 1-b2: ** ** + .byte %01100110 ; 0591 1-b2: ** ** + .byte %01100110 ; 0592 1-b2: ** ** + .byte %00111100 ; 0593 1-b2: **** + .byte %00011000 ; 0594 1-b2: ** + .byte %00011000 ; 0595 1-b2: ** + .byte %00011000 ; 0596 1-b2: ** + .byte %00000000 ; 0597 1-b2: - .byte %01100110 ; 0598 1-b3: ** ** - .byte %01100110 ; 0599 1-b3: ** ** - .byte %01100110 ; 059A 1-b3: ** ** - .byte %00111100 ; 059B 1-b3: **** - .byte %00011000 ; 059C 1-b3: ** - .byte %00011000 ; 059D 1-b3: ** - .byte %00011000 ; 059E 1-b3: ** - .byte %00000000 ; 059F 1-b3: + .byte %01100110 ; 0598 1-b3: ** ** + .byte %01100110 ; 0599 1-b3: ** ** + .byte %01100110 ; 059A 1-b3: ** ** + .byte %00111100 ; 059B 1-b3: **** + .byte %00011000 ; 059C 1-b3: ** + .byte %00011000 ; 059D 1-b3: ** + .byte %00011000 ; 059E 1-b3: ** + .byte %00000000 ; 059F 1-b3: - .byte %01111110 ; 05A0 1-b4: ****** - .byte %00000110 ; 05A1 1-b4: ** - .byte %00001100 ; 05A2 1-b4: ** - .byte %00011000 ; 05A3 1-b4: ** - .byte %00110000 ; 05A4 1-b4: ** - .byte %01100000 ; 05A5 1-b4: ** - .byte %01111110 ; 05A6 1-b4: ****** - .byte %00000000 ; 05A7 1-b4: + .byte %01111110 ; 05A0 1-b4: ****** + .byte %00000110 ; 05A1 1-b4: ** + .byte %00001100 ; 05A2 1-b4: ** + .byte %00011000 ; 05A3 1-b4: ** + .byte %00110000 ; 05A4 1-b4: ** + .byte %01100000 ; 05A5 1-b4: ** + .byte %01111110 ; 05A6 1-b4: ****** + .byte %00000000 ; 05A7 1-b4: - .byte %01111110 ; 05A8 1-b5: ****** - .byte %00000110 ; 05A9 1-b5: ** - .byte %00001100 ; 05AA 1-b5: ** - .byte %00011000 ; 05AB 1-b5: ** - .byte %00110000 ; 05AC 1-b5: ** - .byte %01100000 ; 05AD 1-b5: ** - .byte %01111110 ; 05AE 1-b5: ****** - .byte %00000000 ; 05AF 1-b5: + .byte %01111110 ; 05A8 1-b5: ****** + .byte %00000110 ; 05A9 1-b5: ** + .byte %00001100 ; 05AA 1-b5: ** + .byte %00011000 ; 05AB 1-b5: ** + .byte %00110000 ; 05AC 1-b5: ** + .byte %01100000 ; 05AD 1-b5: ** + .byte %01111110 ; 05AE 1-b5: ****** + .byte %00000000 ; 05AF 1-b5: - .byte %00111100 ; 05B0 1-b6: **** - .byte %00110000 ; 05B1 1-b6: ** - .byte %00110000 ; 05B2 1-b6: ** - .byte %00110000 ; 05B3 1-b6: ** - .byte %00110000 ; 05B4 1-b6: ** - .byte %00110000 ; 05B5 1-b6: ** - .byte %00111100 ; 05B6 1-b6: **** - .byte %00000000 ; 05B7 1-b6: + .byte %00111100 ; 05B0 1-b6: **** + .byte %00110000 ; 05B1 1-b6: ** + .byte %00110000 ; 05B2 1-b6: ** + .byte %00110000 ; 05B3 1-b6: ** + .byte %00110000 ; 05B4 1-b6: ** + .byte %00110000 ; 05B5 1-b6: ** + .byte %00111100 ; 05B6 1-b6: **** + .byte %00000000 ; 05B7 1-b6: - .byte %00111100 ; 05B8 1-b7: **** - .byte %00110000 ; 05B9 1-b7: ** - .byte %00110000 ; 05BA 1-b7: ** - .byte %00110000 ; 05BB 1-b7: ** - .byte %00110000 ; 05BC 1-b7: ** - .byte %00110000 ; 05BD 1-b7: ** - .byte %00111100 ; 05BE 1-b7: **** - .byte %00000000 ; 05BF 1-b7: + .byte %00111100 ; 05B8 1-b7: **** + .byte %00110000 ; 05B9 1-b7: ** + .byte %00110000 ; 05BA 1-b7: ** + .byte %00110000 ; 05BB 1-b7: ** + .byte %00110000 ; 05BC 1-b7: ** + .byte %00110000 ; 05BD 1-b7: ** + .byte %00111100 ; 05BE 1-b7: **** + .byte %00000000 ; 05BF 1-b7: - .byte %01100000 ; 05C0 1-b8: ** - .byte %00110000 ; 05C1 1-b8: ** - .byte %00011000 ; 05C2 1-b8: ** - .byte %00001100 ; 05C3 1-b8: ** - .byte %00000110 ; 05C4 1-b8: ** + .byte %01100000 ; 05C0 1-b8: ** + .byte %00110000 ; 05C1 1-b8: ** + .byte %00011000 ; 05C2 1-b8: ** + .byte %00001100 ; 05C3 1-b8: ** + .byte %00000110 ; 05C4 1-b8: ** .byte %00000011 ; 05C5 1-b8: ** - .byte %00000000 ; 05C6 1-b8: - .byte %00000000 ; 05C7 1-b8: + .byte %00000000 ; 05C6 1-b8: + .byte %00000000 ; 05C7 1-b8: - .byte %01100000 ; 05C8 1-b9: ** - .byte %00110000 ; 05C9 1-b9: ** - .byte %00011000 ; 05CA 1-b9: ** - .byte %00001100 ; 05CB 1-b9: ** - .byte %00000110 ; 05CC 1-b9: ** + .byte %01100000 ; 05C8 1-b9: ** + .byte %00110000 ; 05C9 1-b9: ** + .byte %00011000 ; 05CA 1-b9: ** + .byte %00001100 ; 05CB 1-b9: ** + .byte %00000110 ; 05CC 1-b9: ** .byte %00000011 ; 05CD 1-b9: ** - .byte %00000000 ; 05CE 1-b9: - .byte %00000000 ; 05CF 1-b9: + .byte %00000000 ; 05CE 1-b9: + .byte %00000000 ; 05CF 1-b9: - .byte %00111100 ; 05D0 1-ba: **** - .byte %00001100 ; 05D1 1-ba: ** - .byte %00001100 ; 05D2 1-ba: ** - .byte %00001100 ; 05D3 1-ba: ** - .byte %00001100 ; 05D4 1-ba: ** - .byte %00001100 ; 05D5 1-ba: ** - .byte %00111100 ; 05D6 1-ba: **** - .byte %00000000 ; 05D7 1-ba: + .byte %00111100 ; 05D0 1-ba: **** + .byte %00001100 ; 05D1 1-ba: ** + .byte %00001100 ; 05D2 1-ba: ** + .byte %00001100 ; 05D3 1-ba: ** + .byte %00001100 ; 05D4 1-ba: ** + .byte %00001100 ; 05D5 1-ba: ** + .byte %00111100 ; 05D6 1-ba: **** + .byte %00000000 ; 05D7 1-ba: - .byte %00111100 ; 05D8 1-bb: **** - .byte %00001100 ; 05D9 1-bb: ** - .byte %00001100 ; 05DA 1-bb: ** - .byte %00001100 ; 05DB 1-bb: ** - .byte %00001100 ; 05DC 1-bb: ** - .byte %00001100 ; 05DD 1-bb: ** - .byte %00111100 ; 05DE 1-bb: **** - .byte %00000000 ; 05DF 1-bb: + .byte %00111100 ; 05D8 1-bb: **** + .byte %00001100 ; 05D9 1-bb: ** + .byte %00001100 ; 05DA 1-bb: ** + .byte %00001100 ; 05DB 1-bb: ** + .byte %00001100 ; 05DC 1-bb: ** + .byte %00001100 ; 05DD 1-bb: ** + .byte %00111100 ; 05DE 1-bb: **** + .byte %00000000 ; 05DF 1-bb: - .byte %00000000 ; 05E0 1-bc: - .byte %00011000 ; 05E1 1-bc: ** - .byte %00111100 ; 05E2 1-bc: **** - .byte %01100110 ; 05E3 1-bc: ** ** - .byte %00000000 ; 05E4 1-bc: - .byte %00000000 ; 05E5 1-bc: - .byte %00000000 ; 05E6 1-bc: - .byte %00000000 ; 05E7 1-bc: + .byte %00000000 ; 05E0 1-bc: + .byte %00011000 ; 05E1 1-bc: ** + .byte %00111100 ; 05E2 1-bc: **** + .byte %01100110 ; 05E3 1-bc: ** ** + .byte %00000000 ; 05E4 1-bc: + .byte %00000000 ; 05E5 1-bc: + .byte %00000000 ; 05E6 1-bc: + .byte %00000000 ; 05E7 1-bc: - .byte %00000000 ; 05E8 1-bd: - .byte %00011000 ; 05E9 1-bd: ** - .byte %00111100 ; 05EA 1-bd: **** - .byte %01100110 ; 05EB 1-bd: ** ** - .byte %00000000 ; 05EC 1-bd: - .byte %00000000 ; 05ED 1-bd: - .byte %00000000 ; 05EE 1-bd: - .byte %00000000 ; 05EF 1-bd: + .byte %00000000 ; 05E8 1-bd: + .byte %00011000 ; 05E9 1-bd: ** + .byte %00111100 ; 05EA 1-bd: **** + .byte %01100110 ; 05EB 1-bd: ** ** + .byte %00000000 ; 05EC 1-bd: + .byte %00000000 ; 05ED 1-bd: + .byte %00000000 ; 05EE 1-bd: + .byte %00000000 ; 05EF 1-bd: - .byte %00000000 ; 05F0 1-be: - .byte %00000000 ; 05F1 1-be: - .byte %00000000 ; 05F2 1-be: - .byte %00000000 ; 05F3 1-be: - .byte %00000000 ; 05F4 1-be: - .byte %00000000 ; 05F5 1-be: + .byte %00000000 ; 05F0 1-be: + .byte %00000000 ; 05F1 1-be: + .byte %00000000 ; 05F2 1-be: + .byte %00000000 ; 05F3 1-be: + .byte %00000000 ; 05F4 1-be: + .byte %00000000 ; 05F5 1-be: .byte %01111111 ; 05F6 1-be: ******* - .byte %00000000 ; 05F7 1-be: + .byte %00000000 ; 05F7 1-be: - .byte %00000000 ; 05F8 1-bf: - .byte %00000000 ; 05F9 1-bf: - .byte %00000000 ; 05FA 1-bf: - .byte %00000000 ; 05FB 1-bf: - .byte %00000000 ; 05FC 1-bf: - .byte %00000000 ; 05FD 1-bf: + .byte %00000000 ; 05F8 1-bf: + .byte %00000000 ; 05F9 1-bf: + .byte %00000000 ; 05FA 1-bf: + .byte %00000000 ; 05FB 1-bf: + .byte %00000000 ; 05FC 1-bf: + .byte %00000000 ; 05FD 1-bf: .byte %01111111 ; 05FE 1-bf: ******* - .byte %00000000 ; 05FF 1-bf: + .byte %00000000 ; 05FF 1-bf: - .byte %00011000 ; 0600 1-c0: ** - .byte %00011000 ; 0601 1-c0: ** - .byte %00011000 ; 0602 1-c0: ** - .byte %00000000 ; 0603 1-c0: - .byte %00000000 ; 0604 1-c0: - .byte %00000000 ; 0605 1-c0: - .byte %00000000 ; 0606 1-c0: - .byte %00000000 ; 0607 1-c0: + .byte %00011000 ; 0600 1-c0: ** + .byte %00011000 ; 0601 1-c0: ** + .byte %00011000 ; 0602 1-c0: ** + .byte %00000000 ; 0603 1-c0: + .byte %00000000 ; 0604 1-c0: + .byte %00000000 ; 0605 1-c0: + .byte %00000000 ; 0606 1-c0: + .byte %00000000 ; 0607 1-c0: - .byte %00011000 ; 0608 1-c1: ** - .byte %00011000 ; 0609 1-c1: ** - .byte %00011000 ; 060A 1-c1: ** - .byte %00000000 ; 060B 1-c1: - .byte %00000000 ; 060C 1-c1: - .byte %00000000 ; 060D 1-c1: - .byte %00000000 ; 060E 1-c1: - .byte %00000000 ; 060F 1-c1: + .byte %00011000 ; 0608 1-c1: ** + .byte %00011000 ; 0609 1-c1: ** + .byte %00011000 ; 060A 1-c1: ** + .byte %00000000 ; 060B 1-c1: + .byte %00000000 ; 060C 1-c1: + .byte %00000000 ; 060D 1-c1: + .byte %00000000 ; 060E 1-c1: + .byte %00000000 ; 060F 1-c1: - .byte %00000000 ; 0610 1-c2: - .byte %00000000 ; 0611 1-c2: - .byte %00111100 ; 0612 1-c2: **** - .byte %00000110 ; 0613 1-c2: ** - .byte %00111110 ; 0614 1-c2: ***** - .byte %01100110 ; 0615 1-c2: ** ** - .byte %00111110 ; 0616 1-c2: ***** - .byte %00000000 ; 0617 1-c2: + .byte %00000000 ; 0610 1-c2: + .byte %00000000 ; 0611 1-c2: + .byte %00111100 ; 0612 1-c2: **** + .byte %00000110 ; 0613 1-c2: ** + .byte %00111110 ; 0614 1-c2: ***** + .byte %01100110 ; 0615 1-c2: ** ** + .byte %00111110 ; 0616 1-c2: ***** + .byte %00000000 ; 0617 1-c2: - .byte %00000000 ; 0618 1-c3: - .byte %00000000 ; 0619 1-c3: - .byte %00111100 ; 061A 1-c3: **** - .byte %00000110 ; 061B 1-c3: ** - .byte %00111110 ; 061C 1-c3: ***** - .byte %01100110 ; 061D 1-c3: ** ** - .byte %00111110 ; 061E 1-c3: ***** - .byte %00000000 ; 061F 1-c3: + .byte %00000000 ; 0618 1-c3: + .byte %00000000 ; 0619 1-c3: + .byte %00111100 ; 061A 1-c3: **** + .byte %00000110 ; 061B 1-c3: ** + .byte %00111110 ; 061C 1-c3: ***** + .byte %01100110 ; 061D 1-c3: ** ** + .byte %00111110 ; 061E 1-c3: ***** + .byte %00000000 ; 061F 1-c3: - .byte %00000000 ; 0620 1-c4: - .byte %01100000 ; 0621 1-c4: ** - .byte %01100000 ; 0622 1-c4: ** - .byte %01111100 ; 0623 1-c4: ***** - .byte %01100110 ; 0624 1-c4: ** ** - .byte %01100110 ; 0625 1-c4: ** ** - .byte %01111100 ; 0626 1-c4: ***** - .byte %00000000 ; 0627 1-c4: + .byte %00000000 ; 0620 1-c4: + .byte %01100000 ; 0621 1-c4: ** + .byte %01100000 ; 0622 1-c4: ** + .byte %01111100 ; 0623 1-c4: ***** + .byte %01100110 ; 0624 1-c4: ** ** + .byte %01100110 ; 0625 1-c4: ** ** + .byte %01111100 ; 0626 1-c4: ***** + .byte %00000000 ; 0627 1-c4: - .byte %00000000 ; 0628 1-c5: - .byte %01100000 ; 0629 1-c5: ** - .byte %01100000 ; 062A 1-c5: ** - .byte %01111100 ; 062B 1-c5: ***** - .byte %01100110 ; 062C 1-c5: ** ** - .byte %01100110 ; 062D 1-c5: ** ** - .byte %01111100 ; 062E 1-c5: ***** - .byte %00000000 ; 062F 1-c5: + .byte %00000000 ; 0628 1-c5: + .byte %01100000 ; 0629 1-c5: ** + .byte %01100000 ; 062A 1-c5: ** + .byte %01111100 ; 062B 1-c5: ***** + .byte %01100110 ; 062C 1-c5: ** ** + .byte %01100110 ; 062D 1-c5: ** ** + .byte %01111100 ; 062E 1-c5: ***** + .byte %00000000 ; 062F 1-c5: - .byte %00000000 ; 0630 1-c6: - .byte %00000000 ; 0631 1-c6: - .byte %00111100 ; 0632 1-c6: **** - .byte %01100000 ; 0633 1-c6: ** - .byte %01100000 ; 0634 1-c6: ** - .byte %01100000 ; 0635 1-c6: ** - .byte %00111100 ; 0636 1-c6: **** - .byte %00000000 ; 0637 1-c6: + .byte %00000000 ; 0630 1-c6: + .byte %00000000 ; 0631 1-c6: + .byte %00111100 ; 0632 1-c6: **** + .byte %01100000 ; 0633 1-c6: ** + .byte %01100000 ; 0634 1-c6: ** + .byte %01100000 ; 0635 1-c6: ** + .byte %00111100 ; 0636 1-c6: **** + .byte %00000000 ; 0637 1-c6: - .byte %00000000 ; 0638 1-c7: - .byte %00000000 ; 0639 1-c7: - .byte %00111100 ; 063A 1-c7: **** - .byte %01100000 ; 063B 1-c7: ** - .byte %01100000 ; 063C 1-c7: ** - .byte %01100000 ; 063D 1-c7: ** - .byte %00111100 ; 063E 1-c7: **** - .byte %00000000 ; 063F 1-c7: + .byte %00000000 ; 0638 1-c7: + .byte %00000000 ; 0639 1-c7: + .byte %00111100 ; 063A 1-c7: **** + .byte %01100000 ; 063B 1-c7: ** + .byte %01100000 ; 063C 1-c7: ** + .byte %01100000 ; 063D 1-c7: ** + .byte %00111100 ; 063E 1-c7: **** + .byte %00000000 ; 063F 1-c7: - .byte %00000000 ; 0640 1-c8: - .byte %00000110 ; 0641 1-c8: ** - .byte %00000110 ; 0642 1-c8: ** - .byte %00111110 ; 0643 1-c8: ***** - .byte %01100110 ; 0644 1-c8: ** ** - .byte %01100110 ; 0645 1-c8: ** ** - .byte %00111110 ; 0646 1-c8: ***** - .byte %00000000 ; 0647 1-c8: + .byte %00000000 ; 0640 1-c8: + .byte %00000110 ; 0641 1-c8: ** + .byte %00000110 ; 0642 1-c8: ** + .byte %00111110 ; 0643 1-c8: ***** + .byte %01100110 ; 0644 1-c8: ** ** + .byte %01100110 ; 0645 1-c8: ** ** + .byte %00111110 ; 0646 1-c8: ***** + .byte %00000000 ; 0647 1-c8: - .byte %00000000 ; 0648 1-c9: - .byte %00000110 ; 0649 1-c9: ** - .byte %00000110 ; 064A 1-c9: ** - .byte %00111110 ; 064B 1-c9: ***** - .byte %01100110 ; 064C 1-c9: ** ** - .byte %01100110 ; 064D 1-c9: ** ** - .byte %00111110 ; 064E 1-c9: ***** - .byte %00000000 ; 064F 1-c9: + .byte %00000000 ; 0648 1-c9: + .byte %00000110 ; 0649 1-c9: ** + .byte %00000110 ; 064A 1-c9: ** + .byte %00111110 ; 064B 1-c9: ***** + .byte %01100110 ; 064C 1-c9: ** ** + .byte %01100110 ; 064D 1-c9: ** ** + .byte %00111110 ; 064E 1-c9: ***** + .byte %00000000 ; 064F 1-c9: - .byte %00000000 ; 0650 1-ca: - .byte %00000000 ; 0651 1-ca: - .byte %00111100 ; 0652 1-ca: **** - .byte %01100110 ; 0653 1-ca: ** ** - .byte %01111110 ; 0654 1-ca: ****** - .byte %01100000 ; 0655 1-ca: ** - .byte %00111100 ; 0656 1-ca: **** - .byte %00000000 ; 0657 1-ca: + .byte %00000000 ; 0650 1-ca: + .byte %00000000 ; 0651 1-ca: + .byte %00111100 ; 0652 1-ca: **** + .byte %01100110 ; 0653 1-ca: ** ** + .byte %01111110 ; 0654 1-ca: ****** + .byte %01100000 ; 0655 1-ca: ** + .byte %00111100 ; 0656 1-ca: **** + .byte %00000000 ; 0657 1-ca: - .byte %00000000 ; 0658 1-cb: - .byte %00000000 ; 0659 1-cb: - .byte %00111100 ; 065A 1-cb: **** - .byte %01100110 ; 065B 1-cb: ** ** - .byte %01111110 ; 065C 1-cb: ****** - .byte %01100000 ; 065D 1-cb: ** - .byte %00111100 ; 065E 1-cb: **** - .byte %00000000 ; 065F 1-cb: + .byte %00000000 ; 0658 1-cb: + .byte %00000000 ; 0659 1-cb: + .byte %00111100 ; 065A 1-cb: **** + .byte %01100110 ; 065B 1-cb: ** ** + .byte %01111110 ; 065C 1-cb: ****** + .byte %01100000 ; 065D 1-cb: ** + .byte %00111100 ; 065E 1-cb: **** + .byte %00000000 ; 065F 1-cb: - .byte %00000000 ; 0660 1-cc: - .byte %00001110 ; 0661 1-cc: *** - .byte %00011000 ; 0662 1-cc: ** - .byte %00111110 ; 0663 1-cc: ***** - .byte %00011000 ; 0664 1-cc: ** - .byte %00011000 ; 0665 1-cc: ** - .byte %00011000 ; 0666 1-cc: ** - .byte %00000000 ; 0667 1-cc: + .byte %00000000 ; 0660 1-cc: + .byte %00001110 ; 0661 1-cc: *** + .byte %00011000 ; 0662 1-cc: ** + .byte %00111110 ; 0663 1-cc: ***** + .byte %00011000 ; 0664 1-cc: ** + .byte %00011000 ; 0665 1-cc: ** + .byte %00011000 ; 0666 1-cc: ** + .byte %00000000 ; 0667 1-cc: - .byte %00000000 ; 0668 1-cd: - .byte %00001110 ; 0669 1-cd: *** - .byte %00011000 ; 066A 1-cd: ** - .byte %00111110 ; 066B 1-cd: ***** - .byte %00011000 ; 066C 1-cd: ** - .byte %00011000 ; 066D 1-cd: ** - .byte %00011000 ; 066E 1-cd: ** - .byte %00000000 ; 066F 1-cd: + .byte %00000000 ; 0668 1-cd: + .byte %00001110 ; 0669 1-cd: *** + .byte %00011000 ; 066A 1-cd: ** + .byte %00111110 ; 066B 1-cd: ***** + .byte %00011000 ; 066C 1-cd: ** + .byte %00011000 ; 066D 1-cd: ** + .byte %00011000 ; 066E 1-cd: ** + .byte %00000000 ; 066F 1-cd: - .byte %00000000 ; 0670 1-ce: - .byte %00000000 ; 0671 1-ce: - .byte %00111110 ; 0672 1-ce: ***** - .byte %01100110 ; 0673 1-ce: ** ** - .byte %01100110 ; 0674 1-ce: ** ** - .byte %00111110 ; 0675 1-ce: ***** - .byte %00000110 ; 0676 1-ce: ** - .byte %01111100 ; 0677 1-ce: ***** + .byte %00000000 ; 0670 1-ce: + .byte %00000000 ; 0671 1-ce: + .byte %00111110 ; 0672 1-ce: ***** + .byte %01100110 ; 0673 1-ce: ** ** + .byte %01100110 ; 0674 1-ce: ** ** + .byte %00111110 ; 0675 1-ce: ***** + .byte %00000110 ; 0676 1-ce: ** + .byte %01111100 ; 0677 1-ce: ***** - .byte %00000000 ; 0678 1-cf: - .byte %00000000 ; 0679 1-cf: - .byte %00111110 ; 067A 1-cf: ***** - .byte %01100110 ; 067B 1-cf: ** ** - .byte %01100110 ; 067C 1-cf: ** ** - .byte %00111110 ; 067D 1-cf: ***** - .byte %00000110 ; 067E 1-cf: ** - .byte %01111100 ; 067F 1-cf: ***** + .byte %00000000 ; 0678 1-cf: + .byte %00000000 ; 0679 1-cf: + .byte %00111110 ; 067A 1-cf: ***** + .byte %01100110 ; 067B 1-cf: ** ** + .byte %01100110 ; 067C 1-cf: ** ** + .byte %00111110 ; 067D 1-cf: ***** + .byte %00000110 ; 067E 1-cf: ** + .byte %01111100 ; 067F 1-cf: ***** - .byte %00000000 ; 0680 1-d0: - .byte %01100000 ; 0681 1-d0: ** - .byte %01100000 ; 0682 1-d0: ** - .byte %01111100 ; 0683 1-d0: ***** - .byte %01100110 ; 0684 1-d0: ** ** - .byte %01100110 ; 0685 1-d0: ** ** - .byte %01100110 ; 0686 1-d0: ** ** - .byte %00000000 ; 0687 1-d0: + .byte %00000000 ; 0680 1-d0: + .byte %01100000 ; 0681 1-d0: ** + .byte %01100000 ; 0682 1-d0: ** + .byte %01111100 ; 0683 1-d0: ***** + .byte %01100110 ; 0684 1-d0: ** ** + .byte %01100110 ; 0685 1-d0: ** ** + .byte %01100110 ; 0686 1-d0: ** ** + .byte %00000000 ; 0687 1-d0: - .byte %00000000 ; 0688 1-d1: - .byte %01100000 ; 0689 1-d1: ** - .byte %01100000 ; 068A 1-d1: ** - .byte %01111100 ; 068B 1-d1: ***** - .byte %01100110 ; 068C 1-d1: ** ** - .byte %01100110 ; 068D 1-d1: ** ** - .byte %01100110 ; 068E 1-d1: ** ** - .byte %00000000 ; 068F 1-d1: + .byte %00000000 ; 0688 1-d1: + .byte %01100000 ; 0689 1-d1: ** + .byte %01100000 ; 068A 1-d1: ** + .byte %01111100 ; 068B 1-d1: ***** + .byte %01100110 ; 068C 1-d1: ** ** + .byte %01100110 ; 068D 1-d1: ** ** + .byte %01100110 ; 068E 1-d1: ** ** + .byte %00000000 ; 068F 1-d1: - .byte %00000000 ; 0690 1-d2: - .byte %00011000 ; 0691 1-d2: ** - .byte %00000000 ; 0692 1-d2: - .byte %00111000 ; 0693 1-d2: *** - .byte %00011000 ; 0694 1-d2: ** - .byte %00011000 ; 0695 1-d2: ** - .byte %00111100 ; 0696 1-d2: **** - .byte %00000000 ; 0697 1-d2: + .byte %00000000 ; 0690 1-d2: + .byte %00011000 ; 0691 1-d2: ** + .byte %00000000 ; 0692 1-d2: + .byte %00111000 ; 0693 1-d2: *** + .byte %00011000 ; 0694 1-d2: ** + .byte %00011000 ; 0695 1-d2: ** + .byte %00111100 ; 0696 1-d2: **** + .byte %00000000 ; 0697 1-d2: - .byte %00000000 ; 0698 1-d3: - .byte %00011000 ; 0699 1-d3: ** - .byte %00000000 ; 069A 1-d3: - .byte %00111000 ; 069B 1-d3: *** - .byte %00011000 ; 069C 1-d3: ** - .byte %00011000 ; 069D 1-d3: ** - .byte %00111100 ; 069E 1-d3: **** - .byte %00000000 ; 069F 1-d3: + .byte %00000000 ; 0698 1-d3: + .byte %00011000 ; 0699 1-d3: ** + .byte %00000000 ; 069A 1-d3: + .byte %00111000 ; 069B 1-d3: *** + .byte %00011000 ; 069C 1-d3: ** + .byte %00011000 ; 069D 1-d3: ** + .byte %00111100 ; 069E 1-d3: **** + .byte %00000000 ; 069F 1-d3: - .byte %00000000 ; 06A0 1-d4: - .byte %00000110 ; 06A1 1-d4: ** - .byte %00000000 ; 06A2 1-d4: - .byte %00000110 ; 06A3 1-d4: ** - .byte %00000110 ; 06A4 1-d4: ** - .byte %00000110 ; 06A5 1-d4: ** - .byte %00000110 ; 06A6 1-d4: ** - .byte %00111100 ; 06A7 1-d4: **** + .byte %00000000 ; 06A0 1-d4: + .byte %00000110 ; 06A1 1-d4: ** + .byte %00000000 ; 06A2 1-d4: + .byte %00000110 ; 06A3 1-d4: ** + .byte %00000110 ; 06A4 1-d4: ** + .byte %00000110 ; 06A5 1-d4: ** + .byte %00000110 ; 06A6 1-d4: ** + .byte %00111100 ; 06A7 1-d4: **** - .byte %00000000 ; 06A8 1-d5: - .byte %00000110 ; 06A9 1-d5: ** - .byte %00000000 ; 06AA 1-d5: - .byte %00000110 ; 06AB 1-d5: ** - .byte %00000110 ; 06AC 1-d5: ** - .byte %00000110 ; 06AD 1-d5: ** - .byte %00000110 ; 06AE 1-d5: ** - .byte %00111100 ; 06AF 1-d5: **** + .byte %00000000 ; 06A8 1-d5: + .byte %00000110 ; 06A9 1-d5: ** + .byte %00000000 ; 06AA 1-d5: + .byte %00000110 ; 06AB 1-d5: ** + .byte %00000110 ; 06AC 1-d5: ** + .byte %00000110 ; 06AD 1-d5: ** + .byte %00000110 ; 06AE 1-d5: ** + .byte %00111100 ; 06AF 1-d5: **** - .byte %00000000 ; 06B0 1-d6: - .byte %01100000 ; 06B1 1-d6: ** - .byte %01100000 ; 06B2 1-d6: ** - .byte %01101100 ; 06B3 1-d6: ** ** - .byte %01111000 ; 06B4 1-d6: **** - .byte %01101100 ; 06B5 1-d6: ** ** - .byte %01100110 ; 06B6 1-d6: ** ** - .byte %00000000 ; 06B7 1-d6: + .byte %00000000 ; 06B0 1-d6: + .byte %01100000 ; 06B1 1-d6: ** + .byte %01100000 ; 06B2 1-d6: ** + .byte %01101100 ; 06B3 1-d6: ** ** + .byte %01111000 ; 06B4 1-d6: **** + .byte %01101100 ; 06B5 1-d6: ** ** + .byte %01100110 ; 06B6 1-d6: ** ** + .byte %00000000 ; 06B7 1-d6: - .byte %00000000 ; 06B8 1-d7: - .byte %01100000 ; 06B9 1-d7: ** - .byte %01100000 ; 06BA 1-d7: ** - .byte %01101100 ; 06BB 1-d7: ** ** - .byte %01111000 ; 06BC 1-d7: **** - .byte %01101100 ; 06BD 1-d7: ** ** - .byte %01100110 ; 06BE 1-d7: ** ** - .byte %00000000 ; 06BF 1-d7: + .byte %00000000 ; 06B8 1-d7: + .byte %01100000 ; 06B9 1-d7: ** + .byte %01100000 ; 06BA 1-d7: ** + .byte %01101100 ; 06BB 1-d7: ** ** + .byte %01111000 ; 06BC 1-d7: **** + .byte %01101100 ; 06BD 1-d7: ** ** + .byte %01100110 ; 06BE 1-d7: ** ** + .byte %00000000 ; 06BF 1-d7: - .byte %00000000 ; 06C0 1-d8: - .byte %00111000 ; 06C1 1-d8: *** - .byte %00011000 ; 06C2 1-d8: ** - .byte %00011000 ; 06C3 1-d8: ** - .byte %00011000 ; 06C4 1-d8: ** - .byte %00011000 ; 06C5 1-d8: ** - .byte %00111100 ; 06C6 1-d8: **** - .byte %00000000 ; 06C7 1-d8: + .byte %00000000 ; 06C0 1-d8: + .byte %00111000 ; 06C1 1-d8: *** + .byte %00011000 ; 06C2 1-d8: ** + .byte %00011000 ; 06C3 1-d8: ** + .byte %00011000 ; 06C4 1-d8: ** + .byte %00011000 ; 06C5 1-d8: ** + .byte %00111100 ; 06C6 1-d8: **** + .byte %00000000 ; 06C7 1-d8: - .byte %00000000 ; 06C8 1-d9: - .byte %00111000 ; 06C9 1-d9: *** - .byte %00011000 ; 06CA 1-d9: ** - .byte %00011000 ; 06CB 1-d9: ** - .byte %00011000 ; 06CC 1-d9: ** - .byte %00011000 ; 06CD 1-d9: ** - .byte %00111100 ; 06CE 1-d9: **** - .byte %00000000 ; 06CF 1-d9: + .byte %00000000 ; 06C8 1-d9: + .byte %00111000 ; 06C9 1-d9: *** + .byte %00011000 ; 06CA 1-d9: ** + .byte %00011000 ; 06CB 1-d9: ** + .byte %00011000 ; 06CC 1-d9: ** + .byte %00011000 ; 06CD 1-d9: ** + .byte %00111100 ; 06CE 1-d9: **** + .byte %00000000 ; 06CF 1-d9: - .byte %00000000 ; 06D0 1-da: - .byte %00000000 ; 06D1 1-da: - .byte %01100110 ; 06D2 1-da: ** ** + .byte %00000000 ; 06D0 1-da: + .byte %00000000 ; 06D1 1-da: + .byte %01100110 ; 06D2 1-da: ** ** .byte %01111111 ; 06D3 1-da: ******* .byte %01111111 ; 06D4 1-da: ******* .byte %01101011 ; 06D5 1-da: ** * ** .byte %01100011 ; 06D6 1-da: ** ** - .byte %00000000 ; 06D7 1-da: + .byte %00000000 ; 06D7 1-da: - .byte %00000000 ; 06D8 1-db: - .byte %00000000 ; 06D9 1-db: - .byte %01100110 ; 06DA 1-db: ** ** + .byte %00000000 ; 06D8 1-db: + .byte %00000000 ; 06D9 1-db: + .byte %01100110 ; 06DA 1-db: ** ** .byte %01111111 ; 06DB 1-db: ******* .byte %01111111 ; 06DC 1-db: ******* .byte %01101011 ; 06DD 1-db: ** * ** .byte %01100011 ; 06DE 1-db: ** ** - .byte %00000000 ; 06DF 1-db: + .byte %00000000 ; 06DF 1-db: - .byte %00000000 ; 06E0 1-dc: - .byte %00000000 ; 06E1 1-dc: - .byte %01111100 ; 06E2 1-dc: ***** - .byte %01100110 ; 06E3 1-dc: ** ** - .byte %01100110 ; 06E4 1-dc: ** ** - .byte %01100110 ; 06E5 1-dc: ** ** - .byte %01100110 ; 06E6 1-dc: ** ** - .byte %00000000 ; 06E7 1-dc: + .byte %00000000 ; 06E0 1-dc: + .byte %00000000 ; 06E1 1-dc: + .byte %01111100 ; 06E2 1-dc: ***** + .byte %01100110 ; 06E3 1-dc: ** ** + .byte %01100110 ; 06E4 1-dc: ** ** + .byte %01100110 ; 06E5 1-dc: ** ** + .byte %01100110 ; 06E6 1-dc: ** ** + .byte %00000000 ; 06E7 1-dc: - .byte %00000000 ; 06E8 1-dd: - .byte %00000000 ; 06E9 1-dd: - .byte %01111100 ; 06EA 1-dd: ***** - .byte %01100110 ; 06EB 1-dd: ** ** - .byte %01100110 ; 06EC 1-dd: ** ** - .byte %01100110 ; 06ED 1-dd: ** ** - .byte %01100110 ; 06EE 1-dd: ** ** - .byte %00000000 ; 06EF 1-dd: + .byte %00000000 ; 06E8 1-dd: + .byte %00000000 ; 06E9 1-dd: + .byte %01111100 ; 06EA 1-dd: ***** + .byte %01100110 ; 06EB 1-dd: ** ** + .byte %01100110 ; 06EC 1-dd: ** ** + .byte %01100110 ; 06ED 1-dd: ** ** + .byte %01100110 ; 06EE 1-dd: ** ** + .byte %00000000 ; 06EF 1-dd: - .byte %00000000 ; 06F0 1-de: - .byte %00000000 ; 06F1 1-de: - .byte %00111100 ; 06F2 1-de: **** - .byte %01100110 ; 06F3 1-de: ** ** - .byte %01100110 ; 06F4 1-de: ** ** - .byte %01100110 ; 06F5 1-de: ** ** - .byte %00111100 ; 06F6 1-de: **** - .byte %00000000 ; 06F7 1-de: + .byte %00000000 ; 06F0 1-de: + .byte %00000000 ; 06F1 1-de: + .byte %00111100 ; 06F2 1-de: **** + .byte %01100110 ; 06F3 1-de: ** ** + .byte %01100110 ; 06F4 1-de: ** ** + .byte %01100110 ; 06F5 1-de: ** ** + .byte %00111100 ; 06F6 1-de: **** + .byte %00000000 ; 06F7 1-de: - .byte %00000000 ; 06F8 1-df: - .byte %00000000 ; 06F9 1-df: - .byte %00111100 ; 06FA 1-df: **** - .byte %01100110 ; 06FB 1-df: ** ** - .byte %01100110 ; 06FC 1-df: ** ** - .byte %01100110 ; 06FD 1-df: ** ** - .byte %00111100 ; 06FE 1-df: **** - .byte %00000000 ; 06FF 1-df: + .byte %00000000 ; 06F8 1-df: + .byte %00000000 ; 06F9 1-df: + .byte %00111100 ; 06FA 1-df: **** + .byte %01100110 ; 06FB 1-df: ** ** + .byte %01100110 ; 06FC 1-df: ** ** + .byte %01100110 ; 06FD 1-df: ** ** + .byte %00111100 ; 06FE 1-df: **** + .byte %00000000 ; 06FF 1-df: - .byte %00000000 ; 0700 1-e0: - .byte %00000000 ; 0701 1-e0: - .byte %01111100 ; 0702 1-e0: ***** - .byte %01100110 ; 0703 1-e0: ** ** - .byte %01100110 ; 0704 1-e0: ** ** - .byte %01111100 ; 0705 1-e0: ***** - .byte %01100000 ; 0706 1-e0: ** - .byte %01100000 ; 0707 1-e0: ** + .byte %00000000 ; 0700 1-e0: + .byte %00000000 ; 0701 1-e0: + .byte %01111100 ; 0702 1-e0: ***** + .byte %01100110 ; 0703 1-e0: ** ** + .byte %01100110 ; 0704 1-e0: ** ** + .byte %01111100 ; 0705 1-e0: ***** + .byte %01100000 ; 0706 1-e0: ** + .byte %01100000 ; 0707 1-e0: ** - .byte %00000000 ; 0708 1-e1: - .byte %00000000 ; 0709 1-e1: - .byte %01111100 ; 070A 1-e1: ***** - .byte %01100110 ; 070B 1-e1: ** ** - .byte %01100110 ; 070C 1-e1: ** ** - .byte %01111100 ; 070D 1-e1: ***** - .byte %01100000 ; 070E 1-e1: ** - .byte %01100000 ; 070F 1-e1: ** + .byte %00000000 ; 0708 1-e1: + .byte %00000000 ; 0709 1-e1: + .byte %01111100 ; 070A 1-e1: ***** + .byte %01100110 ; 070B 1-e1: ** ** + .byte %01100110 ; 070C 1-e1: ** ** + .byte %01111100 ; 070D 1-e1: ***** + .byte %01100000 ; 070E 1-e1: ** + .byte %01100000 ; 070F 1-e1: ** - .byte %00000000 ; 0710 1-e2: - .byte %00000000 ; 0711 1-e2: - .byte %00111110 ; 0712 1-e2: ***** - .byte %01100110 ; 0713 1-e2: ** ** - .byte %01100110 ; 0714 1-e2: ** ** - .byte %00111110 ; 0715 1-e2: ***** - .byte %00000110 ; 0716 1-e2: ** - .byte %00000110 ; 0717 1-e2: ** + .byte %00000000 ; 0710 1-e2: + .byte %00000000 ; 0711 1-e2: + .byte %00111110 ; 0712 1-e2: ***** + .byte %01100110 ; 0713 1-e2: ** ** + .byte %01100110 ; 0714 1-e2: ** ** + .byte %00111110 ; 0715 1-e2: ***** + .byte %00000110 ; 0716 1-e2: ** + .byte %00000110 ; 0717 1-e2: ** - .byte %00000000 ; 0718 1-e3: - .byte %00000000 ; 0719 1-e3: - .byte %00111110 ; 071A 1-e3: ***** - .byte %01100110 ; 071B 1-e3: ** ** - .byte %01100110 ; 071C 1-e3: ** ** - .byte %00111110 ; 071D 1-e3: ***** - .byte %00000110 ; 071E 1-e3: ** - .byte %00000110 ; 071F 1-e3: ** + .byte %00000000 ; 0718 1-e3: + .byte %00000000 ; 0719 1-e3: + .byte %00111110 ; 071A 1-e3: ***** + .byte %01100110 ; 071B 1-e3: ** ** + .byte %01100110 ; 071C 1-e3: ** ** + .byte %00111110 ; 071D 1-e3: ***** + .byte %00000110 ; 071E 1-e3: ** + .byte %00000110 ; 071F 1-e3: ** - .byte %00000000 ; 0720 1-e4: - .byte %00000000 ; 0721 1-e4: - .byte %01111100 ; 0722 1-e4: ***** - .byte %01100110 ; 0723 1-e4: ** ** - .byte %01100000 ; 0724 1-e4: ** - .byte %01100000 ; 0725 1-e4: ** - .byte %01100000 ; 0726 1-e4: ** - .byte %00000000 ; 0727 1-e4: + .byte %00000000 ; 0720 1-e4: + .byte %00000000 ; 0721 1-e4: + .byte %01111100 ; 0722 1-e4: ***** + .byte %01100110 ; 0723 1-e4: ** ** + .byte %01100000 ; 0724 1-e4: ** + .byte %01100000 ; 0725 1-e4: ** + .byte %01100000 ; 0726 1-e4: ** + .byte %00000000 ; 0727 1-e4: - .byte %00000000 ; 0728 1-e5: - .byte %00000000 ; 0729 1-e5: - .byte %01111100 ; 072A 1-e5: ***** - .byte %01100110 ; 072B 1-e5: ** ** - .byte %01100000 ; 072C 1-e5: ** - .byte %01100000 ; 072D 1-e5: ** - .byte %01100000 ; 072E 1-e5: ** - .byte %00000000 ; 072F 1-e5: + .byte %00000000 ; 0728 1-e5: + .byte %00000000 ; 0729 1-e5: + .byte %01111100 ; 072A 1-e5: ***** + .byte %01100110 ; 072B 1-e5: ** ** + .byte %01100000 ; 072C 1-e5: ** + .byte %01100000 ; 072D 1-e5: ** + .byte %01100000 ; 072E 1-e5: ** + .byte %00000000 ; 072F 1-e5: - .byte %00000000 ; 0730 1-e6: - .byte %00000000 ; 0731 1-e6: - .byte %00111110 ; 0732 1-e6: ***** - .byte %01100000 ; 0733 1-e6: ** - .byte %00111100 ; 0734 1-e6: **** - .byte %00000110 ; 0735 1-e6: ** - .byte %01111100 ; 0736 1-e6: ***** - .byte %00000000 ; 0737 1-e6: + .byte %00000000 ; 0730 1-e6: + .byte %00000000 ; 0731 1-e6: + .byte %00111110 ; 0732 1-e6: ***** + .byte %01100000 ; 0733 1-e6: ** + .byte %00111100 ; 0734 1-e6: **** + .byte %00000110 ; 0735 1-e6: ** + .byte %01111100 ; 0736 1-e6: ***** + .byte %00000000 ; 0737 1-e6: - .byte %00000000 ; 0738 1-e7: - .byte %00000000 ; 0739 1-e7: - .byte %00111110 ; 073A 1-e7: ***** - .byte %01100000 ; 073B 1-e7: ** - .byte %00111100 ; 073C 1-e7: **** - .byte %00000110 ; 073D 1-e7: ** - .byte %01111100 ; 073E 1-e7: ***** - .byte %00000000 ; 073F 1-e7: + .byte %00000000 ; 0738 1-e7: + .byte %00000000 ; 0739 1-e7: + .byte %00111110 ; 073A 1-e7: ***** + .byte %01100000 ; 073B 1-e7: ** + .byte %00111100 ; 073C 1-e7: **** + .byte %00000110 ; 073D 1-e7: ** + .byte %01111100 ; 073E 1-e7: ***** + .byte %00000000 ; 073F 1-e7: - .byte %00000000 ; 0740 1-e8: - .byte %00011000 ; 0741 1-e8: ** - .byte %01111110 ; 0742 1-e8: ****** - .byte %00011000 ; 0743 1-e8: ** - .byte %00011000 ; 0744 1-e8: ** - .byte %00011000 ; 0745 1-e8: ** - .byte %00001110 ; 0746 1-e8: *** - .byte %00000000 ; 0747 1-e8: + .byte %00000000 ; 0740 1-e8: + .byte %00011000 ; 0741 1-e8: ** + .byte %01111110 ; 0742 1-e8: ****** + .byte %00011000 ; 0743 1-e8: ** + .byte %00011000 ; 0744 1-e8: ** + .byte %00011000 ; 0745 1-e8: ** + .byte %00001110 ; 0746 1-e8: *** + .byte %00000000 ; 0747 1-e8: - .byte %00000000 ; 0748 1-e9: - .byte %00011000 ; 0749 1-e9: ** - .byte %01111110 ; 074A 1-e9: ****** - .byte %00011000 ; 074B 1-e9: ** - .byte %00011000 ; 074C 1-e9: ** - .byte %00011000 ; 074D 1-e9: ** - .byte %00001110 ; 074E 1-e9: *** - .byte %00000000 ; 074F 1-e9: + .byte %00000000 ; 0748 1-e9: + .byte %00011000 ; 0749 1-e9: ** + .byte %01111110 ; 074A 1-e9: ****** + .byte %00011000 ; 074B 1-e9: ** + .byte %00011000 ; 074C 1-e9: ** + .byte %00011000 ; 074D 1-e9: ** + .byte %00001110 ; 074E 1-e9: *** + .byte %00000000 ; 074F 1-e9: - .byte %00000000 ; 0750 1-ea: - .byte %00000000 ; 0751 1-ea: - .byte %01100110 ; 0752 1-ea: ** ** - .byte %01100110 ; 0753 1-ea: ** ** - .byte %01100110 ; 0754 1-ea: ** ** - .byte %01100110 ; 0755 1-ea: ** ** - .byte %00111110 ; 0756 1-ea: ***** - .byte %00000000 ; 0757 1-ea: + .byte %00000000 ; 0750 1-ea: + .byte %00000000 ; 0751 1-ea: + .byte %01100110 ; 0752 1-ea: ** ** + .byte %01100110 ; 0753 1-ea: ** ** + .byte %01100110 ; 0754 1-ea: ** ** + .byte %01100110 ; 0755 1-ea: ** ** + .byte %00111110 ; 0756 1-ea: ***** + .byte %00000000 ; 0757 1-ea: - .byte %00000000 ; 0758 1-eb: - .byte %00000000 ; 0759 1-eb: - .byte %01100110 ; 075A 1-eb: ** ** - .byte %01100110 ; 075B 1-eb: ** ** - .byte %01100110 ; 075C 1-eb: ** ** - .byte %01100110 ; 075D 1-eb: ** ** - .byte %00111110 ; 075E 1-eb: ***** - .byte %00000000 ; 075F 1-eb: + .byte %00000000 ; 0758 1-eb: + .byte %00000000 ; 0759 1-eb: + .byte %01100110 ; 075A 1-eb: ** ** + .byte %01100110 ; 075B 1-eb: ** ** + .byte %01100110 ; 075C 1-eb: ** ** + .byte %01100110 ; 075D 1-eb: ** ** + .byte %00111110 ; 075E 1-eb: ***** + .byte %00000000 ; 075F 1-eb: - .byte %00000000 ; 0760 1-ec: - .byte %00000000 ; 0761 1-ec: - .byte %01100110 ; 0762 1-ec: ** ** - .byte %01100110 ; 0763 1-ec: ** ** - .byte %01100110 ; 0764 1-ec: ** ** - .byte %00111100 ; 0765 1-ec: **** - .byte %00011000 ; 0766 1-ec: ** - .byte %00000000 ; 0767 1-ec: + .byte %00000000 ; 0760 1-ec: + .byte %00000000 ; 0761 1-ec: + .byte %01100110 ; 0762 1-ec: ** ** + .byte %01100110 ; 0763 1-ec: ** ** + .byte %01100110 ; 0764 1-ec: ** ** + .byte %00111100 ; 0765 1-ec: **** + .byte %00011000 ; 0766 1-ec: ** + .byte %00000000 ; 0767 1-ec: - .byte %00000000 ; 0768 1-ed: - .byte %00000000 ; 0769 1-ed: - .byte %01100110 ; 076A 1-ed: ** ** - .byte %01100110 ; 076B 1-ed: ** ** - .byte %01100110 ; 076C 1-ed: ** ** - .byte %00111100 ; 076D 1-ed: **** - .byte %00011000 ; 076E 1-ed: ** - .byte %00000000 ; 076F 1-ed: + .byte %00000000 ; 0768 1-ed: + .byte %00000000 ; 0769 1-ed: + .byte %01100110 ; 076A 1-ed: ** ** + .byte %01100110 ; 076B 1-ed: ** ** + .byte %01100110 ; 076C 1-ed: ** ** + .byte %00111100 ; 076D 1-ed: **** + .byte %00011000 ; 076E 1-ed: ** + .byte %00000000 ; 076F 1-ed: - .byte %00000000 ; 0770 1-ee: - .byte %00000000 ; 0771 1-ee: + .byte %00000000 ; 0770 1-ee: + .byte %00000000 ; 0771 1-ee: .byte %01100011 ; 0772 1-ee: ** ** .byte %01101011 ; 0773 1-ee: ** * ** .byte %01111111 ; 0774 1-ee: ******* - .byte %00111110 ; 0775 1-ee: ***** - .byte %00110110 ; 0776 1-ee: ** ** - .byte %00000000 ; 0777 1-ee: + .byte %00111110 ; 0775 1-ee: ***** + .byte %00110110 ; 0776 1-ee: ** ** + .byte %00000000 ; 0777 1-ee: - .byte %00000000 ; 0778 1-ef: - .byte %00000000 ; 0779 1-ef: + .byte %00000000 ; 0778 1-ef: + .byte %00000000 ; 0779 1-ef: .byte %01100011 ; 077A 1-ef: ** ** .byte %01101011 ; 077B 1-ef: ** * ** .byte %01111111 ; 077C 1-ef: ******* - .byte %00111110 ; 077D 1-ef: ***** - .byte %00110110 ; 077E 1-ef: ** ** - .byte %00000000 ; 077F 1-ef: + .byte %00111110 ; 077D 1-ef: ***** + .byte %00110110 ; 077E 1-ef: ** ** + .byte %00000000 ; 077F 1-ef: - .byte %00000000 ; 0780 1-f0: - .byte %00000000 ; 0781 1-f0: - .byte %01100110 ; 0782 1-f0: ** ** - .byte %00111100 ; 0783 1-f0: **** - .byte %00011000 ; 0784 1-f0: ** - .byte %00111100 ; 0785 1-f0: **** - .byte %01100110 ; 0786 1-f0: ** ** - .byte %00000000 ; 0787 1-f0: + .byte %00000000 ; 0780 1-f0: + .byte %00000000 ; 0781 1-f0: + .byte %01100110 ; 0782 1-f0: ** ** + .byte %00111100 ; 0783 1-f0: **** + .byte %00011000 ; 0784 1-f0: ** + .byte %00111100 ; 0785 1-f0: **** + .byte %01100110 ; 0786 1-f0: ** ** + .byte %00000000 ; 0787 1-f0: - .byte %00000000 ; 0788 1-f1: - .byte %00000000 ; 0789 1-f1: - .byte %01100110 ; 078A 1-f1: ** ** - .byte %00111100 ; 078B 1-f1: **** - .byte %00011000 ; 078C 1-f1: ** - .byte %00111100 ; 078D 1-f1: **** - .byte %01100110 ; 078E 1-f1: ** ** - .byte %00000000 ; 078F 1-f1: + .byte %00000000 ; 0788 1-f1: + .byte %00000000 ; 0789 1-f1: + .byte %01100110 ; 078A 1-f1: ** ** + .byte %00111100 ; 078B 1-f1: **** + .byte %00011000 ; 078C 1-f1: ** + .byte %00111100 ; 078D 1-f1: **** + .byte %01100110 ; 078E 1-f1: ** ** + .byte %00000000 ; 078F 1-f1: - .byte %00000000 ; 0790 1-f2: - .byte %00000000 ; 0791 1-f2: - .byte %01100110 ; 0792 1-f2: ** ** - .byte %01100110 ; 0793 1-f2: ** ** - .byte %01100110 ; 0794 1-f2: ** ** - .byte %00111110 ; 0795 1-f2: ***** - .byte %00001100 ; 0796 1-f2: ** - .byte %01111000 ; 0797 1-f2: **** + .byte %00000000 ; 0790 1-f2: + .byte %00000000 ; 0791 1-f2: + .byte %01100110 ; 0792 1-f2: ** ** + .byte %01100110 ; 0793 1-f2: ** ** + .byte %01100110 ; 0794 1-f2: ** ** + .byte %00111110 ; 0795 1-f2: ***** + .byte %00001100 ; 0796 1-f2: ** + .byte %01111000 ; 0797 1-f2: **** - .byte %00000000 ; 0798 1-f3: - .byte %00000000 ; 0799 1-f3: - .byte %01100110 ; 079A 1-f3: ** ** - .byte %01100110 ; 079B 1-f3: ** ** - .byte %01100110 ; 079C 1-f3: ** ** - .byte %00111110 ; 079D 1-f3: ***** - .byte %00001100 ; 079E 1-f3: ** - .byte %01111000 ; 079F 1-f3: **** + .byte %00000000 ; 0798 1-f3: + .byte %00000000 ; 0799 1-f3: + .byte %01100110 ; 079A 1-f3: ** ** + .byte %01100110 ; 079B 1-f3: ** ** + .byte %01100110 ; 079C 1-f3: ** ** + .byte %00111110 ; 079D 1-f3: ***** + .byte %00001100 ; 079E 1-f3: ** + .byte %01111000 ; 079F 1-f3: **** - .byte %00000000 ; 07A0 1-f4: - .byte %00000000 ; 07A1 1-f4: - .byte %01111110 ; 07A2 1-f4: ****** - .byte %00001100 ; 07A3 1-f4: ** - .byte %00011000 ; 07A4 1-f4: ** - .byte %00110000 ; 07A5 1-f4: ** - .byte %01111110 ; 07A6 1-f4: ****** - .byte %00000000 ; 07A7 1-f4: + .byte %00000000 ; 07A0 1-f4: + .byte %00000000 ; 07A1 1-f4: + .byte %01111110 ; 07A2 1-f4: ****** + .byte %00001100 ; 07A3 1-f4: ** + .byte %00011000 ; 07A4 1-f4: ** + .byte %00110000 ; 07A5 1-f4: ** + .byte %01111110 ; 07A6 1-f4: ****** + .byte %00000000 ; 07A7 1-f4: - .byte %00000000 ; 07A8 1-f5: - .byte %00000000 ; 07A9 1-f5: - .byte %01111110 ; 07AA 1-f5: ****** - .byte %00001100 ; 07AB 1-f5: ** - .byte %00011000 ; 07AC 1-f5: ** - .byte %00110000 ; 07AD 1-f5: ** - .byte %01111110 ; 07AE 1-f5: ****** - .byte %00000000 ; 07AF 1-f5: + .byte %00000000 ; 07A8 1-f5: + .byte %00000000 ; 07A9 1-f5: + .byte %01111110 ; 07AA 1-f5: ****** + .byte %00001100 ; 07AB 1-f5: ** + .byte %00011000 ; 07AC 1-f5: ** + .byte %00110000 ; 07AD 1-f5: ** + .byte %01111110 ; 07AE 1-f5: ****** + .byte %00000000 ; 07AF 1-f5: - .byte %00011100 ; 07B0 1-f6: *** - .byte %00110000 ; 07B1 1-f6: ** - .byte %00011000 ; 07B2 1-f6: ** - .byte %01110000 ; 07B3 1-f6: *** - .byte %00011000 ; 07B4 1-f6: ** - .byte %00110000 ; 07B5 1-f6: ** - .byte %00011100 ; 07B6 1-f6: *** - .byte %00000000 ; 07B7 1-f6: + .byte %00011100 ; 07B0 1-f6: *** + .byte %00110000 ; 07B1 1-f6: ** + .byte %00011000 ; 07B2 1-f6: ** + .byte %01110000 ; 07B3 1-f6: *** + .byte %00011000 ; 07B4 1-f6: ** + .byte %00110000 ; 07B5 1-f6: ** + .byte %00011100 ; 07B6 1-f6: *** + .byte %00000000 ; 07B7 1-f6: - .byte %00011100 ; 07B8 1-f7: *** - .byte %00110000 ; 07B9 1-f7: ** - .byte %00011000 ; 07BA 1-f7: ** - .byte %01110000 ; 07BB 1-f7: *** - .byte %00011000 ; 07BC 1-f7: ** - .byte %00110000 ; 07BD 1-f7: ** - .byte %00011100 ; 07BE 1-f7: *** - .byte %00000000 ; 07BF 1-f7: + .byte %00011100 ; 07B8 1-f7: *** + .byte %00110000 ; 07B9 1-f7: ** + .byte %00011000 ; 07BA 1-f7: ** + .byte %01110000 ; 07BB 1-f7: *** + .byte %00011000 ; 07BC 1-f7: ** + .byte %00110000 ; 07BD 1-f7: ** + .byte %00011100 ; 07BE 1-f7: *** + .byte %00000000 ; 07BF 1-f7: - .byte %00011000 ; 07C0 1-f8: ** - .byte %00011000 ; 07C1 1-f8: ** - .byte %00011000 ; 07C2 1-f8: ** - .byte %00000000 ; 07C3 1-f8: - .byte %00000000 ; 07C4 1-f8: - .byte %00011000 ; 07C5 1-f8: ** - .byte %00011000 ; 07C6 1-f8: ** - .byte %00011000 ; 07C7 1-f8: ** + .byte %00011000 ; 07C0 1-f8: ** + .byte %00011000 ; 07C1 1-f8: ** + .byte %00011000 ; 07C2 1-f8: ** + .byte %00000000 ; 07C3 1-f8: + .byte %00000000 ; 07C4 1-f8: + .byte %00011000 ; 07C5 1-f8: ** + .byte %00011000 ; 07C6 1-f8: ** + .byte %00011000 ; 07C7 1-f8: ** - .byte %00011000 ; 07C8 1-f9: ** - .byte %00011000 ; 07C9 1-f9: ** - .byte %00011000 ; 07CA 1-f9: ** - .byte %00000000 ; 07CB 1-f9: - .byte %00000000 ; 07CC 1-f9: - .byte %00011000 ; 07CD 1-f9: ** - .byte %00011000 ; 07CE 1-f9: ** - .byte %00011000 ; 07CF 1-f9: ** + .byte %00011000 ; 07C8 1-f9: ** + .byte %00011000 ; 07C9 1-f9: ** + .byte %00011000 ; 07CA 1-f9: ** + .byte %00000000 ; 07CB 1-f9: + .byte %00000000 ; 07CC 1-f9: + .byte %00011000 ; 07CD 1-f9: ** + .byte %00011000 ; 07CE 1-f9: ** + .byte %00011000 ; 07CF 1-f9: ** - .byte %00111000 ; 07D0 1-fa: *** - .byte %00001100 ; 07D1 1-fa: ** - .byte %00011000 ; 07D2 1-fa: ** - .byte %00001110 ; 07D3 1-fa: *** - .byte %00011000 ; 07D4 1-fa: ** - .byte %00001100 ; 07D5 1-fa: ** - .byte %00111000 ; 07D6 1-fa: *** - .byte %00000000 ; 07D7 1-fa: + .byte %00111000 ; 07D0 1-fa: *** + .byte %00001100 ; 07D1 1-fa: ** + .byte %00011000 ; 07D2 1-fa: ** + .byte %00001110 ; 07D3 1-fa: *** + .byte %00011000 ; 07D4 1-fa: ** + .byte %00001100 ; 07D5 1-fa: ** + .byte %00111000 ; 07D6 1-fa: *** + .byte %00000000 ; 07D7 1-fa: - .byte %00111000 ; 07D8 1-fb: *** - .byte %00001100 ; 07D9 1-fb: ** - .byte %00011000 ; 07DA 1-fb: ** - .byte %00001110 ; 07DB 1-fb: *** - .byte %00011000 ; 07DC 1-fb: ** - .byte %00001100 ; 07DD 1-fb: ** - .byte %00111000 ; 07DE 1-fb: *** - .byte %00000000 ; 07DF 1-fb: + .byte %00111000 ; 07D8 1-fb: *** + .byte %00001100 ; 07D9 1-fb: ** + .byte %00011000 ; 07DA 1-fb: ** + .byte %00001110 ; 07DB 1-fb: *** + .byte %00011000 ; 07DC 1-fb: ** + .byte %00001100 ; 07DD 1-fb: ** + .byte %00111000 ; 07DE 1-fb: *** + .byte %00000000 ; 07DF 1-fb: .byte %00110011 ; 07E0 1-fc: ** ** .byte %11111111 ; 07E1 1-fc: ******** - .byte %11001100 ; 07E2 1-fc: ** ** - .byte %00000000 ; 07E3 1-fc: - .byte %00000000 ; 07E4 1-fc: - .byte %00000000 ; 07E5 1-fc: - .byte %00000000 ; 07E6 1-fc: - .byte %00000000 ; 07E7 1-fc: + .byte %11001100 ; 07E2 1-fc: ** ** + .byte %00000000 ; 07E3 1-fc: + .byte %00000000 ; 07E4 1-fc: + .byte %00000000 ; 07E5 1-fc: + .byte %00000000 ; 07E6 1-fc: + .byte %00000000 ; 07E7 1-fc: .byte %00110011 ; 07E8 1-fd: ** ** .byte %11111111 ; 07E9 1-fd: ******** - .byte %11001100 ; 07EA 1-fd: ** ** - .byte %00000000 ; 07EB 1-fd: - .byte %00000000 ; 07EC 1-fd: - .byte %00000000 ; 07ED 1-fd: - .byte %00000000 ; 07EE 1-fd: - .byte %00000000 ; 07EF 1-fd: + .byte %11001100 ; 07EA 1-fd: ** ** + .byte %00000000 ; 07EB 1-fd: + .byte %00000000 ; 07EC 1-fd: + .byte %00000000 ; 07ED 1-fd: + .byte %00000000 ; 07EE 1-fd: + .byte %00000000 ; 07EF 1-fd: - .byte %00000000 ; 07F0 1-fe: - .byte %00000000 ; 07F1 1-fe: - .byte %00000000 ; 07F2 1-fe: - .byte %00000000 ; 07F3 1-fe: - .byte %00000000 ; 07F4 1-fe: - .byte %00000000 ; 07F5 1-fe: - .byte %00000000 ; 07F6 1-fe: - .byte %00000000 ; 07F7 1-fe: + .byte %00000000 ; 07F0 1-fe: + .byte %00000000 ; 07F1 1-fe: + .byte %00000000 ; 07F2 1-fe: + .byte %00000000 ; 07F3 1-fe: + .byte %00000000 ; 07F4 1-fe: + .byte %00000000 ; 07F5 1-fe: + .byte %00000000 ; 07F6 1-fe: + .byte %00000000 ; 07F7 1-fe: - .byte %00000000 ; 07F8 1-ff: - .byte %00000000 ; 07F9 1-ff: - .byte %00000000 ; 07FA 1-ff: - .byte %00000000 ; 07FB 1-ff: - .byte %00000000 ; 07FC 1-ff: - .byte %00000000 ; 07FD 1-ff: - .byte %00000000 ; 07FE 1-ff: - .byte %00000000 ; 07FF 1-ff: + .byte %00000000 ; 07F8 1-ff: + .byte %00000000 ; 07F9 1-ff: + .byte %00000000 ; 07FA 1-ff: + .byte %00000000 ; 07FB 1-ff: + .byte %00000000 ; 07FC 1-ff: + .byte %00000000 ; 07FD 1-ff: + .byte %00000000 ; 07FE 1-ff: + .byte %00000000 ; 07FF 1-ff: .byte %11111111 ; 0800 2-00: ******** .byte %11111111 ; 0801 2-00: ******** @@ -2322,21 +2331,21 @@ .byte %00110011 ; 0810 2-02: ** ** .byte %00110011 ; 0811 2-02: ** ** - .byte %11001100 ; 0812 2-02: ** ** - .byte %11001100 ; 0813 2-02: ** ** + .byte %11001100 ; 0812 2-02: ** ** + .byte %11001100 ; 0813 2-02: ** ** .byte %00110011 ; 0814 2-02: ** ** .byte %00110011 ; 0815 2-02: ** ** - .byte %11001100 ; 0816 2-02: ** ** - .byte %11001100 ; 0817 2-02: ** ** + .byte %11001100 ; 0816 2-02: ** ** + .byte %11001100 ; 0817 2-02: ** ** .byte %00110011 ; 0818 2-03: ** ** .byte %00110011 ; 0819 2-03: ** ** - .byte %11001100 ; 081A 2-03: ** ** - .byte %11001100 ; 081B 2-03: ** ** + .byte %11001100 ; 081A 2-03: ** ** + .byte %11001100 ; 081B 2-03: ** ** .byte %00110011 ; 081C 2-03: ** ** .byte %00110011 ; 081D 2-03: ** ** - .byte %11001100 ; 081E 2-03: ** ** - .byte %11001100 ; 081F 2-03: ** ** + .byte %11001100 ; 081E 2-03: ** ** + .byte %11001100 ; 081F 2-03: ** ** .byte %11111111 ; 0820 2-04: ******** .byte %11100111 ; 0821 2-04: *** *** @@ -2359,8 +2368,8 @@ .byte %11111111 ; 0830 2-06: ******** .byte %11101111 ; 0831 2-06: *** **** .byte %11001111 ; 0832 2-06: ** **** - .byte %10000000 ; 0833 2-06: * - .byte %10000000 ; 0834 2-06: * + .byte %10000000 ; 0833 2-06: * + .byte %10000000 ; 0834 2-06: * .byte %11001111 ; 0835 2-06: ** **** .byte %11101111 ; 0836 2-06: *** **** .byte %11111111 ; 0837 2-06: ******** @@ -2368,8 +2377,8 @@ .byte %11111111 ; 0838 2-07: ******** .byte %11101111 ; 0839 2-07: *** **** .byte %11001111 ; 083A 2-07: ** **** - .byte %10000000 ; 083B 2-07: * - .byte %10000000 ; 083C 2-07: * + .byte %10000000 ; 083B 2-07: * + .byte %10000000 ; 083C 2-07: * .byte %11001111 ; 083D 2-07: ** **** .byte %11101111 ; 083E 2-07: *** **** .byte %11111111 ; 083F 2-07: ******** @@ -2394,7 +2403,7 @@ .byte %11111111 ; 0850 2-0a: ******** .byte %11111111 ; 0851 2-0a: ******** - .byte %11111100 ; 0852 2-0a: ****** + .byte %11111100 ; 0852 2-0a: ****** .byte %11000001 ; 0853 2-0a: ** * .byte %10001001 ; 0854 2-0a: * * * .byte %11001001 ; 0855 2-0a: ** * * @@ -2403,15 +2412,15 @@ .byte %11111111 ; 0858 2-0b: ******** .byte %11111111 ; 0859 2-0b: ******** - .byte %11111100 ; 085A 2-0b: ****** + .byte %11111100 ; 085A 2-0b: ****** .byte %11000001 ; 085B 2-0b: ** * .byte %10001001 ; 085C 2-0b: * * * .byte %11001001 ; 085D 2-0b: ** * * .byte %11001001 ; 085E 2-0b: ** * * .byte %11111111 ; 085F 2-0b: ******** - .byte %10000000 ; 0860 2-0c: * - .byte %10000000 ; 0861 2-0c: * + .byte %10000000 ; 0860 2-0c: * + .byte %10000000 ; 0861 2-0c: * .byte %11111111 ; 0862 2-0c: ******** .byte %11111111 ; 0863 2-0c: ******** .byte %11111111 ; 0864 2-0c: ******** @@ -2419,8 +2428,8 @@ .byte %11111111 ; 0866 2-0c: ******** .byte %11111111 ; 0867 2-0c: ******** - .byte %10000000 ; 0868 2-0d: * - .byte %10000000 ; 0869 2-0d: * + .byte %10000000 ; 0868 2-0d: * + .byte %10000000 ; 0869 2-0d: * .byte %11111111 ; 086A 2-0d: ******** .byte %11111111 ; 086B 2-0d: ******** .byte %11111111 ; 086C 2-0d: ******** @@ -2465,46 +2474,46 @@ .byte %11111111 ; 088F 2-11: ******** .byte %00110011 ; 0890 2-12: ** ** - .byte %01100110 ; 0891 2-12: ** ** - .byte %11001100 ; 0892 2-12: ** ** + .byte %01100110 ; 0891 2-12: ** ** + .byte %11001100 ; 0892 2-12: ** ** .byte %10011001 ; 0893 2-12: * ** * .byte %00110011 ; 0894 2-12: ** ** - .byte %01100110 ; 0895 2-12: ** ** - .byte %11001100 ; 0896 2-12: ** ** + .byte %01100110 ; 0895 2-12: ** ** + .byte %11001100 ; 0896 2-12: ** ** .byte %10011001 ; 0897 2-12: * ** * .byte %00110011 ; 0898 2-13: ** ** - .byte %01100110 ; 0899 2-13: ** ** - .byte %11001100 ; 089A 2-13: ** ** + .byte %01100110 ; 0899 2-13: ** ** + .byte %11001100 ; 089A 2-13: ** ** .byte %10011001 ; 089B 2-13: * ** * .byte %00110011 ; 089C 2-13: ** ** - .byte %01100110 ; 089D 2-13: ** ** - .byte %11001100 ; 089E 2-13: ** ** + .byte %01100110 ; 089D 2-13: ** ** + .byte %11001100 ; 089E 2-13: ** ** .byte %10011001 ; 089F 2-13: * ** * - .byte %11001100 ; 08A0 2-14: ** ** - .byte %01100110 ; 08A1 2-14: ** ** + .byte %11001100 ; 08A0 2-14: ** ** + .byte %01100110 ; 08A1 2-14: ** ** .byte %00110011 ; 08A2 2-14: ** ** .byte %10011001 ; 08A3 2-14: * ** * - .byte %11001100 ; 08A4 2-14: ** ** - .byte %01100110 ; 08A5 2-14: ** ** + .byte %11001100 ; 08A4 2-14: ** ** + .byte %01100110 ; 08A5 2-14: ** ** .byte %00110011 ; 08A6 2-14: ** ** .byte %10011001 ; 08A7 2-14: * ** * - .byte %11001100 ; 08A8 2-15: ** ** - .byte %01100110 ; 08A9 2-15: ** ** + .byte %11001100 ; 08A8 2-15: ** ** + .byte %01100110 ; 08A9 2-15: ** ** .byte %00110011 ; 08AA 2-15: ** ** .byte %10011001 ; 08AB 2-15: * ** * - .byte %11001100 ; 08AC 2-15: ** ** - .byte %01100110 ; 08AD 2-15: ** ** + .byte %11001100 ; 08AC 2-15: ** ** + .byte %01100110 ; 08AD 2-15: ** ** .byte %00110011 ; 08AE 2-15: ** ** .byte %10011001 ; 08AF 2-15: * ** * .byte %11111111 ; 08B0 2-16: ******** .byte %11111111 ; 08B1 2-16: ******** .byte %11111111 ; 08B2 2-16: ******** - .byte %00000000 ; 08B3 2-16: - .byte %00000000 ; 08B4 2-16: + .byte %00000000 ; 08B3 2-16: + .byte %00000000 ; 08B4 2-16: .byte %11111111 ; 08B5 2-16: ******** .byte %11111111 ; 08B6 2-16: ******** .byte %11111111 ; 08B7 2-16: ******** @@ -2512,29 +2521,29 @@ .byte %11111111 ; 08B8 2-17: ******** .byte %11111111 ; 08B9 2-17: ******** .byte %11111111 ; 08BA 2-17: ******** - .byte %00000000 ; 08BB 2-17: - .byte %00000000 ; 08BC 2-17: + .byte %00000000 ; 08BB 2-17: + .byte %00000000 ; 08BC 2-17: .byte %11111111 ; 08BD 2-17: ******** .byte %11111111 ; 08BE 2-17: ******** .byte %11111111 ; 08BF 2-17: ******** - .byte %11111100 ; 08C0 2-18: ****** - .byte %11111100 ; 08C1 2-18: ****** - .byte %11111100 ; 08C2 2-18: ****** - .byte %11111100 ; 08C3 2-18: ****** - .byte %11111100 ; 08C4 2-18: ****** - .byte %11111100 ; 08C5 2-18: ****** - .byte %11111100 ; 08C6 2-18: ****** - .byte %11111100 ; 08C7 2-18: ****** + .byte %11111100 ; 08C0 2-18: ****** + .byte %11111100 ; 08C1 2-18: ****** + .byte %11111100 ; 08C2 2-18: ****** + .byte %11111100 ; 08C3 2-18: ****** + .byte %11111100 ; 08C4 2-18: ****** + .byte %11111100 ; 08C5 2-18: ****** + .byte %11111100 ; 08C6 2-18: ****** + .byte %11111100 ; 08C7 2-18: ****** - .byte %11111100 ; 08C8 2-19: ****** - .byte %11111100 ; 08C9 2-19: ****** - .byte %11111100 ; 08CA 2-19: ****** - .byte %11111100 ; 08CB 2-19: ****** - .byte %11111100 ; 08CC 2-19: ****** - .byte %11111100 ; 08CD 2-19: ****** - .byte %11111100 ; 08CE 2-19: ****** - .byte %11111100 ; 08CF 2-19: ****** + .byte %11111100 ; 08C8 2-19: ****** + .byte %11111100 ; 08C9 2-19: ****** + .byte %11111100 ; 08CA 2-19: ****** + .byte %11111100 ; 08CB 2-19: ****** + .byte %11111100 ; 08CC 2-19: ****** + .byte %11111100 ; 08CD 2-19: ****** + .byte %11111100 ; 08CE 2-19: ****** + .byte %11111100 ; 08CF 2-19: ****** .byte %11111111 ; 08D0 2-1a: ******** .byte %11111111 ; 08D1 2-1a: ******** @@ -2542,8 +2551,8 @@ .byte %11111111 ; 08D3 2-1a: ******** .byte %00110011 ; 08D4 2-1a: ** ** .byte %00110011 ; 08D5 2-1a: ** ** - .byte %11001100 ; 08D6 2-1a: ** ** - .byte %11001100 ; 08D7 2-1a: ** ** + .byte %11001100 ; 08D6 2-1a: ** ** + .byte %11001100 ; 08D7 2-1a: ** ** .byte %11111111 ; 08D8 2-1b: ******** .byte %11111111 ; 08D9 2-1b: ******** @@ -2551,8 +2560,8 @@ .byte %11111111 ; 08DB 2-1b: ******** .byte %00110011 ; 08DC 2-1b: ** ** .byte %00110011 ; 08DD 2-1b: ** ** - .byte %11001100 ; 08DE 2-1b: ** ** - .byte %11001100 ; 08DF 2-1b: ** ** + .byte %11001100 ; 08DE 2-1b: ** ** + .byte %11001100 ; 08DF 2-1b: ** ** .byte %11100111 ; 08E0 2-1c: *** *** .byte %11100111 ; 08E1 2-1c: *** *** @@ -2575,8 +2584,8 @@ .byte %11100111 ; 08F0 2-1e: *** *** .byte %11100111 ; 08F1 2-1e: *** *** .byte %11100111 ; 08F2 2-1e: *** *** - .byte %11100000 ; 08F3 2-1e: *** - .byte %11100000 ; 08F4 2-1e: *** + .byte %11100000 ; 08F3 2-1e: *** + .byte %11100000 ; 08F4 2-1e: *** .byte %11100111 ; 08F5 2-1e: *** *** .byte %11100111 ; 08F6 2-1e: *** *** .byte %11100111 ; 08F7 2-1e: *** *** @@ -2584,8 +2593,8 @@ .byte %11100111 ; 08F8 2-1f: *** *** .byte %11100111 ; 08F9 2-1f: *** *** .byte %11100111 ; 08FA 2-1f: *** *** - .byte %11100000 ; 08FB 2-1f: *** - .byte %11100000 ; 08FC 2-1f: *** + .byte %11100000 ; 08FB 2-1f: *** + .byte %11100000 ; 08FC 2-1f: *** .byte %11100111 ; 08FD 2-1f: *** *** .byte %11100111 ; 08FE 2-1f: *** *** .byte %11100111 ; 08FF 2-1f: *** *** @@ -2593,8 +2602,8 @@ .byte %11100111 ; 0900 2-20: *** *** .byte %11100111 ; 0901 2-20: *** *** .byte %11100111 ; 0902 2-20: *** *** - .byte %00000000 ; 0903 2-20: - .byte %00000000 ; 0904 2-20: + .byte %00000000 ; 0903 2-20: + .byte %00000000 ; 0904 2-20: .byte %11100111 ; 0905 2-20: *** *** .byte %11100111 ; 0906 2-20: *** *** .byte %11100111 ; 0907 2-20: *** *** @@ -2602,8 +2611,8 @@ .byte %11100111 ; 0908 2-21: *** *** .byte %11100111 ; 0909 2-21: *** *** .byte %11100111 ; 090A 2-21: *** *** - .byte %00000000 ; 090B 2-21: - .byte %00000000 ; 090C 2-21: + .byte %00000000 ; 090B 2-21: + .byte %00000000 ; 090C 2-21: .byte %11100111 ; 090D 2-21: *** *** .byte %11100111 ; 090E 2-21: *** *** .byte %11100111 ; 090F 2-21: *** *** @@ -2611,8 +2620,8 @@ .byte %11100111 ; 0910 2-22: *** *** .byte %11100111 ; 0911 2-22: *** *** .byte %11100111 ; 0912 2-22: *** *** - .byte %11100000 ; 0913 2-22: *** - .byte %11100000 ; 0914 2-22: *** + .byte %11100000 ; 0913 2-22: *** + .byte %11100000 ; 0914 2-22: *** .byte %11111111 ; 0915 2-22: ******** .byte %11111111 ; 0916 2-22: ******** .byte %11111111 ; 0917 2-22: ******** @@ -2620,8 +2629,8 @@ .byte %11100111 ; 0918 2-23: *** *** .byte %11100111 ; 0919 2-23: *** *** .byte %11100111 ; 091A 2-23: *** *** - .byte %11100000 ; 091B 2-23: *** - .byte %11100000 ; 091C 2-23: *** + .byte %11100000 ; 091B 2-23: *** + .byte %11100000 ; 091C 2-23: *** .byte %11111111 ; 091D 2-23: ******** .byte %11111111 ; 091E 2-23: ******** .byte %11111111 ; 091F 2-23: ******** @@ -2650,8 +2659,8 @@ .byte %11111111 ; 0933 2-26: ******** .byte %11111111 ; 0934 2-26: ******** .byte %11111111 ; 0935 2-26: ******** - .byte %00000000 ; 0936 2-26: - .byte %00000000 ; 0937 2-26: + .byte %00000000 ; 0936 2-26: + .byte %00000000 ; 0937 2-26: .byte %11111111 ; 0938 2-27: ******** .byte %11111111 ; 0939 2-27: ******** @@ -2659,14 +2668,14 @@ .byte %11111111 ; 093B 2-27: ******** .byte %11111111 ; 093C 2-27: ******** .byte %11111111 ; 093D 2-27: ******** - .byte %00000000 ; 093E 2-27: - .byte %00000000 ; 093F 2-27: + .byte %00000000 ; 093E 2-27: + .byte %00000000 ; 093F 2-27: .byte %11111111 ; 0940 2-28: ******** .byte %11111111 ; 0941 2-28: ******** .byte %11111111 ; 0942 2-28: ******** - .byte %11100000 ; 0943 2-28: *** - .byte %11100000 ; 0944 2-28: *** + .byte %11100000 ; 0943 2-28: *** + .byte %11100000 ; 0944 2-28: *** .byte %11100111 ; 0945 2-28: *** *** .byte %11100111 ; 0946 2-28: *** *** .byte %11100111 ; 0947 2-28: *** *** @@ -2674,8 +2683,8 @@ .byte %11111111 ; 0948 2-29: ******** .byte %11111111 ; 0949 2-29: ******** .byte %11111111 ; 094A 2-29: ******** - .byte %11100000 ; 094B 2-29: *** - .byte %11100000 ; 094C 2-29: *** + .byte %11100000 ; 094B 2-29: *** + .byte %11100000 ; 094C 2-29: *** .byte %11100111 ; 094D 2-29: *** *** .byte %11100111 ; 094E 2-29: *** *** .byte %11100111 ; 094F 2-29: *** *** @@ -2683,8 +2692,8 @@ .byte %11100111 ; 0950 2-2a: *** *** .byte %11100111 ; 0951 2-2a: *** *** .byte %11100111 ; 0952 2-2a: *** *** - .byte %00000000 ; 0953 2-2a: - .byte %00000000 ; 0954 2-2a: + .byte %00000000 ; 0953 2-2a: + .byte %00000000 ; 0954 2-2a: .byte %11111111 ; 0955 2-2a: ******** .byte %11111111 ; 0956 2-2a: ******** .byte %11111111 ; 0957 2-2a: ******** @@ -2692,8 +2701,8 @@ .byte %11100111 ; 0958 2-2b: *** *** .byte %11100111 ; 0959 2-2b: *** *** .byte %11100111 ; 095A 2-2b: *** *** - .byte %00000000 ; 095B 2-2b: - .byte %00000000 ; 095C 2-2b: + .byte %00000000 ; 095B 2-2b: + .byte %00000000 ; 095C 2-2b: .byte %11111111 ; 095D 2-2b: ******** .byte %11111111 ; 095E 2-2b: ******** .byte %11111111 ; 095F 2-2b: ******** @@ -2701,8 +2710,8 @@ .byte %11111111 ; 0960 2-2c: ******** .byte %11111111 ; 0961 2-2c: ******** .byte %11111111 ; 0962 2-2c: ******** - .byte %00000000 ; 0963 2-2c: - .byte %00000000 ; 0964 2-2c: + .byte %00000000 ; 0963 2-2c: + .byte %00000000 ; 0964 2-2c: .byte %11100111 ; 0965 2-2c: *** *** .byte %11100111 ; 0966 2-2c: *** *** .byte %11100111 ; 0967 2-2c: *** *** @@ -2710,8 +2719,8 @@ .byte %11111111 ; 0968 2-2d: ******** .byte %11111111 ; 0969 2-2d: ******** .byte %11111111 ; 096A 2-2d: ******** - .byte %00000000 ; 096B 2-2d: - .byte %00000000 ; 096C 2-2d: + .byte %00000000 ; 096B 2-2d: + .byte %00000000 ; 096C 2-2d: .byte %11100111 ; 096D 2-2d: *** *** .byte %11100111 ; 096E 2-2d: *** *** .byte %11100111 ; 096F 2-2d: *** *** @@ -2756,19 +2765,19 @@ .byte %11111111 ; 0991 2-32: ******** .byte %11111111 ; 0992 2-32: ******** .byte %11111111 ; 0993 2-32: ******** - .byte %00000000 ; 0994 2-32: - .byte %00000000 ; 0995 2-32: - .byte %00000000 ; 0996 2-32: - .byte %00000000 ; 0997 2-32: + .byte %00000000 ; 0994 2-32: + .byte %00000000 ; 0995 2-32: + .byte %00000000 ; 0996 2-32: + .byte %00000000 ; 0997 2-32: .byte %11111111 ; 0998 2-33: ******** .byte %11111111 ; 0999 2-33: ******** .byte %11111111 ; 099A 2-33: ******** .byte %11111111 ; 099B 2-33: ******** - .byte %00000000 ; 099C 2-33: - .byte %00000000 ; 099D 2-33: - .byte %00000000 ; 099E 2-33: - .byte %00000000 ; 099F 2-33: + .byte %00000000 ; 099C 2-33: + .byte %00000000 ; 099D 2-33: + .byte %00000000 ; 099E 2-33: + .byte %00000000 ; 099F 2-33: .byte %11111111 ; 09A0 2-34: ******** .byte %11111111 ; 09A1 2-34: ******** @@ -2806,19 +2815,19 @@ .byte %11001111 ; 09BE 2-37: ** **** .byte %11001111 ; 09BF 2-37: ** **** - .byte %11110000 ; 09C0 2-38: **** - .byte %11110000 ; 09C1 2-38: **** - .byte %11110000 ; 09C2 2-38: **** - .byte %11110000 ; 09C3 2-38: **** + .byte %11110000 ; 09C0 2-38: **** + .byte %11110000 ; 09C1 2-38: **** + .byte %11110000 ; 09C2 2-38: **** + .byte %11110000 ; 09C3 2-38: **** .byte %11111111 ; 09C4 2-38: ******** .byte %11111111 ; 09C5 2-38: ******** .byte %11111111 ; 09C6 2-38: ******** .byte %11111111 ; 09C7 2-38: ******** - .byte %11110000 ; 09C8 2-39: **** - .byte %11110000 ; 09C9 2-39: **** - .byte %11110000 ; 09CA 2-39: **** - .byte %11110000 ; 09CB 2-39: **** + .byte %11110000 ; 09C8 2-39: **** + .byte %11110000 ; 09C9 2-39: **** + .byte %11110000 ; 09CA 2-39: **** + .byte %11110000 ; 09CB 2-39: **** .byte %11111111 ; 09CC 2-39: ******** .byte %11111111 ; 09CD 2-39: ******** .byte %11111111 ; 09CE 2-39: ******** @@ -2828,19 +2837,19 @@ .byte %11111111 ; 09D1 2-3a: ******** .byte %11111111 ; 09D2 2-3a: ******** .byte %11111111 ; 09D3 2-3a: ******** - .byte %11110000 ; 09D4 2-3a: **** - .byte %11110000 ; 09D5 2-3a: **** - .byte %11110000 ; 09D6 2-3a: **** - .byte %11110000 ; 09D7 2-3a: **** + .byte %11110000 ; 09D4 2-3a: **** + .byte %11110000 ; 09D5 2-3a: **** + .byte %11110000 ; 09D6 2-3a: **** + .byte %11110000 ; 09D7 2-3a: **** .byte %11111111 ; 09D8 2-3b: ******** .byte %11111111 ; 09D9 2-3b: ******** .byte %11111111 ; 09DA 2-3b: ******** .byte %11111111 ; 09DB 2-3b: ******** - .byte %11110000 ; 09DC 2-3b: **** - .byte %11110000 ; 09DD 2-3b: **** - .byte %11110000 ; 09DE 2-3b: **** - .byte %11110000 ; 09DF 2-3b: **** + .byte %11110000 ; 09DC 2-3b: **** + .byte %11110000 ; 09DD 2-3b: **** + .byte %11110000 ; 09DE 2-3b: **** + .byte %11110000 ; 09DF 2-3b: **** .byte %00001111 ; 09E0 2-3c: **** .byte %00001111 ; 09E1 2-3c: **** @@ -2864,19 +2873,19 @@ .byte %00001111 ; 09F1 2-3e: **** .byte %00001111 ; 09F2 2-3e: **** .byte %00001111 ; 09F3 2-3e: **** - .byte %11110000 ; 09F4 2-3e: **** - .byte %11110000 ; 09F5 2-3e: **** - .byte %11110000 ; 09F6 2-3e: **** - .byte %11110000 ; 09F7 2-3e: **** + .byte %11110000 ; 09F4 2-3e: **** + .byte %11110000 ; 09F5 2-3e: **** + .byte %11110000 ; 09F6 2-3e: **** + .byte %11110000 ; 09F7 2-3e: **** .byte %00001111 ; 09F8 2-3f: **** .byte %00001111 ; 09F9 2-3f: **** .byte %00001111 ; 09FA 2-3f: **** .byte %00001111 ; 09FB 2-3f: **** - .byte %11110000 ; 09FC 2-3f: **** - .byte %11110000 ; 09FD 2-3f: **** - .byte %11110000 ; 09FE 2-3f: **** - .byte %11110000 ; 09FF 2-3f: **** + .byte %11110000 ; 09FC 2-3f: **** + .byte %11110000 ; 09FD 2-3f: **** + .byte %11110000 ; 09FE 2-3f: **** + .byte %11110000 ; 09FF 2-3f: **** .byte %11111111 ; 0A00 2-40: ******** .byte %11111111 ; 0A01 2-40: ******** @@ -2934,18 +2943,18 @@ .byte %10011001 ; 0A30 2-46: * ** * .byte %10011001 ; 0A31 2-46: * ** * - .byte %00000000 ; 0A32 2-46: + .byte %00000000 ; 0A32 2-46: .byte %10011001 ; 0A33 2-46: * ** * - .byte %00000000 ; 0A34 2-46: + .byte %00000000 ; 0A34 2-46: .byte %10011001 ; 0A35 2-46: * ** * .byte %10011001 ; 0A36 2-46: * ** * .byte %11111111 ; 0A37 2-46: ******** .byte %10011001 ; 0A38 2-47: * ** * .byte %10011001 ; 0A39 2-47: * ** * - .byte %00000000 ; 0A3A 2-47: + .byte %00000000 ; 0A3A 2-47: .byte %10011001 ; 0A3B 2-47: * ** * - .byte %00000000 ; 0A3C 2-47: + .byte %00000000 ; 0A3C 2-47: .byte %10011001 ; 0A3D 2-47: * ** * .byte %10011001 ; 0A3E 2-47: * ** * .byte %11111111 ; 0A3F 2-47: ******** @@ -2990,18 +2999,18 @@ .byte %10011001 ; 0A61 2-4c: * ** * .byte %11000011 ; 0A62 2-4c: ** ** .byte %11000111 ; 0A63 2-4c: ** *** - .byte %10011000 ; 0A64 2-4c: * ** + .byte %10011000 ; 0A64 2-4c: * ** .byte %10011001 ; 0A65 2-4c: * ** * - .byte %11000000 ; 0A66 2-4c: ** + .byte %11000000 ; 0A66 2-4c: ** .byte %11111111 ; 0A67 2-4c: ******** .byte %11000011 ; 0A68 2-4d: ** ** .byte %10011001 ; 0A69 2-4d: * ** * .byte %11000011 ; 0A6A 2-4d: ** ** .byte %11000111 ; 0A6B 2-4d: ** *** - .byte %10011000 ; 0A6C 2-4d: * ** + .byte %10011000 ; 0A6C 2-4d: * ** .byte %10011001 ; 0A6D 2-4d: * ** * - .byte %11000000 ; 0A6E 2-4d: ** + .byte %11000000 ; 0A6E 2-4d: ** .byte %11111111 ; 0A6F 2-4d: ******** .byte %11111001 ; 0A70 2-4e: ***** * @@ -3061,7 +3070,7 @@ .byte %11111111 ; 0AA0 2-54: ******** .byte %10011001 ; 0AA1 2-54: * ** * .byte %11000011 ; 0AA2 2-54: ** ** - .byte %00000000 ; 0AA3 2-54: + .byte %00000000 ; 0AA3 2-54: .byte %11000011 ; 0AA4 2-54: ** ** .byte %10011001 ; 0AA5 2-54: * ** * .byte %11111111 ; 0AA6 2-54: ******** @@ -3070,7 +3079,7 @@ .byte %11111111 ; 0AA8 2-55: ******** .byte %10011001 ; 0AA9 2-55: * ** * .byte %11000011 ; 0AAA 2-55: ** ** - .byte %00000000 ; 0AAB 2-55: + .byte %00000000 ; 0AAB 2-55: .byte %11000011 ; 0AAC 2-55: ** ** .byte %10011001 ; 0AAD 2-55: * ** * .byte %11111111 ; 0AAE 2-55: ******** @@ -3149,7 +3158,7 @@ .byte %11111111 ; 0AEF 2-5d: ******** .byte %11111111 ; 0AF0 2-5e: ******** - .byte %11111100 ; 0AF1 2-5e: ****** + .byte %11111100 ; 0AF1 2-5e: ****** .byte %11111001 ; 0AF2 2-5e: ***** * .byte %11110011 ; 0AF3 2-5e: **** ** .byte %11100111 ; 0AF4 2-5e: *** *** @@ -3158,7 +3167,7 @@ .byte %11111111 ; 0AF7 2-5e: ******** .byte %11111111 ; 0AF8 2-5f: ******** - .byte %11111100 ; 0AF9 2-5f: ****** + .byte %11111100 ; 0AF9 2-5f: ****** .byte %11111001 ; 0AFA 2-5f: ***** * .byte %11110011 ; 0AFB 2-5f: **** ** .byte %11100111 ; 0AFC 2-5f: *** *** @@ -3242,7 +3251,7 @@ .byte %11110001 ; 0B41 2-68: **** * .byte %11100001 ; 0B42 2-68: *** * .byte %10011001 ; 0B43 2-68: * ** * - .byte %10000000 ; 0B44 2-68: * + .byte %10000000 ; 0B44 2-68: * .byte %11111001 ; 0B45 2-68: ***** * .byte %11111001 ; 0B46 2-68: ***** * .byte %11111111 ; 0B47 2-68: ******** @@ -3251,7 +3260,7 @@ .byte %11110001 ; 0B49 2-69: **** * .byte %11100001 ; 0B4A 2-69: *** * .byte %10011001 ; 0B4B 2-69: * ** * - .byte %10000000 ; 0B4C 2-69: * + .byte %10000000 ; 0B4C 2-69: * .byte %11111001 ; 0B4D 2-69: ***** * .byte %11111001 ; 0B4E 2-69: ***** * .byte %11111111 ; 0B4F 2-69: ******** @@ -3688,22 +3697,22 @@ .byte %10000001 ; 0CCE 2-99: * * .byte %11111111 ; 0CCF 2-99: ******** - .byte %10011100 ; 0CD0 2-9a: * *** - .byte %10001000 ; 0CD1 2-9a: * * - .byte %10000000 ; 0CD2 2-9a: * - .byte %10010100 ; 0CD3 2-9a: * * * - .byte %10011100 ; 0CD4 2-9a: * *** - .byte %10011100 ; 0CD5 2-9a: * *** - .byte %10011100 ; 0CD6 2-9a: * *** + .byte %10011100 ; 0CD0 2-9a: * *** + .byte %10001000 ; 0CD1 2-9a: * * + .byte %10000000 ; 0CD2 2-9a: * + .byte %10010100 ; 0CD3 2-9a: * * * + .byte %10011100 ; 0CD4 2-9a: * *** + .byte %10011100 ; 0CD5 2-9a: * *** + .byte %10011100 ; 0CD6 2-9a: * *** .byte %11111111 ; 0CD7 2-9a: ******** - .byte %10011100 ; 0CD8 2-9b: * *** - .byte %10001000 ; 0CD9 2-9b: * * - .byte %10000000 ; 0CDA 2-9b: * - .byte %10010100 ; 0CDB 2-9b: * * * - .byte %10011100 ; 0CDC 2-9b: * *** - .byte %10011100 ; 0CDD 2-9b: * *** - .byte %10011100 ; 0CDE 2-9b: * *** + .byte %10011100 ; 0CD8 2-9b: * *** + .byte %10001000 ; 0CD9 2-9b: * * + .byte %10000000 ; 0CDA 2-9b: * + .byte %10010100 ; 0CDB 2-9b: * * * + .byte %10011100 ; 0CDC 2-9b: * *** + .byte %10011100 ; 0CDD 2-9b: * *** + .byte %10011100 ; 0CDE 2-9b: * *** .byte %11111111 ; 0CDF 2-9b: ******** .byte %10011001 ; 0CE0 2-9c: * ** * @@ -3868,22 +3877,22 @@ .byte %11100111 ; 0D6E 2-ad: *** *** .byte %11111111 ; 0D6F 2-ad: ******** - .byte %10011100 ; 0D70 2-ae: * *** - .byte %10011100 ; 0D71 2-ae: * *** - .byte %10011100 ; 0D72 2-ae: * *** - .byte %10010100 ; 0D73 2-ae: * * * - .byte %10000000 ; 0D74 2-ae: * - .byte %10001000 ; 0D75 2-ae: * * - .byte %10011100 ; 0D76 2-ae: * *** + .byte %10011100 ; 0D70 2-ae: * *** + .byte %10011100 ; 0D71 2-ae: * *** + .byte %10011100 ; 0D72 2-ae: * *** + .byte %10010100 ; 0D73 2-ae: * * * + .byte %10000000 ; 0D74 2-ae: * + .byte %10001000 ; 0D75 2-ae: * * + .byte %10011100 ; 0D76 2-ae: * *** .byte %11111111 ; 0D77 2-ae: ******** - .byte %10011100 ; 0D78 2-af: * *** - .byte %10011100 ; 0D79 2-af: * *** - .byte %10011100 ; 0D7A 2-af: * *** - .byte %10010100 ; 0D7B 2-af: * * * - .byte %10000000 ; 0D7C 2-af: * - .byte %10001000 ; 0D7D 2-af: * * - .byte %10011100 ; 0D7E 2-af: * *** + .byte %10011100 ; 0D78 2-af: * *** + .byte %10011100 ; 0D79 2-af: * *** + .byte %10011100 ; 0D7A 2-af: * *** + .byte %10010100 ; 0D7B 2-af: * * * + .byte %10000000 ; 0D7C 2-af: * + .byte %10001000 ; 0D7D 2-af: * * + .byte %10011100 ; 0D7E 2-af: * *** .byte %11111111 ; 0D7F 2-af: ******** .byte %10011001 ; 0D80 2-b0: * ** * @@ -3963,7 +3972,7 @@ .byte %11100111 ; 0DC2 2-b8: *** *** .byte %11110011 ; 0DC3 2-b8: **** ** .byte %11111001 ; 0DC4 2-b8: ***** * - .byte %11111100 ; 0DC5 2-b8: ****** + .byte %11111100 ; 0DC5 2-b8: ****** .byte %11111111 ; 0DC6 2-b8: ******** .byte %11111111 ; 0DC7 2-b8: ******** @@ -3972,7 +3981,7 @@ .byte %11100111 ; 0DCA 2-b9: *** *** .byte %11110011 ; 0DCB 2-b9: **** ** .byte %11111001 ; 0DCC 2-b9: ***** * - .byte %11111100 ; 0DCD 2-b9: ****** + .byte %11111100 ; 0DCD 2-b9: ****** .byte %11111111 ; 0DCE 2-b9: ******** .byte %11111111 ; 0DCF 2-b9: ******** @@ -4018,7 +4027,7 @@ .byte %11111111 ; 0DF3 2-be: ******** .byte %11111111 ; 0DF4 2-be: ******** .byte %11111111 ; 0DF5 2-be: ******** - .byte %10000000 ; 0DF6 2-be: * + .byte %10000000 ; 0DF6 2-be: * .byte %11111111 ; 0DF7 2-be: ******** .byte %11111111 ; 0DF8 2-bf: ******** @@ -4027,7 +4036,7 @@ .byte %11111111 ; 0DFB 2-bf: ******** .byte %11111111 ; 0DFC 2-bf: ******** .byte %11111111 ; 0DFD 2-bf: ******** - .byte %10000000 ; 0DFE 2-bf: * + .byte %10000000 ; 0DFE 2-bf: * .byte %11111111 ; 0DFF 2-bf: ******** .byte %11100111 ; 0E00 2-c0: *** *** @@ -4267,19 +4276,19 @@ .byte %11111111 ; 0ED0 2-da: ******** .byte %11111111 ; 0ED1 2-da: ******** .byte %10011001 ; 0ED2 2-da: * ** * - .byte %10000000 ; 0ED3 2-da: * - .byte %10000000 ; 0ED4 2-da: * - .byte %10010100 ; 0ED5 2-da: * * * - .byte %10011100 ; 0ED6 2-da: * *** + .byte %10000000 ; 0ED3 2-da: * + .byte %10000000 ; 0ED4 2-da: * + .byte %10010100 ; 0ED5 2-da: * * * + .byte %10011100 ; 0ED6 2-da: * *** .byte %11111111 ; 0ED7 2-da: ******** .byte %11111111 ; 0ED8 2-db: ******** .byte %11111111 ; 0ED9 2-db: ******** .byte %10011001 ; 0EDA 2-db: * ** * - .byte %10000000 ; 0EDB 2-db: * - .byte %10000000 ; 0EDC 2-db: * - .byte %10010100 ; 0EDD 2-db: * * * - .byte %10011100 ; 0EDE 2-db: * *** + .byte %10000000 ; 0EDB 2-db: * + .byte %10000000 ; 0EDC 2-db: * + .byte %10010100 ; 0EDD 2-db: * * * + .byte %10011100 ; 0EDE 2-db: * *** .byte %11111111 ; 0EDF 2-db: ******** .byte %11111111 ; 0EE0 2-dc: ******** @@ -4446,18 +4455,18 @@ .byte %11111111 ; 0F70 2-ee: ******** .byte %11111111 ; 0F71 2-ee: ******** - .byte %10011100 ; 0F72 2-ee: * *** - .byte %10010100 ; 0F73 2-ee: * * * - .byte %10000000 ; 0F74 2-ee: * + .byte %10011100 ; 0F72 2-ee: * *** + .byte %10010100 ; 0F73 2-ee: * * * + .byte %10000000 ; 0F74 2-ee: * .byte %11000001 ; 0F75 2-ee: ** * .byte %11001001 ; 0F76 2-ee: ** * * .byte %11111111 ; 0F77 2-ee: ******** .byte %11111111 ; 0F78 2-ef: ******** .byte %11111111 ; 0F79 2-ef: ******** - .byte %10011100 ; 0F7A 2-ef: * *** - .byte %10010100 ; 0F7B 2-ef: * * * - .byte %10000000 ; 0F7C 2-ef: * + .byte %10011100 ; 0F7A 2-ef: * *** + .byte %10010100 ; 0F7B 2-ef: * * * + .byte %10000000 ; 0F7C 2-ef: * .byte %11000001 ; 0F7D 2-ef: ** * .byte %11001001 ; 0F7E 2-ef: ** * * .byte %11111111 ; 0F7F 2-ef: ******** @@ -4570,8 +4579,8 @@ .byte %11000111 ; 0FDE 2-fb: ** *** .byte %11111111 ; 0FDF 2-fb: ******** - .byte %11001100 ; 0FE0 2-fc: ** ** - .byte %00000000 ; 0FE1 2-fc: + .byte %11001100 ; 0FE0 2-fc: ** ** + .byte %00000000 ; 0FE1 2-fc: .byte %00110011 ; 0FE2 2-fc: ** ** .byte %11111111 ; 0FE3 2-fc: ******** .byte %11111111 ; 0FE4 2-fc: ******** @@ -4579,8 +4588,8 @@ .byte %11111111 ; 0FE6 2-fc: ******** .byte %11111111 ; 0FE7 2-fc: ******** - .byte %11001100 ; 0FE8 2-fd: ** ** - .byte %00000000 ; 0FE9 2-fd: + .byte %11001100 ; 0FE8 2-fd: ** ** + .byte %00000000 ; 0FE9 2-fd: .byte %00110011 ; 0FEA 2-fd: ** ** .byte %11111111 ; 0FEB 2-fd: ******** .byte %11111111 ; 0FEC 2-fd: ******** @@ -4605,4 +4614,3 @@ .byte %11111111 ; 0FFD 2-ff: ******** .byte %11111111 ; 0FFE 2-ff: ******** .byte %11111111 ; 0FFF 2-ff: ******** - From c39d07dd177a23079c9660d65f974861f331e29a Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 29 Aug 2018 15:43:20 -0400 Subject: [PATCH 0828/2161] Document style clean-up. --- doc/c128.sgml | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/doc/c128.sgml b/doc/c128.sgml index db93e854c..0094631ad 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -3,8 +3,9 @@ <article> <title>Commodore 128-specific information for cc65 -<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2014-04-12 +<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> +<url url="mailto:polluks@sdf.lonestar.org" name="Stefan A. Haubenthal"> +<date>2018-08-29 <abstract> An overview over the C128 runtime system as it is implemented for the cc65 C @@ -198,6 +199,13 @@ Note: The graphics drivers for the VDC are incompatible with the extended memory drivers using the VDC memory! <descrip> + + <tag><tt/c128-hi.tgi (c128_hi_tgi)/</tag> + This driver features a resolution of 320×200 with two colors and an + adjustable palette (that means that the two colors can be chosen out of a + palette of the 16 VIC colors). Unlike BASIC 7.0, this driver puts its + graphics data into the RAM behind the ROMs. + <tag><tt/c128-vdc.tgi (c128_vdc_tgi)/</tag> This driver was written by Maciej Witkowiak. It uses the 80-column display, and features a resolution of 640×200 with two colors and an adjustable @@ -209,19 +217,13 @@ memory drivers using the VDC memory! display, and features a resolution of 640×480 with two colors and an adjustable palette (that means that the two colors can be chosen out of the 16 VDC colors). The driver requires 64KB VDC RAM. + </descrip><p> -Note: The colors are translated from definitions in headers to correct VDC values; -so, please use definitions or VIC color numbers only. Colors <tt/GRAY3/ and <tt/BROWN/ are -missing on VDC, and are translated to the two colors missing from the VIC palette. - -<descrip> - <tag><tt/c128-hi.tgi (c128_hi_tgi)/</tag> - This driver features a resolution of 320×200 with two colors and an - adjustable palette (that means that the two colors can be chosen out of a - palette of the 16 VIC colors). Unlike BASIC 7.0 this driver put its graphics - data into the RAM behind the ROMs. -</descrip><p> +Note: The colors are translated from the definitions in the headers to correct +VDC values; so, please use definitions or VIC color numbers only. Colors +<tt/GRAY3/ and <tt/BROWN/ are missing on the VDC; and, are translated to the +two colors missing from the VIC palette. <sect1>Extended memory drivers<p> From 203200e259054e4c6c4fd56eb94da5fac5ce11c7 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 29 Sep 2015 12:39:58 -0400 Subject: [PATCH 0829/2161] Used I/O mirror locations that avoid (redirected) zero-page accesses. --- asminc/pce.inc | 10 ++++++---- libsrc/pce/clrscr.s | 4 ++-- libsrc/pce/conio.s | 4 ++-- libsrc/pce/cputc.s | 8 ++++---- libsrc/pce/irq.s | 2 +- libsrc/pce/vdc.s | 4 ++-- 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/asminc/pce.inc b/asminc/pce.inc index 623ab4da8..86ed5232d 100644 --- a/asminc/pce.inc +++ b/asminc/pce.inc @@ -34,11 +34,13 @@ VDC_LENR = 18 ; (DMA) Length Register VDC_SATB = 19 ; Sprite Attribute Table ; VDC port -; Note: absolute addressing mode must be used when writing to this port +; Note: The zero-page addressing mode is redirected to page $20. +; Therefore, absolute addressing mode must be used when writing to this port. +; We force it by using mirror locations that are outside of zero page. -VDC_CTRL = $0000 -VDC_DATA_LO = $0002 -VDC_DATA_HI = $0003 +VDC_CTRL := $0200 +VDC_DATA_LO := $0202 +VDC_DATA_HI := $0203 ; huc6260 - Video Color Encoder (vce) diff --git a/libsrc/pce/clrscr.s b/libsrc/pce/clrscr.s index e3f40bb8b..851c7e317 100644 --- a/libsrc/pce/clrscr.s +++ b/libsrc/pce/clrscr.s @@ -16,9 +16,9 @@ rowloop: ldx #$80 colloop: lda #' ' - sta a:VDC_DATA_LO + sta VDC_DATA_LO lda #$02 - sta a:VDC_DATA_HI + sta VDC_DATA_HI dex bne colloop diff --git a/libsrc/pce/conio.s b/libsrc/pce/conio.s index 674b70279..d5b12c3fe 100644 --- a/libsrc/pce/conio.s +++ b/libsrc/pce/conio.s @@ -90,8 +90,8 @@ charloop: lineloop: lda (ptr1) eor tmp1 - sta a:VDC_DATA_LO ; bitplane 0 - stz a:VDC_DATA_HI ; bitplane 1 + sta VDC_DATA_LO ; bitplane 0 + stz VDC_DATA_HI ; bitplane 1 clc ; increment font pointer lda ptr1 diff --git a/libsrc/pce/cputc.s b/libsrc/pce/cputc.s index cfe6a1a27..aaf67b298 100644 --- a/libsrc/pce/cputc.s +++ b/libsrc/pce/cputc.s @@ -69,15 +69,15 @@ putchar: st0 #VDC_MAWR ; Memory Adress Write lda SCREEN_PTR - sta a:VDC_DATA_LO + sta VDC_DATA_LO lda SCREEN_PTR + 1 - sta a:VDC_DATA_HI + sta VDC_DATA_HI st0 #VDC_VWR ; VWR txa - sta a:VDC_DATA_LO ; character + sta VDC_DATA_LO ; character lda CHARCOLOR @@ -87,7 +87,7 @@ putchar: asl a ora #$02 - sta a:VDC_DATA_HI + sta VDC_DATA_HI rts diff --git a/libsrc/pce/irq.s b/libsrc/pce/irq.s index e0fb68556..60a7e22ba 100644 --- a/libsrc/pce/irq.s +++ b/libsrc/pce/irq.s @@ -32,7 +32,7 @@ IRQStub: ; Save the display-source flags (and, release the interrupt). ; - ldy a:VDC_CTRL + ldy VDC_CTRL sty vdc_flags ldy #<(__INTERRUPTOR_COUNT__ * 2) diff --git a/libsrc/pce/vdc.s b/libsrc/pce/vdc.s index 878c79321..91d58bd51 100644 --- a/libsrc/pce/vdc.s +++ b/libsrc/pce/vdc.s @@ -7,7 +7,7 @@ HIRES = 1 .export vdc_init vdc_init: - lda a:VDC_CTRL + lda VDC_CTRL VREG $00, $0000 ; MAWR VREG $01, $0000 ; MARR @@ -37,5 +37,5 @@ vdc_init: .endif - lda a:VDC_CTRL + lda VDC_CTRL rts From b5d939c858218e0cba64e6ccda6aedba969a3cfe Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 2 Oct 2015 10:50:22 -0400 Subject: [PATCH 0830/2161] Style changes. --- asminc/pce.inc | 20 ++++++------- cfg/pce.cfg | 2 +- doc/pce.sgml | 58 ++++++++++++++++++++----------------- include/pce.h | 8 ++--- libsrc/pce/_scrsize.s | 5 ++-- libsrc/pce/chline.s | 5 +--- libsrc/pce/clock.s | 9 ++---- libsrc/pce/clrscr.s | 6 ++-- libsrc/pce/color.s | 43 ++++++++++++++------------- libsrc/pce/conio.s | 16 +++++----- libsrc/pce/cputc.s | 12 ++++---- libsrc/pce/crt0.s | 40 +++++++++++-------------- libsrc/pce/ctype.s | 4 +-- libsrc/pce/cvline.s | 4 +-- libsrc/pce/extzp.s | 20 ++++++------- libsrc/pce/gotoxy.s | 1 + libsrc/pce/joy/pce-stdjoy.s | 19 +++++------- libsrc/pce/kplot.s | 2 +- libsrc/pce/psg.s | 4 +-- libsrc/pce/revers.s | 6 ++-- libsrc/pce/vce.s | 4 +-- libsrc/pce/vdc.s | 4 +-- libsrc/pce/waitvsync.s | 9 +++--- 23 files changed, 142 insertions(+), 159 deletions(-) diff --git a/asminc/pce.inc b/asminc/pce.inc index 86ed5232d..d2538e8f9 100644 --- a/asminc/pce.inc +++ b/asminc/pce.inc @@ -9,7 +9,7 @@ charsperline = 61 CH_HLINE = 1 CH_VLINE = 2 -; huc6270 - Video Display Controller (VDC) +; HuC6270 - Video Display Controller (VDC) VDC_MAWR = 0 ; Memory Address Write Register VDC_MARR = 1 ; Memory Address Read Register @@ -42,21 +42,21 @@ VDC_CTRL := $0200 VDC_DATA_LO := $0202 VDC_DATA_HI := $0203 -; huc6260 - Video Color Encoder (vce) +; HuC6260 - Video Color Encoder (vce) ; The DAC has a palette of 512 colours. -; bitmap of the palette data is this: 0000000gggrrrbbb. -; You can read and write the DAC-registers. +; The bitmap of the palette data is this: 0000000gggrrrbbb. +; You can read and write the DAC registers. VCE = $0400 ; base -VCE_CTRL = $0400 ; write$00 to reset +VCE_CTRL = $0400 ; write $00 to reset VCE_ADDR_LO = $0402 ; LSB of byte offset into palette VCE_ADDR_HI = $0403 ; MSB of byte offset into palette VCE_DATA_LO = $0404 ; LSB of 16-bit palette data VCE_DATA_HI = $0405 ; MSB of 16-bit palette data -; programmable sound generator (PSG) +; Programmable Sound Generator (PSG) PSG = $0800 ; base @@ -71,12 +71,12 @@ PSG_NOISE = $0807 PSG_LFO_FREQ = $0808 PSG_LFO_CTRL = $0809 -; timer +; Timer -TIMER = $0c00 ; base +TIMER = $0C00 ; base -TIMER_COUNT = $0c00 -TIMER_CTRL = $0c01 +TIMER_COUNT = $0C00 +TIMER_CTRL = $0C01 JOY_CTRL = $1000 diff --git a/cfg/pce.cfg b/cfg/pce.cfg index 77f8c5c97..be0345fc4 100644 --- a/cfg/pce.cfg +++ b/cfg/pce.cfg @@ -1,4 +1,4 @@ -# linker config. to produce a NEC PC-Engine 8K, 16K, or 32K image (.bin) +# Linker config. to produce a NEC PC-Engine 8K, 16K, or 32K image (.bin) SYMBOLS { __CARTSIZE__: type = weak, value = $2000; # $2000, $4000, or $8000 __STACKSIZE__: type = weak, value = $0300; # 3 pages stack diff --git a/doc/pce.sgml b/doc/pce.sgml index bc7dcf5c8..4eeb1c084 100644 --- a/doc/pce.sgml +++ b/doc/pce.sgml @@ -2,10 +2,10 @@ <article> -<title>PC-Engine (TurboGrafx) System specific information for cc65 +<title>PC-Engine (TurboGrafx 16) System-specific information for cc65 <author><url url="mailto:groepaz@gmx.net" name="Groepaz/Hitmen">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2018-02-12 +<date>2018-02-24 <abstract> An overview over the PCE runtime system as it is implemented for the @@ -20,12 +20,12 @@ cc65 C compiler. <sect>Overview<p> This file contains an overview of the PCE runtime system as it comes -with the cc65 C compiler. It describes the memory layout, PCE specific header +with the cc65 C compiler. It describes the memory layout, PCE-specific header files, available drivers, and any pitfalls specific to that platform. -Please note that PCE specific functions are just mentioned here, they are -described in detail in the separate <url url="funcref.html" name="function -reference">. Even functions marked as "platform dependent" may be available on +Please note that PCE-specific functions are just mentioned here; they are +described, in detail, in the separate <url url="funcref.html" name="function +reference">. Even functions marked as "platform dependent" might be available on more than one platform. Please see the function reference for more information. @@ -63,7 +63,7 @@ actually see when they execute the code in that cartridge. <sect>Memory layout<p> -cc65 generated programs with the default setup run with the I/O area and a +cc65-generated programs with the default setup run with the I/O area and a CHR bank enabled, which gives a usable memory range of $8000 - $FFF3. All boot ROM entry points may be called directly without additional code. @@ -71,11 +71,11 @@ Special locations: <descrip> <tag/Text screen and Font/ - The text screen is located at VRAM $0000, + The text screen is located at VRAM $0000; the Font is located at VRAM $2000. <tag/Stack/ - The C runtime stack is located in system RAM at $3FFF and growing downwards. + The C runtime stack is located in system RAM at $3FFF; and, grows downwards. <tag/Data and BSS/ The Data (initialized variables) and BSS (uninitialized variables) sections are @@ -98,12 +98,12 @@ Special locations: -<sect>Platform specific header files<p> +<sect>Platform-specific header files<p> -Programs containing PCE specific code may use the <tt/pce.h/ header file. +Programs containing PCE-specific code may use the <tt/pce.h/ header file. -<sect1>PCE specific functions<p> +<sect1>PCE-specific functions<p> <itemize> <item>waitvsync</item> @@ -111,11 +111,10 @@ Programs containing PCE specific code may use the <tt/pce.h/ header file. </itemize> - <sect1>Hardware access<p> -The following pseudo variables declared in the <tt/pce.inc/ include file do -allow access to hardware located in the address space. +The following pseudo variables, declared in the <tt/pce.inc/ include file, do +allow access to hardware that is located in the address space. <descrip> @@ -153,9 +152,9 @@ No extended memory drivers are currently available for the PCE. <descrip> <tag><tt/pce-stdjoy.joy (pce_stdjoy)/</tag> - A joystick driver for the standard two buttons joypad is available. + A joystick driver for the standard two-button joypad is available. - Note that the japanese 6-button pad is currently not supported. + Note that the Japanese 6-button pad currently is not supported. </descrip><p> @@ -177,6 +176,7 @@ No serial drivers are currently available for the PCE. <item>interruptor support in crt0 (and cfg) is missing </itemize> + <sect1>Disk I/O<p> The existing library for the PCE doesn't implement C file @@ -197,6 +197,8 @@ following functions (and a few others): <item>... </itemize> + + <sect>Other hints<p> <itemize> @@ -204,7 +206,7 @@ following functions (and a few others): emulator to use for the PC-Engine. </itemize> -some useful resources on PCE coding: +Some useful resources on PCE coding: <itemize> <item><url url="http://blog.blockos.org/?tag=pc-engine"> @@ -218,9 +220,11 @@ some useful resources on PCE coding: <item><url url="http://www.zeograd.com/parse.php?src=hucf"> </itemize> + + <sect>License<p> -This software is provided 'as-is', without any expressed or implied +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. @@ -229,14 +233,14 @@ 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. +<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 marked plainly 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/include/pce.h b/include/pce.h index 7744d0148..d7cf0a695 100644 --- a/include/pce.h +++ b/include/pce.h @@ -2,11 +2,11 @@ /* */ /* pce.h */ /* */ -/* PC-Engine system specific definitions */ +/* PC-Engine system-specific definitions */ /* */ /* */ /* */ -/* (C) 2015 Groepaz/Hitmen */ +/* (C) 2015, Groepaz/Hitmen */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -51,7 +51,7 @@ #define CH_ENTER 13 #define CH_PI 18 -/* Color defines (CBM compatible, for conio) */ +/* Color defines (CBM-compatible, for conio) */ #define COLOR_BLACK 0x00 #define COLOR_WHITE 0x01 #define COLOR_RED 0x02 @@ -102,7 +102,7 @@ extern void pce_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ void waitvsync (void); /* Wait for start of the next frame */ -/* NOTE: all PCE are NTSC */ +/* NOTE: all PCEs are NTSC. */ #define get_tv() TV_NTSC /* Return the video mode the machine is using. */ diff --git a/libsrc/pce/_scrsize.s b/libsrc/pce/_scrsize.s index 038622a6f..e730aa83b 100644 --- a/libsrc/pce/_scrsize.s +++ b/libsrc/pce/_scrsize.s @@ -1,9 +1,11 @@ ; ; Screen size variables ; + .export screensize + .export xsize, ysize + .include "pce.inc" - .export screensize screensize: ldx xsize ldy ysize @@ -12,7 +14,6 @@ screensize: ; FIXME: changing the video mode allows for different screen sizes .rodata - .export xsize, ysize xsize: .byte charsperline ysize: .byte screenrows diff --git a/libsrc/pce/chline.s b/libsrc/pce/chline.s index 3c6589375..25644a72a 100644 --- a/libsrc/pce/chline.s +++ b/libsrc/pce/chline.s @@ -6,6 +6,7 @@ ; .export _chlinexy, _chline + .import gotoxy, cputdirect .importzp tmp1 @@ -25,7 +26,3 @@ L1: lda #CH_HLINE ; Horizontal line, screen code dec tmp1 bne L1 L9: rts - - - - diff --git a/libsrc/pce/clock.s b/libsrc/pce/clock.s index 828efdc1d..b71f1e2bc 100644 --- a/libsrc/pce/clock.s +++ b/libsrc/pce/clock.s @@ -2,17 +2,15 @@ ; clock_t clock (void); ; - .include "pce.inc" - .include "extzp.inc" - .export _clock + .constructor initclock, 24 + .forceimport ticktock .importzp sreg - .constructor initclock + .include "extzp.inc" .proc _clock - lda tickcount+3 sta sreg+1 lda tickcount+2 @@ -20,7 +18,6 @@ ldx tickcount+1 lda tickcount rts - .endproc .segment "ONCE" diff --git a/libsrc/pce/clrscr.s b/libsrc/pce/clrscr.s index 851c7e317..6ca12549a 100644 --- a/libsrc/pce/clrscr.s +++ b/libsrc/pce/clrscr.s @@ -1,11 +1,11 @@ + .export _clrscr + + .import plot .include "pce.inc" .include "extzp.inc" - .import plot - .export _clrscr _clrscr: - st0 #VDC_MAWR st1 #<$0000 st2 #>$0000 diff --git a/libsrc/pce/color.s b/libsrc/pce/color.s index 1223d2936..4b8189db6 100644 --- a/libsrc/pce/color.s +++ b/libsrc/pce/color.s @@ -4,14 +4,15 @@ ; unsigned char __fastcall__ bordercolor (unsigned char color); ; - .export _textcolor, _bgcolor, _bordercolor + .export colors + .import return0 .include "pce.inc" .include "extzp.inc" -_bordercolor = return0 +_bordercolor := return0 _textcolor: ldx CHARCOLOR ; get old value @@ -35,27 +36,25 @@ _bgcolor: txa rts - .rodata - .export colors +.rodata -colors: - ; G R B - .word ((0<<6)+(0<<3)+(0)) ; 0 black - .word ((7<<6)+(7<<3)+(7)) ; 1 white - .word ((0<<6)+(7<<3)+(0)) ; 2 red - .word ((7<<6)+(0<<3)+(7)) ; 3 cyan - .word ((0<<6)+(5<<3)+(7)) ; 4 violett - .word ((7<<6)+(0<<3)+(0)) ; 5 green - .word ((0<<6)+(0<<3)+(7)) ; 6 blue - .word ((7<<6)+(7<<3)+(0)) ; 7 yellow - .word ((5<<6)+(7<<3)+(0)) ; 8 orange - .word ((3<<6)+(4<<3)+(3)) ; 9 brown - .word ((4<<6)+(7<<3)+(4)) ; a light red - .word ((3<<6)+(3<<3)+(3)) ; b dark grey - .word ((4<<6)+(4<<3)+(4)) ; c middle grey - .word ((7<<6)+(4<<3)+(4)) ; d light green - .word ((4<<6)+(4<<3)+(7)) ; e light blue - .word ((6<<6)+(6<<3)+(6)) ; f light gray + ; G R B +colors: .word ((0<<6)+(0<<3)+(0)) ; $0 black + .word ((7<<6)+(7<<3)+(7)) ; $1 white + .word ((0<<6)+(7<<3)+(0)) ; $2 red + .word ((7<<6)+(0<<3)+(7)) ; $3 cyan + .word ((0<<6)+(5<<3)+(7)) ; $4 violett + .word ((7<<6)+(0<<3)+(0)) ; $5 green + .word ((0<<6)+(0<<3)+(7)) ; $6 blue + .word ((7<<6)+(7<<3)+(0)) ; $7 yellow + .word ((5<<6)+(7<<3)+(0)) ; $8 orange + .word ((3<<6)+(4<<3)+(3)) ; $9 brown + .word ((4<<6)+(7<<3)+(4)) ; $A light red + .word ((3<<6)+(3<<3)+(3)) ; $B dark grey + .word ((4<<6)+(4<<3)+(4)) ; $C middle grey + .word ((7<<6)+(4<<3)+(4)) ; $D light green + .word ((4<<6)+(4<<3)+(7)) ; $E light blue + .word ((6<<6)+(6<<3)+(6)) ; $F light gray ;------------------------------------------------------------------------------- ; force the init constructor to be imported diff --git a/libsrc/pce/conio.s b/libsrc/pce/conio.s index d5b12c3fe..35276c239 100644 --- a/libsrc/pce/conio.s +++ b/libsrc/pce/conio.s @@ -1,13 +1,13 @@ - .include "pce.inc" - .include "extzp.inc" + .constructor initconio, 24 .import vce_init .import psg_init + .import vdc_init .import colors .importzp ptr1, tmp1 - .constructor initconio - + .include "pce.inc" + .include "extzp.inc" .macpack longbranch .segment "ONCE" @@ -39,7 +39,7 @@ set_palette: inx inx - cpx #16*2 + cpx #16 * 2 jne @lp stz VCE_ADDR_LO @@ -72,7 +72,7 @@ conio_init: lda #>font sta ptr1+1 - lda #$ff + lda #$FF sta tmp1 jsr copy @@ -113,5 +113,5 @@ fillloop: rts -font: - .include "vga.inc" +.rodata +font: .include "vga.inc" diff --git a/libsrc/pce/cputc.s b/libsrc/pce/cputc.s index aaf67b298..5f720dd57 100644 --- a/libsrc/pce/cputc.s +++ b/libsrc/pce/cputc.s @@ -5,11 +5,11 @@ .export _cputcxy, _cputc, cputdirect, putchar .export newline, plot + .import gotoxy .import PLOT .import xsize - - .importzp tmp3,tmp4 + .importzp tmp3, tmp4 .include "pce.inc" .include "extzp.inc" @@ -21,13 +21,13 @@ _cputcxy: ; Plot a character - also used as internal function -_cputc: cmp #$0d ; CR? +_cputc: cmp #$0D ; CR? bne L1 lda #0 sta CURS_X beq plot ; Recalculate pointers -L1: cmp #$0a ; LF? +L1: cmp #$0A ; LF? beq newline ; Recalculate pointers ; Printable char of some sort @@ -43,7 +43,7 @@ advance: cpy xsize bne L3 jsr newline ; new line - ldy #0 ; + cr + ldy #0 ; + CR L3: sty CURS_X jmp plot @@ -71,7 +71,7 @@ putchar: lda SCREEN_PTR sta VDC_DATA_LO - lda SCREEN_PTR + 1 + lda SCREEN_PTR+1 sta VDC_DATA_HI st0 #VDC_VWR ; VWR diff --git a/libsrc/pce/crt0.s b/libsrc/pce/crt0.s index 16e69fc4d..f5ed23186 100644 --- a/libsrc/pce/crt0.s +++ b/libsrc/pce/crt0.s @@ -1,8 +1,8 @@ ; ; Startup code for cc65 (PCEngine version) ; -; by Groepaz/Hitmen <groepaz@gmx.net> -; based on code by Ullrich von Bassewitz <uz@cc65.org> +; by Groepaz/Hitmen <groepaz@gmx.net>, +; based on code by Ullrich von Bassewitz <uz@cc65.org>. ; ; 2018-02-11, Greg King ; @@ -28,16 +28,12 @@ ; ------------------------------------------------------------------------ ; Place the startup code in a special segment. - .segment "STARTUP" - -start: - - ; Set up the CPU and System-IRQ +.segment "STARTUP" ; Initialize CPU - sei +start: sei nop - csh ; Set high speed CPU mode + csh ; Set high-speed CPU mode nop ; Set up stack and memory mapping @@ -64,7 +60,7 @@ start: inc a @L1: tam #%01000000 ; $C000-$DFFF = ROM bank 3 (32K) or 1 (16K) ;lda #$00 ; (The reset default) - ;tam #%10000000 ; $E000-$FFFF hucard/syscard bank 0 + ;tam #%10000000 ; $E000-$FFFF Hucard/Syscard bank 0 ; Initialize hardware stz TIMER_CTRL ; Timer off @@ -72,7 +68,7 @@ start: sta IRQ_MASK ; Interrupts off stz IRQ_STATUS ; Acknowledge timer - ; FIXME; i dont know why the heck this one doesnt work when called from a constructor :/ + ; FIXME; I don't know why the heck this one doesn't work when called from a constructor. :/ .import vdc_init jsr vdc_init @@ -96,24 +92,22 @@ start: ; Call module constructors jsr initlib - cli ; allow IRQ only after constructors have run + cli ; allow IRQ only after constructors have run ; Pass an empty command line jsr push0 ; argc jsr push0 ; argv ldy #4 ; Argument size - jsr _main ; Call the users code + jsr _main ; Call the user's code ; Call module destructors. This is also the _exit entry. -_exit: - jsr donelib ; Run module destructors +_exit: jsr donelib ; Run module destructors ; reset the PCEngine (start over) jmp start -_nmi: - rti +_nmi: rti .export initmainargs initmainargs: @@ -122,10 +116,10 @@ initmainargs: ; ------------------------------------------------------------------------ ; hardware vectors ; ------------------------------------------------------------------------ - .segment "VECTORS" +.segment "VECTORS" - .word IRQStub ; $fff6 IRQ2 (External IRQ, BRK) - .word IRQStub ; $fff8 IRQ1 (VDC) - .word IRQStub ; $fffa Timer - .word _nmi ; $fffc NMI - .word start ; $fffe reset + .word IRQStub ; $FFF6 IRQ2 (External IRQ, BRK) + .word IRQStub ; $FFF8 IRQ1 (VDC) + .word IRQStub ; $FFFA Timer + .word _nmi ; $FFFC NMI + .word start ; $FFFE reset diff --git a/libsrc/pce/ctype.s b/libsrc/pce/ctype.s index fa9a65c8b..16528bae9 100644 --- a/libsrc/pce/ctype.s +++ b/libsrc/pce/ctype.s @@ -10,7 +10,7 @@ .rodata -; The following 256 byte wide table specifies attributes for the isxxx type +; The following 256-byte-wide table specifies attributes for the isxxx type ; of functions. Doing it by a table means some overhead in space, but it ; has major advantages: ; @@ -157,5 +157,3 @@ __ctype: .byte CT_NONE ; 126/7e _____~_____ .byte CT_OTHER_WS ; 127/7f ____DEL____ .endrepeat - - diff --git a/libsrc/pce/cvline.s b/libsrc/pce/cvline.s index 279c691a9..c02378bfa 100644 --- a/libsrc/pce/cvline.s +++ b/libsrc/pce/cvline.s @@ -6,6 +6,7 @@ ; .export _cvlinexy, _cvline + .import gotoxy, putchar, newline .importzp tmp1 @@ -26,6 +27,3 @@ L1: lda #CH_VLINE ; Vertical bar dec tmp1 bne L1 L9: rts - - - diff --git a/libsrc/pce/extzp.s b/libsrc/pce/extzp.s index 26dc589b1..3ac0a1446 100644 --- a/libsrc/pce/extzp.s +++ b/libsrc/pce/extzp.s @@ -4,15 +4,15 @@ ; zeropage locations for exclusive use by the library ; - .include "extzp.inc" + .include "extzp.inc" - .segment "EXTZP" : zeropage +.segment "EXTZP" : zeropage -CURS_X: .res 1 -CURS_Y: .res 1 -SCREEN_PTR: .res 2 -CHARCOLOR: .res 1 -RVS: .res 1 -BGCOLOR: .res 1 -tickcount: .res 4 -vdc_flags: .res 1 +CURS_X: .res 1 +CURS_Y: .res 1 +SCREEN_PTR: .res 2 +CHARCOLOR: .res 1 +RVS: .res 1 +BGCOLOR: .res 1 +tickcount: .res 4 +vdc_flags: .res 1 diff --git a/libsrc/pce/gotoxy.s b/libsrc/pce/gotoxy.s index dae9e6e43..379b02f7c 100644 --- a/libsrc/pce/gotoxy.s +++ b/libsrc/pce/gotoxy.s @@ -3,6 +3,7 @@ ; .export gotoxy, _gotoxy + .import popa, plot .include "pce.inc" diff --git a/libsrc/pce/joy/pce-stdjoy.s b/libsrc/pce/joy/pce-stdjoy.s index c0f338f90..c3985b203 100644 --- a/libsrc/pce/joy/pce-stdjoy.s +++ b/libsrc/pce/joy/pce-stdjoy.s @@ -1,4 +1,3 @@ - ; ; Standard joystick driver for the PCEngine ; @@ -17,8 +16,8 @@ ; Driver signature - .byte $6A, $6F, $79 ; "joy" - .byte JOY_API_VERSION ; Driver API version number + .byte $6A, $6F, $79 ; "joy" + .byte JOY_API_VERSION ; Driver API version number ; Library reference @@ -43,7 +42,7 @@ JOY_COUNT = 4 ; Number of joysticks we support ; 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. +; Must return a JOY_ERR_xx code in a/x. ; INSTALL: @@ -90,7 +89,7 @@ joy1: rts read_joy: - ; reset multitap counter + ; Reset Multitap counter. lda #$01 sta JOY_CTRL pha @@ -108,7 +107,7 @@ read_joy: cly nextpad: lda #$01 - sta JOY_CTRL ; sel = 1 + sta JOY_CTRL ; sel = 1 pha pla nop ; some delay is required @@ -119,21 +118,20 @@ nextpad: asl a asl a asl a - sta padbuffer, y ; store new value + sta padbuffer,y ; store new value stz JOY_CTRL pha pla - nop ; some delay is required nop lda JOY_CTRL and #$0F - ora padbuffer, y ; second half of new value + ora padbuffer,y ; second half of new value eor #$FF - sta padbuffer, y ; store new value + sta padbuffer,y ; store new value iny cpy #$05 @@ -144,4 +142,3 @@ nextpad: padbuffer: .res 4 - diff --git a/libsrc/pce/kplot.s b/libsrc/pce/kplot.s index e4426d005..b533e4a2a 100644 --- a/libsrc/pce/kplot.s +++ b/libsrc/pce/kplot.s @@ -20,7 +20,7 @@ PLOT: ldy CURS_X rts - .rodata +.rodata _plotlo: .repeat screenrows,line diff --git a/libsrc/pce/psg.s b/libsrc/pce/psg.s index c3392d9ff..4e212dd3d 100644 --- a/libsrc/pce/psg.s +++ b/libsrc/pce/psg.s @@ -1,7 +1,7 @@ - .include "pce.inc" - .export psg_init + .include "pce.inc" + .segment "ONCE" psg_init: clx diff --git a/libsrc/pce/revers.s b/libsrc/pce/revers.s index 17a74508c..5c5cd7fbe 100644 --- a/libsrc/pce/revers.s +++ b/libsrc/pce/revers.s @@ -1,11 +1,10 @@ + .export _revers + .include "pce.inc" .include "extzp.inc" - .export _revers - .proc _revers - ldx #$00 ; Assume revers off tay ; Test onoff beq L1 ; Jump if off @@ -18,7 +17,6 @@ L1: lda RVS ; Load old value L2: ldx #$00 ; Load high byte of result tya ; Load low byte, set CC rts - .endproc ;------------------------------------------------------------------------------- diff --git a/libsrc/pce/vce.s b/libsrc/pce/vce.s index 70f4d376a..4a498ab58 100644 --- a/libsrc/pce/vce.s +++ b/libsrc/pce/vce.s @@ -1,7 +1,7 @@ - .include "pce.inc" - .export vce_init + .include "pce.inc" + .segment "ONCE" vce_init: ; Set CTA to zero diff --git a/libsrc/pce/vdc.s b/libsrc/pce/vdc.s index 91d58bd51..170be9cf5 100644 --- a/libsrc/pce/vdc.s +++ b/libsrc/pce/vdc.s @@ -1,11 +1,11 @@ + .export vdc_init + .include "pce.inc" ; FIXME: implement selection of different video modes at runtime HIRES = 1 - .export vdc_init - vdc_init: lda VDC_CTRL diff --git a/libsrc/pce/waitvsync.s b/libsrc/pce/waitvsync.s index c6435dabd..6cdfdda56 100644 --- a/libsrc/pce/waitvsync.s +++ b/libsrc/pce/waitvsync.s @@ -4,17 +4,16 @@ ; void waitvsync (void); ; + .export _waitvsync + + .forceimport ticktock + .include "pce.inc" .include "extzp.inc" - .forceimport ticktock - .export _waitvsync - .proc _waitvsync - lda tickcount @lp: cmp tickcount beq @lp rts - .endproc From 2cc822b44e337e04ac0834f861fa6cadc1473df4 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 2 Oct 2015 13:28:17 -0400 Subject: [PATCH 0831/2161] Fixed some mistakes (mostly in the documentation). --- asminc/pce.inc | 62 +++++++++++++++++++++---------------------- doc/index.sgml | 2 +- doc/pce.sgml | 45 ++++++++++++++++++------------- libsrc/pce/ctype.s | 2 +- libsrc/pce/ticktock.s | 2 +- 5 files changed, 60 insertions(+), 53 deletions(-) diff --git a/asminc/pce.inc b/asminc/pce.inc index d2538e8f9..d603aae08 100644 --- a/asminc/pce.inc +++ b/asminc/pce.inc @@ -1,15 +1,15 @@ ; -; PCE definitions. By Groepaz/Hitmem. +; PCE definitions. By Groepaz/Hitmen. ; -; FIXME: screen dimensions my change according to selected video mode +; FIXME: Screen dimensions can change according to the selected video mode. screenrows = (224/8) charsperline = 61 CH_HLINE = 1 CH_VLINE = 2 -; HuC6270 - Video Display Controller (VDC) +; HuC6270 -- Video Display Controller (VDC) VDC_MAWR = 0 ; Memory Address Write Register VDC_MARR = 1 ; Memory Address Read Register @@ -24,8 +24,8 @@ VDC_BYR = 8 ; Background Y-Scroll Register VDC_MWR = 9 ; Memory-access Width Register VDC_HSR = 10 ; Horizontal Sync Register VDC_HDR = 11 ; Horizontal Display Register -VDC_VPR = 12 ; Vertical synchronous register -VDC_VDW = 13 ; Vertical display register +VDC_VSR = 12 ; Vertical sync Register +VDC_VDR = 13 ; Vertical Display register VDC_VCR = 14 ; Vertical display END position register VDC_DCR = 15 ; (DMA) Control Register VDC_SOUR = 16 ; (DMA) Source Register @@ -42,49 +42,49 @@ VDC_CTRL := $0200 VDC_DATA_LO := $0202 VDC_DATA_HI := $0203 -; HuC6260 - Video Color Encoder (vce) +; HuC6260 -- Video Color Encoder (VCE) ; The DAC has a palette of 512 colours. ; The bitmap of the palette data is this: 0000000gggrrrbbb. ; You can read and write the DAC registers. -VCE = $0400 ; base +VCE := $0400 ; base -VCE_CTRL = $0400 ; write $00 to reset -VCE_ADDR_LO = $0402 ; LSB of byte offset into palette -VCE_ADDR_HI = $0403 ; MSB of byte offset into palette -VCE_DATA_LO = $0404 ; LSB of 16-bit palette data -VCE_DATA_HI = $0405 ; MSB of 16-bit palette data +VCE_CTRL := $0400 ; write $00 to reset +VCE_ADDR_LO := $0402 ; LSB of byte offset into palette +VCE_ADDR_HI := $0403 ; MSB of byte offset into palette +VCE_DATA_LO := $0404 ; LSB of 16-bit palette data +VCE_DATA_HI := $0405 ; MSB of 16-bit palette data ; Programmable Sound Generator (PSG) -PSG = $0800 ; base +PSG := $0800 ; base -PSG_CHAN_SELECT = $0800 -PSG_GLOBAL_PAN = $0801 -PSG_FREQ_LO = $0802 -PSG_FREQ_HI = $0803 -PSG_CHAN_CTRL = $0804 -PSG_CHAN_PAN = $0805 -PSG_CHAN_DATA = $0806 -PSG_NOISE = $0807 -PSG_LFO_FREQ = $0808 -PSG_LFO_CTRL = $0809 +PSG_CHAN_SELECT := $0800 +PSG_GLOBAL_PAN := $0801 +PSG_FREQ_LO := $0802 +PSG_FREQ_HI := $0803 +PSG_CHAN_CTRL := $0804 +PSG_CHAN_PAN := $0805 +PSG_CHAN_DATA := $0806 +PSG_NOISE := $0807 +PSG_LFO_FREQ := $0808 +PSG_LFO_CTRL := $0809 ; Timer -TIMER = $0C00 ; base +TIMER := $0C00 ; base -TIMER_COUNT = $0C00 -TIMER_CTRL = $0C01 +TIMER_COUNT := $0C00 +TIMER_CTRL := $0C01 -JOY_CTRL = $1000 +JOY_CTRL := $1000 -IRQ_MASK = $1402 -IRQ_STATUS = $1403 +IRQ_MASK := $1402 +IRQ_STATUS := $1403 -CDR_MEM_DISABLE = $1803 -CDR_MEM_ENABLE = $1807 +CDR_MEM_DISABLE := $1803 +CDR_MEM_ENABLE := $1807 ; Write VDC register .macro VREG arg1,arg2 diff --git a/doc/index.sgml b/doc/index.sgml index a7aa06037..e1ee064a8 100644 --- a/doc/index.sgml +++ b/doc/index.sgml @@ -159,7 +159,7 @@ Topics specific to the Ohio Scientific machines. <tag><htmlurl url="pce.html" name="pce.html"></tag> - Topics specific to NEC PC-Engine (TurboGrafx) Console. + Topics specific to the NEC PC-Engine (TurboGrafx-16) Console. <tag><htmlurl url="pet.html" name="pet.html"></tag> Topics specific to the Commodore PET machines. diff --git a/doc/pce.sgml b/doc/pce.sgml index 4eeb1c084..ee9c81a49 100644 --- a/doc/pce.sgml +++ b/doc/pce.sgml @@ -63,27 +63,37 @@ actually see when they execute the code in that cartridge. <sect>Memory layout<p> -cc65-generated programs with the default setup run with the I/O area and a -CHR bank enabled, which gives a usable memory range of $8000 - $FFF3. -All boot ROM entry points may be called directly without additional code. +cc65-generated programs with the default setup run with the memory map that was +used by many PC-Engine games: +<itemize> +<item>The first 8K bytes is the I/O area. +<item>The second 8K bytes is RAM, which holds +<itemize> +<item>the redirected zero-page and the redirected hardware stack page, +<item>and 7680 bytes of general memory ($2200 - $3FFF). +</itemize> +<item>The last 8K bytes in the usual 64K-byte range is the ROM that holds the +program. +</itemize> Special locations: <descrip> <tag/Text screen and Font/ - The text screen is located at VRAM $0000; - the Font is located at VRAM $2000. + The text screen is located at Video RAM (VRAM) address $0000; + the Font is located at VRAM address $2000. <tag/Stack/ - The C runtime stack is located in system RAM at $3FFF; and, grows downwards. + The C run-time stack is located in system RAM at $3FFF; + and, grows downwards. <tag/Data and BSS/ The Data (initialized variables) and BSS (uninitialized variables) sections are placed one after the other into system RAM at $2200. <tag/Heap/ - The C heap is located after the end of the BSS section; and, grows towards the C - runtime stack. + The C heap is located after the end of the BSS section; + and, extends up to the C run-time stack. <tag/Code/ In an 8K ROM cartridge, code and read-only data are located between @@ -94,7 +104,7 @@ Special locations: In a 32K cartridge, code and read-only data are located between $8000 and $FFF5. -</descrip><p> +</descrip> @@ -113,21 +123,22 @@ Programs containing PCE-specific code may use the <tt/pce.h/ header file. <sect1>Hardware access<p> -The following pseudo variables, declared in the <tt/pce.inc/ include file, do +The following constants, defined in the <tt/pce.inc/ include file, do allow access to hardware that is located in the address space. <descrip> <tag><tt/PSG/</tag> - The <tt/PSG/ defines allow access to the PSG chip (Programmable Sound Generator). + The <tt/PSG/ defines allow access to the PSG (Programmable Sound Generator). <tag><tt/VCE/</tag> The <tt/VCE/ defines allow access to the VCE chip (Video Color Encoder). <tag><tt/VDC/</tag> - The <tt/VDC/ defines allow access to the VDC chip (Video Display Controller). + The <tt/VDC/ defines allow access to the VDC chip (Video Display Controller).<newline> + 32K of 16-bit words of Video RAM can be accessed only through this chip. -</descrip><p> +</descrip> @@ -156,7 +167,7 @@ No extended memory drivers are currently available for the PCE. Note that the Japanese 6-button pad currently is not supported. -</descrip><p> +</descrip> <sect1>Mouse drivers<p> @@ -172,17 +183,13 @@ No serial drivers are currently available for the PCE. <sect>Limitations<p> -<itemize> -<item>interruptor support in crt0 (and cfg) is missing -</itemize> - <sect1>Disk I/O<p> The existing library for the PCE doesn't implement C file I/O. There are no hacks for the <tt/read()/ and <tt/write()/ routines. -To be more concrete, this limitation means that you cannot use any of the +To be more concrete, that limitation means that you cannot use any of the following functions (and a few others): <itemize> diff --git a/libsrc/pce/ctype.s b/libsrc/pce/ctype.s index 16528bae9..aaedeb1a9 100644 --- a/libsrc/pce/ctype.s +++ b/libsrc/pce/ctype.s @@ -14,7 +14,7 @@ ; of functions. Doing it by a table means some overhead in space, but it ; has major advantages: ; -; * It is fast. If it were'nt for the slow parameter passing of cc65, one +; * It is fast. If it weren't for the slow parameter passing of cc65, one ; could even define macros for the isxxx functions (this is usually ; done on other platforms). ; diff --git a/libsrc/pce/ticktock.s b/libsrc/pce/ticktock.s index 4e4d44d9a..433e00e8d 100644 --- a/libsrc/pce/ticktock.s +++ b/libsrc/pce/ticktock.s @@ -4,7 +4,7 @@ .include "extzp.inc" ticktock: - bbr5 vdc_flags,@s1 ; not vertical-blank interrupt + bbr5 vdc_flags,@s1 ; skip if not vertical-blank interrupt ; Increment the system tick counter. inc tickcount From 959eff34a3c21673f043005c92d46549e9f0e726 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 17 Nov 2015 09:14:15 -0500 Subject: [PATCH 0832/2161] Fixed and improved some pce comments. --- asminc/pce.inc | 13 ++++++------- cfg/pce.cfg | 4 ++-- libsrc/pce/clock.s | 7 +++++-- libsrc/pce/clrscr.s | 10 ++++++++-- libsrc/pce/color.s | 12 ++++++------ libsrc/pce/conio.s | 21 ++++++++++++++------- libsrc/pce/cputc.s | 15 ++++++--------- libsrc/pce/crt0.s | 6 +++--- libsrc/pce/ctype.s | 3 +-- libsrc/pce/gotoxy.s | 2 +- libsrc/pce/joy_stat_stddrv.s | 3 +-- libsrc/pce/psg.s | 2 +- libsrc/pce/revers.s | 12 +++++------- libsrc/pce/vdc.s | 3 +-- libsrc/pce/waitvsync.s | 3 +-- 15 files changed, 61 insertions(+), 55 deletions(-) diff --git a/asminc/pce.inc b/asminc/pce.inc index d603aae08..8d141e899 100644 --- a/asminc/pce.inc +++ b/asminc/pce.inc @@ -13,8 +13,8 @@ CH_VLINE = 2 VDC_MAWR = 0 ; Memory Address Write Register VDC_MARR = 1 ; Memory Address Read Register -VDC_VWR = 2 ; VRAM Write Register (write only) -VDC_VRR = 2 ; VRAM Read Register (read only) +VDC_VWR = 2 ; VRAM Write Register +VDC_VRR = 2 ; VRAM Read Register VDC_UNK03 = 3 ; (unknown) VDC_UNK04 = 4 ; (unknown) VDC_CR = 5 ; Control Register @@ -35,8 +35,7 @@ VDC_SATB = 19 ; Sprite Attribute Table ; VDC port ; Note: The zero-page addressing mode is redirected to page $20. -; Therefore, absolute addressing mode must be used when writing to this port. -; We force it by using mirror locations that are outside of zero page. +; We avoid it by using mirror locations that are outside of the zero page. VDC_CTRL := $0200 VDC_DATA_LO := $0202 @@ -45,7 +44,7 @@ VDC_DATA_HI := $0203 ; HuC6260 -- Video Color Encoder (VCE) ; The DAC has a palette of 512 colours. -; The bitmap of the palette data is this: 0000000gggrrrbbb. +; The bitmap of that data is 0000000gggrrrbbb (Green, Red, Blue). ; You can read and write the DAC registers. VCE := $0400 ; base @@ -86,8 +85,8 @@ IRQ_STATUS := $1403 CDR_MEM_DISABLE := $1803 CDR_MEM_ENABLE := $1807 -; Write VDC register -.macro VREG arg1,arg2 +; Write to a VDC register. +.macro VREG arg1, arg2 st0 #arg1 st1 #<(arg2) st2 #>(arg2) diff --git a/cfg/pce.cfg b/cfg/pce.cfg index be0345fc4..eae9c1316 100644 --- a/cfg/pce.cfg +++ b/cfg/pce.cfg @@ -4,9 +4,9 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0300; # 3 pages stack } MEMORY { - ZP: file = "", start = $0000, size = $0100, define = yes; + ZP: file = "", start = $0000, define = yes, size = $0100; # RAM bank - MAIN: file = "", start = $2200, size = $1E00 - __STACKSIZE__, define = yes; + MAIN: file = "", start = $2200, define = yes, size = $1E00 - __STACKSIZE__; # ROM banks, before swapping, and after mapping ROM: file = %O, start = $10000 - __CARTSIZE__, size = __CARTSIZE__, fill = yes, fillval = $FF; } diff --git a/libsrc/pce/clock.s b/libsrc/pce/clock.s index b71f1e2bc..a57b6c4da 100644 --- a/libsrc/pce/clock.s +++ b/libsrc/pce/clock.s @@ -3,9 +3,9 @@ ; .export _clock - .constructor initclock, 24 + .constructor initclock - .forceimport ticktock + .forceimport ticktock ; make sure that tickcount changes .importzp sreg .include "extzp.inc" @@ -20,6 +20,9 @@ rts .endproc + +; Make the process clock start at zero. + .segment "ONCE" initclock: lda #0 diff --git a/libsrc/pce/clrscr.s b/libsrc/pce/clrscr.s index 6ca12549a..907a78899 100644 --- a/libsrc/pce/clrscr.s +++ b/libsrc/pce/clrscr.s @@ -1,3 +1,9 @@ +; +; Clear (erase) the screen. +; +; Support the full 128- x 64-tile background. +; + .export _clrscr .import plot @@ -15,9 +21,9 @@ _clrscr: rowloop: ldx #$80 colloop: - lda #' ' + lda #' ' ; low byte of char. index sta VDC_DATA_LO - lda #$02 + lda #$02 ; background color, high nybble of char. index sta VDC_DATA_HI dex diff --git a/libsrc/pce/color.s b/libsrc/pce/color.s index 4b8189db6..45eb9ffcd 100644 --- a/libsrc/pce/color.s +++ b/libsrc/pce/color.s @@ -12,17 +12,17 @@ .include "pce.inc" .include "extzp.inc" -_bordercolor := return0 +_bordercolor := return0 ; always black _textcolor: - ldx CHARCOLOR ; get old value - sta CHARCOLOR ; set new value + ldx CHARCOLOR ; get old value + sta CHARCOLOR ; set new value txa rts _bgcolor: - ldx BGCOLOR ; get old value - sta BGCOLOR ; set new value + ldx BGCOLOR ; get old value + sta BGCOLOR ; set new value asl a tay @@ -43,7 +43,7 @@ colors: .word ((0<<6)+(0<<3)+(0)) ; $0 black .word ((7<<6)+(7<<3)+(7)) ; $1 white .word ((0<<6)+(7<<3)+(0)) ; $2 red .word ((7<<6)+(0<<3)+(7)) ; $3 cyan - .word ((0<<6)+(5<<3)+(7)) ; $4 violett + .word ((0<<6)+(5<<3)+(7)) ; $4 violet .word ((7<<6)+(0<<3)+(0)) ; $5 green .word ((0<<6)+(0<<3)+(7)) ; $6 blue .word ((7<<6)+(7<<3)+(0)) ; $7 yellow diff --git a/libsrc/pce/conio.s b/libsrc/pce/conio.s index 35276c239..46907cc42 100644 --- a/libsrc/pce/conio.s +++ b/libsrc/pce/conio.s @@ -28,7 +28,7 @@ set_palette: ldx #0 @lp: - ldy #16 + ldy #16 ; size of a pallette @lp1: lda colors,x sta VCE_DATA_LO @@ -42,6 +42,8 @@ set_palette: cpx #16 * 2 jne @lp +; Set background to black. + stz VCE_ADDR_LO stz VCE_ADDR_HI stz VCE_DATA_LO @@ -49,13 +51,18 @@ set_palette: rts +;---------------------------------------------------------------------------- +; 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. + conio_init: ; Load font st0 #VDC_MAWR st1 #<$2000 st2 #>$2000 - ; ptr to font data + ; pointer to font data lda #<font sta ptr1 lda #>font @@ -76,7 +83,7 @@ conio_init: sta tmp1 jsr copy - ldx #0 + ldx #0 ; white on black stx BGCOLOR inx stx CHARCOLOR @@ -101,11 +108,11 @@ lineloop: adc #$00 sta ptr1+1 dex - bne lineloop ; next bitplane 0 byte - ldx #$08 ; fill bitplane 2/3 with 0 + bne lineloop ; next bitplane-0 byte + ldx #$08 ; fill bitplanes 2 and 3 with 0 fillloop: - st1 #$00 - st2 #$00 + st1 #<$0000 + st2 #>$0000 dex bne fillloop ; next byte dey diff --git a/libsrc/pce/cputc.s b/libsrc/pce/cputc.s index 5f720dd57..5d9afdc93 100644 --- a/libsrc/pce/cputc.s +++ b/libsrc/pce/cputc.s @@ -25,10 +25,10 @@ _cputc: cmp #$0D ; CR? bne L1 lda #0 sta CURS_X - beq plot ; Recalculate pointers + beq plot ; Recalculate pointer L1: cmp #$0A ; LF? - beq newline ; Recalculate pointers + beq newline ; Recalculate pointer ; Printable char of some sort @@ -50,23 +50,21 @@ L3: sty CURS_X newline: inc CURS_Y -; Set cursor position, calculate RAM pointers +; Set cursor position; calculate VRAM pointer. 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 +; Write one character to the screen without doing anything else. putchar: - ora RVS ; Set revers bit tax - st0 #VDC_MAWR ; Memory Adress Write + st0 #VDC_MAWR ; Memory Address Write lda SCREEN_PTR sta VDC_DATA_LO @@ -79,8 +77,7 @@ putchar: txa sta VDC_DATA_LO ; character - lda CHARCOLOR - + lda CHARCOLOR ; pallette number asl a asl a asl a diff --git a/libsrc/pce/crt0.s b/libsrc/pce/crt0.s index f5ed23186..2b079727f 100644 --- a/libsrc/pce/crt0.s +++ b/libsrc/pce/crt0.s @@ -36,7 +36,7 @@ start: sei csh ; Set high-speed CPU mode nop - ; Set up stack and memory mapping + ; Set up stack and memory mapping. ldx #$FF ; Stack top ($21FF) txs @@ -74,7 +74,7 @@ start: sei ; Turn on background and VD interrupt/IRQ1 lda #$05 - sta IRQ_MASK ; IRQ1=on + sta IRQ_MASK ; IRQ1 = on ; Copy the .data segment to RAM tii __DATA_LOAD__, __DATA_RUN__, __DATA_SIZE__ @@ -87,7 +87,7 @@ start: sei lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) sta sp - stx sp + 1 + stx sp+1 ; Call module constructors jsr initlib diff --git a/libsrc/pce/ctype.s b/libsrc/pce/ctype.s index aaedeb1a9..1ee51b230 100644 --- a/libsrc/pce/ctype.s +++ b/libsrc/pce/ctype.s @@ -6,7 +6,7 @@ .include "ctype.inc" -; The tables are readonly, put them into the rodata segment +; The tables are read-only; put them into the RODATA segment. .rodata @@ -23,7 +23,6 @@ ; ; * We save some code in the isxxx functions. - __ctype: .repeat 2 .byte CT_CTRL ; 0/00 ___ctrl_@___ diff --git a/libsrc/pce/gotoxy.s b/libsrc/pce/gotoxy.s index 379b02f7c..dd7cbf1c2 100644 --- a/libsrc/pce/gotoxy.s +++ b/libsrc/pce/gotoxy.s @@ -1,5 +1,5 @@ ; -; void gotoxy (unsigned char x, unsigned char y); +; void __fastcall__ gotoxy (unsigned char x, unsigned char y); ; .export gotoxy, _gotoxy diff --git a/libsrc/pce/joy_stat_stddrv.s b/libsrc/pce/joy_stat_stddrv.s index 2424c456b..87af5617c 100644 --- a/libsrc/pce/joy_stat_stddrv.s +++ b/libsrc/pce/joy_stat_stddrv.s @@ -7,8 +7,7 @@ ; .export _joy_static_stddrv + .import _pce_stdjoy_joy -.rodata - _joy_static_stddrv := _pce_stdjoy_joy diff --git a/libsrc/pce/psg.s b/libsrc/pce/psg.s index 4e212dd3d..996b4e5ac 100644 --- a/libsrc/pce/psg.s +++ b/libsrc/pce/psg.s @@ -5,7 +5,7 @@ .segment "ONCE" psg_init: clx - stz PSG_GLOBAL_PAN ; Clear global balance + stz PSG_GLOBAL_PAN ; Silence global balance psg_clear_loop: stx PSG_CHAN_SELECT ; Select channel diff --git a/libsrc/pce/revers.s b/libsrc/pce/revers.s index 5c5cd7fbe..b31ff150c 100644 --- a/libsrc/pce/revers.s +++ b/libsrc/pce/revers.s @@ -1,7 +1,11 @@ +; +; Ullrich von Bassewitz, 07.08.1998 +; +; unsigned char revers (unsigned char onoff); +; .export _revers - .include "pce.inc" .include "extzp.inc" .proc _revers @@ -18,9 +22,3 @@ L2: ldx #$00 ; Load high byte of result tya ; Load low byte, set CC rts .endproc - -;------------------------------------------------------------------------------- -; force the init constructor to be imported - - .import initconio -conio_init = initconio diff --git a/libsrc/pce/vdc.s b/libsrc/pce/vdc.s index 170be9cf5..e73004db8 100644 --- a/libsrc/pce/vdc.s +++ b/libsrc/pce/vdc.s @@ -1,4 +1,3 @@ - .export vdc_init .include "pce.inc" @@ -15,7 +14,7 @@ vdc_init: VREG $06, $0000 ; RCR VREG $07, $0000 ; BXR VREG $08, $0000 ; BYR - VREG $09, $0070 ; MAWR + VREG $09, $0070 ; MWR VREG $0C, $1702 ; CRTC - VSR VREG $0D, $00DF ; CRTC - VDS VREG $0E, $000C ; CRTC - VDE diff --git a/libsrc/pce/waitvsync.s b/libsrc/pce/waitvsync.s index 6cdfdda56..fed10c4e8 100644 --- a/libsrc/pce/waitvsync.s +++ b/libsrc/pce/waitvsync.s @@ -6,9 +6,8 @@ .export _waitvsync - .forceimport ticktock + .forceimport ticktock ; make sure that tickcount changes - .include "pce.inc" .include "extzp.inc" .proc _waitvsync From 39694d0aaa4bef354bf6c719d92d9c55757ee869 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 26 Nov 2015 15:06:20 -0500 Subject: [PATCH 0833/2161] Fixed bugs; and, improved the efficiency of some pce library functions. --- libsrc/pce/clock.s | 41 ++++++++------ libsrc/pce/clrscr.s | 13 ++--- libsrc/pce/color.s | 1 + libsrc/pce/conio.s | 103 ++++++++++++------------------------ libsrc/pce/cputc.s | 49 +++++++---------- libsrc/pce/crt0.s | 47 ++++++++-------- libsrc/pce/gotoxy.s | 7 --- libsrc/pce/irq.s | 4 +- libsrc/pce/joy/pce-stdjoy.s | 14 +++-- libsrc/pce/kplot.s | 21 +++----- libsrc/pce/psg.s | 12 ++--- libsrc/pce/revers.s | 27 +++++----- libsrc/pce/ticktock.s | 3 +- libsrc/pce/vce.s | 5 +- libsrc/pce/vdc.s | 34 +++++------- libsrc/pce/vga.inc | 6 ++- 16 files changed, 158 insertions(+), 229 deletions(-) diff --git a/libsrc/pce/clock.s b/libsrc/pce/clock.s index a57b6c4da..1d7579a2f 100644 --- a/libsrc/pce/clock.s +++ b/libsrc/pce/clock.s @@ -2,32 +2,39 @@ ; clock_t clock (void); ; - .export _clock .constructor initclock + .export _clock .forceimport ticktock ; make sure that tickcount changes - .importzp sreg - - .include "extzp.inc" - -.proc _clock - lda tickcount+3 - sta sreg+1 - lda tickcount+2 - sta sreg - ldx tickcount+1 - lda tickcount - rts -.endproc + .importzp tickcount, sreg ; Make the process clock start at zero. .segment "ONCE" initclock: - lda #0 - ldx #3 -@lp: sta tickcount,x + ldx #4 - 1 +@lp: stz tickcount,x dex bpl @lp rts + +; ------------------------------------------------------------------------ +.code + +; This function might be interrupted while it is reading the several bytes of +; the clock. They are read again if that happens. (We do not want to stop +; interrupts because that might cause glitches in interrupt-driven graphics +; and sound.) + +.proc _clock + lda tickcount + ldy tickcount+3 + sty sreg+1 + ldy tickcount+2 + sty sreg + ldx tickcount+1 + cmp tickcount + bne _clock ; clock changed; reread it + rts +.endproc diff --git a/libsrc/pce/clrscr.s b/libsrc/pce/clrscr.s index 907a78899..476277886 100644 --- a/libsrc/pce/clrscr.s +++ b/libsrc/pce/clrscr.s @@ -12,20 +12,15 @@ .include "extzp.inc" _clrscr: - st0 #VDC_MAWR - st1 #<$0000 - st2 #>$0000 - + VREG VDC_MAWR, $0000 st0 #VDC_VWR + ldy #$40 rowloop: ldx #$80 colloop: - lda #' ' ; low byte of char. index - sta VDC_DATA_LO - lda #$02 ; background color, high nybble of char. index - sta VDC_DATA_HI - + st1 #' ' ; low byte of char. index + st2 #$02 ; background color, high nybble of char. index dex bne colloop dey diff --git a/libsrc/pce/color.s b/libsrc/pce/color.s index 45eb9ffcd..a527cb2c0 100644 --- a/libsrc/pce/color.s +++ b/libsrc/pce/color.s @@ -21,6 +21,7 @@ _textcolor: rts _bgcolor: + and #$0F ldx BGCOLOR ; get old value sta BGCOLOR ; set new value asl a diff --git a/libsrc/pce/conio.s b/libsrc/pce/conio.s index 46907cc42..8fefe01f6 100644 --- a/libsrc/pce/conio.s +++ b/libsrc/pce/conio.s @@ -1,36 +1,27 @@ .constructor initconio, 24 - .import vce_init - .import psg_init .import vdc_init + .import psg_init .import colors .importzp ptr1, tmp1 .include "pce.inc" .include "extzp.inc" - .macpack longbranch .segment "ONCE" initconio: - jsr vce_init + jsr vdc_init jsr psg_init - jsr conio_init - jsr set_palette - - st0 #VDC_CR - st1 #<$0088 - st2 #>$0088 - rts + jsr load_font set_palette: stz VCE_ADDR_LO stz VCE_ADDR_HI - ldx #0 -@lp: - ldy #16 ; size of a pallette -@lp1: - lda colors,x + clx +@lp: ldy #16 ; size of a palette + +@lp1: lda colors,x sta VCE_DATA_LO lda colors+1,x sta VCE_DATA_HI @@ -39,58 +30,34 @@ set_palette: inx inx - cpx #16 * 2 - jne @lp + cpx #16 * 2 ; 16 palettes + bne @lp -; Set background to black. - - stz VCE_ADDR_LO - stz VCE_ADDR_HI - stz VCE_DATA_LO - stz VCE_DATA_HI + sty BGCOLOR ; white on black + iny + sty CHARCOLOR + VREG VDC_CR, $0088 ; enable background and vertical-blank interrupt rts -;---------------------------------------------------------------------------- -; 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. +; Load the conio font into the VDC. +load_font: + VREG VDC_MAWR, $2000 + st0 #VDC_VWR -conio_init: - ; Load font - st0 #VDC_MAWR - st1 #<$2000 - st2 #>$2000 + stz tmp1 ; #%00000000 + bsr copy ; make normal characters - ; pointer to font data - lda #<font + dec tmp1 ; #%11111111 +; bsr copy ; make reversed characters +; rts ; (fall through) + +; Point to the font data. +copy: lda #<font + ldx #>font sta ptr1 - lda #>font - sta ptr1+1 + stx ptr1+1 - st0 #VDC_VWR ; VWR - - lda #0 - sta tmp1 - jsr copy - - lda #<font - sta ptr1 - lda #>font - sta ptr1+1 - - lda #$FF - sta tmp1 - jsr copy - - ldx #0 ; white on black - stx BGCOLOR - inx - stx CHARCOLOR - - rts - -copy: ldy #$80 ; 128 chars charloop: ldx #$08 ; 8 bytes/char @@ -98,23 +65,21 @@ lineloop: lda (ptr1) eor tmp1 sta VDC_DATA_LO ; bitplane 0 - stz VDC_DATA_HI ; bitplane 1 + st2 #>$0000 ; bitplane 1 - clc ; increment font pointer - lda ptr1 - adc #$01 - sta ptr1 - lda ptr1+1 - adc #$00 - sta ptr1+1 - dex + inc ptr1 ; increment font pointer + bne @noC + inc ptr1+1 +@noC: dex bne lineloop ; next bitplane-0 byte + ldx #$08 ; fill bitplanes 2 and 3 with 0 fillloop: st1 #<$0000 st2 #>$0000 dex bne fillloop ; next byte + dey bne charloop ; next character diff --git a/libsrc/pce/cputc.s b/libsrc/pce/cputc.s index 5d9afdc93..04d901423 100644 --- a/libsrc/pce/cputc.s +++ b/libsrc/pce/cputc.s @@ -5,6 +5,7 @@ .export _cputcxy, _cputc, cputdirect, putchar .export newline, plot + .forceimport initconio ; force conio initiation .import gotoxy .import PLOT @@ -23,9 +24,8 @@ _cputcxy: _cputc: cmp #$0D ; CR? bne L1 - lda #0 - sta CURS_X - beq plot ; Recalculate pointer + stz CURS_X + bra plot ; Recalculate pointer L1: cmp #$0A ; LF? beq newline ; Recalculate pointer @@ -35,20 +35,16 @@ L1: cmp #$0A ; LF? cputdirect: jsr putchar ; Write the character to the screen -; Advance cursor position +; Move the cursor (rightwards) to the next position. advance: ldy CURS_X iny cpy xsize bne L3 - jsr newline ; new line - ldy #0 ; + CR + inc CURS_Y ; new line + cly ; + CR L3: sty CURS_X - jmp plot - -newline: - inc CURS_Y ; Set cursor position; calculate VRAM pointer. @@ -57,24 +53,22 @@ plot: ldy CURS_X clc jmp PLOT ; Set the new cursor +newline: + inc CURS_Y + bra plot + ; Write one character to the screen without doing anything else. putchar: - ora RVS ; Set revers bit + ora RVS ; Set reverse bit - tax + st0 #VDC_MAWR ; Memory-Address Write + ldy SCREEN_PTR + ldx SCREEN_PTR+1 + sty VDC_DATA_LO + stx VDC_DATA_HI - st0 #VDC_MAWR ; Memory Address Write - - lda SCREEN_PTR - sta VDC_DATA_LO - - lda SCREEN_PTR+1 - sta VDC_DATA_HI - - st0 #VDC_VWR ; VWR - - txa + st0 #VDC_VWR sta VDC_DATA_LO ; character lda CHARCOLOR ; pallette number @@ -82,14 +76,7 @@ putchar: asl a asl a asl a - - ora #$02 + ora #>$0200 ; high nybble of char. index sta VDC_DATA_HI rts - -;------------------------------------------------------------------------------- -; force the init constructor to be imported - - .import initconio -conio_init = initconio diff --git a/libsrc/pce/crt0.s b/libsrc/pce/crt0.s index 2b079727f..d6dee3ef4 100644 --- a/libsrc/pce/crt0.s +++ b/libsrc/pce/crt0.s @@ -1,18 +1,19 @@ ; -; Startup code for cc65 (PCEngine version) +; Start-up code for cc65 (PC-Engine version) ; ; by Groepaz/Hitmen <groepaz@gmx.net>, -; based on code by Ullrich von Bassewitz <uz@cc65.org>. +; based on code by Ullrich von Bassewitz <uz@cc65.org> ; -; 2018-02-11, Greg King +; 2018-02-24, Greg King ; .export _exit - .export __STARTUP__ : absolute = 1 ; Mark as startup + .export __STARTUP__ : absolute = 1 ; Mark as start-up .import initlib, donelib .import push0, _main - .import IRQStub + .import IRQStub, __nmi + .importzp sp ; Linker-generated .import __CARTSIZE__ @@ -23,20 +24,18 @@ .include "pce.inc" .include "extzp.inc" - .importzp sp - ; ------------------------------------------------------------------------ -; Place the startup code in a special segment. +; Place the start-up code in a special segment. .segment "STARTUP" - ; Initialize CPU + ; Initialize the CPU. start: sei nop csh ; Set high-speed CPU mode nop - ; Set up stack and memory mapping. + ; Set up the stack and the memory mapping. ldx #$FF ; Stack top ($21FF) txs @@ -62,18 +61,19 @@ start: sei ;lda #$00 ; (The reset default) ;tam #%10000000 ; $E000-$FFFF Hucard/Syscard bank 0 - ; Initialize hardware + ; Initialize the hardware. stz TIMER_CTRL ; Timer off - lda #$07 + lda #%00000111 sta IRQ_MASK ; Interrupts off - stz IRQ_STATUS ; Acknowledge timer - ; FIXME; I don't know why the heck this one doesn't work when called from a constructor. :/ + ; FIXME; I don't know why the heck this one doesn't work when called from a constructor. -Groepaz :-/ +.if 0 ; It now seems to work (at least, in Mednafen). -Greg King .import vdc_init jsr vdc_init +.endif - ; Turn on background and VD interrupt/IRQ1 - lda #$05 + ; Allow interrupts from the VDC. + lda #%00000101 sta IRQ_MASK ; IRQ1 = on ; Copy the .data segment to RAM @@ -89,10 +89,11 @@ start: sei sta sp stx sp+1 - ; Call module constructors + ; Call the module constructors. jsr initlib - cli ; allow IRQ only after constructors have run + stz IRQ_STATUS ; Clear IRQs + cli ; Allow IRQ only after constructors have run ; Pass an empty command line jsr push0 ; argc @@ -101,14 +102,12 @@ start: sei ldy #4 ; Argument size jsr _main ; Call the user's code - ; Call module destructors. This is also the _exit entry. -_exit: jsr donelib ; Run module destructors + ; Call the module destructors. This is also the exit() entry. +_exit: jsr donelib - ; reset the PCEngine (start over) + ; Reset the PCEngine (start over). jmp start -_nmi: rti - .export initmainargs initmainargs: rts @@ -121,5 +120,5 @@ initmainargs: .word IRQStub ; $FFF6 IRQ2 (External IRQ, BRK) .word IRQStub ; $FFF8 IRQ1 (VDC) .word IRQStub ; $FFFA Timer - .word _nmi ; $FFFC NMI + .word __nmi ; $FFFC NMI .word start ; $FFFE reset diff --git a/libsrc/pce/gotoxy.s b/libsrc/pce/gotoxy.s index dd7cbf1c2..49f0c602a 100644 --- a/libsrc/pce/gotoxy.s +++ b/libsrc/pce/gotoxy.s @@ -17,10 +17,3 @@ _gotoxy: jsr popa ; Get X sta CURS_X ; Set X jmp plot ; Set the cursor position - -;------------------------------------------------------------------------------- -; force the init constructor to be imported - - .import initconio -conio_init = initconio - diff --git a/libsrc/pce/irq.s b/libsrc/pce/irq.s index 60a7e22ba..7ab42d8a8 100644 --- a/libsrc/pce/irq.s +++ b/libsrc/pce/irq.s @@ -2,7 +2,7 @@ ; IRQ handling (PCE version) ; - .export initirq, doneirq, IRQStub + .export initirq, doneirq, IRQStub, __nmi .import __INTERRUPTOR_COUNT__, callirq_y @@ -45,4 +45,4 @@ IRQStub: pla plx @L1: ply - rti +__nmi: rti diff --git a/libsrc/pce/joy/pce-stdjoy.s b/libsrc/pce/joy/pce-stdjoy.s index c3985b203..2de3d0c4c 100644 --- a/libsrc/pce/joy/pce-stdjoy.s +++ b/libsrc/pce/joy/pce-stdjoy.s @@ -36,6 +36,10 @@ JOY_COUNT = 4 ; Number of joysticks we support +.bss + +padbuffer: .res JOY_COUNT + .code ; ------------------------------------------------------------------------ @@ -67,7 +71,7 @@ UNINSTALL: COUNT: lda #<JOY_COUNT - ldx #>JOY_COUNT + clx ; ldx #>JOY_COUNT rts ; ------------------------------------------------------------------------ @@ -85,7 +89,6 @@ READJOY: joy1: lda padbuffer,x - ldx #0 rts read_joy: @@ -134,11 +137,6 @@ nextpad: sta padbuffer,y ; store new value iny - cpy #$05 + cpy #.sizeof(padbuffer) bcc nextpad rts - -.bss - -padbuffer: - .res 4 diff --git a/libsrc/pce/kplot.s b/libsrc/pce/kplot.s index b533e4a2a..ae31710f3 100644 --- a/libsrc/pce/kplot.s +++ b/libsrc/pce/kplot.s @@ -4,16 +4,15 @@ .include "pce.inc" .include "extzp.inc" -PLOT: - bcs @getpos +PLOT: bcs @getpos tya ;clc ; already cleared - adc _plotlo,x + adc plotlo,x sta SCREEN_PTR - lda _plothi,x - adc #0 + cla + adc plothi,x sta SCREEN_PTR+1 @getpos: ldx CURS_Y @@ -22,18 +21,10 @@ PLOT: .rodata -_plotlo: - .repeat screenrows,line +plotlo: .repeat screenrows,line .byte <($0000+(line*$80)) .endrepeat -_plothi: - .repeat screenrows,line +plothi: .repeat screenrows,line .byte >($0000+(line*$80)) .endrepeat - -;------------------------------------------------------------------------------- -; force the init constructor to be imported - - .import initconio -conio_init = initconio diff --git a/libsrc/pce/psg.s b/libsrc/pce/psg.s index 996b4e5ac..7087c2084 100644 --- a/libsrc/pce/psg.s +++ b/libsrc/pce/psg.s @@ -4,8 +4,8 @@ .segment "ONCE" psg_init: - clx stz PSG_GLOBAL_PAN ; Silence global balance + ldx #6 - 1 psg_clear_loop: stx PSG_CHAN_SELECT ; Select channel @@ -17,14 +17,12 @@ psg_clear_loop: stz PSG_LFO_FREQ ; Clear LFO frequency stz PSG_LFO_CTRL ; Clear LFO control - cly + ldy #$20 psg_clear_waveform: stz PSG_CHAN_DATA ; Clear waveform byte - iny - cpy #$20 + dey bne psg_clear_waveform - inx - cpx #$06 - bne psg_clear_loop + dex + bpl psg_clear_loop rts diff --git a/libsrc/pce/revers.s b/libsrc/pce/revers.s index b31ff150c..ff9957efd 100644 --- a/libsrc/pce/revers.s +++ b/libsrc/pce/revers.s @@ -1,24 +1,23 @@ ; -; Ullrich von Bassewitz, 07.08.1998 +; 1998-08-07, Ullrich von Bassewitz +; 2015-11-23, Greg King ; -; unsigned char revers (unsigned char onoff); +; unsigned char __fastcall__ revers (unsigned char onoff); ; .export _revers - .include "extzp.inc" + .importzp RVS .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 + cmp #$01 ; False or true? + cla + ror a ; Either $00 or $80 + ldy RVS ; Load old value + sta RVS ; Set new value + tya + asl a + rol a ; Either $00 or $01 + clx rts .endproc diff --git a/libsrc/pce/ticktock.s b/libsrc/pce/ticktock.s index 433e00e8d..b1974ee4d 100644 --- a/libsrc/pce/ticktock.s +++ b/libsrc/pce/ticktock.s @@ -1,6 +1,5 @@ - .interruptor ticktock, 24 + .interruptor ticktock - .include "pce.inc" .include "extzp.inc" ticktock: diff --git a/libsrc/pce/vce.s b/libsrc/pce/vce.s index 4a498ab58..d7f5bdc1d 100644 --- a/libsrc/pce/vce.s +++ b/libsrc/pce/vce.s @@ -7,9 +7,10 @@ vce_init: ; Set CTA to zero stz VCE_ADDR_LO stz VCE_ADDR_HI - ldy #$01 + + ldy #$01 ; Only background palettes vce_clear_bank: - ldx #$00 + clx ; ldx #<$0100 ; <(16 * 16) vce_clear_color: stz VCE_DATA_LO ; Clear color (LSB) stz VCE_DATA_HI ; Clear color (MSB) diff --git a/libsrc/pce/vdc.s b/libsrc/pce/vdc.s index e73004db8..8495a9163 100644 --- a/libsrc/pce/vdc.s +++ b/libsrc/pce/vdc.s @@ -8,33 +8,25 @@ HIRES = 1 vdc_init: lda VDC_CTRL - VREG $00, $0000 ; MAWR - VREG $01, $0000 ; MARR - VREG $05, $0000 ; CR - VREG $06, $0000 ; RCR - VREG $07, $0000 ; BXR - VREG $08, $0000 ; BYR - VREG $09, $0070 ; MWR - VREG $0C, $1702 ; CRTC - VSR - VREG $0D, $00DF ; CRTC - VDS - VREG $0E, $000C ; CRTC - VDE - VREG $0F, $0000 ; DCR + VREG VDC_CR , $0000 ; disable display and interrupts + VREG VDC_BXR, $0000 ; no scrolling + VREG VDC_BYR, $0000 + VREG VDC_MWR, $0070 ; 128 x 64 tiles (1024 x 512 pixels) + VREG VDC_VSR, $1702 ; CRTC + VREG VDC_VDR, $00DF ; CRTC - VDS + VREG VDC_VCR, $000C ; CRTC - VDE + VREG VDC_DCR, $0000 .if HIRES - - VREG $0A, $0C02 ; CRTC - HSR - VREG $0B, $043C ; CRTC - HDS + VREG VDC_HSR, $0C02 ; CRTC + VREG VDC_HDR, $043C ; CRTC - HDS lda #$06 - sta VCE_CTRL - .else - - VREG $0A, $0202 ; CRTC - HSR - VREG $0B, $041F ; CRTC - HDS + VREG VDC_HSR, $0202 ; CRTC + VREG VDC_HDR, $041F ; CRTC - HDS lda #$04 - sta VCE_CTRL - .endif + sta VCE_CTRL lda VDC_CTRL rts diff --git a/libsrc/pce/vga.inc b/libsrc/pce/vga.inc index 9317d6ce4..72c173146 100644 --- a/libsrc/pce/vga.inc +++ b/libsrc/pce/vga.inc @@ -1,5 +1,9 @@ +;---------------------------------------------------------------------------- +; VGA font for the PC-Engine conio implementation -; VGA charset for the PC-Engine conio implementation +; 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. .byte $00, $00, $00, $00, $00, $00, $00, $00 From 70a131e09ab92f9093f95075ded9e5149201a7ce Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 2 Sep 2018 23:06:27 +0200 Subject: [PATCH 0834/2161] Just a minor comment improvement. --- libsrc/apple2/getdevice.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/apple2/getdevice.s b/libsrc/apple2/getdevice.s index ef35edea7..0c674cad0 100644 --- a/libsrc/apple2/getdevice.s +++ b/libsrc/apple2/getdevice.s @@ -18,7 +18,7 @@ _getfirstdevice: _getnextdevice: tax next: inx - cpx #$FF + cpx #$FF ; INVALID_DEVICE beq done ; Check for ProDOS 8 From cd9efd53fe1b4588e5473452304960f3072ed529 Mon Sep 17 00:00:00 2001 From: Laubzega <mileksmyk@gmail.com> Date: Tue, 4 Sep 2018 00:34:28 -0700 Subject: [PATCH 0835/2161] Segment OVERLAY renamed to REPLACE. Bugfix for read-only segments. Formatting. --- src/ld65/bin.c | 4 ++-- src/ld65/config.c | 24 +++++++++++------------- src/ld65/config.h | 2 +- src/ld65/scanner.h | 2 +- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/ld65/bin.c b/src/ld65/bin.c index f4d241add..c94ac9319 100644 --- a/src/ld65/bin.c +++ b/src/ld65/bin.c @@ -194,8 +194,8 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M) } if (DoWrite || (M->Flags & MF_FILL) != 0) { /* Seek in "overlay" segments */ - if (S->Flags & SF_OVERLAY) { - fseek(D->F, NewAddr - M->Start, SEEK_SET); + if (S->Flags & SF_REPLACE) { + fseek (D->F, NewAddr - M->Start, SEEK_SET); } else { WriteMult (D->F, M->FillVal, NewAddr-Addr); PrintNumVal ("SF_OFFSET", NewAddr - Addr); diff --git a/src/ld65/config.c b/src/ld65/config.c index f6603d628..5c61bdd3f 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -653,7 +653,7 @@ static void ParseSegments (void) { "RW", CFGTOK_RW }, { "BSS", CFGTOK_BSS }, { "ZP", CFGTOK_ZP }, - { "OVERLAY", CFGTOK_OVERLAY }, + { "REPLACE", CFGTOK_REPLACE }, }; unsigned Count; @@ -754,12 +754,12 @@ static void ParseSegments (void) FlagAttr (&S->Attr, SA_TYPE, "TYPE"); CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type"); switch (CfgTok) { - case CFGTOK_RO: S->Flags |= SF_RO; break; - case CFGTOK_RW: /* Default */ break; - case CFGTOK_BSS: S->Flags |= SF_BSS; break; - case CFGTOK_ZP: S->Flags |= (SF_BSS | SF_ZP); break; - case CFGTOK_OVERLAY: S->Flags |= SF_OVERLAY; break; - default: Internal ("Unexpected token: %d", CfgTok); + case CFGTOK_RO: S->Flags |= SF_RO; break; + case CFGTOK_RW: /* Default */ break; + case CFGTOK_BSS: S->Flags |= SF_BSS; break; + case CFGTOK_ZP: S->Flags |= (SF_BSS | SF_ZP); break; + case CFGTOK_REPLACE: S->Flags |= (SF_REPLACE | SF_RO); break; + default: Internal ("Unexpected token: %d", CfgTok); } CfgNextTok (); break; @@ -1854,17 +1854,15 @@ unsigned CfgProcess (void) /* Take note of overlayed segments and make sure there are no other ** segment types following them in current memory region. */ - if (S->Flags & SF_OVERLAY) { - { + if (S->Flags & SF_REPLACE) { if (S->Flags & (SF_OFFSET | SF_START)) { ++Overlays; } else { CfgError (GetSourcePos (M->LI), "Segment `%s' of type `overlay' requires either" - " `Start' or `Offset' argument to be specified.", + " `Start' or `Offset' attribute to be specified", GetString (S->Name)); } - } } else { if (Overlays > 0) { CfgError (GetSourcePos (M->LI), @@ -1923,10 +1921,10 @@ unsigned CfgProcess (void) NewAddr += M->Start; } - if (S->Flags & SF_OVERLAY) { + if (S->Flags & SF_REPLACE) { if (NewAddr < M->Start) { CfgError (GetSourcePos (S->LI), - "Segment `%s' begins before memory area `%s'.", + "Segment `%s' begins before memory area `%s'", GetString (S->Name), GetString (M->Name)); } else { Addr = NewAddr; diff --git a/src/ld65/config.h b/src/ld65/config.h index a60580da3..d172560bd 100644 --- a/src/ld65/config.h +++ b/src/ld65/config.h @@ -96,7 +96,7 @@ struct SegDesc { #define SF_RUN_DEF 0x0200 /* RUN symbols already defined */ #define SF_LOAD_DEF 0x0400 /* LOAD symbols already defined */ #define SF_FILLVAL 0x0800 /* Segment has separate fill value */ -#define SF_OVERLAY 0x1000 /* Segment can be overlayed on another one */ +#define SF_REPLACE 0x1000 /* Segment can replace (part of) another one */ diff --git a/src/ld65/scanner.h b/src/ld65/scanner.h index e994c0547..2c60da975 100644 --- a/src/ld65/scanner.h +++ b/src/ld65/scanner.h @@ -105,7 +105,7 @@ typedef enum { CFGTOK_RW, CFGTOK_BSS, CFGTOK_ZP, - CFGTOK_OVERLAY, + CFGTOK_REPLACE, CFGTOK_O65, CFGTOK_BIN, From d199ca14602d3fe9bceb74dcabcdbfaa16726f99 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 4 Sep 2018 23:08:38 +0200 Subject: [PATCH 0836/2161] Atari, Atari5200: disable "attract mode" on mouse or joystick input Fixes #736. --- libsrc/atari/joy/atrmj8.s | 13 +++++++- libsrc/atari/joy/atrstd.s | 15 ++++++++-- libsrc/atari/mou/atrjoy.s | 20 +++++++++++-- libsrc/atari/mou/atrst.s | 38 +++++++++++++++-------- libsrc/atari/mou/atrtt.s | 50 ++++++++++++++++++------------- libsrc/atari5200/joy/atr5200std.s | 16 ++++++++-- 6 files changed, 111 insertions(+), 41 deletions(-) diff --git a/libsrc/atari/joy/atrmj8.s b/libsrc/atari/joy/atrmj8.s index 9b02485d6..3a26c381d 100644 --- a/libsrc/atari/joy/atrmj8.s +++ b/libsrc/atari/joy/atrmj8.s @@ -95,6 +95,8 @@ COUNT: ; READJOY: + and #JOY_COUNT-1 ; fix joystick number + tax ; Joystick number into X asl a asl a asl a @@ -110,5 +112,14 @@ READJOY: asl a ora PORTA ; add position information eor #$1F - ldx #0 ; fix X + cmp oldval,x + beq :+ + sta oldval,x + ldx #0 + stx ATRACT ; we have interaction, disable "attract mode" +: ldx #0 ; fix X rts + + .bss + +oldval: .res JOY_COUNT diff --git a/libsrc/atari/joy/atrstd.s b/libsrc/atari/joy/atrstd.s index 0c49499f8..fd1d99d31 100644 --- a/libsrc/atari/joy/atrstd.s +++ b/libsrc/atari/joy/atrstd.s @@ -93,8 +93,8 @@ _400800: ; READJOY: - and #3 ; fix joystick number - tax ; Joystick number (0-3) into X + and #JOY_COUNT-1 ; fix joystick number + tax ; Joystick number into X ; Read joystick @@ -105,5 +105,14 @@ READJOY: asl a ora STICK0,x ; add position information eor #$1F - ldx #0 ; fix X + cmp oldval,x + beq :+ + sta oldval,x + ldx #0 + stx ATRACT ; we have interaction, disable "attract mode" +: ldx #0 ; fix X rts + + .bss + +oldval: .res JOY_COUNT diff --git a/libsrc/atari/mou/atrjoy.s b/libsrc/atari/mou/atrjoy.s index 7f1085fb8..3ea428576 100644 --- a/libsrc/atari/mou/atrjoy.s +++ b/libsrc/atari/mou/atrjoy.s @@ -89,6 +89,8 @@ YMin: .res 2 ; Y1 value of bounding box XMax: .res 2 ; X2 value of bounding box YMax: .res 2 ; Y2 value of bounding box Buttons: .res 1 ; Button mask +OldDir: .res 1 ; previous direction bits +OldButton: .res 1 ; previous buttons Temp: .res 1 ; Temporary value used in the int handler @@ -336,9 +338,24 @@ IRQ: jsr CPREP +; Check if user activity occurred, and if yes, disable "attract mode" + + lda Buttons + cmp OldButton + beq @ChkDir + sta OldButton + lda #0 + sta ATRACT ; disable "attract mode" +@ChkDir:lda Temp + cmp OldDir + beq @ChkCnt + sta OldDir + lda #0 + sta ATRACT + ; Check left/right - lda Temp ; Read joystick #0 +@ChkCnt:lda Temp ; Read joystick #0 and #(JOY::LEFT | JOY::RIGHT) beq @SkipX ; @@ -437,4 +454,3 @@ IRQ: @SkipY: jsr CDRAW clc ; Interrupt not "handled" rts - diff --git a/libsrc/atari/mou/atrst.s b/libsrc/atari/mou/atrst.s index 17d2affb5..f8ba24551 100644 --- a/libsrc/atari/mou/atrst.s +++ b/libsrc/atari/mou/atrst.s @@ -126,6 +126,7 @@ YMin: .res 2 ; Y1 value of bounding box XMax: .res 2 ; X2 value of bounding box YMax: .res 2 ; Y2 value of bounding box Buttons: .res 1 ; Button mask +OldButton: .res 1 ; previous buttons XPosWrk: .res 2 YPosWrk: .res 2 @@ -496,6 +497,8 @@ IRQ: lda PORTA ; mouse port contents cmp old_porta_vbi beq @L3 ; no motion + lda #0 + sta ATRACT ; disable "attract mode" ; Turn mouse polling IRQ back on @@ -544,25 +547,34 @@ IRQ: lda PORTA ; mouse port contents jsr CPREP +; Disable "attract mode" if button status has changed + + lda Buttons + cmp OldButton + beq @L5 + sta OldButton + lda #0 + sta ATRACT + ; Limit the X coordinate to the bounding box - lda XPosWrk+1 +@L5: lda XPosWrk+1 ldy XPosWrk tax cpy XMin sbc XMin+1 - bpl @L5 + bpl @L6 ldy XMin ldx XMin+1 - jmp @L6 + jmp @L7 -@L5: txa +@L6: txa cpy XMax sbc XMax+1 - bmi @L6 + bmi @L7 ldy XMax ldx XMax+1 -@L6: sty XPos +@L7: sty XPos stx XPos+1 tya jsr CMOVEX @@ -574,18 +586,18 @@ IRQ: lda PORTA ; mouse port contents tax cpy YMin sbc YMin+1 - bpl @L7 + bpl @L8 ldy YMin ldx YMin+1 - jmp @L8 + jmp @L9 -@L7: txa +@L8: txa cpy YMax sbc YMax+1 - bmi @L8 + bmi @L9 ldy YMax ldx YMax+1 -@L8: sty YPos +@L9: sty YPos stx YPos+1 tya jsr CMOVEY @@ -595,10 +607,10 @@ IRQ: lda PORTA ; mouse port contents .ifdef DEBUG ; print on upper right corner 'E' or 'D', indicating the IRQ is enabled or disabled ldy irq_enabled - beq @L9 + beq @L10 lda #37 ; screen code for 'E' .byte $2c ; bit opcode, eats next 2 bytes -@L9: lda #36 ; screen code for 'D' +@L10: lda #36 ; screen code for 'D' ldy #39 sta (SAVMSC),y .endif diff --git a/libsrc/atari/mou/atrtt.s b/libsrc/atari/mou/atrtt.s index f1f2cde63..61963aa61 100644 --- a/libsrc/atari/mou/atrtt.s +++ b/libsrc/atari/mou/atrtt.s @@ -88,6 +88,7 @@ YMin: .res 2 ; Y1 value of bounding box XMax: .res 2 ; X2 value of bounding box YMax: .res 2 ; Y2 value of bounding box Buttons: .res 1 ; Button mask +OldButton: .res 1 ; previous buttons ; Default values for above variables @@ -337,10 +338,19 @@ IRQ: ora Buttons sta Buttons +; Check if button status changed, and disable "attract mode" if yes + +@L02: lda Buttons + cmp OldButton + beq @L03 + sta OldButton + lda #0 + sta ATRACT + ; If we read 228 for X or Y positions, we assume the user has lifted the pen ; and don't change the cursor position. -@L02: lda PADDL0 +@L03: lda PADDL0 cmp #228 beq @Cont ; CF set if equal lda PADDL1 @@ -350,12 +360,13 @@ IRQ: jsr CPREP plp ; restore CF - bcc @L03 + bcc @L04 jmp @Show -@L03: ldx #0 +@L04: ldx #0 stx XPos+1 stx YPos+1 + stx ATRACT ; disable "attract mode" ; Get cursor position ; ------------------- @@ -382,9 +393,9 @@ IRQ: clc adc XPos sta XPos - bcc @L04 + bcc @L05 inc XPos+1 -@L04: txa +@L05: txa lsr a ; port value / 4 lsr a ; port value / 8 tax @@ -393,18 +404,18 @@ IRQ: stx XPos sbc XPos sta XPos - bcs @L05 + bcs @L06 dec XPos+1 -@L05: txa +@L06: txa lsr a ; port value / 16 lsr a ; port value / 32 clc adc XPos sta XPos - bcc @L06 + bcc @L07 inc XPos+1 -@L06: tay +@L07: tay lda XPos+1 tax @@ -412,18 +423,18 @@ IRQ: cpy XMin sbc XMin+1 - bpl @L07 + bpl @L08 ldy XMin ldx XMin+1 - jmp @L08 -@L07: txa + jmp @L09 +@L08: txa cpy XMax sbc XMax+1 - bmi @L08 + bmi @L09 ldy XMax ldx XMax+1 -@L08: sty XPos +@L09: sty XPos stx XPos+1 ; Move the mouse pointer to the new X pos @@ -456,18 +467,18 @@ IRQ: cpy YMin sbc YMin+1 - bpl @L09 + bpl @L10 ldy YMin ldx YMin+1 - jmp @L10 -@L09: txa + jmp @L11 +@L10: txa cpy YMax sbc YMax+1 - bmi @L10 + bmi @L11 ldy YMax ldx YMax+1 -@L10: sty YPos +@L11: sty YPos stx YPos+1 ; Move the mouse pointer to the new X pos @@ -479,4 +490,3 @@ IRQ: clc ; Interrupt not "handled" rts - diff --git a/libsrc/atari5200/joy/atr5200std.s b/libsrc/atari5200/joy/atr5200std.s index 002ffdaaf..989bc5ee0 100644 --- a/libsrc/atari5200/joy/atr5200std.s +++ b/libsrc/atari5200/joy/atr5200std.s @@ -82,6 +82,7 @@ SENSIVITY = 16 READJOY: and #3 ; put joystick number in range, just in case + sta jsnum ; remember joystick number tay asl a tax ; Joystick number * 2 (0-6) into X, index into ZP shadow registers @@ -89,7 +90,7 @@ READJOY: lda #0 ; Initialize return value cmp TRIG0,y bne @notrg - lda #$10 ; JOY_BTN + ora #$10 ; JOY_BTN ; Read joystick @@ -119,4 +120,15 @@ READJOY: ora #2 ; JOY_DOWN -@done: rts +@done: ldx #0 + ldy jsnum + cmp oldval,y + beq @ret + sta oldval,y + stx ATRACT +@ret: rts + +.bss + +oldval:.res 4 +jsnum: .res 1 From 1cc4fa9356a8a7ca17b3bd519dc818531a8e6b66 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Sun, 2 Sep 2018 23:07:03 +0200 Subject: [PATCH 0837/2161] Atari: fix interrupt handling if extended memory is banked in Extendend memory is mapped over the main memory in the 0x4000..0x7FFF area. Many DOSes disable interrupts while extended memory is banked in, but not all (e.g. SpartaDOS-X). This change modifies the initial interrupt handler to map in main memory before chaining to the "worker" handlers. Since the initial interrupt handler uses a data segment to store the trampoline to chain to the original handler, introduce a new "LOWBSS" segment to hold this trampoline. Otherwise the trampoline may end up inside the 0x4000..0x7FFF area. Add a link time warning if "LOWCODE" segment lays within the extended memory window. --- cfg/atari-cart.cfg | 32 +++++++++++++++++--------------- cfg/atari-cassette.cfg | 1 + cfg/atari-overlay.cfg | 1 + cfg/atari.cfg | 1 + cfg/atarixl-largehimem.cfg | 1 + cfg/atarixl-overlay.cfg | 1 + cfg/atarixl.cfg | 1 + libsrc/atari/crt0.s | 9 +++++++++ libsrc/atari/irq.s | 21 +++++++++++++++------ 9 files changed, 47 insertions(+), 21 deletions(-) diff --git a/cfg/atari-cart.cfg b/cfg/atari-cart.cfg index 31d2cb1b9..16208f90d 100644 --- a/cfg/atari-cart.cfg +++ b/cfg/atari-cart.cfg @@ -10,23 +10,25 @@ SYMBOLS { __CARTFLAGS__: type = weak, value = $01; # see documentation for other possible values } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; - MAIN: file = "", define = yes, start = %S, size = __CARTSIZE__; - ROM: file = %O, define = yes, start = $C000 - __CARTSIZE__, size = __CARTSIZE__ - 6, fill = yes, fillval = $FF; - CARTID: file = %O, start = $BFFA, size = $0006; + ZP: file = "", define = yes, start = $0082, size = $007E; + MAIN: file = "", define = yes, start = %S, size = __CARTSIZE__; + ROM: file = %O, define = yes, start = $C000 - __CARTSIZE__, size = __CARTSIZE__ - 6, fill = yes, fillval = $FF; + CARTID: file = %O, start = $BFFA, size = $0006; + DISCARD: file = "", start = $0100, size = $FF00; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp, optional = yes; - EXTZP: load = ZP, type = zp, 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; - CODE: load = ROM, type = ro, define = yes; - RODATA: load = ROM, type = ro, optional = yes; - DATA: load = ROM, run = MAIN, type = rw, define = yes, optional = yes; - INIT: load = MAIN, type = bss, optional = yes; - BSS: load = MAIN, type = bss, define = yes, optional = yes; - CARTHDR: load = CARTID, type = ro; + ZEROPAGE: load = ZP, type = zp, optional = yes; + EXTZP: load = ZP, type = zp, optional = yes; + STARTUP: load = ROM, type = ro, define = yes, optional = yes; + LOWBSS: load = DISCARD, run = MAIN, type = rw, optional = yes; # not zero-initialized + LOWCODE: load = ROM, type = ro, define = yes, optional = yes; + ONCE: load = ROM, type = ro, optional = yes; + CODE: load = ROM, type = ro, define = yes; + RODATA: load = ROM, type = ro, optional = yes; + DATA: load = ROM, run = MAIN, type = rw, define = yes, optional = yes; + INIT: load = MAIN, type = bss, optional = yes; + BSS: load = MAIN, type = bss, define = yes, optional = yes; + CARTHDR: load = CARTID, type = ro; } FEATURES { CONDES: type = constructor, diff --git a/cfg/atari-cassette.cfg b/cfg/atari-cassette.cfg index 5e99c303e..465add95e 100644 --- a/cfg/atari-cassette.cfg +++ b/cfg/atari-cassette.cfg @@ -16,6 +16,7 @@ SEGMENTS { EXTZP: load = ZP, type = zp, optional = yes; CASHDR: load = MAIN, type = ro; STARTUP: load = MAIN, type = ro, define = yes, optional = yes; + LOWBSS: load = MAIN, type = rw, optional = yes; # not zero-initialized LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro, define = yes; diff --git a/cfg/atari-overlay.cfg b/cfg/atari-overlay.cfg index 87e62d764..fdf2e983c 100644 --- a/cfg/atari-overlay.cfg +++ b/cfg/atari-overlay.cfg @@ -46,6 +46,7 @@ SEGMENTS { SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes; MAINHDR: load = MAINHDR, type = ro; STARTUP: load = MAIN, type = ro, define = yes; + LOWBSS: load = MAIN, type = rw, optional = yes; # not zero-initialized LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro, define = yes; diff --git a/cfg/atari.cfg b/cfg/atari.cfg index 4680a89ed..9e0ea474f 100644 --- a/cfg/atari.cfg +++ b/cfg/atari.cfg @@ -34,6 +34,7 @@ SEGMENTS { SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes; MAINHDR: load = MAINHDR, type = ro; STARTUP: load = MAIN, type = ro, define = yes; + LOWBSS: load = MAIN, type = rw, optional = yes; # not zero-initialized LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro, define = yes; diff --git a/cfg/atarixl-largehimem.cfg b/cfg/atarixl-largehimem.cfg index 56d2af15b..842a485a1 100644 --- a/cfg/atarixl-largehimem.cfg +++ b/cfg/atarixl-largehimem.cfg @@ -61,6 +61,7 @@ SEGMENTS { MAINHDR: load = MAINHDR, type = ro; STARTUP: load = MAIN, type = ro, define = yes; + LOWBSS: load = MAIN, type = rw, optional = yes; # not zero-initialized LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro, define = yes; diff --git a/cfg/atarixl-overlay.cfg b/cfg/atarixl-overlay.cfg index 923436497..f3a40b6a7 100644 --- a/cfg/atarixl-overlay.cfg +++ b/cfg/atarixl-overlay.cfg @@ -72,6 +72,7 @@ SEGMENTS { MAINHDR: load = MAINHDR, type = ro; STARTUP: load = MAIN, type = ro, define = yes; + LOWBSS: load = MAIN, type = rw, optional = yes; # not zero-initialized LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro, define = yes; diff --git a/cfg/atarixl.cfg b/cfg/atarixl.cfg index 197daace6..c2d331fab 100644 --- a/cfg/atarixl.cfg +++ b/cfg/atarixl.cfg @@ -59,6 +59,7 @@ SEGMENTS { MAINHDR: load = MAINHDR, type = ro; STARTUP: load = MAIN, type = ro, define = yes; + LOWBSS: load = MAIN, type = rw, optional = yes; # not zero-initialized LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro, define = yes; diff --git a/libsrc/atari/crt0.s b/libsrc/atari/crt0.s index d14567491..97b7d7e95 100644 --- a/libsrc/atari/crt0.s +++ b/libsrc/atari/crt0.s @@ -15,6 +15,7 @@ .import callmain, zerobss .import __RESERVED_MEMORY__ .import __MAIN_START__, __MAIN_SIZE__ + .import __LOWCODE_RUN__, __LOWCODE_SIZE__ .ifdef __ATARIXL__ .import __STACKSIZE__ .import sram_init @@ -199,3 +200,11 @@ LMARGN_save: .res 1 .ifndef __ATARIXL__ APPMHI_save: .res 2 .endif + +; ------------------------------------------------------------------------ + +.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 +; check for LOWCODE_RUN > $7FFF is mostly for cartridges, where this segment is loaded high (into cart ROM) +; there is a small chance that if the user loads the program really high, LOWCODE is above $7FFF, but LOWBSS is below -- no warning emitted in this case diff --git a/libsrc/atari/irq.s b/libsrc/atari/irq.s index 1878ea0a2..86fef609b 100644 --- a/libsrc/atari/irq.s +++ b/libsrc/atari/irq.s @@ -16,6 +16,8 @@ .segment "ONCE" initirq: + lda #$4C ; JMP opcode + sta IRQInd lda VVBLKD ldx VVBLKD+1 sta IRQInd+1 @@ -45,17 +47,22 @@ IRQStub: .ifdef CHARGEN_RELOC lda CHBAS pha +.endif .endif lda PORTB pha - and #$FE - sta PORTB ; disable ROM +.ifdef __ATARIXL__ + and #$FE ; disable ROM +.endif + ora #$10 ; map main memory into $4000..$7FFF area + sta PORTB +.ifdef __ATARIXL__ set_chbase >__CHARGEN_START__ .endif jsr callirq ; Call the functions -.ifdef __ATARIXL__ pla - sta PORTB ; restore old ROM setting + sta PORTB ; restore old memory settings +.ifdef __ATARIXL__ .ifdef CHARGEN_RELOC pla sta CHBAS @@ -66,6 +73,8 @@ IRQStub: ; ------------------------------------------------------------------------ -.data +.segment "LOWBSS" -IRQInd: jmp $0000 +IRQInd: .res 3 + +.end From a104c289dab24d7ba0eee0290151920ebac38f16 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 4 Sep 2018 11:32:40 +0200 Subject: [PATCH 0838/2161] Atari: atari-cart.cfg: There's a simpler way to discard the contents of the LOWBSS segment. Thanks to Greg King for the hint. --- cfg/atari-cart.cfg | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/cfg/atari-cart.cfg b/cfg/atari-cart.cfg index 16208f90d..e903d4d74 100644 --- a/cfg/atari-cart.cfg +++ b/cfg/atari-cart.cfg @@ -10,25 +10,24 @@ SYMBOLS { __CARTFLAGS__: type = weak, value = $01; # see documentation for other possible values } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; - MAIN: file = "", define = yes, start = %S, size = __CARTSIZE__; - ROM: file = %O, define = yes, start = $C000 - __CARTSIZE__, size = __CARTSIZE__ - 6, fill = yes, fillval = $FF; - CARTID: file = %O, start = $BFFA, size = $0006; - DISCARD: file = "", start = $0100, size = $FF00; + ZP: file = "", define = yes, start = $0082, size = $007E; + MAIN: file = "", define = yes, start = %S, size = __CARTSIZE__; + ROM: file = %O, define = yes, start = $C000 - __CARTSIZE__, size = __CARTSIZE__ - 6, fill = yes, fillval = $FF; + CARTID: file = %O, start = $BFFA, size = $0006; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp, optional = yes; - EXTZP: load = ZP, type = zp, optional = yes; - STARTUP: load = ROM, type = ro, define = yes, optional = yes; - LOWBSS: load = DISCARD, run = MAIN, type = rw, optional = yes; # not zero-initialized - LOWCODE: load = ROM, type = ro, define = yes, optional = yes; - ONCE: load = ROM, type = ro, optional = yes; - CODE: load = ROM, type = ro, define = yes; - RODATA: load = ROM, type = ro, optional = yes; - DATA: load = ROM, run = MAIN, type = rw, define = yes, optional = yes; - INIT: load = MAIN, type = bss, optional = yes; - BSS: load = MAIN, type = bss, define = yes, optional = yes; - CARTHDR: load = CARTID, type = ro; + ZEROPAGE: load = ZP, type = zp, optional = yes; + EXTZP: load = ZP, type = zp, optional = yes; + STARTUP: load = ROM, type = ro, define = yes, optional = yes; + LOWBSS: load = MAIN, type = bss, optional = yes; # not zero initialized + LOWCODE: load = ROM, type = ro, define = yes, optional = yes; + ONCE: load = ROM, type = ro, optional = yes; + CODE: load = ROM, type = ro, define = yes; + RODATA: load = ROM, type = ro, optional = yes; + DATA: load = ROM, run = MAIN, type = rw, define = yes, optional = yes; + INIT: load = MAIN, type = bss, optional = yes; + BSS: load = MAIN, type = bss, define = yes, optional = yes; + CARTHDR: load = CARTID, type = ro; } FEATURES { CONDES: type = constructor, From af50b5e5162432506e649726efe1c2d000cc2263 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 4 Sep 2018 11:44:04 +0200 Subject: [PATCH 0839/2161] Atari: atarixl config files already had a LOWBSS segment. --- cfg/atari-cassette.cfg | 2 +- cfg/atari-overlay.cfg | 2 +- cfg/atari.cfg | 2 +- cfg/atarixl-largehimem.cfg | 1 - cfg/atarixl-overlay.cfg | 1 - cfg/atarixl.cfg | 1 - 6 files changed, 3 insertions(+), 6 deletions(-) diff --git a/cfg/atari-cassette.cfg b/cfg/atari-cassette.cfg index 465add95e..13b34cc73 100644 --- a/cfg/atari-cassette.cfg +++ b/cfg/atari-cassette.cfg @@ -16,7 +16,7 @@ SEGMENTS { EXTZP: load = ZP, type = zp, optional = yes; CASHDR: load = MAIN, type = ro; STARTUP: load = MAIN, type = ro, define = yes, optional = yes; - LOWBSS: load = MAIN, type = rw, optional = yes; # not zero-initialized + LOWBSS: load = MAIN, type = rw, optional = yes; # not zero initialized LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro, define = yes; diff --git a/cfg/atari-overlay.cfg b/cfg/atari-overlay.cfg index fdf2e983c..9311a1b22 100644 --- a/cfg/atari-overlay.cfg +++ b/cfg/atari-overlay.cfg @@ -46,7 +46,7 @@ SEGMENTS { SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes; MAINHDR: load = MAINHDR, type = ro; STARTUP: load = MAIN, type = ro, define = yes; - LOWBSS: load = MAIN, type = rw, optional = yes; # not zero-initialized + LOWBSS: load = MAIN, type = rw, optional = yes; # not zero initialized LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro, define = yes; diff --git a/cfg/atari.cfg b/cfg/atari.cfg index 9e0ea474f..106c75e63 100644 --- a/cfg/atari.cfg +++ b/cfg/atari.cfg @@ -34,7 +34,7 @@ SEGMENTS { SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes; MAINHDR: load = MAINHDR, type = ro; STARTUP: load = MAIN, type = ro, define = yes; - LOWBSS: load = MAIN, type = rw, optional = yes; # not zero-initialized + LOWBSS: load = MAIN, type = rw, optional = yes; # not zero initialized LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro, define = yes; diff --git a/cfg/atarixl-largehimem.cfg b/cfg/atarixl-largehimem.cfg index 842a485a1..56d2af15b 100644 --- a/cfg/atarixl-largehimem.cfg +++ b/cfg/atarixl-largehimem.cfg @@ -61,7 +61,6 @@ SEGMENTS { MAINHDR: load = MAINHDR, type = ro; STARTUP: load = MAIN, type = ro, define = yes; - LOWBSS: load = MAIN, type = rw, optional = yes; # not zero-initialized LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro, define = yes; diff --git a/cfg/atarixl-overlay.cfg b/cfg/atarixl-overlay.cfg index f3a40b6a7..923436497 100644 --- a/cfg/atarixl-overlay.cfg +++ b/cfg/atarixl-overlay.cfg @@ -72,7 +72,6 @@ SEGMENTS { MAINHDR: load = MAINHDR, type = ro; STARTUP: load = MAIN, type = ro, define = yes; - LOWBSS: load = MAIN, type = rw, optional = yes; # not zero-initialized LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro, define = yes; diff --git a/cfg/atarixl.cfg b/cfg/atarixl.cfg index c2d331fab..197daace6 100644 --- a/cfg/atarixl.cfg +++ b/cfg/atarixl.cfg @@ -59,7 +59,6 @@ SEGMENTS { MAINHDR: load = MAINHDR, type = ro; STARTUP: load = MAIN, type = ro, define = yes; - LOWBSS: load = MAIN, type = rw, optional = yes; # not zero-initialized LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; ONCE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro, define = yes; From c7bb27bac9ee3a55d08692f250ab3763fc0b1dca Mon Sep 17 00:00:00 2001 From: Laubzega <mileksmyk@gmail.com> Date: Thu, 6 Sep 2018 00:18:39 -0700 Subject: [PATCH 0840/2161] Rename more stuff from "overlay" to "replace". --- src/ld65/bin.c | 2 +- src/ld65/config.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ld65/bin.c b/src/ld65/bin.c index c94ac9319..6f0e4ab36 100644 --- a/src/ld65/bin.c +++ b/src/ld65/bin.c @@ -193,7 +193,7 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M) NewAddr += M->Start; } if (DoWrite || (M->Flags & MF_FILL) != 0) { - /* Seek in "overlay" segments */ + /* Seek in "replace" segments */ if (S->Flags & SF_REPLACE) { fseek (D->F, NewAddr - M->Start, SEEK_SET); } else { diff --git a/src/ld65/config.c b/src/ld65/config.c index 5c61bdd3f..0e4d0c1e4 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -1797,7 +1797,7 @@ unsigned CfgProcess (void) for (I = 0; I < CollCount (&MemoryAreas); ++I) { unsigned J; unsigned long Addr; - unsigned Overlays = 0; + unsigned Replaces = 0; /* Get the next memory area */ MemoryArea* M = CollAtUnchecked (&MemoryAreas, I); @@ -1851,23 +1851,23 @@ unsigned CfgProcess (void) /* Remember the start address before handling this segment */ unsigned long StartAddr = Addr; - /* Take note of overlayed segments and make sure there are no other + /* Take note of "replace" segments and make sure there are no other ** segment types following them in current memory region. */ if (S->Flags & SF_REPLACE) { if (S->Flags & (SF_OFFSET | SF_START)) { - ++Overlays; + ++Replaces; } else { CfgError (GetSourcePos (M->LI), - "Segment `%s' of type `overlay' requires either" + "Segment `%s' of type `replace' requires either" " `Start' or `Offset' attribute to be specified", GetString (S->Name)); } } else { - if (Overlays > 0) { + if (Replaces > 0) { CfgError (GetSourcePos (M->LI), "Segment `%s' is preceded by at least one segment" - " of type `overlay'", + " of type `replace'", GetString (S->Name)); } } From e9b8f5d814a7ce103f60c06482f3e875e74fee3c Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 6 Sep 2018 01:10:47 +0200 Subject: [PATCH 0841/2161] Atari: Add detection of RealDOS (http://www.realdos.net/realdos.html). --- asminc/atari.inc | 7 ++++--- include/atari.h | 19 ++++--------------- libsrc/atari/dosdetect.s | 5 +++++ 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/asminc/atari.inc b/asminc/atari.inc index 1b995e380..7b16b528f 100644 --- a/asminc/atari.inc +++ b/asminc/atari.inc @@ -1005,12 +1005,13 @@ diopp_size = 5 ; size of structure SPARTADOS = 0 OSADOS = 1 ; OS/A+ XDOS = 2 -ATARIDOS = 3 -MYDOS = 4 +REALDOS = 3 +ATARIDOS = 4 +MYDOS = 5 NODOS = 255 ; The DOSes with dos_type below or equal MAX_DOS_WITH_CMDLINE do support ; command line arguments. -MAX_DOS_WITH_CMDLINE = XDOS +MAX_DOS_WITH_CMDLINE = REALDOS ;------------------------------------------------------------------------- ; XDOS defines (version 2.4, taken from xdos24.pdf) diff --git a/include/atari.h b/include/atari.h index 4bed8d7a7..d9463904c 100644 --- a/include/atari.h +++ b/include/atari.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2000-2006 Mark Keates <markk@dendrite.co.uk> */ +/* (C) 2000-2018 Mark Keates <markk@dendrite.co.uk> */ /* Freddy Offenga <taf_offenga@yahoo.com> */ /* Christian Groessler <chris@groessler.org> */ /* */ @@ -232,18 +232,6 @@ extern void atrx15_tgi[]; extern void atrx15p2_tgi[]; #endif -/* provide old names for backwards compatibility */ -#ifdef ATARI_COMPAT_PRE_2_11 -#define setcolor _setcolor -#define setcolor_low _setcolor_low -#define getcolor _getcolor -#define graphics _graphics -#define scroll _scroll -#define save_vecs _save_vecs -#define rest_vecs _rest_vecs -#define getdefdev _getdefdev -#endif /* #ifdef ATARI_COMPAT_PRE_2_11 */ - /* get_ostype return value defines (for explanation, see ostype.s) */ /* masks */ #define AT_OS_TYPE_MAIN 7 @@ -275,8 +263,9 @@ extern void atrx15p2_tgi[]; #define SPARTADOS 0 #define OSADOS 1 #define XDOS 2 -#define ATARIDOS 3 -#define MYDOS 4 +#define REALDOS 3 +#define ATARIDOS 4 +#define MYDOS 5 #define NODOS 255 /* Define hardware */ diff --git a/libsrc/atari/dosdetect.s b/libsrc/atari/dosdetect.s index 68f4aefb2..7e6088d97 100644 --- a/libsrc/atari/dosdetect.s +++ b/libsrc/atari/dosdetect.s @@ -20,6 +20,8 @@ detect: lda DOS beq mydos cmp #'X' ; XDOS beq xdos + cmp #'R' ; RealDOS + beq rdos lda #$4C ; probably default ldy #COMTAB @@ -41,6 +43,9 @@ spdos: lda #SPARTADOS mydos: lda #MYDOS .byte $2C ; BIT <abs> +rdos: lda #REALDOS + .byte $2C ; BIT <abs> + xdos: lda #XDOS sta __dos_type done: rts From b6ccd4d5d44d6f2a19f625d466f291d2ae833430 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 6 Sep 2018 15:55:07 +0200 Subject: [PATCH 0842/2161] Atari: RealDOS adaptations RealDOS is a SpartaDOS clone. Handle it the same way as SpartaDOS. --- libsrc/atari/lseek.s | 6 ++++-- libsrc/atari/syschdir.s | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libsrc/atari/lseek.s b/libsrc/atari/lseek.s index 889976f5b..462f2f90b 100644 --- a/libsrc/atari/lseek.s +++ b/libsrc/atari/lseek.s @@ -176,7 +176,7 @@ seek: jsr ldax0sp ; get lower word of new offset .endproc -; check, whether seeking is supported +; check whether seeking is supported ; tmp3: iocb ; X: index into fd_table ; @@ -194,8 +194,10 @@ chk_supp: ; do the test lda __dos_type cmp #SPARTADOS + beq :+ + cmp #REALDOS bne ns1 - txa +: txa pha lda DOS+1 ; get SpartaDOS version cmp #$40 diff --git a/libsrc/atari/syschdir.s b/libsrc/atari/syschdir.s index d57708384..9e4c33a19 100644 --- a/libsrc/atari/syschdir.s +++ b/libsrc/atari/syschdir.s @@ -3,7 +3,7 @@ ; Based on on code by Christian Groessler ; ; unsigned char __fastcall__ _syschdir (const char* name); -; for SpartaDOS and MyDOS +; for SpartaDOS, RealDOS, and MyDOS ; .include "atari.inc" @@ -65,6 +65,8 @@ ucok1: lda __dos_type cmp #SPARTADOS beq :+ + cmp #REALDOS + beq :+ lda #CHDIR_MYDOS .byte $2C ; BIT <abs> : lda #CHDIR_SPDOS From 73faf60fe0eff3a7e0cc1f074cecbe5f4c658426 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 8 Sep 2018 18:44:30 +0200 Subject: [PATCH 0843/2161] Support randomize(). In order to have randomize() work as expected (and the Apple II random number generation in general) it is necessary to update the random counter during keypress wait just like the ROM function does. --- libsrc/apple2/cgetc.s | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libsrc/apple2/cgetc.s b/libsrc/apple2/cgetc.s index b1bda8b91..ecce9f9de 100644 --- a/libsrc/apple2/cgetc.s +++ b/libsrc/apple2/cgetc.s @@ -25,8 +25,11 @@ _cgetc: jsr putchardirect ; Returns old character in X ; Wait for keyboard strobe. +: inc RNDL ; Increment random counter low + bne :+ + inc RNDH ; Increment random counter high : lda KBD - bpl :- ; If < 128, no key pressed + bpl :-- ; If < 128, no key pressed ; Cursor on ? ldy cursor From cddc4da3bb2439bef057a3b2217636d7edaf70cf Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 8 Sep 2018 23:14:54 +0200 Subject: [PATCH 0844/2161] Just removed some trailing spaces. --- libsrc/apple2/diocommon.s | 2 +- libsrc/apple2/initcwd.s | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/apple2/diocommon.s b/libsrc/apple2/diocommon.s index 4e8d76147..92d274ea8 100644 --- a/libsrc/apple2/diocommon.s +++ b/libsrc/apple2/diocommon.s @@ -26,7 +26,7 @@ dioprolog: diocommon: ; Call read_block or write_block ldx #RW_BLOCK_COUNT - jsr callmli + jsr callmli dioepilog: ; Return success or error diff --git a/libsrc/apple2/initcwd.s b/libsrc/apple2/initcwd.s index 7af29c75e..7a12bc52a 100644 --- a/libsrc/apple2/initcwd.s +++ b/libsrc/apple2/initcwd.s @@ -37,5 +37,5 @@ initcwd: ; Add terminating zero lda #$00 sta __cwd,x - + done: rts From a9a102b0e8fe5854b8e84769f81d15c270aea3d0 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 8 Sep 2018 23:29:59 +0200 Subject: [PATCH 0845/2161] Protect random counter against ProDOS. Although documented nowhere (!!!) ProDOS trashes the random counter locations $4E/$4F. Is discovered this because my TCP connections didn't have random local ports. It's a really funny coincidence that David Finnigan discovered only 3 years ago the very same issue because of the very same reason: https://groups.google.com/forum/#!topic/comp.sys.apple2.programmer/1ciep_Oetvo --- libsrc/apple2/mli.s | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/libsrc/apple2/mli.s b/libsrc/apple2/mli.s index 3e4771400..891cbaa6b 100644 --- a/libsrc/apple2/mli.s +++ b/libsrc/apple2/mli.s @@ -6,6 +6,7 @@ .import __dos_type + .include "apple2.inc" .include "mli.inc" .bss @@ -23,10 +24,24 @@ callmli: lda __dos_type beq oserr - ; Call MLI and return + ; Save random counter + lda RNDL + pha + lda RNDH + pha + + ; Call MLI jsr $BF00 ; MLI call entry point call: .byte $00 .addr mliparam + + ; Restore random counter and return + tax + pla + sta RNDH + pla + sta RNDL + txa rts ; Load oserror code and return From c7a40db1b7460bf5c862a43feaf2742ca7cb68f2 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 8 Sep 2018 23:59:39 +0200 Subject: [PATCH 0846/2161] Added hint random number generator hint. --- doc/apple2.sgml | 14 +++++++++++++- doc/apple2enh.sgml | 14 +++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index eef0eed3d..405f2ccbd 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -455,7 +455,7 @@ BASIC.SYSTEM) there are some limitations for DOS 3.3: <descrip> - <tag>Disk File I/O</tag> + <tag>Disk file I/O</tag> There's no disk file I/O support. Any attempt to use it yields an error with <tt/errno/ set to <tt/ENOSYS/. This implicitly means that loadable drivers are in general not functional as they depend on disk file I/O. Therefore the statically @@ -480,6 +480,18 @@ BASIC.SYSTEM) there are some limitations for DOS 3.3: </descrip><p> +<sect1>Random number generator<p> + +<descrip> + + <tag/Random number seed/ + The random number seed is generated from the time the program waits for user input. + Therefore it is necessary to wait for at least one user keypress either via Standard + I/O or via Direct console I/O before initializing the pseudo random number generator. + +</descrip><p> + + <sect>Other hints<p> diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index b40523aba..501abde61 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -456,7 +456,7 @@ BASIC.SYSTEM) there are some limitations for DOS 3.3: <descrip> - <tag>Disk File I/O</tag> + <tag>Disk file I/O</tag> There's no disk file I/O support. Any attempt to use it yields an error with <tt/errno/ set to <tt/ENOSYS/. This implicitly means that loadable drivers are in general not functional as they depend on disk file I/O. Therefore the statically @@ -481,6 +481,18 @@ BASIC.SYSTEM) there are some limitations for DOS 3.3: </descrip><p> +<sect1>Random number generator<p> + +<descrip> + + <tag/Random number seed/ + The random number seed is generated from the time the program waits for user input. + Therefore it is necessary to wait for at least one user keypress either via Standard + I/O or via Direct console I/O before initializing the pseudo random number generator. + +</descrip><p> + + <sect>Other hints<p> From d293d766ef39363891d174cd8a6b6647e18bfb5d Mon Sep 17 00:00:00 2001 From: Laubzega <mileksmyk@gmail.com> Date: Sat, 8 Sep 2018 19:18:41 -0700 Subject: [PATCH 0847/2161] New segment type renamed to "overwrite". --- src/ld65/bin.c | 4 ++-- src/ld65/config.c | 32 ++++++++++++++++---------------- src/ld65/config.h | 2 +- src/ld65/scanner.h | 2 +- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/ld65/bin.c b/src/ld65/bin.c index 6f0e4ab36..a77d49679 100644 --- a/src/ld65/bin.c +++ b/src/ld65/bin.c @@ -193,8 +193,8 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M) NewAddr += M->Start; } if (DoWrite || (M->Flags & MF_FILL) != 0) { - /* Seek in "replace" segments */ - if (S->Flags & SF_REPLACE) { + /* Seek in "overwrite" segments */ + if (S->Flags & SF_OVERWRITE) { fseek (D->F, NewAddr - M->Start, SEEK_SET); } else { WriteMult (D->F, M->FillVal, NewAddr-Addr); diff --git a/src/ld65/config.c b/src/ld65/config.c index 0e4d0c1e4..73eee1caa 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -653,7 +653,7 @@ static void ParseSegments (void) { "RW", CFGTOK_RW }, { "BSS", CFGTOK_BSS }, { "ZP", CFGTOK_ZP }, - { "REPLACE", CFGTOK_REPLACE }, + { "OVERWRITE", CFGTOK_OVERWRITE }, }; unsigned Count; @@ -754,12 +754,12 @@ static void ParseSegments (void) FlagAttr (&S->Attr, SA_TYPE, "TYPE"); CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type"); switch (CfgTok) { - case CFGTOK_RO: S->Flags |= SF_RO; break; - case CFGTOK_RW: /* Default */ break; - case CFGTOK_BSS: S->Flags |= SF_BSS; break; - case CFGTOK_ZP: S->Flags |= (SF_BSS | SF_ZP); break; - case CFGTOK_REPLACE: S->Flags |= (SF_REPLACE | SF_RO); break; - default: Internal ("Unexpected token: %d", CfgTok); + case CFGTOK_RO: S->Flags |= SF_RO; break; + case CFGTOK_RW: /* Default */ break; + case CFGTOK_BSS: S->Flags |= SF_BSS; break; + case CFGTOK_ZP: S->Flags |= (SF_BSS | SF_ZP); break; + case CFGTOK_OVERWRITE: S->Flags |= (SF_OVERWRITE | SF_RO); break; + default: Internal ("Unexpected token: %d", CfgTok); } CfgNextTok (); break; @@ -1797,7 +1797,7 @@ unsigned CfgProcess (void) for (I = 0; I < CollCount (&MemoryAreas); ++I) { unsigned J; unsigned long Addr; - unsigned Replaces = 0; + unsigned Overwrites = 0; /* Get the next memory area */ MemoryArea* M = CollAtUnchecked (&MemoryAreas, I); @@ -1851,23 +1851,23 @@ unsigned CfgProcess (void) /* Remember the start address before handling this segment */ unsigned long StartAddr = Addr; - /* Take note of "replace" segments and make sure there are no other - ** segment types following them in current memory region. + /* Take note of "overwrite" segments and make sure there are no + ** other segment types following them in current memory region. */ - if (S->Flags & SF_REPLACE) { + if (S->Flags & SF_OVERWRITE) { if (S->Flags & (SF_OFFSET | SF_START)) { - ++Replaces; + ++Overwrites; } else { CfgError (GetSourcePos (M->LI), - "Segment `%s' of type `replace' requires either" + "Segment `%s' of type `overwrite' requires either" " `Start' or `Offset' attribute to be specified", GetString (S->Name)); } } else { - if (Replaces > 0) { + if (Overwrites > 0) { CfgError (GetSourcePos (M->LI), "Segment `%s' is preceded by at least one segment" - " of type `replace'", + " of type `overwrite'", GetString (S->Name)); } } @@ -1921,7 +1921,7 @@ unsigned CfgProcess (void) NewAddr += M->Start; } - if (S->Flags & SF_REPLACE) { + if (S->Flags & SF_OVERWRITE) { if (NewAddr < M->Start) { CfgError (GetSourcePos (S->LI), "Segment `%s' begins before memory area `%s'", diff --git a/src/ld65/config.h b/src/ld65/config.h index d172560bd..d97675b21 100644 --- a/src/ld65/config.h +++ b/src/ld65/config.h @@ -96,7 +96,7 @@ struct SegDesc { #define SF_RUN_DEF 0x0200 /* RUN symbols already defined */ #define SF_LOAD_DEF 0x0400 /* LOAD symbols already defined */ #define SF_FILLVAL 0x0800 /* Segment has separate fill value */ -#define SF_REPLACE 0x1000 /* Segment can replace (part of) another one */ +#define SF_OVERWRITE 0x1000 /* Segment can overwrite (part of) another one */ diff --git a/src/ld65/scanner.h b/src/ld65/scanner.h index 2c60da975..2df952ebb 100644 --- a/src/ld65/scanner.h +++ b/src/ld65/scanner.h @@ -105,7 +105,7 @@ typedef enum { CFGTOK_RW, CFGTOK_BSS, CFGTOK_ZP, - CFGTOK_REPLACE, + CFGTOK_OVERWRITE, CFGTOK_O65, CFGTOK_BIN, From 1646acb26fef184992b653d835c03eef4a6be7d2 Mon Sep 17 00:00:00 2001 From: Laubzega <mileksmyk@gmail.com> Date: Sat, 8 Sep 2018 19:20:01 -0700 Subject: [PATCH 0848/2161] First cut of "overwrite" segment docs. --- doc/ld65.sgml | 60 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 8f9dd7093..48821797a 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -512,13 +512,15 @@ What we are doing here is telling the linker, that all segments go into the the linker will first write the <tt/CODE/ segment, then the <tt/RODATA/ segment, then the <tt/DATA/ segment - but it will not write the <tt/BSS/ segment. Why? Here enters the segment type: For each segment specified, you may also -specify a segment attribute. There are four possible segment attributes: +specify a segment attribute. There are five possible segment attributes: <tscreen><verb> - ro means readonly - rw means read/write - bss means that this is an uninitialized segment - zp a zeropage segment + ro means readonly + rw means read/write + bss means that this is an uninitialized segment + zp a zeropage segment + overwrite a segment that overwrites another one + </verb></tscreen> So, because we specified that the segment with the name BSS is of type bss, @@ -618,6 +620,54 @@ the command line, with "-1.bin" and "-2.bin" appended respectively. Because '%' is used as an escape char, the sequence "%%" has to be used if a single percent sign is required. +<sect1>OVERWRITE segments<p> + +There are situations when you may wish to overwrite some part (or parts) of a +segment with another one. Perhaps you are modifying an OS ROM that has its +public subroutines at fixed, well-known addresses, and you want to prevent them +from shifting to other locations in memory if your changed code takes less +space. Or you are updating a block of code available in binary-only form with +fixes that are scattered in various places. Generally, whenever you want to +minimize disturbance to an existing code brought on by your updates, OVERWRITE +segments are worth considering. + +Here is an example: + +<tscreen><verb> +MEMORY { + RAM: file = "", start = $6000, size = $2000, type=bss; + ROM: file = %O, start = $8000, size = $8000, type=ro; +} +</verb></tscreen> + +Nothing unusual so far, just two memory blocks - one RAM, one ROM. Now let's +look at the segment configuration: + +<tscreen><verb> +SEGMENTS { + RAM: load = RAM, type = bss; + ORIGINAL: load = ROM, type = ro; + FASTCOPY: load = ROM, start=$9000, type = overwrite; + JMPPATCH1: load = ROM, start=$f7e8, type = overwrite; + DEBUG: load = ROM, start=$8000, type = overwrite; + VERSION: load = ROM, start=$e5b7, type = overwrite; +} +</verb></tscreen> + +Segment named ORIGINAL contains the original code, disassembled or provided in +a binary form. Subsequent four segments will be relocated to addresses +specified by their "start" attributes ("offset" can also be used) and then will +overwrite whatever was at these locations in the ORIGINAL segment. In the end, +resulting binary output file will thus contain original data with the exception +of four sequences starting at $9000, $f7e8, $8000 and $e5b7, which will sport +code from their respective segments. How long these sequences will be depends +on the lengths of corresponding segments - they can even overlap, so think what +you're doing. + +Finally, note that OVERWRITE segments should be the final segments loaded to a +particular memory area, and that they need at least one of "start" or "offset" +attributes specified. + <sect1>LOAD and RUN addresses (ROMable code)<p> Let us look now at a more complex example. Say, you've successfully tested From e4e3dbf756933141f5991fbecaed43212f57d8d8 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 12 Sep 2018 01:05:52 +0200 Subject: [PATCH 0849/2161] atarixl: check at startup whether RAM beneath the ROM is in use If detected, the program refuses to run, preventing a crash. The check only works with SpartaDOS. I don't have an overview which DOSes potentially use the RAM under the ROM. Or which other installed programs might use it. No additional runtime memory space is consumed, since the change is in the "system check" load chunk which gets replaced by the user program during loading. --- libsrc/atari/system_check.s | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/libsrc/atari/system_check.s b/libsrc/atari/system_check.s index 2f1feefc4..df55f3d13 100644 --- a/libsrc/atari/system_check.s +++ b/libsrc/atari/system_check.s @@ -68,8 +68,32 @@ cont: ldx #0 ; channel 0 .segment "SYSCHK" + rts ; for older DOSes which unconditionally run the first load chunk + .ifdef __ATARIXL__ +; check for SpartaDOS and its usage of RAM below ROM +; return CF 0/1 for bad/ok +sdcheck:lda DOS + cmp #'S' + bne sdcrts0 ; not SpartaDOS, assume RAM is not used + lda DOS+1 ; SD version + cmp #$40 ; SD-X has $40 or higher + bcc sdcrts1 ; older versions (except maybe 1.x) always use the RAM under the ROM + ldy #31 ; offset for OSRMFLG + lda (DOSVEC),y ; get OSRMFLG + bne sdcrts1 + +sdcrts0:clc + rts +sdcrts1:sec + rts + +ramrom_txt: + .byte "Memory under ROM is in use.", ATEOL + .byte "Cannot run this program.", ATEOL +ramrom_txt_len = * - ramrom_txt + lmemerrxl_txt: .byte "Not enough memory to move screen", ATEOL .byte "memory to low memory. Consider using", ATEOL @@ -94,8 +118,13 @@ syschk: lda $fcd8 ; from ostype.s jmp mem_err -sys_ok: - .include "xlmemchk.inc" ; calculate lowest address we will use when we move the screen buffer down +sys_ok: jsr sdcheck ; check for SpartaDOS-X, and if found, whether it uses the RAM under the ROM + bcc sd_ok + + print_string2 ramrom_txt, ramrom_txt_len + jmp fail + +sd_ok: .include "xlmemchk.inc" ; calculate lowest address we will use when we move the screen buffer down lda MEMLO cmp lowadr From 08d164a8110af60ff8b1eb30f4fe9e299de8c77a Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 12 Sep 2018 01:20:12 +0200 Subject: [PATCH 0850/2161] fix comment in last change --- libsrc/atari/system_check.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/atari/system_check.s b/libsrc/atari/system_check.s index df55f3d13..ec0d60513 100644 --- a/libsrc/atari/system_check.s +++ b/libsrc/atari/system_check.s @@ -73,7 +73,7 @@ cont: ldx #0 ; channel 0 .ifdef __ATARIXL__ ; check for SpartaDOS and its usage of RAM below ROM -; return CF 0/1 for bad/ok +; return CF 0/1 for ok/bad sdcheck:lda DOS cmp #'S' bne sdcrts0 ; not SpartaDOS, assume RAM is not used From 3432788763595512d0c864ba5fc4c8d143c5eb3f Mon Sep 17 00:00:00 2001 From: Laubzega <mileksmyk@gmail.com> Date: Tue, 11 Sep 2018 22:14:45 -0700 Subject: [PATCH 0851/2161] Slight fixes to the documentation. --- doc/ld65.sgml | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 48821797a..17f4378b7 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -519,7 +519,7 @@ specify a segment attribute. There are five possible segment attributes: rw means read/write bss means that this is an uninitialized segment zp a zeropage segment - overwrite a segment that overwrites another one + overwrite a segment that overwrites (parts of) another one </verb></tscreen> @@ -635,8 +635,8 @@ Here is an example: <tscreen><verb> MEMORY { - RAM: file = "", start = $6000, size = $2000, type=bss; - ROM: file = %O, start = $8000, size = $8000, type=ro; + RAM: file = "", start = $6000, size = $2000, type=rw; + ROM: file = %O, start = $8000, size = $8000, type=ro; } </verb></tscreen> @@ -655,14 +655,15 @@ SEGMENTS { </verb></tscreen> Segment named ORIGINAL contains the original code, disassembled or provided in -a binary form. Subsequent four segments will be relocated to addresses -specified by their "start" attributes ("offset" can also be used) and then will -overwrite whatever was at these locations in the ORIGINAL segment. In the end, -resulting binary output file will thus contain original data with the exception -of four sequences starting at $9000, $f7e8, $8000 and $e5b7, which will sport -code from their respective segments. How long these sequences will be depends -on the lengths of corresponding segments - they can even overlap, so think what -you're doing. +a binary form (i.e. using <tt><ref id=".INCBIN" name=".incbin"></tt> +directive). Subsequent four segments will be relocated to addresses specified +by their "start" attributes ("offset" can also be used) and then will overwrite +whatever was at these locations in the ORIGINAL segment. In the end, resulting +binary output file will thus contain original data with the exception of four +sequences starting at $9000, $f7e8, $8000 and $e5b7, which will sport code from +their respective segments. How long these sequences will be depends on the +lengths of corresponding segments - they can even overlap, so think what you're +doing. Finally, note that OVERWRITE segments should be the final segments loaded to a particular memory area, and that they need at least one of "start" or "offset" From 3bace79604146af289ab96da3337c8dc854e7fb6 Mon Sep 17 00:00:00 2001 From: Laubzega <mileksmyk@gmail.com> Date: Wed, 12 Sep 2018 23:51:38 -0700 Subject: [PATCH 0852/2161] Fixed reference link. --- doc/ld65.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 17f4378b7..f4cbebbe9 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -655,8 +655,8 @@ SEGMENTS { </verb></tscreen> Segment named ORIGINAL contains the original code, disassembled or provided in -a binary form (i.e. using <tt><ref id=".INCBIN" name=".incbin"></tt> -directive). Subsequent four segments will be relocated to addresses specified +a binary form (i.e. using <tt/.INCBIN/ directive; see the <tt/ca65/ assembler +document). Subsequent four segments will be relocated to addresses specified by their "start" attributes ("offset" can also be used) and then will overwrite whatever was at these locations in the ORIGINAL segment. In the end, resulting binary output file will thus contain original data with the exception of four From 4691974466ff8e28dc635b0d13b089a54fbfe6b4 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 13 Sep 2018 22:33:54 +0200 Subject: [PATCH 0853/2161] Atari: Make a good "default device" on AtariDOS (2.0 and 2.5) and MyDOS. The default device will be the one the program was loaded from instead of always D1:. --- asminc/atari.inc | 8 ++++---- libsrc/atari/getdefdev.s | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/asminc/atari.inc b/asminc/atari.inc index 7b16b528f..6b8c0dc30 100644 --- a/asminc/atari.inc +++ b/asminc/atari.inc @@ -1003,15 +1003,15 @@ diopp_size = 5 ; size of structure ;------------------------------------------------------------------------- SPARTADOS = 0 -OSADOS = 1 ; OS/A+ -XDOS = 2 -REALDOS = 3 +REALDOS = 1 +OSADOS = 2 ; OS/A+ +XDOS = 3 ATARIDOS = 4 MYDOS = 5 NODOS = 255 ; The DOSes with dos_type below or equal MAX_DOS_WITH_CMDLINE do support ; command line arguments. -MAX_DOS_WITH_CMDLINE = REALDOS +MAX_DOS_WITH_CMDLINE = XDOS ;------------------------------------------------------------------------- ; XDOS defines (version 2.4, taken from xdos24.pdf) diff --git a/libsrc/atari/getdefdev.s b/libsrc/atari/getdefdev.s index 480639b4a..cad768783 100644 --- a/libsrc/atari/getdefdev.s +++ b/libsrc/atari/getdefdev.s @@ -3,7 +3,11 @@ ; ; function to get default device: char *_getdefdev(void); ; -; SpartaDOS: +; AtariDOS/MyDOS: +; Default device number is derived from DUNIT. Therefore "default +; device" is the one the program was loaded from. +; +; SpartaDOS/RealDOS: ; the ZCRNAME routine is only used to get the default drive because ; ZCRNAME has two disadvantages: ; 1. It will convert D: into D1: instead of Dn: (n = default drive) @@ -30,7 +34,7 @@ __getdefdev: cmp #XDOS beq xdos ; only supported on XDOS ... ; cmp #OSADOS+1 ; (redundant: #OSADOS+1 = #XDOS) - bcs finish ; ... and on OS/A+ and SpartaDOS + bcs use_DUNIT ; ... and on OS/A+ and SpartaDOS ldy #BUFOFF lda #0 @@ -77,6 +81,17 @@ finish: lda #<__defdev ldx #>__defdev rts +; On AtariDOS or MyDOS, use the DUNIT variable to setuo the default +; device. The default device will then be the one the program was +; loaded from. + +use_DUNIT: + lda DUNIT + clc + adc #'0' + sta __defdev + 1 + bne finish ; jump always + ; XDOS default device retrieval xdos: From d52d986acaa9de1cadf357c010419eaddc302810 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Fri, 14 Sep 2018 16:54:20 +0200 Subject: [PATCH 0854/2161] libsrc/atari/getdefdev.s: small optimization and fix a typo --- libsrc/atari/getdefdev.s | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libsrc/atari/getdefdev.s b/libsrc/atari/getdefdev.s index cad768783..e1ec3f4c0 100644 --- a/libsrc/atari/getdefdev.s +++ b/libsrc/atari/getdefdev.s @@ -81,7 +81,7 @@ finish: lda #<__defdev ldx #>__defdev rts -; On AtariDOS or MyDOS, use the DUNIT variable to setuo the default +; On AtariDOS or MyDOS, use the DUNIT variable to setup the default ; device. The default device will then be the one the program was ; loaded from. @@ -89,8 +89,7 @@ use_DUNIT: lda DUNIT clc adc #'0' - sta __defdev + 1 - bne finish ; jump always + bne done ; jump always ; XDOS default device retrieval From aa219d1ec7ea7c2eedf7966f12bfd1c2f0a2a559 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 18 Sep 2018 23:37:25 +0200 Subject: [PATCH 0855/2161] The doc now lives in the 'master' branch of the 'doc' project. --- Makefile.travis | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.travis b/Makefile.travis index 4c0f688f8..71811eacb 100644 --- a/Makefile.travis +++ b/Makefile.travis @@ -10,8 +10,8 @@ GH_PATH = ../doc gh-pages: ifdef GH_TOKEN - @echo 'git clone --branch=gh-pages https://$$(GH_TOKEN)@github.com/cc65/doc.git $(GH_PATH)' - @git clone --branch=gh-pages https://$(GH_TOKEN)@github.com/cc65/doc.git $(GH_PATH) + @echo 'git clone https://$$(GH_TOKEN)@github.com/cc65/doc.git $(GH_PATH)' + @git clone https://$(GH_TOKEN)@github.com/cc65/doc.git $(GH_PATH) cd $(GH_PATH) && git config user.name "$(GH_NAME)" cd $(GH_PATH) && git config user.email "$(GH_MAIL)" cd $(GH_PATH) && git config push.default simple From b6e4add9b5beb78caab31fc6c24d711b46ee52f9 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 20 Sep 2018 12:21:58 +0200 Subject: [PATCH 0856/2161] Switch to https links. Most targets redirected to https anyway. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6704eec9b..7b3ea342e 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -[Windows Snapshot](http://sourceforge.net/projects/cc65/files/cc65-snapshot-win32.zip) +[Windows Snapshot](https://sourceforge.net/projects/cc65/files/cc65-snapshot-win32.zip) -[Documentation](http://cc65.github.io/doc) +[Documentation](https://cc65.github.io/doc) -[Wiki](http://github.com/cc65/wiki/wiki) +[Wiki](https://github.com/cc65/wiki/wiki) [![Build Status](https://api.travis-ci.org/cc65/cc65.svg?branch=master)](https://travis-ci.org/cc65/cc65/builds) From 6cce110345e87885e3ac0801affea63f1366b2d2 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 20 Sep 2018 12:42:15 +0200 Subject: [PATCH 0857/2161] Adjusted URL to use https (and removed obsolete dates). --- doc/apple2.sgml | 2 -- doc/apple2enh.sgml | 2 -- doc/ar65.sgml | 2 -- doc/atari.sgml | 2 -- doc/atari2600.sgml | 2 -- doc/atari5200.sgml | 2 -- doc/atmos.sgml | 2 -- doc/c128.sgml | 2 -- doc/c16.sgml | 2 -- doc/c64.sgml | 2 -- doc/ca65.sgml | 1 - doc/cbm510.sgml | 2 -- doc/cbm610.sgml | 2 -- doc/cc65-intern.sgml | 1 - doc/cc65.sgml | 1 - doc/chrcvt65.sgml | 1 - doc/cl65.sgml | 1 - doc/co65.sgml | 1 - doc/coding.sgml | 1 - doc/creativision.sgml | 2 -- doc/customizing.sgml | 1 - doc/da65.sgml | 1 - doc/debugging.sgml | 2 -- doc/dio.sgml | 1 - doc/funcref.sgml | 1 - doc/gamate.sgml | 2 -- doc/geos.sgml | 5 +---- doc/grc65.sgml | 6 ++---- doc/index.sgml | 3 +-- doc/intro.sgml | 2 -- doc/ld65.sgml | 1 - doc/library.sgml | 2 -- doc/lynx.sgml | 2 -- doc/nes.sgml | 2 -- doc/od65.sgml | 1 - doc/osi.sgml | 2 -- doc/pce.sgml | 2 -- doc/pet.sgml | 2 -- doc/plus4.sgml | 2 -- doc/sim65.sgml | 1 - doc/smc.sgml | 1 - doc/sp65.sgml | 1 - doc/supervision.sgml | 2 -- doc/telestrat.sgml | 3 --- doc/tgi.sgml | 1 - doc/using-make.sgml | 2 -- doc/vic20.sgml | 2 -- 47 files changed, 4 insertions(+), 82 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 405f2ccbd..aa3089957 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -1,10 +1,8 @@ <!doctype linuxdoc system> <article> - <title>Apple ][ specific information for cc65 <author><url url="mailto:ol.sc@web.de" name="Oliver Schmidt"> -<date>2014-04-10 <abstract> An overview over the Apple ][ runtime system as it is diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 501abde61..fbdba908b 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -1,10 +1,8 @@ <!doctype linuxdoc system> <article> - <title>Enhanced Apple //e specific information for cc65 <author><url url="mailto:ol.sc@web.de" name="Oliver Schmidt"> -<date>2014-04-10 <abstract> An overview over the enhanced Apple //e runtime system as it is diff --git a/doc/ar65.sgml b/doc/ar65.sgml index 2e01025ca..d5e91a3a3 100644 --- a/doc/ar65.sgml +++ b/doc/ar65.sgml @@ -1,10 +1,8 @@ <!doctype linuxdoc system> <article> - <title>ar65 Users Guide <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2017-05-28 <abstract> ar65 is an archiver for object files generated by ca65. It allows to create diff --git a/doc/atari.sgml b/doc/atari.sgml index 459e8e745..cb41e1105 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -1,12 +1,10 @@ <!doctype linuxdoc system> <article> - <title>Atari specific information for cc65 <author> <url url="mailto:shawnjefferson@24fightingchickens.com" name="Shawn Jefferson"> and<newline> <url url="mailto:chris@groessler.org" name="Christian Groessler"> -<date>2014-04-24 <abstract> An overview over the Atari runtime system as it is implemented for the cc65 C diff --git a/doc/atari2600.sgml b/doc/atari2600.sgml index ae1b6cb5c..797b1e8be 100644 --- a/doc/atari2600.sgml +++ b/doc/atari2600.sgml @@ -1,11 +1,9 @@ <!doctype linuxdoc system> <article> - <title>Atari 2600 specific information for cc65 <author> <url url="mailto:contact@florentflament.com" name="Florent Flament"><newline> -<date>2017-01-11 <abstract> An overview over the Atari 2600 runtime system as it is implemented diff --git a/doc/atari5200.sgml b/doc/atari5200.sgml index a19641fe7..e33c8a832 100644 --- a/doc/atari5200.sgml +++ b/doc/atari5200.sgml @@ -1,11 +1,9 @@ <!doctype linuxdoc system> <article> - <title>Atari 5200 specific information for cc65 <author> <url url="mailto:chris@groessler.org" name="Christian Groessler"><newline> -<date>2014-05-27 <abstract> An overview over the Atari 5200 runtime system as it is implemented for the diff --git a/doc/atmos.sgml b/doc/atmos.sgml index 9e61fbd1c..ab7104f9d 100644 --- a/doc/atmos.sgml +++ b/doc/atmos.sgml @@ -1,13 +1,11 @@ <!doctype linuxdoc system> <article> - <title>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:greg.king5@verizon.net" name="Greg King"> -<date>2015-01-09 <abstract> An overview over the Atmos runtime system as it is implemented for the cc65 C diff --git a/doc/c128.sgml b/doc/c128.sgml index 0094631ad..dd9af2d6b 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -1,11 +1,9 @@ <!doctype linuxdoc system> <article> - <title>Commodore 128-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"> -<date>2018-08-29 <abstract> An overview over the C128 runtime system as it is implemented for the cc65 C diff --git a/doc/c16.sgml b/doc/c16.sgml index aaf497d42..9f81c5115 100644 --- a/doc/c16.sgml +++ b/doc/c16.sgml @@ -1,10 +1,8 @@ <!doctype linuxdoc system> <article> - <title>Commodore 16/116 specific information for cc65 <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2014-04-10 <abstract> An overview over the C16 runtime system as it is implemented for the cc65 C diff --git a/doc/c64.sgml b/doc/c64.sgml index a0043d3ad..328a77ab6 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -1,11 +1,9 @@ <!doctype linuxdoc system> <article> - <title>Commodore 64-specific information for cc65 <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"><newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2018-05-14 <abstract> An overview over the C64 runtime system as it is implemented for the cc65 C diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 715ecd89e..fc32efa61 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -4,7 +4,6 @@ <title>ca65 Users Guide <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2016-06-11 <abstract> ca65 is a powerful macro assembler for the 6502, 65C02, and 65816 CPUs. It is diff --git a/doc/cbm510.sgml b/doc/cbm510.sgml index d38d35d29..5c7c0f767 100644 --- a/doc/cbm510.sgml +++ b/doc/cbm510.sgml @@ -1,13 +1,11 @@ <!doctype linuxdoc system> <article> - <title>Commodore 510 (aka P500) 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:greg.king5@verizon.net" name="Greg King"> -<date>2014-04-25 <abstract> An overview over the Commodore 510 runtime system as it is implemented for the diff --git a/doc/cbm610.sgml b/doc/cbm610.sgml index 44c9155a5..c1faefd51 100644 --- a/doc/cbm610.sgml +++ b/doc/cbm610.sgml @@ -1,12 +1,10 @@ <!doctype linuxdoc system> <article> - <title>Commodore 610-specific information for cc65 <author> <url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2014-04-25 <abstract> An overview over the Commodore 610 runtime system as it is implemented for the diff --git a/doc/cc65-intern.sgml b/doc/cc65-intern.sgml index 231c04544..ec6c48ca3 100644 --- a/doc/cc65-intern.sgml +++ b/doc/cc65-intern.sgml @@ -3,7 +3,6 @@ <article> <title>cc65 internals <author><url url="mailto:bbbradsmith@users.noreply.github.com" name="Brad Smith"> -<date>2016-02-27 <abstract> Internal details of cc65 code generation, diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 11a5937b2..a66854095 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -4,7 +4,6 @@ <title>cc65 Users Guide <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:gregdk@users.sf.net" name="Greg King"> -<date>2017-05-20 <abstract> cc65 is a C compiler for 6502 targets. It supports several 6502 based home diff --git a/doc/chrcvt65.sgml b/doc/chrcvt65.sgml index 0c5538426..0a2fc2f76 100644 --- a/doc/chrcvt65.sgml +++ b/doc/chrcvt65.sgml @@ -3,7 +3,6 @@ <article> <title>chrcvt65 Users Guide <author><url url="mailto:polluks@sdf.lonestar.org" name="Stefan A. Haubenthal"> -<date>2013-02-10 <abstract> chrcvt65 is the vector font converter. It is able to convert a foreign font into diff --git a/doc/cl65.sgml b/doc/cl65.sgml index ca5f9d2af..2a3e61828 100644 --- a/doc/cl65.sgml +++ b/doc/cl65.sgml @@ -4,7 +4,6 @@ <title>cl65 Users Guide <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2017-10-16 <abstract> cl65 is the compile & link utility for cc65, the 6502 C compiler. It was diff --git a/doc/co65.sgml b/doc/co65.sgml index 9d70ffe6a..06bdbe191 100644 --- a/doc/co65.sgml +++ b/doc/co65.sgml @@ -3,7 +3,6 @@ <article> <title>co65 Users Guide <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>12.02.2003 <abstract> co65 is an object file conversion utility. It converts o65 object files into diff --git a/doc/coding.sgml b/doc/coding.sgml index f6dfc3a35..5897837c4 100644 --- a/doc/coding.sgml +++ b/doc/coding.sgml @@ -3,7 +3,6 @@ <article> <title>cc65 coding hints <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2000-12-03, 2009-09-01 <abstract> How to generate the most effective code with cc65. diff --git a/doc/creativision.sgml b/doc/creativision.sgml index 29653ce0f..a701ae1ce 100644 --- a/doc/creativision.sgml +++ b/doc/creativision.sgml @@ -1,10 +1,8 @@ <!doctype linuxdoc system> <article> - <title>VTech Creativision (aka Funvision) specific information for cc65 <author><url url="mailto:polluks+cc65@sdf.lonestar.org" name="Stefan A. Haubenthal"> -<date>2017-11-15 <abstract> An overview over the Creativision runtime system as it is implemented for the diff --git a/doc/customizing.sgml b/doc/customizing.sgml index e502f2e9d..e18bcf86c 100644 --- a/doc/customizing.sgml +++ b/doc/customizing.sgml @@ -3,7 +3,6 @@ <article> <title>Defining a Custom cc65 Target <author>Bruce Reidenbach -<date>2015-03-13 <abstract> This section provides step-by-step instructions on how to use the cc65 diff --git a/doc/da65.sgml b/doc/da65.sgml index 05154ffd8..466b41984 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -5,7 +5,6 @@ <author> <url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2014-11-23 <abstract> da65 is a 6502/65C02 disassembler that is able to read user-supplied diff --git a/doc/debugging.sgml b/doc/debugging.sgml index c7c7792db..7f2c3af5a 100644 --- a/doc/debugging.sgml +++ b/doc/debugging.sgml @@ -1,10 +1,8 @@ <!doctype linuxdoc system> <article> - <title>Using emulators with cc65 <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2014-04-11 <abstract> How to debug your code using the VICE and Oricutron emulators. diff --git a/doc/dio.sgml b/doc/dio.sgml index 39aac251c..0aa43ec76 100644 --- a/doc/dio.sgml +++ b/doc/dio.sgml @@ -3,7 +3,6 @@ <article> <title>Diskette Sector I/O Routines <author><url url="mailto:chris@groessler.org" name="Christian Groessler"> -<date>2014-04-10 <abstract> The cc65 library provides functions to read and write raw disk sectors. diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 589fbb75d..1fa6558a7 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -4,7 +4,6 @@ <title>cc65 function reference <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2018-05-29 <abstract> cc65 is a C compiler for 6502 based systems. This function reference describes diff --git a/doc/gamate.sgml b/doc/gamate.sgml index 0948c20c4..1a2a73178 100644 --- a/doc/gamate.sgml +++ b/doc/gamate.sgml @@ -1,11 +1,9 @@ <!doctype linuxdoc system> <article> - <title>Gamate System specific information for cc65 <author> <url url="mailto:groepaz@gmx.net" name="Groepaz/Hitmen"> -<date>2015-11-29 <abstract> An overview over the Gamate runtime system as it is implemented for the diff --git a/doc/geos.sgml b/doc/geos.sgml index aa3725bdf..1f8868090 100644 --- a/doc/geos.sgml +++ b/doc/geos.sgml @@ -1,12 +1,9 @@ <!doctype linuxdoc system> <article> - -<!-- Title information --> - <title>GEOSLib docs <author><url url="mailto:ytm@elysium.pl" name="Maciej Witkowiak"> -<date>2014-04-11 + <abstract> This is the documentation of cc65's GEOSLib, but information contained here may be also useful for writing GEOS applications in general. diff --git a/doc/grc65.sgml b/doc/grc65.sgml index 1acc6b1f2..fb90fe23f 100644 --- a/doc/grc65.sgml +++ b/doc/grc65.sgml @@ -1,13 +1,11 @@ <!doctype linuxdoc system> + <article> - -<!-- Title information --> - <title>grc65 -- GEOS Resource Compiler <author> <url url="mailto:ytm@elysium.pl" name="Maciej 'YTM/Elysium' Witkowiak">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2014-04-24 + <abstract> This document describes a compiler that can create GEOS headers and menues for cc65-compiled programs. diff --git a/doc/index.sgml b/doc/index.sgml index e1ee064a8..aecfb7de9 100644 --- a/doc/index.sgml +++ b/doc/index.sgml @@ -2,8 +2,7 @@ <article> <title>cc65 Documentation Overview -<author><url url="http://cc65.github.io/doc"> -<date>2017-02-15 +<author><url url="https://cc65.github.io/doc"> <sect>Program documentation<p> diff --git a/doc/intro.sgml b/doc/intro.sgml index 47516e671..994d30bc0 100644 --- a/doc/intro.sgml +++ b/doc/intro.sgml @@ -1,14 +1,12 @@ <!doctype linuxdoc system> <article> - <title>cc65 Compiler Intro <author> <url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:cbmnut@hushmail.com" name="CbmNut">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King">,<newline> <url url="mailto:stephan.muehlstrasser@web.de" name="Stephan Mühlstrasser"> -<date>2015-03-07 <abstract> How to use the cc65 C language system -- an introduction. diff --git a/doc/ld65.sgml b/doc/ld65.sgml index f4cbebbe9..1750cb3e8 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -3,7 +3,6 @@ <article> <title>ld65 Users Guide <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2014-04-20 <abstract> The ld65 linker combines object files into an executable file. ld65 is highly diff --git a/doc/library.sgml b/doc/library.sgml index c36605844..b2f880051 100644 --- a/doc/library.sgml +++ b/doc/library.sgml @@ -1,10 +1,8 @@ <!doctype linuxdoc system> <article> - <title>cc65 Library Overview <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2018-02-28 <abstract> An overview over the runtime and C libraries that come with the cc65 compiler, diff --git a/doc/lynx.sgml b/doc/lynx.sgml index 73763f1dd..de9951b9a 100644 --- a/doc/lynx.sgml +++ b/doc/lynx.sgml @@ -1,12 +1,10 @@ <!doctype linuxdoc system> <article> - <title>Atari Lynx specific information for cc65 <author> <url url="mailto:karri@sipo.fi" name="Karri Kaksonen">,<newline> <url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2014-04-12 <abstract> An overview over the Atari Lynx runtime system as it is implemented for the diff --git a/doc/nes.sgml b/doc/nes.sgml index 8f4374e05..14fcac559 100644 --- a/doc/nes.sgml +++ b/doc/nes.sgml @@ -1,12 +1,10 @@ <!doctype linuxdoc system> <article> - <title>Nintendo Entertainment System 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"> -<date>2014-04-12 <abstract> An overview over the NES runtime system as it is implemented for the diff --git a/doc/od65.sgml b/doc/od65.sgml index f5611a889..aab7522d9 100644 --- a/doc/od65.sgml +++ b/doc/od65.sgml @@ -3,7 +3,6 @@ <article> <title>od65 Users Guide <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2014-04-14 <abstract> od65 is the object file dump utility. It is able to output most parts of diff --git a/doc/osi.sgml b/doc/osi.sgml index ab1b4cee5..081d7cfbb 100644 --- a/doc/osi.sgml +++ b/doc/osi.sgml @@ -1,12 +1,10 @@ <!doctype linuxdoc system> <article> - <title>Ohio Scientific-specific information for cc65 <author> <url url="mailto:stephan.muehlstrasser@web.de" name="Stephan Mühlstrasser">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2015-03-17 <abstract> An overview over the Ohio Scientific runtime system as it is implemented for the cc65 C diff --git a/doc/pce.sgml b/doc/pce.sgml index ee9c81a49..a1866b8f0 100644 --- a/doc/pce.sgml +++ b/doc/pce.sgml @@ -1,11 +1,9 @@ <!doctype linuxdoc system> <article> - <title>PC-Engine (TurboGrafx 16) System-specific information for cc65 <author><url url="mailto:groepaz@gmx.net" name="Groepaz/Hitmen">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> -<date>2018-02-24 <abstract> An overview over the PCE runtime system as it is implemented for the diff --git a/doc/pet.sgml b/doc/pet.sgml index fd61716dd..61d6eb7a7 100644 --- a/doc/pet.sgml +++ b/doc/pet.sgml @@ -1,12 +1,10 @@ <!doctype linuxdoc system> <article> - <title>Commodore PET-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"> -<date>2014-04-12 <abstract> An overview over the PET runtime system as it is implemented for the cc65 C diff --git a/doc/plus4.sgml b/doc/plus4.sgml index ed5fa3d4e..da9171a6f 100644 --- a/doc/plus4.sgml +++ b/doc/plus4.sgml @@ -1,10 +1,8 @@ <!doctype linuxdoc system> <article> - <title>Commodore Plus/4 specific information for cc65 <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2014-04-12 <abstract> An overview over the Plus/4 runtime system as it is implemented for the cc65 C diff --git a/doc/sim65.sgml b/doc/sim65.sgml index a2ebbac25..14741dd31 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -4,7 +4,6 @@ <title>sim65 Users Guide <author><url url="mailto:polluks@sdf.lonestar.org" name="Stefan A. Haubenthal"> -<date>2016-07-05 <abstract> sim65 is a simulator for 6502 and 65C02 CPUs. It allows to test target diff --git a/doc/smc.sgml b/doc/smc.sgml index 4f3e2ace4..aec0d3d0b 100644 --- a/doc/smc.sgml +++ b/doc/smc.sgml @@ -3,7 +3,6 @@ <article> <title>ca65 Macros for Self Modifying Code <author>Christian Krüger -<date>2014-04-24 <abstract> The 'smc.inc' macro package for ca65 eases the use, increases the safeness and diff --git a/doc/sp65.sgml b/doc/sp65.sgml index ccad930c3..82b308025 100644 --- a/doc/sp65.sgml +++ b/doc/sp65.sgml @@ -3,7 +3,6 @@ <article> <title>sp65 Users Guide <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2012-03-11 <abstract> sp65 is a sprite and bitmap utility that is part of the cc65 development suite. diff --git a/doc/supervision.sgml b/doc/supervision.sgml index 153746025..641a7e807 100644 --- a/doc/supervision.sgml +++ b/doc/supervision.sgml @@ -1,10 +1,8 @@ <!doctype linuxdoc system> <article> - <title>Watara Supervision specific information for cc65 <author><url url="mailto:polluks@sdf.lonestar.org" name="Stefan A. Haubenthal"> -<date>2017-11-21 <abstract> An overview over the Supervision runtime system as it is implemented for the diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index 76b3cdd30..fe9efcfdb 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -1,13 +1,10 @@ <!doctype linuxdoc system> <article> - <title>Oric Telestrat-specific information for cc65 <author> <url url="mailto:jede@oric.org" name="Jede"> -<date>2017-01-22 - <abstract> An overview over the Telestrat (Telemon 2.4 & Telemon 3.x : http://orix.oric.org) runtime system as it is implemented for the cc65 C compiler. </abstract> diff --git a/doc/tgi.sgml b/doc/tgi.sgml index d20df40d1..c5878622e 100644 --- a/doc/tgi.sgml +++ b/doc/tgi.sgml @@ -5,7 +5,6 @@ <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:greg.king5@verizon.net" name="Greg King"> -<date>2017-11-30 <abstract> The cc65 library provides functions for platform independent graphics. diff --git a/doc/using-make.sgml b/doc/using-make.sgml index e0e99a99c..7986e1dc9 100644 --- a/doc/using-make.sgml +++ b/doc/using-make.sgml @@ -1,10 +1,8 @@ <!doctype linuxdoc system> <article> - <title>Using GNU Make with cc65 <author><url url="mailto:ol.sc@web.de" name="Oliver Schmidt"> -<date>2014-04-12 <abstract> How to build your program using the GNU Make utility. diff --git a/doc/vic20.sgml b/doc/vic20.sgml index 79c2fb898..6f98c6920 100644 --- a/doc/vic20.sgml +++ b/doc/vic20.sgml @@ -1,12 +1,10 @@ <!doctype linuxdoc system> <article> - <title>Commodore VIC20 (aka VC20 aka VIC1001) 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"> -<date>2018-04-20 <abstract> An overview over the VIC20 runtime system as it is implemented for the cc65 C From 118bc996fb0f45018668f8ec1c59e581e9c660a8 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 20 Sep 2018 23:58:23 +0200 Subject: [PATCH 0858/2161] libsrc/atari/getdefdev.s: small comment change --- libsrc/atari/getdefdev.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/atari/getdefdev.s b/libsrc/atari/getdefdev.s index e1ec3f4c0..20e32246a 100644 --- a/libsrc/atari/getdefdev.s +++ b/libsrc/atari/getdefdev.s @@ -32,9 +32,9 @@ __getdefdev: lda __dos_type ; which DOS? cmp #XDOS - beq xdos ; only supported on XDOS ... + beq xdos ; XDOS detected ; cmp #OSADOS+1 ; (redundant: #OSADOS+1 = #XDOS) - bcs use_DUNIT ; ... and on OS/A+ and SpartaDOS + bcs use_DUNIT ; neither XDOS, nor OS/A+ or SpartaDOS ldy #BUFOFF lda #0 From bfba206d160f637cd17b1bb898ec054d9c6f030e Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 25 Sep 2018 02:31:49 +0200 Subject: [PATCH 0859/2161] asminc/atari.inc: add some SpartaDOS-X defines --- asminc/atari.inc | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/asminc/atari.inc b/asminc/atari.inc index 6b8c0dc30..19ed333c3 100644 --- a/asminc/atari.inc +++ b/asminc/atari.inc @@ -7,6 +7,7 @@ ; - Atari OS manual - XL addendum ; - Atari XL/XE rev.2 source code, Atari 1984 ; - Mapping the Atari - revised edition, Ian Chadwick 1985 +; - SpartaDOS-X User Guide (Aug-8-2016) ; ; ##old## old OS rev.B label - moved or deleted ; ##1200xl## new label introduced in 1200XL OS (rev.10/11) @@ -757,6 +758,34 @@ FPSCR1 = $05EC ;6-byte floating point temporary DOS = $0700 +;------------------------------------------------------------------------- +; SpartaDOS-X Definitions +;------------------------------------------------------------------------- + +SDX_FLAG = DOS ; 'S' for SpartaDOS +SDX_VERSION = $0701 ; SD version (e.g. $32 = 3.2, $40 = 4.0) + ; address $0702 contains sub-version, e.g. + ; 8 in case of SDX 4.48 +SDX_KERNEL = $0703 ; SDX kernel entry point +SDX_BLOCK_IO = $0706 ; block I/O entry point +SDX_MISC = $0709 ; "misc" entry point +SDX_DEVICE = $0761 +SDX_DATE = $077B ; day, month, year (3 bytes) +SDX_TIME = $077E ; hour, min, sec (3 bytes) +SDX_DATESET = $0781 +SDX_PATH = $07A0 ; 64 bytes +SDX_IFSYMBOL = $07EB ; only valid on SDX 4.40 or newer +SDX_S_LOOKUP = SDX_IFSYMBOL ; alternative name for SDX_IFSYMBOL + +; values for SDX_DEVICE + +SDX_CLK_DEV = $10 ; clock device + +; clock device functions + +SDX_KD_GETTD = 100 ; get time and date +SDX_KD_SETTD = 101 ; set time and date + ;------------------------------------------------------------------------- ; Cartridge Address Equates ;------------------------------------------------------------------------- From 9c7cccf3e5214ebbb3ac031168e349a5f27fb5ae Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 25 Sep 2018 02:42:45 +0200 Subject: [PATCH 0860/2161] Atari: clock_gettime() and clock_settime() implementations They are using SpartaDOS-X interfaces and are therefore only working in this environment. --- libsrc/atari/gettime.s | 114 +++++++++++++++++++++++++++++++++++++ libsrc/atari/sdxtime-bss.s | 9 +++ libsrc/atari/settime.s | 101 ++++++++++++++++++++++++++++++-- 3 files changed, 219 insertions(+), 5 deletions(-) create mode 100644 libsrc/atari/gettime.s create mode 100644 libsrc/atari/sdxtime-bss.s diff --git a/libsrc/atari/gettime.s b/libsrc/atari/gettime.s new file mode 100644 index 000000000..093d34843 --- /dev/null +++ b/libsrc/atari/gettime.s @@ -0,0 +1,114 @@ +; +; Oliver Schmidt, 14.08.2018 +; Christian Groessler, 25.09.2018 +; +; int __fastcall__ clock_gettime (clockid_t clk_id, struct timespec *tp); +; + + .import pushax, steaxspidx, incsp1, incsp3, return0 + .import __dos_type + .import sdxtry + + .include "time.inc" + .include "zeropage.inc" + .include "errno.inc" + .include "atari.inc" + +_clock_gettime: + jsr pushax + +; clear tp + + sta ptr1 + stx ptr1+1 + lda #$00 + ldy #.sizeof(timespec)-1 +: sta (ptr1),y + dey + bpl :- + +; only supported on SpartaDOS-X >= 4.40 + + lda #SPARTADOS + cmp __dos_type + bne notsupp + lda SDX_VERSION + cmp #$44 + bcc notsupp + +; get date/time from system (SD-X call) +; see settime.s for reasons of using sdxtry + + lda #0 ; init loop count (256) + sta sdxtry + +try_get:lda #SDX_CLK_DEV ; CLK device + sta SDX_DEVICE + ldy #SDX_KD_GETTD ; GETTD function + jsr SDX_KERNEL ; do the call + bcc done + + dec sdxtry + bne try_get + + lda #EBUSY + bne errexit + +; fill timespec + +; date +done: lda SDX_DATE ; mday + sta TM + tm::tm_mday + ldx SDX_DATE+1 ; month + dex + stx TM + tm::tm_mon + lda SDX_DATE+2 ; year + cmp #79 ; 1979: the Atari 800 came out + bcs :+ + adc #100 ; adjust century +: sta TM + tm::tm_year + +; time + lda SDX_TIME + sta TM + tm::tm_hour + lda SDX_TIME+1 + sta TM + tm::tm_min + lda SDX_TIME+2 + sta TM + tm::tm_sec + +; make time_t + + lda #<TM + ldx #>TM + jsr _mktime + +; store tv_sec into output tp struct + + ldy #timespec::tv_sec + jsr steaxspidx + +; cleanup stack + + jsr incsp1 + +; return success + + jmp return0 + +; load errno code + +notsupp:lda #ENOSYS + +; cleanup stack + +errexit:jsr incsp3 ; Preserves A + +; set __errno + + jmp __directerrno + +; ------- + + .bss + +TM: .tag tm diff --git a/libsrc/atari/sdxtime-bss.s b/libsrc/atari/sdxtime-bss.s new file mode 100644 index 000000000..62bb58bba --- /dev/null +++ b/libsrc/atari/sdxtime-bss.s @@ -0,0 +1,9 @@ +; .bss variable used by SpartaDOS-X implementations of +; gettime.s and settime.s + + .export sdxtry + + .bss + +sdxtry: .res 1 ; limit of unsuccessful tries to call GETTD/SETTD + ; (see settime.s) diff --git a/libsrc/atari/settime.s b/libsrc/atari/settime.s index 698aa2a29..7d6fff2c0 100644 --- a/libsrc/atari/settime.s +++ b/libsrc/atari/settime.s @@ -1,8 +1,99 @@ ; -; int clock_settime (clockid_t clk_id, const struct timespec *tp); +; Oliver Schmidt, 15.08.2018 +; Christian Groessler, 25.09.2018 ; - .include "errno.inc" - .export _clock_settime +; int __fastcall__ clock_settime (clockid_t clk_id, const struct timespec *tp); +; + + .import __dos_type + .import incsp1, return0 + .import sdxtry + + .include "time.inc" + .include "zeropage.inc" + .include "errno.inc" + .include "atari.inc" + _clock_settime: - lda #ENOSYS - jmp __directerrno + +; cleanup stack + + jsr incsp1 ; preserves AX + +; only supported on SpartaDOS-X >= 4.40 + + ldy #SPARTADOS + cpy __dos_type + bne enosys + ldy SDX_VERSION + cpy #$44 + bcc enosys + +; create tm from tp (tv_sec) input parameter + + .assert timespec::tv_sec = 0, error + jsr _localtime + sta ptr1 + stx ptr1+1 + +; set date + + ldy #tm::tm_mday + lda (ptr1),y ; get day of month + sta SDX_DATE ; set day of month + + ldy #tm::tm_mon + lda (ptr1),y ; get month (0-based) + tax + inx ; move [0..11] to [1..12] + stx SDX_DATE+1 + + ldy #tm::tm_year + lda (ptr1),y ; get year (0 = year 1900) + cmp #100 + bcc :+ + sbc #100 +: sta SDX_DATE+2 + + ldy #tm::tm_hour + lda (ptr1),y ; get hour + sta SDX_TIME + + ldy #tm::tm_min + lda (ptr1),y ; get minutes + sta SDX_TIME+1 + + ldy #tm::tm_sec + lda (ptr1),y ; get seconds + sta SDX_TIME+2 + +; set new time/date (SD-X call) +; SpartaDOS-X User's Guide (4.48) states at page 145: +; "In the I_GETTD and I_SETTD procedures a set Carry-Flag means that the clock driver is +; busy at the moment. You should call the routine again." +; It goes on to mention that one should provide an upper limit on the number of calls, +; in order not to "hang". We are doing this here... + + lda #0 ; init loop count (256) + sta sdxtry + +try_set:lda #SDX_CLK_DEV ; CLK device + sta SDX_DEVICE + ldy #SDX_KD_SETTD ; SETTD function + jsr SDX_KERNEL ; do the call + bcc done + + dec sdxtry + bne try_set + + lda #EBUSY + bne drcter ; jump always + +; return success + +done: jmp return0 + +; load errno code + +enosys: lda #ENOSYS +drcter: jmp __directerrno From 3a2d68fd1f3343ad2c0bfb25fff7603ff5ba20e7 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 25 Sep 2018 02:47:45 +0200 Subject: [PATCH 0861/2161] Add testcode/lib/clock-test.c. A test program for the "clock" functions. --- testcode/lib/clock-test.c | 100 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 testcode/lib/clock-test.c diff --git a/testcode/lib/clock-test.c b/testcode/lib/clock-test.c new file mode 100644 index 000000000..0267668aa --- /dev/null +++ b/testcode/lib/clock-test.c @@ -0,0 +1,100 @@ +/* Clock test program + * + * 25-Sep-2018, chris@groessler.org + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <errno.h> + +#ifdef __CC65__ +#include <conio.h> +#include <cc65.h> + +static void exitfn(void) +{ + if (doesclrscrafterexit()) cgetc(); +} +#endif /* #ifdef __CC65__ */ + +static void print_time(void) +{ + struct tm *cur_tm; + time_t cur_time = time(NULL); + if (cur_time == -1) { + printf("time() failed: %s\n", strerror(errno)); + return; + } + cur_tm = localtime(&cur_time); + + printf("time: %s\n", asctime(cur_tm)); + // DEBUG: + printf("mday=%d mon=%d year=%d\nhour=%d min=%d sec=%d\n", cur_tm->tm_mday, cur_tm->tm_mon, cur_tm->tm_year, cur_tm->tm_hour, cur_tm->tm_min, cur_tm->tm_sec); +} + +int main(int argc, char **argv) +{ + static char c; + static int s; + static struct tm cur_time; + static struct timespec new_time; + +#ifdef __CC65__ + atexit(exitfn); +#endif + + if (argc <= 1) { + print_time(); + return 0; + } + + if (argc != 3 || strcasecmp(*(argv + 1), "set")) { + printf("usage: CLOCKTST [set DD-MM-YY-HH-MM-SS]\n"); + return 1; + } + + s = sscanf(*(argv + 2), "%d-%d-%d-%d-%d-%d", &cur_time.tm_mday, &cur_time.tm_mon, &cur_time.tm_year, &cur_time.tm_hour, &cur_time.tm_min, &cur_time.tm_sec); + if (s != 6 || cur_time.tm_year > 99 /* other input values aren't being verified... */) { + printf("invalid time/date format\n"); + return 1; + } + --cur_time.tm_mon; + if (cur_time.tm_year < 79) + cur_time.tm_year += 100; /* adjust century */ + + memset(&new_time, 0, sizeof(new_time)); + new_time.tv_sec = mktime(&cur_time); + + printf("\nyou are about to set the time to\n--> %s\n\nContinue (y/n)?", ctime(&new_time.tv_sec)); + + while (c != 'y' && c != 'Y' && c != 'n' && c != 'N') { +#ifdef __CC65__ + c = cgetc(); +#else + c = getchar(); +#endif + } + printf("%c\n", c); + + if (c == 'n' || c == 'N') { + printf("user abort\n"); + return 0; + } + + s = clock_settime(CLOCK_REALTIME, &new_time); + if (s) { + printf("clock_settime() failed: %s\n", strerror(errno)); + return 1; + } + printf("time set!\n"); + //DEBUG test begin + print_time(); + //DEBUG test end + return 0; +} +/* Local Variables: */ +/* c-file-style: "cpg" */ +/* c-basic-offset: 4 */ +/* End: */ From b1ca01f72066d0a50dc9ebec8fd23a53094eb2c0 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 25 Sep 2018 03:05:30 +0200 Subject: [PATCH 0862/2161] asminc/atari.inc: remove TABs which slipped in --- asminc/atari.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asminc/atari.inc b/asminc/atari.inc index 19ed333c3..4e2958fbc 100644 --- a/asminc/atari.inc +++ b/asminc/atari.inc @@ -765,7 +765,7 @@ DOS = $0700 SDX_FLAG = DOS ; 'S' for SpartaDOS SDX_VERSION = $0701 ; SD version (e.g. $32 = 3.2, $40 = 4.0) ; address $0702 contains sub-version, e.g. - ; 8 in case of SDX 4.48 + ; 8 in case of SDX 4.48 SDX_KERNEL = $0703 ; SDX kernel entry point SDX_BLOCK_IO = $0706 ; block I/O entry point SDX_MISC = $0709 ; "misc" entry point From 1203e9e0c4d7a3c90736a78b53079e9d584fc084 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 25 Sep 2018 14:35:52 +0200 Subject: [PATCH 0863/2161] clock-test.c: do doesclrscrafterexit() handling the canonical way. --- testcode/lib/clock-test.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/testcode/lib/clock-test.c b/testcode/lib/clock-test.c index 0267668aa..9d420a5b0 100644 --- a/testcode/lib/clock-test.c +++ b/testcode/lib/clock-test.c @@ -12,11 +12,6 @@ #ifdef __CC65__ #include <conio.h> #include <cc65.h> - -static void exitfn(void) -{ - if (doesclrscrafterexit()) cgetc(); -} #endif /* #ifdef __CC65__ */ static void print_time(void) @@ -42,7 +37,9 @@ int main(int argc, char **argv) static struct timespec new_time; #ifdef __CC65__ - atexit(exitfn); + /* if DOS will automatically clear the screen after the program exits, wait for a keypress... */ + if (doesclrscrafterexit()) + atexit((void (*)(void))cgetc); #endif if (argc <= 1) { From fe7845b5f014aa9f063876019bd5bae17a63c194 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 25 Sep 2018 20:26:25 +0200 Subject: [PATCH 0864/2161] clock-test.c: remove "static" optimization --- testcode/lib/clock-test.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/testcode/lib/clock-test.c b/testcode/lib/clock-test.c index 9d420a5b0..e3115d2f1 100644 --- a/testcode/lib/clock-test.c +++ b/testcode/lib/clock-test.c @@ -31,10 +31,10 @@ static void print_time(void) int main(int argc, char **argv) { - static char c; - static int s; - static struct tm cur_time; - static struct timespec new_time; + char c = 0; + int s; + struct tm cur_time; + struct timespec new_time; #ifdef __CC65__ /* if DOS will automatically clear the screen after the program exits, wait for a keypress... */ @@ -52,6 +52,7 @@ int main(int argc, char **argv) return 1; } + memset(&cur_time, 0, sizeof(cur_time)); s = sscanf(*(argv + 2), "%d-%d-%d-%d-%d-%d", &cur_time.tm_mday, &cur_time.tm_mon, &cur_time.tm_year, &cur_time.tm_hour, &cur_time.tm_min, &cur_time.tm_sec); if (s != 6 || cur_time.tm_year > 99 /* other input values aren't being verified... */) { printf("invalid time/date format\n"); From 6dc7309e50c59ca114dfb6500ca786c2a84d13e9 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 27 Sep 2018 17:37:59 +0200 Subject: [PATCH 0865/2161] Atari: add support for BW-DOS. Initially contributed by Daniel Serpell. --- asminc/atari.inc | 9 +++++---- include/atari.h | 11 ++++++----- libsrc/atari/dosdetect.s | 15 +++++++++++++-- libsrc/atari/lseek.s | 2 ++ libsrc/atari/syschdir.s | 2 ++ libsrc/atari/system_check.s | 11 ++++++++++- 6 files changed, 38 insertions(+), 12 deletions(-) diff --git a/asminc/atari.inc b/asminc/atari.inc index 4e2958fbc..98c721296 100644 --- a/asminc/atari.inc +++ b/asminc/atari.inc @@ -1033,10 +1033,11 @@ diopp_size = 5 ; size of structure SPARTADOS = 0 REALDOS = 1 -OSADOS = 2 ; OS/A+ -XDOS = 3 -ATARIDOS = 4 -MYDOS = 5 +BWDOS = 2 +OSADOS = 3 ; OS/A+ +XDOS = 4 +ATARIDOS = 5 +MYDOS = 6 NODOS = 255 ; The DOSes with dos_type below or equal MAX_DOS_WITH_CMDLINE do support ; command line arguments. diff --git a/include/atari.h b/include/atari.h index d9463904c..ca6bd424c 100644 --- a/include/atari.h +++ b/include/atari.h @@ -261,11 +261,12 @@ extern void atrx15p2_tgi[]; /* valid _dos_type values */ #define SPARTADOS 0 -#define OSADOS 1 -#define XDOS 2 -#define REALDOS 3 -#define ATARIDOS 4 -#define MYDOS 5 +#define REALDOS 1 +#define BWDOS 2 +#define OSADOS 3 +#define XDOS 4 +#define ATARIDOS 5 +#define MYDOS 6 #define NODOS 255 /* Define hardware */ diff --git a/libsrc/atari/dosdetect.s b/libsrc/atari/dosdetect.s index 7e6088d97..1dd6a87f5 100644 --- a/libsrc/atari/dosdetect.s +++ b/libsrc/atari/dosdetect.s @@ -35,9 +35,20 @@ detect: lda DOS cmp (DOSVEC),y beq done lda #OSADOS + bne set + +spdos: lda DOS+3 ; 'B' in BW-DOS + cmp #'B' + bne spdos_real + lda DOS+4 ; 'W' in BW-DOS + cmp #'W' + bne spdos_real + + lda #BWDOS .byte $2C ; BIT <abs> -spdos: lda #SPARTADOS +spdos_real: + lda #SPARTADOS .byte $2C ; BIT <abs> mydos: lda #MYDOS @@ -47,7 +58,7 @@ rdos: lda #REALDOS .byte $2C ; BIT <abs> xdos: lda #XDOS - sta __dos_type +set: sta __dos_type done: rts ; ------------------------------------------------------------------------ diff --git a/libsrc/atari/lseek.s b/libsrc/atari/lseek.s index 462f2f90b..b6a766361 100644 --- a/libsrc/atari/lseek.s +++ b/libsrc/atari/lseek.s @@ -195,6 +195,8 @@ chk_supp: lda __dos_type cmp #SPARTADOS beq :+ + cmp #BWDOS + beq :+ cmp #REALDOS bne ns1 : txa diff --git a/libsrc/atari/syschdir.s b/libsrc/atari/syschdir.s index 9e4c33a19..f493fea54 100644 --- a/libsrc/atari/syschdir.s +++ b/libsrc/atari/syschdir.s @@ -67,6 +67,8 @@ ucok1: beq :+ cmp #REALDOS beq :+ + cmp #BWDOS + beq :+ lda #CHDIR_MYDOS .byte $2C ; BIT <abs> : lda #CHDIR_SPDOS diff --git a/libsrc/atari/system_check.s b/libsrc/atari/system_check.s index ec0d60513..19efaf2e2 100644 --- a/libsrc/atari/system_check.s +++ b/libsrc/atari/system_check.s @@ -77,7 +77,16 @@ cont: ldx #0 ; channel 0 sdcheck:lda DOS cmp #'S' bne sdcrts0 ; not SpartaDOS, assume RAM is not used - lda DOS+1 ; SD version + +; check for BW-DOS, which always reports itself as SpartaDOS, but doesn't use memory under the ROM + lda DOS+3 ; 'B' in BW-DOS + cmp #'B' + bne sdnobw + lda DOS+4 ; 'W' in BW-DOS + cmp #'W' + beq sdcrts0 ; BW-DOS does not use RAM below ROM + +sdnobw: lda DOS+1 ; SD version cmp #$40 ; SD-X has $40 or higher bcc sdcrts1 ; older versions (except maybe 1.x) always use the RAM under the ROM ldy #31 ; offset for OSRMFLG From df3c43bedea8d5384a8e1c28fa1dd78ee5aaa6cd Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 27 Sep 2018 20:22:21 +0200 Subject: [PATCH 0866/2161] Atari: implement clock_getres() --- libsrc/apple2/getres.s | 2 +- libsrc/atari/getres.s | 51 ++++++++++++++++++++++++++++++++++++++++++ libsrc/cbm/getres.s | 2 +- 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 libsrc/atari/getres.s diff --git a/libsrc/apple2/getres.s b/libsrc/apple2/getres.s index 777a5df3f..6441671cc 100644 --- a/libsrc/apple2/getres.s +++ b/libsrc/apple2/getres.s @@ -1,7 +1,7 @@ ; ; Oliver Schmidt, 15.08.2018 ; -; int clock_getres (clockid_t clk_id, struct timespec *res); +; int __fastcall__ clock_getres (clockid_t clk_id, struct timespec *res); ; .import __dos_type diff --git a/libsrc/atari/getres.s b/libsrc/atari/getres.s new file mode 100644 index 000000000..f2e4874f9 --- /dev/null +++ b/libsrc/atari/getres.s @@ -0,0 +1,51 @@ +; +; Oliver Schmidt, 15.8.2018 +; Christian Groessler, 27.9.2018 +; +; int __fastcall__ clock_getres (clockid_t clk_id, struct timespec *res); +; + + .include "atari.inc" + .include "time.inc" + .include "errno.inc" + + .importzp ptr1 + .import incsp1, return0, __dos_type + +;---------------------------------------------------------------------------- +.code + +_clock_getres: + sta ptr1 + stx ptr1+1 + + ; Cleanup stack + jsr incsp1 + + ; Check for SpartaDOS-X 4.40 or newer + ldy #SPARTADOS + cpy __dos_type + bne enosys + ldy SDX_VERSION + cpy #$44 + bcc enosys + + ldy #.sizeof(timespec)-1 +@L1: lda time,y + sta (ptr1),y + dey + bpl @L1 + + jmp return0 + +enosys: lda #ENOSYS + + ; Set __errno + jmp __directerrno + +;---------------------------------------------------------------------------- +; timespec struct with tv_sec set to 1 second +.rodata + +time: .dword 1 + .dword 0 diff --git a/libsrc/cbm/getres.s b/libsrc/cbm/getres.s index d216a1b6a..998bac9f6 100644 --- a/libsrc/cbm/getres.s +++ b/libsrc/cbm/getres.s @@ -1,7 +1,7 @@ ; ; Oliver Schmidt, 15.8.2018 ; -; int clock_getres (clockid_t clk_id, struct timespec *res); +; int __fastcall__ clock_getres (clockid_t clk_id, struct timespec *res); ; .include "time.inc" From 581c46c2136fa18bd3a60cddf6d2732862381023 Mon Sep 17 00:00:00 2001 From: Laubzega <mileksmyk@gmail.com> Date: Fri, 21 Sep 2018 00:40:05 -0700 Subject: [PATCH 0867/2161] Add checks for risky goto statements. --- src/cc65/asmstmt.c | 4 ++-- src/cc65/expr.c | 2 +- src/cc65/function.c | 41 +++++++++++-------------------------- src/cc65/function.h | 27 ++++++++++++++++++++++-- src/cc65/goto.c | 4 ++-- src/cc65/locals.c | 7 +++++++ src/cc65/stmt.c | 4 ++++ src/cc65/symentry.c | 13 ++++++++++++ src/cc65/symentry.h | 15 +++++++++++++- src/cc65/symtab.c | 50 ++++++++++++++++++++++++++++++++++++++++----- 10 files changed, 125 insertions(+), 42 deletions(-) diff --git a/src/cc65/asmstmt.c b/src/cc65/asmstmt.c index 4dd6628c4..1fc4e3167 100644 --- a/src/cc65/asmstmt.c +++ b/src/cc65/asmstmt.c @@ -238,7 +238,7 @@ static void ParseGVarArg (StrBuf* T, unsigned Arg) } else { /* Static variable */ char Buf [16]; - xsprintf (Buf, sizeof (Buf), "L%04X", Sym->V.Label); + xsprintf (Buf, sizeof (Buf), "L%04X", Sym->V.L.Label); SB_AppendStr (T, Buf); } } @@ -293,7 +293,7 @@ static void ParseLabelArg (StrBuf* T, unsigned Arg attribute ((unused))) SymEntry* Entry = AddLabelSym (CurTok.Ident, SC_REF); /* Append the label name to the buffer */ - SB_AppendStr (T, LocalLabelName (Entry->V.Label)); + SB_AppendStr (T, LocalLabelName (Entry->V.L.Label)); /* Eat the label name */ NextToken (); diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 43971caae..55c6391d2 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -757,7 +757,7 @@ static void Primary (ExprDesc* E) E->Name = (uintptr_t) Sym->Name; } else { E->Flags = E_LOC_STATIC | E_RTYPE_LVAL; - E->Name = Sym->V.Label; + E->Name = Sym->V.L.Label; } } else { /* Local static variable */ diff --git a/src/cc65/function.c b/src/cc65/function.c index 22b305739..6a601db2c 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -60,27 +60,6 @@ /*****************************************************************************/ - -/* Enumeration for function flags */ -typedef enum { - FF_NONE = 0x0000, - FF_HAS_RETURN = 0x0001, /* Function has a return statement */ - FF_IS_MAIN = 0x0002, /* This is the main function */ - FF_VOID_RETURN = 0x0004, /* Function returning void */ -} funcflags_t; - -/* Structure that holds all data needed for function activation */ -struct Function { - struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ - FuncDesc* Desc; /* Function descriptor */ - int Reserved; /* Reserved local space */ - unsigned RetLab; /* Return code label */ - int TopLevelSP; /* SP at function top level */ - unsigned RegOffs; /* Register variable space offset */ - funcflags_t Flags; /* Function flags */ -}; - /* Pointer to current function */ Function* CurrentFunc = 0; @@ -99,14 +78,17 @@ static Function* NewFunction (struct SymEntry* Sym) Function* F = (Function*) xmalloc (sizeof (Function)); /* Initialize the fields */ - F->FuncEntry = Sym; - F->ReturnType = GetFuncReturn (Sym->Type); - F->Desc = GetFuncDesc (Sym->Type); - F->Reserved = 0; - F->RetLab = GetLocalLabel (); - F->TopLevelSP = 0; - F->RegOffs = RegisterSpace; - F->Flags = IsTypeVoid (F->ReturnType) ? FF_VOID_RETURN : FF_NONE; + F->FuncEntry = Sym; + F->ReturnType = GetFuncReturn (Sym->Type); + F->Desc = GetFuncDesc (Sym->Type); + F->Reserved = 0; + F->RetLab = GetLocalLabel (); + F->TopLevelSP = 0; + F->RegOffs = RegisterSpace; + F->Flags = IsTypeVoid (F->ReturnType) ? FF_VOID_RETURN : FF_NONE; + F->LocalsBlockCount = 0; + + InitCollection (&F->LocalsBlockStack); /* Return the new structure */ return F; @@ -117,6 +99,7 @@ static Function* NewFunction (struct SymEntry* Sym) static void FreeFunction (Function* F) /* Free a function activation structure */ { + DoneCollection (&F->LocalsBlockStack); xfree (F); } diff --git a/src/cc65/function.h b/src/cc65/function.h index 627457277..1b04009d6 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -36,13 +36,36 @@ #ifndef FUNCTION_H #define FUNCTION_H - +#include "coll.h" /*****************************************************************************/ -/* data */ +/* Data */ /*****************************************************************************/ +/* Enumeration for function flags */ +typedef enum { + FF_NONE = 0x0000, + FF_HAS_RETURN = 0x0001, /* Function has a return statement */ + FF_IS_MAIN = 0x0002, /* This is the main function */ + FF_VOID_RETURN = 0x0004, /* Function returning void */ +} funcflags_t; + +/* Structure that holds all data needed for function activation */ +struct Function { + struct SymEntry* FuncEntry; /* Symbol table entry */ + Type* ReturnType; /* Function return type */ + FuncDesc* Desc; /* Function descriptor */ + int Reserved; /* Reserved local space */ + unsigned RetLab; /* Return code label */ + int TopLevelSP; /* SP at function top level */ + unsigned RegOffs; /* Register variable space offset */ + funcflags_t Flags; /* Function flags */ + long LocalsBlockCount; /* Number of blocks with local vars */ + Collection LocalsBlockStack; /* Stack of blocks with local vars */ +}; + + /* Structure that holds all data needed for function activation */ typedef struct Function Function; diff --git a/src/cc65/goto.c b/src/cc65/goto.c index 6e282c636..3b1d243e7 100644 --- a/src/cc65/goto.c +++ b/src/cc65/goto.c @@ -64,7 +64,7 @@ void GotoStatement (void) SymEntry* Entry = AddLabelSym (CurTok.Ident, SC_REF); /* Jump to the label */ - g_jump (Entry->V.Label); + g_jump (Entry->V.L.Label); } /* Eat the label name */ @@ -80,7 +80,7 @@ void DoLabel (void) SymEntry* Entry = AddLabelSym (CurTok.Ident, SC_DEF); /* Emit the jump label */ - g_defcodelabel (Entry->V.Label); + g_defcodelabel (Entry->V.L.Label); /* Eat the ident and colon */ NextToken (); diff --git a/src/cc65/locals.c b/src/cc65/locals.c index ffadb1bd5..a231a6003 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -538,6 +538,13 @@ void DeclareLocals (void) /* Be sure to allocate any reserved space for locals */ F_AllocLocalSpace (CurrentFunc); + if (InitialStack != StackPtr) + { + ++CurrentFunc->LocalsBlockCount; + /* Is it ok to abuse Collection in this way? */ + CollAppend (&CurrentFunc->LocalsBlockStack, (void *)CurrentFunc->LocalsBlockCount); + } + /* In case we've allocated local variables in this block, emit a call to ** the stack checking routine if stack checks are enabled. */ diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index c6167fa78..be58e4a7e 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -534,6 +534,10 @@ static int CompoundStatement (void) if (!GotBreak) { g_space (StackPtr - OldStack); } + + if (OldStack != StackPtr) + CollPop (&CurrentFunc->LocalsBlockStack); + StackPtr = OldStack; /* Emit references to imports/exports for this block */ diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index d6e68d1bb..8091c4d26 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -83,8 +83,21 @@ SymEntry* NewSymEntry (const char* Name, unsigned Flags) void FreeSymEntry (SymEntry* E) /* Free a symbol entry */ { + unsigned i; + TypeFree (E->Type); xfree (E->AsmName); + + if (E->Flags & SC_LABEL) + { + for (i = 0; i < CollCount (E->V.L.DefsOrRefs); i++) + { + xfree (CollAt(E->V.L.DefsOrRefs, i)); + } + + DoneCollection (E->V.L.DefsOrRefs); + } + xfree (E); } diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index ff136702f..2c22f99a0 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -101,7 +101,17 @@ struct LiteralPool; /* Symbol table entry */ + +typedef struct DefOrRef DefOrRef; + +struct DefOrRef { + unsigned Line; + long LocalsBlockNum; + unsigned Flags; +}; + typedef struct SymEntry SymEntry; + struct SymEntry { SymEntry* NextHash; /* Next entry in hash list */ SymEntry* PrevSym; /* Previous symbol in dl list */ @@ -120,7 +130,10 @@ struct SymEntry { int Offs; /* Label name for static symbols */ - unsigned Label; + struct { + unsigned Label; + Collection *DefsOrRefs; + } L; /* Register bank offset and offset of the saved copy on stack for ** register variables. diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 3275332c5..51b43b4c9 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -57,6 +57,8 @@ #include "symentry.h" #include "typecmp.h" #include "symtab.h" +#include "function.h" +#include "input.h" @@ -658,10 +660,26 @@ SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val } +DefOrRef* AddDefOrRef(SymEntry* E, unsigned Flags) +/* Add definition or reference to the SymEntry and preserve its attributes */ +{ + DefOrRef *DOR; + + DOR = xmalloc (sizeof (DefOrRef)); + CollAppend (E->V.L.DefsOrRefs, DOR); + DOR->Line = GetCurrentLine (); + DOR->LocalsBlockNum = (long)CollLast (&CurrentFunc->LocalsBlockStack); + DOR->Flags = Flags; + + return DOR; +} + SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* Add a goto label to the label table */ { + unsigned i; + DefOrRef *DOR; /* Do we have an entry with this name already? */ SymEntry* Entry = FindSymInTable (LabelTab, Name, HashStr (Name)); if (Entry) { @@ -670,6 +688,24 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* Trying to define the label more than once */ Error ("Label `%s' is defined more than once", Name); } + + /* Walk through all occurrences of the label so far and check + if any of them is in a region that would be risky to jump from/to + from the place where we are right now. */ + for (i = 0; i < CollCount (Entry->V.L.DefsOrRefs); i++) { + DOR = CollAt (Entry->V.L.DefsOrRefs, i); + /* We are only interested in label occurences of type opposite to + the one currently being added, i.e. if we are processing the + definition, we will only check the gotos; if we are processing + a goto statement, we will only look for the label definition. */ + if (((DOR->Flags & SC_DEF) != (Flags & SC_DEF)) && + (DOR->LocalsBlockNum != (long)CollLast (&CurrentFunc->LocalsBlockStack))) + Warning ("Goto from line %d to label \'%s\' can result in a " + "trashed stack", Flags & SC_DEF ? DOR->Line : GetCurrentLine (), Name); + } + + AddDefOrRef (Entry, Flags); + Entry->Flags |= Flags; } else { @@ -678,10 +714,14 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) Entry = NewSymEntry (Name, SC_LABEL | Flags); /* Set a new label number */ - Entry->V.Label = GetLocalLabel (); + Entry->V.L.Label = GetLocalLabel (); + + /* Create Collection for label definition and references */ + Entry->V.L.DefsOrRefs = NewCollection (); + AddDefOrRef (Entry, Flags); /* Generate the assembler name of the label */ - Entry->AsmName = xstrdup (LocalLabelName (Entry->V.Label)); + Entry->AsmName = xstrdup (LocalLabelName (Entry->V.L.Label)); /* Add the entry to the label table */ AddSymEntry (LabelTab, Entry); @@ -717,12 +757,12 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs Entry->V.R.RegOffs = Offs; Entry->V.R.SaveOffs = StackPtr; } else if ((Flags & SC_EXTERN) == SC_EXTERN) { - Entry->V.Label = Offs; + Entry->V.L.Label = Offs; SymSetAsmName (Entry); } else if ((Flags & SC_STATIC) == SC_STATIC) { /* Generate the assembler name from the label number */ - Entry->V.Label = Offs; - Entry->AsmName = xstrdup (LocalLabelName (Entry->V.Label)); + Entry->V.L.Label = Offs; + Entry->AsmName = xstrdup (LocalLabelName (Entry->V.L.Label)); } else if ((Flags & SC_STRUCTFIELD) == SC_STRUCTFIELD) { Entry->V.Offs = Offs; } else { From f5b3c5351e0fe91551c4ff54d168d665c3cfa0c7 Mon Sep 17 00:00:00 2001 From: Laubzega <mileksmyk@gmail.com> Date: Fri, 21 Sep 2018 01:17:29 -0700 Subject: [PATCH 0868/2161] Fix for variableless main(). --- src/cc65/function.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc65/function.c b/src/cc65/function.c index 6a601db2c..eb2ad4bcd 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -523,6 +523,7 @@ void NewFunc (SymEntry* Func) /* Need a starting curly brace */ ConsumeLCurly (); + CollAppend (&CurrentFunc->LocalsBlockStack, (void *)CurrentFunc->LocalsBlockCount); /* Parse local variable declarations if any */ DeclareLocals (); From a4b6bb63c093b0947995ae67fa34910cf8151166 Mon Sep 17 00:00:00 2001 From: Laubzega <mileksmyk@gmail.com> Date: Fri, 21 Sep 2018 21:10:58 -0700 Subject: [PATCH 0869/2161] Minor changes after review. --- src/cc65/function.c | 3 ++- src/cc65/function.h | 2 -- src/cc65/locals.c | 3 +-- src/cc65/stmt.c | 3 ++- src/cc65/symentry.h | 5 ++--- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/cc65/function.c b/src/cc65/function.c index eb2ad4bcd..96b3d6c75 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -60,6 +60,7 @@ /*****************************************************************************/ + /* Pointer to current function */ Function* CurrentFunc = 0; @@ -523,7 +524,7 @@ void NewFunc (SymEntry* Func) /* Need a starting curly brace */ ConsumeLCurly (); - CollAppend (&CurrentFunc->LocalsBlockStack, (void *)CurrentFunc->LocalsBlockCount); + CollAppend (&CurrentFunc->LocalsBlockStack, 0); /* Parse local variable declarations if any */ DeclareLocals (); diff --git a/src/cc65/function.h b/src/cc65/function.h index 1b04009d6..5c5822045 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -65,8 +65,6 @@ struct Function { Collection LocalsBlockStack; /* Stack of blocks with local vars */ }; - - /* Structure that holds all data needed for function activation */ typedef struct Function Function; diff --git a/src/cc65/locals.c b/src/cc65/locals.c index a231a6003..20d370c46 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -538,8 +538,7 @@ void DeclareLocals (void) /* Be sure to allocate any reserved space for locals */ F_AllocLocalSpace (CurrentFunc); - if (InitialStack != StackPtr) - { + if (InitialStack != StackPtr) { ++CurrentFunc->LocalsBlockCount; /* Is it ok to abuse Collection in this way? */ CollAppend (&CurrentFunc->LocalsBlockStack, (void *)CurrentFunc->LocalsBlockCount); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index be58e4a7e..b766ec044 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -535,8 +535,9 @@ static int CompoundStatement (void) g_space (StackPtr - OldStack); } - if (OldStack != StackPtr) + if (OldStack != StackPtr) { CollPop (&CurrentFunc->LocalsBlockStack); + } StackPtr = OldStack; diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 2c22f99a0..24b647234 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -100,18 +100,17 @@ struct LiteralPool; -/* Symbol table entry */ +/* Label definition or reference */ typedef struct DefOrRef DefOrRef; - struct DefOrRef { unsigned Line; long LocalsBlockNum; unsigned Flags; }; +/* Symbol table entry */ typedef struct SymEntry SymEntry; - struct SymEntry { SymEntry* NextHash; /* Next entry in hash list */ SymEntry* PrevSym; /* Previous symbol in dl list */ From 403783b649fe5155bb07f00fadd0829b42e8f916 Mon Sep 17 00:00:00 2001 From: Laubzega <mileksmyk@gmail.com> Date: Fri, 21 Sep 2018 22:23:21 -0700 Subject: [PATCH 0870/2161] Add a testcase for https://github.com/cc65/cc65/pull/757 --- test/misc/Makefile | 5 ++++ test/misc/goto.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++ test/misc/goto.ref | 7 +++++ 3 files changed, 77 insertions(+) create mode 100644 test/misc/goto.c create mode 100644 test/misc/goto.ref diff --git a/test/misc/Makefile b/test/misc/Makefile index 330c9d500..ad39176bd 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -72,6 +72,11 @@ $(WORKDIR)/limits.$1.$2.prg: limits.c $(DIFF) $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/limits.$1.out $(DIFF) $(WORKDIR)/limits.$1.out limits.ref +$(WORKDIR)/goto.$1.$2.prg: goto.c $(DIFF) + $(if $(QUIET),echo misc/goto.$1.$2.prg) + $(CL65) -t sim$2 -$1 -o $$@ $$< 2>$(WORKDIR)/goto.$1.out + $(DIFF) $(WORKDIR)/goto.$1.out goto.ref + # the rest are tests that fail currently for one reason or another $(WORKDIR)/fields.$1.$2.prg: fields.c | $(WORKDIR) @echo "FIXME: " $$@ "currently will fail." diff --git a/test/misc/goto.c b/test/misc/goto.c new file mode 100644 index 000000000..bdc407f82 --- /dev/null +++ b/test/misc/goto.c @@ -0,0 +1,65 @@ +#include <stdio.h> +#define false 0 +#define true (!false) + +int main () { + int var = 3; + int quit = false; + + goto finish; + + while (!quit) { + var += 1; + { + if (var % 2) { + int var2 = 2; + int var3 = 4; + goto safe; + goto unsafe; + { + another: + var2 = 0x5599; + safe: + printf ("var2: %d\n", var2); + } + } else { + int var3 = 3; + int x = 4; + goto unsafe; + goto bad; + unused: + printf ("var3: %d\n", var3); + { + int var = 1; + bad: + var++; + if (var < 4) + goto bad; + goto finish; + } + unsafe: + var3 = 4; + goto another; + } + + { + int var = 2; + goto bad; + } + + + var += 1; + if (var >= 10) + goto finish; + } + } +finish: + return var; +} + +int function () { + goto end; + +end: + ; +} diff --git a/test/misc/goto.ref b/test/misc/goto.ref new file mode 100644 index 000000000..f31fa4507 --- /dev/null +++ b/test/misc/goto.ref @@ -0,0 +1,7 @@ +goto.c(34): Warning: Goto from line 29 to label 'bad' can result in a trashed stack +goto.c(40): Warning: Goto from line 18 to label 'unsafe' can result in a trashed stack +goto.c(42): Warning: Goto from line 42 to label 'another' can result in a trashed stack +goto.c(47): Warning: Goto from line 47 to label 'bad' can result in a trashed stack +goto.c(56): Warning: Goto from line 38 to label 'finish' can result in a trashed stack +goto.c(58): Warning: `unused' is defined but never used +goto.c(65): Warning: Control reaches end of non-void function From 7a5acaf39a72dee5e008749d6715217a2c8e3da1 Mon Sep 17 00:00:00 2001 From: Laubzega <mileksmyk@gmail.com> Date: Fri, 21 Sep 2018 22:25:05 -0700 Subject: [PATCH 0871/2161] Missed the comment. --- test/misc/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/test/misc/Makefile b/test/misc/Makefile index ad39176bd..2332f1785 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -72,6 +72,7 @@ $(WORKDIR)/limits.$1.$2.prg: limits.c $(DIFF) $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/limits.$1.out $(DIFF) $(WORKDIR)/limits.$1.out limits.ref +# here we check if the right warnings are produced $(WORKDIR)/goto.$1.$2.prg: goto.c $(DIFF) $(if $(QUIET),echo misc/goto.$1.$2.prg) $(CL65) -t sim$2 -$1 -o $$@ $$< 2>$(WORKDIR)/goto.$1.out From a48bbc4be09fdfcc0bd2a157341ffccece882fe8 Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Sun, 23 Sep 2018 16:22:59 -0700 Subject: [PATCH 0872/2161] Switched from warning to error. Tightened the testcase. --- src/cc65/symtab.c | 2 +- test/misc/Makefile | 4 ++-- test/misc/goto.c | 2 +- test/misc/goto.ref | 11 +++++------ 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 51b43b4c9..fe3787f00 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -700,7 +700,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) a goto statement, we will only look for the label definition. */ if (((DOR->Flags & SC_DEF) != (Flags & SC_DEF)) && (DOR->LocalsBlockNum != (long)CollLast (&CurrentFunc->LocalsBlockStack))) - Warning ("Goto from line %d to label \'%s\' can result in a " + Error ("Goto from line %d to label \'%s\' can result in a " "trashed stack", Flags & SC_DEF ? DOR->Line : GetCurrentLine (), Name); } diff --git a/test/misc/Makefile b/test/misc/Makefile index 2332f1785..83d6e03ba 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -72,10 +72,10 @@ $(WORKDIR)/limits.$1.$2.prg: limits.c $(DIFF) $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/limits.$1.out $(DIFF) $(WORKDIR)/limits.$1.out limits.ref -# here we check if the right warnings are produced +# here we check if the right errors are produced $(WORKDIR)/goto.$1.$2.prg: goto.c $(DIFF) $(if $(QUIET),echo misc/goto.$1.$2.prg) - $(CL65) -t sim$2 -$1 -o $$@ $$< 2>$(WORKDIR)/goto.$1.out + $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< 2>$(WORKDIR)/goto.$1.out $(DIFF) $(WORKDIR)/goto.$1.out goto.ref # the rest are tests that fail currently for one reason or another diff --git a/test/misc/goto.c b/test/misc/goto.c index bdc407f82..6d16722e1 100644 --- a/test/misc/goto.c +++ b/test/misc/goto.c @@ -61,5 +61,5 @@ int function () { goto end; end: - ; + return 0; } diff --git a/test/misc/goto.ref b/test/misc/goto.ref index f31fa4507..e319a153f 100644 --- a/test/misc/goto.ref +++ b/test/misc/goto.ref @@ -1,7 +1,6 @@ -goto.c(34): Warning: Goto from line 29 to label 'bad' can result in a trashed stack -goto.c(40): Warning: Goto from line 18 to label 'unsafe' can result in a trashed stack -goto.c(42): Warning: Goto from line 42 to label 'another' can result in a trashed stack -goto.c(47): Warning: Goto from line 47 to label 'bad' can result in a trashed stack -goto.c(56): Warning: Goto from line 38 to label 'finish' can result in a trashed stack +goto.c(34): Error: Goto from line 29 to label 'bad' can result in a trashed stack +goto.c(40): Error: Goto from line 18 to label 'unsafe' can result in a trashed stack +goto.c(42): Error: Goto from line 42 to label 'another' can result in a trashed stack +goto.c(47): Error: Goto from line 47 to label 'bad' can result in a trashed stack +goto.c(56): Error: Goto from line 38 to label 'finish' can result in a trashed stack goto.c(58): Warning: `unused' is defined but never used -goto.c(65): Warning: Control reaches end of non-void function From 2ac2ffcd430a412241a25c6dcb5645a7343a645f Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Tue, 25 Sep 2018 00:56:08 -0700 Subject: [PATCH 0873/2161] Adjust SP on gotos between blocks with local variables. --- src/cc65/codegen.c | 13 +++++++++++++ src/cc65/codegen.h | 3 +++ src/cc65/symentry.h | 3 +++ src/cc65/symtab.c | 47 +++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 9e5102728..c878c7bf6 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -2425,6 +2425,19 @@ void g_falsejump (unsigned flags attribute ((unused)), unsigned label) } +void g_lateadjustSP (unsigned label) +{ +/* Adjust stack based on non-immediate data */ + AddCodeLine ("pha"); + AddCodeLine ("lda %s", LocalLabelName (label)); + AddCodeLine ("clc"); + AddCodeLine ("adc sp"); + AddCodeLine ("sta sp"); + AddCodeLine ("lda %s+1", LocalLabelName (label)); + AddCodeLine ("adc sp+1"); + AddCodeLine ("sta sp+1"); + AddCodeLine ("pla"); +} void g_drop (unsigned Space) /* Drop space allocated on the stack */ diff --git a/src/cc65/codegen.h b/src/cc65/codegen.h index bbad0f125..6f61b33a6 100644 --- a/src/cc65/codegen.h +++ b/src/cc65/codegen.h @@ -406,6 +406,9 @@ void g_truejump (unsigned flags, unsigned label); void g_falsejump (unsigned flags, unsigned label); /* Jump to label if zero flag set */ +void g_lateadjustSP (unsigned label); +/* Adjust stack based on non-immediate data */ + void g_drop (unsigned Space); /* Drop space allocated on the stack */ diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 24b647234..03a63a7d2 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -107,6 +107,9 @@ struct DefOrRef { unsigned Line; long LocalsBlockNum; unsigned Flags; + int StackPtr; + unsigned Depth; + unsigned LateSP_Label; }; /* Symbol table entry */ diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index fe3787f00..c2edcb344 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -670,6 +670,9 @@ DefOrRef* AddDefOrRef(SymEntry* E, unsigned Flags) DOR->Line = GetCurrentLine (); DOR->LocalsBlockNum = (long)CollLast (&CurrentFunc->LocalsBlockStack); DOR->Flags = Flags; + DOR->StackPtr = StackPtr; + DOR->Depth = CollCount(&CurrentFunc->LocalsBlockStack); + DOR->LateSP_Label = GetLocalLabel(); return DOR; } @@ -679,7 +682,8 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* Add a goto label to the label table */ { unsigned i; - DefOrRef *DOR; + DefOrRef *DOR, *NewDOR; + /* Do we have an entry with this name already? */ SymEntry* Entry = FindSymInTable (LabelTab, Name, HashStr (Name)); if (Entry) { @@ -689,6 +693,8 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) Error ("Label `%s' is defined more than once", Name); } + NewDOR = AddDefOrRef (Entry, Flags); + /* Walk through all occurrences of the label so far and check if any of them is in a region that would be risky to jump from/to from the place where we are right now. */ @@ -698,13 +704,41 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) the one currently being added, i.e. if we are processing the definition, we will only check the gotos; if we are processing a goto statement, we will only look for the label definition. */ + /* if (((DOR->Flags & SC_DEF) != (Flags & SC_DEF)) && + (CollCount(&CurrentFunc->LocalsBlockStack) == DOR->Depth) && (DOR->LocalsBlockNum != (long)CollLast (&CurrentFunc->LocalsBlockStack))) Error ("Goto from line %d to label \'%s\' can result in a " "trashed stack", Flags & SC_DEF ? DOR->Line : GetCurrentLine (), Name); - } + */ + if((DOR->Flags & SC_DEF) && (Flags & SC_REF)) { + /* We're processing a goto and here is its destination label. + This means the difference between SP values is also known, so + we simply emit SP adjustment code. */ + if(StackPtr != DOR->StackPtr) + g_space(StackPtr - DOR->StackPtr); - AddDefOrRef (Entry, Flags); + if (CollCount(&CurrentFunc->LocalsBlockStack) <= DOR->Depth && + DOR->LocalsBlockNum != (long)CollLast (&CurrentFunc->LocalsBlockStack)) { + Warning ("Goto from line %d to label \'%s\' can result in a " + "trashed stack", DOR->Line, Name); + } + } + + if((DOR->Flags & SC_REF) && (Flags & SC_DEF)) { + /* We're processing a label, let's update all gotos encountered + so far */ + g_defdatalabel(DOR->LateSP_Label); + g_defdata(CF_CONST | CF_INT, StackPtr - DOR->StackPtr, 0); + + if (CollCount(&CurrentFunc->LocalsBlockStack) >= DOR->Depth && + DOR->LocalsBlockNum != (long)CollLast (&CurrentFunc->LocalsBlockStack)) { + Warning ("Goto from line %d to label \'%s\' can result in a " + "trashed stack", DOR->Line, Name); + } + } + + } Entry->Flags |= Flags; @@ -718,7 +752,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* Create Collection for label definition and references */ Entry->V.L.DefsOrRefs = NewCollection (); - AddDefOrRef (Entry, Flags); + NewDOR = AddDefOrRef (Entry, Flags); /* Generate the assembler name of the label */ Entry->AsmName = xstrdup (LocalLabelName (Entry->V.L.Label)); @@ -728,6 +762,11 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) } + /* We are processing a goto, but the label has not yet been defined */ + if (!SymIsDef (Entry) && (Flags & SC_REF)) { + g_lateadjustSP(NewDOR->LateSP_Label); + } + /* Return the entry */ return Entry; } From 4b78d40e9788efccb747ae38362b6ce23f32d48f Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Tue, 25 Sep 2018 23:54:45 -0700 Subject: [PATCH 0874/2161] Added testcase for between-blocks gotos. Deleted old testcase. --- test/misc/Makefile | 6 ----- test/misc/goto.c | 65 ---------------------------------------------- test/misc/goto.ref | 6 ----- test/ref/goto.c | 35 +++++++++++++++++++++++++ 4 files changed, 35 insertions(+), 77 deletions(-) delete mode 100644 test/misc/goto.c delete mode 100644 test/misc/goto.ref create mode 100644 test/ref/goto.c diff --git a/test/misc/Makefile b/test/misc/Makefile index 83d6e03ba..330c9d500 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -72,12 +72,6 @@ $(WORKDIR)/limits.$1.$2.prg: limits.c $(DIFF) $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/limits.$1.out $(DIFF) $(WORKDIR)/limits.$1.out limits.ref -# here we check if the right errors are produced -$(WORKDIR)/goto.$1.$2.prg: goto.c $(DIFF) - $(if $(QUIET),echo misc/goto.$1.$2.prg) - $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< 2>$(WORKDIR)/goto.$1.out - $(DIFF) $(WORKDIR)/goto.$1.out goto.ref - # the rest are tests that fail currently for one reason or another $(WORKDIR)/fields.$1.$2.prg: fields.c | $(WORKDIR) @echo "FIXME: " $$@ "currently will fail." diff --git a/test/misc/goto.c b/test/misc/goto.c deleted file mode 100644 index 6d16722e1..000000000 --- a/test/misc/goto.c +++ /dev/null @@ -1,65 +0,0 @@ -#include <stdio.h> -#define false 0 -#define true (!false) - -int main () { - int var = 3; - int quit = false; - - goto finish; - - while (!quit) { - var += 1; - { - if (var % 2) { - int var2 = 2; - int var3 = 4; - goto safe; - goto unsafe; - { - another: - var2 = 0x5599; - safe: - printf ("var2: %d\n", var2); - } - } else { - int var3 = 3; - int x = 4; - goto unsafe; - goto bad; - unused: - printf ("var3: %d\n", var3); - { - int var = 1; - bad: - var++; - if (var < 4) - goto bad; - goto finish; - } - unsafe: - var3 = 4; - goto another; - } - - { - int var = 2; - goto bad; - } - - - var += 1; - if (var >= 10) - goto finish; - } - } -finish: - return var; -} - -int function () { - goto end; - -end: - return 0; -} diff --git a/test/misc/goto.ref b/test/misc/goto.ref deleted file mode 100644 index e319a153f..000000000 --- a/test/misc/goto.ref +++ /dev/null @@ -1,6 +0,0 @@ -goto.c(34): Error: Goto from line 29 to label 'bad' can result in a trashed stack -goto.c(40): Error: Goto from line 18 to label 'unsafe' can result in a trashed stack -goto.c(42): Error: Goto from line 42 to label 'another' can result in a trashed stack -goto.c(47): Error: Goto from line 47 to label 'bad' can result in a trashed stack -goto.c(56): Error: Goto from line 38 to label 'finish' can result in a trashed stack -goto.c(58): Warning: `unused' is defined but never used diff --git a/test/ref/goto.c b/test/ref/goto.c new file mode 100644 index 000000000..3a445e647 --- /dev/null +++ b/test/ref/goto.c @@ -0,0 +1,35 @@ +#include <stdio.h> + +int main () { + char a[200] = "xyz"; + int ctr = 0; +start: + a[ctr] = ctr + 65; + goto second; + + { + char b[64] = "xxx"; + first: + b[0] = ctr + 97; + goto safe; + b[0] = 'Z'; + safe: + printf ("%c%c", a[0], b[0]); + if (ctr++ > 20) + goto end; + else + goto second; + } + { + char c[100] = "aaa"; + second:; + c[0] = '1'; + c[99] = '2'; + goto first; + } +end: + a[ctr] = '\n'; + printf ("\n%s\n", a); + + return 0; +} From c835f4991309385ec9dbb93dc92a08139ae609b9 Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Wed, 26 Sep 2018 00:11:40 -0700 Subject: [PATCH 0875/2161] Clean-up --- src/cc65/symentry.c | 6 ++---- src/cc65/symtab.c | 45 +++++++++++++++++++-------------------------- 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index 8091c4d26..f78c5da80 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -88,10 +88,8 @@ void FreeSymEntry (SymEntry* E) TypeFree (E->Type); xfree (E->AsmName); - if (E->Flags & SC_LABEL) - { - for (i = 0; i < CollCount (E->V.L.DefsOrRefs); i++) - { + if (E->Flags & SC_LABEL) { + for (i = 0; i < CollCount (E->V.L.DefsOrRefs); i++) { xfree (CollAt(E->V.L.DefsOrRefs, i)); } diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index c2edcb344..f7fb07f61 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -671,8 +671,8 @@ DefOrRef* AddDefOrRef(SymEntry* E, unsigned Flags) DOR->LocalsBlockNum = (long)CollLast (&CurrentFunc->LocalsBlockStack); DOR->Flags = Flags; DOR->StackPtr = StackPtr; - DOR->Depth = CollCount(&CurrentFunc->LocalsBlockStack); - DOR->LateSP_Label = GetLocalLabel(); + DOR->Depth = CollCount (&CurrentFunc->LocalsBlockStack); + DOR->LateSP_Label = GetLocalLabel (); return DOR; } @@ -695,30 +695,21 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) NewDOR = AddDefOrRef (Entry, Flags); - /* Walk through all occurrences of the label so far and check - if any of them is in a region that would be risky to jump from/to - from the place where we are right now. */ + /* Walk through all occurrences of the label so far and evaluate + their relationship with the one passed to the function. */ for (i = 0; i < CollCount (Entry->V.L.DefsOrRefs); i++) { DOR = CollAt (Entry->V.L.DefsOrRefs, i); - /* We are only interested in label occurences of type opposite to - the one currently being added, i.e. if we are processing the - definition, we will only check the gotos; if we are processing - a goto statement, we will only look for the label definition. */ - /* - if (((DOR->Flags & SC_DEF) != (Flags & SC_DEF)) && - (CollCount(&CurrentFunc->LocalsBlockStack) == DOR->Depth) && - (DOR->LocalsBlockNum != (long)CollLast (&CurrentFunc->LocalsBlockStack))) - Error ("Goto from line %d to label \'%s\' can result in a " - "trashed stack", Flags & SC_DEF ? DOR->Line : GetCurrentLine (), Name); - */ + if((DOR->Flags & SC_DEF) && (Flags & SC_REF)) { /* We're processing a goto and here is its destination label. - This means the difference between SP values is also known, so - we simply emit SP adjustment code. */ - if(StackPtr != DOR->StackPtr) - g_space(StackPtr - DOR->StackPtr); + This means the difference between SP values is already known, + so we simply emit the SP adjustment code. */ + if(StackPtr != DOR->StackPtr) + g_space (StackPtr - DOR->StackPtr); - if (CollCount(&CurrentFunc->LocalsBlockStack) <= DOR->Depth && + /* Are we jumping into same or deeper nesting region? That's risky, + so let's emit a warning. */ + if (CollCount (&CurrentFunc->LocalsBlockStack) <= DOR->Depth && DOR->LocalsBlockNum != (long)CollLast (&CurrentFunc->LocalsBlockStack)) { Warning ("Goto from line %d to label \'%s\' can result in a " "trashed stack", DOR->Line, Name); @@ -727,11 +718,13 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) if((DOR->Flags & SC_REF) && (Flags & SC_DEF)) { /* We're processing a label, let's update all gotos encountered - so far */ - g_defdatalabel(DOR->LateSP_Label); - g_defdata(CF_CONST | CF_INT, StackPtr - DOR->StackPtr, 0); + so far */ + g_defdatalabel (DOR->LateSP_Label); + g_defdata (CF_CONST | CF_INT, StackPtr - DOR->StackPtr, 0); - if (CollCount(&CurrentFunc->LocalsBlockStack) >= DOR->Depth && + /* Are we jumping into same or deeper nesting region? That's risky, + so let's emit a warning. */ + if (CollCount (&CurrentFunc->LocalsBlockStack) >= DOR->Depth && DOR->LocalsBlockNum != (long)CollLast (&CurrentFunc->LocalsBlockStack)) { Warning ("Goto from line %d to label \'%s\' can result in a " "trashed stack", DOR->Line, Name); @@ -764,7 +757,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* We are processing a goto, but the label has not yet been defined */ if (!SymIsDef (Entry) && (Flags & SC_REF)) { - g_lateadjustSP(NewDOR->LateSP_Label); + g_lateadjustSP (NewDOR->LateSP_Label); } /* Return the entry */ From c797b3b37674938d4ebf0e3eb0c65cbdc98427ac Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Fri, 28 Sep 2018 22:11:09 -0700 Subject: [PATCH 0876/2161] Proper warnings for "risky" gotos. --- src/cc65/function.c | 3 +- src/cc65/function.h | 1 - src/cc65/locals.c | 17 +- src/cc65/stmt.c | 5 +- src/cc65/symentry.c | 2 +- src/cc65/symentry.h | 2 +- src/cc65/symtab.c | 42 +++-- test/misc/Makefile | 5 + test/misc/goto.c | 437 ++++++++++++++++++++++++++++++++++++++++++++ test/misc/goto.ref | 150 +++++++++++++++ 10 files changed, 637 insertions(+), 27 deletions(-) create mode 100644 test/misc/goto.c create mode 100644 test/misc/goto.ref diff --git a/src/cc65/function.c b/src/cc65/function.c index 96b3d6c75..1d63d55c5 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -87,7 +87,6 @@ static Function* NewFunction (struct SymEntry* Sym) F->TopLevelSP = 0; F->RegOffs = RegisterSpace; F->Flags = IsTypeVoid (F->ReturnType) ? FF_VOID_RETURN : FF_NONE; - F->LocalsBlockCount = 0; InitCollection (&F->LocalsBlockStack); @@ -524,6 +523,8 @@ void NewFunc (SymEntry* Func) /* Need a starting curly brace */ ConsumeLCurly (); + + /* Make sure there is always something on the stack of local variable blocks */ CollAppend (&CurrentFunc->LocalsBlockStack, 0); /* Parse local variable declarations if any */ diff --git a/src/cc65/function.h b/src/cc65/function.h index 5c5822045..0954322ac 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -61,7 +61,6 @@ struct Function { int TopLevelSP; /* SP at function top level */ unsigned RegOffs; /* Register variable space offset */ funcflags_t Flags; /* Function flags */ - long LocalsBlockCount; /* Number of blocks with local vars */ Collection LocalsBlockStack; /* Stack of blocks with local vars */ }; diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 20d370c46..d3d73d197 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -52,6 +52,7 @@ #include "standard.h" #include "symtab.h" #include "typeconv.h" +#include "input.h" @@ -270,6 +271,12 @@ static void ParseAutoDecl (Declaration* Decl) /* Mark the variable as referenced */ Sym->Flags |= SC_REF; + /* Make note of auto variables initialized in current block. + We abuse the Collection somewhat by using it to store line + numbers. */ + CollReplace (&CurrentFunc->LocalsBlockStack, (void *)(long)GetCurrentLine (), + CollCount (&CurrentFunc->LocalsBlockStack) - 1); + } else { /* Non-initialized local variable. Just keep track of ** the space needed. @@ -489,6 +496,9 @@ void DeclareLocals (void) /* Remember the current stack pointer */ int InitialStack = StackPtr; + /* A place to store info about potential initializations of auto variables */ + CollAppend (&CurrentFunc->LocalsBlockStack, 0); + /* Loop until we don't find any more variables */ while (1) { @@ -538,10 +548,9 @@ void DeclareLocals (void) /* Be sure to allocate any reserved space for locals */ F_AllocLocalSpace (CurrentFunc); - if (InitialStack != StackPtr) { - ++CurrentFunc->LocalsBlockCount; - /* Is it ok to abuse Collection in this way? */ - CollAppend (&CurrentFunc->LocalsBlockStack, (void *)CurrentFunc->LocalsBlockCount); + /* No auto variables were inited. No new block on the stack then. */ + if (CollLast (&CurrentFunc->LocalsBlockStack) == NULL) { + CollPop (&CurrentFunc->LocalsBlockStack); } /* In case we've allocated local variables in this block, emit a call to diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index b766ec044..0c891c386 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -513,6 +513,7 @@ static int CompoundStatement (void) /* Remember the stack at block entry */ int OldStack = StackPtr; + long OldBlockStackSize = CollCount (&CurrentFunc->LocalsBlockStack); /* Enter a new lexical level */ EnterBlockLevel (); @@ -535,7 +536,9 @@ static int CompoundStatement (void) g_space (StackPtr - OldStack); } - if (OldStack != StackPtr) { + /* If the segment had autoinited variables, let's pop it of a stack + of such blocks. */ + if (OldBlockStackSize != CollCount (&CurrentFunc->LocalsBlockStack)) { CollPop (&CurrentFunc->LocalsBlockStack); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index f78c5da80..18cc026ea 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -90,7 +90,7 @@ void FreeSymEntry (SymEntry* E) if (E->Flags & SC_LABEL) { for (i = 0; i < CollCount (E->V.L.DefsOrRefs); i++) { - xfree (CollAt(E->V.L.DefsOrRefs, i)); + xfree (CollAt (E->V.L.DefsOrRefs, i)); } DoneCollection (E->V.L.DefsOrRefs); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 03a63a7d2..2dc731f35 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -105,7 +105,7 @@ struct LiteralPool; typedef struct DefOrRef DefOrRef; struct DefOrRef { unsigned Line; - long LocalsBlockNum; + long LocalsBlockId; unsigned Flags; int StackPtr; unsigned Depth; diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index f7fb07f61..5ca2d4967 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -668,7 +668,7 @@ DefOrRef* AddDefOrRef(SymEntry* E, unsigned Flags) DOR = xmalloc (sizeof (DefOrRef)); CollAppend (E->V.L.DefsOrRefs, DOR); DOR->Line = GetCurrentLine (); - DOR->LocalsBlockNum = (long)CollLast (&CurrentFunc->LocalsBlockStack); + DOR->LocalsBlockId = (long)CollLast (&CurrentFunc->LocalsBlockStack); DOR->Flags = Flags; DOR->StackPtr = StackPtr; DOR->Depth = CollCount (&CurrentFunc->LocalsBlockStack); @@ -677,12 +677,13 @@ DefOrRef* AddDefOrRef(SymEntry* E, unsigned Flags) return DOR; } - SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* Add a goto label to the label table */ { unsigned i; DefOrRef *DOR, *NewDOR; + /* We juggle it so much that a shortcut will help with clarity */ + Collection *AIC = &CurrentFunc->LocalsBlockStack; /* Do we have an entry with this name already? */ SymEntry* Entry = FindSymInTable (LabelTab, Name, HashStr (Name)); @@ -700,35 +701,40 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) for (i = 0; i < CollCount (Entry->V.L.DefsOrRefs); i++) { DOR = CollAt (Entry->V.L.DefsOrRefs, i); - if((DOR->Flags & SC_DEF) && (Flags & SC_REF)) { + if ((DOR->Flags & SC_DEF) && (Flags & SC_REF)) { /* We're processing a goto and here is its destination label. This means the difference between SP values is already known, so we simply emit the SP adjustment code. */ - if(StackPtr != DOR->StackPtr) + if (StackPtr != DOR->StackPtr) { g_space (StackPtr - DOR->StackPtr); + } - /* Are we jumping into same or deeper nesting region? That's risky, - so let's emit a warning. */ - if (CollCount (&CurrentFunc->LocalsBlockStack) <= DOR->Depth && - DOR->LocalsBlockNum != (long)CollLast (&CurrentFunc->LocalsBlockStack)) { - Warning ("Goto from line %d to label \'%s\' can result in a " - "trashed stack", DOR->Line, Name); + /* Are we jumping into a block with initalization of an object that + has automatic storage duration? Let's emit a warning. */ + if ((long)CollLast (AIC) != DOR->LocalsBlockId && + (CollCount (AIC) < DOR->Depth || + (long)CollAt (AIC, DOR->Depth - 1) != DOR->LocalsBlockId)) { + Warning ("Goto at line %d to label %s jumps into a block with " + "initialization of an object that has automatic storage duration.", + GetCurrentLine (), Name); } } - if((DOR->Flags & SC_REF) && (Flags & SC_DEF)) { + + if ((DOR->Flags & SC_REF) && (Flags & SC_DEF)) { /* We're processing a label, let's update all gotos encountered so far */ g_defdatalabel (DOR->LateSP_Label); g_defdata (CF_CONST | CF_INT, StackPtr - DOR->StackPtr, 0); - /* Are we jumping into same or deeper nesting region? That's risky, - so let's emit a warning. */ - if (CollCount (&CurrentFunc->LocalsBlockStack) >= DOR->Depth && - DOR->LocalsBlockNum != (long)CollLast (&CurrentFunc->LocalsBlockStack)) { - Warning ("Goto from line %d to label \'%s\' can result in a " - "trashed stack", DOR->Line, Name); - } + /* Are we jumping into a block with initalization of an object that + has automatic storage duration? Let's emit a warning. */ + if ((long)CollLast (AIC) != DOR->LocalsBlockId && + (CollCount (AIC) >= DOR->Depth || + (long)CollLast (AIC) >= DOR->Line)) + Warning ("Goto at line %d to label %s jumps into a block with " + "initialization of an object that has automatic storage duration.", + DOR->Line, Name); } } diff --git a/test/misc/Makefile b/test/misc/Makefile index 330c9d500..ad39176bd 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -72,6 +72,11 @@ $(WORKDIR)/limits.$1.$2.prg: limits.c $(DIFF) $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/limits.$1.out $(DIFF) $(WORKDIR)/limits.$1.out limits.ref +$(WORKDIR)/goto.$1.$2.prg: goto.c $(DIFF) + $(if $(QUIET),echo misc/goto.$1.$2.prg) + $(CL65) -t sim$2 -$1 -o $$@ $$< 2>$(WORKDIR)/goto.$1.out + $(DIFF) $(WORKDIR)/goto.$1.out goto.ref + # the rest are tests that fail currently for one reason or another $(WORKDIR)/fields.$1.$2.prg: fields.c | $(WORKDIR) @echo "FIXME: " $$@ "currently will fail." diff --git a/test/misc/goto.c b/test/misc/goto.c new file mode 100644 index 000000000..69247a4df --- /dev/null +++ b/test/misc/goto.c @@ -0,0 +1,437 @@ +void main () { + goto end; + { + int a = 1; +start: + goto end; + } + goto start; +end:; +} + +void f2 () { + int a = 2; + +l1: + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; + { + int a; + l2:; + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; + { + int a; + l3:; + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; + { + int a; + l4:; + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; + } + l5:; + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; + } + l6:; + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; + } +l7:; + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; + { + int a = 1; + l8:; + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; + { + int a = 1; + l9:; + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; + { + int a = 1; + la:; + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; + } + lb:; + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; + } + lc:; + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; + } + { + int a = 1; + ld:; + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; + { + int a = 1; + le:; + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; + { + int a = 1; + lf:; + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; + } + lg:; + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; + } + lh:; + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; + } +li:; + goto l1; + goto l2; + goto l3; + goto l4; + goto l5; + goto l6; + goto l7; + goto l8; + goto l9; + goto la; + goto lb; + goto lc; + goto ld; + goto le; + goto lf; + goto lg; + goto lh; + goto li; +} + +/* Structure of the above function. + +void f2 () { + int a = 2; + +l1: + { + int a; + l2:; + { + int a; + l3:; + { + int a; + l4:; + } + l5:; + } + l6:; + } +l7:; + { + int a = 1; + l8:; + { + int a = 1; + l9:; + { + int a = 1; + la:; + } + lb:; + } + lc:; + } + { + int a = 1; + ld:; + { + int a = 1; + le:; + { + int a = 1; + lf:; + } + lg:; + } + lh:; + } +li:; +} +*/ diff --git a/test/misc/goto.ref b/test/misc/goto.ref new file mode 100644 index 000000000..0f57d97ba --- /dev/null +++ b/test/misc/goto.ref @@ -0,0 +1,150 @@ +goto.c(8): Warning: Goto at line 8 to label start jumps into a block with initialization of an object that has automatic storage duration. +goto.c(97): Warning: `a' is defined but never used +goto.c(117): Warning: `a' is defined but never used +goto.c(137): Warning: `a' is defined but never used +goto.c(159): Warning: Goto at line 23 to label l8 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(159): Warning: Goto at line 44 to label l8 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(159): Warning: Goto at line 65 to label l8 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(159): Warning: Goto at line 86 to label l8 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(159): Warning: Goto at line 106 to label l8 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(159): Warning: Goto at line 126 to label l8 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(159): Warning: Goto at line 146 to label l8 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(180): Warning: Goto at line 24 to label l9 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(180): Warning: Goto at line 45 to label l9 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(180): Warning: Goto at line 66 to label l9 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(180): Warning: Goto at line 87 to label l9 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(180): Warning: Goto at line 107 to label l9 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(180): Warning: Goto at line 127 to label l9 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(180): Warning: Goto at line 147 to label l9 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(180): Warning: Goto at line 168 to label l9 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(201): Warning: Goto at line 25 to label la jumps into a block with initialization of an object that has automatic storage duration. +goto.c(201): Warning: Goto at line 46 to label la jumps into a block with initialization of an object that has automatic storage duration. +goto.c(201): Warning: Goto at line 67 to label la jumps into a block with initialization of an object that has automatic storage duration. +goto.c(201): Warning: Goto at line 88 to label la jumps into a block with initialization of an object that has automatic storage duration. +goto.c(201): Warning: Goto at line 108 to label la jumps into a block with initialization of an object that has automatic storage duration. +goto.c(201): Warning: Goto at line 128 to label la jumps into a block with initialization of an object that has automatic storage duration. +goto.c(201): Warning: Goto at line 148 to label la jumps into a block with initialization of an object that has automatic storage duration. +goto.c(201): Warning: Goto at line 169 to label la jumps into a block with initialization of an object that has automatic storage duration. +goto.c(201): Warning: Goto at line 190 to label la jumps into a block with initialization of an object that has automatic storage duration. +goto.c(221): Warning: Goto at line 26 to label lb jumps into a block with initialization of an object that has automatic storage duration. +goto.c(221): Warning: Goto at line 47 to label lb jumps into a block with initialization of an object that has automatic storage duration. +goto.c(221): Warning: Goto at line 68 to label lb jumps into a block with initialization of an object that has automatic storage duration. +goto.c(221): Warning: Goto at line 89 to label lb jumps into a block with initialization of an object that has automatic storage duration. +goto.c(221): Warning: Goto at line 109 to label lb jumps into a block with initialization of an object that has automatic storage duration. +goto.c(221): Warning: Goto at line 129 to label lb jumps into a block with initialization of an object that has automatic storage duration. +goto.c(221): Warning: Goto at line 149 to label lb jumps into a block with initialization of an object that has automatic storage duration. +goto.c(221): Warning: Goto at line 170 to label lb jumps into a block with initialization of an object that has automatic storage duration. +goto.c(231): Warning: Goto at line 231 to label la jumps into a block with initialization of an object that has automatic storage duration. +goto.c(241): Warning: Goto at line 27 to label lc jumps into a block with initialization of an object that has automatic storage duration. +goto.c(241): Warning: Goto at line 48 to label lc jumps into a block with initialization of an object that has automatic storage duration. +goto.c(241): Warning: Goto at line 69 to label lc jumps into a block with initialization of an object that has automatic storage duration. +goto.c(241): Warning: Goto at line 90 to label lc jumps into a block with initialization of an object that has automatic storage duration. +goto.c(241): Warning: Goto at line 110 to label lc jumps into a block with initialization of an object that has automatic storage duration. +goto.c(241): Warning: Goto at line 130 to label lc jumps into a block with initialization of an object that has automatic storage duration. +goto.c(241): Warning: Goto at line 150 to label lc jumps into a block with initialization of an object that has automatic storage duration. +goto.c(250): Warning: Goto at line 250 to label l9 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(251): Warning: Goto at line 251 to label la jumps into a block with initialization of an object that has automatic storage duration. +goto.c(252): Warning: Goto at line 252 to label lb jumps into a block with initialization of an object that has automatic storage duration. +goto.c(263): Warning: Goto at line 28 to label ld jumps into a block with initialization of an object that has automatic storage duration. +goto.c(263): Warning: Goto at line 49 to label ld jumps into a block with initialization of an object that has automatic storage duration. +goto.c(263): Warning: Goto at line 70 to label ld jumps into a block with initialization of an object that has automatic storage duration. +goto.c(263): Warning: Goto at line 91 to label ld jumps into a block with initialization of an object that has automatic storage duration. +goto.c(263): Warning: Goto at line 111 to label ld jumps into a block with initialization of an object that has automatic storage duration. +goto.c(263): Warning: Goto at line 131 to label ld jumps into a block with initialization of an object that has automatic storage duration. +goto.c(263): Warning: Goto at line 151 to label ld jumps into a block with initialization of an object that has automatic storage duration. +goto.c(263): Warning: Goto at line 172 to label ld jumps into a block with initialization of an object that has automatic storage duration. +goto.c(263): Warning: Goto at line 193 to label ld jumps into a block with initialization of an object that has automatic storage duration. +goto.c(263): Warning: Goto at line 214 to label ld jumps into a block with initialization of an object that has automatic storage duration. +goto.c(263): Warning: Goto at line 234 to label ld jumps into a block with initialization of an object that has automatic storage duration. +goto.c(263): Warning: Goto at line 254 to label ld jumps into a block with initialization of an object that has automatic storage duration. +goto.c(271): Warning: Goto at line 271 to label l8 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(272): Warning: Goto at line 272 to label l9 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(273): Warning: Goto at line 273 to label la jumps into a block with initialization of an object that has automatic storage duration. +goto.c(274): Warning: Goto at line 274 to label lb jumps into a block with initialization of an object that has automatic storage duration. +goto.c(275): Warning: Goto at line 275 to label lc jumps into a block with initialization of an object that has automatic storage duration. +goto.c(284): Warning: Goto at line 29 to label le jumps into a block with initialization of an object that has automatic storage duration. +goto.c(284): Warning: Goto at line 50 to label le jumps into a block with initialization of an object that has automatic storage duration. +goto.c(284): Warning: Goto at line 71 to label le jumps into a block with initialization of an object that has automatic storage duration. +goto.c(284): Warning: Goto at line 92 to label le jumps into a block with initialization of an object that has automatic storage duration. +goto.c(284): Warning: Goto at line 112 to label le jumps into a block with initialization of an object that has automatic storage duration. +goto.c(284): Warning: Goto at line 132 to label le jumps into a block with initialization of an object that has automatic storage duration. +goto.c(284): Warning: Goto at line 152 to label le jumps into a block with initialization of an object that has automatic storage duration. +goto.c(284): Warning: Goto at line 173 to label le jumps into a block with initialization of an object that has automatic storage duration. +goto.c(284): Warning: Goto at line 194 to label le jumps into a block with initialization of an object that has automatic storage duration. +goto.c(284): Warning: Goto at line 215 to label le jumps into a block with initialization of an object that has automatic storage duration. +goto.c(284): Warning: Goto at line 235 to label le jumps into a block with initialization of an object that has automatic storage duration. +goto.c(284): Warning: Goto at line 255 to label le jumps into a block with initialization of an object that has automatic storage duration. +goto.c(284): Warning: Goto at line 277 to label le jumps into a block with initialization of an object that has automatic storage duration. +goto.c(292): Warning: Goto at line 292 to label l8 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(293): Warning: Goto at line 293 to label l9 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(294): Warning: Goto at line 294 to label la jumps into a block with initialization of an object that has automatic storage duration. +goto.c(295): Warning: Goto at line 295 to label lb jumps into a block with initialization of an object that has automatic storage duration. +goto.c(296): Warning: Goto at line 296 to label lc jumps into a block with initialization of an object that has automatic storage duration. +goto.c(305): Warning: Goto at line 30 to label lf jumps into a block with initialization of an object that has automatic storage duration. +goto.c(305): Warning: Goto at line 51 to label lf jumps into a block with initialization of an object that has automatic storage duration. +goto.c(305): Warning: Goto at line 72 to label lf jumps into a block with initialization of an object that has automatic storage duration. +goto.c(305): Warning: Goto at line 93 to label lf jumps into a block with initialization of an object that has automatic storage duration. +goto.c(305): Warning: Goto at line 113 to label lf jumps into a block with initialization of an object that has automatic storage duration. +goto.c(305): Warning: Goto at line 133 to label lf jumps into a block with initialization of an object that has automatic storage duration. +goto.c(305): Warning: Goto at line 153 to label lf jumps into a block with initialization of an object that has automatic storage duration. +goto.c(305): Warning: Goto at line 174 to label lf jumps into a block with initialization of an object that has automatic storage duration. +goto.c(305): Warning: Goto at line 195 to label lf jumps into a block with initialization of an object that has automatic storage duration. +goto.c(305): Warning: Goto at line 216 to label lf jumps into a block with initialization of an object that has automatic storage duration. +goto.c(305): Warning: Goto at line 236 to label lf jumps into a block with initialization of an object that has automatic storage duration. +goto.c(305): Warning: Goto at line 256 to label lf jumps into a block with initialization of an object that has automatic storage duration. +goto.c(305): Warning: Goto at line 278 to label lf jumps into a block with initialization of an object that has automatic storage duration. +goto.c(305): Warning: Goto at line 299 to label lf jumps into a block with initialization of an object that has automatic storage duration. +goto.c(313): Warning: Goto at line 313 to label l8 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(314): Warning: Goto at line 314 to label l9 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(315): Warning: Goto at line 315 to label la jumps into a block with initialization of an object that has automatic storage duration. +goto.c(316): Warning: Goto at line 316 to label lb jumps into a block with initialization of an object that has automatic storage duration. +goto.c(317): Warning: Goto at line 317 to label lc jumps into a block with initialization of an object that has automatic storage duration. +goto.c(325): Warning: Goto at line 31 to label lg jumps into a block with initialization of an object that has automatic storage duration. +goto.c(325): Warning: Goto at line 52 to label lg jumps into a block with initialization of an object that has automatic storage duration. +goto.c(325): Warning: Goto at line 73 to label lg jumps into a block with initialization of an object that has automatic storage duration. +goto.c(325): Warning: Goto at line 94 to label lg jumps into a block with initialization of an object that has automatic storage duration. +goto.c(325): Warning: Goto at line 114 to label lg jumps into a block with initialization of an object that has automatic storage duration. +goto.c(325): Warning: Goto at line 134 to label lg jumps into a block with initialization of an object that has automatic storage duration. +goto.c(325): Warning: Goto at line 154 to label lg jumps into a block with initialization of an object that has automatic storage duration. +goto.c(325): Warning: Goto at line 175 to label lg jumps into a block with initialization of an object that has automatic storage duration. +goto.c(325): Warning: Goto at line 196 to label lg jumps into a block with initialization of an object that has automatic storage duration. +goto.c(325): Warning: Goto at line 217 to label lg jumps into a block with initialization of an object that has automatic storage duration. +goto.c(325): Warning: Goto at line 237 to label lg jumps into a block with initialization of an object that has automatic storage duration. +goto.c(325): Warning: Goto at line 257 to label lg jumps into a block with initialization of an object that has automatic storage duration. +goto.c(325): Warning: Goto at line 279 to label lg jumps into a block with initialization of an object that has automatic storage duration. +goto.c(333): Warning: Goto at line 333 to label l8 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(334): Warning: Goto at line 334 to label l9 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(335): Warning: Goto at line 335 to label la jumps into a block with initialization of an object that has automatic storage duration. +goto.c(336): Warning: Goto at line 336 to label lb jumps into a block with initialization of an object that has automatic storage duration. +goto.c(337): Warning: Goto at line 337 to label lc jumps into a block with initialization of an object that has automatic storage duration. +goto.c(340): Warning: Goto at line 340 to label lf jumps into a block with initialization of an object that has automatic storage duration. +goto.c(345): Warning: Goto at line 32 to label lh jumps into a block with initialization of an object that has automatic storage duration. +goto.c(345): Warning: Goto at line 53 to label lh jumps into a block with initialization of an object that has automatic storage duration. +goto.c(345): Warning: Goto at line 74 to label lh jumps into a block with initialization of an object that has automatic storage duration. +goto.c(345): Warning: Goto at line 95 to label lh jumps into a block with initialization of an object that has automatic storage duration. +goto.c(345): Warning: Goto at line 115 to label lh jumps into a block with initialization of an object that has automatic storage duration. +goto.c(345): Warning: Goto at line 135 to label lh jumps into a block with initialization of an object that has automatic storage duration. +goto.c(345): Warning: Goto at line 155 to label lh jumps into a block with initialization of an object that has automatic storage duration. +goto.c(345): Warning: Goto at line 176 to label lh jumps into a block with initialization of an object that has automatic storage duration. +goto.c(345): Warning: Goto at line 197 to label lh jumps into a block with initialization of an object that has automatic storage duration. +goto.c(345): Warning: Goto at line 218 to label lh jumps into a block with initialization of an object that has automatic storage duration. +goto.c(345): Warning: Goto at line 238 to label lh jumps into a block with initialization of an object that has automatic storage duration. +goto.c(345): Warning: Goto at line 258 to label lh jumps into a block with initialization of an object that has automatic storage duration. +goto.c(353): Warning: Goto at line 353 to label l8 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(354): Warning: Goto at line 354 to label l9 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(355): Warning: Goto at line 355 to label la jumps into a block with initialization of an object that has automatic storage duration. +goto.c(356): Warning: Goto at line 356 to label lb jumps into a block with initialization of an object that has automatic storage duration. +goto.c(357): Warning: Goto at line 357 to label lc jumps into a block with initialization of an object that has automatic storage duration. +goto.c(359): Warning: Goto at line 359 to label le jumps into a block with initialization of an object that has automatic storage duration. +goto.c(360): Warning: Goto at line 360 to label lf jumps into a block with initialization of an object that has automatic storage duration. +goto.c(361): Warning: Goto at line 361 to label lg jumps into a block with initialization of an object that has automatic storage duration. +goto.c(373): Warning: Goto at line 373 to label l8 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(374): Warning: Goto at line 374 to label l9 jumps into a block with initialization of an object that has automatic storage duration. +goto.c(375): Warning: Goto at line 375 to label la jumps into a block with initialization of an object that has automatic storage duration. +goto.c(376): Warning: Goto at line 376 to label lb jumps into a block with initialization of an object that has automatic storage duration. +goto.c(377): Warning: Goto at line 377 to label lc jumps into a block with initialization of an object that has automatic storage duration. +goto.c(378): Warning: Goto at line 378 to label ld jumps into a block with initialization of an object that has automatic storage duration. +goto.c(379): Warning: Goto at line 379 to label le jumps into a block with initialization of an object that has automatic storage duration. +goto.c(380): Warning: Goto at line 380 to label lf jumps into a block with initialization of an object that has automatic storage duration. +goto.c(381): Warning: Goto at line 381 to label lg jumps into a block with initialization of an object that has automatic storage duration. +goto.c(382): Warning: Goto at line 382 to label lh jumps into a block with initialization of an object that has automatic storage duration. From 6ad79067ac0f0172ea4a7b373de92affe07ec575 Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Fri, 28 Sep 2018 22:17:49 -0700 Subject: [PATCH 0877/2161] Fix a warning. --- src/cc65/stmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 0c891c386..a9552ba96 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -513,7 +513,7 @@ static int CompoundStatement (void) /* Remember the stack at block entry */ int OldStack = StackPtr; - long OldBlockStackSize = CollCount (&CurrentFunc->LocalsBlockStack); + unsigned OldBlockStackSize = CollCount (&CurrentFunc->LocalsBlockStack); /* Enter a new lexical level */ EnterBlockLevel (); From 8845e71161bfffbb4eea7bf4957fa226e31dc29a Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Fri, 28 Sep 2018 22:25:22 -0700 Subject: [PATCH 0878/2161] Another warning. --- 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 5ca2d4967..9a34de0dc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -731,7 +731,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) has automatic storage duration? Let's emit a warning. */ if ((long)CollLast (AIC) != DOR->LocalsBlockId && (CollCount (AIC) >= DOR->Depth || - (long)CollLast (AIC) >= DOR->Line)) + (long)CollLast (AIC) >= (long)DOR->Line)) Warning ("Goto at line %d to label %s jumps into a block with " "initialization of an object that has automatic storage duration.", DOR->Line, Name); From 2ec21c5b7f5b875171b581380d4ee6ed5990b4ac Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Sat, 29 Sep 2018 12:06:33 -0700 Subject: [PATCH 0879/2161] Fix non-goto jumps (i.e. inline assembly). --- src/cc65/goto.c | 2 +- src/cc65/symentry.h | 2 ++ src/cc65/symtab.c | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cc65/goto.c b/src/cc65/goto.c index 3b1d243e7..ae9e6096d 100644 --- a/src/cc65/goto.c +++ b/src/cc65/goto.c @@ -61,7 +61,7 @@ void GotoStatement (void) } else { /* Add a new label symbol if we don't have one until now */ - SymEntry* Entry = AddLabelSym (CurTok.Ident, SC_REF); + SymEntry* Entry = AddLabelSym (CurTok.Ident, SC_REF | SC_GOTO); /* Jump to the label */ g_jump (Entry->V.L.Label); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 2dc731f35..e978274dc 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -98,6 +98,8 @@ struct LiteralPool; #define SC_HAVEATTR 0x10000U /* Symbol has attributes */ +#define SC_GOTO 0x20000U + diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 9a34de0dc..d76729cd8 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -701,7 +701,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) for (i = 0; i < CollCount (Entry->V.L.DefsOrRefs); i++) { DOR = CollAt (Entry->V.L.DefsOrRefs, i); - if ((DOR->Flags & SC_DEF) && (Flags & SC_REF)) { + if ((DOR->Flags & SC_DEF) && (Flags & SC_REF) && (Flags & SC_GOTO)) { /* We're processing a goto and here is its destination label. This means the difference between SP values is already known, so we simply emit the SP adjustment code. */ @@ -721,7 +721,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) } - if ((DOR->Flags & SC_REF) && (Flags & SC_DEF)) { + if ((DOR->Flags & SC_REF) && (DOR->Flags & SC_GOTO) && (Flags & SC_DEF)) { /* We're processing a label, let's update all gotos encountered so far */ g_defdatalabel (DOR->LateSP_Label); @@ -762,7 +762,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) } /* We are processing a goto, but the label has not yet been defined */ - if (!SymIsDef (Entry) && (Flags & SC_REF)) { + if (!SymIsDef (Entry) && (Flags & SC_REF) && (Flags & SC_GOTO)) { g_lateadjustSP (NewDOR->LateSP_Label); } From 02a914625be6fec56fd79eef47ab6df6a2f46779 Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Sun, 30 Sep 2018 14:22:23 -0700 Subject: [PATCH 0880/2161] Formatting fixes. --- src/cc65/function.c | 16 ++++++++-------- src/cc65/locals.c | 5 +++-- src/cc65/stmt.c | 3 ++- src/cc65/symtab.c | 21 +++++++++++++-------- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/cc65/function.c b/src/cc65/function.c index 1d63d55c5..97d6916ff 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -79,14 +79,14 @@ static Function* NewFunction (struct SymEntry* Sym) Function* F = (Function*) xmalloc (sizeof (Function)); /* Initialize the fields */ - F->FuncEntry = Sym; - F->ReturnType = GetFuncReturn (Sym->Type); - F->Desc = GetFuncDesc (Sym->Type); - F->Reserved = 0; - F->RetLab = GetLocalLabel (); - F->TopLevelSP = 0; - F->RegOffs = RegisterSpace; - F->Flags = IsTypeVoid (F->ReturnType) ? FF_VOID_RETURN : FF_NONE; + F->FuncEntry = Sym; + F->ReturnType = GetFuncReturn (Sym->Type); + F->Desc = GetFuncDesc (Sym->Type); + F->Reserved = 0; + F->RetLab = GetLocalLabel (); + F->TopLevelSP = 0; + F->RegOffs = RegisterSpace; + F->Flags = IsTypeVoid (F->ReturnType) ? FF_VOID_RETURN : FF_NONE; InitCollection (&F->LocalsBlockStack); diff --git a/src/cc65/locals.c b/src/cc65/locals.c index d3d73d197..36afb6223 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -272,8 +272,9 @@ static void ParseAutoDecl (Declaration* Decl) Sym->Flags |= SC_REF; /* Make note of auto variables initialized in current block. - We abuse the Collection somewhat by using it to store line - numbers. */ + ** We abuse the Collection somewhat by using it to store line + ** numbers. + */ CollReplace (&CurrentFunc->LocalsBlockStack, (void *)(long)GetCurrentLine (), CollCount (&CurrentFunc->LocalsBlockStack) - 1); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index a9552ba96..14169671b 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -537,7 +537,8 @@ static int CompoundStatement (void) } /* If the segment had autoinited variables, let's pop it of a stack - of such blocks. */ + ** of such blocks. + */ if (OldBlockStackSize != CollCount (&CurrentFunc->LocalsBlockStack)) { CollPop (&CurrentFunc->LocalsBlockStack); } diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index d76729cd8..22a63b893 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -697,25 +697,28 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) NewDOR = AddDefOrRef (Entry, Flags); /* Walk through all occurrences of the label so far and evaluate - their relationship with the one passed to the function. */ + ** their relationship with the one passed to the function. + */ for (i = 0; i < CollCount (Entry->V.L.DefsOrRefs); i++) { DOR = CollAt (Entry->V.L.DefsOrRefs, i); if ((DOR->Flags & SC_DEF) && (Flags & SC_REF) && (Flags & SC_GOTO)) { /* We're processing a goto and here is its destination label. - This means the difference between SP values is already known, - so we simply emit the SP adjustment code. */ + ** This means the difference between SP values is already known, + ** so we simply emit the SP adjustment code. + */ if (StackPtr != DOR->StackPtr) { g_space (StackPtr - DOR->StackPtr); } /* Are we jumping into a block with initalization of an object that - has automatic storage duration? Let's emit a warning. */ + ** has automatic storage duration? Let's emit a warning. + */ if ((long)CollLast (AIC) != DOR->LocalsBlockId && (CollCount (AIC) < DOR->Depth || (long)CollAt (AIC, DOR->Depth - 1) != DOR->LocalsBlockId)) { Warning ("Goto at line %d to label %s jumps into a block with " - "initialization of an object that has automatic storage duration.", + "initialization of an object that has automatic storage duration", GetCurrentLine (), Name); } } @@ -723,17 +726,19 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) if ((DOR->Flags & SC_REF) && (DOR->Flags & SC_GOTO) && (Flags & SC_DEF)) { /* We're processing a label, let's update all gotos encountered - so far */ + ** so far + */ g_defdatalabel (DOR->LateSP_Label); g_defdata (CF_CONST | CF_INT, StackPtr - DOR->StackPtr, 0); /* Are we jumping into a block with initalization of an object that - has automatic storage duration? Let's emit a warning. */ + ** has automatic storage duration? Let's emit a warning. + */ if ((long)CollLast (AIC) != DOR->LocalsBlockId && (CollCount (AIC) >= DOR->Depth || (long)CollLast (AIC) >= (long)DOR->Line)) Warning ("Goto at line %d to label %s jumps into a block with " - "initialization of an object that has automatic storage duration.", + "initialization of an object that has automatic storage duration", DOR->Line, Name); } From 2bb4abda23f5adfaf0e26f136e28790fc19f9b45 Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Sun, 30 Sep 2018 14:30:48 -0700 Subject: [PATCH 0881/2161] Testcase .ref updated for new warning style. --- test/misc/goto.ref | 294 ++++++++++++++++++++++----------------------- 1 file changed, 147 insertions(+), 147 deletions(-) diff --git a/test/misc/goto.ref b/test/misc/goto.ref index 0f57d97ba..ad69cdfe2 100644 --- a/test/misc/goto.ref +++ b/test/misc/goto.ref @@ -1,150 +1,150 @@ -goto.c(8): Warning: Goto at line 8 to label start jumps into a block with initialization of an object that has automatic storage duration. +goto.c(8): Warning: Goto at line 8 to label start jumps into a block with initialization of an object that has automatic storage duration goto.c(97): Warning: `a' is defined but never used goto.c(117): Warning: `a' is defined but never used goto.c(137): Warning: `a' is defined but never used -goto.c(159): Warning: Goto at line 23 to label l8 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(159): Warning: Goto at line 44 to label l8 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(159): Warning: Goto at line 65 to label l8 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(159): Warning: Goto at line 86 to label l8 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(159): Warning: Goto at line 106 to label l8 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(159): Warning: Goto at line 126 to label l8 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(159): Warning: Goto at line 146 to label l8 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(180): Warning: Goto at line 24 to label l9 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(180): Warning: Goto at line 45 to label l9 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(180): Warning: Goto at line 66 to label l9 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(180): Warning: Goto at line 87 to label l9 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(180): Warning: Goto at line 107 to label l9 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(180): Warning: Goto at line 127 to label l9 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(180): Warning: Goto at line 147 to label l9 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(180): Warning: Goto at line 168 to label l9 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(201): Warning: Goto at line 25 to label la jumps into a block with initialization of an object that has automatic storage duration. -goto.c(201): Warning: Goto at line 46 to label la jumps into a block with initialization of an object that has automatic storage duration. -goto.c(201): Warning: Goto at line 67 to label la jumps into a block with initialization of an object that has automatic storage duration. -goto.c(201): Warning: Goto at line 88 to label la jumps into a block with initialization of an object that has automatic storage duration. -goto.c(201): Warning: Goto at line 108 to label la jumps into a block with initialization of an object that has automatic storage duration. -goto.c(201): Warning: Goto at line 128 to label la jumps into a block with initialization of an object that has automatic storage duration. -goto.c(201): Warning: Goto at line 148 to label la jumps into a block with initialization of an object that has automatic storage duration. -goto.c(201): Warning: Goto at line 169 to label la jumps into a block with initialization of an object that has automatic storage duration. -goto.c(201): Warning: Goto at line 190 to label la jumps into a block with initialization of an object that has automatic storage duration. -goto.c(221): Warning: Goto at line 26 to label lb jumps into a block with initialization of an object that has automatic storage duration. -goto.c(221): Warning: Goto at line 47 to label lb jumps into a block with initialization of an object that has automatic storage duration. -goto.c(221): Warning: Goto at line 68 to label lb jumps into a block with initialization of an object that has automatic storage duration. -goto.c(221): Warning: Goto at line 89 to label lb jumps into a block with initialization of an object that has automatic storage duration. -goto.c(221): Warning: Goto at line 109 to label lb jumps into a block with initialization of an object that has automatic storage duration. -goto.c(221): Warning: Goto at line 129 to label lb jumps into a block with initialization of an object that has automatic storage duration. -goto.c(221): Warning: Goto at line 149 to label lb jumps into a block with initialization of an object that has automatic storage duration. -goto.c(221): Warning: Goto at line 170 to label lb jumps into a block with initialization of an object that has automatic storage duration. -goto.c(231): Warning: Goto at line 231 to label la jumps into a block with initialization of an object that has automatic storage duration. -goto.c(241): Warning: Goto at line 27 to label lc jumps into a block with initialization of an object that has automatic storage duration. -goto.c(241): Warning: Goto at line 48 to label lc jumps into a block with initialization of an object that has automatic storage duration. -goto.c(241): Warning: Goto at line 69 to label lc jumps into a block with initialization of an object that has automatic storage duration. -goto.c(241): Warning: Goto at line 90 to label lc jumps into a block with initialization of an object that has automatic storage duration. -goto.c(241): Warning: Goto at line 110 to label lc jumps into a block with initialization of an object that has automatic storage duration. -goto.c(241): Warning: Goto at line 130 to label lc jumps into a block with initialization of an object that has automatic storage duration. -goto.c(241): Warning: Goto at line 150 to label lc jumps into a block with initialization of an object that has automatic storage duration. -goto.c(250): Warning: Goto at line 250 to label l9 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(251): Warning: Goto at line 251 to label la jumps into a block with initialization of an object that has automatic storage duration. -goto.c(252): Warning: Goto at line 252 to label lb jumps into a block with initialization of an object that has automatic storage duration. -goto.c(263): Warning: Goto at line 28 to label ld jumps into a block with initialization of an object that has automatic storage duration. -goto.c(263): Warning: Goto at line 49 to label ld jumps into a block with initialization of an object that has automatic storage duration. -goto.c(263): Warning: Goto at line 70 to label ld jumps into a block with initialization of an object that has automatic storage duration. -goto.c(263): Warning: Goto at line 91 to label ld jumps into a block with initialization of an object that has automatic storage duration. -goto.c(263): Warning: Goto at line 111 to label ld jumps into a block with initialization of an object that has automatic storage duration. -goto.c(263): Warning: Goto at line 131 to label ld jumps into a block with initialization of an object that has automatic storage duration. -goto.c(263): Warning: Goto at line 151 to label ld jumps into a block with initialization of an object that has automatic storage duration. -goto.c(263): Warning: Goto at line 172 to label ld jumps into a block with initialization of an object that has automatic storage duration. -goto.c(263): Warning: Goto at line 193 to label ld jumps into a block with initialization of an object that has automatic storage duration. -goto.c(263): Warning: Goto at line 214 to label ld jumps into a block with initialization of an object that has automatic storage duration. -goto.c(263): Warning: Goto at line 234 to label ld jumps into a block with initialization of an object that has automatic storage duration. -goto.c(263): Warning: Goto at line 254 to label ld jumps into a block with initialization of an object that has automatic storage duration. -goto.c(271): Warning: Goto at line 271 to label l8 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(272): Warning: Goto at line 272 to label l9 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(273): Warning: Goto at line 273 to label la jumps into a block with initialization of an object that has automatic storage duration. -goto.c(274): Warning: Goto at line 274 to label lb jumps into a block with initialization of an object that has automatic storage duration. -goto.c(275): Warning: Goto at line 275 to label lc jumps into a block with initialization of an object that has automatic storage duration. -goto.c(284): Warning: Goto at line 29 to label le jumps into a block with initialization of an object that has automatic storage duration. -goto.c(284): Warning: Goto at line 50 to label le jumps into a block with initialization of an object that has automatic storage duration. -goto.c(284): Warning: Goto at line 71 to label le jumps into a block with initialization of an object that has automatic storage duration. -goto.c(284): Warning: Goto at line 92 to label le jumps into a block with initialization of an object that has automatic storage duration. -goto.c(284): Warning: Goto at line 112 to label le jumps into a block with initialization of an object that has automatic storage duration. -goto.c(284): Warning: Goto at line 132 to label le jumps into a block with initialization of an object that has automatic storage duration. -goto.c(284): Warning: Goto at line 152 to label le jumps into a block with initialization of an object that has automatic storage duration. -goto.c(284): Warning: Goto at line 173 to label le jumps into a block with initialization of an object that has automatic storage duration. -goto.c(284): Warning: Goto at line 194 to label le jumps into a block with initialization of an object that has automatic storage duration. -goto.c(284): Warning: Goto at line 215 to label le jumps into a block with initialization of an object that has automatic storage duration. -goto.c(284): Warning: Goto at line 235 to label le jumps into a block with initialization of an object that has automatic storage duration. -goto.c(284): Warning: Goto at line 255 to label le jumps into a block with initialization of an object that has automatic storage duration. -goto.c(284): Warning: Goto at line 277 to label le jumps into a block with initialization of an object that has automatic storage duration. -goto.c(292): Warning: Goto at line 292 to label l8 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(293): Warning: Goto at line 293 to label l9 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(294): Warning: Goto at line 294 to label la jumps into a block with initialization of an object that has automatic storage duration. -goto.c(295): Warning: Goto at line 295 to label lb jumps into a block with initialization of an object that has automatic storage duration. -goto.c(296): Warning: Goto at line 296 to label lc jumps into a block with initialization of an object that has automatic storage duration. -goto.c(305): Warning: Goto at line 30 to label lf jumps into a block with initialization of an object that has automatic storage duration. -goto.c(305): Warning: Goto at line 51 to label lf jumps into a block with initialization of an object that has automatic storage duration. -goto.c(305): Warning: Goto at line 72 to label lf jumps into a block with initialization of an object that has automatic storage duration. -goto.c(305): Warning: Goto at line 93 to label lf jumps into a block with initialization of an object that has automatic storage duration. -goto.c(305): Warning: Goto at line 113 to label lf jumps into a block with initialization of an object that has automatic storage duration. -goto.c(305): Warning: Goto at line 133 to label lf jumps into a block with initialization of an object that has automatic storage duration. -goto.c(305): Warning: Goto at line 153 to label lf jumps into a block with initialization of an object that has automatic storage duration. -goto.c(305): Warning: Goto at line 174 to label lf jumps into a block with initialization of an object that has automatic storage duration. -goto.c(305): Warning: Goto at line 195 to label lf jumps into a block with initialization of an object that has automatic storage duration. -goto.c(305): Warning: Goto at line 216 to label lf jumps into a block with initialization of an object that has automatic storage duration. -goto.c(305): Warning: Goto at line 236 to label lf jumps into a block with initialization of an object that has automatic storage duration. -goto.c(305): Warning: Goto at line 256 to label lf jumps into a block with initialization of an object that has automatic storage duration. -goto.c(305): Warning: Goto at line 278 to label lf jumps into a block with initialization of an object that has automatic storage duration. -goto.c(305): Warning: Goto at line 299 to label lf jumps into a block with initialization of an object that has automatic storage duration. -goto.c(313): Warning: Goto at line 313 to label l8 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(314): Warning: Goto at line 314 to label l9 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(315): Warning: Goto at line 315 to label la jumps into a block with initialization of an object that has automatic storage duration. -goto.c(316): Warning: Goto at line 316 to label lb jumps into a block with initialization of an object that has automatic storage duration. -goto.c(317): Warning: Goto at line 317 to label lc jumps into a block with initialization of an object that has automatic storage duration. -goto.c(325): Warning: Goto at line 31 to label lg jumps into a block with initialization of an object that has automatic storage duration. -goto.c(325): Warning: Goto at line 52 to label lg jumps into a block with initialization of an object that has automatic storage duration. -goto.c(325): Warning: Goto at line 73 to label lg jumps into a block with initialization of an object that has automatic storage duration. -goto.c(325): Warning: Goto at line 94 to label lg jumps into a block with initialization of an object that has automatic storage duration. -goto.c(325): Warning: Goto at line 114 to label lg jumps into a block with initialization of an object that has automatic storage duration. -goto.c(325): Warning: Goto at line 134 to label lg jumps into a block with initialization of an object that has automatic storage duration. -goto.c(325): Warning: Goto at line 154 to label lg jumps into a block with initialization of an object that has automatic storage duration. -goto.c(325): Warning: Goto at line 175 to label lg jumps into a block with initialization of an object that has automatic storage duration. -goto.c(325): Warning: Goto at line 196 to label lg jumps into a block with initialization of an object that has automatic storage duration. -goto.c(325): Warning: Goto at line 217 to label lg jumps into a block with initialization of an object that has automatic storage duration. -goto.c(325): Warning: Goto at line 237 to label lg jumps into a block with initialization of an object that has automatic storage duration. -goto.c(325): Warning: Goto at line 257 to label lg jumps into a block with initialization of an object that has automatic storage duration. -goto.c(325): Warning: Goto at line 279 to label lg jumps into a block with initialization of an object that has automatic storage duration. -goto.c(333): Warning: Goto at line 333 to label l8 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(334): Warning: Goto at line 334 to label l9 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(335): Warning: Goto at line 335 to label la jumps into a block with initialization of an object that has automatic storage duration. -goto.c(336): Warning: Goto at line 336 to label lb jumps into a block with initialization of an object that has automatic storage duration. -goto.c(337): Warning: Goto at line 337 to label lc jumps into a block with initialization of an object that has automatic storage duration. -goto.c(340): Warning: Goto at line 340 to label lf jumps into a block with initialization of an object that has automatic storage duration. -goto.c(345): Warning: Goto at line 32 to label lh jumps into a block with initialization of an object that has automatic storage duration. -goto.c(345): Warning: Goto at line 53 to label lh jumps into a block with initialization of an object that has automatic storage duration. -goto.c(345): Warning: Goto at line 74 to label lh jumps into a block with initialization of an object that has automatic storage duration. -goto.c(345): Warning: Goto at line 95 to label lh jumps into a block with initialization of an object that has automatic storage duration. -goto.c(345): Warning: Goto at line 115 to label lh jumps into a block with initialization of an object that has automatic storage duration. -goto.c(345): Warning: Goto at line 135 to label lh jumps into a block with initialization of an object that has automatic storage duration. -goto.c(345): Warning: Goto at line 155 to label lh jumps into a block with initialization of an object that has automatic storage duration. -goto.c(345): Warning: Goto at line 176 to label lh jumps into a block with initialization of an object that has automatic storage duration. -goto.c(345): Warning: Goto at line 197 to label lh jumps into a block with initialization of an object that has automatic storage duration. -goto.c(345): Warning: Goto at line 218 to label lh jumps into a block with initialization of an object that has automatic storage duration. -goto.c(345): Warning: Goto at line 238 to label lh jumps into a block with initialization of an object that has automatic storage duration. -goto.c(345): Warning: Goto at line 258 to label lh jumps into a block with initialization of an object that has automatic storage duration. -goto.c(353): Warning: Goto at line 353 to label l8 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(354): Warning: Goto at line 354 to label l9 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(355): Warning: Goto at line 355 to label la jumps into a block with initialization of an object that has automatic storage duration. -goto.c(356): Warning: Goto at line 356 to label lb jumps into a block with initialization of an object that has automatic storage duration. -goto.c(357): Warning: Goto at line 357 to label lc jumps into a block with initialization of an object that has automatic storage duration. -goto.c(359): Warning: Goto at line 359 to label le jumps into a block with initialization of an object that has automatic storage duration. -goto.c(360): Warning: Goto at line 360 to label lf jumps into a block with initialization of an object that has automatic storage duration. -goto.c(361): Warning: Goto at line 361 to label lg jumps into a block with initialization of an object that has automatic storage duration. -goto.c(373): Warning: Goto at line 373 to label l8 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(374): Warning: Goto at line 374 to label l9 jumps into a block with initialization of an object that has automatic storage duration. -goto.c(375): Warning: Goto at line 375 to label la jumps into a block with initialization of an object that has automatic storage duration. -goto.c(376): Warning: Goto at line 376 to label lb jumps into a block with initialization of an object that has automatic storage duration. -goto.c(377): Warning: Goto at line 377 to label lc jumps into a block with initialization of an object that has automatic storage duration. -goto.c(378): Warning: Goto at line 378 to label ld jumps into a block with initialization of an object that has automatic storage duration. -goto.c(379): Warning: Goto at line 379 to label le jumps into a block with initialization of an object that has automatic storage duration. -goto.c(380): Warning: Goto at line 380 to label lf jumps into a block with initialization of an object that has automatic storage duration. -goto.c(381): Warning: Goto at line 381 to label lg jumps into a block with initialization of an object that has automatic storage duration. -goto.c(382): Warning: Goto at line 382 to label lh jumps into a block with initialization of an object that has automatic storage duration. +goto.c(159): Warning: Goto at line 23 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c(159): Warning: Goto at line 44 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c(159): Warning: Goto at line 65 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c(159): Warning: Goto at line 86 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c(159): Warning: Goto at line 106 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c(159): Warning: Goto at line 126 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c(159): Warning: Goto at line 146 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c(180): Warning: Goto at line 24 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c(180): Warning: Goto at line 45 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c(180): Warning: Goto at line 66 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c(180): Warning: Goto at line 87 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c(180): Warning: Goto at line 107 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c(180): Warning: Goto at line 127 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c(180): Warning: Goto at line 147 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c(180): Warning: Goto at line 168 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c(201): Warning: Goto at line 25 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c(201): Warning: Goto at line 46 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c(201): Warning: Goto at line 67 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c(201): Warning: Goto at line 88 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c(201): Warning: Goto at line 108 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c(201): Warning: Goto at line 128 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c(201): Warning: Goto at line 148 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c(201): Warning: Goto at line 169 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c(201): Warning: Goto at line 190 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c(221): Warning: Goto at line 26 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c(221): Warning: Goto at line 47 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c(221): Warning: Goto at line 68 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c(221): Warning: Goto at line 89 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c(221): Warning: Goto at line 109 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c(221): Warning: Goto at line 129 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c(221): Warning: Goto at line 149 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c(221): Warning: Goto at line 170 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c(231): Warning: Goto at line 231 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c(241): Warning: Goto at line 27 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c(241): Warning: Goto at line 48 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c(241): Warning: Goto at line 69 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c(241): Warning: Goto at line 90 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c(241): Warning: Goto at line 110 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c(241): Warning: Goto at line 130 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c(241): Warning: Goto at line 150 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c(250): Warning: Goto at line 250 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c(251): Warning: Goto at line 251 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c(252): Warning: Goto at line 252 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c(263): Warning: Goto at line 28 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c(263): Warning: Goto at line 49 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c(263): Warning: Goto at line 70 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c(263): Warning: Goto at line 91 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c(263): Warning: Goto at line 111 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c(263): Warning: Goto at line 131 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c(263): Warning: Goto at line 151 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c(263): Warning: Goto at line 172 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c(263): Warning: Goto at line 193 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c(263): Warning: Goto at line 214 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c(263): Warning: Goto at line 234 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c(263): Warning: Goto at line 254 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c(271): Warning: Goto at line 271 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c(272): Warning: Goto at line 272 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c(273): Warning: Goto at line 273 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c(274): Warning: Goto at line 274 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c(275): Warning: Goto at line 275 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c(284): Warning: Goto at line 29 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c(284): Warning: Goto at line 50 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c(284): Warning: Goto at line 71 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c(284): Warning: Goto at line 92 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c(284): Warning: Goto at line 112 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c(284): Warning: Goto at line 132 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c(284): Warning: Goto at line 152 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c(284): Warning: Goto at line 173 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c(284): Warning: Goto at line 194 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c(284): Warning: Goto at line 215 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c(284): Warning: Goto at line 235 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c(284): Warning: Goto at line 255 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c(284): Warning: Goto at line 277 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c(292): Warning: Goto at line 292 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c(293): Warning: Goto at line 293 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c(294): Warning: Goto at line 294 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c(295): Warning: Goto at line 295 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c(296): Warning: Goto at line 296 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c(305): Warning: Goto at line 30 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c(305): Warning: Goto at line 51 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c(305): Warning: Goto at line 72 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c(305): Warning: Goto at line 93 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c(305): Warning: Goto at line 113 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c(305): Warning: Goto at line 133 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c(305): Warning: Goto at line 153 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c(305): Warning: Goto at line 174 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c(305): Warning: Goto at line 195 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c(305): Warning: Goto at line 216 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c(305): Warning: Goto at line 236 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c(305): Warning: Goto at line 256 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c(305): Warning: Goto at line 278 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c(305): Warning: Goto at line 299 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c(313): Warning: Goto at line 313 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c(314): Warning: Goto at line 314 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c(315): Warning: Goto at line 315 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c(316): Warning: Goto at line 316 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c(317): Warning: Goto at line 317 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c(325): Warning: Goto at line 31 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c(325): Warning: Goto at line 52 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c(325): Warning: Goto at line 73 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c(325): Warning: Goto at line 94 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c(325): Warning: Goto at line 114 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c(325): Warning: Goto at line 134 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c(325): Warning: Goto at line 154 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c(325): Warning: Goto at line 175 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c(325): Warning: Goto at line 196 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c(325): Warning: Goto at line 217 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c(325): Warning: Goto at line 237 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c(325): Warning: Goto at line 257 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c(325): Warning: Goto at line 279 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c(333): Warning: Goto at line 333 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c(334): Warning: Goto at line 334 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c(335): Warning: Goto at line 335 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c(336): Warning: Goto at line 336 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c(337): Warning: Goto at line 337 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c(340): Warning: Goto at line 340 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c(345): Warning: Goto at line 32 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c(345): Warning: Goto at line 53 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c(345): Warning: Goto at line 74 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c(345): Warning: Goto at line 95 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c(345): Warning: Goto at line 115 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c(345): Warning: Goto at line 135 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c(345): Warning: Goto at line 155 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c(345): Warning: Goto at line 176 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c(345): Warning: Goto at line 197 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c(345): Warning: Goto at line 218 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c(345): Warning: Goto at line 238 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c(345): Warning: Goto at line 258 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c(353): Warning: Goto at line 353 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c(354): Warning: Goto at line 354 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c(355): Warning: Goto at line 355 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c(356): Warning: Goto at line 356 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c(357): Warning: Goto at line 357 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c(359): Warning: Goto at line 359 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c(360): Warning: Goto at line 360 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c(361): Warning: Goto at line 361 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c(373): Warning: Goto at line 373 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c(374): Warning: Goto at line 374 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c(375): Warning: Goto at line 375 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c(376): Warning: Goto at line 376 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c(377): Warning: Goto at line 377 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c(378): Warning: Goto at line 378 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c(379): Warning: Goto at line 379 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c(380): Warning: Goto at line 380 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c(381): Warning: Goto at line 381 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c(382): Warning: Goto at line 382 to label lh jumps into a block with initialization of an object that has automatic storage duration From 88d1d20cd0d45b3c32bdfcaaff89f78e1b469a57 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 2 Oct 2018 18:53:01 +0200 Subject: [PATCH 0882/2161] Minor style adjustment. --- 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 c878c7bf6..0f7b45968 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -2426,8 +2426,8 @@ void g_falsejump (unsigned flags attribute ((unused)), unsigned label) void g_lateadjustSP (unsigned label) -{ /* Adjust stack based on non-immediate data */ +{ AddCodeLine ("pha"); AddCodeLine ("lda %s", LocalLabelName (label)); AddCodeLine ("clc"); From f11ae87adae1c519da4aff77f862b40ffd1ab66f Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 2 Oct 2018 23:19:38 -0400 Subject: [PATCH 0883/2161] Always put goto stack-adjustments in the RODATA segment. --- src/cc65/symtab.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 22a63b893..87fad111b 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -728,6 +728,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* We're processing a label, let's update all gotos encountered ** so far */ + g_userodata(); g_defdatalabel (DOR->LateSP_Label); g_defdata (CF_CONST | CF_INT, StackPtr - DOR->StackPtr, 0); From 0149de4da75e0d03a17f905dcc18c34c131174d3 Mon Sep 17 00:00:00 2001 From: Egor <egor@opensrc.club> Date: Sat, 6 Oct 2018 18:30:35 +0300 Subject: [PATCH 0884/2161] da65: properly scan empty strings Previously, doing something like `LABEL { NAME ""; ADDR $1000; };` would result in $1000 being labeled as NAME: instead of being unnamed. --- src/da65/scanner.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/da65/scanner.c b/src/da65/scanner.c index 143bb2636..2bb80a8ef 100644 --- a/src/da65/scanner.c +++ b/src/da65/scanner.c @@ -413,6 +413,7 @@ Again: case '\"': NextChar (); I = 0; + InfoSVal[0] = '\0'; while (C != EOF && C != '\"') { if (GetEncodedChar (InfoSVal, &I, sizeof InfoSVal) < 0) { if (C == EOF) { From 92defb7a2b1638f5e8949dfff5eef9c04a167ff1 Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Wed, 3 Oct 2018 21:59:19 -0700 Subject: [PATCH 0885/2161] Fix crash due to mistaken symbol identity. --- src/cc65/symtab.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 87fad111b..c875360e3 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -839,6 +839,12 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) Type* EType; + /* Even if the symbol already exists, let's make sure it + ** is not an ENUM. See bug #728. */ + if (Entry->Flags & SC_ENUM) { + Fatal ("Conflicting types for `%s'", Name); + } + /* We have a symbol with this name already */ if (Entry->Flags & SC_TYPE) { Error ("Multiple definition for `%s'", Name); From 03e43d1fbfc281f05026e4466c5e73e2cdac0dcb Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 8 Oct 2018 20:39:46 -0400 Subject: [PATCH 0886/2161] Changed a comment and an error message into more specific text. --- src/cc65/symtab.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index c875360e3..8eefe1178 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -836,13 +836,13 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) /* Do we have an entry with this name already? */ SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name)); if (Entry) { - Type* EType; - /* Even if the symbol already exists, let's make sure it - ** is not an ENUM. See bug #728. */ + /* If the existing symbol is an enumerated constant, + ** then avoid a compiler crash. See GitHub issue #728. + */ if (Entry->Flags & SC_ENUM) { - Fatal ("Conflicting types for `%s'", Name); + Fatal ("Can't redeclare enum constant `%s' as global variable", Name); } /* We have a symbol with this name already */ From 8eb9f4a8aa63ffbee31f5c87586ba298271e4cd5 Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Sun, 14 Oct 2018 13:53:14 -0700 Subject: [PATCH 0887/2161] Fix for issue #735 --- src/cc65/coptind.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index ca9d5effd..f87c367b2 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -2056,8 +2056,14 @@ unsigned OptPrecalc (CodeSeg* S) ** results we don't already have (including the flags), so ** remove it. Something like this is generated as a result of ** a compare where parts of the values are known to be zero. + ** The only situation where we need to leave things as they are + ** is when V flag is being tested in the next instruction, + ** because ADC/SBC #0 always clears it. */ - if (In->RegA == 0 && CE_IsKnownImm (E, 0x00)) { + if (In->RegA == 0 && CE_IsKnownImm (E, 0x00) && + (E = CS_GetEntry (S, I + 1)) && + E->OPC != OP65_BVC && + E->OPC != OP65_BVS ) { /* 0-0 or 0+0 -> remove */ CS_DelEntry (S, I); ++Changes; From 6d8c315cdbe4aca6c88ed815c403d32b3b746377 Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Sun, 14 Oct 2018 14:10:59 -0700 Subject: [PATCH 0888/2161] Testcase added. --- test/val/bug735.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 test/val/bug735.c diff --git a/test/val/bug735.c b/test/val/bug735.c new file mode 100644 index 000000000..7bcc8d9cc --- /dev/null +++ b/test/val/bug735.c @@ -0,0 +1,17 @@ +#include <stdio.h> + +unsigned char failures = 0; + +int main(void) +{ + int i; + + i = 0; + if ((i > 1) && (i < 3)) { + failures++; + } + + printf("failures: %u\n", failures); + return failures; +} + From 249248ccc8be81a411cd83b833d3249b909ab6cf Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Mon, 15 Oct 2018 22:20:12 -0700 Subject: [PATCH 0889/2161] Formatting tweaks. --- src/cc65/coptind.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index f87c367b2..f2ece2cee 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -2061,9 +2061,9 @@ unsigned OptPrecalc (CodeSeg* S) ** because ADC/SBC #0 always clears it. */ if (In->RegA == 0 && CE_IsKnownImm (E, 0x00) && - (E = CS_GetEntry (S, I + 1)) && - E->OPC != OP65_BVC && - E->OPC != OP65_BVS ) { + (E = CS_GetEntry (S, I + 1)) && + E->OPC != OP65_BVC && + E->OPC != OP65_BVS ) { /* 0-0 or 0+0 -> remove */ CS_DelEntry (S, I); ++Changes; From d3665b263ee9c7a028e39186b28017ba26fd13d9 Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Sat, 13 Oct 2018 00:05:33 -0700 Subject: [PATCH 0890/2161] Stack adjustment code optimizations. --- src/cc65/codeopt.c | 85 ++++++++++++++++++++++++++++++++++++++++++++- src/cc65/opcodes.h | 2 +- src/cc65/symentry.h | 5 +++ src/cc65/symtab.c | 27 ++++++++++++-- src/cc65/symtab.h | 2 ++ 5 files changed, 116 insertions(+), 5 deletions(-) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index e44bf2bf5..6e547f16d 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -69,7 +69,7 @@ #include "error.h" #include "global.h" #include "output.h" - +#include "symtab.h" /*****************************************************************************/ @@ -613,7 +613,86 @@ static unsigned OptStackPtrOps (CodeSeg* S) return Changes; } +static unsigned OptGotoSPAdj (CodeSeg* S) +/* Remove unnecessary SP adjustment while gotoing +*/ +{ + unsigned Changes = 0; + unsigned I; + /* Walk over the entries */ + I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* L[10], *X; + unsigned short adjustment; + const char* Arg; + + /* Get next entry */ + L[0] = CS_GetEntry (S, I); + + /* Check for the sequence */ + if (L[0]->OPC == OP65_PHA && + CS_GetEntries (S, L+1, I+1, 9) && + L[1]->OPC == OP65_LDA && + L[1]->AM == AM65_ABS && + L[2]->OPC == OP65_CLC && + L[3]->OPC == OP65_ADC && + strcmp (L[3]->Arg, "sp") == 0 && + L[6]->OPC == OP65_ADC && + strcmp (L[6]->Arg, "sp+1") == 0 && + L[9]->OPC == OP65_JMP + ) { + printf("Goto SP adjustment found. Jump to: %s, data Label: %s\n", L[9]->Arg, L[1]->Arg); + adjustment = FindSPAdjustment(L[1]->Arg); + + if (adjustment == 0) { + CS_DelEntries (S, I, 9); + } + else if (adjustment > 255) { + Arg = MakeHexArg (adjustment & 0xff); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, L[1]->LI); + CS_InsertEntry(S, X, I + 1); + Arg = MakeHexArg (adjustment >> 8); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, L[5]->LI); + CS_InsertEntry(S, X, I + 6); + + CS_DelEntry(S, I + 2); + CS_DelEntry(S, I + 6); + } + else if (adjustment > 8) { + Arg = MakeHexArg (adjustment & 0xff); + X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI); + CS_InsertEntry (S, X, I); + X = NewCodeEntry (OP65_JSR, AM65_ABS, "addysp", 0, L[1]->LI); + CS_InsertEntry (S, X, I + 1); + + CS_DelEntries(S, I + 2, 9); + } + else { + char Buf[20]; + xsprintf (Buf, sizeof (Buf), "incsp%u", adjustment); + X = NewCodeEntry (OP65_JSR, AM65_ABS, Buf, 0, L[1]->LI); + CS_InsertEntry (S, X, I); + + CS_DelEntries(S, I + 1, 9); + } + /* Regenerate register info */ + CS_GenRegInfo (S); + + /* Remember we had changes */ + Changes++; + } else { + + /* Next entry */ + ++I; + } + + } + + /* Return the number of changes made */ + return Changes; +} /*****************************************************************************/ /* struct OptFunc */ @@ -675,6 +754,7 @@ static OptFunc DOptDeadCode = { OptDeadCode, "OptDeadCode", 100, 0, static OptFunc DOptDeadJumps = { OptDeadJumps, "OptDeadJumps", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptDecouple = { OptDecouple, "OptDecouple", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptDupLoads = { OptDupLoads, "OptDupLoads", 0, 0, 0, 0, 0, 0 }; +static OptFunc DOptGotoSPAdj = { OptGotoSPAdj, "OptGotoSPAdj", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptIndLoads1 = { OptIndLoads1, "OptIndLoads1", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptIndLoads2 = { OptIndLoads2, "OptIndLoads2", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptJumpCascades = { OptJumpCascades, "OptJumpCascades", 100, 0, 0, 0, 0, 0 }; @@ -774,6 +854,7 @@ static OptFunc* OptFuncs[] = { &DOptDeadJumps, &DOptDecouple, &DOptDupLoads, + &DOptGotoSPAdj, &DOptIndLoads1, &DOptIndLoads2, &DOptJumpCascades, @@ -1122,6 +1203,7 @@ static unsigned RunOptGroup1 (CodeSeg* S) { unsigned Changes = 0; + Changes += RunOptFunc (S, &DOptGotoSPAdj, 1); Changes += RunOptFunc (S, &DOptStackPtrOps, 5); Changes += RunOptFunc (S, &DOptPtrStore1, 1); Changes += RunOptFunc (S, &DOptPtrStore2, 1); @@ -1229,6 +1311,7 @@ static unsigned RunOptGroup3 (CodeSeg* S) C += RunOptFunc (S, &DOptCmp6, 1); C += RunOptFunc (S, &DOptCmp7, 1); C += RunOptFunc (S, &DOptCmp9, 1); + C += RunOptFunc (S, &DOptTest1, 1); C += RunOptFunc (S, &DOptLoad1, 1); C += RunOptFunc (S, &DOptJumpTarget3, 1); /* After OptCondBranches2 */ diff --git a/src/cc65/opcodes.h b/src/cc65/opcodes.h index 349de32a4..0d191f6c7 100644 --- a/src/cc65/opcodes.h +++ b/src/cc65/opcodes.h @@ -134,7 +134,7 @@ typedef enum { typedef enum { AM65_IMP, /* implicit */ AM65_ACC, /* accumulator */ - AM65_IMM, /* immidiate */ + AM65_IMM, /* immediate */ AM65_ZP, /* zeropage */ AM65_ZPX, /* zeropage,X */ AM65_ZPY, /* zeropage,Y */ diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index e978274dc..630ca944c 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -99,6 +99,7 @@ struct LiteralPool; #define SC_HAVEATTR 0x10000U /* Symbol has attributes */ #define SC_GOTO 0x20000U +#define SC_SPADJUSTMENT 0x40000U @@ -139,6 +140,10 @@ struct SymEntry { Collection *DefsOrRefs; } L; + struct { + unsigned short SPAdjustment; + } G; + /* Register bank offset and offset of the saved copy on stack for ** register variables. */ diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 8eefe1178..8db6a741c 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -92,7 +92,7 @@ static SymTable* SymTab = 0; static SymTable* TagTab0 = 0; static SymTable* TagTab = 0; static SymTable* LabelTab = 0; - +static SymTable* SPAdjustTab = 0; /*****************************************************************************/ @@ -225,6 +225,8 @@ void EnterGlobalLevel (void) /* Create and assign the tag table */ TagTab0 = TagTab = NewSymTable (SYMTAB_SIZE_GLOBAL); + + SPAdjustTab = NewSymTable (SYMTAB_SIZE_GLOBAL); } @@ -405,7 +407,7 @@ void LeaveStructLevel (void) -static SymEntry* FindSymInTable (const SymTable* T, const char* Name, unsigned Hash) +SymEntry* FindSymInTable (const SymTable* T, const char* Name, unsigned Hash) /* Search for an entry in one table */ { /* Get the start of the hash chain */ @@ -660,7 +662,7 @@ SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val } -DefOrRef* AddDefOrRef(SymEntry* E, unsigned Flags) +DefOrRef* AddDefOrRef (SymEntry* E, unsigned Flags) /* Add definition or reference to the SymEntry and preserve its attributes */ { DefOrRef *DOR; @@ -677,6 +679,20 @@ DefOrRef* AddDefOrRef(SymEntry* E, unsigned Flags) return DOR; } +unsigned short FindSPAdjustment (const char* Name) +{ + SymEntry* Entry = FindSymInTable (SPAdjustTab, Name, HashStr (Name)); + + if (Entry) { + printf("L: %s sa: %d\n", Name, Entry->V.G.SPAdjustment); + return Entry->V.G.SPAdjustment; + } + + Fatal("ICE: No label entry found"); + + return 0; +} + SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* Add a goto label to the label table */ { @@ -728,9 +744,14 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* We're processing a label, let's update all gotos encountered ** so far */ + SymEntry *E; g_userodata(); g_defdatalabel (DOR->LateSP_Label); g_defdata (CF_CONST | CF_INT, StackPtr - DOR->StackPtr, 0); + E = NewSymEntry (LocalLabelName(DOR->LateSP_Label), SC_SPADJUSTMENT); + E->V.G.SPAdjustment = StackPtr - DOR->StackPtr; + AddSymEntry (SPAdjustTab, E); + /* Are we jumping into a block with initalization of an object that ** has automatic storage duration? Let's emit a warning. diff --git a/src/cc65/symtab.h b/src/cc65/symtab.h index 39782d6ab..0856740cc 100644 --- a/src/cc65/symtab.h +++ b/src/cc65/symtab.h @@ -136,6 +136,8 @@ SymEntry* FindTagSym (const char* Name); SymEntry* FindStructField (const Type* TypeArray, const char* Name); /* Find a struct field in the fields list */ +unsigned short FindSPAdjustment (const char* Name); +/* Search for an entry in the table of SP adjustments */ /*****************************************************************************/ From cf7f3abadd27567ec3950ac82b0f6c3f9fbfd4c8 Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Sun, 14 Oct 2018 01:07:59 -0700 Subject: [PATCH 0891/2161] Even more optimization, cleanup, bugfix, comments. --- src/cc65/codeopt.c | 64 ++++++++++++++++++++++++++++++++------------- src/cc65/symentry.h | 1 + src/cc65/symtab.c | 17 ++++++------ 3 files changed, 56 insertions(+), 26 deletions(-) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 6e547f16d..f87d44900 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -614,8 +614,7 @@ static unsigned OptStackPtrOps (CodeSeg* S) } static unsigned OptGotoSPAdj (CodeSeg* S) -/* Remove unnecessary SP adjustment while gotoing -*/ +/* Optimize SP adjustment for forward 'goto' */ { unsigned Changes = 0; unsigned I; @@ -631,7 +630,7 @@ static unsigned OptGotoSPAdj (CodeSeg* S) /* Get next entry */ L[0] = CS_GetEntry (S, I); - /* Check for the sequence */ + /* Check for the sequence generated by g_lateadjustSP */ if (L[0]->OPC == OP65_PHA && CS_GetEntries (S, L+1, I+1, 9) && L[1]->OPC == OP65_LDA && @@ -640,48 +639,78 @@ static unsigned OptGotoSPAdj (CodeSeg* S) L[3]->OPC == OP65_ADC && strcmp (L[3]->Arg, "sp") == 0 && L[6]->OPC == OP65_ADC && - strcmp (L[6]->Arg, "sp+1") == 0 && - L[9]->OPC == OP65_JMP - ) { - printf("Goto SP adjustment found. Jump to: %s, data Label: %s\n", L[9]->Arg, L[1]->Arg); - adjustment = FindSPAdjustment(L[1]->Arg); + strcmp (L[6]->Arg, "sp+1") == 0 && + L[9]->OPC == OP65_JMP) { + adjustment = FindSPAdjustment (L[1]->Arg); if (adjustment == 0) { + /* No SP adjustment needed, remove the whole sequence */ + CS_DelEntries (S, I, 9); + } + else if (adjustment >= 65536 - 8) { + /* If adjustment is in range [-8, 0) we use decsp* calls */ + char Buf[20]; + adjustment = 65536 - adjustment; + xsprintf (Buf, sizeof (Buf), "decsp%u", adjustment); + X = NewCodeEntry (OP65_JSR, AM65_ABS, Buf, 0, L[1]->LI); + CS_InsertEntry (S, X, I + 9); + + /* Delete the old code */ + CS_DelEntries (S, I, 9); + } + else if (adjustment >= 65536 - 255) { + /* For range [-255, -8) we have ldy #, jsr subysp */ + adjustment = 65536 - adjustment; + Arg = MakeHexArg (adjustment); + X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI); + CS_InsertEntry (S, X, I + 9); + X = NewCodeEntry (OP65_JSR, AM65_ABS, "subysp", 0, L[1]->LI); + CS_InsertEntry (S, X, I + 10); + + /* Delete the old code */ CS_DelEntries (S, I, 9); } else if (adjustment > 255) { + /* For ranges [-32768, 255) and (255, 32767) the only modification + ** is to replace the absolute with immediate addressing */ Arg = MakeHexArg (adjustment & 0xff); X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, L[1]->LI); - CS_InsertEntry(S, X, I + 1); + CS_InsertEntry (S, X, I + 1); Arg = MakeHexArg (adjustment >> 8); X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, L[5]->LI); - CS_InsertEntry(S, X, I + 6); + CS_InsertEntry (S, X, I + 6); - CS_DelEntry(S, I + 2); - CS_DelEntry(S, I + 6); + /* Delete the old code */ + CS_DelEntry (S, I + 2); + CS_DelEntry (S, I + 6); } else if (adjustment > 8) { + /* For range (8, 255] we have ldy #0, jsr addysp */ Arg = MakeHexArg (adjustment & 0xff); X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI); - CS_InsertEntry (S, X, I); + CS_InsertEntry (S, X, I + 9); X = NewCodeEntry (OP65_JSR, AM65_ABS, "addysp", 0, L[1]->LI); - CS_InsertEntry (S, X, I + 1); + CS_InsertEntry (S, X, I + 10); - CS_DelEntries(S, I + 2, 9); + /* Delete the old code */ + CS_DelEntries (S, I, 9); } else { + /* If adjustment is in range (0, 8] we use incsp* calls */ char Buf[20]; xsprintf (Buf, sizeof (Buf), "incsp%u", adjustment); X = NewCodeEntry (OP65_JSR, AM65_ABS, Buf, 0, L[1]->LI); - CS_InsertEntry (S, X, I); + CS_InsertEntry (S, X, I + 9); - CS_DelEntries(S, I + 1, 9); + /* Delete the old code */ + CS_DelEntries (S, I, 9); } /* Regenerate register info */ CS_GenRegInfo (S); /* Remember we had changes */ Changes++; + } else { /* Next entry */ @@ -1311,7 +1340,6 @@ static unsigned RunOptGroup3 (CodeSeg* S) C += RunOptFunc (S, &DOptCmp6, 1); C += RunOptFunc (S, &DOptCmp7, 1); C += RunOptFunc (S, &DOptCmp9, 1); - C += RunOptFunc (S, &DOptTest1, 1); C += RunOptFunc (S, &DOptLoad1, 1); C += RunOptFunc (S, &DOptJumpTarget3, 1); /* After OptCondBranches2 */ diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 630ca944c..3d4bcdcc1 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -140,6 +140,7 @@ struct SymEntry { Collection *DefsOrRefs; } L; + /* Value of SP adjustment needed after forward 'goto' */ struct { unsigned short SPAdjustment; } G; diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 8db6a741c..11314b53a 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -226,6 +226,7 @@ void EnterGlobalLevel (void) /* Create and assign the tag table */ TagTab0 = TagTab = NewSymTable (SYMTAB_SIZE_GLOBAL); + /* Create and assign the table of SP adjustment symbols */ SPAdjustTab = NewSymTable (SYMTAB_SIZE_GLOBAL); } @@ -681,16 +682,14 @@ DefOrRef* AddDefOrRef (SymEntry* E, unsigned Flags) unsigned short FindSPAdjustment (const char* Name) { +/* Search for an entry in the table of SP adjustments */ SymEntry* Entry = FindSymInTable (SPAdjustTab, Name, HashStr (Name)); - if (Entry) { - printf("L: %s sa: %d\n", Name, Entry->V.G.SPAdjustment); - return Entry->V.G.SPAdjustment; + if (!Entry) { + Internal ("No SP adjustment label entry found"); } - Fatal("ICE: No label entry found"); - - return 0; + return Entry->V.G.SPAdjustment; } SymEntry* AddLabelSym (const char* Name, unsigned Flags) @@ -748,11 +747,13 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) g_userodata(); g_defdatalabel (DOR->LateSP_Label); g_defdata (CF_CONST | CF_INT, StackPtr - DOR->StackPtr, 0); - E = NewSymEntry (LocalLabelName(DOR->LateSP_Label), SC_SPADJUSTMENT); + + /* Optimizer will need the information about the value of SP adjustment + ** later, so let's preserve it. */ + E = NewSymEntry (LocalLabelName (DOR->LateSP_Label), SC_SPADJUSTMENT); E->V.G.SPAdjustment = StackPtr - DOR->StackPtr; AddSymEntry (SPAdjustTab, E); - /* Are we jumping into a block with initalization of an object that ** has automatic storage duration? Let's emit a warning. */ From 7d9485f6bc736a8ad7f8aeade9566190e49b1f78 Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Sun, 14 Oct 2018 01:21:34 -0700 Subject: [PATCH 0892/2161] Typo --- 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 f87d44900..c577ff8ba 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -685,7 +685,7 @@ static unsigned OptGotoSPAdj (CodeSeg* S) CS_DelEntry (S, I + 6); } else if (adjustment > 8) { - /* For range (8, 255] we have ldy #0, jsr addysp */ + /* For range (8, 255] we have ldy #, jsr addysp */ Arg = MakeHexArg (adjustment & 0xff); X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI); CS_InsertEntry (S, X, I + 9); From 5fa79be997303c0a9d017f99f4d8f5e2bfa11b5c Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Mon, 15 Oct 2018 23:08:44 -0700 Subject: [PATCH 0893/2161] Post-review tweaks. --- src/cc65/codeopt.c | 15 ++++++++------- src/cc65/symentry.h | 4 +--- src/cc65/symtab.c | 11 ++++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index c577ff8ba..3116539dc 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -644,11 +644,11 @@ static unsigned OptGotoSPAdj (CodeSeg* S) adjustment = FindSPAdjustment (L[1]->Arg); if (adjustment == 0) { - /* No SP adjustment needed, remove the whole sequence */ + /* No SP adjustment needed, remove the whole sequence */ CS_DelEntries (S, I, 9); } else if (adjustment >= 65536 - 8) { - /* If adjustment is in range [-8, 0) we use decsp* calls */ + /* If adjustment is in range [-8, 0) we use decsp* calls */ char Buf[20]; adjustment = 65536 - adjustment; xsprintf (Buf, sizeof (Buf), "decsp%u", adjustment); @@ -659,7 +659,7 @@ static unsigned OptGotoSPAdj (CodeSeg* S) CS_DelEntries (S, I, 9); } else if (adjustment >= 65536 - 255) { - /* For range [-255, -8) we have ldy #, jsr subysp */ + /* For range [-255, -8) we have ldy #, jsr subysp */ adjustment = 65536 - adjustment; Arg = MakeHexArg (adjustment); X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI); @@ -671,8 +671,9 @@ static unsigned OptGotoSPAdj (CodeSeg* S) CS_DelEntries (S, I, 9); } else if (adjustment > 255) { - /* For ranges [-32768, 255) and (255, 32767) the only modification - ** is to replace the absolute with immediate addressing */ + /* For ranges [-32768, 255) and (255, 32767) the only modification + ** is to replace the absolute with immediate addressing + */ Arg = MakeHexArg (adjustment & 0xff); X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, L[1]->LI); CS_InsertEntry (S, X, I + 1); @@ -685,7 +686,7 @@ static unsigned OptGotoSPAdj (CodeSeg* S) CS_DelEntry (S, I + 6); } else if (adjustment > 8) { - /* For range (8, 255] we have ldy #, jsr addysp */ + /* For range (8, 255] we have ldy #, jsr addysp */ Arg = MakeHexArg (adjustment & 0xff); X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI); CS_InsertEntry (S, X, I + 9); @@ -696,7 +697,7 @@ static unsigned OptGotoSPAdj (CodeSeg* S) CS_DelEntries (S, I, 9); } else { - /* If adjustment is in range (0, 8] we use incsp* calls */ + /* If adjustment is in range (0, 8] we use incsp* calls */ char Buf[20]; xsprintf (Buf, sizeof (Buf), "incsp%u", adjustment); X = NewCodeEntry (OP65_JSR, AM65_ABS, Buf, 0, L[1]->LI); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 3d4bcdcc1..73a8a72e7 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -141,9 +141,7 @@ struct SymEntry { } L; /* Value of SP adjustment needed after forward 'goto' */ - struct { - unsigned short SPAdjustment; - } G; + unsigned short SPAdjustment; /* Register bank offset and offset of the saved copy on stack for ** register variables. diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 11314b53a..9eb0346e8 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -408,7 +408,7 @@ void LeaveStructLevel (void) -SymEntry* FindSymInTable (const SymTable* T, const char* Name, unsigned Hash) +static SymEntry* FindSymInTable (const SymTable* T, const char* Name, unsigned Hash) /* Search for an entry in one table */ { /* Get the start of the hash chain */ @@ -681,15 +681,15 @@ DefOrRef* AddDefOrRef (SymEntry* E, unsigned Flags) } unsigned short FindSPAdjustment (const char* Name) -{ /* Search for an entry in the table of SP adjustments */ +{ SymEntry* Entry = FindSymInTable (SPAdjustTab, Name, HashStr (Name)); if (!Entry) { Internal ("No SP adjustment label entry found"); } - return Entry->V.G.SPAdjustment; + return Entry->V.SPAdjustment; } SymEntry* AddLabelSym (const char* Name, unsigned Flags) @@ -749,9 +749,10 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) g_defdata (CF_CONST | CF_INT, StackPtr - DOR->StackPtr, 0); /* Optimizer will need the information about the value of SP adjustment - ** later, so let's preserve it. */ + ** later, so let's preserve it. + */ E = NewSymEntry (LocalLabelName (DOR->LateSP_Label), SC_SPADJUSTMENT); - E->V.G.SPAdjustment = StackPtr - DOR->StackPtr; + E->V.SPAdjustment = StackPtr - DOR->StackPtr; AddSymEntry (SPAdjustTab, E); /* Are we jumping into a block with initalization of an object that From 16aec54276edf2b9f4d3f2912a09df2e6b0c3a34 Mon Sep 17 00:00:00 2001 From: Brad Smith <bbbradsmith@users.noreply.github.com> Date: Wed, 17 Oct 2018 21:27:21 -0400 Subject: [PATCH 0894/2161] ca65.sgml fails to document z: a: f: address size override prefixes. --- doc/ca65.sgml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index fc32efa61..52e9634ae 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1186,7 +1186,21 @@ an explanation on how this is done. <sect1>Address sizes of symbols<p> +The address size of a symbol can be specified with a prefix: +<itemize> +<item>z: zeropage addressing (8 bits). +<item>a: absolute addressing (16 bits). +<item>f: far addressing (24 bits). +</itemize> + +The zeropage addressing override can be used to ensure the use of optimal +zeropage instructions, or correct cases where the size isn't yet known +due to the single-pass assembly model. + +The larger addressing overrides can be used to promote a smaller address +to absolute or far addressing, instead of being automatically fit into +a smaller addressing type. <sect1>Memory models<p> From 2a9bb0d8de76a69fa3c92f0bb7bb12b198ba7ef2 Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky <me@veg.by> Date: Thu, 18 Oct 2018 00:07:37 +0300 Subject: [PATCH 0895/2161] CL65: --no-rtl option for disabling default runtime library --- doc/cl65.sgml | 6 ++++++ src/cl65/main.c | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/doc/cl65.sgml b/doc/cl65.sgml index 2a3e61828..b83cd96f3 100644 --- a/doc/cl65.sgml +++ b/doc/cl65.sgml @@ -103,6 +103,7 @@ Long options: --memory-model model Set the memory model --module Link as a module --module-id id Specify a module id for the linker + --no-rtl Don't link default runtime library --o65-model model Override the o65 model --obj file Link this object file --obj-path path Specify an object file search path @@ -185,6 +186,11 @@ There are a few remaining options that control the behaviour of cl65: seem to use cc65 to develop for the C64. + <tag><tt>--no-rtl</tt></tag> + + This option disables default runtime library of target system. + + <tag><tt>-Wa options, --asm-args options</tt></tag> Pass options directly to the assembler. This may be used to pass options diff --git a/src/cl65/main.c b/src/cl65/main.c index 118acfb03..1e64af787 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -139,6 +139,7 @@ static int Module = 0; /* Name of the target specific runtime library */ static char* TargetLib = 0; +static int NoRTL = 0; @@ -414,6 +415,12 @@ static void SetTargetFiles (void) const char* TargetName = GetTargetName (Target); unsigned TargetNameLen = strlen (TargetName); + if (NoRTL) + { + /* Default RunTime Library is disabled */ + return; + } + /* Set the library file */ TargetLib = xmalloc (TargetNameLen + 4 + 1); memcpy (TargetLib, TargetName, TargetNameLen); @@ -812,6 +819,7 @@ static void Usage (void) " --memory-model model\t\tSet the memory model\n" " --module\t\t\tLink as a module\n" " --module-id id\t\tSpecify a module ID for the linker\n" + " --no-rtl\t\t\tDon't link default runtime library\n" " --o65-model model\t\tOverride the o65 model\n" " --obj file\t\t\tLink this object file\n" " --obj-path path\t\tSpecify an object file search path\n" @@ -1167,6 +1175,15 @@ static void OptModuleId (const char* Opt attribute ((unused)), const char* Arg) +static void OptNoRTL (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Disable default runtime library */ +{ + NoRTL = 1; +} + + + static void OptO65Model (const char* Opt attribute ((unused)), const char* Arg) /* Handle the --o65-model option */ { @@ -1369,6 +1386,7 @@ int main (int argc, char* argv []) { "--memory-model", 1, OptMemoryModel }, { "--module", 0, OptModule }, { "--module-id", 1, OptModuleId }, + { "--no-rtl", 0, OptNoRTL }, { "--o65-model", 1, OptO65Model }, { "--obj", 1, OptObj }, { "--obj-path", 1, OptObjPath }, From 23b5cc870ed43fb80a39768356ba072430f10735 Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky <me@veg.by> Date: Thu, 18 Oct 2018 12:54:15 +0300 Subject: [PATCH 0896/2161] Renamed to '--no-crt-lib' --- doc/cl65.sgml | 7 ++++--- src/cl65/main.c | 23 ++++++++++------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/doc/cl65.sgml b/doc/cl65.sgml index b83cd96f3..4591b42f7 100644 --- a/doc/cl65.sgml +++ b/doc/cl65.sgml @@ -103,7 +103,7 @@ Long options: --memory-model model Set the memory model --module Link as a module --module-id id Specify a module id for the linker - --no-rtl Don't link default runtime library + --no-crt-lib Don't link default C runtime library --o65-model model Override the o65 model --obj file Link this object file --obj-path path Specify an object file search path @@ -186,9 +186,10 @@ There are a few remaining options that control the behaviour of cl65: seem to use cc65 to develop for the C64. - <tag><tt>--no-rtl</tt></tag> + <tag><tt>--no-crt-lib</tt></tag> + + This option tells the cl65 to not include default C runtime library into the list of libraries. - This option disables default runtime library of target system. <tag><tt>-Wa options, --asm-args options</tt></tag> diff --git a/src/cl65/main.c b/src/cl65/main.c index 1e64af787..badf15585 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -139,7 +139,7 @@ static int Module = 0; /* Name of the target specific runtime library */ static char* TargetLib = 0; -static int NoRTL = 0; +static int NoCrtLib = 0; @@ -415,12 +415,6 @@ static void SetTargetFiles (void) const char* TargetName = GetTargetName (Target); unsigned TargetNameLen = strlen (TargetName); - if (NoRTL) - { - /* Default RunTime Library is disabled */ - return; - } - /* Set the library file */ TargetLib = xmalloc (TargetNameLen + 4 + 1); memcpy (TargetLib, TargetName, TargetNameLen); @@ -498,8 +492,11 @@ static void Link (void) CmdSetTarget (&LD65, Target); } - /* Determine which target libraries are needed */ - SetTargetFiles (); + if (!NoCrtLib) + { + /* Determine which target libraries are needed */ + SetTargetFiles (); + } /* Add all object files as parameters */ for (I = 0; I < LD65.FileCount; ++I) { @@ -819,7 +816,7 @@ static void Usage (void) " --memory-model model\t\tSet the memory model\n" " --module\t\t\tLink as a module\n" " --module-id id\t\tSpecify a module ID for the linker\n" - " --no-rtl\t\t\tDon't link default runtime library\n" + " --no-crt-lib\t\t\tDon't link default C runtime library\n" " --o65-model model\t\tOverride the o65 model\n" " --obj file\t\t\tLink this object file\n" " --obj-path path\t\tSpecify an object file search path\n" @@ -1175,11 +1172,11 @@ static void OptModuleId (const char* Opt attribute ((unused)), const char* Arg) -static void OptNoRTL (const char* Opt attribute ((unused)), +static void OptNoCrtLib (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Disable default runtime library */ { - NoRTL = 1; + NoCrtLib = 1; } @@ -1386,7 +1383,7 @@ int main (int argc, char* argv []) { "--memory-model", 1, OptMemoryModel }, { "--module", 0, OptModule }, { "--module-id", 1, OptModuleId }, - { "--no-rtl", 0, OptNoRTL }, + { "--no-crt-lib", 0, OptNoCrtLib }, { "--o65-model", 1, OptO65Model }, { "--obj", 1, OptObj }, { "--obj-path", 1, OptObjPath }, From 8084702a58b3c5b669b735a98db7c9c14e383529 Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky <me@veg.by> Date: Thu, 18 Oct 2018 13:16:48 +0300 Subject: [PATCH 0897/2161] Renamed to '--no-std-lib' --- doc/cl65.sgml | 7 ++++--- src/cl65/main.c | 32 ++++++++++++++++---------------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/doc/cl65.sgml b/doc/cl65.sgml index 4591b42f7..a2413fe7a 100644 --- a/doc/cl65.sgml +++ b/doc/cl65.sgml @@ -103,7 +103,7 @@ Long options: --memory-model model Set the memory model --module Link as a module --module-id id Specify a module id for the linker - --no-crt-lib Don't link default C runtime library + --no-std-lib Don't link standard runtime library --o65-model model Override the o65 model --obj file Link this object file --obj-path path Specify an object file search path @@ -186,9 +186,10 @@ There are a few remaining options that control the behaviour of cl65: seem to use cc65 to develop for the C64. - <tag><tt>--no-crt-lib</tt></tag> + <tag><tt>--no-std-lib</tt></tag> - This option tells the cl65 to not include default C runtime library into the list of libraries. + This option tells the cl65 to not include standard runtime library into the + list of libraries. diff --git a/src/cl65/main.c b/src/cl65/main.c index badf15585..c2f09323b 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -139,7 +139,7 @@ static int Module = 0; /* Name of the target specific runtime library */ static char* TargetLib = 0; -static int NoCrtLib = 0; +static int NoStdLib = 0; @@ -492,20 +492,20 @@ static void Link (void) CmdSetTarget (&LD65, Target); } - if (!NoCrtLib) - { - /* Determine which target libraries are needed */ - SetTargetFiles (); - } - /* Add all object files as parameters */ for (I = 0; I < LD65.FileCount; ++I) { CmdAddArg (&LD65, LD65.Files [I]); } - /* Add the system runtime library */ - if (TargetLib) { - CmdAddArg (&LD65, TargetLib); + /* Add the standard runtime library if it is not disabled */ + if (!NoStdLib) + { + /* Determine which target library is needed */ + SetTargetFiles (); + + if (TargetLib) { + CmdAddArg (&LD65, TargetLib); + } } /* Terminate the argument list with a NULL pointer */ @@ -816,7 +816,7 @@ static void Usage (void) " --memory-model model\t\tSet the memory model\n" " --module\t\t\tLink as a module\n" " --module-id id\t\tSpecify a module ID for the linker\n" - " --no-crt-lib\t\t\tDon't link default C runtime library\n" + " --no-std-lib\t\t\tDon't link standard runtime library\n" " --o65-model model\t\tOverride the o65 model\n" " --obj file\t\t\tLink this object file\n" " --obj-path path\t\tSpecify an object file search path\n" @@ -1172,11 +1172,11 @@ static void OptModuleId (const char* Opt attribute ((unused)), const char* Arg) -static void OptNoCrtLib (const char* Opt attribute ((unused)), - const char* Arg attribute ((unused))) -/* Disable default runtime library */ +static void OptNoStdLib (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Disable standard runtime library */ { - NoCrtLib = 1; + NoStdLib = 1; } @@ -1383,7 +1383,7 @@ int main (int argc, char* argv []) { "--memory-model", 1, OptMemoryModel }, { "--module", 0, OptModule }, { "--module-id", 1, OptModuleId }, - { "--no-crt-lib", 0, OptNoCrtLib }, + { "--no-std-lib", 0, OptNoStdLib }, { "--o65-model", 1, OptO65Model }, { "--obj", 1, OptObj }, { "--obj-path", 1, OptObjPath }, From 96196f00e9f409f48506b72547979020c8d38d02 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 18 Oct 2018 13:22:26 +0200 Subject: [PATCH 0898/2161] Adjusted library name. --- doc/cl65.sgml | 6 +++--- src/cl65/main.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/cl65.sgml b/doc/cl65.sgml index a2413fe7a..647b1bdbd 100644 --- a/doc/cl65.sgml +++ b/doc/cl65.sgml @@ -103,7 +103,7 @@ Long options: --memory-model model Set the memory model --module Link as a module --module-id id Specify a module id for the linker - --no-std-lib Don't link standard runtime library + --no-std-lib Don't link the standard library --o65-model model Override the o65 model --obj file Link this object file --obj-path path Specify an object file search path @@ -188,8 +188,8 @@ There are a few remaining options that control the behaviour of cl65: <tag><tt>--no-std-lib</tt></tag> - This option tells the cl65 to not include standard runtime library into the - list of libraries. + This option tells the cl65 to not include the standard library into the list + of libraries. diff --git a/src/cl65/main.c b/src/cl65/main.c index c2f09323b..bcb97b148 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -497,7 +497,7 @@ static void Link (void) CmdAddArg (&LD65, LD65.Files [I]); } - /* Add the standard runtime library if it is not disabled */ + /* Add the standard library if it is not disabled */ if (!NoStdLib) { /* Determine which target library is needed */ @@ -816,7 +816,7 @@ static void Usage (void) " --memory-model model\t\tSet the memory model\n" " --module\t\t\tLink as a module\n" " --module-id id\t\tSpecify a module ID for the linker\n" - " --no-std-lib\t\t\tDon't link standard runtime library\n" + " --no-std-lib\t\t\tDon't link the standard library\n" " --o65-model model\t\tOverride the o65 model\n" " --obj file\t\t\tLink this object file\n" " --obj-path path\t\tSpecify an object file search path\n" @@ -1174,7 +1174,7 @@ static void OptModuleId (const char* Opt attribute ((unused)), const char* Arg) static void OptNoStdLib (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) -/* Disable standard runtime library */ +/* Disable the standard library */ { NoStdLib = 1; } From d4088f9eee390dc9c88a780eb90d96b661be5e22 Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky <me@veg.by> Date: Wed, 17 Oct 2018 22:05:21 +0300 Subject: [PATCH 0899/2161] Don't output a warning about alignment when section address is defined by START or OFFSET and fits required alignment requirements --- src/ld65/config.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ld65/config.c b/src/ld65/config.c index 73eee1caa..1d3e810f6 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -1881,9 +1881,14 @@ unsigned CfgProcess (void) */ /* Check if the alignment for the segment from the linker - ** config. is a multiple for that of the segment. + ** config is a multiple for that of the segment. + ** If START or OFFSET is provided instead of ALIGN, check + ** if its address fits alignment requirements. */ - if ((S->RunAlignment % S->Seg->Alignment) != 0) { + unsigned long AlignedBy = (S->Flags & SF_START) ? S->Addr + : (S->Flags & SF_OFFSET) ? (S->Addr + M->Start) + : S->RunAlignment; + if ((AlignedBy % S->Seg->Alignment) != 0) { /* Segment requires another alignment than configured ** in the linker. */ From f73aa2af718adf255ad58c7419587c954270135f Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky <me@veg.by> Date: Fri, 19 Oct 2018 11:46:48 +0300 Subject: [PATCH 0900/2161] '--no-std-lib' was renamed to '--no-target-lib' --- doc/cl65.sgml | 6 +++--- src/cl65/main.c | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/doc/cl65.sgml b/doc/cl65.sgml index 647b1bdbd..ef7309eec 100644 --- a/doc/cl65.sgml +++ b/doc/cl65.sgml @@ -103,7 +103,7 @@ Long options: --memory-model model Set the memory model --module Link as a module --module-id id Specify a module id for the linker - --no-std-lib Don't link the standard library + --no-target-lib Don't link the target library --o65-model model Override the o65 model --obj file Link this object file --obj-path path Specify an object file search path @@ -186,9 +186,9 @@ There are a few remaining options that control the behaviour of cl65: seem to use cc65 to develop for the C64. - <tag><tt>--no-std-lib</tt></tag> + <tag><tt>--no-target-lib</tt></tag> - This option tells the cl65 to not include the standard library into the list + This option tells the cl65 to not include the target library into the list of libraries. diff --git a/src/cl65/main.c b/src/cl65/main.c index bcb97b148..e61bd02a5 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -138,8 +138,8 @@ static int Module = 0; #define MODULE_EXT ".o65" /* Name of the target specific runtime library */ -static char* TargetLib = 0; -static int NoStdLib = 0; +static char* TargetLib = 0; +static int NoTargetLib = 0; @@ -497,8 +497,8 @@ static void Link (void) CmdAddArg (&LD65, LD65.Files [I]); } - /* Add the standard library if it is not disabled */ - if (!NoStdLib) + /* Add the target library if it is not disabled */ + if (!NoTargetLib) { /* Determine which target library is needed */ SetTargetFiles (); @@ -816,7 +816,7 @@ static void Usage (void) " --memory-model model\t\tSet the memory model\n" " --module\t\t\tLink as a module\n" " --module-id id\t\tSpecify a module ID for the linker\n" - " --no-std-lib\t\t\tDon't link the standard library\n" + " --no-target-lib\t\tDon't link the target library\n" " --o65-model model\t\tOverride the o65 model\n" " --obj file\t\t\tLink this object file\n" " --obj-path path\t\tSpecify an object file search path\n" @@ -1172,11 +1172,11 @@ static void OptModuleId (const char* Opt attribute ((unused)), const char* Arg) -static void OptNoStdLib (const char* Opt attribute ((unused)), - const char* Arg attribute ((unused))) -/* Disable the standard library */ +static void OptNoTargetLib (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Disable the target library */ { - NoStdLib = 1; + NoTargetLib = 1; } @@ -1383,7 +1383,7 @@ int main (int argc, char* argv []) { "--memory-model", 1, OptMemoryModel }, { "--module", 0, OptModule }, { "--module-id", 1, OptModuleId }, - { "--no-std-lib", 0, OptNoStdLib }, + { "--no-target-lib", 0, OptNoTargetLib }, { "--o65-model", 1, OptO65Model }, { "--obj", 1, OptObj }, { "--obj-path", 1, OptObjPath }, From ee7514fea2f5499087bcd11344caec0a13b634d6 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Tue, 18 Sep 2018 21:52:37 +0200 Subject: [PATCH 0901/2161] Remove BASHEAD segment which is not useful --- cfg/telestrat.cfg | 4 ++-- libsrc/telestrat/orixhdr.s | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cfg/telestrat.cfg b/cfg/telestrat.cfg index 42e8d2cb5..400958f86 100644 --- a/cfg/telestrat.cfg +++ b/cfg/telestrat.cfg @@ -6,8 +6,8 @@ SYMBOLS { MEMORY { ZP: file = "", define = yes, start = $00B0, size = $003A; ORIXHDR: file = %O, type = ro, start = $0000, size = $001F; - BASHEAD: file = %O, define = yes, start = $0801, size = $000D; - MAIN: file = %O, define = yes, start = __BASHEAD_LAST__, size = __RAMEND__ - __MAIN_START__; +# BASHEAD: file = %O, define = yes, start = $0801, size = $000D; + MAIN: file = %O, define = yes, start = $0800, size = __RAMEND__ - __MAIN_START__; BSS: file = "", start = __ONCE_RUN__, size = __RAMEND__ - __STACKSIZE__ - __ONCE_RUN__; } SEGMENTS { diff --git a/libsrc/telestrat/orixhdr.s b/libsrc/telestrat/orixhdr.s index 6fe2fca73..0046bb79c 100644 --- a/libsrc/telestrat/orixhdr.s +++ b/libsrc/telestrat/orixhdr.s @@ -9,7 +9,7 @@ ; These symbols, also, come from the configuration file. .import __AUTORUN__, __PROGFLAG__ - .import __BASHEAD_START__, __MAIN_LAST__ + .import __MAIN_START__, __MAIN_LAST__ ; ------------------------------------------------------------------------ @@ -29,7 +29,7 @@ .byte $00 ; reserved .byte $00 ; auto or not - .word __BASHEAD_START__ ; Address of start of file + .word __MAIN_START__ ; Address of start of file .word __MAIN_LAST__ - 1 ; Address of end of file - .word __BASHEAD_START__ ; Address of start of file + .word __MAIN_START__ ; Address of start of file From ff182f9498b864c427372aae8953e9f08acf1c5d Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Wed, 17 Oct 2018 21:12:05 +0200 Subject: [PATCH 0902/2161] Cleaning telestrat.cfg (no need to have bashead segment). Some primitives added --- asminc/telestrat.inc | 4 ++++ cfg/telestrat.cfg | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 956d31be3..7c923f6f8 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -149,6 +149,8 @@ SCREEN := $BB80 ; ROM entries ; telemon primitives (2.4 & 3.x) + +; all values are used to call bank 7 of telestrat cardridge. It works with 'brk value' XRD0 = $08 XRDW0 = $0C XWR0 = $10 @@ -158,6 +160,7 @@ XHIRES = $1A XFILLM = $1C XMINMA = $1F XVARS = $24 ; only in TELEMON 3.x, in telemon 2.4, it's XNOMFI ($24) +XCRLF = $25 ; jump a line and return to the beginning of the line XFREAD = $27 ; only in TELEMON 3.x XOPEN = $30 ; only in TELEMON 3.x XCOSCR = $34 ; switch off cursor @@ -173,6 +176,7 @@ XZAP = $46 XSHOOT = $47 XMKDIR = $4B ; create a folder. Only available in telemon 3.x XRM = $4D ; remove a folder or a file. Only available in telemon 3.x +XMALLOC = $5B ; only in telemon 3.x XSOUT = $67 ; send accumulator value (A) to RS232, available in telemon 2.4 & 3.x : if RS232 buffer is full, the Oric Telestrat freezes XHRSSE = $8C ; set hires position cursor XDRAWA = $8D ; draw a line diff --git a/cfg/telestrat.cfg b/cfg/telestrat.cfg index 400958f86..9aa182116 100644 --- a/cfg/telestrat.cfg +++ b/cfg/telestrat.cfg @@ -6,8 +6,7 @@ SYMBOLS { MEMORY { ZP: file = "", define = yes, start = $00B0, size = $003A; ORIXHDR: file = %O, type = ro, start = $0000, size = $001F; -# BASHEAD: file = %O, define = yes, start = $0801, size = $000D; - MAIN: file = %O, define = yes, start = $0800, size = __RAMEND__ - __MAIN_START__; + MAIN: file = %O, define = yes, start = $0800, size = __RAMEND__ - __MAIN_START__; BSS: file = "", start = __ONCE_RUN__, size = __RAMEND__ - __STACKSIZE__ - __ONCE_RUN__; } SEGMENTS { From 6a18ad5fbf3e8df59007a9ec5bcc084f8ad67299 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Wed, 17 Oct 2018 22:13:24 +0200 Subject: [PATCH 0903/2161] Clean wherey.s --- libsrc/telestrat/wherey.s | 2 -- 1 file changed, 2 deletions(-) diff --git a/libsrc/telestrat/wherey.s b/libsrc/telestrat/wherey.s index 4958f10cf..962608ca2 100644 --- a/libsrc/telestrat/wherey.s +++ b/libsrc/telestrat/wherey.s @@ -3,8 +3,6 @@ ; .export _wherey - .importzp sp - .include "telestrat.inc" .proc _wherey From 5585396532bc04d7a78186950d3bdde3b89ece01 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Wed, 17 Oct 2018 22:36:00 +0200 Subject: [PATCH 0904/2161] By default, we get the memory reserved for hires mode --- cfg/telestrat.cfg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cfg/telestrat.cfg b/cfg/telestrat.cfg index 9aa182116..2a8ebfd70 100644 --- a/cfg/telestrat.cfg +++ b/cfg/telestrat.cfg @@ -1,7 +1,8 @@ SYMBOLS { __ORIXHDR__: type = import; __STACKSIZE__: type = weak, value = $0800; # 2K stack - __RAMEND__: type = weak, value = $9800; + __GRAB__: type = weak, value = 1; # 0=don't grab graphics RAM, 1=grab graphics RAM + __RAMEND__: type = weak, value = $9800 + $1C00 * __GRAB__; } MEMORY { ZP: file = "", define = yes, start = $00B0, size = $003A; From af7b271f558656dc3ce082339297bcf628d14ec8 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Thu, 18 Oct 2018 23:48:20 +0200 Subject: [PATCH 0905/2161] update ld65.sgml with telestrat target --- doc/ld65.sgml | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 1750cb3e8..9cbb5aad8 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -174,6 +174,7 @@ Here is a description of all of the command-line options: <item>sim6502 <item>sim65c02 <item>supervision + <item>telestrat <item>vic20 </itemize> From a22b10e72b704f5fb96cbd6559f6eb6b5882af75 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Thu, 18 Oct 2018 23:57:21 +0200 Subject: [PATCH 0906/2161] Correct grab default value --- cfg/telestrat.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/telestrat.cfg b/cfg/telestrat.cfg index 2a8ebfd70..14ae30311 100644 --- a/cfg/telestrat.cfg +++ b/cfg/telestrat.cfg @@ -1,7 +1,7 @@ SYMBOLS { __ORIXHDR__: type = import; __STACKSIZE__: type = weak, value = $0800; # 2K stack - __GRAB__: type = weak, value = 1; # 0=don't grab graphics RAM, 1=grab graphics RAM + __GRAB__: type = weak, value = 0; # 0=don't grab graphics RAM, 1=grab graphics RAM __RAMEND__: type = weak, value = $9800 + $1C00 * __GRAB__; } MEMORY { From 385260e453ca63c13413c22900e38996bcd2f355 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Fri, 19 Oct 2018 23:21:16 +0200 Subject: [PATCH 0907/2161] Fix comments and TELEMON uppercase --- asminc/telestrat.inc | 69 +++++++++++++++++++------------------- libsrc/telestrat/orixhdr.s | 16 ++++----- 2 files changed, 42 insertions(+), 43 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 7c923f6f8..7ba1dd43b 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -1,31 +1,29 @@ ; -; Oric Telemon definition -; Telemon 2.4 & Telemon 3.x -; For telemon 3.x check http://orix.oric.org +; Oric TELEMON definition +; TELEMON 2.4 & TELEMON 3.x +; For TELEMON 3.x check http://orix.oric.org ; - ; --------------------------------------------------------------------------- ; Constants -SCREEN_XSIZE = 40 ; screen columns -SCREEN_YSIZE = 28 ; screen rows +SCREEN_XSIZE = 40 ; Screen columns +SCREEN_YSIZE = 28 ; Screen rows FUNCTKEY = $A5 -FNAME_LEN = 11 ; maximum length of file-name +FNAME_LEN = 11 ; Maximum length of file-name ; --------------------------------------------------------------------------- ; I/O Identifier -; theses identifers are used for channel management +; Theses identifers are used for channel management ; -XKBD = $80 ; keyboard +XKBD = $80 ; Keyboard XRSE = $83 ; RS232 in -XSCR = $88 ; screen +XSCR = $88 ; Screen XRSS = $90 ; RS232 out - ; --------------------------------------------------------------------------- ; Zero page @@ -43,7 +41,7 @@ TR5 := $11 TR6 := $12 TR7 := $13 -PTR_READ_DEST := $2C ; used for XFREAD and XWRITE only in telemon 3.x +PTR_READ_DEST := $2C ; Used for XFREAD and XWRITE only in TELEMON 3.x HRSX := $46 HRSY := $47 @@ -59,7 +57,7 @@ HRSFB := $57 ; RS232T ; b0-b3 : speed ; 1111 => 19200 bps (please note that telestrat can't handle this speed without stopping all IRQ except ACIA's one) -; 1100 => 9600 bps (default from telemon) +; 1100 => 9600 bps (default from TELEMON) ; 1110 => 4800 bps ; 1010 => 2400 bps ; 1000 => 1200 bps @@ -92,8 +90,6 @@ RS232C := $5A ; Low memory IRQVec := $02FB ; "fast" interrupt vector - - ; --------------------------------------------------------------------------- ; I/O locations @@ -148,39 +144,40 @@ SCREEN := $BB80 ; --------------------------------------------------------------------------- ; ROM entries -; telemon primitives (2.4 & 3.x) +; TELEMON primitives (2.4 & 3.x) ; all values are used to call bank 7 of telestrat cardridge. It works with 'brk value' XRD0 = $08 XRDW0 = $0C XWR0 = $10 -XWSTR0 = $14 ; write a string in text mode +XWSTR0 = $14 ; Write a string in text mode XTEXT = $19 XHIRES = $1A XFILLM = $1C XMINMA = $1F -XVARS = $24 ; only in TELEMON 3.x, in telemon 2.4, it's XNOMFI ($24) -XCRLF = $25 ; jump a line and return to the beginning of the line -XFREAD = $27 ; only in TELEMON 3.x -XOPEN = $30 ; only in TELEMON 3.x -XCOSCR = $34 ; switch off cursor -XCSSCR = $35 ; switch on cursor -XCLOSE = $3A ; only in TELEMON 3.x Close file -XFWRITE = $3B ; only in TELEMON 3.x write file +XVARS = $24 ; Only in TELEMON 3.x, in TELEMON 2.4, it's XNOMFI ($24) +XCRLF = $25 ; Jump a line and return to the beginning of the line +XFREAD = $27 ; Only in TELEMON 3.x (bank 7 of Orix) +XOPEN = $30 ; Only in TELEMON 3.x (bank 7 of Orix) +XCOSCR = $34 ; Switch off cursor +XCSSCR = $35 ; Switch on cursor +XCLOSE = $3A ; Only in TELEMON 3.x close file (bank 7 of Orix) +XFWRITE = $3B ; Only in TELEMON 3.x write file (bank 7 of Orix) XSONPS = $40 -XOUPS = $42 ; send Oups sound into PSG +XOUPS = $42 ; Send Oups sound into PSG XPLAY = $43 XSOUND = $44 XMUSIC = $45 XZAP = $46 XSHOOT = $47 -XMKDIR = $4B ; create a folder. Only available in telemon 3.x -XRM = $4D ; remove a folder or a file. Only available in telemon 3.x -XMALLOC = $5B ; only in telemon 3.x -XSOUT = $67 ; send accumulator value (A) to RS232, available in telemon 2.4 & 3.x : if RS232 buffer is full, the Oric Telestrat freezes -XHRSSE = $8C ; set hires position cursor -XDRAWA = $8D ; draw a line -XDRAWR = $8E ; draw a line +XMKDIR = $4B ; Create a folder. Only available in TELEMON 3.x (bank 7 of Orix) +XRM = $4D ; Remove a folder or a file. Only available in TELEMON 3.x (bank 7 of Orix) +XMALLOC = $5B ; Only in TELEMON 3.x (bank 7 of Orix) +XFREE = $62 ; Only in TELEMON 3.x (bank 7 of Orix) +XSOUT = $67 ; Send accumulator value (A) to RS232, available in TELEMON 2.4 & 3.x : if RS232 buffer is full, the Oric Telestrat freezes +XHRSSE = $8C ; Set hires position cursor +XDRAWA = $8D ; Draw a line +XDRAWR = $8E ; Draw a line XCIRCL = $8F XCURSE = $90 XCURMO = $91 @@ -190,7 +187,7 @@ XBOX = $94 XABOX = $95 XFILL = $96 XCHAR = $97 -XSCHAR = $98 ; draw a string in hires +XSCHAR = $98 ; Draw a string in hires XEXPLO = $9C XPING = $9D @@ -205,7 +202,7 @@ SCRX := $220 SCRY := $224 ADSCRL := $218 ADSCRH := $21C -HRSPAT := $2AA ; hires pattern : it's used to draw pattern for a line or a circle +HRSPAT := $2AA ; Hires pattern : it's used to draw pattern for a line or a circle IRQVECTOR := $2FA @@ -217,10 +214,12 @@ BUFEDT := $590 MAX_BUFEDT_LENGTH=110 +; --------------------------------------------------------------------------- ; Hardware CH376_DATA := $340 CH376_COMMAND := $341 +; --------------------------------------------------------------------------- ; MACRO .macro BRK_TELEMON value diff --git a/libsrc/telestrat/orixhdr.s b/libsrc/telestrat/orixhdr.s index 0046bb79c..58e93efbb 100644 --- a/libsrc/telestrat/orixhdr.s +++ b/libsrc/telestrat/orixhdr.s @@ -17,19 +17,19 @@ .segment "ORIXHDR" - .byte $01, $00 ; non C64 marker (same as o65 format) + .byte $01, $00 ; Non C64 marker (same as o65 format) - .byte "ori" ; magic number + .byte "ori" ; Magic number - .byte $01 ; version of the header + .byte $01 ; Version of the header .byte $00,%00000000 ; 6502 only - .byte $00,$00 ; type of language + .byte $00,$00 ; Type of language .byte $00,$00 ; OS version - .byte $00 ; reserved - .byte $00 ; auto or not + .byte $00 ; Reserved + .byte $00 ; Auto or not .word __MAIN_START__ ; Address of start of file - .word __MAIN_LAST__ - 1 ; Address of end of file - .word __MAIN_START__ ; Address of start of file + .word __MAIN_LAST__ - 1 ; Address of end of file + .word __MAIN_START__ ; Address of start of file From 554448a1f1c1e5daf72193c9609bf1112fc43ce9 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 20 Oct 2018 13:40:16 -0400 Subject: [PATCH 0908/2161] .byt "" emits no data; avoid a ca65 crash. Fixes #775 on GitHub. --- src/ca65/pseudo.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 5dd67af90..a1115606b 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -574,7 +574,7 @@ static void DoByte (void) /* Record type information */ Span* S = OpenSpan (); - StrBuf Type = STATIC_STRBUF_INITIALIZER; + StrBuf Type = AUTO_STRBUF_INITIALIZER; /* Parse arguments */ while (1) { @@ -598,9 +598,14 @@ static void DoByte (void) } } - /* Close the span, then add type information to it */ + /* Close the span, then add type information to it. + ** Note: empty string operands emit nothing; + ** so, add a type only if there's a span. + */ S = CloseSpan (S); - SetSpanType (S, GenArrayType (&Type, GetSpanSize (S), EType, sizeof (EType))); + if (S != 0) { + SetSpanType (S, GenArrayType (&Type, GetSpanSize (S), EType, sizeof (EType))); + } /* Free the type string */ SB_Done (&Type); From c2568d804d8c5aa341dcfc86aea9347e556f24a6 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 23 Oct 2018 19:52:23 -0400 Subject: [PATCH 0909/2161] Fixed the Plus4's serial driver's ACIA address. --- libsrc/plus4/ser/plus4-stdser.s | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libsrc/plus4/ser/plus4-stdser.s b/libsrc/plus4/ser/plus4-stdser.s index 47dd96042..6cacff327 100644 --- a/libsrc/plus4/ser/plus4-stdser.s +++ b/libsrc/plus4/ser/plus4-stdser.s @@ -1,14 +1,14 @@ ; -; Serial driver for the builtin 6551 ACIA of the Plus/4. +; Serial driver for the built-in 6551 ACIA of the Plus/4. ; ; Ullrich von Bassewitz, 2003-12-13 ; ; The driver is based on the cc65 rs232 module, which in turn is based on -; Craig Bruce device driver for the Switftlink/Turbo-232. +; Craig Bruce's device driver for the Switftlink/Turbo-232. ; ; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998. ; -; This software is Public Domain. It is in Buddy assembler format. +; This (C. Bruce) software is Public Domain. It is in Buddy assembler format. ; ; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from ; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232 @@ -17,7 +17,7 @@ ; ; The code assumes that the kernal + I/O are in context. On the C128, call ; it from Bank 15. On the C64, don't flip out the Kernal unless a suitable -; NMI catcher is put into the RAM under then Kernal. For the SuperCPU, the +; NMI catcher is put into the RAM under the Kernal. For the SuperCPU, the ; interrupt handling assumes that the 65816 is in 6502-emulation mode. ; @@ -36,7 +36,7 @@ ; Driver signature - .byte $73, $65, $72 ; "ser" + .byte $73, $65, $72 ; ASCII "ser" .byte SER_API_VERSION ; Serial API version number ; Library reference @@ -58,11 +58,11 @@ ;---------------------------------------------------------------------------- ; I/O definitions -ACIA = $DE00 -ACIA_DATA = ACIA+0 ; Data register -ACIA_STATUS = ACIA+1 ; Status register -ACIA_CMD = ACIA+2 ; Command register -ACIA_CTRL = ACIA+3 ; Control register +ACIA := $FD00 +ACIA_DATA := ACIA+0 ; Data register +ACIA_STATUS := ACIA+1 ; Status register +ACIA_CMD := ACIA+2 ; Command register +ACIA_CTRL := ACIA+3 ; Control register ;---------------------------------------------------------------------------- ; From f5534a54325ce133b939119c2875c1ae49736259 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Thu, 1 Nov 2018 17:45:51 +0100 Subject: [PATCH 0910/2161] Add definitions in telestrat.inc (TELEMON 2.4) --- asminc/telestrat.inc | 67 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 7ba1dd43b..0296f5cb8 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -32,6 +32,11 @@ XRSS = $90 ; RS232 out RES := $00 RESB := $02 +DECDEB := $04 +DECFIN := $06 +DECCIB := $08 +DECTRV := $0A + TR0 := $0C TR1 := $0D TR2 := $0E @@ -41,6 +46,9 @@ TR5 := $11 TR6 := $12 TR7 := $13 +DEFAFF := $14 +ADSCR := $26 + PTR_READ_DEST := $2C ; Used for XFREAD and XWRITE only in TELEMON 3.x HRSX := $46 @@ -86,6 +94,9 @@ RS232T := $59 RS232C := $5A +VARLNG := $8C +VARAPL := $D0 + ; --------------------------------------------------------------------------- ; Low memory IRQVec := $02FB ; "fast" interrupt vector @@ -147,10 +158,31 @@ SCREEN := $BB80 ; TELEMON primitives (2.4 & 3.x) ; all values are used to call bank 7 of telestrat cardridge. It works with 'brk value' +XOP0 = $00 ; Open device on channel 0 +XOP1 = $01 ; Open device on channel 1 +XOP2 = $02 ; Open device on channel 2 +XOP3 = $03 ; Open device on channel 3 + +XCL0 = $04 ; Close channel 0 +XCL1 = $05 ; Close channel 1 +XCL2 = $06 ; Close channel 2 +XCL3 = $07 ; Close channel 3 + XRD0 = $08 XRDW0 = $0C -XWR0 = $10 -XWSTR0 = $14 ; Write a string in text mode + +XWR0 = $10 ; Write a char in channel 0 +XWR1 = $11 ; Write a char in channel 1 +XWR2 = $12 ; Write a char in channel 2 +XWR3 = $13 ; Write a char in channel 3 + +XWSTR0 = $14 ; Write a string in text mode channel 0 +XWSTR1 = $15 ; Write a string in text mode channel 1 +XWSTR2 = $16 ; Write a string in text mode channel 2 +XWSTR3 = $17 ; Write a string in text mode channel 3 + +XDECAL = $18 + XTEXT = $19 XHIRES = $1A XFILLM = $1C @@ -158,44 +190,53 @@ XMINMA = $1F XVARS = $24 ; Only in TELEMON 3.x, in TELEMON 2.4, it's XNOMFI ($24) XCRLF = $25 ; Jump a line and return to the beginning of the line XFREAD = $27 ; Only in TELEMON 3.x (bank 7 of Orix) +XHEXA = $2A ; Convert a number into hex +XBINDX = $28 ; Convert a number into hex and displays on channel 0 XOPEN = $30 ; Only in TELEMON 3.x (bank 7 of Orix) XCOSCR = $34 ; Switch off cursor XCSSCR = $35 ; Switch on cursor +XSCRSE = $36 XCLOSE = $3A ; Only in TELEMON 3.x close file (bank 7 of Orix) XFWRITE = $3B ; Only in TELEMON 3.x write file (bank 7 of Orix) -XSONPS = $40 +XSONPS = $40 ; Send data to PSG register (14 values) XOUPS = $42 ; Send Oups sound into PSG -XPLAY = $43 +XPLAY = $43 ; Play a sound XSOUND = $44 XMUSIC = $45 -XZAP = $46 +XZAP = $46 ; Send Zap sound to PSG XSHOOT = $47 XMKDIR = $4B ; Create a folder. Only available in TELEMON 3.x (bank 7 of Orix) XRM = $4D ; Remove a folder or a file. Only available in TELEMON 3.x (bank 7 of Orix) +XGOKBD = $52 XMALLOC = $5B ; Only in TELEMON 3.x (bank 7 of Orix) XFREE = $62 ; Only in TELEMON 3.x (bank 7 of Orix) XSOUT = $67 ; Send accumulator value (A) to RS232, available in TELEMON 2.4 & 3.x : if RS232 buffer is full, the Oric Telestrat freezes XHRSSE = $8C ; Set hires position cursor XDRAWA = $8D ; Draw a line -XDRAWR = $8E ; Draw a line -XCIRCL = $8F -XCURSE = $90 -XCURMO = $91 +XDRAWR = $8E ; Draw a line (relative) +XCIRCL = $8F ; Draw a circle +XCURSE = $90 ; Plot a pixel +XCURMO = $91 ; Move to x,y pos in Hires XPAPER = $92 XINK = $93 -XBOX = $94 +XBOX = $94 ; Draw a box XABOX = $95 XFILL = $96 -XCHAR = $97 +XCHAR = $97 ; Display a char on the screen in Hires XSCHAR = $98 ; Draw a string in hires -XEXPLO = $9C -XPING = $9D +XEXPLO = $9C ; Send Explode sound to PSG +XPING = $9D ; Send Ping sound to PSG ; --------------------------------------------------------------------------- ; ROM entries variables PWD_PTR = $00 +; --------------------------------------------------------------------------- +; +BUFTRV := $100 + + ; --------------------------------------------------------------------------- ; Page $200 SCRX := $220 From 40f42e977f40a9a861345d77ef6f8b986fbece4b Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 6 Nov 2018 11:13:23 +0100 Subject: [PATCH 0911/2161] Adjusted comments to match actual prototypes. --- libsrc/apple2/break.s | 2 +- libsrc/apple2/gettime.s | 2 +- libsrc/apple2/settime.s | 2 +- libsrc/atari/break.s | 2 +- libsrc/c128/break.s | 2 +- libsrc/c128/gettime.s | 2 +- libsrc/c128/settime.s | 2 +- libsrc/c16/break.s | 2 +- libsrc/c64/break.s | 2 +- libsrc/c64/gettime.s | 2 +- libsrc/c64/settime.s | 2 +- libsrc/cbm510/break.s | 2 +- libsrc/cbm510/gettime.s | 2 +- libsrc/cbm510/settime.s | 2 +- libsrc/cbm610/break.s | 2 +- libsrc/cbm610/gettime.s | 2 +- libsrc/cbm610/settime.s | 2 +- libsrc/geos-common/system/gettime.c | 2 +- libsrc/pet/break.s | 2 +- libsrc/plus4/break.s | 2 +- libsrc/vic20/break.s | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/libsrc/apple2/break.s b/libsrc/apple2/break.s index 9129dde96..21538e1e5 100644 --- a/libsrc/apple2/break.s +++ b/libsrc/apple2/break.s @@ -1,7 +1,7 @@ ; ; Ullrich von Bassewitz, 27.09.1998 ; -; void set_brk (unsigned Addr); +; void __fastcall__ set_brk (unsigned Addr); ; void reset_brk (void); ; diff --git a/libsrc/apple2/gettime.s b/libsrc/apple2/gettime.s index a11032af5..dc00e3b49 100644 --- a/libsrc/apple2/gettime.s +++ b/libsrc/apple2/gettime.s @@ -1,7 +1,7 @@ ; ; Oliver Schmidt, 14.08.2018 ; -; int clock_gettime (clockid_t clk_id, struct timespec *tp); +; int __fastcall__ clock_gettime (clockid_t clk_id, struct timespec *tp); ; .import pushax, steaxspidx, incsp1, incsp3, return0 diff --git a/libsrc/apple2/settime.s b/libsrc/apple2/settime.s index 2235d1a3f..07032fdd1 100644 --- a/libsrc/apple2/settime.s +++ b/libsrc/apple2/settime.s @@ -1,7 +1,7 @@ ; ; Oliver Schmidt, 15.08.2018 ; -; int clock_settime (clockid_t clk_id, const struct timespec *tp); +; int __fastcall__ clock_settime (clockid_t clk_id, const struct timespec *tp); ; .import __dos_type diff --git a/libsrc/atari/break.s b/libsrc/atari/break.s index a53ed9803..0cfba1c5a 100644 --- a/libsrc/atari/break.s +++ b/libsrc/atari/break.s @@ -1,7 +1,7 @@ ; ; Christian Groessler, 27-Feb-2000 ; -; void set_brk (unsigned Addr); +; void __fastcall__ set_brk (unsigned Addr); ; void reset_brk (void); ; diff --git a/libsrc/c128/break.s b/libsrc/c128/break.s index f2f872be8..092ca3469 100644 --- a/libsrc/c128/break.s +++ b/libsrc/c128/break.s @@ -1,7 +1,7 @@ ; ; Ullrich von Bassewitz, 27.09.1998 ; -; void set_brk (unsigned Addr); +; void __fastcall__ set_brk (unsigned Addr); ; void reset_brk (void); ; diff --git a/libsrc/c128/gettime.s b/libsrc/c128/gettime.s index ba0068aa7..0267e683f 100644 --- a/libsrc/c128/gettime.s +++ b/libsrc/c128/gettime.s @@ -2,7 +2,7 @@ ; Stefan Haubenthal, 27.7.2009 ; Oliver Schmidt, 14.8.2018 ; -; int clock_gettime (clockid_t clk_id, struct timespec *tp); +; int __fastcall__ clock_gettime (clockid_t clk_id, struct timespec *tp); ; .include "time.inc" diff --git a/libsrc/c128/settime.s b/libsrc/c128/settime.s index 0d95a3958..fe306b735 100644 --- a/libsrc/c128/settime.s +++ b/libsrc/c128/settime.s @@ -1,7 +1,7 @@ ; ; Oliver Schmidt, 16.8.2018 ; -; int clock_settime (clockid_t clk_id, const struct timespec *tp); +; int __fastcall__ clock_settime (clockid_t clk_id, const struct timespec *tp); ; .include "time.inc" diff --git a/libsrc/c16/break.s b/libsrc/c16/break.s index e143ac6d5..456dbb434 100644 --- a/libsrc/c16/break.s +++ b/libsrc/c16/break.s @@ -1,7 +1,7 @@ ; ; Ullrich von Bassewitz, 27.09.1998 ; -; void set_brk (unsigned Addr); +; void __fastcall__ set_brk (unsigned Addr); ; void reset_brk (void); ; diff --git a/libsrc/c64/break.s b/libsrc/c64/break.s index 1c44c59a0..63fab707f 100644 --- a/libsrc/c64/break.s +++ b/libsrc/c64/break.s @@ -1,7 +1,7 @@ ; ; Ullrich von Bassewitz, 27.09.1998 ; -; void set_brk (unsigned Addr); +; void __fastcall__ set_brk (unsigned Addr); ; void reset_brk (void); ; diff --git a/libsrc/c64/gettime.s b/libsrc/c64/gettime.s index ddb865c8f..25fc8c94a 100644 --- a/libsrc/c64/gettime.s +++ b/libsrc/c64/gettime.s @@ -2,7 +2,7 @@ ; Stefan Haubenthal, 27.7.2009 ; Oliver Schmidt, 14.8.2018 ; -; int clock_gettime (clockid_t clk_id, struct timespec *tp); +; int __fastcall__ clock_gettime (clockid_t clk_id, struct timespec *tp); ; .include "time.inc" diff --git a/libsrc/c64/settime.s b/libsrc/c64/settime.s index c72d535bc..88b4d0bef 100644 --- a/libsrc/c64/settime.s +++ b/libsrc/c64/settime.s @@ -1,7 +1,7 @@ ; ; Oliver Schmidt, 16.8.2018 ; -; int clock_settime (clockid_t clk_id, const struct timespec *tp); +; int __fastcall__ clock_settime (clockid_t clk_id, const struct timespec *tp); ; .include "time.inc" diff --git a/libsrc/cbm510/break.s b/libsrc/cbm510/break.s index b58db068e..fff475d3a 100644 --- a/libsrc/cbm510/break.s +++ b/libsrc/cbm510/break.s @@ -1,7 +1,7 @@ ; ; Ullrich von Bassewitz, 27.09.1998 ; -; void set_brk (unsigned Addr); +; void __fastcall__ set_brk (unsigned Addr); ; void reset_brk (void); ; diff --git a/libsrc/cbm510/gettime.s b/libsrc/cbm510/gettime.s index c767c1f33..7f9e1017c 100644 --- a/libsrc/cbm510/gettime.s +++ b/libsrc/cbm510/gettime.s @@ -4,7 +4,7 @@ ; 2018-08-18, Oliver Schmidt ; 2018-08-19, Greg King ; -; int clock_gettime (clockid_t clk_id, struct timespec *tp); +; int __fastcall__ clock_gettime (clockid_t clk_id, struct timespec *tp); ; .include "time.inc" diff --git a/libsrc/cbm510/settime.s b/libsrc/cbm510/settime.s index 6eb08a1ac..08de7915a 100644 --- a/libsrc/cbm510/settime.s +++ b/libsrc/cbm510/settime.s @@ -2,7 +2,7 @@ ; 2018-08-18, Oliver Schmidt ; 2018-08-19, Greg King ; -; int clock_settime (clockid_t clk_id, const struct timespec *tp); +; int __fastcall__ clock_settime (clockid_t clk_id, const struct timespec *tp); ; .include "time.inc" diff --git a/libsrc/cbm610/break.s b/libsrc/cbm610/break.s index 03927fa70..aa9d17f16 100644 --- a/libsrc/cbm610/break.s +++ b/libsrc/cbm610/break.s @@ -1,7 +1,7 @@ ; ; Ullrich von Bassewitz, 27.09.1998 ; -; void set_brk (unsigned Addr); +; void __fastcall__ set_brk (unsigned Addr); ; void reset_brk (void); ; diff --git a/libsrc/cbm610/gettime.s b/libsrc/cbm610/gettime.s index 4c66f7747..7e510af29 100644 --- a/libsrc/cbm610/gettime.s +++ b/libsrc/cbm610/gettime.s @@ -4,7 +4,7 @@ ; 2018-08-18, Oliver Schmidt ; 2018-08-19, Greg King ; -; int clock_gettime (clockid_t clk_id, struct timespec *tp); +; int __fastcall__ clock_gettime (clockid_t clk_id, struct timespec *tp); ; .include "time.inc" diff --git a/libsrc/cbm610/settime.s b/libsrc/cbm610/settime.s index 3d2a24af9..217135d76 100644 --- a/libsrc/cbm610/settime.s +++ b/libsrc/cbm610/settime.s @@ -2,7 +2,7 @@ ; 2018-08-18, Oliver Schmidt ; 2018-08-19, Greg King ; -; int clock_settime (clockid_t clk_id, const struct timespec *tp); +; int __fastcall__ clock_settime (clockid_t clk_id, const struct timespec *tp); ; .include "time.inc" diff --git a/libsrc/geos-common/system/gettime.c b/libsrc/geos-common/system/gettime.c index d695787c3..947a6a4f4 100644 --- a/libsrc/geos-common/system/gettime.c +++ b/libsrc/geos-common/system/gettime.c @@ -25,7 +25,7 @@ clock_t clock(void) return mktime(¤tTime); } -int clock_gettime(clockid_t, struct timespec *tp) +int __fastcall__ clock_gettime(clockid_t, struct timespec *tp) { tp->tv_sec = clock(); tp->tv_nsec = 0; diff --git a/libsrc/pet/break.s b/libsrc/pet/break.s index 49585ffef..42cd95bfa 100644 --- a/libsrc/pet/break.s +++ b/libsrc/pet/break.s @@ -1,7 +1,7 @@ ; ; Ullrich von Bassewitz, 26.11.1998 ; -; void set_brk (unsigned Addr); +; void __fastcall__ set_brk (unsigned Addr); ; void reset_brk (void); ; diff --git a/libsrc/plus4/break.s b/libsrc/plus4/break.s index 248a558c7..917304425 100644 --- a/libsrc/plus4/break.s +++ b/libsrc/plus4/break.s @@ -1,7 +1,7 @@ ; ; Ullrich von Bassewitz, 27.09.1998 ; -; void set_brk (unsigned Addr); +; void __fastcall__ set_brk (unsigned Addr); ; void reset_brk (void); ; diff --git a/libsrc/vic20/break.s b/libsrc/vic20/break.s index 9a5ef02e7..fc1edc727 100644 --- a/libsrc/vic20/break.s +++ b/libsrc/vic20/break.s @@ -1,7 +1,7 @@ ; ; Ullrich von Bassewitz, 27.09.1998 ; -; void set_brk (unsigned Addr); +; void __fastcall__ set_brk (unsigned Addr); ; void reset_brk (void); ; From 679d0468b99c4a2065e2e8921c91c864c614ef41 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 6 Nov 2018 11:57:57 +0100 Subject: [PATCH 0912/2161] Updated URLs. --- doc/geos.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/geos.sgml b/doc/geos.sgml index 1f8868090..8e50a2605 100644 --- a/doc/geos.sgml +++ b/doc/geos.sgml @@ -68,7 +68,7 @@ programs. The software needed: <itemize> <item><em/cc65/ Excellent package containing a C crosscompiler, a crossassembler and a linker, you - can get it from: <url url="http://cc65.github.io/cc65/">. + can get it from: <url url="https://cc65.github.io/">. <item><em/VICE/ This is a portable C64, C128 and few other Commodore computers emulator, you can obtain it from: <url url="http://vice-emu.sourceforge.net/">. The VICE package contains the <em/c1541/ program that is able @@ -80,7 +80,7 @@ The software needed: <item><em/opencbm/ A package that allows for communication directly with a 1541 and other Commodore IEC bus drives. It can be a replacement for Star Commander if you only want to transfer files to a disk and unconvert using GEOS program for - this purpose. Check out: <url url="http://opencbm.sourceforge.net/">. + this purpose. Check out: <url url="https://spiro.trikaliotis.net/opencbm">. </itemize> <p> VICE and cc65 are portable - they run on variety of platforms - DOS, Win32 and UNIX. GEOSLib only From 8fd1db4d7882cb7c65fc43a7cc25b4b3ac678b06 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 8 Nov 2018 20:43:46 +0100 Subject: [PATCH 0913/2161] Added basic docs on the clock_... functions. --- doc/funcref.sgml | 90 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 2 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 1fa6558a7..ade7a855f 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -748,9 +748,11 @@ communication, see also <tt>testcode/lib/ser-test.c</tt>. <sect1><tt/time.h/<label id="time.h"><p> <itemize> -<!-- <item><ref id="_systime" name="_systime"> --> <!-- <item><ref id="asctime" name="asctime"> --> <item><ref id="clock" name="clock"> +<item><ref id="clock_getres" name="clock_getres"> +<item><ref id="clock_gettime" name="clock_gettime"> +<item><ref id="clock_settime" name="clock_settime"> <!-- <item><ref id="ctime" name="ctime"> --> <!-- <item><ref id="gmtime" name="gmtime"> --> <!-- <item><ref id="localtime" name="localtime"> --> @@ -2574,6 +2576,89 @@ changing values. (See the description of <tt/cbm_k_udtim()/.) </quote> +<sect1>clock_getres<label id="clock_getres"><p> + +<quote> +<descrip> +<tag/Function/Determine the realtime clock resolution. +<tag/Header/<tt/<ref id="time.h" name="time.h">/ +<tag/Declaration/<tt/int __fastcall__ clock_getres (clockid_t clock_id, struct timespec *res);/ +<tag/Description/The <tt/clock_getres/ function finds the resolution (precision) +of the realtime clock. <tt/clock_id/ has to be <tt/CLOCK_REALTIME/. If <tt/res/ +is not <tt/NULL/, the resolution of the realtime clock is stored in the location +pointed to by <tt/res/. If <tt/res/ is <tt/NULL/, the clock resolution is not returned. +If the <tt/time/ argument of <tt/<ref id="clock_settime" name="clock_settime">/ is not +a multiple of <tt/res/, then the value is truncated to a multiple of <tt/res/. 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. +<tag/Notes/<itemize> +<item>The function is only available as fastcall function, so it may only +be used in presence of a prototype. +<item>Depending on the target either the <tt/tv_sec/ or the <tt/tv_nsec/ +field of the <tt/struct timespec/ returned is zero. +</itemize> +<tag/Availability/POSIX 1003.1 +<tag/See also/ +<ref id="clock_gettime" name="clock_gettime">, +<ref id="clock_settime" name="clock_settime"> +<tag/Example/None. +</descrip> +</quote> + + +<sect1>clock_gettime<label id="clock_gettime"><p> + +<quote> +<descrip> +<tag/Function/Get the time from the realtime clock. +<tag/Header/<tt/<ref id="time.h" name="time.h">/ +<tag/Declaration/<tt/int __fastcall__ clock_gettime (clockid_t clock_id, struct timespec *tp);/ +<tag/Description/The <tt/clock_gettime/ function retrieves the time since the 1970-01-01 00:00:00 +measured in nanoseconds. <tt/clock_id/ has to be <tt/CLOCK_REALTIME/. 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. +<tag/Notes/<itemize> +<item>The function is only available as fastcall function, so it may only +be used in presence of a prototype. +<item>Many platforms supported by cc65 do not have a realtime clock, so the +retrieved value may not be valid. See also the platform-specific information. +</itemize> +<tag/Availability/POSIX 1003.1 +<tag/See also/ +<ref id="clock_getres" name="clock_getres">, +<ref id="clock_settime" name="clock_settime"> +<ref id="time" name="time"> +<tag/Example/None. +</descrip> +</quote> + + +<sect1>clock_settime<label id="clock_settime"><p> + +<quote> +<descrip> +<tag/Function/Get the time from the realtime clock. +<tag/Header/<tt/<ref id="time.h" name="time.h">/ +<tag/Declaration/<tt/int __fastcall__ clock_settime (clockid_t clock_id, const struct timespec *tp);/ +<tag/Description/The <tt/clock_settime/ function sets the time since the 1970-01-01 00:00:00 +measured in nanoseconds. <tt/clock_id/ has to be <tt/CLOCK_REALTIME/. 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. +<tag/Notes/<itemize> +<item>The function is only available as fastcall function, so it may only +be used in presence of a prototype. +<item>Many platforms supported by cc65 do not have a realtime clock, so +setting the time may not work. See also the platform-specific information. +</itemize> +<tag/Availability/POSIX 1003.1 +<tag/See also/ +<ref id="clock_getres" name="clock_getres">, +<ref id="clock_gettime" name="clock_gettime"> +<tag/Example/None. +</descrip> +</quote> + + <sect1>clrscr<label id="clrscr"><p> <quote> @@ -7381,7 +7466,8 @@ returned value may not be valid. </itemize> <tag/Availability/ISO 9899 <tag/See also/ -<ref id="clock" name="clock"> +<ref id="clock" name="clock">, +<ref id="clock_gettime" name="clock_gettime"> <tag/Example/None. </descrip> </quote> From 2acfa5e78f4fab5c540f3798d7444b816c264e7f Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 9 Nov 2018 17:11:03 -0500 Subject: [PATCH 0914/2161] Made div-test.c use doesclrscrafterexit(). It no longer waits for a key tap if it doesn't need to do that. Also, normalized the source code formatting. --- testcode/lib/div-test.c | 57 +++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/testcode/lib/div-test.c b/testcode/lib/div-test.c index 2d5c2541e..401f13ff8 100644 --- a/testcode/lib/div-test.c +++ b/testcode/lib/div-test.c @@ -2,37 +2,44 @@ ** ** This program tests the division and modulo operators ** and the div() library function. -** -** 2002-10-24, Greg King */ +#include <cc65.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> -#include <stdbool.h> -static bool test(int dividend, int divisor) { - div_t result; +static bool test (int dividend, int divisor) +{ + div_t result; - result = div(dividend, divisor); - printf("%+d/%+d= %+d, %+d%%%+d= %+d, div()= %+d, %+d\n", - dividend, divisor, dividend / divisor, - dividend, divisor, dividend % divisor, - result.quot, result.rem); - return result.quot * divisor + result.rem != dividend; - } + result = div (dividend, divisor); + printf ("%+d/%+d= %+d, %+d%%%+d= %+d, div()= %+d, %+d\n", + dividend, divisor, dividend / divisor, + dividend, divisor, dividend % divisor, + result.quot, result.rem); -int main(void) { - bool t; + return result.quot * divisor + result.rem != dividend; +} - printf("\nTest of division and modulus operations:\n\n"); - t = test(+40, +3) || - test(+40, -3) || - test(-40, +3) || - test(-40, -3); - if (t) - printf("\nThe div() function made a wrong result!\n"); +int main (void) +{ + bool t; - printf("\nTap a key, to exit. "); - getchar(); - return (int)t; - } + printf ("\nTest of division and modulus operations:\n\n"); + + t = test (+40, +3) || + test (+40, -3) || + test (-40, +3) || + test (-40, -3); + if (t) { + printf ("\nThe div() function made a wrong result!\n"); + } + + if (doesclrscrafterexit ()) { + printf ("\nTap the Return key to quit. "); + getchar (); + } + + return (int)t; +} From 923fa8fc932638f2d8242433f86405e92cc426cd Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Fri, 9 Nov 2018 15:56:16 +0100 Subject: [PATCH 0915/2161] Saved 2 bytes and fixed error in case of negative result. --- libsrc/common/divt.s | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libsrc/common/divt.s b/libsrc/common/divt.s index f1291c86f..914eb569d 100644 --- a/libsrc/common/divt.s +++ b/libsrc/common/divt.s @@ -18,12 +18,15 @@ .importzp sreg, ptr1, tmp1 _div: jsr tosdivax ; Division-operator does most of the work - lda sreg ; Unsigned remainder is in sreg - ldx sreg+1 - ldy ptr1 ; transfer quotient to sreg - sty sreg - ldy ptr1+1 - sty sreg+1 + + ldy sreg ; low byte remainder from sreg + sta sreg ; store low byte quotient to sreg + + lda sreg+1 ; high byte remainder from sreg + stx sreg+1 ; store high byte quotient to sreg + + tax ; high byte remainder to x + tya ; low byte remainder to a ; Adjust the sign of the remainder. ; It must be the same as the sign of the dividend. @@ -33,4 +36,3 @@ _div: jsr tosdivax ; Division-operator does most of the work jmp negax ; Result is negative, adjust the sign Pos: rts - From be2a425eb16508df07ac4dfefb08dd3a1c1a0dcb Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 10 Nov 2018 00:10:37 +0100 Subject: [PATCH 0916/2161] Some variables from TELEMON 2.4 added --- asminc/telestrat.inc | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 0296f5cb8..8c6b4243b 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -47,6 +47,12 @@ TR6 := $12 TR7 := $13 DEFAFF := $14 + +IRQSVA := $21 ; Used to save A when a BRK call occurs +IRQSVX := $22 ; Used to save X when a BRK call occurs +IRQSVY := $23 ; Used to save Y when a BRK call occurs +IRQSVP := $24 ; Used to save P when a BRK call occurs + ADSCR := $26 PTR_READ_DEST := $2C ; Used for XFREAD and XWRITE only in TELEMON 3.x @@ -190,14 +196,19 @@ XMINMA = $1F XVARS = $24 ; Only in TELEMON 3.x, in TELEMON 2.4, it's XNOMFI ($24) XCRLF = $25 ; Jump a line and return to the beginning of the line XFREAD = $27 ; Only in TELEMON 3.x (bank 7 of Orix) -XHEXA = $2A ; Convert a number into hex XBINDX = $28 ; Convert a number into hex and displays on channel 0 +XDECIM = $29 +XHEXA = $2A ; Convert a number into hex +XSCELG = $2F ; Search a line in editor mode XOPEN = $30 ; Only in TELEMON 3.x (bank 7 of Orix) +XECRPR = $33 ; Displays prompt XCOSCR = $34 ; Switch off cursor XCSSCR = $35 ; Switch on cursor XSCRSE = $36 +XSCRNE = $39 ; Load charset from rom to ram XCLOSE = $3A ; Only in TELEMON 3.x close file (bank 7 of Orix) XFWRITE = $3B ; Only in TELEMON 3.x write file (bank 7 of Orix) +XWRCLK = $3E ; Update clock XSONPS = $40 ; Send data to PSG register (14 values) XOUPS = $42 ; Send Oups sound into PSG XPLAY = $43 ; Play a sound @@ -212,7 +223,7 @@ XMALLOC = $5B ; Only in TELEMON 3.x (bank 7 of Orix) XFREE = $62 ; Only in TELEMON 3.x (bank 7 of Orix) XSOUT = $67 ; Send accumulator value (A) to RS232, available in TELEMON 2.4 & 3.x : if RS232 buffer is full, the Oric Telestrat freezes XHRSSE = $8C ; Set hires position cursor -XDRAWA = $8D ; Draw a line +XDRAWA = $8D ; Draw a line absolute XDRAWR = $8E ; Draw a line (relative) XCIRCL = $8F ; Draw a circle XCURSE = $90 ; Plot a pixel @@ -239,13 +250,37 @@ BUFTRV := $100 ; --------------------------------------------------------------------------- ; Page $200 -SCRX := $220 -SCRY := $224 +BNKST := $200 ; Used to store signature of 8 bank (length : 8 bytes) +FLGTEL := $20D +KOROM := $20E ; Used to compute the size of all rom bank. The result is store here. The value is in KB +KORAM := $20F ; Used to compute the size of all ram bank. The result is store here. The value is in KB +TIMED := $210 +TIMES := $211 +TIMEM := $212 ADSCRL := $218 ADSCRH := $21C +SCRX := $220 +SCRY := $224 +KBDVRL := $273 +FLGKBD := $275 +KBDFCT := $276 +KBDSHT := $278 +KBDCTC := $27E +LPRFX := $288 +LPRFY := $289 HRSPAT := $2AA ; Hires pattern : it's used to draw pattern for a line or a circle +ADIOB := $2BE +FLGRST := $2EE +CSRND := $2EF +VNMI := $2F4 IRQVECTOR := $2FA +VAPLIC := $2FD +; --------------------------------------------------------------------------- +; Page $400 +EXBNK := $40C +VEXBNK := $414 +BNKCIB := $417 ; --------------------------------------------------------------------------- ; Page $500 From be6d155b698a9d1cb80fa2d1c09e7444b664fde0 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 10 Nov 2018 00:47:09 +0100 Subject: [PATCH 0917/2161] Stratsed vectors added --- asminc/telestrat.inc | 73 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 8c6b4243b..e9aa3a243 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -60,6 +60,10 @@ PTR_READ_DEST := $2C ; Used for XFREAD and XWRITE only in TELEMON 3. HRSX := $46 HRSY := $47 +XLPRBI := $48 ; Printer flag (b7) + +HRSX40 := $49 +HRSX6 := $4A HRS1 := $4D HRS2 := $4F HRS3 := $51 @@ -251,6 +255,7 @@ BUFTRV := $100 ; --------------------------------------------------------------------------- ; Page $200 BNKST := $200 ; Used to store signature of 8 bank (length : 8 bytes) +TABDRV := $208 FLGTEL := $20D KOROM := $20E ; Used to compute the size of all rom bank. The result is store here. The value is in KB KORAM := $20F ; Used to compute the size of all ram bank. The result is store here. The value is in KB @@ -285,8 +290,18 @@ BNKCIB := $417 ; --------------------------------------------------------------------------- ; Page $500 +DRIVE := $500 +ERRNB := $512 +SAVES := $513 +VSALO0 := $528 +VSALO1 := $529 +FTYPE := $52C ; File type +DESALO := $52D +FISALO := $52F +EXSALO := $531 +EXTDEF := $55D ; Default extension. At the start of telemon, it's set to ".COM" BUFNOM := $517 -BUFEDT := $590 +BUFEDT := $590 ; Buffer edition MAX_BUFEDT_LENGTH=110 @@ -295,6 +310,62 @@ MAX_BUFEDT_LENGTH=110 CH376_DATA := $340 CH376_COMMAND := $341 +; --------------------------------------------------------------------------- +; Stratsed vectors +; Stratsed is the main OS for Telestrat +XMERGE := $FF0E +XFST := $FF11 +XSPUT := $FF14 +XSTAKE := $FF17 +XTAKE := $FF20 +XOPEN := $FF1A +XCLOSE := $FF1D +XPUT := $FF23 +XREWIN := $FF29 +XJUMP := $FF2C +XLGBUF := $FF2F +XERVEC := $FF32 +XESAVE := $FF35 +XCOPY := $FF38 +XDNAME := $FF3B +XSTATU := $FF3E +XUPDAT := $FF41 +XFORMA := $FF44 +XDELBK := $FF4A +XDELN := $FF4D +XPROT := $FF50 +XUNPRO := $FF53 +XDIRN := $FF56 +XBKP := $FF59 +XINITI := $FF5C +XERREU := $FF5F +XLOAD := $FF62 +XDEFSA := $FF65 +XDEFLO := $FF68 +XSAVE := $FF6B +XNOMDE := $FF6E +XCREAY := $FF71 +XDETSE := $FF74 +XLIBSE := $FF77 +XTRVCA := $FF7A +XTRVNM := $FF7D +XTRVNX := $FF80 +XBUCA := $FF86 +XVBUF1 := $FF89 +XSVSEC := $FF8C +XSAY := $FF8F +XSBUF1 := $FF92 +XSBUF2 := $FF95 +XSBUF3 := $FF98 +XSCAT := $FF9B +XPRSEC := $FFA1 +XPBUF1 := $FFA4 +XPMAP := $FFA7 +XRWTS := $FFAA + + + + ; --------------------------------------------------------------------------- ; MACRO From f558d299c4fb9af98df283fa28788dfaa9cf14dd Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 10 Nov 2018 00:54:58 +0100 Subject: [PATCH 0918/2161] Fix duplicated variables --- asminc/telestrat.inc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index e9aa3a243..df607e375 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -293,6 +293,7 @@ BNKCIB := $417 DRIVE := $500 ERRNB := $512 SAVES := $513 +BUFNOM := $517 VSALO0 := $528 VSALO1 := $529 FTYPE := $52C ; File type @@ -300,7 +301,6 @@ DESALO := $52D FISALO := $52F EXSALO := $531 EXTDEF := $55D ; Default extension. At the start of telemon, it's set to ".COM" -BUFNOM := $517 BUFEDT := $590 ; Buffer edition MAX_BUFEDT_LENGTH=110 @@ -318,8 +318,8 @@ XFST := $FF11 XSPUT := $FF14 XSTAKE := $FF17 XTAKE := $FF20 -XOPEN := $FF1A -XCLOSE := $FF1D +XOPENS := $FF1A ; XOPEN from Stratsed +XCLOSES := $FF1D ; XCLOSE from Stratsed XPUT := $FF23 XREWIN := $FF29 XJUMP := $FF2C @@ -363,9 +363,6 @@ XPBUF1 := $FFA4 XPMAP := $FFA7 XRWTS := $FFAA - - - ; --------------------------------------------------------------------------- ; MACRO From a6b0b9d8507b55c73995ba1c063e2566cce1e8f0 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 10 Nov 2018 00:10:37 +0100 Subject: [PATCH 0919/2161] Some variables from TELEMON 2.4 added --- asminc/telestrat.inc | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 0296f5cb8..8c6b4243b 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -47,6 +47,12 @@ TR6 := $12 TR7 := $13 DEFAFF := $14 + +IRQSVA := $21 ; Used to save A when a BRK call occurs +IRQSVX := $22 ; Used to save X when a BRK call occurs +IRQSVY := $23 ; Used to save Y when a BRK call occurs +IRQSVP := $24 ; Used to save P when a BRK call occurs + ADSCR := $26 PTR_READ_DEST := $2C ; Used for XFREAD and XWRITE only in TELEMON 3.x @@ -190,14 +196,19 @@ XMINMA = $1F XVARS = $24 ; Only in TELEMON 3.x, in TELEMON 2.4, it's XNOMFI ($24) XCRLF = $25 ; Jump a line and return to the beginning of the line XFREAD = $27 ; Only in TELEMON 3.x (bank 7 of Orix) -XHEXA = $2A ; Convert a number into hex XBINDX = $28 ; Convert a number into hex and displays on channel 0 +XDECIM = $29 +XHEXA = $2A ; Convert a number into hex +XSCELG = $2F ; Search a line in editor mode XOPEN = $30 ; Only in TELEMON 3.x (bank 7 of Orix) +XECRPR = $33 ; Displays prompt XCOSCR = $34 ; Switch off cursor XCSSCR = $35 ; Switch on cursor XSCRSE = $36 +XSCRNE = $39 ; Load charset from rom to ram XCLOSE = $3A ; Only in TELEMON 3.x close file (bank 7 of Orix) XFWRITE = $3B ; Only in TELEMON 3.x write file (bank 7 of Orix) +XWRCLK = $3E ; Update clock XSONPS = $40 ; Send data to PSG register (14 values) XOUPS = $42 ; Send Oups sound into PSG XPLAY = $43 ; Play a sound @@ -212,7 +223,7 @@ XMALLOC = $5B ; Only in TELEMON 3.x (bank 7 of Orix) XFREE = $62 ; Only in TELEMON 3.x (bank 7 of Orix) XSOUT = $67 ; Send accumulator value (A) to RS232, available in TELEMON 2.4 & 3.x : if RS232 buffer is full, the Oric Telestrat freezes XHRSSE = $8C ; Set hires position cursor -XDRAWA = $8D ; Draw a line +XDRAWA = $8D ; Draw a line absolute XDRAWR = $8E ; Draw a line (relative) XCIRCL = $8F ; Draw a circle XCURSE = $90 ; Plot a pixel @@ -239,13 +250,37 @@ BUFTRV := $100 ; --------------------------------------------------------------------------- ; Page $200 -SCRX := $220 -SCRY := $224 +BNKST := $200 ; Used to store signature of 8 bank (length : 8 bytes) +FLGTEL := $20D +KOROM := $20E ; Used to compute the size of all rom bank. The result is store here. The value is in KB +KORAM := $20F ; Used to compute the size of all ram bank. The result is store here. The value is in KB +TIMED := $210 +TIMES := $211 +TIMEM := $212 ADSCRL := $218 ADSCRH := $21C +SCRX := $220 +SCRY := $224 +KBDVRL := $273 +FLGKBD := $275 +KBDFCT := $276 +KBDSHT := $278 +KBDCTC := $27E +LPRFX := $288 +LPRFY := $289 HRSPAT := $2AA ; Hires pattern : it's used to draw pattern for a line or a circle +ADIOB := $2BE +FLGRST := $2EE +CSRND := $2EF +VNMI := $2F4 IRQVECTOR := $2FA +VAPLIC := $2FD +; --------------------------------------------------------------------------- +; Page $400 +EXBNK := $40C +VEXBNK := $414 +BNKCIB := $417 ; --------------------------------------------------------------------------- ; Page $500 From b80e11febc784414c88b660a14a8da8c09c6a06d Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 10 Nov 2018 00:47:09 +0100 Subject: [PATCH 0920/2161] Stratsed vectors added --- asminc/telestrat.inc | 73 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 8c6b4243b..e9aa3a243 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -60,6 +60,10 @@ PTR_READ_DEST := $2C ; Used for XFREAD and XWRITE only in TELEMON 3. HRSX := $46 HRSY := $47 +XLPRBI := $48 ; Printer flag (b7) + +HRSX40 := $49 +HRSX6 := $4A HRS1 := $4D HRS2 := $4F HRS3 := $51 @@ -251,6 +255,7 @@ BUFTRV := $100 ; --------------------------------------------------------------------------- ; Page $200 BNKST := $200 ; Used to store signature of 8 bank (length : 8 bytes) +TABDRV := $208 FLGTEL := $20D KOROM := $20E ; Used to compute the size of all rom bank. The result is store here. The value is in KB KORAM := $20F ; Used to compute the size of all ram bank. The result is store here. The value is in KB @@ -285,8 +290,18 @@ BNKCIB := $417 ; --------------------------------------------------------------------------- ; Page $500 +DRIVE := $500 +ERRNB := $512 +SAVES := $513 +VSALO0 := $528 +VSALO1 := $529 +FTYPE := $52C ; File type +DESALO := $52D +FISALO := $52F +EXSALO := $531 +EXTDEF := $55D ; Default extension. At the start of telemon, it's set to ".COM" BUFNOM := $517 -BUFEDT := $590 +BUFEDT := $590 ; Buffer edition MAX_BUFEDT_LENGTH=110 @@ -295,6 +310,62 @@ MAX_BUFEDT_LENGTH=110 CH376_DATA := $340 CH376_COMMAND := $341 +; --------------------------------------------------------------------------- +; Stratsed vectors +; Stratsed is the main OS for Telestrat +XMERGE := $FF0E +XFST := $FF11 +XSPUT := $FF14 +XSTAKE := $FF17 +XTAKE := $FF20 +XOPEN := $FF1A +XCLOSE := $FF1D +XPUT := $FF23 +XREWIN := $FF29 +XJUMP := $FF2C +XLGBUF := $FF2F +XERVEC := $FF32 +XESAVE := $FF35 +XCOPY := $FF38 +XDNAME := $FF3B +XSTATU := $FF3E +XUPDAT := $FF41 +XFORMA := $FF44 +XDELBK := $FF4A +XDELN := $FF4D +XPROT := $FF50 +XUNPRO := $FF53 +XDIRN := $FF56 +XBKP := $FF59 +XINITI := $FF5C +XERREU := $FF5F +XLOAD := $FF62 +XDEFSA := $FF65 +XDEFLO := $FF68 +XSAVE := $FF6B +XNOMDE := $FF6E +XCREAY := $FF71 +XDETSE := $FF74 +XLIBSE := $FF77 +XTRVCA := $FF7A +XTRVNM := $FF7D +XTRVNX := $FF80 +XBUCA := $FF86 +XVBUF1 := $FF89 +XSVSEC := $FF8C +XSAY := $FF8F +XSBUF1 := $FF92 +XSBUF2 := $FF95 +XSBUF3 := $FF98 +XSCAT := $FF9B +XPRSEC := $FFA1 +XPBUF1 := $FFA4 +XPMAP := $FFA7 +XRWTS := $FFAA + + + + ; --------------------------------------------------------------------------- ; MACRO From 2fb4b568e40b5796835e37351fbfe8b5f5d0ceea Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 10 Nov 2018 00:54:58 +0100 Subject: [PATCH 0921/2161] Fix duplicated variables --- asminc/telestrat.inc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index e9aa3a243..df607e375 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -293,6 +293,7 @@ BNKCIB := $417 DRIVE := $500 ERRNB := $512 SAVES := $513 +BUFNOM := $517 VSALO0 := $528 VSALO1 := $529 FTYPE := $52C ; File type @@ -300,7 +301,6 @@ DESALO := $52D FISALO := $52F EXSALO := $531 EXTDEF := $55D ; Default extension. At the start of telemon, it's set to ".COM" -BUFNOM := $517 BUFEDT := $590 ; Buffer edition MAX_BUFEDT_LENGTH=110 @@ -318,8 +318,8 @@ XFST := $FF11 XSPUT := $FF14 XSTAKE := $FF17 XTAKE := $FF20 -XOPEN := $FF1A -XCLOSE := $FF1D +XOPENS := $FF1A ; XOPEN from Stratsed +XCLOSES := $FF1D ; XCLOSE from Stratsed XPUT := $FF23 XREWIN := $FF29 XJUMP := $FF2C @@ -363,9 +363,6 @@ XPBUF1 := $FFA4 XPMAP := $FFA7 XRWTS := $FFAA - - - ; --------------------------------------------------------------------------- ; MACRO From b0495cb44aee6eeef99cb02aa37fbeca8a3e27a7 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 10 Nov 2018 14:54:43 +0100 Subject: [PATCH 0922/2161] Update doc (how telestrat works), tgi_outtext doc added --- doc/telestrat.sgml | 97 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 81 insertions(+), 16 deletions(-) diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index fe9efcfdb..97229db00 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -16,9 +16,9 @@ An overview over the Telestrat (Telemon 2.4 & Telemon 3.x : http://orix.oric.org <sect>Overview<p> -This file contains an overview of the Telestrat runtime system as it comes with the -cc65 C compiler. It describes the memory layout, Telestrat-specific header files, -available drivers, and any pitfalls specific to that platform. +This file contains an overview of the Telestrat runtime system as it comes +with the cc65 C compiler. It describes the memory layout, Telestrat-specific +header files, available drivers, and any pitfalls specific to that platform. Please note that Telestrat-specific functions are just mentioned here, they are described in detail in the separate <url url="funcref.html" name="function @@ -26,17 +26,56 @@ reference">. Even functions marked as "platform dependent" may be available on more than one platform. Please see the function reference for more information. +Oric Telestrat is the last Oric computer (Released in 1986, mainly in France). +This computer is an Atmos with extra hardware : RS232, cardridge (banking system), +joysticks (2 ports) or mouse (on joystick port), FDC. + +Video chip, CPU, keyboard management, tape hardware are the same than Atmos. + +Telestrat can start in Atmos mode with Atmos Cardridge (which is only the atmos +Basic 1.1 ROM). + +Telestrat can start in Sedoric (Atmos OS) and Atmos mode with Stratoric Cardridge. +This Cardridge is a Sedoric ROM, Basic 1.1 ROM (Atmos), Basic 1.0 ROM (Oric-1). + +The main Telestrat's configuration is the Telemon/Hyperbasic Cardridge inserted +with Stratsed in floppy drive. + +Anyway, there is no way to load a tape file in Telemon/Hyperbasic mode without +alternative program. + +There is also no software to write a Stratsed dsk file on PC. + +This Telestrat target build an Orix binary file. But, in the future, it will be possible +to build a Stratsed disk. Orix uses the same systems calls than Telemon mode. + +That is why if you need to do software for telestrat target, you have the choice to : +<itemize> +<item>use cc65 Atmos target and start Telestrat in Atmos mode : a tape file is required +<item>use cc65 Atmos target and start Telestrat in Stratoric mode : a dsk file or tape file is required +<item>use cc65 Telestrat target and start Telestrat in Orix mode (see <url +name="here" url="http://orix.oric.org/download/">) +<item>use cc65 Telestrat target, remove Orix header from binary, code a dsk tool for Stratsed, +add Stratsed header on your binary, insert your binary on floppy disk (this solution will be possible is the future) +</itemize> + +Telestrat (from cardridge) can handle 8 banks (from $C000 to $FFFF): Bank 0 is the overlay ram. Others banks can be ROM or RAM. + <sect>Binary format<p> The standard binary output format generated the linker for the Telestrat target is a machine language program with a 20 bytes header described <url -name="here" url="http://orix.oric.org/doku.php?id=orix:header"> +name="here" url="http://orix.oric.org/orix-header/"> This header is used for Telemon 3.0. -Anyway, for Telemon 2.4, there is no file management, there is no TAPE routine in Telemon, there is no way to load a binary easily. +Anyway, for Telemon 2.4, there is no file management, there is no TAPE routine +in Telemon, there is no way to load a binary easily. -Stratsed (the Telestrat operating system) handles files management. Stratsed is loaded to memory from floppy disk. +Stratsed (the Telestrat operating system) handles files management. Stratsed +is loaded to memory from floppy disk. Stratsed vector are declared in asminc/telestrat.inc. +But, reverse engineering is required to find how theses vectors works. Please, note that +Stratsed is located in overlay memory (bank 0) There is no tool to insert a binary in a Stratsed floppy disk. @@ -44,7 +83,9 @@ The only way to load a binary (for Telemon 2.4) is to: <itemize> <item>remove the 20 bytes header <item>download <url name="osdk" url="http://osdk.defence-force.org/index?page=download"> -<item>use Floppybuilder in OSDK to insert the binary with the tool (please read FloppyBuilder manual to insert your binary, and to start microdisc boot sector when Telestrat starts) +<item>use Floppybuilder in OSDK to insert the binary with the tool (please read +FloppyBuilder manual to insert your binary, and to start microdisc boot sector +when Telestrat starts) </itemize> Please note also, that the binary converted into TAP file, will not produce @@ -58,7 +99,7 @@ If you know the Stratsed disk format, please contact the author of this doc. In the standard setup, cc65-generated programs use the memory from $0801 to $9800; so, nearly 37K of memory (including the stack) is -available. ROM calls are possible without further precautions. +available. ROM calls are possible with BRK feature. Special locations: @@ -109,6 +150,22 @@ structures; accessing the struct fields will access the chip registers. </descrip><p> +<descrip> + + <tag><tt/VIA2/</tag> + Access to the VIA2 (Versatile Interface Adapter) chip is available via the + <tt/VIA2/ variable. The structure behind this variable is explained in <tt/_6522.h/. + +</descrip><p> + +<descrip> + + <tag><tt/6551/</tag> + Access to the 6551 ACIA chip is available via the + <tt/6551/ variable. The structure behind this variable is explained in <tt/_6551.h/. + +</descrip><p> + <sect>Loadable drivers<p> @@ -117,25 +174,31 @@ structures; accessing the struct fields will access the chip registers. TGI drivers is available on Oric Telestrat with some functions : <itemize> -<item>tgi_done -<item>tgi_install -<item>tgi_init <item>tgi_clear +<item>tgi_done +<item>tgi_init +<item>tgi_install <item>tgi_line +<item>tgi_outtext <item>tgi_setpixel </itemize> <sect1>Extended memory drivers<p> -No extended memory drivers are currently available for the Telestrat. - +No extended memory drivers are currently available for the Telestrat. +This feature could be done because telestrat can manage RAM inserted in his +port cardridge. <sect1>Joystick drivers<p> <descrip> -telemon 2.4 & 3.0 manages joysticks but it had been handled yet. +Telemon 2.4 & 3.0 manages joysticks but it had been handled yet. This means that +joysticks driver could be written easily. + +Telemon 2.4 returns in keyboard buffer the direction of the joysticks. This means that +if you get input from keyboard by conio cgetc function, you will get direction from joysticks. </descrip> @@ -144,7 +207,8 @@ telemon 2.4 & 3.0 manages joysticks but it had been handled yet. <descrip> -Telestrat manages also mouse, but it had been no handled yet in this version. +Telestrat manages also mouse, but it had been no handled yet in this version. +Telestrat mouse is really difficult to find. </descrip> @@ -152,7 +216,8 @@ Telestrat manages also mouse, but it had been no handled yet in this version. <descrip> -Telestrat has a RS232 port, but it's not usable in cc65. +Telestrat has a RS232 port, but it's not usable in cc65. It is possible to use +RS232 port with Telemon calls (see XSOUT primitive for example) </descrip> From 8b4179d104ce4327f1074cae9a9679d56ca65847 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Sat, 10 Nov 2018 16:55:55 +0200 Subject: [PATCH 0923/2161] Added VIC control register names --- asminc/vic20.inc | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/asminc/vic20.inc b/asminc/vic20.inc index 6ac7ef35c..5976981fd 100644 --- a/asminc/vic20.inc +++ b/asminc/vic20.inc @@ -59,9 +59,25 @@ NMIVec := $0318 ; I/O: 6560 VIC VIC := $9000 -VIC_LINES := $9003 ; Screen lines, bit 7 is bit 0 from VIC_HLINE -VIC_HLINE := $9004 ; Rasterline, bits 1-8 -VIC_COLOR := $900F ; Border and background color +VIC_CR0 := VIC+$0 +VIC_CR1 := VIC+$1 +VIC_CR2 := VIC+$2 +VIC_CR3 := VIC+$3 +VIC_LINES := VIC+$3 ; Screen lines, bit 7 is bit 0 from VIC_HLINE +VIC_CR4 := VIC+$4 +VIC_HLINE := VIC+$4 ; Rasterline, bits 1-8 +VIC_CR5 := VIC+$5 +VIC_CR6 := VIC+$6 +VIC_CR7 := VIC+$7 +VIC_CR8 := VIC+$8 +VIC_CR9 := VIC+$9 +VIC_CRA := VIC+$A +VIC_CRB := VIC+$B +VIC_CRC := VIC+$C +VIC_CRD := VIC+$D +VIC_CRE := VIC+$E +VIC_CRF := VIC+$F +VIC_COLOR := VIC+$F ; Border and background color ; --------------------------------------------------------------------------- ; I/O: 6522 VIA1 From f86ebbd2587558b63062b26a4d9042e3471a11e2 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Wed, 7 Nov 2018 23:05:05 +0100 Subject: [PATCH 0924/2161] Support for self explanatory KBCODE values --- asminc/atari_pokey.inc | 98 ++++++++++++++++++++++++++++++++++++++++ doc/atari.sgml | 95 ++++++++++++++++++++++++--------------- include/_pokey.h | 100 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 257 insertions(+), 36 deletions(-) diff --git a/asminc/atari_pokey.inc b/asminc/atari_pokey.inc index 99d192fbd..07e9c00ef 100644 --- a/asminc/atari_pokey.inc +++ b/asminc/atari_pokey.inc @@ -42,3 +42,101 @@ SEROUT = POKEY + $0D ;serial port output IRQEN = POKEY + $0E ;IRQ interrupt enable SKCTL = POKEY + $0F ;serial port and keyboard control + +; KBCODE Values + +KEY_NONE = $FF + +KEY_0 = $32 +KEY_1 = $1F +KEY_2 = $1E +KEY_3 = $1A +KEY_4 = $18 +KEY_5 = $1D +KEY_6 = $1B +KEY_7 = $33 +KEY_8 = $35 +KEY_9 = $30 + +KEY_A = $3F +KEY_B = $15 +KEY_C = $12 +KEY_D = $3A +KEY_E = $2A +KEY_F = $38 +KEY_G = $3D +KEY_H = $39 +KEY_I = $0D +KEY_J = $01 +KEY_K = $05 +KEY_L = $00 +KEY_M = $25 +KEY_N = $23 +KEY_O = $08 +KEY_P = $0A +KEY_Q = $2F +KEY_R = $28 +KEY_S = $3E +KEY_T = $2D +KEY_U = $0B +KEY_V = $10 +KEY_W = $2E +KEY_X = $16 +KEY_Y = $2B +KEY_Z = $17 + +KEY_COMMA = $20 +KEY_PERIOD = $22 +KEY_SLASH = $26 +KEY_SEMICOLON = $02 +KEY_PLUS = $06 +KEY_ASTERISK = $07 +KEY_DASH = $0E +KEY_EQUALS = $0F +KEY_LESSTHAN = $36 +KEY_GREATERTHAN = $37 + +KEY_ESC = $1C +KEY_TAB = $2C +KEY_SPACE = $21 +KEY_RETURN = $0C +KEY_DELETE = $34 +KEY_CAPS = $3C +KEY_INVERSE = $27 +KEY_HELP = $11 + +KEY_F1 = $03 +KEY_F2 = $04 +KEY_F3 = $13 +KEY_F4 = $14 + +KEY_SHIFT = $40 +KEY_CTRL = $80 + +; Composed keys + +KEY_EXCLAMATIONMARK = KEY_1 | KEY_SHIFT +KEY_QUOTE = KEY_2 | KEY_SHIFT +KEY_HASH = KEY_3 | KEY_SHIFT +KEY_DOLLAR = KEY_4 | KEY_SHIFT +KEY_PERCENT = KEY_5 | KEY_SHIFT +KEY_AMPERSAND = KEY_6 | KEY_SHIFT +KEY_APOSTROPHE = KEY_7 | KEY_SHIFT +KEY_AT = KEY_8 | KEY_SHIFT +KEY_OPENINGPARAN = KEY_9 | KEY_SHIFT +KEY_CLOSINGPARAN = KEY_0 | KEY_SHIFT +KEY_UNDERLINE = KEY_DASH | KEY_SHIFT +KEY_BAR = KEY_EQUALS | KEY_SHIFT +KEY_COLON = KEY_SEMICOLON | KEY_SHIFT +KEY_BACKSLASH = KEY_PLUS | KEY_SHIFT +KEY_CIRCUMFLEX = KEY_ASTERISK | KEY_SHIFT +KEY_OPENINGBRACKET = KEY_COMMA | KEY_SHIFT +KEY_CLOSINGBRACKET = KEY_PERIOD | KEY_SHIFT +KEY_QUESTIONMARK = KEY_SLASH | KEY_SHIFT +KEY_CLEAR = KEY_LESSTHAN | KEY_SHIFT +KEY_INSERT = KEY_GREATERTHAN | KEY_SHIFT + +KEY_UP = KEY_UNDERLINE | KEY_CTRL +KEY_DOWN = KEY_EQUALS | KEY_CTRL +KEY_LEFT = KEY_PLUS | KEY_CTRL +KEY_RIGHT = KEY_ASTERISK | KEY_CTRL diff --git a/doc/atari.sgml b/doc/atari.sgml index cb41e1105..db76c6736 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -329,20 +329,20 @@ unsigned char ScreenMemory[100]; void DisplayList = { - DL_BLK8, - DL_BLK8, - DL_BLK8, - DL_LMS(DL_CHR20x8x2), - ScreenMemory, - DL_CHR20x8x2, - DL_CHR20x8x2, - DL_CHR20x8x2, - DL_BLK4, - DL_CHR20x8x2, - DL_JVB + DL_BLK8, + DL_BLK8, + DL_BLK8, + DL_LMS(DL_CHR20x8x2), + ScreenMemory, + DL_CHR20x8x2, + DL_CHR20x8x2, + DL_CHR20x8x2, + DL_BLK4, + DL_CHR20x8x2, + DL_JVB }; ... -POKEW(560,(unsigned int)&DisplayList); // SDLSTL +POKEW(560,(unsigned int)&DisplayList); // SDLSTL ... </verb> @@ -411,6 +411,29 @@ char* pcAtasciiMappingString = "Hello Atari!"; does not. +<sect1>Keyboard codes<p> + +For direct keyboard scanning in conjunction with e.g. the OS location "CH" (764/$2FC), +all keyboard codes are available as defined values on C and assembler side. + +Example: +<verb> +... + while (!kbhit()); + switch (PEEK(764)) + { + case KEY_RETURN: + ... + case KEY_SPACE: + ... + case KEY_1: + ... + } +... +</verb> + +You can find the C defines in the file "<tt/_pokey.h/" or "<tt/atari_pokey.inc/" for the assembler variant. + <sect>Loadable drivers<p> @@ -932,16 +955,16 @@ chunk #2 (RAM memory area). The contents of the new NEXEHDR and CHKHDR segments come from this file (split.s): <tscreen><verb> - .import __CODE_LOAD__, __BSS_LOAD__, __CODE_SIZE__ - .import __DATA_LOAD__, __RODATA_LOAD__, __STARTUP_LOAD__ + .import __CODE_LOAD__, __BSS_LOAD__, __CODE_SIZE__ + .import __DATA_LOAD__, __RODATA_LOAD__, __STARTUP_LOAD__ - .segment "NEXEHDR" - .word __STARTUP_LOAD__ - .word __CODE_LOAD__ + __CODE_SIZE__ - 1 + .segment "NEXEHDR" + .word __STARTUP_LOAD__ + .word __CODE_LOAD__ + __CODE_SIZE__ - 1 - .segment "CHKHDR" - .word __RODATA_LOAD__ - .word __BSS_LOAD__ - 1 + .segment "CHKHDR" + .word __RODATA_LOAD__ + .word __BSS_LOAD__ - 1 </verb></tscreen> <p> Compile with @@ -1008,16 +1031,16 @@ FEATURES { New contents for NEXEHDR and CHKHDR are needed (split2.s): <tscreen><verb> - .import __STARTUP_LOAD__, __BSS_LOAD__, __DATA_SIZE__ - .import __DATA_LOAD__, __RODATA_LOAD__ + .import __STARTUP_LOAD__, __BSS_LOAD__, __DATA_SIZE__ + .import __DATA_LOAD__, __RODATA_LOAD__ - .segment "NEXEHDR" - .word __RODATA_LOAD__ - .word __DATA_LOAD__ + __DATA_SIZE__ - 1 + .segment "NEXEHDR" + .word __RODATA_LOAD__ + .word __DATA_LOAD__ + __DATA_SIZE__ - 1 - .segment "CHKHDR" - .word __STARTUP_LOAD__ - .word __BSS_LOAD__ - 1 + .segment "CHKHDR" + .word __STARTUP_LOAD__ + .word __BSS_LOAD__ - 1 </verb></tscreen> Compile with @@ -1096,14 +1119,14 @@ 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. +<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/include/_pokey.h b/include/_pokey.h index df10eac3f..2c2f7167e 100644 --- a/include/_pokey.h +++ b/include/_pokey.h @@ -7,6 +7,7 @@ /* */ /* */ /* (C) 2000 Freddy Offenga <taf_offenga@yahoo.com> */ +/* 06-Nov-2018: Christian Krueger: Added defines for keyboard codes */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -73,6 +74,105 @@ struct __pokey_read { unsigned char skstat; /* serial port status */ }; + +/* Keyboard values returned by kbcode */ + +#define KEY_NONE (unsigned char) 0xFF + +#define KEY_0 (unsigned char) 0x32 +#define KEY_1 (unsigned char) 0x1F +#define KEY_2 (unsigned char) 0x1E +#define KEY_3 (unsigned char) 0x1A +#define KEY_4 (unsigned char) 0x18 +#define KEY_5 (unsigned char) 0x1D +#define KEY_6 (unsigned char) 0x1B +#define KEY_7 (unsigned char) 0x33 +#define KEY_8 (unsigned char) 0x35 +#define KEY_9 (unsigned char) 0x30 + +#define KEY_A (unsigned char) 0x3F +#define KEY_B (unsigned char) 0x15 +#define KEY_C (unsigned char) 0x12 +#define KEY_D (unsigned char) 0x3A +#define KEY_E (unsigned char) 0x2A +#define KEY_F (unsigned char) 0x38 +#define KEY_G (unsigned char) 0x3D +#define KEY_H (unsigned char) 0x39 +#define KEY_I (unsigned char) 0x0D +#define KEY_J (unsigned char) 0x01 +#define KEY_K (unsigned char) 0x05 +#define KEY_L (unsigned char) 0x00 +#define KEY_M (unsigned char) 0x25 +#define KEY_N (unsigned char) 0x23 +#define KEY_O (unsigned char) 0x08 +#define KEY_P (unsigned char) 0x0A +#define KEY_Q (unsigned char) 0x2F +#define KEY_R (unsigned char) 0x28 +#define KEY_S (unsigned char) 0x3E +#define KEY_T (unsigned char) 0x2D +#define KEY_U (unsigned char) 0x0B +#define KEY_V (unsigned char) 0x10 +#define KEY_W (unsigned char) 0x2E +#define KEY_X (unsigned char) 0x16 +#define KEY_Y (unsigned char) 0x2B +#define KEY_Z (unsigned char) 0x17 + +#define KEY_COMMA (unsigned char) 0x20 +#define KEY_PERIOD (unsigned char) 0x22 +#define KEY_SLASH (unsigned char) 0x26 +#define KEY_SEMICOLON (unsigned char) 0x02 +#define KEY_PLUS (unsigned char) 0x06 +#define KEY_ASTERISK (unsigned char) 0x07 +#define KEY_DASH (unsigned char) 0x0E +#define KEY_EQUALS (unsigned char) 0x0F +#define KEY_LESSTHAN (unsigned char) 0x36 +#define KEY_GREATERTHAN (unsigned char) 0x37 + +#define KEY_ESC (unsigned char) 0x1C +#define KEY_TAB (unsigned char) 0x2C +#define KEY_SPACE (unsigned char) 0x21 +#define KEY_RETURN (unsigned char) 0x0C +#define KEY_DELETE (unsigned char) 0x34 +#define KEY_CAPS (unsigned char) 0x3C +#define KEY_INVERSE (unsigned char) 0x27 +#define KEY_HELP (unsigned char) 0x11 + +#define KEY_F1 (unsigned char) 0x03 +#define KEY_F2 (unsigned char) 0x04 +#define KEY_F3 (unsigned char) 0x13 +#define KEY_F4 (unsigned char) 0x14 + +#define KEY_CTRL (unsigned char) 0x80 +#define KEY_SHIFT (unsigned char) 0x40 + +/* Composed keys */ + +#define KEY_EXCLAMATIONMARK (KEY_1 | KEY_SHIFT) +#define KEY_QUOTE (KEY_2 | KEY_SHIFT) +#define KEY_HASH (KEY_3 | KEY_SHIFT) +#define KEY_DOLLAR (KEY_4 | KEY_SHIFT) +#define KEY_PERCENT (KEY_5 | KEY_SHIFT) +#define KEY_AMPERSAND (KEY_6 | KEY_SHIFT) +#define KEY_APOSTROPHE (KEY_7 | KEY_SHIFT) +#define KEY_AT (KEY_8 | KEY_SHIFT) +#define KEY_OPENINGPARAN (KEY_9 | KEY_SHIFT) +#define KEY_CLOSINGPARAN (KEY_0 | KEY_SHIFT) +#define KEY_UNDERLINE (KEY_DASH | KEY_SHIFT) +#define KEY_BAR (KEY_EQUALS | KEY_SHIFT) +#define KEY_COLON (KEY_SEMICOLON | KEY_SHIFT) +#define KEY_BACKSLASH (KEY_PLUS | KEY_SHIFT) +#define KEY_CIRCUMFLEX (KEY_ASTERISK | KEY_SHIFT) +#define KEY_OPENINGBRACKET (KEY_COMMA | KEY_SHIFT) +#define KEY_CLOSINGBRACKET (KEY_PERIOD | KEY_SHIFT) +#define KEY_QUESTIONMARK (KEY_SLASH | KEY_SHIFT) +#define KEY_CLEAR (KEY_LESSTHAN | KEY_SHIFT) +#define KEY_INSERT (KEY_GREATERTHAN | KEY_SHIFT) + +#define KEY_UP (KEY_UNDERLINE | KEY_CTRL) +#define KEY_DOWN (KEY_EQUALS | KEY_CTRL) +#define KEY_LEFT (KEY_PLUS | KEY_CTRL) +#define KEY_RIGHT (KEY_ASTERISK | KEY_CTRL) + /* End of _pokey.h */ #endif /* #ifndef __POKEY_H */ From 61a9871c21b0c859d5afd5ffd8167297d07ebef5 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Thu, 8 Nov 2018 08:29:56 +0100 Subject: [PATCH 0925/2161] Adaptations due to code review. --- asminc/atari.inc | 98 +++++++++++++++++++++++++++++++++++++++++ asminc/atari_pokey.inc | 99 ------------------------------------------ doc/atari.sgml | 2 +- include/_pokey.h | 99 ------------------------------------------ include/atari.h | 97 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 196 insertions(+), 199 deletions(-) diff --git a/asminc/atari.inc b/asminc/atari.inc index 98c721296..7c46b3252 100644 --- a/asminc/atari.inc +++ b/asminc/atari.inc @@ -831,6 +831,104 @@ PDVS = $D1FF ;##rev2## parallel device select POKEY = $D200 ;POKEY area .include "atari_pokey.inc" +; POKEY KBCODE Values + +KEY_NONE = $FF + +KEY_0 = $32 +KEY_1 = $1F +KEY_2 = $1E +KEY_3 = $1A +KEY_4 = $18 +KEY_5 = $1D +KEY_6 = $1B +KEY_7 = $33 +KEY_8 = $35 +KEY_9 = $30 + +KEY_A = $3F +KEY_B = $15 +KEY_C = $12 +KEY_D = $3A +KEY_E = $2A +KEY_F = $38 +KEY_G = $3D +KEY_H = $39 +KEY_I = $0D +KEY_J = $01 +KEY_K = $05 +KEY_L = $00 +KEY_M = $25 +KEY_N = $23 +KEY_O = $08 +KEY_P = $0A +KEY_Q = $2F +KEY_R = $28 +KEY_S = $3E +KEY_T = $2D +KEY_U = $0B +KEY_V = $10 +KEY_W = $2E +KEY_X = $16 +KEY_Y = $2B +KEY_Z = $17 + +KEY_COMMA = $20 +KEY_PERIOD = $22 +KEY_SLASH = $26 +KEY_SEMICOLON = $02 +KEY_PLUS = $06 +KEY_ASTERISK = $07 +KEY_DASH = $0E +KEY_EQUALS = $0F +KEY_LESSTHAN = $36 +KEY_GREATERTHAN = $37 + +KEY_ESC = $1C +KEY_TAB = $2C +KEY_SPACE = $21 +KEY_RETURN = $0C +KEY_DELETE = $34 +KEY_CAPS = $3C +KEY_INVERSE = $27 +KEY_HELP = $11 + +KEY_F1 = $03 +KEY_F2 = $04 +KEY_F3 = $13 +KEY_F4 = $14 + +KEY_SHIFT = $40 +KEY_CTRL = $80 + +; Composed keys + +KEY_EXCLAMATIONMARK = KEY_1 | KEY_SHIFT +KEY_QUOTE = KEY_2 | KEY_SHIFT +KEY_HASH = KEY_3 | KEY_SHIFT +KEY_DOLLAR = KEY_4 | KEY_SHIFT +KEY_PERCENT = KEY_5 | KEY_SHIFT +KEY_AMPERSAND = KEY_6 | KEY_SHIFT +KEY_APOSTROPHE = KEY_7 | KEY_SHIFT +KEY_AT = KEY_8 | KEY_SHIFT +KEY_OPENINGPARAN = KEY_9 | KEY_SHIFT +KEY_CLOSINGPARAN = KEY_0 | KEY_SHIFT +KEY_UNDERLINE = KEY_DASH | KEY_SHIFT +KEY_BAR = KEY_EQUALS | KEY_SHIFT +KEY_COLON = KEY_SEMICOLON | KEY_SHIFT +KEY_BACKSLASH = KEY_PLUS | KEY_SHIFT +KEY_CIRCUMFLEX = KEY_ASTERISK | KEY_SHIFT +KEY_OPENINGBRACKET = KEY_COMMA | KEY_SHIFT +KEY_CLOSINGBRACKET = KEY_PERIOD | KEY_SHIFT +KEY_QUESTIONMARK = KEY_SLASH | KEY_SHIFT +KEY_CLEAR = KEY_LESSTHAN | KEY_SHIFT +KEY_INSERT = KEY_GREATERTHAN | KEY_SHIFT + +KEY_UP = KEY_UNDERLINE | KEY_CTRL +KEY_DOWN = KEY_EQUALS | KEY_CTRL +KEY_LEFT = KEY_PLUS | KEY_CTRL +KEY_RIGHT = KEY_ASTERISK | KEY_CTRL + ;------------------------------------------------------------------------- ; ANTIC Address Equates ;------------------------------------------------------------------------- diff --git a/asminc/atari_pokey.inc b/asminc/atari_pokey.inc index 07e9c00ef..4174865d5 100644 --- a/asminc/atari_pokey.inc +++ b/asminc/atari_pokey.inc @@ -41,102 +41,3 @@ POTGO = POKEY + $0B ;start potentiometer scan sequence SEROUT = POKEY + $0D ;serial port output IRQEN = POKEY + $0E ;IRQ interrupt enable SKCTL = POKEY + $0F ;serial port and keyboard control - - -; KBCODE Values - -KEY_NONE = $FF - -KEY_0 = $32 -KEY_1 = $1F -KEY_2 = $1E -KEY_3 = $1A -KEY_4 = $18 -KEY_5 = $1D -KEY_6 = $1B -KEY_7 = $33 -KEY_8 = $35 -KEY_9 = $30 - -KEY_A = $3F -KEY_B = $15 -KEY_C = $12 -KEY_D = $3A -KEY_E = $2A -KEY_F = $38 -KEY_G = $3D -KEY_H = $39 -KEY_I = $0D -KEY_J = $01 -KEY_K = $05 -KEY_L = $00 -KEY_M = $25 -KEY_N = $23 -KEY_O = $08 -KEY_P = $0A -KEY_Q = $2F -KEY_R = $28 -KEY_S = $3E -KEY_T = $2D -KEY_U = $0B -KEY_V = $10 -KEY_W = $2E -KEY_X = $16 -KEY_Y = $2B -KEY_Z = $17 - -KEY_COMMA = $20 -KEY_PERIOD = $22 -KEY_SLASH = $26 -KEY_SEMICOLON = $02 -KEY_PLUS = $06 -KEY_ASTERISK = $07 -KEY_DASH = $0E -KEY_EQUALS = $0F -KEY_LESSTHAN = $36 -KEY_GREATERTHAN = $37 - -KEY_ESC = $1C -KEY_TAB = $2C -KEY_SPACE = $21 -KEY_RETURN = $0C -KEY_DELETE = $34 -KEY_CAPS = $3C -KEY_INVERSE = $27 -KEY_HELP = $11 - -KEY_F1 = $03 -KEY_F2 = $04 -KEY_F3 = $13 -KEY_F4 = $14 - -KEY_SHIFT = $40 -KEY_CTRL = $80 - -; Composed keys - -KEY_EXCLAMATIONMARK = KEY_1 | KEY_SHIFT -KEY_QUOTE = KEY_2 | KEY_SHIFT -KEY_HASH = KEY_3 | KEY_SHIFT -KEY_DOLLAR = KEY_4 | KEY_SHIFT -KEY_PERCENT = KEY_5 | KEY_SHIFT -KEY_AMPERSAND = KEY_6 | KEY_SHIFT -KEY_APOSTROPHE = KEY_7 | KEY_SHIFT -KEY_AT = KEY_8 | KEY_SHIFT -KEY_OPENINGPARAN = KEY_9 | KEY_SHIFT -KEY_CLOSINGPARAN = KEY_0 | KEY_SHIFT -KEY_UNDERLINE = KEY_DASH | KEY_SHIFT -KEY_BAR = KEY_EQUALS | KEY_SHIFT -KEY_COLON = KEY_SEMICOLON | KEY_SHIFT -KEY_BACKSLASH = KEY_PLUS | KEY_SHIFT -KEY_CIRCUMFLEX = KEY_ASTERISK | KEY_SHIFT -KEY_OPENINGBRACKET = KEY_COMMA | KEY_SHIFT -KEY_CLOSINGBRACKET = KEY_PERIOD | KEY_SHIFT -KEY_QUESTIONMARK = KEY_SLASH | KEY_SHIFT -KEY_CLEAR = KEY_LESSTHAN | KEY_SHIFT -KEY_INSERT = KEY_GREATERTHAN | KEY_SHIFT - -KEY_UP = KEY_UNDERLINE | KEY_CTRL -KEY_DOWN = KEY_EQUALS | KEY_CTRL -KEY_LEFT = KEY_PLUS | KEY_CTRL -KEY_RIGHT = KEY_ASTERISK | KEY_CTRL diff --git a/doc/atari.sgml b/doc/atari.sgml index db76c6736..a0efab9be 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -432,7 +432,7 @@ Example: ... </verb> -You can find the C defines in the file "<tt/_pokey.h/" or "<tt/atari_pokey.inc/" for the assembler variant. +You can find the C defines in the file "<tt/atari.h/" or "<tt/atari.inc/" for the assembler variant. <sect>Loadable drivers<p> diff --git a/include/_pokey.h b/include/_pokey.h index 2c2f7167e..fed8628b6 100644 --- a/include/_pokey.h +++ b/include/_pokey.h @@ -7,7 +7,6 @@ /* */ /* */ /* (C) 2000 Freddy Offenga <taf_offenga@yahoo.com> */ -/* 06-Nov-2018: Christian Krueger: Added defines for keyboard codes */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -75,104 +74,6 @@ struct __pokey_read { }; -/* Keyboard values returned by kbcode */ - -#define KEY_NONE (unsigned char) 0xFF - -#define KEY_0 (unsigned char) 0x32 -#define KEY_1 (unsigned char) 0x1F -#define KEY_2 (unsigned char) 0x1E -#define KEY_3 (unsigned char) 0x1A -#define KEY_4 (unsigned char) 0x18 -#define KEY_5 (unsigned char) 0x1D -#define KEY_6 (unsigned char) 0x1B -#define KEY_7 (unsigned char) 0x33 -#define KEY_8 (unsigned char) 0x35 -#define KEY_9 (unsigned char) 0x30 - -#define KEY_A (unsigned char) 0x3F -#define KEY_B (unsigned char) 0x15 -#define KEY_C (unsigned char) 0x12 -#define KEY_D (unsigned char) 0x3A -#define KEY_E (unsigned char) 0x2A -#define KEY_F (unsigned char) 0x38 -#define KEY_G (unsigned char) 0x3D -#define KEY_H (unsigned char) 0x39 -#define KEY_I (unsigned char) 0x0D -#define KEY_J (unsigned char) 0x01 -#define KEY_K (unsigned char) 0x05 -#define KEY_L (unsigned char) 0x00 -#define KEY_M (unsigned char) 0x25 -#define KEY_N (unsigned char) 0x23 -#define KEY_O (unsigned char) 0x08 -#define KEY_P (unsigned char) 0x0A -#define KEY_Q (unsigned char) 0x2F -#define KEY_R (unsigned char) 0x28 -#define KEY_S (unsigned char) 0x3E -#define KEY_T (unsigned char) 0x2D -#define KEY_U (unsigned char) 0x0B -#define KEY_V (unsigned char) 0x10 -#define KEY_W (unsigned char) 0x2E -#define KEY_X (unsigned char) 0x16 -#define KEY_Y (unsigned char) 0x2B -#define KEY_Z (unsigned char) 0x17 - -#define KEY_COMMA (unsigned char) 0x20 -#define KEY_PERIOD (unsigned char) 0x22 -#define KEY_SLASH (unsigned char) 0x26 -#define KEY_SEMICOLON (unsigned char) 0x02 -#define KEY_PLUS (unsigned char) 0x06 -#define KEY_ASTERISK (unsigned char) 0x07 -#define KEY_DASH (unsigned char) 0x0E -#define KEY_EQUALS (unsigned char) 0x0F -#define KEY_LESSTHAN (unsigned char) 0x36 -#define KEY_GREATERTHAN (unsigned char) 0x37 - -#define KEY_ESC (unsigned char) 0x1C -#define KEY_TAB (unsigned char) 0x2C -#define KEY_SPACE (unsigned char) 0x21 -#define KEY_RETURN (unsigned char) 0x0C -#define KEY_DELETE (unsigned char) 0x34 -#define KEY_CAPS (unsigned char) 0x3C -#define KEY_INVERSE (unsigned char) 0x27 -#define KEY_HELP (unsigned char) 0x11 - -#define KEY_F1 (unsigned char) 0x03 -#define KEY_F2 (unsigned char) 0x04 -#define KEY_F3 (unsigned char) 0x13 -#define KEY_F4 (unsigned char) 0x14 - -#define KEY_CTRL (unsigned char) 0x80 -#define KEY_SHIFT (unsigned char) 0x40 - -/* Composed keys */ - -#define KEY_EXCLAMATIONMARK (KEY_1 | KEY_SHIFT) -#define KEY_QUOTE (KEY_2 | KEY_SHIFT) -#define KEY_HASH (KEY_3 | KEY_SHIFT) -#define KEY_DOLLAR (KEY_4 | KEY_SHIFT) -#define KEY_PERCENT (KEY_5 | KEY_SHIFT) -#define KEY_AMPERSAND (KEY_6 | KEY_SHIFT) -#define KEY_APOSTROPHE (KEY_7 | KEY_SHIFT) -#define KEY_AT (KEY_8 | KEY_SHIFT) -#define KEY_OPENINGPARAN (KEY_9 | KEY_SHIFT) -#define KEY_CLOSINGPARAN (KEY_0 | KEY_SHIFT) -#define KEY_UNDERLINE (KEY_DASH | KEY_SHIFT) -#define KEY_BAR (KEY_EQUALS | KEY_SHIFT) -#define KEY_COLON (KEY_SEMICOLON | KEY_SHIFT) -#define KEY_BACKSLASH (KEY_PLUS | KEY_SHIFT) -#define KEY_CIRCUMFLEX (KEY_ASTERISK | KEY_SHIFT) -#define KEY_OPENINGBRACKET (KEY_COMMA | KEY_SHIFT) -#define KEY_CLOSINGBRACKET (KEY_PERIOD | KEY_SHIFT) -#define KEY_QUESTIONMARK (KEY_SLASH | KEY_SHIFT) -#define KEY_CLEAR (KEY_LESSTHAN | KEY_SHIFT) -#define KEY_INSERT (KEY_GREATERTHAN | KEY_SHIFT) - -#define KEY_UP (KEY_UNDERLINE | KEY_CTRL) -#define KEY_DOWN (KEY_EQUALS | KEY_CTRL) -#define KEY_LEFT (KEY_PLUS | KEY_CTRL) -#define KEY_RIGHT (KEY_ASTERISK | KEY_CTRL) - /* End of _pokey.h */ #endif /* #ifndef __POKEY_H */ diff --git a/include/atari.h b/include/atari.h index ca6bd424c..ca12a493a 100644 --- a/include/atari.h +++ b/include/atari.h @@ -159,6 +159,103 @@ #define JOY_FIRE_MASK JOY_BTN_1_MASK #define JOY_FIRE(v) ((v) & JOY_FIRE_MASK) +/* Keyboard values returned by kbcode / CH */ +#define KEY_NONE (unsigned char) 0xFF + +#define KEY_0 (unsigned char) 0x32 +#define KEY_1 (unsigned char) 0x1F +#define KEY_2 (unsigned char) 0x1E +#define KEY_3 (unsigned char) 0x1A +#define KEY_4 (unsigned char) 0x18 +#define KEY_5 (unsigned char) 0x1D +#define KEY_6 (unsigned char) 0x1B +#define KEY_7 (unsigned char) 0x33 +#define KEY_8 (unsigned char) 0x35 +#define KEY_9 (unsigned char) 0x30 + +#define KEY_A (unsigned char) 0x3F +#define KEY_B (unsigned char) 0x15 +#define KEY_C (unsigned char) 0x12 +#define KEY_D (unsigned char) 0x3A +#define KEY_E (unsigned char) 0x2A +#define KEY_F (unsigned char) 0x38 +#define KEY_G (unsigned char) 0x3D +#define KEY_H (unsigned char) 0x39 +#define KEY_I (unsigned char) 0x0D +#define KEY_J (unsigned char) 0x01 +#define KEY_K (unsigned char) 0x05 +#define KEY_L (unsigned char) 0x00 +#define KEY_M (unsigned char) 0x25 +#define KEY_N (unsigned char) 0x23 +#define KEY_O (unsigned char) 0x08 +#define KEY_P (unsigned char) 0x0A +#define KEY_Q (unsigned char) 0x2F +#define KEY_R (unsigned char) 0x28 +#define KEY_S (unsigned char) 0x3E +#define KEY_T (unsigned char) 0x2D +#define KEY_U (unsigned char) 0x0B +#define KEY_V (unsigned char) 0x10 +#define KEY_W (unsigned char) 0x2E +#define KEY_X (unsigned char) 0x16 +#define KEY_Y (unsigned char) 0x2B +#define KEY_Z (unsigned char) 0x17 + +#define KEY_COMMA (unsigned char) 0x20 +#define KEY_PERIOD (unsigned char) 0x22 +#define KEY_SLASH (unsigned char) 0x26 +#define KEY_SEMICOLON (unsigned char) 0x02 +#define KEY_PLUS (unsigned char) 0x06 +#define KEY_ASTERISK (unsigned char) 0x07 +#define KEY_DASH (unsigned char) 0x0E +#define KEY_EQUALS (unsigned char) 0x0F +#define KEY_LESSTHAN (unsigned char) 0x36 +#define KEY_GREATERTHAN (unsigned char) 0x37 + +#define KEY_ESC (unsigned char) 0x1C +#define KEY_TAB (unsigned char) 0x2C +#define KEY_SPACE (unsigned char) 0x21 +#define KEY_RETURN (unsigned char) 0x0C +#define KEY_DELETE (unsigned char) 0x34 +#define KEY_CAPS (unsigned char) 0x3C +#define KEY_INVERSE (unsigned char) 0x27 +#define KEY_HELP (unsigned char) 0x11 + +#define KEY_F1 (unsigned char) 0x03 +#define KEY_F2 (unsigned char) 0x04 +#define KEY_F3 (unsigned char) 0x13 +#define KEY_F4 (unsigned char) 0x14 + +#define KEY_CTRL (unsigned char) 0x80 +#define KEY_SHIFT (unsigned char) 0x40 + +/* Composed keys */ + +#define KEY_EXCLAMATIONMARK (KEY_1 | KEY_SHIFT) +#define KEY_QUOTE (KEY_2 | KEY_SHIFT) +#define KEY_HASH (KEY_3 | KEY_SHIFT) +#define KEY_DOLLAR (KEY_4 | KEY_SHIFT) +#define KEY_PERCENT (KEY_5 | KEY_SHIFT) +#define KEY_AMPERSAND (KEY_6 | KEY_SHIFT) +#define KEY_APOSTROPHE (KEY_7 | KEY_SHIFT) +#define KEY_AT (KEY_8 | KEY_SHIFT) +#define KEY_OPENINGPARAN (KEY_9 | KEY_SHIFT) +#define KEY_CLOSINGPARAN (KEY_0 | KEY_SHIFT) +#define KEY_UNDERLINE (KEY_DASH | KEY_SHIFT) +#define KEY_BAR (KEY_EQUALS | KEY_SHIFT) +#define KEY_COLON (KEY_SEMICOLON | KEY_SHIFT) +#define KEY_BACKSLASH (KEY_PLUS | KEY_SHIFT) +#define KEY_CIRCUMFLEX (KEY_ASTERISK | KEY_SHIFT) +#define KEY_OPENINGBRACKET (KEY_COMMA | KEY_SHIFT) +#define KEY_CLOSINGBRACKET (KEY_PERIOD | KEY_SHIFT) +#define KEY_QUESTIONMARK (KEY_SLASH | KEY_SHIFT) +#define KEY_CLEAR (KEY_LESSTHAN | KEY_SHIFT) +#define KEY_INSERT (KEY_GREATERTHAN | KEY_SHIFT) + +#define KEY_UP (KEY_UNDERLINE | KEY_CTRL) +#define KEY_DOWN (KEY_EQUALS | KEY_CTRL) +#define KEY_LEFT (KEY_PLUS | KEY_CTRL) +#define KEY_RIGHT (KEY_ASTERISK | KEY_CTRL) + /* color register functions */ extern void __fastcall__ _setcolor (unsigned char color_reg, unsigned char hue, unsigned char luminace); extern void __fastcall__ _setcolor_low (unsigned char color_reg, unsigned char color_value); From d0053422e9cb3acb3960d652532af01d311e9c8a Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sun, 11 Nov 2018 19:25:06 +0100 Subject: [PATCH 0926/2161] Code review aftermath 2: Put defines into parentheses --- include/_antic.h | 56 +++++++++++----------- include/atari.h | 122 +++++++++++++++++++++++------------------------ 2 files changed, 89 insertions(+), 89 deletions(-) diff --git a/include/_antic.h b/include/_antic.h index 23a72609c..2aac3fccf 100644 --- a/include/_antic.h +++ b/include/_antic.h @@ -57,42 +57,42 @@ struct __antic { /* antic instruction set */ /* absolute instructions (non mode lines) */ -#define DL_JMP (unsigned char) 1 -#define DL_JVB (unsigned char) 65 +#define DL_JMP ((unsigned char) 1) +#define DL_JVB ((unsigned char) 65) -#define DL_BLK1 (unsigned char) 0 -#define DL_BLK2 (unsigned char) 16 -#define DL_BLK3 (unsigned char) 32 -#define DL_BLK4 (unsigned char) 48 -#define DL_BLK5 (unsigned char) 64 -#define DL_BLK6 (unsigned char) 80 -#define DL_BLK7 (unsigned char) 96 -#define DL_BLK8 (unsigned char) 112 +#define DL_BLK1 ((unsigned char) 0) +#define DL_BLK2 ((unsigned char) 16) +#define DL_BLK3 ((unsigned char) 32) +#define DL_BLK4 ((unsigned char) 48) +#define DL_BLK5 ((unsigned char) 64) +#define DL_BLK6 ((unsigned char) 80) +#define DL_BLK7 ((unsigned char) 96) +#define DL_BLK8 ((unsigned char) 112) /* absolute instructions (mode lines) */ -#define DL_CHR40x8x1 (unsigned char) 2 /* monochrome, 40 character & 8 scanlines per mode line (GR. 0) */ -#define DL_CHR40x10x1 (unsigned char) 3 /* monochrome, 40 character & 10 scanlines per mode line */ -#define DL_CHR40x8x4 (unsigned char) 4 /* colour, 40 character & 8 scanlines per mode line (GR. 12) */ -#define DL_CHR40x16x4 (unsigned char) 5 /* colour, 40 character & 16 scanlines per mode line (GR. 13) */ -#define DL_CHR20x8x2 (unsigned char) 6 /* colour (duochrome per character), 20 character & 8 scanlines per mode line (GR. 1) */ -#define DL_CHR20x16x2 (unsigned char) 7 /* colour (duochrome per character), 20 character & 16 scanlines per mode line (GR. 2) */ +#define DL_CHR40x8x1 ((unsigned char) 2) /* monochrome, 40 character & 8 scanlines per mode line (GR. 0) */ +#define DL_CHR40x10x1 ((unsigned char) 3) /* monochrome, 40 character & 10 scanlines per mode line */ +#define DL_CHR40x8x4 ((unsigned char) 4) /* colour, 40 character & 8 scanlines per mode line (GR. 12) */ +#define DL_CHR40x16x4 ((unsigned char) 5) /* colour, 40 character & 16 scanlines per mode line (GR. 13) */ +#define DL_CHR20x8x2 ((unsigned char) 6) /* colour (duochrome per character), 20 character & 8 scanlines per mode line (GR. 1) */ +#define DL_CHR20x16x2 ((unsigned char) 7) /* colour (duochrome per character), 20 character & 16 scanlines per mode line (GR. 2) */ -#define DL_MAP40x8x4 (unsigned char) 8 /* colour, 40 pixel & 8 scanlines per mode line (GR. 3) */ -#define DL_MAP80x4x2 (unsigned char) 9 /* 'duochrome', 80 pixel & 4 scanlines per mode line (GR.4) */ -#define DL_MAP80x4x4 (unsigned char) 10 /* colour, 80 pixel & 4 scanlines per mode line (GR.5) */ -#define DL_MAP160x2x2 (unsigned char) 11 /* 'duochrome', 160 pixel & 2 scanlines per mode line (GR.6) */ -#define DL_MAP160x1x2 (unsigned char) 12 /* 'duochrome', 160 pixel & 1 scanline per mode line (GR.14) */ -#define DL_MAP160x2x4 (unsigned char) 13 /* 4 colours, 160 pixel & 2 scanlines per mode line (GR.7) */ -#define DL_MAP160x1x4 (unsigned char) 14 /* 4 colours, 160 pixel & 1 scanline per mode line (GR.15) */ -#define DL_MAP320x1x1 (unsigned char) 15 /* monochrome, 320 pixel & 1 scanline per mode line (GR.8) */ +#define DL_MAP40x8x4 ((unsigned char) 8) /* colour, 40 pixel & 8 scanlines per mode line (GR. 3) */ +#define DL_MAP80x4x2 ((unsigned char) 9) /* 'duochrome', 80 pixel & 4 scanlines per mode line (GR.4) */ +#define DL_MAP80x4x4 ((unsigned char) 10) /* colour, 80 pixel & 4 scanlines per mode line (GR.5) */ +#define DL_MAP160x2x2 ((unsigned char) 11) /* 'duochrome', 160 pixel & 2 scanlines per mode line (GR.6) */ +#define DL_MAP160x1x2 ((unsigned char) 12) /* 'duochrome', 160 pixel & 1 scanline per mode line (GR.14) */ +#define DL_MAP160x2x4 ((unsigned char) 13) /* 4 colours, 160 pixel & 2 scanlines per mode line (GR.7) */ +#define DL_MAP160x1x4 ((unsigned char) 14) /* 4 colours, 160 pixel & 1 scanline per mode line (GR.15) */ +#define DL_MAP320x1x1 ((unsigned char) 15) /* monochrome, 320 pixel & 1 scanline per mode line (GR.8) */ /* modifiers on mode lines */ -#define DL_HSCROL(x) (unsigned char)((x) | 16) -#define DL_VSCROL(x) (unsigned char)((x) | 32) -#define DL_LMS(x) (unsigned char)((x) | 64) +#define DL_HSCROL(x) ((unsigned char)((x) | 16)) +#define DL_VSCROL(x) ((unsigned char)((x) | 32)) +#define DL_LMS(x) ((unsigned char)((x) | 64)) /* general modifier */ -#define DL_DLI(x) (unsigned char)((x) | 128) +#define DL_DLI(x) ((unsigned char)((x) | 128)) /* End of _antic.h */ #endif /* #ifndef __ANTIC_H */ diff --git a/include/atari.h b/include/atari.h index ca12a493a..0ca2dc577 100644 --- a/include/atari.h +++ b/include/atari.h @@ -160,73 +160,73 @@ #define JOY_FIRE(v) ((v) & JOY_FIRE_MASK) /* Keyboard values returned by kbcode / CH */ -#define KEY_NONE (unsigned char) 0xFF +#define KEY_NONE ((unsigned char) 0xFF) -#define KEY_0 (unsigned char) 0x32 -#define KEY_1 (unsigned char) 0x1F -#define KEY_2 (unsigned char) 0x1E -#define KEY_3 (unsigned char) 0x1A -#define KEY_4 (unsigned char) 0x18 -#define KEY_5 (unsigned char) 0x1D -#define KEY_6 (unsigned char) 0x1B -#define KEY_7 (unsigned char) 0x33 -#define KEY_8 (unsigned char) 0x35 -#define KEY_9 (unsigned char) 0x30 +#define KEY_0 ((unsigned char) 0x32) +#define KEY_1 ((unsigned char) 0x1F) +#define KEY_2 ((unsigned char) 0x1E) +#define KEY_3 ((unsigned char) 0x1A) +#define KEY_4 ((unsigned char) 0x18) +#define KEY_5 ((unsigned char) 0x1D) +#define KEY_6 ((unsigned char) 0x1B) +#define KEY_7 ((unsigned char) 0x33) +#define KEY_8 ((unsigned char) 0x35) +#define KEY_9 ((unsigned char) 0x30) -#define KEY_A (unsigned char) 0x3F -#define KEY_B (unsigned char) 0x15 -#define KEY_C (unsigned char) 0x12 -#define KEY_D (unsigned char) 0x3A -#define KEY_E (unsigned char) 0x2A -#define KEY_F (unsigned char) 0x38 -#define KEY_G (unsigned char) 0x3D -#define KEY_H (unsigned char) 0x39 -#define KEY_I (unsigned char) 0x0D -#define KEY_J (unsigned char) 0x01 -#define KEY_K (unsigned char) 0x05 -#define KEY_L (unsigned char) 0x00 -#define KEY_M (unsigned char) 0x25 -#define KEY_N (unsigned char) 0x23 -#define KEY_O (unsigned char) 0x08 -#define KEY_P (unsigned char) 0x0A -#define KEY_Q (unsigned char) 0x2F -#define KEY_R (unsigned char) 0x28 -#define KEY_S (unsigned char) 0x3E -#define KEY_T (unsigned char) 0x2D -#define KEY_U (unsigned char) 0x0B -#define KEY_V (unsigned char) 0x10 -#define KEY_W (unsigned char) 0x2E -#define KEY_X (unsigned char) 0x16 -#define KEY_Y (unsigned char) 0x2B -#define KEY_Z (unsigned char) 0x17 +#define KEY_A ((unsigned char) 0x3F) +#define KEY_B ((unsigned char) 0x15) +#define KEY_C ((unsigned char) 0x12) +#define KEY_D ((unsigned char) 0x3A) +#define KEY_E ((unsigned char) 0x2A) +#define KEY_F ((unsigned char) 0x38) +#define KEY_G ((unsigned char) 0x3D) +#define KEY_H ((unsigned char) 0x39) +#define KEY_I ((unsigned char) 0x0D) +#define KEY_J ((unsigned char) 0x01) +#define KEY_K ((unsigned char) 0x05) +#define KEY_L ((unsigned char) 0x00) +#define KEY_M ((unsigned char) 0x25) +#define KEY_N ((unsigned char) 0x23) +#define KEY_O ((unsigned char) 0x08) +#define KEY_P ((unsigned char) 0x0A) +#define KEY_Q ((unsigned char) 0x2F) +#define KEY_R ((unsigned char) 0x28) +#define KEY_S ((unsigned char) 0x3E) +#define KEY_T ((unsigned char) 0x2D) +#define KEY_U ((unsigned char) 0x0B) +#define KEY_V ((unsigned char) 0x10) +#define KEY_W ((unsigned char) 0x2E) +#define KEY_X ((unsigned char) 0x16) +#define KEY_Y ((unsigned char) 0x2B) +#define KEY_Z ((unsigned char) 0x17) -#define KEY_COMMA (unsigned char) 0x20 -#define KEY_PERIOD (unsigned char) 0x22 -#define KEY_SLASH (unsigned char) 0x26 -#define KEY_SEMICOLON (unsigned char) 0x02 -#define KEY_PLUS (unsigned char) 0x06 -#define KEY_ASTERISK (unsigned char) 0x07 -#define KEY_DASH (unsigned char) 0x0E -#define KEY_EQUALS (unsigned char) 0x0F -#define KEY_LESSTHAN (unsigned char) 0x36 -#define KEY_GREATERTHAN (unsigned char) 0x37 +#define KEY_COMMA ((unsigned char) 0x20) +#define KEY_PERIOD ((unsigned char) 0x22) +#define KEY_SLASH ((unsigned char) 0x26) +#define KEY_SEMICOLON ((unsigned char) 0x02) +#define KEY_PLUS ((unsigned char) 0x06) +#define KEY_ASTERISK ((unsigned char) 0x07) +#define KEY_DASH ((unsigned char) 0x0E) +#define KEY_EQUALS ((unsigned char) 0x0F) +#define KEY_LESSTHAN ((unsigned char) 0x36) +#define KEY_GREATERTHAN ((unsigned char) 0x37) -#define KEY_ESC (unsigned char) 0x1C -#define KEY_TAB (unsigned char) 0x2C -#define KEY_SPACE (unsigned char) 0x21 -#define KEY_RETURN (unsigned char) 0x0C -#define KEY_DELETE (unsigned char) 0x34 -#define KEY_CAPS (unsigned char) 0x3C -#define KEY_INVERSE (unsigned char) 0x27 -#define KEY_HELP (unsigned char) 0x11 +#define KEY_ESC ((unsigned char) 0x1C) +#define KEY_TAB ((unsigned char) 0x2C) +#define KEY_SPACE ((unsigned char) 0x21) +#define KEY_RETURN ((unsigned char) 0x0C) +#define KEY_DELETE ((unsigned char) 0x34) +#define KEY_CAPS ((unsigned char) 0x3C) +#define KEY_INVERSE ((unsigned char) 0x27) +#define KEY_HELP ((unsigned char) 0x11) -#define KEY_F1 (unsigned char) 0x03 -#define KEY_F2 (unsigned char) 0x04 -#define KEY_F3 (unsigned char) 0x13 -#define KEY_F4 (unsigned char) 0x14 +#define KEY_F1 ((unsigned char) 0x03) +#define KEY_F2 ((unsigned char) 0x04) +#define KEY_F3 ((unsigned char) 0x13) +#define KEY_F4 ((unsigned char) 0x14) -#define KEY_CTRL (unsigned char) 0x80 -#define KEY_SHIFT (unsigned char) 0x40 +#define KEY_CTRL ((unsigned char) 0x80) +#define KEY_SHIFT ((unsigned char) 0x40) /* Composed keys */ From 83768a1e8adb40e59756dfaf2bdd87e3b5c94570 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 13 Nov 2018 16:47:53 +0100 Subject: [PATCH 0927/2161] Fixed two typos. --- doc/funcref.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index ade7a855f..47542825e 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -2626,7 +2626,7 @@ retrieved value may not be valid. See also the platform-specific information. <tag/Availability/POSIX 1003.1 <tag/See also/ <ref id="clock_getres" name="clock_getres">, -<ref id="clock_settime" name="clock_settime"> +<ref id="clock_settime" name="clock_settime">, <ref id="time" name="time"> <tag/Example/None. </descrip> @@ -2637,7 +2637,7 @@ retrieved value may not be valid. See also the platform-specific information. <quote> <descrip> -<tag/Function/Get the time from the realtime clock. +<tag/Function/Set the time on the realtime clock. <tag/Header/<tt/<ref id="time.h" name="time.h">/ <tag/Declaration/<tt/int __fastcall__ clock_settime (clockid_t clock_id, const struct timespec *tp);/ <tag/Description/The <tt/clock_settime/ function sets the time since the 1970-01-01 00:00:00 From 4b42d6ad54a9e8d3adc801fca7b19092396a6c42 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 13 Nov 2018 18:31:53 +0100 Subject: [PATCH 0928/2161] Added target docs on the clock_... functions. --- doc/apple2.sgml | 48 +++++++++++++++++++++++++++++++++------------- doc/apple2enh.sgml | 48 +++++++++++++++++++++++++++++++++------------- doc/c128.sgml | 7 +++++++ doc/c64.sgml | 7 +++++++ doc/cbm510.sgml | 7 +++++++ doc/cbm610.sgml | 7 +++++++ 6 files changed, 98 insertions(+), 26 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index aa3089957..f61a8a68e 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -469,25 +469,47 @@ BASIC.SYSTEM) there are some limitations for DOS 3.3: <sect1>Direct console I/O<p> -<descrip> - - <tag/Color/ - The Apple ][ has no color text mode. Therefore the functions textcolor(), - bgcolor() and bordercolor() have no effect. - -</descrip><p> +The Apple ][ has no color text mode. Therefore the functions +<tt/textcolor()/, <tt/bgcolor()/ and <tt/bordercolor()/ have no effect. <sect1>Random number generator<p> -<descrip> +The random number seed is generated from the time the program waits for user input. +Therefore it is necessary to wait for at least one user keypress either via Standard +I/O or via Direct console I/O before initializing the pseudo random number generator. - <tag/Random number seed/ - The random number seed is generated from the time the program waits for user input. - Therefore it is necessary to wait for at least one user keypress either via Standard - I/O or via Direct console I/O before initializing the pseudo random number generator. -</descrip><p> +<sect1>Realtime clock<p> + +There are several types of realtime clocks. It's not desirable to have specific code +for all of them. As ProDOS 8 supports file timestamps, realtime clock owners usually +use ProDOS 8 drivers for their realtime clock. Those drivers read the realtime clock +and write the result to the date/time location in RAM ($BF90 to $BF93). +ProDOS 8 reads the date/time from that RAM location. If there's no realtime clock the +RAM location keeps containing zeros. ProDOS 8 uses those zeros as timestamps and the +files show up in a directory as <tt/<NO DATE>/. + +There's no common interface to set realtime clocks so if a realtme clock <bf/IS/ +present there's just nothing to do. However, if there's <bf/NO/ realtime clock present, +the user might very well be interest to "manually" set the RAM location in order to +have timestamps. But he surely doesn't want to manually set the RAM location over and +over again. Rather he wants to set it just once after booting ProDOS 8. + +From that perspective it makes most sense to not set both the date and the time but +rather only set the date and have the time just stay zero. Then files show up in a +directory as <tt/DD-MON-YY 0:00/. + +So <tt/clock_settime()/ checks if the current time equals 0:00. If it does <bf/NOT/ +then a realtime clock is supposed to be active and <tt/clock_settime()/ fails with +<tt/ERANGE/. Otherwise <tt/clock_settime()/ sets the date - and completely ignores +the time provided as parameter. + +<tt/clock_getres()/ too checks if the current time equals 0:00. If it does <bf/NOT/ +then a realtime clock is supposed to be active and <tt/clock_getres()/ returns a time +resolution of one minute. Otherwise <tt/clock_getres()/ presumes that the only one +who sets the RAM location is <tt/clock_settime()/ and therefore returns a time +resolution of one day. diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index fbdba908b..649c6ef9f 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -470,25 +470,47 @@ BASIC.SYSTEM) there are some limitations for DOS 3.3: <sect1>Direct console I/O<p> -<descrip> - - <tag/Color/ - The enhanced Apple //e has no color text mode. Therefore the functions - textcolor(), bgcolor() and bordercolor() have no effect. - -</descrip><p> +The enhanced Apple //e has no color text mode. Therefore the functions +<tt/textcolor()/, <tt/bgcolor()/ and <tt/bordercolor()/ have no effect. <sect1>Random number generator<p> -<descrip> +The random number seed is generated from the time the program waits for user input. +Therefore it is necessary to wait for at least one user keypress either via Standard +I/O or via Direct console I/O before initializing the pseudo random number generator. - <tag/Random number seed/ - The random number seed is generated from the time the program waits for user input. - Therefore it is necessary to wait for at least one user keypress either via Standard - I/O or via Direct console I/O before initializing the pseudo random number generator. -</descrip><p> +<sect1>Realtime clock<p> + +There are several types of realtime clocks. It's not desirable to have specific code +for all of them. As ProDOS 8 supports file timestamps, realtime clock owners usually +use ProDOS 8 drivers for their realtime clock. Those drivers read the realtime clock +and write the result to the date/time location in RAM ($BF90 to $BF93). +ProDOS 8 reads the date/time from that RAM location. If there's no realtime clock the +RAM location keeps containing zeros. ProDOS 8 uses those zeros as timestamps and the +files show up in a directory as <tt/<NO DATE>/. + +There's no common interface to set realtime clocks so if a realtme clock <bf/IS/ +present there's just nothing to do. However, if there's <bf/NO/ realtime clock present, +the user might very well be interest to "manually" set the RAM location in order to +have timestamps. But he surely doesn't want to manually set the RAM location over and +over again. Rather he wants to set it just once after booting ProDOS 8. + +From that perspective it makes most sense to not set both the date and the time but +rather only set the date and have the time just stay zero. Then files show up in a +directory as <tt/DD-MON-YY 0:00/. + +So <tt/clock_settime()/ checks if the current time equals 0:00. If it does <bf/NOT/ +then a realtime clock is supposed to be active and <tt/clock_settime()/ fails with +<tt/ERANGE/. Otherwise <tt/clock_settime()/ sets the date - and completely ignores +the time provided as parameter. + +<tt/clock_getres()/ too checks if the current time equals 0:00. If it does <bf/NOT/ +then a realtime clock is supposed to be active and <tt/clock_getres()/ returns a time +resolution of one minute. Otherwise <tt/clock_getres()/ presumes that the only one +who sets the RAM location is <tt/clock_settime()/ and therefore returns a time +resolution of one day. diff --git a/doc/c128.sgml b/doc/c128.sgml index dd9af2d6b..84b601ab7 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -339,6 +339,13 @@ The default drivers, <tt/mouse_stddrv (mouse_static_stddrv)/, point to <tt/c128- <sect>Limitations<p> +<sect1>Realtime clock<p> + +The realtime clock functions use the CIA1 TOD clock. As that clock only stores +the time but not the date, the date set by <tt/clock_settime()/ ist simply stored +inside the C library for retrieval in the same program via <tt/clock_gettime()/. + + <sect>Other hints<p> diff --git a/doc/c64.sgml b/doc/c64.sgml index 328a77ab6..8c910666c 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -418,6 +418,13 @@ The default drivers, <tt/mouse_stddrv (mouse_static_stddrv)/, point to <tt/c64-1 <sect>Limitations<p> +<sect1>Realtime clock<p> + +The realtime clock functions use the CIA1 TOD clock. As that clock only stores +the time but not the date, the date set by <tt/clock_settime()/ ist simply stored +inside the C library for retrieval in the same program via <tt/clock_gettime()/. + + <sect>Other hints<p> diff --git a/doc/cbm510.sgml b/doc/cbm510.sgml index 5c7c0f767..5df8f06f6 100644 --- a/doc/cbm510.sgml +++ b/doc/cbm510.sgml @@ -242,6 +242,13 @@ The default drivers, <tt/mouse_stddrv (mouse_static_stddrv)/, point to <tt/cbm51 <sect>Limitations<label id="limitations"><p> +<sect1>Realtime clock<p> + +The realtime clock functions use the CIA1 TOD clock. As that clock only stores +the time but not the date, the date set by <tt/clock_settime()/ ist simply stored +inside the C library for retrieval in the same program via <tt/clock_gettime()/. + + <sect1>Kernal and hardware access<p> Since the program runs in bank 0, and the kernal and all I/O chips are located diff --git a/doc/cbm610.sgml b/doc/cbm610.sgml index c1faefd51..49313c4d2 100644 --- a/doc/cbm610.sgml +++ b/doc/cbm610.sgml @@ -224,6 +224,13 @@ No mouse drivers are currently available for the Commodore 610. <sect>Limitations<label id="limitations"><p> +<sect1>Realtime clock<p> + +The realtime clock functions use the CIA1 TOD clock. As that clock only stores +the time but not the date, the date set by <tt/clock_settime()/ ist simply stored +inside the C library for retrieval in the same program via <tt/clock_gettime()/. + + <sect1>Kernal and hardware access<p> Since the program runs in bank 1, and the kernal and all I/O chips are located From 582aa41f2a702ff477a00a5d69a794390a13b544 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 14 Nov 2018 18:02:56 +0100 Subject: [PATCH 0929/2161] Fixed typo. --- doc/c128.sgml | 2 +- doc/c64.sgml | 2 +- doc/cbm510.sgml | 2 +- doc/cbm610.sgml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/c128.sgml b/doc/c128.sgml index 84b601ab7..82c280ef0 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -342,7 +342,7 @@ The default drivers, <tt/mouse_stddrv (mouse_static_stddrv)/, point to <tt/c128- <sect1>Realtime clock<p> The realtime clock functions use the CIA1 TOD clock. As that clock only stores -the time but not the date, the date set by <tt/clock_settime()/ ist simply stored +the time but not the date, the date set by <tt/clock_settime()/ is simply stored inside the C library for retrieval in the same program via <tt/clock_gettime()/. diff --git a/doc/c64.sgml b/doc/c64.sgml index 8c910666c..37ac0c146 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -421,7 +421,7 @@ The default drivers, <tt/mouse_stddrv (mouse_static_stddrv)/, point to <tt/c64-1 <sect1>Realtime clock<p> The realtime clock functions use the CIA1 TOD clock. As that clock only stores -the time but not the date, the date set by <tt/clock_settime()/ ist simply stored +the time but not the date, the date set by <tt/clock_settime()/ is simply stored inside the C library for retrieval in the same program via <tt/clock_gettime()/. diff --git a/doc/cbm510.sgml b/doc/cbm510.sgml index 5df8f06f6..600a1fe90 100644 --- a/doc/cbm510.sgml +++ b/doc/cbm510.sgml @@ -245,7 +245,7 @@ The default drivers, <tt/mouse_stddrv (mouse_static_stddrv)/, point to <tt/cbm51 <sect1>Realtime clock<p> The realtime clock functions use the CIA1 TOD clock. As that clock only stores -the time but not the date, the date set by <tt/clock_settime()/ ist simply stored +the time but not the date, the date set by <tt/clock_settime()/ is simply stored inside the C library for retrieval in the same program via <tt/clock_gettime()/. diff --git a/doc/cbm610.sgml b/doc/cbm610.sgml index 49313c4d2..68b1060ad 100644 --- a/doc/cbm610.sgml +++ b/doc/cbm610.sgml @@ -227,7 +227,7 @@ No mouse drivers are currently available for the Commodore 610. <sect1>Realtime clock<p> The realtime clock functions use the CIA1 TOD clock. As that clock only stores -the time but not the date, the date set by <tt/clock_settime()/ ist simply stored +the time but not the date, the date set by <tt/clock_settime()/ is simply stored inside the C library for retrieval in the same program via <tt/clock_gettime()/. From 3ffefb0f0d2e5985981b4208fae07b26be500ef1 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 16 Nov 2018 12:45:45 +0100 Subject: [PATCH 0930/2161] Fixed reference to clock_settime(). --- doc/funcref.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 47542825e..0d294d886 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -2587,7 +2587,7 @@ changing values. (See the description of <tt/cbm_k_udtim()/.) of the realtime clock. <tt/clock_id/ has to be <tt/CLOCK_REALTIME/. If <tt/res/ is not <tt/NULL/, the resolution of the realtime clock is stored in the location pointed to by <tt/res/. If <tt/res/ is <tt/NULL/, the clock resolution is not returned. -If the <tt/time/ argument of <tt/<ref id="clock_settime" name="clock_settime">/ is not +If the <tt/tp/ argument of <tt/<ref id="clock_settime" name="clock_settime">/ is not a multiple of <tt/res/, then the value is truncated to a multiple of <tt/res/. 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 ee6b2edd72676cef8d709d467fba162906797c42 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 16 Nov 2018 12:54:26 +0100 Subject: [PATCH 0931/2161] Replaced systime() with clock_gettime(). --- doc/geos.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/geos.sgml b/doc/geos.sgml index 8e50a2605..cb849c389 100644 --- a/doc/geos.sgml +++ b/doc/geos.sgml @@ -48,7 +48,7 @@ changed between <tt/tgi_init/ and <tt/tgi_done/. It is safe to use these standard includes and their contents: <tt/assert.h, conio.h, dio.h, errno.h, em.h, geos.h, joystick.h, modload.h, mouse.h, stdlib.h, string.h, tgi.h, time.h/ <p> -For <tt/time.h/ functions <tt/systime()/ and <tt/clock()/ note that the resolution is one second. +For <tt/time.h/ functions <tt/clock()/ and <tt/clock_gettime()/ note that the resolution is one second. <p> Functions from the headers above are either standard C library functions or cc65-specific, in either case they are not GEOS specific and so they are not described here. From bc6127ffef1bbb8c53451680b5d38615d1e94a60 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 15 Nov 2018 22:25:38 +0100 Subject: [PATCH 0932/2161] atari.sgml: Add documentation for Atari clock_... functions implementation. --- doc/atari.sgml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/doc/atari.sgml b/doc/atari.sgml index a0efab9be..5b09a6635 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -29,7 +29,7 @@ supports XL type or newer machines (excluding the 600XL). The <tt/atarixl/ runtime makes the whole 64K of memory available, with the exception of the I/O area at $D000 - $D7FF. Since the -<tt/atarixl/ runtime has some <ref name="limitations" id="limitations">, it is +<tt/atarixl/ runtime has some <ref name="limitations" id="xllimitations">, it is recommended to use the <tt/atari/ target unless lack of memory dictates the use of the <tt/atarixl/ target. @@ -634,7 +634,18 @@ interface module. <sect>Limitations<p> -<sect1><tt/atarixl/<#if output="info|latex2e"> limitations</#if><label id="limitations"<p> +<sect1><tt/Realtime clock/<label id="realtimeclock"<p> + +Access to the real time clock is supported only when running on SpartaDOS-X. +There needs to be an RTC driver installed. This is normally the case +in the default installation (CONFIG.SYS) of SpartaDOS-X. +A missing RTC driver in SpartaDOS-X is not supported, and the program +may crash when calling the <tt/clock_settime()/ or <tt/clock_readtime()/ +functions. + +The resolution of the RTC driver is 1 second. + +<sect1><tt/atarixl target/<#if output="info|latex2e"> limitations</#if><label id="xllimitations"<p> <itemize> <item>The display is cleared at program start and at program termination. This is a side From b8bd075e5ebaf0034b875393bc3e8c623f6c49bf Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 15 Nov 2018 22:47:48 +0100 Subject: [PATCH 0933/2161] atari.sgml: fix typo --- doc/atari.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/atari.sgml b/doc/atari.sgml index 5b09a6635..7389cb9bc 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -640,7 +640,7 @@ Access to the real time clock is supported only when running on SpartaDOS-X. There needs to be an RTC driver installed. This is normally the case in the default installation (CONFIG.SYS) of SpartaDOS-X. A missing RTC driver in SpartaDOS-X is not supported, and the program -may crash when calling the <tt/clock_settime()/ or <tt/clock_readtime()/ +may crash when calling the <tt/clock_settime()/ or <tt/clock_gettime()/ functions. The resolution of the RTC driver is 1 second. From 9405323815509bd79b895fc426e72b351ad22555 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 15 Nov 2018 23:06:47 +0100 Subject: [PATCH 0934/2161] Some documentation fixes - gamate.sgml: remove empty section "Hardware access" - telestrat.sgml: remove wrong "<descrip>" tags --- doc/gamate.sgml | 13 ------------- doc/telestrat.sgml | 13 ------------- 2 files changed, 26 deletions(-) diff --git a/doc/gamate.sgml b/doc/gamate.sgml index 1a2a73178..e5e3acbdd 100644 --- a/doc/gamate.sgml +++ b/doc/gamate.sgml @@ -49,16 +49,6 @@ Programs containing Gamate specific code may use the <tt/gamate.h/ header file. </itemize> -<sect1>Hardware access<p> - -The following pseudo variables declared in the <tt/gamate.inc/ include file do -allow access to hardware located in the address space. - -<descrip> - -</descrip><p> - - <sect>Loadable drivers<p> @@ -159,6 +149,3 @@ freely, subject to the following restrictions: </enum> </article> - - - diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index fe9efcfdb..8d8aa23d2 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -133,29 +133,16 @@ No extended memory drivers are currently available for the Telestrat. <sect1>Joystick drivers<p> -<descrip> - telemon 2.4 & 3.0 manages joysticks but it had been handled yet. -</descrip> - - <sect1>Mouse drivers<p> -<descrip> - Telestrat manages also mouse, but it had been no handled yet in this version. -</descrip> - <sect1>RS232 device drivers<p> -<descrip> - Telestrat has a RS232 port, but it's not usable in cc65. -</descrip> - <sect>Limitations<label id="limitations"><p> <sect1>Disk I/O<p> From 462d8096c08c6669f34d8bf655d93352da658a69 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Fri, 16 Nov 2018 15:22:02 +0100 Subject: [PATCH 0935/2161] atari.sgml: use consistent naming for realtime clock. --- doc/atari.sgml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/atari.sgml b/doc/atari.sgml index 7389cb9bc..2531c8d03 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -636,14 +636,14 @@ interface module. <sect1><tt/Realtime clock/<label id="realtimeclock"<p> -Access to the real time clock is supported only when running on SpartaDOS-X. -There needs to be an RTC driver installed. This is normally the case +Access to the realtime clock is supported only when running on SpartaDOS-X. +There needs to be a realtime clock driver installed. This is normally the case in the default installation (CONFIG.SYS) of SpartaDOS-X. -A missing RTC driver in SpartaDOS-X is not supported, and the program +A missing realtime clock driver in SpartaDOS-X is not supported, and the program may crash when calling the <tt/clock_settime()/ or <tt/clock_gettime()/ functions. -The resolution of the RTC driver is 1 second. +The resolution of the realtime clock driver is 1 second. <sect1><tt/atarixl target/<#if output="info|latex2e"> limitations</#if><label id="xllimitations"<p> From 01857cd4defd74d1a084a6e85b746743d1271403 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 24 Nov 2018 14:10:58 +0100 Subject: [PATCH 0936/2161] Updated Visual Studio solution files to VS 2017. --- src/ar65.vcxproj | 7 ++++--- src/ca65.vcxproj | 7 ++++--- src/cc65.vcxproj | 7 ++++--- src/chrcvt65.vcxproj | 7 ++++--- src/cl65.vcxproj | 7 ++++--- src/co65.vcxproj | 7 ++++--- src/common.vcxproj | 7 ++++--- src/da65.vcxproj | 7 ++++--- src/grc65.vcxproj | 7 ++++--- src/ld65.vcxproj | 7 ++++--- src/od65.vcxproj | 7 ++++--- src/sim65.vcxproj | 7 ++++--- src/sp65.vcxproj | 7 ++++--- 13 files changed, 52 insertions(+), 39 deletions(-) diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index 003a5fa69..a57bec813 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -14,16 +14,17 @@ <ProjectGuid>{5E8C19C6-B167-440C-8BEF-3CBF109CDB49}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>ar65</RootNamespace> + <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index fb7cf2e26..df246a59f 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -14,16 +14,17 @@ <ProjectGuid>{D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>ca65</RootNamespace> + <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 12573e862..a56ecf880 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -14,16 +14,17 @@ <ProjectGuid>{B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>cc65</RootNamespace> + <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index d120399d1..351f6077e 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -14,16 +14,17 @@ <ProjectGuid>{1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>chrcvt65</RootNamespace> + <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index b6ceb161a..dab77e196 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -14,16 +14,17 @@ <ProjectGuid>{F657912F-050A-488B-B203-50ED5715CDD7}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>cl65</RootNamespace> + <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 89eed36e1..9b4f18786 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -14,16 +14,17 @@ <ProjectGuid>{F5DB5D1A-05BC-48FE-B346-4E96DD522AA2}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>co65</RootNamespace> + <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/common.vcxproj b/src/common.vcxproj index 644d6da85..eb0dffd66 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -110,18 +110,19 @@ <ProjectGuid>{71DC1F68-BFC4-478C-8655-C8E9C9654D2B}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>common</RootNamespace> + <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> <ConfigurationType>StaticLibrary</ConfigurationType> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 06af7505d..7a8b0de68 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -14,16 +14,17 @@ <ProjectGuid>{0BCFB793-2B25-40E2-B265-75848824AC4C}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>da65</RootNamespace> + <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index afac0cce1..841ec635a 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -14,16 +14,17 @@ <ProjectGuid>{E0FD0AB3-3BEE-496F-8108-A8E0F8933F39}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>grc65</RootNamespace> + <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index cc5598aad..f98da6119 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -14,16 +14,17 @@ <ProjectGuid>{26C749A0-814C-47A2-9D36-AE92AE932FE4}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>ld65</RootNamespace> + <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 2ace26001..03ea41fce 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -14,16 +14,17 @@ <ProjectGuid>{FF8576C2-1253-44FE-A51B-D9AE35F3CEAD}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>od65</RootNamespace> + <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9ba0980ba..9dc61e53f 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -14,16 +14,17 @@ <ProjectGuid>{002A366E-2863-46A8-BDDE-DDF534AAEC73}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>sim65</RootNamespace> + <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 6e7d992d4..3b770ec57 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -14,16 +14,17 @@ <ProjectGuid>{4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>sp65</RootNamespace> + <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v140</PlatformToolset> + <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> From e69bc65cf1f7b117af190774f692c4e99feb5ba9 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Sun, 25 Nov 2018 10:28:37 +0200 Subject: [PATCH 0937/2161] Moved kernal entries to cbm_kernal.inc --- asminc/c128.inc | 14 -------------- asminc/c64.inc | 8 -------- asminc/cbm_kernal.inc | 25 +++++++++++++++++++++++++ asminc/plus4.inc | 9 --------- asminc/vic20.inc | 7 ------- 5 files changed, 25 insertions(+), 38 deletions(-) diff --git a/asminc/c128.inc b/asminc/c128.inc index 7a98d770c..2852631f3 100644 --- a/asminc/c128.inc +++ b/asminc/c128.inc @@ -45,20 +45,6 @@ KBDREPEAT := $028a KBDREPEATRATE := $028b KBDREPEATDELAY := $028c -; --------------------------------------------------------------------------- -; Kernal routines - -; Direct entries -CURS_SET := $CD57 -CURS_ON := $CD6F -CURS_OFF := $CD9F -CLRSCR := $C142 -KBDREAD := $C006 -NEWLINE := $C363 -PRINT := $C322 -NMIEXIT := $FF33 -INDFET := $FF74 - ; --------------------------------------------------------------------------- ; Vectors diff --git a/asminc/c64.inc b/asminc/c64.inc index c12f8e64b..1d10f673d 100644 --- a/asminc/c64.inc +++ b/asminc/c64.inc @@ -37,14 +37,6 @@ KBDREPEAT := $28a KBDREPEATRATE := $28b KBDREPEATDELAY := $28c -; --------------------------------------------------------------------------- -; Kernal routines - -; Direct entries -CLRSCR := $E544 -KBDREAD := $E5B4 -NMIEXIT := $FEBC - ; --------------------------------------------------------------------------- ; Vector and other locations diff --git a/asminc/cbm_kernal.inc b/asminc/cbm_kernal.inc index 4e2e927e4..29a6e5ddf 100644 --- a/asminc/cbm_kernal.inc +++ b/asminc/cbm_kernal.inc @@ -82,3 +82,28 @@ UDTIM := $FFEA PLOT := $FFF0 IOBASE := $FFF3 .endif + +; --------------------------------------------------------------------------- +; Kernal routines, direct entries + +.if .def(__VIC20__) + CLRSCR := $E55F + KBDREAD := $E5CF +.elseif .def(__C64__) + CLRSCR := $E544 + KBDREAD := $E5B4 + NMIEXIT := $FEBC +.elseif .def(__C128__) + CLRSCR := $C142 + KBDREAD := $C006 + NMIEXIT := $FF33 + NEWLINE := $C363 + PRINT := $C322 + CURS_SET := $CD57 + CURS_ON := $CD6F + CURS_OFF := $CD9F + INDFET := $FF74 +.elseif .def(__C16__) + CLRSCR := $D88B + KBDREAD := $D8C1 +.endif diff --git a/asminc/plus4.inc b/asminc/plus4.inc index 5ea4dcf88..774722e93 100644 --- a/asminc/plus4.inc +++ b/asminc/plus4.inc @@ -37,13 +37,6 @@ KBDREPEAT := $540 KBDREPEATRATE := $541 KBDREPEATDELAY := $542 -; --------------------------------------------------------------------------- -; Kernal routines - -; Direct entries -CLRSCR := $D88B -KBDREAD := $D8C1 - ; --------------------------------------------------------------------------- ; Vector and other locations @@ -90,5 +83,3 @@ TED_RAMSEL := $FF3F ENABLE_ROM := TED_ROMSEL ENABLE_RAM := TED_RAMSEL - - diff --git a/asminc/vic20.inc b/asminc/vic20.inc index 5976981fd..b82874f56 100644 --- a/asminc/vic20.inc +++ b/asminc/vic20.inc @@ -41,13 +41,6 @@ KBDREPEATDELAY := $28c XSIZE = 22 YSIZE = 23 -; --------------------------------------------------------------------------- -; Kernal routines - -; Direct entries -CLRSCR := $E55F -KBDREAD := $E5CF - ; --------------------------------------------------------------------------- ; Vector and other locations From aeff90ca90b45162afe151cba2c64c217822a9d3 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Sun, 25 Nov 2018 10:46:05 +0200 Subject: [PATCH 0938/2161] Updated to use cbm_kernal.inc. Whitespace cleanups --- libsrc/c128/cgetc.s | 5 +-- libsrc/c128/clrscr.s | 5 +-- libsrc/c128/cputc.s | 3 +- libsrc/c128/mainargs.s | 1 + libsrc/c16/cgetc.s | 1 + libsrc/c16/clrscr.s | 6 +--- libsrc/c64/cgetc.s | 1 + libsrc/c64/clrscr.s | 5 +-- libsrc/c64/ser/c64-swlink.s | 59 ++++++++++++++++++----------------- libsrc/c64/soft80_cgetc.s | 1 + libsrc/c64/soft80mono_cgetc.s | 1 + libsrc/plus4/cgetc.s | 1 + libsrc/plus4/clrscr.s | 7 +---- libsrc/vic20/cgetc.s | 1 + libsrc/vic20/clrscr.s | 5 +-- 15 files changed, 47 insertions(+), 55 deletions(-) diff --git a/libsrc/c128/cgetc.s b/libsrc/c128/cgetc.s index bc9d8da7f..7cf7fcc3e 100644 --- a/libsrc/c128/cgetc.s +++ b/libsrc/c128/cgetc.s @@ -10,6 +10,7 @@ .import cursor + .include "cbm_kernal.inc" .include "c128.inc" ;-------------------------------------------------------------------------- @@ -17,8 +18,8 @@ _cgetc: lda KEY_COUNT ; Get number of characters bne L2 ; Jump if there are already chars waiting -; Switch on the cursor if needed. We MUST always switch the cursor on, -; before switching it off, because switching it off will restore the +; Switch on the cursor if needed. We MUST always switch the cursor on, +; before switching it off, because switching it off will restore the ; character attribute remembered when it was switched on. So just switching ; it off will restore the wrong character attribute. diff --git a/libsrc/c128/clrscr.s b/libsrc/c128/clrscr.s index 2213be0cd..a3c519cb1 100644 --- a/libsrc/c128/clrscr.s +++ b/libsrc/c128/clrscr.s @@ -6,9 +6,6 @@ .export _clrscr - .include "c128.inc" + .include "cbm_kernal.inc" _clrscr = CLRSCR - - - diff --git a/libsrc/c128/cputc.s b/libsrc/c128/cputc.s index 9d269a47e..667260843 100644 --- a/libsrc/c128/cputc.s +++ b/libsrc/c128/cputc.s @@ -9,8 +9,8 @@ .export _cputcxy, _cputc, cputdirect, putchar .export newline, plot .import gotoxy - .import PLOT + .include "cbm_kernal.inc" .include "c128.inc" newline = NEWLINE @@ -85,4 +85,3 @@ plot: ldy CURS_X ; position in Y putchar = $CC2F - diff --git a/libsrc/c128/mainargs.s b/libsrc/c128/mainargs.s index f53ceafa0..dcf590024 100644 --- a/libsrc/c128/mainargs.s +++ b/libsrc/c128/mainargs.s @@ -25,6 +25,7 @@ .constructor initmainargs, 24 .import __argc, __argv + .include "cbm_kernal.inc" .include "c128.inc" diff --git a/libsrc/c16/cgetc.s b/libsrc/c16/cgetc.s index a61373ac7..52d985caf 100644 --- a/libsrc/c16/cgetc.s +++ b/libsrc/c16/cgetc.s @@ -7,6 +7,7 @@ .export _cgetc .import cursor + .include "cbm_kernal.inc" .include "plus4.inc" diff --git a/libsrc/c16/clrscr.s b/libsrc/c16/clrscr.s index 56fe0c62c..a3c519cb1 100644 --- a/libsrc/c16/clrscr.s +++ b/libsrc/c16/clrscr.s @@ -6,10 +6,6 @@ .export _clrscr - .include "plus4.inc" + .include "cbm_kernal.inc" _clrscr = CLRSCR - - - - diff --git a/libsrc/c64/cgetc.s b/libsrc/c64/cgetc.s index 042f99fd3..58008990b 100644 --- a/libsrc/c64/cgetc.s +++ b/libsrc/c64/cgetc.s @@ -7,6 +7,7 @@ .export _cgetc .import cursor + .include "cbm_kernal.inc" .include "c64.inc" _cgetc: lda KEY_COUNT ; Get number of characters diff --git a/libsrc/c64/clrscr.s b/libsrc/c64/clrscr.s index 396828847..a3c519cb1 100644 --- a/libsrc/c64/clrscr.s +++ b/libsrc/c64/clrscr.s @@ -6,9 +6,6 @@ .export _clrscr - .include "c64.inc" + .include "cbm_kernal.inc" _clrscr = CLRSCR - - - diff --git a/libsrc/c64/ser/c64-swlink.s b/libsrc/c64/ser/c64-swlink.s index 813067239..87b8e2f09 100644 --- a/libsrc/c64/ser/c64-swlink.s +++ b/libsrc/c64/ser/c64-swlink.s @@ -24,6 +24,7 @@ .include "zeropage.inc" .include "ser-kernel.inc" .include "ser-error.inc" + .include "cbm_kernal.inc" .include "c64.inc" .macpack module @@ -45,15 +46,15 @@ ; Jump table - .word INSTALL - .word UNINSTALL - .word OPEN - .word CLOSE - .word GET - .word PUT - .word STATUS - .word IOCTL - .word IRQ + .word SWL_INSTALL + .word SWL_UNINSTALL + .word SWL_OPEN + .word SWL_CLOSE + .word SWL_GET + .word SWL_PUT + .word SWL_STATUS + .word SWL_IOCTL + .word SWL_IRQ ;---------------------------------------------------------------------------- ; I/O definitions @@ -136,11 +137,11 @@ ParityTable: .code ;---------------------------------------------------------------------------- -; INSTALL routine. Is called after the driver is loaded into memory. If +; SWL_INSTALL routine. Is called after the driver is loaded into memory. If ; possible, check if the hardware is present. ; Must return an SER_ERR_xx code in a/x. -INSTALL: +SWL_INSTALL: ; Deactivate DTR and disable 6551 interrupts @@ -165,10 +166,10 @@ SetNMI: sta NMIVec rts ;---------------------------------------------------------------------------- -; UNINSTALL routine. Is called before the driver is removed from memory. +; SWL_UNINSTALL routine. Is called before the driver is removed from memory. ; Must return an SER_ERR_xx code in a/x. -UNINSTALL: +SWL_UNINSTALL: ; Stop interrupts, drop DTR @@ -185,7 +186,7 @@ UNINSTALL: ; PARAMS routine. A pointer to a ser_params structure is passed in ptr1. ; Must return an SER_ERR_xx code in a/x. -OPEN: +SWL_OPEN: ; Check if the handshake setting is valid @@ -256,11 +257,11 @@ InvBaud: rts ;---------------------------------------------------------------------------- -; CLOSE: Close the port, disable interrupts and flush the buffer. Called +; SWL_CLOSE: Close the port, disable interrupts and flush the buffer. Called ; without parameters. Must return an error code in a/x. ; -CLOSE: +SWL_CLOSE: ; Stop interrupts, drop DTR @@ -278,12 +279,13 @@ CLOSE: rts ;---------------------------------------------------------------------------- -; GET: Will fetch a character from the receive buffer and store it into the +; SWL_GET: Will fetch a character from the receive buffer and store it into the ; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is ; return. ; -GET: ldx SendFreeCnt ; Send data if necessary +SWL_GET: + ldx SendFreeCnt ; Send data if necessary inx ; X == $FF? beq @L1 lda #$00 @@ -322,11 +324,11 @@ GET: ldx SendFreeCnt ; Send data if necessary rts ;---------------------------------------------------------------------------- -; PUT: Output character in A. +; SWL_PUT: Output character in A. ; Must return an error code in a/x. ; -PUT: +SWL_PUT: ; Try to send @@ -356,31 +358,33 @@ PUT: rts ;---------------------------------------------------------------------------- -; STATUS: Return the status in the variable pointed to by ptr1. +; SWL_STATUS: Return the status in the variable pointed to by ptr1. ; Must return an error code in a/x. ; -STATUS: lda ACIA_STATUS +SWL_STATUS: + lda ACIA_STATUS ldx #0 sta (ptr1,x) txa ; SER_ERR_OK rts ;---------------------------------------------------------------------------- -; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl +; SWL_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl ; specific data in ptr1, and the ioctl code in A. ; Must return an error code in a/x. ; -IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now +SWL_IOCTL: + lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now ldx #>SER_ERR_INV_IOCTL - rts + rts ;---------------------------------------------------------------------------- -; IRQ: Not used on the C64 +; SWL_IRQ: Not used on the C64 ; -IRQ = $0000 +SWL_IRQ = $0000 ;---------------------------------------------------------------------------- ; @@ -476,4 +480,3 @@ InitBuffers: stx RecvFreeCnt stx SendFreeCnt rts - diff --git a/libsrc/c64/soft80_cgetc.s b/libsrc/c64/soft80_cgetc.s index ae0e23857..05e9e5b47 100644 --- a/libsrc/c64/soft80_cgetc.s +++ b/libsrc/c64/soft80_cgetc.s @@ -11,6 +11,7 @@ .import cursor .importzp tmp1 + .include "cbm_kernal.inc" .include "c64.inc" .include "soft80.inc" diff --git a/libsrc/c64/soft80mono_cgetc.s b/libsrc/c64/soft80mono_cgetc.s index d99dc7775..8d8dc940d 100644 --- a/libsrc/c64/soft80mono_cgetc.s +++ b/libsrc/c64/soft80mono_cgetc.s @@ -12,6 +12,7 @@ .import cursor .importzp tmp1 + .include "cbm_kernal.inc" .include "c64.inc" .include "soft80.inc" diff --git a/libsrc/plus4/cgetc.s b/libsrc/plus4/cgetc.s index fcbc66064..62863c06e 100644 --- a/libsrc/plus4/cgetc.s +++ b/libsrc/plus4/cgetc.s @@ -7,6 +7,7 @@ .export _cgetc .import cursor + .include "cbm_kernal.inc" .include "plus4.inc" ; -------------------------------------------------------------------------- diff --git a/libsrc/plus4/clrscr.s b/libsrc/plus4/clrscr.s index 720a5e6e4..a67016255 100644 --- a/libsrc/plus4/clrscr.s +++ b/libsrc/plus4/clrscr.s @@ -6,6 +6,7 @@ .export _clrscr + .include "cbm_kernal.inc" .include "plus4.inc" .segment "LOWCODE" ; Must go into low memory @@ -16,9 +17,3 @@ sta ENABLE_RAM ; Switch back to RAM rts ; Return to caller .endproc - - - - - - diff --git a/libsrc/vic20/cgetc.s b/libsrc/vic20/cgetc.s index d5af9a9f6..1a5c8d5a2 100644 --- a/libsrc/vic20/cgetc.s +++ b/libsrc/vic20/cgetc.s @@ -7,6 +7,7 @@ .export _cgetc .import cursor + .include "cbm_kernal.inc" .include "vic20.inc" _cgetc: lda KEY_COUNT ; Get number of characters diff --git a/libsrc/vic20/clrscr.s b/libsrc/vic20/clrscr.s index 8d4994eac..a3c519cb1 100644 --- a/libsrc/vic20/clrscr.s +++ b/libsrc/vic20/clrscr.s @@ -6,9 +6,6 @@ .export _clrscr - .include "vic20.inc" + .include "cbm_kernal.inc" _clrscr = CLRSCR - - - From 7b4807a8f7a8f82ad0a2c665f950cd4b200584b9 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Mon, 26 Nov 2018 21:31:12 +0200 Subject: [PATCH 0939/2161] Changed prefix SWL_ to SER_ --- libsrc/c64/ser/c64-swlink.s | 52 ++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/libsrc/c64/ser/c64-swlink.s b/libsrc/c64/ser/c64-swlink.s index 87b8e2f09..597cf1dd6 100644 --- a/libsrc/c64/ser/c64-swlink.s +++ b/libsrc/c64/ser/c64-swlink.s @@ -46,15 +46,15 @@ ; Jump table - .word SWL_INSTALL - .word SWL_UNINSTALL - .word SWL_OPEN - .word SWL_CLOSE - .word SWL_GET - .word SWL_PUT - .word SWL_STATUS - .word SWL_IOCTL - .word SWL_IRQ + .word SER_INSTALL + .word SER_UNINSTALL + .word SER_OPEN + .word SER_CLOSE + .word SER_GET + .word SER_PUT + .word SER_STATUS + .word SER_IOCTL + .word SER_IRQ ;---------------------------------------------------------------------------- ; I/O definitions @@ -137,11 +137,11 @@ ParityTable: .code ;---------------------------------------------------------------------------- -; SWL_INSTALL routine. Is called after the driver is loaded into memory. If +; SER_INSTALL routine. Is called after the driver is loaded into memory. If ; possible, check if the hardware is present. ; Must return an SER_ERR_xx code in a/x. -SWL_INSTALL: +SER_INSTALL: ; Deactivate DTR and disable 6551 interrupts @@ -166,10 +166,10 @@ SetNMI: sta NMIVec rts ;---------------------------------------------------------------------------- -; SWL_UNINSTALL routine. Is called before the driver is removed from memory. +; SER_UNINSTALL routine. Is called before the driver is removed from memory. ; Must return an SER_ERR_xx code in a/x. -SWL_UNINSTALL: +SER_UNINSTALL: ; Stop interrupts, drop DTR @@ -186,7 +186,7 @@ SWL_UNINSTALL: ; PARAMS routine. A pointer to a ser_params structure is passed in ptr1. ; Must return an SER_ERR_xx code in a/x. -SWL_OPEN: +SER_OPEN: ; Check if the handshake setting is valid @@ -257,11 +257,11 @@ InvBaud: rts ;---------------------------------------------------------------------------- -; SWL_CLOSE: Close the port, disable interrupts and flush the buffer. Called +; SER_CLOSE: Close the port, disable interrupts and flush the buffer. Called ; without parameters. Must return an error code in a/x. ; -SWL_CLOSE: +SER_CLOSE: ; Stop interrupts, drop DTR @@ -279,12 +279,12 @@ SWL_CLOSE: rts ;---------------------------------------------------------------------------- -; SWL_GET: Will fetch a character from the receive buffer and store it into the +; SER_GET: Will fetch a character from the receive buffer and store it into the ; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is ; return. ; -SWL_GET: +SER_GET: ldx SendFreeCnt ; Send data if necessary inx ; X == $FF? beq @L1 @@ -324,11 +324,11 @@ SWL_GET: rts ;---------------------------------------------------------------------------- -; SWL_PUT: Output character in A. +; SER_PUT: Output character in A. ; Must return an error code in a/x. ; -SWL_PUT: +SER_PUT: ; Try to send @@ -358,11 +358,11 @@ SWL_PUT: rts ;---------------------------------------------------------------------------- -; SWL_STATUS: Return the status in the variable pointed to by ptr1. +; SER_STATUS: Return the status in the variable pointed to by ptr1. ; Must return an error code in a/x. ; -SWL_STATUS: +SER_STATUS: lda ACIA_STATUS ldx #0 sta (ptr1,x) @@ -370,21 +370,21 @@ SWL_STATUS: rts ;---------------------------------------------------------------------------- -; SWL_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl +; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl ; specific data in ptr1, and the ioctl code in A. ; Must return an error code in a/x. ; -SWL_IOCTL: +SER_IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now ldx #>SER_ERR_INV_IOCTL rts ;---------------------------------------------------------------------------- -; SWL_IRQ: Not used on the C64 +; SER_IRQ: Not used on the C64 ; -SWL_IRQ = $0000 +SER_IRQ = $0000 ;---------------------------------------------------------------------------- ; From ad0b0982d003584228cdae11ff461a2530df9dfb Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Mon, 26 Nov 2018 21:41:44 +0200 Subject: [PATCH 0940/2161] Added SER_ prefix --- libsrc/atmos/ser/atmos-acia.s | 48 +++++++++++++++++------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/libsrc/atmos/ser/atmos-acia.s b/libsrc/atmos/ser/atmos-acia.s index 79fbc1bbe..f84b66a0a 100644 --- a/libsrc/atmos/ser/atmos-acia.s +++ b/libsrc/atmos/ser/atmos-acia.s @@ -44,15 +44,15 @@ .addr $0000 ; Jump table - .addr INSTALL - .addr UNINSTALL - .addr OPEN - .addr CLOSE - .addr GET - .addr PUT + .addr SER_INSTALL + .addr SER_UNINSTALL + .addr SER_OPEN + .addr SER_CLOSE + .addr SER_GET + .addr SER_PUT .addr SER_STATUS - .addr IOCTL - .addr IRQ + .addr SER_IOCTL + .addr SER_IRQ ;---------------------------------------------------------------------------- ; Global variables @@ -116,23 +116,23 @@ ParityTable: .code ;---------------------------------------------------------------------------- -; INSTALL: Is called after the driver is loaded into memory. If possible, +; SER_INSTALL: Is called after the driver is loaded into memory. If possible, ; check if the hardware is present. Must return an SER_ERR_xx code in a/x. ; ; Since we don't have to manage the IRQ vector on the Telestrat/Atmos, this is ; actually the same as: ; -; UNINSTALL: Is called before the driver is removed from memory. +; SER_UNINSTALL: Is called before the driver is removed from memory. ; No return code required (the driver is removed from memory on return). ; ; and: ; -; CLOSE: Close the port and disable interrupts. Called without parameters. +; SER_CLOSE: Close the port and disable interrupts. Called without parameters. ; Must return an SER_ERR_xx code in a/x. -INSTALL: -UNINSTALL: -CLOSE: +SER_INSTALL: +SER_UNINSTALL: +SER_CLOSE: ldx Index ; Check for open port beq :+ @@ -147,10 +147,10 @@ CLOSE: rts ;---------------------------------------------------------------------------- -; OPEN: A pointer to a ser_params structure is passed in ptr1. +; SER_OPEN: A pointer to a ser_params structure is passed in ptr1. ; Must return an SER_ERR_xx code in a/x. -OPEN: +SER_OPEN: ; Check if the handshake setting is valid ldy #SER_PARAMS::HANDSHAKE ; Handshake lda (ptr1),y @@ -220,11 +220,11 @@ InvBaud:lda #<SER_ERR_BAUD_UNAVAIL rts ;---------------------------------------------------------------------------- -; GET: Will fetch a character from the receive buffer and store it into the +; SER_GET: Will fetch a character from the receive buffer and store it into the ; variable pointed to by ptr1. If no data is available, SER_ERR_NO_DATA is ; returned. -GET: +SER_GET: ldy SendFreeCnt ; Send data if necessary iny ; Y == $FF? beq :+ @@ -261,10 +261,10 @@ GET: rts ;---------------------------------------------------------------------------- -; PUT: Output character in A. +; SER_PUT: Output character in A. ; Must return an SER_ERR_xx code in a/x. -PUT: +SER_PUT: ; Try to send ldy SendFreeCnt iny ; Y = $FF? @@ -303,22 +303,22 @@ SER_STATUS: rts ;---------------------------------------------------------------------------- -; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl +; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl ; specific data in ptr1, and the ioctl code in A. ; Must return an SER_ERR_xx code in a/x. -IOCTL: +SER_IOCTL: lda #<SER_ERR_INV_IOCTL ldx #>SER_ERR_INV_IOCTL rts ;---------------------------------------------------------------------------- -; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All +; SER_IRQ: Called from the builtin runtime IRQ handler as a subroutine. All ; registers are already saved, no parameters are passed, but the carry flag ; is clear on entry. The routine must return with carry set if the interrupt ; was handled, otherwise with carry clear. -IRQ: +SER_IRQ: ldx Index ; Check for open port beq Done lda ACIA::STATUS,x ; Check ACIA status for receive interrupt From 5901ea80a4556325598241b6fcb540fea896b383 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Mon, 26 Nov 2018 22:01:04 +0200 Subject: [PATCH 0941/2161] Added SER_ prefix. Whitespace cleanup --- libsrc/apple2/ser/a2.ssc.s | 60 +++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/libsrc/apple2/ser/a2.ssc.s b/libsrc/apple2/ser/a2.ssc.s index d5c567165..a32110ef2 100644 --- a/libsrc/apple2/ser/a2.ssc.s +++ b/libsrc/apple2/ser/a2.ssc.s @@ -44,15 +44,15 @@ .addr $0000 ; Jump table - .addr INSTALL - .addr UNINSTALL - .addr OPEN - .addr CLOSE - .addr GET - .addr PUT - .addr STATUS - .addr IOCTL - .addr IRQ + .addr SER_INSTALL + .addr SER_UNINSTALL + .addr SER_OPEN + .addr SER_CLOSE + .addr SER_GET + .addr SER_PUT + .addr SER_STATUS + .addr SER_IOCTL + .addr SER_IRQ ;---------------------------------------------------------------------------- ; I/O definitions @@ -141,23 +141,23 @@ IdTableLen = * - IdValTable .code ;---------------------------------------------------------------------------- -; INSTALL: Is called after the driver is loaded into memory. If possible, +; SER_INSTALL: Is called after the driver is loaded into memory. If possible, ; check if the hardware is present. Must return an SER_ERR_xx code in a/x. ; ; Since we don't have to manage the IRQ vector on the Apple II, this is ; actually the same as: ; -; UNINSTALL: Is called before the driver is removed from memory. +; SER_UNINSTALL: Is called before the driver is removed from memory. ; No return code required (the driver is removed from memory on return). ; ; and: ; -; CLOSE: Close the port and disable interrupts. Called without parameters. +; SER_CLOSE: Close the port and disable interrupts. Called without parameters. ; Must return an SER_ERR_xx code in a/x. -INSTALL: -UNINSTALL: -CLOSE: +SER_INSTALL: +SER_UNINSTALL: +SER_CLOSE: ldx Index ; Check for open port beq :+ @@ -172,16 +172,16 @@ CLOSE: rts ;---------------------------------------------------------------------------- -; OPEN: A pointer to a ser_params structure is passed in ptr1. +; SER_OPEN: A pointer to a ser_params structure is passed in ptr1. ; Must return an SER_ERR_xx code in a/x. -OPEN: +SER_OPEN: ldx #<$C000 stx ptr2 lda #>$C000 ora Slot sta ptr2+1 - + ; Check Pascal 1.1 Firmware Protocol ID bytes : ldy IdOfsTable,x lda IdValTable,x @@ -190,7 +190,7 @@ OPEN: inx cpx #IdTableLen bcc :- - + ; Convert slot to I/O register index lda Slot asl @@ -273,11 +273,11 @@ InvBaud:lda #<SER_ERR_BAUD_UNAVAIL rts ;---------------------------------------------------------------------------- -; GET: Will fetch a character from the receive buffer and store it into the +; SER_GET: Will fetch a character from the receive buffer and store it into the ; variable pointed to by ptr1. If no data is available, SER_ERR_NO_DATA is ; returned. -GET: +SER_GET: ldx Index ldy SendFreeCnt ; Send data if necessary iny ; Y == $FF? @@ -315,10 +315,10 @@ GET: rts ;---------------------------------------------------------------------------- -; PUT: Output character in A. +; SER_PUT: Output character in A. ; Must return an SER_ERR_xx code in a/x. -PUT: +SER_PUT: ldx Index ; Try to send @@ -348,10 +348,10 @@ PUT: rts ;---------------------------------------------------------------------------- -; STATUS: Return the status in the variable pointed to by ptr1. +; SER_STATUS: Return the status in the variable pointed to by ptr1. ; Must return an SER_ERR_xx code in a/x. -STATUS: +SER_STATUS: ldx Index lda ACIA_STATUS,x ldx #$00 @@ -360,11 +360,11 @@ STATUS: rts ;---------------------------------------------------------------------------- -; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl +; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl ; specific data in ptr1, and the ioctl code in A. ; Must return an SER_ERR_xx code in a/x. -IOCTL: +SER_IOCTL: ; Check data msb and code to be 0 ora ptr1+1 bne :+ @@ -384,12 +384,12 @@ IOCTL: rts ;---------------------------------------------------------------------------- -; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All +; SER_IRQ: Called from the builtin runtime IRQ handler as a subroutine. All ; registers are already saved, no parameters are passed, but the carry flag ; is clear on entry. The routine must return with carry set if the interrupt ; was handled, otherwise with carry clear. -IRQ: +SER_IRQ: ldx Index ; Check for open port beq Done lda ACIA_STATUS,x ; Check ACIA status for receive interrupt @@ -431,7 +431,7 @@ Again: lda SendFreeCnt lda ACIA_STATUS,x and #$10 bne Send - bit tmp1 ; Keep trying if must try hard + bit tmp1 ; Keep trying if must try hard bmi Again Quit: rts From 7147e780e6033ffc5239041f4bbead1d4e65f451 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Mon, 26 Nov 2018 22:12:28 +0200 Subject: [PATCH 0942/2161] Added SER_ prefix. Whitespace cleanup --- libsrc/c128/ser/c128-swlink.s | 55 ++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/libsrc/c128/ser/c128-swlink.s b/libsrc/c128/ser/c128-swlink.s index 98411d4f8..3337e2668 100644 --- a/libsrc/c128/ser/c128-swlink.s +++ b/libsrc/c128/ser/c128-swlink.s @@ -45,15 +45,15 @@ ; Jump table - .word INSTALL - .word UNINSTALL - .word OPEN - .word CLOSE - .word GET - .word PUT - .word STATUS - .word IOCTL - .word IRQ + .word SER_INSTALL + .word SER_UNINSTALL + .word SER_OPEN + .word SER_CLOSE + .word SER_GET + .word SER_PUT + .word SER_STATUS + .word SER_IOCTL + .word SER_IRQ ;---------------------------------------------------------------------------- ; I/O definitions @@ -155,11 +155,11 @@ Vector := *+1 .reloc ;---------------------------------------------------------------------------- -; INSTALL routine. Is called after the driver is loaded into memory. If +; SER_INSTALL routine. Is called after the driver is loaded into memory. If ; possible, check if the hardware is present. ; Must return an SER_ERR_xx code in a/x. -INSTALL: +SER_INSTALL: ; Deactivate DTR and disable 6551 interrupts @@ -192,10 +192,10 @@ SetNMI: sta NMIVec rts ;---------------------------------------------------------------------------- -; UNINSTALL routine. Is called before the driver is removed from memory. +; SER_UNINSTALL routine. Is called before the driver is removed from memory. ; Must return an SER_ERR_xx code in a/x. -UNINSTALL: +SER_UNINSTALL: ; Stop interrupts, drop DTR @@ -212,7 +212,7 @@ UNINSTALL: ; PARAMS routine. A pointer to a ser_params structure is passed in ptr1. ; Must return an SER_ERR_xx code in a/x. -OPEN: +SER_OPEN: ; Check if the handshake setting is valid @@ -283,11 +283,11 @@ InvBaud: rts ;---------------------------------------------------------------------------- -; CLOSE: Close the port, disable interrupts and flush the buffer. Called +; SER_CLOSE: Close the port, disable interrupts and flush the buffer. Called ; without parameters. Must return an error code in a/x. ; -CLOSE: +SER_CLOSE: ; Stop interrupts, drop DTR @@ -305,12 +305,13 @@ CLOSE: rts ;---------------------------------------------------------------------------- -; GET: Will fetch a character from the receive buffer and store it into the +; SER_GET: Will fetch a character from the receive buffer and store it into the ; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is ; return. ; -GET: ldx SendFreeCnt ; Send data if necessary +SER_GET: + ldx SendFreeCnt ; Send data if necessary inx ; X == $FF? beq @L1 lda #$00 @@ -349,11 +350,11 @@ GET: ldx SendFreeCnt ; Send data if necessary rts ;---------------------------------------------------------------------------- -; PUT: Output character in A. +; SER_PUT: Output character in A. ; Must return an error code in a/x. ; -PUT: +SER_PUT: ; Try to send @@ -383,23 +384,25 @@ PUT: rts ;---------------------------------------------------------------------------- -; STATUS: Return the status in the variable pointed to by ptr1. +; SER_STATUS: Return the status in the variable pointed to by ptr1. ; Must return an error code in a/x. ; -STATUS: lda ACIA_STATUS +SER_STATUS: + lda ACIA_STATUS ldx #0 sta (ptr1,x) txa ; SER_ERR_OK rts ;---------------------------------------------------------------------------- -; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl +; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl ; specific data in ptr1, and the ioctl code in A. ; Must return an error code in a/x. ; -IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now +SER_IOCTL: + lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now ldx #>SER_ERR_INV_IOCTL rts @@ -407,7 +410,7 @@ IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now ; IRQ: Not used on the C128 ; -IRQ = $0000 +SER_IRQ = $0000 ;---------------------------------------------------------------------------- ; @@ -500,5 +503,3 @@ InitBuffers: stx RecvFreeCnt stx SendFreeCnt rts - - From 4304f115495a927756b0b33c73bc3ecd5d0f5559 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Mon, 26 Nov 2018 22:18:26 +0200 Subject: [PATCH 0943/2161] Added SER_ prefix. Whitespace cleanup --- libsrc/plus4/ser/plus4-stdser.s | 58 +++++++++++++++++---------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/libsrc/plus4/ser/plus4-stdser.s b/libsrc/plus4/ser/plus4-stdser.s index 6cacff327..bb44a4cf9 100644 --- a/libsrc/plus4/ser/plus4-stdser.s +++ b/libsrc/plus4/ser/plus4-stdser.s @@ -45,15 +45,15 @@ ; Jump table - .word INSTALL - .word UNINSTALL - .word OPEN - .word CLOSE - .word GET - .word PUT - .word STATUS - .word IOCTL - .word IRQ + .word SER_INSTALL + .word SER_UNINSTALL + .word SER_OPEN + .word SER_CLOSE + .word SER_GET + .word SER_PUT + .word SER_STATUS + .word SER_IOCTL + .word SER_IRQ ;---------------------------------------------------------------------------- ; I/O definitions @@ -130,25 +130,25 @@ ParityTable: .code ;---------------------------------------------------------------------------- -; INSTALL routine. Is called after the driver is loaded into memory. If +; SER_INSTALL routine. Is called after the driver is loaded into memory. If ; possible, check if the hardware is present. ; Must return an SER_ERR_xx code in a/x. ; ; Since we don't have to manage the IRQ vector on the Plus/4, this is actually ; the same as: ; -; UNINSTALL routine. Is called before the driver is removed from memory. +; SER_UNINSTALL routine. Is called before the driver is removed from memory. ; Must return an SER_ERR_xx code in a/x. ; ; and: ; -; CLOSE: Close the port, disable interrupts and flush the buffer. Called +; SER_CLOSE: Close the port, disable interrupts and flush the buffer. Called ; without parameters. Must return an error code in a/x. ; -INSTALL: -UNINSTALL: -CLOSE: +SER_INSTALL: +SER_UNINSTALL: +SER_CLOSE: ; Deactivate DTR and disable 6551 interrupts @@ -165,7 +165,7 @@ CLOSE: ; PARAMS routine. A pointer to a ser_params structure is passed in ptr1. ; Must return an SER_ERR_xx code in a/x. -OPEN: +SER_OPEN: ; Check if the handshake setting is valid @@ -244,12 +244,13 @@ InvBaud: rts ;---------------------------------------------------------------------------- -; GET: Will fetch a character from the receive buffer and store it into the +; SER_GET: Will fetch a character from the receive buffer and store it into the ; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is ; return. ; -GET: ldx SendFreeCnt ; Send data if necessary +SER_GET: + ldx SendFreeCnt ; Send data if necessary inx ; X == $FF? beq @L1 lda #$00 @@ -288,11 +289,11 @@ GET: ldx SendFreeCnt ; Send data if necessary rts ;---------------------------------------------------------------------------- -; PUT: Output character in A. +; SER_PUT: Output character in A. ; Must return an error code in a/x. ; -PUT: +SER_PUT: ; Try to send @@ -322,34 +323,37 @@ PUT: rts ;---------------------------------------------------------------------------- -; STATUS: Return the status in the variable pointed to by ptr1. +; SER_STATUS: Return the status in the variable pointed to by ptr1. ; Must return an error code in a/x. ; -STATUS: lda ACIA_STATUS +SER_STATUS: + lda ACIA_STATUS ldx #0 sta (ptr1,x) txa ; SER_ERR_OK rts ;---------------------------------------------------------------------------- -; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl +; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl ; specific data in ptr1, and the ioctl code in A. ; Must return an error code in a/x. ; -IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now +SER_IOCTL: + lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now ldx #>SER_ERR_INV_IOCTL rts ; Run into IRQ instead ;---------------------------------------------------------------------------- -; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All +; SER_IRQ: Called from the builtin runtime IRQ handler as a subroutine. All ; registers are already save, no parameters are passed, but the carry flag ; is clear on entry. The routine must return with carry set if the interrupt ; was handled, otherwise with carry clear. ; -IRQ: lda ACIA_STATUS ; Check ACIA status for receive interrupt +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 @@ -405,5 +409,3 @@ IRQ: lda ACIA_STATUS ; Check ACIA status for receive interrupt jmp @L0 .endproc - - From b9054ec9a7c38c09d8241835f4ce5356e4178612 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Mon, 26 Nov 2018 22:23:11 +0200 Subject: [PATCH 0944/2161] Added SER_ prefix. Whitespace cleanup --- libsrc/cbm610/ser/cbm610-std.s | 57 ++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/libsrc/cbm610/ser/cbm610-std.s b/libsrc/cbm610/ser/cbm610-std.s index 1b2d38aa5..7cdb285bd 100644 --- a/libsrc/cbm610/ser/cbm610-std.s +++ b/libsrc/cbm610/ser/cbm610-std.s @@ -46,15 +46,15 @@ ; Jump table - .word INSTALL - .word UNINSTALL - .word OPEN - .word CLOSE - .word GET - .word PUT - .word STATUS - .word IOCTL - .word IRQ + .word SER_INSTALL + .word SER_UNINSTALL + .word SER_OPEN + .word SER_CLOSE + .word SER_GET + .word SER_PUT + .word SER_STATUS + .word SER_IOCTL + .word SER_IRQ ;---------------------------------------------------------------------------- ; @@ -122,25 +122,25 @@ ParityTable: .code ;---------------------------------------------------------------------------- -; INSTALL routine. Is called after the driver is loaded into memory. If +; SER_INSTALL routine. Is called after the driver is loaded into memory. If ; possible, check if the hardware is present. ; Must return an SER_ERR_xx code in a/x. ; ; Since we don't have to manage the IRQ vector on the Plus/4, this is actually ; the same as: ; -; UNINSTALL routine. Is called before the driver is removed from memory. +; SER_UNINSTALL routine. Is called before the driver is removed from memory. ; Must return an SER_ERR_xx code in a/x. ; ; and: ; -; CLOSE: Close the port, disable interrupts and flush the buffer. Called +; SER_CLOSE: Close the port, disable interrupts and flush the buffer. Called ; without parameters. Must return an error code in a/x. ; -INSTALL: -UNINSTALL: -CLOSE: +SER_INSTALL: +SER_UNINSTALL: +SER_CLOSE: ; Deactivate DTR and disable 6551 interrupts @@ -157,7 +157,7 @@ CLOSE: ; PARAMS routine. A pointer to a ser_params structure is passed in ptr1. ; Must return an SER_ERR_xx code in a/x. -OPEN: +SER_OPEN: ; Check if the handshake setting is valid @@ -237,12 +237,13 @@ InvBaud: rts ;---------------------------------------------------------------------------- -; GET: Will fetch a character from the receive buffer and store it into the +; SER_GET: Will fetch a character from the receive buffer and store it into the ; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is ; return. ; -GET: ldx SendFreeCnt ; Send data if necessary +SER_GET: + ldx SendFreeCnt ; Send data if necessary inx ; X == $FF? beq @L1 lda #$00 @@ -281,11 +282,11 @@ GET: ldx SendFreeCnt ; Send data if necessary rts ;---------------------------------------------------------------------------- -; PUT: Output character in A. +; SER_PUT: Output character in A. ; Must return an error code in a/x. ; -PUT: +SER_PUT: ; Try to send @@ -315,11 +316,12 @@ PUT: rts ;---------------------------------------------------------------------------- -; STATUS: Return the status in the variable pointed to by ptr1. +; SER_STATUS: Return the status in the variable pointed to by ptr1. ; Must return an error code in a/x. ; -STATUS: lda #$0F +SER_STATUS: + lda #$0F sta IndReg ldy #ACIA::STATUS lda (acia),y @@ -331,23 +333,25 @@ STATUS: lda #$0F rts ;---------------------------------------------------------------------------- -; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl +; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl ; specific data in ptr1, and the ioctl code in A. ; Must return an error code in a/x. ; -IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now +SER_IOCTL: + lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now ldx #>SER_ERR_INV_IOCTL rts ;---------------------------------------------------------------------------- -; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All +; SER_IRQ: Called from the builtin runtime IRQ handler as a subroutine. All ; registers are already save, no parameters are passed, but the carry flag ; is clear on entry. The routine must return with carry set if the interrupt ; was handled, otherwise with carry clear. ; -IRQ: lda #$0F +SER_IRQ: + lda #$0F sta IndReg ; Switch to the system bank ldy #ACIA::STATUS lda (acia),y ; Check ACIA status for receive interrupt @@ -436,4 +440,3 @@ write: pha lda ExecReg sta IndReg rts - From b269b3f5b24aec01d5bc222e401198b20cc32ac7 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Mon, 26 Nov 2018 22:28:40 +0200 Subject: [PATCH 0945/2161] Added SER_ prefix. Whitespace cleanup --- libsrc/lynx/ser/lynx-comlynx.s | 57 +++++++++++++++++----------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/libsrc/lynx/ser/lynx-comlynx.s b/libsrc/lynx/ser/lynx-comlynx.s index 1fd24ad94..ded862eaa 100644 --- a/libsrc/lynx/ser/lynx-comlynx.s +++ b/libsrc/lynx/ser/lynx-comlynx.s @@ -25,15 +25,15 @@ .addr $0000 ; Jump table - .addr INSTALL - .addr UNINSTALL - .addr OPEN - .addr CLOSE - .addr GET - .addr PUT - .addr STATUS - .addr IOCTL - .addr IRQ + .addr SER_INSTALL + .addr SER_UNINSTALL + .addr SER_OPEN + .addr SER_CLOSE + .addr SER_GET + .addr SER_PUT + .addr SER_STATUS + .addr SER_IOCTL + .addr SER_IRQ ;---------------------------------------------------------------------------- ; Global variables @@ -54,25 +54,25 @@ TxDone: .res 1 .code ;---------------------------------------------------------------------------- -; INSTALL: Is called after the driver is loaded into memory. +; SER_INSTALL: Is called after the driver is loaded into memory. ; ; Must return an SER_ERR_xx code in a/x. -INSTALL: +SER_INSTALL: ; Set up IRQ vector ? ;---------------------------------------------------------------------------- -; UNINSTALL: Is called before the driver is removed from memory. +; SER_UNINSTALL: Is called before the driver is removed from memory. ; No return code required (the driver is removed from memory on return). ; -UNINSTALL: +SER_UNINSTALL: ;---------------------------------------------------------------------------- -; CLOSE: Close the port and disable interrupts. Called without parameters. +; SER_CLOSE: Close the port and disable interrupts. Called without parameters. ; Must return an SER_ERR_xx code in a/x. -CLOSE: +SER_CLOSE: ; Disable interrupts ; Done, return an error code lda #<SER_ERR_OK @@ -80,7 +80,7 @@ CLOSE: rts ;---------------------------------------------------------------------------- -; OPEN: A pointer to a ser_params structure is passed in ptr1. +; SER_OPEN: A pointer to a ser_params structure is passed in ptr1. ; ; The Lynx has only two correct serial data formats: ; 8 bits, parity mark, 1 stop bit @@ -101,7 +101,7 @@ CLOSE: ; ; Must return an SER_ERR_xx code in a/x. -OPEN: +SER_OPEN: stz RxPtrIn stz RxPtrOut stz TxPtrIn @@ -247,11 +247,11 @@ invparameter: rts ;---------------------------------------------------------------------------- -; GET: Will fetch a character from the receive buffer and store it into the +; SER_GET: Will fetch a character from the receive buffer and store it into the ; variable pointed to by ptr1. If no data is available, SER_ERR_NO_DATA is ; returned. -GET: +SER_GET: lda RxPtrIn cmp RxPtrOut bne GetByte @@ -260,7 +260,7 @@ GET: rts GetByte: ldy RxPtrOut - lda RxBuffer,y + lda RxBuffer,y inc RxPtrOut ldx #$00 sta (ptr1,x) @@ -268,10 +268,10 @@ GetByte: rts ;---------------------------------------------------------------------------- -; PUT: Output character in A. +; SER_PUT: Output character in A. ; Must return an SER_ERR_xx code in a/x. -PUT: +SER_PUT: tax lda TxPtrIn ina @@ -301,10 +301,10 @@ PutByte: rts ;---------------------------------------------------------------------------- -; STATUS: Return the status in the variable pointed to by ptr1. +; SER_STATUS: Return the status in the variable pointed to by ptr1. ; Must return an SER_ERR_xx code in a/x. -STATUS: +SER_STATUS: ldy SerialStat ldx #$00 sta (ptr1,x) @@ -312,17 +312,17 @@ STATUS: rts ;---------------------------------------------------------------------------- -; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl +; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl ; specific data in ptr1, and the ioctl code in A. ; Must return an SER_ERR_xx code in a/x. -IOCTL: +SER_IOCTL: lda #<SER_ERR_INV_IOCTL ldx #>SER_ERR_INV_IOCTL rts ;---------------------------------------------------------------------------- -; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All +; SER_IRQ: Called from the builtin runtime IRQ handler as a subroutine. All ; registers are already saved, no parameters are passed, but the carry flag ; is clear on entry. The routine must return with carry set if the interrupt ; was handled, otherwise with carry clear. @@ -330,7 +330,7 @@ IOCTL: ; Both the Tx and Rx interrupts are level sensitive instead of edge sensitive. ; Due to this bug you have to disable the interrupt before clearing it. -IRQ: +SER_IRQ: lda INTSET ; Poll all pending interrupts and #SERIAL_INTERRUPT bne @L0 @@ -411,4 +411,3 @@ IRQ: @IRQexit: clc rts - From b6529225e962e4ab4474ad14aef7fd9b099feac2 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Mon, 26 Nov 2018 22:32:49 +0200 Subject: [PATCH 0946/2161] Added SER_ prefix. Whitespace cleanup --- libsrc/cbm510/ser/cbm510-std.s | 57 ++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/libsrc/cbm510/ser/cbm510-std.s b/libsrc/cbm510/ser/cbm510-std.s index 7629892e0..64f613cd5 100644 --- a/libsrc/cbm510/ser/cbm510-std.s +++ b/libsrc/cbm510/ser/cbm510-std.s @@ -46,15 +46,15 @@ ; Jump table - .word INSTALL - .word UNINSTALL - .word OPEN - .word CLOSE - .word GET - .word PUT - .word STATUS - .word IOCTL - .word IRQ + .word SER_INSTALL + .word SER_UNINSTALL + .word SER_OPEN + .word SER_CLOSE + .word SER_GET + .word SER_PUT + .word SER_STATUS + .word SER_IOCTL + .word SER_IRQ ;---------------------------------------------------------------------------- ; @@ -122,24 +122,24 @@ ParityTable: .code ;---------------------------------------------------------------------------- -; INSTALL routine. Is called after the driver is loaded into memory. If +; SER_INSTALL routine. Is called after the driver is loaded into memory. If ; possible, check if the hardware is present. ; Must return an SER_ERR_xx code in a/x. ; ; Since we don't have to manage the IRQ vector on the Plus/4, this is actually ; the same as: ; -; UNINSTALL routine. Is called before the driver is removed from memory. +; SER_UNINSTALL routine. Is called before the driver is removed from memory. ; Must return an SER_ERR_xx code in a/x. ; and: ; -; CLOSE: Close the port, disable interrupts and flush the buffer. Called +; SER_CLOSE: Close the port, disable interrupts and flush the buffer. Called ; without parameters. Must return an error code in a/x. ; -INSTALL: -UNINSTALL: -CLOSE: +SER_INSTALL: +SER_UNINSTALL: +SER_CLOSE: ; Deactivate DTR and disable 6551 interrupts @@ -156,7 +156,7 @@ CLOSE: ; PARAMS routine. A pointer to a ser_params structure is passed in ptr1. ; Must return an SER_ERR_xx code in a/x. -OPEN: +SER_OPEN: ; Check if the handshake setting is valid @@ -236,12 +236,13 @@ InvBaud: rts ;---------------------------------------------------------------------------- -; GET: Will fetch a character from the receive buffer and store it into the +; SER_GET: Will fetch a character from the receive buffer and store it into the ; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is ; return. ; -GET: ldx SendFreeCnt ; Send data if necessary +SER_GET: + ldx SendFreeCnt ; Send data if necessary inx ; X == $FF? beq @L1 lda #$00 @@ -280,11 +281,11 @@ GET: ldx SendFreeCnt ; Send data if necessary rts ;---------------------------------------------------------------------------- -; PUT: Output character in A. +; SER_PUT: Output character in A. ; Must return an error code in a/x. ; -PUT: +SER_PUT: ; Try to send @@ -314,11 +315,12 @@ PUT: rts ;---------------------------------------------------------------------------- -; STATUS: Return the status in the variable pointed to by ptr1. +; SER_STATUS: Return the status in the variable pointed to by ptr1. ; Must return an error code in a/x. ; -STATUS: lda #$0F +SER_STATUS: + lda #$0F sta IndReg ldy #ACIA::STATUS lda (acia),y @@ -330,23 +332,25 @@ STATUS: lda #$0F rts ;---------------------------------------------------------------------------- -; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl +; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl ; specific data in ptr1, and the ioctl code in A. ; Must return an error code in a/x. ; -IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now +SER_IOCTL: + lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now ldx #>SER_ERR_INV_IOCTL rts ;---------------------------------------------------------------------------- -; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All +; SER_IRQ: Called from the builtin runtime IRQ handler as a subroutine. All ; registers are already save, no parameters are passed, but the carry flag ; is clear on entry. The routine must return with carry set if the interrupt ; was handled, otherwise with carry clear. ; -IRQ: lda #$0F +SER_IRQ: + lda #$0F sta IndReg ; Switch to the system bank ldy #ACIA::STATUS lda (acia),y ; Check ACIA status for receive interrupt @@ -435,4 +439,3 @@ write: pha lda ExecReg sta IndReg rts - From b7a3abad62a6d57f46302b5bc89e3f6c978ee7d0 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Mon, 26 Nov 2018 22:36:22 +0200 Subject: [PATCH 0947/2161] Added SER_ prefix. Whitespace cleanup --- asminc/ser-kernel.inc | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/asminc/ser-kernel.inc b/asminc/ser-kernel.inc index 3ddb7f300..546587515 100644 --- a/asminc/ser-kernel.inc +++ b/asminc/ser-kernel.inc @@ -41,15 +41,15 @@ VERSION .byte 1 ; Interface version LIBREF .addr ; Library reference JUMPTAB .struct - INSTALL .addr ; INSTALL routine - UNINSTALL .addr ; UNINSTALL routine - OPEN .addr ; OPEN routine - CLOSE .addr ; CLOSE routine - GET .addr ; GET routine - PUT .addr ; PUT routine - STATUS .addr ; STATUS routine - IOCTL .addr ; IOCTL routine - IRQ .addr ; IRQ routine + SER_INSTALL .addr ; SER_INSTALL routine + SER_UNINSTALL .addr ; SER_UNINSTALL routine + SER_OPEN .addr ; SER_OPEN routine + SER_CLOSE .addr ; SER_CLOSE routine + SER_GET .addr ; SER_GET routine + SER_PUT .addr ; SER_PUT routine + SER_STATUS .addr ; SER_STATUS routine + SER_IOCTL .addr ; SER_IOCTL routine + SER_IRQ .addr ; SER_IRQ routine .endstruct .endstruct @@ -160,4 +160,3 @@ SER_STATUS_DSR = $40 ; NOT data set ready .global _ser_ioctl .global _ser_clear_ptr - From 180bb0823a5c92ae1db2cde9d30cf818a7e2a6be Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 3 Dec 2018 12:52:00 +0100 Subject: [PATCH 0948/2161] Fixed typo. --- doc/apple2.sgml | 2 +- doc/apple2enh.sgml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index f61a8a68e..ac5059902 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -492,7 +492,7 @@ files show up in a directory as <tt/<NO DATE>/. There's no common interface to set realtime clocks so if a realtme clock <bf/IS/ present there's just nothing to do. However, if there's <bf/NO/ realtime clock present, -the user might very well be interest to "manually" set the RAM location in order to +the user might very well be interested to "manually" set the RAM location in order to have timestamps. But he surely doesn't want to manually set the RAM location over and over again. Rather he wants to set it just once after booting ProDOS 8. diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 649c6ef9f..d8d24ea32 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -493,7 +493,7 @@ files show up in a directory as <tt/<NO DATE>/. There's no common interface to set realtime clocks so if a realtme clock <bf/IS/ present there's just nothing to do. However, if there's <bf/NO/ realtime clock present, -the user might very well be interest to "manually" set the RAM location in order to +the user might very well be interested to "manually" set the RAM location in order to have timestamps. But he surely doesn't want to manually set the RAM location over and over again. Rather he wants to set it just once after booting ProDOS 8. From d707ef4c72bf236a5c2da4915999fb1a38c3afe8 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 10 Dec 2018 21:48:09 +0100 Subject: [PATCH 0949/2161] Now tgi_clear() works --- asminc/telestrat.inc | 1 + libsrc/telestrat/tgi/telestrat-228-200-3.s | 2 +- libsrc/telestrat/tgi/telestrat-240-200-2.s | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index df607e375..956f4b8ac 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -195,6 +195,7 @@ XDECAL = $18 XTEXT = $19 XHIRES = $1A +XEFFHI = $1B ; Clear hires screen XFILLM = $1C XMINMA = $1F XVARS = $24 ; Only in TELEMON 3.x, in TELEMON 2.4, it's XNOMFI ($24) diff --git a/libsrc/telestrat/tgi/telestrat-228-200-3.s b/libsrc/telestrat/tgi/telestrat-228-200-3.s index ce501f0bf..228bdce99 100644 --- a/libsrc/telestrat/tgi/telestrat-228-200-3.s +++ b/libsrc/telestrat/tgi/telestrat-228-200-3.s @@ -170,7 +170,7 @@ CONTROL: ; CLEAR: - ; not done yet + BRK_TELEMON(XEFFHI) rts ; ------------------------------------------------------------------------ diff --git a/libsrc/telestrat/tgi/telestrat-240-200-2.s b/libsrc/telestrat/tgi/telestrat-240-200-2.s index 3ee918c4f..9bffebb0c 100644 --- a/libsrc/telestrat/tgi/telestrat-240-200-2.s +++ b/libsrc/telestrat/tgi/telestrat-240-200-2.s @@ -169,7 +169,7 @@ CONTROL: ; CLEAR: - ; not done yet + BRK_TELEMON(XEFFHI) rts ; ------------------------------------------------------------------------ From 80a43d732dc9551ad84343ea9644d8fab7ec0bd9 Mon Sep 17 00:00:00 2001 From: Marc Rintsch <github.com@rintsch.de> Date: Thu, 20 Dec 2018 13:07:25 +0100 Subject: [PATCH 0950/2161] Added missing external declaration of c64_65816_emd. --- include/c64.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/c64.h b/include/c64.h index eb10600d6..b1cd2e2c4 100644 --- a/include/c64.h +++ b/include/c64.h @@ -137,6 +137,7 @@ /* The addresses of the static drivers */ +extern void c64_65816_emd[]; extern void c64_c256k_emd[]; extern void c64_dqbb_emd[]; extern void c64_georam_emd[]; From 19ca1f6b48ba67bf3b4acd1c7efdb15e6ca60240 Mon Sep 17 00:00:00 2001 From: Paul Gardner-Stephen <paul@servalproject.org> Date: Thu, 27 Dec 2018 10:50:25 +1030 Subject: [PATCH 0951/2161] add support for detecting 45GS02 --- include/6502.h | 1 + libsrc/common/getcpu.s | 99 +++++++++++++++++++++++++++++++++++------- 2 files changed, 84 insertions(+), 16 deletions(-) diff --git a/include/6502.h b/include/6502.h index 642a608a8..4a27b706e 100644 --- a/include/6502.h +++ b/include/6502.h @@ -55,6 +55,7 @@ typedef unsigned size_t; #define CPU_65CE02 5 #define CPU_HUC6280 6 #define CPU_2A0x 7 +#define CPU_45GS02 8 unsigned char getcpu (void); /* Detect the CPU the program is running on */ diff --git a/libsrc/common/getcpu.s b/libsrc/common/getcpu.s index 169c56bbd..024a60608 100644 --- a/libsrc/common/getcpu.s +++ b/libsrc/common/getcpu.s @@ -17,6 +17,7 @@ ; - carry set and 5 in A for a 65CE02 ; - carry set and 6 in A for a HuC6280 ; - carry clear and 7 in A for a 2a03/2a07 +; - carry set and 8 in A for a 45GS02 ; ; This function uses a $1A opcode which is a INA on the 816 and ignored ; (interpreted as a NOP) on a NMOS 6502. There are several CMOS versions @@ -26,52 +27,119 @@ .p816 ; Enable 65816 instructions _getcpu: + lda #0 inc a ; .byte $1A ; nop on nmos, inc on every cmos cmp #1 - bcc @L8 + bcc @IsNMOS ; This is at least a 65C02, check for a 65CE02/4510 .byte $42,$EA ; neg on 65CE02/4510, nop #$EA on 65C02, wdm $EA on 65816 cmp #1 - beq @L6 + beq @HasINCA ; This is at least a 65CE02, check for 4510 lda #5 ; CPU_65CE02 constant + ldx #0 ; to make sure MAP doesn't do anything, the upper nybl of X and Z must be clear .byte $5C ; map on 4510, aug on 65CE02 (acts like 4 byte nop) lda #3 ; CPU_4510 constant nop - bne @L9 + cmp #5 + beq @LoadXAndReturn + +; It is either a 4510 (C65) or a 45GS02 (MEGA65) + + ; 45GS02 supports 32-bit ZP indirect, so use that to check CPU type + ; without requiring a functioning MEGA65 hypervisor. + ; We setup a read of $200FF, then store a different value in $00FF + ; and then re-read $200FF to see if it is unchanged. + + ; Save the 32-bit ZP pointer and data byte + ldx #4 +@L10: lda $fb,x + sta @GetCPUTemp,x + dex + bpl @L10 + + ; Setup 32-bit pointer to $000200FF + lda #$ff + sta $fb + lda #$00 + sta $fc + sta $fe + lda #$02 + sta $fd + + ; Prefixing LDA ($nn),Z with a NOP uses 32-bit ZP pointer on 45GS02, + ; but normal 16-bit ZP pointer on 4510 + ; (We assume Z=$00, which will be the normal case) + nop ; prefix to tell next instruction to be 32-bit ZP + .byte $b2,$fb ; LDA ($nn),Z + eor #$ff ; change the value + sta $ff ; store in $FF + ; now try again to load it: If the same, then 45GS02, as $200FF is unchanged + nop ; prefix to tell next instruction to be 32-bit ZP + .byte $b2,$fb ; LDA ($nn),Z + cmp $ff ; does the loaded value match what is in $FF? + beq @Is4510 ; matches, so must be a 4510 = C65 + bne @Is45GS02 ; $200FF and $FF have different values, so must be a MEGA65 45GS02 +@Is4510: + jsr @RestoreGetCPUTemp + lda #3 ; CPU_4510 constant + ldx #0 ; load high byte of word + rts + +@Is45GS02: + jsr @RestoreGetCPUTemp + lda #8 ; CPU_45GS02 constant + ldx #0 ; load high byte of word + rts + +@RestoreGetCPUTemp: + ; Save the 32-bit ZP pointer and data byte + ldx #4 +@L11: lda @GetCPUTemp,x + sta $fb,x + dex + bpl @L11 + rts + + ; Temporary storage for the ZP locations we modify above +@GetCPUTemp: .byte 0,0,0,0,0 + + ; 6502 type of cpu, check for a 2a03/2a07 -@L8: +@IsNMOS: sed ; set decimal mode, no decimal mode on the 2a03/2a07 lda #9 clc adc #1 ; $01+$09 = $10 on 6502, $01+$09 = $0A on 2a03/2a07 cld cmp #$0a - beq @L5 + beq @Is2a03 lda #0 ; CPU_6502 constant - beq @L9 -@L5: + beq @LoadXAndReturn +@Is2a03: lda #7 ; CPU_2A0x constant - bne @L9 + bne @LoadXAndReturn ; 65C02 cpu type, check for HuC6280 -@L4: ldx #6 ; CPU_HUC6280 constant +@CheckHuC6280: + ldx #6 ; CPU_HUC6280 constant .byte $22,$EA ; sax nop on HuC6280 (A=$06, X=$01), nop #$EA on 65C02 (A=$01, X=$06) - bne @L9 + bne @LoadXAndReturn ; Check for 65816/65802 -@L6: xba ; .byte $EB, put $01 in B accu (nop on 65C02/65SC02) +@HasINCA: + xba ; .byte $EB, put $01 in B accu (nop on 65C02/65SC02) dec a ; .byte $3A, A=$00 xba ; .byte $EB, A=$01 if 65816/65802 and A=$00 if 65C02/65SC02 inc a ; .byte $1A, A=$02 if 65816/65802 and A=$01 if 65C02/65SC02 cmp #2 - beq @L9 + beq @LoadXAndReturn ; check for 65SC02 @@ -82,9 +150,8 @@ _getcpu: ldx $F7 sty $F7 cpx #$00 - bne @L4 + bne @CheckHuC6280 lda #4 ; CPU_65SC02 constant - -@L9: ldx #0 ; Load high byte of word +@LoadXAndReturn: + ldx #0 rts - From 837b9b3c2cfc35c88ee2c2f567669d5738dd1d00 Mon Sep 17 00:00:00 2001 From: Paul Gardner-Stephen <paul@servalproject.org> Date: Sat, 29 Dec 2018 00:07:29 +1030 Subject: [PATCH 0952/2161] use pre-existing ZP storage. Make 32-bit pointer value loading more self-evident --- libsrc/common/getcpu.s | 55 ++++++++++++------------------------------ 1 file changed, 16 insertions(+), 39 deletions(-) diff --git a/libsrc/common/getcpu.s b/libsrc/common/getcpu.s index 024a60608..36da39e7a 100644 --- a/libsrc/common/getcpu.s +++ b/libsrc/common/getcpu.s @@ -3,7 +3,7 @@ ; ; unsigned char getcpu (void); ; - + .include "zeropage.inc" .export _getcpu ; --------------------------------------------------------------------------- @@ -53,64 +53,41 @@ _getcpu: ; 45GS02 supports 32-bit ZP indirect, so use that to check CPU type ; without requiring a functioning MEGA65 hypervisor. - ; We setup a read of $200FF, then store a different value in $00FF - ; and then re-read $200FF to see if it is unchanged. + ; We setup a read of $200xx, then store a different value in $xx + ; and then re-read $200xx to see if it is unchanged. - ; Save the 32-bit ZP pointer and data byte - ldx #4 -@L10: lda $fb,x - sta @GetCPUTemp,x - dex - bpl @L10 - - ; Setup 32-bit pointer to $000200FF - lda #$ff - sta $fb - lda #$00 - sta $fc - sta $fe - lda #$02 - sta $fd + ; Setup 32-bit pointer to $00020000+tmp1 + lda #<$020000+tmp1 + sta regsave + lda #>$020000+tmp1 + sta regsave+1 + sta regsave+3 ; also write to upper byte of pointer to save an extra LDA #$00 + lda #^$020000+tmp1 + sta regsave+2 ; Prefixing LDA ($nn),Z with a NOP uses 32-bit ZP pointer on 45GS02, ; but normal 16-bit ZP pointer on 4510 ; (We assume Z=$00, which will be the normal case) nop ; prefix to tell next instruction to be 32-bit ZP - .byte $b2,$fb ; LDA ($nn),Z + .byte $b2,regsave ; LDA (regsave),Z eor #$ff ; change the value - sta $ff ; store in $FF - ; now try again to load it: If the same, then 45GS02, as $200FF is unchanged + sta tmp1 ; store in $xx + ; now try again to load it: If the same, then 45GS02, as $200xx is unchanged nop ; prefix to tell next instruction to be 32-bit ZP - .byte $b2,$fb ; LDA ($nn),Z - cmp $ff ; does the loaded value match what is in $FF? + .byte $b2,regsave ; LDA (regsave),Z + cmp tmp1 ; does the loaded value match what is in $FF? beq @Is4510 ; matches, so must be a 4510 = C65 bne @Is45GS02 ; $200FF and $FF have different values, so must be a MEGA65 45GS02 @Is4510: - jsr @RestoreGetCPUTemp lda #3 ; CPU_4510 constant ldx #0 ; load high byte of word rts @Is45GS02: - jsr @RestoreGetCPUTemp lda #8 ; CPU_45GS02 constant ldx #0 ; load high byte of word rts -@RestoreGetCPUTemp: - ; Save the 32-bit ZP pointer and data byte - ldx #4 -@L11: lda @GetCPUTemp,x - sta $fb,x - dex - bpl @L11 - rts - - ; Temporary storage for the ZP locations we modify above -@GetCPUTemp: .byte 0,0,0,0,0 - - - ; 6502 type of cpu, check for a 2a03/2a07 @IsNMOS: sed ; set decimal mode, no decimal mode on the 2a03/2a07 From 576d64da3845b67b09a6c4a70a69ab93a684d810 Mon Sep 17 00:00:00 2001 From: Paul Gardner-Stephen <paul@servalproject.org> Date: Sat, 29 Dec 2018 00:08:54 +1030 Subject: [PATCH 0953/2161] remove redundant line --- libsrc/common/getcpu.s | 1 - 1 file changed, 1 deletion(-) diff --git a/libsrc/common/getcpu.s b/libsrc/common/getcpu.s index 36da39e7a..b13daf23c 100644 --- a/libsrc/common/getcpu.s +++ b/libsrc/common/getcpu.s @@ -76,7 +76,6 @@ _getcpu: nop ; prefix to tell next instruction to be 32-bit ZP .byte $b2,regsave ; LDA (regsave),Z cmp tmp1 ; does the loaded value match what is in $FF? - beq @Is4510 ; matches, so must be a 4510 = C65 bne @Is45GS02 ; $200FF and $FF have different values, so must be a MEGA65 45GS02 @Is4510: lda #3 ; CPU_4510 constant From 1b46dfe820912702ce7db2b944dcd69b1e257b9f Mon Sep 17 00:00:00 2001 From: Paul Gardner-Stephen <paul@servalproject.org> Date: Sat, 29 Dec 2018 22:19:51 +1030 Subject: [PATCH 0954/2161] change reference to $0200FF to $0200xx --- libsrc/common/getcpu.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/common/getcpu.s b/libsrc/common/getcpu.s index b13daf23c..51ccd5a4a 100644 --- a/libsrc/common/getcpu.s +++ b/libsrc/common/getcpu.s @@ -75,8 +75,8 @@ _getcpu: ; now try again to load it: If the same, then 45GS02, as $200xx is unchanged nop ; prefix to tell next instruction to be 32-bit ZP .byte $b2,regsave ; LDA (regsave),Z - cmp tmp1 ; does the loaded value match what is in $FF? - bne @Is45GS02 ; $200FF and $FF have different values, so must be a MEGA65 45GS02 + cmp tmp1 ; does the loaded value match what is in $xx? + bne @Is45GS02 ; $200xx and $xx have different values, so must be a MEGA65 45GS02 @Is4510: lda #3 ; CPU_4510 constant ldx #0 ; load high byte of word From 2f6f468aad0606b0cd89f447ef7d853d119e4473 Mon Sep 17 00:00:00 2001 From: Scott Hutter <scott.hutter@gmail.com> Date: Tue, 18 Dec 2018 11:09:06 -0600 Subject: [PATCH 0955/2161] Added SetNewMode() to geoslib - #814 --- include/geos/ggraph.h | 5 ++++- libsrc/geos-cbm/setnewmode.s | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 libsrc/geos-cbm/setnewmode.s diff --git a/include/geos/ggraph.h b/include/geos/ggraph.h index 35e02c198..642bd85ce 100644 --- a/include/geos/ggraph.h +++ b/include/geos/ggraph.h @@ -45,6 +45,10 @@ void __fastcall__ BitOtherClip(void *proc1, void *proc2, char skipl, void __fastcall__ GraphicsString(char *myGfxString); +#ifdef __GEOS_CBM__ +void __fastcall__ SetNewMode(void); +#endif + /* VIC colour constants */ #define BLACK 0 #define WHITE 1 @@ -172,5 +176,4 @@ typedef void graphicStr; /* ESC_PUTSTRING can't be implemented - it needs text, not pointer to it #define ESC_PUTSTRING(x,y,text) (char)6, (unsigned)(x), (char)(y), (text), (char)NULL */ - #endif diff --git a/libsrc/geos-cbm/setnewmode.s b/libsrc/geos-cbm/setnewmode.s new file mode 100644 index 000000000..58098a299 --- /dev/null +++ b/libsrc/geos-cbm/setnewmode.s @@ -0,0 +1,18 @@ +; +; Scott Hutter +; +; 18.12.18 + +; void SetNewMode(void); + + .export _SetNewMode + + .include "jumptab.inc" + .include "geossym.inc" + +_SetNewMode: + lda graphMode + eor #$80 + sta graphMode + jsr SetNewMode + rts From 0012b6d81197fafed73c1bb1f626d88f863b7ae9 Mon Sep 17 00:00:00 2001 From: Scott Hutter <scott.hutter@gmail.com> Date: Tue, 18 Dec 2018 11:15:45 -0600 Subject: [PATCH 0956/2161] SetNewMode() documentation = issue #814 --- doc/geos.sgml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/geos.sgml b/doc/geos.sgml index cb849c389..ae781dfae 100644 --- a/doc/geos.sgml +++ b/doc/geos.sgml @@ -332,6 +332,14 @@ The <tt/parameter/ is the field width in pixels (range 1-31) and the mode bits. the string can be filled with zeroes (the string is always 5 characters long) or not and left or right justified to the given pixel. See <tt/ggraph.h/ for predefined values for <tt/parameter/. +<sect3>SetNewMode +<p> +<tt/void SetNewMode (void)/ +<p> +This function is intended for use by GEOS 128 only, and will exhibit undefined behavior on the +C64. It will toggle between the 40 column screen mode and the 80 column screen mode. Many C128 GEOS +programs implement a "Switch 40/80" submenu option under the geos menu. + <sect2>Font Handling <sect3>GetCharWidth From 9160b8ddc2a233347cdf23f70c43314a9f3fb6fc Mon Sep 17 00:00:00 2001 From: Scott Hutter <scott.hutter@gmail.com> Date: Tue, 18 Dec 2018 16:16:22 -0600 Subject: [PATCH 0957/2161] Issue 814 --- libsrc/geos-cbm/setnewmode.s | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libsrc/geos-cbm/setnewmode.s b/libsrc/geos-cbm/setnewmode.s index 58098a299..1d63cf78e 100644 --- a/libsrc/geos-cbm/setnewmode.s +++ b/libsrc/geos-cbm/setnewmode.s @@ -11,8 +11,8 @@ .include "geossym.inc" _SetNewMode: - lda graphMode - eor #$80 - sta graphMode - jsr SetNewMode - rts + lda graphMode + eor #$80 + sta graphMode + jmp SetNewMode + From a6725edb15902ef2f1228294361170ae330c7861 Mon Sep 17 00:00:00 2001 From: Scott Hutter <scott.hutter@gmail.com> Date: Sun, 30 Dec 2018 05:23:17 -0600 Subject: [PATCH 0958/2161] moved to better folder location --- libsrc/geos-cbm/{ => graph}/setnewmode.s | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename libsrc/geos-cbm/{ => graph}/setnewmode.s (100%) diff --git a/libsrc/geos-cbm/setnewmode.s b/libsrc/geos-cbm/graph/setnewmode.s similarity index 100% rename from libsrc/geos-cbm/setnewmode.s rename to libsrc/geos-cbm/graph/setnewmode.s From 74f622d9c664dcd00aaf7cf67f22265cca5cc5b7 Mon Sep 17 00:00:00 2001 From: Scott Hutter <scott.hutter@gmail.com> Date: Sun, 30 Dec 2018 05:30:46 -0600 Subject: [PATCH 0959/2161] corrected text formatting --- doc/geos.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/geos.sgml b/doc/geos.sgml index ae781dfae..891c8ed18 100644 --- a/doc/geos.sgml +++ b/doc/geos.sgml @@ -338,7 +338,7 @@ justified to the given pixel. See <tt/ggraph.h/ for predefined values for <tt/pa <p> This function is intended for use by GEOS 128 only, and will exhibit undefined behavior on the C64. It will toggle between the 40 column screen mode and the 80 column screen mode. Many C128 GEOS -programs implement a "Switch 40/80" submenu option under the geos menu. +programs implement a "Switch 40/80" submenu option under the <tt/geos/ menu. <sect2>Font Handling From 94e623165dc3fb5b4ca01a8c3e2ca3d3d8e6491f Mon Sep 17 00:00:00 2001 From: Scott Hutter <scott.hutter@gmail.com> Date: Sun, 30 Dec 2018 11:33:45 -0600 Subject: [PATCH 0960/2161] removed fastcall from SetNewMode --- include/geos/ggraph.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/geos/ggraph.h b/include/geos/ggraph.h index 642bd85ce..eb3ff81da 100644 --- a/include/geos/ggraph.h +++ b/include/geos/ggraph.h @@ -46,7 +46,7 @@ void __fastcall__ BitOtherClip(void *proc1, void *proc2, char skipl, void __fastcall__ GraphicsString(char *myGfxString); #ifdef __GEOS_CBM__ -void __fastcall__ SetNewMode(void); +void SetNewMode(void); #endif /* VIC colour constants */ From fa27c9dfc6abc2c62868db9d948487497e566c08 Mon Sep 17 00:00:00 2001 From: Scott Hutter <scott.hutter@gmail.com> Date: Sun, 30 Dec 2018 11:39:40 -0600 Subject: [PATCH 0961/2161] Moved contents of SetNewMode doc --- doc/geos.sgml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/geos.sgml b/doc/geos.sgml index 891c8ed18..08e642c24 100644 --- a/doc/geos.sgml +++ b/doc/geos.sgml @@ -188,6 +188,14 @@ are covered by new names, but I tried to keep them in the naming convention. <p> This section covers the drawing package of GEOS along with text output routines. +<sect2>SetNewMode +<p> +<tt/void SetNewMode (void)/ +<p> +This function is intended for use by GEOS 128 only, and will exhibit undefined behavior on the +C64. It will toggle between the 40 column screen mode and the 80 column screen mode. Many C128 GEOS +programs implement a "Switch 40/80" submenu option under the <tt/geos/ menu. + <sect2>SetPattern <p> <tt/void SetPattern (char pattern)/ @@ -332,14 +340,6 @@ The <tt/parameter/ is the field width in pixels (range 1-31) and the mode bits. the string can be filled with zeroes (the string is always 5 characters long) or not and left or right justified to the given pixel. See <tt/ggraph.h/ for predefined values for <tt/parameter/. -<sect3>SetNewMode -<p> -<tt/void SetNewMode (void)/ -<p> -This function is intended for use by GEOS 128 only, and will exhibit undefined behavior on the -C64. It will toggle between the 40 column screen mode and the 80 column screen mode. Many C128 GEOS -programs implement a "Switch 40/80" submenu option under the <tt/geos/ menu. - <sect2>Font Handling <sect3>GetCharWidth From 59ab140dc91be605a63fcacd7362d6357be3ba30 Mon Sep 17 00:00:00 2001 From: Scott Hutter <scott.hutter@gmail.com> Date: Sun, 30 Dec 2018 11:48:16 -0600 Subject: [PATCH 0962/2161] fix for err blank line removal --- include/geos/ggraph.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/geos/ggraph.h b/include/geos/ggraph.h index eb3ff81da..ec9fb0fa1 100644 --- a/include/geos/ggraph.h +++ b/include/geos/ggraph.h @@ -176,4 +176,5 @@ typedef void graphicStr; /* ESC_PUTSTRING can't be implemented - it needs text, not pointer to it #define ESC_PUTSTRING(x,y,text) (char)6, (unsigned)(x), (char)(y), (text), (char)NULL */ + #endif From 003d6542e48de792c64892660eb8fa20cffcff66 Mon Sep 17 00:00:00 2001 From: Marrin <> Date: Wed, 2 Jan 2019 12:06:01 +0100 Subject: [PATCH 0963/2161] Fixed documented return type. --- doc/funcref.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 0d294d886..bfd687b6f 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -3386,7 +3386,7 @@ used in presence of a prototype. <descrip> <tag/Function/Load and initialize an extended memory driver. <tag/Header/<tt/<ref id="em.h" name="em.h">/ -<tag/Declaration/<tt/void __fastcall__ em_load_driver (const char* name);/ +<tag/Declaration/<tt/unsigned char __fastcall__ em_load_driver (const char* name);/ <tag/Description/Load an extended memory driver into memory and initialize it. The function returns an error code that tells if all this has been successful. From 2959ade6e6c684d9982047bcc2e51717bc4dfee8 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 3 Jan 2019 10:49:56 -0500 Subject: [PATCH 0964/2161] Added, to Plus4 and GEOS linker configure files, the ability to set the start and end addresses of the program region. --- cfg/geos-apple.cfg | 12 ++++++++---- cfg/geos-cbm.cfg | 10 +++++++--- cfg/plus4.cfg | 14 +++++++++----- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/cfg/geos-apple.cfg b/cfg/geos-apple.cfg index 2c9f6c589..98dcfb5aa 100644 --- a/cfg/geos-apple.cfg +++ b/cfg/geos-apple.cfg @@ -1,15 +1,19 @@ +FEATURES { + STARTADDRESS: default = $4000; +} SYMBOLS { __BACKBUFSIZE__: type = weak, value = $2000; + __HIMEM__: type = weak, value = $C000 - __BACKBUFSIZE__; __OVERLAYSIZE__: type = weak, value = $0000; - __OVERLAYADDR__: type = weak, value = $C000 - __BACKBUFSIZE__ - __OVERLAYSIZE__; - __STACKSIZE__: type = weak, value = $0400; + __OVERLAYADDR__: type = weak, value = __HIMEM__ - __OVERLAYSIZE__; + __STACKSIZE__: type = weak, value = $0400; # 1k stack __STACKADDR__: type = weak, value = $2000 - __STACKSIZE__; } MEMORY { CVT: file = %O, start = $0, size = $20000; ZP: define = yes, start = $80, size = $1A + $06; - EXT: define = yes, start = $0C00, size = __STACKADDR__ - $0C00; - VLIR0: define = yes, start = $4000, size = __OVERLAYADDR__ - $4000; + EXT: define = yes, start = $0C00, size = __STACKADDR__ - __EXT_START__; + VLIR0: define = yes, start = %S, size = __OVERLAYADDR__ - %S; VLIR1: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; VLIR2: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; VLIR3: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; diff --git a/cfg/geos-cbm.cfg b/cfg/geos-cbm.cfg index d2e896fa5..4bf33fdf5 100644 --- a/cfg/geos-cbm.cfg +++ b/cfg/geos-cbm.cfg @@ -1,14 +1,18 @@ +FEATURES { + STARTADDRESS: default = $0400; +} SYMBOLS { __BACKBUFSIZE__: type = weak, value = $2000; + __HIMEM__: type = weak, value = $8000 - __BACKBUFSIZE__; __OVERLAYSIZE__: type = weak, value = $0000; - __OVERLAYADDR__: type = weak, value = $8000 - __BACKBUFSIZE__ - __OVERLAYSIZE__; - __STACKSIZE__: type = weak, value = $0400; + __OVERLAYADDR__: type = weak, value = __HIMEM__ - __OVERLAYSIZE__; + __STACKSIZE__: type = weak, value = $0400; # 1k stack __STACKADDR__: type = weak, value = __OVERLAYADDR__ - __STACKSIZE__; } MEMORY { CVT: file = %O, start = $0, size = $40000; ZP: define = yes, start = $58, size = $1A + $06; - VLIR0: define = yes, start = $0400, size = __STACKADDR__ - $0400; + VLIR0: define = yes, start = %S, size = __STACKADDR__ - %S; VLIR1: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; VLIR2: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; VLIR3: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; diff --git a/cfg/plus4.cfg b/cfg/plus4.cfg index 802f1076e..b7199e008 100644 --- a/cfg/plus4.cfg +++ b/cfg/plus4.cfg @@ -1,13 +1,17 @@ +FEATURES { + STARTADDRESS: default = $1001; +} SYMBOLS { __LOADADDR__: type = import; __EXEHDR__: type = import; __STACKSIZE__: type = weak, value = $0800; # 2k stack + __HIMEM__: type = weak, value = $FD00; } MEMORY { - ZP: file = "", define = yes, start = $0002, size = $001A; - LOADADDR: file = %O, start = $0FFF, size = $0002; - HEADER: file = %O, start = $1001, size = $000C; - MAIN: file = %O, define = yes, start = $100D, size = $ECF3 - __STACKSIZE__; + 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 = __HIMEM__ - __MAIN_START__ - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; @@ -15,8 +19,8 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: 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; From cd6e167982615cdf6cc529c8b15d4b84c0058fa3 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 4 Jan 2019 02:29:17 -0500 Subject: [PATCH 0965/2161] Fixed a duplicate-label test. Don't call strcmp() if either argument is NULL. --- src/da65/labels.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/da65/labels.c b/src/da65/labels.c index 6aa7f38cf..97e195ebf 100644 --- a/src/da65/labels.c +++ b/src/da65/labels.c @@ -92,7 +92,9 @@ static void AddLabel (unsigned Addr, attr_t Attr, const char* Name) ** have a name (you guessed that, didn't you?). */ if (ExistingAttr == Attr && - ((Name == 0 && SymTab[Addr] == 0) || strcmp (SymTab[Addr], Name) == 0)) { + ((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], Name); From 5ac11b5e882d09e9e1dba34b76f536520a1c34fc Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 4 Jan 2019 03:35:49 -0500 Subject: [PATCH 0966/2161] Added an error message, in case there's a typo in the definitions of long command-line options. --- src/cc65/main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cc65/main.c b/src/cc65/main.c index 7783587aa..a98603dd8 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -256,7 +256,7 @@ static void SetSys (const char* Sys) case TGT_TELESTRAT: DefineNumericMacro ("__TELESTRAT__", 1); break; - + case TGT_NES: DefineNumericMacro ("__NES__", 1); break; @@ -302,6 +302,10 @@ static void FileNameOption (const char* Opt, const char* Arg, StrBuf* Name) if (SB_NotEmpty (Name)) { AbEnd ("Cannot use option `%s' twice", Opt); } + /* A typo in OptTab[] might allow a NULL Arg */ + if (Arg == 0) { + Internal ("Typo in OptTab[]; option '%s' should require an argument", Opt); + } /* Remember the file name for later */ SB_CopyStr (Name, Arg); SB_Terminate (Name); @@ -558,7 +562,7 @@ static void OptDebugOpt (const char* Opt attribute ((unused)), const char* Arg) -static void OptDebugOptOutput (const char* Opt attribute ((unused)), +static void OptDebugOptOutput (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Output optimization steps */ { From c8bf6529829949d87ec87e5f4ee256fc0de08cde Mon Sep 17 00:00:00 2001 From: Joshua Bell <inexorabletash@gmail.com> Date: Sat, 5 Jan 2019 11:29:54 -0800 Subject: [PATCH 0967/2161] ca65: Add string_escapes feature. Resolves #535 --- doc/ca65.sgml | 18 ++++++++++++++++++ src/ca65/feature.c | 2 ++ src/ca65/feature.h | 1 + src/ca65/global.c | 2 +- src/ca65/global.h | 1 + src/ca65/scanner.c | 37 +++++++++++++++++++++++++++++++++++++ 6 files changed, 60 insertions(+), 1 deletion(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 52e9634ae..bc22ba354 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -2831,6 +2831,24 @@ Here's a list of all control commands and a description, what they do: removing the lines with the assignments may also be an option when porting code written for older assemblers). + <tag><tt>string_escapes</tt><label id="string_escapes"></tag> + + Allow C-style backslash escapes within string constants to embed + special characters. The following escapes are accepted: + +<itemize> +<item><tt>\\</tt> backslash (<tt>$5C</tt>) +<item><tt>\'</tt> single quote (<tt>$27</tt>) +<item><tt>\"</tt> double quote (<tt>$22</tt>) +<item><tt>\t</tt> tab (<tt>$09</tt>) +<item><tt>\r</tt> carriage return (<tt>$0D</tt>) +<item><tt>\n</tt> newline (<tt>$0A</tt>) +<item><tt>\xNN</tt> (<tt>$NN</tt>) +</itemize> + + Note that <tt>\n</tt> maps to ASCII <tt>$0A</tt>, not a platform specific + line ending character. + <tag><tt>ubiquitous_idents</tt><label id="ubiquitous_idents"></tag> Allow the use of instructions names as names for macros and symbols. This diff --git a/src/ca65/feature.c b/src/ca65/feature.c index 0fb766b6f..b11345338 100644 --- a/src/ca65/feature.c +++ b/src/ca65/feature.c @@ -65,6 +65,7 @@ static const char* const FeatureKeys[FEAT_COUNT] = { "underline_in_numbers", "addrsize", "bracket_as_indirect", + "string_escapes", }; @@ -123,6 +124,7 @@ feature_t SetFeature (const StrBuf* Key) case FEAT_UNDERLINE_IN_NUMBERS: UnderlineInNumbers= 1; break; case FEAT_ADDRSIZE: AddrSize = 1; break; case FEAT_BRACKET_AS_INDIRECT: BracketAsIndirect = 1; break; + case FEAT_STRING_ESCAPES: StringEscapes = 1; break; default: /* Keep gcc silent */ break; } diff --git a/src/ca65/feature.h b/src/ca65/feature.h index 050c197f0..876f3c4a8 100644 --- a/src/ca65/feature.h +++ b/src/ca65/feature.h @@ -67,6 +67,7 @@ typedef enum { FEAT_UNDERLINE_IN_NUMBERS, FEAT_ADDRSIZE, FEAT_BRACKET_AS_INDIRECT, + FEAT_STRING_ESCAPES, /* Special value: Number of features available */ FEAT_COUNT diff --git a/src/ca65/global.c b/src/ca65/global.c index 31e599f00..a216fc406 100644 --- a/src/ca65/global.c +++ b/src/ca65/global.c @@ -66,6 +66,7 @@ unsigned char DbgSyms = 0; /* Add debug symbols */ unsigned char LineCont = 0; /* Allow line continuation */ unsigned char LargeAlignment = 0; /* Don't warn about large alignments */ unsigned char RelaxChecks = 0; /* Relax a few assembler checks */ +unsigned char StringEscapes = 0; /* Allow C-style escapes in strings */ /* Emulation features */ unsigned char DollarIsPC = 0; /* Allow the $ symbol as current PC */ @@ -84,4 +85,3 @@ unsigned char ForceRange = 0; /* Force values into expected range */ unsigned char UnderlineInNumbers = 0; /* Allow underlines in numbers */ unsigned char AddrSize = 0; /* Allow .ADDRSIZE function */ unsigned char BracketAsIndirect = 0; /* Use '[]' not '()' for indirection */ - diff --git a/src/ca65/global.h b/src/ca65/global.h index 397d9221b..77d90beca 100644 --- a/src/ca65/global.h +++ b/src/ca65/global.h @@ -68,6 +68,7 @@ extern unsigned char DbgSyms; /* Add debug symbols */ extern unsigned char LineCont; /* Allow line continuation */ extern unsigned char LargeAlignment; /* Don't warn about large alignments */ extern unsigned char RelaxChecks; /* Relax a few assembler checks */ +extern unsigned char StringEscapes; /* Allow C-style escapes in strings */ /* Emulation features */ extern unsigned char DollarIsPC; /* Allow the $ symbol as current PC */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 7c291666c..965fa3581 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -794,6 +794,43 @@ static void ReadStringConst (int StringTerm) break; } + if (C == '\\' && StringEscapes) { + NextChar (); + + switch (C) { + case EOF: + Error ("Unterminated escape sequence in string constant"); + break; + case '\\': + case '\'': + case '"': + break; + case 't': + C = '\x09'; + break; + case 'r': + C = '\x0D'; + break; + case 'n': + C = '\x0A'; + break; + case 'x': + NextChar (); + if (IsXDigit (C)) { + char high_nibble = DigitVal (C) << 4; + NextChar (); + if (IsXDigit (C)) { + C = high_nibble | DigitVal (C); + break; + } + } + /* otherwise, fall through */ + default: + Error ("Unsupported escape sequence in string constant"); + break; + } + } + /* Append the char to the string */ SB_AppendChar (&CurTok.SVal, C); From a6b04f6e97b59ca0ad1cc98dbd91ad600c0414a8 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 5 Jan 2019 14:57:12 -0500 Subject: [PATCH 0968/2161] Changed most "backticks" (grave accents) into apostrophes. Quotations that are embraced by tick marks now look better, in most fonts. --- doc/Makefile | 2 +- doc/ar65.sgml | 16 ++++++------ doc/atari.sgml | 2 +- doc/ca65.sgml | 12 ++++----- doc/cl65.sgml | 4 +-- doc/geos.sgml | 2 +- doc/ld65.sgml | 8 +++--- doc/sim65.sgml | 2 +- libsrc/Makefile | 2 +- libsrc/lynx/lynx-snd.s | 2 +- samples/Makefile | 2 +- src/Makefile | 2 +- src/ar65/exports.c | 4 +-- src/ar65/library.c | 16 ++++++------ src/ar65/objdata.c | 2 +- src/ar65/objfile.c | 20 +++++++-------- src/ca65/dbginfo.c | 2 +- src/ca65/ea65.c | 6 ++--- src/ca65/enum.c | 2 +- src/ca65/expr.c | 12 ++++----- src/ca65/filetab.c | 4 +-- src/ca65/listing.c | 2 +- src/ca65/macro.c | 10 ++++---- src/ca65/main.c | 24 +++++++++--------- src/ca65/nexttok.c | 14 +++++------ src/ca65/objfile.c | 4 +-- src/ca65/pseudo.c | 14 +++++------ src/ca65/scanner.c | 8 +++--- src/ca65/segment.c | 2 +- src/ca65/struct.c | 4 +-- src/ca65/studyexpr.c | 2 +- src/ca65/symbol.c | 4 +-- src/ca65/symentry.c | 52 +++++++++++++++++++-------------------- src/ca65/symtab.c | 20 +++++++-------- src/cc65/asmstmt.c | 2 +- src/cc65/codeinfo.c | 2 +- src/cc65/codeopt.c | 8 +++--- src/cc65/codeseg.c | 16 ++++++------ src/cc65/compile.c | 14 +++++------ src/cc65/declare.c | 32 ++++++++++++------------ src/cc65/declattr.c | 2 +- src/cc65/expr.c | 30 +++++++++++------------ src/cc65/function.c | 4 +-- src/cc65/hexval.c | 2 +- src/cc65/input.c | 12 ++++----- src/cc65/locals.c | 8 +++--- src/cc65/macrotab.c | 2 +- src/cc65/main.c | 16 ++++++------ src/cc65/output.c | 10 ++++---- src/cc65/pragma.c | 6 ++--- src/cc65/preproc.c | 22 ++++++++--------- src/cc65/scanner.c | 20 +++++++-------- src/cc65/scanstrbuf.c | 2 +- src/cc65/stmt.c | 12 ++++----- src/cc65/swstmt.c | 2 +- src/cc65/symtab.c | 36 +++++++++++++-------------- src/cc65/typeconv.c | 2 +- src/chrcvt65/main.c | 34 +++++++++++++------------- src/cl65/main.c | 16 ++++++------ src/cl65/spawn-unix.inc | 4 +-- src/co65/convert.c | 14 +++++------ src/co65/main.c | 8 +++--- src/co65/o65.c | 2 +- src/common/check.c | 2 +- src/common/cmdline.c | 4 +-- src/da65/asminc.c | 2 +- src/da65/code.c | 12 ++++----- src/da65/main.c | 2 +- src/da65/output.c | 2 +- src/da65/scanner.c | 16 ++++++------ src/dbginfo/dbginfo.c | 2 +- src/grc65/main.c | 4 +-- src/ld65/asserts.c | 4 +-- src/ld65/bin.c | 10 ++++---- src/ld65/config.c | 54 ++++++++++++++++++++--------------------- src/ld65/dbgfile.c | 4 +-- src/ld65/exports.c | 20 +++++++-------- src/ld65/expr.c | 4 +-- src/ld65/extsyms.c | 2 +- src/ld65/library.c | 10 ++++---- src/ld65/lineinfo.c | 2 +- src/ld65/main.c | 18 +++++++------- src/ld65/mapfile.c | 8 +++--- src/ld65/o65.c | 18 +++++++------- src/ld65/objdata.c | 12 ++++----- src/ld65/objfile.c | 4 +-- src/ld65/scanner.c | 10 ++++---- src/ld65/scopes.c | 2 +- src/ld65/segments.c | 22 ++++++++--------- src/od65/main.c | 2 +- src/sim65/main.c | 10 ++++---- src/sp65/asm.c | 10 ++++---- src/sp65/attr.c | 6 ++--- src/sp65/bin.c | 6 ++--- src/sp65/c.c | 10 ++++---- src/sp65/convert.c | 2 +- src/sp65/input.c | 4 +-- src/sp65/lynxsprite.c | 2 +- src/sp65/main.c | 2 +- src/sp65/output.c | 4 +-- src/sp65/pcx.c | 18 +++++++------- src/sp65/vic2sprite.c | 2 +- test/misc/goto.ref | 6 ++--- test/ref/cc65090124.c | 2 +- test/ref/cc65091022.c | 2 +- test/ref/cc65101102.c | 10 ++++---- test/ref/cc65110210.c | 16 ++++++------ test/ref/paranoia.c | 8 +++--- test/val/compare1.c | 6 ++--- 109 files changed, 501 insertions(+), 501 deletions(-) diff --git a/doc/Makefile b/doc/Makefile index 33b5c2686..bb8f551ad 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -46,7 +46,7 @@ clean: $(RM) -r ../html ../info install: - $(if $(PREFIX),,$(error variable `PREFIX' must be set)) + $(if $(PREFIX),,$(error variable "PREFIX" must be set)) ifeq ($(wildcard ../html),../html) $(INSTALL) -d $(DESTDIR)$(htmldir) $(INSTALL) -m0644 ../html/*.* $(DESTDIR)$(htmldir) diff --git a/doc/ar65.sgml b/doc/ar65.sgml index d5e91a3a3..df4154539 100644 --- a/doc/ar65.sgml +++ b/doc/ar65.sgml @@ -40,7 +40,7 @@ The archiver is called as follows: V Print the archiver version </verb></tscreen> -You may add modules to a library using the `r' command (`a' is deprecated). If the library +You may add modules to a library using the <tt/'r'/ command ('a' is deprecated). If the library does not exist, it is created (and a warning message is printed which you may ignore if creation of the library was your intention). You may specify any number of modules on the command line following the library. @@ -55,7 +55,7 @@ Here's an example: ar65 r mysubs.lib sub1.o sub2.o </verb></tscreen> -This will add two modules to the library `mysubs.lib' creating the +This will add two modules to the library 'mysubs.lib' creating the library if necessary. If the library contains modules named sub1.o or sub2.o, they are replaced by the new ones. @@ -65,9 +65,9 @@ Modules names in the library are stored without the path, so, using ar65 v v r mysubs.lib ofiles/sub1.o ofiles/sub2.o </verb></tscreen> -will verbose add two modules named `sub1.o' and `sub2.o' to the library. +will verbose add two modules named 'sub1.o' and 'sub2.o' to the library. -Deleting modules from a library is done with the `d' command. You may not +Deleting modules from a library is done with the <tt/'d'/ command. You may not give a path when naming the modules. Example: @@ -76,11 +76,11 @@ Example: ar65 d mysubs.lib sub1.o </verb></tscreen> -This will delete the module named `sub1.o' from the library, printing an +This will delete the module named 'sub1.o' from the library, printing an error if the library does not contain that module. -The `t' command prints a table of all modules in the library (`l' is deprecated). +The <tt/'t'/ command prints a table of all modules in the library ('l' is deprecated). Any module names on the command line are ignored. Example: @@ -90,7 +90,7 @@ Example: </verb></tscreen> -Using the `x' command, you may extract modules from the library. The +Using the <tt/'x'/ command, you may extract modules from the library. The modules named on the command line are extracted from the library and put into the current directory. @@ -107,7 +107,7 @@ Example for extracting a module from the library: </verb></tscreen> -The `V' command prints the version number of the assembler. If you send +The <tt/'V'/ command prints the version number of the assembler. If you send any suggestions or bugfixes, please include your version number. In addition to these operations, the archiver will check for, and warn diff --git a/doc/atari.sgml b/doc/atari.sgml index 2531c8d03..80293d82f 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -1082,7 +1082,7 @@ If you are using a customized linker config file you might get some errors regarding the MAINHDR segment. Like this: <tscreen><verb> -ld65: Error: Missing memory area assignment for segment `MAINHDR' +ld65: Error: Missing memory area assignment for segment 'MAINHDR' </verb></tscreen> The old "HEADER" memory description contained six bytes: $FFFF diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 52e9634ae..1f8f2f0d3 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -2730,7 +2730,7 @@ Here's a list of all control commands and a description, what they do: <tag><tt>at_in_identifiers</tt><label id="at_in_identifiers"></tag> - Accept the at character (`@') as a valid character in identifiers. The + Accept the at character ('@') as a valid character in identifiers. The at character is not allowed to start an identifier, even with this feature enabled. @@ -2765,13 +2765,13 @@ Here's a list of all control commands and a description, what they do: <tag><tt>dollar_in_identifiers</tt><label id="dollar_in_identifiers"></tag> - Accept the dollar sign (`$') as a valid character in identifiers. The + Accept the dollar sign ('$') as a valid character in identifiers. The dollar character is not allowed to start an identifier, even with this feature enabled. <tag><tt>dollar_is_pc</tt><label id="dollar_is_pc"></tag> - The dollar sign may be used as an alias for the star (`*'), which + The dollar sign may be used as an alias for the star ('*'), which gives the value of the current PC in expressions. Note: Assignment to the pseudo variable is not allowed. @@ -2789,7 +2789,7 @@ Here's a list of all control commands and a description, what they do: <tag><tt>leading_dot_in_identifiers</tt><label id="leading_dot_in_identifiers"></tag> - Accept the dot (`.') as the first character of an identifier. This may be + Accept the dot ('.') as the first character of an identifier. This may be used for example to create macro names that start with a dot emulating control directives of other assemblers. Note however, that none of the reserved keywords built into the assembler, that starts with a dot, may be @@ -2825,7 +2825,7 @@ Here's a list of all control commands and a description, what they do: <tag><tt>pc_assignment</tt><label id="pc_assignment"></tag> - Allow assignments to the PC symbol (`*' or `$' if <tt/dollar_is_pc/ + Allow assignments to the PC symbol ('*' or '$' if <tt/dollar_is_pc/ is enabled). Such an assignment is handled identical to the <tt><ref id=".ORG" name=".ORG"></tt> command (which is usually not needed, so just removing the lines with the assignments may also be an option when porting @@ -3799,7 +3799,7 @@ Here's a list of all control commands and a description, what they do: page and direct (short) addressing is possible for data in this segment. Beware: Only labels in a segment with the zeropage attribute are marked - as reachable by short addressing. The `*' (PC counter) operator will + as reachable by short addressing. The '*' (PC counter) operator will work as in other segments and will create absolute variable values. Please note that a segment cannot have two different address sizes. A diff --git a/doc/cl65.sgml b/doc/cl65.sgml index ef7309eec..c6761ed9e 100644 --- a/doc/cl65.sgml +++ b/doc/cl65.sgml @@ -44,7 +44,7 @@ Short options: -o name Name the output file -r Enable register variables -t sys Set the target system - -u sym Force an import of symbol `sym' + -u sym Force an import of symbol 'sym' -v Verbose mode -vm Verbose map file -C name Use linker config file @@ -90,7 +90,7 @@ Long options: --debug Debug mode --debug-info Add debug info --feature name Set an emulation feature - --force-import sym Force an import of symbol `sym' + --force-import sym Force an import of symbol 'sym' --help Help (this text) --include-dir dir Set a compiler include directory path --ld-args options Pass options to the linker diff --git a/doc/geos.sgml b/doc/geos.sgml index 08e642c24..eb8d74939 100644 --- a/doc/geos.sgml +++ b/doc/geos.sgml @@ -1561,7 +1561,7 @@ char text = "foo"; DB_VARSTR (TXT_LN_X, TXT_LN_1_Y, &r15), ... </verb></tscreen> -will cause the word ``foo'' to appear in the window, but you may store the pointer to any text in +will cause the word ''foo'' to appear in the window, but you may store the pointer to any text in <tt/r15/ (in this case) before the call to DoDlgBox. <p> <tt/DB_GETSTR(x, y, ptr, length)/ - will add a input-from-keyboard feature. <tt/ptr/ works as in the diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 9cbb5aad8..beb2144bf 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -66,7 +66,7 @@ Short options: -m name Create a map file -o name Name the default output file -t sys Set the target system - -u sym Force an import of symbol `sym' + -u sym Force an import of symbol 'sym' -v Verbose mode -vm Verbose map file @@ -76,7 +76,7 @@ Long options: --dbgfile name Generate debug information --define sym=val Define a symbol --end-group End a library group - --force-import sym Force an import of symbol `sym' + --force-import sym Force an import of symbol 'sym' --help Help (this text) --lib file Link this library --lib-path path Specify a library search path @@ -487,7 +487,7 @@ There are of course more attributes for a memory section than just start and size. Start and size are mandatory attributes, that means, each memory area defined <em/must/ have these attributes given (the linker will check that). I will cover other attributes later. As you may have noticed, I've used a -comment in the example above. Comments start with a hash mark (`#'), the +comment in the example above. Comments start with a hash mark ('#'), the remainder of the line is ignored if this character is found. @@ -572,7 +572,7 @@ default behaviour is OK for our purposes, I did not use the attribute in the example above. Let's have a look at it now. The "file" attribute (the keyword may also be written as "FILE" if you like -that better) takes a string enclosed in double quotes (`&dquot;') that specifies the +that better) takes a string enclosed in double quotes ('&dquot;') that specifies the file, where the data is written. You may specify the same file several times, in that case the data for all memory areas having this file name is written into this file, in the order of the memory areas defined in the <tt/MEMORY/ diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 14741dd31..286c46c56 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -89,7 +89,7 @@ Example output for the command sim65 --verbose --verbose samples/gunzip65 </verb></tscreen> <tscreen><verb> -Loaded `samples/gunzip65' at $0200-$151F +Loaded 'samples/gunzip65' at $0200-$151F PVWrite ($0001, $13C9, $000F) GZIP file name:PVWrite ($0001, $151F, $0001) diff --git a/libsrc/Makefile b/libsrc/Makefile index 0d0cd320b..0ebec46b1 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -93,7 +93,7 @@ INSTALL = install define INSTALL_recipe -$(if $(PREFIX),,$(error variable `PREFIX' must be set)) +$(if $(PREFIX),,$(error variable "PREFIX" must be set)) $(INSTALL) -d $(DESTDIR)$(datadir)/$(dir) $(INSTALL) -m0644 ../$(dir)/*.* $(DESTDIR)$(datadir)/$(dir) diff --git a/libsrc/lynx/lynx-snd.s b/libsrc/lynx/lynx-snd.s index 9d0b8b7af..82b05276f 100644 --- a/libsrc/lynx/lynx-snd.s +++ b/libsrc/lynx/lynx-snd.s @@ -1062,7 +1062,7 @@ SndSetValues: ldx #4-1 set0: ldy SndOffsets,x lda SndChannel+2,y - _IFNE ; flag == 0 => don`t set + _IFNE ; flag == 0 => don't set bit #$80 _IFNE ; diff --git a/samples/Makefile b/samples/Makefile index 601d19d76..74094aeae 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -296,7 +296,7 @@ INSTALL = install samplesdir = $(PREFIX)/share/cc65/samples install: - $(if $(PREFIX),,$(error variable `PREFIX' must be set)) + $(if $(PREFIX),,$(error variable "PREFIX" must be set)) $(INSTALL) -d $(DESTDIR)$(samplesdir) $(INSTALL) -d $(DESTDIR)$(samplesdir)/geos $(INSTALL) -d $(DESTDIR)$(samplesdir)/tutorial diff --git a/src/Makefile b/src/Makefile index c1f11ff58..c93a8645f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -107,7 +107,7 @@ $(RM) /usr/local/bin/$(prog) endef # UNAVAIL_recipe install: - $(if $(PREFIX),,$(error variable `PREFIX' must be set)) + $(if $(PREFIX),,$(error variable "PREFIX" must be set)) $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL) ../bin/* $(DESTDIR)$(bindir) diff --git a/src/ar65/exports.c b/src/ar65/exports.c index b3bb4cebe..b1e133e72 100644 --- a/src/ar65/exports.c +++ b/src/ar65/exports.c @@ -113,8 +113,8 @@ void ExpInsert (const char* Name, const ObjData* Module) while (1) { if (strcmp (L->Name, Name) == 0) { /* Duplicate entry */ - Warning ("External symbol `%s' in module `%s', library `%s', " - "is duplicated in module `%s'", + Warning ("External symbol '%s' in module '%s', library '%s', " + "is duplicated in module '%s'", Name, L->Module->Name, LibName, Module->Name); } if (L->Next == 0) { diff --git a/src/ar65/library.c b/src/ar65/library.c index c72e6e3cf..4d18168d8 100644 --- a/src/ar65/library.c +++ b/src/ar65/library.c @@ -95,11 +95,11 @@ static void ReadHeader (void) /* Read the header fields, checking magic and version */ Header.Magic = Read32 (Lib); if (Header.Magic != LIB_MAGIC) { - Error ("`%s' is not a valid library file", LibName); + Error ("'%s' is not a valid library file", LibName); } Header.Version = Read16 (Lib); if (Header.Version != LIB_VERSION) { - Error ("Wrong data version in `%s'", LibName); + Error ("Wrong data version in '%s'", LibName); } Header.Flags = Read16 (Lib); Header.IndexOffs = Read32 (Lib); @@ -229,11 +229,11 @@ void LibOpen (const char* Name, int MustExist, int NeedTemp) /* File does not exist */ if (MustExist) { - Error ("Library `%s' does not exist", Name); + Error ("Library '%s' does not exist", Name); } else { /* Announce the library's creation if ar65 is verbose. */ Print (stdout, 1, - "%s: Library `%s' will be created.\n", ProgName, Name); + "%s: Library '%s' will be created.\n", ProgName, Name); } } else { @@ -317,7 +317,7 @@ static void LibCheckExports (ObjData* O) unsigned I; /* Let the user know what we do */ - Print (stdout, 2, "Module `%s' (%u exports):\n", O->Name, CollCount (&O->Exports)); + Print (stdout, 2, "Module '%s' (%u exports):\n", O->Name, CollCount (&O->Exports)); /* Insert the exports into the global table */ for (I = 0; I < CollCount (&O->Exports); ++I) { @@ -381,7 +381,7 @@ void LibClose (void) /* Reopen the library and truncate it */ Lib = fopen (LibName, "wb"); if (Lib == 0) { - Error ("Cannot open library `%s' for writing: %s", + Error ("Cannot open library '%s' for writing: %s", LibName, strerror (errno)); } @@ -389,14 +389,14 @@ void LibClose (void) fseek (NewLib, 0, SEEK_SET); while ((Count = fread (Buf, 1, sizeof (Buf), NewLib)) != 0) { if (fwrite (Buf, 1, Count, Lib) != Count) { - Error ("Cannot write to `%s': %s", LibName, strerror (errno)); + Error ("Cannot write to '%s': %s", LibName, strerror (errno)); } } } /* Close both files */ if (Lib && fclose (Lib) != 0) { - Error ("Problem closing `%s': %s", LibName, strerror (errno)); + Error ("Problem closing '%s': %s", LibName, strerror (errno)); } if (NewLib && fclose (NewLib) != 0) { Error ("Problem closing temporary library file: %s", strerror (errno)); diff --git a/src/ar65/objdata.c b/src/ar65/objdata.c index 5a8f0c5fb..252ebe6ab 100644 --- a/src/ar65/objdata.c +++ b/src/ar65/objdata.c @@ -165,5 +165,5 @@ void DelObjData (const char* Module) } /* Not found! */ - Warning ("Module `%s' not found in library `%s'", Module, LibName); + Warning ("Module '%s' not found in library '%s'", Module, LibName); } diff --git a/src/ar65/objfile.c b/src/ar65/objfile.c index 0434f7e59..ac7dccb0d 100644 --- a/src/ar65/objfile.c +++ b/src/ar65/objfile.c @@ -68,7 +68,7 @@ static const char* GetModule (const char* Name) /* Must not end with a path separator */ if (*Module == 0) { - Error ("Cannot make module name from `%s'", Name); + Error ("Cannot make module name from '%s'", Name); } /* Done */ @@ -82,11 +82,11 @@ static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name) { H->Magic = Read32 (Obj); if (H->Magic != OBJ_MAGIC) { - Error ("`%s' is not an object file", Name); + Error ("'%s' is not an object file", Name); } H->Version = Read16 (Obj); if (H->Version != OBJ_VERSION) { - Error ("Object file `%s' has wrong version", Name); + Error ("Object file '%s' has wrong version", Name); } H->Flags = Read16 (Obj); H->OptionOffs = Read32 (Obj); @@ -236,7 +236,7 @@ void ObjAdd (const char* Name) /* Open the object file */ FILE* Obj = fopen (Name, "rb"); if (Obj == 0) { - Error ("Could not open `%s': %s", Name, strerror (errno)); + Error ("Could not open '%s': %s", Name, strerror (errno)); } /* Get the modification time of the object file. There's a race condition @@ -248,7 +248,7 @@ void ObjAdd (const char* Name) ** here. */ if (FileStat (Name, &StatBuf) != 0) { - Error ("Cannot stat object file `%s': %s", Name, strerror (errno)); + Error ("Cannot stat object file '%s': %s", Name, strerror (errno)); } /* Read and check the header */ @@ -267,7 +267,7 @@ void ObjAdd (const char* Name) ** and the external one. */ if (difftime ((time_t)O->MTime, StatBuf.st_mtime) > 0.0) { - Warning ("Replacing module `%s' by older version in library `%s'", + Warning ("Replacing module '%s' by older version in library '%s'", O->Name, LibName); } @@ -313,13 +313,13 @@ void ObjExtract (const char* Name) /* Bail out if the module does not exist */ if (O == 0) { - Error ("Module `%s' not found in library `%s'", Module, LibName); + Error ("Module '%s' not found in library '%s'", Module, LibName); } /* Open the output file */ Obj = fopen (Name, "w+b"); if (Obj == 0) { - Error ("Cannot open target file `%s': %s", Name, strerror (errno)); + Error ("Cannot open target file '%s': %s", Name, strerror (errno)); } /* Copy the complete object file data from the library to the new object @@ -329,11 +329,11 @@ void ObjExtract (const char* Name) /* Close the file */ if (fclose (Obj) != 0) { - Error ("Problem closing object file `%s': %s", Name, strerror (errno)); + Error ("Problem closing object file '%s': %s", Name, strerror (errno)); } /* Set access and modification time */ if (SetFileTimes (Name, O->MTime) != 0) { - Error ("Cannot set mod time on `%s': %s", Name, strerror (errno)); + Error ("Cannot set mod time on '%s': %s", Name, strerror (errno)); } } diff --git a/src/ca65/dbginfo.c b/src/ca65/dbginfo.c index 135739fb5..c9dd7ab6d 100644 --- a/src/ca65/dbginfo.c +++ b/src/ca65/dbginfo.c @@ -468,7 +468,7 @@ void DbgInfoCheck (void) /* Search for the symbol name */ S->Sym = SymFindAny (S->Scope, GetStrBuf (S->AsmName)); if (S->Sym == 0) { - PError (&S->Pos, "Assembler symbol `%s' not found", + PError (&S->Pos, "Assembler symbol '%s' not found", GetString (S->AsmName)); } else { /* Set the backlink */ diff --git a/src/ca65/ea65.c b/src/ca65/ea65.c index 2f7c2bfa9..275d90b56 100644 --- a/src/ca65/ea65.c +++ b/src/ca65/ea65.c @@ -133,7 +133,7 @@ void GetEA (EffAddr* A) A->AddrModeSet = AM65_STACK_REL_IND_Y; Consume (IndirectLeave, IndirectExpect); ConsumeComma (); - Consume (TOK_Y, "`Y' expected"); + Consume (TOK_Y, "'Y' expected"); } else { Error ("Syntax error"); } @@ -152,7 +152,7 @@ void GetEA (EffAddr* A) A->AddrModeSet = AM65_DIR_IND; break; default: - Consume (TOK_Y, "`Y' expected"); + Consume (TOK_Y, "'Y' expected"); A->AddrModeSet = AM65_DIR_IND_Y; break; } @@ -173,7 +173,7 @@ void GetEA (EffAddr* A) if (CurTok.Tok == TOK_COMMA) { /* [dir],y */ NextTok (); - Consume (TOK_Y, "`Y' expected"); + Consume (TOK_Y, "'Y' expected"); A->AddrModeSet = AM65_DIR_IND_LONG_Y; } else { /* [dir] */ diff --git a/src/ca65/enum.c b/src/ca65/enum.c index f0561b692..339b3230f 100644 --- a/src/ca65/enum.c +++ b/src/ca65/enum.c @@ -146,7 +146,7 @@ void DoEnum (void) } /* End of enum definition */ - Consume (TOK_ENDENUM, "`.ENDENUM' expected"); + Consume (TOK_ENDENUM, "'.ENDENUM' expected"); /* Free the base expression */ FreeExpr (BaseExpr); diff --git a/src/ca65/expr.c b/src/ca65/expr.c index ff4232c00..982bb05c6 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -699,7 +699,7 @@ static ExprNode* FuncAddrSize (void) /* Cheap local symbol */ Sym = SymFindLocal (SymLast, &CurTok.SVal, SYM_FIND_EXISTING); if (Sym == 0) { - Error ("Unknown symbol or scope: `%m%p'", &CurTok.SVal); + Error ("Unknown symbol or scope: '%m%p'", &CurTok.SVal); } else { AddrSize = Sym->AddrSize; } @@ -739,13 +739,13 @@ static ExprNode* FuncAddrSize (void) if (Sym) { AddrSize = Sym->AddrSize; } else { - Error ("Unknown symbol or scope: `%m%p%m%p'", &ScopeName, &Name); + Error ("Unknown symbol or scope: '%m%p%m%p'", &ScopeName, &Name); } } if (AddrSize == 0) { - Warning (1, "Unknown address size: `%m%p%m%p'", &ScopeName, &Name); + Warning (1, "Unknown address size: '%m%p%m%p'", &ScopeName, &Name); } /* Free the string buffers */ @@ -780,7 +780,7 @@ static ExprNode* FuncSizeOf (void) /* Cheap local symbol */ Sym = SymFindLocal (SymLast, &CurTok.SVal, SYM_FIND_EXISTING); if (Sym == 0) { - Error ("Unknown symbol or scope: `%m%p'", &CurTok.SVal); + Error ("Unknown symbol or scope: '%m%p'", &CurTok.SVal); } else { SizeSym = GetSizeOfSymbol (Sym); } @@ -832,7 +832,7 @@ static ExprNode* FuncSizeOf (void) if (Sym) { SizeSym = GetSizeOfSymbol (Sym); } else { - Error ("Unknown symbol or scope: `%m%p%m%p'", + Error ("Unknown symbol or scope: '%m%p%m%p'", &ScopeName, &Name); } } @@ -840,7 +840,7 @@ static ExprNode* FuncSizeOf (void) /* Check if we have a size */ if (SizeSym == 0 || !SymIsConst (SizeSym, &Size)) { - Error ("Size of `%m%p%m%p' is unknown", &ScopeName, &Name); + Error ("Size of '%m%p%m%p' is unknown", &ScopeName, &Name); Size = 0; } diff --git a/src/ca65/filetab.c b/src/ca65/filetab.c index ce4b15c03..4ca32631e 100644 --- a/src/ca65/filetab.c +++ b/src/ca65/filetab.c @@ -211,7 +211,7 @@ unsigned GetFileIndex (const StrBuf* Name) /* If we don't have this index, print a diagnostic and use the main file */ if (F == 0) { - Error ("File name `%m%p' not found in file table", Name); + Error ("File name '%m%p' not found in file table", Name); return 0; } else { return F->Index; @@ -316,7 +316,7 @@ static void CreateDepFile (const char* Name, FileType Types) /* Open the file */ FILE* F = fopen (Name, "w"); if (F == 0) { - Fatal ("Cannot open dependency file `%s': %s", Name, strerror (errno)); + Fatal ("Cannot open dependency file '%s': %s", Name, strerror (errno)); } /* Print the output file followed by a tab char */ diff --git a/src/ca65/listing.c b/src/ca65/listing.c index b3f3d9282..9f2396612 100644 --- a/src/ca65/listing.c +++ b/src/ca65/listing.c @@ -304,7 +304,7 @@ void CreateListing (void) /* Open the real listing file */ F = fopen (SB_GetConstBuf (&ListingName), "w"); if (F == 0) { - Fatal ("Cannot open listing file `%s': %s", + Fatal ("Cannot open listing file '%s': %s", SB_GetConstBuf (&ListingName), strerror (errno)); } diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 1f6812ce0..988493976 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -375,7 +375,7 @@ static void MacSkipDef (unsigned Style) if (CurTok.Tok != TOK_EOF) { SkipUntilSep (); } else { - Error ("`.ENDMACRO' expected"); + Error ("'.ENDMACRO' expected"); } } else { /* Skip until end of line */ @@ -409,7 +409,7 @@ void MacDef (unsigned Style) /* Did we already define that macro? */ if (HT_Find (&MacroTab, &CurTok.SVal) != 0) { /* Macro is already defined */ - Error ("A macro named `%m%p' is already defined", &CurTok.SVal); + Error ("A macro named '%m%p' is already defined", &CurTok.SVal); /* Skip tokens until we reach the final .endmacro */ MacSkipDef (Style); return; @@ -451,7 +451,7 @@ void MacDef (unsigned Style) IdDesc* List = M->Params; while (1) { if (SB_Compare (&List->Id, &CurTok.SVal) == 0) { - Error ("Duplicate symbol `%m%p'", &CurTok.SVal); + Error ("Duplicate symbol '%m%p'", &CurTok.SVal); } if (List->Next == 0) { break; @@ -500,7 +500,7 @@ void MacDef (unsigned Style) } /* May not have end of file in a macro definition */ if (CurTok.Tok == TOK_EOF) { - Error ("`.ENDMACRO' expected"); + Error ("'.ENDMACRO' expected"); goto Done; } } else { @@ -930,7 +930,7 @@ static void StartExpDefine (MacExp* E) if (CurTok.Tok == TOK_COMMA) { NextTok (); } else { - Error ("`,' expected"); + Error ("',' expected"); } } } diff --git a/src/ca65/main.c b/src/ca65/main.c index fbca2beac..33e0a74b5 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -168,7 +168,7 @@ static void NewSymbol (const char* SymName, long Val) /* Check if have already a symbol with this name */ if (SymIsDef (Sym)) { - AbEnd ("`%s' is already defined", SymName); + AbEnd ("'%s' is already defined", SymName); } /* Generate an expression for the symbol */ @@ -201,7 +201,7 @@ static void SetSys (const char* Sys) break; case TGT_MODULE: - AbEnd ("Cannot use `module' as a target for the assembler"); + AbEnd ("Cannot use 'module' as a target for the assembler"); break; case TGT_ATARI2600: @@ -331,7 +331,7 @@ static void SetSys (const char* Sys) break; default: - AbEnd ("Invalid target name: `%s'", Sys); + AbEnd ("Invalid target name: '%s'", Sys); } @@ -346,7 +346,7 @@ static void FileNameOption (const char* Opt, const char* Arg, StrBuf* Name) { /* Cannot have the option twice */ if (SB_NotEmpty (Name)) { - AbEnd ("Cannot use option `%s' twice", Opt); + AbEnd ("Cannot use option '%s' twice", Opt); } /* Remember the file name for later */ SB_CopyStr (Name, Arg); @@ -427,7 +427,7 @@ static void OptCPU (const char* Opt attribute ((unused)), const char* Arg) { cpu_t CPU = FindCPU (Arg); if (CPU == CPU_UNKNOWN) { - AbEnd ("Invalid CPU: `%s'", Arg); + AbEnd ("Invalid CPU: '%s'", Arg); } else { SetCPU (CPU); } @@ -478,7 +478,7 @@ static void OptFeature (const char* Opt attribute ((unused)), const char* Arg) /* Set the feature, check for errors */ if (SetFeature (SB_InitFromString (&Feature, Arg)) == FEAT_UNKNOWN) { - AbEnd ("Illegal emulation feature: `%s'", Arg); + AbEnd ("Illegal emulation feature: '%s'", Arg); } } @@ -533,7 +533,7 @@ static void OptListBytes (const char* Opt, const char* Arg) /* Check the bounds */ if (Num != 0 && (Num < MIN_LIST_BYTES || Num > MAX_LIST_BYTES)) { - AbEnd ("Argument for option `%s' is out of range", Opt); + AbEnd ("Argument for option '%s' is out of range", Opt); } /* Use the value */ @@ -549,7 +549,7 @@ static void OptListing (const char* Opt, const char* Arg) ** the filename is empty or begins with the option char. */ if (Arg == 0 || *Arg == '\0' || *Arg == '-') { - Fatal ("The meaning of `%s' has changed. It does now " + Fatal ("The meaning of '%s' has changed. It does now " "expect a file name as argument.", Opt); } @@ -566,7 +566,7 @@ static void OptMemoryModel (const char* Opt, const char* Arg) /* Check the current memory model */ if (MemoryModel != MMODEL_UNKNOWN) { - AbEnd ("Cannot use option `%s' twice", Opt); + AbEnd ("Cannot use option '%s' twice", Opt); } /* Translate the memory model name and check it */ @@ -762,7 +762,7 @@ static void OneLine (void) */ if (CurTok.Tok != TOK_COLON) { if (HadWS || !NoColonLabels) { - Error ("`:' expected"); + Error ("':' expected"); /* Try some smart error recovery */ if (CurTok.Tok == TOK_NAMESPACE) { NextTok (); @@ -807,7 +807,7 @@ static void OneLine (void) } else if (PCAssignment && (CurTok.Tok == TOK_STAR || CurTok.Tok == TOK_PC)) { NextTok (); if (CurTok.Tok != TOK_EQ) { - Error ("`=' expected"); + Error ("'=' expected"); SkipUntilSep (); } else { /* Skip the equal sign */ @@ -1040,7 +1040,7 @@ int main (int argc, char* argv []) } else { /* Filename. Check if we already had one */ if (InFile) { - fprintf (stderr, "%s: Don't know what to do with `%s'\n", + fprintf (stderr, "%s: Don't know what to do with '%s'\n", ProgName, Arg); exit (EXIT_FAILURE); } else { diff --git a/src/ca65/nexttok.c b/src/ca65/nexttok.c index 1521ed0c2..54733740e 100644 --- a/src/ca65/nexttok.c +++ b/src/ca65/nexttok.c @@ -179,7 +179,7 @@ static void FuncConcat (void) ** by the string token just created. */ if (CurTok.Tok != TOK_RPAREN) { - Error ("`)' expected"); + Error ("')' expected"); } else { CurTok.Tok = TOK_STRCON; SB_Copy (&CurTok.SVal, &Buf); @@ -253,7 +253,7 @@ static void FuncIdent (void) SB_Copy (&Buf, &CurTok.SVal); NextTok (); if (CurTok.Tok != TOK_RPAREN) { - Error ("`)' expected"); + Error ("')' expected"); } else { CurTok.Tok = Id; SB_Copy (&CurTok.SVal, &Buf); @@ -600,7 +600,7 @@ static void FuncSPrintF (void) ** by the string token just created. */ if (CurTok.Tok != TOK_RPAREN) { - Error ("`)' expected"); + Error ("')' expected"); } else { CurTok.Tok = TOK_STRCON; SB_Copy (&CurTok.SVal, &R); @@ -660,7 +660,7 @@ static void FuncString (void) ** by the string token just created. */ if (CurTok.Tok != TOK_RPAREN) { - Error ("`)' expected"); + Error ("')' expected"); } else { CurTok.Tok = TOK_STRCON; SB_Copy (&CurTok.SVal, &Buf); @@ -754,7 +754,7 @@ void ConsumeSep (void) void ConsumeLParen (void) /* Consume a left paren */ { - Consume (TOK_LPAREN, "`(' expected"); + Consume (TOK_LPAREN, "'(' expected"); } @@ -762,7 +762,7 @@ void ConsumeLParen (void) void ConsumeRParen (void) /* Consume a right paren */ { - Consume (TOK_RPAREN, "`)' expected"); + Consume (TOK_RPAREN, "')' expected"); } @@ -770,7 +770,7 @@ void ConsumeRParen (void) void ConsumeComma (void) /* Consume a comma */ { - Consume (TOK_COMMA, "`,' expected"); + Consume (TOK_COMMA, "',' expected"); } diff --git a/src/ca65/objfile.c b/src/ca65/objfile.c index dfa0d146e..b475d15df 100644 --- a/src/ca65/objfile.c +++ b/src/ca65/objfile.c @@ -113,7 +113,7 @@ static void ObjWriteError (void) remove (OutFile); /* Now abort with a fatal error */ - Fatal ("Cannot write to output file `%s': %s", OutFile, strerror (Error)); + Fatal ("Cannot write to output file '%s': %s", OutFile, strerror (Error)); } @@ -170,7 +170,7 @@ void ObjOpen (void) /* Create the output file */ F = fopen (OutFile, "w+b"); if (F == 0) { - Fatal ("Cannot open output file `%s': %s", OutFile, strerror (errno)); + Fatal ("Cannot open output file '%s': %s", OutFile, strerror (errno)); } /* Write a dummy header */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index a1115606b..a0eb28699 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -167,13 +167,13 @@ static void SetBoolOption (unsigned char* Flag) switch (GetSubKey (Keys, sizeof (Keys) / sizeof (Keys [0]))) { case 0: *Flag = 0; NextTok (); break; case 1: *Flag = 1; NextTok (); break; - default: ErrorSkip ("`on' or `off' expected"); break; + default: ErrorSkip ("'on' or 'off' expected"); break; } } else if (TokIsSep (CurTok.Tok)) { /* Without anything assume switch on */ *Flag = 1; } else { - ErrorSkip ("`on' or `off' expected"); + ErrorSkip ("'on' or 'off' expected"); } } @@ -1017,7 +1017,7 @@ static void DoFeature (void) /* Set the feature and check for errors */ if (SetFeature (&CurTok.SVal) == FEAT_UNKNOWN) { /* Not found */ - ErrorSkip ("Invalid feature: `%m%p'", &CurTok.SVal); + ErrorSkip ("Invalid feature: '%m%p'", &CurTok.SVal); return; } else { /* Skip the keyword */ @@ -1242,7 +1242,7 @@ static void DoIncBin (void) char* PathName = SearchFile (BinSearchPath, SB_GetConstBuf (&Name)); if (PathName == 0 || (F = fopen (PathName, "rb")) == 0) { /* Not found or cannot open, print an error and bail out */ - ErrorSkip ("Cannot open include file `%m%p': %s", &Name, strerror (errno)); + ErrorSkip ("Cannot open include file '%m%p': %s", &Name, strerror (errno)); xfree (PathName); goto ExitPoint; } @@ -1268,7 +1268,7 @@ static void DoIncBin (void) */ SB_Terminate (&Name); if (FileStat (SB_GetConstBuf (&Name), &StatBuf) != 0) { - Fatal ("Cannot stat input file `%m%p': %s", &Name, strerror (errno)); + Fatal ("Cannot stat input file '%m%p': %s", &Name, strerror (errno)); } /* Add the file to the input file table */ @@ -1305,7 +1305,7 @@ static void DoIncBin (void) size_t BytesRead = fread (Buf, 1, BytesToRead, F); if (BytesToRead != BytesRead) { /* Some sort of error */ - ErrorSkip ("Cannot read from include file `%m%p': %s", + ErrorSkip ("Cannot read from include file '%m%p': %s", &Name, strerror (errno)); break; } @@ -1896,7 +1896,7 @@ static void DoUnDef (void) static void DoUnexpected (void) /* Got an unexpected keyword */ { - Error ("Unexpected `%m%p'", &Keyword); + Error ("Unexpected '%m%p'", &Keyword); SkipUntilSep (); } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 7c291666c..39911b478 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -501,7 +501,7 @@ int NewInputFile (const char* Name) /* Main file */ F = fopen (Name, "r"); if (F == 0) { - Fatal ("Cannot open input file `%s': %s", Name, strerror (errno)); + Fatal ("Cannot open input file '%s': %s", Name, strerror (errno)); } } else { /* We are on include level. Search for the file in the include @@ -510,7 +510,7 @@ int NewInputFile (const char* Name) PathName = SearchFile (IncSearchPath, Name); if (PathName == 0 || (F = fopen (PathName, "r")) == 0) { /* Not found or cannot open, print an error and bail out */ - Error ("Cannot open include file `%s': %s", Name, strerror (errno)); + Error ("Cannot open include file '%s': %s", Name, strerror (errno)); goto ExitPoint; } @@ -527,7 +527,7 @@ int NewInputFile (const char* Name) ** here. */ if (FileStat (Name, &Buf) != 0) { - Fatal ("Cannot stat input file `%s': %s", Name, strerror (errno)); + Fatal ("Cannot stat input file '%s': %s", Name, strerror (errno)); } /* Add the file to the input file table and remember the index */ @@ -1054,7 +1054,7 @@ Again: /* Not found */ if (!LeadingDotInIdents) { /* Invalid pseudo instruction */ - Error ("`%m%p' is not a recognized control command", &CurTok.SVal); + Error ("'%m%p' is not a recognized control command", &CurTok.SVal); goto Again; } diff --git a/src/ca65/segment.c b/src/ca65/segment.c index 35a41ffe1..aa9a48512 100644 --- a/src/ca65/segment.c +++ b/src/ca65/segment.c @@ -134,7 +134,7 @@ static Segment* NewSegment (const char* Name, unsigned char AddrSize) /* Check the segment name for invalid names */ if (!ValidSegName (Name)) { - Error ("Illegal segment name: `%s'", Name); + Error ("Illegal segment name: '%s'", Name); } /* Create a new segment and return it */ diff --git a/src/ca65/struct.c b/src/ca65/struct.c index 195f29ba4..5ea7a18ec 100644 --- a/src/ca65/struct.c +++ b/src/ca65/struct.c @@ -261,9 +261,9 @@ static long DoStructInternal (long Offs, unsigned Type) /* End of struct/union definition */ if (Type == STRUCT) { - Consume (TOK_ENDSTRUCT, "`.ENDSTRUCT' expected"); + Consume (TOK_ENDSTRUCT, "'.ENDSTRUCT' expected"); } else { - Consume (TOK_ENDUNION, "`.ENDUNION' expected"); + Consume (TOK_ENDUNION, "'.ENDUNION' expected"); } /* Return the size of the struct */ diff --git a/src/ca65/studyexpr.c b/src/ca65/studyexpr.c index 366b50ff1..90d2d6e18 100644 --- a/src/ca65/studyexpr.c +++ b/src/ca65/studyexpr.c @@ -524,7 +524,7 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D) if (SymHasUserMark (Sym)) { LIError (&Sym->DefLines, - "Circular reference in definition of symbol `%m%p'", + "Circular reference in definition of symbol '%m%p'", GetSymName (Sym)); ED_SetError (D); } else { diff --git a/src/ca65/symbol.c b/src/ca65/symbol.c index 0b02aab45..3b06fd1a2 100644 --- a/src/ca65/symbol.c +++ b/src/ca65/symbol.c @@ -95,7 +95,7 @@ SymTable* ParseScopedIdent (StrBuf* Name, StrBuf* FullName) if (Scope == 0) { /* Scope not found */ SB_Terminate (FullName); - Error ("No such scope: `%m%p'", FullName); + Error ("No such scope: '%m%p'", FullName); return 0; } @@ -139,7 +139,7 @@ SymTable* ParseScopedIdent (StrBuf* Name, StrBuf* FullName) Scope = SymFindScope (Scope, Name, SYM_FIND_EXISTING); if (Scope == 0) { /* Scope not found */ - Error ("No such scope: `%m%p'", FullName); + Error ("No such scope: '%m%p'", FullName); return 0; } diff --git a/src/ca65/symentry.c b/src/ca65/symentry.c index 06c537cf6..cf789da5e 100644 --- a/src/ca65/symentry.c +++ b/src/ca65/symentry.c @@ -213,24 +213,24 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags { if (S->Flags & SF_IMPORT) { /* Defined symbol is marked as imported external symbol */ - Error ("Symbol `%m%p' is already an import", GetSymName (S)); + Error ("Symbol '%m%p' is already an import", GetSymName (S)); return; } if ((Flags & SF_VAR) != 0 && (S->Flags & (SF_EXPORT | SF_GLOBAL))) { /* Variable symbols cannot be exports or globals */ - Error ("Var symbol `%m%p' cannot be an export or global symbol", GetSymName (S)); + Error ("Var symbol '%m%p' cannot be an export or global symbol", GetSymName (S)); return; } if (S->Flags & SF_DEFINED) { /* Multiple definition. In case of a variable, this is legal. */ if ((S->Flags & SF_VAR) == 0) { - Error ("Symbol `%m%p' is already defined", GetSymName (S)); + Error ("Symbol '%m%p' is already defined", GetSymName (S)); S->Flags |= SF_MULTDEF; return; } else { /* Redefinition must also be a variable symbol */ if ((Flags & SF_VAR) == 0) { - Error ("Symbol `%m%p' is already different kind", GetSymName (S)); + Error ("Symbol '%m%p' is already different kind", GetSymName (S)); return; } /* Delete the current symbol expression, since it will get @@ -285,7 +285,7 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags S->ExportSize = S->AddrSize; } else if (S->AddrSize > S->ExportSize) { /* We're exporting a symbol smaller than it actually is */ - Warning (1, "Symbol `%m%p' is %s but exported %s", + Warning (1, "Symbol '%m%p' is %s but exported %s", GetSymName (S), AddrSizeToStr (S->AddrSize), AddrSizeToStr (S->ExportSize)); } @@ -315,13 +315,13 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags) /* Mark the given symbol as an imported symbol */ { if (S->Flags & SF_DEFINED) { - Error ("Symbol `%m%p' is already defined", GetSymName (S)); + Error ("Symbol '%m%p' is already defined", GetSymName (S)); S->Flags |= SF_MULTDEF; return; } if (S->Flags & SF_EXPORT) { /* The symbol is already marked as exported symbol */ - Error ("Cannot import exported symbol `%m%p'", GetSymName (S)); + Error ("Cannot import exported symbol '%m%p'", GetSymName (S)); return; } @@ -337,16 +337,16 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags) */ if (S->Flags & SF_IMPORT) { if ((Flags & SF_FORCED) != (S->Flags & SF_FORCED)) { - Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S)); + Error ("Redeclaration mismatch for symbol '%m%p'", GetSymName (S)); } if (AddrSize != S->AddrSize) { - Error ("Address size mismatch for symbol `%m%p'", GetSymName (S)); + Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); } } if (S->Flags & SF_GLOBAL) { S->Flags &= ~SF_GLOBAL; if (AddrSize != S->AddrSize) { - Error ("Address size mismatch for symbol `%m%p'", GetSymName (S)); + Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); } } @@ -369,12 +369,12 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags) /* Check if it's ok to export the symbol */ if (S->Flags & SF_IMPORT) { /* The symbol is already marked as imported external symbol */ - Error ("Symbol `%m%p' is already an import", GetSymName (S)); + Error ("Symbol '%m%p' is already an import", GetSymName (S)); return; } if (S->Flags & SF_VAR) { /* Variable symbols cannot be exported */ - Error ("Var symbol `%m%p' cannot be exported", GetSymName (S)); + Error ("Var symbol '%m%p' cannot be exported", GetSymName (S)); return; } @@ -383,7 +383,7 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags) */ if (S->Flags & SF_GLOBAL) { if (AddrSize != S->ExportSize) { - Error ("Address size mismatch for symbol `%m%p'", GetSymName (S)); + Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); } S->Flags &= ~SF_GLOBAL; @@ -398,7 +398,7 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags) */ if ((S->Flags & (SF_EXPORT|SF_DEFINED)) == SF_EXPORT) { if (S->ExportSize != AddrSize) { - Error ("Address size mismatch for symbol `%m%p'", GetSymName (S)); + Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); } } S->ExportSize = AddrSize; @@ -412,7 +412,7 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags) S->ExportSize = S->AddrSize; } else if (S->AddrSize > S->ExportSize) { /* We're exporting a symbol smaller than it actually is */ - Warning (1, "Symbol `%m%p' is %s but exported %s", + Warning (1, "Symbol '%m%p' is %s but exported %s", GetSymName (S), AddrSizeToStr (S->AddrSize), AddrSizeToStr (S->ExportSize)); } @@ -434,7 +434,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags) { if (S->Flags & SF_VAR) { /* Variable symbols cannot be exported or imported */ - Error ("Var symbol `%m%p' cannot be made global", GetSymName (S)); + Error ("Var symbol '%m%p' cannot be made global", GetSymName (S)); return; } @@ -447,7 +447,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags) AddrSize = GetCurrentSegAddrSize (); } if (AddrSize != S->AddrSize) { - Error ("Address size mismatch for symbol `%m%p'", GetSymName (S)); + Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); } return; } @@ -459,12 +459,12 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags) if ((S->Flags & SF_DEFINED) == 0) { /* Symbol is undefined */ if (AddrSize != S->ExportSize) { - Error ("Address size mismatch for symbol `%m%p'", GetSymName (S)); + Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); } } else if (AddrSize != ADDR_SIZE_DEFAULT) { /* Symbol is defined and address size given */ if (AddrSize != S->ExportSize) { - Error ("Address size mismatch for symbol `%m%p'", GetSymName (S)); + Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); } } return; @@ -476,7 +476,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags) */ if (S->Flags & SF_GLOBAL) { if (AddrSize != S->ExportSize) { - Error ("Address size mismatch for symbol `%m%p'", GetSymName (S)); + Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); } return; } @@ -494,7 +494,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags) S->ExportSize = S->AddrSize; } else if (S->AddrSize > S->ExportSize) { /* We're exporting a symbol smaller than it actually is */ - Warning (1, "Symbol `%m%p' is %s but exported %s", + Warning (1, "Symbol '%m%p' is %s but exported %s", GetSymName (S), AddrSizeToStr (S->AddrSize), AddrSizeToStr (S->ExportSize)); } @@ -537,12 +537,12 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri /* Check for errors */ if (S->Flags & SF_IMPORT) { /* The symbol is already marked as imported external symbol */ - Error ("Symbol `%m%p' is already an import", GetSymName (S)); + Error ("Symbol '%m%p' is already an import", GetSymName (S)); return; } if (S->Flags & SF_VAR) { /* Variable symbols cannot be exported or imported */ - Error ("Var symbol `%m%p' cannot be exported", GetSymName (S)); + Error ("Var symbol '%m%p' cannot be exported", GetSymName (S)); return; } @@ -552,7 +552,7 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri */ if (S->Flags & (SF_EXPORT | SF_GLOBAL)) { if (S->ExportSize != AddrSize) { - Error ("Address size mismatch for symbol `%m%p'", GetSymName (S)); + Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); } S->Flags &= ~SF_GLOBAL; } @@ -566,7 +566,7 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri /* Use the real size of the symbol */ S->ExportSize = S->AddrSize; } else if (S->AddrSize != S->ExportSize) { - Error ("Address size mismatch for symbol `%m%p'", GetSymName (S)); + Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); } } @@ -575,7 +575,7 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri */ if (S->ConDesPrio[Type] != CD_PRIO_NONE) { if (S->ConDesPrio[Type] != Prio) { - Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S)); + Error ("Redeclaration mismatch for symbol '%m%p'", GetSymName (S)); } } S->ConDesPrio[Type] = Prio; diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c index 35d5a8066..afe7b3ad6 100644 --- a/src/ca65/symtab.c +++ b/src/ca65/symtab.c @@ -178,7 +178,7 @@ static SymTable* NewSymTable (SymTable* Parent, const StrBuf* Name) } } else { /* Duplicate scope name */ - Internal ("Duplicate scope name: `%m%p'", Name); + Internal ("Duplicate scope name: '%m%p'", Name); } } } @@ -216,7 +216,7 @@ void SymEnterLevel (const StrBuf* ScopeName, unsigned char Type, /* Check if the scope has been defined before */ if (CurrentScope->Flags & ST_DEFINED) { - Error ("Duplicate scope `%m%p'", ScopeName); + Error ("Duplicate scope '%m%p'", ScopeName); } } else { @@ -502,7 +502,7 @@ static void SymCheckUndefined (SymEntry* S) if (Sym->Flags & SF_IMPORT) { /* The symbol is already marked as import */ LIError (&S->RefLines, - "Symbol `%s' is already an import", + "Symbol '%s' is already an import", GetString (Sym->Name)); } if ((Sym->Flags & SF_EXPORT) == 0) { @@ -516,7 +516,7 @@ static void SymCheckUndefined (SymEntry* S) if (Sym->AddrSize > Sym->ExportSize) { /* We're exporting a symbol smaller than it actually is */ LIWarning (&Sym->DefLines, 1, - "Symbol `%m%p' is %s but exported %s", + "Symbol '%m%p' is %s but exported %s", GetSymName (Sym), AddrSizeToStr (Sym->AddrSize), AddrSizeToStr (Sym->ExportSize)); @@ -541,7 +541,7 @@ static void SymCheckUndefined (SymEntry* S) if (S->Flags & SF_EXPORT) { /* We will not auto-import an export */ LIError (&S->RefLines, - "Exported symbol `%m%p' was never defined", + "Exported symbol '%m%p' was never defined", GetSymName (S)); } else { if (AutoImport) { @@ -554,7 +554,7 @@ static void SymCheckUndefined (SymEntry* S) } else { /* Error */ LIError (&S->RefLines, - "Symbol `%m%p' is undefined", + "Symbol '%m%p' is undefined", GetSymName (S)); } } @@ -616,7 +616,7 @@ void SymCheck (void) ReleaseFullLineInfo (&S->RefLines); } else if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) { LIWarning (&S->DefLines, 2, - "Symbol `%m%p' is defined but never used", + "Symbol '%m%p' is defined but never used", GetSymName (S)); } @@ -625,7 +625,7 @@ void SymCheck (void) if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) { /* Imported symbol is not referenced */ LIWarning (&S->DefLines, 2, - "Symbol `%m%p' is imported but never used", + "Symbol '%m%p' is imported but never used", GetSymName (S)); } else { /* Give the import an id, count imports */ @@ -653,7 +653,7 @@ void SymCheck (void) } else if (S->AddrSize > S->ExportSize) { /* We're exporting a symbol smaller than it actually is */ LIWarning (&S->DefLines, 1, - "Symbol `%m%p' is %s but exported %s", + "Symbol '%m%p' is %s but exported %s", GetSymName (S), AddrSizeToStr (S->AddrSize), AddrSizeToStr (S->ExportSize)); @@ -673,7 +673,7 @@ void SymCheck (void) const FilePos* P = S->GuessedUse[S->AddrSize - 1]; if (P) { PWarning (P, 0, - "Didn't use %s addressing for `%m%p'", + "Didn't use %s addressing for '%m%p'", AddrSizeToStr (S->AddrSize), GetSymName (S)); } diff --git a/src/cc65/asmstmt.c b/src/cc65/asmstmt.c index 1fc4e3167..ae4308522 100644 --- a/src/cc65/asmstmt.c +++ b/src/cc65/asmstmt.c @@ -102,7 +102,7 @@ static SymEntry* AsmGetSym (unsigned Arg, unsigned Type) /* Did we find a symbol with this name? */ if (Sym == 0) { - Error ("Undefined symbol `%s' for argument %u", CurTok.Ident, Arg); + Error ("Undefined symbol '%s' for argument %u", CurTok.Ident, Arg); AsmErrorSkip (); return 0; } diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index e9d98f5b8..972d48f6a 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -461,7 +461,7 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) ** use and change all registers. */ if (Debug) { - fprintf (stderr, "No info about internal function `%s'\n", Name); + fprintf (stderr, "No info about internal function '%s'\n", Name); } *Use = REG_ALL; *Chg = REG_ALL; diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 3116539dc..575398c11 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -981,7 +981,7 @@ static OptFunc* GetOptFunc (const char* Name) OptFunc* F = FindOptFunc (Name); if (F == 0) { /* Not found */ - AbEnd ("Optimization step `%s' not found", Name); + AbEnd ("Optimization step '%s' not found", Name); } return F; } @@ -1168,10 +1168,10 @@ static void WriteDebugOutput (CodeSeg* S, const char* Step) /* Output a header line */ if (Step == 0) { /* Initial output */ - WriteOutput ("Initial code for function `%s':\n", + WriteOutput ("Initial code for function '%s':\n", S->Func? S->Func->Name : "<global>"); } else { - WriteOutput ("Code after applying `%s':\n", Step); + WriteOutput ("Code after applying '%s':\n", Step); } /* Output the code segment */ @@ -1512,7 +1512,7 @@ void RunOpt (CodeSeg* S) /* Print the name of the function we are working on */ if (S->Func) { - Print (stdout, 1, "Running optimizer for function `%s'\n", S->Func->Name); + Print (stdout, 1, "Running optimizer for function '%s'\n", S->Func->Name); } else { Print (stdout, 1, "Running optimizer for global code segment\n"); } diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index a808a26f7..ba759988b 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -317,12 +317,12 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) /* Expect zp x indirect */ L = SkipSpace (L+1); if (toupper (*L) != 'X') { - Error ("ASM code error: `X' expected"); + Error ("ASM code error: 'X' expected"); return 0; } L = SkipSpace (L+1); if (*L != ')') { - Error ("ASM code error: `)' expected"); + Error ("ASM code error: ')' expected"); return 0; } L = SkipSpace (L+1); @@ -337,7 +337,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) if (*L == ',') { L = SkipSpace (L+1); if (toupper (*L) != 'Y') { - Error ("ASM code error: `Y' expected"); + Error ("ASM code error: 'Y' expected"); return 0; } L = SkipSpace (L+1); @@ -378,7 +378,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) /* Check for subroutine call to local label */ if ((OPC->Info & OF_CALL) && IsLocalLabelName (Arg)) { Error ("ASM code error: " - "Cannot use local label `%s' in subroutine call", + "Cannot use local label '%s' in subroutine call", Arg); } AM = AM65_ABS; @@ -532,7 +532,7 @@ void CS_AddVLine (CodeSeg* S, LineInfo* LI, const char* Format, va_list ap) case '.': /* Control instruction */ ReadToken (L, " \t", Token, sizeof (Token)); - Error ("ASM code error: Pseudo instruction `%s' not supported", Token); + Error ("ASM code error: Pseudo instruction '%s' not supported", Token); break; default: @@ -780,7 +780,7 @@ CodeLabel* CS_AddLabel (CodeSeg* S, const char* Name) if (L) { /* We found it - be sure it does not already have an owner */ if (L->Owner) { - Error ("ASM label `%s' is already defined", Name); + Error ("ASM label '%s' is already defined", Name); return L; } } else { @@ -790,7 +790,7 @@ CodeLabel* CS_AddLabel (CodeSeg* S, const char* Name) /* Safety. This call is quite costly, but safety is better */ if (CollIndex (&S->Labels, L) >= 0) { - Error ("ASM label `%s' is already defined", Name); + Error ("ASM label '%s' is already defined", Name); return L; } @@ -906,7 +906,7 @@ void CS_MergeLabels (CodeSeg* S) /* Print some debugging output */ if (Debug) { - printf ("Removing unused global label `%s'", X->Name); + printf ("Removing unused global label '%s'", X->Name); } /* And free the label */ diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d79ef350b..9cc7f9641 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -192,7 +192,7 @@ static void Parse (void) /* This is a definition */ if (SymIsDef (Entry)) { - Error ("Global variable `%s' has already been defined", + Error ("Global variable '%s' has already been defined", Entry->Name); } Entry->Flags |= SC_DEF; @@ -204,11 +204,11 @@ static void Parse (void) if (!IsTypeVoid (Decl.Type)) { if (!IsTypeArray (Decl.Type)) { /* Size is unknown and not an array */ - Error ("Variable `%s' has unknown size", Decl.Ident); + Error ("Variable '%s' has unknown size", Decl.Ident); } } else if (IS_Get (&Standard) != STD_CC65) { /* We cannot declare variables of type void */ - Error ("Illegal type for variable `%s'", Decl.Ident); + Error ("Illegal type for variable '%s'", Decl.Ident); } } @@ -234,12 +234,12 @@ static void Parse (void) if (IsTypeVoid (Decl.Type)) { /* We cannot declare variables of type void */ - Error ("Illegal type for variable `%s'", Decl.Ident); + Error ("Illegal type for variable '%s'", Decl.Ident); Entry->Flags &= ~(SC_STORAGE | SC_DEF); } else if (Size == 0) { /* Size is unknown. Is it an array? */ if (!IsTypeArray (Decl.Type)) { - Error ("Variable `%s' has unknown size", Decl.Ident); + Error ("Variable '%s' has unknown size", Decl.Ident); } Entry->Flags &= ~(SC_STORAGE | SC_DEF); } else { @@ -256,7 +256,7 @@ static void Parse (void) const char* bssName = GetSegName (SEG_BSS); if (Entry->V.BssName && strcmp (Entry->V.BssName, bssName) != 0) { - Error ("Global variable `%s' already was defined in the `%s' segment.", + Error ("Global variable '%s' already was defined in the '%s' segment.", Entry->Name, Entry->V.BssName); } Entry->V.BssName = xstrdup (bssName); @@ -286,7 +286,7 @@ static void Parse (void) /* Function body. Check for duplicate function definitions */ if (SymIsDef (Entry)) { - Error ("Body for function `%s' has already been defined", + Error ("Body for function '%s' has already been defined", Entry->Name); } diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 19100781c..e3b5edfec 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -102,7 +102,7 @@ static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers); static void DuplicateQualifier (const char* Name) /* Print an error message */ { - Warning ("Duplicate qualifier: `%s'", Name); + Warning ("Duplicate qualifier: '%s'", Name); } @@ -551,7 +551,7 @@ static SymEntry* StructOrUnionForwardDecl (const char* Name, unsigned Type) Entry = AddStructSym (Name, Type, 0, 0); } else if ((Entry->Flags & SC_TYPEMASK) != Type) { /* Already defined, but no struct */ - Error ("Symbol `%s' is already different kind", Name); + Error ("Symbol '%s' is already different kind", Name); } return Entry; } @@ -1070,7 +1070,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers) Entry = FindTagSym (CurTok.Ident); if (Entry) { if (SymIsLocal (Entry) && (Entry->Flags & SC_ENUM) == 0) { - Error ("Symbol `%s' is already different kind", Entry->Name); + Error ("Symbol '%s' is already different kind", Entry->Name); } } else { /* Insert entry into table ### */ @@ -1211,10 +1211,10 @@ static void ParseOldStyleParamList (FuncDesc* F) Sym->Flags &= ~SC_DEFTYPE; } else { /* Type has already been changed */ - Error ("Redefinition for parameter `%s'", Sym->Name); + Error ("Redefinition for parameter '%s'", Sym->Name); } } else { - Error ("Unknown identifier: `%s'", Decl.Ident); + Error ("Unknown identifier: '%s'", Decl.Ident); } } @@ -1291,7 +1291,7 @@ static void ParseAnsiParamList (FuncDesc* F) /* If the parameter is a struct or union, emit a warning */ if (IsClassStruct (Decl.Type)) { if (IS_Get (&WarnStructParam)) { - Warning ("Passing struct by value for parameter `%s'", Decl.Ident); + Warning ("Passing struct by value for parameter '%s'", Decl.Ident); } } @@ -1512,7 +1512,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) ConstAbsIntExpr (hie1, &Expr); if (Expr.IVal <= 0) { if (D->Ident[0] != '\0') { - Error ("Size of array `%s' is invalid", D->Ident); + Error ("Size of array '%s' is invalid", D->Ident); } else { Error ("Size of array is invalid"); } @@ -1534,16 +1534,16 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* If we have remaining qualifiers, flag them as invalid */ if (Qualifiers & T_QUAL_NEAR) { - Error ("Invalid `__near__' qualifier"); + Error ("Invalid '__near__' qualifier"); } if (Qualifiers & T_QUAL_FAR) { - Error ("Invalid `__far__' qualifier"); + Error ("Invalid '__far__' qualifier"); } if (Qualifiers & T_QUAL_FASTCALL) { - Error ("Invalid `__fastcall__' qualifier"); + Error ("Invalid '__fastcall__' qualifier"); } if (Qualifiers & T_QUAL_CDECL) { - Error ("Invalid `__cdecl__' qualifier"); + Error ("Invalid '__cdecl__' qualifier"); } } @@ -1637,7 +1637,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) ** have the C89 standard enabled explicitly. */ if (IS_Get (&Standard) >= STD_C99) { - Warning ("Implicit `int' return type is an obsolete feature"); + Warning ("Implicit 'int' return type is an obsolete feature"); } GetFuncDesc (D->Type)->Flags |= FD_OLDSTYLE_INTRET; } @@ -1653,7 +1653,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) ** for variables with implicit int type. */ if ((Spec->Flags & DS_DEF_TYPE) != 0 && IS_Get (&Standard) >= STD_C99) { - Warning ("Implicit `int' is an obsolete feature"); + Warning ("Implicit 'int' is an obsolete feature"); } } @@ -1662,7 +1662,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) unsigned Size = SizeOf (D->Type); if (Size >= 0x10000) { if (D->Ident[0] != '\0') { - Error ("Size of `%s' is invalid (0x%06X)", D->Ident, Size); + Error ("Size of '%s' is invalid (0x%06X)", D->Ident, Size); } else { Error ("Invalid size in declaration (0x%06X)", Size); } @@ -1735,7 +1735,7 @@ static unsigned OpeningCurlyBraces (unsigned BracesNeeded) NextToken (); } if (BraceCount < BracesNeeded) { - Error ("`{' expected"); + Error ("'{' expected"); } return BraceCount; } @@ -1755,7 +1755,7 @@ static void ClosingCurlyBraces (unsigned BracesExpected) NextToken (); NextToken (); } else { - Error ("`}' expected"); + Error ("'}' expected"); return; } --BracesExpected; diff --git a/src/cc65/declattr.c b/src/cc65/declattr.c index bdaea20d6..37048e69b 100644 --- a/src/cc65/declattr.c +++ b/src/cc65/declattr.c @@ -225,7 +225,7 @@ void ParseAttribute (Declaration* D) } else { /* Attribute not known, maybe typo */ - Error ("Illegal attribute: `%s'", AttrName); + Error ("Illegal attribute: '%s'", AttrName); /* Skip until end of attribute */ ErrorSkip (); diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 55c6391d2..320ac2321 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -791,9 +791,9 @@ static void Primary (ExprDesc* E) ** list and returning int. */ if (IS_Get (&Standard) >= STD_C99) { - Error ("Call to undefined function `%s'", Ident); + Error ("Call to undefined function '%s'", Ident); } else { - Warning ("Call to undefined function `%s'", Ident); + Warning ("Call to undefined function '%s'", Ident); } Sym = AddGlobalSym (Ident, GetImplicitFuncType(), SC_EXTERN | SC_REF | SC_FUNC); E->Type = Sym->Type; @@ -804,7 +804,7 @@ static void Primary (ExprDesc* E) Sym = AddLocalSym (Ident, type_int, SC_AUTO | SC_REF, 0); E->Flags = E_LOC_STACK | E_RTYPE_LVAL; E->Type = type_int; - Error ("Undefined symbol: `%s'", Ident); + Error ("Undefined symbol: '%s'", Ident); } } @@ -1174,7 +1174,7 @@ static void StructRef (ExprDesc* Expr) NextToken (); Field = FindStructField (Expr->Type, Ident); if (Field == 0) { - Error ("Struct/union has no field named `%s'", Ident); + Error ("Struct/union has no field named '%s'", Ident); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; @@ -2485,7 +2485,7 @@ static void parseadd (ExprDesc* Expr) typeadjust (Expr, &Expr2, 1); } else { /* OOPS */ - Error ("Invalid operands for binary operator `+'"); + Error ("Invalid operands for binary operator '+'"); } } else { @@ -2567,7 +2567,7 @@ static void parseadd (ExprDesc* Expr) } } else { /* OOPS */ - Error ("Invalid operands for binary operator `+'"); + Error ("Invalid operands for binary operator '+'"); flags = CF_INT; } @@ -2611,7 +2611,7 @@ static void parseadd (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } else { /* OOPS */ - Error ("Invalid operands for binary operator `+'"); + Error ("Invalid operands for binary operator '+'"); flags = CF_INT; } @@ -2653,7 +2653,7 @@ static void parseadd (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 0) & ~CF_CONST; } else { /* OOPS */ - Error ("Invalid operands for binary operator `+'"); + Error ("Invalid operands for binary operator '+'"); flags = CF_INT; } @@ -2689,7 +2689,7 @@ static void parsesub (ExprDesc* Expr) /* lhs cannot be function or pointer to function */ if (IsTypeFunc (Expr->Type) || IsTypeFuncPtr (Expr->Type)) { - Error ("Invalid left operand for binary operator `-'"); + Error ("Invalid left operand for binary operator '-'"); /* Make it pointer to char to avoid further errors */ Expr->Type = type_uchar; } @@ -2712,7 +2712,7 @@ static void parsesub (ExprDesc* Expr) /* rhs cannot be function or pointer to function */ if (IsTypeFunc (Expr2.Type) || IsTypeFuncPtr (Expr2.Type)) { - Error ("Invalid right operand for binary operator `-'"); + Error ("Invalid right operand for binary operator '-'"); /* Make it pointer to char to avoid further errors */ Expr2.Type = type_uchar; } @@ -2750,7 +2750,7 @@ static void parsesub (ExprDesc* Expr) Expr->IVal -= Expr2.IVal; } else { /* OOPS */ - Error ("Invalid operands for binary operator `-'"); + Error ("Invalid operands for binary operator '-'"); } /* Result is constant, condition codes not set */ @@ -2783,7 +2783,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } else { /* OOPS */ - Error ("Invalid operands for binary operator `-'"); + Error ("Invalid operands for binary operator '-'"); flags = CF_INT; } @@ -2837,7 +2837,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 0); } else { /* OOPS */ - Error ("Invalid operands for binary operator `-'"); + Error ("Invalid operands for binary operator '-'"); flags = CF_INT; } @@ -3304,7 +3304,7 @@ static void opeq (const GenDesc* Gen, ExprDesc* Expr, const char* Op) /* The rhs must be an integer (or a float, but we don't support that yet */ if (!IsClassInt (Expr2.Type)) { - Error ("Invalid right operand for binary operator `%s'", Op); + Error ("Invalid right operand for binary operator '%s'", Op); /* Continue. Wrong code will be generated, but the compiler won't ** break, so this is the best error recovery. */ @@ -3421,7 +3421,7 @@ static void addsubeq (const GenDesc* Gen, ExprDesc *Expr, const char* Op) */ hie1 (&Expr2); if (!IsClassInt (Expr2.Type)) { - Error ("Invalid right operand for binary operator `%s'", Op); + Error ("Invalid right operand for binary operator '%s'", Op); /* Continue. Wrong code will be generated, but the compiler won't ** break, so this is the best error recovery. */ diff --git a/src/cc65/function.c b/src/cc65/function.c index 97d6916ff..3256d7541 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -422,14 +422,14 @@ void NewFunc (SymEntry* Func) /* Main cannot be a fastcall function */ if (IsQualFastcall (Func->Type)) { - Error ("`main' cannot be declared as __fastcall__"); + Error ("'main' cannot be declared as __fastcall__"); } /* If cc65 extensions aren't enabled, don't allow a main function that ** doesn't return an int. */ if (IS_Get (&Standard) != STD_CC65 && CurrentFunc->ReturnType[0].C != T_INT) { - Error ("`main' must always return an int"); + Error ("'main' must always return an int"); } /* Add a forced import of a symbol that is contained in the startup diff --git a/src/cc65/hexval.c b/src/cc65/hexval.c index 37e43da14..ce4e33acf 100644 --- a/src/cc65/hexval.c +++ b/src/cc65/hexval.c @@ -54,7 +54,7 @@ unsigned HexVal (int C) */ { if (!IsXDigit (C)) { - Error ("Invalid hexadecimal digit: `%c'", C); + Error ("Invalid hexadecimal digit: '%c'", C); } if (IsDigit (C)) { return C - '0'; diff --git a/src/cc65/input.c b/src/cc65/input.c index 005e0c668..22a66e1f7 100644 --- a/src/cc65/input.c +++ b/src/cc65/input.c @@ -174,7 +174,7 @@ static AFile* NewAFile (IFile* IF, FILE* F) struct stat Buf; if (FileStat (IF->Name, &Buf) != 0) { /* Error */ - Fatal ("Cannot stat `%s': %s", IF->Name, strerror (errno)); + Fatal ("Cannot stat '%s': %s", IF->Name, strerror (errno)); } IF->Size = (unsigned long) Buf.st_size; IF->MTime = (unsigned long) Buf.st_mtime; @@ -251,7 +251,7 @@ void OpenMainFile (const char* Name) FILE* F = fopen (Name, "r"); if (F == 0) { /* Cannot open */ - Fatal ("Cannot open input file `%s': %s", Name, strerror (errno)); + Fatal ("Cannot open input file '%s': %s", Name, strerror (errno)); } /* Allocate a new AFile structure for the file */ @@ -284,7 +284,7 @@ void OpenIncludeFile (const char* Name, InputType IT) /* Search for the file */ N = SearchFile ((IT == IT_SYSINC)? SysIncSearchPath : UsrIncSearchPath, Name); if (N == 0) { - PPError ("Include file `%s' not found", Name); + PPError ("Include file '%s' not found", Name); return; } @@ -303,12 +303,12 @@ void OpenIncludeFile (const char* Name, InputType IT) F = fopen (IF->Name, "r"); if (F == 0) { /* Error opening the file */ - PPError ("Cannot open include file `%s': %s", IF->Name, strerror (errno)); + PPError ("Cannot open include file '%s': %s", IF->Name, strerror (errno)); return; } /* Debugging output */ - Print (stdout, 1, "Opened include file `%s'\n", IF->Name); + Print (stdout, 1, "Opened include file '%s'\n", IF->Name); /* Allocate a new AFile structure */ (void) NewAFile (IF, F); @@ -619,7 +619,7 @@ static void CreateDepFile (const char* Name, InputType Types) /* Open the file */ FILE* F = fopen (Name, "w"); if (F == 0) { - Fatal ("Cannot open dependency file `%s': %s", Name, strerror (errno)); + Fatal ("Cannot open dependency file '%s': %s", Name, strerror (errno)); } /* If a dependency target was given, use it, otherwise use the output diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 36afb6223..d0aab7f9c 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -143,7 +143,7 @@ static void ParseRegisterDecl (Declaration* Decl, int Reg) ** we cannot allow that here. */ if (ParseInit (Sym->Type) != Size) { - Error ("Cannot initialize flexible array members of storage class `register'"); + Error ("Cannot initialize flexible array members of storage class 'register'"); } /* Generate code to copy this data into the variable space */ @@ -171,7 +171,7 @@ static void ParseRegisterDecl (Declaration* Decl, int Reg) /* Cannot allocate a variable of zero size */ if (Size == 0) { - Error ("Variable `%s' has unknown size", Decl->Ident); + Error ("Variable '%s' has unknown size", Decl->Ident); } } @@ -356,7 +356,7 @@ static void ParseAutoDecl (Declaration* Decl) /* Cannot allocate a variable of zero size */ if (Size == 0) { - Error ("Variable `%s' has unknown size", Decl->Ident); + Error ("Variable '%s' has unknown size", Decl->Ident); } } @@ -410,7 +410,7 @@ static void ParseStaticDecl (Declaration* Decl) /* Cannot allocate a variable of zero size */ if (Size == 0) { - Error ("Variable `%s' has unknown size", Decl->Ident); + Error ("Variable '%s' has unknown size", Decl->Ident); } } diff --git a/src/cc65/macrotab.c b/src/cc65/macrotab.c index daf5cd7b8..09f0db50a 100644 --- a/src/cc65/macrotab.c +++ b/src/cc65/macrotab.c @@ -245,7 +245,7 @@ void AddMacroArg (Macro* M, const char* Arg) for (I = 0; I < CollCount (&M->FormalArgs); ++I) { if (strcmp (CollAtUnchecked (&M->FormalArgs, I), Arg) == 0) { /* Found */ - Error ("Duplicate macro parameter: `%s'", Arg); + Error ("Duplicate macro parameter: '%s'", Arg); break; } } diff --git a/src/cc65/main.c b/src/cc65/main.c index a98603dd8..871e21ebc 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -160,7 +160,7 @@ static void SetSys (const char* Sys) break; case TGT_MODULE: - AbEnd ("Cannot use `module' as a target for the compiler"); + AbEnd ("Cannot use 'module' as a target for the compiler"); break; case TGT_ATARI2600: @@ -300,7 +300,7 @@ static void FileNameOption (const char* Opt, const char* Arg, StrBuf* Name) { /* Cannot have the option twice */ if (SB_NotEmpty (Name)) { - AbEnd ("Cannot use option `%s' twice", Opt); + AbEnd ("Cannot use option '%s' twice", Opt); } /* A typo in OptTab[] might allow a NULL Arg */ if (Arg == 0) { @@ -362,7 +362,7 @@ static void CheckSegName (const char* Seg) { /* Print an error and abort if the name is not ok */ if (!ValidSegName (Seg)) { - AbEnd ("Segment name `%s' is invalid", Seg); + AbEnd ("Segment name '%s' is invalid", Seg); } } @@ -459,7 +459,7 @@ static void OptCPU (const char* Opt, const char* Arg) CPU = FindCPU (Arg); if (CPU != CPU_6502 && CPU != CPU_6502X && CPU != CPU_65SC02 && CPU != CPU_65C02 && CPU != CPU_65816 && CPU != CPU_HUC6280) { - AbEnd ("Invalid argument for %s: `%s'", Opt, Arg); + AbEnd ("Invalid argument for %s: '%s'", Opt, Arg); } } @@ -504,7 +504,7 @@ static void OptDebugOpt (const char* Opt attribute ((unused)), const char* Arg) /* Open the file */ FILE* F = fopen (Arg, "r"); if (F == 0) { - AbEnd ("Cannot open `%s': %s", Arg, strerror (errno)); + AbEnd ("Cannot open '%s': %s", Arg, strerror (errno)); } /* Read line by line, ignore empty lines and switch optimization @@ -675,7 +675,7 @@ static void OptMemoryModel (const char* Opt, const char* Arg) /* Check the current memory model */ if (MemoryModel != MMODEL_UNKNOWN) { - AbEnd ("Cannot use option `%s' twice", Opt); + AbEnd ("Cannot use option '%s' twice", Opt); } /* Translate the memory model name and check it */ @@ -739,7 +739,7 @@ static void OptStandard (const char* Opt, const char* Arg) /* Find the standard from the given name */ standard_t Std = FindStandard (Arg); if (Std == STD_UNKNOWN) { - AbEnd ("Invalid argument for %s: `%s'", Opt, Arg); + AbEnd ("Invalid argument for %s: '%s'", Opt, Arg); } else if (IS_Get (&Standard) != STD_UNKNOWN) { AbEnd ("Option %s given more than once", Opt); } else { @@ -1069,7 +1069,7 @@ int main (int argc, char* argv[]) /* Write the output to the file */ WriteAsmOutput (); - Print (stdout, 1, "Wrote output to `%s'\n", OutputFilename); + Print (stdout, 1, "Wrote output to '%s'\n", OutputFilename); /* Close the file, check for errors */ CloseOutputFile (); diff --git a/src/cc65/output.c b/src/cc65/output.c index e0b06ef99..6ce5334ca 100644 --- a/src/cc65/output.c +++ b/src/cc65/output.c @@ -102,9 +102,9 @@ void OpenOutputFile () /* Open the file */ OutputFile = fopen (OutputFilename, "w"); if (OutputFile == 0) { - Fatal ("Cannot open output file `%s': %s", OutputFilename, strerror (errno)); + Fatal ("Cannot open output file '%s': %s", OutputFilename, strerror (errno)); } - Print (stdout, 1, "Opened output file `%s'\n", OutputFilename); + Print (stdout, 1, "Opened output file '%s'\n", OutputFilename); } @@ -120,9 +120,9 @@ void OpenDebugOutputFile (const char* Name) /* Open the file */ OutputFile = fopen (Name, "w"); if (OutputFile == 0) { - Fatal ("Cannot open debug output file `%s': %s", Name, strerror (errno)); + Fatal ("Cannot open debug output file '%s': %s", Name, strerror (errno)); } - Print (stdout, 1, "Opened debug output file `%s'\n", Name); + Print (stdout, 1, "Opened debug output file '%s'\n", Name); } @@ -138,7 +138,7 @@ void CloseOutputFile () remove (OutputFilename); Fatal ("Cannot write to output file (disk full?)"); } - Print (stdout, 1, "Closed output file `%s'\n", OutputFilename); + Print (stdout, 1, "Closed output file '%s'\n", OutputFilename); OutputFile = 0; } diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 64ea4a1aa..1a24a08d9 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -356,7 +356,7 @@ static int BoolKeyword (StrBuf* Ident) } /* Error */ - Error ("Pragma argument must be one of `on', `off', `true' or `false'"); + Error ("Pragma argument must be one of 'on', 'off', 'true' or 'false'"); return 0; } @@ -453,7 +453,7 @@ static void SegNamePragma (StrBuf* B, segment_t Seg) } else { /* Segment name is invalid */ - Error ("Illegal segment name: `%s'", Name); + Error ("Illegal segment name: '%s'", Name); } @@ -788,7 +788,7 @@ static void ParsePragma (void) ** for unknown pragmas, but warn about them if enabled (the default). */ if (IS_Get (&WarnUnknownPragma)) { - Warning ("Unknown pragma `%s'", SB_GetConstBuf (&Ident)); + Warning ("Unknown pragma '%s'", SB_GetConstBuf (&Ident)); } goto ExitPoint; } diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index 99ce6acc1..1c4837d94 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -304,7 +304,7 @@ static void OldStyleComment (void) } } else { if (CurC == '/' && NextC == '*') { - PPWarning ("`/*' found inside a comment"); + PPWarning ("'/*' found inside a comment"); } NextChar (); } @@ -491,7 +491,7 @@ static void ReadMacroArgs (MacroExp* E) NewStyleComment (); } else if (CurC == '\0') { /* End of input inside macro argument list */ - PPError ("Unterminated argument list invoking macro `%s'", E->M->Name); + PPError ("Unterminated argument list invoking macro '%s'", E->M->Name); ClearLine (); break; @@ -611,7 +611,7 @@ static void MacroArgSubst (MacroExp* E) NextChar (); SkipWhitespace (0); if (!IsSym (Ident) || (ArgIdx = FindMacroArg (E->M, Ident)) < 0) { - PPError ("`#' is not followed by a macro parameter"); + PPError ("'#' is not followed by a macro parameter"); } else { /* Make a valid string from Replacement */ Arg = ME_GetActual (E, ArgIdx); @@ -782,7 +782,7 @@ static void DefineMacro (void) /* Ellipsis */ NextChar (); if (CurC != '.' || NextC != '.') { - PPError ("`...' expected"); + PPError ("'...' expected"); ClearLine (); return; } @@ -803,7 +803,7 @@ static void DefineMacro (void) /* __VA_ARGS__ is only allowed in C89 mode */ if (!C89 && strcmp (Ident, "__VA_ARGS__") == 0) { - PPWarning ("`__VA_ARGS__' can only appear in the expansion " + PPWarning ("'__VA_ARGS__' can only appear in the expansion " "of a C99 variadic macro"); } @@ -823,7 +823,7 @@ static void DefineMacro (void) /* Check for a right paren and eat it if we find one */ if (CurC != ')') { - PPError ("`)' expected"); + PPError ("')' expected"); ClearLine (); return; } @@ -900,7 +900,7 @@ static unsigned Pass1 (StrBuf* Source, StrBuf* Target) if (HaveParen) { SkipWhitespace (0); if (CurC != ')') { - PPError ("`)' expected"); + PPError ("')' expected"); } else { NextChar (); } @@ -1138,7 +1138,7 @@ static void DoInclude (void) break; default: - PPError ("`\"' or `<' expected"); + PPError ("'\"' or '<' expected"); goto Done; } NextChar (); @@ -1295,7 +1295,7 @@ void Preprocess (void) PPError ("Duplicate #else"); } } else { - PPError ("Unexpected `#else'"); + PPError ("Unexpected '#else'"); } break; @@ -1314,7 +1314,7 @@ void Preprocess (void) /* Remove the clause that needs a terminator */ Skip = (IfStack[IfIndex--] & IFCOND_SKIP) != 0; } else { - PPError ("Unexpected `#endif'"); + PPError ("Unexpected '#endif'"); } break; @@ -1387,7 +1387,7 @@ void Preprocess (void) } if (NextLine () == 0) { if (IfIndex >= 0) { - PPError ("`#endif' expected"); + PPError ("'#endif' expected"); } return; } diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 8605f55a5..695085e94 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -377,7 +377,7 @@ static void CharConst (void) /* Check for closing quote */ if (CurC != '\'') { - Error ("`\'' expected"); + Error ("'\'' expected"); } else { /* Skip the quote */ NextChar (); @@ -1044,7 +1044,7 @@ int Consume (token_t Token, const char* ErrorMsg) int ConsumeColon (void) /* Check for a colon and skip it. */ { - return Consume (TOK_COLON, "`:' expected"); + return Consume (TOK_COLON, "':' expected"); } @@ -1057,7 +1057,7 @@ int ConsumeSemi (void) NextToken (); return 1; } else { - Error ("`;' expected"); + Error ("';' expected"); if (CurTok.Tok == TOK_COLON || CurTok.Tok == TOK_COMMA) { NextToken (); } @@ -1075,7 +1075,7 @@ int ConsumeComma (void) NextToken (); return 1; } else { - Error ("`,' expected"); + Error ("',' expected"); if (CurTok.Tok == TOK_SEMI) { NextToken (); } @@ -1088,7 +1088,7 @@ int ConsumeComma (void) int ConsumeLParen (void) /* Check for a left parenthesis and skip it */ { - return Consume (TOK_LPAREN, "`(' expected"); + return Consume (TOK_LPAREN, "'(' expected"); } @@ -1096,7 +1096,7 @@ int ConsumeLParen (void) int ConsumeRParen (void) /* Check for a right parenthesis and skip it */ { - return Consume (TOK_RPAREN, "`)' expected"); + return Consume (TOK_RPAREN, "')' expected"); } @@ -1104,7 +1104,7 @@ int ConsumeRParen (void) int ConsumeLBrack (void) /* Check for a left bracket and skip it */ { - return Consume (TOK_LBRACK, "`[' expected"); + return Consume (TOK_LBRACK, "'[' expected"); } @@ -1112,7 +1112,7 @@ int ConsumeLBrack (void) int ConsumeRBrack (void) /* Check for a right bracket and skip it */ { - return Consume (TOK_RBRACK, "`]' expected"); + return Consume (TOK_RBRACK, "']' expected"); } @@ -1120,7 +1120,7 @@ int ConsumeRBrack (void) int ConsumeLCurly (void) /* Check for a left curly brace and skip it */ { - return Consume (TOK_LCURLY, "`{' expected"); + return Consume (TOK_LCURLY, "'{' expected"); } @@ -1128,5 +1128,5 @@ int ConsumeLCurly (void) int ConsumeRCurly (void) /* Check for a right curly brace and skip it */ { - return Consume (TOK_RCURLY, "`}' expected"); + return Consume (TOK_RCURLY, "'}' expected"); } diff --git a/src/cc65/scanstrbuf.c b/src/cc65/scanstrbuf.c index 91abc8cb3..bbee569d2 100644 --- a/src/cc65/scanstrbuf.c +++ b/src/cc65/scanstrbuf.c @@ -271,7 +271,7 @@ int SB_GetNumber (StrBuf* B, long* Val) SB_Skip (B); *Val = SignExtendChar (TgtTranslateChar (ParseChar (B))); if (SB_Peek (B) != '\'') { - Error ("`\'' expected"); + Error ("'\'' expected"); return 0; } else { /* Skip the quote */ diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 14169671b..657bc9963 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -115,7 +115,7 @@ static void CheckSemi (int* PendingToken) { int HaveToken = (CurTok.Tok == TOK_SEMI); if (!HaveToken) { - Error ("`;' expected"); + Error ("';' expected"); /* Try to be smart about errors */ if (CurTok.Tok == TOK_COLON || CurTok.Tok == TOK_COMMA) { HaveToken = 1; @@ -231,7 +231,7 @@ static void DoStatement (void) g_defcodelabel (ContinueLabel); /* Parse the end condition */ - Consume (TOK_WHILE, "`while' expected"); + Consume (TOK_WHILE, "'while' expected"); TestInParens (LoopLabel, 1); ConsumeSemi (); @@ -332,7 +332,7 @@ static void ReturnStatement (void) } } else if (!F_HasVoidReturn (CurrentFunc) && !F_HasOldStyleIntRet (CurrentFunc)) { - Error ("Function `%s' must return a value", F_GetFuncName (CurrentFunc)); + Error ("Function '%s' must return a value", F_GetFuncName (CurrentFunc)); } /* Mark the function as having a return statement */ @@ -361,7 +361,7 @@ static void BreakStatement (void) /* Check if we are inside a loop */ if (L == 0) { /* Error: No current loop */ - Error ("`break' statement not within loop or switch"); + Error ("'break' statement not within loop or switch"); return; } @@ -396,7 +396,7 @@ static void ContinueStatement (void) /* Did we find it? */ if (L == 0) { - Error ("`continue' statement not within a loop"); + Error ("'continue' statement not within a loop"); return; } @@ -591,7 +591,7 @@ int Statement (int* PendingToken) case TOK_LCURLY: NextToken (); GotBreak = CompoundStatement (); - CheckTok (TOK_RCURLY, "`{' expected", PendingToken); + CheckTok (TOK_RCURLY, "'{' expected", PendingToken); return GotBreak; case TOK_IF: diff --git a/src/cc65/swstmt.c b/src/cc65/swstmt.c index 512f4257d..4a3730283 100644 --- a/src/cc65/swstmt.c +++ b/src/cc65/swstmt.c @@ -303,7 +303,7 @@ void DefaultLabel (void) } else { /* case keyword outside a switch statement */ - Error ("`default' label not within a switch statement"); + Error ("'default' label not within a switch statement"); } diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 9eb0346e8..56196ea5a 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -168,11 +168,11 @@ static void CheckSymTable (SymTable* Tab) !SymHasAttr (Entry, atUnused)) { if (Flags & SC_PARAM) { if (IS_Get (&WarnUnusedParam)) { - Warning ("Parameter `%s' is never used", Entry->Name); + Warning ("Parameter '%s' is never used", Entry->Name); } } else { if (IS_Get (&WarnUnusedVar)) { - Warning ("`%s' is defined but never used", Entry->Name); + Warning ("'%s' is defined but never used", Entry->Name); } } } @@ -182,11 +182,11 @@ static void CheckSymTable (SymTable* Tab) if (Flags & SC_LABEL) { if (!SymIsDef (Entry)) { /* Undefined label */ - Error ("Undefined label: `%s'", Entry->Name); + Error ("Undefined label: '%s'", Entry->Name); } else if (!SymIsRef (Entry)) { /* Defined but not used */ if (IS_Get (&WarnUnusedLabel)) { - Warning ("`%s' is defined but never used", Entry->Name); + Warning ("'%s' is defined but never used", Entry->Name); } } } @@ -566,10 +566,10 @@ SymEntry* AddStructSym (const char* Name, unsigned Type, unsigned Size, SymTable /* We do have an entry. This may be a forward, so check it. */ if ((Entry->Flags & SC_TYPEMASK) != Type) { /* Existing symbol is not a struct */ - Error ("Symbol `%s' is already different kind", Name); + Error ("Symbol '%s' is already different kind", Name); } else if (Size > 0 && Entry->V.S.Size > 0) { /* Both structs are definitions. */ - Error ("Multiple definition for `%s'", Name); + Error ("Multiple definition for '%s'", Name); } else { /* Define the struct size if it is given */ if (Size > 0) { @@ -605,7 +605,7 @@ SymEntry* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsign if (Entry) { /* We have a symbol with this name already */ - Error ("Multiple definition for `%s'", Name); + Error ("Multiple definition for '%s'", Name); } else { @@ -639,9 +639,9 @@ SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name)); if (Entry) { if ((Entry->Flags & SC_CONST) != SC_CONST) { - Error ("Symbol `%s' is already different kind", Name); + Error ("Symbol '%s' is already different kind", Name); } else { - Error ("Multiple definition for `%s'", Name); + Error ("Multiple definition for '%s'", Name); } return Entry; } @@ -706,7 +706,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) if (SymIsDef (Entry) && (Flags & SC_DEF) != 0) { /* Trying to define the label more than once */ - Error ("Label `%s' is defined more than once", Name); + Error ("Label '%s' is defined more than once", Name); } NewDOR = AddDefOrRef (Entry, Flags); @@ -809,7 +809,7 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs if (Entry) { /* We have a symbol with this name already */ - Error ("Multiple definition for `%s'", Name); + Error ("Multiple definition for '%s'", Name); } else { @@ -865,12 +865,12 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) ** then avoid a compiler crash. See GitHub issue #728. */ if (Entry->Flags & SC_ENUM) { - Fatal ("Can't redeclare enum constant `%s' as global variable", Name); + Fatal ("Can't redeclare enum constant '%s' as global variable", Name); } /* We have a symbol with this name already */ if (Entry->Flags & SC_TYPE) { - Error ("Multiple definition for `%s'", Name); + Error ("Multiple definition for '%s'", Name); return Entry; } @@ -890,7 +890,7 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) if ((Size != UNSPECIFIED && ESize != UNSPECIFIED && Size != ESize) || TypeCmp (T + 1, EType + 1) < TC_EQUAL) { /* Types not identical: Conflicting types */ - Error ("Conflicting types for `%s'", Name); + Error ("Conflicting types for '%s'", Name); return Entry; } else { /* Check if we have a size in the existing definition */ @@ -903,7 +903,7 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) } else { /* New type must be identical */ if (TypeCmp (EType, T) < TC_EQUAL) { - Error ("Conflicting types for `%s'", Name); + Error ("Conflicting types for '%s'", Name); return Entry; } @@ -930,7 +930,7 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) ** warn about the conflict. (It will compile a public declaration.) */ if ((Flags & SC_EXTERN) == 0 && (Entry->Flags & SC_EXTERN) != 0) { - Warning ("static declaration follows non-static declaration of `%s'.", Name); + Warning ("static declaration follows non-static declaration of '%s'.", Name); } /* An extern declaration must not change the current linkage. */ @@ -942,7 +942,7 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) ** warn about the conflict. (It will compile a public declaration.) */ if ((Flags & SC_EXTERN) != 0 && (Entry->Flags & SC_EXTERN) == 0) { - Warning ("public declaration follows static declaration of `%s'.", Name); + Warning ("public declaration follows static declaration of '%s'.", Name); } /* Add the new flags */ @@ -1017,7 +1017,7 @@ void MakeZPSym (const char* Name) if (Entry) { Entry->Flags |= SC_ZEROPAGE; } else { - Error ("Undefined symbol: `%s'", Name); + Error ("Undefined symbol: '%s'", Name); } } diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 47ab993c1..21ad33f12 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -76,7 +76,7 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Don't allow casts from void to something else. */ if (IsTypeVoid (OldType)) { - Error ("Cannot convert from `void' to something else"); + Error ("Cannot convert from 'void' to something else"); goto ExitPoint; } diff --git a/src/chrcvt65/main.c b/src/chrcvt65/main.c index 7e7183e0a..b2a21a114 100644 --- a/src/chrcvt65/main.c +++ b/src/chrcvt65/main.c @@ -325,7 +325,7 @@ static void ConvertFile (const char* Input, const char* Output) /* Try to open the file for reading */ FILE* F = fopen (Input, "rb"); if (F == 0) { - Error ("Cannot open input file `%s': %s", Input, strerror (errno)); + Error ("Cannot open input file '%s': %s", Input, strerror (errno)); } /* Seek to the end and determine the size */ @@ -337,9 +337,9 @@ static void ConvertFile (const char* Input, const char* Output) /* Check if the size is reasonable */ if (Size > 32*1024) { - Error ("Input file `%s' is too large (max = 32k)", Input); + Error ("Input file '%s' is too large (max = 32k)", Input); } else if (Size < 0x100) { - Error ("Input file `%s' is too small to be a vector font file", Input); + Error ("Input file '%s' is too small to be a vector font file", Input); } /* Allocate memory for the file */ @@ -347,7 +347,7 @@ static void ConvertFile (const char* Input, const char* Output) /* Read the file contents into the buffer */ if (fread (Buf, 1, (size_t) Size, F) != (size_t) Size) { - Error ("Error reading from input file `%s'", Input); + Error ("Error reading from input file '%s'", Input); } /* Close the file */ @@ -355,14 +355,14 @@ static void ConvertFile (const char* Input, const char* Output) /* Verify the header */ if (memcmp (Buf, ChrHeader, sizeof (ChrHeader)) != 0) { - Error ("Invalid format for `%s': invalid header", Input); + Error ("Invalid format for '%s': invalid header", Input); } MsgEnd = memchr (Buf + sizeof (ChrHeader), 0x1A, 0x80); if (MsgEnd == 0) { - Error ("Invalid format for `%s': description not found", Input); + Error ("Invalid format for '%s': description not found", Input); } if (MsgEnd[1] != 0x80 || MsgEnd[2] != 0x00) { - Error ("Invalid format for `%s': wrong header size", Input); + Error ("Invalid format for '%s': wrong header size", Input); } /* We expect the file to hold chars from 0x20 (space) to 0x7E (tilde) */ @@ -372,9 +372,9 @@ static void ConvertFile (const char* Input, const char* Output) if (FirstChar > 0x20 || LastChar < 0x7E) { Print (stderr, 1, "FirstChar = $%04X, CharCount = %u\n", FirstChar, CharCount); - Error ("File `%s' doesn't contain the chars we need", Input); + Error ("File '%s' doesn't contain the chars we need", Input); } else if (LastChar >= 0x100) { - Error ("File `%s' contains too many character definitions", Input); + Error ("File '%s' contains too many character definitions", Input); } /* Print the copyright from the header */ @@ -405,7 +405,7 @@ static void ConvertFile (const char* Input, const char* Output) /* Check if the offset is valid */ if (Remaining <= 0) { - Error ("Invalid data offset in input file `%s'", Input); + Error ("Invalid data offset in input file '%s'", Input); } /* Convert the vector data and place it into the buffer */ @@ -422,7 +422,7 @@ static void ConvertFile (const char* Input, const char* Output) /* The baseline must be zero, otherwise we cannot convert */ if (Buf[0x89] != 0) { - Error ("Baseline of font in `%s' is not zero", Input); + Error ("Baseline of font in '%s' is not zero", Input); } /* If the output file is NULL, use the name of the input file with ".tch" @@ -435,33 +435,33 @@ static void ConvertFile (const char* Input, const char* Output) /* Open the output file */ F = fopen (Output, "wb"); if (F == 0) { - Error ("Cannot open output file `%s': %s", Output, strerror (errno)); + Error ("Cannot open output file '%s': %s", Output, strerror (errno)); } /* Write the header to the output file */ if (fwrite (TchHeader, 1, sizeof (TchHeader), F) != sizeof (TchHeader)) { - Error ("Error writing to `%s' (disk full?)", Output); + Error ("Error writing to '%s' (disk full?)", Output); } /* Write the width table to the output file */ if (fwrite (WidthBuf, 1, 0x5F, F) != 0x5F) { - Error ("Error writing to `%s' (disk full?)", Output); + Error ("Error writing to '%s' (disk full?)", Output); } /* Write the offsets to the output file */ if (fwrite (SB_GetConstBuf (&Offsets), 1, 0x5F * 2, F) != 0x5F * 2) { - Error ("Error writing to `%s' (disk full?)", Output); + Error ("Error writing to '%s' (disk full?)", Output); } /* Write the data to the output file */ Offs = SB_GetLen (&VectorData); if (fwrite (SB_GetConstBuf (&VectorData), 1, Offs, F) != Offs) { - Error ("Error writing to `%s' (disk full?)", Output); + Error ("Error writing to '%s' (disk full?)", Output); } /* Close the output file */ if (fclose (F) != 0) { - Error ("Error closing to `%s': %s", Output, strerror (errno)); + Error ("Error closing to '%s': %s", Output, strerror (errno)); } /* Done */ diff --git a/src/cl65/main.c b/src/cl65/main.c index e61bd02a5..4a65e8729 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -339,7 +339,7 @@ static void CmdAddFile (CmdDesc* Cmd, const char* File) for (I = 0; I < Cmd->FileCount; ++I) { if (strcmp (Cmd->Files[I], File) == 0) { /* Duplicate file */ - Warning ("Duplicate file in argument list: `%s'", File); + Warning ("Duplicate file in argument list: '%s'", File); /* No need to search further */ break; } @@ -447,7 +447,7 @@ static void ExecProgram (CmdDesc* Cmd) /* Check the result code */ if (Status < 0) { /* Error executing the program */ - Error ("Cannot execute `%s': %s", Cmd->Name, strerror (errno)); + Error ("Cannot execute '%s': %s", Cmd->Name, strerror (errno)); } else if (Status != 0) { /* Called program had an error */ exit (Status); @@ -573,7 +573,7 @@ static void AssembleIntermediate (const char* SourceFile) /* Remove the input file */ if (remove (AsmName) < 0) { - Warning ("Cannot remove temporary file `%s': %s", + Warning ("Cannot remove temporary file '%s': %s", AsmName, strerror (errno)); } @@ -757,7 +757,7 @@ static void Usage (void) " -o name\t\t\tName the output file\n" " -r\t\t\t\tEnable register variables\n" " -t sys\t\t\tSet the target system\n" - " -u sym\t\t\tForce an import of symbol `sym'\n" + " -u sym\t\t\tForce an import of symbol 'sym'\n" " -v\t\t\t\tVerbose mode\n" " -vm\t\t\t\tVerbose map file\n" " -C name\t\t\tUse linker config file\n" @@ -803,7 +803,7 @@ static void Usage (void) " --debug\t\t\tDebug mode\n" " --debug-info\t\t\tAdd debug info\n" " --feature name\t\tSet an emulation feature\n" - " --force-import sym\t\tForce an import of symbol `sym'\n" + " --force-import sym\t\tForce an import of symbol 'sym'\n" " --help\t\t\tHelp (this text)\n" " --include-dir dir\t\tSet a compiler include directory path\n" " --ld-args options\t\tPass options to the linker\n" @@ -1296,9 +1296,9 @@ static void OptTarget (const char* Opt attribute ((unused)), const char* Arg) { Target = FindTarget (Arg); if (Target == TGT_UNKNOWN) { - Error ("No such target system: `%s'", Arg); + Error ("No such target system: '%s'", Arg); } else if (Target == TGT_MODULE) { - Error ("Cannot use `module' as target, use --module instead"); + Error ("Cannot use 'module' as target, use --module instead"); } } @@ -1631,7 +1631,7 @@ int main (int argc, char* argv []) break; default: - Error ("Don't know what to do with `%s'", Arg); + Error ("Don't know what to do with '%s'", Arg); } diff --git a/src/cl65/spawn-unix.inc b/src/cl65/spawn-unix.inc index 283285c76..36eb7aab4 100644 --- a/src/cl65/spawn-unix.inc +++ b/src/cl65/spawn-unix.inc @@ -82,7 +82,7 @@ int spawnvp (int Mode attribute ((unused)), const char* File, char* const argv [ /* The son - exec the program */ if (execvp (File, argv) < 0) { - Error ("Cannot exec `%s': %s", File, strerror (errno)); + Error ("Cannot exec '%s': %s", File, strerror (errno)); } } else { @@ -94,7 +94,7 @@ int spawnvp (int Mode attribute ((unused)), const char* File, char* const argv [ /* Examine the child status */ if (!WIFEXITED (Status)) { - Error ("Subprocess `%s' aborted by signal %d", File, WTERMSIG (Status)); + Error ("Subprocess '%s' aborted by signal %d", File, WTERMSIG (Status)); } } diff --git a/src/co65/convert.c b/src/co65/convert.c index af036ebf7..ec6d68401 100644 --- a/src/co65/convert.c +++ b/src/co65/convert.c @@ -394,7 +394,7 @@ void Convert (const O65Data* D) switch (O->Type) { case O65_OPT_FILENAME: - Print (stdout, 1, "O65 filename option: `%s'\n", + Print (stdout, 1, "O65 filename option: '%s'\n", GetO65OptionText (O)); break; @@ -402,7 +402,7 @@ void Convert (const O65Data* D) if (O->Len == 2) { Warning ("Operating system option without data found"); } else { - Print (stdout, 1, "O65 operating system option: `%s'\n", + Print (stdout, 1, "O65 operating system option: '%s'\n", GetO65OSName (O->Data[0])); switch (O->Data[0]) { case O65_OS_CC65_MODULE: @@ -418,7 +418,7 @@ void Convert (const O65Data* D) break; case O65_OPT_ASM: - Print (stdout, 1, "O65 assembler option: `%s'\n", + Print (stdout, 1, "O65 assembler option: '%s'\n", GetO65OptionText (O)); break; @@ -427,11 +427,11 @@ void Convert (const O65Data* D) xfree (Author); } Author = xstrdup (GetO65OptionText (O)); - Print (stdout, 1, "O65 author option: `%s'\n", Author); + Print (stdout, 1, "O65 author option: '%s'\n", Author); break; case O65_OPT_TIMESTAMP: - Print (stdout, 1, "O65 timestamp option: `%s'\n", + Print (stdout, 1, "O65 timestamp option: '%s'\n", GetO65OptionText (O)); break; @@ -450,11 +450,11 @@ void Convert (const O65Data* D) /* Open the output file */ F = fopen (OutputName, "w"); if (F == 0) { - Error ("Cannot open `%s': %s", OutputName, strerror (errno)); + Error ("Cannot open '%s': %s", OutputName, strerror (errno)); } /* Create a header */ - fprintf (F, ";\n; File generated by co65 v %s using model `%s'\n;\n", + fprintf (F, ";\n; File generated by co65 v %s using model '%s'\n;\n", GetVersionAsString (), GetModelName (Model)); /* Select the CPU */ diff --git a/src/co65/main.c b/src/co65/main.c index 43d263516..33ecdbf6f 100644 --- a/src/co65/main.c +++ b/src/co65/main.c @@ -112,7 +112,7 @@ static void CheckLabelName (const char* Label) } if (*L) { - Error ("Label name `%s' is invalid", Label); + Error ("Label name '%s' is invalid", Label); } } @@ -123,7 +123,7 @@ static void CheckSegName (const char* Seg) { /* Print an error and abort if the name is not ok */ if (!ValidSegName (Seg)) { - Error ("Segment name `%s' is invalid", Seg); + Error ("Segment name '%s' is invalid", Seg); } } @@ -244,7 +244,7 @@ static void OptO65Model (const char* Opt attribute ((unused)), const char* Arg) /* Search for the model name */ Model = FindModel (Arg); if (Model == O65_MODEL_INVALID) { - Error ("Unknown o65 model `%s'", Arg); + Error ("Unknown o65 model '%s'", Arg); } } @@ -387,7 +387,7 @@ int main (int argc, char* argv []) } else { /* Filename. Check if we already had one */ if (InputName) { - Error ("Don't know what to do with `%s'", Arg); + Error ("Don't know what to do with '%s'", Arg); } else { InputName = Arg; } diff --git a/src/co65/o65.c b/src/co65/o65.c index 3496995a8..81c07bb8c 100644 --- a/src/co65/o65.c +++ b/src/co65/o65.c @@ -361,7 +361,7 @@ O65Data* ReadO65File (const char* Name) /* Open the o65 input file */ FILE* F = fopen (Name, "rb"); if (F == 0) { - Error ("Cannot open `%s': %s", Name, strerror (errno)); + Error ("Cannot open '%s': %s", Name, strerror (errno)); } /* Read the file data */ diff --git a/src/common/check.c b/src/common/check.c index c6c5d2d95..0d0e6ef4b 100644 --- a/src/common/check.c +++ b/src/common/check.c @@ -75,5 +75,5 @@ static void DefaultCheckFailed (const char* Msg, const char* Cond, const char* File, unsigned Line) { /* Output a diagnostic and abort */ - AbEnd ("%s%s, file `%s', line %u", Msg, Cond, File, Line); + AbEnd ("%s%s, file '%s', line %u", Msg, Cond, File, Line); } diff --git a/src/common/cmdline.c b/src/common/cmdline.c index 0f6622934..4de79a419 100644 --- a/src/common/cmdline.c +++ b/src/common/cmdline.c @@ -239,7 +239,7 @@ void NeedArg (const char* Opt) void InvArg (const char* Opt, const char* Arg) /* Print an error about an invalid option argument and exit. */ { - AbEnd ("Invalid argument for %s: `%s'", Opt, Arg); + AbEnd ("Invalid argument for %s: '%s'", Opt, Arg); } @@ -247,7 +247,7 @@ void InvArg (const char* Opt, const char* Arg) void InvDef (const char* Def) /* Print an error about an invalid definition and die */ { - AbEnd ("Invalid definition: `%s'", Def); + AbEnd ("Invalid definition: '%s'", Def); } diff --git a/src/da65/asminc.c b/src/da65/asminc.c index 06a397d52..59ba0aab4 100644 --- a/src/da65/asminc.c +++ b/src/da65/asminc.c @@ -148,7 +148,7 @@ void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown) ++L; } else { if (!IgnoreUnknown) { - Error ("%s(%u): Missing `='", Filename, Line); + Error ("%s(%u): Missing '='", Filename, Line); } continue; } diff --git a/src/da65/code.c b/src/da65/code.c index 9aff732b3..3fb6a21d3 100644 --- a/src/da65/code.c +++ b/src/da65/code.c @@ -78,12 +78,12 @@ void LoadCode (void) /* Open the file */ F = fopen (InFile, "rb"); if (F == 0) { - Error ("Cannot open `%s': %s", InFile, strerror (errno)); + Error ("Cannot open '%s': %s", InFile, strerror (errno)); } /* Seek to the end to get the size of the file */ if (fseek (F, 0, SEEK_END) != 0) { - Error ("Cannot seek on file `%s': %s", InFile, strerror (errno)); + Error ("Cannot seek on file '%s': %s", InFile, strerror (errno)); } Size = ftell (F); @@ -101,7 +101,7 @@ void LoadCode (void) ** the file. */ if (fseek (F, InputOffs, SEEK_SET) != 0) { - Error ("Cannot seek on file `%s': %s", InFile, strerror (errno)); + Error ("Cannot seek on file '%s': %s", InFile, strerror (errno)); } Size -= InputOffs; @@ -130,10 +130,10 @@ void LoadCode (void) /* Check if the size is larger than what we can read */ if (Size == 0) { - Error ("Nothing to read from input file `%s'", InFile); + Error ("Nothing to read from input file '%s'", InFile); } if (Size > MaxCount) { - Warning ("File `%s' is too large, ignoring %ld bytes", + Warning ("File '%s' is too large, ignoring %ld bytes", InFile, Size - MaxCount); } else if (MaxCount > Size) { MaxCount = (unsigned) Size; @@ -142,7 +142,7 @@ void LoadCode (void) /* Read from the file and remember the number of bytes read */ Count = fread (CodeBuf + StartAddr, 1, MaxCount, F); if (ferror (F) || Count != MaxCount) { - Error ("Error reading from `%s': %s", InFile, strerror (errno)); + Error ("Error reading from '%s': %s", InFile, strerror (errno)); } /* Close the file */ diff --git a/src/da65/main.c b/src/da65/main.c index b0a784dd8..1fc07f006 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -617,7 +617,7 @@ int main (int argc, char* argv []) } else { /* Filename. Check if we already had one */ if (InFile) { - fprintf (stderr, "%s: Don't know what to do with `%s'\n", + fprintf (stderr, "%s: Don't know what to do with '%s'\n", ProgName, Arg); exit (EXIT_FAILURE); } else { diff --git a/src/da65/output.c b/src/da65/output.c index 4daacb1ee..5b0b6b79c 100644 --- a/src/da65/output.c +++ b/src/da65/output.c @@ -96,7 +96,7 @@ void OpenOutput (const char* Name) if (Name != 0) { F = fopen (Name, "w"); if (F == 0) { - Error ("Cannot open `%s': %s", Name, strerror (errno)); + Error ("Cannot open '%s': %s", Name, strerror (errno)); } } else { F = stdout; diff --git a/src/da65/scanner.c b/src/da65/scanner.c index 2bb80a8ef..85853d6c4 100644 --- a/src/da65/scanner.c +++ b/src/da65/scanner.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -466,7 +466,7 @@ Again: /* C++ style comment */ NextChar (); if (C != '/') { - InfoError ("Invalid token `/'"); + InfoError ("Invalid token '/'"); } do { NextChar (); @@ -482,7 +482,7 @@ Again: break; default: - InfoError ("Invalid character `%c'", C); + InfoError ("Invalid character '%c'", C); } } @@ -503,7 +503,7 @@ void InfoConsume (unsigned T, const char* Msg) void InfoConsumeLCurly (void) /* Consume a left curly brace */ { - InfoConsume (INFOTOK_LCURLY, "`{' expected"); + InfoConsume (INFOTOK_LCURLY, "'{' expected"); } @@ -511,7 +511,7 @@ void InfoConsumeLCurly (void) void InfoConsumeRCurly (void) /* Consume a right curly brace */ { - InfoConsume (INFOTOK_RCURLY, "`}' expected"); + InfoConsume (INFOTOK_RCURLY, "'}' expected"); } @@ -519,7 +519,7 @@ void InfoConsumeRCurly (void) void InfoConsumeSemi (void) /* Consume a semicolon */ { - InfoConsume (INFOTOK_SEMI, "`;' expected"); + InfoConsume (INFOTOK_SEMI, "';' expected"); } @@ -527,7 +527,7 @@ void InfoConsumeSemi (void) void InfoConsumeColon (void) /* Consume a colon */ { - InfoConsume (INFOTOK_COLON, "`:' expected"); + InfoConsume (INFOTOK_COLON, "':' expected"); } @@ -683,7 +683,7 @@ void InfoOpenInput (void) /* Open the file */ InputFile = fopen (InfoFile, "r"); if (InputFile == 0) { - Error ("Cannot open `%s': %s", InfoFile, strerror (errno)); + Error ("Cannot open '%s': %s", InfoFile, strerror (errno)); } /* Initialize variables */ diff --git a/src/dbginfo/dbginfo.c b/src/dbginfo/dbginfo.c index e0d8894f9..42001ed07 100644 --- a/src/dbginfo/dbginfo.c +++ b/src/dbginfo/dbginfo.c @@ -2687,7 +2687,7 @@ static void NextToken (InputData* D) break; default: - ParseError (D, CC65_ERROR, "Invalid input character `%c'", D->C); + ParseError (D, CC65_ERROR, "Invalid input character '%c'", D->C); } } diff --git a/src/grc65/main.c b/src/grc65/main.c index a53801a39..f6554eada 100644 --- a/src/grc65/main.c +++ b/src/grc65/main.c @@ -151,12 +151,12 @@ static void OptTarget (const char* Opt attribute ((unused)), const char* Arg) break; case TGT_UNKNOWN: - AbEnd ("Unknown target system `%s'", Arg); + AbEnd ("Unknown target system '%s'", Arg); break; default: /* Target is known but unsupported */ - AbEnd ("Unsupported target system `%s'", Arg); + AbEnd ("Unsupported target system '%s'", Arg); break; } } diff --git a/src/ld65/asserts.c b/src/ld65/asserts.c index 276b13595..626ed94a6 100644 --- a/src/ld65/asserts.c +++ b/src/ld65/asserts.c @@ -129,7 +129,7 @@ void CheckAssertions (void) /* If the expression is not constant, we're not able to handle it */ if (!IsConstExpr (A->Expr)) { - Warning ("Cannot evaluate assertion in module `%s', line %u", + Warning ("Cannot evaluate assertion in module '%s', line %u", Module, Line); } else if (GetExprVal (A->Expr) == 0) { @@ -149,7 +149,7 @@ void CheckAssertions (void) break; default: - Internal ("Invalid assertion action (%u) in module `%s', " + Internal ("Invalid assertion action (%u) in module '%s', " "line %u (file corrupt?)", A->Action, Module, Line); break; diff --git a/src/ld65/bin.c b/src/ld65/bin.c index a77d49679..688622415 100644 --- a/src/ld65/bin.c +++ b/src/ld65/bin.c @@ -154,7 +154,7 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M) SegDesc* S = CollAtUnchecked (&M->SegList, I); /* Keep the user happy */ - Print (stdout, 1, " Writing `%s'\n", GetString (S->Name)); + Print (stdout, 1, " Writing '%s'\n", GetString (S->Name)); /* Writes do only occur in the load area and not for BSS segments */ DoWrite = (S->Flags & SF_BSS) == 0 && /* No BSS segment */ @@ -286,23 +286,23 @@ void BinWriteTarget (BinDesc* D, struct File* F) /* Open the file */ D->F = fopen (D->Filename, "wb"); if (D->F == 0) { - Error ("Cannot open `%s': %s", D->Filename, strerror (errno)); + Error ("Cannot open '%s': %s", D->Filename, strerror (errno)); } /* Keep the user happy */ - Print (stdout, 1, "Opened `%s'...\n", D->Filename); + Print (stdout, 1, "Opened '%s'...\n", D->Filename); /* Dump all memory areas */ for (I = 0; I < CollCount (&F->MemoryAreas); ++I) { /* Get this entry */ MemoryArea* M = CollAtUnchecked (&F->MemoryAreas, I); - Print (stdout, 1, " Dumping `%s'\n", GetString (M->Name)); + Print (stdout, 1, " Dumping '%s'\n", GetString (M->Name)); BinWriteMem (D, M); } /* Close the file */ if (fclose (D->F) != 0) { - Error ("Cannot write to `%s': %s", D->Filename, strerror (errno)); + Error ("Cannot write to '%s': %s", D->Filename, strerror (errno)); } /* Reset the file and filename */ diff --git a/src/ld65/config.c b/src/ld65/config.c index 1d3e810f6..099617ba0 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -226,7 +226,7 @@ static MemoryArea* CfgGetMemory (unsigned Name) { MemoryArea* M = CfgFindMemory (Name); if (M == 0) { - CfgError (&CfgErrorPos, "Invalid memory area `%s'", GetString (Name)); + CfgError (&CfgErrorPos, "Invalid memory area '%s'", GetString (Name)); } return M; } @@ -320,7 +320,7 @@ static MemoryArea* CreateMemoryArea (const FilePos* Pos, unsigned Name) MemoryArea* M = CfgFindMemory (Name); if (M) { CfgError (&CfgErrorPos, - "Memory area `%s' defined twice", + "Memory area '%s' defined twice", GetString (Name)); } @@ -343,7 +343,7 @@ static SegDesc* NewSegDesc (unsigned Name) /* Check for duplicate names */ SegDesc* S = CfgFindSegDesc (Name); if (S) { - CfgError (&CfgErrorPos, "Segment `%s' defined twice", GetString (Name)); + CfgError (&CfgErrorPos, "Segment '%s' defined twice", GetString (Name)); } /* Allocate memory */ @@ -566,7 +566,7 @@ static void ParseFiles (void) F = FindFile (GetStrBufId (&CfgSVal)); if (F == 0) { CfgError (&CfgErrorPos, - "File `%s' not found in MEMORY section", + "File '%s' not found in MEMORY section", SB_GetConstBuf (&CfgSVal)); } @@ -798,7 +798,7 @@ static void ParseSegments (void) */ if ((S->Flags & SF_BSS) != 0 && (S->Load != S->Run)) { CfgWarning (&CfgErrorPos, - "Segment with type `bss' has both LOAD and RUN " + "Segment with type 'bss' has both LOAD and RUN " "memory areas assigned"); } @@ -806,7 +806,7 @@ static void ParseSegments (void) if ((S->Flags & SF_RO) == 0) { if (S->Run->Flags & MF_RO) { CfgError (&CfgErrorPos, - "Cannot put r/w segment `%s' in r/o memory area `%s'", + "Cannot put r/w segment '%s' in r/o memory area '%s'", GetString (S->Name), GetString (S->Run->Name)); } } @@ -1511,7 +1511,7 @@ static void ParseConfig (void) CfgNextTok (); /* Expected a curly brace */ - CfgConsume (CFGTOK_LCURLY, "`{' expected"); + CfgConsume (CFGTOK_LCURLY, "'{' expected"); /* Read the block */ switch (BlockTok) { @@ -1546,7 +1546,7 @@ static void ParseConfig (void) } /* Skip closing brace */ - CfgConsume (CFGTOK_RCURLY, "`}' expected"); + CfgConsume (CFGTOK_RCURLY, "'}' expected"); } while (CfgTok != CFGTOK_EOF); } @@ -1603,7 +1603,7 @@ static void ProcessSegments (void) */ if ((S->Flags & SF_BSS) != 0 && S->Seg != 0 && !IsBSSType (S->Seg)) { CfgWarning (GetSourcePos (S->LI), - "Segment `%s' with type `bss' contains initialized data", + "Segment '%s' with type 'bss' contains initialized data", GetString (S->Name)); } @@ -1632,7 +1632,7 @@ static void ProcessSegments (void) /* Print a warning if the segment is not optional */ if ((S->Flags & SF_OPTIONAL) == 0) { CfgWarning (&CfgErrorPos, - "Segment `%s' does not exist", + "Segment '%s' does not exist", GetString (S->Name)); } @@ -1665,7 +1665,7 @@ static void ProcessSymbols (void) if (O65GetImport (O65FmtDesc, Sym->Name) != 0) { CfgError ( GetSourcePos (Sym->LI), - "Exported o65 symbol `%s' cannot also be an o65 import", + "Exported o65 symbol '%s' cannot also be an o65 import", GetString (Sym->Name) ); } @@ -1677,7 +1677,7 @@ static void ProcessSymbols (void) if (O65GetExport (O65FmtDesc, Sym->Name) != 0) { CfgError ( GetSourcePos (Sym->LI), - "Duplicate exported o65 symbol: `%s'", + "Duplicate exported o65 symbol: '%s'", GetString (Sym->Name) ); } @@ -1691,7 +1691,7 @@ static void ProcessSymbols (void) if (O65GetExport (O65FmtDesc, Sym->Name) != 0) { CfgError ( GetSourcePos (Sym->LI), - "Imported o65 symbol `%s' cannot also be an o65 export", + "Imported o65 symbol '%s' cannot also be an o65 export", GetString (Sym->Name) ); } @@ -1703,7 +1703,7 @@ static void ProcessSymbols (void) if (O65GetImport (O65FmtDesc, Sym->Name) != 0) { CfgError ( GetSourcePos (Sym->LI), - "Duplicate imported o65 symbol: `%s'", + "Duplicate imported o65 symbol: '%s'", GetString (Sym->Name) ); } @@ -1813,7 +1813,7 @@ unsigned CfgProcess (void) */ if (!IsConstExpr (M->StartExpr)) { CfgError (GetSourcePos (M->LI), - "Start address of memory area `%s' is not constant", + "Start address of memory area '%s' is not constant", GetString (M->Name)); } Addr = M->Start = GetExprVal (M->StartExpr); @@ -1838,7 +1838,7 @@ unsigned CfgProcess (void) /* Resolve the size expression */ if (!IsConstExpr (M->SizeExpr)) { CfgError (GetSourcePos (M->LI), - "Size of memory area `%s' is not constant", + "Size of memory area '%s' is not constant", GetString (M->Name)); } M->Size = GetExprVal (M->SizeExpr); @@ -1859,15 +1859,15 @@ unsigned CfgProcess (void) ++Overwrites; } else { CfgError (GetSourcePos (M->LI), - "Segment `%s' of type `overwrite' requires either" - " `Start' or `Offset' attribute to be specified", + "Segment '%s' of type 'overwrite' requires either" + " 'Start' or 'Offset' attribute to be specified", GetString (S->Name)); } } else { if (Overwrites > 0) { CfgError (GetSourcePos (M->LI), - "Segment `%s' is preceded by at least one segment" - " of type `overwrite'", + "Segment '%s' is preceded by at least one segment" + " of type 'overwrite'", GetString (S->Name)); } } @@ -1893,7 +1893,7 @@ unsigned CfgProcess (void) ** in the linker. */ CfgWarning (GetSourcePos (S->LI), - "Segment `%s' isn't aligned properly; the" + "Segment '%s' isn't aligned properly; the" " resulting executable might not be functional.", GetString (S->Name)); } @@ -1908,7 +1908,7 @@ unsigned CfgProcess (void) */ if (M->FillLevel == 0 && NewAddr > Addr) { CfgWarning (GetSourcePos (S->LI), - "The first segment in memory area `%s' " + "The first segment in memory area '%s' " "needs fill bytes for alignment.", GetString (M->Name)); } @@ -1929,7 +1929,7 @@ unsigned CfgProcess (void) if (S->Flags & SF_OVERWRITE) { if (NewAddr < M->Start) { CfgError (GetSourcePos (S->LI), - "Segment `%s' begins before memory area `%s'", + "Segment '%s' begins before memory area '%s'", GetString (S->Name), GetString (M->Name)); } else { Addr = NewAddr; @@ -1940,12 +1940,12 @@ unsigned CfgProcess (void) ++Overflows; if (S->Flags & SF_OFFSET) { CfgWarning (GetSourcePos (S->LI), - "Segment `%s' offset is too small in `%s' by %lu byte%c", + "Segment '%s' offset is too small in '%s' by %lu byte%c", GetString (S->Name), GetString (M->Name), Addr - NewAddr, (Addr - NewAddr == 1) ? ' ' : 's'); } else { CfgWarning (GetSourcePos (S->LI), - "Segment `%s' start address is too low in `%s' by %lu byte%c", + "Segment '%s' start address is too low in '%s' by %lu byte%c", GetString (S->Name), GetString (M->Name), Addr - NewAddr, (Addr - NewAddr == 1) ? ' ' : 's'); } @@ -1992,7 +1992,7 @@ unsigned CfgProcess (void) ++Overflows; M->Flags |= MF_OVERFLOW; CfgWarning (GetSourcePos (M->LI), - "Segment `%s' overflows memory area `%s' by %lu byte%c", + "Segment '%s' overflows memory area '%s' by %lu byte%c", GetString (S->Name), GetString (M->Name), M->FillLevel - M->Size, (M->FillLevel - M->Size == 1) ? ' ' : 's'); } @@ -2117,7 +2117,7 @@ void CfgWriteTarget (void) MemoryArea* M = CollAtUnchecked (&F->MemoryAreas, J); /* Debugging */ - Print (stdout, 2, "Skipping `%s'...\n", GetString (M->Name)); + Print (stdout, 2, "Skipping '%s'...\n", GetString (M->Name)); /* Walk throught the segments */ for (K = 0; K < CollCount (&M->SegList); ++K) { diff --git a/src/ld65/dbgfile.c b/src/ld65/dbgfile.c index 386706f66..204aff9d8 100644 --- a/src/ld65/dbgfile.c +++ b/src/ld65/dbgfile.c @@ -107,7 +107,7 @@ void CreateDbgFile (void) /* Open the debug info file */ FILE* F = fopen (DbgFileName, "w"); if (F == 0) { - Error ("Cannot create debug file `%s': %s", DbgFileName, strerror (errno)); + Error ("Cannot create debug file '%s': %s", DbgFileName, strerror (errno)); } /* Output version information */ @@ -166,6 +166,6 @@ void CreateDbgFile (void) /* Close the file */ if (fclose (F) != 0) { - Error ("Error closing debug file `%s': %s", DbgFileName, strerror (errno)); + Error ("Error closing debug file '%s': %s", DbgFileName, strerror (errno)); } } diff --git a/src/ld65/exports.c b/src/ld65/exports.c index e7ef3d413..0f9ac1c10 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -166,13 +166,13 @@ Import* ReadImport (FILE* F, ObjData* Obj) */ if (ObjHasFiles (I->Obj)) { const LineInfo* LI = GetImportPos (I); - Error ("Invalid import size in for `%s', imported from %s(%u): 0x%02X", + Error ("Invalid import size in for '%s', imported from %s(%u): 0x%02X", GetString (I->Name), GetSourceName (LI), GetSourceLine (LI), I->AddrSize); } else { - Error ("Invalid import size in for `%s', imported from %s: 0x%02X", + Error ("Invalid import size in for '%s', imported from %s: 0x%02X", GetString (I->Name), GetObjFileName (I->Obj), I->AddrSize); @@ -199,7 +199,7 @@ Import* GenImport (unsigned Name, unsigned char AddrSize) /* We have no object file information and no line info for a new ** import */ - Error ("Invalid import size 0x%02X for symbol `%s'", + Error ("Invalid import size 0x%02X for symbol '%s'", I->AddrSize, GetString (I->Name)); } @@ -483,7 +483,7 @@ void InsertExport (Export* E) } } else { /* Duplicate entry, ignore it */ - Warning ("Duplicate external identifier: `%s'", + Warning ("Duplicate external identifier: '%s'", GetString (L->Name)); } return; @@ -662,7 +662,7 @@ long GetExportVal (const Export* E) { if (E->Expr == 0) { /* OOPS */ - Internal ("`%s' is an undefined external", GetString (E->Name)); + Internal ("'%s' is an undefined external", GetString (E->Name)); } return GetExprVal (E->Expr); } @@ -720,9 +720,9 @@ static void CheckSymType (const Export* E) } /* Output the diagnostic */ - Warning ("Address size mismatch for `%s': " - "Exported from %s as `%s', " - "import in %s as `%s'", + Warning ("Address size mismatch for '%s': " + "Exported from %s as '%s', " + "import in %s as '%s'", GetString (E->Name), SB_GetConstBuf (&ExportLoc), ExpAddrSize, @@ -770,7 +770,7 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data) /* Unresolved external */ Import* Imp = E->ImpList; fprintf (stderr, - "Unresolved external `%s' referenced in:\n", + "Unresolved external '%s' referenced in:\n", GetString (E->Name)); while (Imp) { unsigned J; @@ -1053,7 +1053,7 @@ void CircularRefError (const Export* E) /* Print an error about a circular reference using to define the given export */ { const LineInfo* LI = GetExportPos (E); - Error ("Circular reference for symbol `%s', %s(%u)", + Error ("Circular reference for symbol '%s', %s(%u)", GetString (E->Name), GetSourceName (LI), GetSourceLine (LI)); diff --git a/src/ld65/expr.c b/src/ld65/expr.c index efdff899e..2a08b5a98 100644 --- a/src/ld65/expr.c +++ b/src/ld65/expr.c @@ -407,12 +407,12 @@ long GetExprVal (ExprNode* Expr) Error ("Argument for .BANK is not segment relative or too complex"); } if (D.Seg->MemArea == 0) { - Error ("Segment `%s' is referenced by .BANK but " + Error ("Segment '%s' is referenced by .BANK but " "not assigned to a memory area", GetString (D.Seg->Name)); } if (D.Seg->MemArea->BankExpr == 0) { - Error ("Memory area `%s' is referenced by .BANK but " + Error ("Memory area '%s' is referenced by .BANK but " "has no BANK attribute", GetString (D.Seg->MemArea->Name)); } diff --git a/src/ld65/extsyms.c b/src/ld65/extsyms.c index b250125a7..cca10f3ad 100644 --- a/src/ld65/extsyms.c +++ b/src/ld65/extsyms.c @@ -89,7 +89,7 @@ ExtSym* NewExtSym (ExtSymTab* Tab, unsigned Name) ExtSym* E = GetExtSym (Tab, Name); if (E != 0) { /* We do already have a symbol with this name */ - Error ("Duplicate external symbol `%s'", GetString (Name)); + Error ("Duplicate external symbol '%s'", GetString (Name)); } /* Allocate memory for the structure */ diff --git a/src/ld65/library.c b/src/ld65/library.c index 0dadcfa67..dd964cff2 100644 --- a/src/ld65/library.c +++ b/src/ld65/library.c @@ -112,7 +112,7 @@ static void CloseLibrary (Library* L) { /* Close the library file */ if (fclose (L->F) != 0) { - Error ("Error closing `%s': %s", GetString (L->Name), strerror (errno)); + Error ("Error closing '%s': %s", GetString (L->Name), strerror (errno)); } L->F = 0; } @@ -144,7 +144,7 @@ static void LibSeek (Library* L, unsigned long Offs) /* Do a seek in the library checking for errors */ { if (fseek (L->F, Offs, SEEK_SET) != 0) { - Error ("Seek error in `%s' (%lu): %s", + Error ("Seek error in '%s' (%lu): %s", GetString (L->Name), Offs, strerror (errno)); } } @@ -158,7 +158,7 @@ static void LibReadHeader (Library* L) L->Header.Magic = LIB_MAGIC; L->Header.Version = Read16 (L->F); if (L->Header.Version != LIB_VERSION) { - Error ("Wrong data version in `%s'", GetString (L->Name)); + Error ("Wrong data version in '%s'", GetString (L->Name)); } L->Header.Flags = Read16 (L->F); L->Header.IndexOffs = Read32 (L->F); @@ -171,12 +171,12 @@ static void LibReadObjHeader (Library* L, ObjData* O) { O->Header.Magic = Read32 (L->F); if (O->Header.Magic != OBJ_MAGIC) { - Error ("Object file `%s' in library `%s' is invalid", + Error ("Object file '%s' in library '%s' is invalid", GetObjFileName (O), GetString (L->Name)); } O->Header.Version = Read16 (L->F); if (O->Header.Version != OBJ_VERSION) { - Error ("Object file `%s' in library `%s' has wrong version", + Error ("Object file '%s' in library '%s' has wrong version", GetObjFileName (O), GetString (L->Name)); } O->Header.Flags = Read16 (L->F); diff --git a/src/ld65/lineinfo.c b/src/ld65/lineinfo.c index 25eca4fcd..d2c1de0f7 100644 --- a/src/ld65/lineinfo.c +++ b/src/ld65/lineinfo.c @@ -162,7 +162,7 @@ void ReadLineInfoList (FILE* F, ObjData* O, Collection* LineInfos) ** therefore be part of the line infos read from the object file. */ if (LineInfoIndex >= CollCount (&O->LineInfos)) { - Internal ("Invalid line info index %u in module `%s' - max is %u", + Internal ("Invalid line info index %u in module '%s' - max is %u", LineInfoIndex, GetObjFileName (O), CollCount (&O->LineInfos)); diff --git a/src/ld65/main.c b/src/ld65/main.c index 74511a48a..e0dcf9727 100644 --- a/src/ld65/main.c +++ b/src/ld65/main.c @@ -123,7 +123,7 @@ static void Usage (void) " -m name\t\tCreate a map file\n" " -o name\t\tName the default output file\n" " -t sys\t\tSet the target system\n" - " -u sym\t\tForce an import of symbol `sym'\n" + " -u sym\t\tForce an import of symbol 'sym'\n" " -v\t\t\tVerbose mode\n" " -vm\t\t\tVerbose map file\n" "\n" @@ -133,7 +133,7 @@ static void Usage (void) " --dbgfile name\tGenerate debug information\n" " --define sym=val\tDefine a symbol\n" " --end-group\t\tEnd a library group\n" - " --force-import sym\tForce an import of symbol `sym'\n" + " --force-import sym\tForce an import of symbol 'sym'\n" " --help\t\tHelp (this text)\n" " --lib file\t\tLink this library\n" " --lib-path path\tSpecify a library search path\n" @@ -214,13 +214,13 @@ static void LinkFile (const char* Name, FILETYPE Type) /* We must have a valid name now */ if (PathName == 0) { - Error ("Input file `%s' not found", Name); + Error ("Input file '%s' not found", Name); } /* Try to open the file */ F = fopen (PathName, "rb"); if (F == 0) { - Error ("Cannot open `%s': %s", PathName, strerror (errno)); + Error ("Cannot open '%s': %s", PathName, strerror (errno)); } /* Read the magic word */ @@ -246,7 +246,7 @@ static void LinkFile (const char* Name, FILETYPE Type) default: fclose (F); - Error ("File `%s' has unknown type", PathName); + Error ("File '%s' has unknown type", PathName); } @@ -322,7 +322,7 @@ static void OptConfig (const char* Opt attribute ((unused)), const char* Arg) PathName = SearchFile (CfgDefaultPath, Arg); } if (PathName == 0) { - Error ("Cannot find config file `%s'", Arg); + Error ("Cannot find config file '%s'", Arg); } /* Read the config */ @@ -376,7 +376,7 @@ static void OptForceImport (const char* Opt attribute ((unused)), const char* Ar /* Get the address size and check it */ unsigned char AddrSize = AddrSizeFromStr (ColPos+1); if (AddrSize == ADDR_SIZE_INVALID) { - Error ("Invalid address size `%s'", ColPos+1); + Error ("Invalid address size '%s'", ColPos+1); } /* Create a copy of the argument */ @@ -509,7 +509,7 @@ static void OptTarget (const char* Opt attribute ((unused)), const char* Arg) /* Map the target name to a target id */ Target = FindTarget (Arg); if (Target == TGT_UNKNOWN) { - Error ("Invalid target name: `%s'", Arg); + Error ("Invalid target name: '%s'", Arg); } /* Set the target binary format */ @@ -526,7 +526,7 @@ static void OptTarget (const char* Opt attribute ((unused)), const char* Arg) PathName = SearchFile (CfgDefaultPath, SB_GetBuf (&FileName)); } if (PathName == 0) { - Error ("Cannot find config file `%s'", SB_GetBuf (&FileName)); + Error ("Cannot find config file '%s'", SB_GetBuf (&FileName)); } /* Free file name memory */ diff --git a/src/ld65/mapfile.c b/src/ld65/mapfile.c index 0cf9b651b..7fec986ff 100644 --- a/src/ld65/mapfile.c +++ b/src/ld65/mapfile.c @@ -67,7 +67,7 @@ void CreateMapFile (int ShortMap) /* Open the map file */ FILE* F = fopen (MapFileName, "w"); if (F == 0) { - Error ("Cannot create map file `%s': %s", MapFileName, strerror (errno)); + Error ("Cannot create map file '%s': %s", MapFileName, strerror (errno)); } /* Write a modules list */ @@ -132,7 +132,7 @@ void CreateMapFile (int ShortMap) /* Close the file */ if (fclose (F) != 0) { - Error ("Error closing map file `%s': %s", MapFileName, strerror (errno)); + Error ("Error closing map file '%s': %s", MapFileName, strerror (errno)); } } @@ -144,7 +144,7 @@ void CreateLabelFile (void) /* Open the label file */ FILE* F = fopen (LabelFileName, "w"); if (F == 0) { - Error ("Cannot create label file `%s': %s", LabelFileName, strerror (errno)); + Error ("Cannot create label file '%s': %s", LabelFileName, strerror (errno)); } /* Print the labels for the export symbols */ @@ -155,6 +155,6 @@ void CreateLabelFile (void) /* Close the file */ if (fclose (F) != 0) { - Error ("Error closing label file `%s': %s", LabelFileName, strerror (errno)); + Error ("Error closing label file '%s': %s", LabelFileName, strerror (errno)); } } diff --git a/src/ld65/o65.c b/src/ld65/o65.c index aceb5158a..e36f40d36 100644 --- a/src/ld65/o65.c +++ b/src/ld65/o65.c @@ -784,7 +784,7 @@ static void O65WriteSeg (O65Desc* D, SegDesc** Seg, unsigned Count, int DoWrite) S = Seg [I]; /* Keep the user happy */ - Print (stdout, 1, " Writing `%s'\n", GetString (S->Name)); + Print (stdout, 1, " Writing '%s'\n", GetString (S->Name)); /* Write this segment */ if (DoWrite) { @@ -805,7 +805,7 @@ static void O65WriteSeg (O65Desc* D, SegDesc** Seg, unsigned Count, int DoWrite) /* Check the size of the segment for overflow */ if ((D->Header.Mode & MF_SIZE_MASK) == MF_SIZE_16BIT && D->SegSize > 0xFFFF) { - Error ("Segment overflow in file `%s'", D->Filename); + Error ("Segment overflow in file '%s'", D->Filename); } } @@ -940,7 +940,7 @@ static void O65WriteExports (O65Desc* D) */ Export* E = FindExport (NameIdx); if (E == 0 || IsUnresolvedExport (E)) { - Internal ("Unresolved export `%s' found in O65WriteExports", Name); + Internal ("Unresolved export '%s' found in O65WriteExports", Name); } /* Get the expression for the symbol */ @@ -958,7 +958,7 @@ static void O65WriteExports (O65Desc* D) /* Bail out if we cannot handle the expression */ if (ED.TooComplex) { - Error ("Expression for symbol `%s' is too complex", Name); + Error ("Expression for symbol '%s' is too complex", Name); } /* Determine the segment id for the expression */ @@ -977,7 +977,7 @@ static void O65WriteExports (O65Desc* D) /* For some reason, we didn't find this segment in the list of ** segments written to the o65 file. */ - Error ("Segment for symbol `%s' is undefined", Name); + Error ("Segment for symbol '%s' is undefined", Name); } SegmentID = O65SegType (Seg); @@ -1207,7 +1207,7 @@ void O65SetExport (O65Desc* D, unsigned Ident) */ Export* E = FindExport (Ident); if (E == 0 || IsUnresolvedExport (E)) { - Error ("Unresolved export: `%s'", GetString (Ident)); + Error ("Unresolved export: '%s'", GetString (Ident)); } /* Insert the entry into the table */ @@ -1370,11 +1370,11 @@ void O65WriteTarget (O65Desc* D, File* F) /* Open the file */ D->F = fopen (D->Filename, "wb"); if (D->F == 0) { - Error ("Cannot open `%s': %s", D->Filename, strerror (errno)); + Error ("Cannot open '%s': %s", D->Filename, strerror (errno)); } /* Keep the user happy */ - Print (stdout, 1, "Opened `%s'...\n", D->Filename); + Print (stdout, 1, "Opened '%s'...\n", D->Filename); /* Define some more options: A timestamp, the linker version and the ** filename @@ -1428,7 +1428,7 @@ void O65WriteTarget (O65Desc* D, File* F) /* Close the file */ if (fclose (D->F) != 0) { - Error ("Cannot write to `%s': %s", D->Filename, strerror (errno)); + Error ("Cannot write to '%s': %s", D->Filename, strerror (errno)); } /* Reset the file and filename */ diff --git a/src/ld65/objdata.c b/src/ld65/objdata.c index 7e83f9107..88a7bded4 100644 --- a/src/ld65/objdata.c +++ b/src/ld65/objdata.c @@ -184,7 +184,7 @@ unsigned MakeGlobalStringId (const ObjData* O, unsigned Index) /* Convert a local string id into a global one and return it. */ { if (Index >= O->StringCount) { - Error ("Invalid string index (%u) in module `%s'", + Error ("Invalid string index (%u) in module '%s'", Index, GetObjFileName (O)); } return O->Strings[Index]; @@ -214,7 +214,7 @@ struct Section* GetObjSection (const ObjData* O, unsigned Id) /* Get a section from an object file checking for a valid index */ { if (Id >= CollCount (&O->Sections)) { - Error ("Invalid section index (%u) in module `%s'", + Error ("Invalid section index (%u) in module '%s'", Id, GetObjFileName (O)); } return CollAtUnchecked (&O->Sections, Id); @@ -226,7 +226,7 @@ struct Import* GetObjImport (const ObjData* O, unsigned Id) /* Get an import from an object file checking for a valid index */ { if (Id >= CollCount (&O->Imports)) { - Error ("Invalid import index (%u) in module `%s'", + Error ("Invalid import index (%u) in module '%s'", Id, GetObjFileName (O)); } return CollAtUnchecked (&O->Imports, Id); @@ -238,7 +238,7 @@ struct Export* GetObjExport (const ObjData* O, unsigned Id) /* Get an export from an object file checking for a valid index */ { if (Id >= CollCount (&O->Exports)) { - Error ("Invalid export index (%u) in module `%s'", + Error ("Invalid export index (%u) in module '%s'", Id, GetObjFileName (O)); } return CollAtUnchecked (&O->Exports, Id); @@ -250,7 +250,7 @@ struct DbgSym* GetObjDbgSym (const ObjData* O, unsigned Id) /* Get a debug symbol from an object file checking for a valid index */ { if (Id >= CollCount (&O->DbgSyms)) { - Error ("Invalid debug symbol index (%u) in module `%s'", + Error ("Invalid debug symbol index (%u) in module '%s'", Id, GetObjFileName (O)); } return CollAtUnchecked (&O->DbgSyms, Id); @@ -262,7 +262,7 @@ struct Scope* GetObjScope (const ObjData* O, unsigned Id) /* Get a scope from an object file checking for a valid index */ { if (Id >= CollCount (&O->Scopes)) { - Error ("Invalid scope index (%u) in module `%s'", + Error ("Invalid scope index (%u) in module '%s'", Id, GetObjFileName (O)); } return CollAtUnchecked (&O->Scopes, Id); diff --git a/src/ld65/objfile.c b/src/ld65/objfile.c index 870ca5221..a44e3239a 100644 --- a/src/ld65/objfile.c +++ b/src/ld65/objfile.c @@ -67,7 +67,7 @@ static unsigned GetModule (const char* Name) /* Make a module name from the file name */ const char* Module = FindName (Name); if (*Module == 0) { - Error ("Cannot make module name from `%s'", Name); + Error ("Cannot make module name from '%s'", Name); } return GetStringId (Module); } @@ -79,7 +79,7 @@ static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name) { H->Version = Read16 (Obj); if (H->Version != OBJ_VERSION) { - Error ("Object file `%s' has wrong version, expected %08X, got %08X", + Error ("Object file '%s' has wrong version, expected %08X, got %08X", Name, OBJ_VERSION, H->Version); } H->Flags = Read16 (Obj); diff --git a/src/ld65/scanner.c b/src/ld65/scanner.c index 3c2346aac..31f1c7a41 100644 --- a/src/ld65/scanner.c +++ b/src/ld65/scanner.c @@ -196,7 +196,7 @@ static void StrVal (void) default: CfgWarning (&CfgErrorPos, - "Unkown escape sequence `%%%c'", C); + "Unkown escape sequence '%%%c'", C); SB_AppendChar (&CfgSVal, '%'); SB_AppendChar (&CfgSVal, C); NextChar (); @@ -389,7 +389,7 @@ Again: break; default: - CfgError (&CfgErrorPos, "Invalid character `%c'", C); + CfgError (&CfgErrorPos, "Invalid character '%c'", C); } } @@ -410,7 +410,7 @@ void CfgConsume (cfgtok_t T, const char* Msg) void CfgConsumeSemi (void) /* Consume a semicolon */ { - CfgConsume (CFGTOK_SEMI, "`;' expected"); + CfgConsume (CFGTOK_SEMI, "';' expected"); } @@ -418,7 +418,7 @@ void CfgConsumeSemi (void) void CfgConsumeColon (void) /* Consume a colon */ { - CfgConsume (CFGTOK_COLON, "`:' expected"); + CfgConsume (CFGTOK_COLON, "':' expected"); } @@ -556,7 +556,7 @@ void CfgOpenInput (void) /* Open the file */ InputFile = fopen (CfgName, "r"); if (InputFile == 0) { - Error ("Cannot open `%s': %s", CfgName, strerror (errno)); + Error ("Cannot open '%s': %s", CfgName, strerror (errno)); } /* Initialize variables */ diff --git a/src/ld65/scopes.c b/src/ld65/scopes.c index edf0d0da2..cf40fac01 100644 --- a/src/ld65/scopes.c +++ b/src/ld65/scopes.c @@ -147,7 +147,7 @@ void PrintDbgScopes (FILE* F) case SCOPE_ENUM: fputs (",type=enum", F); break; default: - Error ("Module `%s': Unknown scope type %u", + Error ("Module '%s': Unknown scope type %u", GetObjFileName (O), S->Type); } diff --git a/src/ld65/segments.c b/src/ld65/segments.c index 9c3972ac5..56a4719ad 100644 --- a/src/ld65/segments.c +++ b/src/ld65/segments.c @@ -144,7 +144,7 @@ Segment* GetSegment (unsigned Name, unsigned char AddrSize, const char* ObjName) if (ObjName == 0) { ObjName = "[linker generated]"; } - Error ("Module `%s': Type mismatch for segment `%s'", ObjName, + Error ("Module '%s': Type mismatch for segment '%s'", ObjName, GetString (Name)); } } @@ -210,7 +210,7 @@ Section* ReadSection (FILE* F, ObjData* O) /* Print some data */ Print (stdout, 2, - "Module `%s': Found segment `%s', size = %u, alignment = %lu, type = %u\n", + "Module '%s': Found segment '%s', size = %u, alignment = %lu, type = %u\n", GetObjFileName (O), GetString (Name), Size, Alignment, Type); /* Get the segment for this section */ @@ -226,13 +226,13 @@ Section* ReadSection (FILE* F, ObjData* O) if (Sec->Alignment > 1) { Alignment = LeastCommonMultiple (S->Alignment, Sec->Alignment); if (Alignment > MAX_ALIGNMENT) { - Error ("Combined alignment for segment `%s' is %lu which exceeds " - "%lu. Last module requiring alignment was `%s'.", + Error ("Combined alignment for segment '%s' is %lu which exceeds " + "%lu. Last module requiring alignment was '%s'.", GetString (Name), Alignment, MAX_ALIGNMENT, GetObjFileName (O)); } else if (Alignment >= LARGE_ALIGNMENT) { - Warning ("Combined alignment for segment `%s' is suspiciously " - "large (%lu). Last module requiring alignment was `%s'.", + Warning ("Combined alignment for segment '%s' is suspiciously " + "large (%lu). Last module requiring alignment was '%s'.", GetString (Name), Alignment, GetObjFileName (O)); } S->Alignment = Alignment; @@ -270,7 +270,7 @@ Section* ReadSection (FILE* F, ObjData* O) break; default: - Error ("Unknown fragment type in module `%s', segment `%s': %02X", + Error ("Unknown fragment type in module '%s', segment '%s': %02X", GetObjFileName (O), GetString (S->Name), Type); /* NOTREACHED */ return 0; @@ -502,19 +502,19 @@ void SegWrite (const char* TgtName, FILE* Tgt, Segment* S, SegWriteFunc F, void* break; case SEG_EXPR_RANGE_ERROR: - Error ("Range error in module `%s', line %u", + Error ("Range error in module '%s', line %u", GetFragmentSourceName (Frag), GetFragmentSourceLine (Frag)); break; case SEG_EXPR_TOO_COMPLEX: - Error ("Expression too complex in module `%s', line %u", + Error ("Expression too complex in module '%s', line %u", GetFragmentSourceName (Frag), GetFragmentSourceLine (Frag)); break; case SEG_EXPR_INVALID: - Error ("Invalid expression in module `%s', line %u", + Error ("Invalid expression in module '%s', line %u", GetFragmentSourceName (Frag), GetFragmentSourceLine (Frag)); break; @@ -657,7 +657,7 @@ void CheckSegments (void) /* Check it */ if (S->Size > 0 && S->Dumped == 0) { - Error ("Missing memory area assignment for segment `%s'", + Error ("Missing memory area assignment for segment '%s'", GetString (S->Name)); } } diff --git a/src/od65/main.c b/src/od65/main.c index 2d23f4202..ce71608ed 100644 --- a/src/od65/main.c +++ b/src/od65/main.c @@ -222,7 +222,7 @@ static void DumpFile (const char* Name) /* Try to open the file */ FILE* F = fopen (Name, "rb"); if (F == 0) { - Error ("Cannot open `%s': %s", Name, strerror (errno)); + Error ("Cannot open '%s': %s", Name, strerror (errno)); } /* Read the magic word */ diff --git a/src/sim65/main.c b/src/sim65/main.c index f7f73165a..a1bbc5561 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -141,13 +141,13 @@ static void ReadProgramFile (void) /* Open the file */ FILE* F = fopen (ProgramFile, "rb"); if (F == 0) { - Error ("Cannot open `%s': %s", ProgramFile, strerror (errno)); + Error ("Cannot open '%s': %s", ProgramFile, strerror (errno)); } /* Get the CPU type from the file header */ if ((Val = fgetc(F)) != EOF) { if (Val != CPU_6502 && Val != CPU_65C02) { - Error ("`%s': Invalid CPU type", ProgramFile); + Error ("'%s': Invalid CPU type", ProgramFile); } CPU = Val; } @@ -155,20 +155,20 @@ static void ReadProgramFile (void) /* Read the file body into memory */ while ((Val = fgetc(F)) != EOF) { if (Addr == 0xFF00) { - Error ("`%s': To large to fit into $0200-$FFF0", ProgramFile); + Error ("'%s': To large to fit into $0200-$FFF0", ProgramFile); } MemWriteByte (Addr++, (unsigned char) Val); } /* Check for errors */ if (ferror (F)) { - Error ("Error reading from `%s': %s", ProgramFile, strerror (errno)); + Error ("Error reading from '%s': %s", ProgramFile, strerror (errno)); } /* Close the file */ fclose (F); - Print (stderr, 1, "Loaded `%s' at $0200-$%04X\n", ProgramFile, Addr - 1); + Print (stderr, 1, "Loaded '%s' at $0200-$%04X\n", ProgramFile, Addr - 1); } diff --git a/src/sp65/asm.c b/src/sp65/asm.c index 8f520cb9e..74c9bc023 100644 --- a/src/sp65/asm.c +++ b/src/sp65/asm.c @@ -89,7 +89,7 @@ static unsigned GetBytesPerLine (const Collection* A) const char* V = GetAttrVal (A, "bytesperline"); if ((V && sscanf (V, "%u%c", &BytesPerLine, &C) != 1) || (BytesPerLine < 1 || BytesPerLine > 64)) { - Error ("Invalid value for attribute `bytesperline'"); + Error ("Invalid value for attribute 'bytesperline'"); } return BytesPerLine; } @@ -106,7 +106,7 @@ static unsigned GetBase (const Collection* A) const char* V = GetAttrVal (A, "base"); if ((V && sscanf (V, "%u%c", &Base, &C) != 1) || (Base != 2 && Base != 10 && Base != 16)) { - Error ("Invalid value for attribute `base'"); + Error ("Invalid value for attribute 'base'"); } return Base; } @@ -119,7 +119,7 @@ static const char* GetIdentifier (const Collection* A) /* Check for a ident attribute */ const char* Ident = GetAttrVal (A, "ident"); if (Ident && !ValidIdentifier (Ident)) { - Error ("Invalid value for attribute `ident'"); + Error ("Invalid value for attribute 'ident'"); } return Ident; } @@ -152,7 +152,7 @@ void WriteAsmFile (const StrBuf* Data, const Collection* A, const Bitmap* B) /* Open the output file */ F = fopen (Name, "w"); if (F == 0) { - Error ("Cannot open output file `%s': %s", Name, strerror (errno)); + Error ("Cannot open output file '%s': %s", Name, strerror (errno)); } /* Write a readable header */ @@ -235,6 +235,6 @@ void WriteAsmFile (const StrBuf* Data, const Collection* A, const Bitmap* B) /* Close the file */ if (fclose (F) != 0) { - Error ("Error closing output file `%s': %s", Name, strerror (errno)); + Error ("Error closing output file '%s': %s", Name, strerror (errno)); } } diff --git a/src/sp65/attr.c b/src/sp65/attr.c index e57b86973..1b7883c47 100644 --- a/src/sp65/attr.c +++ b/src/sp65/attr.c @@ -160,7 +160,7 @@ const Attr* NeedAttr (const Collection* C, const char* Name, const char* Op) /* Search for the attribute and return it */ unsigned Index; if (!FindAttr (C, Name, &Index)) { - Error ("Found no attribute named `%s' for operation %s", Name, Op); + Error ("Found no attribute named '%s' for operation %s", Name, Op); } return CollConstAt (C, Index); } @@ -201,7 +201,7 @@ void AddAttr (Collection* C, const char* Name, const char* Value) */ unsigned Index; if (FindAttr (C, Name, &Index)) { - Error ("Duplicate command line attribute `%s'", Name); + Error ("Duplicate command line attribute '%s'", Name); } /* Insert the attribute */ @@ -221,7 +221,7 @@ void SplitAddAttr (Collection* C, const char* Combined, const char* Name) if (Pos == 0) { /* Combined is actually a value */ if (Name == 0) { - Error ("Command line attribute `%s' doesn't contain a name", Combined); + Error ("Command line attribute '%s' doesn't contain a name", Combined); } AddAttr (C, Name, Combined); } else { diff --git a/src/sp65/bin.c b/src/sp65/bin.c index fdf7ddee0..a3f856340 100644 --- a/src/sp65/bin.c +++ b/src/sp65/bin.c @@ -65,7 +65,7 @@ void WriteBinFile (const StrBuf* Data, const Collection* A, /* Open the output file */ FILE* F = fopen (Name, "wb"); if (F == 0) { - Error ("Cannot open output file `%s': %s", Name, strerror (errno)); + Error ("Cannot open output file '%s': %s", Name, strerror (errno)); } /* Write to the file. We will use fwrite here instead of the fileio @@ -75,11 +75,11 @@ void WriteBinFile (const StrBuf* Data, const Collection* A, */ Size = SB_GetLen (Data); if (fwrite (SB_GetConstBuf (Data), 1, Size, F) != Size) { - Error ("Error writing to output file `%s': %s", Name, strerror (errno)); + Error ("Error writing to output file '%s': %s", Name, strerror (errno)); } /* Close the file */ if (fclose (F) != 0) { - Error ("Error closing output file `%s': %s", Name, strerror (errno)); + Error ("Error closing output file '%s': %s", Name, strerror (errno)); } } diff --git a/src/sp65/c.c b/src/sp65/c.c index d4d6ee00b..57950ca6d 100644 --- a/src/sp65/c.c +++ b/src/sp65/c.c @@ -89,7 +89,7 @@ static unsigned GetBytesPerLine (const Collection* A) const char* V = GetAttrVal (A, "bytesperline"); if ((V && sscanf (V, "%u%c", &BytesPerLine, &C) != 1) || (BytesPerLine < 1 || BytesPerLine > 64)) { - Error ("Invalid value for attribute `bytesperline'"); + Error ("Invalid value for attribute 'bytesperline'"); } return BytesPerLine; } @@ -105,7 +105,7 @@ static unsigned GetBase (const Collection* A) /* Check for a base attribute */ const char* V = GetAttrVal (A, "base"); if ((V && sscanf (V, "%u%c", &Base, &C) != 1) || (Base != 10 && Base != 16)) { - Error ("Invalid value for attribute `base'"); + Error ("Invalid value for attribute 'base'"); } return Base; } @@ -118,7 +118,7 @@ static const char* GetIdentifier (const Collection* A) /* Check for a ident attribute */ const char* Ident = GetAttrVal (A, "ident"); if (Ident && !ValidIdentifier (Ident)) { - Error ("Invalid value for attribute `ident'"); + Error ("Invalid value for attribute 'ident'"); } return Ident; } @@ -151,7 +151,7 @@ void WriteCFile (const StrBuf* Data, const Collection* A, const Bitmap* B) /* Open the output file */ F = fopen (Name, "w"); if (F == 0) { - Error ("Cannot open output file `%s': %s", Name, strerror (errno)); + Error ("Cannot open output file '%s': %s", Name, strerror (errno)); } /* Write a readable header */ @@ -220,6 +220,6 @@ void WriteCFile (const StrBuf* Data, const Collection* A, const Bitmap* B) /* Close the file */ if (fclose (F) != 0) { - Error ("Error closing output file `%s': %s", Name, strerror (errno)); + Error ("Error closing output file '%s': %s", Name, strerror (errno)); } } diff --git a/src/sp65/convert.c b/src/sp65/convert.c index 45b40f1ef..a9047ffb0 100644 --- a/src/sp65/convert.c +++ b/src/sp65/convert.c @@ -106,7 +106,7 @@ StrBuf* ConvertTo (const Bitmap* B, const Collection* A) sizeof (ConverterMap[0]), Compare); if (E == 0) { - Error ("No such target format: `%s'", Format); + Error ("No such target format: '%s'", Format); } /* Do the conversion */ diff --git a/src/sp65/input.c b/src/sp65/input.c index 381adf6b9..f1df247ae 100644 --- a/src/sp65/input.c +++ b/src/sp65/input.c @@ -103,7 +103,7 @@ Bitmap* ReadInputFile (const Collection* A) sizeof (FormatTable[0]), CompareFileId); if (F == 0) { - Error ("Unknown input format `%s'", Format); + Error ("Unknown input format '%s'", Format); } } else { /* No format given, use file name extension */ @@ -112,7 +112,7 @@ Bitmap* ReadInputFile (const Collection* A) sizeof (FormatTable) / sizeof (FormatTable[0])); /* Found? */ if (F == 0) { - Error ("Cannot determine file format of input file `%s'", Name); + Error ("Cannot determine file format of input file '%s'", Name); } } diff --git a/src/sp65/lynxsprite.c b/src/sp65/lynxsprite.c index e4afc7773..4d7669faf 100644 --- a/src/sp65/lynxsprite.c +++ b/src/sp65/lynxsprite.c @@ -80,7 +80,7 @@ static enum Mode GetMode (const Collection* A) } else if (strcmp (Mode, "shaped") == 0) { return smShaped; } else { - Error ("Invalid value for attribute `mode'"); + Error ("Invalid value for attribute 'mode'"); } } diff --git a/src/sp65/main.c b/src/sp65/main.c index 5c9724a8a..1dda696d6 100644 --- a/src/sp65/main.c +++ b/src/sp65/main.c @@ -392,7 +392,7 @@ int main (int argc, char* argv []) } } else { /* We don't accept anything else */ - AbEnd ("Don't know what to do with `%s'", Arg); + AbEnd ("Don't know what to do with '%s'", Arg); } /* Next argument */ diff --git a/src/sp65/output.c b/src/sp65/output.c index 3ffa38dcc..c12d1f612 100644 --- a/src/sp65/output.c +++ b/src/sp65/output.c @@ -124,7 +124,7 @@ void WriteOutputFile (const StrBuf* Data, const Collection* A, const Bitmap* B) sizeof (FormatTable[0]), CompareFileId); if (F == 0) { - Error ("Unknown output format `%s'", Format); + Error ("Unknown output format '%s'", Format); } } else { /* No format given, use file name extension */ @@ -133,7 +133,7 @@ void WriteOutputFile (const StrBuf* Data, const Collection* A, const Bitmap* B) sizeof (FormatTable) / sizeof (FormatTable[0])); /* Found? */ if (F == 0) { - Error ("Cannot determine file format of output file `%s'", Name); + Error ("Cannot determine file format of output file '%s'", Name); } } diff --git a/src/sp65/pcx.c b/src/sp65/pcx.c index 273ad8cf0..d721671b3 100644 --- a/src/sp65/pcx.c +++ b/src/sp65/pcx.c @@ -146,10 +146,10 @@ static PCXHeader* ReadPCXHeader (FILE* F, const char* Name) /* Check the header data */ if (P->Id != PCX_MAGIC_ID || P->FileVersion == 1 || P->FileVersion > 5) { - Error ("`%s' is not a PCX file", Name); + Error ("'%s' is not a PCX file", Name); } if (P->Compressed > 1) { - Error ("Unsupported compression (%d) in PCX file `%s'", + Error ("Unsupported compression (%d) in PCX file '%s'", P->Compressed, Name); } /* We support: @@ -160,15 +160,15 @@ static PCXHeader* ReadPCXHeader (FILE* F, const char* Name) if (!((P->BPP == 1 && P->Planes == 1) || (P->BPP == 8 && (P->Planes == 1 || P->Planes == 3 || P->Planes == 4)))) { /* We could support others, but currently we don't */ - Error ("Unsupported PCX format: %u planes, %u bpp in PCX file `%s'", + Error ("Unsupported PCX format: %u planes, %u bpp in PCX file '%s'", P->Planes, P->BPP, Name); } if (P->PalInfo != 1 && P->PalInfo != 2) { - Error ("Unsupported palette info (%u) in PCX file `%s'", + Error ("Unsupported palette info (%u) in PCX file '%s'", P->PalInfo, Name); } if (!ValidBitmapSize (P->Width, P->Height)) { - Error ("PCX file `%s' has an unsupported size (w=%u, h=%d)", + Error ("PCX file '%s' has an unsupported size (w=%u, h=%d)", Name, P->Width, P->Height); } @@ -261,7 +261,7 @@ Bitmap* ReadPCXFile (const Collection* A) /* Open the file */ FILE* F = fopen (Name, "rb"); if (F == 0) { - Error ("Cannot open PCX file `%s': %s", Name, strerror (errno)); + Error ("Cannot open PCX file '%s': %s", Name, strerror (errno)); } /* Read the PCX header */ @@ -357,7 +357,7 @@ Bitmap* ReadPCXFile (const Collection* A) /* Check for palette marker */ if (Read8 (F) != 0x0C) { - Error ("Invalid palette marker in PCX file `%s'", Name); + Error ("Invalid palette marker in PCX file '%s'", Name); } } else if (EndPos == CurPos) { @@ -367,12 +367,12 @@ Bitmap* ReadPCXFile (const Collection* A) /* Check the maximum index for safety */ if (MaxIdx > 15) { - Error ("PCX file `%s' contains more than 16 indexed colors " + Error ("PCX file '%s' contains more than 16 indexed colors " "but no extra palette", Name); } } else { - Error ("Error in PCX file `%s': %lu bytes at end of pixel data", + Error ("Error in PCX file '%s': %lu bytes at end of pixel data", Name, EndPos - CurPos); } diff --git a/src/sp65/vic2sprite.c b/src/sp65/vic2sprite.c index 3e99ec7b2..94a9ad499 100644 --- a/src/sp65/vic2sprite.c +++ b/src/sp65/vic2sprite.c @@ -81,7 +81,7 @@ static enum Mode GetMode (const Collection* A) } else if (strcmp (Mode, "multicolor") == 0) { return smMultiColor; } else { - Error ("Invalid value for attribute `mode'"); + Error ("Invalid value for attribute 'mode'"); } } diff --git a/test/misc/goto.ref b/test/misc/goto.ref index ad69cdfe2..85dc20a61 100644 --- a/test/misc/goto.ref +++ b/test/misc/goto.ref @@ -1,7 +1,7 @@ goto.c(8): Warning: Goto at line 8 to label start jumps into a block with initialization of an object that has automatic storage duration -goto.c(97): Warning: `a' is defined but never used -goto.c(117): Warning: `a' is defined but never used -goto.c(137): Warning: `a' is defined but never used +goto.c(97): Warning: 'a' is defined but never used +goto.c(117): Warning: 'a' is defined but never used +goto.c(137): Warning: 'a' is defined but never used goto.c(159): Warning: Goto at line 23 to label l8 jumps into a block with initialization of an object that has automatic storage duration goto.c(159): Warning: Goto at line 44 to label l8 jumps into a block with initialization of an object that has automatic storage duration goto.c(159): Warning: Goto at line 65 to label l8 jumps into a block with initialization of an object that has automatic storage duration diff --git a/test/ref/cc65090124.c b/test/ref/cc65090124.c index 3f8279b27..3a75b28fa 100644 --- a/test/ref/cc65090124.c +++ b/test/ref/cc65090124.c @@ -32,7 +32,7 @@ int main(void) fs=(func((fd/a),(func(2,0x0082c90f)))); } -i get "Error: `)' expected" on that line. (this is with the snapshot, freshly +i get "Error: ')' expected" on that line. (this is with the snapshot, freshly compiled 5 minutes ago) */ diff --git a/test/ref/cc65091022.c b/test/ref/cc65091022.c index 25d197c11..ea19afe43 100644 --- a/test/ref/cc65091022.c +++ b/test/ref/cc65091022.c @@ -8,7 +8,7 @@ #include <stdio.h> /* -...gives "test.c(2): Error: Variable `foo' has unknown size" using -Cl. +...gives "test.c(2): Error: Variable 'foo' has unknown size" using -Cl. Is it really unknown? cc65 V2.13.0, SVN version: 4384 diff --git a/test/ref/cc65101102.c b/test/ref/cc65101102.c index 4faa7c12b..1f87f65b5 100644 --- a/test/ref/cc65101102.c +++ b/test/ref/cc65101102.c @@ -11,12 +11,12 @@ Compiler is build from cc65-snapshot-2.13.9.20101031 sources. Expected results and also what I get from this without any optimisations are: 48663 and 49218 -When I turn on ``-O``: 58096 and 58096. After swapping the two variable -declaration lines in `calculate_checksum()` the results are correct -with ``-O``. +When I turn on ''-O'': 58096 and 58096. After swapping the two variable +declaration lines in 'calculate_checksum()' the results are correct +with ''-O''. -But with ``--O --static-locals`` the results are incorrect again (31757 -and 15408). ``--static-locals`` alone works though. +But with ''--O --static-locals'' the results are incorrect again (31757 +and 15408). ''--static-locals'' alone works though. */ #include <stdio.h> diff --git a/test/ref/cc65110210.c b/test/ref/cc65110210.c index 2c7853556..ca5b39203 100644 --- a/test/ref/cc65110210.c +++ b/test/ref/cc65110210.c @@ -8,15 +8,15 @@ with SVN version: 4973M $ cl65 -v -o test.prg tests/cc65110210.c -Opened include file `/usr/local/lib/cc65/include/stdio.h' -Opened include file `/usr/local/lib/cc65/include/stddef.h' -Opened include file `/usr/local/lib/cc65/include/stdarg.h' -Opened include file `/usr/local/lib/cc65/include/limits.h' +Opened include file '/usr/local/lib/cc65/include/stdio.h' +Opened include file '/usr/local/lib/cc65/include/stddef.h' +Opened include file '/usr/local/lib/cc65/include/stdarg.h' +Opened include file '/usr/local/lib/cc65/include/limits.h' 0 errors, 0 warnings -Opened output file `tests/cc65110210.s' -Wrote output to `tests/cc65110210.s' -Closed output file `tests/cc65110210.s' -cl65: Subprocess `ld65' aborted by signal 11 +Opened output file 'tests/cc65110210.s' +Wrote output to 'tests/cc65110210.s' +Closed output file 'tests/cc65110210.s' +cl65: Subprocess 'ld65' aborted by signal 11 */ diff --git a/test/ref/paranoia.c b/test/ref/paranoia.c index e9a47dd71..e4833bd16 100644 --- a/test/ref/paranoia.c +++ b/test/ref/paranoia.c @@ -1626,7 +1626,7 @@ part7(){ overflow: sigsave = 0; Z = V9; - printf("Can `Z = -Y' overflow?\n"); + printf("Can 'Z = -Y' overflow?\n"); printf("Trying it on Y = %.17e .\n", Y); V9 = - Y; V0 = V9; @@ -2087,7 +2087,7 @@ Instructions() { static char *instr[] = { "Lest this program stop prematurely, i.e. before displaying\n", - " `END OF TEST',\n", + " 'END OF TEST',\n", "try to persuade the computer NOT to terminate execution when an", "error like Over/Underflow or Division by Zero occurs, but rather", "to persevere with a surrogate value after, perhaps, displaying some", @@ -2170,8 +2170,8 @@ History() " FAILUREs, like 2+2 == 5 .", "Failures may confound subsequent diagnoses.\n", "The diagnostic capabilities of this program go beyond an earlier", - "program called `MACHAR', which can be found at the end of the", - "book `Software Manual for the Elementary Functions' (1980) by", + "program called 'MACHAR', which can be found at the end of the", + "book 'Software Manual for the Elementary Functions' (1980) by", "W. J. Cody and W. Waite. Although both programs try to discover", "the Radix, Precision and range (over/underflow thresholds)", "of the arithmetic, this program tries to cope with a wider variety", diff --git a/test/val/compare1.c b/test/val/compare1.c index 0127e3b1b..e9d2f7d4a 100644 --- a/test/val/compare1.c +++ b/test/val/compare1.c @@ -52,7 +52,7 @@ compare_char_to_lits1 (void) failures++; } -/* achar0 should be `5' */ +/* achar0 should be '5' */ void compare_char_to_lits2 (void) { @@ -106,7 +106,7 @@ compare_int_to_lits1 (void) failures++; } -/* aint0 should be `5' */ +/* aint0 should be '5' */ void compare_int_to_lits2 (void) { @@ -123,7 +123,7 @@ compare_int_to_lits2 (void) failures++; } -/* aint0 should be `0x1234' */ +/* aint0 should be '0x1234' */ void compare_int_to_lits3 (void) { From ab31b3edfebf5f54af71b4050bfc9cdae50b797f Mon Sep 17 00:00:00 2001 From: Bill Kendrick <nbs@sonic.net> Date: Sun, 13 Jan 2019 00:31:31 -0800 Subject: [PATCH 0969/2161] Add more register #defines to ANTIC header file * DMACTL - playfield size, DMA access, PMG resolution * CHACTL - inverted text, inverse effects * NMIEN Also, added #define equivalents for Display List mode line instructions based on Atari 8-bit OS (aka Atari BASIC "GRAPHICS" command) values (e.g., "DL_GRAPHICS0" == "DL_CHR40x8x1"). Added some more documentation in the comments. Added macros with assembly language for the start/end of Display List Interrupt (DLI) functions. --- include/_antic.h | 130 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 103 insertions(+), 27 deletions(-) diff --git a/include/_antic.h b/include/_antic.h index 2aac3fccf..0d1bdaf65 100644 --- a/include/_antic.h +++ b/include/_antic.h @@ -5,9 +5,19 @@ /* Internal include file, do not use directly */ /* */ /* */ +/* "ANTIC is responsible for the generation of playfield graphics which is */ +/* delivered as a datastream to the related CTIA/GTIA chip. The CTIA/GTIA */ +/* provides the coloring of the playfield graphics, and is responsible for */ +/* adding overlaid sprites referred to as "Player/Missile graphics" by */ +/* Atari. Atari advertised it as a true microprocessor, in that it has an */ +/* instruction set to run programs (called display lists) to process data. */ +/* ANTIC has no capacity for writing back computed values to memory, it */ +/* merely reads data from memory and processes it for output to the screen, */ +/* therefore it is not Turing complete." - Wikipedia article on "ANTIC" */ /* */ /* (C) 2000 Freddy Offenga <taf_offenga@yahoo.com> */ /* 24-Jan-2011: Christian Krueger: Added defines for Antic instruction set */ +/* 2019-01-12: Bill Kendrick <nbs@sonic.net>: More defines for registers */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -33,50 +43,86 @@ #ifndef __ANTIC_H #define __ANTIC_H -/* Define a structure with the antic register offsets */ +/* Define a structure with the ANTIC coprocessor's register offsets */ struct __antic { - unsigned char dmactl; /* direct memory access control */ - unsigned char chactl; /* character mode control */ + unsigned char dmactl; /* (W) direct memory access control */ + +/* Playfield modes: */ +#define DMACTL_PLAYFIELD_NONE 0x00 +#define DMACTL_PLAYFIELD_NARROW 0x01 /* e.g., 32 bytes per scanline with thick borders */ +#define DMACTL_PLAYFIELD_NORMAL 0x02 /* e.g., 40 bytes per scanline with normal borders */ +#define DMACTL_PLAYFIELD_WIDE 0x03 /* e.g., 48 bytes per scanline with no borders (overscan) */ +/* Other options: */ +#define DMACTL_DMA_MISSILES 0x04 /* if not set, GTIA's GRAFP0 thru GRAFP3 used for player shapes; if set, ANTIC's PMBASE will be used to fetch shapes via DMA */ +#define DMACTL_DMA_PLAYERS 0x08 /* (ditto, using GTIA's GRAFM for missile shapes...) */ +#define DMACTL_PMG_SINGLELINE 0x10 /* if not set, default is double-scanline resolution PMGs */ +#define DMACTL_DMA_FETCH 0x20 /* if not set, disables ANTIC operation since it cannot fetch Display List instructions */ +/* Initialized to 0x22 (DMA fetch, normal playfield, no PMG DMA, double-line PMGs) */ + + + unsigned char chactl; /* (W) character mode control */ + +/* Inverted (upside-down) characters */ +#define CHACTL_CHAR_NORMAL 0x00 +#define CHACTL_CHAR_INVERTED 0x04 +/* Inverse (reverse-video) characters */ +#define CHACTL_INV_TRANS 0x00 /* chars with high-bit shown */ +#define CHACTL_INV_OPAQUE 0x01 /* chars with high-bit appear as space */ +#define CHACTL_INV_PRESENT 0x02 /* chars with high-bit are reverse-video */ +/* N.B. Default is "CHACTL_CHAR_NORMAL | CHACTL_INV_PRESENT", aka decimal 2 */ + + unsigned char dlistl; /* display list pointer low-byte */ unsigned char dlisth; /* display list pointer high-byte */ - unsigned char hscrol; /* horizontal scroll enable */ - unsigned char vscrol; /* vertical scroll enable */ + unsigned char hscrol; /* (W) horizontal scroll enable */ + unsigned char vscrol; /* (W) vertical scroll enable */ unsigned char unuse0; /* unused */ - unsigned char pmbase; /* msb of p/m base address */ + unsigned char pmbase; /* (W) msb of p/m base address (for when DMACTL has player and/or missile DMA enabled) */ unsigned char unuse1; /* unused */ - unsigned char chbase; /* character base address */ - unsigned char wsync; /* wait for horizontal synchronization */ - unsigned char vcount; /* vertical line counter */ - unsigned char penh; /* light pen horizontal position */ - unsigned char penv; /* light pen vertical position */ - unsigned char nmien; /* non-maskable interrupt enable */ - unsigned char nmires; /* nmi reset/status */ + unsigned char chbase; /* (W) character set base address */ + unsigned char wsync; /* (W) wait for horizontal synchronization */ + unsigned char vcount; /* (R) vertical line counter */ + unsigned char penh; /* (R) light pen horizontal position */ + unsigned char penv; /* (R) light pen vertical position */ + + unsigned char nmien; /* (W) non-maskable interrupt enable */ + +/* NMIEN settings: */ +#define NMIEN_DLI 0x80 /* see also: DL_DLI */ +#define NMIEN_VBI 0x40 +#define NMIEN_RESET 0x20 + + unsigned char nmires; /* (W) ("NMIRES") nmi reset; (R) ("NMIST") nmi status */ }; -/* antic instruction set */ +/* ANTIC instruction set */ -/* absolute instructions (non mode lines) */ +/* Absolute instructions (non mode lines) */ #define DL_JMP ((unsigned char) 1) #define DL_JVB ((unsigned char) 65) -#define DL_BLK1 ((unsigned char) 0) -#define DL_BLK2 ((unsigned char) 16) -#define DL_BLK3 ((unsigned char) 32) +#define DL_BLK1 ((unsigned char) 0) /* 1 blank scanline */ +#define DL_BLK2 ((unsigned char) 16) /* 2 blank scanlines */ +#define DL_BLK3 ((unsigned char) 32) /* ...etc. */ #define DL_BLK4 ((unsigned char) 48) #define DL_BLK5 ((unsigned char) 64) #define DL_BLK6 ((unsigned char) 80) #define DL_BLK7 ((unsigned char) 96) #define DL_BLK8 ((unsigned char) 112) -/* absolute instructions (mode lines) */ -#define DL_CHR40x8x1 ((unsigned char) 2) /* monochrome, 40 character & 8 scanlines per mode line (GR. 0) */ -#define DL_CHR40x10x1 ((unsigned char) 3) /* monochrome, 40 character & 10 scanlines per mode line */ +/* Absolute instructions (mode lines) */ +/* Note: Actual width varies (e.g., 40 vs 32 vs 48) depending on normal vs narrow vs wide (overscan) playfield setting; see DMACTL */ + +/* Character modes (text, tile graphics, etc.) */ +#define DL_CHR40x8x1 ((unsigned char) 2) /* monochrome, 40 character & 8 scanlines per mode line (aka Atari BASIC GRAPHICS 0 via OS's CIO routines) */ +#define DL_CHR40x10x1 ((unsigned char) 3) /* monochrome, 40 character & 10 scanlines per mode line (like GR. 0, with descenders) */ #define DL_CHR40x8x4 ((unsigned char) 4) /* colour, 40 character & 8 scanlines per mode line (GR. 12) */ #define DL_CHR40x16x4 ((unsigned char) 5) /* colour, 40 character & 16 scanlines per mode line (GR. 13) */ #define DL_CHR20x8x2 ((unsigned char) 6) /* colour (duochrome per character), 20 character & 8 scanlines per mode line (GR. 1) */ #define DL_CHR20x16x2 ((unsigned char) 7) /* colour (duochrome per character), 20 character & 16 scanlines per mode line (GR. 2) */ +/* Bitmap modes */ #define DL_MAP40x8x4 ((unsigned char) 8) /* colour, 40 pixel & 8 scanlines per mode line (GR. 3) */ #define DL_MAP80x4x2 ((unsigned char) 9) /* 'duochrome', 80 pixel & 4 scanlines per mode line (GR.4) */ #define DL_MAP80x4x4 ((unsigned char) 10) /* colour, 80 pixel & 4 scanlines per mode line (GR.5) */ @@ -86,13 +132,43 @@ struct __antic { #define DL_MAP160x1x4 ((unsigned char) 14) /* 4 colours, 160 pixel & 1 scanline per mode line (GR.15) */ #define DL_MAP320x1x1 ((unsigned char) 15) /* monochrome, 320 pixel & 1 scanline per mode line (GR.8) */ -/* modifiers on mode lines */ -#define DL_HSCROL(x) ((unsigned char)((x) | 16)) -#define DL_VSCROL(x) ((unsigned char)((x) | 32)) -#define DL_LMS(x) ((unsigned char)((x) | 64)) +/* Equivalents, for people familiar with Atari 8-bit OS */ +#define DL_GRAPHICS0 DL_CHR40x8x1 +#define DL_GRAPHICS1 DL_CHR20x8x2 +#define DL_GRAPHICS2 DL_CHR20x16x2 +#define DL_GRAPHICS3 DL_MAP40x8x4 +#define DL_GRAPHICS4 DL_MAP80x4x2 +#define DL_GRAPHICS5 DL_MAP80x4x4 +#define DL_GRAPHICS6 DL_MAP160x2x2 +#define DL_GRAPHICS7 DL_MAP160x2x4 +#define DL_GRAPHICS8 DL_MAP320x1x1 +#define DL_GRAPHICS9 DL_MAP320x1x1 /* N.B.: GRAPHICS 9, 10, and 11 also involve GTIA's PRIOR register */ +#define DL_GRAPHICS10 DL_MAP320x1x1 +#define DL_GRAPHICS11 DL_MAP320x1x1 +#define DL_GRAPHICS12 DL_CHR40x8x4 /* N.B.: Atari 400/800 OS didn't have GRAPHICS 12 or 13 */ +#define DL_GRAPHICS13 DL_CHR40x16x4 +#define DL_GRAPHICS14 DL_MAP160x1x2 +#define DL_GRAPHICS15 DL_MAP160x1x4 -/* general modifier */ -#define DL_DLI(x) ((unsigned char)((x) | 128)) +/* Atari 400/800 OS didn't have GRAPHICS 14 or 15, so they were known by "6+" and "7+" */ +#define DL_GRAPHICS6PLUS DL_GRAPHICS14 +#define DL_GRAPHICS7PLUS DL_GRAPHICS15 + +/* Neither Atari 400/800 nor XL OS supported 10-scanline (descenders) text mode via CIO */ +#define DL_GRAPHICS0_DESCENDERS DL_CHR40x10x1 + +/* Modifiers to mode lines */ +#define DL_HSCROL(x) ((unsigned char)((x) | 16)) /* enable smooth horizontal scrolling on this line; see HSCROL */ +#define DL_VSCROL(x) ((unsigned char)((x) | 32)) /* enable smooth vertical scrolling on this line; see VSCROL */ +#define DL_LMS(x) ((unsigned char)((x) | 64)) /* Load Memory Scan (next two bytes must be the LSB/MSB of the data to load */ + +/* General modifier */ +#define DL_DLI(x) ((unsigned char)((x) | 128)) /* enable Display List Interrupt on this mode line; requires NMIEN set to enable DLIs */ + + +/* Macros for the beginning and end of functions used as Display List Interrupts */ +#define DLI_START asm("pha"); asm("txa"); asm("pha"); asm("tya"); asm("pha"); +#define DLI_END asm("pla"); asm("tay"); asm("pla"); asm("tax"); asm("pla"); asm("rti"); /* End of _antic.h */ #endif /* #ifndef __ANTIC_H */ From 95b791bf0e22b154e631de7da8b625f952e2c1c2 Mon Sep 17 00:00:00 2001 From: Bill Kendrick <nbs@sonic.net> Date: Sun, 13 Jan 2019 01:57:21 -0800 Subject: [PATCH 0970/2161] Added #defines for GTIA register values --- include/_gtia.h | 88 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 74 insertions(+), 14 deletions(-) diff --git a/include/_gtia.h b/include/_gtia.h index 0542efa2f..a6c6b6032 100644 --- a/include/_gtia.h +++ b/include/_gtia.h @@ -4,9 +4,16 @@ /* */ /* Internal include file, do not use directly */ /* */ +/* "GTIA, Graphic Television Interface Adaptor, is a custom chip used in the */ +/* Atari 8-bit family of computers and in the Atari 5200 console. In these */ +/* systems, GTIA chip works together with ANTIC to produce video display. */ +/* ANTIC generates the playfield graphics (text and bitmap) while GTIA */ +/* provides the color for the playfield and adds overlay objects known as */ +/* player/missile graphics (sprites)" - Wikipedia article on "GTIA" */ /* */ /* */ /* (C) 2000 Freddy Offenga <taf_offenga@yahoo.com> */ +/* 2019-01-12: Bill Kendrick <nbs@sonic.net>: More defines for registers */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -32,26 +39,33 @@ #ifndef __GTIA_H #define __GTIA_H -/* Define a structure with the gtia register offsets */ +/* Define a structure with the GTIA register offsets for write (W) */ struct __gtia_write { - unsigned char hposp0; /* 0x00: horizontal position player 0 */ - unsigned char hposp1; /* 0x01: horizontal position player 1 */ - unsigned char hposp2; /* 0x02: horizontal position player 2 */ - unsigned char hposp3; /* 0x03: horizontal position player 3 */ - unsigned char hposm0; /* 0x04: horizontal position missile 0 */ - unsigned char hposm1; /* 0x05: horizontal position missile 1 */ - unsigned char hposm2; /* 0x06: horizontal position missile 2 */ - unsigned char hposm3; /* 0x07: horizontal position missile 3 */ + unsigned char hposp0; /* 0x00: horizontal position of player 0 */ + unsigned char hposp1; /* 0x01: horizontal position of player 1 */ + unsigned char hposp2; /* 0x02: horizontal position of player 2 */ + unsigned char hposp3; /* 0x03: horizontal position of player 3 */ + unsigned char hposm0; /* 0x04: horizontal position of missile 0 */ + unsigned char hposm1; /* 0x05: horizontal position of missile 1 */ + unsigned char hposm2; /* 0x06: horizontal position of missile 2 */ + unsigned char hposm3; /* 0x07: horizontal position of missile 3 */ + unsigned char sizep0; /* 0x08: size of player 0 */ unsigned char sizep1; /* 0x09: size of player 1 */ unsigned char sizep2; /* 0x0A: size of player 2 */ unsigned char sizep3; /* 0x0B: size of player 3 */ unsigned char sizem; /* 0x0C: size of missiles */ - unsigned char grafp0; /* 0x0D: graphics shape player 0 */ + +#define PMG_SIZE_NORMAL 0x0 +#define PMG_SIZE_DOUBLE 0x1 +#define PMG_SIZE_QUAD 0x2 + + unsigned char grafp0; /* 0x0D: graphics shape player 0 (used when ANTIC is not instructed to use DMA; see DMACTL) */ unsigned char grafp1; /* 0x0E: graphics shape player 1 */ unsigned char grafp2; /* 0x0F: graphics shape player 2 */ unsigned char grafp3; /* 0x10: graphics shape player 3 */ unsigned char grafm; /* 0x11: graphics shape missiles */ + unsigned char colpm0; /* 0x12: color player and missile 0 */ unsigned char colpm1; /* 0x13: color player and missile 1 */ unsigned char colpm2; /* 0x14: color player and missile 2 */ @@ -61,14 +75,47 @@ struct __gtia_write { unsigned char colpf2; /* 0x18: color playfield 2 */ unsigned char colpf3; /* 0x19: color playfield 3 */ unsigned char colbk; /* 0x1A: color background */ + +/* See the "HUE_..." #defines in "atari.h" for the hue values to use with color registers, above */ +/* Bitwise OR (|) with 0x00 (darkest) through 0x0F (lightest) (only even values are unique) */ + unsigned char prior; /* 0x1B: priority selection */ - unsigned char vdelay; /* 0x1C: vertical delay */ + +#define PRIOR_P03_PF03 0x01 /* Players 0-3, then Playfields 0-3, then background */ +#define PRIOR_P01_PF03_P23 0x02 /* Players 0-1, then Playfields 0-3, then Players 2-3, then background */ +#define PRIOR_PF03_P03 0x04 /* Playfields 0-3, then Players 0-3, then background */ +#define PRIOR_PF01_P03_PF23 0x08 /* Playfields 0-1, then Players 0-3, then Playfields 2-3, then background */ + +#define PRIOR_5TH_PLAYER 0x10 /* Four missiles combine to be a 5th player (uses COLPF3) */ +#define PRIOR_OVERLAP_3RD_COLOR 0x20 /* Overlap of players 0 and 1, and of players 2 and 3, results in a third color + (else overlap is black). The resulting color is a logical OR of the two player colors. */ + +#define PRIOR_GFX_MODE_9 0x40 /* 80x192 16 shade mode (shades of the background (COLBK) hue; brightness in COLBK cause additional effects) */ +#define PRIOR_GFX_MODE_10 0x80 /* 80x192 9 color mode (COLPM0 (acts as background) thru COLPM3, followed by COLPF0 thru COLPF4) */ +#define PRIOR_GFX_MODE_11 0xC0 /* 80x192 16 hue mode (hues of the background (COLBK) brightness) */ + + unsigned char vdelay; /* 0x1C: vertical delay (for one-line resolution movement of vertical position of an object when two line resolution display is enabled */ + +#define VDELAY_MISSILE0 0x01 +#define VDELAY_MISSILE1 0x02 +#define VDELAY_MISSILE2 0x04 +#define VDELAY_MISSILE3 0x08 +#define VDELAY_PLAYER0 0x10 +#define VDELAY_PLAYER1 0x20 +#define VDELAY_PLAYER2 0x40 +#define VDELAY_PLAYER3 0x80 + unsigned char gractl; /* 0x1D: stick/paddle latch, p/m control */ + +#define GRACTL_MISSLES 0x01 /* enable missiles */ +#define GRACTL_PLAYERS 0x02 /* enable players */ +#define GRACTL_LATCH_TRIGGER_INPUTS 0x04 /* "latch" triggers; once pressed, will give a continuous pressed input until this bit is cleared */ + unsigned char hitclr; /* 0x1E: clear p/m collision */ unsigned char consol; /* 0x1F: builtin speaker */ }; -/* Define a structure with the gtia register offsets */ +/* Define a structure with the GTIA register offsets for read (R) */ struct __gtia_read { unsigned char m0pf; /* 0x00: missile 0 to playfield collision */ unsigned char m1pf; /* 0x01: missile 1 to playfield collision */ @@ -86,15 +133,28 @@ struct __gtia_read { unsigned char p1pl; /* 0x0D: player 1 to player collision */ unsigned char p2pl; /* 0x0E: player 2 to player collision */ unsigned char p3pl; /* 0x0F: player 3 to player collision */ - unsigned char trig0; /* 0x10: joystick trigger 0 */ + + unsigned char trig0; /* 0x10: joystick trigger 0 (0=pressed, 1=released) */ unsigned char trig1; /* 0x11: joystick trigger 1 */ unsigned char trig2; /* 0x12: joystick trigger 2 */ unsigned char trig3; /* 0x13: joystick trigger 3 */ + unsigned char pal; /* 0x14: pal/ntsc flag */ + +#define TV_STD_PAL 0x1 +#define TV_STD_NTSC 0xE +/* Note: This only tells you whether the GTIA is PAL or NTSC; some NTSC systems are modded with PAL ANTIC chips; testing VCOUNT limits can be done to check for that */ +/* Note: Seems like it's not possible to test for SECAM */ + unsigned char unused[10]; + unsigned char consol; /* 0x1F: console buttons */ + +#define CONSOL_START(x) !((unsigned char)((x) & 1)) /* true if Start pressed */ +#define CONSOL_SELECT(x) !((unsigned char)((x) & 2)) /* true if Select pressed */ +#define CONSOL_OPTION(x) !((unsigned char)((x) & 4)) /* true if Option pressed */ + }; /* End of _gtia.h */ #endif /* #ifndef __GTIA_H */ - From 10f44c18a34609abe77365a9cabe206b04ffb58f Mon Sep 17 00:00:00 2001 From: Bill Kendrick <nbs@sonic.net> Date: Sun, 13 Jan 2019 01:58:10 -0800 Subject: [PATCH 0971/2161] Tweaks to description of ANTIC chip in _antic.h Tweak to comments at the top --- include/_antic.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/include/_antic.h b/include/_antic.h index 0d1bdaf65..291a3e57c 100644 --- a/include/_antic.h +++ b/include/_antic.h @@ -5,15 +5,16 @@ /* Internal include file, do not use directly */ /* */ /* */ -/* "ANTIC is responsible for the generation of playfield graphics which is */ -/* delivered as a datastream to the related CTIA/GTIA chip. The CTIA/GTIA */ -/* provides the coloring of the playfield graphics, and is responsible for */ -/* adding overlaid sprites referred to as "Player/Missile graphics" by */ -/* Atari. Atari advertised it as a true microprocessor, in that it has an */ -/* instruction set to run programs (called display lists) to process data. */ -/* ANTIC has no capacity for writing back computed values to memory, it */ -/* merely reads data from memory and processes it for output to the screen, */ -/* therefore it is not Turing complete." - Wikipedia article on "ANTIC" */ +/* "ANTIC, Alphanumeric Television Interface Controller, is responsible for */ +/* the generation of playfield graphics which is delivered as a datastream */ +/* to the related CTIA/GTIA chip. The CTIA/GTIA provides the coloring of the */ +/* playfield graphics, and is responsible for adding overlaid sprite */ +/* (referred to as "Player/Missile graphics" by Atari). Atari advertised it */ +/* as a true microprocessor, in that it has an instruction set to run */ +/* programs (called display lists) to process data. ANTIC has no capacity */ +/* for writing back computed values to memory, it merely reads data from */ +/* memory and processes it for output to the screen, therefore it is not */ +/* Turing complete." - Wikipedia article on "ANTIC" (with edits) */ /* */ /* (C) 2000 Freddy Offenga <taf_offenga@yahoo.com> */ /* 24-Jan-2011: Christian Krueger: Added defines for Antic instruction set */ From d371d1bd51497e1280bde30d649f1735da8677d6 Mon Sep 17 00:00:00 2001 From: Bill Kendrick <nbs@sonic.net> Date: Sun, 13 Jan 2019 01:59:41 -0800 Subject: [PATCH 0972/2161] Note about hues varying depending on environment There aren't really standard color names (e.g., Compute!'s Mapping the Atari and First Book of Atari Graphics have different names), and exact colors shown depend on the system & device, anyway. Added a note. --- include/atari.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/atari.h b/include/atari.h index 0ca2dc577..25dcfa092 100644 --- a/include/atari.h +++ b/include/atari.h @@ -93,7 +93,7 @@ /* luminance values go from 0 (black) to 7 (white) */ -/* hue values */ +/* hue values (these can vary depending on TV standard (NTSC vs PAL), tint potentiometer settings, TV tint settings, emulator palette, etc. */ #define HUE_GREY 0 #define HUE_GOLD 1 #define HUE_GOLDORANGE 2 From 3783010091b8f845b05e1bf0d3e789c14b7c35d8 Mon Sep 17 00:00:00 2001 From: Bill Kendrick <bill@smashwords.com> Date: Sun, 13 Jan 2019 20:32:55 -0800 Subject: [PATCH 0973/2161] POKEY: Add register #defines & internal kybd codes Add #defines for certain registers' values. Also add #defines for internal keyboard codes (unrelated to ATASCII; e.g. [Q] = 47, [W] = 46, [Shift] adds 64, etc), as seen in KBCODE. --- include/_pokey.h | 159 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 155 insertions(+), 4 deletions(-) diff --git a/include/_pokey.h b/include/_pokey.h index fed8628b6..5cbf11f68 100644 --- a/include/_pokey.h +++ b/include/_pokey.h @@ -4,9 +4,17 @@ /* */ /* Internal include file, do not use directly */ /* */ +/* POKEY, Pot Keyboard Integrated Circuit, is a digital I/O chip designed */ +/* for the Atari 8-bit family of home computers; it combines functions for */ +/* sampling (ADC) potentiometers (such as game paddles) and scan matrices of */ +/* switches (such as a computer keyboard) as well as sound generation. */ +/* It produces four voices of distinctive square wave sound, either as clear */ +/* tones or modified with a number of distortion settings. - Wikipedia */ +/* "POKEY" article. */ /* */ /* */ /* (C) 2000 Freddy Offenga <taf_offenga@yahoo.com> */ +/* 2019-01-13: Bill Kendrick <nbs@sonic.net>: More defines for registers */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -35,7 +43,7 @@ -/* Define a structure with the pokey register offsets */ +/* Define a structure with the POKEY register offsets for write (W) */ struct __pokey_write { unsigned char audf1; /* audio channel #1 frequency */ unsigned char audc1; /* audio channel #1 control */ @@ -45,15 +53,71 @@ struct __pokey_write { unsigned char audc3; /* audio channel #3 control */ unsigned char audf4; /* audio channel #4 frequency */ unsigned char audc4; /* audio channel #4 control */ + +/* The values for the distortion bits (AUDCx) are as follows; + the first process is to divide the clock value by the frequency, + then mask the output using the polys in the order below; + finally, the result is divided by two */ +#define AUDC_POLYS_5_17 0x00 +#define AUDC_POLYS_5 0x20 /* Same as 0x60 */ +#define AUDC_POLYS_5_4 0x40 +#define AUDC_POLYS_17 0x80 +#define AUDC_POLYS_NONE 0xA0 /* Same as 0xE0 */ +#define AUDC_POLYS_4 0xC0 + +#define AUDC_VOLUME_ONLY 0x10 + + unsigned char audctl; /* audio control */ + +#define AUDCTL_CLOCKBASE_15HZ 0x01 /* Switch main clock base from 64 KHz to 15 KHz */ +#define AUDCTL_HIGHPASS_CHAN2 0x02 /* Insert high pass filter into channel two, clocked by channel four */ +#define AUDCTL_HIGHPASS_CHAN1 0x04 /* Insert high pass filter into channel one, clocked by channel two */ +#define AUDCTL_JOIN_CHAN34 0x08 /* Join channels four and three (16 bit) */ +#define AUDCTL_JOIN_CHAN12 0x10 /* Join channels two and one (16 bit) */ +#define AUDCTL_CLOCK_CHAN3_179MHZ 0x20 /* Clock channel three with 1.79 MHz */ +#define AUDCTL_CLOCK_CHAN1_179MHZ 0x40 /* Clock channel one with 1.79 MHz */ +#define AUDCTL_9BIT_POLY 0x80 /* Makes the 17 bit poly counter into nine bit poly (see also: RANDOM) */ + unsigned char stimer; /* start pokey timers */ - unsigned char skrest; /* reset serial port status reg. */ - unsigned char potgo; /* start paddle scan sequence */ + + unsigned char skrest; /* reset serial port status reg.; + Reset BITs 5 - 7 of the serial port status register (SKCTL) to "1" */ + + unsigned char potgo; /* start paddle scan sequence (see "ALLPOT") */ unsigned char unuse1; /* unused */ unsigned char serout; /* serial port data output */ + unsigned char irqen; /* interrupt request enable */ +#define POKMSK *(unsigned char *) 0x10 /* POKEY interrupts: the IRQ service uses and alters this location */ +#define IRQEN_TIMER_1 0x01 /* The POKEY timer one interrupt is enabled */ +#define IRQEN_TIMER_2 0x02 /* The POKEY timer two interrupt is enabled */ +#define IRQEN_TIMER_4 0x04 /* The POKEY timer four interrupt is enabled */ +#define IRQEN_SERIAL_TRANS_FINISHED 0x08 /* The serial out transmission finished interrupt is enabled */ +#define IRQEN_SERIAL_OUT_DATA_REQUIRED 0x10 /* The serial output data required interrupt is enabled */ +#define IRQEN_SERIAL_IN_DATA_READY 0x20 /* The serial input data ready interrupt is enabled. */ +#define IRQEN_OTHER_KEY 0x40 /* The "other key" interrupt is enabled */ +#define IRQEN_BREAK_KEY 0x80 /* The BREAK key is enabled */ + + unsigned char skctl; /* serial port control */ + +#define SKCTL_KEYBOARD_DEBOUNCE 0x01 /* Enable keyboard debounce circuits */ +#define SKCTL_KEYBOARD_SCANNING 0x02 /* Enable keyboard scanning circuit */ +#define SKCTL_FAST_POT_SCAN 0x04 /* Fast pot scan */ +/* the pot scan counter completes its sequence in two TV line times instead of + one frame time (228 scan lines). Not as accurate as the normal pot scan */ +#define SKCTL_TWO_TONE_MODE 0x08 /* Serial output is transmitted as a two-tone +signal rather than a logic true/false. POKEY two-tone mode. */ +/* Serial port mode control used to set the bi-directional clock lines */ +#define SKCTL_BIT4 0x10 /* FIXME; more meaningful name */ +#define SKCTL_BIT5 0x20 /* FIXME; more meaningful name */ +#define SKCTL_BIT6 0x40 /* FIXME; more meaningful name */ +#define SKCTL_FORCE_BREAK 0x80 /* Force break (serial output to zero) */ }; + + +/* Define a structure with the POKEY register offsets for read (R) */ struct __pokey_read { unsigned char pot0; /* paddle 0 value */ unsigned char pot1; /* paddle 1 value */ @@ -63,17 +127,104 @@ struct __pokey_read { unsigned char pot5; /* paddle 5 value */ unsigned char pot6; /* paddle 6 value */ unsigned char pot7; /* paddle 7 value */ - unsigned char allpot; /* eight paddle port status */ + unsigned char allpot; /* eight paddle port status (see "POTGO") */ unsigned char kbcode; /* keyboard code */ unsigned char random; /* random number generator */ unsigned char unuse2; /* unused */ unsigned char unuse3; /* unused */ unsigned char serin; /* serial port input */ unsigned char irqst; /* interrupt request status */ + unsigned char skstat; /* serial port status */ +#define SKSTAT_SERIN_SHIFTREG_BUSY 0x02 /* Serial input shift register busy */ +#define SKSTAT_LASTKEY_PRESSED 0x04 /* the last key is still pressed */ +#define SKSTAT_SHIFTKEY_PRESSED 0x08 /* the [Shift] key is pressed */ +#define SKSTAT_DATA_READ_INGORING_SHIFTREG 0x10 /* Data can be read directly from the serial input port, ignoring the shift register. */ +#define SKSTAT_KEYBOARD_OVERRUN 0x20 /* Keyboard over-run; Reset BITs 7, 6 and 5 (latches) to 1, using SKREST */ +#define SKSTAT_INPUT_OVERRUN 0x40 /* Serial data input over-run. Reset latches as above. */ +#define SKSTAT_INPUT_FRAMEERROR 0x80 /* Serial data input frame error caused by missing or extra bits. Reset latches as above. */ }; +/* Internal keyboard codes from http://www.atariarchives.org/c3ba/page004.php */ +/* (Defined below in the order the keys appear on a 1200XL keyboard, from top left to bottom right) */ +/* (Note: Numerous Shift+Ctrl+key combos are unavailable) */ + +#define KEYCODE_NONE 255 /* 255 = no key pressed (but is also same as Ctrl+Shift+A) */ + +/* Fn (function) keys only available on 1200XL */ +#define KEYCODE_F1 3 +#define KEYCODE_F2 4 +#define KEYCODE_F3 19 +#define KEYCODE_F4 20 + +/* HELP key only available on XL/XE series */ +#define KEYCODE_HELP 17 + +#define KEYCODE_ESC 28 +#define KEYCODE_1 31 +#define KEYCODE_2 30 +#define KEYCODE_3 26 +#define KEYCODE_4 24 +#define KEYCODE_5 29 +#define KEYCODE_6 27 +#define KEYCODE_7 51 +#define KEYCODE_8 53 +#define KEYCODE_9 48 +#define KEYCODE_0 50 +#define KEYCODE_LT 54 +#define KEYCODE_GT 55 +#define KEYCODE_BKSPC 52 + +#define KEYCODE_TAB 44 +#define KEYCODE_Q 47 +#define KEYCODE_W 46 +#define KEYCODE_E 42 +#define KEYCODE_R 40 +#define KEYCODE_T 45 +#define KEYCODE_Y 43 +#define KEYCODE_U 11 +#define KEYCODE_I 13 +#define KEYCODE_O 8 +#define KEYCODE_P 10 +#define KEYCODE_MINUS 14 +#define KEYCODE_EQUALS 15 +#define KEYCODE_RETURN 12 + +#define KEYCODE_CTRL 128 /* binary OR'd */ + +#define KEYCODE_A 63 +#define KEYCODE_S 62 +#define KEYCODE_D 58 +#define KEYCODE_F 56 +#define KEYCODE_G 61 +#define KEYCODE_H 57 +#define KEYCODE_J 1 +#define KEYCODE_K 5 +#define KEYCODE_L 0 +#define KEYCODE_; 2 +#define KEYCODE_PLUS 6 +#define KEYCODE_ASTERISK 7 +#define KEYCODE_CAPS 60 + +#define KEYCODE_SHIFT 64 /* binary OR'd */ + +#define KEYCODE_Z 23 +#define KEYCODE_X 22 +#define KEYCODE_C 18 +#define KEYCODE_V 16 +#define KEYCODE_B 21 +#define KEYCODE_N 35 +#define KEYCODE_M 37 +#define KEYCODE_COMMA 32 +#define KEYCODE_PERIOD 34 +#define KEYCODE_SLASH 38 +#define KEYCODE_FUJI 39 /* (as seen on 400/800) */ +#define KEYCODE_INVERSE 39 /* (alternative name; as seen on XL/XE) */ + +#define KEYCODE_SPACE 33 + + /* End of _pokey.h */ #endif /* #ifndef __POKEY_H */ From 5ee3c88017d45c5a11216e3f5833ecbe234c9a4c Mon Sep 17 00:00:00 2001 From: Bill Kendrick <nbs@sonic.net> Date: Sun, 13 Jan 2019 21:31:18 -0800 Subject: [PATCH 0974/2161] Some PIA register #defines Some register #defines for PIA. (Some may be too Atari-centric -- I know PIA chip was used by PET & perhaps other platforms supported by cc65. If so, perhaps we can define them elsewhere. Not sure whether they'd be the same for 5200; I admit I know zilch about that system except that it's _more or less_ an Atari 400) --- include/_pia.h | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/include/_pia.h b/include/_pia.h index 867c8f8a5..bd4f7c8ba 100644 --- a/include/_pia.h +++ b/include/_pia.h @@ -4,9 +4,14 @@ /* */ /* Internal include file, do not use directly */ /* */ +/* The Peripheral Interface Adapter (PIA) chip provides parallel I/O */ +/* interfacing; it was used in Atari 400/800 and Commodore PET family of */ +/* computers, for joystick and interrupts. */ +/* - Sources; various + Wikpedia article on "Peripheral Interface Adapter" */ /* */ /* */ /* (C) 2000 Freddy Offenga <taf_offenga@yahoo.com> */ +/* 2019-01-13: Bill Kendrick <nbs@sonic.net>: Defines for registers */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -34,18 +39,45 @@ #define __PIA_H -/* Define a structure with the pia register offsets */ +/* Define a structure with the PIA register offsets */ struct __pia { unsigned char porta; /* port A data r/w */ +/* Paddle 0-3 triggers (per PORTA bits) */ +#define PORTA_PTRIG3 0x80 +#define PORTA_PTRIG2 0x40 +#define PORTA_PTRIG1 0x08 +#define PORTA_PTRIG0 0x04 + + unsigned char portb; /* port B data r/w */ +/* Paddle 4-7 triggers (per PORTB bits); only 400/800 had four controller ports */ +#define PORTB_PTRIG7 0x80 +#define PORTB_PTRIG6 0x40 +#define PORTB_PTRIG5 0x08 +#define PORTB_PTRIG4 0x04 + + /* See also: "JOY_xxx_MASK" in "atari.h" */ + unsigned char pactl; /* port A control */ unsigned char pbctl; /* port B control */ + +#define PxCTL_IRQ_ENABLE 0x01 /* (W) Peripheral A interrupt (IRQ) enable. */ + /* One equals enable. Set by the OS but available to the user; + reset on powerup. */ +#define PxCTL_BIT1 0x02 /* "Set to zero" */ +#define PxCTL_ADDRESSING 0x04 /* (W) Controls PORTA addressing */ + /* One equals PORTA register; zero equals direction control register */ +#define PACTL_MOTOR_CONTROL 0x08 /* (W) Peripheral motor control line (turn the cassette on + or off; zero equals on) */ +#define PBCTL_PERIPH_CMD_IDENT 0x08 /* Peripheral command identification (serial bus command) */ +#define PxCTL_BIT4 0x10 /* "Set to one" */ +#define PxCTL_BIT5 0x20 /* "Set to one" */ +#define PxCTL_BIT6 0x40 /* "Set to zero" */ +#define PxCTL_IRQ_STATUS 0x80 /* Peripheral interrupt (IRQ) status bit. */ + /* Set by Peripherals (PORTA / PORTB). Reset by reading PORTA / PORTB*/ }; /* End of _pia.h */ #endif - - - From d52af69d6914b66966cf35e65639537117b9eb76 Mon Sep 17 00:00:00 2001 From: Bill Kendrick <nbs@sonic.net> Date: Mon, 14 Jan 2019 20:47:05 -0800 Subject: [PATCH 0975/2161] Adjustments per most feedback on cc65 PR 831 (I appreciate the feedback!) --- include/_antic.h | 10 ++++------ include/_pia.h | 37 +++++++++++++++++++++---------------- include/_pokey.h | 12 ++++++------ include/atari.h | 2 +- 4 files changed, 32 insertions(+), 29 deletions(-) diff --git a/include/_antic.h b/include/_antic.h index 291a3e57c..8fd99694e 100644 --- a/include/_antic.h +++ b/include/_antic.h @@ -66,10 +66,12 @@ struct __antic { /* Inverted (upside-down) characters */ #define CHACTL_CHAR_NORMAL 0x00 #define CHACTL_CHAR_INVERTED 0x04 + /* Inverse (reverse-video) characters */ #define CHACTL_INV_TRANS 0x00 /* chars with high-bit shown */ #define CHACTL_INV_OPAQUE 0x01 /* chars with high-bit appear as space */ #define CHACTL_INV_PRESENT 0x02 /* chars with high-bit are reverse-video */ + /* N.B. Default is "CHACTL_CHAR_NORMAL | CHACTL_INV_PRESENT", aka decimal 2 */ @@ -161,15 +163,11 @@ struct __antic { /* Modifiers to mode lines */ #define DL_HSCROL(x) ((unsigned char)((x) | 16)) /* enable smooth horizontal scrolling on this line; see HSCROL */ #define DL_VSCROL(x) ((unsigned char)((x) | 32)) /* enable smooth vertical scrolling on this line; see VSCROL */ -#define DL_LMS(x) ((unsigned char)((x) | 64)) /* Load Memory Scan (next two bytes must be the LSB/MSB of the data to load */ +#define DL_LMS(x) ((unsigned char)((x) | 64)) /* Load Memory Scan (next two bytes must be the LSB/MSB of the data to load) */ /* General modifier */ -#define DL_DLI(x) ((unsigned char)((x) | 128)) /* enable Display List Interrupt on this mode line; requires NMIEN set to enable DLIs */ +#define DL_DLI(x) ((unsigned char)((x) | 128)) /* enable Display List Interrupt on this mode line; requires NMIEN be set to enable DLIs */ -/* Macros for the beginning and end of functions used as Display List Interrupts */ -#define DLI_START asm("pha"); asm("txa"); asm("pha"); asm("tya"); asm("pha"); -#define DLI_END asm("pla"); asm("tay"); asm("pla"); asm("tax"); asm("pla"); asm("rti"); - /* End of _antic.h */ #endif /* #ifndef __ANTIC_H */ diff --git a/include/_pia.h b/include/_pia.h index bd4f7c8ba..22016f3a5 100644 --- a/include/_pia.h +++ b/include/_pia.h @@ -42,6 +42,7 @@ /* Define a structure with the PIA register offsets */ struct __pia { unsigned char porta; /* port A data r/w */ + /* Paddle 0-3 triggers (per PORTA bits) */ #define PORTA_PTRIG3 0x80 #define PORTA_PTRIG2 0x40 @@ -50,34 +51,38 @@ struct __pia { unsigned char portb; /* port B data r/w */ + /* Paddle 4-7 triggers (per PORTB bits); only 400/800 had four controller ports */ #define PORTB_PTRIG7 0x80 #define PORTB_PTRIG6 0x40 #define PORTB_PTRIG5 0x08 #define PORTB_PTRIG4 0x04 - /* See also: "JOY_xxx_MASK" in "atari.h" */ +/* See also: "JOY_xxx_MASK" in "atari.h" */ + unsigned char pactl; /* port A control */ unsigned char pbctl; /* port B control */ -#define PxCTL_IRQ_ENABLE 0x01 /* (W) Peripheral A interrupt (IRQ) enable. */ - /* One equals enable. Set by the OS but available to the user; - reset on powerup. */ -#define PxCTL_BIT1 0x02 /* "Set to zero" */ -#define PxCTL_ADDRESSING 0x04 /* (W) Controls PORTA addressing */ - /* One equals PORTA register; zero equals direction control register */ -#define PACTL_MOTOR_CONTROL 0x08 /* (W) Peripheral motor control line (turn the cassette on - or off; zero equals on) */ +#define PxCTL_IRQ_ENABLE 0x01 /* (W) Peripheral A interrupt (IRQ) enable. */ +/* One equals enable. Set by the OS but available to the user; reset on powerup. */ + +#define PxCTL_BIT1 0x02 /* "Set to zero" */ + +#define PxCTL_ADDRESSING 0x04 /* (W) Controls PORTA addressing */ +/* One equals PORTA register; zero equals direction control register */ + +#define PACTL_MOTOR_CONTROL 0x08 /* (W) Peripheral motor control line */ +/* Turn the cassette on or off; zero equals on) */ + #define PBCTL_PERIPH_CMD_IDENT 0x08 /* Peripheral command identification (serial bus command) */ -#define PxCTL_BIT4 0x10 /* "Set to one" */ -#define PxCTL_BIT5 0x20 /* "Set to one" */ -#define PxCTL_BIT6 0x40 /* "Set to zero" */ -#define PxCTL_IRQ_STATUS 0x80 /* Peripheral interrupt (IRQ) status bit. */ - /* Set by Peripherals (PORTA / PORTB). Reset by reading PORTA / PORTB*/ + +#define PxCTL_BIT4 0x10 /* "Set to one" */ +#define PxCTL_BIT5 0x20 /* "Set to one" */ +#define PxCTL_BIT6 0x40 /* "Set to zero" */ +#define PxCTL_IRQ_STATUS 0x80 /* Peripheral interrupt (IRQ) status bit. */ +/* Set by Peripherals (PORTA / PORTB). Reset by reading PORTA / PORTB. */ }; - - /* End of _pia.h */ #endif diff --git a/include/_pokey.h b/include/_pokey.h index 5cbf11f68..4a7643eb5 100644 --- a/include/_pokey.h +++ b/include/_pokey.h @@ -70,14 +70,14 @@ struct __pokey_write { unsigned char audctl; /* audio control */ -#define AUDCTL_CLOCKBASE_15HZ 0x01 /* Switch main clock base from 64 KHz to 15 KHz */ -#define AUDCTL_HIGHPASS_CHAN2 0x02 /* Insert high pass filter into channel two, clocked by channel four */ -#define AUDCTL_HIGHPASS_CHAN1 0x04 /* Insert high pass filter into channel one, clocked by channel two */ -#define AUDCTL_JOIN_CHAN34 0x08 /* Join channels four and three (16 bit) */ -#define AUDCTL_JOIN_CHAN12 0x10 /* Join channels two and one (16 bit) */ +#define AUDCTL_CLOCKBASE_15HZ 0x01 /* Switch main clock base from 64 KHz to 15 KHz */ +#define AUDCTL_HIGHPASS_CHAN2 0x02 /* Insert high pass filter into channel two, clocked by channel four */ +#define AUDCTL_HIGHPASS_CHAN1 0x04 /* Insert high pass filter into channel one, clocked by channel two */ +#define AUDCTL_JOIN_CHAN34 0x08 /* Join channels four and three (16 bit) */ +#define AUDCTL_JOIN_CHAN12 0x10 /* Join channels two and one (16 bit) */ #define AUDCTL_CLOCK_CHAN3_179MHZ 0x20 /* Clock channel three with 1.79 MHz */ #define AUDCTL_CLOCK_CHAN1_179MHZ 0x40 /* Clock channel one with 1.79 MHz */ -#define AUDCTL_9BIT_POLY 0x80 /* Makes the 17 bit poly counter into nine bit poly (see also: RANDOM) */ +#define AUDCTL_9BIT_POLY 0x80 /* Makes the 17 bit poly counter into nine bit poly (see also: RANDOM) */ unsigned char stimer; /* start pokey timers */ diff --git a/include/atari.h b/include/atari.h index 25dcfa092..f9c78be0c 100644 --- a/include/atari.h +++ b/include/atari.h @@ -93,7 +93,7 @@ /* luminance values go from 0 (black) to 7 (white) */ -/* hue values (these can vary depending on TV standard (NTSC vs PAL), tint potentiometer settings, TV tint settings, emulator palette, etc. */ +/* hue values (these can vary depending on TV standard (NTSC vs PAL), tint potentiometer settings, TV tint settings, emulator palette, etc.) */ #define HUE_GREY 0 #define HUE_GOLD 1 #define HUE_GOLDORANGE 2 From 4b61c54092b4c12b4c02bdb0a04b42fe5e609e79 Mon Sep 17 00:00:00 2001 From: Bill Kendrick <nbs@sonic.net> Date: Tue, 15 Jan 2019 01:24:12 -0800 Subject: [PATCH 0976/2161] Relocate register values outside structs, + more Relocated register #define'd values outside of the structs, improved comment format, expanded & corrected some things. h/t Trevin Beattie (https://user.xmission.com/~trevin/) for the PIA register descriptions. --- include/_antic.h | 84 ++++++++++----- include/_gtia.h | 92 +++++++++++++---- include/_pia.h | 84 +++++++++++++-- include/_pokey.h | 263 ++++++++++++++++++++++++++++++----------------- include/atari.h | 25 +++-- 5 files changed, 385 insertions(+), 163 deletions(-) diff --git a/include/_antic.h b/include/_antic.h index 8fd99694e..8520c5f19 100644 --- a/include/_antic.h +++ b/include/_antic.h @@ -18,7 +18,7 @@ /* */ /* (C) 2000 Freddy Offenga <taf_offenga@yahoo.com> */ /* 24-Jan-2011: Christian Krueger: Added defines for Antic instruction set */ -/* 2019-01-12: Bill Kendrick <nbs@sonic.net>: More defines for registers */ +/* 2019-01-14: Bill Kendrick <nbs@sonic.net>: More defines for registers */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -47,21 +47,57 @@ /* Define a structure with the ANTIC coprocessor's register offsets */ struct __antic { unsigned char dmactl; /* (W) direct memory access control */ + unsigned char chactl; /* (W) character mode control */ + unsigned char dlistl; /* display list pointer low-byte */ + unsigned char dlisth; /* display list pointer high-byte */ + unsigned char hscrol; /* (W) horizontal scroll enable */ + unsigned char vscrol; /* (W) vertical scroll enable */ + unsigned char unuse0; /* unused */ + unsigned char pmbase; /* (W) msb of p/m base address (for when DMACTL has player and/or missile DMA enabled) */ + unsigned char unuse1; /* unused */ + unsigned char chbase; /* (W) msb of character set base address */ + unsigned char wsync; /* (W) wait for horizontal synchronization */ + unsigned char vcount; /* (R) vertical line counter */ + unsigned char penh; /* (R) light pen horizontal position */ + unsigned char penv; /* (R) light pen vertical position */ + unsigned char nmien; /* (W) non-maskable interrupt enable */ + unsigned char nmires; + /* (W) ("NMIRES") nmi reset -- clears the interrupt request register; resets all of the NMI status together + ** (R) ("NMIST") nmi status -- holds cause for the NMI interrupt + */ +}; + + +/* DMACTL register options */ +/* Initialized to 0x22: DMA fetch, normal playfield, no PMG DMA, double-line PMGs */ /* Playfield modes: */ #define DMACTL_PLAYFIELD_NONE 0x00 #define DMACTL_PLAYFIELD_NARROW 0x01 /* e.g., 32 bytes per scanline with thick borders */ #define DMACTL_PLAYFIELD_NORMAL 0x02 /* e.g., 40 bytes per scanline with normal borders */ #define DMACTL_PLAYFIELD_WIDE 0x03 /* e.g., 48 bytes per scanline with no borders (overscan) */ + /* Other options: */ -#define DMACTL_DMA_MISSILES 0x04 /* if not set, GTIA's GRAFP0 thru GRAFP3 used for player shapes; if set, ANTIC's PMBASE will be used to fetch shapes via DMA */ -#define DMACTL_DMA_PLAYERS 0x08 /* (ditto, using GTIA's GRAFM for missile shapes...) */ -#define DMACTL_PMG_SINGLELINE 0x10 /* if not set, default is double-scanline resolution PMGs */ -#define DMACTL_DMA_FETCH 0x20 /* if not set, disables ANTIC operation since it cannot fetch Display List instructions */ -/* Initialized to 0x22 (DMA fetch, normal playfield, no PMG DMA, double-line PMGs) */ + +/* If not set, GTIA's GRAFP0 thru GRAFP3, and/or GRAFM registers are used for +** player & missile shapes, respectively. (Modify the registers during the horizontal blank +** (Display List Interrupt), a la "racing the beam" on an Atari VCS/2600, ) +** if set, ANTIC's PMBASE will be used to fetch shapes from memory via DMA. +*/ +#define DMACTL_DMA_MISSILES 0x04 +#define DMACTL_DMA_PLAYERS 0x08 + +/* Unless set, PMGs (as fetched via DMA) will be double-scanline resolution */ +#define DMACTL_PMG_SINGLELINE 0x10 + +/* Unless set, ANTIC operation is disabled, since it cannot fetch +** Display List instructions +*/ +#define DMACTL_DMA_FETCH 0x20 - unsigned char chactl; /* (W) character mode control */ +/* CHACTL register options */ +/* Initialized to 2 (CHACTL_CHAR_NORMAL | CHACTL_INV_PRESENT) */ /* Inverted (upside-down) characters */ #define CHACTL_CHAR_NORMAL 0x00 @@ -72,31 +108,25 @@ struct __antic { #define CHACTL_INV_OPAQUE 0x01 /* chars with high-bit appear as space */ #define CHACTL_INV_PRESENT 0x02 /* chars with high-bit are reverse-video */ -/* N.B. Default is "CHACTL_CHAR_NORMAL | CHACTL_INV_PRESENT", aka decimal 2 */ +/* Register bits for NMIEN (enabling interrupts) +** and NMIST (determining the cause for the NMI interrupt) +*/ - unsigned char dlistl; /* display list pointer low-byte */ - unsigned char dlisth; /* display list pointer high-byte */ - unsigned char hscrol; /* (W) horizontal scroll enable */ - unsigned char vscrol; /* (W) vertical scroll enable */ - unsigned char unuse0; /* unused */ - unsigned char pmbase; /* (W) msb of p/m base address (for when DMACTL has player and/or missile DMA enabled) */ - unsigned char unuse1; /* unused */ - unsigned char chbase; /* (W) character set base address */ - unsigned char wsync; /* (W) wait for horizontal synchronization */ - unsigned char vcount; /* (R) vertical line counter */ - unsigned char penh; /* (R) light pen horizontal position */ - unsigned char penv; /* (R) light pen vertical position */ +#define NMIEN_DLI 0x80 +/* Display List Interrupts +** Called on a modeline when "DL_DLI" bit is set the ANTIC instruction, +** and jumps through VDSLST vector. +*/ - unsigned char nmien; /* (W) non-maskable interrupt enable */ +#define NMIEN_VBI 0x40 +/* Vertical Blank Interrupt +** Called during every vertical blank; see SYSVBV, VVBLKI, CRITIC, and VVBLKD, +** as well as the SETVBV routine. +*/ -/* NMIEN settings: */ -#define NMIEN_DLI 0x80 /* see also: DL_DLI */ -#define NMIEN_VBI 0x40 #define NMIEN_RESET 0x20 - - unsigned char nmires; /* (W) ("NMIRES") nmi reset; (R) ("NMIST") nmi status */ -}; +/* [Reset] key pressed */ /* ANTIC instruction set */ diff --git a/include/_gtia.h b/include/_gtia.h index a6c6b6032..25d26093c 100644 --- a/include/_gtia.h +++ b/include/_gtia.h @@ -13,7 +13,7 @@ /* */ /* */ /* (C) 2000 Freddy Offenga <taf_offenga@yahoo.com> */ -/* 2019-01-12: Bill Kendrick <nbs@sonic.net>: More defines for registers */ +/* 2019-01-14: Bill Kendrick <nbs@sonic.net>: More defines for registers */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -56,10 +56,6 @@ struct __gtia_write { unsigned char sizep3; /* 0x0B: size of player 3 */ unsigned char sizem; /* 0x0C: size of missiles */ -#define PMG_SIZE_NORMAL 0x0 -#define PMG_SIZE_DOUBLE 0x1 -#define PMG_SIZE_QUAD 0x2 - unsigned char grafp0; /* 0x0D: graphics shape player 0 (used when ANTIC is not instructed to use DMA; see DMACTL) */ unsigned char grafp1; /* 0x0E: graphics shape player 1 */ unsigned char grafp2; /* 0x0F: graphics shape player 2 */ @@ -76,25 +72,69 @@ struct __gtia_write { unsigned char colpf3; /* 0x19: color playfield 3 */ unsigned char colbk; /* 0x1A: color background */ -/* See the "HUE_..." #defines in "atari.h" for the hue values to use with color registers, above */ -/* Bitwise OR (|) with 0x00 (darkest) through 0x0F (lightest) (only even values are unique) */ - unsigned char prior; /* 0x1B: priority selection */ + unsigned char vdelay; + /* 0x1C: vertical delay -- one-line resolution movement of + ** vertical position of an object when two line resolution display is enabled + */ + + unsigned char gractl; /* 0x1D: stick/paddle latch, p/m control */ + + unsigned char hitclr; /* 0x1E: clear p/m collision */ + unsigned char consol; /* 0x1F: builtin speaker */ +}; + + +/* Values for SIZEP0-SIZEP3 and SIZEM registers: */ +#define PMG_SIZE_NORMAL 0x0 /* one color clock per pixel */ +#define PMG_SIZE_DOUBLE 0x1 /* two color clocks per pixel */ +#define PMG_SIZE_QUAD 0x2 /* four color clocks per pixel */ + + +/* COLPM0-COLPM3, COLPF0-COLPF3, COLBK color registers: +** See the "HUE_..." #defines in "atari.h" for the hue values; +** Bitwise OR (|) with 0x00 (darkest) through 0x0F (lightest) (only even values are unique) +*/ + +/* PRIOR register values */ + #define PRIOR_P03_PF03 0x01 /* Players 0-3, then Playfields 0-3, then background */ #define PRIOR_P01_PF03_P23 0x02 /* Players 0-1, then Playfields 0-3, then Players 2-3, then background */ #define PRIOR_PF03_P03 0x04 /* Playfields 0-3, then Players 0-3, then background */ #define PRIOR_PF01_P03_PF23 0x08 /* Playfields 0-1, then Players 0-3, then Playfields 2-3, then background */ #define PRIOR_5TH_PLAYER 0x10 /* Four missiles combine to be a 5th player (uses COLPF3) */ -#define PRIOR_OVERLAP_3RD_COLOR 0x20 /* Overlap of players 0 and 1, and of players 2 and 3, results in a third color - (else overlap is black). The resulting color is a logical OR of the two player colors. */ -#define PRIOR_GFX_MODE_9 0x40 /* 80x192 16 shade mode (shades of the background (COLBK) hue; brightness in COLBK cause additional effects) */ -#define PRIOR_GFX_MODE_10 0x80 /* 80x192 9 color mode (COLPM0 (acts as background) thru COLPM3, followed by COLPF0 thru COLPF4) */ -#define PRIOR_GFX_MODE_11 0xC0 /* 80x192 16 hue mode (hues of the background (COLBK) brightness) */ +#define PRIOR_OVERLAP_3RD_COLOR 0x20 /* Overlap of players result in a 3rd color */ +/* Overlap of players 0 & 1 and of players 2 & 3 results in a third color, +** the logical OR of the two players' colors; +** Other overlaps (e.g., players 0 and 2) result in black (0x00). +*/ - unsigned char vdelay; /* 0x1C: vertical delay (for one-line resolution movement of vertical position of an object when two line resolution display is enabled */ +/* GTIA special graphics mode options */ +/* Pixels are 2 color clocks wide, and one scanline tall +** (so 80x192 in normal playfield width). +** May be used with both bitmap and character modelines. +*/ + +#define PRIOR_GFX_MODE_9 0x40 +/* 16 shade shades of the background (COLBK) hue; +** Note: brightnesses other than 0 (darkest) in COLBK cause additional effects +*/ + +#define PRIOR_GFX_MODE_10 0x80 +/* 9 color palette mode; +** COLPM0 (acts as background) thru COLPM3, followed by COLPF0 thru COLPF3, and COLBK +*/ + +#define PRIOR_GFX_MODE_11 0xC0 +/* 16 hues of the background (COLBK) brightness; +** Note: hues other than 0 (greys) in COLBK caus additional effects +*/ + + +/* VDELAY register values */ #define VDELAY_MISSILE0 0x01 #define VDELAY_MISSILE1 0x02 @@ -105,15 +145,17 @@ struct __gtia_write { #define VDELAY_PLAYER2 0x40 #define VDELAY_PLAYER3 0x80 - unsigned char gractl; /* 0x1D: stick/paddle latch, p/m control */ + +/* GRACTL register values */ #define GRACTL_MISSLES 0x01 /* enable missiles */ #define GRACTL_PLAYERS 0x02 /* enable players */ -#define GRACTL_LATCH_TRIGGER_INPUTS 0x04 /* "latch" triggers; once pressed, will give a continuous pressed input until this bit is cleared */ - unsigned char hitclr; /* 0x1E: clear p/m collision */ - unsigned char consol; /* 0x1F: builtin speaker */ -}; +#define GRACTL_LATCH_TRIGGER_INPUTS 0x04 +/* "Latch" triggers; once pressed, will give a continuous +** pressed input until this bit is cleared +*/ + /* Define a structure with the GTIA register offsets for read (R) */ struct __gtia_read { @@ -141,20 +183,26 @@ struct __gtia_read { unsigned char pal; /* 0x14: pal/ntsc flag */ + unsigned char unused[10]; + + unsigned char consol; /* 0x1F: console buttons */ +}; + + +/* PAL register possible values */ + #define TV_STD_PAL 0x1 #define TV_STD_NTSC 0xE /* Note: This only tells you whether the GTIA is PAL or NTSC; some NTSC systems are modded with PAL ANTIC chips; testing VCOUNT limits can be done to check for that */ /* Note: Seems like it's not possible to test for SECAM */ - unsigned char unused[10]; - unsigned char consol; /* 0x1F: console buttons */ +/* Reading console keys (Start, Select, Option) via CONSOL register: */ #define CONSOL_START(x) !((unsigned char)((x) & 1)) /* true if Start pressed */ #define CONSOL_SELECT(x) !((unsigned char)((x) & 2)) /* true if Select pressed */ #define CONSOL_OPTION(x) !((unsigned char)((x) & 4)) /* true if Option pressed */ -}; /* End of _gtia.h */ #endif /* #ifndef __GTIA_H */ diff --git a/include/_pia.h b/include/_pia.h index 22016f3a5..dc3830acb 100644 --- a/include/_pia.h +++ b/include/_pia.h @@ -11,7 +11,7 @@ /* */ /* */ /* (C) 2000 Freddy Offenga <taf_offenga@yahoo.com> */ -/* 2019-01-13: Bill Kendrick <nbs@sonic.net>: Defines for registers */ +/* 2019-01-14: Bill Kendrick <nbs@sonic.net>: Defines for registers */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -42,6 +42,15 @@ /* Define a structure with the PIA register offsets */ struct __pia { unsigned char porta; /* port A data r/w */ + unsigned char portb; /* port B data r/w */ + unsigned char pactl; /* port A control */ + unsigned char pbctl; /* port B control */ +}; + + +/* PORTA and PORTB register bits */ + +/* See also: "JOY_xxx_MASK" in "atari.h" */ /* Paddle 0-3 triggers (per PORTA bits) */ #define PORTA_PTRIG3 0x80 @@ -50,7 +59,7 @@ struct __pia { #define PORTA_PTRIG0 0x04 - unsigned char portb; /* port B data r/w */ +/* On the Atari 400/800, PORTB is the same as PORTA, but for controller ports 3 & 4. */ /* Paddle 4-7 triggers (per PORTB bits); only 400/800 had four controller ports */ #define PORTB_PTRIG7 0x80 @@ -58,11 +67,57 @@ struct __pia { #define PORTB_PTRIG5 0x08 #define PORTB_PTRIG4 0x04 -/* See also: "JOY_xxx_MASK" in "atari.h" */ + +/* On the XL series of computers, PORTB has been changed to a memory and +** LED control (1200XL model only) register (read/write): +*/ + +#define PORTB_OSROM 0x01 +/* If set, the built-in OS is enabled, and occupies the address range $C000-$FFFF +** (except that the area $D000-$D7FF will only access the hardware registers.) +** If clear, RAM is enabled in this area (again, save for the hole.) +*/ + +#define PORTB_BASICROM 0x02 +/* If set, RAM is enabled for the address range $A000-$BFFF. +** If clear, the built-in BASIC ROM is enabled at this address. +** And if there is a cartridge installed in the computer, it makes no difference. +*/ + +#define PORTB_LED1 0x04 +#define PORTB_LED2 0x08 +/* If set, the corresponding LED is turned off. If clear, the LED will be on. +** (1200XL only) +*/ - unsigned char pactl; /* port A control */ - unsigned char pbctl; /* port B control */ +/* On the XE series of computers, PORTB is a bank-selected memory control register (read/write): */ + +/* These bits determine which memory bank is visible to the CPU and/or ANTIC chip +** when their Bank Switch bit is set. There are four possible banks of 16KB each. +*/ +#define PORTB_BANKSELECT1 0x00 +#define PORTB_BANKSELECT2 0x04 +#define PORTB_BANKSELECT3 0x08 +#define PORTB_BANKSELECT4 0x0C + + +#define PORTB_BANKSWITCH_CPU 0x10 +#define PORTB_BANKSWITCH_ANTIC 0x20 +/* If set, the CPU and/or ANTIC chip will access bank-switched memory mapped to the +** address range $4000-$7FFF. +** If clear, the CPU and/or ANTIC will see normal memory in this region. +*/ + + +#define PORTB_SELFTEST 0x80 +/* If set, RAM is enabled for the address range $5000-$57FF. +** If clear, the self-test ROM (physically located at $D000-$D7FF, under the hardware registers) +** is remapped to this memory area. +*/ + + +/* PACTL and PBCTL register bits */ #define PxCTL_IRQ_ENABLE 0x01 /* (W) Peripheral A interrupt (IRQ) enable. */ /* One equals enable. Set by the OS but available to the user; reset on powerup. */ @@ -72,17 +127,24 @@ struct __pia { #define PxCTL_ADDRESSING 0x04 /* (W) Controls PORTA addressing */ /* One equals PORTA register; zero equals direction control register */ -#define PACTL_MOTOR_CONTROL 0x08 /* (W) Peripheral motor control line */ -/* Turn the cassette on or off; zero equals on) */ - -#define PBCTL_PERIPH_CMD_IDENT 0x08 /* Peripheral command identification (serial bus command) */ - #define PxCTL_BIT4 0x10 /* "Set to one" */ #define PxCTL_BIT5 0x20 /* "Set to one" */ #define PxCTL_BIT6 0x40 /* "Set to zero" */ #define PxCTL_IRQ_STATUS 0x80 /* Peripheral interrupt (IRQ) status bit. */ /* Set by Peripherals (PORTA / PORTB). Reset by reading PORTA / PORTB. */ -}; + + +/* PACTL-specific register bit */ + +#define PACTL_MOTOR_CONTROL 0x08 /* (W) Peripheral motor control line */ +/* Turn the cassette on or off; zero equals on) */ + + +/* PBCTL-specific register bit */ + +#define PBCTL_PERIPH_CMD_IDENT 0x08 /* Peripheral command identification (serial bus command) */ + + /* End of _pia.h */ #endif diff --git a/include/_pokey.h b/include/_pokey.h index 4a7643eb5..01a3225a6 100644 --- a/include/_pokey.h +++ b/include/_pokey.h @@ -14,7 +14,7 @@ /* */ /* */ /* (C) 2000 Freddy Offenga <taf_offenga@yahoo.com> */ -/* 2019-01-13: Bill Kendrick <nbs@sonic.net>: More defines for registers */ +/* 2019-01-14: Bill Kendrick <nbs@sonic.net>: More defines for registers */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -53,11 +53,30 @@ struct __pokey_write { unsigned char audc3; /* audio channel #3 control */ unsigned char audf4; /* audio channel #4 frequency */ unsigned char audc4; /* audio channel #4 control */ + unsigned char audctl; /* audio control */ + unsigned char stimer; /* start pokey timers */ -/* The values for the distortion bits (AUDCx) are as follows; - the first process is to divide the clock value by the frequency, - then mask the output using the polys in the order below; - finally, the result is divided by two */ + unsigned char skrest; + /* reset serial port status reg.; + ** Reset BITs 5 - 7 of the serial port status register (SKCTL) to "1" + */ + + unsigned char potgo; /* start paddle scan sequence (see "ALLPOT") */ + unsigned char unuse1; /* unused */ + unsigned char serout; /* serial port data output */ + unsigned char irqen; /* interrupt request enable */ + unsigned char skctl; /* serial port control */ +}; + + + +/* AUDC1-4 register values */ + +/* Meaningful values for the distortion bits. +** The first process is to divide the clock value by the frequency, +** then mask the output using the polys in the order below; +** finally, the result is divided by two. +*/ #define AUDC_POLYS_5_17 0x00 #define AUDC_POLYS_5 0x20 /* Same as 0x60 */ #define AUDC_POLYS_5_4 0x40 @@ -65,10 +84,14 @@ struct __pokey_write { #define AUDC_POLYS_NONE 0xA0 /* Same as 0xE0 */ #define AUDC_POLYS_4 0xC0 +/* When set, the volume value in AUDC1-4 bits 0-3 is sent directly to the speaker; +** it is not modulated with the frequency specified in the AUDF1-4 registers. +** (See "De Re Atari" Chapter 7: Sound) +*/ #define AUDC_VOLUME_ONLY 0x10 - unsigned char audctl; /* audio control */ +/* AUDCTL register values */ #define AUDCTL_CLOCKBASE_15HZ 0x01 /* Switch main clock base from 64 KHz to 15 KHz */ #define AUDCTL_HIGHPASS_CHAN2 0x02 /* Insert high pass filter into channel two, clocked by channel four */ @@ -79,17 +102,9 @@ struct __pokey_write { #define AUDCTL_CLOCK_CHAN1_179MHZ 0x40 /* Clock channel one with 1.79 MHz */ #define AUDCTL_9BIT_POLY 0x80 /* Makes the 17 bit poly counter into nine bit poly (see also: RANDOM) */ - unsigned char stimer; /* start pokey timers */ - unsigned char skrest; /* reset serial port status reg.; - Reset BITs 5 - 7 of the serial port status register (SKCTL) to "1" */ +/* IRQEN register values */ - unsigned char potgo; /* start paddle scan sequence (see "ALLPOT") */ - unsigned char unuse1; /* unused */ - unsigned char serout; /* serial port data output */ - - unsigned char irqen; /* interrupt request enable */ -#define POKMSK *(unsigned char *) 0x10 /* POKEY interrupts: the IRQ service uses and alters this location */ #define IRQEN_TIMER_1 0x01 /* The POKEY timer one interrupt is enabled */ #define IRQEN_TIMER_2 0x02 /* The POKEY timer two interrupt is enabled */ #define IRQEN_TIMER_4 0x04 /* The POKEY timer four interrupt is enabled */ @@ -100,21 +115,46 @@ struct __pokey_write { #define IRQEN_BREAK_KEY 0x80 /* The BREAK key is enabled */ - unsigned char skctl; /* serial port control */ +/* SKCTL register values */ #define SKCTL_KEYBOARD_DEBOUNCE 0x01 /* Enable keyboard debounce circuits */ #define SKCTL_KEYBOARD_SCANNING 0x02 /* Enable keyboard scanning circuit */ + #define SKCTL_FAST_POT_SCAN 0x04 /* Fast pot scan */ -/* the pot scan counter completes its sequence in two TV line times instead of - one frame time (228 scan lines). Not as accurate as the normal pot scan */ -#define SKCTL_TWO_TONE_MODE 0x08 /* Serial output is transmitted as a two-tone -signal rather than a logic true/false. POKEY two-tone mode. */ -/* Serial port mode control used to set the bi-directional clock lines */ -#define SKCTL_BIT4 0x10 /* FIXME; more meaningful name */ -#define SKCTL_BIT5 0x20 /* FIXME; more meaningful name */ -#define SKCTL_BIT6 0x40 /* FIXME; more meaningful name */ +/* The pot scan counter completes its sequence in two TV line times instead of +** one frame time (228 scan lines). Not as accurate as the normal pot scan +*/ + +#define SKCTL_TWO_TONE_MODE 0x08 /* POKEY two-tone mode */ +/* Serial output is transmitted as a two-tone signal rather than a logic true/false. */ + + +/* Bits 4, 5, and 6 of SKCTL set Serial Mode Control: */ + +#define SKCTL_SER_MODE_TX_EXT_RX_EXT 0x00 +/* Trans. & Receive rates set by external clock; Also internal clock phase reset to zero. */ + +#define SKCTL_SER_MODE_TX_EXT_RX_ASYNC 0x10 +/* Trans. rate set by external clock; Receive asynch. (ch. 4) (CH3 and CH4). */ + +#define SKCTL_SER_MODE_TX_CH4_RX_CH4_BIDIR 0x20 +/* Trans. & Receive rates set by Chan. 4; Chan. 4 output on Bi-Direct. clock line. */ + +/* N.B.: Bit combination 0,1,1 not useful */ + +#define SKCTL_SER_MODE_TX_CH4_RX_EXT 0x40 +/* Trans. rate set by Chan. 4; Receive rate set by external clock. */ + +/* N.B.: Bit combination 1,0,1 not useful */ + +#define SKCTL_SER_MODE_TX_CH2_RX_CH4_BIDIR 0x60 +/* Trans. rate set by Chan. 2; Receive rate set by Chan. 4; Chan. 4 out on Bi-Direct. clock line. */ + +#define SKCTL_SER_MODE_TX_CH4_RX_ASYNC 0x70 +/* Trans. rate set by Chan. 2; Receive asynch. (chan 3 & 4); Bi-Direct. clock not used (tri-state condition). */ + + #define SKCTL_FORCE_BREAK 0x80 /* Force break (serial output to zero) */ -}; /* Define a structure with the POKEY register offsets for read (R) */ @@ -134,8 +174,11 @@ struct __pokey_read { unsigned char unuse3; /* unused */ unsigned char serin; /* serial port input */ unsigned char irqst; /* interrupt request status */ - unsigned char skstat; /* serial port status */ +}; + + +/* SKSTAT register values */ #define SKSTAT_SERIN_SHIFTREG_BUSY 0x02 /* Serial input shift register busy */ #define SKSTAT_LASTKEY_PRESSED 0x04 /* the last key is still pressed */ #define SKSTAT_SHIFTKEY_PRESSED 0x08 /* the [Shift] key is pressed */ @@ -143,88 +186,122 @@ struct __pokey_read { #define SKSTAT_KEYBOARD_OVERRUN 0x20 /* Keyboard over-run; Reset BITs 7, 6 and 5 (latches) to 1, using SKREST */ #define SKSTAT_INPUT_OVERRUN 0x40 /* Serial data input over-run. Reset latches as above. */ #define SKSTAT_INPUT_FRAMEERROR 0x80 /* Serial data input frame error caused by missing or extra bits. Reset latches as above. */ -}; -/* Internal keyboard codes from http://www.atariarchives.org/c3ba/page004.php */ -/* (Defined below in the order the keys appear on a 1200XL keyboard, from top left to bottom right) */ -/* (Note: Numerous Shift+Ctrl+key combos are unavailable) */ +/* KBCODE internal keyboard codes for Atari 8-bit computers*/ -#define KEYCODE_NONE 255 /* 255 = no key pressed (but is also same as Ctrl+Shift+A) */ +/* Defined below in the order the keys appear on a 1200XL keyboard, +** from top left to bottom right. +** Note: Numerous Shift+Ctrl+key combos are unavailable. +** (Source: "Compute!'s Thrid Book of Atari", "Reading the Keyboard Codes") +*/ + +#define KEYCODE_NONE 255 /* No key pressed (but also Ctrl+Shift+A) */ + + +/* Special keys: */ + +/* N.B. Reset key not handled like other keys */ + +/* N.B. Select, Start, and Option console keys not handled like other keys; +** see CONSOL register in GTIA +*/ /* Fn (function) keys only available on 1200XL */ -#define KEYCODE_F1 3 -#define KEYCODE_F2 4 -#define KEYCODE_F3 19 -#define KEYCODE_F4 20 +#define KEYCODE_F1 3 +#define KEYCODE_F2 4 +#define KEYCODE_F3 19 +#define KEYCODE_F4 20 /* HELP key only available on XL/XE series */ -#define KEYCODE_HELP 17 +#define KEYCODE_HELP 17 -#define KEYCODE_ESC 28 -#define KEYCODE_1 31 -#define KEYCODE_2 30 -#define KEYCODE_3 26 -#define KEYCODE_4 24 -#define KEYCODE_5 29 -#define KEYCODE_6 27 -#define KEYCODE_7 51 -#define KEYCODE_8 53 -#define KEYCODE_9 48 -#define KEYCODE_0 50 -#define KEYCODE_LT 54 -#define KEYCODE_GT 55 -#define KEYCODE_BKSPC 52 +/* N.B. Break key not handled like other keys */ -#define KEYCODE_TAB 44 -#define KEYCODE_Q 47 -#define KEYCODE_W 46 -#define KEYCODE_E 42 -#define KEYCODE_R 40 -#define KEYCODE_T 45 -#define KEYCODE_Y 43 -#define KEYCODE_U 11 -#define KEYCODE_I 13 -#define KEYCODE_O 8 -#define KEYCODE_P 10 -#define KEYCODE_MINUS 14 -#define KEYCODE_EQUALS 15 -#define KEYCODE_RETURN 12 -#define KEYCODE_CTRL 128 /* binary OR'd */ +/* Keyboard top row */ -#define KEYCODE_A 63 -#define KEYCODE_S 62 -#define KEYCODE_D 58 -#define KEYCODE_F 56 -#define KEYCODE_G 61 -#define KEYCODE_H 57 -#define KEYCODE_J 1 -#define KEYCODE_K 5 -#define KEYCODE_L 0 -#define KEYCODE_; 2 -#define KEYCODE_PLUS 6 -#define KEYCODE_ASTERISK 7 -#define KEYCODE_CAPS 60 +#define KEYCODE_ESC 28 +#define KEYCODE_1 31 +#define KEYCODE_2 30 +#define KEYCODE_3 26 +#define KEYCODE_4 24 +#define KEYCODE_5 29 +#define KEYCODE_6 27 +#define KEYCODE_7 51 +#define KEYCODE_8 53 +#define KEYCODE_9 48 +#define KEYCODE_0 50 +#define KEYCODE_LT 54 +#define KEYCODE_GT 55 +#define KEYCODE_BKSPC 52 -#define KEYCODE_SHIFT 64 /* binary OR'd */ -#define KEYCODE_Z 23 -#define KEYCODE_X 22 -#define KEYCODE_C 18 -#define KEYCODE_V 16 -#define KEYCODE_B 21 -#define KEYCODE_N 35 -#define KEYCODE_M 37 -#define KEYCODE_COMMA 32 -#define KEYCODE_PERIOD 34 -#define KEYCODE_SLASH 38 -#define KEYCODE_FUJI 39 /* (as seen on 400/800) */ -#define KEYCODE_INVERSE 39 /* (alternative name; as seen on XL/XE) */ +/* Keyboard second row */ -#define KEYCODE_SPACE 33 +#define KEYCODE_TAB 44 +#define KEYCODE_Q 47 +#define KEYCODE_W 46 +#define KEYCODE_E 42 +#define KEYCODE_R 40 +#define KEYCODE_T 45 +#define KEYCODE_Y 43 +#define KEYCODE_U 11 +#define KEYCODE_I 13 +#define KEYCODE_O 8 +#define KEYCODE_P 10 +#define KEYCODE_MINUS 14 +#define KEYCODE_EQUALS 15 +#define KEYCODE_RETURN 12 + + +/* Keyboard third row */ + +#define KEYCODE_CTRL 128 /* binary OR'd */ +/* N.B. Cannot read Ctrl key alone */ + +#define KEYCODE_A 63 +#define KEYCODE_S 62 +#define KEYCODE_D 58 +#define KEYCODE_F 56 +#define KEYCODE_G 61 +#define KEYCODE_H 57 +#define KEYCODE_J 1 +#define KEYCODE_K 5 +#define KEYCODE_L 0 +#define KEYCODE_SEMICOLON 2 +#define KEYCODE_PLUS 6 +#define KEYCODE_ASTERISK 7 +#define KEYCODE_CAPS 60 + + +/* Keyboard bottom row */ + +#define KEYCODE_SHIFT 64 /* binary OR'd */ +/* N.B. Cannot read Shift key alone via KBCODE; +** instead, check "Shfit key press" bit of SKSTAT register +*/ + +#define KEYCODE_Z 23 +#define KEYCODE_X 22 +#define KEYCODE_C 18 +#define KEYCODE_V 16 +#define KEYCODE_B 21 +#define KEYCODE_N 35 +#define KEYCODE_M 37 +#define KEYCODE_COMMA 32 +#define KEYCODE_PERIOD 34 +#define KEYCODE_SLASH 38 +#define KEYCODE_FUJI 39 /* (as seen on 400/800) */ +#define KEYCODE_INVERSE 39 /* (alternative name; as seen on XL/XE) */ + +/* N.B. No way to tell left from right Shift keys */ + + +/* Keyboard Space key */ + +#define KEYCODE_SPACE 33 /* End of _pokey.h */ #endif /* #ifndef __POKEY_H */ - diff --git a/include/atari.h b/include/atari.h index f9c78be0c..613f0e5bb 100644 --- a/include/atari.h +++ b/include/atari.h @@ -86,14 +86,18 @@ #define CH_HLINE 0x12 #define CH_VLINE 0x7C -/* color defines */ -/* make GTIA color value */ +/* Color definitions */ + +/* Make a GTIA color value */ #define _gtia_mkcolor(hue,lum) (((hue) << 4) | ((lum) << 1)) -/* luminance values go from 0 (black) to 7 (white) */ +/* Luminance values go from 0 (black) to 7 (white) */ -/* hue values (these can vary depending on TV standard (NTSC vs PAL), tint potentiometer settings, TV tint settings, emulator palette, etc.) */ +/* Hue values */ +/* (These can vary depending on TV standard (NTSC vs PAL), +** tint potentiometer settings, TV tint settings, emulator palette, etc.) +*/ #define HUE_GREY 0 #define HUE_GOLD 1 #define HUE_GOLDORANGE 2 @@ -112,7 +116,9 @@ #define HUE_YELLOWRED 15 /* Color defines, similar to c64 colors (untested) */ -/* Note that the conio color implementation is monochrome (bgcolor and textcolor are only placeholders) */ +/* Note that the conio color implementation is monochrome +** (bgcolor and textcolor are only placeholders) +*/ /* Use the defines with the setcolor() or _atari_xxxcolor() functions */ #define COLOR_BLACK _gtia_mkcolor(HUE_GREY,0) #define COLOR_WHITE _gtia_mkcolor(HUE_GREY,7) @@ -256,18 +262,18 @@ #define KEY_LEFT (KEY_PLUS | KEY_CTRL) #define KEY_RIGHT (KEY_ASTERISK | KEY_CTRL) -/* color register functions */ +/* Color register functions */ extern void __fastcall__ _setcolor (unsigned char color_reg, unsigned char hue, unsigned char luminace); extern void __fastcall__ _setcolor_low (unsigned char color_reg, unsigned char color_value); extern unsigned char __fastcall__ _getcolor (unsigned char color_reg); -/* other screen functions */ +/* Other screen functions */ extern int __fastcall__ _graphics (unsigned char mode); /* mode value same as in BASIC */ extern void __fastcall__ _scroll (signed char numlines); /* numlines > 0 scrolls up */ /* numlines < 0 scrolls down */ -/* misc. functions */ +/* 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 */ @@ -275,7 +281,7 @@ 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 */ -/* global variables */ +/* Global variables */ extern unsigned char _dos_type; /* the DOS flavour */ #ifndef __ATARIXL__ extern void atr130_emd[]; @@ -443,6 +449,5 @@ struct __iocb { #define IOCB_FORMAT 0xFE /* format */ - /* End of atari.h */ #endif From 93a13315deb03f660b26b9026ded8a50ba0c753b Mon Sep 17 00:00:00 2001 From: Bill Kendrick <nbs@sonic.net> Date: Wed, 16 Jan 2019 23:29:41 -0800 Subject: [PATCH 0977/2161] Comment adjustments; removed surperfluous keycodes Cleaned up comments in Atari 8-bit headers. Internal keycodes (POKEY's KBCODE) were already #defined in atari.h, so didn't need a whole new set in _pokey.h. --- include/_antic.h | 100 +++++++++++++++++++------- include/_gtia.h | 67 ++++++++++++------ include/_pia.h | 60 +++++++++------- include/_pokey.h | 179 ++++++++++++----------------------------------- include/atari.h | 96 ++++++++++++++++++++----- 5 files changed, 282 insertions(+), 220 deletions(-) diff --git a/include/_antic.h b/include/_antic.h index 8520c5f19..f9d880b0a 100644 --- a/include/_antic.h +++ b/include/_antic.h @@ -18,7 +18,7 @@ /* */ /* (C) 2000 Freddy Offenga <taf_offenga@yahoo.com> */ /* 24-Jan-2011: Christian Krueger: Added defines for Antic instruction set */ -/* 2019-01-14: Bill Kendrick <nbs@sonic.net>: More defines for registers */ +/* 2019-01-16: Bill Kendrick <nbs@sonic.net>: More defines for registers */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -44,7 +44,10 @@ #ifndef __ANTIC_H #define __ANTIC_H -/* Define a structure with the ANTIC coprocessor's register offsets */ +/*****************************************************************************/ +/* Define a structure with the ANTIC coprocessor's register offsets */ +/*****************************************************************************/ + struct __antic { unsigned char dmactl; /* (W) direct memory access control */ unsigned char chactl; /* (W) character mode control */ @@ -68,7 +71,10 @@ struct __antic { }; -/* DMACTL register options */ +/*****************************************************************************/ +/* DMACTL register options */ +/*****************************************************************************/ + /* Initialized to 0x22: DMA fetch, normal playfield, no PMG DMA, double-line PMGs */ /* Playfield modes: */ @@ -96,7 +102,10 @@ struct __antic { #define DMACTL_DMA_FETCH 0x20 -/* CHACTL register options */ +/*****************************************************************************/ +/* CHACTL register options */ +/*****************************************************************************/ + /* Initialized to 2 (CHACTL_CHAR_NORMAL | CHACTL_INV_PRESENT) */ /* Inverted (upside-down) characters */ @@ -109,27 +118,29 @@ struct __antic { #define CHACTL_INV_PRESENT 0x02 /* chars with high-bit are reverse-video */ -/* Register bits for NMIEN (enabling interrupts) -** and NMIST (determining the cause for the NMI interrupt) -*/ +/*****************************************************************************/ +/* Values for NMIEN (enabling interrupts) & NMIST (cause for the interrupt) */ +/*****************************************************************************/ -#define NMIEN_DLI 0x80 /* Display List Interrupts ** Called on a modeline when "DL_DLI" bit is set the ANTIC instruction, ** and jumps through VDSLST vector. */ +#define NMIEN_DLI 0x80 -#define NMIEN_VBI 0x40 /* Vertical Blank Interrupt ** Called during every vertical blank; see SYSVBV, VVBLKI, CRITIC, and VVBLKD, ** as well as the SETVBV routine. */ +#define NMIEN_VBI 0x40 -#define NMIEN_RESET 0x20 /* [Reset] key pressed */ +#define NMIEN_RESET 0x20 -/* ANTIC instruction set */ +/*****************************************************************************/ +/* ANTIC instruction set */ +/*****************************************************************************/ /* Absolute instructions (non mode lines) */ #define DL_JMP ((unsigned char) 1) @@ -144,28 +155,63 @@ struct __antic { #define DL_BLK7 ((unsigned char) 96) #define DL_BLK8 ((unsigned char) 112) + /* Absolute instructions (mode lines) */ -/* Note: Actual width varies (e.g., 40 vs 32 vs 48) depending on normal vs narrow vs wide (overscan) playfield setting; see DMACTL */ + +/* Note: Actual width varies (e.g., 40 vs 32 vs 48) depending on +** normal vs narrow vs wide (overscan) playfield setting; see DMACTL +*/ /* Character modes (text, tile graphics, etc.) */ -#define DL_CHR40x8x1 ((unsigned char) 2) /* monochrome, 40 character & 8 scanlines per mode line (aka Atari BASIC GRAPHICS 0 via OS's CIO routines) */ -#define DL_CHR40x10x1 ((unsigned char) 3) /* monochrome, 40 character & 10 scanlines per mode line (like GR. 0, with descenders) */ -#define DL_CHR40x8x4 ((unsigned char) 4) /* colour, 40 character & 8 scanlines per mode line (GR. 12) */ -#define DL_CHR40x16x4 ((unsigned char) 5) /* colour, 40 character & 16 scanlines per mode line (GR. 13) */ -#define DL_CHR20x8x2 ((unsigned char) 6) /* colour (duochrome per character), 20 character & 8 scanlines per mode line (GR. 1) */ -#define DL_CHR20x16x2 ((unsigned char) 7) /* colour (duochrome per character), 20 character & 16 scanlines per mode line (GR. 2) */ + +/* monochrome, 40 character & 8 scanlines per mode line (aka Atari BASIC GRAPHICS 0 via OS's CIO routines) */ +#define DL_CHR40x8x1 ((unsigned char) 2) + +/* monochrome, 40 character & 10 scanlines per mode line (like GR. 0, with descenders) */ +#define DL_CHR40x10x1 ((unsigned char) 3) + +/* colour, 40 character & 8 scanlines per mode line (GR. 12) */ +#define DL_CHR40x8x4 ((unsigned char) 4) + +/* colour, 40 character & 16 scanlines per mode line (GR. 13) */ +#define DL_CHR40x16x4 ((unsigned char) 5) + +/* colour (duochrome per character), 20 character & 8 scanlines per mode line (GR. 1) */ +#define DL_CHR20x8x2 ((unsigned char) 6) + +/* colour (duochrome per character), 20 character & 16 scanlines per mode line (GR. 2) */ +#define DL_CHR20x16x2 ((unsigned char) 7) + /* Bitmap modes */ -#define DL_MAP40x8x4 ((unsigned char) 8) /* colour, 40 pixel & 8 scanlines per mode line (GR. 3) */ -#define DL_MAP80x4x2 ((unsigned char) 9) /* 'duochrome', 80 pixel & 4 scanlines per mode line (GR.4) */ -#define DL_MAP80x4x4 ((unsigned char) 10) /* colour, 80 pixel & 4 scanlines per mode line (GR.5) */ -#define DL_MAP160x2x2 ((unsigned char) 11) /* 'duochrome', 160 pixel & 2 scanlines per mode line (GR.6) */ -#define DL_MAP160x1x2 ((unsigned char) 12) /* 'duochrome', 160 pixel & 1 scanline per mode line (GR.14) */ -#define DL_MAP160x2x4 ((unsigned char) 13) /* 4 colours, 160 pixel & 2 scanlines per mode line (GR.7) */ -#define DL_MAP160x1x4 ((unsigned char) 14) /* 4 colours, 160 pixel & 1 scanline per mode line (GR.15) */ -#define DL_MAP320x1x1 ((unsigned char) 15) /* monochrome, 320 pixel & 1 scanline per mode line (GR.8) */ + +/* colour, 40 pixel & 8 scanlines per mode line (GR. 3) */ +#define DL_MAP40x8x4 ((unsigned char) 8) + +/* 'duochrome', 80 pixel & 4 scanlines per mode line (GR.4) */ +#define DL_MAP80x4x2 ((unsigned char) 9) + +/* colour, 80 pixel & 4 scanlines per mode line (GR.5) */ +#define DL_MAP80x4x4 ((unsigned char) 10) + +/* 'duochrome', 160 pixel & 2 scanlines per mode line (GR.6) */ +#define DL_MAP160x2x2 ((unsigned char) 11) + +/* 'duochrome', 160 pixel & 1 scanline per mode line (GR.14) */ +#define DL_MAP160x1x2 ((unsigned char) 12) + +/* 4 colours, 160 pixel & 2 scanlines per mode line (GR.7) */ +#define DL_MAP160x2x4 ((unsigned char) 13) + +/* 4 colours, 160 pixel & 1 scanline per mode line (GR.15) */ +#define DL_MAP160x1x4 ((unsigned char) 14) + +/* monochrome, 320 pixel & 1 scanline per mode line (GR.8) */ +#define DL_MAP320x1x1 ((unsigned char) 15) + /* Equivalents, for people familiar with Atari 8-bit OS */ + #define DL_GRAPHICS0 DL_CHR40x8x1 #define DL_GRAPHICS1 DL_CHR20x8x2 #define DL_GRAPHICS2 DL_CHR20x16x2 @@ -196,7 +242,7 @@ struct __antic { #define DL_LMS(x) ((unsigned char)((x) | 64)) /* Load Memory Scan (next two bytes must be the LSB/MSB of the data to load) */ /* General modifier */ -#define DL_DLI(x) ((unsigned char)((x) | 128)) /* enable Display List Interrupt on this mode line; requires NMIEN be set to enable DLIs */ +#define DL_DLI(x) ((unsigned char)((x) | 128)) /* enable Display List Interrupt on this mode line */ /* End of _antic.h */ diff --git a/include/_gtia.h b/include/_gtia.h index 25d26093c..25181e875 100644 --- a/include/_gtia.h +++ b/include/_gtia.h @@ -13,7 +13,7 @@ /* */ /* */ /* (C) 2000 Freddy Offenga <taf_offenga@yahoo.com> */ -/* 2019-01-14: Bill Kendrick <nbs@sonic.net>: More defines for registers */ +/* 2019-01-16: Bill Kendrick <nbs@sonic.net>: More defines for registers */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -39,7 +39,10 @@ #ifndef __GTIA_H #define __GTIA_H -/* Define a structure with the GTIA register offsets for write (W) */ +/*****************************************************************************/ +/* Define a structure with the GTIA register offsets for write (W) */ +/*****************************************************************************/ + struct __gtia_write { unsigned char hposp0; /* 0x00: horizontal position of player 0 */ unsigned char hposp1; /* 0x01: horizontal position of player 1 */ @@ -86,7 +89,10 @@ struct __gtia_write { }; -/* Values for SIZEP0-SIZEP3 and SIZEM registers: */ +/*****************************************************************************/ +/* (W) Values for SIZEP0-SIZEP3 and SIZEM registers: */ +/*****************************************************************************/ + #define PMG_SIZE_NORMAL 0x0 /* one color clock per pixel */ #define PMG_SIZE_DOUBLE 0x1 /* two color clocks per pixel */ #define PMG_SIZE_QUAD 0x2 /* four color clocks per pixel */ @@ -97,7 +103,10 @@ struct __gtia_write { ** Bitwise OR (|) with 0x00 (darkest) through 0x0F (lightest) (only even values are unique) */ -/* PRIOR register values */ + +/*****************************************************************************/ +/* (W) PRIOR register values */ +/*****************************************************************************/ #define PRIOR_P03_PF03 0x01 /* Players 0-3, then Playfields 0-3, then background */ #define PRIOR_P01_PF03_P23 0x02 /* Players 0-1, then Playfields 0-3, then Players 2-3, then background */ @@ -106,35 +115,41 @@ struct __gtia_write { #define PRIOR_5TH_PLAYER 0x10 /* Four missiles combine to be a 5th player (uses COLPF3) */ -#define PRIOR_OVERLAP_3RD_COLOR 0x20 /* Overlap of players result in a 3rd color */ -/* Overlap of players 0 & 1 and of players 2 & 3 results in a third color, -** the logical OR of the two players' colors; -** Other overlaps (e.g., players 0 and 2) result in black (0x00). +/* Causes overlap of players 0 & 1 and of players 2 & 3 to result in a third color, +** the logical OR of the two players' colors, and other overlaps (e.g., players 0 and 2) +** to result in black (0x00). */ +#define PRIOR_OVERLAP_3RD_COLOR 0x20 + + +/*****************************************************************************/ +/* (W) GTIA special graphics mode options for GPRIOR */ +/*****************************************************************************/ -/* GTIA special graphics mode options */ /* Pixels are 2 color clocks wide, and one scanline tall ** (so 80x192 in normal playfield width). ** May be used with both bitmap and character modelines. */ -#define PRIOR_GFX_MODE_9 0x40 /* 16 shade shades of the background (COLBK) hue; ** Note: brightnesses other than 0 (darkest) in COLBK cause additional effects */ +#define PRIOR_GFX_MODE_9 0x40 -#define PRIOR_GFX_MODE_10 0x80 /* 9 color palette mode; ** COLPM0 (acts as background) thru COLPM3, followed by COLPF0 thru COLPF3, and COLBK */ +#define PRIOR_GFX_MODE_10 0x80 -#define PRIOR_GFX_MODE_11 0xC0 /* 16 hues of the background (COLBK) brightness; ** Note: hues other than 0 (greys) in COLBK caus additional effects */ +#define PRIOR_GFX_MODE_11 0xC0 -/* VDELAY register values */ +/*****************************************************************************/ +/* (W) VDELAY register values */ +/*****************************************************************************/ #define VDELAY_MISSILE0 0x01 #define VDELAY_MISSILE1 0x02 @@ -146,18 +161,23 @@ struct __gtia_write { #define VDELAY_PLAYER3 0x80 -/* GRACTL register values */ +/*****************************************************************************/ +/* (W) GRACTL register values */ +/*****************************************************************************/ #define GRACTL_MISSLES 0x01 /* enable missiles */ #define GRACTL_PLAYERS 0x02 /* enable players */ -#define GRACTL_LATCH_TRIGGER_INPUTS 0x04 /* "Latch" triggers; once pressed, will give a continuous ** pressed input until this bit is cleared */ +#define GRACTL_LATCH_TRIGGER_INPUTS 0x04 -/* Define a structure with the GTIA register offsets for read (R) */ +/*****************************************************************************/ +/* Define a structure with the GTIA register offsets for read (R) */ +/*****************************************************************************/ + struct __gtia_read { unsigned char m0pf; /* 0x00: missile 0 to playfield collision */ unsigned char m1pf; /* 0x01: missile 1 to playfield collision */ @@ -189,15 +209,22 @@ struct __gtia_read { }; -/* PAL register possible values */ +/*****************************************************************************/ +/* (R) PAL register possible values */ +/*****************************************************************************/ + +/* Note: This only tells you whether the GTIA is PAL or NTSC; some NTSC +** systems are modded with PAL ANTIC chips; testing VCOUNT limits can be +** done to check for that. Seems like it's not possible to test for SECAM +*/ #define TV_STD_PAL 0x1 #define TV_STD_NTSC 0xE -/* Note: This only tells you whether the GTIA is PAL or NTSC; some NTSC systems are modded with PAL ANTIC chips; testing VCOUNT limits can be done to check for that */ -/* Note: Seems like it's not possible to test for SECAM */ -/* Reading console keys (Start, Select, Option) via CONSOL register: */ +/*****************************************************************************/ +/* Macros for reading console keys (Start/Select/Option) via CONSOL register */ +/*****************************************************************************/ #define CONSOL_START(x) !((unsigned char)((x) & 1)) /* true if Start pressed */ #define CONSOL_SELECT(x) !((unsigned char)((x) & 2)) /* true if Select pressed */ diff --git a/include/_pia.h b/include/_pia.h index dc3830acb..51426cc80 100644 --- a/include/_pia.h +++ b/include/_pia.h @@ -7,11 +7,11 @@ /* The Peripheral Interface Adapter (PIA) chip provides parallel I/O */ /* interfacing; it was used in Atari 400/800 and Commodore PET family of */ /* computers, for joystick and interrupts. */ -/* - Sources; various + Wikpedia article on "Peripheral Interface Adapter" */ +/* Sources; various + Wikpedia article on "Peripheral Interface Adapter". */ /* */ /* */ /* (C) 2000 Freddy Offenga <taf_offenga@yahoo.com> */ -/* 2019-01-14: Bill Kendrick <nbs@sonic.net>: Defines for registers */ +/* 2019-01-16: Bill Kendrick <nbs@sonic.net>: Defines for registers */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -48,7 +48,9 @@ struct __pia { }; -/* PORTA and PORTB register bits */ +/*****************************************************************************/ +/* PORTA and PORTB register bits */ +/*****************************************************************************/ /* See also: "JOY_xxx_MASK" in "atari.h" */ @@ -72,23 +74,23 @@ struct __pia { ** LED control (1200XL model only) register (read/write): */ -#define PORTB_OSROM 0x01 /* If set, the built-in OS is enabled, and occupies the address range $C000-$FFFF ** (except that the area $D000-$D7FF will only access the hardware registers.) ** If clear, RAM is enabled in this area (again, save for the hole.) */ +#define PORTB_OSROM 0x01 -#define PORTB_BASICROM 0x02 /* If set, RAM is enabled for the address range $A000-$BFFF. ** If clear, the built-in BASIC ROM is enabled at this address. ** And if there is a cartridge installed in the computer, it makes no difference. */ +#define PORTB_BASICROM 0x02 -#define PORTB_LED1 0x04 -#define PORTB_LED2 0x08 /* If set, the corresponding LED is turned off. If clear, the LED will be on. ** (1200XL only) */ +#define PORTB_LED1 0x04 +#define PORTB_LED2 0x08 /* On the XE series of computers, PORTB is a bank-selected memory control register (read/write): */ @@ -101,49 +103,59 @@ struct __pia { #define PORTB_BANKSELECT3 0x08 #define PORTB_BANKSELECT4 0x0C - -#define PORTB_BANKSWITCH_CPU 0x10 -#define PORTB_BANKSWITCH_ANTIC 0x20 /* If set, the CPU and/or ANTIC chip will access bank-switched memory mapped to the ** address range $4000-$7FFF. ** If clear, the CPU and/or ANTIC will see normal memory in this region. */ +#define PORTB_BANKSWITCH_CPU 0x10 +#define PORTB_BANKSWITCH_ANTIC 0x20 - -#define PORTB_SELFTEST 0x80 /* If set, RAM is enabled for the address range $5000-$57FF. ** If clear, the self-test ROM (physically located at $D000-$D7FF, under the hardware registers) ** is remapped to this memory area. */ +#define PORTB_SELFTEST 0x80 -/* PACTL and PBCTL register bits */ +/*****************************************************************************/ +/* PACTL and PBCTL register bits */ +/*****************************************************************************/ -#define PxCTL_IRQ_ENABLE 0x01 /* (W) Peripheral A interrupt (IRQ) enable. */ -/* One equals enable. Set by the OS but available to the user; reset on powerup. */ +/* (W) Peripheral A interrupt (IRQ) enable. +** One equals enable. Set by the OS but available to the user; reset on powerup. +*/ +#define PxCTL_IRQ_ENABLE 0x01 -#define PxCTL_BIT1 0x02 /* "Set to zero" */ +/* "Set to zero" */ +#define PxCTL_BIT1 0x02 -#define PxCTL_ADDRESSING 0x04 /* (W) Controls PORTA addressing */ -/* One equals PORTA register; zero equals direction control register */ +/* (W) Controls PORTA addressing +** One equals PORTA register; zero equals direction control register +*/ +#define PxCTL_ADDRESSING 0x04 #define PxCTL_BIT4 0x10 /* "Set to one" */ #define PxCTL_BIT5 0x20 /* "Set to one" */ #define PxCTL_BIT6 0x40 /* "Set to zero" */ -#define PxCTL_IRQ_STATUS 0x80 /* Peripheral interrupt (IRQ) status bit. */ -/* Set by Peripherals (PORTA / PORTB). Reset by reading PORTA / PORTB. */ + +/* Peripheral interrupt (IRQ) status bit. +** Set by Peripherals (PORTA / PORTB). Reset by reading PORTA / PORTB. +*/ +#define PxCTL_IRQ_STATUS 0x80 /* PACTL-specific register bit */ -#define PACTL_MOTOR_CONTROL 0x08 /* (W) Peripheral motor control line */ -/* Turn the cassette on or off; zero equals on) */ +/* (W) Peripheral motor control line +** Turn the cassette on or off; zero equals on) +*/ +#define PACTL_MOTOR_CONTROL 0x08 /* PBCTL-specific register bit */ -#define PBCTL_PERIPH_CMD_IDENT 0x08 /* Peripheral command identification (serial bus command) */ - +/* Peripheral command identification (serial bus command) */ +#define PBCTL_PERIPH_CMD_IDENT 0x08 /* End of _pia.h */ diff --git a/include/_pokey.h b/include/_pokey.h index 01a3225a6..88d6949aa 100644 --- a/include/_pokey.h +++ b/include/_pokey.h @@ -14,7 +14,7 @@ /* */ /* */ /* (C) 2000 Freddy Offenga <taf_offenga@yahoo.com> */ -/* 2019-01-14: Bill Kendrick <nbs@sonic.net>: More defines for registers */ +/* 2019-01-16: Bill Kendrick <nbs@sonic.net>: More defines for registers */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -43,7 +43,10 @@ -/* Define a structure with the POKEY register offsets for write (W) */ +/*****************************************************************************/ +/* Define a structure with the POKEY register offsets for write (W) */ +/*****************************************************************************/ + struct __pokey_write { unsigned char audf1; /* audio channel #1 frequency */ unsigned char audc1; /* audio channel #1 control */ @@ -69,8 +72,9 @@ struct __pokey_write { }; - -/* AUDC1-4 register values */ +/*****************************************************************************/ +/* (W) AUDC1-4 register values */ +/*****************************************************************************/ /* Meaningful values for the distortion bits. ** The first process is to divide the clock value by the frequency, @@ -91,7 +95,9 @@ struct __pokey_write { #define AUDC_VOLUME_ONLY 0x10 -/* AUDCTL register values */ +/*****************************************************************************/ +/* (W) AUDCTL register values */ +/*****************************************************************************/ #define AUDCTL_CLOCKBASE_15HZ 0x01 /* Switch main clock base from 64 KHz to 15 KHz */ #define AUDCTL_HIGHPASS_CHAN2 0x02 /* Insert high pass filter into channel two, clocked by channel four */ @@ -103,7 +109,9 @@ struct __pokey_write { #define AUDCTL_9BIT_POLY 0x80 /* Makes the 17 bit poly counter into nine bit poly (see also: RANDOM) */ -/* IRQEN register values */ +/*****************************************************************************/ +/* (W) IRQEN register values */ +/*****************************************************************************/ #define IRQEN_TIMER_1 0x01 /* The POKEY timer one interrupt is enabled */ #define IRQEN_TIMER_2 0x02 /* The POKEY timer two interrupt is enabled */ @@ -115,49 +123,57 @@ struct __pokey_write { #define IRQEN_BREAK_KEY 0x80 /* The BREAK key is enabled */ -/* SKCTL register values */ +/*****************************************************************************/ +/* (W) SKCTL register values */ +/*****************************************************************************/ #define SKCTL_KEYBOARD_DEBOUNCE 0x01 /* Enable keyboard debounce circuits */ #define SKCTL_KEYBOARD_SCANNING 0x02 /* Enable keyboard scanning circuit */ -#define SKCTL_FAST_POT_SCAN 0x04 /* Fast pot scan */ -/* The pot scan counter completes its sequence in two TV line times instead of +/* Fast pot scan +** The pot scan counter completes its sequence in two TV line times instead of ** one frame time (228 scan lines). Not as accurate as the normal pot scan */ +#define SKCTL_FAST_POT_SCAN 0x04 -#define SKCTL_TWO_TONE_MODE 0x08 /* POKEY two-tone mode */ -/* Serial output is transmitted as a two-tone signal rather than a logic true/false. */ +/* POKEY two-tone mode +** Serial output is transmitted as a two-tone signal rather than a logic true/false. +*/ +#define SKCTL_TWO_TONE_MODE 0x08 + +/* Force break (serial output to zero) */ +#define SKCTL_FORCE_BREAK 0x80 /* Bits 4, 5, and 6 of SKCTL set Serial Mode Control: */ -#define SKCTL_SER_MODE_TX_EXT_RX_EXT 0x00 /* Trans. & Receive rates set by external clock; Also internal clock phase reset to zero. */ +#define SKCTL_SER_MODE_TX_EXT_RX_EXT 0x00 -#define SKCTL_SER_MODE_TX_EXT_RX_ASYNC 0x10 /* Trans. rate set by external clock; Receive asynch. (ch. 4) (CH3 and CH4). */ +#define SKCTL_SER_MODE_TX_EXT_RX_ASYNC 0x10 -#define SKCTL_SER_MODE_TX_CH4_RX_CH4_BIDIR 0x20 /* Trans. & Receive rates set by Chan. 4; Chan. 4 output on Bi-Direct. clock line. */ +#define SKCTL_SER_MODE_TX_CH4_RX_CH4_BIDIR 0x20 /* N.B.: Bit combination 0,1,1 not useful */ -#define SKCTL_SER_MODE_TX_CH4_RX_EXT 0x40 /* Trans. rate set by Chan. 4; Receive rate set by external clock. */ +#define SKCTL_SER_MODE_TX_CH4_RX_EXT 0x40 /* N.B.: Bit combination 1,0,1 not useful */ -#define SKCTL_SER_MODE_TX_CH2_RX_CH4_BIDIR 0x60 /* Trans. rate set by Chan. 2; Receive rate set by Chan. 4; Chan. 4 out on Bi-Direct. clock line. */ +#define SKCTL_SER_MODE_TX_CH2_RX_CH4_BIDIR 0x60 -#define SKCTL_SER_MODE_TX_CH4_RX_ASYNC 0x70 /* Trans. rate set by Chan. 2; Receive asynch. (chan 3 & 4); Bi-Direct. clock not used (tri-state condition). */ +#define SKCTL_SER_MODE_TX_CH4_RX_ASYNC 0x70 -#define SKCTL_FORCE_BREAK 0x80 /* Force break (serial output to zero) */ +/*****************************************************************************/ +/* Define a structure with the POKEY register offsets for read (R) */ +/*****************************************************************************/ - -/* Define a structure with the POKEY register offsets for read (R) */ struct __pokey_read { unsigned char pot0; /* paddle 0 value */ unsigned char pot1; /* paddle 1 value */ @@ -178,7 +194,10 @@ struct __pokey_read { }; -/* SKSTAT register values */ +/*****************************************************************************/ +/* (R) SKSTAT register values */ +/*****************************************************************************/ + #define SKSTAT_SERIN_SHIFTREG_BUSY 0x02 /* Serial input shift register busy */ #define SKSTAT_LASTKEY_PRESSED 0x04 /* the last key is still pressed */ #define SKSTAT_SHIFTKEY_PRESSED 0x08 /* the [Shift] key is pressed */ @@ -188,120 +207,14 @@ struct __pokey_read { #define SKSTAT_INPUT_FRAMEERROR 0x80 /* Serial data input frame error caused by missing or extra bits. Reset latches as above. */ -/* KBCODE internal keyboard codes for Atari 8-bit computers*/ - -/* Defined below in the order the keys appear on a 1200XL keyboard, -** from top left to bottom right. -** Note: Numerous Shift+Ctrl+key combos are unavailable. -** (Source: "Compute!'s Thrid Book of Atari", "Reading the Keyboard Codes") +/* KBCODE, internal keyboard codes for Atari 8-bit computers, +** are #defined as "KEY_..." in "atari.h". +** Note some keys are not read via KBCODE: +** - Reset +** - Start, Select, and Option; see CONSOL in "gtia.h" +** - Break */ -#define KEYCODE_NONE 255 /* No key pressed (but also Ctrl+Shift+A) */ - - -/* Special keys: */ - -/* N.B. Reset key not handled like other keys */ - -/* N.B. Select, Start, and Option console keys not handled like other keys; -** see CONSOL register in GTIA -*/ - -/* Fn (function) keys only available on 1200XL */ -#define KEYCODE_F1 3 -#define KEYCODE_F2 4 -#define KEYCODE_F3 19 -#define KEYCODE_F4 20 - -/* HELP key only available on XL/XE series */ -#define KEYCODE_HELP 17 - -/* N.B. Break key not handled like other keys */ - - -/* Keyboard top row */ - -#define KEYCODE_ESC 28 -#define KEYCODE_1 31 -#define KEYCODE_2 30 -#define KEYCODE_3 26 -#define KEYCODE_4 24 -#define KEYCODE_5 29 -#define KEYCODE_6 27 -#define KEYCODE_7 51 -#define KEYCODE_8 53 -#define KEYCODE_9 48 -#define KEYCODE_0 50 -#define KEYCODE_LT 54 -#define KEYCODE_GT 55 -#define KEYCODE_BKSPC 52 - - -/* Keyboard second row */ - -#define KEYCODE_TAB 44 -#define KEYCODE_Q 47 -#define KEYCODE_W 46 -#define KEYCODE_E 42 -#define KEYCODE_R 40 -#define KEYCODE_T 45 -#define KEYCODE_Y 43 -#define KEYCODE_U 11 -#define KEYCODE_I 13 -#define KEYCODE_O 8 -#define KEYCODE_P 10 -#define KEYCODE_MINUS 14 -#define KEYCODE_EQUALS 15 -#define KEYCODE_RETURN 12 - - -/* Keyboard third row */ - -#define KEYCODE_CTRL 128 /* binary OR'd */ -/* N.B. Cannot read Ctrl key alone */ - -#define KEYCODE_A 63 -#define KEYCODE_S 62 -#define KEYCODE_D 58 -#define KEYCODE_F 56 -#define KEYCODE_G 61 -#define KEYCODE_H 57 -#define KEYCODE_J 1 -#define KEYCODE_K 5 -#define KEYCODE_L 0 -#define KEYCODE_SEMICOLON 2 -#define KEYCODE_PLUS 6 -#define KEYCODE_ASTERISK 7 -#define KEYCODE_CAPS 60 - - -/* Keyboard bottom row */ - -#define KEYCODE_SHIFT 64 /* binary OR'd */ -/* N.B. Cannot read Shift key alone via KBCODE; -** instead, check "Shfit key press" bit of SKSTAT register -*/ - -#define KEYCODE_Z 23 -#define KEYCODE_X 22 -#define KEYCODE_C 18 -#define KEYCODE_V 16 -#define KEYCODE_B 21 -#define KEYCODE_N 35 -#define KEYCODE_M 37 -#define KEYCODE_COMMA 32 -#define KEYCODE_PERIOD 34 -#define KEYCODE_SLASH 38 -#define KEYCODE_FUJI 39 /* (as seen on 400/800) */ -#define KEYCODE_INVERSE 39 /* (alternative name; as seen on XL/XE) */ - -/* N.B. No way to tell left from right Shift keys */ - - -/* Keyboard Space key */ - -#define KEYCODE_SPACE 33 - /* End of _pokey.h */ #endif /* #ifndef __POKEY_H */ diff --git a/include/atari.h b/include/atari.h index 613f0e5bb..af4e6209a 100644 --- a/include/atari.h +++ b/include/atari.h @@ -6,9 +6,10 @@ /* */ /* */ /* */ -/* (C) 2000-2018 Mark Keates <markk@dendrite.co.uk> */ +/* (C) 2000-2019 Mark Keates <markk@dendrite.co.uk> */ /* Freddy Offenga <taf_offenga@yahoo.com> */ /* Christian Groessler <chris@groessler.org> */ +/* Bill Kendrick <nbs@sonic.net> */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -44,7 +45,10 @@ -/* Character codes */ +/*****************************************************************************/ +/* Character codes */ +/*****************************************************************************/ + #define CH_DELCHR 0xFE /* delete char under the cursor */ #define CH_ENTER 0x9B #define CH_ESC 0x1B @@ -87,7 +91,9 @@ #define CH_VLINE 0x7C -/* Color definitions */ +/*****************************************************************************/ +/* Color definitions */ +/*****************************************************************************/ /* Make a GTIA color value */ #define _gtia_mkcolor(hue,lum) (((hue) << 4) | ((lum) << 1)) @@ -155,7 +161,11 @@ #define TGI_COLOR_LIGHTBLUE COLOR_LIGHTBLUE #define TGI_COLOR_GRAY3 COLOR_GRAY3 -/* Masks for joy_read */ + +/*****************************************************************************/ +/* Masks for joy_read */ +/*****************************************************************************/ + #define JOY_UP_MASK 0x01 #define JOY_DOWN_MASK 0x02 #define JOY_LEFT_MASK 0x04 @@ -165,7 +175,11 @@ #define JOY_FIRE_MASK JOY_BTN_1_MASK #define JOY_FIRE(v) ((v) & JOY_FIRE_MASK) -/* Keyboard values returned by kbcode / CH */ + +/*****************************************************************************/ +/* Keyboard values returned by kbcode / CH */ +/*****************************************************************************/ + #define KEY_NONE ((unsigned char) 0xFF) #define KEY_0 ((unsigned char) 0x32) @@ -226,15 +240,26 @@ #define KEY_INVERSE ((unsigned char) 0x27) #define KEY_HELP ((unsigned char) 0x11) +/* Function keys only exist on the 1200XL model. */ #define KEY_F1 ((unsigned char) 0x03) #define KEY_F2 ((unsigned char) 0x04) #define KEY_F3 ((unsigned char) 0x13) #define KEY_F4 ((unsigned char) 0x14) +/* N.B. Cannot read Ctrl key alone */ #define KEY_CTRL ((unsigned char) 0x80) + +/* N.B. Cannot read Shift key alone via KBCODE; +** instead, check "Shfit key press" bit of SKSTAT register. +** Also, no way to tell left Shift from right Shift. +*/ #define KEY_SHIFT ((unsigned char) 0x40) -/* Composed keys */ + +/* Composed keys +** (Other combinations are possible, including Shift+Ctrl+key, +** though not all such combinations are available.) +*/ #define KEY_EXCLAMATIONMARK (KEY_1 | KEY_SHIFT) #define KEY_QUOTE (KEY_2 | KEY_SHIFT) @@ -262,18 +287,29 @@ #define KEY_LEFT (KEY_PLUS | KEY_CTRL) #define KEY_RIGHT (KEY_ASTERISK | KEY_CTRL) -/* Color register functions */ + +/*****************************************************************************/ +/* Color register functions */ +/*****************************************************************************/ + extern void __fastcall__ _setcolor (unsigned char color_reg, unsigned char hue, unsigned char luminace); extern void __fastcall__ _setcolor_low (unsigned char color_reg, unsigned char color_value); extern unsigned char __fastcall__ _getcolor (unsigned char color_reg); -/* Other screen functions */ +/*****************************************************************************/ +/* Other screen functions */ +/*****************************************************************************/ + extern int __fastcall__ _graphics (unsigned char mode); /* mode value same as in BASIC */ extern void __fastcall__ _scroll (signed char numlines); /* numlines > 0 scrolls up */ /* numlines < 0 scrolls down */ -/* Misc. functions */ + +/*****************************************************************************/ +/* 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 */ @@ -281,7 +317,11 @@ 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 */ -/* Global variables */ + +/*****************************************************************************/ +/* Global variables */ +/*****************************************************************************/ + extern unsigned char _dos_type; /* the DOS flavour */ #ifndef __ATARIXL__ extern void atr130_emd[]; @@ -335,7 +375,11 @@ extern void atrx15_tgi[]; extern void atrx15p2_tgi[]; #endif -/* get_ostype return value defines (for explanation, see ostype.s) */ + +/*****************************************************************************/ +/* get_ostype return value defines (for explanation, see ostype.s) */ +/*****************************************************************************/ + /* masks */ #define AT_OS_TYPE_MAIN 7 #define AT_OS_TYPE_MINOR (7 << 3) @@ -358,11 +402,19 @@ extern void atrx15p2_tgi[]; #define AT_OS_XLXE_3 3 #define AT_OS_XLXE_4 4 -/* get_tv return values */ + +/*****************************************************************************/ +/* get_tv return values */ +/*****************************************************************************/ + #define AT_NTSC 0 #define AT_PAL 1 -/* valid _dos_type values */ + +/*****************************************************************************/ +/* valid _dos_type values */ +/*****************************************************************************/ + #define SPARTADOS 0 #define REALDOS 1 #define BWDOS 2 @@ -372,7 +424,11 @@ extern void atrx15p2_tgi[]; #define MYDOS 6 #define NODOS 255 -/* Define hardware */ + +/*****************************************************************************/ +/* Define hardware and where they're mapped in memory */ +/*****************************************************************************/ + #include <_gtia.h> #define GTIA_READ (*(struct __gtia_read*)0xD000) #define GTIA_WRITE (*(struct __gtia_write*)0xD000) @@ -389,7 +445,11 @@ extern void atrx15p2_tgi[]; #include <_antic.h> #define ANTIC (*(struct __antic*)0xD400) -/* device control block */ + +/*****************************************************************************/ +/* Device control block */ +/*****************************************************************************/ + struct __dcb { unsigned char device; /* device id */ unsigned char unit; /* unit number */ @@ -404,7 +464,11 @@ struct __dcb { }; #define DCB (*(struct __dcb *)0x300) -/* I/O control block */ + +/*****************************************************************************/ +/* I/O control block */ +/*****************************************************************************/ + struct __iocb { unsigned char handler; /* handler index number (0xff free) */ unsigned char drive; /* device number (drive) */ From 32525e0ddb728cb828c0541ba4b57343bfafcd7a Mon Sep 17 00:00:00 2001 From: Bill Kendrick <nbs@sonic.net> Date: Thu, 17 Jan 2019 00:23:04 -0800 Subject: [PATCH 0978/2161] atari.h: Shadow registers for hardware registers --- include/atari.h | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/include/atari.h b/include/atari.h index af4e6209a..ba2a43549 100644 --- a/include/atari.h +++ b/include/atari.h @@ -446,6 +446,63 @@ extern void atrx15p2_tgi[]; #define ANTIC (*(struct __antic*)0xD400) +/*****************************************************************************/ +/* Shadow registers for hardware registers */ +/*****************************************************************************/ + +/* GTIA */ +#define STRIG0 (*(unsigned char*)0x284) /* TRIG0 */ +#define STRIG1 (*(unsigned char*)0x285) /* TRIG1 */ +#define STRIG2 (*(unsigned char*)0x286) /* TRIG2 */ +#define STRIG3 (*(unsigned char*)0x287) /* TRIG3 */ +#define PCOLR0 (*(unsigned char*)0x2C0) /* COLPM0 */ +#define PCOLR1 (*(unsigned char*)0x2C1) /* COLPM1 */ +#define PCOLR2 (*(unsigned char*)0x2C2) /* COLPM2 */ +#define PCOLR3 (*(unsigned char*)0x2C3) /* COLPM3 */ +#define COLOR0 (*(unsigned char*)0x2C4) /* COLPF0 */ +#define COLOR1 (*(unsigned char*)0x2C5) /* COLPF1 */ +#define COLOR2 (*(unsigned char*)0x2C6) /* COLPF2 */ +#define COLOR3 (*(unsigned char*)0x2C7) /* COLPF3 */ +#define COLOR4 (*(unsigned char*)0x2C8) /* COLPBK */ +#define GPRIOR (*(unsigned char*)0x264) /* PRIOR */ + +/* ANTIC */ +#define SDMCTL (*(unsigned char*)0x22F) /* DMACTL */ +#define CHACT (*(unsigned char*)0x2F3) /* CHACTL */ +#define SDLSTL (*(unsigned char*)0x230) /* DLISTL */ +#define SDLSTH (*(unsigned char*)0x231) /* DLISTH */ +#define SDLST (*(unsigned int*)0x230) /* DLISTL/H together */ +#define CHBAS (*(unsigned char*)0x2F4) /* CHBASE */ +#define LPENH (*(unsigned char*)0x233) /* PENH */ +#define LPENV (*(unsigned char*)0x234) /* PENV */ + +/* POKEY */ +#define PADDL0 (*(unsigned char*)0x270) /* POT0 */ +#define PADDL1 (*(unsigned char*)0x271) /* POT1 */ +#define PADDL2 (*(unsigned char*)0x272) /* POT2 */ +#define PADDL3 (*(unsigned char*)0x273) /* POT3 */ +#define PADDL4 (*(unsigned char*)0x274) /* POT4 */ +#define PADDL5 (*(unsigned char*)0x275) /* POT5 */ +#define PADDL6 (*(unsigned char*)0x276) /* POT6 */ +#define PADDL7 (*(unsigned char*)0x277) /* POT7 */ +#define CH (*(unsigned char*)0x2FC) /* KBCODE */ +#define POKMSK (*(unsigned char*)0x10) /* IRQEN */ + +/* PIA */ +#define STICK0 (*(unsigned char*)0x278) /* PORTA for controller port 1 */ +#define STICK1 (*(unsigned char*)0x279) /* PORTA for controller port 2 */ +#define STICK2 (*(unsigned char*)0x27A) /* PORTB for controller port 3 */ +#define STICK3 (*(unsigned char*)0x27B) /* PORTB for controller port 4 */ +#define PTRIG0 (*(unsigned char*)0x27C) /* PORTA for controller port 1, paddle 1 */ +#define PTRIG1 (*(unsigned char*)0x27D) /* PORTA for controller port 1, paddle 2 */ +#define PTRIG2 (*(unsigned char*)0x27E) /* PORTA for controller port 1, paddle 3 */ +#define PTRIG3 (*(unsigned char*)0x27F) /* PORTA for controller port 1, paddle 4 */ +#define PTRIG4 (*(unsigned char*)0x280) /* PORTA for controller port 2, paddle 5 */ +#define PTRIG5 (*(unsigned char*)0x281) /* PORTA for controller port 2, paddle 6 */ +#define PTRIG6 (*(unsigned char*)0x282) /* PORTA for controller port 2, paddle 7 */ +#define PTRIG7 (*(unsigned char*)0x283) /* PORTA for controller port 2, paddle 8 */ + + /*****************************************************************************/ /* Device control block */ /*****************************************************************************/ From af8eb57f63f8306ea3c575c6671c933482582fef Mon Sep 17 00:00:00 2001 From: Bill Kendrick <nbs@sonic.net> Date: Thu, 17 Jan 2019 22:44:25 -0800 Subject: [PATCH 0979/2161] Atari colors into _gtia.h; NMIRES/NMIST as union Use a C "union" to give both read (NMIST) and write (NMIRES) labels to their shared register in ANTIC. (h/t @groessler). Consolodate duplicated color definitions (HUE_..., COLOR_... and TGI_COLOR_...; and the "_gtia_mkcolor()" macro), found in both "atari.h" and "atari5200.h", moving it to "_gtia.h", which they both share (and which makes the most sense). --- include/_antic.h | 13 +++++--- include/_gtia.h | 73 +++++++++++++++++++++++++++++++++++++++++++-- include/atari.h | 71 ------------------------------------------- include/atari5200.h | 41 ------------------------- 4 files changed, 79 insertions(+), 119 deletions(-) diff --git a/include/_antic.h b/include/_antic.h index f9d880b0a..717f7f820 100644 --- a/include/_antic.h +++ b/include/_antic.h @@ -64,10 +64,15 @@ struct __antic { unsigned char penh; /* (R) light pen horizontal position */ unsigned char penv; /* (R) light pen vertical position */ unsigned char nmien; /* (W) non-maskable interrupt enable */ - unsigned char nmires; - /* (W) ("NMIRES") nmi reset -- clears the interrupt request register; resets all of the NMI status together - ** (R) ("NMIST") nmi status -- holds cause for the NMI interrupt - */ + union { + /* (W) ("NMIRES") nmi reset -- clears the interrupt request register; + ** resets all of the NMI status together + */ + unsigned char nmires; + + /* (R) ("NMIST") nmi status -- holds cause for the NMI interrupt */ + unsigned char nmist; + }; }; diff --git a/include/_gtia.h b/include/_gtia.h index 25181e875..ae3e69445 100644 --- a/include/_gtia.h +++ b/include/_gtia.h @@ -98,10 +98,77 @@ struct __gtia_write { #define PMG_SIZE_QUAD 0x2 /* four color clocks per pixel */ -/* COLPM0-COLPM3, COLPF0-COLPF3, COLBK color registers: -** See the "HUE_..." #defines in "atari.h" for the hue values; -** Bitwise OR (|) with 0x00 (darkest) through 0x0F (lightest) (only even values are unique) +/* COLPM0-COLPM3, COLPF0-COLPF3, COLBK color registers */ + +/*****************************************************************************/ +/* Color definitions */ +/*****************************************************************************/ + +/* Make a GTIA color value */ +#define _gtia_mkcolor(hue,lum) (((hue) << 4) | ((lum) << 1)) + +/* Luminance values go from 0 (black) to 7 (white) */ + +/* Hue values */ +/* (These can vary depending on TV standard (NTSC vs PAL), +** tint potentiometer settings, TV tint settings, emulator palette, etc.) */ +#define HUE_GREY 0 +#define HUE_GOLD 1 +#define HUE_GOLDORANGE 2 +#define HUE_REDORANGE 3 +#define HUE_ORANGE 4 +#define HUE_MAGENTA 5 +#define HUE_PURPLE 6 +#define HUE_BLUE 7 +#define HUE_BLUE2 8 +#define HUE_CYAN 9 +#define HUE_BLUEGREEN 10 +#define HUE_BLUEGREEN2 11 +#define HUE_GREEN 12 +#define HUE_YELLOWGREEN 13 +#define HUE_YELLOW 14 +#define HUE_YELLOWRED 15 + +/* Color defines, similar to c64 colors (untested) */ +/* Note that the conio color implementation is monochrome +** (bgcolor and textcolor are only placeholders) +*/ +/* Use the defines with the setcolor() or _atari_xxxcolor() functions */ +#define COLOR_BLACK _gtia_mkcolor(HUE_GREY,0) +#define COLOR_WHITE _gtia_mkcolor(HUE_GREY,7) +#define COLOR_RED _gtia_mkcolor(HUE_REDORANGE,1) +#define COLOR_CYAN _gtia_mkcolor(HUE_CYAN,3) +#define COLOR_VIOLET _gtia_mkcolor(HUE_PURPLE,4) +#define COLOR_GREEN _gtia_mkcolor(HUE_GREEN,2) +#define COLOR_BLUE _gtia_mkcolor(HUE_BLUE,2) +#define COLOR_YELLOW _gtia_mkcolor(HUE_YELLOW,7) +#define COLOR_ORANGE _gtia_mkcolor(HUE_ORANGE,5) +#define COLOR_BROWN _gtia_mkcolor(HUE_YELLOW,2) +#define COLOR_LIGHTRED _gtia_mkcolor(HUE_REDORANGE,6) +#define COLOR_GRAY1 _gtia_mkcolor(HUE_GREY,2) +#define COLOR_GRAY2 _gtia_mkcolor(HUE_GREY,3) +#define COLOR_LIGHTGREEN _gtia_mkcolor(HUE_GREEN,6) +#define COLOR_LIGHTBLUE _gtia_mkcolor(HUE_BLUE,6) +#define COLOR_GRAY3 _gtia_mkcolor(HUE_GREY,5) + +/* 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_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 /*****************************************************************************/ diff --git a/include/atari.h b/include/atari.h index ba2a43549..e06967ff9 100644 --- a/include/atari.h +++ b/include/atari.h @@ -91,77 +91,6 @@ #define CH_VLINE 0x7C -/*****************************************************************************/ -/* Color definitions */ -/*****************************************************************************/ - -/* Make a GTIA color value */ -#define _gtia_mkcolor(hue,lum) (((hue) << 4) | ((lum) << 1)) - -/* Luminance values go from 0 (black) to 7 (white) */ - -/* Hue values */ -/* (These can vary depending on TV standard (NTSC vs PAL), -** tint potentiometer settings, TV tint settings, emulator palette, etc.) -*/ -#define HUE_GREY 0 -#define HUE_GOLD 1 -#define HUE_GOLDORANGE 2 -#define HUE_REDORANGE 3 -#define HUE_ORANGE 4 -#define HUE_MAGENTA 5 -#define HUE_PURPLE 6 -#define HUE_BLUE 7 -#define HUE_BLUE2 8 -#define HUE_CYAN 9 -#define HUE_BLUEGREEN 10 -#define HUE_BLUEGREEN2 11 -#define HUE_GREEN 12 -#define HUE_YELLOWGREEN 13 -#define HUE_YELLOW 14 -#define HUE_YELLOWRED 15 - -/* Color defines, similar to c64 colors (untested) */ -/* Note that the conio color implementation is monochrome -** (bgcolor and textcolor are only placeholders) -*/ -/* Use the defines with the setcolor() or _atari_xxxcolor() functions */ -#define COLOR_BLACK _gtia_mkcolor(HUE_GREY,0) -#define COLOR_WHITE _gtia_mkcolor(HUE_GREY,7) -#define COLOR_RED _gtia_mkcolor(HUE_REDORANGE,1) -#define COLOR_CYAN _gtia_mkcolor(HUE_CYAN,3) -#define COLOR_VIOLET _gtia_mkcolor(HUE_PURPLE,4) -#define COLOR_GREEN _gtia_mkcolor(HUE_GREEN,2) -#define COLOR_BLUE _gtia_mkcolor(HUE_BLUE,2) -#define COLOR_YELLOW _gtia_mkcolor(HUE_YELLOW,7) -#define COLOR_ORANGE _gtia_mkcolor(HUE_ORANGE,5) -#define COLOR_BROWN _gtia_mkcolor(HUE_YELLOW,2) -#define COLOR_LIGHTRED _gtia_mkcolor(HUE_REDORANGE,6) -#define COLOR_GRAY1 _gtia_mkcolor(HUE_GREY,2) -#define COLOR_GRAY2 _gtia_mkcolor(HUE_GREY,3) -#define COLOR_LIGHTGREEN _gtia_mkcolor(HUE_GREEN,6) -#define COLOR_LIGHTBLUE _gtia_mkcolor(HUE_BLUE,6) -#define COLOR_GRAY3 _gtia_mkcolor(HUE_GREY,5) - -/* 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_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 */ /*****************************************************************************/ diff --git a/include/atari5200.h b/include/atari5200.h index 12c2bb349..67c11c1df 100644 --- a/include/atari5200.h +++ b/include/atari5200.h @@ -46,47 +46,6 @@ /* the addresses of the static drivers */ extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */ -/* make GTIA color value */ -#define _gtia_mkcolor(hue,lum) (((hue) << 4) | ((lum) << 1)) - -/* luminance values go from 0 (black) to 7 (white) */ - -/* hue values */ -#define HUE_GREY 0 -#define HUE_GOLD 1 -#define HUE_GOLDORANGE 2 -#define HUE_REDORANGE 3 -#define HUE_ORANGE 4 -#define HUE_MAGENTA 5 -#define HUE_PURPLE 6 -#define HUE_BLUE 7 -#define HUE_BLUE2 8 -#define HUE_CYAN 9 -#define HUE_BLUEGREEN 10 -#define HUE_BLUEGREEN2 11 -#define HUE_GREEN 12 -#define HUE_YELLOWGREEN 13 -#define HUE_YELLOW 14 -#define HUE_YELLOWRED 15 - -/* Color defines, similar to c64 colors (untested) */ -#define COLOR_BLACK _gtia_mkcolor(HUE_GREY,0) -#define COLOR_WHITE _gtia_mkcolor(HUE_GREY,7) -#define COLOR_RED _gtia_mkcolor(HUE_REDORANGE,1) -#define COLOR_CYAN _gtia_mkcolor(HUE_CYAN,3) -#define COLOR_VIOLET _gtia_mkcolor(HUE_PURPLE,4) -#define COLOR_GREEN _gtia_mkcolor(HUE_GREEN,2) -#define COLOR_BLUE _gtia_mkcolor(HUE_BLUE,2) -#define COLOR_YELLOW _gtia_mkcolor(HUE_YELLOW,7) -#define COLOR_ORANGE _gtia_mkcolor(HUE_ORANGE,5) -#define COLOR_BROWN _gtia_mkcolor(HUE_YELLOW,2) -#define COLOR_LIGHTRED _gtia_mkcolor(HUE_REDORANGE,6) -#define COLOR_GRAY1 _gtia_mkcolor(HUE_GREY,2) -#define COLOR_GRAY2 _gtia_mkcolor(HUE_GREY,3) -#define COLOR_LIGHTGREEN _gtia_mkcolor(HUE_GREEN,6) -#define COLOR_LIGHTBLUE _gtia_mkcolor(HUE_BLUE,6) -#define COLOR_GRAY3 _gtia_mkcolor(HUE_GREY,5) - /* Masks for joy_read */ #define JOY_UP_MASK 0x01 #define JOY_DOWN_MASK 0x02 From 9a83284b7b5236dcb113c28fbd0c1b6d2db1349f Mon Sep 17 00:00:00 2001 From: Bill Kendrick <nbs@sonic.net> Date: Thu, 17 Jan 2019 23:53:53 -0800 Subject: [PATCH 0980/2161] Cleaned up _pia.h register stuff a bit Most documentation say that most of the bits are normally set to 1 or 0, so just mentioning that in the comments. A.N.A.L.O.G. issue 59 (April 1988) "Bits & Pieces" column, "Atari Zucchini" (https://www.atarimagazines.com/analog/issue59/bits_pieces.php) implies that they are used for specific things, but it's not clear enough to be useful (or specifically states "Too complex and not pertinent"). This is probably sufficient for most purposes; if any PIA / PACTL/PBCTL experts pop up, they can tell us exactly how those 4 bits can be utilized. --- include/_pia.h | 58 +++++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/include/_pia.h b/include/_pia.h index 51426cc80..8c9fa01f1 100644 --- a/include/_pia.h +++ b/include/_pia.h @@ -4,14 +4,14 @@ /* */ /* Internal include file, do not use directly */ /* */ -/* The Peripheral Interface Adapter (PIA) chip provides parallel I/O */ -/* interfacing; it was used in Atari 400/800 and Commodore PET family of */ -/* computers, for joystick and interrupts. */ +/* The Peripheral Interface Adapter (PIA) chip (a 6520 or 6820) provides */ +/* parallel I/O interfacing; it was used in Atari 400/800 and Commodore PET */ +/* family of computers, for joystick and some interrupts. */ /* Sources; various + Wikpedia article on "Peripheral Interface Adapter". */ /* */ /* */ /* (C) 2000 Freddy Offenga <taf_offenga@yahoo.com> */ -/* 2019-01-16: Bill Kendrick <nbs@sonic.net>: Defines for registers */ +/* 2019-01-17: Bill Kendrick <nbs@sonic.net>: Defines for registers */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -121,41 +121,45 @@ struct __pia { /* PACTL and PBCTL register bits */ /*****************************************************************************/ -/* (W) Peripheral A interrupt (IRQ) enable. +/* (W) Peripheral PA1/PB1 interrupt (IRQ) ("peripheral proceed line available") enable. ** One equals enable. Set by the OS but available to the user; reset on powerup. +** (PxCTL_IRQ_STATUS (R) bit will get set upon interrupt occurance) */ -#define PxCTL_IRQ_ENABLE 0x01 +#define PxCTL_IRQ_ENABLE 0x01 /* bit 0 */ -/* "Set to zero" */ -#define PxCTL_BIT1 0x02 +/* Note: Bit 1 is always set to */ -/* (W) Controls PORTA addressing -** One equals PORTA register; zero equals direction control register +/* (W) Controls PORTA/PORTB addressing +** 1 = PORTA/PORTB register; read/write to controller port +** 0 = direction control register; write to direction controls +** (allows setting data flow; write 0s & 1s to PORTA/PORTB bits +** to set which port's pins are read (input), or write (output), +** respectively) */ -#define PxCTL_ADDRESSING 0x04 +#define PxCTL_ADDRESSING 0x04 /* bit 2 */ -#define PxCTL_BIT4 0x10 /* "Set to one" */ -#define PxCTL_BIT5 0x20 /* "Set to one" */ -#define PxCTL_BIT6 0x40 /* "Set to zero" */ - -/* Peripheral interrupt (IRQ) status bit. -** Set by Peripherals (PORTA / PORTB). Reset by reading PORTA / PORTB. +/* (W) Peripheral motor control line; Turn the cassette on or off +** (PACTL-specific register bit) +** 0 = on +** 1 = off */ -#define PxCTL_IRQ_STATUS 0x80 +#define PACTL_MOTOR_CONTROL 0x08 /* bit 3 */ - -/* PACTL-specific register bit */ - -/* (W) Peripheral motor control line -** Turn the cassette on or off; zero equals on) +/* Peripheral command identification (serial bus command line) +** (PBCTL-specific register bit) */ -#define PACTL_MOTOR_CONTROL 0x08 +#define PBCTL_PERIPH_CMD_IDENT 0x08 /* bit 3 */ +/* Note: Bits 4 & 5 are always set to 1 */ -/* PBCTL-specific register bit */ +/* Note: Bit 6 is always set to 0 */ -/* Peripheral command identification (serial bus command) */ -#define PBCTL_PERIPH_CMD_IDENT 0x08 +/* (R) Peripheral interrupt (IRQ) status bit. +** Set by Peripherals (PORTA / PORTB). Reset by reading from PORTA / PORTB. +** PACTL's is interrupt status of PROCEED +** PBCTL's is interrupt status of SIO +*/ +#define PxCTL_IRQ_STATUS 0x80 /* End of _pia.h */ From 1781a5cfe72c8de4fff66adbd08650014ef526c4 Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Wed, 23 Jan 2019 00:05:31 +0100 Subject: [PATCH 0981/2161] Optimize the conversions from Atari ASCII to screen codes. --- libsrc/atari/cputc.s | 22 ++++----- libsrc/atari/tgi/atari_tgi_common.inc | 65 ++++++++++++--------------- 2 files changed, 37 insertions(+), 50 deletions(-) diff --git a/libsrc/atari/cputc.s b/libsrc/atari/cputc.s index a06daa691..6345983fe 100644 --- a/libsrc/atari/cputc.s +++ b/libsrc/atari/cputc.s @@ -1,5 +1,5 @@ ; -; Mark Keates, Christian Groessler +; Mark Keates, Christian Groessler, Piotr Fusik ; ; void cputcxy (unsigned char x, unsigned char y, char c); ; void cputc (char c); @@ -30,16 +30,13 @@ L4: cmp #$0A ; LF cmp #ATEOL ; Atari-EOL? beq newline - tay - rol a - rol a - rol a - rol a - and #3 - tax - tya - and #$9f - ora ataint,x + asl a + adc #$c0 + bpl intok + eor #$40 +intok: lsr + bcc cputdirect + eor #$80 cputdirect: ; accepts screen code jsr putchar @@ -89,6 +86,3 @@ putchar: ldy COLCRS sta (ptr4),y jmp setcursor - - .rodata -ataint: .byte 64,0,32,96 diff --git a/libsrc/atari/tgi/atari_tgi_common.inc b/libsrc/atari/tgi/atari_tgi_common.inc index cd486d91b..8c9f6c1f9 100644 --- a/libsrc/atari/tgi/atari_tgi_common.inc +++ b/libsrc/atari/tgi/atari_tgi_common.inc @@ -1110,11 +1110,8 @@ skipm: ; Loop while --dy > 0 ; locals string := tmp1 - cols := tmp3 pixels := tmp4 font := regsave -.rodata - ataint: .byte 64,0,32,96 .bss rows: .res 1 @@ -1222,32 +1219,31 @@ scvert: ldx x1 .endif ; Draw one character - ; Convert to ANTIC code -draw: tay - rol a - rol a - rol a - rol a - and #3 - tax - tya - and #$9f - ora ataint,x - ; Save and clear inverse video bit - sta inv - and #$7F +draw: + ; Extract the inverse mask + ldx #0 + asl a + bcc noinv + dex +noinv: stx inv + ; Calculate font data address + ldx CHBAS + cmp #$20*2 + bpl lowhalf + ; Semigraphic or lowercase + inx + inx +lowhalf: + asl a + bcc lowquarter + ; Letter + inx +lowquarter: + asl a sta font - lda #0 - sta font + 1 + stx font+1 - .repeat 3 - asl font - rol a - .endrepeat - - adc CHBAS - sta font + 1 ; Save old coords bit text_dir bpl hor @@ -1273,15 +1269,12 @@ cont: ldy #7 ; Put one row of the glyph putrow: sty rows lda (font),y - bit inv - bpl noinv - eor #$FF -noinv: sta pixels - lda #7 - sta cols + eor inv + sec + rol a + sta pixels ; Put one column of the row -putcol: asl pixels - bcc next_col +putcol: bcc next_col lda x1 pha lda x1 + 1 @@ -1317,8 +1310,8 @@ vertinc: sub mag_x sta y2 L2: - dec cols - bpl putcol + asl pixels + bne putcol next_row: ; Go to next row bit text_dir From 7a034f505bd2690e4a05a166746e8be1cdfecfb7 Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Wed, 23 Jan 2019 19:02:26 +0100 Subject: [PATCH 0982/2161] Comment the ATASCII to screen code conversion. --- libsrc/atari/cputc.s | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libsrc/atari/cputc.s b/libsrc/atari/cputc.s index 6345983fe..7132fdca6 100644 --- a/libsrc/atari/cputc.s +++ b/libsrc/atari/cputc.s @@ -30,13 +30,13 @@ L4: cmp #$0A ; LF cmp #ATEOL ; Atari-EOL? beq newline - asl a - adc #$c0 - bpl intok - eor #$40 -intok: lsr + asl a ; shift out the inverse bit + adc #$c0 ; grab the inverse bit; convert ATASCII to screen code + bpl codeok ; screen code ok? + eor #$40 ; needs correction +codeok: lsr a ; undo the shift bcc cputdirect - eor #$80 + eor #$80 ; restore the inverse bit cputdirect: ; accepts screen code jsr putchar From 2848ddf8ab0243ba3469e92ea11ede0d9b8459d7 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Thu, 24 Jan 2019 23:07:49 +0100 Subject: [PATCH 0983/2161] Telemon variables added --- asminc/telestrat.inc | 101 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 3 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 956f4b8ac..9d7949920 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -54,9 +54,18 @@ IRQSVY := $23 ; Used to save Y when a BRK call occurs IRQSVP := $24 ; Used to save P when a BRK call occurs ADSCR := $26 +SCRNB := $28 ; id of the current window + +ADKBD := $2A ; Address ASCII conversion table + PTR_READ_DEST := $2C ; Used for XFREAD and XWRITE only in TELEMON 3.x +ADCLK := $40 ; Address for clock display +TIMEUS := $42 +TIMEUD := $44 + + HRSX := $46 HRSY := $47 @@ -64,6 +73,7 @@ XLPRBI := $48 ; Printer flag (b7) HRSX40 := $49 HRSX6 := $4A +ADHRS := $4B ; hires screen address (word) HRS1 := $4D HRS2 := $4F HRS3 := $51 @@ -72,6 +82,8 @@ HRS5 := $55 HRSFB := $57 +VABKP1 := $58 + ; RS232T ; b0-b3 : speed ; 1111 => 19200 bps (please note that telestrat can't handle this speed without stopping all IRQ except ACIA's one) @@ -103,6 +115,18 @@ RS232T := $59 ; : 11 SPACE SENT, reception not tested RS232C := $5A +INDRS := $5B + +ACC1E := $60 +ACC1M := $61 + +ACC1S := $65 + +FLGMEN := $68 +ADMEN := $69 + +FLSVS := $89 +FLERR := $8B VARLNG := $8C VARAPL := $D0 @@ -200,10 +224,13 @@ XFILLM = $1C XMINMA = $1F XVARS = $24 ; Only in TELEMON 3.x, in TELEMON 2.4, it's XNOMFI ($24) XCRLF = $25 ; Jump a line and return to the beginning of the line +XDECAY = $26 XFREAD = $27 ; Only in TELEMON 3.x (bank 7 of Orix) XBINDX = $28 ; Convert a number into hex and displays on channel 0 XDECIM = $29 XHEXA = $2A ; Convert a number into hex +XEDT = $2D ; Launch editor +XINSER = $2E XSCELG = $2F ; Search a line in editor mode XOPEN = $30 ; Only in TELEMON 3.x (bank 7 of Orix) XECRPR = $33 ; Displays prompt @@ -213,7 +240,12 @@ XSCRSE = $36 XSCRNE = $39 ; Load charset from rom to ram XCLOSE = $3A ; Only in TELEMON 3.x close file (bank 7 of Orix) XFWRITE = $3B ; Only in TELEMON 3.x write file (bank 7 of Orix) -XWRCLK = $3E ; Update clock + +; Clock primitive +XRECLK = $3C ; Reset clock +XCLCL = $3D ; Close clock +XWRCLK = $3E ; Displays clock in the adress in A & Y registers + XSONPS = $40 ; Send data to PSG register (14 values) XOUPS = $42 ; Send Oups sound into PSG XPLAY = $43 ; Play a sound @@ -223,7 +255,17 @@ XZAP = $46 ; Send Zap sound to PSG XSHOOT = $47 XMKDIR = $4B ; Create a folder. Only available in TELEMON 3.x (bank 7 of Orix) XRM = $4D ; Remove a folder or a file. Only available in TELEMON 3.x (bank 7 of Orix) -XGOKBD = $52 +XGOKBD = $52 + +; Buffer management +XECRBU = $54 ; Write A or AY in the buffer +XLISBU = $55 ; Read A or AY in the buffer +XTSTBU = $56 +XVIDBU = $57 ; Flush the buffer +XINIBU = $58 ; Initialize the buffer X +XDEFBU = $59 ; Reset all value of the buffer +XBUSY = $5A ; Test if the buffer is empty + XMALLOC = $5B ; Only in TELEMON 3.x (bank 7 of Orix) XFREE = $62 ; Only in TELEMON 3.x (bank 7 of Orix) XSOUT = $67 ; Send accumulator value (A) to RS232, available in TELEMON 2.4 & 3.x : if RS232 buffer is full, the Oric Telestrat freezes @@ -257,28 +299,78 @@ BUFTRV := $100 ; Page $200 BNKST := $200 ; Used to store signature of 8 bank (length : 8 bytes) TABDRV := $208 +DRVDEF := $20C FLGTEL := $20D KOROM := $20E ; Used to compute the size of all rom bank. The result is store here. The value is in KB KORAM := $20F ; Used to compute the size of all ram bank. The result is store here. The value is in KB +; Time management TIMED := $210 TIMES := $211 TIMEM := $212 +TIMEH := $213 +FLGCLK := $214 +FLGCLK_FLAG := $215 +FLGCUR := $216 ; cursor management flag +; screens position managements + +FLGCUR_STATE := $217 ; cursor state flag ADSCRL := $218 ADSCRH := $21C SCRX := $220 SCRY := $224 +SCRDX := $228 +SCRFX := $22C +SCRDY := $230 +SCRFY := $234 +SCRBAL := $238 +SCRBAH := $23C +SCRCT := $240 +SCRCF := $244 +FLGSCR := $248 +CURSCR := $24C + +HARD_COPY_HIRES := $250 ; Hard copy vector + +SCRTXT := $256 +SCRHIR := $25C +SCRTRA := $262 ; 6 bytes lenfth + + +; Keyboard management +KBDCOL := $268 ; 8 bytes length +KBDFLG_KEY := $270 ; 0 if no key pressed +KBDVRR := $272 KBDVRL := $273 FLGKBD := $275 KBDFCT := $276 KBDSHT := $278 +KBDKEY := $279 KBDCTC := $27E +LPRX := $286 +LPRY := $287 LPRFX := $288 LPRFY := $289 +FLGLPR := $28A + +; Joysticks management +FLGJCK := $28C +JCGVAL := $28D +JCDVAL := $28E +JCKTAB := $29D + + HRSPAT := $2AA ; Hires pattern : it's used to draw pattern for a line or a circle -ADIOB := $2BE +HRSERR := $2AB + +IOTAB0 := $2AE +IOTAB1 := $2B2 +IOTAB2 := $2B6 +IOTAB3 := $2BA +ADIOB := $2BE ; 48 bytes length FLGRST := $2EE CSRND := $2EF VNMI := $2F4 +ADIODB_VECTOR := $2f7 ; 3 bytes length IRQVECTOR := $2FA VAPLIC := $2FD @@ -311,6 +403,9 @@ MAX_BUFEDT_LENGTH=110 CH376_DATA := $340 CH376_COMMAND := $341 +; RAM overlays buffer +BUFBUF := $c080 + ; --------------------------------------------------------------------------- ; Stratsed vectors ; Stratsed is the main OS for Telestrat From b360a128f9d53aeb9a4dc5e21f0524dad70b9308 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 26 Jan 2019 11:39:24 +0100 Subject: [PATCH 0984/2161] fix uppercase command --- asminc/telestrat.inc | 53 -------------------------------------------- 1 file changed, 53 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index c4dc509a3..14e686d19 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -468,59 +468,6 @@ XPBUF1 := $FFA4 XPMAP := $FFA7 XRWTS := $FFAA -; --------------------------------------------------------------------------- -; Stratsed vectors -; Stratsed is the main OS for Telestrat -XMERGE := $FF0E -XFST := $FF11 -XSPUT := $FF14 -XSTAKE := $FF17 -XTAKE := $FF20 -XOPENS := $FF1A ; XOPEN from Stratsed -XCLOSES := $FF1D ; XCLOSE from Stratsed -XPUT := $FF23 -XREWIN := $FF29 -XJUMP := $FF2C -XLGBUF := $FF2F -XERVEC := $FF32 -XESAVE := $FF35 -XCOPY := $FF38 -XDNAME := $FF3B -XSTATU := $FF3E -XUPDAT := $FF41 -XFORMA := $FF44 -XDELBK := $FF4A -XDELN := $FF4D -XPROT := $FF50 -XUNPRO := $FF53 -XDIRN := $FF56 -XBKP := $FF59 -XINITI := $FF5C -XERREU := $FF5F -XLOAD := $FF62 -XDEFSA := $FF65 -XDEFLO := $FF68 -XSAVE := $FF6B -XNOMDE := $FF6E -XCREAY := $FF71 -XDETSE := $FF74 -XLIBSE := $FF77 -XTRVCA := $FF7A -XTRVNM := $FF7D -XTRVNX := $FF80 -XBUCA := $FF86 -XVBUF1 := $FF89 -XSVSEC := $FF8C -XSAY := $FF8F -XSBUF1 := $FF92 -XSBUF2 := $FF95 -XSBUF3 := $FF98 -XSCAT := $FF9B -XPRSEC := $FFA1 -XPBUF1 := $FFA4 -XPMAP := $FFA7 -XRWTS := $FFAA - ; --------------------------------------------------------------------------- ; MACRO From dfa91106fd95031d48d91e06cab6208b028f106c Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 26 Jan 2019 12:00:13 +0100 Subject: [PATCH 0985/2161] fix doc/telestrat.sgml --- doc/telestrat.sgml | 44 +++++++++++--------------------------------- 1 file changed, 11 insertions(+), 33 deletions(-) diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index 1c0b3d954..8dddd3061 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -27,7 +27,7 @@ more than one platform. Please see the function reference for more information. Oric Telestrat is the last Oric computer (Released in 1986, mainly in France). -This computer is an Atmos with extra hardware : RS232, cardridge (banking system), +This computer is an Atmos with extra hardware: RS232, cardridge(banking system), joysticks (2 ports) or mouse (on joystick port), FDC. Video chip, CPU, keyboard management, tape hardware are the same than Atmos. @@ -49,14 +49,14 @@ There is also no software to write a Stratsed dsk file on PC. This Telestrat target build an Orix binary file. But, in the future, it will be possible to build a Stratsed disk. Orix uses the same systems calls than Telemon mode. -That is why if you need to do software for telestrat target, you have the choice to : +That is why if you need to do software for telestrat target,you have the choice to: <itemize> -<item>use cc65 Atmos target and start Telestrat in Atmos mode : a tape file is required -<item>use cc65 Atmos target and start Telestrat in Stratoric mode : a dsk file or tape file is required +<item>use cc65 Atmos target and start Telestrat in Atmos mode: A tape file is required. +<item>use cc65 Atmos target and start Telestrat in Stratoric mode: A dsk file or tape file is required. <item>use cc65 Telestrat target and start Telestrat in Orix mode (see <url -name="here" url="http://orix.oric.org/download/">) -<item>use cc65 Telestrat target, remove Orix header from binary, code a dsk tool for Stratsed, -add Stratsed header on your binary, insert your binary on floppy disk (this solution will be possible is the future) +name="here" url="http://orix.oric.org/download/">). +<item>use cc65 Telestrat target, remove Orix header from binary, code a dsk tool for Stratsed, +add Stratsed header on your binary,insert your binary on floppy disk (this solution will be possible is the future). </itemize> Telestrat (from cardridge) can handle 8 banks (from $C000 to $FFFF): Bank 0 is the overlay ram. Others banks can be ROM or RAM. @@ -148,21 +148,13 @@ structures; accessing the struct fields will access the chip registers. Access to the VIA (Versatile Interface Adapter) chip is available via the <tt/VIA/ variable. The structure behind this variable is explained in <tt/_6522.h/. -</descrip><p> - -<descrip> - <tag><tt/VIA2/</tag> Access to the VIA2 (Versatile Interface Adapter) chip is available via the <tt/VIA2/ variable. The structure behind this variable is explained in <tt/_6522.h/. -</descrip><p> - -<descrip> - - <tag><tt/6551/</tag> + <tag><tt/ACIA/</tag> Access to the 6551 ACIA chip is available via the - <tt/6551/ variable. The structure behind this variable is explained in <tt/_6551.h/. + <tt/ACIA/ variable. The structure behind this variable is explained in <tt/_6551.h/. </descrip><p> @@ -171,7 +163,7 @@ structures; accessing the struct fields will access the chip registers. <sect1>TGI<p> -TGI drivers is available on Oric Telestrat with some functions : +TGI drivers is available on Oric Telestrat with some functions: <itemize> <item>tgi_clear @@ -192,34 +184,22 @@ port cardridge. <sect1>Joystick drivers<p> - -<descrip> - Telemon 2.4 & 3.0 manages joysticks but it had been handled yet. This means that joysticks driver could be written easily. Telemon 2.4 returns in keyboard buffer the direction of the joysticks. This means that if you get input from keyboard by conio cgetc function, you will get direction from joysticks. - <sect1>Mouse drivers<p> - -<descrip> - Telestrat manages also mouse, but it had been no handled yet in this version. Telestrat mouse is really difficult to find. - <sect1>RS232 device drivers<p> - -<descrip> - Telestrat has a RS232 port, but it's not usable in cc65. It is possible to use RS232 port with Telemon calls (see XSOUT primitive for example) - <sect>Limitations<label id="limitations"><p> <sect1>Disk I/O<p> @@ -227,9 +207,7 @@ RS232 port with Telemon calls (see XSOUT primitive for example) Telemon 3.0 handles fopen, fread, fclose primitives. It means that this function will crash the Telestrat because Telemon 2.4 does not have these primitives. By the way, Telemon 3.0 uses an extension "ch376 card" which -handles sdcard and FAT 32 usb key. In the next version of Telemon, FT DOS, -Sedoric, Stratsed will be handled in these 3 primitives (fopen, fread, -fclose). +handles sdcard and FAT 32 usb key. In the next version of Telemon, FT DOS, Sedoric, Stratsed will be handled in these 3 primitives (fopen, fread, fclose). <itemize> <item>fclose From a3d876b737a5f74c47505f6f92909b5a39ccef28 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 26 Jan 2019 12:01:48 +0100 Subject: [PATCH 0986/2161] fix comma in telestrat.sgml --- doc/telestrat.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index 8dddd3061..4b08e8365 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -49,7 +49,7 @@ There is also no software to write a Stratsed dsk file on PC. This Telestrat target build an Orix binary file. But, in the future, it will be possible to build a Stratsed disk. Orix uses the same systems calls than Telemon mode. -That is why if you need to do software for telestrat target,you have the choice to: +That is why if you need to do software for telestrat target, you have the choice to: <itemize> <item>use cc65 Atmos target and start Telestrat in Atmos mode: A tape file is required. <item>use cc65 Atmos target and start Telestrat in Stratoric mode: A dsk file or tape file is required. From bade791570c8fc8f241dec3dfb278d545209091e Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Tue, 29 Jan 2019 20:46:16 +0100 Subject: [PATCH 0987/2161] fix uppercase --- asminc/telestrat.inc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 14e686d19..8d2e9afc1 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -54,7 +54,7 @@ IRQSVY := $23 ; Used to save Y when a BRK call occurs IRQSVP := $24 ; Used to save P when a BRK call occurs ADSCR := $26 -SCRNB := $28 ; id of the current window +SCRNB := $28 ; Id of the current window ADKBD := $2A ; Address ASCII conversion table @@ -74,7 +74,7 @@ XLPRBI := $48 ; Printer flag (b7) HRSX40 := $49 HRSX6 := $4A -ADHRS := $4B ; hires screen address (word) +ADHRS := $4B ; Hires screen address (word) HRS1 := $4D HRS2 := $4F @@ -315,10 +315,10 @@ TIMEM := $212 TIMEH := $213 FLGCLK := $214 FLGCLK_FLAG := $215 -FLGCUR := $216 ; cursor management flag +FLGCUR := $216 ; Cursor management flag ; screens position managements -FLGCUR_STATE := $217 ; cursor state flag +FLGCUR_STATE := $217 ; Cursor state flag ADSCRL := $218 ADSCRH := $21C From 055c294ac01f7cff8dcb2223ef0b7e113918b381 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 29 Jan 2019 22:00:55 +0100 Subject: [PATCH 0988/2161] Use Timer2 for mouse polling. This follows a suggestion by Sijmen Schouten in issue #818. Platoterm64 now works with mouse at 1200 baud. Bump MOUSE_API_VERSION in asminc/mouse-kernel.inc. Fix typo in testcode/lib/mouse-test.c. --- asminc/mouse-kernel.inc | 2 +- libsrc/atari/mou/atrst.s | 74 +++++++++++++------------- libsrc/atari/mouseref.s | 4 +- libsrc/atari/shadow_ram_timerirq2.s | 81 +++++++++++++++++++++++++++++ testcode/lib/mouse-test.c | 2 +- 5 files changed, 122 insertions(+), 41 deletions(-) create mode 100644 libsrc/atari/shadow_ram_timerirq2.s diff --git a/asminc/mouse-kernel.inc b/asminc/mouse-kernel.inc index 3eebca244..ab4790d1d 100644 --- a/asminc/mouse-kernel.inc +++ b/asminc/mouse-kernel.inc @@ -103,7 +103,7 @@ ;------------------------------------------------------------------------------ ; The mouse API version, stored in MOUSE_HDR::VERSION -MOUSE_API_VERSION = $05 +MOUSE_API_VERSION = $06 ;------------------------------------------------------------------------------ ; Bitmapped mouse driver flags, stored in MOUSE_HDR::FLAGS. diff --git a/libsrc/atari/mou/atrst.s b/libsrc/atari/mou/atrst.s index f8ba24551..5d8a5cd12 100644 --- a/libsrc/atari/mou/atrst.s +++ b/libsrc/atari/mou/atrst.s @@ -134,6 +134,7 @@ YPosWrk: .res 2 irq_enabled: .res 1 ; flag indicating that the high frequency polling interrupt is enabled old_porta_vbi: .res 1 ; previous PORTA value of the VBI interrupt (IRQ) how_long: .res 1 ; counter for how many VBI interrupts the mouse hasn't been moved +in_irq: .res 1 ; flag indicating high-frequency polling interrupt is active .if .defined (AMIGA_MOUSE) .or .defined (ST_MOUSE) dumx: .res 1 @@ -145,11 +146,11 @@ oldval: .res 1 .endif .ifndef __ATARIXL__ -OldT1: .res 2 +OldT2: .res 2 .else .data -set_VTIMR1_handler: +set_VTIMR2_handler: .byte $4C, 0, 0 .endif @@ -226,29 +227,29 @@ INSTALL: ; Setup pointer to wrapper install/deinstall function. lda libref - sta set_VTIMR1_handler+1 + sta set_VTIMR2_handler+1 lda libref+1 - sta set_VTIMR1_handler+2 + sta set_VTIMR2_handler+2 ; Install my handler. sec - lda #<T1Han - ldx #>T1Han - jsr set_VTIMR1_handler + lda #<T2Han + ldx #>T2Han + jsr set_VTIMR2_handler .else - lda VTIMR1 - sta OldT1 - lda VTIMR1+1 - sta OldT1+1 + lda VTIMR2 + sta OldT2 + lda VTIMR2+1 + sta OldT2+1 php sei - lda #<T1Han - sta VTIMR1 - lda #>T1Han - sta VTIMR1+1 + lda #<T2Han + sta VTIMR2 + lda #>T2Han + sta VTIMR2+1 plp .endif @@ -257,20 +258,12 @@ INSTALL: sta AUDCTL lda #0 - sta AUDC1 + sta AUDC2 lda #15 - sta AUDF1 + sta AUDF2 sta STIMER -.if 0 ; the IRQ will now be dynamically enabled when the mouse is moved - lda POKMSK - ora #%00000001 ; timer 1 enable - sta POKMSK - sta IRQEN - sta irq_enabled -.endif - lda PORTA and #$0f sta old_porta_vbi @@ -290,23 +283,23 @@ UNINSTALL: ; uninstall timer irq routine lda POKMSK - and #%11111110 ; timer 1 disable + and #%11111101 ; timer 2 disable sta IRQEN sta POKMSK .ifdef __ATARIXL__ clc - jsr set_VTIMR1_handler + jsr set_VTIMR2_handler .else php sei - lda OldT1 - sta VTIMR1 - lda OldT1+1 - sta VTIMR1+1 + lda OldT2 + sta VTIMR2 + lda OldT2+1 + sta VTIMR2+1 plp .endif @@ -503,7 +496,7 @@ IRQ: lda PORTA ; mouse port contents ; Turn mouse polling IRQ back on lda POKMSK - ora #%00000001 ; timer 1 enable + ora #%00000010 ; timer 2 enable sta POKMSK sta IRQEN sta irq_enabled @@ -533,7 +526,7 @@ IRQ: lda PORTA ; mouse port contents sta irq_enabled lda POKMSK - and #%11111110 ; timer 1 disable + and #%11111101 ; timer 2 disable sta IRQEN sta POKMSK @@ -620,13 +613,18 @@ IRQ: lda PORTA ; mouse port contents ;---------------------------------------------------------------------------- -; T1Han: Local IRQ routine to poll mouse +; T2Han: Local IRQ routine to poll mouse ; -T1Han: lda CRITIC ; if CRITIC flag is set, disable the +T2Han: lda CRITIC ; if CRITIC flag is set, disable the bne disable_me ; high frequency polling IRQ, in order ; not to interfere with SIO I/O (e.g. - ; floppy access) + ; floppy access or serial I/O) + + lda in_irq ; handler entered again? + bne skip ; yes, ignore this interrupt + inc in_irq + cli ; enable IRQs so that we don't block them for too long tya pha @@ -803,6 +801,8 @@ mmexit: sty oldval tax pla tay + dec in_irq +skip: .ifdef __ATARIXL__ rts .else @@ -819,7 +819,7 @@ mmexit: sty oldval disable_me: lda POKMSK - and #%11111110 ; timer 1 disable + and #%11111101 ; timer 2 disable sta IRQEN sta POKMSK lda #0 diff --git a/libsrc/atari/mouseref.s b/libsrc/atari/mouseref.s index b75df93d1..ac99d36fa 100644 --- a/libsrc/atari/mouseref.s +++ b/libsrc/atari/mouseref.s @@ -5,8 +5,8 @@ .export mouse_libref .ifdef __ATARIXL__ - .import set_VTIMR1_handler -mouse_libref := set_VTIMR1_handler + .import set_VTIMR2_handler +mouse_libref := set_VTIMR2_handler .else .import _exit mouse_libref := _exit diff --git a/libsrc/atari/shadow_ram_timerirq2.s b/libsrc/atari/shadow_ram_timerirq2.s new file mode 100644 index 000000000..b2cdaecd2 --- /dev/null +++ b/libsrc/atari/shadow_ram_timerirq2.s @@ -0,0 +1,81 @@ +; +; Atari XL shadow RAM timer IRQ #2 handler +; +; Christian Groessler, chris@groessler.org, 2019 +; + +;DEBUG = 1 + +.ifdef __ATARIXL__ + +SHRAM_HANDLERS = 1 + .include "atari.inc" + .include "romswitch.inc" + .export set_VTIMR2_handler + + +.segment "LOWBSS" + +VTIMR2_handler: .res 3 + + +.segment "BSS" + +old_VTIMR2_handler: + .res 2 + + +.segment "LOWCODE" + +; timer interrupt handler: +; disable ROM, call user handler, enable ROM again + +my_VTIMR2_handler: + disable_rom_quick + jsr VTIMR2_handler + enable_rom_quick + pla + rti + +.segment "CODE" + +; install or remove VTIMR2 handler +; input: CF - 0/1 for remove/install handler +; AX - pointer to handler (if CF=1) +; registers destroyed + +set_VTIMR2_handler: + + bcc @remove + +; install vector + + stx VTIMR2_handler+2 + sta VTIMR2_handler+1 ; save passed vector in low memory + lda #$4C ; "JMP" opcode + sta VTIMR2_handler + + lda VTIMR2 + sta old_VTIMR2_handler + lda VTIMR2+1 + sta old_VTIMR2_handler+1 + + lda #<my_VTIMR2_handler + php + sei + sta VTIMR2 + lda #>my_VTIMR2_handler + sta VTIMR2+1 + plp + rts + +@remove: php + sei + lda old_VTIMR2_handler + sta VTIMR2 + lda old_VTIMR2_handler+1 + sta VTIMR2+1 + plp + rts + +.endif ; .ifdef __ATARIXL__ diff --git a/testcode/lib/mouse-test.c b/testcode/lib/mouse-test.c index 2e316c4c6..ea8311d19 100644 --- a/testcode/lib/mouse-test.c +++ b/testcode/lib/mouse-test.c @@ -7,7 +7,7 @@ ** ** Compile with "-DSTATIC_MOUSE" to statically link all available drivers. ** Compile with "-DMOUSE_DRIVER=<driver_sym>" to statically link the given driver. -** E.g., -DMOUSE_DRIVER=atrsts_mou to just link with the Atari ST mouse driver. +** E.g., -DMOUSE_DRIVER=atrst_mou to just link with the Atari ST mouse driver. */ From 620359fa2ee8d52a66ca348b21aa774a3c03d38e Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Wed, 30 Jan 2019 13:28:50 +0100 Subject: [PATCH 0989/2161] add more clearly what rom stratoric contains --- doc/telestrat.sgml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index 4b08e8365..6ae9cf941 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -36,7 +36,12 @@ Telestrat can start in Atmos mode with Atmos Cardridge (which is only the atmos Basic 1.1 ROM). Telestrat can start in Sedoric (Atmos OS) and Atmos mode with Stratoric Cardridge. -This Cardridge is a Sedoric ROM, Basic 1.1 ROM (Atmos), Basic 1.0 ROM (Oric-1). +This Cardridge has 3 banks of 16KB of rom with : +<itemize> +<item>a Sedoric ROM. +<item>a Basic 1.1 ROM (Atmos). +<item>a Basic 1.0 ROM (Oric-1). +</itemize> The main Telestrat's configuration is the Telemon/Hyperbasic Cardridge inserted with Stratsed in floppy drive. From c37582bb00465f7f17cf029543b024ab6a6c7870 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 30 Jan 2019 12:18:32 -0500 Subject: [PATCH 0990/2161] Fixed a note in "ca65.sgml". String escapes are converted to a target platform's encoding. --- doc/ca65.sgml | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index e0566fda4..25c46c4c2 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -2835,19 +2835,18 @@ Here's a list of all control commands and a description, what they do: Allow C-style backslash escapes within string constants to embed special characters. The following escapes are accepted: + <itemize> + <item><tt>\\</tt> backslash (<tt>$5C</tt>) + <item><tt>\'</tt> single quote (<tt>$27</tt>) + <item><tt>\"</tt> double quote (<tt>$22</tt>) + <item><tt>\t</tt> tab (<tt>$09</tt>) + <item><tt>\r</tt> carriage return (<tt>$0D</tt>) + <item><tt>\n</tt> newline (<tt>$0A</tt>) + <item><tt>\xNN</tt> (<tt>$NN</tt>) + </itemize> -<itemize> -<item><tt>\\</tt> backslash (<tt>$5C</tt>) -<item><tt>\'</tt> single quote (<tt>$27</tt>) -<item><tt>\"</tt> double quote (<tt>$22</tt>) -<item><tt>\t</tt> tab (<tt>$09</tt>) -<item><tt>\r</tt> carriage return (<tt>$0D</tt>) -<item><tt>\n</tt> newline (<tt>$0A</tt>) -<item><tt>\xNN</tt> (<tt>$NN</tt>) -</itemize> - - Note that <tt>\n</tt> maps to ASCII <tt>$0A</tt>, not a platform specific - line ending character. + Note that string escapes are converted to platform-specific characters in + the same way that other characters are converted. <tag><tt>ubiquitous_idents</tt><label id="ubiquitous_idents"></tag> From 0e947d594f43bfba4165b80ddef1a47e22d1afa3 Mon Sep 17 00:00:00 2001 From: Daniel Serpell <daniel.serpell@gmail.com> Date: Mon, 24 Sep 2018 23:58:06 -0300 Subject: [PATCH 0991/2161] Add support for Atari XEX file format to LD65 --- src/common/target.h | 1 + src/ld65.vcxproj | 4 +- src/ld65/binfmt.c | 1 + src/ld65/config.c | 13 ++ src/ld65/scanner.h | 1 + src/ld65/xex.c | 344 ++++++++++++++++++++++++++++++++++++++++++++ src/ld65/xex.h | 72 ++++++++++ 7 files changed, 435 insertions(+), 1 deletion(-) create mode 100644 src/ld65/xex.c create mode 100644 src/ld65/xex.h diff --git a/src/common/target.h b/src/common/target.h index c8e2472d3..5b086e40c 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -103,6 +103,7 @@ extern target_t Target; #define BINFMT_DEFAULT 0 /* Default (binary) */ #define BINFMT_BINARY 1 /* Straight binary format */ #define BINFMT_O65 2 /* Andre Fachats o65 format */ +#define BINFMT_ATARIEXE 3 /* Standard Atari binary load */ diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index f98da6119..a78f3128b 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -106,6 +106,7 @@ <ClInclude Include="ld65\span.h" /> <ClInclude Include="ld65\spool.h" /> <ClInclude Include="ld65\tpool.h" /> + <ClInclude Include="ld65\xex.h" /> </ItemGroup> <ItemGroup> <ClCompile Include="ld65\asserts.c" /> @@ -139,8 +140,9 @@ <ClCompile Include="ld65\span.c" /> <ClCompile Include="ld65\spool.c" /> <ClCompile Include="ld65\tpool.c" /> + <ClCompile Include="ld65\xex.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/src/ld65/binfmt.c b/src/ld65/binfmt.c index a510f94b7..f4f2678fe 100644 --- a/src/ld65/binfmt.c +++ b/src/ld65/binfmt.c @@ -73,6 +73,7 @@ int RelocatableBinFmt (unsigned Format) switch (Format) { case BINFMT_BINARY: + case BINFMT_ATARIEXE: Reloc = 0; break; diff --git a/src/ld65/config.c b/src/ld65/config.c index 099617ba0..fdf7d13eb 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -68,6 +68,7 @@ #include "objdata.h" #include "scanner.h" #include "spool.h" +#include "xex.h" @@ -149,6 +150,7 @@ static Collection CfgSymbols = STATIC_COLLECTION_INITIALIZER; /* Descriptor holding information about the binary formats */ static BinDesc* BinFmtDesc = 0; static O65Desc* O65FmtDesc = 0; +static XexDesc* XexFmtDesc = 0; @@ -543,6 +545,7 @@ static void ParseFiles (void) { "FORMAT", CFGTOK_FORMAT }, }; static const IdentTok Formats [] = { + { "ATARI", CFGTOK_ATARIEXE }, { "O65", CFGTOK_O65 }, { "BIN", CFGTOK_BIN }, { "BINARY", CFGTOK_BIN }, @@ -607,6 +610,10 @@ static void ParseFiles (void) F->Format = BINFMT_O65; break; + case CFGTOK_ATARIEXE: + F->Format = BINFMT_ATARIEXE; + break; + default: Error ("Unexpected format token"); } @@ -1023,6 +1030,7 @@ static void ParseFormats (void) break; case CFGTOK_BIN: + case CFGTOK_ATARIEXE: /* No attribibutes available */ break; @@ -1559,6 +1567,7 @@ void CfgRead (void) /* Create the descriptors for the binary formats */ BinFmtDesc = NewBinDesc (); O65FmtDesc = NewO65Desc (); + XexFmtDesc = NewXexDesc (); /* If we have a config name given, open the file, otherwise we will read ** from a buffer. @@ -2098,6 +2107,10 @@ void CfgWriteTarget (void) O65WriteTarget (O65FmtDesc, F); break; + case BINFMT_ATARIEXE: + XexWriteTarget (XexFmtDesc, F); + break; + default: Internal ("Invalid binary format: %u", F->Format); diff --git a/src/ld65/scanner.h b/src/ld65/scanner.h index 2df952ebb..783685951 100644 --- a/src/ld65/scanner.h +++ b/src/ld65/scanner.h @@ -107,6 +107,7 @@ typedef enum { CFGTOK_ZP, CFGTOK_OVERWRITE, + CFGTOK_ATARIEXE, CFGTOK_O65, CFGTOK_BIN, diff --git a/src/ld65/xex.c b/src/ld65/xex.c new file mode 100644 index 000000000..a57fdad06 --- /dev/null +++ b/src/ld65/xex.c @@ -0,0 +1,344 @@ +/*****************************************************************************/ +/* */ +/* xex.c */ +/* */ +/* Module to handle the Atari XEX binary format */ +/* */ +/* */ +/* */ +/* (C) 2018 Daniel Serpell */ +/* */ +/* */ +/* 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 <string.h> +#include <errno.h> + +/* common */ +#include "alignment.h" +#include "print.h" +#include "xmalloc.h" + +/* ld65 */ +#include "xex.h" +#include "config.h" +#include "exports.h" +#include "expr.h" +#include "error.h" +#include "global.h" +#include "fileio.h" +#include "lineinfo.h" +#include "memarea.h" +#include "segments.h" +#include "spool.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +struct XexDesc { + unsigned Undef; /* Count of undefined externals */ + FILE* F; /* Output file */ + const char* Filename; /* Name of output file */ +}; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +XexDesc* NewXexDesc (void) +/* Create a new XEX format descriptor */ +{ + /* Allocate memory for a new XexDesc struct */ + XexDesc* D = xmalloc (sizeof (XexDesc)); + + /* Initialize the fields */ + D->Undef = 0; + D->F = 0; + D->Filename = 0; + + /* Return the created struct */ + return D; +} + + + +void FreeXexDesc (XexDesc* D) +/* Free a XEX format descriptor */ +{ + xfree (D); +} + + + +static unsigned XexWriteExpr (ExprNode* E, int Signed, unsigned Size, + unsigned long Offs attribute ((unused)), + void* Data) +/* Called from SegWrite for an expression. Evaluate the expression, check the +** range and write the expression value to the file. +*/ +{ + /* There's a predefined function to handle constant expressions */ + return SegWriteConstExpr (((XexDesc*)Data)->F, E, Signed, Size); +} + + + +static void PrintBoolVal (const char* Name, int B) +/* Print a boolean value for debugging */ +{ + Print (stdout, 2, " %s = %s\n", Name, B? "true" : "false"); +} + + + +static void PrintNumVal (const char* Name, unsigned long V) +/* Print a numerical value for debugging */ +{ + Print (stdout, 2, " %s = 0x%lx\n", Name, V); +} + + + +static void XexWriteMem (XexDesc* D, MemoryArea* M) +/* Write the segments of one memory area to a file */ +{ + unsigned I; + + /* Get the start address and size of this memory area */ + unsigned long Addr = M->Start; + + /* Walk over segments twice: first to get real area size, then to write + * all segments. */ + for (I = 0; I < CollCount (&M->SegList); ++I) { + + /* Get the segment */ + SegDesc* S = CollAtUnchecked (&M->SegList, I); + + /* Keep the user happy */ + Print (stdout, 1, " Allocating `%s'\n", GetString (S->Name)); + + /* If this is the run memory area, we must apply run alignment. If + ** this is not the run memory area but the load memory area (which + ** means that both are different), we must apply load alignment. + ** Beware: DoWrite may be true even if this is the run memory area, + ** because it may be also the load memory area. + */ + if (S->Run == M) { + + /* Handle ALIGN and OFFSET/START */ + if (S->Flags & SF_ALIGN) { + /* Align the address */ + Addr = AlignAddr (Addr, S->RunAlignment); + } else if (S->Flags & (SF_OFFSET | SF_START)) { + Addr = S->Addr; + if (S->Flags & SF_OFFSET) { + /* It's an offset, not a fixed address, make an address */ + Addr += M->Start; + } + } + + } else if (S->Load == M) { + + /* Handle ALIGN_LOAD */ + if (S->Flags & SF_ALIGN_LOAD) { + /* Align the address */ + Addr = AlignAddr (Addr, S->LoadAlignment); + } + + } + + /* Calculate the new address */ + Addr += S->Seg->Size; + } + + /* Write header */ + Write16(D->F, 0xFFFF); + Write16(D->F, M->Start); + Write16(D->F, Addr-1); + + /* Redo */ + Addr = M->Start; + for (I = 0; I < CollCount (&M->SegList); ++I) { + + int DoWrite; + + /* Get the segment */ + SegDesc* S = CollAtUnchecked (&M->SegList, I); + + /* Keep the user happy */ + Print (stdout, 1, " Allocating `%s'\n", GetString (S->Name)); + + /* Writes do only occur in the load area and not for BSS segments */ + DoWrite = (S->Flags & SF_BSS) == 0 && /* No BSS segment */ + S->Load == M && /* LOAD segment */ + S->Seg->Dumped == 0; /* Not already written */ + + /* If this is the run memory area, we must apply run alignment. If + ** this is not the run memory area but the load memory area (which + ** means that both are different), we must apply load alignment. + ** Beware: DoWrite may be true even if this is the run memory area, + ** because it may be also the load memory area. + */ + if (S->Run == M) { + + /* Handle ALIGN and OFFSET/START */ + if (S->Flags & SF_ALIGN) { + /* Align the address */ + unsigned long NewAddr = AlignAddr (Addr, S->RunAlignment); + if (DoWrite || (M->Flags & MF_FILL) != 0) { + WriteMult (D->F, M->FillVal, NewAddr - Addr); + PrintNumVal ("SF_ALIGN", NewAddr - Addr); + } + Addr = NewAddr; + } else if (S->Flags & (SF_OFFSET | SF_START)) { + unsigned long NewAddr = S->Addr; + if (S->Flags & SF_OFFSET) { + /* It's an offset, not a fixed address, make an address */ + NewAddr += M->Start; + } + if (DoWrite || (M->Flags & MF_FILL) != 0) { + /* Seek in "overwrite" segments */ + if (S->Flags & SF_OVERWRITE) { + fseek (D->F, NewAddr - M->Start, SEEK_SET); + } else { + WriteMult (D->F, M->FillVal, NewAddr-Addr); + PrintNumVal ("SF_OFFSET", NewAddr - Addr); + } + } + Addr = NewAddr; + } + + } else if (S->Load == M) { + + /* Handle ALIGN_LOAD */ + if (S->Flags & SF_ALIGN_LOAD) { + /* Align the address */ + unsigned long NewAddr = AlignAddr (Addr, S->LoadAlignment); + if (DoWrite || (M->Flags & MF_FILL) != 0) { + WriteMult (D->F, M->FillVal, NewAddr - Addr); + PrintNumVal ("SF_ALIGN_LOAD", NewAddr - Addr); + } + Addr = NewAddr; + } + + } + + /* Now write the segment to disk if it is not a BSS type segment and + ** if the memory area is the load area. + */ + if (DoWrite) { + unsigned long P = ftell (D->F); + SegWrite (D->Filename, D->F, S->Seg, XexWriteExpr, D); + PrintNumVal ("Wrote", (unsigned long) (ftell (D->F) - P)); + } else if (M->Flags & MF_FILL) { + WriteMult (D->F, S->Seg->FillVal, S->Seg->Size); + PrintNumVal ("Filled", (unsigned long) S->Seg->Size); + } + + /* If this was the load memory area, mark the segment as dumped */ + if (S->Load == M) { + S->Seg->Dumped = 1; + } + + /* Calculate the new address */ + Addr += S->Seg->Size; + } + + /* If a fill was requested, fill the remaining space */ + if ((M->Flags & MF_FILL) != 0 && M->FillLevel < M->Size) { + unsigned long ToFill = M->Size - M->FillLevel; + Print (stdout, 2, " Filling 0x%lx bytes with 0x%02x\n", + ToFill, M->FillVal); + WriteMult (D->F, M->FillVal, ToFill); + M->FillLevel = M->Size; + } +} + + + +static int XexUnresolved (unsigned Name attribute ((unused)), void* D) +/* Called if an unresolved symbol is encountered */ +{ + /* Unresolved symbols are an error in XEX format. Bump the counter + ** and return zero telling the caller that the symbol is indeed + ** unresolved. + */ + ((XexDesc*) D)->Undef++; + return 0; +} + + + +void XexWriteTarget (XexDesc* D, struct File* F) +/* Write a XEX output file */ +{ + unsigned I; + + /* Place the filename in the control structure */ + D->Filename = GetString (F->Name); + + /* Check for unresolved symbols. The function XexUnresolved is called + ** if we get an unresolved symbol. + */ + D->Undef = 0; /* Reset the counter */ + CheckUnresolvedImports (XexUnresolved, D); + if (D->Undef > 0) { + /* We had unresolved symbols, cannot create output file */ + Error ("%u unresolved external(s) found - cannot create output file", D->Undef); + } + + /* Open the file */ + D->F = fopen (D->Filename, "wb"); + if (D->F == 0) { + Error ("Cannot open `%s': %s", D->Filename, strerror (errno)); + } + + /* Keep the user happy */ + Print (stdout, 1, "Opened `%s'...\n", D->Filename); + + /* Dump all memory areas */ + for (I = 0; I < CollCount (&F->MemoryAreas); ++I) { + /* Get this entry */ + MemoryArea* M = CollAtUnchecked (&F->MemoryAreas, I); + Print (stdout, 1, " XEX Dumping `%s'\n", GetString (M->Name)); + XexWriteMem (D, M); + } + + /* Close the file */ + if (fclose (D->F) != 0) { + Error ("Cannot write to `%s': %s", D->Filename, strerror (errno)); + } + + /* Reset the file and filename */ + D->F = 0; + D->Filename = 0; +} diff --git a/src/ld65/xex.h b/src/ld65/xex.h new file mode 100644 index 000000000..fd6ba7201 --- /dev/null +++ b/src/ld65/xex.h @@ -0,0 +1,72 @@ +/*****************************************************************************/ +/* */ +/* xex.h */ +/* */ +/* Module to handle the Atari EXE binary format */ +/* */ +/* */ +/* */ +/* (C) 2018 Daniel Serpell */ +/* */ +/* */ +/* 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 XEX_H +#define XEX_H + + + +#include "config.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Structure describing the format */ +typedef struct XexDesc XexDesc; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +XexDesc* NewXexDesc (void); +/* Create a new XEX format descriptor */ + +void FreeXexDesc (XexDesc* D); +/* Free a XEX format descriptor */ + +void XexWriteTarget (XexDesc* D, File* F); +/* Write a XEX output file */ + + + +/* End of xex.h */ + +#endif From 8e3fe2ef86054aae8401616daffe5cc202b88839 Mon Sep 17 00:00:00 2001 From: Daniel Serpell <daniel.serpell@gmail.com> Date: Tue, 25 Sep 2018 20:21:35 -0300 Subject: [PATCH 0992/2161] Remove unused function. --- src/ld65/xex.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/ld65/xex.c b/src/ld65/xex.c index a57fdad06..71065ea57 100644 --- a/src/ld65/xex.c +++ b/src/ld65/xex.c @@ -112,14 +112,6 @@ static unsigned XexWriteExpr (ExprNode* E, int Signed, unsigned Size, -static void PrintBoolVal (const char* Name, int B) -/* Print a boolean value for debugging */ -{ - Print (stdout, 2, " %s = %s\n", Name, B? "true" : "false"); -} - - - static void PrintNumVal (const char* Name, unsigned long V) /* Print a numerical value for debugging */ { From 63d9b492b7d9c82b58ac69a09ed98a54d4ab7908 Mon Sep 17 00:00:00 2001 From: Daniel Serpell <daniel.serpell@gmail.com> Date: Tue, 25 Sep 2018 20:21:49 -0300 Subject: [PATCH 0993/2161] Only write full ATARI XEX header in the first chunk. --- src/ld65/config.c | 66 +++++++++++++++++++++++++++++++++++++++++++++- src/ld65/scanner.h | 1 + src/ld65/xex.c | 21 ++++++++++++++- src/ld65/xex.h | 3 +++ 4 files changed, 89 insertions(+), 2 deletions(-) diff --git a/src/ld65/config.c b/src/ld65/config.c index fdf7d13eb..fafbed290 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -1002,6 +1002,66 @@ static void ParseO65 (void) +static void ParseXex (void) +/* Parse the o65 format section */ +{ + static const IdentTok Attributes [] = { + { "RUNAD", CFGTOK_RUNAD }, + }; + + /* Remember the attributes read */ + /* Bitmask to remember the attributes we got already */ + enum { + atNone = 0x0000, + atRunAd = 0x0001, + }; + unsigned AttrFlags = atNone; + Import *RunAd = 0; + + /* Read the attributes */ + while (CfgTok == CFGTOK_IDENT) { + + /* Map the identifier to a token */ + cfgtok_t AttrTok; + CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute"); + AttrTok = CfgTok; + + /* An optional assignment follows */ + CfgNextTok (); + CfgOptionalAssign (); + + /* Check which attribute was given */ + switch (AttrTok) { + + case CFGTOK_RUNAD: + /* Cannot have this attribute twice */ + FlagAttr (&AttrFlags, atRunAd, "RUNAD"); + /* We expect an identifier */ + CfgAssureIdent (); + /* Generate an import for the symbol */ + RunAd = InsertImport (GenImport (GetStrBufId (&CfgSVal), ADDR_SIZE_ABS)); + /* Remember the file position */ + CollAppend (&RunAd->RefLines, GenLineInfo (&CfgErrorPos)); + /* Eat the identifier token */ + CfgNextTok (); + break; + + default: + FAIL ("Unexpected attribute token"); + + } + + /* Skip an optional comma */ + CfgOptionalComma (); + } + + /* Set the RUNAD import if we have one */ + if ( RunAd ) + XexSetRunAd (XexFmtDesc, RunAd); +} + + + static void ParseFormats (void) /* Parse a target format section */ { @@ -1009,6 +1069,7 @@ static void ParseFormats (void) { "O65", CFGTOK_O65 }, { "BIN", CFGTOK_BIN }, { "BINARY", CFGTOK_BIN }, + { "ATARI", CFGTOK_ATARIEXE }, }; while (CfgTok == CFGTOK_IDENT) { @@ -1029,8 +1090,11 @@ static void ParseFormats (void) ParseO65 (); break; - case CFGTOK_BIN: case CFGTOK_ATARIEXE: + ParseXex (); + break; + + case CFGTOK_BIN: /* No attribibutes available */ break; diff --git a/src/ld65/scanner.h b/src/ld65/scanner.h index 783685951..77fa91da8 100644 --- a/src/ld65/scanner.h +++ b/src/ld65/scanner.h @@ -93,6 +93,7 @@ typedef enum { CFGTOK_ID, CFGTOK_VERSION, CFGTOK_FORMAT, + CFGTOK_RUNAD, CFGTOK_LOAD, CFGTOK_RUN, diff --git a/src/ld65/xex.c b/src/ld65/xex.c index 71065ea57..9d373fb36 100644 --- a/src/ld65/xex.c +++ b/src/ld65/xex.c @@ -64,6 +64,7 @@ struct XexDesc { unsigned Undef; /* Count of undefined externals */ FILE* F; /* Output file */ const char* Filename; /* Name of output file */ + Import* RunAd; /* Run Address */ }; @@ -84,6 +85,7 @@ XexDesc* NewXexDesc (void) D->Undef = 0; D->F = 0; D->Filename = 0; + D->RunAd = 0; /* Return the created struct */ return D; @@ -99,6 +101,14 @@ void FreeXexDesc (XexDesc* D) +void XexSetRunAd (XexDesc* D, Import *RunAd) +/* Set the RUNAD export */ +{ + D->RunAd = RunAd; +} + + + static unsigned XexWriteExpr (ExprNode* E, int Signed, unsigned Size, unsigned long Offs attribute ((unused)), void* Data) @@ -173,7 +183,8 @@ static void XexWriteMem (XexDesc* D, MemoryArea* M) } /* Write header */ - Write16(D->F, 0xFFFF); + if (ftell (D->F) == 0) + Write16(D->F, 0xFFFF); Write16(D->F, M->Start); Write16(D->F, Addr-1); @@ -273,6 +284,7 @@ static void XexWriteMem (XexDesc* D, MemoryArea* M) WriteMult (D->F, M->FillVal, ToFill); M->FillLevel = M->Size; } + } @@ -325,6 +337,13 @@ void XexWriteTarget (XexDesc* D, struct File* F) XexWriteMem (D, M); } + /* Write RUNAD at file end */ + if (D->RunAd) { + Write16 (D->F, 0x2E0); + Write16 (D->F, 0x2E1); + Write16 (D->F, GetExportVal (D->RunAd->Exp)); + } + /* Close the file */ if (fclose (D->F) != 0) { Error ("Cannot write to `%s': %s", D->Filename, strerror (errno)); diff --git a/src/ld65/xex.h b/src/ld65/xex.h index fd6ba7201..c74f78eca 100644 --- a/src/ld65/xex.h +++ b/src/ld65/xex.h @@ -36,6 +36,7 @@ #include "config.h" +#include "exports.h" @@ -65,6 +66,8 @@ void FreeXexDesc (XexDesc* D); void XexWriteTarget (XexDesc* D, File* F); /* Write a XEX output file */ +void XexSetRunAd (XexDesc* D, Import *RunAd); +/* Set the RUNAD export */ /* End of xex.h */ From 4e51fcbdd4b487a1ef0526b1feb23b6dd56eeb0e Mon Sep 17 00:00:00 2001 From: Daniel Serpell <daniel.serpell@gmail.com> Date: Tue, 25 Sep 2018 23:51:51 -0300 Subject: [PATCH 0994/2161] Don't support overwrite segments. This simplifies the memory area size calculations. --- src/ld65/xex.c | 59 +++++++++----------------------------------------- 1 file changed, 10 insertions(+), 49 deletions(-) diff --git a/src/ld65/xex.c b/src/ld65/xex.c index 9d373fb36..95d723ed0 100644 --- a/src/ld65/xex.c +++ b/src/ld65/xex.c @@ -138,58 +138,18 @@ static void XexWriteMem (XexDesc* D, MemoryArea* M) /* Get the start address and size of this memory area */ unsigned long Addr = M->Start; - /* Walk over segments twice: first to get real area size, then to write - * all segments. */ - for (I = 0; I < CollCount (&M->SegList); ++I) { - - /* Get the segment */ - SegDesc* S = CollAtUnchecked (&M->SegList, I); - - /* Keep the user happy */ - Print (stdout, 1, " Allocating `%s'\n", GetString (S->Name)); - - /* If this is the run memory area, we must apply run alignment. If - ** this is not the run memory area but the load memory area (which - ** means that both are different), we must apply load alignment. - ** Beware: DoWrite may be true even if this is the run memory area, - ** because it may be also the load memory area. - */ - if (S->Run == M) { - - /* Handle ALIGN and OFFSET/START */ - if (S->Flags & SF_ALIGN) { - /* Align the address */ - Addr = AlignAddr (Addr, S->RunAlignment); - } else if (S->Flags & (SF_OFFSET | SF_START)) { - Addr = S->Addr; - if (S->Flags & SF_OFFSET) { - /* It's an offset, not a fixed address, make an address */ - Addr += M->Start; - } - } - - } else if (S->Load == M) { - - /* Handle ALIGN_LOAD */ - if (S->Flags & SF_ALIGN_LOAD) { - /* Align the address */ - Addr = AlignAddr (Addr, S->LoadAlignment); - } - - } - - /* Calculate the new address */ - Addr += S->Seg->Size; - } + /* Real size of the memory area, either the FillLevel or the Size */ + unsigned long Size = M->FillLevel; + if ((M->Flags & MF_FILL) != 0 && M->FillLevel < M->Size) + Size = M->Size; /* Write header */ if (ftell (D->F) == 0) Write16(D->F, 0xFFFF); - Write16(D->F, M->Start); - Write16(D->F, Addr-1); + Write16(D->F, Addr); + Write16(D->F, Addr + Size - 1); - /* Redo */ - Addr = M->Start; + /* Walk over all segments in this memory area */ for (I = 0; I < CollCount (&M->SegList); ++I) { int DoWrite; @@ -229,9 +189,10 @@ static void XexWriteMem (XexDesc* D, MemoryArea* M) NewAddr += M->Start; } if (DoWrite || (M->Flags & MF_FILL) != 0) { - /* Seek in "overwrite" segments */ + /* "overwrite" segments are not supported */ if (S->Flags & SF_OVERWRITE) { - fseek (D->F, NewAddr - M->Start, SEEK_SET); + Error ("ATARI file format does not support overwrite for segment '%s'.", + GetString (S->Name)); } else { WriteMult (D->F, M->FillVal, NewAddr-Addr); PrintNumVal ("SF_OFFSET", NewAddr - Addr); From 2aa5b4cafee3277580005cf6399a2ece8e06b405 Mon Sep 17 00:00:00 2001 From: Daniel Serpell <daniel.serpell@gmail.com> Date: Thu, 27 Sep 2018 00:06:52 -0300 Subject: [PATCH 0995/2161] Rewrites ATARI EXE segment writing to optimally write segment sizes. We now expand segments as needed to write a minimal set of headers. --- src/ld65/xex.c | 103 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 89 insertions(+), 14 deletions(-) diff --git a/src/ld65/xex.c b/src/ld65/xex.c index 95d723ed0..18190c063 100644 --- a/src/ld65/xex.c +++ b/src/ld65/xex.c @@ -65,6 +65,9 @@ struct XexDesc { FILE* F; /* Output file */ const char* Filename; /* Name of output file */ Import* RunAd; /* Run Address */ + unsigned long HeadPos; /* Position in the file of current header */ + unsigned long HeadEnd; /* End address of current header */ + unsigned long HeadSize; /* Last header size, can be removed if zero */ }; @@ -86,6 +89,9 @@ XexDesc* NewXexDesc (void) D->F = 0; D->Filename = 0; D->RunAd = 0; + D->HeadPos = 0; + D->HeadEnd = 0; + D->HeadSize = 0; /* Return the created struct */ return D; @@ -130,25 +136,80 @@ static void PrintNumVal (const char* Name, unsigned long V) +static void XexStartSegment (XexDesc *D, unsigned long Addr, unsigned long Size) +{ + /* Skip segment without size */ + if (!Size) + return; + + /* Store current position */ + unsigned long Pos = ftell (D->F); + unsigned long End = Addr + Size - 1; + + /* See if last header can be expanded into this one */ + if (D->HeadPos && ((D->HeadEnd + 1) == Addr)) { + /* Expand current header */ + D->HeadEnd = End; + D->HeadSize += Size; + fseek (D->F, D->HeadPos + 2, SEEK_SET); + Write16 (D->F, End); + /* Seek to old position */ + fseek (D->F, Pos, SEEK_SET); + } + else + { + if (D->HeadSize == 0) { + /* Last header had no data, replace */ + Pos = D->HeadPos; + fseek (D->F, Pos, SEEK_SET); + } + + /* If we are at start of file, write XEX heder */ + if (Pos == 0) + Write16 (D->F, 0xFFFF); + + /* Writes a new segment header */ + D->HeadPos = ftell (D->F); + D->HeadEnd = End; + D->HeadSize = Size; + Write16 (D->F, Addr); + Write16 (D->F, End); + } +} + + + +static void XexFakeSegment (XexDesc *D, unsigned long Addr) +{ + /* See if last header can be expanded into this one, we are done */ + if (D->HeadPos && ((D->HeadEnd + 1) == Addr)) + return; + + /* If we are at start of file, write XEX heder */ + if (ftell (D->F) == 0) + Write16 (D->F, 0xFFFF); + + /* Writes a new (invalid) segment header */ + D->HeadPos = ftell (D->F); + D->HeadEnd = Addr - 1; + D->HeadSize = 0; + Write16 (D->F, Addr); + Write16 (D->F, D->HeadEnd); +} + + + static void XexWriteMem (XexDesc* D, MemoryArea* M) /* Write the segments of one memory area to a file */ { unsigned I; + /* Always write a segment header for each memory area */ + D->HeadPos = 0; + /* Get the start address and size of this memory area */ unsigned long Addr = M->Start; - /* Real size of the memory area, either the FillLevel or the Size */ - unsigned long Size = M->FillLevel; - if ((M->Flags & MF_FILL) != 0 && M->FillLevel < M->Size) - Size = M->Size; - - /* Write header */ - if (ftell (D->F) == 0) - Write16(D->F, 0xFFFF); - Write16(D->F, Addr); - Write16(D->F, Addr + Size - 1); - /* Walk over all segments in this memory area */ for (I = 0; I < CollCount (&M->SegList); ++I) { @@ -158,7 +219,7 @@ static void XexWriteMem (XexDesc* D, MemoryArea* M) SegDesc* S = CollAtUnchecked (&M->SegList, I); /* Keep the user happy */ - Print (stdout, 1, " Allocating `%s'\n", GetString (S->Name)); + Print (stdout, 1, " ATARI EXE Writing `%s'\n", GetString (S->Name)); /* Writes do only occur in the load area and not for BSS segments */ DoWrite = (S->Flags & SF_BSS) == 0 && /* No BSS segment */ @@ -178,6 +239,7 @@ static void XexWriteMem (XexDesc* D, MemoryArea* M) /* Align the address */ unsigned long NewAddr = AlignAddr (Addr, S->RunAlignment); if (DoWrite || (M->Flags & MF_FILL) != 0) { + XexStartSegment (D, Addr, NewAddr - Addr); WriteMult (D->F, M->FillVal, NewAddr - Addr); PrintNumVal ("SF_ALIGN", NewAddr - Addr); } @@ -194,6 +256,7 @@ static void XexWriteMem (XexDesc* D, MemoryArea* M) Error ("ATARI file format does not support overwrite for segment '%s'.", GetString (S->Name)); } else { + XexStartSegment (D, Addr, NewAddr - Addr); WriteMult (D->F, M->FillVal, NewAddr-Addr); PrintNumVal ("SF_OFFSET", NewAddr - Addr); } @@ -208,6 +271,7 @@ static void XexWriteMem (XexDesc* D, MemoryArea* M) /* Align the address */ unsigned long NewAddr = AlignAddr (Addr, S->LoadAlignment); if (DoWrite || (M->Flags & MF_FILL) != 0) { + XexStartSegment (D, Addr, NewAddr - Addr); WriteMult (D->F, M->FillVal, NewAddr - Addr); PrintNumVal ("SF_ALIGN_LOAD", NewAddr - Addr); } @@ -220,10 +284,16 @@ static void XexWriteMem (XexDesc* D, MemoryArea* M) ** if the memory area is the load area. */ if (DoWrite) { + /* Start a segment with only one byte, will fix later */ + XexFakeSegment (D, Addr); unsigned long P = ftell (D->F); SegWrite (D->Filename, D->F, S->Seg, XexWriteExpr, D); - PrintNumVal ("Wrote", (unsigned long) (ftell (D->F) - P)); + unsigned long Size = ftell (D->F) - P; + /* Fix segment size */ + XexStartSegment (D, Addr, Size); + PrintNumVal ("Wrote", Size); } else if (M->Flags & MF_FILL) { + XexStartSegment (D, Addr, S->Seg->Size); WriteMult (D->F, S->Seg->FillVal, S->Seg->Size); PrintNumVal ("Filled", (unsigned long) S->Seg->Size); } @@ -242,10 +312,15 @@ static void XexWriteMem (XexDesc* D, MemoryArea* M) unsigned long ToFill = M->Size - M->FillLevel; Print (stdout, 2, " Filling 0x%lx bytes with 0x%02x\n", ToFill, M->FillVal); + XexStartSegment (D, Addr, ToFill); WriteMult (D->F, M->FillVal, ToFill); M->FillLevel = M->Size; } + /* If the last segment is empty, remove */ + if (D->HeadSize == 0 && D->HeadPos) { + fseek (D->F, D->HeadPos, SEEK_SET); + } } @@ -294,7 +369,7 @@ void XexWriteTarget (XexDesc* D, struct File* F) for (I = 0; I < CollCount (&F->MemoryAreas); ++I) { /* Get this entry */ MemoryArea* M = CollAtUnchecked (&F->MemoryAreas, I); - Print (stdout, 1, " XEX Dumping `%s'\n", GetString (M->Name)); + Print (stdout, 1, " ATARI EXE Dumping `%s'\n", GetString (M->Name)); XexWriteMem (D, M); } From e767c8990d07003d9c91a6151cc61f0ea28639ea Mon Sep 17 00:00:00 2001 From: Daniel Serpell <daniel.serpell@gmail.com> Date: Sat, 1 Dec 2018 21:45:22 -0300 Subject: [PATCH 0996/2161] Adds documentation and a sample config file for the ATARI format. --- cfg/atari-xex.cfg | 24 ++++++++++++++++++++++++ doc/atari.sgml | 12 ++++++++++++ doc/ld65.sgml | 26 ++++++++++++++++++++++++-- 3 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 cfg/atari-xex.cfg diff --git a/cfg/atari-xex.cfg b/cfg/atari-xex.cfg new file mode 100644 index 000000000..f0a6291db --- /dev/null +++ b/cfg/atari-xex.cfg @@ -0,0 +1,24 @@ +FEATURES { + STARTADDRESS: default = $2E00; +} +SYMBOLS { + __STARTADDRESS__: type = export, value = %S; +} +MEMORY { + ZP: file = "", define = yes, start = $0082, size = $007E; + MAIN: file = %O, define = yes, start = %S, size = $BC20 - %S; +} +FILES { + %O: format = atari; +} +FORMATS { + atari: runad = start; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, optional = yes; + EXTZP: load = ZP, type = zp, optional = yes; # to enable modules to be able to link to C and assembler programs + CODE: load = MAIN, type = rw, define = yes; + 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/doc/atari.sgml b/doc/atari.sgml index 80293d82f..346377b36 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -203,6 +203,18 @@ is <it/left out/, keep this in mind. The values you assign to the two symbols <tt/__AUTOSTART__/ and <tt/__EXEHDR__/ don't matter. +<sect2><tt/atari-xex.cfg/<p> + +This config file allows writing multi segment binaries easily, without having to +write the header explicitly on each segment. + +It is similar to the <tt/atari-asm.cfg/ above, but uses the ATARI (xex) file +format support on LD65 instead of the standard binary output, so it does not +have the <tt/__AUTOSTART/ nor the <tt/__EXEHDR__/ symbols. + +Note that each <tt/MEMORY/ area in the configuration file will have it's own +segment in the output file with the correct headers. + <sect2><tt/atari-cart.cfg/<p> This config file can be used to create 8K or 16K cartridges. It's suited both diff --git a/doc/ld65.sgml b/doc/ld65.sgml index beb2144bf..0230b517f 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -894,7 +894,7 @@ look like this: } </verb></tscreen> -The only other available output format is the o65 format specified by Andre +There are two other available formats, one is the o65 format specified by Andre Fachat (see the <url url="http://www.6502.org/users/andre/o65/fileformat.html" name="6502 binary relocation format specification">). It is defined like this: @@ -904,7 +904,20 @@ name="6502 binary relocation format specification">). It is defined like this: } </verb></tscreen> -The necessary o65 attributes are defined in a special section labeled +The other format available is the Atari (xex) segmented file format, this is +the standard format used by Atari DOS 2.0 and upward file managers in the Atari +8-bit computers, and it is defined like this: + +<tscreen><verb> + FILES { + %O: format = atari; + } +</verb></tscreen> + +In the Atari segmented file format, the linker will write each <tt/MEMORY/ area +as a new segment, including a header with the start and end address. + +The necessary o65 or Atari attributes are defined in a special section labeled <ref id="FORMAT" name="FORMAT">. @@ -925,6 +938,15 @@ has several attributes that may be defined here. } </verb></tscreen> +The Atari file format has only one attribute, <tt/RUNAD/ that allows to specify +a symbol as the run address of the binary. If the attribute is omiteed, no run +address is specified. + +<tscreen><verb> + FORMATS { + atari: runad = _start; + } +</verb></tscreen> <sect1>The FEATURES section<label id="FEATURES"><p> From 2190703a576aebd71673009e73f0aa6de457ca47 Mon Sep 17 00:00:00 2001 From: Daniel Serpell <daniel.serpell@gmail.com> Date: Sun, 2 Dec 2018 00:41:36 -0300 Subject: [PATCH 0997/2161] Adds test code for the Atari (xex) linker file format. --- testcode/lib/atari/asm-xex.s | 51 ++++++++++++++++++++++++++ testcode/lib/atari/multi-xex.cfg | 31 ++++++++++++++++ testcode/lib/atari/multi-xex.s | 63 ++++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 testcode/lib/atari/asm-xex.s create mode 100644 testcode/lib/atari/multi-xex.cfg create mode 100644 testcode/lib/atari/multi-xex.s diff --git a/testcode/lib/atari/asm-xex.s b/testcode/lib/atari/asm-xex.s new file mode 100644 index 000000000..d2a8d0335 --- /dev/null +++ b/testcode/lib/atari/asm-xex.s @@ -0,0 +1,51 @@ +; Sample using ATARI file format, by "atari-xex.cfg" linker configuration. +; +; This is a very simple example, shows a message to the screen, waits and +; returns to DOS. +; +; Compile with: +; cl65 -tatari -Catari-xex.cfg asm-xex.s -o prog.xex + + .include "atari.inc" + +; Default RUNAD is "start", export that: + .export start + + +; Write string to screen +.proc puts + sta ICBAL + stx ICBAH + lda #PUTREC + sta ICCOM + ldx #$FF + stx ICBLL + inx + stx ICBLH + jsr CIOV + rts +.endproc + + +; Write a message and exit + +.proc start + lda #<msg + ldx #>msg + jsr puts + + + ; Delay before returning to DOS + lda #0 + tax +loop: + inx + cpx #$FF + adc #0 + bcc loop + + rts +.endproc + +msg: .byte "Hello world", ATEOL + diff --git a/testcode/lib/atari/multi-xex.cfg b/testcode/lib/atari/multi-xex.cfg new file mode 100644 index 000000000..18dfff820 --- /dev/null +++ b/testcode/lib/atari/multi-xex.cfg @@ -0,0 +1,31 @@ +FEATURES { + STARTADDRESS: default = $2E00; +} +MEMORY { + ZP: file = "", define = yes, start = $0082, size = $007E; + # First memory segment in file, load over COLOR registers: + COLOR: file = %O, start = $2C4, size = 5; + # Second memory segment, load at page 6: + PAGE6: file = %O, start = $600, size = 256; + # Third memory segment in file, load over SDLST register: + SDLST: file = %O, start = $230, size = 2; + # Main segment, load at "STARTADDRESS" + MAIN: file = %O, start = %S, size = $BC20 - %S; +} +FILES { + %O: format = atari; +} +FORMATS { + atari: runad = start; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, optional = yes; + # Place segments in memory areas: + COLOR: load = COLOR, type = rw; + PAGE6: load = PAGE6, type = rw; + SDLST: load = SDLST, type = rw; + 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/testcode/lib/atari/multi-xex.s b/testcode/lib/atari/multi-xex.s new file mode 100644 index 000000000..7957ddf64 --- /dev/null +++ b/testcode/lib/atari/multi-xex.s @@ -0,0 +1,63 @@ +; Multiple segment ATARI file format sample, using custom linker script. +; +; This sample defines a custom display-list screen with no code, writing all +; memory areas directly. +; +; See the linker script (multi-xex.cfg) for the definition of memory areas and +; segments. +; +; Compile with: +; cl65 -tatari -Cmulti-xex.cfg multi-xex.s -o prog.xex + + .include "atari.inc" + + .macpack atari + +; Default RUNAD is "start", export that: + .export start + + +; We load color values directly into registers + .segment "COLOR" + + .byte $16 ; COLOR0 + .byte $46 ; COLOR1 + .byte $00 ; COLOR2 + .byte $6A ; COLOR3 + .byte $82 ; COLOR4 + +; We load our display list over page 6 + .segment "PAGE6" + +display_list: + .byte DL_BLK8 + .byte DL_BLK8 + .byte DL_BLK8 + .byte DL_BLK8 + .byte DL_BLK8 + .byte DL_BLK8 + .byte DL_CHR20x8x2 | DL_LMS + .word screen_memory + .byte DL_CHR40x8x1 + .byte DL_JVB + .word display_list + +screen_memory: + ; first text line: 20 bytes + scrcode " HeLlO wOrLd! " + ; second text line, 40 bytes + .byte 0, 0, 0, 0, 0, 0, 0, 0,70,71,70,71,70,71,70,71,70,71,70,71 + .byte 70,71,70,71,70,71,70,71,70,71,70,71, 0, 0, 0, 0, 0, 0, 0, 0 + +; We write directly to the display list pointer + .segment "SDLST" + .word display_list + +; And we load our main program + .code + +.proc start + ; Jump forever + jmp start +.endproc + From a4a968dfd159e4aa4f89aa269ca9d2f80d3d8766 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 4 Feb 2019 20:42:03 +0100 Subject: [PATCH 0998/2161] Fix typo --- doc/telestrat.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index 6ae9cf941..1f352607f 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -36,7 +36,7 @@ Telestrat can start in Atmos mode with Atmos Cardridge (which is only the atmos Basic 1.1 ROM). Telestrat can start in Sedoric (Atmos OS) and Atmos mode with Stratoric Cardridge. -This Cardridge has 3 banks of 16KB of rom with : +This Cardridge has 3 banks of 16KB of rom with: <itemize> <item>a Sedoric ROM. <item>a Basic 1.1 ROM (Atmos). @@ -89,7 +89,7 @@ The only way to load a binary (for Telemon 2.4) is to: <item>remove the 20 bytes header <item>download <url name="osdk" url="http://osdk.defence-force.org/index?page=download"> <item>use Floppybuilder in OSDK to insert the binary with the tool (please read -FloppyBuilder manual to insert your binary, and to start microdisc boot sector +FloppyBuilder manual to learn how to insert your binary and how to start Microdisc boot sector when Telestrat starts) </itemize> From 58484449b4842517d09618bc1c5dad59373250ef Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 5 Feb 2019 23:27:52 +0100 Subject: [PATCH 0999/2161] remove TABs --- asminc/smc.inc | 22 +++++++------- asminc/telestrat.inc | 2 +- cfg/telestrat.cfg | 2 +- include/_tia.h | 56 +++++++++++++++++------------------ libsrc/common/getcpu.s | 2 +- libsrc/telestrat/cgetc.s | 20 ++++++------- libsrc/telestrat/close.s | 14 ++++----- libsrc/telestrat/clrscr.s | 18 +++++------ libsrc/telestrat/gotox.s | 6 ++-- libsrc/telestrat/gotoy.s | 2 +- libsrc/telestrat/mainargs.s | 48 +++++++++++++++--------------- libsrc/telestrat/open.s | 20 ++++++------- libsrc/telestrat/read.s | 10 +++---- libsrc/telestrat/wherex.s | 4 +-- libsrc/telestrat/wherey.s | 6 ++-- libsrc/telestrat/write.s | 40 ++++++++++++------------- samples/atari2600hello.c | 44 +++++++++++++-------------- src/cc65/codegen.c | 4 +-- src/cc65/pragma.c | 6 ++-- src/common/intptrstack.h | 4 +-- testcode/lib/gamate/lcdtest.s | 3 +- 21 files changed, 164 insertions(+), 169 deletions(-) diff --git a/asminc/smc.inc b/asminc/smc.inc index 0583f79e0..137c2d49a 100644 --- a/asminc/smc.inc +++ b/asminc/smc.inc @@ -63,7 +63,7 @@ _SMCDesignator: statement ldy #opcode sty _SMCDesignator .else - .error "Invalid usage of macro 'SMC_TransferOpcode'" + .error "Invalid usage of macro 'SMC_TransferOpcode'" .endif .endmacro @@ -75,7 +75,7 @@ _SMCDesignator: statement .elseif .match ({register}, y) ldy _SMCDesignator .else - .error "Invalid usage of macro 'SMC_LoadOpcode'" + .error "Invalid usage of macro 'SMC_LoadOpcode'" .endif .endmacro @@ -87,7 +87,7 @@ _SMCDesignator: statement .elseif .match ({register}, y) sty _SMCDesignator .else - .error "Invalid usage of macro 'SMC_StoreOpcode'" + .error "Invalid usage of macro 'SMC_StoreOpcode'" .endif .endmacro @@ -102,7 +102,7 @@ _SMCDesignator: statement ldy #(<(destination - _SMCDesignator - 2)) sty _SMCDesignator+1 .else - .error "Invalid usage of macro 'SMC_ChangeBranch'" + .error "Invalid usage of macro 'SMC_ChangeBranch'" .endif .endmacro @@ -117,7 +117,7 @@ _SMCDesignator: statement ldy value sty _SMCDesignator+1 .else - .error "Invalid usage of macro 'SMC_TransferValue'" + .error "Invalid usage of macro 'SMC_TransferValue'" .endif .endmacro @@ -129,7 +129,7 @@ _SMCDesignator: statement .elseif .match ({register}, y) ldy _SMCDesignator+1 .else - .error "Invalid usage of macro 'SMC_LoadValue'" + .error "Invalid usage of macro 'SMC_LoadValue'" .endif .endmacro @@ -141,7 +141,7 @@ _SMCDesignator: statement .elseif .match ({register}, y) sty _SMCDesignator+1 .else - .error "Invalid usage of macro 'SMC_StoreValue'" + .error "Invalid usage of macro 'SMC_StoreValue'" .endif .endmacro @@ -169,7 +169,7 @@ SMC_StoreValue label, register ldy value sty _SMCDesignator+2 .else - .error "Invalid usage of macro 'SMC_TransferHighByte'" + .error "Invalid usage of macro 'SMC_TransferHighByte'" .endif .endmacro @@ -181,7 +181,7 @@ SMC_StoreValue label, register .elseif .match ({register}, y) ldy _SMCDesignator+2 .else - .error "Invalid usage of macro 'SMC_LoadHighByte'" + .error "Invalid usage of macro 'SMC_LoadHighByte'" .endif .endmacro @@ -193,7 +193,7 @@ SMC_StoreValue label, register .elseif .match ({register}, y) sty _SMCDesignator+2 .else - .error "Invalid usage of macro 'SMC_StoreHighByte'" + .error "Invalid usage of macro 'SMC_StoreHighByte'" .endif .endmacro @@ -241,7 +241,7 @@ SMC_StoreValue label, register sty _SMCDesignator+2 .endif .else - .error "Invalid usage of macro 'SMC_TransferAddressSingle'" + .error "Invalid usage of macro 'SMC_TransferAddressSingle'" .endif .endmacro diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index df607e375..9322ec114 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -367,5 +367,5 @@ XRWTS := $FFAA ; MACRO .macro BRK_TELEMON value - .byte $00,value + .byte $00,value .endmacro diff --git a/cfg/telestrat.cfg b/cfg/telestrat.cfg index 14ae30311..db897133e 100644 --- a/cfg/telestrat.cfg +++ b/cfg/telestrat.cfg @@ -2,7 +2,7 @@ SYMBOLS { __ORIXHDR__: type = import; __STACKSIZE__: type = weak, value = $0800; # 2K stack __GRAB__: type = weak, value = 0; # 0=don't grab graphics RAM, 1=grab graphics RAM - __RAMEND__: type = weak, value = $9800 + $1C00 * __GRAB__; + __RAMEND__: type = weak, value = $9800 + $1C00 * __GRAB__; } MEMORY { ZP: file = "", define = yes, start = $00B0, size = $003A; diff --git a/include/_tia.h b/include/_tia.h index c89c04d6c..67c08ea18 100644 --- a/include/_tia.h +++ b/include/_tia.h @@ -11,60 +11,60 @@ /* TIA write / read registers */ struct __tia { union { - unsigned char vsync; - unsigned char cxm0p; + unsigned char vsync; + unsigned char cxm0p; }; union { - unsigned char vblank; - unsigned char cxm1p; + unsigned char vblank; + unsigned char cxm1p; }; union { - unsigned char wsync; - unsigned char cxp0fb; + unsigned char wsync; + unsigned char cxp0fb; }; union { - unsigned char rsync; - unsigned char cxp1fb; + unsigned char rsync; + unsigned char cxp1fb; }; union { - unsigned char nusiz0; - unsigned char cxm0fb; + unsigned char nusiz0; + unsigned char cxm0fb; }; union { - unsigned char nusiz1; - unsigned char cxm1fb; + unsigned char nusiz1; + unsigned char cxm1fb; }; union { - unsigned char colup0; - unsigned char cxblpf; + unsigned char colup0; + unsigned char cxblpf; }; union { - unsigned char colup1; - unsigned char cxppmm; + unsigned char colup1; + unsigned char cxppmm; }; union { - unsigned char colupf; - unsigned char inpt0; + unsigned char colupf; + unsigned char inpt0; }; union { - unsigned char colubk; - unsigned char inpt1; + unsigned char colubk; + unsigned char inpt1; }; union { - unsigned char ctrlpf; - unsigned char inpt2; + unsigned char ctrlpf; + unsigned char inpt2; }; union { - unsigned char refp0; - unsigned char inpt3; + unsigned char refp0; + unsigned char inpt3; }; union { - unsigned char refp1; - unsigned char inpt4; + unsigned char refp1; + unsigned char inpt4; }; union { - unsigned char pf0; - unsigned char inpt5; + unsigned char pf0; + unsigned char inpt5; }; unsigned char pf1; unsigned char pf2; diff --git a/libsrc/common/getcpu.s b/libsrc/common/getcpu.s index 51ccd5a4a..ab6a8aef9 100644 --- a/libsrc/common/getcpu.s +++ b/libsrc/common/getcpu.s @@ -3,7 +3,7 @@ ; ; unsigned char getcpu (void); ; - .include "zeropage.inc" + .include "zeropage.inc" .export _getcpu ; --------------------------------------------------------------------------- diff --git a/libsrc/telestrat/cgetc.s b/libsrc/telestrat/cgetc.s index 6a6b23318..cad8814af 100644 --- a/libsrc/telestrat/cgetc.s +++ b/libsrc/telestrat/cgetc.s @@ -2,27 +2,27 @@ ; jede jede@oric.org 2017-10-01 ; .export _cgetc - + .import cursor - + .include "telestrat.inc" .proc _cgetc - ; this routine could be quicker if we wrote in page 2 variables, + ; this routine could be quicker if we wrote in page 2 variables, ; but it's better to use telemon routine in that case, because telemon can manage 4 I/O ldx cursor ; if cursor equal to 0, then switch off cursor beq switchoff_cursor - + ldx #$00 ; x is the first screen BRK_TELEMON(XCSSCR) ; display cursor jmp loop ; could be replaced by a bne/beq but 'jmp' is cleaner than a bne/beq which could expect some matters - -switchoff_cursor: + +switchoff_cursor: ; at this step X is equal to $00, X must be set, because it's the id of the screen (telestrat can handle 4 virtuals screen) - BRK_TELEMON(XCOSCR) ; switch off cursor - -loop: + BRK_TELEMON(XCOSCR) ; switch off cursor + +loop: BRK_TELEMON XRD0 ; waits until key is pressed bcs loop rts -.endproc +.endproc diff --git a/libsrc/telestrat/close.s b/libsrc/telestrat/close.s index 40e2c10b3..17f6327f0 100644 --- a/libsrc/telestrat/close.s +++ b/libsrc/telestrat/close.s @@ -1,16 +1,16 @@ ; jede jede@oric.org 2017-01-22 .export _close - - .import addysp,popax - - .include "zeropage.inc" + + .import addysp,popax + + .include "zeropage.inc" .include "telestrat.inc" .include "errno.inc" - .include "fcntl.inc" - + .include "fcntl.inc" + ; int open (const char* name, int flags, ...); /* May take a mode argument */ .proc _close - BRK_TELEMON XCLOSE ; launch primitive ROM + BRK_TELEMON XCLOSE ; launch primitive ROM rts .endproc diff --git a/libsrc/telestrat/clrscr.s b/libsrc/telestrat/clrscr.s index 31c8ee205..1f90a7ca5 100644 --- a/libsrc/telestrat/clrscr.s +++ b/libsrc/telestrat/clrscr.s @@ -1,16 +1,16 @@ ; ; jede jede@oric.org 2017-02-25 -; +; .export _clrscr - + .importzp sp - + .include "telestrat.inc" .proc _clrscr ; Switch to text mode - BRK_TELEMON(XTEXT) + BRK_TELEMON(XTEXT) lda #<SCREEN ldy #>SCREEN @@ -21,18 +21,18 @@ ldx #>(SCREEN+SCREEN_XSIZE*SCREEN_YSIZE) lda #' ' BRK_TELEMON XFILLM - - + + ; reset prompt position lda #<(SCREEN+40) sta ADSCRL lda #>(SCREEN+40) sta ADSCRH - + ; reset display position lda #$01 sta SCRY lda #$00 - sta SCRX + sta SCRX rts -.endproc +.endproc diff --git a/libsrc/telestrat/gotox.s b/libsrc/telestrat/gotox.s index d6af0e4dd..f16c05b71 100644 --- a/libsrc/telestrat/gotox.s +++ b/libsrc/telestrat/gotox.s @@ -2,9 +2,9 @@ ; jede jede@oric.org 2017-02-25 ; .export _gotox - + .import popa - + .importzp sp .include "telestrat.inc" @@ -13,4 +13,4 @@ .proc _gotox sta SCRX rts -.endproc +.endproc diff --git a/libsrc/telestrat/gotoy.s b/libsrc/telestrat/gotoy.s index ed7101c80..05ed71de7 100644 --- a/libsrc/telestrat/gotoy.s +++ b/libsrc/telestrat/gotoy.s @@ -10,4 +10,4 @@ .proc _gotoy sta SCRY rts -.endproc +.endproc diff --git a/libsrc/telestrat/mainargs.s b/libsrc/telestrat/mainargs.s index 0c9e799da..b7ffb4ec7 100644 --- a/libsrc/telestrat/mainargs.s +++ b/libsrc/telestrat/mainargs.s @@ -24,28 +24,28 @@ initmainargs: ldx #0 ; Limit the length L0: lda BUFEDT,x - beq L3 - cmp #' ' - bne L1 - lda #0 - beq L3 + beq L3 + cmp #' ' + bne L1 + lda #0 + beq L3 L1: sta name,x inx - cpx #FNAME_LEN + cpx #FNAME_LEN bne L0 - lda #0 -L3: - sta name,x + lda #0 +L3: + sta name,x inc __argc ; argc always is equal to, at least, 1 - + ldy #1 * 2 ; Point to second argv slot - + next: lda BUFEDT,x beq done ; End of line reached inx cmp #' ' ; Skip leading spaces - beq next + beq next found: cmp #'"' ; Is the argument quoted? beq setterm ; Jump if so @@ -58,12 +58,12 @@ setterm:sta term ; Set end of argument marker txa ; Get low byte clc - adc #<BUFEDT - bcc L4 - inc L5+1 + adc #<BUFEDT + bcc L4 + inc L5+1 L4: sta argv,y ; argv[y]=&arg -L5: +L5: lda #>BUFEDT sta argv+1,y iny @@ -92,16 +92,16 @@ argloop:lda BUFEDT,x lda __argc ; Get low byte of argument count cmp #MAXARGS ; Maximum number of arguments reached? - bcc next ; Parse next one if not - - + bcc next ; Parse next one if not + + done: lda #<argv ldx #>argv sta __argv stx __argv + 1 rts - - + + .segment "INIT" term: .res 1 @@ -113,8 +113,8 @@ name: .res FNAME_LEN + 1 args: .res SCREEN_XSIZE * 2 - 1 param_found: - .res 1 + .res 1 ; char* argv[MAXARGS+1]={name}; -argv: - .addr name +argv: + .addr name .res MAXARGS * 2 diff --git a/libsrc/telestrat/open.s b/libsrc/telestrat/open.s index 08910f4f2..f59d3d31a 100644 --- a/libsrc/telestrat/open.s +++ b/libsrc/telestrat/open.s @@ -1,13 +1,13 @@ .export _open - + .import addysp,popax - + .importzp sp,tmp2,tmp3,tmp1 - - + + .include "telestrat.inc" .include "errno.inc" - .include "fcntl.inc" + .include "fcntl.inc" ; int open (const char* name, int flags, ...); /* May take a mode argument */ .proc _open @@ -17,8 +17,8 @@ dey ; ...checked (it generates a c compiler warning) dey dey - beq parmok ; Branch if parameter count ok - jsr addysp ; Fix stack, throw away unused parameters + beq parmok ; Branch if parameter count ok + jsr addysp ; Fix stack, throw away unused parameters ; Parameters ok. Pop the flags and save them into tmp3 @@ -26,8 +26,8 @@ parmok: jsr popax ; Get flagss sta tmp3 ; save flags ; Get the filename from stack and parse it. Bail out if is not ok - jsr popax ; Get name - ldy tmp3 ; Get flags again - BRK_TELEMON XOPEN ; launch primitive ROM + jsr popax ; Get name + ldy tmp3 ; Get flags again + BRK_TELEMON XOPEN ; launch primitive ROM rts .endproc diff --git a/libsrc/telestrat/read.s b/libsrc/telestrat/read.s index 75766cda2..76de9d0ac 100644 --- a/libsrc/telestrat/read.s +++ b/libsrc/telestrat/read.s @@ -8,7 +8,7 @@ .include "zeropage.inc" .include "telestrat.inc" - + ;int read (int fd, void* buf, unsigned count); .proc _read @@ -20,22 +20,20 @@ stx PTR_READ_DEST+1 sta ptr2 ; in order to calculate nb of bytes read stx ptr2+1 ; - + ; jsr popax ; fp pointer don't care in this version - lda ptr1 ; + lda ptr1 ; ldy ptr1+1 ; BRK_TELEMON XFREAD ; calls telemon30 routine ; compute nb of bytes read lda PTR_READ_DEST+1 sec sbc ptr2+1 - tax + tax lda PTR_READ_DEST sec sbc ptr2 ; Here A and X contains number of bytes read rts .endproc - - diff --git a/libsrc/telestrat/wherex.s b/libsrc/telestrat/wherex.s index 0dd5139e1..8616003c8 100644 --- a/libsrc/telestrat/wherex.s +++ b/libsrc/telestrat/wherex.s @@ -2,7 +2,7 @@ ; jede jede@oric.org 2017-02-25 ; .export _wherex - + .importzp sp .include "telestrat.inc" @@ -11,4 +11,4 @@ ldx #$00 lda SCRX rts -.endproc +.endproc diff --git a/libsrc/telestrat/wherey.s b/libsrc/telestrat/wherey.s index 962608ca2..c05b5f5c8 100644 --- a/libsrc/telestrat/wherey.s +++ b/libsrc/telestrat/wherey.s @@ -1,12 +1,12 @@ ; ; jede jede@oric.org 2017-02-25 -; +; .export _wherey - + .include "telestrat.inc" .proc _wherey ldx #$00 lda SCRY rts -.endproc +.endproc diff --git a/libsrc/telestrat/write.s b/libsrc/telestrat/write.s index 6498283fb..68aef42d6 100644 --- a/libsrc/telestrat/write.s +++ b/libsrc/telestrat/write.s @@ -23,34 +23,34 @@ jsr popax ; get fd and discard ; if fd=0001 then it stdout - cpx #0 - beq next - jmp L1 -next: - cmp #1 - beq L1 - + cpx #0 + beq next + jmp L1 +next: + cmp #1 + beq L1 + ; here it's a file opened - lda ptr1 - sta PTR_READ_DEST - lda ptr1+1 - sta PTR_READ_DEST+1 - lda ptr3 - ldy ptr3+1 + lda ptr1 + sta PTR_READ_DEST + lda ptr1+1 + sta PTR_READ_DEST+1 + lda ptr3 + ldy ptr3+1 BRK_TELEMON XFWRITE ; compute nb of bytes written - + lda PTR_READ_DEST+1 sec sbc ptr1+1 - tax + tax lda PTR_READ_DEST sec sbc ptr1 rts - - + + L1: inc ptr2 bne L2 inc ptr2+1 @@ -63,10 +63,10 @@ L2: ldy #0 BRK_TELEMON XWR0 ; macro send char to screen (channel 0 in telemon terms) lda #$0D ; return to the beggining of the line BRK_TELEMON XWR0 ; macro - + ldx #$0D -L3: +L3: BRK_TELEMON XWR0 ; macro inc ptr1 @@ -81,5 +81,3 @@ L9: lda ptr3 rts .endproc - - diff --git a/samples/atari2600hello.c b/samples/atari2600hello.c index e4f7893b7..4785ad90b 100644 --- a/samples/atari2600hello.c +++ b/samples/atari2600hello.c @@ -25,32 +25,32 @@ void main(void) { bss_v = 0x88; // Testing BSS variable for/*ever*/(;;) { - // Vertical Sync signal - TIA.vsync = 0x02; - TIA.wsync = 0x00; - TIA.wsync = 0x00; - TIA.wsync = 0x00; - TIA.vsync = 0x00; + // Vertical Sync signal + TIA.vsync = 0x02; + TIA.wsync = 0x00; + TIA.wsync = 0x00; + TIA.wsync = 0x00; + TIA.vsync = 0x00; - // Vertical Blank timer setting - RIOT.tim64t = VBLANK_TIM64; + // Vertical Blank timer setting + RIOT.tim64t = VBLANK_TIM64; - // Doing frame computation during blank - TIA.colubk = color++; // Update color + // Doing frame computation during blank + TIA.colubk = color++; // Update color - // Wait for end of Vertical Blank - while (RIOT.timint == 0) {} - TIA.wsync = 0x00; - TIA.vblank = 0x00; // Turn on beam + // Wait for end of Vertical Blank + while (RIOT.timint == 0) {} + TIA.wsync = 0x00; + TIA.vblank = 0x00; // Turn on beam - // Display frame - RIOT.t1024t = KERNAL_T1024; - while (RIOT.timint == 0) {} - TIA.wsync = 0x00; - TIA.vblank = 0x02; // Turn off beam + // Display frame + RIOT.t1024t = KERNAL_T1024; + while (RIOT.timint == 0) {} + TIA.wsync = 0x00; + TIA.vblank = 0x02; // Turn off beam - // Overscan - RIOT.tim64t = OVERSCAN_TIM64; - while (RIOT.timint == 0) {} + // Overscan + RIOT.tim64t = OVERSCAN_TIM64; + while (RIOT.timint == 0) {} } } diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 0f7b45968..a611f4f6a 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -4256,7 +4256,7 @@ void g_initauto (unsigned Label, unsigned Size) AddCodeLine ("lda %s,y", GetLabelName (CF_STATIC, Label, 0)); AddCodeLine ("sta (sp),y"); AddCodeLine ("iny"); - AddCmpCodeIfSizeNot256 ("cpy #$%02X", Size); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Size); AddCodeLine ("bne %s", LocalLabelName (CodeLabel)); } } @@ -4281,7 +4281,7 @@ void g_initstatic (unsigned InitLabel, unsigned VarLabel, unsigned Size) AddCodeLine ("lda %s,y", GetLabelName (CF_STATIC, InitLabel, 0)); AddCodeLine ("sta %s,y", GetLabelName (CF_STATIC, VarLabel, 0)); AddCodeLine ("iny"); - AddCmpCodeIfSizeNot256 ("cpy #$%02X", Size); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Size); AddCodeLine ("bne %s", LocalLabelName (CodeLabel)); } else { /* Use the easy way here: memcpy() */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 1a24a08d9..b05ef6122 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -898,9 +898,9 @@ static void ParsePragma (void) FlagPragma (&B, &StaticLocals); break; - case PRAGMA_WRAPPED_CALL: - WrappedCallPragma(&B); - break; + case PRAGMA_WRAPPED_CALL: + WrappedCallPragma(&B); + break; case PRAGMA_WARN: WarnPragma (&B); diff --git a/src/common/intptrstack.h b/src/common/intptrstack.h index a7b1c6683..4e9cf08f4 100644 --- a/src/common/intptrstack.h +++ b/src/common/intptrstack.h @@ -47,8 +47,8 @@ typedef struct IntPtrStack IntPtrStack; struct IntPtrInner { - long val; - void *ptr; + long val; + void *ptr; }; struct IntPtrStack { unsigned Count; diff --git a/testcode/lib/gamate/lcdtest.s b/testcode/lib/gamate/lcdtest.s index 3a8d72226..56ed82a79 100644 --- a/testcode/lib/gamate/lcdtest.s +++ b/testcode/lib/gamate/lcdtest.s @@ -13,7 +13,7 @@ psa: .word 0 .bss temp_x: .byte 0 temp_y: .byte 0 -temp_a: .byte 0 +temp_a: .byte 0 irq_count: .byte 0 nmi_count: .byte 0 psx: .byte 0 @@ -419,4 +419,3 @@ printsign1: ldy temp_y rts .endproc - From 50fd96bbabe91ad115ad324cd0aa2a19382905c1 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Thu, 7 Feb 2019 12:19:49 +0100 Subject: [PATCH 1000/2161] Fixed 65C02 timing. --- src/sim65/6502.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index bfbfbd78c..683937ed7 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -37,8 +37,6 @@ BBRx, BBSx, RMBx, SMBx, WAI, and STP are unsupported * BCD flag handling equals 6502 (unchecked if bug is simulated or wrong for 6502) - * one cycle win for fetch-modify-write instructions ignored - (e.g., ROL abs,x takes only 6 cycles if no page break occurs) */ #include "memory.h" @@ -629,6 +627,8 @@ static void OPC_6502_1E (void) 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); @@ -898,6 +898,8 @@ static void OPC_6502_3E (void) 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); @@ -1132,6 +1134,8 @@ static void OPC_6502_5E (void) 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; @@ -1462,6 +1466,8 @@ static void OPC_6502_7E (void) 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); @@ -2341,6 +2347,8 @@ static void OPC_6502_DE (void) 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) - 1; MemWriteByte (Addr, Val); TEST_ZF (Val); @@ -2648,6 +2656,8 @@ static void OPC_6502_FE (void) 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) + 1; MemWriteByte (Addr, Val); TEST_ZF (Val); From 08ec9fc392a2583420d13ccf6c74a2a258a3d03f Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 12 Feb 2019 11:27:12 +0100 Subject: [PATCH 1001/2161] Fixed 65C02 timing again. --- src/sim65/6502.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index 683937ed7..b3c06293a 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -2347,8 +2347,6 @@ static void OPC_6502_DE (void) 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) - 1; MemWriteByte (Addr, Val); TEST_ZF (Val); @@ -2656,8 +2654,6 @@ static void OPC_6502_FE (void) 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) + 1; MemWriteByte (Addr, Val); TEST_ZF (Val); From 10a31d006b7fe230a2cd2a233ba86e05618beec4 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 12 Feb 2019 17:47:17 +0100 Subject: [PATCH 1002/2161] Add translation from PETSCII to screen codes. --- include/c64_screen_charmap.h | 290 +++++++++++++++++++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 include/c64_screen_charmap.h diff --git a/include/c64_screen_charmap.h b/include/c64_screen_charmap.h new file mode 100644 index 000000000..861ad2704 --- /dev/null +++ b/include/c64_screen_charmap.h @@ -0,0 +1,290 @@ +/*****************************************************************************/ +/* */ +/* c64_screen_charmap.h */ +/* */ +/* (c) Copyright 2019, Gerhard W. Gruber (sparhawk@gmx.at) */ +/* */ +/* When using C64 mode, this include converts the characters */ +/* from PETSCII to screen mapping, so you can write directly to */ +/* the screen memory. */ +/* */ +/* If this include is used, no additional macros are needed */ +/* */ +/*****************************************************************************/ + +/* No include guard here! Multiple use in one file may be intentional. */ + +// Char $00 ... $1F -> c + 128 +#pragma warn (remap-zero, push, off) +#pragma charmap ($00, $80) +#pragma warn (remap-zero, pop) + +#pragma charmap ($01, $81) +#pragma charmap ($02, $82) +#pragma charmap ($03, $83) +#pragma charmap ($04, $84) +#pragma charmap ($05, $85) +#pragma charmap ($06, $86) +#pragma charmap ($07, $87) +#pragma charmap ($08, $88) +#pragma charmap ($09, $89) +#pragma charmap ($0A, $8A) +#pragma charmap ($0B, $8B) +#pragma charmap ($0C, $8C) +#pragma charmap ($0D, $8D) +#pragma charmap ($0E, $8E) +#pragma charmap ($0F, $8F) +#pragma charmap ($10, $90) +#pragma charmap ($11, $91) +#pragma charmap ($12, $92) +#pragma charmap ($13, $93) +#pragma charmap ($14, $94) +#pragma charmap ($15, $95) +#pragma charmap ($16, $96) +#pragma charmap ($17, $97) +#pragma charmap ($18, $98) +#pragma charmap ($19, $99) +#pragma charmap ($1A, $9A) +#pragma charmap ($1B, $9B) +#pragma charmap ($1C, $9C) +#pragma charmap ($1D, $9D) +#pragma charmap ($1E, $9E) +#pragma charmap ($1F, $9F) + +// Char $20 ... $3F -> c = c +#pragma charmap ($20, $20) +#pragma charmap ($21, $21) +#pragma charmap ($22, $22) +#pragma charmap ($23, $23) +#pragma charmap ($24, $24) +#pragma charmap ($25, $25) +#pragma charmap ($26, $26) +#pragma charmap ($27, $27) +#pragma charmap ($28, $28) +#pragma charmap ($29, $29) +#pragma charmap ($2A, $2A) +#pragma charmap ($2B, $2B) +#pragma charmap ($2C, $2C) +#pragma charmap ($2D, $2D) +#pragma charmap ($2E, $2E) +#pragma charmap ($2F, $2F) +#pragma charmap ($30, $30) +#pragma charmap ($31, $31) +#pragma charmap ($32, $32) +#pragma charmap ($33, $33) +#pragma charmap ($34, $34) +#pragma charmap ($35, $35) +#pragma charmap ($36, $36) +#pragma charmap ($37, $37) +#pragma charmap ($38, $38) +#pragma charmap ($39, $39) +#pragma charmap ($3A, $3A) +#pragma charmap ($3B, $3B) +#pragma charmap ($3C, $3C) +#pragma charmap ($3D, $3D) +#pragma charmap ($3E, $3E) +#pragma charmap ($3F, $3F) + +// Char $40 ... $5F -> c - 64 +#pragma charmap ($40, $00) +#pragma charmap ($41, $01) +#pragma charmap ($42, $02) +#pragma charmap ($43, $03) +#pragma charmap ($44, $04) +#pragma charmap ($45, $05) +#pragma charmap ($46, $06) +#pragma charmap ($47, $07) +#pragma charmap ($48, $08) +#pragma charmap ($49, $09) +#pragma charmap ($4A, $0A) +#pragma charmap ($4B, $0B) +#pragma charmap ($4C, $0C) +#pragma charmap ($4D, $0D) +#pragma charmap ($4E, $0E) +#pragma charmap ($4F, $0F) +#pragma charmap ($50, $10) +#pragma charmap ($51, $11) +#pragma charmap ($52, $12) +#pragma charmap ($53, $13) +#pragma charmap ($54, $14) +#pragma charmap ($55, $15) +#pragma charmap ($56, $16) +#pragma charmap ($57, $17) +#pragma charmap ($58, $18) +#pragma charmap ($59, $19) +#pragma charmap ($5A, $1A) +#pragma charmap ($5B, $1B) +#pragma charmap ($5C, $1C) +#pragma charmap ($5D, $1D) +#pragma charmap ($5E, $1E) +#pragma charmap ($5F, $1F) + +// Char $60 ... $7F -> c - 32 +#pragma charmap ($60, $40) +#pragma charmap ($61, $41) +#pragma charmap ($62, $42) +#pragma charmap ($63, $43) +#pragma charmap ($64, $44) +#pragma charmap ($65, $45) +#pragma charmap ($66, $46) +#pragma charmap ($67, $47) +#pragma charmap ($68, $48) +#pragma charmap ($69, $49) +#pragma charmap ($6A, $4A) +#pragma charmap ($6B, $4B) +#pragma charmap ($6C, $4C) +#pragma charmap ($6D, $4D) +#pragma charmap ($6E, $4E) +#pragma charmap ($6F, $4F) +#pragma charmap ($70, $50) +#pragma charmap ($71, $51) +#pragma charmap ($72, $52) +#pragma charmap ($73, $53) +#pragma charmap ($74, $54) +#pragma charmap ($75, $55) +#pragma charmap ($76, $56) +#pragma charmap ($77, $57) +#pragma charmap ($78, $58) +#pragma charmap ($79, $59) +#pragma charmap ($7A, $5A) +#pragma charmap ($7B, $5B) +#pragma charmap ($7C, $5C) +#pragma charmap ($7D, $5D) +#pragma charmap ($7E, $5E) +#pragma charmap ($7F, $5F) + +// Char $80 ... $9F -> c + 64 +#pragma charmap ($80, $C0) +#pragma charmap ($81, $C1) +#pragma charmap ($82, $C2) +#pragma charmap ($83, $C3) +#pragma charmap ($84, $C4) +#pragma charmap ($85, $C5) +#pragma charmap ($86, $C6) +#pragma charmap ($87, $C7) +#pragma charmap ($88, $C8) +#pragma charmap ($89, $C9) +#pragma charmap ($8A, $CA) +#pragma charmap ($8B, $CB) +#pragma charmap ($8C, $CC) +#pragma charmap ($8D, $CD) +#pragma charmap ($8E, $CE) +#pragma charmap ($8F, $CF) +#pragma charmap ($90, $D0) +#pragma charmap ($91, $D1) +#pragma charmap ($92, $D2) +#pragma charmap ($93, $D3) +#pragma charmap ($94, $D4) +#pragma charmap ($95, $D5) +#pragma charmap ($96, $D6) +#pragma charmap ($97, $D7) +#pragma charmap ($98, $D8) +#pragma charmap ($99, $D9) +#pragma charmap ($9A, $DA) +#pragma charmap ($9B, $DB) +#pragma charmap ($9C, $DC) +#pragma charmap ($9D, $DD) +#pragma charmap ($9E, $DE) +#pragma charmap ($9F, $DF) + +// Char $A0 ... $BF -> c - 64 +#pragma charmap ($A0, $60) +#pragma charmap ($A1, $61) +#pragma charmap ($A2, $62) +#pragma charmap ($A3, $63) +#pragma charmap ($A4, $64) +#pragma charmap ($A5, $65) +#pragma charmap ($A6, $66) +#pragma charmap ($A7, $67) +#pragma charmap ($A8, $68) +#pragma charmap ($A9, $69) +#pragma charmap ($AA, $6A) +#pragma charmap ($AB, $6B) +#pragma charmap ($AC, $6C) +#pragma charmap ($AD, $6D) +#pragma charmap ($AE, $6E) +#pragma charmap ($AF, $6F) +#pragma charmap ($B0, $70) +#pragma charmap ($B1, $71) +#pragma charmap ($B2, $72) +#pragma charmap ($B3, $73) +#pragma charmap ($B4, $74) +#pragma charmap ($B5, $75) +#pragma charmap ($B6, $76) +#pragma charmap ($B7, $77) +#pragma charmap ($B8, $78) +#pragma charmap ($B9, $79) +#pragma charmap ($BA, $7A) +#pragma charmap ($BB, $7B) +#pragma charmap ($BC, $7C) +#pragma charmap ($BD, $7D) +#pragma charmap ($BE, $7E) +#pragma charmap ($BF, $7F) + +// Char $C0 ... $DF -> c - 128 +#pragma charmap ($C0, $40) +#pragma charmap ($C1, $41) +#pragma charmap ($C2, $42) +#pragma charmap ($C3, $43) +#pragma charmap ($C4, $44) +#pragma charmap ($C5, $45) +#pragma charmap ($C6, $46) +#pragma charmap ($C7, $47) +#pragma charmap ($C8, $48) +#pragma charmap ($C9, $49) +#pragma charmap ($CA, $4A) +#pragma charmap ($CB, $4B) +#pragma charmap ($CC, $4C) +#pragma charmap ($CD, $4D) +#pragma charmap ($CE, $4E) +#pragma charmap ($CF, $4F) +#pragma charmap ($D0, $50) +#pragma charmap ($D1, $51) +#pragma charmap ($D2, $52) +#pragma charmap ($D3, $53) +#pragma charmap ($D4, $54) +#pragma charmap ($D5, $55) +#pragma charmap ($D6, $56) +#pragma charmap ($D7, $57) +#pragma charmap ($D8, $58) +#pragma charmap ($D9, $59) +#pragma charmap ($DA, $5A) +#pragma charmap ($DB, $5B) +#pragma charmap ($DC, $5C) +#pragma charmap ($DD, $5D) +#pragma charmap ($DE, $5E) +#pragma charmap ($DF, $5F) + +// Char $E0 ... $FE -> c - 128 +#pragma charmap ($E0, $60) +#pragma charmap ($E1, $61) +#pragma charmap ($E2, $62) +#pragma charmap ($E3, $63) +#pragma charmap ($E4, $64) +#pragma charmap ($E5, $65) +#pragma charmap ($E6, $66) +#pragma charmap ($E7, $67) +#pragma charmap ($E8, $68) +#pragma charmap ($E9, $69) +#pragma charmap ($EA, $6A) +#pragma charmap ($EB, $6B) +#pragma charmap ($EC, $6C) +#pragma charmap ($ED, $6D) +#pragma charmap ($EE, $6E) +#pragma charmap ($EF, $6F) +#pragma charmap ($F0, $70) +#pragma charmap ($F1, $71) +#pragma charmap ($F2, $72) +#pragma charmap ($F3, $73) +#pragma charmap ($F4, $74) +#pragma charmap ($F5, $75) +#pragma charmap ($F6, $76) +#pragma charmap ($F7, $77) +#pragma charmap ($F8, $78) +#pragma charmap ($F9, $79) +#pragma charmap ($FA, $7A) +#pragma charmap ($FB, $7B) +#pragma charmap ($FC, $7C) +#pragma charmap ($FD, $7D) +#pragma charmap ($FE, $7E) +#pragma charmap ($FF, $5E) From 74455508314bc2b007e812ec5f9429496b9fbd5f Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 12 Feb 2019 22:50:49 +0100 Subject: [PATCH 1003/2161] remote TABs in doc/ and test/ --- doc/apple2.sgml | 54 +- doc/apple2enh.sgml | 54 +- doc/ar65.sgml | 45 +- doc/atari2600.sgml | 16 +- doc/atari5200.sgml | 16 +- doc/atmos.sgml | 16 +- doc/c128.sgml | 16 +- doc/c16.sgml | 16 +- doc/c64.sgml | 16 +- doc/ca65.sgml | 772 ++++---- doc/cbm510.sgml | 16 +- doc/cbm610.sgml | 16 +- doc/chrcvt65.sgml | 16 +- doc/cl65.sgml | 38 +- doc/co65.sgml | 20 +- doc/coding.sgml | 58 +- doc/creativision.sgml | 16 +- doc/debugging.sgml | 8 +- doc/gamate.sgml | 16 +- doc/geos.sgml | 110 +- doc/grc65.sgml | 12 +- doc/ld65.sgml | 40 +- doc/library.sgml | 16 +- doc/lynx.sgml | 16 +- doc/nes.sgml | 19 +- doc/od65.sgml | 17 +- doc/osi.sgml | 16 +- doc/pet.sgml | 16 +- doc/plus4.sgml | 16 +- doc/sim65.sgml | 40 +- doc/smc.sgml | 12 +- doc/sp65.sgml | 16 +- doc/supervision.sgml | 16 +- doc/telestrat.sgml | 54 +- doc/using-make.sgml | 6 +- doc/vic20.sgml | 16 +- test/err/front.c | 66 +- test/misc/fields.c | 64 +- test/misc/limits.c | 6 +- test/misc/sitest.c | 2770 +++++++++++++------------- test/ref/8q.c | 48 +- test/ref/array.c | 68 +- test/ref/cc65070303.c | 10 +- test/ref/cc65090726.c | 22 +- test/ref/cc65090910.c | 2 +- test/ref/cc65090913.c | 2 +- test/ref/cf.c | 66 +- test/ref/charconst.c | 28 +- test/ref/charset.c | 128 +- test/ref/divmod.c | 36 +- test/ref/hanoi.c | 82 +- test/ref/incr.c | 44 +- test/ref/init.c | 54 +- test/ref/macro.c | 16 +- test/ref/paranoia.c | 3448 ++++++++++++++++----------------- test/ref/pointer2.c | 48 +- test/ref/sort.c | 64 +- test/ref/spill.c | 4 +- test/ref/stdarg.c | 118 +- test/ref/strptr.c | 100 +- test/ref/struct.c | 86 +- test/ref/switch.c | 240 +-- test/ref/switch2.c | 398 ++-- test/ref/varargs.c | 2 +- test/ref/wf1.c | 102 +- test/ref/yacc.c | 1052 +++++----- test/ref/yacc2.c | 222 +-- test/val/compare5.c | 6 +- test/val/cq22.c | 6 +- test/val/cq241.c | 6 +- test/val/cq243.c | 38 +- test/val/cq244.c | 6 +- test/val/cq25.c | 6 +- test/val/cq26.c | 6 +- test/val/cq4.c | 6 +- test/val/cq61.c | 6 +- test/val/cq626.c | 6 +- test/val/cq71.c | 6 +- test/val/cq714.c | 342 ++-- test/val/cq714b.c | 6 +- test/val/cq715.c | 6 +- test/val/cq72.c | 6 +- test/val/cq757.c | 4 +- test/val/cq7813.c | 6 +- test/val/cq81.c | 6 +- test/val/cq84.c | 10 +- test/val/cq85.c | 22 +- test/val/cq86.c | 6 +- test/val/cq88.c | 6 +- test/val/cq9.c | 4 +- test/val/lz4.c | 8 +- test/val/nestfor.c | 154 +- test/val/postincdec.c | 16 +- test/val/ptrfunc.c | 94 +- test/val/trampoline-params.c | 12 +- test/val/trampoline-varargs.c | 34 +- test/val/trampoline.c | 20 +- 97 files changed, 5956 insertions(+), 5963 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index ac5059902..648ee56db 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -32,7 +32,7 @@ more information. <sect>Binary format<p> The standard binary file format generated by the linker for the -Apple ][ target is an <url name="AppleSingle" +Apple ][ target is an <url name="AppleSingle" url="http://kaiser-edv.de/documents/AppleSingle_AppleDouble.pdf"> file. The default load address is $803. @@ -580,18 +580,18 @@ url="ca65.html" name="assembler manual">. ProDOS associates a file type and an auxiliary type with each file. These type specifications are separate from the file's name, unlike Windows which uses the file name's suffix (a.k.a. - extension) to specify the file type. For example, <tt/.exe/, + extension) to specify the file type. For example, <tt/.exe/, <tt/.doc/, or <tt/.bat/. - The ProDOS low-level - Machine-Language Interface (MLI) functions for creating and opening + The ProDOS low-level + Machine-Language Interface (MLI) functions for creating and opening files require these types to be specified. And if they don't match with the file being opened, the operation may fail. In contrast, the ISO C function <tt/fopen()/ and the POSIX function <tt/open()/ have no parameter to specify either a file type or an auxiliary type. Therefore, some additional mechanism for specifying - the file types is needed. - + the file types is needed. + <tag>Specifying the File Type and Auxiliary Type</tag> There are two global variables provided that allow the file type @@ -603,7 +603,7 @@ url="ca65.html" name="assembler manual">. extern unsigned char _filetype; /* Default: PRODOS_T_BIN */ extern unsigned int _auxtype; /* Default: 0 */ </verb> - </tscreen> + </tscreen> The header file <tt/apple2_filetype.h/ also defines many values that can be used to set these variables. It is included in @@ -614,26 +614,26 @@ url="ca65.html" name="assembler manual">. <tag>Example</tag> A text file cannot be created with just the - standard C functions because they default to the binary type + standard C functions because they default to the binary type <tt/PRODOS_T_BIN/. The <tt/_filetype/ variable must be set to - <tt/PRODOS_T_TXT/ to create a text file. - - For a text file, + <tt/PRODOS_T_TXT/ to create a text file. + + For a text file, <tt/_auxtype/ specifies the record length. A zero record length text file is referred to as a sequential text file. - This is equivalent to text files on + This is equivalent to text files on other operating systems, except that the line terminator is a - carriage return instead of a line-feed (Linux/BSD/MacOS) or + carriage return instead of a line-feed (Linux/BSD/MacOS) or carriage return, line-feed pair (Windows). - - The "sequential" text file terminology is in contrast to a + + The "sequential" text file terminology is in contrast to a "random-access" text file which would - have a fixed-length, non-zero record length, so that the + have a fixed-length, non-zero record length, so that the file position of any individual record can be calculated. - + For this example, the <tt/_auxtype/ does not need to be set because it defaults to - the desired value, which is zero. To be more explicit, + the desired value, which is zero. To be more explicit, <tt/_auxtype/ can also be set to <tt/PRODOS_AUX_T_TXT_SEQ/ which is defined as zero. @@ -670,7 +670,7 @@ url="ca65.html" name="assembler manual">. } } </verb> - </tscreen> + </tscreen> </descrip><p> @@ -686,14 +686,14 @@ 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. +<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/apple2enh.sgml b/doc/apple2enh.sgml index d8d24ea32..d25aa7efe 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -32,7 +32,7 @@ more information. <sect>Binary format<p> The standard binary file format generated by the linker for the -enhanced Apple //e target is an <url name="AppleSingle" +enhanced Apple //e target is an <url name="AppleSingle" url="http://kaiser-edv.de/documents/AppleSingle_AppleDouble.pdf"> file. The default load address is $803. @@ -586,18 +586,18 @@ url="ca65.html" name="assembler manual">. ProDOS associates a file type and an auxiliary type with each file. These type specifications are separate from the file's name, unlike Windows which uses the file name's suffix (a.k.a. - extension) to specify the file type. For example, <tt/.exe/, + extension) to specify the file type. For example, <tt/.exe/, <tt/.doc/, or <tt/.bat/. - The ProDOS low-level - Machine-Language Interface (MLI) functions for creating and opening + The ProDOS low-level + Machine-Language Interface (MLI) functions for creating and opening files require these types to be specified. And if they don't match with the file being opened, the operation may fail. In contrast, the ISO C function <tt/fopen()/ and the POSIX function <tt/open()/ have no parameter to specify either a file type or an auxiliary type. Therefore, some additional mechanism for specifying - the file types is needed. - + the file types is needed. + <tag>Specifying the File Type and Auxiliary Type</tag> There are two global variables provided that allow the file type @@ -609,7 +609,7 @@ url="ca65.html" name="assembler manual">. extern unsigned char _filetype; /* Default: PRODOS_T_BIN */ extern unsigned int _auxtype; /* Default: 0 */ </verb> - </tscreen> + </tscreen> The header file <tt/apple2_filetype.h/ also defines many values that can be used to set these variables. It is included in @@ -620,26 +620,26 @@ url="ca65.html" name="assembler manual">. <tag>Example</tag> A text file cannot be created with just the - standard C functions because they default to the binary type + standard C functions because they default to the binary type <tt/PRODOS_T_BIN/. The <tt/_filetype/ variable must be set to - <tt/PRODOS_T_TXT/ to create a text file. - - For a text file, + <tt/PRODOS_T_TXT/ to create a text file. + + For a text file, <tt/_auxtype/ specifies the record length. A zero record length text file is referred to as a sequential text file. - This is equivalent to text files on + This is equivalent to text files on other operating systems, except that the line terminator is a - carriage return instead of a line-feed (Linux/BSD/MacOS) or + carriage return instead of a line-feed (Linux/BSD/MacOS) or carriage return, line-feed pair (Windows). - - The "sequential" text file terminology is in contrast to a + + The "sequential" text file terminology is in contrast to a "random-access" text file which would - have a fixed-length, non-zero record length, so that the + have a fixed-length, non-zero record length, so that the file position of any individual record can be calculated. - + For this example, the <tt/_auxtype/ does not need to be set because it defaults to - the desired value, which is zero. To be more explicit, + the desired value, which is zero. To be more explicit, <tt/_auxtype/ can also be set to <tt/PRODOS_AUX_T_TXT_SEQ/ which is defined as zero. @@ -676,7 +676,7 @@ url="ca65.html" name="assembler manual">. } } </verb> - </tscreen> + </tscreen> </descrip><p> @@ -692,14 +692,14 @@ 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. +<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/ar65.sgml b/doc/ar65.sgml index df4154539..900a0a92b 100644 --- a/doc/ar65.sgml +++ b/doc/ar65.sgml @@ -30,14 +30,14 @@ for the cc65 compiler. ar65 is part of this suite. The archiver is called as follows: <tscreen><verb> - Usage: ar65 <operation ...> lib file|module ... - Operations are some of: - r Add modules - d Delete modules - t List library table - v Increase verbosity (put before other operation) - x Extract modules - V Print the archiver version + Usage: ar65 <operation ...> lib file|module ... + Operations are some of: + r Add modules + d Delete modules + t List library table + v Increase verbosity (put before other operation) + x Extract modules + V Print the archiver version </verb></tscreen> You may add modules to a library using the <tt/'r'/ command ('a' is deprecated). If the library @@ -52,7 +52,7 @@ has a newer timestamp than the one to add. Here's an example: <tscreen><verb> - ar65 r mysubs.lib sub1.o sub2.o + ar65 r mysubs.lib sub1.o sub2.o </verb></tscreen> This will add two modules to the library 'mysubs.lib' creating the @@ -62,7 +62,7 @@ sub2.o, they are replaced by the new ones. Modules names in the library are stored without the path, so, using <tscreen><verb> - ar65 v v r mysubs.lib ofiles/sub1.o ofiles/sub2.o + ar65 v v r mysubs.lib ofiles/sub1.o ofiles/sub2.o </verb></tscreen> will verbose add two modules named 'sub1.o' and 'sub2.o' to the library. @@ -73,7 +73,7 @@ give a path when naming the modules. Example: <tscreen><verb> - ar65 d mysubs.lib sub1.o + ar65 d mysubs.lib sub1.o </verb></tscreen> This will delete the module named 'sub1.o' from the library, printing an @@ -86,7 +86,7 @@ Any module names on the command line are ignored. Example: <tscreen><verb> - ar65 tv mysubs.lib + ar65 tv mysubs.lib </verb></tscreen> @@ -103,7 +103,7 @@ this is not a problem. Example for extracting a module from the library: <tscreen><verb> - ar65 x mysubs.lib sub1.o + ar65 x mysubs.lib sub1.o </verb></tscreen> @@ -131,17 +131,14 @@ 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. +<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/atari2600.sgml b/doc/atari2600.sgml index 797b1e8be..36c06ad08 100644 --- a/doc/atari2600.sgml +++ b/doc/atari2600.sgml @@ -109,14 +109,14 @@ 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. +<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/atari5200.sgml b/doc/atari5200.sgml index e33c8a832..fedac4466 100644 --- a/doc/atari5200.sgml +++ b/doc/atari5200.sgml @@ -184,14 +184,14 @@ 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. +<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/atmos.sgml b/doc/atmos.sgml index ab7104f9d..3fd61abcf 100644 --- a/doc/atmos.sgml +++ b/doc/atmos.sgml @@ -279,14 +279,14 @@ 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. +<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/c128.sgml b/doc/c128.sgml index 82c280ef0..1d8734fdf 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -397,14 +397,14 @@ 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. +<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/c16.sgml b/doc/c16.sgml index 9f81c5115..462f98345 100644 --- a/doc/c16.sgml +++ b/doc/c16.sgml @@ -259,14 +259,14 @@ 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. +<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/c64.sgml b/doc/c64.sgml index 37ac0c146..c11867051 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -481,14 +481,14 @@ 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. +<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/ca65.sgml b/doc/ca65.sgml index 25c46c4c2..211039995 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -36,42 +36,42 @@ development: <itemize> -<item> The assembler must support macros. Macros are not essential, but they - make some things easier, especially when you use the assembler in the - backend of a compiler. -<item> The assembler must support the newer 65C02 and 65816 CPUs. I have been - thinking about a 65816 backend for the C compiler, and even my old - a816 assembler had support for these CPUs, so this wasn't really a - problem. -<item> The assembler must produce relocatable code. This is necessary for the - compiler support, and it is more convenient. -<item> Conditional assembly must be supported. This is a must for bigger - projects written in assembler (like Elite128). -<item> The assembler must support segments, and it must support more than - three segments (this is the count, most other assemblers support). - Having more than one code segments helps developing code for systems - with a divided ROM area (like the C64). -<item> The linker must be able to resolve arbitrary expressions. It should - be able to get things like +<item> The assembler must support macros. Macros are not essential, but they + make some things easier, especially when you use the assembler in the + backend of a compiler. +<item> The assembler must support the newer 65C02 and 65816 CPUs. I have been + thinking about a 65816 backend for the C compiler, and even my old + a816 assembler had support for these CPUs, so this wasn't really a + problem. +<item> The assembler must produce relocatable code. This is necessary for the + compiler support, and it is more convenient. +<item> Conditional assembly must be supported. This is a must for bigger + projects written in assembler (like Elite128). +<item> The assembler must support segments, and it must support more than + three segments (this is the count, most other assemblers support). + Having more than one code segments helps developing code for systems + with a divided ROM area (like the C64). +<item> The linker must be able to resolve arbitrary expressions. It should + be able to get things like <tscreen><verb> - .import S1, S2 - .export Special - Special = 2*S1 + S2/7 + .import S1, S2 + .export Special + Special = 2*S1 + S2/7 </verb></tscreen> - right. -<item> True lexical nesting for symbols. This is very convenient for larger - assembly projects. -<item> "Cheap" local symbols without lexical nesting for those quick, late - night hacks. -<item> I liked the idea of "options" as Anre Fachats .o65 format has it, so I - introduced the concept into the object file format use by the new cc65 - binutils. -<item> The assembler will be a one pass assembler. There was no real need for - this decision, but I've written several multipass assemblers, and it - started to get boring. A one pass assembler needs much more elaborated - data structures, and because of that it's much more fun:-) -<item> Non-GPLed code that may be used in any project without restrictions or - fear of "GPL infecting" other code. + right. +<item> True lexical nesting for symbols. This is very convenient for larger + assembly projects. +<item> "Cheap" local symbols without lexical nesting for those quick, late + night hacks. +<item> I liked the idea of "options" as Anre Fachats .o65 format has it, so I + introduced the concept into the object file format use by the new cc65 + binutils. +<item> The assembler will be a one pass assembler. There was no real need for + this decision, but I've written several multipass assemblers, and it + started to get boring. A one pass assembler needs much more elaborated + data structures, and because of that it's much more fun:-) +<item> Non-GPLed code that may be used in any project without restrictions or + fear of "GPL infecting" other code. </itemize> <p> @@ -151,7 +151,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, 65SC02, 65C02, 65816, sweet16, HuC6280, 4510 + 6502, 6502X, 65SC02, 65C02, 65816, sweet16, HuC6280, 4510 <label id="option-create-dep"> @@ -403,13 +403,13 @@ it is ignored). Here are some examples for valid input lines: <tscreen><verb> - Label: ; A label and a comment - lda #$20 ; A 6502 instruction plus comment - L1: ldx #$20 ; Same with label - L2: .byte "Hello world" ; Label plus control command - mymac $20 ; Macro expansion - MySym = 3*L1 ; Symbol definition - MaSym = Label ; Another symbol + Label: ; A label and a comment + lda #$20 ; A 6502 instruction plus comment + L1: ldx #$20 ; Same with label + L2: .byte "Hello world" ; Label plus control command + mymac $20 ; Macro expansion + MySym = 3*L1 ; Symbol definition + MaSym = Label ; Another symbol </verb></tscreen> The assembler accepts @@ -565,19 +565,19 @@ case, the assembler has to make some assumptions about the result of an expression: <itemize> -<item> If the result of an expression is constant, the actual value is - checked to see if it's a byte sized expression or not. -<item> If the expression is explicitly casted to a byte sized expression by - one of the '>', '<' or '^' operators, it is a byte expression. -<item> If this is not the case, and the expression contains a symbol, - explicitly declared as zero page symbol (by one of the .importzp or - .exportzp instructions), then the whole expression is assumed to be - byte sized. -<item> If the expression contains symbols that are not defined, and these - symbols are local symbols, the enclosing scopes are searched for a - symbol with the same name. If one exists and this symbol is defined, - its attributes are used to determine the result size. -<item> In all other cases the expression is assumed to be word sized. +<item> If the result of an expression is constant, the actual value is + checked to see if it's a byte sized expression or not. +<item> If the expression is explicitly casted to a byte sized expression by + one of the '>', '<' or '^' operators, it is a byte expression. +<item> If this is not the case, and the expression contains a symbol, + explicitly declared as zero page symbol (by one of the .importzp or + .exportzp instructions), then the whole expression is assumed to be + byte sized. +<item> If the expression contains symbols that are not defined, and these + symbols are local symbols, the enclosing scopes are searched for a + symbol with the same name. If one exists and this symbol is defined, + its attributes are used to determine the result size. +<item> In all other cases the expression is assumed to be word sized. </itemize> Note: If the assembler is not able to evaluate the expression at assembly @@ -786,14 +786,14 @@ You may use cheap local labels as an easy way to reuse common label names like "Loop". Here is an example: <tscreen><verb> - Clear: lda #$00 ; Global label - ldy #$20 - @Loop: sta Mem,y ; Local label - dey - bne @Loop ; Ok - rts - Sub: ... ; New global label - bne @Loop ; ERROR: Unknown identifier! + Clear: lda #$00 ; Global label + ldy #$20 + @Loop: sta Mem,y ; Local label + dey + bne @Loop ; Ok + rts + Sub: ... ; New global label + bne @Loop ; ERROR: Unknown identifier! </verb></tscreen> <sect1>Unnamed labels<p> @@ -809,23 +809,23 @@ reference (use the n'th label in forward direction). An example will help to understand this: <tscreen><verb> - : lda (ptr1),y ; #1 - cmp (ptr2),y - bne :+ ; -> #2 - tax - beq :+++ ; -> #4 - iny - bne :- ; -> #1 - inc ptr1+1 - inc ptr2+1 - bne :- ; -> #1 + : 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 + : bcs :+ ; #2 -> #3 + ldx #$FF + rts - : ldx #$01 ; #3 - : rts ; #4 + : ldx #$01 ; #3 + : rts ; #4 </verb></tscreen> As you can see from the example, unnamed labels will make even short @@ -857,15 +857,15 @@ errors. Because of these problems, the general advice is, <bf/NOT/ do use Example: <tscreen><verb> - .DEFINE two 2 - .DEFINE version "SOS V2.3" + .DEFINE two 2 + .DEFINE version "SOS V2.3" - four = two * two ; Ok - .byte version ; Ok + four = two * two ; Ok + .byte version ; Ok - .PROC ; Start local scope - two = 3 ; Will give "2 = 3" - invalid! - .ENDPROC + .PROC ; Start local scope + two = 3 ; Will give "2 = 3" - invalid! + .ENDPROC </verb></tscreen> @@ -1241,17 +1241,17 @@ writable. Example: <tscreen><verb> - ; Reverse Subtract with Accumulator - ; A = memory - A - .macro rsb param - .if .asize = 8 - eor #$ff - .else - eor #$ffff - .endif - sec - adc param - .endmacro + ; Reverse Subtract with Accumulator + ; A = memory - A + .macro rsb param + .if .asize = 8 + eor #$ff + .else + eor #$ffff + .endif + sec + adc param + .endmacro </verb></tscreen> See also: <tt><ref id=".ISIZE" name=".ISIZE"></tt> @@ -1272,15 +1272,15 @@ writable. <tscreen><verb> .macpack cpu - .if (.cpu .bitand CPU_ISET_65816) - phx - phy - .else - txa - pha - tya - pha - .endif + .if (.cpu .bitand CPU_ISET_65816) + phx + phy + .else + txa + pha + tya + pha + .endif </verb></tscreen> @@ -1305,12 +1305,12 @@ writable. Example: <tscreen><verb> - .macro foo arg1, arg2, arg3 - .if .paramcount <> 3 - .error "Too few parameters for macro foo" - .endif - ... - .endmacro + .macro foo arg1, arg2, arg3 + .if .paramcount <> 3 + .error "Too few parameters for macro foo" + .endif + ... + .endmacro </verb></tscreen> See section <ref id="macros" name="Macros">. @@ -1417,7 +1417,7 @@ either a string or an expression. .endproc .proc bank_table - .addr banked_func_1 + .addr banked_func_1 .byte <.BANK (banked_func_1) .addr banked_func_2 @@ -1449,7 +1449,7 @@ either a string or an expression. As an example, the <tt/.IFBLANK/ statement may be replaced by <tscreen><verb> - .if .blank({arg}) + .if .blank({arg}) </verb></tscreen> @@ -1465,13 +1465,13 @@ either a string or an expression. Example: <tscreen><verb> - .include .concat ("myheader", ".", "inc") + .include .concat ("myheader", ".", "inc") </verb></tscreen> This is the same as the command <tscreen><verb> - .include "myheader.inc" + .include "myheader.inc" </verb></tscreen> @@ -1483,7 +1483,7 @@ either a string or an expression. otherwise. As an example, the .IFCONST statement may be replaced by <tscreen><verb> - .if .const(a + 3) + .if .const(a + 3) </verb></tscreen> @@ -1513,7 +1513,7 @@ either a string or an expression. Example: <tscreen><verb> - .macro makelabel arg1, arg2 + .macro makelabel arg1, arg2 .ident (.concat (arg1, arg2)): .endmacro @@ -1530,7 +1530,7 @@ either a string or an expression. Syntax: <tscreen><verb> - .LEFT (<int expr>, <token list>) + .LEFT (<int expr>, <token list>) </verb></tscreen> The first integer expression gives the number of tokens to extract from @@ -1545,16 +1545,16 @@ either a string or an expression. (immediate addressing mode), use something like this: <tscreen><verb> - .macro ldax arg - ... - .if (.match (.left (1, {arg}), #)) + .macro ldax arg + ... + .if (.match (.left (1, {arg}), #)) - ; ldax called with immediate operand - ... + ; ldax called with immediate operand + ... - .endif - ... - .endmacro + .endif + ... + .endmacro </verb></tscreen> See also the <tt><ref id=".MID" name=".MID"></tt> and <tt><ref id=".RIGHT" @@ -1586,7 +1586,7 @@ either a string or an expression. The syntax is <tscreen><verb> - .MATCH(<token list #1>, <token list #2>) + .MATCH(<token list #1>, <token list #2>) </verb></tscreen> Both token list may contain arbitrary tokens with the exception of the @@ -1617,16 +1617,16 @@ either a string or an expression. to check for this and print and error for invalid calls. <tscreen><verb> - .macro asr arg + .macro asr arg - .if (.not .blank(arg)) .and (.not .match ({arg}, a)) - .error "Syntax error" - .endif + .if (.not .blank(arg)) .and (.not .match ({arg}, a)) + .error "Syntax error" + .endif - cmp #$80 ; Bit 7 into carry - lsr a ; Shift carry into bit 7 + cmp #$80 ; Bit 7 into carry + lsr a ; Shift carry into bit 7 - .endmacro + .endmacro </verb></tscreen> The macro will only accept no arguments, or one argument that must be the @@ -1642,14 +1642,14 @@ either a string or an expression. The syntax is <tscreen><verb> - .MAX (<value #1>, <value #2>) + .MAX (<value #1>, <value #2>) </verb></tscreen> Example: <tscreen><verb> ; Reserve space for the larger of two data blocks - savearea: .res .max (.sizeof (foo), .sizeof (bar)) + savearea: .res .max (.sizeof (foo), .sizeof (bar)) </verb></tscreen> See: <tt><ref id=".MIN" name=".MIN"></tt> @@ -1663,7 +1663,7 @@ either a string or an expression. Syntax: <tscreen><verb> - .MID (<int expr>, <int expr>, <token list>) + .MID (<int expr>, <int expr>, <token list>) </verb></tscreen> The first integer expression gives the starting token in the list (the first @@ -1679,16 +1679,16 @@ either a string or an expression. (immediate addressing mode), use something like this: <tscreen><verb> - .macro ldax arg - ... - .if (.match (.mid (0, 1, {arg}), #)) + .macro ldax arg + ... + .if (.match (.mid (0, 1, {arg}), #)) - ; ldax called with immediate operand - ... + ; ldax called with immediate operand + ... - .endif - ... - .endmacro + .endif + ... + .endmacro </verb></tscreen> See also the <tt><ref id=".LEFT" name=".LEFT"></tt> and <tt><ref id=".RIGHT" @@ -1702,14 +1702,14 @@ either a string or an expression. The syntax is <tscreen><verb> - .MIN (<value #1>, <value #2>) + .MIN (<value #1>, <value #2>) </verb></tscreen> Example: <tscreen><verb> ; Reserve space for some data, but 256 bytes maximum - savearea: .res .min (.sizeof (foo), 256) + savearea: .res .min (.sizeof (foo), 256) </verb></tscreen> See: <tt><ref id=".MAX" name=".MAX"></tt> @@ -1724,7 +1724,7 @@ either a string or an expression. the <tt><ref id=".IFREF" name=".IFREF"></tt> statement may be replaced by <tscreen><verb> - .if .referenced(a) + .if .referenced(a) </verb></tscreen> See: <tt><ref id=".DEFINED" name=".DEFINED"></tt> @@ -1737,7 +1737,7 @@ either a string or an expression. Syntax: <tscreen><verb> - .RIGHT (<int expr>, <token list>) + .RIGHT (<int expr>, <token list>) </verb></tscreen> The first integer expression gives the number of tokens to extract from the @@ -1833,12 +1833,12 @@ either a string or an expression. Example: <tscreen><verb> - .macro M Arg - ; Check if the argument string starts with '#' - .if (.strat (Arg, 0) = '#') - ... - .endif - .endmacro + .macro M Arg + ; Check if the argument string starts with '#' + .if (.strat (Arg, 0) = '#') + ... + .endif + .endmacro </verb></tscreen> @@ -1873,10 +1873,10 @@ either a string or an expression. Example: <tscreen><verb> - ; Emulate other assemblers: - .macro section name - .segment .string(name) - .endmacro + ; Emulate other assemblers: + .macro section name + .segment .string(name) + .endmacro </verb></tscreen> @@ -1891,9 +1891,9 @@ either a string or an expression. a leading length byte. <tscreen><verb> - .macro PString Arg - .byte .strlen(Arg), Arg - .endmacro + .macro PString Arg + .byte .strlen(Arg), Arg + .endmacro </verb></tscreen> @@ -1913,15 +1913,15 @@ either a string or an expression. load instructions, the '#' token has to get stripped from the argument: <tscreen><verb> - .macro ldax arg - .if (.match (.mid (0, 1, {arg}), #)) - ; ldax called with immediate operand - lda #<(.right (.tcount ({arg})-1, {arg})) - ldx #>(.right (.tcount ({arg})-1, {arg})) - .else - ... - .endif - .endmacro + .macro ldax arg + .if (.match (.mid (0, 1, {arg}), #)) + ; ldax called with immediate operand + lda #<(.right (.tcount ({arg})-1, {arg})) + ldx #>(.right (.tcount ({arg})-1, {arg})) + .else + ... + .endif + .endmacro </verb></tscreen> @@ -1934,7 +1934,7 @@ either a string or an expression. The syntax is <tscreen><verb> - .XMATCH(<token list #1>, <token list #2>) + .XMATCH(<token list #1>, <token list #2>) </verb></tscreen> Both token list may contain arbitrary tokens with the exception of the @@ -1994,7 +1994,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .addr $0D00, $AF13, _Clear + .addr $0D00, $AF13, _Clear </verb></tscreen> See: <tt><ref id=".FARADDR" name=".FARADDR"></tt>, <tt><ref id=".WORD" @@ -2022,7 +2022,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .align 256 + .align 256 </verb></tscreen> Some unexpected behaviour might occur if there are multiple <tt/.ALIGN/ @@ -2077,7 +2077,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - Msg: .asciiz "Hello world" + Msg: .asciiz "Hello world" </verb></tscreen> This will put the string "Hello world" followed by a binary zero into @@ -2099,7 +2099,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .assert * = $8000, error, "Code not at $8000" + .assert * = $8000, error, "Code not at $8000" </verb></tscreen> The example assertion will check that the current location is at $8000, @@ -2131,7 +2131,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .autoimport + ; Switch on auto import + .autoimport + ; Switch on auto import </verb></tscreen> <sect1><tt>.BANKBYTES</tt><label id=".BANKBYTES"><p> @@ -2145,17 +2145,17 @@ Here's a list of all control commands and a description, what they do: <tscreen><verb> .define MyTable TableItem0, TableItem1, TableItem2, TableItem3 - TableLookupLo: .lobytes MyTable - TableLookupHi: .hibytes MyTable - TableLookupBank: .bankbytes MyTable + TableLookupLo: .lobytes MyTable + TableLookupHi: .hibytes MyTable + TableLookupBank: .bankbytes MyTable </verb></tscreen> which is equivalent to <tscreen><verb> TableLookupLo: .byte <TableItem0, <TableItem1, <TableItem2, <TableItem3 - TableLookupHi: .byte >TableItem0, >TableItem1, >TableItem2, >TableItem3 - TableLookupBank: .byte ^TableItem0, ^TableItem1, ^TableItem2, ^TableItem3 + TableLookupHi: .byte >TableItem0, >TableItem1, >TableItem2, >TableItem3 + TableLookupBank: .byte ^TableItem0, ^TableItem1, ^TableItem2, ^TableItem3 </verb></tscreen> See also: <tt><ref id=".BYTE" name=".BYTE"></tt>, @@ -2169,7 +2169,7 @@ Here's a list of all control commands and a description, what they do: so this is a shortcut for <tscreen><verb> - .segment "BSS" + .segment "BSS" </verb></tscreen> See also the <tt><ref id=".SEGMENT" name=".SEGMENT"></tt> command. @@ -2183,8 +2183,8 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .byte "Hello " - .byt "world", $0D, $00 + .byte "Hello " + .byt "world", $0D, $00 </verb></tscreen> @@ -2199,7 +2199,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .case - ; Identifiers are not case sensitive + .case - ; Identifiers are not case sensitive </verb></tscreen> @@ -2224,7 +2224,7 @@ Here's a list of all control commands and a description, what they do: "CODE", so this is a shortcut for <tscreen><verb> - .segment "CODE" + .segment "CODE" </verb></tscreen> See also the <tt><ref id=".SEGMENT" name=".SEGMENT"></tt> command. @@ -2260,8 +2260,8 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .condes ModuleInit, constructor - .condes ModInit, 0, 16 + .condes ModuleInit, constructor + .condes ModInit, 0, 16 </verb></tscreen> See the <tt><ref id=".CONSTRUCTOR" name=".CONSTRUCTOR"></tt>, <tt><ref @@ -2292,8 +2292,8 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .constructor ModuleInit - .constructor ModInit, 16 + .constructor ModuleInit + .constructor ModInit, 16 </verb></tscreen> See the <tt><ref id=".CONDES" name=".CONDES"></tt> and <tt><ref @@ -2308,7 +2308,7 @@ Here's a list of all control commands and a description, what they do: "DATA", so this is a shortcut for <tscreen><verb> - .segment "DATA" + .segment "DATA" </verb></tscreen> See also the <tt><ref id=".SEGMENT" name=".SEGMENT"></tt> command. @@ -2323,13 +2323,13 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .dbyt $1234, $4512 + .dbyt $1234, $4512 </verb></tscreen> This will emit the bytes <tscreen><verb> - $12 $34 $45 $12 + $12 $34 $45 $12 </verb></tscreen> into the current segment in that order. @@ -2346,7 +2346,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .debuginfo + ; Generate debug info + .debuginfo + ; Generate debug info </verb></tscreen> @@ -2387,7 +2387,7 @@ Here's a list of all control commands and a description, what they do: <tt><ref id=".IFDEF" name=".IFDEF"></tt> statement may be replaced by <tscreen><verb> - .if .defined(a) + .if .defined(a) </verb></tscreen> @@ -2404,7 +2404,7 @@ Here's a list of all control commands and a description, what they do: adc foo .endmacro - .if .definedmacro(add) + .if .definedmacro(add) add #$01 .else clc @@ -2434,8 +2434,8 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .destructor ModuleDone - .destructor ModDone, 16 + .destructor ModuleDone + .destructor ModDone, 16 </verb></tscreen> See the <tt><ref id=".CONDES" name=".CONDES"></tt> and <tt><ref @@ -2452,7 +2452,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .dword $12344512, $12FA489 + .dword $12344512, $12FA489 </verb></tscreen> @@ -2595,13 +2595,13 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .if foo = 1 - ... - .elseif bar = 1 - ... - .else - .error "Must define foo or bar!" - .endif + .if foo = 1 + ... + .elseif bar = 1 + ... + .else + .error "Must define foo or bar!" + .endif </verb></tscreen> See also: <tt><ref id=".FATAL" name=".FATAL"></tt>, @@ -2634,7 +2634,7 @@ Here's a list of all control commands and a description, what they do: Examples: <tscreen><verb> - .export foo + .export foo .export bar: far .export foobar: far = foo * bar .export baz := foobar, zap: far = baz - bar @@ -2657,7 +2657,7 @@ Here's a list of all control commands and a description, what they do: Examples: <tscreen><verb> - .exportzp foo, bar + .exportzp foo, bar .exportzp baz := $02 </verb></tscreen> @@ -2672,7 +2672,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .faraddr DrawCircle, DrawRectangle, DrawHexagon + .faraddr DrawCircle, DrawRectangle, DrawHexagon </verb></tscreen> See: <tt><ref id=".ADDR" name=".ADDR"></tt> @@ -2690,13 +2690,13 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .if foo = 1 - ... - .elseif bar = 1 - ... - .else - .fatal "Must define foo or bar!" - .endif + .if foo = 1 + ... + .elseif bar = 1 + ... + .else + .fatal "Must define foo or bar!" + .endif </verb></tscreen> See also: <tt><ref id=".ERROR" name=".ERROR"></tt>, @@ -2713,7 +2713,7 @@ Here's a list of all control commands and a description, what they do: enabled it, so using <tscreen><verb> - .FEATURE xxx + .FEATURE xxx </verb></tscreen> will enable the feature until end of assembly is reached. @@ -2877,7 +2877,7 @@ Here's a list of all control commands and a description, what they do: assembler, the features <verb> - labels_without_colons, pc_assignment, loose_char_term + labels_without_colons, pc_assignment, loose_char_term </verb> may be helpful. They do not make ca65 completely compatible, so you may not @@ -2897,9 +2897,9 @@ Here's a list of all control commands and a description, what they do: The command is followed by one of the keywords <tscreen><verb> - author - comment - compiler + author + comment + compiler </verb></tscreen> a comma and a string. The option is written into the object file @@ -2910,9 +2910,9 @@ Here's a list of all control commands and a description, what they do: Examples: <tscreen><verb> - .fileopt comment, "Code stolen from my brother" - .fileopt compiler, "BASIC 2.0" - .fopt author, "J. R. User" + .fileopt comment, "Code stolen from my brother" + .fileopt compiler, "BASIC 2.0" + .fopt author, "J. R. User" </verb></tscreen> @@ -2928,7 +2928,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .forceimport needthisone, needthistoo + .forceimport needthisone, needthistoo </verb></tscreen> See: <tt><ref id=".IMPORT" name=".IMPORT"></tt> @@ -2945,7 +2945,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .global foo, bar + .global foo, bar </verb></tscreen> @@ -2961,7 +2961,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .globalzp foo, bar + .globalzp foo, bar </verb></tscreen> <sect1><tt>.HIBYTES</tt><label id=".HIBYTES"><p> @@ -2974,14 +2974,14 @@ Here's a list of all control commands and a description, what they do: <tscreen><verb> .lobytes $1234, $2345, $3456, $4567 - .hibytes $fedc, $edcb, $dcba, $cba9 + .hibytes $fedc, $edcb, $dcba, $cba9 </verb></tscreen> which is equivalent to <tscreen><verb> .byte $34, $45, $56, $67 - .byte $fe, $ed, $dc, $cb + .byte $fe, $ed, $dc, $cb </verb></tscreen> Example: @@ -2989,15 +2989,15 @@ Here's a list of all control commands and a description, what they do: <tscreen><verb> .define MyTable TableItem0, TableItem1, TableItem2, TableItem3 - TableLookupLo: .lobytes MyTable - TableLookupHi: .hibytes MyTable + TableLookupLo: .lobytes MyTable + TableLookupHi: .hibytes MyTable </verb></tscreen> which is equivalent to <tscreen><verb> TableLookupLo: .byte <TableItem0, <TableItem1, <TableItem2, <TableItem3 - TableLookupHi: .byte >TableItem0, >TableItem1, >TableItem2, >TableItem3 + TableLookupHi: .byte >TableItem0, >TableItem1, >TableItem2, >TableItem3 </verb></tscreen> See also: <tt><ref id=".BYTE" name=".BYTE"></tt>, @@ -3052,13 +3052,13 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .macro arg1, arg2 - .ifblank arg2 - lda #arg1 - .else - lda #arg2 - .endif - .endmacro + .macro arg1, arg2 + .ifblank arg2 + lda #arg1 + .else + lda #arg2 + .endif + .endmacro </verb></tscreen> See also: <tt><ref id=".BLANK" name=".BLANK"></tt> @@ -3100,12 +3100,12 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .macro arg1, arg2 - lda #arg1 - .ifnblank arg2 - lda #arg2 - .endif - .endmacro + .macro arg1, arg2 + lda #arg1 + .ifnblank arg2 + lda #arg2 + .endif + .endmacro </verb></tscreen> See also: <tt><ref id=".BLANK" name=".BLANK"></tt> @@ -3171,11 +3171,11 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .ifref ToHex ; If someone used this subroutine - ToHex: tay ; Define subroutine - lda HexTab,y - rts - .endif + .ifref ToHex ; If someone used this subroutine + ToHex: tay ; Define subroutine + lda HexTab,y + rts + .endif </verb></tscreen> See also: <tt><ref id=".REFERENCED" name=".REFERENCED"></tt> @@ -3190,7 +3190,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .import foo + .import foo .import bar: zeropage </verb></tscreen> @@ -3206,7 +3206,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .importzp foo, bar + .importzp foo, bar </verb></tscreen> See: <tt><ref id=".IMPORT" name=".IMPORT"></tt> @@ -3224,14 +3224,14 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - ; Include whole file - .incbin "sprites.dat" + ; Include whole file + .incbin "sprites.dat" - ; Include file starting at offset 256 - .incbin "music.dat", $100 + ; Include file starting at offset 256 + .incbin "music.dat", $100 - ; Read 100 bytes starting at offset 200 - .incbin "graphics.dat", 200, 100 + ; Read 100 bytes starting at offset 200 + .incbin "graphics.dat", 200, 100 </verb></tscreen> @@ -3242,7 +3242,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .include "subs.inc" + .include "subs.inc" </verb></tscreen> @@ -3267,8 +3267,8 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .interruptor IrqHandler - .interruptor Handler, 16 + .interruptor IrqHandler + .interruptor Handler, 16 </verb></tscreen> See the <tt><ref id=".CONDES" name=".CONDES"></tt> command and the separate @@ -3284,12 +3284,12 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .if .not .ismnemonic(ina) - .macro ina - clc - adc #$01 - .endmacro - .endif + .if .not .ismnemonic(ina) + .macro ina + clc + adc #$01 + .endmacro + .endif </verb></tscreen> @@ -3306,10 +3306,10 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .linecont + ; Allow line continuations + .linecont + ; Allow line continuations - lda \ - #$20 ; This is legal now + lda \ + #$20 ; This is legal now </verb></tscreen> @@ -3327,7 +3327,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .list on ; Enable listing output + .list on ; Enable listing output </verb></tscreen> @@ -3342,9 +3342,9 @@ Here's a list of all control commands and a description, what they do: Examples: <tscreen><verb> - .listbytes unlimited ; List all bytes - .listbytes 12 ; List the first 12 bytes - .incbin "data.bin" ; Include large binary file + .listbytes unlimited ; List all bytes + .listbytes 12 ; List the first 12 bytes + .incbin "data.bin" ; Include large binary file </verb></tscreen> @@ -3358,14 +3358,14 @@ Here's a list of all control commands and a description, what they do: <tscreen><verb> .lobytes $1234, $2345, $3456, $4567 - .hibytes $fedc, $edcb, $dcba, $cba9 + .hibytes $fedc, $edcb, $dcba, $cba9 </verb></tscreen> which is equivalent to <tscreen><verb> .byte $34, $45, $56, $67 - .byte $fe, $ed, $dc, $cb + .byte $fe, $ed, $dc, $cb </verb></tscreen> Example: @@ -3373,15 +3373,15 @@ Here's a list of all control commands and a description, what they do: <tscreen><verb> .define MyTable TableItem0, TableItem1, TableItem2, TableItem3 - TableLookupLo: .lobytes MyTable - TableLookupHi: .hibytes MyTable + TableLookupLo: .lobytes MyTable + TableLookupHi: .hibytes MyTable </verb></tscreen> which is equivalent to <tscreen><verb> TableLookupLo: .byte <TableItem0, <TableItem1, <TableItem2, <TableItem3 - TableLookupHi: .byte >TableItem0, >TableItem1, >TableItem2, >TableItem3 + TableLookupHi: .byte >TableItem0, >TableItem1, >TableItem2, >TableItem3 </verb></tscreen> See also: <tt><ref id=".BYTE" name=".BYTE"></tt>, @@ -3422,15 +3422,15 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .localchar '?' + .localchar '?' - Clear: lda #$00 ; Global label - ?Loop: sta Mem,y ; Local label - dey - bne ?Loop ; Ok - rts - Sub: ... ; New global label - bne ?Loop ; ERROR: Unknown identifier! + Clear: lda #$00 ; Global label + ?Loop: sta Mem,y ; Local label + dey + bne ?Loop ; Ok + rts + Sub: ... ; New global label + bne ?Loop ; ERROR: Unknown identifier! </verb></tscreen> @@ -3454,10 +3454,10 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .macpack longbranch ; Include macro package + .macpack longbranch ; Include macro package - cmp #$20 ; Set condition codes - jne Label ; Jump long on condition + cmp #$20 ; Set condition codes + jne Label ; Jump long on condition </verb></tscreen> Macro packages are explained in more detail in section <ref @@ -3474,7 +3474,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .macro ldax arg ; Define macro ldax + .macro ldax arg ; Define macro ldax lda arg ldx arg+1 </verb></tscreen> @@ -3504,7 +3504,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .org $7FF ; Emit code starting at $7FF + .org $7FF ; Emit code starting at $7FF </verb></tscreen> @@ -3517,7 +3517,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .out "This code was written by the codebuster(tm)" + .out "This code was written by the codebuster(tm)" </verb></tscreen> See also: <tt><ref id=".ERROR" name=".ERROR"></tt>, @@ -3569,9 +3569,9 @@ Here's a list of all control commands and a description, what they do: Examples: <tscreen><verb> - .pagelength 66 ; Use 66 lines per listing page + .pagelength 66 ; Use 66 lines per listing page - .pagelength unlimited ; Unlimited page length + .pagelength unlimited ; Unlimited page length </verb></tscreen> @@ -3634,15 +3634,15 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .proc Clear ; Define Clear subroutine, start new level - lda #$00 - L1: sta Mem,y ; L1 is local and does not cause a - ; duplicate symbol error if used in other - ; places - dey - bne L1 ; Reference local symbol - rts - .endproc ; Leave lexical level + .proc Clear ; Define Clear subroutine, start new level + lda #$00 + L1: sta Mem,y ; L1 is local and does not cause a + ; duplicate symbol error if used in other + ; places + dey + bne L1 ; Reference local symbol + rts + .endproc ; Leave lexical level </verb></tscreen> See: <tt/<ref id=".ENDPROC" name=".ENDPROC">/ and <tt/<ref id=".SCOPE" @@ -3717,11 +3717,11 @@ Here's a list of all control commands and a description, what they do: characters of the string are XORed by the value $55. <tscreen><verb> - .macro Crypt Arg - .repeat .strlen(Arg), I - .byte .strat(Arg, I) ^ $55 - .endrep - .endmacro + .macro Crypt Arg + .repeat .strlen(Arg), I + .byte .strat(Arg, I) ^ $55 + .endrep + .endmacro </verb></tscreen> See: <tt><ref id=".ENDREPEAT" name=".ENDREPEAT"></tt> @@ -3739,8 +3739,8 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - ; Reserve 12 bytes of memory with value $AA - .res 12, $AA + ; Reserve 12 bytes of memory with value $AA + .res 12, $AA </verb></tscreen> @@ -3750,7 +3750,7 @@ Here's a list of all control commands and a description, what they do: "RODATA", so this is a shortcut for <tscreen><verb> - .segment "RODATA" + .segment "RODATA" </verb></tscreen> The RODATA segment is a segment that is used by the compiler for @@ -3778,11 +3778,11 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .scope Error ; Start new scope named Error + .scope Error ; Start new scope named Error None = 0 ; No error File = 1 ; File error Parse = 2 ; Parse error - .endscope ; Close lexical level + .endscope ; Close lexical level ... lda #Error::File ; Use symbol from scope Error @@ -3825,10 +3825,10 @@ Here's a list of all control commands and a description, what they do: Examples: <tscreen><verb> - .segment "ROM2" ; Switch to ROM2 segment - .segment "ZP2": zeropage ; New direct segment - .segment "ZP2" ; Ok, will use last attribute - .segment "ZP2": absolute ; Error, redecl mismatch + .segment "ROM2" ; Switch to ROM2 segment + .segment "ZP2": zeropage ; New direct segment + .segment "ZP2" ; Ok, will use last attribute + .segment "ZP2": absolute ; Error, redecl mismatch </verb></tscreen> See: <tt><ref id=".BSS" name=".BSS"></tt>, <tt><ref id=".CODE" @@ -3888,8 +3888,8 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .smart ; Be smart - .smart - ; Stop being smart + .smart ; Be smart + .smart - ; Stop being smart </verb></tscreen> See: <tt><ref id=".A16" name=".A16"></tt>, @@ -3959,17 +3959,17 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .macro jne target - .local L1 - .ifndef target - .warning "Forward jump in jne, cannot optimize!" - beq L1 - jmp target - L1: - .else - ... - .endif - .endmacro + .macro jne target + .local L1 + .ifndef target + .warning "Forward jump in jne, cannot optimize!" + beq L1 + jmp target + L1: + .else + ... + .endif + .endmacro </verb></tscreen> See also: <tt><ref id=".ERROR" name=".ERROR"></tt>, @@ -3985,7 +3985,7 @@ Here's a list of all control commands and a description, what they do: Example: <tscreen><verb> - .word $0D00, $AF13, _Clear + .word $0D00, $AF13, _Clear </verb></tscreen> @@ -4306,41 +4306,41 @@ different: <itemize> -<item> Macros defined with <tt><ref id=".DEFINE" name=".DEFINE"></tt> may not - span more than a line. You may use line continuation (see <tt><ref - id=".LINECONT" name=".LINECONT"></tt>) to spread the definition over - more than one line for increased readability, but the macro itself - may not contain an end-of-line token. +<item> Macros defined with <tt><ref id=".DEFINE" name=".DEFINE"></tt> may not + span more than a line. You may use line continuation (see <tt><ref + id=".LINECONT" name=".LINECONT"></tt>) to spread the definition over + more than one line for increased readability, but the macro itself + may not contain an end-of-line token. -<item> Macros defined with <tt><ref id=".DEFINE" name=".DEFINE"></tt> share - the name space with classic macros, but they are detected and replaced - at the scanner level. While classic macros may be used in every place, - where a mnemonic or other directive is allowed, <tt><ref id=".DEFINE" - name=".DEFINE"></tt> style macros are allowed anywhere in a line. So - they are more versatile in some situations. +<item> Macros defined with <tt><ref id=".DEFINE" name=".DEFINE"></tt> share + the name space with classic macros, but they are detected and replaced + at the scanner level. While classic macros may be used in every place, + where a mnemonic or other directive is allowed, <tt><ref id=".DEFINE" + name=".DEFINE"></tt> style macros are allowed anywhere in a line. So + they are more versatile in some situations. -<item> <tt><ref id=".DEFINE" name=".DEFINE"></tt> style macros may take - parameters. While classic macros may have empty parameters, this is - not true for <tt><ref id=".DEFINE" name=".DEFINE"></tt> style macros. - For this macro type, the number of actual parameters must match - exactly the number of formal parameters. +<item> <tt><ref id=".DEFINE" name=".DEFINE"></tt> style macros may take + parameters. While classic macros may have empty parameters, this is + not true for <tt><ref id=".DEFINE" name=".DEFINE"></tt> style macros. + For this macro type, the number of actual parameters must match + exactly the number of formal parameters. - To make this possible, formal parameters are enclosed in braces when - defining the macro. If there are no parameters, the empty braces may - be omitted. + To make this possible, formal parameters are enclosed in braces when + defining the macro. If there are no parameters, the empty braces may + be omitted. -<item> Since <tt><ref id=".DEFINE" name=".DEFINE"></tt> style macros may not - contain end-of-line tokens, there are things that cannot be done. They - may not contain several processor instructions for example. So, while - some things may be done with both macro types, each type has special - usages. The types complement each other. +<item> Since <tt><ref id=".DEFINE" name=".DEFINE"></tt> style macros may not + contain end-of-line tokens, there are things that cannot be done. They + may not contain several processor instructions for example. So, while + some things may be done with both macro types, each type has special + usages. The types complement each other. -<item> Parentheses work differently from C macros. - The common practice of wrapping C macros in parentheses may cause - unintended problems here, such as accidentally implying an - indirect addressing mode. While the definition of a macro requires - parentheses around its argument list, when invoked they should not be - included. +<item> Parentheses work differently from C macros. + The common practice of wrapping C macros in parentheses may cause + unintended problems here, such as accidentally implying an + indirect addressing mode. While the definition of a macro requires + parentheses around its argument list, when invoked they should not be + included. </itemize> @@ -4484,14 +4484,14 @@ Currently defined macroes are: <tscreen><verb> .macro add Arg ; add without carry - clc - adc Arg - .endmacro + clc + adc Arg + .endmacro .macro sub Arg ; subtract without borrow - sec - sbc Arg - .endmacro + sec + sbc Arg + .endmacro .macro bge Arg ; branch on greater-than or equal bcs Arg @@ -4531,14 +4531,14 @@ definition for the "<tt/jeq/" macro, the other macros are built using the same scheme: <tscreen><verb> - .macro jeq Target - .if .def(Target) .and ((*+2)-(Target) <= 127) - beq Target - .else - bne *+5 - jmp Target - .endif - .endmacro + .macro jeq Target + .if .def(Target) .and ((*+2)-(Target) <= 127) + beq Target + .else + bne *+5 + jmp Target + .endif + .endmacro </verb></tscreen> All macros expand to a short branch, if the label is already defined (back @@ -4549,7 +4549,7 @@ jump to the actual branch target. The package defines the following macros: <tscreen><verb> - jeq, jne, jmi, jpl, jcs, jcc, jvs, jvc + jeq, jne, jmi, jpl, jcs, jcc, jvs, jvc </verb></tscreen> @@ -4980,14 +4980,14 @@ 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. +<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> diff --git a/doc/cbm510.sgml b/doc/cbm510.sgml index 600a1fe90..1ec0e05d4 100644 --- a/doc/cbm510.sgml +++ b/doc/cbm510.sgml @@ -322,14 +322,14 @@ 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. +<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/cbm610.sgml b/doc/cbm610.sgml index 68b1060ad..37a445dd1 100644 --- a/doc/cbm610.sgml +++ b/doc/cbm610.sgml @@ -304,14 +304,14 @@ 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. +<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/chrcvt65.sgml b/doc/chrcvt65.sgml index 0a2fc2f76..a631a0004 100644 --- a/doc/chrcvt65.sgml +++ b/doc/chrcvt65.sgml @@ -102,14 +102,14 @@ 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. +<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/cl65.sgml b/doc/cl65.sgml index c6761ed9e..0291f2eb3 100644 --- a/doc/cl65.sgml +++ b/doc/cl65.sgml @@ -236,14 +236,14 @@ package, it tries to be smart about several things. <itemize> -<item> If you don't give a target system on the command line, cl65 - defaults to the C64. +<item> If you don't give a target system on the command line, cl65 + defaults to the C64. <item> When linking, cl65 will supply the name of the library file for the target system to the linker; so, you don't have to do that. -<item> If the final step is the linker, and the name of the output file was - not explicitly given, cl65 will use the name of the first input file +<item> If the final step is the linker, and the name of the output file was + not explicitly given, cl65 will use the name of the first input file without the extension, provided that the name of that file has an extension. So, you don't need to give the executable name in most cases; just give the name of your "main" file as the first input file. @@ -284,24 +284,24 @@ assembler file (irq.s) will need the following separate steps to compile into an executable named morse: <tscreen><verb> - cc65 -g -Oi -t c64 morse.c - ca65 -g morse.s - ca65 -g irq.s - ld65 -o morse -t c64 c64.o morse.o irq.o c64.lib + cc65 -g -Oi -t c64 morse.c + ca65 -g morse.s + ca65 -g irq.s + ld65 -o morse -t c64 c64.o morse.o irq.o c64.lib </verb></tscreen> When using cl65, this is simplified to <tscreen><verb> - cl65 -g -Oi morse.c irq.s + cl65 -g -Oi morse.c irq.s </verb></tscreen> As a general rule, you may use cl65 instead of cc65 at most times, especially in makefiles to build object files directly from C files. Use <tscreen><verb> - .c.o: - cl65 -g -Oi $< + .c.o: + cl65 -g -Oi $< </verb></tscreen> to do this. @@ -323,14 +323,14 @@ 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. +<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> diff --git a/doc/co65.sgml b/doc/co65.sgml index 06bdbe191..865aed2bb 100644 --- a/doc/co65.sgml +++ b/doc/co65.sgml @@ -285,7 +285,7 @@ segment. Use the assembler to generate an object file from the assembler output. <tscreen><verb> - co65 --code-label _c64_hi c64-hi.tgi + co65 --code-label _c64_hi c64-hi.tgi ca65 c64-hi.s </verb></tscreen> @@ -293,7 +293,7 @@ Next, change your C code to declare a variable that is actually the address of the driver: <tscreen><verb> - extern void c64_hi[]; + extern void c64_hi[]; </verb></tscreen> Instead of loading and unloading the driver, change the code to install and @@ -329,14 +329,14 @@ 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. +<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/coding.sgml b/doc/coding.sgml index 5897837c4..dc07c091a 100644 --- a/doc/coding.sgml +++ b/doc/coding.sgml @@ -127,17 +127,17 @@ and predecrement operators if you don't need the resulting value. That means, use <tscreen><verb> - ... - ++i; - ... + ... + ++i; + ... </verb></tscreen> instead of <tscreen><verb> - ... - i++; - ... + ... + i++; + ... </verb></tscreen> @@ -148,24 +148,24 @@ The compiler produces optimized code, if the value of a pointer is a constant. So, to access direct memory locations, use <tscreen><verb> - #define VDC_STATUS 0xD601 - *(char*)VDC_STATUS = 0x01; + #define VDC_STATUS 0xD601 + *(char*)VDC_STATUS = 0x01; </verb></tscreen> That will be translated to <tscreen><verb> - lda #$01 - sta $D601 + lda #$01 + sta $D601 </verb></tscreen> The constant value detection works also for struct pointers and arrays, if the subscript is a constant. So <tscreen><verb> - #define VDC ((unsigned char*)0xD600) - #define STATUS 0x01 - VDC[STATUS] = 0x01; + #define VDC ((unsigned char*)0xD600) + #define STATUS 0x01 + VDC[STATUS] = 0x01; </verb></tscreen> will also work. @@ -182,14 +182,14 @@ Initialization of local variables when declaring them gives shorter and faster code. So, use <tscreen><verb> - int i = 1; + int i = 1; </verb></tscreen> instead of <tscreen><verb> - int i; - i = 1; + int i; + i = 1; </verb></tscreen> But beware: To maximize your savings, don't mix uninitialized and initialized @@ -201,18 +201,18 @@ variables, you force the compiler to allocate space for the uninitialized variables each time, it parses an initialized one. So do this: <tscreen><verb> - int i, j; - int a = 3; - int b = 0; + int i, j; + int a = 3; + int b = 0; </verb></tscreen> instead of <tscreen><verb> - int i; - int a = 3; - int j; - int b = 0; + int i; + int a = 3; + int j; + int b = 0; </verb></tscreen> The latter will work, but will create larger and slower code. @@ -228,17 +228,17 @@ common cases. Don't use <tscreen><verb> - char* a; - char b, c; - char b = *(a + c); + char* a; + char b, c; + char b = *(a + c); </verb></tscreen> Use <tscreen><verb> - char* a; - char b, c; - char b = a[c]; + char* a; + char b, c; + char b = a[c]; </verb></tscreen> instead. diff --git a/doc/creativision.sgml b/doc/creativision.sgml index a701ae1ce..f7e5de8b1 100644 --- a/doc/creativision.sgml +++ b/doc/creativision.sgml @@ -168,14 +168,14 @@ 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. +<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/debugging.sgml b/doc/debugging.sgml index 7f2c3af5a..8b09db384 100644 --- a/doc/debugging.sgml +++ b/doc/debugging.sgml @@ -109,7 +109,7 @@ Load your program, then enter the monitor and use the "<tt/ll/" command to load your label file like this: <tscreen><verb> - ll "hello.lbl" + ll "hello.lbl" </verb></tscreen> You will get lots of warnings and even a few errors. You may ignore safely all @@ -120,7 +120,7 @@ After loading the labels, they are used by VICE in the disassembler listing, and you may use them whereever you need to specify an address. Try <tscreen><verb> - d ._main + d ._main </verb></tscreen> as an example (note that VICE needs a leading dot before all labels, and that @@ -134,14 +134,14 @@ Load your program, then enter the monitor and use the "<tt/sl/" command to load your label file like this: <tscreen><verb> - sl hello.sym + sl hello.sym </verb></tscreen> After loading the labels, they are used by Oricutron in the disassembler listing, and you may use them whereever you need to specify an address. Try <tscreen><verb> - d ._main + d ._main </verb></tscreen> as an example (note that VICE needs a leading dot before all labels, and that diff --git a/doc/gamate.sgml b/doc/gamate.sgml index e5e3acbdd..8e18ab76d 100644 --- a/doc/gamate.sgml +++ b/doc/gamate.sgml @@ -138,14 +138,14 @@ 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. +<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/geos.sgml b/doc/geos.sgml index eb8d74939..ec9d66b1a 100644 --- a/doc/geos.sgml +++ b/doc/geos.sgml @@ -68,19 +68,19 @@ programs. The software needed: <itemize> <item><em/cc65/ Excellent package containing a C crosscompiler, a crossassembler and a linker, you - can get it from: <url url="https://cc65.github.io/">. + can get it from: <url url="https://cc65.github.io/">. <item><em/VICE/ This is a portable C64, C128 and few other Commodore computers emulator, you - can obtain it from: <url url="http://vice-emu.sourceforge.net/">. - The VICE package contains the <em/c1541/ program that is able - to convert/unconvert GEOS files to disk images. + can obtain it from: <url url="http://vice-emu.sourceforge.net/">. + The VICE package contains the <em/c1541/ program that is able + to convert/unconvert GEOS files to disk images. <item><em/The Star Commander/ This tool is only for DOS. You will need it for transferring - object files from a PC to a 1541. There's also one important ability of this - tool - it automatically un-converts .cvt files into GEOS native format on - disk image files. Check out: <url url="http://sta.c64.org/sc.html">. + object files from a PC to a 1541. There's also one important ability of this + tool - it automatically un-converts .cvt files into GEOS native format on + disk image files. Check out: <url url="http://sta.c64.org/sc.html">. <item><em/opencbm/ A package that allows for communication directly with a 1541 and - other Commodore IEC bus drives. It can be a replacement for Star Commander if - you only want to transfer files to a disk and unconvert using GEOS program for - this purpose. Check out: <url url="https://spiro.trikaliotis.net/opencbm">. + other Commodore IEC bus drives. It can be a replacement for Star Commander if + you only want to transfer files to a disk and unconvert using GEOS program for + this purpose. Check out: <url url="https://spiro.trikaliotis.net/opencbm">. </itemize> <p> VICE and cc65 are portable - they run on variety of platforms - DOS, Win32 and UNIX. GEOSLib only @@ -387,7 +387,7 @@ and the number of rows to skip from the top if it. <sect3>BitOtherClip <p> <tt/void BitOtherClip (void *proc1, void *proc2, char skipLeft, char skip Right, unsigned skipTop, - struct iconpic *myPic)/ + struct iconpic *myPic)/ <p> Similar to the previous one with some extension. <tt/proc1/ is called before reading a byte (it returns in .A the next value), and <tt/proc2/ is called every time the parser reads a byte which is @@ -1390,9 +1390,9 @@ has the following fields: <itemize> <item><tt/char number/ - total number of icons declared here <item><tt/struct pixel mousepos/ - after finishing <tt/DoIcons/ the mouse pointer will be placed in - this point allowing you to have a hint for the user what the default action is + this point allowing you to have a hint for the user what the default action is <item><tt/struct icondef tab[&rsqb/ - this table of size equal to <tt/icontab.number/ contains - descriptions for all icons + descriptions for all icons </itemize> <sect1>File and Disk @@ -1452,9 +1452,9 @@ void example = { Which will be compiled to following string of bytes: <tscreen><verb> _example: - .byte 3 - .word 3 - .byte 0 + .byte 3 + .word 3 + .byte 0 </verb></tscreen> As you see this way it is possible to define data of any type in any order. You must remember to cast each member to proper type. @@ -1474,21 +1474,21 @@ just in the content. Here is how a single descriptor looks like: <tscreen><verb> void myMenu = { - (char)top, (char)bottom, // this is the size of the menubox - (unsigned)left, (unsigned)right, // counting all items in the current descriptor - (char)number_of_items | type_of_menu, // number of following items ORed with - // type of this menu, it can be either - // HORIZONTAL or VERTICAL if you will have also bit 6 set then menu won't be closed - // after moving mouse pointer outside the menubox. You can have at most 31 items. + (char)top, (char)bottom, // this is the size of the menubox + (unsigned)left, (unsigned)right, // counting all items in the current descriptor + (char)number_of_items | type_of_menu, // number of following items ORed with + // type of this menu, it can be either + // HORIZONTAL or VERTICAL if you will have also bit 6 set then menu won't be closed + // after moving mouse pointer outside the menubox. You can have at most 31 items. </verb></tscreen> This is followed by <tt/number_of_items/ of following item description. <tscreen><verb> - ... - "menuitemname", (char)item_type, (unsigned)pointer, - "nextitemname", (char)item_type, (unsigned)pointer, - ... - "lastitemname", (char)item_type, (unsigned)pointer }; - // Note that there isn't ending <tt/NULL/ or something like that. + ... + "menuitemname", (char)item_type, (unsigned)pointer, + "nextitemname", (char)item_type, (unsigned)pointer, + ... + "lastitemname", (char)item_type, (unsigned)pointer }; + // Note that there isn't ending <tt/NULL/ or something like that. </verb></tscreen> <tt/pointer/ is a pointer to something, what it points for depends from <tt/item_type/. This one can have following values: @@ -1521,16 +1521,16 @@ The first element can be specified in two ways - by using the default size and p your own. The first case results in <tscreen><verb> const dlgBoxStr example = { - DB_DEFPOS (pattern_of_shadow), - ... // commands - DB_END }; + DB_DEFPOS (pattern_of_shadow), + ... // commands + DB_END }; </verb></tscreen> And the own size and position would be: <tscreen><verb> const dlgBoxStr example = { - DB_SETPOS (pattern, top, bottom, left, right) - ... // commands - DB_END }; + DB_SETPOS (pattern, top, bottom, left, right) + ... // commands + DB_END }; </verb></tscreen> <sect3>Commands @@ -1539,9 +1539,9 @@ The next element of the <tt/DoDlgBox/ command string are the commands themselves default icons and the number of the selected icon will be returned from window processor. The icons are <tt/OK, CANCEL, YES, NO, OPEN/, and <tt/DISK/. You can use predefined macros for using them, e.g.: <tscreen><verb> - ... - DB_ICON(OK, DBI_X_0, DBI_Y_0), - ... + ... + DB_ICON(OK, DBI_X_0, DBI_Y_0), + ... </verb></tscreen> Note that the position is counted from top left corner of window, not entire screen and that the 'x' position is counted in cards (8-pixel) and not in pixels. This is also true for all following commands. @@ -1555,11 +1555,11 @@ where the address of the text is stored. This is useful for information windows is variable. Consider following: <tscreen><verb> char text = "foo"; - ... - r15=(unsigned)text; // in code just before call to DoDlgBox - ... - DB_VARSTR (TXT_LN_X, TXT_LN_1_Y, &r15), - ... + ... + r15=(unsigned)text; // in code just before call to DoDlgBox + ... + DB_VARSTR (TXT_LN_X, TXT_LN_1_Y, &r15), + ... </verb></tscreen> will cause the word ''foo'' to appear in the window, but you may store the pointer to any text in <tt/r15/ (in this case) before the call to DoDlgBox. @@ -1596,10 +1596,10 @@ command has to be <tt/GSTR_END/. There is a custom type defined for the command Here is an example for clearing the screen: <tscreen><verb> const graphicStr example = { - MOVEPENTO(0,0), - NEWPATTERN(0), - RECTANGLETO(319,199) - GSTR_END }; + MOVEPENTO(0,0), + NEWPATTERN(0), + RECTANGLETO(319,199) + GSTR_END }; </verb></tscreen> <sect2>InitRam table @@ -1623,17 +1623,17 @@ It is possible to intercept events and hook into the GEOS Kernal using vectors. void_func oldVector; void NewVectorHandler(void) { - // do something and at the end call the old vector routine - oldVector(); + // do something and at the end call the old vector routine + oldVector(); } void hook_into_system(void) { - oldVector = mouseVector; - mouseVector = NewVectorHandler; + oldVector = mouseVector; + mouseVector = NewVectorHandler; } void remove_hook(void) { - mouseVector = oldVector; + mouseVector = oldVector; } </verb></tscreen> <p> @@ -1655,10 +1655,10 @@ That little example above intercepts <tt/mouseVector/. The <tt/NewVectorHandler/ called every time the mouse button changes status. Other important vectors you should know about are: <itemize> - <item><tt/appMain/ - this is called from within the <tt/MainLoop/ system loop - <item><tt/keyVector/ - called whenever a keypress occurs - <item><tt/intTopVector/ - called at the start of the IRQ routine - <item><tt/intBotVector/ - called at the end of the IRQ routine + <item><tt/appMain/ - this is called from within the <tt/MainLoop/ system loop + <item><tt/keyVector/ - called whenever a keypress occurs + <item><tt/intTopVector/ - called at the start of the IRQ routine + <item><tt/intBotVector/ - called at the end of the IRQ routine </itemize> </article> diff --git a/doc/grc65.sgml b/doc/grc65.sgml index fb90fe23f..aec112f6b 100644 --- a/doc/grc65.sgml +++ b/doc/grc65.sgml @@ -381,11 +381,11 @@ HEADER APPLICATION "MyFirstApp" "Class Name" "V1.0" ; file named MyFirstApp with the Class-string "Class Name V1.0" { ; Not all fields are required, default and current values will be used. - author "Maciej Witkowiak" ; always in quotes! - info "Information text" ; always in quotes! -; date yy mm dd hh ss ; always 5 fields! -; dostype seq ; can be: PRG, SEQ, USR (only all UPPER- or lower-case) -; structure seq ; can be: SEQ, VLIR (only UPPER- or lower-case) - mode c64only ; can be: any, 40only, 80only, c64only + author "Maciej Witkowiak" ; always in quotes! + info "Information text" ; always in quotes! +; date yy mm dd hh ss ; always 5 fields! +; dostype seq ; can be: PRG, SEQ, USR (only all UPPER- or lower-case) +; structure seq ; can be: SEQ, VLIR (only UPPER- or lower-case) + mode c64only ; can be: any, 40only, 80only, c64only }</verb></tscreen> </article> diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 0230b517f..9116eb442 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -24,21 +24,21 @@ It complements the features that are built into the ca65 macroassembler: <itemize> -<item> Accept any number of segments to form an executable module. +<item> Accept any number of segments to form an executable module. -<item> Resolve arbitrary expressions stored in the object files. +<item> Resolve arbitrary expressions stored in the object files. -<item> In case of errors, use the meta information stored in the object files - to produce helpful error messages. In case of undefined symbols, - expression range errors, or symbol type mismatches, ld65 is able to - tell you the exact location in the original assembler source, where - the symbol was referenced. +<item> In case of errors, use the meta information stored in the object files + to produce helpful error messages. In case of undefined symbols, + expression range errors, or symbol type mismatches, ld65 is able to + tell you the exact location in the original assembler source, where + the symbol was referenced. -<item> Flexible output. The output of ld65 is highly configurable by a config - file. Some more-common platforms are supported by default configurations - that may be activated by naming the target system. The output - generation was designed with different output formats in mind, so - adding other formats shouldn't be a great problem. +<item> Flexible output. The output of ld65 is highly configurable by a config + file. Some more-common platforms are supported by default configurations + that may be activated by naming the target system. The output + generation was designed with different output formats in mind, so + adding other formats shouldn't be a great problem. </itemize> @@ -1148,14 +1148,14 @@ 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. +<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> diff --git a/doc/library.sgml b/doc/library.sgml index b2f880051..8800c5496 100644 --- a/doc/library.sgml +++ b/doc/library.sgml @@ -228,14 +228,14 @@ 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. +<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/lynx.sgml b/doc/lynx.sgml index de9951b9a..0eef70535 100644 --- a/doc/lynx.sgml +++ b/doc/lynx.sgml @@ -337,14 +337,14 @@ 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. +<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/nes.sgml b/doc/nes.sgml index 14fcac559..3f8f74183 100644 --- a/doc/nes.sgml +++ b/doc/nes.sgml @@ -179,17 +179,14 @@ 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. +<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/od65.sgml b/doc/od65.sgml index aab7522d9..633f7b164 100644 --- a/doc/od65.sgml +++ b/doc/od65.sgml @@ -200,15 +200,14 @@ 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. +<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/osi.sgml b/doc/osi.sgml index 081d7cfbb..eeaee4a97 100644 --- a/doc/osi.sgml +++ b/doc/osi.sgml @@ -217,14 +217,14 @@ 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. +<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/pet.sgml b/doc/pet.sgml index 61d6eb7a7..eb13d9fb9 100644 --- a/doc/pet.sgml +++ b/doc/pet.sgml @@ -242,14 +242,14 @@ 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. +<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/plus4.sgml b/doc/plus4.sgml index da9171a6f..11468bb33 100644 --- a/doc/plus4.sgml +++ b/doc/plus4.sgml @@ -260,14 +260,14 @@ 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. +<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/sim65.sgml b/doc/sim65.sgml index 286c46c56..0739ea2f1 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -27,19 +27,19 @@ binary needs to be compiled with <tt/--target sim6502/ or <tt/--target sim65c02/ The simulator is called as follows: <tscreen><verb> - Usage: sim65 [options] file [arguments] - Short options: - -h Help (this text) - -c Print amount of executed CPU cycles - -v Increase verbosity - -V Print the simulator version number - -x <num> Exit simulator after <num> cycles + Usage: sim65 [options] file [arguments] + Short options: + -h Help (this text) + -c Print amount of executed CPU cycles + -v Increase verbosity + -V Print the simulator version number + -x <num> Exit simulator after <num> cycles - Long options: - --help Help (this text) - --cycles Print amount of executed CPU cycles - --verbose Increase verbosity - --version Print the simulator version number + Long options: + --help Help (this text) + --cycles Print amount of executed CPU cycles + --verbose Increase verbosity + --version Print the simulator version number </verb></tscreen> @@ -120,14 +120,14 @@ 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. +<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/smc.sgml b/doc/smc.sgml index aec0d3d0b..e277c5008 100644 --- a/doc/smc.sgml +++ b/doc/smc.sgml @@ -470,7 +470,7 @@ SMC instructions. Example: <tscreen><verb> - SMC_OperateOnValue ASL, LoadMask ; shift mask to left + SMC_OperateOnValue ASL, LoadMask ; shift mask to left ... SMC LoadMask, { LDA #$20 } </verb></tscreen> @@ -555,14 +555,14 @@ allowing reuse of some instructions. 5: SMC StoreAccuFirstSection, { sta SMC_AbsAdr, Y } 6: ... 7: RestoreCodeBranchBaseAdr: - 8: SMC FirstIncHighByte, { SMC_OperateOnHighByte inc, StoreAccuFirstSection } ; code will be overwritten to 'beq RestoreCode' (*) + 8: SMC FirstIncHighByte, { SMC_OperateOnHighByte inc, StoreAccuFirstSection } ; code will be overwritten to 'beq RestoreCode' (*) 9: ... -10: SMC_TransferOpcode FirstIncHighByte, OPC_BEQ , x ; change code marked above with (*) -11: SMC_TransferValue FirstIncHighByte, #(restoreCode - RestoreCodeBranchBaseAdr-2), x ; set relative address to 'RestoreCode' +10: SMC_TransferOpcode FirstIncHighByte, OPC_BEQ , x ; change code marked above with (*) +11: SMC_TransferValue FirstIncHighByte, #(restoreCode - RestoreCodeBranchBaseAdr-2), x ; set relative address to 'RestoreCode' 12: ... 13: restoreCode: -14: SMC_TransferOpcode FirstIncHighByte, OPC_INC_abs , x ; restore original code... -15: SMC_TransferValue FirstIncHighByte, #(<(StoreToFirstSection+2)), x ; (second byte of inc contained low-byte of address) +14: SMC_TransferOpcode FirstIncHighByte, OPC_INC_abs , x ; restore original code... +15: SMC_TransferValue FirstIncHighByte, #(<(StoreToFirstSection+2)), x ; (second byte of inc contained low-byte of address) 16: ... </verb></tscreen> diff --git a/doc/sp65.sgml b/doc/sp65.sgml index 82b308025..255d7a552 100644 --- a/doc/sp65.sgml +++ b/doc/sp65.sgml @@ -403,14 +403,14 @@ 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. +<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> diff --git a/doc/supervision.sgml b/doc/supervision.sgml index 641a7e807..2570cfb9c 100644 --- a/doc/supervision.sgml +++ b/doc/supervision.sgml @@ -148,14 +148,14 @@ 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. +<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/telestrat.sgml b/doc/telestrat.sgml index 1f352607f..e52b183d0 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -16,8 +16,8 @@ An overview over the Telestrat (Telemon 2.4 & Telemon 3.x : http://orix.oric.org <sect>Overview<p> -This file contains an overview of the Telestrat runtime system as it comes -with the cc65 C compiler. It describes the memory layout, Telestrat-specific +This file contains an overview of the Telestrat runtime system as it comes +with the cc65 C compiler. It describes the memory layout, Telestrat-specific header files, available drivers, and any pitfalls specific to that platform. Please note that Telestrat-specific functions are just mentioned here, they are @@ -27,13 +27,13 @@ more than one platform. Please see the function reference for more information. Oric Telestrat is the last Oric computer (Released in 1986, mainly in France). -This computer is an Atmos with extra hardware: RS232, cardridge(banking system), +This computer is an Atmos with extra hardware: RS232, cardridge(banking system), joysticks (2 ports) or mouse (on joystick port), FDC. Video chip, CPU, keyboard management, tape hardware are the same than Atmos. -Telestrat can start in Atmos mode with Atmos Cardridge (which is only the atmos -Basic 1.1 ROM). +Telestrat can start in Atmos mode with Atmos Cardridge (which is only the atmos +Basic 1.1 ROM). Telestrat can start in Sedoric (Atmos OS) and Atmos mode with Stratoric Cardridge. This Cardridge has 3 banks of 16KB of rom with: @@ -43,15 +43,15 @@ This Cardridge has 3 banks of 16KB of rom with: <item>a Basic 1.0 ROM (Oric-1). </itemize> -The main Telestrat's configuration is the Telemon/Hyperbasic Cardridge inserted +The main Telestrat's configuration is the Telemon/Hyperbasic Cardridge inserted with Stratsed in floppy drive. -Anyway, there is no way to load a tape file in Telemon/Hyperbasic mode without +Anyway, there is no way to load a tape file in Telemon/Hyperbasic mode without alternative program. There is also no software to write a Stratsed dsk file on PC. -This Telestrat target build an Orix binary file. But, in the future, it will be possible +This Telestrat target build an Orix binary file. But, in the future, it will be possible to build a Stratsed disk. Orix uses the same systems calls than Telemon mode. That is why if you need to do software for telestrat target, you have the choice to: @@ -74,12 +74,12 @@ name="here" url="http://orix.oric.org/orix-header/"> This header is used for Telemon 3.0. -Anyway, for Telemon 2.4, there is no file management, there is no TAPE routine +Anyway, for Telemon 2.4, there is no file management, there is no TAPE routine in Telemon, there is no way to load a binary easily. -Stratsed (the Telestrat operating system) handles files management. Stratsed +Stratsed (the Telestrat operating system) handles files management. Stratsed is loaded to memory from floppy disk. Stratsed vector are declared in asminc/telestrat.inc. -But, reverse engineering is required to find how theses vectors works. Please, note that +But, reverse engineering is required to find how theses vectors works. Please, note that Stratsed is located in overlay memory (bank 0) There is no tool to insert a binary in a Stratsed floppy disk. @@ -88,8 +88,8 @@ The only way to load a binary (for Telemon 2.4) is to: <itemize> <item>remove the 20 bytes header <item>download <url name="osdk" url="http://osdk.defence-force.org/index?page=download"> -<item>use Floppybuilder in OSDK to insert the binary with the tool (please read -FloppyBuilder manual to learn how to insert your binary and how to start Microdisc boot sector +<item>use Floppybuilder in OSDK to insert the binary with the tool (please read +FloppyBuilder manual to learn how to insert your binary and how to start Microdisc boot sector when Telestrat starts) </itemize> @@ -183,13 +183,13 @@ TGI drivers is available on Oric Telestrat with some functions: <sect1>Extended memory drivers<p> -No extended memory drivers are currently available for the Telestrat. -This feature could be done because telestrat can manage RAM inserted in his -port cardridge. +No extended memory drivers are currently available for the Telestrat. +This feature could be done because telestrat can manage RAM inserted in his +port cardridge. <sect1>Joystick drivers<p> -Telemon 2.4 & 3.0 manages joysticks but it had been handled yet. This means that +Telemon 2.4 & 3.0 manages joysticks but it had been handled yet. This means that joysticks driver could be written easily. Telemon 2.4 returns in keyboard buffer the direction of the joysticks. This means that @@ -197,12 +197,12 @@ if you get input from keyboard by conio cgetc function, you will get direction f <sect1>Mouse drivers<p> -Telestrat manages also mouse, but it had been no handled yet in this version. +Telestrat manages also mouse, but it had been no handled yet in this version. Telestrat mouse is really difficult to find. <sect1>RS232 device drivers<p> -Telestrat has a RS232 port, but it's not usable in cc65. It is possible to use +Telestrat has a RS232 port, but it's not usable in cc65. It is possible to use RS232 port with Telemon calls (see XSOUT primitive for example) <sect>Limitations<label id="limitations"><p> @@ -236,14 +236,14 @@ 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. +<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/using-make.sgml b/doc/using-make.sgml index 7986e1dc9..2758a340b 100644 --- a/doc/using-make.sgml +++ b/doc/using-make.sgml @@ -76,13 +76,13 @@ ifneq ($(MAKECMDGOALS),clean) endif %.o: %.c - $(CC) -c $(CFLAGS) -o $@ $< + $(CC) -c $(CFLAGS) -o $@ $< $(PROGRAM): $(SOURCES:.c=.o) - $(CC) $(LDFLAGS) -o $@ $^ + $(CC) $(LDFLAGS) -o $@ $^ clean: - $(RM) $(SOURCES:.c=.o) $(SOURCES:.c=.d) $(PROGRAM) $(PROGRAM).map + $(RM) $(SOURCES:.c=.o) $(SOURCES:.c=.d) $(PROGRAM) $(PROGRAM).map </verb></tscreen> <bf/Important:/ When using the sample Makefile above via copy & paste it is diff --git a/doc/vic20.sgml b/doc/vic20.sgml index 6f98c6920..e292e0a1a 100644 --- a/doc/vic20.sgml +++ b/doc/vic20.sgml @@ -264,14 +264,14 @@ 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. +<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/test/err/front.c b/test/err/front.c index dde8d47ec..af59209b7 100644 --- a/test/err/front.c +++ b/test/err/front.c @@ -5,25 +5,25 @@ */ main() { - return 0; + return 0; } nested(a,b) { - if ((a<4 && b == 'r') - || (a == 1 && (b == 'h' || b == 'i')) - || (a == 2 && (b == 'o' || b == 'y')) - ) a=b; + if ((a<4 && b == 'r') + || (a == 1 && (b == 'h' || b == 'i')) + || (a == 2 && (b == 'o' || b == 'y')) + ) a=b; } /* type name scope */ -void s(struct D *d) {} /* this struct D differs from the one below */ +void s(struct D *d) {} /* this struct D differs from the one below */ typedef struct D D; struct D {int x, y;} Dy={0}; D Dz={1}; Dfunc(){ - D a; a.y=1; - s(&Dy); /* error */ + D a; a.y=1; + s(&Dy); /* error */ } /* qualifiers */ @@ -33,39 +33,39 @@ const int a, *x; int b, *y; volatile unsigned z; f() { - x = y; - z = z + z; /* should be 2 references to z's r-value */ + x = y; + z = z + z; /* should be 2 references to z's r-value */ } f1() { - x = &a; - x = &b; - y = &a; /* error */ - y = &b; + x = &a; + x = &b; + y = &a; /* error */ + y = &b; } f2(int **a, int **b) { - f(&x, &y); - **a = 0; - return **b; + f(&x, &y); + **a = 0; + return **b; } g(const int *p) { - g(&a); - g(&b); - return *p; + g(&a); + g(&b); + return *p; } h(int *p) { - f(&a); - f(&b); - return *p; + f(&a); + f(&b); + return *p; } h1(const int x, int y) { - h1(a,b); - h1(b,a); - return x + y; + h1(a,b); + h1(b,a); + return x + y; } h2() { - char *b; const void *p; - p = b; - b = p; /* error (incompatible pointer type) */ + char *b; const void *p; + p = b; + b = p; /* error (incompatible pointer type) */ } /* static naming */ @@ -120,14 +120,14 @@ extern int strcmp(const char*, const char*); extern void qsort(void*, int, int, int (*)(const void*, const void*)); extern int cmp(char**a, char**b) { return strcmp(*a,*b); } sort() { - int n; char *a[100]; - qsort(a, n, sizeof(char*), (int (*)(const void*, const void*))cmp); + int n; char *a[100]; + qsort(a, n, sizeof(char*), (int (*)(const void*, const void*))cmp); qsort(a, n, sizeof(char*), cmp); /* error (incompatible pointer type) */ } /* nasty calls */ onearg(){ - int a,b,c,d; - f( ( (a? (b = 1): (c = 2)), (d ? 3 : 4) ) ); /* 1 argument */ + int a,b,c,d; + f( ( (a? (b = 1): (c = 2)), (d ? 3 : 4) ) ); /* 1 argument */ } diff --git a/test/misc/fields.c b/test/misc/fields.c index 83bee82b7..acc561ce7 100644 --- a/test/misc/fields.c +++ b/test/misc/fields.c @@ -20,11 +20,11 @@ main() #ifdef REFCC #include <stdint.h> struct foo { - int16_t a; - char b; - int16_t x : 12, y : 4; - int16_t zz : 1, : 0, : 4, z : 3; - char c; + int16_t a; + char b; + int16_t x : 12, y : 4; + int16_t zz : 1, : 0, : 4, z : 3; + char c; } x = { 1, 2, 3, 4, 5, 6 }; struct baz { uint16_t a:2, b:4, c:16;} y = { 7, 8, 9}; @@ -33,11 +33,11 @@ int16_t i = 8; #else struct foo { - int a; - char b; - int x : 12, y : 4; - int zz : 1, : 0, : 4, z : 3; - char c; + int a; + char b; + int x : 12, y : 4; + int zz : 1, : 0, : 4, z : 3; + char c; } x = { 1, 2, 3, 4, 5, 6 }; struct baz { unsigned int a:2, b:4, c:16;} y = { 7, 8, 9}; @@ -46,10 +46,10 @@ int i = 8; #else struct foo { - int a; - char b; - int x : 12, y : 4, : 0, : 4, z : 3; - char c; + int a; + char b; + int x : 12, y : 4, : 0, : 4, z : 3; + char c; } x = { 1, 2, 3, 4, 5, 6 }; struct baz { unsigned int a:2, b:4, c:32;} y = { 7, 8, 9}; @@ -63,32 +63,32 @@ f2(struct baz *p); main() { - printf("x = %d b:%d %d %d %d c:%d\n", x.a, x.b, x.x, x.y, x.z, x.c); - printf("y = %d b:%d c:%d\n", y.a, y.b, y.c); - x.y = i; - x.z = 070; - printf("x = %d b:%d %d %d %d c:%d\n", x.a, x.b, x.x, x.y, x.z, x.c); - y.a = 2; - y.c = i; - printf("y = %d b:%d c:%d\n", y.a, y.b, y.c); + printf("x = %d b:%d %d %d %d c:%d\n", x.a, x.b, x.x, x.y, x.z, x.c); + printf("y = %d b:%d c:%d\n", y.a, y.b, y.c); + x.y = i; + x.z = 070; + printf("x = %d b:%d %d %d %d c:%d\n", x.a, x.b, x.x, x.y, x.z, x.c); + y.a = 2; + y.c = i; + printf("y = %d b:%d c:%d\n", y.a, y.b, y.c); #ifdef CAST_STRUCT_PTR - f2((struct baz *)&x); + f2((struct baz *)&x); #else - f2(&x); + f2(&x); #endif - return 0; + return 0; } f1(struct baz *p) { - p->a = p->b = 0; - if (p->b) - printf("p->b != 0!\n"); - p->a = 0x3; p->b = 0xf; - printf("p->a = 0x%x, p->b = 0x%x\n", p->a, p->b); + p->a = p->b = 0; + if (p->b) + printf("p->b != 0!\n"); + p->a = 0x3; p->b = 0xf; + printf("p->a = 0x%x, p->b = 0x%x\n", p->a, p->b); } f2(struct baz *p) { - p->a = (i==0); - p->b = (f1(p),0); + p->a = (i==0); + p->b = (f1(p),0); } #endif diff --git a/test/misc/limits.c b/test/misc/limits.c index 613d6bd09..427c54d23 100644 --- a/test/misc/limits.c +++ b/test/misc/limits.c @@ -7,9 +7,9 @@ #include <stdio.h> #include <limits.h> -#define SSHRT_MAX SHRT_MAX -#define SINT_MAX INT_MAX -#define SLONG_MAX LONG_MAX +#define SSHRT_MAX SHRT_MAX +#define SINT_MAX INT_MAX +#define SLONG_MAX LONG_MAX #define UCHAR_MIN 0 #define USHRT_MIN 0 diff --git a/test/misc/sitest.c b/test/misc/sitest.c index 9570f4989..3332c064e 100644 --- a/test/misc/sitest.c +++ b/test/misc/sitest.c @@ -5,29 +5,29 @@ */ /* - sitest -- exercise features of C99 <stdint.h> and <inttypes.h> + sitest -- exercise features of C99 <stdint.h> and <inttypes.h> - This source code has been placed into the PUBLIC DOMAIN by its author. + This source code has been placed into the PUBLIC DOMAIN by its author. - last edit: 1999/11/05 gwyn@arl.mil + last edit: 1999/11/05 gwyn@arl.mil - Tries to accommodate pre-C99 versions of <inttypes.h>. + Tries to accommodate pre-C99 versions of <inttypes.h>. - Takes advantage of __Q8_* symbols defined by a particular - implementation of <stdint.h>, but doesn't require them. + Takes advantage of __Q8_* symbols defined by a particular + implementation of <stdint.h>, but doesn't require them. - NOTE: This is not a thorough validation test of the facilities. + NOTE: This is not a thorough validation test of the facilities. */ #define NO_INTERNAL_WCHAR /*#define STANDALONE*/ -#include <errno.h> -#include <limits.h> /* for CHAR_BIT */ -#include <stdio.h> -#include <stddef.h> /* for ptrdiff_t */ -#include <stdlib.h> -#include <string.h> +#include <errno.h> +#include <limits.h> /* for CHAR_BIT */ +#include <stdio.h> +#include <stddef.h> /* for ptrdiff_t */ +#include <stdlib.h> +#include <string.h> #if !defined(STANDARD_C99) && !defined(STANDARD_CC65) @@ -41,15 +41,15 @@ #endif -#include <inttypes.h> /* embeds <stdint.h> */ +#include <inttypes.h> /* embeds <stdint.h> */ -#include <signal.h> /* for sig_atomic_t */ +#include <signal.h> /* for sig_atomic_t */ -#if defined(INTMAX_MAX) /* <inttypes.h> has C99 features */ -#include <wchar.h> +#if defined(INTMAX_MAX) /* <inttypes.h> has C99 features */ +#include <wchar.h> #endif -#include <inttypes.h> /* test idempotency */ +#include <inttypes.h> /* test idempotency */ #ifdef STANDALONE @@ -61,1531 +61,1531 @@ FILE *outfile=NULL; #endif -#if __STDC_VERSION__ >= 199901 -#ifndef __Q8_QT -#define __Q8_QT long long +#if __STDC_VERSION__ >= 199901 +#ifndef __Q8_QT +#define __Q8_QT long long #endif #endif -#ifdef PRIdMAX -#define HAVE_PRIdMAX -#ifndef __Q8_MT -#define __Q8_MT intmax_t +#ifdef PRIdMAX +#define HAVE_PRIdMAX +#ifndef __Q8_MT +#define __Q8_MT intmax_t #endif #else -#ifdef PRIdLEAST64 -#ifndef __Q8_MT -#define __Q8_MT int_least64_t +#ifdef PRIdLEAST64 +#ifndef __Q8_MT +#define __Q8_MT int_least64_t #endif -#define PRIdMAX PRIdLEAST64 +#define PRIdMAX PRIdLEAST64 #else -#ifndef __Q8_MT -#define __Q8_MT long +#ifndef __Q8_MT +#define __Q8_MT long #endif -#define PRIdMAX "ld" +#define PRIdMAX "ld" #endif #endif -#ifdef PRIuMAX -#define HAVE_PRIuMAX -#define U__Q8_MT uintmax_t +#ifdef PRIuMAX +#define HAVE_PRIuMAX +#define U__Q8_MT uintmax_t #else -#ifdef PRIuLEAST64 -#define U__Q8_MT uint_least64_t -#define PRIuMAX PRIuLEAST64 +#ifdef PRIuLEAST64 +#define U__Q8_MT uint_least64_t +#define PRIuMAX PRIuLEAST64 #else -#define U__Q8_MT unsigned long -#define PRIuMAX "lu" +#define U__Q8_MT unsigned long +#define PRIuMAX "lu" #endif #endif -#define STR_SUB(s) # s -#define STRINGIZE(s) STR_SUB(s) /* extra level to expand argument */ +#define STR_SUB(s) # s +#define STRINGIZE(s) STR_SUB(s) /* extra level to expand argument */ -#if defined(SCNo32) || defined(PRIo32) -static int32_t int32; +#if defined(SCNo32) || defined(PRIo32) +static int32_t int32; #endif -static int_least16_t intl16; -static uint_least16_t uintl16; -static uint_fast16_t uintf16; -static intmax_t intmax; -static uintmax_t uintmax; +static int_least16_t intl16; +static uint_least16_t uintl16; +static uint_fast16_t uintf16; +static intmax_t intmax; +static uintmax_t uintmax; int -main() { - int status = 0; /* exit status to be returned */ +main() { + int status = 0; /* exit status to be returned */ - - /* <stdint.h> features: */ + + /* <stdint.h> features: */ - printf("CHAR_BIT=%u\n", (unsigned)CHAR_BIT ); - printf("sizeof(char)=%u\n", (unsigned)sizeof(char)); /* s.b. 1 */ - printf("sizeof(short)=%u\n", (unsigned)sizeof(short)); - printf("sizeof(int)=%u\n", (unsigned)sizeof(int)); - printf("sizeof(long)=%u\n", (unsigned)sizeof(long)); -#ifdef __Q8_QT - printf("sizeof(long long)=%u\n", (unsigned)sizeof(__Q8_QT)); + printf("CHAR_BIT=%u\n", (unsigned)CHAR_BIT ); + printf("sizeof(char)=%u\n", (unsigned)sizeof(char)); /* s.b. 1 */ + printf("sizeof(short)=%u\n", (unsigned)sizeof(short)); + printf("sizeof(int)=%u\n", (unsigned)sizeof(int)); + printf("sizeof(long)=%u\n", (unsigned)sizeof(long)); +#ifdef __Q8_QT + printf("sizeof(long long)=%u\n", (unsigned)sizeof(__Q8_QT)); #else - printf("*** long long isn't defined ***\n"); + printf("*** long long isn't defined ***\n"); #endif - printf("sizeof(intmax_t)=%u\n", (unsigned)sizeof(intmax_t)); - printf("sizeof(ptrdiff_t)=%u\n", (unsigned)sizeof(ptrdiff_t)); - printf("sizeof(size_t)=%u\n", (unsigned)sizeof(size_t)); - printf("sizeof(sig_atomic_t)=%u\n", (unsigned)sizeof(sig_atomic_t)); - printf("sizeof(wchar_t)=%u\n", (unsigned)sizeof(wchar_t)); -#if defined(WINT_MAX) || __STDC_VERSION__ >= 199901 - printf("sizeof(wint_t)=%u\n", (unsigned)sizeof(wint_t)); + printf("sizeof(intmax_t)=%u\n", (unsigned)sizeof(intmax_t)); + printf("sizeof(ptrdiff_t)=%u\n", (unsigned)sizeof(ptrdiff_t)); + printf("sizeof(size_t)=%u\n", (unsigned)sizeof(size_t)); + printf("sizeof(sig_atomic_t)=%u\n", (unsigned)sizeof(sig_atomic_t)); + printf("sizeof(wchar_t)=%u\n", (unsigned)sizeof(wchar_t)); +#if defined(WINT_MAX) || __STDC_VERSION__ >= 199901 + printf("sizeof(wint_t)=%u\n", (unsigned)sizeof(wint_t)); #else - printf("*** wint_t isn't defined ***\n"); - status = EXIT_FAILURE; + printf("*** wint_t isn't defined ***\n"); + status = EXIT_FAILURE; #endif -#ifdef INT8_MAX - printf("sizeof(int8_t)=%u\n", (unsigned)sizeof(int8_t)); - printf("sizeof(uint8_t)=%u\n", (unsigned)sizeof(uint8_t)); +#ifdef INT8_MAX + printf("sizeof(int8_t)=%u\n", (unsigned)sizeof(int8_t)); + printf("sizeof(uint8_t)=%u\n", (unsigned)sizeof(uint8_t)); #endif -#ifdef INT9_MAX - printf("sizeof(int9_t)=%u\n", (unsigned)sizeof(int9_t)); - printf("sizeof(uint9_t)=%u\n", (unsigned)sizeof(uint9_t)); +#ifdef INT9_MAX + printf("sizeof(int9_t)=%u\n", (unsigned)sizeof(int9_t)); + printf("sizeof(uint9_t)=%u\n", (unsigned)sizeof(uint9_t)); #endif -#ifdef INT12_MAX - printf("sizeof(int12_t)=%u\n", (unsigned)sizeof(int12_t)); - printf("sizeof(uint12_t)=%u\n", (unsigned)sizeof(uint12_t)); +#ifdef INT12_MAX + printf("sizeof(int12_t)=%u\n", (unsigned)sizeof(int12_t)); + printf("sizeof(uint12_t)=%u\n", (unsigned)sizeof(uint12_t)); #endif -#ifdef INT16_MAX - printf("sizeof(int16_t)=%u\n", (unsigned)sizeof(int16_t)); - printf("sizeof(uint16_t)=%u\n", (unsigned)sizeof(uint16_t)); +#ifdef INT16_MAX + printf("sizeof(int16_t)=%u\n", (unsigned)sizeof(int16_t)); + printf("sizeof(uint16_t)=%u\n", (unsigned)sizeof(uint16_t)); #endif -#ifdef INT18_MAX - printf("sizeof(int18_t)=%u\n", (unsigned)sizeof(int18_t)); - printf("sizeof(uint18_t)=%u\n", (unsigned)sizeof(uint18_t)); +#ifdef INT18_MAX + printf("sizeof(int18_t)=%u\n", (unsigned)sizeof(int18_t)); + printf("sizeof(uint18_t)=%u\n", (unsigned)sizeof(uint18_t)); #endif -#ifdef INT24_MAX - printf("sizeof(int24_t)=%u\n", (unsigned)sizeof(int24_t)); - printf("sizeof(uint24_t)=%u\n", (unsigned)sizeof(uint24_t)); +#ifdef INT24_MAX + printf("sizeof(int24_t)=%u\n", (unsigned)sizeof(int24_t)); + printf("sizeof(uint24_t)=%u\n", (unsigned)sizeof(uint24_t)); #endif -#ifdef INT32_MAX - printf("sizeof(int32_t)=%u\n", (unsigned)sizeof(int32_t)); - printf("sizeof(uint32_t)=%u\n", (unsigned)sizeof(uint32_t)); +#ifdef INT32_MAX + printf("sizeof(int32_t)=%u\n", (unsigned)sizeof(int32_t)); + printf("sizeof(uint32_t)=%u\n", (unsigned)sizeof(uint32_t)); #endif -#ifdef INT36_MAX - printf("sizeof(int36_t)=%u\n", (unsigned)sizeof(int36_t)); - printf("sizeof(uint36_t)=%u\n", (unsigned)sizeof(uint36_t)); +#ifdef INT36_MAX + printf("sizeof(int36_t)=%u\n", (unsigned)sizeof(int36_t)); + printf("sizeof(uint36_t)=%u\n", (unsigned)sizeof(uint36_t)); #endif -#ifdef INT40_MAX - printf("sizeof(int40_t)=%u\n", (unsigned)sizeof(int40_t)); - printf("sizeof(uint40_t)=%u\n", (unsigned)sizeof(uint40_t)); +#ifdef INT40_MAX + printf("sizeof(int40_t)=%u\n", (unsigned)sizeof(int40_t)); + printf("sizeof(uint40_t)=%u\n", (unsigned)sizeof(uint40_t)); #endif -#ifdef INT48_MAX - printf("sizeof(int48_t)=%u\n", (unsigned)sizeof(int48_t)); - printf("sizeof(uint48_t)=%u\n", (unsigned)sizeof(uint48_t)); +#ifdef INT48_MAX + printf("sizeof(int48_t)=%u\n", (unsigned)sizeof(int48_t)); + printf("sizeof(uint48_t)=%u\n", (unsigned)sizeof(uint48_t)); #endif -#ifdef INT60_MAX - printf("sizeof(int60_t)=%u\n", (unsigned)sizeof(int60_t)); - printf("sizeof(uint60_t)=%u\n", (unsigned)sizeof(uint60_t)); +#ifdef INT60_MAX + printf("sizeof(int60_t)=%u\n", (unsigned)sizeof(int60_t)); + printf("sizeof(uint60_t)=%u\n", (unsigned)sizeof(uint60_t)); #endif -#ifdef INT64_MAX - printf("sizeof(int64_t)=%u\n", (unsigned)sizeof(int64_t)); - printf("sizeof(uint64_t)=%u\n", (unsigned)sizeof(uint64_t)); +#ifdef INT64_MAX + printf("sizeof(int64_t)=%u\n", (unsigned)sizeof(int64_t)); + printf("sizeof(uint64_t)=%u\n", (unsigned)sizeof(uint64_t)); #endif -#ifdef INT72_MAX - printf("sizeof(int72_t)=%u\n", (unsigned)sizeof(int72_t)); - printf("sizeof(uint72_t)=%u\n", (unsigned)sizeof(uint72_t)); +#ifdef INT72_MAX + printf("sizeof(int72_t)=%u\n", (unsigned)sizeof(int72_t)); + printf("sizeof(uint72_t)=%u\n", (unsigned)sizeof(uint72_t)); #endif -#ifdef INT128_MAX - printf("sizeof(int128_t)=%u\n", (unsigned)sizeof(int128_t)); - printf("sizeof(uint128_t)=%u\n", (unsigned)sizeof(uint128_t)); +#ifdef INT128_MAX + printf("sizeof(int128_t)=%u\n", (unsigned)sizeof(int128_t)); + printf("sizeof(uint128_t)=%u\n", (unsigned)sizeof(uint128_t)); #endif - printf("sizeof(int_least8_t)=%u\n", (unsigned)sizeof(int_least8_t)); - printf("sizeof(uint_least8_t)=%u\n", (unsigned)sizeof(uint_least8_t)); - printf("sizeof(int_least16_t)=%u\n", (unsigned)sizeof(int_least16_t)); - printf("sizeof(uint_least16_t)=%u\n", (unsigned)sizeof(uint_least16_t)); - printf("sizeof(int_least32_t)=%u\n", (unsigned)sizeof(int_least32_t)); - printf("sizeof(uint_least32_t)=%u\n", (unsigned)sizeof(uint_least32_t)); -#ifdef INT_LEAST64_MAX - printf("sizeof(int_least64_t)=%u\n", (unsigned)sizeof(int_least64_t)); - printf("sizeof(uint_least64_t)=%u\n", (unsigned)sizeof(uint_least64_t)); + printf("sizeof(int_least8_t)=%u\n", (unsigned)sizeof(int_least8_t)); + printf("sizeof(uint_least8_t)=%u\n", (unsigned)sizeof(uint_least8_t)); + printf("sizeof(int_least16_t)=%u\n", (unsigned)sizeof(int_least16_t)); + printf("sizeof(uint_least16_t)=%u\n", (unsigned)sizeof(uint_least16_t)); + printf("sizeof(int_least32_t)=%u\n", (unsigned)sizeof(int_least32_t)); + printf("sizeof(uint_least32_t)=%u\n", (unsigned)sizeof(uint_least32_t)); +#ifdef INT_LEAST64_MAX + printf("sizeof(int_least64_t)=%u\n", (unsigned)sizeof(int_least64_t)); + printf("sizeof(uint_least64_t)=%u\n", (unsigned)sizeof(uint_least64_t)); #else - printf("*** uint_least64_t isn't defined ***\n"); - status = EXIT_FAILURE; + printf("*** uint_least64_t isn't defined ***\n"); + status = EXIT_FAILURE; #endif -#ifdef INT_LEAST128_MAX - printf("sizeof(int_least128_t)=%u\n", (unsigned)sizeof(int_least128_t)); - printf("sizeof(uint_least128_t)=%u\n", - (unsigned)sizeof(uint_least128_t)); +#ifdef INT_LEAST128_MAX + printf("sizeof(int_least128_t)=%u\n", (unsigned)sizeof(int_least128_t)); + printf("sizeof(uint_least128_t)=%u\n", + (unsigned)sizeof(uint_least128_t)); #endif - printf("sizeof(int_fast8_t)=%u\n", (unsigned)sizeof(int_fast8_t)); - printf("sizeof(uint_fast8_t)=%u\n", (unsigned)sizeof(uint_fast8_t)); - printf("sizeof(int_fast16_t)=%u\n", (unsigned)sizeof(int_fast16_t)); - printf("sizeof(uint_fast16_t)=%u\n", (unsigned)sizeof(uint_fast16_t)); - printf("sizeof(int_fast32_t)=%u\n", (unsigned)sizeof(int_fast32_t)); - printf("sizeof(uint_fast32_t)=%u\n", (unsigned)sizeof(uint_fast32_t)); -#ifdef INT_FAST64_MAX - printf("sizeof(int_fast64_t)=%u\n", (unsigned)sizeof(int_fast64_t)); - printf("sizeof(uint_fast64_t)=%u\n", (unsigned)sizeof(uint_fast64_t)); + printf("sizeof(int_fast8_t)=%u\n", (unsigned)sizeof(int_fast8_t)); + printf("sizeof(uint_fast8_t)=%u\n", (unsigned)sizeof(uint_fast8_t)); + printf("sizeof(int_fast16_t)=%u\n", (unsigned)sizeof(int_fast16_t)); + printf("sizeof(uint_fast16_t)=%u\n", (unsigned)sizeof(uint_fast16_t)); + printf("sizeof(int_fast32_t)=%u\n", (unsigned)sizeof(int_fast32_t)); + printf("sizeof(uint_fast32_t)=%u\n", (unsigned)sizeof(uint_fast32_t)); +#ifdef INT_FAST64_MAX + printf("sizeof(int_fast64_t)=%u\n", (unsigned)sizeof(int_fast64_t)); + printf("sizeof(uint_fast64_t)=%u\n", (unsigned)sizeof(uint_fast64_t)); #else - printf("*** int_fast64_t isn't defined ***\n"); - status = EXIT_FAILURE; + printf("*** int_fast64_t isn't defined ***\n"); + status = EXIT_FAILURE; #endif -#ifdef INT_FAST128_MAX - printf("sizeof(int_fast128_t)=%u\n", (unsigned)sizeof(int_fast128_t)); - printf("sizeof(uint_fast128_t)=%u\n", (unsigned)sizeof(uint_fast128_t)); +#ifdef INT_FAST128_MAX + printf("sizeof(int_fast128_t)=%u\n", (unsigned)sizeof(int_fast128_t)); + printf("sizeof(uint_fast128_t)=%u\n", (unsigned)sizeof(uint_fast128_t)); #endif -#if defined(INTPTR_MAX) - printf("sizeof(intptr_t)=%u\n", (unsigned)sizeof(intptr_t)); -#if defined(UINTPTR_MAX) - printf("sizeof(uintptr_t)=%u\n", (unsigned)sizeof(uintptr_t)); +#if defined(INTPTR_MAX) + printf("sizeof(intptr_t)=%u\n", (unsigned)sizeof(intptr_t)); +#if defined(UINTPTR_MAX) + printf("sizeof(uintptr_t)=%u\n", (unsigned)sizeof(uintptr_t)); #else - printf("*** intptr_t is defined but uintptr_t isn't ***\n"); - status = EXIT_FAILURE; + printf("*** intptr_t is defined but uintptr_t isn't ***\n"); + status = EXIT_FAILURE; #endif -#elif defined(UINTPTR_MAX) - printf("sizeof(uintptr_t)=%u\n", (unsigned)sizeof(uintptr_t)); - printf("*** uintptr_t is defined but intptr_t isn't ***\n"); - status = EXIT_FAILURE; +#elif defined(UINTPTR_MAX) + printf("sizeof(uintptr_t)=%u\n", (unsigned)sizeof(uintptr_t)); + printf("*** uintptr_t is defined but intptr_t isn't ***\n"); + status = EXIT_FAILURE; #else - printf("*** neither intptr_t nor uintptr_t is defined ***\n"); - status = EXIT_FAILURE; + printf("*** neither intptr_t nor uintptr_t is defined ***\n"); + status = EXIT_FAILURE; #endif -#ifdef INTMAX_MAX - printf("sizeof(intmax_t)=%u\n", (unsigned)sizeof(intmax_t)); - printf("sizeof(uintmax_t)=%u\n", (unsigned)sizeof(uintmax_t)); +#ifdef INTMAX_MAX + printf("sizeof(intmax_t)=%u\n", (unsigned)sizeof(intmax_t)); + printf("sizeof(uintmax_t)=%u\n", (unsigned)sizeof(uintmax_t)); #else - printf("*** intmax_t isn't defined ***\n"); - status = EXIT_FAILURE; + printf("*** intmax_t isn't defined ***\n"); + status = EXIT_FAILURE; #endif -#ifdef INT8_MAX - printf("INT8_MIN=%"PRIdMAX"\n", (__Q8_MT)INT8_MIN); - printf("INT8_MAX=%"PRIdMAX"\n", (__Q8_MT)INT8_MAX); - printf("UINT8_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT8_MAX); +#ifdef INT8_MAX + printf("INT8_MIN=%"PRIdMAX"\n", (__Q8_MT)INT8_MIN); + printf("INT8_MAX=%"PRIdMAX"\n", (__Q8_MT)INT8_MAX); + printf("UINT8_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT8_MAX); #endif -#ifdef INT9_MAX - printf("INT9_MIN=%"PRIdMAX"\n", (__Q8_MT)INT9_MIN); - printf("INT9_MAX=%"PRIdMAX"\n", (__Q8_MT)INT9_MAX); - printf("UINT9_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT9_MAX); +#ifdef INT9_MAX + printf("INT9_MIN=%"PRIdMAX"\n", (__Q8_MT)INT9_MIN); + printf("INT9_MAX=%"PRIdMAX"\n", (__Q8_MT)INT9_MAX); + printf("UINT9_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT9_MAX); #endif -#ifdef INT12_MAX - printf("INT12_MIN=%"PRIdMAX"\n", (__Q8_MT)INT12_MIN); - printf("INT12_MAX=%"PRIdMAX"\n", (__Q8_MT)INT12_MAX); - printf("UINT12_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT12_MAX); +#ifdef INT12_MAX + printf("INT12_MIN=%"PRIdMAX"\n", (__Q8_MT)INT12_MIN); + printf("INT12_MAX=%"PRIdMAX"\n", (__Q8_MT)INT12_MAX); + printf("UINT12_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT12_MAX); #endif -#ifdef INT16_MAX - printf("INT16_MIN=%"PRIdMAX"\n", (__Q8_MT)INT16_MIN); - printf("INT16_MAX=%"PRIdMAX"\n", (__Q8_MT)INT16_MAX); - printf("UINT16_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT16_MAX); +#ifdef INT16_MAX + printf("INT16_MIN=%"PRIdMAX"\n", (__Q8_MT)INT16_MIN); + printf("INT16_MAX=%"PRIdMAX"\n", (__Q8_MT)INT16_MAX); + printf("UINT16_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT16_MAX); #endif -#ifdef INT18_MAX - printf("INT18_MIN=%"PRIdMAX"\n", (__Q8_MT)INT18_MIN); - printf("INT18_MAX=%"PRIdMAX"\n", (__Q8_MT)INT18_MAX); - printf("UINT18_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT18_MAX); +#ifdef INT18_MAX + printf("INT18_MIN=%"PRIdMAX"\n", (__Q8_MT)INT18_MIN); + printf("INT18_MAX=%"PRIdMAX"\n", (__Q8_MT)INT18_MAX); + printf("UINT18_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT18_MAX); #endif -#ifdef INT24_MAX - printf("INT24_MIN=%"PRIdMAX"\n", (__Q8_MT)INT24_MIN); - printf("INT24_MAX=%"PRIdMAX"\n", (__Q8_MT)INT24_MAX); - printf("UINT24_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT24_MAX); +#ifdef INT24_MAX + printf("INT24_MIN=%"PRIdMAX"\n", (__Q8_MT)INT24_MIN); + printf("INT24_MAX=%"PRIdMAX"\n", (__Q8_MT)INT24_MAX); + printf("UINT24_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT24_MAX); #endif -#ifdef INT32_MAX - printf("INT32_MIN=%"PRIdMAX"\n", (__Q8_MT)INT32_MIN); - printf("INT32_MAX=%"PRIdMAX"\n", (__Q8_MT)INT32_MAX); - printf("UINT32_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT32_MAX); +#ifdef INT32_MAX + printf("INT32_MIN=%"PRIdMAX"\n", (__Q8_MT)INT32_MIN); + printf("INT32_MAX=%"PRIdMAX"\n", (__Q8_MT)INT32_MAX); + printf("UINT32_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT32_MAX); #endif -#ifdef INT36_MAX - printf("INT36_MIN=%"PRIdMAX"\n", (__Q8_MT)INT36_MIN); - printf("INT36_MAX=%"PRIdMAX"\n", (__Q8_MT)INT36_MAX); - printf("UINT36_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT36_MAX); +#ifdef INT36_MAX + printf("INT36_MIN=%"PRIdMAX"\n", (__Q8_MT)INT36_MIN); + printf("INT36_MAX=%"PRIdMAX"\n", (__Q8_MT)INT36_MAX); + printf("UINT36_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT36_MAX); #endif -#ifdef INT40_MAX - printf("INT40_MIN=%"PRIdMAX"\n", (__Q8_MT)INT40_MIN); - printf("INT40_MAX=%"PRIdMAX"\n", (__Q8_MT)INT40_MAX); - printf("UINT40_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT40_MAX); +#ifdef INT40_MAX + printf("INT40_MIN=%"PRIdMAX"\n", (__Q8_MT)INT40_MIN); + printf("INT40_MAX=%"PRIdMAX"\n", (__Q8_MT)INT40_MAX); + printf("UINT40_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT40_MAX); #endif -#ifdef INT48_MAX - printf("INT48_MIN=%"PRIdMAX"\n", (__Q8_MT)INT48_MIN); - printf("INT48_MAX=%"PRIdMAX"\n", (__Q8_MT)INT48_MAX); - printf("UINT48_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT48_MAX); +#ifdef INT48_MAX + printf("INT48_MIN=%"PRIdMAX"\n", (__Q8_MT)INT48_MIN); + printf("INT48_MAX=%"PRIdMAX"\n", (__Q8_MT)INT48_MAX); + printf("UINT48_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT48_MAX); #endif -#ifdef INT60_MAX - printf("INT60_MIN=%"PRIdMAX"\n", (__Q8_MT)INT60_MIN); - printf("INT60_MAX=%"PRIdMAX"\n", (__Q8_MT)INT60_MAX); - printf("UINT60_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT60_MAX); +#ifdef INT60_MAX + printf("INT60_MIN=%"PRIdMAX"\n", (__Q8_MT)INT60_MIN); + printf("INT60_MAX=%"PRIdMAX"\n", (__Q8_MT)INT60_MAX); + printf("UINT60_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT60_MAX); #endif -#ifdef INT64_MAX - printf("INT64_MIN=%"PRIdMAX"\n", (__Q8_MT)INT64_MIN); - printf("INT64_MAX=%"PRIdMAX"\n", (__Q8_MT)INT64_MAX); - printf("UINT64_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT64_MAX); +#ifdef INT64_MAX + printf("INT64_MIN=%"PRIdMAX"\n", (__Q8_MT)INT64_MIN); + printf("INT64_MAX=%"PRIdMAX"\n", (__Q8_MT)INT64_MAX); + printf("UINT64_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT64_MAX); #endif -#ifdef INT72_MAX - printf("INT72_MIN=%"PRIdMAX"\n", (__Q8_MT)INT72_MIN); - printf("INT72_MAX=%"PRIdMAX"\n", (__Q8_MT)INT72_MAX); - printf("UINT72_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT72_MAX); +#ifdef INT72_MAX + printf("INT72_MIN=%"PRIdMAX"\n", (__Q8_MT)INT72_MIN); + printf("INT72_MAX=%"PRIdMAX"\n", (__Q8_MT)INT72_MAX); + printf("UINT72_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT72_MAX); #endif -#ifdef INT128_MAX - printf("INT128_MIN=%"PRIdMAX"\n", (__Q8_MT)INT128_MIN); - printf("INT128_MAX=%"PRIdMAX"\n", (__Q8_MT)INT128_MAX); - printf("UINT128_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT128_MAX); +#ifdef INT128_MAX + printf("INT128_MIN=%"PRIdMAX"\n", (__Q8_MT)INT128_MIN); + printf("INT128_MAX=%"PRIdMAX"\n", (__Q8_MT)INT128_MAX); + printf("UINT128_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT128_MAX); #endif - printf("INT_LEAST8_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST8_MIN); - printf("INT_LEAST8_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST8_MAX); - printf("UINT_LEAST8_MAX=%"PRIuMAX"\n", - (U__Q8_MT)UINT_LEAST8_MAX); - printf("INT_LEAST16_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST16_MIN); - printf("INT_LEAST16_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST16_MAX); - printf("UINT_LEAST16_MAX=%"PRIuMAX"\n", - (U__Q8_MT)UINT_LEAST16_MAX); - printf("INT_LEAST32_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST32_MIN); - printf("INT_LEAST32_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST32_MAX); - printf("UINT_LEAST32_MAX=%"PRIuMAX"\n", - (U__Q8_MT)UINT_LEAST32_MAX); -#ifdef INT_LEAST64_MAX - printf("INT_LEAST64_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST64_MIN); - printf("INT_LEAST64_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST64_MAX); - printf("UINT_LEAST64_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT_LEAST64_MAX); + printf("INT_LEAST8_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST8_MIN); + printf("INT_LEAST8_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST8_MAX); + printf("UINT_LEAST8_MAX=%"PRIuMAX"\n", + (U__Q8_MT)UINT_LEAST8_MAX); + printf("INT_LEAST16_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST16_MIN); + printf("INT_LEAST16_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST16_MAX); + printf("UINT_LEAST16_MAX=%"PRIuMAX"\n", + (U__Q8_MT)UINT_LEAST16_MAX); + printf("INT_LEAST32_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST32_MIN); + printf("INT_LEAST32_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST32_MAX); + printf("UINT_LEAST32_MAX=%"PRIuMAX"\n", + (U__Q8_MT)UINT_LEAST32_MAX); +#ifdef INT_LEAST64_MAX + printf("INT_LEAST64_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST64_MIN); + printf("INT_LEAST64_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST64_MAX); + printf("UINT_LEAST64_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT_LEAST64_MAX); #endif -#ifdef INT_LEAST128_MAX - printf("INT_LEAST128_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST128_MIN); - printf("INT_LEAST128_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST128_MAX); - printf("UINT_LEAST128_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT_LEAST128_MAX); +#ifdef INT_LEAST128_MAX + printf("INT_LEAST128_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST128_MIN); + printf("INT_LEAST128_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST128_MAX); + printf("UINT_LEAST128_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT_LEAST128_MAX); #endif - printf("INT_FAST8_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_FAST8_MIN); - printf("INT_FAST8_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_FAST8_MAX); - printf("UINT_FAST8_MAX=%"PRIuMAX"\n", - (U__Q8_MT)UINT_FAST8_MAX); - printf("INT_FAST16_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_FAST16_MIN); - printf("INT_FAST16_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_FAST16_MAX); - printf("UINT_FAST16_MAX=%"PRIuMAX"\n", - (U__Q8_MT)UINT_FAST16_MAX); - printf("INT_FAST32_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_FAST32_MIN); - printf("INT_FAST32_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_FAST32_MAX); - printf("UINT_FAST32_MAX=%"PRIuMAX"\n", - (U__Q8_MT)UINT_FAST32_MAX); -#ifdef INT_FAST64_MAX - printf("INT_FAST64_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_FAST64_MIN); - printf("INT_FAST64_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_FAST64_MAX); - printf("UINT_FAST64_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT_FAST64_MAX); + printf("INT_FAST8_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_FAST8_MIN); + printf("INT_FAST8_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_FAST8_MAX); + printf("UINT_FAST8_MAX=%"PRIuMAX"\n", + (U__Q8_MT)UINT_FAST8_MAX); + printf("INT_FAST16_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_FAST16_MIN); + printf("INT_FAST16_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_FAST16_MAX); + printf("UINT_FAST16_MAX=%"PRIuMAX"\n", + (U__Q8_MT)UINT_FAST16_MAX); + printf("INT_FAST32_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_FAST32_MIN); + printf("INT_FAST32_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_FAST32_MAX); + printf("UINT_FAST32_MAX=%"PRIuMAX"\n", + (U__Q8_MT)UINT_FAST32_MAX); +#ifdef INT_FAST64_MAX + printf("INT_FAST64_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_FAST64_MIN); + printf("INT_FAST64_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_FAST64_MAX); + printf("UINT_FAST64_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT_FAST64_MAX); #endif -#ifdef INT_FAST128_MAX - printf("INT_FAST128_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_FAST128_MIN); - printf("INT_FAST128_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_FAST128_MAX); - printf("UINT_FAST128_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT_FAST128_MAX); +#ifdef INT_FAST128_MAX + printf("INT_FAST128_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_FAST128_MIN); + printf("INT_FAST128_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_FAST128_MAX); + printf("UINT_FAST128_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT_FAST128_MAX); #endif -#ifdef INTPTR_MAX - printf("INTPTR_MIN=%"PRIdMAX"\n", (__Q8_MT)INTPTR_MIN); - printf("INTPTR_MAX=%"PRIdMAX"\n", (__Q8_MT)INTPTR_MAX); +#ifdef INTPTR_MAX + printf("INTPTR_MIN=%"PRIdMAX"\n", (__Q8_MT)INTPTR_MIN); + printf("INTPTR_MAX=%"PRIdMAX"\n", (__Q8_MT)INTPTR_MAX); #endif -#ifdef UINTPTR_MAX - printf("UINTPTR_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINTPTR_MAX); +#ifdef UINTPTR_MAX + printf("UINTPTR_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINTPTR_MAX); #endif -#ifdef INTMAX_MAX - printf("INTMAX_MIN=%"PRIdMAX"\n", (__Q8_MT)INTMAX_MIN); - printf("INTMAX_MAX=%"PRIdMAX"\n", (__Q8_MT)INTMAX_MAX); - printf("UINTMAX_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINTMAX_MAX); +#ifdef INTMAX_MAX + printf("INTMAX_MIN=%"PRIdMAX"\n", (__Q8_MT)INTMAX_MIN); + printf("INTMAX_MAX=%"PRIdMAX"\n", (__Q8_MT)INTMAX_MAX); + printf("UINTMAX_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINTMAX_MAX); #endif -#ifdef PTRDIFF_MAX - printf("PTRDIFF_MIN=%"PRIdMAX"\n", (__Q8_MT)PTRDIFF_MIN); - printf("PTRDIFF_MAX=%"PRIdMAX"\n", (__Q8_MT)PTRDIFF_MAX); +#ifdef PTRDIFF_MAX + printf("PTRDIFF_MIN=%"PRIdMAX"\n", (__Q8_MT)PTRDIFF_MIN); + printf("PTRDIFF_MAX=%"PRIdMAX"\n", (__Q8_MT)PTRDIFF_MAX); #endif -#ifdef SIG_ATOMIC_MAX -#if SIG_ATOMIC_MIN < 0 - printf("SIG_ATOMIC_MIN=%"PRIdMAX"\n", (__Q8_MT)SIG_ATOMIC_MIN); - printf("SIG_ATOMIC_MAX=%"PRIdMAX"\n", (__Q8_MT)SIG_ATOMIC_MAX); +#ifdef SIG_ATOMIC_MAX +#if SIG_ATOMIC_MIN < 0 + printf("SIG_ATOMIC_MIN=%"PRIdMAX"\n", (__Q8_MT)SIG_ATOMIC_MIN); + printf("SIG_ATOMIC_MAX=%"PRIdMAX"\n", (__Q8_MT)SIG_ATOMIC_MAX); #else - printf("SIG_ATOMIC_MIN=%"PRIuMAX"\n", (U__Q8_MT)SIG_ATOMIC_MIN); - printf("SIG_ATOMIC_MAX=%"PRIuMAX"\n", (U__Q8_MT)SIG_ATOMIC_MAX); + printf("SIG_ATOMIC_MIN=%"PRIuMAX"\n", (U__Q8_MT)SIG_ATOMIC_MIN); + printf("SIG_ATOMIC_MAX=%"PRIuMAX"\n", (U__Q8_MT)SIG_ATOMIC_MAX); #endif #endif -#ifdef SIZE_MAX - printf("SIZE_MAX=%"PRIuMAX"\n", (U__Q8_MT)SIZE_MAX); +#ifdef SIZE_MAX + printf("SIZE_MAX=%"PRIuMAX"\n", (U__Q8_MT)SIZE_MAX); #endif -#ifdef WCHAR_MAX -#if WCHAR_MIN < 0 - printf("WCHAR_MIN=%"PRIdMAX"\n", (__Q8_MT)WCHAR_MIN); - printf("WCHAR_MAX=%"PRIdMAX"\n", (__Q8_MT)WCHAR_MAX); +#ifdef WCHAR_MAX +#if WCHAR_MIN < 0 + printf("WCHAR_MIN=%"PRIdMAX"\n", (__Q8_MT)WCHAR_MIN); + printf("WCHAR_MAX=%"PRIdMAX"\n", (__Q8_MT)WCHAR_MAX); #else - printf("WCHAR_MIN=%"PRIuMAX"\n", (U__Q8_MT)WCHAR_MIN); - printf("WCHAR_MAX=%"PRIuMAX"\n", (U__Q8_MT)WCHAR_MAX); + printf("WCHAR_MIN=%"PRIuMAX"\n", (U__Q8_MT)WCHAR_MIN); + printf("WCHAR_MAX=%"PRIuMAX"\n", (U__Q8_MT)WCHAR_MAX); #endif #endif -#ifdef WINT_MAX -#if WINT_MIN < 0 - printf("WINT_MIN=%"PRIdMAX"\n", (__Q8_MT)WINT_MIN); - printf("WINT_MAX=%"PRIdMAX"\n", (__Q8_MT)WINT_MAX); +#ifdef WINT_MAX +#if WINT_MIN < 0 + printf("WINT_MIN=%"PRIdMAX"\n", (__Q8_MT)WINT_MIN); + printf("WINT_MAX=%"PRIdMAX"\n", (__Q8_MT)WINT_MAX); #else - printf("WINT_MIN=%"PRIuMAX"\n", (U__Q8_MT)WINT_MIN); - printf("WINT_MAX=%"PRIuMAX"\n", (U__Q8_MT)WINT_MAX); + printf("WINT_MIN=%"PRIuMAX"\n", (U__Q8_MT)WINT_MIN); + printf("WINT_MAX=%"PRIuMAX"\n", (U__Q8_MT)WINT_MAX); #endif #endif - /* - 7.18.4 Macros for integer constants - */ + /* + 7.18.4 Macros for integer constants + */ - /* INTn_C for n=8 and 16 were at one point unimplementable - on most platforms, so they're treated as "optional": */ -#ifdef INT8_C - if ( INT8_C(-123) != -123 ) - printf("*** INT8_C(-123) produced %"PRIdMAX" ***\n", - (__Q8_MT)INT8_C(-123) - ); - if ( UINT8_C(123) != 123 ) - printf("*** UINT8_C(123) produced %"PRIuMAX" ***\n", - (U__Q8_MT)UINT8_C(123) - ); + /* INTn_C for n=8 and 16 were at one point unimplementable + on most platforms, so they're treated as "optional": */ +#ifdef INT8_C + if ( INT8_C(-123) != -123 ) + printf("*** INT8_C(-123) produced %"PRIdMAX" ***\n", + (__Q8_MT)INT8_C(-123) + ); + if ( UINT8_C(123) != 123 ) + printf("*** UINT8_C(123) produced %"PRIuMAX" ***\n", + (U__Q8_MT)UINT8_C(123) + ); #endif -#ifdef INT16_C - if ( INT16_C(-12345) != -12345 ) - printf("*** INT16_C(-12345) produced %"PRIdMAX" ***\n", - (__Q8_MT)INT16_C(-12345) - ); - if ( UINT16_C(12345) != 12345 ) - printf("*** UINT16_C(12345) produced %"PRIuMAX" ***\n", - (U__Q8_MT)UINT16_C(12345) - ); +#ifdef INT16_C + if ( INT16_C(-12345) != -12345 ) + printf("*** INT16_C(-12345) produced %"PRIdMAX" ***\n", + (__Q8_MT)INT16_C(-12345) + ); + if ( UINT16_C(12345) != 12345 ) + printf("*** UINT16_C(12345) produced %"PRIuMAX" ***\n", + (U__Q8_MT)UINT16_C(12345) + ); #endif - if ( INT32_C(-123456789) != -123456789 ) - printf("*** INT32_C(-123456789) produced %"PRIdMAX" ***\n", - (__Q8_MT)INT32_C(-123456789) - ); - if ( UINT32_C(123456789) != 123456789 ) - printf("*** UINT32_C(123456789) produced %"PRIuMAX" ***\n", - (U__Q8_MT)UINT32_C(123456789) - ); -#ifdef INT_LEAST64_MAX - if ( INT64_C(-1234567890123456789) != -1234567890123456789 ) - printf("*** INT64_C(-1234567890123456789) produced %"PRIdMAX - " ***\n", - (__Q8_MT)INT64_C(-1234567890123456789) - ); - if ( UINT64_C(1234567890123456789) != 1234567890123456789 ) - printf("*** UINT64_C(1234567890123456789) produced %"PRIuMAX - " ***\n", - (U__Q8_MT)UINT64_C(1234567890123456789) - ); + if ( INT32_C(-123456789) != -123456789 ) + printf("*** INT32_C(-123456789) produced %"PRIdMAX" ***\n", + (__Q8_MT)INT32_C(-123456789) + ); + if ( UINT32_C(123456789) != 123456789 ) + printf("*** UINT32_C(123456789) produced %"PRIuMAX" ***\n", + (U__Q8_MT)UINT32_C(123456789) + ); +#ifdef INT_LEAST64_MAX + if ( INT64_C(-1234567890123456789) != -1234567890123456789 ) + printf("*** INT64_C(-1234567890123456789) produced %"PRIdMAX + " ***\n", + (__Q8_MT)INT64_C(-1234567890123456789) + ); + if ( UINT64_C(1234567890123456789) != 1234567890123456789 ) + printf("*** UINT64_C(1234567890123456789) produced %"PRIuMAX + " ***\n", + (U__Q8_MT)UINT64_C(1234567890123456789) + ); #endif -#ifdef INTMAX_MAX - if ( INTMAX_C(-1234567890123456789) != -1234567890123456789 ) - printf("*** INTMAX_C(-1234567890123456789) produced %"PRIdMAX - " ***\n", - (__Q8_MT)INTMAX_C(-1234567890123456789) - ); - if ( UINTMAX_C(1234567890123456789) != 1234567890123456789 ) - printf("*** UINTMAX_C(1234567890123456789) produced %"PRIuMAX - " ***\n", - (U__Q8_MT)UINTMAX_C(1234567890123456789) - ); +#ifdef INTMAX_MAX + if ( INTMAX_C(-1234567890123456789) != -1234567890123456789 ) + printf("*** INTMAX_C(-1234567890123456789) produced %"PRIdMAX + " ***\n", + (__Q8_MT)INTMAX_C(-1234567890123456789) + ); + if ( UINTMAX_C(1234567890123456789) != 1234567890123456789 ) + printf("*** UINTMAX_C(1234567890123456789) produced %"PRIuMAX + " ***\n", + (U__Q8_MT)UINTMAX_C(1234567890123456789) + ); #endif - /* <inttypes.h> features: */ + /* <inttypes.h> features: */ -#if __STDC_VERSION__ >= 199901 - printf("sizeof(imaxdiv_t)=%u\n", (unsigned)sizeof(imaxdiv_t)); +#if __STDC_VERSION__ >= 199901 + printf("sizeof(imaxdiv_t)=%u\n", (unsigned)sizeof(imaxdiv_t)); #endif - /* - 7.8.1 Macros for format specifiers - */ + /* + 7.8.1 Macros for format specifiers + */ - { - /* scanf these strings */ - static const char in_dn[] = "Z119bZ"; - static const char in_dmo[] = "Z-0119bZ"; - static const char in_dspx[] = "Z \t\n +0X119bZ"; - static const char in_dsmx[] = "Z \t\n -0x119bZ"; - static const char in_dsn[] = "Z \t\n 119bZ"; - static const char in_dp[] = "Z+119bZ"; - static const char in_dpx[] = "Z+0X119bz"; + { + /* scanf these strings */ + static const char in_dn[] = "Z119bZ"; + static const char in_dmo[] = "Z-0119bZ"; + static const char in_dspx[] = "Z \t\n +0X119bZ"; + static const char in_dsmx[] = "Z \t\n -0x119bZ"; + static const char in_dsn[] = "Z \t\n 119bZ"; + static const char in_dp[] = "Z+119bZ"; + static const char in_dpx[] = "Z+0X119bz"; - /* sprintf into this */ - static char buffer[1024]; + /* sprintf into this */ + static char buffer[1024]; #if 1 -#define SCAN(buf,fs,var,exp) if ( sscanf(buf, "Z%" fs, &var) != 1 ) \ - { \ - printf("***%s=",fs, STR_SUB(fs) \ - " failed ***\n" \ - ); \ - status = EXIT_FAILURE; \ - } \ - else if ( var != (exp) ) \ - { \ - printf("***%s=",fs, STR_SUB(fs) \ - " should be: " STR_SUB(exp) \ - ", was: %" fs " ***\n", var \ - ); \ - status = EXIT_FAILURE; \ - } \ - else /* for trailing semicolon */ +#define SCAN(buf,fs,var,exp) if ( sscanf(buf, "Z%" fs, &var) != 1 ) \ + { \ + printf("***%s=",fs, STR_SUB(fs) \ + " failed ***\n" \ + ); \ + status = EXIT_FAILURE; \ + } \ + else if ( var != (exp) ) \ + { \ + printf("***%s=",fs, STR_SUB(fs) \ + " should be: " STR_SUB(exp) \ + ", was: %" fs " ***\n", var \ + ); \ + status = EXIT_FAILURE; \ + } \ + else /* for trailing semicolon */ -#define PRINT(fs,var,exp) if ( sprintf(buffer, "%" fs, var ) <= 0 ) \ - { \ - printf("***%s=",fs, STR_SUB(fs) \ - " failed ***\n" \ - ); \ - status = EXIT_FAILURE; \ - } \ - else if ( strcmp(buffer, STR_SUB(exp)) != 0 ) \ - { \ - printf("***%s=",fs, STR_SUB(fs) \ - " should be: " STR_SUB(exp) \ - ", was: %s ***\n", buffer \ - ); \ - status = EXIT_FAILURE; \ - } \ - else /* for trailing semicolon */ +#define PRINT(fs,var,exp) if ( sprintf(buffer, "%" fs, var ) <= 0 ) \ + { \ + printf("***%s=",fs, STR_SUB(fs) \ + " failed ***\n" \ + ); \ + status = EXIT_FAILURE; \ + } \ + else if ( strcmp(buffer, STR_SUB(exp)) != 0 ) \ + { \ + printf("***%s=",fs, STR_SUB(fs) \ + " should be: " STR_SUB(exp) \ + ", was: %s ***\n", buffer \ + ); \ + status = EXIT_FAILURE; \ + } \ + else /* for trailing semicolon */ #else - -#define SCAN(buf,fs,var,exp) -#define PRINT(fs,var,exp) + +#define SCAN(buf,fs,var,exp) +#define PRINT(fs,var,exp) #endif - -#ifdef SCNo32 + +#ifdef SCNo32 - SCAN(in_dn, SCNo32, int32, 9); + SCAN(in_dn, SCNo32, int32, 9); #endif -#ifdef PRIo32 - PRINT(PRIo32, int32, 11); +#ifdef PRIo32 + PRINT(PRIo32, int32, 11); #endif - SCAN(in_dmo, SCNiLEAST16, intl16, -9); - SCAN(in_dspx, SCNdLEAST16, intl16, 0); - SCAN(in_dsmx, SCNiLEAST16, intl16, -4507); - PRINT(PRIdLEAST16, intl16, -4507); - PRINT(PRIiLEAST16, intl16, -4507); - SCAN(in_dsn, SCNxLEAST16, uintl16, 4507); - PRINT(PRIoLEAST16, uintl16, 10633); - PRINT(PRIuLEAST16, uintl16, 4507); - PRINT(PRIxLEAST16, uintl16, 119b); - PRINT(PRIXLEAST16, uintl16, 119B); - SCAN(in_dp, SCNxFAST16, uintf16, 4507); - PRINT(PRIxFAST16, uintf16, 119b); -#ifdef SCNdMAX - SCAN(in_dp, SCNdMAX, intmax, 119); + SCAN(in_dmo, SCNiLEAST16, intl16, -9); + SCAN(in_dspx, SCNdLEAST16, intl16, 0); + SCAN(in_dsmx, SCNiLEAST16, intl16, -4507); + PRINT(PRIdLEAST16, intl16, -4507); + PRINT(PRIiLEAST16, intl16, -4507); + SCAN(in_dsn, SCNxLEAST16, uintl16, 4507); + PRINT(PRIoLEAST16, uintl16, 10633); + PRINT(PRIuLEAST16, uintl16, 4507); + PRINT(PRIxLEAST16, uintl16, 119b); + PRINT(PRIXLEAST16, uintl16, 119B); + SCAN(in_dp, SCNxFAST16, uintf16, 4507); + PRINT(PRIxFAST16, uintf16, 119b); +#ifdef SCNdMAX + SCAN(in_dp, SCNdMAX, intmax, 119); #endif -#ifdef PRIiMAX - PRINT(PRIiMAX, intmax, 119); +#ifdef PRIiMAX + PRINT(PRIiMAX, intmax, 119); #endif -#ifdef SCNoMAX - SCAN(in_dpx, SCNoMAX, uintmax, 0); +#ifdef SCNoMAX + SCAN(in_dpx, SCNoMAX, uintmax, 0); #endif -#ifdef PRIxMAX - PRINT(PRIxMAX, uintmax, 0); +#ifdef PRIxMAX + PRINT(PRIxMAX, uintmax, 0); #endif - /* Obviously there should be a much larger battery of such tests. */ - } + /* Obviously there should be a much larger battery of such tests. */ + } -#if defined(INTMAX_MAX) /* <inttypes.h> has C99 features */ - /* - 7.8.2 Functions for greatest-width integer types - */ +#if defined(INTMAX_MAX) /* <inttypes.h> has C99 features */ + /* + 7.8.2 Functions for greatest-width integer types + */ - { - static struct - { - intmax_t input; - intmax_t expect; - } abs_data[] = - { -#ifdef INT8_MAX - { INT8_MAX, INT8_MAX, }, - { -INT8_MAX, INT8_MAX, }, - { UINT8_MAX, UINT8_MAX, }, + { + static struct + { + intmax_t input; + intmax_t expect; + } abs_data[] = + { +#ifdef INT8_MAX + { INT8_MAX, INT8_MAX, }, + { -INT8_MAX, INT8_MAX, }, + { UINT8_MAX, UINT8_MAX, }, #endif #if 0 -#ifdef INT16_MAX - { INT16_MAX, INT16_MAX, }, - { -INT16_MAX, INT16_MAX, }, - { UINT16_MAX, UINT16_MAX, }, +#ifdef INT16_MAX + { INT16_MAX, INT16_MAX, }, + { -INT16_MAX, INT16_MAX, }, + { UINT16_MAX, UINT16_MAX, }, #endif -#ifdef INT32_MAX - { INT32_MAX, INT32_MAX, }, - { -INT32_MAX, INT32_MAX, }, -#ifdef INT_LEAST64_MAX /* else might support only 32 bits */ - { UINT32_MAX, UINT32_MAX, }, +#ifdef INT32_MAX + { INT32_MAX, INT32_MAX, }, + { -INT32_MAX, INT32_MAX, }, +#ifdef INT_LEAST64_MAX /* else might support only 32 bits */ + { UINT32_MAX, UINT32_MAX, }, #endif #endif -#ifdef INT64_MAX - { INT64_MAX, INT64_MAX, }, - { -INT64_MAX, INT64_MAX, }, +#ifdef INT64_MAX + { INT64_MAX, INT64_MAX, }, + { -INT64_MAX, INT64_MAX, }, #endif - { INT_LEAST8_MAX, INT_LEAST8_MAX, }, - { -INT_LEAST8_MAX, INT_LEAST8_MAX, }, - { UINT_LEAST8_MAX, UINT_LEAST8_MAX, }, - { INT_LEAST16_MAX, INT_LEAST16_MAX, }, - { -INT_LEAST16_MAX, INT_LEAST16_MAX, }, - { UINT_LEAST16_MAX, UINT_LEAST16_MAX, }, - { INT_LEAST32_MAX, INT_LEAST32_MAX, }, - { -INT_LEAST32_MAX, INT_LEAST32_MAX, }, -#ifdef INT_LEAST64_MAX - { UINT_LEAST32_MAX, UINT_LEAST32_MAX, }, - { INT_LEAST64_MAX, INT_LEAST64_MAX, }, - { -INT_LEAST64_MAX, INT_LEAST64_MAX, }, + { INT_LEAST8_MAX, INT_LEAST8_MAX, }, + { -INT_LEAST8_MAX, INT_LEAST8_MAX, }, + { UINT_LEAST8_MAX, UINT_LEAST8_MAX, }, + { INT_LEAST16_MAX, INT_LEAST16_MAX, }, + { -INT_LEAST16_MAX, INT_LEAST16_MAX, }, + { UINT_LEAST16_MAX, UINT_LEAST16_MAX, }, + { INT_LEAST32_MAX, INT_LEAST32_MAX, }, + { -INT_LEAST32_MAX, INT_LEAST32_MAX, }, +#ifdef INT_LEAST64_MAX + { UINT_LEAST32_MAX, UINT_LEAST32_MAX, }, + { INT_LEAST64_MAX, INT_LEAST64_MAX, }, + { -INT_LEAST64_MAX, INT_LEAST64_MAX, }, #endif - { INT_FAST8_MAX, INT_FAST8_MAX, }, - { -INT_FAST8_MAX, INT_FAST8_MAX, }, - { UINT_FAST8_MAX, UINT_FAST8_MAX, }, - { INT_FAST16_MAX, INT_FAST16_MAX, }, - { -INT_FAST16_MAX, INT_FAST16_MAX, }, - { UINT_FAST16_MAX, UINT_FAST16_MAX, }, - { INT_FAST32_MAX, INT_FAST32_MAX, }, - { -INT_FAST32_MAX, INT_FAST32_MAX, }, -#ifdef INT_FAST64_MAX - { UINT_FAST32_MAX, UINT_FAST32_MAX, }, - { INT_FAST64_MAX, INT_FAST64_MAX, }, - { -INT_FAST64_MAX, INT_FAST64_MAX, }, + { INT_FAST8_MAX, INT_FAST8_MAX, }, + { -INT_FAST8_MAX, INT_FAST8_MAX, }, + { UINT_FAST8_MAX, UINT_FAST8_MAX, }, + { INT_FAST16_MAX, INT_FAST16_MAX, }, + { -INT_FAST16_MAX, INT_FAST16_MAX, }, + { UINT_FAST16_MAX, UINT_FAST16_MAX, }, + { INT_FAST32_MAX, INT_FAST32_MAX, }, + { -INT_FAST32_MAX, INT_FAST32_MAX, }, +#ifdef INT_FAST64_MAX + { UINT_FAST32_MAX, UINT_FAST32_MAX, }, + { INT_FAST64_MAX, INT_FAST64_MAX, }, + { -INT_FAST64_MAX, INT_FAST64_MAX, }, #endif -#ifdef INTPTR_MAX - { INTPTR_MAX, INTPTR_MAX, }, - { -INTPTR_MAX, INTPTR_MAX, }, +#ifdef INTPTR_MAX + { INTPTR_MAX, INTPTR_MAX, }, + { -INTPTR_MAX, INTPTR_MAX, }, #endif -#ifdef UINTPTR_MAX - { UINTPTR_MAX, UINTPTR_MAX, }, +#ifdef UINTPTR_MAX + { UINTPTR_MAX, UINTPTR_MAX, }, #endif - { INTMAX_MAX, INTMAX_MAX, }, -#ifdef PTRDIFF_MAX - { PTRDIFF_MAX, PTRDIFF_MAX, }, + { INTMAX_MAX, INTMAX_MAX, }, +#ifdef PTRDIFF_MAX + { PTRDIFF_MAX, PTRDIFF_MAX, }, #endif -#ifdef SIG_ATOMIC_MAX - { SIG_ATOMIC_MAX, SIG_ATOMIC_MAX, }, -#if SIG_ATOMIC_MIN < 0 - { -SIG_ATOMIC_MAX, SIG_ATOMIC_MAX, }, +#ifdef SIG_ATOMIC_MAX + { SIG_ATOMIC_MAX, SIG_ATOMIC_MAX, }, +#if SIG_ATOMIC_MIN < 0 + { -SIG_ATOMIC_MAX, SIG_ATOMIC_MAX, }, #endif #endif -#ifdef SIZE_MAX - { SIZE_MAX, SIZE_MAX, }, +#ifdef SIZE_MAX + { SIZE_MAX, SIZE_MAX, }, #endif -#ifdef WCHAR_MAX - { WCHAR_MAX, WCHAR_MAX, }, -#if WCHAR_MIN < 0 - { -WCHAR_MAX, WCHAR_MAX, }, +#ifdef WCHAR_MAX + { WCHAR_MAX, WCHAR_MAX, }, +#if WCHAR_MIN < 0 + { -WCHAR_MAX, WCHAR_MAX, }, #endif #endif -#ifdef WINT_MAX - { WINT_MAX, WINT_MAX, }, -#if WINT_MIN < 0 - { -WINT_MAX, WINT_MAX, }, +#ifdef WINT_MAX + { WINT_MAX, WINT_MAX, }, +#if WINT_MIN < 0 + { -WINT_MAX, WINT_MAX, }, #endif #endif - { 127, 127, }, - { -127, 127, }, - { 128, 128, }, - { -127-1, 128, }, - { 255, 255, }, - { -256+1, 255, }, - { 256, 256, }, - { -256, 256, }, - { 32767, 32767, }, - { -32767, 32767, }, - { 32768, 32768, }, - { -32767-1, 32768, }, - { 65535, 65535, }, - { -65536+1, 65535, }, - { 65536, 65536, }, - { -65536, 65536, }, - { 2147483647, 2147483647, }, - { -2147483647, 2147483647, }, - { 2147483648, 2147483648, }, - { -2147483647-1, 2147483648, }, -#ifdef INT_LEAST64_MAX /* else might support only 32 bits */ - { 4294967295, 4294967295, }, - { -4294967296+1, 4294967295, }, - { 4294967296, 4294967296, }, - { -4294967296, 4294967296, }, - { 9223372036854775807, 9223372036854775807, }, - { -9223372036854775807, 9223372036854775807, }, - { 1234567890123456789, 1234567890123456789, }, - { -1234567890123456789, 1234567890123456789, }, + { 127, 127, }, + { -127, 127, }, + { 128, 128, }, + { -127-1, 128, }, + { 255, 255, }, + { -256+1, 255, }, + { 256, 256, }, + { -256, 256, }, + { 32767, 32767, }, + { -32767, 32767, }, + { 32768, 32768, }, + { -32767-1, 32768, }, + { 65535, 65535, }, + { -65536+1, 65535, }, + { 65536, 65536, }, + { -65536, 65536, }, + { 2147483647, 2147483647, }, + { -2147483647, 2147483647, }, + { 2147483648, 2147483648, }, + { -2147483647-1, 2147483648, }, +#ifdef INT_LEAST64_MAX /* else might support only 32 bits */ + { 4294967295, 4294967295, }, + { -4294967296+1, 4294967295, }, + { 4294967296, 4294967296, }, + { -4294967296, 4294967296, }, + { 9223372036854775807, 9223372036854775807, }, + { -9223372036854775807, 9223372036854775807, }, + { 1234567890123456789, 1234567890123456789, }, + { -1234567890123456789, 1234567890123456789, }, #endif - { 1, 1, }, - { -1, 1, }, - { 2, 2, }, - { -2, 2, }, - { 10, 10, }, - { -10, 10, }, - { 16, 16, }, - { -16, 16, }, + { 1, 1, }, + { -1, 1, }, + { 2, 2, }, + { -2, 2, }, + { 10, 10, }, + { -10, 10, }, + { 16, 16, }, + { -16, 16, }, #endif - /* Other test cases can be added here. */ - { 0, 0 /* terminates the list */ }, - }, *adp = abs_data; + /* Other test cases can be added here. */ + { 0, 0 /* terminates the list */ }, + }, *adp = abs_data; - do { - if ( (intmax = imaxabs(adp->input)) != adp->expect ) - { - printf("*** imaxabs(%"PRIdMAX") failed; should be: %" - PRIdMAX", was: %"PRIdMAX" ***\n", - adp->input, adp->expect, intmax - ); - status = EXIT_FAILURE; - } -// } while ( adp++->input != 0 ); - } while ( (adp++)->input != 0 ); - } + do { + if ( (intmax = imaxabs(adp->input)) != adp->expect ) + { + printf("*** imaxabs(%"PRIdMAX") failed; should be: %" + PRIdMAX", was: %"PRIdMAX" ***\n", + adp->input, adp->expect, intmax + ); + status = EXIT_FAILURE; + } +// } while ( adp++->input != 0 ); + } while ( (adp++)->input != 0 ); + } - { - imaxdiv_t result; - static struct - { - intmax_t numer; - intmax_t denom; - intmax_t exp_quot; - intmax_t exp_rem; - } div_data[] = - { - { 0, 1, 0, 0, }, + { + imaxdiv_t result; + static struct + { + intmax_t numer; + intmax_t denom; + intmax_t exp_quot; + intmax_t exp_rem; + } div_data[] = + { + { 0, 1, 0, 0, }, #if 0 - { 0, -1, 0, 0, }, - { 0, 2, 0, 0, }, - { 0, -2, 0, 0, }, - { 0, 5, 0, 0, }, - { 0, -5, 0, 0, }, - { 1, 1, 1, 0, }, - { 1, -1, -1, 0, }, - { 1, 2, 0, 1, }, - { 1, -2, 0, 1, }, - { 1, 5, 0, 1, }, - { 1, -5, 0, 1, }, - { -1, 1, -1, 0, }, - { -1, -1, 1, 0, }, - { -1, 2, 0, -1, }, - { -1, -2, 0, -1, }, - { -1, 5, 0, -1, }, - { -1, -5, 0, -1, }, - { 2, 1, 2, 0, }, - { 2, -1, -2, 0, }, - { 2, 2, 1, 0, }, - { 2, -2, -1, 0, }, - { 2, 5, 0, 2, }, - { 2, -5, 0, 2, }, - { -2, 1, -2, 0, }, - { -2, -1, 2, 0, }, - { -2, 2, -1, 0, }, - { -2, -2, 1, 0, }, - { -2, 5, 0, -2, }, - { -2, -5, 0, -2, }, - { 17, 5, 3, 2, }, - { -17, -5, 3, -2, }, - { 17, -5, -3, 2, }, - { -17, 5, -3, -2, }, - { 2147483647, 1, 2147483647, 0, }, - { -2147483647, 1, -2147483647, 0, }, - { 2147483648, 1, 2147483648, 0, }, - { -2147483647-1, 1, -2147483647-1, 0, }, - { 2147483647, 2, 1073741823, 1, }, - { -2147483647, 2, -1073741823, -1, }, - { 2147483648, 2, 1073741824, 0, }, - { -2147483647-1, 2, -1073741824, 0, }, -#ifdef INT_LEAST64_MAX /* else might support only 32 bits */ - { 4294967295, 1, 4294967295, 0, }, - { -4294967296+1, 1, -4294967296+1, 0, }, - { 4294967296, 1, 4294967296, 0, }, - { -4294967296, 1, -4294967296, 0, }, - { 4294967295, -1, -4294967296+1, 0, }, - { -4294967296+1, -1, 4294967295, 0, }, - { 4294967296, -1, -4294967296, 0, }, - { -4294967296, -1, 4294967296, 0, }, - { 4294967295, 2, 2147483647, 1, }, - { -4294967296+1, 2, -2147483647, -1, }, - { 4294967296, 2, 2147483648, 0, }, - { -4294967296, 2, -2147483647-1, 0, }, - { 4294967295, 2147483647, 2, 1, }, - { -4294967296+1, 2147483647, -2, -1, }, - { 4294967296, 2147483647, 2, 2, }, - { -4294967296, 2147483647, -2, -2, }, - { 4294967295, -2147483647, -2, 1, }, - { -4294967296+1, -2147483647, 2, -1, }, - { 4294967296, -2147483647, -2, 2, }, - { -4294967296, -2147483647, 2, -2, }, - { 4294967295, 2147483648, 1, 2147483647, }, - { -4294967296+1, 2147483648, -1, -2147483647, }, - { 4294967296, 2147483648, 2, 0, }, - { -4294967296, 2147483648, -2, 0, }, - { 4294967295, -2147483647-1, -1, 2147483647, }, - { -4294967296+1, -2147483647-1, 1, -2147483647,}, - { 4294967296, -2147483647-1, -2, 0, }, - { -4294967296, -2147483647-1, 2, 0, }, - { 9223372036854775807, 1, 9223372036854775807, 0, }, - { -9223372036854775807, 1, -9223372036854775807, 0, }, - { 9223372036854775807, 2, 4611686018427387903, 1, }, - { -9223372036854775807, 2, -4611686018427387903, -1, }, + { 0, -1, 0, 0, }, + { 0, 2, 0, 0, }, + { 0, -2, 0, 0, }, + { 0, 5, 0, 0, }, + { 0, -5, 0, 0, }, + { 1, 1, 1, 0, }, + { 1, -1, -1, 0, }, + { 1, 2, 0, 1, }, + { 1, -2, 0, 1, }, + { 1, 5, 0, 1, }, + { 1, -5, 0, 1, }, + { -1, 1, -1, 0, }, + { -1, -1, 1, 0, }, + { -1, 2, 0, -1, }, + { -1, -2, 0, -1, }, + { -1, 5, 0, -1, }, + { -1, -5, 0, -1, }, + { 2, 1, 2, 0, }, + { 2, -1, -2, 0, }, + { 2, 2, 1, 0, }, + { 2, -2, -1, 0, }, + { 2, 5, 0, 2, }, + { 2, -5, 0, 2, }, + { -2, 1, -2, 0, }, + { -2, -1, 2, 0, }, + { -2, 2, -1, 0, }, + { -2, -2, 1, 0, }, + { -2, 5, 0, -2, }, + { -2, -5, 0, -2, }, + { 17, 5, 3, 2, }, + { -17, -5, 3, -2, }, + { 17, -5, -3, 2, }, + { -17, 5, -3, -2, }, + { 2147483647, 1, 2147483647, 0, }, + { -2147483647, 1, -2147483647, 0, }, + { 2147483648, 1, 2147483648, 0, }, + { -2147483647-1, 1, -2147483647-1, 0, }, + { 2147483647, 2, 1073741823, 1, }, + { -2147483647, 2, -1073741823, -1, }, + { 2147483648, 2, 1073741824, 0, }, + { -2147483647-1, 2, -1073741824, 0, }, +#ifdef INT_LEAST64_MAX /* else might support only 32 bits */ + { 4294967295, 1, 4294967295, 0, }, + { -4294967296+1, 1, -4294967296+1, 0, }, + { 4294967296, 1, 4294967296, 0, }, + { -4294967296, 1, -4294967296, 0, }, + { 4294967295, -1, -4294967296+1, 0, }, + { -4294967296+1, -1, 4294967295, 0, }, + { 4294967296, -1, -4294967296, 0, }, + { -4294967296, -1, 4294967296, 0, }, + { 4294967295, 2, 2147483647, 1, }, + { -4294967296+1, 2, -2147483647, -1, }, + { 4294967296, 2, 2147483648, 0, }, + { -4294967296, 2, -2147483647-1, 0, }, + { 4294967295, 2147483647, 2, 1, }, + { -4294967296+1, 2147483647, -2, -1, }, + { 4294967296, 2147483647, 2, 2, }, + { -4294967296, 2147483647, -2, -2, }, + { 4294967295, -2147483647, -2, 1, }, + { -4294967296+1, -2147483647, 2, -1, }, + { 4294967296, -2147483647, -2, 2, }, + { -4294967296, -2147483647, 2, -2, }, + { 4294967295, 2147483648, 1, 2147483647, }, + { -4294967296+1, 2147483648, -1, -2147483647, }, + { 4294967296, 2147483648, 2, 0, }, + { -4294967296, 2147483648, -2, 0, }, + { 4294967295, -2147483647-1, -1, 2147483647, }, + { -4294967296+1, -2147483647-1, 1, -2147483647,}, + { 4294967296, -2147483647-1, -2, 0, }, + { -4294967296, -2147483647-1, 2, 0, }, + { 9223372036854775807, 1, 9223372036854775807, 0, }, + { -9223372036854775807, 1, -9223372036854775807, 0, }, + { 9223372036854775807, 2, 4611686018427387903, 1, }, + { -9223372036854775807, 2, -4611686018427387903, -1, }, #endif #endif - /* There should be a much larger battery of such tests. */ - { 0, 0, 0, 0 }, /* 0 denom terminates the list */ - }, *ddp; + /* There should be a much larger battery of such tests. */ + { 0, 0, 0, 0 }, /* 0 denom terminates the list */ + }, *ddp; #if 0 - for ( ddp = div_data; ddp->denom != 0; ++ddp ) - if ( (result = imaxdiv(ddp->numer, ddp->denom)).quot - != ddp->exp_quot || result.rem != ddp->exp_rem - ) { -// printf("*** imaxdiv(%"PRIdMAX",%"PRIdMAX -// ") failed; should be: (%"PRIdMAX",%"PRIdMAX -// "), was: (%"PRIdMAX",%"PRIdMAX") ***\n", -// ddp->numer, ddp->denom, ddp->exp_quot, -// ddp->exp_rem, result.quot, result.rem -// ); - printf("err:imaxdiv(%"PRIdMAX",%"PRIdMAX - ") = (%"PRIdMAX",%"PRIdMAX - "), is: (%"PRIdMAX",%"PRIdMAX")\n", - ddp->numer, ddp->denom, ddp->exp_quot, - ddp->exp_rem, result.quot, result.rem - ); - status = EXIT_FAILURE; - } + for ( ddp = div_data; ddp->denom != 0; ++ddp ) + if ( (result = imaxdiv(ddp->numer, ddp->denom)).quot + != ddp->exp_quot || result.rem != ddp->exp_rem + ) { +// printf("*** imaxdiv(%"PRIdMAX",%"PRIdMAX +// ") failed; should be: (%"PRIdMAX",%"PRIdMAX +// "), was: (%"PRIdMAX",%"PRIdMAX") ***\n", +// ddp->numer, ddp->denom, ddp->exp_quot, +// ddp->exp_rem, result.quot, result.rem +// ); + printf("err:imaxdiv(%"PRIdMAX",%"PRIdMAX + ") = (%"PRIdMAX",%"PRIdMAX + "), is: (%"PRIdMAX",%"PRIdMAX")\n", + ddp->numer, ddp->denom, ddp->exp_quot, + ddp->exp_rem, result.quot, result.rem + ); + status = EXIT_FAILURE; + } #endif - } - - { - char *endptr; - wchar_t *wendptr; - static char saved[64]; /* holds copy of input string */ - static wchar_t wnptr[64]; /* holds wide copy of test string */ - static int warned; /* "warned for null endptr" flag */ - register int i; - static struct - { - char * nptr; - int base; - intmax_t exp_val; - int exp_len; - } str_data[] = - { - { "", 0, 0, 0, }, - { "", 2, 0, 0, }, - { "", 8, 0, 0, }, - { "", 9, 0, 0, }, - { "", 10, 0, 0, }, - { "", 16, 0, 0, }, - { "", 36, 0, 0, }, - { "0", 0, 0, 1, }, - { "0", 2, 0, 1, }, - { "0", 8, 0, 1, }, - { "0", 9, 0, 1, }, - { "0", 10, 0, 1, }, - { "0", 16, 0, 1, }, - { "0", 36, 0, 1, }, - { "+0", 0, 0, 2, }, - { "+0", 2, 0, 2, }, - { "+0", 8, 0, 2, }, - { "+0", 9, 0, 2, }, - { "+0", 10, 0, 2, }, - { "+0", 16, 0, 2, }, - { "+0", 36, 0, 2, }, - { "-0", 0, 0, 2, }, - { "-0", 2, 0, 2, }, - { "-0", 8, 0, 2, }, - { "-0", 9, 0, 2, }, - { "-0", 10, 0, 2, }, - { "-0", 16, 0, 2, }, - { "-0", 36, 0, 2, }, - { "Inf", 0, 0, 0, }, - { "Inf", 2, 0, 0, }, - { "Inf", 8, 0, 0, }, - { "Inf", 9, 0, 0, }, - { "Inf", 10, 0, 0, }, - { "Inf", 16, 0, 0, }, - { "Inf", 36, 24171, 3, }, - { "+Inf", 0, 0, 0, }, - { "+Inf", 2, 0, 0, }, - { "+Inf", 8, 0, 0, }, - { "+Inf", 9, 0, 0, }, - { "+Inf", 10, 0, 0, }, - { "+Inf", 16, 0, 0, }, - { "+Inf", 36, 24171, 4, }, - { "-Inf", 0, 0, 0, }, - { "-Inf", 2, 0, 0, }, - { "-Inf", 8, 0, 0, }, - { "-Inf", 9, 0, 0, }, - { "-Inf", 10, 0, 0, }, - { "-Inf", 16, 0, 0, }, - { "-Inf", 36, -24171, 4, }, - { "inf", 0, 0, 0, }, - { "inf", 2, 0, 0, }, - { "inf", 8, 0, 0, }, - { "inf", 9, 0, 0, }, - { "inf", 10, 0, 0, }, - { "inf", 16, 0, 0, }, - { "inf", 36, 24171, 3, }, - { "+inf", 0, 0, 0, }, - { "+inf", 2, 0, 0, }, - { "+inf", 8, 0, 0, }, - { "+inf", 9, 0, 0, }, - { "+inf", 10, 0, 0, }, - { "+inf", 16, 0, 0, }, - { "+inf", 36, 24171, 4, }, - { "-inf", 0, 0, 0, }, - { "-inf", 2, 0, 0, }, - { "-inf", 8, 0, 0, }, - { "-inf", 9, 0, 0, }, - { "-inf", 10, 0, 0, }, - { "-inf", 16, 0, 0, }, - { "-inf", 36, -24171, 4, }, - { "119b8Z", 0, 119, 3, }, - { "119bZ", 0, 119, 3, }, - { "-0119bZ", 0, -9, 4, }, - { " \t\n 0X119bZ", 0, 4507, 10, }, - { " \t\n +0X119bZ", 0, 4507, 11, }, - { " \t\n -0x119bZ", 0, -4507, 11, }, - { " \t\n 119bZ", 0, 119, 7, }, - { "+119bZ", 0, 119, 4, }, - { "+0X119bz", 0, 4507, 7, }, - { "119b8Z", 2, 3, 2, }, - { "119bZ", 2, 3, 2, }, - { "-0119bZ", 2, -3, 4, }, - { " \t\n 0X119bZ", 2, 0, 5, }, - { " \t\n +0X119bZ", 2, 0, 6, }, - { " \t\n -0x119bZ", 2, 0, 6, }, - { " \t\n 119bZ", 2, 3, 6, }, - { "+119bZ", 2, 3, 3, }, - { "+0X119bz", 2, 0, 2, }, - { "119b8Z", 8, 9, 2, }, - { "119bZ", 8, 9, 2, }, - { "-0119bZ", 8, -9, 4, }, - { " \t\n 0X119bZ", 8, 0, 5, }, - { " \t\n +0X119bZ", 8, 0, 6, }, - { " \t\n -0x119bZ", 8, 0, 6, }, - { " \t\n 119bZ", 8, 9, 6, }, - { "+119bZ", 8, 9, 3, }, - { "+0X119bz", 8, 0, 2, }, - { "119b8Z", 9, 10, 2, }, - { "119bZ", 9, 10, 2, }, - { "-0119bZ", 9, -10, 4, }, - { " \t\n 0X119bZ", 9, 0, 5, }, - { " \t\n +0X119bZ", 9, 0, 6, }, - { " \t\n -0x119bZ", 9, 0, 6, }, - { " \t\n 119bZ", 9, 10, 6, }, - { "+119bZ", 9, 10, 3, }, - { "+0X119bz", 9, 0, 2, }, - { "119b8Z", 10, 119, 3, }, - { "119bZ", 10, 119, 3, }, - { "-0119bZ", 10, -119, 5, }, - { " \t\n 0X119bZ", 10, 0, 5, }, - { " \t\n +0X119bZ", 10, 0, 6, }, - { " \t\n -0x119bZ", 10, 0, 6, }, - { " \t\n 119bZ", 10, 119, 7, }, - { "+119bZ", 10, 119, 4, }, - { "+0X119bz", 10, 0, 2, }, - { "119b8Z", 16, 72120, 5, }, - { "119bZ", 16, 4507, 4, }, - { "-0119bZ", 16, -4507, 6, }, - { " \t\n 0X119bZ", 16, 4507, 10, }, - { " \t\n +0X119bZ", 16, 4507, 11, }, - { " \t\n -0x119bZ", 16, -4507, 11, }, - { " \t\n 119bZ", 16, 4507,8, }, - { "+119bZ", 16, 4507, 5, }, - { "+0X119bz", 16, 4507, 7, }, - { "119b8Z", 36, 62580275, 6, }, - { "119bZ", 36, 1738367, 5, }, - { "-0119bZ", 36, -1738367, 7, }, - { " \t\n 0X119bZ", 36, 1997122175, 11, }, - { " \t\n +0X119bZ", 36, 1997122175, 12, }, - { " \t\n -0x119bZ", 36, -1997122175, 12, }, - { " \t\n 119bZ", 36, 1738367, 9, }, - { "+119bZ", 36, 1738367, 6, }, - { "+0X119bz", 36, 1997122175, 8, }, - /* There should be a much larger battery of such tests. */ - { "127", 0, 127, 3, }, - { "-127", 0, -127, 4, }, - { "128", 0, 128, 3, }, - { "-128", 0, -127-1, 4, }, - { "255", 0, 255, 3, }, - { "-255", 0, -255, 4, }, - { "256", 0, 256, 3, }, - { "-256", 0, -255-1, 4, }, - { "32767", 0, 32767, 5, }, - { "-32767", 0, -32767, 6, }, - { "32768", 0, 32768, 5, }, - { "-32768", 0, -32767-1, 6, }, - { "65535", 0, 65535, 5, }, - { "-65535", 0, -65536+1, 6, }, - { "65536", 0, 65536, 5, }, - { "-65536", 0, -65536, 6, }, - { "2147483647", 0, 2147483647, 10, }, - { "-2147483647", 0, -2147483647, 11, }, - { "2147483648", 0, 2147483648, 10, }, - { "-2147483648", 0, -2147483647-1, 11, }, - { "4294967295", 0, 4294967295, 10, }, - { "-4294967295", 0, -4294967296+1, 11, }, - { "4294967296", 0, 4294967296, 10, }, - { "-4294967296", 0, -4294967296, 11, }, - { "9223372036854775807", 0, 9223372036854775807, 19, }, - { "-9223372036854775807", 0, -9223372036854775807, 20, }, - { "1234567890123456789", 0, 1234567890123456789, 19, }, - { "-1234567890123456789", 0, -1234567890123456789, 20, }, - { "1", 0, 1, 1, }, - { "-1", 0, -1, 2, }, - { "2", 0, 2, 1, }, - { "-2", 0, -2, 2, }, - { "10", 0, 10, 2, }, - { "-10", 0, -10, 3, }, - { "16", 0, 16, 2, }, - { "-16", 0, -16, 3, }, - /* Other test cases can be added here. */ - { NULL, 0, 0, 0 }, /* terminates the list */ - }, *sdp; - - for ( sdp = str_data; sdp->nptr != NULL ; ++sdp ) - { - /* - 7.8.2.3 The strtoimax and strtoumax functions - */ - - strcpy(saved, sdp->nptr); - - errno = 0; /* shouldn't be changed */ - - if ( (intmax = strtoimax(sdp->nptr, &endptr, sdp->base)) - != sdp->exp_val - ) { - int save = errno; - - printf("*** strtoimax(%s,,%d) failed; should be: %" - PRIdMAX", was: %"PRIdMAX" ***\n", sdp->nptr, - sdp->base, sdp->exp_val, intmax - ); - status = EXIT_FAILURE; - errno = save; - } - else if ( endptr != sdp->nptr + sdp->exp_len ) - { - int save = errno; - - printf("*** strtoimax(%s,,%d) returned wrong endptr" - " ***\n", sdp->nptr, sdp->base - ); - status = EXIT_FAILURE; - errno = save; - } - - if ( errno != 0 ) - { - printf("*** strtoimax modified errno ***\n"); - status = EXIT_FAILURE; - } - - if ( strcmp(sdp->nptr, saved) != 0 ) - { - printf("*** strtoimax modified its input ***\n"); - status = EXIT_FAILURE; - strcpy(saved, sdp->nptr); - } - - if ( sdp->exp_val >= 0 ) /* else some sign extension */ - { - errno = 0; /* shouldn't be changed */ - - if ( (uintmax = strtoumax(sdp->nptr, &endptr, sdp->base - ) - ) != sdp->exp_val - ) { - int save = errno; - - printf("*** strtoumax(%s,,%d) failed; " - "should be: %"PRIuMAX", was: %"PRIuMAX - " ***\n", sdp->nptr, sdp->base, - sdp->exp_val, uintmax - ); - status = EXIT_FAILURE; - errno = save; - } - else if ( endptr != sdp->nptr + sdp->exp_len ) - { - int save = errno; - - printf("*** strtoumax(%s,,%d) returned wrong " - "endptr ***\n", sdp->nptr, sdp->base - ); - status = EXIT_FAILURE; - errno = save; - } - - if ( errno != 0 ) - { - printf("*** strtoumax modified errno ***\n"); - status = EXIT_FAILURE; - } - - if ( strcmp(sdp->nptr, saved) != 0 ) - { - printf("*** strtoumax" - " modified its input ***\n" - ); - status = EXIT_FAILURE; - strcpy(saved, sdp->nptr); - } - } - - /* tests for null endptr */ - -#define WARN() if (!warned) warned = 1, printf("*** Using null endptr: ***\n") - - warned = 0; - errno = 0; /* shouldn't be changed */ - - if ( (intmax = strtoimax(sdp->nptr, (char **)NULL, sdp->base)) - != sdp->exp_val - ) { - int save = errno; - - WARN(); - printf("*** strtoimax(%s,NULL,%d) failed; " - "should be: %"PRIdMAX", was: %"PRIdMAX" ***\n", - sdp->nptr, sdp->base, sdp->exp_val, intmax - ); - status = EXIT_FAILURE; - errno = save; - } - - if ( errno != 0 ) - { - WARN(); - printf("*** strtoimax modified errno ***\n"); - status = EXIT_FAILURE; - } - - if ( strcmp(sdp->nptr, saved) != 0 ) - { - WARN(); - printf("*** strtoimax modified its input ***\n"); - status = EXIT_FAILURE; - strcpy(saved, sdp->nptr); - } - - if ( sdp->exp_val >= 0 ) /* else some sign extension */ - { - errno = 0; /* shouldn't be changed */ - - if ( (uintmax = strtoumax(sdp->nptr, (char **)NULL, - sdp->base - ) - ) != sdp->exp_val - ) { - int save = errno; - - WARN(); - printf("*** strtoumax(%s,NULL,%d) failed; " - "should be: %"PRIuMAX", was: %"PRIuMAX - " ***\n", sdp->nptr, sdp->base, - sdp->exp_val, uintmax - ); - status = EXIT_FAILURE; - errno = save; - } - - if ( errno != 0 ) - { - WARN(); - printf("*** strtoumax modified errno ***\n"); - status = EXIT_FAILURE; - } - - if ( strcmp(sdp->nptr, saved) != 0 ) - { - WARN(); - printf("*** strtoumax" - " modified its input ***\n" - ); - status = EXIT_FAILURE; - strcpy(saved, sdp->nptr); - } - } - - /* - 7.8.2.4 The wcstoimax and wcstoumax functions - */ - - for ( i = 0; i < 64; ++i ) - if ( (wnptr[i] = sdp->nptr[i]) == '\0' ) - break; - - errno = 0; /* shouldn't be changed */ - - if ( (intmax = wcstoimax(wnptr, &wendptr, sdp->base)) - != sdp->exp_val - ) { - int save = errno; - - printf("*** wcstoimax(%s,,%d) failed; should be: %" - PRIdMAX", was: %"PRIdMAX" ***\n", sdp->nptr, - sdp->base, sdp->exp_val, intmax - ); - status = EXIT_FAILURE; - errno = save; - } - else if ( wendptr != wnptr + sdp->exp_len ) - { - int save = errno; - - printf("*** wcstoimax(%s,,%d) returned wrong endptr" - " ***\n", sdp->nptr, sdp->base - ); - status = EXIT_FAILURE; - errno = save; - } - - if ( errno != 0 ) - { - printf("*** wcstoimax modified errno ***\n"); - status = EXIT_FAILURE; - } - - for ( i = 0; i < 64; ++i ) - if ( wnptr[i] != sdp->nptr[i] ) - { - printf("*** wcstoimax modified its input ***\n" - ); - status = EXIT_FAILURE; - - for ( ; i < 64; ++i ) - if ( (wnptr[i] = sdp->nptr[i]) == '\0' ) - break; - - break; - } - else if ( wnptr[i] == '\0' ) - break; - - if ( sdp->exp_val >= 0 ) /* else some sign extension */ - { - errno = 0; /* shouldn't be changed */ - - if ( (uintmax = wcstoumax(wnptr, &wendptr, sdp->base) - ) != sdp->exp_val - ) { - int save = errno; - - printf("*** wcstoumax(%s,,%d) failed; " - "should be: %"PRIuMAX", was: %"PRIuMAX - " ***\n", sdp->nptr, sdp->base, - sdp->exp_val, uintmax - ); - status = EXIT_FAILURE; - errno = save; - } - else if ( wendptr != wnptr + sdp->exp_len ) - { - int save = errno; - - printf("*** wcstoumax(%s,,%d) returned wrong " - "endptr ***\n", sdp->nptr, sdp->base - ); - status = EXIT_FAILURE; - errno = save; - } - - if ( errno != 0 ) - { - printf("*** wcstoumax modified errno ***\n"); - status = EXIT_FAILURE; - } - - for ( i = 0; i < 64; ++i ) - if ( wnptr[i] != sdp->nptr[i] ) - { - printf("*** wcstoumax" - " modified its input ***\n" - ); - status = EXIT_FAILURE; - - for ( ; i < 64; ++i ) - if ( (wnptr[i] = sdp->nptr[i]) - == '\0' - ) - break; - - break; - } - else if ( wnptr[i] == '\0' ) - break; - } - - /* tests for null endptr */ - - warned = 0; - errno = 0; /* shouldn't be changed */ - - if ( (intmax = wcstoimax(wnptr, (wchar_t **)NULL, sdp->base)) - != sdp->exp_val - ) { - int save = errno; - - WARN(); - printf("*** wcstoimax(%s,NULL,%d) failed; should be: %" - PRIdMAX", was: %"PRIdMAX" ***\n", sdp->nptr, - sdp->base, sdp->exp_val, intmax - ); - status = EXIT_FAILURE; - errno = save; - } - - if ( errno != 0 ) - { - WARN(); - printf("*** wcstoimax modified errno ***\n"); - status = EXIT_FAILURE; - } - - for ( i = 0; i < 64; ++i ) - if ( wnptr[i] != sdp->nptr[i] ) - { - WARN(); - printf("*** wcstoimax modified its input ***\n" - ); - status = EXIT_FAILURE; - - for ( ; i < 64; ++i ) - if ( (wnptr[i] = sdp->nptr[i]) - == '\0' - ) - break; - - break; - } - else if ( wnptr[i] == '\0' ) - break; - - if ( sdp->exp_val >= 0 ) /* else some sign extension */ - { - errno = 0; /* shouldn't be changed */ - - if ( (uintmax = wcstoumax(wnptr, (wchar_t **)NULL, - sdp->base - ) - ) != sdp->exp_val - ) { - int save = errno; - - WARN(); - printf("*** wcstoumax(%s,NULL,%d) failed; " - "should be: %"PRIuMAX", was: %"PRIuMAX - " ***\n", sdp->nptr, sdp->base, - sdp->exp_val, uintmax - ); - status = EXIT_FAILURE; - errno = save; - } - - if ( errno != 0 ) - { - WARN(); - printf("*** wcstoumax modified errno ***\n"); - status = EXIT_FAILURE; - } - - for ( i = 0; i < 64; ++i ) - if ( wnptr[i] != sdp->nptr[i] ) - { - WARN(); - printf("*** wcstoumax" - " modified its input ***\n" - ); - status = EXIT_FAILURE; - - for ( ; i < 64; ++i ) - if ( (wnptr[i] = sdp->nptr[i]) - == '\0' - ) - break; - - break; - } - else if ( wnptr[i] == '\0' ) - break; - } - } - - /* - 7.8.2.3 The strtoimax and strtoumax functions (continued) - */ - - if ( (intmax = strtoimax("1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890", - &endptr, 0 - ) - ) != INTMAX_MAX || errno != ERANGE - ) { - printf("*** strtoimax failed overflow test ***\n"); - status = EXIT_FAILURE; - } - - if ( (intmax = strtoimax("+1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890", - &endptr, 0 - ) - ) != INTMAX_MAX || errno != ERANGE - ) { - printf("*** strtoimax failed +overflow test ***\n"); - status = EXIT_FAILURE; - } - - if ( (intmax = strtoimax("-1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890", - &endptr, 0 - ) - ) != INTMAX_MIN || errno != ERANGE - ) { - printf("*** strtoimax failed -overflow test ***\n"); - status = EXIT_FAILURE; - } - - if ( (uintmax = strtoumax("1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890", - &endptr, 0 - ) - ) != UINTMAX_MAX || errno != ERANGE - ) { - printf("*** strtoumax failed overflow test ***\n"); - status = EXIT_FAILURE; - } - - if ( (uintmax = strtoumax("+1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890", - &endptr, 0 - ) - ) != UINTMAX_MAX || errno != ERANGE - ) { - printf("*** strtoumax failed +overflow test ***\n"); - status = EXIT_FAILURE; - } - - if ( (uintmax = strtoumax("-1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890", - &endptr, 0 - ) - ) != UINTMAX_MAX || errno != ERANGE - ) { - printf("*** strtoumax failed -overflow test ***\n"); - status = EXIT_FAILURE; - } - - /* - 7.8.2.4 The wcstoimax and wcstoumax functions (continued) - */ + } + + { + char *endptr; + wchar_t *wendptr; + static char saved[64]; /* holds copy of input string */ + static wchar_t wnptr[64]; /* holds wide copy of test string */ + static int warned; /* "warned for null endptr" flag */ + register int i; + static struct + { + char * nptr; + int base; + intmax_t exp_val; + int exp_len; + } str_data[] = + { + { "", 0, 0, 0, }, + { "", 2, 0, 0, }, + { "", 8, 0, 0, }, + { "", 9, 0, 0, }, + { "", 10, 0, 0, }, + { "", 16, 0, 0, }, + { "", 36, 0, 0, }, + { "0", 0, 0, 1, }, + { "0", 2, 0, 1, }, + { "0", 8, 0, 1, }, + { "0", 9, 0, 1, }, + { "0", 10, 0, 1, }, + { "0", 16, 0, 1, }, + { "0", 36, 0, 1, }, + { "+0", 0, 0, 2, }, + { "+0", 2, 0, 2, }, + { "+0", 8, 0, 2, }, + { "+0", 9, 0, 2, }, + { "+0", 10, 0, 2, }, + { "+0", 16, 0, 2, }, + { "+0", 36, 0, 2, }, + { "-0", 0, 0, 2, }, + { "-0", 2, 0, 2, }, + { "-0", 8, 0, 2, }, + { "-0", 9, 0, 2, }, + { "-0", 10, 0, 2, }, + { "-0", 16, 0, 2, }, + { "-0", 36, 0, 2, }, + { "Inf", 0, 0, 0, }, + { "Inf", 2, 0, 0, }, + { "Inf", 8, 0, 0, }, + { "Inf", 9, 0, 0, }, + { "Inf", 10, 0, 0, }, + { "Inf", 16, 0, 0, }, + { "Inf", 36, 24171, 3, }, + { "+Inf", 0, 0, 0, }, + { "+Inf", 2, 0, 0, }, + { "+Inf", 8, 0, 0, }, + { "+Inf", 9, 0, 0, }, + { "+Inf", 10, 0, 0, }, + { "+Inf", 16, 0, 0, }, + { "+Inf", 36, 24171, 4, }, + { "-Inf", 0, 0, 0, }, + { "-Inf", 2, 0, 0, }, + { "-Inf", 8, 0, 0, }, + { "-Inf", 9, 0, 0, }, + { "-Inf", 10, 0, 0, }, + { "-Inf", 16, 0, 0, }, + { "-Inf", 36, -24171, 4, }, + { "inf", 0, 0, 0, }, + { "inf", 2, 0, 0, }, + { "inf", 8, 0, 0, }, + { "inf", 9, 0, 0, }, + { "inf", 10, 0, 0, }, + { "inf", 16, 0, 0, }, + { "inf", 36, 24171, 3, }, + { "+inf", 0, 0, 0, }, + { "+inf", 2, 0, 0, }, + { "+inf", 8, 0, 0, }, + { "+inf", 9, 0, 0, }, + { "+inf", 10, 0, 0, }, + { "+inf", 16, 0, 0, }, + { "+inf", 36, 24171, 4, }, + { "-inf", 0, 0, 0, }, + { "-inf", 2, 0, 0, }, + { "-inf", 8, 0, 0, }, + { "-inf", 9, 0, 0, }, + { "-inf", 10, 0, 0, }, + { "-inf", 16, 0, 0, }, + { "-inf", 36, -24171, 4, }, + { "119b8Z", 0, 119, 3, }, + { "119bZ", 0, 119, 3, }, + { "-0119bZ", 0, -9, 4, }, + { " \t\n 0X119bZ", 0, 4507, 10, }, + { " \t\n +0X119bZ", 0, 4507, 11, }, + { " \t\n -0x119bZ", 0, -4507, 11, }, + { " \t\n 119bZ", 0, 119, 7, }, + { "+119bZ", 0, 119, 4, }, + { "+0X119bz", 0, 4507, 7, }, + { "119b8Z", 2, 3, 2, }, + { "119bZ", 2, 3, 2, }, + { "-0119bZ", 2, -3, 4, }, + { " \t\n 0X119bZ", 2, 0, 5, }, + { " \t\n +0X119bZ", 2, 0, 6, }, + { " \t\n -0x119bZ", 2, 0, 6, }, + { " \t\n 119bZ", 2, 3, 6, }, + { "+119bZ", 2, 3, 3, }, + { "+0X119bz", 2, 0, 2, }, + { "119b8Z", 8, 9, 2, }, + { "119bZ", 8, 9, 2, }, + { "-0119bZ", 8, -9, 4, }, + { " \t\n 0X119bZ", 8, 0, 5, }, + { " \t\n +0X119bZ", 8, 0, 6, }, + { " \t\n -0x119bZ", 8, 0, 6, }, + { " \t\n 119bZ", 8, 9, 6, }, + { "+119bZ", 8, 9, 3, }, + { "+0X119bz", 8, 0, 2, }, + { "119b8Z", 9, 10, 2, }, + { "119bZ", 9, 10, 2, }, + { "-0119bZ", 9, -10, 4, }, + { " \t\n 0X119bZ", 9, 0, 5, }, + { " \t\n +0X119bZ", 9, 0, 6, }, + { " \t\n -0x119bZ", 9, 0, 6, }, + { " \t\n 119bZ", 9, 10, 6, }, + { "+119bZ", 9, 10, 3, }, + { "+0X119bz", 9, 0, 2, }, + { "119b8Z", 10, 119, 3, }, + { "119bZ", 10, 119, 3, }, + { "-0119bZ", 10, -119, 5, }, + { " \t\n 0X119bZ", 10, 0, 5, }, + { " \t\n +0X119bZ", 10, 0, 6, }, + { " \t\n -0x119bZ", 10, 0, 6, }, + { " \t\n 119bZ", 10, 119, 7, }, + { "+119bZ", 10, 119, 4, }, + { "+0X119bz", 10, 0, 2, }, + { "119b8Z", 16, 72120, 5, }, + { "119bZ", 16, 4507, 4, }, + { "-0119bZ", 16, -4507, 6, }, + { " \t\n 0X119bZ", 16, 4507, 10, }, + { " \t\n +0X119bZ", 16, 4507, 11, }, + { " \t\n -0x119bZ", 16, -4507, 11, }, + { " \t\n 119bZ", 16, 4507,8, }, + { "+119bZ", 16, 4507, 5, }, + { "+0X119bz", 16, 4507, 7, }, + { "119b8Z", 36, 62580275, 6, }, + { "119bZ", 36, 1738367, 5, }, + { "-0119bZ", 36, -1738367, 7, }, + { " \t\n 0X119bZ", 36, 1997122175, 11, }, + { " \t\n +0X119bZ", 36, 1997122175, 12, }, + { " \t\n -0x119bZ", 36, -1997122175, 12, }, + { " \t\n 119bZ", 36, 1738367, 9, }, + { "+119bZ", 36, 1738367, 6, }, + { "+0X119bz", 36, 1997122175, 8, }, + /* There should be a much larger battery of such tests. */ + { "127", 0, 127, 3, }, + { "-127", 0, -127, 4, }, + { "128", 0, 128, 3, }, + { "-128", 0, -127-1, 4, }, + { "255", 0, 255, 3, }, + { "-255", 0, -255, 4, }, + { "256", 0, 256, 3, }, + { "-256", 0, -255-1, 4, }, + { "32767", 0, 32767, 5, }, + { "-32767", 0, -32767, 6, }, + { "32768", 0, 32768, 5, }, + { "-32768", 0, -32767-1, 6, }, + { "65535", 0, 65535, 5, }, + { "-65535", 0, -65536+1, 6, }, + { "65536", 0, 65536, 5, }, + { "-65536", 0, -65536, 6, }, + { "2147483647", 0, 2147483647, 10, }, + { "-2147483647", 0, -2147483647, 11, }, + { "2147483648", 0, 2147483648, 10, }, + { "-2147483648", 0, -2147483647-1, 11, }, + { "4294967295", 0, 4294967295, 10, }, + { "-4294967295", 0, -4294967296+1, 11, }, + { "4294967296", 0, 4294967296, 10, }, + { "-4294967296", 0, -4294967296, 11, }, + { "9223372036854775807", 0, 9223372036854775807, 19, }, + { "-9223372036854775807", 0, -9223372036854775807, 20, }, + { "1234567890123456789", 0, 1234567890123456789, 19, }, + { "-1234567890123456789", 0, -1234567890123456789, 20, }, + { "1", 0, 1, 1, }, + { "-1", 0, -1, 2, }, + { "2", 0, 2, 1, }, + { "-2", 0, -2, 2, }, + { "10", 0, 10, 2, }, + { "-10", 0, -10, 3, }, + { "16", 0, 16, 2, }, + { "-16", 0, -16, 3, }, + /* Other test cases can be added here. */ + { NULL, 0, 0, 0 }, /* terminates the list */ + }, *sdp; + + for ( sdp = str_data; sdp->nptr != NULL ; ++sdp ) + { + /* + 7.8.2.3 The strtoimax and strtoumax functions + */ + + strcpy(saved, sdp->nptr); + + errno = 0; /* shouldn't be changed */ + + if ( (intmax = strtoimax(sdp->nptr, &endptr, sdp->base)) + != sdp->exp_val + ) { + int save = errno; + + printf("*** strtoimax(%s,,%d) failed; should be: %" + PRIdMAX", was: %"PRIdMAX" ***\n", sdp->nptr, + sdp->base, sdp->exp_val, intmax + ); + status = EXIT_FAILURE; + errno = save; + } + else if ( endptr != sdp->nptr + sdp->exp_len ) + { + int save = errno; + + printf("*** strtoimax(%s,,%d) returned wrong endptr" + " ***\n", sdp->nptr, sdp->base + ); + status = EXIT_FAILURE; + errno = save; + } + + if ( errno != 0 ) + { + printf("*** strtoimax modified errno ***\n"); + status = EXIT_FAILURE; + } + + if ( strcmp(sdp->nptr, saved) != 0 ) + { + printf("*** strtoimax modified its input ***\n"); + status = EXIT_FAILURE; + strcpy(saved, sdp->nptr); + } + + if ( sdp->exp_val >= 0 ) /* else some sign extension */ + { + errno = 0; /* shouldn't be changed */ + + if ( (uintmax = strtoumax(sdp->nptr, &endptr, sdp->base + ) + ) != sdp->exp_val + ) { + int save = errno; + + printf("*** strtoumax(%s,,%d) failed; " + "should be: %"PRIuMAX", was: %"PRIuMAX + " ***\n", sdp->nptr, sdp->base, + sdp->exp_val, uintmax + ); + status = EXIT_FAILURE; + errno = save; + } + else if ( endptr != sdp->nptr + sdp->exp_len ) + { + int save = errno; + + printf("*** strtoumax(%s,,%d) returned wrong " + "endptr ***\n", sdp->nptr, sdp->base + ); + status = EXIT_FAILURE; + errno = save; + } + + if ( errno != 0 ) + { + printf("*** strtoumax modified errno ***\n"); + status = EXIT_FAILURE; + } + + if ( strcmp(sdp->nptr, saved) != 0 ) + { + printf("*** strtoumax" + " modified its input ***\n" + ); + status = EXIT_FAILURE; + strcpy(saved, sdp->nptr); + } + } + + /* tests for null endptr */ + +#define WARN() if (!warned) warned = 1, printf("*** Using null endptr: ***\n") + + warned = 0; + errno = 0; /* shouldn't be changed */ + + if ( (intmax = strtoimax(sdp->nptr, (char **)NULL, sdp->base)) + != sdp->exp_val + ) { + int save = errno; + + WARN(); + printf("*** strtoimax(%s,NULL,%d) failed; " + "should be: %"PRIdMAX", was: %"PRIdMAX" ***\n", + sdp->nptr, sdp->base, sdp->exp_val, intmax + ); + status = EXIT_FAILURE; + errno = save; + } + + if ( errno != 0 ) + { + WARN(); + printf("*** strtoimax modified errno ***\n"); + status = EXIT_FAILURE; + } + + if ( strcmp(sdp->nptr, saved) != 0 ) + { + WARN(); + printf("*** strtoimax modified its input ***\n"); + status = EXIT_FAILURE; + strcpy(saved, sdp->nptr); + } + + if ( sdp->exp_val >= 0 ) /* else some sign extension */ + { + errno = 0; /* shouldn't be changed */ + + if ( (uintmax = strtoumax(sdp->nptr, (char **)NULL, + sdp->base + ) + ) != sdp->exp_val + ) { + int save = errno; + + WARN(); + printf("*** strtoumax(%s,NULL,%d) failed; " + "should be: %"PRIuMAX", was: %"PRIuMAX + " ***\n", sdp->nptr, sdp->base, + sdp->exp_val, uintmax + ); + status = EXIT_FAILURE; + errno = save; + } + + if ( errno != 0 ) + { + WARN(); + printf("*** strtoumax modified errno ***\n"); + status = EXIT_FAILURE; + } + + if ( strcmp(sdp->nptr, saved) != 0 ) + { + WARN(); + printf("*** strtoumax" + " modified its input ***\n" + ); + status = EXIT_FAILURE; + strcpy(saved, sdp->nptr); + } + } + + /* + 7.8.2.4 The wcstoimax and wcstoumax functions + */ + + for ( i = 0; i < 64; ++i ) + if ( (wnptr[i] = sdp->nptr[i]) == '\0' ) + break; + + errno = 0; /* shouldn't be changed */ + + if ( (intmax = wcstoimax(wnptr, &wendptr, sdp->base)) + != sdp->exp_val + ) { + int save = errno; + + printf("*** wcstoimax(%s,,%d) failed; should be: %" + PRIdMAX", was: %"PRIdMAX" ***\n", sdp->nptr, + sdp->base, sdp->exp_val, intmax + ); + status = EXIT_FAILURE; + errno = save; + } + else if ( wendptr != wnptr + sdp->exp_len ) + { + int save = errno; + + printf("*** wcstoimax(%s,,%d) returned wrong endptr" + " ***\n", sdp->nptr, sdp->base + ); + status = EXIT_FAILURE; + errno = save; + } + + if ( errno != 0 ) + { + printf("*** wcstoimax modified errno ***\n"); + status = EXIT_FAILURE; + } + + for ( i = 0; i < 64; ++i ) + if ( wnptr[i] != sdp->nptr[i] ) + { + printf("*** wcstoimax modified its input ***\n" + ); + status = EXIT_FAILURE; + + for ( ; i < 64; ++i ) + if ( (wnptr[i] = sdp->nptr[i]) == '\0' ) + break; + + break; + } + else if ( wnptr[i] == '\0' ) + break; + + if ( sdp->exp_val >= 0 ) /* else some sign extension */ + { + errno = 0; /* shouldn't be changed */ + + if ( (uintmax = wcstoumax(wnptr, &wendptr, sdp->base) + ) != sdp->exp_val + ) { + int save = errno; + + printf("*** wcstoumax(%s,,%d) failed; " + "should be: %"PRIuMAX", was: %"PRIuMAX + " ***\n", sdp->nptr, sdp->base, + sdp->exp_val, uintmax + ); + status = EXIT_FAILURE; + errno = save; + } + else if ( wendptr != wnptr + sdp->exp_len ) + { + int save = errno; + + printf("*** wcstoumax(%s,,%d) returned wrong " + "endptr ***\n", sdp->nptr, sdp->base + ); + status = EXIT_FAILURE; + errno = save; + } + + if ( errno != 0 ) + { + printf("*** wcstoumax modified errno ***\n"); + status = EXIT_FAILURE; + } + + for ( i = 0; i < 64; ++i ) + if ( wnptr[i] != sdp->nptr[i] ) + { + printf("*** wcstoumax" + " modified its input ***\n" + ); + status = EXIT_FAILURE; + + for ( ; i < 64; ++i ) + if ( (wnptr[i] = sdp->nptr[i]) + == '\0' + ) + break; + + break; + } + else if ( wnptr[i] == '\0' ) + break; + } + + /* tests for null endptr */ + + warned = 0; + errno = 0; /* shouldn't be changed */ + + if ( (intmax = wcstoimax(wnptr, (wchar_t **)NULL, sdp->base)) + != sdp->exp_val + ) { + int save = errno; + + WARN(); + printf("*** wcstoimax(%s,NULL,%d) failed; should be: %" + PRIdMAX", was: %"PRIdMAX" ***\n", sdp->nptr, + sdp->base, sdp->exp_val, intmax + ); + status = EXIT_FAILURE; + errno = save; + } + + if ( errno != 0 ) + { + WARN(); + printf("*** wcstoimax modified errno ***\n"); + status = EXIT_FAILURE; + } + + for ( i = 0; i < 64; ++i ) + if ( wnptr[i] != sdp->nptr[i] ) + { + WARN(); + printf("*** wcstoimax modified its input ***\n" + ); + status = EXIT_FAILURE; + + for ( ; i < 64; ++i ) + if ( (wnptr[i] = sdp->nptr[i]) + == '\0' + ) + break; + + break; + } + else if ( wnptr[i] == '\0' ) + break; + + if ( sdp->exp_val >= 0 ) /* else some sign extension */ + { + errno = 0; /* shouldn't be changed */ + + if ( (uintmax = wcstoumax(wnptr, (wchar_t **)NULL, + sdp->base + ) + ) != sdp->exp_val + ) { + int save = errno; + + WARN(); + printf("*** wcstoumax(%s,NULL,%d) failed; " + "should be: %"PRIuMAX", was: %"PRIuMAX + " ***\n", sdp->nptr, sdp->base, + sdp->exp_val, uintmax + ); + status = EXIT_FAILURE; + errno = save; + } + + if ( errno != 0 ) + { + WARN(); + printf("*** wcstoumax modified errno ***\n"); + status = EXIT_FAILURE; + } + + for ( i = 0; i < 64; ++i ) + if ( wnptr[i] != sdp->nptr[i] ) + { + WARN(); + printf("*** wcstoumax" + " modified its input ***\n" + ); + status = EXIT_FAILURE; + + for ( ; i < 64; ++i ) + if ( (wnptr[i] = sdp->nptr[i]) + == '\0' + ) + break; + + break; + } + else if ( wnptr[i] == '\0' ) + break; + } + } + + /* + 7.8.2.3 The strtoimax and strtoumax functions (continued) + */ + + if ( (intmax = strtoimax("1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890", + &endptr, 0 + ) + ) != INTMAX_MAX || errno != ERANGE + ) { + printf("*** strtoimax failed overflow test ***\n"); + status = EXIT_FAILURE; + } + + if ( (intmax = strtoimax("+1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890", + &endptr, 0 + ) + ) != INTMAX_MAX || errno != ERANGE + ) { + printf("*** strtoimax failed +overflow test ***\n"); + status = EXIT_FAILURE; + } + + if ( (intmax = strtoimax("-1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890", + &endptr, 0 + ) + ) != INTMAX_MIN || errno != ERANGE + ) { + printf("*** strtoimax failed -overflow test ***\n"); + status = EXIT_FAILURE; + } + + if ( (uintmax = strtoumax("1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890", + &endptr, 0 + ) + ) != UINTMAX_MAX || errno != ERANGE + ) { + printf("*** strtoumax failed overflow test ***\n"); + status = EXIT_FAILURE; + } + + if ( (uintmax = strtoumax("+1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890", + &endptr, 0 + ) + ) != UINTMAX_MAX || errno != ERANGE + ) { + printf("*** strtoumax failed +overflow test ***\n"); + status = EXIT_FAILURE; + } + + if ( (uintmax = strtoumax("-1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890", + &endptr, 0 + ) + ) != UINTMAX_MAX || errno != ERANGE + ) { + printf("*** strtoumax failed -overflow test ***\n"); + status = EXIT_FAILURE; + } + + /* + 7.8.2.4 The wcstoimax and wcstoumax functions (continued) + */ #ifdef NO_INTERNAL_WCHAR - printf("NO_INTERNAL_WCHAR\n"); + printf("NO_INTERNAL_WCHAR\n"); #else - if ( (intmax = wcstoimax(L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890", - &wendptr, 0 - ) - ) != INTMAX_MAX || errno != ERANGE - ) { - printf("*** wcstoimax failed overflow test ***\n"); - status = EXIT_FAILURE; - } + if ( (intmax = wcstoimax(L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890", + &wendptr, 0 + ) + ) != INTMAX_MAX || errno != ERANGE + ) { + printf("*** wcstoimax failed overflow test ***\n"); + status = EXIT_FAILURE; + } - if ( (intmax = wcstoimax(L"+1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890", - &wendptr, 0 - ) - ) != INTMAX_MAX || errno != ERANGE - ) { - printf("*** wcstoimax failed +overflow test ***\n"); - status = EXIT_FAILURE; - } + if ( (intmax = wcstoimax(L"+1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890", + &wendptr, 0 + ) + ) != INTMAX_MAX || errno != ERANGE + ) { + printf("*** wcstoimax failed +overflow test ***\n"); + status = EXIT_FAILURE; + } - if ( (intmax = wcstoimax(L"-1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890", - &wendptr, 0 - ) - ) != INTMAX_MIN || errno != ERANGE - ) { - printf("*** wcstoimax failed -overflow test ***\n"); - status = EXIT_FAILURE; - } + if ( (intmax = wcstoimax(L"-1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890", + &wendptr, 0 + ) + ) != INTMAX_MIN || errno != ERANGE + ) { + printf("*** wcstoimax failed -overflow test ***\n"); + status = EXIT_FAILURE; + } - if ( (uintmax = wcstoumax(L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890", - &wendptr, 0 - ) - ) != UINTMAX_MAX || errno != ERANGE - ) { - printf("*** wcstoumax failed overflow test ***\n"); - status = EXIT_FAILURE; - } + if ( (uintmax = wcstoumax(L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890", + &wendptr, 0 + ) + ) != UINTMAX_MAX || errno != ERANGE + ) { + printf("*** wcstoumax failed overflow test ***\n"); + status = EXIT_FAILURE; + } - if ( (uintmax = wcstoumax(L"+1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890", - &wendptr, 0 - ) - ) != UINTMAX_MAX || errno != ERANGE - ) { - printf("*** wcstoumax failed +overflow test ***\n"); - status = EXIT_FAILURE; - } + if ( (uintmax = wcstoumax(L"+1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890", + &wendptr, 0 + ) + ) != UINTMAX_MAX || errno != ERANGE + ) { + printf("*** wcstoumax failed +overflow test ***\n"); + status = EXIT_FAILURE; + } - if ( (uintmax = wcstoumax(L"-1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890" - L"1234567890123456789012345678901234567890", - &wendptr, 0 - ) - ) != UINTMAX_MAX || errno != ERANGE - ) { - printf("*** wcstoumax failed -overflow test ***\n"); - status = EXIT_FAILURE; - } + if ( (uintmax = wcstoumax(L"-1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890" + L"1234567890123456789012345678901234567890", + &wendptr, 0 + ) + ) != UINTMAX_MAX || errno != ERANGE + ) { + printf("*** wcstoumax failed -overflow test ***\n"); + status = EXIT_FAILURE; + } #endif // NO_INTERNAL_WCHAR - } -#endif /* defined(INTMAX_MAX) */ + } +#endif /* defined(INTMAX_MAX) */ - if ( status != 0 ) - printf("sitest failed.\n"); + if ( status != 0 ) + printf("sitest failed.\n"); - return status; + return status; } #endif \ No newline at end of file diff --git a/test/ref/8q.c b/test/ref/8q.c index e8bd1ca2e..2055b5fd5 100644 --- a/test/ref/8q.c +++ b/test/ref/8q.c @@ -12,38 +12,38 @@ void print(void); int main(void) { - int i; - for (i = 0; i < 15; i++) - up[i] = down[i] = 1; - for (i = 0; i < 8; i++) - rows[i] = 1; - queens(0); - return 0; + int i; + for (i = 0; i < 15; i++) + up[i] = down[i] = 1; + for (i = 0; i < 8; i++) + rows[i] = 1; + queens(0); + return 0; } void queens(int c) { - int r; + int r; - for (r = 0; r < 8; r++) - if (rows[r] && up[r-c+7] && down[r+c]) { - rows[r] = up[r-c+7] = down[r+c] = 0; - x[c] = r; - if (c == 7) - print(); - else - queens(c + 1); - rows[r] = up[r-c+7] = down[r+c] = 1; - } + for (r = 0; r < 8; r++) + if (rows[r] && up[r-c+7] && down[r+c]) { + rows[r] = up[r-c+7] = down[r+c] = 0; + x[c] = r; + if (c == 7) + print(); + else + queens(c + 1); + rows[r] = up[r-c+7] = down[r+c] = 1; + } } void print(void) { - int k; + int k; - for (k = 0; k < 8; k++) { - printf("%c", x[k]+'1'); - if(k<7) printf(" "); - } - printf("\n"); + for (k = 0; k < 8; k++) { + printf("%c", x[k]+'1'); + if(k<7) printf(" "); + } + printf("\n"); } diff --git a/test/ref/array.c b/test/ref/array.c index 9d170aaa9..96bf22c3a 100644 --- a/test/ref/array.c +++ b/test/ref/array.c @@ -14,49 +14,49 @@ int g(int x[][4],int *y[]); int x[3][4], *y[3]; main() { - int z[3][4]; - int i, j, *p; + int z[3][4]; + int i, j, *p; - for (i = 0; i < 3; i++) { - for (j = 0; j < 4; j++) - x[i][j] = 1000*i + j; - y[i] = x[i]; - } - f(); - for (i = 0; i < 3; i++) { - y[i] = p = &z[i][0]; - for (j = 0; j < 4; j++) - p[j] = x[i][j]; - } - g(z, y); - - return 0; + for (i = 0; i < 3; i++) { + for (j = 0; j < 4; j++) + x[i][j] = 1000*i + j; + y[i] = x[i]; + } + f(); + for (i = 0; i < 3; i++) { + y[i] = p = &z[i][0]; + for (j = 0; j < 4; j++) + p[j] = x[i][j]; + } + g(z, y); + + return 0; } f() { - int i, j; + int i, j; - for (i = 0; i < 3; i++) - for (j = 0; j < 4; j++) - printf(" %d", x[i][j]); - printf("\n"); - for (i = 0; i < 3; i++) - for (j = 0; j < 4; j++) - printf(" %d", y[i][j]); - printf("\n"); + for (i = 0; i < 3; i++) + for (j = 0; j < 4; j++) + printf(" %d", x[i][j]); + printf("\n"); + for (i = 0; i < 3; i++) + for (j = 0; j < 4; j++) + printf(" %d", y[i][j]); + printf("\n"); } g(x, y) int x[][4], *y[]; { - int i, j; + int i, j; - for (i = 0; i < 3; i++) - for (j = 0; j < 4; j++) - printf(" %d", x[i][j]); - printf("\n"); - for (i = 0; i < 3; i++) - for (j = 0; j < 4; j++) - printf(" %d", y[i][j]); - printf("\n"); + for (i = 0; i < 3; i++) + for (j = 0; j < 4; j++) + printf(" %d", x[i][j]); + printf("\n"); + for (i = 0; i < 3; i++) + for (j = 0; j < 4; j++) + printf(" %d", y[i][j]); + printf("\n"); } diff --git a/test/ref/cc65070303.c b/test/ref/cc65070303.c index c0404dab8..6dbceeefc 100644 --- a/test/ref/cc65070303.c +++ b/test/ref/cc65070303.c @@ -9,17 +9,17 @@ typedef signed int TypA[3]; typedef struct TypB { - TypA Data[2]; + TypA Data[2]; } sTypB; sTypB Bs[10]; TypA * APtr; int main(int argc, char* argv[]) { - Bs[7].Data[1][2]=11; - APtr=&(Bs[7].Data[1]); - printf("Hallo Welt! %i = %i \n",Bs[7].Data[1][2], (*APtr)[2] ); - return 0; + Bs[7].Data[1][2]=11; + APtr=&(Bs[7].Data[1]); + printf("Hallo Welt! %i = %i \n",Bs[7].Data[1][2], (*APtr)[2] ); + return 0; } /* diff --git a/test/ref/cc65090726.c b/test/ref/cc65090726.c index b260f0afd..609594dc4 100644 --- a/test/ref/cc65090726.c +++ b/test/ref/cc65090726.c @@ -17,26 +17,26 @@ typedef RecordType *RecordPtr; void Proc3(RecordPtr *PtrParOut) { - /* whatever */ + /* whatever */ } void Proc1(RecordPtr PtrParIn) { #define NextRecord (*(PtrParIn->PtrComp)) - Proc3((RecordPtr *)NextRecord.PtrComp); - Proc3(&NextRecord.PtrComp); - Proc3(&PtrParIn->PtrComp->PtrComp); + Proc3((RecordPtr *)NextRecord.PtrComp); + Proc3(&NextRecord.PtrComp); + Proc3(&PtrParIn->PtrComp->PtrComp); #ifdef CAST_STRUCT_PTR - Proc3((RecordPtr *) PtrParIn->PtrComp->PtrComp); - Proc3((RecordPtr *) (*(PtrParIn->PtrComp)).PtrComp); - Proc3((RecordPtr *) NextRecord.PtrComp); + Proc3((RecordPtr *) PtrParIn->PtrComp->PtrComp); + Proc3((RecordPtr *) (*(PtrParIn->PtrComp)).PtrComp); + Proc3((RecordPtr *) NextRecord.PtrComp); #else - Proc3(PtrParIn->PtrComp->PtrComp); - Proc3((*(PtrParIn->PtrComp)).PtrComp); - Proc3(NextRecord.PtrComp); + Proc3(PtrParIn->PtrComp->PtrComp); + Proc3((*(PtrParIn->PtrComp)).PtrComp); + Proc3(NextRecord.PtrComp); #endif - + #undef NextRecord } diff --git a/test/ref/cc65090910.c b/test/ref/cc65090910.c index 6ac5d9dcb..d68c2b8e6 100644 --- a/test/ref/cc65090910.c +++ b/test/ref/cc65090910.c @@ -17,7 +17,7 @@ with compiler option -O but does _not_ show up with -Oi. unsigned htons(unsigned val) { - return (((unsigned) (val)) << 8) | (((unsigned) (val)) >> 8); + return (((unsigned) (val)) << 8) | (((unsigned) (val)) >> 8); } int main(void) diff --git a/test/ref/cc65090913.c b/test/ref/cc65090913.c index da6e37ef3..3a92dc6ec 100644 --- a/test/ref/cc65090913.c +++ b/test/ref/cc65090913.c @@ -25,7 +25,7 @@ int foo=0,bar=2; int main(void) { while(foo<bar) - label: ++foo; + label: ++foo; printf("foo: %d bar: %d\n",foo,bar); diff --git a/test/ref/cf.c b/test/ref/cf.c index 66fb42b10..bb0c13e8b 100644 --- a/test/ref/cf.c +++ b/test/ref/cf.c @@ -33,9 +33,9 @@ int argc; char *argv[]; #endif { - int i, c, nc; + int i, c, nc; #ifndef NO_FLOATS - float cutoff, atof(); + float cutoff, atof(); #else signed cutoff; #endif @@ -45,22 +45,22 @@ char *argv[]; return EXIT_FAILURE; } - if (argc <= 1) + if (argc <= 1) #ifndef NO_FLOATS - cutoff = 0.0; + cutoff = 0.0; #else cutoff = 0; #endif - else + else #ifndef NO_FLOATS - cutoff = atof(argv[1])/100; + cutoff = atof(argv[1])/100; #else cutoff = atoi(argv[1])/100; #endif - for (i = 0; i < 0x100; ) + for (i = 0; i < 0x100; ) { #ifndef NO_FLOATS - f[i++] = 0.0; + f[i++] = 0.0; #else f[i++] = 0; #endif @@ -87,13 +87,13 @@ char *argv[]; printf("a-z char:freq\n\n"); /* first round ... lowercase characters */ - for (i = 0; i < 0x100; ++i) + for (i = 0; i < 0x100; ++i) { - if ((f[i]) && ((f[i]/nc) >= cutoff)) + if ((f[i]) && ((f[i]/nc) >= cutoff)) { - if ((i >= 'a') && (i <= 'z')) + if ((i >= 'a') && (i <= 'z')) { - printf("%c", i); + printf("%c", i); #ifndef NO_FLOATS printf(":%.1f\n", 100*f[i]/nc); #else @@ -101,19 +101,19 @@ char *argv[]; #endif f[i]=0; } - } + } } printf("A-Z char:freq\n\n"); /* second round ... uppercase characters */ - for (i = 0; i < 0x100; ++i) + for (i = 0; i < 0x100; ++i) { - if ((f[i]) && ((f[i]/nc) >= cutoff)) + if ((f[i]) && ((f[i]/nc) >= cutoff)) { - if ((i >= 'A') && (i <= 'Z')) + if ((i >= 'A') && (i <= 'Z')) { - printf("%c", i); + printf("%c", i); #ifndef NO_FLOATS printf(":%.1f\n", 100*f[i]/nc); #else @@ -121,19 +121,19 @@ char *argv[]; #endif f[i]=0; } - } + } } printf("0-9 char:freq\n\n"); /* third round ... numbers */ - for (i = 0; i < 0x100; ++i) + for (i = 0; i < 0x100; ++i) { - if ((f[i]) && ((f[i]/nc) >= cutoff)) + if ((f[i]) && ((f[i]/nc) >= cutoff)) { - if ((i >= '0') && (i <= '9')) + if ((i >= '0') && (i <= '9')) { - printf("%c", i); + printf("%c", i); #ifndef NO_FLOATS printf(":%.1f\n", 100*f[i]/nc); #else @@ -141,19 +141,19 @@ char *argv[]; #endif f[i]=0; } - } + } } printf("isprint char:freq\n\n"); /* second last round ... remaining printable characters */ - for (i = 0; i < 0x100; ++i) + for (i = 0; i < 0x100; ++i) { - if ((f[i]) && ((f[i]/nc) >= cutoff)) + if ((f[i]) && ((f[i]/nc) >= cutoff)) { - if(isprint(i)) + if(isprint(i)) { - printf("%c", i); + printf("%c", i); #ifndef NO_FLOATS printf(":%.1f\n", 100*f[i]/nc); #else @@ -161,30 +161,30 @@ char *argv[]; #endif f[i]=0; } - } + } } printf("rest char:freq\n\n"); /* last round ... remaining non printable characters */ - for (i = 0; i < 0x100; ++i) + for (i = 0; i < 0x100; ++i) { - if ((f[i]) && ((f[i]/nc) >= cutoff)) + if ((f[i]) && ((f[i]/nc) >= cutoff)) { if(i=='\n') { - printf("newline"); + printf("newline"); } else { - printf("%03o", i); + printf("%03o", i); } #ifndef NO_FLOATS printf(":%.1f\n", 100*f[i]/nc); #else printf(":%d\n", 100*f[i]/nc); #endif - } + } } fclose(in); return 0; diff --git a/test/ref/charconst.c b/test/ref/charconst.c index 65ebc70be..1a2f5303d 100644 --- a/test/ref/charconst.c +++ b/test/ref/charconst.c @@ -14,23 +14,23 @@ void backslash(unsigned char c) switch (c) { - case 'b': - c = '\b'; - case 'f': - c = '\f'; - case 'n': - c = '\n'; - case 'r': - c = '\r'; - case 't': - c = '\t'; - case 'v': + case 'b': + c = '\b'; + case 'f': + c = '\f'; + case 'n': + c = '\n'; + case 'r': + c = '\r'; + case 't': + c = '\t'; + case 'v': #ifndef NO_BACKSLASH_V c = '\v'; #else c = 0x0b; #endif - } + } if(!isprint(c)) { @@ -54,7 +54,7 @@ void testbackslash(void) int main(void) { - testbackslash(); + testbackslash(); - return 0; + return 0; } diff --git a/test/ref/charset.c b/test/ref/charset.c index 59b7c4c54..8bd1675c8 100644 --- a/test/ref/charset.c +++ b/test/ref/charset.c @@ -12,82 +12,82 @@ /* this kind of line-continuation for strings doesnt work properly for cc65 */ const unsigned char characters[]={ - /*0123456789abcdef0123456789abcdef*/ - /* iso646-us control-characters */ - " " /* 00-1f */ - /* iso646-us printable characters */ - " !\"#$%&'()*+,-./" /* 20-2f !"#$%&'()*+,-./ */ - "0123456789" /* 30-39 0123456789 */ - ":;<=>?@" /* 3a-40 :;<=>?@ */ - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" /* 41-5a A-Z */ - "[\\]^_`" /* 5b-60 [\]^_` */ - "abcdefghijklmnopqrstuvwxyz" /* 61-7a a-z */ - "{|}~ " /* 7b-7f {|}~ */ - /* iso8859-15 extended characters */ + /*0123456789abcdef0123456789abcdef*/ + /* iso646-us control-characters */ + " " /* 00-1f */ + /* iso646-us printable characters */ + " !\"#$%&'()*+,-./" /* 20-2f !"#$%&'()*+,-./ */ + "0123456789" /* 30-39 0123456789 */ + ":;<=>?@" /* 3a-40 :;<=>?@ */ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" /* 41-5a A-Z */ + "[\\]^_`" /* 5b-60 [\]^_` */ + "abcdefghijklmnopqrstuvwxyz" /* 61-7a a-z */ + "{|}~ " /* 7b-7f {|}~ */ + /* iso8859-15 extended characters */ }; #endif const unsigned char characters[]={ - /*0123456789abcdef0123456789abcdef*/ - /* iso646-us control-characters */ - /* 00-1f */ - 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,0x00, - /* iso646-us printable characters */ - /* 20-2f !"#$%&'()*+,-./ */ - ' ','!','"','#','$','%','&','\'','(',')','*','+',',','-','.','/', - /* 30-39 0123456789 */ - '0','1','2','3','4','5','6','7','8','9', - /* 3a-40 :;<=>?@ */ - ':',';','<','=','>','?','@', - /* 41-5a A-Z */ - 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z', - /* 5b-60 [\]^_` */ - '[','\\',']','^','_','`', - /* 61-7a a-z */ - 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', - /* 7b-7f {|}~ */ - '{','|','}','~',' ' - /* iso8859-15 extended characters */ + /*0123456789abcdef0123456789abcdef*/ + /* iso646-us control-characters */ + /* 00-1f */ + 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,0x00, + /* iso646-us printable characters */ + /* 20-2f !"#$%&'()*+,-./ */ + ' ','!','"','#','$','%','&','\'','(',')','*','+',',','-','.','/', + /* 30-39 0123456789 */ + '0','1','2','3','4','5','6','7','8','9', + /* 3a-40 :;<=>?@ */ + ':',';','<','=','>','?','@', + /* 41-5a A-Z */ + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z', + /* 5b-60 [\]^_` */ + '[','\\',']','^','_','`', + /* 61-7a a-z */ + 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', + /* 7b-7f {|}~ */ + '{','|','}','~',' ' + /* iso8859-15 extended characters */ }; void printchars(unsigned char a,unsigned char b){ - for(b++;a!=b;a++) + for(b++;a!=b;a++) /* printf("%02x ",a); */ /* printf("%02x ",characters[a]); */ - printf("%c",characters[a]); - printf("\n"); + printf("%c",characters[a]); + printf("\n"); } int main(void) { - printf("characters:\n\n"); - printchars(0x61,0x7a); - printchars(0x41,0x5a); - printf("numbers:\n\n"); - printchars(0x30,0x39); - printf("other:\n\n"); - printchars(0x20,0x2f); - /*printchars(0x3a,0x40);*/ - printchars(0x3a,0x3f); - /*printchars(0x5b,0x60);*/ - /*printchars(0x7b,0x7f);*/ - printf("\n\n"); - printf("slash: '%c'\n",'/'); - printf("backslash: '%c'\n",'\\'); - printf("curly braces open: '%c'\n",'{'); - printf("curly braces close: '%c'\n",'}'); - printf("square braces open: '%c'\n",'['); - printf("square braces close: '%c'\n",']'); - printf("underscore: '%c'\n",'_'); - printf("tilde: '%c'\n",'~'); - printf("pipe: '%c'\n",'|'); - printf("apostroph: '%c'\n",'\''); - printf("single quote '%c'\n",'`'); - printf("xor '%c'\n",'^'); - printf("at '%c'\n",'@'); + printf("characters:\n\n"); + printchars(0x61,0x7a); + printchars(0x41,0x5a); + printf("numbers:\n\n"); + printchars(0x30,0x39); + printf("other:\n\n"); + printchars(0x20,0x2f); + /*printchars(0x3a,0x40);*/ + printchars(0x3a,0x3f); + /*printchars(0x5b,0x60);*/ + /*printchars(0x7b,0x7f);*/ + printf("\n\n"); + printf("slash: '%c'\n",'/'); + printf("backslash: '%c'\n",'\\'); + printf("curly braces open: '%c'\n",'{'); + printf("curly braces close: '%c'\n",'}'); + printf("square braces open: '%c'\n",'['); + printf("square braces close: '%c'\n",']'); + printf("underscore: '%c'\n",'_'); + printf("tilde: '%c'\n",'~'); + printf("pipe: '%c'\n",'|'); + printf("apostroph: '%c'\n",'\''); + printf("single quote '%c'\n",'`'); + printf("xor '%c'\n",'^'); + printf("at '%c'\n",'@'); - return 0; + return 0; } diff --git a/test/ref/divmod.c b/test/ref/divmod.c index 8fcc951a6..e5535ebc4 100644 --- a/test/ref/divmod.c +++ b/test/ref/divmod.c @@ -8,31 +8,31 @@ void printc(signed char a,signed char b){ signed char x=a/b,y=a%b,z=a*b; - printf("%3d,%3d is %3d,%3d,%3d\n",a,b,x,y,z); + printf("%3d,%3d is %3d,%3d,%3d\n",a,b,x,y,z); } void prints(short a,short b){ short x=a/b,y=a%b,z=a*b; - printf("%3d,%3d is %3d,%3d,%3d\n",a,b,x,y,z); + printf("%3d,%3d is %3d,%3d,%3d\n",a,b,x,y,z); } void printl(long a,long b){ long x=a/b,y=a%b,z=a*b; - printf("%3ld,%3ld is %3ld,%3ld,%3ld\n",a,b,x,y,z); + printf("%3ld,%3ld is %3ld,%3ld,%3ld\n",a,b,x,y,z); } int main(void) { - printl( 3,-2); - printl(-3,-2); - printl(-3, 2); - printl( 3, 2); - printf("-\n"); - prints( 3,-2); - prints(-3,-2); - prints(-3, 2); - prints( 3, 2); - printf("-\n"); - printc( 3,-2); - printc(-3,-2); - printc(-3, 2); - printc( 3, 2); - return 0; + printl( 3,-2); + printl(-3,-2); + printl(-3, 2); + printl( 3, 2); + printf("-\n"); + prints( 3,-2); + prints(-3,-2); + prints(-3, 2); + prints( 3, 2); + printf("-\n"); + printc( 3,-2); + printc(-3,-2); + printc(-3, 2); + printc( 3, 2); + return 0; } diff --git a/test/ref/hanoi.c b/test/ref/hanoi.c index 234ac41e4..5198c5c61 100644 --- a/test/ref/hanoi.c +++ b/test/ref/hanoi.c @@ -11,8 +11,8 @@ ******************************************************************************* * Bug reports, patches, comments, suggestions should be sent to: * - * Ben Smith, Rick Grehan or Tom Yager - * ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com + * Ben Smith, Rick Grehan or Tom Yager + * ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com * ******************************************************************************* * Modification Log: @@ -38,53 +38,53 @@ void mov(unsigned char n,unsigned char f,unsigned char t) { char o; - if(n == 1) - { - num[f]--; - num[t]++; - } - else - { - o = (6-(f+t)); - mov(n-1,f,o); - mov(1,f,t); - mov(n-1,o,t); - } + if(n == 1) + { + num[f]--; + num[t]++; + } + else + { + o = (6-(f+t)); + mov(n-1,f,o); + mov(1,f,t); + mov(n-1,o,t); + } - #ifdef VERBOSE - printf("%2d: %2d %2d %2d %2d\n", - (int)iter,(int)num[0],(int)num[1],(int)num[2],(int)num[3]); - #endif + #ifdef VERBOSE + printf("%2d: %2d %2d %2d %2d\n", + (int)iter,(int)num[0],(int)num[1],(int)num[2],(int)num[3]); + #endif } int main(int argc,char **argv) { - #ifdef USECMDLINE - if (argc < 2) { - printf("Usage: %s [duration] [disks]\n", argv[0]); - exit(1); - } - else - { - if(argc > 1) duration = atoi(argv[1]); - if(argc > 2) disk = atoi(argv[2]); - } - #endif + #ifdef USECMDLINE + if (argc < 2) { + printf("Usage: %s [duration] [disks]\n", argv[0]); + exit(1); + } + else + { + if(argc > 1) duration = atoi(argv[1]); + if(argc > 2) disk = atoi(argv[2]); + } + #endif - printf("towers of hanoi\ndisks: %d\n\n",disk); + printf("towers of hanoi\ndisks: %d\n\n",disk); - num[1] = disk; + num[1] = disk; - #ifdef VERBOSE - printf("%2d: %2d %2d %2d %2d\n", - (int)iter,(int)num[0],(int)num[1],(int)num[2],(int)num[3]); - #endif + #ifdef VERBOSE + printf("%2d: %2d %2d %2d %2d\n", + (int)iter,(int)num[0],(int)num[1],(int)num[2],(int)num[3]); + #endif - while(num[3]<disk) - { - mov(disk,1,3); - ++iter; - } + while(num[3]<disk) + { + mov(disk,1,3); + ++iter; + } - return 0; + return 0; } diff --git a/test/ref/incr.c b/test/ref/incr.c index adce0e1c0..5e2a78764 100644 --- a/test/ref/incr.c +++ b/test/ref/incr.c @@ -13,39 +13,39 @@ int main(void) } memchar() { - char x, *p; + char x, *p; - &x, &p; - x = *p++; - x = *++p; - x = *p--; - x = *--p; + &x, &p; + x = *p++; + x = *++p; + x = *p--; + x = *--p; } memint() { - int x, *p; + int x, *p; - &x, &p; - x = *p++; - x = *++p; - x = *p--; - x = *--p; + &x, &p; + x = *p++; + x = *++p; + x = *p--; + x = *--p; } regchar() { - register char x, *p; + register char x, *p; - x = *p++; - x = *++p; - x = *p--; - x = *--p; + x = *p++; + x = *++p; + x = *p--; + x = *--p; } regint() { - register int x, *p; + register int x, *p; - x = *p++; - x = *++p; - x = *p--; - x = *--p; + x = *p++; + x = *++p; + x = *p--; + x = *--p; } diff --git a/test/ref/init.c b/test/ref/init.c index 44cd544fd..3742446d6 100644 --- a/test/ref/init.c +++ b/test/ref/init.c @@ -26,7 +26,7 @@ h(); /* Word words[] = { 1, 2, 3,"if", - { { 4, 5 }, { 'f', 'o', 'r' } }, + { { 4, 5 }, { 'f', 'o', 'r' } }, 6, 7, 8, {"else"}, { { 9, 10, 11,}, 'w', 'h', 'i', 'l', 'e', }, { 0 }, @@ -35,7 +35,7 @@ Word words[] = { Word words[] = { {{1, 2, 3},"if"}, - { { 4, 5 }, { 'f', 'o', 'r' } }, + { { 4, 5 }, { 'f', 'o', 'r' } }, {{6, 7, 8}, "else"}, { { 9, 10, 11}, {'w', 'h', 'i', 'l', 'e', }}, {{ 0 }}, @@ -47,24 +47,24 @@ int *y[] = { x[0], x[1], x[2], 0 }; main() { - int i, j; + int i, j; - for (i = 0; y[i]; i++) { - for (j = 0; y[i][j]; j++) - printf(" %d", y[i][j]); - printf("\n"); - } - f(); - g(wordlist); - return 0; + for (i = 0; y[i]; i++) { + for (j = 0; y[i][j]; j++) + printf(" %d", y[i][j]); + printf("\n"); + } + f(); + g(wordlist); + return 0; } f() { - static char *keywords[] = {"if", "for", "else", "while", 0, }; - char **p; + static char *keywords[] = {"if", "for", "else", "while", 0, }; + char **p; - for (p = keywords; *p; p++) - printf("%s\n", *p); + for (p = keywords; *p; p++) + printf("%s\n", *p); } #ifdef NO_OLD_FUNC_DECL @@ -74,22 +74,22 @@ g(p) Word *p; #endif { - int i; + int i; - for ( ; p->codes[0]; p++) { - for (i = 0; i < sizeof p->codes/sizeof(p->codes[0]); i++) - printf("%d ", p->codes[i]); - printf("%s\n", p->name); - } - h(); + for ( ; p->codes[0]; p++) { + for (i = 0; i < sizeof p->codes/sizeof(p->codes[0]); i++) + printf("%d ", p->codes[i]); + printf("%s\n", p->name); + } + h(); } h() { - int i; + int i; - for (i = 0; i < sizeof(words)/sizeof(Word); i++) - printf("%d %d %d %s\n", words[i].codes[0], - words[i].codes[1], words[i].codes[2], - &words[i].name[0]); + for (i = 0; i < sizeof(words)/sizeof(Word); i++) + printf("%d %d %d %s\n", words[i].codes[0], + words[i].codes[1], words[i].codes[2], + &words[i].name[0]); } diff --git a/test/ref/macro.c b/test/ref/macro.c index 1650b98db..c1346b939 100644 --- a/test/ref/macro.c +++ b/test/ref/macro.c @@ -14,17 +14,17 @@ unsigned long a=3; unsigned long _func(unsigned long x,unsigned long y) { - printf("x:%ld y:%ld\n",x,y); - return 0; + printf("x:%ld y:%ld\n",x,y); + return 0; } -#define func(x,y) _func(x,y) +#define func(x,y) _func(x,y) int main(void) { - fs= func( (fd/a) , func(2,0x0082c90f) ); - printf("fs:%ld\n",fs); - fs=_func( (fd/a) , _func(2,0x0082c90f) ); - printf("fs:%ld\n",fs); - return 0; + fs= func( (fd/a) , func(2,0x0082c90f) ); + printf("fs:%ld\n",fs); + fs=_func( (fd/a) , _func(2,0x0082c90f) ); + printf("fs:%ld\n",fs); + return 0; } diff --git a/test/ref/paranoia.c b/test/ref/paranoia.c index e4833bd16..1021264a5 100644 --- a/test/ref/paranoia.c +++ b/test/ref/paranoia.c @@ -18,39 +18,39 @@ main() #undef V9 #define NOPAUSE -/* A C version of Kahan's Floating Point Test "Paranoia" +/* A C version of Kahan's Floating Point Test "Paranoia" - Thos Sumner, UCSF, Feb. 1985 - David Gay, BTL, Jan. 1986 + Thos Sumner, UCSF, Feb. 1985 + David Gay, BTL, Jan. 1986 - This is a rewrite from the Pascal version by + This is a rewrite from the Pascal version by - B. A. Wichmann, 18 Jan. 1985 + B. A. Wichmann, 18 Jan. 1985 - (and does NOT exhibit good C programming style). + (and does NOT exhibit good C programming style). (C) Apr 19 1983 in BASIC version by: - Professor W. M. Kahan, - 567 Evans Hall - Electrical Engineering & Computer Science Dept. - University of California - Berkeley, California 94720 - USA + Professor W. M. Kahan, + 567 Evans Hall + Electrical Engineering & Computer Science Dept. + University of California + Berkeley, California 94720 + USA converted to Pascal by: - B. A. Wichmann - National Physical Laboratory - Teddington Middx - TW11 OLW - UK + B. A. Wichmann + National Physical Laboratory + Teddington Middx + TW11 OLW + UK converted to C by: - David M. Gay and Thos Sumner - AT&T Bell Labs Computer Center, Rm. U-76 - 600 Mountain Avenue University of California - Murray Hill, NJ 07974 San Francisco, CA 94143 - USA USA + David M. Gay and Thos Sumner + AT&T Bell Labs Computer Center, Rm. U-76 + 600 Mountain Avenue University of California + Murray Hill, NJ 07974 San Francisco, CA 94143 + USA USA with simultaneous corrections to the Pascal source (reflected in the Pascal source available over netlib). @@ -282,11 +282,11 @@ int NoTrials = 20; /*Number of tests for commutativity. */ #define True 1 /* Definitions for declared types - Guard == (Yes, No); - Rounding == (Chopped, Rounded, Other); - Message == packed array [1..40] of char; - Class == (Flaw, Defect, Serious, Failure); - */ + Guard == (Yes, No); + Rounding == (Chopped, Rounded, Other); + Message == packed array [1..40] of char; + Class == (Flaw, Defect, Serious, Failure); + */ #define Yes 1 #define No 0 #define Chopped 2 @@ -331,7 +331,7 @@ int M, N, N1; Guard GMult, GDiv, GAddSub; Rounding RMult, RDiv, RAddSub, RSqrt; int Break, Done, NotMonot, Monot, Anomaly, IEEE, - SqRWrng, UfNGrad; + SqRWrng, UfNGrad; /* Computed constants. */ /*U1 gap below 1.0, i.e, 1.0-U1 is next number below 1.0 */ /*U2 gap above 1.0, i.e, 1.0+U2 is next number above 1.0 */ @@ -340,1518 +340,1518 @@ int Break, Done, NotMonot, Monot, Anomaly, IEEE, void sigfpe(i) { - fpecount++; - printf("\n* * * FLOATING-POINT ERROR * * *\n"); - fflush(stdout); - if (sigsave) { + fpecount++; + printf("\n* * * FLOATING-POINT ERROR * * *\n"); + fflush(stdout); + if (sigsave) { #ifndef NOSIGNAL - signal(SIGFPE, sigsave); + signal(SIGFPE, sigsave); #endif - sigsave = 0; - longjmp(ovfl_buf, 1); - } - abort(); + sigsave = 0; + longjmp(ovfl_buf, 1); + } + abort(); } main() { #ifdef mc - char *out; - ieee_flags("set", "precision", "double", &out); + char *out; + ieee_flags("set", "precision", "double", &out); #endif - /* First two assignments use integer right-hand sides. */ - Zero = 0; - One = 1; - Two = One + One; - Three = Two + One; - Four = Three + One; - Five = Four + One; - Eight = Four + Four; - Nine = Three * Three; - TwentySeven = Nine * Three; - ThirtyTwo = Four * Eight; - TwoForty = Four * Five * Three * Four; - MinusOne = -One; - Half = One / Two; - OneAndHalf = One + Half; - ErrCnt[Failure] = 0; - ErrCnt[Serious] = 0; - ErrCnt[Defect] = 0; - ErrCnt[Flaw] = 0; - PageNo = 1; - /*=============================================*/ - Milestone = 0; - /*=============================================*/ + /* First two assignments use integer right-hand sides. */ + Zero = 0; + One = 1; + Two = One + One; + Three = Two + One; + Four = Three + One; + Five = Four + One; + Eight = Four + Four; + Nine = Three * Three; + TwentySeven = Nine * Three; + ThirtyTwo = Four * Eight; + TwoForty = Four * Five * Three * Four; + MinusOne = -One; + Half = One / Two; + OneAndHalf = One + Half; + ErrCnt[Failure] = 0; + ErrCnt[Serious] = 0; + ErrCnt[Defect] = 0; + ErrCnt[Flaw] = 0; + PageNo = 1; + /*=============================================*/ + Milestone = 0; + /*=============================================*/ #ifndef NOSIGNAL - signal(SIGFPE, sigfpe); + signal(SIGFPE, sigfpe); #endif - Instructions(); - Pause(); - Heading(); - Pause(); - Characteristics(); - Pause(); - History(); - Pause(); - /*=============================================*/ - Milestone = 7; - /*=============================================*/ - printf("Program is now RUNNING tests on small integers:\n"); + Instructions(); + Pause(); + Heading(); + Pause(); + Characteristics(); + Pause(); + History(); + Pause(); + /*=============================================*/ + Milestone = 7; + /*=============================================*/ + printf("Program is now RUNNING tests on small integers:\n"); - TstCond (Failure, (Zero + Zero == Zero) && (One - One == Zero) - && (One > Zero) && (One + One == Two), - "0+0 != 0, 1-1 != 0, 1 <= 0, or 1+1 != 2"); - Z = - Zero; - if (Z != 0.0) { - ErrCnt[Failure] = ErrCnt[Failure] + 1; - printf("Comparison alleges that -0.0 is Non-zero!\n"); - U1 = 0.001; - Radix = 1; - TstPtUf(); - } - TstCond (Failure, (Three == Two + One) && (Four == Three + One) - && (Four + Two * (- Two) == Zero) - && (Four - Three - One == Zero), - "3 != 2+1, 4 != 3+1, 4+2*(-2) != 0, or 4-3-1 != 0"); - TstCond (Failure, (MinusOne == (0 - One)) - && (MinusOne + One == Zero ) && (One + MinusOne == Zero) - && (MinusOne + FABS(One) == Zero) - && (MinusOne + MinusOne * MinusOne == Zero), - "-1+1 != 0, (-1)+abs(1) != 0, or -1+(-1)*(-1) != 0"); - TstCond (Failure, Half + MinusOne + Half == Zero, - "1/2 + (-1) + 1/2 != 0"); - /*=============================================*/ - /*SPLIT - part2(); - part3(); - part4(); - part5(); - part6(); - part7(); - part8(); - } + TstCond (Failure, (Zero + Zero == Zero) && (One - One == Zero) + && (One > Zero) && (One + One == Two), + "0+0 != 0, 1-1 != 0, 1 <= 0, or 1+1 != 2"); + Z = - Zero; + if (Z != 0.0) { + ErrCnt[Failure] = ErrCnt[Failure] + 1; + printf("Comparison alleges that -0.0 is Non-zero!\n"); + U1 = 0.001; + Radix = 1; + TstPtUf(); + } + TstCond (Failure, (Three == Two + One) && (Four == Three + One) + && (Four + Two * (- Two) == Zero) + && (Four - Three - One == Zero), + "3 != 2+1, 4 != 3+1, 4+2*(-2) != 0, or 4-3-1 != 0"); + TstCond (Failure, (MinusOne == (0 - One)) + && (MinusOne + One == Zero ) && (One + MinusOne == Zero) + && (MinusOne + FABS(One) == Zero) + && (MinusOne + MinusOne * MinusOne == Zero), + "-1+1 != 0, (-1)+abs(1) != 0, or -1+(-1)*(-1) != 0"); + TstCond (Failure, Half + MinusOne + Half == Zero, + "1/2 + (-1) + 1/2 != 0"); + /*=============================================*/ + /*SPLIT + part2(); + part3(); + part4(); + part5(); + part6(); + part7(); + part8(); + } #include "paranoia.h" part2(){ */ - Milestone = 10; - /*=============================================*/ - TstCond (Failure, (Nine == Three * Three) - && (TwentySeven == Nine * Three) && (Eight == Four + Four) - && (ThirtyTwo == Eight * Four) - && (ThirtyTwo - TwentySeven - Four - One == Zero), - "9 != 3*3, 27 != 9*3, 32 != 8*4, or 32-27-4-1 != 0"); - TstCond (Failure, (Five == Four + One) && - (TwoForty == Four * Five * Three * Four) - && (TwoForty / Three - Four * Four * Five == Zero) - && ( TwoForty / Four - Five * Three * Four == Zero) - && ( TwoForty / Five - Four * Three * Four == Zero), - "5 != 4+1, 240/3 != 80, 240/4 != 60, or 240/5 != 48"); - if (ErrCnt[Failure] == 0) { - printf("-1, 0, 1/2, 1, 2, 3, 4, 5, 9, 27, 32 & 240 are O.K.\n"); - printf("\n"); - } - printf("Searching for Radix and Precision.\n"); - W = One; - do { - W = W + W; - Y = W + One; - Z = Y - W; - Y = Z - One; - } while (MinusOne + FABS(Y) < Zero); - /*.. now W is just big enough that |((W+1)-W)-1| >= 1 ...*/ - Precision = Zero; - Y = One; - do { - Radix = W + Y; - Y = Y + Y; - Radix = Radix - W; - } while ( Radix == Zero); - if (Radix < Two) Radix = One; - printf("Radix = %f .\n", Radix); - if (Radix != 1) { - W = One; - do { - Precision = Precision + One; - W = W * Radix; - Y = W + One; - } while ((Y - W) == One); - } - /*... now W == Radix^Precision is barely too big to satisfy (W+1)-W == 1 - ...*/ - U1 = One / W; - U2 = Radix * U1; - printf("Closest relative separation found is U1 = %.7e .\n\n", U1); - printf("Recalculating radix and precision\n "); + Milestone = 10; + /*=============================================*/ + TstCond (Failure, (Nine == Three * Three) + && (TwentySeven == Nine * Three) && (Eight == Four + Four) + && (ThirtyTwo == Eight * Four) + && (ThirtyTwo - TwentySeven - Four - One == Zero), + "9 != 3*3, 27 != 9*3, 32 != 8*4, or 32-27-4-1 != 0"); + TstCond (Failure, (Five == Four + One) && + (TwoForty == Four * Five * Three * Four) + && (TwoForty / Three - Four * Four * Five == Zero) + && ( TwoForty / Four - Five * Three * Four == Zero) + && ( TwoForty / Five - Four * Three * Four == Zero), + "5 != 4+1, 240/3 != 80, 240/4 != 60, or 240/5 != 48"); + if (ErrCnt[Failure] == 0) { + printf("-1, 0, 1/2, 1, 2, 3, 4, 5, 9, 27, 32 & 240 are O.K.\n"); + printf("\n"); + } + printf("Searching for Radix and Precision.\n"); + W = One; + do { + W = W + W; + Y = W + One; + Z = Y - W; + Y = Z - One; + } while (MinusOne + FABS(Y) < Zero); + /*.. now W is just big enough that |((W+1)-W)-1| >= 1 ...*/ + Precision = Zero; + Y = One; + do { + Radix = W + Y; + Y = Y + Y; + Radix = Radix - W; + } while ( Radix == Zero); + if (Radix < Two) Radix = One; + printf("Radix = %f .\n", Radix); + if (Radix != 1) { + W = One; + do { + Precision = Precision + One; + W = W * Radix; + Y = W + One; + } while ((Y - W) == One); + } + /*... now W == Radix^Precision is barely too big to satisfy (W+1)-W == 1 + ...*/ + U1 = One / W; + U2 = Radix * U1; + printf("Closest relative separation found is U1 = %.7e .\n\n", U1); + printf("Recalculating radix and precision\n "); - /*save old values*/ - E0 = Radix; - E1 = U1; - E9 = U2; - E3 = Precision; + /*save old values*/ + E0 = Radix; + E1 = U1; + E9 = U2; + E3 = Precision; - X = Four / Three; - Third = X - One; - F6 = Half - Third; - X = F6 + F6; - X = FABS(X - Third); - if (X < U2) X = U2; + X = Four / Three; + Third = X - One; + F6 = Half - Third; + X = F6 + F6; + X = FABS(X - Third); + if (X < U2) X = U2; - /*... now X = (unknown no.) ulps of 1+...*/ - do { - U2 = X; - Y = Half * U2 + ThirtyTwo * U2 * U2; - Y = One + Y; - X = Y - One; - } while ( ! ((U2 <= X) || (X <= Zero))); + /*... now X = (unknown no.) ulps of 1+...*/ + do { + U2 = X; + Y = Half * U2 + ThirtyTwo * U2 * U2; + Y = One + Y; + X = Y - One; + } while ( ! ((U2 <= X) || (X <= Zero))); - /*... now U2 == 1 ulp of 1 + ... */ - X = Two / Three; - F6 = X - Half; - Third = F6 + F6; - X = Third - Half; - X = FABS(X + F6); - if (X < U1) X = U1; + /*... now U2 == 1 ulp of 1 + ... */ + X = Two / Three; + F6 = X - Half; + Third = F6 + F6; + X = Third - Half; + X = FABS(X + F6); + if (X < U1) X = U1; - /*... now X == (unknown no.) ulps of 1 -... */ - do { - U1 = X; - Y = Half * U1 + ThirtyTwo * U1 * U1; - Y = Half - Y; - X = Half + Y; - Y = Half - X; - X = Half + Y; - } while ( ! ((U1 <= X) || (X <= Zero))); - /*... now U1 == 1 ulp of 1 - ... */ - if (U1 == E1) printf("confirms closest relative separation U1 .\n"); - else printf("gets better closest relative separation U1 = %.7e .\n", U1); - W = One / U1; - F9 = (Half - U1) + Half; - Radix = FLOOR(0.01 + U2 / U1); - if (Radix == E0) printf("Radix confirmed.\n"); - else printf("MYSTERY: recalculated Radix = %.7e .\n", Radix); - TstCond (Defect, Radix <= Eight + Eight, - "Radix is too big: roundoff problems"); - TstCond (Flaw, (Radix == Two) || (Radix == 10) - || (Radix == One), "Radix is not as good as 2 or 10"); - /*=============================================*/ - Milestone = 20; - /*=============================================*/ - TstCond (Failure, F9 - Half < Half, - "(1-U1)-1/2 < 1/2 is FALSE, prog. fails?"); - X = F9; - I = 1; - Y = X - Half; - Z = Y - Half; - TstCond (Failure, (X != One) - || (Z == Zero), "Comparison is fuzzy,X=1 but X-1/2-1/2 != 0"); - X = One + U2; - I = 0; - /*=============================================*/ - Milestone = 25; - /*=============================================*/ - /*... BMinusU2 = nextafter(Radix, 0) */ - BMinusU2 = Radix - One; - BMinusU2 = (BMinusU2 - U2) + One; - /* Purify Integers */ - if (Radix != One) { - X = - TwoForty * LOG(U1) / LOG(Radix); - Y = FLOOR(Half + X); - if (FABS(X - Y) * Four < One) X = Y; - Precision = X / TwoForty; - Y = FLOOR(Half + Precision); - if (FABS(Precision - Y) * TwoForty < Half) Precision = Y; - } - if ((Precision != FLOOR(Precision)) || (Radix == One)) { - printf("Precision cannot be characterized by an Integer number\n"); - printf("of significant digits but, by itself, this is a minor flaw.\n"); - } - if (Radix == One) - printf("logarithmic encoding has precision characterized solely by U1.\n"); - else printf("The number of significant digits of the Radix is %f .\n", - Precision); - TstCond (Serious, U2 * Nine * Nine * TwoForty < One, - "Precision worse than 5 decimal figures "); - /*=============================================*/ - Milestone = 30; - /*=============================================*/ - /* Test for extra-precise subepressions */ - X = FABS(((Four / Three - One) - One / Four) * Three - One / Four); - do { - Z2 = X; - X = (One + (Half * Z2 + ThirtyTwo * Z2 * Z2)) - One; - } while ( ! ((Z2 <= X) || (X <= Zero))); - X = Y = Z = FABS((Three / Four - Two / Three) * Three - One / Four); - do { - Z1 = Z; - Z = (One / Two - ((One / Two - (Half * Z1 + ThirtyTwo * Z1 * Z1)) - + One / Two)) + One / Two; - } while ( ! ((Z1 <= Z) || (Z <= Zero))); - do { - do { - Y1 = Y; - Y = (Half - ((Half - (Half * Y1 + ThirtyTwo * Y1 * Y1)) + Half - )) + Half; - } while ( ! ((Y1 <= Y) || (Y <= Zero))); - X1 = X; - X = ((Half * X1 + ThirtyTwo * X1 * X1) - F9) + F9; - } while ( ! ((X1 <= X) || (X <= Zero))); - if ((X1 != Y1) || (X1 != Z1)) { - BadCond(Serious, "Disagreements among the values X1, Y1, Z1,\n"); - printf("respectively %.7e, %.7e, %.7e,\n", X1, Y1, Z1); - printf("are symptoms of inconsistencies introduced\n"); - printf("by extra-precise evaluation of arithmetic subexpressions.\n"); - notify("Possibly some part of this"); - if ((X1 == U1) || (Y1 == U1) || (Z1 == U1)) printf( - "That feature is not tested further by this program.\n") ; - } - else { - if ((Z1 != U1) || (Z2 != U2)) { - if ((Z1 >= U1) || (Z2 >= U2)) { - BadCond(Failure, ""); - notify("Precision"); - printf("\tU1 = %.7e, Z1 - U1 = %.7e\n",U1,Z1-U1); - printf("\tU2 = %.7e, Z2 - U2 = %.7e\n",U2,Z2-U2); - } - else { - if ((Z1 <= Zero) || (Z2 <= Zero)) { - printf("Because of unusual Radix = %f", Radix); - printf(", or exact rational arithmetic a result\n"); - printf("Z1 = %.7e, or Z2 = %.7e ", Z1, Z2); - notify("of an\nextra-precision"); - } - if (Z1 != Z2 || Z1 > Zero) { - X = Z1 / U1; - Y = Z2 / U2; - if (Y > X) X = Y; - Q = - LOG(X); - printf("Some subexpressions appear to be calculated extra\n"); - printf("precisely with about %g extra B-digits, i.e.\n", - (Q / LOG(Radix))); - printf("roughly %g extra significant decimals.\n", - Q / LOG(10.)); - } - printf("That feature is not tested further by this program.\n"); - } - } - } - Pause(); - /*=============================================*/ - /*SPLIT - } + /*... now X == (unknown no.) ulps of 1 -... */ + do { + U1 = X; + Y = Half * U1 + ThirtyTwo * U1 * U1; + Y = Half - Y; + X = Half + Y; + Y = Half - X; + X = Half + Y; + } while ( ! ((U1 <= X) || (X <= Zero))); + /*... now U1 == 1 ulp of 1 - ... */ + if (U1 == E1) printf("confirms closest relative separation U1 .\n"); + else printf("gets better closest relative separation U1 = %.7e .\n", U1); + W = One / U1; + F9 = (Half - U1) + Half; + Radix = FLOOR(0.01 + U2 / U1); + if (Radix == E0) printf("Radix confirmed.\n"); + else printf("MYSTERY: recalculated Radix = %.7e .\n", Radix); + TstCond (Defect, Radix <= Eight + Eight, + "Radix is too big: roundoff problems"); + TstCond (Flaw, (Radix == Two) || (Radix == 10) + || (Radix == One), "Radix is not as good as 2 or 10"); + /*=============================================*/ + Milestone = 20; + /*=============================================*/ + TstCond (Failure, F9 - Half < Half, + "(1-U1)-1/2 < 1/2 is FALSE, prog. fails?"); + X = F9; + I = 1; + Y = X - Half; + Z = Y - Half; + TstCond (Failure, (X != One) + || (Z == Zero), "Comparison is fuzzy,X=1 but X-1/2-1/2 != 0"); + X = One + U2; + I = 0; + /*=============================================*/ + Milestone = 25; + /*=============================================*/ + /*... BMinusU2 = nextafter(Radix, 0) */ + BMinusU2 = Radix - One; + BMinusU2 = (BMinusU2 - U2) + One; + /* Purify Integers */ + if (Radix != One) { + X = - TwoForty * LOG(U1) / LOG(Radix); + Y = FLOOR(Half + X); + if (FABS(X - Y) * Four < One) X = Y; + Precision = X / TwoForty; + Y = FLOOR(Half + Precision); + if (FABS(Precision - Y) * TwoForty < Half) Precision = Y; + } + if ((Precision != FLOOR(Precision)) || (Radix == One)) { + printf("Precision cannot be characterized by an Integer number\n"); + printf("of significant digits but, by itself, this is a minor flaw.\n"); + } + if (Radix == One) + printf("logarithmic encoding has precision characterized solely by U1.\n"); + else printf("The number of significant digits of the Radix is %f .\n", + Precision); + TstCond (Serious, U2 * Nine * Nine * TwoForty < One, + "Precision worse than 5 decimal figures "); + /*=============================================*/ + Milestone = 30; + /*=============================================*/ + /* Test for extra-precise subepressions */ + X = FABS(((Four / Three - One) - One / Four) * Three - One / Four); + do { + Z2 = X; + X = (One + (Half * Z2 + ThirtyTwo * Z2 * Z2)) - One; + } while ( ! ((Z2 <= X) || (X <= Zero))); + X = Y = Z = FABS((Three / Four - Two / Three) * Three - One / Four); + do { + Z1 = Z; + Z = (One / Two - ((One / Two - (Half * Z1 + ThirtyTwo * Z1 * Z1)) + + One / Two)) + One / Two; + } while ( ! ((Z1 <= Z) || (Z <= Zero))); + do { + do { + Y1 = Y; + Y = (Half - ((Half - (Half * Y1 + ThirtyTwo * Y1 * Y1)) + Half + )) + Half; + } while ( ! ((Y1 <= Y) || (Y <= Zero))); + X1 = X; + X = ((Half * X1 + ThirtyTwo * X1 * X1) - F9) + F9; + } while ( ! ((X1 <= X) || (X <= Zero))); + if ((X1 != Y1) || (X1 != Z1)) { + BadCond(Serious, "Disagreements among the values X1, Y1, Z1,\n"); + printf("respectively %.7e, %.7e, %.7e,\n", X1, Y1, Z1); + printf("are symptoms of inconsistencies introduced\n"); + printf("by extra-precise evaluation of arithmetic subexpressions.\n"); + notify("Possibly some part of this"); + if ((X1 == U1) || (Y1 == U1) || (Z1 == U1)) printf( + "That feature is not tested further by this program.\n") ; + } + else { + if ((Z1 != U1) || (Z2 != U2)) { + if ((Z1 >= U1) || (Z2 >= U2)) { + BadCond(Failure, ""); + notify("Precision"); + printf("\tU1 = %.7e, Z1 - U1 = %.7e\n",U1,Z1-U1); + printf("\tU2 = %.7e, Z2 - U2 = %.7e\n",U2,Z2-U2); + } + else { + if ((Z1 <= Zero) || (Z2 <= Zero)) { + printf("Because of unusual Radix = %f", Radix); + printf(", or exact rational arithmetic a result\n"); + printf("Z1 = %.7e, or Z2 = %.7e ", Z1, Z2); + notify("of an\nextra-precision"); + } + if (Z1 != Z2 || Z1 > Zero) { + X = Z1 / U1; + Y = Z2 / U2; + if (Y > X) X = Y; + Q = - LOG(X); + printf("Some subexpressions appear to be calculated extra\n"); + printf("precisely with about %g extra B-digits, i.e.\n", + (Q / LOG(Radix))); + printf("roughly %g extra significant decimals.\n", + Q / LOG(10.)); + } + printf("That feature is not tested further by this program.\n"); + } + } + } + Pause(); + /*=============================================*/ + /*SPLIT + } #include "paranoia.h" part3(){ */ - Milestone = 35; - /*=============================================*/ - if (Radix >= Two) { - X = W / (Radix * Radix); - Y = X + One; - Z = Y - X; - T = Z + U2; - X = T - Z; - TstCond (Failure, X == U2, - "Subtraction is not normalized X=Y,X+Z != Y+Z!"); - if (X == U2) printf( - "Subtraction appears to be normalized, as it should be."); - } - printf("\nChecking for guard digit in *, /, and -.\n"); - Y = F9 * One; - Z = One * F9; - X = F9 - Half; - Y = (Y - Half) - X; - Z = (Z - Half) - X; - X = One + U2; - T = X * Radix; - R = Radix * X; - X = T - Radix; - X = X - Radix * U2; - T = R - Radix; - T = T - Radix * U2; - X = X * (Radix - One); - T = T * (Radix - One); - if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)) GMult = Yes; - else { - GMult = No; - TstCond (Serious, False, - "* lacks a Guard Digit, so 1*X != X"); - } - Z = Radix * U2; - X = One + Z; - Y = FABS((X + Z) - X * X) - U2; - X = One - U2; - Z = FABS((X - U2) - X * X) - U1; - TstCond (Failure, (Y <= Zero) - && (Z <= Zero), "* gets too many final digits wrong.\n"); - Y = One - U2; - X = One + U2; - Z = One / Y; - Y = Z - X; - X = One / Three; - Z = Three / Nine; - X = X - Z; - T = Nine / TwentySeven; - Z = Z - T; - TstCond(Defect, X == Zero && Y == Zero && Z == Zero, - "Division lacks a Guard Digit, so error can exceed 1 ulp\nor 1/3 and 3/9 and 9/27 may disagree"); - Y = F9 / One; - X = F9 - Half; - Y = (Y - Half) - X; - X = One + U2; - T = X / One; - X = T - X; - if ((X == Zero) && (Y == Zero) && (Z == Zero)) GDiv = Yes; - else { - GDiv = No; - TstCond (Serious, False, - "Division lacks a Guard Digit, so X/1 != X"); - } - X = One / (One + U2); - Y = X - Half - Half; - TstCond (Serious, Y < Zero, - "Computed value of 1/1.000..1 >= 1"); - X = One - U2; - Y = One + Radix * U2; - Z = X * Radix; - T = Y * Radix; - R = Z / Radix; - StickyBit = T / Radix; - X = R - X; - Y = StickyBit - Y; - TstCond (Failure, X == Zero && Y == Zero, - "* and/or / gets too many last digits wrong"); - Y = One - U1; - X = One - F9; - Y = One - Y; - T = Radix - U2; - Z = Radix - BMinusU2; - T = Radix - T; - if ((X == U1) && (Y == U1) && (Z == U2) && (T == U2)) GAddSub = Yes; - else { - GAddSub = No; - TstCond (Serious, False, - "- lacks Guard Digit, so cancellation is obscured"); - } - if (F9 != One && F9 - One >= Zero) { - BadCond(Serious, "comparison alleges (1-U1) < 1 although\n"); - printf(" subtraction yields (1-U1) - 1 = 0 , thereby vitiating\n"); - printf(" such precautions against division by zero as\n"); - printf(" ... if (X == 1.0) {.....} else {.../(X-1.0)...}\n"); - } - if (GMult == Yes && GDiv == Yes && GAddSub == Yes) printf( - " *, /, and - appear to have guard digits, as they should.\n"); - /*=============================================*/ - Milestone = 40; - /*=============================================*/ - Pause(); - printf("Checking rounding on multiply, divide and add/subtract.\n"); - RMult = Other; - RDiv = Other; - RAddSub = Other; - RadixD2 = Radix / Two; - A1 = Two; - Done = False; - do { - AInvrse = Radix; - do { - X = AInvrse; - AInvrse = AInvrse / A1; - } while ( ! (FLOOR(AInvrse) != AInvrse)); - Done = (X == One) || (A1 > Three); - if (! Done) A1 = Nine + One; - } while ( ! (Done)); - if (X == One) A1 = Radix; - AInvrse = One / A1; - X = A1; - Y = AInvrse; - Done = False; - do { - Z = X * Y - Half; - TstCond (Failure, Z == Half, - "X * (1/X) differs from 1"); - Done = X == Radix; - X = Radix; - Y = One / X; - } while ( ! (Done)); - Y2 = One + U2; - Y1 = One - U2; - X = OneAndHalf - U2; - Y = OneAndHalf + U2; - Z = (X - U2) * Y2; - T = Y * Y1; - Z = Z - X; - T = T - X; - X = X * Y2; - Y = (Y + U2) * Y1; - X = X - OneAndHalf; - Y = Y - OneAndHalf; - if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T <= Zero)) { - X = (OneAndHalf + U2) * Y2; - Y = OneAndHalf - U2 - U2; - Z = OneAndHalf + U2 + U2; - T = (OneAndHalf - U2) * Y1; - X = X - (Z + U2); - StickyBit = Y * Y1; - S = Z * Y2; - T = T - Y; - Y = (U2 - Y) + StickyBit; - Z = S - (Z + U2 + U2); - StickyBit = (Y2 + U2) * Y1; - Y1 = Y2 * Y1; - StickyBit = StickyBit - Y2; - Y1 = Y1 - Half; - if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero) - && ( StickyBit == Zero) && (Y1 == Half)) { - RMult = Rounded; - printf("Multiplication appears to round correctly.\n"); - } - else if ((X + U2 == Zero) && (Y < Zero) && (Z + U2 == Zero) - && (T < Zero) && (StickyBit + U2 == Zero) - && (Y1 < Half)) { - RMult = Chopped; - printf("Multiplication appears to chop.\n"); - } - else printf("* is neither chopped nor correctly rounded.\n"); - if ((RMult == Rounded) && (GMult == No)) notify("Multiplication"); - } - else printf("* is neither chopped nor correctly rounded.\n"); - /*=============================================*/ - Milestone = 45; - /*=============================================*/ - Y2 = One + U2; - Y1 = One - U2; - Z = OneAndHalf + U2 + U2; - X = Z / Y2; - T = OneAndHalf - U2 - U2; - Y = (T - U2) / Y1; - Z = (Z + U2) / Y2; - X = X - OneAndHalf; - Y = Y - T; - T = T / Y1; - Z = Z - (OneAndHalf + U2); - T = (U2 - OneAndHalf) + T; - if (! ((X > Zero) || (Y > Zero) || (Z > Zero) || (T > Zero))) { - X = OneAndHalf / Y2; - Y = OneAndHalf - U2; - Z = OneAndHalf + U2; - X = X - Y; - T = OneAndHalf / Y1; - Y = Y / Y1; - T = T - (Z + U2); - Y = Y - Z; - Z = Z / Y2; - Y1 = (Y2 + U2) / Y2; - Z = Z - OneAndHalf; - Y2 = Y1 - Y2; - Y1 = (F9 - U1) / F9; - if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero) - && (Y2 == Zero) && (Y2 == Zero) - && (Y1 - Half == F9 - Half )) { - RDiv = Rounded; - printf("Division appears to round correctly.\n"); - if (GDiv == No) notify("Division"); - } - else if ((X < Zero) && (Y < Zero) && (Z < Zero) && (T < Zero) - && (Y2 < Zero) && (Y1 - Half < F9 - Half)) { - RDiv = Chopped; - printf("Division appears to chop.\n"); - } - } - if (RDiv == Other) printf("/ is neither chopped nor correctly rounded.\n"); - BInvrse = One / Radix; - TstCond (Failure, (BInvrse * Radix - Half == Half), - "Radix * ( 1 / Radix ) differs from 1"); - /*=============================================*/ - /*SPLIT - } + Milestone = 35; + /*=============================================*/ + if (Radix >= Two) { + X = W / (Radix * Radix); + Y = X + One; + Z = Y - X; + T = Z + U2; + X = T - Z; + TstCond (Failure, X == U2, + "Subtraction is not normalized X=Y,X+Z != Y+Z!"); + if (X == U2) printf( + "Subtraction appears to be normalized, as it should be."); + } + printf("\nChecking for guard digit in *, /, and -.\n"); + Y = F9 * One; + Z = One * F9; + X = F9 - Half; + Y = (Y - Half) - X; + Z = (Z - Half) - X; + X = One + U2; + T = X * Radix; + R = Radix * X; + X = T - Radix; + X = X - Radix * U2; + T = R - Radix; + T = T - Radix * U2; + X = X * (Radix - One); + T = T * (Radix - One); + if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)) GMult = Yes; + else { + GMult = No; + TstCond (Serious, False, + "* lacks a Guard Digit, so 1*X != X"); + } + Z = Radix * U2; + X = One + Z; + Y = FABS((X + Z) - X * X) - U2; + X = One - U2; + Z = FABS((X - U2) - X * X) - U1; + TstCond (Failure, (Y <= Zero) + && (Z <= Zero), "* gets too many final digits wrong.\n"); + Y = One - U2; + X = One + U2; + Z = One / Y; + Y = Z - X; + X = One / Three; + Z = Three / Nine; + X = X - Z; + T = Nine / TwentySeven; + Z = Z - T; + TstCond(Defect, X == Zero && Y == Zero && Z == Zero, + "Division lacks a Guard Digit, so error can exceed 1 ulp\nor 1/3 and 3/9 and 9/27 may disagree"); + Y = F9 / One; + X = F9 - Half; + Y = (Y - Half) - X; + X = One + U2; + T = X / One; + X = T - X; + if ((X == Zero) && (Y == Zero) && (Z == Zero)) GDiv = Yes; + else { + GDiv = No; + TstCond (Serious, False, + "Division lacks a Guard Digit, so X/1 != X"); + } + X = One / (One + U2); + Y = X - Half - Half; + TstCond (Serious, Y < Zero, + "Computed value of 1/1.000..1 >= 1"); + X = One - U2; + Y = One + Radix * U2; + Z = X * Radix; + T = Y * Radix; + R = Z / Radix; + StickyBit = T / Radix; + X = R - X; + Y = StickyBit - Y; + TstCond (Failure, X == Zero && Y == Zero, + "* and/or / gets too many last digits wrong"); + Y = One - U1; + X = One - F9; + Y = One - Y; + T = Radix - U2; + Z = Radix - BMinusU2; + T = Radix - T; + if ((X == U1) && (Y == U1) && (Z == U2) && (T == U2)) GAddSub = Yes; + else { + GAddSub = No; + TstCond (Serious, False, + "- lacks Guard Digit, so cancellation is obscured"); + } + if (F9 != One && F9 - One >= Zero) { + BadCond(Serious, "comparison alleges (1-U1) < 1 although\n"); + printf(" subtraction yields (1-U1) - 1 = 0 , thereby vitiating\n"); + printf(" such precautions against division by zero as\n"); + printf(" ... if (X == 1.0) {.....} else {.../(X-1.0)...}\n"); + } + if (GMult == Yes && GDiv == Yes && GAddSub == Yes) printf( + " *, /, and - appear to have guard digits, as they should.\n"); + /*=============================================*/ + Milestone = 40; + /*=============================================*/ + Pause(); + printf("Checking rounding on multiply, divide and add/subtract.\n"); + RMult = Other; + RDiv = Other; + RAddSub = Other; + RadixD2 = Radix / Two; + A1 = Two; + Done = False; + do { + AInvrse = Radix; + do { + X = AInvrse; + AInvrse = AInvrse / A1; + } while ( ! (FLOOR(AInvrse) != AInvrse)); + Done = (X == One) || (A1 > Three); + if (! Done) A1 = Nine + One; + } while ( ! (Done)); + if (X == One) A1 = Radix; + AInvrse = One / A1; + X = A1; + Y = AInvrse; + Done = False; + do { + Z = X * Y - Half; + TstCond (Failure, Z == Half, + "X * (1/X) differs from 1"); + Done = X == Radix; + X = Radix; + Y = One / X; + } while ( ! (Done)); + Y2 = One + U2; + Y1 = One - U2; + X = OneAndHalf - U2; + Y = OneAndHalf + U2; + Z = (X - U2) * Y2; + T = Y * Y1; + Z = Z - X; + T = T - X; + X = X * Y2; + Y = (Y + U2) * Y1; + X = X - OneAndHalf; + Y = Y - OneAndHalf; + if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T <= Zero)) { + X = (OneAndHalf + U2) * Y2; + Y = OneAndHalf - U2 - U2; + Z = OneAndHalf + U2 + U2; + T = (OneAndHalf - U2) * Y1; + X = X - (Z + U2); + StickyBit = Y * Y1; + S = Z * Y2; + T = T - Y; + Y = (U2 - Y) + StickyBit; + Z = S - (Z + U2 + U2); + StickyBit = (Y2 + U2) * Y1; + Y1 = Y2 * Y1; + StickyBit = StickyBit - Y2; + Y1 = Y1 - Half; + if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero) + && ( StickyBit == Zero) && (Y1 == Half)) { + RMult = Rounded; + printf("Multiplication appears to round correctly.\n"); + } + else if ((X + U2 == Zero) && (Y < Zero) && (Z + U2 == Zero) + && (T < Zero) && (StickyBit + U2 == Zero) + && (Y1 < Half)) { + RMult = Chopped; + printf("Multiplication appears to chop.\n"); + } + else printf("* is neither chopped nor correctly rounded.\n"); + if ((RMult == Rounded) && (GMult == No)) notify("Multiplication"); + } + else printf("* is neither chopped nor correctly rounded.\n"); + /*=============================================*/ + Milestone = 45; + /*=============================================*/ + Y2 = One + U2; + Y1 = One - U2; + Z = OneAndHalf + U2 + U2; + X = Z / Y2; + T = OneAndHalf - U2 - U2; + Y = (T - U2) / Y1; + Z = (Z + U2) / Y2; + X = X - OneAndHalf; + Y = Y - T; + T = T / Y1; + Z = Z - (OneAndHalf + U2); + T = (U2 - OneAndHalf) + T; + if (! ((X > Zero) || (Y > Zero) || (Z > Zero) || (T > Zero))) { + X = OneAndHalf / Y2; + Y = OneAndHalf - U2; + Z = OneAndHalf + U2; + X = X - Y; + T = OneAndHalf / Y1; + Y = Y / Y1; + T = T - (Z + U2); + Y = Y - Z; + Z = Z / Y2; + Y1 = (Y2 + U2) / Y2; + Z = Z - OneAndHalf; + Y2 = Y1 - Y2; + Y1 = (F9 - U1) / F9; + if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero) + && (Y2 == Zero) && (Y2 == Zero) + && (Y1 - Half == F9 - Half )) { + RDiv = Rounded; + printf("Division appears to round correctly.\n"); + if (GDiv == No) notify("Division"); + } + else if ((X < Zero) && (Y < Zero) && (Z < Zero) && (T < Zero) + && (Y2 < Zero) && (Y1 - Half < F9 - Half)) { + RDiv = Chopped; + printf("Division appears to chop.\n"); + } + } + if (RDiv == Other) printf("/ is neither chopped nor correctly rounded.\n"); + BInvrse = One / Radix; + TstCond (Failure, (BInvrse * Radix - Half == Half), + "Radix * ( 1 / Radix ) differs from 1"); + /*=============================================*/ + /*SPLIT + } #include "paranoia.h" part4(){ */ - Milestone = 50; - /*=============================================*/ - TstCond (Failure, ((F9 + U1) - Half == Half) - && ((BMinusU2 + U2 ) - One == Radix - One), - "Incomplete carry-propagation in Addition"); - X = One - U1 * U1; - Y = One + U2 * (One - U2); - Z = F9 - Half; - X = (X - Half) - Z; - Y = Y - One; - if ((X == Zero) && (Y == Zero)) { - RAddSub = Chopped; - printf("Add/Subtract appears to be chopped.\n"); - } - if (GAddSub == Yes) { - X = (Half + U2) * U2; - Y = (Half - U2) * U2; - X = One + X; - Y = One + Y; - X = (One + U2) - X; - Y = One - Y; - if ((X == Zero) && (Y == Zero)) { - X = (Half + U2) * U1; - Y = (Half - U2) * U1; - X = One - X; - Y = One - Y; - X = F9 - X; - Y = One - Y; - if ((X == Zero) && (Y == Zero)) { - RAddSub = Rounded; - printf("Addition/Subtraction appears to round correctly.\n"); - if (GAddSub == No) notify("Add/Subtract"); - } - else printf("Addition/Subtraction neither rounds nor chops.\n"); - } - else printf("Addition/Subtraction neither rounds nor chops.\n"); - } - else printf("Addition/Subtraction neither rounds nor chops.\n"); - S = One; - X = One + Half * (One + Half); - Y = (One + U2) * Half; - Z = X - Y; - T = Y - X; - StickyBit = Z + T; - if (StickyBit != Zero) { - S = Zero; - BadCond(Flaw, "(X - Y) + (Y - X) is non zero!\n"); - } - StickyBit = Zero; - if ((GMult == Yes) && (GDiv == Yes) && (GAddSub == Yes) - && (RMult == Rounded) && (RDiv == Rounded) - && (RAddSub == Rounded) && (FLOOR(RadixD2) == RadixD2)) { - printf("Checking for sticky bit.\n"); - X = (Half + U1) * U2; - Y = Half * U2; - Z = One + Y; - T = One + X; - if ((Z - One <= Zero) && (T - One >= U2)) { - Z = T + Y; - Y = Z - X; - if ((Z - T >= U2) && (Y - T == Zero)) { - X = (Half + U1) * U1; - Y = Half * U1; - Z = One - Y; - T = One - X; - if ((Z - One == Zero) && (T - F9 == Zero)) { - Z = (Half - U1) * U1; - T = F9 - Z; - Q = F9 - Y; - if ((T - F9 == Zero) && (F9 - U1 - Q == Zero)) { - Z = (One + U2) * OneAndHalf; - T = (OneAndHalf + U2) - Z + U2; - X = One + Half / Radix; - Y = One + Radix * U2; - Z = X * Y; - if (T == Zero && X + Radix * U2 - Z == Zero) { - if (Radix != Two) { - X = Two + U2; - Y = X / Two; - if ((Y - One == Zero)) StickyBit = S; - } - else StickyBit = S; - } - } - } - } - } - } - if (StickyBit == One) printf("Sticky bit apparently used correctly.\n"); - else printf("Sticky bit used incorrectly or not at all.\n"); - TstCond (Flaw, !(GMult == No || GDiv == No || GAddSub == No || - RMult == Other || RDiv == Other || RAddSub == Other), - "lack(s) of guard digits or failure(s) to correctly round or chop\n(noted above) count as one flaw in the final tally below"); - /*=============================================*/ - Milestone = 60; - /*=============================================*/ - printf("\n"); - printf("Does Multiplication commute? "); - printf("Testing on %d random pairs.\n", NoTrials); - Random9 = SQRT(3.0); - Random1 = Third; - I = 1; - do { - X = Random(); - Y = Random(); - Z9 = Y * X; - Z = X * Y; - Z9 = Z - Z9; - I = I + 1; - } while ( ! ((I > NoTrials) || (Z9 != Zero))); - if (I == NoTrials) { - Random1 = One + Half / Three; - Random2 = (U2 + U1) + One; - Z = Random1 * Random2; - Y = Random2 * Random1; - Z9 = (One + Half / Three) * ((U2 + U1) + One) - (One + Half / - Three) * ((U2 + U1) + One); - } - if (! ((I == NoTrials) || (Z9 == Zero))) - BadCond(Defect, "X * Y == Y * X trial fails.\n"); - else printf(" No failures found in %d integer pairs.\n", NoTrials); - /*=============================================*/ - Milestone = 70; - /*=============================================*/ - printf("\nRunning test of square root(x).\n"); - TstCond (Failure, (Zero == SQRT(Zero)) - && (- Zero == SQRT(- Zero)) - && (One == SQRT(One)), "Square root of 0.0, -0.0 or 1.0 wrong"); - MinSqEr = Zero; - MaxSqEr = Zero; - J = Zero; - X = Radix; - OneUlp = U2; - SqXMinX (Serious); - X = BInvrse; - OneUlp = BInvrse * U1; - SqXMinX (Serious); - X = U1; - OneUlp = U1 * U1; - SqXMinX (Serious); - if (J != Zero) Pause(); - printf("Testing if sqrt(X * X) == X for %d Integers X.\n", NoTrials); - J = Zero; - X = Two; - Y = Radix; - if ((Radix != One)) do { - X = Y; - Y = Radix * Y; - } while ( ! ((Y - X >= NoTrials))); - OneUlp = X * U2; - I = 1; - while (I <= NoTrials) { - X = X + One; - SqXMinX (Defect); - if (J > Zero) break; - I = I + 1; - } - printf("Test for sqrt monotonicity.\n"); - I = - 1; - X = BMinusU2; - Y = Radix; - Z = Radix + Radix * U2; - NotMonot = False; - Monot = False; - while ( ! (NotMonot || Monot)) { - I = I + 1; - X = SQRT(X); - Q = SQRT(Y); - Z = SQRT(Z); - if ((X > Q) || (Q > Z)) NotMonot = True; - else { - Q = FLOOR(Q + Half); - if ((I > 0) || (Radix == Q * Q)) Monot = True; - else if (I > 0) { - if (I > 1) Monot = True; - else { - Y = Y * BInvrse; - X = Y - U1; - Z = Y + U1; - } - } - else { - Y = Q; - X = Y - U2; - Z = Y + U2; - } - } - } - if (Monot) printf("sqrt has passed a test for Monotonicity.\n"); - else { - BadCond(Defect, ""); - printf("sqrt(X) is non-monotonic for X near %.7e .\n", Y); - } - /*=============================================*/ - /*SPLIT - } + Milestone = 50; + /*=============================================*/ + TstCond (Failure, ((F9 + U1) - Half == Half) + && ((BMinusU2 + U2 ) - One == Radix - One), + "Incomplete carry-propagation in Addition"); + X = One - U1 * U1; + Y = One + U2 * (One - U2); + Z = F9 - Half; + X = (X - Half) - Z; + Y = Y - One; + if ((X == Zero) && (Y == Zero)) { + RAddSub = Chopped; + printf("Add/Subtract appears to be chopped.\n"); + } + if (GAddSub == Yes) { + X = (Half + U2) * U2; + Y = (Half - U2) * U2; + X = One + X; + Y = One + Y; + X = (One + U2) - X; + Y = One - Y; + if ((X == Zero) && (Y == Zero)) { + X = (Half + U2) * U1; + Y = (Half - U2) * U1; + X = One - X; + Y = One - Y; + X = F9 - X; + Y = One - Y; + if ((X == Zero) && (Y == Zero)) { + RAddSub = Rounded; + printf("Addition/Subtraction appears to round correctly.\n"); + if (GAddSub == No) notify("Add/Subtract"); + } + else printf("Addition/Subtraction neither rounds nor chops.\n"); + } + else printf("Addition/Subtraction neither rounds nor chops.\n"); + } + else printf("Addition/Subtraction neither rounds nor chops.\n"); + S = One; + X = One + Half * (One + Half); + Y = (One + U2) * Half; + Z = X - Y; + T = Y - X; + StickyBit = Z + T; + if (StickyBit != Zero) { + S = Zero; + BadCond(Flaw, "(X - Y) + (Y - X) is non zero!\n"); + } + StickyBit = Zero; + if ((GMult == Yes) && (GDiv == Yes) && (GAddSub == Yes) + && (RMult == Rounded) && (RDiv == Rounded) + && (RAddSub == Rounded) && (FLOOR(RadixD2) == RadixD2)) { + printf("Checking for sticky bit.\n"); + X = (Half + U1) * U2; + Y = Half * U2; + Z = One + Y; + T = One + X; + if ((Z - One <= Zero) && (T - One >= U2)) { + Z = T + Y; + Y = Z - X; + if ((Z - T >= U2) && (Y - T == Zero)) { + X = (Half + U1) * U1; + Y = Half * U1; + Z = One - Y; + T = One - X; + if ((Z - One == Zero) && (T - F9 == Zero)) { + Z = (Half - U1) * U1; + T = F9 - Z; + Q = F9 - Y; + if ((T - F9 == Zero) && (F9 - U1 - Q == Zero)) { + Z = (One + U2) * OneAndHalf; + T = (OneAndHalf + U2) - Z + U2; + X = One + Half / Radix; + Y = One + Radix * U2; + Z = X * Y; + if (T == Zero && X + Radix * U2 - Z == Zero) { + if (Radix != Two) { + X = Two + U2; + Y = X / Two; + if ((Y - One == Zero)) StickyBit = S; + } + else StickyBit = S; + } + } + } + } + } + } + if (StickyBit == One) printf("Sticky bit apparently used correctly.\n"); + else printf("Sticky bit used incorrectly or not at all.\n"); + TstCond (Flaw, !(GMult == No || GDiv == No || GAddSub == No || + RMult == Other || RDiv == Other || RAddSub == Other), + "lack(s) of guard digits or failure(s) to correctly round or chop\n(noted above) count as one flaw in the final tally below"); + /*=============================================*/ + Milestone = 60; + /*=============================================*/ + printf("\n"); + printf("Does Multiplication commute? "); + printf("Testing on %d random pairs.\n", NoTrials); + Random9 = SQRT(3.0); + Random1 = Third; + I = 1; + do { + X = Random(); + Y = Random(); + Z9 = Y * X; + Z = X * Y; + Z9 = Z - Z9; + I = I + 1; + } while ( ! ((I > NoTrials) || (Z9 != Zero))); + if (I == NoTrials) { + Random1 = One + Half / Three; + Random2 = (U2 + U1) + One; + Z = Random1 * Random2; + Y = Random2 * Random1; + Z9 = (One + Half / Three) * ((U2 + U1) + One) - (One + Half / + Three) * ((U2 + U1) + One); + } + if (! ((I == NoTrials) || (Z9 == Zero))) + BadCond(Defect, "X * Y == Y * X trial fails.\n"); + else printf(" No failures found in %d integer pairs.\n", NoTrials); + /*=============================================*/ + Milestone = 70; + /*=============================================*/ + printf("\nRunning test of square root(x).\n"); + TstCond (Failure, (Zero == SQRT(Zero)) + && (- Zero == SQRT(- Zero)) + && (One == SQRT(One)), "Square root of 0.0, -0.0 or 1.0 wrong"); + MinSqEr = Zero; + MaxSqEr = Zero; + J = Zero; + X = Radix; + OneUlp = U2; + SqXMinX (Serious); + X = BInvrse; + OneUlp = BInvrse * U1; + SqXMinX (Serious); + X = U1; + OneUlp = U1 * U1; + SqXMinX (Serious); + if (J != Zero) Pause(); + printf("Testing if sqrt(X * X) == X for %d Integers X.\n", NoTrials); + J = Zero; + X = Two; + Y = Radix; + if ((Radix != One)) do { + X = Y; + Y = Radix * Y; + } while ( ! ((Y - X >= NoTrials))); + OneUlp = X * U2; + I = 1; + while (I <= NoTrials) { + X = X + One; + SqXMinX (Defect); + if (J > Zero) break; + I = I + 1; + } + printf("Test for sqrt monotonicity.\n"); + I = - 1; + X = BMinusU2; + Y = Radix; + Z = Radix + Radix * U2; + NotMonot = False; + Monot = False; + while ( ! (NotMonot || Monot)) { + I = I + 1; + X = SQRT(X); + Q = SQRT(Y); + Z = SQRT(Z); + if ((X > Q) || (Q > Z)) NotMonot = True; + else { + Q = FLOOR(Q + Half); + if ((I > 0) || (Radix == Q * Q)) Monot = True; + else if (I > 0) { + if (I > 1) Monot = True; + else { + Y = Y * BInvrse; + X = Y - U1; + Z = Y + U1; + } + } + else { + Y = Q; + X = Y - U2; + Z = Y + U2; + } + } + } + if (Monot) printf("sqrt has passed a test for Monotonicity.\n"); + else { + BadCond(Defect, ""); + printf("sqrt(X) is non-monotonic for X near %.7e .\n", Y); + } + /*=============================================*/ + /*SPLIT + } #include "paranoia.h" part5(){ */ - Milestone = 80; - /*=============================================*/ - MinSqEr = MinSqEr + Half; - MaxSqEr = MaxSqEr - Half; - Y = (SQRT(One + U2) - One) / U2; - SqEr = (Y - One) + U2 / Eight; - if (SqEr > MaxSqEr) MaxSqEr = SqEr; - SqEr = Y + U2 / Eight; - if (SqEr < MinSqEr) MinSqEr = SqEr; - Y = ((SQRT(F9) - U2) - (One - U2)) / U1; - SqEr = Y + U1 / Eight; - if (SqEr > MaxSqEr) MaxSqEr = SqEr; - SqEr = (Y + One) + U1 / Eight; - if (SqEr < MinSqEr) MinSqEr = SqEr; - OneUlp = U2; - X = OneUlp; - for( Indx = 1; Indx <= 3; ++Indx) { - Y = SQRT((X + U1 + X) + F9); - Y = ((Y - U2) - ((One - U2) + X)) / OneUlp; - Z = ((U1 - X) + F9) * Half * X * X / OneUlp; - SqEr = (Y + Half) + Z; - if (SqEr < MinSqEr) MinSqEr = SqEr; - SqEr = (Y - Half) + Z; - if (SqEr > MaxSqEr) MaxSqEr = SqEr; - if (((Indx == 1) || (Indx == 3))) - X = OneUlp * Sign (X) * FLOOR(Eight / (Nine * SQRT(OneUlp))); - else { - OneUlp = U1; - X = - OneUlp; - } - } - /*=============================================*/ - Milestone = 85; - /*=============================================*/ - SqRWrng = False; - Anomaly = False; - RSqrt = Other; /* ~dgh */ - if (Radix != One) { - printf("Testing whether sqrt is rounded or chopped.\n"); - D = FLOOR(Half + POW(Radix, One + Precision - FLOOR(Precision))); - /* ... == Radix^(1 + fract) if (Precision == Integer + fract. */ - X = D / Radix; - Y = D / A1; - if ((X != FLOOR(X)) || (Y != FLOOR(Y))) { - Anomaly = True; - } - else { - X = Zero; - Z2 = X; - Y = One; - Y2 = Y; - Z1 = Radix - One; - FourD = Four * D; - do { - if (Y2 > Z2) { - Q = Radix; - Y1 = Y; - do { - X1 = FABS(Q + FLOOR(Half - Q / Y1) * Y1); - Q = Y1; - Y1 = X1; - } while ( ! (X1 <= Zero)); - if (Q <= One) { - Z2 = Y2; - Z = Y; - } - } - Y = Y + Two; - X = X + Eight; - Y2 = Y2 + X; - if (Y2 >= FourD) Y2 = Y2 - FourD; - } while ( ! (Y >= D)); - X8 = FourD - Z2; - Q = (X8 + Z * Z) / FourD; - X8 = X8 / Eight; - if (Q != FLOOR(Q)) Anomaly = True; - else { - Break = False; - do { - X = Z1 * Z; - X = X - FLOOR(X / Radix) * Radix; - if (X == One) - Break = True; - else - Z1 = Z1 - One; - } while ( ! (Break || (Z1 <= Zero))); - if ((Z1 <= Zero) && (! Break)) Anomaly = True; - else { - if (Z1 > RadixD2) Z1 = Z1 - Radix; - do { - NewD(); - } while ( ! (U2 * D >= F9)); - if (D * Radix - D != W - D) Anomaly = True; - else { - Z2 = D; - I = 0; - Y = D + (One + Z) * Half; - X = D + Z + Q; - SR3750(); - Y = D + (One - Z) * Half + D; - X = D - Z + D; - X = X + Q + X; - SR3750(); - NewD(); - if (D - Z2 != W - Z2) Anomaly = True; - else { - Y = (D - Z2) + (Z2 + (One - Z) * Half); - X = (D - Z2) + (Z2 - Z + Q); - SR3750(); - Y = (One + Z) * Half; - X = Q; - SR3750(); - if (I == 0) Anomaly = True; - } - } - } - } - } - if ((I == 0) || Anomaly) { - BadCond(Failure, "Anomalous arithmetic with Integer < "); - printf("Radix^Precision = %.7e\n", W); - printf(" fails test whether sqrt rounds or chops.\n"); - SqRWrng = True; - } - } - if (! Anomaly) { - if (! ((MinSqEr < Zero) || (MaxSqEr > Zero))) { - RSqrt = Rounded; - printf("Square root appears to be correctly rounded.\n"); - } - else { - if ((MaxSqEr + U2 > U2 - Half) || (MinSqEr > Half) - || (MinSqEr + Radix < Half)) SqRWrng = True; - else { - RSqrt = Chopped; - printf("Square root appears to be chopped.\n"); - } - } - } - if (SqRWrng) { - printf("Square root is neither chopped nor correctly rounded.\n"); - printf("Observed errors run from %.7e ", MinSqEr - Half); - printf("to %.7e ulps.\n", Half + MaxSqEr); - TstCond (Serious, MaxSqEr - MinSqEr < Radix * Radix, - "sqrt gets too many last digits wrong"); - } - /*=============================================*/ - Milestone = 90; - /*=============================================*/ - Pause(); - printf("Testing powers Z^i for small Integers Z and i.\n"); - N = 0; - /* ... test powers of zero. */ - I = 0; - Z = -Zero; - M = 3.0; - Break = False; - do { - X = One; - SR3980(); - if (I <= 10) { - I = 1023; - SR3980(); - } - if (Z == MinusOne) Break = True; - else { - Z = MinusOne; - PrintIfNPositive(); - N = 0; - /* .. if(-1)^N is invalid, replace MinusOne by One. */ - I = - 4; - } - } while ( ! Break); - PrintIfNPositive(); - N1 = N; - N = 0; - Z = A1; - M = FLOOR(Two * LOG(W) / LOG(A1)); - Break = False; - do { - X = Z; - I = 1; - SR3980(); - if (Z == AInvrse) Break = True; - else Z = AInvrse; - } while ( ! (Break)); - /*=============================================*/ - Milestone = 100; - /*=============================================*/ - /* Powers of Radix have been tested, */ - /* next try a few primes */ - M = NoTrials; - Z = Three; - do { - X = Z; - I = 1; - SR3980(); - do { - Z = Z + Two; - } while ( Three * FLOOR(Z / Three) == Z ); - } while ( Z < Eight * Three ); - if (N > 0) { - printf("Errors like this may invalidate financial calculations\n"); - printf("\tinvolving interest rates.\n"); - } - PrintIfNPositive(); - N += N1; - if (N == 0) printf("... no discrepancis found.\n"); - if (N > 0) Pause(); - else printf("\n"); - /*=============================================*/ - /*SPLIT - } + Milestone = 80; + /*=============================================*/ + MinSqEr = MinSqEr + Half; + MaxSqEr = MaxSqEr - Half; + Y = (SQRT(One + U2) - One) / U2; + SqEr = (Y - One) + U2 / Eight; + if (SqEr > MaxSqEr) MaxSqEr = SqEr; + SqEr = Y + U2 / Eight; + if (SqEr < MinSqEr) MinSqEr = SqEr; + Y = ((SQRT(F9) - U2) - (One - U2)) / U1; + SqEr = Y + U1 / Eight; + if (SqEr > MaxSqEr) MaxSqEr = SqEr; + SqEr = (Y + One) + U1 / Eight; + if (SqEr < MinSqEr) MinSqEr = SqEr; + OneUlp = U2; + X = OneUlp; + for( Indx = 1; Indx <= 3; ++Indx) { + Y = SQRT((X + U1 + X) + F9); + Y = ((Y - U2) - ((One - U2) + X)) / OneUlp; + Z = ((U1 - X) + F9) * Half * X * X / OneUlp; + SqEr = (Y + Half) + Z; + if (SqEr < MinSqEr) MinSqEr = SqEr; + SqEr = (Y - Half) + Z; + if (SqEr > MaxSqEr) MaxSqEr = SqEr; + if (((Indx == 1) || (Indx == 3))) + X = OneUlp * Sign (X) * FLOOR(Eight / (Nine * SQRT(OneUlp))); + else { + OneUlp = U1; + X = - OneUlp; + } + } + /*=============================================*/ + Milestone = 85; + /*=============================================*/ + SqRWrng = False; + Anomaly = False; + RSqrt = Other; /* ~dgh */ + if (Radix != One) { + printf("Testing whether sqrt is rounded or chopped.\n"); + D = FLOOR(Half + POW(Radix, One + Precision - FLOOR(Precision))); + /* ... == Radix^(1 + fract) if (Precision == Integer + fract. */ + X = D / Radix; + Y = D / A1; + if ((X != FLOOR(X)) || (Y != FLOOR(Y))) { + Anomaly = True; + } + else { + X = Zero; + Z2 = X; + Y = One; + Y2 = Y; + Z1 = Radix - One; + FourD = Four * D; + do { + if (Y2 > Z2) { + Q = Radix; + Y1 = Y; + do { + X1 = FABS(Q + FLOOR(Half - Q / Y1) * Y1); + Q = Y1; + Y1 = X1; + } while ( ! (X1 <= Zero)); + if (Q <= One) { + Z2 = Y2; + Z = Y; + } + } + Y = Y + Two; + X = X + Eight; + Y2 = Y2 + X; + if (Y2 >= FourD) Y2 = Y2 - FourD; + } while ( ! (Y >= D)); + X8 = FourD - Z2; + Q = (X8 + Z * Z) / FourD; + X8 = X8 / Eight; + if (Q != FLOOR(Q)) Anomaly = True; + else { + Break = False; + do { + X = Z1 * Z; + X = X - FLOOR(X / Radix) * Radix; + if (X == One) + Break = True; + else + Z1 = Z1 - One; + } while ( ! (Break || (Z1 <= Zero))); + if ((Z1 <= Zero) && (! Break)) Anomaly = True; + else { + if (Z1 > RadixD2) Z1 = Z1 - Radix; + do { + NewD(); + } while ( ! (U2 * D >= F9)); + if (D * Radix - D != W - D) Anomaly = True; + else { + Z2 = D; + I = 0; + Y = D + (One + Z) * Half; + X = D + Z + Q; + SR3750(); + Y = D + (One - Z) * Half + D; + X = D - Z + D; + X = X + Q + X; + SR3750(); + NewD(); + if (D - Z2 != W - Z2) Anomaly = True; + else { + Y = (D - Z2) + (Z2 + (One - Z) * Half); + X = (D - Z2) + (Z2 - Z + Q); + SR3750(); + Y = (One + Z) * Half; + X = Q; + SR3750(); + if (I == 0) Anomaly = True; + } + } + } + } + } + if ((I == 0) || Anomaly) { + BadCond(Failure, "Anomalous arithmetic with Integer < "); + printf("Radix^Precision = %.7e\n", W); + printf(" fails test whether sqrt rounds or chops.\n"); + SqRWrng = True; + } + } + if (! Anomaly) { + if (! ((MinSqEr < Zero) || (MaxSqEr > Zero))) { + RSqrt = Rounded; + printf("Square root appears to be correctly rounded.\n"); + } + else { + if ((MaxSqEr + U2 > U2 - Half) || (MinSqEr > Half) + || (MinSqEr + Radix < Half)) SqRWrng = True; + else { + RSqrt = Chopped; + printf("Square root appears to be chopped.\n"); + } + } + } + if (SqRWrng) { + printf("Square root is neither chopped nor correctly rounded.\n"); + printf("Observed errors run from %.7e ", MinSqEr - Half); + printf("to %.7e ulps.\n", Half + MaxSqEr); + TstCond (Serious, MaxSqEr - MinSqEr < Radix * Radix, + "sqrt gets too many last digits wrong"); + } + /*=============================================*/ + Milestone = 90; + /*=============================================*/ + Pause(); + printf("Testing powers Z^i for small Integers Z and i.\n"); + N = 0; + /* ... test powers of zero. */ + I = 0; + Z = -Zero; + M = 3.0; + Break = False; + do { + X = One; + SR3980(); + if (I <= 10) { + I = 1023; + SR3980(); + } + if (Z == MinusOne) Break = True; + else { + Z = MinusOne; + PrintIfNPositive(); + N = 0; + /* .. if(-1)^N is invalid, replace MinusOne by One. */ + I = - 4; + } + } while ( ! Break); + PrintIfNPositive(); + N1 = N; + N = 0; + Z = A1; + M = FLOOR(Two * LOG(W) / LOG(A1)); + Break = False; + do { + X = Z; + I = 1; + SR3980(); + if (Z == AInvrse) Break = True; + else Z = AInvrse; + } while ( ! (Break)); + /*=============================================*/ + Milestone = 100; + /*=============================================*/ + /* Powers of Radix have been tested, */ + /* next try a few primes */ + M = NoTrials; + Z = Three; + do { + X = Z; + I = 1; + SR3980(); + do { + Z = Z + Two; + } while ( Three * FLOOR(Z / Three) == Z ); + } while ( Z < Eight * Three ); + if (N > 0) { + printf("Errors like this may invalidate financial calculations\n"); + printf("\tinvolving interest rates.\n"); + } + PrintIfNPositive(); + N += N1; + if (N == 0) printf("... no discrepancis found.\n"); + if (N > 0) Pause(); + else printf("\n"); + /*=============================================*/ + /*SPLIT + } #include "paranoia.h" part6(){ */ - Milestone = 110; - /*=============================================*/ - printf("Seeking Underflow thresholds UfThold and E0.\n"); - D = U1; - if (Precision != FLOOR(Precision)) { - D = BInvrse; - X = Precision; - do { - D = D * BInvrse; - X = X - One; - } while ( X > Zero); - } - Y = One; - Z = D; - /* ... D is power of 1/Radix < 1. */ - do { - C = Y; - Y = Z; - Z = Y * Y; - } while ((Y > Z) && (Z + Z > Z)); - Y = C; - Z = Y * D; - do { - C = Y; - Y = Z; - Z = Y * D; - } while ((Y > Z) && (Z + Z > Z)); - if (Radix < Two) HInvrse = Two; - else HInvrse = Radix; - H = One / HInvrse; - /* ... 1/HInvrse == H == Min(1/Radix, 1/2) */ - CInvrse = One / C; - E0 = C; - Z = E0 * H; - /* ...1/Radix^(BIG Integer) << 1 << CInvrse == 1/C */ - do { - Y = E0; - E0 = Z; - Z = E0 * H; - } while ((E0 > Z) && (Z + Z > Z)); - UfThold = E0; - E1 = Zero; - Q = Zero; - E9 = U2; - S = One + E9; - D = C * S; - if (D <= C) { - E9 = Radix * U2; - S = One + E9; - D = C * S; - if (D <= C) { - BadCond(Failure, "multiplication gets too many last digits wrong.\n"); - Underflow = E0; - Y1 = Zero; - PseudoZero = Z; - Pause(); - } - } - else { - Underflow = D; - PseudoZero = Underflow * H; - UfThold = Zero; - do { - Y1 = Underflow; - Underflow = PseudoZero; - if (E1 + E1 <= E1) { - Y2 = Underflow * HInvrse; - E1 = FABS(Y1 - Y2); - Q = Y1; - if ((UfThold == Zero) && (Y1 != Y2)) UfThold = Y1; - } - PseudoZero = PseudoZero * H; - } while ((Underflow > PseudoZero) - && (PseudoZero + PseudoZero > PseudoZero)); - } - /* Comment line 4530 .. 4560 */ - if (PseudoZero != Zero) { - printf("\n"); - Z = PseudoZero; - /* ... Test PseudoZero for "phoney- zero" violates */ - /* ... PseudoZero < Underflow or PseudoZero < PseudoZero + PseudoZero - ... */ - if (PseudoZero <= Zero) { - BadCond(Failure, "Positive expressions can underflow to an\n"); - printf("allegedly negative value\n"); - printf("PseudoZero that prints out as: %g .\n", PseudoZero); - X = - PseudoZero; - if (X <= Zero) { - printf("But -PseudoZero, which should be\n"); - printf("positive, isn't; it prints out as %g .\n", X); - } - } - else { - BadCond(Flaw, "Underflow can stick at an allegedly positive\n"); - printf("value PseudoZero that prints out as %g .\n", PseudoZero); - } - TstPtUf(); - } - /*=============================================*/ - Milestone = 120; - /*=============================================*/ - if (CInvrse * Y > CInvrse * Y1) { - S = H * S; - E0 = Underflow; - } - if (! ((E1 == Zero) || (E1 == E0))) { - BadCond(Defect, ""); - if (E1 < E0) { - printf("Products underflow at a higher"); - printf(" threshold than differences.\n"); - if (PseudoZero == Zero) - E0 = E1; - } - else { - printf("Difference underflows at a higher"); - printf(" threshold than products.\n"); - } - } - printf("Smallest strictly positive number found is E0 = %g .\n", E0); - Z = E0; - TstPtUf(); - Underflow = E0; - if (N == 1) Underflow = Y; - I = 4; - if (E1 == Zero) I = 3; - if (UfThold == Zero) I = I - 2; - UfNGrad = True; - switch (I) { - case 1: - UfThold = Underflow; - if ((CInvrse * Q) != ((CInvrse * Y) * S)) { - UfThold = Y; - BadCond(Failure, "Either accuracy deteriorates as numbers\n"); - printf("approach a threshold = %.17e\n", UfThold);; - printf(" coming down from %.17e\n", C); - printf(" or else multiplication gets too many last digits wrong.\n"); - } - Pause(); - break; + Milestone = 110; + /*=============================================*/ + printf("Seeking Underflow thresholds UfThold and E0.\n"); + D = U1; + if (Precision != FLOOR(Precision)) { + D = BInvrse; + X = Precision; + do { + D = D * BInvrse; + X = X - One; + } while ( X > Zero); + } + Y = One; + Z = D; + /* ... D is power of 1/Radix < 1. */ + do { + C = Y; + Y = Z; + Z = Y * Y; + } while ((Y > Z) && (Z + Z > Z)); + Y = C; + Z = Y * D; + do { + C = Y; + Y = Z; + Z = Y * D; + } while ((Y > Z) && (Z + Z > Z)); + if (Radix < Two) HInvrse = Two; + else HInvrse = Radix; + H = One / HInvrse; + /* ... 1/HInvrse == H == Min(1/Radix, 1/2) */ + CInvrse = One / C; + E0 = C; + Z = E0 * H; + /* ...1/Radix^(BIG Integer) << 1 << CInvrse == 1/C */ + do { + Y = E0; + E0 = Z; + Z = E0 * H; + } while ((E0 > Z) && (Z + Z > Z)); + UfThold = E0; + E1 = Zero; + Q = Zero; + E9 = U2; + S = One + E9; + D = C * S; + if (D <= C) { + E9 = Radix * U2; + S = One + E9; + D = C * S; + if (D <= C) { + BadCond(Failure, "multiplication gets too many last digits wrong.\n"); + Underflow = E0; + Y1 = Zero; + PseudoZero = Z; + Pause(); + } + } + else { + Underflow = D; + PseudoZero = Underflow * H; + UfThold = Zero; + do { + Y1 = Underflow; + Underflow = PseudoZero; + if (E1 + E1 <= E1) { + Y2 = Underflow * HInvrse; + E1 = FABS(Y1 - Y2); + Q = Y1; + if ((UfThold == Zero) && (Y1 != Y2)) UfThold = Y1; + } + PseudoZero = PseudoZero * H; + } while ((Underflow > PseudoZero) + && (PseudoZero + PseudoZero > PseudoZero)); + } + /* Comment line 4530 .. 4560 */ + if (PseudoZero != Zero) { + printf("\n"); + Z = PseudoZero; + /* ... Test PseudoZero for "phoney- zero" violates */ + /* ... PseudoZero < Underflow or PseudoZero < PseudoZero + PseudoZero + ... */ + if (PseudoZero <= Zero) { + BadCond(Failure, "Positive expressions can underflow to an\n"); + printf("allegedly negative value\n"); + printf("PseudoZero that prints out as: %g .\n", PseudoZero); + X = - PseudoZero; + if (X <= Zero) { + printf("But -PseudoZero, which should be\n"); + printf("positive, isn't; it prints out as %g .\n", X); + } + } + else { + BadCond(Flaw, "Underflow can stick at an allegedly positive\n"); + printf("value PseudoZero that prints out as %g .\n", PseudoZero); + } + TstPtUf(); + } + /*=============================================*/ + Milestone = 120; + /*=============================================*/ + if (CInvrse * Y > CInvrse * Y1) { + S = H * S; + E0 = Underflow; + } + if (! ((E1 == Zero) || (E1 == E0))) { + BadCond(Defect, ""); + if (E1 < E0) { + printf("Products underflow at a higher"); + printf(" threshold than differences.\n"); + if (PseudoZero == Zero) + E0 = E1; + } + else { + printf("Difference underflows at a higher"); + printf(" threshold than products.\n"); + } + } + printf("Smallest strictly positive number found is E0 = %g .\n", E0); + Z = E0; + TstPtUf(); + Underflow = E0; + if (N == 1) Underflow = Y; + I = 4; + if (E1 == Zero) I = 3; + if (UfThold == Zero) I = I - 2; + UfNGrad = True; + switch (I) { + case 1: + UfThold = Underflow; + if ((CInvrse * Q) != ((CInvrse * Y) * S)) { + UfThold = Y; + BadCond(Failure, "Either accuracy deteriorates as numbers\n"); + printf("approach a threshold = %.17e\n", UfThold);; + printf(" coming down from %.17e\n", C); + printf(" or else multiplication gets too many last digits wrong.\n"); + } + Pause(); + break; - case 2: - BadCond(Failure, "Underflow confuses Comparison, which alleges that\n"); - printf("Q == Y while denying that |Q - Y| == 0; these values\n"); - printf("print out as Q = %.17e, Y = %.17e .\n", Q, Y2); - printf ("|Q - Y| = %.17e .\n" , FABS(Q - Y2)); - UfThold = Q; - break; + case 2: + BadCond(Failure, "Underflow confuses Comparison, which alleges that\n"); + printf("Q == Y while denying that |Q - Y| == 0; these values\n"); + printf("print out as Q = %.17e, Y = %.17e .\n", Q, Y2); + printf ("|Q - Y| = %.17e .\n" , FABS(Q - Y2)); + UfThold = Q; + break; - case 3: - X = X; - break; + case 3: + X = X; + break; - case 4: - if ((Q == UfThold) && (E1 == E0) - && (FABS( UfThold - E1 / E9) <= E1)) { - UfNGrad = False; - printf("Underflow is gradual; it incurs Absolute Error =\n"); - printf("(roundoff in UfThold) < E0.\n"); - Y = E0 * CInvrse; - Y = Y * (OneAndHalf + U2); - X = CInvrse * (One + U2); - Y = Y / X; - IEEE = (Y == E0); - } - } - if (UfNGrad) { - printf("\n"); - sigsave = sigfpe; - if (setjmp(ovfl_buf)) { - printf("Underflow / UfThold failed!\n"); - R = H + H; - } - else R = SQRT(Underflow / UfThold); - sigsave = 0; - if (R <= H) { - Z = R * UfThold; - X = Z * (One + R * H * (One + H)); - } - else { - Z = UfThold; - X = Z * (One + H * H * (One + H)); - } - if (! ((X == Z) || (X - Z != Zero))) { - BadCond(Flaw, ""); - printf("X = %.17e\n\tis not equal to Z = %.17e .\n", X, Z); - Z9 = X - Z; - printf("yet X - Z yields %.17e .\n", Z9); - printf(" Should this NOT signal Underflow, "); - printf("this is a SERIOUS DEFECT\nthat causes "); - printf("confusion when innocent statements like\n");; - printf(" if (X == Z) ... else"); - printf(" ... (f(X) - f(Z)) / (X - Z) ...\n"); - printf("encounter Division by Zero although actually\n"); - sigsave = sigfpe; - if (setjmp(ovfl_buf)) printf("X / Z fails!\n"); - else printf("X / Z = 1 + %g .\n", (X / Z - Half) - Half); - sigsave = 0; - } - } - printf("The Underflow threshold is %.17e, %s\n", UfThold, - " below which"); - printf("calculation may suffer larger Relative error than "); - printf("merely roundoff.\n"); - Y2 = U1 * U1; - Y = Y2 * Y2; - Y2 = Y * U1; - if (Y2 <= UfThold) { - if (Y > E0) { - BadCond(Defect, ""); - I = 5; - } - else { - BadCond(Serious, ""); - I = 4; - } - printf("Range is too narrow; U1^%d Underflows.\n", I); - } - /*=============================================*/ - /*SPLIT - } + case 4: + if ((Q == UfThold) && (E1 == E0) + && (FABS( UfThold - E1 / E9) <= E1)) { + UfNGrad = False; + printf("Underflow is gradual; it incurs Absolute Error =\n"); + printf("(roundoff in UfThold) < E0.\n"); + Y = E0 * CInvrse; + Y = Y * (OneAndHalf + U2); + X = CInvrse * (One + U2); + Y = Y / X; + IEEE = (Y == E0); + } + } + if (UfNGrad) { + printf("\n"); + sigsave = sigfpe; + if (setjmp(ovfl_buf)) { + printf("Underflow / UfThold failed!\n"); + R = H + H; + } + else R = SQRT(Underflow / UfThold); + sigsave = 0; + if (R <= H) { + Z = R * UfThold; + X = Z * (One + R * H * (One + H)); + } + else { + Z = UfThold; + X = Z * (One + H * H * (One + H)); + } + if (! ((X == Z) || (X - Z != Zero))) { + BadCond(Flaw, ""); + printf("X = %.17e\n\tis not equal to Z = %.17e .\n", X, Z); + Z9 = X - Z; + printf("yet X - Z yields %.17e .\n", Z9); + printf(" Should this NOT signal Underflow, "); + printf("this is a SERIOUS DEFECT\nthat causes "); + printf("confusion when innocent statements like\n");; + printf(" if (X == Z) ... else"); + printf(" ... (f(X) - f(Z)) / (X - Z) ...\n"); + printf("encounter Division by Zero although actually\n"); + sigsave = sigfpe; + if (setjmp(ovfl_buf)) printf("X / Z fails!\n"); + else printf("X / Z = 1 + %g .\n", (X / Z - Half) - Half); + sigsave = 0; + } + } + printf("The Underflow threshold is %.17e, %s\n", UfThold, + " below which"); + printf("calculation may suffer larger Relative error than "); + printf("merely roundoff.\n"); + Y2 = U1 * U1; + Y = Y2 * Y2; + Y2 = Y * U1; + if (Y2 <= UfThold) { + if (Y > E0) { + BadCond(Defect, ""); + I = 5; + } + else { + BadCond(Serious, ""); + I = 4; + } + printf("Range is too narrow; U1^%d Underflows.\n", I); + } + /*=============================================*/ + /*SPLIT + } #include "paranoia.h" part7(){ */ - Milestone = 130; - /*=============================================*/ - Y = - FLOOR(Half - TwoForty * LOG(UfThold) / LOG(HInvrse)) / TwoForty; - Y2 = Y + Y; - printf("Since underflow occurs below the threshold\n"); - printf("UfThold = (%.17e) ^ (%.17e)\nonly underflow ", HInvrse, Y); - printf("should afflict the expression\n\t(%.17e) ^ (%.17e);\n", HInvrse, Y); - V9 = POW(HInvrse, Y2); - printf("actually calculating yields: %.17e .\n", V9); - if (! ((V9 >= Zero) && (V9 <= (Radix + Radix + E9) * UfThold))) { - BadCond(Serious, "this is not between 0 and underflow\n"); - printf(" threshold = %.17e .\n", UfThold); - } - else if (! (V9 > UfThold * (One + E9))) - printf("This computed value is O.K.\n"); - else { - BadCond(Defect, "this is not between 0 and underflow\n"); - printf(" threshold = %.17e .\n", UfThold); - } - /*=============================================*/ - Milestone = 140; - /*=============================================*/ - printf("\n"); - /* ...calculate Exp2 == exp(2) == 7.389056099... */ - X = Zero; - I = 2; - Y = Two * Three; - Q = Zero; - N = 0; - do { - Z = X; - I = I + 1; - Y = Y / (I + I); - R = Y + Q; - X = Z + R; - Q = (Z - X) + R; - } while(X > Z); - Z = (OneAndHalf + One / Eight) + X / (OneAndHalf * ThirtyTwo); - X = Z * Z; - Exp2 = X * X; - X = F9; - Y = X - U1; - printf("Testing X^((X + 1) / (X - 1)) vs. exp(2) = %.17e as X -> 1.\n", - Exp2); - for(I = 1;;) { - Z = X - BInvrse; - Z = (X + One) / (Z - (One - BInvrse)); - Q = POW(X, Z) - Exp2; - if (FABS(Q) > TwoForty * U2) { - N = 1; - V9 = (X - BInvrse) - (One - BInvrse); - BadCond(Defect, "Calculated"); - printf(" %.17e for\n", POW(X,Z)); - printf("\t(1 + (%.17e) ^ (%.17e);\n", V9, Z); - printf("\tdiffers from correct value by %.17e .\n", Q); - printf("\tThis much error may spoil financial\n"); - printf("\tcalculations involving tiny interest rates.\n"); - break; - } - else { - Z = (Y - X) * Two + Y; - X = Y; - Y = Z; - Z = One + (X - F9)*(X - F9); - if (Z > One && I < NoTrials) I++; - else { - if (X > One) { - if (N == 0) - printf("Accuracy seems adequate.\n"); - break; - } - else { - X = One + U2; - Y = U2 + U2; - Y += X; - I = 1; - } - } - } - } - /*=============================================*/ - Milestone = 150; - /*=============================================*/ - printf("Testing powers Z^Q at four nearly extreme values.\n"); - N = 0; - Z = A1; - Q = FLOOR(Half - LOG(C) / LOG(A1)); - Break = False; - do { - X = CInvrse; - Y = POW(Z, Q); - IsYeqX(); - Q = - Q; - X = C; - Y = POW(Z, Q); - IsYeqX(); - if (Z < One) Break = True; - else Z = AInvrse; - } while ( ! (Break)); - PrintIfNPositive(); - if (N == 0) printf(" ... no discrepancies found.\n"); - printf("\n"); + Milestone = 130; + /*=============================================*/ + Y = - FLOOR(Half - TwoForty * LOG(UfThold) / LOG(HInvrse)) / TwoForty; + Y2 = Y + Y; + printf("Since underflow occurs below the threshold\n"); + printf("UfThold = (%.17e) ^ (%.17e)\nonly underflow ", HInvrse, Y); + printf("should afflict the expression\n\t(%.17e) ^ (%.17e);\n", HInvrse, Y); + V9 = POW(HInvrse, Y2); + printf("actually calculating yields: %.17e .\n", V9); + if (! ((V9 >= Zero) && (V9 <= (Radix + Radix + E9) * UfThold))) { + BadCond(Serious, "this is not between 0 and underflow\n"); + printf(" threshold = %.17e .\n", UfThold); + } + else if (! (V9 > UfThold * (One + E9))) + printf("This computed value is O.K.\n"); + else { + BadCond(Defect, "this is not between 0 and underflow\n"); + printf(" threshold = %.17e .\n", UfThold); + } + /*=============================================*/ + Milestone = 140; + /*=============================================*/ + printf("\n"); + /* ...calculate Exp2 == exp(2) == 7.389056099... */ + X = Zero; + I = 2; + Y = Two * Three; + Q = Zero; + N = 0; + do { + Z = X; + I = I + 1; + Y = Y / (I + I); + R = Y + Q; + X = Z + R; + Q = (Z - X) + R; + } while(X > Z); + Z = (OneAndHalf + One / Eight) + X / (OneAndHalf * ThirtyTwo); + X = Z * Z; + Exp2 = X * X; + X = F9; + Y = X - U1; + printf("Testing X^((X + 1) / (X - 1)) vs. exp(2) = %.17e as X -> 1.\n", + Exp2); + for(I = 1;;) { + Z = X - BInvrse; + Z = (X + One) / (Z - (One - BInvrse)); + Q = POW(X, Z) - Exp2; + if (FABS(Q) > TwoForty * U2) { + N = 1; + V9 = (X - BInvrse) - (One - BInvrse); + BadCond(Defect, "Calculated"); + printf(" %.17e for\n", POW(X,Z)); + printf("\t(1 + (%.17e) ^ (%.17e);\n", V9, Z); + printf("\tdiffers from correct value by %.17e .\n", Q); + printf("\tThis much error may spoil financial\n"); + printf("\tcalculations involving tiny interest rates.\n"); + break; + } + else { + Z = (Y - X) * Two + Y; + X = Y; + Y = Z; + Z = One + (X - F9)*(X - F9); + if (Z > One && I < NoTrials) I++; + else { + if (X > One) { + if (N == 0) + printf("Accuracy seems adequate.\n"); + break; + } + else { + X = One + U2; + Y = U2 + U2; + Y += X; + I = 1; + } + } + } + } + /*=============================================*/ + Milestone = 150; + /*=============================================*/ + printf("Testing powers Z^Q at four nearly extreme values.\n"); + N = 0; + Z = A1; + Q = FLOOR(Half - LOG(C) / LOG(A1)); + Break = False; + do { + X = CInvrse; + Y = POW(Z, Q); + IsYeqX(); + Q = - Q; + X = C; + Y = POW(Z, Q); + IsYeqX(); + if (Z < One) Break = True; + else Z = AInvrse; + } while ( ! (Break)); + PrintIfNPositive(); + if (N == 0) printf(" ... no discrepancies found.\n"); + printf("\n"); - /*=============================================*/ - Milestone = 160; - /*=============================================*/ - Pause(); - printf("Searching for Overflow threshold:\n"); - printf("This may generate an error.\n"); - Y = - CInvrse; - V9 = HInvrse * Y; - sigsave = sigfpe; - if (setjmp(ovfl_buf)) { I = 0; V9 = Y; goto overflow; } - do { - V = Y; - Y = V9; - V9 = HInvrse * Y; - } while(V9 < Y); - I = 1; + /*=============================================*/ + Milestone = 160; + /*=============================================*/ + Pause(); + printf("Searching for Overflow threshold:\n"); + printf("This may generate an error.\n"); + Y = - CInvrse; + V9 = HInvrse * Y; + sigsave = sigfpe; + if (setjmp(ovfl_buf)) { I = 0; V9 = Y; goto overflow; } + do { + V = Y; + Y = V9; + V9 = HInvrse * Y; + } while(V9 < Y); + I = 1; overflow: - sigsave = 0; - Z = V9; - printf("Can 'Z = -Y' overflow?\n"); - printf("Trying it on Y = %.17e .\n", Y); - V9 = - Y; - V0 = V9; - if (V - Y == V + V0) printf("Seems O.K.\n"); - else { - printf("finds a "); - BadCond(Flaw, "-(-Y) differs from Y.\n"); - } - if (Z != Y) { - BadCond(Serious, ""); - printf("overflow past %.17e\n\tshrinks to %.17e .\n", Y, Z); - } - if (I) { - Y = V * (HInvrse * U2 - HInvrse); - Z = Y + ((One - HInvrse) * U2) * V; - if (Z < V0) Y = Z; - if (Y < V0) V = Y; - if (V0 - V < V0) V = V0; - } - else { - V = Y * (HInvrse * U2 - HInvrse); - V = V + ((One - HInvrse) * U2) * Y; - } - printf("Overflow threshold is V = %.17e .\n", V); - if (I) printf("Overflow saturates at V0 = %.17e .\n", V0); - else printf("There is no saturation value because the system traps on overflow.\n"); - V9 = V * One; - printf("No Overflow should be signaled for V * 1 = %.17e\n", V9); - V9 = V / One; - printf(" nor for V / 1 = %.17e .\n", V9); - printf("Any overflow signal separating this * from the one\n"); - printf("above is a DEFECT.\n"); - /*=============================================*/ - Milestone = 170; - /*=============================================*/ - if (!(-V < V && -V0 < V0 && -UfThold < V && UfThold < V)) { - BadCond(Failure, "Comparisons involving "); - printf("+-%g, +-%g\nand +-%g are confused by Overflow.", - V, V0, UfThold); - } - /*=============================================*/ - Milestone = 175; - /*=============================================*/ - printf("\n"); - for(Indx = 1; Indx <= 3; ++Indx) { - switch (Indx) { - case 1: Z = UfThold; break; - case 2: Z = E0; break; - case 3: Z = PseudoZero; break; - } - if (Z != Zero) { - V9 = SQRT(Z); - Y = V9 * V9; - if (Y / (One - Radix * E9) < Z - || Y > (One + Radix * E9) * Z) { /* dgh: + E9 --> * E9 */ - if (V9 > U1) BadCond(Serious, ""); - else BadCond(Defect, ""); - printf("Comparison alleges that what prints as Z = %.17e\n", Z); - printf(" is too far from sqrt(Z) ^ 2 = %.17e .\n", Y); - } - } - } - /*=============================================*/ - Milestone = 180; - /*=============================================*/ - for(Indx = 1; Indx <= 2; ++Indx) { - if (Indx == 1) Z = V; - else Z = V0; - V9 = SQRT(Z); - X = (One - Radix * E9) * V9; - V9 = V9 * X; - if (((V9 < (One - Two * Radix * E9) * Z) || (V9 > Z))) { - Y = V9; - if (X < W) BadCond(Serious, ""); - else BadCond(Defect, ""); - printf("Comparison alleges that Z = %17e\n", Z); - printf(" is too far from sqrt(Z) ^ 2 (%.17e) .\n", Y); - } - } - /*=============================================*/ - /*SPLIT - } + sigsave = 0; + Z = V9; + printf("Can 'Z = -Y' overflow?\n"); + printf("Trying it on Y = %.17e .\n", Y); + V9 = - Y; + V0 = V9; + if (V - Y == V + V0) printf("Seems O.K.\n"); + else { + printf("finds a "); + BadCond(Flaw, "-(-Y) differs from Y.\n"); + } + if (Z != Y) { + BadCond(Serious, ""); + printf("overflow past %.17e\n\tshrinks to %.17e .\n", Y, Z); + } + if (I) { + Y = V * (HInvrse * U2 - HInvrse); + Z = Y + ((One - HInvrse) * U2) * V; + if (Z < V0) Y = Z; + if (Y < V0) V = Y; + if (V0 - V < V0) V = V0; + } + else { + V = Y * (HInvrse * U2 - HInvrse); + V = V + ((One - HInvrse) * U2) * Y; + } + printf("Overflow threshold is V = %.17e .\n", V); + if (I) printf("Overflow saturates at V0 = %.17e .\n", V0); + else printf("There is no saturation value because the system traps on overflow.\n"); + V9 = V * One; + printf("No Overflow should be signaled for V * 1 = %.17e\n", V9); + V9 = V / One; + printf(" nor for V / 1 = %.17e .\n", V9); + printf("Any overflow signal separating this * from the one\n"); + printf("above is a DEFECT.\n"); + /*=============================================*/ + Milestone = 170; + /*=============================================*/ + if (!(-V < V && -V0 < V0 && -UfThold < V && UfThold < V)) { + BadCond(Failure, "Comparisons involving "); + printf("+-%g, +-%g\nand +-%g are confused by Overflow.", + V, V0, UfThold); + } + /*=============================================*/ + Milestone = 175; + /*=============================================*/ + printf("\n"); + for(Indx = 1; Indx <= 3; ++Indx) { + switch (Indx) { + case 1: Z = UfThold; break; + case 2: Z = E0; break; + case 3: Z = PseudoZero; break; + } + if (Z != Zero) { + V9 = SQRT(Z); + Y = V9 * V9; + if (Y / (One - Radix * E9) < Z + || Y > (One + Radix * E9) * Z) { /* dgh: + E9 --> * E9 */ + if (V9 > U1) BadCond(Serious, ""); + else BadCond(Defect, ""); + printf("Comparison alleges that what prints as Z = %.17e\n", Z); + printf(" is too far from sqrt(Z) ^ 2 = %.17e .\n", Y); + } + } + } + /*=============================================*/ + Milestone = 180; + /*=============================================*/ + for(Indx = 1; Indx <= 2; ++Indx) { + if (Indx == 1) Z = V; + else Z = V0; + V9 = SQRT(Z); + X = (One - Radix * E9) * V9; + V9 = V9 * X; + if (((V9 < (One - Two * Radix * E9) * Z) || (V9 > Z))) { + Y = V9; + if (X < W) BadCond(Serious, ""); + else BadCond(Defect, ""); + printf("Comparison alleges that Z = %17e\n", Z); + printf(" is too far from sqrt(Z) ^ 2 (%.17e) .\n", Y); + } + } + /*=============================================*/ + /*SPLIT + } #include "paranoia.h" part8(){ */ - Milestone = 190; - /*=============================================*/ - Pause(); - X = UfThold * V; - Y = Radix * Radix; - if (X*Y < One || X > Y) { - if (X * Y < U1 || X > Y/U1) BadCond(Defect, "Badly"); - else BadCond(Flaw, ""); + Milestone = 190; + /*=============================================*/ + Pause(); + X = UfThold * V; + Y = Radix * Radix; + if (X*Y < One || X > Y) { + if (X * Y < U1 || X > Y/U1) BadCond(Defect, "Badly"); + else BadCond(Flaw, ""); - printf(" unbalanced range; UfThold * V = %.17e\n\t%s\n", - X, "is too far from 1.\n"); - } - /*=============================================*/ - Milestone = 200; - /*=============================================*/ - for (Indx = 1; Indx <= 5; ++Indx) { - X = F9; - switch (Indx) { - case 2: X = One + U2; break; - case 3: X = V; break; - case 4: X = UfThold; break; - case 5: X = Radix; - } - Y = X; - sigsave = sigfpe; - if (setjmp(ovfl_buf)) - printf(" X / X traps when X = %g\n", X); - else { - V9 = (Y / X - Half) - Half; - if (V9 == Zero) continue; - if (V9 == - U1 && Indx < 5) BadCond(Flaw, ""); - else BadCond(Serious, ""); - printf(" X / X differs from 1 when X = %.17e\n", X); - printf(" instead, X / X - 1/2 - 1/2 = %.17e .\n", V9); - } - sigsave = 0; - } - /*=============================================*/ - Milestone = 210; - /*=============================================*/ - MyZero = Zero; - printf("\n"); - printf("What message and/or values does Division by Zero produce?\n") ; + printf(" unbalanced range; UfThold * V = %.17e\n\t%s\n", + X, "is too far from 1.\n"); + } + /*=============================================*/ + Milestone = 200; + /*=============================================*/ + for (Indx = 1; Indx <= 5; ++Indx) { + X = F9; + switch (Indx) { + case 2: X = One + U2; break; + case 3: X = V; break; + case 4: X = UfThold; break; + case 5: X = Radix; + } + Y = X; + sigsave = sigfpe; + if (setjmp(ovfl_buf)) + printf(" X / X traps when X = %g\n", X); + else { + V9 = (Y / X - Half) - Half; + if (V9 == Zero) continue; + if (V9 == - U1 && Indx < 5) BadCond(Flaw, ""); + else BadCond(Serious, ""); + printf(" X / X differs from 1 when X = %.17e\n", X); + printf(" instead, X / X - 1/2 - 1/2 = %.17e .\n", V9); + } + sigsave = 0; + } + /*=============================================*/ + Milestone = 210; + /*=============================================*/ + MyZero = Zero; + printf("\n"); + printf("What message and/or values does Division by Zero produce?\n") ; #ifndef NOPAUSE - printf("This can interupt your program. You can "); - printf("skip this part if you wish.\n"); - printf("Do you wish to compute 1 / 0? "); - fflush(stdout); - read (KEYBOARD, ch, 8); - if ((ch[0] == 'Y') || (ch[0] == 'y')) { + printf("This can interupt your program. You can "); + printf("skip this part if you wish.\n"); + printf("Do you wish to compute 1 / 0? "); + fflush(stdout); + read (KEYBOARD, ch, 8); + if ((ch[0] == 'Y') || (ch[0] == 'y')) { #endif - sigsave = sigfpe; - printf(" Trying to compute 1 / 0 produces ..."); - if (!setjmp(ovfl_buf)) printf(" %.7e .\n", One / MyZero); - sigsave = 0; + sigsave = sigfpe; + printf(" Trying to compute 1 / 0 produces ..."); + if (!setjmp(ovfl_buf)) printf(" %.7e .\n", One / MyZero); + sigsave = 0; #ifndef NOPAUSE - } - else printf("O.K.\n"); - printf("\nDo you wish to compute 0 / 0? "); - fflush(stdout); - read (KEYBOARD, ch, 80); - if ((ch[0] == 'Y') || (ch[0] == 'y')) { + } + else printf("O.K.\n"); + printf("\nDo you wish to compute 0 / 0? "); + fflush(stdout); + read (KEYBOARD, ch, 80); + if ((ch[0] == 'Y') || (ch[0] == 'y')) { #endif - sigsave = sigfpe; - printf("\n Trying to compute 0 / 0 produces ..."); - if (!setjmp(ovfl_buf)) printf(" %.7e .\n", Zero / MyZero); - sigsave = 0; + sigsave = sigfpe; + printf("\n Trying to compute 0 / 0 produces ..."); + if (!setjmp(ovfl_buf)) printf(" %.7e .\n", Zero / MyZero); + sigsave = 0; #ifndef NOPAUSE - } - else printf("O.K.\n"); + } + else printf("O.K.\n"); #endif - /*=============================================*/ - Milestone = 220; - /*=============================================*/ - Pause(); - printf("\n"); - { - static char *msg[] = { - "FAILUREs encountered =", - "SERIOUS DEFECTs discovered =", - "DEFECTs discovered =", - "FLAWs discovered =" }; - int i; - for(i = 0; i < 4; i++) if (ErrCnt[i]) - printf("The number of %-29s %d.\n", - msg[i], ErrCnt[i]); - } - printf("\n"); - if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[Defect] - + ErrCnt[Flaw]) > 0) { - if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[ - Defect] == 0) && (ErrCnt[Flaw] > 0)) { - printf("The arithmetic diagnosed seems "); - printf("Satisfactory though flawed.\n"); - } - if ((ErrCnt[Failure] + ErrCnt[Serious] == 0) - && ( ErrCnt[Defect] > 0)) { - printf("The arithmetic diagnosed may be Acceptable\n"); - printf("despite inconvenient Defects.\n"); - } - if ((ErrCnt[Failure] + ErrCnt[Serious]) > 0) { - printf("The arithmetic diagnosed has "); - printf("unacceptable Serious Defects.\n"); - } - if (ErrCnt[Failure] > 0) { - printf("Potentially fatal FAILURE may have spoiled this"); - printf(" program's subsequent diagnoses.\n"); - } - } - else { - printf("No failures, defects nor flaws have been discovered.\n"); - if (! ((RMult == Rounded) && (RDiv == Rounded) - && (RAddSub == Rounded) && (RSqrt == Rounded))) - printf("The arithmetic diagnosed seems Satisfactory.\n"); - else { - if (StickyBit >= One && - (Radix - Two) * (Radix - Nine - One) == Zero) { - printf("Rounding appears to conform to "); - printf("the proposed IEEE standard P"); - if ((Radix == Two) && - ((Precision - Four * Three * Two) * - ( Precision - TwentySeven - - TwentySeven + One) == Zero)) - printf("754"); - else printf("854"); - if (IEEE) printf(".\n"); - else { - printf(",\nexcept for possibly Double Rounding"); - printf(" during Gradual Underflow.\n"); - } - } - printf("The arithmetic diagnosed appears to be Excellent!\n"); - } - } - if (fpecount) - printf("\nA total of %d floating point exceptions were registered.\n", - fpecount); - printf("END OF TEST.\n"); - return 0; - } + /*=============================================*/ + Milestone = 220; + /*=============================================*/ + Pause(); + printf("\n"); + { + static char *msg[] = { + "FAILUREs encountered =", + "SERIOUS DEFECTs discovered =", + "DEFECTs discovered =", + "FLAWs discovered =" }; + int i; + for(i = 0; i < 4; i++) if (ErrCnt[i]) + printf("The number of %-29s %d.\n", + msg[i], ErrCnt[i]); + } + printf("\n"); + if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[Defect] + + ErrCnt[Flaw]) > 0) { + if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[ + Defect] == 0) && (ErrCnt[Flaw] > 0)) { + printf("The arithmetic diagnosed seems "); + printf("Satisfactory though flawed.\n"); + } + if ((ErrCnt[Failure] + ErrCnt[Serious] == 0) + && ( ErrCnt[Defect] > 0)) { + printf("The arithmetic diagnosed may be Acceptable\n"); + printf("despite inconvenient Defects.\n"); + } + if ((ErrCnt[Failure] + ErrCnt[Serious]) > 0) { + printf("The arithmetic diagnosed has "); + printf("unacceptable Serious Defects.\n"); + } + if (ErrCnt[Failure] > 0) { + printf("Potentially fatal FAILURE may have spoiled this"); + printf(" program's subsequent diagnoses.\n"); + } + } + else { + printf("No failures, defects nor flaws have been discovered.\n"); + if (! ((RMult == Rounded) && (RDiv == Rounded) + && (RAddSub == Rounded) && (RSqrt == Rounded))) + printf("The arithmetic diagnosed seems Satisfactory.\n"); + else { + if (StickyBit >= One && + (Radix - Two) * (Radix - Nine - One) == Zero) { + printf("Rounding appears to conform to "); + printf("the proposed IEEE standard P"); + if ((Radix == Two) && + ((Precision - Four * Three * Two) * + ( Precision - TwentySeven - + TwentySeven + One) == Zero)) + printf("754"); + else printf("854"); + if (IEEE) printf(".\n"); + else { + printf(",\nexcept for possibly Double Rounding"); + printf(" during Gradual Underflow.\n"); + } + } + printf("The arithmetic diagnosed appears to be Excellent!\n"); + } + } + if (fpecount) + printf("\nA total of %d floating point exceptions were registered.\n", + fpecount); + printf("END OF TEST.\n"); + return 0; + } /*SPLIT subs.c #include "paranoia.h" @@ -1868,17 +1868,17 @@ FLOAT X; Pause() { #ifndef NOPAUSE - char ch[8]; + char ch[8]; - printf("\nTo continue, press RETURN"); - fflush(stdout); - read(KEYBOARD, ch, 8); + printf("\nTo continue, press RETURN"); + fflush(stdout); + read(KEYBOARD, ch, 8); #endif - printf("\nDiagnosis resumes after milestone Number %d", Milestone); - printf(" Page: %d\n\n", PageNo); - ++Milestone; - ++PageNo; - } + printf("\nDiagnosis resumes after milestone Number %d", Milestone); + printf(" Page: %d\n\n", PageNo); + ++Milestone; + ++PageNo; + } /* TstCond */ @@ -1891,11 +1891,11 @@ BadCond(K, T) int K; char *T; { - static char *msg[] = { "FAILURE", "SERIOUS DEFECT", "DEFECT", "FLAW" }; + static char *msg[] = { "FAILURE", "SERIOUS DEFECT", "DEFECT", "FLAW" }; - ErrCnt [K] = ErrCnt [K] + 1; - printf("%s: %s", msg[K], T); - } + ErrCnt [K] = ErrCnt [K] + 1; + printf("%s: %s", msg[K], T); + } /* Random */ /* Random computes @@ -1906,174 +1906,174 @@ char *T; FLOAT Random() { - FLOAT X, Y; + FLOAT X, Y; - X = Random1 + Random9; - Y = X * X; - Y = Y * Y; - X = X * Y; - Y = X - FLOOR(X); - Random1 = Y + X * 0.000005; - return(Random1); - } + X = Random1 + Random9; + Y = X * X; + Y = Y * Y; + X = X * Y; + Y = X - FLOOR(X); + Random1 = Y + X * 0.000005; + return(Random1); + } /* SqXMinX */ SqXMinX (ErrKind) int ErrKind; { - FLOAT XA, XB; + FLOAT XA, XB; - XB = X * BInvrse; - XA = X - XB; - SqEr = ((SQRT(X * X) - XB) - XA) / OneUlp; - if (SqEr != Zero) { - if (SqEr < MinSqEr) MinSqEr = SqEr; - if (SqEr > MaxSqEr) MaxSqEr = SqEr; - J = J + 1.0; - BadCond(ErrKind, "\n"); - printf("sqrt( %.17e) - %.17e = %.17e\n", X * X, X, OneUlp * SqEr); - printf("\tinstead of correct value 0 .\n"); - } - } + XB = X * BInvrse; + XA = X - XB; + SqEr = ((SQRT(X * X) - XB) - XA) / OneUlp; + if (SqEr != Zero) { + if (SqEr < MinSqEr) MinSqEr = SqEr; + if (SqEr > MaxSqEr) MaxSqEr = SqEr; + J = J + 1.0; + BadCond(ErrKind, "\n"); + printf("sqrt( %.17e) - %.17e = %.17e\n", X * X, X, OneUlp * SqEr); + printf("\tinstead of correct value 0 .\n"); + } + } /* NewD */ NewD() { - X = Z1 * Q; - X = FLOOR(Half - X / Radix) * Radix + X; - Q = (Q - X * Z) / Radix + X * X * (D / Radix); - Z = Z - Two * X * D; - if (Z <= Zero) { - Z = - Z; - Z1 = - Z1; - } - D = Radix * D; - } + X = Z1 * Q; + X = FLOOR(Half - X / Radix) * Radix + X; + Q = (Q - X * Z) / Radix + X * X * (D / Radix); + Z = Z - Two * X * D; + if (Z <= Zero) { + Z = - Z; + Z1 = - Z1; + } + D = Radix * D; + } /* SR3750 */ SR3750() { - if (! ((X - Radix < Z2 - Radix) || (X - Z2 > W - Z2))) { - I = I + 1; - X2 = SQRT(X * D); - Y2 = (X2 - Z2) - (Y - Z2); - X2 = X8 / (Y - Half); - X2 = X2 - Half * X2 * X2; - SqEr = (Y2 + Half) + (Half - X2); - if (SqEr < MinSqEr) MinSqEr = SqEr; - SqEr = Y2 - X2; - if (SqEr > MaxSqEr) MaxSqEr = SqEr; - } - } + if (! ((X - Radix < Z2 - Radix) || (X - Z2 > W - Z2))) { + I = I + 1; + X2 = SQRT(X * D); + Y2 = (X2 - Z2) - (Y - Z2); + X2 = X8 / (Y - Half); + X2 = X2 - Half * X2 * X2; + SqEr = (Y2 + Half) + (Half - X2); + if (SqEr < MinSqEr) MinSqEr = SqEr; + SqEr = Y2 - X2; + if (SqEr > MaxSqEr) MaxSqEr = SqEr; + } + } /* IsYeqX */ IsYeqX() { - if (Y != X) { - if (N <= 0) { - if (Z == Zero && Q <= Zero) - printf("WARNING: computing\n"); - else BadCond(Defect, "computing\n"); - printf("\t(%.17e) ^ (%.17e)\n", Z, Q); - printf("\tyielded %.17e;\n", Y); - printf("\twhich compared unequal to correct %.17e ;\n", - X); - printf("\t\tthey differ by %.17e .\n", Y - X); - } - N = N + 1; /* ... count discrepancies. */ - } - } + if (Y != X) { + if (N <= 0) { + if (Z == Zero && Q <= Zero) + printf("WARNING: computing\n"); + else BadCond(Defect, "computing\n"); + printf("\t(%.17e) ^ (%.17e)\n", Z, Q); + printf("\tyielded %.17e;\n", Y); + printf("\twhich compared unequal to correct %.17e ;\n", + X); + printf("\t\tthey differ by %.17e .\n", Y - X); + } + N = N + 1; /* ... count discrepancies. */ + } + } /* SR3980 */ SR3980() { - do { - Q = (FLOAT) I; - Y = POW(Z, Q); - IsYeqX(); - if (++I > M) break; - X = Z * X; - } while ( X < W ); - } + do { + Q = (FLOAT) I; + Y = POW(Z, Q); + IsYeqX(); + if (++I > M) break; + X = Z * X; + } while ( X < W ); + } /* PrintIfNPositive */ PrintIfNPositive() { - if (N > 0) printf("Similar discrepancies have occurred %d times.\n", N); - } + if (N > 0) printf("Similar discrepancies have occurred %d times.\n", N); + } /* TstPtUf */ TstPtUf() { - N = 0; - if (Z != Zero) { - printf("Since comparison denies Z = 0, evaluating "); - printf("(Z + Z) / Z should be safe.\n"); - sigsave = sigfpe; - if (setjmp(ovfl_buf)) goto very_serious; - Q9 = (Z + Z) / Z; - printf("What the machine gets for (Z + Z) / Z is %.17e .\n", - Q9); - if (FABS(Q9 - Two) < Radix * U2) { - printf("This is O.K., provided Over/Underflow"); - printf(" has NOT just been signaled.\n"); - } - else { - if ((Q9 < One) || (Q9 > Two)) { + N = 0; + if (Z != Zero) { + printf("Since comparison denies Z = 0, evaluating "); + printf("(Z + Z) / Z should be safe.\n"); + sigsave = sigfpe; + if (setjmp(ovfl_buf)) goto very_serious; + Q9 = (Z + Z) / Z; + printf("What the machine gets for (Z + Z) / Z is %.17e .\n", + Q9); + if (FABS(Q9 - Two) < Radix * U2) { + printf("This is O.K., provided Over/Underflow"); + printf(" has NOT just been signaled.\n"); + } + else { + if ((Q9 < One) || (Q9 > Two)) { very_serious: - N = 1; - ErrCnt [Serious] = ErrCnt [Serious] + 1; - printf("This is a VERY SERIOUS DEFECT!\n"); - } - else { - N = 1; - ErrCnt [Defect] = ErrCnt [Defect] + 1; - printf("This is a DEFECT!\n"); - } - } - sigsave = 0; - V9 = Z * One; - Random1 = V9; - V9 = One * Z; - Random2 = V9; - V9 = Z / One; - if ((Z == Random1) && (Z == Random2) && (Z == V9)) { - if (N > 0) Pause(); - } - else { - N = 1; - BadCond(Defect, "What prints as Z = "); - printf("%.17e\n\tcompares different from ", Z); - if (Z != Random1) printf("Z * 1 = %.17e ", Random1); - if (! ((Z == Random2) - || (Random2 == Random1))) - printf("1 * Z == %g\n", Random2); - if (! (Z == V9)) printf("Z / 1 = %.17e\n", V9); - if (Random2 != Random1) { - ErrCnt [Defect] = ErrCnt [Defect] + 1; - BadCond(Defect, "Multiplication does not commute!\n"); - printf("\tComparison alleges that 1 * Z = %.17e\n", - Random2); - printf("\tdiffers from Z * 1 = %.17e\n", Random1); - } - Pause(); - } - } - } + N = 1; + ErrCnt [Serious] = ErrCnt [Serious] + 1; + printf("This is a VERY SERIOUS DEFECT!\n"); + } + else { + N = 1; + ErrCnt [Defect] = ErrCnt [Defect] + 1; + printf("This is a DEFECT!\n"); + } + } + sigsave = 0; + V9 = Z * One; + Random1 = V9; + V9 = One * Z; + Random2 = V9; + V9 = Z / One; + if ((Z == Random1) && (Z == Random2) && (Z == V9)) { + if (N > 0) Pause(); + } + else { + N = 1; + BadCond(Defect, "What prints as Z = "); + printf("%.17e\n\tcompares different from ", Z); + if (Z != Random1) printf("Z * 1 = %.17e ", Random1); + if (! ((Z == Random2) + || (Random2 == Random1))) + printf("1 * Z == %g\n", Random2); + if (! (Z == V9)) printf("Z / 1 = %.17e\n", V9); + if (Random2 != Random1) { + ErrCnt [Defect] = ErrCnt [Defect] + 1; + BadCond(Defect, "Multiplication does not commute!\n"); + printf("\tComparison alleges that 1 * Z = %.17e\n", + Random2); + printf("\tdiffers from Z * 1 = %.17e\n", Random1); + } + Pause(); + } + } + } notify(s) char *s; { - printf("%s test appears to be inconsistent...\n", s); - printf(" PLEASE NOTIFY KARPINKSI!\n"); - } + printf("%s test appears to be inconsistent...\n", s); + printf(" PLEASE NOTIFY KARPINKSI!\n"); + } /*SPLIT msgs.c */ @@ -2086,134 +2086,134 @@ char **s; Instructions() { static char *instr[] = { - "Lest this program stop prematurely, i.e. before displaying\n", - " 'END OF TEST',\n", - "try to persuade the computer NOT to terminate execution when an", - "error like Over/Underflow or Division by Zero occurs, but rather", - "to persevere with a surrogate value after, perhaps, displaying some", - "warning. If persuasion avails naught, don't despair but run this", - "program anyway to see how many milestones it passes, and then", - "amend it to make further progress.\n", - "Answer questions with Y, y, N or n (unless otherwise indicated).\n", - 0}; + "Lest this program stop prematurely, i.e. before displaying\n", + " 'END OF TEST',\n", + "try to persuade the computer NOT to terminate execution when an", + "error like Over/Underflow or Division by Zero occurs, but rather", + "to persevere with a surrogate value after, perhaps, displaying some", + "warning. If persuasion avails naught, don't despair but run this", + "program anyway to see how many milestones it passes, and then", + "amend it to make further progress.\n", + "Answer questions with Y, y, N or n (unless otherwise indicated).\n", + 0}; - msglist(instr); - } + msglist(instr); + } /* Heading */ Heading() { static char *head[] = { - "Users are invited to help debug and augment this program so it will", - "cope with unanticipated and newly uncovered arithmetic pathologies.\n", - "Please send suggestions and interesting results to", - "\tRichard Karpinski", - "\tComputer Center U-76", - "\tUniversity of California", - "\tSan Francisco, CA 94143-0704, USA\n", - "In doing so, please include the following information:", + "Users are invited to help debug and augment this program so it will", + "cope with unanticipated and newly uncovered arithmetic pathologies.\n", + "Please send suggestions and interesting results to", + "\tRichard Karpinski", + "\tComputer Center U-76", + "\tUniversity of California", + "\tSan Francisco, CA 94143-0704, USA\n", + "In doing so, please include the following information:", #ifdef Single - "\tPrecision:\tsingle;", + "\tPrecision:\tsingle;", #else - "\tPrecision:\tdouble;", + "\tPrecision:\tdouble;", #endif - "\tVersion:\t10 February 1989;", - "\tComputer:\n", - "\tCompiler:\n", - "\tOptimization level:\n", - "\tOther relevant compiler options:", - 0}; + "\tVersion:\t10 February 1989;", + "\tComputer:\n", + "\tCompiler:\n", + "\tOptimization level:\n", + "\tOther relevant compiler options:", + 0}; - msglist(head); - } + msglist(head); + } /* Characteristics */ Characteristics() { - static char *chars[] = { - "Running this program should reveal these characteristics:", - " Radix = 1, 2, 4, 8, 10, 16, 100, 256 ...", - " Precision = number of significant digits carried.", - " U2 = Radix/Radix^Precision = One Ulp", - "\t(OneUlpnit in the Last Place) of 1.000xxx .", - " U1 = 1/Radix^Precision = One Ulp of numbers a little less than 1.0 .", - " Adequacy of guard digits for Mult., Div. and Subt.", - " Whether arithmetic is chopped, correctly rounded, or something else", - "\tfor Mult., Div., Add/Subt. and Sqrt.", - " Whether a Sticky Bit used correctly for rounding.", - " UnderflowThreshold = an underflow threshold.", - " E0 and PseudoZero tell whether underflow is abrupt, gradual, or fuzzy.", - " V = an overflow threshold, roughly.", - " V0 tells, roughly, whether Infinity is represented.", - " Comparisions are checked for consistency with subtraction", - "\tand for contamination with pseudo-zeros.", - " Sqrt is tested. Y^X is not tested.", - " Extra-precise subexpressions are revealed but NOT YET tested.", - " Decimal-Binary conversion is NOT YET tested for accuracy.", - 0}; + static char *chars[] = { + "Running this program should reveal these characteristics:", + " Radix = 1, 2, 4, 8, 10, 16, 100, 256 ...", + " Precision = number of significant digits carried.", + " U2 = Radix/Radix^Precision = One Ulp", + "\t(OneUlpnit in the Last Place) of 1.000xxx .", + " U1 = 1/Radix^Precision = One Ulp of numbers a little less than 1.0 .", + " Adequacy of guard digits for Mult., Div. and Subt.", + " Whether arithmetic is chopped, correctly rounded, or something else", + "\tfor Mult., Div., Add/Subt. and Sqrt.", + " Whether a Sticky Bit used correctly for rounding.", + " UnderflowThreshold = an underflow threshold.", + " E0 and PseudoZero tell whether underflow is abrupt, gradual, or fuzzy.", + " V = an overflow threshold, roughly.", + " V0 tells, roughly, whether Infinity is represented.", + " Comparisions are checked for consistency with subtraction", + "\tand for contamination with pseudo-zeros.", + " Sqrt is tested. Y^X is not tested.", + " Extra-precise subexpressions are revealed but NOT YET tested.", + " Decimal-Binary conversion is NOT YET tested for accuracy.", + 0}; - msglist(chars); - } + msglist(chars); + } History() { /* History */ /* Converted from Brian Wichmann's Pascal version to C by Thos Sumner, - with further massaging by David M. Gay. */ + with further massaging by David M. Gay. */ static char *hist[] = { - "The program attempts to discriminate among", - " FLAWs, like lack of a sticky bit,", - " Serious DEFECTs, like lack of a guard digit, and", - " FAILUREs, like 2+2 == 5 .", - "Failures may confound subsequent diagnoses.\n", - "The diagnostic capabilities of this program go beyond an earlier", - "program called 'MACHAR', which can be found at the end of the", - "book 'Software Manual for the Elementary Functions' (1980) by", - "W. J. Cody and W. Waite. Although both programs try to discover", - "the Radix, Precision and range (over/underflow thresholds)", - "of the arithmetic, this program tries to cope with a wider variety", - "of pathologies, and to say how well the arithmetic is implemented.", - "\nThe program is based upon a conventional radix representation for", - "floating-point numbers, but also allows logarithmic encoding", - "as used by certain early WANG machines.\n", - "BASIC version of this program (C) 1983 by Prof. W. M. Kahan;", - "see source comments for more history.", - 0}; + "The program attempts to discriminate among", + " FLAWs, like lack of a sticky bit,", + " Serious DEFECTs, like lack of a guard digit, and", + " FAILUREs, like 2+2 == 5 .", + "Failures may confound subsequent diagnoses.\n", + "The diagnostic capabilities of this program go beyond an earlier", + "program called 'MACHAR', which can be found at the end of the", + "book 'Software Manual for the Elementary Functions' (1980) by", + "W. J. Cody and W. Waite. Although both programs try to discover", + "the Radix, Precision and range (over/underflow thresholds)", + "of the arithmetic, this program tries to cope with a wider variety", + "of pathologies, and to say how well the arithmetic is implemented.", + "\nThe program is based upon a conventional radix representation for", + "floating-point numbers, but also allows logarithmic encoding", + "as used by certain early WANG machines.\n", + "BASIC version of this program (C) 1983 by Prof. W. M. Kahan;", + "see source comments for more history.", + 0}; - msglist(hist); - } + msglist(hist); + } double pow(x, y) /* return x ^ y (exponentiation) */ double x, y; { - extern double exp(), frexp(), ldexp(), log(), modf(); - double xy, ye; - long i; - int ex, ey = 0, flip = 0; + extern double exp(), frexp(), ldexp(), log(), modf(); + double xy, ye; + long i; + int ex, ey = 0, flip = 0; - if (!y) return 1.0; + if (!y) return 1.0; - if ((y < -1100. || y > 1100.) && x != -1.) return exp(y * log(x)); + if ((y < -1100. || y > 1100.) && x != -1.) return exp(y * log(x)); - if (y < 0.) { y = -y; flip = 1; } - y = modf(y, &ye); - if (y) xy = exp(y * log(x)); - else xy = 1.0; - /* next several lines assume >= 32 bit integers */ - x = frexp(x, &ex); - if (i = ye) for(;;) { - if (i & 1) { xy *= x; ey += ex; } - if (!(i >>= 1)) break; - x *= x; - ex *= 2; - if (x < .5) { x *= 2.; ex -= 1; } - } - if (flip) { xy = 1. / xy; ey = -ey; } - return ldexp(xy, ey); + if (y < 0.) { y = -y; flip = 1; } + y = modf(y, &ye); + if (y) xy = exp(y * log(x)); + else xy = 1.0; + /* next several lines assume >= 32 bit integers */ + x = frexp(x, &ex); + if (i = ye) for(;;) { + if (i & 1) { xy *= x; ey += ex; } + if (!(i >>= 1)) break; + x *= x; + ex *= 2; + if (x < .5) { x *= 2.; ex -= 1; } + } + if (flip) { xy = 1. / xy; ey = -ey; } + return ldexp(xy, ey); } #endif /* NO_FLOATS */ diff --git a/test/ref/pointer2.c b/test/ref/pointer2.c index 29f9e3de4..cfa384268 100644 --- a/test/ref/pointer2.c +++ b/test/ref/pointer2.c @@ -16,15 +16,15 @@ char i1[]; void test1(void) { int a; - a=sizeof(i1[0]); - printf("%04x - ",a); - if(sizeof(i1[0])==sizeof(char)) { - /* gcc gives size of element */ - printf("sizeof(i1[0]) gives size of element\n"); - } - if(sizeof(i1[0])==sizeof(char*)) { - printf("sizeof(i1[0]) gives size of pointer to element\n"); - } + a=sizeof(i1[0]); + printf("%04x - ",a); + if(sizeof(i1[0])==sizeof(char)) { + /* gcc gives size of element */ + printf("sizeof(i1[0]) gives size of element\n"); + } + if(sizeof(i1[0])==sizeof(char*)) { + printf("sizeof(i1[0]) gives size of pointer to element\n"); + } } /* @@ -40,14 +40,14 @@ char *t4={"abcde"}; void test2(void) { char c1,c2,c3,c4; int i,e=0; - for(i=0;i<5;i++){ - c1=t1[i];c2=t2[i];c3=t3[i];c4=t4[i]; -/* printf("%02x %02x %02x %02x\n",c1,c2,c3,c4); */ - printf("%c %c %c %c\n",c1,c2,c3,c4); - if(!((c1==c2)&(c1==c3)&(c1==c4))) e=1; - } - if(e) printf("test2 failed.\n"); - else printf("test2 ok.\n"); + for(i=0;i<5;i++){ + c1=t1[i];c2=t2[i];c3=t3[i];c4=t4[i]; +/* printf("%02x %02x %02x %02x\n",c1,c2,c3,c4); */ + printf("%c %c %c %c\n",c1,c2,c3,c4); + if(!((c1==c2)&(c1==c3)&(c1==c4))) e=1; + } + if(e) printf("test2 failed.\n"); + else printf("test2 ok.\n"); } /* @@ -74,7 +74,7 @@ A3 a3[] = { #endif void test3a(A3 *list, int number){ - printf("%s %d\n",list->name,number); + printf("%s %d\n",list->name,number); } static void test31(void) @@ -103,10 +103,10 @@ static void test30(void) */ int main(void) { - test1(); - test2(); - test30(); - test31(); -/* test32(); */ - return 0; + test1(); + test2(); + test30(); + test31(); +/* test32(); */ + return 0; } diff --git a/test/ref/sort.c b/test/ref/sort.c index 5db5cf01b..b4dee8734 100644 --- a/test/ref/sort.c +++ b/test/ref/sort.c @@ -14,62 +14,62 @@ int *xx; exchange(int *x,int *y) { int t; - printf("exchange(%d,%d)\n", x - xx, y - xx); - t = *x; *x = *y; *y = t; + printf("exchange(%d,%d)\n", x - xx, y - xx); + t = *x; *x = *y; *y = t; } /* partition - partition a[i..j] */ int partition(int a[], int i, int j) { int v, k; - j++; - k = i; - v = a[k]; - while (i < j) { - i++; while (a[i] < v) i++; - j--; while (a[j] > v) j--; - if (i < j) exchange(&a[i], &a[j]); - } - exchange(&a[k], &a[j]); - return j; + j++; + k = i; + v = a[k]; + while (i < j) { + i++; while (a[i] < v) i++; + j--; while (a[j] > v) j--; + if (i < j) exchange(&a[i], &a[j]); + } + exchange(&a[k], &a[j]); + return j; } /* quick - quicksort a[lb..ub] */ void quick(int a[], int lb, int ub) { int k; - if (lb >= ub) - return; - k = partition(a, lb, ub); - quick(a, lb, k - 1); - quick(a, k + 1, ub); + if (lb >= ub) + return; + k = partition(a, lb, ub); + quick(a, lb, k - 1); + quick(a, k + 1, ub); } /* sort - sort a[0..n-1] into increasing order */ sort(int a[], int n) { - quick(xx = a, 0, --n); + quick(xx = a, 0, --n); } /* putd - output decimal number */ void putd(int n) { - if (n < 0) { - putchar('-'); - n = -n; - } - if (n/10) - putd(n/10); - putchar(n%10 + '0'); + if (n < 0) { + putchar('-'); + n = -n; + } + if (n/10) + putd(n/10); + putchar(n%10 + '0'); } int main(void) { - int i; + int i; - sort(in, (sizeof in)/(sizeof in[0])); - for (i = 0; i < (sizeof in)/(sizeof in[0]); i++) { - putd(in[i]); - putchar('\n'); - } + sort(in, (sizeof in)/(sizeof in[0])); + for (i = 0; i < (sizeof in)/(sizeof in[0]); i++) { + putd(in[i]); + putchar('\n'); + } - return 0; + return 0; } diff --git a/test/ref/spill.c b/test/ref/spill.c index 56b03d6a7..316928ab3 100644 --- a/test/ref/spill.c +++ b/test/ref/spill.c @@ -51,6 +51,6 @@ int j, k, m, n; #endif f5(){ - x=A[k*m]*A[j*m]+B[k*n]*B[j*n]; - x=A[k*m]*B[j*n]-B[k*n]*A[j*m]; + x=A[k*m]*A[j*m]+B[k*n]*B[j*n]; + x=A[k*m]*B[j*n]-B[k*n]*A[j*m]; } diff --git a/test/ref/stdarg.c b/test/ref/stdarg.c index 295a2ccad..b88fcaafe 100644 --- a/test/ref/stdarg.c +++ b/test/ref/stdarg.c @@ -10,15 +10,15 @@ #ifndef NO_FUNCS_TAKE_STRUCTS struct node { - int a[4]; + int a[4]; } x = { #ifdef NO_SLOPPY_STRUCT_INIT - { + { #endif - 1,2,3,4 + 1,2,3,4 #ifdef NO_SLOPPY_STRUCT_INIT - } + } #endif }; #endif @@ -27,68 +27,68 @@ print(char *fmt, ...); main() { - print("test 1\n"); - print("test %s\n", "2"); - print("test %d%c", 3, '\n'); - print("%s%s %w%c", "te", "st", 4, '\n'); + print("test 1\n"); + print("test %s\n", "2"); + print("test %d%c", 3, '\n'); + print("%s%s %w%c", "te", "st", 4, '\n'); #ifdef NO_FLOATS - print("%s%s %f%c", "te", "st", (signed long) 5, '\n'); - #else - print("%s%s %f%c", "te", "st", 5.0, '\n'); + print("%s%s %f%c", "te", "st", (signed long) 5, '\n'); + #else + print("%s%s %f%c", "te", "st", 5.0, '\n'); #endif - #ifndef NO_FUNCS_TAKE_STRUCTS + #ifndef NO_FUNCS_TAKE_STRUCTS print("%b %b %b %b %b %b\n", x, x, x, x, x, x); - #endif - return 0; + #endif + return 0; } print(char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - for (; *fmt; fmt++) - { - if (*fmt == '%') - switch (*++fmt) { + va_list ap; + va_start(ap, fmt); + for (; *fmt; fmt++) + { + if (*fmt == '%') + switch (*++fmt) { case 'b': { - #ifdef NO_FUNCS_TAKE_STRUCTS - printf("(1 2 3 4)"); - #else - struct node x = - va_arg( - ap, - struct node - ); - printf("(%d %d %d %d)", x.a[0], x.a[1], x.a[2], x.a[3]); - #endif + #ifdef NO_FUNCS_TAKE_STRUCTS + printf("(1 2 3 4)"); + #else + struct node x = + va_arg( + ap, + struct node + ); + printf("(%d %d %d %d)", x.a[0], x.a[1], x.a[2], x.a[3]); + #endif break; } - case 'c': - /* printf("%c", va_arg(ap, char)); */ - printf("%c", va_arg(ap, int)); - break; - case 'd': - printf("%d", va_arg(ap, int)); - break; - case 'w': - /* printf("%x", va_arg(ap, short)); */ - printf("%x", va_arg(ap, int)); - break; - case 's': - printf("%s", va_arg(ap, char *)); - break; - case 'f': - #ifdef NO_FLOATS - printf("%ld.000000", va_arg(ap, signed long)); - #else - printf("%f", va_arg(ap, double)); - #endif - break; - default: - printf("%c", *fmt); - break; - } - else - printf("%c", *fmt); - } - va_end(ap); + case 'c': + /* printf("%c", va_arg(ap, char)); */ + printf("%c", va_arg(ap, int)); + break; + case 'd': + printf("%d", va_arg(ap, int)); + break; + case 'w': + /* printf("%x", va_arg(ap, short)); */ + printf("%x", va_arg(ap, int)); + break; + case 's': + printf("%s", va_arg(ap, char *)); + break; + case 'f': + #ifdef NO_FLOATS + printf("%ld.000000", va_arg(ap, signed long)); + #else + printf("%f", va_arg(ap, double)); + #endif + break; + default: + printf("%c", *fmt); + break; + } + else + printf("%c", *fmt); + } + va_end(ap); } diff --git a/test/ref/strptr.c b/test/ref/strptr.c index 8bfa983a8..152c1bb48 100644 --- a/test/ref/strptr.c +++ b/test/ref/strptr.c @@ -24,7 +24,7 @@ FILE *outfile=NULL; #else #endif - + #include <stdio.h> #include <stdlib.h> #include <fcntl.h> @@ -34,18 +34,18 @@ FILE *outfile=NULL; struct Xdirent { - char d_name[XNAME_MAX+1]; - unsigned short d_off; - unsigned short d_reclen; - unsigned char d_type; - unsigned char d_namlen; + char d_name[XNAME_MAX+1]; + unsigned short d_off; + unsigned short d_reclen; + unsigned char d_type; + unsigned char d_namlen; }; typedef struct { - unsigned char fd; - unsigned short off; - char name[XNAME_MAX+1]; + unsigned char fd; + unsigned short off; + char name[XNAME_MAX+1]; } XDIR; unsigned char b1[4]; @@ -61,51 +61,51 @@ static struct Xdirent entry; unsigned char fd; static unsigned char ch; - entry.d_off=dir->off; + entry.d_off=dir->off; - /* basic line-link / file-length */ - memcpy(buffer,b1,4); - - dir->off=dir->off+4; - entry.d_reclen=254*(buffer[2]+(buffer[3]<<8)); + /* basic line-link / file-length */ + memcpy(buffer,b1,4); + + dir->off=dir->off+4; + entry.d_reclen=254*(buffer[2]+(buffer[3]<<8)); - /* read file entry */ - memcpy(buffer,b2,0x10); - - dir->off=dir->off+i; + /* read file entry */ + memcpy(buffer,b2,0x10); + + dir->off=dir->off+i; - printf("Xreaddir: '%s'\n",buffer); - - /* skip until either quote (file) or b (blocks free => end) */ - i=0;ii=0; - while(i==0){ - temp=buffer[ii];ii++; - if(ii>16){ - /* something went wrong...this shouldnt happen! */ - return(NULL); - } - else if(temp=='\"') i++; - else if(temp=='b') { - /* "blocks free" */ - return(NULL); - } - } - printf("Xreaddir: '%s'\n",buffer); + printf("Xreaddir: '%s'\n",buffer); + + /* skip until either quote (file) or b (blocks free => end) */ + i=0;ii=0; + while(i==0){ + temp=buffer[ii];ii++; + if(ii>16){ + /* something went wrong...this shouldnt happen! */ + return(NULL); + } + else if(temp=='\"') i++; + else if(temp=='b') { + /* "blocks free" */ + return(NULL); + } + } + printf("Xreaddir: '%s'\n",buffer); - /* process file entry */ + /* process file entry */ - i=0; temp=buffer[ii];ii++; - while(temp!='\"'){ - entry.d_name[i]=temp; - i++; - temp=buffer[ii];ii++; - } - entry.d_name[i]=0; - entry.d_namlen=i; + i=0; temp=buffer[ii];ii++; + while(temp!='\"'){ + entry.d_name[i]=temp; + i++; + temp=buffer[ii];ii++; + } + entry.d_name[i]=0; + entry.d_namlen=i; - /* set type flag */ + /* set type flag */ - return(&entry); + return(&entry); } int main(void) @@ -113,16 +113,16 @@ int main(void) char mydirname[XNAME_MAX+1]="."; XDIR mydir; struct Xdirent *mydirent; - + printf("start\n"); if((mydirent=Xreaddir(&mydir))==NULL) { - printf("NULL\n"); + printf("NULL\n"); } else { - printf("=%s\n",mydirent->d_name); + printf("=%s\n",mydirent->d_name); } printf("done\n"); diff --git a/test/ref/struct.c b/test/ref/struct.c index a0f181e96..15fae62fc 100644 --- a/test/ref/struct.c +++ b/test/ref/struct.c @@ -74,8 +74,8 @@ void makepoint(point *p,int x, int y) { /* make a rectangle from two points */ void makerect(rect *d,point p1, point p2) { rect r; - r.pt1 = p1; - r.pt2 = p2; + r.pt1 = p1; + r.pt2 = p2; canonrect(d,r); } @@ -97,53 +97,53 @@ odd(struct odd y) { /* add two points */ point addpoint(point p1, point p2) { - p1.x += p2.x; - p1.y += p2.y; - return p1; + p1.x += p2.x; + p1.y += p2.y; + return p1; } /* canonicalize rectangle coordinates */ rect canonrect(rect r) { - rect temp; + rect temp; - temp.pt1.x = min(r.pt1.x, r.pt2.x); - temp.pt1.y = min(r.pt1.y, r.pt2.y); - temp.pt2.x = max(r.pt1.x, r.pt2.x); - temp.pt2.y = max(r.pt1.y, r.pt2.y); - return temp; + temp.pt1.x = min(r.pt1.x, r.pt2.x); + temp.pt1.y = min(r.pt1.y, r.pt2.y); + temp.pt2.x = max(r.pt1.x, r.pt2.x); + temp.pt2.y = max(r.pt1.y, r.pt2.y); + return temp; } /* make a point from x and y components */ point makepoint(int x, int y) { - point p; + point p; - p.x = x; - p.y = y; - return p; + p.x = x; + p.y = y; + return p; } /* make a rectangle from two points */ rect makerect(point p1, point p2) { - rect r; + rect r; - r.pt1 = p1; - r.pt2 = p2; - return canonrect(r); + r.pt1 = p1; + r.pt2 = p2; + return canonrect(r); } struct odd {char a[3]; } y = { #ifdef NO_SLOPPY_STRUCT_INIT - { + { #endif - 'a', 'b', 0 + 'a', 'b', 0 #ifdef NO_SLOPPY_STRUCT_INIT - } + } #endif }; odd(struct odd y) { - struct odd x - = y; + struct odd x + = y; printf("%s\n\r", x.a); } @@ -157,8 +157,8 @@ int ptinrect(point *p, rect *r) { } #else int ptinrect(point p, rect r) { - return p.x >= r.pt1.x && p.x < r.pt2.x - && p.y >= r.pt1.y && p.y < r.pt2.y; + return p.x >= r.pt1.x && p.x < r.pt2.x + && p.y >= r.pt1.y && p.y < r.pt2.y; } #endif @@ -212,9 +212,9 @@ point pts[] = { -1, -1, 1, 1, 20, 300, 500, 400 }; #else if (ptinrect(x, screen) == 0) #endif - { + { printf("not "); - } + } printf("within (%d,%d; %d,%d)\n\r", screen.pt1.x, screen.pt1.y, screen.pt2.x, screen.pt2.y); } @@ -240,24 +240,24 @@ point pts[] = { -1, -1, 1, 1, 20, 300, 500, 400 }; #endif rect screen = - makerect( - addpoint(maxpt, makepoint(-10, -10)), - addpoint(origin, makepoint(10, 10)) - ); + makerect( + addpoint(maxpt, makepoint(-10, -10)), + addpoint(origin, makepoint(10, 10)) + ); - test1(); - - for (i = 0; i < sizeof pts/sizeof pts[0]; i++) { - printf("(%d,%d) is ", pts[i].x, - (x = makepoint(pts[i].x, pts[i].y)).y); - if (ptinrect(x, screen) == 0) - printf("not "); + test1(); + + for (i = 0; i < sizeof pts/sizeof pts[0]; i++) { + printf("(%d,%d) is ", pts[i].x, + (x = makepoint(pts[i].x, pts[i].y)).y); + if (ptinrect(x, screen) == 0) + printf("not "); printf("within (%d,%d; %d,%d)\n\r", screen.pt1.x, screen.pt1.y, - screen.pt2.x, screen.pt2.y); - } - odd(y); + screen.pt2.x, screen.pt2.y); + } + odd(y); - return 0; + return 0; } #endif /* FUNCS_RETURN_STRUCTS */ diff --git a/test/ref/switch.c b/test/ref/switch.c index 0821d29ee..dc7fdc8ce 100644 --- a/test/ref/switch.c +++ b/test/ref/switch.c @@ -18,9 +18,9 @@ limit(); big( # ifdef ASSUME_32BIT_UNSIGNED - unsigned + unsigned # else - unsigned long + unsigned long # endif x); @@ -28,28 +28,28 @@ x); main() { - testbackslash(); - f(); - g(); - h(); - testbig(); /* ! broken long int compare (?) */ - limit(); /* ! broken long int compare (?) */ + testbackslash(); + f(); + g(); + h(); + testbig(); /* ! broken long int compare (?) */ + limit(); /* ! broken long int compare (?) */ - return 0; + return 0; } testbig() { - #ifdef ASSUME_32BIT_INT - int i; - #else - signed long i; - #endif - /* 2341234 2341234 2341234 */ - for (i = 0x1000000; i&0x7000000; i += 0x1000000) { -/* printf("i = 0x%lx\n", i); */ - big(i); - } + #ifdef ASSUME_32BIT_INT + int i; + #else + signed long i; + #endif + /* 2341234 2341234 2341234 */ + for (i = 0x1000000; i&0x7000000; i += 0x1000000) { +/* printf("i = 0x%lx\n", i); */ + big(i); + } } #ifdef NO_LOCAL_STRING_INIT @@ -69,93 +69,93 @@ testbackslash() #else for (s = "bfnrtvx"; *s; s++) { #endif - printf("%c = %c\n", *s, backslash(*s)); + printf("%c = %c\n", *s, backslash(*s)); } } backslash(c) { - switch (c) + switch (c) { - case 'b': - return 'b'; - case 'f': - return 'f'; - case 'n': - return 'n'; - case 'r': - return 'r'; - case 't': - return 't'; - case 'v': + case 'b': + return 'b'; + case 'f': + return 'f'; + case 'n': + return 'n'; + case 'r': + return 'r'; + case 't': + return 't'; + case 'v': return 'v'; - } + } - return 'x'; + return 'x'; } f() { - int i, x = 0, y; + int i, x = 0, y; - printf("f:\n"); - for (i = 0; i <= 20; i++) { - y = i; - switch (i) { - case 1: x = i; break; - case 2: x = i; break; - case 7: x = i; break; - case 8: x = i; break; - case 9: x = i; break; - case 16: x = i; break; - case 17: x = i; break; - case 18: x = i; break; - case 19: x = i; break; - case 20: x = i; break; - } - printf("x = %d\n", x); - } + printf("f:\n"); + for (i = 0; i <= 20; i++) { + y = i; + switch (i) { + case 1: x = i; break; + case 2: x = i; break; + case 7: x = i; break; + case 8: x = i; break; + case 9: x = i; break; + case 16: x = i; break; + case 17: x = i; break; + case 18: x = i; break; + case 19: x = i; break; + case 20: x = i; break; + } + printf("x = %d\n", x); + } } g() { - int i; + int i; - printf("g:\n"); - for (i = 1; i <= 10; i++) - switch (i) { - case 1: case 2: printf("1 %d\n", i); break; - case 3: case 4: case 5: printf("2 %d\n", i); break; - case 6: case 7: case 8: printf("3 %d\n", i); - default: - printf("d %d\n", i); break; - case 1001: case 1002: case 1003: case 1004: - printf("5 %d\n", i); break; - case 3001: case 3002: case 3003: case 3004: - printf("6 %d\n", i); break; - } + printf("g:\n"); + for (i = 1; i <= 10; i++) + switch (i) { + case 1: case 2: printf("1 %d\n", i); break; + case 3: case 4: case 5: printf("2 %d\n", i); break; + case 6: case 7: case 8: printf("3 %d\n", i); + default: + printf("d %d\n", i); break; + case 1001: case 1002: case 1003: case 1004: + printf("5 %d\n", i); break; + case 3001: case 3002: case 3003: case 3004: + printf("6 %d\n", i); break; + } } h() { - int i, n=0; + int i, n=0; - printf("h:\n"); - for (i = 1; i <= 500; i++) - switch (i) { - default: n++; continue; - case 128: printf("i = %d\n", i); break; - case 16: printf("i = %d\n", i); break; - case 8: printf("i = %d\n", i); break; - case 120: printf("i = %d\n", i); break; - case 280: printf("i = %d\n", i); break; - case 264: printf("i = %d\n", i); break; - case 248: printf("i = %d\n", i); break; - case 272: printf("i = %d\n", i); break; - case 304: printf("i = %d\n", i); break; - case 296: printf("i = %d\n", i); break; - case 288: printf("i = %d\n", i); break; - case 312: printf("i = %d\n", i); break; - } - printf("%d defaults\n", n); + printf("h:\n"); + for (i = 1; i <= 500; i++) + switch (i) { + default: n++; continue; + case 128: printf("i = %d\n", i); break; + case 16: printf("i = %d\n", i); break; + case 8: printf("i = %d\n", i); break; + case 120: printf("i = %d\n", i); break; + case 280: printf("i = %d\n", i); break; + case 264: printf("i = %d\n", i); break; + case 248: printf("i = %d\n", i); break; + case 272: printf("i = %d\n", i); break; + case 304: printf("i = %d\n", i); break; + case 296: printf("i = %d\n", i); break; + case 288: printf("i = %d\n", i); break; + case 312: printf("i = %d\n", i); break; + } + printf("%d defaults\n", n); } #ifdef NO_OLD_FUNC_DECL @@ -165,9 +165,9 @@ h() #endif # ifdef ASSUME_32BIT_UNSIGNED - unsigned + unsigned # else - unsigned long + unsigned long # endif #ifdef NO_OLD_FUNC_DECL @@ -176,42 +176,42 @@ h() x; { #endif -/* printf("x = 0x%x\n", x); */ +/* printf("x = 0x%x\n", x); */ - switch(x&0x6000000){ - case -1: - case -2: - case 0x0000000: - printf("x = 0x%lx\n", x); break; - case 0x2000000: - printf("x = 0x%lx\n", x); break; - case 0x4000000: - printf("x = 0x%lx\n", x); break; - default: - printf("x = 0x%lx (default)\n", x); break; - } + switch(x&0x6000000){ + case -1: + case -2: + case 0x0000000: + printf("x = 0x%lx\n", x); break; + case 0x2000000: + printf("x = 0x%lx\n", x); break; + case 0x4000000: + printf("x = 0x%lx\n", x); break; + default: + printf("x = 0x%lx (default)\n", x); break; + } } limit() { - int i; + int i; - for (i = INT_MIN; i <= INT_MIN+5; i++) -/* for (i = INT_MIN; i < INT_MIN+6; i++) */ - switch (i) { - case INT_MIN: printf("0\n"); break; - case INT_MIN+1: printf("1\n"); break; - case INT_MIN+2: printf("2\n"); break; - case INT_MIN+3: printf("3\n"); break; - case INT_MIN+4: printf("4\n"); break; - default: printf("5\n"); break; - } - for (i = INT_MAX; i >= INT_MAX-5; i--) - switch (i) { - case INT_MAX: printf("0\n"); break; - case INT_MAX-1: printf("1\n"); break; - case INT_MAX-2: printf("2\n"); break; - case INT_MAX-3: printf("3\n"); break; - case INT_MAX-4: printf("4\n"); break; - default: printf("5\n"); break; - } + for (i = INT_MIN; i <= INT_MIN+5; i++) +/* for (i = INT_MIN; i < INT_MIN+6; i++) */ + switch (i) { + case INT_MIN: printf("0\n"); break; + case INT_MIN+1: printf("1\n"); break; + case INT_MIN+2: printf("2\n"); break; + case INT_MIN+3: printf("3\n"); break; + case INT_MIN+4: printf("4\n"); break; + default: printf("5\n"); break; + } + for (i = INT_MAX; i >= INT_MAX-5; i--) + switch (i) { + case INT_MAX: printf("0\n"); break; + case INT_MAX-1: printf("1\n"); break; + case INT_MAX-2: printf("2\n"); break; + case INT_MAX-3: printf("3\n"); break; + case INT_MAX-4: printf("4\n"); break; + default: printf("5\n"); break; + } } diff --git a/test/ref/switch2.c b/test/ref/switch2.c index 7a9bcecd7..7884f3722 100644 --- a/test/ref/switch2.c +++ b/test/ref/switch2.c @@ -9,31 +9,31 @@ #include <stdio.h> void testlimits(int i) { - printf("%d:",i); + printf("%d:",i); - switch(i) { - case -1: /* works */ - /* case 0xffff: */ /* 'range error' (-1) */ + switch(i) { + case -1: /* works */ + /* case 0xffff: */ /* 'range error' (-1) */ - printf("-1\n"); - break; - /* max int */ + printf("-1\n"); + break; + /* max int */ -/* case 0x7fff: */ /* works */ - case 32767: /* works */ - /* case 32768: */ /* 'range error' (correct for that one!) */ +/* case 0x7fff: */ /* works */ + case 32767: /* works */ + /* case 32768: */ /* 'range error' (correct for that one!) */ - printf("max\n"); - break; - /* min int */ + printf("max\n"); + break; + /* min int */ - case -32768: /* 'warning. constant is long' */ - /* case 0x8000: */ /* 'range error' */ - /* case -32769: */ /* 'range error' (correct for that one!) */ - printf("min\n"); - break; - } - printf("\n"); + case -32768: /* 'warning. constant is long' */ + /* case 0x8000: */ /* 'range error' */ + /* case -32769: */ /* 'range error' (correct for that one!) */ + printf("min\n"); + break; + } + printf("\n"); } void testdefault1(unsigned char i) { @@ -45,9 +45,9 @@ signed char k; #else char k; #endif - + #else - + #ifdef UNSIGNED_CHARS signed char k; #else @@ -56,89 +56,89 @@ char k; #endif - for(;i<254;) { - k = i; - printf(">%d\n",i);i++; - switch(k) { - case 1: - break; - case 2: - break; - case 3: - break; - case 4: - break; - case 5: - break; - case 6: - break; - case 7: - break; - case 8: - break; - case 9: - break; - case 10: - break; - case 11: - break; - case 12: - break; - case 13: - break; - case 14: - break; - case 15: - break; - case 17: - break; - /* triggers bug ? */ - /* gcc warning: case label value exceeds maximum value for type */ - /* cc65 error: range error */ + for(;i<254;) { + k = i; + printf(">%d\n",i);i++; + switch(k) { + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + break; + case 7: + break; + case 8: + break; + case 9: + break; + case 10: + break; + case 11: + break; + case 12: + break; + case 13: + break; + case 14: + break; + case 15: + break; + case 17: + break; + /* triggers bug ? */ + /* gcc warning: case label value exceeds maximum value for type */ + /* cc65 error: range error */ - /* - case 170: - break; - */ - case 18: - break; - case 19: - break; - case 20: - break; - case 21: - break; - case 22: - break; - case 23: - break; - case 24: - switch(k) { - case 1: - break; - case 2: - break; - case 3: - break; - case 4: - case 5: - break; - case 6: - case 7: - break; - case 8: - case 9: - break; - } - break; - case 100: - break; - default: - printf(">>>default\n"); - /* triggers bug if this break; is missing? */ - /* break; */ - } - } + /* + case 170: + break; + */ + case 18: + break; + case 19: + break; + case 20: + break; + case 21: + break; + case 22: + break; + case 23: + break; + case 24: + switch(k) { + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + case 5: + break; + case 6: + case 7: + break; + case 8: + case 9: + break; + } + break; + case 100: + break; + default: + printf(">>>default\n"); + /* triggers bug if this break; is missing? */ + /* break; */ + } + } } void testdefault2(unsigned char i) { @@ -150,9 +150,9 @@ char k; #else unsigned char k; #endif - + #else - + #ifdef UNSIGNED_CHARS char k; #else @@ -161,102 +161,102 @@ unsigned char k; #endif - for(;i<254;) { - k = i; - printf(">%d\n",i);i++; - switch(k) { - case 1: - break; - case 2: - break; - case 3: - break; - case 4: - break; - case 5: - break; - case 6: - break; - case 7: - break; - case 8: - break; - case 9: - break; - case 10: - break; - case 11: - break; - case 12: - break; - case 13: - break; - case 14: - break; - case 15: - break; - case 17: - break; - /* triggers bug ? */ + for(;i<254;) { + k = i; + printf(">%d\n",i);i++; + switch(k) { + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + break; + case 7: + break; + case 8: + break; + case 9: + break; + case 10: + break; + case 11: + break; + case 12: + break; + case 13: + break; + case 14: + break; + case 15: + break; + case 17: + break; + /* triggers bug ? */ - case 170: - break; - - case 18: - break; - case 19: - break; - case 20: - break; - case 21: - break; - case 22: - break; - case 23: - break; - case 24: - switch(k) { - case 1: - break; - case 2: - break; - case 3: - break; - case 4: - case 5: - break; - case 6: - case 7: - break; - case 8: - case 9: - break; - } - break; - case 100: - break; - default: - printf(">>>default\n"); - /* triggers bug if this break; is missing? */ - /* break; */ - } - } + case 170: + break; + + case 18: + break; + case 19: + break; + case 20: + break; + case 21: + break; + case 22: + break; + case 23: + break; + case 24: + switch(k) { + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + case 5: + break; + case 6: + case 7: + break; + case 8: + case 9: + break; + } + break; + case 100: + break; + default: + printf(">>>default\n"); + /* triggers bug if this break; is missing? */ + /* break; */ + } + } } int main(void) { - testlimits(32767); - testlimits(-32768); - testlimits(-1); - - testdefault1(1); - testdefault1(2); - testdefault1(3); - testdefault1(4); - - testdefault2(1); - testdefault2(2); - testdefault2(3); - testdefault2(4); + testlimits(32767); + testlimits(-32768); + testlimits(-1); + + testdefault1(1); + testdefault1(2); + testdefault1(3); + testdefault1(4); + + testdefault2(1); + testdefault2(2); + testdefault2(3); + testdefault2(4); - return 0; + return 0; } diff --git a/test/ref/varargs.c b/test/ref/varargs.c index 3d61fdbd0..c3e89aaa5 100644 --- a/test/ref/varargs.c +++ b/test/ref/varargs.c @@ -86,7 +86,7 @@ static char string[0x100]; va_start(ap,format); vsprintf(string,format,ap); - printf("fd:%d,format:%s,string:%s\n",fd,format,string); + printf("fd:%d,format:%s,string:%s\n",fd,format,string); va_end(ap); } diff --git a/test/ref/wf1.c b/test/ref/wf1.c index 0539d8398..1c3bfbd37 100644 --- a/test/ref/wf1.c +++ b/test/ref/wf1.c @@ -16,12 +16,12 @@ FILE *in; struct node { - int count; /* frequency count */ - struct node *left; /* left subtree */ - struct node *right; /* right subtree */ - char *word; /* word itself */ + int count; /* frequency count */ + struct node *left; /* left subtree */ + struct node *right; /* right subtree */ + char *word; /* word itself */ } words[MAXWORDS]; -int next; /* index of next free entry in words */ +int next; /* index of next free entry in words */ /*struct node *lookup();*/ @@ -38,14 +38,14 @@ struct node *lookup(char *word, struct node **p); int isletter(char c); -/* err - print error message s and die */ +/* err - print error message s and die */ #ifndef NO_OLD_FUNC_DECL err(s) char *s; { #else int err(char *s) { #endif - printf("? %s\n", s); - exit(1); + printf("? %s\n", s); + exit(1); } /* getword - get next input word into buf, return 0 on EOF */ @@ -55,25 +55,25 @@ int getword(buf) char *buf; int getword(char *buf) #endif { - char *s; - int c; + char *s; + int c; while (((c = getchar()) != -1) && (isletter(c) == 0)) - ; + ; for (s = buf; (c = isletter(c)); c = getchar()) - *s++ = c; - *s = 0; - if (s > buf) - return 1; - return 0; + *s++ = c; + *s = 0; + if (s > buf) + return 1; + return 0; } /* isletter - return folded version of c if it is a letter, 0 otherwise */ int isletter(char c) { - if ((c >= 'A') && (c <= 'Z')) c += 'a' - 'A'; - if ((c >= 'a') && (c <= 'z')) return c; - return 0; + if ((c >= 'A') && (c <= 'Z')) c += 'a' - 'A'; + if ((c >= 'a') && (c <= 'z')) return c; + return 0; } /* lookup - lookup word in tree; install if necessary */ @@ -84,27 +84,27 @@ char *word; struct node **p; struct node *lookup(char *word, struct node **p) #endif { - int cond; -/* char *malloc(); */ + int cond; +/* char *malloc(); */ - if (*p) { - cond = strcmp(word, (*p)->word); - if (cond < 0) - return lookup(word, &(*p)->left); - else if (cond > 0) - return lookup(word, &(*p)->right); - else - return *p; - } - if (next >= MAXWORDS) - err("out of node storage"); - words[next].count = 0; - words[next].left = words[next].right = 0; - words[next].word = malloc(strlen(word) + 1); - if (words[next].word == 0) - err("out of word storage"); - strcpy(words[next].word, word); - return *p = &words[next++]; + if (*p) { + cond = strcmp(word, (*p)->word); + if (cond < 0) + return lookup(word, &(*p)->left); + else if (cond > 0) + return lookup(word, &(*p)->right); + else + return *p; + } + if (next >= MAXWORDS) + err("out of node storage"); + words[next].count = 0; + words[next].left = words[next].right = 0; + words[next].word = malloc(strlen(word) + 1); + if (words[next].word == 0) + err("out of word storage"); + strcpy(words[next].word, word); + return *p = &words[next++]; } /* tprint - print tree */ @@ -113,28 +113,28 @@ void tprint(tree) struct node *tree; { #else void tprint(struct node *tree) { #endif - if (tree) { - tprint(tree->left); - printf("%d:%s\n", tree->count, tree->word); - tprint(tree->right); - } + if (tree) { + tprint(tree->left); + printf("%d:%s\n", tree->count, tree->word); + tprint(tree->right); + } } int main(void) { - struct node *root; - char word[20]; + struct node *root; + char word[20]; in = fopen("wf1.in","rb"); if (in == NULL) { return EXIT_FAILURE; } - root = 0; - next = 0; - while (getword(word)) - lookup(word, &root)->count++; - tprint(root); + root = 0; + next = 0; + while (getword(word)) + lookup(word, &root)->count++; + tprint(root); fclose(in); return 0; diff --git a/test/ref/yacc.c b/test/ref/yacc.c index ab72e24c0..f2c3e2a58 100644 --- a/test/ref/yacc.c +++ b/test/ref/yacc.c @@ -72,9 +72,9 @@ int yytchar; extern int yylineno; struct yysvf { - struct yywork *yystoff; - struct yysvf *yyother; - int *yystops; + struct yywork *yystoff; + struct yysvf *yyother; + int *yystops; }; struct yysvf *yyestate; extern struct yysvf yysvec[], *yybgin; @@ -96,18 +96,18 @@ yyback(int *p,int m); #ifdef YYDEBUG void printchar(char *name,int ch) { - if((ch==YYNEWLINE)) - { - fprintf(yyout," %s=YYNEWLINE\n",name); - } - else if((ch<0)||(ch>0xf0)||(!isprint(ch))) - { - fprintf(yyout," %s=%04x\n",name,ch &0xffff); - } - else - { - fprintf(yyout," %s='%c'\n",name,ch); - } + if((ch==YYNEWLINE)) + { + fprintf(yyout," %s=YYNEWLINE\n",name); + } + else if((ch<0)||(ch>0xf0)||(!isprint(ch))) + { + fprintf(yyout," %s=%04x\n",name,ch &0xffff); + } + else + { + fprintf(yyout," %s='%c'\n",name,ch); + } } #endif @@ -117,148 +117,148 @@ int nstr; extern int yyprevious; #ifdef YYDEBUG - fprintf(yyout,"yylex()\n"); + fprintf(yyout,"yylex()\n"); #endif - while((nstr = yylook()) >= 0) - { + while((nstr = yylook()) >= 0) + { #ifdef YYDEBUG - fprintf(yyout,"yylex: nstr=%d\n",nstr); + fprintf(yyout,"yylex: nstr=%d\n",nstr); #endif yyfussy: - switch(nstr) - { - case 0: - if(yywrap()) return(0); - break; - case 1: - return ID; - break; - case 2: - return CON; - break; - case 3: - ; - break; - case 4: - return yytext[0]; - break; - case -1: - break; - default: - fprintf(yyout,"yylex: bad switch yylook %d\n",nstr); - } + switch(nstr) + { + case 0: + if(yywrap()) return(0); + break; + case 1: + return ID; + break; + case 2: + return CON; + break; + case 3: + ; + break; + case 4: + return yytext[0]; + break; + case -1: + break; + default: + fprintf(yyout,"yylex: bad switch yylook %d\n",nstr); + } - } - + } + #ifdef YYDEBUG - fprintf(yyout,"yylex: return 0\n"); + fprintf(yyout,"yylex: return 0\n"); #endif - return(0); + return(0); } /* end of yylex */ int yyvstop[] = { - 0,4,0,3,4,0,2,4,0,1,4,0,2,0,1,0,0 + 0,4,0,3,4,0,2,4,0,1,4,0,2,0,1,0,0 }; # define YYTYPE char struct yywork { - YYTYPE verify, advance; + YYTYPE verify, advance; } yycrank[] = { - {0,0}, {0,0}, {1,3}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {1,4}, {1,3}, - {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {1,3}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {1,4}, {1,3}, + {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {1,5}, {5,7}, {5,7}, - {5,7}, {5,7}, {5,7}, {5,7}, - {5,7}, {5,7}, {5,7}, {5,7}, - {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {1,5}, {5,7}, {5,7}, + {5,7}, {5,7}, {5,7}, {5,7}, + {5,7}, {5,7}, {5,7}, {5,7}, + {0,0}, {0,0}, {0,0}, {0,0}, /* 0x40 */ - {0,0}, {0,0}, {1,6}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {1,6}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, + {0,0}, {0,0}, {0,0}, {0,0}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {0,0}, {0,0}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {0,0}, {0,0}, - {0,0}, {0,0}, {6,8}, {0,0}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, + {0,0}, {0,0}, {6,8}, {0,0}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, /* 0x80 */ - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {0,0}, {0,0}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {0,0}, {0,0}, #ifdef CHARSETHACK - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, /* 0xc0 */ - {0,0}, {0,0}, {1,6}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {1,6}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {0,0}, {0,0}, {0,0}, #endif - {0,0} + {0,0} }; /* struct yysvf { - struct yywork *yystoff; - struct yysvf *yyother; - int *yystops; + struct yywork *yystoff; + struct yysvf *yyother; + int *yystops; }; */ struct yysvf yysvec[] = { - {0, 0, 0}, - {yycrank+-1, 0, 0}, - {yycrank+0, yysvec+1, 0}, - {yycrank+0, 0, yyvstop+1}, - {yycrank+0, 0, yyvstop+3}, - {yycrank+2, 0, yyvstop+6}, - {yycrank+19, 0, yyvstop+9}, - {yycrank+0, yysvec+5, yyvstop+12}, - {yycrank+0, yysvec+6, yyvstop+14}, - {0, 0, 0} + {0, 0, 0}, + {yycrank+-1, 0, 0}, + {yycrank+0, yysvec+1, 0}, + {yycrank+0, 0, yyvstop+1}, + {yycrank+0, 0, yyvstop+3}, + {yycrank+2, 0, yyvstop+6}, + {yycrank+19, 0, yyvstop+9}, + {yycrank+0, yysvec+5, yyvstop+12}, + {yycrank+0, yysvec+6, yyvstop+14}, + {0, 0, 0} }; /* 0x8d */ /* struct yywork *yytop = yycrank+141; */ @@ -268,66 +268,66 @@ struct yywork *yytop = yycrank+255; struct yysvf *yybgin = yysvec+1; /* - WARNING: this table contains one entry per character - in the execution character set and must match it. + WARNING: this table contains one entry per character + in the execution character set and must match it. */ char yymatch[] = { - 00 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , + 00 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , #ifdef CHARSETHACK - 01 ,011 ,012 ,01 ,01 ,012 ,01 ,01 , + 01 ,011 ,012 ,01 ,01 ,012 ,01 ,01 , #else - 01 ,011 ,012 ,01 ,01 ,01 ,01 ,01 , + 01 ,011 ,012 ,01 ,01 ,01 ,01 ,01 , #endif - 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , - 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , + 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , + 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , - 011 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , - 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , + 011 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , + 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , - '0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' , - '0' ,'0' ,01 ,01 ,01 ,01 ,01 ,01 , + '0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' , + '0' ,'0' ,01 ,01 ,01 ,01 ,01 ,01 , /* 0x40 (ascii) @A... (petscii) @a... */ - 01 ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , - 'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , + 01 ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , + 'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , - 'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , - 'A' ,'A' ,'A' ,01 ,01 ,01 ,01 ,'A' , + 'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , + 'A' ,'A' ,'A' ,01 ,01 ,01 ,01 ,'A' , /* 0x60 (ascii) @a... */ - 01 ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , - 'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , + 01 ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , + 'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , - 'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , - 'A' ,'A' ,'A' ,01 ,01 ,01 ,01 ,01 , + 'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , + 'A' ,'A' ,'A' ,01 ,01 ,01 ,01 ,01 , #ifdef CHARSETHACK /* 0x80 */ - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0xc0 (petcii) @A... */ - 01 ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , - 'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , + 01 ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , + 'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , - 'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , - 'A' ,'A' ,'A' ,01 ,01 ,01 ,01 ,01 , + 'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , + 'A' ,'A' ,'A' ,01 ,01 ,01 ,01 ,01 , - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, #endif - 0 + 0 }; char yyextra[] = { - 0,0,0,0,0,0,0,0,0 + 0,0,0,0,0,0,0,0,0 }; -/* ncform 4.1 83/08/11 */ +/* ncform 4.1 83/08/11 */ int yylineno =1; # define YYU(x) x @@ -344,26 +344,26 @@ unsigned char testbreak=0; yylook() { - register struct yysvf *yystate, **lsp; - register struct yywork *yyt; - struct yysvf *yyz; - int yych; - struct yywork *yyr; + register struct yysvf *yystate, **lsp; + register struct yywork *yyt; + struct yysvf *yyz; + int yych; + struct yywork *yyr; /* # ifdef LEXDEBUG - int debug; + int debug; # endif */ - - char *yylastch; - - /* start off machines */ + + char *yylastch; + + /* start off machines */ /* # ifdef LEXDEBUG - debug = 1; + debug = 1; # else - debug = 0; + debug = 0; # endif */ @@ -372,298 +372,298 @@ yylook() # else #define debug 0 #endif - + #ifdef YYDEBUG - fprintf(yyout,"yylook()\n"); + fprintf(yyout,"yylook()\n"); # endif - - if (!yymorfg) - yylastch = yytext; - else - { - yymorfg=0; - yylastch = yytext+yyleng; - } + + if (!yymorfg) + yylastch = yytext; + else + { + yymorfg=0; + yylastch = yytext+yyleng; + } #ifdef YYDEBUG - fprintf(yyout,"yylook: yymorfg=%d\n",yymorfg); + fprintf(yyout,"yylook: yymorfg=%d\n",yymorfg); # endif - - for(;;) - { + + for(;;) + { #ifdef YYDEBUG - fprintf(yyout,"yylook: (outer loop)"); - printchar("yyprevious",yyprevious); + fprintf(yyout,"yylook: (outer loop)"); + printchar("yyprevious",yyprevious); # endif - lsp = yylstate; - yyestate = yystate = yybgin; - if (yyprevious==YYNEWLINE) yystate++; + lsp = yylstate; + yyestate = yystate = yybgin; + if (yyprevious==YYNEWLINE) yystate++; - testbreak=0; - - for (;;) - { + testbreak=0; + + for (;;) + { # ifdef LEXDEBUG - fprintf(yyout,"yylook: (inner loop) state %d\n",yystate-yysvec-1); + fprintf(yyout,"yylook: (inner loop) state %d\n",yystate-yysvec-1); # endif - if(testbreak==5) - { - fprintf(yyout,"yylook: error, aborted after 5 loops\n"); - exit(0); - } - testbreak++; - - yyt = yystate->yystoff; + if(testbreak==5) + { + fprintf(yyout,"yylook: error, aborted after 5 loops\n"); + exit(0); + } + testbreak++; + + yyt = yystate->yystoff; -/* fprintf(yyout,"yylook: yyt offs: %02x\n",yyt-yycrank); */ +/* fprintf(yyout,"yylook: yyt offs: %02x\n",yyt-yycrank); */ - - if(yyt == yycrank) - { /* may not be any transitions */ - yyz = yystate->yyother; - if(yyz == 0)break; - if(yyz->yystoff == yycrank)break; - } - *yylastch++ = yych = input(); + + if(yyt == yycrank) + { /* may not be any transitions */ + yyz = yystate->yyother; + if(yyz == 0)break; + if(yyz->yystoff == yycrank)break; + } + *yylastch++ = yych = input(); # ifdef LEXDEBUG - fprintf(yyout,"yylook: input "); - printchar("yych",yych); + fprintf(yyout,"yylook: input "); + printchar("yych",yych); # endif - - tryagain: + + tryagain: # ifdef LEXDEBUG -/* fprintf(yyout,"yylook: yych=%02x yymatch[yych]=%02x\n",yych,yymatch[yych]); */ - fprintf(yyout,"yylook: tryagain\n"); +/* fprintf(yyout,"yylook: yych=%02x yymatch[yych]=%02x\n",yych,yymatch[yych]); */ + fprintf(yyout,"yylook: tryagain\n"); # endif - yyr = yyt; + yyr = yyt; -/* fprintf(yyout,"yylook: yyr offs: %02x\n",yyr-yycrank); */ - - if ( yyt > yycrank) - { - yyt = yyr + yych; - if (yyt <= yytop && yyt->verify+yysvec == yystate) - { - if(yyt->advance+yysvec == YYLERR) /* error transitions */ - { +/* fprintf(yyout,"yylook: yyr offs: %02x\n",yyr-yycrank); */ + + if ( yyt > yycrank) + { + yyt = yyr + yych; + if (yyt <= yytop && yyt->verify+yysvec == yystate) + { + if(yyt->advance+yysvec == YYLERR) /* error transitions */ + { # ifdef LEXDEBUG - fprintf(yyout,"yylook: unput (1) "); - printchar("*yylastch",*yylastch); + fprintf(yyout,"yylook: unput (1) "); + printchar("*yylastch",*yylastch); # endif - unput(*--yylastch); - break; - } - *lsp++ = yystate = yyt->advance+yysvec; + unput(*--yylastch); + break; + } + *lsp++ = yystate = yyt->advance+yysvec; # ifdef LEXDEBUG - fprintf(yyout,"yylook: continue (1)\n"); + fprintf(yyout,"yylook: continue (1)\n"); # endif - goto contin; - } + goto contin; + } # ifdef LEXDEBUG - fprintf(yyout,"yylook: ( yyt > yycrank)\n"); + fprintf(yyout,"yylook: ( yyt > yycrank)\n"); # endif - } + } # ifdef YYOPTIM - else if(yyt < yycrank) /* r < yycrank */ - { - yyt = yyr = yycrank+(yycrank-yyt); + else if(yyt < yycrank) /* r < yycrank */ + { + yyt = yyr = yycrank+(yycrank-yyt); # ifdef LEXDEBUG - fprintf(yyout,"yylook: compressed state\n"); + fprintf(yyout,"yylook: compressed state\n"); # endif - yyt = yyt + yych; - if(yyt <= yytop && yyt->verify+yysvec == yystate) - { + yyt = yyt + yych; + if(yyt <= yytop && yyt->verify+yysvec == yystate) + { # ifdef LEXDEBUG - fprintf(yyout,"yylook: (1)\n"); + fprintf(yyout,"yylook: (1)\n"); # endif - if(yyt->advance+yysvec == YYLERR) /* error transitions */ - { + if(yyt->advance+yysvec == YYLERR) /* error transitions */ + { # ifdef LEXDEBUG - fprintf(yyout,"yylook: unput (2) "); - printchar("*yylastch",*yylastch); + fprintf(yyout,"yylook: unput (2) "); + printchar("*yylastch",*yylastch); # endif - unput(*--yylastch); - break; - } - *lsp++ = yystate = yyt->advance+yysvec; + unput(*--yylastch); + break; + } + *lsp++ = yystate = yyt->advance+yysvec; # ifdef LEXDEBUG - fprintf(yyout,"yylook: continue (2)\n"); + fprintf(yyout,"yylook: continue (2)\n"); # endif - goto contin; - - } + goto contin; + + } # ifdef LEXDEBUG /* - fprintf(yyout,"yylook: yych=%02x yymatch[yych]=%02x\n",yych,yymatch[yych]); - fprintf(yyout,"yylook: yyt offs: %02x\n",yyt-yycrank); - fprintf(yyout,"yylook: yyr offs: %02x\n",yyr-yycrank); + fprintf(yyout,"yylook: yych=%02x yymatch[yych]=%02x\n",yych,yymatch[yych]); + fprintf(yyout,"yylook: yyt offs: %02x\n",yyt-yycrank); + fprintf(yyout,"yylook: yyr offs: %02x\n",yyr-yycrank); */ # endif - yyt = yyr + YYU(yymatch[yych]); + yyt = yyr + YYU(yymatch[yych]); # ifdef LEXDEBUG /* - fprintf(yyout,"yylook: yyt offs: %02x <= yytop offs: %02x\n",yyt-yycrank,yytop-yycrank); - fprintf(yyout,"yylook: yyt->verify=%04x yysvec=%04x (yyt->verify+yysvec)=%04x == yystate=%04x\n",yyt->verify,yysvec,(yyt->verify+yysvec),yystate); + fprintf(yyout,"yylook: yyt offs: %02x <= yytop offs: %02x\n",yyt-yycrank,yytop-yycrank); + fprintf(yyout,"yylook: yyt->verify=%04x yysvec=%04x (yyt->verify+yysvec)=%04x == yystate=%04x\n",yyt->verify,yysvec,(yyt->verify+yysvec),yystate); */ - fprintf(yyout,"yylook: try fall back character\n"); + fprintf(yyout,"yylook: try fall back character\n"); # endif - if(yyt <= yytop && yyt->verify+yysvec == yystate) - { + if(yyt <= yytop && yyt->verify+yysvec == yystate) + { # ifdef LEXDEBUG - fprintf(yyout,"yylook: (2a)\n"); + fprintf(yyout,"yylook: (2a)\n"); # endif - - if(yyt->advance+yysvec == YYLERR) /* error transition */ - { + + if(yyt->advance+yysvec == YYLERR) /* error transition */ + { # ifdef LEXDEBUG -/* cc65 compiles this ?! fprintf(yyout,"yylook: unput (3) ",); */ - fprintf(yyout,"yylook: unput (3) "); - printchar("*yylastch",*yylastch); +/* cc65 compiles this ?! fprintf(yyout,"yylook: unput (3) ",); */ + fprintf(yyout,"yylook: unput (3) "); + printchar("*yylastch",*yylastch); # endif - unput(*--yylastch); - break; - } - *lsp++ = yystate = yyt->advance+yysvec; + unput(*--yylastch); + break; + } + *lsp++ = yystate = yyt->advance+yysvec; # ifdef LEXDEBUG -/* fprintf(yyout,"yylook: yyt offs: %02x yyt->advance=%d\n",yyt-yycrank,yyt->advance); */ - fprintf(yyout,"yylook: continue (3)\n"); +/* fprintf(yyout,"yylook: yyt offs: %02x yyt->advance=%d\n",yyt-yycrank,yyt->advance); */ + fprintf(yyout,"yylook: continue (3)\n"); # endif - goto contin; - - } + goto contin; + + } # ifdef LEXDEBUG - fprintf(yyout,"yylook: (2)\n"); + fprintf(yyout,"yylook: (2)\n"); # endif - } - if ((yystate = yystate->yyother) && (yyt= yystate->yystoff) != yycrank) - { + } + if ((yystate = yystate->yyother) && (yyt= yystate->yystoff) != yycrank) + { # ifdef LEXDEBUG - fprintf(yyout,"yylook: fall back to state %d\n",yystate-yysvec-1); + fprintf(yyout,"yylook: fall back to state %d\n",yystate-yysvec-1); # endif - goto tryagain; - } + goto tryagain; + } # endif - else - { + else + { # ifdef LEXDEBUG - fprintf(yyout,"yylook: unput (4) "); - printchar("*yylastch",*yylastch); + fprintf(yyout,"yylook: unput (4) "); + printchar("*yylastch",*yylastch); # endif - unput(*--yylastch); - break; - } - contin: + unput(*--yylastch); + break; + } + contin: # ifdef LEXDEBUG - fprintf(yyout,"yylook: contin state=%d\n",yystate-yysvec-1); + fprintf(yyout,"yylook: contin state=%d\n",yystate-yysvec-1); # endif - ; - } + ; + } # ifdef LEXDEBUG - if (lsp == yylstate) - { - fprintf(yyout,"yylook: stopped (end)\n"); - } - else - { - fprintf(yyout,"yylook: stopped at %d with:\n",*(lsp-1)-(yysvec+1)); - } + if (lsp == yylstate) + { + fprintf(yyout,"yylook: stopped (end)\n"); + } + else + { + fprintf(yyout,"yylook: stopped at %d with:\n",*(lsp-1)-(yysvec+1)); + } # endif - while (lsp-- > yylstate) - { - *yylastch-- = 0; - if (*lsp != 0 && (yyfnd= (*lsp)->yystops) && *yyfnd > 0) - { - yyolsp = lsp; - if(yyextra[*yyfnd]) /* must backup */ - { - while(yyback((*lsp)->yystops,-*yyfnd) != 1 && lsp > yylstate) - { - lsp--; + while (lsp-- > yylstate) + { + *yylastch-- = 0; + if (*lsp != 0 && (yyfnd= (*lsp)->yystops) && *yyfnd > 0) + { + yyolsp = lsp; + if(yyextra[*yyfnd]) /* must backup */ + { + while(yyback((*lsp)->yystops,-*yyfnd) != 1 && lsp > yylstate) + { + lsp--; # ifdef LEXDEBUG - fprintf(yyout,"yylook: unput (5) "); - printchar("*yylastch",*yylastch); + fprintf(yyout,"yylook: unput (5) "); + printchar("*yylastch",*yylastch); # endif - unput(*yylastch--); - } - } - yyprevious = YYU(*yylastch); - yylsp = lsp; - yyleng = yylastch-yytext+1; - yytext[yyleng] = 0; + unput(*yylastch--); + } + } + yyprevious = YYU(*yylastch); + yylsp = lsp; + yyleng = yylastch-yytext+1; + yytext[yyleng] = 0; # ifdef LEXDEBUG - fprintf(yyout,"yylook: match action %d\n",*yyfnd); - fprintf(yyout,"yylook: done loops: %d\n",testbreak); + fprintf(yyout,"yylook: match action %d\n",*yyfnd); + fprintf(yyout,"yylook: done loops: %d\n",testbreak); # endif - return(*yyfnd++); - } - unput(*yylastch); - } - if (yytext[0] == 0 /* && feof(yyin) */) - { - yysptr=yysbuf; + return(*yyfnd++); + } + unput(*yylastch); + } + if (yytext[0] == 0 /* && feof(yyin) */) + { + yysptr=yysbuf; # ifdef LEXDEBUG - fprintf(yyout,"yylook: done loops: %d\n",testbreak); + fprintf(yyout,"yylook: done loops: %d\n",testbreak); # endif - return(0); - } - yyprevious = yytext[0] = input(); + return(0); + } + yyprevious = yytext[0] = input(); # ifdef LEXDEBUG - fprintf(yyout,"yylook: input "); - printchar("yyprevious",yyprevious); + fprintf(yyout,"yylook: input "); + printchar("yyprevious",yyprevious); # endif - if (yyprevious>0) - output(yyprevious); - yylastch=yytext; + if (yyprevious>0) + output(yyprevious); + yylastch=yytext; # ifdef LEXDEBUG -/* if(debug)putchar('\n'); */ +/* if(debug)putchar('\n'); */ # endif - } + } # ifdef LEXDEBUG - fprintf(yyout,"yylook: done loops: %d\n",testbreak); - fprintf(yyout,"yylook: return <void>\n"); + fprintf(yyout,"yylook: done loops: %d\n",testbreak); + fprintf(yyout,"yylook: return <void>\n"); # endif } - + yyback(p, m) - int *p; + int *p; { - if (p==0) return(0); - while (*p) - { - if (*p++ == m) - { - return(1); - } - } - return(0); + if (p==0) return(0); + while (*p) + { + if (*p++ == m) + { + return(1); + } + } + return(0); } - /* the following are only used in the lex library */ + /* the following are only used in the lex library */ yyinput() { - int out=input(); - + int out=input(); + #ifdef YYDEBUG - fprintf(yyout,"yylook: input "); - printchar("out",out); -#endif - return(out); + fprintf(yyout,"yylook: input "); + printchar("out",out); +#endif + return(out); } yyoutput(c) int c; { - output(c); + output(c); } yyunput(c) int c; { - unput(c); + unput(c); } main() @@ -689,8 +689,8 @@ char *s; short yyexca[] = { -1, 1, - 0, -1, - -2, 0, + 0, -1, + -2, 0, }; # define YYNPROD 15 @@ -762,7 +762,7 @@ short yydef[]= # define YYACCEPT return(0) # define YYABORT return(1) -/* parser for yacc output */ +/* parser for yacc output */ #ifdef YYDEBUG int yydebug = 1; /* 1 for debugging */ @@ -776,231 +776,231 @@ short yyerrflag = 0; /* error recovery flag */ yyparse() { - short yys[YYMAXDEPTH]; - short yyj, yym; - register YYSTYPE *yypvt; - register short yystate, *yyps, yyn; - register YYSTYPE *yypv; - register short *yyxi; + short yys[YYMAXDEPTH]; + short yyj, yym; + register YYSTYPE *yypvt; + register short yystate, *yyps, yyn; + register YYSTYPE *yypv; + register short *yyxi; - yystate = 0; - yychar = -1; - yynerrs = 0; - yyerrflag = 0; - yyps= &yys[-1]; - yypv= &yyv[-1]; + yystate = 0; + yychar = -1; + yynerrs = 0; + yyerrflag = 0; + yyps= &yys[-1]; + yypv= &yyv[-1]; yystack: /* put a state and value onto the stack */ #ifdef YYDEBUG - printf("yyparse: yystack\n"); + printf("yyparse: yystack\n"); #endif #ifdef YYDEBUG - printf("yyparse: yystate=%d, ", yystate); - printchar("yychar",yychar); + printf("yyparse: yystate=%d, ", yystate); + printchar("yychar",yychar); #endif - if( ++yyps> &yys[YYMAXDEPTH] ) - { - yyerror( "yyparse: yacc stack overflow" ); - return(1); - } - *yyps = yystate; - ++yypv; - *yypv = yyval; + if( ++yyps> &yys[YYMAXDEPTH] ) + { + yyerror( "yyparse: yacc stack overflow" ); + return(1); + } + *yyps = yystate; + ++yypv; + *yypv = yyval; yynewstate: #ifdef YYDEBUG - printf("yyparse: yynewstate\n"); + printf("yyparse: yynewstate\n"); #endif - yyn = yypact[yystate]; + yyn = yypact[yystate]; - if( yyn<= YYFLAG ) goto yydefault; /* simple state */ + if( yyn<= YYFLAG ) goto yydefault; /* simple state */ #ifdef YYDEBUG - printf("yyparse: yynewstate (1)\n"); + printf("yyparse: yynewstate (1)\n"); #endif - - if( yychar<0 ) if( (yychar=yylex())<0 ) yychar=0; + + if( yychar<0 ) if( (yychar=yylex())<0 ) yychar=0; #ifdef YYDEBUG - - printf("yyparse: yynewstate yyn=%d ",yyn); - printchar("yychar",yychar); + + printf("yyparse: yynewstate yyn=%d ",yyn); + printchar("yychar",yychar); #endif - - if( (yyn += yychar)<0 || yyn >= YYLAST ) goto yydefault; + + if( (yyn += yychar)<0 || yyn >= YYLAST ) goto yydefault; #ifdef YYDEBUG - printf("yyparse: yynewstate (2)\n"); + printf("yyparse: yynewstate (2)\n"); #endif - - if( yychk[ yyn=yyact[ yyn ] ] == yychar ) /* valid shift */ - { - yychar = -1; - yyval = yylval; - yystate = yyn; + + if( yychk[ yyn=yyact[ yyn ] ] == yychar ) /* valid shift */ + { + yychar = -1; + yyval = yylval; + yystate = yyn; #ifdef YYDEBUG - printf("yyparse: yynewstate (3)\n"); + printf("yyparse: yynewstate (3)\n"); #endif - if( yyerrflag > 0 ) --yyerrflag; - goto yystack; - } + if( yyerrflag > 0 ) --yyerrflag; + goto yystack; + } yydefault: #ifdef YYDEBUG - printf("yyparse: yydefault yystate=%d\n",yystate); + printf("yyparse: yydefault yystate=%d\n",yystate); #endif - /* default state action */ + /* default state action */ - if( (yyn=yydef[yystate]) == -2 ) - { - if( yychar<0 ) if( (yychar=yylex())<0 ) yychar = 0; - /* look through exception table */ + if( (yyn=yydef[yystate]) == -2 ) + { + if( yychar<0 ) if( (yychar=yylex())<0 ) yychar = 0; + /* look through exception table */ - for( yyxi=yyexca; (*yyxi!= (-1)) || (yyxi[1]!=yystate) ; yyxi += 2 ) ; /* VOID */ + for( yyxi=yyexca; (*yyxi!= (-1)) || (yyxi[1]!=yystate) ; yyxi += 2 ) ; /* VOID */ - while( *(yyxi+=2) >= 0 ) - { - if( *yyxi == yychar ) break; - } - if( (yyn = yyxi[1]) < 0 ) return(0); /* accept */ - } + while( *(yyxi+=2) >= 0 ) + { + if( *yyxi == yychar ) break; + } + if( (yyn = yyxi[1]) < 0 ) return(0); /* accept */ + } #ifdef YYDEBUG - printf("yyparse: yyn=%d yyerrflag=%d\n",yyn,yyerrflag); + printf("yyparse: yyn=%d yyerrflag=%d\n",yyn,yyerrflag); #endif - - if( yyn == 0 ) /* error */ - { - /* error ... attempt to resume parsing */ + + if( yyn == 0 ) /* error */ + { + /* error ... attempt to resume parsing */ - switch( yyerrflag ){ - case 0: /* brand new error */ + switch( yyerrflag ){ + case 0: /* brand new error */ - yyerror( "yyparse: syntax error" ); - yyerrlab: - ++yynerrs; + yyerror( "yyparse: syntax error" ); + yyerrlab: + ++yynerrs; - case 1: - case 2: /* incompletely recovered error ... try again */ + case 1: + case 2: /* incompletely recovered error ... try again */ - yyerrflag = 3; + yyerrflag = 3; - /* find a state where "error" is a legal shift action */ + /* find a state where "error" is a legal shift action */ - while ( yyps >= yys ) { - yyn = yypact[*yyps] + YYERRCODE; - if( yyn>= 0 && yyn < YYLAST && yychk[yyact[yyn]] == YYERRCODE ){ - yystate = yyact[yyn]; /* simulate a shift of "error" */ - goto yystack; - } - yyn = yypact[*yyps]; + while ( yyps >= yys ) { + yyn = yypact[*yyps] + YYERRCODE; + if( yyn>= 0 && yyn < YYLAST && yychk[yyact[yyn]] == YYERRCODE ){ + yystate = yyact[yyn]; /* simulate a shift of "error" */ + goto yystack; + } + yyn = yypact[*yyps]; - /* the current yyps has no shift onn "error", pop stack */ + /* the current yyps has no shift onn "error", pop stack */ #ifdef YYDEBUG - printf("yyparse: error recovery pops state %d, uncovers %d\n", *yyps, yyps[-1] ); + printf("yyparse: error recovery pops state %d, uncovers %d\n", *yyps, yyps[-1] ); #endif - --yyps; - --yypv; - } + --yyps; + --yypv; + } - /* there is no state on the stack with an error shift ... abort */ + /* there is no state on the stack with an error shift ... abort */ - yyabort: - return(1); + yyabort: + return(1); - case 3: /* no shift yet; clobber input char */ + case 3: /* no shift yet; clobber input char */ #ifdef YYDEBUG - printf("yyparse: error recovery discards char "); - printchar("yychar",yychar); + printf("yyparse: error recovery discards char "); + printchar("yychar",yychar); #endif - if( yychar == 0 ) goto yyabort; /* don't discard EOF, quit */ - yychar = -1; - goto yynewstate; /* try again in the same state */ + if( yychar == 0 ) goto yyabort; /* don't discard EOF, quit */ + yychar = -1; + goto yynewstate; /* try again in the same state */ - } + } - } + } - /* reduction by production yyn */ + /* reduction by production yyn */ #ifdef YYDEBUG - printf("yyparse: reduce %d\n",yyn); + printf("yyparse: reduce %d\n",yyn); #endif - yyps -= yyr2[yyn]; - yypvt = yypv; - yypv -= yyr2[yyn]; - yyval = yypv[1]; - yym=yyn; - /* consult goto table to find next state */ - yyn = yyr1[yyn]; - yyj = yypgo[yyn] + *yyps + 1; - if( yyj>=YYLAST || yychk[ yystate = yyact[yyj] ] != -yyn ) yystate = yyact[yypgo[yyn]]; - - switch(yym) - { - case 4: - { - yyerrok; - } - break; - case 5: - { - printf("[STORE]\n"); - } - break; - case 6: - { - printf("[ADD]\n"); - } - break; - case 7: - { - printf("[NEG]\n[ADD]\n"); - } - break; - case 8: - { - printf("[MUL]\n"); - } - break; - case 9: - { - printf("[DIV]\n"); - } - break; - case 10: - { - printf("[NEG]\n"); - } - break; - case 12: - { - printf("[LOAD]\n"); - } - break; - case 13: - { - printf("[PUSH %s]\n", yytext); - } - break; - case 14: - { - printf("[%s]\n", yytext); - } - break; - } - - goto yystack; /* stack new state and value */ + yyps -= yyr2[yyn]; + yypvt = yypv; + yypv -= yyr2[yyn]; + yyval = yypv[1]; + yym=yyn; + /* consult goto table to find next state */ + yyn = yyr1[yyn]; + yyj = yypgo[yyn] + *yyps + 1; + if( yyj>=YYLAST || yychk[ yystate = yyact[yyj] ] != -yyn ) yystate = yyact[yypgo[yyn]]; + + switch(yym) + { + case 4: + { + yyerrok; + } + break; + case 5: + { + printf("[STORE]\n"); + } + break; + case 6: + { + printf("[ADD]\n"); + } + break; + case 7: + { + printf("[NEG]\n[ADD]\n"); + } + break; + case 8: + { + printf("[MUL]\n"); + } + break; + case 9: + { + printf("[DIV]\n"); + } + break; + case 10: + { + printf("[NEG]\n"); + } + break; + case 12: + { + printf("[LOAD]\n"); + } + break; + case 13: + { + printf("[PUSH %s]\n", yytext); + } + break; + case 14: + { + printf("[%s]\n", yytext); + } + break; + } + + goto yystack; /* stack new state and value */ } - + int yywrap() { - return 1; + return 1; } diff --git a/test/ref/yacc2.c b/test/ref/yacc2.c index 78d654ded..3b4819c55 100644 --- a/test/ref/yacc2.c +++ b/test/ref/yacc2.c @@ -10,105 +10,105 @@ # define YYTYPE char struct yywork { - YYTYPE verify, advance; + YYTYPE verify, advance; } yycrank[] = { - {0,0}, {0,0}, {1,3}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {1,4}, {1,3}, - {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {1,3}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {1,4}, {1,3}, + {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {1,5}, {5,7}, {5,7}, - {5,7}, {5,7}, {5,7}, {5,7}, - {5,7}, {5,7}, {5,7}, {5,7}, - {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {1,5}, {5,7}, {5,7}, + {5,7}, {5,7}, {5,7}, {5,7}, + {5,7}, {5,7}, {5,7}, {5,7}, + {0,0}, {0,0}, {0,0}, {0,0}, /* 0x40 */ - {0,0}, {0,0}, {1,6}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {1,6}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, + {0,0}, {0,0}, {0,0}, {0,0}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {0,0}, {0,0}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {0,0}, {0,0}, - {0,0}, {0,0}, {6,8}, {0,0}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, + {0,0}, {0,0}, {6,8}, {0,0}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, /* 0x80 */ - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {0,0}, {0,0}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {0,0}, {0,0}, #ifdef CHARSETHACK - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, /* 0xc0 */ - {0,0}, {0,0}, {1,6}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {6,8}, {6,8}, {6,8}, - {6,8}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {1,6}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {6,8}, {6,8}, {6,8}, + {6,8}, {0,0}, {0,0}, {0,0}, #endif - {0,0} + {0,0} }; struct yywork *yytop = yycrank+255; int yyvstop[] = { - 0,4,0,3,4,0,2,4,0,1,4,0,2,0,1,0,0 + 0,4,0,3,4,0,2,4,0,1,4,0,2,0,1,0,0 }; struct yysvf { - struct yywork *yystoff; - struct yysvf *yyother; - int *yystops; + struct yywork *yystoff; + struct yysvf *yyother; + int *yystops; }; struct yysvf yysvec[] = { - {0, 0, 0}, - {yycrank+-1, 0, 0}, - {yycrank+0, yysvec+1, 0}, - {yycrank+0, 0, yyvstop+1}, - {yycrank+0, 0, yyvstop+3}, - {yycrank+2, 0, yyvstop+6}, - {yycrank+19, 0, yyvstop+9}, - {yycrank+0, yysvec+5, yyvstop+12}, - {yycrank+0, yysvec+6, yyvstop+14}, - {0, 0, 0} + {0, 0, 0}, + {yycrank+-1, 0, 0}, + {yycrank+0, yysvec+1, 0}, + {yycrank+0, 0, yyvstop+1}, + {yycrank+0, 0, yyvstop+3}, + {yycrank+2, 0, yyvstop+6}, + {yycrank+19, 0, yyvstop+9}, + {yycrank+0, yysvec+5, yyvstop+12}, + {yycrank+0, yysvec+6, yyvstop+14}, + {0, 0, 0} }; #if 0 @@ -116,7 +116,7 @@ struct yysvf yysvec[] = // *yylastch++ = yych = input(); void subtest1(void) { - *yylastch++ = yych = input(); + *yylastch++ = yych = input(); } #endif @@ -125,26 +125,26 @@ static int bog=1234; #if 0 void bogus(void) { - bog*=0x1234; + bog*=0x1234; } #else -#define bogus() bog+=0x1234 +#define bogus() bog+=0x1234 #endif #if 1 // yyt = yyt + yych; void subtest2(void) { - register struct yywork *yyt; - int yych; + register struct yywork *yyt; + int yych; - yyt=yycrank; - yych=10; + yyt=yycrank; + yych=10; - bogus(); - yyt = yyt + yych; + bogus(); + yyt = yyt + yych; - printf("yyt: %d %d\n",yyt->verify,yyt->advance); + printf("yyt: %d %d\n",yyt->verify,yyt->advance); } #endif @@ -152,21 +152,21 @@ void subtest2(void) // if(yyt <= yytop && yyt->verify+yysvec == yystate) void subtest3(void) { - register struct yywork *yyt; - register struct yysvf *yystate; + register struct yywork *yyt; + register struct yysvf *yystate; - yyt=yycrank; - yystate=yysvec; - - bogus(); - if(yyt <= yytop && yyt->verify+yysvec == yystate) - { - printf("if ok %d %d\n",yyt->verify,yyt->advance); - } - else - { - printf("if not ok %d %d\n",yyt->verify,yyt->advance); - } + yyt=yycrank; + yystate=yysvec; + + bogus(); + if(yyt <= yytop && yyt->verify+yysvec == yystate) + { + printf("if ok %d %d\n",yyt->verify,yyt->advance); + } + else + { + printf("if not ok %d %d\n",yyt->verify,yyt->advance); + } } #endif @@ -179,19 +179,19 @@ short yyr2[]= // yyps -= yyr2[yyn]; void subtest4(void) { - register short *yyps, yyn; + register short *yyps, yyn; - yyps=0x8004; - yyn=0; + yyps=0x8004; + yyn=0; - while(yyn<14) - { - bogus(); - yyps -= yyr2[yyn]; + while(yyn<14) + { + bogus(); + yyps -= yyr2[yyn]; - yyn++; - } - printf("yyps: %04x\n",yyps); + yyn++; + } + printf("yyps: %04x\n",yyps); } #if 1 @@ -199,21 +199,21 @@ void subtest4(void) int yylookret=10; yylook() { - yylookret--; - return yylookret; + yylookret--; + return yylookret; } // while((nstr = yylook()) >= 0) void subtest5(void) { - int nstr; + int nstr; - bogus(); - while((nstr = yylook()) >= 0) - { - printf("nstr: %04x\n",nstr); - bogus(); - } + bogus(); + while((nstr = yylook()) >= 0) + { + printf("nstr: %04x\n",nstr); + bogus(); + } } #endif diff --git a/test/val/compare5.c b/test/val/compare5.c index 9e0c97a63..f1d94d537 100644 --- a/test/val/compare5.c +++ b/test/val/compare5.c @@ -288,17 +288,17 @@ void c_minus1(void) printf("(long0 != -1)\n"); if(long0 != -1) { - failures++; + failures++; } printf("(long0 > 0)\n"); if(long0 > 0) { - failures++; + failures++; } printf("(long1 < 0)\n"); if(long1 < 0) { - failures++; + failures++; } /* if(long1 < 2) diff --git a/test/val/cq22.c b/test/val/cq22.c index bcd1570c8..015b7bf77 100644 --- a/test/val/cq22.c +++ b/test/val/cq22.c @@ -101,9 +101,9 @@ int s22(struct defs *pd0) #define cq_sections 1 #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s22(pd0); @@ -125,7 +125,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq241.c b/test/val/cq241.c index 76f437e0c..1f66a378c 100644 --- a/test/val/cq241.c +++ b/test/val/cq241.c @@ -243,9 +243,9 @@ int s241(struct defs *pd0) { #define cq_sections 1 #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s241(pd0); @@ -267,7 +267,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq243.c b/test/val/cq243.c index 676c73182..aaec9a8ea 100644 --- a/test/val/cq243.c +++ b/test/val/cq243.c @@ -176,21 +176,21 @@ int s243(struct defs *pd0) { by a more failproof version if( - '\0' != 0 || - '\01' != 1 || - '\02' != 2 || - '\03' != 3 || - '\04' != 4 || - '\05' != 5 || - '\06' != 6 || - '\07' != 7 || - '\10' != 8 || - '\17' != 15 || - '\20' != 16 || - '\77' != 63 || - '\100' != 64 || - '\177' != 127 - ) + '\0' != 0 || + '\01' != 1 || + '\02' != 2 || + '\03' != 3 || + '\04' != 4 || + '\05' != 5 || + '\06' != 6 || + '\07' != 7 || + '\10' != 8 || + '\17' != 15 || + '\20' != 16 || + '\77' != 63 || + '\100' != 64 || + '\177' != 127 + ) */ if( ('0' != '\60') || @@ -201,7 +201,7 @@ int s243(struct defs *pd0) { ('z' != '\172') ) - { + { rc = rc+8; if(pd0->flgd != 0) { @@ -221,9 +221,9 @@ int s243(struct defs *pd0) { #define cq_sections 1 #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s243(pd0); @@ -245,7 +245,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq244.c b/test/val/cq244.c index bedf51e95..9f4704f36 100644 --- a/test/val/cq244.c +++ b/test/val/cq244.c @@ -116,9 +116,9 @@ s244(struct defs *pd0) { #define cq_sections 1 #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s244(pd0); @@ -140,7 +140,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq25.c b/test/val/cq25.c index 9cb2f61c8..bfdade957 100644 --- a/test/val/cq25.c +++ b/test/val/cq25.c @@ -128,9 +128,9 @@ int s25(struct defs *pd0) { #define cq_sections 1 #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s25(pd0); @@ -152,7 +152,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq26.c b/test/val/cq26.c index 399f0a45e..239411f1c 100644 --- a/test/val/cq26.c +++ b/test/val/cq26.c @@ -171,9 +171,9 @@ s26(struct defs *pd0) { *********************************************************************************************/ #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s26(pd0); @@ -197,7 +197,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq4.c b/test/val/cq4.c index 8a8125c52..a8b6b1d52 100644 --- a/test/val/cq4.c +++ b/test/val/cq4.c @@ -317,9 +317,9 @@ setev(){ *********************************************************************************************/ #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s26(pd0); @@ -344,7 +344,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq61.c b/test/val/cq61.c index 3dcca6454..fc4d1d95f 100644 --- a/test/val/cq61.c +++ b/test/val/cq61.c @@ -140,9 +140,9 @@ simply discarded. */ *********************************************************************************************/ #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ /*case 0: return s26(pd0);*/ @@ -167,7 +167,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq626.c b/test/val/cq626.c index 166d3a95b..a8b05c8f2 100644 --- a/test/val/cq626.c +++ b/test/val/cq626.c @@ -291,9 +291,9 @@ int s626(struct defs *pd0){ *********************************************************************************************/ #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s26(pd0); @@ -318,7 +318,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq71.c b/test/val/cq71.c index 7bf0d9e1e..f7167c728 100644 --- a/test/val/cq71.c +++ b/test/val/cq71.c @@ -194,9 +194,9 @@ int *********************************************************************************************/ #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ /*case 0: return s26(pd0);*/ @@ -221,7 +221,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq714.c b/test/val/cq714.c index f4c58801f..d7a878033 100644 --- a/test/val/cq714.c +++ b/test/val/cq714.c @@ -1507,175 +1507,175 @@ initial (5,2) | (5,2) | (12,10) } #ifdef NO_FLOATS - fl = 5; cr = 2; - fl /= cr; - if(fl != 2){ - lrc = 232; - if(prlc) printf(f,lrc); - } - fl = 5; sr = 2; - fl /= sr; - if(fl != 2){ - lrc = 233; - if(prlc) printf(f,lrc); - } - fl = 5; ir = 2; - fl /= ir; - if(fl != 2){ - lrc = 234; - if(prlc) printf(f,lrc); - } - fl = 5; lr = 2; - fl /= lr; - if(fl != 2){ - lrc = 235; - if(prlc) printf(f,lrc); - } - fl = 5; ur = 2; - fl /= ur; - if(fl != 2){ - lrc = 236; - if(prlc) printf(f,lrc); - } - fl = 5; fr = 2; - fl /= fr; - if(fl != 2){ - lrc = 237; - if(prlc) printf(f,lrc); - } - fl = 5; dr = 2; - fl /= dr; - if(fl != 2){ - lrc = 238; - if(prlc) printf(f,lrc); - } - dl = 5; cr = 2; - dl /= cr; - if(dl != 2){ - lrc = 239; - if(prlc) printf(f,lrc); - } - dl = 5; sr = 2; - dl /= sr; - if(dl != 2){ - lrc = 240; - if(prlc) printf(f,lrc); - } - dl = 5; ir = 2; - dl /= ir; - if(dl != 2){ - lrc = 241; - if(prlc) printf(f,lrc); - } - dl = 5; lr = 2; - dl /= lr; - if(dl != 2){ - lrc = 242; - if(prlc) printf(f,lrc); - } - dl = 5; ur = 2; - dl /= ur; - if(dl != 2){ - lrc = 243; - if(prlc) printf(f,lrc); - } - dl = 5; fr = 2; - dl /= fr; - if(dl != 2){ - lrc = 244; - if(prlc) printf(f,lrc); - } - dl = 5; dr = 2; - dl /= dr; - if(dl != 2){ - lrc = 245; - if(prlc) printf(f,lrc); - } + fl = 5; cr = 2; + fl /= cr; + if(fl != 2){ + lrc = 232; + if(prlc) printf(f,lrc); + } + fl = 5; sr = 2; + fl /= sr; + if(fl != 2){ + lrc = 233; + if(prlc) printf(f,lrc); + } + fl = 5; ir = 2; + fl /= ir; + if(fl != 2){ + lrc = 234; + if(prlc) printf(f,lrc); + } + fl = 5; lr = 2; + fl /= lr; + if(fl != 2){ + lrc = 235; + if(prlc) printf(f,lrc); + } + fl = 5; ur = 2; + fl /= ur; + if(fl != 2){ + lrc = 236; + if(prlc) printf(f,lrc); + } + fl = 5; fr = 2; + fl /= fr; + if(fl != 2){ + lrc = 237; + if(prlc) printf(f,lrc); + } + fl = 5; dr = 2; + fl /= dr; + if(fl != 2){ + lrc = 238; + if(prlc) printf(f,lrc); + } + dl = 5; cr = 2; + dl /= cr; + if(dl != 2){ + lrc = 239; + if(prlc) printf(f,lrc); + } + dl = 5; sr = 2; + dl /= sr; + if(dl != 2){ + lrc = 240; + if(prlc) printf(f,lrc); + } + dl = 5; ir = 2; + dl /= ir; + if(dl != 2){ + lrc = 241; + if(prlc) printf(f,lrc); + } + dl = 5; lr = 2; + dl /= lr; + if(dl != 2){ + lrc = 242; + if(prlc) printf(f,lrc); + } + dl = 5; ur = 2; + dl /= ur; + if(dl != 2){ + lrc = 243; + if(prlc) printf(f,lrc); + } + dl = 5; fr = 2; + dl /= fr; + if(dl != 2){ + lrc = 244; + if(prlc) printf(f,lrc); + } + dl = 5; dr = 2; + dl /= dr; + if(dl != 2){ + lrc = 245; + if(prlc) printf(f,lrc); + } #else - fl = 5; cr = 2; - fl /= cr; - if(fl != 2.5){ - lrc = 232; - if(prlc) printf(f,lrc); - } - fl = 5; sr = 2; - fl /= sr; - if(fl != 2.5){ - lrc = 233; - if(prlc) printf(f,lrc); - } - fl = 5; ir = 2; - fl /= ir; - if(fl != 2.5){ - lrc = 234; - if(prlc) printf(f,lrc); - } - fl = 5; lr = 2; - fl /= lr; - if(fl != 2.5){ - lrc = 235; - if(prlc) printf(f,lrc); - } - fl = 5; ur = 2; - fl /= ur; - if(fl != 2.5){ - lrc = 236; - if(prlc) printf(f,lrc); - } - fl = 5; fr = 2; - fl /= fr; - if(fl != 2.5){ - lrc = 237; - if(prlc) printf(f,lrc); - } - fl = 5; dr = 2; - fl /= dr; - if(fl != 2.5){ - lrc = 238; - if(prlc) printf(f,lrc); - } - dl = 5; cr = 2; - dl /= cr; - if(dl != 2.5){ - lrc = 239; - if(prlc) printf(f,lrc); - } - dl = 5; sr = 2; - dl /= sr; - if(dl != 2.5){ - lrc = 240; - if(prlc) printf(f,lrc); - } - dl = 5; ir = 2; - dl /= ir; - if(dl != 2.5){ - lrc = 241; - if(prlc) printf(f,lrc); - } - dl = 5; lr = 2; - dl /= lr; - if(dl != 2.5){ - lrc = 242; - if(prlc) printf(f,lrc); - } - dl = 5; ur = 2; - dl /= ur; - if(dl != 2.5){ - lrc = 243; - if(prlc) printf(f,lrc); - } - dl = 5; fr = 2; - dl /= fr; - if(dl != 2.5){ - lrc = 244; - if(prlc) printf(f,lrc); - } - dl = 5; dr = 2; - dl /= dr; - if(dl != 2.5){ - lrc = 245; - if(prlc) printf(f,lrc); - } + fl = 5; cr = 2; + fl /= cr; + if(fl != 2.5){ + lrc = 232; + if(prlc) printf(f,lrc); + } + fl = 5; sr = 2; + fl /= sr; + if(fl != 2.5){ + lrc = 233; + if(prlc) printf(f,lrc); + } + fl = 5; ir = 2; + fl /= ir; + if(fl != 2.5){ + lrc = 234; + if(prlc) printf(f,lrc); + } + fl = 5; lr = 2; + fl /= lr; + if(fl != 2.5){ + lrc = 235; + if(prlc) printf(f,lrc); + } + fl = 5; ur = 2; + fl /= ur; + if(fl != 2.5){ + lrc = 236; + if(prlc) printf(f,lrc); + } + fl = 5; fr = 2; + fl /= fr; + if(fl != 2.5){ + lrc = 237; + if(prlc) printf(f,lrc); + } + fl = 5; dr = 2; + fl /= dr; + if(fl != 2.5){ + lrc = 238; + if(prlc) printf(f,lrc); + } + dl = 5; cr = 2; + dl /= cr; + if(dl != 2.5){ + lrc = 239; + if(prlc) printf(f,lrc); + } + dl = 5; sr = 2; + dl /= sr; + if(dl != 2.5){ + lrc = 240; + if(prlc) printf(f,lrc); + } + dl = 5; ir = 2; + dl /= ir; + if(dl != 2.5){ + lrc = 241; + if(prlc) printf(f,lrc); + } + dl = 5; lr = 2; + dl /= lr; + if(dl != 2.5){ + lrc = 242; + if(prlc) printf(f,lrc); + } + dl = 5; ur = 2; + dl /= ur; + if(dl != 2.5){ + lrc = 243; + if(prlc) printf(f,lrc); + } + dl = 5; fr = 2; + dl /= fr; + if(dl != 2.5){ + lrc = 244; + if(prlc) printf(f,lrc); + } + dl = 5; dr = 2; + dl /= dr; + if(dl != 2.5){ + lrc = 245; + if(prlc) printf(f,lrc); + } #endif cl = 5; cr = 2; cl %= cr; @@ -1750,9 +1750,9 @@ initial (5,2) | (5,2) | (12,10) *********************************************************************************************/ #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s714(pd0); @@ -1776,7 +1776,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq714b.c b/test/val/cq714b.c index b4908f4cb..9538281b8 100644 --- a/test/val/cq714b.c +++ b/test/val/cq714b.c @@ -971,9 +971,9 @@ initial (5,2) | (5,2) | (12,10) *********************************************************************************************/ #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s714(pd0); @@ -997,7 +997,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq715.c b/test/val/cq715.c index fec9c6170..0fe864159 100644 --- a/test/val/cq715.c +++ b/test/val/cq715.c @@ -105,9 +105,9 @@ int x, y, z; *********************************************************************************************/ #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ /*case 0: return s26(pd0);*/ @@ -132,7 +132,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq72.c b/test/val/cq72.c index 2f956e59d..421177a0b 100644 --- a/test/val/cq72.c +++ b/test/val/cq72.c @@ -299,9 +299,9 @@ int s72(struct defs *pd0){ *********************************************************************************************/ #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s26(pd0); @@ -326,7 +326,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq757.c b/test/val/cq757.c index 60b588555..cf28f79e3 100644 --- a/test/val/cq757.c +++ b/test/val/cq757.c @@ -289,9 +289,9 @@ int s757(struct defs *pd0){ *********************************************************************************************/ #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s26(pd0); diff --git a/test/val/cq7813.c b/test/val/cq7813.c index 0e743abcd..9d4308a3e 100644 --- a/test/val/cq7813.c +++ b/test/val/cq7813.c @@ -336,9 +336,9 @@ int s7813(struct defs *pd0){ *********************************************************************************************/ #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s7813(pd0); @@ -362,7 +362,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq81.c b/test/val/cq81.c index 0271cae5d..85e1ac1d6 100644 --- a/test/val/cq81.c +++ b/test/val/cq81.c @@ -682,9 +682,9 @@ test is unreliable. */ *********************************************************************************************/ #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s81(pd0); @@ -708,7 +708,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq84.c b/test/val/cq84.c index d37c82f29..64429e300 100644 --- a/test/val/cq84.c +++ b/test/val/cq84.c @@ -101,13 +101,13 @@ int s84(struct defs *pd0){ if(pd0->flgd != 0) printf(s84er,2); rc = rc+2; } - #else + #else pfi = glork; if((*pfi)(4) != 4){ if(pd0->flgd != 0) printf(s84er,2); rc = rc+2; } - #endif + #endif /* Float fa[17] declares an array of floating point numbers, and *afp[17] declares an array of pointers @@ -223,9 +223,9 @@ return x;} *********************************************************************************************/ #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s84(pd0); @@ -249,7 +249,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq85.c b/test/val/cq85.c index 15b055b20..49423e7de 100644 --- a/test/val/cq85.c +++ b/test/val/cq85.c @@ -118,10 +118,10 @@ int s85(struct defs *pd0){ #ifdef NO_FLOATS "signed", "signed", - #else + #else "float", "double" - #endif + #endif }; static char aln[] = " alignment: "; @@ -205,12 +205,12 @@ int s85(struct defs *pd0){ if(pd0->flgm != 0) printf("Sign extension in fields\n"); } else{ - #ifdef NO_BITFIELDS - if(pd0->flgd != 0) printf("NO_BITFIELDS\n"); - #else - if(pd0->flgd != 0) printf(s85er,2); - rc = rc+2; - #endif + #ifdef NO_BITFIELDS + if(pd0->flgd != 0) printf("NO_BITFIELDS\n"); + #else + if(pd0->flgd != 0) printf(s85er,2); + rc = rc+2; + #endif } } @@ -268,9 +268,9 @@ int one(); *********************************************************************************************/ #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s85(pd0); @@ -294,7 +294,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq86.c b/test/val/cq86.c index 9f2409e7a..9c850662a 100644 --- a/test/val/cq86.c +++ b/test/val/cq86.c @@ -183,9 +183,9 @@ int *metricp; *********************************************************************************************/ #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s86(pd0); @@ -209,7 +209,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq88.c b/test/val/cq88.c index a15f75110..ef742824e 100644 --- a/test/val/cq88.c +++ b/test/val/cq88.c @@ -139,9 +139,9 @@ int s88(struct defs *pd0){ *********************************************************************************************/ #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s88(pd0); @@ -165,7 +165,7 @@ int main(int n,char **args) { int j; static struct defs d0, *pd0; - + d0.flgs = 1; /* These flags dictate */ d0.flgm = 1; /* the verbosity of */ d0.flgd = 1; /* the program. */ diff --git a/test/val/cq9.c b/test/val/cq9.c index 228ac9e77..c0f1f45ff 100644 --- a/test/val/cq9.c +++ b/test/val/cq9.c @@ -109,9 +109,9 @@ int s9(struct defs *pd0){ *********************************************************************************************/ #ifndef NO_TYPELESS_STRUCT_PTR - int section(int j,struct* pd0){ + int section(int j,struct* pd0){ #else - int section(int j,void* pd0){ + int section(int j,void* pd0){ #endif switch(j){ case 0: return s9(pd0); diff --git a/test/val/lz4.c b/test/val/lz4.c index dceefbfcc..6fe72e72d 100644 --- a/test/val/lz4.c +++ b/test/val/lz4.c @@ -660,10 +660,10 @@ static unsigned char buf[18830]; int main() { - unsigned long cksum = adler32(0, NULL, 0); + unsigned long cksum = adler32(0, NULL, 0); - decompress_lz4(compressed, buf, 18830); - cksum = adler32(cksum, buf, 18830); + decompress_lz4(compressed, buf, 18830); + cksum = adler32(cksum, buf, 18830); - return cksum == 0xf748269d ? 0 : 1; + return cksum == 0xf748269d ? 0 : 1; } diff --git a/test/val/nestfor.c b/test/val/nestfor.c index 735da21de..09f9d093d 100644 --- a/test/val/nestfor.c +++ b/test/val/nestfor.c @@ -21,10 +21,10 @@ unsigned char uchar1 = 0; void dput(unsigned char val) { - /*PORTB = val; - PORTA = 0x01; - PORTA = 0x00; - */ + /*PORTB = val; + PORTA = 0x01; + PORTA = 0x00; + */ } void done() @@ -35,104 +35,104 @@ void done() /* both loops use the loop variable inside the inner loop */ void for1(void) { - unsigned char i, j; + unsigned char i, j; - uchar0 = 0; - uchar1 = 0; - for(i = 0; i < 3; i++) { - uchar0++; - for(j = 0; j < 4; j++) { - uchar1++; - dput(i); - dput(j); - } - } - if(uchar0 != 3) - failures++; - if(uchar1 != 12) - failures++; + uchar0 = 0; + uchar1 = 0; + for(i = 0; i < 3; i++) { + uchar0++; + for(j = 0; j < 4; j++) { + uchar1++; + dput(i); + dput(j); + } + } + if(uchar0 != 3) + failures++; + if(uchar1 != 12) + failures++; } /* only the outer loop's variable is used inside, inner can be optimized into a repeat-loop */ void for2(void) { - unsigned char i, j; + unsigned char i, j; - uchar0 = 0; - uchar1 = 0; - for(i = 0; i < 3; i++) { - uchar0++; - for(j = 0; j < 4; j++) { - uchar1++; - dput(i); - } - } - if(uchar0 != 3) - failures++; - if(uchar1 != 12) - failures++; + uchar0 = 0; + uchar1 = 0; + for(i = 0; i < 3; i++) { + uchar0++; + for(j = 0; j < 4; j++) { + uchar1++; + dput(i); + } + } + if(uchar0 != 3) + failures++; + if(uchar1 != 12) + failures++; } /* only the inner loop's variable is used inside */ void for3(void) { - unsigned char i, j; + unsigned char i, j; - uchar0 = 0; - uchar1 = 0; - for(i = 0; i < 3; i++) { - uchar0++; - for(j = 0; j < 4; j++) { - uchar1++; - dput(j); - } - } - if(uchar0 != 3) - failures++; - if(uchar1 != 12) - failures++; + uchar0 = 0; + uchar1 = 0; + for(i = 0; i < 3; i++) { + uchar0++; + for(j = 0; j < 4; j++) { + uchar1++; + dput(j); + } + } + if(uchar0 != 3) + failures++; + if(uchar1 != 12) + failures++; } /* neither loop variable used inside the loops */ void for4(void) { - unsigned char i, j; + unsigned char i, j; - uchar0 = 0; - uchar1 = 0; - for(i = 0; i < 3; i++) { - uchar0++; - for(j = 0; j < 4; j++) { - uchar1++; - dput(uchar0); - dput(uchar1); - } - } - if(uchar0 != 3) - failures++; - if(uchar1 != 12) - failures++; + uchar0 = 0; + uchar1 = 0; + for(i = 0; i < 3; i++) { + uchar0++; + for(j = 0; j < 4; j++) { + uchar1++; + dput(uchar0); + dput(uchar1); + } + } + if(uchar0 != 3) + failures++; + if(uchar1 != 12) + failures++; } /* like for1 but different condition in inner loop */ void for5(void) { - unsigned char i, j; + unsigned char i, j; - uchar0 = 0; - uchar1 = 0; - for(i = 0; i < 3; i++) { - uchar0++; - for(j = 10; j >= 5; j--) { - uchar1++; - dput(i); - dput(j); - } - } - if(uchar0 != 3) - failures++; - if(uchar1 != 18) - failures++; + uchar0 = 0; + uchar1 = 0; + for(i = 0; i < 3; i++) { + uchar0++; + for(j = 10; j >= 5; j--) { + uchar1++; + dput(i); + dput(j); + } + } + if(uchar0 != 3) + failures++; + if(uchar1 != 18) + failures++; } int main(void) diff --git a/test/val/postincdec.c b/test/val/postincdec.c index 6d3e9593c..9a4f06183 100644 --- a/test/val/postincdec.c +++ b/test/val/postincdec.c @@ -10,14 +10,14 @@ static unsigned char val, array[2]; int main() { - val = 0; - array[0] = array[1] = 10; + val = 0; + array[0] = array[1] = 10; - array[val++] = 2; - array[val++] = 2; - --val; - array[val--] = 0; - array[val--] = 0; + array[val++] = 2; + array[val++] = 2; + --val; + array[val--] = 0; + array[val--] = 0; - return (array[0] == array[1] && array[0] == 0 && val == 0xff) ? 0 : 1; + return (array[0] == array[1] && array[0] == 0 && val == 0xff) ? 0 : 1; } diff --git a/test/val/ptrfunc.c b/test/val/ptrfunc.c index 55503e176..4aa23b77b 100644 --- a/test/val/ptrfunc.c +++ b/test/val/ptrfunc.c @@ -50,33 +50,33 @@ void done() void call0(void) { - uchar0++; + uchar0++; } void call1(void) { - uchar1++; + uchar1++; } unsigned char call2(void) { - return uchar0 + 9; + return uchar0 + 9; } void docall0(void) { - pfunc = call0; - (pfunc)(); - if(uchar0 != 1) - failures++; + pfunc = call0; + (pfunc)(); + if(uchar0 != 1) + failures++; } void docall1() { - unsigned char i; - for(i = 0; i < 3; i++) { - (*p1func)(); - } + unsigned char i; + for(i = 0; i < 3; i++) { + (*p1func)(); + } } #ifdef NO_IMPLICIT_FUNCPTR_CONV @@ -85,53 +85,53 @@ void docall2( void(*pf)(void) ) void docall2( void(*pf)() ) #endif { - unsigned char i; - for(i = 0; i < 2; i++) { - pf(); - } + unsigned char i; + for(i = 0; i < 2; i++) { + pf(); + } } int main(void) { docall0(); - p1func = call1; - docall1(); - if(uchar1 != 3) - failures++; - if(uchar0 != 1) - failures++; + p1func = call1; + docall1(); + if(uchar1 != 3) + failures++; + if(uchar0 != 1) + failures++; - p1func = call0; - docall1(); - if(uchar1 != 3) - failures++; - if(uchar0 != 4) - failures++; + p1func = call0; + docall1(); + if(uchar1 != 3) + failures++; + if(uchar0 != 4) + failures++; - docall2(call0); - if(uchar1 != 3) - failures++; - if(uchar0 != 6) - failures++; + docall2(call0); + if(uchar1 != 3) + failures++; + if(uchar0 != 6) + failures++; - docall2(call1); - if(uchar1 != 5) - failures++; - if(uchar0 != 6) - failures++; + docall2(call1); + if(uchar1 != 5) + failures++; + if(uchar0 != 6) + failures++; - pcfunc = call2; - uchar2 = (*pcfunc)(); - if(uchar2 != 15) - failures++; + pcfunc = call2; + uchar2 = (*pcfunc)(); + if(uchar2 != 15) + failures++; - uchar2 += (pcfunc)(); - uchar2 += pcfunc(); + uchar2 += (pcfunc)(); + uchar2 += pcfunc(); - success = failures; - done(); - printf("failures: %d\n",failures); + success = failures; + done(); + printf("failures: %d\n",failures); - return failures; + return failures; } diff --git a/test/val/trampoline-params.c b/test/val/trampoline-params.c index 890e43e5f..c05d8c06d 100644 --- a/test/val/trampoline-params.c +++ b/test/val/trampoline-params.c @@ -10,9 +10,9 @@ static unsigned char flag; static void trampoline_set() { - asm("ldy tmp4"); - asm("sty %v", flag); - asm("jsr callptr4"); + asm("ldy tmp4"); + asm("sty %v", flag); + asm("jsr callptr4"); } #pragma wrapped-call(push, trampoline_set, 4) @@ -21,12 +21,12 @@ long adder(long in); long adder(long in) { - return in + 7; + return in + 7; } int main() { - flag = 0; + flag = 0; - return adder(70436) == 70436 + 7 && flag == 4 ? 0 : 1; + return adder(70436) == 70436 + 7 && flag == 4 ? 0 : 1; } diff --git a/test/val/trampoline-varargs.c b/test/val/trampoline-varargs.c index d154a3da0..e2db839c8 100644 --- a/test/val/trampoline-varargs.c +++ b/test/val/trampoline-varargs.c @@ -10,14 +10,14 @@ static unsigned char flag; static void trampoline_set() { - // The Y register is used for variadics - save and restore - asm("sty tmp3"); + // The Y register is used for variadics - save and restore + asm("sty tmp3"); - asm("ldy tmp4"); - asm("sty %v", flag); + asm("ldy tmp4"); + asm("sty %v", flag); - asm("ldy tmp3"); - asm("jsr callptr4"); + asm("ldy tmp3"); + asm("jsr callptr4"); } #pragma wrapped-call(push, trampoline_set, 4) @@ -26,23 +26,23 @@ unsigned adder(unsigned char num, ...); unsigned adder(unsigned char num, ...) { - unsigned char i; - unsigned sum = 0; - va_list ap; - va_start(ap, num); + unsigned char i; + unsigned sum = 0; + va_list ap; + va_start(ap, num); - for (i = 0; i < num; i++) { - sum += va_arg(ap, unsigned); - } + for (i = 0; i < num; i++) { + sum += va_arg(ap, unsigned); + } - va_end(ap); + va_end(ap); - return sum; + return sum; } int main() { - flag = 0; + flag = 0; - return adder(3, 0, 5, 500) == 505 && flag == 4 ? 0 : 1; + return adder(3, 0, 5, 500) == 505 && flag == 4 ? 0 : 1; } diff --git a/test/val/trampoline.c b/test/val/trampoline.c index 63741b590..b2010f6f3 100644 --- a/test/val/trampoline.c +++ b/test/val/trampoline.c @@ -8,14 +8,14 @@ static unsigned char flag; static void trampoline_set() { - asm("ldy tmp4"); - asm("sty %v", flag); - asm("jsr callptr4"); + asm("ldy tmp4"); + asm("sty %v", flag); + asm("jsr callptr4"); } void trampoline_inc() { - asm("inc %v", flag); - asm("jsr callptr4"); + asm("inc %v", flag); + asm("jsr callptr4"); } void func3() { @@ -25,7 +25,7 @@ void func3() { #pragma wrapped-call(push, trampoline_inc, 0) void func2() { - func3(); + func3(); } #pragma wrapped-call(push, trampoline_set, 4) @@ -36,14 +36,14 @@ void func1(void); #pragma wrapped-call(pop) void func1() { - func2(); + func2(); } int main(void) { - flag = 0; + flag = 0; - func1(); + func1(); - return flag == 5 ? 0 : 1; + return flag == 5 ? 0 : 1; } From 417ef278a337f4eaa11fca905dba94a822e97372 Mon Sep 17 00:00:00 2001 From: Bill Kendrick <nbs@sonic.net> Date: Sat, 16 Feb 2019 00:25:25 -0800 Subject: [PATCH 1004/2161] Move Atari-specific PIA reg vals to atari.h PIA is also used in the Commodore PET, and for different purposes (see http://www.6502.org/users/andre/petindex/progmod.html#pia1), so extracted Atari-specific register #defines and placed them in atari.h. --- include/_pia.h | 116 +----------------------------------------------- include/atari.h | 114 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 115 deletions(-) diff --git a/include/_pia.h b/include/_pia.h index 8c9fa01f1..4b71ecfd4 100644 --- a/include/_pia.h +++ b/include/_pia.h @@ -11,7 +11,6 @@ /* */ /* */ /* (C) 2000 Freddy Offenga <taf_offenga@yahoo.com> */ -/* 2019-01-17: Bill Kendrick <nbs@sonic.net>: Defines for registers */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -47,120 +46,7 @@ struct __pia { unsigned char pbctl; /* port B control */ }; - -/*****************************************************************************/ -/* PORTA and PORTB register bits */ -/*****************************************************************************/ - -/* See also: "JOY_xxx_MASK" in "atari.h" */ - -/* Paddle 0-3 triggers (per PORTA bits) */ -#define PORTA_PTRIG3 0x80 -#define PORTA_PTRIG2 0x40 -#define PORTA_PTRIG1 0x08 -#define PORTA_PTRIG0 0x04 - - -/* On the Atari 400/800, PORTB is the same as PORTA, but for controller ports 3 & 4. */ - -/* Paddle 4-7 triggers (per PORTB bits); only 400/800 had four controller ports */ -#define PORTB_PTRIG7 0x80 -#define PORTB_PTRIG6 0x40 -#define PORTB_PTRIG5 0x08 -#define PORTB_PTRIG4 0x04 - - -/* On the XL series of computers, PORTB has been changed to a memory and -** LED control (1200XL model only) register (read/write): -*/ - -/* If set, the built-in OS is enabled, and occupies the address range $C000-$FFFF -** (except that the area $D000-$D7FF will only access the hardware registers.) -** If clear, RAM is enabled in this area (again, save for the hole.) -*/ -#define PORTB_OSROM 0x01 - -/* If set, RAM is enabled for the address range $A000-$BFFF. -** If clear, the built-in BASIC ROM is enabled at this address. -** And if there is a cartridge installed in the computer, it makes no difference. -*/ -#define PORTB_BASICROM 0x02 - -/* If set, the corresponding LED is turned off. If clear, the LED will be on. -** (1200XL only) -*/ -#define PORTB_LED1 0x04 -#define PORTB_LED2 0x08 - - -/* On the XE series of computers, PORTB is a bank-selected memory control register (read/write): */ - -/* These bits determine which memory bank is visible to the CPU and/or ANTIC chip -** when their Bank Switch bit is set. There are four possible banks of 16KB each. -*/ -#define PORTB_BANKSELECT1 0x00 -#define PORTB_BANKSELECT2 0x04 -#define PORTB_BANKSELECT3 0x08 -#define PORTB_BANKSELECT4 0x0C - -/* If set, the CPU and/or ANTIC chip will access bank-switched memory mapped to the -** address range $4000-$7FFF. -** If clear, the CPU and/or ANTIC will see normal memory in this region. -*/ -#define PORTB_BANKSWITCH_CPU 0x10 -#define PORTB_BANKSWITCH_ANTIC 0x20 - -/* If set, RAM is enabled for the address range $5000-$57FF. -** If clear, the self-test ROM (physically located at $D000-$D7FF, under the hardware registers) -** is remapped to this memory area. -*/ -#define PORTB_SELFTEST 0x80 - - -/*****************************************************************************/ -/* PACTL and PBCTL register bits */ -/*****************************************************************************/ - -/* (W) Peripheral PA1/PB1 interrupt (IRQ) ("peripheral proceed line available") enable. -** One equals enable. Set by the OS but available to the user; reset on powerup. -** (PxCTL_IRQ_STATUS (R) bit will get set upon interrupt occurance) -*/ -#define PxCTL_IRQ_ENABLE 0x01 /* bit 0 */ - -/* Note: Bit 1 is always set to */ - -/* (W) Controls PORTA/PORTB addressing -** 1 = PORTA/PORTB register; read/write to controller port -** 0 = direction control register; write to direction controls -** (allows setting data flow; write 0s & 1s to PORTA/PORTB bits -** to set which port's pins are read (input), or write (output), -** respectively) -*/ -#define PxCTL_ADDRESSING 0x04 /* bit 2 */ - -/* (W) Peripheral motor control line; Turn the cassette on or off -** (PACTL-specific register bit) -** 0 = on -** 1 = off -*/ -#define PACTL_MOTOR_CONTROL 0x08 /* bit 3 */ - -/* Peripheral command identification (serial bus command line) -** (PBCTL-specific register bit) -*/ -#define PBCTL_PERIPH_CMD_IDENT 0x08 /* bit 3 */ - -/* Note: Bits 4 & 5 are always set to 1 */ - -/* Note: Bit 6 is always set to 0 */ - -/* (R) Peripheral interrupt (IRQ) status bit. -** Set by Peripherals (PORTA / PORTB). Reset by reading from PORTA / PORTB. -** PACTL's is interrupt status of PROCEED -** PBCTL's is interrupt status of SIO -*/ -#define PxCTL_IRQ_STATUS 0x80 - +/* (Some specific register values for Atari defined in atari.h) */ /* End of _pia.h */ #endif diff --git a/include/atari.h b/include/atari.h index e06967ff9..39b4e6947 100644 --- a/include/atari.h +++ b/include/atari.h @@ -375,6 +375,120 @@ extern void atrx15p2_tgi[]; #define ANTIC (*(struct __antic*)0xD400) +/*****************************************************************************/ +/* PIA PORTA and PORTB register bits */ +/*****************************************************************************/ + +/* See also: "JOY_xxx_MASK" in "atari.h" */ + +/* Paddle 0-3 triggers (per PORTA bits) */ +#define PORTA_PTRIG3 0x80 +#define PORTA_PTRIG2 0x40 +#define PORTA_PTRIG1 0x08 +#define PORTA_PTRIG0 0x04 + + +/* On the Atari 400/800, PORTB is the same as PORTA, but for controller ports 3 & 4. */ + +/* Paddle 4-7 triggers (per PORTB bits); only 400/800 had four controller ports */ +#define PORTB_PTRIG7 0x80 +#define PORTB_PTRIG6 0x40 +#define PORTB_PTRIG5 0x08 +#define PORTB_PTRIG4 0x04 + + +/* On the XL series of computers, PORTB has been changed to a memory and +** LED control (1200XL model only) register (read/write): +*/ + +/* If set, the built-in OS is enabled, and occupies the address range $C000-$FFFF +** (except that the area $D000-$D7FF will only access the hardware registers.) +** If clear, RAM is enabled in this area (again, save for the hole.) +*/ +#define PORTB_OSROM 0x01 + +/* If set, RAM is enabled for the address range $A000-$BFFF. +** If clear, the built-in BASIC ROM is enabled at this address. +** And if there is a cartridge installed in the computer, it makes no difference. +*/ +#define PORTB_BASICROM 0x02 + +/* If set, the corresponding LED is turned off. If clear, the LED will be on. +** (1200XL only) +*/ +#define PORTB_LED1 0x04 +#define PORTB_LED2 0x08 + + +/* On the XE series of computers, PORTB is a bank-selected memory control register (read/write): */ + +/* These bits determine which memory bank is visible to the CPU and/or ANTIC chip +** when their Bank Switch bit is set. There are four possible banks of 16KB each. +*/ +#define PORTB_BANKSELECT1 0x00 +#define PORTB_BANKSELECT2 0x04 +#define PORTB_BANKSELECT3 0x08 +#define PORTB_BANKSELECT4 0x0C + +/* If set, the CPU and/or ANTIC chip will access bank-switched memory mapped to the +** address range $4000-$7FFF. +** If clear, the CPU and/or ANTIC will see normal memory in this region. +*/ +#define PORTB_BANKSWITCH_CPU 0x10 +#define PORTB_BANKSWITCH_ANTIC 0x20 + +/* If set, RAM is enabled for the address range $5000-$57FF. +** If clear, the self-test ROM (physically located at $D000-$D7FF, under the hardware registers) +** is remapped to this memory area. +*/ +#define PORTB_SELFTEST 0x80 + + +/*****************************************************************************/ +/* PACTL and PBCTL register bits */ +/*****************************************************************************/ + +/* (W) Peripheral PA1/PB1 interrupt (IRQ) ("peripheral proceed line available") enable. +** One equals enable. Set by the OS but available to the user; reset on powerup. +** (PxCTL_IRQ_STATUS (R) bit will get set upon interrupt occurance) +*/ +#define PxCTL_IRQ_ENABLE 0x01 /* bit 0 */ + +/* Note: Bit 1 is always set to */ + +/* (W) Controls PORTA/PORTB addressing +** 1 = PORTA/PORTB register; read/write to controller port +** 0 = direction control register; write to direction controls +** (allows setting data flow; write 0s & 1s to PORTA/PORTB bits +** to set which port's pins are read (input), or write (output), +** respectively) +*/ +#define PxCTL_ADDRESSING 0x04 /* bit 2 */ + +/* (W) Peripheral motor control line; Turn the cassette on or off +** (PACTL-specific register bit) +** 0 = on +** 1 = off +*/ +#define PACTL_MOTOR_CONTROL 0x08 /* bit 3 */ + +/* Peripheral command identification (serial bus command line) +** (PBCTL-specific register bit) +*/ +#define PBCTL_PERIPH_CMD_IDENT 0x08 /* bit 3 */ + +/* Note: Bits 4 & 5 are always set to 1 */ + +/* Note: Bit 6 is always set to 0 */ + +/* (R) Peripheral interrupt (IRQ) status bit. +** Set by Peripherals (PORTA / PORTB). Reset by reading from PORTA / PORTB. +** PACTL's is interrupt status of PROCEED +** PBCTL's is interrupt status of SIO +*/ +#define PxCTL_IRQ_STATUS 0x80 + + /*****************************************************************************/ /* Shadow registers for hardware registers */ /*****************************************************************************/ From b6f22d332ba140df46b47c844aec8df5e00110bf Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 21 Feb 2019 13:45:51 +0100 Subject: [PATCH 1005/2161] un-remove TABs in doc/using-make.sgml --- doc/using-make.sgml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/using-make.sgml b/doc/using-make.sgml index 2758a340b..e324b7484 100644 --- a/doc/using-make.sgml +++ b/doc/using-make.sgml @@ -76,18 +76,18 @@ ifneq ($(MAKECMDGOALS),clean) endif %.o: %.c - $(CC) -c $(CFLAGS) -o $@ $< + $(CC) -c $(CFLAGS) -o $@ $< $(PROGRAM): $(SOURCES:.c=.o) - $(CC) $(LDFLAGS) -o $@ $^ + $(CC) $(LDFLAGS) -o $@ $^ clean: - $(RM) $(SOURCES:.c=.o) $(SOURCES:.c=.d) $(PROGRAM) $(PROGRAM).map + $(RM) $(SOURCES:.c=.o) $(SOURCES:.c=.d) $(PROGRAM) $(PROGRAM).map </verb></tscreen> <bf/Important:/ When using the sample Makefile above via copy & paste it is -necessary to replace the eight spaces at the beginning of command lines (lines -26, 29 and 32) with a tab character (ASCII code 9). +important to make sure that command lines (lines 26, 29 and 32) start +with a tab character (ASCII code 9). <sect1>Invoking the sample Makefile<p> @@ -119,7 +119,7 @@ The recommended way to use GNU Make on Windows is to install it as part of a Cygwin environment. For more information see the Cygwin home page: <url url="http://www.cygwin.com/"> - + If however installing Cygwin shouldn't be an option for one or the other reason then the sample Makefile may be invoked from the Windows Command Prompt (cmd.exe) by downloading the following programs: @@ -132,17 +132,17 @@ by downloading the following programs: <sect>Target-specific Variable Values<p> - + The very limited resources of the cc65 target machines now and then require manual optimization of the build process by compiling individual source files with different compiler options. GNU Make offers <url url="http://www.gnu.org/software/make/manual/html_node/Target_002dspecific.html" name="Target-specific Variable Values"> -perfectly suited for doing so. For example placing the code of the two modules +perfectly suited for doing so. For example placing the code of the two modules <tt/foo/ and <tt/bar/ in the segment <tt/FOOBAR/ can be achieved with this target-specific variable definition: <tscreen><verb> foo.o bar.o: CFLAGS += --code-name FOOBAR </verb></tscreen> - + </article> From b03ae76b54d77f435088cacf12d3cfd9873f05ed Mon Sep 17 00:00:00 2001 From: Daniel Serpell <daniel.serpell@gmail.com> Date: Mon, 18 Feb 2019 00:24:52 -0300 Subject: [PATCH 1006/2161] Add support for INITAD to the Atari binary format. --- doc/ld65.sgml | 21 ++++++++++++--- src/ld65/config.c | 21 +++++++++++++++ src/ld65/scanner.h | 1 + src/ld65/xex.c | 43 ++++++++++++++++++++++++++++++- src/ld65/xex.h | 2 ++ testcode/lib/atari/multi-xex.cfg | 8 ++++-- testcode/lib/atari/multi-xex.s | 19 +++++++++++++- testcode/lib/atari/multi.xex | Bin 0 -> 157 bytes 8 files changed, 108 insertions(+), 7 deletions(-) create mode 100644 testcode/lib/atari/multi.xex diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 9116eb442..3f159b39b 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -938,9 +938,24 @@ has several attributes that may be defined here. } </verb></tscreen> -The Atari file format has only one attribute, <tt/RUNAD/ that allows to specify -a symbol as the run address of the binary. If the attribute is omiteed, no run -address is specified. +The Atari file format has two attributes: + +<descrip> + + <tag><tt>RUNAD = symbol</tt></tag> + + Specify a symbol as the run address of the binary, the loader will call this + address after all the file is loaded in memory. If the attribute is omitted, + no run address is included in the file. + + <tag><tt>INITAD = memory_area : symbol</tt></tag> + + Specify a symbol as the initialization address for the given memory area. + The binary loader will call this address just after the memory area is loaded + into memory, before continuing loading the rest of the file. + +</descrip> + <tscreen><verb> FORMATS { diff --git a/src/ld65/config.c b/src/ld65/config.c index fafbed290..f8bff2ac0 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -1007,6 +1007,7 @@ static void ParseXex (void) { static const IdentTok Attributes [] = { { "RUNAD", CFGTOK_RUNAD }, + { "INITAD", CFGTOK_INITAD }, }; /* Remember the attributes read */ @@ -1017,6 +1018,8 @@ static void ParseXex (void) }; unsigned AttrFlags = atNone; Import *RunAd = 0; + Import *InitAd; + MemoryArea *InitMem; /* Read the attributes */ while (CfgTok == CFGTOK_IDENT) { @@ -1046,6 +1049,24 @@ static void ParseXex (void) CfgNextTok (); break; + case CFGTOK_INITAD: + /* We expect a memory area followed by a colon and an identifier */ + CfgAssureIdent (); + InitMem = CfgGetMemory (GetStrBufId (&CfgSVal)); + CfgNextTok (); + CfgConsumeColon (); + CfgAssureIdent (); + /* Generate an import for the symbol */ + InitAd = InsertImport (GenImport (GetStrBufId (&CfgSVal), ADDR_SIZE_ABS)); + /* Remember the file position */ + CollAppend (&InitAd->RefLines, GenLineInfo (&CfgErrorPos)); + /* Eat the identifier token */ + CfgNextTok (); + /* Add to XEX */ + if (XexAddInitAd (XexFmtDesc, InitMem, InitAd)) + CfgError (&CfgErrorPos, "INITAD already given for memory area"); + break; + default: FAIL ("Unexpected attribute token"); diff --git a/src/ld65/scanner.h b/src/ld65/scanner.h index 77fa91da8..aeabbdca8 100644 --- a/src/ld65/scanner.h +++ b/src/ld65/scanner.h @@ -94,6 +94,7 @@ typedef enum { CFGTOK_VERSION, CFGTOK_FORMAT, CFGTOK_RUNAD, + CFGTOK_INITAD, CFGTOK_LOAD, CFGTOK_RUN, diff --git a/src/ld65/xex.c b/src/ld65/xex.c index 18190c063..e7674949a 100644 --- a/src/ld65/xex.c +++ b/src/ld65/xex.c @@ -58,6 +58,12 @@ /* Data */ /*****************************************************************************/ +/* Linked list of memory area initialization addresses */ +typedef struct XexInitAd { + MemoryArea *InitMem; + Import *InitAd; + struct XexInitAd *next; +} XexInitAd; struct XexDesc { @@ -65,13 +71,13 @@ struct XexDesc { FILE* F; /* Output file */ const char* Filename; /* Name of output file */ Import* RunAd; /* Run Address */ + XexInitAd* InitAds; /* List of Init Addresses */ unsigned long HeadPos; /* Position in the file of current header */ unsigned long HeadEnd; /* End address of current header */ unsigned long HeadSize; /* Last header size, can be removed if zero */ }; - /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -89,6 +95,7 @@ XexDesc* NewXexDesc (void) D->F = 0; D->Filename = 0; D->RunAd = 0; + D->InitAds = 0; D->HeadPos = 0; D->HeadEnd = 0; D->HeadSize = 0; @@ -113,8 +120,35 @@ void XexSetRunAd (XexDesc* D, Import *RunAd) D->RunAd = RunAd; } +XexInitAd* XexSearchInitMem(XexDesc* D, MemoryArea *InitMem) +{ + XexInitAd* I; + for (I=D->InitAds; I != 0; I=I->next) + { + if (I->InitMem == InitMem) + return I; + } + return NULL; +} +int XexAddInitAd (XexDesc* D, MemoryArea *InitMem, Import *InitAd) +/* Sets and INITAD for the given memory area */ +{ + XexInitAd* I; + + /* Search for repeated entry */ + if (XexSearchInitMem (D, InitMem)) + return 1; + + I = xmalloc (sizeof (XexInitAd)); + I->InitAd = InitAd; + I->InitMem = InitMem; + I->next = D->InitAds; + D->InitAds = I; + return 0; +} + static unsigned XexWriteExpr (ExprNode* E, int Signed, unsigned Size, unsigned long Offs attribute ((unused)), void* Data) @@ -369,8 +403,15 @@ void XexWriteTarget (XexDesc* D, struct File* F) for (I = 0; I < CollCount (&F->MemoryAreas); ++I) { /* Get this entry */ MemoryArea* M = CollAtUnchecked (&F->MemoryAreas, I); + /* See if we have an init address for this area */ + XexInitAd* I = XexSearchInitMem (D, M); Print (stdout, 1, " ATARI EXE Dumping `%s'\n", GetString (M->Name)); XexWriteMem (D, M); + if (I) { + Write16 (D->F, 0x2E2); + Write16 (D->F, 0x2E3); + Write16 (D->F, GetExportVal (I->InitAd->Exp)); + } } /* Write RUNAD at file end */ diff --git a/src/ld65/xex.h b/src/ld65/xex.h index c74f78eca..2eb80de86 100644 --- a/src/ld65/xex.h +++ b/src/ld65/xex.h @@ -69,6 +69,8 @@ void XexWriteTarget (XexDesc* D, File* F); void XexSetRunAd (XexDesc* D, Import *RunAd); /* Set the RUNAD export */ +int XexAddInitAd (XexDesc* D, MemoryArea *InitMem, Import *InitAd); +/* Sets and INITAD for the given memory area */ /* End of xex.h */ diff --git a/testcode/lib/atari/multi-xex.cfg b/testcode/lib/atari/multi-xex.cfg index 18dfff820..7558aa895 100644 --- a/testcode/lib/atari/multi-xex.cfg +++ b/testcode/lib/atari/multi-xex.cfg @@ -3,10 +3,12 @@ FEATURES { } MEMORY { ZP: file = "", define = yes, start = $0082, size = $007E; + # First memory segment in file, show message + LOADER: file = %O, start = $680, size = 128; # First memory segment in file, load over COLOR registers: COLOR: file = %O, start = $2C4, size = 5; # Second memory segment, load at page 6: - PAGE6: file = %O, start = $600, size = 256; + PAGE6: file = %O, start = $600, size = 128; # Third memory segment in file, load over SDLST register: SDLST: file = %O, start = $230, size = 2; # Main segment, load at "STARTADDRESS" @@ -16,11 +18,13 @@ FILES { %O: format = atari; } FORMATS { - atari: runad = start; + atari: runad = start, + initad = LOADER: show_load; } SEGMENTS { ZEROPAGE: load = ZP, type = zp, optional = yes; # Place segments in memory areas: + LOADER: load = LOADER, type = rw; COLOR: load = COLOR, type = rw; PAGE6: load = PAGE6, type = rw; SDLST: load = SDLST, type = rw; diff --git a/testcode/lib/atari/multi-xex.s b/testcode/lib/atari/multi-xex.s index 7957ddf64..cdf43469d 100644 --- a/testcode/lib/atari/multi-xex.s +++ b/testcode/lib/atari/multi-xex.s @@ -14,8 +14,25 @@ .macpack atari ; Default RUNAD is "start", export that: - .export start + .export start, show_load +; Loader + .segment "LOADER" +show_load: + ldx #0 ; channel 0 + lda #<msg_load + sta ICBAL,x ; address + lda #>msg_load + sta ICBAH,x + lda #$FF + sta ICBLL,x ; length + sta ICBLH,x + lda #PUTREC + sta ICCOM,x + jmp CIOV + +msg_load: + .byte "Loading....", ATEOL ; We load color values directly into registers .segment "COLOR" diff --git a/testcode/lib/atari/multi.xex b/testcode/lib/atari/multi.xex new file mode 100644 index 0000000000000000000000000000000000000000..7da39ad47af630bef4edab9f21e06b7162e98e88 GIT binary patch literal 157 zcmezWzkzKz+aiXQbLP4*uVkC+%DnRbTo2~Cp3Eyb=Q=U_ggx=ePfW?oOV<N}*^ihW zGc~XsVLHJi=EjiK#K7jkRsaTWylhO43~UTQppmMRqt8&TU!;@52;#$ln>%(0lQ&>8 UWCEI?$E4@Op!b03Arpfh0RH4B!2kdN literal 0 HcmV?d00001 From 61463e1a7051ede837ae83e377ddabc8b7cbb50a Mon Sep 17 00:00:00 2001 From: Daniel Serpell <daniel.serpell@gmail.com> Date: Mon, 18 Feb 2019 09:28:00 -0300 Subject: [PATCH 1007/2161] Don't write INITAD if the memory area is empty. --- src/ld65/xex.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ld65/xex.c b/src/ld65/xex.c index e7674949a..c57fa0a8c 100644 --- a/src/ld65/xex.c +++ b/src/ld65/xex.c @@ -233,11 +233,14 @@ static void XexFakeSegment (XexDesc *D, unsigned long Addr) -static void XexWriteMem (XexDesc* D, MemoryArea* M) +static unsigned long XexWriteMem (XexDesc* D, MemoryArea* M) /* Write the segments of one memory area to a file */ { unsigned I; + /* Store initial position to get total file size */ + unsigned long StartPos = ftell (D->F); + /* Always write a segment header for each memory area */ D->HeadPos = 0; @@ -355,6 +358,8 @@ static void XexWriteMem (XexDesc* D, MemoryArea* M) if (D->HeadSize == 0 && D->HeadPos) { fseek (D->F, D->HeadPos, SEEK_SET); } + + return ftell (D->F) - StartPos; } @@ -406,8 +411,7 @@ void XexWriteTarget (XexDesc* D, struct File* F) /* See if we have an init address for this area */ XexInitAd* I = XexSearchInitMem (D, M); Print (stdout, 1, " ATARI EXE Dumping `%s'\n", GetString (M->Name)); - XexWriteMem (D, M); - if (I) { + if (XexWriteMem (D, M) && I) { Write16 (D->F, 0x2E2); Write16 (D->F, 0x2E3); Write16 (D->F, GetExportVal (I->InitAd->Exp)); From 258ba05660dd18dcf35539fe91218a12ae5ad987 Mon Sep 17 00:00:00 2001 From: Daniel Serpell <daniel.serpell@gmail.com> Date: Mon, 18 Feb 2019 00:26:01 -0300 Subject: [PATCH 1008/2161] Separate header and trailers of Atari system_check chunk. This allows to omit the headers and trailers if needed. --- libsrc/atari/system_check.s | 26 ++++++-------------------- libsrc/atari/system_check_hdr.s | 16 ++++++++++++++++ libsrc/atari/system_check_trailer.s | 17 +++++++++++++++++ 3 files changed, 39 insertions(+), 20 deletions(-) create mode 100644 libsrc/atari/system_check_hdr.s create mode 100644 libsrc/atari/system_check_trailer.s diff --git a/libsrc/atari/system_check.s b/libsrc/atari/system_check.s index 19efaf2e2..df7c433a4 100644 --- a/libsrc/atari/system_check.s +++ b/libsrc/atari/system_check.s @@ -16,8 +16,7 @@ ;DEBUG = 1 - .export __SYSTEM_CHECK__: absolute = 1 - .import __SYSCHK_LOAD__ + .export __SYSTEM_CHECK__, __SYSCHK_END__ .import __STARTADDRESS__ ; the following imports are only needed for the 'atari' target version @@ -25,10 +24,12 @@ .import __STACKSIZE__ .import __RESERVED_MEMORY__ + ; import our header and trailers + .forceimport __SYSCHKHDR__, __SYSCHKTRL__ + .include "zeropage.inc" .include "atari.inc" - .macro print_string text .local start, cont jmp cont @@ -229,25 +230,10 @@ delay1: ldx #0 .endproc -end: +__SYSTEM_CHECK__=syschk +__SYSCHK_END__: .ifndef __ATARIXL__ tmp: ; outside of the load chunk, some kind of poor man's .bss .endif -; ------------------------------------------------------------------------ -; Chunk header - -.segment "SYSCHKHDR" - - .word __SYSCHK_LOAD__ - .word end - 1 - -; ------------------------------------------------------------------------ -; Chunk "trailer" - sets INITAD - -.segment "SYSCHKTRL" - - .word INITAD - .word INITAD+1 - .word syschk diff --git a/libsrc/atari/system_check_hdr.s b/libsrc/atari/system_check_hdr.s new file mode 100644 index 000000000..1581ab918 --- /dev/null +++ b/libsrc/atari/system_check_hdr.s @@ -0,0 +1,16 @@ +; +; Atari startup system check headers +; +; Christian Groessler, chris@groessler.org, 2013 +; + .export __SYSCHKHDR__: absolute = 1 + .import __SYSCHK_LOAD__, __SYSCHK_END__ + +; ------------------------------------------------------------------------ +; Chunk header + +.segment "SYSCHKHDR" + + .word __SYSCHK_LOAD__ + .word __SYSCHK_END__ - 1 + diff --git a/libsrc/atari/system_check_trailer.s b/libsrc/atari/system_check_trailer.s new file mode 100644 index 000000000..312b83b1f --- /dev/null +++ b/libsrc/atari/system_check_trailer.s @@ -0,0 +1,17 @@ +; +; Atari startup system check headers +; +; Christian Groessler, chris@groessler.org, 2013 +; + .export __SYSCHKTRL__: absolute = 1 + .import __SYSTEM_CHECK__ + + .include "atari.inc" +; ------------------------------------------------------------------------ +; Chunk "trailer" - sets INITAD + +.segment "SYSCHKTRL" + + .word INITAD + .word INITAD+1 + .word __SYSTEM_CHECK__ From 0e33a653d72ef72558e2e99bdb3828da02981b88 Mon Sep 17 00:00:00 2001 From: Daniel Serpell <daniel.serpell@gmail.com> Date: Mon, 18 Feb 2019 00:30:04 -0300 Subject: [PATCH 1009/2161] Add sample linker configurations for Atari binary output in C. --- cfg/atari-c-xex.cfg | 56 ++++++++++++++++++++++++++++++ cfg/atarixl-c-xex.cfg | 79 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 cfg/atari-c-xex.cfg create mode 100644 cfg/atarixl-c-xex.cfg diff --git a/cfg/atari-c-xex.cfg b/cfg/atari-c-xex.cfg new file mode 100644 index 000000000..5f390e12c --- /dev/null +++ b/cfg/atari-c-xex.cfg @@ -0,0 +1,56 @@ +# Sample linker configuration for C programs using the Atari binary file support. +# Use with: cl65 -tatari -Catari-c-xex.cfg prog.c -o prog.xex +FEATURES { + STARTADDRESS: default = $2000; +} +SYMBOLS { + __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __STARTADDRESS__: type = export, value = %S; + __RESERVED_MEMORY__: type = weak, value = $0000; + __SYSCHKHDR__: type = export, value = 0; # Disable system check header + __SYSCHKTRL__: type = export, value = 0; # Disable system check trailer +} +MEMORY { + ZP: file = "", define = yes, start = $0082, size = $007E; +# "system check" load chunk + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; +# "main program" load chunk + MAIN: file = %O, define = yes, start = %S, size = $BC20 - __STACKSIZE__ - __RESERVED_MEMORY__ - %S; +} +FILES { + %O: format = atari; +} +FORMATS { + atari: runad = start, + initad = SYSCHKCHNK: __SYSTEM_CHECK__; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; + SYSCHK: load = SYSCHKCHNK, type = rw, define = yes, optional = yes; + STARTUP: load = MAIN, type = ro, define = yes; + LOWBSS: load = MAIN, type = rw, optional = yes; # not zero initialized + LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; + CODE: load = MAIN, type = ro, define = yes; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = rw, optional = yes; + 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/cfg/atarixl-c-xex.cfg b/cfg/atarixl-c-xex.cfg new file mode 100644 index 000000000..0b1fe9ca1 --- /dev/null +++ b/cfg/atarixl-c-xex.cfg @@ -0,0 +1,79 @@ +# Sample linker configuration for C programs using the Atari binary file support. +# Use with: cl65 -tatarixl -Catarixl-c-xex.cfg prog.c -o prog.xex +FEATURES { + STARTADDRESS: default = $2400; +} +SYMBOLS { + __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __STARTADDRESS__: type = export, value = %S; + __SYSCHKHDR__: type = export, value = 0; # Disable system check header + __SYSCHKTRL__: type = export, value = 0; # Disable system check trailer +} +MEMORY { + ZP: file = "", define = yes, start = $0082, size = $007E; + +# "system check" load chunk + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + +# "shadow RAM preparation" load chunk + SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned + +# "main program" load chunk + MAIN: file = %O, define = yes, start = %S + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __LOWBSS_SIZE__; + +# memory beneath the ROM preceeding the character generator + HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; + +# address of relocated character generator (same addess as ROM version) + CHARGEN: file = "", define = yes, start = $E000, size = $0400; + +# memory beneath the ROM + HIDDEN_RAM: file = "", define = yes, start = $E400, size = $FFFA - $E400; + +# UNUSED - hide + UNUSED: file = "", start = $0, size = $10; +} +FILES { + %O: format = atari; +} +FORMATS { + atari: runad = start, + initad = SYSCHKCHNK: __SYSTEM_CHECK__, + initad = SRPREPCHNK: sramprep; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; + + SYSCHK: load = SYSCHKCHNK, type = rw, define = yes, optional = yes; + LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and RAM, not zero initialized + SRPREP: load = SRPREPCHNK, type = rw, define = yes; + SHADOW_RAM: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = yes; + SHADOW_RAM2: load = SRPREPCHNK, run = HIDDEN_RAM2, type = rw, define = yes, optional = yes; + STARTUP: load = MAIN, type = ro, define = yes; + LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; + CODE: load = MAIN, type = ro, define = yes; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = rw, optional = yes; + BSS: load = MAIN, type = bss, define = yes; + SRPREPHDR: load = UNUSED, type = ro; + SRPREPTRL: load = UNUSED, type = ro; +} +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 824e30934e43b5cc3de9202bf246c96f66f692b6 Mon Sep 17 00:00:00 2001 From: Daniel Serpell <daniel.serpell@gmail.com> Date: Thu, 21 Feb 2019 18:55:08 -0300 Subject: [PATCH 1010/2161] Change XEX configuration file names to better reflect original names. Also, updates documentation with the new files. --- cfg/atari-asm-xex.cfg | 24 ++++++++++ cfg/atari-c-xex.cfg | 56 ---------------------- cfg/atari-xex.cfg | 54 ++++++++++++++++----- cfg/{atarixl-c-xex.cfg => atarixl-xex.cfg} | 0 doc/atari.sgml | 26 +++++++++- 5 files changed, 91 insertions(+), 69 deletions(-) create mode 100644 cfg/atari-asm-xex.cfg delete mode 100644 cfg/atari-c-xex.cfg rename cfg/{atarixl-c-xex.cfg => atarixl-xex.cfg} (100%) diff --git a/cfg/atari-asm-xex.cfg b/cfg/atari-asm-xex.cfg new file mode 100644 index 000000000..f0a6291db --- /dev/null +++ b/cfg/atari-asm-xex.cfg @@ -0,0 +1,24 @@ +FEATURES { + STARTADDRESS: default = $2E00; +} +SYMBOLS { + __STARTADDRESS__: type = export, value = %S; +} +MEMORY { + ZP: file = "", define = yes, start = $0082, size = $007E; + MAIN: file = %O, define = yes, start = %S, size = $BC20 - %S; +} +FILES { + %O: format = atari; +} +FORMATS { + atari: runad = start; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, optional = yes; + EXTZP: load = ZP, type = zp, optional = yes; # to enable modules to be able to link to C and assembler programs + CODE: load = MAIN, type = rw, define = yes; + 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/atari-c-xex.cfg b/cfg/atari-c-xex.cfg deleted file mode 100644 index 5f390e12c..000000000 --- a/cfg/atari-c-xex.cfg +++ /dev/null @@ -1,56 +0,0 @@ -# Sample linker configuration for C programs using the Atari binary file support. -# Use with: cl65 -tatari -Catari-c-xex.cfg prog.c -o prog.xex -FEATURES { - STARTADDRESS: default = $2000; -} -SYMBOLS { - __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk - __STACKSIZE__: type = weak, value = $0800; # 2k stack - __STARTADDRESS__: type = export, value = %S; - __RESERVED_MEMORY__: type = weak, value = $0000; - __SYSCHKHDR__: type = export, value = 0; # Disable system check header - __SYSCHKTRL__: type = export, value = 0; # Disable system check trailer -} -MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; -# "system check" load chunk - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; -# "main program" load chunk - MAIN: file = %O, define = yes, start = %S, size = $BC20 - __STACKSIZE__ - __RESERVED_MEMORY__ - %S; -} -FILES { - %O: format = atari; -} -FORMATS { - atari: runad = start, - initad = SYSCHKCHNK: __SYSTEM_CHECK__; -} -SEGMENTS { - ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = zp, optional = yes; - SYSCHK: load = SYSCHKCHNK, type = rw, define = yes, optional = yes; - STARTUP: load = MAIN, type = ro, define = yes; - LOWBSS: load = MAIN, type = rw, optional = yes; # not zero initialized - LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; - ONCE: load = MAIN, type = ro, optional = yes; - CODE: load = MAIN, type = ro, define = yes; - RODATA: load = MAIN, type = ro; - DATA: load = MAIN, type = rw; - INIT: load = MAIN, type = rw, optional = yes; - 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/cfg/atari-xex.cfg b/cfg/atari-xex.cfg index f0a6291db..5f390e12c 100644 --- a/cfg/atari-xex.cfg +++ b/cfg/atari-xex.cfg @@ -1,24 +1,56 @@ +# Sample linker configuration for C programs using the Atari binary file support. +# Use with: cl65 -tatari -Catari-c-xex.cfg prog.c -o prog.xex FEATURES { - STARTADDRESS: default = $2E00; + STARTADDRESS: default = $2000; } SYMBOLS { - __STARTADDRESS__: type = export, value = %S; + __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __STARTADDRESS__: type = export, value = %S; + __RESERVED_MEMORY__: type = weak, value = $0000; + __SYSCHKHDR__: type = export, value = 0; # Disable system check header + __SYSCHKTRL__: type = export, value = 0; # Disable system check trailer } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; - MAIN: file = %O, define = yes, start = %S, size = $BC20 - %S; + ZP: file = "", define = yes, start = $0082, size = $007E; +# "system check" load chunk + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; +# "main program" load chunk + MAIN: file = %O, define = yes, start = %S, size = $BC20 - __STACKSIZE__ - __RESERVED_MEMORY__ - %S; } FILES { %O: format = atari; } FORMATS { - atari: runad = start; + atari: runad = start, + initad = SYSCHKCHNK: __SYSTEM_CHECK__; } SEGMENTS { - ZEROPAGE: load = ZP, type = zp, optional = yes; - EXTZP: load = ZP, type = zp, optional = yes; # to enable modules to be able to link to C and assembler programs - CODE: load = MAIN, type = rw, define = yes; - RODATA: load = MAIN, type = ro optional = yes; - DATA: load = MAIN, type = rw optional = yes; - BSS: load = MAIN, type = bss, optional = yes, define = yes; + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; + SYSCHK: load = SYSCHKCHNK, type = rw, define = yes, optional = yes; + STARTUP: load = MAIN, type = ro, define = yes; + LOWBSS: load = MAIN, type = rw, optional = yes; # not zero initialized + LOWCODE: load = MAIN, type = ro, define = yes, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; + CODE: load = MAIN, type = ro, define = yes; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = rw, optional = yes; + 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/cfg/atarixl-c-xex.cfg b/cfg/atarixl-xex.cfg similarity index 100% rename from cfg/atarixl-c-xex.cfg rename to cfg/atarixl-xex.cfg diff --git a/doc/atari.sgml b/doc/atari.sgml index 346377b36..42b06d83e 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -203,7 +203,7 @@ is <it/left out/, keep this in mind. The values you assign to the two symbols <tt/__AUTOSTART__/ and <tt/__EXEHDR__/ don't matter. -<sect2><tt/atari-xex.cfg/<p> +<sect2><tt/atari-asm-xex.cfg/<p> This config file allows writing multi segment binaries easily, without having to write the header explicitly on each segment. @@ -213,7 +213,8 @@ format support on LD65 instead of the standard binary output, so it does not have the <tt/__AUTOSTART/ nor the <tt/__EXEHDR__/ symbols. Note that each <tt/MEMORY/ area in the configuration file will have it's own -segment in the output file with the correct headers. +segment in the output file with the correct headers, and you can specify and +init address INITAD) for each memory area. <sect2><tt/atari-cart.cfg/<p> @@ -242,6 +243,18 @@ would need to be split in more parts and the parts to be loaded manually. To write the generated file to a cassette, a utility (<tt/w2cas.com/) to run on an Atari is provided in the <tt/util/ directory of <tt/atari/ target dir. +<sect2><tt/atari-xex.cfg/<p> + +This config file shows how to write a binary using the ATARI (xex) file format +support on LD65, this simplifies the memory areas and allows to add new memory +areas easily without writing new headers and trailers. + +Note that the default C library includes the system-check chunk, so in this +linker configuration we suppress the importing of the header and trailer for +this chunk by defining the standard import symbols to a 0 value. For the +initialization address of the system-check chunk, the INITAD is set directly in +the configuration. + <sect1><tt/atarixl/ config files<p> <sect2>default config file (<tt/atarixl.cfg/)<p> @@ -265,6 +278,15 @@ The files generated by this config file include the <ref name="&dquot;system check&dquot;" id="syschkxl"> load chunk. It can optionally be left out, see <ref name="Getting rid of the &dquot;system check&dquot; load chunk" id="nosyschk">. +<sect2><tt/atarixl-xex.cfg/<p> + +Similar to the <tt/atari-xex.cfg/ above, this config file shows how to write a +binary using the ATARI (xex) file format support on LD65. + +In addition to the suppressing of the system-check headers and trailers, this +also suppresses the shadow-ram-preparation headers and trailers, but does this +by defining an "UNUSED" memory area that is not written to the output file. + <sect>Platform specific header files<p> From 01489f9ffc916c8dcdfdc80c7a185b0b2a296977 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 26 Feb 2019 18:38:05 +0100 Subject: [PATCH 1011/2161] Update cbm510.sgml There is just one CIA but it's not called "CIA1"... --- doc/cbm510.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/cbm510.sgml b/doc/cbm510.sgml index 1ec0e05d4..012a7b596 100644 --- a/doc/cbm510.sgml +++ b/doc/cbm510.sgml @@ -244,7 +244,7 @@ The default drivers, <tt/mouse_stddrv (mouse_static_stddrv)/, point to <tt/cbm51 <sect1>Realtime clock<p> -The realtime clock functions use the CIA1 TOD clock. As that clock only stores +The realtime clock functions use the CIA2 TOD clock. As that clock only stores the time but not the date, the date set by <tt/clock_settime()/ is simply stored inside the C library for retrieval in the same program via <tt/clock_gettime()/. From cc6559c3f6a81e3b4ad676c2242505466e6e9ec1 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Thu, 28 Feb 2019 17:30:34 +0100 Subject: [PATCH 1012/2161] Minor math optimizations --- libsrc/runtime/ludiv.s | 8 ++++---- libsrc/runtime/udiv32by16r16.s | 8 ++++---- libsrc/runtime/umul16x16r32.s | 4 ++-- libsrc/runtime/umul8x16r24.s | 6 ++++++ 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/libsrc/runtime/ludiv.s b/libsrc/runtime/ludiv.s index 54af4780e..8a3126d72 100644 --- a/libsrc/runtime/ludiv.s +++ b/libsrc/runtime/ludiv.s @@ -78,7 +78,7 @@ L0: asl ptr1 ; Do a subtraction. we do not have enough space to store the intermediate ; result, so we may have to do the subtraction twice. - pha + tax cmp ptr3 lda ptr2+1 sbc ptr3+1 @@ -91,9 +91,9 @@ L0: asl ptr1 ; Overflow, do the subtraction again, this time store the result sta tmp4 ; We have the high byte already - pla + txa sbc ptr3 ; byte 0 - pha + tax lda ptr2+1 sbc ptr3+1 sta ptr2+1 ; byte 1 @@ -102,7 +102,7 @@ L0: asl ptr1 sta tmp3 ; byte 2 inc ptr1 ; Set result bit -L1: pla +L1: txa dey bne L0 sta ptr2 diff --git a/libsrc/runtime/udiv32by16r16.s b/libsrc/runtime/udiv32by16r16.s index 9897f9908..27f1176dd 100644 --- a/libsrc/runtime/udiv32by16r16.s +++ b/libsrc/runtime/udiv32by16r16.s @@ -34,19 +34,19 @@ L0: asl ptr1 rol a rol sreg+1 - pha + tax cmp ptr3 lda sreg+1 sbc ptr3+1 bcc L1 sta sreg+1 - pla + txa sbc ptr3 - pha + tax inc ptr1 -L1: pla +L1: txa dey bne L0 sta sreg diff --git a/libsrc/runtime/umul16x16r32.s b/libsrc/runtime/umul16x16r32.s index 9ecd1596e..cd2dae351 100644 --- a/libsrc/runtime/umul16x16r32.s +++ b/libsrc/runtime/umul16x16r32.s @@ -42,11 +42,11 @@ umul16x16r16m: clc adc ptr3 - pha + tax lda ptr3+1 adc sreg+1 sta sreg+1 - pla + txa @L1: ror sreg+1 ror a diff --git a/libsrc/runtime/umul8x16r24.s b/libsrc/runtime/umul8x16r24.s index ff7d0bae6..c006082a4 100644 --- a/libsrc/runtime/umul8x16r24.s +++ b/libsrc/runtime/umul8x16r24.s @@ -9,6 +9,7 @@ .include "zeropage.inc" + .macpack cpu ;--------------------------------------------------------------------------- ; 8x16 => 24 unsigned multiplication routine. Because the overhead for a @@ -30,9 +31,14 @@ umul8x16r16: umul8x16r24m: umul8x16r16m: +.if (.cpu .bitand ::CPU_ISET_65SC02) + stz ptr1+1 + stz sreg +.else ldx #0 stx ptr1+1 stx sreg +.endif ldy #8 ; Number of bits ldx ptr3 ; Get into register for speed From 8ead5f2f5a1bedf9439256428764ba5c68aaeb40 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sun, 3 Mar 2019 22:50:57 +0100 Subject: [PATCH 1013/2161] Access Atari OS variables by structure. --- doc/atari.sgml | 23 +- include/_atarios.h | 655 +++++++++++++++++++++++++++++++++++++++++++++ include/atari.h | 130 +-------- 3 files changed, 680 insertions(+), 128 deletions(-) create mode 100644 include/_atarios.h diff --git a/doc/atari.sgml b/doc/atari.sgml index 42b06d83e..49993d22c 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -293,6 +293,25 @@ by defining an "UNUSED" memory area that is not written to the output file. Programs containing Atari specific code may use the <tt/atari.h/ header file. +This also includes access to operating system locations (e.g. hardware shadow registers) by a structure called +"<tt/OS/". +The names are the usual ones you can find in system reference manuals. Example: + +<verb> +... + OS.savmsc = ScreenMemory; + OS.color4 = 14; // white frame + if (OS.stick0 != 15 || OS.ch != 255) // key or stick input? +... +</verb> + +Please note that memory location 762/$2FA is called "<tt/char_/" while the orignal name "<tt/char/" conflicts with the C keyword. + +If you like to use the OS names and locations for the original Atari 800 operating system, please "<tt/#define OSA/" before including the +<tt/atari.h/ header file. +If you like to target the floating point register model of revision 2 machines, put a "<tt/#define OS_REV2/" before including <tt/atari.h/. + +Access to the Basic programming language zero page variables is established by the structure "<tt/BASIC/". <sect1>Atari specific functions<p> @@ -376,7 +395,7 @@ void DisplayList = DL_JVB }; ... -POKEW(560,(unsigned int)&DisplayList); // SDLSTL +OS.sdlst = &DisplayList; ... </verb> @@ -454,7 +473,7 @@ Example: <verb> ... while (!kbhit()); - switch (PEEK(764)) + switch (OS.ch) { case KEY_RETURN: ... diff --git a/include/_atarios.h b/include/_atarios.h new file mode 100644 index 000000000..89fcfea9b --- /dev/null +++ b/include/_atarios.h @@ -0,0 +1,655 @@ +/*****************************************************************************/ +/* */ +/* _atarios.h */ +/* */ +/* Internal include file, do not use directly */ +/* */ +/* */ +/* 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 __ATARIOS_H +#define __ATARIOS_H + + +/* IOCB Command Codes */ + +#define IOCB_OPEN 0x03 /* open */ +#define IOCB_GETREC 0x05 /* get record */ +#define IOCB_GETCHR 0x07 /* get character(s) */ +#define IOCB_PUTREC 0x09 /* put record */ +#define IOCB_PUTCHR 0x0B /* put character(s) */ +#define IOCB_CLOSE 0x0C /* close */ +#define IOCB_STATIS 0x0D /* status */ +#define IOCB_SPECIL 0x0E /* special */ +#define IOCB_DRAWLN 0x11 /* draw line */ +#define IOCB_FILLIN 0x12 /* draw line with right fill */ +#define IOCB_RENAME 0x20 /* rename disk file */ +#define IOCB_DELETE 0x21 /* delete disk file */ +#define IOCB_LOCKFL 0x23 /* lock file (set to read-only) */ +#define IOCB_UNLOCK 0x24 /* unlock file */ +#define IOCB_POINT 0x25 /* point sector */ +#define IOCB_NOTE 0x26 /* note sector */ +#define IOCB_GETFL 0x27 /* get file length */ +#define IOCB_CHDIR_MYDOS 0x29 /* change directory (MyDOS) */ +#define IOCB_MKDIR 0x2A /* make directory (MyDOS/SpartaDOS) */ +#define IOCB_RMDIR 0x2B /* remove directory (SpartaDOS) */ +#define IOCB_CHDIR_SPDOS 0x2C /* change directory (SpartaDOS) */ +#define IOCB_GETCWD 0x30 /* get current directory (MyDOS/SpartaDOS) */ +#define IOCB_FORMAT 0xFE /* format */ + + +/* I/O control block */ + +typedef struct { + unsigned char handler; /* handler index number (0xff free) */ + unsigned char drive; /* device number (drive) */ + unsigned char command; /* command */ + unsigned char status; /* status of last operation */ + void* buffer; /* pointer to buffer */ + void* put_byte; /* pointer to device's PUT BYTE routine */ + unsigned int buflen; /* length of buffer */ + unsigned char aux1; /* 1st auxiliary byte */ + unsigned char aux2; /* 2nd auxiliary byte */ + unsigned char aux3; /* 3rd auxiliary byte */ + unsigned char aux4; /* 4th auxiliary byte */ + unsigned char aux5; /* 5th auxiliary byte */ + unsigned char spare; /* spare byte */ +} IOCB; + + +/* DOS 2.x zeropage variables */ + +typedef struct { + unsigned char* zbufp; /* points to user filename */ + unsigned char* zdrva; /* points to serveral buffers (mostly VTOC) */ + unsigned char* zsba; /* points to sector buffer */ + unsigned char errno; /* number of occured error */ +} DOS2X; + + +/* A single device handler formed by it's routines */ + +typedef struct { + void *open; /* address of OPEN routine -1 */ + void *close; /* address of CLOSE routine -1 */ + void *get; /* address of GET BYTE routine -1 */ + void *put; /* address of PUT BYTE routine -1 */ + void *status; /* address of GET STATUS routine -1 */ + void *special; /* address od SPECIAL routine -1 */ + void (*init)(void); /* init routine (JMP INIT) */ + void *reserved; /* unused */ +} DEVHDL; + + +/* List of device handlers, as managed in HATABS */ + +typedef struct { + unsigned char id; /* ATASCII code of handler e.g. 'C','D','E','K','P','S','R' */ + DEVHDL* devhdl; /* Pointer to routines of device */ +} HATABS; + +/* Floating point register */ + +typedef struct { +#ifdef OS_REV2 + unsigned char fr; + unsigned char frm[5]; /* 5-byte register mantissa */ +#else + unsigned char fr[6]; /* 6 bytes for single register */ +#endif +} FPREG; + +enum { /* enum for access of floating point registers */ + R0 = 0, /* (to use as index) */ + RE = 1, + R1 = 2, + R2 = 3 +} FPIDX; + + +/* Define a structure with atari os register offsets */ + +struct __os { + + // --- Zero-Page --- + +#ifdef OSA + unsigned char* linzbs; // = $00/$01 LINBUG RAM (WILL BE REPLACED BY MONITOR RAM) +#else + unsigned char linflg; // = $00 LNBUG FLAG (0 = NOT LNBUG) + unsigned char ngflag; // = $01 MEMORY STATUS (0 = FAILURE) +#endif + unsigned char* casini; // = $02/$03 CASSETTE INIT LOCATION + unsigned char* ramlo; // = $04/$05 RAM POINTER FOR MEMORY TEST + +#ifdef OSA + unsigned char tramsz; // = $06 FLAG FOR LEFT CARTRIDGE + unsigned char tstdat; // = $07 FLAG FOR RIGHT CARTRIDGE +#else + unsigned char trnsmz; // = $06 TEMPORARY REGISTER FOR RAM SIZE + unsigned char tstdat; // = $07 UNUSED (NOT TOUCHED DURING RESET/COLD START) +#endif + + // Cleared upon Coldstart only + + unsigned char warmst; // = $08 WARM START FLAG + unsigned char bootq; // = $09 SUCCESSFUL BOOT FLAG + void (*dosvec)(void); // = $0A/$0B DISK SOFTWARE START VECTOR + void (*dosini)(void); // = $0C/$0D DISK SOFTWARE INIT ADDRESS + unsigned char* appmhi; // = $0E/$0F APPLICATIONS MEMORY HI LIMIT + + // Cleared upon Coldstart or Warmstart + + unsigned char pokmsk; // = $10 SYSTEM MASK FOR POKEY IRQ ENABLE + unsigned char brkkey; // = $11 BREAK KEY FLAG + unsigned char rtclok[3]; // = $12-$14 REAL TIME CLOCK (IN 16 MSEC UNITS) + unsigned char* bufadr; // = $15/$16 INDIRECT BUFFER ADDRESS REGISTER + unsigned char iccomt; // = $17 COMMAND FOR VECTOR + unsigned char* dskfms; // = $18/$19 DISK FILE MANAGER POINTER + unsigned char* dskutl; // = $1A/$1B DISK UTILITIES POINTER +#ifdef OSA + unsigned char ptimot; // = $1C PRINTER TIME OUT REGISTER + unsigned char pbpnt; // = $1D PRINT BUFFER POINTER + unsigned char pbufsz; // = $1E PRINT BUFFER SIZE + unsigned char ptemp; // = $1F TEMPORARY REGISTER +#else + unsigned char abufpt[4]; // = $1C-$1F ACMI BUFFER POINTER AREA +#endif + IOCB ziocb; // = $20-$2F ZERO PAGE I/O CONTROL BLOCK + + unsigned char status; // = $30 INTERNAL STATUS STORAGE + unsigned char chksum; // = $31 CHECKSUM (SINGLE BYTE SUM WITH CARRY) + unsigned char* bufr; // = $32/$33 POINTER TO DATA BUFFER + unsigned char* bfen; // = $34/$35 NEXT BYTE PAST END OF THE DATA BUFFER LO +#ifdef OSA + unsigned char cretry; // = $36 NUMBER OF COMMAND FRAME RETRIES + unsigned char dretry; // = $37 NUMBER OF DEVICE RETRIES +#else + unsigned int ltemp; // = $36/$37 LOADER TEMPORARY +#endif + unsigned char bufrfl; // = $38 DATA BUFFER FULL FLAG + unsigned char recvdn; // = $39 RECEIVE DONE FLAG + unsigned char xmtdon; // = $3A TRANSMISSION DONE FLAG + unsigned char chksnt; // = $3B CHECKSUM SENT FLAG + unsigned char nocksm; // = $3C NO CHECKSUM FOLLOWS DATA FLAG + unsigned char bptr; // = $3D CASSETTE BUFFER POINTER + unsigned char ftype; // = $3E CASSETTE IRG TYPE + unsigned char feof; // = $3F CASSETTE EOF FLAG (0 // = QUIET) + + unsigned char freq; // = $40 CASSETTE BEEP COUNTER + unsigned char soundr; // = $41 NOISY I/0 FLAG. (ZERO IS QUIET) + unsigned char critic; // = $42 DEFINES CRITICAL SECTION (CRITICAL IF NON-Z) + DOS2X fmszpg; // = $43-$49 DISK FILE MANAGER SYSTEM ZERO PAGE +#ifdef OSA + unsigned char ckey; // = $4A FLAG SET WHEN GAME START PRESSED + unsigned char cassbt; // = $4B CASSETTE BOOT FLAG +#else + void* zchain; // = $4A/$4B HANDLER LINKAGE CHAIN POINTER +#endif + unsigned char dstat; // = $4C DISPLAY STATUS + unsigned char atract; // = $4D ATRACT FLAG + unsigned char drkmsk; // = $4E DARK ATRACT MASK + unsigned char colrsh; // = $4F ATRACT COLOR SHIFTER (EOR'ED WITH PLAYFIELD + + unsigned char tmpchr; // = $50 TEMPORARY CHARACTER + unsigned char hold1; // = $51 TEMPORARY + unsigned char lmargn; // = $52 LEFT MARGIN (NORMALLY 2, CC65 C STARTUP CODE SETS IT TO 0) + unsigned char rmargn; // = $53 RIGHT MARGIN (NORMALLY 39 IF NO XEP80 IS USED) + unsigned char rowcrs; // = $54 1CURSOR ROW + unsigned int colcrs; // = $55/$56 CURSOR COLUMN + unsigned char dindex; // = $57 DISPLAY MODE + unsigned char* savmsc; // = $58/$59 SAVED MEMORY SCAN COUNTER + unsigned char oldrow; // = $5A PRIOR ROW + unsigned int oldcol; // = $5B/$5C PRIOR COLUMN + unsigned char oldchr; // = $5D DATA UNDER CURSOR + unsigned char* oldadr; // = $5E/$5F SAVED CURSOR MEMORY ADDRESS + +#ifdef OSA + unsigned char newrow; // = $60 POINT DRAW GOES TO + unsigned int newcol; // = $61/$62 COLUMN DRAW GOES TO +#else + unsigned char* fkdef; // = $60/$61 FUNCTION KEY DEFINITION TABLE + unsigned char palnts; // = $62 PAL/NTSC INDICATOR (0 // = NTSC) +#endif + unsigned char logcol; // = $63 POINTS AT COLUMN IN LOGICAL LINE + unsigned char* adress; // = $64/$65 TEMPORARY ADDRESS + unsigned int mlttmp; // = $66/$67 TEMPORARY / FIRST BYTE IS USED IN OPEN AS TEMP + unsigned int savadr; // = $68/$69 SAVED ADDRESS + unsigned char ramtop; // = $6A RAM SIZE DEFINED BY POWER ON LOGIC + unsigned char bufcnt; // = $6B BUFFER COUNT + unsigned char* bufstr; // = $6C/$6D EDITOR GETCH POINTER + unsigned char bitmsk; // = $6E BIT MASK + unsigned char shfamt; // = $6F SHIFT AMOUNT FOR PIXEL JUSTIFUCATION + + unsigned int rowac; // = $70/$71 DRAW WORKING ROW + unsigned int colac; // = $72/$73 DRAW WORKING COLUMN + unsigned char* endpt; // = $74/$75 END POINT + unsigned char deltar; // = $76 ROW DIFFERENCE + unsigned int deltac; // = $77/$78 COLUMN DIFFERENCE +#ifdef OSA + unsigned char rowinc; // = $79 ROWINC + unsigned char colinc; // = $7A COLINC +#else + unsigned char* keydef; // = $79/$7A 2-BYTE KEY DEFINITION TABLE ADDRESS +#endif + unsigned char swpflg; // = $7B NON-0 1F TXT AND REGULAR RAM IS SWAPPED + unsigned char holdch; // = $7C CH IS MOVED HERE IN KGETCH BEFORE CNTL & SH + unsigned char insdat; // = $7D 1-BYTE TEMPORARY + unsigned int countr; // = $7E/$7F 2-BYTE DRAW ITERATION COUNT + + unsigned char _free_1[0xD4-0x7F-1]; // USER SPACE + + // Floating Point Package Page Zero Address Equates + FPREG fpreg[4]; // = $D4-$EB 4 REGSITERS, ACCCESS LIKE "fpreg[R0].fr" + unsigned char frx; // = $EC 1-BYTE TEMPORARY + unsigned char eexp; // = $ED VALUE OF EXP +#ifdef OS_REV2 + unsigned char frsign; // = $EE ##REV2## 1-BYTE FLOATING POINT SIGN + unsigned char plycnt; // = $EF ##REV2## 1-BYTE POLYNOMIAL DEGREE + unsigned char sgnflg; // = $F0 ##REV2## 1-BYTE SIGN FLAG + unsigned char xfmflg; // = $F1 ##REV2## 1-BYTE TRANSFORM FLAG +#else + unsigned char nsign; // = $EE SIGN OF # + unsigned char esign; // = $EF SIGN OF EXPONENT + unsigned char fchrflg; // = $F0 1ST CHAR FLAG + unsigned char digrt; // = $F1 # OF DIGITS RIGHT OF DECIMAL +#endif + unsigned char cix; // = $F2 CURRENT INPUT INDEX + unsigned char* inbuff; // = $F3/$F4 POINTS TO USER'S LINE INPUT BUFFER + unsigned int ztemp1; // = $F5/$F6 2-BYTE TEMPORARY + unsigned int ztemp4; // = $F7/$F8 2-BYTE TEMPORARY + unsigned int ztemp3; // = $F9/$FA 2-BYTE TEMPORARY + + union { + unsigned char degflg; // = $FB ##OLD## SAME AS RADFLG + unsigned char radflg; // = $FB ##OLD## 0=RADIANS, 6=DEGREES + }; + + FPREG* flptr; // = $FC/$FD 2-BYTE FLOATING POINT NUMBER POINTER + FPREG* fptr2; // = $FE/$FF 2-BYTE FLOATING POINT NUMBER POINTER + + // --- Page 1 --- + + unsigned char stack[0x100]; // STACK + + // --- Page 2 --- + + void (*vdslst)(void); // = $0200/$0201 DISPLAY LIST NMI VECTOR + void (*vprced)(void); // = $0202/$0203 PROCEED LINE IRQ VECTOR + void (*vinter)(void); // = $0204/$0205 INTERRUPT LINE IRQ VECTOR + void (*vbreak)(void); // = $0206/$0207 SOFTWARE BREAK (00) INSTRUCTION IRQ VECTOR + void (*vkeybd)(void); // = $0208/$0209 POKEY KEYBOARD IRQ VECTOR + void (*vserin)(void); // = $020A/$020B POKEY SERIAL INPUT READY IRQ + void (*vseror)(void); // = $020C/$020D POKEY SERIAL OUTPUT READY IRQ + void (*vseroc)(void); // = $020E/$020F POKEY SERIAL OUTPUT COMPLETE IRQ + void (*vtimr1)(void); // = $0210/$0201 POKEY TIMER 1 IRQ + void (*vtimr2)(void); // = $0212/$0203 POKEY TIMER 2 IRQ + void (*vtimr4)(void); // = $0214/$0205 POKEY TIMER 4 IRQ + void (*vimirq)(void); // = $0216/$0207 IMMEDIATE IRQ VECTOR + unsigned int cdtmv1; // = $0218/$0210 COUNT DOWN TIMER 1 + unsigned int cdtmv2; // = $021A/$021B COUNT DOWN TIMER 2 + unsigned int cdtmv3; // = $021C/$021D COUNT DOWN TIMER 3 + unsigned int cdtmv4; // = $021E/$021F COUNT DOWN TIMER 4 + unsigned int cdtmv5; // = $0220/$0221 COUNT DOWN TIMER 5 + void (*vvblki)(void); // = $0222/$0223 IMMEDIATE VERTICAL BLANK NMI VECTOR + void (*vvblkd)(void); // = $0224/$0224 DEFERRED VERTICAL BLANK NMI VECTOR + void (*cdtma1)(void); // = $0226/$0227 COUNT DOWN TIMER 1 JSR ADDRESS + void (*cdtma2)(void); // = $0228/$0229 COUNT DOWN TIMER 2 JSR ADDRESS + unsigned char cdtmf3; // = $022A COUNT DOWN TIMER 3 FLAG + unsigned char srtimr; // = $022B SOFTWARE REPEAT TIMER + unsigned char cdtmf4; // = $022C COUNT DOWN TIMER 4 FLAG + unsigned char intemp; // = $022D IAN'S TEMP + unsigned char cdtmf5; // = $022E COUNT DOWN TIMER FLAG 5 + unsigned char sdmctl; // = $022F SAVE DMACTL REGISTER + union { + struct { + unsigned char sdlstl; // = $0230 SAVE DISPLAY LIST LOW BYTE + unsigned char sdlsth; // = $0231 SAVE DISPLAY LIST HI BYTE + }; + void* sdlst; // = $0230/$0231 (same as above as pointer) + }; + unsigned char sskctl; // = $0232 SKCTL REGISTER RAM +#ifdef OSA + unsigned char _spare_1; // = $0233 No OS use. +#else + unsigned char lcount; // = $0233 ##1200xl## 1-byte relocating loader record +#endif + unsigned char lpenh; // = $0234 LIGHT PEN HORIZONTAL VALUE + unsigned char lpenv; // = $0235 LIGHT PEN VERTICAL VALUE + void (*brkky)(void); // = $0236/$0237 BREAK KEY VECTOR +#ifdef OSA + unsigned char spare2[2]; // = $0238/$0239 No OS use. +#else + void (*vpirq)(void); // = $0238/$0239 ##rev2## 2-byte parallel device IRQ vector +#endif + unsigned char cdevic; // = $023A COMMAND FRAME BUFFER - DEVICE + unsigned char ccomnd; // = $023B COMMAND + union { + struct { + unsigned char caux1; // = $023C COMMAND AUX BYTE 1 + unsigned char caux2; // = $023D COMMAND AUX BYTE 2 + }; + unsigned caux; // = $023C/$023D (same as above as word) + }; + unsigned char temp; // = $023E TEMPORARY RAM CELL + unsigned char errflg; // = $023F ERROR FLAG - ANY DEVICE ERROR EXCEPT TIME OUT + unsigned char dflags; // = $0240 DISK FLAGS FROM SECTOR ONE + unsigned char dbsect; // = $0241 NUMBER OF DISK BOOT SECTORS + unsigned char* bootad; // = $0242/$0243 ADDRESS WHERE DISK BOOT LOADER WILL BE PUT + unsigned char coldst; // = $0244 COLDSTART FLAG (1=IN MIDDLE OF COLDSTART> +#ifdef OSA + unsigned char spare3; // = $0245 No OS use. +#else + unsigned char reclen; // = $0245 ##1200xl## 1-byte relocating loader record length +#endif + unsigned char dsktim; // = $0246 DISK TIME OUT REGISTER +#ifdef OSA + unsigned char linbuf[40]; // = $0247-$026E ##old## CHAR LINE BUFFER +#else + unsigned char pdvmsk; // = $0247 ##rev2## 1-byte parallel device selection mask + unsigned char shpdvs; // = $0248 ##rev2## 1-byte PDVS (parallel device select) + unsigned char pdimsk; // = $0249 ##rev2## 1-byte parallel device IRQ selection + unsigned reladr; // = $024A/$024B ##rev2## 2-byte relocating loader relative adr. + unsigned char pptmpa; // = $024C ##rev2## 1-byte parallel device handler temporary + unsigned char pptmpx; // = $024D ##rev2## 1-byte parallel device handler temporary + unsigned char _reserved_1[29]; // = $024E-$026A RESERVED + unsigned char chsalt; // = $026B ##1200xl## 1-byte character set alternate + unsigned char vsflag; // = $026C ##1200xl## 1-byte fine vertical scroll count + unsigned char keydis; // = $026D ##1200xl## 1-byte keyboard disable + unsigned char fine; // = $026E ##1200xl## 1-byte fine scrolling mode +#endif + unsigned char gprior; // = $026F GLOBAL PRIORITY CELL + unsigned char paddl0; // = $0270 1-BYTE POTENTIOMETER 0 + unsigned char paddl1; // = $0271 1-BYTE POTENTIOMETER 1 + unsigned char paddl2; // = $0272 1-BYTE POTENTIOMETER 2 + unsigned char paddl3; // = $0273 1-BYTE POTENTIOMETER 3 + unsigned char paddl4; // = $0274 1-BYTE POTENTIOMETER 4 + unsigned char paddl5; // = $0275 1-BYTE POTENTIOMETER 5 + unsigned char paddl6; // = $0276 1-BYTE POTENTIOMETER 6 + unsigned char paddl7; // = $0277 1-BYTE POTENTIOMETER 7 + unsigned char stick0; // = $0278 1-byte joystick 0 + unsigned char stick1; // = $0279 1-byte joystick 1 + unsigned char stick2; // = $027A 1-byte joystick 2 + unsigned char stick3; // = $027B 1-byte joystick 3 + unsigned char ptrig0; // = $027C 1-BYTE PADDLE TRIGGER 0 + unsigned char ptrig1; // = $027D 1-BYTE PADDLE TRIGGER 1 + unsigned char ptrig2; // = $027E 1-BYTE PADDLE TRIGGER 2 + unsigned char ptrig3; // = $027F 1-BYTE PADDLE TRIGGER 3 + unsigned char ptrig4; // = $0280 1-BYTE PADDLE TRIGGER 4 + unsigned char ptrig5; // = $0281 1-BYTE PADDLE TRIGGER 5 + unsigned char ptrig6; // = $0281 1-BYTE PADDLE TRIGGER 6 + unsigned char ptrig7; // = $0283 1-BYTE PADDLE TRIGGER 7 + unsigned char strig0; // = $0284 1-BYTE JOYSTICK TRIGGER 0 + unsigned char strig1; // = $0285 1-BYTE JOYSTICK TRIGGER 1 + unsigned char strig2; // = $0286 1-BYTE JOYSTICK TRIGGER 2 + unsigned char strig3; // = $0287 1-BYTE JOYSTICK TRIGGER 3 +#ifdef OSA + unsigned char cstat; // = $0288 ##old## cassette status register +#else + unsigned char hibyte; // = $0288 ##1200xl## 1-byte relocating loader high byte +#endif + unsigned char wmode; // = $0289 1-byte cassette WRITE mode + unsigned char blim; // = $028A 1-byte cassette buffer limit +#ifdef OSA + unsigned char _reserved_2[5]; // = $028B-$028F RESERVED +#else + unsigned char imask; // = $028B ##rev2## (not used) + void (*jveck)(void); // = $028C/$028D 2-byte jump vector + unsigned newadr; // = $028E/028F ##1200xl## 2-byte relocating address +#endif + unsigned char txtrow; // = $0290 TEXT ROWCRS + unsigned txtcol; // = $0291/$0292 TEXT COLCRS + unsigned char tindex; // = $0293 TEXT INDEX + unsigned char* txtmsc; // = $0294/$0295 FOOLS CONVRT INTO NEW MSC + unsigned char txtold[6]; // = $0296-$029B OLDROW & OLDCOL FOR TEXT (AND THEN SOME) +#ifdef OSA + unsigned char tmpx1; // = $029C ##old## 1--byte temporary register +#else + unsigned char cretry; // = $029C ##1200xl## 1-byte number of command frame retries +#endif + unsigned char hold3; // = $029D 1-byte temporary + unsigned char subtmp; // = $029E 1-byte temporary + unsigned char hold2; // = $029F 1-byte (not used) + unsigned char dmask; // = $02A0 1-byte display (pixel location) mask + unsigned char tmplbt; // = $02A1 1-byte (not used) + unsigned char escflg; // = $02A2 ESCAPE FLAG + unsigned char tabmap[15]; // = $02A3-$02B1 15-byte (120 bit) tab stop bit map + unsigned char logmap[4]; // = $02B2-$02B5 LOGICAL LINE START BIT MAP + unsigned char invflg; // = $02B6 INVERSE VIDEO FLAG (TOGGLED BY ATARI KEY) + unsigned char filflg; // = $02B7 RIGHT FILL FLAG FOR DRAW + unsigned char tmprow; // = $02B8 1-byte temporary row + unsigned tmpcol; // = $02B9/$02BA 2-byte temporary column + unsigned char scrflg; // = $02BB SET IF SCROLL OCCURS + unsigned char hold4; // = $02BC TEMP CELL USED IN DRAW ONLY +#ifdef OSA + unsigned char hold5; // = $02BD ##old## DITTO +#else + unsigned char dretry; // = $02BD ##1200xl## 1-byte number of device retries +#endif + unsigned char shflok; // = $02BE 1-byte shift/control lock flags + unsigned char botscr; // = $02BF BOTTOM OF SCREEN 24 NORM 4 SPLIT + unsigned char pcolr0; // = $02C0 1-byte player-missile 0 color/luminance + unsigned char pcolr1; // = $02C1 1-byte player-missile 1 color/luminance + unsigned char pcolr2; // = $02C2 1-byte player-missile 2 color/luminance + unsigned char pcolr3; // = $02C3 1-byte player-missile 3 color/luminance + unsigned char color0; // = $02C4 1-byte playfield 0 color/luminance + unsigned char color1; // = $02C5 1-byte playfield 1 color/luminance + unsigned char color2; // = $02C6 1-byte playfield 2 color/luminance + unsigned char color3; // = $02C7 1-byte playfield 3 color/luminance + unsigned char color4; // = $02C8 1-byte background color/luminance +#ifdef OSA + unsigned char _spare_2[23]; // = $02C9-$02DF No OS use. +#else + union { + unsigned char parmbl[6]; // = $02C9 ##rev2## 6-byte relocating loader parameter + struct { + void (*runadr)(void); // = $02C9 ##1200xl## 2-byte run address + unsigned int hiused; // = $02CB ##1200xl## 2-byte highest non-zero page address + unsigned int zhiuse; // = $02CD ##1200xl## 2-byte highest zero page address + }; + }; + union { + unsigned char oldpar[6]; // = $02CF ##rev2## 6-byte relocating loader parameter + struct { + void (*gbytea)(void); // = $02CF ##1200xl## 2-byte GET-BYTE routine address + unsigned int loadad; // = $02D1 ##1200xl## 2-byte non-zero page load address + unsigned int zloada; // = $02D3 ##1200xl## 2-byte zero page load address + }; + }; + unsigned int dsctln; // = $02D5 ##1200xl## 2-byte disk sector length + unsigned int acmisr; // = $02D7 ##1200xl## 2-byte ACMI interrupt service routine + unsigned char krpdel; // = $02D9 ##1200xl## 1-byte auto-repeat delay + unsigned char keyrep; // = $02DA ##1200xl## 1-byte auto-repeat rate + unsigned char noclik; // = $02DB ##1200xl## 1-byte key click disable + unsigned char helpfg; // = $02DC ##1200xl## 1-byte HELP key flag (0 = no HELP) + unsigned char dmasav; // = $02DD ##1200xl## 1-byte SDMCTL save/restore + unsigned char pbpnt; // = $02DE ##1200xl## 1-byte printer buffer pointer + unsigned char pbufsz; // = $02DF ##1200xl## 1-byte printer buffer size +#endif + union { + unsigned char glbabs[4]; // = $02E0-$02E3 byte global variables for non-DOS users + struct { + void (*runad)(void); // = $02E0 ##map## 2-byte binary file run address + void (*initad)(void); // = $02E2 ##map## 2-byte binary file initialization address + }; + }; + unsigned char ramsiz; // = $02E4 RAM SIZE (HI BYTE ONLY) + void* memtop; // = $02E5 TOP OF AVAILABLE USER MEMORY + void* memlo; // = $02E7 BOTTOM OF AVAILABLE USER MEMORY +#ifdef OSA + unsigned char _spare_3; // = $02E9 No OS use. +#else + unsigned char hndlod; // = $02E9 ##1200xl## 1-byte user load flag +#endif + unsigned char dvstat[4]; // = $02EA-$02ED STATUS BUFFER + union { + unsigned int cbaud; // = $02EE/$02EF 2-byte cassette baud rate + struct { + unsigned char cbaudl; // = $02EE 1-byte low cassette baud rate + unsigned char cbaudh; // = $02EF 1-byte high cassette baud rate + }; + }; + unsigned char crsinh; // = $02F0 CURSOR INHIBIT (00 = CURSOR ON) + unsigned char keydel; // = $02F1 KEY DELAY + unsigned char ch1; // = $02F2 1-byte prior keyboard character + unsigned char chact; // = $02F3 CHACTL REGISTER RAM + unsigned char chbas; // = $02F4 CHBAS REGISTER RAM +#ifdef OSA + unsigned char _spare_4[5]; // = $02F5-$02F9 No OS use. +#else + unsigned char newrow; // = $02F5 ##1200xl## 1-byte draw destination row + unsigned int newcol; // = $02F6/$02F7 ##1200xl## 2-byte draw destination column + unsigned char rowinc; // = $02F8 ##1200xl## 1-byte draw row increment + unsigned char colinc; // = $02F9 ##1200xl## 1-byte draw column increment +#endif + unsigned char char_; // = $02FA 1-byte internal character (naming changed due to do keyword conflict) + unsigned char atachr; // = $02FB ATASCII CHARACTER + unsigned char ch; // = $02FC GLOBAL VARIABLE FOR KEYBOARD + unsigned char fildat; // = $02FD RIGHT FILL DATA <DRAW> + unsigned char dspflg; // = $02FE DISPLAY FLAG DISPLAY CNTLS IF NON-ZERO + unsigned char ssflag; // = $02FF START/STOP FLAG FOR PAGING (CNTL 1). CLEARE + + // --- Page 3 --- + + union { + unsigned char dcb[0x40]; // = $0300-$03XX DEVICE CONTROL BLOCK + struct { + unsigned char ddevic; // = $0300 PERIPHERAL UNIT 1 BUS I.D. NUMBER + unsigned char dunit; // = $0301 UNIT NUMBER + unsigned char dcomnd; // = $0302 BUS COMMAND + unsigned char dstats; // = $0303 COMMAND TYPE/STATUS RETURN + union { + void* dbuf; // = $0304/$0305 data buffer address + struct { + unsigned char dbuflo; // = $0304 1-byte low data buffer address + unsigned char dbufhi; // = $0305 1-byte high data buffer address + }; + }; + unsigned char dtimlo; // = $0306 DEVICE TIME OUT IN 1 SECOND UNITS + unsigned char dunuse; // = $0307 UNUSED BYTE + union { + unsigned int dbyt; // = $0308/$0309 number of bytes to transfer + struct { + unsigned char dbytlo; // = $0308 1-byte low number of bytes to transfer + unsigned char dbythi; // = $0309 1-byte high number of bytes to transfer + }; + }; + union { + unsigned int daux; // = $030A/$030B first and second auxiliary + struct { + unsigned char daux1; // = $030A 1-byte first command auxiliary + unsigned char daux2; // = $030B 1-byte second command auxiliary + }; + }; + unsigned int timer1; // = $030C/$030D INITIAL TIMER VALUE +#ifdef OSA + unsigned char addcor; // = $030E ##old## ADDITION CORRECTION +#else + unsigned char jmpers; // = $030E ##1200xl## 1-byte jumper options +#endif + unsigned char casflg; // = $030F CASSETTE MODE WHEN SET + unsigned char timer2; // = $0310/$0311 2-byte final baud rate timer value + unsigned char temp1; // = $0312 TEMPORARY STORAGE REGISTER +#ifdef OSA + unsigned char _spare_5; // = $0313 unused + unsigned char temp2; // = $0314 ##old## TEMPORARY STORAGE REGISTER +#else + unsigned char temp2; // = $0313 ##1200xl## 1-byte temporary + unsigned char ptimot; // = $0314 ##1200xl## 1-byte printer timeout +#endif + unsigned char temp3; // = $0315 TEMPORARY STORAGE REGISTER + unsigned char savio; // = $0316 SAVE SERIAL IN DATA PORT + unsigned char timflg; // = $0317 TIME OUT FLAG FOR BAUD RATE CORRECTION + unsigned char stackp; // = $0318 SIO STACK POINTER SAVE CELL + unsigned char tstat; // = $0319 TEMPORARY STATUS HOLDER +#ifdef OSA + HATABS hatabs[12]; // = $031A-$033D handler address table + unsigned int zeropad; // = $033E/$033F zero padding +#else + HATABS hatabs[11]; // = $031A-$033A handler address table + unsigned int zeropad; // = $033B/$033C zero padding + unsigned char pupbt1; // = $033D ##1200xl## 1-byte power-up validation byte 1 + unsigned char pupbt2; // = $033E ##1200xl## 1-byte power-up validation byte 2 + unsigned char pupbt3; // = $033F ##1200xl## 1-byte power-up validation byte 3 +#endif + }; + }; + IOCB iocb[8]; // = $0340-$03BF 8 I/O Control Blocks + unsigned char prnbuf[40]; // = $03C0-$3E7 PRINTER BUFFER +#ifdef OSA + unsigned char _spare_6[151]; // = $03E8-$047F unused +#else + unsigned char superf; // = $03E8 ##1200xl## 1-byte editor super function flag + unsigned char ckey; // = $03E9 ##1200xl## 1-byte cassette boot request flag + unsigned char cassbt; // = $03EA ##1200xl## 1-byte cassette boot flag + unsigned char cartck; // = $03EB ##1200xl## 1-byte cartridge equivalence check + unsigned char derrf; // = $03EC ##rev2## 1-byte screen OPEN error flag + unsigned char acmvar[11]; // = $03ED-$03F7 ##1200xl## reserved for ACMI, not cleared upon reset + unsigned char basicf; // = $03F8 ##rev2## 1-byte BASIC switch flag + unsigned char mintlk; // = $03F9 ##1200xl## 1-byte ACMI module interlock + unsigned char gintlk; // = $03FA ##1200xl## 1-byte cartridge interlock + void* chlink; // = $03FB/$03FC ##1200xl## 2-byte loaded handler chain link + unsigned char casbuf[131]; // = $03FD-$047F CASSETTE BUFFER +#endif + + // --- Page 4 --- + + unsigned char usarea[128]; // = $0480 128 bytes reserved for application + + // --- Page 5 --- + + unsigned char _spare_7[126]; // = $0500-$057D reserved for FP package / unused + unsigned char lbpr1; // = $057E LBUFF PREFIX 1 + unsigned char lbpr2; // = $057F LBUFF PREFIX 2 + unsigned char lbuff[128]; // = $0580-$05FF 128-byte line buffer +}; + + +/* Define a structure with the zero page atari basic register offsets */ + +struct __basic { + void* lowmem; // = $80/$81 POINTER TO BASIC'S LOW MEMORY + void* vntp; // = $82/$83 BEGINNING ADDRESS OF THE VARIABLE NAME TABLE + void* vntd; // = $84/$85 POINTER TO THE ENDING ADDRESS OF THE VARIABLE NAME TABLE PLUS ONE + void* vvtp; // = $86/$87 ADDRESS FOR THE VARIABLE VALUE TABLE + void* stmtab; // = $88/$89 ADDRESS OF THE STATEMENT TABLE + void* stmcur; // = $8A/$8B CURRENT BASIC STATEMENT POINTER + void* starp; // = $8C/$8D ADDRESS FOR THE STRING AND ARRAY TABLE + void* runstk; // = $8E/$8F ADDRESS OF THE RUNTIME STACK + void* memtop; // = $90/$91 POINTER TO THE TOP OF BASIC MEMORY + + unsigned char _internal_1[0xBA-0x91-1]; // INTERNAL DATA + + unsigned int stopln; // = $BA/$BB LINE WHERE A PROGRAM WAS STOPPED + + unsigned char _internal_2[0xC3-0xBB-1]; // INTERNAL DATA + + unsigned char errsav; // = $C3 NUMBER OF THE ERROR CODE + + unsigned char _internal_3[0xC9-0xC3-1]; // INTERNAL DATA + + unsigned char ptabw; // = $C9 NUMBER OF COLUMNS BETWEEN TAB STOPS + unsigned char loadflg; // = $CA LIST PROTECTION + + unsigned char _internal_4[0xD4-0xCA-1]; // INTERNAL DATA + + unsigned int binint; // = $D4/$D5 USR-CALL RETURN VALUE +}; + diff --git a/include/atari.h b/include/atari.h index 39b4e6947..78c006d42 100644 --- a/include/atari.h +++ b/include/atari.h @@ -37,14 +37,12 @@ #define _ATARI_H - /* Check for errors */ #if !defined(__ATARI__) # error This module may only be used when compiling for the Atari! #endif - /*****************************************************************************/ /* Character codes */ /*****************************************************************************/ @@ -358,6 +356,10 @@ extern void atrx15p2_tgi[]; /* Define hardware and where they're mapped in memory */ /*****************************************************************************/ +#include <_atarios.h> +#define OS (*(struct __os*)0x0000) +#define BASIC (*(struct __basic)0x0080) + #include <_gtia.h> #define GTIA_READ (*(struct __gtia_read*)0xD000) #define GTIA_WRITE (*(struct __gtia_write*)0xD000) @@ -489,129 +491,5 @@ extern void atrx15p2_tgi[]; #define PxCTL_IRQ_STATUS 0x80 -/*****************************************************************************/ -/* Shadow registers for hardware registers */ -/*****************************************************************************/ - -/* GTIA */ -#define STRIG0 (*(unsigned char*)0x284) /* TRIG0 */ -#define STRIG1 (*(unsigned char*)0x285) /* TRIG1 */ -#define STRIG2 (*(unsigned char*)0x286) /* TRIG2 */ -#define STRIG3 (*(unsigned char*)0x287) /* TRIG3 */ -#define PCOLR0 (*(unsigned char*)0x2C0) /* COLPM0 */ -#define PCOLR1 (*(unsigned char*)0x2C1) /* COLPM1 */ -#define PCOLR2 (*(unsigned char*)0x2C2) /* COLPM2 */ -#define PCOLR3 (*(unsigned char*)0x2C3) /* COLPM3 */ -#define COLOR0 (*(unsigned char*)0x2C4) /* COLPF0 */ -#define COLOR1 (*(unsigned char*)0x2C5) /* COLPF1 */ -#define COLOR2 (*(unsigned char*)0x2C6) /* COLPF2 */ -#define COLOR3 (*(unsigned char*)0x2C7) /* COLPF3 */ -#define COLOR4 (*(unsigned char*)0x2C8) /* COLPBK */ -#define GPRIOR (*(unsigned char*)0x264) /* PRIOR */ - -/* ANTIC */ -#define SDMCTL (*(unsigned char*)0x22F) /* DMACTL */ -#define CHACT (*(unsigned char*)0x2F3) /* CHACTL */ -#define SDLSTL (*(unsigned char*)0x230) /* DLISTL */ -#define SDLSTH (*(unsigned char*)0x231) /* DLISTH */ -#define SDLST (*(unsigned int*)0x230) /* DLISTL/H together */ -#define CHBAS (*(unsigned char*)0x2F4) /* CHBASE */ -#define LPENH (*(unsigned char*)0x233) /* PENH */ -#define LPENV (*(unsigned char*)0x234) /* PENV */ - -/* POKEY */ -#define PADDL0 (*(unsigned char*)0x270) /* POT0 */ -#define PADDL1 (*(unsigned char*)0x271) /* POT1 */ -#define PADDL2 (*(unsigned char*)0x272) /* POT2 */ -#define PADDL3 (*(unsigned char*)0x273) /* POT3 */ -#define PADDL4 (*(unsigned char*)0x274) /* POT4 */ -#define PADDL5 (*(unsigned char*)0x275) /* POT5 */ -#define PADDL6 (*(unsigned char*)0x276) /* POT6 */ -#define PADDL7 (*(unsigned char*)0x277) /* POT7 */ -#define CH (*(unsigned char*)0x2FC) /* KBCODE */ -#define POKMSK (*(unsigned char*)0x10) /* IRQEN */ - -/* PIA */ -#define STICK0 (*(unsigned char*)0x278) /* PORTA for controller port 1 */ -#define STICK1 (*(unsigned char*)0x279) /* PORTA for controller port 2 */ -#define STICK2 (*(unsigned char*)0x27A) /* PORTB for controller port 3 */ -#define STICK3 (*(unsigned char*)0x27B) /* PORTB for controller port 4 */ -#define PTRIG0 (*(unsigned char*)0x27C) /* PORTA for controller port 1, paddle 1 */ -#define PTRIG1 (*(unsigned char*)0x27D) /* PORTA for controller port 1, paddle 2 */ -#define PTRIG2 (*(unsigned char*)0x27E) /* PORTA for controller port 1, paddle 3 */ -#define PTRIG3 (*(unsigned char*)0x27F) /* PORTA for controller port 1, paddle 4 */ -#define PTRIG4 (*(unsigned char*)0x280) /* PORTA for controller port 2, paddle 5 */ -#define PTRIG5 (*(unsigned char*)0x281) /* PORTA for controller port 2, paddle 6 */ -#define PTRIG6 (*(unsigned char*)0x282) /* PORTA for controller port 2, paddle 7 */ -#define PTRIG7 (*(unsigned char*)0x283) /* PORTA for controller port 2, paddle 8 */ - - -/*****************************************************************************/ -/* Device control block */ -/*****************************************************************************/ - -struct __dcb { - unsigned char device; /* device id */ - unsigned char unit; /* unit number */ - unsigned char command; /* command */ - unsigned char status; /* command type / status return */ - void *buffer; /* pointer to buffer */ - unsigned char timeout; /* device timeout in seconds */ - unsigned char unused; - unsigned int xfersize; /* # of bytes to transfer */ - unsigned char aux1; /* 1st command auxiliary byte */ - unsigned char aux2; /* 2nd command auxiliary byte */ -}; -#define DCB (*(struct __dcb *)0x300) - - -/*****************************************************************************/ -/* I/O control block */ -/*****************************************************************************/ - -struct __iocb { - unsigned char handler; /* handler index number (0xff free) */ - unsigned char drive; /* device number (drive) */ - unsigned char command; /* command */ - unsigned char status; /* status of last operation */ - void *buffer; /* pointer to buffer */ - void *put_byte; /* pointer to device's PUT BYTE routine */ - unsigned int buflen; /* length of buffer */ - unsigned char aux1; /* 1st auxiliary byte */ - unsigned char aux2; /* 2nd auxiliary byte */ - unsigned char aux3; /* 3rd auxiliary byte */ - unsigned char aux4; /* 4th auxiliary byte */ - unsigned char aux5; /* 5th auxiliary byte */ - unsigned char spare; /* spare byte */ -}; -#define ZIOCB (*(struct __iocb *)0x20) /* zero page IOCB */ -#define IOCB (*(struct __iocb *)0x340) /* system IOCB buffers */ - -/* IOCB Command Codes */ -#define IOCB_OPEN 0x03 /* open */ -#define IOCB_GETREC 0x05 /* get record */ -#define IOCB_GETCHR 0x07 /* get character(s) */ -#define IOCB_PUTREC 0x09 /* put record */ -#define IOCB_PUTCHR 0x0B /* put character(s) */ -#define IOCB_CLOSE 0x0C /* close */ -#define IOCB_STATIS 0x0D /* status */ -#define IOCB_SPECIL 0x0E /* special */ -#define IOCB_DRAWLN 0x11 /* draw line */ -#define IOCB_FILLIN 0x12 /* draw line with right fill */ -#define IOCB_RENAME 0x20 /* rename disk file */ -#define IOCB_DELETE 0x21 /* delete disk file */ -#define IOCB_LOCKFL 0x23 /* lock file (set to read-only) */ -#define IOCB_UNLOCK 0x24 /* unlock file */ -#define IOCB_POINT 0x25 /* point sector */ -#define IOCB_NOTE 0x26 /* note sector */ -#define IOCB_GETFL 0x27 /* get file length */ -#define IOCB_CHDIR_MYDOS 0x29 /* change directory (MyDOS) */ -#define IOCB_MKDIR 0x2A /* make directory (MyDOS/SpartaDOS) */ -#define IOCB_RMDIR 0x2B /* remove directory (SpartaDOS) */ -#define IOCB_CHDIR_SPDOS 0x2C /* change directory (SpartaDOS) */ -#define IOCB_GETCWD 0x30 /* get current directory (MyDOS/SpartaDOS) */ -#define IOCB_FORMAT 0xFE /* format */ - - /* End of atari.h */ #endif From 13fa31a3bcb6f304a8cc0e26de4af0f6e75ac5e3 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 4 Mar 2019 10:19:27 -0500 Subject: [PATCH 1014/2161] Refactorred a CBM screen-code macro, so that we can use it as an operand. For example: lda #scrbyte 'B' --- asminc/cbm.mac | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/asminc/cbm.mac b/asminc/cbm.mac index b2bfe5992..6d7ac7e8d 100644 --- a/asminc/cbm.mac +++ b/asminc/cbm.mac @@ -1,9 +1,13 @@ ; Convert characters to screen codes -; Helper macro that converts and outputs one character +; Macro that converts one character. +; scrbyte() can be used as an instruction operand +.define scrbyte(code) (<(.strat ("h@dbdlhh", code >> 5) << 4) ^ code) + +; Helper macro that stores one character .macro _scrcode char .if (char < 256) - .byte <(.strat ("h@dbdlhh", char >> 5) << 4) ^ char + .byte scrbyte {char} .else .error "scrcode: Character constant out of range" .endif @@ -38,13 +42,9 @@ ; Anything else is an error .else - .error "scrcode: invalid argument type" - .endif ; Call the macro recursively with the remaining args scrcode arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 .endmacro - - From e1a49105809b8876575c0f48fd07d5d5a2d40e6f Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Mon, 4 Mar 2019 23:13:24 +0100 Subject: [PATCH 1015/2161] Code review changes and build fix. --- include/_atarios.h | 32 ++++++++++++++++++++++---------- libsrc/atari/targetutil/w2cas.c | 8 +++----- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/include/_atarios.h b/include/_atarios.h index 89fcfea9b..266617971 100644 --- a/include/_atarios.h +++ b/include/_atarios.h @@ -57,7 +57,7 @@ /* I/O control block */ -typedef struct { +struct __iocb { unsigned char handler; /* handler index number (0xff free) */ unsigned char drive; /* device number (drive) */ unsigned char command; /* command */ @@ -71,22 +71,26 @@ typedef struct { unsigned char aux4; /* 4th auxiliary byte */ unsigned char aux5; /* 5th auxiliary byte */ unsigned char spare; /* spare byte */ -} IOCB; +}; + +typedef struct __iocb IOCB; /* DOS 2.x zeropage variables */ -typedef struct { +struct __dos2x { unsigned char* zbufp; /* points to user filename */ unsigned char* zdrva; /* points to serveral buffers (mostly VTOC) */ unsigned char* zsba; /* points to sector buffer */ unsigned char errno; /* number of occured error */ -} DOS2X; +}; + +typedef struct __dos2x DOS2X; /* A single device handler formed by it's routines */ -typedef struct { +struct __devhdl { void *open; /* address of OPEN routine -1 */ void *close; /* address of CLOSE routine -1 */ void *get; /* address of GET BYTE routine -1 */ @@ -95,26 +99,33 @@ typedef struct { void *special; /* address od SPECIAL routine -1 */ void (*init)(void); /* init routine (JMP INIT) */ void *reserved; /* unused */ -} DEVHDL; +}; + +typedef struct __devhdl DEVHDL; /* List of device handlers, as managed in HATABS */ -typedef struct { +struct __hatabs { unsigned char id; /* ATASCII code of handler e.g. 'C','D','E','K','P','S','R' */ DEVHDL* devhdl; /* Pointer to routines of device */ -} HATABS; +}; + +typedef struct __hatabs HATABS; + /* Floating point register */ -typedef struct { +struct __fpreg { #ifdef OS_REV2 unsigned char fr; unsigned char frm[5]; /* 5-byte register mantissa */ #else unsigned char fr[6]; /* 6 bytes for single register */ #endif -} FPREG; +}; + +typedef struct __fpreg FPREG; enum { /* enum for access of floating point registers */ R0 = 0, /* (to use as index) */ @@ -653,3 +664,4 @@ struct __basic { unsigned int binint; // = $D4/$D5 USR-CALL RETURN VALUE }; +#endif diff --git a/libsrc/atari/targetutil/w2cas.c b/libsrc/atari/targetutil/w2cas.c index 1381a49a0..9358e5fea 100644 --- a/libsrc/atari/targetutil/w2cas.c +++ b/libsrc/atari/targetutil/w2cas.c @@ -22,13 +22,11 @@ static char C_dev[] = "C:"; static struct __iocb *findfreeiocb(void) { - struct __iocb *iocb = &IOCB; /* first IOCB (#0) */ int i; for (i = 0; i < 8; i++) { - if (iocb->handler == 0xff) - return iocb; - iocb++; + if (OS.iocb[i].handler == 0xff) + return &OS.iocb[i]; } return NULL; } @@ -52,7 +50,7 @@ int main(int argc, char **argv) fprintf(stderr, "couldn't find a free iocb\n"); return 1; } - iocb_num = (iocb - &IOCB) * 16; + iocb_num = (iocb - OS.iocb) * 16; if (verbose) printf("using iocb index $%02X ($%04X)\n", iocb_num, iocb); From 3d9ac21b806b76fb134c53fad5aca83191917c75 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Tue, 5 Mar 2019 00:26:14 +0100 Subject: [PATCH 1016/2161] Added missing pointer star for Basic structure. --- include/atari.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/atari.h b/include/atari.h index 78c006d42..a0d4a3d27 100644 --- a/include/atari.h +++ b/include/atari.h @@ -358,7 +358,7 @@ extern void atrx15p2_tgi[]; #include <_atarios.h> #define OS (*(struct __os*)0x0000) -#define BASIC (*(struct __basic)0x0080) +#define BASIC (*(struct __basic*)0x0080) #include <_gtia.h> #define GTIA_READ (*(struct __gtia_read*)0xD000) From 7e298e347d306fd80722e8de7cf21ce26965cfb2 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 5 Mar 2019 15:52:00 -0500 Subject: [PATCH 1017/2161] Fixed the CBM screen-code C header. Changed the number literals from Assembly format to C format. Swapped the (upper-/lower-case) mappings of letters because the header converts from ASCII, not PetSCII. --- include/c64_screen_charmap.h | 557 ++++++++++++++++++----------------- 1 file changed, 289 insertions(+), 268 deletions(-) diff --git a/include/c64_screen_charmap.h b/include/c64_screen_charmap.h index 861ad2704..76e0d7d7b 100644 --- a/include/c64_screen_charmap.h +++ b/include/c64_screen_charmap.h @@ -1,290 +1,311 @@ /*****************************************************************************/ /* */ -/* c64_screen_charmap.h */ +/* cbm_screen_charmap.h */ /* */ /* (c) Copyright 2019, Gerhard W. Gruber (sparhawk@gmx.at) */ /* */ -/* When using C64 mode, this include converts the characters */ -/* from PETSCII to screen mapping, so you can write directly to */ -/* the screen memory. */ +/* When using CBM mode, this include converts character literals */ +/* from ASCII to screen-code mapping, so you can write directly */ +/* to the screen memory. */ /* */ -/* If this include is used, no additional macros are needed */ +/* If this include is used, no additional macroes are needed. */ /* */ /*****************************************************************************/ /* No include guard here! Multiple use in one file may be intentional. */ -// Char $00 ... $1F -> c + 128 #pragma warn (remap-zero, push, off) -#pragma charmap ($00, $80) -#pragma warn (remap-zero, pop) -#pragma charmap ($01, $81) -#pragma charmap ($02, $82) -#pragma charmap ($03, $83) -#pragma charmap ($04, $84) -#pragma charmap ($05, $85) -#pragma charmap ($06, $86) -#pragma charmap ($07, $87) -#pragma charmap ($08, $88) -#pragma charmap ($09, $89) -#pragma charmap ($0A, $8A) -#pragma charmap ($0B, $8B) -#pragma charmap ($0C, $8C) -#pragma charmap ($0D, $8D) -#pragma charmap ($0E, $8E) -#pragma charmap ($0F, $8F) -#pragma charmap ($10, $90) -#pragma charmap ($11, $91) -#pragma charmap ($12, $92) -#pragma charmap ($13, $93) -#pragma charmap ($14, $94) -#pragma charmap ($15, $95) -#pragma charmap ($16, $96) -#pragma charmap ($17, $97) -#pragma charmap ($18, $98) -#pragma charmap ($19, $99) -#pragma charmap ($1A, $9A) -#pragma charmap ($1B, $9B) -#pragma charmap ($1C, $9C) -#pragma charmap ($1D, $9D) -#pragma charmap ($1E, $9E) -#pragma charmap ($1F, $9F) +// Char $00 -> c + 128 +#pragma charmap (0x00, 0x80) -// Char $20 ... $3F -> c = c -#pragma charmap ($20, $20) -#pragma charmap ($21, $21) -#pragma charmap ($22, $22) -#pragma charmap ($23, $23) -#pragma charmap ($24, $24) -#pragma charmap ($25, $25) -#pragma charmap ($26, $26) -#pragma charmap ($27, $27) -#pragma charmap ($28, $28) -#pragma charmap ($29, $29) -#pragma charmap ($2A, $2A) -#pragma charmap ($2B, $2B) -#pragma charmap ($2C, $2C) -#pragma charmap ($2D, $2D) -#pragma charmap ($2E, $2E) -#pragma charmap ($2F, $2F) -#pragma charmap ($30, $30) -#pragma charmap ($31, $31) -#pragma charmap ($32, $32) -#pragma charmap ($33, $33) -#pragma charmap ($34, $34) -#pragma charmap ($35, $35) -#pragma charmap ($36, $36) -#pragma charmap ($37, $37) -#pragma charmap ($38, $38) -#pragma charmap ($39, $39) -#pragma charmap ($3A, $3A) -#pragma charmap ($3B, $3B) -#pragma charmap ($3C, $3C) -#pragma charmap ($3D, $3D) -#pragma charmap ($3E, $3E) -#pragma charmap ($3F, $3F) +// Char $01 ... $1A -> c + 128 + 64 (control alphabet) +#pragma charmap (0x01, 0xC1) +#pragma charmap (0x02, 0xC2) +#pragma charmap (0x03, 0xC3) +#pragma charmap (0x04, 0xC4) +#pragma charmap (0x05, 0xC5) +#pragma charmap (0x06, 0xC6) +#pragma charmap (0x07, 0xC7) +#pragma charmap (0x08, 0xC8) +#pragma charmap (0x09, 0xC9) +#pragma charmap (0x0A, 0xCA) +#pragma charmap (0x0B, 0xCB) +#pragma charmap (0x0C, 0xCC) +#pragma charmap (0x0D, 0xCD) +#pragma charmap (0x0E, 0xCE) +#pragma charmap (0x0F, 0xCF) +#pragma charmap (0x10, 0xD0) +#pragma charmap (0x11, 0xD1) +#pragma charmap (0x12, 0xD2) +#pragma charmap (0x13, 0xD3) +#pragma charmap (0x14, 0xD4) +#pragma charmap (0x15, 0xD5) +#pragma charmap (0x16, 0xD6) +#pragma charmap (0x17, 0xD7) +#pragma charmap (0x18, 0xD8) +#pragma charmap (0x19, 0xD9) +#pragma charmap (0x1A, 0xDA) -// Char $40 ... $5F -> c - 64 -#pragma charmap ($40, $00) -#pragma charmap ($41, $01) -#pragma charmap ($42, $02) -#pragma charmap ($43, $03) -#pragma charmap ($44, $04) -#pragma charmap ($45, $05) -#pragma charmap ($46, $06) -#pragma charmap ($47, $07) -#pragma charmap ($48, $08) -#pragma charmap ($49, $09) -#pragma charmap ($4A, $0A) -#pragma charmap ($4B, $0B) -#pragma charmap ($4C, $0C) -#pragma charmap ($4D, $0D) -#pragma charmap ($4E, $0E) -#pragma charmap ($4F, $0F) -#pragma charmap ($50, $10) -#pragma charmap ($51, $11) -#pragma charmap ($52, $12) -#pragma charmap ($53, $13) -#pragma charmap ($54, $14) -#pragma charmap ($55, $15) -#pragma charmap ($56, $16) -#pragma charmap ($57, $17) -#pragma charmap ($58, $18) -#pragma charmap ($59, $19) -#pragma charmap ($5A, $1A) -#pragma charmap ($5B, $1B) -#pragma charmap ($5C, $1C) -#pragma charmap ($5D, $1D) -#pragma charmap ($5E, $1E) -#pragma charmap ($5F, $1F) +// Char $1B ... $1F -> c + 128 +#pragma charmap (0x1B, 0x9B) +#pragma charmap (0x1C, 0x9C) +#pragma charmap (0x1D, 0x9D) +#pragma charmap (0x1E, 0x9E) +#pragma charmap (0x1F, 0x9F) -// Char $60 ... $7F -> c - 32 -#pragma charmap ($60, $40) -#pragma charmap ($61, $41) -#pragma charmap ($62, $42) -#pragma charmap ($63, $43) -#pragma charmap ($64, $44) -#pragma charmap ($65, $45) -#pragma charmap ($66, $46) -#pragma charmap ($67, $47) -#pragma charmap ($68, $48) -#pragma charmap ($69, $49) -#pragma charmap ($6A, $4A) -#pragma charmap ($6B, $4B) -#pragma charmap ($6C, $4C) -#pragma charmap ($6D, $4D) -#pragma charmap ($6E, $4E) -#pragma charmap ($6F, $4F) -#pragma charmap ($70, $50) -#pragma charmap ($71, $51) -#pragma charmap ($72, $52) -#pragma charmap ($73, $53) -#pragma charmap ($74, $54) -#pragma charmap ($75, $55) -#pragma charmap ($76, $56) -#pragma charmap ($77, $57) -#pragma charmap ($78, $58) -#pragma charmap ($79, $59) -#pragma charmap ($7A, $5A) -#pragma charmap ($7B, $5B) -#pragma charmap ($7C, $5C) -#pragma charmap ($7D, $5D) -#pragma charmap ($7E, $5E) -#pragma charmap ($7F, $5F) +// Char $20 ... $3F -> c +#pragma charmap (0x20, 0x20) +#pragma charmap (0x21, 0x21) +#pragma charmap (0x22, 0x22) +#pragma charmap (0x23, 0x23) +#pragma charmap (0x24, 0x24) +#pragma charmap (0x25, 0x25) +#pragma charmap (0x26, 0x26) +#pragma charmap (0x27, 0x27) +#pragma charmap (0x28, 0x28) +#pragma charmap (0x29, 0x29) +#pragma charmap (0x2A, 0x2A) +#pragma charmap (0x2B, 0x2B) +#pragma charmap (0x2C, 0x2C) +#pragma charmap (0x2D, 0x2D) +#pragma charmap (0x2E, 0x2E) +#pragma charmap (0x2F, 0x2F) +#pragma charmap (0x30, 0x30) +#pragma charmap (0x31, 0x31) +#pragma charmap (0x32, 0x32) +#pragma charmap (0x33, 0x33) +#pragma charmap (0x34, 0x34) +#pragma charmap (0x35, 0x35) +#pragma charmap (0x36, 0x36) +#pragma charmap (0x37, 0x37) +#pragma charmap (0x38, 0x38) +#pragma charmap (0x39, 0x39) +#pragma charmap (0x3A, 0x3A) +#pragma charmap (0x3B, 0x3B) +#pragma charmap (0x3C, 0x3C) +#pragma charmap (0x3D, 0x3D) +#pragma charmap (0x3E, 0x3E) +#pragma charmap (0x3F, 0x3F) -// Char $80 ... $9F -> c + 64 -#pragma charmap ($80, $C0) -#pragma charmap ($81, $C1) -#pragma charmap ($82, $C2) -#pragma charmap ($83, $C3) -#pragma charmap ($84, $C4) -#pragma charmap ($85, $C5) -#pragma charmap ($86, $C6) -#pragma charmap ($87, $C7) -#pragma charmap ($88, $C8) -#pragma charmap ($89, $C9) -#pragma charmap ($8A, $CA) -#pragma charmap ($8B, $CB) -#pragma charmap ($8C, $CC) -#pragma charmap ($8D, $CD) -#pragma charmap ($8E, $CE) -#pragma charmap ($8F, $CF) -#pragma charmap ($90, $D0) -#pragma charmap ($91, $D1) -#pragma charmap ($92, $D2) -#pragma charmap ($93, $D3) -#pragma charmap ($94, $D4) -#pragma charmap ($95, $D5) -#pragma charmap ($96, $D6) -#pragma charmap ($97, $D7) -#pragma charmap ($98, $D8) -#pragma charmap ($99, $D9) -#pragma charmap ($9A, $DA) -#pragma charmap ($9B, $DB) -#pragma charmap ($9C, $DC) -#pragma charmap ($9D, $DD) -#pragma charmap ($9E, $DE) -#pragma charmap ($9F, $DF) +// Char $40 -> c - 64 +#pragma charmap (0x40, 0x00) + +// Char $41 ... $5A -> c (upper-case alphabet) +#pragma charmap (0x41, 0x41) +#pragma charmap (0x42, 0x42) +#pragma charmap (0x43, 0x43) +#pragma charmap (0x44, 0x44) +#pragma charmap (0x45, 0x45) +#pragma charmap (0x46, 0x46) +#pragma charmap (0x47, 0x47) +#pragma charmap (0x48, 0x48) +#pragma charmap (0x49, 0x49) +#pragma charmap (0x4A, 0x4A) +#pragma charmap (0x4B, 0x4B) +#pragma charmap (0x4C, 0x4C) +#pragma charmap (0x4D, 0x4D) +#pragma charmap (0x4E, 0x4E) +#pragma charmap (0x4F, 0x4F) +#pragma charmap (0x50, 0x50) +#pragma charmap (0x51, 0x51) +#pragma charmap (0x52, 0x52) +#pragma charmap (0x53, 0x53) +#pragma charmap (0x54, 0x54) +#pragma charmap (0x55, 0x55) +#pragma charmap (0x56, 0x56) +#pragma charmap (0x57, 0x57) +#pragma charmap (0x58, 0x58) +#pragma charmap (0x59, 0x59) +#pragma charmap (0x5A, 0x5A) + +// Char $5B ... $5F -> c - 64 +#pragma charmap (0x5B, 0x1B) +#pragma charmap (0x5C, 0x1C) +#pragma charmap (0x5D, 0x1D) +#pragma charmap (0x5E, 0x1E) +#pragma charmap (0x5F, 0x1F) + +// Char $60 -> c - 32 +#pragma charmap (0x60, 0x40) + +// Char $61 ... $7A -> c - 32 - 64 (lower-case alphabet) +#pragma charmap (0x61, 0x01) +#pragma charmap (0x62, 0x02) +#pragma charmap (0x63, 0x03) +#pragma charmap (0x64, 0x04) +#pragma charmap (0x65, 0x05) +#pragma charmap (0x66, 0x06) +#pragma charmap (0x67, 0x07) +#pragma charmap (0x68, 0x08) +#pragma charmap (0x69, 0x09) +#pragma charmap (0x6A, 0x0A) +#pragma charmap (0x6B, 0x0B) +#pragma charmap (0x6C, 0x0C) +#pragma charmap (0x6D, 0x0D) +#pragma charmap (0x6E, 0x0E) +#pragma charmap (0x6F, 0x0F) +#pragma charmap (0x70, 0x10) +#pragma charmap (0x71, 0x11) +#pragma charmap (0x72, 0x12) +#pragma charmap (0x73, 0x13) +#pragma charmap (0x74, 0x14) +#pragma charmap (0x75, 0x15) +#pragma charmap (0x76, 0x16) +#pragma charmap (0x77, 0x17) +#pragma charmap (0x78, 0x18) +#pragma charmap (0x79, 0x19) +#pragma charmap (0x7A, 0x1A) + +// Char $7B ... $7F -> c - 32 +#pragma charmap (0x7B, 0x5B) +#pragma charmap (0x7C, 0x5C) +#pragma charmap (0x7D, 0x5D) +#pragma charmap (0x7E, 0x5E) +#pragma charmap (0x7F, 0x5F) + +// Char $80 -> c + 64 +#pragma charmap (0x80, 0xC0) + +// Char $81 ... $9A -> c (control alphabet) +#pragma charmap (0x81, 0x81) +#pragma charmap (0x82, 0x82) +#pragma charmap (0x83, 0x83) +#pragma charmap (0x84, 0x84) +#pragma charmap (0x85, 0x85) +#pragma charmap (0x86, 0x86) +#pragma charmap (0x87, 0x87) +#pragma charmap (0x88, 0x88) +#pragma charmap (0x89, 0x89) +#pragma charmap (0x8A, 0x8A) +#pragma charmap (0x8B, 0x8B) +#pragma charmap (0x8C, 0x8C) +#pragma charmap (0x8D, 0x8D) +#pragma charmap (0x8E, 0x8E) +#pragma charmap (0x8F, 0x8F) +#pragma charmap (0x90, 0x90) +#pragma charmap (0x91, 0x91) +#pragma charmap (0x92, 0x92) +#pragma charmap (0x93, 0x93) +#pragma charmap (0x94, 0x94) +#pragma charmap (0x95, 0x95) +#pragma charmap (0x96, 0x96) +#pragma charmap (0x97, 0x97) +#pragma charmap (0x98, 0x98) +#pragma charmap (0x99, 0x99) +#pragma charmap (0x9A, 0x9A) + +// Char $9B ... $9F -> c + 64 +#pragma charmap (0x9B, 0xDB) +#pragma charmap (0x9C, 0xDC) +#pragma charmap (0x9D, 0xDD) +#pragma charmap (0x9E, 0xDE) +#pragma charmap (0x9F, 0xDF) // Char $A0 ... $BF -> c - 64 -#pragma charmap ($A0, $60) -#pragma charmap ($A1, $61) -#pragma charmap ($A2, $62) -#pragma charmap ($A3, $63) -#pragma charmap ($A4, $64) -#pragma charmap ($A5, $65) -#pragma charmap ($A6, $66) -#pragma charmap ($A7, $67) -#pragma charmap ($A8, $68) -#pragma charmap ($A9, $69) -#pragma charmap ($AA, $6A) -#pragma charmap ($AB, $6B) -#pragma charmap ($AC, $6C) -#pragma charmap ($AD, $6D) -#pragma charmap ($AE, $6E) -#pragma charmap ($AF, $6F) -#pragma charmap ($B0, $70) -#pragma charmap ($B1, $71) -#pragma charmap ($B2, $72) -#pragma charmap ($B3, $73) -#pragma charmap ($B4, $74) -#pragma charmap ($B5, $75) -#pragma charmap ($B6, $76) -#pragma charmap ($B7, $77) -#pragma charmap ($B8, $78) -#pragma charmap ($B9, $79) -#pragma charmap ($BA, $7A) -#pragma charmap ($BB, $7B) -#pragma charmap ($BC, $7C) -#pragma charmap ($BD, $7D) -#pragma charmap ($BE, $7E) -#pragma charmap ($BF, $7F) +#pragma charmap (0xA0, 0x60) +#pragma charmap (0xA1, 0x61) +#pragma charmap (0xA2, 0x62) +#pragma charmap (0xA3, 0x63) +#pragma charmap (0xA4, 0x64) +#pragma charmap (0xA5, 0x65) +#pragma charmap (0xA6, 0x66) +#pragma charmap (0xA7, 0x67) +#pragma charmap (0xA8, 0x68) +#pragma charmap (0xA9, 0x69) +#pragma charmap (0xAA, 0x6A) +#pragma charmap (0xAB, 0x6B) +#pragma charmap (0xAC, 0x6C) +#pragma charmap (0xAD, 0x6D) +#pragma charmap (0xAE, 0x6E) +#pragma charmap (0xAF, 0x6F) +#pragma charmap (0xB0, 0x70) +#pragma charmap (0xB1, 0x71) +#pragma charmap (0xB2, 0x72) +#pragma charmap (0xB3, 0x73) +#pragma charmap (0xB4, 0x74) +#pragma charmap (0xB5, 0x75) +#pragma charmap (0xB6, 0x76) +#pragma charmap (0xB7, 0x77) +#pragma charmap (0xB8, 0x78) +#pragma charmap (0xB9, 0x79) +#pragma charmap (0xBA, 0x7A) +#pragma charmap (0xBB, 0x7B) +#pragma charmap (0xBC, 0x7C) +#pragma charmap (0xBD, 0x7D) +#pragma charmap (0xBE, 0x7E) +#pragma charmap (0xBF, 0x7F) // Char $C0 ... $DF -> c - 128 -#pragma charmap ($C0, $40) -#pragma charmap ($C1, $41) -#pragma charmap ($C2, $42) -#pragma charmap ($C3, $43) -#pragma charmap ($C4, $44) -#pragma charmap ($C5, $45) -#pragma charmap ($C6, $46) -#pragma charmap ($C7, $47) -#pragma charmap ($C8, $48) -#pragma charmap ($C9, $49) -#pragma charmap ($CA, $4A) -#pragma charmap ($CB, $4B) -#pragma charmap ($CC, $4C) -#pragma charmap ($CD, $4D) -#pragma charmap ($CE, $4E) -#pragma charmap ($CF, $4F) -#pragma charmap ($D0, $50) -#pragma charmap ($D1, $51) -#pragma charmap ($D2, $52) -#pragma charmap ($D3, $53) -#pragma charmap ($D4, $54) -#pragma charmap ($D5, $55) -#pragma charmap ($D6, $56) -#pragma charmap ($D7, $57) -#pragma charmap ($D8, $58) -#pragma charmap ($D9, $59) -#pragma charmap ($DA, $5A) -#pragma charmap ($DB, $5B) -#pragma charmap ($DC, $5C) -#pragma charmap ($DD, $5D) -#pragma charmap ($DE, $5E) -#pragma charmap ($DF, $5F) +#pragma charmap (0xC0, 0x40) -// Char $E0 ... $FE -> c - 128 -#pragma charmap ($E0, $60) -#pragma charmap ($E1, $61) -#pragma charmap ($E2, $62) -#pragma charmap ($E3, $63) -#pragma charmap ($E4, $64) -#pragma charmap ($E5, $65) -#pragma charmap ($E6, $66) -#pragma charmap ($E7, $67) -#pragma charmap ($E8, $68) -#pragma charmap ($E9, $69) -#pragma charmap ($EA, $6A) -#pragma charmap ($EB, $6B) -#pragma charmap ($EC, $6C) -#pragma charmap ($ED, $6D) -#pragma charmap ($EE, $6E) -#pragma charmap ($EF, $6F) -#pragma charmap ($F0, $70) -#pragma charmap ($F1, $71) -#pragma charmap ($F2, $72) -#pragma charmap ($F3, $73) -#pragma charmap ($F4, $74) -#pragma charmap ($F5, $75) -#pragma charmap ($F6, $76) -#pragma charmap ($F7, $77) -#pragma charmap ($F8, $78) -#pragma charmap ($F9, $79) -#pragma charmap ($FA, $7A) -#pragma charmap ($FB, $7B) -#pragma charmap ($FC, $7C) -#pragma charmap ($FD, $7D) -#pragma charmap ($FE, $7E) -#pragma charmap ($FF, $5E) +// Char $C1 ... $DA -> c - 128 - 64 (lower-case alphabet) +#pragma charmap (0xC1, 0x01) +#pragma charmap (0xC2, 0x02) +#pragma charmap (0xC3, 0x03) +#pragma charmap (0xC4, 0x04) +#pragma charmap (0xC5, 0x05) +#pragma charmap (0xC6, 0x06) +#pragma charmap (0xC7, 0x07) +#pragma charmap (0xC8, 0x08) +#pragma charmap (0xC9, 0x09) +#pragma charmap (0xCA, 0x0A) +#pragma charmap (0xCB, 0x0B) +#pragma charmap (0xCC, 0x0C) +#pragma charmap (0xCD, 0x0D) +#pragma charmap (0xCE, 0x0E) +#pragma charmap (0xCF, 0x0F) +#pragma charmap (0xD0, 0x10) +#pragma charmap (0xD1, 0x11) +#pragma charmap (0xD2, 0x12) +#pragma charmap (0xD3, 0x13) +#pragma charmap (0xD4, 0x14) +#pragma charmap (0xD5, 0x15) +#pragma charmap (0xD6, 0x16) +#pragma charmap (0xD7, 0x17) +#pragma charmap (0xD8, 0x18) +#pragma charmap (0xD9, 0x19) +#pragma charmap (0xDA, 0x1A) + +// Char $DB ... $DF -> c - 128 +#pragma charmap (0xDB, 0x5B) +#pragma charmap (0xDC, 0x5C) +#pragma charmap (0xDD, 0x5D) +#pragma charmap (0xDE, 0x5E) +#pragma charmap (0xDF, 0x5F) + +// Char $E0 ... $FF -> c - 128 +#pragma charmap (0xE0, 0x60) +#pragma charmap (0xE1, 0x61) +#pragma charmap (0xE2, 0x62) +#pragma charmap (0xE3, 0x63) +#pragma charmap (0xE4, 0x64) +#pragma charmap (0xE5, 0x65) +#pragma charmap (0xE6, 0x66) +#pragma charmap (0xE7, 0x67) +#pragma charmap (0xE8, 0x68) +#pragma charmap (0xE9, 0x69) +#pragma charmap (0xEA, 0x6A) +#pragma charmap (0xEB, 0x6B) +#pragma charmap (0xEC, 0x6C) +#pragma charmap (0xED, 0x6D) +#pragma charmap (0xEE, 0x6E) +#pragma charmap (0xEF, 0x6F) +#pragma charmap (0xF0, 0x70) +#pragma charmap (0xF1, 0x71) +#pragma charmap (0xF2, 0x72) +#pragma charmap (0xF3, 0x73) +#pragma charmap (0xF4, 0x74) +#pragma charmap (0xF5, 0x75) +#pragma charmap (0xF6, 0x76) +#pragma charmap (0xF7, 0x77) +#pragma charmap (0xF8, 0x78) +#pragma charmap (0xF9, 0x79) +#pragma charmap (0xFA, 0x7A) +#pragma charmap (0xFB, 0x7B) +#pragma charmap (0xFC, 0x7C) +#pragma charmap (0xFD, 0x7D) +#pragma charmap (0xFE, 0x7E) +#pragma charmap (0xFF, 0x7F) + +#pragma warn (remap-zero, pop) From 2362db22f7bedf79fa0489f2e018e2431a890144 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 5 Mar 2019 16:18:20 -0500 Subject: [PATCH 1018/2161] Renamed a C header. All of Commodore's 8-bit computer models use the same screen-codes. --- include/{c64_screen_charmap.h => cbm_screen_charmap.h} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename include/{c64_screen_charmap.h => cbm_screen_charmap.h} (100%) diff --git a/include/c64_screen_charmap.h b/include/cbm_screen_charmap.h similarity index 100% rename from include/c64_screen_charmap.h rename to include/cbm_screen_charmap.h From 1359ad793d4ee6a0b0c63478527b1c4318603292 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Fri, 8 Mar 2019 11:48:37 +0100 Subject: [PATCH 1019/2161] Atari OS: Reestablished DCB structure, fixed union span and timer2. --- include/_atarios.h | 83 ++++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 32 deletions(-) diff --git a/include/_atarios.h b/include/_atarios.h index 266617971..410bd3142 100644 --- a/include/_atarios.h +++ b/include/_atarios.h @@ -55,6 +55,24 @@ #define IOCB_FORMAT 0xFE /* format */ +/* Device control block */ + +struct __dcb { + unsigned char device; /* device id */ + unsigned char unit; /* unit number */ + unsigned char command; /* command */ + unsigned char status; /* command type / status return */ + void *buffer; /* pointer to buffer */ + unsigned char timeout; /* device timeout in seconds */ + unsigned char unused; + unsigned int xfersize; /* # of bytes to transfer */ + unsigned char aux1; /* 1st command auxiliary byte */ + unsigned char aux2; /* 2nd command auxiliary byte */ +}; + +typedef struct __dcb DCB; + + /* I/O control block */ struct __iocb { @@ -540,7 +558,7 @@ struct __os { // --- Page 3 --- union { - unsigned char dcb[0x40]; // = $0300-$03XX DEVICE CONTROL BLOCK + DCB dcb; // = $0300-$030B DEVICE CONTROL BLOCK struct { unsigned char ddevic; // = $0300 PERIPHERAL UNIT 1 BUS I.D. NUMBER unsigned char dunit; // = $0301 UNIT NUMBER @@ -569,39 +587,40 @@ struct __os { unsigned char daux2; // = $030B 1-byte second command auxiliary }; }; - unsigned int timer1; // = $030C/$030D INITIAL TIMER VALUE -#ifdef OSA - unsigned char addcor; // = $030E ##old## ADDITION CORRECTION -#else - unsigned char jmpers; // = $030E ##1200xl## 1-byte jumper options -#endif - unsigned char casflg; // = $030F CASSETTE MODE WHEN SET - unsigned char timer2; // = $0310/$0311 2-byte final baud rate timer value - unsigned char temp1; // = $0312 TEMPORARY STORAGE REGISTER -#ifdef OSA - unsigned char _spare_5; // = $0313 unused - unsigned char temp2; // = $0314 ##old## TEMPORARY STORAGE REGISTER -#else - unsigned char temp2; // = $0313 ##1200xl## 1-byte temporary - unsigned char ptimot; // = $0314 ##1200xl## 1-byte printer timeout -#endif - unsigned char temp3; // = $0315 TEMPORARY STORAGE REGISTER - unsigned char savio; // = $0316 SAVE SERIAL IN DATA PORT - unsigned char timflg; // = $0317 TIME OUT FLAG FOR BAUD RATE CORRECTION - unsigned char stackp; // = $0318 SIO STACK POINTER SAVE CELL - unsigned char tstat; // = $0319 TEMPORARY STATUS HOLDER -#ifdef OSA - HATABS hatabs[12]; // = $031A-$033D handler address table - unsigned int zeropad; // = $033E/$033F zero padding -#else - HATABS hatabs[11]; // = $031A-$033A handler address table - unsigned int zeropad; // = $033B/$033C zero padding - unsigned char pupbt1; // = $033D ##1200xl## 1-byte power-up validation byte 1 - unsigned char pupbt2; // = $033E ##1200xl## 1-byte power-up validation byte 2 - unsigned char pupbt3; // = $033F ##1200xl## 1-byte power-up validation byte 3 -#endif }; }; + unsigned int timer1; // = $030C/$030D INITIAL TIMER VALUE +#ifdef OSA + unsigned char addcor; // = $030E ##old## ADDITION CORRECTION +#else + unsigned char jmpers; // = $030E ##1200xl## 1-byte jumper options +#endif + unsigned char casflg; // = $030F CASSETTE MODE WHEN SET + unsigned int timer2; // = $0310/$0311 2-byte final baud rate timer value + unsigned char temp1; // = $0312 TEMPORARY STORAGE REGISTER +#ifdef OSA + unsigned char _spare_5; // = $0313 unused + unsigned char temp2; // = $0314 ##old## TEMPORARY STORAGE REGISTER +#else + unsigned char temp2; // = $0313 ##1200xl## 1-byte temporary + unsigned char ptimot; // = $0314 ##1200xl## 1-byte printer timeout +#endif + unsigned char temp3; // = $0315 TEMPORARY STORAGE REGISTER + unsigned char savio; // = $0316 SAVE SERIAL IN DATA PORT + unsigned char timflg; // = $0317 TIME OUT FLAG FOR BAUD RATE CORRECTION + unsigned char stackp; // = $0318 SIO STACK POINTER SAVE CELL + unsigned char tstat; // = $0319 TEMPORARY STATUS HOLDER +#ifdef OSA + HATABS hatabs[12]; // = $031A-$033D handler address table + unsigned int zeropad; // = $033E/$033F zero padding +#else + HATABS hatabs[11]; // = $031A-$033A handler address table + unsigned int zeropad; // = $033B/$033C zero padding + unsigned char pupbt1; // = $033D ##1200xl## 1-byte power-up validation byte 1 + unsigned char pupbt2; // = $033E ##1200xl## 1-byte power-up validation byte 2 + unsigned char pupbt3; // = $033F ##1200xl## 1-byte power-up validation byte 3 +#endif + IOCB iocb[8]; // = $0340-$03BF 8 I/O Control Blocks unsigned char prnbuf[40]; // = $03C0-$3E7 PRINTER BUFFER #ifdef OSA From 203f4c80d42aa0ae4f50f094ed806b1be84228c1 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sat, 9 Mar 2019 21:40:57 +0100 Subject: [PATCH 1020/2161] Code review changes and improved formatting. --- include/_atarios.h | 128 ++++++++++++++++++--------------------------- 1 file changed, 51 insertions(+), 77 deletions(-) diff --git a/include/_atarios.h b/include/_atarios.h index 410bd3142..9a8a864b7 100644 --- a/include/_atarios.h +++ b/include/_atarios.h @@ -58,19 +58,24 @@ /* Device control block */ struct __dcb { - unsigned char device; /* device id */ - unsigned char unit; /* unit number */ - unsigned char command; /* command */ - unsigned char status; /* command type / status return */ - void *buffer; /* pointer to buffer */ - unsigned char timeout; /* device timeout in seconds */ - unsigned char unused; - unsigned int xfersize; /* # of bytes to transfer */ - unsigned char aux1; /* 1st command auxiliary byte */ - unsigned char aux2; /* 2nd command auxiliary byte */ + unsigned char ddevic; /* device id */ + unsigned char dunit; /* unit number */ + unsigned char dcomnd; /* command */ + unsigned char dstats; /* command type / status return */ + void *dbuf; /* pointer to buffer */ + unsigned char dtimlo; /* device timeout in seconds */ + unsigned char dunuse; /* - unused - */ + unsigned int dbyt; /* # of bytes to transfer */ + union { + struct { + unsigned char daux1; /* 1st command auxiliary byte */ + unsigned char daux2; /* 2nd command auxiliary byte */ + }; + unsigned int daux; /* auxiliary as word */ + }; }; -typedef struct __dcb DCB; +typedef struct __dcb dcb_t; /* I/O control block */ @@ -91,7 +96,7 @@ struct __iocb { unsigned char spare; /* spare byte */ }; -typedef struct __iocb IOCB; +typedef struct __iocb iocb_t; /* DOS 2.x zeropage variables */ @@ -103,7 +108,7 @@ struct __dos2x { unsigned char errno; /* number of occured error */ }; -typedef struct __dos2x DOS2X; +typedef struct __dos2x dos2x_t; /* A single device handler formed by it's routines */ @@ -119,17 +124,17 @@ struct __devhdl { void *reserved; /* unused */ }; -typedef struct __devhdl DEVHDL; +typedef struct __devhdl devhdl_t; /* List of device handlers, as managed in HATABS */ struct __hatabs { unsigned char id; /* ATASCII code of handler e.g. 'C','D','E','K','P','S','R' */ - DEVHDL* devhdl; /* Pointer to routines of device */ + devhdl_t* devhdl; /* Pointer to routines of device */ }; -typedef struct __hatabs HATABS; +typedef struct __hatabs hatabs_t; /* Floating point register */ @@ -143,7 +148,7 @@ struct __fpreg { #endif }; -typedef struct __fpreg FPREG; +typedef struct __fpreg fpreg_t; enum { /* enum for access of floating point registers */ R0 = 0, /* (to use as index) */ @@ -201,7 +206,7 @@ struct __os { #else unsigned char abufpt[4]; // = $1C-$1F ACMI BUFFER POINTER AREA #endif - IOCB ziocb; // = $20-$2F ZERO PAGE I/O CONTROL BLOCK + iocb_t ziocb; // = $20-$2F ZERO PAGE I/O CONTROL BLOCK unsigned char status; // = $30 INTERNAL STATUS STORAGE unsigned char chksum; // = $31 CHECKSUM (SINGLE BYTE SUM WITH CARRY) @@ -225,7 +230,7 @@ struct __os { unsigned char freq; // = $40 CASSETTE BEEP COUNTER unsigned char soundr; // = $41 NOISY I/0 FLAG. (ZERO IS QUIET) unsigned char critic; // = $42 DEFINES CRITICAL SECTION (CRITICAL IF NON-Z) - DOS2X fmszpg; // = $43-$49 DISK FILE MANAGER SYSTEM ZERO PAGE + dos2x_t fmszpg; // = $43-$49 DISK FILE MANAGER SYSTEM ZERO PAGE #ifdef OSA unsigned char ckey; // = $4A FLAG SET WHEN GAME START PRESSED unsigned char cassbt; // = $4B CASSETTE BOOT FLAG @@ -286,7 +291,7 @@ struct __os { unsigned char _free_1[0xD4-0x7F-1]; // USER SPACE // Floating Point Package Page Zero Address Equates - FPREG fpreg[4]; // = $D4-$EB 4 REGSITERS, ACCCESS LIKE "fpreg[R0].fr" + fpreg_t fpreg[4]; // = $D4-$EB 4 REGSITERS, ACCCESS LIKE "fpreg[R0].fr" unsigned char frx; // = $EC 1-BYTE TEMPORARY unsigned char eexp; // = $ED VALUE OF EXP #ifdef OS_REV2 @@ -311,8 +316,8 @@ struct __os { unsigned char radflg; // = $FB ##OLD## 0=RADIANS, 6=DEGREES }; - FPREG* flptr; // = $FC/$FD 2-BYTE FLOATING POINT NUMBER POINTER - FPREG* fptr2; // = $FE/$FF 2-BYTE FLOATING POINT NUMBER POINTER + fpreg_t* flptr; // = $FC/$FD 2-BYTE FLOATING POINT NUMBER POINTER + fpreg_t* fptr2; // = $FE/$FF 2-BYTE FLOATING POINT NUMBER POINTER // --- Page 1 --- @@ -375,7 +380,7 @@ struct __os { unsigned char caux1; // = $023C COMMAND AUX BYTE 1 unsigned char caux2; // = $023D COMMAND AUX BYTE 2 }; - unsigned caux; // = $023C/$023D (same as above as word) + unsigned int caux; // = $023C/$023D (same as above as word) }; unsigned char temp; // = $023E TEMPORARY RAM CELL unsigned char errflg; // = $023F ERROR FLAG - ANY DEVICE ERROR EXCEPT TIME OUT @@ -395,7 +400,7 @@ struct __os { unsigned char pdvmsk; // = $0247 ##rev2## 1-byte parallel device selection mask unsigned char shpdvs; // = $0248 ##rev2## 1-byte PDVS (parallel device select) unsigned char pdimsk; // = $0249 ##rev2## 1-byte parallel device IRQ selection - unsigned reladr; // = $024A/$024B ##rev2## 2-byte relocating loader relative adr. + unsigned int reladr; // = $024A/$024B ##rev2## 2-byte relocating loader relative adr. unsigned char pptmpa; // = $024C ##rev2## 1-byte parallel device handler temporary unsigned char pptmpx; // = $024D ##rev2## 1-byte parallel device handler temporary unsigned char _reserved_1[29]; // = $024E-$026A RESERVED @@ -544,7 +549,7 @@ struct __os { unsigned char _spare_4[5]; // = $02F5-$02F9 No OS use. #else unsigned char newrow; // = $02F5 ##1200xl## 1-byte draw destination row - unsigned int newcol; // = $02F6/$02F7 ##1200xl## 2-byte draw destination column + unsigned int newcol; // = $02F6/$02F7 ##1200xl## 2-byte draw destination column unsigned char rowinc; // = $02F8 ##1200xl## 1-byte draw row increment unsigned char colinc; // = $02F9 ##1200xl## 1-byte draw column increment #endif @@ -557,38 +562,7 @@ struct __os { // --- Page 3 --- - union { - DCB dcb; // = $0300-$030B DEVICE CONTROL BLOCK - struct { - unsigned char ddevic; // = $0300 PERIPHERAL UNIT 1 BUS I.D. NUMBER - unsigned char dunit; // = $0301 UNIT NUMBER - unsigned char dcomnd; // = $0302 BUS COMMAND - unsigned char dstats; // = $0303 COMMAND TYPE/STATUS RETURN - union { - void* dbuf; // = $0304/$0305 data buffer address - struct { - unsigned char dbuflo; // = $0304 1-byte low data buffer address - unsigned char dbufhi; // = $0305 1-byte high data buffer address - }; - }; - unsigned char dtimlo; // = $0306 DEVICE TIME OUT IN 1 SECOND UNITS - unsigned char dunuse; // = $0307 UNUSED BYTE - union { - unsigned int dbyt; // = $0308/$0309 number of bytes to transfer - struct { - unsigned char dbytlo; // = $0308 1-byte low number of bytes to transfer - unsigned char dbythi; // = $0309 1-byte high number of bytes to transfer - }; - }; - union { - unsigned int daux; // = $030A/$030B first and second auxiliary - struct { - unsigned char daux1; // = $030A 1-byte first command auxiliary - unsigned char daux2; // = $030B 1-byte second command auxiliary - }; - }; - }; - }; + dcb_t dcb; // = $0300-$030B DEVICE CONTROL BLOCK unsigned int timer1; // = $030C/$030D INITIAL TIMER VALUE #ifdef OSA unsigned char addcor; // = $030E ##old## ADDITION CORRECTION @@ -611,17 +585,17 @@ struct __os { unsigned char stackp; // = $0318 SIO STACK POINTER SAVE CELL unsigned char tstat; // = $0319 TEMPORARY STATUS HOLDER #ifdef OSA - HATABS hatabs[12]; // = $031A-$033D handler address table - unsigned int zeropad; // = $033E/$033F zero padding + hatabs_t hatabs[12]; // = $031A-$033D handler address table + unsigned int zeropad; // = $033E/$033F zero padding #else - HATABS hatabs[11]; // = $031A-$033A handler address table - unsigned int zeropad; // = $033B/$033C zero padding + hatabs_t hatabs[11]; // = $031A-$033A handler address table + unsigned int zeropad; // = $033B/$033C zero padding unsigned char pupbt1; // = $033D ##1200xl## 1-byte power-up validation byte 1 unsigned char pupbt2; // = $033E ##1200xl## 1-byte power-up validation byte 2 unsigned char pupbt3; // = $033F ##1200xl## 1-byte power-up validation byte 3 #endif - IOCB iocb[8]; // = $0340-$03BF 8 I/O Control Blocks + iocb_t iocb[8]; // = $0340-$03BF 8 I/O Control Blocks unsigned char prnbuf[40]; // = $03C0-$3E7 PRINTER BUFFER #ifdef OSA unsigned char _spare_6[151]; // = $03E8-$047F unused @@ -635,7 +609,7 @@ struct __os { unsigned char basicf; // = $03F8 ##rev2## 1-byte BASIC switch flag unsigned char mintlk; // = $03F9 ##1200xl## 1-byte ACMI module interlock unsigned char gintlk; // = $03FA ##1200xl## 1-byte cartridge interlock - void* chlink; // = $03FB/$03FC ##1200xl## 2-byte loaded handler chain link + void* chlink; // = $03FB/$03FC ##1200xl## 2-byte loaded handler chain link unsigned char casbuf[131]; // = $03FD-$047F CASSETTE BUFFER #endif @@ -655,32 +629,32 @@ struct __os { /* Define a structure with the zero page atari basic register offsets */ struct __basic { - void* lowmem; // = $80/$81 POINTER TO BASIC'S LOW MEMORY - void* vntp; // = $82/$83 BEGINNING ADDRESS OF THE VARIABLE NAME TABLE - void* vntd; // = $84/$85 POINTER TO THE ENDING ADDRESS OF THE VARIABLE NAME TABLE PLUS ONE - void* vvtp; // = $86/$87 ADDRESS FOR THE VARIABLE VALUE TABLE - void* stmtab; // = $88/$89 ADDRESS OF THE STATEMENT TABLE - void* stmcur; // = $8A/$8B CURRENT BASIC STATEMENT POINTER - void* starp; // = $8C/$8D ADDRESS FOR THE STRING AND ARRAY TABLE - void* runstk; // = $8E/$8F ADDRESS OF THE RUNTIME STACK - void* memtop; // = $90/$91 POINTER TO THE TOP OF BASIC MEMORY + void* lowmem; // = $80/$81 POINTER TO BASIC'S LOW MEMORY + void* vntp; // = $82/$83 BEGINNING ADDRESS OF THE VARIABLE NAME TABLE + void* vntd; // = $84/$85 POINTER TO THE ENDING ADDRESS OF THE VARIABLE NAME TABLE PLUS ONE + void* vvtp; // = $86/$87 ADDRESS FOR THE VARIABLE VALUE TABLE + void* stmtab; // = $88/$89 ADDRESS OF THE STATEMENT TABLE + void* stmcur; // = $8A/$8B CURRENT BASIC STATEMENT POINTER + void* starp; // = $8C/$8D ADDRESS FOR THE STRING AND ARRAY TABLE + void* runstk; // = $8E/$8F ADDRESS OF THE RUNTIME STACK + void* memtop; // = $90/$91 POINTER TO THE TOP OF BASIC MEMORY unsigned char _internal_1[0xBA-0x91-1]; // INTERNAL DATA - unsigned int stopln; // = $BA/$BB LINE WHERE A PROGRAM WAS STOPPED + unsigned int stopln; // = $BA/$BB LINE WHERE A PROGRAM WAS STOPPED unsigned char _internal_2[0xC3-0xBB-1]; // INTERNAL DATA - unsigned char errsav; // = $C3 NUMBER OF THE ERROR CODE + unsigned char errsav; // = $C3 NUMBER OF THE ERROR CODE unsigned char _internal_3[0xC9-0xC3-1]; // INTERNAL DATA - unsigned char ptabw; // = $C9 NUMBER OF COLUMNS BETWEEN TAB STOPS - unsigned char loadflg; // = $CA LIST PROTECTION + unsigned char ptabw; // = $C9 NUMBER OF COLUMNS BETWEEN TAB STOPS + unsigned char loadflg; // = $CA LIST PROTECTION unsigned char _internal_4[0xD4-0xCA-1]; // INTERNAL DATA - unsigned int binint; // = $D4/$D5 USR-CALL RETURN VALUE + unsigned int binint; // = $D4/$D5 USR-CALL RETURN VALUE }; #endif From 2617e9a3c03d3fed8e28aca2f4022c369544c404 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 11 Mar 2019 08:59:30 -0400 Subject: [PATCH 1021/2161] Added a C header that translates from the source file's encoding to PetSCII. It can be used to undo what "cbm_screen_charmap.h" does. Together, those headers let you mix screen-code and PetSCII string and character literals in a C source file's Assembly output. --- include/cbm_petscii_charmap.h | 297 ++++++++++++++++++++++++++++++++++ 1 file changed, 297 insertions(+) create mode 100644 include/cbm_petscii_charmap.h diff --git a/include/cbm_petscii_charmap.h b/include/cbm_petscii_charmap.h new file mode 100644 index 000000000..ebf478f19 --- /dev/null +++ b/include/cbm_petscii_charmap.h @@ -0,0 +1,297 @@ +/*****************************************************************************/ +/* */ +/* cbm_petscii_charmap.h */ +/* */ +/* CBM system standard string mapping (ISO-8859-1 -> PetSCII) */ +/* */ +/* */ +/* 2019-03-10, Greg King */ +/* */ +/* 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 must not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + +/* No include guard here! Multiple use in one file might be intentional. */ + +#pragma warn (remap-zero, push, off) + +#pragma charmap (0x00, 0x00) +#pragma charmap (0x01, 0x01) +#pragma charmap (0x02, 0x02) +#pragma charmap (0x03, 0x03) +#pragma charmap (0x04, 0x04) +#pragma charmap (0x05, 0x05) +#pragma charmap (0x06, 0x06) +#pragma charmap (0x07, 0x07) +#pragma charmap (0x08, 0x14) +#pragma charmap (0x09, 0x09) +#pragma charmap (0x0A, 0x0D) +#pragma charmap (0x0B, 0x11) +#pragma charmap (0x0C, 0x93) +#pragma charmap (0x0D, 0x0A) +#pragma charmap (0x0E, 0x0E) +#pragma charmap (0x0F, 0x0F) +#pragma charmap (0x10, 0x10) +#pragma charmap (0x11, 0x0B) +#pragma charmap (0x12, 0x12) +#pragma charmap (0x13, 0x13) +#pragma charmap (0x14, 0x08) +#pragma charmap (0x15, 0x15) +#pragma charmap (0x16, 0x16) +#pragma charmap (0x17, 0x17) +#pragma charmap (0x18, 0x18) +#pragma charmap (0x19, 0x19) +#pragma charmap (0x1A, 0x1A) +#pragma charmap (0x1B, 0x1B) +#pragma charmap (0x1C, 0x1C) +#pragma charmap (0x1D, 0x1D) +#pragma charmap (0x1E, 0x1E) +#pragma charmap (0x1F, 0x1F) + +#pragma charmap (0x20, 0x20) +#pragma charmap (0x21, 0x21) +#pragma charmap (0x22, 0x22) +#pragma charmap (0x23, 0x23) +#pragma charmap (0x24, 0x24) +#pragma charmap (0x25, 0x25) +#pragma charmap (0x26, 0x26) +#pragma charmap (0x27, 0x27) +#pragma charmap (0x28, 0x28) +#pragma charmap (0x29, 0x29) +#pragma charmap (0x2A, 0x2A) +#pragma charmap (0x2B, 0x2B) +#pragma charmap (0x2C, 0x2C) +#pragma charmap (0x2D, 0x2D) +#pragma charmap (0x2E, 0x2E) +#pragma charmap (0x2F, 0x2F) +#pragma charmap (0x30, 0x30) +#pragma charmap (0x31, 0x31) +#pragma charmap (0x32, 0x32) +#pragma charmap (0x33, 0x33) +#pragma charmap (0x34, 0x34) +#pragma charmap (0x35, 0x35) +#pragma charmap (0x36, 0x36) +#pragma charmap (0x37, 0x37) +#pragma charmap (0x38, 0x38) +#pragma charmap (0x39, 0x39) +#pragma charmap (0x3A, 0x3A) +#pragma charmap (0x3B, 0x3B) +#pragma charmap (0x3C, 0x3C) +#pragma charmap (0x3D, 0x3D) +#pragma charmap (0x3E, 0x3E) +#pragma charmap (0x3F, 0x3F) + +#pragma charmap (0x40, 0x40) +#pragma charmap (0x41, 0xC1) +#pragma charmap (0x42, 0xC2) +#pragma charmap (0x43, 0xC3) +#pragma charmap (0x44, 0xC4) +#pragma charmap (0x45, 0xC5) +#pragma charmap (0x46, 0xC6) +#pragma charmap (0x47, 0xC7) +#pragma charmap (0x48, 0xC8) +#pragma charmap (0x49, 0xC9) +#pragma charmap (0x4A, 0xCA) +#pragma charmap (0x4B, 0xCB) +#pragma charmap (0x4C, 0xCC) +#pragma charmap (0x4D, 0xCD) +#pragma charmap (0x4E, 0xCE) +#pragma charmap (0x4F, 0xCF) +#pragma charmap (0x50, 0xD0) +#pragma charmap (0x51, 0xD1) +#pragma charmap (0x52, 0xD2) +#pragma charmap (0x53, 0xD3) +#pragma charmap (0x54, 0xD4) +#pragma charmap (0x55, 0xD5) +#pragma charmap (0x56, 0xD6) +#pragma charmap (0x57, 0xD7) +#pragma charmap (0x58, 0xD8) +#pragma charmap (0x59, 0xD9) +#pragma charmap (0x5A, 0xDA) +#pragma charmap (0x5B, 0x5B) +#pragma charmap (0x5C, 0xBF) +#pragma charmap (0x5D, 0x5D) +#pragma charmap (0x5E, 0x5E) +#pragma charmap (0x5F, 0xA4) + +#pragma charmap (0x60, 0xAD) +#pragma charmap (0x61, 0x41) +#pragma charmap (0x62, 0x42) +#pragma charmap (0x63, 0x43) +#pragma charmap (0x64, 0x44) +#pragma charmap (0x65, 0x45) +#pragma charmap (0x66, 0x46) +#pragma charmap (0x67, 0x47) +#pragma charmap (0x68, 0x48) +#pragma charmap (0x69, 0x49) +#pragma charmap (0x6A, 0x4A) +#pragma charmap (0x6B, 0x4B) +#pragma charmap (0x6C, 0x4C) +#pragma charmap (0x6D, 0x4D) +#pragma charmap (0x6E, 0x4E) +#pragma charmap (0x6F, 0x4F) +#pragma charmap (0x70, 0x50) +#pragma charmap (0x71, 0x51) +#pragma charmap (0x72, 0x52) +#pragma charmap (0x73, 0x53) +#pragma charmap (0x74, 0x54) +#pragma charmap (0x75, 0x55) +#pragma charmap (0x76, 0x56) +#pragma charmap (0x77, 0x57) +#pragma charmap (0x78, 0x58) +#pragma charmap (0x79, 0x59) +#pragma charmap (0x7A, 0x5A) +#pragma charmap (0x7B, 0xB3) +#pragma charmap (0x7C, 0xDD) +#pragma charmap (0x7D, 0xAB) +#pragma charmap (0x7E, 0xB1) +#pragma charmap (0x7F, 0xDF) + +#pragma charmap (0x80, 0x80) +#pragma charmap (0x81, 0x81) +#pragma charmap (0x82, 0x82) +#pragma charmap (0x83, 0x83) +#pragma charmap (0x84, 0x84) +#pragma charmap (0x85, 0x85) +#pragma charmap (0x86, 0x86) +#pragma charmap (0x87, 0x87) +#pragma charmap (0x88, 0x88) +#pragma charmap (0x89, 0x89) +#pragma charmap (0x8A, 0x8A) +#pragma charmap (0x8B, 0x8B) +#pragma charmap (0x8C, 0x8C) +#pragma charmap (0x8D, 0x8D) +#pragma charmap (0x8E, 0x8E) +#pragma charmap (0x8F, 0x8F) +#pragma charmap (0x90, 0x90) +#pragma charmap (0x91, 0x91) +#pragma charmap (0x92, 0x92) +#pragma charmap (0x93, 0x0C) +#pragma charmap (0x94, 0x94) +#pragma charmap (0x95, 0x95) +#pragma charmap (0x96, 0x96) +#pragma charmap (0x97, 0x97) +#pragma charmap (0x98, 0x98) +#pragma charmap (0x99, 0x99) +#pragma charmap (0x9A, 0x9A) +#pragma charmap (0x9B, 0x9B) +#pragma charmap (0x9C, 0x9C) +#pragma charmap (0x9D, 0x9D) +#pragma charmap (0x9E, 0x9E) +#pragma charmap (0x9F, 0x9F) + +#pragma charmap (0xA0, 0xA0) +#pragma charmap (0xA1, 0xA1) +#pragma charmap (0xA2, 0xA2) +#pragma charmap (0xA3, 0xA3) +#pragma charmap (0xA4, 0xA4) +#pragma charmap (0xA5, 0xA5) +#pragma charmap (0xA6, 0xA6) +#pragma charmap (0xA7, 0xA7) +#pragma charmap (0xA8, 0xA8) +#pragma charmap (0xA9, 0xA9) +#pragma charmap (0xAA, 0xAA) +#pragma charmap (0xAB, 0xAB) +#pragma charmap (0xAC, 0xAC) +#pragma charmap (0xAD, 0xAD) +#pragma charmap (0xAE, 0xAE) +#pragma charmap (0xAF, 0xAF) +#pragma charmap (0xB0, 0xB0) +#pragma charmap (0xB1, 0xB1) +#pragma charmap (0xB2, 0xB2) +#pragma charmap (0xB3, 0xB3) +#pragma charmap (0xB4, 0xB4) +#pragma charmap (0xB5, 0xB5) +#pragma charmap (0xB6, 0xB6) +#pragma charmap (0xB7, 0xB7) +#pragma charmap (0xB8, 0xB8) +#pragma charmap (0xB9, 0xB9) +#pragma charmap (0xBA, 0xBA) +#pragma charmap (0xBB, 0xBB) +#pragma charmap (0xBC, 0xBC) +#pragma charmap (0xBD, 0xBD) +#pragma charmap (0xBE, 0xBE) +#pragma charmap (0xBF, 0xBF) + +#pragma charmap (0xC0, 0x60) +#pragma charmap (0xC1, 0x61) +#pragma charmap (0xC2, 0x62) +#pragma charmap (0xC3, 0x63) +#pragma charmap (0xC4, 0x64) +#pragma charmap (0xC5, 0x65) +#pragma charmap (0xC6, 0x66) +#pragma charmap (0xC7, 0x67) +#pragma charmap (0xC8, 0x68) +#pragma charmap (0xC9, 0x69) +#pragma charmap (0xCA, 0x6A) +#pragma charmap (0xCB, 0x6B) +#pragma charmap (0xCC, 0x6C) +#pragma charmap (0xCD, 0x6D) +#pragma charmap (0xCE, 0x6E) +#pragma charmap (0xCF, 0x6F) +#pragma charmap (0xD0, 0x70) +#pragma charmap (0xD1, 0x71) +#pragma charmap (0xD2, 0x72) +#pragma charmap (0xD3, 0x73) +#pragma charmap (0xD4, 0x74) +#pragma charmap (0xD5, 0x75) +#pragma charmap (0xD6, 0x76) +#pragma charmap (0xD7, 0x77) +#pragma charmap (0xD8, 0x78) +#pragma charmap (0xD9, 0x79) +#pragma charmap (0xDA, 0x7A) +#pragma charmap (0xDB, 0x7B) +#pragma charmap (0xDC, 0x7C) +#pragma charmap (0xDD, 0x7D) +#pragma charmap (0xDE, 0x7E) +#pragma charmap (0xDF, 0x7F) + +#pragma charmap (0xE0, 0xE0) +#pragma charmap (0xE1, 0xE1) +#pragma charmap (0xE2, 0xE2) +#pragma charmap (0xE3, 0xE3) +#pragma charmap (0xE4, 0xE4) +#pragma charmap (0xE5, 0xE5) +#pragma charmap (0xE6, 0xE6) +#pragma charmap (0xE7, 0xE7) +#pragma charmap (0xE8, 0xE8) +#pragma charmap (0xE9, 0xE9) +#pragma charmap (0xEA, 0xEA) +#pragma charmap (0xEB, 0xEB) +#pragma charmap (0xEC, 0xEC) +#pragma charmap (0xED, 0xED) +#pragma charmap (0xEE, 0xEE) +#pragma charmap (0xEF, 0xEF) +#pragma charmap (0xF0, 0xF0) +#pragma charmap (0xF1, 0xF1) +#pragma charmap (0xF2, 0xF2) +#pragma charmap (0xF3, 0xF3) +#pragma charmap (0xF4, 0xF4) +#pragma charmap (0xF5, 0xF5) +#pragma charmap (0xF6, 0xF6) +#pragma charmap (0xF7, 0xF7) +#pragma charmap (0xF8, 0xF8) +#pragma charmap (0xF9, 0xF9) +#pragma charmap (0xFA, 0xFA) +#pragma charmap (0xFB, 0xFB) +#pragma charmap (0xFC, 0xFC) +#pragma charmap (0xFD, 0xFD) +#pragma charmap (0xFE, 0xFE) +#pragma charmap (0xFF, 0xFF) + +#pragma warn (remap-zero, pop) From bcbcbbd9c0c1034b07f01acca7cc4c0b4597559a Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Wed, 13 Mar 2019 08:19:04 +0100 Subject: [PATCH 1022/2161] AtariOS: Fix for FPIDX enum --- include/_atarios.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/_atarios.h b/include/_atarios.h index 9a8a864b7..bed840100 100644 --- a/include/_atarios.h +++ b/include/_atarios.h @@ -150,12 +150,12 @@ struct __fpreg { typedef struct __fpreg fpreg_t; -enum { /* enum for access of floating point registers */ +enum FPIDX { /* enum for access of floating point registers */ R0 = 0, /* (to use as index) */ RE = 1, R1 = 2, R2 = 3 -} FPIDX; +}; /* Define a structure with atari os register offsets */ From 5c8854fff61b8c1e9b2f4a4e39691d558e11016a Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sat, 16 Mar 2019 20:37:42 +0100 Subject: [PATCH 1023/2161] Changed enum for FP-register index. --- include/_atarios.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/_atarios.h b/include/_atarios.h index bed840100..c15a99439 100644 --- a/include/_atarios.h +++ b/include/_atarios.h @@ -150,11 +150,11 @@ struct __fpreg { typedef struct __fpreg fpreg_t; -enum FPIDX { /* enum for access of floating point registers */ - R0 = 0, /* (to use as index) */ - RE = 1, - R1 = 2, - R2 = 3 +enum { /* enum for access of floating point registers */ + FPIDX_R0 = 0, /* (to use as index) */ + FPIDX_RE = 1, + FPIDX_R1 = 2, + FPIDX_R2 = 3 }; @@ -291,7 +291,7 @@ struct __os { unsigned char _free_1[0xD4-0x7F-1]; // USER SPACE // Floating Point Package Page Zero Address Equates - fpreg_t fpreg[4]; // = $D4-$EB 4 REGSITERS, ACCCESS LIKE "fpreg[R0].fr" + fpreg_t fpreg[4]; // = $D4-$EB 4 REGSITERS, ACCCESS LIKE "fpreg[FPIDX_R0].fr" unsigned char frx; // = $EC 1-BYTE TEMPORARY unsigned char eexp; // = $ED VALUE OF EXP #ifdef OS_REV2 From 2eac69a94361323bf7556d2cdde8f61c85c5ef99 Mon Sep 17 00:00:00 2001 From: Bas Wassink <b.wassink@ziggo.nl> Date: Fri, 22 Mar 2019 22:54:05 +0100 Subject: [PATCH 1024/2161] Remove trailings spaces from CBM-related asm files --- libsrc/c128/kbhit.s | 3 --- libsrc/c64/acc_chameleon_speed.s | 2 +- libsrc/c64/emd/c64-ram.s | 4 ++-- libsrc/c64/emd/c64-reu.s | 2 +- libsrc/c64/mouse_stddrv.s | 1 - libsrc/c64/randomize.s | 2 +- libsrc/c64/sysuname.s | 2 -- libsrc/cbm/cclear.s | 2 +- libsrc/cbm/dir.s | 2 +- libsrc/cbm/gotox.s | 4 +--- libsrc/cbm/open.s | 2 -- libsrc/cbm510/_scrsize.s | 3 +-- libsrc/cbm510/kopen.s | 6 ++---- libsrc/cbm510/kudtim.s | 2 +- libsrc/cbm610/_scrsize.s | 3 +-- libsrc/cbm610/kopen.s | 6 ++---- libsrc/cbm610/ksetnam.s | 4 +--- libsrc/cbm610/kudtim.s | 2 +- libsrc/cbm610/randomize.s | 2 +- libsrc/pet/kbsout.s | 2 -- libsrc/pet/kckout.s | 2 -- libsrc/pet/kclose.s | 3 +-- libsrc/pet/krdtim.s | 3 +-- libsrc/pet/ksetlfs.s | 3 +-- libsrc/pet/ksetnam.s | 3 +-- libsrc/pet/randomize.s | 2 +- libsrc/plus4/break.s | 3 +-- libsrc/vic20/emd/vic20-rama.s | 4 ++-- libsrc/vic20/kplot.s | 3 +-- libsrc/vic20/mainargs.s | 2 +- 30 files changed, 28 insertions(+), 56 deletions(-) diff --git a/libsrc/c128/kbhit.s b/libsrc/c128/kbhit.s index c1bca2416..0d4deacdf 100644 --- a/libsrc/c128/kbhit.s +++ b/libsrc/c128/kbhit.s @@ -20,6 +20,3 @@ L9: rts .endproc - - - diff --git a/libsrc/c64/acc_chameleon_speed.s b/libsrc/c64/acc_chameleon_speed.s index ce51b9dde..f73fddd01 100755 --- a/libsrc/c64/acc_chameleon_speed.s +++ b/libsrc/c64/acc_chameleon_speed.s @@ -5,7 +5,7 @@ ; unsigned char __fastcall__ set_chameleon_speed (unsigned char speed); ; ;/* Set the speed of the Chameleon cartridge, the following inputs -; * are accepted: +; * are accepted: ; * SPEED_SLOW : 1 Mhz mode ; * SPEED_1X : 1 Mhz mode ; * SPEED_2X : 2 Mhz mode diff --git a/libsrc/c64/emd/c64-ram.s b/libsrc/c64/emd/c64-ram.s index b41f932e6..5355b552d 100644 --- a/libsrc/c64/emd/c64-ram.s +++ b/libsrc/c64/emd/c64-ram.s @@ -167,7 +167,7 @@ loop: .repeat 8 ; Done -done: rts +done: rts ; ------------------------------------------------------------------------ ; COPYFROM: Copy from extended into linear memory. A pointer to a structure @@ -178,7 +178,7 @@ done: rts COPYFROM: sta ptr3 stx ptr3+1 ; Save the passed em_copy pointer - + ldy #EM_COPY::OFFS lda (ptr3),y sta ptr1 diff --git a/libsrc/c64/emd/c64-reu.s b/libsrc/c64/emd/c64-reu.s index bf7bb4fb0..a563305ce 100644 --- a/libsrc/c64/emd/c64-reu.s +++ b/libsrc/c64/emd/c64-reu.s @@ -190,7 +190,7 @@ done: rts ; ------------------------------------------------------------------------ ; USE: Tell the driver that the window is now associated with a given page. - + USE: sta curpage stx curpage+1 ; Remember the page lda #<window diff --git a/libsrc/c64/mouse_stddrv.s b/libsrc/c64/mouse_stddrv.s index b53440a52..f3a2c6499 100644 --- a/libsrc/c64/mouse_stddrv.s +++ b/libsrc/c64/mouse_stddrv.s @@ -12,4 +12,3 @@ _mouse_stddrv: .asciiz "c64-1351.mou" - diff --git a/libsrc/c64/randomize.s b/libsrc/c64/randomize.s index d74bae91e..a875203af 100644 --- a/libsrc/c64/randomize.s +++ b/libsrc/c64/randomize.s @@ -11,7 +11,7 @@ .include "c64.inc" -__randomize: +__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/c64/sysuname.s b/libsrc/c64/sysuname.s index 15546bfa3..2d185a1c8 100644 --- a/libsrc/c64/sysuname.s +++ b/libsrc/c64/sysuname.s @@ -35,5 +35,3 @@ utsdata: ; machine .asciiz "Commodore 64" - - diff --git a/libsrc/cbm/cclear.s b/libsrc/cbm/cclear.s index 14b9d0e8b..e6277eed0 100644 --- a/libsrc/cbm/cclear.s +++ b/libsrc/cbm/cclear.s @@ -17,7 +17,7 @@ _cclearxy: _cclear: cmp #0 ; Is the length zero? beq L9 ; Jump if done - sta tmp1 + sta tmp1 L1: lda #$20 ; Blank - screen code jsr cputdirect ; Direct output dec tmp1 diff --git a/libsrc/cbm/dir.s b/libsrc/cbm/dir.s index fddd71d7c..808fcf982 100644 --- a/libsrc/cbm/dir.s +++ b/libsrc/cbm/dir.s @@ -7,7 +7,7 @@ .include "dir.inc" .include "errno.inc" .include "zeropage.inc" - + .import pushax .import _read diff --git a/libsrc/cbm/gotox.s b/libsrc/cbm/gotox.s index f122a276c..76f56cb4b 100644 --- a/libsrc/cbm/gotox.s +++ b/libsrc/cbm/gotox.s @@ -5,11 +5,9 @@ ; .export _gotox - .import plot + .import plot .importzp CURS_X _gotox: sta CURS_X ; Set new position jmp plot ; And activate it - - diff --git a/libsrc/cbm/open.s b/libsrc/cbm/open.s index f23e97383..317f9eaa2 100644 --- a/libsrc/cbm/open.s +++ b/libsrc/cbm/open.s @@ -194,5 +194,3 @@ nofile: ; ... else use SA=0 (read) .endproc - - diff --git a/libsrc/cbm510/_scrsize.s b/libsrc/cbm510/_scrsize.s index 8b68b8cdc..5f3076920 100644 --- a/libsrc/cbm510/_scrsize.s +++ b/libsrc/cbm510/_scrsize.s @@ -6,7 +6,6 @@ .export screensize .import SCREEN - + screensize = SCREEN - diff --git a/libsrc/cbm510/kopen.s b/libsrc/cbm510/kopen.s index 025922320..7358b091a 100644 --- a/libsrc/cbm510/kopen.s +++ b/libsrc/cbm510/kopen.s @@ -3,10 +3,10 @@ ; ; OPEN kernal call. ; -; NOTE: The OPEN system call in the CBM610 kernal is different from the +; NOTE: The OPEN system call in the CBM610 kernal is different from the ; standard. It evaluates the carry flag and does a normal open if carry clear ; and some strange things (output sa 15 + name on IEC) if carry set. To be -; compatible with our CBM file stuff, we have to clear the carry before +; compatible with our CBM file stuff, we have to clear the carry before ; calling the real OPEN. .export OPEN @@ -18,5 +18,3 @@ .endproc - - diff --git a/libsrc/cbm510/kudtim.s b/libsrc/cbm510/kudtim.s index 6862787fb..f587e5aa0 100644 --- a/libsrc/cbm510/kudtim.s +++ b/libsrc/cbm510/kudtim.s @@ -3,7 +3,7 @@ ; ; udtim routine for the 610. We will not check for the stop key here, since ; C programs will not use it. -; +; .export UDTIM .import time: zp diff --git a/libsrc/cbm610/_scrsize.s b/libsrc/cbm610/_scrsize.s index 8b68b8cdc..5f3076920 100644 --- a/libsrc/cbm610/_scrsize.s +++ b/libsrc/cbm610/_scrsize.s @@ -6,7 +6,6 @@ .export screensize .import SCREEN - + screensize = SCREEN - diff --git a/libsrc/cbm610/kopen.s b/libsrc/cbm610/kopen.s index 025922320..7358b091a 100644 --- a/libsrc/cbm610/kopen.s +++ b/libsrc/cbm610/kopen.s @@ -3,10 +3,10 @@ ; ; OPEN kernal call. ; -; NOTE: The OPEN system call in the CBM610 kernal is different from the +; NOTE: The OPEN system call in the CBM610 kernal is different from the ; standard. It evaluates the carry flag and does a normal open if carry clear ; and some strange things (output sa 15 + name on IEC) if carry set. To be -; compatible with our CBM file stuff, we have to clear the carry before +; compatible with our CBM file stuff, we have to clear the carry before ; calling the real OPEN. .export OPEN @@ -18,5 +18,3 @@ .endproc - - diff --git a/libsrc/cbm610/ksetnam.s b/libsrc/cbm610/ksetnam.s index ab5c6d730..97ecf0126 100644 --- a/libsrc/cbm610/ksetnam.s +++ b/libsrc/cbm610/ksetnam.s @@ -12,7 +12,7 @@ .import sys_bank, restore_bank .import sysp0: zp, ktmp: zp - + .include "cbm610.inc" .proc SETNAM @@ -41,5 +41,3 @@ .endproc - - diff --git a/libsrc/cbm610/kudtim.s b/libsrc/cbm610/kudtim.s index 6862787fb..f587e5aa0 100644 --- a/libsrc/cbm610/kudtim.s +++ b/libsrc/cbm610/kudtim.s @@ -3,7 +3,7 @@ ; ; udtim routine for the 610. We will not check for the stop key here, since ; C programs will not use it. -; +; .export UDTIM .import time: zp diff --git a/libsrc/cbm610/randomize.s b/libsrc/cbm610/randomize.s index d313baa1b..75c419ccb 100644 --- a/libsrc/cbm610/randomize.s +++ b/libsrc/cbm610/randomize.s @@ -10,7 +10,7 @@ .import _srand .importzp time -__randomize: +__randomize: ldx time+2 ; Use 50/60HZ clock lda time+1 jmp _srand ; Initialize generator diff --git a/libsrc/pet/kbsout.s b/libsrc/pet/kbsout.s index 1e8912324..178ac8205 100644 --- a/libsrc/pet/kbsout.s +++ b/libsrc/pet/kbsout.s @@ -15,5 +15,3 @@ .endproc - - diff --git a/libsrc/pet/kckout.s b/libsrc/pet/kckout.s index 8c5f4d415..65c4e8142 100644 --- a/libsrc/pet/kckout.s +++ b/libsrc/pet/kckout.s @@ -15,5 +15,3 @@ .endproc - - diff --git a/libsrc/pet/kclose.s b/libsrc/pet/kclose.s index 1da034017..c7eb19ea0 100644 --- a/libsrc/pet/kclose.s +++ b/libsrc/pet/kclose.s @@ -10,7 +10,7 @@ .proc CLOSE - + ldx PET_DETECT cpx #PET_4000 bne @L1 @@ -19,4 +19,3 @@ .endproc - diff --git a/libsrc/pet/krdtim.s b/libsrc/pet/krdtim.s index 355cce3d8..cce218928 100644 --- a/libsrc/pet/krdtim.s +++ b/libsrc/pet/krdtim.s @@ -5,7 +5,7 @@ ; .export RDTIM - + .include "pet.inc" @@ -20,4 +20,3 @@ .endproc - diff --git a/libsrc/pet/ksetlfs.s b/libsrc/pet/ksetlfs.s index 6e9065ac7..50e6471e3 100644 --- a/libsrc/pet/ksetlfs.s +++ b/libsrc/pet/ksetlfs.s @@ -15,7 +15,6 @@ stx DEVNUM ; Device address sty SECADR ; Secondary address rts - + .endproc - diff --git a/libsrc/pet/ksetnam.s b/libsrc/pet/ksetnam.s index 0bf6411bd..9a911e38b 100644 --- a/libsrc/pet/ksetnam.s +++ b/libsrc/pet/ksetnam.s @@ -10,7 +10,7 @@ .proc SETNAM - + sta FNLEN stx FNADR sty FNADR+1 @@ -18,4 +18,3 @@ .endproc - diff --git a/libsrc/pet/randomize.s b/libsrc/pet/randomize.s index 2c0fe722a..44bf4c38e 100644 --- a/libsrc/pet/randomize.s +++ b/libsrc/pet/randomize.s @@ -11,7 +11,7 @@ .include "pet.inc" -__randomize: +__randomize: ldx TIME+2 lda TIME+1 ; Use 60HZ clock jmp _srand ; Initialize generator diff --git a/libsrc/plus4/break.s b/libsrc/plus4/break.s index 917304425..03d2ee97a 100644 --- a/libsrc/plus4/break.s +++ b/libsrc/plus4/break.s @@ -55,7 +55,7 @@ uservec: jmp $FFFF ; Patched at runtime -; Break handler, called if a break occurs. +; Break handler, called if a break occurs. .proc brk_handler @@ -91,4 +91,3 @@ uservec: jmp $FFFF ; Patched at runtime .endproc - diff --git a/libsrc/vic20/emd/vic20-rama.s b/libsrc/vic20/emd/vic20-rama.s index a48959c13..133c3974b 100644 --- a/libsrc/vic20/emd/vic20-rama.s +++ b/libsrc/vic20/emd/vic20-rama.s @@ -167,7 +167,7 @@ loop: .repeat 8 ; Done -done: rts +done: rts ; ------------------------------------------------------------------------ ; COPYFROM: Copy from extended into linear memory. A pointer to a structure @@ -178,7 +178,7 @@ done: rts COPYFROM: sta ptr3 stx ptr3+1 ; Save the passed em_copy pointer - + ldy #EM_COPY::OFFS lda (ptr3),y sta ptr1 diff --git a/libsrc/vic20/kplot.s b/libsrc/vic20/kplot.s index 2f4de2754..f37ed8fce 100644 --- a/libsrc/vic20/kplot.s +++ b/libsrc/vic20/kplot.s @@ -10,7 +10,7 @@ .proc PLOT - bcs @L1 + bcs @L1 jsr $FFF0 ; Set cursor position jmp $EAB2 ; Set pointer to color RAM @@ -18,4 +18,3 @@ .endproc - diff --git a/libsrc/vic20/mainargs.s b/libsrc/vic20/mainargs.s index b24745c08..84e256615 100644 --- a/libsrc/vic20/mainargs.s +++ b/libsrc/vic20/mainargs.s @@ -102,7 +102,7 @@ argloop:lda BASIC_BUF,x 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. From 0614078198d69d3d891fe669e4703e8a60beddca Mon Sep 17 00:00:00 2001 From: Bas Wassink <b.wassink@ziggo.nl> Date: Sat, 23 Mar 2019 01:14:04 +0100 Subject: [PATCH 1025/2161] Fix 32/64-bit int/pointer casts --- src/cc65/locals.c | 5 +++-- src/cc65/symtab.c | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 36afb6223..024c1c5fc 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -275,8 +275,9 @@ static void ParseAutoDecl (Declaration* Decl) ** We abuse the Collection somewhat by using it to store line ** numbers. */ - CollReplace (&CurrentFunc->LocalsBlockStack, (void *)(long)GetCurrentLine (), - CollCount (&CurrentFunc->LocalsBlockStack) - 1); + CollReplace (&CurrentFunc->LocalsBlockStack, + (void *)(size_t)GetCurrentLine (), + CollCount (&CurrentFunc->LocalsBlockStack) - 1); } else { /* Non-initialized local variable. Just keep track of diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 9eb0346e8..bdbec55bb 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -671,7 +671,7 @@ DefOrRef* AddDefOrRef (SymEntry* E, unsigned Flags) DOR = xmalloc (sizeof (DefOrRef)); CollAppend (E->V.L.DefsOrRefs, DOR); DOR->Line = GetCurrentLine (); - DOR->LocalsBlockId = (long)CollLast (&CurrentFunc->LocalsBlockStack); + DOR->LocalsBlockId = (ssize_t)CollLast (&CurrentFunc->LocalsBlockStack); DOR->Flags = Flags; DOR->StackPtr = StackPtr; DOR->Depth = CollCount (&CurrentFunc->LocalsBlockStack); @@ -729,9 +729,9 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* Are we jumping into a block with initalization of an object that ** has automatic storage duration? Let's emit a warning. */ - if ((long)CollLast (AIC) != DOR->LocalsBlockId && + if ((size_t)CollLast (AIC) != (size_t)(DOR->LocalsBlockId) && (CollCount (AIC) < DOR->Depth || - (long)CollAt (AIC, DOR->Depth - 1) != DOR->LocalsBlockId)) { + (size_t)CollAt (AIC, DOR->Depth - 1) != DOR->LocalsBlockId)) { Warning ("Goto at line %d to label %s jumps into a block with " "initialization of an object that has automatic storage duration", GetCurrentLine (), Name); @@ -758,9 +758,9 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* Are we jumping into a block with initalization of an object that ** has automatic storage duration? Let's emit a warning. */ - if ((long)CollLast (AIC) != DOR->LocalsBlockId && + if ((ssize_t)CollLast (AIC) != DOR->LocalsBlockId && (CollCount (AIC) >= DOR->Depth || - (long)CollLast (AIC) >= (long)DOR->Line)) + (ssize_t)CollLast (AIC) >= (long)DOR->Line)) Warning ("Goto at line %d to label %s jumps into a block with " "initialization of an object that has automatic storage duration", DOR->Line, Name); From f94a125f30e561419fb731635403aa7b103b0c00 Mon Sep 17 00:00:00 2001 From: Daniel Serpell <daniel.serpell@gmail.com> Date: Sat, 23 Mar 2019 12:19:25 -0300 Subject: [PATCH 1026/2161] Adds address after JVB instruction in the display list example. --- doc/atari.sgml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/atari.sgml b/doc/atari.sgml index 49993d22c..1affc8362 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -392,7 +392,8 @@ void DisplayList = DL_CHR20x8x2, DL_BLK4, DL_CHR20x8x2, - DL_JVB + DL_JVB, + &DisplayList }; ... OS.sdlst = &DisplayList; From 2cd4b5109a59c3743b38369359c389cc1b9edab4 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 24 Mar 2019 14:39:04 -0400 Subject: [PATCH 1027/2161] Fixed LinuxDoc Tools issues in some verbatim blocks in the Atari document. --- doc/atari.sgml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/atari.sgml b/doc/atari.sgml index 1affc8362..eecd1b803 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -297,13 +297,13 @@ This also includes access to operating system locations (e.g. hardware shadow re "<tt/OS/". The names are the usual ones you can find in system reference manuals. Example: -<verb> +<tscreen><verb> ... OS.savmsc = ScreenMemory; OS.color4 = 14; // white frame if (OS.stick0 != 15 || OS.ch != 255) // key or stick input? ... -</verb> +</verb></tscreen> Please note that memory location 762/$2FA is called "<tt/char_/" while the orignal name "<tt/char/" conflicts with the C keyword. @@ -376,7 +376,7 @@ cc65 supports constructing these display lists by offering defines for the instructions. In conjunction with the "void"-variable extension of cc65, display lists can be created quite comfortable: -<verb> +<tscreen><verb> ... unsigned char ScreenMemory[100]; @@ -393,12 +393,12 @@ void DisplayList = DL_BLK4, DL_CHR20x8x2, DL_JVB, - &DisplayList + &DisplayList }; ... OS.sdlst = &DisplayList; ... -</verb> +</verb></tscreen> Please inspect the <tt/_antic.h/ header file to detemine the supported instruction names. Modifiers on instructions can be nested without need @@ -445,23 +445,23 @@ A final note: Since cc65 has currently some difficulties with string merging under different mappings, defining remapped strings works only flawlessly with static array initialization: -<verb> +<tscreen><verb> #include <atari_screen_charmap.h> char pcScreenMappingString[] = "Hello Atari!"; #include <atari_atascii_charmap.h> char pcAtasciiMappingString[] = "Hello Atari!"; -</verb> +</verb></tscreen> delivers correct results, while -<verb> +<tscreen><verb> #include <atari_screen_charmap.h> char* pcScreenMappingString = "Hello Atari!"; #include <atari_atascii_charmap.h> char* pcAtasciiMappingString = "Hello Atari!"; -</verb> +</verb></tscreen> does not. @@ -471,7 +471,7 @@ For direct keyboard scanning in conjunction with e.g. the OS location "CH" (764/ all keyboard codes are available as defined values on C and assembler side. Example: -<verb> +<tscreen><verb> ... while (!kbhit()); switch (OS.ch) @@ -484,7 +484,7 @@ Example: ... } ... -</verb> +</verb></tscreen> You can find the C defines in the file "<tt/atari.h/" or "<tt/atari.inc/" for the assembler variant. From 56c96e8ab0f1d0b80c86f0d24d48c64ada4f00ed Mon Sep 17 00:00:00 2001 From: Bas Wassink <b.wassink@ziggo.nl> Date: Sun, 24 Mar 2019 21:15:34 +0100 Subject: [PATCH 1028/2161] Revert accidentally committed changes for a future PR --- src/cc65/locals.c | 2 +- src/cc65/symtab.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 02155f412..e2e71e96c 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -276,7 +276,7 @@ static void ParseAutoDecl (Declaration* Decl) ** numbers. */ CollReplace (&CurrentFunc->LocalsBlockStack, - (void *)(size_t)GetCurrentLine (), + (void *)(long)GetCurrentLine (), CollCount (&CurrentFunc->LocalsBlockStack) - 1); } else { diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 72f7f54da..02b7f0501 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -671,7 +671,7 @@ DefOrRef* AddDefOrRef (SymEntry* E, unsigned Flags) DOR = xmalloc (sizeof (DefOrRef)); CollAppend (E->V.L.DefsOrRefs, DOR); DOR->Line = GetCurrentLine (); - DOR->LocalsBlockId = (ssize_t)CollLast (&CurrentFunc->LocalsBlockStack); + DOR->LocalsBlockId = CollLast (&CurrentFunc->LocalsBlockStack); DOR->Flags = Flags; DOR->StackPtr = StackPtr; DOR->Depth = CollCount (&CurrentFunc->LocalsBlockStack); @@ -729,9 +729,9 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* Are we jumping into a block with initalization of an object that ** has automatic storage duration? Let's emit a warning. */ - if ((size_t)CollLast (AIC) != (size_t)(DOR->LocalsBlockId) && + if ((long)CollLast (AIC) != DOR->LocalsBlockId && (CollCount (AIC) < DOR->Depth || - (size_t)CollAt (AIC, DOR->Depth - 1) != DOR->LocalsBlockId)) { + (long)CollAt (AIC, DOR->Depth - 1) != DOR->LocalsBlockId)) { Warning ("Goto at line %d to label %s jumps into a block with " "initialization of an object that has automatic storage duration", GetCurrentLine (), Name); @@ -758,9 +758,9 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* Are we jumping into a block with initalization of an object that ** has automatic storage duration? Let's emit a warning. */ - if ((ssize_t)CollLast (AIC) != DOR->LocalsBlockId && + if ((long)CollLast (AIC) != DOR->LocalsBlockId && (CollCount (AIC) >= DOR->Depth || - (ssize_t)CollLast (AIC) >= (long)DOR->Line)) + (long)CollLast (AIC) >= (long)DOR->Line)) Warning ("Goto at line %d to label %s jumps into a block with " "initialization of an object that has automatic storage duration", DOR->Line, Name); From 41e449b306ca207052a481e7be505a4fc490708c Mon Sep 17 00:00:00 2001 From: Bas Wassink <b.wassink@ziggo.nl> Date: Sun, 24 Mar 2019 21:41:00 +0100 Subject: [PATCH 1029/2161] Forgot a cast, sorry --- 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 02b7f0501..56196ea5a 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -671,7 +671,7 @@ DefOrRef* AddDefOrRef (SymEntry* E, unsigned Flags) DOR = xmalloc (sizeof (DefOrRef)); CollAppend (E->V.L.DefsOrRefs, DOR); DOR->Line = GetCurrentLine (); - DOR->LocalsBlockId = CollLast (&CurrentFunc->LocalsBlockStack); + DOR->LocalsBlockId = (long)CollLast (&CurrentFunc->LocalsBlockStack); DOR->Flags = Flags; DOR->StackPtr = StackPtr; DOR->Depth = CollCount (&CurrentFunc->LocalsBlockStack); From 9e0ab14cfe0bc107e99d1867792b7c127b1465a8 Mon Sep 17 00:00:00 2001 From: Bas Wassink <b.wassink@ziggo.nl> Date: Sun, 24 Mar 2019 23:05:11 +0100 Subject: [PATCH 1030/2161] Restore src/cc65/locals.c:278 to its orignal state --- src/cc65/locals.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cc65/locals.c b/src/cc65/locals.c index e2e71e96c..d0aab7f9c 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -275,9 +275,8 @@ static void ParseAutoDecl (Declaration* Decl) ** We abuse the Collection somewhat by using it to store line ** numbers. */ - CollReplace (&CurrentFunc->LocalsBlockStack, - (void *)(long)GetCurrentLine (), - CollCount (&CurrentFunc->LocalsBlockStack) - 1); + CollReplace (&CurrentFunc->LocalsBlockStack, (void *)(long)GetCurrentLine (), + CollCount (&CurrentFunc->LocalsBlockStack) - 1); } else { /* Non-initialized local variable. Just keep track of From 399250a105da67f2137ba96316ac9da16633780b Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Thu, 21 Mar 2019 15:59:45 +0100 Subject: [PATCH 1031/2161] Optimized mul20 & mul40 and extracted to new library. --- doc/index.sgml | 3 ++ doc/specialmath.sgml | 38 ++++++++++++++++++++++++ include/specialmath.h | 46 +++++++++++++++++++++++++++++ libsrc/Makefile | 1 + libsrc/atari/cputc.s | 5 ++-- libsrc/atari/mcbtxtchar.s | 15 +++------- libsrc/atari/mul40.s | 35 ---------------------- libsrc/atari/scroll.s | 7 ++--- libsrc/atari/setcursor.s | 5 ++-- libsrc/atari5200/cputc.s | 5 ++-- libsrc/atari5200/mul20.s | 33 --------------------- libsrc/specialmath/mul20.s | 47 ++++++++++++++++++++++++++++++ libsrc/specialmath/mul40.s | 50 ++++++++++++++++++++++++++++++++ test/val/lib_specialmath_mulxx.c | 18 ++++++++++++ 14 files changed, 216 insertions(+), 92 deletions(-) create mode 100644 doc/specialmath.sgml create mode 100644 include/specialmath.h delete mode 100644 libsrc/atari/mul40.s delete mode 100644 libsrc/atari5200/mul20.s create mode 100644 libsrc/specialmath/mul20.s create mode 100644 libsrc/specialmath/mul40.s create mode 100644 test/val/lib_specialmath_mulxx.c diff --git a/doc/index.sgml b/doc/index.sgml index aecfb7de9..55e69f40f 100644 --- a/doc/index.sgml +++ b/doc/index.sgml @@ -97,6 +97,9 @@ Describes Christian Krüger's macro package for writing self modifying assembler code. + <tag><htmlurl url="specialmath.html" name="specialmath.html"></tag> + Library for speed optimized math functions. + <tag><url name="6502 Binary Relocation Format document" url="http://www.6502.org/users/andre/o65/fileformat.html"></tag> Describes the o65 file format that is used for dynamically loadable modules diff --git a/doc/specialmath.sgml b/doc/specialmath.sgml new file mode 100644 index 000000000..18de970eb --- /dev/null +++ b/doc/specialmath.sgml @@ -0,0 +1,38 @@ +<!doctype linuxdoc system> + +<article> +<title>Special math functions +<author>Christian Krüger + +<abstract> +This library provides functions for speed optimized math operations. +</abstract> + +<!-- Table of contents --> +<toc> + +<!-- Begin the document --> + +<sect>Multiplication<p> + +When accessing screen memory often a multiplication of the vertical position is needed to calculate +the target address. A quite common horizontal span for 8-bit systems is 20 or 40 bytes (beside e.g. 32 bytes, where the multiplication can be accomplished by shifting 5 times). + +<p> +<tscreen><verb> + unsigned int __fastcall__ mul20(unsigned char value); +</verb></tscreen> + +The 8 bit <tt>value</tt> is multiplied by 20 and returned as 16 bit value. +</p> + +<p> +<tscreen><verb> + unsigned int __fastcall__ mul40(unsigned char value); +</verb></tscreen> + +The 8 bit <tt>value</tt> is multiplied by 40 and returned as 16 bit value. +</p> + + +</article> diff --git a/include/specialmath.h b/include/specialmath.h new file mode 100644 index 000000000..fa2f65736 --- /dev/null +++ b/include/specialmath.h @@ -0,0 +1,46 @@ +/*****************************************************************************/ +/* */ +/* specialmath.h */ +/* */ +/* Optimized math routines for special usages */ +/* */ +/* */ +/* */ +/* (C) 2019 Christian 'Irgendwer' Krueger */ +/* */ +/* 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 _SPECIALMATH_H +#define _SPECIALMATH_H + + +/* Multiply an 8 bit unsigned value by 20 and return the 16 bit unsigned result */ + +unsigned int __fastcall__ mul20(unsigned char value); + + +/* Multiply an 8 bit unsigned value by 40 and return the 16 bit unsigned result */ + +unsigned int __fastcall__ mul40(unsigned char value); + + + +/* End of specialmath.h */ +#endif diff --git a/libsrc/Makefile b/libsrc/Makefile index 0ebec46b1..4e1a3520d 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -181,6 +181,7 @@ SRCDIRS += common \ mouse \ runtime \ serial \ + specialmath \ tgi \ zlib diff --git a/libsrc/atari/cputc.s b/libsrc/atari/cputc.s index 7132fdca6..cf66fdacf 100644 --- a/libsrc/atari/cputc.s +++ b/libsrc/atari/cputc.s @@ -7,7 +7,7 @@ .export _cputcxy, _cputc .export plot, cputdirect, putchar - .import gotoxy, mul40 + .import gotoxy, _mul40 .importzp tmp4,ptr4 .import _revflag,setcursor @@ -71,8 +71,7 @@ putchar: sta (OLDADR),y lda ROWCRS - jsr mul40 ; destroys tmp4 - clc + jsr _mul40 ; destroys tmp4, carry is cleared adc SAVMSC ; add start of screen memory sta ptr4 txa diff --git a/libsrc/atari/mcbtxtchar.s b/libsrc/atari/mcbtxtchar.s index 90a25f673..4ff79c651 100644 --- a/libsrc/atari/mcbtxtchar.s +++ b/libsrc/atari/mcbtxtchar.s @@ -12,7 +12,7 @@ .export _mouse_txt_callbacks .importzp tmp4 - .import mul40,loc_tmp + .import _mul40 .importzp mouse_txt_char ; screen code of mouse cursor .include "atari.inc" @@ -104,22 +104,15 @@ movex: ; Move the mouse cursor y position to the value in A/X. movey: - tax - ldy tmp4 ; mul40 uses tmp4 - lda loc_tmp ; and this local variable - pha - txa ; get parameter back + ldy tmp4 ; mul40 uses tmp4, save in Y lsr a ; convert y position to character line lsr a lsr a - jsr mul40 - clc + jsr _mul40 ; carry is cleared by _mul40 adc SAVMSC sta scrptr txa adc SAVMSC+1 sta scrptr+1 - pla - sta loc_tmp - sty tmp4 + sty tmp4 ; restore tmp4 rts diff --git a/libsrc/atari/mul40.s b/libsrc/atari/mul40.s deleted file mode 100644 index 96235bf6c..000000000 --- a/libsrc/atari/mul40.s +++ /dev/null @@ -1,35 +0,0 @@ -; -; Christian Groessler, June 2000 -; -; mul40 -; multiplies A by 40 and returns result in AX -; uses tmp4 - - .importzp tmp4 - .export mul40,loc_tmp - -.proc mul40 - - ldx #0 - stx tmp4 - sta loc_tmp - asl a - rol tmp4 - asl a - rol tmp4 ; val * 4 - adc loc_tmp - bcc L1 - inc tmp4 ; val * 5 -L1: asl a - rol tmp4 ; val * 10 - asl a - rol tmp4 - asl a - rol tmp4 ; val * 40 - ldx tmp4 - rts - -.endproc - - .bss -loc_tmp:.res 1 diff --git a/libsrc/atari/scroll.s b/libsrc/atari/scroll.s index 5e8428cc2..4bc0d72ed 100644 --- a/libsrc/atari/scroll.s +++ b/libsrc/atari/scroll.s @@ -8,7 +8,7 @@ .include "atari.inc" .importzp tmp1,tmp4,ptr1,ptr2 - .import mul40,_clrscr + .import _mul40,_clrscr .export __scroll .proc __scroll @@ -40,7 +40,7 @@ down_ok:lda SAVMSC sta ptr2+1 lda tmp1 - jsr mul40 + jsr _mul40 sta tmp4 lda ptr2 sec @@ -103,8 +103,7 @@ up: sta tmp1 ; # of lines to scroll jmp _clrscr ;multiply by 40 (xsize) -up_ok: jsr mul40 - clc +up_ok: jsr _mul40 ; carry is cleared by _mul40 adc SAVMSC ; add start of screen mem sta ptr2 txa diff --git a/libsrc/atari/setcursor.s b/libsrc/atari/setcursor.s index cf596d4fe..c6d844047 100644 --- a/libsrc/atari/setcursor.s +++ b/libsrc/atari/setcursor.s @@ -4,7 +4,7 @@ ; cursor handling, internal function .include "atari.inc" - .import cursor,mul40 + .import cursor,_mul40 .export setcursor .proc setcursor @@ -14,8 +14,7 @@ sta (OLDADR),y lda ROWCRS - jsr mul40 - clc + jsr _mul40 ; function leaves with carry clear! adc SAVMSC ; add start of screen memory sta OLDADR txa diff --git a/libsrc/atari5200/cputc.s b/libsrc/atari5200/cputc.s index 860eea88d..185ad8da8 100644 --- a/libsrc/atari5200/cputc.s +++ b/libsrc/atari5200/cputc.s @@ -10,7 +10,7 @@ .export _cputcxy, _cputc .export plot, cputdirect, putchar - .import gotoxy, mul20 + .import gotoxy, _mul20 .importzp ptr4 .import setcursor @@ -75,8 +75,7 @@ putchar: pha ; save char lda ROWCRS_5200 - jsr mul20 ; destroys tmp4 - clc + jsr _mul20 ; destroys tmp4, carry is cleared adc SAVMSC ; add start of screen memory sta ptr4 txa diff --git a/libsrc/atari5200/mul20.s b/libsrc/atari5200/mul20.s deleted file mode 100644 index fc67b34e4..000000000 --- a/libsrc/atari5200/mul20.s +++ /dev/null @@ -1,33 +0,0 @@ -; -; Christian Groessler, April 2014 -; -; mul20 -; multiplies A by 20 and returns result in AX -; uses tmp4 - - .importzp tmp4 - .export mul20,loc_tmp - -.proc mul20 - - ldx #0 - stx tmp4 - sta loc_tmp - asl a - rol tmp4 - asl a - rol tmp4 ; val * 4 - adc loc_tmp - bcc L1 - inc tmp4 ; val * 5 -L1: asl a - rol tmp4 ; val * 10 - asl a - rol tmp4 ; val * 20 - ldx tmp4 - rts - -.endproc - - .bss -loc_tmp:.res 1 diff --git a/libsrc/specialmath/mul20.s b/libsrc/specialmath/mul20.s new file mode 100644 index 000000000..3339f7dd2 --- /dev/null +++ b/libsrc/specialmath/mul20.s @@ -0,0 +1,47 @@ +; mul20.s +; +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. +; +; +; unsigned int __fastcall__ mul20(unsigned char value); +; +; REMARKS: Function is defined to return with carry-flag cleared + + + .importzp tmp4 + .export _mul20 + +.proc _mul20 ; = 30 bytes, 41/46 cycles + + sta tmp4 ; remember value for later addition... + ldx #0 ; clear high-byte + asl a ; * 2 + bcc mul4 ; high-byte affected? + ldx #2 ; this will be the 1st high-bit soon... + +mul4: asl a ; * 4 + bcc mul5 ; high-byte affected? + inx ; => yes, apply to 0 high-bit + clc ; prepare addition + +mul5: adc tmp4 ; * 5 + bcc mul10 ; high-byte affected? + inx ; yes, correct... + +mul10: stx tmp4 ; continue with classic shifting... + + asl a ; * 10 + rol tmp4 + + asl a ; * 20 + rol tmp4 + + ldx tmp4 ; deliver high-byte in X + rts + +.endproc diff --git a/libsrc/specialmath/mul40.s b/libsrc/specialmath/mul40.s new file mode 100644 index 000000000..110351935 --- /dev/null +++ b/libsrc/specialmath/mul40.s @@ -0,0 +1,50 @@ +; mul40.s +; +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. +; +; +; unsigned int __fastcall__ mul40(unsigned char value); +; +; REMARKS: Function is defined to return with carry-flag cleared + + + .importzp tmp4 + .export _mul40 + +.proc _mul40 ; = 33 bytes, 48/53 cycles + + sta tmp4 ; remember value for later addition... + ldx #0 ; clear high-byte + asl a ; * 2 + bcc mul4 ; high-byte affected? + ldx #2 ; this will be the 1st high-bit soon... + +mul4: asl a ; * 4 + bcc mul5 ; high-byte affected? + inx ; => yes, apply to 0 high-bit + clc ; prepare addition + +mul5: adc tmp4 ; * 5 + bcc mul10 ; high-byte affected? + inx ; yes, correct... + +mul10: stx tmp4 ; continue with classic shifting... + + asl a ; * 10 + rol tmp4 + + asl a ; * 20 + rol tmp4 + + asl a ; * 40 + rol tmp4 + + ldx tmp4 ; deliver high-byte in X + rts + +.endproc diff --git a/test/val/lib_specialmath_mulxx.c b/test/val/lib_specialmath_mulxx.c new file mode 100644 index 000000000..de7cc1e29 --- /dev/null +++ b/test/val/lib_specialmath_mulxx.c @@ -0,0 +1,18 @@ +#include <specialmath.h> +#include "unittest.h" + +TEST +{ + unsigned i; + + for (i=0; i < 256; ++i) + { + ASSERT_AreEqual(i*20, mul20(i), "%u", "Invalid 'mul20(%u)' calculation!" COMMA i); + } + + for (i=0; i < 256; ++i) + { + ASSERT_AreEqual(i*40, mul40(i), "%u", "Invalid 'mul40(%u)' calculation!" COMMA i); + } +} +ENDTEST From db8bd84a82992d7d29fdd46443c194c1d8ea37fd Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Thu, 21 Mar 2019 20:43:07 +0100 Subject: [PATCH 1032/2161] Changes due to code review. --- doc/specialmath.sgml | 4 ++-- include/specialmath.h | 4 ++-- libsrc/Makefile | 1 - libsrc/atari/cputc.s | 4 ++-- libsrc/atari/mcbtxtchar.s | 4 ++-- libsrc/atari/scroll.s | 6 +++--- libsrc/atari/setcursor.s | 4 ++-- libsrc/atari5200/cputc.s | 4 ++-- .../{specialmath/mul20.s => common/_mul20.s} | 6 +++--- .../{specialmath/mul40.s => common/_mul40.s} | 6 +++--- test/val/lib_common_mulxx.c | 18 ++++++++++++++++++ test/val/lib_specialmath_mulxx.c | 18 ------------------ 12 files changed, 39 insertions(+), 40 deletions(-) rename libsrc/{specialmath/mul20.s => common/_mul20.s} (89%) rename libsrc/{specialmath/mul40.s => common/_mul40.s} (89%) create mode 100644 test/val/lib_common_mulxx.c delete mode 100644 test/val/lib_specialmath_mulxx.c diff --git a/doc/specialmath.sgml b/doc/specialmath.sgml index 18de970eb..5e2fd90a7 100644 --- a/doc/specialmath.sgml +++ b/doc/specialmath.sgml @@ -20,7 +20,7 @@ the target address. A quite common horizontal span for 8-bit systems is 20 or 40 <p> <tscreen><verb> - unsigned int __fastcall__ mul20(unsigned char value); + unsigned int __fastcall__ _mul20(unsigned char value); </verb></tscreen> The 8 bit <tt>value</tt> is multiplied by 20 and returned as 16 bit value. @@ -28,7 +28,7 @@ The 8 bit <tt>value</tt> is multiplied by 20 and returned as 16 bit value. <p> <tscreen><verb> - unsigned int __fastcall__ mul40(unsigned char value); + unsigned int __fastcall__ _mul40(unsigned char value); </verb></tscreen> The 8 bit <tt>value</tt> is multiplied by 40 and returned as 16 bit value. diff --git a/include/specialmath.h b/include/specialmath.h index fa2f65736..6b6776914 100644 --- a/include/specialmath.h +++ b/include/specialmath.h @@ -33,12 +33,12 @@ /* Multiply an 8 bit unsigned value by 20 and return the 16 bit unsigned result */ -unsigned int __fastcall__ mul20(unsigned char value); +unsigned int __fastcall__ _mul20(unsigned char value); /* Multiply an 8 bit unsigned value by 40 and return the 16 bit unsigned result */ -unsigned int __fastcall__ mul40(unsigned char value); +unsigned int __fastcall__ _mul40(unsigned char value); diff --git a/libsrc/Makefile b/libsrc/Makefile index 4e1a3520d..0ebec46b1 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -181,7 +181,6 @@ SRCDIRS += common \ mouse \ runtime \ serial \ - specialmath \ tgi \ zlib diff --git a/libsrc/atari/cputc.s b/libsrc/atari/cputc.s index cf66fdacf..5de39573c 100644 --- a/libsrc/atari/cputc.s +++ b/libsrc/atari/cputc.s @@ -7,7 +7,7 @@ .export _cputcxy, _cputc .export plot, cputdirect, putchar - .import gotoxy, _mul40 + .import gotoxy, __mul40 .importzp tmp4,ptr4 .import _revflag,setcursor @@ -71,7 +71,7 @@ putchar: sta (OLDADR),y lda ROWCRS - jsr _mul40 ; destroys tmp4, carry is cleared + jsr __mul40 ; destroys tmp4, carry is cleared adc SAVMSC ; add start of screen memory sta ptr4 txa diff --git a/libsrc/atari/mcbtxtchar.s b/libsrc/atari/mcbtxtchar.s index 4ff79c651..3c992000c 100644 --- a/libsrc/atari/mcbtxtchar.s +++ b/libsrc/atari/mcbtxtchar.s @@ -12,7 +12,7 @@ .export _mouse_txt_callbacks .importzp tmp4 - .import _mul40 + .import __mul40 .importzp mouse_txt_char ; screen code of mouse cursor .include "atari.inc" @@ -108,7 +108,7 @@ movey: lsr a ; convert y position to character line lsr a lsr a - jsr _mul40 ; carry is cleared by _mul40 + jsr __mul40 ; carry is cleared by _mul40 adc SAVMSC sta scrptr txa diff --git a/libsrc/atari/scroll.s b/libsrc/atari/scroll.s index 4bc0d72ed..7c839cd48 100644 --- a/libsrc/atari/scroll.s +++ b/libsrc/atari/scroll.s @@ -8,7 +8,7 @@ .include "atari.inc" .importzp tmp1,tmp4,ptr1,ptr2 - .import _mul40,_clrscr + .import __mul40,_clrscr .export __scroll .proc __scroll @@ -40,7 +40,7 @@ down_ok:lda SAVMSC sta ptr2+1 lda tmp1 - jsr _mul40 + jsr __mul40 sta tmp4 lda ptr2 sec @@ -103,7 +103,7 @@ up: sta tmp1 ; # of lines to scroll jmp _clrscr ;multiply by 40 (xsize) -up_ok: jsr _mul40 ; carry is cleared by _mul40 +up_ok: jsr __mul40 ; carry is cleared by __mul40 adc SAVMSC ; add start of screen mem sta ptr2 txa diff --git a/libsrc/atari/setcursor.s b/libsrc/atari/setcursor.s index c6d844047..33b93ae16 100644 --- a/libsrc/atari/setcursor.s +++ b/libsrc/atari/setcursor.s @@ -4,7 +4,7 @@ ; cursor handling, internal function .include "atari.inc" - .import cursor,_mul40 + .import cursor,__mul40 .export setcursor .proc setcursor @@ -14,7 +14,7 @@ sta (OLDADR),y lda ROWCRS - jsr _mul40 ; function leaves with carry clear! + jsr __mul40 ; function leaves with carry clear! adc SAVMSC ; add start of screen memory sta OLDADR txa diff --git a/libsrc/atari5200/cputc.s b/libsrc/atari5200/cputc.s index 185ad8da8..cac66699a 100644 --- a/libsrc/atari5200/cputc.s +++ b/libsrc/atari5200/cputc.s @@ -10,7 +10,7 @@ .export _cputcxy, _cputc .export plot, cputdirect, putchar - .import gotoxy, _mul20 + .import gotoxy, __mul20 .importzp ptr4 .import setcursor @@ -75,7 +75,7 @@ putchar: pha ; save char lda ROWCRS_5200 - jsr _mul20 ; destroys tmp4, carry is cleared + jsr __mul20 ; destroys tmp4, carry is cleared adc SAVMSC ; add start of screen memory sta ptr4 txa diff --git a/libsrc/specialmath/mul20.s b/libsrc/common/_mul20.s similarity index 89% rename from libsrc/specialmath/mul20.s rename to libsrc/common/_mul20.s index 3339f7dd2..42ab420e5 100644 --- a/libsrc/specialmath/mul20.s +++ b/libsrc/common/_mul20.s @@ -8,15 +8,15 @@ ; See "LICENSE" file for legal information. ; ; -; unsigned int __fastcall__ mul20(unsigned char value); +; unsigned int __fastcall__ _mul20(unsigned char value); ; ; REMARKS: Function is defined to return with carry-flag cleared .importzp tmp4 - .export _mul20 + .export __mul20 -.proc _mul20 ; = 30 bytes, 41/46 cycles +.proc __mul20 ; = 30 bytes, 41/46 cycles sta tmp4 ; remember value for later addition... ldx #0 ; clear high-byte diff --git a/libsrc/specialmath/mul40.s b/libsrc/common/_mul40.s similarity index 89% rename from libsrc/specialmath/mul40.s rename to libsrc/common/_mul40.s index 110351935..d68a9f7c0 100644 --- a/libsrc/specialmath/mul40.s +++ b/libsrc/common/_mul40.s @@ -8,15 +8,15 @@ ; See "LICENSE" file for legal information. ; ; -; unsigned int __fastcall__ mul40(unsigned char value); +; unsigned int __fastcall__ _mul40(unsigned char value); ; ; REMARKS: Function is defined to return with carry-flag cleared .importzp tmp4 - .export _mul40 + .export __mul40 -.proc _mul40 ; = 33 bytes, 48/53 cycles +.proc __mul40 ; = 33 bytes, 48/53 cycles sta tmp4 ; remember value for later addition... ldx #0 ; clear high-byte diff --git a/test/val/lib_common_mulxx.c b/test/val/lib_common_mulxx.c new file mode 100644 index 000000000..340838a83 --- /dev/null +++ b/test/val/lib_common_mulxx.c @@ -0,0 +1,18 @@ +#include <specialmath.h> +#include "unittest.h" + +TEST +{ + unsigned i; + + for (i=0; i < 256; ++i) + { + ASSERT_AreEqual(i*20, _mul20(i), "%u", "Invalid 'mul20(%u)' calculation!" COMMA i); + } + + for (i=0; i < 256; ++i) + { + ASSERT_AreEqual(i*40, _mul40(i), "%u", "Invalid 'mul40(%u)' calculation!" COMMA i); + } +} +ENDTEST diff --git a/test/val/lib_specialmath_mulxx.c b/test/val/lib_specialmath_mulxx.c deleted file mode 100644 index de7cc1e29..000000000 --- a/test/val/lib_specialmath_mulxx.c +++ /dev/null @@ -1,18 +0,0 @@ -#include <specialmath.h> -#include "unittest.h" - -TEST -{ - unsigned i; - - for (i=0; i < 256; ++i) - { - ASSERT_AreEqual(i*20, mul20(i), "%u", "Invalid 'mul20(%u)' calculation!" COMMA i); - } - - for (i=0; i < 256; ++i) - { - ASSERT_AreEqual(i*40, mul40(i), "%u", "Invalid 'mul40(%u)' calculation!" COMMA i); - } -} -ENDTEST From 435f417c6418b0c6bc3e0f48ec5da2593cb50d89 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Thu, 21 Mar 2019 21:04:24 +0100 Subject: [PATCH 1033/2161] Moved documentation to funcref. --- doc/funcref.sgml | 29 +++++++++++++++++++++++++++++ doc/index.sgml | 3 --- doc/specialmath.sgml | 38 -------------------------------------- 3 files changed, 29 insertions(+), 41 deletions(-) delete mode 100644 doc/specialmath.sgml diff --git a/doc/funcref.sgml b/doc/funcref.sgml index bfd687b6f..f995d2982 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -578,6 +578,12 @@ communication, see also <tt>testcode/lib/ser-test.c</tt>. <item><ref id="signal" name="signal"> </itemize> +<sect1><tt/specialmath.h/<label id="specialmath.h"><p> + +<itemize> +<item><ref id="_mul20" name="_mul20"> +<item><ref id="_mul40" name="_mul40"> +</itemize> <sect1><tt/stdarg.h/<label id="stdarg.h"><p> @@ -1020,6 +1026,29 @@ It returns 1 if it does. </descrip> </quote> +<sect1>_mul20<label id="_mul20"><p> + +<quote> +<descrip> +<tag/Function/Multiplies argument by 20. +<tag/Header/<tt/<ref id="specialmath.h" name="specialmath.h">/ +<tag/Declaration/<tt/unsigned int __fastcall__ _mul20(unsigned char value);/ +<tag/Description/Speed optimized function to multiply an 8 bit unsigned value by 20 to get a 16 bit result. +<tag/Availability/cc65 +</descrip> +</quote> + +<sect1>_mul40<label id="_mul40"><p> + +<quote> +<descrip> +<tag/Function/Multiplies argument by 40. +<tag/Header/<tt/<ref id="specialmath.h" name="specialmath.h">/ +<tag/Declaration/<tt/unsigned int __fastcall__ _mul40(unsigned char value);/ +<tag/Description/Speed optimized function to multiply an 8 bit unsigned value by 40 to get a 16 bit result. +<tag/Availability/cc65 +</descrip> +</quote> <sect1>_poserror<label id="_poserror"><p> diff --git a/doc/index.sgml b/doc/index.sgml index 55e69f40f..aecfb7de9 100644 --- a/doc/index.sgml +++ b/doc/index.sgml @@ -97,9 +97,6 @@ Describes Christian Krüger's macro package for writing self modifying assembler code. - <tag><htmlurl url="specialmath.html" name="specialmath.html"></tag> - Library for speed optimized math functions. - <tag><url name="6502 Binary Relocation Format document" url="http://www.6502.org/users/andre/o65/fileformat.html"></tag> Describes the o65 file format that is used for dynamically loadable modules diff --git a/doc/specialmath.sgml b/doc/specialmath.sgml deleted file mode 100644 index 5e2fd90a7..000000000 --- a/doc/specialmath.sgml +++ /dev/null @@ -1,38 +0,0 @@ -<!doctype linuxdoc system> - -<article> -<title>Special math functions -<author>Christian Krüger - -<abstract> -This library provides functions for speed optimized math operations. -</abstract> - -<!-- Table of contents --> -<toc> - -<!-- Begin the document --> - -<sect>Multiplication<p> - -When accessing screen memory often a multiplication of the vertical position is needed to calculate -the target address. A quite common horizontal span for 8-bit systems is 20 or 40 bytes (beside e.g. 32 bytes, where the multiplication can be accomplished by shifting 5 times). - -<p> -<tscreen><verb> - unsigned int __fastcall__ _mul20(unsigned char value); -</verb></tscreen> - -The 8 bit <tt>value</tt> is multiplied by 20 and returned as 16 bit value. -</p> - -<p> -<tscreen><verb> - unsigned int __fastcall__ _mul40(unsigned char value); -</verb></tscreen> - -The 8 bit <tt>value</tt> is multiplied by 40 and returned as 16 bit value. -</p> - - -</article> From 3d8c3a494801e106e33fa7dcc4fd3daedad1b98a Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Fri, 29 Mar 2019 22:36:01 +0100 Subject: [PATCH 1034/2161] Code review adaptations, removed "cc65_" prefix from functions --- doc/funcref.sgml | 75 +++++++++---------- include/cc65.h | 28 ++++--- include/specialmath.h | 46 ------------ libsrc/atari/cputc.s | 4 +- libsrc/atari/mcbtxtchar.s | 4 +- libsrc/atari/scroll.s | 6 +- libsrc/atari/setcursor.s | 4 +- libsrc/atari5200/cputc.s | 4 +- .../{cc65_idiv32by16r16.s => idiv32by16r16.s} | 4 +- .../{cc65_imul16x16r32.s => imul16x16r32.s} | 4 +- .../{cc65_imul8x8r16.s => imul8x8r16.s} | 4 +- libsrc/common/{_mul20.s => mul20.s} | 12 +-- libsrc/common/{_mul40.s => mul40.s} | 12 +-- libsrc/common/{cc65_sincos.s => sincos.s} | 14 ++-- .../{cc65_udiv32by16r16.s => udiv32by16r16.s} | 4 +- .../{cc65_umul16x16r32.s => umul16x16r32.s} | 4 +- .../{cc65_umul16x8r32.s => umul16x8r32.s} | 4 +- .../{cc65_umul8x8r16.s => umul8x8r16.s} | 4 +- libsrc/tgi/tgi_arc.c | 8 +- libsrc/tgi/tgi_pieslice.c | 4 +- test/val/lib_common_mulxx.c | 6 +- 21 files changed, 107 insertions(+), 148 deletions(-) delete mode 100644 include/specialmath.h rename libsrc/common/{cc65_idiv32by16r16.s => idiv32by16r16.s} (90%) rename libsrc/common/{cc65_imul16x16r32.s => imul16x16r32.s} (85%) rename libsrc/common/{cc65_imul8x8r16.s => imul8x8r16.s} (84%) rename libsrc/common/{_mul20.s => mul20.s} (78%) rename libsrc/common/{_mul40.s => mul40.s} (79%) rename libsrc/common/{cc65_sincos.s => sincos.s} (95%) rename libsrc/common/{cc65_udiv32by16r16.s => udiv32by16r16.s} (90%) rename libsrc/common/{cc65_umul16x16r32.s => umul16x16r32.s} (85%) rename libsrc/common/{cc65_umul16x8r32.s => umul16x8r32.s} (88%) rename libsrc/common/{cc65_umul8x8r16.s => umul8x8r16.s} (83%) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index f995d2982..c715b3a2a 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -243,16 +243,19 @@ function. <sect1><tt/cc65.h/<label id="cc65.h"><p> <itemize> -<!-- <item><ref id="cc65_cos" name="cc65_cos"> --> -<!-- <item><ref id="cc65_idiv32by16r16" name="cc65_idiv32by16r16"> --> -<!-- <item><ref id="cc65_imul16x16r32" name="cc65_imul16x16r32"> --> -<!-- <item><ref id="cc65_imul8x8r16" name="cc65_imul8x8r16"> --> -<!-- <item><ref id="cc65_sin" name="cc65_sin"> --> -<!-- <item><ref id="cc65_udiv32by16r16" name="cc65_udiv32by16r16"> --> -<!-- <item><ref id="cc65_umul16x16r32" name="cc65_umul16x16r32"> --> -<!-- <item><ref id="cc65_umul16x8r32" name="cc65_umul16x8r32"> --> -<!-- <item><ref id="cc65_umul8x8r16" name="cc65_umul8x8r16"> --> + +<!-- <item><ref id="cos" name="cos"> --> +<!-- <item><ref id="idiv32by16r16" name="idiv32by16r16"> --> +<!-- <item><ref id="imul16x16r32" name="imul16x16r32"> --> +<!-- <item><ref id="imul8x8r16" name="imul8x8r16"> --> +<!-- <item><ref id="sin" name="sin"> --> +<!-- <item><ref id="udiv32by16r16" name="udiv32by16r16"> --> +<!-- <item><ref id="umul16x16r32" name="umul16x16r32"> --> +<!-- <item><ref id="umul16x8r32" name="umul16x8r32"> --> +<!-- <item><ref id="umul8x8r16" name="umul8x8r16"> --> <item><ref id="doesclrscrafterexit" name="doesclrscrafterexit"> +<item><ref id="mul20" name="mul20"> +<item><ref id="mul40" name="mul40"> </itemize> (incomplete) @@ -578,13 +581,6 @@ communication, see also <tt>testcode/lib/ser-test.c</tt>. <item><ref id="signal" name="signal"> </itemize> -<sect1><tt/specialmath.h/<label id="specialmath.h"><p> - -<itemize> -<item><ref id="_mul20" name="_mul20"> -<item><ref id="_mul40" name="_mul40"> -</itemize> - <sect1><tt/stdarg.h/<label id="stdarg.h"><p> (incomplete) @@ -1026,30 +1022,6 @@ It returns 1 if it does. </descrip> </quote> -<sect1>_mul20<label id="_mul20"><p> - -<quote> -<descrip> -<tag/Function/Multiplies argument by 20. -<tag/Header/<tt/<ref id="specialmath.h" name="specialmath.h">/ -<tag/Declaration/<tt/unsigned int __fastcall__ _mul20(unsigned char value);/ -<tag/Description/Speed optimized function to multiply an 8 bit unsigned value by 20 to get a 16 bit result. -<tag/Availability/cc65 -</descrip> -</quote> - -<sect1>_mul40<label id="_mul40"><p> - -<quote> -<descrip> -<tag/Function/Multiplies argument by 40. -<tag/Header/<tt/<ref id="specialmath.h" name="specialmath.h">/ -<tag/Declaration/<tt/unsigned int __fastcall__ _mul40(unsigned char value);/ -<tag/Description/Speed optimized function to multiply an 8 bit unsigned value by 40 to get a 16 bit result. -<tag/Availability/cc65 -</descrip> -</quote> - <sect1>_poserror<label id="_poserror"><p> <quote> @@ -5587,6 +5559,29 @@ memory allocated for the driver. </descrip> </quote> +<sect1>mul20<label id="mul20"><p> + +<quote> +<descrip> +<tag/Function/Multiplies argument by 20. +<tag/Header/<tt/<ref id="cc65.h" name="cc65.h">/ +<tag/Declaration/<tt/unsigned int __fastcall__ mul20(unsigned char value);/ +<tag/Description/Speed optimized function to multiply an 8 bit unsigned value by 20 to get a 16 bit result. +<tag/Availability/cc65 +</descrip> +</quote> + +<sect1>mul40<label id="mul40"><p> + +<quote> +<descrip> +<tag/Function/Multiplies argument by 40. +<tag/Header/<tt/<ref id="cc65.h" name="cc65.h">/ +<tag/Declaration/<tt/unsigned int __fastcall__ mul40(unsigned char value);/ +<tag/Description/Speed optimized function to multiply an 8 bit unsigned value by 40 to get a 16 bit result. +<tag/Availability/cc65 +</descrip> +</quote> <sect1>offsetof<label id="offsetof"><p> diff --git a/include/cc65.h b/include/cc65.h index 9b7b69a0e..e596e93df 100644 --- a/include/cc65.h +++ b/include/cc65.h @@ -44,43 +44,53 @@ -long __fastcall__ cc65_idiv32by16r16 (long rhs, int lhs); +long __fastcall__ idiv32by16r16 (long rhs, int lhs); /* Divide a 32 bit signed value by a 16 bit signed value yielding a 16 ** bit result and a 16 bit remainder. The former is returned in the lower 16 ** bit of the result, the latter in the upper. If you don't need the ** remainder, just assign (or cast) to an int. */ -unsigned long __fastcall__ cc65_udiv32by16r16 (unsigned long rhs, unsigned lhs); +unsigned long __fastcall__ udiv32by16r16 (unsigned long rhs, unsigned lhs); /* Divide a 32 bit unsigned value by a 16 bit unsigned value yielding a 16 ** bit result and a 16 bit remainder. The former is returned in the lower 16 ** bit of the result, the latter in the upper. If you don't need the ** remainder, just assign (or cast) to an unsigned. */ -int __fastcall__ cc65_imul8x8r16 (signed char lhs, signed char rhs); +int __fastcall__ imul8x8r16 (signed char lhs, signed char rhs); /* Multiplicate two signed 8 bit to yield an signed 16 bit result */ -long __fastcall__ cc65_imul16x16r32 (int lhs, int rhs); +long __fastcall__ imul16x16r32 (int lhs, int rhs); /* Multiplicate two signed 16 bit to yield a signed 32 bit result */ -unsigned __fastcall__ cc65_umul8x8r16 (unsigned char lhs, unsigned char rhs); +unsigned __fastcall__ umul8x8r16 (unsigned char lhs, unsigned char rhs); /* Multiplicate two unsigned 8 bit to yield an unsigned 16 bit result */ -unsigned long __fastcall__ cc65_umul16x8r32 (unsigned lhs, unsigned char rhs); +unsigned long __fastcall__ umul16x8r32 (unsigned lhs, unsigned char rhs); /* Multiplicate an unsigned 16 bit by an unsigned 8 bit number yielding a 24 ** bit unsigned result that is extended to 32 bits for easier handling from C. */ -unsigned long __fastcall__ cc65_umul16x16r32 (unsigned lhs, unsigned rhs); +unsigned long __fastcall__ umul16x16r32 (unsigned lhs, unsigned rhs); /* Multiplicate two unsigned 16 bit to yield an unsigned 32 bit result */ -int __fastcall__ cc65_sin (unsigned x); +unsigned int __fastcall__ mul20(unsigned char value); +/* Multiply an 8 bit unsigned value by 20 and return the 16 bit unsigned +** result +*/ + +unsigned int __fastcall__ mul40(unsigned char value); +/* Multiply an 8 bit unsigned value by 40 and return the 16 bit unsigned +** result +*/ + +int __fastcall__ sin (unsigned x); /* Return the sine of the argument, which must be in range 0..360. The result ** is in 8.8 fixed point format, which means that 1.0 = $100 and -1.0 = $FF00. */ -int __fastcall__ cc65_cos (unsigned x); +int __fastcall__ cos (unsigned x); /* Return the cosine of the argument, which must be in range 0..360. The result ** is in 8.8 fixed point format, which means that 1.0 = $100 and -1.0 = $FF00. */ diff --git a/include/specialmath.h b/include/specialmath.h deleted file mode 100644 index 6b6776914..000000000 --- a/include/specialmath.h +++ /dev/null @@ -1,46 +0,0 @@ -/*****************************************************************************/ -/* */ -/* specialmath.h */ -/* */ -/* Optimized math routines for special usages */ -/* */ -/* */ -/* */ -/* (C) 2019 Christian 'Irgendwer' Krueger */ -/* */ -/* 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 _SPECIALMATH_H -#define _SPECIALMATH_H - - -/* Multiply an 8 bit unsigned value by 20 and return the 16 bit unsigned result */ - -unsigned int __fastcall__ _mul20(unsigned char value); - - -/* Multiply an 8 bit unsigned value by 40 and return the 16 bit unsigned result */ - -unsigned int __fastcall__ _mul40(unsigned char value); - - - -/* End of specialmath.h */ -#endif diff --git a/libsrc/atari/cputc.s b/libsrc/atari/cputc.s index 5de39573c..cf66fdacf 100644 --- a/libsrc/atari/cputc.s +++ b/libsrc/atari/cputc.s @@ -7,7 +7,7 @@ .export _cputcxy, _cputc .export plot, cputdirect, putchar - .import gotoxy, __mul40 + .import gotoxy, _mul40 .importzp tmp4,ptr4 .import _revflag,setcursor @@ -71,7 +71,7 @@ putchar: sta (OLDADR),y lda ROWCRS - jsr __mul40 ; destroys tmp4, carry is cleared + jsr _mul40 ; destroys tmp4, carry is cleared adc SAVMSC ; add start of screen memory sta ptr4 txa diff --git a/libsrc/atari/mcbtxtchar.s b/libsrc/atari/mcbtxtchar.s index 3c992000c..4ff79c651 100644 --- a/libsrc/atari/mcbtxtchar.s +++ b/libsrc/atari/mcbtxtchar.s @@ -12,7 +12,7 @@ .export _mouse_txt_callbacks .importzp tmp4 - .import __mul40 + .import _mul40 .importzp mouse_txt_char ; screen code of mouse cursor .include "atari.inc" @@ -108,7 +108,7 @@ movey: lsr a ; convert y position to character line lsr a lsr a - jsr __mul40 ; carry is cleared by _mul40 + jsr _mul40 ; carry is cleared by _mul40 adc SAVMSC sta scrptr txa diff --git a/libsrc/atari/scroll.s b/libsrc/atari/scroll.s index 7c839cd48..4bc0d72ed 100644 --- a/libsrc/atari/scroll.s +++ b/libsrc/atari/scroll.s @@ -8,7 +8,7 @@ .include "atari.inc" .importzp tmp1,tmp4,ptr1,ptr2 - .import __mul40,_clrscr + .import _mul40,_clrscr .export __scroll .proc __scroll @@ -40,7 +40,7 @@ down_ok:lda SAVMSC sta ptr2+1 lda tmp1 - jsr __mul40 + jsr _mul40 sta tmp4 lda ptr2 sec @@ -103,7 +103,7 @@ up: sta tmp1 ; # of lines to scroll jmp _clrscr ;multiply by 40 (xsize) -up_ok: jsr __mul40 ; carry is cleared by __mul40 +up_ok: jsr _mul40 ; carry is cleared by _mul40 adc SAVMSC ; add start of screen mem sta ptr2 txa diff --git a/libsrc/atari/setcursor.s b/libsrc/atari/setcursor.s index 33b93ae16..c6d844047 100644 --- a/libsrc/atari/setcursor.s +++ b/libsrc/atari/setcursor.s @@ -4,7 +4,7 @@ ; cursor handling, internal function .include "atari.inc" - .import cursor,__mul40 + .import cursor,_mul40 .export setcursor .proc setcursor @@ -14,7 +14,7 @@ sta (OLDADR),y lda ROWCRS - jsr __mul40 ; function leaves with carry clear! + jsr _mul40 ; function leaves with carry clear! adc SAVMSC ; add start of screen memory sta OLDADR txa diff --git a/libsrc/atari5200/cputc.s b/libsrc/atari5200/cputc.s index cac66699a..185ad8da8 100644 --- a/libsrc/atari5200/cputc.s +++ b/libsrc/atari5200/cputc.s @@ -10,7 +10,7 @@ .export _cputcxy, _cputc .export plot, cputdirect, putchar - .import gotoxy, __mul20 + .import gotoxy, _mul20 .importzp ptr4 .import setcursor @@ -75,7 +75,7 @@ putchar: pha ; save char lda ROWCRS_5200 - jsr __mul20 ; destroys tmp4, carry is cleared + jsr _mul20 ; destroys tmp4, carry is cleared adc SAVMSC ; add start of screen memory sta ptr4 txa diff --git a/libsrc/common/cc65_idiv32by16r16.s b/libsrc/common/idiv32by16r16.s similarity index 90% rename from libsrc/common/cc65_idiv32by16r16.s rename to libsrc/common/idiv32by16r16.s index 9c30984b8..7df78f4dd 100644 --- a/libsrc/common/cc65_idiv32by16r16.s +++ b/libsrc/common/idiv32by16r16.s @@ -4,7 +4,7 @@ ; CC65 library: 32by16 => 16 signed division ; - .export _cc65_idiv32by16r16 + .export _idiv32by16r16 .import idiv32by16r16, incsp4 .include "zeropage.inc" @@ -13,7 +13,7 @@ ;--------------------------------------------------------------------------- ; 32by16 division. -.proc _cc65_idiv32by16r16 +.proc _idiv32by16r16 pha ; Save rhs diff --git a/libsrc/common/cc65_imul16x16r32.s b/libsrc/common/imul16x16r32.s similarity index 85% rename from libsrc/common/cc65_imul16x16r32.s rename to libsrc/common/imul16x16r32.s index b4e82de10..e08d11c6c 100644 --- a/libsrc/common/cc65_imul16x16r32.s +++ b/libsrc/common/imul16x16r32.s @@ -4,7 +4,7 @@ ; CC65 library: 16x16 => 32 signed multiplication ; - .export _cc65_imul16x16r32 + .export _imul16x16r32 .import imul16x16r32, popax .include "zeropage.inc" @@ -14,7 +14,7 @@ ; 16x16 => 32 signed multiplication routine. -.proc _cc65_imul16x16r32 +.proc _imul16x16r32 sta ptr1 stx ptr1+1 diff --git a/libsrc/common/cc65_imul8x8r16.s b/libsrc/common/imul8x8r16.s similarity index 84% rename from libsrc/common/cc65_imul8x8r16.s rename to libsrc/common/imul8x8r16.s index 0e7d5479b..9987f6e85 100644 --- a/libsrc/common/cc65_imul8x8r16.s +++ b/libsrc/common/imul8x8r16.s @@ -5,7 +5,7 @@ ; CC65 library: 8x8 => 16 signed multiplication ; - .export _cc65_imul8x8r16 + .export _imul8x8r16 .import imul8x8r16, popa, ptr1:zp @@ -13,7 +13,7 @@ ; 8x8 => 16 signed multiplication routine. -.proc _cc65_imul8x8r16 +.proc _imul8x8r16 sta ptr1 jsr popa diff --git a/libsrc/common/_mul20.s b/libsrc/common/mul20.s similarity index 78% rename from libsrc/common/_mul20.s rename to libsrc/common/mul20.s index 42ab420e5..4035b9476 100644 --- a/libsrc/common/_mul20.s +++ b/libsrc/common/mul20.s @@ -8,15 +8,15 @@ ; See "LICENSE" file for legal information. ; ; -; unsigned int __fastcall__ _mul20(unsigned char value); +; unsigned int __fastcall__ mul20(unsigned char value); ; ; REMARKS: Function is defined to return with carry-flag cleared .importzp tmp4 - .export __mul20 + .export _mul20 -.proc __mul20 ; = 30 bytes, 41/46 cycles +.proc _mul20 ; = 30 bytes, 41/46 cycles sta tmp4 ; remember value for later addition... ldx #0 ; clear high-byte @@ -24,7 +24,7 @@ bcc mul4 ; high-byte affected? ldx #2 ; this will be the 1st high-bit soon... -mul4: asl a ; * 4 +mul4: asl a ; * 4 bcc mul5 ; high-byte affected? inx ; => yes, apply to 0 high-bit clc ; prepare addition @@ -36,9 +36,9 @@ mul5: adc tmp4 ; * 5 mul10: stx tmp4 ; continue with classic shifting... asl a ; * 10 - rol tmp4 + rol tmp4 - asl a ; * 20 + asl a ; * 20 rol tmp4 ldx tmp4 ; deliver high-byte in X diff --git a/libsrc/common/_mul40.s b/libsrc/common/mul40.s similarity index 79% rename from libsrc/common/_mul40.s rename to libsrc/common/mul40.s index d68a9f7c0..f240fc41a 100644 --- a/libsrc/common/_mul40.s +++ b/libsrc/common/mul40.s @@ -8,15 +8,15 @@ ; See "LICENSE" file for legal information. ; ; -; unsigned int __fastcall__ _mul40(unsigned char value); +; unsigned int __fastcall__ mul40(unsigned char value); ; ; REMARKS: Function is defined to return with carry-flag cleared .importzp tmp4 - .export __mul40 + .export _mul40 -.proc __mul40 ; = 33 bytes, 48/53 cycles +.proc _mul40 ; = 33 bytes, 48/53 cycles sta tmp4 ; remember value for later addition... ldx #0 ; clear high-byte @@ -24,7 +24,7 @@ bcc mul4 ; high-byte affected? ldx #2 ; this will be the 1st high-bit soon... -mul4: asl a ; * 4 +mul4: asl a ; * 4 bcc mul5 ; high-byte affected? inx ; => yes, apply to 0 high-bit clc ; prepare addition @@ -36,9 +36,9 @@ mul5: adc tmp4 ; * 5 mul10: stx tmp4 ; continue with classic shifting... asl a ; * 10 - rol tmp4 + rol tmp4 - asl a ; * 20 + asl a ; * 20 rol tmp4 asl a ; * 40 diff --git a/libsrc/common/cc65_sincos.s b/libsrc/common/sincos.s similarity index 95% rename from libsrc/common/cc65_sincos.s rename to libsrc/common/sincos.s index 6baba8bb3..7cdcb7167 100644 --- a/libsrc/common/cc65_sincos.s +++ b/libsrc/common/sincos.s @@ -13,7 +13,7 @@ ; Ullrich von Bassewitz, 2009-10-29 ; - .export _cc65_cos, _cc65_sin + .export _cos, _sin ; --------------------------------------------------------------------------- @@ -23,7 +23,7 @@ .rodata -_cc65_sintab: +_sintab: .byte $00, $04, $09, $0D, $12, $16, $1B, $1F, $24, $28 .byte $2C, $31, $35, $3A, $3E, $42, $47, $4B, $4F, $53 .byte $58, $5C, $60, $64, $68, $6C, $70, $74, $78, $7C @@ -41,7 +41,7 @@ _cc65_sintab: .code -_cc65_cos: +_cos: ; cos(x) = sin(x+90) @@ -55,7 +55,7 @@ _cc65_cos: @L1: cpx #>360 bne @L2 cmp #<360 -@L2: bcc _cc65_sin +@L2: bcc _sin sbc #<360 bcs @L3 @@ -71,7 +71,7 @@ _cc65_cos: ; ; Plus special handling for the values missing in the table. -_cc65_sin: +_sin: ; If the high byte is non zero, argument is > 255 @@ -114,7 +114,7 @@ L1: cmp #87 L2: tay ldx #0 - lda _cc65_sintab,y + lda _sintab,y rts ; 180..360°. sin(x) = -sin(x-180). Since the argument is in range 0..180 @@ -155,7 +155,7 @@ L5: ldx #$FF L6: tay txa ; A = $FF - eor _cc65_sintab,y + eor _sintab,y adc #1 bcc L7 inx diff --git a/libsrc/common/cc65_udiv32by16r16.s b/libsrc/common/udiv32by16r16.s similarity index 90% rename from libsrc/common/cc65_udiv32by16r16.s rename to libsrc/common/udiv32by16r16.s index 9cad63bd4..a1d5f4e66 100644 --- a/libsrc/common/cc65_udiv32by16r16.s +++ b/libsrc/common/udiv32by16r16.s @@ -4,7 +4,7 @@ ; CC65 library: 32by16 => 16 unsigned division ; - .export _cc65_udiv32by16r16 + .export _udiv32by16r16 .import udiv32by16r16m, incsp4 .include "zeropage.inc" @@ -13,7 +13,7 @@ ;--------------------------------------------------------------------------- ; 32by16 division. -.proc _cc65_udiv32by16r16 +.proc _udiv32by16r16 sta ptr3 stx ptr3+1 ; Store rhs diff --git a/libsrc/common/cc65_umul16x16r32.s b/libsrc/common/umul16x16r32.s similarity index 85% rename from libsrc/common/cc65_umul16x16r32.s rename to libsrc/common/umul16x16r32.s index 0e7ed7602..674b55f77 100644 --- a/libsrc/common/cc65_umul16x16r32.s +++ b/libsrc/common/umul16x16r32.s @@ -4,7 +4,7 @@ ; CC65 library: 16x16 => 32 unsigned multiplication ; - .export _cc65_umul16x16r32 + .export _umul16x16r32 .import umul16x16r32, popax .include "zeropage.inc" @@ -13,7 +13,7 @@ ;--------------------------------------------------------------------------- ; 16x16 => 32 unsigned multiplication routine. -.proc _cc65_umul16x16r32 +.proc _umul16x16r32 sta ptr1 stx ptr1+1 diff --git a/libsrc/common/cc65_umul16x8r32.s b/libsrc/common/umul16x8r32.s similarity index 88% rename from libsrc/common/cc65_umul16x8r32.s rename to libsrc/common/umul16x8r32.s index 8af349348..83a3d9c73 100644 --- a/libsrc/common/cc65_umul16x8r32.s +++ b/libsrc/common/umul16x8r32.s @@ -4,7 +4,7 @@ ; CC65 library: 16x8 => 32 unsigned multiplication ; - .export _cc65_umul16x8r32 + .export _umul16x8r32 .import umul8x16r24, popax .include "zeropage.inc" @@ -14,7 +14,7 @@ ; 16x8 => 32 unsigned multiplication routine. We use 8x16 => 24 and clear ; the high byte of the result -.proc _cc65_umul16x8r32 +.proc _umul16x8r32 sta ptr1 lda #0 diff --git a/libsrc/common/cc65_umul8x8r16.s b/libsrc/common/umul8x8r16.s similarity index 83% rename from libsrc/common/cc65_umul8x8r16.s rename to libsrc/common/umul8x8r16.s index cf3b26bb1..8a3d46212 100644 --- a/libsrc/common/cc65_umul8x8r16.s +++ b/libsrc/common/umul8x8r16.s @@ -4,7 +4,7 @@ ; CC65 library: 8x8 => 16 unsigned multiplication ; - .export _cc65_umul8x8r16 + .export _umul8x8r16 .import umul8x8r16, popa, ptr1:zp @@ -12,7 +12,7 @@ ; 8x8 => 16 unsigned multiplication routine. -.proc _cc65_umul8x8r16 +.proc _umul8x8r16 sta ptr1 jsr popa diff --git a/libsrc/tgi/tgi_arc.c b/libsrc/tgi/tgi_arc.c index e505b7b69..94cc593ce 100644 --- a/libsrc/tgi/tgi_arc.c +++ b/libsrc/tgi/tgi_arc.c @@ -70,16 +70,16 @@ void __fastcall__ tgi_arc (int x, int y, unsigned char rx, unsigned char ry, } /* Calculate the start coords */ - x1 = x + tgi_imulround (rx, cc65_cos (sa)); - y1 = y - tgi_imulround (ry, cc65_sin (sa)); + x1 = x + tgi_imulround (rx, cos (sa)); + y1 = y - tgi_imulround (ry, sin (sa)); do { sa += inc; if (sa >= ea) { sa = ea; done = 1; } - x2 = x + tgi_imulround (rx, cc65_cos (sa)); - y2 = y - tgi_imulround (ry, cc65_sin (sa)); + x2 = x + tgi_imulround (rx, cos (sa)); + y2 = y - tgi_imulround (ry, sin (sa)); tgi_line (x1, y1, x2, y2); x1 = x2; y1 = y2; diff --git a/libsrc/tgi/tgi_pieslice.c b/libsrc/tgi/tgi_pieslice.c index 60d2f1d13..b119b9b2d 100644 --- a/libsrc/tgi/tgi_pieslice.c +++ b/libsrc/tgi/tgi_pieslice.c @@ -57,8 +57,8 @@ void __fastcall__ tgi_pieslice (int x, int y, unsigned char rx, unsigned char ry tgi_arc (x, y, rx, ry, sa, ea); /* ... and close it */ - tgi_line (x, y, x + tgi_imulround (rx, cc65_cos (sa)), y - tgi_imulround (ry, cc65_sin (sa))); - tgi_line (x, y, x + tgi_imulround (rx, cc65_cos (ea)), y - tgi_imulround (ry, cc65_sin (ea))); + tgi_line (x, y, x + tgi_imulround (rx, cos (sa)), y - tgi_imulround (ry, sin (sa))); + tgi_line (x, y, x + tgi_imulround (rx, cos (ea)), y - tgi_imulround (ry, sin (ea))); } diff --git a/test/val/lib_common_mulxx.c b/test/val/lib_common_mulxx.c index 340838a83..cf5f089e9 100644 --- a/test/val/lib_common_mulxx.c +++ b/test/val/lib_common_mulxx.c @@ -1,4 +1,4 @@ -#include <specialmath.h> +#include <cc65.h> #include "unittest.h" TEST @@ -7,12 +7,12 @@ TEST for (i=0; i < 256; ++i) { - ASSERT_AreEqual(i*20, _mul20(i), "%u", "Invalid 'mul20(%u)' calculation!" COMMA i); + ASSERT_AreEqual(i*20, mul20(i), "%u", "Invalid 'mul20(%u)' calculation!" COMMA i); } for (i=0; i < 256; ++i) { - ASSERT_AreEqual(i*40, _mul40(i), "%u", "Invalid 'mul40(%u)' calculation!" COMMA i); + ASSERT_AreEqual(i*40, mul40(i), "%u", "Invalid 'mul40(%u)' calculation!" COMMA i); } } ENDTEST From df80d071e8eeb799bd1d8ec55acd1ee92714c752 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Fri, 29 Mar 2019 22:47:42 +0100 Subject: [PATCH 1035/2161] Added space after function name. --- doc/funcref.sgml | 4 ++-- include/cc65.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index c715b3a2a..89a8eb13c 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -5565,7 +5565,7 @@ memory allocated for the driver. <descrip> <tag/Function/Multiplies argument by 20. <tag/Header/<tt/<ref id="cc65.h" name="cc65.h">/ -<tag/Declaration/<tt/unsigned int __fastcall__ mul20(unsigned char value);/ +<tag/Declaration/<tt/unsigned int __fastcall__ mul20 (unsigned char value);/ <tag/Description/Speed optimized function to multiply an 8 bit unsigned value by 20 to get a 16 bit result. <tag/Availability/cc65 </descrip> @@ -5577,7 +5577,7 @@ memory allocated for the driver. <descrip> <tag/Function/Multiplies argument by 40. <tag/Header/<tt/<ref id="cc65.h" name="cc65.h">/ -<tag/Declaration/<tt/unsigned int __fastcall__ mul40(unsigned char value);/ +<tag/Declaration/<tt/unsigned int __fastcall__ mul40 (unsigned char value);/ <tag/Description/Speed optimized function to multiply an 8 bit unsigned value by 40 to get a 16 bit result. <tag/Availability/cc65 </descrip> diff --git a/include/cc65.h b/include/cc65.h index e596e93df..a30bad247 100644 --- a/include/cc65.h +++ b/include/cc65.h @@ -75,12 +75,12 @@ unsigned long __fastcall__ umul16x8r32 (unsigned lhs, unsigned char rhs); unsigned long __fastcall__ umul16x16r32 (unsigned lhs, unsigned rhs); /* Multiplicate two unsigned 16 bit to yield an unsigned 32 bit result */ -unsigned int __fastcall__ mul20(unsigned char value); +unsigned int __fastcall__ mul20 (unsigned char value); /* Multiply an 8 bit unsigned value by 20 and return the 16 bit unsigned ** result */ -unsigned int __fastcall__ mul40(unsigned char value); +unsigned int __fastcall__ mul40 (unsigned char value); /* Multiply an 8 bit unsigned value by 40 and return the 16 bit unsigned ** result */ From 60e40c854cc6d7d8d181a66714b8f7b8bfb58e0e Mon Sep 17 00:00:00 2001 From: greg-king5 <gregdk@users.sf.net> Date: Sat, 30 Mar 2019 11:06:09 -0400 Subject: [PATCH 1036/2161] Removed a "cc65_" prefix. This change is needed because of commit 3d8c3a494801e106e33fa7dcc4fd3daedad1b98a. --- samples/tgidemo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/tgidemo.c b/samples/tgidemo.c index 6f3b86abc..1d76fee2e 100644 --- a/samples/tgidemo.c +++ b/samples/tgidemo.c @@ -151,7 +151,7 @@ static void DoDiagram (void) /* Calculate the next points */ X = (int) (((long) (MaxX - 19) * I) / 360); - Y = (int) (((long) Amp * -cc65_sin (I)) / 256); + Y = (int) (((long) Amp * -sin (I)) / 256); /* Draw the line */ tgi_lineto (XOrigin + X, YOrigin + Y); From f95481fabf041750642c018f798c693ae41b17a8 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Sat, 30 Mar 2019 22:09:16 +0200 Subject: [PATCH 1037/2161] Fixed gcc compiler warning (#867) * Changed spelling FALLTHRU -> FALLTHROUGH --- src/ca65/scanner.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index f80fe2bca..361a817c1 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -824,7 +824,7 @@ static void ReadStringConst (int StringTerm) break; } } - /* otherwise, fall through */ + /* FALLTHROUGH */ default: Error ("Unsupported escape sequence in string constant"); break; From ffc118cd94465ee5c3573a6176304b8cd86397e8 Mon Sep 17 00:00:00 2001 From: Steven Hugg <hugg@fasterlight.com> Date: Thu, 14 Mar 2019 07:20:16 -0400 Subject: [PATCH 1038/2161] added optimization for indexed pointer load of a constant, e.g.: y = ((unsigned char*)0x100)[i] --- src/cc65/codeopt.c | 3 ++ src/cc65/coptptrload.c | 97 ++++++++++++++++++++++++++++++++++++++++++ src/cc65/coptptrload.h | 21 +++++++++ 3 files changed, 121 insertions(+) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 575398c11..db63ba8e7 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -814,6 +814,7 @@ static OptFunc DOptPtrLoad14 = { OptPtrLoad14, "OptPtrLoad14", 108, 0, static OptFunc DOptPtrLoad15 = { OptPtrLoad15, "OptPtrLoad15", 86, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrLoad16 = { OptPtrLoad16, "OptPtrLoad16", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrLoad17 = { OptPtrLoad17, "OptPtrLoad17", 190, 0, 0, 0, 0, 0 }; +static OptFunc DOptPtrLoad18 = { OptPtrLoad18, "OptPtrLoad18", 100, 0, 0, 0, 0, 0 }; static OptFunc 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 }; @@ -905,6 +906,7 @@ static OptFunc* OptFuncs[] = { &DOptPtrLoad15, &DOptPtrLoad16, &DOptPtrLoad17, + &DOptPtrLoad18, &DOptPtrLoad2, &DOptPtrLoad3, &DOptPtrLoad4, @@ -1246,6 +1248,7 @@ static unsigned RunOptGroup1 (CodeSeg* S) Changes += RunOptFunc (S, &DOptPtrLoad5, 1); Changes += RunOptFunc (S, &DOptPtrLoad6, 1); Changes += RunOptFunc (S, &DOptPtrLoad7, 1); + Changes += RunOptFunc (S, &DOptPtrLoad18, 1); /* Before OptPtrLoad11 */ Changes += RunOptFunc (S, &DOptPtrLoad11, 1); Changes += RunOptFunc (S, &DOptPtrLoad12, 1); Changes += RunOptFunc (S, &DOptPtrLoad13, 1); diff --git a/src/cc65/coptptrload.c b/src/cc65/coptptrload.c index ee783c93f..81682ab09 100644 --- a/src/cc65/coptptrload.c +++ b/src/cc65/coptptrload.c @@ -1457,3 +1457,100 @@ unsigned OptPtrLoad17 (CodeSeg* S) /* Return the number of changes made */ return Changes; } + + + +unsigned OptPtrLoad18 (CodeSeg* S) +/* Search for the sequence: +** +** ldx #$xx +** lda #$yy +** clc +** adc xxx +** bcc L +** inx +** L: ldy #$00 +** jsr ldauidx +** +** and replace it by: +** +** ldy xxx +** ldx #$00 +** lda $xxyy,y +** +** This is similar to OptPtrLoad3 but works on a constant address +** instead of a label. Also, the initial X and A loads are reversed. +** Must be run before OptPtrLoad11. +*/ +{ + unsigned Changes = 0; + + /* Walk over the entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* L[8]; + + /* Get next entry */ + L[0] = CS_GetEntry (S, I); + + /* Check for the sequence */ + if (L[0]->OPC == OP65_LDX && + L[0]->AM == AM65_IMM && + CS_GetEntries (S, L+1, I+1, 7) && + L[1]->OPC == OP65_LDA && + L[1]->AM == AM65_IMM && + L[2]->OPC == OP65_CLC && + L[3]->OPC == OP65_ADC && + (L[3]->AM == AM65_ABS || L[3]->AM == AM65_ZP) && + (L[4]->OPC == OP65_BCC || L[4]->OPC == OP65_JCC) && + L[4]->JumpTo != 0 && + L[4]->JumpTo->Owner == L[6] && + L[5]->OPC == OP65_INX && + L[6]->OPC == OP65_LDY && + CE_IsKnownImm (L[6], 0) && + CE_IsCallTo (L[7], "ldauidx") && + !CS_RangeHasLabel (S, I+1, 5) && + !CE_HasLabel (L[7]) && + strlen (L[0]->Arg) == 3 && + L[0]->Arg[0] == '$' && + strlen (L[1]->Arg) == 3 && + L[1]->Arg[0] == '$' ) { + + CodeEntry* X; + char* Label; + + /* We will create all the new stuff behind the current one so + ** we keep the line references. + */ + X = NewCodeEntry (OP65_LDY, L[3]->AM, L[3]->Arg, 0, L[0]->LI); + CS_InsertEntry (S, X, I+8); + + X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[0]->LI); + CS_InsertEntry (S, X, I+9); + + Label = xmalloc(6); + sprintf(Label, "$%s%s", L[0]->Arg+1, L[1]->Arg+1); + X = NewCodeEntry (OP65_LDA, AM65_ABSY, Label, 0, L[0]->LI); + CS_InsertEntry (S, X, I+10); + xfree (Label); + + /* Remove the old code */ + CS_DelEntries (S, I, 8); + + /* Remember, we had changes */ + ++Changes; + + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + + diff --git a/src/cc65/coptptrload.h b/src/cc65/coptptrload.h index fd93bf5c2..4581ccb45 100644 --- a/src/cc65/coptptrload.h +++ b/src/cc65/coptptrload.h @@ -356,6 +356,27 @@ unsigned OptPtrLoad17 (CodeSeg* S); ** the step with less than 200% so it gets executed when -Oi is in effect. */ +unsigned OptPtrLoad18 (CodeSeg* S); +/* Search for the sequence: +** +** ldx #$xx +** lda #$yy +** clc +** adc xxx +** bcc L +** inx +** L: ldy #$00 +** jsr ldauidx +** +** and replace it by: +** +** ldy xxx +** ldx #$00 +** lda $xxyy,y +** +** This is similar to OptPtrLoad3 but works on a constant address +** instead of a label. Also, the initial X and A loads are reversed. +*/ /* End of coptptrload.h */ From 5d274e4bc5b81002146e72602dae235dcd4c591e Mon Sep 17 00:00:00 2001 From: Steven Hugg <hugg@fasterlight.com> Date: Thu, 14 Mar 2019 09:41:50 -0400 Subject: [PATCH 1039/2161] added optimization for indexed 16-bit array load of form (array[i & 0x7f]) --- src/cc65/codeopt.c | 3 ++ src/cc65/coptptrload.c | 113 +++++++++++++++++++++++++++++++++++++++++ src/cc65/coptptrload.h | 25 +++++++++ 3 files changed, 141 insertions(+) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index db63ba8e7..d920f001a 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -815,6 +815,7 @@ static OptFunc DOptPtrLoad15 = { OptPtrLoad15, "OptPtrLoad15", 86, 0, static OptFunc DOptPtrLoad16 = { OptPtrLoad16, "OptPtrLoad16", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrLoad17 = { OptPtrLoad17, "OptPtrLoad17", 190, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrLoad18 = { OptPtrLoad18, "OptPtrLoad18", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptPtrLoad19 = { OptPtrLoad19, "OptPtrLoad19", 65, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrStore1 = { OptPtrStore1, "OptPtrStore1", 65, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrStore2 = { OptPtrStore2, "OptPtrStore2", 65, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrStore3 = { OptPtrStore3, "OptPtrStore3", 100, 0, 0, 0, 0, 0 }; @@ -907,6 +908,7 @@ static OptFunc* OptFuncs[] = { &DOptPtrLoad16, &DOptPtrLoad17, &DOptPtrLoad18, + &DOptPtrLoad19, &DOptPtrLoad2, &DOptPtrLoad3, &DOptPtrLoad4, @@ -1256,6 +1258,7 @@ static unsigned RunOptGroup1 (CodeSeg* S) Changes += RunOptFunc (S, &DOptPtrLoad15, 1); Changes += RunOptFunc (S, &DOptPtrLoad16, 1); Changes += RunOptFunc (S, &DOptPtrLoad17, 1); + Changes += RunOptFunc (S, &DOptPtrLoad19, 1); Changes += RunOptFunc (S, &DOptBNegAX1, 1); Changes += RunOptFunc (S, &DOptBNegAX2, 1); Changes += RunOptFunc (S, &DOptBNegAX3, 1); diff --git a/src/cc65/coptptrload.c b/src/cc65/coptptrload.c index 81682ab09..c508d56f4 100644 --- a/src/cc65/coptptrload.c +++ b/src/cc65/coptptrload.c @@ -1554,3 +1554,116 @@ unsigned OptPtrLoad18 (CodeSeg* S) +unsigned OptPtrLoad19 (CodeSeg* S) +/* Search for the sequence: +** +** and #mask (any value < 128) +** jsr aslax1/shlax1 +** clc +** adc #<(label+0) +** tay +** txa +** adc #>(label+0) +** tax +** tya +** ldy #$01 +** jsr ldaxidx +** +** and replace it by: +** +** and #mask (remove if == 127) +** asl +** tay +** lda label,y +** ldx label+1,y +*/ +{ + unsigned Changes = 0; + unsigned I; + + /* Walk over the entries */ + I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* L[11]; + + /* Get next entry */ + L[0] = CS_GetEntry (S, I); + + /* Check for the sequence */ + if (L[0]->OPC == OP65_AND && + L[0]->AM == AM65_IMM && + CE_HasNumArg (L[0]) && L[0]->Num <= 127 && + CS_GetEntries (S, L+1, I+1, 10) && + L[1]->OPC == OP65_JSR && + (strcmp (L[1]->Arg, "aslax1") == 0 || + strcmp (L[1]->Arg, "shlax1") == 0) && + L[2]->OPC == OP65_CLC && + L[3]->OPC == OP65_ADC && + L[4]->OPC == OP65_TAY && + L[5]->OPC == OP65_TXA && + L[6]->OPC == OP65_ADC && + L[7]->OPC == OP65_TAX && + L[8]->OPC == OP65_TYA && + L[9]->OPC == OP65_LDY && + CE_IsKnownImm(L[9], 1) && + strlen(L[3]->Arg) >= 3 && + L[3]->Arg[0] == '<' && + strlen(L[6]->Arg) >= 3 && + L[6]->Arg[0] == '>' && + !strcmp(L[3]->Arg+1, L[6]->Arg+1) && + CE_IsCallTo (L[10], "ldaxidx") && + !CS_RangeHasLabel (S, I+1, 10)) { + + CodeEntry* X; + char* Label; + int Len = strlen(L[3]->Arg); + + /* Track the insertion point */ + unsigned IP = I + 11; + + /* asl a */ + X = NewCodeEntry (OP65_ASL, AM65_ACC, "a", 0, L[1]->LI); + CS_InsertEntry (S, X, IP++); + + /* tay */ + X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, L[1]->LI); + CS_InsertEntry (S, X, IP++); + + /* lda label,y */ + Label = memcpy (xmalloc (Len-2), L[3]->Arg+2, Len-3); + Label[Len-3] = '\0'; + X = NewCodeEntry (OP65_LDA, AM65_ABSY, Label, 0, L[9]->LI); + CS_InsertEntry (S, X, IP++); + xfree (Label); + + /* lda label+1,y */ + Label = memcpy (xmalloc (Len), L[3]->Arg+2, Len-3); + strcpy(&Label[Len-3], "+1"); + X = NewCodeEntry (OP65_LDX, AM65_ABSY, Label, 0, L[9]->LI); + CS_InsertEntry (S, X, IP++); + xfree (Label); + + /* Remove the old code */ + /* Remove the AND only if it's == 127, since ASL erases high bit */ + if (L[0]->Num == 127) + CS_DelEntries (S, I, 11); + else + CS_DelEntries (S, I+1, 10); + + /* Remember, we had changes */ + ++Changes; + + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + + diff --git a/src/cc65/coptptrload.h b/src/cc65/coptptrload.h index 4581ccb45..8a118a268 100644 --- a/src/cc65/coptptrload.h +++ b/src/cc65/coptptrload.h @@ -379,6 +379,31 @@ unsigned OptPtrLoad18 (CodeSeg* S); */ +unsigned OptPtrLoad19 (CodeSeg* S); +/* Search for the sequence: +** +** and #mask (any value < 128) +** jsr aslax1/shlax1 +** clc +** adc #<(label+0) +** tay +** txa +** adc #>(label+0) +** tax +** tya +** ldy #$01 +** jsr ldaxidx +** +** and replace it by: +** +** and #mask (remove if == 127) +** asl +** tay +** lda label,y +** ldx label+1,y +*/ + + /* End of coptptrload.h */ #endif From dca99d59e51515dbf511271afa093247dbd6869a Mon Sep 17 00:00:00 2001 From: Steven Hugg <hugg@fasterlight.com> Date: Thu, 14 Mar 2019 11:00:02 -0400 Subject: [PATCH 1040/2161] rearranged order of new optimizations to better handle -Oi flag --- src/cc65/codeopt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index d920f001a..498aa0ff2 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -1249,8 +1249,9 @@ static unsigned RunOptGroup1 (CodeSeg* S) Changes += RunOptFunc (S, &DOptPtrLoad4, 1); Changes += RunOptFunc (S, &DOptPtrLoad5, 1); Changes += RunOptFunc (S, &DOptPtrLoad6, 1); + Changes += RunOptFunc (S, &DOptPtrLoad18, 1); /* Before OptPtrLoad7 */ + Changes += RunOptFunc (S, &DOptPtrLoad19, 1); /* Before OptPtrLoad7 */ Changes += RunOptFunc (S, &DOptPtrLoad7, 1); - Changes += RunOptFunc (S, &DOptPtrLoad18, 1); /* Before OptPtrLoad11 */ Changes += RunOptFunc (S, &DOptPtrLoad11, 1); Changes += RunOptFunc (S, &DOptPtrLoad12, 1); Changes += RunOptFunc (S, &DOptPtrLoad13, 1); @@ -1258,7 +1259,6 @@ static unsigned RunOptGroup1 (CodeSeg* S) Changes += RunOptFunc (S, &DOptPtrLoad15, 1); Changes += RunOptFunc (S, &DOptPtrLoad16, 1); Changes += RunOptFunc (S, &DOptPtrLoad17, 1); - Changes += RunOptFunc (S, &DOptPtrLoad19, 1); Changes += RunOptFunc (S, &DOptBNegAX1, 1); Changes += RunOptFunc (S, &DOptBNegAX2, 1); Changes += RunOptFunc (S, &DOptBNegAX3, 1); From a71f764c33b5dd5281a9a87f4fe788da3d4eb0b1 Mon Sep 17 00:00:00 2001 From: Steven Hugg <hugg@fasterlight.com> Date: Fri, 15 Mar 2019 15:10:58 -0400 Subject: [PATCH 1041/2161] fixed optimization bug where array index is 16-bit, e.g. arr16[i & 0x7f7f] --- src/cc65/coptptrload.c | 76 +++++++++++++++++++++++------------------- src/cc65/coptptrload.h | 2 ++ 2 files changed, 43 insertions(+), 35 deletions(-) diff --git a/src/cc65/coptptrload.c b/src/cc65/coptptrload.c index c508d56f4..da5525b48 100644 --- a/src/cc65/coptptrload.c +++ b/src/cc65/coptptrload.c @@ -1557,6 +1557,7 @@ unsigned OptPtrLoad18 (CodeSeg* S) unsigned OptPtrLoad19 (CodeSeg* S) /* Search for the sequence: ** +** ldx #0 ** and #mask (any value < 128) ** jsr aslax1/shlax1 ** clc @@ -1571,6 +1572,7 @@ unsigned OptPtrLoad19 (CodeSeg* S) ** ** and replace it by: ** +** ldx #0 ** and #mask (remove if == 127) ** asl ** tay @@ -1585,71 +1587,75 @@ unsigned OptPtrLoad19 (CodeSeg* S) I = 0; while (I < CS_GetEntryCount (S)) { - CodeEntry* L[11]; + CodeEntry* L[12]; /* Get next entry */ L[0] = CS_GetEntry (S, I); /* Check for the sequence */ - if (L[0]->OPC == OP65_AND && - L[0]->AM == AM65_IMM && - CE_HasNumArg (L[0]) && L[0]->Num <= 127 && - CS_GetEntries (S, L+1, I+1, 10) && - L[1]->OPC == OP65_JSR && - (strcmp (L[1]->Arg, "aslax1") == 0 || - strcmp (L[1]->Arg, "shlax1") == 0) && - L[2]->OPC == OP65_CLC && - L[3]->OPC == OP65_ADC && - L[4]->OPC == OP65_TAY && - L[5]->OPC == OP65_TXA && - L[6]->OPC == OP65_ADC && - L[7]->OPC == OP65_TAX && - L[8]->OPC == OP65_TYA && - L[9]->OPC == OP65_LDY && - CE_IsKnownImm(L[9], 1) && - strlen(L[3]->Arg) >= 3 && - L[3]->Arg[0] == '<' && - strlen(L[6]->Arg) >= 3 && - L[6]->Arg[0] == '>' && - !strcmp(L[3]->Arg+1, L[6]->Arg+1) && - CE_IsCallTo (L[10], "ldaxidx") && - !CS_RangeHasLabel (S, I+1, 10)) { + if (L[0]->OPC == OP65_LDX && + CE_IsKnownImm(L[0], 0) && + CS_GetEntries (S, L+1, I+1, 11) && + L[1]->OPC == OP65_AND && + L[1]->AM == AM65_IMM && + CE_HasNumArg (L[1]) && L[1]->Num <= 127 && + L[2]->OPC == OP65_JSR && + (strcmp (L[2]->Arg, "aslax1") == 0 || + strcmp (L[2]->Arg, "shlax1") == 0) && + L[3]->OPC == OP65_CLC && + L[4]->OPC == OP65_ADC && + L[5]->OPC == OP65_TAY && + L[6]->OPC == OP65_TXA && + L[7]->OPC == OP65_ADC && + L[8]->OPC == OP65_TAX && + L[9]->OPC == OP65_TYA && + L[10]->OPC == OP65_LDY && + CE_IsKnownImm(L[10], 1) && + strlen(L[4]->Arg) >= 3 && + L[4]->Arg[0] == '<' && + strlen(L[7]->Arg) >= 3 && + L[7]->Arg[0] == '>' && + !strcmp(L[4]->Arg+1, L[7]->Arg+1) && + CE_IsCallTo (L[11], "ldaxidx") && + !CS_RangeHasLabel (S, I+1, 11)) { CodeEntry* X; char* Label; - int Len = strlen(L[3]->Arg); + int Len = strlen(L[4]->Arg); /* Track the insertion point */ - unsigned IP = I + 11; + unsigned IP = I + 12; /* asl a */ - X = NewCodeEntry (OP65_ASL, AM65_ACC, "a", 0, L[1]->LI); + X = NewCodeEntry (OP65_ASL, AM65_ACC, "a", 0, L[2]->LI); CS_InsertEntry (S, X, IP++); /* tay */ - X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, L[1]->LI); + X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, L[2]->LI); CS_InsertEntry (S, X, IP++); /* lda label,y */ - Label = memcpy (xmalloc (Len-2), L[3]->Arg+2, Len-3); + Label = memcpy (xmalloc (Len-2), L[4]->Arg+2, Len-3); Label[Len-3] = '\0'; - X = NewCodeEntry (OP65_LDA, AM65_ABSY, Label, 0, L[9]->LI); + X = NewCodeEntry (OP65_LDA, AM65_ABSY, Label, 0, L[10]->LI); CS_InsertEntry (S, X, IP++); xfree (Label); /* lda label+1,y */ - Label = memcpy (xmalloc (Len), L[3]->Arg+2, Len-3); + Label = memcpy (xmalloc (Len), L[4]->Arg+2, Len-3); strcpy(&Label[Len-3], "+1"); - X = NewCodeEntry (OP65_LDX, AM65_ABSY, Label, 0, L[9]->LI); + X = NewCodeEntry (OP65_LDX, AM65_ABSY, Label, 0, L[10]->LI); CS_InsertEntry (S, X, IP++); xfree (Label); /* Remove the old code */ /* Remove the AND only if it's == 127, since ASL erases high bit */ - if (L[0]->Num == 127) - CS_DelEntries (S, I, 11); + if (L[1]->Num == 127) + CS_DelEntries (S, I+1, 11); else - CS_DelEntries (S, I+1, 10); + CS_DelEntries (S, I+2, 10); + /* Remove the ldx #0 */ + CS_DelEntry(S, I); /* Remember, we had changes */ ++Changes; diff --git a/src/cc65/coptptrload.h b/src/cc65/coptptrload.h index 8a118a268..4e9db8f80 100644 --- a/src/cc65/coptptrload.h +++ b/src/cc65/coptptrload.h @@ -382,6 +382,7 @@ unsigned OptPtrLoad18 (CodeSeg* S); unsigned OptPtrLoad19 (CodeSeg* S); /* Search for the sequence: ** +** ldx #0 ** and #mask (any value < 128) ** jsr aslax1/shlax1 ** clc @@ -396,6 +397,7 @@ unsigned OptPtrLoad19 (CodeSeg* S); ** ** and replace it by: ** +** ldx #0 ** and #mask (remove if == 127) ** asl ** tay From 9faaa0689b028ab064ba0d60341280df033e3f0e Mon Sep 17 00:00:00 2001 From: Steven Hugg <hugg@fasterlight.com> Date: Sat, 16 Mar 2019 17:35:22 -0400 Subject: [PATCH 1042/2161] cleaned up code per review --- src/cc65/coptptrload.c | 58 +++++++++++++++++++++--------------------- src/cc65/coptptrload.h | 13 +++++----- 2 files changed, 35 insertions(+), 36 deletions(-) diff --git a/src/cc65/coptptrload.c b/src/cc65/coptptrload.c index da5525b48..c23858579 100644 --- a/src/cc65/coptptrload.c +++ b/src/cc65/coptptrload.c @@ -1480,7 +1480,7 @@ unsigned OptPtrLoad18 (CodeSeg* S) ** ** This is similar to OptPtrLoad3 but works on a constant address ** instead of a label. Also, the initial X and A loads are reversed. -** Must be run before OptPtrLoad11. +** Must be run before OptPtrLoad7(). */ { unsigned Changes = 0; @@ -1512,10 +1512,10 @@ unsigned OptPtrLoad18 (CodeSeg* S) CE_IsCallTo (L[7], "ldauidx") && !CS_RangeHasLabel (S, I+1, 5) && !CE_HasLabel (L[7]) && - strlen (L[0]->Arg) == 3 && L[0]->Arg[0] == '$' && - strlen (L[1]->Arg) == 3 && - L[1]->Arg[0] == '$' ) { + L[1]->Arg[0] == '$' && + strlen (L[0]->Arg) == 3 && + strlen (L[1]->Arg) == 3 ) { CodeEntry* X; char* Label; @@ -1558,7 +1558,7 @@ unsigned OptPtrLoad19 (CodeSeg* S) /* Search for the sequence: ** ** ldx #0 -** and #mask (any value < 128) +** and #mask (any value < 0x80) ** jsr aslax1/shlax1 ** clc ** adc #<(label+0) @@ -1572,12 +1572,11 @@ unsigned OptPtrLoad19 (CodeSeg* S) ** ** and replace it by: ** -** ldx #0 -** and #mask (remove if == 127) -** asl -** tay -** lda label,y -** ldx label+1,y +** and #mask (remove if == 0x7F) +** asl +** tay +** lda label,y +** ldx label+1,y */ { unsigned Changes = 0; @@ -1598,10 +1597,8 @@ unsigned OptPtrLoad19 (CodeSeg* S) CS_GetEntries (S, L+1, I+1, 11) && L[1]->OPC == OP65_AND && L[1]->AM == AM65_IMM && - CE_HasNumArg (L[1]) && L[1]->Num <= 127 && + CE_HasNumArg (L[1]) && L[1]->Num <= 0x7F && L[2]->OPC == OP65_JSR && - (strcmp (L[2]->Arg, "aslax1") == 0 || - strcmp (L[2]->Arg, "shlax1") == 0) && L[3]->OPC == OP65_CLC && L[4]->OPC == OP65_ADC && L[5]->OPC == OP65_TAY && @@ -1609,13 +1606,15 @@ unsigned OptPtrLoad19 (CodeSeg* S) L[7]->OPC == OP65_ADC && L[8]->OPC == OP65_TAX && L[9]->OPC == OP65_TYA && - L[10]->OPC == OP65_LDY && - CE_IsKnownImm(L[10], 1) && - strlen(L[4]->Arg) >= 3 && + L[10]->OPC == OP65_LDY && + CE_IsKnownImm(L[10], 1) && L[4]->Arg[0] == '<' && - strlen(L[7]->Arg) >= 3 && L[7]->Arg[0] == '>' && - !strcmp(L[4]->Arg+1, L[7]->Arg+1) && + strlen(L[4]->Arg) > 3 && + strlen(L[7]->Arg) > 3 && + strcmp(L[4]->Arg+1, L[7]->Arg+1) == 0 && + (strcmp (L[2]->Arg, "aslax1") == 0 || + strcmp (L[2]->Arg, "shlax1") == 0) && CE_IsCallTo (L[11], "ldaxidx") && !CS_RangeHasLabel (S, I+1, 11)) { @@ -1634,26 +1633,30 @@ unsigned OptPtrLoad19 (CodeSeg* S) X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, L[2]->LI); CS_InsertEntry (S, X, IP++); + /* allocate Label memory */ + Label = xmalloc (Len); /* lda label,y */ - Label = memcpy (xmalloc (Len-2), L[4]->Arg+2, Len-3); + Label = memcpy (Label, L[4]->Arg+2, Len-3); Label[Len-3] = '\0'; X = NewCodeEntry (OP65_LDA, AM65_ABSY, Label, 0, L[10]->LI); CS_InsertEntry (S, X, IP++); - xfree (Label); - /* lda label+1,y */ - Label = memcpy (xmalloc (Len), L[4]->Arg+2, Len-3); + /* ldx label+1,y */ + Label = memcpy (Label, L[4]->Arg+2, Len-3); strcpy(&Label[Len-3], "+1"); X = NewCodeEntry (OP65_LDX, AM65_ABSY, Label, 0, L[10]->LI); CS_InsertEntry (S, X, IP++); + /* free Label memory */ xfree (Label); /* Remove the old code */ - /* Remove the AND only if it's == 127, since ASL erases high bit */ - if (L[1]->Num == 127) + /* Remove the AND only if it's == 0x7F, since ASL erases high bit */ + if (L[1]->Num == 0x7F) { CS_DelEntries (S, I+1, 11); - else + } else { CS_DelEntries (S, I+2, 10); + } + /* Remove the ldx #0 */ CS_DelEntry(S, I); @@ -1670,6 +1673,3 @@ unsigned OptPtrLoad19 (CodeSeg* S) /* Return the number of changes made */ return Changes; } - - - diff --git a/src/cc65/coptptrload.h b/src/cc65/coptptrload.h index 4e9db8f80..84d7cc19f 100644 --- a/src/cc65/coptptrload.h +++ b/src/cc65/coptptrload.h @@ -383,7 +383,7 @@ unsigned OptPtrLoad19 (CodeSeg* S); /* Search for the sequence: ** ** ldx #0 -** and #mask (any value < 128) +** and #mask (any value < 0x80) ** jsr aslax1/shlax1 ** clc ** adc #<(label+0) @@ -397,12 +397,11 @@ unsigned OptPtrLoad19 (CodeSeg* S); ** ** and replace it by: ** -** ldx #0 -** and #mask (remove if == 127) -** asl -** tay -** lda label,y -** ldx label+1,y +** and #mask (remove if == 0x7F) +** asl +** tay +** lda label,y +** ldx label+1,y */ From ae261e91f2cce3d828c1df4df5bc1bce72586d1c Mon Sep 17 00:00:00 2001 From: Steven Hugg <hugg@fasterlight.com> Date: Sun, 31 Mar 2019 21:39:36 -0400 Subject: [PATCH 1043/2161] Code cleanup per code review --- src/cc65/coptptrload.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/cc65/coptptrload.c b/src/cc65/coptptrload.c index c23858579..0534a1fa2 100644 --- a/src/cc65/coptptrload.c +++ b/src/cc65/coptptrload.c @@ -1633,16 +1633,14 @@ unsigned OptPtrLoad19 (CodeSeg* S) X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, L[2]->LI); CS_InsertEntry (S, X, IP++); - /* allocate Label memory */ - Label = xmalloc (Len); /* lda label,y */ - Label = memcpy (Label, L[4]->Arg+2, Len-3); + /* allocate Label memory */ + Label = memcpy (xmalloc (Len), L[4]->Arg+2, Len-3); Label[Len-3] = '\0'; X = NewCodeEntry (OP65_LDA, AM65_ABSY, Label, 0, L[10]->LI); CS_InsertEntry (S, X, IP++); /* ldx label+1,y */ - Label = memcpy (Label, L[4]->Arg+2, Len-3); strcpy(&Label[Len-3], "+1"); X = NewCodeEntry (OP65_LDX, AM65_ABSY, Label, 0, L[10]->LI); CS_InsertEntry (S, X, IP++); From 1530020a1f10e5155a849621f0f6bca8deaf6732 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Mon, 1 Apr 2019 21:47:00 +0200 Subject: [PATCH 1044/2161] Fix for multiplication optimization issue #367 --- src/cc65/coptstop.c | 43 ++++++++++++++++++++++++++++--------------- test/val/bug367.c | 12 ++++++++++++ 2 files changed, 40 insertions(+), 15 deletions(-) create mode 100644 test/val/bug367.c diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 41d928750..1d14ec59c 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2001-2013, Ullrich von Bassewitz */ +/* (C) 2001-2019, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -122,7 +122,7 @@ struct StackOpData { const OptFuncDesc* OptFunc; /* ZP register usage inside the sequence */ - unsigned UsedRegs; + unsigned ZPUsage; /* Register load information for lhs and rhs */ LoadInfo Lhs; @@ -1771,7 +1771,7 @@ static void ResetStackOpData (StackOpData* Data) /* Reset the given data structure */ { Data->OptFunc = 0; - Data->UsedRegs = REG_NONE; + Data->ZPUsage = REG_NONE; ClearLoadInfo (&Data->Lhs); ClearLoadInfo (&Data->Rhs); @@ -1832,14 +1832,16 @@ static int PreCondOk (StackOpData* D) return 0; } - /* Determine the zero page locations to use */ - if ((D->UsedRegs & REG_PTR1) == REG_NONE) { + /* Determine the zero page locations to use. We've tracked the used + * ZP locations, so try to find some for us that are unused. + */ + if ((D->ZPUsage & REG_PTR1) == REG_NONE) { D->ZPLo = "ptr1"; D->ZPHi = "ptr1+1"; - } else if ((D->UsedRegs & REG_SREG) == REG_NONE) { + } else if ((D->ZPUsage & REG_SREG) == REG_NONE) { D->ZPLo = "sreg"; D->ZPHi = "sreg+1"; - } else if ((D->UsedRegs & REG_PTR2) == REG_NONE) { + } else if ((D->ZPUsage & REG_PTR2) == REG_NONE) { D->ZPLo = "ptr2"; D->ZPHi = "ptr2+1"; } else { @@ -1959,7 +1961,7 @@ unsigned OptStackOps (CodeSeg* S) break; } else { /* Track register usage */ - Data.UsedRegs |= (E->Use | E->Chg); + Data.ZPUsage |= (E->Use | E->Chg); TrackLoads (&Data.Rhs, E, I); } @@ -1991,7 +1993,7 @@ unsigned OptStackOps (CodeSeg* S) } else { /* Other stuff: Track register usage */ - Data.UsedRegs |= (E->Use | E->Chg); + Data.ZPUsage |= (E->Use | E->Chg); TrackLoads (&Data.Rhs, E, I); } /* If the registers from the push (A/X) are used before they're @@ -2009,21 +2011,32 @@ unsigned OptStackOps (CodeSeg* S) case FoundOp: /* Track zero page location usage beyond this point */ - Data.UsedRegs |= GetRegInfo (S, I, REG_SREG | REG_PTR1 | REG_PTR2); + Data.ZPUsage |= GetRegInfo (S, I, REG_SREG | REG_PTR1 | REG_PTR2); /* Finalize the load info */ FinalizeLoadInfo (&Data.Lhs, S); FinalizeLoadInfo (&Data.Rhs, S); - /* If the Lhs loads do load from zeropage, we have to include - ** them into UsedRegs registers used. The Rhs loads have already - ** been tracked. + /* Check if the lhs loads from zeropage. If this is true, these + * zero page locations have to be added to ZPUsage, because + * they cannot be used for intermediate storage. In addition, + * if one of these zero page locations is destroyed between + * pushing the lhs and the actual operation, we cannot use the + * original zero page locations for the final op, but must + * use another ZP location to save them. */ + ChangedRegs &= REG_ZP; if (Data.Lhs.A.LoadEntry && Data.Lhs.A.LoadEntry->AM == AM65_ZP) { - Data.UsedRegs |= Data.Lhs.A.LoadEntry->Use; + Data.ZPUsage |= Data.Lhs.A.LoadEntry->Use; + if ((Data.Lhs.A.LoadEntry->Use & ChangedRegs) != 0) { + Data.Lhs.A.Flags &= ~(LI_DIRECT | LI_RELOAD_Y); + } } if (Data.Lhs.X.LoadEntry && Data.Lhs.X.LoadEntry->AM == AM65_ZP) { - Data.UsedRegs |= Data.Lhs.X.LoadEntry->Use; + Data.ZPUsage |= Data.Lhs.X.LoadEntry->Use; + if ((Data.Lhs.X.LoadEntry->Use & ChangedRegs) != 0) { + Data.Lhs.X.Flags &= ~(LI_DIRECT | LI_RELOAD_Y); + } } /* Check the preconditions. If they aren't ok, reset the insn diff --git a/test/val/bug367.c b/test/val/bug367.c new file mode 100644 index 000000000..affe6b88e --- /dev/null +++ b/test/val/bug367.c @@ -0,0 +1,12 @@ +#include "unittest.h" + +TEST +{ + unsigned int y=192; + unsigned int d=y&0xFFF8; + unsigned int e=d*32+d*8; + unsigned int f=d*40; + + ASSERT_AreEqual(f, e, "%u", "Multiplication results differ (should be 7680)!"); +} +ENDTEST From dcbe03f23bebea52a239e8355f2c4b3a71bb6574 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Mon, 1 Apr 2019 23:08:51 +0200 Subject: [PATCH 1045/2161] Adjusted to the current multiline-comment style. --- src/cc65/coptstop.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 1d14ec59c..53582d565 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -1833,8 +1833,8 @@ static int PreCondOk (StackOpData* D) } /* Determine the zero page locations to use. We've tracked the used - * ZP locations, so try to find some for us that are unused. - */ + ** ZP locations, so try to find some for us that are unused. + */ if ((D->ZPUsage & REG_PTR1) == REG_NONE) { D->ZPLo = "ptr1"; D->ZPHi = "ptr1+1"; @@ -2018,12 +2018,12 @@ unsigned OptStackOps (CodeSeg* S) FinalizeLoadInfo (&Data.Rhs, S); /* Check if the lhs loads from zeropage. If this is true, these - * zero page locations have to be added to ZPUsage, because - * they cannot be used for intermediate storage. In addition, - * if one of these zero page locations is destroyed between - * pushing the lhs and the actual operation, we cannot use the - * original zero page locations for the final op, but must - * use another ZP location to save them. + ** zero page locations have to be added to ZPUsage, because + ** they cannot be used for intermediate storage. In addition, + ** if one of these zero page locations is destroyed between + ** pushing the lhs and the actual operation, we cannot use the + ** original zero page locations for the final op, but must + ** use another ZP location to save them. */ ChangedRegs &= REG_ZP; if (Data.Lhs.A.LoadEntry && Data.Lhs.A.LoadEntry->AM == AM65_ZP) { From fc6a63a15e431b53a993ad285598536f0485bb7f Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 4 Apr 2019 09:16:59 +0200 Subject: [PATCH 1046/2161] Avoid unintended file "shadowing". https://github.com/cc65/cc65/commit/3d8c3a494801e106e33fa7dcc4fd3daedad1b98a caused an unintended "shadowing" of files in /libsrc/runtime by files in /libsrc/common. Therefore the files in question are renamed (again) in /libsrc/common to make the files in /libsrc/runtime "visible" again. --- libsrc/common/{idiv32by16r16.s => _idiv32by16r16.s} | 0 libsrc/common/{imul16x16r32.s => _imul16x16r32.s} | 0 libsrc/common/{imul8x8r16.s => _imul8x8r16.s} | 0 libsrc/common/{udiv32by16r16.s => _udiv32by16r16.s} | 0 libsrc/common/{umul16x16r32.s => _umul16x16r32.s} | 0 libsrc/common/{umul16x8r32.s => _umul16x8r32.s} | 0 libsrc/common/{umul8x8r16.s => _umul8x8r16.s} | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename libsrc/common/{idiv32by16r16.s => _idiv32by16r16.s} (100%) rename libsrc/common/{imul16x16r32.s => _imul16x16r32.s} (100%) rename libsrc/common/{imul8x8r16.s => _imul8x8r16.s} (100%) rename libsrc/common/{udiv32by16r16.s => _udiv32by16r16.s} (100%) rename libsrc/common/{umul16x16r32.s => _umul16x16r32.s} (100%) rename libsrc/common/{umul16x8r32.s => _umul16x8r32.s} (100%) rename libsrc/common/{umul8x8r16.s => _umul8x8r16.s} (100%) diff --git a/libsrc/common/idiv32by16r16.s b/libsrc/common/_idiv32by16r16.s similarity index 100% rename from libsrc/common/idiv32by16r16.s rename to libsrc/common/_idiv32by16r16.s diff --git a/libsrc/common/imul16x16r32.s b/libsrc/common/_imul16x16r32.s similarity index 100% rename from libsrc/common/imul16x16r32.s rename to libsrc/common/_imul16x16r32.s diff --git a/libsrc/common/imul8x8r16.s b/libsrc/common/_imul8x8r16.s similarity index 100% rename from libsrc/common/imul8x8r16.s rename to libsrc/common/_imul8x8r16.s diff --git a/libsrc/common/udiv32by16r16.s b/libsrc/common/_udiv32by16r16.s similarity index 100% rename from libsrc/common/udiv32by16r16.s rename to libsrc/common/_udiv32by16r16.s diff --git a/libsrc/common/umul16x16r32.s b/libsrc/common/_umul16x16r32.s similarity index 100% rename from libsrc/common/umul16x16r32.s rename to libsrc/common/_umul16x16r32.s diff --git a/libsrc/common/umul16x8r32.s b/libsrc/common/_umul16x8r32.s similarity index 100% rename from libsrc/common/umul16x8r32.s rename to libsrc/common/_umul16x8r32.s diff --git a/libsrc/common/umul8x8r16.s b/libsrc/common/_umul8x8r16.s similarity index 100% rename from libsrc/common/umul8x8r16.s rename to libsrc/common/_umul8x8r16.s From 5daed49e978e3b8c6fbdc1535a401b9623d049fd Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 4 Apr 2019 16:38:40 +0200 Subject: [PATCH 1047/2161] Fixed typo. --- samples/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index 74094aeae..abc8194c9 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -51,8 +51,8 @@ ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),) # If TARGET_PATH contains spaces then it is presumed to contain escaped spaces. GNU make # has very limited support for paths containing spaces. $(wildcard) is the only function # that is aware of escaped spaces. However, $(wildcard) never returns paths with escaped - # spaces !!! So if it e.g. finds in a path with 2 spaces 4 files then one ends up with a - # return value consisting of 12 plain words :-(( + # spaces !!! So if it e.g. finds in a path with 2 spaces in 4 files then one ends up with + # a return value consisting of 12 plain words :-(( # # Fortunately we can work around that behaviour here because we know that the files we # are looking for have known extensions. So we can $(filter) the in our example above 12 From 0576fe51e70431906e93c0f3ab5b8a900b806f73 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 4 Apr 2019 17:13:09 +0200 Subject: [PATCH 1048/2161] Minor clarification. --- samples/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index abc8194c9..6c94495f5 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -51,8 +51,8 @@ ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),) # If TARGET_PATH contains spaces then it is presumed to contain escaped spaces. GNU make # has very limited support for paths containing spaces. $(wildcard) is the only function # that is aware of escaped spaces. However, $(wildcard) never returns paths with escaped - # spaces !!! So if it e.g. finds in a path with 2 spaces in 4 files then one ends up with - # a return value consisting of 12 plain words :-(( + # spaces !!! So if it e.g. finds 4 files in a path with 2 spaces then one ends up with a + # return value consisting of 12 plain words :-(( # # Fortunately we can work around that behaviour here because we know that the files we # are looking for have known extensions. So we can $(filter) the in our example above 12 From edd596b2a4438788dca88f457910945614699ba1 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 2 Apr 2019 19:10:52 +0200 Subject: [PATCH 1049/2161] atari: split color.s into bordercolor.s and bgcolor.s --- include/atari.h | 6 ++++++ libsrc/atari/{color.s => bgcolor.s} | 16 ++-------------- libsrc/atari/bordercolor.s | 15 +++++++++++++++ 3 files changed, 23 insertions(+), 14 deletions(-) rename libsrc/atari/{color.s => bgcolor.s} (54%) create mode 100644 libsrc/atari/bordercolor.s diff --git a/include/atari.h b/include/atari.h index a0d4a3d27..899a6ac51 100644 --- a/include/atari.h +++ b/include/atari.h @@ -491,5 +491,11 @@ extern void atrx15p2_tgi[]; #define PxCTL_IRQ_STATUS 0x80 +/* 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 _textcolor(color) 1 + /* End of atari.h */ #endif diff --git a/libsrc/atari/color.s b/libsrc/atari/bgcolor.s similarity index 54% rename from libsrc/atari/color.s rename to libsrc/atari/bgcolor.s index 57d0036c9..928dfff9a 100644 --- a/libsrc/atari/color.s +++ b/libsrc/atari/bgcolor.s @@ -1,15 +1,12 @@ ; -; Christian Groessler, 27-Dec-2002 +; Christian Groessler, 02-Apr-2019 ; - .export _textcolor, _bgcolor, _bordercolor - .import return1 + .export _bgcolor .include "atari.inc" -_textcolor = return1 - _bgcolor: ldx COLOR2 ; get old value sta COLOR2 ; set new value @@ -23,12 +20,3 @@ bright: lda #0 txa ldx #0 ; fix X rts - - -_bordercolor: - ldx COLOR4 ; get old value - sta COLOR4 ; set new value - txa - ldx #0 ; fix X - rts - diff --git a/libsrc/atari/bordercolor.s b/libsrc/atari/bordercolor.s new file mode 100644 index 000000000..b519686c5 --- /dev/null +++ b/libsrc/atari/bordercolor.s @@ -0,0 +1,15 @@ +; +; Christian Groessler, 02-Apr-2019 +; + + .export _bordercolor + + .include "atari.inc" + + +_bordercolor: + ldx COLOR4 ; get old value + sta COLOR4 ; set new value + txa + ldx #0 ; fix X + rts From ec5e38617a6bbb00bac0411d7d0125afb5a1f5c3 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 2 Apr 2019 21:11:11 +0200 Subject: [PATCH 1050/2161] atari5200: implement bgcolor() and textcolor() Includes some other small fixes/cleanups. --- asminc/atari5200.inc | 10 ++++ include/atari.h | 2 +- include/atari5200.h | 14 +++++ libsrc/atari/chline.s | 4 -- libsrc/atari/cvline.s | 4 -- libsrc/atari5200/bgcolor.s | 1 + libsrc/atari5200/chline.s | 27 ++++++++- libsrc/atari5200/conioscreen.s | 9 +++ libsrc/atari5200/cputc.s | 18 +++--- libsrc/atari5200/cvline.s | 32 ++++++++++- libsrc/atari5200/gotox.s | 3 +- libsrc/atari5200/gotoxy.s | 3 +- libsrc/atari5200/gotoy.s | 3 +- libsrc/atari5200/textcolor.s | 28 +++++++++ libsrc/atari5200/wherex.s | 13 +++++ libsrc/atari5200/wherey.s | 13 +++++ samples/hello.c | 2 +- testcode/lib/atari5200/hello.c | 101 +++++++++++++++++++++++++++++++++ 18 files changed, 261 insertions(+), 26 deletions(-) create mode 100644 libsrc/atari5200/bgcolor.s create mode 100644 libsrc/atari5200/textcolor.s create mode 100644 libsrc/atari5200/wherex.s create mode 100644 libsrc/atari5200/wherey.s create mode 100644 testcode/lib/atari5200/hello.c diff --git a/asminc/atari5200.inc b/asminc/atari5200.inc index 91fae4a9a..a1fe624e6 100644 --- a/asminc/atari5200.inc +++ b/asminc/atari5200.inc @@ -10,6 +10,16 @@ ATEOL = $9B ; END-OF-LINE, used by CONIO +;------------------------------------------------------------------------- +; CONIO CHARACTER DEFS +;------------------------------------------------------------------------- + +CH_ULCORNER = $0B ; '+' sign +CH_URCORNER = $0B +CH_LLCORNER = $0B +CH_LRCORNER = $0B +CH_HLINE = $0D ; dash +CH_VLINE = $01 ; exclamation mark ;------------------------------------------------------------------------- ; Zero Page diff --git a/include/atari.h b/include/atari.h index 899a6ac51..455c43260 100644 --- a/include/atari.h +++ b/include/atari.h @@ -491,7 +491,7 @@ extern void atrx15p2_tgi[]; #define PxCTL_IRQ_STATUS 0x80 -/* The following #defines will cause the matching functions calls in conio.h +/* The following #define will cause the matching function calls in conio.h ** to be overlaid by macros with the same names, saving the function call ** overhead. */ diff --git a/include/atari5200.h b/include/atari5200.h index 67c11c1df..10cd32fe9 100644 --- a/include/atari5200.h +++ b/include/atari5200.h @@ -53,6 +53,14 @@ extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */ #define JOY_RIGHT_MASK 0x08 #define JOY_BTN_1_MASK 0x10 +/* Character codes */ +#define CH_ULCORNER 0x0B /* '+' sign */ +#define CH_URCORNER 0x0B +#define CH_LLCORNER 0x0B +#define CH_LRCORNER 0x0B +#define CH_HLINE 0x0D /* dash */ +#define CH_VLINE 0x01 /* exclamation mark */ + /* get_tv return values */ #define AT_NTSC 0 #define AT_PAL 1 @@ -69,5 +77,11 @@ extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */ #include <_antic.h> #define ANTIC (*(struct __antic*)0xD400) +/* The following #define will cause the matching function calls in conio.h +** to be overlaid by macros with the same names, saving the function call +** overhead. +*/ +#define _bordercolor(color) 0 + /* End of atari5200.h */ #endif diff --git a/libsrc/atari/chline.s b/libsrc/atari/chline.s index 194fe0bb3..f4931dd4f 100644 --- a/libsrc/atari/chline.s +++ b/libsrc/atari/chline.s @@ -9,11 +9,7 @@ .import gotoxy, cputdirect, setcursor .importzp tmp1 -.ifdef __ATARI5200__ -CHRCODE = 14 -.else CHRCODE = $12+64 -.endif _chlinexy: pha ; Save the length diff --git a/libsrc/atari/cvline.s b/libsrc/atari/cvline.s index 1b4ba0b1b..735e47dd2 100644 --- a/libsrc/atari/cvline.s +++ b/libsrc/atari/cvline.s @@ -10,11 +10,7 @@ .import gotoxy, putchar, setcursor .importzp tmp1 -.ifdef __ATARI5200__ -CHRCODE = 1 ; exclamation mark -.else CHRCODE = $7C ; Vertical bar -.endif _cvlinexy: pha ; Save the length diff --git a/libsrc/atari5200/bgcolor.s b/libsrc/atari5200/bgcolor.s new file mode 100644 index 000000000..1f9f77260 --- /dev/null +++ b/libsrc/atari5200/bgcolor.s @@ -0,0 +1 @@ +.include "../atari/bgcolor.s" diff --git a/libsrc/atari5200/chline.s b/libsrc/atari5200/chline.s index d5872f149..47c57966b 100644 --- a/libsrc/atari5200/chline.s +++ b/libsrc/atari5200/chline.s @@ -1 +1,26 @@ -.include "../atari/chline.s" +; +; Ullrich von Bassewitz, 08.08.1998 +; +; void chlinexy (unsigned char x, unsigned char y, unsigned char length); +; void chline (unsigned char length); +; + + .export _chlinexy, _chline + .import gotoxy, cputdirect + .importzp tmp1 + .include "atari5200.inc" + +_chlinexy: + pha ; Save the length + jsr gotoxy ; Call this one, will pop params + pla ; Restore the length + +_chline: + cmp #0 ; Is the length zero? + beq L9 ; Jump if done + sta tmp1 +L1: lda #CH_HLINE ; Horizontal line, screen code + jsr cputdirect ; Direct output + dec tmp1 + bne L1 +L9: rts diff --git a/libsrc/atari5200/conioscreen.s b/libsrc/atari5200/conioscreen.s index 30c0e0788..2c6a8a4e4 100644 --- a/libsrc/atari5200/conioscreen.s +++ b/libsrc/atari5200/conioscreen.s @@ -8,6 +8,12 @@ SCREEN_BUF_SIZE = 20 * 24 SCREEN_BUF = $4000 - SCREEN_BUF_SIZE .export screen_setup_20x24 + .export screen_width, screen_height + .export conio_color + +screen_width = 20 +screen_height = 24 + .segment "ONCE" @@ -57,6 +63,9 @@ clrscr: sta (SAVMSC),y rts + .data + +conio_color: .byte 0 .segment "DLIST" diff --git a/libsrc/atari5200/cputc.s b/libsrc/atari5200/cputc.s index 185ad8da8..8fc00fcdc 100644 --- a/libsrc/atari5200/cputc.s +++ b/libsrc/atari5200/cputc.s @@ -11,8 +11,9 @@ .export _cputcxy, _cputc .export plot, cputdirect, putchar .import gotoxy, _mul20 + .import conio_color + .importzp screen_width, screen_height .importzp ptr4 - .import setcursor .constructor screen_setup, 26 .import screen_setup_20x24 @@ -44,7 +45,7 @@ L4: cmp #$0A ; LF and #3 tax tya - and #$9f + and #$9F ora ataint,x cputdirect: ; accepts screen code @@ -53,7 +54,7 @@ cputdirect: ; accepts screen code ; advance cursor inc COLCRS_5200 lda COLCRS_5200 - cmp #20 + cmp #screen_width bcc plot lda #0 sta COLCRS_5200 @@ -62,12 +63,11 @@ cputdirect: ; accepts screen code newline: inc ROWCRS_5200 lda ROWCRS_5200 - cmp #24 + cmp #screen_height bne plot lda #0 sta ROWCRS_5200 -plot: jsr setcursor - ldy COLCRS_5200 +plot: ldy COLCRS_5200 ldx ROWCRS_5200 rts @@ -83,10 +83,12 @@ putchar: sta ptr4+1 pla ; get char again +; and #$C0 ; without this we are compatible with the old version. user must not try to output a char >= $3F + ora conio_color + ldy COLCRS_5200 sta (ptr4),y - jmp setcursor + rts .rodata ataint: .byte 64,0,32,96 - diff --git a/libsrc/atari5200/cvline.s b/libsrc/atari5200/cvline.s index d987bcb62..204d90382 100644 --- a/libsrc/atari5200/cvline.s +++ b/libsrc/atari5200/cvline.s @@ -1 +1,31 @@ -.include "../atari/cvline.s" +; +; Ullrich von Bassewitz, 08.08.1998 +; +; void cvlinexy (unsigned char x, unsigned char y, unsigned char length); +; void cvline (unsigned char length); +; + .include "atari5200.inc" + + .export _cvlinexy, _cvline + .import gotoxy, putchar + .importzp tmp1 + +_cvlinexy: + pha ; Save the length + jsr gotoxy ; Call this one, will pop params + pla ; Restore the length and run into _cvline + +_cvline: + cmp #0 ; Is the length zero? + beq L9 ; Jump if done + sta tmp1 +L1: lda COLCRS_5200 + pha + lda #CH_VLINE ; Vertical bar + jsr putchar ; Write, no cursor advance + pla + sta COLCRS_5200 + inc ROWCRS_5200 + dec tmp1 + bne L1 +L9: rts diff --git a/libsrc/atari5200/gotox.s b/libsrc/atari5200/gotox.s index 99f7cfd22..04fc46223 100644 --- a/libsrc/atari5200/gotox.s +++ b/libsrc/atari5200/gotox.s @@ -6,8 +6,7 @@ .include "atari5200.inc" .export _gotox - .import setcursor _gotox: sta COLCRS_5200 ; Set X - jmp setcursor + rts diff --git a/libsrc/atari5200/gotoxy.s b/libsrc/atari5200/gotoxy.s index 24e2c2e35..dce5b6c2a 100644 --- a/libsrc/atari5200/gotoxy.s +++ b/libsrc/atari5200/gotoxy.s @@ -8,7 +8,6 @@ .export gotoxy, _gotoxy .import popa - .import setcursor gotoxy: jsr popa ; Get Y @@ -17,4 +16,4 @@ _gotoxy: ; Set the cursor position sta ROWCRS_5200 ; Set Y jsr popa ; Get X sta COLCRS_5200 ; Set X - jmp setcursor + rts diff --git a/libsrc/atari5200/gotoy.s b/libsrc/atari5200/gotoy.s index fcdd05e4c..ef7c2e565 100644 --- a/libsrc/atari5200/gotoy.s +++ b/libsrc/atari5200/gotoy.s @@ -6,8 +6,7 @@ .include "atari5200.inc" .export _gotoy - .import setcursor _gotoy: sta ROWCRS_5200 ; Set Y - jmp setcursor + rts diff --git a/libsrc/atari5200/textcolor.s b/libsrc/atari5200/textcolor.s new file mode 100644 index 000000000..061e84088 --- /dev/null +++ b/libsrc/atari5200/textcolor.s @@ -0,0 +1,28 @@ +; +; Christian Groessler, 02-Apr-2019 +; +; unsigned char __fastcall__ textcolor (unsigned char color); + + .export _textcolor + .import conio_color + + .include "atari.inc" + + +_textcolor: + ; move bits #0 and #1 to bits #6 and #7 + and #3 + clc + ror a + ror a + ror a ; new conio_color value + ldx conio_color ; get old value + sta conio_color ; store new value + txa + ; move bits #6 and #7 to bits #0 and #1 + clc + rol a + rol a + rol a + ldx #0 + rts diff --git a/libsrc/atari5200/wherex.s b/libsrc/atari5200/wherex.s new file mode 100644 index 000000000..77f099d88 --- /dev/null +++ b/libsrc/atari5200/wherex.s @@ -0,0 +1,13 @@ +; +; Carsten Strotmann, 30.12.2002 +; +; unsigned char wherex (void); +; + + .export _wherex + .include "atari5200.inc" + +_wherex: + lda COLCRS_5200 + ldx #0 + rts diff --git a/libsrc/atari5200/wherey.s b/libsrc/atari5200/wherey.s new file mode 100644 index 000000000..d2c50427c --- /dev/null +++ b/libsrc/atari5200/wherey.s @@ -0,0 +1,13 @@ +; +; Carsten Strotmann, 30.12.2002 +; +; unsigned char wherey (void); +; + + .export _wherey + .include "atari5200.inc" + +_wherey: + lda ROWCRS_5200 + ldx #0 + rts diff --git a/samples/hello.c b/samples/hello.c index dd15128d2..255dccd00 100644 --- a/samples/hello.c +++ b/samples/hello.c @@ -67,7 +67,7 @@ int main (void) gotoxy ((XSize - strlen (Text)) / 2, YSize / 2); cprintf ("%s", Text); -#if defined(__NES__) || defined(__PCE__) || defined(__GAMATE__) +#if defined(__NES__) || defined(__PCE__) || defined(__GAMATE__) || defined(__ATARI5200__) /* Wait for the user to press a button */ joy_install (joy_static_stddrv); diff --git a/testcode/lib/atari5200/hello.c b/testcode/lib/atari5200/hello.c new file mode 100644 index 000000000..b2088461b --- /dev/null +++ b/testcode/lib/atari5200/hello.c @@ -0,0 +1,101 @@ +/* +** Fancy hello world program using cc65. +** +** Ullrich von Bassewitz (ullrich@von-bassewitz.de) +** +** TEST version for atari5200 conio, using all four colors +*/ + + + +#include <stdlib.h> +#include <string.h> +#include <conio.h> +#include <joystick.h> + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +static const char Text [] = "Hello world!"; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +int main (void) +{ + unsigned char XSize, YSize; + unsigned char PosY; + + /* Set screen colors */ + (void) textcolor (COLOR_WHITE); + (void) bordercolor (COLOR_BLACK); + (void) bgcolor (COLOR_BLACK); + + /* Clear the screen, put cursor in upper left corner */ + clrscr (); + + /* Ask for the screen size */ + screensize (&XSize, &YSize); + + /* Draw a border around the screen */ + + /* Top line */ + cputc (CH_ULCORNER); + chline (XSize - 2); + cputc (CH_URCORNER); + + /* Vertical line, left side */ + cvlinexy (0, 1, YSize - 2); + + /* Bottom line */ + cputc (CH_LLCORNER); + chline (XSize - 2); + cputc (CH_LRCORNER); + + /* Vertical line, right side */ + cvlinexy (XSize - 1, 1, YSize - 2); + + /* Write the greeting in the mid of the screen */ + gotoxy ((XSize - strlen (Text)) / 2, YSize / 2); + cprintf ("%s", Text); + + PosY = wherey () + 1; + textcolor (0); /* switch to color #0 */ + cputsxy(3, PosY++, "COLOR 0"); + textcolor (1); /* switch to color #1 */ + cputsxy(3, PosY++, "COLOR 1"); + textcolor (2); /* switch to color #2 */ + cputsxy(3, PosY++, "COLOR 2"); + textcolor (3); /* switch to color #3 */ + cputsxy(3, PosY, "COLOR 3"); + +#if defined(__NES__) || defined(__PCE__) || defined(__GAMATE__) || defined(__ATARI5200__) + + /* Wait for the user to press a button */ + joy_install (joy_static_stddrv); + while (!joy_read (JOY_1)) ; + joy_uninstall (); + +#else + + /* Wait for the user to press a key */ + cgetc (); + +#endif + + /* Clear the screen again */ + clrscr (); + + /* Done */ + return EXIT_SUCCESS; +} From db01036e2e244405e371d53253ace00424749fe1 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 2 Apr 2019 21:31:12 +0200 Subject: [PATCH 1051/2161] atari5200: add alternative conio screen (20x12 resolution) --- libsrc/atari5200/conioscreen.s | 4 +- libsrc/atari5200/cputc.s | 7 +- libsrc/atari5200/extra/conioscreen_20x12.s | 92 ++++++++++++++++++++++ 3 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 libsrc/atari5200/extra/conioscreen_20x12.s diff --git a/libsrc/atari5200/conioscreen.s b/libsrc/atari5200/conioscreen.s index 2c6a8a4e4..a16557d2a 100644 --- a/libsrc/atari5200/conioscreen.s +++ b/libsrc/atari5200/conioscreen.s @@ -7,7 +7,7 @@ SCREEN_BUF_SIZE = 20 * 24 SCREEN_BUF = $4000 - SCREEN_BUF_SIZE - .export screen_setup_20x24 + .export screen_setup .export screen_width, screen_height .export conio_color @@ -17,7 +17,7 @@ screen_height = 24 .segment "ONCE" -screen_setup_20x24: +screen_setup: ; initialize SAVMSC lda #<SCREEN_BUF diff --git a/libsrc/atari5200/cputc.s b/libsrc/atari5200/cputc.s index 8fc00fcdc..b230df68c 100644 --- a/libsrc/atari5200/cputc.s +++ b/libsrc/atari5200/cputc.s @@ -15,10 +15,9 @@ .importzp screen_width, screen_height .importzp ptr4 - .constructor screen_setup, 26 - .import screen_setup_20x24 -screen_setup = screen_setup_20x24 - + .import screen_setup + .constructor screen_setup_constructor, 26 +screen_setup_constructor = screen_setup _cputcxy: pha ; Save C diff --git a/libsrc/atari5200/extra/conioscreen_20x12.s b/libsrc/atari5200/extra/conioscreen_20x12.s new file mode 100644 index 000000000..12043c74c --- /dev/null +++ b/libsrc/atari5200/extra/conioscreen_20x12.s @@ -0,0 +1,92 @@ +; setup alternative CONIO screen (20x12, Antic mode 7, BASIC mode 2) +; +; 02-Apr-2019, Christian Groessler <chris@groessler.org> + + .include "atari5200.inc" + +SCREEN_BUF_SIZE = 20 * 12 +SCREEN_BUF = $4000 - SCREEN_BUF_SIZE + + .export screen_setup + .export screen_width, screen_height + .export conio_color + +screen_width = 20 +screen_height = 12 + + + .segment "ONCE" + +screen_setup: + + ; initialize SAVMSC + lda #<SCREEN_BUF + sta SAVMSC + 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 + + ; set default colors + + lda #40 + sta COLOR0 + lda #202 + sta COLOR1 + lda #148 + sta COLOR2 + lda #70 + sta COLOR3 + lda #0 + sta COLOR4 + + ; set display list + + lda #<dlist + sta SDLSTL + lda #>dlist + sta SDLSTH + + rts + + .data + +conio_color: .byte 0 + + .segment "DLIST" + +; display list for 20x12 text mode + +dlist: .repeat 3 + .byte DL_BLK8 + .endrepeat + + .byte DL_CHR20x16x2 | DL_LMS + .word SCREEN_BUF + + .repeat 11 + .byte DL_CHR20x16x2 + .endrepeat + + .byte DL_JVB + .word dlist + +; end of display list + +.assert ((* >> 10) = (dlist >> 10)), error, "Display list crosses 1K boundary" + + .end From 79b9a8d2dfa6d13af7f2de963cc591fec786a6b0 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 2 Apr 2019 22:06:53 +0200 Subject: [PATCH 1052/2161] atari5200: add screensize function --- libsrc/atari5200/_scrsize.s | 19 +++++++++++++++++++ libsrc/atari5200/textcolor.s | 2 -- 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 libsrc/atari5200/_scrsize.s diff --git a/libsrc/atari5200/_scrsize.s b/libsrc/atari5200/_scrsize.s new file mode 100644 index 000000000..025b1b3ff --- /dev/null +++ b/libsrc/atari5200/_scrsize.s @@ -0,0 +1,19 @@ +; +; Christian Groessler, 02-Apr-2019 +; +; Screen size variables +; + + .export screensize + .importzp screen_width, screen_height + .include "atari.inc" + +.proc screensize + + ldx #screen_width + ldy #screen_height + rts + +.endproc + + diff --git a/libsrc/atari5200/textcolor.s b/libsrc/atari5200/textcolor.s index 061e84088..598945134 100644 --- a/libsrc/atari5200/textcolor.s +++ b/libsrc/atari5200/textcolor.s @@ -6,8 +6,6 @@ .export _textcolor .import conio_color - .include "atari.inc" - _textcolor: ; move bits #0 and #1 to bits #6 and #7 From be6bba66a927e419860d2115e2d38de4e1c09d96 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Fri, 5 Apr 2019 01:26:34 +0200 Subject: [PATCH 1053/2161] atari5200: conio now uses just four colors altogether See discussion in PR #870. --- asminc/atari5200.inc | 8 ++++ asminc/atari_gtia.inc | 38 +++++++++++++++ include/_gtia.h | 55 +++++++--------------- include/atari.h | 45 ++++++++++++++++++ include/atari5200.h | 6 +++ libsrc/atari5200/bgcolor.s | 38 ++++++++++++++- libsrc/atari5200/conioscreen.s | 12 ++--- libsrc/atari5200/cputc.s | 4 +- libsrc/atari5200/extra/conioscreen_20x12.s | 12 ++--- libsrc/atari5200/textcolor.s | 2 + testcode/lib/atari5200/hello.c | 12 ++--- 11 files changed, 173 insertions(+), 59 deletions(-) diff --git a/asminc/atari5200.inc b/asminc/atari5200.inc index a1fe624e6..a17268de2 100644 --- a/asminc/atari5200.inc +++ b/asminc/atari5200.inc @@ -111,6 +111,14 @@ ANTIC = $D400 ; ANTIC area POKEY = $E800 ; POKEY area .include "atari_pokey.inc" +;------------------------------------------------------------------------- +; conio color defines +;------------------------------------------------------------------------- + +COLOR_WHITE = 0 +COLOR_RED = 1 +COLOR_GREEN = 2 +COLOR_BLACK = 3 ;------------------------------------------------------------------------- ; Cartridge Parameters diff --git a/asminc/atari_gtia.inc b/asminc/atari_gtia.inc index f50583271..dd1c877d5 100644 --- a/asminc/atari_gtia.inc +++ b/asminc/atari_gtia.inc @@ -79,3 +79,41 @@ VDELAY = GTIA + $1C ;vertical delay GRACTL = GTIA + $1D ;graphic control HITCLR = GTIA + $1E ;collision clear + +; Hue values + +HUE_GREY = 0 +HUE_GOLD = 1 +HUE_GOLDORANGE = 2 +HUE_REDORANGE = 3 +HUE_ORANGE = 4 +HUE_MAGENTA = 5 +HUE_PURPLE = 6 +HUE_BLUE = 7 +HUE_BLUE2 = 8 +HUE_CYAN = 9 +HUE_BLUEGREEN = 10 +HUE_BLUEGREEN2 = 11 +HUE_GREEN = 12 +HUE_YELLOWGREEN = 13 +HUE_YELLOW = 14 +HUE_YELLOWRED = 15 + +; Color defines, similar to c64 colors (untested) + +GTIA_COLOR_BLACK = (HUE_GREY << 4) +GTIA_COLOR_WHITE = (HUE_GREY << 4 | 7 << 1) +GTIA_COLOR_RED = (HUE_REDORANGE << 4 | 1 << 1) +GTIA_COLOR_CYAN = (HUE_CYAN << 4 | 3 << 1) +GTIA_COLOR_VIOLET = (HUE_PURPLE << 4 | 4 << 1) +GTIA_COLOR_GREEN = (HUE_GREEN << 4 | 2 << 1) +GTIA_COLOR_BLUE = (HUE_BLUE << 4 | 2 << 1) +GTIA_COLOR_YELLOW = (HUE_YELLOW << 4 | 7 << 1) +GTIA_COLOR_ORANGE = (HUE_ORANGE << 4 | 5 << 1) +GTIA_COLOR_BROWN = (HUE_YELLOW << 4 | 2 << 1) +GTIA_COLOR_LIGHTRED = (HUE_REDORANGE << 4 | 6 << 1) +GTIA_COLOR_GRAY1 = (HUE_GREY << 4 | 2 << 1) +GTIA_COLOR_GRAY2 = (HUE_GREY << 4 | 3 << 1) +GTIA_COLOR_LIGHTGREEN = (HUE_GREEN << 4 | 6 << 1) +GTIA_COLOR_LIGHTBLUE = (HUE_BLUE << 4 | 6 << 1) +GTIA_COLOR_GRAY3 = (HUE_GREY << 4 | 5 << 1) diff --git a/include/_gtia.h b/include/_gtia.h index ae3e69445..cbdf7608e 100644 --- a/include/_gtia.h +++ b/include/_gtia.h @@ -131,44 +131,23 @@ struct __gtia_write { #define HUE_YELLOWRED 15 /* Color defines, similar to c64 colors (untested) */ -/* Note that the conio color implementation is monochrome -** (bgcolor and textcolor are only placeholders) -*/ -/* Use the defines with the setcolor() or _atari_xxxcolor() functions */ -#define COLOR_BLACK _gtia_mkcolor(HUE_GREY,0) -#define COLOR_WHITE _gtia_mkcolor(HUE_GREY,7) -#define COLOR_RED _gtia_mkcolor(HUE_REDORANGE,1) -#define COLOR_CYAN _gtia_mkcolor(HUE_CYAN,3) -#define COLOR_VIOLET _gtia_mkcolor(HUE_PURPLE,4) -#define COLOR_GREEN _gtia_mkcolor(HUE_GREEN,2) -#define COLOR_BLUE _gtia_mkcolor(HUE_BLUE,2) -#define COLOR_YELLOW _gtia_mkcolor(HUE_YELLOW,7) -#define COLOR_ORANGE _gtia_mkcolor(HUE_ORANGE,5) -#define COLOR_BROWN _gtia_mkcolor(HUE_YELLOW,2) -#define COLOR_LIGHTRED _gtia_mkcolor(HUE_REDORANGE,6) -#define COLOR_GRAY1 _gtia_mkcolor(HUE_GREY,2) -#define COLOR_GRAY2 _gtia_mkcolor(HUE_GREY,3) -#define COLOR_LIGHTGREEN _gtia_mkcolor(HUE_GREEN,6) -#define COLOR_LIGHTBLUE _gtia_mkcolor(HUE_BLUE,6) -#define COLOR_GRAY3 _gtia_mkcolor(HUE_GREY,5) - -/* 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_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 +/* Hardware palette values (for GTIA colxxx registers) */ +#define GTIA_COLOR_BLACK _gtia_mkcolor(HUE_GREY,0) +#define GTIA_COLOR_WHITE _gtia_mkcolor(HUE_GREY,7) +#define GTIA_COLOR_RED _gtia_mkcolor(HUE_REDORANGE,1) +#define GTIA_COLOR_CYAN _gtia_mkcolor(HUE_CYAN,3) +#define GTIA_COLOR_VIOLET _gtia_mkcolor(HUE_PURPLE,4) +#define GTIA_COLOR_GREEN _gtia_mkcolor(HUE_GREEN,2) +#define GTIA_COLOR_BLUE _gtia_mkcolor(HUE_BLUE,2) +#define GTIA_COLOR_YELLOW _gtia_mkcolor(HUE_YELLOW,7) +#define GTIA_COLOR_ORANGE _gtia_mkcolor(HUE_ORANGE,5) +#define GTIA_COLOR_BROWN _gtia_mkcolor(HUE_YELLOW,2) +#define GTIA_COLOR_LIGHTRED _gtia_mkcolor(HUE_REDORANGE,6) +#define GTIA_COLOR_GRAY1 _gtia_mkcolor(HUE_GREY,2) +#define GTIA_COLOR_GRAY2 _gtia_mkcolor(HUE_GREY,3) +#define GTIA_COLOR_LIGHTGREEN _gtia_mkcolor(HUE_GREEN,6) +#define GTIA_COLOR_LIGHTBLUE _gtia_mkcolor(HUE_BLUE,6) +#define GTIA_COLOR_GRAY3 _gtia_mkcolor(HUE_GREY,5) /*****************************************************************************/ diff --git a/include/atari.h b/include/atari.h index 455c43260..4fc027d20 100644 --- a/include/atari.h +++ b/include/atari.h @@ -377,6 +377,51 @@ extern void atrx15p2_tgi[]; #define ANTIC (*(struct __antic*)0xD400) +/*****************************************************************************/ +/* conio and TGI color defines */ +/*****************************************************************************/ + +/* Note that the conio color implementation is monochrome +** (textcolor just sets text brightness low or high, depending on background +** color) +** These values can be used with bordercolor(), bgcolor(), and _setcolor_low() +*/ +#define COLOR_BLACK GTIA_COLOR_BLACK +#define COLOR_WHITE GTIA_COLOR_WHITE +#define COLOR_RED GTIA_COLOR_RED +#define COLOR_CYAN GTIA_COLOR_CYAN +#define COLOR_VIOLET GTIA_COLOR_VIOLET +#define COLOR_GREEN GTIA_COLOR_GREEN +#define COLOR_BLUE GTIA_COLOR_BLUE +#define COLOR_YELLOW GTIA_COLOR_YELLOW +#define COLOR_ORANGE GTIA_COLOR_ORANGE +#define COLOR_BROWN GTIA_COLOR_BROWN +#define COLOR_LIGHTRED GTIA_COLOR_LIGHTRED +#define COLOR_GRAY1 GTIA_COLOR_GRAY1 +#define COLOR_GRAY2 GTIA_COLOR_GRAY2 +#define COLOR_LIGHTGREEN GTIA_COLOR_LIGHTGREEN +#define COLOR_LIGHTBLUE GTIA_COLOR_LIGHTBLUE +#define COLOR_GRAY3 GTIA_COLOR_GRAY3 + +/* 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_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 + + /*****************************************************************************/ /* PIA PORTA and PORTB register bits */ /*****************************************************************************/ diff --git a/include/atari5200.h b/include/atari5200.h index 10cd32fe9..d6c2561b2 100644 --- a/include/atari5200.h +++ b/include/atari5200.h @@ -77,6 +77,12 @@ extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */ #include <_antic.h> #define ANTIC (*(struct __antic*)0xD400) +/* conio color defines */ +#define COLOR_WHITE 0x00 +#define COLOR_RED 0x01 +#define COLOR_GREEN 0x02 +#define COLOR_BLACK 0x03 + /* The following #define will cause the matching function calls in conio.h ** to be overlaid by macros with the same names, saving the function call ** overhead. diff --git a/libsrc/atari5200/bgcolor.s b/libsrc/atari5200/bgcolor.s index 1f9f77260..bf10dff2c 100644 --- a/libsrc/atari5200/bgcolor.s +++ b/libsrc/atari5200/bgcolor.s @@ -1 +1,37 @@ -.include "../atari/bgcolor.s" +; +; Christian Groessler, 05-Apr-2019 +; + + .import conio_colors + .export _bgcolor + + .include "atari5200.inc" + + .constructor init_old_bgcolor + +.bss + +old_bg_color: + .res 1 + +.code + +_bgcolor: + and #3 + tax + lda conio_colors,x + ldx old_bg_color + sta COLOR4 ; set new value + sta old_bg_color + txa + ldx #0 ; fix X + rts + +.segment "ONCE" + +init_old_bgcolor: + lda conio_colors+3 ; see also conioscreen.s for initialization + sta old_bg_color + rts + + .end diff --git a/libsrc/atari5200/conioscreen.s b/libsrc/atari5200/conioscreen.s index a16557d2a..d1a709fc3 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 conio_colors .export screen_setup .export screen_width, screen_height .export conio_color @@ -43,16 +44,15 @@ clrscr: sta (SAVMSC),y ; set default colors - lda #40 + lda conio_colors sta COLOR0 - lda #202 + lda conio_colors+1 sta COLOR1 - lda #148 + lda conio_colors+2 sta COLOR2 - lda #70 + lda conio_colors+3 sta COLOR3 - lda #0 - sta COLOR4 + sta COLOR4 ; background ; set display list diff --git a/libsrc/atari5200/cputc.s b/libsrc/atari5200/cputc.s index b230df68c..6de397182 100644 --- a/libsrc/atari5200/cputc.s +++ b/libsrc/atari5200/cputc.s @@ -82,8 +82,8 @@ putchar: sta ptr4+1 pla ; get char again -; and #$C0 ; without this we are compatible with the old version. user must not try to output a char >= $3F - ora conio_color + and #$3F ; clear palette index bits + ora conio_color ; use currently selected palette ldy COLCRS_5200 sta (ptr4),y diff --git a/libsrc/atari5200/extra/conioscreen_20x12.s b/libsrc/atari5200/extra/conioscreen_20x12.s index 12043c74c..20ab7ea2b 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 conio_colors .export screen_setup .export screen_width, screen_height .export conio_color @@ -43,16 +44,15 @@ clrscr: sta (SAVMSC),y ; set default colors - lda #40 + lda conio_colors sta COLOR0 - lda #202 + lda conio_colors+1 sta COLOR1 - lda #148 + lda conio_colors+2 sta COLOR2 - lda #70 + lda conio_colors+3 sta COLOR3 - lda #0 - sta COLOR4 + sta COLOR4 ; background ; set display list diff --git a/libsrc/atari5200/textcolor.s b/libsrc/atari5200/textcolor.s index 598945134..511e23de3 100644 --- a/libsrc/atari5200/textcolor.s +++ b/libsrc/atari5200/textcolor.s @@ -2,6 +2,8 @@ ; Christian Groessler, 02-Apr-2019 ; ; unsigned char __fastcall__ textcolor (unsigned char color); +; +; "color" value is a palette index (0..3) or COLOR_xxx value (0..3) .export _textcolor .import conio_color diff --git a/testcode/lib/atari5200/hello.c b/testcode/lib/atari5200/hello.c index b2088461b..18daf0bdf 100644 --- a/testcode/lib/atari5200/hello.c +++ b/testcode/lib/atari5200/hello.c @@ -69,15 +69,15 @@ int main (void) gotoxy ((XSize - strlen (Text)) / 2, YSize / 2); cprintf ("%s", Text); - PosY = wherey () + 1; + PosY = wherey (); textcolor (0); /* switch to color #0 */ - cputsxy(3, PosY++, "COLOR 0"); + cputsxy(3, ++PosY, "COLOR 0"); textcolor (1); /* switch to color #1 */ - cputsxy(3, PosY++, "COLOR 1"); + cputsxy(3, ++PosY, "COLOR 1"); textcolor (2); /* switch to color #2 */ - cputsxy(3, PosY++, "COLOR 2"); - textcolor (3); /* switch to color #3 */ - cputsxy(3, PosY, "COLOR 3"); + cputsxy(3, ++PosY, "COLOR 2"); + textcolor (3); /* switch to color #3 */ /* color #3 is the background color. So written text isn't visible. */ + cputsxy(3, ++PosY, "COLOR 3"); #if defined(__NES__) || defined(__PCE__) || defined(__GAMATE__) || defined(__ATARI5200__) From dfb7c0f24d7df8b6de735d730ba0465fc5d7c775 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Mon, 8 Apr 2019 22:03:15 +0200 Subject: [PATCH 1054/2161] atari5200: fix COLOR defines' names COLOR_RED -> COLOR_LIGHTRED and COLOR_GREEN -> COLOR_LIGHTGREEN --- asminc/atari5200.inc | 8 ++++---- include/atari5200.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/asminc/atari5200.inc b/asminc/atari5200.inc index a17268de2..a09b44257 100644 --- a/asminc/atari5200.inc +++ b/asminc/atari5200.inc @@ -115,10 +115,10 @@ POKEY = $E800 ; POKEY area ; conio color defines ;------------------------------------------------------------------------- -COLOR_WHITE = 0 -COLOR_RED = 1 -COLOR_GREEN = 2 -COLOR_BLACK = 3 +COLOR_WHITE = 0 +COLOR_LIGHTRED = 1 +COLOR_LIGHTGREEN = 2 +COLOR_BLACK = 3 ;------------------------------------------------------------------------- ; Cartridge Parameters diff --git a/include/atari5200.h b/include/atari5200.h index d6c2561b2..e014c8ac4 100644 --- a/include/atari5200.h +++ b/include/atari5200.h @@ -78,10 +78,10 @@ extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */ #define ANTIC (*(struct __antic*)0xD400) /* conio color defines */ -#define COLOR_WHITE 0x00 -#define COLOR_RED 0x01 -#define COLOR_GREEN 0x02 -#define COLOR_BLACK 0x03 +#define COLOR_WHITE 0x00 +#define COLOR_LIGHTRED 0x01 +#define COLOR_LIGHTGREEN 0x02 +#define COLOR_BLACK 0x03 /* The following #define will cause the matching function calls in conio.h ** to be overlaid by macros with the same names, saving the function call From d7eecb57f8d2c9fadb41a3a55cb1ea5ebb7f1c34 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 9 Apr 2019 14:34:28 +0200 Subject: [PATCH 1055/2161] atari5200: get rid of conio_colors table use system color variables instead; improve testcode/lib/atari5200/hello.c test program --- libsrc/atari5200/bgcolor.s | 5 +- libsrc/atari5200/conioscreen.s | 9 +- libsrc/atari5200/extra/conioscreen_20x12.s | 9 +- testcode/lib/atari5200/hello.c | 100 +++++++++++---------- 4 files changed, 64 insertions(+), 59 deletions(-) diff --git a/libsrc/atari5200/bgcolor.s b/libsrc/atari5200/bgcolor.s index bf10dff2c..127d26998 100644 --- a/libsrc/atari5200/bgcolor.s +++ b/libsrc/atari5200/bgcolor.s @@ -2,7 +2,6 @@ ; Christian Groessler, 05-Apr-2019 ; - .import conio_colors .export _bgcolor .include "atari5200.inc" @@ -19,7 +18,7 @@ old_bg_color: _bgcolor: and #3 tax - lda conio_colors,x + lda COLOR0,x ldx old_bg_color sta COLOR4 ; set new value sta old_bg_color @@ -30,7 +29,7 @@ _bgcolor: .segment "ONCE" init_old_bgcolor: - lda conio_colors+3 ; see also conioscreen.s for initialization + lda COLOR0+3 ; see also conioscreen.s for initialization sta old_bg_color rts diff --git a/libsrc/atari5200/conioscreen.s b/libsrc/atari5200/conioscreen.s index d1a709fc3..895e946ef 100644 --- a/libsrc/atari5200/conioscreen.s +++ b/libsrc/atari5200/conioscreen.s @@ -7,7 +7,6 @@ SCREEN_BUF_SIZE = 20 * 24 SCREEN_BUF = $4000 - SCREEN_BUF_SIZE - .import conio_colors .export screen_setup .export screen_width, screen_height .export conio_color @@ -44,13 +43,13 @@ clrscr: sta (SAVMSC),y ; set default colors - lda conio_colors + lda #GTIA_COLOR_WHITE sta COLOR0 - lda conio_colors+1 + lda #GTIA_COLOR_LIGHTRED sta COLOR1 - lda conio_colors+2 + lda #GTIA_COLOR_LIGHTGREEN sta COLOR2 - lda conio_colors+3 + lda #GTIA_COLOR_BLACK sta COLOR3 sta COLOR4 ; background diff --git a/libsrc/atari5200/extra/conioscreen_20x12.s b/libsrc/atari5200/extra/conioscreen_20x12.s index 20ab7ea2b..9cde9826d 100644 --- a/libsrc/atari5200/extra/conioscreen_20x12.s +++ b/libsrc/atari5200/extra/conioscreen_20x12.s @@ -7,7 +7,6 @@ SCREEN_BUF_SIZE = 20 * 12 SCREEN_BUF = $4000 - SCREEN_BUF_SIZE - .import conio_colors .export screen_setup .export screen_width, screen_height .export conio_color @@ -44,13 +43,13 @@ clrscr: sta (SAVMSC),y ; set default colors - lda conio_colors + lda #GTIA_COLOR_WHITE sta COLOR0 - lda conio_colors+1 + lda #GTIA_COLOR_LIGHTRED sta COLOR1 - lda conio_colors+2 + lda #GTIA_COLOR_LIGHTGREEN sta COLOR2 - lda conio_colors+3 + lda #GTIA_COLOR_BLACK sta COLOR3 sta COLOR4 ; background diff --git a/testcode/lib/atari5200/hello.c b/testcode/lib/atari5200/hello.c index 18daf0bdf..830d03a91 100644 --- a/testcode/lib/atari5200/hello.c +++ b/testcode/lib/atari5200/hello.c @@ -22,6 +22,7 @@ static const char Text [] = "Hello world!"; +static unsigned char colors[] = { COLOR_WHITE, COLOR_LIGHTGREEN, COLOR_LIGHTRED, COLOR_BLACK }; @@ -35,6 +36,7 @@ int main (void) { unsigned char XSize, YSize; unsigned char PosY; + unsigned char i = 0; /* Set screen colors */ (void) textcolor (COLOR_WHITE); @@ -47,55 +49,61 @@ int main (void) /* Ask for the screen size */ screensize (&XSize, &YSize); - /* Draw a border around the screen */ - - /* Top line */ - cputc (CH_ULCORNER); - chline (XSize - 2); - cputc (CH_URCORNER); - - /* Vertical line, left side */ - cvlinexy (0, 1, YSize - 2); - - /* Bottom line */ - cputc (CH_LLCORNER); - chline (XSize - 2); - cputc (CH_LRCORNER); - - /* Vertical line, right side */ - cvlinexy (XSize - 1, 1, YSize - 2); - - /* Write the greeting in the mid of the screen */ - gotoxy ((XSize - strlen (Text)) / 2, YSize / 2); - cprintf ("%s", Text); - - PosY = wherey (); - textcolor (0); /* switch to color #0 */ - cputsxy(3, ++PosY, "COLOR 0"); - textcolor (1); /* switch to color #1 */ - cputsxy(3, ++PosY, "COLOR 1"); - textcolor (2); /* switch to color #2 */ - cputsxy(3, ++PosY, "COLOR 2"); - textcolor (3); /* switch to color #3 */ /* color #3 is the background color. So written text isn't visible. */ - cputsxy(3, ++PosY, "COLOR 3"); - -#if defined(__NES__) || defined(__PCE__) || defined(__GAMATE__) || defined(__ATARI5200__) - - /* Wait for the user to press a button */ + /* Install joystick driver */ joy_install (joy_static_stddrv); - while (!joy_read (JOY_1)) ; + + while (1) { + /* Draw a border around the screen */ + + /* Top line */ + cputc (CH_ULCORNER); + chline (XSize - 2); + cputc (CH_URCORNER); + + /* Vertical line, left side */ + cvlinexy (0, 1, YSize - 2); + + /* Bottom line */ + cputc (CH_LLCORNER); + chline (XSize - 2); + cputc (CH_LRCORNER); + + /* Vertical line, right side */ + cvlinexy (XSize - 1, 1, YSize - 2); + + /* Write the greeting in the mid of the screen */ + gotoxy ((XSize - strlen (Text)) / 2, YSize / 2); + cprintf ("%s", Text); + + PosY = wherey (); + textcolor (colors[i]); /* switch to color #0 */ + cputsxy(3, ++PosY, "COLOR 0"); + textcolor ((colors[i] + 1) & 3); /* switch to color #1 */ + cputsxy(3, ++PosY, "COLOR 1"); + textcolor ((colors[i] + 2) & 3); /* switch to color #2 */ + cputsxy(3, ++PosY, "COLOR 2"); + textcolor ((colors[i] + 3) & 3); /* switch to color #3 */ /* color #3 is the background color. So written text isn't visible. */ + cputsxy(3, ++PosY, "COLOR 3"); + + /* Wait for the user to press and release a button */ + while (!joy_read (JOY_1)) + ; + while (joy_read (JOY_1)) + ; + + i = (i + 1) & 3; + + /* Change colors */ + textcolor (colors[i]); + bgcolor ((colors[i] + 3) & 3); + + /* Clear the screen again */ + clrscr (); + } + /* not reached */ + joy_uninstall (); -#else - - /* Wait for the user to press a key */ - cgetc (); - -#endif - - /* Clear the screen again */ - clrscr (); - /* Done */ return EXIT_SUCCESS; } From e1e6bec9ff3d993efb6986990b11ec1751d97372 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 10 Apr 2019 22:15:27 +0200 Subject: [PATCH 1056/2161] atari5200: changes from discussions in #870 - rename screen_setup to initconio - use Greg King's version of bgcolor() --- libsrc/atari5200/bgcolor.s | 32 ++++++++-------------- libsrc/atari5200/conioscreen.s | 9 +++--- libsrc/atari5200/cputc.s | 6 ++-- libsrc/atari5200/extra/conioscreen_20x12.s | 9 +++--- 4 files changed, 24 insertions(+), 32 deletions(-) diff --git a/libsrc/atari5200/bgcolor.s b/libsrc/atari5200/bgcolor.s index 127d26998..90db8892b 100644 --- a/libsrc/atari5200/bgcolor.s +++ b/libsrc/atari5200/bgcolor.s @@ -1,36 +1,26 @@ ; -; Christian Groessler, 05-Apr-2019 +; Greg King, 10-Apr-2019 ; .export _bgcolor .include "atari5200.inc" - .constructor init_old_bgcolor +.data -.bss - -old_bg_color: - .res 1 +old_bg_index: + .byte COLOR_BLACK ; see conioscreen.s for default palette .code _bgcolor: - and #3 + and #$03 tax - lda COLOR0,x - ldx old_bg_color - sta COLOR4 ; set new value - sta old_bg_color - txa - ldx #0 ; fix X + ldy COLOR0,x + lda old_bg_index + sty COLOR4 ; set new value + stx old_bg_index + ldx #0 ; fix high byte rts -.segment "ONCE" - -init_old_bgcolor: - lda COLOR0+3 ; see also conioscreen.s for initialization - sta old_bg_color - rts - - .end +.end diff --git a/libsrc/atari5200/conioscreen.s b/libsrc/atari5200/conioscreen.s index 895e946ef..4e769b126 100644 --- a/libsrc/atari5200/conioscreen.s +++ b/libsrc/atari5200/conioscreen.s @@ -7,7 +7,7 @@ SCREEN_BUF_SIZE = 20 * 24 SCREEN_BUF = $4000 - SCREEN_BUF_SIZE - .export screen_setup + .export initconio .export screen_width, screen_height .export conio_color @@ -17,7 +17,8 @@ screen_height = 24 .segment "ONCE" -screen_setup: +; initialize color registers, display list, and screen memory +initconio: ; initialize SAVMSC lda #<SCREEN_BUF @@ -62,9 +63,9 @@ clrscr: sta (SAVMSC),y rts - .data + .bss -conio_color: .byte 0 +conio_color: .res 1 .segment "DLIST" diff --git a/libsrc/atari5200/cputc.s b/libsrc/atari5200/cputc.s index 6de397182..3210f0a84 100644 --- a/libsrc/atari5200/cputc.s +++ b/libsrc/atari5200/cputc.s @@ -15,9 +15,9 @@ .importzp screen_width, screen_height .importzp ptr4 - .import screen_setup - .constructor screen_setup_constructor, 26 -screen_setup_constructor = screen_setup + .import initconio + .constructor initconio_constructor +initconio_constructor = initconio _cputcxy: pha ; Save C diff --git a/libsrc/atari5200/extra/conioscreen_20x12.s b/libsrc/atari5200/extra/conioscreen_20x12.s index 9cde9826d..b1e50aed7 100644 --- a/libsrc/atari5200/extra/conioscreen_20x12.s +++ b/libsrc/atari5200/extra/conioscreen_20x12.s @@ -7,7 +7,7 @@ SCREEN_BUF_SIZE = 20 * 12 SCREEN_BUF = $4000 - SCREEN_BUF_SIZE - .export screen_setup + .export initconio .export screen_width, screen_height .export conio_color @@ -17,7 +17,8 @@ screen_height = 12 .segment "ONCE" -screen_setup: +; initialize color registers, display list, and screen memory +initconio: ; initialize SAVMSC lda #<SCREEN_BUF @@ -62,9 +63,9 @@ clrscr: sta (SAVMSC),y rts - .data + .bss -conio_color: .byte 0 +conio_color: .res 1 .segment "DLIST" From 8590de5cf3515d7df156a5d470ad06bd68f97555 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 10 Apr 2019 22:20:01 +0200 Subject: [PATCH 1057/2161] Revert "atari5200: fix COLOR defines' names" This reverts commit 87e653f47bd4bda4b2f27849148a163684073e0a. --- asminc/atari5200.inc | 8 ++++---- include/atari5200.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/asminc/atari5200.inc b/asminc/atari5200.inc index a09b44257..a17268de2 100644 --- a/asminc/atari5200.inc +++ b/asminc/atari5200.inc @@ -115,10 +115,10 @@ POKEY = $E800 ; POKEY area ; conio color defines ;------------------------------------------------------------------------- -COLOR_WHITE = 0 -COLOR_LIGHTRED = 1 -COLOR_LIGHTGREEN = 2 -COLOR_BLACK = 3 +COLOR_WHITE = 0 +COLOR_RED = 1 +COLOR_GREEN = 2 +COLOR_BLACK = 3 ;------------------------------------------------------------------------- ; Cartridge Parameters diff --git a/include/atari5200.h b/include/atari5200.h index e014c8ac4..d6c2561b2 100644 --- a/include/atari5200.h +++ b/include/atari5200.h @@ -78,10 +78,10 @@ extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */ #define ANTIC (*(struct __antic*)0xD400) /* conio color defines */ -#define COLOR_WHITE 0x00 -#define COLOR_LIGHTRED 0x01 -#define COLOR_LIGHTGREEN 0x02 -#define COLOR_BLACK 0x03 +#define COLOR_WHITE 0x00 +#define COLOR_RED 0x01 +#define COLOR_GREEN 0x02 +#define COLOR_BLACK 0x03 /* The following #define will cause the matching function calls in conio.h ** to be overlaid by macros with the same names, saving the function call From 34942a2da555ac1de9f8ab7410775b9984c1378c Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 10 Apr 2019 22:22:16 +0200 Subject: [PATCH 1058/2161] atari5200: testcode/lib/atari5200/hello.c: adapt to changed COLOR_xxx defines --- testcode/lib/atari5200/hello.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testcode/lib/atari5200/hello.c b/testcode/lib/atari5200/hello.c index 830d03a91..e1a7a0137 100644 --- a/testcode/lib/atari5200/hello.c +++ b/testcode/lib/atari5200/hello.c @@ -22,7 +22,7 @@ static const char Text [] = "Hello world!"; -static unsigned char colors[] = { COLOR_WHITE, COLOR_LIGHTGREEN, COLOR_LIGHTRED, COLOR_BLACK }; +static unsigned char colors[] = { COLOR_WHITE, COLOR_GREEN, COLOR_RED, COLOR_BLACK }; From 78daf84f1269ca2ae0c935946b4e336641f889b2 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Fri, 12 Apr 2019 12:39:37 +0200 Subject: [PATCH 1059/2161] atari5200: name conio constructor 'initconio' --- libsrc/atari5200/conioscreen.s | 4 ++-- libsrc/atari5200/cputc.s | 6 +++--- libsrc/atari5200/extra/conioscreen_20x12.s | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libsrc/atari5200/conioscreen.s b/libsrc/atari5200/conioscreen.s index 4e769b126..1311e874c 100644 --- a/libsrc/atari5200/conioscreen.s +++ b/libsrc/atari5200/conioscreen.s @@ -7,7 +7,7 @@ SCREEN_BUF_SIZE = 20 * 24 SCREEN_BUF = $4000 - SCREEN_BUF_SIZE - .export initconio + .export screen_setup .export screen_width, screen_height .export conio_color @@ -18,7 +18,7 @@ screen_height = 24 .segment "ONCE" ; initialize color registers, display list, and screen memory -initconio: +screen_setup: ; initialize SAVMSC lda #<SCREEN_BUF diff --git a/libsrc/atari5200/cputc.s b/libsrc/atari5200/cputc.s index 3210f0a84..3e3a36cff 100644 --- a/libsrc/atari5200/cputc.s +++ b/libsrc/atari5200/cputc.s @@ -15,9 +15,9 @@ .importzp screen_width, screen_height .importzp ptr4 - .import initconio - .constructor initconio_constructor -initconio_constructor = initconio + .import screen_setup + .constructor initconio +initconio = screen_setup _cputcxy: pha ; Save C diff --git a/libsrc/atari5200/extra/conioscreen_20x12.s b/libsrc/atari5200/extra/conioscreen_20x12.s index b1e50aed7..e591bf05a 100644 --- a/libsrc/atari5200/extra/conioscreen_20x12.s +++ b/libsrc/atari5200/extra/conioscreen_20x12.s @@ -7,7 +7,7 @@ SCREEN_BUF_SIZE = 20 * 12 SCREEN_BUF = $4000 - SCREEN_BUF_SIZE - .export initconio + .export screen_setup .export screen_width, screen_height .export conio_color @@ -18,7 +18,7 @@ screen_height = 12 .segment "ONCE" ; initialize color registers, display list, and screen memory -initconio: +screen_setup: ; initialize SAVMSC lda #<SCREEN_BUF From 03311e72689111c76b07f39b1ed181a9efc4ebd0 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Fri, 12 Apr 2019 14:01:26 +0200 Subject: [PATCH 1060/2161] atari5200: update docs for recent conio changes also renames libsrc/atari5200/extra/conioscreen_20x12.s to libsrc/atari5200/extra/conioscreen-20x12.s to be in line with other optional link modules --- doc/atari5200.sgml | 42 ++++++++++++++++++- doc/library.sgml | 1 + ...onioscreen_20x12.s => conioscreen-20x12.s} | 0 3 files changed, 42 insertions(+), 1 deletion(-) rename libsrc/atari5200/extra/{conioscreen_20x12.s => conioscreen-20x12.s} (100%) diff --git a/doc/atari5200.sgml b/doc/atari5200.sgml index fedac4466..bd2b6adcb 100644 --- a/doc/atari5200.sgml +++ b/doc/atari5200.sgml @@ -52,7 +52,7 @@ Special locations: <tag/Text screen/ The text screen is only enabled if any of the CONIO output functions is used in the program. Its size is 20x24 characters (Antic mode 6, - BASIC mode 1). The text screen is located at $3E00. The + BASIC mode 1) by default. The text screen is located at $3E00. The address of the screen memory is available at runtime in the variable SAVMSC ($001B).<p> If the program doesn't use any CONIO output functions it needs to setup its own @@ -151,6 +151,43 @@ No serial drivers are available for the Atari 5200. <sect>Limitations<p> + +<sect1>Direct console I/O<p> + +The <tt/atari5200/ target uses Antic mode 6 (BASIC mode 1) for the console +screen by default. There are four colors available: + +<itemize> +<item><tt/COLOR_WHITE/ +<item><tt/COLOR_RED/ +<item><tt/COLOR_GREEN/ +<item><tt/COLOR_BLACK/ +</itemize> + +Note that the <tt/COLOR_GREEN/ and <tt/COLOR_RED/ colors aren't +exactly the same colors as the ones with the same name on the +<tt/atari/ target. +They are the colors which are available as <tt/COLOR_LIGHTGREEN/ +and <tt/COLOR_LIGHTRED/ there. + +One can set the color shadow registers directly with other colors. +Then the color defines from above will just become placeholders. In +this scenario it might be more convenient to use index values (0..3) +instead of the color defines. The index values specify which of the +system shadow color registers (<tt/COLOR0/ .. <tt/COLOR3/) to use. + +The default console screen has a layout of 20x24 characters. An +alternative layout, 20x12, Antic mode 7, BASIC mode 2, is provided in +the file <tt/atari5200-conioscreen-20x12.o/. + +Using <tt/atari5200-conioscreen-20x12.o/ is as simple as placing it on +the linker command line like this: + +<tscreen><verb> +cl65 -t atari5200 myprog.c lib/atari5200-conioscreen-20x12.o +</verb></tscreen> + + <sect1>Disk I/O<p> Disk I/O is not supported by the <tt/atari5200/ target. This means that @@ -171,6 +208,9 @@ you cannot use any of the following functions (and a few others): <sect>Other hints<p> +AtariROMMaker (<url url="https://www.wudsn.com/index.php/productions-atari800/tools/atarirommaker"> ) +can be used to create a <tt/.CAR/ file from the binary ROM image cc65 generates. +This might be more convenient when working with emulators. <sect>License<p> diff --git a/doc/library.sgml b/doc/library.sgml index 8800c5496..e8ca84653 100644 --- a/doc/library.sgml +++ b/doc/library.sgml @@ -162,6 +162,7 @@ portable. conio implementations exist for the following targets: <item>apple2 <item>apple2enh <item>atari + <item>atari5200 <item>atarixl <item>atmos <item>c16 (works also for the c116 with up to 32K memory) diff --git a/libsrc/atari5200/extra/conioscreen_20x12.s b/libsrc/atari5200/extra/conioscreen-20x12.s similarity index 100% rename from libsrc/atari5200/extra/conioscreen_20x12.s rename to libsrc/atari5200/extra/conioscreen-20x12.s From cb7882a2022ed7ec17d935c7f1e7a1db8785547a Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Sat, 13 Apr 2019 00:11:57 +0200 Subject: [PATCH 1061/2161] atari5200.sgml: small fix for last change --- doc/atari5200.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/atari5200.sgml b/doc/atari5200.sgml index bd2b6adcb..00d3dfbd2 100644 --- a/doc/atari5200.sgml +++ b/doc/atari5200.sgml @@ -184,7 +184,7 @@ Using <tt/atari5200-conioscreen-20x12.o/ is as simple as placing it on the linker command line like this: <tscreen><verb> -cl65 -t atari5200 myprog.c lib/atari5200-conioscreen-20x12.o +cl65 -t atari5200 myprog.c atari5200-conioscreen-20x12.o </verb></tscreen> From ac0b452834265d7f4287e9d6e10f2631fbd66dd0 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 13 Apr 2019 11:25:54 +0200 Subject: [PATCH 1062/2161] Added '_' prefix to sin and cos. Users complained that otherwise the names might clash with their functions. --- doc/funcref.sgml | 4 ++-- include/cc65.h | 4 ++-- libsrc/common/sincos.s | 28 +++++++++++++--------------- libsrc/tgi/tgi_arc.c | 8 ++++---- libsrc/tgi/tgi_pieslice.c | 4 ++-- samples/tgidemo.c | 2 +- 6 files changed, 24 insertions(+), 26 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 89a8eb13c..030c726cc 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -244,11 +244,11 @@ function. <itemize> -<!-- <item><ref id="cos" name="cos"> --> +<!-- <item><ref id="_cos" name="_cos"> --> <!-- <item><ref id="idiv32by16r16" name="idiv32by16r16"> --> <!-- <item><ref id="imul16x16r32" name="imul16x16r32"> --> <!-- <item><ref id="imul8x8r16" name="imul8x8r16"> --> -<!-- <item><ref id="sin" name="sin"> --> +<!-- <item><ref id="_sin" name="_sin"> --> <!-- <item><ref id="udiv32by16r16" name="udiv32by16r16"> --> <!-- <item><ref id="umul16x16r32" name="umul16x16r32"> --> <!-- <item><ref id="umul16x8r32" name="umul16x8r32"> --> diff --git a/include/cc65.h b/include/cc65.h index a30bad247..7e9c2cae2 100644 --- a/include/cc65.h +++ b/include/cc65.h @@ -85,12 +85,12 @@ unsigned int __fastcall__ mul40 (unsigned char value); ** result */ -int __fastcall__ sin (unsigned x); +int __fastcall__ _sin (unsigned x); /* Return the sine of the argument, which must be in range 0..360. The result ** is in 8.8 fixed point format, which means that 1.0 = $100 and -1.0 = $FF00. */ -int __fastcall__ cos (unsigned x); +int __fastcall__ _cos (unsigned x); /* Return the cosine of the argument, which must be in range 0..360. The result ** is in 8.8 fixed point format, which means that 1.0 = $100 and -1.0 = $FF00. */ diff --git a/libsrc/common/sincos.s b/libsrc/common/sincos.s index 7cdcb7167..6bbc151f4 100644 --- a/libsrc/common/sincos.s +++ b/libsrc/common/sincos.s @@ -1,8 +1,8 @@ ; ; Fixed point cosine/sine functions. ; -; int __fastcall__ cc65_sin (unsigned x); -; int __fastcall__ cc65_cos (unsigned x); +; int __fastcall__ _sin (unsigned x); +; int __fastcall__ _cos (unsigned x); ; ; Returns the cosine/sine for the given argument as angular degree. ; Valid argument range is 0..360 for both functions. They will return @@ -13,7 +13,7 @@ ; Ullrich von Bassewitz, 2009-10-29 ; - .export _cos, _sin + .export __cos, __sin ; --------------------------------------------------------------------------- @@ -37,13 +37,13 @@ _sintab: ; --------------------------------------------------------------------------- -; Cosine function. Is actually implemented as cos(x) = sin(x+90) +; Cosine function. Is actually implemented as _cos(x) = _sin(x+90) .code -_cos: +__cos: -; cos(x) = sin(x+90) +; _cos(x) = _sin(x+90) clc adc #90 @@ -55,7 +55,7 @@ _cos: @L1: cpx #>360 bne @L2 cmp #<360 -@L2: bcc _sin +@L2: bcc __sin sbc #<360 bcs @L3 @@ -66,12 +66,12 @@ _cos: ; Sine function. Uses ; ; table lookup for 0..89° -; sin(x) = sin(180-x) for 90°..179° -; sin(x) = -sin(x-180) for 180..360° +; _sin(x) = _sin(180-x) for 90°..179° +; _sin(x) = -_sin(x-180) for 180..360° ; ; Plus special handling for the values missing in the table. -_sin: +__sin: ; If the high byte is non zero, argument is > 255 @@ -85,7 +85,7 @@ _sin: cmp #90 bcc L1 -; 90..179°. Value is identical to sin(180-val). Carry is set on entry. +; 90..179°. Value is identical to _sin(180-val). Carry is set on entry. ; ; 180-val := -val + 180. ; With @@ -117,7 +117,7 @@ L2: tay lda _sintab,y rts -; 180..360°. sin(x) = -sin(x-180). Since the argument is in range 0..180 +; 180..360°. _sin(x) = -_sin(x-180). Since the argument is in range 0..180 ; after the subtraction, we don't need to handle the high byte. L3: sec @@ -126,7 +126,7 @@ L4: sbc #180 cmp #90 bcc L5 -; 270..360°. Value is identical to -sin(180-val). Carry is set on entry. +; 270..360°. Value is identical to -_sin(180-val). Carry is set on entry. ; ; 180-val := -val + 180. ; With @@ -160,5 +160,3 @@ L6: tay bcc L7 inx L7: rts - - diff --git a/libsrc/tgi/tgi_arc.c b/libsrc/tgi/tgi_arc.c index 94cc593ce..c0baabbde 100644 --- a/libsrc/tgi/tgi_arc.c +++ b/libsrc/tgi/tgi_arc.c @@ -70,16 +70,16 @@ void __fastcall__ tgi_arc (int x, int y, unsigned char rx, unsigned char ry, } /* Calculate the start coords */ - x1 = x + tgi_imulround (rx, cos (sa)); - y1 = y - tgi_imulround (ry, sin (sa)); + x1 = x + tgi_imulround (rx, _cos (sa)); + y1 = y - tgi_imulround (ry, _sin (sa)); do { sa += inc; if (sa >= ea) { sa = ea; done = 1; } - x2 = x + tgi_imulround (rx, cos (sa)); - y2 = y - tgi_imulround (ry, sin (sa)); + x2 = x + tgi_imulround (rx, _cos (sa)); + y2 = y - tgi_imulround (ry, _sin (sa)); tgi_line (x1, y1, x2, y2); x1 = x2; y1 = y2; diff --git a/libsrc/tgi/tgi_pieslice.c b/libsrc/tgi/tgi_pieslice.c index b119b9b2d..748d1819a 100644 --- a/libsrc/tgi/tgi_pieslice.c +++ b/libsrc/tgi/tgi_pieslice.c @@ -57,8 +57,8 @@ void __fastcall__ tgi_pieslice (int x, int y, unsigned char rx, unsigned char ry tgi_arc (x, y, rx, ry, sa, ea); /* ... and close it */ - tgi_line (x, y, x + tgi_imulround (rx, cos (sa)), y - tgi_imulround (ry, sin (sa))); - tgi_line (x, y, x + tgi_imulround (rx, cos (ea)), y - tgi_imulround (ry, sin (ea))); + tgi_line (x, y, x + tgi_imulround (rx, _cos (sa)), y - tgi_imulround (ry, _sin (sa))); + tgi_line (x, y, x + tgi_imulround (rx, _cos (ea)), y - tgi_imulround (ry, _sin (ea))); } diff --git a/samples/tgidemo.c b/samples/tgidemo.c index 1d76fee2e..de743314e 100644 --- a/samples/tgidemo.c +++ b/samples/tgidemo.c @@ -151,7 +151,7 @@ static void DoDiagram (void) /* Calculate the next points */ X = (int) (((long) (MaxX - 19) * I) / 360); - Y = (int) (((long) Amp * -sin (I)) / 256); + Y = (int) (((long) Amp * -_sin (I)) / 256); /* Draw the line */ tgi_lineto (XOrigin + X, YOrigin + Y); From f29220be1b37f139b64f9844b74014bda03e8b3c Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Wed, 10 Apr 2019 13:04:41 +0300 Subject: [PATCH 1063/2161] Add test showing optimizer failure, OptUnusedLoads removes needed loads --- test/val/jmp-callax.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 test/val/jmp-callax.c diff --git a/test/val/jmp-callax.c b/test/val/jmp-callax.c new file mode 100644 index 000000000..224b89251 --- /dev/null +++ b/test/val/jmp-callax.c @@ -0,0 +1,21 @@ +static unsigned char val; + +static void foo(void) { + val = 5; +} + +static void wrap() { + + asm("lda #<%v", foo); + asm("ldx #>%v", foo); + asm("jmp callax"); + +} + +int main() { + + val = 0; + wrap(); + + return val == 5 ? 0 : 1; +} From c3d809b1296df85bb742ffe4bf140459998f9c3d Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Wed, 10 Apr 2019 13:43:35 +0300 Subject: [PATCH 1064/2161] Fix jmp-callax.c bug --- src/cc65/codeseg.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index ba759988b..c27d105c9 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -426,8 +426,10 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; Label = CS_FindLabel (S, Arg, Hash); - /* If we don't have the label, it's a forward ref - create it */ - if (Label == 0) { + /* If we don't have the label, it's a forward ref - create it unless + ** it's an external function. + */ + if (Label == 0 && IsLocalLabelName(Arg)) { /* Generate a new label */ Label = CS_NewCodeLabel (S, Arg, Hash); } From 2af76c7cffb08af3a6f7ca87c90132aa3e365f76 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Wed, 10 Apr 2019 14:01:36 +0300 Subject: [PATCH 1065/2161] Only for jumps, the lib uses named asm labels in branches --- src/cc65/codeseg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index c27d105c9..297d09c4f 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -429,7 +429,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && IsLocalLabelName(Arg)) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName(Arg)) ) { /* Generate a new label */ Label = CS_NewCodeLabel (S, Arg, Hash); } From 37f00e664454e98196fc7058d1de8e0f6dae99f5 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Wed, 10 Apr 2019 14:20:24 +0300 Subject: [PATCH 1066/2161] Export the label symbol table --- src/cc65/symtab.c | 6 ++++++ src/cc65/symtab.h | 3 +++ 2 files changed, 9 insertions(+) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 56196ea5a..7adafc413 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -997,6 +997,12 @@ SymTable* GetGlobalSymTab (void) return SymTab0; } +SymTable* GetLabelSymTab (void) +/* Return the global symbol table */ +{ + return LabelTab; +} + int SymIsLocal (SymEntry* Sym) diff --git a/src/cc65/symtab.h b/src/cc65/symtab.h index 0856740cc..cd736ec1e 100644 --- a/src/cc65/symtab.h +++ b/src/cc65/symtab.h @@ -178,6 +178,9 @@ SymTable* GetSymTab (void); SymTable* GetGlobalSymTab (void); /* Return the global symbol table */ +SymTable* GetLabelSymTab (void); +/* Return the label symbol table */ + int SymIsLocal (SymEntry* Sym); /* Return true if the symbol is defined in the highest lexical level */ From c2220f3c3055aa1187b1876d0cee75509079da4d Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Wed, 10 Apr 2019 14:46:07 +0300 Subject: [PATCH 1067/2161] Add a goto indirect jump from pointer --- src/cc65/symentry.h | 2 ++ src/cc65/symtab.c | 1 + 2 files changed, 3 insertions(+) diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 73a8a72e7..abadc35c2 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -58,6 +58,7 @@ struct Segments; struct LiteralPool; +struct CodeEntry; @@ -138,6 +139,7 @@ struct SymEntry { struct { unsigned Label; Collection *DefsOrRefs; + struct CodeEntry *IndJumpFrom; } L; /* Value of SP adjustment needed after forward 'goto' */ diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 7adafc413..9a767fd0e 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -777,6 +777,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* Set a new label number */ Entry->V.L.Label = GetLocalLabel (); + Entry->V.L.IndJumpFrom = NULL; /* Create Collection for label definition and references */ Entry->V.L.DefsOrRefs = NewCollection (); From 3b3b16ee9c2632a8feae56cb990f72893d9aea14 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Tue, 9 Apr 2019 15:49:52 +0300 Subject: [PATCH 1068/2161] Add support for computed gotos This is a GCC extension that allows C to use fast jump tables. --- src/cc65/expr.c | 16 ++++++ src/cc65/goto.c | 105 ++++++++++++++++++++++++++++++++++++---- src/cc65/symentry.h | 1 + src/cc65/symtab.c | 26 +++++----- test/val/computedgoto.c | 55 +++++++++++++++++++++ 5 files changed, 182 insertions(+), 21 deletions(-) create mode 100644 test/val/computedgoto.c diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 320ac2321..a4b58b723 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -696,6 +696,22 @@ static void Primary (ExprDesc* E) switch (CurTok.Tok) { + case TOK_BOOL_AND: + /* A computed goto label address */ + if (IS_Get (&Standard) >= STD_CC65) { + NextToken (); + SymEntry* Entry = AddLabelSym (CurTok.Ident, SC_REF | SC_GOTO_IND); + /* output its label */ + E->Flags = E_RTYPE_RVAL | E_LOC_STATIC; + E->Name = Entry->V.L.Label; + E->Type = PointerTo(type_void); + NextToken (); + } else { + Error ("Computed gotos are a C extension, not supported with this --standard"); + ED_MakeConstAbsInt (E, 1); + } + break; + case TOK_IDENT: /* Identifier. Get a pointer to the symbol table entry */ Sym = E->Sym = FindSym (CurTok.Ident); diff --git a/src/cc65/goto.c b/src/cc65/goto.c index ae9e6096d..ae509e643 100644 --- a/src/cc65/goto.c +++ b/src/cc65/goto.c @@ -33,9 +33,17 @@ +#include "asmlabel.h" +#include "codeent.h" #include "codegen.h" +#include "codeseg.h" +#include "cpu.h" #include "error.h" +#include "exprdesc.h" +#include "expr.h" +#include "loadexpr.h" #include "scanner.h" +#include "standard.h" #include "symtab.h" #include "goto.h" @@ -54,21 +62,97 @@ void GotoStatement (void) NextToken (); /* Label name must follow */ - if (CurTok.Tok != TOK_IDENT) { - - Error ("Label name expected"); - - } else { + if (CurTok.Tok == TOK_IDENT) { /* Add a new label symbol if we don't have one until now */ SymEntry* Entry = AddLabelSym (CurTok.Ident, SC_REF | SC_GOTO); /* Jump to the label */ g_jump (Entry->V.L.Label); - } - /* Eat the label name */ - NextToken (); + /* Eat the label name */ + NextToken (); + + } else if (CurTok.Tok == TOK_STAR && IS_Get (&Standard) >= STD_CC65) { + SymEntry *arr, *idx, *cur; + SymTable *tab; + ExprDesc desc; + CodeEntry *E; + unsigned char val; + unsigned I; + + NextToken (); + + /* arr[foo], we only support simple foo for now */ + if (CurTok.Tok == TOK_IDENT && + (arr = FindSym (CurTok.Ident))) { + NextToken (); + ConsumeLBrack (); + + /* Find array size */ + if (!IsTypeArray(arr->Type) || SizeOf(arr->Type) == 0 || + SizeOf(GetElementType(arr->Type)) != 2) + Error ("Expected array"); + if (GetElementCount(arr->Type) > 127) + Error ("Only arrays with <= 127 labels are supported, got %lu", + GetElementCount(arr->Type)); + + if (CurTok.Tok == TOK_ICONST) { + val = CurTok.IVal; + NextToken (); + + if (CPUIsets[CPU] & CPU_ISET_65SC02) { + AddCodeLine ("ldx #$%02X", val * 2); + AddCodeLine ("jmp (%s,x)", arr->AsmName); + } else { + AddCodeLine ("ldy #$%02X", val * 2); + AddCodeLine ("lda %s,y", arr->AsmName); + AddCodeLine ("ldx %s+1,y", arr->AsmName); + AddCodeLine ("jmp callax"); + } + } else if (CurTok.Tok == TOK_IDENT && + (idx = FindSym (CurTok.Ident))) { + hie10 (&desc); + LoadExpr (CF_NONE, &desc); + AddCodeLine ("asl a"); + + if (CPUIsets[CPU] & CPU_ISET_65SC02) { + AddCodeLine ("tax"); + AddCodeLine ("jmp (%s,x)", arr->AsmName); + } else { + AddCodeLine ("tay"); + AddCodeLine ("lda %s,y", arr->AsmName); + AddCodeLine ("ldx %s+1,y", arr->AsmName); + AddCodeLine ("jmp callax"); + } + } else { + Error ("Only simple expressions are supported for computed goto"); + } + + ConsumeRBrack (); + + /* Loop over all target labels, specifying this as a jump point. + ** It's not exact - if there's multiple gotos, the last will be used, + ** but it's only needed so the optimizer does not remove the labels. + */ + I = CS_GetEntryCount (CS->Code) - 1; + E = CS_GetEntry (CS->Code, I); + + tab = GetLabelSymTab (); + if (tab) { + cur = tab->SymHead; + while (cur) { + if ((cur->Flags & (SC_LABEL|SC_GOTO_IND)) == (SC_LABEL|SC_GOTO_IND)) { + cur->V.L.IndJumpFrom = E; + } + cur = cur->NextSym; + } + } + } + } else { + + Error ("Label name expected"); + } } @@ -80,7 +164,10 @@ void DoLabel (void) SymEntry* Entry = AddLabelSym (CurTok.Ident, SC_DEF); /* Emit the jump label */ - g_defcodelabel (Entry->V.L.Label); + CodeLabel* L = CS_AddLabel (CS->Code, LocalLabelName (Entry->V.L.Label)); + if (Entry->V.L.IndJumpFrom) { + CollAppend (&L->JumpFrom, Entry->V.L.IndJumpFrom); + } /* Eat the ident and colon */ NextToken (); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index abadc35c2..62bf0b0e7 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -101,6 +101,7 @@ struct CodeEntry; #define SC_GOTO 0x20000U #define SC_SPADJUSTMENT 0x40000U +#define SC_GOTO_IND 0x80000U /* Indirect goto */ diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 9a767fd0e..52ef04e42 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -717,7 +717,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) for (i = 0; i < CollCount (Entry->V.L.DefsOrRefs); i++) { DOR = CollAt (Entry->V.L.DefsOrRefs, i); - if ((DOR->Flags & SC_DEF) && (Flags & SC_REF) && (Flags & SC_GOTO)) { + if ((DOR->Flags & SC_DEF) && (Flags & SC_REF) && (Flags & (SC_GOTO|SC_GOTO_IND))) { /* We're processing a goto and here is its destination label. ** This means the difference between SP values is already known, ** so we simply emit the SP adjustment code. @@ -739,21 +739,23 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) } - if ((DOR->Flags & SC_REF) && (DOR->Flags & SC_GOTO) && (Flags & SC_DEF)) { + if ((DOR->Flags & SC_REF) && (DOR->Flags & (SC_GOTO|SC_GOTO_IND)) && (Flags & SC_DEF)) { /* We're processing a label, let's update all gotos encountered ** so far */ - SymEntry *E; - g_userodata(); - g_defdatalabel (DOR->LateSP_Label); - g_defdata (CF_CONST | CF_INT, StackPtr - DOR->StackPtr, 0); + if (DOR->Flags & SC_GOTO) { + SymEntry *E; + g_userodata(); + g_defdatalabel (DOR->LateSP_Label); + g_defdata (CF_CONST | CF_INT, StackPtr - DOR->StackPtr, 0); - /* Optimizer will need the information about the value of SP adjustment - ** later, so let's preserve it. - */ - E = NewSymEntry (LocalLabelName (DOR->LateSP_Label), SC_SPADJUSTMENT); - E->V.SPAdjustment = StackPtr - DOR->StackPtr; - AddSymEntry (SPAdjustTab, E); + /* Optimizer will need the information about the value of SP adjustment + ** later, so let's preserve it. + */ + E = NewSymEntry (LocalLabelName (DOR->LateSP_Label), SC_SPADJUSTMENT); + E->V.SPAdjustment = StackPtr - DOR->StackPtr; + AddSymEntry (SPAdjustTab, E); + } /* Are we jumping into a block with initalization of an object that ** has automatic storage duration? Let's emit a warning. diff --git a/test/val/computedgoto.c b/test/val/computedgoto.c new file mode 100644 index 000000000..f7a4e28ec --- /dev/null +++ b/test/val/computedgoto.c @@ -0,0 +1,55 @@ +static unsigned char val, val2; + +static void act(const unsigned char op) { + + static const void * const arr[] = { + &&op0, + &&op1, + &&op2, + &&op3, + &&op4, + &&op5, + &&op6, + }; + + goto *arr[op]; + + op0: + val += 1; + return; + + op1: + val += 2; + return; + + op2: + val += 3; + return; + + op3: + val2 += 1; + return; + + op4: + val2 += 5; + return; + + op5: + val2 += 7; + return; + + op6: + val2 += 9; + return; +} + +int main() { + + val = val2 = 0; + + act(1); + act(3); + act(5); + + return val == 2 && val2 == 8 ? 0 : 1; +} From 304473d8579f1a266c76c90c2c4da59fcc219281 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Wed, 10 Apr 2019 17:29:57 +0300 Subject: [PATCH 1069/2161] Adjustment for '816 --- src/cc65/goto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65/goto.c b/src/cc65/goto.c index ae509e643..1b99a9803 100644 --- a/src/cc65/goto.c +++ b/src/cc65/goto.c @@ -103,7 +103,7 @@ void GotoStatement (void) if (CPUIsets[CPU] & CPU_ISET_65SC02) { AddCodeLine ("ldx #$%02X", val * 2); - AddCodeLine ("jmp (%s,x)", arr->AsmName); + AddCodeLine ("jmp (.loword(%s),x)", arr->AsmName); } else { AddCodeLine ("ldy #$%02X", val * 2); AddCodeLine ("lda %s,y", arr->AsmName); @@ -118,7 +118,7 @@ void GotoStatement (void) if (CPUIsets[CPU] & CPU_ISET_65SC02) { AddCodeLine ("tax"); - AddCodeLine ("jmp (%s,x)", arr->AsmName); + AddCodeLine ("jmp (.loword(%s),x)", arr->AsmName); } else { AddCodeLine ("tay"); AddCodeLine ("lda %s,y", arr->AsmName); From a9cbb5305c3863b3385c54d7112bd587e8d075c4 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Sat, 13 Apr 2019 19:43:44 +0300 Subject: [PATCH 1070/2161] Fix missing spaces --- src/cc65/codeseg.c | 2 +- src/cc65/expr.c | 2 +- src/cc65/goto.c | 8 ++++---- src/cc65/symtab.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 297d09c4f..e2fd84a7c 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -429,7 +429,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName(Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { /* Generate a new label */ Label = CS_NewCodeLabel (S, Arg, Hash); } diff --git a/src/cc65/expr.c b/src/cc65/expr.c index a4b58b723..fad1c9514 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -704,7 +704,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_STATIC; E->Name = Entry->V.L.Label; - E->Type = PointerTo(type_void); + E->Type = PointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); diff --git a/src/cc65/goto.c b/src/cc65/goto.c index 1b99a9803..08a7033c3 100644 --- a/src/cc65/goto.c +++ b/src/cc65/goto.c @@ -90,12 +90,12 @@ void GotoStatement (void) ConsumeLBrack (); /* Find array size */ - if (!IsTypeArray(arr->Type) || SizeOf(arr->Type) == 0 || - SizeOf(GetElementType(arr->Type)) != 2) + if (!IsTypeArray (arr->Type) || SizeOf (arr->Type) == 0 || + SizeOf (GetElementType(arr->Type)) != 2) Error ("Expected array"); - if (GetElementCount(arr->Type) > 127) + if (GetElementCount (arr->Type) > 127) Error ("Only arrays with <= 127 labels are supported, got %lu", - GetElementCount(arr->Type)); + GetElementCount (arr->Type)); if (CurTok.Tok == TOK_ICONST) { val = CurTok.IVal; diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 52ef04e42..a31c11bfc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -745,7 +745,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) */ if (DOR->Flags & SC_GOTO) { SymEntry *E; - g_userodata(); + g_userodata (); g_defdatalabel (DOR->LateSP_Label); g_defdata (CF_CONST | CF_INT, StackPtr - DOR->StackPtr, 0); From 654d97228835bed379b25cb967bf45d6673772c6 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Sun, 14 Apr 2019 19:45:53 +0300 Subject: [PATCH 1071/2161] C90 param, void --- src/cc65/expr.c | 3 ++- test/val/computedgoto.c | 2 +- test/val/jmp-callax.c | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index fad1c9514..e6522f949 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -699,8 +699,9 @@ static void Primary (ExprDesc* E) case TOK_BOOL_AND: /* A computed goto label address */ if (IS_Get (&Standard) >= STD_CC65) { + SymEntry* Entry; NextToken (); - SymEntry* Entry = AddLabelSym (CurTok.Ident, SC_REF | SC_GOTO_IND); + Entry = AddLabelSym (CurTok.Ident, SC_REF | SC_GOTO_IND); /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_STATIC; E->Name = Entry->V.L.Label; diff --git a/test/val/computedgoto.c b/test/val/computedgoto.c index f7a4e28ec..f8ab7c05f 100644 --- a/test/val/computedgoto.c +++ b/test/val/computedgoto.c @@ -43,7 +43,7 @@ static void act(const unsigned char op) { return; } -int main() { +int main(void) { val = val2 = 0; diff --git a/test/val/jmp-callax.c b/test/val/jmp-callax.c index 224b89251..35d3db6b6 100644 --- a/test/val/jmp-callax.c +++ b/test/val/jmp-callax.c @@ -4,7 +4,7 @@ static void foo(void) { val = 5; } -static void wrap() { +static void wrap(void) { asm("lda #<%v", foo); asm("ldx #>%v", foo); @@ -12,7 +12,7 @@ static void wrap() { } -int main() { +int main(void) { val = 0; wrap(); From 60d8559372c3cfd89c41c3e392086c486794571d Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Sun, 14 Apr 2019 19:47:42 +0300 Subject: [PATCH 1072/2161] Return after errors, move left bracket consumption down --- src/cc65/goto.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/cc65/goto.c b/src/cc65/goto.c index 08a7033c3..fde9df945 100644 --- a/src/cc65/goto.c +++ b/src/cc65/goto.c @@ -87,15 +87,20 @@ void GotoStatement (void) if (CurTok.Tok == TOK_IDENT && (arr = FindSym (CurTok.Ident))) { NextToken (); - ConsumeLBrack (); /* Find array size */ if (!IsTypeArray (arr->Type) || SizeOf (arr->Type) == 0 || - SizeOf (GetElementType(arr->Type)) != 2) + SizeOf (GetElementType(arr->Type)) != 2) { Error ("Expected array"); - if (GetElementCount (arr->Type) > 127) + return; + } + if (GetElementCount (arr->Type) > 127) { Error ("Only arrays with <= 127 labels are supported, got %lu", GetElementCount (arr->Type)); + return; + } + + ConsumeLBrack (); if (CurTok.Tok == TOK_ICONST) { val = CurTok.IVal; From f328481a480e253a86dd74598dc8c5044fb574e3 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Mon, 15 Apr 2019 16:23:01 +0300 Subject: [PATCH 1073/2161] Replace hard returns with an "else", add an error for non-IDENT tokens, and test for static --- src/cc65/goto.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cc65/goto.c b/src/cc65/goto.c index fde9df945..939eb65a9 100644 --- a/src/cc65/goto.c +++ b/src/cc65/goto.c @@ -90,14 +90,12 @@ void GotoStatement (void) /* Find array size */ if (!IsTypeArray (arr->Type) || SizeOf (arr->Type) == 0 || + !(arr->Flags & SC_STATIC) || SizeOf (GetElementType(arr->Type)) != 2) { - Error ("Expected array"); - return; - } - if (GetElementCount (arr->Type) > 127) { + Error ("Expected a static array"); + } else if (GetElementCount (arr->Type) > 127) { Error ("Only arrays with <= 127 labels are supported, got %lu", GetElementCount (arr->Type)); - return; } ConsumeLBrack (); @@ -153,6 +151,8 @@ void GotoStatement (void) cur = cur->NextSym; } } + } else { /* It was not TOK_IDENT, or we couldn't find the symbol */ + Error ("Array name expected"); } } else { From 55ce618bf2e64b2b4331a7f7a41223e3e6933492 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Mon, 15 Apr 2019 19:27:23 +0300 Subject: [PATCH 1074/2161] Document computed gotos --- doc/cc65.sgml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index a66854095..11b112f6f 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -776,6 +776,25 @@ This cc65 version has some extensions to the ISO C standard. size zero, even if it is initialized. <p> +<item> Computed gotos, a GCC extension, has limited support. With it you can + use fast jump tables from C. You can take the address of a label with + a double ampersand, putting them in a static const array of type void *. + Then you can jump to one of these labels as follows: + + <tscreen><verb> + static const void * const jumptable[] = { + &&add, + &&sub + }; + goto *jumptable[somevar]; + + add: + ...code... + </verb></tscreen> + + In the jump table, no expressions are supported. The array index + used in the goto must be a simple variable or a constant. + </itemize> <p> From 214c90f957f96b094cf88db858d0a0a17747d0de Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 22 Apr 2019 14:27:36 -0400 Subject: [PATCH 1075/2161] Made the code that logs indirect-goto referals be a little more efficient. --- src/cc65/goto.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/cc65/goto.c b/src/cc65/goto.c index 939eb65a9..10293642f 100644 --- a/src/cc65/goto.c +++ b/src/cc65/goto.c @@ -79,7 +79,6 @@ void GotoStatement (void) ExprDesc desc; CodeEntry *E; unsigned char val; - unsigned I; NextToken (); @@ -135,27 +134,25 @@ void GotoStatement (void) ConsumeRBrack (); /* Loop over all target labels, specifying this as a jump point. - ** It's not exact - if there's multiple gotos, the last will be used, - ** but it's only needed so the optimizer does not remove the labels. + ** It's not exact -- if there's multiple gotos, the last will be used; + ** but, it's needed only so the optimizer does not remove the labels. */ - I = CS_GetEntryCount (CS->Code) - 1; - E = CS_GetEntry (CS->Code, I); - + E = CS_GetEntry (CS->Code, CS_GetEntryCount (CS->Code) - 1); tab = GetLabelSymTab (); if (tab) { cur = tab->SymHead; while (cur) { - if ((cur->Flags & (SC_LABEL|SC_GOTO_IND)) == (SC_LABEL|SC_GOTO_IND)) { + if ((cur->Flags & SC_GOTO_IND) != 0) { cur->V.L.IndJumpFrom = E; } cur = cur->NextSym; } } - } else { /* It was not TOK_IDENT, or we couldn't find the symbol */ + } else { + /* It was not TOK_IDENT, or we couldn't find the symbol */ Error ("Array name expected"); } } else { - Error ("Label name expected"); } } @@ -170,6 +167,7 @@ void DoLabel (void) /* Emit the jump label */ CodeLabel* L = CS_AddLabel (CS->Code, LocalLabelName (Entry->V.L.Label)); + if (Entry->V.L.IndJumpFrom) { CollAppend (&L->JumpFrom, Entry->V.L.IndJumpFrom); } From 14d8f3d81d9cb0de2fbb3d956f4dc16c58c09458 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 24 Apr 2019 13:17:11 +0200 Subject: [PATCH 1076/2161] cfg/atari-xex.cfg: fix typo in comment --- cfg/atari-xex.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/atari-xex.cfg b/cfg/atari-xex.cfg index 5f390e12c..cabde3708 100644 --- a/cfg/atari-xex.cfg +++ b/cfg/atari-xex.cfg @@ -1,5 +1,5 @@ # Sample linker configuration for C programs using the Atari binary file support. -# Use with: cl65 -tatari -Catari-c-xex.cfg prog.c -o prog.xex +# Use with: cl65 -tatari -Catari-xex.cfg prog.c -o prog.xex FEATURES { STARTADDRESS: default = $2000; } From 37f80534c9953e168f2bc512b7b6484aeec50e18 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Mon, 22 Apr 2019 17:40:09 +0200 Subject: [PATCH 1077/2161] Fix for #830 supplied by UvB --- src/cc65/coptstop.c | 59 +++++++++++++++++++++++++++++++++------------ test/val/bug830.c | 13 ++++++++++ 2 files changed, 56 insertions(+), 16 deletions(-) create mode 100644 test/val/bug830.c diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 53582d565..87514cfdd 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -437,51 +437,78 @@ static void AdjustStackOffset (StackOpData* D, unsigned Offs) CodeEntry* E = CS_GetEntry (D->Code, I); - int NeedCorrection = 0; + /* Check if this entry does a stack access, and if so, if it's a plain + ** load from stack, since this is needed later. + */ + int Correction = 0; if ((E->Use & REG_SP) != 0) { /* Check for some things that should not happen */ CHECK (E->AM == AM65_ZP_INDY || E->RI->In.RegY >= (short) Offs); CHECK (strcmp (E->Arg, "sp") == 0); - /* We need to correct this one */ - NeedCorrection = 1; + Correction = (E->OPC == OP65_LDA)? 2 : 1; } else if (CE_IsCallTo (E, "ldaxysp")) { - /* We need to correct this one */ - NeedCorrection = 1; - + Correction = 1; } - if (NeedCorrection) { - + if (Correction) { /* Get the code entry before this one. If it's a LDY, adjust the ** value. */ CodeEntry* P = CS_GetPrevEntry (D->Code, I); if (P && P->OPC == OP65_LDY && CE_IsConstImm (P)) { - /* The Y load is just before the stack access, adjust it */ CE_SetNumArg (P, P->Num - Offs); - } else { - /* Insert a new load instruction before the stack access */ const char* Arg = MakeHexArg (E->RI->In.RegY - Offs); CodeEntry* X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); InsertEntry (D, X, I++); - } /* If we need the value of Y later, be sure to reload it */ if (RegYUsed (D->Code, I+1)) { + CodeEntry* N; const char* Arg = MakeHexArg (E->RI->In.RegY); - CodeEntry* X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); - InsertEntry (D, X, I+1); + if (Correction == 2 && (N = CS_GetNextEntry(D->Code, I)) != 0 && + ((N->Info & OF_ZBRA) != 0) && N->JumpTo != 0) { + /* The Y register is used but the load instruction loads A + ** and is followed by a branch that evaluates the zero flag. + ** This means that we cannot just insert the load insn + ** for the Y register at this place, because it would + ** destroy the Z flag. Instead place load insns at the + ** target of the branch and after it. + ** Note: There is a chance that this code won't work. The + ** jump may be a backwards jump (in which case the stack + ** offset has already been adjusted) or there may be other + ** instructions between the load and the conditional jump. + ** Currently the compiler does not generate such code, but + ** it is possible to force the optimizer into something + ** invalid by use of inline assembler. + */ - /* Skip this instruction in the next round */ - ++I; + /* Add load insn after the branch */ + CodeEntry* X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + InsertEntry (D, X, I+2); + + /* Add load insn before branch target */ + CodeEntry* Y = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + int J = CS_GetEntryIndex (D->Code, N->JumpTo->Owner); + CHECK (J > I); /* Must not happen */ + InsertEntry (D, Y, J); + + /* Move the label to the new insn */ + CodeLabel* L = CS_GenLabel (D->Code, Y); + CS_MoveLabelRef (D->Code, N, L); + } else { + CodeEntry* X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + InsertEntry (D, X, I+1); + /* Skip this instruction in the next round */ + ++I; + } } } diff --git a/test/val/bug830.c b/test/val/bug830.c new file mode 100644 index 000000000..05080e263 --- /dev/null +++ b/test/val/bug830.c @@ -0,0 +1,13 @@ +#include "unittest.h" + +char test[1]; +char *dst = &test[0]; + +TEST +{ + char src = 0; + *dst = (src == 0) ? 42 : src; + + ASSERT_AreEqual(42, *dst, "%u", "Incorrect ternary expression evaluation!"); +} +ENDTEST From 7b234d44977f7a33b231101fe3d93aa48e642068 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 30 Apr 2019 17:55:26 +0200 Subject: [PATCH 1078/2161] Adjusted doc to code. The requirement in question was lifted with https://github.com/cc65/cc65/commit/6ead4abf244abfab4bd52eff55da5cefe4d4a98f back in 2011. --- doc/ld65.sgml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 3f159b39b..2195ca48d 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -808,8 +808,7 @@ segment. <sect1>Other SEGMENT attributes<p> Segments may be aligned to some memory boundary. Specify "<tt/align = num/" to -request this feature. Num must be a power of two. To align all segments on a -page boundary, use +request this feature. To align all segments on a page boundary, use <tscreen><verb> SEGMENTS { From 392e6e10fc40a046d4e7dbc083a1e0bfd2e07d69 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 30 Apr 2019 18:21:13 +0200 Subject: [PATCH 1079/2161] again, some TABs slipped into the code... --- test/val/computedgoto.c | 72 ++++++++++++++++++++--------------------- test/val/jmp-callax.c | 14 ++++---- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/test/val/computedgoto.c b/test/val/computedgoto.c index f8ab7c05f..9f9404941 100644 --- a/test/val/computedgoto.c +++ b/test/val/computedgoto.c @@ -2,54 +2,54 @@ static unsigned char val, val2; static void act(const unsigned char op) { - static const void * const arr[] = { - &&op0, - &&op1, - &&op2, - &&op3, - &&op4, - &&op5, - &&op6, - }; + static const void * const arr[] = { + &&op0, + &&op1, + &&op2, + &&op3, + &&op4, + &&op5, + &&op6, + }; - goto *arr[op]; + goto *arr[op]; - op0: - val += 1; - return; + op0: + val += 1; + return; - op1: - val += 2; - return; + op1: + val += 2; + return; - op2: - val += 3; - return; + op2: + val += 3; + return; - op3: - val2 += 1; - return; + op3: + val2 += 1; + return; - op4: - val2 += 5; - return; + op4: + val2 += 5; + return; - op5: - val2 += 7; - return; + op5: + val2 += 7; + return; - op6: - val2 += 9; - return; + op6: + val2 += 9; + return; } int main(void) { - val = val2 = 0; + val = val2 = 0; - act(1); - act(3); - act(5); + act(1); + act(3); + act(5); - return val == 2 && val2 == 8 ? 0 : 1; + return val == 2 && val2 == 8 ? 0 : 1; } diff --git a/test/val/jmp-callax.c b/test/val/jmp-callax.c index 35d3db6b6..eb0cb271a 100644 --- a/test/val/jmp-callax.c +++ b/test/val/jmp-callax.c @@ -1,21 +1,21 @@ static unsigned char val; static void foo(void) { - val = 5; + val = 5; } static void wrap(void) { - asm("lda #<%v", foo); - asm("ldx #>%v", foo); - asm("jmp callax"); + asm("lda #<%v", foo); + asm("ldx #>%v", foo); + asm("jmp callax"); } int main(void) { - val = 0; - wrap(); + val = 0; + wrap(); - return val == 5 ? 0 : 1; + return val == 5 ? 0 : 1; } From 1a5fa6dc512221490c5547505668a78308f904a8 Mon Sep 17 00:00:00 2001 From: Brad Smith <bbbradsmith@users.noreply.github.com> Date: Wed, 1 May 2019 02:45:51 -0400 Subject: [PATCH 1080/2161] goto.c warning fix for implicit truncation --- src/cc65/goto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/goto.c b/src/cc65/goto.c index 10293642f..f1fb725d2 100644 --- a/src/cc65/goto.c +++ b/src/cc65/goto.c @@ -100,7 +100,7 @@ void GotoStatement (void) ConsumeLBrack (); if (CurTok.Tok == TOK_ICONST) { - val = CurTok.IVal; + val = (unsigned char)CurTok.IVal; NextToken (); if (CPUIsets[CPU] & CPU_ISET_65SC02) { From c248c14075aecc1598326dc0e88581596f6ad6d7 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Sat, 27 Apr 2019 00:04:38 +0200 Subject: [PATCH 1081/2161] src/ld65/exports.c: Issue an error instead of a warning for duplicate global symbols. --- src/ld65/exports.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ld65/exports.c b/src/ld65/exports.c index 0f9ac1c10..160e0c797 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -482,9 +482,9 @@ void InsertExport (Export* E) Imp = Imp->Next; } } else { - /* Duplicate entry, ignore it */ - Warning ("Duplicate external identifier: '%s'", - GetString (L->Name)); + /* Duplicate entry, this is fatal */ + Error ("Duplicate external identifier: '%s'", + GetString (L->Name)); } return; } From 5a05acf9366e4c1eef73fd4387afc45f6a6cebef Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 30 Apr 2019 16:20:22 +0200 Subject: [PATCH 1082/2161] ld65: implement '--allow-multiple-definition' command line parameter --- src/ld65/exports.c | 4 +-- src/ld65/global.c | 1 + src/ld65/global.h | 1 + src/ld65/main.c | 79 ++++++++++++++++++++++++++-------------------- 4 files changed, 49 insertions(+), 36 deletions(-) diff --git a/src/ld65/exports.c b/src/ld65/exports.c index 160e0c797..b83d8b496 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -481,8 +481,8 @@ void InsertExport (Export* E) Imp->Exp = E; Imp = Imp->Next; } - } else { - /* Duplicate entry, this is fatal */ + } else if (AllowMultDef == 0) { + /* Duplicate entry, this is fatal unless allowed by the user */ Error ("Duplicate external identifier: '%s'", GetString (L->Name)); } diff --git a/src/ld65/global.c b/src/ld65/global.c index dc0c8d521..59c3754e6 100644 --- a/src/ld65/global.c +++ b/src/ld65/global.c @@ -53,6 +53,7 @@ unsigned char HaveStartAddr = 0; /* Start address not given */ unsigned long StartAddr = 0x200; /* Start address */ unsigned char VerboseMap = 0; /* Verbose map file */ +unsigned char AllowMultDef = 0; /* Allow multiple definitions */ const char* MapFileName = 0; /* Name of the map file */ const char* LabelFileName = 0; /* Name of the label file */ const char* DbgFileName = 0; /* Name of the debug file */ diff --git a/src/ld65/global.h b/src/ld65/global.h index 4b873f027..6af265f45 100644 --- a/src/ld65/global.h +++ b/src/ld65/global.h @@ -53,6 +53,7 @@ extern unsigned char HaveStartAddr; /* True if start address was given */ extern unsigned long StartAddr; /* Start address */ extern unsigned char VerboseMap; /* Verbose map file */ +extern unsigned char AllowMultDef; /* Allow multiple definitions */ extern const char* MapFileName; /* Name of the map file */ extern const char* LabelFileName; /* Name of the label file */ extern const char* DbgFileName; /* Name of the debug file */ diff --git a/src/ld65/main.c b/src/ld65/main.c index e0dcf9727..94a2101b3 100644 --- a/src/ld65/main.c +++ b/src/ld65/main.c @@ -128,23 +128,24 @@ static void Usage (void) " -vm\t\t\tVerbose map file\n" "\n" "Long options:\n" - " --cfg-path path\tSpecify a config file search path\n" - " --config name\t\tUse linker config file\n" - " --dbgfile name\tGenerate debug information\n" - " --define sym=val\tDefine a symbol\n" - " --end-group\t\tEnd a library group\n" - " --force-import sym\tForce an import of symbol 'sym'\n" - " --help\t\tHelp (this text)\n" - " --lib file\t\tLink this library\n" - " --lib-path path\tSpecify a library search path\n" - " --mapfile name\tCreate a map file\n" - " --module-id id\tSpecify a module id\n" - " --obj file\t\tLink this object file\n" - " --obj-path path\tSpecify an object file search path\n" - " --start-addr addr\tSet the default start address\n" - " --start-group\t\tStart a library group\n" - " --target sys\t\tSet the target system\n" - " --version\t\tPrint the linker version\n", + " --allow-multiple-definition\tAllow multiple definitions\n" + " --cfg-path path\t\tSpecify a config file search path\n" + " --config name\t\t\tUse linker config file\n" + " --dbgfile name\t\tGenerate debug information\n" + " --define sym=val\t\tDefine a symbol\n" + " --end-group\t\t\tEnd a library group\n" + " --force-import sym\t\tForce an import of symbol 'sym'\n" + " --help\t\t\tHelp (this text)\n" + " --lib file\t\t\tLink this library\n" + " --lib-path path\t\tSpecify a library search path\n" + " --mapfile name\t\tCreate a map file\n" + " --module-id id\t\tSpecify a module id\n" + " --obj file\t\t\tLink this object file\n" + " --obj-path path\t\tSpecify an object file search path\n" + " --start-addr addr\t\tSet the default start address\n" + " --start-group\t\t\tStart a library group\n" + " --target sys\t\t\tSet the target system\n" + " --version\t\t\tPrint the linker version\n", ProgName); } @@ -549,6 +550,15 @@ static void OptVersion (const char* Opt attribute ((unused)), +static void OptMultDef (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Print the assembler version */ +{ + AllowMultDef = 1; +} + + + static void CmdlOptStartGroup (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Remember 'start group' occurrence in input files array */ @@ -599,23 +609,24 @@ static void ParseCommandLine(void) { /* Program long options */ static const LongOpt OptTab[] = { - { "--cfg-path", 1, OptCfgPath }, - { "--config", 1, CmdlOptConfig }, - { "--dbgfile", 1, OptDbgFile }, - { "--define", 1, OptDefine }, - { "--end-group", 0, CmdlOptEndGroup }, - { "--force-import", 1, OptForceImport }, - { "--help", 0, OptHelp }, - { "--lib", 1, OptLib }, - { "--lib-path", 1, OptLibPath }, - { "--mapfile", 1, OptMapFile }, - { "--module-id", 1, OptModuleId }, - { "--obj", 1, OptObj }, - { "--obj-path", 1, OptObjPath }, - { "--start-addr", 1, OptStartAddr }, - { "--start-group", 0, CmdlOptStartGroup }, - { "--target", 1, CmdlOptTarget }, - { "--version", 0, OptVersion }, + { "--allow-multiple-definition", 0, OptMultDef }, + { "--cfg-path", 1, OptCfgPath }, + { "--config", 1, CmdlOptConfig }, + { "--dbgfile", 1, OptDbgFile }, + { "--define", 1, OptDefine }, + { "--end-group", 0, CmdlOptEndGroup }, + { "--force-import", 1, OptForceImport }, + { "--help", 0, OptHelp }, + { "--lib", 1, OptLib }, + { "--lib-path", 1, OptLibPath }, + { "--mapfile", 1, OptMapFile }, + { "--module-id", 1, OptModuleId }, + { "--obj", 1, OptObj }, + { "--obj-path", 1, OptObjPath }, + { "--start-addr", 1, OptStartAddr }, + { "--start-group", 0, CmdlOptStartGroup }, + { "--target", 1, CmdlOptTarget }, + { "--version", 0, OptVersion }, }; unsigned I; From dd53c2ddc355128a4251658c99a2ab0882d8eec4 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 30 Apr 2019 18:30:20 +0200 Subject: [PATCH 1083/2161] src/ld65/main.c: fix copy'n'paste error in comment --- src/ld65/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ld65/main.c b/src/ld65/main.c index 94a2101b3..a3fd81143 100644 --- a/src/ld65/main.c +++ b/src/ld65/main.c @@ -552,7 +552,7 @@ static void OptVersion (const char* Opt attribute ((unused)), static void OptMultDef (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) -/* Print the assembler version */ +/* Set flag to allow multiple definitions of a global symbol */ { AllowMultDef = 1; } From a24e3d9e72c89655692aa32b5e1234aa8119504c Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 30 Apr 2019 23:33:22 +0200 Subject: [PATCH 1084/2161] ld65.sgml: document '--allow-multiple-definition' switch --- doc/ld65.sgml | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 2195ca48d..36489b0c6 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -71,23 +71,24 @@ Short options: -vm Verbose map file Long options: - --cfg-path path Specify a config file search path - --config name Use linker config file - --dbgfile name Generate debug information - --define sym=val Define a symbol - --end-group End a library group - --force-import sym Force an import of symbol 'sym' - --help Help (this text) - --lib file Link this library - --lib-path path Specify a library search path - --mapfile name Create a map file - --module-id id Specify a module id - --obj file Link this object file - --obj-path path Specify an object file search path - --start-addr addr Set the default start address - --start-group Start a library group - --target sys Set the target system - --version Print the linker version + --allow-multiple-definition Allow multiple definitions + --cfg-path path Specify a config file search path + --config name Use linker config file + --dbgfile name Generate debug information + --define sym=val Define a symbol + --end-group End a library group + --force-import sym Force an import of symbol 'sym' + --help Help (this text) + --lib file Link this library + --lib-path path Specify a library search path + --mapfile name Create a map file + --module-id id Specify a module id + --obj file Link this object file + --obj-path path Specify an object file search path + --start-addr addr Set the default start address + --start-group Start a library group + --target sys Set the target system + --version Print the linker version --------------------------------------------------------------------------- </verb></tscreen> @@ -98,6 +99,14 @@ Here is a description of all of the command-line options: <descrip> + <tag><tt>--allow-multiple-definition</tt></tag> + + Normally when a global symbol is defined multiple times, ld65 will + issue an error and not create the output file. This option lets it + silently ignore this fact and continue. The first definition of a + symbol will be used. + + <label id="option--start-group"> <tag><tt>-(, --start-group</tt></tag> From a01c4231f20a27cea7022e8d2a9b8e4124fb65ca Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 8 May 2019 10:22:12 +0200 Subject: [PATCH 1085/2161] Fixed _textcolor definition. The _textcolor() macro doesn't just turn on the macro optimization. It defines the return value of textcolor() - and that is supposed to be a COLOR_... value. --- include/atari.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/atari.h b/include/atari.h index 4fc027d20..582e23be6 100644 --- a/include/atari.h +++ b/include/atari.h @@ -540,7 +540,7 @@ extern void atrx15p2_tgi[]; ** to be overlaid by macros with the same names, saving the function call ** overhead. */ -#define _textcolor(color) 1 +#define _textcolor(color) COLOR_WHITE /* End of atari.h */ #endif From ac2ecb0b2ca84c579eb4f6eba66ba46512e58700 Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Wed, 1 May 2019 02:12:03 -0400 Subject: [PATCH 1086/2161] 65816 now generate EXPR_NEARADDR instead of EXPR_WORD0 for default assumed address mode, which will be validated by the linker's range check rather than blindly truncated. Assuming the assembler correctly validated this, the linker is allowed to truncate. --- src/ca65/expr.c | 22 ++++++++++++++++++++++ src/ca65/expr.h | 3 +++ src/ca65/instr.c | 2 +- src/ca65/studyexpr.c | 24 ++++++++++++++++++++++++ src/common/exprdefs.c | 4 ++++ src/common/exprdefs.h | 5 +++-- src/ld65/expr.c | 4 ++++ 7 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/ca65/expr.c b/src/ca65/expr.c index 982bb05c6..8703b2a55 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -1865,6 +1865,28 @@ ExprNode* GenWordExpr (ExprNode* Expr) +ExprNode* GenNearAddrExpr (ExprNode* Expr) +/* A word sized expression that will error if given a far expression at assemble time. */ +{ + long Val; + /* Special handling for const expressions */ + if (IsEasyConst (Expr, &Val)) { + FreeExpr (Expr); + Expr = GenLiteralExpr (Val & 0xFFFF); + if (Val > 0xFFFF) + { + Error("Range error: constant too large for assumed near address."); + } + } else { + ExprNode* Operand = Expr; + Expr = NewExprNode (EXPR_NEARADDR); + Expr->Left = Operand; + } + return Expr; +} + + + ExprNode* GenFarAddrExpr (ExprNode* Expr) /* Force the given expression into a far address and return the result. */ { diff --git a/src/ca65/expr.h b/src/ca65/expr.h index 03c2c26d8..16dffd901 100644 --- a/src/ca65/expr.h +++ b/src/ca65/expr.h @@ -109,6 +109,9 @@ ExprNode* GenByteExpr (ExprNode* Expr); ExprNode* GenWordExpr (ExprNode* Expr); /* Force the given expression into a word and return the result. */ +ExprNode* GenNearAddrExpr (ExprNode* Expr); +/* A word sized expression that will error if given a far expression at assemble time. */ + ExprNode* GenFarAddrExpr (ExprNode* Expr); /* Force the given expression into a far address and return the result. */ diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 532a8748e..58011eb8f 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -1217,7 +1217,7 @@ static void EmitCode (EffAddr* A) ** mode, force this address into 16 bit range to allow ** addressing inside a 64K segment. */ - Emit2 (A->Opcode, GenWordExpr (A->Expr)); + Emit2 (A->Opcode, GenNearAddrExpr (A->Expr)); } else { Emit2 (A->Opcode, A->Expr); } diff --git a/src/ca65/studyexpr.c b/src/ca65/studyexpr.c index 90d2d6e18..3aabd3f88 100644 --- a/src/ca65/studyexpr.c +++ b/src/ca65/studyexpr.c @@ -1277,6 +1277,26 @@ static void StudyDWord (ExprNode* Expr, ExprDesc* D) +static void StudyNearAddr (ExprNode* Expr, ExprDesc* D) +/* Study an EXPR_NearAddr expression node */ +{ + /* Study the expression */ + StudyExprInternal (Expr->Left, D); + + /* We can handle only const expressions */ + if (!ED_IsConst (D)) { + ED_Invalidate (D); + } + + /* Promote to absolute if smaller. */ + if (D->AddrSize < ADDR_SIZE_ABS) + { + D->AddrSize = ADDR_SIZE_ABS; + } +} + + + static void StudyExprInternal (ExprNode* Expr, ExprDesc* D) /* Study an expression tree and place the contents into D */ { @@ -1427,6 +1447,10 @@ static void StudyExprInternal (ExprNode* Expr, ExprDesc* D) StudyWord1 (Expr, D); break; + case EXPR_NEARADDR: + StudyNearAddr (Expr, D); + break; + case EXPR_FARADDR: StudyFarAddr (Expr, D); break; diff --git a/src/common/exprdefs.c b/src/common/exprdefs.c index d9a5adf6b..c9db831a2 100644 --- a/src/common/exprdefs.c +++ b/src/common/exprdefs.c @@ -210,6 +210,10 @@ static void InternalDumpExpr (const ExprNode* Expr, const ExprNode* (*ResolveSym printf (" WORD1"); break; + case EXPR_NEARADDR: + printf (" NEARADDR"); + break; + case EXPR_FARADDR: printf (" FARADDR"); break; diff --git a/src/common/exprdefs.h b/src/common/exprdefs.h index 5465c4f25..90da6dff4 100644 --- a/src/common/exprdefs.h +++ b/src/common/exprdefs.h @@ -97,8 +97,9 @@ #define EXPR_BYTE3 (EXPR_UNARYNODE | 0x0B) #define EXPR_WORD0 (EXPR_UNARYNODE | 0x0C) #define EXPR_WORD1 (EXPR_UNARYNODE | 0x0D) -#define EXPR_FARADDR (EXPR_UNARYNODE | 0x0E) -#define EXPR_DWORD (EXPR_UNARYNODE | 0x0F) +#define EXPR_NEARADDR (EXPR_UNARYNODE | 0x0E) +#define EXPR_FARADDR (EXPR_UNARYNODE | 0x0F) +#define EXPR_DWORD (EXPR_UNARYNODE | 0x10) diff --git a/src/ld65/expr.c b/src/ld65/expr.c index 2a08b5a98..482430a19 100644 --- a/src/ld65/expr.c +++ b/src/ld65/expr.c @@ -436,6 +436,10 @@ long GetExprVal (ExprNode* Expr) case EXPR_WORD1: return (GetExprVal (Expr->Left) >> 16) & 0xFFFF; + case EXPR_NEARADDR: + /* Assembler was expected to validate this truncation. */ + return GetExprVal (Expr->Left) & 0xFFFF; + case EXPR_FARADDR: return GetExprVal (Expr->Left) & 0xFFFFFF; From 10cefdb456327cbe0edeb4d7d9fb637d16b3cd5d Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Wed, 1 May 2019 02:50:16 -0400 Subject: [PATCH 1087/2161] move EXPR_NEARADDR to end of enum list to avoid invalidation of existing object binaries? --- src/ca65/studyexpr.c | 8 ++++---- src/common/exprdefs.c | 8 ++++---- src/common/exprdefs.h | 6 +++--- src/ld65/expr.c | 8 ++++---- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/ca65/studyexpr.c b/src/ca65/studyexpr.c index 3aabd3f88..b4260cab7 100644 --- a/src/ca65/studyexpr.c +++ b/src/ca65/studyexpr.c @@ -1447,10 +1447,6 @@ static void StudyExprInternal (ExprNode* Expr, ExprDesc* D) StudyWord1 (Expr, D); break; - case EXPR_NEARADDR: - StudyNearAddr (Expr, D); - break; - case EXPR_FARADDR: StudyFarAddr (Expr, D); break; @@ -1459,6 +1455,10 @@ static void StudyExprInternal (ExprNode* Expr, ExprDesc* D) StudyDWord (Expr, D); break; + case EXPR_NEARADDR: + StudyNearAddr (Expr, D); + break; + default: Internal ("Unknown Op type: %u", Expr->Op); break; diff --git a/src/common/exprdefs.c b/src/common/exprdefs.c index c9db831a2..6639e3d02 100644 --- a/src/common/exprdefs.c +++ b/src/common/exprdefs.c @@ -210,10 +210,6 @@ static void InternalDumpExpr (const ExprNode* Expr, const ExprNode* (*ResolveSym printf (" WORD1"); break; - case EXPR_NEARADDR: - printf (" NEARADDR"); - break; - case EXPR_FARADDR: printf (" FARADDR"); break; @@ -222,6 +218,10 @@ static void InternalDumpExpr (const ExprNode* Expr, const ExprNode* (*ResolveSym printf (" DWORD"); break; + case EXPR_NEARADDR: + printf (" NEARADDR"); + break; + default: AbEnd ("Unknown Op type: %u", Expr->Op); diff --git a/src/common/exprdefs.h b/src/common/exprdefs.h index 90da6dff4..bf2b7a2da 100644 --- a/src/common/exprdefs.h +++ b/src/common/exprdefs.h @@ -97,9 +97,9 @@ #define EXPR_BYTE3 (EXPR_UNARYNODE | 0x0B) #define EXPR_WORD0 (EXPR_UNARYNODE | 0x0C) #define EXPR_WORD1 (EXPR_UNARYNODE | 0x0D) -#define EXPR_NEARADDR (EXPR_UNARYNODE | 0x0E) -#define EXPR_FARADDR (EXPR_UNARYNODE | 0x0F) -#define EXPR_DWORD (EXPR_UNARYNODE | 0x10) +#define EXPR_FARADDR (EXPR_UNARYNODE | 0x0E) +#define EXPR_DWORD (EXPR_UNARYNODE | 0x0F) +#define EXPR_NEARADDR (EXPR_UNARYNODE | 0x10) diff --git a/src/ld65/expr.c b/src/ld65/expr.c index 482430a19..bc3d7941c 100644 --- a/src/ld65/expr.c +++ b/src/ld65/expr.c @@ -436,16 +436,16 @@ long GetExprVal (ExprNode* Expr) case EXPR_WORD1: return (GetExprVal (Expr->Left) >> 16) & 0xFFFF; - case EXPR_NEARADDR: - /* Assembler was expected to validate this truncation. */ - return GetExprVal (Expr->Left) & 0xFFFF; - case EXPR_FARADDR: return GetExprVal (Expr->Left) & 0xFFFFFF; case EXPR_DWORD: return GetExprVal (Expr->Left) & 0xFFFFFFFF; + case EXPR_NEARADDR: + /* Assembler was expected to validate this truncation. */ + return GetExprVal (Expr->Left) & 0xFFFF; + default: Internal ("Unknown expression Op type: %u", Expr->Op); /* NOTREACHED */ From 7d14cff6bb0499ad95ced05b6133cb3c1e896240 Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Wed, 1 May 2019 03:21:14 -0400 Subject: [PATCH 1088/2161] o65.c: missed a link time resolution of EXPR_NEARADDR --- src/ld65/o65.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ld65/o65.c b/src/ld65/o65.c index e36f40d36..5e10ae6f4 100644 --- a/src/ld65/o65.c +++ b/src/ld65/o65.c @@ -633,7 +633,8 @@ static unsigned O65WriteExpr (ExprNode* E, int Signed, unsigned Size, if (E->Op == EXPR_BYTE0 || E->Op == EXPR_BYTE1 || E->Op == EXPR_BYTE2 || E->Op == EXPR_BYTE3 || E->Op == EXPR_WORD0 || E->Op == EXPR_WORD1 || - E->Op == EXPR_FARADDR || E->Op == EXPR_DWORD) { + E->Op == EXPR_FARADDR || E->Op == EXPR_DWORD || + E->Op == EXPR_NEARADDR) { /* Use the real expression */ Expr = E->Left; } @@ -678,6 +679,7 @@ static unsigned O65WriteExpr (ExprNode* E, int Signed, unsigned Size, case EXPR_WORD1: BinVal = (BinVal >> 16) & 0xFFFF; break; case EXPR_FARADDR: BinVal &= 0xFFFFFFUL; break; case EXPR_DWORD: BinVal &= 0xFFFFFFFFUL; break; + case EXPR_NEARADDR: BinVal &= 0xFFFF; break; } WriteVal (D->F, BinVal, Size); From 9299e550a522aa191053c454c0f69f9649ea73c3 Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Wed, 1 May 2019 03:59:05 -0400 Subject: [PATCH 1089/2161] fix NearAddr case in comment --- src/ca65/studyexpr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ca65/studyexpr.c b/src/ca65/studyexpr.c index b4260cab7..6d8734c9e 100644 --- a/src/ca65/studyexpr.c +++ b/src/ca65/studyexpr.c @@ -1278,7 +1278,7 @@ static void StudyDWord (ExprNode* Expr, ExprDesc* D) static void StudyNearAddr (ExprNode* Expr, ExprDesc* D) -/* Study an EXPR_NearAddr expression node */ +/* Study an EXPR_NEARADDR expression node */ { /* Study the expression */ StudyExprInternal (Expr->Left, D); From c2f3421deeede90f53ea18dcb399c3d645c5edf9 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Tue, 14 May 2019 18:15:27 +0300 Subject: [PATCH 1090/2161] Document using inline asm with SoA, structs with array members --- doc/cc65.sgml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 11b112f6f..24634ea3f 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1448,10 +1448,16 @@ Or, to access a struct member of a static variable: unsigned char x; unsigned char y; unsigned char color; + unsigned char aux[32]; } pixel_t; static pixel_t pixel; __asm__ ("ldy #%b", offsetof(pixel_t, color)); __asm__ ("lda %v,y", pixel); + + /* or to access an array member */ + static unsigned char i; + __asm__ ("ldy %v", i); + __asm__ ("lda %v+%b,y", pixel, offsetof(pixel_t, aux)); </verb></tscreen> <p> The next example shows how to use global variables to exchange data between C From f16ce2228183a686303cf7e8681e1f35ba2dd8e2 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Wed, 15 May 2019 12:02:42 +0300 Subject: [PATCH 1091/2161] doc: Rename aux member to data --- doc/cc65.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24634ea3f..ed3386294 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1448,7 +1448,7 @@ Or, to access a struct member of a static variable: unsigned char x; unsigned char y; unsigned char color; - unsigned char aux[32]; + unsigned char data[32]; } pixel_t; static pixel_t pixel; __asm__ ("ldy #%b", offsetof(pixel_t, color)); @@ -1457,7 +1457,7 @@ Or, to access a struct member of a static variable: /* or to access an array member */ static unsigned char i; __asm__ ("ldy %v", i); - __asm__ ("lda %v+%b,y", pixel, offsetof(pixel_t, aux)); + __asm__ ("lda %v+%b,y", pixel, offsetof(pixel_t, data)); </verb></tscreen> <p> The next example shows how to use global variables to exchange data between C From 0d000bb629ce67386d39a880c0a9e1fdb1fff1a3 Mon Sep 17 00:00:00 2001 From: Brad Smith <bbbradsmith@users.noreply.github.com> Date: Tue, 14 May 2019 19:33:55 -0400 Subject: [PATCH 1092/2161] Document --debug-opt-output and --debug-opt --- doc/cc65.sgml | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index ed3386294..60b60861b 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -84,7 +84,8 @@ Long options: --data-name seg Set the name of the DATA segment --debug Debug mode --debug-info Add debug info to object file - --debug-opt name Debug optimization steps + --debug-opt name Configure optimizations with a file + --debug-opt-output Debug output of each optimization step --dep-target target Use this dependency target --disable-opt name Disable an optimization step --eagerly-inline-funcs Eagerly inline some known functions @@ -193,8 +194,26 @@ Here is a description of all the command line options: <tag><tt>-d, --debug</tt></tag> - Enables debug mode, something that should not be needed for mere - mortals:-) + Enables debug mode, for debugging the behavior of CC65. + + + <tag><tt>--debug-opt name</tt></tag> + + The named file contains a list of specific optimization steps to enable or disable. + Each line contains the name of an optimization step with either a + <tt>+</tt> (enable) or <tt>-</tt> (disable) prefix. + The name <tt>all</tt> can be used to enable or disable all optimizations. + Comment lines may begin with <tt>#</tt> or <tt>;<tt>. + + Use <tt>--list-opt-steps</tt> to generate a complete list of available optimization steps. + + Use <tt>--debug</tt> to see a list of optimizations applied during compilation. + + + <tag><tt>--debug-opt-output</tt></tag> + + For debugging the output of each optimization pass, step by step. + Generates a <tt>name.opt</tt> output listing for each optimized function <tt>name</tt>. <label id="option-dep-target"> From d56e3adf2f94fc162defb6386f4a495fe50a4749 Mon Sep 17 00:00:00 2001 From: Brad Smith <bbbradsmith@users.noreply.github.com> Date: Wed, 15 May 2019 09:22:35 -0400 Subject: [PATCH 1093/2161] CC65 -> cc65 --- doc/cc65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 60b60861b..756d9f891 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -194,7 +194,7 @@ 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. + Enables debug mode, for debugging the behavior of cc65. <tag><tt>--debug-opt name</tt></tag> From 644d623d314f0c6fa62b6ca3031ae8c658c803fc Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 18 May 2019 12:16:52 -0400 Subject: [PATCH 1094/2161] Reset the name of the "current bss segment" before writing bss variables into the output Assembly file. Then, cc65 can notice a single "#pragma bss-name()" at the beginning of the variables list. --- src/cc65/compile.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 9cc7f9641..bf9ada833 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -38,6 +38,7 @@ /* common */ #include "debugflag.h" +#include "segnames.h" #include "version.h" #include "xmalloc.h" #include "xsprintf.h" @@ -419,6 +420,11 @@ void FinishCompile (void) { SymEntry* Entry; + /* Reset the BSS segment name to its default; so that the below strcmp() + ** will work as expected, at the beginning of the list of variables + */ + SetSegName (SEG_BSS, SEGNAME_BSS); + /* Walk over all global symbols: ** - for functions, do clean-up and optimizations ** - generate code for uninitialized global variables From 448aa35f50f5a70c9c16aac1f8d4d64c270f6eef Mon Sep 17 00:00:00 2001 From: Richard Halkyard <rhalkyard@gmail.com> Date: Tue, 21 May 2019 16:06:47 -0500 Subject: [PATCH 1095/2161] Fix realloc() bug in gr65 The pointer to the input buffer was not being updated after a call to realloc(), causing the program to crash if realloc() moved the buffer. --- src/grc65/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/grc65/main.c b/src/grc65/main.c index f6554eada..349b5c110 100644 --- a/src/grc65/main.c +++ b/src/grc65/main.c @@ -861,7 +861,7 @@ static char *filterInput (FILE *F, char *tbl) } if (a == EOF) { tbl[i] = '\0'; - xrealloc (tbl, i + 1); + tbl = xrealloc (tbl, i + 1); break; } if (IsSpace (a)) { From 3a3107b244c8872e3d7848a0da5689fa39d31a62 Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Tue, 14 May 2019 22:47:18 -0400 Subject: [PATCH 1096/2161] Disabling too-aggressive optimization in OptCmp8 Generates incorrect code for some 16-bit cases. See: #895 --- src/cc65/coptcmp.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/cc65/coptcmp.c b/src/cc65/coptcmp.c index 9e9c20502..a82f08d88 100644 --- a/src/cc65/coptcmp.c +++ b/src/cc65/coptcmp.c @@ -885,11 +885,16 @@ unsigned OptCmp8 (CodeSeg* S) ++Changes; } - /* If we have made changes above, we may also remove the compare */ - if (JumpsChanged) { - CS_DelEntry (S, I); - } - + /* "If we have made changes above, we may also remove the compare." + ** + ** Removing the compare was too aggressive. E.g. for 16-bit compares the compiler + ** may generate a branch to a second shared branch that still requires the flag + ** result of the first compare instruction. + ** + **if (JumpsChanged) { + ** CS_DelEntry (S, I); + **} + */ } NextEntry: From 1461ad6fccd3c7317f25158c44122007f106436e Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Thu, 16 May 2019 15:56:09 -0400 Subject: [PATCH 1097/2161] unit test to catch regression of bug #895 --- test/val/bug895.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 test/val/bug895.c diff --git a/test/val/bug895.c b/test/val/bug895.c new file mode 100644 index 000000000..dc9f1cb42 --- /dev/null +++ b/test/val/bug895.c @@ -0,0 +1,81 @@ +/** This test is related to GitHub issue 895 + ** https://github.com/cc65/cc65/issues/895 + ** + ** The OptCmp8 optimization attempts to eliminate an unnecessary + ** comparison and branch when the operands of the comparison are + ** known to be constant at compile time. + ** + ** For 8-bit types it worked well, but for larger types it failed + ** to generate correct code. The bug manifest as a branch on an + ** uninitialized carry flag. + ** + ** This does four tests for each type tested: + ** 1: < with carry clear + ** 2: >= with carry clear + ** 3: < with carry set + ** 4: >= with carry set + */ + +#include "unittest.h" + +signed char sca, scb; +signed int sia, sib; +signed long sla, slb; + +unsigned char uca, ucb; +unsigned int uia, uib; +unsigned long ula, ulb; + +#define OPTCMP8TEST(vara,varb,startb,starta,cmpa,setb,printterm,typename,name) \ + void name ## 1(void) { \ + varb = startb; \ + asm("clc"); \ + vara = starta; \ + if (vara < cmpa) varb = setb; \ + ASSERT_AreEqual(startb, varb, printterm, "Incorrect optimization of " typename " comparison (1: < clc)."); \ + } \ + void name ## 2(void) { \ + varb = startb; \ + asm("sec"); \ + vara = starta; \ + if (vara < cmpa) varb = setb; \ + ASSERT_AreEqual(startb, varb, printterm, "Incorrect optimization of " typename " comparison (2: < sec)."); \ + } \ + void name ## 3(void) { \ + varb = startb; \ + asm("clc"); \ + vara = starta; \ + if (vara >= cmpa) varb = setb; \ + ASSERT_AreEqual(setb, varb, printterm, "Incorrect optimization of " typename " comparison (3: >= clc)."); \ + } \ + void name ## 4(void) { \ + varb = startb; \ + asm("sec"); \ + vara = starta; \ + if (vara >= cmpa) varb = setb; \ + ASSERT_AreEqual(setb, varb, printterm, "Incorrect optimization of " typename " comparison (4: >= sec)."); \ + } + +#define RUNOPTCMP8TEST(name) \ + name ## 1(); \ + name ## 2(); \ + name ## 3(); \ + name ## 4(); + +OPTCMP8TEST(sca,scb,-20,100,50,5,"%d","signed char",signed_char); +OPTCMP8TEST(uca,ucb,20,100,50,5,"%u","unsigned char",unsigned_char); +OPTCMP8TEST(sia,sib,-2000,1000,500,50,"%d","signed int",signed_int); +OPTCMP8TEST(uia,uib,2000,1000,500,50,"%u","unsigned int",unsigned_int); +OPTCMP8TEST(sla,slb,-200000L,100000L,50000L,5000L,"%d","signed long",signed_long); +OPTCMP8TEST(ula,ulb,200000UL,100000UL,50000UL,5000UL,"%u","unsigned long",unsigned_long); + +TEST +{ + RUNOPTCMP8TEST(signed_char); + RUNOPTCMP8TEST(unsigned_char); + RUNOPTCMP8TEST(signed_int); + RUNOPTCMP8TEST(unsigned_int); + RUNOPTCMP8TEST(signed_long); + RUNOPTCMP8TEST(unsigned_long); +} +ENDTEST From df90a005cd4e7e9cfa39e98203bb84c4ab7453e5 Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Thu, 16 May 2019 17:52:33 -0400 Subject: [PATCH 1098/2161] bug895 testing against more permutations of comparison --- test/val/bug895.c | 127 +++++++++++++++++++++++++++------------------- 1 file changed, 76 insertions(+), 51 deletions(-) diff --git a/test/val/bug895.c b/test/val/bug895.c index dc9f1cb42..2ab2a2117 100644 --- a/test/val/bug895.c +++ b/test/val/bug895.c @@ -8,12 +8,6 @@ ** For 8-bit types it worked well, but for larger types it failed ** to generate correct code. The bug manifest as a branch on an ** uninitialized carry flag. - ** - ** This does four tests for each type tested: - ** 1: < with carry clear - ** 2: >= with carry clear - ** 3: < with carry set - ** 4: >= with carry set */ #include "unittest.h" @@ -26,56 +20,87 @@ unsigned char uca, ucb; unsigned int uia, uib; unsigned long ula, ulb; -#define OPTCMP8TEST(vara,varb,startb,starta,cmpa,setb,printterm,typename,name) \ - void name ## 1(void) { \ - varb = startb; \ - asm("clc"); \ - vara = starta; \ - if (vara < cmpa) varb = setb; \ - ASSERT_AreEqual(startb, varb, printterm, "Incorrect optimization of " typename " comparison (1: < clc)."); \ - } \ - void name ## 2(void) { \ - varb = startb; \ - asm("sec"); \ - vara = starta; \ - if (vara < cmpa) varb = setb; \ - ASSERT_AreEqual(startb, varb, printterm, "Incorrect optimization of " typename " comparison (2: < sec)."); \ - } \ - void name ## 3(void) { \ - varb = startb; \ - asm("clc"); \ - vara = starta; \ - if (vara >= cmpa) varb = setb; \ - ASSERT_AreEqual(setb, varb, printterm, "Incorrect optimization of " typename " comparison (3: >= clc)."); \ - } \ - void name ## 4(void) { \ - varb = startb; \ - asm("sec"); \ - vara = starta; \ - if (vara >= cmpa) varb = setb; \ - ASSERT_AreEqual(setb, varb, printterm, "Incorrect optimization of " typename " comparison (4: >= sec)."); \ +#define OPTCMP8TEST_SINGLE(num,cmpop,asmprefix,vara,varb,b0,b1,a0,a1,typename,name) \ + typename name ## _ ## num ## (void) { \ + varb = b0; \ + asm( asmprefix ); \ + vara = a0; \ + if (vara cmpop a1) varb = b1; \ + return varb; \ } -#define RUNOPTCMP8TEST(name) \ - name ## 1(); \ - name ## 2(); \ - name ## 3(); \ - name ## 4(); +#define OPTCMP8TEST_VERIFY(num,b,desc,printterm,name) \ + ASSERT_AreEqual(name ## _ ## num ##(),b,printterm,"Incorrect optimization of const comparison (" #name "_" #num ": " desc ")."); -OPTCMP8TEST(sca,scb,-20,100,50,5,"%d","signed char",signed_char); -OPTCMP8TEST(uca,ucb,20,100,50,5,"%u","unsigned char",unsigned_char); -OPTCMP8TEST(sia,sib,-2000,1000,500,50,"%d","signed int",signed_int); -OPTCMP8TEST(uia,uib,2000,1000,500,50,"%u","unsigned int",unsigned_int); -OPTCMP8TEST(sla,slb,-200000L,100000L,50000L,5000L,"%d","signed long",signed_long); -OPTCMP8TEST(ula,ulb,200000UL,100000UL,50000UL,5000UL,"%u","unsigned long",unsigned_long); +/* Generates a set of comparison tests for one type and set of test values. +** name = a name for this test (no spaces) +** typename = the type used +** b0 = result if comparison is false +** b1 = result if comparison is true +** a0 = a low value to use for the comparison tests (a0 < a1) +** a1 = a high value to use for the comparison tests (a0 < a1) +** vara = temporary variable of the type to be examined +** varb = temporary variable of the type to be examined +** printterm = printf term to display the variable type +*/ +#define OPTCMP8TEST(name,typename,b0,b1,a0,a1,vara,varb,printterm) \ + OPTCMP8TEST_SINGLE(1,<,"clc",vara,varb,b0,b1,a0,a1,typename,name); \ + OPTCMP8TEST_SINGLE(2,<,"sec",vara,varb,b0,b1,a0,a1,typename,name); \ + OPTCMP8TEST_SINGLE(3,<,"clc",vara,varb,b0,b1,a1,a0,typename,name); \ + OPTCMP8TEST_SINGLE(4,<,"sec",vara,varb,b0,b1,a1,a0,typename,name); \ + OPTCMP8TEST_SINGLE(5,>,"clc",vara,varb,b0,b1,a0,a1,typename,name); \ + OPTCMP8TEST_SINGLE(6,>,"sec",vara,varb,b0,b1,a0,a1,typename,name); \ + OPTCMP8TEST_SINGLE(7,>,"clc",vara,varb,b0,b1,a1,a0,typename,name); \ + OPTCMP8TEST_SINGLE(8,>,"sec",vara,varb,b0,b1,a1,a0,typename,name); \ + OPTCMP8TEST_SINGLE(9,<=,"clc",vara,varb,b0,b1,a0,a1,typename,name); \ + OPTCMP8TEST_SINGLE(10,<=,"sec",vara,varb,b0,b1,a0,a1,typename,name); \ + OPTCMP8TEST_SINGLE(11,<=,"clc",vara,varb,b0,b1,a1,a0,typename,name); \ + OPTCMP8TEST_SINGLE(12,<=,"sec",vara,varb,b0,b1,a1,a0,typename,name); \ + OPTCMP8TEST_SINGLE(13,>=,"clc",vara,varb,b0,b1,a0,a1,typename,name); \ + OPTCMP8TEST_SINGLE(14,>=,"sec",vara,varb,b0,b1,a0,a1,typename,name); \ + OPTCMP8TEST_SINGLE(15,>=,"clc",vara,varb,b0,b1,a1,a0,typename,name); \ + OPTCMP8TEST_SINGLE(16,>=,"sec",vara,varb,b0,b1,a1,a0,typename,name); \ + OPTCMP8TEST_SINGLE(17,==,"nop",vara,varb,b0,b1,a0,a1,typename,name); \ + OPTCMP8TEST_SINGLE(18,==,"nop",vara,varb,b0,b1,a1,a1,typename,name); \ + OPTCMP8TEST_SINGLE(19,!=,"nop",vara,varb,b0,b1,a0,a1,typename,name); \ + OPTCMP8TEST_SINGLE(20,!=,"nop",vara,varb,b0,b1,a1,a1,typename,name); \ + void name ## _ ## test(void) { \ + OPTCMP8TEST_VERIFY(1,b1,"low < high, clc",printterm,name); \ + OPTCMP8TEST_VERIFY(2,b1,"low < high, sec",printterm,name); \ + OPTCMP8TEST_VERIFY(3,b0,"high < low, clc",printterm,name); \ + OPTCMP8TEST_VERIFY(4,b0,"high < low, sec",printterm,name); \ + OPTCMP8TEST_VERIFY(5,b0,"low > high, clc",printterm,name); \ + OPTCMP8TEST_VERIFY(6,b0,"low > high, sec",printterm,name); \ + OPTCMP8TEST_VERIFY(7,b1,"high > low, clc",printterm,name); \ + OPTCMP8TEST_VERIFY(8,b1,"high > low, sec",printterm,name); \ + OPTCMP8TEST_VERIFY(9,b1,"low <= high, clc",printterm,name); \ + OPTCMP8TEST_VERIFY(10,b1,"low <= high, sec",printterm,name); \ + OPTCMP8TEST_VERIFY(11,b0,"high <= low, clc",printterm,name); \ + OPTCMP8TEST_VERIFY(12,b0,"high <= low, sec",printterm,name); \ + OPTCMP8TEST_VERIFY(13,b0,"low >= high, clc",printterm,name); \ + OPTCMP8TEST_VERIFY(14,b0,"low >= high, sec",printterm,name); \ + OPTCMP8TEST_VERIFY(15,b1,"high >= low, clc",printterm,name); \ + OPTCMP8TEST_VERIFY(16,b1,"high >= low, sec",printterm,name); \ + OPTCMP8TEST_VERIFY(17,b0,"low == high, nop",printterm,name); \ + OPTCMP8TEST_VERIFY(18,b1,"high == high, nop",printterm,name); \ + OPTCMP8TEST_VERIFY(19,b1,"low != high, nop",printterm,name); \ + OPTCMP8TEST_VERIFY(20,b0,"high != high, nop",printterm,name); \ + } + +OPTCMP8TEST(signed_char,signed char,-20,5,60,100,sca,scb,"%d"); +OPTCMP8TEST(unsigned_char,unsigned char,20,5,60,100,uca,ucb,"%u"); +OPTCMP8TEST(signed_int,signed int,-2000,50,600,1000,sia,sib,"%d"); +OPTCMP8TEST(unsigned_int,unsigned int,2000,50,600,1000,uia,uib,"%u"); +OPTCMP8TEST(signed_long,signed long,-200000L,5000L,60000L,100000L,sla,slb,"%d"); +OPTCMP8TEST(unsigned_long,unsigned long,200000UL,5000UL,60000UL,100000UL,ula,ulb,"%u"); TEST { - RUNOPTCMP8TEST(signed_char); - RUNOPTCMP8TEST(unsigned_char); - RUNOPTCMP8TEST(signed_int); - RUNOPTCMP8TEST(unsigned_int); - RUNOPTCMP8TEST(signed_long); - RUNOPTCMP8TEST(unsigned_long); + signed_char_test(); + unsigned_char_test(); + signed_int_test(); + unsigned_int_test(); + signed_long_test(); + unsigned_long_test(); } ENDTEST From 7a863e5cda78ccb82a50c49a239727288f31ae57 Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Thu, 16 May 2019 18:01:44 -0400 Subject: [PATCH 1099/2161] bug895 test: more specific description comment --- test/val/bug895.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/val/bug895.c b/test/val/bug895.c index 2ab2a2117..c4892d7b1 100644 --- a/test/val/bug895.c +++ b/test/val/bug895.c @@ -1,13 +1,13 @@ /** This test is related to GitHub issue 895 ** https://github.com/cc65/cc65/issues/895 ** - ** The OptCmp8 optimization attempts to eliminate an unnecessary + ** The OptCmp8 optimization attempted to eliminate an unnecessary ** comparison and branch when the operands of the comparison are ** known to be constant at compile time. ** - ** For 8-bit types it worked well, but for larger types it failed - ** to generate correct code. The bug manifest as a branch on an - ** uninitialized carry flag. + ** For 8-bit types it worked well, but for 16-bit types it failed + ** to generate correct code for some cases. The bug manifest as a + ** branch on an uninitialized carry flag. */ #include "unittest.h" From 4642421da44a99d90197f8c225f609fdc6418b7e Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Fri, 24 May 2019 23:51:22 -0400 Subject: [PATCH 1100/2161] are more specific version of the comparison removal #895 --- src/cc65/coptcmp.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/cc65/coptcmp.c b/src/cc65/coptcmp.c index a82f08d88..dbc71bcd5 100644 --- a/src/cc65/coptcmp.c +++ b/src/cc65/coptcmp.c @@ -819,6 +819,7 @@ unsigned OptCmp8 (CodeSeg* S) /* We are able to evaluate the compare at compile time. Check if ** one or more branches are ahead. */ + unsigned ProtectCompare = 0; unsigned JumpsChanged = 0; CodeEntry* N; while ((N = CS_GetNextEntry (S, I)) != 0 && /* Followed by something.. */ @@ -878,6 +879,21 @@ unsigned OptCmp8 (CodeSeg* S) CodeEntry* X = NewCodeEntry (OP65_JMP, AM65_BRA, LabelName, L, N->LI); CS_InsertEntry (S, X, I+2); CS_DelEntry (S, I+1); + /* Normally we can remove the compare as well, + ** but some comparisons generate code with a + ** shared branch operation. This prevents the unsafe + ** removal of the compare for known problem cases. + */ + if ( + /* Jump to branch that relies on the comparison. */ + (L->Owner->Info & (OF_CBRA | OF_ZBRA)) || + /* Jump to boolean transformer that relies on the comparison. */ + (L->Owner->OPC == OP65_JSR && + (FindBoolCmpCond (L->Owner->Arg)) != CMP_INV) + ) + { + ++ProtectCompare; + } } /* Remember, we had changes */ @@ -885,16 +901,10 @@ unsigned OptCmp8 (CodeSeg* S) ++Changes; } - /* "If we have made changes above, we may also remove the compare." - ** - ** Removing the compare was too aggressive. E.g. for 16-bit compares the compiler - ** may generate a branch to a second shared branch that still requires the flag - ** result of the first compare instruction. - ** - **if (JumpsChanged) { - ** CS_DelEntry (S, I); - **} - */ + /* Delete the original compare, if safe to do so. */ + if (JumpsChanged && !ProtectCompare) { + CS_DelEntry (S, I); + } } NextEntry: From 69c7acb3bcb428c943e1bbfb108fa67352bdb671 Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Sat, 25 May 2019 02:56:53 -0400 Subject: [PATCH 1101/2161] some documentation for sim65 --- doc/sim65.sgml | 59 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 0739ea2f1..99fdc1886 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -7,7 +7,7 @@ <abstract> sim65 is a simulator for 6502 and 65C02 CPUs. It allows to test target -independed code. +independent code. </abstract> <!-- Table of contents --> @@ -18,8 +18,8 @@ independed code. <sect>Overview<p> -sim65 is the only solution as part of the toolchain to execute code. The -binary needs to be compiled with <tt/--target sim6502/ or <tt/--target sim65c02/. +sim65 is used as part of the toolchain to test 6502 or 65C02 code. +The binary to test needs to be compiled with <tt/--target sim6502/ or <tt/--target sim65c02/. <sect>Usage<p> @@ -104,6 +104,59 @@ PVExit ($01) </verb></tscreen> +<sect>Creating a Test in C<p> + +For a C test compiled and linked with <tt/--target sim65/ the +command line arguments to <tt/sim65/ will be passed to <tt/main/, +and the return value from <tt/main/ will become sim65's exit code. +The <tt/exit/ function may also be used to terminate with an exit code. + +Exit codes are limited to 8 bits. + +In addition to this, the simulator provides a set of built-in functions +for simple file input and output: + +<tscreen><verb> + int open (const char* name, int flags, ...); + int __fastcall__ close (int fd); + int __fastcall__ read (int fd, void* buf, unsigned count); + int __fastcall__ write (int fd, const void* buf, unsigned count); +</verb></tscreen> + + +<sect>Creating a Test in Assembly<p> + +Assembly tests may similarly be assembled ant linked with <tt/--target sim65/, +and the sim65 library provides an <tt/exit/ symbol that the program may <tt/JMP/ +to terminate with the current A register value as an exit code. + +Without using the provided target library, there are some relevant internal details: + +<itemize> + +<item>The binary input file has a 1 byte header. A value of 0 indicates 6502 simulation, +and 1 indicates 65C02. + +<item>The rest of the input file, after the header, will be loaded at <tt/$0200/, +and execution will begin at <tt/$0200/. + +<item>The entire 64 kilobyte address space is writeable RAM. +Aside from the loaded binary, the reset vector at <tt/$FFFC/ will be +pre-loaded with <tt/$0200/ as the start address. + +<item>The <tt/exit/ address is <tt/$FFF1/. +Jumping to this address will terminate execution with the A register value as an exit code. + +<item>The built-in functions are provided by 6 "paravirtualization" hooks present at +<tt/$FFF0-$FFF5/. Except for <tt/exit/, a <tt/JSR/ to one of these +addresses will return immediately after performing a special function, +intended only for use with the sim65 target C library. + +<item><tt/IRQ/ and <tt/NMI/ events will not be generated, though <tt/BRK/ +can be used if the IRQ vector at <tt/$FFFE/ is manually prepared by the test code. + +</itemize> + <sect>Copyright<p> From 17505e2173da792764fdcc8f9a8f1c4202d04ead Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Sat, 25 May 2019 03:00:44 -0400 Subject: [PATCH 1102/2161] sim65.sgml noting sim65c02 target as well --- doc/sim65.sgml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 99fdc1886..9cc5921a0 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -19,7 +19,7 @@ independent code. sim65 is used as part of the toolchain to test 6502 or 65C02 code. -The binary to test needs to be compiled with <tt/--target sim6502/ or <tt/--target sim65c02/. +The binary to test should be compiled with <tt/--target sim6502/ or <tt/--target sim65c02/. <sect>Usage<p> @@ -126,7 +126,8 @@ for simple file input and output: <sect>Creating a Test in Assembly<p> -Assembly tests may similarly be assembled ant linked with <tt/--target sim65/, +Assembly tests may similarly be assembled and linked with +<tt/--target sim65/ or <tt/--target sim65c02>, and the sim65 library provides an <tt/exit/ symbol that the program may <tt/JMP/ to terminate with the current A register value as an exit code. From 42beb29f72fedf45a518f4c4c259b3cf92d03bb6 Mon Sep 17 00:00:00 2001 From: Brad Smith <bbbradsmith@users.noreply.github.com> Date: Sat, 25 May 2019 04:12:43 -0400 Subject: [PATCH 1103/2161] sim65.sgml syntax error unclosed tt --- doc/sim65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 9cc5921a0..d7ac91e4d 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -127,7 +127,7 @@ for simple file input and output: <sect>Creating a Test in Assembly<p> Assembly tests may similarly be assembled and linked with -<tt/--target sim65/ or <tt/--target sim65c02>, +<tt/--target sim65/ or <tt/--target sim65c02/, and the sim65 library provides an <tt/exit/ symbol that the program may <tt/JMP/ to terminate with the current A register value as an exit code. From 4acf011fa4141cc05c5079debb5b51532415295b Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Sat, 25 May 2019 13:42:13 -0400 Subject: [PATCH 1104/2161] noting that standard file functions work as well correcting target name --- doc/sim65.sgml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index d7ac91e4d..39fadad94 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -106,14 +106,18 @@ PVExit ($01) <sect>Creating a Test in C<p> -For a C test compiled and linked with <tt/--target sim65/ the +For a C test compiled and linked with <tt/--target sim6502/ the command line arguments to <tt/sim65/ will be passed to <tt/main/, and the return value from <tt/main/ will become sim65's exit code. The <tt/exit/ function may also be used to terminate with an exit code. Exit codes are limited to 8 bits. -In addition to this, the simulator provides a set of built-in functions +The standard C library file input and output is functional, +with <tt/STDIN_FILENO/, <tt/STDOUT_FILENO/ and <tt/STDERR_FILENO/ mapped to sim65's +STDIN_FILENO, STDOUT_FILENO and STDERR_FILENO. + +These utilize an underlying set of built-in virtual functions for simple file input and output: <tscreen><verb> @@ -127,7 +131,7 @@ for simple file input and output: <sect>Creating a Test in Assembly<p> Assembly tests may similarly be assembled and linked with -<tt/--target sim65/ or <tt/--target sim65c02/, +<tt/--target sim6502/ or <tt/--target sim65c02/, and the sim65 library provides an <tt/exit/ symbol that the program may <tt/JMP/ to terminate with the current A register value as an exit code. @@ -148,7 +152,7 @@ pre-loaded with <tt/$0200/ as the start address. <item>The <tt/exit/ address is <tt/$FFF1/. Jumping to this address will terminate execution with the A register value as an exit code. -<item>The built-in functions are provided by 6 "paravirtualization" hooks present at +<item>The built-in functions are provided by 6 paravirtualization hooks present at <tt/$FFF0-$FFF5/. Except for <tt/exit/, a <tt/JSR/ to one of these addresses will return immediately after performing a special function, intended only for use with the sim65 target C library. From 53bfd2e8cdba448e095111a88d2ca59843b39e80 Mon Sep 17 00:00:00 2001 From: Brad Smith <bbbradsmith@users.noreply.github.com> Date: Sat, 25 May 2019 23:38:18 -0400 Subject: [PATCH 1105/2161] added name --- doc/sim65.sgml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 39fadad94..a6be5a14f 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -3,7 +3,9 @@ <article> <title>sim65 Users Guide -<author><url url="mailto:polluks@sdf.lonestar.org" name="Stefan A. Haubenthal"> +<author><url url="mailto:polluks@sdf.lonestar.org" name="Stefan A. Haubenthal">,<newline> +<url url="mailto:bbbradsmith@users.noreply.github.com" name="Brad Smith"> + <abstract> sim65 is a simulator for 6502 and 65C02 CPUs. It allows to test target From 26d436b90d1dc7fee4b178965f1430458b399ebf Mon Sep 17 00:00:00 2001 From: Brad Smith <bbbradsmith@users.noreply.github.com> Date: Mon, 27 May 2019 14:57:31 -0400 Subject: [PATCH 1106/2161] separating standard file I/O from low-level paravirtualization --- doc/sim65.sgml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index a6be5a14f..ff66079a1 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -115,12 +115,11 @@ The <tt/exit/ function may also be used to terminate with an exit code. Exit codes are limited to 8 bits. -The standard C library file input and output is functional, -with <tt/STDIN_FILENO/, <tt/STDOUT_FILENO/ and <tt/STDERR_FILENO/ mapped to sim65's -STDIN_FILENO, STDOUT_FILENO and STDERR_FILENO. +The standard C library high level file input and output is functional, +and can be used like a command line application in sim65. -These utilize an underlying set of built-in virtual functions -for simple file input and output: +Lower level file input and output is provided by +a set of built-in paravirtualization functions: <tscreen><verb> int open (const char* name, int flags, ...); @@ -129,6 +128,10 @@ for simple file input and output: int __fastcall__ write (int fd, const void* buf, unsigned count); </verb></tscreen> +These built-in functions can be used with +<tt/STDIN_FILENO/, <tt/STDOUT_FILENO/ and <tt/STDERR_FILENO/ +which are mapped to sim65's corresponding file descriptors. + <sect>Creating a Test in Assembly<p> From 38d2eb7a0e4127bd02b8bac35f98b5729e42f9f1 Mon Sep 17 00:00:00 2001 From: Brad Smith <bbbradsmith@users.noreply.github.com> Date: Wed, 29 May 2019 16:22:42 -0400 Subject: [PATCH 1107/2161] cc65.sgml incorrectly closed tt --- doc/cc65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 756d9f891..86b61ae4f 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -203,7 +203,7 @@ Here is a description of all the command line options: Each line contains the name of an optimization step with either a <tt>+</tt> (enable) or <tt>-</tt> (disable) prefix. The name <tt>all</tt> can be used to enable or disable all optimizations. - Comment lines may begin with <tt>#</tt> or <tt>;<tt>. + Comment lines may begin with <tt>#</tt> or <tt>;</tt>. Use <tt>--list-opt-steps</tt> to generate a complete list of available optimization steps. From 2f3cae0d2e32b29bf7064a4d63ffd3609434d934 Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Tue, 28 May 2019 15:29:55 -0400 Subject: [PATCH 1108/2161] movable sp for sim65 --- cfg/sim6502.cfg | 2 +- cfg/sim65c02.cfg | 2 +- doc/sim65.sgml | 7 ++++--- libsrc/sim6502/exehdr.s | 5 ++++- src/common/version.c | 2 +- src/sim65/main.c | 17 +++++++++++++---- src/sim65/paravirt.c | 14 ++++++++------ src/sim65/paravirt.h | 2 +- 8 files changed, 33 insertions(+), 18 deletions(-) diff --git a/cfg/sim6502.cfg b/cfg/sim6502.cfg index 530787489..546671641 100644 --- a/cfg/sim6502.cfg +++ b/cfg/sim6502.cfg @@ -4,7 +4,7 @@ SYMBOLS { } MEMORY { ZP: file = "", start = $0000, size = $001B; - HEADER: file = %O, start = $0000, size = $0001; + HEADER: file = %O, start = $0000, size = $0002; MAIN: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; } SEGMENTS { diff --git a/cfg/sim65c02.cfg b/cfg/sim65c02.cfg index 530787489..546671641 100644 --- a/cfg/sim65c02.cfg +++ b/cfg/sim65c02.cfg @@ -4,7 +4,7 @@ SYMBOLS { } MEMORY { ZP: file = "", start = $0000, size = $001B; - HEADER: file = %O, start = $0000, size = $0001; + HEADER: file = %O, start = $0000, size = $0002; MAIN: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; } SEGMENTS { diff --git a/doc/sim65.sgml b/doc/sim65.sgml index ff66079a1..6f197f518 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -144,8 +144,9 @@ Without using the provided target library, there are some relevant internal deta <itemize> -<item>The binary input file has a 1 byte header. A value of 0 indicates 6502 simulation, -and 1 indicates 65C02. +<item>The binary input file has a 2 byte header. The first byte indicates CPU type: + 0 = 6502, 1 = 65C02. The second byte is the address of the C parameter stack pointer + <tt/sp/, used by the paravirtualization functions. <item>The rest of the input file, after the header, will be loaded at <tt/$0200/, and execution will begin at <tt/$0200/. @@ -160,7 +161,7 @@ Jumping to this address will terminate execution with the A register value as an <item>The built-in functions are provided by 6 paravirtualization hooks present at <tt/$FFF0-$FFF5/. Except for <tt/exit/, a <tt/JSR/ to one of these addresses will return immediately after performing a special function, -intended only for use with the sim65 target C library. +intended for use with the sim65 target C library. <item><tt/IRQ/ and <tt/NMI/ events will not be generated, though <tt/BRK/ can be used if the IRQ vector at <tt/$FFFE/ is manually prepared by the test code. diff --git a/libsrc/sim6502/exehdr.s b/libsrc/sim6502/exehdr.s index 865bd6553..d10cf3763 100644 --- a/libsrc/sim6502/exehdr.s +++ b/libsrc/sim6502/exehdr.s @@ -1,11 +1,14 @@ ; ; Oliver Schmidt, 2013-05-16 ; -; This module supplies a 1 byte header identifying the simulator type +; This module supplies a 2 byte header identifying the simulator type, +; and parameter stack pointer sp. ; .export __EXEHDR__ : absolute = 1 ; Linker referenced + .importzp sp .segment "EXEHDR" .byte .defined(__SIM65C02__) + .byte sp diff --git a/src/common/version.c b/src/common/version.c index 1f1e8093e..c76a39933 100644 --- a/src/common/version.c +++ b/src/common/version.c @@ -47,7 +47,7 @@ #define VER_MAJOR 2U -#define VER_MINOR 17U +#define VER_MINOR 18U diff --git a/src/sim65/main.c b/src/sim65/main.c index a1bbc5561..03803a1bf 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -132,11 +132,12 @@ static void OptQuitXIns (const char* Opt attribute ((unused)), MaxCycles = strtoul(Arg, NULL, 0); } -static void ReadProgramFile (void) +static unsigned char ReadProgramFile (void) /* Load program into memory */ { int Val; unsigned Addr = 0x0200; + unsigned char SPAddr = 0x0000; /* Open the file */ FILE* F = fopen (ProgramFile, "rb"); @@ -152,6 +153,11 @@ static void ReadProgramFile (void) CPU = Val; } + /* Get the address of sp from the file header */ + if ((Val = fgetc(F)) != EOF) { + SPAddr = Val; + } + /* Read the file body into memory */ while ((Val = fgetc(F)) != EOF) { if (Addr == 0xFF00) { @@ -169,6 +175,8 @@ static void ReadProgramFile (void) fclose (F); Print (stderr, 1, "Loaded '%s' at $0200-$%04X\n", ProgramFile, Addr - 1); + + return SPAddr; } @@ -184,6 +192,7 @@ int main (int argc, char* argv[]) }; unsigned I; + unsigned char SPAddr; /* Initialize the cmdline module */ InitCmdLine (&argc, &argv, "sim65"); @@ -243,11 +252,11 @@ int main (int argc, char* argv[]) AbEnd ("No program file"); } - ParaVirtInit (I); - MemInit (); - ReadProgramFile (); + SPAddr = ReadProgramFile (); + + ParaVirtInit (I, SPAddr); Reset (); diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 55caeeb94..b03767c5a 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -77,6 +77,7 @@ typedef void (*PVFunc) (CPURegs* Regs); static unsigned ArgStart; +static unsigned char SPAddr; @@ -120,9 +121,9 @@ static unsigned char Pop (CPURegs* Regs) static unsigned PopParam (unsigned char Incr) { - unsigned SP = MemReadZPWord (0x00); + unsigned SP = MemReadZPWord (SPAddr); unsigned Val = MemReadWord (SP); - MemWriteWord (0x0000, SP + Incr); + MemWriteWord (SPAddr, SP + Incr); return Val; } @@ -132,7 +133,7 @@ static void PVArgs (CPURegs* Regs) { unsigned ArgC = ArgCount - ArgStart; unsigned ArgV = GetAX (Regs); - unsigned SP = MemReadZPWord (0x00); + unsigned SP = MemReadZPWord (SPAddr); unsigned Args = SP - (ArgC + 1) * 2; Print (stderr, 2, "PVArgs ($%04X)\n", ArgV); @@ -152,9 +153,9 @@ static void PVArgs (CPURegs* Regs) MemWriteWord (Args, SP); Args += 2; } - MemWriteWord (Args, 0x0000); + MemWriteWord (Args, SPAddr); - MemWriteWord (0x0000, SP); + MemWriteWord (SPAddr, SP); SetAX (Regs, ArgC); } @@ -313,10 +314,11 @@ static const PVFunc Hooks[] = { -void ParaVirtInit (unsigned aArgStart) +void ParaVirtInit (unsigned aArgStart, unsigned char aSPAddr) /* Initialize the paravirtualization subsystem */ { ArgStart = aArgStart; + SPAddr = aSPAddr; }; diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 34317b49f..cd4915398 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -44,7 +44,7 @@ -void ParaVirtInit (unsigned aArgStart); +void ParaVirtInit (unsigned aArgStart, unsigned char aSPAddr); /* Initialize the paravirtualization subsystem */ void ParaVirtHooks (CPURegs* Regs); From 07ca77293296018d71a4b1e51d84bd80fd8afceb Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Tue, 28 May 2019 15:38:27 -0400 Subject: [PATCH 1109/2161] adjust literal width to match variable type --- src/sim65/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sim65/main.c b/src/sim65/main.c index 03803a1bf..d3f507f64 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -137,7 +137,7 @@ static unsigned char ReadProgramFile (void) { int Val; unsigned Addr = 0x0200; - unsigned char SPAddr = 0x0000; + unsigned char SPAddr = 0x00; /* Open the file */ FILE* F = fopen (ProgramFile, "rb"); From fb7d4acd5c42ab190b876c9c966fbf4ce0126a9e Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Wed, 29 May 2019 16:04:54 -0400 Subject: [PATCH 1110/2161] versionable header for sim65 load and run address now configured from header fix error codes not to conflict with test fix test/misc/endless.c which is supposed to fail if an endless loop does not occur --- cfg/sim6502.cfg | 2 +- cfg/sim65c02.cfg | 2 +- doc/sim65.sgml | 29 +++++++++++++++------- libsrc/sim6502/crt0.s | 2 ++ libsrc/sim6502/exehdr.s | 10 ++++++-- src/sim65/error.c | 18 ++++++++++++-- src/sim65/error.h | 17 +++++++++++++ src/sim65/main.c | 55 +++++++++++++++++++++++++++++++++++------ src/sim65/memory.c | 17 ++++++++----- src/sim65/memory.h | 5 +++- src/sim65/paravirt.c | 9 ------- test/misc/endless.c | 2 +- 12 files changed, 129 insertions(+), 39 deletions(-) diff --git a/cfg/sim6502.cfg b/cfg/sim6502.cfg index 546671641..c768ab4a3 100644 --- a/cfg/sim6502.cfg +++ b/cfg/sim6502.cfg @@ -4,7 +4,7 @@ SYMBOLS { } MEMORY { ZP: file = "", start = $0000, size = $001B; - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $000C; MAIN: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; } SEGMENTS { diff --git a/cfg/sim65c02.cfg b/cfg/sim65c02.cfg index 546671641..c768ab4a3 100644 --- a/cfg/sim65c02.cfg +++ b/cfg/sim65c02.cfg @@ -4,7 +4,7 @@ SYMBOLS { } MEMORY { ZP: file = "", start = $0000, size = $001B; - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $000C; MAIN: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; } SEGMENTS { diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 6f197f518..0c3687e2b 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -140,28 +140,39 @@ Assembly tests may similarly be assembled and linked with and the sim65 library provides an <tt/exit/ symbol that the program may <tt/JMP/ to terminate with the current A register value as an exit code. -Without using the provided target library, there are some relevant internal details: +The binary file has a 12 byte header: <itemize> -<item>The binary input file has a 2 byte header. The first byte indicates CPU type: - 0 = 6502, 1 = 65C02. The second byte is the address of the C parameter stack pointer - <tt/sp/, used by the paravirtualization functions. +<item>5 byte **signature**: <tt/$73, $69, $6D, $36, $35/ or <tt/'sim65'/ -<item>The rest of the input file, after the header, will be loaded at <tt/$0200/, -and execution will begin at <tt/$0200/. +<item>1 byte **version**: <tt/2/ + +<item>1 byte **CPU type**: <tt/0/ = 6502, <tt/1/ = 65C02 + +<item>1 byte **sp address**: the zero page address of the C parameter stack pointer <tt/sp/ used by the paravirtualization functions + +<item>1 word **load address**: where to load the data from the file into memory (default: <tt/$0200/) + +<item>1 word **reset address**: specifies where to begin execution after loading (default: <tt/$0200/) + +</itemize> + +Other internal details: + +<itemize> <item>The entire 64 kilobyte address space is writeable RAM. Aside from the loaded binary, the reset vector at <tt/$FFFC/ will be -pre-loaded with <tt/$0200/ as the start address. +pre-loaded with the given **reset address**. <item>The <tt/exit/ address is <tt/$FFF1/. Jumping to this address will terminate execution with the A register value as an exit code. <item>The built-in functions are provided by 6 paravirtualization hooks present at <tt/$FFF0-$FFF5/. Except for <tt/exit/, a <tt/JSR/ to one of these -addresses will return immediately after performing a special function, -intended for use with the sim65 target C library. +addresses will return immediately after performing a special function. +These use cc65 calling conventions, and are intended for use with the sim65 target C library. <item><tt/IRQ/ and <tt/NMI/ events will not be generated, though <tt/BRK/ can be used if the IRQ vector at <tt/$FFFE/ is manually prepared by the test code. diff --git a/libsrc/sim6502/crt0.s b/libsrc/sim6502/crt0.s index bd02f0e42..848b7044f 100644 --- a/libsrc/sim6502/crt0.s +++ b/libsrc/sim6502/crt0.s @@ -5,6 +5,7 @@ ; .export _exit + .export sim65start .export __STARTUP__ : absolute = 1 ; Mark as startup .import zerobss, callmain .import initlib, donelib @@ -16,6 +17,7 @@ .segment "STARTUP" +sim65start: cld ldx #$FF txs diff --git a/libsrc/sim6502/exehdr.s b/libsrc/sim6502/exehdr.s index d10cf3763..875562216 100644 --- a/libsrc/sim6502/exehdr.s +++ b/libsrc/sim6502/exehdr.s @@ -7,8 +7,14 @@ .export __EXEHDR__ : absolute = 1 ; Linker referenced .importzp sp + .import __MAIN_START__ + .import sim65start .segment "EXEHDR" - .byte .defined(__SIM65C02__) - .byte sp + .byte $73, $69, $6D, $36, $35 ; 'sim65' + .byte 2 ; header version + .byte .defined(__SIM65C02__) ; CPU type + .byte sp ; sp address + .addr __MAIN_START__ ; load address + .addr sim65start ; reset address diff --git a/src/sim65/error.c b/src/sim65/error.c index 3114951af..30d90c700 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -69,7 +69,21 @@ void Error (const char* Format, ...) vfprintf (stderr, Format, ap); putc ('\n', stderr); va_end (ap); - exit (EXIT_FAILURE); + exit (SIM65_ERROR); +} + + + +void ErrorCode (int Code, const char* Format, ...) +/* Print an error message and die with the given exit code */ +{ + va_list ap; + va_start (ap, Format); + fprintf (stderr, "Error: "); + vfprintf (stderr, Format, ap); + putc ('\n', stderr); + va_end (ap); + exit (Code); } @@ -83,5 +97,5 @@ void Internal (const char* Format, ...) vfprintf (stderr, Format, ap); putc ('\n', stderr); va_end (ap); - exit (EXIT_FAILURE); + exit (SIM65_ERROR); } diff --git a/src/sim65/error.h b/src/sim65/error.h index 7bee4954c..5d6e8be21 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -43,6 +43,20 @@ +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +#define SIM65_ERROR 256 +/* Does not use EXIT_FAILURE because it may overlap with test results. */ + +#define SIM65_ERROR_TIMEOUT 257 +/* An error result for max CPU instructions exceeded. */ + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -55,6 +69,9 @@ void Warning (const char* Format, ...) attribute((format(printf,1,2))); void Error (const char* Format, ...) attribute((noreturn, format(printf,1,2))); /* Print an error message and die */ +void ErrorCode (int Code, const char* Format, ...) attribute((noreturn, format(printf,2,3))); +/* Print an error message and die with the given exit code */ + void Internal (const char* Format, ...) attribute((noreturn, format(printf,1,2))); /* Print an internal error message and die */ diff --git a/src/sim65/main.c b/src/sim65/main.c index d3f507f64..4c931a51f 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -63,6 +63,16 @@ const char* ProgramFile; /* exit simulator after MaxCycles Cycles */ unsigned long MaxCycles; +/* Header signature 'sim65' */ +static const unsigned char HeaderSignature[] = { + 0x73, 0x69, 0x6D, 0x36, 0x35 +}; +#define HEADER_SIGNATURE_LENGTH (sizeof(HeaderSignature)/sizeof(HeaderSignature[0])) + +static const unsigned char HeaderVersion = 2; + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -135,8 +145,11 @@ static void OptQuitXIns (const char* Opt attribute ((unused)), static unsigned char ReadProgramFile (void) /* Load program into memory */ { - int Val; - unsigned Addr = 0x0200; + unsigned I; + int Val, Val2; + int Version; + unsigned Addr; + unsigned Load, Reset; unsigned char SPAddr = 0x00; /* Open the file */ @@ -145,6 +158,18 @@ static unsigned char ReadProgramFile (void) Error ("Cannot open '%s': %s", ProgramFile, strerror (errno)); } + /* Verify the header signature */ + for (I=0; I<HEADER_SIGNATURE_LENGTH; ++I) { + if ((Val = fgetc(F)) != HeaderSignature[I]) { + Error ("'%s': Invalid header signature.", ProgramFile); + } + } + + /* Get header version */ + if ((Version = fgetc(F)) != HeaderVersion) { + Error ("'%s': Invalid header version.", ProgramFile); + } + /* Get the CPU type from the file header */ if ((Val = fgetc(F)) != EOF) { if (Val != CPU_6502 && Val != CPU_65C02) { @@ -158,10 +183,25 @@ static unsigned char ReadProgramFile (void) SPAddr = Val; } + /* Get load address */ + if (((Val = fgetc(F)) == EOF) || + ((Val2 = fgetc(F)) == EOF)) { + Error ("'%s': Header missing load address", ProgramFile); + } + Load = Val | (Val2 << 8); + + /* Get reset address */ + if (((Val = fgetc(F)) == EOF) || + ((Val2 = fgetc(F)) == EOF)) { + Error ("'%s': Header missing reset address", ProgramFile); + } + Reset = Val | (Val2 << 8); + /* Read the file body into memory */ + Addr = Load; while ((Val = fgetc(F)) != EOF) { if (Addr == 0xFF00) { - Error ("'%s': To large to fit into $0200-$FFF0", ProgramFile); + Error ("'%s': To large to fit into $%04X-$FFF0", ProgramFile, Addr); } MemWriteByte (Addr++, (unsigned char) Val); } @@ -174,8 +214,11 @@ static unsigned char ReadProgramFile (void) /* Close the file */ fclose (F); - Print (stderr, 1, "Loaded '%s' at $0200-$%04X\n", ProgramFile, Addr - 1); + Print (stderr, 1, "Loaded '%s' at $%04X-$%04X\n", ProgramFile, Load, Addr - 1); + Print (stderr, 1, "File version: %d\n", Version); + Print (stderr, 1, "Reset: $%04X\n", Reset); + MemWriteWord(0xFFFC, Reset); return SPAddr; } @@ -263,9 +306,7 @@ int main (int argc, char* argv[]) while (1) { ExecuteInsn (); if (MaxCycles && (GetCycles () >= MaxCycles)) { - Error ("Maximum number of cycles reached."); - exit (-99); /* do not use EXIT_FAILURE to avoid conflicts with the - same value being used in a test program */ + ErrorCode (SIM65_ERROR_TIMEOUT, "Maximum number of cycles reached."); } } diff --git a/src/sim65/memory.c b/src/sim65/memory.c index 305b26a73..11f0be55a 100644 --- a/src/sim65/memory.c +++ b/src/sim65/memory.c @@ -64,6 +64,15 @@ void MemWriteByte (unsigned Addr, unsigned char Val) +void MemWriteWord (unsigned Addr, unsigned Val) +/* Write a word to a memory location */ +{ + MemWriteByte (Addr, Val & 0xFF); + MemWriteByte (Addr + 1, Val >> 8); +} + + + unsigned char MemReadByte (unsigned Addr) /* Read a byte from a memory location */ { @@ -82,7 +91,7 @@ unsigned MemReadWord (unsigned Addr) unsigned MemReadZPWord (unsigned char Addr) -/* Read a word from the zero page. This function differs from ReadMemW in that +/* 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. */ @@ -96,10 +105,6 @@ unsigned MemReadZPWord (unsigned char Addr) void MemInit (void) /* Initialize the memory subsystem */ { - /* Fill momory with illegal opcode */ + /* Fill memory with illegal opcode */ memset (Mem, 0xFF, sizeof (Mem)); - - /* Set RESET vector to 0x0200 */ - Mem[0xFFFC] = 0x00; - Mem[0xFFFD] = 0x02; } diff --git a/src/sim65/memory.h b/src/sim65/memory.h index 5de3a2bb8..41cc800d3 100644 --- a/src/sim65/memory.h +++ b/src/sim65/memory.h @@ -47,6 +47,9 @@ void MemWriteByte (unsigned Addr, unsigned char Val); /* Write a byte to a memory location */ +void MemWriteWord (unsigned Addr, unsigned Val); +/* Write a word to a memory location */ + unsigned char MemReadByte (unsigned Addr); /* Read a byte from a memory location */ @@ -54,7 +57,7 @@ unsigned MemReadWord (unsigned Addr); /* Read a word from a memory location */ unsigned MemReadZPWord (unsigned char Addr); -/* Read a word from the zero page. This function differs from ReadMemW in that +/* 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. */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index b03767c5a..5abae9091 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -103,15 +103,6 @@ static void SetAX (CPURegs* Regs, unsigned Val) -static void MemWriteWord (unsigned Addr, unsigned Val) -{ - MemWriteByte (Addr, Val); - Val >>= 8; - MemWriteByte (Addr + 1, Val); -} - - - static unsigned char Pop (CPURegs* Regs) { return MemReadByte (0x0100 + ++Regs->SP); diff --git a/test/misc/endless.c b/test/misc/endless.c index fe0782941..f637d1f22 100644 --- a/test/misc/endless.c +++ b/test/misc/endless.c @@ -9,5 +9,5 @@ int main(void) ; } printf("error: should not come here\n"); - return EXIT_FAILURE; + return EXIT_SUCCESS; /* test verifies failure, not success */ } From 3612edf4fa93f038a883d3ab3e362d402e932487 Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Wed, 29 May 2019 16:14:48 -0400 Subject: [PATCH 1111/2161] sim65.sgml typo: bold is bf not ** --- doc/sim65.sgml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 0c3687e2b..075f6cbe2 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -144,17 +144,17 @@ The binary file has a 12 byte header: <itemize> -<item>5 byte **signature**: <tt/$73, $69, $6D, $36, $35/ or <tt/'sim65'/ +<item>5 byte <bf/signature/: <tt/$73, $69, $6D, $36, $35/ or <tt/'sim65'/ -<item>1 byte **version**: <tt/2/ +<item>1 byte <bf/version/: <tt/2/ -<item>1 byte **CPU type**: <tt/0/ = 6502, <tt/1/ = 65C02 +<item>1 byte <bf/CPU type/: <tt/0/ = 6502, <tt/1/ = 65C02 -<item>1 byte **sp address**: the zero page address of the C parameter stack pointer <tt/sp/ used by the paravirtualization functions +<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 word **load address**: where to load the data from the file into memory (default: <tt/$0200/) +<item>1 word <bf/load address/: where to load the data from the file into memory (default: <tt/$0200/) -<item>1 word **reset address**: specifies where to begin execution after loading (default: <tt/$0200/) +<item>1 word <bf/reset address/: specifies where to begin execution after loading (default: <tt/$0200/) </itemize> @@ -164,7 +164,7 @@ Other internal details: <item>The entire 64 kilobyte address space is writeable RAM. Aside from the loaded binary, the reset vector at <tt/$FFFC/ will be -pre-loaded with the given **reset address**. +pre-loaded with the given <bf/reset address/. <item>The <tt/exit/ address is <tt/$FFF1/. Jumping to this address will terminate execution with the A register value as an exit code. From 9fcd91ebe96f07edc9f09c54fdcb3d6a2eb390ee Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Wed, 29 May 2019 16:32:44 -0400 Subject: [PATCH 1112/2161] sim65 header comment fix --- libsrc/sim6502/exehdr.s | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libsrc/sim6502/exehdr.s b/libsrc/sim6502/exehdr.s index 875562216..297caa85f 100644 --- a/libsrc/sim6502/exehdr.s +++ b/libsrc/sim6502/exehdr.s @@ -1,8 +1,7 @@ ; ; Oliver Schmidt, 2013-05-16 ; -; This module supplies a 2 byte header identifying the simulator type, -; and parameter stack pointer sp. +; This module supplies a header used by sim65. ; .export __EXEHDR__ : absolute = 1 ; Linker referenced From 7e4c4ee53eaf2adbe006c9ed2cc21c8242fdab50 Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Wed, 29 May 2019 16:47:58 -0400 Subject: [PATCH 1113/2161] sim65/main.c spaces were requested --- src/sim65/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sim65/main.c b/src/sim65/main.c index 4c931a51f..bcd436a13 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -159,7 +159,7 @@ static unsigned char ReadProgramFile (void) } /* Verify the header signature */ - for (I=0; I<HEADER_SIGNATURE_LENGTH; ++I) { + for (I = 0; I < HEADER_SIGNATURE_LENGTH; ++I) { if ((Val = fgetc(F)) != HeaderSignature[I]) { Error ("'%s': Invalid header signature.", ProgramFile); } From c6bbea0bb0b760952c2e17f2f571b790682daa1b Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 30 May 2019 00:06:31 +0200 Subject: [PATCH 1114/2161] Renamed program start label. --- libsrc/sim6502/crt0.s | 5 ++--- libsrc/sim6502/exehdr.s | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/libsrc/sim6502/crt0.s b/libsrc/sim6502/crt0.s index 848b7044f..c04a2b8a6 100644 --- a/libsrc/sim6502/crt0.s +++ b/libsrc/sim6502/crt0.s @@ -5,7 +5,7 @@ ; .export _exit - .export sim65start + .export startup .export __STARTUP__ : absolute = 1 ; Mark as startup .import zerobss, callmain .import initlib, donelib @@ -17,8 +17,7 @@ .segment "STARTUP" -sim65start: - cld +startup:cld ldx #$FF txs lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) diff --git a/libsrc/sim6502/exehdr.s b/libsrc/sim6502/exehdr.s index 297caa85f..09d099da5 100644 --- a/libsrc/sim6502/exehdr.s +++ b/libsrc/sim6502/exehdr.s @@ -7,7 +7,7 @@ .export __EXEHDR__ : absolute = 1 ; Linker referenced .importzp sp .import __MAIN_START__ - .import sim65start + .import startup .segment "EXEHDR" @@ -16,4 +16,4 @@ .byte .defined(__SIM65C02__) ; CPU type .byte sp ; sp address .addr __MAIN_START__ ; load address - .addr sim65start ; reset address + .addr startup ; reset address From 6efb71bea773837c6fc4aae0c8270b2d70e3e69f Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 30 May 2019 00:10:17 +0200 Subject: [PATCH 1115/2161] Rearranged paravirt function vector. - exit right below 6502 vectors. - keep exit addr stable as it may be called from asm. --- doc/sim65.sgml | 7 +------ libsrc/sim6502/paravirt.s | 14 +++++++------- src/sim65/paravirt.c | 34 +++++++++++++++++----------------- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 075f6cbe2..8a7329b0b 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -166,14 +166,9 @@ Other internal details: Aside from the loaded binary, the reset vector at <tt/$FFFC/ will be pre-loaded with the given <bf/reset address/. -<item>The <tt/exit/ address is <tt/$FFF1/. +<item>The <tt/exit/ address is <tt/$FFF9/. Jumping to this address will terminate execution with the A register value as an exit code. -<item>The built-in functions are provided by 6 paravirtualization hooks present at -<tt/$FFF0-$FFF5/. Except for <tt/exit/, a <tt/JSR/ to one of these -addresses will return immediately after performing a special function. -These use cc65 calling conventions, and are intended for use with the sim65 target C library. - <item><tt/IRQ/ and <tt/NMI/ events will not be generated, though <tt/BRK/ can be used if the IRQ vector at <tt/$FFFE/ is manually prepared by the test code. diff --git a/libsrc/sim6502/paravirt.s b/libsrc/sim6502/paravirt.s index 81b655c73..0d8e528b1 100644 --- a/libsrc/sim6502/paravirt.s +++ b/libsrc/sim6502/paravirt.s @@ -7,11 +7,11 @@ ; int __fastcall__ write (int fd, const void* buf, unsigned count); ; - .export args, exit, _open, _close, _read, _write + .export exit, args, _open, _close, _read, _write -args := $FFF0 -exit := $FFF1 -_open := $FFF2 -_close := $FFF3 -_read := $FFF4 -_write := $FFF5 +_open := $FFF4 +_close := $FFF5 +_read := $FFF6 +_write := $FFF7 +args := $FFF8 +exit := $FFF9 diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 5abae9091..c9f6e61b0 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -120,6 +120,18 @@ static unsigned PopParam (unsigned char Incr) +static void PVExit (CPURegs* Regs) +{ + Print (stderr, 1, "PVExit ($%02X)\n", Regs->AC); + if (PrintCycles) { + Print (stdout, 0, "%lu cycles\n", GetCycles ()); + } + + exit (Regs->AC); +} + + + static void PVArgs (CPURegs* Regs) { unsigned ArgC = ArgCount - ArgStart; @@ -152,18 +164,6 @@ static void PVArgs (CPURegs* Regs) -static void PVExit (CPURegs* Regs) -{ - Print (stderr, 1, "PVExit ($%02X)\n", Regs->AC); - if (PrintCycles) { - Print (stdout, 0, "%lu cycles\n", GetCycles ()); - } - - exit (Regs->AC); -} - - - static void PVOpen (CPURegs* Regs) { char Path[1024]; @@ -295,12 +295,12 @@ static void PVWrite (CPURegs* Regs) static const PVFunc Hooks[] = { - PVArgs, - PVExit, PVOpen, PVClose, PVRead, PVWrite, + PVArgs, + PVExit, }; @@ -318,13 +318,13 @@ void ParaVirtHooks (CPURegs* Regs) /* Potentially execute paravirtualization hooks */ { /* Check for paravirtualization address range */ - if (Regs->PC < 0xFFF0 || - Regs->PC >= 0xFFF0 + sizeof (Hooks) / sizeof (Hooks[0])) { + if (Regs->PC < 0xFFF4 || + Regs->PC >= 0xFFF4 + sizeof (Hooks) / sizeof (Hooks[0])) { return; } /* Call paravirtualization hook */ - Hooks[Regs->PC - 0xFFF0] (Regs); + Hooks[Regs->PC - 0xFFF4] (Regs); /* Simulate RTS */ Regs->PC = Pop(Regs) + (Pop(Regs) << 8) + 1; From 52695523465cb8bc72a0728b1f5b46ffc3eb2eef Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Thu, 30 May 2019 15:34:05 -0400 Subject: [PATCH 1116/2161] sim65 common define for paravirt hooks base location allows the loaded binary to take up as much space as possible restored some documentation of the hooks but without reference to specific location --- doc/sim65.sgml | 25 ++++++++++--------------- src/sim65/main.c | 4 ++-- src/sim65/paravirt.c | 6 +++--- src/sim65/paravirt.h | 11 +++++++++++ 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 8a7329b0b..075d95849 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -115,22 +115,12 @@ The <tt/exit/ function may also be used to terminate with an exit code. Exit codes are limited to 8 bits. -The standard C library high level file input and output is functional, -and can be used like a command line application in sim65. +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 <tt/main/ and using the <tt/stdio.h/ interfaces. -Lower level file input and output is provided by -a set of built-in paravirtualization functions: - -<tscreen><verb> - int open (const char* name, int flags, ...); - int __fastcall__ close (int fd); - int __fastcall__ read (int fd, void* buf, unsigned count); - int __fastcall__ write (int fd, const void* buf, unsigned count); -</verb></tscreen> - -These built-in functions can be used with -<tt/STDIN_FILENO/, <tt/STDOUT_FILENO/ and <tt/STDERR_FILENO/ -which are mapped to sim65's corresponding file descriptors. +Internally, file input and output is provided at a lower level by +a set of built-in paravirtualization functions (<ref id="paravirt-internal" name="see below">). <sect>Creating a Test in Assembly<p> @@ -169,6 +159,11 @@ pre-loaded with the given <bf/reset address/. <item>The <tt/exit/ address is <tt/$FFF9/. Jumping to this address will terminate execution with the A register value as an exit code. +<label id="paravirt-internal"> +<item>Several bytes immediately below the vector table are reserved for paravirtualization functions. +Except for <tt/exit/, a <tt/JSR/ to one of these addresses will return immediately after performing a special function. +These use cc65 calling conventions, and are intended for use with the sim65 target C library. + <item><tt/IRQ/ and <tt/NMI/ events will not be generated, though <tt/BRK/ can be used if the IRQ vector at <tt/$FFFE/ is manually prepared by the test code. diff --git a/src/sim65/main.c b/src/sim65/main.c index bcd436a13..f2daf9295 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -200,8 +200,8 @@ static unsigned char ReadProgramFile (void) /* Read the file body into memory */ Addr = Load; while ((Val = fgetc(F)) != EOF) { - if (Addr == 0xFF00) { - Error ("'%s': To large to fit into $%04X-$FFF0", ProgramFile, Addr); + if (Addr >= PARAVIRT_BASE) { + Error ("'%s': To large to fit into $%04X-$%04X", ProgramFile, Addr, PARAVIRT_BASE); } MemWriteByte (Addr++, (unsigned char) Val); } diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index c9f6e61b0..603a07e9a 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -318,13 +318,13 @@ void ParaVirtHooks (CPURegs* Regs) /* Potentially execute paravirtualization hooks */ { /* Check for paravirtualization address range */ - if (Regs->PC < 0xFFF4 || - Regs->PC >= 0xFFF4 + sizeof (Hooks) / sizeof (Hooks[0])) { + if (Regs->PC < PARAVIRT_BASE || + Regs->PC >= PARAVIRT_BASE + sizeof (Hooks) / sizeof (Hooks[0])) { return; } /* Call paravirtualization hook */ - Hooks[Regs->PC - 0xFFF4] (Regs); + Hooks[Regs->PC - PARAVIRT_BASE] (Regs); /* Simulate RTS */ Regs->PC = Pop(Regs) + (Pop(Regs) << 8) + 1; diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index cd4915398..99c28fa02 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -38,6 +38,17 @@ +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +#define PARAVIRT_BASE 0xFFF4 +/* Lowest address used by a paravirtualization hook */ + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ From e34ee329738b5b8f54e62e7dd63deff5e1088bff Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 4 Jun 2019 11:43:07 +0200 Subject: [PATCH 1117/2161] Reduced shadow for h2 to improve readability. --- doc/doc.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/doc.css b/doc/doc.css index 232599a75..e4c316e16 100644 --- a/doc/doc.css +++ b/doc/doc.css @@ -26,7 +26,7 @@ h1 { h2 { font-size: 160%; - text-shadow: 2px 2px 6px #303030; + text-shadow: 1px 1px 3px #303030; letter-spacing: 1px; margin-top: 2em; margin-bottom: 1em; From 83e0c70de509e0be2825fae1deadfcefb6366270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org> Date: Sun, 9 Jun 2019 01:19:53 +0200 Subject: [PATCH 1118/2161] Replace GIT_SHA with a more versatile BUILD_ID definition. When compiling cc65, it will by default place the git hash (if available) of the checked out commit in the version string. This isn't useful when building a package for a Linux distribution, since there either won't be an upstream git hash if there is one at all. Thus we replace GIT_SHA with a more versatile BUILD_ID, which can be defined to any arbitrary string. When building, its contents will be appended to the version string instead of the git hash. If BUILD_ID is not defined by the user the behaviour will be exactly the same as before. That means BUILD_ID gets automatically defined to Git <GIT_SHA>, if it can be determined from a checkout. --- src/Makefile | 14 +++++++------- src/common/version.c | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Makefile b/src/Makefile index c93a8645f..bbf594aa4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -52,13 +52,13 @@ ifdef USER_CFLAGS $(info USER_CFLAGS: $(USER_CFLAGS)) endif -ifdef GIT_SHA - $(info GIT_SHA: $(GIT_SHA)) +ifdef BUILD_ID + $(info BUILD_ID: $(BUILD_ID)) else - GIT_SHA := $(shell git rev-parse --short HEAD 2>$(NULLDEV) || svnversion 2>$(NULLDEV)) - ifneq ($(words $(GIT_SHA)),1) - GIT_SHA := N/A - $(info GIT_SHA: N/A) + BUILD_ID := Git $(shell git rev-parse --short HEAD 2>$(NULLDEV) || svnversion 2>$(NULLDEV)) + ifneq ($(words $(BUILD_ID)),2) + BUILD_ID := N/A + $(info BUILD_ID: N/A) endif endif @@ -66,7 +66,7 @@ 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)" \ - -DGIT_SHA=$(GIT_SHA) + -DBUILD_ID="$(BUILD_ID)" LDLIBS += -lm diff --git a/src/common/version.c b/src/common/version.c index c76a39933..202c61cc3 100644 --- a/src/common/version.c +++ b/src/common/version.c @@ -61,8 +61,8 @@ const char* GetVersionAsString (void) /* Returns the version number as a string in a static buffer */ { static char Buf[60]; -#if defined(GIT_SHA) - xsnprintf (Buf, sizeof (Buf), "%u.%u - Git %s", VER_MAJOR, VER_MINOR, STRINGIZE (GIT_SHA)); +#if defined(BUILD_ID) + xsnprintf (Buf, sizeof (Buf), "%u.%u - %s", VER_MAJOR, VER_MINOR, STRINGIZE (BUILD_ID)); #else xsnprintf (Buf, sizeof (Buf), "%u.%u", VER_MAJOR, VER_MINOR); #endif From 9faca05e6a028915bc4d6e3b2e5993bdf1fc1ada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org> Date: Sun, 9 Jun 2019 17:46:31 +0200 Subject: [PATCH 1119/2161] test/ref/otccex: Fix ramdomly occurring segfault. The variables named tab and p are used in the context of pointers and thus must be declared as such. Determining the purpose they serve, using char over int seems more feasible here as well. --- test/ref/otccex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/ref/otccex.c b/test/ref/otccex.c index aa5df158f..645078ef0 100644 --- a/test/ref/otccex.c +++ b/test/ref/otccex.c @@ -58,7 +58,7 @@ long fact(n) /* Well, we could use printf, but it would be too easy */ print_num(long n,int b) { - int tab, p, c; + char *tab, *p, c; /* Numbers can be entered in decimal, hexadecimal ('0x' prefix) and octal ('0' prefix) */ /* more complex programs use malloc */ @@ -71,7 +71,7 @@ print_num(long n,int b) c = c + 'a' - 10; else c = c + '0'; - *(char *)p = c; + *p = c; p++; n = n / b; /* 'break' is supported */ From e0ac9d5d8e843c0a14f22da0ba1922ae18bccbb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org> Date: Sun, 9 Jun 2019 21:07:33 +0200 Subject: [PATCH 1120/2161] util/zlib/deflater: Fix several compiler warnings. --- util/zlib/deflater.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/zlib/deflater.c b/util/zlib/deflater.c index 32d01a36e..7e13600ad 100644 --- a/util/zlib/deflater.c +++ b/util/zlib/deflater.c @@ -16,8 +16,8 @@ int main(int argc, char* argv[]) { FILE* fp; - char* inbuf; - char* outbuf; + unsigned char* inbuf; + unsigned char* outbuf; size_t inlen; size_t outlen; z_stream stream; @@ -84,7 +84,7 @@ int main(int argc, char* argv[]) } /* display summary */ - printf("Compressed %s (%d bytes) to %s (%d bytes)\n", + printf("Compressed %s (%zu bytes) to %s (%zu bytes)\n", argv[1], inlen, argv[2], outlen); return 0; } From 93b6efcb2f969c6de0fd1eca5b07dbce18046c0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org> Date: Sat, 15 Jun 2019 06:53:27 +0200 Subject: [PATCH 1121/2161] zlib: Use correct (un)signedness of char in prototypes and functions. Also ensure we are using the same constness qualifiers. --- include/zlib.h | 7 ++++--- libsrc/zlib/inflatemem.s | 3 ++- libsrc/zlib/uncompress.c | 9 ++++----- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/include/zlib.h b/include/zlib.h index 8ced89800..3f6c2b27b 100644 --- a/include/zlib.h +++ b/include/zlib.h @@ -48,7 +48,8 @@ #define Z_NULL 0 -unsigned __fastcall__ inflatemem (char* dest, const char* source); +unsigned __fastcall__ inflatemem (unsigned char* dest, + const unsigned char* source); /* Decompresses the source buffer into the destination buffer. Returns the size of the uncompressed data (number of bytes written starting @@ -83,8 +84,8 @@ unsigned __fastcall__ inflatemem (char* dest, const char* source); */ -int __fastcall__ uncompress (char* dest, unsigned* destLen, - const char* source, unsigned sourceLen); +int __fastcall__ uncompress (unsigned char* dest, unsigned* destLen, + const unsigned char* source, unsigned sourceLen); /* Original zlib description: diff --git a/libsrc/zlib/inflatemem.s b/libsrc/zlib/inflatemem.s index bc89f2016..80c19f223 100644 --- a/libsrc/zlib/inflatemem.s +++ b/libsrc/zlib/inflatemem.s @@ -1,7 +1,8 @@ ; ; 2017-11-07, Piotr Fusik ; -; unsigned __fastcall__ inflatemem (char* dest, const char* source); +; unsigned __fastcall__ inflatemem (unsigned char* dest, +; const unsigned char* source); ; ; NOTE: Be extremely careful with modifications, because this code is heavily ; optimized for size (for example assumes certain register and flag values diff --git a/libsrc/zlib/uncompress.c b/libsrc/zlib/uncompress.c index 4e449a3ef..61838b47d 100644 --- a/libsrc/zlib/uncompress.c +++ b/libsrc/zlib/uncompress.c @@ -6,11 +6,11 @@ #include <zlib.h> -int __fastcall__ uncompress (char* dest, unsigned* destLen, - const char* source, unsigned sourceLen) +int __fastcall__ uncompress (unsigned char* dest, unsigned* destLen, + const unsigned char* source, unsigned sourceLen) { unsigned len; - unsigned char* ptr; + const unsigned char* ptr = source + sourceLen - 4; unsigned long csum; /* source[0]: Compression method and flags bits 0 to 3: Compression method (must be Z_DEFLATED) @@ -22,10 +22,9 @@ int __fastcall__ uncompress (char* dest, unsigned* destLen, */ if ((source[0] & 0x8f) != Z_DEFLATED || source[1] & 0x20) return Z_DATA_ERROR; - if ((((unsigned) source[0] << 8) | (unsigned char) source[1]) % 31) + if ((((unsigned) source[0] << 8) | source[1]) % 31) return Z_DATA_ERROR; *destLen = len = inflatemem(dest, source + 2); - ptr = (unsigned char*) source + sourceLen - 4; csum = adler32(adler32(0L, Z_NULL, 0), dest, len); if ((unsigned char) csum != ptr[3] || (unsigned char) (csum >> 8) != ptr[2] From 28584b31f1b3560173c16487f45aad23dc6f9fb5 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 30 Jun 2019 22:44:10 -0400 Subject: [PATCH 1122/2161] Made the ld65 configure file's segment offset attribute accept zero as a value. Expressions are allowed as values. Therefore, zero might be set explicitly by some conditions. --- src/ld65/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ld65/config.c b/src/ld65/config.c index f8bff2ac0..b8699a87b 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -732,7 +732,7 @@ static void ParseSegments (void) case CFGTOK_OFFSET: FlagAttr (&S->Attr, SA_OFFSET, "OFFSET"); - S->Addr = CfgCheckedConstExpr (1, 0x1000000); + S->Addr = CfgCheckedConstExpr (0, 0x1000000); S->Flags |= SF_OFFSET; break; From 9be25dab9ce05434978ff16fd1761f3502bbd03e Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 15 Jul 2019 12:29:09 +0200 Subject: [PATCH 1123/2161] Minor URL update. --- samples/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Makefile b/samples/Makefile index 6c94495f5..ad81c2474 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -90,7 +90,7 @@ ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),) # For this one, see https://applecommander.github.io/ AC ?= ac.jar - # For this one, see http://www.horus.com/~hias/atari/ + # For this one, see https://www.horus.com/~hias/atari/ DIR2ATR ?= dir2atr DISK_c64 = samples.d64 From 2f3955dbc7fe97e4415231bc0204c5a4a3a9447b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org> Date: Sun, 14 Jul 2019 09:28:49 +0200 Subject: [PATCH 1124/2161] src/Makefile: Simplify BUILD_ID logic. --- src/Makefile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Makefile b/src/Makefile index bbf594aa4..87f1e8236 100644 --- a/src/Makefile +++ b/src/Makefile @@ -52,15 +52,13 @@ ifdef USER_CFLAGS $(info USER_CFLAGS: $(USER_CFLAGS)) endif -ifdef BUILD_ID - $(info BUILD_ID: $(BUILD_ID)) -else +ifndef BUILD_ID BUILD_ID := Git $(shell git rev-parse --short HEAD 2>$(NULLDEV) || svnversion 2>$(NULLDEV)) ifneq ($(words $(BUILD_ID)),2) BUILD_ID := N/A - $(info BUILD_ID: N/A) endif endif +$(info BUILD_ID: $(BUILD_ID)) CFLAGS += -MMD -MP -O3 -I common \ -Wall -Wextra -Wno-char-subscripts $(USER_CFLAGS) \ From 88c6dd2da81c10eb36bdc76f236ef3d428d9312e Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 16 Jul 2019 13:16:02 -0400 Subject: [PATCH 1125/2161] Changed empty parameter lists into (void) lists on functions with asm() statements. The fix avoids any possible problems with how cc65 will handle old-style (K & R) function declarations, in the future. --- test/val/trampoline-params.c | 2 +- test/val/trampoline-varargs.c | 2 +- test/val/trampoline.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/val/trampoline-params.c b/test/val/trampoline-params.c index c05d8c06d..9dbbba077 100644 --- a/test/val/trampoline-params.c +++ b/test/val/trampoline-params.c @@ -9,7 +9,7 @@ static unsigned char flag; -static void trampoline_set() { +static void trampoline_set(void) { asm("ldy tmp4"); asm("sty %v", flag); asm("jsr callptr4"); diff --git a/test/val/trampoline-varargs.c b/test/val/trampoline-varargs.c index e2db839c8..0e6be49c3 100644 --- a/test/val/trampoline-varargs.c +++ b/test/val/trampoline-varargs.c @@ -9,7 +9,7 @@ static unsigned char flag; -static void trampoline_set() { +static void trampoline_set(void) { // The Y register is used for variadics - save and restore asm("sty tmp3"); diff --git a/test/val/trampoline.c b/test/val/trampoline.c index b2010f6f3..8f1e1547c 100644 --- a/test/val/trampoline.c +++ b/test/val/trampoline.c @@ -7,13 +7,13 @@ static unsigned char flag; -static void trampoline_set() { +static void trampoline_set(void) { asm("ldy tmp4"); asm("sty %v", flag); asm("jsr callptr4"); } -void trampoline_inc() { +void trampoline_inc(void) { asm("inc %v", flag); asm("jsr callptr4"); } @@ -35,7 +35,7 @@ void func1(void); #pragma wrapped-call(pop) #pragma wrapped-call(pop) -void func1() { +void func1(void) { func2(); } From 99de3cb6ea5ae3bfed01cb9139dc68939b3909ef Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 20 Jul 2019 11:28:33 +0200 Subject: [PATCH 1126/2161] Add page 0 variables from Telemon 2.4 --- asminc/telestrat.inc | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index f2eb42ff4..3bd8a1f51 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -119,14 +119,39 @@ RS232T := $59 RS232C := $5A INDRS := $5B +; Float and integer management ACC1E := $60 ACC1M := $61 - ACC1S := $65 +ACC1EX := $66 +ACC1J := $67 +ACC2E := $68 +ACC2M := $69 +ACC2S := $6D +ACCPS := $6E +ACC3 := $6F +ACC4E := $73 +ACC4M := $74 + + +FLDT0 := $74 +FLDT1 := $75 +FLDT2 := $76 +FLSVY := $77 +FLTR0 := $7D +FLTR1 := $7E + +; Menu management +MENDDY := $62 +MENDFY := $63 +MENX := $64 +MENDY := $66 FLGMEN := $68 ADMEN := $69 +FLSGN := $8A +FLINT := $88 FLSVS := $89 FLERR := $8B From 76fe064e03a909be3139cf2daae48d8ded0fe269 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 20 Jul 2019 11:31:00 +0200 Subject: [PATCH 1127/2161] Add XSCROH & XSCROB value --- asminc/telestrat.inc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 3bd8a1f51..3526c6f98 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -266,6 +266,8 @@ XECRPR = $33 ; Displays prompt XCOSCR = $34 ; Switch off cursor XCSSCR = $35 ; Switch on cursor XSCRSE = $36 +XSCROH = $37 ; Scroll up text screen +XSCROB = $38 ; Scroll down text screen XSCRNE = $39 ; Load charset from rom to ram XCLOSE = $3A ; Only in TELEMON 3.x close file (bank 7 of Orix) XFWRITE = $3B ; Only in TELEMON 3.x write file (bank 7 of Orix) From 925ea9d5443949cfd916504a9ed04ada8b750e27 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Tue, 16 Jul 2019 18:39:37 +0300 Subject: [PATCH 1128/2161] cc65: Add support for binary literals Binary literals, 0b001, are a GCC extension in C and a C++14 feature. --- src/cc65/scanner.c | 7 +- test/val/binlit.c | 533 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 538 insertions(+), 2 deletions(-) create mode 100644 test/val/binlit.c diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 695085e94..3e829aabb 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -464,8 +464,8 @@ static void NumericConst (void) unsigned DigitVal; unsigned long IVal; /* Value */ - /* Check for a leading hex or octal prefix and determine the possible - ** integer types. + /* Check for a leading hex, octal or binary prefix and determine the + ** possible integer types. */ if (CurC == '0') { /* Gobble 0 and examine next char */ @@ -473,6 +473,9 @@ static void NumericConst (void) if (toupper (CurC) == 'X') { Base = Prefix = 16; NextChar (); /* gobble "x" */ + } else if (toupper (CurC) == 'B' && IS_Get (&Standard) >= STD_CC65) { + Base = Prefix = 2; + NextChar (); /* gobble 'b' */ } else { Base = 10; /* Assume 10 for now - see below */ Prefix = 8; /* Actual prefix says octal */ diff --git a/test/val/binlit.c b/test/val/binlit.c new file mode 100644 index 000000000..2b6c1ca89 --- /dev/null +++ b/test/val/binlit.c @@ -0,0 +1,533 @@ +static unsigned char small[256]; +static unsigned big[256]; + +int main() { + + unsigned i; + + small[0] = 0b0; + small[1] = 0b1; + small[2] = 0b10; + small[3] = 0b11; + small[4] = 0b100; + small[5] = 0b101; + small[6] = 0b110; + small[7] = 0b111; + small[8] = 0b1000; + small[9] = 0b1001; + small[10] = 0b1010; + small[11] = 0b1011; + small[12] = 0b1100; + small[13] = 0b1101; + small[14] = 0b1110; + small[15] = 0b1111; + small[16] = 0b10000; + small[17] = 0b10001; + small[18] = 0b10010; + small[19] = 0b10011; + small[20] = 0b10100; + small[21] = 0b10101; + small[22] = 0b10110; + small[23] = 0b10111; + small[24] = 0b11000; + small[25] = 0b11001; + small[26] = 0b11010; + small[27] = 0b11011; + small[28] = 0b11100; + small[29] = 0b11101; + small[30] = 0b11110; + small[31] = 0b11111; + small[32] = 0b100000; + small[33] = 0b100001; + small[34] = 0b100010; + small[35] = 0b100011; + small[36] = 0b100100; + small[37] = 0b100101; + small[38] = 0b100110; + small[39] = 0b100111; + small[40] = 0b101000; + small[41] = 0b101001; + small[42] = 0b101010; + small[43] = 0b101011; + small[44] = 0b101100; + small[45] = 0b101101; + small[46] = 0b101110; + small[47] = 0b101111; + small[48] = 0b110000; + small[49] = 0b110001; + small[50] = 0b110010; + small[51] = 0b110011; + small[52] = 0b110100; + small[53] = 0b110101; + small[54] = 0b110110; + small[55] = 0b110111; + small[56] = 0b111000; + small[57] = 0b111001; + small[58] = 0b111010; + small[59] = 0b111011; + small[60] = 0b111100; + small[61] = 0b111101; + small[62] = 0b111110; + small[63] = 0b111111; + small[64] = 0b1000000; + small[65] = 0b1000001; + small[66] = 0b1000010; + small[67] = 0b1000011; + small[68] = 0b1000100; + small[69] = 0b1000101; + small[70] = 0b1000110; + small[71] = 0b1000111; + small[72] = 0b1001000; + small[73] = 0b1001001; + small[74] = 0b1001010; + small[75] = 0b1001011; + small[76] = 0b1001100; + small[77] = 0b1001101; + small[78] = 0b1001110; + small[79] = 0b1001111; + small[80] = 0b1010000; + small[81] = 0b1010001; + small[82] = 0b1010010; + small[83] = 0b1010011; + small[84] = 0b1010100; + small[85] = 0b1010101; + small[86] = 0b1010110; + small[87] = 0b1010111; + small[88] = 0b1011000; + small[89] = 0b1011001; + small[90] = 0b1011010; + small[91] = 0b1011011; + small[92] = 0b1011100; + small[93] = 0b1011101; + small[94] = 0b1011110; + small[95] = 0b1011111; + small[96] = 0b1100000; + small[97] = 0b1100001; + small[98] = 0b1100010; + small[99] = 0b1100011; + small[100] = 0b1100100; + small[101] = 0b1100101; + small[102] = 0b1100110; + small[103] = 0b1100111; + small[104] = 0b1101000; + small[105] = 0b1101001; + small[106] = 0b1101010; + small[107] = 0b1101011; + small[108] = 0b1101100; + small[109] = 0b1101101; + small[110] = 0b1101110; + small[111] = 0b1101111; + small[112] = 0b1110000; + small[113] = 0b1110001; + small[114] = 0b1110010; + small[115] = 0b1110011; + small[116] = 0b1110100; + small[117] = 0b1110101; + small[118] = 0b1110110; + small[119] = 0b1110111; + small[120] = 0b1111000; + small[121] = 0b1111001; + small[122] = 0b1111010; + small[123] = 0b1111011; + small[124] = 0b1111100; + small[125] = 0b1111101; + small[126] = 0b1111110; + small[127] = 0b1111111; + small[128] = 0b10000000; + small[129] = 0b10000001; + small[130] = 0b10000010; + small[131] = 0b10000011; + small[132] = 0b10000100; + small[133] = 0b10000101; + small[134] = 0b10000110; + small[135] = 0b10000111; + small[136] = 0b10001000; + small[137] = 0b10001001; + small[138] = 0b10001010; + small[139] = 0b10001011; + small[140] = 0b10001100; + small[141] = 0b10001101; + small[142] = 0b10001110; + small[143] = 0b10001111; + small[144] = 0b10010000; + small[145] = 0b10010001; + small[146] = 0b10010010; + small[147] = 0b10010011; + small[148] = 0b10010100; + small[149] = 0b10010101; + small[150] = 0b10010110; + small[151] = 0b10010111; + small[152] = 0b10011000; + small[153] = 0b10011001; + small[154] = 0b10011010; + small[155] = 0b10011011; + small[156] = 0b10011100; + small[157] = 0b10011101; + small[158] = 0b10011110; + small[159] = 0b10011111; + small[160] = 0b10100000; + small[161] = 0b10100001; + small[162] = 0b10100010; + small[163] = 0b10100011; + small[164] = 0b10100100; + small[165] = 0b10100101; + small[166] = 0b10100110; + small[167] = 0b10100111; + small[168] = 0b10101000; + small[169] = 0b10101001; + small[170] = 0b10101010; + small[171] = 0b10101011; + small[172] = 0b10101100; + small[173] = 0b10101101; + small[174] = 0b10101110; + small[175] = 0b10101111; + small[176] = 0b10110000; + small[177] = 0b10110001; + small[178] = 0b10110010; + small[179] = 0b10110011; + small[180] = 0b10110100; + small[181] = 0b10110101; + small[182] = 0b10110110; + small[183] = 0b10110111; + small[184] = 0b10111000; + small[185] = 0b10111001; + small[186] = 0b10111010; + small[187] = 0b10111011; + small[188] = 0b10111100; + small[189] = 0b10111101; + small[190] = 0b10111110; + small[191] = 0b10111111; + small[192] = 0b11000000; + small[193] = 0b11000001; + small[194] = 0b11000010; + small[195] = 0b11000011; + small[196] = 0b11000100; + small[197] = 0b11000101; + small[198] = 0b11000110; + small[199] = 0b11000111; + small[200] = 0b11001000; + small[201] = 0b11001001; + small[202] = 0b11001010; + small[203] = 0b11001011; + small[204] = 0b11001100; + small[205] = 0b11001101; + small[206] = 0b11001110; + small[207] = 0b11001111; + small[208] = 0b11010000; + small[209] = 0b11010001; + small[210] = 0b11010010; + small[211] = 0b11010011; + small[212] = 0b11010100; + small[213] = 0b11010101; + small[214] = 0b11010110; + small[215] = 0b11010111; + small[216] = 0b11011000; + small[217] = 0b11011001; + small[218] = 0b11011010; + small[219] = 0b11011011; + small[220] = 0b11011100; + small[221] = 0b11011101; + small[222] = 0b11011110; + small[223] = 0b11011111; + small[224] = 0b11100000; + small[225] = 0b11100001; + small[226] = 0b11100010; + small[227] = 0b11100011; + small[228] = 0b11100100; + small[229] = 0b11100101; + small[230] = 0b11100110; + small[231] = 0b11100111; + small[232] = 0b11101000; + small[233] = 0b11101001; + small[234] = 0b11101010; + small[235] = 0b11101011; + small[236] = 0b11101100; + small[237] = 0b11101101; + small[238] = 0b11101110; + small[239] = 0b11101111; + small[240] = 0b11110000; + small[241] = 0b11110001; + small[242] = 0b11110010; + small[243] = 0b11110011; + small[244] = 0b11110100; + small[245] = 0b11110101; + small[246] = 0b11110110; + small[247] = 0b11110111; + small[248] = 0b11111000; + small[249] = 0b11111001; + small[250] = 0b11111010; + small[251] = 0b11111011; + small[252] = 0b11111100; + small[253] = 0b11111101; + small[254] = 0b11111110; + small[255] = 0b11111111; + + for (i = 0; i < 256; i++) { + if (small[i] != i) + return 1; + } + + big[0] = 0b1111111100000000; + big[1] = 0b1111111100000001; + big[2] = 0b1111111100000010; + big[3] = 0b1111111100000011; + big[4] = 0b1111111100000100; + big[5] = 0b1111111100000101; + big[6] = 0b1111111100000110; + big[7] = 0b1111111100000111; + big[8] = 0b1111111100001000; + big[9] = 0b1111111100001001; + big[10] = 0b1111111100001010; + big[11] = 0b1111111100001011; + big[12] = 0b1111111100001100; + big[13] = 0b1111111100001101; + big[14] = 0b1111111100001110; + big[15] = 0b1111111100001111; + big[16] = 0b1111111100010000; + big[17] = 0b1111111100010001; + big[18] = 0b1111111100010010; + big[19] = 0b1111111100010011; + big[20] = 0b1111111100010100; + big[21] = 0b1111111100010101; + big[22] = 0b1111111100010110; + big[23] = 0b1111111100010111; + big[24] = 0b1111111100011000; + big[25] = 0b1111111100011001; + big[26] = 0b1111111100011010; + big[27] = 0b1111111100011011; + big[28] = 0b1111111100011100; + big[29] = 0b1111111100011101; + big[30] = 0b1111111100011110; + big[31] = 0b1111111100011111; + big[32] = 0b1111111100100000; + big[33] = 0b1111111100100001; + big[34] = 0b1111111100100010; + big[35] = 0b1111111100100011; + big[36] = 0b1111111100100100; + big[37] = 0b1111111100100101; + big[38] = 0b1111111100100110; + big[39] = 0b1111111100100111; + big[40] = 0b1111111100101000; + big[41] = 0b1111111100101001; + big[42] = 0b1111111100101010; + big[43] = 0b1111111100101011; + big[44] = 0b1111111100101100; + big[45] = 0b1111111100101101; + big[46] = 0b1111111100101110; + big[47] = 0b1111111100101111; + big[48] = 0b1111111100110000; + big[49] = 0b1111111100110001; + big[50] = 0b1111111100110010; + big[51] = 0b1111111100110011; + big[52] = 0b1111111100110100; + big[53] = 0b1111111100110101; + big[54] = 0b1111111100110110; + big[55] = 0b1111111100110111; + big[56] = 0b1111111100111000; + big[57] = 0b1111111100111001; + big[58] = 0b1111111100111010; + big[59] = 0b1111111100111011; + big[60] = 0b1111111100111100; + big[61] = 0b1111111100111101; + big[62] = 0b1111111100111110; + big[63] = 0b1111111100111111; + big[64] = 0b1111111101000000; + big[65] = 0b1111111101000001; + big[66] = 0b1111111101000010; + big[67] = 0b1111111101000011; + big[68] = 0b1111111101000100; + big[69] = 0b1111111101000101; + big[70] = 0b1111111101000110; + big[71] = 0b1111111101000111; + big[72] = 0b1111111101001000; + big[73] = 0b1111111101001001; + big[74] = 0b1111111101001010; + big[75] = 0b1111111101001011; + big[76] = 0b1111111101001100; + big[77] = 0b1111111101001101; + big[78] = 0b1111111101001110; + big[79] = 0b1111111101001111; + big[80] = 0b1111111101010000; + big[81] = 0b1111111101010001; + big[82] = 0b1111111101010010; + big[83] = 0b1111111101010011; + big[84] = 0b1111111101010100; + big[85] = 0b1111111101010101; + big[86] = 0b1111111101010110; + big[87] = 0b1111111101010111; + big[88] = 0b1111111101011000; + big[89] = 0b1111111101011001; + big[90] = 0b1111111101011010; + big[91] = 0b1111111101011011; + big[92] = 0b1111111101011100; + big[93] = 0b1111111101011101; + big[94] = 0b1111111101011110; + big[95] = 0b1111111101011111; + big[96] = 0b1111111101100000; + big[97] = 0b1111111101100001; + big[98] = 0b1111111101100010; + big[99] = 0b1111111101100011; + big[100] = 0b1111111101100100; + big[101] = 0b1111111101100101; + big[102] = 0b1111111101100110; + big[103] = 0b1111111101100111; + big[104] = 0b1111111101101000; + big[105] = 0b1111111101101001; + big[106] = 0b1111111101101010; + big[107] = 0b1111111101101011; + big[108] = 0b1111111101101100; + big[109] = 0b1111111101101101; + big[110] = 0b1111111101101110; + big[111] = 0b1111111101101111; + big[112] = 0b1111111101110000; + big[113] = 0b1111111101110001; + big[114] = 0b1111111101110010; + big[115] = 0b1111111101110011; + big[116] = 0b1111111101110100; + big[117] = 0b1111111101110101; + big[118] = 0b1111111101110110; + big[119] = 0b1111111101110111; + big[120] = 0b1111111101111000; + big[121] = 0b1111111101111001; + big[122] = 0b1111111101111010; + big[123] = 0b1111111101111011; + big[124] = 0b1111111101111100; + big[125] = 0b1111111101111101; + big[126] = 0b1111111101111110; + big[127] = 0b1111111101111111; + big[128] = 0b1111111110000000; + big[129] = 0b1111111110000001; + big[130] = 0b1111111110000010; + big[131] = 0b1111111110000011; + big[132] = 0b1111111110000100; + big[133] = 0b1111111110000101; + big[134] = 0b1111111110000110; + big[135] = 0b1111111110000111; + big[136] = 0b1111111110001000; + big[137] = 0b1111111110001001; + big[138] = 0b1111111110001010; + big[139] = 0b1111111110001011; + big[140] = 0b1111111110001100; + big[141] = 0b1111111110001101; + big[142] = 0b1111111110001110; + big[143] = 0b1111111110001111; + big[144] = 0b1111111110010000; + big[145] = 0b1111111110010001; + big[146] = 0b1111111110010010; + big[147] = 0b1111111110010011; + big[148] = 0b1111111110010100; + big[149] = 0b1111111110010101; + big[150] = 0b1111111110010110; + big[151] = 0b1111111110010111; + big[152] = 0b1111111110011000; + big[153] = 0b1111111110011001; + big[154] = 0b1111111110011010; + big[155] = 0b1111111110011011; + big[156] = 0b1111111110011100; + big[157] = 0b1111111110011101; + big[158] = 0b1111111110011110; + big[159] = 0b1111111110011111; + big[160] = 0b1111111110100000; + big[161] = 0b1111111110100001; + big[162] = 0b1111111110100010; + big[163] = 0b1111111110100011; + big[164] = 0b1111111110100100; + big[165] = 0b1111111110100101; + big[166] = 0b1111111110100110; + big[167] = 0b1111111110100111; + big[168] = 0b1111111110101000; + big[169] = 0b1111111110101001; + big[170] = 0b1111111110101010; + big[171] = 0b1111111110101011; + big[172] = 0b1111111110101100; + big[173] = 0b1111111110101101; + big[174] = 0b1111111110101110; + big[175] = 0b1111111110101111; + big[176] = 0b1111111110110000; + big[177] = 0b1111111110110001; + big[178] = 0b1111111110110010; + big[179] = 0b1111111110110011; + big[180] = 0b1111111110110100; + big[181] = 0b1111111110110101; + big[182] = 0b1111111110110110; + big[183] = 0b1111111110110111; + big[184] = 0b1111111110111000; + big[185] = 0b1111111110111001; + big[186] = 0b1111111110111010; + big[187] = 0b1111111110111011; + big[188] = 0b1111111110111100; + big[189] = 0b1111111110111101; + big[190] = 0b1111111110111110; + big[191] = 0b1111111110111111; + big[192] = 0b1111111111000000; + big[193] = 0b1111111111000001; + big[194] = 0b1111111111000010; + big[195] = 0b1111111111000011; + big[196] = 0b1111111111000100; + big[197] = 0b1111111111000101; + big[198] = 0b1111111111000110; + big[199] = 0b1111111111000111; + big[200] = 0b1111111111001000; + big[201] = 0b1111111111001001; + big[202] = 0b1111111111001010; + big[203] = 0b1111111111001011; + big[204] = 0b1111111111001100; + big[205] = 0b1111111111001101; + big[206] = 0b1111111111001110; + big[207] = 0b1111111111001111; + big[208] = 0b1111111111010000; + big[209] = 0b1111111111010001; + big[210] = 0b1111111111010010; + big[211] = 0b1111111111010011; + big[212] = 0b1111111111010100; + big[213] = 0b1111111111010101; + big[214] = 0b1111111111010110; + big[215] = 0b1111111111010111; + big[216] = 0b1111111111011000; + big[217] = 0b1111111111011001; + big[218] = 0b1111111111011010; + big[219] = 0b1111111111011011; + big[220] = 0b1111111111011100; + big[221] = 0b1111111111011101; + big[222] = 0b1111111111011110; + big[223] = 0b1111111111011111; + big[224] = 0b1111111111100000; + big[225] = 0b1111111111100001; + big[226] = 0b1111111111100010; + big[227] = 0b1111111111100011; + big[228] = 0b1111111111100100; + big[229] = 0b1111111111100101; + big[230] = 0b1111111111100110; + big[231] = 0b1111111111100111; + big[232] = 0b1111111111101000; + big[233] = 0b1111111111101001; + big[234] = 0b1111111111101010; + big[235] = 0b1111111111101011; + big[236] = 0b1111111111101100; + big[237] = 0b1111111111101101; + big[238] = 0b1111111111101110; + big[239] = 0b1111111111101111; + big[240] = 0b1111111111110000; + big[241] = 0b1111111111110001; + big[242] = 0b1111111111110010; + big[243] = 0b1111111111110011; + big[244] = 0b1111111111110100; + big[245] = 0b1111111111110101; + big[246] = 0b1111111111110110; + big[247] = 0b1111111111110111; + big[248] = 0b1111111111111000; + big[249] = 0b1111111111111001; + big[250] = 0b1111111111111010; + big[251] = 0b1111111111111011; + big[252] = 0b1111111111111100; + big[253] = 0b1111111111111101; + big[254] = 0b1111111111111110; + big[255] = 0b1111111111111111; + + for (i = 0; i < 256; i++) { + if (big[i] != i + 65280U) + return 1; + } + + return 0; +} From 1bfdce55edf0184ef9e9f8318977253da78c3748 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Tue, 16 Jul 2019 19:06:34 +0300 Subject: [PATCH 1129/2161] binlit: Add a few random leading zeros --- test/val/binlit.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/val/binlit.c b/test/val/binlit.c index 2b6c1ca89..47e7a196e 100644 --- a/test/val/binlit.c +++ b/test/val/binlit.c @@ -12,21 +12,21 @@ int main() { small[4] = 0b100; small[5] = 0b101; small[6] = 0b110; - small[7] = 0b111; + small[7] = 0b000111; small[8] = 0b1000; small[9] = 0b1001; - small[10] = 0b1010; - small[11] = 0b1011; + small[10] = 0b0001010; + small[11] = 0b0001011; small[12] = 0b1100; small[13] = 0b1101; small[14] = 0b1110; small[15] = 0b1111; small[16] = 0b10000; small[17] = 0b10001; - small[18] = 0b10010; - small[19] = 0b10011; - small[20] = 0b10100; - small[21] = 0b10101; + small[18] = 0b00010010; + small[19] = 0b00010011; + small[20] = 0b00010100; + small[21] = 0b00010101; small[22] = 0b10110; small[23] = 0b10111; small[24] = 0b11000; @@ -37,8 +37,8 @@ int main() { small[29] = 0b11101; small[30] = 0b11110; small[31] = 0b11111; - small[32] = 0b100000; - small[33] = 0b100001; + small[32] = 0b00000000100000; + small[33] = 0b00000000100001; small[34] = 0b100010; small[35] = 0b100011; small[36] = 0b100100; From 5cbbb4597fee58a1b22b751e9f3e49d53892f863 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <cand@gmx.com> Date: Wed, 17 Jul 2019 09:28:14 +0300 Subject: [PATCH 1130/2161] Document binary literals --- doc/cc65.sgml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 86b61ae4f..601e364ea 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -814,6 +814,14 @@ This cc65 version has some extensions to the ISO C standard. In the jump table, no expressions are supported. The array index used in the goto must be a simple variable or a constant. +<item> Binary literals, a C++14 feature and a GCC C extension, are accepted. + They can be disabled with the <tt><ref id="option--standard" + name="--standard"></tt> option. + + <tscreen><verb> + unsigned char foo = 0b101; // sets it to 5 + </verb></tscreen> + </itemize> <p> From 14ac1a7ff6cd26b862de76f4feab27be1f4974d4 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Wed, 3 Jul 2019 01:13:59 +0200 Subject: [PATCH 1131/2161] Fix bug : gotoxy does not working because Y does not update the adress on the screen --- libsrc/telestrat/gotoxy.s | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/libsrc/telestrat/gotoxy.s b/libsrc/telestrat/gotoxy.s index e1470f848..03d0a215c 100644 --- a/libsrc/telestrat/gotoxy.s +++ b/libsrc/telestrat/gotoxy.s @@ -18,9 +18,27 @@ gotoxy: jsr popa ; Get Y ; This function moves only the display cursor; it does not move the prompt position. ; In telemon, there is a position for the prompt, and another for the cursor. - sta SCRY jsr popa sta SCRX + + lda #<SCREEN + sta ADSCRL + + lda #>SCREEN + sta ADSCRL+1 + + ldy SCRY +loop: + lda ADSCRL + clc + adc #$28 + bcc skip + inc ADSCRH +skip: + sta ADSCRL + dey + bne loop + rts .endproc From 7f9e73a1ce42ca5489f7b533d942a4d8b3193148 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 6 Jul 2019 10:16:57 +0200 Subject: [PATCH 1132/2161] Add textcolor and bgcolor.s --- asminc/telestrat.inc | 1 + doc/telestrat.sgml | 10 ++++++++-- libsrc/telestrat/bgcolor.s | 28 +++++++++++++++++++++++++++ libsrc/telestrat/clrscr.s | 15 ++++++++++++--- libsrc/telestrat/cputc.s | 37 +++++++++++++++++++++++++++++++++--- libsrc/telestrat/gotoxy.s | 21 +++++++++++++++----- libsrc/telestrat/gotoy.s | 3 ++- libsrc/telestrat/textcolor.s | 28 +++++++++++++++++++++++++++ 8 files changed, 129 insertions(+), 14 deletions(-) create mode 100644 libsrc/telestrat/bgcolor.s create mode 100644 libsrc/telestrat/textcolor.s diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 3526c6f98..2036574a4 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -286,6 +286,7 @@ XZAP = $46 ; Send Zap sound to PSG XSHOOT = $47 XMKDIR = $4B ; Create a folder. Only available in TELEMON 3.x (bank 7 of Orix) XRM = $4D ; Remove a folder or a file. Only available in TELEMON 3.x (bank 7 of Orix) +XFWR = $4E ; Put a char on the first screen. Only available in TELEMON 3.x (bank 7 of Orix) XGOKBD = $52 ; Buffer management diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index e52b183d0..0cb40c501 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -212,7 +212,8 @@ RS232 port with Telemon calls (see XSOUT primitive for example) Telemon 3.0 handles fopen, fread, fclose primitives. It means that this function will crash the Telestrat because Telemon 2.4 does not have these primitives. By the way, Telemon 3.0 uses an extension "ch376 card" which -handles sdcard and FAT 32 usb key. In the next version of Telemon, FT DOS, Sedoric, Stratsed will be handled in these 3 primitives (fopen, fread, fclose). +handles sdcard and FAT 32 usb key. In the next version of Telemon, FT DOS, +Sedoric, Stratsed will be handled in these 3 primitives (fopen, fread, fclose). <itemize> <item>fclose @@ -220,7 +221,12 @@ handles sdcard and FAT 32 usb key. In the next version of Telemon, FT DOS, Sedor <item>fread </itemize> - +<sect1>conio<p> +Functions textcolor and bgcolor are available only with Telemon 3.0 (Orix). +Telemon 2.4 primitives can't handle any change of colors in text mode except with XINK or +XPAPER primitives which put on the first and second columns ink and paper attributes. +The only way to change color on the same line for text is to handle it in pure assembly +without systems calls. <sect>Other hints<p> diff --git a/libsrc/telestrat/bgcolor.s b/libsrc/telestrat/bgcolor.s new file mode 100644 index 000000000..4af0ef763 --- /dev/null +++ b/libsrc/telestrat/bgcolor.s @@ -0,0 +1,28 @@ +; 2019-07-02, Jede (jede@oric.org) +; + + .export _bgcolor + .import BGCOLOR + .import BGCOLOR_CHANGE + .include "telestrat.inc" + +.proc _bgcolor + cmp BGCOLOR ; Do we set the same color? if we don't detect it, we loose one char on the screen for each textcolor call with the same color + bne out ; Yes + lda #$00 + sta BGCOLOR_CHANGE + + lda BGCOLOR ; Return last color + + rts +out: + ldx BGCOLOR ; Get last color in order to return it + sta BGCOLOR + + lda #$01 ; Notify the change color + sta BGCOLOR_CHANGE + txa ; Return previous color + rts +.endproc + + diff --git a/libsrc/telestrat/clrscr.s b/libsrc/telestrat/clrscr.s index 1f90a7ca5..a24647f86 100644 --- a/libsrc/telestrat/clrscr.s +++ b/libsrc/telestrat/clrscr.s @@ -4,15 +4,15 @@ .export _clrscr - .importzp sp + .import CHARCOLOR_CHANGE, CHARCOLOR, BGCOLOR, BGCOLOR_CHANGE .include "telestrat.inc" .proc _clrscr ; Switch to text mode BRK_TELEMON(XTEXT) - lda #<SCREEN + lda #<SCREEN ; Get position screen ldy #>SCREEN sta RES sty RES+1 @@ -20,7 +20,7 @@ ldy #<(SCREEN+SCREEN_XSIZE*SCREEN_YSIZE) ldx #>(SCREEN+SCREEN_XSIZE*SCREEN_YSIZE) lda #' ' - BRK_TELEMON XFILLM + BRK_TELEMON XFILLM ; Calls XFILLM : it fills A value from RES address and size of X and Y value ; reset prompt position @@ -34,5 +34,14 @@ sta SCRY lda #$00 sta SCRX + + lda #$00 + sta CHARCOLOR_CHANGE + sta BGCOLOR_CHANGE + + lda #$07 + sta CHARCOLOR + sta BGCOLOR + rts .endproc diff --git a/libsrc/telestrat/cputc.s b/libsrc/telestrat/cputc.s index b4f2966a4..f38db8a13 100644 --- a/libsrc/telestrat/cputc.s +++ b/libsrc/telestrat/cputc.s @@ -4,12 +4,43 @@ ; void cputc (char c); ; - .export _cputc + .export _cputc, CHARCOLOR, CHARCOLOR_CHANGE, BGCOLOR, BGCOLOR_CHANGE .include "telestrat.inc" .proc _cputc - BRK_TELEMON XWR0 ; macro send char to screen (channel 0 in telemon terms) + ldx CHARCOLOR_CHANGE + beq do_not_change_color_foreground + + pha + lda CHARCOLOR + BRK_TELEMON $4E ; Change color on the screen (foreground) + lda #$00 + sta CHARCOLOR_CHANGE + pla + +do_not_change_color_foreground: + ldx BGCOLOR_CHANGE + beq do_not_change_color + + pha + lda BGCOLOR + ORA #%00010000 ; Add 16 because background color is an attribute between 16 and 23. 17 is red background for example + BRK_TELEMON XFWR ; Change color on the screen (background) + lda #$00 + sta BGCOLOR_CHANGE + + pla + +do_not_change_color: + BRK_TELEMON XFWR ; Macro send char to screen (channel 0) rts .endproc - +CHARCOLOR: + .res 1 +CHARCOLOR_CHANGE: + .res 1 +BGCOLOR: + .res 1 +BGCOLOR_CHANGE: + .res 1 diff --git a/libsrc/telestrat/gotoxy.s b/libsrc/telestrat/gotoxy.s index 03d0a215c..0a3db00b7 100644 --- a/libsrc/telestrat/gotoxy.s +++ b/libsrc/telestrat/gotoxy.s @@ -5,10 +5,10 @@ ; void gotoxy (unsigned char x, unsigned char y); ; - .export gotoxy, _gotoxy + .export gotoxy, _gotoxy, _update_adscr + + .import popa,CHARCOLOR_CHANGE,BGCOLOR_CHANGE - .import popa - .importzp sp .include "telestrat.inc" @@ -22,6 +22,16 @@ gotoxy: jsr popa ; Get Y jsr popa sta SCRX + jsr _update_adscr ; Update adress video ram position when SCRY et SCRX are modified + ; Force to put again attribute when it moves on the screen + lda #$01 + sta CHARCOLOR_CHANGE + sta BGCOLOR_CHANGE + rts +.endproc + + +.proc _update_adscr lda #<SCREEN sta ADSCRL @@ -29,6 +39,7 @@ gotoxy: jsr popa ; Get Y sta ADSCRL+1 ldy SCRY + beq out loop: lda ADSCRL clc @@ -39,6 +50,6 @@ skip: sta ADSCRL dey bne loop - +out: rts -.endproc +.endproc \ No newline at end of file diff --git a/libsrc/telestrat/gotoy.s b/libsrc/telestrat/gotoy.s index 05ed71de7..c6010cc2c 100644 --- a/libsrc/telestrat/gotoy.s +++ b/libsrc/telestrat/gotoy.s @@ -3,11 +3,12 @@ ; .export _gotoy - .importzp sp + .import _update_adscr .include "telestrat.inc" .proc _gotoy sta SCRY + jsr _update_adscr rts .endproc diff --git a/libsrc/telestrat/textcolor.s b/libsrc/telestrat/textcolor.s new file mode 100644 index 000000000..6c6352683 --- /dev/null +++ b/libsrc/telestrat/textcolor.s @@ -0,0 +1,28 @@ +; 2019-07-02, Jede (jede@oric.org) +; + + .export _textcolor + .import CHARCOLOR + .import CHARCOLOR_CHANGE + .include "telestrat.inc" + +.proc _textcolor + cmp CHARCOLOR ; Do we set the same color? if we don't detect it, we loose one char on the screen for each textcolor call with the same color + bne out ; yes + lda #$00 + sta CHARCOLOR_CHANGE + + lda CHARCOLOR ; return last color + + rts +out: + ldx CHARCOLOR ; get last color in order to return it + sta CHARCOLOR + + lda #$01 + sta CHARCOLOR_CHANGE + txa ; return previous color + rts +.endproc + + From 3d5811d8f5ef8b14e39635c7ec9fb9f01ca6c62f Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 6 Jul 2019 10:19:45 +0200 Subject: [PATCH 1133/2161] Fix gotoy changecolor --- libsrc/telestrat/gotoy.s | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libsrc/telestrat/gotoy.s b/libsrc/telestrat/gotoy.s index c6010cc2c..99ab3ec65 100644 --- a/libsrc/telestrat/gotoy.s +++ b/libsrc/telestrat/gotoy.s @@ -10,5 +10,11 @@ .proc _gotoy sta SCRY jsr _update_adscr + + ; We change the current line, it means that we need to put color attributes again. + ; That is not the case with _gotox because, it's on the same line attribute are already set + lda #$01 + sta CHARCOLOR_CHANGE + sta BGCOLOR_CHANGE rts .endproc From 7767a0e88e28882c03e9072b72995205d30cd1ea Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 6 Jul 2019 10:26:19 +0200 Subject: [PATCH 1134/2161] fix typo --- libsrc/telestrat/gotoxy.s | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libsrc/telestrat/gotoxy.s b/libsrc/telestrat/gotoxy.s index 0a3db00b7..a73ab5ff2 100644 --- a/libsrc/telestrat/gotoxy.s +++ b/libsrc/telestrat/gotoxy.s @@ -7,8 +7,7 @@ .export gotoxy, _gotoxy, _update_adscr - .import popa,CHARCOLOR_CHANGE,BGCOLOR_CHANGE - + .import popa, CHARCOLOR_CHANGE, BGCOLOR_CHANGE .include "telestrat.inc" From 28eba8bff9688173257a7c537b3e2533cf1e7012 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 6 Jul 2019 10:33:39 +0200 Subject: [PATCH 1135/2161] fix import --- libsrc/telestrat/gotoxy.s | 2 +- libsrc/telestrat/gotoy.s | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libsrc/telestrat/gotoxy.s b/libsrc/telestrat/gotoxy.s index a73ab5ff2..73e7d272c 100644 --- a/libsrc/telestrat/gotoxy.s +++ b/libsrc/telestrat/gotoxy.s @@ -35,7 +35,7 @@ gotoxy: jsr popa ; Get Y sta ADSCRL lda #>SCREEN - sta ADSCRL+1 + sta ADSCRH ldy SCRY beq out diff --git a/libsrc/telestrat/gotoy.s b/libsrc/telestrat/gotoy.s index 99ab3ec65..ee437f006 100644 --- a/libsrc/telestrat/gotoy.s +++ b/libsrc/telestrat/gotoy.s @@ -2,6 +2,7 @@ ; jede jede@oric.org 2017-02-25 ; .export _gotoy + .import CHARCOLOR_CHANGE, BGCOLOR_CHANGE .import _update_adscr From a0a6537bdaa29743ceea170ee4884ab018da7369 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 7 Jul 2019 22:02:48 +0200 Subject: [PATCH 1136/2161] Fix typo and optimize --- libsrc/telestrat/bgcolor.s | 9 +++------ libsrc/telestrat/cputc.s | 7 +++++-- libsrc/telestrat/gotoxy.s | 8 ++++---- libsrc/telestrat/gotoy.s | 4 ++-- libsrc/telestrat/textcolor.s | 15 +++++++-------- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/libsrc/telestrat/bgcolor.s b/libsrc/telestrat/bgcolor.s index 4af0ef763..14ecf4bd7 100644 --- a/libsrc/telestrat/bgcolor.s +++ b/libsrc/telestrat/bgcolor.s @@ -7,12 +7,11 @@ .include "telestrat.inc" .proc _bgcolor - cmp BGCOLOR ; Do we set the same color? if we don't detect it, we loose one char on the screen for each textcolor call with the same color + cmp BGCOLOR ; Do we set the same color? If we don't detect it, we loose one char on the screen for each bgcolor call with the same color bne out ; Yes - lda #$00 - sta BGCOLOR_CHANGE - lda BGCOLOR ; Return last color + ldy #$00 + sty BGCOLOR_CHANGE rts out: @@ -24,5 +23,3 @@ out: txa ; Return previous color rts .endproc - - diff --git a/libsrc/telestrat/cputc.s b/libsrc/telestrat/cputc.s index f38db8a13..96763cafb 100644 --- a/libsrc/telestrat/cputc.s +++ b/libsrc/telestrat/cputc.s @@ -11,18 +11,20 @@ .proc _cputc ldx CHARCOLOR_CHANGE beq do_not_change_color_foreground - + dec SCRX + dec SCRX pha lda CHARCOLOR BRK_TELEMON $4E ; Change color on the screen (foreground) lda #$00 sta CHARCOLOR_CHANGE + inc SCRX pla do_not_change_color_foreground: ldx BGCOLOR_CHANGE beq do_not_change_color - + dec SCRX ; Dec SCRX in order to place attribute before the right position pha lda BGCOLOR ORA #%00010000 ; Add 16 because background color is an attribute between 16 and 23. 17 is red background for example @@ -36,6 +38,7 @@ do_not_change_color: BRK_TELEMON XFWR ; Macro send char to screen (channel 0) rts .endproc +.bss CHARCOLOR: .res 1 CHARCOLOR_CHANGE: diff --git a/libsrc/telestrat/gotoxy.s b/libsrc/telestrat/gotoxy.s index 73e7d272c..8dcb69e89 100644 --- a/libsrc/telestrat/gotoxy.s +++ b/libsrc/telestrat/gotoxy.s @@ -5,7 +5,7 @@ ; void gotoxy (unsigned char x, unsigned char y); ; - .export gotoxy, _gotoxy, _update_adscr + .export gotoxy, _gotoxy, update_adscr .import popa, CHARCOLOR_CHANGE, BGCOLOR_CHANGE @@ -21,7 +21,7 @@ gotoxy: jsr popa ; Get Y jsr popa sta SCRX - jsr _update_adscr ; Update adress video ram position when SCRY et SCRX are modified + jsr update_adscr ; Update adress video ram position when SCRY et SCRX are modified ; Force to put again attribute when it moves on the screen lda #$01 sta CHARCOLOR_CHANGE @@ -30,7 +30,7 @@ gotoxy: jsr popa ; Get Y .endproc -.proc _update_adscr +.proc update_adscr lda #<SCREEN sta ADSCRL @@ -51,4 +51,4 @@ skip: bne loop out: rts -.endproc \ No newline at end of file +.endproc diff --git a/libsrc/telestrat/gotoy.s b/libsrc/telestrat/gotoy.s index ee437f006..ae6a0bcf0 100644 --- a/libsrc/telestrat/gotoy.s +++ b/libsrc/telestrat/gotoy.s @@ -4,13 +4,13 @@ .export _gotoy .import CHARCOLOR_CHANGE, BGCOLOR_CHANGE - .import _update_adscr + .import update_adscr .include "telestrat.inc" .proc _gotoy sta SCRY - jsr _update_adscr + jsr update_adscr ; We change the current line, it means that we need to put color attributes again. ; That is not the case with _gotox because, it's on the same line attribute are already set diff --git a/libsrc/telestrat/textcolor.s b/libsrc/telestrat/textcolor.s index 6c6352683..b5584902d 100644 --- a/libsrc/telestrat/textcolor.s +++ b/libsrc/telestrat/textcolor.s @@ -7,22 +7,21 @@ .include "telestrat.inc" .proc _textcolor - cmp CHARCOLOR ; Do we set the same color? if we don't detect it, we loose one char on the screen for each textcolor call with the same color + cmp CHARCOLOR ; Do we set the same color? If we don't detect it, we loose one char on the screen for each textcolor call with the same color bne out ; yes - lda #$00 - sta CHARCOLOR_CHANGE - lda CHARCOLOR ; return last color + ldy #$00 + sty CHARCOLOR_CHANGE + + lda CHARCOLOR ; Return last color rts out: - ldx CHARCOLOR ; get last color in order to return it + ldx CHARCOLOR ; Get last color in order to return it sta CHARCOLOR lda #$01 sta CHARCOLOR_CHANGE - txa ; return previous color + txa ; Return previous color rts .endproc - - From 6f7f6b5119344a4cb855b5ea0b849b96a91701a7 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Wed, 10 Jul 2019 21:44:07 +0200 Subject: [PATCH 1137/2161] Fix label, optimize code --- libsrc/telestrat/clrscr.s | 13 ++++++------- libsrc/telestrat/cputc.s | 2 +- libsrc/telestrat/gotoxy.s | 9 ++++++--- libsrc/telestrat/gotoy.s | 4 ---- libsrc/telestrat/textcolor.s | 4 ++-- 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/libsrc/telestrat/clrscr.s b/libsrc/telestrat/clrscr.s index a24647f86..22a880126 100644 --- a/libsrc/telestrat/clrscr.s +++ b/libsrc/telestrat/clrscr.s @@ -30,14 +30,13 @@ sta ADSCRH ; reset display position - lda #$01 - sta SCRY - lda #$00 - sta SCRX + ldx #$01 + stx SCRY + dex + stx SCRX - lda #$00 - sta CHARCOLOR_CHANGE - sta BGCOLOR_CHANGE + stx CHARCOLOR_CHANGE + stx BGCOLOR_CHANGE lda #$07 sta CHARCOLOR diff --git a/libsrc/telestrat/cputc.s b/libsrc/telestrat/cputc.s index 96763cafb..d313d7780 100644 --- a/libsrc/telestrat/cputc.s +++ b/libsrc/telestrat/cputc.s @@ -15,7 +15,7 @@ dec SCRX pha lda CHARCOLOR - BRK_TELEMON $4E ; Change color on the screen (foreground) + BRK_TELEMON XFWR ; Change color on the screen (foreground) lda #$00 sta CHARCOLOR_CHANGE inc SCRX diff --git a/libsrc/telestrat/gotoxy.s b/libsrc/telestrat/gotoxy.s index 8dcb69e89..7a53a77ab 100644 --- a/libsrc/telestrat/gotoxy.s +++ b/libsrc/telestrat/gotoxy.s @@ -23,14 +23,17 @@ gotoxy: jsr popa ; Get Y jsr update_adscr ; Update adress video ram position when SCRY et SCRX are modified ; Force to put again attribute when it moves on the screen - lda #$01 - sta CHARCOLOR_CHANGE - sta BGCOLOR_CHANGE + rts .endproc .proc update_adscr + + lda #$01 + sta CHARCOLOR_CHANGE + sta BGCOLOR_CHANGE + lda #<SCREEN sta ADSCRL diff --git a/libsrc/telestrat/gotoy.s b/libsrc/telestrat/gotoy.s index ae6a0bcf0..13be8e42b 100644 --- a/libsrc/telestrat/gotoy.s +++ b/libsrc/telestrat/gotoy.s @@ -2,7 +2,6 @@ ; jede jede@oric.org 2017-02-25 ; .export _gotoy - .import CHARCOLOR_CHANGE, BGCOLOR_CHANGE .import update_adscr @@ -14,8 +13,5 @@ ; We change the current line, it means that we need to put color attributes again. ; That is not the case with _gotox because, it's on the same line attribute are already set - lda #$01 - sta CHARCOLOR_CHANGE - sta BGCOLOR_CHANGE rts .endproc diff --git a/libsrc/telestrat/textcolor.s b/libsrc/telestrat/textcolor.s index b5584902d..ee6ba729a 100644 --- a/libsrc/telestrat/textcolor.s +++ b/libsrc/telestrat/textcolor.s @@ -9,11 +9,11 @@ .proc _textcolor cmp CHARCOLOR ; Do we set the same color? If we don't detect it, we loose one char on the screen for each textcolor call with the same color bne out ; yes - + ldy #$00 sty CHARCOLOR_CHANGE - lda CHARCOLOR ; Return last color + ; Return last color rts out: From ede64f68a9e2a9bf38d70e0887748409ba157384 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Wed, 17 Jul 2019 21:48:53 +0200 Subject: [PATCH 1138/2161] Fix bug with bgcolor and textcolor --- libsrc/telestrat/bgcolor.s | 15 +--------- libsrc/telestrat/clrscr.s | 14 ++++----- libsrc/telestrat/cputc.s | 31 +++++++++++-------- libsrc/telestrat/gotox.s | 5 ---- libsrc/telestrat/gotoxy.s | 58 +++++++++++++++++++----------------- libsrc/telestrat/gotoy.s | 9 ++---- libsrc/telestrat/textcolor.s | 16 ---------- 7 files changed, 59 insertions(+), 89 deletions(-) diff --git a/libsrc/telestrat/bgcolor.s b/libsrc/telestrat/bgcolor.s index 14ecf4bd7..2f602922f 100644 --- a/libsrc/telestrat/bgcolor.s +++ b/libsrc/telestrat/bgcolor.s @@ -3,23 +3,10 @@ .export _bgcolor .import BGCOLOR - .import BGCOLOR_CHANGE + .include "telestrat.inc" .proc _bgcolor - cmp BGCOLOR ; Do we set the same color? If we don't detect it, we loose one char on the screen for each bgcolor call with the same color - bne out ; Yes - - ldy #$00 - sty BGCOLOR_CHANGE - - rts -out: - ldx BGCOLOR ; Get last color in order to return it sta BGCOLOR - - lda #$01 ; Notify the change color - sta BGCOLOR_CHANGE - txa ; Return previous color rts .endproc diff --git a/libsrc/telestrat/clrscr.s b/libsrc/telestrat/clrscr.s index 22a880126..f44000d1a 100644 --- a/libsrc/telestrat/clrscr.s +++ b/libsrc/telestrat/clrscr.s @@ -3,9 +3,8 @@ ; .export _clrscr - - - .import CHARCOLOR_CHANGE, CHARCOLOR, BGCOLOR, BGCOLOR_CHANGE + .import OLD_CHARCOLOR, OLD_BGCOLOR, CHARCOLOR, BGCOLOR + .include "telestrat.inc" .proc _clrscr @@ -34,13 +33,14 @@ stx SCRY dex stx SCRX - - stx CHARCOLOR_CHANGE - stx BGCOLOR_CHANGE + + ; X is equal to 0 + stx BGCOLOR + stx OLD_BGCOLOR lda #$07 sta CHARCOLOR - sta BGCOLOR + sta OLD_CHARCOLOR rts .endproc diff --git a/libsrc/telestrat/cputc.s b/libsrc/telestrat/cputc.s index d313d7780..4b8e4fef8 100644 --- a/libsrc/telestrat/cputc.s +++ b/libsrc/telestrat/cputc.s @@ -4,34 +4,39 @@ ; void cputc (char c); ; - .export _cputc, CHARCOLOR, CHARCOLOR_CHANGE, BGCOLOR, BGCOLOR_CHANGE + .export _cputc, CHARCOLOR, OLD_CHARCOLOR, BGCOLOR, OLD_BGCOLOR .include "telestrat.inc" .proc _cputc - ldx CHARCOLOR_CHANGE + ldx CHARCOLOR + cpx OLD_CHARCOLOR beq do_not_change_color_foreground + + stx OLD_CHARCOLOR ; Store CHARCOLOR into OLD_CHARCOLOR + dec SCRX dec SCRX + pha - lda CHARCOLOR + txa ; Swap X to A because, X contains CHARCOLOR BRK_TELEMON XFWR ; Change color on the screen (foreground) - lda #$00 - sta CHARCOLOR_CHANGE inc SCRX pla do_not_change_color_foreground: - ldx BGCOLOR_CHANGE + ldx BGCOLOR + cpx OLD_BGCOLOR beq do_not_change_color + + stx OLD_BGCOLOR + dec SCRX ; Dec SCRX in order to place attribute before the right position + pha - lda BGCOLOR + txa ; Swap X to A because, X contains CHARCOLOR ORA #%00010000 ; Add 16 because background color is an attribute between 16 and 23. 17 is red background for example BRK_TELEMON XFWR ; Change color on the screen (background) - lda #$00 - sta BGCOLOR_CHANGE - pla do_not_change_color: @@ -41,9 +46,9 @@ do_not_change_color: .bss CHARCOLOR: .res 1 -CHARCOLOR_CHANGE: +OLD_CHARCOLOR: .res 1 BGCOLOR: - .res 1 -BGCOLOR_CHANGE: .res 1 +OLD_BGCOLOR: + .res 1 diff --git a/libsrc/telestrat/gotox.s b/libsrc/telestrat/gotox.s index f16c05b71..cd8828d69 100644 --- a/libsrc/telestrat/gotox.s +++ b/libsrc/telestrat/gotox.s @@ -3,13 +3,8 @@ ; .export _gotox - .import popa - - .importzp sp - .include "telestrat.inc" - .proc _gotox sta SCRX rts diff --git a/libsrc/telestrat/gotoxy.s b/libsrc/telestrat/gotoxy.s index 7a53a77ab..04a680e61 100644 --- a/libsrc/telestrat/gotoxy.s +++ b/libsrc/telestrat/gotoxy.s @@ -7,7 +7,7 @@ .export gotoxy, _gotoxy, update_adscr - .import popa, CHARCOLOR_CHANGE, BGCOLOR_CHANGE + .import popa, OLD_CHARCOLOR, OLD_BGCOLOR .include "telestrat.inc" @@ -17,41 +17,43 @@ gotoxy: jsr popa ; Get Y ; This function moves only the display cursor; it does not move the prompt position. ; In telemon, there is a position for the prompt, and another for the cursor. - sta SCRY - jsr popa - sta SCRX - - jsr update_adscr ; Update adress video ram position when SCRY et SCRX are modified - ; Force to put again attribute when it moves on the screen - rts + sta SCRY + jsr update_adscr ; Update adress video ram position when SCRY is modified + + jsr popa + sta SCRX + + rts .endproc - .proc update_adscr +; Force to set again color if cursor moves +; $FF is used because we know that it's impossible to have this value with a color +; It prevents a bug : If bgcolor or textcolor is set to black for example with no char displays, +; next cputsxy will not set the attribute if y coordinate changes + lda #$FF + sta OLD_CHARCOLOR + sta OLD_BGCOLOR - lda #$01 - sta CHARCOLOR_CHANGE - sta BGCOLOR_CHANGE + lda #<SCREEN + sta ADSCRL - lda #<SCREEN - sta ADSCRL + lda #>SCREEN + sta ADSCRH - lda #>SCREEN - sta ADSCRH - - ldy SCRY - beq out + ldy SCRY + beq out loop: - lda ADSCRL - clc - adc #$28 - bcc skip - inc ADSCRH + lda ADSCRL + clc + adc #$28 + bcc skip + inc ADSCRH skip: - sta ADSCRL - dey - bne loop + sta ADSCRL + dey + bne loop out: - rts + rts .endproc diff --git a/libsrc/telestrat/gotoy.s b/libsrc/telestrat/gotoy.s index 13be8e42b..182e3f74e 100644 --- a/libsrc/telestrat/gotoy.s +++ b/libsrc/telestrat/gotoy.s @@ -8,10 +8,7 @@ .include "telestrat.inc" .proc _gotoy - sta SCRY - jsr update_adscr - - ; We change the current line, it means that we need to put color attributes again. - ; That is not the case with _gotox because, it's on the same line attribute are already set - rts + sta SCRY + jsr update_adscr + rts .endproc diff --git a/libsrc/telestrat/textcolor.s b/libsrc/telestrat/textcolor.s index ee6ba729a..77bf6c719 100644 --- a/libsrc/telestrat/textcolor.s +++ b/libsrc/telestrat/textcolor.s @@ -3,25 +3,9 @@ .export _textcolor .import CHARCOLOR - .import CHARCOLOR_CHANGE .include "telestrat.inc" .proc _textcolor - cmp CHARCOLOR ; Do we set the same color? If we don't detect it, we loose one char on the screen for each textcolor call with the same color - bne out ; yes - - ldy #$00 - sty CHARCOLOR_CHANGE - - ; Return last color - - rts -out: - ldx CHARCOLOR ; Get last color in order to return it sta CHARCOLOR - - lda #$01 - sta CHARCOLOR_CHANGE - txa ; Return previous color rts .endproc From f9e13abc11ed85418e288eefdfb031766ee90b3b Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Wed, 17 Jul 2019 22:53:49 +0200 Subject: [PATCH 1139/2161] jmp instead of jsr --- libsrc/telestrat/gotoxy.s | 5 +++-- libsrc/telestrat/gotoy.s | 3 +-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libsrc/telestrat/gotoxy.s b/libsrc/telestrat/gotoxy.s index 04a680e61..890970ebb 100644 --- a/libsrc/telestrat/gotoxy.s +++ b/libsrc/telestrat/gotoxy.s @@ -19,12 +19,13 @@ gotoxy: jsr popa ; Get Y ; In telemon, there is a position for the prompt, and another for the cursor. sta SCRY - jsr update_adscr ; Update adress video ram position when SCRY is modified + jsr popa sta SCRX - rts + jmp update_adscr ; Update adress video ram position when SCRY is modified + .endproc .proc update_adscr diff --git a/libsrc/telestrat/gotoy.s b/libsrc/telestrat/gotoy.s index 182e3f74e..008d4413f 100644 --- a/libsrc/telestrat/gotoy.s +++ b/libsrc/telestrat/gotoy.s @@ -9,6 +9,5 @@ .proc _gotoy sta SCRY - jsr update_adscr - rts + jmp update_adscr .endproc From 0fe98a7ca862d42456a5b9cdba4daf22b94de843 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Thu, 18 Jul 2019 20:48:10 +0200 Subject: [PATCH 1140/2161] Fix bgcolor and textcolor must return last color, jmp remove. --- libsrc/telestrat/bgcolor.s | 2 ++ libsrc/telestrat/clrscr.s | 8 ++------ libsrc/telestrat/gotoxy.s | 6 +++--- libsrc/telestrat/textcolor.s | 2 ++ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libsrc/telestrat/bgcolor.s b/libsrc/telestrat/bgcolor.s index 2f602922f..90a63e6de 100644 --- a/libsrc/telestrat/bgcolor.s +++ b/libsrc/telestrat/bgcolor.s @@ -7,6 +7,8 @@ .include "telestrat.inc" .proc _bgcolor + ldx BGCOLOR ; Get previous color sta BGCOLOR + txa ; Return previous color rts .endproc diff --git a/libsrc/telestrat/clrscr.s b/libsrc/telestrat/clrscr.s index f44000d1a..52f34dcab 100644 --- a/libsrc/telestrat/clrscr.s +++ b/libsrc/telestrat/clrscr.s @@ -34,12 +34,8 @@ dex stx SCRX - ; X is equal to 0 - stx BGCOLOR - stx OLD_BGCOLOR - - lda #$07 - sta CHARCOLOR + lda #$FF + sta OLD_BGCOLOR sta OLD_CHARCOLOR rts diff --git a/libsrc/telestrat/gotoxy.s b/libsrc/telestrat/gotoxy.s index 890970ebb..3387efe40 100644 --- a/libsrc/telestrat/gotoxy.s +++ b/libsrc/telestrat/gotoxy.s @@ -24,8 +24,8 @@ gotoxy: jsr popa ; Get Y jsr popa sta SCRX - jmp update_adscr ; Update adress video ram position when SCRY is modified - +; Update adress video ram position when SCRY is modified (update_adscr) +; Fall through .endproc .proc update_adscr @@ -48,7 +48,7 @@ gotoxy: jsr popa ; Get Y loop: lda ADSCRL clc - adc #$28 + adc #SCREEN_XSIZE bcc skip inc ADSCRH skip: diff --git a/libsrc/telestrat/textcolor.s b/libsrc/telestrat/textcolor.s index 77bf6c719..7d16c9e19 100644 --- a/libsrc/telestrat/textcolor.s +++ b/libsrc/telestrat/textcolor.s @@ -6,6 +6,8 @@ .include "telestrat.inc" .proc _textcolor + ldx CHARCOLOR ; Get previous color sta CHARCOLOR + txa ; Return previous color rts .endproc From 848df36f6b766835f6a560447341037448d54478 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 21 Jul 2019 10:56:32 +0200 Subject: [PATCH 1141/2161] Optimize Clrscr --- libsrc/telestrat/clrscr.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/telestrat/clrscr.s b/libsrc/telestrat/clrscr.s index 52f34dcab..2adc905b1 100644 --- a/libsrc/telestrat/clrscr.s +++ b/libsrc/telestrat/clrscr.s @@ -34,7 +34,7 @@ dex stx SCRX - lda #$FF + dex sta OLD_BGCOLOR sta OLD_CHARCOLOR From 996537282c6c9c3eb4565f03ce8653c5889bbab1 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 21 Jul 2019 10:57:17 +0200 Subject: [PATCH 1142/2161] Cleaning import variables --- libsrc/telestrat/clrscr.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/telestrat/clrscr.s b/libsrc/telestrat/clrscr.s index 2adc905b1..aa2eae684 100644 --- a/libsrc/telestrat/clrscr.s +++ b/libsrc/telestrat/clrscr.s @@ -3,7 +3,7 @@ ; .export _clrscr - .import OLD_CHARCOLOR, OLD_BGCOLOR, CHARCOLOR, BGCOLOR + .import OLD_CHARCOLOR, OLD_BGCOLOR .include "telestrat.inc" From e7bb0aad19ca0636e1fba54c6f9b7dae55f91e08 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 21 Jul 2019 11:01:14 +0200 Subject: [PATCH 1143/2161] Fix comment and gotox force colour change --- libsrc/telestrat/cputc.s | 2 +- libsrc/telestrat/gotox.s | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libsrc/telestrat/cputc.s b/libsrc/telestrat/cputc.s index 4b8e4fef8..38f8af84b 100644 --- a/libsrc/telestrat/cputc.s +++ b/libsrc/telestrat/cputc.s @@ -34,7 +34,7 @@ do_not_change_color_foreground: dec SCRX ; Dec SCRX in order to place attribute before the right position pha - txa ; Swap X to A because, X contains CHARCOLOR + txa ; Swap X to A because, X contains BGCOLOR ORA #%00010000 ; Add 16 because background color is an attribute between 16 and 23. 17 is red background for example BRK_TELEMON XFWR ; Change color on the screen (background) pla diff --git a/libsrc/telestrat/gotox.s b/libsrc/telestrat/gotox.s index cd8828d69..7a172071c 100644 --- a/libsrc/telestrat/gotox.s +++ b/libsrc/telestrat/gotox.s @@ -2,10 +2,15 @@ ; jede jede@oric.org 2017-02-25 ; .export _gotox + .import OLD_CHARCOLOR, OLD_BGCOLOR .include "telestrat.inc" .proc _gotox sta SCRX + + lda #$FF + sta OLD_CHARCOLOR + sta OLD_BGCOLOR rts .endproc From cceffbdb8c5f90302d0a89f6524fe71dd5489001 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 21 Jul 2019 18:38:17 +0200 Subject: [PATCH 1144/2161] Fix bug $FF --- libsrc/telestrat/clrscr.s | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libsrc/telestrat/clrscr.s b/libsrc/telestrat/clrscr.s index aa2eae684..39c2f7724 100644 --- a/libsrc/telestrat/clrscr.s +++ b/libsrc/telestrat/clrscr.s @@ -34,9 +34,11 @@ dex stx SCRX + ; At this step X is equal to $00 dex - sta OLD_BGCOLOR - sta OLD_CHARCOLOR + ; At this step X is equal to $FF + stx OLD_BGCOLOR + stx OLD_CHARCOLOR rts .endproc From a0db846a9772ef82cf7163670e7a2fc109ec4b53 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 22 Jul 2019 09:05:01 -0400 Subject: [PATCH 1145/2161] Allowed old-style (K and R) function declarations to be fastcall. That lets them match old-style definitions. It avoids "Type conflict" error messages. It allows shorter function calls. Fixed the types of some variables in "test/ref/otccex.c". It avoids crashes on 64-bit Windows (32-bit Windows with 64-bit pointers). --- doc/cc65-intern.sgml | 12 ++++---- src/cc65/compile.c | 3 +- src/cc65/declare.c | 20 ++++++------- src/cc65/expr.c | 17 +++++++---- test/ref/Makefile | 10 ------- test/ref/otccex.c | 69 ++++++++++++++++++++++++-------------------- test/val/Makefile | 10 ------- 7 files changed, 66 insertions(+), 75 deletions(-) diff --git a/doc/cc65-intern.sgml b/doc/cc65-intern.sgml index ec6c48ca3..8e36578b5 100644 --- a/doc/cc65-intern.sgml +++ b/doc/cc65-intern.sgml @@ -42,7 +42,7 @@ The standard compliant variations <tt/__cdecl__/ and <tt/__fastcall__/ are alway If a function has a prototype, parameters are pushed to the C-stack as their respective types (i.e. a <tt/char/ parameter will push 1 byte), but if a function has no prototype, default promotions will apply. This means that with no prototype, <tt/char/ will be promoted -to <tt/int/ and be pushed as 2 bytes. K & R style function prototypes may be used, +to <tt/int/ and be pushed as 2 bytes. "K & R"-style forward declarations may be used, but they will function the same as if no prototype was used. <sect1>Prologue, before the function call<p> @@ -61,8 +61,8 @@ 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. -If the function has no prototype or is variadic -the <tt/Y/ register will contain the number of bytes pushed to the stack for this function. +If the function is variadic, the <tt/Y/ register will contain the number of +bytes pushed to the stack for this function. Example: <tscreen><verb> @@ -108,8 +108,9 @@ The C-stack pointer <tt/sp/ must be restored by the function to its value before 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. -If the function has no prototype, or 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 original state. +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 +original state. The internal pseudo-register <tt/regbank/ must not be changed by the function. @@ -136,4 +137,3 @@ it may clobber any of these itself: </article> - diff --git a/src/cc65/compile.c b/src/cc65/compile.c index bf9ada833..d914afb97 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -171,8 +171,9 @@ static void Parse (void) (CurTok.Tok != TOK_SEMI)) { FuncDesc* D = GetFuncDesc (Decl.Type); + if (D->Flags & FD_EMPTY) { - D->Flags = (D->Flags & ~(FD_EMPTY | FD_VARIADIC)) | FD_VOID_PARAM; + D->Flags = (D->Flags & ~FD_EMPTY) | FD_VOID_PARAM; } } diff --git a/src/cc65/declare.c b/src/cc65/declare.c index e3b5edfec..35ce5d0b2 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1132,7 +1132,7 @@ static Type* ParamTypeCvt (Type* T) static void ParseOldStyleParamList (FuncDesc* F) -/* Parse an old style (K&R) parameter list */ +/* Parse an old-style (K&R) parameter list */ { /* Some fix point tokens that are used for error recovery */ static const token_t TokenList[] = { TOK_COMMA, TOK_RPAREN, TOK_SEMI }; @@ -1234,7 +1234,7 @@ static void ParseOldStyleParamList (FuncDesc* F) static void ParseAnsiParamList (FuncDesc* F) -/* Parse a new style (ANSI) parameter list */ +/* Parse a new-style (ANSI) parameter list */ { /* Parse params */ while (CurTok.Tok != TOK_RPAREN) { @@ -1330,32 +1330,30 @@ static FuncDesc* ParseFuncDecl (void) /* Check for several special parameter lists */ if (CurTok.Tok == TOK_RPAREN) { - /* Parameter list is empty */ - F->Flags |= (FD_EMPTY | FD_VARIADIC); + /* Parameter list is empty (K&R-style) */ + F->Flags |= FD_EMPTY; } else if (CurTok.Tok == TOK_VOID && NextTok.Tok == TOK_RPAREN) { /* Parameter list declared as void */ NextToken (); F->Flags |= FD_VOID_PARAM; } else if (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. + /* 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. */ Sym = FindSym (CurTok.Ident); if (Sym == 0 || !SymIsTypeDef (Sym)) { - /* Old style (K&R) function. */ + /* Old-style (K&R) function. */ F->Flags |= FD_OLDSTYLE; } } /* Parse params */ if ((F->Flags & FD_OLDSTYLE) == 0) { - - /* New style function */ + /* New-style function */ ParseAnsiParamList (F); - } else { - /* Old style function */ + /* Old-style function */ ParseOldStyleParamList (F); } diff --git a/src/cc65/expr.c b/src/cc65/expr.c index e6522f949..904c3af01 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -359,8 +359,8 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) CHECK ((Param->Flags & SC_PARAM) != 0); } } else if (!Ellipsis) { - /* Too many arguments. Do we have an open param list? */ - if ((Func->Flags & FD_VARIADIC) == 0) { + /* Too many arguments. Do we have an open or empty param. list? */ + if ((Func->Flags & (FD_VARIADIC | FD_EMPTY)) == 0) { /* End of param list reached, no ellipsis */ Error ("Too many arguments in function call"); } @@ -401,8 +401,9 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) Flags |= TypeOf (Expr.Type); /* If this is a fastcall function, don't push the last argument */ - if (ParamCount != Func->ParamCount || !IsFastcall) { + if ((CurTok.Tok == TOK_COMMA && NextTok.Tok != TOK_RPAREN) || !IsFastcall) { unsigned ArgSize = sizeofarg (Flags); + if (FrameSize > 0) { /* We have the space already allocated, store in the frame. ** Because of invalid type conversions (that have produced an @@ -472,8 +473,14 @@ static void FunctionCall (ExprDesc* Expr) /* Handle function pointers transparently */ IsFuncPtr = IsTypeFuncPtr (Expr->Type); if (IsFuncPtr) { - /* Check whether it's a fastcall function that has parameters */ - IsFastcall = (Func->Flags & FD_VARIADIC) == 0 && Func->ParamCount > 0 && + /* Check whether it's a fastcall function that has parameters. + ** Note: if a function is forward-declared in the old K & R style, then + ** it may be called with any number of arguments, even though its + ** parameter count is zero. Handle K & R functions as though there are + ** parameters. + */ + IsFastcall = (Func->Flags & FD_VARIADIC) == 0 && + (Func->ParamCount > 0 || (Func->Flags & FD_EMPTY)) && (AutoCDecl ? IsQualFastcall (Expr->Type + 1) : !IsQualCDecl (Expr->Type + 1)); diff --git a/test/ref/Makefile b/test/ref/Makefile index 3c2e582e4..5f0b86164 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -60,16 +60,6 @@ $(WORKDIR)/%.ref: %.c | $(WORKDIR) $(DIFF): ../bdiff.c | $(WORKDIR) $(CC) $(CFLAGS) -o $@ $< -# Some files have "K & R"-style syntax. Therefore, some forward -# function-declarations don't match the later function definitions. -# Those programs fail when fastcall is used; but, the cdecl calling convention -# tolerates those conflicts. Therefore, make their functions default to cdecl. -# -$(WORKDIR)/init.%.prg \ -$(WORKDIR)/switch.%.prg \ -$(WORKDIR)/yacc.%.prg \ -$(WORKDIR)/yaccdbg.%.prg: CC65FLAGS += -Wc --all-cdecl - # "yaccdbg.c" includes "yacc.c". # yaccdbg's built files must depend on both of them. # diff --git a/test/ref/otccex.c b/test/ref/otccex.c index 645078ef0..12a8b9bfc 100644 --- a/test/ref/otccex.c +++ b/test/ref/otccex.c @@ -8,31 +8,31 @@ /* * Sample OTCC C example. You can uncomment the first line and install - * otcc in /usr/local/bin to make otcc scripts ! + * otcc in /usr/local/bin to make otcc scripts ! */ /* Any preprocessor directive except #define are ignored. We put this include so that a standard C compiler can compile this code too. */ #include <stdio.h> -#include <limits.h> /* defines are handled, but macro arguments cannot be given. No recursive defines are tolerated */ #define DEFAULT_BASE 10 #ifdef NO_IMPLICIT_FUNC_PROTOTYPES -help(char *name); +void help(char *name); #endif /* - * Only old style K&R prototypes are parsed. Only int arguments are + * Only old-style K&R prototypes are parsed. Only int arguments are * allowed (implicit types). - * + * * By benchmarking the execution time of this function (for example * for fib(35)), you'll notice that OTCC is quite fast because it - * generates native i386 machine code. + * generates native i386 machine code. */ -fib(n) +int fib(n) + int n; { printf("[fib(%d)]", n); if (n <= 2) @@ -42,12 +42,14 @@ fib(n) } /* Identifiers are parsed the same way as C: begins with letter or - '_', and then letters, '_' or digits */ + '_', and then letters, '_', or digits. */ long fact(n) + int n; { /* local variables can be declared. Only 'int' type is supported */ int i; long r; + r = 1; /* 'while' and 'for' loops are supported */ for(i=2;i<=n;i++) @@ -56,13 +58,15 @@ long fact(n) } /* Well, we could use printf, but it would be too easy */ -print_num(long n,int b) +void print_num(n, b) + long n; int b; { char *tab, *p, c; - /* Numbers can be entered in decimal, hexadecimal ('0x' prefix) and - octal ('0' prefix) */ - /* more complex programs use malloc */ - tab = malloc(0x100); + + /* Numbers can be entered in decimal, hexadecimal ('0x' prefix), and + octal ('0' prefix). */ + /* More complex programs use malloc(). */ + tab = malloc(0x100); p = tab; while (1) { c = n % b; @@ -80,29 +84,30 @@ print_num(long n,int b) } while (p != tab) { p--; - printf("%c", *(char *)p); + printf("%c", *p); } free(tab); } /* 'main' takes standard 'argc' and 'argv' parameters */ -mymain(int argc,char **argv) +int mymain(argc, argv) + int argc; char **argv; { - /* no local name space is supported, but local variables ARE + /* No local name space is supported, but local variables ARE supported. As long as you do not use a globally defined - variable name as local variable (which is a bad habbit), you - won't have any problem */ - int s, n, f, base; - - + variable name as a local variable (which is a bad habit), you + won't have any problems. */ + size_t s, f; + int n, base; + /* && and || operator have the same semantics as C (left to right evaluation and early exit) */ if (argc != 2 && argc != 3) { /* '*' operator is supported with explicit casting to 'int *', - 'char *' or 'int (*)()' (function pointer). Of course, 'int' - are supposed to be used as pointers too. */ - s = *(int *)argv; - help(s); + 'char *', or 'int (*)()' (function pointer). Of course, 'int' + are supposed to be used as pointers, too. */ + s = *(size_t *)argv; + help((char *)s); return 1; } /* Any libc function can be used because OTCC uses dynamic linking */ @@ -125,15 +130,15 @@ mymain(int argc,char **argv) printf("Overflow"); } else { /* why not using a function pointer ? */ - f = &fact; - print_num((*(long (*)(int))f)(n), base); + f = (size_t)&fact; + print_num((*(long (*)())f)(n), base); } printf("\n"); return 0; } /* functions can be used before being defined */ -help(char *name) +void help(char *name) { printf("usage: %s n [base]\n", name); printf("Compute fib(n) and fact(n) and output the result in base 'base'\n"); @@ -142,9 +147,9 @@ help(char *name) int main(void) { char *argv[3]; - argv[0]=""; + + argv[0]="otccex"; argv[1]="10"; /* n */ argv[2]="8"; /* base */ - mymain(3, argv); - return 0; -} \ No newline at end of file + return mymain(3, argv); +} diff --git a/test/val/Makefile b/test/val/Makefile index fe194d892..df1d314e4 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -44,16 +44,6 @@ all: $(TESTS) $(WORKDIR): $(call MKDIR,$(WORKDIR)) -# Some files have "K & R"-style syntax. Therefore, some forward -# function-declarations don't match the later function definitions. -# Those programs fail when fastcall is used; but, the cdecl calling convention -# tolerates those conflicts. Therefore, make their functions default to cdecl. -# -$(WORKDIR)/cq4.%.prg \ -$(WORKDIR)/cq71.%.prg \ -$(WORKDIR)/cq81.%.prg \ -$(WORKDIR)/cq84.%.prg: CC65FLAGS += -Wc --all-cdecl - define PRG_template $(WORKDIR)/%.$1.$2.prg: %.c | $(WORKDIR) From 3b07b8b8e3771ab297707facc043bbf78a542029 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Fri, 26 Jul 2019 23:04:54 +0200 Subject: [PATCH 1146/2161] Add cclear and cclearxy --- libsrc/telestrat/cclear.s | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 libsrc/telestrat/cclear.s diff --git a/libsrc/telestrat/cclear.s b/libsrc/telestrat/cclear.s new file mode 100644 index 000000000..bf875ec1a --- /dev/null +++ b/libsrc/telestrat/cclear.s @@ -0,0 +1,35 @@ +; +; 2019-07-07, Jede (jede@oric.org) +; +; void cclearxy (unsigned char x, unsigned char y, unsigned char length); +; void cclear (unsigned char length); +; + + .export _cclearxy, _cclear + .import update_adscr + + .importzp tmp1 + .import popax + .include "telestrat.inc" + + +_cclearxy: + pha ; Save the length + jsr popax ; Get X and Y + sta SCRY ; Store Y + stx SCRX ; Store X + jsr update_adscr + pla ; Restore the length and run into _cclear + +_cclear: + tax ; Is the length zero? + beq @L9 ; Jump if done +@L1: + stx tmp1 + lda #' ' + BRK_TELEMON XFWR + ldx tmp1 + dex + bne @L1 +@L9: + rts From 3d63a8bb6233875d985f4658612878c6016d9dbd Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Fri, 26 Jul 2019 23:11:34 +0200 Subject: [PATCH 1147/2161] Cleaning --- libsrc/telestrat/cclear.s | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libsrc/telestrat/cclear.s b/libsrc/telestrat/cclear.s index bf875ec1a..a32919962 100644 --- a/libsrc/telestrat/cclear.s +++ b/libsrc/telestrat/cclear.s @@ -8,7 +8,7 @@ .export _cclearxy, _cclear .import update_adscr - .importzp tmp1 + .importzp tmp1 .import popax .include "telestrat.inc" @@ -22,14 +22,14 @@ _cclearxy: pla ; Restore the length and run into _cclear _cclear: - tax ; Is the length zero? - beq @L9 ; Jump if done + tax ; Is the length equal to zero? + beq @L2 ; Yes we skip @L1: - stx tmp1 - lda #' ' + stx tmp1 ; Save X + lda #' ' ; Erase current char BRK_TELEMON XFWR ldx tmp1 dex bne @L1 -@L9: +@L2: rts From cc373cc41dc4387e9936288047e892daafc44217 Mon Sep 17 00:00:00 2001 From: Jeremy Chadwick <jdc@koitsu.org> Date: Fri, 23 Aug 2019 23:36:43 -0700 Subject: [PATCH 1148/2161] doc: clarify need for .IMPORT on some special symbols --- doc/ld65.sgml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 36489b0c6..6add0f0fd 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -562,7 +562,8 @@ segment, where this attribute is true, the linker will export three symbols. </verb></tscreen> Replace <tt/NAME/ by the name of the segment, in the example above, this would -be <tt/BSS/. These symbols may be accessed by your code. +be <tt/BSS/. These symbols may be accessed by your code once the symbol has +been imported using the <tt>.IMPORT</tt> directive. Now, as we've configured the linker to write the first three segments and create symbols for the last one, there's only one question left: Where does @@ -766,7 +767,8 @@ useful for things like a software stack, or an I/O area. } </verb></tscreen> -This will define some external symbols that may be used in your code: +This will define some external symbols that may be used in your code once +the symbol has imported using the <tt>.IMPORT</tt> directive: <tscreen><verb> __STACK_START__ This is set to the start of the memory From 57b997355fd97565d4a6a9713832afd5fdaf4f83 Mon Sep 17 00:00:00 2001 From: Jeremy Chadwick <jdc@koitsu.org> Date: Sat, 24 Aug 2019 03:49:32 -0700 Subject: [PATCH 1149/2161] Grammatical modifications --- doc/ld65.sgml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 6add0f0fd..97233271c 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -562,8 +562,8 @@ segment, where this attribute is true, the linker will export three symbols. </verb></tscreen> Replace <tt/NAME/ by the name of the segment, in the example above, this would -be <tt/BSS/. These symbols may be accessed by your code once the symbol has -been imported using the <tt>.IMPORT</tt> directive. +be <tt/BSS/. These symbols may be accessed by your code when imported using +the <tt>.IMPORT</tt> directive. Now, as we've configured the linker to write the first three segments and create symbols for the last one, there's only one question left: Where does @@ -767,8 +767,8 @@ useful for things like a software stack, or an I/O area. } </verb></tscreen> -This will define some external symbols that may be used in your code once -the symbol has imported using the <tt>.IMPORT</tt> directive: +This will define some external symbols that may be used in your code when +imported using the <tt>.IMPORT</tt> directive: <tscreen><verb> __STACK_START__ This is set to the start of the memory From 4e3abf417fc485b89edf2a591cd4e22432d62ed1 Mon Sep 17 00:00:00 2001 From: Jeremy Chadwick <jdc@koitsu.org> Date: Mon, 26 Aug 2019 12:16:22 -0700 Subject: [PATCH 1150/2161] Use the word 'macros' universally (not macroes) --- doc/ca65.sgml | 8 ++++---- doc/cl65.sgml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 211039995..af2ce8259 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -3444,8 +3444,8 @@ Here's a list of all control commands and a description, what they do: atari Defines the scrcode macro. cbm Defines the scrcode macro. cpu Defines constants for the .CPU variable. - generic Defines generic macroes like add, sub, and blt. - longbranch Defines conditional long-jump macroes. + generic Defines generic macros like add, sub, and blt. + longbranch Defines conditional long-jump macros. </verb></tscreen> Including a macro package twice, or including a macro package that @@ -4479,8 +4479,8 @@ are: <sect1><tt>.MACPACK generic</tt><p> -This macro package defines macroes that are useful in almost any program. -Currently defined macroes are: +This macro package defines macros that are useful in almost any program. +Currently defined macros are: <tscreen><verb> .macro add Arg ; add without carry diff --git a/doc/cl65.sgml b/doc/cl65.sgml index 0291f2eb3..989dce702 100644 --- a/doc/cl65.sgml +++ b/doc/cl65.sgml @@ -138,7 +138,7 @@ There are a few remaining options that control the behaviour of cl65: This option is passed to the cc65 compiler; and, it forces cl65 to stop before the assembly step. That means that C-level preprocessor directives - are obeyed; and, macroes are expanded. But, the C source isn't compiled. + are obeyed; and, macros are expanded. But, the C source isn't compiled. If the <tt/-o/ option isn't used, then the C code results are written into files with a ".i" suffix on their base names. Assembler files, object files, and libraries given on the command line are ignored. From c53b167307431ce1d087d4417d57fbadb06bc1eb Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 7 Sep 2019 18:50:11 -0400 Subject: [PATCH 1151/2161] Added a charmap header that converts no character encodings. It can be used in programs, on non-ASCII machines, that need to send/write ASCII strings. --- include/ascii_charmap.h | 295 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 include/ascii_charmap.h diff --git a/include/ascii_charmap.h b/include/ascii_charmap.h new file mode 100644 index 000000000..876dab183 --- /dev/null +++ b/include/ascii_charmap.h @@ -0,0 +1,295 @@ +/*****************************************************************************/ +/* */ +/* ascii_charmap.h */ +/* */ +/* No translations, encodings are stored as they were typed in the host. */ +/* */ +/* */ +/* 2019-09-07, Greg King */ +/* */ +/* 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 must not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + +/* No include guard here. Each charnap header +** may be included many times in a source file. +*/ + +#pragma warn (remap-zero, push, off) + +/* ASCII */ +#pragma charmap (0x00, 0x00) +#pragma charmap (0x01, 0x01) +#pragma charmap (0x02, 0x02) +#pragma charmap (0x03, 0x03) +#pragma charmap (0x04, 0x04) +#pragma charmap (0x05, 0x05) +#pragma charmap (0x06, 0x06) +#pragma charmap (0x07, 0x07) +#pragma charmap (0x08, 0x08) +#pragma charmap (0x09, 0x09) +#pragma charmap (0x0A, 0x0A) +#pragma charmap (0x0B, 0x0B) +#pragma charmap (0x0C, 0x0C) +#pragma charmap (0x0D, 0x0D) +#pragma charmap (0x0E, 0x0E) +#pragma charmap (0x0F, 0x0F) +#pragma charmap (0x10, 0x10) +#pragma charmap (0x11, 0x11) +#pragma charmap (0x12, 0x12) +#pragma charmap (0x13, 0x13) +#pragma charmap (0x14, 0x14) +#pragma charmap (0x15, 0x15) +#pragma charmap (0x16, 0x16) +#pragma charmap (0x17, 0x17) +#pragma charmap (0x18, 0x18) +#pragma charmap (0x19, 0x19) +#pragma charmap (0x1A, 0x1A) +#pragma charmap (0x1B, 0x1B) +#pragma charmap (0x1C, 0x1C) +#pragma charmap (0x1D, 0x1D) +#pragma charmap (0x1E, 0x1E) +#pragma charmap (0x1F, 0x1F) +#pragma charmap (0x20, 0x20) +#pragma charmap (0x21, 0x21) +#pragma charmap (0x22, 0x22) +#pragma charmap (0x23, 0x23) +#pragma charmap (0x24, 0x24) +#pragma charmap (0x25, 0x25) +#pragma charmap (0x26, 0x26) +#pragma charmap (0x27, 0x27) +#pragma charmap (0x28, 0x28) +#pragma charmap (0x29, 0x29) +#pragma charmap (0x2A, 0x2A) +#pragma charmap (0x2B, 0x2B) +#pragma charmap (0x2C, 0x2C) +#pragma charmap (0x2D, 0x2D) +#pragma charmap (0x2E, 0x2E) +#pragma charmap (0x2F, 0x2F) +#pragma charmap (0x30, 0x30) +#pragma charmap (0x31, 0x31) +#pragma charmap (0x32, 0x32) +#pragma charmap (0x33, 0x33) +#pragma charmap (0x34, 0x34) +#pragma charmap (0x35, 0x35) +#pragma charmap (0x36, 0x36) +#pragma charmap (0x37, 0x37) +#pragma charmap (0x38, 0x38) +#pragma charmap (0x39, 0x39) +#pragma charmap (0x3A, 0x3A) +#pragma charmap (0x3B, 0x3B) +#pragma charmap (0x3C, 0x3C) +#pragma charmap (0x3D, 0x3D) +#pragma charmap (0x3E, 0x3E) +#pragma charmap (0x3F, 0x3F) +#pragma charmap (0x40, 0x40) +#pragma charmap (0x41, 0x41) +#pragma charmap (0x42, 0x42) +#pragma charmap (0x43, 0x43) +#pragma charmap (0x44, 0x44) +#pragma charmap (0x45, 0x45) +#pragma charmap (0x46, 0x46) +#pragma charmap (0x47, 0x47) +#pragma charmap (0x48, 0x48) +#pragma charmap (0x49, 0x49) +#pragma charmap (0x4A, 0x4A) +#pragma charmap (0x4B, 0x4B) +#pragma charmap (0x4C, 0x4C) +#pragma charmap (0x4D, 0x4D) +#pragma charmap (0x4E, 0x4E) +#pragma charmap (0x4F, 0x4F) +#pragma charmap (0x50, 0x50) +#pragma charmap (0x51, 0x51) +#pragma charmap (0x52, 0x52) +#pragma charmap (0x53, 0x53) +#pragma charmap (0x54, 0x54) +#pragma charmap (0x55, 0x55) +#pragma charmap (0x56, 0x56) +#pragma charmap (0x57, 0x57) +#pragma charmap (0x58, 0x58) +#pragma charmap (0x59, 0x59) +#pragma charmap (0x5A, 0x5A) +#pragma charmap (0x5B, 0x5B) +#pragma charmap (0x5C, 0x5C) +#pragma charmap (0x5D, 0x5D) +#pragma charmap (0x5E, 0x5E) +#pragma charmap (0x5F, 0x5F) +#pragma charmap (0x60, 0x60) +#pragma charmap (0x61, 0x61) +#pragma charmap (0x62, 0x62) +#pragma charmap (0x63, 0x63) +#pragma charmap (0x64, 0x64) +#pragma charmap (0x65, 0x65) +#pragma charmap (0x66, 0x66) +#pragma charmap (0x67, 0x67) +#pragma charmap (0x68, 0x68) +#pragma charmap (0x69, 0x69) +#pragma charmap (0x6A, 0x6A) +#pragma charmap (0x6B, 0x6B) +#pragma charmap (0x6C, 0x6C) +#pragma charmap (0x6D, 0x6D) +#pragma charmap (0x6E, 0x6E) +#pragma charmap (0x6F, 0x6F) +#pragma charmap (0x70, 0x70) +#pragma charmap (0x71, 0x71) +#pragma charmap (0x72, 0x72) +#pragma charmap (0x73, 0x73) +#pragma charmap (0x74, 0x74) +#pragma charmap (0x75, 0x75) +#pragma charmap (0x76, 0x76) +#pragma charmap (0x77, 0x77) +#pragma charmap (0x78, 0x78) +#pragma charmap (0x79, 0x79) +#pragma charmap (0x7A, 0x7A) +#pragma charmap (0x7B, 0x7B) +#pragma charmap (0x7C, 0x7C) +#pragma charmap (0x7D, 0x7D) +#pragma charmap (0x7E, 0x7E) +#pragma charmap (0x7F, 0x7F) + +/* beyond ASCII */ +#pragma charmap (0x80, 0x80) +#pragma charmap (0x81, 0x81) +#pragma charmap (0x82, 0x82) +#pragma charmap (0x83, 0x83) +#pragma charmap (0x84, 0x84) +#pragma charmap (0x85, 0x85) +#pragma charmap (0x86, 0x86) +#pragma charmap (0x87, 0x87) +#pragma charmap (0x88, 0x88) +#pragma charmap (0x89, 0x89) +#pragma charmap (0x8A, 0x8A) +#pragma charmap (0x8B, 0x8B) +#pragma charmap (0x8C, 0x8C) +#pragma charmap (0x8D, 0x8D) +#pragma charmap (0x8E, 0x8E) +#pragma charmap (0x8F, 0x8F) +#pragma charmap (0x90, 0x90) +#pragma charmap (0x91, 0x91) +#pragma charmap (0x92, 0x92) +#pragma charmap (0x93, 0x93) +#pragma charmap (0x94, 0x94) +#pragma charmap (0x95, 0x95) +#pragma charmap (0x96, 0x96) +#pragma charmap (0x97, 0x97) +#pragma charmap (0x98, 0x98) +#pragma charmap (0x99, 0x99) +#pragma charmap (0x9A, 0x9A) +#pragma charmap (0x9B, 0x9B) +#pragma charmap (0x9C, 0x9C) +#pragma charmap (0x9D, 0x9D) +#pragma charmap (0x9E, 0x9E) +#pragma charmap (0x9F, 0x9F) +#pragma charmap (0xA0, 0xA0) +#pragma charmap (0xA1, 0xA1) +#pragma charmap (0xA2, 0xA2) +#pragma charmap (0xA3, 0xA3) +#pragma charmap (0xA4, 0xA4) +#pragma charmap (0xA5, 0xA5) +#pragma charmap (0xA6, 0xA6) +#pragma charmap (0xA7, 0xA7) +#pragma charmap (0xA8, 0xA8) +#pragma charmap (0xA9, 0xA9) +#pragma charmap (0xAA, 0xAA) +#pragma charmap (0xAB, 0xAB) +#pragma charmap (0xAC, 0xAC) +#pragma charmap (0xAD, 0xAD) +#pragma charmap (0xAE, 0xAE) +#pragma charmap (0xAF, 0xAF) +#pragma charmap (0xB0, 0xB0) +#pragma charmap (0xB1, 0xB1) +#pragma charmap (0xB2, 0xB2) +#pragma charmap (0xB3, 0xB3) +#pragma charmap (0xB4, 0xB4) +#pragma charmap (0xB5, 0xB5) +#pragma charmap (0xB6, 0xB6) +#pragma charmap (0xB7, 0xB7) +#pragma charmap (0xB8, 0xB8) +#pragma charmap (0xB9, 0xB9) +#pragma charmap (0xBA, 0xBA) +#pragma charmap (0xBB, 0xBB) +#pragma charmap (0xBC, 0xBC) +#pragma charmap (0xBD, 0xBD) +#pragma charmap (0xBE, 0xBE) +#pragma charmap (0xBF, 0xBF) +#pragma charmap (0xC0, 0xC0) +#pragma charmap (0xC1, 0xC1) +#pragma charmap (0xC2, 0xC2) +#pragma charmap (0xC3, 0xC3) +#pragma charmap (0xC4, 0xC4) +#pragma charmap (0xC5, 0xC5) +#pragma charmap (0xC6, 0xC6) +#pragma charmap (0xC7, 0xC7) +#pragma charmap (0xC8, 0xC8) +#pragma charmap (0xC9, 0xC9) +#pragma charmap (0xCA, 0xCA) +#pragma charmap (0xCB, 0xCB) +#pragma charmap (0xCC, 0xCC) +#pragma charmap (0xCD, 0xCD) +#pragma charmap (0xCE, 0xCE) +#pragma charmap (0xCF, 0xCF) +#pragma charmap (0xD0, 0xD0) +#pragma charmap (0xD1, 0xD1) +#pragma charmap (0xD2, 0xD2) +#pragma charmap (0xD3, 0xD3) +#pragma charmap (0xD4, 0xD4) +#pragma charmap (0xD5, 0xD5) +#pragma charmap (0xD6, 0xD6) +#pragma charmap (0xD7, 0xD7) +#pragma charmap (0xD8, 0xD8) +#pragma charmap (0xD9, 0xD9) +#pragma charmap (0xDA, 0xDA) +#pragma charmap (0xDB, 0xDB) +#pragma charmap (0xDC, 0xDC) +#pragma charmap (0xDD, 0xDD) +#pragma charmap (0xDE, 0xDE) +#pragma charmap (0xDF, 0xDF) +#pragma charmap (0xE0, 0xE0) +#pragma charmap (0xE1, 0xE1) +#pragma charmap (0xE2, 0xE2) +#pragma charmap (0xE3, 0xE3) +#pragma charmap (0xE4, 0xE4) +#pragma charmap (0xE5, 0xE5) +#pragma charmap (0xE6, 0xE6) +#pragma charmap (0xE7, 0xE7) +#pragma charmap (0xE8, 0xE8) +#pragma charmap (0xE9, 0xE9) +#pragma charmap (0xEA, 0xEA) +#pragma charmap (0xEB, 0xEB) +#pragma charmap (0xEC, 0xEC) +#pragma charmap (0xED, 0xED) +#pragma charmap (0xEE, 0xEE) +#pragma charmap (0xEF, 0xEF) +#pragma charmap (0xF0, 0xF0) +#pragma charmap (0xF1, 0xF1) +#pragma charmap (0xF2, 0xF2) +#pragma charmap (0xF3, 0xF3) +#pragma charmap (0xF4, 0xF4) +#pragma charmap (0xF5, 0xF5) +#pragma charmap (0xF6, 0xF6) +#pragma charmap (0xF7, 0xF7) +#pragma charmap (0xF8, 0xF8) +#pragma charmap (0xF9, 0xF9) +#pragma charmap (0xFA, 0xFA) +#pragma charmap (0xFB, 0xFB) +#pragma charmap (0xFC, 0xFC) +#pragma charmap (0xFD, 0xFD) +#pragma charmap (0xFE, 0xFE) +#pragma charmap (0xFF, 0xFF) + +#pragma warn (remap-zero, pop) From 3b128ba59f6bfc943bfdc9a971daa00f612f1193 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 10 Sep 2019 09:49:06 +0200 Subject: [PATCH 1152/2161] Use MACHID to check for realtime clock. There's no need to do guesswork to know if a realtime clock is present/active. --- doc/apple2.sgml | 16 +++++++--------- doc/apple2enh.sgml | 16 +++++++--------- libsrc/apple2/getres.s | 8 ++++---- libsrc/apple2/settime.s | 8 ++++---- 4 files changed, 22 insertions(+), 26 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 648ee56db..91c02c7ad 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -500,16 +500,14 @@ From that perspective it makes most sense to not set both the date and the time rather only set the date and have the time just stay zero. Then files show up in a directory as <tt/DD-MON-YY 0:00/. -So <tt/clock_settime()/ checks if the current time equals 0:00. If it does <bf/NOT/ -then a realtime clock is supposed to be active and <tt/clock_settime()/ fails with -<tt/ERANGE/. Otherwise <tt/clock_settime()/ sets the date - and completely ignores -the time provided as parameter. +So <tt/clock_settime()/ checks if a realtime clock is active. If it is then +<tt/clock_settime()/ fails with <tt/ERANGE/. Otherwise <tt/clock_settime()/ +sets the date - and completely ignores the time provided as parameter. -<tt/clock_getres()/ too checks if the current time equals 0:00. If it does <bf/NOT/ -then a realtime clock is supposed to be active and <tt/clock_getres()/ returns a time -resolution of one minute. Otherwise <tt/clock_getres()/ presumes that the only one -who sets the RAM location is <tt/clock_settime()/ and therefore returns a time -resolution of one day. +<tt/clock_getres()/ too checks if a realtime clock is active. If it is then +<tt/clock_getres()/ returns a time resolution of one minute. Otherwise +<tt/clock_getres()/ presumes that the only one who sets the RAM location is +<tt/clock_settime()/ and therefore returns a time resolution of one day. diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index d25aa7efe..fa70da4ee 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -501,16 +501,14 @@ From that perspective it makes most sense to not set both the date and the time rather only set the date and have the time just stay zero. Then files show up in a directory as <tt/DD-MON-YY 0:00/. -So <tt/clock_settime()/ checks if the current time equals 0:00. If it does <bf/NOT/ -then a realtime clock is supposed to be active and <tt/clock_settime()/ fails with -<tt/ERANGE/. Otherwise <tt/clock_settime()/ sets the date - and completely ignores -the time provided as parameter. +So <tt/clock_settime()/ checks if a realtime clock is active. If it is then +<tt/clock_settime()/ fails with <tt/ERANGE/. Otherwise <tt/clock_settime()/ +sets the date - and completely ignores the time provided as parameter. -<tt/clock_getres()/ too checks if the current time equals 0:00. If it does <bf/NOT/ -then a realtime clock is supposed to be active and <tt/clock_getres()/ returns a time -resolution of one minute. Otherwise <tt/clock_getres()/ presumes that the only one -who sets the RAM location is <tt/clock_settime()/ and therefore returns a time -resolution of one day. +<tt/clock_getres()/ too checks if a realtime clock is active. If it is then +<tt/clock_getres()/ returns a time resolution of one minute. Otherwise +<tt/clock_getres()/ presumes that the only one who sets the RAM location is +<tt/clock_settime()/ and therefore returns a time resolution of one day. diff --git a/libsrc/apple2/getres.s b/libsrc/apple2/getres.s index 6441671cc..4364bc967 100644 --- a/libsrc/apple2/getres.s +++ b/libsrc/apple2/getres.s @@ -27,10 +27,10 @@ _clock_getres: ldx #<day_res ldy #>day_res - ; Check for existing minutes or hours - lda TIMELO - ora TIMELO+1 - beq :+ + ; Check for realtme clock + lda MACHID + lsr a + bcc :+ ; Switch to minute resolution ldx #<min_res diff --git a/libsrc/apple2/settime.s b/libsrc/apple2/settime.s index 07032fdd1..f722f6f40 100644 --- a/libsrc/apple2/settime.s +++ b/libsrc/apple2/settime.s @@ -21,11 +21,11 @@ _clock_settime: ldy __dos_type beq enosys - ; Check for existing minutes or hours + ; Check for realtme clock tay ; Save A - lda TIMELO - ora TIMELO+1 - bne erange + lda MACHID + lsr a + bcs erange tya ; Restore A ; Get tm From 0896deedefa81598ecbc472ffb6cdb9f8dca864e Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 11 Sep 2019 17:55:49 -0400 Subject: [PATCH 1153/2161] Added a .ORG keyword to ca65 structs/unions. Allow 24-bit numbers as operands in ca65 structs/unions. --- doc/ca65.sgml | 137 ++++++++++++++++++++++++++++------------------ src/ca65/struct.c | 45 ++++++++------- 2 files changed, 111 insertions(+), 71 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index af2ce8259..8a5e307d8 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1,4 +1,4 @@ -<!doctype linuxdoc system> <!-- -*- text-mode -*- --> +<!doctype linuxdoc system> <article> <title>ca65 Users Guide @@ -1752,18 +1752,18 @@ either a string or an expression. <sect1><tt>.SIZEOF</tt><label id=".SIZEOF"><p> - <tt/.SIZEOF/ is a pseudo function that returns the size of its argument. The - argument can be a struct/union, a struct member, a procedure, or a label. In - case of a procedure or label, its size is defined by the amount of data - placed in the segment where the label is relative to. If a line of code - switches segments (for example in a macro) data placed in other segments - does not count for the size. + <tt/.SIZEOF()/ is a pseudo function that returns the size of its argument. + The argument can be a struct/union, a struct member, a scope/procedure, or a + label. In the case of a procedure or label, its size is defined by the + amount of data placed in the segment where the label is relative to. If a + line of code switches segments (for example, in a macro), data placed in + other segments does not count for the size. - Please note that a symbol or scope must exist, before it is used together with - <tt/.SIZEOF/ (this may get relaxed later, but will always be true for scopes). - A scope has preference over a symbol with the same name, so if the last part - of a name represents both, a scope and a symbol, the scope is chosen over the - symbol. + Please note that a symbol or scope must exist before it can be used together + with <tt/.SIZEOF()/ (that may get relaxed later, but always will be true for + scopes). A scope has preference over a symbol with the same name; so, if the + last part of a name represents both a scope and a symbol, then the scope is + chosen over the symbol. After the following code: @@ -2496,7 +2496,7 @@ Here's a list of all control commands and a description, what they do: <sect1><tt>.ENDPROC</tt><label id=".ENDPROC"><p> - End of local lexical level (see <tt><ref id=".PROC" name=".PROC"></tt>). + End of the local lexical level (see <tt><ref id=".PROC" name=".PROC"></tt>). <sect1><tt>.ENDREP, .ENDREPEAT</tt><label id=".ENDREPEAT"><p> @@ -2506,7 +2506,7 @@ Here's a list of all control commands and a description, what they do: <sect1><tt>.ENDSCOPE</tt><label id=".ENDSCOPE"><p> - End of local lexical level (see <tt/<ref id=".SCOPE" name=".SCOPE">/). + End of the local lexical level (see <tt/<ref id=".SCOPE" name=".SCOPE">/). <sect1><tt>.ENDSTRUCT</tt><label id=".ENDSTRUCT"><p> @@ -2530,8 +2530,8 @@ Here's a list of all control commands and a description, what they do: otherwise the enumeration members are placed in the enclosing scope. In the enumeration body, symbols are declared. The first symbol has a value - of zero, and each following symbol will get the value of the preceding plus - one. This behaviour may be overridden by an explicit assignment. Two symbols + of zero, and each following symbol will get the value of the preceding, plus + one. That behaviour may be overridden by an explicit assignment. Two symbols may have the same value. Example: @@ -2544,9 +2544,9 @@ Here's a list of all control commands and a description, what they do: .endenum </verb></tscreen> - Above example will create a new scope named <tt/errorcodes/ with three - symbols in it that get the values 0, 1 and 2 respectively. Another way - to write this would have been: + The above example will create a new scope named <tt/errorcodes/ with three + symbols in it that get the values 0, 1, and 2 respectively. Another way + to write that would have been: <tscreen><verb> .scope errorcodes @@ -2575,12 +2575,12 @@ Here's a list of all control commands and a description, what they do: .endenum </verb></tscreen> - In this example, the enumeration does not have a name, which means that the - members will be visible in the enclosing scope and can be used in this scope + In that example, the enumeration does not have a name, which means that the + members will be visible in the enclosing scope, and can be used in that scope without explicit scoping. The first member (<tt/EUNKNOWN/) has the value -1. - The value for the following members is incremented by one, so <tt/EOK/ would - be zero and so on. <tt/EWOULDBLOCK/ is an alias for <tt/EGAIN/, so it has an - override for the value using an already defined symbol. + The values for the following members are incremented by one; so, <tt/EOK/ + would be zero, and so on. <tt/EWOULDBLOCK/ is an alias for <tt/EAGAIN/; so, + it has an override for the value, using an already defined symbol. <sect1><tt>.ERROR</tt><label id=".ERROR"><p> @@ -4672,22 +4672,22 @@ compiler, depending on the target system selected: </itemize> + <sect>Structs and unions<label id="structs"><p> <sect1>Structs and unions Overview<p> Structs and unions are special forms of <ref id="scopes" name="scopes">. They -are to some degree comparable to their C counterparts. Both have a list of -members. Each member allocates storage and may optionally have a name, which, -in case of a struct, is the offset from the beginning and, in case of a union, -is always zero. +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. <sect1>Declaration<p> Here is an example for a very simple struct with two members and a total size of 4 bytes: - <tscreen><verb> .struct Point xcoord .word @@ -4695,10 +4695,9 @@ of 4 bytes: .endstruct </verb></tscreen> -A union shares the total space between all its members, its size is the same +A union shares the total space between all its members; its size is the same as that of the largest member. The offset of all members relative to the union is zero. - <tscreen><verb> .union Entry index .word @@ -4706,13 +4705,12 @@ is zero. .endunion </verb></tscreen> -A struct or union must not necessarily have a name. If it is anonymous, no -local scope is opened, the identifiers used to name the members are placed +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. The -storage allocators may contain a multiplier, as in the example below: - +A struct may contain unnamed members and definitions of local structs/unions. +The storage allocators may contain a multiplier, as in the example below: <tscreen><verb> .struct Circle .struct Point @@ -4721,13 +4719,51 @@ storage allocators may contain a multiplier, as in the example below: Radius .word .endstruct </verb></tscreen> +The size of the Circle struct is 6 (three words). + + +<sect1>The storage allocator keywords<p> + + <descrip> + + <tag/.BYTE, .RES/ + Allocates multiples of 1 byte. <tt/.RES/ requires an operand. + + <tag/.DBYTE, .WORD, .ADDR/ + Allocates multiples of 2 bytes. + + <tag/.FARADDR/ + Allocates multiples of 3 bytes. + + <tag/.DWORD/ + Allocates multiples of 4 bytes. + + </descrip> + + +<sect1>The <tt/.ORG/ keyword<p> + +The <tt/.ORG/ keyword changes the offset value that is assigned to subsequent +member names. It's useful when using a struct to define the names of the +registers in an I/O chip. Example: +<tscreen><verb> +; 6551 +.struct ACIA ; Asynchronous Communications Interface Adapter + .org $031C +DATA .byte +STATUS .byte +CMD .byte ; Command register +CTRL .byte ; Control register +.endstruct + + lda ACIA::DATA ; Get an RS-232 character +</verb></tscreen> <sect1>The <tt/.TAG/ keyword<p> -Using the <ref id=".TAG" name=".TAG"> keyword, it is possible to reserve space -for an already defined struct or unions within another struct: - +By using the <ref id=".TAG" name=".TAG"> keyword, it is possible to reserve +space for an already defined struct or union within another struct: <tscreen><verb> .struct Point xcoord .word @@ -4740,33 +4776,30 @@ for an already defined struct or unions within another struct: .endstruct </verb></tscreen> -Space for a struct or union may be allocated using the <ref id=".TAG" +Actual space for a struct or union may be allocated by using the <ref id=".TAG" name=".TAG"> directive. - <tscreen><verb> - C: .tag Circle +C: .tag Circle </verb></tscreen> Currently, members are just offsets from the start of the struct or union. To -access a field of a struct, the member offset has to be added to the address -of the struct itself: - +access a field of a struct, the member offset must be added to the address of +the struct variable itself: <tscreen><verb> lda C+Circle::Radius ; Load circle radius into A </verb></tscreen> - -This may change in a future version of the assembler. +That may change in a future version of the assembler. <sect1>Limitations<p> -Structs and unions are currently implemented as nested symbol tables (in fact, +Structs and unions currently are implemented as nested symbol tables (in fact, they were a by-product of the improved scoping rules). Currently, the -assembler has no idea of types. This means that the <ref id=".TAG" -name=".TAG"> keyword will only allocate space. You won't be able to initialize -variables declared with <ref id=".TAG" name=".TAG">, and adding an embedded +assembler has no idea of types. That means that the <ref id=".TAG" +name=".TAG"> keyword only will allocate space. You won't be able to initialize +variables declared with <ref id=".TAG" name=".TAG">; and, adding an embedded structure to another structure with <ref id=".TAG" name=".TAG"> will not make -this structure accessible by using the '::' operator. +that added structure accessible by using the '::' operator. diff --git a/src/ca65/struct.c b/src/ca65/struct.c index 5ea7a18ec..6d279a701 100644 --- a/src/ca65/struct.c +++ b/src/ca65/struct.c @@ -5,7 +5,6 @@ /* .STRUCT/.UNION commands */ /* */ /* */ -/* */ /* (C) 2003-2011, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ @@ -73,20 +72,20 @@ enum { static long Member (long AllocSize) /* Read one struct member and return its size */ { - long Multiplicator; + long Multiplier; - /* A multiplicator may follow */ + /* A multiplier may follow */ if (CurTok.Tok != TOK_SEP) { - Multiplicator = ConstExpression (); - if (Multiplicator <= 0) { + Multiplier = ConstExpression (); + if (Multiplier <= 0) { ErrorSkip ("Range error"); - Multiplicator = 1; + Multiplier = 1; } - AllocSize *= Multiplicator; + AllocSize *= Multiplier; } /* Check the size for a reasonable value */ - if (AllocSize >= 0x10000) { + if (AllocSize >= 0x1000000) { ErrorSkip ("Range error"); } @@ -102,10 +101,11 @@ static long DoStructInternal (long Offs, unsigned Type) long Size = 0; /* Outside of other structs, we need a name. Inside another struct or - ** union, the struct may be anonymous, in which case no new lexical level + ** union, the struct may be anonymous; in which case, no new lexical level ** is started. */ int Anon = (CurTok.Tok != TOK_IDENT); + if (!Anon) { /* Enter a new scope, then skip the name */ SymEnterLevel (&CurTok.SVal, SCOPE_STRUCT, ADDR_SIZE_ABS, 0); @@ -121,7 +121,6 @@ static long DoStructInternal (long Offs, unsigned Type) while (CurTok.Tok != TOK_ENDSTRUCT && CurTok.Tok != TOK_ENDUNION && CurTok.Tok != TOK_EOF) { - long MemberSize; SymTable* Struct; SymEntry* Sym; @@ -132,14 +131,14 @@ static long DoStructInternal (long Offs, unsigned Type) continue; } - /* The format is "[identifier] storage-allocator [, multiplicator]" */ + /* The format is "[identifier ].storage-allocator[ multiplier]" */ Sym = 0; if (CurTok.Tok == TOK_IDENT) { - - /* Beware: An identifier may also be a macro, in which case we have - ** to start over. + /* Beware: An identifier may be a macro also; + ** in which case, we must start over. */ Macro* M = FindMacro (&CurTok.SVal); + if (M) { MacExpandStart (M); continue; @@ -155,10 +154,9 @@ static long DoStructInternal (long Offs, unsigned Type) NextTok (); } - /* Read storage allocators */ - MemberSize = 0; /* In case of errors, use zero */ + /* Read the storage allocator */ + MemberSize = 0; /* In case of errors or .ORG, use zero */ switch (CurTok.Tok) { - case TOK_BYTE: NextTok (); MemberSize = Member (1); @@ -190,6 +188,15 @@ static long DoStructInternal (long Offs, unsigned Type) } break; + case TOK_ORG: + NextTok (); + if (CurTok.Tok == TOK_SEP) { + ErrorSkip ("Address is missing"); + } else { + Offs = Member (1); + } + break; + case TOK_TAG: NextTok (); Struct = ParseScopedSymTable (); @@ -244,8 +251,8 @@ static long DoStructInternal (long Offs, unsigned Type) ConsumeSep (); } - /* If this is not a anon struct, enter a special symbol named ".size" - ** into the symbol table of the struct that holds the size of the + /* If this is not an anon. struct, enter a special symbol named ".size" + ** into the symbol table, of the struct, that holds the size of the ** struct. Since the symbol starts with a dot, it cannot be accessed ** by user code. ** Leave the struct scope level. From 18afc7c7038280e2443c64e31cf2f0092a484004 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 27 Sep 2019 03:38:51 -0400 Subject: [PATCH 1154/2161] Created a target and a library for the Commander X16 prototype computer. --- asminc/cbm_kernal.inc | 36 ++-- asminc/cx16.inc | 316 ++++++++++++++++++++++++++++++++++ cfg/cx16-asm.cfg | 37 ++++ cfg/cx16-bank.cfg | 112 ++++++++++++ cfg/cx16.cfg | 45 +++++ doc/ca65.sgml | 3 +- doc/cc65.sgml | 4 + doc/cx16.sgml | 311 +++++++++++++++++++++++++++++++++ doc/index.sgml | 3 + doc/intro.sgml | 27 ++- include/cbm.h | 4 +- include/cx16.h | 189 ++++++++++++++++++++ libsrc/Makefile | 1 + libsrc/cx16/_scrsize.s | 14 ++ libsrc/cx16/bankramaddr.s | 50 ++++++ libsrc/cx16/bordercolor.s | 27 +++ libsrc/cx16/break.s | 109 ++++++++++++ libsrc/cx16/cgetc.s | 72 ++++++++ libsrc/cx16/clrscr.s | 26 +++ libsrc/cx16/color.s | 43 +++++ libsrc/cx16/conio.s | 9 + libsrc/cx16/cpeekc.s | 48 ++++++ libsrc/cx16/cpeekcolor.s | 27 +++ libsrc/cx16/cpeekrevers.s | 32 ++++ libsrc/cx16/cpeeks.s | 0 libsrc/cx16/cputc.s | 98 +++++++++++ libsrc/cx16/crt0.s | 115 +++++++++++++ libsrc/cx16/devnum.s | 8 + libsrc/cx16/get_ostype.s | 20 +++ libsrc/cx16/get_tv.s | 31 ++++ libsrc/cx16/irq.s | 48 ++++++ libsrc/cx16/joy/cx16-stdjoy.s | 119 +++++++++++++ libsrc/cx16/joy_stat_stddrv.s | 10 ++ libsrc/cx16/joy_stddrv.s | 13 ++ libsrc/cx16/kbhit.s | 17 ++ libsrc/cx16/kernal.s | 59 +++++++ libsrc/cx16/libref.s | 18 ++ libsrc/cx16/mainargs.s | 137 +++++++++++++++ libsrc/cx16/revers.s | 23 +++ libsrc/cx16/set_tv.s | 32 ++++ libsrc/cx16/status.s | 6 + libsrc/cx16/sysuname.s | 37 ++++ libsrc/cx16/videomode.s | 30 ++++ libsrc/cx16/waitvsync.s | 17 ++ src/ca65/main.c | 6 +- src/cc65/main.c | 4 + src/common/target.c | 16 +- src/common/target.h | 4 +- testcode/lib/joy-test.c | 86 +++++---- 49 files changed, 2440 insertions(+), 59 deletions(-) create mode 100644 asminc/cx16.inc create mode 100644 cfg/cx16-asm.cfg create mode 100644 cfg/cx16-bank.cfg create mode 100644 cfg/cx16.cfg create mode 100644 doc/cx16.sgml create mode 100644 include/cx16.h create mode 100644 libsrc/cx16/_scrsize.s create mode 100644 libsrc/cx16/bankramaddr.s create mode 100644 libsrc/cx16/bordercolor.s create mode 100644 libsrc/cx16/break.s create mode 100644 libsrc/cx16/cgetc.s create mode 100644 libsrc/cx16/clrscr.s create mode 100644 libsrc/cx16/color.s create mode 100644 libsrc/cx16/conio.s create mode 100644 libsrc/cx16/cpeekc.s create mode 100644 libsrc/cx16/cpeekcolor.s create mode 100644 libsrc/cx16/cpeekrevers.s create mode 100644 libsrc/cx16/cpeeks.s create mode 100644 libsrc/cx16/cputc.s create mode 100644 libsrc/cx16/crt0.s create mode 100644 libsrc/cx16/devnum.s create mode 100644 libsrc/cx16/get_ostype.s create mode 100644 libsrc/cx16/get_tv.s create mode 100644 libsrc/cx16/irq.s create mode 100644 libsrc/cx16/joy/cx16-stdjoy.s create mode 100644 libsrc/cx16/joy_stat_stddrv.s create mode 100644 libsrc/cx16/joy_stddrv.s create mode 100644 libsrc/cx16/kbhit.s create mode 100644 libsrc/cx16/kernal.s create mode 100644 libsrc/cx16/libref.s create mode 100644 libsrc/cx16/mainargs.s create mode 100644 libsrc/cx16/revers.s create mode 100644 libsrc/cx16/set_tv.s create mode 100644 libsrc/cx16/status.s create mode 100644 libsrc/cx16/sysuname.s create mode 100644 libsrc/cx16/videomode.s create mode 100644 libsrc/cx16/waitvsync.s diff --git a/asminc/cbm_kernal.inc b/asminc/cbm_kernal.inc index 29a6e5ddf..79edce06b 100644 --- a/asminc/cbm_kernal.inc +++ b/asminc/cbm_kernal.inc @@ -1,30 +1,45 @@ ; ; Olli Savia <ops@iki.fi> ; -; Commodore kernal functions +; Commodore Kernal functions ; +.if .def(__CX16__) + ; CX16 extended jump table + GETJOY := $FF06 +.endif + .if .def(__C128__) - ; C128 Extended jump table + ; C128 extended jump table C64MODE := $FF4D - SWAPPER := $FF5F SETBNK := $FF68 .endif -.if .def(__C64__) || .def(__C128__) || .def(__C16__) +.if .def(__C128__) || .def(__CX16__) + ; Extended jump table + CLSALL := $FF4A + SWAPPER := $FF5F + JSRFAR := $FF6E + INDFET := $FF74 + INDSTA := $FF77 + INDCMP := $FF7A + PRIMM := $FF7D +.endif + +.if .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) CINT := $FF81 IOINIT := $FF84 RAMTAS := $FF87 .elseif .def(__VIC20__) - CINT := $E518 ; No entries are in the kernal jump table of the Vic20 for these three (3) functions. + CINT := $E518 ; No entries are in the Kernal jump table of the VIC-20 for these three (3) functions. IOINIT := $FDF9 ; The entries for these functions have been set to point directly to the functions - RAMTAS := $FD8D ; in the kernal to maintain compatibility with the other Commodore platforms. + RAMTAS := $FD8D ; in the Kernal, to maintain compatibility with the other Commodore platforms. .elseif .def(__CBM510__) || .def(__CBM610__) IOINIT := $FF7B CINT := $FF7E .endif -.if .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) +.if .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) RESTOR := $FF8A VECTOR := $FF8D .elseif .def(__CBM510__) || .def(__CBM610__) @@ -32,7 +47,7 @@ RESTOR := $FF87 .endif -.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) +.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) SETMSG := $FF90 SECOND := $FF93 TKSA := $FF96 @@ -64,7 +79,7 @@ CHRIN := $FFCF BSOUT := $FFD2 CHROUT := $FFD2 -.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) +.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) LOAD := $FFD5 SAVE := $FFD8 SETTIM := $FFDB @@ -77,7 +92,7 @@ GETIN := $FFE4 CLALL := $FFE7 UDTIM := $FFEA -.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) +.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) SCREEN := $FFED PLOT := $FFF0 IOBASE := $FFF3 @@ -102,7 +117,6 @@ UDTIM := $FFEA CURS_SET := $CD57 CURS_ON := $CD6F CURS_OFF := $CD9F - INDFET := $FF74 .elseif .def(__C16__) CLRSCR := $D88B KBDREAD := $D8C1 diff --git a/asminc/cx16.inc b/asminc/cx16.inc new file mode 100644 index 000000000..6f3f1c731 --- /dev/null +++ b/asminc/cx16.inc @@ -0,0 +1,316 @@ +; +; CX16 definitions +; + +; --------------------------------------------------------------------------- +; Constants + +.enum COLOR + BLACK = $00 + WHITE + RED + CYAN + VIOLET + PURPLE = VIOLET + GREEN + BLUE + YELLOW + ORANGE + BROWN + LIGHTRED + GRAY1 + GRAY2 + LIGHTGREEN + LIGHTBLUE + GRAY3 +.endenum + +; Special keys +.enum KEY + F1 = $85 + F3 + F5 + F7 + F2 + F4 + F6 + F8 + F9 = $10 + F10 = $15 + F11 + F12 +.endenum + +; --------------------------------------------------------------------------- +; Zero page + +; BASIC +VARTAB := $2D ; Pointer to start of BASIC variables +MEMSIZE := $37 ; Pointer to highest BASIC RAM location (+1) +TXTPTR := $7A ; Pointer into BASIC source code + +; Kernal +IN_DEV := $99 ; Current input device number +OUT_DEV := $9A ; Current output device number +IMPARM := $9B ; Pointer for PRIMM function +TIME := $A0 ; 60 Hz. clock +FNAM_LEN := $B7 ; Length of filename +SECADR := $B9 ; Secondary address +DEVNUM := $BA ; Device number +FNAM := $BB ; Pointer to filename +KEY_COUNT := $C6 ; Number of keys in input buffer +RVS := $C7 ; Reverse flag +CURS_FLAG := $CC ; 1 = cursor off +CURS_BLINK := $CD ; Blink counter +CURS_CHAR := $CE ; Character under the cursor +CURS_STATE := $CF ; Cursor blink state +SCREEN_PTR := $D1 ; Pointer to current row on text screen (16 bits) +CURS_X := $D3 ; Cursor column +CURS_Y := $D6 ; Cursor row +LLEN := $D9 ; Line length +NLINES := $DA ; Number of screen lines +JOY1 := $EF ; 3 bytes of NES/SNES gamepad data +JOY2 := $F2 +FREKZP := $FB ; Five unused bytes + +; Page two + +BASIC_BUF := $200 ; Location of command-line +BASIC_BUF_LEN = 89 ; Maximum length of command-line + +CHARCOLOR := $286 +CURS_COLOR := $287 ; Color under the cursor + +; --------------------------------------------------------------------------- +; Vector and other locations + +IRQVec := $0314 +BRKVec := $0316 +NMIVec := $0318 + +; --------------------------------------------------------------------------- +; I/O locations + +; Video Enhanced Retro Adapter +; Has audio, SPI, and UART. +.scope VERA + ; External registers + .struct + .org $9F20 + ADDR .faraddr ; Address for data port access + DATA0 .byte ; First data port + DATA1 .byte ; Second data port + CTRL .byte ; Control register + IRQ_EN .byte ; Interrupt enable bits + IRQ_FLAGS .byte ; Interrupt flags + .endstruct + .enum ; Address automatic increment amounts + INC0 = 0 << 4 + INC1 = 1 << 4 + INC2 = 2 << 4 + INC4 = 3 << 4 + INC8 = 4 << 4 + INC16 = 5 << 4 + INC32 = 6 << 4 + INC64 = 7 << 4 + INC128 = 8 << 4 + INC256 = 9 << 4 + INC512 = 10 << 4 + INC1024 = 11 << 4 + INC2048 = 12 << 4 + INC4096 = 13 << 4 + INC8192 = 14 << 4 + INC16384 = 15 << 4 + .endenum + ; Internal RAM and registers + VRAM := $000000 + .scope COMPOSER ; Display composer + .struct + .org $0F0000 + VIDEO .byte + HSCALE .byte + VSCALE .byte + FRAME .byte + HSTART_LO .byte + HSTOP_LO .byte + VSTART_LO .byte + VSTOP_LO .byte + STRTSTOP_HI .byte + IRQ_LINE .word + .endstruct + .enum MODE ; Output mode + DISABLE = 0 + VGA + NTSC + RGB ; Interlaced, composite sync + .endenum + .enum + ENABLE_COLOR = 0 << 2 + DISABLE_COLOR = 1 << 2 ; NTSC monochrome + .endenum + .endscope + PALETTE := $0F1000 + .struct L0 ; Layer 0 registers + .org $0F2000 + CTRL0 .byte ; Display mode control + CTRL1 .byte ; Geometry control + MAP_BASE .addr + TILE_BASE .addr + HSCROLL .word ; Horizontal scroll + VSCROLL .word ; Vertical scroll + .endstruct + .struct L1 ; Layer 1 registers (same as layer 0) + .org $0F3000 + CTRL0 .byte + CTRL1 .byte + MAP_BASE .addr + TILE_BASE .addr + HSCROLL .word + VSCROLL .word + .endstruct + .enum MAP ; Map geometry + WIDTH32 = 0 + WIDTH64 + WIDTH128 + WIDTH256 + HEIGHT32 = 0 << 2 + HEIGHT64 = 1 << 2 + HEIGHT128 = 2 << 2 + HEIGHT256 = 3 << 2 + .endenum + .scope TILE ; Tile geometry + .enum + WIDTH8 = 0 << 4 + WIDTH16 = 1 << 4 + WIDTH320 = WIDTH8 + WIDTH640 = WIDTH16 + HEIGHT8 = 0 << 5 + HEIGHT16 = 1 << 5 + .endenum + .enum FLIP + NONE = 0 << 2 + HORIZ = 1 << 2 + VERT = 2 << 2 + BOTH = 3 << 2 + .endenum + .endscope + .enum DMODE ; Display modes + TEXT16 = 0 << 5 + TEXT256 = 1 << 5 + TILE4 = 2 << 5 + TILE16 = 3 << 5 + TILE256 = 4 << 5 + BITMAP4 = 5 << 5 + BITMAP16 = 6 << 5 + BITMAP256 = 7 << 5 + .endenum + .scope SPRITE + .struct + .org $0F4000 + CTRL .byte ; Enables sprites + COLLISION .byte + .endstruct + .enum FLIP + NONE = 0 + HORIZ + VERT + BOTH + .endenum + .enum ; Sprite geometry + WIDTH8 = 0 << 4 + WIDTH16 = 1 << 4 + WIDTH32 = 2 << 4 + WIDTH64 = 3 << 4 + HEIGHT8 = 0 << 6 + HEIGHT16 = 1 << 6 + HEIGHT32 = 2 << 6 + HEIGHT64 = 3 << 6 + COLORS16 = 0 << 7 + COLORS256 = 1 << 7 + .endenum + .enum DEPTH + DISABLE = 0 << 2 + CANVAS = 1 << 2 + LAYER0 = 2 << 2 + LAYER1 = 3 << 2 + .endenum + ATTRIB := $0F5000 ; Sprite attributes + .endscope + AUDIO := $0F6000 + .scope SPI + .struct + .org $0F7000 + DATA .byte + CONTROL .byte + .endstruct + .enum + DESELECT = 0 + SELECT + BUSY_MASK = 1 << 1 + .endenum + .endscope + .scope UART ; Universal Asyncronous Receiver Transmitter + .struct + .org $0F8000 + DATA .byte + STATUS .byte + BPS_DIV .word + .endstruct + .enum MASK + RECEIVE = 1 << 0 + TRANSMIT = 1 << 1 + .endenum + .endscope +.endscope + +; 65c22 +.struct VIA1 ; Versatile Interface Adapter + .org $9F60 + PRB .byte ; ROM bank, IEC (Port Register B) + PRA .byte ; RAM bank (Port Register A) + DDRB .byte ; (Data Direction Register B) + DDRA .byte ; (Data Direction Register A) + T1 .word ; (Timer 1) + T1L .word ; (Timer 1 Latch) + T2 .word ; (Timer 2) + SR .byte ; (Shift Register) + ACR .byte ; (Auxiliary Control Register) + PCR .byte ; (Peripheral Control Register) + IFR .byte ; (Interrupt Flags Register) + IER .byte ; (Interrupt Enable Register) + PRA2 .byte ; RAM bank (Port Register A without handshaking) +.endstruct + +; 65c22 +.struct VIA2 + .org $9F70 + PRB .byte + PRA .byte ; NES controller communication + DDRB .byte + DDRA .byte + T1 .word + T1L .word + T2 .word + SR .byte + ACR .byte + PCR .byte + IFR .byte + IER .byte + PRA2 .byte +.endstruct + +; Real-Time Clock + +; X16 Emulator device +; This device doesn't exist on the real machine. +.struct EMULATOR + .org $9FB0 + DEBUG .byte ; Boolean: debugging enabled + VIDACCESSLOG .byte ; Boolean: log VERA activity + KEYBOARDLOG .byte ; Boolean: log keyboard data + ECHO .byte ; Boolean: echo enabled + SAVEXIT .byte ; Boolean: save on exit + .res $D - $5 + KEYMAP .byte ; Current keyboard layout number + DETECT .byte 2 ; If is "16" string, then running on emulator +.endstruct diff --git a/cfg/cx16-asm.cfg b/cfg/cx16-asm.cfg new file mode 100644 index 000000000..53f6da176 --- /dev/null +++ b/cfg/cx16-asm.cfg @@ -0,0 +1,37 @@ +FEATURES { + STARTADDRESS: default = $0801; +} +SYMBOLS { + __LOADADDR__: type = import; + __HIMEM__: type = weak, value = $9F00; +} +MEMORY { + ZP: file = "", start = $0004, size = $0090 - $0004, define = yes; + LOADADDR: file = %O, start = %S - 2, size = $0002; + MAIN: file = %O, start = %S, size = __HIMEM__ - %S; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + LOADADDR: load = LOADADDR, type = ro; + EXEHDR: 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; + 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/cfg/cx16-bank.cfg b/cfg/cx16-bank.cfg new file mode 100644 index 000000000..52438fbac --- /dev/null +++ b/cfg/cx16-bank.cfg @@ -0,0 +1,112 @@ +FEATURES { + STARTADDRESS: default = $0801; +} +SYMBOLS { + __LOADADDR__: type = import; + __EXEHDR__: type = import; + __BANKRAMADDR__: type = import; + __STACKSIZE__: type = weak, value = $0800; # 2K stack + __HIMEM__: type = weak, value = $9F00; + __BANKRAMSTART__: type = export, value = $A000; + __BANKRAMSIZE__: type = weak, value = $2000; # 8K banked RAM +} +MEMORY { + ZP: file = "", define = yes, start = $0004, size = $0090 - $0004; + 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 = __HIMEM__ - __HEADER_LAST__; + BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __ONCE_RUN__ - __STACKSIZE__; + BRAM00ADDR: file = "%O.00", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM00: file = "%O.00", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM01ADDR: file = "%O.01", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM01: file = "%O.01", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM02ADDR: file = "%O.02", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM02: file = "%O.02", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM03ADDR: file = "%O.03", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM03: file = "%O.03", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM04ADDR: file = "%O.04", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM04: file = "%O.04", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM05ADDR: file = "%O.05", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM05: file = "%O.05", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM06ADDR: file = "%O.06", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM06: file = "%O.06", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM07ADDR: file = "%O.07", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM07: file = "%O.07", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM08ADDR: file = "%O.08", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM08: file = "%O.08", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM09ADDR: file = "%O.09", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM09: file = "%O.09", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM0AADDR: file = "%O.0a", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0A: file = "%O.0a", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM0BADDR: file = "%O.0b", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0B: file = "%O.0b", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM0CADDR: file = "%O.0c", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0C: file = "%O.0c", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM0DADDR: file = "%O.0d", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0D: file = "%O.0d", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM0EADDR: file = "%O.0e", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0E: file = "%O.0e", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM0FADDR: file = "%O.0f", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0F: file = "%O.0f", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; + 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; + ONCE: load = MAIN, type = ro, define = yes; + BSS: load = BSS, type = bss, define = yes; + BRAM00ADDR: load = BRAM00ADDR, type = ro, optional = yes; + BANKRAM00: load = BRAM00, type = rw, define = yes, optional = yes; + BRAM01ADDR: load = BRAM01ADDR, type = ro, optional = yes; + BANKRAM01: load = BRAM01, type = rw, define = yes, optional = yes; + BRAM02ADDR: load = BRAM02ADDR, type = ro, optional = yes; + BANKRAM02: load = BRAM02, type = rw, define = yes, optional = yes; + BRAM03ADDR: load = BRAM03ADDR, type = ro, optional = yes; + BANKRAM03: load = BRAM03, type = rw, define = yes, optional = yes; + BRAM04ADDR: load = BRAM04ADDR, type = ro, optional = yes; + BANKRAM04: load = BRAM04, type = rw, define = yes, optional = yes; + BRAM05ADDR: load = BRAM05ADDR, type = ro, optional = yes; + BANKRAM05: load = BRAM05, type = rw, define = yes, optional = yes; + BRAM06ADDR: load = BRAM06ADDR, type = ro, optional = yes; + BANKRAM06: load = BRAM06, type = rw, define = yes, optional = yes; + BRAM07ADDR: load = BRAM07ADDR, type = ro, optional = yes; + BANKRAM07: load = BRAM07, type = rw, define = yes, optional = yes; + BRAM08ADDR: load = BRAM08ADDR, type = ro, optional = yes; + BANKRAM08: load = BRAM08, type = rw, define = yes, optional = yes; + BRAM09ADDR: load = BRAM09ADDR, type = ro, optional = yes; + BANKRAM09: load = BRAM09, type = rw, define = yes, optional = yes; + BRAM0AADDR: load = BRAM0AADDR, type = ro, optional = yes; + BANKRAM0A: load = BRAM0A, type = rw, define = yes, optional = yes; + BRAM0BADDR: load = BRAM0BADDR, type = ro, optional = yes; + BANKRAM0B: load = BRAM0B, type = rw, define = yes, optional = yes; + BRAM0CADDR: load = BRAM0CADDR, type = ro, optional = yes; + BANKRAM0C: load = BRAM0C, type = rw, define = yes, optional = yes; + BRAM0DADDR: load = BRAM0DADDR, type = ro, optional = yes; + BANKRAM0D: load = BRAM0D, type = rw, define = yes, optional = yes; + BRAM0EADDR: load = BRAM0EADDR, type = ro, optional = yes; + BANKRAM0E: load = BRAM0E, type = rw, define = yes, optional = yes; + BRAM0FADDR: load = BRAM0FADDR, type = ro, optional = yes; + BANKRAM0F: load = BRAM0F, type = rw, define = yes, optional = 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/cx16.cfg b/cfg/cx16.cfg new file mode 100644 index 000000000..f912e0f83 --- /dev/null +++ b/cfg/cx16.cfg @@ -0,0 +1,45 @@ +FEATURES { + STARTADDRESS: default = $0801; +} +SYMBOLS { + __LOADADDR__: type = import; + __EXEHDR__: type = import; + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __HIMEM__: type = weak, value = $9F00; +} +MEMORY { + ZP: file = "", define = yes, start = $0004, size = $0090 - $0004; + 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 = __HIMEM__ - __HEADER_LAST__; + BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __ONCE_RUN__ - __STACKSIZE__; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; + 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; + 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/doc/ca65.sgml b/doc/ca65.sgml index 8a5e307d8..ad72189c0 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -4653,9 +4653,10 @@ compiler, depending on the target system selected: <item><tt/__C128__/ - Target system is <tt/c128/ <item><tt/__C16__/ - Target system is <tt/c16/ or <tt/plus4/ <item><tt/__C64__/ - Target system is <tt/c64/ -<item><tt/__CBM__/ - Target is a Commodore system +<item><tt/__CBM__/ - Target is a Commodore or Commodore-alike system <item><tt/__CBM510__/ - Target system is <tt/cbm510/ <item><tt/__CBM610__/ - Target system is <tt/cbm610/ +<item><tt/__CX16__/ - Target system is <tt/cx16/ <item><tt/__GEOS__/ - Target is a GEOS system <item><tt/__GEOS_APPLE__/ - Target system is <tt/geos-apple/ <item><tt/__GEOS_CBM__/ - Target system is <tt/geos-cbm/ diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 601e364ea..8691f9471 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -901,6 +901,10 @@ The compiler defines several macros at startup: <item><tt/__CC65_STD_CC65__/ </itemize> + <tag><tt>__CX16__</tt></tag> + + This macro is defined if the target is the Commander X16 (-t cx16). + <tag><tt>__DATE__</tt></tag> This macro expands to the date of translation of the preprocessing diff --git a/doc/cx16.sgml b/doc/cx16.sgml new file mode 100644 index 000000000..077458bf6 --- /dev/null +++ b/doc/cx16.sgml @@ -0,0 +1,311 @@ +<!doctype linuxdoc system> + +<article> +<title>Commander X16-specific information for cc65 +<author><url url="mailto:greg.king5@verizon.net" name="Greg King"> + +<abstract> +An overview over the CX16 run-time system as it's implemented for the cc65 C +compiler. +</abstract> + +<!-- Table of contents --> +<toc> + +<!-- Begin the document --> + +<sect>Overview<p> + +The Commander X16 is a modern small computer with firmware that is based on +the ROMs in Commodore's VIC-20 and 64C. It has a couple of the I/O chips that +are in the VIC-20. + +This file contains an overview of the CX16 run-time system as it comes with the +cc65 C compiler. It describes the memory layout, CX16-specific header files, +available drivers, and any pitfalls specific to that platform. + +Please note that CX16-specific functions just are mentioned here; they are +described in detail in the separate <url url="funcref.html" name="function +reference">. Even functions marked as "platform dependent" may be available on +more than one platform. Please see the function reference for more +information. + + + +<sect>Binary format<p> + +The standard binary output format generated by the linker for the CX16 target +is a machine language program with a one-line BASIC stub which calls the +machine language part via SYS. That means that a program can be loaded as a +BASIC program, and started with RUN. It is, of course, possible to change that +behaviour by using a modified start-up file and linker config. + + + +<sect>Memory layout<p> + +cc65-generated programs with the default setup run with the I/O area and the +Kernal ROM visible. That means that Kernal entry points can be called directly. +The usable memory ranges are $0800 - $9EFF and $A000 - +$BFFF. + +Special locations: + +<descrip> + <tag/Stack/ + The C run-time stack is located at $9EFF, and grows downward. + + <tag/Heap/ + The C heap is located at the end of the program, and grows toward the C + run-time stack. + + <tag/Bank RAM/ + Bank RAM is located at $A000 - $BFFF. It's an eight-Kibibyte + window into a half Mibibyte or two Mibibytes of banked RAM. + + <tag/Bank ROM/ + Bank ROM is located at $C000 - $FFFF. It's a sixteen-Kibibyte + window into 128 Kibibytes of banked ROM. +</descrip><p> + + + +<sect>Linker configurations<p> + +The ld65 linker comes with a default config. file for the Commander X16, which +is used via <tt/-t cx16/. The cx16 package comes with additional secondary +linker config. files which are used via <tt/-t cx16 -C <configfile>/. + + +<sect1>Default config. file (<tt/cx16.cfg/)<p> + +The default configuration is tailored to C programs. It supplies the load +address and a small BASIC stub that starts the compiled program using a SYS +command. + + +<sect1><tt/cx16-asm.cfg/<p> + +This configuration is made for Assembly programmers who don't need a special +setup. The default start address is $0801. It can be changed with the +linker command-line option <tt/--start-addr/ or <tt/-S/. All standard segments, +with the exception of <tt/ZEROPAGE/, are written to the output file; +and, a two-byte load address is prepended. + +To use that config. file, assemble with <tt/-t cx16/, and link with <tt/-C +cx16-asm.cfg/. The former will make sure that the correct character +translations are in effect, while the latter supplies the actual config. +When using <tt/cl65/, use both command-line options. + +Sample command line for <tt/cl65/: +<tscreen><verb> +cl65 -o file.prg -t cx16 -C cx16-asm.cfg source.s +</verb></tscreen> + +To generate code that loads to $A000: +<tscreen><verb> +cl65 -o file.prg -Wl -S,$A000 -t cX16 -C cX16-asm.cfg source.s +</verb></tscreen> + +It also is possible to add a small BASIC header to the program, that uses SYS +to jump to the program entry point (which is the start of the code segment). +The advantage is that the program can be started using RUN. + +To generate a program with a BASIC SYS header, use +<tscreen><verb> +cl65 -o file.prg -u __EXEHDR__ -t cx16 -C cx16-asm.cfg source.s +</verb></tscreen> + +Please note that, in this case, a changed start address doesn't make sense, +because the program must be loaded to BASIC's start address. + + + +<sect>Platform-specific header files<p> + +Programs containing CX16-specific code may use the <tt/cx16.h/ or <tt/cbm.h/ +header files. Using the later may be an option when writing code for more than +one CBM-like platform, because it includes <tt/cx16.h/, and declares several +functions common to all CBM-like platforms. + + +<sect1>CX16-specific functions<p> + +The functions listed below are special for the CX16. See the <url +url="funcref.html" name="function reference"> for declarations and usage. + +<itemize> +<item>get_ostype() +<item>set_tv() +<item>videomode() +<item>waitvsync() +</itemize> + + +<sect1>CBM-specific functions<p> + +Some functions are available for all (or, at least most) of the Commodore-like +machines. See the <url url="funcref.html" name="function reference"> for +declarations and usage. + +<itemize> +<item>cbm_close() +<item>cbm_closedir() +<item>cbm_k_basin() +<item>cbm_k_bsout() +<item>cbm_k_chkin() +<item>cbm_k_ckout() +<item>cbm_k_close() +<item>cbm_k_clrch() +<item>cbm_k_load() +<item>cbm_k_open() +<item>cbm_k_readst() +<item>cbm_k_save() +<item>cbm_k_second() +<item>cbm_k_setlfs() +<item>cbm_k_setnam() +<item>cbm_k_tksa() +<item>cbm_load() +<item>cbm_open() +<item>cbm_opendir() +<item>cbm_read() +<item>cbm_readdir() +<item>cbm_save() +<item>cbm_write() +<item>get_tv() +</itemize> + + +<sect1>Hardware access<p> + +The following pseudo variables declared in the <tt/cx16.h/ header file do allow +access to hardware located in the address space. Some variables are +structures, accessing the struct fields will access the chip registers. + +<descrip> + <tag><tt/VERA/</tag> + The <tt/VERA/ structure allows access + to the Video Enhanced Retro Adapter chip. + + <tag><tt/VIA1, VIA2/</tag> + Access to the two VIA (Versatile Interface Adapter) chips is available via + the <tt/VIA1/ and <tt/VIA2/ variables. The structure behind those variables + is explained in <tt/_6522.h/. + + <tag><tt/BANK_RAM/</tag> + A character array that mirrors the eight-Kibibyte window, at $A000, + into banked RAM. +</descrip><p> + + + +<sect>Loadable drivers<p> + +The names in the parentheses denote the symbols to be used for static linking of the drivers. + + +<sect1>Graphics drivers<p> + +No graphics drivers are available currently for the CX16. + + +<sect1>Extended memory drivers<p> + +No extended memory drivers are available currently for the CX16. + + +<sect1>Joystick drivers<p> + +The default drivers, <tt/joy_stddrv (joy_static_stddrv)/, +point to <tt/cX16-stdjoy.joy (cx16_stdjoy_joy)/. + +<descrip> + <tag><tt/cX16-stdjoy.joy (cX16_stdjoy_joy)/</tag> + Supports up to two NES and SNES controllers connected to the joystick ports + of the CX16. It reads the four directions, and the A, B, Select, and Start + buttons. Button A is the primary fire button. +</descrip><p> + + +<sect1>Mouse drivers<p> + +No mouse drivers are available currently for the CX16. + + +<sect1>RS232 device drivers<p> + +No serial drivers are available currently for the CX16. + + + +<sect>Limitations<p> + +The Commander X16 still is being designed. It's configuration can change at +any time. Some changes could make old programs fail to work. + + + +<sect>Other hints<p> + + +<sect1>Escape code<p> + +For an Esc, press <tt/Ctrl/ and the <tt/[/ key. + + +<sect1>Passing arguments to the program<p> + +Command-line arguments can be passed to <tt/main()/. Because that is not +supported directly by BASIC, the following syntax was chosen: +<tscreen><verb> + RUN:REM ARG1 " ARG2 IS QUOTED" ARG3 "" ARG5 +</verb></tscreen> + +<enum> +<item>Arguments are separated by spaces. +<item>Arguments may be quoted. +<item>Leading and trailing spaces around an argument are ignored. Spaces within + a quoted argument are allowed. +<item>The first argument passed to <tt/main()/ is the program name. +<item>A maximum number of 10 arguments (including the program name) are + supported. +</enum> + + +<sect1>Program return code<p> + +The program return code (low byte) is passed back to BASIC by use of the +<tt/ST/ variable. + + +<sect1>Interrupts<p> + +The run-time for the CX16 uses routines marked as <tt/.INTERRUPTOR/ for +interrupt handlers. Such routines must be written as simple machine language +subroutines, and will be called automatically by the interrupt handler code +if they are linked into a program. See the discussion of the <tt/.CONDES/ +feature in the <url url="ca65.html" name="assembler manual">. + + + +<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 aecfb7de9..01325529d 100644 --- a/doc/index.sgml +++ b/doc/index.sgml @@ -145,6 +145,9 @@ <tag><htmlurl url="creativision.html" name="creativision.html"></tag> Topics specific to the Creativision Console. + <tag><htmlurl url="cx16.html" name="cx16.html"></tag> + Topics specific to the Commander X16. + <tag><htmlurl url="gamate.html" name="gamate.html"></tag> Topics specific to the Bit Corporation Gamate Console. diff --git a/doc/intro.sgml b/doc/intro.sgml index 994d30bc0..b2b141d10 100644 --- a/doc/intro.sgml +++ b/doc/intro.sgml @@ -402,11 +402,36 @@ RUN The emulation, also, supports that method. +<sect1>Commander X16 + +<sect2>x16-emulator<p> +Available at <url +url="https://github.com/commanderx16/x16-emulator/releases">: + +Emulates the Commander X16 Single Board Computer, with sound, SD card images, +VGA and NTSC video, and a NES game controller emulation. Includes a monitor. +It runs on all SDL2 platforms. + +Compile the tutorial with +<tscreen><verb> +cl65 -O -t cx16 hello.c text.s +</verb></tscreen> + +Start the emulator. Then, type +<tscreen><verb> +LOAD"HELLO",1 +RUN +</verb></tscreen> +(Type those lines in lower-case; but, they will appear as upper-case.) + +On a real computer, you would type an <tt/8/ instead of a <tt/1/. + + <sect1>Commodore <sect2>VICE<p> Available at <url -url="http://vice-emu.sourceforge.net/">: +url="https://vice-emu.sourceforge.net/">: Emulates Commodore 64/128/VIC-20/PET/CBM II/Plus 4 computers. Supports printers, serial port and adapters, stereo sound, disk drives and images, RAM expansions, diff --git a/include/cbm.h b/include/cbm.h index 0a2d64694..d9b31543f 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -65,6 +65,8 @@ # include <cbm610.h> #elif defined(__PET__) && !defined(_PET_H) # include <pet.h> +#elif defined(__CX16__) && !defined(_CX16_H) +# include <cx16.h> #endif /* Include definitions for CBM file types */ @@ -300,5 +302,3 @@ void __fastcall__ cbm_closedir (unsigned char lfn); /* End of cbm.h */ #endif - - diff --git a/include/cx16.h b/include/cx16.h new file mode 100644 index 000000000..db32d8460 --- /dev/null +++ b/include/cx16.h @@ -0,0 +1,189 @@ +/*****************************************************************************/ +/* */ +/* cx16.h */ +/* */ +/* CX16 system-specific definitions */ +/* */ +/* */ +/* 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 _CX16_H +#define _CX16_H + + + +/* Check for errors */ +#ifndef __CX16__ +# error This module may be used only when compiling for the CX16! +#endif + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Additional key defines */ +#define CH_F1 0x85 +#define CH_F2 0x89 +#define CH_F3 0x86 +#define CH_F4 0x8A +#define CH_F5 0x87 +#define CH_F6 0x8B +#define CH_F7 0x88 +#define CH_F8 0x8C +#define CH_F9 0x10 +#define CH_F10 0x15 +#define CH_F11 0x16 +#define CH_F12 0x17 + +/* Color defines */ +#define COLOR_BLACK 0x00 +#define COLOR_WHITE 0x01 +#define COLOR_RED 0x02 +#define COLOR_CYAN 0x03 +#define COLOR_VIOLET 0x04 +#define COLOR_PURPLE COLOR_VIOLET +#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_BTN_1_MASK 0x80 +#define JOY_BTN_2_MASK 0x40 +#define JOY_BTN_3_MASK 0x20 +#define JOY_BTN_4_MASK 0x10 +#define JOY_UP_MASK 0x08 +#define JOY_DOWN_MASK 0x04 +#define JOY_LEFT_MASK 0x02 +#define JOY_RIGHT_MASK 0x01 + +#define JOY_BTN_A_MASK JOY_BTN_1_MASK +#define JOY_BTN_B_MASK JOY_BTN_2_MASK +#define JOY_SELECT_MASK JOY_BTN_3_MASK +#define JOY_START_MASK JOY_BTN_4_MASK + +#define JOY_BTN_A(v) ((v) & JOY_BTN_A_MASK) +#define JOY_BTN_B(v) ((v) & JOY_BTN_B_MASK) +#define JOY_SELECT(v) ((v) & JOY_SELECT_MASK) +#define JOY_START(v) ((v) & JOY_START_MASK) + +#define JOY_FIRE2_MASK JOY_BTN_2_MASK +#define JOY_FIRE2(v) ((v) & JOY_FIRE2_MASK) + +/* get_tv() return codes +** set_tv() argument codes +*/ +#define TV_NONE 0 +#define TV_VGA 1 +#define TV_NTSC_COLOR 2 +#define TV_RGB 3 +#define TV_NONE2 4 +#define TV_VGA2 5 +#define TV_NTSC_MONO 6 +#define TV_RGB2 7 + +/* Video mode defines */ +#define VIDEOMODE_40x30 40u +#define VIDEOMODE_80x60 80u +#define VIDEOMODE_40COL VIDEOMODE_40x30 +#define VIDEOMODE_80COL VIDEOMODE_80x60 + + +/* Define hardware */ + +/* Define a structure with the Video Enhanced Retro Adapter's +** external registers. +*/ +struct __vera { + unsigned short address; /* Address for data ports */ + unsigned char address_hi; + unsigned char data0; /* Data port 0 */ + unsigned char data1; /* Data port 1 */ + unsigned char control; /* Control register */ + unsigned char irq_enable; /* Interrupt enable bits */ + unsigned char irq_flags; /* Interrupt flags */ +}; +#define VERA (*(volatile struct __vera *)0x9F20) + +#include <_6522.h> +#define VIA1 (*(volatile struct __6522 *)0x9F60) +#define VIA2 (*(volatile struct __6522 *)0x9F70) + +/* Define a structure with the x16emu's settings registers. */ +struct __emul { + unsigned char debug; /* Boolean: debugging enabled */ + unsigned char vera_action; /* Boolean: displaying VERA activity */ + unsigned char keyboard; /* Boolean: displaying typed keys */ + unsigned char echo; /* Boolean: Kernal output echoed to host */ + unsigned char save_on_exit; /* Boolean: save SD card when quitting */ + unsigned char unused[0xD - 0x5]; + unsigned char keymap; /* Keyboard layout number */ + const char detect[2]; /* "16" if running on x16emu */ +}; +#define EMULATOR (*(volatile struct __emul)0x9FB0) + + + +/* The addresses of the static drivers */ + +extern void cx16_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +signed char get_ostype (void); +/* Get the ROM build version. +** -1 -- custom build +** Negative -- prerelease build +** Positive -- release build +*/ + +void __fastcall__ set_tv (unsigned char); +/* Set the video mode the machine will use. +** Call with a TV_xx constant. +*/ + +unsigned char __fastcall__ videomode (unsigned char Mode); +/* Set the video mode, return the old mode. Call with one of the VIDEOMODE_xx +** constants. +*/ + + + +/* End of cX16.h */ +#endif diff --git a/libsrc/Makefile b/libsrc/Makefile index 0ebec46b1..d9ddb3ccd 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -7,6 +7,7 @@ CBMS = c128 \ c64 \ cbm510 \ cbm610 \ + cx16 \ pet \ plus4 \ vic20 diff --git a/libsrc/cx16/_scrsize.s b/libsrc/cx16/_scrsize.s new file mode 100644 index 000000000..8059f04d9 --- /dev/null +++ b/libsrc/cx16/_scrsize.s @@ -0,0 +1,14 @@ +; +; 2019-09-16, Greg King +; +; Screen size info +; + + .export screensize + + .include "cx16.inc" + +screensize: + ldx LLEN + ldy NLINES + rts diff --git a/libsrc/cx16/bankramaddr.s b/libsrc/cx16/bankramaddr.s new file mode 100644 index 000000000..53d96e916 --- /dev/null +++ b/libsrc/cx16/bankramaddr.s @@ -0,0 +1,50 @@ +; +; 2019-09-16, Greg King +; +; This module supplies the load addresses that are expected +; by a Commander X16 in the first two bytes of banked RAM load files. +; + + ; The following symbol is used by a linker config. to force + ; this module to get included into the output files. + .export __BANKRAMADDR__: abs = 1 + +.segment "BRAM00ADDR" + + .addr *+2 + +.segment "BRAM01ADDR" + + .addr *+2 + +.segment "BRAM02ADDR" + + .addr *+2 + +.segment "BRAM03ADDR" + + .addr *+2 + +.segment "BRAM04ADDR" + + .addr *+2 + +.segment "BRAM05ADDR" + + .addr *+2 + +.segment "BRAM06ADDR" + + .addr *+2 + +.segment "BRAM07ADDR" + + .addr *+2 + +.segment "BRAM08ADDR" + + .addr *+2 + +.segment "BRAM09ADDR" + + .addr *+2 diff --git a/libsrc/cx16/bordercolor.s b/libsrc/cx16/bordercolor.s new file mode 100644 index 000000000..6691e2ec5 --- /dev/null +++ b/libsrc/cx16/bordercolor.s @@ -0,0 +1,27 @@ +; +; 2019-09-23, Greg King +; +; unsigned char __fastcall__ bordercolor (unsigned char color); +; /* Set the color for the border. The old color setting is returned. */ +; + + .export _bordercolor + + .include "cx16.inc" + +_bordercolor: + tax + + ; Point to the border color register. + + stz VERA::CTRL ; Use port 0 + lda #<VERA::COMPOSER::FRAME + sta VERA::ADDR + lda #>VERA::COMPOSER::FRAME + sta VERA::ADDR+1 + ldy #^VERA::COMPOSER::FRAME | VERA::INC0 + sty VERA::ADDR+2 + + lda VERA::DATA0 ; get old value + stx VERA::DATA0 ; set new value + rts diff --git a/libsrc/cx16/break.s b/libsrc/cx16/break.s new file mode 100644 index 000000000..ec569b9a7 --- /dev/null +++ b/libsrc/cx16/break.s @@ -0,0 +1,109 @@ +; +; 1998-09-27, Ullrich von Bassewitz +; 2019-09-08, Greg King +; +; void __fastcall__ set_brk (unsigned Addr); +; void reset_brk (void); +; + + .export _set_brk, _reset_brk + .destructor _reset_brk + .export _brk_a, _brk_x, _brk_y, _brk_sr, _brk_pc + + .include "cx16.inc" + + +.bss +_brk_a: .res 1 +_brk_x: .res 1 +_brk_y: .res 1 +_brk_sr: .res 1 +_brk_pc: .res 2 + +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 + + pla + sta _brk_y + pla + sta _brk_x + pla + sta _brk_a + pla + and #$EF ; Clear break bit + sta _brk_sr + pla ; PC low + sec + sbc #2 ; Point to start of brk + sta _brk_pc + pla ; PC high + sbc #0 + sta _brk_pc+1 + + 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/cx16/cgetc.s b/libsrc/cx16/cgetc.s new file mode 100644 index 000000000..14cad5f5a --- /dev/null +++ b/libsrc/cx16/cgetc.s @@ -0,0 +1,72 @@ +; +; 2019-09-23, Greg King +; +; char cgetc (void); +; /* Return a character from the keyboard. */ +; + + .export _cgetc + + .import cursor, GETIN + + .include "cx16.inc" + .macpack generic + + +_cgetc: ldx KEY_COUNT ; Get number of characters + bnz L3 ; Jump if there are already chars waiting + +; Switch the cursor on if wanted. + + lda CURS_FLAG ; Save cursor's current enable flag + tay + lda cursor + jsr setcursor +L1: lda KEY_COUNT + bze L1 ; Wait for key + tya + eor #%00000001 ; (Cursor flag uses negative logic) + jsr setcursor ; Restore previous cursor condition + +; An internal Kernal function can't be used because it might be moved in future +; revisions. Use an official function; but, make sure that it reads +; the keyboard. + +L3: ldy IN_DEV ; Save current input device + stz IN_DEV ; Keyboard + jsr GETIN ; Read char, and return in .A + sty IN_DEV ; Restore input device + ldx #>$0000 + rts + +; Switch the cursor on or off. + +setcursor: + tax ; On or off? + bnz seton ; Go set it on + lda CURS_FLAG ; Is the cursor currently off? + bnz crs9 ; Jump if yes + inc CURS_FLAG ; Mark it as off + ldx CURS_STATE ; Cursor currently displayed? + bze crs9 ; Jump if not + +; Restore the current character in video RAM. +; Restore that character's colors. + + stz VERA::CTRL ; Use port 0 + lda CURS_Y + sta VERA::ADDR+1 ; Set row number + lda #VERA::INC1 ; Increment address by one + sta VERA::ADDR+2 + lda CURS_X ; Get character column + asl a + sta VERA::ADDR + ldx CURS_CHAR + stx VERA::DATA0 + ldx CURS_COLOR + stx VERA::DATA0 + stz CURS_STATE ; Cursor not displayed +crs9: rts + +seton: stz CURS_FLAG + rts diff --git a/libsrc/cx16/clrscr.s b/libsrc/cx16/clrscr.s new file mode 100644 index 000000000..51fae6bf2 --- /dev/null +++ b/libsrc/cx16/clrscr.s @@ -0,0 +1,26 @@ +; +; 2019-09-22, Greg King +; +; void clrscr (void); +; /* Clear the screen. */ +; + + .export _clrscr + + .import CHROUT + + .include "cx16.inc" + + +; An internal Kernal function can't be used because it might be moved in future +; revisions. Use an official function; but, make sure that it prints +; to the screen. + +_clrscr: + ldy OUT_DEV ; Save current output device + ldx #$03 ; Screen device + stx OUT_DEV + lda #$93 + jsr CHROUT ; Print clear-screen character + sty OUT_DEV ; Restore output device + rts diff --git a/libsrc/cx16/color.s b/libsrc/cx16/color.s new file mode 100644 index 000000000..1be01c473 --- /dev/null +++ b/libsrc/cx16/color.s @@ -0,0 +1,43 @@ +; +; 2019-09-16, Greg King +; +; unsigned char __fastcall__ textcolor (unsigned char color); +; unsigned char __fastcall__ bgcolor (unsigned char color); +; + + + .export _textcolor, _bgcolor + + .importzp tmp1 + .include "cx16.inc" + +_textcolor: + and #$0F + sta tmp1 + ldx CHARCOLOR ; get old values + txa + and #<~$0F ; keep screen color, remove text color + ora tmp1 + sta CHARCOLOR ; set new values + txa + and #$0F + rts + + +_bgcolor: + asl a ; move number to screen-color nybble + asl a + asl a + asl a + sta tmp1 + ldx CHARCOLOR ; get old values + txa + and #<~$F0 ; remove screen color, keep text color + ora tmp1 + sta CHARCOLOR ; set new values + txa + lsr a ; get screen color + lsr a + lsr a + lsr a + rts diff --git a/libsrc/cx16/conio.s b/libsrc/cx16/conio.s new file mode 100644 index 000000000..e760af21c --- /dev/null +++ b/libsrc/cx16/conio.s @@ -0,0 +1,9 @@ +; +; 2019-09-23, Greg King +; +; Low-level stuff for screen output/console input +; + + .exportzp CURS_X, CURS_Y + + .include "cx16.inc" diff --git a/libsrc/cx16/cpeekc.s b/libsrc/cx16/cpeekc.s new file mode 100644 index 000000000..2f02623bf --- /dev/null +++ b/libsrc/cx16/cpeekc.s @@ -0,0 +1,48 @@ +; +; 2016-02-28, Groepaz +; 2019-09-25, Greg King +; +; char cpeekc (void); +; /* Return the character from the current cursor position. */ +; + + .export _cpeekc + + .include "cx16.inc" + + +_cpeekc: + php + sei ; don't let cursor blinking interfere + stz VERA::CTRL ; use port 0 + lda CURS_Y + sta VERA::ADDR+1 ; set row number + stz VERA::ADDR+2 + lda CURS_X ; get character column + asl a + sta VERA::ADDR + lda VERA::DATA0 ; get screen code + plp + ldx #>$0000 + and #<~%10000000 ; 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/cx16/cpeekcolor.s b/libsrc/cx16/cpeekcolor.s new file mode 100644 index 000000000..4e3a39a2c --- /dev/null +++ b/libsrc/cx16/cpeekcolor.s @@ -0,0 +1,27 @@ +; +; 2019-09-25, Greg King +; +; unsigned char cpeekcolor (void); +; /* Return the colors from the current cursor position. */ +; + + .export _cpeekcolor + + .include "cx16.inc" + + +_cpeekcolor: + php + sei ; don't let cursor blinking interfere + stz VERA::CTRL ; use port 0 + lda CURS_Y + sta VERA::ADDR+1 ; set row number + stz VERA::ADDR+2 + lda CURS_X ; get character column + sec ; color attribute is second byte + rol a + sta VERA::ADDR + lda VERA::DATA0 ; get color + plp + ldx #>$0000 + rts diff --git a/libsrc/cx16/cpeekrevers.s b/libsrc/cx16/cpeekrevers.s new file mode 100644 index 000000000..d67dd2956 --- /dev/null +++ b/libsrc/cx16/cpeekrevers.s @@ -0,0 +1,32 @@ +; +; 2016-02-28, Groepaz +; 2019-09-25, Greg King +; +; unsigned char cpeekrevers (void); +; /* Return the reverse attribute from the current cursor position. +; ** If the character is reversed, then return 1; return 0 otherwise. +; */ +; + + .export _cpeekrevers + + .include "cx16.inc" + + +_cpeekrevers: + php + sei ; don't let cursor blinking interfere + stz VERA::CTRL ; use port 0 + lda CURS_Y + sta VERA::ADDR+1 ; set row number + stz VERA::ADDR+2 + lda CURS_X ; get character column + asl a + sta VERA::ADDR + lda VERA::DATA0 ; get screen code + plp + and #%10000000 ; get reverse bit + asl a + tax ; ldx #>$0000 + rol a ; return boolean value + rts diff --git a/libsrc/cx16/cpeeks.s b/libsrc/cx16/cpeeks.s new file mode 100644 index 000000000..e69de29bb diff --git a/libsrc/cx16/cputc.s b/libsrc/cx16/cputc.s new file mode 100644 index 000000000..cf0a5fa22 --- /dev/null +++ b/libsrc/cx16/cputc.s @@ -0,0 +1,98 @@ +; +; 2019-09-23, Greg King +; +; 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, PLOT + + .include "cx16.inc" + .macpack generic + + +; First, move to a new position. + +_cputcxy: + pha ; Save C + jsr gotoxy ; Set cursor, drop x and y + pla ; Restore C + +; Print a character. + +_cputc: cmp #$0D ; LF? + beq newline + cmp #$0A ; CR? + beq plotx0 + +; Printable char of some sort + + cmp #' ' + blt cputdirect ; Other control char + tay + bmi L10 + cmp #$60 + blt L2 + and #<~%00100000 + bra cputdirect + +; Handle character if high bit set + +L10: and #<~%10000000 ; Remove high bit + ora #%01000000 + bra cputdirect + +L2: and #<~%01000000 + +cputdirect: + jsr putchar ; Write character to screen, return .Y + +; Advance cursor position. + + iny + cpy LLEN ; Reached end of line? + bne L3 + jsr newline ; Next line + ldy #$00 ; + CR +L3: sty CURS_X + rts + +; Move down. + +newline: + inc SCREEN_PTR+1 + inc CURS_Y + rts + + +; Set the cursor's position, calculate RAM pointer. + +plotx0: stz CURS_X +plot: ldy CURS_X + ldx CURS_Y + clc + jmp PLOT ; Set the new cursor + + +; Write one screen-code and color to the video RAM without doing anything else. +; Return the x position in Y. + +putchar: + ora RVS ; Set revers bit + tax + stz VERA::CTRL ; Use port 0 + lda CURS_Y + sta VERA::ADDR+1 ; Set row number + lda #VERA::INC1 ; Increment address by one + sta VERA::ADDR+2 + ldy CURS_X ; Get character column + tya + asl a + sta VERA::ADDR + stx VERA::DATA0 + lda CHARCOLOR + sta VERA::DATA0 + rts diff --git a/libsrc/cx16/crt0.s b/libsrc/cx16/crt0.s new file mode 100644 index 000000000..181e63081 --- /dev/null +++ b/libsrc/cx16/crt0.s @@ -0,0 +1,115 @@ +; +; Start-up code for cc65 (CX16 version) +; + + .export _exit + .export __STARTUP__ : absolute = 1 ; Mark as start-up + + .import initlib, donelib + .import zerobss, callmain + .import BSOUT + .import __MAIN_START__, __MAIN_SIZE__ ; Linker-generated + .importzp ST + + .include "zeropage.inc" + .include "cx16.inc" + + +; ------------------------------------------------------------------------ +; Start-up code + +.segment "STARTUP" + +Start: tsx + stx spsave ; Save the system stack ptr + +; Save space by putting some of the start-up code in the ONCE segment, +; which will 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 sp,x + dex + bpl L2 + +; Place the program return code into BASIC's status variable. + + pla + sta ST + +; Restore the system stuff. + + ldx spsave + txs ; Restore stack pointer + ldx banksave + stx VIA1::PRA2 ; Restore former RAM bank + +; Back to BASIC. + + rts + + +; ------------------------------------------------------------------------ + +.segment "ONCE" + +init: + +; Change to the first RAM bank. + + lda VIA1::PRA2 + sta banksave ; Save the current bank number + lda #$00 ; Choose RAM bank zero + sta VIA1::PRA2 + +; Save the zero-page locations that we need. + + ldx #zpspace-1 +L1: lda sp,x + sta zpsave,x + dex + bpl L1 + +; Set up the stack. + + lda #<(__MAIN_START__ + __MAIN_SIZE__) + ldx #>(__MAIN_START__ + __MAIN_SIZE__) + sta sp + stx sp+1 ; Set argument stack ptr + +; Switch to the second charset. + + lda #$0E + jsr BSOUT + +; Call the module constructors. + + jmp initlib + + +; ------------------------------------------------------------------------ +; Data + +.segment "INIT" + +banksave: + .res 1 +spsave: .res 1 +zpsave: .res zpspace diff --git a/libsrc/cx16/devnum.s b/libsrc/cx16/devnum.s new file mode 100644 index 000000000..6a59d6ecd --- /dev/null +++ b/libsrc/cx16/devnum.s @@ -0,0 +1,8 @@ +; +; 2010-02-14, Oliver Schmidt +; 2019-09-08, Greg King +; + + .include "cx16.inc" + + .exportzp devnum := DEVNUM diff --git a/libsrc/cx16/get_ostype.s b/libsrc/cx16/get_ostype.s new file mode 100644 index 000000000..a778b6eae --- /dev/null +++ b/libsrc/cx16/get_ostype.s @@ -0,0 +1,20 @@ +; +; 2019-09-09, Greg King +; +; signed char get_ostype(void) +; /* Return a "build version". */ +; +; Positive number -- release build +; Negative number -- prerelease build +; -1 -- custom build +; + + .export _get_ostype + +.proc _get_ostype + ldx #>$0000 + lda $ff80 + bpl :+ + dex ; negative +: rts +.endproc diff --git a/libsrc/cx16/get_tv.s b/libsrc/cx16/get_tv.s new file mode 100644 index 000000000..79a577dff --- /dev/null +++ b/libsrc/cx16/get_tv.s @@ -0,0 +1,31 @@ +; +; 2019-09-20, Greg King +; +; unsigned char get_tv (void); +; /* Return the video mode the machine is using. */ +; + + .export _get_tv + + .include "cx16.inc" + + +.proc _get_tv + php + sei ; Don't let interrupts interfere + + ; Point to the video output register. + + stz VERA::CTRL ; Use port 0 + lda #<VERA::COMPOSER::VIDEO + ldx #>VERA::COMPOSER::VIDEO + ldy #^VERA::COMPOSER::VIDEO + sta VERA::ADDR + stx VERA::ADDR+1 + sty VERA::ADDR+2 + + lda VERA::DATA0 + plp ; Re-enable interrupts + and #$07 ; Get the type of output signal + rts +.endproc diff --git a/libsrc/cx16/irq.s b/libsrc/cx16/irq.s new file mode 100644 index 000000000..0d9d54c60 --- /dev/null +++ b/libsrc/cx16/irq.s @@ -0,0 +1,48 @@ +; +; IRQ handling (CX16 version) +; + + .export initirq, doneirq + .import callirq + + .include "cx16.inc" + +; ------------------------------------------------------------------------ + +.segment "ONCE" + +initirq: + lda IRQVec + ldx IRQVec+1 + sta IRQInd+1 + stx IRQInd+2 + lda #<IRQStub + ldx #>IRQStub + jmp setvec + +; ------------------------------------------------------------------------ + +.code + +doneirq: + lda IRQInd+1 + ldx IRQInd+2 +setvec: sei + sta IRQVec + stx IRQVec+1 + cli + rts + +; ------------------------------------------------------------------------ + +.segment "LOWCODE" + +IRQStub: + jsr callirq ; Call the functions + jmp IRQInd ; Jump to the saved IRQ vector + +; ------------------------------------------------------------------------ + +.data + +IRQInd: jmp $0000 diff --git a/libsrc/cx16/joy/cx16-stdjoy.s b/libsrc/cx16/joy/cx16-stdjoy.s new file mode 100644 index 000000000..8c7ddd2f2 --- /dev/null +++ b/libsrc/cx16/joy/cx16-stdjoy.s @@ -0,0 +1,119 @@ +; +; Standard joystick driver for the CX16. +; May be used multiple times when statically linked to the application. +; +; 2019-09-23, Greg King +; + + .include "joy-kernel.inc" + .include "joy-error.inc" + + .include "cbm_kernal.inc" + .include "cx16.inc" + + .macpack generic + .macpack module + + +; ------------------------------------------------------------------------ +; Header. Includes jump table + + module_header _cx16_stdjoy_joy + +; Driver signature + + .byte $6A, $6F, $79 ; ASCII "joy" + .byte JOY_API_VERSION ; Driver API version number + +; Library reference + + .addr $0000 + +; Jump table. + + .addr INSTALL + .addr UNINSTALL + .addr COUNT + .addr READ + +; ------------------------------------------------------------------------ +; Constant + +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 a JOY_ERR_xx code in a/x. +; + +INSTALL: + lda #<JOY_ERR_OK + ldx #>JOY_ERR_OK +; rts ; Run into UNINSTALL instead + +; ------------------------------------------------------------------------ +; UNINSTALL routine. Is called before the driver is removed from memory. +; Can do clean-up or whatever. Must not return anything. +; + +UNINSTALL: + rts + +; ------------------------------------------------------------------------ +; COUNT: Return the total number of possible joysticks in a/x. +; + +COUNT: lda #<JOY_COUNT + ldx #>JOY_COUNT + rts + +; ------------------------------------------------------------------------ +; READ: Read a particular joystick passed in A. +; +; TODO: Find a way to report the SNES controller's extra four lines. +; + +READ: pha + jsr GETJOY + pla + bne pad2 + +; Read game pad 1 + +pad1: lda JOY1 + 1 + bit #%00001110 + beq nes1 + asl JOY1 ; Get SNES's B button + ror a ; Put it next to the A button + asl JOY1 ; Drop SNES's Y button + asl a ; Get the B button + ror JOY1 + asl a ; Get SNES's A button + ror JOY1 ; Make byte look like NES pad +nes1: lda JOY1 + eor #%11111111 ; We don't want the pad's negative logic + rts + +; Read game pad 2 + +pad2: lda JOY2 + 1 + bit #%00001110 + beq nes2 + asl JOY2 + ror a + asl JOY2 + asl a + ror JOY2 + asl a + ror JOY2 +nes2: lda JOY2 + eor #%11111111 + rts diff --git a/libsrc/cx16/joy_stat_stddrv.s b/libsrc/cx16/joy_stat_stddrv.s new file mode 100644 index 000000000..0e1a3e94d --- /dev/null +++ b/libsrc/cx16/joy_stat_stddrv.s @@ -0,0 +1,10 @@ +; +; Address of the static standard joystick driver +; +; 2019-09-19, Greg King +; +; const void joy_static_stddrv[]; +; + + .import _cx16_stdjoy_joy + .export _joy_static_stddrv := _cx16_stdjoy_joy diff --git a/libsrc/cx16/joy_stddrv.s b/libsrc/cx16/joy_stddrv.s new file mode 100644 index 000000000..4edf9afc0 --- /dev/null +++ b/libsrc/cx16/joy_stddrv.s @@ -0,0 +1,13 @@ +; +; Name of the standard joystick driver +; +; 2019-09-19, Greg King +; +; const char joy_stddrv[]; +; + + .export _joy_stddrv + +.rodata + +_joy_stddrv: .asciiz "cx16-stdjoy.joy" diff --git a/libsrc/cx16/kbhit.s b/libsrc/cx16/kbhit.s new file mode 100644 index 000000000..8ceba64be --- /dev/null +++ b/libsrc/cx16/kbhit.s @@ -0,0 +1,17 @@ +; +; 2019-09-20, Greg King +; +; unsigned char kbhit (void); +; /* Returns non-zero (true) if a typed character is waiting. */ +; + + .export _kbhit + + .include "cx16.inc" + + +.proc _kbhit + ldx #>$0000 ; High byte of return + lda KEY_COUNT ; Get number of characters + rts +.endproc diff --git a/libsrc/cx16/kernal.s b/libsrc/cx16/kernal.s new file mode 100644 index 000000000..faf91385a --- /dev/null +++ b/libsrc/cx16/kernal.s @@ -0,0 +1,59 @@ +; +; 2019-09-22, Greg King +; +; CX16 Kernal functions +; + + .include "cbm_kernal.inc" + + .export GETJOY + + .export CLSALL + .export SWAPPER + .export JSRFAR + .export INDFET + .export INDSTA + .export INDCMP + .export PRIMM + + .export CINT + .export IOINIT + .export RAMTAS + .export RESTOR + .export VECTOR + .export SETMSG + .export SECOND + .export TKSA + .export MEMTOP + .export MEMBOT + .export SCNKEY + .export SETTMO + .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 PLOT + .export IOBASE diff --git a/libsrc/cx16/libref.s b/libsrc/cx16/libref.s new file mode 100644 index 000000000..54ebb91d2 --- /dev/null +++ b/libsrc/cx16/libref.s @@ -0,0 +1,18 @@ +; +; 2013-05-31, Oliver Schmidt +; 2019-09-22, Greg King +; + + .export em_libref + .export joy_libref + .export mouse_libref + .export ser_libref + .export tgi_libref + + .import _exit + +em_libref := _exit +joy_libref := _exit +mouse_libref := _exit +ser_libref := _exit +tgi_libref := _exit diff --git a/libsrc/cx16/mainargs.s b/libsrc/cx16/mainargs.s new file mode 100644 index 000000000..fe4a071c7 --- /dev/null +++ b/libsrc/cx16/mainargs.s @@ -0,0 +1,137 @@ +; mainargs.s +; +; Ullrich von Bassewitz, 2003-03-07 +; Based on code from Stefan A. Haubenthal, <polluks@web.de> +; 2005-02-26, Ullrich von Bassewitz +; 2019-09-08, Greg King +; +; 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 "cx16.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/cx16/revers.s b/libsrc/cx16/revers.s new file mode 100644 index 000000000..300237ee8 --- /dev/null +++ b/libsrc/cx16/revers.s @@ -0,0 +1,23 @@ +; +; 2019-09-16, Greg King +; +; unsigned char __fastcall__ revers (unsigned char onoff); +; + + .export _revers + + .include "cx16.inc" + +.proc _revers + ldy #$00 ; Assume revers off + tax ; Test on/off + beq :+ ; Jump if off + ldy #$80 ; Load "on" value + ldx #>$0000 ; Zero high byte of result +: lda RVS ; Load old value + sty RVS ; Set new value + clc + rol a ; Convert bit-mask into boolean + rol a + rts +.endproc diff --git a/libsrc/cx16/set_tv.s b/libsrc/cx16/set_tv.s new file mode 100644 index 000000000..0cf49aff7 --- /dev/null +++ b/libsrc/cx16/set_tv.s @@ -0,0 +1,32 @@ +; +; 2019-09-20, Greg King +; +; void __fastcall__ set_tv (unsigned char); +; /* Set the video mode the machine will use. */ +; + + .export _set_tv + + .include "cx16.inc" + + +.proc _set_tv + php + pha + sei ; Don't let interrupts interfere + + ; Point to the video output register. + + stz VERA::CTRL ; Use port 0 + lda #<VERA::COMPOSER::VIDEO + ldx #>VERA::COMPOSER::VIDEO + ldy #^VERA::COMPOSER::VIDEO + sta VERA::ADDR + stx VERA::ADDR+1 + sty VERA::ADDR+2 + + pla + sta VERA::DATA0 + plp ; Re-enable interrupts + rts +.endproc diff --git a/libsrc/cx16/status.s b/libsrc/cx16/status.s new file mode 100644 index 000000000..6292dc274 --- /dev/null +++ b/libsrc/cx16/status.s @@ -0,0 +1,6 @@ +; +; 2012-09-30, Oliver Schmidt +; 2019-09-08, Greg King +; + + .exportzp ST := $90 ; IEC status byte diff --git a/libsrc/cx16/sysuname.s b/libsrc/cx16/sysuname.s new file mode 100644 index 000000000..f8500936b --- /dev/null +++ b/libsrc/cx16/sysuname.s @@ -0,0 +1,37 @@ +; +; 2003-08-12, Ullrich von Bassewitz +; 2019-09-08, Greg King +; +; 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 ((.VERSION >> 8) & $0F) + '0' + .byte '.' + .byte ((.VERSION >> 4) & $0F) + '0' + .byte $00 + + ; version + .byte (.VERSION & $0F) + '0' + .byte $00 + + ; machine + .asciiz "Commander X16" diff --git a/libsrc/cx16/videomode.s b/libsrc/cx16/videomode.s new file mode 100644 index 000000000..4582ec1bd --- /dev/null +++ b/libsrc/cx16/videomode.s @@ -0,0 +1,30 @@ +; +; 2009-09-07, Ullrich von Bassewitz +; 2019-09-23, Greg King +; +; unsigned __fastcall__ videomode (unsigned Mode); +; /* Set the video mode, return the old mode. */ +; + + .export _videomode + .import SWAPPER + + .include "cx16.inc" + + +.proc _videomode + cmp LLEN ; Do we have this mode already? + beq @L9 + + lda LLEN ; Get current mode ... + pha ; ... and save it + + jsr SWAPPER ; Toggle the mode + + pla ; Get old mode into A + +; Done, old mode is in .A + +@L9: ldx #>$0000 ; Clear high byte + rts +.endproc diff --git a/libsrc/cx16/waitvsync.s b/libsrc/cx16/waitvsync.s new file mode 100644 index 000000000..3fb6354f0 --- /dev/null +++ b/libsrc/cx16/waitvsync.s @@ -0,0 +1,17 @@ +; +; 2019-09-26, Greg King +; +; void waitvsync (void); +; +; VERA's vertical sync. causes IRQs which increment the jiffy clock. +; + + .export _waitvsync + + .include "cx16.inc" + +_waitvsync: + lda TIME + 2 +: cmp TIME + 2 + beq :- ; Wait for next jiffy + rts diff --git a/src/ca65/main.c b/src/ca65/main.c index 33e0a74b5..ab19d0b4d 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -296,7 +296,7 @@ static void SetSys (const char* Sys) case TGT_ATMOS: NewSymbol ("__ATMOS__", 1); - break; + break; case TGT_TELESTRAT: NewSymbol ("__TELESTRAT__", 1); @@ -330,6 +330,10 @@ static void SetSys (const char* Sys) NewSymbol ("__PCE__", 1); break; + case TGT_CX16: + CBMSystem ("__CX16__"); + break; + default: AbEnd ("Invalid target name: '%s'", Sys); diff --git a/src/cc65/main.c b/src/cc65/main.c index 871e21ebc..a4f794fb5 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -285,6 +285,10 @@ static void SetSys (const char* Sys) DefineNumericMacro ("__PCE__", 1); break; + case TGT_CX16: + cbmsys ("__CX16__"); + break; + default: AbEnd ("Unknown target system type %d", Target); } diff --git a/src/common/target.c b/src/common/target.c index 56ea0a2ff..a21ef2125 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -135,11 +135,11 @@ static const unsigned char CTPET[256] = { typedef struct TargetEntry TargetEntry; struct TargetEntry { char Name[13]; /* Target name */ - target_t Id; /* Target id */ + target_t Id; /* Target ID */ }; -/* Table that maps target names to ids. Sorted alphabetically for bsearch. -** Allows multiple entries for one target id (target name aliases). +/* Table that maps target names to IDs. Sorted alphabetically for bsearch(). +** Allows multiple entries for one target ID (target name aliases). */ static const TargetEntry TargetMap[] = { { "apple2", TGT_APPLE2 }, @@ -157,6 +157,7 @@ static const TargetEntry TargetMap[] = { { "cbm510", TGT_CBM510 }, { "cbm610", TGT_CBM610 }, { "creativision", TGT_CREATIVISION }, + { "cx16", TGT_CX16 }, { "gamate", TGT_GAMATE }, { "geos", TGT_GEOS_CBM }, { "geos-apple", TGT_GEOS_APPLE }, @@ -179,7 +180,7 @@ static const TargetEntry TargetMap[] = { #define MAP_ENTRY_COUNT (sizeof (TargetMap) / sizeof (TargetMap[0])) -/* Table with target properties by target id */ +/* Table with target properties by target ID */ static const TargetProperties PropertyTable[TGT_COUNT] = { { "none", CPU_6502, BINFMT_BINARY, CTNone }, { "module", CPU_6502, BINFMT_O65, CTNone }, @@ -213,6 +214,7 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "pce", CPU_HUC6280, BINFMT_BINARY, CTNone }, { "gamate", CPU_6502, BINFMT_BINARY, CTNone }, { "c65", CPU_4510, BINFMT_BINARY, CTPET }, + { "cx16", CPU_65C02, BINFMT_BINARY, CTPET }, }; /* Target system */ @@ -235,7 +237,7 @@ static int Compare (const void* Key, const void* Entry) target_t FindTarget (const char* Name) -/* Find a target by name and return the target id. TGT_UNKNOWN is returned if +/* Find a target by name and return the target ID. TGT_UNKNOWN is returned if ** the given name is no valid target. */ { @@ -243,7 +245,7 @@ target_t FindTarget (const char* Name) const TargetEntry* T; T = bsearch (Name, TargetMap, MAP_ENTRY_COUNT, sizeof (TargetMap[0]), Compare); - /* Return the target id */ + /* Return the target ID */ return (T == 0)? TGT_UNKNOWN : T->Id; } @@ -252,7 +254,7 @@ target_t FindTarget (const char* Name) const TargetProperties* GetTargetProperties (target_t Target) /* Return the properties for a target */ { - /* Must have a valid target id */ + /* Must have a valid target ID */ PRECONDITION (Target >= 0 && Target < TGT_COUNT); /* Return the array entry */ diff --git a/src/common/target.h b/src/common/target.h index 5b086e40c..50c400e2e 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -84,6 +84,7 @@ typedef enum { TGT_PCENGINE, TGT_GAMATE, TGT_C65, + TGT_CX16, TGT_COUNT /* Number of target systems */ } target_t; @@ -102,7 +103,7 @@ extern target_t Target; /* Types of available output formats */ #define BINFMT_DEFAULT 0 /* Default (binary) */ #define BINFMT_BINARY 1 /* Straight binary format */ -#define BINFMT_O65 2 /* Andre Fachats o65 format */ +#define BINFMT_O65 2 /* Andre Fachat's o65 format */ #define BINFMT_ATARIEXE 3 /* Standard Atari binary load */ @@ -127,5 +128,4 @@ const char* GetTargetName (target_t Target); /* End of target.h */ - #endif diff --git a/testcode/lib/joy-test.c b/testcode/lib/joy-test.c index 3d584bf9d..53d63c5ce 100644 --- a/testcode/lib/joy-test.c +++ b/testcode/lib/joy-test.c @@ -1,4 +1,3 @@ -#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> @@ -14,16 +13,15 @@ # define DYN_DRV 0 /* -** link existing drivers like this: +** Link existing drivers this way: ** ** cl65 -DJOYSTICK_DRIVER=c64_hitjoy_joy -o joy-test.prg joy-test.c ** -** for testing a new driver you will have to uncomment the define below, and -** link your driver like this: +** For testing a new driver, you need to uncomment the declaration below, +** and link your driver this way: ** ** co65 ../../target/c64/drv/joy/c64-hitjoy.joy -o hitjoy.s --code-label _hitjoy ** cl65 -DJOYSTICK_DRIVER=hitjoy -o joy-test.prg joy-test.c hitjoy.s -** */ /* extern char JOYSTICK_DRIVER; */ @@ -40,10 +38,8 @@ int main (void) { unsigned char j; - unsigned char count; - unsigned char i; + unsigned char i, count; unsigned char Res; - unsigned char ch, kb; clrscr (); @@ -58,47 +54,69 @@ int main (void) if (Res != JOY_ERR_OK) { cprintf ("Error in joy_load_driver: %u\r\n", Res); #if DYN_DRV - cprintf ("os: %u, %s\r\n", _oserror, _stroserror (_oserror)); + cprintf ("OS: %u, %s\r\n", _oserror, _stroserror (_oserror)); #endif - exit (EXIT_FAILURE); + return EXIT_FAILURE; } count = joy_count (); #if defined(__ATARI5200__) || defined(__CREATIVISION__) - cprintf ("JOYSTICKS: %d", count); + cprintf ("JOYSTICKS: %u.", count); #else - cprintf ("Driver supports %d joystick(s)", count); + cprintf ("Driver supports %u joystick%s", count, count == 1 ? "." : "s."); #endif while (1) { for (i = 0; i < count; ++i) { - gotoxy (0, i+1); j = joy_read (i); -#if defined(__ATARI5200__) || defined(__CREATIVISION__) - cprintf ("%1d:%-3s%-3s%-3s%-3s%-3s %02x", +#if defined(__NES__) || defined(__CX16__) + /* two lines for each device */ + gotoxy (0, i * 2 +1); + cprintf ("%2u:%-6s%-6s%-6s%-6s\r\n" + " %-6s%-6s%-6s%-6s $%02X", i, - JOY_UP(j)? " U " : " - ", - JOY_DOWN(j)? " D " : " - ", - JOY_LEFT(j)? " L " : " - ", - JOY_RIGHT(j)? " R " : " - ", - JOY_BTN_1(j)? " 1 " : " - ", j); + JOY_UP(j) ? " up " : " ---- ", + JOY_DOWN(j) ? " down " : " ---- ", + JOY_LEFT(j) ? " left " : " ---- ", + JOY_RIGHT(j) ? " right" : " ---- ", + JOY_BTN_1(j) ? "btn A " : " ---- ", + JOY_BTN_2(j) ? "btn B " : " ---- ", + JOY_BTN_3(j) ? "select" : " ---- ", + JOY_BTN_4(j) ? " start" : " ---- ", + j); #else - cprintf ("%2d: %-6s%-6s%-6s%-6s%-6s %02x", + /* one line for each device */ + gotoxy (0, i + 1); +# if defined(__ATARI5200__) || defined(__CREATIVISION__) + cprintf ("%1u:%-3s%-3s%-3s%-3s%-3s %02X", i, - JOY_UP(j)? " up " : " ---- ", - JOY_DOWN(j)? " down " : " ---- ", - JOY_LEFT(j)? " left " : " ---- ", - JOY_RIGHT(j)? "right " : " ---- ", - JOY_BTN_1(j)? "button" : " ---- ", j); + JOY_UP(j) ? " U " : " - ", + JOY_DOWN(j) ? " D " : " - ", + JOY_LEFT(j) ? " L " : " - ", + JOY_RIGHT(j) ? " R " : " - ", + JOY_BTN_1(j) ? " 1 " : " - ", + j); +# else + cprintf ("%2u: %-6s%-6s%-6s%-6s%-6s $%02X", + i, + JOY_UP(j) ? " up " : " ---- ", + JOY_DOWN(j) ? " down " : " ---- ", + JOY_LEFT(j) ? " left " : " ---- ", + JOY_RIGHT(j) ? "right " : " ---- ", + JOY_BTN_1(j) ? "button" : " ---- ", + j); +# endif #endif } - /* show pressed key, so we can verify keyboard is working */ - kb = kbhit (); - ch = kb ? cgetc () : ' '; - gotoxy (1, i+2); - revers (kb); - cprintf ("kbd: %c", ch); - revers (0); + /* Show any pressed keys; so that we can verify that the keyboard is working. */ + if (kbhit ()) { +#if defined(__NES__) || defined(__CX16__) + gotoxy (1, i * 2 + 2); +#else + gotoxy (1, i + 2); +#endif + cprintf ("keyboard: $%02X", cgetc ()); + } } - return 0; + return EXIT_SUCCESS; } From 6cae84a25da68d0970c54e55d3faf6efa28b0da1 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 28 Sep 2019 00:54:27 -0400 Subject: [PATCH 1155/2161] Updated the cx16 start-up to the emulator's release 32. Made the Kernal ROM be visible when programs start. --- libsrc/cx16/crt0.s | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/libsrc/cx16/crt0.s b/libsrc/cx16/crt0.s index 181e63081..a3a613bd1 100644 --- a/libsrc/cx16/crt0.s +++ b/libsrc/cx16/crt0.s @@ -7,7 +7,7 @@ .import initlib, donelib .import zerobss, callmain - .import BSOUT + .import CHROUT .import __MAIN_START__, __MAIN_SIZE__ ; Linker-generated .importzp ST @@ -58,8 +58,11 @@ L2: lda zpsave,x ldx spsave txs ; Restore stack pointer - ldx banksave + ldx ramsave stx VIA1::PRA2 ; Restore former RAM bank + lda VIA1::PRB + and #<~$07 + sta VIA1::PRB ; Change back to BASIC ROM ; Back to BASIC. @@ -71,11 +74,16 @@ L2: lda zpsave,x .segment "ONCE" init: +; Change from BASIC's ROM to Kernal's ROM. + + lda VIA1::PRB + ora #$07 + sta VIA1::PRB ; Change to the first RAM bank. lda VIA1::PRA2 - sta banksave ; Save the current bank number + sta ramsave ; Save the current RAM bank number lda #$00 ; Choose RAM bank zero sta VIA1::PRA2 @@ -97,7 +105,7 @@ L1: lda sp,x ; Switch to the second charset. lda #$0E - jsr BSOUT + jsr CHROUT ; Call the module constructors. @@ -109,7 +117,7 @@ L1: lda sp,x .segment "INIT" -banksave: +ramsave: .res 1 spsave: .res 1 zpsave: .res zpspace From 2546c6ba1c985d3280c4f9539af3080ec2233b1e Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 28 Sep 2019 01:38:16 -0400 Subject: [PATCH 1156/2161] Put the C64 code into cx16/_scrsize.s. (I forgot that SCREEN is an official jumptable function. --- libsrc/cx16/_scrsize.s | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/libsrc/cx16/_scrsize.s b/libsrc/cx16/_scrsize.s index 8059f04d9..f240b1e52 100644 --- a/libsrc/cx16/_scrsize.s +++ b/libsrc/cx16/_scrsize.s @@ -1,14 +1,10 @@ ; -; 2019-09-16, Greg King +; Ullrich von Bassewitz, 26.10.2000 ; -; Screen size info +; Screen size variables ; .export screensize + .import SCREEN - .include "cx16.inc" - -screensize: - ldx LLEN - ldy NLINES - rts +screensize := SCREEN From d7ec817f0a472d9e812a5e7c5da298a16c228168 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 30 Sep 2019 10:41:21 -0400 Subject: [PATCH 1157/2161] Fixed a typo in the cx16 document. --- doc/cx16.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/cx16.sgml b/doc/cx16.sgml index 077458bf6..b739e6a9d 100644 --- a/doc/cx16.sgml +++ b/doc/cx16.sgml @@ -240,7 +240,7 @@ No serial drivers are available currently for the CX16. <sect>Limitations<p> -The Commander X16 still is being designed. It's configuration can change at +The Commander X16 still is being designed. Its configuration can change at any time. Some changes could make old programs fail to work. From 3cece61525cec3def39ac4791b04cdaccb45c85b Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 1 Oct 2019 04:16:44 -0400 Subject: [PATCH 1158/2161] Added character codes to change between the two CBM fonts. --- include/cbm.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/cbm.h b/include/cbm.h index d9b31543f..96eb675cd 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -121,6 +121,8 @@ extern char _filetype; /* Defaults to 's' */ #define CH_STOP 3 #define CH_LIRA 92 #define CH_ESC 27 +#define CH_FONT_LOWER 14 +#define CH_FONT_UPPER 142 From 9dfc8f84bcc8b5ad4b50c16615a84b76cb7bedca Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 1 Oct 2019 05:30:36 -0400 Subject: [PATCH 1159/2161] Fixed cgetc(). The GETIN function doesn't protect CPU registers. --- libsrc/cx16/cgetc.s | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libsrc/cx16/cgetc.s b/libsrc/cx16/cgetc.s index 14cad5f5a..2c5ea76d1 100644 --- a/libsrc/cx16/cgetc.s +++ b/libsrc/cx16/cgetc.s @@ -1,5 +1,5 @@ ; -; 2019-09-23, Greg King +; 2019-10-01, Greg King ; ; char cgetc (void); ; /* Return a character from the keyboard. */ @@ -34,7 +34,9 @@ L1: lda KEY_COUNT L3: ldy IN_DEV ; Save current input device stz IN_DEV ; Keyboard + phy jsr GETIN ; Read char, and return in .A + ply sty IN_DEV ; Restore input device ldx #>$0000 rts From 2e5fbe89cd3f67b06b292936dfdf4fdb104b7112 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 2 Oct 2019 10:09:48 -0400 Subject: [PATCH 1160/2161] Made the "none" CPU allow all address sizes. --- src/common/cpu.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index b055fae88..c1ff400b8 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -95,20 +95,20 @@ int ValidAddrSizeForCPU (unsigned char AddrSize) return 1; case ADDR_SIZE_ZP: - /* Not supported by None and Sweet16 */ - return (CPU != CPU_NONE && CPU != CPU_SWEET16); + /* Not supported by Sweet16 */ + return (CPU != CPU_SWEET16); case ADDR_SIZE_ABS: - /* Not supported by None */ - return (CPU != CPU_NONE); + /* Always supported */ + return 1; case ADDR_SIZE_FAR: - /* Only supported by 65816 */ - return (CPU == CPU_65816); + /* Supported by "none" and 65816 */ + return (CPU == CPU_NONE && CPU == CPU_65816); case ADDR_SIZE_LONG: - /* Not supported by any CPU */ - return 0; + /* "none" supports all sizes */ + return (CPU == CPU_NONE); default: FAIL ("Invalid address size"); From 9bd92178b6b122727ad23179b8edb59759e9f999 Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Thu, 3 Oct 2019 18:47:10 +0200 Subject: [PATCH 1161/2161] Fix Gamate RVS --- libsrc/gamate/conio.s | 1 + 1 file changed, 1 insertion(+) diff --git a/libsrc/gamate/conio.s b/libsrc/gamate/conio.s index 18d5da674..6ac439490 100644 --- a/libsrc/gamate/conio.s +++ b/libsrc/gamate/conio.s @@ -13,6 +13,7 @@ initconio: lda #0 sta LCD_XPOS sta LCD_YPOS + sta RVS lda #LCD_MODE_INC_Y sta LCD_MODE From 96547d1dd46694ff940fa36e9fc4ac02472fb26b Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 9 Oct 2019 10:03:38 +0200 Subject: [PATCH 1162/2161] Fix colors for #948 --- include/creativision.h | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/include/creativision.h b/include/creativision.h index a97109029..40b9ee03a 100644 --- a/include/creativision.h +++ b/include/creativision.h @@ -52,22 +52,22 @@ #define DYN_DRV 0 /* Colours - from TMS9918 */ -#define C_TRANSPARENT 0 -#define C_BLACK 1 -#define C_MED_GREEN 2 -#define C_LIGHT_GREEN 3 -#define C_DARK_BLUE 4 -#define C_LIGHT_BLUE 5 -#define C_DARK_RED 6 -#define C_CYAN 7 -#define C_MED_RED 8 -#define C_LIGHT_RED 9 -#define C_DARK_YELLOW 10 -#define C_LIGHT_YELLOW 11 -#define C_DARK_GREEN 12 -#define C_MAGENTA 13 -#define C_GREY 14 -#define C_WHITE 15 +#define COLOR_TRANSPARENT 0 +#define COLOR_BLACK 1 +#define COLOR_MED_GREEN 2 +#define COLOR_LIGHT_GREEN 3 +#define COLOR_DARK_BLUE 4 +#define COLOR_LIGHT_BLUE 5 +#define COLOR_DARK_RED 6 +#define COLOR_CYAN 7 +#define COLOR_MED_RED 8 +#define COLOR_LIGHT_RED 9 +#define COLOR_DARK_YELLOW 10 +#define COLOR_LIGHT_YELLOW 11 +#define COLOR_DARK_GREEN 12 +#define COLOR_MAGENTA 13 +#define COLOR_GREY 14 +#define COLOR_WHITE 15 /* Protos */ void __fastcall__ psg_outb(unsigned char b); From 74a904be54d357d6010cb24d9d1d69d488a558b1 Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Thu, 3 Oct 2019 22:46:34 +0200 Subject: [PATCH 1163/2161] Hello world example for the Supervision --- samples/supervisionhello.c | 72 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100755 samples/supervisionhello.c diff --git a/samples/supervisionhello.c b/samples/supervisionhello.c new file mode 100755 index 000000000..9b09a7730 --- /dev/null +++ b/samples/supervisionhello.c @@ -0,0 +1,72 @@ +#include <supervision.h> +#include <peekpoke.h> + +#define SV_OFFSET 0x0A +#define SV_INIT_POSITION (SV_VIDEO+0x0A*48+0x0A) + +unsigned char h_char[] = {0x66,0x66,0x66,0x7e,0x66,0x66,0x66,0x00}; +unsigned char e_char[] = {0x7e,0x60,0x60,0x78,0x60,0x60,0x7e,0x00}; +unsigned char l_char[] = {0x60,0x60,0x60,0x60,0x60,0x60,0x7e,0x00}; +unsigned char o_char[] = {0x3c,0x66,0x66,0x66,0x66,0x66,0x3c,0x00}; +unsigned char w_char[] = {0x63,0x63,0x63,0x6b,0x7f,0x77,0x63,0x00}; +unsigned char r_char[] = {0x7c,0x66,0x66,0x7c,0x78,0x6c,0x66,0x00}; +unsigned char d_char[] = {0x78,0x6c,0x66,0x66,0x66,0x6c,0x78,0x00}; + + +void clear_screen(void) +{ + unsigned short i; + + for(i=0;i<0x2000;++i) + { + POKE(SV_VIDEO+i,0); + } +} + +unsigned char bit_reverse_lookup[16] = +{ + 0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE, + 0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF +}; + +unsigned char bit_reverse(unsigned char n) +{ + return (bit_reverse_lookup[n&0b1111] << 4) | bit_reverse_lookup[n>>4]; +} + +void init_screen(void) +{ + SV_LCD.height = 0xA0; + SV_LCD.width = 0xA0; + SV_BANK = 0xC9; +} + +int main() +{ + unsigned char i; + + init_screen(); + + clear_screen(); + + for(i=0;i<8;++i) + { + POKE(SV_INIT_POSITION+1 +i*48,bit_reverse(h_char[i])); + POKE(SV_INIT_POSITION+2 +i*48,bit_reverse(e_char[i])); + POKE(SV_INIT_POSITION+3 +i*48,bit_reverse(l_char[i])); + POKE(SV_INIT_POSITION+4 +i*48,bit_reverse(l_char[i])); + POKE(SV_INIT_POSITION+5 +i*48,bit_reverse(o_char[i])); + + POKE(SV_INIT_POSITION+7 +i*48,bit_reverse(w_char[i])); + POKE(SV_INIT_POSITION+8 +i*48,bit_reverse(o_char[i])); + POKE(SV_INIT_POSITION+9 +i*48,bit_reverse(r_char[i])); + POKE(SV_INIT_POSITION+10+i*48,bit_reverse(l_char[i])); + POKE(SV_INIT_POSITION+11+i*48,bit_reverse(d_char[i])); + } + + while(1) {}; + + return 0; +} + + From cdb8035cf0228a2194c7bfe9216e4897777b60a9 Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Thu, 3 Oct 2019 23:32:16 +0200 Subject: [PATCH 1164/2161] Move screen init into crt0.s --- cfg/supervision.cfg | 2 +- libsrc/supervision/crt0.s | 5 ++++- samples/supervisionhello.c | 9 --------- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/cfg/supervision.cfg b/cfg/supervision.cfg index d9f189f2b..6a71f4682 100644 --- a/cfg/supervision.cfg +++ b/cfg/supervision.cfg @@ -19,7 +19,7 @@ SEGMENTS { CODE: load = ROM, type = ro, define = yes; RODATA: load = ROM, type = ro, define = yes; DATA: load = ROM, run = RAM, type = rw, define = yes; - FFF0: load = ROM, type = ro, offset = $7FF0; + FFF0: load = ROM, type = ro, offset = $7FEA; VECTOR: load = ROM, type = ro, offset = $7FFA; BSS: load = RAM, type = bss, define = yes; } diff --git a/libsrc/supervision/crt0.s b/libsrc/supervision/crt0.s index 6c1287868..ab147efb4 100644 --- a/libsrc/supervision/crt0.s +++ b/libsrc/supervision/crt0.s @@ -67,7 +67,10 @@ not_dma: ; Removing this segment gives only a warning. .segment "FFF0" .proc reset32kcode - lda #(6<<5) + lda #$A0 + sta lcd_width + sta lcd_height + lda #$C9 sta sv_bank ; Now, the 32Kbyte image can reside in the top of 64Kbyte and 128Kbyte ROMs. jmp reset diff --git a/samples/supervisionhello.c b/samples/supervisionhello.c index 9b09a7730..5996d219f 100755 --- a/samples/supervisionhello.c +++ b/samples/supervisionhello.c @@ -34,19 +34,10 @@ unsigned char bit_reverse(unsigned char n) return (bit_reverse_lookup[n&0b1111] << 4) | bit_reverse_lookup[n>>4]; } -void init_screen(void) -{ - SV_LCD.height = 0xA0; - SV_LCD.width = 0xA0; - SV_BANK = 0xC9; -} - int main() { unsigned char i; - init_screen(); - clear_screen(); for(i=0;i<8;++i) From 915836b3ec888445eb290f61456a4e23f947bc6a Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Sun, 6 Oct 2019 13:00:37 +0200 Subject: [PATCH 1165/2161] Improve init code readability --- cfg/supervision.cfg | 2 +- libsrc/supervision/crt0.s | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cfg/supervision.cfg b/cfg/supervision.cfg index 6a71f4682..95f049761 100644 --- a/cfg/supervision.cfg +++ b/cfg/supervision.cfg @@ -19,7 +19,7 @@ SEGMENTS { CODE: load = ROM, type = ro, define = yes; RODATA: load = ROM, type = ro, define = yes; DATA: load = ROM, run = RAM, type = rw, define = yes; - FFF0: load = ROM, type = ro, offset = $7FEA; + FFEA: load = ROM, type = ro, offset = $7FEA; VECTOR: load = ROM, type = ro, offset = $7FFA; BSS: load = RAM, type = bss, define = yes; } diff --git a/libsrc/supervision/crt0.s b/libsrc/supervision/crt0.s index ab147efb4..a474cfbeb 100644 --- a/libsrc/supervision/crt0.s +++ b/libsrc/supervision/crt0.s @@ -65,12 +65,12 @@ not_dma: .endproc ; Removing this segment gives only a warning. - .segment "FFF0" + .segment "FFEA" .proc reset32kcode lda #$A0 sta lcd_width sta lcd_height - lda #$C9 + lda #(6<<5) | SV_LCD_ON | SV_NMI_ENABLE_ON sta sv_bank ; Now, the 32Kbyte image can reside in the top of 64Kbyte and 128Kbyte ROMs. jmp reset From eb83a3fd0f1f55910353bb6cb329b1a7f7d5137c Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Sun, 6 Oct 2019 13:41:02 +0200 Subject: [PATCH 1166/2161] Improve helloworld example for Supervision --- samples/supervisionhello.c | 73 +++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/samples/supervisionhello.c b/samples/supervisionhello.c index 5996d219f..c1832179a 100755 --- a/samples/supervisionhello.c +++ b/samples/supervisionhello.c @@ -1,17 +1,15 @@ #include <supervision.h> #include <peekpoke.h> -#define SV_OFFSET 0x0A -#define SV_INIT_POSITION (SV_VIDEO+0x0A*48+0x0A) - -unsigned char h_char[] = {0x66,0x66,0x66,0x7e,0x66,0x66,0x66,0x00}; -unsigned char e_char[] = {0x7e,0x60,0x60,0x78,0x60,0x60,0x7e,0x00}; -unsigned char l_char[] = {0x60,0x60,0x60,0x60,0x60,0x60,0x7e,0x00}; -unsigned char o_char[] = {0x3c,0x66,0x66,0x66,0x66,0x66,0x3c,0x00}; -unsigned char w_char[] = {0x63,0x63,0x63,0x6b,0x7f,0x77,0x63,0x00}; -unsigned char r_char[] = {0x7c,0x66,0x66,0x7c,0x78,0x6c,0x66,0x00}; -unsigned char d_char[] = {0x78,0x6c,0x66,0x66,0x66,0x6c,0x78,0x00}; +#define BYTES_PER_LINE 48 +const unsigned char h_char[] = {0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}; +const unsigned char e_char[] = {0x7E,0x60,0x60,0x78,0x60,0x60,0x7E,0x00}; +const unsigned char l_char[] = {0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00}; +const unsigned char o_char[] = {0x3C,0x66,0x66,0x66,0x66,0x66,0x3C,0x00}; +const unsigned char w_char[] = {0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00}; +const unsigned char r_char[] = {0x7C,0x66,0x66,0x7C,0x78,0x6C,0x66,0x00}; +const unsigned char d_char[] = {0x78,0x6C,0x66,0x66,0x66,0x6C,0x78,0x00}; void clear_screen(void) { @@ -23,37 +21,48 @@ void clear_screen(void) } } -unsigned char bit_reverse_lookup[16] = +unsigned char reversed_map_one_to_two_lookup[16] = { - 0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE, - 0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF + 0x00, 0xC0, 0x30, 0xF0, 0x0C, 0xCC, 0x3C, 0xFC, + 0x03, 0xC3, 0x33, 0xF3, 0x0F, 0xCF, 0x3F, 0xFF }; -unsigned char bit_reverse(unsigned char n) +unsigned char left_map_one_to_two(unsigned char n) { - return (bit_reverse_lookup[n&0b1111] << 4) | bit_reverse_lookup[n>>4]; + return reversed_map_one_to_two_lookup[n >> 4]; +} + +unsigned char right_map_one_to_two(unsigned char n) +{ + return reversed_map_one_to_two_lookup[n&0x0F]; +} + +void display_char(const unsigned char x, const unsigned char y, const unsigned char *ch) +{ + unsigned char k; + + for(k=0;k<8;++k) + { \ + SV_VIDEO[2*(y)+BYTES_PER_LINE*k+BYTES_PER_LINE*(x<<3)] = left_map_one_to_two(ch[k]); + SV_VIDEO[2*(y)+BYTES_PER_LINE*k+BYTES_PER_LINE*(x<<3)+1] = right_map_one_to_two(ch[k]); + } } int main() -{ - unsigned char i; - +{ clear_screen(); - for(i=0;i<8;++i) - { - POKE(SV_INIT_POSITION+1 +i*48,bit_reverse(h_char[i])); - POKE(SV_INIT_POSITION+2 +i*48,bit_reverse(e_char[i])); - POKE(SV_INIT_POSITION+3 +i*48,bit_reverse(l_char[i])); - POKE(SV_INIT_POSITION+4 +i*48,bit_reverse(l_char[i])); - POKE(SV_INIT_POSITION+5 +i*48,bit_reverse(o_char[i])); - - POKE(SV_INIT_POSITION+7 +i*48,bit_reverse(w_char[i])); - POKE(SV_INIT_POSITION+8 +i*48,bit_reverse(o_char[i])); - POKE(SV_INIT_POSITION+9 +i*48,bit_reverse(r_char[i])); - POKE(SV_INIT_POSITION+10+i*48,bit_reverse(l_char[i])); - POKE(SV_INIT_POSITION+11+i*48,bit_reverse(d_char[i])); - } + display_char(3,2, h_char); + display_char(3,3, e_char); + display_char(3,4, l_char); + display_char(3,5, l_char); + display_char(3,6, o_char); + + display_char(3,8, w_char); + display_char(3,9, o_char); + display_char(3,10,r_char); + display_char(3,11,l_char); + display_char(3,12,d_char); while(1) {}; From b051c913e9ae0b6d87c92e438d091e0c61da98f6 Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Sun, 6 Oct 2019 15:19:45 +0200 Subject: [PATCH 1167/2161] Add supervisionhello in samples/Makefile --- samples/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/samples/Makefile b/samples/Makefile index ad81c2474..69efbe43b 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -198,6 +198,9 @@ EXELIST_atarixl = $(EXELIST_atari) EXELIST_atari2600 = \ atari2600hello + +EXELIST_supervision = \ + supervisionhello # Unlisted targets will try to build everything. # That lets us learn what they cannot build, and what settings From 40cf719068f69da617bc448b031160d47a914c2a Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Sun, 6 Oct 2019 20:30:30 +0200 Subject: [PATCH 1168/2161] Use decimal for lcd size initialization --- libsrc/supervision/crt0.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/supervision/crt0.s b/libsrc/supervision/crt0.s index a474cfbeb..f1c655387 100644 --- a/libsrc/supervision/crt0.s +++ b/libsrc/supervision/crt0.s @@ -67,7 +67,7 @@ not_dma: ; Removing this segment gives only a warning. .segment "FFEA" .proc reset32kcode - lda #$A0 + lda #160 sta lcd_width sta lcd_height lda #(6<<5) | SV_LCD_ON | SV_NMI_ENABLE_ON From 1b1d29ca9e8de2f323ac7e2492741034f0227872 Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Mon, 7 Oct 2019 11:36:57 +0200 Subject: [PATCH 1169/2161] Comments --- samples/supervisionhello.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/samples/supervisionhello.c b/samples/supervisionhello.c index c1832179a..3d2c26027 100755 --- a/samples/supervisionhello.c +++ b/samples/supervisionhello.c @@ -1,8 +1,18 @@ +/*****************************************************************************/ +/* */ +/* Watara Supervision sample C program */ +/* */ +/* Fabrizio Caruso (fabrizio_caruso@hotmail.com), 2019 */ +/* */ +/*****************************************************************************/ + #include <supervision.h> #include <peekpoke.h> +// Last 8 bytes are not displayed #define BYTES_PER_LINE 48 +// Characters definitions in 8x8 format const unsigned char h_char[] = {0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}; const unsigned char e_char[] = {0x7E,0x60,0x60,0x78,0x60,0x60,0x7E,0x00}; const unsigned char l_char[] = {0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00}; @@ -21,6 +31,7 @@ void clear_screen(void) } } +// Necessary conversion to have 2 bits per pixel with darkest hue unsigned char reversed_map_one_to_two_lookup[16] = { 0x00, 0xC0, 0x30, 0xF0, 0x0C, 0xCC, 0x3C, 0xFC, From 7706ea2f133287fb0d107d6c7a9f1e99e3b0e4df Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Mon, 7 Oct 2019 11:41:29 +0200 Subject: [PATCH 1170/2161] Improve comments --- samples/supervisionhello.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/samples/supervisionhello.c b/samples/supervisionhello.c index 3d2c26027..7cc866e57 100755 --- a/samples/supervisionhello.c +++ b/samples/supervisionhello.c @@ -9,10 +9,10 @@ #include <supervision.h> #include <peekpoke.h> -// Last 8 bytes are not displayed +// Number of bytes per screen line (Remark: Last 8 bytes are not displayed) #define BYTES_PER_LINE 48 -// Characters definitions in 8x8 format +// Character definitions in 8x8 format const unsigned char h_char[] = {0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}; const unsigned char e_char[] = {0x7E,0x60,0x60,0x78,0x60,0x60,0x7E,0x00}; const unsigned char l_char[] = {0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00}; @@ -32,6 +32,7 @@ void clear_screen(void) } // Necessary conversion to have 2 bits per pixel with darkest hue +// Remark: The Supervision uses 2 bits per pixel and bits are mapped into pixel in reversed order unsigned char reversed_map_one_to_two_lookup[16] = { 0x00, 0xC0, 0x30, 0xF0, 0x0C, 0xCC, 0x3C, 0xFC, From fb260ef17f28305321a9932b710bd8f30f243dfc Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Wed, 9 Oct 2019 09:23:57 +0200 Subject: [PATCH 1171/2161] Init is no longer in crt0.s --- cfg/supervision.cfg | 2 +- libsrc/supervision/crt0.s | 5 +---- samples/supervisionhello.c | 9 ++++++++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/cfg/supervision.cfg b/cfg/supervision.cfg index 95f049761..d9f189f2b 100644 --- a/cfg/supervision.cfg +++ b/cfg/supervision.cfg @@ -19,7 +19,7 @@ SEGMENTS { CODE: load = ROM, type = ro, define = yes; RODATA: load = ROM, type = ro, define = yes; DATA: load = ROM, run = RAM, type = rw, define = yes; - FFEA: load = ROM, type = ro, offset = $7FEA; + FFF0: load = ROM, type = ro, offset = $7FF0; VECTOR: load = ROM, type = ro, offset = $7FFA; BSS: load = RAM, type = bss, define = yes; } diff --git a/libsrc/supervision/crt0.s b/libsrc/supervision/crt0.s index f1c655387..ac61c8215 100644 --- a/libsrc/supervision/crt0.s +++ b/libsrc/supervision/crt0.s @@ -65,11 +65,8 @@ not_dma: .endproc ; Removing this segment gives only a warning. - .segment "FFEA" + .segment "FFF0" .proc reset32kcode - lda #160 - sta lcd_width - sta lcd_height lda #(6<<5) | SV_LCD_ON | SV_NMI_ENABLE_ON sta sv_bank ; Now, the 32Kbyte image can reside in the top of 64Kbyte and 128Kbyte ROMs. diff --git a/samples/supervisionhello.c b/samples/supervisionhello.c index 7cc866e57..db2b5f66c 100755 --- a/samples/supervisionhello.c +++ b/samples/supervisionhello.c @@ -60,8 +60,15 @@ void display_char(const unsigned char x, const unsigned char y, const unsigned c } } +void init_lcd(void) +{ + SV_LCD.width = 160; + SV_LCD.height = 160; +} + int main() -{ +{ + init_lcd(); clear_screen(); display_char(3,2, h_char); From 3994fee595605c5981d023c29b5d9d8e170d9adc Mon Sep 17 00:00:00 2001 From: LRFLEW <LRFLEW@aol.com> Date: Mon, 7 Oct 2019 22:37:34 -0500 Subject: [PATCH 1172/2161] Significantly faster rand() implementation --- libsrc/common/rand.s | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/libsrc/common/rand.s b/libsrc/common/rand.s index 102dd5be2..fc23b6ee4 100644 --- a/libsrc/common/rand.s +++ b/libsrc/common/rand.s @@ -35,27 +35,17 @@ rand: .dword 1 .code _rand: clc - lda rand+0 ; SEED *= $01010101 - adc rand+1 + lda rand+0 ; SEED += $B3 + adc #$B3 + sta rand+0 + adc rand+1 ; SEED *= $01010101 sta rand+1 adc rand+2 sta rand+2 - adc rand+3 - sta rand+3 - clc - lda rand+0 ; SEED += $31415927 - adc #$27 - sta rand+0 - lda rand+1 - adc #$59 - sta rand+1 - lda rand+2 - adc #$41 - sta rand+2 and #$7f ; Suppress sign bit (make it positive) tax - lda rand+3 - adc #$31 + lda rand+2 + adc rand+3 sta rand+3 rts ; return bit (16-22,24-31) in (X,A) From 216105f6df0f24ee656de3cf3abca4591ed3723d Mon Sep 17 00:00:00 2001 From: LRFLEW <LRFLEW@aol.com> Date: Wed, 9 Oct 2019 01:42:50 -0500 Subject: [PATCH 1173/2161] Update comments in rand.s --- libsrc/common/rand.s | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/libsrc/common/rand.s b/libsrc/common/rand.s index fc23b6ee4..a272af80a 100644 --- a/libsrc/common/rand.s +++ b/libsrc/common/rand.s @@ -3,6 +3,7 @@ ; ; Written and donated by Sidney Cadot - sidney@ch.twi.tudelft.nl ; 2016-11-07, modified by Brad Smith +; 2019-10-07, modified by Lewis "LRFLEW" Fox ; ; May be distributed with the cc65 runtime using the same license. ; @@ -22,6 +23,17 @@ ; The best 8 bits, 24-31 are returned in the ; low byte A to provide the best entropy in the ; most commonly used part of the return value. +; +; Uses the following LCG values for ax + c (mod m) +; a = $01010101 +; c = $B3B3B3B3 +; m = $100000000 (32-bit truncation) +; +; The multiplier was carefully chosen such that it can +; be computed with 3 adc instructions, and the increment +; was chosen to have the same value in each byte to allow +; the addition to be performed in conjunction with the +; multiplication, adding only 1 additional adc instruction. ; .export _rand, _srand @@ -35,10 +47,10 @@ rand: .dword 1 .code _rand: clc - lda rand+0 ; SEED += $B3 + lda rand+0 adc #$B3 sta rand+0 - adc rand+1 ; SEED *= $01010101 + adc rand+1 sta rand+1 adc rand+2 sta rand+2 From 39b10f9599b15a5256db22fe386472fa6ec0e12f Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 11 Oct 2019 10:48:56 -0400 Subject: [PATCH 1174/2161] Added new program descriptions to the list. --- samples/README | 80 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/samples/README b/samples/README index 88a6021c8..7ace7da3f 100644 --- a/samples/README +++ b/samples/README @@ -1,19 +1,20 @@ This directory contains sample programs for the cc65 compiler. -Below is a short description for each of the programs together with a list of -the supported platforms. +Below is a short description for each of the programs, together with a list +of the supported platforms. Please note: - * The supplied makefile needs GNU make. It works out of the box on Linux - and similar systems. If you're using Windows, consider installing Cygwin. + * The supplied makefile needs GNU make. It works out of the box on Linux and + similar systems. If you're using Windows, then consider installing Cygwin + or MSys2. - * The makefile specifies the C64 as the default target system, because all - but one of the programs run on this platform. When compiling for another + * The makefile specifies the C64 as the default target system because all + but three of the programs run on that platform. When compiling for another system, you will have to change the line that specifies the target system at the top of the makefile, specify the system with SYS=<target> on the - make command line or set a SYS env var. + make command line, or set a SYS environment variable. List of supplied sample programs: @@ -22,87 +23,95 @@ List of supplied sample programs: Name: ascii Description: Shows the ASCII (or ATASCII, PETSCII) codes of typed characters. Written and contributed by Greg King - <gngking@erols.com>. + <greg.king5@verizon.com>. Platforms: All platforms with conio or stdio (compile time configurable). +----------------------------------------------------------------------------- +Name: atari2600hello +Description: A "Hello world" type program. +Platforms: Runs on only the Atari 2600 Video Console System. + ----------------------------------------------------------------------------- Name: diodemo Description: A disc copy program written and contributed by Oliver Schmidt, <ol.sc@web.de>. Supports single or dual disc copy. Platforms: The program does depend on conio and dio (direct disk i/o), - so it does currently compile for the Atari and Apple ][ + so it currently does compile for only the Atari and Apple ][ machines. ----------------------------------------------------------------------------- Name: enumdevdir -Description: Enumerates all devices, directories and files. Written and +Description: Enumerates all devices, directories, and files. Written and contributed by Oliver Schmidt, <ol.sc@web.de>. Platforms: All systems with device enumeration and directory access - (currently the C64, the C128 and the Apple ][). + (currently the Commodore machines, the Commander X16, + and the Apple ][). ----------------------------------------------------------------------------- Name: fire Description: Another graphics demo written by groepaz/hitmen. -Platforms: The program is currently only running on the C64, but should +Platforms: The program currently is running on only the C64, but should be portable to the C128 and CBM510 (and maybe more machines). ----------------------------------------------------------------------------- Name: gunzip65 -Description: A gunzip utility for 6502 based machines written by Piotr +Description: A gunzip utility for 6502-based machines, written by Piotr Fusik <fox@scene.pl>. Platforms: Runs on all platforms with file I/O (currently the Atari, the - Apple ][ and most Commodore machines). + Apple ][, Commodore machines, and the Commander X16). ----------------------------------------------------------------------------- Name: hello Description: A nice "Hello world" type program that uses the conio console I/O library for output. Platforms: Runs on all platforms that support conio, which means: - Apple ][, Atari, C16, C64, C128, CBM510, CBM610, PET, Plus/4 + Apple ][, Atari, Commodore machines, Commander X16, + Creativision, Gamate, NES. ----------------------------------------------------------------------------- Name: mandelbrot Description: A mandelbrot demo using integer arithmetic. The demo was - written by groepaz/hitmen and converted to cc65 using TGI + written by groepaz/hitmen, and converted to cc65 using TGI graphics by Stephan Haubenthal. Platforms: Runs on all platforms that have TGI support: - Apple ][, C64, C128, Oric Atmos, Geos and Lynx. + Apple ][, Atari, C64, C128, Oric Atmos and Telestrat, GEOS, + NES, and Lynx. ----------------------------------------------------------------------------- Name: mousedemo Description: Shows how to use the mouse. Platforms: All systems with mouse and conio support: - C64, C128, CBM510, Atari, Apple ][ + C64, C128, CBM510, Atari, Apple ][. ----------------------------------------------------------------------------- Name: multidemo Description: Shows how to combine multiple cc65 features incl. overlays and extended memory drivers. Written and contributed by Oliver Schmidt, <ol.sc@web.de>. -Platforms: All systems with an overlay linker config, disk directory - access and EMD support (currently the C64, the C128, - the Atari and the Apple ][). +Platforms: All systems with an overlay linker config., disk directory + access, and EMD support (currently the C64, the C128, + the Atari, and the Apple ][). ----------------------------------------------------------------------------- Name: nachtm -Description: Plays "Eine kleine Nachtmusik" by Wolfgang Amadeus Mozart +Description: Plays "Eine kleine Nachtmusik" by Wolfgang Amadeus Mozart. Platforms: All systems that have the Commodore SID (Sound Interface Device): - C64, C128, CBM510, CBM610 + C64, C128, CBM510, CBM610. ----------------------------------------------------------------------------- Name: overlaydemo Description: Shows how to load overlay files from disk. Written and contributed by Oliver Schmidt, <ol.sc@web.de>. -Platforms: All systems with an overlay linker config (currently the C64, - the C128, the Atari and the Apple ][). +Platforms: All systems with an overlay linker config. (currently the C64, + the C128, the Atari, and the Apple ][). ----------------------------------------------------------------------------- Name: plasma Description: A fancy graphics demo written by groepaz/hitmen. -Platforms: The program needs a VIC, or a TED, so it runs on the following +Platforms: The program needs a VIC-II or a TED, so it runs on the following systems: - C64, C128, CBM510, Plus/4 + C64, C128, CBM510, Plus/4. ----------------------------------------------------------------------------- Name: sieve @@ -110,12 +119,19 @@ Description: Implements the "Sieve of Eratosthenes" as a way to find all prime numbers in a specific number interval. Often used as a benchmark program. Platforms: All systems with conio and clock support: - Atari, C16, C64, C128, CBM510, CBM610, PET, Plus/4, - Apple ][ (without timing due to missing clock support) + Atari, Commodore machines (VIC-20 needs memory expansion), + Commander X16, Apple ][ (without timing due to missing clock + support). + +----------------------------------------------------------------------------- +Name: supervisionhello +Description: A "Hello world" type program. +Platforms: Runs on only the Watara Supervision game console. ----------------------------------------------------------------------------- Name: tgidemo -Description: Shows some of the graphics capabilities of the "tiny graphics - interface". +Description: Shows some of the graphics capabilities of the "Tiny Graphics + Interface". Platforms: Runs on all platforms that have TGI support: - Apple ][, C64, C128, Oric Atmos, Geos and Lynx. + Apple ][, Atari, C64, C128, Oric Atmos and Telestrat, GEOS, + NES, and Lynx. From f3f15cfd25dc5379ca48021884f4b96471dd895e Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 12 Oct 2019 04:01:03 -0400 Subject: [PATCH 1175/2161] Fixed problems with the Atari Lynx's TGI driver. * The sprite-types for black and transparent backgrounds were swapped. * A filler-byte for text output isn't printed. (A hardware bug might not need that work-around in most cases.) --- libsrc/lynx/tgi/lynx-160-102-16.s | 52 +++++++++++++++++-------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/libsrc/lynx/tgi/lynx-160-102-16.s b/libsrc/lynx/tgi/lynx-160-102-16.s index 04bdaae04..0728e6870 100644 --- a/libsrc/lynx/tgi/lynx-160-102-16.s +++ b/libsrc/lynx/tgi/lynx-160-102-16.s @@ -1,10 +1,10 @@ ; ; Graphics driver for the 160x102x16 mode on the Lynx. ; -; All the drawing functions are simply done by sprites as the sprite +; All the drawing functions simply are done by sprites, as the sprite ; engine is the only way to do fast graphics on a Lynx. ; -; This code is written by Karri Kaksonen, 2004 for the cc65 compiler. +; This code was written by Karri Kaksonen, 2004 for the cc65 compiler. ; .include "zeropage.inc" @@ -104,8 +104,10 @@ BGINDEX: .res 1 ; Pen to use for text background DRAWPAGE: .res 1 SWAPREQUEST: .res 1 +; 8 rows with (one offset-byte plus 20 character bytes plus one fill-byte) plus one 0-offset-byte. +; (As an experiment, the fill-byte isn't being generated. +; It might not be needed to work around a Suzy bug.) text_bitmap: .res 8*(1+20+1)+1 -; 8 rows with (one offset-byte plus 20 character bytes plus one fill-byte) plus one 0-offset-byte ; Constants and tables @@ -830,7 +832,7 @@ TEXTSTYLE: ; ------------------------------------------------------------------------ ; 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 +; current text style. The text to output is given as a zero-terminated ; string with address in ptr3. ; ; Must set an error code: NO @@ -842,12 +844,11 @@ OUTTEXT: lda TEXTMAGY sta text_sy+1 - stz text_sprite ; Set normal sprite lda BGINDEX - bne @L1 - lda #4 - sta text_sprite ; Set opaque sprite + beq @L1 ; Choose opaque black sprite? + lda #$04 ; No, choose normal sprite @L1: + sta text_sprite lda DRAWINDEX ; Set color asl asl @@ -875,15 +876,18 @@ OUTTEXT: ldy #20 @L3: sty STRLEN + tya bne @L4 - rts ; Zero length string + rts ; Zero-length string @L4: iny ; Prepare text_bitmap - iny + +; The next instruction is commented because the code won't include a fill-byte. +; iny sty STROFF ldy #8-1 ; 8 pixel lines per character - ldx #0 + ldx #$00 clc @L5: lda STROFF @@ -891,45 +895,45 @@ OUTTEXT: txa adc STROFF tax - lda #$ff - sta text_bitmap-1,x + +; This was the fill-byte. +; lda #$FF +; sta text_bitmap-1,x dey bpl @L5 stz text_bitmap,x stz tmp2 - iny + iny ;(ldy #$00) @L6: lda (STRPTR),y sty tmp1 - sec ; (ch-' ') * 8 - sbc #32 - stz FONTOFF + sub #' ' ; (ch - ' ') * 8 stz FONTOFF+1 asl asl rol FONTOFF+1 asl rol FONTOFF+1 - clc ; Choose font - adc #<font + ;clc ; (cleared by rol) + adc #<font ; Choose font sta FONTOFF lda FONTOFF+1 adc #>font sta FONTOFF+1 -; and now copy the 8 bytes of that char +; And now, copy the 8 bytes of that glyph. ldx tmp2 inx stx tmp2 -; draw char from top to bottom, reading char-data from offset 8-1 to offset 0 +; Draw char. from top to bottom, reading char-data from offset 8-1 to offset 0. ldy #8-1 @L7: - lda (FONTOFF),y ; *chptr - sta text_bitmap,x ;textbuf[y*(1+len+1)+1+x] + lda (FONTOFF),y ; *chptr + sta text_bitmap,x ; textbuf[y*(1+len+1)+1+x] txa adc STROFF @@ -938,7 +942,7 @@ OUTTEXT: dey bpl @L7 - ; goto next char + ; Goto next char. ldy tmp1 iny dec STRLEN From e660a4934791d046a2034257619148a72841a2ab Mon Sep 17 00:00:00 2001 From: LRFLEW <LRFLEW@aol.com> Date: Mon, 7 Oct 2019 13:36:54 -0500 Subject: [PATCH 1176/2161] [cx16] Update ROM banks to new mapping --- libsrc/cx16/crt0.s | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libsrc/cx16/crt0.s b/libsrc/cx16/crt0.s index a3a613bd1..873fd706f 100644 --- a/libsrc/cx16/crt0.s +++ b/libsrc/cx16/crt0.s @@ -62,6 +62,7 @@ L2: lda zpsave,x stx VIA1::PRA2 ; Restore former RAM bank lda VIA1::PRB and #<~$07 + ora #$04 sta VIA1::PRB ; Change back to BASIC ROM ; Back to BASIC. @@ -77,7 +78,7 @@ init: ; Change from BASIC's ROM to Kernal's ROM. lda VIA1::PRB - ora #$07 + and #<~$07 sta VIA1::PRB ; Change to the first RAM bank. From 4f24a06f0e06ea420ef6ec995ed86260aba8749a Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 12 Oct 2019 07:59:49 -0400 Subject: [PATCH 1177/2161] Fixed error handling for missing names in ld65 configure files. --- src/ld65/scanner.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ld65/scanner.c b/src/ld65/scanner.c index 31f1c7a41..d6278abbd 100644 --- a/src/ld65/scanner.c +++ b/src/ld65/scanner.c @@ -490,7 +490,6 @@ void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name) /* We need an identifier */ if (CfgTok == CFGTOK_IDENT) { - /* Make it upper case */ SB_ToUpper (&CfgSVal); @@ -502,10 +501,13 @@ void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name) } } + /* Not found */ + CfgError (&CfgErrorPos, "%s expected, got '%s'", Name, SB_GetConstBuf(&CfgSVal)); + return; } - /* Not found or no identifier */ - CfgError (&CfgErrorPos, "%s expected, got '%s'", Name, SB_GetConstBuf(&CfgSVal)); + /* No identifier */ + CfgError (&CfgErrorPos, "%s expected", Name); } From 5eda1c256cdda5fda1c8ee17a1036a84782a00b3 Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Sun, 13 Oct 2019 10:27:09 +0200 Subject: [PATCH 1178/2161] Fix char 35 38 42 47 52 --- libsrc/lynx/tgi/lynx-160-102-16.s | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libsrc/lynx/tgi/lynx-160-102-16.s b/libsrc/lynx/tgi/lynx-160-102-16.s index 0728e6870..cc85060c9 100644 --- a/libsrc/lynx/tgi/lynx-160-102-16.s +++ b/libsrc/lynx/tgi/lynx-160-102-16.s @@ -979,24 +979,24 @@ font: .byte $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF ;32 .byte $FF, $E7, $FF, $FF, $E7, $E7, $E7, $E7 ;33 .byte $FF, $FF, $FF, $FF, $FF, $99, $99, $99 ;34 - .byte $FF, $99, $99, $00, $99, $00, $99, $99 ;35 + .byte $FF, $D7, $D7, $01, $D7, $01, $D7, $D7 ;35 .byte $FF, $E7, $83, $F9, $C3, $9F, $C1, $E7 ;36 .byte $FF, $B9, $99, $CF, $E7, $F3, $99, $9D ;37 - .byte $FF, $C0, $99, $98, $C7, $C3, $99, $C3 ;38 + .byte $81, $B3, $31, $8F, $87, $33, $87, $FF ;38 .byte $FF, $FF, $FF, $FF, $FF, $E7, $F3, $F9 ;39 .byte $FF, $F3, $E7, $CF, $CF, $CF, $E7, $F3 ;40 .byte $FF, $CF, $E7, $F3, $F3, $F3, $E7, $CF ;41 - .byte $FF, $FF, $99, $C3, $00, $C3, $99, $FF ;42 + .byte $FF, $99, $C3, $81, $C3, $99, $FF, $FF ;42 .byte $FF, $FF, $E7, $E7, $81, $E7, $E7, $FF ;43 .byte $CF, $E7, $E7, $FF, $FF, $FF, $FF, $FF ;44 .byte $FF, $FF, $FF, $FF, $81, $FF, $FF, $FF ;45 .byte $FF, $E7, $E7, $FF, $FF, $FF, $FF, $FF ;46 - .byte $FF, $9F, $CF, $E7, $F3, $F9, $FC, $FF ;47 + .byte $FF, $BF, $9F, $CF, $E7, $F3, $F9, $FD ;47 .byte $FF, $C3, $99, $99, $89, $91, $99, $C3 ;48 .byte $FF, $81, $E7, $E7, $E7, $C7, $E7, $E7 ;49 .byte $FF, $81, $9F, $CF, $F3, $F9, $99, $C3 ;50 .byte $FF, $C3, $99, $F9, $E3, $F9, $99, $C3 ;51 - .byte $FF, $F9, $F9, $80, $99, $E1, $F1, $F9 ;52 + .byte $F3, $F3, $01, $33, $C3, $E3, $FB, $FF ;52 .byte $FF, $C3, $99, $F9, $F9, $83, $9F, $81 ;53 .byte $FF, $C3, $99, $99, $83, $9F, $99, $C3 ;54 .byte $FF, $E7, $E7, $E7, $E7, $F3, $99, $81 ;55 From 0210d76694bad683f5fb6d384f619c0975d5f14d Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Sun, 13 Oct 2019 10:41:44 +0200 Subject: [PATCH 1179/2161] Fix 4 --- libsrc/lynx/tgi/lynx-160-102-16.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/lynx/tgi/lynx-160-102-16.s b/libsrc/lynx/tgi/lynx-160-102-16.s index cc85060c9..f749fc57d 100644 --- a/libsrc/lynx/tgi/lynx-160-102-16.s +++ b/libsrc/lynx/tgi/lynx-160-102-16.s @@ -996,7 +996,7 @@ font: .byte $FF, $81, $E7, $E7, $E7, $C7, $E7, $E7 ;49 .byte $FF, $81, $9F, $CF, $F3, $F9, $99, $C3 ;50 .byte $FF, $C3, $99, $F9, $E3, $F9, $99, $C3 ;51 - .byte $F3, $F3, $01, $33, $C3, $E3, $FB, $FF ;52 + .byte $FF, $F3, $F3, $01, $33, $C3, $E3, $FB ;52 .byte $FF, $C3, $99, $F9, $F9, $83, $9F, $81 ;53 .byte $FF, $C3, $99, $99, $83, $9F, $99, $C3 ;54 .byte $FF, $E7, $E7, $E7, $E7, $F3, $99, $81 ;55 From d04f7935c30b4b7aacb5670a968f51981c0c90df Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Sun, 13 Oct 2019 11:23:09 +0200 Subject: [PATCH 1180/2161] M N fixed --- libsrc/lynx/tgi/lynx-160-102-16.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/lynx/tgi/lynx-160-102-16.s b/libsrc/lynx/tgi/lynx-160-102-16.s index f749fc57d..463a322a7 100644 --- a/libsrc/lynx/tgi/lynx-160-102-16.s +++ b/libsrc/lynx/tgi/lynx-160-102-16.s @@ -1023,7 +1023,7 @@ font: .byte $FF, $C7, $93, $F3, $F3, $F3, $F3, $E1 ;10 .byte $FF, $99, $93, $87, $8F, $87, $93, $99 ;11 .byte $FF, $81, $9F, $9F, $9F, $9F, $9F, $9F ;12 - .byte $FF, $9C, $9C, $9C, $94, $80, $88, $9C ;13 + .byte $FF, $39, $39, $39, $29, $01, $11, $39 ;13 .byte $FF, $99, $99, $91, $81, $81, $89, $99 ;14 .byte $FF, $C3, $99, $99, $99, $99, $99, $C3 ;15 .byte $FF, $9F, $9F, $9F, $83, $99, $99, $83 ;16 @@ -1033,7 +1033,7 @@ font: .byte $FF, $E7, $E7, $E7, $E7, $E7, $E7, $81 ;20 .byte $FF, $C3, $99, $99, $99, $99, $99, $99 ;21 .byte $FF, $E7, $C3, $99, $99, $99, $99, $99 ;22 - .byte $FF, $9C, $88, $80, $94, $9C, $9C, $9C ;23 + .byte $FF, $39, $11, $01, $29, $39, $39, $39 ;23 .byte $FF, $99, $99, $C3, $E7, $C3, $99, $99 ;24 .byte $FF, $E7, $E7, $E7, $C3, $99, $99, $99 ;25 .byte $FF, $81, $9F, $CF, $E7, $F3, $F9, $81 ;26 From b91e2337146cab57a3a481a152c1b3051999696d Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Sun, 13 Oct 2019 11:30:21 +0200 Subject: [PATCH 1181/2161] Fix left arrow (char 77=13+64) --- libsrc/lynx/tgi/lynx-160-102-16.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/lynx/tgi/lynx-160-102-16.s b/libsrc/lynx/tgi/lynx-160-102-16.s index 463a322a7..53597b7d8 100644 --- a/libsrc/lynx/tgi/lynx-160-102-16.s +++ b/libsrc/lynx/tgi/lynx-160-102-16.s @@ -1041,7 +1041,7 @@ font: .byte $FF, $03, $9D, $CF, $83, $CF, $ED, $F3 ;28 .byte $FF, $C3, $F3, $F3, $F3, $F3, $F3, $C3 ;29 .byte $E7, $E7, $E7, $E7, $81, $C3, $E7, $FF ;30 - .byte $FF, $EF, $CF, $80, $80, $CF, $EF, $FF ;31 + .byte $FF, $DF, $9F, $01, $01, $9F, $DF, $FF ;31 ; gemena From bac6f94929497f28d8a15a996e4fb578a6ff80d5 Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Sun, 13 Oct 2019 12:13:46 +0200 Subject: [PATCH 1182/2161] Fix 127 (second left arrow) --- libsrc/lynx/tgi/lynx-160-102-16.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/lynx/tgi/lynx-160-102-16.s b/libsrc/lynx/tgi/lynx-160-102-16.s index 53597b7d8..00b7364c3 100644 --- a/libsrc/lynx/tgi/lynx-160-102-16.s +++ b/libsrc/lynx/tgi/lynx-160-102-16.s @@ -1076,4 +1076,4 @@ font: .byte $FF, $03, $9D, $CF, $83, $CF, $ED, $F3 ;252 .byte $FF, $C3, $F3, $F3, $F3, $F3, $F3, $C3 ;253 .byte $E7, $E7, $E7, $E7, $81, $C3, $E7, $FF ;254 - .byte $FF, $EF, $CF, $80, $80, $CF, $EF, $FF ;255 + .byte $FF, $DF, $9F, $01, $01, $9F, $DF, $FF ;255 From 9a3e521358a31d7764988101e1da674b390ba49a Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Sun, 13 Oct 2019 12:32:54 +0200 Subject: [PATCH 1183/2161] small m and n fixed --- libsrc/lynx/tgi/lynx-160-102-16.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/lynx/tgi/lynx-160-102-16.s b/libsrc/lynx/tgi/lynx-160-102-16.s index 00b7364c3..903d8f25e 100644 --- a/libsrc/lynx/tgi/lynx-160-102-16.s +++ b/libsrc/lynx/tgi/lynx-160-102-16.s @@ -1058,7 +1058,7 @@ font: .byte $C3, $F9, $F9, $F9, $F9, $FF, $F9, $FF ;234 .byte $FF, $99, $93, $87, $93, $9F, $9F, $FF ;235 .byte $FF, $C3, $E7, $E7, $E7, $E7, $C7, $FF ;236 - .byte $FF, $9C, $94, $80, $80, $99, $FF, $FF ;237 + .byte $FF, $39, $29, $01, $83, $93, $FF, $FF ;237 .byte $FF, $99, $99, $99, $99, $83, $FF, $FF ;238 .byte $FF, $C3, $99, $99, $99, $C3, $FF, $FF ;239 .byte $9F, $9F, $83, $99, $99, $83, $FF, $FF ;240 @@ -1068,7 +1068,7 @@ font: .byte $FF, $F1, $E7, $E7, $E7, $81, $E7, $FF ;244 .byte $FF, $C1, $99, $99, $99, $99, $FF, $FF ;245 .byte $FF, $E7, $C3, $99, $99, $99, $FF, $FF ;246 - .byte $FF, $C9, $C1, $80, $94, $9C, $FF, $FF ;247 + .byte $FF, $93, $83, $01, $29, $39, $FF, $FF ;247 .byte $FF, $99, $C3, $E7, $C3, $99, $FF, $FF ;248 .byte $87, $F3, $C1, $99, $99, $99, $FF, $FF ;249 .byte $FF, $81, $CF, $E7, $F3, $81, $FF, $FF ;250 From e2007d074312c2f8600d8da87b2c55a724f4b128 Mon Sep 17 00:00:00 2001 From: Jeff Tranter <tranter@pobox.com> Date: Thu, 4 Jan 2018 19:04:13 -0500 Subject: [PATCH 1184/2161] New OSI input routine based on disassembly of ROM code. --- libsrc/osic1p/cgetc.s | 189 ++++++++++++++++++++++++++++++++++++++- libsrc/osic1p/kbhit.s | 3 +- libsrc/osic1p/osic1p.inc | 1 - 3 files changed, 190 insertions(+), 3 deletions(-) diff --git a/libsrc/osic1p/cgetc.s b/libsrc/osic1p/cgetc.s index f05ad33e0..d99f69a72 100644 --- a/libsrc/osic1p/cgetc.s +++ b/libsrc/osic1p/cgetc.s @@ -4,17 +4,34 @@ .constructor initcgetc .export _cgetc + .export inputc .import cursor .include "osic1p.inc" .include "extzp.inc" .include "zeropage.inc" +; Internal state that needs to be preserved across calls. +; These variables are named after the original memory locations used by the +; 65V PROM MONITOR, until the actual meaning is determined. +.segment "EXTZP" : zeropage + +KB0213: .res 1 +KB0214: .res 1 +KB0215: .res 1 +KB0216: .res 1 + ; Initialize one-character buffer that is filled by kbhit() .segment "ONCE" initcgetc: lda #$00 sta CHARBUF ; No character in buffer initially + + sta KB0213 ; Initialize keyboard state + sta KB0214 + sta KB0215 + sta KB0216 + rts ; Input routine from 65V PROM MONITOR, show cursor if enabled @@ -35,7 +52,7 @@ nobuffer: lda #$A1 ; full white square sta (SCREEN_PTR),y ; store at cursor position nocursor: - jsr INPUTC ; get input character in A + jsr inputc ; get input character in A ldx cursor beq done ; was cursor on? tax ; save A in X @@ -48,3 +65,173 @@ restorex: done: ldx #$00 ; high byte of int return value rts + +; Routine to get character from keyboard and return it in A. +; Based on the OSI ROM routine at $FD00 but uses different +; storage locations to avoid corrupting CC65 run-time code. + +inputc: txa ; Save X on stack. + pha + tya ; Save Y on stack. + pha +LFD04: lda #$80 ; Bit mask for initial keyboard row +LFD06: jsr LFCBE ; Write keyboard row + jsr LFCC6 ; Read keyboard column + bne LFD13 ; Branch if a key in this column was pressed + lsr a ; Otherwise shift mask to next row + bne LFD06 ; If not done yet, check next row + beq LFD3A ; Branch if last row reached and no key pressed +LFD13: lsr a ; Have a key press. Shift LSB into carry + bcc LFD1F ; Branch if no key pressed in column 0 + txa ; Key pressed in row zero. Get the column data + and #$20 ; Mask only the bit for <ESC> as it is the only key in row zero that returns key press + beq LFD3A ; Branch if <ESC> was not the key + lda #$1B ; Set character to <ESC> + bne LFD50 ; Do more processing +LFD1F: jsr LFE86 ; Shift to find bit that is set (in Y) + tya ; Get bit + sta KB0215 ; Save it + asl a ; Multiply by 7 by shifting left three times (X8)... + asl a + asl a + sec ; ...then subtracting one + sbc KB0215 + sta KB0215 ; Save value*7 for later lookup in table + txa ; Get the keyboard column + lsr a ; Shift out bit zero (only key there is <SHIFT LOCK>) + asl a ; And shift back + jsr LFE86 ; Shift to find bit that is set (in Y) + beq LFD47 ; Branch if no keys pressed + lda #$00 +LFD3A: sta KB0216 ; Save state of <CTRL> and shift keys +LFD3D: sta KB0213 + lda #$02 ; Count used for key debouncing + sta KB0214 + bne LFD04 ; Go back and scan keyboard again +LFD47: clc + tya ; Get bit number of pressed key + adc KB0215 ; Add previously calculated offset for keyboard row*7 + tay + lda LFF3B,y ; Read ASCII code for key from table +LFD50: cmp KB0213 ; Debounce - same as last key scan? + bne LFD3D ; If not, try again + dec KB0214 ; Decrement debounce counter + beq LFD5F ; Branch if done debouncing + jsr LFCDF ; Wait for short delay to debounce keyboard + beq LFD04 ; Go back and scan keyboard. +LFD5F: ldx #$64 ; Was <CONTROL> key down? + cmp KB0216 + bne LFD68 ; Branch if not + ldx #$0F +LFD68: stx KB0214 + sta KB0216 + cmp #$21 + bmi LFDD0 ; Done, return key + cmp #$5F + beq LFDD0 ; Done, return key + lda #$01 + jsr LFCBE ; Write keyboard row + jsr LFCCF ; Read keyboard column + sta KB0215 + and #$01 + tax + lda KB0215 + and #$06 + bne LFDA2 + bit KB0213 + bvc LFDBB + txa + eor #$01 + and #$01 + beq LFDBB + lda #$20 + bit KB0215 + bvc LFDC3 + lda #$C0 + bne LFDC3 +LFDA2: bit KB0213 + bvc LFDAA + txa + beq LFDBB +LFDAA: ldy KB0213 + cpy #$31 + bcc LFDB9 + cpy #$3C + bcs LFDB9 + lda #$F0 + bne LFDBB +LFDB9: lda #$10 +LFDBB: bit KB0215 + bvc LFDC3 + clc + adc #$C0 +LFDC3: clc + adc KB0213 + and #$7F + bit KB0215 + bpl LFDD0 + ora #$80 +LFDD0: sta KB0215 ; Save pressed key + pla + tay ; Restore saved Y value + pla + tax ; Restore saved Y value + lda KB0215 ; Get pressed key and return in A + rts + +; Write keyboard row with value in A. +; Invert the bits before writing. +; Returns original value of A. + +LFCBE: eor #$FF + sta KBD + eor #$FF + rts + +; Read keyboard column and return in X. +; Sets Z flag if no keys were pressed. +; Saves current value of A. + +LFCC6: pha ; Save A + jsr LFCCF ; Read keyboard column + tax ; Save in X + pla ; Restore A + dex ; Decrement and then increment to + inx ; preserve value of X but set flags + rts + +; Read keyboard column. +; Invert the bits (pressed key(s) will show up as ones). + +LFCCF: lda KBD ; Read keyboard hardware + eor #$FF ; Invert the bits + rts + +; Short fixed delay routine. + +LFCDF: ldy #$10 +LFCE1: ldx #$40 +LFCE3: dex + bne LFCE3 + dey + bne LFCE1 + rts + +; Shift A left until we find a 1 in the most significant bit. +; Return the bit number in Y. + +LFE86: ldy #$08 +LFE88: dey + asl a + bcc LFE88 + rts + +; Lookup table of keyboard keys for each scan row. +LFF3B: .byte $BD + .byte 'P', ';', '/', ' ', 'Z', 'A', 'Q' + .byte ',', 'M', 'N', 'B', 'V', 'C', 'X' + .byte 'K', 'J', 'H', 'G', 'F', 'D', 'S' + .byte 'I', 'U', 'Y', 'T', 'R', 'E', 'W' + .byte $00, $00, $0D, $0A, 'O', 'L', '.' + .byte $00, '_', '-', ':', '0', '9', '8' + .byte '7', '6', '5', '4', '3', '2', '1' diff --git a/libsrc/osic1p/kbhit.s b/libsrc/osic1p/kbhit.s index b616b4a3f..1ecfa1041 100644 --- a/libsrc/osic1p/kbhit.s +++ b/libsrc/osic1p/kbhit.s @@ -11,6 +11,7 @@ ; .export _kbhit + .import inputc .include "osic1p.inc" .include "extzp.inc" .include "zeropage.inc" @@ -40,7 +41,7 @@ scan: sta CHARBUF ; No character in buffer rts keypressed: - jsr INPUTC ; Get input character in A + jsr inputc ; Get input character in A sta CHARBUF ; Save in buffer ldx #$00 ; High byte of return is always zero lda #$01 ; Return true diff --git a/libsrc/osic1p/osic1p.inc b/libsrc/osic1p/osic1p.inc index aaa03ba61..9f8620dcb 100644 --- a/libsrc/osic1p/osic1p.inc +++ b/libsrc/osic1p/osic1p.inc @@ -1,4 +1,3 @@ ; Addresses -INPUTC := $FD00 ; Input character from keyboard RESET := $FF00 ; Reset address, show boot prompt KBD := $DF00 ; Polled keyboard register From eb2317d01400f361c396b4626b41894139060983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20M=C3=BChlstrasser?= <stephan.muehlstrasser@web.de> Date: Mon, 2 Sep 2019 20:52:16 +0200 Subject: [PATCH 1185/2161] Restructured according to review Restructured according to review in pull request #567. The "inputc" function was moved in slightly modified form to kbhit.s and replaces the old keyboard scanner. cgetc() uses the new kbhit() to read a character. --- libsrc/osic1p/cgetc.s | 222 +++--------------------------------------- libsrc/osic1p/kbhit.s | 212 +++++++++++++++++++++++++++++++++++----- 2 files changed, 198 insertions(+), 236 deletions(-) diff --git a/libsrc/osic1p/cgetc.s b/libsrc/osic1p/cgetc.s index d99f69a72..56209ff6b 100644 --- a/libsrc/osic1p/cgetc.s +++ b/libsrc/osic1p/cgetc.s @@ -2,236 +2,40 @@ ; char cgetc (void); ; - .constructor initcgetc .export _cgetc - .export inputc .import cursor + .import _kbhit .include "osic1p.inc" .include "extzp.inc" .include "zeropage.inc" -; Internal state that needs to be preserved across calls. -; These variables are named after the original memory locations used by the -; 65V PROM MONITOR, until the actual meaning is determined. -.segment "EXTZP" : zeropage - -KB0213: .res 1 -KB0214: .res 1 -KB0215: .res 1 -KB0216: .res 1 - -; Initialize one-character buffer that is filled by kbhit() - .segment "ONCE" -initcgetc: - lda #$00 - sta CHARBUF ; No character in buffer initially - - sta KB0213 ; Initialize keyboard state - sta KB0214 - sta KB0215 - sta KB0216 - - rts - -; Input routine from 65V PROM MONITOR, show cursor if enabled +; Input routine, show cursor if enabled .code _cgetc: - lda CHARBUF ; character in buffer available? - beq nobuffer - tax ; save character in X - lda #$00 - sta CHARBUF ; empty buffer - beq restorex ; restore X and return -nobuffer: + ldx CHARBUF ; character in buffer available? + bne done lda cursor ; show cursor? beq nocursor ldy CURS_X lda (SCREEN_PTR),y ; fetch current character sta tmp1 ; save it lda #$A1 ; full white square - sta (SCREEN_PTR),y ; store at cursor position + sta (SCREEN_PTR),y ; store at cursor position^ + nocursor: - jsr inputc ; get input character in A - ldx cursor + jsr _kbhit ; get input character in A + tax ; save A in X, set flags + beq nocursor ; until a key is actually pressed + lda cursor beq done ; was cursor on? - tax ; save A in X lda tmp1 ; fetch saved character ldy CURS_X sta (SCREEN_PTR),y ; store at cursor position -restorex: - txa ; restore saved character from X done: + lda #$00 + sta CHARBUF ; empty buffer + txa ; restore saved character from X ldx #$00 ; high byte of int return value rts - -; Routine to get character from keyboard and return it in A. -; Based on the OSI ROM routine at $FD00 but uses different -; storage locations to avoid corrupting CC65 run-time code. - -inputc: txa ; Save X on stack. - pha - tya ; Save Y on stack. - pha -LFD04: lda #$80 ; Bit mask for initial keyboard row -LFD06: jsr LFCBE ; Write keyboard row - jsr LFCC6 ; Read keyboard column - bne LFD13 ; Branch if a key in this column was pressed - lsr a ; Otherwise shift mask to next row - bne LFD06 ; If not done yet, check next row - beq LFD3A ; Branch if last row reached and no key pressed -LFD13: lsr a ; Have a key press. Shift LSB into carry - bcc LFD1F ; Branch if no key pressed in column 0 - txa ; Key pressed in row zero. Get the column data - and #$20 ; Mask only the bit for <ESC> as it is the only key in row zero that returns key press - beq LFD3A ; Branch if <ESC> was not the key - lda #$1B ; Set character to <ESC> - bne LFD50 ; Do more processing -LFD1F: jsr LFE86 ; Shift to find bit that is set (in Y) - tya ; Get bit - sta KB0215 ; Save it - asl a ; Multiply by 7 by shifting left three times (X8)... - asl a - asl a - sec ; ...then subtracting one - sbc KB0215 - sta KB0215 ; Save value*7 for later lookup in table - txa ; Get the keyboard column - lsr a ; Shift out bit zero (only key there is <SHIFT LOCK>) - asl a ; And shift back - jsr LFE86 ; Shift to find bit that is set (in Y) - beq LFD47 ; Branch if no keys pressed - lda #$00 -LFD3A: sta KB0216 ; Save state of <CTRL> and shift keys -LFD3D: sta KB0213 - lda #$02 ; Count used for key debouncing - sta KB0214 - bne LFD04 ; Go back and scan keyboard again -LFD47: clc - tya ; Get bit number of pressed key - adc KB0215 ; Add previously calculated offset for keyboard row*7 - tay - lda LFF3B,y ; Read ASCII code for key from table -LFD50: cmp KB0213 ; Debounce - same as last key scan? - bne LFD3D ; If not, try again - dec KB0214 ; Decrement debounce counter - beq LFD5F ; Branch if done debouncing - jsr LFCDF ; Wait for short delay to debounce keyboard - beq LFD04 ; Go back and scan keyboard. -LFD5F: ldx #$64 ; Was <CONTROL> key down? - cmp KB0216 - bne LFD68 ; Branch if not - ldx #$0F -LFD68: stx KB0214 - sta KB0216 - cmp #$21 - bmi LFDD0 ; Done, return key - cmp #$5F - beq LFDD0 ; Done, return key - lda #$01 - jsr LFCBE ; Write keyboard row - jsr LFCCF ; Read keyboard column - sta KB0215 - and #$01 - tax - lda KB0215 - and #$06 - bne LFDA2 - bit KB0213 - bvc LFDBB - txa - eor #$01 - and #$01 - beq LFDBB - lda #$20 - bit KB0215 - bvc LFDC3 - lda #$C0 - bne LFDC3 -LFDA2: bit KB0213 - bvc LFDAA - txa - beq LFDBB -LFDAA: ldy KB0213 - cpy #$31 - bcc LFDB9 - cpy #$3C - bcs LFDB9 - lda #$F0 - bne LFDBB -LFDB9: lda #$10 -LFDBB: bit KB0215 - bvc LFDC3 - clc - adc #$C0 -LFDC3: clc - adc KB0213 - and #$7F - bit KB0215 - bpl LFDD0 - ora #$80 -LFDD0: sta KB0215 ; Save pressed key - pla - tay ; Restore saved Y value - pla - tax ; Restore saved Y value - lda KB0215 ; Get pressed key and return in A - rts - -; Write keyboard row with value in A. -; Invert the bits before writing. -; Returns original value of A. - -LFCBE: eor #$FF - sta KBD - eor #$FF - rts - -; Read keyboard column and return in X. -; Sets Z flag if no keys were pressed. -; Saves current value of A. - -LFCC6: pha ; Save A - jsr LFCCF ; Read keyboard column - tax ; Save in X - pla ; Restore A - dex ; Decrement and then increment to - inx ; preserve value of X but set flags - rts - -; Read keyboard column. -; Invert the bits (pressed key(s) will show up as ones). - -LFCCF: lda KBD ; Read keyboard hardware - eor #$FF ; Invert the bits - rts - -; Short fixed delay routine. - -LFCDF: ldy #$10 -LFCE1: ldx #$40 -LFCE3: dex - bne LFCE3 - dey - bne LFCE1 - rts - -; Shift A left until we find a 1 in the most significant bit. -; Return the bit number in Y. - -LFE86: ldy #$08 -LFE88: dey - asl a - bcc LFE88 - rts - -; Lookup table of keyboard keys for each scan row. -LFF3B: .byte $BD - .byte 'P', ';', '/', ' ', 'Z', 'A', 'Q' - .byte ',', 'M', 'N', 'B', 'V', 'C', 'X' - .byte 'K', 'J', 'H', 'G', 'F', 'D', 'S' - .byte 'I', 'U', 'Y', 'T', 'R', 'E', 'W' - .byte $00, $00, $0D, $0A, 'O', 'L', '.' - .byte $00, '_', '-', ':', '0', '9', '8' - .byte '7', '6', '5', '4', '3', '2', '1' diff --git a/libsrc/osic1p/kbhit.s b/libsrc/osic1p/kbhit.s index 1ecfa1041..db28854f5 100644 --- a/libsrc/osic1p/kbhit.s +++ b/libsrc/osic1p/kbhit.s @@ -10,39 +10,197 @@ ; in tmp1 and that is set to zero after the first round. ; + .constructor initkbhit .export _kbhit - .import inputc .include "osic1p.inc" .include "extzp.inc" .include "zeropage.inc" -_kbhit: - lda #%11011111 ; Mask for only checking the column for the - sta tmp1 ; ESC key in the first keyboard row. +; Internal state that needs to be preserved across calls. +.segment "EXTZP" : zeropage + +LASTSCAN: .res 1 ; Result of previous keyboard scan +DBNCCNT: .res 1 ; Debounce counter +KBDTMP: .res 1 ; Temporary values +CTRLSHIFT: .res 1 ; State of CTRL and SHIFT keys + +; Initialize one-character buffer that is filled by kbhit() + .segment "ONCE" +initkbhit: + lda #$00 + sta CHARBUF ; No character in buffer initially + + sta LASTSCAN ; Initialize keyboard state + sta DBNCCNT + sta KBDTMP + sta CTRLSHIFT - lda #%11111110 ; Mask for first keyboard row -scan: - sta KBD ; Select keyboard row - tax ; Save A - lda KBD ; Read keyboard columns - ora tmp1 ; Mask out uninteresting keys (only relevant in - ; first row) - cmp #$FF ; No keys pressed? - bne keypressed - lda #$00 ; For remaining rows no keys masked - sta tmp1 - txa ; Restore A - sec ; Want to shift in ones - rol a ; Rotate row select to next bit position - cmp #$FF ; Done? - bne scan ; If not, continue - lda #$00 ; Return false - tax ; High byte of return is also zero - sta CHARBUF ; No character in buffer rts -keypressed: - jsr inputc ; Get input character in A - sta CHARBUF ; Save in buffer + +; Routine to get character from keyboard and return it in A. +; Based on the OSI ROM routine at $FD00 but uses different +; storage locations to avoid corrupting CC65 run-time code. + +_kbhit: lda CHARBUF ; Check for previously saved character + beq LFD05 ldx #$00 ; High byte of return is always zero - lda #$01 ; Return true + rts ; A contains non-zero character code meaning true +LFD05: lda #$80 ; Bit mask for initial keyboard row +LFD06: jsr LFCBE ; Write keyboard row + jsr LFCC6 ; Read keyboard column + bne LFD13 ; Branch if a key in this column was pressed + lsr a ; Otherwise shift mask to next row + bne LFD06 ; If not done yet, check next row + beq LFD3A ; Branch if last row reached and no key pressed +LFD13: lsr a ; Have a key press. Shift LSB into carry + bcc LFD1F ; Branch if no key pressed in column 0 + txa ; Key pressed in row zero. Get the column data + and #$20 ; Mask only the bit for <ESC> as it is the only key in row zero that returns key press + beq LFD3A ; Branch if <ESC> was not the key + lda #$1B ; Set character to <ESC> + bne LFD50 ; Do more processing +LFD1F: jsr LFE86 ; Shift to find bit that is set (in Y) + tya ; Get bit + sta KBDTMP ; Save it + asl a ; Multiply by 7 by shifting left three times (X8)... + asl a + asl a + sec ; ...then subtracting one + sbc KBDTMP + sta KBDTMP ; Save value*7 for later lookup in table + txa ; Get the keyboard column + lsr a ; Shift out bit zero (only key there is <SHIFT LOCK>) + asl a ; And shift back + jsr LFE86 ; Shift to find bit that is set (in Y) + beq LFD47 ; Branch if no keys pressed STM: IS THIS CORRECT? + lda #$00 +LFD3A: sta CTRLSHIFT ; Save state of <CTRL> and shift keys +LFD3D: sta LASTSCAN + lda #$02 ; Count used for key debouncing + sta DBNCCNT + ldx #$00 ; High byte of return is always zero + lda #$00 ; Return false rts +LFD47: clc + tya ; Get bit number of pressed key + adc KBDTMP ; Add previously calculated offset for keyboard row*7 + tay + lda LFF3B,y ; Read ASCII code for key from table +LFD50: cmp LASTSCAN ; Debounce - same as last key scan? + bne LFD3D ; If not, try again + dec DBNCCNT ; Decrement debounce counter + beq LFD5F ; Branch if done debouncing + jsr LFCDF ; Wait for short delay to debounce keyboard + beq _kbhit ; Go back and scan keyboard. +LFD5F: ldx #$64 ; Was <CONTROL> key down? + cmp CTRLSHIFT + bne LFD68 ; Branch if not + ldx #$0F +LFD68: stx DBNCCNT + sta CTRLSHIFT + cmp #$21 + bmi LFDD0 ; Done, return key + cmp #$5F + beq LFDD0 ; Done, return key + lda #$01 + jsr LFCBE ; Write keyboard row + jsr LFCCF ; Read keyboard column + sta KBDTMP + and #$01 + tax + lda KBDTMP + and #$06 + bne LFDA2 + bit LASTSCAN + bvc LFDBB + txa + eor #$01 + and #$01 + beq LFDBB + lda #$20 + bit KBDTMP + bvc LFDC3 + lda #$C0 + bne LFDC3 +LFDA2: bit LASTSCAN + bvc LFDAA + txa + beq LFDBB +LFDAA: ldy LASTSCAN + cpy #$31 + bcc LFDB9 + cpy #$3C + bcs LFDB9 + lda #$F0 + bne LFDBB +LFDB9: lda #$10 +LFDBB: bit KBDTMP + bvc LFDC3 + clc + adc #$C0 +LFDC3: clc + adc LASTSCAN + and #$7F + bit KBDTMP + bpl LFDD0 + ora #$80 +LFDD0: sta KBDTMP ; Save pressed key and return in A + sta CHARBUF + rts + +; Write keyboard row with value in A. +; Invert the bits before writing. +; Returns original value of A. + +LFCBE: eor #$FF + sta KBD + eor #$FF + rts + +; Read keyboard column and return in X. +; Sets Z flag if no keys were pressed. +; Saves current value of A. + +LFCC6: pha ; Save A + jsr LFCCF ; Read keyboard column + tax ; Save in X + pla ; Restore A + dex ; Decrement and then increment to + inx ; preserve value of X but set flags + rts + +; Read keyboard column. +; Invert the bits (pressed key(s) will show up as ones). + +LFCCF: lda KBD ; Read keyboard hardware + eor #$FF ; Invert the bits + rts + +; Short fixed delay routine. + +LFCDF: ldy #$10 +LFCE1: ldx #$40 +LFCE3: dex + bne LFCE3 + dey + bne LFCE1 + rts + +; Shift A left until we find a 1 in the most significant bit. +; Return the bit number in Y. + +LFE86: ldy #$08 +LFE88: dey + asl a + bcc LFE88 + rts + +; Lookup table of keyboard keys for each scan row. +LFF3B: .byte $BD + .byte 'P', ';', '/', ' ', 'Z', 'A', 'Q' + .byte ',', 'M', 'N', 'B', 'V', 'C', 'X' + .byte 'K', 'J', 'H', 'G', 'F', 'D', 'S' + .byte 'I', 'U', 'Y', 'T', 'R', 'E', 'W' + .byte $00, $00, $0D, $0A, 'O', 'L', '.' + .byte $00, '_', '-', ':', '0', '9', '8' + .byte '7', '6', '5', '4', '3', '2', '1' From 8704d42005f91e11257a34c94ff97485a9ba1379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20M=C3=BChlstrasser?= <stephan.muehlstrasser@web.de> Date: Tue, 3 Sep 2019 10:04:30 +0200 Subject: [PATCH 1186/2161] Remove obsolete comment --- kbhit.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 kbhit.c diff --git a/kbhit.c b/kbhit.c new file mode 100644 index 000000000..4ce1894ca --- /dev/null +++ b/kbhit.c @@ -0,0 +1,19 @@ +/* + * Keyboard test program. + */ + +#include <conio.h> + +int main(void) +{ + unsigned char c; + + clrscr(); + cputs(" Keyboard Test\r\n"); + + while (1) { + c = cgetc(); + cputc(c); + } + return 0; +} From 668273cdf5b402b78457bff3b8a6a1a275c0c404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20M=C3=BChlstrasser?= <stephan.muehlstrasser@web.de> Date: Wed, 4 Sep 2019 19:33:14 +0200 Subject: [PATCH 1187/2161] Remove source file that was only used for testing --- kbhit.c | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 kbhit.c diff --git a/kbhit.c b/kbhit.c deleted file mode 100644 index 4ce1894ca..000000000 --- a/kbhit.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Keyboard test program. - */ - -#include <conio.h> - -int main(void) -{ - unsigned char c; - - clrscr(); - cputs(" Keyboard Test\r\n"); - - while (1) { - c = cgetc(); - cputc(c); - } - return 0; -} From 7547c4c77c1feef64a247c3c091ba995ff1de03c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20M=C3=BChlstrasser?= <stephan.muehlstrasser@web.de> Date: Tue, 17 Sep 2019 20:03:51 +0200 Subject: [PATCH 1188/2161] Address review comments - removed typo from comment - removed redundant AND instruction --- libsrc/osic1p/cgetc.s | 2 +- libsrc/osic1p/kbhit.s | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/libsrc/osic1p/cgetc.s b/libsrc/osic1p/cgetc.s index 56209ff6b..380353b77 100644 --- a/libsrc/osic1p/cgetc.s +++ b/libsrc/osic1p/cgetc.s @@ -21,7 +21,7 @@ _cgetc: lda (SCREEN_PTR),y ; fetch current character sta tmp1 ; save it lda #$A1 ; full white square - sta (SCREEN_PTR),y ; store at cursor position^ + sta (SCREEN_PTR),y ; store at cursor position nocursor: jsr _kbhit ; get input character in A diff --git a/libsrc/osic1p/kbhit.s b/libsrc/osic1p/kbhit.s index db28854f5..122a81c6d 100644 --- a/libsrc/osic1p/kbhit.s +++ b/libsrc/osic1p/kbhit.s @@ -72,7 +72,7 @@ LFD1F: jsr LFE86 ; Shift to find bit that is set (in Y) lsr a ; Shift out bit zero (only key there is <SHIFT LOCK>) asl a ; And shift back jsr LFE86 ; Shift to find bit that is set (in Y) - beq LFD47 ; Branch if no keys pressed STM: IS THIS CORRECT? + beq LFD47 ; Branch if no keys pressed lda #$00 LFD3A: sta CTRLSHIFT ; Save state of <CTRL> and shift keys LFD3D: sta LASTSCAN @@ -106,7 +106,6 @@ LFD68: stx DBNCCNT jsr LFCBE ; Write keyboard row jsr LFCCF ; Read keyboard column sta KBDTMP - and #$01 tax lda KBDTMP and #$06 From 55444b8337bf163970f62ad1aa3f917a6f0719ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20M=C3=BChlstrasser?= <stephan.muehlstrasser@web.de> Date: Tue, 17 Sep 2019 20:23:36 +0200 Subject: [PATCH 1189/2161] Removed redundant LDA After the removal of the redundant AND in commit 704c8df04ffa3679f87fff019ad986fbd8801ca5 also the subsequent LDA became redundant. --- libsrc/osic1p/kbhit.s | 1 - 1 file changed, 1 deletion(-) diff --git a/libsrc/osic1p/kbhit.s b/libsrc/osic1p/kbhit.s index 122a81c6d..8744baf61 100644 --- a/libsrc/osic1p/kbhit.s +++ b/libsrc/osic1p/kbhit.s @@ -107,7 +107,6 @@ LFD68: stx DBNCCNT jsr LFCCF ; Read keyboard column sta KBDTMP tax - lda KBDTMP and #$06 bne LFDA2 bit LASTSCAN From f3d898d6a3e2f5a595e542c5fb27c06fd3e21fad Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 15 Oct 2019 12:10:34 -0400 Subject: [PATCH 1190/2161] Added the GIF switch to the X16 emulator's control port. --- asminc/cx16.inc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/asminc/cx16.inc b/asminc/cx16.inc index 6f3f1c731..5b46908d9 100644 --- a/asminc/cx16.inc +++ b/asminc/cx16.inc @@ -285,7 +285,7 @@ NMIVec := $0318 .struct VIA2 .org $9F70 PRB .byte - PRA .byte ; NES controller communication + PRA .byte ; NES controller communication DDRB .byte DDRA .byte T1 .word @@ -306,11 +306,12 @@ NMIVec := $0318 .struct EMULATOR .org $9FB0 DEBUG .byte ; Boolean: debugging enabled - VIDACCESSLOG .byte ; Boolean: log VERA activity + VERALOG .byte ; Boolean: log VERA activity KEYBOARDLOG .byte ; Boolean: log keyboard data - ECHO .byte ; Boolean: echo enabled + ECHO .byte ; Type of echo that's enabled SAVEXIT .byte ; Boolean: save on exit - .res $D - $5 - KEYMAP .byte ; Current keyboard layout number - DETECT .byte 2 ; If is "16" string, then running on emulator + GIFREC .byte ; Method of recording GIF movie + .org $9FBD + KEYMAP .byte ; Current keyboard layout number (Read-Only) + DETECT .byte 2 ; If is "16" string, then running on emulator (RO) .endstruct From da01286037dd1e396b15d756a401240c14b277a7 Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Tue, 15 Oct 2019 22:25:26 +0200 Subject: [PATCH 1191/2161] Tentative solution for cgetc in Lynx --- libsrc/lynx/cgetc.s | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libsrc/lynx/cgetc.s b/libsrc/lynx/cgetc.s index b61fb44f6..19cfdaff1 100644 --- a/libsrc/lynx/cgetc.s +++ b/libsrc/lynx/cgetc.s @@ -20,13 +20,13 @@ ; So the keyboard returns '1', '2', '3', 'P', 'R', 'F' or '?'. _cgetc: - lda KBSTL - ora KBEDG - bne @L1 jsr _kbhit ; Check for char available + bne @L1 tax ; Test result bra _cgetc @L1: + lda KBSTL + ora KBEDG ldx #0 and #1 beq @L6 From e4b60e10682717360575c1d93885c72ab3dc86ea Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Wed, 16 Oct 2019 13:30:58 +0200 Subject: [PATCH 1192/2161] Remove useless tax --- libsrc/lynx/cgetc.s | 1 - 1 file changed, 1 deletion(-) diff --git a/libsrc/lynx/cgetc.s b/libsrc/lynx/cgetc.s index 19cfdaff1..c81afa82b 100644 --- a/libsrc/lynx/cgetc.s +++ b/libsrc/lynx/cgetc.s @@ -22,7 +22,6 @@ _cgetc: jsr _kbhit ; Check for char available bne @L1 - tax ; Test result bra _cgetc @L1: lda KBSTL From 1074d35a1579ae1a6cc334455c0391fec6da416a Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Wed, 16 Oct 2019 23:22:41 +0200 Subject: [PATCH 1193/2161] remove bra --- libsrc/lynx/cgetc.s | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/libsrc/lynx/cgetc.s b/libsrc/lynx/cgetc.s index c81afa82b..ee4893377 100644 --- a/libsrc/lynx/cgetc.s +++ b/libsrc/lynx/cgetc.s @@ -21,49 +21,47 @@ _cgetc: jsr _kbhit ; Check for char available - bne @L1 - bra _cgetc -@L1: + beq _cgetc lda KBSTL ora KBEDG ldx #0 and #1 - beq @L6 + beq @L5 lda KBEDG ; Pause button is pressed and #$0c - beq @L3 + beq @L2 ora KBSTL -@L2: +@L1: bit #$04 - beq @L4 ; Pause + Opt 1 = Reset + beq @L3 ; Pause + Opt 1 = Reset bit #$08 - beq @L5 ; Pause + Opt 2 = Flip + beq @L4 ; Pause + Opt 2 = Flip lda #'?' ; All buttons pressed rts -@L3: +@L2: lda KBSTL ; Pause alone was the last placed button and #$0c - bne @L2 + bne @L1 lda #'P' ; Pause pressed rts -@L4: +@L3: lda #'R' ; Reset pressed rts -@L5: +@L4: lda #'F' ; Flip pressed rts -@L6: +@L5: lda KBEDG ; No Pause pressed ora KBSTL bit #$08 - beq @L8 - bit #$04 beq @L7 + bit #$04 + beq @L6 lda #'3' ; opt 1 + opt 2 pressed rts -@L7: +@L6: lda #'1' ; opt 1 pressed rts -@L8: +@L7: lda #'2' ; opt 2 pressed rts From 9fa90e2265b0d54e3fd9e6ec0227821f6a09d9de Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 24 Oct 2019 05:15:42 -0400 Subject: [PATCH 1194/2161] Added VERA peek() and poke() to the cx16 library. They simplify C programs' direct access to VERA's internal address space. --- include/cx16.h | 19 ++++++++++++++----- libsrc/cx16/vpeek.s | 19 +++++++++++++++++++ libsrc/cx16/vpoke.s | 21 +++++++++++++++++++++ libsrc/cx16/vset.s | 20 ++++++++++++++++++++ 4 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 libsrc/cx16/vpeek.s create mode 100644 libsrc/cx16/vpoke.s create mode 100644 libsrc/cx16/vset.s diff --git a/include/cx16.h b/include/cx16.h index db32d8460..a2f52850a 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -144,9 +144,10 @@ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ unsigned char vera_action; /* Boolean: displaying VERA activity */ unsigned char keyboard; /* Boolean: displaying typed keys */ - unsigned char echo; /* Boolean: Kernal output echoed to host */ + unsigned char echo; /* How Kernal output should be echoed to host */ unsigned char save_on_exit; /* Boolean: save SD card when quitting */ - unsigned char unused[0xD - 0x5]; + unsigned char gif_method; /* How GIF movie is being recorded */ + unsigned char unused[0xD - 0x6]; unsigned char keymap; /* Keyboard layout number */ const char detect[2]; /* "16" if running on x16emu */ }; @@ -173,16 +174,24 @@ signed char get_ostype (void); ** Positive -- release build */ -void __fastcall__ set_tv (unsigned char); -/* Set the video mode the machine will use. +void __fastcall__ set_tv (unsigned char type); +/* Set the video type that the machine will use. ** Call with a TV_xx constant. */ -unsigned char __fastcall__ videomode (unsigned char Mode); +unsigned char __fastcall__ videomode (unsigned char mode); /* Set the video mode, return the old mode. Call with one of the VIDEOMODE_xx ** constants. */ +unsigned char __fastcall__ vpeek (unsigned long addr); +/* Get a byte from a location in VERA's internal address space. */ + +void __fastcall__ vpoke (unsigned char data, unsigned long addr); +/* Put a byte into a location in VERA's internal address space. +** (addr is second instead of first for the sake of code efficiency.) +*/ + /* End of cX16.h */ diff --git a/libsrc/cx16/vpeek.s b/libsrc/cx16/vpeek.s new file mode 100644 index 000000000..0c1a94651 --- /dev/null +++ b/libsrc/cx16/vpeek.s @@ -0,0 +1,19 @@ +; +; 2019-10-22, Greg King +; +; unsigned char fastcall vpeek (unsigned long addr); +; /* Get a byte from a location in VERA's internal address space. */ +; + + .export _vpeek + + .import vset + .include "cx16.inc" + + +_vpeek: php ; (vset blocks interrupts) + jsr vset ; put VERA's address + ldx #>$0000 + lda VERA::DATA0 ; read VERA port zero + plp + rts diff --git a/libsrc/cx16/vpoke.s b/libsrc/cx16/vpoke.s new file mode 100644 index 000000000..8c21e9b21 --- /dev/null +++ b/libsrc/cx16/vpoke.s @@ -0,0 +1,21 @@ +; +; 2019-10-22, Greg King +; +; void fastcall vpoke (unsigned char data, unsigned long addr); +; /* Put a byte into a location in VERA's internal address space. +; ** (addr is second instead of first for the sake of code efficiency.) +; */ +; + + .export _vpoke + + .import vset, popa + .include "cx16.inc" + + +_vpoke: php ; (vset blocks interrupts) + jsr vset ; put VERA's address + jsr popa + sta VERA::DATA0 ; write data to VERA port zero + plp + rts diff --git a/libsrc/cx16/vset.s b/libsrc/cx16/vset.s new file mode 100644 index 000000000..9178850ea --- /dev/null +++ b/libsrc/cx16/vset.s @@ -0,0 +1,20 @@ +; +; 2019-10-22, Greg King +; +; Set the __far__ address that VERA will use for data access. +; This is a support function for the fastcall functions vpeek() and vpoke(). +; + + .export vset + + .importzp sreg + .include "cx16.inc" + + +vset: ldy sreg + sei ; don't let interrupt handlers interfere + stz VERA::CTRL ; set address for VERA's data port zero + sta VERA::ADDR + stx VERA::ADDR+1 + sty VERA::ADDR+2 + rts From 128991d868f94d471540a3964b682d902073460d Mon Sep 17 00:00:00 2001 From: "Curt J. Sampson" <cjs@cynic.net> Date: Thu, 24 Oct 2019 13:46:41 +0900 Subject: [PATCH 1195/2161] libsrc/*/kplot.s: Use cbm_kernal.inc symbols, not hardcoded addrs On C64, VIC-20 and Plus/4, the conio library PLOT routine uses direct calls into the Kernal, including the Kernal PLOT routine that we're replacing. These were previously hardcoded addresses; we change these to use the symbols for those routines defined in cbm_kernal.inc. (This changes no functionality.) To do this, we need to import cbm_kernal.inc in a namespace so we don't have a collision between the PLOT that we're defining and the Kernal definition. We also add a UPDCRAMPTR symbol (used by kplot for VIC-20 and C64) to the direct entry kernal routines in in cbm_kernal.inc, and expand the comments describing what the "direct entry" Kernal routines are. <greg.king5@verizon.net> (GitHub: greg-king5) came up with this idea and did initial testing of it. This has been tested on VICE xvic, x64 and xplus4 emulators with a program that does a cputs() call (github.com/0cjs/vic20cc65) to confirm that it works the same way after as it did before. --- asminc/cbm_kernal.inc | 12 ++++++++++++ libsrc/c64/kplot.s | 11 ++++++----- libsrc/plus4/kplot.s | 9 +++++---- libsrc/vic20/kplot.s | 10 ++++++---- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/asminc/cbm_kernal.inc b/asminc/cbm_kernal.inc index 79edce06b..6e1e1604b 100644 --- a/asminc/cbm_kernal.inc +++ b/asminc/cbm_kernal.inc @@ -100,14 +100,26 @@ UDTIM := $FFEA ; --------------------------------------------------------------------------- ; Kernal routines, direct entries +; +; Unlike the above, these are not standard functions with entries in the jump +; table. They do not exist in all Kernals, and where they do the entry point is +; specific to that particular machine and possibly even Kernal version. +; +; This list is not comprehensive: missing items for particular machines +; should be added as needed. +; +; UPDCRAMPTR: Updates the color RAM pointer to match the screen RAM pointer. +; .if .def(__VIC20__) CLRSCR := $E55F KBDREAD := $E5CF + UPDCRAMPTR := $EAB2 .elseif .def(__C64__) CLRSCR := $E544 KBDREAD := $E5B4 NMIEXIT := $FEBC + UPDCRAMPTR := $EA24 .elseif .def(__C128__) CLRSCR := $C142 KBDREAD := $C006 diff --git a/libsrc/c64/kplot.s b/libsrc/c64/kplot.s index 2d60fd4a6..856bd148d 100644 --- a/libsrc/c64/kplot.s +++ b/libsrc/c64/kplot.s @@ -7,15 +7,16 @@ .export PLOT +.scope KERNAL + .include "cbm_kernal.inc" +.endscope .proc PLOT bcs @L1 - jsr $FFF0 ; Set cursor position - jmp $EA24 ; Set pointer to color RAM + jsr KERNAL::PLOT ; Set cursor position using original ROM PLOT + jmp KERNAL::UPDCRAMPTR ; Set pointer to color RAM to match new cursor position -@L1: jmp $FFF0 ; Get cursor position +@L1: jmp KERNAL::PLOT ; Get cursor position .endproc - - diff --git a/libsrc/plus4/kplot.s b/libsrc/plus4/kplot.s index 7035b05d5..7883c28a6 100644 --- a/libsrc/plus4/kplot.s +++ b/libsrc/plus4/kplot.s @@ -6,16 +6,17 @@ .export PLOT +.scope KERNAL + .include "cbm_kernal.inc" +.endscope + .include "plus4.inc" .segment "LOWCODE" ; Must go into low memory .proc PLOT sta ENABLE_ROM ; Enable the ROM - jsr $FFF0 ; Call the ROM routine + jsr KERNAL::PLOT ; Call the ROM routine sta ENABLE_RAM ; Switch back to RAM rts ; Return to caller .endproc - - - diff --git a/libsrc/vic20/kplot.s b/libsrc/vic20/kplot.s index f37ed8fce..1a943d374 100644 --- a/libsrc/vic20/kplot.s +++ b/libsrc/vic20/kplot.s @@ -7,14 +7,16 @@ .export PLOT +.scope KERNAL + .include "cbm_kernal.inc" +.endscope .proc PLOT bcs @L1 - jsr $FFF0 ; Set cursor position - jmp $EAB2 ; Set pointer to color RAM + jsr KERNAL::PLOT ; Set cursor position using original ROM PLOT + jmp KERNAL::UPDCRAMPTR ; Set pointer to color RAM to match new cursor position -@L1: jmp $FFF0 ; Get cursor position +@L1: jmp KERNAL::PLOT ; Get cursor position .endproc - From 1d39863a602a728c83aa600a7929b76ce9d1bb06 Mon Sep 17 00:00:00 2001 From: "Curt J. Sampson" <cjs@cynic.net> Date: Wed, 9 Oct 2019 21:05:00 +0900 Subject: [PATCH 1196/2161] vic20/cputc: Fix incorrect CRAM_PTR at startup when using conio To do this we add a constructor call to UPDCRAMPTR, which is the ROM routine that fixes up CRAM_PTR to match the screen location pointed to by SCREEN_PTR. This adds two additional bytes to programs using cputc() or other routines that call it. These are in theory recoverable, but the VIC-20 does not yet free space used by constructors after the constructors have been called. Thanks to <greg.king5@verizon.net> (GitHub: greg-king5) for investigating the difference in the VIC-20 KERNAL from the C64 and proposing this solution to the problem.[1] [1]: https://github.com/cc65/cc65/issues/946#issuecomment-538502820 --- libsrc/vic20/cputc.s | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/libsrc/vic20/cputc.s b/libsrc/vic20/cputc.s index 43aacdae3..1db818546 100644 --- a/libsrc/vic20/cputc.s +++ b/libsrc/vic20/cputc.s @@ -10,8 +10,29 @@ .import gotoxy .import PLOT +.scope KERNAL + .include "cbm_kernal.inc" +.endscope + .include "vic20.inc" +; VIC-20 KERNAL routines (such as PLOT) do not always leave the color RAM +; pointer CRAM_PTR pointing at the color RAM location matching the screen +; RAM pointer SCREEN_PTR. Instead they update it when they need it to be +; correct by calling UPDCRAMPTR. +; +; We make things more efficient by having conio always update CRAM_PTR when +; we move the screen pointer to avoid extra calls to ensure it's updated +; before doing screen output. (Among other things, We replace the ROM +; version of PLOT with our own in libsrc/vic20/kplot.s to ensure this +; precondition.) +; +; However, this means that CRAM_PTR may be (and is, after a cold boot) +; incorrect for us at program startup, causing cputc() not to work. We fix +; this with a constructor that ensures CRAM_PTR matches SCREEN_PTR. +; + UPDCRAMPTR := KERNAL::UPDCRAMPTR ; .constructor doesn't understand namespaces + .constructor UPDCRAMPTR _cputcxy: pha ; Save C From 609f63ac749fc4bfc75720d5b27c5f7820dc741b Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Mon, 28 Oct 2019 20:02:18 +0100 Subject: [PATCH 1197/2161] Second tentative fix --- libsrc/lynx/cgetc.s | 4 ++++ libsrc/lynx/kbhit.s | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libsrc/lynx/cgetc.s b/libsrc/lynx/cgetc.s index ee4893377..bb2840b1f 100644 --- a/libsrc/lynx/cgetc.s +++ b/libsrc/lynx/cgetc.s @@ -20,8 +20,10 @@ ; So the keyboard returns '1', '2', '3', 'P', 'R', 'F' or '?'. _cgetc: + bne _start jsr _kbhit ; Check for char available beq _cgetc +_start: lda KBSTL ora KBEDG ldx #0 @@ -52,6 +54,8 @@ _cgetc: rts @L5: lda KBEDG ; No Pause pressed + ldx #$00 + stx KBEDG ora KBSTL bit #$08 beq @L7 diff --git a/libsrc/lynx/kbhit.s b/libsrc/lynx/kbhit.s index b606fc49a..a5126a7dc 100644 --- a/libsrc/lynx/kbhit.s +++ b/libsrc/lynx/kbhit.s @@ -49,8 +49,6 @@ _kbhit: sta KBNPR ; inverted previous ones pressed stx KBPRV lda KBEDG - beq @L1 - jmp return1 ; Key hit - @L1: tax ; No new keys hit rts + From 43f24afe297c93256f98dfae2e71613feeedb751 Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Mon, 28 Oct 2019 21:25:41 +0100 Subject: [PATCH 1198/2161] stz --- libsrc/lynx/cgetc.s | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libsrc/lynx/cgetc.s b/libsrc/lynx/cgetc.s index bb2840b1f..17943e2dd 100644 --- a/libsrc/lynx/cgetc.s +++ b/libsrc/lynx/cgetc.s @@ -54,8 +54,7 @@ _start: rts @L5: lda KBEDG ; No Pause pressed - ldx #$00 - stx KBEDG + stz KBEDG ora KBSTL bit #$08 beq @L7 From 78d660da5571f29605dfdafe359527bf3c102823 Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Wed, 30 Oct 2019 09:14:17 +0100 Subject: [PATCH 1199/2161] kbhit checks KBEDG and getc resets KBEDG --- libsrc/lynx/cgetc.s | 16 ++++++++++------ libsrc/lynx/kbhit.s | 4 +++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/libsrc/lynx/cgetc.s b/libsrc/lynx/cgetc.s index 17943e2dd..368a0e8d3 100644 --- a/libsrc/lynx/cgetc.s +++ b/libsrc/lynx/cgetc.s @@ -20,6 +20,7 @@ ; So the keyboard returns '1', '2', '3', 'P', 'R', 'F' or '?'. _cgetc: + lda KBEDG bne _start jsr _kbhit ; Check for char available beq _cgetc @@ -39,19 +40,19 @@ _start: bit #$08 beq @L4 ; Pause + Opt 2 = Flip lda #'?' ; All buttons pressed - rts + bra reset_and_exit @L2: lda KBSTL ; Pause alone was the last placed button and #$0c bne @L1 lda #'P' ; Pause pressed - rts + bra reset_and_exit @L3: lda #'R' ; Reset pressed - rts + bra reset_and_exit @L4: lda #'F' ; Flip pressed - rts + bra reset_and_exit @L5: lda KBEDG ; No Pause pressed stz KBEDG @@ -61,10 +62,13 @@ _start: bit #$04 beq @L6 lda #'3' ; opt 1 + opt 2 pressed - rts + bra reset_and_exit @L6: lda #'1' ; opt 1 pressed - rts + bra reset_and_exit @L7: lda #'2' ; opt 2 pressed + +reset_and_exit: + stz KBEDG rts diff --git a/libsrc/lynx/kbhit.s b/libsrc/lynx/kbhit.s index a5126a7dc..a846c43e8 100644 --- a/libsrc/lynx/kbhit.s +++ b/libsrc/lynx/kbhit.s @@ -29,6 +29,8 @@ KBNPR: .byte 0 .code _kbhit: + lda KBEDG + bne L1 lda $FCB0 ; Read the Opt buttons and #$0c sta KBTMP @@ -49,6 +51,6 @@ _kbhit: sta KBNPR ; inverted previous ones pressed stx KBPRV lda KBEDG -@L1: tax ; No new keys hit +L1: ldx #$00 rts From 2bd798fa13fffa2a73df3ca46285a59fd020f6bc Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Wed, 30 Oct 2019 18:32:35 +0100 Subject: [PATCH 1200/2161] Optimizations --- libsrc/lynx/cgetc.s | 9 ++------- libsrc/lynx/kbhit.s | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/libsrc/lynx/cgetc.s b/libsrc/lynx/cgetc.s index 368a0e8d3..362371ec3 100644 --- a/libsrc/lynx/cgetc.s +++ b/libsrc/lynx/cgetc.s @@ -19,14 +19,10 @@ ; and Opt1 + Opt2 pressed '3'. ; So the keyboard returns '1', '2', '3', 'P', 'R', 'F' or '?'. -_cgetc: - lda KBEDG - bne _start +_cgetc: jsr _kbhit ; Check for char available beq _cgetc -_start: - lda KBSTL - ora KBEDG + ora KBSTL ldx #0 and #1 beq @L5 @@ -55,7 +51,6 @@ _start: bra reset_and_exit @L5: lda KBEDG ; No Pause pressed - stz KBEDG ora KBSTL bit #$08 beq @L7 diff --git a/libsrc/lynx/kbhit.s b/libsrc/lynx/kbhit.s index a846c43e8..90d9061cd 100644 --- a/libsrc/lynx/kbhit.s +++ b/libsrc/lynx/kbhit.s @@ -51,6 +51,6 @@ _kbhit: sta KBNPR ; inverted previous ones pressed stx KBPRV lda KBEDG -L1: ldx #$00 +L1: tax rts From 0d21a2b5a4a71a39b730492068ca1cf01448b4d5 Mon Sep 17 00:00:00 2001 From: Richard Halkyard <rhalkyard@gmail.com> Date: Thu, 31 Oct 2019 11:23:15 -0500 Subject: [PATCH 1201/2161] Reformat comments to style guide rules --- libsrc/c64/tgi/c64-hi.s | 95 ++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 48 deletions(-) diff --git a/libsrc/c64/tgi/c64-hi.s b/libsrc/c64/tgi/c64-hi.s index c9167b51d..38faf3d77 100644 --- a/libsrc/c64/tgi/c64-hi.s +++ b/libsrc/c64/tgi/c64-hi.s @@ -131,7 +131,7 @@ VBASE := $E000 ; Video memory base address ; INSTALL: -; rts ; fall through +; rts ; Fall through ; ------------------------------------------------------------------------ @@ -272,7 +272,7 @@ CLEAR: ldy #$00 sta VBASE+$1C00,y sta VBASE+$1D00,y sta VBASE+$1E00,y - sta VBASE+$1E40,y ; preserve vectors + sta VBASE+$1E40,y ; Preserve vectors iny bne @L1 rts @@ -285,7 +285,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). @@ -460,14 +460,14 @@ GETPIXEL: LINE: -@CHECK: lda X2 ;Make sure x1<x2 +@CHECK: lda X2 ; Make sure x1<x2 sec sbc X1 tax lda X2+1 sbc X1+1 bpl @CONT - lda Y2 ;If not, swap P1 and P2 + lda Y2 ; If not, swap P1 and P2 ldy Y1 sta Y1 sty Y2 @@ -488,19 +488,19 @@ LINE: @CONT: sta DX+1 stx DX - ldx #$C8 ;INY - lda Y2 ;Calculate dy + ldx #$C8 ; INY + lda Y2 ; Calculate dy sec sbc Y1 tay lda Y2+1 sbc Y1+1 - bpl @DYPOS ;Is y2>=y1? - lda Y1 ;Otherwise dy=y1-y2 + 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 @@ -516,8 +516,8 @@ LINE: sta $01 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 @@ -535,14 +535,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 ; @@ -554,17 +554,17 @@ 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 @@ -574,13 +574,13 @@ YCONT2: lda (POINT),y ;Plot endpoint cli 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 @@ -598,34 +598,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 - jsr LINEPLOT ;Plot the last chunk + lsr CHUNK ; Advance to last point + jsr LINEPLOT ; Plot the last chunk lda #$36 sta $01 cli @@ -651,22 +650,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 @@ -691,11 +690,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 @@ -704,8 +703,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 @@ -861,10 +860,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 2bec637637df08ffa5a43c0e75fa04015934e0e3 Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Tue, 5 Nov 2019 20:15:34 +0100 Subject: [PATCH 1202/2161] Optimize a negation in signed division. --- libsrc/runtime/idiv32by16r16.s | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/libsrc/runtime/idiv32by16r16.s b/libsrc/runtime/idiv32by16r16.s index 12e7feb51..098e3dbfc 100644 --- a/libsrc/runtime/idiv32by16r16.s +++ b/libsrc/runtime/idiv32by16r16.s @@ -29,19 +29,18 @@ idiv32by16r16: stx ptr3+1 lda ptr2+1 + cmp #$80 eor tmp1 sta tmp1 - bit ptr2+1 - bpl @L3 + bcc @L3 ; Negate the value in ptr1:ptr2 ldx #0 ldy #4 - sec -@L2: lda ptr1,x - eor #$FF - adc #$00 +; sec +@L2: lda #$00 + sbc ptr1,x sta ptr1,x inx dey From 421c3f2b4fef1896316b0d8b0227727c50071fdb Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Tue, 5 Nov 2019 20:16:21 +0100 Subject: [PATCH 1203/2161] Don't set carry when already set. --- libsrc/runtime/imul8x8r16.s | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libsrc/runtime/imul8x8r16.s b/libsrc/runtime/imul8x8r16.s index e1aea30ae..72e6d03a2 100644 --- a/libsrc/runtime/imul8x8r16.s +++ b/libsrc/runtime/imul8x8r16.s @@ -1,6 +1,7 @@ ; ; 2010-11-02, Ullrich von Bassewitz ; 2014-09-10, Greg King +; 2019-11-05, Piotr Fusik ; ; CC65 runtime: 8x8 => 16 signed multiplication ; @@ -59,7 +60,8 @@ NegMult: bnz @L2 ; Branch always @L0: tya ; Subtract current multiplicand - sub ptr3 +; sec + sbc ptr3 tay txa sbc ptr3+1 From 985371433b016b4412f115c852fd44e0cf6dba69 Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Tue, 5 Nov 2019 20:26:02 +0100 Subject: [PATCH 1204/2161] Swap the positive/negative paths to save a branch. --- libsrc/runtime/imul8x8r16.s | 55 +++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/libsrc/runtime/imul8x8r16.s b/libsrc/runtime/imul8x8r16.s index 72e6d03a2..fe939f668 100644 --- a/libsrc/runtime/imul8x8r16.s +++ b/libsrc/runtime/imul8x8r16.s @@ -32,24 +32,7 @@ imul8x8r16m: ldy #<$0000 ; Clear .XY accumulator ldx #>$0000 lda ptr1 - bmi NegMult - bpl @L2 ; Branch always - -@L0: tya ; Add current multiplicand - add ptr3 - tay - txa - adc ptr3+1 - tax - -@L1: asl ptr3 - rol ptr3+1 -@L2: lsr ptr1 ; Get next bit of Right-Hand Side into carry - bcs @L0 - bnz @L1 ; Loop if more one-bits in multiplier - - tya ; Put result into cc65's accumulator - rts + bpl PosStart ; The multiplier is negative. ; Therefore, make it positive; and, subtract when multiplying. @@ -57,9 +40,10 @@ NegMult: eor #%11111111 sta ptr1 inc ptr1 - bnz @L2 ; Branch always + bnz NegStart ; Branch always -@L0: tya ; Subtract current multiplicand +NegAdd: + tya ; Subtract current multiplicand ; sec sbc ptr3 tay @@ -67,11 +51,34 @@ NegMult: sbc ptr3+1 tax -@L1: asl ptr3 +NegShift: + asl ptr3 rol ptr3+1 -@L2: lsr ptr1 ; Get next bit of Right-Hand Side into carry - bcs @L0 - bnz @L1 ; Loop if more one-bits in multiplier +NegStart: + lsr ptr1 ; Get next bit of Right-Hand Side into carry + bcs NegAdd + bnz NegShift ; Loop if more one-bits in multiplier + + tya ; Put result into cc65's accumulator + rts + +; The multiplier is positive. + +PosAdd: + tya ; Add current multiplicand + add ptr3 + tay + txa + adc ptr3+1 + tax + +PosShift: + asl ptr3 + rol ptr3+1 +PosStart: + lsr ptr1 ; Get next bit of Right-Hand Side into carry + bcs PosAdd + bnz PosShift ; Loop if more one-bits in multiplier tya ; Put result into cc65's accumulator rts From d38417b347323ba73d2af5106316720f038e95fa Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Tue, 5 Nov 2019 20:44:21 +0100 Subject: [PATCH 1205/2161] Optimize sign extension. --- libsrc/runtime/imul8x8r16.s | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/libsrc/runtime/imul8x8r16.s b/libsrc/runtime/imul8x8r16.s index fe939f668..fe08c855d 100644 --- a/libsrc/runtime/imul8x8r16.s +++ b/libsrc/runtime/imul8x8r16.s @@ -24,13 +24,17 @@ imul8x8r16: sta ptr3 imul8x8r16m: +; Extend sign of Left-Hand Side + lda #$7f + cmp ptr3 + adc #$80 + sta ptr3+1 + +; Clear .XY accumulator + ldy #<$0000 ldx #>$0000 - bit ptr3 - bpl @L7 - dex -@L7: stx ptr3+1 ; Extend sign of Left-Hand Side - ldy #<$0000 ; Clear .XY accumulator - ldx #>$0000 + +; Check the multiplier sign. lda ptr1 bpl PosStart From 7f7db01e257be7215430f5eaaa95842f96e3f949 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 9 Nov 2019 22:23:46 +0100 Subject: [PATCH 1206/2161] Fixed typos --- doc/funcref.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 030c726cc..6b39ad5e4 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -1360,8 +1360,8 @@ used in presence of a prototype. <tag/Function/Test a condition and possibly abort. <tag/Header/<tt/<ref id="assert.h" name="assert.h">/ <tag/Declaration/<tt/void assert (int cond);/ -<tag/Description/<tt/assert/ is a macro that expands to a <tt/id/ -statement. If the condition evaluates t zero (false), assert prints a message +<tag/Description/<tt/assert/ is a macro that expands to an <tt/id/ +statement. If the condition evaluates to zero (false), assert prints a message on stderr and aborts the program. <tag/Notes/<itemize> <item>The function is actually a macro. From ac4866c027b881b9cde2b4195cac0988eb3ca411 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 10 Nov 2019 12:46:01 -0500 Subject: [PATCH 1207/2161] Made assert() send SIGABRT when an assertion fails. A signal handler can catch it, and do anything needed to make stderr work. --- doc/funcref.sgml | 28 +++++++++++++++------------- libsrc/common/_afailed.c | 7 +++---- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 6b39ad5e4..314c57d89 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -1,4 +1,4 @@ -<!doctype linuxdoc system> <!-- -*- text-mode -*- --> +<!doctype linuxdoc system> <article> <title>cc65 function reference @@ -1316,11 +1316,11 @@ disabled. <quote> <descrip> -<tag/Function/Terminates a program abnormally. +<tag/Function/Terminate a program abnormally. <tag/Header/<tt/<ref id="stdlib.h" name="stdlib.h">/ <tag/Declaration/<tt/void abort (void);/ -<tag/Description/<tt/abort/ raises <tt/SIGABRT/, writes a termination message -on stderr, then terminates the program with an exit code of 3. +<tag/Description/<tt/abort()/ raises <tt/SIGABRT/, writes a termination message +on <tt/stderr/, then terminates the program with an exit code of 3. <tag/Availability/ISO 9899 <tag/See also/ <ref id="assert" name="assert">, @@ -1357,19 +1357,20 @@ used in presence of a prototype. <quote> <descrip> -<tag/Function/Test a condition and possibly abort. +<tag/Function/Test a condition, and possibly abort. <tag/Header/<tt/<ref id="assert.h" name="assert.h">/ <tag/Declaration/<tt/void assert (int cond);/ -<tag/Description/<tt/assert/ is a macro that expands to an <tt/id/ -statement. If the condition evaluates to zero (false), assert prints a message -on stderr and aborts the program. +<tag/Description/<tt/assert()/ is a macro that expands to an <tt/if/ statement. +If the condition evaluates to zero (false), <tt/assert()/ raises <tt/SIGABRT/, +prints a message on <tt/stderr/, then exits the program with an exit code of 2. <tag/Notes/<itemize> <item>The function is actually a macro. </itemize> <tag/Availability/ISO 9899 <tag/See also/ <ref id="abort" name="abort">, -<ref id="exit" name="exit"> +<ref id="exit" name="exit">, +<ref id="raise" name="raise"> <tag/Example/None. </descrip> </quote> @@ -5820,18 +5821,19 @@ calling convention. <tag/Function/Send a signal to the executing program. <tag/Header/<tt/<ref id="signal.h" name="signal.h">/ <tag/Declaration/<tt/int __fastcall__ raise (int sig);/ -<tag/Description/<tt/raise/ sends the given signal to the program. If the +<tag/Description/<tt/raise()/ sends the given signal to the program. If the program has installed a signal handler for the signal, this signal handler will be executed. If no handler has been installed, the default action for the raised signal will be taken. The function returns zero on success, -nonzero otherwise. +non-zero otherwise. <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 function is available only as a fastcall function, +so it may be used only in the presence of a prototype. </itemize> <tag/Availability/ISO 9899 <tag/See also/ <ref id="abort" name="abort">, +<ref id="assert" name="assert">, <ref id="signal" name="signal"> <tag/Example/None. </descrip> diff --git a/libsrc/common/_afailed.c b/libsrc/common/_afailed.c index 7c6df4a2c..ed93fc12d 100644 --- a/libsrc/common/_afailed.c +++ b/libsrc/common/_afailed.c @@ -2,11 +2,12 @@ ** _afailed.c ** ** 1998-06-06, Ullrich von Bassewitz -** 2015-03-13, Greg King +** 2019-11-10, Greg King */ +#include <signal.h> #include <stdio.h> #include <stdlib.h> @@ -14,9 +15,7 @@ void __fastcall__ _afailed (char* file, unsigned line) { + raise (SIGABRT); fprintf (stderr, "ASSERTION FAILED IN %s(%u)\n", file, line); exit (2); } - - - From 659d1729eb4e8192f3ff76a8813d8944b4c3cb40 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 12 Nov 2019 11:23:23 +0100 Subject: [PATCH 1208/2161] Fixed exit code #974 --- test/ref/yacc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ref/yacc.c b/test/ref/yacc.c index f2c3e2a58..776e4f93d 100644 --- a/test/ref/yacc.c +++ b/test/ref/yacc.c @@ -409,7 +409,7 @@ yylook() if(testbreak==5) { fprintf(yyout,"yylook: error, aborted after 5 loops\n"); - exit(0); + exit(EXIT_FAILURE); } testbreak++; From 4dda5d2173928271dd3d8b506b493e55088819c0 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 12 Nov 2019 11:57:38 -0500 Subject: [PATCH 1209/2161] Changed a "See also" link in the abort() and assert() descriptions from raise() to signal(). Programmers might want to use signal() to catch the SIGABRT that's sent by abort() and assert(). --- doc/funcref.sgml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 314c57d89..72a44c7b6 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -1325,7 +1325,7 @@ on <tt/stderr/, then terminates the program with an exit code of 3. <tag/See also/ <ref id="assert" name="assert">, <ref id="exit" name="exit">, -<ref id="raise" name="raise"> +<ref id="signal" name="signal"> <tag/Example/None. </descrip> </quote> @@ -1370,7 +1370,7 @@ prints a message on <tt/stderr/, then exits the program with an exit code of 2. <tag/See also/ <ref id="abort" name="abort">, <ref id="exit" name="exit">, -<ref id="raise" name="raise"> +<ref id="signal" name="signal"> <tag/Example/None. </descrip> </quote> @@ -6656,6 +6656,7 @@ be used in presence of a prototype. <tag/Availability/ISO 9899 <tag/See also/ <ref id="abort" name="abort">, +<ref id="assert" name="assert">, <ref id="raise" name="raise"> <tag/Example/None. </descrip> From d78133e1f00be19929ca6ee920c30f782c502e8b Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 16 Nov 2019 13:11:40 -0500 Subject: [PATCH 1210/2161] Updated cx16 to match the Commander X16 ROMs and emulator, release 34. --- asminc/cbm_kernal.inc | 4 +- asminc/cx16.inc | 87 ++++++++----- cfg/cx16-asm.cfg | 3 +- cfg/cx16-bank.cfg | 2 +- cfg/cx16.cfg | 2 +- doc/cx16.sgml | 50 ++++--- include/cx16.h | 23 +++- libsrc/cx16/break.s | 21 ++- libsrc/cx16/conio.s | 9 -- libsrc/cx16/cpeekc.s | 2 +- libsrc/cx16/cpeekrevers.s | 2 +- libsrc/cx16/cputc.s | 4 +- libsrc/cx16/crt0.s | 22 ++-- libsrc/cx16/devnum.s | 8 -- libsrc/cx16/exec.c | 122 ++++++++++++++++++ libsrc/cx16/execvars.s | 16 +++ libsrc/cx16/filevars.s | 39 ++++++ libsrc/cx16/getdevice.s | 67 ++++++++++ libsrc/cx16/gotox.s | 13 ++ libsrc/cx16/gotoxy.s | 18 +++ libsrc/cx16/gotoy.s | 13 ++ libsrc/cx16/joy/{cx16-stdjoy.s => cx16-std.s} | 76 ++++++----- libsrc/cx16/joy_stat_stddrv.s | 7 +- libsrc/cx16/joy_stddrv.s | 4 +- libsrc/cx16/joyref.s | 20 +++ libsrc/cx16/kbhit.s | 6 +- libsrc/cx16/kernal.s | 5 +- libsrc/cx16/libref.s | 4 +- libsrc/cx16/mainargs.s | 8 +- libsrc/cx16/set_tv.s | 16 +-- libsrc/cx16/status.s | 16 ++- libsrc/cx16/tgi_stat_stddrv.s | 11 ++ libsrc/cx16/tgi_stddrv.s | 13 ++ libsrc/cx16/videomode.s | 44 ++++--- libsrc/cx16/waitvsync.s | 2 +- libsrc/cx16/wherex.s | 15 +++ libsrc/cx16/wherey.s | 15 +++ 37 files changed, 607 insertions(+), 182 deletions(-) delete mode 100644 libsrc/cx16/conio.s delete mode 100644 libsrc/cx16/devnum.s create mode 100644 libsrc/cx16/exec.c create mode 100644 libsrc/cx16/execvars.s create mode 100644 libsrc/cx16/filevars.s create mode 100644 libsrc/cx16/getdevice.s create mode 100644 libsrc/cx16/gotox.s create mode 100644 libsrc/cx16/gotoxy.s create mode 100644 libsrc/cx16/gotoy.s rename libsrc/cx16/joy/{cx16-stdjoy.s => cx16-std.s} (58%) create mode 100644 libsrc/cx16/joyref.s create mode 100644 libsrc/cx16/tgi_stat_stddrv.s create mode 100644 libsrc/cx16/tgi_stddrv.s create mode 100644 libsrc/cx16/wherex.s create mode 100644 libsrc/cx16/wherey.s diff --git a/asminc/cbm_kernal.inc b/asminc/cbm_kernal.inc index 6e1e1604b..a38836ceb 100644 --- a/asminc/cbm_kernal.inc +++ b/asminc/cbm_kernal.inc @@ -7,18 +7,20 @@ .if .def(__CX16__) ; CX16 extended jump table GETJOY := $FF06 + MOUSE := $FF09 + SCRMOD := $FF5F .endif .if .def(__C128__) ; C128 extended jump table C64MODE := $FF4D + SWAPPER := $FF5F SETBNK := $FF68 .endif .if .def(__C128__) || .def(__CX16__) ; Extended jump table CLSALL := $FF4A - SWAPPER := $FF5F JSRFAR := $FF6E INDFET := $FF74 INDSTA := $FF77 diff --git a/asminc/cx16.inc b/asminc/cx16.inc index 5b46908d9..1c22c99b1 100644 --- a/asminc/cx16.inc +++ b/asminc/cx16.inc @@ -44,42 +44,55 @@ ; --------------------------------------------------------------------------- ; Zero page -; BASIC -VARTAB := $2D ; Pointer to start of BASIC variables -MEMSIZE := $37 ; Pointer to highest BASIC RAM location (+1) -TXTPTR := $7A ; Pointer into BASIC source code - ; Kernal -IN_DEV := $99 ; Current input device number -OUT_DEV := $9A ; Current output device number -IMPARM := $9B ; Pointer for PRIMM function -TIME := $A0 ; 60 Hz. clock -FNAM_LEN := $B7 ; Length of filename -SECADR := $B9 ; Secondary address -DEVNUM := $BA ; Device number -FNAM := $BB ; Pointer to filename -KEY_COUNT := $C6 ; Number of keys in input buffer -RVS := $C7 ; Reverse flag -CURS_FLAG := $CC ; 1 = cursor off -CURS_BLINK := $CD ; Blink counter -CURS_CHAR := $CE ; Character under the cursor -CURS_STATE := $CF ; Cursor blink state -SCREEN_PTR := $D1 ; Pointer to current row on text screen (16 bits) -CURS_X := $D3 ; Cursor column -CURS_Y := $D6 ; Cursor row -LLEN := $D9 ; Line length -NLINES := $DA ; Number of screen lines -JOY1 := $EF ; 3 bytes of NES/SNES gamepad data -JOY2 := $F2 -FREKZP := $FB ; Five unused bytes +FNAM := $84 ; Pointer to filename +KTEMP2 := $86 ; 2 bytes for temporary storage +SCREEN_PTR := $88 ; Pointer to current row on text screen (16 bits) +IMPARM := $8A ; Pointer for PRIMM function + +; BASIC +TXTPTR := $EE ; Pointer into BASIC source code ; Page two -BASIC_BUF := $200 ; Location of command-line -BASIC_BUF_LEN = 89 ; Maximum length of command-line +BASIC_BUF := $0200 ; Location of command-line +BASIC_BUF_LEN = 81 ; Maximum length of command-line -CHARCOLOR := $286 -CURS_COLOR := $287 ; Color under the cursor +CURS_COLOR := $027E ; Color under the cursor +CHARCOLOR := $0286 ; Cursor's color nybbles (high: background, low: foreground) +STATUS := $0287 ; Status from previous I/O operation +IN_DEV := $028E ; Current input device number +OUT_DEV := $028F ; Current output device number +TIME := $0292 ; 60 Hz. clock (3 bytes, big-endian) +FNAM_LEN := $0298 ; Length of filename +SECADR := $029A ; Secondary address +DEVNUM := $029B ; Device number +KEY_COUNT := $029E ; Number of keys in input buffer +RVS := $029F ; Reverse flag +CURS_FLAG := $02A3 ; 1 = cursor off +CURS_BLINK := $02A4 ; Blink counter +CURS_CHAR := $02A5 ; Character under the cursor +CURS_STATE := $02A6 ; Cursor blink state +CURS_X := $02A8 ; Cursor column +CURS_Y := $02AB ; Cursor row +LLEN := $02AE ; Line length +NLINES := $02AF ; Number of screen lines +JOY1 := $02BC ; 3 bytes of NES/SNES gamepad data +JOY2 := $02BF + +; BASIC +VARTAB := $02DD ; Pointer to start of BASIC variables +MEMSIZE := $02E5 ; Pointer to highest BASIC RAM location (+1) + +; Kernal mouse +MSEPAR := $0371 ; mouse: $8x=sprite on, 1/2: scale +MOUSEL := $0372 ; min. x co-ordinate +MOUSER := $0374 ; max. x co-ordinate +MOUSET := $0376 ; min. y co-ordinate +MOUSEB := $0378 ; max. y co-ordinate +MOUSEX := $037A ; x co-ordinate +MOUSEY := $037C ; y co-ordinate +MOUSEBT := $037E ; buttons (bits 2: middle, 1: right, 0: left) ; --------------------------------------------------------------------------- ; Vector and other locations @@ -122,6 +135,12 @@ NMIVec := $0318 INC8192 = 14 << 4 INC16384 = 15 << 4 .endenum + .enum ; Interrupt request flags + VERT_SYNC = %00000001 + RASTER = %00000010 + SPR_COLLIDED = %00000100 + UART_IRQ = %00001000 + .endenum ; Internal RAM and registers VRAM := $000000 .scope COMPOSER ; Display composer @@ -263,7 +282,7 @@ NMIVec := $0318 .endscope .endscope -; 65c22 +; 65C22 .struct VIA1 ; Versatile Interface Adapter .org $9F60 PRB .byte ; ROM bank, IEC (Port Register B) @@ -281,10 +300,10 @@ NMIVec := $0318 PRA2 .byte ; RAM bank (Port Register A without handshaking) .endstruct -; 65c22 +; 65C22 .struct VIA2 .org $9F70 - PRB .byte + PRB .byte ; Mouse communication ? PRA .byte ; NES controller communication DDRB .byte DDRA .byte diff --git a/cfg/cx16-asm.cfg b/cfg/cx16-asm.cfg index 53f6da176..4228f6da5 100644 --- a/cfg/cx16-asm.cfg +++ b/cfg/cx16-asm.cfg @@ -6,12 +6,13 @@ SYMBOLS { __HIMEM__: type = weak, value = $9F00; } MEMORY { - ZP: file = "", start = $0004, size = $0090 - $0004, define = yes; + ZP: file = "", start = $0002, size = $0080 - $0002, define = yes; LOADADDR: file = %O, start = %S - 2, size = $0002; MAIN: file = %O, start = %S, size = __HIMEM__ - %S; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = MAIN, type = ro, optional = yes; LOWCODE: load = MAIN, type = ro, optional = yes; diff --git a/cfg/cx16-bank.cfg b/cfg/cx16-bank.cfg index 52438fbac..ff5dded3d 100644 --- a/cfg/cx16-bank.cfg +++ b/cfg/cx16-bank.cfg @@ -11,7 +11,7 @@ SYMBOLS { __BANKRAMSIZE__: type = weak, value = $2000; # 8K banked RAM } MEMORY { - ZP: file = "", define = yes, start = $0004, size = $0090 - $0004; + ZP: file = "", define = yes, start = $0002, size = $0080 - $0002; 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 = __HIMEM__ - __HEADER_LAST__; diff --git a/cfg/cx16.cfg b/cfg/cx16.cfg index f912e0f83..c72f6c35d 100644 --- a/cfg/cx16.cfg +++ b/cfg/cx16.cfg @@ -8,7 +8,7 @@ SYMBOLS { __HIMEM__: type = weak, value = $9F00; } MEMORY { - ZP: file = "", define = yes, start = $0004, size = $0090 - $0004; + ZP: file = "", define = yes, start = $0002, size = $0080 - $0002; 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 = __HIMEM__ - __HEADER_LAST__; diff --git a/doc/cx16.sgml b/doc/cx16.sgml index b739e6a9d..16e43db99 100644 --- a/doc/cx16.sgml +++ b/doc/cx16.sgml @@ -17,14 +17,14 @@ compiler. <sect>Overview<p> The Commander X16 is a modern small computer with firmware that is based on -the ROMs in Commodore's VIC-20 and 64C. It has a couple of the I/O chips that -are in the VIC-20. +the ROMs in Commodore's VIC-20 and 64C. It has a couple of I/O chips +(WDC65C22 VIA) that are like the ones in the VIC-20. This file contains an overview of the CX16 run-time system as it comes with the -cc65 C compiler. It describes the memory layout, CX16-specific header files, +cc65 C compiler. It describes the memory layout, CX16-specific header files, available drivers, and any pitfalls specific to that platform. -Please note that CX16-specific functions just are mentioned here; they are +Please note that CX16-specific functions just are mentioned here; they might be described in detail in the separate <url url="funcref.html" name="function reference">. Even functions marked as "platform dependent" may be available on more than one platform. Please see the function reference for more @@ -35,19 +35,20 @@ information. <sect>Binary format<p> The standard binary output format generated by the linker for the CX16 target -is a machine language program with a one-line BASIC stub which calls the -machine language part via SYS. That means that a program can be loaded as a -BASIC program, and started with RUN. It is, of course, possible to change that -behaviour by using a modified start-up file and linker config. +is a machine language program that's prepended with a 16-bit load address and a +one-line BASIC stub which calls the machine language part via SYS. That means +that a program can be loaded as a BASIC program, and started with RUN. It is, +of course, possible to change that behaviour by using a modified program-header +file and linker config. <sect>Memory layout<p> -cc65-generated programs with the default setup run with the I/O area and the -Kernal ROM visible. That means that Kernal entry points can be called directly. -The usable memory ranges are $0800 - $9EFF and $A000 - -$BFFF. +cc65-generated programs with the default setup run with the I/O area, RAM bank +zero, and the Kernal ROM visible. That means that Kernal entry points can be +called directly. The usable memory ranges are $0800 - $9EFF and +$A000 - $BFFF. Special locations: @@ -76,6 +77,9 @@ The ld65 linker comes with a default config. file for the Commander X16, which is used via <tt/-t cx16/. The cx16 package comes with additional secondary linker config. files which are used via <tt/-t cx16 -C <configfile>/. +Those files use 126 bytes in the zero page. (The rest of page zero is reserved +for Kernal and BASIC.) + <sect1>Default config. file (<tt/cx16.cfg/)<p> @@ -138,6 +142,8 @@ url="funcref.html" name="function reference"> for declarations and usage. <item>get_ostype() <item>set_tv() <item>videomode() +<item>vpeek() +<item>vpoke() <item>waitvsync() </itemize> @@ -157,6 +163,7 @@ declarations and usage. <item>cbm_k_ckout() <item>cbm_k_close() <item>cbm_k_clrch() +<item>cbm_k_getin() <item>cbm_k_load() <item>cbm_k_open() <item>cbm_k_readst() @@ -217,13 +224,13 @@ No extended memory drivers are available currently for the CX16. <sect1>Joystick drivers<p> The default drivers, <tt/joy_stddrv (joy_static_stddrv)/, -point to <tt/cX16-stdjoy.joy (cx16_stdjoy_joy)/. +point to <tt/cX16-std.joy (cx16_std_joy)/. <descrip> - <tag><tt/cX16-stdjoy.joy (cX16_stdjoy_joy)/</tag> - Supports up to two NES and SNES controllers connected to the joystick ports + <tag><tt/cX16-std.joy (cX16_std_joy)/</tag> + Supports up to two NES (and SNES) controllers connected to the joystick ports of the CX16. It reads the four directions, and the A, B, Select, and Start - buttons. Button A is the primary fire button. + buttons. Buttons A and B are the primary and secondary fire buttons. </descrip><p> @@ -248,9 +255,16 @@ any time. Some changes could make old programs fail to work. <sect>Other hints<p> +<sect1>STOP and RUN codes<p> + +The <tt/Esc/ key acts as Commodore's <tt/STOP/ key -- or, you can press the +<tt/Ctrl/ key and the <tt/C/ key together. Pressing the <tt/Shift/ and the +<tt/Esc/ keys together will type Commodore's <tt/RUN/ key. + + <sect1>Escape code<p> -For an Esc, press <tt/Ctrl/ and the <tt/[/ key. +For an <tt/Esc/, press the <tt/Ctrl/ key and the <tt/[/ key together. <sect1>Passing arguments to the program<p> @@ -274,7 +288,7 @@ supported directly by BASIC, the following syntax was chosen: <sect1>Program return code<p> -The program return code (low byte) is passed back to BASIC by use of the +The program return code (low byte) is passed back to BASIC by the use of its <tt/ST/ variable. diff --git a/include/cx16.h b/include/cx16.h index a2f52850a..a6f1b78f6 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -100,6 +100,9 @@ #define JOY_FIRE2_MASK JOY_BTN_2_MASK #define JOY_FIRE2(v) ((v) & JOY_FIRE2_MASK) +/* Additional mouse button mask */ +#define MOUSE_BTN_MIDDLE 0x02 + /* get_tv() return codes ** set_tv() argument codes */ @@ -113,10 +116,12 @@ #define TV_RGB2 7 /* Video mode defines */ -#define VIDEOMODE_40x30 40u -#define VIDEOMODE_80x60 80u +#define VIDEOMODE_40x30 0x00 +#define VIDEOMODE_80x60 0x02 #define VIDEOMODE_40COL VIDEOMODE_40x30 #define VIDEOMODE_80COL VIDEOMODE_80x60 +#define VIDEOMODE_320x240 0x80 +#define VIDEOMODE_SWAP (-1) /* Define hardware */ @@ -157,7 +162,7 @@ struct __emul { /* The addresses of the static drivers */ -extern void cx16_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ +extern void cx16_std_joy[]; /* Referred to by joy_static_stddrv[] */ @@ -174,14 +179,20 @@ signed char get_ostype (void); ** Positive -- release build */ +unsigned char get_tv (void); +/* Return the video type that the machine is using. +** Return a TV_xx constant. +*/ + void __fastcall__ set_tv (unsigned char type); /* Set the video type that the machine will use. ** Call with a TV_xx constant. */ -unsigned char __fastcall__ videomode (unsigned char mode); -/* Set the video mode, return the old mode. Call with one of the VIDEOMODE_xx -** constants. +signed char __fastcall__ videomode (signed char mode); +/* Set the video mode, return the old mode. +** Return -1 if Mode isn't valid. +** Call with one of the VIDEOMODE_xx constants. */ unsigned char __fastcall__ vpeek (unsigned long addr); diff --git a/libsrc/cx16/break.s b/libsrc/cx16/break.s index ec569b9a7..6c79c903d 100644 --- a/libsrc/cx16/break.s +++ b/libsrc/cx16/break.s @@ -1,6 +1,6 @@ ; ; 1998-09-27, Ullrich von Bassewitz -; 2019-09-08, Greg King +; 2019-11-06, Greg King ; ; void __fastcall__ set_brk (unsigned Addr); ; void reset_brk (void); @@ -30,6 +30,7 @@ uservec: jmp $FFFF ; Patched at runtime .code ; Set the break vector + .proc _set_brk sta uservec+1 @@ -40,9 +41,9 @@ uservec: jmp $FFFF ; Patched at runtime bne L1 ; Jump if we installed the handler already lda BRKVec + ldx BRKVec+1 sta oldvec - lda BRKVec+1 - sta oldvec+1 ; Save the old vector + stx oldvec+1 ; Save the old vector L1: lda #<brk_handler ; Set the break vector to our routine ldx #>brk_handler @@ -54,6 +55,7 @@ L1: lda #<brk_handler ; Set the break vector to our routine ; Reset the break vector + .proc _reset_brk lda oldvec @@ -61,15 +63,15 @@ L1: lda #<brk_handler ; Set the break vector to our routine beq @L9 ; Jump if vector not installed sta BRKVec stx BRKVec+1 + lda #$00 sta oldvec ; Clear the old vector - stx oldvec+1 + sta oldvec+1 @L9: rts .endproc - ; Break handler, called if a break occurs .proc brk_handler @@ -81,14 +83,13 @@ L1: lda #<brk_handler ; Set the break vector to our routine pla sta _brk_a pla - and #$EF ; Clear break bit sta _brk_sr pla ; PC low sec - sbc #2 ; Point to start of brk + sbc #<$0002 ; Point to start of BRK sta _brk_pc pla ; PC high - sbc #0 + sbc #>$0002 sta _brk_pc+1 jsr uservec ; Call the user's routine @@ -99,11 +100,9 @@ L1: lda #<brk_handler ; Set the break vector to our routine pha lda _brk_sr pha - ldx _brk_x ldy _brk_y + ldx _brk_x lda _brk_a rti ; Jump back... .endproc - - diff --git a/libsrc/cx16/conio.s b/libsrc/cx16/conio.s deleted file mode 100644 index e760af21c..000000000 --- a/libsrc/cx16/conio.s +++ /dev/null @@ -1,9 +0,0 @@ -; -; 2019-09-23, Greg King -; -; Low-level stuff for screen output/console input -; - - .exportzp CURS_X, CURS_Y - - .include "cx16.inc" diff --git a/libsrc/cx16/cpeekc.s b/libsrc/cx16/cpeekc.s index 2f02623bf..f7a7d2081 100644 --- a/libsrc/cx16/cpeekc.s +++ b/libsrc/cx16/cpeekc.s @@ -19,7 +19,7 @@ _cpeekc: sta VERA::ADDR+1 ; set row number stz VERA::ADDR+2 lda CURS_X ; get character column - asl a + asl a ; each character has two bytes sta VERA::ADDR lda VERA::DATA0 ; get screen code plp diff --git a/libsrc/cx16/cpeekrevers.s b/libsrc/cx16/cpeekrevers.s index d67dd2956..15131d348 100644 --- a/libsrc/cx16/cpeekrevers.s +++ b/libsrc/cx16/cpeekrevers.s @@ -21,7 +21,7 @@ _cpeekrevers: sta VERA::ADDR+1 ; set row number stz VERA::ADDR+2 lda CURS_X ; get character column - asl a + asl a ; each character has two bytes sta VERA::ADDR lda VERA::DATA0 ; get screen code plp diff --git a/libsrc/cx16/cputc.s b/libsrc/cx16/cputc.s index cf0a5fa22..11c4f5782 100644 --- a/libsrc/cx16/cputc.s +++ b/libsrc/cx16/cputc.s @@ -78,7 +78,7 @@ plot: ldy CURS_X ; Write one screen-code and color to the video RAM without doing anything else. -; Return the x position in Y. +; Return the x position in .Y . putchar: ora RVS ; Set revers bit @@ -90,7 +90,7 @@ putchar: sta VERA::ADDR+2 ldy CURS_X ; Get character column tya - asl a + asl a ; Each character has two bytes sta VERA::ADDR stx VERA::DATA0 lda CHARCOLOR diff --git a/libsrc/cx16/crt0.s b/libsrc/cx16/crt0.s index 873fd706f..bfb4de10d 100644 --- a/libsrc/cx16/crt0.s +++ b/libsrc/cx16/crt0.s @@ -9,7 +9,6 @@ .import zerobss, callmain .import CHROUT .import __MAIN_START__, __MAIN_SIZE__ ; Linker-generated - .importzp ST .include "zeropage.inc" .include "cx16.inc" @@ -36,11 +35,18 @@ Start: tsx jsr callmain -; Back from main() [this is also the exit() entry]. Run the module destructors. +; Back from main() [this is also the exit() entry]. + +_exit: +; Put the program return code into BASIC's status variable. + + sta STATUS + +; Run the module destructors. -_exit: pha ; Save the return code on stack jsr donelib +.if 0 ; We no longer need to preserve zero-page space for cc65's variables. ; Copy back the zero-page stuff. ldx #zpspace-1 @@ -48,11 +54,7 @@ L2: lda zpsave,x sta sp,x dex bpl L2 - -; Place the program return code into BASIC's status variable. - - pla - sta ST +.endif ; Restore the system stuff. @@ -88,6 +90,7 @@ init: lda #$00 ; Choose RAM bank zero sta VIA1::PRA2 +.if 0 ; We no longer need to preserve zero-page space for cc65's variables. ; Save the zero-page locations that we need. ldx #zpspace-1 @@ -95,6 +98,7 @@ L1: lda sp,x sta zpsave,x dex bpl L1 +.endif ; Set up the stack. @@ -121,4 +125,6 @@ L1: lda sp,x ramsave: .res 1 spsave: .res 1 +.if 0 zpsave: .res zpspace +.endif diff --git a/libsrc/cx16/devnum.s b/libsrc/cx16/devnum.s deleted file mode 100644 index 6a59d6ecd..000000000 --- a/libsrc/cx16/devnum.s +++ /dev/null @@ -1,8 +0,0 @@ -; -; 2010-02-14, Oliver Schmidt -; 2019-09-08, Greg King -; - - .include "cx16.inc" - - .exportzp devnum := DEVNUM diff --git a/libsrc/cx16/exec.c b/libsrc/cx16/exec.c new file mode 100644 index 000000000..90af4e406 --- /dev/null +++ b/libsrc/cx16/exec.c @@ -0,0 +1,122 @@ +/* +** Program-chaining function for Commodore platforms. +** +** 2019-11-08, Greg King +** +** This function exploits the program-chaining feature in Commander X16 BASIC's ROM. +** +** CC65's CBM programs have a BASIC program stub. We start those programs by +** RUNning that stub; it SYSes to the Machine Language code. Normally, after +** the ML code exits, the BASIC ROM continues running the stub. But, it has +** no more statements; so, the program stops. +** +** This function puts the desired program's name and device number into a LOAD +** statement. Then, it points BASIC to that statement, so that the ROM will run +** that statement after this program quits. The ROM will load the next program, +** and will execute it (because the LOAD will be seen in a running program). +*/ + +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <device.h> + + +/* The struct below is a line of BASIC code. It sits in the LOWCODE segment +** to make sure that it won't be hidden by a ROM when BASIC is re-enabled. +** The line is: +** 0 CLR:LOAD""+"" ,01 +** After this function has written into the line, it might look like this: +** 0 CLR:LOAD""+"program name" ,08 +** +** When BASIC's LOAD command asks the Kernal to load a file, it gives the +** Kernal a pointer to a file-name string. CC65's CBM programs use that +** pointer to give a copy of the program's name to main()'s argv[0] parameter. +** But, when BASIC uses a string literal that is in a program, it points +** directly to that literal -- in the models that don't use banked RAM +** (Pet/CBM, VIC-20, and 64). The literal is overwritten by the next program +** that is loaded. So, argv[0] would point to machine code. String operations +** create a new result string -- even when that operation changes nothing. The +** result is put in the string space at the top of BASIC's memory. So, the ""+ +** in this BASIC line guarantees that argv[0] will get a name from a safe place. +*/ +#pragma data-name(push, "LOWCODE") +static struct line { + const char end_of_line; /* fake previous line */ + const struct line* const next; + const unsigned line_num; + const char CLR_token, colon, LOAD_token, quotes[2], add_token, quote; + char name[21]; + const char comma; + char unit[3]; +} basic = { + '\0', &basic + 1, /* high byte of link must be non-zero */ + 0, 0x9C, ':', 0x93, "\"\"", 0xAA, '\"', + "\" ", /* format: "123:1234567890123456\"" */ + ',', "01" +}; +#pragma data-name(pop) + +/* These values are platform-specific. */ +extern const void* vartab; /* points to BASIC program variables */ +extern const void* memsize; /* points to top of BASIC RAM */ +extern const struct line* txtptr; /* points to BASIC code */ +#pragma zpsym("txtptr") +extern char basbuf[]; /* BASIC's input buffer */ +extern void basbuf_len[]; +#pragma zpsym("basbuf_len") + + +int __fastcall__ exec (const char* progname, const char* cmdline) +{ + static int fd; + static unsigned char dv, n; + + /* Exclude devices that can't load files. */ + /* (Use hand optimization, to make smaller code.) */ + dv = getcurrentdevice (); + if (dv < 8 && __AX__ != 1 || __AX__ > 30) { + return _mappederrno (9); /* illegal device number */ + } + utoa (dv, basic.unit, 10); + + /* Don't try to run a program that doesn't exist. */ + fd = open (progname, O_RDONLY); + if (fd < 0) { + return _mappederrno (4); /* file not found */ + } + close (fd); + + n = 0; + do { + if ((basic.name[n] = progname[n]) == '\0') { + break; + } + } while (++n < 20); /* truncate long names */ + basic.name[n] = '\"'; + + /* cc65 program loads might extend beyond the end of the RAM that is allowed + ** for BASIC. Then, the LOAD statement would complain that it is "out of + ** memory". Some pointers that say where to put BASIC program variables + ** must be changed, so that we do not get that error. One pointer is + ** changed here; a BASIC CLR statement changes the others. + */ + vartab = (char*)memsize - 256; + + /* Build the next program's argument list. */ + basbuf[0] = 0x8F; /* REM token */ + basbuf[1] = '\0'; + if (cmdline != NULL) { + strncat (basbuf, cmdline, (size_t)basbuf_len - 2); + } + + /* Tell the ROM where to find that BASIC program. */ + txtptr = &basic; + + /* (The return code, in STATUS, will be destroyed by LOAD. + ** So, don't bother to set it here.) + */ + exit (__AX__); +} diff --git a/libsrc/cx16/execvars.s b/libsrc/cx16/execvars.s new file mode 100644 index 000000000..2df647a50 --- /dev/null +++ b/libsrc/cx16/execvars.s @@ -0,0 +1,16 @@ +; +; Platform-specific variables for the exec program-chaining function +; + + .include "cx16.inc" + +; exec() is written in C. +; Provide the spellings that the C compiler wants to use. + +.export _vartab := VARTAB +.export _memsize := MEMSIZE + +.exportzp _txtptr := TXTPTR + +.export _basbuf := BASIC_BUF +.exportzp _basbuf_len = BASIC_BUF_LEN diff --git a/libsrc/cx16/filevars.s b/libsrc/cx16/filevars.s new file mode 100644 index 000000000..f3fa64664 --- /dev/null +++ b/libsrc/cx16/filevars.s @@ -0,0 +1,39 @@ +; +; 2002-11-15, Ullrich von Bassewitz +; 2019-11-08, Greg King +; +; Variables used for CBM file I/O +; + + .export curunit + .constructor initcurunit, 30 + .destructor updatedevnum, 30 + + .include "cx16.inc" + + +.segment "INIT" + +curunit: + .res 1 + + +.segment "ONCE" + +.proc initcurunit + lda DEVNUM + bne L0 + lda #8 ; Default is SD card + sta DEVNUM +L0: sta curunit + rts +.endproc + + +.code + +.proc updatedevnum + lda curunit + sta DEVNUM + rts +.endproc diff --git a/libsrc/cx16/getdevice.s b/libsrc/cx16/getdevice.s new file mode 100644 index 000000000..9b554900f --- /dev/null +++ b/libsrc/cx16/getdevice.s @@ -0,0 +1,67 @@ +; +; 2012-09-04, Oliver Schmidt +; 2019-11-08, Greg King +; +; unsigned char getfirstdevice (void); +; unsigned char __fastcall__ getnextdevice (unsigned char device); +; + + .export _getfirstdevice + .export _getnextdevice + .import isdisk + .import opencmdchannel + .import closecmdchannel + .importzp tmp2 + + .include "cx16.inc" + +;------------------------------------------------------------------------------ +; getfirstdevice() + +_getfirstdevice: + lda #$FF + ; Fall through + +;------------------------------------------------------------------------------ +; getnextdevice() + +_getnextdevice: + tax +next: inx + cpx #$FF + beq done + +; [open|close]cmdchannel already call isdisk internally; but, they +; interpret a non-disk as a no-op, while we need to interpret it +; as an error here. + + jsr isdisk + bcs next + +; [open|close]cmdchannel don't call into the Kernal, at all, if they +; only [in|de]crement the reference count of the shared cmdchannel. +; Therefore, we need to initiate STATUS explicitly here. + + lda #$00 + sta STATUS + + stx tmp2 + jsr opencmdchannel + ldx tmp2 + jsr closecmdchannel + ldx tmp2 + +; As we had to reference ST above anyway, we can do so, as well, +; here too (instead of calling READST). + + lda STATUS + +; Either the Kernal calls above were successfull, or there was +; already a cmdchannel to the device open -- which is a pretty +; good indication of its existence. ;-) + + bmi next + +done: txa + ldx #$00 + rts diff --git a/libsrc/cx16/gotox.s b/libsrc/cx16/gotox.s new file mode 100644 index 000000000..1cd7c6931 --- /dev/null +++ b/libsrc/cx16/gotox.s @@ -0,0 +1,13 @@ +; +; 2019-11-06, Greg King +; +; void fastcall gotox (unsigned char x); +; + + .export _gotox + + .import plot + .include "cx16.inc" + +_gotox: sta CURS_X ; Set new position + jmp plot ; And activate it diff --git a/libsrc/cx16/gotoxy.s b/libsrc/cx16/gotoxy.s new file mode 100644 index 000000000..1c1b60e28 --- /dev/null +++ b/libsrc/cx16/gotoxy.s @@ -0,0 +1,18 @@ +; +; 2019-11-06, Greg King +; +; void fastcall gotoxy (unsigned char x, unsigned char y); +; + + .export gotoxy, _gotoxy + + .import popa, plot + .include "cx16.inc" + +gotoxy: jsr popa ; Get Y + +_gotoxy: + sta CURS_Y ; Set Y + jsr popa ; Get X + sta CURS_X ; Set X + jmp plot ; Set the cursor position diff --git a/libsrc/cx16/gotoy.s b/libsrc/cx16/gotoy.s new file mode 100644 index 000000000..487cfa793 --- /dev/null +++ b/libsrc/cx16/gotoy.s @@ -0,0 +1,13 @@ +; +; 2019-11-06, Greg King +; +; void gotoy (unsigned char y); +; + + .export _gotoy + + .import plot + .include "cx16.inc" + +_gotoy: sta CURS_Y ; Set the new position + jmp plot ; And activate it diff --git a/libsrc/cx16/joy/cx16-stdjoy.s b/libsrc/cx16/joy/cx16-std.s similarity index 58% rename from libsrc/cx16/joy/cx16-stdjoy.s rename to libsrc/cx16/joy/cx16-std.s index 8c7ddd2f2..b41c6606c 100644 --- a/libsrc/cx16/joy/cx16-stdjoy.s +++ b/libsrc/cx16/joy/cx16-std.s @@ -1,8 +1,8 @@ ; ; Standard joystick driver for the CX16. -; May be used multiple times when statically linked to the application. +; May be installed multiple times when statically linked to the application. ; -; 2019-09-23, Greg King +; 2019-11-15 Greg King ; .include "joy-kernel.inc" @@ -18,7 +18,7 @@ ; ------------------------------------------------------------------------ ; Header. Includes jump table - module_header _cx16_stdjoy_joy + module_header _cx16_std_joy ; Driver signature @@ -48,11 +48,10 @@ JOY_COUNT = 2 ; Number of joysticks we support .code ; ------------------------------------------------------------------------ -; INSTALL routine. Is called after the driver is loaded into memory. +; 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 a JOY_ERR_xx code in a/x. -; +; Must return a JOY_ERR_xx code in .XA . INSTALL: lda #<JOY_ERR_OK @@ -60,60 +59,67 @@ INSTALL: ; rts ; Run into UNINSTALL instead ; ------------------------------------------------------------------------ -; UNINSTALL routine. Is called before the driver is removed from memory. -; Can do clean-up or whatever. Must not return anything. -; +; UNINSTALL routine -- is called before the driver is removed from memory. +; Can do clean-up or whatever. Shouldn't return anything. UNINSTALL: rts ; ------------------------------------------------------------------------ -; COUNT: Return the total number of possible joysticks in a/x. -; +; COUNT: Return the total number of possible joysticks, in .XA . COUNT: lda #<JOY_COUNT ldx #>JOY_COUNT rts ; ------------------------------------------------------------------------ -; READ: Read a particular joystick passed in A. -; -; TODO: Find a way to report the SNES controller's extra four lines. -; +; READ: Read a particular joystick passed in .A . -READ: pha - jsr GETJOY - pla - bne pad2 +READ: php + bit #JOY_COUNT - $01 + sei + bnz pad2 ; Read game pad 1 -pad1: lda JOY1 + 1 +pad1: ldy JOY1 ; Allow JOY1 to be reread between interrupts + sty JOY1 + 2 + + lda JOY1 + 1 bit #%00001110 - beq nes1 - asl JOY1 ; Get SNES's B button + bze nes1 + + asl JOY1 + 2 ; Get SNES's B button ror a ; Put it next to the A button - asl JOY1 ; Drop SNES's Y button - asl a ; Get the B button - ror JOY1 + asl JOY1 + 2 ; Drop SNES's Y button + asl a ; Get back the B button + ror JOY1 + 2 asl a ; Get SNES's A button - ror JOY1 ; Make byte look like NES pad -nes1: lda JOY1 - eor #%11111111 ; We don't want the pad's negative logic + ror JOY1 + 2 ; Make byte look like NES pad + +nes1: lda JOY1 + 2 + plp + eor #%11111111 ; (The controllers use negative logic) rts ; Read game pad 2 -pad2: lda JOY2 + 1 +pad2: ldy JOY2 + sty JOY2 + 2 + + lda JOY2 + 1 bit #%00001110 - beq nes2 - asl JOY2 + bze nes2 + + asl JOY2 + 2 ror a - asl JOY2 + asl JOY2 + 2 asl a - ror JOY2 + ror JOY2 + 2 asl a - ror JOY2 -nes2: lda JOY2 + ror JOY2 + 2 + +nes2: lda JOY2 + 2 + plp eor #%11111111 rts diff --git a/libsrc/cx16/joy_stat_stddrv.s b/libsrc/cx16/joy_stat_stddrv.s index 0e1a3e94d..08cd2f951 100644 --- a/libsrc/cx16/joy_stat_stddrv.s +++ b/libsrc/cx16/joy_stat_stddrv.s @@ -1,10 +1,11 @@ ; ; Address of the static standard joystick driver ; -; 2019-09-19, Greg King +; 2019-11-10, Greg King ; ; const void joy_static_stddrv[]; ; - .import _cx16_stdjoy_joy - .export _joy_static_stddrv := _cx16_stdjoy_joy + .import _cx16_std_joy + + .export _joy_static_stddrv := _cx16_std_joy diff --git a/libsrc/cx16/joy_stddrv.s b/libsrc/cx16/joy_stddrv.s index 4edf9afc0..ff2f54de1 100644 --- a/libsrc/cx16/joy_stddrv.s +++ b/libsrc/cx16/joy_stddrv.s @@ -1,7 +1,7 @@ ; ; Name of the standard joystick driver ; -; 2019-09-19, Greg King +; 2019-11-10, Greg King ; ; const char joy_stddrv[]; ; @@ -10,4 +10,4 @@ .rodata -_joy_stddrv: .asciiz "cx16-stdjoy.joy" +_joy_stddrv: .asciiz "cx16-std.joy" diff --git a/libsrc/cx16/joyref.s b/libsrc/cx16/joyref.s new file mode 100644 index 000000000..fb21918c4 --- /dev/null +++ b/libsrc/cx16/joyref.s @@ -0,0 +1,20 @@ +; +; 2019-11-14, Greg King +; +; Link an interrupt handler if joysticks are used by a program. +; + + .interruptor joy_libref, 9 + + .include "cbm_kernal.inc" + .include "cx16.inc" + + +joy_libref: + lda VERA::IRQ_FLAGS + lsr a + bcc not_vsync + jsr GETJOY ; Bit-bang game controllers + clc ; Let other Jiffy handlers run +not_vsync: + rts diff --git a/libsrc/cx16/kbhit.s b/libsrc/cx16/kbhit.s index 8ceba64be..a73533e20 100644 --- a/libsrc/cx16/kbhit.s +++ b/libsrc/cx16/kbhit.s @@ -1,5 +1,5 @@ ; -; 2019-09-20, Greg King +; 2019-11-06, Greg King ; ; unsigned char kbhit (void); ; /* Returns non-zero (true) if a typed character is waiting. */ @@ -11,7 +11,7 @@ .proc _kbhit - ldx #>$0000 ; High byte of return lda KEY_COUNT ; Get number of characters - rts + tax ; High byte of return (only its zero/nonzero ... + rts ; ... state matters) .endproc diff --git a/libsrc/cx16/kernal.s b/libsrc/cx16/kernal.s index faf91385a..97443c824 100644 --- a/libsrc/cx16/kernal.s +++ b/libsrc/cx16/kernal.s @@ -1,5 +1,5 @@ ; -; 2019-09-22, Greg King +; 2019-11-05, Greg King ; ; CX16 Kernal functions ; @@ -7,9 +7,10 @@ .include "cbm_kernal.inc" .export GETJOY + .export MOUSE + .export SCRMOD .export CLSALL - .export SWAPPER .export JSRFAR .export INDFET .export INDSTA diff --git a/libsrc/cx16/libref.s b/libsrc/cx16/libref.s index 54ebb91d2..0d85c7cd8 100644 --- a/libsrc/cx16/libref.s +++ b/libsrc/cx16/libref.s @@ -1,10 +1,9 @@ ; ; 2013-05-31, Oliver Schmidt -; 2019-09-22, Greg King +; 2019-11-14, Greg King ; .export em_libref - .export joy_libref .export mouse_libref .export ser_libref .export tgi_libref @@ -12,7 +11,6 @@ .import _exit em_libref := _exit -joy_libref := _exit mouse_libref := _exit ser_libref := _exit tgi_libref := _exit diff --git a/libsrc/cx16/mainargs.s b/libsrc/cx16/mainargs.s index fe4a071c7..1764b5e20 100644 --- a/libsrc/cx16/mainargs.s +++ b/libsrc/cx16/mainargs.s @@ -33,7 +33,7 @@ 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 +; which may be reused after the startup code is run. .segment "ONCE" @@ -64,7 +64,7 @@ L2: lda BASIC_BUF,x bne L2 ldy #1 * 2 -; Find the next argument +; Find the next argument. next: lda BASIC_BUF,x beq done ; End of line reached @@ -74,7 +74,7 @@ next: lda BASIC_BUF,x ; 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 +; will check now for a quoted argument, in which case, we will have to skip this ; first character. found: cmp #'"' ; Is the argument quoted? @@ -95,7 +95,7 @@ setterm:sta term ; Set end of argument marker iny inc __argc ; Found another arg -; Search for the end of the argument +; Search for the end of the argument. argloop:lda BASIC_BUF,x beq done diff --git a/libsrc/cx16/set_tv.s b/libsrc/cx16/set_tv.s index 0cf49aff7..8b802f324 100644 --- a/libsrc/cx16/set_tv.s +++ b/libsrc/cx16/set_tv.s @@ -1,5 +1,5 @@ ; -; 2019-09-20, Greg King +; 2019-11-06, Greg King ; ; void __fastcall__ set_tv (unsigned char); ; /* Set the video mode the machine will use. */ @@ -12,20 +12,18 @@ .proc _set_tv php - pha sei ; Don't let interrupts interfere ; Point to the video output register. stz VERA::CTRL ; Use port 0 - lda #<VERA::COMPOSER::VIDEO - ldx #>VERA::COMPOSER::VIDEO - ldy #^VERA::COMPOSER::VIDEO - sta VERA::ADDR - stx VERA::ADDR+1 - sty VERA::ADDR+2 + ldx #<VERA::COMPOSER::VIDEO + ldy #>VERA::COMPOSER::VIDEO + stx VERA::ADDR + sty VERA::ADDR+1 + ldx #^VERA::COMPOSER::VIDEO + stx VERA::ADDR+2 - pla sta VERA::DATA0 plp ; Re-enable interrupts rts diff --git a/libsrc/cx16/status.s b/libsrc/cx16/status.s index 6292dc274..e3446637d 100644 --- a/libsrc/cx16/status.s +++ b/libsrc/cx16/status.s @@ -1,6 +1,16 @@ ; -; 2012-09-30, Oliver Schmidt -; 2019-09-08, Greg King +; 2019-11-05, Greg King ; - .exportzp ST := $90 ; IEC status byte + .export ST: zp + +.segment "EXTZP": zp + +; This is a temporary hack. + +; A zero-page copy of the IEC status byte. +; This is needed because the Commander X16's Kernal's status +; variable was moved out of the zero page. But, the common +; CBM file function modules import this as a zero-page variable. + +ST: .res 1 diff --git a/libsrc/cx16/tgi_stat_stddrv.s b/libsrc/cx16/tgi_stat_stddrv.s new file mode 100644 index 000000000..566a36393 --- /dev/null +++ b/libsrc/cx16/tgi_stat_stddrv.s @@ -0,0 +1,11 @@ +; +; Address of the static standard TGI driver +; +; 2019-11-06, Greg King +; +; const void tgi_static_stddrv[]; +; + + .import _cx16_640x4c_tgi + + .export _tgi_static_stddrv := _cx16_640x4c_tgi diff --git a/libsrc/cx16/tgi_stddrv.s b/libsrc/cx16/tgi_stddrv.s new file mode 100644 index 000000000..0f77e7340 --- /dev/null +++ b/libsrc/cx16/tgi_stddrv.s @@ -0,0 +1,13 @@ +; +; Name of the standard TGI driver +; +; 2019-11-06, Greg King +; +; const char tgi_stddrv[]; +; + + .export _tgi_stddrv + +.rodata + +_tgi_stddrv: .asciiz "cx16-640x4c.tgi" diff --git a/libsrc/cx16/videomode.s b/libsrc/cx16/videomode.s index 4582ec1bd..e3a777b8e 100644 --- a/libsrc/cx16/videomode.s +++ b/libsrc/cx16/videomode.s @@ -1,30 +1,44 @@ ; -; 2009-09-07, Ullrich von Bassewitz -; 2019-09-23, Greg King +; 2019-11-06, Greg King ; -; unsigned __fastcall__ videomode (unsigned Mode); -; /* Set the video mode, return the old mode. */ +; /* Video mode defines */ +; #define VIDEOMODE_40x30 0x00 +; #define VIDEOMODE_80x60 0x02 +; #define VIDEOMODE_320x240 0x80 +; #define VIDEOMODE_SWAP (-1) +; +; signed char __fastcall__ videomode (signed char Mode); +; /* Set the video mode, return the old mode. +; ** Return -1 if Mode isn't valid. +; ** Call with one of the VIDEOMODE_xx constants. +; */ ; .export _videomode - .import SWAPPER - .include "cx16.inc" + .import SCRMOD .proc _videomode - cmp LLEN ; Do we have this mode already? - beq @L9 + tax + clc ; (Get old mode) + jsr SCRMOD + pha + txa - lda LLEN ; Get current mode ... - pha ; ... and save it + sec ; (Set new mode) + jsr SCRMOD - jsr SWAPPER ; Toggle the mode + pla ; Get back old mode + bcs @L1 + ldx #>$0000 ; Clear high byte + rts - pla ; Get old mode into A +; The new mode is invalid. Go back to the old mode. Return -1. -; Done, old mode is in .A - -@L9: ldx #>$0000 ; Clear high byte +@L1: sec + jsr SCRMOD + lda #<-1 + tax rts .endproc diff --git a/libsrc/cx16/waitvsync.s b/libsrc/cx16/waitvsync.s index 3fb6354f0..09d01c6a1 100644 --- a/libsrc/cx16/waitvsync.s +++ b/libsrc/cx16/waitvsync.s @@ -3,7 +3,7 @@ ; ; void waitvsync (void); ; -; VERA's vertical sync. causes IRQs which increment the jiffy clock. +; VERA's vertical sync causes IRQs which increment the jiffy clock. ; .export _waitvsync diff --git a/libsrc/cx16/wherex.s b/libsrc/cx16/wherex.s new file mode 100644 index 000000000..56f423592 --- /dev/null +++ b/libsrc/cx16/wherex.s @@ -0,0 +1,15 @@ +; +; 2019-11-06, Greg King +; +; unsigned char wherex (void); +; + + .export _wherex + + .include "cx16.inc" + +.proc _wherex + lda CURS_X + ldx #>$0000 + rts +.endproc diff --git a/libsrc/cx16/wherey.s b/libsrc/cx16/wherey.s new file mode 100644 index 000000000..396a2d14e --- /dev/null +++ b/libsrc/cx16/wherey.s @@ -0,0 +1,15 @@ +; +; 2019-11-06, Greg King +; +; unsigned char wherey (void); +; + + .export _wherey + + .include "cx16.inc" + +.proc _wherey + lda CURS_Y + ldx #>$0000 + rts +.endproc From 5da525e0ea10987d9dbf1ad2ba5bad9548d23f59 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 16 Nov 2019 14:51:24 -0500 Subject: [PATCH 1211/2161] Added a standard mouse driver to the cx16 library. --- doc/cx16.sgml | 9 +- include/cx16.h | 9 +- libsrc/cx16/mcbdefault.s | 65 +++++++ libsrc/cx16/mou/cx16-std.s | 310 ++++++++++++++++++++++++++++++++ libsrc/cx16/mouse_stat_stddrv.s | 11 ++ libsrc/cx16/mouse_stddrv.s | 13 ++ 6 files changed, 415 insertions(+), 2 deletions(-) create mode 100644 libsrc/cx16/mcbdefault.s create mode 100644 libsrc/cx16/mou/cx16-std.s create mode 100644 libsrc/cx16/mouse_stat_stddrv.s create mode 100644 libsrc/cx16/mouse_stddrv.s diff --git a/doc/cx16.sgml b/doc/cx16.sgml index 16e43db99..7189e7157 100644 --- a/doc/cx16.sgml +++ b/doc/cx16.sgml @@ -236,7 +236,14 @@ point to <tt/cX16-std.joy (cx16_std_joy)/. <sect1>Mouse drivers<p> -No mouse drivers are available currently for the CX16. +The default drivers, <tt/mouse_stddrv (mouse_static_stddrv)/, +point to <tt/cX16-std.mou (cx16_std_mou)/. + +<descrip> + <tag><tt/cX16-std.mou (cX16_std_mou)/</tag> + Supports a standard 3-button mouse connected to the PS/2 mouse port of the + Commander X16. +</descrip><p> <sect1>RS232 device drivers<p> diff --git a/include/cx16.h b/include/cx16.h index a6f1b78f6..b465378a5 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -115,7 +115,7 @@ #define TV_NTSC_MONO 6 #define TV_RGB2 7 -/* Video mode defines */ +/* Video modes */ #define VIDEOMODE_40x30 0x00 #define VIDEOMODE_80x60 0x02 #define VIDEOMODE_40COL VIDEOMODE_40x30 @@ -123,6 +123,12 @@ #define VIDEOMODE_320x240 0x80 #define VIDEOMODE_SWAP (-1) +/* VERA's interrupt flags */ +#define VERA_IRQ_VSYNC 0b00000001 +#define VERA_IRQ_RASTER 0b00000010 +#define VERA_IRQ_SPR_COLL 0b00000100 +#define VERA_IRQ_UART 0b00001000 + /* Define hardware */ @@ -163,6 +169,7 @@ struct __emul { /* The addresses of the static drivers */ extern void cx16_std_joy[]; /* Referred to by joy_static_stddrv[] */ +extern void cx16_std_mou[]; /* Referred to by mouse_static_stddrv[] */ diff --git a/libsrc/cx16/mcbdefault.s b/libsrc/cx16/mcbdefault.s new file mode 100644 index 000000000..d817b9ae6 --- /dev/null +++ b/libsrc/cx16/mcbdefault.s @@ -0,0 +1,65 @@ +; +; Default mouse callbacks for the CX16 +; +; 2019-11-09, Greg King +; +; All functions in this module should be interrupt safe +; because they might be called from an interrupt handler. +; + + .export _mouse_def_callbacks + + .include "cbm_kernal.inc" + .include "cx16.inc" + +; -------------------------------------------------------------------------- +; Hide the mouse pointer. Always called with interrupts disabled. + +.code + +hide: ldx #$00 ; Don't change sprite's scale + lda #$00 ; Disable sprite + jmp MOUSE + +; -------------------------------------------------------------------------- +; Show the mouse pointer. Always called with interrupts disabled. + +show: ldx #$00 + lda #<-$01 ; Enable sprite + jmp MOUSE + +; -------------------------------------------------------------------------- +; Prepare to move the mouse pointer. Always called with interrupts disabled. + +prep: ; Fall through + +; -------------------------------------------------------------------------- +; Draw the mouse pointer. Always called with interrupts disabled. + +draw: ; Fall through + +; -------------------------------------------------------------------------- +; Move the mouse pointer X position to the value in .XA . Always called with +; interrupts disabled. + +movex: ; Already set by drivers + ; Fall through + +; -------------------------------------------------------------------------- +; Move the mouse pointer Y position to the value in .XA . Always called with +; interrupts disabled. + +movey: rts ; Already set by drivers + +; -------------------------------------------------------------------------- +; Callback structure + +.rodata + +_mouse_def_callbacks: + .addr hide + .addr show + .addr prep + .addr draw + .addr movex + .addr movey diff --git a/libsrc/cx16/mou/cx16-std.s b/libsrc/cx16/mou/cx16-std.s new file mode 100644 index 000000000..eb3f83167 --- /dev/null +++ b/libsrc/cx16/mou/cx16-std.s @@ -0,0 +1,310 @@ +; +; Driver for the Commander X16 Kernal's mouse driver. +; +; 2019-11-16, Greg King +; + + .include "zeropage.inc" + .include "mouse-kernel.inc" + .include "cx16.inc" + .include "cbm_kernal.inc" + + .macpack module + + +; ------------------------------------------------------------------------ +; Header. Includes jump table + + module_header _cx16_std_mou + +HEADER: + +; Driver signature + + .byte $6d, $6f, $75 ; ASCII "mou" + .byte MOUSE_API_VERSION ; Mouse driver API version number + +; Library reference + + .addr $0000 + +; Jump table + + .addr INSTALL + .addr UNINSTALL + .addr HIDE + .addr SHOW + .addr SETBOX + .addr GETBOX + .addr MOVE + .addr BUTTONS + .addr POS + .addr INFO + .addr IOCTL + .addr IRQ + +; Mouse driver flags + + .byte $00 ; Don't need interrupts + +; Callback table, set by the mouse kernel before INSTALL is called + +CHIDE: jmp $0000 ; Hide the cursor +CSHOW: jmp $0000 ; Show the cursor +CPREP: jmp $0000 ; Prepare to move the cursor +CDRAW: jmp $0000 ; Draw the cursor +CMOVEX: jmp $0000 ; Move the cursor to X coord +CMOVEY: jmp $0000 ; Move the cursor to Y coord + + +;---------------------------------------------------------------------------- +; Constants + +SCREEN_WIDTH = 640 - 1 ; (origin is zero) +SCREEN_HEIGHT = 480 - 1 + +;---------------------------------------------------------------------------- +; Global variables. + +.bss + +XPos := MOUSEX ; Current mouse position, X +YPos := MOUSEY ; Current mouse position, Y + +XMin := MOUSEL ; X1 value of bounding box +XMax := MOUSER ; X2 value of bounding box +YMin := MOUSET ; Y1 value of bounding box +YMax := MOUSEB ; Y2 value of bounding box +Box := XMin + +Buttons := MOUSEBT ; button status bits + +.rodata + +; Default values for above variables +; (We use ".proc" because we want to define both a label and a scope.) + +.proc DefBox + .word 0 ; XMin + .word SCREEN_WIDTH ; XMax + .word 0 ; YMin + .word SCREEN_HEIGHT ; YMax +.endproc + +; These button masks are compatible with the CBM 1351 and the CMD SmartMouse. + +ButtMask: + .byte %00000000 ; No buttons + .byte %00010000 ; Left + .byte %00000001 ; Right + .byte %00010001 ; Left, right + .byte %00000010 ; Middle + .byte %00010010 ; Left, middle + .byte %00000011 ; Middle, right + .byte %00010011 ; Left, middle, right + +.code + +;---------------------------------------------------------------------------- +; INSTALL routine. Is called after the driver is loaded into memory. +; If possible, check if the hardware is present. +; Must return a MOUSE_ERR_xx code in .XA . + +INSTALL: + +; Initialize variables. Just copy the default stuff over. + + ldx #.sizeof(DefBox) - 1 +@L1: lda DefBox,x + sta Box,x + dex + bpl @L1 + + ldx #$00 ; Don't change sprite's scale + lda #$01 ; Initiate and show sprite + jsr MOUSE + +; Be sure the mouse cursor is invisible, and at the default location. We +; need to do that here, because the mouse interrupt handler might not set +; the mouse position if it hasn't changed. + + sei + jsr CHIDE + lda XPos + ldx XPos+1 + jsr CMOVEX + lda YPos + ldx YPos+1 + jsr CMOVEY + cli + +; Done, return zero + + ldx #>MOUSE_ERR_OK + txa + rts + +;---------------------------------------------------------------------------- +; UNINSTALL routine -- is called before the driver is removed from memory. +; No return code required (the driver is removed from memory on return). + +UNINSTALL := HIDE ; Hide cursor on exit + +;---------------------------------------------------------------------------- +; HIDE routine -- is called to hide the mouse pointer. The mouse kernel manages +; a counter for calls to show/hide, and the driver entry point is called only +; if the mouse currently is visible, and should get hidden. For most drivers, +; no special action is required besides disabling the mouse cursor. +; No return code required. + +HIDE: jmp CHIDE + +;---------------------------------------------------------------------------- +; SHOW routine -- is called to show the mouse pointer. The mouse kernel manages +; a counter for calls to show/hide, and the driver entry point is called only +; if the mouse currently is hidden, and should become visible. For most drivers, +; no special action is required besides enabling the mouse cursor. +; No return code required. + +SHOW: jmp CSHOW + +;---------------------------------------------------------------------------- +; SETBOX: Set the mouse bounding box. The parameters are passed as they come +; from the C program, that is, a pointer to a mouse_box struct in .XA . +; No checks are done if the mouse is currently inside the box, that is the job +; of the caller. It is not necessary to validate the parameters, trust the +; caller, and save some code here. No return code required. + +SETBOX: sta ptr1 + stx ptr1+1 ; Save data pointer + + lda (ptr1) + ldy #$01 + + sei + sta XMin + lda (ptr1),y + sta YMin + iny + lda (ptr1),y + sta XMax + iny + lda (ptr1),y + sta YMax + cli + + rts + +;---------------------------------------------------------------------------- +; GETBOX: Return the mouse bounding box. The parameters are passed as they +; come from the C program, that is, a pointer to a mouse_box struct in .XA . + +GETBOX: sta ptr1 + stx ptr1+1 ; Save data pointer + + lda XMin + sta (ptr1) + ldy #$01 + lda YMin + sta (ptr1),y + iny + lda XMax + sta (ptr1),y + iny + lda YMax + sta (ptr1),y + rts + +;---------------------------------------------------------------------------- +; MOVE: Put the mouse at a new position. That position is passed as it comes +; from the C program, that is: X on the stack and Y in .XA . The C wrapper +; will remove the parameter from the stack, on return. +; No checks are done to see if the new position is valid (within +; the bounding box or the screen). No return code required. + +MOVE: sei ; No interrupts + + sta YPos + stx YPos+1 ; New Y position + jsr CMOVEY ; Set it + + ldy #$01 + lda (sp),y + sta XPos+1 + tax + dey + lda (sp),y + sta XPos ; New X position + jsr CMOVEX ; Move the cursor + + cli ; Allow interrupts + rts + +;---------------------------------------------------------------------------- +; BUTTONS: Return the CBM 1351 button mask in .XA . + +BUTTONS: + lda Buttons + and #%00000111 + tax + lda ButtMask,x + ldx #>$0000 + rts + +;---------------------------------------------------------------------------- +; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1. +; No return code required. + +POS: ldy #MOUSE_POS::XCOORD ; Structure offset + + sei ; Disable interrupts + lda XPos ; Transfer the position + sta (ptr1),y + lda XPos+1 + iny + sta (ptr1),y + lda YPos + iny + sta (ptr1),y + lda YPos+1 + cli ; Enable interrupts + + iny + sta (ptr1),y ; Store last byte + rts ; Done + +;---------------------------------------------------------------------------- +; INFO: Returns mouse position and current button mask in the MOUSE_INFO +; struct pointed to by ptr1. No return code required. +; +; We're cheating here to keep the code smaller: The first fields of the +; mouse_info struct are identical to the mouse_pos struct; so, we just will +; call mouse_pos to initialize the struct pointer, and fill the position +; fields. + +INFO: jsr POS + +; Fill in the button state + + jsr BUTTONS ; Will not touch ptr1 + ldy #MOUSE_INFO::BUTTONS + sta (ptr1),y + rts + +;---------------------------------------------------------------------------- +; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl +; specific data in ptr1, and the ioctl code in A. +; Must return an error code in .XA . +; + +IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioctls, for now + ldx #>MOUSE_ERR_INV_IOCTL +; rts ; Fall through + +;---------------------------------------------------------------------------- +; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context +; (so be careful). The routine MUST return carry set if the interrupt has been +; 'handled' -- which means that the interrupt source is gone. Otherwise, it +; MUST return carry clear. + +IRQ: rts ; Kernal ROM does this routine's job diff --git a/libsrc/cx16/mouse_stat_stddrv.s b/libsrc/cx16/mouse_stat_stddrv.s new file mode 100644 index 000000000..1ff8ad43b --- /dev/null +++ b/libsrc/cx16/mouse_stat_stddrv.s @@ -0,0 +1,11 @@ +; +; Address of the static standard mouse driver +; +; 2019-11-08,Greg King +; +; const void mouse_static_stddrv[]; +; + + .import _cx16_std_mou + + .export _mouse_static_stddrv := _cx16_std_mou diff --git a/libsrc/cx16/mouse_stddrv.s b/libsrc/cx16/mouse_stddrv.s new file mode 100644 index 000000000..d708bb668 --- /dev/null +++ b/libsrc/cx16/mouse_stddrv.s @@ -0,0 +1,13 @@ +; +; Name of the standard mouse driver +; +; 2019-11-08, Greg King +; +; const char mouse_stddrv[]; +; + + .export _mouse_stddrv + +.rodata + +_mouse_stddrv: .asciiz "cx16-std.mou" From 788fbcc9c8cdd88ecaf6baacef9cd347e406b0fd Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Sun, 17 Nov 2019 03:45:32 -0500 Subject: [PATCH 1212/2161] Fix silent crash failure on warning from linker command line define import size mismatch --- src/ld65/exports.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ld65/exports.c b/src/ld65/exports.c index b83d8b496..be14f7484 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -694,10 +694,15 @@ static void CheckSymType (const Export* E) GetString (E->Obj->Name), GetSourceName (ExportLI), GetSourceLine (ExportLI)); - } else { + } else if (ExportLI) { SB_Printf (&ExportLoc, "%s(%u)", GetSourceName (ExportLI), GetSourceLine (ExportLI)); + } else { + /* The export is linker generated and we don't have line + ** information (likely from command line define) + */ + SB_Printf (&ExportLoc, "linker"); } if (I->Obj) { /* The import comes from an object file */ From c9355734f5acce3c06553d7b7b7ddbda50a7b495 Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Mon, 18 Nov 2019 01:37:26 -0500 Subject: [PATCH 1213/2161] make linker generated export warning conistent with the import warning --- src/ld65/exports.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ld65/exports.c b/src/ld65/exports.c index be14f7484..5df7a37c9 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -702,7 +702,7 @@ static void CheckSymType (const Export* E) /* The export is linker generated and we don't have line ** information (likely from command line define) */ - SB_Printf (&ExportLoc, "linker"); + SB_Printf (&ExportLoc, "%s", GetObjFileName (E->Obj)); } if (I->Obj) { /* The import comes from an object file */ From 7bae9038cfc1ff25a6845c050a4a0d6a98fd47a9 Mon Sep 17 00:00:00 2001 From: mc78 <mc78@outlook.de> Date: Mon, 11 Nov 2019 16:30:09 +0100 Subject: [PATCH 1214/2161] Replaced plain 0's and 1's in exit statements with EXIT_SUCCESS or EXIT_FAILURE --- samples/geos/getid.c | 2 +- samples/geos/hello1.c | 2 +- samples/geos/hello2.c | 2 +- test/ref/hanoi.c | 2 +- test/ref/wf1.c | 2 +- testcode/lib/getopt-test.c | 6 ++++-- testcode/lib/shift-test.c | 6 +++--- 7 files changed, 12 insertions(+), 10 deletions(-) diff --git a/samples/geos/getid.c b/samples/geos/getid.c index 4331e27e8..200a1478e 100644 --- a/samples/geos/getid.c +++ b/samples/geos/getid.c @@ -16,7 +16,7 @@ const graphicStr Table = { void Exit(void) { - exit(0); + exit(EXIT_SUCCESS); } void Menu = { diff --git a/samples/geos/hello1.c b/samples/geos/hello1.c index fd46d157d..8dc13d5b4 100644 --- a/samples/geos/hello1.c +++ b/samples/geos/hello1.c @@ -26,7 +26,7 @@ void main (void) // MainLoop(); // we can do: // (nothing as this is the end of main function) - // exit(0); + // exit(EXIT_SUCCESS); // return; return; diff --git a/samples/geos/hello2.c b/samples/geos/hello2.c index d41bdb3c9..3f148b0b8 100644 --- a/samples/geos/hello2.c +++ b/samples/geos/hello2.c @@ -44,7 +44,7 @@ void main (void) // MainLoop(); // we can do: // (nothing as this is the end of main function) - // exit(0); + // exit(EXIT_SUCCESS); // return; return; diff --git a/test/ref/hanoi.c b/test/ref/hanoi.c index 5198c5c61..14bc60fa6 100644 --- a/test/ref/hanoi.c +++ b/test/ref/hanoi.c @@ -62,7 +62,7 @@ int main(int argc,char **argv) #ifdef USECMDLINE if (argc < 2) { printf("Usage: %s [duration] [disks]\n", argv[0]); - exit(1); + exit(EXIT_FAILURE); } else { diff --git a/test/ref/wf1.c b/test/ref/wf1.c index 1c3bfbd37..e1ed7a417 100644 --- a/test/ref/wf1.c +++ b/test/ref/wf1.c @@ -45,7 +45,7 @@ err(s) char *s; { int err(char *s) { #endif printf("? %s\n", s); - exit(1); + exit(EXIT_FAILURE); } /* getword - get next input word into buf, return 0 on EOF */ diff --git a/testcode/lib/getopt-test.c b/testcode/lib/getopt-test.c index 2f1155419..b5639b7c9 100644 --- a/testcode/lib/getopt-test.c +++ b/testcode/lib/getopt-test.c @@ -22,6 +22,8 @@ #define BADCH '?' #define ENDARGS "--" +#define NUMARGS 2 + int main (int argc, char **argv) { char *optstring = argv[1]; @@ -34,9 +36,9 @@ int main (int argc, char **argv) char *opi; - if (argc == 1) { + if (argc != NUMARGS) { fprintf (stderr, "Usage: %s optstring args\n", argv0); - exit (1); + exit (EXIT_FAILURE); } argv++; argc--; diff --git a/testcode/lib/shift-test.c b/testcode/lib/shift-test.c index 5712f4534..27c7d88a7 100644 --- a/testcode/lib/shift-test.c +++ b/testcode/lib/shift-test.c @@ -58,7 +58,7 @@ static void TestUnsignedLeftShift (void) fprintf (stderr, "Failed: %u << %u != %u (%u)\n", L, R, V, L << R); - exit (1); + exit (EXIT_FAILURE); } V = UnsignedShiftLeft1 (V); } @@ -85,7 +85,7 @@ static void TestUnsignedRightShift (void) fprintf (stderr, "Failed: %u >> %u != %u (%u)\n", L, R, V, L >> R); - exit (1); + exit (EXIT_FAILURE); } V = UnsignedShiftRight1 (V); } @@ -112,7 +112,7 @@ static void TestSignedRightShift (void) fprintf (stderr, "Failed: %d >> %d != %d (%d)\n", L, R, V, L >> R); - exit (1); + exit (EXIT_FAILURE); } V = SignedShiftRight1 (V); } From 3daecfb3dd357047e12bdd002ab114bbeb29c85d Mon Sep 17 00:00:00 2001 From: mc78 <mc78@outlook.de> Date: Tue, 12 Nov 2019 13:08:33 +0100 Subject: [PATCH 1215/2161] Added enum for cc65 exit codes. replaced stdlib exit code names constants in libsrc with cc65 exit code named constants --- include/cc65.h | 6 ++++++ libsrc/common/_afailed.c | 2 +- libsrc/common/abort.c | 2 +- libsrc/dbg/dbg.c | 2 +- libsrc/geos-apple/targetutil/convert.c | 5 +++-- libsrc/geos-common/common/_afailed.c | 2 +- libsrc/geos-common/common/abort.c | 3 ++- 7 files changed, 15 insertions(+), 7 deletions(-) diff --git a/include/cc65.h b/include/cc65.h index 7e9c2cae2..99a8665c8 100644 --- a/include/cc65.h +++ b/include/cc65.h @@ -36,6 +36,12 @@ #ifndef _CC65_H #define _CC65_H +typedef enum { + CC65_EXIT_SUCCESS, + CC65_EXIT_FAILURE, + CC65_EXIT_AFAILED, + CC65_EXIT_ABORT +} cc65_exit_codes_t; /*****************************************************************************/ diff --git a/libsrc/common/_afailed.c b/libsrc/common/_afailed.c index ed93fc12d..654025e1a 100644 --- a/libsrc/common/_afailed.c +++ b/libsrc/common/_afailed.c @@ -17,5 +17,5 @@ void __fastcall__ _afailed (char* file, unsigned line) { raise (SIGABRT); fprintf (stderr, "ASSERTION FAILED IN %s(%u)\n", file, line); - exit (2); + exit (CC65_EXIT_AFAILED); } diff --git a/libsrc/common/abort.c b/libsrc/common/abort.c index 43ad676a7..e59adb7d3 100644 --- a/libsrc/common/abort.c +++ b/libsrc/common/abort.c @@ -16,7 +16,7 @@ void abort (void) { raise (SIGABRT); fputs ("ABNORMAL PROGRAM TERMINATION\n", stderr); - exit (3); + exit (CC65_EXIT_ABORT); } diff --git a/libsrc/dbg/dbg.c b/libsrc/dbg/dbg.c index 60b452799..1b08d7750 100644 --- a/libsrc/dbg/dbg.c +++ b/libsrc/dbg/dbg.c @@ -1580,7 +1580,7 @@ void DbgEntry (void) case 'q': /* Quit program */ clrscr (); - exit (1); + exit (CC65_EXIT_FAILURE); } } diff --git a/libsrc/geos-apple/targetutil/convert.c b/libsrc/geos-apple/targetutil/convert.c index ea9273fc3..a4d07ac0a 100644 --- a/libsrc/geos-apple/targetutil/convert.c +++ b/libsrc/geos-apple/targetutil/convert.c @@ -5,6 +5,7 @@ #include <dirent.h> #include <device.h> #include <dio.h> +#include <cc65.h> unsigned char info_signature[3] = {3, 21, 63 | 0x80}; @@ -69,7 +70,7 @@ static void err_exit(char *operation, unsigned char oserr) operation); } getchar(); - exit(EXIT_FAILURE); + exit(CC65_EXIT_FAILURE); } @@ -342,5 +343,5 @@ int main(int argc, char* argv[]) printf("Convert to '%.*s' successful", dir_entry->storage_length.name_length, dir_entry->file_name); getchar(); - return EXIT_SUCCESS; + return CC65_EXIT_SUCCESS; } diff --git a/libsrc/geos-common/common/_afailed.c b/libsrc/geos-common/common/_afailed.c index 2448534c0..ec21a6b4e 100644 --- a/libsrc/geos-common/common/_afailed.c +++ b/libsrc/geos-common/common/_afailed.c @@ -28,5 +28,5 @@ void _afailed (char* file, unsigned line) DlgBoxOk(CBOLDON "ASSERTION FAILED", "PROGRAM TERMINATED" CPLAINTEXT); - exit (2); + exit (CC65_EXIT_AFAILED); } diff --git a/libsrc/geos-common/common/abort.c b/libsrc/geos-common/common/abort.c index b7cb35eb9..665b70863 100644 --- a/libsrc/geos-common/common/abort.c +++ b/libsrc/geos-common/common/abort.c @@ -6,10 +6,11 @@ #include <stdlib.h> #include <geos.h> +#include <cc65.h> void abort (void) { ExitTurbo(); DlgBoxOk(CBOLDON "ABNORMAL PROGRAM", "TERMINATION." CPLAINTEXT); - exit(3); + exit(CC65_EXIT_ABORT); } From 694dd9240fe42d9544af82ed161927c62971d95d Mon Sep 17 00:00:00 2001 From: mc78 <mc78@outlook.de> Date: Tue, 12 Nov 2019 20:48:43 +0100 Subject: [PATCH 1216/2161] Added comment to debugger exit with error --- libsrc/common/_afailed.c | 2 +- libsrc/common/abort.c | 2 +- libsrc/dbg/dbg.c | 7 +++++-- libsrc/geos-common/common/_afailed.c | 1 + 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/libsrc/common/_afailed.c b/libsrc/common/_afailed.c index 654025e1a..980045a63 100644 --- a/libsrc/common/_afailed.c +++ b/libsrc/common/_afailed.c @@ -10,7 +10,7 @@ #include <signal.h> #include <stdio.h> #include <stdlib.h> - +#include <cc65.h> void __fastcall__ _afailed (char* file, unsigned line) diff --git a/libsrc/common/abort.c b/libsrc/common/abort.c index e59adb7d3..43f4ab004 100644 --- a/libsrc/common/abort.c +++ b/libsrc/common/abort.c @@ -9,7 +9,7 @@ #include <stdio.h> #include <stdlib.h> #include <signal.h> - +#include <cc65.h> void abort (void) diff --git a/libsrc/dbg/dbg.c b/libsrc/dbg/dbg.c index 1b08d7750..a58e6c7a6 100644 --- a/libsrc/dbg/dbg.c +++ b/libsrc/dbg/dbg.c @@ -14,7 +14,7 @@ #include <ctype.h> #include <6502.h> #include <dbg.h> - +#include <cc65.h> /*****************************************************************************/ @@ -1580,8 +1580,11 @@ void DbgEntry (void) case 'q': /* Quit program */ clrscr (); + + /* Exit intentionally with error because one may + say that DbgEntry is always abnormal. */ exit (CC65_EXIT_FAILURE); - + } } } diff --git a/libsrc/geos-common/common/_afailed.c b/libsrc/geos-common/common/_afailed.c index ec21a6b4e..cc9610ddf 100644 --- a/libsrc/geos-common/common/_afailed.c +++ b/libsrc/geos-common/common/_afailed.c @@ -7,6 +7,7 @@ #include <stdio.h> #include <stdlib.h> #include <geos.h> +#include <cc65.h> void _afailed (char* file, unsigned line) { From 16a66f19e10b85e5adc4b0c72de07cbd8dd2159f Mon Sep 17 00:00:00 2001 From: mc78 <mc78@outlook.de> Date: Fri, 15 Nov 2019 16:35:58 +0100 Subject: [PATCH 1217/2161] Replaced enum in cc65.h by defines. added comment that cc65 exit constants should not redefine 0 and 1 as they are reserved for exit_success and exit_failure --- include/cc65.h | 13 +++++++------ libsrc/dbg/dbg.c | 3 +-- libsrc/geos-apple/targetutil/convert.c | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/cc65.h b/include/cc65.h index 99a8665c8..95de8e4ab 100644 --- a/include/cc65.h +++ b/include/cc65.h @@ -36,12 +36,13 @@ #ifndef _CC65_H #define _CC65_H -typedef enum { - CC65_EXIT_SUCCESS, - CC65_EXIT_FAILURE, - CC65_EXIT_AFAILED, - CC65_EXIT_ABORT -} cc65_exit_codes_t; + +/* Those cc65 exit constants definitions are in addition the the + constants defined in stdlib.h. The values 0 and 1 are still + reserved for EXIT_SUCCESS and EXIT_FAILURE and should not be + redefined */ +#define CC65_EXIT_AFAILED 2 +#define CC65_EXIT_ABORT 3 /*****************************************************************************/ diff --git a/libsrc/dbg/dbg.c b/libsrc/dbg/dbg.c index a58e6c7a6..a6f952f35 100644 --- a/libsrc/dbg/dbg.c +++ b/libsrc/dbg/dbg.c @@ -14,7 +14,6 @@ #include <ctype.h> #include <6502.h> #include <dbg.h> -#include <cc65.h> /*****************************************************************************/ @@ -1583,7 +1582,7 @@ void DbgEntry (void) /* Exit intentionally with error because one may say that DbgEntry is always abnormal. */ - exit (CC65_EXIT_FAILURE); + exit (EXIT_FAILURE); } } diff --git a/libsrc/geos-apple/targetutil/convert.c b/libsrc/geos-apple/targetutil/convert.c index a4d07ac0a..7798e004d 100644 --- a/libsrc/geos-apple/targetutil/convert.c +++ b/libsrc/geos-apple/targetutil/convert.c @@ -70,7 +70,7 @@ static void err_exit(char *operation, unsigned char oserr) operation); } getchar(); - exit(CC65_EXIT_FAILURE); + exit(EXIT_FAILURE); } @@ -343,5 +343,5 @@ int main(int argc, char* argv[]) printf("Convert to '%.*s' successful", dir_entry->storage_length.name_length, dir_entry->file_name); getchar(); - return CC65_EXIT_SUCCESS; + return EXIT_SUCCESS; } From a139c4057c4bcea6518ab3dc9c23db0171d2d4c5 Mon Sep 17 00:00:00 2001 From: mc78 <mc78@outlook.de> Date: Sun, 17 Nov 2019 13:13:43 +0100 Subject: [PATCH 1218/2161] Removed CC65_ prefixes from exit statements in abort and assert code as well from definition --- include/cc65.h | 4 ++-- libsrc/common/_afailed.c | 2 +- libsrc/common/abort.c | 2 +- libsrc/geos-common/common/_afailed.c | 2 +- libsrc/geos-common/common/abort.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/cc65.h b/include/cc65.h index 95de8e4ab..9506cf107 100644 --- a/include/cc65.h +++ b/include/cc65.h @@ -41,8 +41,8 @@ constants defined in stdlib.h. The values 0 and 1 are still reserved for EXIT_SUCCESS and EXIT_FAILURE and should not be redefined */ -#define CC65_EXIT_AFAILED 2 -#define CC65_EXIT_ABORT 3 +#define EXIT_ASSERT 2 +#define EXIT_ABORT 3 /*****************************************************************************/ diff --git a/libsrc/common/_afailed.c b/libsrc/common/_afailed.c index 980045a63..7df2db60f 100644 --- a/libsrc/common/_afailed.c +++ b/libsrc/common/_afailed.c @@ -17,5 +17,5 @@ void __fastcall__ _afailed (char* file, unsigned line) { raise (SIGABRT); fprintf (stderr, "ASSERTION FAILED IN %s(%u)\n", file, line); - exit (CC65_EXIT_AFAILED); + exit (EXIT_ASSERT); } diff --git a/libsrc/common/abort.c b/libsrc/common/abort.c index 43f4ab004..af0d8c314 100644 --- a/libsrc/common/abort.c +++ b/libsrc/common/abort.c @@ -16,7 +16,7 @@ void abort (void) { raise (SIGABRT); fputs ("ABNORMAL PROGRAM TERMINATION\n", stderr); - exit (CC65_EXIT_ABORT); + exit (EXIT_ABORT); } diff --git a/libsrc/geos-common/common/_afailed.c b/libsrc/geos-common/common/_afailed.c index cc9610ddf..63f234962 100644 --- a/libsrc/geos-common/common/_afailed.c +++ b/libsrc/geos-common/common/_afailed.c @@ -29,5 +29,5 @@ void _afailed (char* file, unsigned line) DlgBoxOk(CBOLDON "ASSERTION FAILED", "PROGRAM TERMINATED" CPLAINTEXT); - exit (CC65_EXIT_AFAILED); + exit (EXIT_ASSERT); } diff --git a/libsrc/geos-common/common/abort.c b/libsrc/geos-common/common/abort.c index 665b70863..92ed745a0 100644 --- a/libsrc/geos-common/common/abort.c +++ b/libsrc/geos-common/common/abort.c @@ -12,5 +12,5 @@ void abort (void) { ExitTurbo(); DlgBoxOk(CBOLDON "ABNORMAL PROGRAM", "TERMINATION." CPLAINTEXT); - exit(CC65_EXIT_ABORT); + exit(EXIT_ABORT); } From 8d2617110facddc2ba709db28abd710e7ce2ca38 Mon Sep 17 00:00:00 2001 From: mc78 <mc78@outlook.de> Date: Sun, 17 Nov 2019 15:57:34 +0100 Subject: [PATCH 1219/2161] Removed additional exit constants definitions from cc65.h to stdlih.h. Guarded the definitions by #ifdef. Removed cc65.h includes from abort and assert implementations. --- include/cc65.h | 8 -------- include/stdlib.h | 11 +++++++++++ libsrc/common/_afailed.c | 1 - libsrc/common/abort.c | 1 - libsrc/geos-common/common/_afailed.c | 1 - libsrc/geos-common/common/abort.c | 1 - 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/include/cc65.h b/include/cc65.h index 9506cf107..720f1cd04 100644 --- a/include/cc65.h +++ b/include/cc65.h @@ -37,14 +37,6 @@ #define _CC65_H -/* Those cc65 exit constants definitions are in addition the the - constants defined in stdlib.h. The values 0 and 1 are still - reserved for EXIT_SUCCESS and EXIT_FAILURE and should not be - redefined */ -#define EXIT_ASSERT 2 -#define EXIT_ABORT 3 - - /*****************************************************************************/ /* Code */ /*****************************************************************************/ diff --git a/include/stdlib.h b/include/stdlib.h index 3103172d8..638cb475b 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -48,6 +48,17 @@ typedef unsigned size_t; #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 +#if __CC65_STD__ == __CC65_STD_CC65__ + +/* Those non-standard cc65 exit constants definitions are in addition + to the EXIT_SUCCESS and EXIT_FAILURE constants, which should not be + redefined */ +#define EXIT_ASSERT 2 +#define EXIT_ABORT 3 + +#endif + + /* Return type of the div function */ typedef struct { int rem; diff --git a/libsrc/common/_afailed.c b/libsrc/common/_afailed.c index 7df2db60f..ad50a8750 100644 --- a/libsrc/common/_afailed.c +++ b/libsrc/common/_afailed.c @@ -10,7 +10,6 @@ #include <signal.h> #include <stdio.h> #include <stdlib.h> -#include <cc65.h> void __fastcall__ _afailed (char* file, unsigned line) diff --git a/libsrc/common/abort.c b/libsrc/common/abort.c index af0d8c314..1dda559bb 100644 --- a/libsrc/common/abort.c +++ b/libsrc/common/abort.c @@ -9,7 +9,6 @@ #include <stdio.h> #include <stdlib.h> #include <signal.h> -#include <cc65.h> void abort (void) diff --git a/libsrc/geos-common/common/_afailed.c b/libsrc/geos-common/common/_afailed.c index 63f234962..97727d605 100644 --- a/libsrc/geos-common/common/_afailed.c +++ b/libsrc/geos-common/common/_afailed.c @@ -7,7 +7,6 @@ #include <stdio.h> #include <stdlib.h> #include <geos.h> -#include <cc65.h> void _afailed (char* file, unsigned line) { diff --git a/libsrc/geos-common/common/abort.c b/libsrc/geos-common/common/abort.c index 92ed745a0..90a651286 100644 --- a/libsrc/geos-common/common/abort.c +++ b/libsrc/geos-common/common/abort.c @@ -6,7 +6,6 @@ #include <stdlib.h> #include <geos.h> -#include <cc65.h> void abort (void) { From 1dee2360fa5a5690271a347f782a214776550cab Mon Sep 17 00:00:00 2001 From: mc78 <mc78@outlook.de> Date: Sun, 17 Nov 2019 16:16:32 +0100 Subject: [PATCH 1220/2161] added additional empty line after header guard in cc65.h to conform to other headers --- include/cc65.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/cc65.h b/include/cc65.h index 720f1cd04..7e9c2cae2 100644 --- a/include/cc65.h +++ b/include/cc65.h @@ -37,6 +37,7 @@ #define _CC65_H + /*****************************************************************************/ /* Code */ /*****************************************************************************/ From db971d8a655c8f00109ba1d9403cf9838643b93a Mon Sep 17 00:00:00 2001 From: mc78 <mc78@outlook.de> Date: Tue, 19 Nov 2019 13:17:02 +0100 Subject: [PATCH 1221/2161] Removed unnecessary #include <cc65.h> from convert.c Adjusted block comments to predominant style --- include/stdlib.h | 5 +++-- libsrc/dbg/dbg.c | 3 ++- libsrc/geos-apple/targetutil/convert.c | 1 - 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/stdlib.h b/include/stdlib.h index 638cb475b..b929e8f02 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -51,8 +51,9 @@ typedef unsigned size_t; #if __CC65_STD__ == __CC65_STD_CC65__ /* Those non-standard cc65 exit constants definitions are in addition - to the EXIT_SUCCESS and EXIT_FAILURE constants, which should not be - redefined */ +** to the EXIT_SUCCESS and EXIT_FAILURE constants, which should not be +** redefined +*/ #define EXIT_ASSERT 2 #define EXIT_ABORT 3 diff --git a/libsrc/dbg/dbg.c b/libsrc/dbg/dbg.c index a6f952f35..27f2086eb 100644 --- a/libsrc/dbg/dbg.c +++ b/libsrc/dbg/dbg.c @@ -1581,7 +1581,8 @@ void DbgEntry (void) clrscr (); /* Exit intentionally with error because one may - say that DbgEntry is always abnormal. */ + ** say that DbgEntry is always abnormal. + */ exit (EXIT_FAILURE); } diff --git a/libsrc/geos-apple/targetutil/convert.c b/libsrc/geos-apple/targetutil/convert.c index 7798e004d..ea9273fc3 100644 --- a/libsrc/geos-apple/targetutil/convert.c +++ b/libsrc/geos-apple/targetutil/convert.c @@ -5,7 +5,6 @@ #include <dirent.h> #include <device.h> #include <dio.h> -#include <cc65.h> unsigned char info_signature[3] = {3, 21, 63 | 0x80}; From d9a6fbac48d52e5765b0ac6e5531f7261561f61d Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 18:59:18 +0100 Subject: [PATCH 1222/2161] Fixed C16 #978 --- libsrc/c16/waitvsync.s | 1 + 1 file changed, 1 insertion(+) create mode 100644 libsrc/c16/waitvsync.s diff --git a/libsrc/c16/waitvsync.s b/libsrc/c16/waitvsync.s new file mode 100644 index 000000000..c020976b9 --- /dev/null +++ b/libsrc/c16/waitvsync.s @@ -0,0 +1 @@ +.include "../plus4/waitvsync.s" From 9ab614d764b5f524cb60fb65c0e3d7187b97fdd0 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:05:28 +0100 Subject: [PATCH 1223/2161] Update c16.sgml --- doc/c16.sgml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/doc/c16.sgml b/doc/c16.sgml index 462f98345..ae64da47b 100644 --- a/doc/c16.sgml +++ b/doc/c16.sgml @@ -123,6 +123,7 @@ declaration and usage. <item>cbm_save <item>cbm_write <item>get_tv +<item>waitvsync </itemize> @@ -270,7 +271,3 @@ freely, subject to the following restrictions: </enum> </article> - - - - From 9bf2bf308aeb349b7693ed3feb64c29654c8d673 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:09:54 +0100 Subject: [PATCH 1224/2161] Update c128.sgml --- doc/c128.sgml | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/c128.sgml b/doc/c128.sgml index 1d8734fdf..8c62b6ad1 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -133,6 +133,7 @@ declaration and usage. <item>cbm_save <item>cbm_write <item>get_tv +<item>waitvsync </itemize> From 94892231bcc60ba0b004b94ecd2a7002b7b29e90 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:10:32 +0100 Subject: [PATCH 1225/2161] Update c64.sgml --- doc/c64.sgml | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/c64.sgml b/doc/c64.sgml index c11867051..7cd9b2d81 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -225,6 +225,7 @@ declaration and usage. <item>cbm_save <item>cbm_write <item>get_tv +<item>waitvsync </itemize> From 49ebac7ac1c6e563f481c6bdd585e724ae749763 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:11:11 +0100 Subject: [PATCH 1226/2161] Update cbm510.sgml --- doc/cbm510.sgml | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/cbm510.sgml b/doc/cbm510.sgml index 012a7b596..c208f3ead 100644 --- a/doc/cbm510.sgml +++ b/doc/cbm510.sgml @@ -126,6 +126,7 @@ declaration and usage. <item>cbm_save <item>cbm_write <item>get_tv +<item>waitvsync </itemize> From 63ab22f97f59953da5a38b265d3277dde163214c Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:14:08 +0100 Subject: [PATCH 1227/2161] Update cx16.sgml --- doc/cx16.sgml | 62 +++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/doc/cx16.sgml b/doc/cx16.sgml index 7189e7157..2136265bc 100644 --- a/doc/cx16.sgml +++ b/doc/cx16.sgml @@ -139,12 +139,11 @@ The functions listed below are special for the CX16. See the <url url="funcref.html" name="function reference"> for declarations and usage. <itemize> -<item>get_ostype() -<item>set_tv() -<item>videomode() -<item>vpeek() -<item>vpoke() -<item>waitvsync() +<item>get_ostype +<item>set_tv +<item>videomode +<item>vpeek +<item>vpoke </itemize> @@ -155,31 +154,32 @@ machines. See the <url url="funcref.html" name="function reference"> for declarations and usage. <itemize> -<item>cbm_close() -<item>cbm_closedir() -<item>cbm_k_basin() -<item>cbm_k_bsout() -<item>cbm_k_chkin() -<item>cbm_k_ckout() -<item>cbm_k_close() -<item>cbm_k_clrch() -<item>cbm_k_getin() -<item>cbm_k_load() -<item>cbm_k_open() -<item>cbm_k_readst() -<item>cbm_k_save() -<item>cbm_k_second() -<item>cbm_k_setlfs() -<item>cbm_k_setnam() -<item>cbm_k_tksa() -<item>cbm_load() -<item>cbm_open() -<item>cbm_opendir() -<item>cbm_read() -<item>cbm_readdir() -<item>cbm_save() -<item>cbm_write() -<item>get_tv() +<item>cbm_close +<item>cbm_closedir +<item>cbm_k_basin +<item>cbm_k_bsout +<item>cbm_k_chkin +<item>cbm_k_ckout +<item>cbm_k_close +<item>cbm_k_clrch +<item>cbm_k_getin +<item>cbm_k_load +<item>cbm_k_open +<item>cbm_k_readst +<item>cbm_k_save +<item>cbm_k_second +<item>cbm_k_setlfs +<item>cbm_k_setnam +<item>cbm_k_tksa +<item>cbm_load +<item>cbm_open +<item>cbm_opendir +<item>cbm_read +<item>cbm_readdir +<item>cbm_save +<item>cbm_write +<item>get_tv +<item>waitvsync </itemize> From c08f1e4bfdc56bcdd7da4c6422246f6e5896e9c3 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:15:50 +0100 Subject: [PATCH 1228/2161] Update funcref.sgml --- doc/funcref.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 72a44c7b6..7a46736ec 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -213,8 +213,8 @@ function. <!-- <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="waitvsync" name="waitvsync"> <item><ref id="kbrepeat" name="kbrepeat"> +<item><ref id="waitvsync" name="waitvsync"> </itemize> (incomplete) @@ -7716,7 +7716,7 @@ name="toggle_videomode">. <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> -<tag/Availability/C128 and enhanced Apple //e +<tag/Availability/C128, enhanced Apple //e and CX16 <tag/See also/ <ref id="fast" name="fast">, <ref id="isfast" name="isfast">, From 7361aa9959b8a869d18e4f457f00ea1bf449f0f9 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:16:31 +0100 Subject: [PATCH 1229/2161] Update nes.sgml --- doc/nes.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/nes.sgml b/doc/nes.sgml index 3f8f74183..beb322fc3 100644 --- a/doc/nes.sgml +++ b/doc/nes.sgml @@ -67,8 +67,8 @@ Programs containing NES specific code may use the <tt/nes.h/ header file. <sect1>NES specific functions<p> <itemize> -<item>waitvsync - wait until the start of the next frame</item> <item>get_tv</item> +<item>waitvsync - wait until the start of the next frame</item> </itemize> From ea16316e336f53c915bc038e0cd53f0e9895ab0f Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:17:22 +0100 Subject: [PATCH 1230/2161] Update pce.sgml --- doc/pce.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/pce.sgml b/doc/pce.sgml index a1866b8f0..42a1ca9d3 100644 --- a/doc/pce.sgml +++ b/doc/pce.sgml @@ -114,8 +114,8 @@ Programs containing PCE-specific code may use the <tt/pce.h/ header file. <sect1>PCE-specific functions<p> <itemize> -<item>waitvsync</item> <item>get_tv (since all PCE systems are NTSC, this always returns TV_NTSC)</item> +<item>waitvsync</item> </itemize> From a56b176749bb6bf43a29e797e362a9596f5cb079 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:18:05 +0100 Subject: [PATCH 1231/2161] Update plus4.sgml --- doc/plus4.sgml | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/plus4.sgml b/doc/plus4.sgml index 11468bb33..645de5161 100644 --- a/doc/plus4.sgml +++ b/doc/plus4.sgml @@ -121,6 +121,7 @@ declaration and usage. <item>cbm_save <item>cbm_write <item>get_tv +<item>waitvsync </itemize> From c9d2c10cbd43cf4e46aec6ec6489515742737daf Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:18:39 +0100 Subject: [PATCH 1232/2161] Update vic20.sgml --- doc/vic20.sgml | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/vic20.sgml b/doc/vic20.sgml index e292e0a1a..4fcd0079c 100644 --- a/doc/vic20.sgml +++ b/doc/vic20.sgml @@ -107,6 +107,7 @@ declaration and usage. <item>cbm_save <item>cbm_write <item>get_tv +<item>waitvsync </itemize> From 4497998944981862233914b75875590226021345 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:20:19 +0100 Subject: [PATCH 1233/2161] Update color.s --- libsrc/c16/color.s | 34 +--------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/libsrc/c16/color.s b/libsrc/c16/color.s index 2f3046e8f..fbcc95a2a 100644 --- a/libsrc/c16/color.s +++ b/libsrc/c16/color.s @@ -1,33 +1 @@ -; -; Ullrich von Bassewitz, 06.08.1998 -; -; unsigned char __fastcall__ textcolor (unsigned char color); -; unsigned char __fastcall__ bgcolor (unsigned char color); -; unsigned char __fastcall__ bordercolor (unsigned char color); -; - - .export _textcolor, _bgcolor, _bordercolor - - .include "plus4.inc" - -_textcolor: - ldx CHARCOLOR ; get old value - sta CHARCOLOR ; set new value - txa - rts - - -_bgcolor: - ldx TED_BGCOLOR ; get old value - sta TED_BGCOLOR ; set new value - txa - rts - - -_bordercolor: - ldx TED_BORDERCOLOR ; get old value - sta TED_BORDERCOLOR ; set new value - txa - rts - - +.include "../plus4/color.s" From 06c98952fcd153d5ae4ac22477e8a51006481ee9 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:21:00 +0100 Subject: [PATCH 1234/2161] Update conio.s --- libsrc/c16/conio.s | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/libsrc/c16/conio.s b/libsrc/c16/conio.s index feca30c68..3ab372a29 100644 --- a/libsrc/c16/conio.s +++ b/libsrc/c16/conio.s @@ -1,10 +1 @@ -; -; Ullrich von Bassewitz, 06.08.1998 -; -; Low level stuff for screen output/console input -; - - .exportzp CURS_X, CURS_Y - - .include "plus4.inc" - +.include "../plus4/conio.s" From 3f360fe3ee04490dd1664e27066c1248f9e4de87 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:21:52 +0100 Subject: [PATCH 1235/2161] Update cputc.s --- libsrc/c16/cputc.s | 105 +-------------------------------------------- 1 file changed, 1 insertion(+), 104 deletions(-) diff --git a/libsrc/c16/cputc.s b/libsrc/c16/cputc.s index 49b3a84dd..86959675a 100644 --- a/libsrc/c16/cputc.s +++ b/libsrc/c16/cputc.s @@ -1,104 +1 @@ -; -; Ullrich von Bassewitz, 06.08.1998 -; -; void cputcxy (unsigned char x, unsigned char y, char c); -; void cputc (char c); -; - - .export _cputcxy, _cputc, cputdirect, putchar - .export newline, plot - .import gotoxy - .import PLOT - - .include "plus4.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 #$7E ; PI? - bne L11 - lda #$5E ; Load screen code for PI - bne cputdirect -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 - sta (SCREEN_PTR),y ; Set char - lda CHARCOLOR - sta (CRAM_PTR),y ; Set color - rts +.include "../plus4/cputc.s" From df752ff7a58da5785f113c84cf946c5de75bbc58 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:22:28 +0100 Subject: [PATCH 1236/2161] Update fast.s --- libsrc/c16/fast.s | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/libsrc/c16/fast.s b/libsrc/c16/fast.s index e48813969..50924edbc 100644 --- a/libsrc/c16/fast.s +++ b/libsrc/c16/fast.s @@ -1,22 +1 @@ -; -; Marco van den Heuvel, 2018-03-20 -; -; void fast (void); -; /* Switch the CPU into double clock mode. */ -; - - .export _fast - - .include "plus4.inc" - - -.proc _fast - - lda TED_CLK - and #%11111101 - sta TED_CLK - rts - -.endproc - - +.include "../plus4/fast.s" From 2c34723a97631992dd6d00fa6e19bd49e05a7c87 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:22:53 +0100 Subject: [PATCH 1237/2161] Update isfast.s --- libsrc/c16/isfast.s | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/libsrc/c16/isfast.s b/libsrc/c16/isfast.s index ff104d97f..036840753 100644 --- a/libsrc/c16/isfast.s +++ b/libsrc/c16/isfast.s @@ -1,22 +1 @@ -; -; Marco van den Heuvel, 2018-03-20 -; -; unsigned char isfast (void); -; /* Returns 1 if the CPU is in double clock mode. */ -; - - .export _isfast - - .include "plus4.inc" - - -.proc _isfast - - lda TED_CLK - lsr - and #$01 - ldx #$00 - rts - -.endproc - +.include "../plus4/isfast.s" From eeefd10f8f8699e7ceb0d02840257dd56f6a0bbb Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:23:31 +0100 Subject: [PATCH 1238/2161] Update revers.s --- libsrc/c16/revers.s | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/libsrc/c16/revers.s b/libsrc/c16/revers.s index f1c0b4d64..3ce668760 100644 --- a/libsrc/c16/revers.s +++ b/libsrc/c16/revers.s @@ -1,27 +1 @@ -; -; Ullrich von Bassewitz, 07.08.1998 -; -; unsigned char revers (unsigned char onoff); -; - - .export _revers - - .include "plus4.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 - +.include "../plus4/revers.s" From 9d4d00737ec18db92ea395bef6185345eb353adb Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:24:14 +0100 Subject: [PATCH 1239/2161] Update slow.s --- libsrc/c16/slow.s | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/libsrc/c16/slow.s b/libsrc/c16/slow.s index 18b8c231c..70e461a9a 100644 --- a/libsrc/c16/slow.s +++ b/libsrc/c16/slow.s @@ -1,22 +1 @@ -; -; Marco van den Heuvel, 2018-03-28 -; -; void slow (void); -; /* Switch the CPU into single clock mode. */ -; - - .export _slow - - .include "plus4.inc" - - -.proc _slow - - lda TED_CLK - ora #%00000010 - sta TED_CLK - rts - -.endproc - - +.include "../plus4/slow.s" From d1fd7ffc59f2aa06ec4f5af263c867d2907eaaa0 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Tue, 19 Nov 2019 19:24:49 +0100 Subject: [PATCH 1240/2161] Update status.s --- libsrc/c16/status.s | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libsrc/c16/status.s b/libsrc/c16/status.s index c6f279230..04d971696 100644 --- a/libsrc/c16/status.s +++ b/libsrc/c16/status.s @@ -1,5 +1 @@ -; -; Oliver Schmidt, 2012-09-30 -; - - .exportzp ST := $90 ; IEC status byte +.include "../plus4/status.s" From f75657d7e250268c5a4c444ecd8b2ac2ea7815db Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 20 Nov 2019 12:11:47 -0500 Subject: [PATCH 1241/2161] Added <cx16.h> to the function reference document. --- doc/funcref.sgml | 59 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 7a46736ec..c2b46f0f0 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -318,6 +318,20 @@ function. </itemize> +<sect1><tt/cx16.h/<label id="cx16.h"><p> + +<itemize> +<!-- <item><ref id="get_ostype" name="get_ostype"> --> +<!-- <item><ref id="get_tv" name="get_tv"> --> +<!-- <item><ref id="set_tv" name="set_tv"> --> +<item><ref id="videomode" name="videomode"> +<!-- <item><ref id="vpeek" name="vpeek"> --> +<!-- <item><ref id="vpoke" name="vpoke"> --> +</itemize> + +(incomplete) + + <sect1><tt/dbg.h/<label id="dbg.h"><p> <!-- <itemize> --> @@ -7702,24 +7716,31 @@ used in presence of a prototype. <quote> <descrip> -<tag/Function/Switch to either 40 or 80 column mode. -<tag/Header/<tt/<ref id="apple2enh.h" name="apple2enh.h">, -<ref id="c128.h" name="c128.h">/ -<tag/Declaration/<tt/unsigned __fastcall__ videomode (unsigned Mode);/ -<tag/Description/Switch to 40 or 80 column mode depending on the argument. If -the requested mode is already active, nothing happens. The old mode is returned -from the call. +<tag/Function/Switch to either 40- or 80-column text mode, or a standard +graphics mode. +<tag/Header/<tt/ +<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> +<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 C128 and enhanced Apple //e. +<item>The function is specific to the Commodore 128, the enhanced Apple //e, +and the Commander X16. <item>This function replaces <ref id="toggle_videomode" name="toggle_videomode">. -<item>The function is only available as fastcall function, so it may only be -used in presence of a prototype. +<item>The function is available as only a fastcall function, so it may be used +only in the presence of a prototype. </itemize> -<tag/Availability/C128, enhanced Apple //e and CX16 +<tag/Availability/C128, enhanced Apple //e, and CX16 <tag/See also/ <ref id="fast" name="fast">, <ref id="isfast" name="isfast">, +<!-- <ref id="set_tv" name="set_tv">, --> <ref id="slow" name="slow">, <ref id="toggle_videomode" name="toggle_videomode"> <tag/Example/None. @@ -7731,15 +7752,15 @@ used in presence of a prototype. <quote> <descrip> -<tag/Function/Wait until the start of the next frame. -<tag/Header/ -<tt/<ref id="cbm.h" name="cbm.h">/, -<tt/<ref id="gamate.h" name="gamate.h">/, -<tt/<ref id="nes.h" name="nes.h">/, -<tt/<ref id="pce.h" name="pce.h">/ +<tag/Function/Wait until the start of the next video frame. +<tag/Header/<tt/ +<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/Description/Wait for vertical sync to reduce flickering. -<tag/Availability/Platforms above +<tag/Description/Wait for vertical sync, to reduce flickering. +<tag/Availability/Platforms served by the headers above <tag/Example/None. </descrip> </quote> From d5c804f851c2dcf187a640b320cc49d466bfc76d Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 26 Nov 2019 22:18:12 +0100 Subject: [PATCH 1242/2161] Expanded Sim65 zero page. --- cfg/sim6502.cfg | 2 +- cfg/sim65c02.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cfg/sim6502.cfg b/cfg/sim6502.cfg index c768ab4a3..39c33581c 100644 --- a/cfg/sim6502.cfg +++ b/cfg/sim6502.cfg @@ -3,7 +3,7 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack } MEMORY { - ZP: file = "", start = $0000, size = $001B; + ZP: file = "", start = $0000, size = $0100; HEADER: file = %O, start = $0000, size = $000C; MAIN: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; } diff --git a/cfg/sim65c02.cfg b/cfg/sim65c02.cfg index c768ab4a3..39c33581c 100644 --- a/cfg/sim65c02.cfg +++ b/cfg/sim65c02.cfg @@ -3,7 +3,7 @@ SYMBOLS { __STACKSIZE__: type = weak, value = $0800; # 2k stack } MEMORY { - ZP: file = "", start = $0000, size = $001B; + ZP: file = "", start = $0000, size = $0100; HEADER: file = %O, start = $0000, size = $000C; MAIN: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; } From fb0d09a277ce74959552fe1ce58f1b4d7ee8419f Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 6 Dec 2019 14:47:47 -0500 Subject: [PATCH 1243/2161] Changed sim65's internal error codes from 9-bit values to 7-bit values. Some shells truncate process return codes to 8 bits. And, the eigth bit often is used to show that a signal stopped the process. --- src/sim65/error.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sim65/error.h b/src/sim65/error.h index 5d6e8be21..cbb785875 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -49,10 +49,10 @@ -#define SIM65_ERROR 256 +#define SIM65_ERROR 0x7F /* Does not use EXIT_FAILURE because it may overlap with test results. */ -#define SIM65_ERROR_TIMEOUT 257 +#define SIM65_ERROR_TIMEOUT 0x7E /* An error result for max CPU instructions exceeded. */ From cab4910a7d07029b3cc0ffd8abd4355f0365f5b7 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 10 Dec 2019 05:59:33 -0500 Subject: [PATCH 1244/2161] Added the missing BANK_RAM array to the Commander X16's header. --- include/cx16.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/include/cx16.h b/include/cx16.h index b465378a5..d7ed15d2a 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -77,7 +77,8 @@ #define COLOR_LIGHTBLUE 0x0E #define COLOR_GRAY3 0x0F -/* Masks for joy_read() */ +/* NES controller masks for joy_read() */ + #define JOY_BTN_1_MASK 0x80 #define JOY_BTN_2_MASK 0x40 #define JOY_BTN_3_MASK 0x20 @@ -101,7 +102,7 @@ #define JOY_FIRE2(v) ((v) & JOY_FIRE2_MASK) /* Additional mouse button mask */ -#define MOUSE_BTN_MIDDLE 0x02 +#define MOUSE_BTN_MIDDLE 0x02 /* get_tv() return codes ** set_tv() argument codes @@ -115,7 +116,7 @@ #define TV_NTSC_MONO 6 #define TV_RGB2 7 -/* Video modes */ +/* Video modes for videomode() */ #define VIDEOMODE_40x30 0x00 #define VIDEOMODE_80x60 0x02 #define VIDEOMODE_40COL VIDEOMODE_40x30 @@ -130,11 +131,9 @@ #define VERA_IRQ_UART 0b00001000 -/* Define hardware */ +/* Define hardware. */ -/* Define a structure with the Video Enhanced Retro Adapter's -** external registers. -*/ +/* A structure with the Video Enhanced Retro Adapter's external registers */ struct __vera { unsigned short address; /* Address for data ports */ unsigned char address_hi; @@ -150,7 +149,7 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) -/* Define a structure with the x16emu's settings registers. */ +/* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ unsigned char vera_action; /* Boolean: displaying VERA activity */ @@ -162,7 +161,10 @@ struct __emul { unsigned char keymap; /* Keyboard layout number */ const char detect[2]; /* "16" if running on x16emu */ }; -#define EMULATOR (*(volatile struct __emul)0x9FB0) +#define EMULATOR (*(volatile struct __emul)0x9FB0) + +/* An array window into the half Mibibyte or two Mibibytes of banked RAM */ +#define BANK_RAM ((unsigned char[0x2000])0xA000) From 3fa253d31fbec8602e791345125e33efadd98cbf Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 25 Dec 2019 10:56:32 -0500 Subject: [PATCH 1245/2161] Updated the cx16 library to the Commander X16 Kernal's prerelease 35. --- asminc/cbm_kernal.inc | 40 +++++- asminc/cx16.inc | 217 ++++++++++++++++++++++++------- cfg/cx16-asm.cfg | 2 +- cfg/cx16-bank.cfg | 10 +- cfg/cx16.cfg | 2 +- doc/cx16.sgml | 10 +- include/cbm.h | 2 +- include/cx16.h | 14 +- libsrc/cbm/clock.s | 19 ++- libsrc/cx16/_scrsize.s | 6 +- libsrc/cx16/bankramaddr.s | 6 +- libsrc/cx16/cgetc.s | 8 +- libsrc/cx16/clock.s | 36 +++++ libsrc/cx16/crt0.s | 12 +- libsrc/cx16/get_tv.s | 6 +- libsrc/cx16/joy/cx16-std.s | 60 +++------ libsrc/cx16/joyref.s | 4 +- libsrc/cx16/kbhit.s | 7 +- libsrc/cx16/kernal.s | 136 +++++++++++-------- libsrc/cx16/mcbdefault.s | 50 ++++--- libsrc/cx16/mou/cx16-std.s | 64 ++++----- libsrc/cx16/mouse_stat_stddrv.s | 2 +- libsrc/cx16/set_tv.s | 6 +- libsrc/cx16/sysuname.s | 2 +- libsrc/cx16/tgi_stat_stddrv.s | 7 +- libsrc/cx16/tgi_stddrv.s | 5 +- libsrc/cx16/{vset.s => vaddr0.s} | 9 +- libsrc/cx16/vpeek.s | 8 +- libsrc/cx16/vpoke.s | 8 +- libsrc/cx16/waitvsync.s | 12 +- src/ca65/struct.c | 9 +- 31 files changed, 508 insertions(+), 271 deletions(-) create mode 100644 libsrc/cx16/clock.s rename libsrc/cx16/{vset.s => vaddr0.s} (60%) diff --git a/asminc/cbm_kernal.inc b/asminc/cbm_kernal.inc index a38836ceb..86a60d49b 100644 --- a/asminc/cbm_kernal.inc +++ b/asminc/cbm_kernal.inc @@ -6,9 +6,40 @@ .if .def(__CX16__) ; CX16 extended jump table - GETJOY := $FF06 - MOUSE := $FF09 - SCRMOD := $FF5F + FB_INIT := $FEF6 + FB_GET_INFO := $FEF9 + FB_SET_PALETTE := $FEFC + FB_CURSOR_POSITION := $FEFF + FB_CURSOR_NEXT_LINE := $FF02 + FB_GET_PIXEL := $FF05 + FB_GET_PIXELS := $FF08 + FB_SET_PIXEL := $FF0B + FB_SET_PIXELS := $FF0E + FB_SET_8_PIXELS := $FF11 + FB_SET_8_PIXELS_OPAQUE := $FF14 + FB_FILL_PIXELS := $FF17 + FB_FILTER_PIXELS := $FF1A + FB_MOVE_PIXELS := $FF1D + GRAPH_INIT := $FF20 + GRAPH_CLEAR := $FF23 + GRAPH_SET_WINDOW := $FF26 + GRAPH_SET_COLORS := $FF29 + GRAPH_DRAW_LINE := $FF2C + GRAPH_DRAW_RECT := $FF2F + GRAPH_MOVE_RECT := $FF32 + GRAPH_DRAW_OVAL := $FF35 + GRAPH_DRAW_IMAGE := $FF38 + GRAPH_SET_FONT := $FF3B + GRAPH_GET_CHAR_SIZE := $FF3E + GRAPH_PUT_CHAR := $FF41 + RESTORE_BASIC := $FF47 + CLOCK_SET_DATE_TIME := $FF4D + CLOCK_GET_DATE_TIME := $FF50 + JOYSTICK_SCAN := $FF53 + JOYSTICK_GET := $FF56 + SCRMOD := $FF5F + MOUSE_CONFIG := $FF68 + MOUSE_GET := $FF6B .endif .if .def(__C128__) @@ -21,6 +52,9 @@ .if .def(__C128__) || .def(__CX16__) ; Extended jump table CLSALL := $FF4A + LKUPLA := $FF59 + LKUPSA := $FF5C + PFKEY := $FF65 JSRFAR := $FF6E INDFET := $FF74 INDSTA := $FF77 diff --git a/asminc/cx16.inc b/asminc/cx16.inc index 1c22c99b1..e08215df9 100644 --- a/asminc/cx16.inc +++ b/asminc/cx16.inc @@ -1,5 +1,5 @@ ; -; CX16 definitions +; CX16 r35 definitions ; ; --------------------------------------------------------------------------- @@ -44,11 +44,128 @@ ; --------------------------------------------------------------------------- ; Zero page +; GEOS and graphics pseudo-registers +.struct gREG + .org $02 + .union + r0 .word + .struct + r0L .byte + r0H .byte + .endstruct + .endunion + .union + r1 .word + .struct + r1L .byte + r1H .byte + .endstruct + .endunion + .union + r2 .word + .struct + r2L .byte + r2H .byte + .endstruct + .endunion + .union + r3 .word + .struct + r3L .byte + r3H .byte + .endstruct + .endunion + .union + r4 .word + .struct + r4L .byte + r4H .byte + .endstruct + .endunion + .union + r5 .word + .struct + r5L .byte + r5H .byte + .endstruct + .endunion + .union + r6 .word + .struct + r6L .byte + r6H .byte + .endstruct + .endunion + .union + r7 .word + .struct + r7L .byte + r7H .byte + .endstruct + .endunion + .union + r8 .word + .struct + r8L .byte + r8H .byte + .endstruct + .endunion + .union + r9 .word + .struct + r9L .byte + r9H .byte + .endstruct + .endunion + .union + r10 .word + .struct + r10L .byte + r10H .byte + .endstruct + .endunion + .union + r11 .word + .struct + r11L .byte + r11H .byte + .endstruct + .endunion + .union + r12 .word + .struct + r12L .byte + r12H .byte + .endstruct + .endunion + .union + r13 .word + .struct + r13L .byte + r13H .byte + .endstruct + .endunion + .union + r14 .word + .struct + r14L .byte + r14H .byte + .endstruct + .endunion + .union + r15 .word + .struct + r15L .byte + r15H .byte + .endstruct + .endunion +.endstruct + ; Kernal FNAM := $84 ; Pointer to filename KTEMP2 := $86 ; 2 bytes for temporary storage -SCREEN_PTR := $88 ; Pointer to current row on text screen (16 bits) -IMPARM := $8A ; Pointer for PRIMM function +IMPARM := $88 ; Pointer for PRIMM function +SCREEN_PTR := $90 ; Pointer to current row on text screen (16 bits) ; BASIC TXTPTR := $EE ; Pointer into BASIC source code @@ -58,41 +175,27 @@ TXTPTR := $EE ; Pointer into BASIC source code BASIC_BUF := $0200 ; Location of command-line BASIC_BUF_LEN = 81 ; Maximum length of command-line -CURS_COLOR := $027E ; Color under the cursor -CHARCOLOR := $0286 ; Cursor's color nybbles (high: background, low: foreground) -STATUS := $0287 ; Status from previous I/O operation -IN_DEV := $028E ; Current input device number -OUT_DEV := $028F ; Current output device number -TIME := $0292 ; 60 Hz. clock (3 bytes, big-endian) -FNAM_LEN := $0298 ; Length of filename -SECADR := $029A ; Secondary address -DEVNUM := $029B ; Device number -KEY_COUNT := $029E ; Number of keys in input buffer -RVS := $029F ; Reverse flag -CURS_FLAG := $02A3 ; 1 = cursor off -CURS_BLINK := $02A4 ; Blink counter -CURS_CHAR := $02A5 ; Character under the cursor -CURS_STATE := $02A6 ; Cursor blink state -CURS_X := $02A8 ; Cursor column -CURS_Y := $02AB ; Cursor row -LLEN := $02AE ; Line length -NLINES := $02AF ; Number of screen lines -JOY1 := $02BC ; 3 bytes of NES/SNES gamepad data -JOY2 := $02BF +STATUS := $0275 ; Status from previous I/O operation +IN_DEV := $0279 ; Current input device number +OUT_DEV := $027A ; Current output device number +FNAM_LEN := $027D ; Length of filename +SECADR := $027F ; Secondary address +DEVNUM := $0280 ; Device number +CURS_COLOR := $0373 ; Color under the cursor +CHARCOLOR := $0377 ; Cursor's color nybbles (high: background, low: foreground) +RVS := $0378 ; Reverse flag +CURS_FLAG := $037C ; 1 = cursor off +CURS_BLINK := $037D ; Blink counter +CURS_CHAR := $037E ; Character under the cursor +CURS_STATE := $037F ; Cursor blink state +CURS_X := $0381 ; Cursor column +CURS_Y := $0384 ; Cursor row +LLEN := $0387 ; Line length +NLINES := $0388 ; Number of screen lines ; BASIC -VARTAB := $02DD ; Pointer to start of BASIC variables -MEMSIZE := $02E5 ; Pointer to highest BASIC RAM location (+1) - -; Kernal mouse -MSEPAR := $0371 ; mouse: $8x=sprite on, 1/2: scale -MOUSEL := $0372 ; min. x co-ordinate -MOUSER := $0374 ; max. x co-ordinate -MOUSET := $0376 ; min. y co-ordinate -MOUSEB := $0378 ; max. y co-ordinate -MOUSEX := $037A ; x co-ordinate -MOUSEY := $037C ; y co-ordinate -MOUSEBT := $037E ; buttons (bits 2: middle, 1: right, 0: left) +VARTAB := $03E3 ; Pointer to start of BASIC variables +MEMSIZE := $03EB ; Pointer to highest BASIC RAM location (+1) ; --------------------------------------------------------------------------- ; Vector and other locations @@ -141,8 +244,13 @@ NMIVec := $0318 SPR_COLLIDED = %00000100 UART_IRQ = %00001000 .endenum + ; Internal RAM and registers - VRAM := $000000 + + .struct + .org $000000 + VRAM .res $020000 ; 128 Kibibytes + .endstruct .scope COMPOSER ; Display composer .struct .org $0F0000 @@ -226,15 +334,29 @@ NMIVec := $0318 .scope SPRITE .struct .org $0F4000 - CTRL .byte ; Enables sprites + CTRL .byte ; Enables sprite engine COLLISION .byte .endstruct + .struct ATTRIB ; Sprite attributes + .org $0F5000 + ADDR .addr ; Address and color mode + XX .word + YY .word + Z_FLIP .byte + SIZE_PAL .byte + .endstruct .enum FLIP NONE = 0 HORIZ VERT BOTH .endenum + .enum DEPTH + DISABLE = 0 << 2 + CANVAS = 1 << 2 + LAYER0 = 2 << 2 + LAYER1 = 3 << 2 + .endenum .enum ; Sprite geometry WIDTH8 = 0 << 4 WIDTH16 = 1 << 4 @@ -247,13 +369,6 @@ NMIVec := $0318 COLORS16 = 0 << 7 COLORS256 = 1 << 7 .endenum - .enum DEPTH - DISABLE = 0 << 2 - CANVAS = 1 << 2 - LAYER0 = 2 << 2 - LAYER1 = 3 << 2 - .endenum - ATTRIB := $0F5000 ; Sprite attributes .endscope AUDIO := $0F6000 .scope SPI @@ -334,3 +449,15 @@ NMIVec := $0318 KEYMAP .byte ; Current keyboard layout number (Read-Only) DETECT .byte 2 ; If is "16" string, then running on emulator (RO) .endstruct + +; --------------------------------------------------------------------------- +; Banked RAM and ROM + +KEY_COUNT := $A00A ; (bank 0) Number of keys in input buffer +TIMER := $A03E ; (bank 0) 60 Hz. timer (3 bytes, big-endian) + +.struct BANK + .org $A000 + RAM .res $2000 ; 8 Kibibyte window into 512 Kibibytes or 2048 Kibibytes + ROM .res $4000 ; 16 Kibibyte window into 128 Kibibytes +.endstruct diff --git a/cfg/cx16-asm.cfg b/cfg/cx16-asm.cfg index 4228f6da5..3c24bd56f 100644 --- a/cfg/cx16-asm.cfg +++ b/cfg/cx16-asm.cfg @@ -6,7 +6,7 @@ SYMBOLS { __HIMEM__: type = weak, value = $9F00; } MEMORY { - ZP: file = "", start = $0002, size = $0080 - $0002, define = yes; + ZP: file = "", start = $0022, size = $0080 - $0022, define = yes; LOADADDR: file = %O, start = %S - 2, size = $0002; MAIN: file = %O, start = %S, size = __HIMEM__ - %S; } diff --git a/cfg/cx16-bank.cfg b/cfg/cx16-bank.cfg index ff5dded3d..1f998f188 100644 --- a/cfg/cx16-bank.cfg +++ b/cfg/cx16-bank.cfg @@ -11,13 +11,13 @@ SYMBOLS { __BANKRAMSIZE__: type = weak, value = $2000; # 8K banked RAM } MEMORY { - ZP: file = "", define = yes, start = $0002, size = $0080 - $0002; + ZP: file = "", define = yes, start = $0022, size = $0080 - $0022; 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 = __HIMEM__ - __HEADER_LAST__; BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __ONCE_RUN__ - __STACKSIZE__; - BRAM00ADDR: file = "%O.00", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM00: file = "%O.00", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; +# BRAM00ADDR: file = "%O.00", start = __BANKRAMSTART__ - 2, size = $0002; +# BRAM00: file = "%O.00", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; BRAM01ADDR: file = "%O.01", start = __BANKRAMSTART__ - 2, size = $0002; BRAM01: file = "%O.01", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; BRAM02ADDR: file = "%O.02", start = __BANKRAMSTART__ - 2, size = $0002; @@ -62,8 +62,8 @@ SEGMENTS { INIT: load = MAIN, type = rw; ONCE: load = MAIN, type = ro, define = yes; BSS: load = BSS, type = bss, define = yes; - BRAM00ADDR: load = BRAM00ADDR, type = ro, optional = yes; - BANKRAM00: load = BRAM00, type = rw, define = yes, optional = yes; +# BRAM00ADDR: load = BRAM00ADDR, type = ro, optional = yes; +# BANKRAM00: load = BRAM00, type = rw, define = yes, optional = yes; BRAM01ADDR: load = BRAM01ADDR, type = ro, optional = yes; BANKRAM01: load = BRAM01, type = rw, define = yes, optional = yes; BRAM02ADDR: load = BRAM02ADDR, type = ro, optional = yes; diff --git a/cfg/cx16.cfg b/cfg/cx16.cfg index c72f6c35d..72fc2fe91 100644 --- a/cfg/cx16.cfg +++ b/cfg/cx16.cfg @@ -8,7 +8,7 @@ SYMBOLS { __HIMEM__: type = weak, value = $9F00; } MEMORY { - ZP: file = "", define = yes, start = $0002, size = $0080 - $0002; + ZP: file = "", define = yes, start = $0022, size = $0080 - $0022; 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 = __HIMEM__ - __HEADER_LAST__; diff --git a/doc/cx16.sgml b/doc/cx16.sgml index 2136265bc..ca9a50ed6 100644 --- a/doc/cx16.sgml +++ b/doc/cx16.sgml @@ -62,7 +62,7 @@ Special locations: <tag/Bank RAM/ Bank RAM is located at $A000 - $BFFF. It's an eight-Kibibyte - window into a half Mibibyte or two Mibibytes of banked RAM. + window into a half Mebibyte or two Mebibytes of banked RAM. <tag/Bank ROM/ Bank ROM is located at $C000 - $FFFF. It's a sixteen-Kibibyte @@ -229,8 +229,9 @@ point to <tt/cX16-std.joy (cx16_std_joy)/. <descrip> <tag><tt/cX16-std.joy (cX16_std_joy)/</tag> Supports up to two NES (and SNES) controllers connected to the joystick ports - of the CX16. It reads the four directions, and the A, B, Select, and Start - buttons. Buttons A and B are the primary and secondary fire buttons. + of the CX16. It reads the four directions, and the <bf/A/, <bf/B/, + <bf/Select/, and <bf/Start/ buttons. Buttons <bf/A/ and <bf/B/ are + the first and second fire buttons. </descrip><p> @@ -243,6 +244,9 @@ point to <tt/cX16-std.mou (cx16_std_mou)/. <tag><tt/cX16-std.mou (cX16_std_mou)/</tag> Supports a standard 3-button mouse connected to the PS/2 mouse port of the Commander X16. + + Currently (r35), this driver doesn't support <tt/mouse_move()/ + and <tt/mouse_setbox()/. </descrip><p> diff --git a/include/cbm.h b/include/cbm.h index 96eb675cd..56b5b2947 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -168,7 +168,7 @@ unsigned char __fastcall__ kbrepeat (unsigned char mode); #if !defined(__CBM610__) && !defined(__PET__) void waitvsync (void); -/* Wait for the start of the next frame */ +/* Wait for the start of the next video field. */ #endif /*****************************************************************************/ diff --git a/include/cx16.h b/include/cx16.h index d7ed15d2a..c6638cef4 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -44,7 +44,19 @@ +/* Additional output character codes */ +#define CH_COLOR_SWAP 0x01 +#define CH_UNDERLINE 0x04 +#define CH_BOLD 0x06 +#define CH_BACKSPACE 0x08 +#define CH_ITALIC 0x0B +#define CH_OUTLINE 0x0C +#define CH_FONT_ISO 0x0F +#define CH_FONT_PET 0x8F + /* Additional key defines */ +#define CH_SHIFT_TAB 0x18 +#define CH_HELP 0x84 #define CH_F1 0x85 #define CH_F2 0x89 #define CH_F3 0x86 @@ -163,7 +175,7 @@ struct __emul { }; #define EMULATOR (*(volatile struct __emul)0x9FB0) -/* An array window into the half Mibibyte or two Mibibytes of banked RAM */ +/* An array window into the half Mebibyte or two Mebibytes of banked RAM */ #define BANK_RAM ((unsigned char[0x2000])0xA000) diff --git a/libsrc/cbm/clock.s b/libsrc/cbm/clock.s index b5fa6e89b..90e4263a8 100644 --- a/libsrc/cbm/clock.s +++ b/libsrc/cbm/clock.s @@ -1,19 +1,28 @@ ; -; Ullrich von Bassewitz, 21.09.1998 +; 1998-09-21, Ullrich von Bassewitz +; 2019-12-25, Greg King ; ; clock_t clock (void); ; - .include "cbm.inc" - .export _clock .importzp sreg + .include "cbm.inc" + .macpack cpu + .proc _clock - lda #0 ; Byte 3 is always zero - sta sreg+1 +; Some accelerator adaptors have CMOS ICs. + +.if (.cpu & ::CPU_ISET_65SC02) + stz sreg + 1 +.else + lda #$00 ; Byte 3 always is zero + sta sreg + 1 +.endif + jsr RDTIM sty sreg rts diff --git a/libsrc/cx16/_scrsize.s b/libsrc/cx16/_scrsize.s index f240b1e52..6b848078c 100644 --- a/libsrc/cx16/_scrsize.s +++ b/libsrc/cx16/_scrsize.s @@ -1,10 +1,6 @@ ; -; Ullrich von Bassewitz, 26.10.2000 -; ; Screen size variables ; - .export screensize .import SCREEN - -screensize := SCREEN + .export screensize := SCREEN diff --git a/libsrc/cx16/bankramaddr.s b/libsrc/cx16/bankramaddr.s index 53d96e916..7736f8692 100644 --- a/libsrc/cx16/bankramaddr.s +++ b/libsrc/cx16/bankramaddr.s @@ -1,7 +1,7 @@ ; -; 2019-09-16, Greg King +; 2019-12-21, Greg King ; -; This module supplies the load addresses that are expected +; This module supplies some load addresses that are expected ; by a Commander X16 in the first two bytes of banked RAM load files. ; @@ -9,9 +9,11 @@ ; this module to get included into the output files. .export __BANKRAMADDR__: abs = 1 +.if 0 ; bank 0 is used by Kernal .segment "BRAM00ADDR" .addr *+2 +.endif .segment "BRAM01ADDR" diff --git a/libsrc/cx16/cgetc.s b/libsrc/cx16/cgetc.s index 2c5ea76d1..2372b431a 100644 --- a/libsrc/cx16/cgetc.s +++ b/libsrc/cx16/cgetc.s @@ -1,5 +1,5 @@ ; -; 2019-10-01, Greg King +; 2019-12-22, Greg King ; ; char cgetc (void); ; /* Return a character from the keyboard. */ @@ -7,13 +7,13 @@ .export _cgetc - .import cursor, GETIN + .import _kbhit, cursor, GETIN .include "cx16.inc" .macpack generic -_cgetc: ldx KEY_COUNT ; Get number of characters +_cgetc: jsr _kbhit bnz L3 ; Jump if there are already chars waiting ; Switch the cursor on if wanted. @@ -22,7 +22,7 @@ _cgetc: ldx KEY_COUNT ; Get number of characters tay lda cursor jsr setcursor -L1: lda KEY_COUNT +L1: jsr _kbhit bze L1 ; Wait for key tya eor #%00000001 ; (Cursor flag uses negative logic) diff --git a/libsrc/cx16/clock.s b/libsrc/cx16/clock.s new file mode 100644 index 000000000..9af215e0f --- /dev/null +++ b/libsrc/cx16/clock.s @@ -0,0 +1,36 @@ +; +; 1998-09-21, Ullrich von Bassewitz +; 2019-12-25, Greg King +; +; clock_t clock (void); +; + + .constructor initclock + .export _clock + + .import SETTIM, RDTIM + .importzp sreg + + +; clock() counts the amount of time that the process has run. +; Therefore, reset it when the program begins. + +.proc initclock + + lda #$00 + tax + tay + jmp SETTIM + +.endproc + + + +.proc _clock + + stz sreg + 1 ; Byte 3 always is zero + jsr RDTIM + sty sreg + rts + +.endproc diff --git a/libsrc/cx16/crt0.s b/libsrc/cx16/crt0.s index bfb4de10d..52deeb76f 100644 --- a/libsrc/cx16/crt0.s +++ b/libsrc/cx16/crt0.s @@ -1,5 +1,5 @@ ; -; Start-up code for cc65 (CX16 version) +; Start-up code for cc65 (CX16 r35 version) ; .export _exit @@ -46,7 +46,7 @@ _exit: jsr donelib -.if 0 ; We no longer need to preserve zero-page space for cc65's variables. +.if 0 ; We don't need to preserve zero-page space for cc65's variables. ; Copy back the zero-page stuff. ldx #zpspace-1 @@ -83,14 +83,14 @@ init: and #<~$07 sta VIA1::PRB -; Change to the first RAM bank. +; Change to the second RAM bank. lda VIA1::PRA2 sta ramsave ; Save the current RAM bank number - lda #$00 ; Choose RAM bank zero + lda #$01 sta VIA1::PRA2 -.if 0 ; We no longer need to preserve zero-page space for cc65's variables. +.if 0 ; We don't need to preserve zero-page space for cc65's variables. ; Save the zero-page locations that we need. ldx #zpspace-1 @@ -107,7 +107,7 @@ L1: lda sp,x sta sp stx sp+1 ; Set argument stack ptr -; Switch to the second charset. +; Switch to the lower/UPPER PetSCII charset. lda #$0E jsr CHROUT diff --git a/libsrc/cx16/get_tv.s b/libsrc/cx16/get_tv.s index 79a577dff..291a32cde 100644 --- a/libsrc/cx16/get_tv.s +++ b/libsrc/cx16/get_tv.s @@ -1,5 +1,5 @@ ; -; 2019-09-20, Greg King +; 2019-12-22, Greg King ; ; unsigned char get_tv (void); ; /* Return the video mode the machine is using. */ @@ -11,9 +11,6 @@ .proc _get_tv - php - sei ; Don't let interrupts interfere - ; Point to the video output register. stz VERA::CTRL ; Use port 0 @@ -25,7 +22,6 @@ sty VERA::ADDR+2 lda VERA::DATA0 - plp ; Re-enable interrupts and #$07 ; Get the type of output signal rts .endproc diff --git a/libsrc/cx16/joy/cx16-std.s b/libsrc/cx16/joy/cx16-std.s index b41c6606c..5c10c0592 100644 --- a/libsrc/cx16/joy/cx16-std.s +++ b/libsrc/cx16/joy/cx16-std.s @@ -1,8 +1,8 @@ ; ; Standard joystick driver for the CX16. -; May be installed multiple times when statically linked to the application. +; May be installed multiple times when statically linked to an application. ; -; 2019-11-15 Greg King +; 2019-12-24, Greg King ; .include "joy-kernel.inc" @@ -14,6 +14,8 @@ .macpack generic .macpack module + .importzp tmp1 + ; ------------------------------------------------------------------------ ; Header. Includes jump table @@ -75,51 +77,21 @@ COUNT: lda #<JOY_COUNT ; ------------------------------------------------------------------------ ; READ: Read a particular joystick passed in .A . -READ: php - bit #JOY_COUNT - $01 - sei - bnz pad2 +READ: and #%00000001 + jsr JOYSTICK_GET + sta tmp1 + txa + bit #%00001110 ; Is it NES or SNES controller? + bze nes -; Read game pad 1 - -pad1: ldy JOY1 ; Allow JOY1 to be reread between interrupts - sty JOY1 + 2 - - lda JOY1 + 1 - bit #%00001110 - bze nes1 - - asl JOY1 + 2 ; Get SNES's B button + asl tmp1 ; Get SNES's B button ror a ; Put it next to the A button - asl JOY1 + 2 ; Drop SNES's Y button + asl tmp1 ; Drop SNES's Y button asl a ; Get back the B button - ror JOY1 + 2 + ror tmp1 asl a ; Get SNES's A button - ror JOY1 + 2 ; Make byte look like NES pad + ror tmp1 ; Make byte look like NES pad -nes1: lda JOY1 + 2 - plp - eor #%11111111 ; (The controllers use negative logic) - rts - -; Read game pad 2 - -pad2: ldy JOY2 - sty JOY2 + 2 - - lda JOY2 + 1 - bit #%00001110 - bze nes2 - - asl JOY2 + 2 - ror a - asl JOY2 + 2 - asl a - ror JOY2 + 2 - asl a - ror JOY2 + 2 - -nes2: lda JOY2 + 2 - plp - eor #%11111111 +nes: lda tmp1 ; The controllers give zeroes for "pressed" + eor #%11111111 ; We want ones for "pressed" rts diff --git a/libsrc/cx16/joyref.s b/libsrc/cx16/joyref.s index fb21918c4..edd89fba6 100644 --- a/libsrc/cx16/joyref.s +++ b/libsrc/cx16/joyref.s @@ -1,5 +1,5 @@ ; -; 2019-11-14, Greg King +; 2019-12-22, Greg King ; ; Link an interrupt handler if joysticks are used by a program. ; @@ -14,7 +14,7 @@ joy_libref: lda VERA::IRQ_FLAGS lsr a bcc not_vsync - jsr GETJOY ; Bit-bang game controllers + jsr JOYSTICK_SCAN ; Bit-bang game controllers clc ; Let other Jiffy handlers run not_vsync: rts diff --git a/libsrc/cx16/kbhit.s b/libsrc/cx16/kbhit.s index a73533e20..34afdeba4 100644 --- a/libsrc/cx16/kbhit.s +++ b/libsrc/cx16/kbhit.s @@ -1,5 +1,5 @@ ; -; 2019-11-06, Greg King +; 2019-12-22, Greg King ; ; unsigned char kbhit (void); ; /* Returns non-zero (true) if a typed character is waiting. */ @@ -11,7 +11,10 @@ .proc _kbhit + ldy VIA1::PRA2 ; (KEY_COUNT is in RAM bank 0) + stz VIA1::PRA2 lda KEY_COUNT ; Get number of characters + sty VIA1::PRA2 tax ; High byte of return (only its zero/nonzero ... - rts ; ... state matters) + rts ; ... state matters) .endproc diff --git a/libsrc/cx16/kernal.s b/libsrc/cx16/kernal.s index 97443c824..ccd52d632 100644 --- a/libsrc/cx16/kernal.s +++ b/libsrc/cx16/kernal.s @@ -1,60 +1,94 @@ ; -; 2019-11-05, Greg King +; 2019-12-22, Greg King ; ; CX16 Kernal functions ; .include "cbm_kernal.inc" - .export GETJOY - .export MOUSE - .export SCRMOD + .export FB_INIT + .export FB_GET_INFO + .export FB_SET_PALETTE + .export FB_CURSOR_POSITION + .export FB_CURSOR_NEXT_LINE + .export FB_GET_PIXEL + .export FB_GET_PIXELS + .export FB_SET_PIXEL + .export FB_SET_PIXELS + .export FB_SET_8_PIXELS + .export FB_SET_8_PIXELS_OPAQUE + .export FB_FILL_PIXELS + .export FB_FILTER_PIXELS + .export FB_MOVE_PIXELS + .export GRAPH_INIT + .export GRAPH_CLEAR + .export GRAPH_SET_WINDOW + .export GRAPH_SET_COLORS + .export GRAPH_DRAW_LINE + .export GRAPH_DRAW_RECT + .export GRAPH_MOVE_RECT + .export GRAPH_DRAW_OVAL + .export GRAPH_DRAW_IMAGE + .export GRAPH_SET_FONT + .export GRAPH_GET_CHAR_SIZE + .export GRAPH_PUT_CHAR + .export RESTORE_BASIC + .export CLOCK_SET_DATE_TIME + .export CLOCK_GET_DATE_TIME + .export JOYSTICK_SCAN + .export JOYSTICK_GET + .export SCRMOD + .export MOUSE_CONFIG + .export MOUSE_GET - .export CLSALL - .export JSRFAR - .export INDFET - .export INDSTA - .export INDCMP - .export PRIMM + .export CLSALL + .export LKUPLA + .export LKUPSA + .export PFKEY + .export JSRFAR + .export INDFET + .export INDSTA + .export INDCMP + .export PRIMM - .export CINT - .export IOINIT - .export RAMTAS - .export RESTOR - .export VECTOR - .export SETMSG - .export SECOND - .export TKSA - .export MEMTOP - .export MEMBOT - .export SCNKEY - .export SETTMO - .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 PLOT - .export IOBASE + .export CINT + .export IOINIT + .export RAMTAS + .export RESTOR + .export VECTOR + .export SETMSG + .export SECOND + .export TKSA + .export MEMTOP + .export MEMBOT + .export SCNKEY + .export SETTMO + .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 PLOT + .export IOBASE diff --git a/libsrc/cx16/mcbdefault.s b/libsrc/cx16/mcbdefault.s index d817b9ae6..3dda1c711 100644 --- a/libsrc/cx16/mcbdefault.s +++ b/libsrc/cx16/mcbdefault.s @@ -1,53 +1,63 @@ ; ; Default mouse callbacks for the CX16 ; -; 2019-11-09, Greg King +; 2019-12-25, Greg King ; -; All functions in this module should be interrupt safe +; All functions in this module should be interrupt-safe ; because they might be called from an interrupt handler. ; .export _mouse_def_callbacks - .include "cbm_kernal.inc" .include "cx16.inc" -; -------------------------------------------------------------------------- -; Hide the mouse pointer. Always called with interrupts disabled. -.code - -hide: ldx #$00 ; Don't change sprite's scale - lda #$00 ; Disable sprite - jmp MOUSE +msprite: + stz VERA::CTRL ; set address for VERA's data port zero + lda #<(VERA::SPRITE::ATTRIB::Z_FLIP + 0 * 8) + ldx #>(VERA::SPRITE::ATTRIB::Z_FLIP + 0 * 8) + ldy #^(VERA::SPRITE::ATTRIB::Z_FLIP + 0 * 8) | VERA::INC0 + sta VERA::ADDR + stx VERA::ADDR+1 + sty VERA::ADDR+2 + rts ; -------------------------------------------------------------------------- -; Show the mouse pointer. Always called with interrupts disabled. +; Hide the mouse pointer. -show: ldx #$00 - lda #<-$01 ; Enable sprite - jmp MOUSE +hide: jsr msprite + lda VERA::DATA0 + and #<~VERA::SPRITE::DEPTH::LAYER1 + sta VERA::DATA0 + rts ; -------------------------------------------------------------------------- -; Prepare to move the mouse pointer. Always called with interrupts disabled. +; Show the mouse pointer. + +show: jsr msprite + lda VERA::DATA0 + ora #VERA::SPRITE::DEPTH::LAYER1 + sta VERA::DATA0 + rts + +; -------------------------------------------------------------------------- +; Prepare to move the mouse pointer. prep: ; Fall through ; -------------------------------------------------------------------------- -; Draw the mouse pointer. Always called with interrupts disabled. +; Draw the mouse pointer. draw: ; Fall through ; -------------------------------------------------------------------------- -; Move the mouse pointer X position to the value in .XA . Always called with -; interrupts disabled. +; Move the mouse pointer X position to the value in .XA . movex: ; Already set by drivers ; Fall through ; -------------------------------------------------------------------------- -; Move the mouse pointer Y position to the value in .XA . Always called with -; interrupts disabled. +; Move the mouse pointer Y position to the value in .XA . movey: rts ; Already set by drivers diff --git a/libsrc/cx16/mou/cx16-std.s b/libsrc/cx16/mou/cx16-std.s index eb3f83167..0d046bbc2 100644 --- a/libsrc/cx16/mou/cx16-std.s +++ b/libsrc/cx16/mou/cx16-std.s @@ -1,7 +1,7 @@ ; ; Driver for the Commander X16 Kernal's mouse driver. ; -; 2019-11-16, Greg King +; 2019-12-25, Greg King ; .include "zeropage.inc" @@ -66,18 +66,16 @@ SCREEN_HEIGHT = 480 - 1 ;---------------------------------------------------------------------------- ; Global variables. +XPos := ptr3 ; Current mouse position, X +YPos := ptr4 ; Current mouse position, Y + .bss -XPos := MOUSEX ; Current mouse position, X -YPos := MOUSEY ; Current mouse position, Y - -XMin := MOUSEL ; X1 value of bounding box -XMax := MOUSER ; X2 value of bounding box -YMin := MOUSET ; Y1 value of bounding box -YMax := MOUSEB ; Y2 value of bounding box -Box := XMin - -Buttons := MOUSEBT ; button status bits +Box: +XMin: .res 2 ; X1 value of bounding box +XMax: .res 2 ; X2 value of bounding box +YMin: .res 2 ; Y1 value of bounding box +YMax: .res 2 ; Y2 value of bounding box .rodata @@ -121,22 +119,22 @@ INSTALL: bpl @L1 ldx #$00 ; Don't change sprite's scale - lda #$01 ; Initiate and show sprite - jsr MOUSE + lda #$01 ; Create sprite + jsr MOUSE_CONFIG ; Be sure the mouse cursor is invisible, and at the default location. We ; need to do that here, because the mouse interrupt handler might not set ; the mouse position if it hasn't changed. - sei jsr CHIDE +.if 0 lda XPos ldx XPos+1 jsr CMOVEX lda YPos ldx YPos+1 jsr CMOVEY - cli +.endif ; Done, return zero @@ -148,7 +146,10 @@ INSTALL: ; UNINSTALL routine -- is called before the driver is removed from memory. ; No return code required (the driver is removed from memory on return). -UNINSTALL := HIDE ; Hide cursor on exit +UNINSTALL: ; Disable mouse on exit + lda #$00 + tax + jmp MOUSE_CONFIG ;---------------------------------------------------------------------------- ; HIDE routine -- is called to hide the mouse pointer. The mouse kernel manages @@ -181,6 +182,7 @@ SETBOX: sta ptr1 lda (ptr1) ldy #$01 + php sei sta XMin lda (ptr1),y @@ -191,10 +193,12 @@ SETBOX: sta ptr1 iny lda (ptr1),y sta YMax - cli + plp rts +;; Note: SETBOX and GETBOX currently have no effect! + ;---------------------------------------------------------------------------- ; GETBOX: Return the mouse bounding box. The parameters are passed as they ; come from the C program, that is, a pointer to a mouse_box struct in .XA . @@ -222,7 +226,10 @@ GETBOX: sta ptr1 ; No checks are done to see if the new position is valid (within ; the bounding box or the screen). No return code required. -MOVE: sei ; No interrupts +;; Note: This function currently has no effect! + +MOVE: php + sei ; No interrupts sta YPos stx YPos+1 ; New Y position @@ -237,14 +244,16 @@ MOVE: sei ; No interrupts sta XPos ; New X position jsr CMOVEX ; Move the cursor - cli ; Allow interrupts + plp ; Allow interrupts rts ;---------------------------------------------------------------------------- ; BUTTONS: Return the CBM 1351 button mask in .XA . BUTTONS: - lda Buttons + ldx #XPos + jsr MOUSE_GET + and #%00000111 tax lda ButtMask,x @@ -255,9 +264,9 @@ BUTTONS: ; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1. ; No return code required. -POS: ldy #MOUSE_POS::XCOORD ; Structure offset +POS: jsr BUTTONS - sei ; Disable interrupts +POS1: ldy #MOUSE_POS::XCOORD ; Structure offset lda XPos ; Transfer the position sta (ptr1),y lda XPos+1 @@ -267,8 +276,6 @@ POS: ldy #MOUSE_POS::XCOORD ; Structure offset iny sta (ptr1),y lda YPos+1 - cli ; Enable interrupts - iny sta (ptr1),y ; Store last byte rts ; Done @@ -282,20 +289,15 @@ POS: ldy #MOUSE_POS::XCOORD ; Structure offset ; call mouse_pos to initialize the struct pointer, and fill the position ; fields. -INFO: jsr POS - -; Fill in the button state - - jsr BUTTONS ; Will not touch ptr1 +INFO: jsr BUTTONS ; Will not touch ptr1 ldy #MOUSE_INFO::BUTTONS sta (ptr1),y - rts + jmp POS1 ;---------------------------------------------------------------------------- ; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl ; specific data in ptr1, and the ioctl code in A. ; Must return an error code in .XA . -; IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioctls, for now ldx #>MOUSE_ERR_INV_IOCTL diff --git a/libsrc/cx16/mouse_stat_stddrv.s b/libsrc/cx16/mouse_stat_stddrv.s index 1ff8ad43b..8e0a3ed53 100644 --- a/libsrc/cx16/mouse_stat_stddrv.s +++ b/libsrc/cx16/mouse_stat_stddrv.s @@ -1,7 +1,7 @@ ; ; Address of the static standard mouse driver ; -; 2019-11-08,Greg King +; 2019-11-08, Greg King ; ; const void mouse_static_stddrv[]; ; diff --git a/libsrc/cx16/set_tv.s b/libsrc/cx16/set_tv.s index 8b802f324..c23568c67 100644 --- a/libsrc/cx16/set_tv.s +++ b/libsrc/cx16/set_tv.s @@ -1,5 +1,5 @@ ; -; 2019-11-06, Greg King +; 2019-12-22, Greg King ; ; void __fastcall__ set_tv (unsigned char); ; /* Set the video mode the machine will use. */ @@ -11,9 +11,6 @@ .proc _set_tv - php - sei ; Don't let interrupts interfere - ; Point to the video output register. stz VERA::CTRL ; Use port 0 @@ -25,6 +22,5 @@ stx VERA::ADDR+2 sta VERA::DATA0 - plp ; Re-enable interrupts rts .endproc diff --git a/libsrc/cx16/sysuname.s b/libsrc/cx16/sysuname.s index f8500936b..4aefb7cf5 100644 --- a/libsrc/cx16/sysuname.s +++ b/libsrc/cx16/sysuname.s @@ -9,7 +9,7 @@ .import utscopy -__sysuname := utscopy +__sysuname := utscopy ;-------------------------------------------------------------------------- ; Data. We define a fixed utsname struct here, and just copy it. diff --git a/libsrc/cx16/tgi_stat_stddrv.s b/libsrc/cx16/tgi_stat_stddrv.s index 566a36393..e501f4c2f 100644 --- a/libsrc/cx16/tgi_stat_stddrv.s +++ b/libsrc/cx16/tgi_stat_stddrv.s @@ -1,11 +1,10 @@ ; ; Address of the static standard TGI driver ; -; 2019-11-06, Greg King +; 2019-12-22, Greg King ; ; const void tgi_static_stddrv[]; ; - .import _cx16_640x4c_tgi - - .export _tgi_static_stddrv := _cx16_640x4c_tgi + .import _cx16_320x8b_tgi + .export _tgi_static_stddrv := _cx16_320x8b_tgi diff --git a/libsrc/cx16/tgi_stddrv.s b/libsrc/cx16/tgi_stddrv.s index 0f77e7340..0e46a6cb3 100644 --- a/libsrc/cx16/tgi_stddrv.s +++ b/libsrc/cx16/tgi_stddrv.s @@ -1,7 +1,7 @@ ; ; Name of the standard TGI driver ; -; 2019-11-06, Greg King +; 2019-12-22, Greg King ; ; const char tgi_stddrv[]; ; @@ -9,5 +9,4 @@ .export _tgi_stddrv .rodata - -_tgi_stddrv: .asciiz "cx16-640x4c.tgi" +_tgi_stddrv: .asciiz "cx16-320x8b.tgi" diff --git a/libsrc/cx16/vset.s b/libsrc/cx16/vaddr0.s similarity index 60% rename from libsrc/cx16/vset.s rename to libsrc/cx16/vaddr0.s index 9178850ea..384bf3503 100644 --- a/libsrc/cx16/vset.s +++ b/libsrc/cx16/vaddr0.s @@ -1,19 +1,18 @@ ; -; 2019-10-22, Greg King +; 2019-12-22, Greg King ; ; Set the __far__ address that VERA will use for data access. ; This is a support function for the fastcall functions vpeek() and vpoke(). ; - .export vset + .export vaddr0 .importzp sreg .include "cx16.inc" -vset: ldy sreg - sei ; don't let interrupt handlers interfere - stz VERA::CTRL ; set address for VERA's data port zero +vaddr0: stz VERA::CTRL ; set address for VERA's data port zero + ldy sreg sta VERA::ADDR stx VERA::ADDR+1 sty VERA::ADDR+2 diff --git a/libsrc/cx16/vpeek.s b/libsrc/cx16/vpeek.s index 0c1a94651..80d4d536f 100644 --- a/libsrc/cx16/vpeek.s +++ b/libsrc/cx16/vpeek.s @@ -1,5 +1,5 @@ ; -; 2019-10-22, Greg King +; 2019-12-22, Greg King ; ; unsigned char fastcall vpeek (unsigned long addr); ; /* Get a byte from a location in VERA's internal address space. */ @@ -7,13 +7,11 @@ .export _vpeek - .import vset + .import vaddr0 .include "cx16.inc" -_vpeek: php ; (vset blocks interrupts) - jsr vset ; put VERA's address +_vpeek: jsr vaddr0 ; put VERA's address ldx #>$0000 lda VERA::DATA0 ; read VERA port zero - plp rts diff --git a/libsrc/cx16/vpoke.s b/libsrc/cx16/vpoke.s index 8c21e9b21..2c8497a5b 100644 --- a/libsrc/cx16/vpoke.s +++ b/libsrc/cx16/vpoke.s @@ -1,5 +1,5 @@ ; -; 2019-10-22, Greg King +; 2019-12-22, Greg King ; ; void fastcall vpoke (unsigned char data, unsigned long addr); ; /* Put a byte into a location in VERA's internal address space. @@ -9,13 +9,11 @@ .export _vpoke - .import vset, popa + .import vaddr0, popa .include "cx16.inc" -_vpoke: php ; (vset blocks interrupts) - jsr vset ; put VERA's address +_vpoke: jsr vaddr0 ; put VERA's address jsr popa sta VERA::DATA0 ; write data to VERA port zero - plp rts diff --git a/libsrc/cx16/waitvsync.s b/libsrc/cx16/waitvsync.s index 09d01c6a1..e8176916b 100644 --- a/libsrc/cx16/waitvsync.s +++ b/libsrc/cx16/waitvsync.s @@ -1,9 +1,10 @@ ; -; 2019-09-26, Greg King +; 2019-12-23, Greg King ; ; void waitvsync (void); +; /* Wait for the start of the next video field. */ ; -; VERA's vertical sync causes IRQs which increment the jiffy clock. +; VERA's vertical sync causes IRQs which increment the jiffy timer. ; .export _waitvsync @@ -11,7 +12,10 @@ .include "cx16.inc" _waitvsync: - lda TIME + 2 -: cmp TIME + 2 + ldx VIA1::PRA2 ; (TIMER is in RAM bank 0) + stz VIA1::PRA2 + lda TIMER + 2 +: cmp TIMER + 2 beq :- ; Wait for next jiffy + stx VIA1::PRA2 rts diff --git a/src/ca65/struct.c b/src/ca65/struct.c index 6d279a701..ecbaa2a71 100644 --- a/src/ca65/struct.c +++ b/src/ca65/struct.c @@ -87,6 +87,7 @@ static long Member (long AllocSize) /* Check the size for a reasonable value */ if (AllocSize >= 0x1000000) { ErrorSkip ("Range error"); + AllocSize = 1; } /* Return the size */ @@ -193,7 +194,13 @@ static long DoStructInternal (long Offs, unsigned Type) if (CurTok.Tok == TOK_SEP) { ErrorSkip ("Address is missing"); } else { - Offs = Member (1); + Offs = ConstExpression (); + + /* Check the address for a reasonable value */ + if (Offs >= 0x1000000) { + ErrorSkip ("Range error"); + Offs = 0; + } } break; From f067c4530fb385137a7458011b082690ac1c705e Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 25 Dec 2019 14:53:32 -0500 Subject: [PATCH 1246/2161] Made the program-chaining exec() handle the X16 emulator's file-system. --- libsrc/cx16/exec.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libsrc/cx16/exec.c b/libsrc/cx16/exec.c index 90af4e406..17a547e68 100644 --- a/libsrc/cx16/exec.c +++ b/libsrc/cx16/exec.c @@ -1,7 +1,7 @@ /* ** Program-chaining function for Commodore platforms. ** -** 2019-11-08, Greg King +** 2019-12-25, Greg King ** ** This function exploits the program-chaining feature in Commander X16 BASIC's ROM. ** @@ -82,12 +82,15 @@ int __fastcall__ exec (const char* progname, const char* cmdline) } utoa (dv, basic.unit, 10); - /* Don't try to run a program that doesn't exist. */ - fd = open (progname, O_RDONLY); - if (fd < 0) { - return _mappederrno (4); /* file not found */ + /* The emulator supports only loading and saving on its file-system. */ + if (dv != 1) { + /* Don't try to run a program that doesn't exist. */ + fd = open (progname, O_RDONLY); + if (fd < 0) { + return _mappederrno (4); /* file not found */ + } + close (fd); } - close (fd); n = 0; do { From b56ba8f073c186339572b091033e1ebcd88191df Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 27 Dec 2019 18:07:37 -0500 Subject: [PATCH 1247/2161] Added real-time clock functions to the cx16 library. --- libsrc/cx16/getres.s | 36 +++++++++++++++++++ libsrc/cx16/gettime.s | 56 +++++++++++++++++++++++++++++ libsrc/cx16/settime.s | 55 +++++++++++++++++++++++++++++ libsrc/cx16/status.s | 16 --------- libsrc/cx16/tmcommon.s | 40 +++++++++++++++++++++ testcode/lib/clock-test.c | 74 ++++++++++++++++++++++----------------- 6 files changed, 229 insertions(+), 48 deletions(-) create mode 100644 libsrc/cx16/getres.s create mode 100644 libsrc/cx16/gettime.s create mode 100644 libsrc/cx16/settime.s delete mode 100644 libsrc/cx16/status.s create mode 100644 libsrc/cx16/tmcommon.s diff --git a/libsrc/cx16/getres.s b/libsrc/cx16/getres.s new file mode 100644 index 000000000..dad237014 --- /dev/null +++ b/libsrc/cx16/getres.s @@ -0,0 +1,36 @@ +; +; 2019-12-26, Greg King +; +; int __fastcall__ clock_getres (clockid_t clk_id, struct timespec *res); +; + + .include "time.inc" + + .importzp ptr1 + .import incsp1, return0 + + +;---------------------------------------------------------------------------- + +.proc _clock_getres + + sta ptr1 + stx ptr1+1 + + ldy #.sizeof(timespec) - 1 +@L1: lda time,y + sta (ptr1),y + dey + bpl @L1 + + jsr incsp1 + jmp return0 + +.endproc + +;---------------------------------------------------------------------------- +; timespec struct with tv_nsec set to approximately 1/60 of a second +.rodata + +time: .dword 0 + .dword 17 * 1000 * 1000 diff --git a/libsrc/cx16/gettime.s b/libsrc/cx16/gettime.s new file mode 100644 index 000000000..336b0f957 --- /dev/null +++ b/libsrc/cx16/gettime.s @@ -0,0 +1,56 @@ +; +; 2019-12-27, Greg King +; +; int __fastcall__ clock_gettime (clockid_t clk_id, struct timespec *tp); +; + + .include "time.inc" + .include "cx16.inc" + + .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1, return0 + .import TM, load_jiffy + .import CLOCK_GET_DATE_TIME + + +;---------------------------------------------------------------------------- + +.proc _clock_gettime + + jsr pushax + jsr pushax + + jsr CLOCK_GET_DATE_TIME + + lda gREG::r0L + sta TM + tm::tm_year + lda gREG::r0H + dec a + sta TM + tm::tm_mon + lda gREG::r1L + sta TM + tm::tm_mday + + lda gREG::r1H + sta TM + tm::tm_hour + lda gREG::r2L + sta TM + tm::tm_min + lda gREG::r2H + 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_jiffy + jsr pusheax + lda gREG::r3L + ldx #>$0000 + jsr tosmul0ax + ldy #timespec::tv_nsec + jsr steaxspidx ; Pops address pushed by 1. pushax + + jsr incsp1 + jmp return0 + +.endproc diff --git a/libsrc/cx16/settime.s b/libsrc/cx16/settime.s new file mode 100644 index 000000000..81749f508 --- /dev/null +++ b/libsrc/cx16/settime.s @@ -0,0 +1,55 @@ +; +; 2019-12-27, Greg King +; +; int __fastcall__ clock_settime (clockid_t clk_id, const struct timespec *tp); +; + + .include "time.inc" + .include "cx16.inc" + + .importzp ptr1 + .import pushax, pusheax, ldax0sp, ldeaxidx + .import tosdiveax, incsp3, return0 + .import load_jiffy + .import CLOCK_SET_DATE_TIME + + +.macro COPY reg, offset + ldy #offset + lda (ptr1),y + sta gREG::reg +.endmac + +;---------------------------------------------------------------------------- + +.proc _clock_settime + + jsr pushax + + .assert timespec::tv_sec = 0, error + jsr _localtime + sta ptr1 + stx ptr1+1 + + COPY r0L, tm::tm_year + COPY r0H, tm::tm_mon + inc gREG::r0H + COPY r1L, tm::tm_mday + COPY r1H, tm::tm_hour + COPY r2L, tm::tm_min + COPY r2H, tm::tm_sec + + jsr ldax0sp ; Get tp + ldy #timespec::tv_nsec+3 + jsr ldeaxidx ; Get nanoseconds + jsr pusheax + jsr load_jiffy + jsr tosdiveax + sta gREG::r3L ; Put number of jiffies + + jsr CLOCK_SET_DATE_TIME + + jsr incsp3 + jmp return0 + +.endproc diff --git a/libsrc/cx16/status.s b/libsrc/cx16/status.s deleted file mode 100644 index e3446637d..000000000 --- a/libsrc/cx16/status.s +++ /dev/null @@ -1,16 +0,0 @@ -; -; 2019-11-05, Greg King -; - - .export ST: zp - -.segment "EXTZP": zp - -; This is a temporary hack. - -; A zero-page copy of the IEC status byte. -; This is needed because the Commander X16's Kernal's status -; variable was moved out of the zero page. But, the common -; CBM file function modules import this as a zero-page variable. - -ST: .res 1 diff --git a/libsrc/cx16/tmcommon.s b/libsrc/cx16/tmcommon.s new file mode 100644 index 000000000..0eed245dc --- /dev/null +++ b/libsrc/cx16/tmcommon.s @@ -0,0 +1,40 @@ +; +; 2019-12-27, Greg King +; +; Common stuff for the clock routines +; + + .export TM, load_jiffy + + .importzp sreg + + +;---------------------------------------------------------------------------- +; Load .EAX with the approximate number of nanoseconds +; in one jiffy (1/60th of a second). + +.proc load_jiffy + + lda #<(17 * 1000 * 1000 / $10000) + ldx #>(17 * 1000 * 1000 / $10000) + sta sreg + stx sreg+1 + lda #<(17 * 1000 * 1000) + ldx #>(17 * 1000 * 1000) + rts + +.endproc + +;---------------------------------------------------------------------------- +; TM struct with "is daylight-saving time" set to "unknown" +.data + +TM: .word 0 ; tm_sec + .word 0 ; tm_min + .word 0 ; tm_hour + .word 0 ; tm_mday + .word 0 ; tm_mon + .word 0 ; tm_year + .word 0 ; tm_wday + .word 0 ; tm_yday + .word .loword(-1) ; tm_isdst diff --git a/testcode/lib/clock-test.c b/testcode/lib/clock-test.c index e3115d2f1..ba4b69e42 100644 --- a/testcode/lib/clock-test.c +++ b/testcode/lib/clock-test.c @@ -1,7 +1,8 @@ -/* Clock test program - * - * 25-Sep-2018, chris@groessler.org - */ +/* Calendar-clock test program +** +** 2018-Sep-25, chris@groessler.org +** 2019-Dec-27, Greg King +*/ #include <stdio.h> #include <stdlib.h> @@ -10,74 +11,83 @@ #include <errno.h> #ifdef __CC65__ -#include <conio.h> -#include <cc65.h> -#endif /* #ifdef __CC65__ */ + #include <conio.h> + #include <cc65.h> +#endif -static void print_time(void) +static int print_time(void) { struct tm *cur_tm; time_t cur_time = time(NULL); + if (cur_time == -1) { printf("time() failed: %s\n", strerror(errno)); - return; + return 1; } cur_tm = localtime(&cur_time); printf("time: %s\n", asctime(cur_tm)); // DEBUG: - printf("mday=%d mon=%d year=%d\nhour=%d min=%d sec=%d\n", cur_tm->tm_mday, cur_tm->tm_mon, cur_tm->tm_year, cur_tm->tm_hour, cur_tm->tm_min, cur_tm->tm_sec); + printf("year=%d, mon=%d, mday=%d\nhour=%d, min=%d, sec=%d\n", + cur_tm->tm_year, cur_tm->tm_mon, cur_tm->tm_mday, + cur_tm->tm_hour, cur_tm->tm_min, cur_tm->tm_sec); + return 0; } int main(int argc, char **argv) { - char c = 0; + char c; int s; struct tm cur_time; struct timespec new_time; #ifdef __CC65__ - /* if DOS will automatically clear the screen after the program exits, wait for a keypress... */ + /* If DOS automatically will clear the screen after the program exits, + ** then wait for a key-press. + */ if (doesclrscrafterexit()) atexit((void (*)(void))cgetc); #endif - if (argc <= 1) { - print_time(); - return 0; + if (argc == 1) { + return print_time(); } - if (argc != 3 || strcasecmp(*(argv + 1), "set")) { - printf("usage: CLOCKTST [set DD-MM-YY-HH-MM-SS]\n"); + if (argc != 2) { +#ifdef __CC65__ + printf("Usage: run:rem [YY-MM-DD-HH-MM-SS]\n"); +#else + printf("Usage: %s [YY-MM-DD-HH-MM-SS]\n", argv[0]); +#endif return 1; } - memset(&cur_time, 0, sizeof(cur_time)); - s = sscanf(*(argv + 2), "%d-%d-%d-%d-%d-%d", &cur_time.tm_mday, &cur_time.tm_mon, &cur_time.tm_year, &cur_time.tm_hour, &cur_time.tm_min, &cur_time.tm_sec); - if (s != 6 || cur_time.tm_year > 99 /* other input values aren't being verified... */) { - printf("invalid time/date format\n"); + memset(&cur_time, 0, sizeof cur_time); + s = sscanf(argv[1], "%d-%d-%d-%d-%d-%d", + &cur_time.tm_year, &cur_time.tm_mon, &cur_time.tm_mday, + &cur_time.tm_hour, &cur_time.tm_min, &cur_time.tm_sec); + if (s != 6 || cur_time.tm_year > 99 /* other input values aren't being verified */) { + printf("Invalid date-time format\n"); return 1; } + cur_time.tm_year += 100; /* assume 21st century */ --cur_time.tm_mon; - if (cur_time.tm_year < 79) - cur_time.tm_year += 100; /* adjust century */ - memset(&new_time, 0, sizeof(new_time)); + memset(&new_time, 0, sizeof new_time); new_time.tv_sec = mktime(&cur_time); - printf("\nyou are about to set the time to\n--> %s\n\nContinue (y/n)?", ctime(&new_time.tv_sec)); - - while (c != 'y' && c != 'Y' && c != 'n' && c != 'N') { + printf("\nYou are about to set the time to\n--> %s\nContinue (y/n)? ", ctime(&new_time.tv_sec)); + do { #ifdef __CC65__ c = cgetc(); #else c = getchar(); #endif - } + } while (c != 'y' && c != 'Y' && c != 'n' && c != 'N'); printf("%c\n", c); if (c == 'n' || c == 'N') { - printf("user abort\n"); + printf("User abort\n"); return 0; } @@ -86,11 +96,11 @@ int main(int argc, char **argv) printf("clock_settime() failed: %s\n", strerror(errno)); return 1; } - printf("time set!\n"); + printf("Time set!\n\n"); + //DEBUG test begin - print_time(); + return print_time(); //DEBUG test end - return 0; } /* Local Variables: */ /* c-file-style: "cpg" */ From 00ab3c2d34b63cdadace7827e2f148db983d48eb Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 30 Dec 2019 19:53:39 -0500 Subject: [PATCH 1248/2161] Fixed the target guards around the usage messages. --- testcode/lib/clock-test.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/testcode/lib/clock-test.c b/testcode/lib/clock-test.c index ba4b69e42..355e69d95 100644 --- a/testcode/lib/clock-test.c +++ b/testcode/lib/clock-test.c @@ -1,7 +1,7 @@ /* Calendar-clock test program ** ** 2018-Sep-25, chris@groessler.org -** 2019-Dec-27, Greg King +** 2019-Dec-30, Greg King */ #include <stdio.h> @@ -54,8 +54,10 @@ int main(int argc, char **argv) } if (argc != 2) { -#ifdef __CC65__ - printf("Usage: run:rem [YY-MM-DD-HH-MM-SS]\n"); +#if defined(__APPLE2__) + printf("USAGE: CALL2051 [:REM YY-MM-DD-HH-MM-SS]\n"); +#elif defined(__ATMOS__) || defined(__CBM__) + printf("Usage: run [:rem YY-MM-DD-HH-MM-SS]\n"); #else printf("Usage: %s [YY-MM-DD-HH-MM-SS]\n", argv[0]); #endif From 5109c0b68f7a2cd07ece07b6812affeab07ae17a Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 2 Jan 2020 04:26:02 -0500 Subject: [PATCH 1249/2161] Made ca65 give error messages when it sees duplicate .define commands. --- src/ca65/pseudo.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index a0eb28699..5b2ef0573 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -821,8 +821,17 @@ static void DoDebugInfo (void) static void DoDefine (void) -/* Define a one line macro */ +/* Define a one-line macro */ { + /* The function is called with the .DEFINE token in place, because we need + ** to disable .define macro expansions before reading the next token. + ** Otherwise, the name of the macro might be expanded; therefore, + ** we never would see it. + */ + DisableDefineStyleMacros (); + NextTok (); + EnableDefineStyleMacros (); + MacDef (MAC_STYLE_DEFINE); } @@ -1871,12 +1880,12 @@ static void DoTag (void) static void DoUnDef (void) -/* Undefine a define style macro */ +/* Undefine a define-style macro */ { /* The function is called with the .UNDEF token in place, because we need ** to disable .define macro expansions before reading the next token. - ** Otherwise the name of the macro would be expanded, so we would never - ** see it. + ** Otherwise, the name of the macro would be expanded; therefore, + ** we never would see it. */ DisableDefineStyleMacros (); NextTok (); @@ -1962,7 +1971,7 @@ static void DoZeropage (void) /* Control commands flags */ enum { ccNone = 0x0000, /* No special flags */ - ccKeepToken = 0x0001 /* Do not skip the current token */ + ccKeepToken = 0x0001 /* Do not skip the control token */ }; /* Control command table */ @@ -2001,7 +2010,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoDbg, }, { ccNone, DoDByt }, { ccNone, DoDebugInfo }, - { ccNone, DoDefine }, + { ccKeepToken, DoDefine }, { ccNone, DoUnexpected }, /* .DEFINED */ { ccNone, DoUnexpected }, /* .DEFINEDMACRO */ { ccNone, DoDelMac }, From 2a421396740049244d85e1591fdec91ae6d5fa08 Mon Sep 17 00:00:00 2001 From: mc78 <mc78@outlook.de> Date: Fri, 29 Nov 2019 11:20:58 +0100 Subject: [PATCH 1250/2161] Changes in INSTALL routine from emd/c128-vdc.s. tmp1 was used at two places resulting in the bug that VDC_CSET was set to garbage on 16k VDC. pagecount and curpage were not reset on INSTALL resulting in non-reentrant code on static linkage of emd driver. --- libsrc/c128/emd/c128-vdc.s | 48 +++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/libsrc/c128/emd/c128-vdc.s b/libsrc/c128/emd/c128-vdc.s index d915fdf25..3f08b0a79 100644 --- a/libsrc/c128/emd/c128-vdc.s +++ b/libsrc/c128/emd/c128-vdc.s @@ -52,13 +52,11 @@ VDC_DATA = 31 ; ------------------------------------------------------------------------ ; Data. -.data - -pagecount: .word 64 ; $0000-$3fff as 16k default -curpage: .word $ffff ; currently mapped-in page (invalid) - .bss +pagecount: .res 1 ; $0000-$3fff as 16k default +curpage: .res 2 ; currently mapped-in page (invalid) +vdc_cset_save: .res 1 window: .res 256 ; memory window .code @@ -71,11 +69,15 @@ window: .res 256 ; memory window ; INSTALL: + ; reset mapped-in page to invalid + lda #$ff + sta curpage + sta curpage+1 + ; do test for VDC presence here??? - ldx #VDC_CSET ; determine size of RAM... jsr vdcgetreg - sta tmp1 + sta vdc_cset_save ora #%00010000 jsr vdcputreg ; turn on 64k @@ -94,35 +96,39 @@ INSTALL: lda tmp2 jsr vdcputbyte ; restore original value of test byte + ldx #0 ; prepare x with hi of default pagecount + lda ptr1 ; do bytes match? cmp ptr1+1 bne @have64k lda ptr2 cmp ptr2+1 bne @have64k - - ldx #VDC_CSET - lda tmp1 - jsr vdcputreg ; restore 16/64k flag - jmp @endok ; and leave default values for 16k - -@have64k: - lda #<256 - ldx #>256 + + lda #64 ; assumes x = 0, here -> p.c = 64 + bne @setpagecnt +@have64k: + txa ; assumes x = 0, here + inx ; so that a/x becomes 0/1 -> p.c. = 256 +@setpagecnt: sta pagecount stx pagecount+1 -@endok: + + ldx #VDC_CSET ; restore 16/64k flag + lda vdc_cset_save + jsr vdcputreg + lda #<EM_ERR_OK ldx #>EM_ERR_OK rts test64k: - sta tmp1 + sta tmp3 sty ptr3 lda #0 sta ptr3+1 jsr settestadr1 - lda tmp1 + lda tmp3 jsr vdcputbyte ; write $55 jsr settestadr1 jsr vdcgetbyte ; read here @@ -199,6 +205,8 @@ transferin: lda VDC_DATA_REG ; get 2 bytes at a time to speed-up sta (ptr2),y ; (in fact up to 8 bytes could be fetched with special VDC config) iny +@L1: bit VDC_ADDR_REG ; XXX: Test waiting for register 31 + bpl @L1 lda VDC_DATA_REG sta (ptr2),y iny @@ -334,6 +342,8 @@ vdcsetsrcaddr: dex tya stx VDC_ADDR_REG +@L1: bit VDC_ADDR_REG ; XXX: Test waiting for register 18 + bpl @L1 sta VDC_DATA_REG rts From 390878e831efdc73fc7698836762952dac53ffd9 Mon Sep 17 00:00:00 2001 From: mc78 <mc78@outlook.de> Date: Fri, 29 Nov 2019 11:47:34 +0100 Subject: [PATCH 1251/2161] Added reservation of second byte for pagecount --- libsrc/c128/emd/c128-vdc.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/c128/emd/c128-vdc.s b/libsrc/c128/emd/c128-vdc.s index 3f08b0a79..842059c3e 100644 --- a/libsrc/c128/emd/c128-vdc.s +++ b/libsrc/c128/emd/c128-vdc.s @@ -54,7 +54,7 @@ VDC_DATA = 31 .bss -pagecount: .res 1 ; $0000-$3fff as 16k default +pagecount: .res 2 ; $0000-$3fff as 16k default curpage: .res 2 ; currently mapped-in page (invalid) vdc_cset_save: .res 1 window: .res 256 ; memory window From 244dc358e55a9b86a7281d40a576355c21268f30 Mon Sep 17 00:00:00 2001 From: mc78 <mc78@outlook.de> Date: Sun, 1 Dec 2019 13:25:14 +0100 Subject: [PATCH 1252/2161] Changed the order in which lo/hi bytes of vdc addr are set according to willimanilys ((z64k) suggestions. Changed offset for vdc ramsize detection from 000 to 000. --- libsrc/c128/emd/c128-vdc.s | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/libsrc/c128/emd/c128-vdc.s b/libsrc/c128/emd/c128-vdc.s index 842059c3e..e359dcdb9 100644 --- a/libsrc/c128/emd/c128-vdc.s +++ b/libsrc/c128/emd/c128-vdc.s @@ -104,7 +104,7 @@ INSTALL: lda ptr2 cmp ptr2+1 bne @have64k - + lda #64 ; assumes x = 0, here -> p.c = 64 bne @setpagecnt @have64k: @@ -113,22 +113,25 @@ INSTALL: @setpagecnt: sta pagecount stx pagecount+1 + + txa + bne @keep64kBit ldx #VDC_CSET ; restore 16/64k flag lda vdc_cset_save - jsr vdcputreg - + jsr vdcputreg +@keep64kBit: lda #<EM_ERR_OK ldx #>EM_ERR_OK rts test64k: - sta tmp3 + sta tmp1 sty ptr3 lda #0 sta ptr3+1 jsr settestadr1 - lda tmp3 + lda tmp1 jsr vdcputbyte ; write $55 jsr settestadr1 jsr vdcgetbyte ; read here @@ -146,7 +149,7 @@ settestadr1: ldy #$02 ; test page 2 (here) .byte $2c settestadr2: - ldy #$42 ; or page 64+2 (there) + ldy #$82 ; or page 64+2 (there) lda #0 jmp vdcsetsrcaddr @@ -334,17 +337,16 @@ COPYTO: ; vdcsetsrcaddr: - ldx #VDC_DATA_LO + ldx #VDC_DATA_HI stx VDC_ADDR_REG @L0: bit VDC_ADDR_REG bpl @L0 sta VDC_DATA_REG - dex - tya + inx stx VDC_ADDR_REG @L1: bit VDC_ADDR_REG ; XXX: Test waiting for register 18 bpl @L1 - sta VDC_DATA_REG + sty VDC_DATA_REG rts vdcgetbyte: From b66f7272af4c566df6205f55296ac365ecbf8c73 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 10 Jan 2020 15:17:23 -0500 Subject: [PATCH 1253/2161] Updated the cx16 library to the ROM's prerelease 36. --- asminc/cbm_kernal.inc | 15 +++- asminc/cx16.inc | 137 +++++++++++++++++++++++++++---------- doc/cx16.sgml | 8 +-- doc/funcref.sgml | 44 ++++++++++-- doc/library.sgml | 118 +++++++++++++++++--------------- include/cbm.h | 1 + include/cx16.h | 84 +++++++++++++++-------- libsrc/cbm/c_settim.s | 16 +++++ libsrc/cx16/clock.s | 1 - libsrc/cx16/color.s | 2 +- libsrc/cx16/crt0.s | 6 +- libsrc/cx16/get_numbanks.s | 20 ++++++ libsrc/cx16/joyref.s | 20 ------ libsrc/cx16/kbhit.s | 8 +-- libsrc/cx16/kernal.s | 14 +++- libsrc/cx16/libref.s | 4 +- libsrc/cx16/mcbdefault.s | 37 +++------- libsrc/cx16/videomode.s | 28 ++++---- libsrc/cx16/waitvsync.s | 8 +-- 19 files changed, 357 insertions(+), 214 deletions(-) create mode 100644 libsrc/cbm/c_settim.s create mode 100644 libsrc/cx16/get_numbanks.s delete mode 100644 libsrc/cx16/joyref.s diff --git a/asminc/cbm_kernal.inc b/asminc/cbm_kernal.inc index 86a60d49b..7125f1253 100644 --- a/asminc/cbm_kernal.inc +++ b/asminc/cbm_kernal.inc @@ -1,11 +1,21 @@ ; ; Olli Savia <ops@iki.fi> +; Greg King ; -; Commodore Kernal functions +; Commodore-compatibles Kernal functions ; .if .def(__CX16__) ; CX16 extended jump table + CONSOLE_INIT := $FEDB + CONSOLE_PUT_CHAR := $FEDE + CONSOLE_GET_CHAR := $FEE1 + MEMORY_FILL := $FEE4 + MEMORY_COPY := $FEE7 + MEMORY_CRC := $FEEA + MEMORY_DECOMPRESS := $FEED + SPRITE_SET_IMAGE := $FEF0 + SPRITE_SET_POSITION := $FEF3 FB_INIT := $FEF6 FB_GET_INFO := $FEF9 FB_SET_PALETTE := $FEFC @@ -37,7 +47,8 @@ CLOCK_GET_DATE_TIME := $FF50 JOYSTICK_SCAN := $FF53 JOYSTICK_GET := $FF56 - SCRMOD := $FF5F + SCREEN_SET_MODE := $FF5F + SCREEN_SET_CHARSET := $FF62 MOUSE_CONFIG := $FF68 MOUSE_GET := $FF6B .endif diff --git a/asminc/cx16.inc b/asminc/cx16.inc index e08215df9..06cc30199 100644 --- a/asminc/cx16.inc +++ b/asminc/cx16.inc @@ -1,5 +1,5 @@ ; -; CX16 r35 definitions +; CX16 r36 definitions ; ; --------------------------------------------------------------------------- @@ -17,7 +17,8 @@ YELLOW ORANGE BROWN - LIGHTRED + PINK + LIGHTRED = PINK GRAY1 GRAY2 LIGHTGREEN @@ -25,20 +26,81 @@ GRAY3 .endenum -; Special keys -.enum KEY - F1 = $85 - F3 - F5 - F7 - F2 - F4 - F6 - F8 - F9 = $10 - F10 = $15 - F11 - F12 +; Special characters +.enum CH +COLOR_SWAP = $01 +STOP = $03 +UNDERLINE +WHITE +BOLD +BELL +BACKSPACE +TAB +LINEFEED +ITALIC +OUTLINE +ENTER +FONT_LOWER +FONT_ISO +F9 +CURS_DOWN +REVERSE +HOME +DEL +F10 +F11 +F12 +SHIFT_TAB +RED = $1C +CURS_RIGHT +GREEN +BLUE +LIRA = $5C +ORANGE = $81 +RUN = $83 +HELP +F1 +F3 +F5 +F7 +F2 +F4 +F6 +F8 +SHIFT_ENTER +FONT_UPPER +FONT_PET +BLACK +CURS_UP +ATTR_CLEAR +SCRN_CLEAR +INS +BROWN +PINK +LIGHTRED = PINK +GRAY1 +GRAY2 +LIGHTGREEN +LIGHTBLUE +GRAY3 +PURPLE +VIOLET = PURPLE +CURS_LEFT +YELLOW +CYAN +SHIFT_SPACE +LTEE = $AB +LLCORNER = $AD +URCORNER +ULCORNER = $B0 +BTEE +TTEE +RTEE +LRCORNER = $BD +HLINE = $C0 +CROSS = $DB +VLINE = $DD +PI .endenum ; --------------------------------------------------------------------------- @@ -162,10 +224,9 @@ .endstruct ; Kernal -FNAM := $84 ; Pointer to filename -KTEMP2 := $86 ; 2 bytes for temporary storage -IMPARM := $88 ; Pointer for PRIMM function -SCREEN_PTR := $90 ; Pointer to current row on text screen (16 bits) +KTEMP2 := $80 ; 2 bytes for temporary storage +IMPARM := $82 ; Pointer for PRIMM function +FNAM := $8C ; Pointer to filename ; BASIC TXTPTR := $EE ; Pointer into BASIC source code @@ -175,23 +236,25 @@ TXTPTR := $EE ; Pointer into BASIC source code BASIC_BUF := $0200 ; Location of command-line BASIC_BUF_LEN = 81 ; Maximum length of command-line -STATUS := $0275 ; Status from previous I/O operation -IN_DEV := $0279 ; Current input device number -OUT_DEV := $027A ; Current output device number -FNAM_LEN := $027D ; Length of filename -SECADR := $027F ; Secondary address -DEVNUM := $0280 ; Device number +SCREEN_MODE := $0262 ; Current screen mode (set by SCREEN_SET_MODE) +SCREEN_PTR := $0263 ; Pointer to current row on text screen (16 bits) +STATUS := $0286 ; Status from previous I/O operation +IN_DEV := $028A ; Current input device number +OUT_DEV := $028B ; Current output device number +FNAM_LEN := $028E ; Length of filename +SECADR := $0290 ; Secondary address +DEVNUM := $0291 ; Device number CURS_COLOR := $0373 ; Color under the cursor -CHARCOLOR := $0377 ; Cursor's color nybbles (high: background, low: foreground) -RVS := $0378 ; Reverse flag -CURS_FLAG := $037C ; 1 = cursor off -CURS_BLINK := $037D ; Blink counter -CURS_CHAR := $037E ; Character under the cursor -CURS_STATE := $037F ; Cursor blink state -CURS_X := $0381 ; Cursor column -CURS_Y := $0384 ; Cursor row -LLEN := $0387 ; Line length -NLINES := $0388 ; Number of screen lines +CHARCOLOR := $0376 ; Cursor's color nybbles (high: background, low: foreground) +RVS := $0377 ; Reverse flag +CURS_FLAG := $037B ; 1 = cursor off +CURS_BLINK := $037C ; Blink counter +CURS_CHAR := $037D ; Character under the cursor +CURS_STATE := $037E ; Cursor blink state +CURS_X := $0380 ; Cursor column +CURS_Y := $0383 ; Cursor row +LLEN := $0386 ; Line length +NLINES := $0387 ; Number of screen lines ; BASIC VARTAB := $03E3 ; Pointer to start of BASIC variables @@ -453,7 +516,7 @@ NMIVec := $0318 ; --------------------------------------------------------------------------- ; Banked RAM and ROM -KEY_COUNT := $A00A ; (bank 0) Number of keys in input buffer +KEY_COUNT := $A00B ; (bank 0) Number of keys in input buffer TIMER := $A03E ; (bank 0) 60 Hz. timer (3 bytes, big-endian) .struct BANK diff --git a/doc/cx16.sgml b/doc/cx16.sgml index ca9a50ed6..20094d609 100644 --- a/doc/cx16.sgml +++ b/doc/cx16.sgml @@ -46,9 +46,9 @@ file and linker config. <sect>Memory layout<p> cc65-generated programs with the default setup run with the I/O area, RAM bank -zero, and the Kernal ROM visible. That means that Kernal entry points can be -called directly. The usable memory ranges are $0800 - $9EFF and -$A000 - $BFFF. +one, and the Kernal ROM being visible. That means that Kernal entry points +can be called directly. The usable memory ranges are $0800 - +$9EFF, $0400 - $07FF, and $A000 - $BFFF. Special locations: @@ -77,7 +77,7 @@ The ld65 linker comes with a default config. file for the Commander X16, which is used via <tt/-t cx16/. The cx16 package comes with additional secondary linker config. files which are used via <tt/-t cx16 -C <configfile>/. -Those files use 126 bytes in the zero page. (The rest of page zero is reserved +Those files use 94 bytes in the zero page. (The rest of page zero is reserved for Kernal and BASIC.) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index c2b46f0f0..b6171a0ef 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -17,9 +17,9 @@ the C functions available in the standard library. <sect>Introduction<p> -cc65 is a C compiler for 6502 based systems. It implements a subset of the ISO +cc65 is a C compiler for 6502-based systems. It implements a subset of the ISO C standard plus additional functions specially crafted for 6502 systems or -just some of the supported machines. This function refrence describes the +just some of the supported machines. This function reference describes the available functions together with any limitations. For an overview about the available libraries, their purpose, and any @@ -27,8 +27,8 @@ differences to the ISO standard, please have a look at the <url url="library.html" name="cc65 Library Overview">. <em/Note:/ Standard C functions are listed here, but not described in detail. -Since these functions behave identical on all standard compliant systems, they -are described in any book covering standard C. +Because those functions behave identically on all standard-compliant systems, +they are described in any book covering standard C. Each entry for a function contains a detailed description @@ -200,6 +200,7 @@ function. <item><ref id="cbm_k_second" name="cbm_k_second"> <item><ref id="cbm_k_setlfs" name="cbm_k_setlfs"> <item><ref id="cbm_k_setnam" name="cbm_k_setnam"> +<item><ref id="cbm_k_settim" name="cbm_k_settim"> <item><ref id="cbm_k_talk" name="cbm_k_talk"> <item><ref id="cbm_k_tksa" name="cbm_k_tksa"> <item><ref id="cbm_k_udtim" name="cbm_k_udtim"> @@ -321,6 +322,7 @@ function. <sect1><tt/cx16.h/<label id="cx16.h"><p> <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="set_tv" name="set_tv"> --> @@ -2281,6 +2283,9 @@ only be used in presence of a prototype. </itemize> <tag/Availability/cc65 <tag/See also/ +<ref id="cbm_k_load" name="cbm_k_load">, +<ref id="cbm_k_open" name="cbm_k_open">, +<ref id="cbm_k_save" name="cbm_k_save">, <ref id="cbm_k_setnam" name="cbm_k_setnam"> <tag/Example/None. </descrip> @@ -2302,9 +2307,34 @@ only be used in presence of a prototype. </itemize> <tag/Availability/cc65 <tag/See also/ -<ref id="cbm_k_open" name="cbm_k_open">, <ref id="cbm_k_load" name="cbm_k_load">, -<ref id="cbm_k_save" name="cbm_k_save"> +<ref id="cbm_k_open" name="cbm_k_open">, +<ref id="cbm_k_save" name="cbm_k_save">, +<ref id="cbm_k_setlfs" name="cbm_k_setlfs"> +<tag/Example/None. +</descrip> +</quote> + + +<sect1>cbm_k_settim<label id="cbm_k_settim"><p> + +<quote> +<descrip> +<tag/Function/Set the Jiffy clock. +<tag/Header/<tt/<ref id="cbm.h" name="cbm.h">/ +<tag/Declaration/<tt/void __fastcall__ cbm_k_settim (unsigned long timer);/ +<tag/Description/This function changes the Jiffy clock to a different value. +That clock counts sixtieths of a second. It is used by the library's +<tt/clock()/ function. The Jiffy clock is updated by the Kernal's Interrupt +Service Routine. +<tag/Notes/<itemize> +<item>The function is available only as a fastcall function; therefore, it may +be used only in the presence of a prototype. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="cbm_k_udtim" name="cbm_k_udtim">, +<ref id="clock" name="clock"> <tag/Example/None. </descrip> </quote> @@ -2368,6 +2398,7 @@ then that ISR must call this function, in order to keep the clock valid. <tag/Availability/cc65 <tag/See also/ <ref id="cbm_k_scnkey" name="cbm_k_scnkey">, +<ref id="cbm_k_settim" name="cbm_k_settim">, <ref id="clock" name="clock"> <tag/Example/None. </descrip> @@ -2585,6 +2616,7 @@ changing values. (See the description of <tt/cbm_k_udtim()/.) </itemize> <tag/Availability/ISO 9899 <tag/See also/ +<ref id="cbm_k_settim" name="cbm_k_settim">, <ref id="cbm_k_udtim" name="cbm_k_udtim">, <ref id="time" name="time"> <tag/Example/None. diff --git a/doc/library.sgml b/doc/library.sgml index e8ca84653..303809c59 100644 --- a/doc/library.sgml +++ b/doc/library.sgml @@ -18,22 +18,22 @@ including a discussion of the differences to the ISO standard. This file contains a short overview of the libraries available for the cc65 C compiler. Please have a look at the <url url="funcref.html" name="function -reference"> for a list function by function. Since the function reference is -not complete (I'm working on that) it may happen that you don't find a -specific function. In this case, have a look into the header files. All -functions, that are not defined by the ISO C standard have a short comment in +reference"> for a function-by-function list. Because the function reference is +not complete (we're working on that), it may happen that you don't find a +specific function. In that case, have a look into the header files. All +functions, that are not defined by the ISO C standard, have a short comment in the headers, explaining their use. <sect>ISO C compatible library<p> -The C library contains a large subset of the ISO C library. Functions are -usually missing in areas, where there is no support on typical 6502 systems. -Wide character sets are an example for this. +The C library contains a large subset of the ISO C library. Functions usually +are missing in areas where there are no support on typical 6502 systems. +Wide-character sets are an example for that. I will not go into detail about the ISO functions. If a function is not -mentioned here explicitly, expect it to be available and to behave as defined +mentioned here explicitly, expect it to be available, and to behave as defined in the C standard. Functions that are <em/not/ available: @@ -45,13 +45,13 @@ Functions that are <em/not/ available: <p> <item>All functions that handle floating point numbers in some manner. <p> - <item>The <tt/ldiv/ function (cc65 is currently not able to return structs - with a size not equal to 1, 2 or 4 bytes by value). + <item>The <tt/ldiv/ function (cc65 currently is not able to return structs, + by value, with a size not equal to 1, 2, or 4 bytes). <p> - <item>All functions handling wide character strings. + <item>All functions handling wide-character strings. <p> <item>Signals and all related functions (having <tt/SIGSEGV/ would be - cool:-) + cool. :-) <p> <item><tt>setbuf/setvbuf</tt> </itemize> @@ -60,7 +60,7 @@ Functions not available on all supported systems: <itemize> <item><tt>fopen/fread/fwrite/fclose/fputs/fgets/fscanf</tt>: The functions - are built on open/read/write/close. These latter functions are not available + are built on open/read/write/close. Those latter functions are not available on all systems. <p> <item><tt>ftell/fseek/fgetpos/fsetpos</tt>: Support depends on the @@ -69,94 +69,95 @@ Functions not available on all supported systems: <item><tt>rename/remove/rewind</tt>: Support depends on the capabilities of the target machine. <p> - <item><tt>time</tt>: Since many of the supported systems do not have a real - time clock, which means that the <tt/time/ function is not available. Please - note that the other functions from <tt/time.h/ <em/are/ available. + <item><tt>time</tt>: Many of the supported systems don't have a real-time + clock, which means that the <tt/time/ function is not available. Please note + that the other functions from <tt/time.h/ <em/are/ available. </itemize> Functions that are limited in any way: <itemize> - <item><tt>strcspn/strpbrk/strspn</tt>: These functions have a length - limitation of 256 for the second string argument. Since this string gives a - character set, and there are only 256 distinct characters, this shouldn't be + <item><tt>strcspn/strpbrk/strspn</tt>: Those functions have a length + limitation of 256 for the second string argument. Since that string gives a + character set, and there are only 256 distinct characters, that shouldn't be a problem. <p> <item><tt>getenv</tt>: Since there is no such thing as an environment on all - supported systems, the <tt/getenv/ function will always return a <tt/NULL/ + supported systems, the <tt/getenv/ function always will return a <tt/NULL/ pointer. <p> - <item><tt>locale</tt>: There is no other locale than the "C" locale. The + <item><tt>locale</tt>: There is no locale other than the "C" locale. The native locale is identical to the "C" locale. </itemize> -In addition to these limitations, some more functions are limited if inlined -versions are requested by using -Os: +In addition to those limitations, some more functions are limited if inlined +versions are requested by using the <tt/-Os/ command-line option: <itemize> - <item>The <tt/strlen/ function only works for strings with a maximum length + <item>The <tt/strlen/ function works for only strings with a maximum length of 255 characters. <p> - <item>The <tt/isxxx/ character classification functions from + <item>The <tt/isXXX/ character classification functions from <tt/<ctype.h>/ will give unpredictable results if the argument is not - in character range (0..255). This limitation may be removed by #undef'ing + in character range (0..255). That limitation may be removed by #undef'ing the function name (when using <tt/-Os/, the functions are actually macros - that expand to inline assembler code, but the real functions are still + that expand to inline assembly code, but the real functions still are available if the macro definition is removed). </itemize> -<sect>CPU specific stuff - 6502.h<p> +<sect>CPU-specific stuff - 6502.h<p> -The header file 6502.h contains some functions that make only sense with the +The header file 6502.h contains some functions that make sense only with the 6502 CPU. Examples are macros to insert more or less useful instructions into your C code, or a function to call arbitrary machine language subroutines, passing registers in and out. -<sect>Target specific stuff<p> +<sect>Target-specific stuff<p> -For each supported system there's a header file that contains calls or defines -specific for this system. So, when programming for the C64, include c64.h, for -the C128, include c128.h and so on. To make the task for the Commodore systems -easier, there is also a header file named cbm.h that will define stuff common -for all CBM systems, and include the header file for the specific target -system. +For each supported system, there's a header file that contains calls or +defines specific for that system. So, when programming for the C64, include +<tt/<c64.h>/, for the C128, include <tt/<c128.h>/, and so on. +To make the task for the Commodore systems easier, there is also a header file +named <tt/<cbm.h>/ that will define stuff common for all CBM systems, +and include the header file for the specific target system. The header files contain <itemize> - <item>Defines for special keys (like function keys) + <item>Defines for special keys (such as function keys) - <item>Defines for special characters (like the graphics characters) + <item>Defines for special characters (such as the graphics characters) <item>Variables with a fixed address in memory that may be used to access - special hardware. For the C64 and C128 there is a variable struct named - <tt/SID/. Writing to the fields of this struct will write to the SID device - instead. Using these variables will make your program more readable and more - portable. Don't fear ineffective code when using these variables, the - compiler will translate reads and writes to these structs into direct memory + special hardware. For the C64 and C128, there is a variable struct named + <tt/SID/. Writing to the fields of that struct will write to the SID device + instead. Using those variables will make your program more readable and more + portable. Don't fear ineffective code when using those variables, the + compiler will translate reads and writes to those structs into direct memory accesses. - <item>Other routines that make only sense for a specific system. One example - are routines to write memory locations in the system bank for the CBM PET-II + <item>Other routines that make sense for only a specific system. One example + is routines to write memory locations in the system bank for the CBM-II family. </itemize> + <sect>Direct console I/O - <tt/conio.h/<p> The <tt/conio.h/ header file contains a large set of functions that do screen and keyboard I/O. The functions will write directly to the screen or poll the keyboard directly with no more help from the operating system than needed. This has some disadvantages, but on the other side it's fast and reasonably -portable. conio implementations exist for the following targets: +portable. Conio implementations exist for the following targets: <itemize> <item>apple2 @@ -165,13 +166,13 @@ portable. conio implementations exist for the following targets: <item>atari5200 <item>atarixl <item>atmos + <item>c128 <item>c16 (works also for the c116 with up to 32K memory) <item>c64 - <item>c128 - <item>plus4 (or expanded c16/c116) - <item>cbm510 (40 column video) - <item>cbm610 (all CBM series-II computers with 80 column video) + <item>cbm510 (40-column video) + <item>cbm610 (all CBM series-II computers with 80-column video) <item>creativision + <item>cx16 <item>gamate <item>geos-apple <item>geos-cbm @@ -179,11 +180,12 @@ portable. conio implementations exist for the following targets: <item>osic1p <item>pce <item>pet (all CBM PET systems except the 2001) + <item>plus4 (or expanded c16/c116) <item>telestrat <item>vic20 </itemize> -The conio.h header file does also include the system specific header files +The <tt/conio.h/ header file does include the system-specific header files also, which define constants for special characters and keys. @@ -191,14 +193,14 @@ which define constants for special characters and keys. <sect>Using the joystick - <tt/joystick.h/<p> For systems that have a joystick, <tt/joystick.h/ will define a subroutine to -read the current value, including constants to evaluate the result of this +read the current value, including constants to evaluate the result of that function. <sect>Using a mouse - <tt/mouse.h/<p> -Some target machines support a mouse. Mouse support is currently available for +Some target machines support a mouse. Mouse support currently is available for the following targets: <itemize> @@ -206,19 +208,21 @@ the following targets: <item>apple2enh <item>atari <item>atarixl - <item>c64 <item>c128 + <item>c64 <item>cbm510 + <item>cx16 </itemize> The available functions are declared in <tt/mouse.h/. + <sect>Copyright<p> This C runtime library implementation for the cc65 compiler is (C) Copyright 1998-2002 Ullrich von Bassewitz. For usage of the binaries -and/or sources the following conditions do apply: +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 @@ -232,8 +236,8 @@ freely, subject to the following restrictions: <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 + appreciated, but is not required. +<item> Altered source versions must be marked plainly 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. diff --git a/include/cbm.h b/include/cbm.h index 56b5b2947..ac3615c38 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -208,6 +208,7 @@ void __fastcall__ cbm_k_second (unsigned char addr); void __fastcall__ cbm_k_setlfs (unsigned char LFN, unsigned char DEV, unsigned char SA); void __fastcall__ cbm_k_setnam (const char* Name); +void __fastcall__ cbm_k_settim (unsigned long timer); void __fastcall__ cbm_k_talk (unsigned char dev); void __fastcall__ cbm_k_tksa (unsigned char addr); void cbm_k_udtim (void); diff --git a/include/cx16.h b/include/cx16.h index c6638cef4..6ceb605c9 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -47,12 +47,32 @@ /* Additional output character codes */ #define CH_COLOR_SWAP 0x01 #define CH_UNDERLINE 0x04 +#define CH_WHITE 0x05 #define CH_BOLD 0x06 #define CH_BACKSPACE 0x08 #define CH_ITALIC 0x0B #define CH_OUTLINE 0x0C #define CH_FONT_ISO 0x0F +#define CH_RED 0x1C +#define CH_GREEN 0x1E +#define CH_BLUE 0x1F +#define CH_ORANGE 0x81 #define CH_FONT_PET 0x8F +#define CH_BLACK 0x90 +#define CH_ATTR_CLEAR 0x92 +#define CH_BROWN 0x95 +#define CH_PINK 0x96 +#define CH_LIGHTRED CH_PINK +#define CH_GRAY1 0x97 +#define CH_GRAY2 0x98 +#define CH_LIGHTGREEN 0x99 +#define CH_LIGHTBLUE 0x9A +#define CH_GRAY3 0x9B +#define CH_PURPLE 0x9C +#define CH_VIOLET CH_PURPLE +#define CH_YELLOW 0x9E +#define CH_CYAN 0x9F +#define CH_SHIFT_SPACE 0xA0 /* Additional key defines */ #define CH_SHIFT_TAB 0x18 @@ -82,7 +102,8 @@ #define COLOR_YELLOW 0x07 #define COLOR_ORANGE 0x08 #define COLOR_BROWN 0x09 -#define COLOR_LIGHTRED 0x0A +#define COLOR_PINK 0x0A +#define COLOR_LIGHTRED COLOR_PINK #define COLOR_GRAY1 0x0B #define COLOR_GRAY2 0x0C #define COLOR_LIGHTGREEN 0x0D @@ -91,27 +112,27 @@ /* NES controller masks for joy_read() */ -#define JOY_BTN_1_MASK 0x80 -#define JOY_BTN_2_MASK 0x40 -#define JOY_BTN_3_MASK 0x20 -#define JOY_BTN_4_MASK 0x10 -#define JOY_UP_MASK 0x08 -#define JOY_DOWN_MASK 0x04 -#define JOY_LEFT_MASK 0x02 -#define JOY_RIGHT_MASK 0x01 +#define JOY_BTN_1_MASK 0x80 +#define JOY_BTN_2_MASK 0x40 +#define JOY_BTN_3_MASK 0x20 +#define JOY_BTN_4_MASK 0x10 +#define JOY_UP_MASK 0x08 +#define JOY_DOWN_MASK 0x04 +#define JOY_LEFT_MASK 0x02 +#define JOY_RIGHT_MASK 0x01 -#define JOY_BTN_A_MASK JOY_BTN_1_MASK -#define JOY_BTN_B_MASK JOY_BTN_2_MASK -#define JOY_SELECT_MASK JOY_BTN_3_MASK -#define JOY_START_MASK JOY_BTN_4_MASK +#define JOY_BTN_A_MASK JOY_BTN_1_MASK +#define JOY_BTN_B_MASK JOY_BTN_2_MASK +#define JOY_SELECT_MASK JOY_BTN_3_MASK +#define JOY_START_MASK JOY_BTN_4_MASK -#define JOY_BTN_A(v) ((v) & JOY_BTN_A_MASK) -#define JOY_BTN_B(v) ((v) & JOY_BTN_B_MASK) -#define JOY_SELECT(v) ((v) & JOY_SELECT_MASK) -#define JOY_START(v) ((v) & JOY_START_MASK) +#define JOY_BTN_A(v) ((v) & JOY_BTN_A_MASK) +#define JOY_BTN_B(v) ((v) & JOY_BTN_B_MASK) +#define JOY_SELECT(v) ((v) & JOY_SELECT_MASK) +#define JOY_START(v) ((v) & JOY_START_MASK) -#define JOY_FIRE2_MASK JOY_BTN_2_MASK -#define JOY_FIRE2(v) ((v) & JOY_FIRE2_MASK) +#define JOY_FIRE2_MASK JOY_BTN_2_MASK +#define JOY_FIRE2(v) ((v) & JOY_FIRE2_MASK) /* Additional mouse button mask */ #define MOUSE_BTN_MIDDLE 0x02 @@ -119,21 +140,21 @@ /* get_tv() return codes ** set_tv() argument codes */ -#define TV_NONE 0 -#define TV_VGA 1 -#define TV_NTSC_COLOR 2 -#define TV_RGB 3 -#define TV_NONE2 4 -#define TV_VGA2 5 -#define TV_NTSC_MONO 6 -#define TV_RGB2 7 +#define TV_NONE 0 +#define TV_VGA 1 +#define TV_NTSC_COLOR 2 +#define TV_RGB 3 +#define TV_NONE2 4 +#define TV_VGA2 5 +#define TV_NTSC_MONO 6 +#define TV_RGB2 7 /* Video modes for videomode() */ #define VIDEOMODE_40x30 0x00 #define VIDEOMODE_80x60 0x02 #define VIDEOMODE_40COL VIDEOMODE_40x30 #define VIDEOMODE_80COL VIDEOMODE_80x60 -#define VIDEOMODE_320x240 0x80 +#define VIDEOMODE_320x200 0x80 #define VIDEOMODE_SWAP (-1) /* VERA's interrupt flags */ @@ -193,6 +214,9 @@ extern void cx16_std_mou[]; /* Referred to by mouse_static_stddrv[] +unsigned char get_numbanks (void); +/* Return the number of RAM banks that the machine has. */ + signed char get_ostype (void); /* Get the ROM build version. ** -1 -- custom build @@ -201,12 +225,12 @@ signed char get_ostype (void); */ unsigned char get_tv (void); -/* Return the video type that the machine is using. +/* Return the video signal type that the machine is using. ** Return a TV_xx constant. */ void __fastcall__ set_tv (unsigned char type); -/* Set the video type that the machine will use. +/* Set the video signal type that the machine will use. ** Call with a TV_xx constant. */ diff --git a/libsrc/cbm/c_settim.s b/libsrc/cbm/c_settim.s new file mode 100644 index 000000000..5206557f4 --- /dev/null +++ b/libsrc/cbm/c_settim.s @@ -0,0 +1,16 @@ +; +; 2020-01-08, Greg King +; +; void __fastcall__ cbm_k_settim (unsigned long timer); +; + + .export _cbm_k_settim + .importzp sreg + + .include "cbm.inc" + + +.proc _cbm_k_settim + ldy sreg + jmp SETTIM +.endproc diff --git a/libsrc/cx16/clock.s b/libsrc/cx16/clock.s index 9af215e0f..a0871dbc7 100644 --- a/libsrc/cx16/clock.s +++ b/libsrc/cx16/clock.s @@ -25,7 +25,6 @@ .endproc - .proc _clock stz sreg + 1 ; Byte 3 always is zero diff --git a/libsrc/cx16/color.s b/libsrc/cx16/color.s index 1be01c473..f8d8c1ebf 100644 --- a/libsrc/cx16/color.s +++ b/libsrc/cx16/color.s @@ -36,7 +36,7 @@ _bgcolor: ora tmp1 sta CHARCOLOR ; set new values txa - lsr a ; get screen color + lsr a ; get old background color lsr a lsr a lsr a diff --git a/libsrc/cx16/crt0.s b/libsrc/cx16/crt0.s index 52deeb76f..d709ea96f 100644 --- a/libsrc/cx16/crt0.s +++ b/libsrc/cx16/crt0.s @@ -61,7 +61,7 @@ L2: lda zpsave,x ldx spsave txs ; Restore stack pointer ldx ramsave - stx VIA1::PRA2 ; Restore former RAM bank + stx VIA1::PRA ; Restore former RAM bank lda VIA1::PRB and #<~$07 ora #$04 @@ -85,10 +85,10 @@ init: ; Change to the second RAM bank. - lda VIA1::PRA2 + lda VIA1::PRA sta ramsave ; Save the current RAM bank number lda #$01 - sta VIA1::PRA2 + sta VIA1::PRA .if 0 ; We don't need to preserve zero-page space for cc65's variables. ; Save the zero-page locations that we need. diff --git a/libsrc/cx16/get_numbanks.s b/libsrc/cx16/get_numbanks.s new file mode 100644 index 000000000..00490fb72 --- /dev/null +++ b/libsrc/cx16/get_numbanks.s @@ -0,0 +1,20 @@ +; +; 2020-01-10, Greg King +; +; unsigned char get_numbanks (void); +; /* Return the number of RAM banks that the machine has. */ +; +; The Commander X16 version of MEMTOP returns with an extra value: +; The accumulator describes the number of RAM banks that exist on the hardware. +; + + .export _get_numbanks + + .import MEMTOP + + +_get_numbanks: + sec + jsr MEMTOP + ldx #>$0000 + rts diff --git a/libsrc/cx16/joyref.s b/libsrc/cx16/joyref.s deleted file mode 100644 index edd89fba6..000000000 --- a/libsrc/cx16/joyref.s +++ /dev/null @@ -1,20 +0,0 @@ -; -; 2019-12-22, Greg King -; -; Link an interrupt handler if joysticks are used by a program. -; - - .interruptor joy_libref, 9 - - .include "cbm_kernal.inc" - .include "cx16.inc" - - -joy_libref: - lda VERA::IRQ_FLAGS - lsr a - bcc not_vsync - jsr JOYSTICK_SCAN ; Bit-bang game controllers - clc ; Let other Jiffy handlers run -not_vsync: - rts diff --git a/libsrc/cx16/kbhit.s b/libsrc/cx16/kbhit.s index 34afdeba4..d7e22efd1 100644 --- a/libsrc/cx16/kbhit.s +++ b/libsrc/cx16/kbhit.s @@ -1,5 +1,5 @@ ; -; 2019-12-22, Greg King +; 2020-01-08, Greg King ; ; unsigned char kbhit (void); ; /* Returns non-zero (true) if a typed character is waiting. */ @@ -11,10 +11,10 @@ .proc _kbhit - ldy VIA1::PRA2 ; (KEY_COUNT is in RAM bank 0) - stz VIA1::PRA2 + ldy VIA1::PRA ; (KEY_COUNT is in RAM bank 0) + stz VIA1::PRA lda KEY_COUNT ; Get number of characters - sty VIA1::PRA2 + sty VIA1::PRA tax ; High byte of return (only its zero/nonzero ... rts ; ... state matters) .endproc diff --git a/libsrc/cx16/kernal.s b/libsrc/cx16/kernal.s index ccd52d632..a6b65ebbd 100644 --- a/libsrc/cx16/kernal.s +++ b/libsrc/cx16/kernal.s @@ -1,11 +1,20 @@ ; -; 2019-12-22, Greg King +; 2020-01-06, Greg King ; ; CX16 Kernal functions ; .include "cbm_kernal.inc" + .export CONSOLE_INIT + .export CONSOLE_PUT_CHAR + .export CONSOLE_GET_CHAR + .export MEMORY_FILL + .export MEMORY_COPY + .export MEMORY_CRC + .export MEMORY_DECOMPRESS + .export SPRITE_SET_IMAGE + .export SPRITE_SET_POSITION .export FB_INIT .export FB_GET_INFO .export FB_SET_PALETTE @@ -37,7 +46,8 @@ .export CLOCK_GET_DATE_TIME .export JOYSTICK_SCAN .export JOYSTICK_GET - .export SCRMOD + .export SCREEN_SET_MODE + .export SCREEN_SET_CHARSET .export MOUSE_CONFIG .export MOUSE_GET diff --git a/libsrc/cx16/libref.s b/libsrc/cx16/libref.s index 0d85c7cd8..82a39c22b 100644 --- a/libsrc/cx16/libref.s +++ b/libsrc/cx16/libref.s @@ -1,9 +1,10 @@ ; ; 2013-05-31, Oliver Schmidt -; 2019-11-14, Greg King +; 2020-01-06, Greg King ; .export em_libref + .export joy_libref .export mouse_libref .export ser_libref .export tgi_libref @@ -11,6 +12,7 @@ .import _exit em_libref := _exit +joy_libref := _exit mouse_libref := _exit ser_libref := _exit tgi_libref := _exit diff --git a/libsrc/cx16/mcbdefault.s b/libsrc/cx16/mcbdefault.s index 3dda1c711..aed0e3a2d 100644 --- a/libsrc/cx16/mcbdefault.s +++ b/libsrc/cx16/mcbdefault.s @@ -1,44 +1,29 @@ ; ; Default mouse callbacks for the CX16 ; -; 2019-12-25, Greg King -; -; All functions in this module should be interrupt-safe -; because they might be called from an interrupt handler. +; 2020-01-10, Greg King ; .export _mouse_def_callbacks + .import MOUSE_GET, SPRITE_SET_POSITION .include "cx16.inc" -msprite: - stz VERA::CTRL ; set address for VERA's data port zero - lda #<(VERA::SPRITE::ATTRIB::Z_FLIP + 0 * 8) - ldx #>(VERA::SPRITE::ATTRIB::Z_FLIP + 0 * 8) - ldy #^(VERA::SPRITE::ATTRIB::Z_FLIP + 0 * 8) | VERA::INC0 - sta VERA::ADDR - stx VERA::ADDR+1 - sty VERA::ADDR+2 - rts - ; -------------------------------------------------------------------------- ; Hide the mouse pointer. -hide: jsr msprite - lda VERA::DATA0 - and #<~VERA::SPRITE::DEPTH::LAYER1 - sta VERA::DATA0 - rts +hide: ldx #%10000000 + stx gREG::r0H + bra mse ; -------------------------------------------------------------------------- ; Show the mouse pointer. -show: jsr msprite - lda VERA::DATA0 - ora #VERA::SPRITE::DEPTH::LAYER1 - sta VERA::DATA0 - rts +show: ldx #gREG::r0 + jsr MOUSE_GET +mse: lda #$00 ; mouse sprite + jmp SPRITE_SET_POSITION ; -------------------------------------------------------------------------- ; Prepare to move the mouse pointer. @@ -53,13 +38,13 @@ draw: ; Fall through ; -------------------------------------------------------------------------- ; Move the mouse pointer X position to the value in .XA . -movex: ; Already set by drivers +movex: ; Already done by Kernal ; Fall through ; -------------------------------------------------------------------------- ; Move the mouse pointer Y position to the value in .XA . -movey: rts ; Already set by drivers +movey: rts ; Already done by Kernal ; -------------------------------------------------------------------------- ; Callback structure diff --git a/libsrc/cx16/videomode.s b/libsrc/cx16/videomode.s index e3a777b8e..8fe797449 100644 --- a/libsrc/cx16/videomode.s +++ b/libsrc/cx16/videomode.s @@ -1,10 +1,10 @@ ; -; 2019-11-06, Greg King +; 2020-01-06, Greg King ; ; /* Video mode defines */ ; #define VIDEOMODE_40x30 0x00 ; #define VIDEOMODE_80x60 0x02 -; #define VIDEOMODE_320x240 0x80 +; #define VIDEOMODE_320x200 0x80 ; #define VIDEOMODE_SWAP (-1) ; ; signed char __fastcall__ videomode (signed char Mode); @@ -16,29 +16,25 @@ .export _videomode - .import SCRMOD + .import SCREEN_SET_MODE + .include "cx16.inc" .proc _videomode - tax - clc ; (Get old mode) - jsr SCRMOD - pha - txa + ldx SCREEN_MODE ; Get old mode + phx - sec ; (Set new mode) - jsr SCRMOD + jsr SCREEN_SET_MODE pla ; Get back old mode - bcs @L1 ldx #>$0000 ; Clear high byte + bcs @L1 rts -; The new mode is invalid. Go back to the old mode. Return -1. +; The new mode is invalid. Go back to the old one. Return -1. -@L1: sec - jsr SCRMOD - lda #<-1 - tax +@L1: sta SCREEN_MODE + dex + txa rts .endproc diff --git a/libsrc/cx16/waitvsync.s b/libsrc/cx16/waitvsync.s index e8176916b..6316a0483 100644 --- a/libsrc/cx16/waitvsync.s +++ b/libsrc/cx16/waitvsync.s @@ -1,5 +1,5 @@ ; -; 2019-12-23, Greg King +; 2020-01-08, Greg King ; ; void waitvsync (void); ; /* Wait for the start of the next video field. */ @@ -12,10 +12,10 @@ .include "cx16.inc" _waitvsync: - ldx VIA1::PRA2 ; (TIMER is in RAM bank 0) - stz VIA1::PRA2 + ldx VIA1::PRA ; (TIMER is in RAM bank 0) + stz VIA1::PRA lda TIMER + 2 : cmp TIMER + 2 beq :- ; Wait for next jiffy - stx VIA1::PRA2 + stx VIA1::PRA rts From 0f08ae2c12829af9c7d4b7a7a47ff37528dd1ae1 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 18 Jan 2020 19:29:02 +0100 Subject: [PATCH 1254/2161] Minor cleanup. --- libsrc/apple2/videomode.s | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libsrc/apple2/videomode.s b/libsrc/apple2/videomode.s index 1da997472..65e582547 100644 --- a/libsrc/apple2/videomode.s +++ b/libsrc/apple2/videomode.s @@ -16,7 +16,7 @@ _videomode: ; Get and save current videomode flag 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) @@ -29,18 +29,18 @@ _videomode: ; 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 @@ -56,7 +56,7 @@ _videomode: ; Switch in LC bank 2 for R/O bit $C080 - + ; Return ctrl-char code for setting previous ; videomode using the saved videomode flag done: lda #$11 ; Ctrl-char code for 40 cols From 90a2edcfa2e759893a1df9f8108267b43f769faf Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 25 Jan 2020 04:13:04 -0500 Subject: [PATCH 1255/2161] Made cc65 detect a possibly missing argument at the end of a function argument list. (It could be a stray comma at the end of the list.) --- src/cc65/expr.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 904c3af01..e59f9b4d3 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1,7 +1,7 @@ /* expr.c ** ** 1998-06-21, Ullrich von Bassewitz -** 2017-12-05, Greg King +** 2020-01-25, Greg King */ @@ -278,9 +278,9 @@ static void WarnConstCompareResult (void) static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) -/* Parse a function parameter list and pass the parameters to the called -** function. Depending on several criteria this may be done by just pushing -** each parameter separately, or creating the parameter frame once and then +/* Parse a function parameter list, and pass the parameters to the called +** function. Depending on several criteria, this may be done by just pushing +** each parameter separately, or creating the parameter frame once, and then ** storing into this frame. ** The function returns the size of the parameters pushed. */ @@ -322,7 +322,7 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) /* Do we have more than one parameter in the frame? */ if (FrameParams > 1) { - /* Okeydokey, setup the frame */ + /* Okeydokey, set up the frame */ FrameOffs = StackPtr; g_space (FrameSize); StackPtr -= FrameSize; @@ -343,7 +343,7 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) /* Fetch the pointer to the next argument, check for too many args */ if (ParamCount <= Func->ParamCount) { /* Beware: If there are parameters with identical names, they - ** cannot go into the same symbol table, which means that in this + ** cannot go into the same symbol table, which means that, in this ** case of errorneous input, the number of nodes in the symbol ** table and ParamCount are NOT equal. We have to handle this case ** below to avoid segmentation violations. Since we know that this @@ -364,7 +364,7 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) /* End of param list reached, no ellipsis */ Error ("Too many arguments in function call"); } - /* Assume an ellipsis even in case of errors to avoid an error + /* Assume an ellipsis even in case of errors, to avoid an error ** message for each other argument. */ Ellipsis = 1; @@ -373,7 +373,7 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) /* Evaluate the parameter expression */ hie1 (&Expr); - /* If we don't have an argument spec, accept anything, otherwise + /* If we don't have an argument spec., accept anything; otherwise, ** convert the actual argument to the type needed. */ Flags = CF_NONE; @@ -433,6 +433,12 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) break; } NextToken (); + + /* Check for stray comma */ + if (CurTok.Tok == TOK_RPAREN) { + Error ("Argument expected after comma"); + break; + } } /* Check if we had enough parameters */ @@ -441,11 +447,11 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) } /* The function returns the size of all parameters pushed onto the stack. - ** However, if there are parameters missing (which is an error and was - ** flagged by the compiler) AND a stack frame was preallocated above, - ** we would loose track of the stackpointer and generate an internal error + ** However, if there are parameters missing (which is an error, and was + ** flagged by the compiler), AND a stack frame was preallocated above, + ** we would loose track of the stackpointer, and generate an internal error ** later. So we correct the value by the parameters that should have been - ** pushed to avoid an internal compiler error. Since an error was + ** pushed, to avoid an internal compiler error. Since an error was ** generated before, no code will be output anyway. */ return ParamSize + FrameSize; From a2bbb6f1be03e1285521da97ffa20622ad1449c1 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 25 Jan 2020 20:56:52 +0100 Subject: [PATCH 1256/2161] added regression test related to bug #1001 --- test/err/bug1001.c | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 test/err/bug1001.c diff --git a/test/err/bug1001.c b/test/err/bug1001.c new file mode 100644 index 000000000..62737c178 --- /dev/null +++ b/test/err/bug1001.c @@ -0,0 +1,10 @@ + +/* https://github.com/cc65/cc65/issues/1001 */ + +#include <stdio.h> + +int main(void) +{ + printf("test",); /* should be an error */ + return 0; +} From a59402d5f544efd6d608ba4fdd64dc3a6758d2e5 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 26 Jan 2020 02:18:04 +0100 Subject: [PATCH 1257/2161] store y first, then a. fix by willymanilly --- libsrc/c128/emd/c128-vdc.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/c128/emd/c128-vdc.s b/libsrc/c128/emd/c128-vdc.s index e359dcdb9..e294ddc18 100644 --- a/libsrc/c128/emd/c128-vdc.s +++ b/libsrc/c128/emd/c128-vdc.s @@ -341,12 +341,12 @@ vdcsetsrcaddr: stx VDC_ADDR_REG @L0: bit VDC_ADDR_REG bpl @L0 - sta VDC_DATA_REG + sty VDC_DATA_REG inx stx VDC_ADDR_REG @L1: bit VDC_ADDR_REG ; XXX: Test waiting for register 18 bpl @L1 - sty VDC_DATA_REG + sta VDC_DATA_REG rts vdcgetbyte: From f68cc06ec746ff6cc889d1a7b07ebd8769d7909c Mon Sep 17 00:00:00 2001 From: Daniel Serpell <daniel.serpell@gmail.com> Date: Sun, 26 Jan 2020 23:55:37 -0300 Subject: [PATCH 1258/2161] Fixes Atari OS devhdl_t, init field needs an JMP byte. This fixes issue #1002. --- include/_atarios.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/_atarios.h b/include/_atarios.h index c15a99439..5e1374fa5 100644 --- a/include/_atarios.h +++ b/include/_atarios.h @@ -120,8 +120,9 @@ struct __devhdl { void *put; /* address of PUT BYTE routine -1 */ void *status; /* address of GET STATUS routine -1 */ void *special; /* address od SPECIAL routine -1 */ + unsigned char jmp_inst; /* a "JMP" byte, should be $4C */ void (*init)(void); /* init routine (JMP INIT) */ - void *reserved; /* unused */ + unsigned char reserved; /* unused */ }; typedef struct __devhdl devhdl_t; From 5b11eb4bb95a9982f33f2c580318202afc0b0882 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 31 Dec 2019 15:55:51 +0800 Subject: [PATCH 1259/2161] Corrected check in OptTransfers2 for register usage. Fixed Issue 992. --- src/cc65/coptind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index f2ece2cee..e35aa5bee 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -1471,7 +1471,7 @@ unsigned OptTransfers2 (CodeSeg* S) (N = CS_GetNextEntry (S, I)) != 0 && !CE_HasLabel (N) && (N->Info & OF_XFR) != 0 && - GetRegInfo (S, I+2, E->Chg) != E->Chg) { + (GetRegInfo (S, I+2, E->Chg) & E->Chg) == 0) { CodeEntry* X = 0; From 9559625ee874434dff7a015191cb14e2303b96b3 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 31 Dec 2019 16:02:42 +0800 Subject: [PATCH 1260/2161] Always insert a LDA after the removed PLA during the optimization in OptPushPop. Fixed Issue 971. --- src/cc65/coptind.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index e35aa5bee..318f9593b 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -1948,17 +1948,22 @@ unsigned OptPushPop (CodeSeg* S) !MemAccess (S, Push+1, Pop-1, E)) { /* Insert a STA after the PHA */ - X = NewCodeEntry (E->OPC, E->AM, E->Arg, E->JumpTo, E->LI); + X = NewCodeEntry (OP65_STA, E->AM, E->Arg, E->JumpTo, E->LI); CS_InsertEntry (S, X, Push+1); /* Remove the PHA instead */ CS_DelEntry (S, Push); + /* Insert a LDA after the PLA */ + X = NewCodeEntry (OP65_LDA, E->AM, E->Arg, E->JumpTo, CS_GetEntry (S, Pop)->LI); + CS_InsertEntry (S, X, Pop+1); + /* Remove the PLA/STA sequence */ - CS_DelEntries (S, Pop, 2); + CS_DelEntry (S, Pop); + CS_DelEntry (S, I); /* Correct I so we continue with the next insn */ - I -= 2; + --I; /* Remember we had changes */ ++Changes; From 6d530931bfc58c925107d2cae10bc2ebe067217b Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 1 Jan 2020 23:44:35 +0800 Subject: [PATCH 1261/2161] Quick fix for the OptPushPop bug reported in Issue #337. --- src/cc65/coptind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index 318f9593b..85901d0f9 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -1968,7 +1968,7 @@ unsigned OptPushPop (CodeSeg* S) /* Remember we had changes */ ++Changes; - } else if ((E->Info & OF_CBRA) == 0 && + } else if (!CE_UseLoadFlags (E) && (!RegAUsed (S, I) || !ChgA)) { /* We can remove the PHA and PLA instructions */ From dc5114b0713fd4a8294e81dab83b8ecb59813d41 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 3 Jan 2020 07:43:51 +0800 Subject: [PATCH 1262/2161] Just disable OptPushPop if N/Z is used after the PLA. This is a more conservative way to fix Issue #971. --- src/cc65/coptind.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index 85901d0f9..04deb0119 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -1892,6 +1892,7 @@ unsigned OptPushPop (CodeSeg* S) while (I < CS_GetEntryCount (S)) { CodeEntry* X; + CodeEntry* N; /* Get next entry */ CodeEntry* E = CS_GetEntry (S, I); @@ -1944,7 +1945,9 @@ unsigned OptPushPop (CodeSeg* S) if (E->OPC == OP65_STA && (E->AM == AM65_ABS || E->AM == AM65_ZP) && !CE_HasLabel (E) && - !RegAUsed (S, I+1) && + ((N = CS_GetNextEntry (S, I)) == 0 || + (!CE_UseLoadFlags (N) && + !RegAUsed (S, I+1))) && !MemAccess (S, Push+1, Pop-1, E)) { /* Insert a STA after the PHA */ @@ -1954,16 +1957,11 @@ unsigned OptPushPop (CodeSeg* S) /* Remove the PHA instead */ CS_DelEntry (S, Push); - /* Insert a LDA after the PLA */ - X = NewCodeEntry (OP65_LDA, E->AM, E->Arg, E->JumpTo, CS_GetEntry (S, Pop)->LI); - CS_InsertEntry (S, X, Pop+1); - /* Remove the PLA/STA sequence */ - CS_DelEntry (S, Pop); - CS_DelEntry (S, I); + CS_DelEntries (S, Pop, 2); /* Correct I so we continue with the next insn */ - --I; + I -= 2; /* Remember we had changes */ ++Changes; From ce80624f627ba887cf01d01d3f7c9dc02538a536 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Thu, 2 Jan 2020 18:57:03 +0100 Subject: [PATCH 1263/2161] ctype size optimization --- asminc/ctype.inc | 16 +- asminc/ctype_common.inc | 91 ++++++ asminc/ctype_console.inc | 92 +++++++ asminc/ctypetable.inc | 48 ++++ doc/cc65.sgml | 5 +- doc/funcref.sgml | 67 ----- include/ctype.h | 101 +------ libsrc/apple2/ctype.s | 160 +---------- libsrc/atari/ctype.s | 425 ++++++++++------------------ libsrc/atari2600/ctype.s | 161 +---------- libsrc/atmos/ctype.s | 426 ++++++++++------------------- libsrc/cbm/ctype.s | 417 ++++++++++------------------ libsrc/common/atoi.s | 22 +- libsrc/common/ctype_preprocessor.s | 50 ++++ libsrc/common/isalnum.s | 24 +- libsrc/common/isalpha.s | 24 +- libsrc/common/isascii.s | 27 ++ libsrc/common/isblank.s | 24 +- libsrc/common/iscntrl.s | 24 +- libsrc/common/isdigit.s | 24 +- libsrc/common/isgraph.s | 28 +- libsrc/common/islower.s | 22 +- libsrc/common/isprint.s | 26 +- libsrc/common/ispunct.s | 29 +- libsrc/common/isspace.s | 24 +- libsrc/common/isupper.s | 24 +- libsrc/common/isxdigit.s | 24 +- libsrc/common/stricmp.s | 43 +-- libsrc/common/strlower.s | 9 +- libsrc/common/strnicmp.s | 36 +-- libsrc/common/strupper.s | 8 +- libsrc/creativision/ctype.s | 171 +----------- libsrc/gamate/ctype.s | 160 +---------- libsrc/geos-common/system/ctype.s | 422 ++++++++++------------------ libsrc/lynx/ctype.s | 171 +----------- libsrc/nes/ctype.s | 171 +----------- libsrc/none/ctype.s | 158 +---------- libsrc/osic1p/ctype.s | 158 +---------- libsrc/pce/ctype.s | 157 +---------- libsrc/sim6502/ctype.s | 158 +---------- libsrc/supervision/ctype.s | 161 +---------- libsrc/telestrat/ctype.s | 298 +------------------- test/val/lib_common_ctype.c | 368 +++++++++++++++++++++++++ 43 files changed, 1491 insertions(+), 3563 deletions(-) create mode 100644 asminc/ctype_common.inc create mode 100644 asminc/ctype_console.inc create mode 100644 asminc/ctypetable.inc create mode 100644 libsrc/common/ctype_preprocessor.s create mode 100644 libsrc/common/isascii.s create mode 100644 test/val/lib_common_ctype.c diff --git a/asminc/ctype.inc b/asminc/ctype.inc index d6b0ccf46..401e772a2 100644 --- a/asminc/ctype.inc +++ b/asminc/ctype.inc @@ -1,12 +1,14 @@ +; ctype.inc +; +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. ; ; Definitions for the character type tables ; -; Ullrich von Bassewitz, 08.09.2001 -; - -; Make the __ctype table an exported/imported symbol - - .global __ctype ; Define bitmapped constants for the table entries @@ -25,5 +27,3 @@ CT_ALNUM = (CT_LOWER | CT_UPPER | CT_DIGIT) CT_ALPHA = (CT_LOWER | CT_UPPER) CT_CTRL_SPACE = (CT_CTRL | CT_SPACE) CT_NOT_PUNCT = (CT_SPACE | CT_CTRL | CT_DIGIT | CT_UPPER | CT_LOWER) - - diff --git a/asminc/ctype_common.inc b/asminc/ctype_common.inc new file mode 100644 index 000000000..ffd8dfe0e --- /dev/null +++ b/asminc/ctype_common.inc @@ -0,0 +1,91 @@ +; ctype_common.inc +; +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. +; +; Character specification table for some common targets. +; + + .include "ctypetable.inc" + .export __ctypeIdx + +; The tables are readonly, put them into the rodata segment + +.rodata + +__ctypeIdx: + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 0/00 ___ctrl_@___, 1/01 ___ctrl_A___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 2/02 ___ctrl_B___, 3/03 ___ctrl_C___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 4/04 ___ctrl_D___, 5/05 ___ctrl_E___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 6/06 ___ctrl_F___, 7/07 ___ctrl_G___ + ct_mix CT_CTRL_IDX, CT_CTRL_WS_SPACETAB_IDX ; 8/08 ___ctrl_H___, 9/09 ___ctrl_I___ + ct_mix CT_CTRL_WS_IDX, CT_CTRL_WS_IDX ; 10/0a ___ctrl_J___, 11/0b ___ctrl_K___ + ct_mix CT_CTRL_WS_IDX, CT_CTRL_WS_IDX ; 12/0c ___ctrl_L___, 13/0d ___ctrl_M___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 14/0e ___ctrl_N___, 15/0f ___ctrl_O___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 16/10 ___ctrl_P___, 17/11 ___ctrl_Q___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 18/12 ___ctrl_R___, 19/13 ___ctrl_S___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 20/14 ___ctrl_T___, 21/15 ___ctrl_U___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 22/16 ___ctrl_V___, 23/17 ___ctrl_W___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 24/18 ___ctrl_X___, 25/19 ___ctrl_Y___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 26/1a ___ctrl_Z___, 27/1b ___ctrl_[___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 28/1c ___ctrl_\___, 29/1d ___ctrl_]___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 30/1e ___ctrl_^___, 31/1f ___ctrl_____ + + ct_mix CT_SPACE_SPACETAB_IDX, CT_NONE_IDX ; 32/20 ___SPACE___, 33/21 _____!_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 34/22 _____"_____, 35/23 _____#_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 36/24 _____$_____, 37/25 _____%_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 38/26 _____&_____, 39/27 _____'_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 40/28 _____(_____, 41/29 _____)_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 42/2a _____*_____, 43/2b _____+_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 44/2c _____,_____, 45/2d _____-_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 46/2e _____._____, 47/2f _____/_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 48/30 _____0_____, 49/31 _____1_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 50/32 _____2_____, 51/33 _____3_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 52/34 _____4_____, 53/35 _____5_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 54/36 _____6_____, 55/37 _____7_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 56/38 _____8_____, 57/39 _____9_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 58/3a _____:_____, 59/3b _____;_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 60/3c _____<_____, 61/3d _____=_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 62/3e _____>_____, 63/3f _____?_____ + + ct_mix CT_NONE_IDX, CT_UPPER_XDIGIT_IDX ; 64/40 _____@_____, 65/41 _____A_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_XDIGIT_IDX ; 66/42 _____B_____, 67/43 _____C_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_XDIGIT_IDX ; 68/44 _____D_____, 69/45 _____E_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_IDX ; 70/46 _____F_____, 71/47 _____G_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 72/48 _____H_____, 73/49 _____I_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 74/4a _____J_____, 75/4b _____K_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 76/4c _____L_____, 77/4d _____M_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 78/4e _____N_____, 79/4f _____O_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 80/50 _____P_____, 81/51 _____Q_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 82/52 _____R_____, 83/53 _____S_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 84/54 _____T_____, 85/55 _____U_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 86/56 _____V_____, 87/57 _____W_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 88/58 _____X_____, 89/59 _____Y_____ + ct_mix CT_UPPER_IDX, CT_NONE_IDX ; 90/5a _____Z_____, 91/5b _____[_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 92/5c _____\_____, 93/5d _____]_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 94/5e _____^_____, 95/5f _UNDERLINE_ + + ct_mix CT_NONE_IDX, CT_LOWER_XDIGIT_IDX ; 96/60 ___grave___, 97/61 _____a_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_XDIGIT_IDX ; 98/62 _____b_____, 99/63 _____c_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_XDIGIT_IDX ; 100/64 _____d_____, 101/65 _____e_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_IDX ; 102/66 _____f_____, 103/67 _____g_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 104/68 _____h_____, 105/69 _____i_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 106/6a _____j_____, 107/6b _____k_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 108/6c _____l_____, 109/6d _____m_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 110/6e _____n_____, 111/6f _____o_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 112/70 _____p_____, 113/71 _____q_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 114/72 _____r_____, 115/73 _____s_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 116/74 _____t_____, 117/75 _____u_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 118/76 _____v_____, 119/77 _____w_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 120/78 _____x_____, 121/79 _____y_____ + ct_mix CT_LOWER_IDX, CT_NONE_IDX ; 122/7a _____z_____, 123/7b _____{_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 124/7c _____|_____, 125/7d _____}_____ + ct_mix CT_NONE_IDX, CT_WS_IDX ; 126/7e _____~_____, 127/7f ____DEL____ + +.repeat 64 + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 128-255 +.endrepeat diff --git a/asminc/ctype_console.inc b/asminc/ctype_console.inc new file mode 100644 index 000000000..55db8e615 --- /dev/null +++ b/asminc/ctype_console.inc @@ -0,0 +1,92 @@ +; ctype_console.inc +; +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. +; +; Character specification table, matching serveral consoles. +; + + .include "ctypetable.inc" + .export __ctypeIdx + +; The tables are readonly, put them into the rodata segment + +.rodata + +__ctypeIdx: + +.repeat 2 ; 2 times for normal and inverted + + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 0/00 ___ctrl_@___, 1/01 ___ctrl_A___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 2/02 ___ctrl_B___, 3/03 ___ctrl_C___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 4/04 ___ctrl_D___, 5/05 ___ctrl_E___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 6/06 ___ctrl_F___, 7/07 ___ctrl_G___ + ct_mix CT_CTRL_IDX, CT_CTRL_WS_SPACETAB_IDX ; 8/08 ___ctrl_H___, 9/09 ___ctrl_I___ + ct_mix CT_CTRL_WS_IDX, CT_CTRL_WS_IDX ; 10/0a ___ctrl_J___, 11/0b ___ctrl_K___ + ct_mix CT_CTRL_WS_IDX, CT_CTRL_WS_IDX ; 12/0c ___ctrl_L___, 13/0d ___ctrl_M___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 14/0e ___ctrl_N___, 15/0f ___ctrl_O___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 16/10 ___ctrl_P___, 17/11 ___ctrl_Q___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 18/12 ___ctrl_R___, 19/13 ___ctrl_S___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 20/14 ___ctrl_T___, 21/15 ___ctrl_U___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 22/16 ___ctrl_V___, 23/17 ___ctrl_W___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 24/18 ___ctrl_X___, 25/19 ___ctrl_Y___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 26/1a ___ctrl_Z___, 27/1b ___ctrl_[___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 28/1c ___ctrl_\___, 29/1d ___ctrl_]___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 30/1e ___ctrl_^___, 31/1f ___ctrl_____ + + ct_mix CT_SPACE_SPACETAB_IDX, CT_NONE_IDX ; 32/20 ___SPACE___, 33/21 _____!_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 34/22 _____"_____, 35/23 _____#_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 36/24 _____$_____, 37/25 _____%_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 38/26 _____&_____, 39/27 _____'_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 40/28 _____(_____, 41/29 _____)_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 42/2a _____*_____, 43/2b _____+_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 44/2c _____,_____, 45/2d _____-_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 46/2e _____._____, 47/2f _____/_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 48/30 _____0_____, 49/31 _____1_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 50/32 _____2_____, 51/33 _____3_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 52/34 _____4_____, 53/35 _____5_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 54/36 _____6_____, 55/37 _____7_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 56/38 _____8_____, 57/39 _____9_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 58/3a _____:_____, 59/3b _____;_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 60/3c _____<_____, 61/3d _____=_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 62/3e _____>_____, 63/3f _____?_____ + + ct_mix CT_NONE_IDX, CT_UPPER_XDIGIT_IDX ; 64/40 _____@_____, 65/41 _____A_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_XDIGIT_IDX ; 66/42 _____B_____, 67/43 _____C_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_XDIGIT_IDX ; 68/44 _____D_____, 69/45 _____E_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_IDX ; 70/46 _____F_____, 71/47 _____G_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 72/48 _____H_____, 73/49 _____I_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 74/4a _____J_____, 75/4b _____K_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 76/4c _____L_____, 77/4d _____M_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 78/4e _____N_____, 79/4f _____O_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 80/50 _____P_____, 81/51 _____Q_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 82/52 _____R_____, 83/53 _____S_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 84/54 _____T_____, 85/55 _____U_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 86/56 _____V_____, 87/57 _____W_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 88/58 _____X_____, 89/59 _____Y_____ + ct_mix CT_UPPER_IDX, CT_NONE_IDX ; 90/5a _____Z_____, 91/5b _____[_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 92/5c _____\_____, 93/5d _____]_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 94/5e _____^_____, 95/5f _UNDERLINE_ + + ct_mix CT_NONE_IDX, CT_LOWER_XDIGIT_IDX ; 96/60 ___grave___, 97/61 _____a_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_XDIGIT_IDX ; 98/62 _____b_____, 99/63 _____c_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_XDIGIT_IDX ; 100/64 _____d_____, 101/65 _____e_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_IDX ; 102/66 _____f_____, 103/67 _____g_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 104/68 _____h_____, 105/69 _____i_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 106/6a _____j_____, 107/6b _____k_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 108/6c _____l_____, 109/6d _____m_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 110/6e _____n_____, 111/6f _____o_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 112/70 _____p_____, 113/71 _____q_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 114/72 _____r_____, 115/73 _____s_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 116/74 _____t_____, 117/75 _____u_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 118/76 _____v_____, 119/77 _____w_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 120/78 _____x_____, 121/79 _____y_____ + ct_mix CT_LOWER_IDX, CT_NONE_IDX ; 122/7a _____z_____, 123/7b _____{_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 124/7c _____|_____, 125/7d _____}_____ + ct_mix CT_NONE_IDX, CT_WS_IDX ; 126/7e _____~_____, 127/7f ____DEL____ + +.endrepeat diff --git a/asminc/ctypetable.inc b/asminc/ctypetable.inc new file mode 100644 index 000000000..e0a8bdcd3 --- /dev/null +++ b/asminc/ctypetable.inc @@ -0,0 +1,48 @@ +; ctypetable.inc +; +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. +; +; Data covering all possible combinations of character flags for target specific definition +; + +.include "ctype.inc" +.export __ctype + +; This data is a table of possible ctype combinations, possible during + +.rodata +__ctype: +ct_none: .byte CT_NONE +ct_lower: .byte CT_LOWER +ct_upper: .byte CT_UPPER +ct_digit_xdigit: .byte CT_DIGIT | CT_XDIGIT +ct_lower_xdigit: .byte CT_LOWER | CT_XDIGIT +ct_upper_xdigit: .byte CT_UPPER | CT_XDIGIT +ct_ctrl: .byte CT_CTRL +ct_ws: .byte CT_OTHER_WS +ct_ctrl_ws: .byte CT_CTRL | CT_OTHER_WS +ct_space_spacetab: .byte CT_SPACE | CT_SPACE_TAB +ct_ctrl_ws_spacetab: .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB + +; build indices out of the table above: + +CT_NONE_IDX = ct_none - __ctype +CT_LOWER_IDX = ct_lower - __ctype +CT_UPPER_IDX = ct_upper - __ctype +CT_DIGIT_XDIGIT_IDX = ct_digit_xdigit - __ctype +CT_LOWER_XDIGIT_IDX = ct_lower_xdigit - __ctype +CT_UPPER_XDIGIT_IDX = ct_upper_xdigit - __ctype +CT_CTRL_IDX = ct_ctrl - __ctype +CT_WS_IDX = ct_ws - __ctype +CT_CTRL_WS_IDX = ct_ctrl_ws - __ctype +CT_SPACE_SPACETAB_IDX = ct_space_spacetab - __ctype +CT_CTRL_WS_SPACETAB_IDX = ct_ctrl_ws_spacetab - __ctype + +.macro ct_mix lower, upper + .byte ((lower) & $0F) | ((upper) << 4) +.endmacro diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 8691f9471..dba0a0288 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -249,7 +249,6 @@ Here is a description of all the command line options: <item><tt/strcmp()/ <item><tt/strcpy()/ <item><tt/strlen()/ - <item>most of the functions declared in <tt/<ctype.h>/ </itemize> Note: This has two consequences: @@ -259,9 +258,7 @@ Here is a description of all the command line options: using <tt/--eagerly-inline-funcs/ actually will break things. <p> <item>The inlined string and memory functions will not handle strings or - memory areas larger than 255 bytes. Similarly, the inlined <tt/is..()/ - functions will not work with values outside the char. range (such as - <tt/EOF/). + memory areas larger than 255 bytes. <p> </itemize> diff --git a/doc/funcref.sgml b/doc/funcref.sgml index b6171a0ef..94e850092 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -4232,11 +4232,6 @@ to undefined behaviour. is a letter or digit. The return value is zero if the character is anything else. <tag/Notes/<itemize> -<item>When compiling with <tt/-Os/ the function is actually a macro. The -inline sequence generated by the macro will not work correctly for values -outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of -this range. The non inline function may be accessed by <tt/#undef/'ing -the macro. <item>When compiling without <tt/-Os/, the function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4269,11 +4264,6 @@ fastcall function, so it may only be used in presence of a prototype. <tag/Description/The function returns a non zero value if the given argument is a letter. The return value is zero if the character is anything else. <tag/Notes/<itemize> -<item>When compiling with <tt/-Os/ the function is actually a macro. The -inline sequence generated by the macro will not work correctly for values -outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of -this range. The non inline function may be accessed by <tt/#undef/'ing the -macro. <item>When compiling without <tt/-Os/, the function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4305,12 +4295,6 @@ fastcall function, so it may only be used in presence of a prototype. <tag/Declaration/<tt/int __fastcall__ isascii (int c);/ <tag/Description/The function returns a non zero value if the given argument is in the range 0..127 (the range of valid ASCII characters) and zero if not. -<tag/Notes/<itemize> -<item>When compiling with <tt/-Os/ the function is actually a macro. The -inline sequence generated by the macro will not work correctly for values -outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of -this range. The non inline function may be accessed by <tt/#undef/'ing the -macro. <item>When compiling without <tt/-Os/, the function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4344,11 +4328,6 @@ fastcall function, so it may only be used in presence of a prototype. is a space or tab character. The return value is zero if the character is anything else. <tag/Notes/<itemize> -<item>When compiling with <tt/-Os/ the function is actually a macro. The -inline sequence generated by the macro will not work correctly for values -outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of -this range. The non inline function may be accessed by <tt/#undef/'ing the -macro. <item>When compiling without <tt/-Os/, the function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4382,11 +4361,6 @@ fastcall function, so it may only be used in presence of a prototype. is a control character. The return value is zero if the character is anything else. <tag/Notes/<itemize> -<item>When compiling with <tt/-Os/ the function is actually a macro. The -inline sequence generated by the macro will not work correctly for values -outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of -this range. The non inline function may be accessed by <tt/#undef/'ing the -macro. <item>When compiling without <tt/-Os/, the function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4418,12 +4392,6 @@ fastcall function, so it may only be used in presence of a prototype. <tag/Declaration/<tt/int __fastcall__ isdigit (int c);/ <tag/Description/The function returns a non zero value if the given argument is a digit. The return value is zero if the character is anything else. -<tag/Notes/<itemize> -<item>When compiling with <tt/-Os/ the function is actually a macro. The -inline sequence generated by the macro will not work correctly for values -outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of -this range. The non inline function may be accessed by <tt/#undef/'ing the -macro. <item>When compiling without <tt/-Os/, the function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4479,11 +4447,6 @@ space). is a printable character with the exception of space. The return value is zero if the character is anything else. <tag/Notes/<itemize> -<item>When compiling with <tt/-Os/ the function is actually a macro. The -inline sequence generated by the macro will not work correctly for values -outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of -this range. The non inline function may be accessed by <tt/#undef/'ing the -macro. <item>When compiling without <tt/-Os/, the function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4517,11 +4480,6 @@ fastcall function, so it may only be used in presence of a prototype. is a lower case letter. The return value is zero if the character is anything else. <tag/Notes/<itemize> -<item>When compiling with <tt/-Os/ the function is actually a macro. The -inline sequence generated by the macro will not work correctly for values -outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of -this range. The non inline function may be accessed by <tt/#undef/'ing the -macro. <item>When compiling without <tt/-Os/, the function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4555,11 +4513,6 @@ fastcall function, so it may only be used in presence of a prototype. is a printable character (this includes the space character). The return value is zero if the character is anything else. <tag/Notes/<itemize> -<item>When compiling with <tt/-Os/ the function is actually a macro. The -inline sequence generated by the macro will not work correctly for values -outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of -this range. The non inline function may be accessed by <tt/#undef/'ing the -macro. <item>When compiling without <tt/-Os/, the function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4594,11 +4547,6 @@ space or an alphanumeric character. is a printable character, but not a space or anything alphanumeric. The return value is zero if the character is anything else. <tag/Notes/<itemize> -<item>When compiling with <tt/-Os/ the function is actually a macro. The -inline sequence generated by the macro will not work correctly for values -outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of -this range. The non inline function may be accessed by <tt/#undef/'ing the -macro. <item>When compiling without <tt/-Os/, the function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4634,11 +4582,6 @@ anything else. The standard white space characters are: space, formfeed ('\f'), newline ('\n'), carriage return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). <tag/Notes/<itemize> -<item>When compiling with <tt/-Os/ the function is actually a macro. The -inline sequence generated by the macro will not work correctly for values -outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of -this range. The non inline function may be accessed by <tt/#undef/'ing the -macro. <item>When compiling without <tt/-Os/, the function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4672,11 +4615,6 @@ fastcall function, so it may only be used in presence of a prototype. is an upper case letter. The return value is zero if the character is anything else. <tag/Notes/<itemize> -<item>When compiling with <tt/-Os/ the function is actually a macro. The -inline sequence generated by the macro will not work correctly for values -outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of -this range. The non inline function may be accessed by <tt/#undef/'ing the -macro. <item>When compiling without <tt/-Os/, the function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4710,11 +4648,6 @@ fastcall function, so it may only be used in presence of a prototype. is a hexadecimal digit (0..9, a..f and A..F). The return value is zero if the character is anything else. <tag/Notes/<itemize> -<item>When compiling with <tt/-Os/ the function is actually a macro. The -inline sequence generated by the macro will not work correctly for values -outside the range 0..255. <em/Note:/ The constant <tt/EOF/ is not part of -this range. The non inline function may be accessed by <tt/#undef/'ing the -macro. <item>When compiling without <tt/-Os/, the function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> diff --git a/include/ctype.h b/include/ctype.h index 103f6cc22..d842228e9 100644 --- a/include/ctype.h +++ b/include/ctype.h @@ -36,10 +36,6 @@ #ifndef _CTYPE_H #define _CTYPE_H - -/* The array containing character classification data */ -extern unsigned char _ctype[256]; - /* Bits used to specify character classes */ #define _CT_LOWER 0x01 /* 0 - Lower case char */ #define _CT_UPPER 0x02 /* 1 - Upper case char */ @@ -61,6 +57,7 @@ extern unsigned char _ctype[256]; /* Character classification functions */ int __fastcall__ isalnum (int c); int __fastcall__ isalpha (int c); +int __fastcall__ isascii (int c); int __fastcall__ iscntrl (int c); int __fastcall__ isdigit (int c); int __fastcall__ isgraph (int c); @@ -82,102 +79,6 @@ unsigned char __fastcall__ toascii (unsigned char c); /* Convert a target-specific character to ASCII. */ #endif - - -/* When --eagerly-inline-funcs is enabled, overload most of the above -** functions by macroes. The function prototypes are available again after -** #undef'ing the macroes. -** Please note that the following macroes do NOT handle EOF correctly, as -** stated in the manual. If you need correct behaviour for EOF, don't -** use --eagerly-inline-funcs, or #undefine the following macroes. -*/ -#ifdef __EAGERLY_INLINE_FUNCS__ - -#define isalnum(c) (__AX__ = (c), \ - __asm__ ("tay"), \ - __asm__ ("lda %v,y", _ctype), \ - __asm__ ("and #%b", _CT_ALNUM), \ - __AX__) - -#define isalpha(c) (__AX__ = (c), \ - __asm__ ("tay"), \ - __asm__ ("lda %v,y", _ctype), \ - __asm__ ("and #%b", _CT_ALPHA), \ - __AX__) - -#if __CC65_STD__ >= __CC65_STD_C99__ -#define isblank(c) (__AX__ = (c), \ - __asm__ ("tay"), \ - __asm__ ("lda %v,y", _ctype), \ - __asm__ ("and #%b", _CT_SPACE_TAB), \ - __AX__) -#endif - -#define iscntrl(c) (__AX__ = (c), \ - __asm__ ("tay"), \ - __asm__ ("lda %v,y", _ctype), \ - __asm__ ("and #%b", _CT_CNTRL), \ - __AX__) - -#define isdigit(c) (__AX__ = (c), \ - __asm__ ("tay"), \ - __asm__ ("lda %v,y", _ctype), \ - __asm__ ("and #%b", _CT_DIGIT), \ - __AX__) - -#define isgraph(c) (__AX__ = (c), \ - __asm__ ("tay"), \ - __asm__ ("lda %v,y", _ctype), \ - __asm__ ("and #%b", _CT_NOT_GRAPH), \ - __asm__ ("cmp #1"), \ - __asm__ ("lda #1"), \ - __asm__ ("sbc #1"), \ - __AX__) - -#define islower(c) (__AX__ = (c), \ - __asm__ ("tay"), \ - __asm__ ("lda %v,y", _ctype), \ - __asm__ ("and #%b", _CT_LOWER), \ - __AX__) - -#define isprint(c) (__AX__ = (c), \ - __asm__ ("tay"), \ - __asm__ ("lda %v,y", _ctype), \ - __asm__ ("and #%b", _CT_NOT_PRINT), \ - __asm__ ("eor #%b", _CT_NOT_PRINT), \ - __AX__) - -#define ispunct(c) (__AX__ = (c), \ - __asm__ ("tay"), \ - __asm__ ("lda %v,y", _ctype), \ - __asm__ ("and #%b", _CT_NOT_PUNCT), \ - __asm__ ("cmp #1"), \ - __asm__ ("lda #1"), \ - __asm__ ("sbc #1"), \ - __AX__) - -#define isspace(c) (__AX__ = (c), \ - __asm__ ("tay"), \ - __asm__ ("lda %v,y", _ctype), \ - __asm__ ("and #%b", _CT_WS), \ - __AX__) - -#define isupper(c) (__AX__ = (c), \ - __asm__ ("tay"), \ - __asm__ ("lda %v,y", _ctype), \ - __asm__ ("and #%b", _CT_UPPER), \ - __AX__) - -#define isxdigit(c) (__AX__ = (c), \ - __asm__ ("tay"), \ - __asm__ ("lda %v,y", _ctype), \ - __asm__ ("and #%b", _CT_XDIGIT), \ - __AX__) - -#endif - - - /* End of ctype.h */ #endif diff --git a/libsrc/apple2/ctype.s b/libsrc/apple2/ctype.s index fa9a65c8b..da4d38472 100644 --- a/libsrc/apple2/ctype.s +++ b/libsrc/apple2/ctype.s @@ -1,161 +1,5 @@ -; -; Stefan Haubenthal with minor changes from Ullrich von Bassewitz, 2003-05-02 -; ; Character specification table. ; +; uses the "console" definition - .include "ctype.inc" - -; The tables are readonly, put them into the rodata segment - -.rodata - -; The following 256 byte wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it -; has major advantages: -; -; * It is fast. If it were'nt for the slow parameter passing of cc65, one -; could even define macros for the isxxx functions (this is usually -; done on other platforms). -; -; * It is highly portable. The only unportable part is the table itself, -; all real code goes into the common library. -; -; * We save some code in the isxxx functions. - - -__ctype: - .repeat 2 - .byte CT_CTRL ; 0/00 ___ctrl_@___ - .byte CT_CTRL ; 1/01 ___ctrl_A___ - .byte CT_CTRL ; 2/02 ___ctrl_B___ - .byte CT_CTRL ; 3/03 ___ctrl_C___ - .byte CT_CTRL ; 4/04 ___ctrl_D___ - .byte CT_CTRL ; 5/05 ___ctrl_E___ - .byte CT_CTRL ; 6/06 ___ctrl_F___ - .byte CT_CTRL ; 7/07 ___ctrl_G___ - .byte CT_CTRL ; 8/08 ___ctrl_H___ - .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB - ; 9/09 ___ctrl_I___ - .byte CT_CTRL | CT_OTHER_WS ; 10/0a ___ctrl_J___ - .byte CT_CTRL | CT_OTHER_WS ; 11/0b ___ctrl_K___ - .byte CT_CTRL | CT_OTHER_WS ; 12/0c ___ctrl_L___ - .byte CT_CTRL | CT_OTHER_WS ; 13/0d ___ctrl_M___ - .byte CT_CTRL ; 14/0e ___ctrl_N___ - .byte CT_CTRL ; 15/0f ___ctrl_O___ - .byte CT_CTRL ; 16/10 ___ctrl_P___ - .byte CT_CTRL ; 17/11 ___ctrl_Q___ - .byte CT_CTRL ; 18/12 ___ctrl_R___ - .byte CT_CTRL ; 19/13 ___ctrl_S___ - .byte CT_CTRL ; 20/14 ___ctrl_T___ - .byte CT_CTRL ; 21/15 ___ctrl_U___ - .byte CT_CTRL ; 22/16 ___ctrl_V___ - .byte CT_CTRL ; 23/17 ___ctrl_W___ - .byte CT_CTRL ; 24/18 ___ctrl_X___ - .byte CT_CTRL ; 25/19 ___ctrl_Y___ - .byte CT_CTRL ; 26/1a ___ctrl_Z___ - .byte CT_CTRL ; 27/1b ___ctrl_[___ - .byte CT_CTRL ; 28/1c ___ctrl_\___ - .byte CT_CTRL ; 29/1d ___ctrl_]___ - .byte CT_CTRL ; 30/1e ___ctrl_^___ - .byte CT_CTRL ; 31/1f ___ctrl_____ - .byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___ - .byte CT_NONE ; 33/21 _____!_____ - .byte CT_NONE ; 34/22 _____"_____ - .byte CT_NONE ; 35/23 _____#_____ - .byte CT_NONE ; 36/24 _____$_____ - .byte CT_NONE ; 37/25 _____%_____ - .byte CT_NONE ; 38/26 _____&_____ - .byte CT_NONE ; 39/27 _____'_____ - .byte CT_NONE ; 40/28 _____(_____ - .byte CT_NONE ; 41/29 _____)_____ - .byte CT_NONE ; 42/2a _____*_____ - .byte CT_NONE ; 43/2b _____+_____ - .byte CT_NONE ; 44/2c _____,_____ - .byte CT_NONE ; 45/2d _____-_____ - .byte CT_NONE ; 46/2e _____._____ - .byte CT_NONE ; 47/2f _____/_____ - .byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____ - .byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____ - .byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____ - .byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____ - .byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____ - .byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____ - .byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____ - .byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____ - .byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____ - .byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____ - .byte CT_NONE ; 58/3a _____:_____ - .byte CT_NONE ; 59/3b _____;_____ - .byte CT_NONE ; 60/3c _____<_____ - .byte CT_NONE ; 61/3d _____=_____ - .byte CT_NONE ; 62/3e _____>_____ - .byte CT_NONE ; 63/3f _____?_____ - - .byte CT_NONE ; 64/40 _____@_____ - .byte CT_UPPER | CT_XDIGIT ; 65/41 _____A_____ - .byte CT_UPPER | CT_XDIGIT ; 66/42 _____B_____ - .byte CT_UPPER | CT_XDIGIT ; 67/43 _____C_____ - .byte CT_UPPER | CT_XDIGIT ; 68/44 _____D_____ - .byte CT_UPPER | CT_XDIGIT ; 69/45 _____E_____ - .byte CT_UPPER | CT_XDIGIT ; 70/46 _____F_____ - .byte CT_UPPER ; 71/47 _____G_____ - .byte CT_UPPER ; 72/48 _____H_____ - .byte CT_UPPER ; 73/49 _____I_____ - .byte CT_UPPER ; 74/4a _____J_____ - .byte CT_UPPER ; 75/4b _____K_____ - .byte CT_UPPER ; 76/4c _____L_____ - .byte CT_UPPER ; 77/4d _____M_____ - .byte CT_UPPER ; 78/4e _____N_____ - .byte CT_UPPER ; 79/4f _____O_____ - .byte CT_UPPER ; 80/50 _____P_____ - .byte CT_UPPER ; 81/51 _____Q_____ - .byte CT_UPPER ; 82/52 _____R_____ - .byte CT_UPPER ; 83/53 _____S_____ - .byte CT_UPPER ; 84/54 _____T_____ - .byte CT_UPPER ; 85/55 _____U_____ - .byte CT_UPPER ; 86/56 _____V_____ - .byte CT_UPPER ; 87/57 _____W_____ - .byte CT_UPPER ; 88/58 _____X_____ - .byte CT_UPPER ; 89/59 _____Y_____ - .byte CT_UPPER ; 90/5a _____Z_____ - .byte CT_NONE ; 91/5b _____[_____ - .byte CT_NONE ; 92/5c _____\_____ - .byte CT_NONE ; 93/5d _____]_____ - .byte CT_NONE ; 94/5e _____^_____ - .byte CT_NONE ; 95/5f _UNDERLINE_ - .byte CT_NONE ; 96/60 ___grave___ - .byte CT_LOWER | CT_XDIGIT ; 97/61 _____a_____ - .byte CT_LOWER | CT_XDIGIT ; 98/62 _____b_____ - .byte CT_LOWER | CT_XDIGIT ; 99/63 _____c_____ - .byte CT_LOWER | CT_XDIGIT ; 100/64 _____d_____ - .byte CT_LOWER | CT_XDIGIT ; 101/65 _____e_____ - .byte CT_LOWER | CT_XDIGIT ; 102/66 _____f_____ - .byte CT_LOWER ; 103/67 _____g_____ - .byte CT_LOWER ; 104/68 _____h_____ - .byte CT_LOWER ; 105/69 _____i_____ - .byte CT_LOWER ; 106/6a _____j_____ - .byte CT_LOWER ; 107/6b _____k_____ - .byte CT_LOWER ; 108/6c _____l_____ - .byte CT_LOWER ; 109/6d _____m_____ - .byte CT_LOWER ; 110/6e _____n_____ - .byte CT_LOWER ; 111/6f _____o_____ - .byte CT_LOWER ; 112/70 _____p_____ - .byte CT_LOWER ; 113/71 _____q_____ - .byte CT_LOWER ; 114/72 _____r_____ - .byte CT_LOWER ; 115/73 _____s_____ - .byte CT_LOWER ; 116/74 _____t_____ - .byte CT_LOWER ; 117/75 _____u_____ - .byte CT_LOWER ; 118/76 _____v_____ - .byte CT_LOWER ; 119/77 _____w_____ - .byte CT_LOWER ; 120/78 _____x_____ - .byte CT_LOWER ; 121/79 _____y_____ - .byte CT_LOWER ; 122/7a _____z_____ - .byte CT_NONE ; 123/7b _____{_____ - .byte CT_NONE ; 124/7c _____|_____ - .byte CT_NONE ; 125/7d _____}_____ - .byte CT_NONE ; 126/7e _____~_____ - .byte CT_OTHER_WS ; 127/7f ____DEL____ - .endrepeat - - + .include "ctype_console.inc" diff --git a/libsrc/atari/ctype.s b/libsrc/atari/ctype.s index 73553dc15..8173b2ea8 100644 --- a/libsrc/atari/ctype.s +++ b/libsrc/atari/ctype.s @@ -1,301 +1,156 @@ +; ctype.s ; -; Ullrich von Bassewitz, 02.06.1998 +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems ; -; Character specification table. +; https://github.com/cc65/cc65 ; -; adapted to Atari by Christian Groessler, June 2000 +; See "LICENSE" file for legal information. +; +; Atari character specification table. ; + .include "ctypetable.inc" + .export __ctypeIdx + ; The tables are readonly, put them into the rodata segment .rodata -; The following 256 byte wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it -; has major advantages: -; -; * It is fast. If it were'nt for the slow parameter passing of cc65, one -; could even define macros for the isxxx functions (this is usually -; done on other platforms). -; -; * It is highly portable. The only unportable part is the table itself, -; all real code goes into the common library. -; -; * We save some code in the isxxx functions. -; -; -; Bit assignments: -; -; 0 - Lower case char -; 1 - Upper case char -; 2 - Numeric digit -; 3 - Hex digit (both, lower and upper) -; 4 - Control character -; 5 - The space character itself -; 6 - Other whitespace (that is: '\f', '\n', '\r', '\t' and '\v') -; 7 - Space or tab character +__ctypeIdx: + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 0/00 ___heart____, 1/01 ___l_tee____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 2/02 ___ctrl_B___, 3/03 ___ctrl_C___ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 4/04 ___r_tee____, 5/05 ___ctrl_E___ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 6/06 ___ctrl_F___, 7/07 ___ctrl_G___ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 8/08 ___ctrl_H___, 9/09 ___ctrl_I___ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 10/0a ___ctrl_J___, 11/0b ___ctrl_K___ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 12/0c ___ctrl_L___, 13/0d ___ctrl_M___ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 14/0e ___ctrl_N___, 15/0f ___ctrl_O___ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 16/10 ____club____, 17/11 ___ctrl_Q___ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 18/12 ___h_line___, 19/13 ___ctrl_S___ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 20/14 ____ball____, 21/15 ___ctrl_U___ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 22/16 ___ctrl_V___, 23/17 ___t_tee____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 24/18 ___b_tee____, 25/19 ___ctrl_Y___ + ct_mix CT_NONE_IDX, CT_CTRL_IDX ; 26/1a ___ctrl_Z___, 27/1b ____ESC_____ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 28/1c ___crsr_up__, 29/1d ___crsr_dn__ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 30/1e ___crsr_lf__, 31/1f ___crsr_rg__ - .export __ctype + ct_mix CT_SPACE_SPACETAB_IDX, CT_NONE_IDX ; 32/20 ___SPACE___, 33/21 _____!_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 34/22 _____"_____, 35/23 _____#_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 36/24 _____$_____, 37/25 _____%_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 38/26 _____&_____, 39/27 _____'_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 40/28 _____(_____, 41/29 _____)_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 42/2a _____*_____, 43/2b _____+_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 44/2c _____,_____, 45/2d _____-_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 46/2e _____._____, 47/2f _____/_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 48/30 _____0_____, 49/31 _____1_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 50/32 _____2_____, 51/33 _____3_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 52/34 _____4_____, 53/35 _____5_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 54/36 _____6_____, 55/37 _____7_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 56/38 _____8_____, 57/39 _____9_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 58/3a _____:_____, 59/3b _____;_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 60/3c _____<_____, 61/3d _____=_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 62/3e _____>_____, 63/3f _____?_____ -__ctype: - .byte $00 ; 0/00 ___heart____ - .byte $00 ; 1/01 ___l_tee____ - .byte $00 ; 2/02 ___ctrl_B___ - .byte $00 ; 3/03 ___ctrl_C___ - .byte $00 ; 4/04 ___r_tee____ - .byte $00 ; 5/05 ___ctrl_E___ - .byte $00 ; 6/06 ___ctrl_F___ - .byte $00 ; 7/07 ___ctrl_G___ - .byte $00 ; 8/08 ___ctrl_H___ - .byte $00 ; 9/09 ___ctrl_I___ - .byte $00 ; 10/0a ___ctrl_J___ - .byte $00 ; 11/0b ___ctrl_K___ - .byte $00 ; 12/0c ___ctrl_L___ - .byte $00 ; 13/0d ___ctrl_M___ - .byte $00 ; 14/0e ___ctrl_N___ - .byte $00 ; 15/0f ___ctrl_O___ - .byte $00 ; 16/10 ____club____ - .byte $00 ; 17/11 ___ctrl_Q___ - .byte $00 ; 18/12 ___h_line___ - .byte $00 ; 19/13 ___ctrl_S___ - .byte $00 ; 20/14 ____ball____ - .byte $00 ; 21/15 ___ctrl_U___ - .byte $00 ; 22/16 ___ctrl_V___ - .byte $00 ; 23/17 ___t_tee____ - .byte $00 ; 24/18 ___b_tee____ - .byte $00 ; 25/19 ___ctrl_Y___ - .byte $00 ; 26/1a ___ctrl_Z___ - .byte $10 ; 27/1b ____ESC_____ - .byte $10 ; 28/1c ___crsr_up__ - .byte $10 ; 29/1d ___crsr_dn__ - .byte $10 ; 30/1e ___crsr_lf__ - .byte $10 ; 31/1f ___crsr_rg__ - .byte $A0 ; 32/20 ___SPACE___ - .byte $00 ; 33/21 _____!_____ - .byte $00 ; 34/22 _____"_____ - .byte $00 ; 35/23 _____#_____ - .byte $00 ; 36/24 _____$_____ - .byte $00 ; 37/25 _____%_____ - .byte $00 ; 38/26 _____&_____ - .byte $00 ; 39/27 _____'_____ - .byte $00 ; 40/28 _____(_____ - .byte $00 ; 41/29 _____)_____ - .byte $00 ; 42/2a _____*_____ - .byte $00 ; 43/2b _____+_____ - .byte $00 ; 44/2c _____,_____ - .byte $00 ; 45/2d _____-_____ - .byte $00 ; 46/2e _____._____ - .byte $00 ; 47/2f _____/_____ - .byte $0C ; 48/30 _____0_____ - .byte $0C ; 49/31 _____1_____ - .byte $0C ; 50/32 _____2_____ - .byte $0C ; 51/33 _____3_____ - .byte $0C ; 52/34 _____4_____ - .byte $0C ; 53/35 _____5_____ - .byte $0C ; 54/36 _____6_____ - .byte $0C ; 55/37 _____7_____ - .byte $0C ; 56/38 _____8_____ - .byte $0C ; 57/39 _____9_____ - .byte $00 ; 58/3a _____:_____ - .byte $00 ; 59/3b _____;_____ - .byte $00 ; 60/3c _____<_____ - .byte $00 ; 61/3d _____=_____ - .byte $00 ; 62/3e _____>_____ - .byte $00 ; 63/3f _____?_____ + ct_mix CT_NONE_IDX, CT_UPPER_XDIGIT_IDX ; 64/40 _____@_____, 65/41 _____A_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_XDIGIT_IDX ; 66/42 _____B_____, 67/43 _____C_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_XDIGIT_IDX ; 68/44 _____D_____, 69/45 _____E_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_IDX ; 70/46 _____F_____, 71/47 _____G_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 72/48 _____H_____, 73/49 _____I_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 74/4a _____J_____, 75/4b _____K_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 76/4c _____L_____, 77/4d _____M_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 78/4e _____N_____, 79/4f _____O_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 80/50 _____P_____, 81/51 _____Q_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 82/52 _____R_____, 83/53 _____S_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 84/54 _____T_____, 85/55 _____U_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 86/56 _____V_____, 87/57 _____W_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 88/58 _____X_____, 89/59 _____Y_____ + ct_mix CT_UPPER_IDX, CT_NONE_IDX ; 90/5a _____Z_____, 91/5b _____[_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 92/5c _____\_____, 93/5d _____]_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 94/5e _____^_____, 95/5f _UNDERLINE_ - .byte $00 ; 64/40 _____@_____ - .byte $0A ; 65/41 _____A_____ - .byte $0A ; 66/42 _____B_____ - .byte $0A ; 67/43 _____C_____ - .byte $0A ; 68/44 _____D_____ - .byte $0A ; 69/45 _____E_____ - .byte $0A ; 70/46 _____F_____ - .byte $02 ; 71/47 _____G_____ - .byte $02 ; 72/48 _____H_____ - .byte $02 ; 73/49 _____I_____ - .byte $02 ; 74/4a _____J_____ - .byte $02 ; 75/4b _____K_____ - .byte $02 ; 76/4c _____L_____ - .byte $02 ; 77/4d _____M_____ - .byte $02 ; 78/4e _____N_____ - .byte $02 ; 79/4f _____O_____ - .byte $02 ; 80/50 _____P_____ - .byte $02 ; 81/51 _____Q_____ - .byte $02 ; 82/52 _____R_____ - .byte $02 ; 83/53 _____S_____ - .byte $02 ; 84/54 _____T_____ - .byte $02 ; 85/55 _____U_____ - .byte $02 ; 86/56 _____V_____ - .byte $02 ; 87/57 _____W_____ - .byte $02 ; 88/58 _____X_____ - .byte $02 ; 89/59 _____Y_____ - .byte $02 ; 90/5a _____Z_____ - .byte $00 ; 91/5b _____[_____ - .byte $00 ; 92/5c _____\_____ - .byte $00 ; 93/5d _____]_____ - .byte $00 ; 94/5e _____^_____ - .byte $00 ; 95/5f _UNDERLINE_ - .byte $00 ; 96/60 __diamond__ - .byte $09 ; 97/61 _____a_____ - .byte $09 ; 98/62 _____b_____ - .byte $09 ; 99/63 _____c_____ - .byte $09 ; 100/64 _____d_____ - .byte $09 ; 101/65 _____e_____ - .byte $09 ; 102/66 _____f_____ - .byte $01 ; 103/67 _____g_____ - .byte $01 ; 104/68 _____h_____ - .byte $01 ; 105/69 _____i_____ - .byte $01 ; 106/6a _____j_____ - .byte $01 ; 107/6b _____k_____ - .byte $01 ; 108/6c _____l_____ - .byte $01 ; 109/6d _____m_____ - .byte $01 ; 110/6e _____n_____ - .byte $01 ; 111/6f _____o_____ - .byte $01 ; 112/70 _____p_____ - .byte $01 ; 113/71 _____q_____ - .byte $01 ; 114/72 _____r_____ - .byte $01 ; 115/73 _____s_____ - .byte $01 ; 116/74 _____t_____ - .byte $01 ; 117/75 _____u_____ - .byte $01 ; 118/76 _____v_____ - .byte $01 ; 119/77 _____w_____ - .byte $01 ; 120/78 _____x_____ - .byte $01 ; 121/79 _____y_____ - .byte $01 ; 122/7a _____z_____ - .byte $00 ; 123/7b ___spade___ - .byte $00 ; 124/7c __v_line___ - .byte $10 ; 125/7d __CLRSCR___ - .byte $D0 ; 126/7e __backtab__ - .byte $D0 ; 127/7f ____tab____ + ct_mix CT_NONE_IDX, CT_LOWER_XDIGIT_IDX ; 96/60 __diamond__, 97/61 _____a_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_XDIGIT_IDX ; 98/62 _____b_____, 99/63 _____c_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_XDIGIT_IDX ; 100/64 _____d_____, 101/65 _____e_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_IDX ; 102/66 _____f_____, 103/67 _____g_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 104/68 _____h_____, 105/69 _____i_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 106/6a _____j_____, 107/6b _____k_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 108/6c _____l_____, 109/6d _____m_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 110/6e _____n_____, 111/6f _____o_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 112/70 _____p_____, 113/71 _____q_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 114/72 _____r_____, 115/73 _____s_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 116/74 _____t_____, 117/75 _____u_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 118/76 _____v_____, 119/77 _____w_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 120/78 _____x_____, 121/79 _____y_____ + ct_mix CT_LOWER_IDX, CT_NONE_IDX ; 122/7a _____z_____, 123/7b ___spade___ + ct_mix CT_NONE_IDX, CT_CTRL_IDX ; 124/7c __v_line___, 125/7d __CLRSCR___ + ct_mix CT_CTRL_WS_SPACETAB_IDX, CT_CTRL_WS_SPACETAB_IDX + ; 126/7e __backtab__, 127/7f ____tab____ - .byte $00 ; 128/80 _inv_heart___ - .byte $00 ; 129/81 _inv_l_tee___ - .byte $00 ; 130/82 _inv_ctrl_B__ - .byte $00 ; 131/83 _inv_ctrl_C__ - .byte $00 ; 132/84 _inv_r_tee___ - .byte $00 ; 133/85 _inv_ctrl_E__ - .byte $00 ; 134/86 _inv_ctrl_F__ - .byte $00 ; 135/87 _inv_ctrl_G__ - .byte $00 ; 136/88 _inv_ctrl_H__ - .byte $00 ; 137/89 _inv_ctrl_I__ - .byte $00 ; 138/8a _inv_ctrl_J__ - .byte $00 ; 139/8b _inv_ctrl_K__ - .byte $00 ; 140/8c _inv_ctrl_L__ - .byte $00 ; 141/8d _inv_ctrl_M__ - .byte $00 ; 142/8e _inv_ctrl_N__ - .byte $00 ; 143/8f _inv_ctrl_O__ - .byte $00 ; 144/90 __inv__club__ - .byte $00 ; 145/91 _inv_ctrl_Q__ - .byte $00 ; 146/92 _inv_h_line__ - .byte $00 ; 147/93 _inv_ctrl_S__ - .byte $00 ; 148/94 __inv__ball__ - .byte $00 ; 149/95 _inv_ctrl_U__ - .byte $00 ; 150/96 _inv_ctrl_V__ - .byte $00 ; 151/97 __inv_t_tee__ - .byte $00 ; 152/98 __inv_b_tee__ - .byte $00 ; 153/99 _inv_ctrl_Y__ - .byte $00 ; 154/9a _inv_ctrl_Z__ - .byte $50 ; 155/9b _____EOL_____ - .byte $10 ; 156/9c ___CLRLINE___ - .byte $10 ; 157/9d ___INSLINE___ - .byte $10 ; 158/9e ____CLRTAB___ - .byte $10 ; 159/9f ____INSTAB___ - .byte $A0 ; 160/a0 __inv_SPACE__ - .byte $00 ; 161/a1 ___inv_!_____ - .byte $00 ; 162/a2 ___inv_"_____ - .byte $00 ; 163/a3 ___inv_#_____ - .byte $00 ; 164/a4 ___inv_$_____ - .byte $00 ; 165/a5 ___inv_%_____ - .byte $00 ; 166/a6 ___inv_&_____ - .byte $00 ; 167/a7 ___inv_'_____ - .byte $00 ; 168/a8 ___inv_(_____ - .byte $00 ; 169/a9 ___inv_)_____ - .byte $00 ; 170/aa ___inv_*_____ - .byte $00 ; 171/ab ___inv_+_____ - .byte $00 ; 172/ac ___inv_,_____ - .byte $00 ; 173/ad ___inv_-_____ - .byte $00 ; 174/ae ___inv_._____ - .byte $00 ; 175/af ___inv_/_____ - .byte $0C ; 176/b0 ___inv_0_____ - .byte $0C ; 177/b1 ___inv_1_____ - .byte $0C ; 178/b2 ___inv_2_____ - .byte $0C ; 179/b3 ___inv_3_____ - .byte $0C ; 180/b4 ___inv_4_____ - .byte $0C ; 181/b5 ___inv_5_____ - .byte $0C ; 182/b6 ___inv_6_____ - .byte $0C ; 183/b7 ___inv_7_____ - .byte $0C ; 184/b8 ___inv_8_____ - .byte $0C ; 185/b9 ___inv_9_____ - .byte $00 ; 186/ba ___inv_:_____ - .byte $00 ; 187/bb ___inv_;_____ - .byte $00 ; 188/bc ___inv_<_____ - .byte $00 ; 189/bd ___inv_=_____ - .byte $00 ; 190/be ___inv_>_____ - .byte $00 ; 191/bf ___inv_?_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 128/80 _inv_heart___, 129/81 _inv_l_tee___ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 130/82 _inv_ctrl_B__, 131/83 _inv_ctrl_C__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 132/84 _inv_r_tee___, 133/85 _inv_ctrl_E__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 134/86 _inv_ctrl_F__, 135/87 _inv_ctrl_G__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 136/88 _inv_ctrl_H__, 137/89 _inv_ctrl_I__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 138/8a _inv_ctrl_J__, 139/8b _inv_ctrl_K__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 140/8c _inv_ctrl_L__, 141/8d _inv_ctrl_M__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 142/8e _inv_ctrl_N__, 143/8f _inv_ctrl_O__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 144/90 __inv__club__, 145/91 _inv_ctrl_Q__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 146/92 _inv_h_line__, 147/93 _inv_ctrl_S__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 148/94 __inv__ball__, 149/95 _inv_ctrl_U__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 150/96 _inv_ctrl_V__, 151/97 __inv_t_tee__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 152/98 __inv_b_tee__, 153/99 _inv_ctrl_Y__ + ct_mix CT_NONE_IDX, CT_CTRL_WS_IDX ; 154/9a _inv_ctrl_Z__, 155/9b _____EOL_____ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 156/9c ___CLRLINE___, 157/9d ___INSLINE___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 158/9e ____CLRTAB___, 159/9f ____INSTAB___ - .byte $00 ; 192/c0 ___inv_@_____ - .byte $0A ; 193/c1 ___inv_A_____ - .byte $0A ; 194/c2 ___inv_B_____ - .byte $0A ; 195/c3 ___inv_C_____ - .byte $0A ; 196/c4 ___inv_D_____ - .byte $0A ; 197/c5 ___inv_E_____ - .byte $0A ; 198/c6 ___inv_F_____ - .byte $02 ; 199/c7 ___inv_G_____ - .byte $02 ; 200/c8 ___inv_H_____ - .byte $02 ; 201/c9 ___inv_I_____ - .byte $02 ; 202/ca ___inv_J_____ - .byte $02 ; 203/cb ___inv_K_____ - .byte $02 ; 204/cc ___inv_L_____ - .byte $02 ; 205/cd ___inv_M_____ - .byte $02 ; 206/ce ___inv_N_____ - .byte $02 ; 207/cf ___inv_O_____ - .byte $02 ; 208/d0 ___inv_P_____ - .byte $02 ; 209/d1 ___inv_Q_____ - .byte $02 ; 210/d2 ___inv_R_____ - .byte $02 ; 211/d3 ___inv_S_____ - .byte $02 ; 212/d4 ___inv_T_____ - .byte $02 ; 213/d5 ___inv_U_____ - .byte $02 ; 214/d6 ___inv_V_____ - .byte $02 ; 215/d7 ___inv_W_____ - .byte $02 ; 216/d8 ___inv_X_____ - .byte $02 ; 217/d9 ___inv_Y_____ - .byte $02 ; 218/da ___inv_Z_____ - .byte $00 ; 219/db ___inv_[_____ - .byte $00 ; 220/dc ___inv_\_____ - .byte $00 ; 221/dd ___inv_]_____ - .byte $00 ; 222/de ___inv_^_____ - .byte $00 ; 223/df _inv_UNDRLIN_ - .byte $00 ; 224/e0 _inv_diamond_ - .byte $09 ; 225/e1 ___inv_a_____ - .byte $09 ; 226/e2 ___inv_b_____ - .byte $09 ; 227/e3 ___inv_c_____ - .byte $09 ; 228/e4 ___inv_d_____ - .byte $09 ; 229/e5 ___inv_e_____ - .byte $09 ; 230/e6 ___inv_f_____ - .byte $01 ; 231/e7 ___inv_g_____ - .byte $01 ; 232/e8 ___inv_h_____ - .byte $01 ; 233/e9 ___inv_i_____ - .byte $01 ; 234/ea ___inv_j_____ - .byte $01 ; 235/eb ___inv_k_____ - .byte $01 ; 236/ec ___inv_l_____ - .byte $01 ; 237/ed ___inv_m_____ - .byte $01 ; 238/ee ___inv_n_____ - .byte $01 ; 239/ef ___inv_o_____ - .byte $01 ; 240/f0 ___inv_p_____ - .byte $01 ; 241/f1 ___inv_q_____ - .byte $01 ; 242/f2 ___inv_r_____ - .byte $01 ; 243/f3 ___inv_s_____ - .byte $01 ; 244/f4 ___inv_t_____ - .byte $01 ; 245/f5 ___inv_u_____ - .byte $01 ; 246/f6 ___inv_v_____ - .byte $01 ; 247/f7 ___inv_w_____ - .byte $01 ; 248/f8 ___inv_x_____ - .byte $01 ; 249/f9 ___inv_y_____ - .byte $01 ; 250/fa ___inv_z_____ - .byte $00 ; 251/fb __inv_spade__ - .byte $00 ; 252/fc __inv_v_line_ - .byte $10 ; 253/fd ____BEEP_____ - .byte $10 ; 254/fe ____DELBS____ - .byte $10 ; 255/ff ___INSERT____ + ct_mix CT_SPACE_SPACETAB_IDX, CT_NONE_IDX ; 160/a0 __inv_SPACE__, 161/a1 ___inv_!_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 162/a2 ___inv_"_____, 163/a3 ___inv_#_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 164/a4 ___inv_$_____, 165/a5 ___inv_%_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 166/a6 ___inv_&_____, 167/a7 ___inv_'_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 168/a8 ___inv_(_____, 169/a9 ___inv_)_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 170/aa ___inv_*_____, 171/ab ___inv_+_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 172/ac ___inv_,_____, 173/ad ___inv_-_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 174/ae ___inv_._____, 175/af ___inv_/_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 176/b0 ___inv_0_____, 177/b1 ___inv_1_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 178/b2 ___inv_2_____, 179/b3 ___inv_3_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 180/b4 ___inv_4_____, 181/b5 ___inv_5_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 182/b6 ___inv_6_____, 183/b7 ___inv_7_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 184/b8 ___inv_8_____, 185/b9 ___inv_9_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 186/ba ___inv_:_____, 187/bb ___inv_;_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 188/bc ___inv_<_____, 189/bd ___inv_=_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 190/be ___inv_>_____, 191/bf ___inv_?_____ + ct_mix CT_NONE_IDX, CT_UPPER_XDIGIT_IDX ; 192/c0 ___inv_@_____, 193/c1 ___inv_A_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_XDIGIT_IDX ; 194/c2 ___inv_B_____, 195/c3 ___inv_C_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_XDIGIT_IDX ; 196/c4 ___inv_D_____, 197/c5 ___inv_E_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_IDX ; 198/c6 ___inv_F_____,199/c7 ___inv_G_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 200/c8 ___inv_H_____, 201/c9 ___inv_I_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 202/ca ___inv_J_____, 203/cb ___inv_K_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 204/cc ___inv_L_____, 205/cd ___inv_M_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 206/ce ___inv_N_____, 207/cf ___inv_O_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 208/d0 ___inv_P_____, 209/d1 ___inv_Q_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 210/d2 ___inv_R_____, 211/d3 ___inv_S_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 212/d4 ___inv_T_____, 213/d5 ___inv_U_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 214/d6 ___inv_V_____, 215/d7 ___inv_W_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 216/d8 ___inv_X_____, 217/d9 ___inv_Y_____ + ct_mix CT_UPPER_IDX, CT_NONE_IDX ; 218/da ___inv_Z_____, 219/db ___inv_[_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 220/dc ___inv_\_____, 221/dd ___inv_]_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 222/de ___inv_^_____, 223/df _inv_UNDRLIN_ + ct_mix CT_NONE_IDX, CT_LOWER_XDIGIT_IDX ; 224/e0 _inv_diamond_, 225/e1 ___inv_a_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_XDIGIT_IDX ; 226/e2 ___inv_b_____, 227/e3 ___inv_c_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_XDIGIT_IDX ; 228/e4 ___inv_d_____, 229/e5 ___inv_e_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_IDX ; 230/e6 ___inv_f_____, 231/e7 ___inv_g_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 232/e8 ___inv_h_____, 233/e9 ___inv_i_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 234/ea ___inv_j_____, 235/eb ___inv_k_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 236/ec ___inv_l_____, 237/ed ___inv_m_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 238/ee ___inv_n_____, 239/ef ___inv_o_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 240/f0 ___inv_p_____, 241/f1 ___inv_q_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 242/f2 ___inv_r_____, 243/f3 ___inv_s_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 244/f4 ___inv_t_____, 245/f5 ___inv_u_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 246/f6 ___inv_v_____, 247/f7 ___inv_w_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 248/f8 ___inv_x_____, 249/f9 ___inv_y_____ + ct_mix CT_LOWER_IDX, CT_NONE_IDX ; 250/fa ___inv_z_____, 251/fb __inv_spade__ + ct_mix CT_NONE_IDX, CT_CTRL_IDX ; 252/fc __inv_v_line_, 253/fd ____BEEP_____ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 254/fe ____DELBS____, 255/ff ___INSERT____ diff --git a/libsrc/atari2600/ctype.s b/libsrc/atari2600/ctype.s index 1892554fd..1301965eb 100644 --- a/libsrc/atari2600/ctype.s +++ b/libsrc/atari2600/ctype.s @@ -1,162 +1,5 @@ -; -; Ullrich von Bassewitz, 2003-10-10 -; ; Character specification table. ; +; uses the "common" definition - .include "ctype.inc" - -; The tables are readonly, put them into the rodata segment - -.rodata - -; The following 256 byte wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it -; has major advantages: -; -; * It is fast. If it weren't for the slow parameter passing of cc65, one -; could even define macros for the isxxx functions (this is usually -; done on other platforms). -; -; * It is highly portable. The only unportable part is the table itself, -; all real code goes into the common library. -; -; * We save some code in the isxxx functions. - - -__ctype: - .byte CT_CTRL ; 0/00 ___ctrl_@___ - .byte CT_CTRL ; 1/01 ___ctrl_A___ - .byte CT_CTRL ; 2/02 ___ctrl_B___ - .byte CT_CTRL ; 3/03 ___ctrl_C___ - .byte CT_CTRL ; 4/04 ___ctrl_D___ - .byte CT_CTRL ; 5/05 ___ctrl_E___ - .byte CT_CTRL ; 6/06 ___ctrl_F___ - .byte CT_CTRL ; 7/07 ___ctrl_G___ - .byte CT_CTRL ; 8/08 ___ctrl_H___ - .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB - ; 9/09 ___ctrl_I___ - .byte CT_CTRL | CT_OTHER_WS ; 10/0a ___ctrl_J___ - .byte CT_CTRL | CT_OTHER_WS ; 11/0b ___ctrl_K___ - .byte CT_CTRL | CT_OTHER_WS ; 12/0c ___ctrl_L___ - .byte CT_CTRL | CT_OTHER_WS ; 13/0d ___ctrl_M___ - .byte CT_CTRL ; 14/0e ___ctrl_N___ - .byte CT_CTRL ; 15/0f ___ctrl_O___ - .byte CT_CTRL ; 16/10 ___ctrl_P___ - .byte CT_CTRL ; 17/11 ___ctrl_Q___ - .byte CT_CTRL ; 18/12 ___ctrl_R___ - .byte CT_CTRL ; 19/13 ___ctrl_S___ - .byte CT_CTRL ; 20/14 ___ctrl_T___ - .byte CT_CTRL ; 21/15 ___ctrl_U___ - .byte CT_CTRL ; 22/16 ___ctrl_V___ - .byte CT_CTRL ; 23/17 ___ctrl_W___ - .byte CT_CTRL ; 24/18 ___ctrl_X___ - .byte CT_CTRL ; 25/19 ___ctrl_Y___ - .byte CT_CTRL ; 26/1a ___ctrl_Z___ - .byte CT_CTRL ; 27/1b ___ctrl_[___ - .byte CT_CTRL ; 28/1c ___ctrl_\___ - .byte CT_CTRL ; 29/1d ___ctrl_]___ - .byte CT_CTRL ; 30/1e ___ctrl_^___ - .byte CT_CTRL ; 31/1f ___ctrl_____ - .byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___ - .byte CT_NONE ; 33/21 _____!_____ - .byte CT_NONE ; 34/22 _____"_____ - .byte CT_NONE ; 35/23 _____#_____ - .byte CT_NONE ; 36/24 _____$_____ - .byte CT_NONE ; 37/25 _____%_____ - .byte CT_NONE ; 38/26 _____&_____ - .byte CT_NONE ; 39/27 _____'_____ - .byte CT_NONE ; 40/28 _____(_____ - .byte CT_NONE ; 41/29 _____)_____ - .byte CT_NONE ; 42/2a _____*_____ - .byte CT_NONE ; 43/2b _____+_____ - .byte CT_NONE ; 44/2c _____,_____ - .byte CT_NONE ; 45/2d _____-_____ - .byte CT_NONE ; 46/2e _____._____ - .byte CT_NONE ; 47/2f _____/_____ - .byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____ - .byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____ - .byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____ - .byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____ - .byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____ - .byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____ - .byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____ - .byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____ - .byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____ - .byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____ - .byte CT_NONE ; 58/3a _____:_____ - .byte CT_NONE ; 59/3b _____;_____ - .byte CT_NONE ; 60/3c _____<_____ - .byte CT_NONE ; 61/3d _____=_____ - .byte CT_NONE ; 62/3e _____>_____ - .byte CT_NONE ; 63/3f _____?_____ - - .byte CT_NONE ; 64/40 _____@_____ - .byte CT_UPPER | CT_XDIGIT ; 65/41 _____A_____ - .byte CT_UPPER | CT_XDIGIT ; 66/42 _____B_____ - .byte CT_UPPER | CT_XDIGIT ; 67/43 _____C_____ - .byte CT_UPPER | CT_XDIGIT ; 68/44 _____D_____ - .byte CT_UPPER | CT_XDIGIT ; 69/45 _____E_____ - .byte CT_UPPER | CT_XDIGIT ; 70/46 _____F_____ - .byte CT_UPPER ; 71/47 _____G_____ - .byte CT_UPPER ; 72/48 _____H_____ - .byte CT_UPPER ; 73/49 _____I_____ - .byte CT_UPPER ; 74/4a _____J_____ - .byte CT_UPPER ; 75/4b _____K_____ - .byte CT_UPPER ; 76/4c _____L_____ - .byte CT_UPPER ; 77/4d _____M_____ - .byte CT_UPPER ; 78/4e _____N_____ - .byte CT_UPPER ; 79/4f _____O_____ - .byte CT_UPPER ; 80/50 _____P_____ - .byte CT_UPPER ; 81/51 _____Q_____ - .byte CT_UPPER ; 82/52 _____R_____ - .byte CT_UPPER ; 83/53 _____S_____ - .byte CT_UPPER ; 84/54 _____T_____ - .byte CT_UPPER ; 85/55 _____U_____ - .byte CT_UPPER ; 86/56 _____V_____ - .byte CT_UPPER ; 87/57 _____W_____ - .byte CT_UPPER ; 88/58 _____X_____ - .byte CT_UPPER ; 89/59 _____Y_____ - .byte CT_UPPER ; 90/5a _____Z_____ - .byte CT_NONE ; 91/5b _____[_____ - .byte CT_NONE ; 92/5c _____\_____ - .byte CT_NONE ; 93/5d _____]_____ - .byte CT_NONE ; 94/5e _____^_____ - .byte CT_NONE ; 95/5f _UNDERLINE_ - .byte CT_NONE ; 96/60 ___grave___ - .byte CT_LOWER | CT_XDIGIT ; 97/61 _____a_____ - .byte CT_LOWER | CT_XDIGIT ; 98/62 _____b_____ - .byte CT_LOWER | CT_XDIGIT ; 99/63 _____c_____ - .byte CT_LOWER | CT_XDIGIT ; 100/64 _____d_____ - .byte CT_LOWER | CT_XDIGIT ; 101/65 _____e_____ - .byte CT_LOWER | CT_XDIGIT ; 102/66 _____f_____ - .byte CT_LOWER ; 103/67 _____g_____ - .byte CT_LOWER ; 104/68 _____h_____ - .byte CT_LOWER ; 105/69 _____i_____ - .byte CT_LOWER ; 106/6a _____j_____ - .byte CT_LOWER ; 107/6b _____k_____ - .byte CT_LOWER ; 108/6c _____l_____ - .byte CT_LOWER ; 109/6d _____m_____ - .byte CT_LOWER ; 110/6e _____n_____ - .byte CT_LOWER ; 111/6f _____o_____ - .byte CT_LOWER ; 112/70 _____p_____ - .byte CT_LOWER ; 113/71 _____q_____ - .byte CT_LOWER ; 114/72 _____r_____ - .byte CT_LOWER ; 115/73 _____s_____ - .byte CT_LOWER ; 116/74 _____t_____ - .byte CT_LOWER ; 117/75 _____u_____ - .byte CT_LOWER ; 118/76 _____v_____ - .byte CT_LOWER ; 119/77 _____w_____ - .byte CT_LOWER ; 120/78 _____x_____ - .byte CT_LOWER ; 121/79 _____y_____ - .byte CT_LOWER ; 122/7a _____z_____ - .byte CT_NONE ; 123/7b _____{_____ - .byte CT_NONE ; 124/7c _____|_____ - .byte CT_NONE ; 125/7d _____}_____ - .byte CT_NONE ; 126/7e _____~_____ - .byte CT_OTHER_WS ; 127/7f ____DEL____ - - .res 128, CT_NONE ; 128-255 - - - + .include "ctype_common.inc" diff --git a/libsrc/atmos/ctype.s b/libsrc/atmos/ctype.s index 79edafbb2..3c3d7be5b 100644 --- a/libsrc/atmos/ctype.s +++ b/libsrc/atmos/ctype.s @@ -1,299 +1,155 @@ +; ctype.s ; -; Ullrich von Bassewitz, 2003-04-13 +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems ; -; Character specification table. +; https://github.com/cc65/cc65 ; +; See "LICENSE" file for legal information. +; +; ATMOS character specification table. +; + + .include "ctypetable.inc" + .export __ctypeIdx ; The tables are readonly, put them into the rodata segment .rodata -; The following 256 byte wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it -; has major advantages: -; -; * It is fast. If it were'nt for the slow parameter passing of cc65, one -; could even define macros for the isxxx functions (this is usually -; done on other platforms). -; -; * It is highly portable. The only unportable part is the table itself, -; all real code goes into the common library. -; -; * We save some code in the isxxx functions. -; -; -; Bit assignments: -; -; 0 - Lower case char -; 1 - Upper case char -; 2 - Numeric digit -; 3 - Hex digit (both, lower and upper) -; 4 - Control character -; 5 - The space character itself -; 6 - Other whitespace (that is: '\f', '\n', '\r', '\t' and '\v') -; 7 - Space or tab character +__ctypeIdx: + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 0/00 ___ctrl_@___, 1/01 ___ctrl_A___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 2/02 ___ctrl_B___, 3/03 ___ctrl_C___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 4/04 ___ctrl_D___, 5/05 ___ctrl_E___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 6/06 ___ctrl_F___, 7/07 ___ctrl_G___ + ct_mix CT_CTRL_IDX, CT_CTRL_WS_SPACETAB_IDX ; 8/08 ___ctrl_H___, 9/09 ___ctrl_I___ + ct_mix CT_CTRL_WS_IDX, CT_CTRL_WS_IDX ; 10/0a ___ctrl_J___, 11/0b ___ctrl_K___ + ct_mix CT_CTRL_WS_IDX, CT_CTRL_WS_IDX ; 12/0c ___ctrl_L___, 13/0d ___ctrl_M___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 14/0e ___ctrl_N___, 15/0f ___ctrl_O___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 16/10 ___ctrl_P___, 17/11 ___ctrl_Q___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 18/12 ___ctrl_R___, 19/13 ___ctrl_S___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 20/14 ___ctrl_T___, 21/15 ___ctrl_U___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 22/16 ___ctrl_V___, 23/17 ___ctrl_W___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 24/18 ___ctrl_X___, 25/19 ___ctrl_Y___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 26/1a ___ctrl_Z___, 27/1b ___ctrl_[___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 28/1c ___ctrl_\___, 29/1d ___ctrl_]___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 30/1e ___ctrl_^___, 31/1f ___ctrl_____ - .export __ctype + ct_mix CT_SPACE_SPACETAB_IDX, CT_NONE_IDX ; 32/20 ___SPACE___, 33/21 _____!_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 34/22 _____"_____, 35/23 _____#_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 36/24 _____$_____, 37/25 _____%_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 38/26 _____&_____, 39/27 _____'_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 40/28 _____(_____, 41/29 _____)_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 42/2a _____*_____, 43/2b _____+_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 44/2c _____,_____, 45/2d _____-_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 46/2e _____._____, 47/2f _____/_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 48/30 _____0_____, 49/31 _____1_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 50/32 _____2_____, 51/33 _____3_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 52/34 _____4_____, 53/35 _____5_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 54/36 _____6_____, 55/37 _____7_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 56/38 _____8_____, 57/39 _____9_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 58/3a _____:_____, 59/3b _____;_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 60/3c _____<_____, 61/3d _____=_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 62/3e _____>_____, 63/3f _____?_____ -__ctype: - .byte $10 ; 0/00 ___ctrl_@___ - .byte $10 ; 1/01 ___ctrl_A___ - .byte $10 ; 2/02 ___ctrl_B___ - .byte $10 ; 3/03 ___ctrl_C___ - .byte $10 ; 4/04 ___ctrl_D___ - .byte $10 ; 5/05 ___ctrl_E___ - .byte $10 ; 6/06 ___ctrl_F___ - .byte $10 ; 7/07 ___ctrl_G___ - .byte $10 ; 8/08 ___ctrl_H___ - .byte $D0 ; 9/09 ___ctrl_I___ - .byte $50 ; 10/0a ___ctrl_J___ - .byte $50 ; 11/0b ___ctrl_K___ - .byte $50 ; 12/0c ___ctrl_L___ - .byte $50 ; 13/0d ___ctrl_M___ - .byte $10 ; 14/0e ___ctrl_N___ - .byte $10 ; 15/0f ___ctrl_O___ - .byte $10 ; 16/10 ___ctrl_P___ - .byte $10 ; 17/11 ___ctrl_Q___ - .byte $10 ; 18/12 ___ctrl_R___ - .byte $10 ; 19/13 ___ctrl_S___ - .byte $10 ; 20/14 ___ctrl_T___ - .byte $10 ; 21/15 ___ctrl_U___ - .byte $10 ; 22/16 ___ctrl_V___ - .byte $10 ; 23/17 ___ctrl_W___ - .byte $10 ; 24/18 ___ctrl_X___ - .byte $10 ; 25/19 ___ctrl_Y___ - .byte $10 ; 26/1a ___ctrl_Z___ - .byte $10 ; 27/1b ___ctrl_[___ - .byte $10 ; 28/1c ___ctrl_\___ - .byte $10 ; 29/1d ___ctrl_]___ - .byte $10 ; 30/1e ___ctrl_^___ - .byte $10 ; 31/1f ___ctrl_____ - .byte $A0 ; 32/20 ___SPACE___ - .byte $00 ; 33/21 _____!_____ - .byte $00 ; 34/22 _____"_____ - .byte $00 ; 35/23 _____#_____ - .byte $00 ; 36/24 _____$_____ - .byte $00 ; 37/25 _____%_____ - .byte $00 ; 38/26 _____&_____ - .byte $00 ; 39/27 _____'_____ - .byte $00 ; 40/28 _____(_____ - .byte $00 ; 41/29 _____)_____ - .byte $00 ; 42/2a _____*_____ - .byte $00 ; 43/2b _____+_____ - .byte $00 ; 44/2c _____,_____ - .byte $00 ; 45/2d _____-_____ - .byte $00 ; 46/2e _____._____ - .byte $00 ; 47/2f _____/_____ - .byte $0C ; 48/30 _____0_____ - .byte $0C ; 49/31 _____1_____ - .byte $0C ; 50/32 _____2_____ - .byte $0C ; 51/33 _____3_____ - .byte $0C ; 52/34 _____4_____ - .byte $0C ; 53/35 _____5_____ - .byte $0C ; 54/36 _____6_____ - .byte $0C ; 55/37 _____7_____ - .byte $0C ; 56/38 _____8_____ - .byte $0C ; 57/39 _____9_____ - .byte $00 ; 58/3a _____:_____ - .byte $00 ; 59/3b _____;_____ - .byte $00 ; 60/3c _____<_____ - .byte $00 ; 61/3d _____=_____ - .byte $00 ; 62/3e _____>_____ - .byte $00 ; 63/3f _____?_____ + ct_mix CT_NONE_IDX, CT_UPPER_XDIGIT_IDX ; 64/40 _____@_____, 65/41 _____A_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_XDIGIT_IDX ; 66/42 _____B_____, 67/43 _____C_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_XDIGIT_IDX ; 68/44 _____D_____, 69/45 _____E_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_IDX ; 70/46 _____F_____, 71/47 _____G_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 72/48 _____H_____, 73/49 _____I_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 74/4a _____J_____, 75/4b _____K_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 76/4c _____L_____, 77/4d _____M_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 78/4e _____N_____, 79/4f _____O_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 80/50 _____P_____, 81/51 _____Q_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 82/52 _____R_____, 83/53 _____S_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 84/54 _____T_____, 85/55 _____U_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 86/56 _____V_____, 87/57 _____W_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 88/58 _____X_____, 89/59 _____Y_____ + ct_mix CT_UPPER_IDX, CT_NONE_IDX ; 90/5a _____Z_____, 91/5b _____[_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 92/5c _____\_____, 93/5d _____]_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 94/5e _____^_____, 95/5f _UNDERLINE_ - .byte $00 ; 64/40 _____@_____ - .byte $0A ; 65/41 _____A_____ - .byte $0A ; 66/42 _____B_____ - .byte $0A ; 67/43 _____C_____ - .byte $0A ; 68/44 _____D_____ - .byte $0A ; 69/45 _____E_____ - .byte $0A ; 70/46 _____F_____ - .byte $02 ; 71/47 _____G_____ - .byte $02 ; 72/48 _____H_____ - .byte $02 ; 73/49 _____I_____ - .byte $02 ; 74/4a _____J_____ - .byte $02 ; 75/4b _____K_____ - .byte $02 ; 76/4c _____L_____ - .byte $02 ; 77/4d _____M_____ - .byte $02 ; 78/4e _____N_____ - .byte $02 ; 79/4f _____O_____ - .byte $02 ; 80/50 _____P_____ - .byte $02 ; 81/51 _____Q_____ - .byte $02 ; 82/52 _____R_____ - .byte $02 ; 83/53 _____S_____ - .byte $02 ; 84/54 _____T_____ - .byte $02 ; 85/55 _____U_____ - .byte $02 ; 86/56 _____V_____ - .byte $02 ; 87/57 _____W_____ - .byte $02 ; 88/58 _____X_____ - .byte $02 ; 89/59 _____Y_____ - .byte $02 ; 90/5a _____Z_____ - .byte $00 ; 91/5b _____[_____ - .byte $00 ; 92/5c _____\_____ - .byte $00 ; 93/5d _____]_____ - .byte $00 ; 94/5e _____^_____ - .byte $00 ; 95/5f _UNDERLINE_ - .byte $00 ; 96/60 ___grave___ - .byte $09 ; 97/61 _____a_____ - .byte $09 ; 98/62 _____b_____ - .byte $09 ; 99/63 _____c_____ - .byte $09 ; 100/64 _____d_____ - .byte $09 ; 101/65 _____e_____ - .byte $09 ; 102/66 _____f_____ - .byte $01 ; 103/67 _____g_____ - .byte $01 ; 104/68 _____h_____ - .byte $01 ; 105/69 _____i_____ - .byte $01 ; 106/6a _____j_____ - .byte $01 ; 107/6b _____k_____ - .byte $01 ; 108/6c _____l_____ - .byte $01 ; 109/6d _____m_____ - .byte $01 ; 110/6e _____n_____ - .byte $01 ; 111/6f _____o_____ - .byte $01 ; 112/70 _____p_____ - .byte $01 ; 113/71 _____q_____ - .byte $01 ; 114/72 _____r_____ - .byte $01 ; 115/73 _____s_____ - .byte $01 ; 116/74 _____t_____ - .byte $01 ; 117/75 _____u_____ - .byte $01 ; 118/76 _____v_____ - .byte $01 ; 119/77 _____w_____ - .byte $01 ; 120/78 _____x_____ - .byte $01 ; 121/79 _____y_____ - .byte $01 ; 122/7a _____z_____ - .byte $00 ; 123/7b _____{_____ - .byte $00 ; 124/7c _____|_____ - .byte $00 ; 125/7d _____}_____ - .byte $00 ; 126/7e _____~_____ - .byte $40 ; 127/7f ____DEL____ + ct_mix CT_NONE_IDX, CT_LOWER_XDIGIT_IDX ; 96/60 ___grave___, 97/61 _____a_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_XDIGIT_IDX ; 98/62 _____b_____, 99/63 _____c_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_XDIGIT_IDX ; 100/64 _____d_____, 101/65 _____e_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_IDX ; 102/66 _____f_____, 103/67 _____g_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 104/68 _____h_____, 105/69 _____i_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 106/6a _____j_____, 107/6b _____k_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 108/6c _____l_____, 109/6d _____m_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 110/6e _____n_____, 111/6f _____o_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 112/70 _____p_____, 113/71 _____q_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 114/72 _____r_____, 115/73 _____s_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 116/74 _____t_____, 117/75 _____u_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 118/76 _____v_____, 119/77 _____w_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 120/78 _____x_____, 121/79 _____y_____ + ct_mix CT_LOWER_IDX, CT_NONE_IDX ; 122/7a _____z_____, 123/7b _____{_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 124/7c _____|_____, 125/7d _____}_____ + ct_mix CT_NONE_IDX, CT_WS_IDX ; 126/7e _____~_____, 127/7f ____DEL____ - .byte $00 ; 128/80 ___________ - .byte $00 ; 129/81 ___________ - .byte $00 ; 130/82 ___________ - .byte $00 ; 131/83 ___________ - .byte $00 ; 132/84 ___________ - .byte $00 ; 133/85 ___________ - .byte $00 ; 134/86 ___________ - .byte $00 ; 135/87 ___________ - .byte $00 ; 136/88 ___________ - .byte $00 ; 137/89 ___________ - .byte $00 ; 138/8a ___________ - .byte $00 ; 139/8b ___________ - .byte $00 ; 140/8c ___________ - .byte $00 ; 141/8d ___________ - .byte $00 ; 142/8e ___________ - .byte $00 ; 143/8f ___________ - .byte $00 ; 144/90 ___________ - .byte $00 ; 145/91 ___________ - .byte $00 ; 146/92 ___________ - .byte $10 ; 147/93 ___________ - .byte $00 ; 148/94 ___________ - .byte $00 ; 149/95 ___________ - .byte $00 ; 150/96 ___________ - .byte $00 ; 151/97 ___________ - .byte $00 ; 152/98 ___________ - .byte $00 ; 153/99 ___________ - .byte $00 ; 154/9a ___________ - .byte $00 ; 155/9b ___________ - .byte $00 ; 156/9c ___________ - .byte $00 ; 157/9d ___________ - .byte $00 ; 158/9e ___________ - .byte $00 ; 159/9f ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 128/80 ___________, 129/81 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 130/82 ___________, 131/83 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 132/84 ___________, 133/85 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 134/86 ___________, 135/87 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 136/88 ___________, 137/89 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 138/8a ___________, 139/8b ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 140/8c ___________, 141/8d ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 142/8e ___________, 143/8f ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 144/90 ___________, 145/91 ___________ + ct_mix CT_NONE_IDX, CT_CTRL_IDX ; 146/92 ___________, 147/93 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 148/94 ___________, 149/95 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 150/96 ___________, 151/97 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 152/98 ___________, 153/99 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 154/9a ___________, 155/9b ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 156/9c ___________, 157/9d ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 158/9e ___________, 159/9f ___________ - .byte $00 ; 160/a0 ___________ - .byte $00 ; 161/a1 ___________ - .byte $00 ; 162/a2 ___________ - .byte $00 ; 163/a3 ___________ - .byte $00 ; 164/a4 ___________ - .byte $00 ; 165/a5 ___________ - .byte $00 ; 166/a6 ___________ - .byte $00 ; 167/a7 ___________ - .byte $00 ; 168/a8 ___________ - .byte $00 ; 169/a9 ___________ - .byte $00 ; 170/aa ___________ - .byte $00 ; 171/ab ___________ - .byte $00 ; 172/ac ___________ - .byte $00 ; 173/ad ___________ - .byte $00 ; 174/ae ___________ - .byte $00 ; 175/af ___________ - .byte $00 ; 176/b0 ___________ - .byte $00 ; 177/b1 ___________ - .byte $00 ; 178/b2 ___________ - .byte $00 ; 179/b3 ___________ - .byte $00 ; 180/b4 ___________ - .byte $00 ; 181/b5 ___________ - .byte $00 ; 182/b6 ___________ - .byte $00 ; 183/b7 ___________ - .byte $00 ; 184/b8 ___________ - .byte $00 ; 185/b9 ___________ - .byte $00 ; 186/ba ___________ - .byte $00 ; 187/bb ___________ - .byte $00 ; 188/bc ___________ - .byte $00 ; 189/bd ___________ - .byte $00 ; 190/be ___________ - .byte $00 ; 191/bf ___________ - - .byte $02 ; 192/c0 ___________ - .byte $02 ; 193/c1 ___________ - .byte $02 ; 194/c2 ___________ - .byte $02 ; 195/c3 ___________ - .byte $02 ; 196/c4 ___________ - .byte $02 ; 197/c5 ___________ - .byte $02 ; 198/c6 ___________ - .byte $02 ; 199/c7 ___________ - .byte $02 ; 200/c8 ___________ - .byte $02 ; 201/c9 ___________ - .byte $02 ; 202/ca ___________ - .byte $02 ; 203/cb ___________ - .byte $02 ; 204/cc ___________ - .byte $02 ; 205/cd ___________ - .byte $02 ; 206/ce ___________ - .byte $02 ; 207/cf ___________ - .byte $02 ; 208/d0 ___________ - .byte $02 ; 209/d1 ___________ - .byte $02 ; 210/d2 ___________ - .byte $02 ; 211/d3 ___________ - .byte $02 ; 212/d4 ___________ - .byte $02 ; 213/d5 ___________ - .byte $02 ; 214/d6 ___________ - .byte $02 ; 215/d7 ___________ - .byte $02 ; 216/d8 ___________ - .byte $02 ; 217/d9 ___________ - .byte $02 ; 218/da ___________ - .byte $02 ; 219/db ___________ - .byte $02 ; 220/dc ___________ - .byte $02 ; 221/dd ___________ - .byte $02 ; 222/de ___________ - .byte $00 ; 223/df ___________ - .byte $01 ; 224/e0 ___________ - .byte $01 ; 225/e1 ___________ - .byte $01 ; 226/e2 ___________ - .byte $01 ; 227/e3 ___________ - .byte $01 ; 228/e4 ___________ - .byte $01 ; 229/e5 ___________ - .byte $01 ; 230/e6 ___________ - .byte $01 ; 231/e7 ___________ - .byte $01 ; 232/e8 ___________ - .byte $01 ; 233/e9 ___________ - .byte $01 ; 234/ea ___________ - .byte $01 ; 235/eb ___________ - .byte $01 ; 236/ec ___________ - .byte $01 ; 237/ed ___________ - .byte $01 ; 238/ee ___________ - .byte $01 ; 239/ef ___________ - .byte $01 ; 240/f0 ___________ - .byte $01 ; 241/f1 ___________ - .byte $01 ; 242/f2 ___________ - .byte $01 ; 243/f3 ___________ - .byte $01 ; 244/f4 ___________ - .byte $01 ; 245/f5 ___________ - .byte $01 ; 246/f6 ___________ - .byte $01 ; 247/f7 ___________ - .byte $01 ; 248/f8 ___________ - .byte $01 ; 249/f9 ___________ - .byte $01 ; 250/fa ___________ - .byte $01 ; 251/fb ___________ - .byte $01 ; 252/fc ___________ - .byte $01 ; 253/fd ___________ - .byte $01 ; 254/fe ___________ - .byte $00 ; 255/ff ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 160/a0 ___________, 161/a1 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 162/a2 ___________, 163/a3 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 164/a4 ___________, 165/a5 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 166/a6 ___________, 167/a7 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 168/a8 ___________, 169/a9 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 170/aa ___________, 171/ab ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 172/ac ___________, 173/ad ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 174/ae ___________, 175/af ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 176/b0 ___________, 177/b1 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 178/b2 ___________, 179/b3 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 180/b4 ___________, 181/b5 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 182/b6 ___________, 183/b7 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 184/b8 ___________, 185/b9 ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 186/ba ___________, 187/bb ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 188/bc ___________, 189/bd ___________ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 190/be ___________, 191/bf ___________ + + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 192/c0 ___________, 193/c1 ___________ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 194/c2 ___________, 195/c3 ___________ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 196/c4 ___________, 197/c5 ___________ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 198/c6 ___________, 199/c7 ___________ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 200/c8 ___________, 201/c9 ___________ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 202/ca ___________, 203/cb ___________ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 204/cc ___________, 205/cd ___________ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 206/ce ___________, 207/cf ___________ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 208/d0 ___________, 209/d1 ___________ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 210/d2 ___________, 211/d3 ___________ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 212/d4 ___________, 213/d5 ___________ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 214/d6 ___________, 215/d7 ___________ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 216/d8 ___________, 217/d9 ___________ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 218/da ___________, 219/db ___________ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 220/dc ___________, 221/dd ___________ + ct_mix CT_UPPER_IDX, CT_NONE_IDX ; 222/de ___________, 223/df ___________ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 224/e0 ___________, 225/e1 ___________ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 226/e2 ___________, 227/e3 ___________ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 228/e4 ___________, 229/e5 ___________ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 230/e6 ___________, 231/e7 ___________ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 232/e8 ___________, 233/e9 ___________ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 234/ea ___________, 235/eb ___________ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 236/ec ___________, 237/ed ___________ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 238/ee ___________, 239/ef ___________ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 240/f0 ___________, 241/f1 ___________ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 242/f2 ___________, 243/f3 ___________ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 244/f4 ___________, 245/f5 ___________ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 246/f6 ___________, 247/f7 ___________ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 248/f8 ___________, 249/f9 ___________ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 250/fa ___________, 251/fb ___________ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 252/fc ___________, 253/fd ___________ + ct_mix CT_LOWER_IDX, CT_NONE_IDX ; 254/fe ___________, 255/ff ___________ diff --git a/libsrc/cbm/ctype.s b/libsrc/cbm/ctype.s index ba096bb13..d0943b123 100644 --- a/libsrc/cbm/ctype.s +++ b/libsrc/cbm/ctype.s @@ -1,289 +1,156 @@ +; ctype.s ; -; Character specification table. +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems ; -; Ullrich von Bassewitz, 02.06.1998 -; 2003-05-02, Greg King +; https://github.com/cc65/cc65 ; - -; The following 256-byte-wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it -; has major advantages: +; See "LICENSE" file for legal information. ; -; * It is fast. If it weren't for the slow parameter-passing of cc65, -; one even could define C-language macroes for the isxxx functions -; (as it usually is done, on other platforms). +; CBM character specification table. ; -; * It is highly portable. The only unportable part is the table itself; -; all real code goes into the common library. -; -; * We save some code in the isxxx functions. - ; This table is taken from Craig S. Bruce's technical docs. for the ACE OS. - .include "ctype.inc" + .include "ctypetable.inc" + .export __ctypeIdx + +; The tables are readonly, put them into the rodata segment -; The table is read-only, put it into the RODATA segment. +.rodata - .rodata +__ctypeIdx: + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 0/00 ___rvs_@___, 1/01 ___rvs_a___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 2/02 ___rvs_b___, 3/03 ___rvs_c___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 4/04 ___rvs_d___, 5/05 ___rvs_e___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 6/06 ___rvs_f___, 7/07 _BEL/rvs_g_ + ct_mix CT_CTRL_IDX, CT_CTRL_WS_SPACETAB_IDX ; 8/08 ___rvs_h___, 9/09 _TAB/rvs_i_ + ct_mix CT_CTRL_WS_IDX, CT_CTRL_IDX ; 10/0a _BOL/rvs_j_, 11/0b ___rvs_k___ + ct_mix CT_CTRL_IDX, CT_CTRL_WS_IDX ; 12/0c ___rvs_l___, 13/0d _CR_/rvs_m_ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 14/0e ___rvs_n___, 15/0f ___rvs_o___ + ct_mix CT_CTRL_IDX, CT_CTRL_WS_IDX ; 16/10 ___rvs_p___, 17/11 _VT_/rvs_q_ + ct_mix CT_CTRL_IDX, CT_CTRL_WS_IDX ; 18/12 ___rvs_r___, 19/13 HOME/rvs_s_ + ct_mix CT_CTRL_WS_IDX, CT_CTRL_IDX ; 20/14 _BS_/rvs_t_, 21/15 ___rvs_u___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 22/16 ___rvs_v___, 23/17 ___rvs_w___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 24/18 ___rvs_x___, 25/19 ___rvs_y___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 26/1a ___rvs_z___, 27/1b ___rvs_[___ + ct_mix CT_CTRL_IDX, CT_CTRL_WS_IDX ; 28/1c ___rvs_\___, 29/1d cursr-right + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 30/1e ___rvs_^___, 31/1f _rvs_under_ -__ctype: - .byte CT_CTRL ; 0/00 ___rvs_@___ - .byte CT_CTRL ; 1/01 ___rvs_a___ - .byte CT_CTRL ; 2/02 ___rvs_b___ - .byte CT_CTRL ; 3/03 ___rvs_c___ - .byte CT_CTRL ; 4/04 ___rvs_d___ - .byte CT_CTRL ; 5/05 ___rvs_e___ - .byte CT_CTRL ; 6/06 ___rvs_f___ - .byte CT_CTRL ; 7/07 _BEL/rvs_g_ - .byte CT_CTRL ; 8/08 ___rvs_h___ - .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB ; 9/09 _TAB/rvs_i_ - .byte CT_CTRL | CT_OTHER_WS ; 10/0a _BOL/rvs_j_ - .byte CT_CTRL ; 11/0b ___rvs_k___ - .byte CT_CTRL ; 12/0c ___rvs_l___ - .byte CT_CTRL | CT_OTHER_WS ; 13/0d _CR_/rvs_m_ - .byte CT_CTRL ; 14/0e ___rvs_n___ - .byte CT_CTRL ; 15/0f ___rvs_o___ - .byte CT_CTRL ; 16/10 ___rvs_p___ - .byte CT_CTRL | CT_OTHER_WS ; 17/11 _VT_/rvs_q_ - .byte CT_CTRL ; 18/12 ___rvs_r___ - .byte CT_CTRL | CT_OTHER_WS ; 19/13 HOME/rvs_s_ - .byte CT_CTRL | CT_OTHER_WS ; 20/14 _BS_/rvs_t_ - .byte CT_CTRL ; 21/15 ___rvs_u___ - .byte CT_CTRL ; 22/16 ___rvs_v___ - .byte CT_CTRL ; 23/17 ___rvs_w___ - .byte CT_CTRL ; 24/18 ___rvs_x___ - .byte CT_CTRL ; 25/19 ___rvs_y___ - .byte CT_CTRL ; 26/1a ___rvs_z___ - .byte CT_CTRL ; 27/1b ___rvs_[___ - .byte CT_CTRL ; 28/1c ___rvs_\___ - .byte CT_CTRL | CT_OTHER_WS ; 29/1d cursr-right - .byte CT_CTRL ; 30/1e ___rvs_^___ - .byte CT_CTRL ; 31/1f _rvs_under_ - .byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___ - .byte $00 ; 33/21 _____!_____ - .byte $00 ; 34/22 _____"_____ - .byte $00 ; 35/23 _____#_____ - .byte $00 ; 36/24 _____$_____ - .byte $00 ; 37/25 _____%_____ - .byte $00 ; 38/26 _____&_____ - .byte $00 ; 39/27 _____'_____ - .byte $00 ; 40/28 _____(_____ - .byte $00 ; 41/29 _____)_____ - .byte $00 ; 42/2a _____*_____ - .byte $00 ; 43/2b _____+_____ - .byte $00 ; 44/2c _____,_____ - .byte $00 ; 45/2d _____-_____ - .byte $00 ; 46/2e _____._____ - .byte $00 ; 47/2f _____/_____ - .byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____ - .byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____ - .byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____ - .byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____ - .byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____ - .byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____ - .byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____ - .byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____ - .byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____ - .byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____ - .byte $00 ; 58/3a _____:_____ - .byte $00 ; 59/3b _____;_____ - .byte $00 ; 60/3c _____<_____ - .byte $00 ; 61/3d _____=_____ - .byte $00 ; 62/3e _____>_____ - .byte $00 ; 63/3f _____?_____ + ct_mix CT_SPACE_SPACETAB_IDX, CT_NONE_IDX ; 32/20 ___SPACE___, 33/21 _____!_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 34/22 _____"_____, 35/23 _____#_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 36/24 _____$_____, 37/25 _____%_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 38/26 _____&_____, 39/27 _____'_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 40/28 _____(_____, 41/29 _____)_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 42/2a _____*_____, 43/2b _____+_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 44/2c _____,_____, 45/2d _____-_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 46/2e _____._____, 47/2f _____/_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 48/30 _____0_____, 49/31 _____1_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 50/32 _____2_____, 51/33 _____3_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 52/34 _____4_____, 53/35 _____5_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 54/36 _____6_____, 55/37 _____7_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 56/38 _____8_____, 57/39 _____9_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 58/3a _____:_____, 59/3b _____;_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 60/3c _____<_____, 61/3d _____=_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 62/3e _____>_____, 63/3f _____?_____ - .byte $00 ; 64/40 _____@_____ - .byte CT_LOWER | CT_XDIGIT ; 65/41 _____a_____ - .byte CT_LOWER | CT_XDIGIT ; 66/42 _____b_____ - .byte CT_LOWER | CT_XDIGIT ; 67/43 _____c_____ - .byte CT_LOWER | CT_XDIGIT ; 68/44 _____d_____ - .byte CT_LOWER | CT_XDIGIT ; 69/45 _____e_____ - .byte CT_LOWER | CT_XDIGIT ; 70/46 _____f_____ - .byte CT_LOWER ; 71/47 _____g_____ - .byte CT_LOWER ; 72/48 _____h_____ - .byte CT_LOWER ; 73/49 _____i_____ - .byte CT_LOWER ; 74/4a _____j_____ - .byte CT_LOWER ; 75/4b _____k_____ - .byte CT_LOWER ; 76/4c _____l_____ - .byte CT_LOWER ; 77/4d _____m_____ - .byte CT_LOWER ; 78/4e _____n_____ - .byte CT_LOWER ; 79/4f _____o_____ - .byte CT_LOWER ; 80/50 _____p_____ - .byte CT_LOWER ; 81/51 _____q_____ - .byte CT_LOWER ; 82/52 _____r_____ - .byte CT_LOWER ; 83/53 _____s_____ - .byte CT_LOWER ; 84/54 _____t_____ - .byte CT_LOWER ; 85/55 _____u_____ - .byte CT_LOWER ; 86/56 _____v_____ - .byte CT_LOWER ; 87/57 _____w_____ - .byte CT_LOWER ; 88/58 _____x_____ - .byte CT_LOWER ; 89/59 _____y_____ - .byte CT_LOWER ; 90/5a _____z_____ - .byte $00 ; 91/5b _____[_____ - .byte $00 ; 92/5c _____\_____ - .byte $00 ; 93/5d _____]_____ - .byte $00 ; 94/5e _____^_____ - .byte $00 ; 95/5f _UNDERLINE_ - .byte $00 ; 96/60 _A`_grave__ - .byte $00 ; 97/61 _A'_acute__ - .byte $00 ; 98/62 _A^_circum_ - .byte $00 ; 99/63 _A~_tilde__ - .byte $00 ; 100/64 _A"_dieres_ - .byte $00 ; 101/65 _A__ring___ - .byte $00 ; 102/66 _AE________ - .byte $00 ; 103/67 _C,cedilla_ - .byte $00 ; 104/68 _E`_grave__ - .byte $00 ; 105/69 _E'_acute__ - .byte $00 ; 106/6a _E^_circum_ - .byte $00 ; 107/6b _E"_dieres_ - .byte $00 ; 108/6c _I`_grave__ - .byte $00 ; 109/6d _I'_acute__ - .byte $00 ; 110/6e _I^_circum_ - .byte $00 ; 111/6f _I"_dieres_ - .byte $00 ; 112/70 _D-_Eth_lr_ - .byte $00 ; 113/71 _N~_tilde__ - .byte $00 ; 114/72 _O`_grave__ - .byte $00 ; 115/73 _O'_acute__ - .byte $00 ; 116/74 _O^_circum_ - .byte $00 ; 117/75 _O~_tilde__ - .byte $00 ; 118/76 _O"_dieres_ - .byte $00 ; 119/77 __multiply_ - .byte $00 ; 120/78 _O/_slash__ - .byte $00 ; 121/79 _U`_grave__ - .byte $00 ; 122/7a _U'_acute__ - .byte $00 ; 123/7b _U^_circum_ - .byte $00 ; 124/7c _U"_dieres_ - .byte $00 ; 125/7d _Y'_acute__ - .byte $00 ; 126/7e _cap_thorn_ - .byte $00 ; 127/7f _Es-sed_B__ + ct_mix CT_NONE_IDX, CT_LOWER_XDIGIT_IDX ; 64/40 _____@_____, 65/41 _____a_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_XDIGIT_IDX ; 66/42 _____b_____, 67/43 _____c_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_XDIGIT_IDX ; 68/44 _____d_____, 69/45 _____e_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_IDX ; 70/46 _____f_____, 71/47 _____g_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 72/48 _____h_____, 73/49 _____i_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 74/4a _____j_____, 75/4b _____k_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 76/4c _____l_____, 77/4d _____m_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 78/4e _____n_____, 79/4f _____o_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 80/50 _____p_____, 81/51 _____q_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 82/52 _____r_____, 83/53 _____s_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 84/54 _____t_____, 85/55 _____u_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 86/56 _____v_____, 87/57 _____w_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 88/58 _____x_____, 89/59 _____y_____ + ct_mix CT_LOWER_IDX, CT_NONE_IDX ; 90/5a _____z_____, 91/5b _____[_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 92/5c _____\_____, 93/5d _____]_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 94/5e _____^_____, 95/5f _UNDERLINE_ - .byte CT_CTRL ; 128/80 __bullet___ - .byte CT_CTRL ; 129/81 __v_line___ - .byte CT_CTRL ; 130/82 __h_line___ - .byte CT_CTRL ; 131/83 ___cross___ - .byte CT_CTRL ; 132/84 _tl_corner_ - .byte CT_CTRL ; 133/85 _tr_corner_ - .byte CT_CTRL ; 134/86 _bl_corner_ - .byte CT_CTRL ; 135/87 _br_corner_ - .byte CT_CTRL ; 136/88 ___l_tee___ - .byte CT_CTRL ; 137/89 ___r_tee___ - .byte CT_CTRL ; 138/8a ___t_tee___ - .byte CT_CTRL ; 139/8b ___b_tee___ - .byte CT_CTRL ; 140/8c ___heart___ - .byte CT_CTRL | CT_OTHER_WS ; 141/8d _CR/diamond - .byte CT_CTRL ; 142/8e ___club____ - .byte CT_CTRL ; 143/8f ___spade___ - .byte CT_CTRL ; 144/90 _s_circle__ - .byte CT_CTRL | CT_OTHER_WS ; 145/91 _cursor-up_ - .byte CT_CTRL ; 146/92 ___pound___ - .byte CT_CTRL | CT_OTHER_WS ; 147/93 _CLS/check_ - .byte CT_CTRL | CT_OTHER_WS ; 148/94 __INSert___ - .byte CT_CTRL ; 149/95 ____+/-____ - .byte CT_CTRL ; 150/96 __divide___ - .byte CT_CTRL ; 151/97 __degree___ - .byte CT_CTRL ; 152/98 _c_checker_ - .byte CT_CTRL ; 153/99 _f_checker_ - .byte CT_CTRL ; 154/9a _solid_sq__ - .byte CT_CTRL ; 155/9b __cr_char__ - .byte CT_CTRL ; 156/9c _up_arrow__ - .byte CT_CTRL | CT_OTHER_WS ; 157/9d cursor-left - .byte CT_CTRL ; 158/9e _left_arro_ - .byte CT_CTRL ; 159/9f _right_arr_ - .byte CT_SPACE | CT_SPACE_TAB ; 160/a0 _req space_ - .byte $00 ; 161/a1 _!_invertd_ - .byte $00 ; 162/a2 ___cent____ - .byte $00 ; 163/a3 ___pound___ - .byte $00 ; 164/a4 __currency_ - .byte $00 ; 165/a5 ____yen____ - .byte $00 ; 166/a6 _|_broken__ - .byte $00 ; 167/a7 __section__ - .byte $00 ; 168/a8 __umulaut__ - .byte $00 ; 169/a9 _copyright_ - .byte $00 ; 170/aa __fem_ord__ - .byte $00 ; 171/ab _l_ang_quo_ - .byte $00 ; 172/ac ____not____ - .byte $00 ; 173/ad _syl_hyphn_ - .byte $00 ; 174/ae _registerd_ - .byte $00 ; 175/af _overline__ - .byte $00 ; 176/b0 __degrees__ - .byte $00 ; 177/b1 ____+/-____ - .byte $00 ; 178/b2 _2_supersc_ - .byte $00 ; 179/b3 _3_supersc_ - .byte $00 ; 180/b4 ___acute___ - .byte $00 ; 181/b5 ____mu_____ - .byte $00 ; 182/b6 _paragraph_ - .byte $00 ; 183/b7 __mid_dot__ - .byte $00 ; 184/b8 __cedilla__ - .byte $00 ; 185/b9 _1_supersc_ - .byte $00 ; 186/ba __mas_ord__ - .byte $00 ; 187/bb _r_ang_quo_ - .byte $00 ; 188/bc ____1/4____ - .byte $00 ; 189/bd ____1/2____ - .byte $00 ; 190/be ____3/4____ - .byte $00 ; 191/bf _?_invertd_ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 96/60 _A`_grave__, 97/61 _A'_acute__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 98/62 _A^_circum_, 99/63 _A~_tilde__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 100/64 _A"_dieres_, 101/65 _A__ring___ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 102/66 _AE________, 103/67 _C,cedilla_ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 104/68 _E`_grave__, 105/69 _E'_acute__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 106/6a _E^_circum_, 107/6b _E"_dieres_ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 108/6c _I`_grave__, 109/6d _I'_acute__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 110/6e _I^_circum_, 111/6f _I"_dieres_ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 112/70 _D-_Eth_lr_, 113/71 _N~_tilde__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 114/72 _O`_grave__, 115/73 _O'_acute__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 116/74 _O^_circum_, 117/75 _O~_tilde__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 118/76 _O"_dieres_, 119/77 __multiply_ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 120/78 _O/_slash__, 121/79 _U`_grave__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 122/7a _U'_acute__, 123/7b _U^_circum_ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 124/7c _U"_dieres_, 125/7d _Y'_acute__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 126/7e _cap_thorn_, 127/7f _Es-sed_B__ - .byte $00 ; 192/c0 _____`_____ - .byte CT_UPPER | CT_XDIGIT ; 193/c1 _____A_____ - .byte CT_UPPER | CT_XDIGIT ; 194/c2 _____B_____ - .byte CT_UPPER | CT_XDIGIT ; 195/c3 _____C_____ - .byte CT_UPPER | CT_XDIGIT ; 196/c4 _____D_____ - .byte CT_UPPER | CT_XDIGIT ; 197/c5 _____E_____ - .byte CT_UPPER | CT_XDIGIT ; 198/c6 _____F_____ - .byte CT_UPPER ; 199/c7 _____G_____ - .byte CT_UPPER ; 200/c8 _____H_____ - .byte CT_UPPER ; 201/c9 _____I_____ - .byte CT_UPPER ; 202/ca _____J_____ - .byte CT_UPPER ; 203/cb _____K_____ - .byte CT_UPPER ; 204/cc _____L_____ - .byte CT_UPPER ; 205/cd _____M_____ - .byte CT_UPPER ; 206/ce _____N_____ - .byte CT_UPPER ; 207/cf _____O_____ - .byte CT_UPPER ; 208/d0 _____P_____ - .byte CT_UPPER ; 209/d1 _____Q_____ - .byte CT_UPPER ; 210/d2 _____R_____ - .byte CT_UPPER ; 211/d3 _____S_____ - .byte CT_UPPER ; 212/d4 _____T_____ - .byte CT_UPPER ; 213/d5 _____U_____ - .byte CT_UPPER ; 214/d6 _____V_____ - .byte CT_UPPER ; 215/d7 _____W_____ - .byte CT_UPPER ; 216/d8 _____X_____ - .byte CT_UPPER ; 217/d9 _____Y_____ - .byte CT_UPPER ; 218/da _____Z_____ - .byte $00 ; 219/db _____{_____ - .byte $00 ; 220/dc _____|_____ - .byte $00 ; 221/dd _____}_____ - .byte $00 ; 222/de _____~_____ - .byte $00 ; 223/df ___HOUSE___ - .byte $00 ; 224/e0 _a`_grave__ - .byte $00 ; 225/e1 _a'_acute__ - .byte $00 ; 226/e2 _a^_circum_ - .byte $00 ; 227/e3 _a~_tilde__ - .byte $00 ; 228/e4 _a"_dieres_ - .byte $00 ; 229/e5 _a__ring___ - .byte $00 ; 230/e6 _ae________ - .byte $00 ; 231/e7 _c,cedilla_ - .byte $00 ; 232/e8 _e`_grave__ - .byte $00 ; 233/e9 _e'_acute__ - .byte $00 ; 234/ea _e^_circum_ - .byte $00 ; 235/eb _e"_dieres_ - .byte $00 ; 236/ec _i`_grave__ - .byte $00 ; 237/ed _i'_acute__ - .byte $00 ; 238/ee _i^_circum_ - .byte $00 ; 239/ef _i"_dieres_ - .byte $00 ; 240/f0 _o^x_Eth_s_ - .byte $00 ; 241/f1 _n~_tilda__ - .byte $00 ; 242/f2 _o`_grave__ - .byte $00 ; 243/f3 _o'_acute__ - .byte $00 ; 244/f4 _o^_circum_ - .byte $00 ; 245/f5 _o~_tilde__ - .byte $00 ; 246/f6 _o"_dieres_ - .byte $00 ; 247/f7 __divide___ - .byte $00 ; 248/f8 _o/_slash__ - .byte $00 ; 249/f9 _u`_grave__ - .byte $00 ; 250/fa _u'_acute__ - .byte $00 ; 251/fb _u^_circum_ - .byte $00 ; 252/fc _u"_dieres_ - .byte $00 ; 253/fd _y'_acute__ - .byte $00 ; 254/fe _sm_thorn__ - .byte $00 ; 255/ff _y"_dieres_ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 128/80 __bullet___, 129/81 __v_line___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 130/82 __h_line___, 131/83 ___cross___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 132/84 _tl_corner_, 133/85 _tr_corner_ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 134/86 _bl_corner_, 135/87 _br_corner_ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 136/88 ___l_tee___, 137/89 ___r_tee___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 138/8a ___t_tee___, 139/8b ___b_tee___ + ct_mix CT_CTRL_IDX, CT_CTRL_WS_IDX ; 140/8c ___heart___, 141/8d _CR/diamond + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 142/8e ___club____, 143/8f ___spade___ + ct_mix CT_CTRL_IDX, CT_CTRL_WS_IDX ; 144/90 _s_circle__, 145/91 _cursor-up_ + ct_mix CT_CTRL_IDX, CT_CTRL_WS_IDX ; 146/92 ___pound___, 147/93 _CLS/check_ + ct_mix CT_CTRL_WS_IDX, CT_CTRL_IDX ; 148/94 __INSert___, 149/95 ____+/-____ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 150/96 __divide___, 151/97 __degree___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 152/98 _c_checker_, 153/99 _f_checker_ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 154/9a _solid_sq__, 155/9b __cr_char__ + ct_mix CT_CTRL_IDX, CT_CTRL_WS_IDX ; 156/9c _up_arrow__, 157/9d cursor-left + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 158/9e _left_arro_, 159/9f _right_arr_ + ct_mix CT_SPACE_SPACETAB_IDX, CT_NONE_IDX ; 160/a0 _req space_, 161/a1 _!_invertd_ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 162/a2 ___cent____, 163/a3 ___pound___ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 164/a4 __currency_, 165/a5 ____yen____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 166/a6 _|_broken__, 167/a7 __section__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 168/a8 __umulaut__, 169/a9 _copyright_ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 170/aa __fem_ord__, 171/ab _l_ang_quo_ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 172/ac ____not____, 173/ad _syl_hyphn_ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 174/ae _registerd_, 175/af _overline__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 176/b0 __degrees__, 177/b1 ____+/-____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 178/b2 _2_supersc_, 179/b3 _3_supersc_ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 180/b4 ___acute___, 181/b5 ____mu_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 182/b6 _paragraph_, 183/b7 __mid_dot__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 184/b8 __cedilla__, 185/b9 _1_supersc_ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 186/ba __mas_ord__, 187/bb _r_ang_quo_ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 188/bc ____1/4____, 189/bd ____1/2____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 190/be ____3/4____, 191/bf _?_invertd_ + + ct_mix CT_NONE_IDX, CT_UPPER_XDIGIT_IDX ; 192/c0 _____`_____, 193/c1 _____A_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_XDIGIT_IDX ; 194/c2 _____B_____, 195/c3 _____C_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_XDIGIT_IDX ; 196/c4 _____D_____, 197/c5 _____E_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_IDX ; 198/c6 _____F_____, 199/c7 _____G_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 200/c8 _____H_____, 201/c9 _____I_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 202/ca _____J_____, 203/cb _____K_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 204/cc _____L_____, 205/cd _____M_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 206/ce _____N_____, 207/cf _____O_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 208/d0 _____P_____, 209/d1 _____Q_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 210/d2 _____R_____, 211/d3 _____S_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 212/d4 _____T_____, 213/d5 _____U_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 214/d6 _____V_____, 215/d7 _____W_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 216/d8 _____X_____, 217/d9 _____Y_____ + ct_mix CT_UPPER_IDX, CT_NONE_IDX ; 218/da _____Z_____, 219/db _____{_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 220/dc _____|_____, 221/dd _____}_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 222/de _____~_____, 223/df ___HOUSE___ + + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 224/e0 _a`_grave__, 225/e1 _a'_acute__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 226/e2 _a^_circum_, 227/e3 _a~_tilde__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 228/e4 _a"_dieres_, 229/e5 _a__ring___ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 230/e6 _ae________, 231/e7 _c,cedilla_ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 232/e8 _e`_grave__, 233/e9 _e'_acute__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 234/ea _e^_circum_, 235/eb _e"_dieres_ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 236/ec _i`_grave__, 237/ed _i'_acute__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 238/ee _i^_circum_, 239/ef _i"_dieres_ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 240/f0 _o^x_Eth_s_, 241/f1 _n~_tilda__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 242/f2 _o`_grave__, 243/f3 _o'_acute__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 244/f4 _o^_circum_, 245/f5 _o~_tilde__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 246/f6 _o"_dieres_, 247/f7 __divide___ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 248/f8 _o/_slash__, 249/f9 _u`_grave__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 250/fa _u'_acute__, 251/fb _u^_circum_ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 252/fc _u"_dieres_, 253/fd _y'_acute__ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 254/fe _sm_thorn__, 255/ff _y"_dieres_ diff --git a/libsrc/common/atoi.s b/libsrc/common/atoi.s index cb598f719..8427be62e 100644 --- a/libsrc/common/atoi.s +++ b/libsrc/common/atoi.s @@ -8,9 +8,8 @@ .export _atoi, _atol .import negeax, __ctype .importzp sreg, ptr1, ptr2, tmp1 - + .import ctype_preprocessor_no_check .include "ctype.inc" - ; ; Conversion routine (32 bit) ; @@ -27,8 +26,9 @@ _atol: sta ptr1 ; Store s ; Skip whitespace L1: lda (ptr1),y - tax - lda __ctype,x ; get character classification + ; get character classification + jsr ctype_preprocessor_no_check + and #CT_SPACE_TAB ; tab or space? beq L2 ; jump if no iny @@ -36,10 +36,10 @@ L1: lda (ptr1),y inc ptr1+1 bne L1 ; branch always -; Check for a sign. The character is in X +; Check for a sign. Refetch character, X is cleared by preprocessor -L2: txa ; get char - ldx #0 ; flag: positive +L2: lda (ptr1),y ; get char + ; x=0 -> flag: positive cmp #'+' ; ### portable? beq L3 cmp #'-' ; ### portable? @@ -54,9 +54,9 @@ L3: iny L5: stx tmp1 ; remember sign flag L6: lda (ptr1),y ; get next char - tax - lda __ctype,x ; get character classification - and #$04 ; digit? + ; get character classification + jsr ctype_preprocessor_no_check + and #CT_DIGIT ; digit? beq L8 ; done ; Multiply ptr2 (the converted value) by 10 @@ -91,7 +91,7 @@ L6: lda (ptr1),y ; get next char ; Get the character back and add it - txa ; get char back + lda (ptr1),y ; fetch char again sec sbc #'0' ; make numeric value clc diff --git a/libsrc/common/ctype_preprocessor.s b/libsrc/common/ctype_preprocessor.s new file mode 100644 index 000000000..1f33bd224 --- /dev/null +++ b/libsrc/common/ctype_preprocessor.s @@ -0,0 +1,50 @@ +; ctype_preprocessor.s +; +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. +; +; ctype_preprocessor(int c) +; +; converts a character to test via the is*-functions to the matching ctype-masks +; If c is out of the 8-bit range, the function returns with carry set and accu cleared. +; Return value is in accu and x has to be always clear when returning +; (makes calling code shorter)! +; +; IMPORTANT: stricmp, strlower, strnicmp, strupper and atoi rely that Y is not changed +; while calling this function! +; + + .export ctype_preprocessor + .export ctype_preprocessor_no_check + .import __ctype + .import __ctypeIdx + +ctype_preprocessor: + cpx #$00 ; char range ok? + bne SC ; branch if not +ctype_preprocessor_no_check: + lsr a + tax + lda __ctypeIdx, x + bcc @lowerNibble +@upperNibble: + lsr a + lsr a + lsr a + lsr a + clc ; remove out of bounds flag +@lowerNibble: + and #%1111 + tax + lda __ctype, x + ldx #0 + rts + +SC: sec + lda #0 + tax + rts diff --git a/libsrc/common/isalnum.s b/libsrc/common/isalnum.s index 33497a30c..4f6a5e91b 100644 --- a/libsrc/common/isalnum.s +++ b/libsrc/common/isalnum.s @@ -1,21 +1,21 @@ +; isalnum.s ; -; Ullrich von Bassewitz, 02.06.1998 +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. ; ; int isalnum (int c); ; .export _isalnum .include "ctype.inc" + .import ctype_preprocessor _isalnum: - cpx #$00 ; Char range ok? - bne @L1 ; Jump if no - tay - lda __ctype,y ; Get character classification - and #CT_ALNUM ; Mask character/digit bits - rts - -@L1: lda #$00 ; Return false - tax - rts - + jsr ctype_preprocessor ; (clears always x) + bcs @L1 ; out of range? (everything already clear -> false) + and #CT_ALNUM ; mask character/digit bits +@L1: rts diff --git a/libsrc/common/isalpha.s b/libsrc/common/isalpha.s index 2ab9bf269..a331722a1 100644 --- a/libsrc/common/isalpha.s +++ b/libsrc/common/isalpha.s @@ -1,21 +1,21 @@ +; isalpha.s ; -; Ullrich von Bassewitz, 02.06.1998 +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. ; ; int isalpha (int c); ; .export _isalpha .include "ctype.inc" + .import ctype_preprocessor _isalpha: - cpx #$00 ; Char range ok? - bne @L1 ; Jump if no - tay - lda __ctype,y ; Get character classification - and #CT_ALPHA ; Mask character bits - rts - -@L1: lda #$00 ; Return false - tax - rts - + jsr ctype_preprocessor ; (clears always x) + bcs @L1 ; out of range? (everything already clear -> false) + and #CT_ALPHA ; mask character bits +@L1: rts diff --git a/libsrc/common/isascii.s b/libsrc/common/isascii.s new file mode 100644 index 000000000..dccfabaa1 --- /dev/null +++ b/libsrc/common/isascii.s @@ -0,0 +1,27 @@ +; isascii.s +; +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. +; +; int isascii (int c); +; + + .export _isascii + +_isascii: + cpx #$00 ; Char range ok? + bne @L1 ; Jump if no + + tay + bmi @L1 + + inx + rts + +@L1: lda #$00 ; Return false + tax + rts diff --git a/libsrc/common/isblank.s b/libsrc/common/isblank.s index 6babe8853..5e0eafd73 100644 --- a/libsrc/common/isblank.s +++ b/libsrc/common/isblank.s @@ -1,5 +1,11 @@ +; isblank.s ; -; Ullrich von Bassewitz, 02.06.1998 +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. ; ; int isblank (int c); ; @@ -8,16 +14,10 @@ .export _isblank .include "ctype.inc" + .import ctype_preprocessor _isblank: - cpx #$00 ; Char range ok? - bne @L1 ; Jump if no - tay - lda __ctype,y ; Get character classification - and #CT_SPACE_TAB ; Mask blank bit - rts - -@L1: lda #$00 ; Return false - tax - rts - + jsr ctype_preprocessor ; (clears always x) + bcs @L1 ; out of range? (everything already clear -> false) + and #CT_SPACE_TAB ; mask blank bit + @L1: rts diff --git a/libsrc/common/iscntrl.s b/libsrc/common/iscntrl.s index 728716450..f4bf02858 100644 --- a/libsrc/common/iscntrl.s +++ b/libsrc/common/iscntrl.s @@ -1,21 +1,21 @@ +; iscntrl.s ; -; Ullrich von Bassewitz, 02.06.1998 +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. ; ; int iscntrl (int c); ; .export _iscntrl .include "ctype.inc" + .import ctype_preprocessor _iscntrl: - cpx #$00 ; Char range ok? - bne @L1 ; Jump if no - tay - lda __ctype,y ; Get character classification - and #CT_CTRL ; Mask control character bit - rts - -@L1: lda #$00 ; Return false - tax - rts - + jsr ctype_preprocessor ; (clears always x) + bcs @L1 ; out of range? (everything already clear -> false) + and #CT_CTRL ; mask control character bit +@L1: rts diff --git a/libsrc/common/isdigit.s b/libsrc/common/isdigit.s index 2972c8941..c0e8bb026 100644 --- a/libsrc/common/isdigit.s +++ b/libsrc/common/isdigit.s @@ -1,21 +1,21 @@ +; isdigit.s ; -; Ullrich von Bassewitz, 02.06.1998 +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. ; ; int isdigit (int c); ; .export _isdigit .include "ctype.inc" + .import ctype_preprocessor _isdigit: - cpx #$00 ; Char range ok? - bne @L1 ; Jump if no - tay - lda __ctype,y ; Get character classification - and #CT_DIGIT ; Mask digit bit - rts - -@L1: lda #$00 ; Return false - tax - rts - + jsr ctype_preprocessor ; (clears always x) + bcs @L1 ; out of range? (everything already clear -> false) + and #CT_DIGIT ; mask digit bit + @L1: rts diff --git a/libsrc/common/isgraph.s b/libsrc/common/isgraph.s index bf94014ec..575b05a62 100644 --- a/libsrc/common/isgraph.s +++ b/libsrc/common/isgraph.s @@ -1,25 +1,25 @@ +; isgraph.s ; -; 1998-06-02, Ullrich von Bassewitz -; 2014-09-10, Greg King +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. ; ; int isgraph (int c); ; .export _isgraph .include "ctype.inc" + .import ctype_preprocessor _isgraph: - cpx #>$0000 ; Char range OK? - bne @L1 ; Jump if no - tay - lda __ctype,y ; Get character classification - and #CT_CTRL_SPACE ; Mask character bits - cmp #1 ; If false, then set "borrow" flag + jsr ctype_preprocessor ; (clears always x) + bcs @L1 ; out of range? (everything already clear -> false) + and #CT_CTRL_SPACE ; mask character bits + cmp #1 ; if false, then set "borrow" flag lda #0 - sbc #0 ; Invert logic - rts ; Return NOT control and NOT space - -@L1: lda #<0 ; Return false - tax - rts + sbc #0 ; invert logic (return NOT control and NOT space) +@L1: rts diff --git a/libsrc/common/islower.s b/libsrc/common/islower.s index 32e00fbd6..62ae41643 100644 --- a/libsrc/common/islower.s +++ b/libsrc/common/islower.s @@ -1,21 +1,23 @@ +; islower.s ; -; Ullrich von Bassewitz, 02.06.1998 +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. ; ; int islower (int c); ; .export _islower .include "ctype.inc" + .import ctype_preprocessor _islower: - cpx #$00 ; Char range ok? - bne @L1 ; Jump if no - tay - lda __ctype,y ; Get character classification - and #CT_LOWER ; Mask lower char bit - rts + jsr ctype_preprocessor ; (clears always x) + bcs @L1 ; out of range? (everything already clear -> false) + and #CT_LOWER ; mask lower char bit +@L1: rts -@L1: lda #$00 ; Return false - tax - rts diff --git a/libsrc/common/isprint.s b/libsrc/common/isprint.s index 1511753fd..cbe68c801 100644 --- a/libsrc/common/isprint.s +++ b/libsrc/common/isprint.s @@ -1,22 +1,22 @@ +; isprint.s ; -; Ullrich von Bassewitz, 02.06.1998 +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. ; ; int isprint (int c); ; .export _isprint .include "ctype.inc" + .import ctype_preprocessor _isprint: - cpx #$00 ; Char range ok? - bne @L1 ; Jump if no - tay - lda __ctype,y ; Get character classification - eor #CT_CTRL ; NOT a control char - and #CT_CTRL ; Mask control char bit - rts - -@L1: lda #$00 ; Return false - tax - rts - + jsr ctype_preprocessor ; (clears always x) + bcs @L1 ; out of range? (everything already clear -> false) + eor #CT_CTRL ; NOT a control char + and #CT_CTRL ; mask control char bit +@L1: rts diff --git a/libsrc/common/ispunct.s b/libsrc/common/ispunct.s index 087532940..ad48fc534 100644 --- a/libsrc/common/ispunct.s +++ b/libsrc/common/ispunct.s @@ -1,25 +1,24 @@ +; ispunct.s ; -; 1998-06-02, Ullrich von Bassewitz -; 2014-09-10, Greg King +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. ; ; int ispunct (int c); ; .export _ispunct .include "ctype.inc" + .import ctype_preprocessor _ispunct: - cpx #>$0000 ; Char range OK? - bne @L1 ; Jump if no - tay - lda __ctype,y ; Get character classification - and #CT_NOT_PUNCT ; Mask relevant bits - cmp #1 ; If false, then set "borrow" flag + jsr ctype_preprocessor ; (clears always x) + bcs @L1 ; out of range? (everything already clear -> false) + and #CT_NOT_PUNCT ; mask relevant bits + cmp #1 ; if false, then set "borrow" flag lda #0 - sbc #0 ; Invert logic - rts ; Return NOT (space | control | digit | alpha) - -@L1: lda #<0 ; Return false - tax - rts - + sbc #0 ; invert logic (return NOT (space | control | digit | alpha)) +@L1: rts diff --git a/libsrc/common/isspace.s b/libsrc/common/isspace.s index 64849f7f7..272acac0c 100644 --- a/libsrc/common/isspace.s +++ b/libsrc/common/isspace.s @@ -1,21 +1,21 @@ +; isspace.s ; -; Ullrich von Bassewitz, 02.06.1998 +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. ; ; int isspace (int c); ; .export _isspace .include "ctype.inc" + .import ctype_preprocessor _isspace: - cpx #$00 ; Char range ok? - bne @L1 ; Jump if no - tay - lda __ctype,y ; Get character classification - and #(CT_SPACE | CT_OTHER_WS) ; Mask space bits - rts - -@L1: lda #$00 ; Return false - tax - rts - + jsr ctype_preprocessor ; (clears always x) + bcs @L1 ; out of range? (everything already clear -> false) + and #(CT_SPACE | CT_OTHER_WS) ; mask space bits + @L1: rts diff --git a/libsrc/common/isupper.s b/libsrc/common/isupper.s index 698983ec8..2d89459a0 100644 --- a/libsrc/common/isupper.s +++ b/libsrc/common/isupper.s @@ -1,21 +1,21 @@ +; isupper.s ; -; Ullrich von Bassewitz, 02.06.1998 +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. ; ; int isupper (int c); ; .export _isupper .include "ctype.inc" + .import ctype_preprocessor _isupper: - cpx #$00 ; Char range ok? - bne @L1 ; Jump if no - tay - lda __ctype,y ; Get character classification - and #CT_UPPER ; Mask upper char bit - rts - -@L1: lda #$00 ; Return false - tax - rts - + jsr ctype_preprocessor ; (clears always x) + bcs @L1 ; out of range? (everything already clear -> false) + and #CT_UPPER ; mask upper char bit +@L1: rts diff --git a/libsrc/common/isxdigit.s b/libsrc/common/isxdigit.s index 36f86ef19..07fef5c2b 100644 --- a/libsrc/common/isxdigit.s +++ b/libsrc/common/isxdigit.s @@ -1,21 +1,21 @@ +; isxdigit.s ; -; Ullrich von Bassewitz, 02.06.1998 +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. ; ; int isxdigit (int c); ; .export _isxdigit .include "ctype.inc" + .import ctype_preprocessor _isxdigit: - cpx #$00 ; Char range ok? - bne @L1 ; Jump if no - tay - lda __ctype,y ; Get character classification - and #CT_XDIGIT ; Mask xdigit bit - rts - -@L1: lda #$00 ; Return false - tax - rts - + jsr ctype_preprocessor ; (clears always x) + bcs @L1 ; out of range? (everything already clear -> false) + and #CT_XDIGIT ; mask xdigit bit +@L1: rts diff --git a/libsrc/common/stricmp.s b/libsrc/common/stricmp.s index 384e78e31..e1683d9f3 100644 --- a/libsrc/common/stricmp.s +++ b/libsrc/common/stricmp.s @@ -1,5 +1,11 @@ +; stricmp.s ; -; Ullrich von Bassewitz, 03.06.1998 +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. ; ; int stricmp (const char* s1, const char* s2); /* DOS way */ ; int strcasecmp (const char* s1, const char* s2); /* UNIX way */ @@ -7,9 +13,8 @@ .export _stricmp, _strcasecmp .import popptr1 - .import __ctype - .importzp ptr1, ptr2, tmp1 - + .importzp ptr1, ptr2, tmp1, tmp2 + .import ctype_preprocessor_no_check .include "ctype.inc" _stricmp: @@ -20,27 +25,27 @@ _strcasecmp: ; ldy #0 ; Y=0 guaranteed by popptr1 loop: lda (ptr2),y ; get char from second string - tax - lda __ctype,x ; get character classification + sta tmp2 ; and save it + ; get character classification + jsr ctype_preprocessor_no_check and #CT_LOWER ; lower case char? beq L1 ; jump if no - txa ; get character back - clc - adc #<('A'-'a') ; make upper case char - tax ; -L1: stx tmp1 ; remember upper case equivalent + lda #<('A'-'a') ; make upper case char + adc tmp2 ; ctype_preprocessor_no_check ensures carry clear! + sta tmp2 ; remember upper case equivalent - lda (ptr1),y ; get character from first string - tax - lda __ctype,x ; get character classification +L1: lda (ptr1),y ; get character from first string + sta tmp1 + ; get character classification + jsr ctype_preprocessor_no_check and #CT_LOWER ; lower case char? beq L2 ; jump if no - txa ; get character back - clc - adc #<('A'-'a') ; make upper case char - tax + lda #<('A'-'a') ; make upper case char + adc tmp1 ; ctype_preprocessor_no_check ensures carry clear! + sta tmp1 ; remember upper case equivalent -L2: cpx tmp1 ; compare characters +L2: ldx tmp1 + cpx tmp2 ; compare characters bne L3 txa ; end of strings? beq L5 ; a/x both zero diff --git a/libsrc/common/strlower.s b/libsrc/common/strlower.s index 848a4faff..8c634b6e6 100644 --- a/libsrc/common/strlower.s +++ b/libsrc/common/strlower.s @@ -10,9 +10,8 @@ .export _strlower, _strlwr .import popax - .import __ctype .importzp ptr1, ptr2 - + .import ctype_preprocessor_no_check .include "ctype.inc" _strlower: @@ -25,11 +24,11 @@ _strlwr: loop: lda (ptr1),y ; get character beq L9 ; jump if done - tax - lda __ctype,x ; get character classification + ; get character classification + jsr ctype_preprocessor_no_check and #CT_UPPER ; upper case char? beq L1 ; jump if no - txa ; get character back into accu + lda (ptr1),y ; fetch character again sec sbc #<('A'-'a') ; make lower case char sta (ptr1),y ; store back diff --git a/libsrc/common/strnicmp.s b/libsrc/common/strnicmp.s index 6a5de09e4..54aef2bb8 100644 --- a/libsrc/common/strnicmp.s +++ b/libsrc/common/strnicmp.s @@ -7,9 +7,9 @@ ; .export _strnicmp, _strncasecmp - .import popax, popptr1, __ctype - .importzp ptr1, ptr2, ptr3, tmp1 - + .import popax, popptr1 + .importzp ptr1, ptr2, ptr3, tmp1, tmp2 + .import ctype_preprocessor_no_check .include "ctype.inc" _strnicmp: @@ -46,27 +46,27 @@ Loop: inc ptr3 ; Compare a byte from the strings Comp: lda (ptr2),y - tax - lda __ctype,x ; get character classification + sta tmp2 ; remember original char + ; get character classification + jsr ctype_preprocessor_no_check and #CT_LOWER ; lower case char? beq L1 ; jump if no - txa ; get character back - sec - sbc #<('a'-'A') ; make upper case char - tax ; -L1: stx tmp1 ; remember upper case equivalent + lda #<('A'-'a') ; make upper case char + adc tmp2 ; ctype_preprocessor_no_check ensures carry clear! + sta tmp2 ; remember upper case equivalent - lda (ptr1),y ; get character from first string - tax - lda __ctype,x ; get character classification +L1: lda (ptr1),y ; get character from first string + sta tmp1 ; remember original char + ; get character classification + jsr ctype_preprocessor_no_check and #CT_LOWER ; lower case char? beq L2 ; jump if no - txa ; get character back - sec - sbc #<('a'-'A') ; make upper case char - tax + lda #<('A'-'a') ; make upper case char + adc tmp1 ; ctype_preprocessor_no_check ensures carry clear! + sta tmp1 ; remember upper case equivalent -L2: cpx tmp1 ; compare characters +L2: ldx tmp1 + cpx tmp2 ; compare characters bne NotEqual ; Jump if strings different txa ; End of strings? beq Equal1 ; Jump if EOS reached, a/x == 0 diff --git a/libsrc/common/strupper.s b/libsrc/common/strupper.s index bf0d3b622..c07fb17c1 100644 --- a/libsrc/common/strupper.s +++ b/libsrc/common/strupper.s @@ -10,9 +10,8 @@ .export _strupper, _strupr .import popax - .import __ctype .importzp ptr1, ptr2 - + .import ctype_preprocessor_no_check .include "ctype.inc" _strupper: @@ -25,11 +24,10 @@ _strupr: loop: lda (ptr1),y ; get character beq L9 ; jump if done - tax - lda __ctype,x ; get character classification + jsr ctype_preprocessor_no_check and #CT_LOWER ; lower case char? beq L1 ; jump if no - txa ; get character back into accu + lda (ptr1),y ; fetch character again clc adc #<('A'-'a') ; make upper case char sta (ptr1),y ; store back diff --git a/libsrc/creativision/ctype.s b/libsrc/creativision/ctype.s index 6e0ab1785..da4d38472 100644 --- a/libsrc/creativision/ctype.s +++ b/libsrc/creativision/ctype.s @@ -1,172 +1,5 @@ -; -; Ullrich von Bassewitz, 02.06.1998 -; ; Character specification table. ; +; uses the "console" definition -; The tables are readonly, put them into the rodata segment - -.rodata - -; The following 256 byte wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it -; has major advantages: -; -; * It is fast. If it were'nt for the slow parameter passing of cc65, one -; could even define macros for the isxxx functions (this is usually -; done on other platforms). -; -; * It is highly portable. The only unportable part is the table itself, -; all real code goes into the common library. -; -; * We save some code in the isxxx functions. -; -; -; Bit assignments: -; -; 0 - Lower case char -; 1 - Upper case char -; 2 - Numeric digit -; 3 - Hex digit (both, lower and upper) -; 4 - Control character -; 5 - The space character itself -; 6 - Other whitespace (that is: '\f', '\n', '\r', '\t' and '\v') -; 7 - Space or tab character - - .export __ctype - -__ctype: - -.repeat 2 ; 2 times for normal and inverted - - .byte $10 ; 0/00 ___ctrl_@___ - .byte $10 ; 1/01 ___ctrl_A___ - .byte $10 ; 2/02 ___ctrl_B___ - .byte $10 ; 3/03 ___ctrl_C___ - .byte $10 ; 4/04 ___ctrl_D___ - .byte $10 ; 5/05 ___ctrl_E___ - .byte $10 ; 6/06 ___ctrl_F___ - .byte $10 ; 7/07 ___ctrl_G___ - .byte $10 ; 8/08 ___ctrl_H___ - .byte $D0 ; 9/09 ___ctrl_I___ - .byte $50 ; 10/0a ___ctrl_J___ - .byte $50 ; 11/0b ___ctrl_K___ - .byte $50 ; 12/0c ___ctrl_L___ - .byte $50 ; 13/0d ___ctrl_M___ - .byte $10 ; 14/0e ___ctrl_N___ - .byte $10 ; 15/0f ___ctrl_O___ - .byte $10 ; 16/10 ___ctrl_P___ - .byte $10 ; 17/11 ___ctrl_Q___ - .byte $10 ; 18/12 ___ctrl_R___ - .byte $10 ; 19/13 ___ctrl_S___ - .byte $10 ; 20/14 ___ctrl_T___ - .byte $10 ; 21/15 ___ctrl_U___ - .byte $10 ; 22/16 ___ctrl_V___ - .byte $10 ; 23/17 ___ctrl_W___ - .byte $10 ; 24/18 ___ctrl_X___ - .byte $10 ; 25/19 ___ctrl_Y___ - .byte $10 ; 26/1a ___ctrl_Z___ - .byte $10 ; 27/1b ___ctrl_[___ - .byte $10 ; 28/1c ___ctrl_\___ - .byte $10 ; 29/1d ___ctrl_]___ - .byte $10 ; 30/1e ___ctrl_^___ - .byte $10 ; 31/1f ___ctrl_____ - .byte $A0 ; 32/20 ___SPACE___ - .byte $00 ; 33/21 _____!_____ - .byte $00 ; 34/22 _____"_____ - .byte $00 ; 35/23 _____#_____ - .byte $00 ; 36/24 _____$_____ - .byte $00 ; 37/25 _____%_____ - .byte $00 ; 38/26 _____&_____ - .byte $00 ; 39/27 _____'_____ - .byte $00 ; 40/28 _____(_____ - .byte $00 ; 41/29 _____)_____ - .byte $00 ; 42/2a _____*_____ - .byte $00 ; 43/2b _____+_____ - .byte $00 ; 44/2c _____,_____ - .byte $00 ; 45/2d _____-_____ - .byte $00 ; 46/2e _____._____ - .byte $00 ; 47/2f _____/_____ - .byte $0C ; 48/30 _____0_____ - .byte $0C ; 49/31 _____1_____ - .byte $0C ; 50/32 _____2_____ - .byte $0C ; 51/33 _____3_____ - .byte $0C ; 52/34 _____4_____ - .byte $0C ; 53/35 _____5_____ - .byte $0C ; 54/36 _____6_____ - .byte $0C ; 55/37 _____7_____ - .byte $0C ; 56/38 _____8_____ - .byte $0C ; 57/39 _____9_____ - .byte $00 ; 58/3a _____:_____ - .byte $00 ; 59/3b _____;_____ - .byte $00 ; 60/3c _____<_____ - .byte $00 ; 61/3d _____=_____ - .byte $00 ; 62/3e _____>_____ - .byte $00 ; 63/3f _____?_____ - - .byte $00 ; 64/40 _____@_____ - .byte $0A ; 65/41 _____A_____ - .byte $0A ; 66/42 _____B_____ - .byte $0A ; 67/43 _____C_____ - .byte $0A ; 68/44 _____D_____ - .byte $0A ; 69/45 _____E_____ - .byte $0A ; 70/46 _____F_____ - .byte $02 ; 71/47 _____G_____ - .byte $02 ; 72/48 _____H_____ - .byte $02 ; 73/49 _____I_____ - .byte $02 ; 74/4a _____J_____ - .byte $02 ; 75/4b _____K_____ - .byte $02 ; 76/4c _____L_____ - .byte $02 ; 77/4d _____M_____ - .byte $02 ; 78/4e _____N_____ - .byte $02 ; 79/4f _____O_____ - .byte $02 ; 80/50 _____P_____ - .byte $02 ; 81/51 _____Q_____ - .byte $02 ; 82/52 _____R_____ - .byte $02 ; 83/53 _____S_____ - .byte $02 ; 84/54 _____T_____ - .byte $02 ; 85/55 _____U_____ - .byte $02 ; 86/56 _____V_____ - .byte $02 ; 87/57 _____W_____ - .byte $02 ; 88/58 _____X_____ - .byte $02 ; 89/59 _____Y_____ - .byte $02 ; 90/5a _____Z_____ - .byte $00 ; 91/5b _____[_____ - .byte $00 ; 92/5c _____\_____ - .byte $00 ; 93/5d _____]_____ - .byte $00 ; 94/5e _____^_____ - .byte $00 ; 95/5f _UNDERLINE_ - .byte $00 ; 96/60 ___grave___ - .byte $09 ; 97/61 _____a_____ - .byte $09 ; 98/62 _____b_____ - .byte $09 ; 99/63 _____c_____ - .byte $09 ; 100/64 _____d_____ - .byte $09 ; 101/65 _____e_____ - .byte $09 ; 102/66 _____f_____ - .byte $01 ; 103/67 _____g_____ - .byte $01 ; 104/68 _____h_____ - .byte $01 ; 105/69 _____i_____ - .byte $01 ; 106/6a _____j_____ - .byte $01 ; 107/6b _____k_____ - .byte $01 ; 108/6c _____l_____ - .byte $01 ; 109/6d _____m_____ - .byte $01 ; 110/6e _____n_____ - .byte $01 ; 111/6f _____o_____ - .byte $01 ; 112/70 _____p_____ - .byte $01 ; 113/71 _____q_____ - .byte $01 ; 114/72 _____r_____ - .byte $01 ; 115/73 _____s_____ - .byte $01 ; 116/74 _____t_____ - .byte $01 ; 117/75 _____u_____ - .byte $01 ; 118/76 _____v_____ - .byte $01 ; 119/77 _____w_____ - .byte $01 ; 120/78 _____x_____ - .byte $01 ; 121/79 _____y_____ - .byte $01 ; 122/7a _____z_____ - .byte $00 ; 123/7b _____{_____ - .byte $00 ; 124/7c _____|_____ - .byte $00 ; 125/7d _____}_____ - .byte $00 ; 126/7e _____~_____ - .byte $40 ; 127/7f ____DEL____ - -.endrepeat + .include "ctype_console.inc" diff --git a/libsrc/gamate/ctype.s b/libsrc/gamate/ctype.s index fa9a65c8b..da4d38472 100644 --- a/libsrc/gamate/ctype.s +++ b/libsrc/gamate/ctype.s @@ -1,161 +1,5 @@ -; -; Stefan Haubenthal with minor changes from Ullrich von Bassewitz, 2003-05-02 -; ; Character specification table. ; +; uses the "console" definition - .include "ctype.inc" - -; The tables are readonly, put them into the rodata segment - -.rodata - -; The following 256 byte wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it -; has major advantages: -; -; * It is fast. If it were'nt for the slow parameter passing of cc65, one -; could even define macros for the isxxx functions (this is usually -; done on other platforms). -; -; * It is highly portable. The only unportable part is the table itself, -; all real code goes into the common library. -; -; * We save some code in the isxxx functions. - - -__ctype: - .repeat 2 - .byte CT_CTRL ; 0/00 ___ctrl_@___ - .byte CT_CTRL ; 1/01 ___ctrl_A___ - .byte CT_CTRL ; 2/02 ___ctrl_B___ - .byte CT_CTRL ; 3/03 ___ctrl_C___ - .byte CT_CTRL ; 4/04 ___ctrl_D___ - .byte CT_CTRL ; 5/05 ___ctrl_E___ - .byte CT_CTRL ; 6/06 ___ctrl_F___ - .byte CT_CTRL ; 7/07 ___ctrl_G___ - .byte CT_CTRL ; 8/08 ___ctrl_H___ - .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB - ; 9/09 ___ctrl_I___ - .byte CT_CTRL | CT_OTHER_WS ; 10/0a ___ctrl_J___ - .byte CT_CTRL | CT_OTHER_WS ; 11/0b ___ctrl_K___ - .byte CT_CTRL | CT_OTHER_WS ; 12/0c ___ctrl_L___ - .byte CT_CTRL | CT_OTHER_WS ; 13/0d ___ctrl_M___ - .byte CT_CTRL ; 14/0e ___ctrl_N___ - .byte CT_CTRL ; 15/0f ___ctrl_O___ - .byte CT_CTRL ; 16/10 ___ctrl_P___ - .byte CT_CTRL ; 17/11 ___ctrl_Q___ - .byte CT_CTRL ; 18/12 ___ctrl_R___ - .byte CT_CTRL ; 19/13 ___ctrl_S___ - .byte CT_CTRL ; 20/14 ___ctrl_T___ - .byte CT_CTRL ; 21/15 ___ctrl_U___ - .byte CT_CTRL ; 22/16 ___ctrl_V___ - .byte CT_CTRL ; 23/17 ___ctrl_W___ - .byte CT_CTRL ; 24/18 ___ctrl_X___ - .byte CT_CTRL ; 25/19 ___ctrl_Y___ - .byte CT_CTRL ; 26/1a ___ctrl_Z___ - .byte CT_CTRL ; 27/1b ___ctrl_[___ - .byte CT_CTRL ; 28/1c ___ctrl_\___ - .byte CT_CTRL ; 29/1d ___ctrl_]___ - .byte CT_CTRL ; 30/1e ___ctrl_^___ - .byte CT_CTRL ; 31/1f ___ctrl_____ - .byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___ - .byte CT_NONE ; 33/21 _____!_____ - .byte CT_NONE ; 34/22 _____"_____ - .byte CT_NONE ; 35/23 _____#_____ - .byte CT_NONE ; 36/24 _____$_____ - .byte CT_NONE ; 37/25 _____%_____ - .byte CT_NONE ; 38/26 _____&_____ - .byte CT_NONE ; 39/27 _____'_____ - .byte CT_NONE ; 40/28 _____(_____ - .byte CT_NONE ; 41/29 _____)_____ - .byte CT_NONE ; 42/2a _____*_____ - .byte CT_NONE ; 43/2b _____+_____ - .byte CT_NONE ; 44/2c _____,_____ - .byte CT_NONE ; 45/2d _____-_____ - .byte CT_NONE ; 46/2e _____._____ - .byte CT_NONE ; 47/2f _____/_____ - .byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____ - .byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____ - .byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____ - .byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____ - .byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____ - .byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____ - .byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____ - .byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____ - .byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____ - .byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____ - .byte CT_NONE ; 58/3a _____:_____ - .byte CT_NONE ; 59/3b _____;_____ - .byte CT_NONE ; 60/3c _____<_____ - .byte CT_NONE ; 61/3d _____=_____ - .byte CT_NONE ; 62/3e _____>_____ - .byte CT_NONE ; 63/3f _____?_____ - - .byte CT_NONE ; 64/40 _____@_____ - .byte CT_UPPER | CT_XDIGIT ; 65/41 _____A_____ - .byte CT_UPPER | CT_XDIGIT ; 66/42 _____B_____ - .byte CT_UPPER | CT_XDIGIT ; 67/43 _____C_____ - .byte CT_UPPER | CT_XDIGIT ; 68/44 _____D_____ - .byte CT_UPPER | CT_XDIGIT ; 69/45 _____E_____ - .byte CT_UPPER | CT_XDIGIT ; 70/46 _____F_____ - .byte CT_UPPER ; 71/47 _____G_____ - .byte CT_UPPER ; 72/48 _____H_____ - .byte CT_UPPER ; 73/49 _____I_____ - .byte CT_UPPER ; 74/4a _____J_____ - .byte CT_UPPER ; 75/4b _____K_____ - .byte CT_UPPER ; 76/4c _____L_____ - .byte CT_UPPER ; 77/4d _____M_____ - .byte CT_UPPER ; 78/4e _____N_____ - .byte CT_UPPER ; 79/4f _____O_____ - .byte CT_UPPER ; 80/50 _____P_____ - .byte CT_UPPER ; 81/51 _____Q_____ - .byte CT_UPPER ; 82/52 _____R_____ - .byte CT_UPPER ; 83/53 _____S_____ - .byte CT_UPPER ; 84/54 _____T_____ - .byte CT_UPPER ; 85/55 _____U_____ - .byte CT_UPPER ; 86/56 _____V_____ - .byte CT_UPPER ; 87/57 _____W_____ - .byte CT_UPPER ; 88/58 _____X_____ - .byte CT_UPPER ; 89/59 _____Y_____ - .byte CT_UPPER ; 90/5a _____Z_____ - .byte CT_NONE ; 91/5b _____[_____ - .byte CT_NONE ; 92/5c _____\_____ - .byte CT_NONE ; 93/5d _____]_____ - .byte CT_NONE ; 94/5e _____^_____ - .byte CT_NONE ; 95/5f _UNDERLINE_ - .byte CT_NONE ; 96/60 ___grave___ - .byte CT_LOWER | CT_XDIGIT ; 97/61 _____a_____ - .byte CT_LOWER | CT_XDIGIT ; 98/62 _____b_____ - .byte CT_LOWER | CT_XDIGIT ; 99/63 _____c_____ - .byte CT_LOWER | CT_XDIGIT ; 100/64 _____d_____ - .byte CT_LOWER | CT_XDIGIT ; 101/65 _____e_____ - .byte CT_LOWER | CT_XDIGIT ; 102/66 _____f_____ - .byte CT_LOWER ; 103/67 _____g_____ - .byte CT_LOWER ; 104/68 _____h_____ - .byte CT_LOWER ; 105/69 _____i_____ - .byte CT_LOWER ; 106/6a _____j_____ - .byte CT_LOWER ; 107/6b _____k_____ - .byte CT_LOWER ; 108/6c _____l_____ - .byte CT_LOWER ; 109/6d _____m_____ - .byte CT_LOWER ; 110/6e _____n_____ - .byte CT_LOWER ; 111/6f _____o_____ - .byte CT_LOWER ; 112/70 _____p_____ - .byte CT_LOWER ; 113/71 _____q_____ - .byte CT_LOWER ; 114/72 _____r_____ - .byte CT_LOWER ; 115/73 _____s_____ - .byte CT_LOWER ; 116/74 _____t_____ - .byte CT_LOWER ; 117/75 _____u_____ - .byte CT_LOWER ; 118/76 _____v_____ - .byte CT_LOWER ; 119/77 _____w_____ - .byte CT_LOWER ; 120/78 _____x_____ - .byte CT_LOWER ; 121/79 _____y_____ - .byte CT_LOWER ; 122/7a _____z_____ - .byte CT_NONE ; 123/7b _____{_____ - .byte CT_NONE ; 124/7c _____|_____ - .byte CT_NONE ; 125/7d _____}_____ - .byte CT_NONE ; 126/7e _____~_____ - .byte CT_OTHER_WS ; 127/7f ____DEL____ - .endrepeat - - + .include "ctype_console.inc" diff --git a/libsrc/geos-common/system/ctype.s b/libsrc/geos-common/system/ctype.s index cc0cc98b3..a50ad1635 100644 --- a/libsrc/geos-common/system/ctype.s +++ b/libsrc/geos-common/system/ctype.s @@ -1,281 +1,157 @@ +; ctype.s +; +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://github.com/cc65/cc65 +; +; See "LICENSE" file for legal information. +; +; GEOS character specification table. ; ; Source: The Hitchhiker's Guide To GEOS ; http://lyonlabs.org/commodore/onrequest/geos-manuals/The_Hitchhikers_Guide_to_GEOS.pdf -; -; Character specification table. -; - .include "ctype.inc" + .include "ctypetable.inc" + .export __ctypeIdx + +; The tables are readonly, put them into the rodata segment .rodata -; The following 256 byte wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it -; has major advantages: -; -; * It is fast. If it were'nt for the slow parameter passing of cc65, one -; could even define macros for the isxxx functions (this is usually -; done on other platforms). -; -; * It is highly portable. The only unportable part is the table itself, -; all real code goes into the common library. -; -; * We save some code in the isxxx functions. +__ctypeIdx: + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 0/00 ____NULL___, 1/01 ____N/A____ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 2/02 ____N/A____, 3/03 ____N/A____ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 4/04 ____N/A____, 5/05 ____N/A____ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 6/06 ____N/A____, 7/07 ____N/A____ + ct_mix CT_CTRL_IDX, CT_CTRL_WS_SPACETAB_IDX ; 8/08 __BAKSPACE_, 9/09 __FWDSPACE_ + ct_mix CT_CTRL_WS_IDX, CT_CTRL_IDX ; 10/0a _____LF____, 11/0b ____HOME___ + ct_mix CT_CTRL_IDX, CT_CTRL_WS_IDX ; 12/0c ___UPLINE__, 13/0d _____CR____ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 14/0e __ULINEON__, 15/0f __ULINEOFF_ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 16/10 _ESC_GRAPH_, 17/11 ____N/A____ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 18/12 ___REVON___, 19/13 ___REVOFF__ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 20/14 ___GOTOX___, 21/15 ___GOTOY___ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 22/16 ___GOTOXY__, 23/17 _NEWCRDSET_ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 24/18 ___BOLDON__, 25/19 __ITALICON_ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 26/1a _OUTLINEON_, 27/1b _PLAINTEXT_ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 28/1c ____N/A____, 29/1d ____N/A____ + ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 30/1e ____N/A____, 31/1f ____N/A____ -__ctype: - .byte CT_CTRL ; 0/00 ____NULL___ - .byte CT_CTRL ; 1/01 ____N/A____ - .byte CT_CTRL ; 2/02 ____N/A____ - .byte CT_CTRL ; 3/03 ____N/A____ - .byte CT_CTRL ; 4/04 ____N/A____ - .byte CT_CTRL ; 5/05 ____N/A____ - .byte CT_CTRL ; 6/06 ____N/A____ - .byte CT_CTRL ; 7/07 ____N/A____ - .byte CT_CTRL ; 8/08 __BAKSPACE_ - .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB ; 9/09 __FWDSPACE_ - .byte CT_CTRL | CT_OTHER_WS ; 10/0a _____LF____ - .byte CT_CTRL ; 11/0b ____HOME___ - .byte CT_CTRL ; 12/0c ___UPLINE__ - .byte CT_CTRL | CT_OTHER_WS ; 13/0d _____CR____ - .byte CT_CTRL ; 14/0e __ULINEON__ - .byte CT_CTRL ; 15/0f __ULINEOFF_ - .byte CT_CTRL ; 16/10 _ESC_GRAPH_ - .byte CT_CTRL ; 17/11 ____N/A____ - .byte CT_CTRL ; 18/12 ___REVON___ - .byte CT_CTRL ; 19/13 ___REVOFF__ - .byte CT_CTRL ; 20/14 ___GOTOX___ - .byte CT_CTRL ; 21/15 ___GOTOY___ - .byte CT_CTRL ; 22/16 ___GOTOXY__ - .byte CT_CTRL ; 23/17 _NEWCRDSET_ - .byte CT_CTRL ; 24/18 ___BOLDON__ - .byte CT_CTRL ; 25/19 __ITALICON_ - .byte CT_CTRL ; 26/1a _OUTLINEON_ - .byte CT_CTRL ; 27/1b _PLAINTEXT_ - .byte CT_CTRL ; 28/1c ____N/A____ - .byte CT_CTRL ; 29/1d ____N/A____ - .byte CT_CTRL ; 30/1e ____N/A____ - .byte CT_CTRL ; 31/1f ____N/A____ - .byte CT_SPACE_TAB | CT_SPACE ; 32/20 ___SPACE___ - .byte CT_NONE ; 33/21 _____!_____ - .byte CT_NONE ; 34/22 _____"_____ - .byte CT_NONE ; 35/23 _____#_____ - .byte CT_NONE ; 36/24 _____$_____ - .byte CT_NONE ; 37/25 _____%_____ - .byte CT_NONE ; 38/26 _____&_____ - .byte CT_NONE ; 39/27 _____'_____ - .byte CT_NONE ; 40/28 _____(_____ - .byte CT_NONE ; 41/29 _____)_____ - .byte CT_NONE ; 42/2a _____*_____ - .byte CT_NONE ; 43/2b _____+_____ - .byte CT_NONE ; 44/2c _____,_____ - .byte CT_NONE ; 45/2d _____-_____ - .byte CT_NONE ; 46/2e _____._____ - .byte CT_NONE ; 47/2f _____/_____ - .byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____ - .byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____ - .byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____ - .byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____ - .byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____ - .byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____ - .byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____ - .byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____ - .byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____ - .byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____ - .byte CT_NONE ; 58/3a _____:_____ - .byte CT_NONE ; 59/3b _____;_____ - .byte CT_NONE ; 60/3c _____<_____ - .byte CT_NONE ; 61/3d _____=_____ - .byte CT_NONE ; 62/3e _____>_____ - .byte CT_NONE ; 63/3f _____?_____ - .byte CT_NONE ; 64/40 _____@_____ - .byte CT_UPPER | CT_XDIGIT ; 65/41 _____A_____ - .byte CT_UPPER | CT_XDIGIT ; 66/42 _____B_____ - .byte CT_UPPER | CT_XDIGIT ; 67/43 _____C_____ - .byte CT_UPPER | CT_XDIGIT ; 68/44 _____D_____ - .byte CT_UPPER | CT_XDIGIT ; 69/45 _____E_____ - .byte CT_UPPER | CT_XDIGIT ; 70/46 _____F_____ - .byte CT_UPPER ; 71/47 _____G_____ - .byte CT_UPPER ; 72/48 _____H_____ - .byte CT_UPPER ; 73/49 _____I_____ - .byte CT_UPPER ; 74/4a _____J_____ - .byte CT_UPPER ; 75/4b _____K_____ - .byte CT_UPPER ; 76/4c _____L_____ - .byte CT_UPPER ; 77/4d _____M_____ - .byte CT_UPPER ; 78/4e _____N_____ - .byte CT_UPPER ; 79/4f _____O_____ - .byte CT_UPPER ; 80/50 _____P_____ - .byte CT_UPPER ; 81/51 _____Q_____ - .byte CT_UPPER ; 82/52 _____R_____ - .byte CT_UPPER ; 83/53 _____S_____ - .byte CT_UPPER ; 84/54 _____T_____ - .byte CT_UPPER ; 85/55 _____U_____ - .byte CT_UPPER ; 86/56 _____V_____ - .byte CT_UPPER ; 87/57 _____W_____ - .byte CT_UPPER ; 88/58 _____X_____ - .byte CT_UPPER ; 89/59 _____Y_____ - .byte CT_UPPER ; 90/5a _____Z_____ - .byte CT_NONE ; 91/5b _____[_____ - .byte CT_NONE ; 92/5c _____\_____ - .byte CT_NONE ; 93/5d _____]_____ - .byte CT_NONE ; 94/5e _____^_____ - .byte CT_NONE ; 95/5f _UNDERLINE_ - .byte CT_NONE ; 96/60 _____`_____ - .byte CT_LOWER | CT_XDIGIT ; 97/61 _____a_____ - .byte CT_LOWER | CT_XDIGIT ; 98/62 _____b_____ - .byte CT_LOWER | CT_XDIGIT ; 99/63 _____c_____ - .byte CT_LOWER | CT_XDIGIT ; 100/64 _____d_____ - .byte CT_LOWER | CT_XDIGIT ; 101/65 _____e_____ - .byte CT_LOWER | CT_XDIGIT ; 102/66 _____f_____ - .byte CT_LOWER ; 103/67 _____g_____ - .byte CT_LOWER ; 104/68 _____h_____ - .byte CT_LOWER ; 105/69 _____i_____ - .byte CT_LOWER ; 106/6a _____j_____ - .byte CT_LOWER ; 107/6b _____k_____ - .byte CT_LOWER ; 108/6c _____l_____ - .byte CT_LOWER ; 109/6d _____m_____ - .byte CT_LOWER ; 110/6e _____n_____ - .byte CT_LOWER ; 111/6f _____o_____ - .byte CT_LOWER ; 112/70 _____p_____ - .byte CT_LOWER ; 113/71 _____q_____ - .byte CT_LOWER ; 114/72 _____r_____ - .byte CT_LOWER ; 115/73 _____s_____ - .byte CT_LOWER ; 116/74 _____t_____ - .byte CT_LOWER ; 117/75 _____u_____ - .byte CT_LOWER ; 118/76 _____v_____ - .byte CT_LOWER ; 119/77 _____w_____ - .byte CT_LOWER ; 120/78 _____x_____ - .byte CT_LOWER ; 121/79 _____y_____ - .byte CT_LOWER ; 122/7a _____z_____ - .byte CT_NONE ; 123/7b _____{_____ - .byte CT_NONE ; 124/7c _____|_____ - .byte CT_NONE ; 125/7d _____}_____ - .byte CT_NONE ; 126/7e _____~_____ - .byte CT_CTRL ; 127/7f __USELAST__ - .byte CT_NONE ; 128/80 __SHORTCUT_ - .byte CT_NONE ; 129/81 ____N/A____ - .byte CT_NONE ; 130/82 ____N/A____ - .byte CT_NONE ; 131/83 ____N/A____ - .byte CT_NONE ; 132/84 ____N/A____ - .byte CT_NONE ; 133/85 ____N/A____ - .byte CT_NONE ; 134/86 ____N/A____ - .byte CT_NONE ; 135/87 ____N/A____ - .byte CT_NONE ; 136/88 ____N/A____ - .byte CT_NONE ; 137/89 ____N/A____ - .byte CT_NONE ; 138/8a ____N/A____ - .byte CT_NONE ; 139/8b ____N/A____ - .byte CT_NONE ; 140/8c ____N/A____ - .byte CT_NONE ; 141/8d ____N/A____ - .byte CT_NONE ; 142/8e ____N/A____ - .byte CT_NONE ; 143/8f ____N/A____ - .byte CT_NONE ; 144/90 ____N/A____ - .byte CT_NONE ; 145/91 ____N/A____ - .byte CT_NONE ; 146/92 ____N/A____ - .byte CT_NONE ; 147/93 ____N/A____ - .byte CT_NONE ; 148/94 ____N/A____ - .byte CT_NONE ; 149/95 ____N/A____ - .byte CT_NONE ; 150/96 ____N/A____ - .byte CT_NONE ; 151/97 ____N/A____ - .byte CT_NONE ; 152/98 ____N/A____ - .byte CT_NONE ; 153/99 ____N/A____ - .byte CT_NONE ; 154/9a ____N/A____ - .byte CT_NONE ; 155/9b ____N/A____ - .byte CT_NONE ; 156/9c ____N/A____ - .byte CT_NONE ; 157/9d ____N/A____ - .byte CT_NONE ; 158/9e ____N/A____ - .byte CT_NONE ; 159/9f ____N/A____ - .byte CT_NONE ; 160/a0 ____N/A____ - .byte CT_NONE ; 161/a1 ____N/A____ - .byte CT_NONE ; 162/a2 ____N/A____ - .byte CT_NONE ; 163/a3 ____N/A____ - .byte CT_NONE ; 164/a4 ____N/A____ - .byte CT_NONE ; 165/a5 ____N/A____ - .byte CT_NONE ; 166/a6 ____N/A____ - .byte CT_NONE ; 167/a7 ____N/A____ - .byte CT_NONE ; 168/a8 ____N/A____ - .byte CT_NONE ; 169/a9 ____N/A____ - .byte CT_NONE ; 170/aa ____N/A____ - .byte CT_NONE ; 171/ab ____N/A____ - .byte CT_NONE ; 172/ac ____N/A____ - .byte CT_NONE ; 173/ad ____N/A____ - .byte CT_NONE ; 174/ae ____N/A____ - .byte CT_NONE ; 175/af ____N/A____ - .byte CT_NONE ; 176/b0 ____N/A____ - .byte CT_NONE ; 177/b1 ____N/A____ - .byte CT_NONE ; 178/b2 ____N/A____ - .byte CT_NONE ; 179/b3 ____N/A____ - .byte CT_NONE ; 180/b4 ____N/A____ - .byte CT_NONE ; 181/b5 ____N/A____ - .byte CT_NONE ; 182/b6 ____N/A____ - .byte CT_NONE ; 183/b7 ____N/A____ - .byte CT_NONE ; 184/b8 ____N/A____ - .byte CT_NONE ; 185/b9 ____N/A____ - .byte CT_NONE ; 186/ba ____N/A____ - .byte CT_NONE ; 187/bb ____N/A____ - .byte CT_NONE ; 188/bc ____N/A____ - .byte CT_NONE ; 189/bd ____N/A____ - .byte CT_NONE ; 190/be ____N/A____ - .byte CT_NONE ; 191/bf ____N/A____ - .byte CT_NONE ; 192/c0 ____N/A____ - .byte CT_NONE ; 193/c1 ____N/A____ - .byte CT_NONE ; 194/c2 ____N/A____ - .byte CT_NONE ; 195/c3 ____N/A____ - .byte CT_NONE ; 196/c4 ____N/A____ - .byte CT_NONE ; 197/c5 ____N/A____ - .byte CT_NONE ; 198/c6 ____N/A____ - .byte CT_NONE ; 199/c7 ____N/A____ - .byte CT_NONE ; 200/c8 ____N/A____ - .byte CT_NONE ; 201/c9 ____N/A____ - .byte CT_NONE ; 202/ca ____N/A____ - .byte CT_NONE ; 203/cb ____N/A____ - .byte CT_NONE ; 204/cc ____N/A____ - .byte CT_NONE ; 205/cd ____N/A____ - .byte CT_NONE ; 206/ce ____N/A____ - .byte CT_NONE ; 207/cf ____N/A____ - .byte CT_NONE ; 208/d0 ____N/A____ - .byte CT_NONE ; 209/d1 ____N/A____ - .byte CT_NONE ; 210/d2 ____N/A____ - .byte CT_NONE ; 211/d3 ____N/A____ - .byte CT_NONE ; 212/d4 ____N/A____ - .byte CT_NONE ; 213/d5 ____N/A____ - .byte CT_NONE ; 214/d6 ____N/A____ - .byte CT_NONE ; 215/d7 ____N/A____ - .byte CT_NONE ; 216/d8 ____N/A____ - .byte CT_NONE ; 217/d9 ____N/A____ - .byte CT_NONE ; 218/da ____N/A____ - .byte CT_NONE ; 219/db ____N/A____ - .byte CT_NONE ; 220/dc ____N/A____ - .byte CT_NONE ; 221/dd ____N/A____ - .byte CT_NONE ; 222/de ____N/A____ - .byte CT_NONE ; 223/df ____N/A____ - .byte CT_NONE ; 224/e0 ____N/A____ - .byte CT_NONE ; 225/e1 ____N/A____ - .byte CT_NONE ; 226/e2 ____N/A____ - .byte CT_NONE ; 227/e3 ____N/A____ - .byte CT_NONE ; 228/e4 ____N/A____ - .byte CT_NONE ; 229/e5 ____N/A____ - .byte CT_NONE ; 230/e6 ____N/A____ - .byte CT_NONE ; 231/e7 ____N/A____ - .byte CT_NONE ; 232/e8 ____N/A____ - .byte CT_NONE ; 233/e9 ____N/A____ - .byte CT_NONE ; 234/ea ____N/A____ - .byte CT_NONE ; 235/eb ____N/A____ - .byte CT_NONE ; 236/ec ____N/A____ - .byte CT_NONE ; 237/ed ____N/A____ - .byte CT_NONE ; 238/ee ____N/A____ - .byte CT_NONE ; 239/ef ____N/A____ - .byte CT_NONE ; 240/f0 ____N/A____ - .byte CT_NONE ; 241/f1 ____N/A____ - .byte CT_NONE ; 242/f2 ____N/A____ - .byte CT_NONE ; 243/f3 ____N/A____ - .byte CT_NONE ; 244/f4 ____N/A____ - .byte CT_NONE ; 245/f5 ____N/A____ - .byte CT_NONE ; 246/f6 ____N/A____ - .byte CT_NONE ; 247/f7 ____N/A____ - .byte CT_NONE ; 248/f8 ____N/A____ - .byte CT_NONE ; 249/f9 ____N/A____ - .byte CT_NONE ; 250/fa ____N/A____ - .byte CT_NONE ; 251/fb ____N/A____ - .byte CT_NONE ; 252/fc ____N/A____ - .byte CT_NONE ; 253/fd ____N/A____ - .byte CT_NONE ; 254/fe ____N/A____ - .byte CT_NONE ; 255/ff ____N/A____ + ct_mix CT_SPACE_SPACETAB_IDX, CT_NONE_IDX ; 32/20 ___SPACE___, 33/21 _____!_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 34/22 _____"_____, 35/23 _____#_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 36/24 _____$_____, 37/25 _____%_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 38/26 _____&_____, 39/27 _____'_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 40/28 _____(_____, 41/29 _____)_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 42/2a _____*_____, 43/2b _____+_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 44/2c _____,_____, 45/2d _____-_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 46/2e _____._____, 47/2f _____/_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 48/30 _____0_____, 49/31 _____1_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 50/32 _____2_____, 51/33 _____3_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 52/34 _____4_____, 53/35 _____5_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 54/36 _____6_____, 55/37 _____7_____ + ct_mix CT_DIGIT_XDIGIT_IDX, CT_DIGIT_XDIGIT_IDX ; 56/38 _____8_____, 57/39 _____9_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 58/3a _____:_____, 59/3b _____;_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 60/3c _____<_____, 61/3d _____=_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 62/3e _____>_____, 63/3f _____?_____ + + ct_mix CT_NONE_IDX, CT_UPPER_XDIGIT_IDX ; 64/40 _____@_____, 65/41 _____A_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_XDIGIT_IDX ; 66/42 _____B_____, 67/43 _____C_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_XDIGIT_IDX ; 68/44 _____D_____, 69/45 _____E_____ + ct_mix CT_UPPER_XDIGIT_IDX, CT_UPPER_IDX ; 70/46 _____F_____, 71/47 _____G_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 72/48 _____H_____, 73/49 _____I_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 74/4a _____J_____, 75/4b _____K_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 76/4c _____L_____, 77/4d _____M_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 78/4e _____N_____, 79/4f _____O_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 80/50 _____P_____, 81/51 _____Q_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 82/52 _____R_____, 83/53 _____S_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 84/54 _____T_____, 85/55 _____U_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 86/56 _____V_____, 87/57 _____W_____ + ct_mix CT_UPPER_IDX, CT_UPPER_IDX ; 88/58 _____X_____, 89/59 _____Y_____ + ct_mix CT_UPPER_IDX, CT_NONE_IDX ; 90/5a _____Z_____, 91/5b _____[_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 92/5c _____\_____, 93/5d _____]_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 94/5e _____^_____, 95/5f _UNDERLINE_ + + ct_mix CT_NONE_IDX, CT_LOWER_XDIGIT_IDX ; 96/60 _____`_____, 97/61 _____a_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_XDIGIT_IDX ; 98/62 _____b_____, 99/63 _____c_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_XDIGIT_IDX ; 100/64 _____d_____, 101/65 _____e_____ + ct_mix CT_LOWER_XDIGIT_IDX, CT_LOWER_IDX ; 102/66 _____f_____, 103/67 _____g_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 104/68 _____h_____, 105/69 _____i_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 106/6a _____j_____, 107/6b _____k_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 108/6c _____l_____, 109/6d _____m_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 110/6e _____n_____, 111/6f _____o_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 112/70 _____p_____, 113/71 _____q_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 114/72 _____r_____, 15/73 _____s_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 116/74 _____t_____, 117/75 _____u_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 118/76 _____v_____, 119/77 _____w_____ + ct_mix CT_LOWER_IDX, CT_LOWER_IDX ; 120/78 _____x_____, 121/79 _____y_____ + ct_mix CT_LOWER_IDX, CT_NONE_IDX ; 122/7a _____z_____, 123/7b _____{_____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 124/7c _____|_____, 125/7d _____}_____ + ct_mix CT_NONE_IDX, CT_CTRL_IDX ; 126/7e _____~_____, 127/7f __USELAST__ + + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 128/80 __SHORTCUT_ ,129/81 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 130/82 ____N/A____ ,131/83 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 132/84 ____N/A____ ,133/85 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 134/86 ____N/A____, 135/87 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 136/88 ____N/A____ ,137/89 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 138/8a ____N/A____ ,139/8b ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 140/8c ____N/A____, 141/8d ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 142/8e ____N/A____, 143/8f ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 144/90 ____N/A____, 145/91 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 146/92 ____N/A____, 147/93 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 148/94 ____N/A____, 149/95 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 150/96 ____N/A____, 151/97 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 152/98 ____N/A____, 153/99 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 154/9a ____N/A____, 155/9b ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 156/9c ____N/A____, 157/9d ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 158/9e ____N/A____, 159/9f ____N/A____ + + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 160/a0 ____N/A____, 161/a1 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 162/a2 ____N/A____, 163/a3 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 164/a4 ____N/A____, 165/a5 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 166/a6 ____N/A____, 167/a7 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 168/a8 ____N/A____, 169/a9 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 170/aa ____N/A____, 171/ab ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 172/ac ____N/A____, 173/ad ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 174/ae ____N/A____, 175/af ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 176/b0 ____N/A____, 177/b1 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 178/b2 ____N/A____, 179/b3 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 180/b4 ____N/A____, 181/b5 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 182/b6 ____N/A____, 183/b7 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 184/b8 ____N/A____, 185/b9 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 186/ba ____N/A____, 187/bb ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 188/bc ____N/A____, 189/bd ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 190/be ____N/A____, 191/bf ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 192/c0 ____N/A____, 193/c1 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 194/c2 ____N/A____, 195/c3 ____N/A____ + + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 196/c4 ____N/A____, 197/c5 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 198/c6 ____N/A____, 199/c7 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 200/c8 ____N/A____, 201/c9 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 202/ca ____N/A____, 203/cb ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 204/cc ____N/A____, 205/cd ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 206/ce ____N/A____, 207/cf ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 208/d0 ____N/A____, 209/d1 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 210/d2 ____N/A____, 211/d3 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 212/d4 ____N/A____, 213/d5 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 214/d6 ____N/A____, 215/d7 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 216/d8 ____N/A____, 217/d9 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 218/da ____N/A____, 219/db ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 220/dc ____N/A____, 221/dd ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 222/de ____N/A____, 223/df ____N/A____ + + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 224/e0 ____N/A____, 225/e1 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 226/e2 ____N/A____, 227/e3 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 228/e4 ____N/A____, 229/e5 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 230/e6 ____N/A____, 231/e7 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 232/e8 ____N/A____, 233/e9 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 234/ea ____N/A____, 235/eb ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 236/ec ____N/A____, 237/ed ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 238/ee ____N/A____, 239/ef ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 240/f0 ____N/A____, 241/f1 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 242/f2 ____N/A____, 243/f3 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 244/f4 ____N/A____, 245/f5 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 246/f6 ____N/A____, 247/f7 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 248/f8 ____N/A____, 249/f9 ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 250/fa ____N/A____, 251/fb ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 252/fc ____N/A____, 253/fd ____N/A____ + ct_mix CT_NONE_IDX, CT_NONE_IDX ; 254/fe ____N/A____, 255/ff ____N/A____ diff --git a/libsrc/lynx/ctype.s b/libsrc/lynx/ctype.s index 6e0ab1785..da4d38472 100644 --- a/libsrc/lynx/ctype.s +++ b/libsrc/lynx/ctype.s @@ -1,172 +1,5 @@ -; -; Ullrich von Bassewitz, 02.06.1998 -; ; Character specification table. ; +; uses the "console" definition -; The tables are readonly, put them into the rodata segment - -.rodata - -; The following 256 byte wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it -; has major advantages: -; -; * It is fast. If it were'nt for the slow parameter passing of cc65, one -; could even define macros for the isxxx functions (this is usually -; done on other platforms). -; -; * It is highly portable. The only unportable part is the table itself, -; all real code goes into the common library. -; -; * We save some code in the isxxx functions. -; -; -; Bit assignments: -; -; 0 - Lower case char -; 1 - Upper case char -; 2 - Numeric digit -; 3 - Hex digit (both, lower and upper) -; 4 - Control character -; 5 - The space character itself -; 6 - Other whitespace (that is: '\f', '\n', '\r', '\t' and '\v') -; 7 - Space or tab character - - .export __ctype - -__ctype: - -.repeat 2 ; 2 times for normal and inverted - - .byte $10 ; 0/00 ___ctrl_@___ - .byte $10 ; 1/01 ___ctrl_A___ - .byte $10 ; 2/02 ___ctrl_B___ - .byte $10 ; 3/03 ___ctrl_C___ - .byte $10 ; 4/04 ___ctrl_D___ - .byte $10 ; 5/05 ___ctrl_E___ - .byte $10 ; 6/06 ___ctrl_F___ - .byte $10 ; 7/07 ___ctrl_G___ - .byte $10 ; 8/08 ___ctrl_H___ - .byte $D0 ; 9/09 ___ctrl_I___ - .byte $50 ; 10/0a ___ctrl_J___ - .byte $50 ; 11/0b ___ctrl_K___ - .byte $50 ; 12/0c ___ctrl_L___ - .byte $50 ; 13/0d ___ctrl_M___ - .byte $10 ; 14/0e ___ctrl_N___ - .byte $10 ; 15/0f ___ctrl_O___ - .byte $10 ; 16/10 ___ctrl_P___ - .byte $10 ; 17/11 ___ctrl_Q___ - .byte $10 ; 18/12 ___ctrl_R___ - .byte $10 ; 19/13 ___ctrl_S___ - .byte $10 ; 20/14 ___ctrl_T___ - .byte $10 ; 21/15 ___ctrl_U___ - .byte $10 ; 22/16 ___ctrl_V___ - .byte $10 ; 23/17 ___ctrl_W___ - .byte $10 ; 24/18 ___ctrl_X___ - .byte $10 ; 25/19 ___ctrl_Y___ - .byte $10 ; 26/1a ___ctrl_Z___ - .byte $10 ; 27/1b ___ctrl_[___ - .byte $10 ; 28/1c ___ctrl_\___ - .byte $10 ; 29/1d ___ctrl_]___ - .byte $10 ; 30/1e ___ctrl_^___ - .byte $10 ; 31/1f ___ctrl_____ - .byte $A0 ; 32/20 ___SPACE___ - .byte $00 ; 33/21 _____!_____ - .byte $00 ; 34/22 _____"_____ - .byte $00 ; 35/23 _____#_____ - .byte $00 ; 36/24 _____$_____ - .byte $00 ; 37/25 _____%_____ - .byte $00 ; 38/26 _____&_____ - .byte $00 ; 39/27 _____'_____ - .byte $00 ; 40/28 _____(_____ - .byte $00 ; 41/29 _____)_____ - .byte $00 ; 42/2a _____*_____ - .byte $00 ; 43/2b _____+_____ - .byte $00 ; 44/2c _____,_____ - .byte $00 ; 45/2d _____-_____ - .byte $00 ; 46/2e _____._____ - .byte $00 ; 47/2f _____/_____ - .byte $0C ; 48/30 _____0_____ - .byte $0C ; 49/31 _____1_____ - .byte $0C ; 50/32 _____2_____ - .byte $0C ; 51/33 _____3_____ - .byte $0C ; 52/34 _____4_____ - .byte $0C ; 53/35 _____5_____ - .byte $0C ; 54/36 _____6_____ - .byte $0C ; 55/37 _____7_____ - .byte $0C ; 56/38 _____8_____ - .byte $0C ; 57/39 _____9_____ - .byte $00 ; 58/3a _____:_____ - .byte $00 ; 59/3b _____;_____ - .byte $00 ; 60/3c _____<_____ - .byte $00 ; 61/3d _____=_____ - .byte $00 ; 62/3e _____>_____ - .byte $00 ; 63/3f _____?_____ - - .byte $00 ; 64/40 _____@_____ - .byte $0A ; 65/41 _____A_____ - .byte $0A ; 66/42 _____B_____ - .byte $0A ; 67/43 _____C_____ - .byte $0A ; 68/44 _____D_____ - .byte $0A ; 69/45 _____E_____ - .byte $0A ; 70/46 _____F_____ - .byte $02 ; 71/47 _____G_____ - .byte $02 ; 72/48 _____H_____ - .byte $02 ; 73/49 _____I_____ - .byte $02 ; 74/4a _____J_____ - .byte $02 ; 75/4b _____K_____ - .byte $02 ; 76/4c _____L_____ - .byte $02 ; 77/4d _____M_____ - .byte $02 ; 78/4e _____N_____ - .byte $02 ; 79/4f _____O_____ - .byte $02 ; 80/50 _____P_____ - .byte $02 ; 81/51 _____Q_____ - .byte $02 ; 82/52 _____R_____ - .byte $02 ; 83/53 _____S_____ - .byte $02 ; 84/54 _____T_____ - .byte $02 ; 85/55 _____U_____ - .byte $02 ; 86/56 _____V_____ - .byte $02 ; 87/57 _____W_____ - .byte $02 ; 88/58 _____X_____ - .byte $02 ; 89/59 _____Y_____ - .byte $02 ; 90/5a _____Z_____ - .byte $00 ; 91/5b _____[_____ - .byte $00 ; 92/5c _____\_____ - .byte $00 ; 93/5d _____]_____ - .byte $00 ; 94/5e _____^_____ - .byte $00 ; 95/5f _UNDERLINE_ - .byte $00 ; 96/60 ___grave___ - .byte $09 ; 97/61 _____a_____ - .byte $09 ; 98/62 _____b_____ - .byte $09 ; 99/63 _____c_____ - .byte $09 ; 100/64 _____d_____ - .byte $09 ; 101/65 _____e_____ - .byte $09 ; 102/66 _____f_____ - .byte $01 ; 103/67 _____g_____ - .byte $01 ; 104/68 _____h_____ - .byte $01 ; 105/69 _____i_____ - .byte $01 ; 106/6a _____j_____ - .byte $01 ; 107/6b _____k_____ - .byte $01 ; 108/6c _____l_____ - .byte $01 ; 109/6d _____m_____ - .byte $01 ; 110/6e _____n_____ - .byte $01 ; 111/6f _____o_____ - .byte $01 ; 112/70 _____p_____ - .byte $01 ; 113/71 _____q_____ - .byte $01 ; 114/72 _____r_____ - .byte $01 ; 115/73 _____s_____ - .byte $01 ; 116/74 _____t_____ - .byte $01 ; 117/75 _____u_____ - .byte $01 ; 118/76 _____v_____ - .byte $01 ; 119/77 _____w_____ - .byte $01 ; 120/78 _____x_____ - .byte $01 ; 121/79 _____y_____ - .byte $01 ; 122/7a _____z_____ - .byte $00 ; 123/7b _____{_____ - .byte $00 ; 124/7c _____|_____ - .byte $00 ; 125/7d _____}_____ - .byte $00 ; 126/7e _____~_____ - .byte $40 ; 127/7f ____DEL____ - -.endrepeat + .include "ctype_console.inc" diff --git a/libsrc/nes/ctype.s b/libsrc/nes/ctype.s index 6e0ab1785..da4d38472 100644 --- a/libsrc/nes/ctype.s +++ b/libsrc/nes/ctype.s @@ -1,172 +1,5 @@ -; -; Ullrich von Bassewitz, 02.06.1998 -; ; Character specification table. ; +; uses the "console" definition -; The tables are readonly, put them into the rodata segment - -.rodata - -; The following 256 byte wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it -; has major advantages: -; -; * It is fast. If it were'nt for the slow parameter passing of cc65, one -; could even define macros for the isxxx functions (this is usually -; done on other platforms). -; -; * It is highly portable. The only unportable part is the table itself, -; all real code goes into the common library. -; -; * We save some code in the isxxx functions. -; -; -; Bit assignments: -; -; 0 - Lower case char -; 1 - Upper case char -; 2 - Numeric digit -; 3 - Hex digit (both, lower and upper) -; 4 - Control character -; 5 - The space character itself -; 6 - Other whitespace (that is: '\f', '\n', '\r', '\t' and '\v') -; 7 - Space or tab character - - .export __ctype - -__ctype: - -.repeat 2 ; 2 times for normal and inverted - - .byte $10 ; 0/00 ___ctrl_@___ - .byte $10 ; 1/01 ___ctrl_A___ - .byte $10 ; 2/02 ___ctrl_B___ - .byte $10 ; 3/03 ___ctrl_C___ - .byte $10 ; 4/04 ___ctrl_D___ - .byte $10 ; 5/05 ___ctrl_E___ - .byte $10 ; 6/06 ___ctrl_F___ - .byte $10 ; 7/07 ___ctrl_G___ - .byte $10 ; 8/08 ___ctrl_H___ - .byte $D0 ; 9/09 ___ctrl_I___ - .byte $50 ; 10/0a ___ctrl_J___ - .byte $50 ; 11/0b ___ctrl_K___ - .byte $50 ; 12/0c ___ctrl_L___ - .byte $50 ; 13/0d ___ctrl_M___ - .byte $10 ; 14/0e ___ctrl_N___ - .byte $10 ; 15/0f ___ctrl_O___ - .byte $10 ; 16/10 ___ctrl_P___ - .byte $10 ; 17/11 ___ctrl_Q___ - .byte $10 ; 18/12 ___ctrl_R___ - .byte $10 ; 19/13 ___ctrl_S___ - .byte $10 ; 20/14 ___ctrl_T___ - .byte $10 ; 21/15 ___ctrl_U___ - .byte $10 ; 22/16 ___ctrl_V___ - .byte $10 ; 23/17 ___ctrl_W___ - .byte $10 ; 24/18 ___ctrl_X___ - .byte $10 ; 25/19 ___ctrl_Y___ - .byte $10 ; 26/1a ___ctrl_Z___ - .byte $10 ; 27/1b ___ctrl_[___ - .byte $10 ; 28/1c ___ctrl_\___ - .byte $10 ; 29/1d ___ctrl_]___ - .byte $10 ; 30/1e ___ctrl_^___ - .byte $10 ; 31/1f ___ctrl_____ - .byte $A0 ; 32/20 ___SPACE___ - .byte $00 ; 33/21 _____!_____ - .byte $00 ; 34/22 _____"_____ - .byte $00 ; 35/23 _____#_____ - .byte $00 ; 36/24 _____$_____ - .byte $00 ; 37/25 _____%_____ - .byte $00 ; 38/26 _____&_____ - .byte $00 ; 39/27 _____'_____ - .byte $00 ; 40/28 _____(_____ - .byte $00 ; 41/29 _____)_____ - .byte $00 ; 42/2a _____*_____ - .byte $00 ; 43/2b _____+_____ - .byte $00 ; 44/2c _____,_____ - .byte $00 ; 45/2d _____-_____ - .byte $00 ; 46/2e _____._____ - .byte $00 ; 47/2f _____/_____ - .byte $0C ; 48/30 _____0_____ - .byte $0C ; 49/31 _____1_____ - .byte $0C ; 50/32 _____2_____ - .byte $0C ; 51/33 _____3_____ - .byte $0C ; 52/34 _____4_____ - .byte $0C ; 53/35 _____5_____ - .byte $0C ; 54/36 _____6_____ - .byte $0C ; 55/37 _____7_____ - .byte $0C ; 56/38 _____8_____ - .byte $0C ; 57/39 _____9_____ - .byte $00 ; 58/3a _____:_____ - .byte $00 ; 59/3b _____;_____ - .byte $00 ; 60/3c _____<_____ - .byte $00 ; 61/3d _____=_____ - .byte $00 ; 62/3e _____>_____ - .byte $00 ; 63/3f _____?_____ - - .byte $00 ; 64/40 _____@_____ - .byte $0A ; 65/41 _____A_____ - .byte $0A ; 66/42 _____B_____ - .byte $0A ; 67/43 _____C_____ - .byte $0A ; 68/44 _____D_____ - .byte $0A ; 69/45 _____E_____ - .byte $0A ; 70/46 _____F_____ - .byte $02 ; 71/47 _____G_____ - .byte $02 ; 72/48 _____H_____ - .byte $02 ; 73/49 _____I_____ - .byte $02 ; 74/4a _____J_____ - .byte $02 ; 75/4b _____K_____ - .byte $02 ; 76/4c _____L_____ - .byte $02 ; 77/4d _____M_____ - .byte $02 ; 78/4e _____N_____ - .byte $02 ; 79/4f _____O_____ - .byte $02 ; 80/50 _____P_____ - .byte $02 ; 81/51 _____Q_____ - .byte $02 ; 82/52 _____R_____ - .byte $02 ; 83/53 _____S_____ - .byte $02 ; 84/54 _____T_____ - .byte $02 ; 85/55 _____U_____ - .byte $02 ; 86/56 _____V_____ - .byte $02 ; 87/57 _____W_____ - .byte $02 ; 88/58 _____X_____ - .byte $02 ; 89/59 _____Y_____ - .byte $02 ; 90/5a _____Z_____ - .byte $00 ; 91/5b _____[_____ - .byte $00 ; 92/5c _____\_____ - .byte $00 ; 93/5d _____]_____ - .byte $00 ; 94/5e _____^_____ - .byte $00 ; 95/5f _UNDERLINE_ - .byte $00 ; 96/60 ___grave___ - .byte $09 ; 97/61 _____a_____ - .byte $09 ; 98/62 _____b_____ - .byte $09 ; 99/63 _____c_____ - .byte $09 ; 100/64 _____d_____ - .byte $09 ; 101/65 _____e_____ - .byte $09 ; 102/66 _____f_____ - .byte $01 ; 103/67 _____g_____ - .byte $01 ; 104/68 _____h_____ - .byte $01 ; 105/69 _____i_____ - .byte $01 ; 106/6a _____j_____ - .byte $01 ; 107/6b _____k_____ - .byte $01 ; 108/6c _____l_____ - .byte $01 ; 109/6d _____m_____ - .byte $01 ; 110/6e _____n_____ - .byte $01 ; 111/6f _____o_____ - .byte $01 ; 112/70 _____p_____ - .byte $01 ; 113/71 _____q_____ - .byte $01 ; 114/72 _____r_____ - .byte $01 ; 115/73 _____s_____ - .byte $01 ; 116/74 _____t_____ - .byte $01 ; 117/75 _____u_____ - .byte $01 ; 118/76 _____v_____ - .byte $01 ; 119/77 _____w_____ - .byte $01 ; 120/78 _____x_____ - .byte $01 ; 121/79 _____y_____ - .byte $01 ; 122/7a _____z_____ - .byte $00 ; 123/7b _____{_____ - .byte $00 ; 124/7c _____|_____ - .byte $00 ; 125/7d _____}_____ - .byte $00 ; 126/7e _____~_____ - .byte $40 ; 127/7f ____DEL____ - -.endrepeat + .include "ctype_console.inc" diff --git a/libsrc/none/ctype.s b/libsrc/none/ctype.s index 35968f982..1301965eb 100644 --- a/libsrc/none/ctype.s +++ b/libsrc/none/ctype.s @@ -1,159 +1,5 @@ -; -; Ullrich von Bassewitz, 2003-10-10 -; ; Character specification table. ; +; uses the "common" definition - .include "ctype.inc" - -; The tables are readonly, put them into the rodata segment - -.rodata - -; The following 256 byte wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it -; has major advantages: -; -; * It is fast. If it weren't for the slow parameter passing of cc65, one -; could even define macros for the isxxx functions (this is usually -; done on other platforms). -; -; * It is highly portable. The only unportable part is the table itself, -; all real code goes into the common library. -; -; * We save some code in the isxxx functions. - - -__ctype: - .byte CT_CTRL ; 0/00 ___ctrl_@___ - .byte CT_CTRL ; 1/01 ___ctrl_A___ - .byte CT_CTRL ; 2/02 ___ctrl_B___ - .byte CT_CTRL ; 3/03 ___ctrl_C___ - .byte CT_CTRL ; 4/04 ___ctrl_D___ - .byte CT_CTRL ; 5/05 ___ctrl_E___ - .byte CT_CTRL ; 6/06 ___ctrl_F___ - .byte CT_CTRL ; 7/07 ___ctrl_G___ - .byte CT_CTRL ; 8/08 ___ctrl_H___ - .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB - ; 9/09 ___ctrl_I___ - .byte CT_CTRL | CT_OTHER_WS ; 10/0a ___ctrl_J___ - .byte CT_CTRL | CT_OTHER_WS ; 11/0b ___ctrl_K___ - .byte CT_CTRL | CT_OTHER_WS ; 12/0c ___ctrl_L___ - .byte CT_CTRL | CT_OTHER_WS ; 13/0d ___ctrl_M___ - .byte CT_CTRL ; 14/0e ___ctrl_N___ - .byte CT_CTRL ; 15/0f ___ctrl_O___ - .byte CT_CTRL ; 16/10 ___ctrl_P___ - .byte CT_CTRL ; 17/11 ___ctrl_Q___ - .byte CT_CTRL ; 18/12 ___ctrl_R___ - .byte CT_CTRL ; 19/13 ___ctrl_S___ - .byte CT_CTRL ; 20/14 ___ctrl_T___ - .byte CT_CTRL ; 21/15 ___ctrl_U___ - .byte CT_CTRL ; 22/16 ___ctrl_V___ - .byte CT_CTRL ; 23/17 ___ctrl_W___ - .byte CT_CTRL ; 24/18 ___ctrl_X___ - .byte CT_CTRL ; 25/19 ___ctrl_Y___ - .byte CT_CTRL ; 26/1a ___ctrl_Z___ - .byte CT_CTRL ; 27/1b ___ctrl_[___ - .byte CT_CTRL ; 28/1c ___ctrl_\___ - .byte CT_CTRL ; 29/1d ___ctrl_]___ - .byte CT_CTRL ; 30/1e ___ctrl_^___ - .byte CT_CTRL ; 31/1f ___ctrl_____ - .byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___ - .byte CT_NONE ; 33/21 _____!_____ - .byte CT_NONE ; 34/22 _____"_____ - .byte CT_NONE ; 35/23 _____#_____ - .byte CT_NONE ; 36/24 _____$_____ - .byte CT_NONE ; 37/25 _____%_____ - .byte CT_NONE ; 38/26 _____&_____ - .byte CT_NONE ; 39/27 _____'_____ - .byte CT_NONE ; 40/28 _____(_____ - .byte CT_NONE ; 41/29 _____)_____ - .byte CT_NONE ; 42/2a _____*_____ - .byte CT_NONE ; 43/2b _____+_____ - .byte CT_NONE ; 44/2c _____,_____ - .byte CT_NONE ; 45/2d _____-_____ - .byte CT_NONE ; 46/2e _____._____ - .byte CT_NONE ; 47/2f _____/_____ - .byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____ - .byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____ - .byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____ - .byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____ - .byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____ - .byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____ - .byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____ - .byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____ - .byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____ - .byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____ - .byte CT_NONE ; 58/3a _____:_____ - .byte CT_NONE ; 59/3b _____;_____ - .byte CT_NONE ; 60/3c _____<_____ - .byte CT_NONE ; 61/3d _____=_____ - .byte CT_NONE ; 62/3e _____>_____ - .byte CT_NONE ; 63/3f _____?_____ - - .byte CT_NONE ; 64/40 _____@_____ - .byte CT_UPPER | CT_XDIGIT ; 65/41 _____A_____ - .byte CT_UPPER | CT_XDIGIT ; 66/42 _____B_____ - .byte CT_UPPER | CT_XDIGIT ; 67/43 _____C_____ - .byte CT_UPPER | CT_XDIGIT ; 68/44 _____D_____ - .byte CT_UPPER | CT_XDIGIT ; 69/45 _____E_____ - .byte CT_UPPER | CT_XDIGIT ; 70/46 _____F_____ - .byte CT_UPPER ; 71/47 _____G_____ - .byte CT_UPPER ; 72/48 _____H_____ - .byte CT_UPPER ; 73/49 _____I_____ - .byte CT_UPPER ; 74/4a _____J_____ - .byte CT_UPPER ; 75/4b _____K_____ - .byte CT_UPPER ; 76/4c _____L_____ - .byte CT_UPPER ; 77/4d _____M_____ - .byte CT_UPPER ; 78/4e _____N_____ - .byte CT_UPPER ; 79/4f _____O_____ - .byte CT_UPPER ; 80/50 _____P_____ - .byte CT_UPPER ; 81/51 _____Q_____ - .byte CT_UPPER ; 82/52 _____R_____ - .byte CT_UPPER ; 83/53 _____S_____ - .byte CT_UPPER ; 84/54 _____T_____ - .byte CT_UPPER ; 85/55 _____U_____ - .byte CT_UPPER ; 86/56 _____V_____ - .byte CT_UPPER ; 87/57 _____W_____ - .byte CT_UPPER ; 88/58 _____X_____ - .byte CT_UPPER ; 89/59 _____Y_____ - .byte CT_UPPER ; 90/5a _____Z_____ - .byte CT_NONE ; 91/5b _____[_____ - .byte CT_NONE ; 92/5c _____\_____ - .byte CT_NONE ; 93/5d _____]_____ - .byte CT_NONE ; 94/5e _____^_____ - .byte CT_NONE ; 95/5f _UNDERLINE_ - .byte CT_NONE ; 96/60 ___grave___ - .byte CT_LOWER | CT_XDIGIT ; 97/61 _____a_____ - .byte CT_LOWER | CT_XDIGIT ; 98/62 _____b_____ - .byte CT_LOWER | CT_XDIGIT ; 99/63 _____c_____ - .byte CT_LOWER | CT_XDIGIT ; 100/64 _____d_____ - .byte CT_LOWER | CT_XDIGIT ; 101/65 _____e_____ - .byte CT_LOWER | CT_XDIGIT ; 102/66 _____f_____ - .byte CT_LOWER ; 103/67 _____g_____ - .byte CT_LOWER ; 104/68 _____h_____ - .byte CT_LOWER ; 105/69 _____i_____ - .byte CT_LOWER ; 106/6a _____j_____ - .byte CT_LOWER ; 107/6b _____k_____ - .byte CT_LOWER ; 108/6c _____l_____ - .byte CT_LOWER ; 109/6d _____m_____ - .byte CT_LOWER ; 110/6e _____n_____ - .byte CT_LOWER ; 111/6f _____o_____ - .byte CT_LOWER ; 112/70 _____p_____ - .byte CT_LOWER ; 113/71 _____q_____ - .byte CT_LOWER ; 114/72 _____r_____ - .byte CT_LOWER ; 115/73 _____s_____ - .byte CT_LOWER ; 116/74 _____t_____ - .byte CT_LOWER ; 117/75 _____u_____ - .byte CT_LOWER ; 118/76 _____v_____ - .byte CT_LOWER ; 119/77 _____w_____ - .byte CT_LOWER ; 120/78 _____x_____ - .byte CT_LOWER ; 121/79 _____y_____ - .byte CT_LOWER ; 122/7a _____z_____ - .byte CT_NONE ; 123/7b _____{_____ - .byte CT_NONE ; 124/7c _____|_____ - .byte CT_NONE ; 125/7d _____}_____ - .byte CT_NONE ; 126/7e _____~_____ - .byte CT_OTHER_WS ; 127/7f ____DEL____ - - .res 128, CT_NONE ; 128-255 + .include "ctype_common.inc" diff --git a/libsrc/osic1p/ctype.s b/libsrc/osic1p/ctype.s index 35968f982..1301965eb 100644 --- a/libsrc/osic1p/ctype.s +++ b/libsrc/osic1p/ctype.s @@ -1,159 +1,5 @@ -; -; Ullrich von Bassewitz, 2003-10-10 -; ; Character specification table. ; +; uses the "common" definition - .include "ctype.inc" - -; The tables are readonly, put them into the rodata segment - -.rodata - -; The following 256 byte wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it -; has major advantages: -; -; * It is fast. If it weren't for the slow parameter passing of cc65, one -; could even define macros for the isxxx functions (this is usually -; done on other platforms). -; -; * It is highly portable. The only unportable part is the table itself, -; all real code goes into the common library. -; -; * We save some code in the isxxx functions. - - -__ctype: - .byte CT_CTRL ; 0/00 ___ctrl_@___ - .byte CT_CTRL ; 1/01 ___ctrl_A___ - .byte CT_CTRL ; 2/02 ___ctrl_B___ - .byte CT_CTRL ; 3/03 ___ctrl_C___ - .byte CT_CTRL ; 4/04 ___ctrl_D___ - .byte CT_CTRL ; 5/05 ___ctrl_E___ - .byte CT_CTRL ; 6/06 ___ctrl_F___ - .byte CT_CTRL ; 7/07 ___ctrl_G___ - .byte CT_CTRL ; 8/08 ___ctrl_H___ - .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB - ; 9/09 ___ctrl_I___ - .byte CT_CTRL | CT_OTHER_WS ; 10/0a ___ctrl_J___ - .byte CT_CTRL | CT_OTHER_WS ; 11/0b ___ctrl_K___ - .byte CT_CTRL | CT_OTHER_WS ; 12/0c ___ctrl_L___ - .byte CT_CTRL | CT_OTHER_WS ; 13/0d ___ctrl_M___ - .byte CT_CTRL ; 14/0e ___ctrl_N___ - .byte CT_CTRL ; 15/0f ___ctrl_O___ - .byte CT_CTRL ; 16/10 ___ctrl_P___ - .byte CT_CTRL ; 17/11 ___ctrl_Q___ - .byte CT_CTRL ; 18/12 ___ctrl_R___ - .byte CT_CTRL ; 19/13 ___ctrl_S___ - .byte CT_CTRL ; 20/14 ___ctrl_T___ - .byte CT_CTRL ; 21/15 ___ctrl_U___ - .byte CT_CTRL ; 22/16 ___ctrl_V___ - .byte CT_CTRL ; 23/17 ___ctrl_W___ - .byte CT_CTRL ; 24/18 ___ctrl_X___ - .byte CT_CTRL ; 25/19 ___ctrl_Y___ - .byte CT_CTRL ; 26/1a ___ctrl_Z___ - .byte CT_CTRL ; 27/1b ___ctrl_[___ - .byte CT_CTRL ; 28/1c ___ctrl_\___ - .byte CT_CTRL ; 29/1d ___ctrl_]___ - .byte CT_CTRL ; 30/1e ___ctrl_^___ - .byte CT_CTRL ; 31/1f ___ctrl_____ - .byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___ - .byte CT_NONE ; 33/21 _____!_____ - .byte CT_NONE ; 34/22 _____"_____ - .byte CT_NONE ; 35/23 _____#_____ - .byte CT_NONE ; 36/24 _____$_____ - .byte CT_NONE ; 37/25 _____%_____ - .byte CT_NONE ; 38/26 _____&_____ - .byte CT_NONE ; 39/27 _____'_____ - .byte CT_NONE ; 40/28 _____(_____ - .byte CT_NONE ; 41/29 _____)_____ - .byte CT_NONE ; 42/2a _____*_____ - .byte CT_NONE ; 43/2b _____+_____ - .byte CT_NONE ; 44/2c _____,_____ - .byte CT_NONE ; 45/2d _____-_____ - .byte CT_NONE ; 46/2e _____._____ - .byte CT_NONE ; 47/2f _____/_____ - .byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____ - .byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____ - .byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____ - .byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____ - .byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____ - .byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____ - .byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____ - .byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____ - .byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____ - .byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____ - .byte CT_NONE ; 58/3a _____:_____ - .byte CT_NONE ; 59/3b _____;_____ - .byte CT_NONE ; 60/3c _____<_____ - .byte CT_NONE ; 61/3d _____=_____ - .byte CT_NONE ; 62/3e _____>_____ - .byte CT_NONE ; 63/3f _____?_____ - - .byte CT_NONE ; 64/40 _____@_____ - .byte CT_UPPER | CT_XDIGIT ; 65/41 _____A_____ - .byte CT_UPPER | CT_XDIGIT ; 66/42 _____B_____ - .byte CT_UPPER | CT_XDIGIT ; 67/43 _____C_____ - .byte CT_UPPER | CT_XDIGIT ; 68/44 _____D_____ - .byte CT_UPPER | CT_XDIGIT ; 69/45 _____E_____ - .byte CT_UPPER | CT_XDIGIT ; 70/46 _____F_____ - .byte CT_UPPER ; 71/47 _____G_____ - .byte CT_UPPER ; 72/48 _____H_____ - .byte CT_UPPER ; 73/49 _____I_____ - .byte CT_UPPER ; 74/4a _____J_____ - .byte CT_UPPER ; 75/4b _____K_____ - .byte CT_UPPER ; 76/4c _____L_____ - .byte CT_UPPER ; 77/4d _____M_____ - .byte CT_UPPER ; 78/4e _____N_____ - .byte CT_UPPER ; 79/4f _____O_____ - .byte CT_UPPER ; 80/50 _____P_____ - .byte CT_UPPER ; 81/51 _____Q_____ - .byte CT_UPPER ; 82/52 _____R_____ - .byte CT_UPPER ; 83/53 _____S_____ - .byte CT_UPPER ; 84/54 _____T_____ - .byte CT_UPPER ; 85/55 _____U_____ - .byte CT_UPPER ; 86/56 _____V_____ - .byte CT_UPPER ; 87/57 _____W_____ - .byte CT_UPPER ; 88/58 _____X_____ - .byte CT_UPPER ; 89/59 _____Y_____ - .byte CT_UPPER ; 90/5a _____Z_____ - .byte CT_NONE ; 91/5b _____[_____ - .byte CT_NONE ; 92/5c _____\_____ - .byte CT_NONE ; 93/5d _____]_____ - .byte CT_NONE ; 94/5e _____^_____ - .byte CT_NONE ; 95/5f _UNDERLINE_ - .byte CT_NONE ; 96/60 ___grave___ - .byte CT_LOWER | CT_XDIGIT ; 97/61 _____a_____ - .byte CT_LOWER | CT_XDIGIT ; 98/62 _____b_____ - .byte CT_LOWER | CT_XDIGIT ; 99/63 _____c_____ - .byte CT_LOWER | CT_XDIGIT ; 100/64 _____d_____ - .byte CT_LOWER | CT_XDIGIT ; 101/65 _____e_____ - .byte CT_LOWER | CT_XDIGIT ; 102/66 _____f_____ - .byte CT_LOWER ; 103/67 _____g_____ - .byte CT_LOWER ; 104/68 _____h_____ - .byte CT_LOWER ; 105/69 _____i_____ - .byte CT_LOWER ; 106/6a _____j_____ - .byte CT_LOWER ; 107/6b _____k_____ - .byte CT_LOWER ; 108/6c _____l_____ - .byte CT_LOWER ; 109/6d _____m_____ - .byte CT_LOWER ; 110/6e _____n_____ - .byte CT_LOWER ; 111/6f _____o_____ - .byte CT_LOWER ; 112/70 _____p_____ - .byte CT_LOWER ; 113/71 _____q_____ - .byte CT_LOWER ; 114/72 _____r_____ - .byte CT_LOWER ; 115/73 _____s_____ - .byte CT_LOWER ; 116/74 _____t_____ - .byte CT_LOWER ; 117/75 _____u_____ - .byte CT_LOWER ; 118/76 _____v_____ - .byte CT_LOWER ; 119/77 _____w_____ - .byte CT_LOWER ; 120/78 _____x_____ - .byte CT_LOWER ; 121/79 _____y_____ - .byte CT_LOWER ; 122/7a _____z_____ - .byte CT_NONE ; 123/7b _____{_____ - .byte CT_NONE ; 124/7c _____|_____ - .byte CT_NONE ; 125/7d _____}_____ - .byte CT_NONE ; 126/7e _____~_____ - .byte CT_OTHER_WS ; 127/7f ____DEL____ - - .res 128, CT_NONE ; 128-255 + .include "ctype_common.inc" diff --git a/libsrc/pce/ctype.s b/libsrc/pce/ctype.s index 1ee51b230..da4d38472 100644 --- a/libsrc/pce/ctype.s +++ b/libsrc/pce/ctype.s @@ -1,158 +1,5 @@ -; -; Stefan Haubenthal with minor changes from Ullrich von Bassewitz, 2003-05-02 -; ; Character specification table. ; +; uses the "console" definition - .include "ctype.inc" - -; The tables are read-only; put them into the RODATA segment. - -.rodata - -; The following 256-byte-wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it -; has major advantages: -; -; * It is fast. If it weren't for the slow parameter passing of cc65, one -; could even define macros for the isxxx functions (this is usually -; done on other platforms). -; -; * It is highly portable. The only unportable part is the table itself, -; all real code goes into the common library. -; -; * We save some code in the isxxx functions. - -__ctype: - .repeat 2 - .byte CT_CTRL ; 0/00 ___ctrl_@___ - .byte CT_CTRL ; 1/01 ___ctrl_A___ - .byte CT_CTRL ; 2/02 ___ctrl_B___ - .byte CT_CTRL ; 3/03 ___ctrl_C___ - .byte CT_CTRL ; 4/04 ___ctrl_D___ - .byte CT_CTRL ; 5/05 ___ctrl_E___ - .byte CT_CTRL ; 6/06 ___ctrl_F___ - .byte CT_CTRL ; 7/07 ___ctrl_G___ - .byte CT_CTRL ; 8/08 ___ctrl_H___ - .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB - ; 9/09 ___ctrl_I___ - .byte CT_CTRL | CT_OTHER_WS ; 10/0a ___ctrl_J___ - .byte CT_CTRL | CT_OTHER_WS ; 11/0b ___ctrl_K___ - .byte CT_CTRL | CT_OTHER_WS ; 12/0c ___ctrl_L___ - .byte CT_CTRL | CT_OTHER_WS ; 13/0d ___ctrl_M___ - .byte CT_CTRL ; 14/0e ___ctrl_N___ - .byte CT_CTRL ; 15/0f ___ctrl_O___ - .byte CT_CTRL ; 16/10 ___ctrl_P___ - .byte CT_CTRL ; 17/11 ___ctrl_Q___ - .byte CT_CTRL ; 18/12 ___ctrl_R___ - .byte CT_CTRL ; 19/13 ___ctrl_S___ - .byte CT_CTRL ; 20/14 ___ctrl_T___ - .byte CT_CTRL ; 21/15 ___ctrl_U___ - .byte CT_CTRL ; 22/16 ___ctrl_V___ - .byte CT_CTRL ; 23/17 ___ctrl_W___ - .byte CT_CTRL ; 24/18 ___ctrl_X___ - .byte CT_CTRL ; 25/19 ___ctrl_Y___ - .byte CT_CTRL ; 26/1a ___ctrl_Z___ - .byte CT_CTRL ; 27/1b ___ctrl_[___ - .byte CT_CTRL ; 28/1c ___ctrl_\___ - .byte CT_CTRL ; 29/1d ___ctrl_]___ - .byte CT_CTRL ; 30/1e ___ctrl_^___ - .byte CT_CTRL ; 31/1f ___ctrl_____ - .byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___ - .byte CT_NONE ; 33/21 _____!_____ - .byte CT_NONE ; 34/22 _____"_____ - .byte CT_NONE ; 35/23 _____#_____ - .byte CT_NONE ; 36/24 _____$_____ - .byte CT_NONE ; 37/25 _____%_____ - .byte CT_NONE ; 38/26 _____&_____ - .byte CT_NONE ; 39/27 _____'_____ - .byte CT_NONE ; 40/28 _____(_____ - .byte CT_NONE ; 41/29 _____)_____ - .byte CT_NONE ; 42/2a _____*_____ - .byte CT_NONE ; 43/2b _____+_____ - .byte CT_NONE ; 44/2c _____,_____ - .byte CT_NONE ; 45/2d _____-_____ - .byte CT_NONE ; 46/2e _____._____ - .byte CT_NONE ; 47/2f _____/_____ - .byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____ - .byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____ - .byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____ - .byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____ - .byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____ - .byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____ - .byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____ - .byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____ - .byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____ - .byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____ - .byte CT_NONE ; 58/3a _____:_____ - .byte CT_NONE ; 59/3b _____;_____ - .byte CT_NONE ; 60/3c _____<_____ - .byte CT_NONE ; 61/3d _____=_____ - .byte CT_NONE ; 62/3e _____>_____ - .byte CT_NONE ; 63/3f _____?_____ - - .byte CT_NONE ; 64/40 _____@_____ - .byte CT_UPPER | CT_XDIGIT ; 65/41 _____A_____ - .byte CT_UPPER | CT_XDIGIT ; 66/42 _____B_____ - .byte CT_UPPER | CT_XDIGIT ; 67/43 _____C_____ - .byte CT_UPPER | CT_XDIGIT ; 68/44 _____D_____ - .byte CT_UPPER | CT_XDIGIT ; 69/45 _____E_____ - .byte CT_UPPER | CT_XDIGIT ; 70/46 _____F_____ - .byte CT_UPPER ; 71/47 _____G_____ - .byte CT_UPPER ; 72/48 _____H_____ - .byte CT_UPPER ; 73/49 _____I_____ - .byte CT_UPPER ; 74/4a _____J_____ - .byte CT_UPPER ; 75/4b _____K_____ - .byte CT_UPPER ; 76/4c _____L_____ - .byte CT_UPPER ; 77/4d _____M_____ - .byte CT_UPPER ; 78/4e _____N_____ - .byte CT_UPPER ; 79/4f _____O_____ - .byte CT_UPPER ; 80/50 _____P_____ - .byte CT_UPPER ; 81/51 _____Q_____ - .byte CT_UPPER ; 82/52 _____R_____ - .byte CT_UPPER ; 83/53 _____S_____ - .byte CT_UPPER ; 84/54 _____T_____ - .byte CT_UPPER ; 85/55 _____U_____ - .byte CT_UPPER ; 86/56 _____V_____ - .byte CT_UPPER ; 87/57 _____W_____ - .byte CT_UPPER ; 88/58 _____X_____ - .byte CT_UPPER ; 89/59 _____Y_____ - .byte CT_UPPER ; 90/5a _____Z_____ - .byte CT_NONE ; 91/5b _____[_____ - .byte CT_NONE ; 92/5c _____\_____ - .byte CT_NONE ; 93/5d _____]_____ - .byte CT_NONE ; 94/5e _____^_____ - .byte CT_NONE ; 95/5f _UNDERLINE_ - .byte CT_NONE ; 96/60 ___grave___ - .byte CT_LOWER | CT_XDIGIT ; 97/61 _____a_____ - .byte CT_LOWER | CT_XDIGIT ; 98/62 _____b_____ - .byte CT_LOWER | CT_XDIGIT ; 99/63 _____c_____ - .byte CT_LOWER | CT_XDIGIT ; 100/64 _____d_____ - .byte CT_LOWER | CT_XDIGIT ; 101/65 _____e_____ - .byte CT_LOWER | CT_XDIGIT ; 102/66 _____f_____ - .byte CT_LOWER ; 103/67 _____g_____ - .byte CT_LOWER ; 104/68 _____h_____ - .byte CT_LOWER ; 105/69 _____i_____ - .byte CT_LOWER ; 106/6a _____j_____ - .byte CT_LOWER ; 107/6b _____k_____ - .byte CT_LOWER ; 108/6c _____l_____ - .byte CT_LOWER ; 109/6d _____m_____ - .byte CT_LOWER ; 110/6e _____n_____ - .byte CT_LOWER ; 111/6f _____o_____ - .byte CT_LOWER ; 112/70 _____p_____ - .byte CT_LOWER ; 113/71 _____q_____ - .byte CT_LOWER ; 114/72 _____r_____ - .byte CT_LOWER ; 115/73 _____s_____ - .byte CT_LOWER ; 116/74 _____t_____ - .byte CT_LOWER ; 117/75 _____u_____ - .byte CT_LOWER ; 118/76 _____v_____ - .byte CT_LOWER ; 119/77 _____w_____ - .byte CT_LOWER ; 120/78 _____x_____ - .byte CT_LOWER ; 121/79 _____y_____ - .byte CT_LOWER ; 122/7a _____z_____ - .byte CT_NONE ; 123/7b _____{_____ - .byte CT_NONE ; 124/7c _____|_____ - .byte CT_NONE ; 125/7d _____}_____ - .byte CT_NONE ; 126/7e _____~_____ - .byte CT_OTHER_WS ; 127/7f ____DEL____ - .endrepeat + .include "ctype_console.inc" diff --git a/libsrc/sim6502/ctype.s b/libsrc/sim6502/ctype.s index 35968f982..1301965eb 100644 --- a/libsrc/sim6502/ctype.s +++ b/libsrc/sim6502/ctype.s @@ -1,159 +1,5 @@ -; -; Ullrich von Bassewitz, 2003-10-10 -; ; Character specification table. ; +; uses the "common" definition - .include "ctype.inc" - -; The tables are readonly, put them into the rodata segment - -.rodata - -; The following 256 byte wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it -; has major advantages: -; -; * It is fast. If it weren't for the slow parameter passing of cc65, one -; could even define macros for the isxxx functions (this is usually -; done on other platforms). -; -; * It is highly portable. The only unportable part is the table itself, -; all real code goes into the common library. -; -; * We save some code in the isxxx functions. - - -__ctype: - .byte CT_CTRL ; 0/00 ___ctrl_@___ - .byte CT_CTRL ; 1/01 ___ctrl_A___ - .byte CT_CTRL ; 2/02 ___ctrl_B___ - .byte CT_CTRL ; 3/03 ___ctrl_C___ - .byte CT_CTRL ; 4/04 ___ctrl_D___ - .byte CT_CTRL ; 5/05 ___ctrl_E___ - .byte CT_CTRL ; 6/06 ___ctrl_F___ - .byte CT_CTRL ; 7/07 ___ctrl_G___ - .byte CT_CTRL ; 8/08 ___ctrl_H___ - .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB - ; 9/09 ___ctrl_I___ - .byte CT_CTRL | CT_OTHER_WS ; 10/0a ___ctrl_J___ - .byte CT_CTRL | CT_OTHER_WS ; 11/0b ___ctrl_K___ - .byte CT_CTRL | CT_OTHER_WS ; 12/0c ___ctrl_L___ - .byte CT_CTRL | CT_OTHER_WS ; 13/0d ___ctrl_M___ - .byte CT_CTRL ; 14/0e ___ctrl_N___ - .byte CT_CTRL ; 15/0f ___ctrl_O___ - .byte CT_CTRL ; 16/10 ___ctrl_P___ - .byte CT_CTRL ; 17/11 ___ctrl_Q___ - .byte CT_CTRL ; 18/12 ___ctrl_R___ - .byte CT_CTRL ; 19/13 ___ctrl_S___ - .byte CT_CTRL ; 20/14 ___ctrl_T___ - .byte CT_CTRL ; 21/15 ___ctrl_U___ - .byte CT_CTRL ; 22/16 ___ctrl_V___ - .byte CT_CTRL ; 23/17 ___ctrl_W___ - .byte CT_CTRL ; 24/18 ___ctrl_X___ - .byte CT_CTRL ; 25/19 ___ctrl_Y___ - .byte CT_CTRL ; 26/1a ___ctrl_Z___ - .byte CT_CTRL ; 27/1b ___ctrl_[___ - .byte CT_CTRL ; 28/1c ___ctrl_\___ - .byte CT_CTRL ; 29/1d ___ctrl_]___ - .byte CT_CTRL ; 30/1e ___ctrl_^___ - .byte CT_CTRL ; 31/1f ___ctrl_____ - .byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___ - .byte CT_NONE ; 33/21 _____!_____ - .byte CT_NONE ; 34/22 _____"_____ - .byte CT_NONE ; 35/23 _____#_____ - .byte CT_NONE ; 36/24 _____$_____ - .byte CT_NONE ; 37/25 _____%_____ - .byte CT_NONE ; 38/26 _____&_____ - .byte CT_NONE ; 39/27 _____'_____ - .byte CT_NONE ; 40/28 _____(_____ - .byte CT_NONE ; 41/29 _____)_____ - .byte CT_NONE ; 42/2a _____*_____ - .byte CT_NONE ; 43/2b _____+_____ - .byte CT_NONE ; 44/2c _____,_____ - .byte CT_NONE ; 45/2d _____-_____ - .byte CT_NONE ; 46/2e _____._____ - .byte CT_NONE ; 47/2f _____/_____ - .byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____ - .byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____ - .byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____ - .byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____ - .byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____ - .byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____ - .byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____ - .byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____ - .byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____ - .byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____ - .byte CT_NONE ; 58/3a _____:_____ - .byte CT_NONE ; 59/3b _____;_____ - .byte CT_NONE ; 60/3c _____<_____ - .byte CT_NONE ; 61/3d _____=_____ - .byte CT_NONE ; 62/3e _____>_____ - .byte CT_NONE ; 63/3f _____?_____ - - .byte CT_NONE ; 64/40 _____@_____ - .byte CT_UPPER | CT_XDIGIT ; 65/41 _____A_____ - .byte CT_UPPER | CT_XDIGIT ; 66/42 _____B_____ - .byte CT_UPPER | CT_XDIGIT ; 67/43 _____C_____ - .byte CT_UPPER | CT_XDIGIT ; 68/44 _____D_____ - .byte CT_UPPER | CT_XDIGIT ; 69/45 _____E_____ - .byte CT_UPPER | CT_XDIGIT ; 70/46 _____F_____ - .byte CT_UPPER ; 71/47 _____G_____ - .byte CT_UPPER ; 72/48 _____H_____ - .byte CT_UPPER ; 73/49 _____I_____ - .byte CT_UPPER ; 74/4a _____J_____ - .byte CT_UPPER ; 75/4b _____K_____ - .byte CT_UPPER ; 76/4c _____L_____ - .byte CT_UPPER ; 77/4d _____M_____ - .byte CT_UPPER ; 78/4e _____N_____ - .byte CT_UPPER ; 79/4f _____O_____ - .byte CT_UPPER ; 80/50 _____P_____ - .byte CT_UPPER ; 81/51 _____Q_____ - .byte CT_UPPER ; 82/52 _____R_____ - .byte CT_UPPER ; 83/53 _____S_____ - .byte CT_UPPER ; 84/54 _____T_____ - .byte CT_UPPER ; 85/55 _____U_____ - .byte CT_UPPER ; 86/56 _____V_____ - .byte CT_UPPER ; 87/57 _____W_____ - .byte CT_UPPER ; 88/58 _____X_____ - .byte CT_UPPER ; 89/59 _____Y_____ - .byte CT_UPPER ; 90/5a _____Z_____ - .byte CT_NONE ; 91/5b _____[_____ - .byte CT_NONE ; 92/5c _____\_____ - .byte CT_NONE ; 93/5d _____]_____ - .byte CT_NONE ; 94/5e _____^_____ - .byte CT_NONE ; 95/5f _UNDERLINE_ - .byte CT_NONE ; 96/60 ___grave___ - .byte CT_LOWER | CT_XDIGIT ; 97/61 _____a_____ - .byte CT_LOWER | CT_XDIGIT ; 98/62 _____b_____ - .byte CT_LOWER | CT_XDIGIT ; 99/63 _____c_____ - .byte CT_LOWER | CT_XDIGIT ; 100/64 _____d_____ - .byte CT_LOWER | CT_XDIGIT ; 101/65 _____e_____ - .byte CT_LOWER | CT_XDIGIT ; 102/66 _____f_____ - .byte CT_LOWER ; 103/67 _____g_____ - .byte CT_LOWER ; 104/68 _____h_____ - .byte CT_LOWER ; 105/69 _____i_____ - .byte CT_LOWER ; 106/6a _____j_____ - .byte CT_LOWER ; 107/6b _____k_____ - .byte CT_LOWER ; 108/6c _____l_____ - .byte CT_LOWER ; 109/6d _____m_____ - .byte CT_LOWER ; 110/6e _____n_____ - .byte CT_LOWER ; 111/6f _____o_____ - .byte CT_LOWER ; 112/70 _____p_____ - .byte CT_LOWER ; 113/71 _____q_____ - .byte CT_LOWER ; 114/72 _____r_____ - .byte CT_LOWER ; 115/73 _____s_____ - .byte CT_LOWER ; 116/74 _____t_____ - .byte CT_LOWER ; 117/75 _____u_____ - .byte CT_LOWER ; 118/76 _____v_____ - .byte CT_LOWER ; 119/77 _____w_____ - .byte CT_LOWER ; 120/78 _____x_____ - .byte CT_LOWER ; 121/79 _____y_____ - .byte CT_LOWER ; 122/7a _____z_____ - .byte CT_NONE ; 123/7b _____{_____ - .byte CT_NONE ; 124/7c _____|_____ - .byte CT_NONE ; 125/7d _____}_____ - .byte CT_NONE ; 126/7e _____~_____ - .byte CT_OTHER_WS ; 127/7f ____DEL____ - - .res 128, CT_NONE ; 128-255 + .include "ctype_common.inc" diff --git a/libsrc/supervision/ctype.s b/libsrc/supervision/ctype.s index 1892554fd..1301965eb 100644 --- a/libsrc/supervision/ctype.s +++ b/libsrc/supervision/ctype.s @@ -1,162 +1,5 @@ -; -; Ullrich von Bassewitz, 2003-10-10 -; ; Character specification table. ; +; uses the "common" definition - .include "ctype.inc" - -; The tables are readonly, put them into the rodata segment - -.rodata - -; The following 256 byte wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it -; has major advantages: -; -; * It is fast. If it weren't for the slow parameter passing of cc65, one -; could even define macros for the isxxx functions (this is usually -; done on other platforms). -; -; * It is highly portable. The only unportable part is the table itself, -; all real code goes into the common library. -; -; * We save some code in the isxxx functions. - - -__ctype: - .byte CT_CTRL ; 0/00 ___ctrl_@___ - .byte CT_CTRL ; 1/01 ___ctrl_A___ - .byte CT_CTRL ; 2/02 ___ctrl_B___ - .byte CT_CTRL ; 3/03 ___ctrl_C___ - .byte CT_CTRL ; 4/04 ___ctrl_D___ - .byte CT_CTRL ; 5/05 ___ctrl_E___ - .byte CT_CTRL ; 6/06 ___ctrl_F___ - .byte CT_CTRL ; 7/07 ___ctrl_G___ - .byte CT_CTRL ; 8/08 ___ctrl_H___ - .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB - ; 9/09 ___ctrl_I___ - .byte CT_CTRL | CT_OTHER_WS ; 10/0a ___ctrl_J___ - .byte CT_CTRL | CT_OTHER_WS ; 11/0b ___ctrl_K___ - .byte CT_CTRL | CT_OTHER_WS ; 12/0c ___ctrl_L___ - .byte CT_CTRL | CT_OTHER_WS ; 13/0d ___ctrl_M___ - .byte CT_CTRL ; 14/0e ___ctrl_N___ - .byte CT_CTRL ; 15/0f ___ctrl_O___ - .byte CT_CTRL ; 16/10 ___ctrl_P___ - .byte CT_CTRL ; 17/11 ___ctrl_Q___ - .byte CT_CTRL ; 18/12 ___ctrl_R___ - .byte CT_CTRL ; 19/13 ___ctrl_S___ - .byte CT_CTRL ; 20/14 ___ctrl_T___ - .byte CT_CTRL ; 21/15 ___ctrl_U___ - .byte CT_CTRL ; 22/16 ___ctrl_V___ - .byte CT_CTRL ; 23/17 ___ctrl_W___ - .byte CT_CTRL ; 24/18 ___ctrl_X___ - .byte CT_CTRL ; 25/19 ___ctrl_Y___ - .byte CT_CTRL ; 26/1a ___ctrl_Z___ - .byte CT_CTRL ; 27/1b ___ctrl_[___ - .byte CT_CTRL ; 28/1c ___ctrl_\___ - .byte CT_CTRL ; 29/1d ___ctrl_]___ - .byte CT_CTRL ; 30/1e ___ctrl_^___ - .byte CT_CTRL ; 31/1f ___ctrl_____ - .byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___ - .byte CT_NONE ; 33/21 _____!_____ - .byte CT_NONE ; 34/22 _____"_____ - .byte CT_NONE ; 35/23 _____#_____ - .byte CT_NONE ; 36/24 _____$_____ - .byte CT_NONE ; 37/25 _____%_____ - .byte CT_NONE ; 38/26 _____&_____ - .byte CT_NONE ; 39/27 _____'_____ - .byte CT_NONE ; 40/28 _____(_____ - .byte CT_NONE ; 41/29 _____)_____ - .byte CT_NONE ; 42/2a _____*_____ - .byte CT_NONE ; 43/2b _____+_____ - .byte CT_NONE ; 44/2c _____,_____ - .byte CT_NONE ; 45/2d _____-_____ - .byte CT_NONE ; 46/2e _____._____ - .byte CT_NONE ; 47/2f _____/_____ - .byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____ - .byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____ - .byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____ - .byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____ - .byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____ - .byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____ - .byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____ - .byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____ - .byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____ - .byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____ - .byte CT_NONE ; 58/3a _____:_____ - .byte CT_NONE ; 59/3b _____;_____ - .byte CT_NONE ; 60/3c _____<_____ - .byte CT_NONE ; 61/3d _____=_____ - .byte CT_NONE ; 62/3e _____>_____ - .byte CT_NONE ; 63/3f _____?_____ - - .byte CT_NONE ; 64/40 _____@_____ - .byte CT_UPPER | CT_XDIGIT ; 65/41 _____A_____ - .byte CT_UPPER | CT_XDIGIT ; 66/42 _____B_____ - .byte CT_UPPER | CT_XDIGIT ; 67/43 _____C_____ - .byte CT_UPPER | CT_XDIGIT ; 68/44 _____D_____ - .byte CT_UPPER | CT_XDIGIT ; 69/45 _____E_____ - .byte CT_UPPER | CT_XDIGIT ; 70/46 _____F_____ - .byte CT_UPPER ; 71/47 _____G_____ - .byte CT_UPPER ; 72/48 _____H_____ - .byte CT_UPPER ; 73/49 _____I_____ - .byte CT_UPPER ; 74/4a _____J_____ - .byte CT_UPPER ; 75/4b _____K_____ - .byte CT_UPPER ; 76/4c _____L_____ - .byte CT_UPPER ; 77/4d _____M_____ - .byte CT_UPPER ; 78/4e _____N_____ - .byte CT_UPPER ; 79/4f _____O_____ - .byte CT_UPPER ; 80/50 _____P_____ - .byte CT_UPPER ; 81/51 _____Q_____ - .byte CT_UPPER ; 82/52 _____R_____ - .byte CT_UPPER ; 83/53 _____S_____ - .byte CT_UPPER ; 84/54 _____T_____ - .byte CT_UPPER ; 85/55 _____U_____ - .byte CT_UPPER ; 86/56 _____V_____ - .byte CT_UPPER ; 87/57 _____W_____ - .byte CT_UPPER ; 88/58 _____X_____ - .byte CT_UPPER ; 89/59 _____Y_____ - .byte CT_UPPER ; 90/5a _____Z_____ - .byte CT_NONE ; 91/5b _____[_____ - .byte CT_NONE ; 92/5c _____\_____ - .byte CT_NONE ; 93/5d _____]_____ - .byte CT_NONE ; 94/5e _____^_____ - .byte CT_NONE ; 95/5f _UNDERLINE_ - .byte CT_NONE ; 96/60 ___grave___ - .byte CT_LOWER | CT_XDIGIT ; 97/61 _____a_____ - .byte CT_LOWER | CT_XDIGIT ; 98/62 _____b_____ - .byte CT_LOWER | CT_XDIGIT ; 99/63 _____c_____ - .byte CT_LOWER | CT_XDIGIT ; 100/64 _____d_____ - .byte CT_LOWER | CT_XDIGIT ; 101/65 _____e_____ - .byte CT_LOWER | CT_XDIGIT ; 102/66 _____f_____ - .byte CT_LOWER ; 103/67 _____g_____ - .byte CT_LOWER ; 104/68 _____h_____ - .byte CT_LOWER ; 105/69 _____i_____ - .byte CT_LOWER ; 106/6a _____j_____ - .byte CT_LOWER ; 107/6b _____k_____ - .byte CT_LOWER ; 108/6c _____l_____ - .byte CT_LOWER ; 109/6d _____m_____ - .byte CT_LOWER ; 110/6e _____n_____ - .byte CT_LOWER ; 111/6f _____o_____ - .byte CT_LOWER ; 112/70 _____p_____ - .byte CT_LOWER ; 113/71 _____q_____ - .byte CT_LOWER ; 114/72 _____r_____ - .byte CT_LOWER ; 115/73 _____s_____ - .byte CT_LOWER ; 116/74 _____t_____ - .byte CT_LOWER ; 117/75 _____u_____ - .byte CT_LOWER ; 118/76 _____v_____ - .byte CT_LOWER ; 119/77 _____w_____ - .byte CT_LOWER ; 120/78 _____x_____ - .byte CT_LOWER ; 121/79 _____y_____ - .byte CT_LOWER ; 122/7a _____z_____ - .byte CT_NONE ; 123/7b _____{_____ - .byte CT_NONE ; 124/7c _____|_____ - .byte CT_NONE ; 125/7d _____}_____ - .byte CT_NONE ; 126/7e _____~_____ - .byte CT_OTHER_WS ; 127/7f ____DEL____ - - .res 128, CT_NONE ; 128-255 - - - + .include "ctype_common.inc" diff --git a/libsrc/telestrat/ctype.s b/libsrc/telestrat/ctype.s index 79edafbb2..db61b1bb7 100644 --- a/libsrc/telestrat/ctype.s +++ b/libsrc/telestrat/ctype.s @@ -1,299 +1,5 @@ -; -; Ullrich von Bassewitz, 2003-04-13 -; ; Character specification table. ; +; same as for "atmos" target -; The tables are readonly, put them into the rodata segment - -.rodata - -; The following 256 byte wide table specifies attributes for the isxxx type -; of functions. Doing it by a table means some overhead in space, but it -; has major advantages: -; -; * It is fast. If it were'nt for the slow parameter passing of cc65, one -; could even define macros for the isxxx functions (this is usually -; done on other platforms). -; -; * It is highly portable. The only unportable part is the table itself, -; all real code goes into the common library. -; -; * We save some code in the isxxx functions. -; -; -; Bit assignments: -; -; 0 - Lower case char -; 1 - Upper case char -; 2 - Numeric digit -; 3 - Hex digit (both, lower and upper) -; 4 - Control character -; 5 - The space character itself -; 6 - Other whitespace (that is: '\f', '\n', '\r', '\t' and '\v') -; 7 - Space or tab character - - .export __ctype - -__ctype: - .byte $10 ; 0/00 ___ctrl_@___ - .byte $10 ; 1/01 ___ctrl_A___ - .byte $10 ; 2/02 ___ctrl_B___ - .byte $10 ; 3/03 ___ctrl_C___ - .byte $10 ; 4/04 ___ctrl_D___ - .byte $10 ; 5/05 ___ctrl_E___ - .byte $10 ; 6/06 ___ctrl_F___ - .byte $10 ; 7/07 ___ctrl_G___ - .byte $10 ; 8/08 ___ctrl_H___ - .byte $D0 ; 9/09 ___ctrl_I___ - .byte $50 ; 10/0a ___ctrl_J___ - .byte $50 ; 11/0b ___ctrl_K___ - .byte $50 ; 12/0c ___ctrl_L___ - .byte $50 ; 13/0d ___ctrl_M___ - .byte $10 ; 14/0e ___ctrl_N___ - .byte $10 ; 15/0f ___ctrl_O___ - .byte $10 ; 16/10 ___ctrl_P___ - .byte $10 ; 17/11 ___ctrl_Q___ - .byte $10 ; 18/12 ___ctrl_R___ - .byte $10 ; 19/13 ___ctrl_S___ - .byte $10 ; 20/14 ___ctrl_T___ - .byte $10 ; 21/15 ___ctrl_U___ - .byte $10 ; 22/16 ___ctrl_V___ - .byte $10 ; 23/17 ___ctrl_W___ - .byte $10 ; 24/18 ___ctrl_X___ - .byte $10 ; 25/19 ___ctrl_Y___ - .byte $10 ; 26/1a ___ctrl_Z___ - .byte $10 ; 27/1b ___ctrl_[___ - .byte $10 ; 28/1c ___ctrl_\___ - .byte $10 ; 29/1d ___ctrl_]___ - .byte $10 ; 30/1e ___ctrl_^___ - .byte $10 ; 31/1f ___ctrl_____ - .byte $A0 ; 32/20 ___SPACE___ - .byte $00 ; 33/21 _____!_____ - .byte $00 ; 34/22 _____"_____ - .byte $00 ; 35/23 _____#_____ - .byte $00 ; 36/24 _____$_____ - .byte $00 ; 37/25 _____%_____ - .byte $00 ; 38/26 _____&_____ - .byte $00 ; 39/27 _____'_____ - .byte $00 ; 40/28 _____(_____ - .byte $00 ; 41/29 _____)_____ - .byte $00 ; 42/2a _____*_____ - .byte $00 ; 43/2b _____+_____ - .byte $00 ; 44/2c _____,_____ - .byte $00 ; 45/2d _____-_____ - .byte $00 ; 46/2e _____._____ - .byte $00 ; 47/2f _____/_____ - .byte $0C ; 48/30 _____0_____ - .byte $0C ; 49/31 _____1_____ - .byte $0C ; 50/32 _____2_____ - .byte $0C ; 51/33 _____3_____ - .byte $0C ; 52/34 _____4_____ - .byte $0C ; 53/35 _____5_____ - .byte $0C ; 54/36 _____6_____ - .byte $0C ; 55/37 _____7_____ - .byte $0C ; 56/38 _____8_____ - .byte $0C ; 57/39 _____9_____ - .byte $00 ; 58/3a _____:_____ - .byte $00 ; 59/3b _____;_____ - .byte $00 ; 60/3c _____<_____ - .byte $00 ; 61/3d _____=_____ - .byte $00 ; 62/3e _____>_____ - .byte $00 ; 63/3f _____?_____ - - .byte $00 ; 64/40 _____@_____ - .byte $0A ; 65/41 _____A_____ - .byte $0A ; 66/42 _____B_____ - .byte $0A ; 67/43 _____C_____ - .byte $0A ; 68/44 _____D_____ - .byte $0A ; 69/45 _____E_____ - .byte $0A ; 70/46 _____F_____ - .byte $02 ; 71/47 _____G_____ - .byte $02 ; 72/48 _____H_____ - .byte $02 ; 73/49 _____I_____ - .byte $02 ; 74/4a _____J_____ - .byte $02 ; 75/4b _____K_____ - .byte $02 ; 76/4c _____L_____ - .byte $02 ; 77/4d _____M_____ - .byte $02 ; 78/4e _____N_____ - .byte $02 ; 79/4f _____O_____ - .byte $02 ; 80/50 _____P_____ - .byte $02 ; 81/51 _____Q_____ - .byte $02 ; 82/52 _____R_____ - .byte $02 ; 83/53 _____S_____ - .byte $02 ; 84/54 _____T_____ - .byte $02 ; 85/55 _____U_____ - .byte $02 ; 86/56 _____V_____ - .byte $02 ; 87/57 _____W_____ - .byte $02 ; 88/58 _____X_____ - .byte $02 ; 89/59 _____Y_____ - .byte $02 ; 90/5a _____Z_____ - .byte $00 ; 91/5b _____[_____ - .byte $00 ; 92/5c _____\_____ - .byte $00 ; 93/5d _____]_____ - .byte $00 ; 94/5e _____^_____ - .byte $00 ; 95/5f _UNDERLINE_ - .byte $00 ; 96/60 ___grave___ - .byte $09 ; 97/61 _____a_____ - .byte $09 ; 98/62 _____b_____ - .byte $09 ; 99/63 _____c_____ - .byte $09 ; 100/64 _____d_____ - .byte $09 ; 101/65 _____e_____ - .byte $09 ; 102/66 _____f_____ - .byte $01 ; 103/67 _____g_____ - .byte $01 ; 104/68 _____h_____ - .byte $01 ; 105/69 _____i_____ - .byte $01 ; 106/6a _____j_____ - .byte $01 ; 107/6b _____k_____ - .byte $01 ; 108/6c _____l_____ - .byte $01 ; 109/6d _____m_____ - .byte $01 ; 110/6e _____n_____ - .byte $01 ; 111/6f _____o_____ - .byte $01 ; 112/70 _____p_____ - .byte $01 ; 113/71 _____q_____ - .byte $01 ; 114/72 _____r_____ - .byte $01 ; 115/73 _____s_____ - .byte $01 ; 116/74 _____t_____ - .byte $01 ; 117/75 _____u_____ - .byte $01 ; 118/76 _____v_____ - .byte $01 ; 119/77 _____w_____ - .byte $01 ; 120/78 _____x_____ - .byte $01 ; 121/79 _____y_____ - .byte $01 ; 122/7a _____z_____ - .byte $00 ; 123/7b _____{_____ - .byte $00 ; 124/7c _____|_____ - .byte $00 ; 125/7d _____}_____ - .byte $00 ; 126/7e _____~_____ - .byte $40 ; 127/7f ____DEL____ - - .byte $00 ; 128/80 ___________ - .byte $00 ; 129/81 ___________ - .byte $00 ; 130/82 ___________ - .byte $00 ; 131/83 ___________ - .byte $00 ; 132/84 ___________ - .byte $00 ; 133/85 ___________ - .byte $00 ; 134/86 ___________ - .byte $00 ; 135/87 ___________ - .byte $00 ; 136/88 ___________ - .byte $00 ; 137/89 ___________ - .byte $00 ; 138/8a ___________ - .byte $00 ; 139/8b ___________ - .byte $00 ; 140/8c ___________ - .byte $00 ; 141/8d ___________ - .byte $00 ; 142/8e ___________ - .byte $00 ; 143/8f ___________ - .byte $00 ; 144/90 ___________ - .byte $00 ; 145/91 ___________ - .byte $00 ; 146/92 ___________ - .byte $10 ; 147/93 ___________ - .byte $00 ; 148/94 ___________ - .byte $00 ; 149/95 ___________ - .byte $00 ; 150/96 ___________ - .byte $00 ; 151/97 ___________ - .byte $00 ; 152/98 ___________ - .byte $00 ; 153/99 ___________ - .byte $00 ; 154/9a ___________ - .byte $00 ; 155/9b ___________ - .byte $00 ; 156/9c ___________ - .byte $00 ; 157/9d ___________ - .byte $00 ; 158/9e ___________ - .byte $00 ; 159/9f ___________ - - .byte $00 ; 160/a0 ___________ - .byte $00 ; 161/a1 ___________ - .byte $00 ; 162/a2 ___________ - .byte $00 ; 163/a3 ___________ - .byte $00 ; 164/a4 ___________ - .byte $00 ; 165/a5 ___________ - .byte $00 ; 166/a6 ___________ - .byte $00 ; 167/a7 ___________ - .byte $00 ; 168/a8 ___________ - .byte $00 ; 169/a9 ___________ - .byte $00 ; 170/aa ___________ - .byte $00 ; 171/ab ___________ - .byte $00 ; 172/ac ___________ - .byte $00 ; 173/ad ___________ - .byte $00 ; 174/ae ___________ - .byte $00 ; 175/af ___________ - .byte $00 ; 176/b0 ___________ - .byte $00 ; 177/b1 ___________ - .byte $00 ; 178/b2 ___________ - .byte $00 ; 179/b3 ___________ - .byte $00 ; 180/b4 ___________ - .byte $00 ; 181/b5 ___________ - .byte $00 ; 182/b6 ___________ - .byte $00 ; 183/b7 ___________ - .byte $00 ; 184/b8 ___________ - .byte $00 ; 185/b9 ___________ - .byte $00 ; 186/ba ___________ - .byte $00 ; 187/bb ___________ - .byte $00 ; 188/bc ___________ - .byte $00 ; 189/bd ___________ - .byte $00 ; 190/be ___________ - .byte $00 ; 191/bf ___________ - - .byte $02 ; 192/c0 ___________ - .byte $02 ; 193/c1 ___________ - .byte $02 ; 194/c2 ___________ - .byte $02 ; 195/c3 ___________ - .byte $02 ; 196/c4 ___________ - .byte $02 ; 197/c5 ___________ - .byte $02 ; 198/c6 ___________ - .byte $02 ; 199/c7 ___________ - .byte $02 ; 200/c8 ___________ - .byte $02 ; 201/c9 ___________ - .byte $02 ; 202/ca ___________ - .byte $02 ; 203/cb ___________ - .byte $02 ; 204/cc ___________ - .byte $02 ; 205/cd ___________ - .byte $02 ; 206/ce ___________ - .byte $02 ; 207/cf ___________ - .byte $02 ; 208/d0 ___________ - .byte $02 ; 209/d1 ___________ - .byte $02 ; 210/d2 ___________ - .byte $02 ; 211/d3 ___________ - .byte $02 ; 212/d4 ___________ - .byte $02 ; 213/d5 ___________ - .byte $02 ; 214/d6 ___________ - .byte $02 ; 215/d7 ___________ - .byte $02 ; 216/d8 ___________ - .byte $02 ; 217/d9 ___________ - .byte $02 ; 218/da ___________ - .byte $02 ; 219/db ___________ - .byte $02 ; 220/dc ___________ - .byte $02 ; 221/dd ___________ - .byte $02 ; 222/de ___________ - .byte $00 ; 223/df ___________ - .byte $01 ; 224/e0 ___________ - .byte $01 ; 225/e1 ___________ - .byte $01 ; 226/e2 ___________ - .byte $01 ; 227/e3 ___________ - .byte $01 ; 228/e4 ___________ - .byte $01 ; 229/e5 ___________ - .byte $01 ; 230/e6 ___________ - .byte $01 ; 231/e7 ___________ - .byte $01 ; 232/e8 ___________ - .byte $01 ; 233/e9 ___________ - .byte $01 ; 234/ea ___________ - .byte $01 ; 235/eb ___________ - .byte $01 ; 236/ec ___________ - .byte $01 ; 237/ed ___________ - .byte $01 ; 238/ee ___________ - .byte $01 ; 239/ef ___________ - .byte $01 ; 240/f0 ___________ - .byte $01 ; 241/f1 ___________ - .byte $01 ; 242/f2 ___________ - .byte $01 ; 243/f3 ___________ - .byte $01 ; 244/f4 ___________ - .byte $01 ; 245/f5 ___________ - .byte $01 ; 246/f6 ___________ - .byte $01 ; 247/f7 ___________ - .byte $01 ; 248/f8 ___________ - .byte $01 ; 249/f9 ___________ - .byte $01 ; 250/fa ___________ - .byte $01 ; 251/fb ___________ - .byte $01 ; 252/fc ___________ - .byte $01 ; 253/fd ___________ - .byte $01 ; 254/fe ___________ - .byte $00 ; 255/ff ___________ - +.include "../atmos/ctype.s" diff --git a/test/val/lib_common_ctype.c b/test/val/lib_common_ctype.c new file mode 100644 index 000000000..15980aff1 --- /dev/null +++ b/test/val/lib_common_ctype.c @@ -0,0 +1,368 @@ +// lib_common_ctype.c +// +// This file is part of +// cc65 - a freeware C compiler for 6502 based systems +// +// https://github.com/cc65/cc65 +// +// See "LICENSE" file for legal information. +// +// Unit test for character classification functions ("is..") +// + +#include <ctype.h> +#include <stdbool.h> +#include "unittest.h" + +#define NUMTESTS 257 + +typedef struct +{ + bool isalnum; + bool isalpha; + bool isascii; + bool iscntrl; + bool isdigit; + bool isgraph; + bool islower; + bool isprint; + bool ispunct; + bool isspace; + bool isupper; + bool isxdigit; + bool isblank; + +} CTypeClassifications; + + +CTypeClassifications testSet[NUMTESTS] = +{ + //alnum, alpha, ascii, cntrl, digit, graph, lower, print, punct, space, upper, xdigit,blank + + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 00 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 01 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 02 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 03 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 04 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 05 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 06 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 07 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 08 + {false, false, true, true, false, false, false, false, false, true, false, false, true }, // 09 + {false, false, true, true, false, false, false, false, false, true, false, false, false}, // 0A + {false, false, true, true, false, false, false, false, false, true, false, false, false}, // 0B + {false, false, true, true, false, false, false, false, false, true, false, false, false}, // 0C + {false, false, true, true, false, false, false, false, false, true, false, false, false}, // 0D + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 0E + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 0F + + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 10 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 11 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 12 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 13 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 14 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 15 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 16 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 17 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 18 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 19 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1A + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1B + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1C + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1D + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1E + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1F + + {false, false, true, false, false, false, false, true, false, true, false, false, true }, // 20 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 21 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 22 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 23 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 24 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 25 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 26 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 27 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 28 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 29 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2A + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2B + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2C + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2D + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2E + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2F + + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 30 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 31 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 32 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 33 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 34 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 35 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 36 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 37 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 38 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 39 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3A + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3B + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3C + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3D + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3E + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3F + + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 40 + {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 41 + {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 42 + {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 43 + {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 44 + {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 45 + {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 46 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 47 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 48 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 49 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4A + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4B + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4C + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4D + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4E + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4F + + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 50 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 51 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 52 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 53 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 54 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 55 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 56 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 57 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 58 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 59 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 5A + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 5B + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 5C + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 5D + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 5E + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 5F + + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 60 + {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 61 + {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 62 + {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 63 + {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 64 + {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 65 + {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 66 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 67 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 68 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 69 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6A + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6B + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6C + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6D + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6E + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6F + + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 70 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 71 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 72 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 73 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 74 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 75 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 76 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 77 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 78 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 79 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 7A + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 7B + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 7C + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 7D + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 7E + {false, false, true, false, false, true, false, true, true, true, false, false, false}, // 7F + + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 80 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 81 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 82 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 83 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 84 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 85 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 86 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 87 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 88 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 89 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8A + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8B + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8C + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8D + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8E + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8F + + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 90 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 91 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 92 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 93 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 94 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 95 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 96 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 97 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 98 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 99 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9A + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9B + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9C + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9D + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9E + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9F + + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A0 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A1 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A2 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A3 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A4 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A5 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A6 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A7 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A8 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A9 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AA + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AB + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AC + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AD + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AE + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AF + + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B0 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B1 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B2 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B3 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B4 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B5 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B6 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B7 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B8 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B9 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BA + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BB + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BC + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BD + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BE + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BF + + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C0 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C1 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C2 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C3 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C4 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C5 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C6 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C7 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C8 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C9 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CA + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CB + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CC + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CD + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CE + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CF + + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D0 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D1 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D2 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D3 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D4 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D5 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D6 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D7 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D8 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D9 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DA + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DB + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DC + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DD + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DE + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DF + + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E0 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E1 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E2 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E3 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E4 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E5 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E6 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E7 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E8 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E9 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // EA + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // EB + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // EC + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // ED + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // EE + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // EF + + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F0 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F1 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F2 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F3 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F4 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F5 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F6 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F7 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F8 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F9 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FA + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FB + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FC + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FD + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FE + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FF + + // out of range test + {false, false, false, false, false, false, false, false, false, false, false, false, false} // 100 +}; + + +TEST +{ + int i = 0; + + while (i<NUMTESTS) + { + // isalnum() + ASSERT_AreEqual(testSet[i].isalnum, (isalnum(i) ? true : false), "%d", "Invalid 'isalnum(%d)' classification!" COMMA i); + + // isalpha() + ASSERT_AreEqual(testSet[i].isalpha, (isalpha(i) ? true : false), "%d", "Invalid 'isalpha(%d)' classification!" COMMA i); + + // isascii() + ASSERT_AreEqual(testSet[i].isascii, (isascii(i) ? true : false), "%d", "Invalid 'isascii(%d)' classification!" COMMA i); + + // iscntrl() + ASSERT_AreEqual(testSet[i].iscntrl, (iscntrl(i) ? true : false), "%d", "Invalid 'iscntrl(%d)' classification!" COMMA i); + + // isdigit() + ASSERT_AreEqual(testSet[i].isdigit, (isdigit(i) ? true : false), "%d", "Invalid 'isdigit(%d)' classification!" COMMA i); + + // isgraph() + ASSERT_AreEqual(testSet[i].isgraph, (isgraph(i) ? true : false), "%d", "Invalid 'isgraph(%d)' classification!" COMMA i); + + // islower() + ASSERT_AreEqual(testSet[i].islower, (islower(i) ? true : false), "%d", "Invalid 'islower(%d)' classification!" COMMA i); + + // isprint() + ASSERT_AreEqual(testSet[i].isprint, (isprint(i) ? true : false), "%d", "Invalid 'isprint(%d)' classification!" COMMA i); + + // ispunct() + ASSERT_AreEqual(testSet[i].ispunct, (ispunct(i) ? true : false), "%d", "Invalid 'ispunct(%d)' classification!" COMMA i); + + // isspace() + ASSERT_AreEqual(testSet[i].isspace, (isspace(i) ? true : false), "%d", "Invalid 'isspace(%d)' classification!" COMMA i); + + // isupper() + ASSERT_AreEqual(testSet[i].isupper, (isupper(i) ? true : false), "%d", "Invalid 'isupper(%d)' classification!" COMMA i); + + // isxdigit() + ASSERT_AreEqual(testSet[i].isxdigit, (isxdigit(i) ? true : false), "%d", "Invalid 'isxdigit(%d)' classification!" COMMA i); + +#if __CC65_STD__ >= __CC65_STD_C99__ + // isblank() + ASSERT_AreEqual(testSet[i].isblank, (isblank(i) ? true : false), "%d", "Invalid 'isblank(%d)' classification!" COMMA i); +#endif + ++i; + } +} +ENDTEST From 002d1801ec72c1dc11e90cd7e821395e6df61a5b Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sun, 5 Jan 2020 15:57:44 +0100 Subject: [PATCH 1264/2161] Changes resulting from code review. --- asminc/ctype.inc | 2 ++ asminc/ctypetable.inc | 2 +- libsrc/common/atoi.s | 13 ++++++------- libsrc/common/isascii.s | 13 +++++-------- libsrc/common/strlower.s | 5 ++--- libsrc/common/strupper.s | 3 +-- 6 files changed, 17 insertions(+), 21 deletions(-) diff --git a/asminc/ctype.inc b/asminc/ctype.inc index 401e772a2..299760789 100644 --- a/asminc/ctype.inc +++ b/asminc/ctype.inc @@ -9,6 +9,8 @@ ; ; Definitions for the character type tables ; +; Ullrich von Bassewitz, 08.09.2001 +; ; Define bitmapped constants for the table entries diff --git a/asminc/ctypetable.inc b/asminc/ctypetable.inc index e0a8bdcd3..7134d002e 100644 --- a/asminc/ctypetable.inc +++ b/asminc/ctypetable.inc @@ -13,7 +13,7 @@ .include "ctype.inc" .export __ctype -; This data is a table of possible ctype combinations, possible during +; Table definition covering all possible ctype combinations .rodata __ctype: diff --git a/libsrc/common/atoi.s b/libsrc/common/atoi.s index 8427be62e..b63fcb206 100644 --- a/libsrc/common/atoi.s +++ b/libsrc/common/atoi.s @@ -54,10 +54,11 @@ L3: iny L5: stx tmp1 ; remember sign flag L6: lda (ptr1),y ; get next char - ; get character classification - jsr ctype_preprocessor_no_check - and #CT_DIGIT ; digit? - beq L8 ; done + sec ; check if char is in digit space + sbc #'0' ; so subtract lower limit + tax ; remember this numeric value + cmp #10 ; and check if upper limit is not crossed + bcs L8 ; done ; Multiply ptr2 (the converted value) by 10 @@ -91,9 +92,7 @@ L6: lda (ptr1),y ; get next char ; Get the character back and add it - lda (ptr1),y ; fetch char again - sec - sbc #'0' ; make numeric value + txa ; restore numeric value back to accu clc adc ptr2 sta ptr2 diff --git a/libsrc/common/isascii.s b/libsrc/common/isascii.s index dccfabaa1..c15cc586d 100644 --- a/libsrc/common/isascii.s +++ b/libsrc/common/isascii.s @@ -13,15 +13,12 @@ .export _isascii _isascii: - cpx #$00 ; Char range ok? - bne @L1 ; Jump if no - - tay - bmi @L1 - - inx + asl a ; high-bit to carry + txa ; check range of input param + bne @L1 ; out-of bounds? + adc #$FF ; calculate return value based on carry rts -@L1: lda #$00 ; Return false +@L1: lda #$00 ; return false tax rts diff --git a/libsrc/common/strlower.s b/libsrc/common/strlower.s index 8c634b6e6..d4e481382 100644 --- a/libsrc/common/strlower.s +++ b/libsrc/common/strlower.s @@ -28,9 +28,8 @@ loop: lda (ptr1),y ; get character jsr ctype_preprocessor_no_check and #CT_UPPER ; upper case char? beq L1 ; jump if no - lda (ptr1),y ; fetch character again - sec - sbc #<('A'-'a') ; make lower case char + lda (ptr1),y ; fetch character again + adc #<('a'-'A') ; make lower case char (ctype_preprocessor_no_check ensures carry clear) sta (ptr1),y ; store back L1: iny ; next char bne loop diff --git a/libsrc/common/strupper.s b/libsrc/common/strupper.s index c07fb17c1..dd6c1c25f 100644 --- a/libsrc/common/strupper.s +++ b/libsrc/common/strupper.s @@ -28,8 +28,7 @@ loop: lda (ptr1),y ; get character and #CT_LOWER ; lower case char? beq L1 ; jump if no lda (ptr1),y ; fetch character again - clc - adc #<('A'-'a') ; make upper case char + adc #<('A'-'a') ; make upper case char (ctype_preprocessor_no_check ensures carry clear) sta (ptr1),y ; store back L1: iny ; next char bne loop From 08705a3fdc5050d284eb655e6efb2ab5664ca9a4 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sun, 2 Feb 2020 18:21:25 +0100 Subject: [PATCH 1265/2161] Changes resulting from 2nd code review --- asminc/ctype.inc | 2 +- asminc/ctype_common.inc | 2 +- asminc/ctypetable.inc | 50 +- libsrc/apple2/ctype.s | 5 - libsrc/atari/ctype.s | 2 +- libsrc/atmos/ctype.s | 2 +- libsrc/cbm/ctype.s | 2 +- .../common/ctype.s | 4 +- libsrc/common/ctype_preprocessor.s | 2 +- libsrc/common/isalnum.s | 2 +- libsrc/common/isalpha.s | 2 +- libsrc/common/isascii.s | 10 +- libsrc/common/isblank.s | 4 +- libsrc/common/iscntrl.s | 4 +- libsrc/common/isdigit.s | 2 +- libsrc/common/isgraph.s | 8 +- libsrc/common/islower.s | 4 +- libsrc/common/isprint.s | 4 +- libsrc/common/ispunct.s | 4 +- libsrc/common/isspace.s | 4 +- libsrc/common/isupper.s | 4 +- libsrc/common/isxdigit.s | 4 +- libsrc/common/mul20.s | 2 +- libsrc/common/mul40.s | 2 +- libsrc/common/stricmp.s | 10 +- libsrc/creativision/ctype.s | 5 - libsrc/gamate/ctype.s | 5 - libsrc/geos-common/system/ctype.s | 2 +- libsrc/lynx/ctype.s | 5 - libsrc/nes/ctype.s | 5 - libsrc/pce/ctype.s | 5 - test/val/lib_common_ctype.c | 606 +++++++++--------- 32 files changed, 372 insertions(+), 402 deletions(-) delete mode 100644 libsrc/apple2/ctype.s rename asminc/ctype_console.inc => libsrc/common/ctype.s (99%) delete mode 100644 libsrc/creativision/ctype.s delete mode 100644 libsrc/gamate/ctype.s delete mode 100644 libsrc/lynx/ctype.s delete mode 100644 libsrc/nes/ctype.s delete mode 100644 libsrc/pce/ctype.s diff --git a/asminc/ctype.inc b/asminc/ctype.inc index 299760789..18a290fbe 100644 --- a/asminc/ctype.inc +++ b/asminc/ctype.inc @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; diff --git a/asminc/ctype_common.inc b/asminc/ctype_common.inc index ffd8dfe0e..04aaa8f95 100644 --- a/asminc/ctype_common.inc +++ b/asminc/ctype_common.inc @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; diff --git a/asminc/ctypetable.inc b/asminc/ctypetable.inc index 7134d002e..76c5b9298 100644 --- a/asminc/ctypetable.inc +++ b/asminc/ctypetable.inc @@ -3,46 +3,46 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; ; Data covering all possible combinations of character flags for target specific definition ; -.include "ctype.inc" -.export __ctype +.include "ctype.inc" +.export __ctype ; Table definition covering all possible ctype combinations .rodata __ctype: -ct_none: .byte CT_NONE -ct_lower: .byte CT_LOWER -ct_upper: .byte CT_UPPER -ct_digit_xdigit: .byte CT_DIGIT | CT_XDIGIT -ct_lower_xdigit: .byte CT_LOWER | CT_XDIGIT -ct_upper_xdigit: .byte CT_UPPER | CT_XDIGIT -ct_ctrl: .byte CT_CTRL -ct_ws: .byte CT_OTHER_WS -ct_ctrl_ws: .byte CT_CTRL | CT_OTHER_WS -ct_space_spacetab: .byte CT_SPACE | CT_SPACE_TAB -ct_ctrl_ws_spacetab: .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB +ct_none: .byte CT_NONE +ct_lower: .byte CT_LOWER +ct_upper: .byte CT_UPPER +ct_digit_xdigit: .byte CT_DIGIT | CT_XDIGIT +ct_lower_xdigit: .byte CT_LOWER | CT_XDIGIT +ct_upper_xdigit: .byte CT_UPPER | CT_XDIGIT +ct_ctrl: .byte CT_CTRL +ct_ws: .byte CT_OTHER_WS +ct_ctrl_ws: .byte CT_CTRL | CT_OTHER_WS +ct_space_spacetab: .byte CT_SPACE | CT_SPACE_TAB +ct_ctrl_ws_spacetab: .byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB ; build indices out of the table above: -CT_NONE_IDX = ct_none - __ctype -CT_LOWER_IDX = ct_lower - __ctype -CT_UPPER_IDX = ct_upper - __ctype -CT_DIGIT_XDIGIT_IDX = ct_digit_xdigit - __ctype -CT_LOWER_XDIGIT_IDX = ct_lower_xdigit - __ctype -CT_UPPER_XDIGIT_IDX = ct_upper_xdigit - __ctype -CT_CTRL_IDX = ct_ctrl - __ctype -CT_WS_IDX = ct_ws - __ctype -CT_CTRL_WS_IDX = ct_ctrl_ws - __ctype -CT_SPACE_SPACETAB_IDX = ct_space_spacetab - __ctype +CT_NONE_IDX = ct_none - __ctype +CT_LOWER_IDX = ct_lower - __ctype +CT_UPPER_IDX = ct_upper - __ctype +CT_DIGIT_XDIGIT_IDX = ct_digit_xdigit - __ctype +CT_LOWER_XDIGIT_IDX = ct_lower_xdigit - __ctype +CT_UPPER_XDIGIT_IDX = ct_upper_xdigit - __ctype +CT_CTRL_IDX = ct_ctrl - __ctype +CT_WS_IDX = ct_ws - __ctype +CT_CTRL_WS_IDX = ct_ctrl_ws - __ctype +CT_SPACE_SPACETAB_IDX = ct_space_spacetab - __ctype CT_CTRL_WS_SPACETAB_IDX = ct_ctrl_ws_spacetab - __ctype .macro ct_mix lower, upper - .byte ((lower) & $0F) | ((upper) << 4) + .byte ((lower) & $0F) | ((upper) << 4) .endmacro diff --git a/libsrc/apple2/ctype.s b/libsrc/apple2/ctype.s deleted file mode 100644 index da4d38472..000000000 --- a/libsrc/apple2/ctype.s +++ /dev/null @@ -1,5 +0,0 @@ -; Character specification table. -; -; uses the "console" definition - - .include "ctype_console.inc" diff --git a/libsrc/atari/ctype.s b/libsrc/atari/ctype.s index 8173b2ea8..7903dc2a3 100644 --- a/libsrc/atari/ctype.s +++ b/libsrc/atari/ctype.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; diff --git a/libsrc/atmos/ctype.s b/libsrc/atmos/ctype.s index 3c3d7be5b..7ca01b32a 100644 --- a/libsrc/atmos/ctype.s +++ b/libsrc/atmos/ctype.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; diff --git a/libsrc/cbm/ctype.s b/libsrc/cbm/ctype.s index d0943b123..77a37431d 100644 --- a/libsrc/cbm/ctype.s +++ b/libsrc/cbm/ctype.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; diff --git a/asminc/ctype_console.inc b/libsrc/common/ctype.s similarity index 99% rename from asminc/ctype_console.inc rename to libsrc/common/ctype.s index 55db8e615..15f115e7d 100644 --- a/asminc/ctype_console.inc +++ b/libsrc/common/ctype.s @@ -1,9 +1,9 @@ -; ctype_console.inc +; ctype.s ; ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; diff --git a/libsrc/common/ctype_preprocessor.s b/libsrc/common/ctype_preprocessor.s index 1f33bd224..efa001e61 100644 --- a/libsrc/common/ctype_preprocessor.s +++ b/libsrc/common/ctype_preprocessor.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; diff --git a/libsrc/common/isalnum.s b/libsrc/common/isalnum.s index 4f6a5e91b..141949c0f 100644 --- a/libsrc/common/isalnum.s +++ b/libsrc/common/isalnum.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; diff --git a/libsrc/common/isalpha.s b/libsrc/common/isalpha.s index a331722a1..95e799161 100644 --- a/libsrc/common/isalpha.s +++ b/libsrc/common/isalpha.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; diff --git a/libsrc/common/isascii.s b/libsrc/common/isascii.s index c15cc586d..70d2f72a3 100644 --- a/libsrc/common/isascii.s +++ b/libsrc/common/isascii.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; @@ -13,10 +13,10 @@ .export _isascii _isascii: - asl a ; high-bit to carry - txa ; check range of input param - bne @L1 ; out-of bounds? - adc #$FF ; calculate return value based on carry + asl a ; high-bit to carry + txa ; check range of input param + bne @L1 ; out-of bounds? + adc #$FF ; calculate return value based on carry rts @L1: lda #$00 ; return false diff --git a/libsrc/common/isblank.s b/libsrc/common/isblank.s index 5e0eafd73..3d0a02f3d 100644 --- a/libsrc/common/isblank.s +++ b/libsrc/common/isblank.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; @@ -14,7 +14,7 @@ .export _isblank .include "ctype.inc" - .import ctype_preprocessor + .import ctype_preprocessor _isblank: jsr ctype_preprocessor ; (clears always x) diff --git a/libsrc/common/iscntrl.s b/libsrc/common/iscntrl.s index f4bf02858..f2b95042d 100644 --- a/libsrc/common/iscntrl.s +++ b/libsrc/common/iscntrl.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; @@ -12,7 +12,7 @@ .export _iscntrl .include "ctype.inc" - .import ctype_preprocessor + .import ctype_preprocessor _iscntrl: jsr ctype_preprocessor ; (clears always x) diff --git a/libsrc/common/isdigit.s b/libsrc/common/isdigit.s index c0e8bb026..36acd73b7 100644 --- a/libsrc/common/isdigit.s +++ b/libsrc/common/isdigit.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; diff --git a/libsrc/common/isgraph.s b/libsrc/common/isgraph.s index 575b05a62..4e317db57 100644 --- a/libsrc/common/isgraph.s +++ b/libsrc/common/isgraph.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; @@ -17,9 +17,9 @@ _isgraph: jsr ctype_preprocessor ; (clears always x) bcs @L1 ; out of range? (everything already clear -> false) - and #CT_CTRL_SPACE ; mask character bits - cmp #1 ; if false, then set "borrow" flag + and #CT_CTRL_SPACE ; mask character bits + cmp #1 ; if false, then set "borrow" flag lda #0 - sbc #0 ; invert logic (return NOT control and NOT space) + sbc #0 ; invert logic (return NOT control and NOT space) @L1: rts diff --git a/libsrc/common/islower.s b/libsrc/common/islower.s index 62ae41643..608d0ccf4 100644 --- a/libsrc/common/islower.s +++ b/libsrc/common/islower.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; @@ -12,7 +12,7 @@ .export _islower .include "ctype.inc" - .import ctype_preprocessor + .import ctype_preprocessor _islower: jsr ctype_preprocessor ; (clears always x) diff --git a/libsrc/common/isprint.s b/libsrc/common/isprint.s index cbe68c801..0d135f24f 100644 --- a/libsrc/common/isprint.s +++ b/libsrc/common/isprint.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; @@ -12,7 +12,7 @@ .export _isprint .include "ctype.inc" - .import ctype_preprocessor + .import ctype_preprocessor _isprint: jsr ctype_preprocessor ; (clears always x) diff --git a/libsrc/common/ispunct.s b/libsrc/common/ispunct.s index ad48fc534..a532399fe 100644 --- a/libsrc/common/ispunct.s +++ b/libsrc/common/ispunct.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; @@ -12,7 +12,7 @@ .export _ispunct .include "ctype.inc" - .import ctype_preprocessor + .import ctype_preprocessor _ispunct: jsr ctype_preprocessor ; (clears always x) diff --git a/libsrc/common/isspace.s b/libsrc/common/isspace.s index 272acac0c..1f70786ce 100644 --- a/libsrc/common/isspace.s +++ b/libsrc/common/isspace.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; @@ -12,7 +12,7 @@ .export _isspace .include "ctype.inc" - .import ctype_preprocessor + .import ctype_preprocessor _isspace: jsr ctype_preprocessor ; (clears always x) diff --git a/libsrc/common/isupper.s b/libsrc/common/isupper.s index 2d89459a0..0dd2a6ead 100644 --- a/libsrc/common/isupper.s +++ b/libsrc/common/isupper.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; @@ -12,7 +12,7 @@ .export _isupper .include "ctype.inc" - .import ctype_preprocessor + .import ctype_preprocessor _isupper: jsr ctype_preprocessor ; (clears always x) diff --git a/libsrc/common/isxdigit.s b/libsrc/common/isxdigit.s index 07fef5c2b..3f36ede01 100644 --- a/libsrc/common/isxdigit.s +++ b/libsrc/common/isxdigit.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; @@ -12,7 +12,7 @@ .export _isxdigit .include "ctype.inc" - .import ctype_preprocessor + .import ctype_preprocessor _isxdigit: jsr ctype_preprocessor ; (clears always x) diff --git a/libsrc/common/mul20.s b/libsrc/common/mul20.s index 4035b9476..5b3bbf830 100644 --- a/libsrc/common/mul20.s +++ b/libsrc/common/mul20.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; diff --git a/libsrc/common/mul40.s b/libsrc/common/mul40.s index f240fc41a..07d6164b5 100644 --- a/libsrc/common/mul40.s +++ b/libsrc/common/mul40.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; diff --git a/libsrc/common/stricmp.s b/libsrc/common/stricmp.s index e1683d9f3..3a03258bd 100644 --- a/libsrc/common/stricmp.s +++ b/libsrc/common/stricmp.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; @@ -27,7 +27,7 @@ _strcasecmp: loop: lda (ptr2),y ; get char from second string sta tmp2 ; and save it ; get character classification - jsr ctype_preprocessor_no_check + jsr ctype_preprocessor_no_check and #CT_LOWER ; lower case char? beq L1 ; jump if no lda #<('A'-'a') ; make upper case char @@ -37,13 +37,13 @@ loop: lda (ptr2),y ; get char from second string L1: lda (ptr1),y ; get character from first string sta tmp1 ; get character classification - jsr ctype_preprocessor_no_check + jsr ctype_preprocessor_no_check and #CT_LOWER ; lower case char? beq L2 ; jump if no lda #<('A'-'a') ; make upper case char adc tmp1 ; ctype_preprocessor_no_check ensures carry clear! - sta tmp1 ; remember upper case equivalent - + sta tmp1 ; remember upper case equivalent + L2: ldx tmp1 cpx tmp2 ; compare characters bne L3 diff --git a/libsrc/creativision/ctype.s b/libsrc/creativision/ctype.s deleted file mode 100644 index da4d38472..000000000 --- a/libsrc/creativision/ctype.s +++ /dev/null @@ -1,5 +0,0 @@ -; Character specification table. -; -; uses the "console" definition - - .include "ctype_console.inc" diff --git a/libsrc/gamate/ctype.s b/libsrc/gamate/ctype.s deleted file mode 100644 index da4d38472..000000000 --- a/libsrc/gamate/ctype.s +++ /dev/null @@ -1,5 +0,0 @@ -; Character specification table. -; -; uses the "console" definition - - .include "ctype_console.inc" diff --git a/libsrc/geos-common/system/ctype.s b/libsrc/geos-common/system/ctype.s index a50ad1635..013a1ba99 100644 --- a/libsrc/geos-common/system/ctype.s +++ b/libsrc/geos-common/system/ctype.s @@ -3,7 +3,7 @@ ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems ; -; https://github.com/cc65/cc65 +; https://cc65.github.io ; ; See "LICENSE" file for legal information. ; diff --git a/libsrc/lynx/ctype.s b/libsrc/lynx/ctype.s deleted file mode 100644 index da4d38472..000000000 --- a/libsrc/lynx/ctype.s +++ /dev/null @@ -1,5 +0,0 @@ -; Character specification table. -; -; uses the "console" definition - - .include "ctype_console.inc" diff --git a/libsrc/nes/ctype.s b/libsrc/nes/ctype.s deleted file mode 100644 index da4d38472..000000000 --- a/libsrc/nes/ctype.s +++ /dev/null @@ -1,5 +0,0 @@ -; Character specification table. -; -; uses the "console" definition - - .include "ctype_console.inc" diff --git a/libsrc/pce/ctype.s b/libsrc/pce/ctype.s deleted file mode 100644 index da4d38472..000000000 --- a/libsrc/pce/ctype.s +++ /dev/null @@ -1,5 +0,0 @@ -; Character specification table. -; -; uses the "console" definition - - .include "ctype_console.inc" diff --git a/test/val/lib_common_ctype.c b/test/val/lib_common_ctype.c index 15980aff1..39c92953b 100644 --- a/test/val/lib_common_ctype.c +++ b/test/val/lib_common_ctype.c @@ -3,7 +3,7 @@ // This file is part of // cc65 - a freeware C compiler for 6502 based systems // -// https://github.com/cc65/cc65 +// https://cc65.github.io // // See "LICENSE" file for legal information. // @@ -18,19 +18,19 @@ typedef struct { - bool isalnum; - bool isalpha; - bool isascii; - bool iscntrl; - bool isdigit; - bool isgraph; - bool islower; - bool isprint; - bool ispunct; - bool isspace; - bool isupper; - bool isxdigit; - bool isblank; + bool isalnum; + bool isalpha; + bool isascii; + bool iscntrl; + bool isdigit; + bool isgraph; + bool islower; + bool isprint; + bool ispunct; + bool isspace; + bool isupper; + bool isxdigit; + bool isblank; } CTypeClassifications; @@ -39,330 +39,330 @@ CTypeClassifications testSet[NUMTESTS] = { //alnum, alpha, ascii, cntrl, digit, graph, lower, print, punct, space, upper, xdigit,blank - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 00 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 01 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 02 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 03 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 04 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 05 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 06 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 07 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 08 - {false, false, true, true, false, false, false, false, false, true, false, false, true }, // 09 - {false, false, true, true, false, false, false, false, false, true, false, false, false}, // 0A - {false, false, true, true, false, false, false, false, false, true, false, false, false}, // 0B - {false, false, true, true, false, false, false, false, false, true, false, false, false}, // 0C - {false, false, true, true, false, false, false, false, false, true, false, false, false}, // 0D - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 0E - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 0F + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 00 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 01 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 02 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 03 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 04 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 05 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 06 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 07 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 08 + {false, false, true, true, false, false, false, false, false, true, false, false, true }, // 09 + {false, false, true, true, false, false, false, false, false, true, false, false, false}, // 0A + {false, false, true, true, false, false, false, false, false, true, false, false, false}, // 0B + {false, false, true, true, false, false, false, false, false, true, false, false, false}, // 0C + {false, false, true, true, false, false, false, false, false, true, false, false, false}, // 0D + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 0E + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 0F - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 10 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 11 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 12 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 13 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 14 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 15 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 16 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 17 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 18 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 19 - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1A - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1B - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1C - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1D - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1E - {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1F + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 10 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 11 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 12 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 13 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 14 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 15 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 16 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 17 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 18 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 19 + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1A + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1B + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1C + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1D + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1E + {false, false, true, true, false, false, false, false, false, false, false, false, false}, // 1F - {false, false, true, false, false, false, false, true, false, true, false, false, true }, // 20 - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 21 - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 22 - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 23 - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 24 - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 25 - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 26 - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 27 - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 28 - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 29 - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2A - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2B - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2C - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2D - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2E - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2F + {false, false, true, false, false, false, false, true, false, true, false, false, true }, // 20 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 21 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 22 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 23 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 24 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 25 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 26 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 27 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 28 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 29 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2A + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2B + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2C + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2D + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2E + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 2F - {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 30 - {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 31 - {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 32 - {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 33 - {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 34 - {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 35 - {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 36 - {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 37 - {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 38 - {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 39 - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3A - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3B - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3C - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3D - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3E - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3F + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 30 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 31 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 32 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 33 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 34 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 35 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 36 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 37 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 38 + {true, false, true, false, true, true, false, true, false, false, false, true, false}, // 39 + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3A + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3B + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3C + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3D + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3E + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 3F - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 40 - {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 41 - {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 42 - {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 43 - {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 44 - {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 45 - {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 46 - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 47 - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 48 - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 49 - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4A - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4B - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4C - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4D - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4E - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4F + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 40 + {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 41 + {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 42 + {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 43 + {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 44 + {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 45 + {true, true, true, false, false, true, false, true, false, false, true, true, false}, // 46 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 47 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 48 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 49 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4A + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4B + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4C + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4D + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4E + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 4F - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 50 - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 51 - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 52 - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 53 - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 54 - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 55 - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 56 - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 57 - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 58 - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 59 - {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 5A - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 5B - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 5C - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 5D - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 5E - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 5F + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 50 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 51 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 52 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 53 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 54 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 55 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 56 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 57 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 58 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 59 + {true, true, true, false, false, true, false, true, false, false, true, false, false}, // 5A + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 5B + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 5C + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 5D + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 5E + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 5F - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 60 - {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 61 - {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 62 - {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 63 - {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 64 - {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 65 - {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 66 - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 67 - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 68 - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 69 - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6A - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6B - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6C - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6D - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6E - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6F + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 60 + {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 61 + {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 62 + {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 63 + {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 64 + {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 65 + {true, true, true, false, false, true, true, true, false, false, false, true, false}, // 66 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 67 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 68 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 69 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6A + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6B + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6C + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6D + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6E + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 6F - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 70 - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 71 - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 72 - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 73 - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 74 - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 75 - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 76 - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 77 - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 78 - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 79 - {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 7A - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 7B - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 7C - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 7D - {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 7E - {false, false, true, false, false, true, false, true, true, true, false, false, false}, // 7F + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 70 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 71 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 72 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 73 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 74 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 75 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 76 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 77 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 78 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 79 + {true, true, true, false, false, true, true, true, false, false, false, false, false}, // 7A + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 7B + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 7C + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 7D + {false, false, true, false, false, true, false, true, true, false, false, false, false}, // 7E + {false, false, true, false, false, true, false, true, true, true, false, false, false}, // 7F - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 80 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 81 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 82 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 83 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 84 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 85 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 86 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 87 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 88 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 89 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8A - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8B - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8C - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8D - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8E - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8F + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 80 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 81 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 82 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 83 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 84 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 85 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 86 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 87 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 88 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 89 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8A + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8B + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8C + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8D + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8E + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 8F - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 90 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 91 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 92 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 93 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 94 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 95 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 96 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 97 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 98 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 99 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9A - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9B - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9C - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9D - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9E - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9F + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 90 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 91 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 92 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 93 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 94 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 95 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 96 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 97 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 98 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 99 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9A + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9B + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9C + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9D + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9E + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // 9F - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A0 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A1 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A2 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A3 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A4 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A5 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A6 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A7 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A8 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A9 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AA - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AB - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AC - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AD - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AE - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AF + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A0 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A1 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A2 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A3 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A4 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A5 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A6 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A7 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A8 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // A9 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AA + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AB + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AC + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AD + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AE + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // AF - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B0 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B1 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B2 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B3 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B4 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B5 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B6 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B7 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B8 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B9 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BA - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BB - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BC - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BD - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BE - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BF + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B0 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B1 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B2 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B3 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B4 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B5 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B6 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B7 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B8 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // B9 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BA + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BB + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BC + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BD + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BE + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // BF - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C0 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C1 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C2 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C3 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C4 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C5 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C6 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C7 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C8 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C9 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CA - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CB - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CC - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CD - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CE - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CF + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C0 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C1 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C2 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C3 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C4 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C5 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C6 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C7 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C8 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // C9 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CA + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CB + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CC + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CD + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CE + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // CF - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D0 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D1 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D2 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D3 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D4 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D5 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D6 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D7 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D8 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D9 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DA - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DB - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DC - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DD - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DE - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DF + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D0 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D1 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D2 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D3 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D4 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D5 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D6 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D7 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D8 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // D9 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DA + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DB + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DC + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DD + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DE + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // DF - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E0 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E1 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E2 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E3 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E4 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E5 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E6 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E7 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E8 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E9 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // EA - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // EB - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // EC - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // ED - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // EE - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // EF + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E0 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E1 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E2 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E3 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E4 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E5 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E6 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E7 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E8 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // E9 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // EA + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // EB + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // EC + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // ED + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // EE + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // EF - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F0 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F1 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F2 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F3 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F4 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F5 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F6 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F7 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F8 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F9 - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FA - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FB - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FC - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FD - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FE - {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FF + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F0 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F1 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F2 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F3 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F4 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F5 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F6 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F7 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F8 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // F9 + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FA + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FB + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FC + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FD + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FE + {false, false, false, false, false, true, false, true, true, false, false, false, false}, // FF - // out of range test - {false, false, false, false, false, false, false, false, false, false, false, false, false} // 100 + // out of range test + {false, false, false, false, false, false, false, false, false, false, false, false, false} // 100 }; TEST { - int i = 0; + int i = 0; - while (i<NUMTESTS) - { - // isalnum() - ASSERT_AreEqual(testSet[i].isalnum, (isalnum(i) ? true : false), "%d", "Invalid 'isalnum(%d)' classification!" COMMA i); + while (i<NUMTESTS) + { + // isalnum() + ASSERT_AreEqual(testSet[i].isalnum, (isalnum(i) ? true : false), "%d", "Invalid 'isalnum(%d)' classification!" COMMA i); - // isalpha() - ASSERT_AreEqual(testSet[i].isalpha, (isalpha(i) ? true : false), "%d", "Invalid 'isalpha(%d)' classification!" COMMA i); + // isalpha() + ASSERT_AreEqual(testSet[i].isalpha, (isalpha(i) ? true : false), "%d", "Invalid 'isalpha(%d)' classification!" COMMA i); - // isascii() - ASSERT_AreEqual(testSet[i].isascii, (isascii(i) ? true : false), "%d", "Invalid 'isascii(%d)' classification!" COMMA i); + // isascii() + ASSERT_AreEqual(testSet[i].isascii, (isascii(i) ? true : false), "%d", "Invalid 'isascii(%d)' classification!" COMMA i); - // iscntrl() - ASSERT_AreEqual(testSet[i].iscntrl, (iscntrl(i) ? true : false), "%d", "Invalid 'iscntrl(%d)' classification!" COMMA i); + // iscntrl() + ASSERT_AreEqual(testSet[i].iscntrl, (iscntrl(i) ? true : false), "%d", "Invalid 'iscntrl(%d)' classification!" COMMA i); - // isdigit() - ASSERT_AreEqual(testSet[i].isdigit, (isdigit(i) ? true : false), "%d", "Invalid 'isdigit(%d)' classification!" COMMA i); + // isdigit() + ASSERT_AreEqual(testSet[i].isdigit, (isdigit(i) ? true : false), "%d", "Invalid 'isdigit(%d)' classification!" COMMA i); - // isgraph() - ASSERT_AreEqual(testSet[i].isgraph, (isgraph(i) ? true : false), "%d", "Invalid 'isgraph(%d)' classification!" COMMA i); + // isgraph() + ASSERT_AreEqual(testSet[i].isgraph, (isgraph(i) ? true : false), "%d", "Invalid 'isgraph(%d)' classification!" COMMA i); - // islower() - ASSERT_AreEqual(testSet[i].islower, (islower(i) ? true : false), "%d", "Invalid 'islower(%d)' classification!" COMMA i); + // islower() + ASSERT_AreEqual(testSet[i].islower, (islower(i) ? true : false), "%d", "Invalid 'islower(%d)' classification!" COMMA i); - // isprint() - ASSERT_AreEqual(testSet[i].isprint, (isprint(i) ? true : false), "%d", "Invalid 'isprint(%d)' classification!" COMMA i); + // isprint() + ASSERT_AreEqual(testSet[i].isprint, (isprint(i) ? true : false), "%d", "Invalid 'isprint(%d)' classification!" COMMA i); - // ispunct() - ASSERT_AreEqual(testSet[i].ispunct, (ispunct(i) ? true : false), "%d", "Invalid 'ispunct(%d)' classification!" COMMA i); + // ispunct() + ASSERT_AreEqual(testSet[i].ispunct, (ispunct(i) ? true : false), "%d", "Invalid 'ispunct(%d)' classification!" COMMA i); - // isspace() - ASSERT_AreEqual(testSet[i].isspace, (isspace(i) ? true : false), "%d", "Invalid 'isspace(%d)' classification!" COMMA i); + // isspace() + ASSERT_AreEqual(testSet[i].isspace, (isspace(i) ? true : false), "%d", "Invalid 'isspace(%d)' classification!" COMMA i); - // isupper() - ASSERT_AreEqual(testSet[i].isupper, (isupper(i) ? true : false), "%d", "Invalid 'isupper(%d)' classification!" COMMA i); + // isupper() + ASSERT_AreEqual(testSet[i].isupper, (isupper(i) ? true : false), "%d", "Invalid 'isupper(%d)' classification!" COMMA i); - // isxdigit() - ASSERT_AreEqual(testSet[i].isxdigit, (isxdigit(i) ? true : false), "%d", "Invalid 'isxdigit(%d)' classification!" COMMA i); + // isxdigit() + ASSERT_AreEqual(testSet[i].isxdigit, (isxdigit(i) ? true : false), "%d", "Invalid 'isxdigit(%d)' classification!" COMMA i); #if __CC65_STD__ >= __CC65_STD_C99__ - // isblank() - ASSERT_AreEqual(testSet[i].isblank, (isblank(i) ? true : false), "%d", "Invalid 'isblank(%d)' classification!" COMMA i); + // isblank() + ASSERT_AreEqual(testSet[i].isblank, (isblank(i) ? true : false), "%d", "Invalid 'isblank(%d)' classification!" COMMA i); #endif - ++i; - } + ++i; + } } ENDTEST From 026e57279de2aead494c93081f0a645aecbb39ae Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Fri, 24 Jan 2020 22:28:53 +0100 Subject: [PATCH 1266/2161] Fix bug in tgi_line : HRS(X) parameters are 16 bits. --- libsrc/telestrat/tgi/telestrat-228-200-3.s | 8 +++++++- libsrc/telestrat/tgi/telestrat-240-200-2.s | 9 ++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/libsrc/telestrat/tgi/telestrat-228-200-3.s b/libsrc/telestrat/tgi/telestrat-228-200-3.s index 228bdce99..c8c569695 100644 --- a/libsrc/telestrat/tgi/telestrat-228-200-3.s +++ b/libsrc/telestrat/tgi/telestrat-228-200-3.s @@ -297,7 +297,13 @@ LINE: lda Y2 sta HRS4 - lda #$ff + lda #$00 + sta HRS1+1 + sta HRS2+1 + sta HRS3+1 + sta HRS4+1 + + lda #$FF sta HRSPAT BRK_TELEMON(XDRAWA) diff --git a/libsrc/telestrat/tgi/telestrat-240-200-2.s b/libsrc/telestrat/tgi/telestrat-240-200-2.s index 9bffebb0c..128003bfd 100644 --- a/libsrc/telestrat/tgi/telestrat-240-200-2.s +++ b/libsrc/telestrat/tgi/telestrat-240-200-2.s @@ -290,7 +290,14 @@ LINE: lda Y2 sta HRS4 - lda #$ff + + lda #$00 + sta HRS1+1 + sta HRS2+1 + sta HRS3+1 + sta HRS4+1 + + lda #$FF sta HRSPAT BRK_TELEMON(XDRAWA) From 0962a9f286b483d35cd854ad1091115e47f9c2e8 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Tue, 28 Jan 2020 13:24:06 +0100 Subject: [PATCH 1267/2161] Fix 16 bits values --- libsrc/telestrat/tgi/telestrat-228-200-3.s | 12 +++++++++--- libsrc/telestrat/tgi/telestrat-240-200-2.s | 8 +++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/libsrc/telestrat/tgi/telestrat-228-200-3.s b/libsrc/telestrat/tgi/telestrat-228-200-3.s index c8c569695..34af597eb 100644 --- a/libsrc/telestrat/tgi/telestrat-228-200-3.s +++ b/libsrc/telestrat/tgi/telestrat-228-200-3.s @@ -296,12 +296,18 @@ LINE: sta HRS3 lda Y2 sta HRS4 - - lda #$00 + + lda X1+1 sta HRS1+1 + + lda Y1+1 sta HRS2+1 + + lda X2+1 sta HRS3+1 - sta HRS4+1 + + lda Y2+1 + sta HRS4+1 lda #$FF sta HRSPAT diff --git a/libsrc/telestrat/tgi/telestrat-240-200-2.s b/libsrc/telestrat/tgi/telestrat-240-200-2.s index 128003bfd..345f80e0e 100644 --- a/libsrc/telestrat/tgi/telestrat-240-200-2.s +++ b/libsrc/telestrat/tgi/telestrat-240-200-2.s @@ -291,10 +291,16 @@ LINE: sta HRS4 - lda #$00 + lda X1+1 sta HRS1+1 + + lda Y1+1 sta HRS2+1 + + lda X2+1 sta HRS3+1 + + lda Y2+1 sta HRS4+1 lda #$FF From 857a566a2ee2202a392471fd86e4129c9076d695 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 17 Feb 2020 11:07:52 +0100 Subject: [PATCH 1268/2161] Normalized Atari naming. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b3ea342e..3d78fda50 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ including - the 600/700 family - newer PET machines (not 2001). - the Apple ]\[+ and successors. -- the Atari 8 bit machines. +- the Atari 8-bit machines. - the Atari 2600 console. - the Atari 5200 console. - GEOS for the C64, C128 and Apple //e. From e2c664860781747eb247770bc766c7f0c5351a62 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 21 Feb 2020 08:12:05 -0500 Subject: [PATCH 1269/2161] Fixed a typo in commit 2e5fbe89cd3f67b06b292936dfdf4fdb104b7112. Changed a && to ||. --- 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 c1ff400b8..b4c5c8dfe 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -104,7 +104,7 @@ int ValidAddrSizeForCPU (unsigned char AddrSize) case ADDR_SIZE_FAR: /* Supported by "none" and 65816 */ - return (CPU == CPU_NONE && CPU == CPU_65816); + return (CPU == CPU_NONE || CPU == CPU_65816); case ADDR_SIZE_LONG: /* "none" supports all sizes */ From b91ad02da1759ddc81d484fe0bfc4d0aaf98b897 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 5 Mar 2020 14:38:12 +0100 Subject: [PATCH 1270/2161] Made use of 65C02 opcode (thx to polluks). --- libsrc/apple2/videomode.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/apple2/videomode.s b/libsrc/apple2/videomode.s index 65e582547..13151a48a 100644 --- a/libsrc/apple2/videomode.s +++ b/libsrc/apple2/videomode.s @@ -62,7 +62,7 @@ _videomode: done: lda #$11 ; Ctrl-char code for 40 cols plp bpl :+ - lda #$12 ; Ctrl-char code for 80 cols + inc a ; Ctrl-char code for 80 cols : rts ; X was preserved all the way .endif ; __APPLE2ENH__ From 2fc24847acc0e7d8718059f33b1d431d557050ef Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 11 Mar 2020 17:28:42 -0400 Subject: [PATCH 1271/2161] Fixed an error message printer. The disassembler can be built and won't crash if it sees duplicate labels, and one of them is an unnamed label. --- src/da65/labels.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/da65/labels.c b/src/da65/labels.c index 97e195ebf..542205c11 100644 --- a/src/da65/labels.c +++ b/src/da65/labels.c @@ -97,7 +97,9 @@ static void AddLabel (unsigned Addr, attr_t Attr, const char* Name) strcmp (SymTab[Addr], Name) == 0))) { return; } - Error ("Duplicate label for address $%04X: %s/%s", Addr, SymTab[Addr], Name); + Error ("Duplicate label for address $%04X (%s): '%s'", Addr, + SymTab[Addr] == 0 ? "<unnamed label>" : SymTab[Addr], + Name == 0 ? "<unnamed label>" : Name); } /* Create a new label (xstrdup will return NULL if input NULL) */ From e0cb33d9d486fe7e8c48d89a61ca4caff239d2e4 Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Sat, 21 Mar 2020 17:11:20 -0400 Subject: [PATCH 1272/2161] SEGMENT start of 0 should be valid --- src/ld65/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ld65/config.c b/src/ld65/config.c index b8699a87b..6606f6976 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -753,7 +753,7 @@ static void ParseSegments (void) case CFGTOK_START: FlagAttr (&S->Attr, SA_START, "START"); - S->Addr = CfgCheckedConstExpr (1, 0x1000000); + S->Addr = CfgCheckedConstExpr (0, 0x1000000); S->Flags |= SF_START; break; From beaa77d2d6c119da0251de254bc1b8b751129a7a Mon Sep 17 00:00:00 2001 From: Dirk Jagdmann <doj@cubic.org> Date: Mon, 23 Mar 2020 03:04:48 -0700 Subject: [PATCH 1273/2161] fix whitespace --- doc/coding.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/coding.sgml b/doc/coding.sgml index dc07c091a..57961209f 100644 --- a/doc/coding.sgml +++ b/doc/coding.sgml @@ -251,7 +251,7 @@ Register variables may give faster and shorter code, but they do also have an overhead. Register variables are actually zero page locations, so using them saves roughly one cycle per access. The calling routine may also use register variables, so the old values have to be saved on function entry and restored -on exit. Saving an d restoring has an overhead of about 70 cycles per 2 byte +on exit. Saving and restoring has an overhead of about 70 cycles per 2 byte variable. It is easy to see, that - apart from the additional code that is needed to save and restore the values - you need to make heavy use of a variable to justify the overhead. From 62eb3137abee926ed25e87574d6c1882c6c634df Mon Sep 17 00:00:00 2001 From: Jeremy Rand <jeremy@rand-family.com> Date: Tue, 24 Mar 2020 23:39:57 -0400 Subject: [PATCH 1274/2161] Update get_ostype.s Do not check $fbbe when detecting the Apple //e card. This byte is a version number for the Apple //e card according to misc technote #7 and it appears that the last version of the software that I am aware of has a 3 at this location. Prior to this change, Apple //e cards which we not version 0 would be detected as an Apple //e enhanced. --- libsrc/apple2/get_ostype.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/apple2/get_ostype.s b/libsrc/apple2/get_ostype.s index b54e38d63..192fa360a 100644 --- a/libsrc/apple2/get_ostype.s +++ b/libsrc/apple2/get_ostype.s @@ -36,7 +36,7 @@ index: .byte $B3, $00 ; Apple ][ .byte $B3, $1E, $00 ; Apple ][+ .byte $B3, $1E, $00 ; Apple /// (emulation) .byte $B3, $C0, $00 ; Apple //e - .byte $B3, $C0, $DD, $BE, $00 ; Apple //e Option Card + .byte $B3, $C0, $DD, $00 ; Apple //e Option Card .byte $B3, $C0, $00 ; Apple //e (enhanced) .byte $B3, $C0, $BF, $00 ; Apple //c .byte $B3, $C0, $BF, $00 ; Apple //c (3.5 ROM) @@ -49,7 +49,7 @@ value: .byte $38, $10 ; Apple ][ .byte $EA, $AD, $11 ; Apple ][+ .byte $EA, $8A, $20 ; Apple /// (emulation) .byte $06, $EA, $30 ; Apple //e - .byte $06, $E0, $02, $00, $40 ; Apple //e Option Card + .byte $06, $E0, $02, $40 ; Apple //e Option Card .byte $06, $E0, $31 ; Apple //e (enhanced) .byte $06, $00, $FF, $50 ; Apple //c .byte $06, $00, $00, $51 ; Apple //c (3.5 ROM) From a53bd345d855fdc175ed050cb4cd5b63427143fe Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 26 Mar 2020 12:29:56 +0100 Subject: [PATCH 1275/2161] Adjusted comments due to recent change. --- libsrc/apple2/get_ostype.s | 44 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/libsrc/apple2/get_ostype.s b/libsrc/apple2/get_ostype.s index 192fa360a..dd44aa831 100644 --- a/libsrc/apple2/get_ostype.s +++ b/libsrc/apple2/get_ostype.s @@ -32,30 +32,30 @@ next: inx bne :- beq next ; Branch always -index: .byte $B3, $00 ; Apple ][ - .byte $B3, $1E, $00 ; Apple ][+ - .byte $B3, $1E, $00 ; Apple /// (emulation) - .byte $B3, $C0, $00 ; Apple //e - .byte $B3, $C0, $DD, $00 ; Apple //e Option Card - .byte $B3, $C0, $00 ; Apple //e (enhanced) - .byte $B3, $C0, $BF, $00 ; Apple //c - .byte $B3, $C0, $BF, $00 ; Apple //c (3.5 ROM) - .byte $B3, $C0, $BF, $00 ; Apple //c (Mem. Exp.) - .byte $B3, $C0, $BF, $00 ; Apple //c (Rev. Mem. Exp.) - .byte $B3, $C0, $BF, $00 ; Apple //c Plus +index: .byte $B3, $00 ; Apple ][ + .byte $B3, $1E, $00 ; Apple ][+ + .byte $B3, $1E, $00 ; Apple /// (emulation) + .byte $B3, $C0, $00 ; Apple //e + .byte $B3, $C0, $DD, $00 ; Apple //e Option Card + .byte $B3, $C0, $00 ; Apple //e (enhanced) + .byte $B3, $C0, $BF, $00 ; Apple //c + .byte $B3, $C0, $BF, $00 ; Apple //c (3.5 ROM) + .byte $B3, $C0, $BF, $00 ; Apple //c (Mem. Exp.) + .byte $B3, $C0, $BF, $00 ; Apple //c (Rev. Mem. Exp.) + .byte $B3, $C0, $BF, $00 ; Apple //c Plus .byte $00 -value: .byte $38, $10 ; Apple ][ - .byte $EA, $AD, $11 ; Apple ][+ - .byte $EA, $8A, $20 ; Apple /// (emulation) - .byte $06, $EA, $30 ; Apple //e - .byte $06, $E0, $02, $40 ; Apple //e Option Card - .byte $06, $E0, $31 ; Apple //e (enhanced) - .byte $06, $00, $FF, $50 ; Apple //c - .byte $06, $00, $00, $51 ; Apple //c (3.5 ROM) - .byte $06, $00, $03, $53 ; Apple //c (Mem. Exp.) - .byte $06, $00, $04, $54 ; Apple //c (Rev. Mem. Exp.) - .byte $06, $00, $05, $55 ; Apple //c Plus +value: .byte $38, $10 ; Apple ][ + .byte $EA, $AD, $11 ; Apple ][+ + .byte $EA, $8A, $20 ; Apple /// (emulation) + .byte $06, $EA, $30 ; Apple //e + .byte $06, $E0, $02, $40 ; Apple //e Option Card + .byte $06, $E0, $31 ; Apple //e (enhanced) + .byte $06, $00, $FF, $50 ; Apple //c + .byte $06, $00, $00, $51 ; Apple //c (3.5 ROM) + .byte $06, $00, $03, $53 ; Apple //c (Mem. Exp.) + .byte $06, $00, $04, $54 ; Apple //c (Rev. Mem. Exp.) + .byte $06, $00, $05, $55 ; Apple //c Plus .byte $00 .code From 68ff89ba0a36b7d5d57d64077dfbb477215fd74a Mon Sep 17 00:00:00 2001 From: "marko.lauke" <marko.lauke@googlemail.com> Date: Fri, 13 Mar 2020 00:42:27 +0100 Subject: [PATCH 1276/2161] +cc65 inline asm stp mnemonic support --- src/cc65/codeent.c | 3 +++ src/cc65/opcodes.c | 7 +++++++ src/cc65/opcodes.h | 1 + 3 files changed, 11 insertions(+) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index 729248e95..7df164cc3 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -615,6 +615,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) case OP65_BRK: break; + case OP65_STP: + break; + case OP65_BVC: break; diff --git a/src/cc65/opcodes.c b/src/cc65/opcodes.c index a7b91ca9a..792b92f7c 100644 --- a/src/cc65/opcodes.c +++ b/src/cc65/opcodes.c @@ -502,6 +502,13 @@ const OPCDesc OPCTable[OP65_COUNT] = { REG_NONE, /* chg */ OF_STORE /* flags */ }, + { OP65_STP, /* opcode */ + "stp", /* mnemonic */ + 1, /* size */ + REG_NONE, /* use */ + REG_NONE, /* chg */ + OF_NONE /* flags */ + }, { OP65_STX, /* opcode */ "stx", /* mnemonic */ 0, /* size */ diff --git a/src/cc65/opcodes.h b/src/cc65/opcodes.h index 0d191f6c7..8267d9550 100644 --- a/src/cc65/opcodes.h +++ b/src/cc65/opcodes.h @@ -114,6 +114,7 @@ typedef enum { OP65_SED, OP65_SEI, OP65_STA, + OP65_STP, /* 65c02, 65816 stop */ OP65_STX, OP65_STY, OP65_STZ, From 3e1284093359f1b57a1032f5708e76d9ca43ff2c Mon Sep 17 00:00:00 2001 From: "marko.lauke" <marko.lauke@googlemail.com> Date: Sat, 21 Mar 2020 20:26:34 +0100 Subject: [PATCH 1277/2161] +code style --- src/cc65/codeent.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index 7df164cc3..51f5f1378 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -615,9 +615,6 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) case OP65_BRK: break; - case OP65_STP: - break; - case OP65_BVC: break; @@ -1141,6 +1138,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) } break; + case OP65_STP: + break; + case OP65_STX: if (E->AM == AM65_ZP) { switch (GetKnownReg (E->Chg & REG_ZP, 0)) { From 4ea2bfef0a80b253d9af81677a524fd1ab1a8670 Mon Sep 17 00:00:00 2001 From: greg-king5 <greg.king5@verizon.net> Date: Thu, 26 Mar 2020 22:54:58 -0400 Subject: [PATCH 1278/2161] Aligned comment. --- src/cc65/opcodes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/opcodes.h b/src/cc65/opcodes.h index 8267d9550..bdb0c28a2 100644 --- a/src/cc65/opcodes.h +++ b/src/cc65/opcodes.h @@ -114,7 +114,7 @@ typedef enum { OP65_SED, OP65_SEI, OP65_STA, - OP65_STP, /* 65c02, 65816 stop */ + OP65_STP, /* 65c02, 65816 stop */ OP65_STX, OP65_STY, OP65_STZ, From 8b5a2f135cdbbafb829c1a3f4fd1518a2042eb56 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 27 Mar 2020 00:59:15 -0400 Subject: [PATCH 1279/2161] Added missing <tag> and <itemize> Linuxdoc tags to some ctype.h function descriptions. --- doc/funcref.sgml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 94e850092..a954c6581 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -4294,7 +4294,8 @@ fastcall function, so it may only be used in presence of a prototype. <tag/Header/<tt/<ref id="ctype.h" name="ctype.h">/ <tag/Declaration/<tt/int __fastcall__ isascii (int c);/ <tag/Description/The function returns a non zero value if the given argument -is in the range 0..127 (the range of valid ASCII characters) and zero if not. +is in the range 0..127 (the range of valid ASCII characters), and zero if not. +<tag/Notes/<itemize> <item>When compiling without <tt/-Os/, the function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> @@ -4392,6 +4393,7 @@ fastcall function, so it may only be used in presence of a prototype. <tag/Declaration/<tt/int __fastcall__ isdigit (int c);/ <tag/Description/The function returns a non zero value if the given argument is a digit. The return value is zero if the character is anything else. +<tag/Notes/<itemize> <item>When compiling without <tt/-Os/, the function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> From c15f4975d0a6d31a03f4c23ce5655f9615224997 Mon Sep 17 00:00:00 2001 From: Dirk Jagdmann <doj@cubic.org> Date: Sun, 29 Mar 2020 13:09:57 -0700 Subject: [PATCH 1280/2161] fix the clean: target to remove any disk images. --- samples/Makefile | 12 ++++++------ samples/README | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index 69efbe43b..adfe870e4 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -92,14 +92,14 @@ ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),) # For this one, see https://www.horus.com/~hias/atari/ DIR2ATR ?= dir2atr - - DISK_c64 = samples.d64 - DISK_apple2 = samples.dsk - DISK_apple2enh = samples.dsk - DISK_atari = samples.atr - DISK_atarixl = samples.atr endif +DISK_c64 = samples.d64 +DISK_apple2 = samples.dsk +DISK_apple2enh = samples.dsk +DISK_atari = samples.atr +DISK_atarixl = samples.atr + # -------------------------------------------------------------------------- # System-dependent settings # For convenience, these groups and lines are sorted alphabetically, first diff --git a/samples/README b/samples/README index 7ace7da3f..73d048fca 100644 --- a/samples/README +++ b/samples/README @@ -16,6 +16,7 @@ Please note: at the top of the makefile, specify the system with SYS=<target> on the make command line, or set a SYS environment variable. + * Use "make disk" to build a disk image with all sample programs. List of supplied sample programs: From 4cc95a2c6ce814a3882121b05db88d95b89822aa Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 2 Apr 2020 09:45:11 +0200 Subject: [PATCH 1281/2161] Matched comment to the one in the C header file. --- libsrc/apple2/dosdetect.s | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libsrc/apple2/dosdetect.s b/libsrc/apple2/dosdetect.s index 46fbb5484..44e46b2b6 100644 --- a/libsrc/apple2/dosdetect.s +++ b/libsrc/apple2/dosdetect.s @@ -14,10 +14,11 @@ ; ProDOS 8 1.6 - $16 ; ProDOS 8 1.7 - $17 ; ProDOS 8 1.8 - $18 -; ProDOS 8 1.9 - $18 +; ProDOS 8 1.9 - $18 (!) ; ProDOS 8 2.0.1 - $21 ; ProDOS 8 2.0.2 - $22 ; ProDOS 8 2.0.3 - $23 +; ProDOS 8 2.4.x - $24 ; .constructor initdostype, 25 From 65dd931d22b7196a0b6a4de8d6d441e15acfdab1 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 2 Apr 2020 10:03:01 +0200 Subject: [PATCH 1282/2161] Some style adjustments. --- libsrc/atari/ostype.s | 4 ++-- libsrc/common/atoi.s | 8 +++----- libsrc/common/ctype_preprocessor.s | 10 +++++----- libsrc/common/isalnum.s | 2 +- libsrc/common/isalpha.s | 2 +- libsrc/common/isblank.s | 4 ++-- libsrc/common/iscntrl.s | 2 +- libsrc/common/isdigit.s | 4 ++-- libsrc/common/isgraph.s | 3 +-- libsrc/common/islower.s | 2 +- libsrc/common/isprint.s | 2 +- libsrc/common/ispunct.s | 2 +- libsrc/common/isspace.s | 4 ++-- libsrc/common/isupper.s | 2 +- libsrc/common/isxdigit.s | 2 +- libsrc/common/strlower.s | 9 +++------ libsrc/common/strnicmp.s | 20 ++++++++++---------- libsrc/common/strupper.s | 7 ++----- libsrc/lynx/crt0.s | 2 +- 19 files changed, 41 insertions(+), 50 deletions(-) diff --git a/libsrc/atari/ostype.s b/libsrc/atari/ostype.s index 7248582a6..876e8749d 100644 --- a/libsrc/atari/ostype.s +++ b/libsrc/atari/ostype.s @@ -93,7 +93,7 @@ _get_ostype: asl a asl a and #%00111000 - ora #%11 + ora #%00000011 _fin: ldx #0 disable_rom_save_a rts @@ -117,7 +117,7 @@ _1200_11: lda #%00010000 _1200_fin: - ora #%010 + ora #%00000010 bne _fin ; 400/800 ROM diff --git a/libsrc/common/atoi.s b/libsrc/common/atoi.s index b63fcb206..10f917f86 100644 --- a/libsrc/common/atoi.s +++ b/libsrc/common/atoi.s @@ -15,7 +15,7 @@ ; _atoi: -_atol: sta ptr1 ; Store s +_atol: sta ptr1 ; store s stx ptr1+1 ldy #0 sty ptr2 @@ -71,7 +71,7 @@ L6: lda (ptr1),y ; get next char lda ptr2+1 pha lda ptr2 - pha ; Save value + pha ; save value jsr mul2 ; * 4 jsr mul2 ; * 8 @@ -118,7 +118,7 @@ L8: lda ptr2 ; Negate the value if necessary, otherwise we're done ldy tmp1 ; sign - beq L9 ; Branch if positive + beq L9 ; branch if positive ; Negate the 32 bit value in ptr2/sreg @@ -133,5 +133,3 @@ mul2: asl ptr2 rol sreg rol sreg+1 ; * 2 L9: rts - - diff --git a/libsrc/common/ctype_preprocessor.s b/libsrc/common/ctype_preprocessor.s index efa001e61..79d93860f 100644 --- a/libsrc/common/ctype_preprocessor.s +++ b/libsrc/common/ctype_preprocessor.s @@ -29,7 +29,7 @@ ctype_preprocessor: ctype_preprocessor_no_check: lsr a tax - lda __ctypeIdx, x + lda __ctypeIdx,x bcc @lowerNibble @upperNibble: lsr a @@ -38,13 +38,13 @@ ctype_preprocessor_no_check: lsr a clc ; remove out of bounds flag @lowerNibble: - and #%1111 + and #%00001111 tax - lda __ctype, x - ldx #0 + lda __ctype,x + ldx #$00 rts SC: sec - lda #0 + lda #$00 tax rts diff --git a/libsrc/common/isalnum.s b/libsrc/common/isalnum.s index 141949c0f..2a05e32ee 100644 --- a/libsrc/common/isalnum.s +++ b/libsrc/common/isalnum.s @@ -15,7 +15,7 @@ .import ctype_preprocessor _isalnum: - jsr ctype_preprocessor ; (clears always x) + jsr ctype_preprocessor ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) and #CT_ALNUM ; mask character/digit bits @L1: rts diff --git a/libsrc/common/isalpha.s b/libsrc/common/isalpha.s index 95e799161..7a1f79d20 100644 --- a/libsrc/common/isalpha.s +++ b/libsrc/common/isalpha.s @@ -15,7 +15,7 @@ .import ctype_preprocessor _isalpha: - jsr ctype_preprocessor ; (clears always x) + jsr ctype_preprocessor ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) and #CT_ALPHA ; mask character bits @L1: rts diff --git a/libsrc/common/isblank.s b/libsrc/common/isblank.s index 3d0a02f3d..cc5b9e5ab 100644 --- a/libsrc/common/isblank.s +++ b/libsrc/common/isblank.s @@ -17,7 +17,7 @@ .import ctype_preprocessor _isblank: - jsr ctype_preprocessor ; (clears always x) + jsr ctype_preprocessor ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) and #CT_SPACE_TAB ; mask blank bit - @L1: rts +@L1: rts diff --git a/libsrc/common/iscntrl.s b/libsrc/common/iscntrl.s index f2b95042d..65e2111be 100644 --- a/libsrc/common/iscntrl.s +++ b/libsrc/common/iscntrl.s @@ -15,7 +15,7 @@ .import ctype_preprocessor _iscntrl: - jsr ctype_preprocessor ; (clears always x) + jsr ctype_preprocessor ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) and #CT_CTRL ; mask control character bit @L1: rts diff --git a/libsrc/common/isdigit.s b/libsrc/common/isdigit.s index 36acd73b7..76b2d1b27 100644 --- a/libsrc/common/isdigit.s +++ b/libsrc/common/isdigit.s @@ -15,7 +15,7 @@ .import ctype_preprocessor _isdigit: - jsr ctype_preprocessor ; (clears always x) + jsr ctype_preprocessor ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) and #CT_DIGIT ; mask digit bit - @L1: rts +@L1: rts diff --git a/libsrc/common/isgraph.s b/libsrc/common/isgraph.s index 4e317db57..6dd91ed35 100644 --- a/libsrc/common/isgraph.s +++ b/libsrc/common/isgraph.s @@ -15,11 +15,10 @@ .import ctype_preprocessor _isgraph: - jsr ctype_preprocessor ; (clears always x) + jsr ctype_preprocessor ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) and #CT_CTRL_SPACE ; mask character bits cmp #1 ; if false, then set "borrow" flag lda #0 sbc #0 ; invert logic (return NOT control and NOT space) @L1: rts - diff --git a/libsrc/common/islower.s b/libsrc/common/islower.s index 608d0ccf4..a11ee129c 100644 --- a/libsrc/common/islower.s +++ b/libsrc/common/islower.s @@ -15,7 +15,7 @@ .import ctype_preprocessor _islower: - jsr ctype_preprocessor ; (clears always x) + jsr ctype_preprocessor ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) and #CT_LOWER ; mask lower char bit @L1: rts diff --git a/libsrc/common/isprint.s b/libsrc/common/isprint.s index 0d135f24f..e1d63bc6b 100644 --- a/libsrc/common/isprint.s +++ b/libsrc/common/isprint.s @@ -15,7 +15,7 @@ .import ctype_preprocessor _isprint: - jsr ctype_preprocessor ; (clears always x) + jsr ctype_preprocessor ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) eor #CT_CTRL ; NOT a control char and #CT_CTRL ; mask control char bit diff --git a/libsrc/common/ispunct.s b/libsrc/common/ispunct.s index a532399fe..ac4ab7f1d 100644 --- a/libsrc/common/ispunct.s +++ b/libsrc/common/ispunct.s @@ -15,7 +15,7 @@ .import ctype_preprocessor _ispunct: - jsr ctype_preprocessor ; (clears always x) + jsr ctype_preprocessor ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) and #CT_NOT_PUNCT ; mask relevant bits cmp #1 ; if false, then set "borrow" flag diff --git a/libsrc/common/isspace.s b/libsrc/common/isspace.s index 1f70786ce..c37023449 100644 --- a/libsrc/common/isspace.s +++ b/libsrc/common/isspace.s @@ -15,7 +15,7 @@ .import ctype_preprocessor _isspace: - jsr ctype_preprocessor ; (clears always x) + jsr ctype_preprocessor ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) and #(CT_SPACE | CT_OTHER_WS) ; mask space bits - @L1: rts +@L1: rts diff --git a/libsrc/common/isupper.s b/libsrc/common/isupper.s index 0dd2a6ead..175fb872b 100644 --- a/libsrc/common/isupper.s +++ b/libsrc/common/isupper.s @@ -15,7 +15,7 @@ .import ctype_preprocessor _isupper: - jsr ctype_preprocessor ; (clears always x) + jsr ctype_preprocessor ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) and #CT_UPPER ; mask upper char bit @L1: rts diff --git a/libsrc/common/isxdigit.s b/libsrc/common/isxdigit.s index 3f36ede01..e8a12a10e 100644 --- a/libsrc/common/isxdigit.s +++ b/libsrc/common/isxdigit.s @@ -15,7 +15,7 @@ .import ctype_preprocessor _isxdigit: - jsr ctype_preprocessor ; (clears always x) + jsr ctype_preprocessor ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) and #CT_XDIGIT ; mask xdigit bit @L1: rts diff --git a/libsrc/common/strlower.s b/libsrc/common/strlower.s index d4e481382..479d852e8 100644 --- a/libsrc/common/strlower.s +++ b/libsrc/common/strlower.s @@ -16,7 +16,7 @@ _strlower: _strlwr: - sta ptr1 ; Save s (working copy) + sta ptr1 ; save s (working copy) stx ptr1+1 sta ptr2 stx ptr2+1 ; save function result @@ -25,10 +25,10 @@ _strlwr: loop: lda (ptr1),y ; get character beq L9 ; jump if done ; get character classification - jsr ctype_preprocessor_no_check + jsr ctype_preprocessor_no_check and #CT_UPPER ; upper case char? beq L1 ; jump if no - lda (ptr1),y ; fetch character again + lda (ptr1),y ; fetch character again adc #<('a'-'A') ; make lower case char (ctype_preprocessor_no_check ensures carry clear) sta (ptr1),y ; store back L1: iny ; next char @@ -41,6 +41,3 @@ L1: iny ; next char L9: lda ptr2 ldx ptr2+1 rts - - - diff --git a/libsrc/common/strnicmp.s b/libsrc/common/strnicmp.s index 54aef2bb8..c4cc272d9 100644 --- a/libsrc/common/strnicmp.s +++ b/libsrc/common/strnicmp.s @@ -41,7 +41,7 @@ _strncasecmp: ; Start of compare loop. Check the counter. Loop: inc ptr3 - beq IncHi ; Increment high byte + beq IncHi ; increment high byte ; Compare a byte from the strings @@ -58,18 +58,18 @@ Comp: lda (ptr2),y L1: lda (ptr1),y ; get character from first string sta tmp1 ; remember original char ; get character classification - jsr ctype_preprocessor_no_check + jsr ctype_preprocessor_no_check and #CT_LOWER ; lower case char? beq L2 ; jump if no lda #<('A'-'a') ; make upper case char adc tmp1 ; ctype_preprocessor_no_check ensures carry clear! - sta tmp1 ; remember upper case equivalent + sta tmp1 ; remember upper case equivalent L2: ldx tmp1 cpx tmp2 ; compare characters - bne NotEqual ; Jump if strings different - txa ; End of strings? - beq Equal1 ; Jump if EOS reached, a/x == 0 + bne NotEqual ; jump if strings different + txa ; end of strings? + beq Equal1 ; jump if EOS reached, a/x == 0 ; Increment the pointers @@ -77,12 +77,12 @@ L2: ldx tmp1 bne Loop inc ptr1+1 inc ptr2+1 - bne Loop ; Branch always + bne Loop ; branch always ; Increment hi byte IncHi: inc ptr3+1 - bne Comp ; Jump if counter not zero + bne Comp ; jump if counter not zero ; Exit code if strings are equal. a/x not set @@ -94,8 +94,8 @@ Equal1: rts NotEqual: bcs L3 - ldx #$FF ; Make result negative + ldx #$FF ; make result negative rts -L3: ldx #$01 ; Make result positive +L3: ldx #$01 ; make result positive rts diff --git a/libsrc/common/strupper.s b/libsrc/common/strupper.s index dd6c1c25f..e2160d4da 100644 --- a/libsrc/common/strupper.s +++ b/libsrc/common/strupper.s @@ -16,7 +16,7 @@ _strupper: _strupr: - sta ptr1 ; Save s (working copy) + sta ptr1 ; save s (working copy) stx ptr1+1 sta ptr2 stx ptr2+1 ; save function result @@ -24,7 +24,7 @@ _strupr: loop: lda (ptr1),y ; get character beq L9 ; jump if done - jsr ctype_preprocessor_no_check + jsr ctype_preprocessor_no_check and #CT_LOWER ; lower case char? beq L1 ; jump if no lda (ptr1),y ; fetch character again @@ -40,6 +40,3 @@ L1: iny ; next char L9: lda ptr2 ldx ptr2+1 rts - - - diff --git a/libsrc/lynx/crt0.s b/libsrc/lynx/crt0.s index da2162b47..238a2c99d 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 #%11101 + lda #%00011101 sta SERCTL ; Clear all pending interrupts. From df015f47662d3b2f44a383bd5dc520216c9285f7 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 2 Apr 2020 11:15:53 +0200 Subject: [PATCH 1283/2161] Adjusted tolower() and toupper() to https://github.com/cc65/cc65/pull/997 For some reason or another both the author of the PR in question and its reviewers didn't notice that the two functions in question were totally overlooked. --- libsrc/common/tolower.s | 32 +++++++++++++++++++------------- libsrc/common/toupper.s | 32 +++++++++++++++++++------------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/libsrc/common/tolower.s b/libsrc/common/tolower.s index 2c624cb74..e672f077e 100644 --- a/libsrc/common/tolower.s +++ b/libsrc/common/tolower.s @@ -1,21 +1,27 @@ +; tolower.s ; -; Ullrich von Bassewitz, 02.06.1998 +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://cc65.github.io +; +; See "LICENSE" file for legal information. ; ; int tolower (int c); ; .export _tolower - .import __ctype + .include "ctype.inc" + .import ctype_preprocessor _tolower: - cpx #$00 ; Outside valid range? - bne L9 ; If so, return the argument unchanged - tay ; Get C into Y - lda __ctype,y ; Get character classification - lsr a - lsr a ; Get bit 1 (upper case char) into carry - tya ; Get char back into A - bcc L9 ; Jump if no upper case char - sbc #<('A'-'a') ; Make lower case char (carry already set) -L9: rts - + tay ; save char + jsr ctype_preprocessor ; (always clears X) + bcc @L2 ; out of range? +@L1: tya ; if so, return the argument unchanged + rts +@L2: and #CT_UPPER ; upper case char? + beq @L1 ; jump if no + tya ; restore char + adc #<('a'-'A') ; make lower case char (ctype_preprocessor ensures carry clear) + rts diff --git a/libsrc/common/toupper.s b/libsrc/common/toupper.s index da1ee0427..5b3a4c22d 100644 --- a/libsrc/common/toupper.s +++ b/libsrc/common/toupper.s @@ -1,21 +1,27 @@ +; toupper.s ; -; Ullrich von Bassewitz, 02.06.1998 +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://cc65.github.io +; +; See "LICENSE" file for legal information. ; ; int toupper (int c); ; .export _toupper - .import __ctype + .include "ctype.inc" + .import ctype_preprocessor _toupper: - cpx #$00 ; Outside valid range? - bne L9 ; If so, return the argument unchanged - tay ; Get c into Y - lda __ctype,y ; Get character classification - lsr a ; Get bit 0 (lower char) into carry - tya ; Get C back into A - bcc L9 ; Jump if not lower char - clc - adc #<('A'-'a') ; make upper case char -L9: rts ; CC are set - + tay ; save char + jsr ctype_preprocessor ; (always clears X) + bcc @L2 ; out of range? +@L1: tya ; if so, return the argument unchanged + rts +@L2: and #CT_LOWER ; lower case char? + beq @L1 ; jump if no + tya ; restore char + adc #<('A'-'a') ; make upper case char (ctype_preprocessor ensures carry clear) + rts From 411fe87f64f57dd3b2469214fdbca01a121b4569 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 2 Apr 2020 22:14:22 +0200 Subject: [PATCH 1284/2161] Fixed tolower() and toupper() to save high byte. --- libsrc/common/tolower.s | 21 +++++++++++---------- libsrc/common/toupper.s | 21 +++++++++++---------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/libsrc/common/tolower.s b/libsrc/common/tolower.s index e672f077e..bebac3c57 100644 --- a/libsrc/common/tolower.s +++ b/libsrc/common/tolower.s @@ -12,16 +12,17 @@ .export _tolower .include "ctype.inc" - .import ctype_preprocessor + .import ctype_preprocessor_no_check _tolower: - tay ; save char - jsr ctype_preprocessor ; (always clears X) - bcc @L2 ; out of range? -@L1: tya ; if so, return the argument unchanged - rts -@L2: and #CT_UPPER ; upper case char? - beq @L1 ; jump if no - tya ; restore char - adc #<('a'-'A') ; make lower case char (ctype_preprocessor ensures carry clear) + cpx #$00 ; out of range? + bne @L2 ; if so, return the argument unchanged + tay ; save char + jsr ctype_preprocessor_no_check + and #CT_UPPER ; upper case char? + beq @L1 ; jump if no + tya ; restore char + adc #<('a'-'A') ; make lower case char (ctype_preprocessor_no_check ensures carry clear) rts +@L1: tya ; restore char +@L2: rts diff --git a/libsrc/common/toupper.s b/libsrc/common/toupper.s index 5b3a4c22d..ed3dd9b07 100644 --- a/libsrc/common/toupper.s +++ b/libsrc/common/toupper.s @@ -12,16 +12,17 @@ .export _toupper .include "ctype.inc" - .import ctype_preprocessor + .import ctype_preprocessor_no_check _toupper: - tay ; save char - jsr ctype_preprocessor ; (always clears X) - bcc @L2 ; out of range? -@L1: tya ; if so, return the argument unchanged - rts -@L2: and #CT_LOWER ; lower case char? - beq @L1 ; jump if no - tya ; restore char - adc #<('A'-'a') ; make upper case char (ctype_preprocessor ensures carry clear) + cpx #$00 ; out of range? + bne @L2 ; if so, return the argument unchanged + tay ; save char + jsr ctype_preprocessor_no_check + and #CT_LOWER ; lower case char? + beq @L1 ; jump if no + tya ; restore char + adc #<('A'-'a') ; make upper case char (ctype_preprocessor_no_check ensures carry clear) rts +@L1: tya ; restore char +@L2: rts From 0981c020b2e36a34fd3dfb29478c99d5b3142f7b Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 2 Apr 2020 22:58:16 +0200 Subject: [PATCH 1285/2161] Shortened names and adjusted style. --- asminc/ctype.inc | 18 +++++++++--------- asminc/ctype_common.inc | 4 ++-- libsrc/atari/ctype.s | 4 ++-- libsrc/atmos/ctype.s | 4 ++-- libsrc/cbm/ctype.s | 4 ++-- libsrc/common/atoi.s | 6 ++---- libsrc/common/ctype.s | 4 ++-- .../{ctype_preprocessor.s => ctypemask.s} | 16 ++++++++-------- libsrc/common/isalnum.s | 4 ++-- libsrc/common/isalpha.s | 4 ++-- libsrc/common/isblank.s | 4 ++-- libsrc/common/iscntrl.s | 4 ++-- libsrc/common/isdigit.s | 4 ++-- libsrc/common/isgraph.s | 4 ++-- libsrc/common/islower.s | 8 ++++---- libsrc/common/isprint.s | 10 +++++----- libsrc/common/ispunct.s | 12 ++++++------ libsrc/common/isspace.s | 8 ++++---- libsrc/common/isupper.s | 8 ++++---- libsrc/common/isxdigit.s | 8 ++++---- libsrc/common/stricmp.s | 12 +++++------- libsrc/common/strlower.s | 7 +++---- libsrc/common/strnicmp.s | 12 +++++------- libsrc/common/strupper.s | 6 +++--- libsrc/common/tolower.s | 6 +++--- libsrc/common/toupper.s | 6 +++--- libsrc/geos-common/system/ctype.s | 4 ++-- 27 files changed, 92 insertions(+), 99 deletions(-) rename libsrc/common/{ctype_preprocessor.s => ctypemask.s} (80%) diff --git a/asminc/ctype.inc b/asminc/ctype.inc index 18a290fbe..4d9ae7986 100644 --- a/asminc/ctype.inc +++ b/asminc/ctype.inc @@ -14,15 +14,15 @@ ; Define bitmapped constants for the table entries -CT_NONE = $00 ; Nothing special -CT_LOWER = $01 ; 0 - Lower case char -CT_UPPER = $02 ; 1 - Upper case char -CT_DIGIT = $04 ; 2 - Numeric digit -CT_XDIGIT = $08 ; 3 - Hex digit (both, lower and upper) -CT_CTRL = $10 ; 4 - Control character -CT_SPACE = $20 ; 5 - The space character itself -CT_OTHER_WS = $40 ; 6 - Other whitespace ('\f', '\n', '\r', '\t' and '\v') -CT_SPACE_TAB = $80 ; 7 - Space or tab character +CT_NONE = %00000000 ; Nothing special +CT_LOWER = %00000001 ; 0 - Lower case char +CT_UPPER = %00000010 ; 1 - Upper case char +CT_DIGIT = %00000100 ; 2 - Numeric digit +CT_XDIGIT = %00001000 ; 3 - Hex digit (both, lower and upper) +CT_CTRL = %00010000 ; 4 - Control character +CT_SPACE = %00100000 ; 5 - The space character itself +CT_OTHER_WS = %01000000 ; 6 - Other whitespace ('\f', '\n', '\r', '\t' and '\v') +CT_SPACE_TAB = %10000000 ; 7 - Space or tab character ; Combined stuff CT_ALNUM = (CT_LOWER | CT_UPPER | CT_DIGIT) diff --git a/asminc/ctype_common.inc b/asminc/ctype_common.inc index 04aaa8f95..044c2834f 100644 --- a/asminc/ctype_common.inc +++ b/asminc/ctype_common.inc @@ -11,13 +11,13 @@ ; .include "ctypetable.inc" - .export __ctypeIdx + .export __ctypeidx ; The tables are readonly, put them into the rodata segment .rodata -__ctypeIdx: +__ctypeidx: ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 0/00 ___ctrl_@___, 1/01 ___ctrl_A___ ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 2/02 ___ctrl_B___, 3/03 ___ctrl_C___ ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 4/04 ___ctrl_D___, 5/05 ___ctrl_E___ diff --git a/libsrc/atari/ctype.s b/libsrc/atari/ctype.s index 7903dc2a3..2f219f8c3 100644 --- a/libsrc/atari/ctype.s +++ b/libsrc/atari/ctype.s @@ -11,13 +11,13 @@ ; .include "ctypetable.inc" - .export __ctypeIdx + .export __ctypeidx ; The tables are readonly, put them into the rodata segment .rodata -__ctypeIdx: +__ctypeidx: ct_mix CT_NONE_IDX, CT_NONE_IDX ; 0/00 ___heart____, 1/01 ___l_tee____ ct_mix CT_NONE_IDX, CT_NONE_IDX ; 2/02 ___ctrl_B___, 3/03 ___ctrl_C___ ct_mix CT_NONE_IDX, CT_NONE_IDX ; 4/04 ___r_tee____, 5/05 ___ctrl_E___ diff --git a/libsrc/atmos/ctype.s b/libsrc/atmos/ctype.s index 7ca01b32a..90a3baa6e 100644 --- a/libsrc/atmos/ctype.s +++ b/libsrc/atmos/ctype.s @@ -11,13 +11,13 @@ ; .include "ctypetable.inc" - .export __ctypeIdx + .export __ctypeidx ; The tables are readonly, put them into the rodata segment .rodata -__ctypeIdx: +__ctypeidx: ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 0/00 ___ctrl_@___, 1/01 ___ctrl_A___ ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 2/02 ___ctrl_B___, 3/03 ___ctrl_C___ ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 4/04 ___ctrl_D___, 5/05 ___ctrl_E___ diff --git a/libsrc/cbm/ctype.s b/libsrc/cbm/ctype.s index 77a37431d..7388f68b8 100644 --- a/libsrc/cbm/ctype.s +++ b/libsrc/cbm/ctype.s @@ -12,13 +12,13 @@ ; This table is taken from Craig S. Bruce's technical docs. for the ACE OS. .include "ctypetable.inc" - .export __ctypeIdx + .export __ctypeidx ; The tables are readonly, put them into the rodata segment .rodata -__ctypeIdx: +__ctypeidx: ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 0/00 ___rvs_@___, 1/01 ___rvs_a___ ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 2/02 ___rvs_b___, 3/03 ___rvs_c___ ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 4/04 ___rvs_d___, 5/05 ___rvs_e___ diff --git a/libsrc/common/atoi.s b/libsrc/common/atoi.s index 10f917f86..0236b77f2 100644 --- a/libsrc/common/atoi.s +++ b/libsrc/common/atoi.s @@ -8,7 +8,7 @@ .export _atoi, _atol .import negeax, __ctype .importzp sreg, ptr1, ptr2, tmp1 - .import ctype_preprocessor_no_check + .import ctypemaskdirect .include "ctype.inc" ; ; Conversion routine (32 bit) @@ -26,9 +26,7 @@ _atol: sta ptr1 ; store s ; Skip whitespace L1: lda (ptr1),y - ; get character classification - jsr ctype_preprocessor_no_check - + jsr ctypemaskdirect ; get character classification and #CT_SPACE_TAB ; tab or space? beq L2 ; jump if no iny diff --git a/libsrc/common/ctype.s b/libsrc/common/ctype.s index 15f115e7d..220ad79c1 100644 --- a/libsrc/common/ctype.s +++ b/libsrc/common/ctype.s @@ -11,13 +11,13 @@ ; .include "ctypetable.inc" - .export __ctypeIdx + .export __ctypeidx ; The tables are readonly, put them into the rodata segment .rodata -__ctypeIdx: +__ctypeidx: .repeat 2 ; 2 times for normal and inverted diff --git a/libsrc/common/ctype_preprocessor.s b/libsrc/common/ctypemask.s similarity index 80% rename from libsrc/common/ctype_preprocessor.s rename to libsrc/common/ctypemask.s index 79d93860f..b518a10c0 100644 --- a/libsrc/common/ctype_preprocessor.s +++ b/libsrc/common/ctypemask.s @@ -1,4 +1,4 @@ -; ctype_preprocessor.s +; ctypemask.s ; ; This file is part of ; cc65 - a freeware C compiler for 6502 based systems @@ -7,7 +7,7 @@ ; ; See "LICENSE" file for legal information. ; -; ctype_preprocessor(int c) +; ctypemask(int c) ; ; converts a character to test via the is*-functions to the matching ctype-masks ; If c is out of the 8-bit range, the function returns with carry set and accu cleared. @@ -18,18 +18,18 @@ ; while calling this function! ; - .export ctype_preprocessor - .export ctype_preprocessor_no_check + .export ctypemask + .export ctypemaskdirect .import __ctype - .import __ctypeIdx + .import __ctypeidx -ctype_preprocessor: +ctypemask: cpx #$00 ; char range ok? bne SC ; branch if not -ctype_preprocessor_no_check: +ctypemaskdirect: lsr a tax - lda __ctypeIdx,x + lda __ctypeidx,x bcc @lowerNibble @upperNibble: lsr a diff --git a/libsrc/common/isalnum.s b/libsrc/common/isalnum.s index 2a05e32ee..ec2c9de1f 100644 --- a/libsrc/common/isalnum.s +++ b/libsrc/common/isalnum.s @@ -12,10 +12,10 @@ .export _isalnum .include "ctype.inc" - .import ctype_preprocessor + .import ctypemask _isalnum: - jsr ctype_preprocessor ; (always clears X) + jsr ctypemask ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) and #CT_ALNUM ; mask character/digit bits @L1: rts diff --git a/libsrc/common/isalpha.s b/libsrc/common/isalpha.s index 7a1f79d20..2d1f4b584 100644 --- a/libsrc/common/isalpha.s +++ b/libsrc/common/isalpha.s @@ -12,10 +12,10 @@ .export _isalpha .include "ctype.inc" - .import ctype_preprocessor + .import ctypemask _isalpha: - jsr ctype_preprocessor ; (always clears X) + jsr ctypemask ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) and #CT_ALPHA ; mask character bits @L1: rts diff --git a/libsrc/common/isblank.s b/libsrc/common/isblank.s index cc5b9e5ab..a9788daac 100644 --- a/libsrc/common/isblank.s +++ b/libsrc/common/isblank.s @@ -14,10 +14,10 @@ .export _isblank .include "ctype.inc" - .import ctype_preprocessor + .import ctypemask _isblank: - jsr ctype_preprocessor ; (always clears X) + jsr ctypemask ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) and #CT_SPACE_TAB ; mask blank bit @L1: rts diff --git a/libsrc/common/iscntrl.s b/libsrc/common/iscntrl.s index 65e2111be..7a4879017 100644 --- a/libsrc/common/iscntrl.s +++ b/libsrc/common/iscntrl.s @@ -12,10 +12,10 @@ .export _iscntrl .include "ctype.inc" - .import ctype_preprocessor + .import ctypemask _iscntrl: - jsr ctype_preprocessor ; (always clears X) + jsr ctypemask ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) and #CT_CTRL ; mask control character bit @L1: rts diff --git a/libsrc/common/isdigit.s b/libsrc/common/isdigit.s index 76b2d1b27..ae3f8d12f 100644 --- a/libsrc/common/isdigit.s +++ b/libsrc/common/isdigit.s @@ -12,10 +12,10 @@ .export _isdigit .include "ctype.inc" - .import ctype_preprocessor + .import ctypemask _isdigit: - jsr ctype_preprocessor ; (always clears X) + jsr ctypemask ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) and #CT_DIGIT ; mask digit bit @L1: rts diff --git a/libsrc/common/isgraph.s b/libsrc/common/isgraph.s index 6dd91ed35..8b97780b9 100644 --- a/libsrc/common/isgraph.s +++ b/libsrc/common/isgraph.s @@ -12,10 +12,10 @@ .export _isgraph .include "ctype.inc" - .import ctype_preprocessor + .import ctypemask _isgraph: - jsr ctype_preprocessor ; (always clears X) + jsr ctypemask ; (always clears X) bcs @L1 ; out of range? (everything already clear -> false) and #CT_CTRL_SPACE ; mask character bits cmp #1 ; if false, then set "borrow" flag diff --git a/libsrc/common/islower.s b/libsrc/common/islower.s index a11ee129c..b19c16825 100644 --- a/libsrc/common/islower.s +++ b/libsrc/common/islower.s @@ -12,12 +12,12 @@ .export _islower .include "ctype.inc" - .import ctype_preprocessor + .import ctypemask _islower: - jsr ctype_preprocessor ; (always clears X) - bcs @L1 ; out of range? (everything already clear -> false) - and #CT_LOWER ; mask lower char bit + jsr ctypemask ; (always clears X) + bcs @L1 ; out of range? (everything already clear -> false) + and #CT_LOWER ; mask lower char bit @L1: rts diff --git a/libsrc/common/isprint.s b/libsrc/common/isprint.s index e1d63bc6b..c62bd784f 100644 --- a/libsrc/common/isprint.s +++ b/libsrc/common/isprint.s @@ -12,11 +12,11 @@ .export _isprint .include "ctype.inc" - .import ctype_preprocessor + .import ctypemask _isprint: - jsr ctype_preprocessor ; (always clears X) - bcs @L1 ; out of range? (everything already clear -> false) - eor #CT_CTRL ; NOT a control char - and #CT_CTRL ; mask control char bit + jsr ctypemask ; (always clears X) + bcs @L1 ; out of range? (everything already clear -> false) + eor #CT_CTRL ; NOT a control char + and #CT_CTRL ; mask control char bit @L1: rts diff --git a/libsrc/common/ispunct.s b/libsrc/common/ispunct.s index ac4ab7f1d..df47322fb 100644 --- a/libsrc/common/ispunct.s +++ b/libsrc/common/ispunct.s @@ -12,13 +12,13 @@ .export _ispunct .include "ctype.inc" - .import ctype_preprocessor + .import ctypemask _ispunct: - jsr ctype_preprocessor ; (always clears X) - bcs @L1 ; out of range? (everything already clear -> false) - and #CT_NOT_PUNCT ; mask relevant bits - cmp #1 ; if false, then set "borrow" flag + jsr ctypemask ; (always clears X) + bcs @L1 ; out of range? (everything already clear -> false) + and #CT_NOT_PUNCT ; mask relevant bits + cmp #1 ; if false, then set "borrow" flag lda #0 - sbc #0 ; invert logic (return NOT (space | control | digit | alpha)) + sbc #0 ; invert logic (return NOT (space | control | digit | alpha)) @L1: rts diff --git a/libsrc/common/isspace.s b/libsrc/common/isspace.s index c37023449..b234febfa 100644 --- a/libsrc/common/isspace.s +++ b/libsrc/common/isspace.s @@ -12,10 +12,10 @@ .export _isspace .include "ctype.inc" - .import ctype_preprocessor + .import ctypemask _isspace: - jsr ctype_preprocessor ; (always clears X) - bcs @L1 ; out of range? (everything already clear -> false) - and #(CT_SPACE | CT_OTHER_WS) ; mask space bits + jsr ctypemask ; (always clears X) + bcs @L1 ; out of range? (everything already clear -> false) + and #(CT_SPACE | CT_OTHER_WS) ; mask space bits @L1: rts diff --git a/libsrc/common/isupper.s b/libsrc/common/isupper.s index 175fb872b..45f48d871 100644 --- a/libsrc/common/isupper.s +++ b/libsrc/common/isupper.s @@ -12,10 +12,10 @@ .export _isupper .include "ctype.inc" - .import ctype_preprocessor + .import ctypemask _isupper: - jsr ctype_preprocessor ; (always clears X) - bcs @L1 ; out of range? (everything already clear -> false) - and #CT_UPPER ; mask upper char bit + jsr ctypemask ; (always clears X) + bcs @L1 ; out of range? (everything already clear -> false) + and #CT_UPPER ; mask upper char bit @L1: rts diff --git a/libsrc/common/isxdigit.s b/libsrc/common/isxdigit.s index e8a12a10e..6d59e2ac8 100644 --- a/libsrc/common/isxdigit.s +++ b/libsrc/common/isxdigit.s @@ -12,10 +12,10 @@ .export _isxdigit .include "ctype.inc" - .import ctype_preprocessor + .import ctypemask _isxdigit: - jsr ctype_preprocessor ; (always clears X) - bcs @L1 ; out of range? (everything already clear -> false) - and #CT_XDIGIT ; mask xdigit bit + jsr ctypemask ; (always clears X) + bcs @L1 ; out of range? (everything already clear -> false) + and #CT_XDIGIT ; mask xdigit bit @L1: rts diff --git a/libsrc/common/stricmp.s b/libsrc/common/stricmp.s index 3a03258bd..494350b06 100644 --- a/libsrc/common/stricmp.s +++ b/libsrc/common/stricmp.s @@ -14,7 +14,7 @@ .export _stricmp, _strcasecmp .import popptr1 .importzp ptr1, ptr2, tmp1, tmp2 - .import ctype_preprocessor_no_check + .import ctypemaskdirect .include "ctype.inc" _stricmp: @@ -26,22 +26,20 @@ _strcasecmp: loop: lda (ptr2),y ; get char from second string sta tmp2 ; and save it - ; get character classification - jsr ctype_preprocessor_no_check + jsr ctypemaskdirect ; get character classification and #CT_LOWER ; lower case char? beq L1 ; jump if no lda #<('A'-'a') ; make upper case char - adc tmp2 ; ctype_preprocessor_no_check ensures carry clear! + adc tmp2 ; ctypemaskdirect ensures carry clear! sta tmp2 ; remember upper case equivalent L1: lda (ptr1),y ; get character from first string sta tmp1 - ; get character classification - jsr ctype_preprocessor_no_check + jsr ctypemaskdirect ; get character classification and #CT_LOWER ; lower case char? beq L2 ; jump if no lda #<('A'-'a') ; make upper case char - adc tmp1 ; ctype_preprocessor_no_check ensures carry clear! + adc tmp1 ; ctypemaskdirect ensures carry clear! sta tmp1 ; remember upper case equivalent L2: ldx tmp1 diff --git a/libsrc/common/strlower.s b/libsrc/common/strlower.s index 479d852e8..b7c1a289b 100644 --- a/libsrc/common/strlower.s +++ b/libsrc/common/strlower.s @@ -11,7 +11,7 @@ .export _strlower, _strlwr .import popax .importzp ptr1, ptr2 - .import ctype_preprocessor_no_check + .import ctypemaskdirect .include "ctype.inc" _strlower: @@ -24,12 +24,11 @@ _strlwr: loop: lda (ptr1),y ; get character beq L9 ; jump if done - ; get character classification - jsr ctype_preprocessor_no_check + jsr ctypemaskdirect ; get character classification and #CT_UPPER ; upper case char? beq L1 ; jump if no lda (ptr1),y ; fetch character again - adc #<('a'-'A') ; make lower case char (ctype_preprocessor_no_check ensures carry clear) + adc #<('a'-'A') ; make lower case char (ctypemaskdirect ensures carry clear) sta (ptr1),y ; store back L1: iny ; next char bne loop diff --git a/libsrc/common/strnicmp.s b/libsrc/common/strnicmp.s index c4cc272d9..43d6d0d50 100644 --- a/libsrc/common/strnicmp.s +++ b/libsrc/common/strnicmp.s @@ -9,7 +9,7 @@ .export _strnicmp, _strncasecmp .import popax, popptr1 .importzp ptr1, ptr2, ptr3, tmp1, tmp2 - .import ctype_preprocessor_no_check + .import ctypemaskdirect .include "ctype.inc" _strnicmp: @@ -47,22 +47,20 @@ Loop: inc ptr3 Comp: lda (ptr2),y sta tmp2 ; remember original char - ; get character classification - jsr ctype_preprocessor_no_check + jsr ctypemaskdirect ; get character classification and #CT_LOWER ; lower case char? beq L1 ; jump if no lda #<('A'-'a') ; make upper case char - adc tmp2 ; ctype_preprocessor_no_check ensures carry clear! + adc tmp2 ; ctypemaskdirect ensures carry clear! sta tmp2 ; remember upper case equivalent L1: lda (ptr1),y ; get character from first string sta tmp1 ; remember original char - ; get character classification - jsr ctype_preprocessor_no_check + jsr ctypemaskdirect ; get character classification and #CT_LOWER ; lower case char? beq L2 ; jump if no lda #<('A'-'a') ; make upper case char - adc tmp1 ; ctype_preprocessor_no_check ensures carry clear! + adc tmp1 ; ctypemaskdirect ensures carry clear! sta tmp1 ; remember upper case equivalent L2: ldx tmp1 diff --git a/libsrc/common/strupper.s b/libsrc/common/strupper.s index e2160d4da..3af0d8d98 100644 --- a/libsrc/common/strupper.s +++ b/libsrc/common/strupper.s @@ -11,7 +11,7 @@ .export _strupper, _strupr .import popax .importzp ptr1, ptr2 - .import ctype_preprocessor_no_check + .import ctypemaskdirect .include "ctype.inc" _strupper: @@ -24,11 +24,11 @@ _strupr: loop: lda (ptr1),y ; get character beq L9 ; jump if done - jsr ctype_preprocessor_no_check + jsr ctypemaskdirect ; get character classification and #CT_LOWER ; lower case char? beq L1 ; jump if no lda (ptr1),y ; fetch character again - adc #<('A'-'a') ; make upper case char (ctype_preprocessor_no_check ensures carry clear) + adc #<('A'-'a') ; make upper case char (ctypemaskdirect ensures carry clear) sta (ptr1),y ; store back L1: iny ; next char bne loop diff --git a/libsrc/common/tolower.s b/libsrc/common/tolower.s index bebac3c57..828be1cb1 100644 --- a/libsrc/common/tolower.s +++ b/libsrc/common/tolower.s @@ -12,17 +12,17 @@ .export _tolower .include "ctype.inc" - .import ctype_preprocessor_no_check + .import ctypemaskdirect _tolower: cpx #$00 ; out of range? bne @L2 ; if so, return the argument unchanged tay ; save char - jsr ctype_preprocessor_no_check + jsr ctypemaskdirect ; get character classification and #CT_UPPER ; upper case char? beq @L1 ; jump if no tya ; restore char - adc #<('a'-'A') ; make lower case char (ctype_preprocessor_no_check ensures carry clear) + adc #<('a'-'A') ; make lower case char (ctypemaskdirect ensures carry clear) rts @L1: tya ; restore char @L2: rts diff --git a/libsrc/common/toupper.s b/libsrc/common/toupper.s index ed3dd9b07..d0465f64f 100644 --- a/libsrc/common/toupper.s +++ b/libsrc/common/toupper.s @@ -12,17 +12,17 @@ .export _toupper .include "ctype.inc" - .import ctype_preprocessor_no_check + .import ctypemaskdirect _toupper: cpx #$00 ; out of range? bne @L2 ; if so, return the argument unchanged tay ; save char - jsr ctype_preprocessor_no_check + jsr ctypemaskdirect ; get character classification and #CT_LOWER ; lower case char? beq @L1 ; jump if no tya ; restore char - adc #<('A'-'a') ; make upper case char (ctype_preprocessor_no_check ensures carry clear) + adc #<('A'-'a') ; make upper case char (ctypemaskdirect ensures carry clear) rts @L1: tya ; restore char @L2: rts diff --git a/libsrc/geos-common/system/ctype.s b/libsrc/geos-common/system/ctype.s index 013a1ba99..b34f68470 100644 --- a/libsrc/geos-common/system/ctype.s +++ b/libsrc/geos-common/system/ctype.s @@ -13,13 +13,13 @@ ; http://lyonlabs.org/commodore/onrequest/geos-manuals/The_Hitchhikers_Guide_to_GEOS.pdf .include "ctypetable.inc" - .export __ctypeIdx + .export __ctypeidx ; The tables are readonly, put them into the rodata segment .rodata -__ctypeIdx: +__ctypeidx: ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 0/00 ____NULL___, 1/01 ____N/A____ ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 2/02 ____N/A____, 3/03 ____N/A____ ct_mix CT_CTRL_IDX, CT_CTRL_IDX ; 4/04 ____N/A____, 5/05 ____N/A____ From 4a224878d8fb1f3dd408864e33edcee7f846449d Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 6 Apr 2020 16:20:52 +0200 Subject: [PATCH 1286/2161] Preserve the accu --- libsrc/nes/waitvsync.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/nes/waitvsync.s b/libsrc/nes/waitvsync.s index 4bdf9a9d0..9f811c0a9 100644 --- a/libsrc/nes/waitvsync.s +++ b/libsrc/nes/waitvsync.s @@ -11,7 +11,7 @@ .proc _waitvsync -wait: lda PPU_STATUS +wait: bit PPU_STATUS bpl wait rts From 31daa706b7290d97b4537feb5a4da87537684c25 Mon Sep 17 00:00:00 2001 From: itaych <itaych@gmail.com> Date: Thu, 16 Apr 2020 02:28:15 +0300 Subject: [PATCH 1287/2161] PMG_SIZE_QUAD is 3, not 2. From "Mapping the Atari": "Size of player. POKE with zero or two for normal size (eight color clocks wide), POKE with one to double a player's width (sixteen color clocks wide), and POKE with three for quadruple width (32 color clocks wide). Each player can have its own width set." --- include/_gtia.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/_gtia.h b/include/_gtia.h index cbdf7608e..eaf6bed3e 100644 --- a/include/_gtia.h +++ b/include/_gtia.h @@ -95,7 +95,7 @@ struct __gtia_write { #define PMG_SIZE_NORMAL 0x0 /* one color clock per pixel */ #define PMG_SIZE_DOUBLE 0x1 /* two color clocks per pixel */ -#define PMG_SIZE_QUAD 0x2 /* four color clocks per pixel */ +#define PMG_SIZE_QUAD 0x3 /* four color clocks per pixel */ /* COLPM0-COLPM3, COLPF0-COLPF3, COLBK color registers */ From cbf0c1d1dddc9d201ef3bf6ce9f3d5b54bc6e325 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 2 May 2020 13:46:06 -0400 Subject: [PATCH 1288/2161] Updated the cx16 library to the Commander X16's ROM prerelease 37. --- asminc/cbm_kernal.inc | 4 + asminc/cx16.inc | 344 +++++++++++++++++++---------------- include/cx16.h | 110 +++++++++-- libsrc/cx16/bordercolor.s | 18 +- libsrc/cx16/cpeekc.s | 5 +- libsrc/cx16/cpeekcolor.s | 15 +- libsrc/cx16/cpeekrevers.s | 13 +- libsrc/cx16/cputc.s | 4 +- libsrc/cx16/crt0.s | 8 +- libsrc/cx16/exec.c | 20 +- libsrc/cx16/get_numbanks.s | 10 +- libsrc/cx16/get_tv.s | 18 +- libsrc/cx16/kernal.s | 6 +- libsrc/cx16/layer_enable.s | 39 ++++ libsrc/cx16/randomize.s | 14 ++ libsrc/cx16/set_tv.s | 18 +- libsrc/cx16/sprites_enable.s | 34 ++++ 17 files changed, 447 insertions(+), 233 deletions(-) create mode 100644 libsrc/cx16/layer_enable.s create mode 100644 libsrc/cx16/randomize.s create mode 100644 libsrc/cx16/sprites_enable.s diff --git a/asminc/cbm_kernal.inc b/asminc/cbm_kernal.inc index 7125f1253..981687206 100644 --- a/asminc/cbm_kernal.inc +++ b/asminc/cbm_kernal.inc @@ -7,6 +7,10 @@ .if .def(__CX16__) ; CX16 extended jump table + ENTROPY_GET := $FECF + KEYBRD_BUF_PUT := $FED2 + CONSOLE_SET_PAGE_MSG := $FED5 + CONSOLE_PUT_IMAGE := $FED8 CONSOLE_INIT := $FEDB CONSOLE_PUT_CHAR := $FEDE CONSOLE_GET_CHAR := $FEE1 diff --git a/asminc/cx16.inc b/asminc/cx16.inc index 06cc30199..8891c1761 100644 --- a/asminc/cx16.inc +++ b/asminc/cx16.inc @@ -1,5 +1,5 @@ ; -; CX16 r36 definitions +; CX16 r37 definitions ; ; --------------------------------------------------------------------------- @@ -236,8 +236,8 @@ TXTPTR := $EE ; Pointer into BASIC source code BASIC_BUF := $0200 ; Location of command-line BASIC_BUF_LEN = 81 ; Maximum length of command-line -SCREEN_MODE := $0262 ; Current screen mode (set by SCREEN_SET_MODE) -SCREEN_PTR := $0263 ; Pointer to current row on text screen (16 bits) +SCREEN_MODE := $0261 ; Current screen mode (set by SCREEN_SET_MODE) +SCREEN_PTR := $0262 ; Pointer to current row on text screen (16 bits) STATUS := $0286 ; Status from previous I/O operation IN_DEV := $028A ; Current input device number OUT_DEV := $028B ; Current output device number @@ -257,8 +257,8 @@ LLEN := $0386 ; Line length NLINES := $0387 ; Number of screen lines ; BASIC -VARTAB := $03E3 ; Pointer to start of BASIC variables -MEMSIZE := $03EB ; Pointer to highest BASIC RAM location (+1) +VARTAB := $03E2 ; Pointer to start of BASIC variables +MEMSIZE := $03EA ; Pointer to highest BASIC RAM location (+1) ; --------------------------------------------------------------------------- ; Vector and other locations @@ -271,9 +271,11 @@ NMIVec := $0318 ; I/O locations ; Video Enhanced Retro Adapter -; Has audio, SPI, and UART. -.scope VERA +; Has audio and SPI. +.scope VERA + ; External registers + .struct .org $9F20 ADDR .faraddr ; Address for data port access @@ -282,31 +284,151 @@ NMIVec := $0318 CTRL .byte ; Control register IRQ_EN .byte ; Interrupt enable bits IRQ_FLAGS .byte ; Interrupt flags + IRQ_RASTER .byte ; Line where IRQ will occur .endstruct .enum ; Address automatic increment amounts - INC0 = 0 << 4 - INC1 = 1 << 4 - INC2 = 2 << 4 - INC4 = 3 << 4 - INC8 = 4 << 4 - INC16 = 5 << 4 - INC32 = 6 << 4 - INC64 = 7 << 4 - INC128 = 8 << 4 - INC256 = 9 << 4 - INC512 = 10 << 4 - INC1024 = 11 << 4 - INC2048 = 12 << 4 - INC4096 = 13 << 4 - INC8192 = 14 << 4 - INC16384 = 15 << 4 + DEC0 = (($00 << 1) | $01) << 3 + DEC1 = (($01 << 1) | $01) << 3 + DEC2 = (($02 << 1) | $01) << 3 + DEC4 = (($03 << 1) | $01) << 3 + DEC8 = (($04 << 1) | $01) << 3 + DEC16 = (($05 << 1) | $01) << 3 + DEC32 = (($06 << 1) | $01) << 3 + DEC64 = (($07 << 1) | $01) << 3 + DEC128 = (($08 << 1) | $01) << 3 + DEC256 = (($09 << 1) | $01) << 3 + DEC512 = (($0A << 1) | $01) << 3 + DEC40 = (($0B << 1) | $01) << 3 + DEC80 = (($0C << 1) | $01) << 3 + DEC160 = (($0D << 1) | $01) << 3 + DEC320 = (($0E << 1) | $01) << 3 + DEC640 = (($0F << 1) | $01) << 3 + INC0 = (($00 << 1) | $00) << 3 + INC1 = (($01 << 1) | $00) << 3 + INC2 = (($02 << 1) | $00) << 3 + INC4 = (($03 << 1) | $00) << 3 + INC8 = (($04 << 1) | $00) << 3 + INC16 = (($05 << 1) | $00) << 3 + INC32 = (($06 << 1) | $00) << 3 + INC64 = (($07 << 1) | $00) << 3 + INC128 = (($08 << 1) | $00) << 3 + INC256 = (($09 << 1) | $00) << 3 + INC512 = (($0A << 1) | $00) << 3 + INC40 = (($0B << 1) | $00) << 3 + INC80 = (($0C << 1) | $00) << 3 + INC160 = (($0D << 1) | $00) << 3 + INC320 = (($0E << 1) | $00) << 3 + INC640 = (($0F << 1) | $00) << 3 .endenum .enum ; Interrupt request flags VERT_SYNC = %00000001 - RASTER = %00000010 + RASTER_IRQ = %00000010 SPR_COLLIDED = %00000100 - UART_IRQ = %00001000 + AUDIO_LOW = %00001000 .endenum + .scope DISP ; Display controller + SELECT1 = %00000010 + .union + .org $9F29 + .struct + ; These four registers are visible when the DCSEL flag = %0 + VIDEO .byte + HSCALE .byte + VSCALE .byte + FRAME .byte + .endstruct + .struct + ; These four registers are visible when the DCSEL flag = %1 + HSTART .byte + HSTOP .byte + VSTART .byte + VSTOP .byte + .endstruct + .endunion + .enum MODE ; Output mode + DISABLE = $00 + VGA + NTSC + RGB ; Interlaced, composite sync + .endenum + .enum DISABLE + COLOR = %00000100 ; NTSC monochrome + .endenum + .enum ENABLE + LAYER0 = %00010000 + LAYER1 = %00100000 + SPRITES = %01000000 + .endenum + .endscope + .struct L0 ; Display layer 0 + .org $9F2D + CONFIG .byte + MAP_BASE .byte + TILE_BASE .byte + HSCROLL .word + VSCROLL .word + .endstruct + .struct L1 ; Display layer 1 + .org $9F34 + CONFIG .byte + MAP_BASE .byte + TILE_BASE .byte + HSCROLL .word + VSCROLL .word + .endstruct + .enum ; Layer display modes + TILE1BPP = %00000000 | $00 + TILE2BPP + TILE4BPP + TILE8BPP + T256C = %00001000 + BITMAP1BPP = %00000100 | $00 + BITMAP2BPP + BITMAP4BPP + BITMAP8BPP + .endenum + .enum MAP ; Map geometry + WIDTH32 = $00 << 4 + WIDTH64 = $01 << 4 + WIDTH128 = $02 << 4 + WIDTH256 = $03 << 4 + HEIGHT32 = $00 << 6 + HEIGHT64 = $01 << 6 + HEIGHT128 = $02 << 6 + HEIGHT256 = $03 << 6 + .endenum + .enum TILE ; Tile geometry + WIDTH8 = $00 + WIDTH16 = $01 + WIDTH320 = WIDTH8 + WIDTH640 = WIDTH16 + HEIGHT8 = $00 << 1 + HEIGHT16 = $01 << 1 + .endenum + .scope PCM ; Pulse-Code Modulator + .struct + .org $9F3B + CTRL .byte + RATE .byte + DATA .byte + .endstruct + .enum + STEREO = %00010000 + BITS16 = %00100000 + RESET = %10000000 + .endenum + .endscope + .scope SPI + .struct + .org $9F3E + DATA .byte + CTRL .byte + .endstruct + .enum + SELECT = %00000001 + SLOW = %00000010 + .endenum + .endscope ; Internal RAM and registers @@ -314,150 +436,66 @@ NMIVec := $0318 .org $000000 VRAM .res $020000 ; 128 Kibibytes .endstruct - .scope COMPOSER ; Display composer + .scope PSG ; Programmable Sound Generator .struct - .org $0F0000 - VIDEO .byte - HSCALE .byte - VSCALE .byte - FRAME .byte - HSTART_LO .byte - HSTOP_LO .byte - VSTART_LO .byte - VSTOP_LO .byte - STRTSTOP_HI .byte - IRQ_LINE .word + PITCH .word + VOL .byte ; Left, right channels; volume + WAVEFORM .byte ; Wave shape, pulse width .endstruct - .enum MODE ; Output mode - DISABLE = 0 - VGA - NTSC - RGB ; Interlaced, composite sync - .endenum + LEFT = %01 << 6 + RIGHT = %10 << 6 .enum - ENABLE_COLOR = 0 << 2 - DISABLE_COLOR = 1 << 2 ; NTSC monochrome + PULSE = $00 << 6 + SAWTOOTH = $01 << 6 + TRIANGLE = $02 << 6 + NOISE = $03 << 6 .endenum + .struct + .org $01F9C0 + VOICES .res $10 * 4 + .endstruct .endscope - PALETTE := $0F1000 - .struct L0 ; Layer 0 registers - .org $0F2000 - CTRL0 .byte ; Display mode control - CTRL1 .byte ; Geometry control - MAP_BASE .addr - TILE_BASE .addr - HSCROLL .word ; Horizontal scroll - VSCROLL .word ; Vertical scroll + .struct + .org $01FA00 + PALETTE .word $0100 .endstruct - .struct L1 ; Layer 1 registers (same as layer 0) - .org $0F3000 - CTRL0 .byte - CTRL1 .byte - MAP_BASE .addr - TILE_BASE .addr - HSCROLL .word - VSCROLL .word - .endstruct - .enum MAP ; Map geometry - WIDTH32 = 0 - WIDTH64 - WIDTH128 - WIDTH256 - HEIGHT32 = 0 << 2 - HEIGHT64 = 1 << 2 - HEIGHT128 = 2 << 2 - HEIGHT256 = 3 << 2 - .endenum - .scope TILE ; Tile geometry - .enum - WIDTH8 = 0 << 4 - WIDTH16 = 1 << 4 - WIDTH320 = WIDTH8 - WIDTH640 = WIDTH16 - HEIGHT8 = 0 << 5 - HEIGHT16 = 1 << 5 - .endenum - .enum FLIP - NONE = 0 << 2 - HORIZ = 1 << 2 - VERT = 2 << 2 - BOTH = 3 << 2 - .endenum - .endscope - .enum DMODE ; Display modes - TEXT16 = 0 << 5 - TEXT256 = 1 << 5 - TILE4 = 2 << 5 - TILE16 = 3 << 5 - TILE256 = 4 << 5 - BITMAP4 = 5 << 5 - BITMAP16 = 6 << 5 - BITMAP256 = 7 << 5 - .endenum .scope SPRITE - .struct - .org $0F4000 - CTRL .byte ; Enables sprite engine - COLLISION .byte - .endstruct - .struct ATTRIB ; Sprite attributes - .org $0F5000 - ADDR .addr ; Address and color mode - XX .word - YY .word - Z_FLIP .byte - SIZE_PAL .byte + .struct ; Sprite attributes + ADDR .addr ; Address and color mode + XX .word ; Co-ordinates + YY .word + Z_FLIP .byte ; Collision mask, Z-depth, flip bits + SIZE_PAL .byte .endstruct .enum FLIP - NONE = 0 + NONE = %00000000 HORIZ VERT BOTH .endenum .enum DEPTH - DISABLE = 0 << 2 - CANVAS = 1 << 2 - LAYER0 = 2 << 2 - LAYER1 = 3 << 2 + DISABLE = $00 << 2 + CANVAS = $01 << 2 + LAYER0 = $02 << 2 + LAYER1 = $03 << 2 .endenum .enum ; Sprite geometry - WIDTH8 = 0 << 4 - WIDTH16 = 1 << 4 - WIDTH32 = 2 << 4 - WIDTH64 = 3 << 4 - HEIGHT8 = 0 << 6 - HEIGHT16 = 1 << 6 - HEIGHT32 = 2 << 6 - HEIGHT64 = 3 << 6 - COLORS16 = 0 << 7 - COLORS256 = 1 << 7 - .endenum - .endscope - AUDIO := $0F6000 - .scope SPI - .struct - .org $0F7000 - DATA .byte - CONTROL .byte - .endstruct - .enum - DESELECT = 0 - SELECT - BUSY_MASK = 1 << 1 - .endenum - .endscope - .scope UART ; Universal Asyncronous Receiver Transmitter - .struct - .org $0F8000 - DATA .byte - STATUS .byte - BPS_DIV .word - .endstruct - .enum MASK - RECEIVE = 1 << 0 - TRANSMIT = 1 << 1 + WIDTH8 = $00 << 4 + WIDTH16 = $01 << 4 + WIDTH32 = $02 << 4 + WIDTH64 = $03 << 4 + HEIGHT8 = $00 << 6 + HEIGHT16 = $01 << 6 + HEIGHT32 = $02 << 6 + HEIGHT64 = $03 << 6 + COLORS16 = $00 << 7 + COLORS256 = $01 << 7 .endenum .endscope + .struct + .org $01FC00 + SPRITES .res 128 * 8 + .endstruct .endscope ; 65C22 @@ -516,8 +554,8 @@ NMIVec := $0318 ; --------------------------------------------------------------------------- ; Banked RAM and ROM -KEY_COUNT := $A00B ; (bank 0) Number of keys in input buffer -TIMER := $A03E ; (bank 0) 60 Hz. timer (3 bytes, big-endian) +KEY_COUNT := $A00A ; (bank 0) Number of keys in input buffer +TIMER := $A037 ; (bank 0) 60 Hz. timer (3 bytes, big-endian) .struct BANK .org $A000 diff --git a/include/cx16.h b/include/cx16.h index 6ceb605c9..253fa2482 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -2,7 +2,8 @@ /* */ /* cx16.h */ /* */ -/* CX16 system-specific definitions */ +/* CX16 system-specific definitions */ +/* For prerelease 37 */ /* */ /* */ /* This software is provided "as-is", without any expressed or implied */ @@ -140,14 +141,16 @@ /* get_tv() return codes ** set_tv() argument codes */ -#define TV_NONE 0 -#define TV_VGA 1 -#define TV_NTSC_COLOR 2 -#define TV_RGB 3 -#define TV_NONE2 4 -#define TV_VGA2 5 -#define TV_NTSC_MONO 6 -#define TV_RGB2 7 +enum { + TV_NONE = 0x00, + TV_VGA, + TV_NTSC_COLOR, + TV_RGB, + TV_NONE2, + TV_VGA2, + TV_NTSC_MONO, + TV_RGB2 +}; /* Video modes for videomode() */ #define VIDEOMODE_40x30 0x00 @@ -157,11 +160,47 @@ #define VIDEOMODE_320x200 0x80 #define VIDEOMODE_SWAP (-1) +/* VERA's address increment/decrement numbers */ +enum { + VERA_DEC_0 = ((0 << 1) | 1) << 3, + VERA_DEC_1 = ((1 << 1) | 1) << 3, + VERA_DEC_2 = ((2 << 1) | 1) << 3, + VERA_DEC_4 = ((3 << 1) | 1) << 3, + VERA_DEC_8 = ((4 << 1) | 1) << 3, + VERA_DEC_16 = ((5 << 1) | 1) << 3, + VERA_DEC_32 = ((6 << 1) | 1) << 3, + VERA_DEC_64 = ((7 << 1) | 1) << 3, + VERA_DEC_128 = ((8 << 1) | 1) << 3, + VERA_DEC_256 = ((9 << 1) | 1) << 3, + VERA_DEC_512 = ((10 << 1) | 1) << 3, + VERA_DEC_40 = ((11 << 1) | 1) << 3, + VERA_DEC_80 = ((12 << 1) | 1) << 3, + VERA_DEC_160 = ((13 << 1) | 1) << 3, + VERA_DEC_320 = ((14 << 1) | 1) << 3, + VERA_DEC_640 = ((15 << 1) | 1) << 3, + VERA_INC_0 = ((0 << 1) | 0) << 3, + VERA_INC_1 = ((1 << 1) | 0) << 3, + VERA_INC_2 = ((2 << 1) | 0) << 3, + VERA_INC_4 = ((3 << 1) | 0) << 3, + VERA_INC_8 = ((4 << 1) | 0) << 3, + VERA_INC_16 = ((5 << 1) | 0) << 3, + VERA_INC_32 = ((6 << 1) | 0) << 3, + VERA_INC_64 = ((7 << 1) | 0) << 3, + VERA_INC_128 = ((8 << 1) | 0) << 3, + VERA_INC_256 = ((9 << 1) | 0) << 3, + VERA_INC_512 = ((10 << 1) | 0) << 3, + VERA_INC_40 = ((11 << 1) | 0) << 3, + VERA_INC_80 = ((12 << 1) | 0) << 3, + VERA_INC_160 = ((13 << 1) | 0) << 3, + VERA_INC_320 = ((14 << 1) | 0) << 3, + VERA_INC_640 = ((15 << 1) | 0) << 3 +}; + /* VERA's interrupt flags */ #define VERA_IRQ_VSYNC 0b00000001 #define VERA_IRQ_RASTER 0b00000010 #define VERA_IRQ_SPR_COLL 0b00000100 -#define VERA_IRQ_UART 0b00001000 +#define VERA_IRQ_AUDIO_LOW 0b00001000 /* Define hardware. */ @@ -175,6 +214,44 @@ struct __vera { unsigned char control; /* Control register */ unsigned char irq_enable; /* Interrupt enable bits */ unsigned char irq_flags; /* Interrupt flags */ + unsigned char irq_raster; /* Line where IRQ will occur */ + union { + struct { /* Visible when DCSEL flag = 0 */ + unsigned char video; /* Flags to enable video layers */ + unsigned char hscale; /* Horizontal scale factor */ + unsigned char vscale; /* Vertical scale factor */ + unsigned char border; /* Border color (NTSC mode) */ + }; + struct { /* Visible when DCSEL flag = 1 */ + unsigned char hstart; /* Horizontal start position */ + unsigned char hstop; /* Horizontal stop position */ + unsigned char vstart; /* Vertical start position */ + unsigned char vstop; /* Vertical stop position */ + }; + } display; + struct { + unsigned char config; /* Layer map geometry */ + unsigned char mapbase; /* Map data address */ + unsigned char tilebase; /* Tile address and geometry */ + unsigned int hscroll; /* Smooth scroll horizontal offset */ + unsigned int vscroll; /* Smooth scroll vertical offset */ + } layer0; + struct { + unsigned char config; + unsigned char mapbase; + unsigned char tilebase; + unsigned int hscroll; + unsigned int vscroll; + } layer1; + struct { + unsigned char control; /* PCM format */ + unsigned char rate; /* Sample rate */ + unsigned char data; /* PCM output queue */ + } audio; /* Pulse-Code Modulation registers */ + struct { + unsigned char data; + unsigned char control; + } spi; /* SD card interface */ }; #define VERA (*(volatile struct __vera *)0x9F20) @@ -214,7 +291,7 @@ extern void cx16_std_mou[]; /* Referred to by mouse_static_stddrv[] -unsigned char get_numbanks (void); +unsigned short get_numbanks (void); /* Return the number of RAM banks that the machine has. */ signed char get_ostype (void); @@ -234,6 +311,17 @@ void __fastcall__ set_tv (unsigned char type); ** Call with a TV_xx constant. */ +unsigned char __fastcall__ vera_layer_enable (unsigned char layers); +/* Display the layers that are "named" by the bit flags in layers. +** A value of 0b01 shows layer 0, a value of 0b10 shows layer 1, +** a value of 0b11 shows both layers. Return the previous value. +*/ + +unsigned char __fastcall__ vera_sprites_enable (unsigned char mode); +/* Enable the sprite engine when mode is non-zero (true); +** disable sprites when mode is zero. Return the previous mode. +*/ + signed char __fastcall__ videomode (signed char mode); /* Set the video mode, return the old mode. ** Return -1 if Mode isn't valid. diff --git a/libsrc/cx16/bordercolor.s b/libsrc/cx16/bordercolor.s index 6691e2ec5..d152d1aa6 100644 --- a/libsrc/cx16/bordercolor.s +++ b/libsrc/cx16/bordercolor.s @@ -1,5 +1,5 @@ ; -; 2019-09-23, Greg King +; 2020-05-02, Greg King ; ; unsigned char __fastcall__ bordercolor (unsigned char color); ; /* Set the color for the border. The old color setting is returned. */ @@ -11,17 +11,7 @@ _bordercolor: tax - - ; Point to the border color register. - - stz VERA::CTRL ; Use port 0 - lda #<VERA::COMPOSER::FRAME - sta VERA::ADDR - lda #>VERA::COMPOSER::FRAME - sta VERA::ADDR+1 - ldy #^VERA::COMPOSER::FRAME | VERA::INC0 - sty VERA::ADDR+2 - - lda VERA::DATA0 ; get old value - stx VERA::DATA0 ; set new value + stz VERA::CTRL ; Use display register bank 0 + lda VERA::DISP::FRAME ; get old value + stx VERA::DISP::FRAME ; set new value rts diff --git a/libsrc/cx16/cpeekc.s b/libsrc/cx16/cpeekc.s index f7a7d2081..6756d995a 100644 --- a/libsrc/cx16/cpeekc.s +++ b/libsrc/cx16/cpeekc.s @@ -1,6 +1,6 @@ ; ; 2016-02-28, Groepaz -; 2019-09-25, Greg King +; 2020-04-29, Greg King ; ; char cpeekc (void); ; /* Return the character from the current cursor position. */ @@ -12,8 +12,6 @@ _cpeekc: - php - sei ; don't let cursor blinking interfere stz VERA::CTRL ; use port 0 lda CURS_Y sta VERA::ADDR+1 ; set row number @@ -22,7 +20,6 @@ _cpeekc: asl a ; each character has two bytes sta VERA::ADDR lda VERA::DATA0 ; get screen code - plp ldx #>$0000 and #<~%10000000 ; remove reverse bit diff --git a/libsrc/cx16/cpeekcolor.s b/libsrc/cx16/cpeekcolor.s index 4e3a39a2c..9c167b07a 100644 --- a/libsrc/cx16/cpeekcolor.s +++ b/libsrc/cx16/cpeekcolor.s @@ -1,5 +1,5 @@ ; -; 2019-09-25, Greg King +; 2020-04-30, Greg King ; ; unsigned char cpeekcolor (void); ; /* Return the colors from the current cursor position. */ @@ -12,8 +12,15 @@ _cpeekcolor: php + lda CURS_FLAG ; is the cursor currently off? + bne @L1 sei ; don't let cursor blinking interfere - stz VERA::CTRL ; use port 0 + ldx CURS_STATE ; is cursor currently displayed? + beq @L1 ; jump if not + lda CURS_COLOR ; get color under cursor + bra @L2 + +@L1: stz VERA::CTRL ; use port 0 lda CURS_Y sta VERA::ADDR+1 ; set row number stz VERA::ADDR+2 @@ -21,7 +28,7 @@ _cpeekcolor: sec ; color attribute is second byte rol a sta VERA::ADDR - lda VERA::DATA0 ; get color - plp + lda VERA::DATA0 ; get color of character +@L2: plp ldx #>$0000 rts diff --git a/libsrc/cx16/cpeekrevers.s b/libsrc/cx16/cpeekrevers.s index 15131d348..fd7428779 100644 --- a/libsrc/cx16/cpeekrevers.s +++ b/libsrc/cx16/cpeekrevers.s @@ -1,6 +1,6 @@ ; ; 2016-02-28, Groepaz -; 2019-09-25, Greg King +; 2020-04-30, Greg King ; ; unsigned char cpeekrevers (void); ; /* Return the reverse attribute from the current cursor position. @@ -15,8 +15,15 @@ _cpeekrevers: php + lda CURS_FLAG ; is the cursor currently off? + bne @L1 sei ; don't let cursor blinking interfere - stz VERA::CTRL ; use port 0 + ldx CURS_STATE ; is cursor currently displayed? + beq @L1 ; jump if not + lda CURS_CHAR ; get screen code under cursor + bra @L2 + +@L1: stz VERA::CTRL ; use port 0 lda CURS_Y sta VERA::ADDR+1 ; set row number stz VERA::ADDR+2 @@ -24,7 +31,7 @@ _cpeekrevers: asl a ; each character has two bytes sta VERA::ADDR lda VERA::DATA0 ; get screen code - plp +@L2: plp and #%10000000 ; get reverse bit asl a tax ; ldx #>$0000 diff --git a/libsrc/cx16/cputc.s b/libsrc/cx16/cputc.s index 11c4f5782..034c3e389 100644 --- a/libsrc/cx16/cputc.s +++ b/libsrc/cx16/cputc.s @@ -86,9 +86,9 @@ putchar: stz VERA::CTRL ; Use port 0 lda CURS_Y sta VERA::ADDR+1 ; Set row number - lda #VERA::INC1 ; Increment address by one + lda #VERA::INC1 ; Address increments by one sta VERA::ADDR+2 - ldy CURS_X ; Get character column + ldy CURS_X ; Get character column into .Y tya asl a ; Each character has two bytes sta VERA::ADDR diff --git a/libsrc/cx16/crt0.s b/libsrc/cx16/crt0.s index d709ea96f..be83927fc 100644 --- a/libsrc/cx16/crt0.s +++ b/libsrc/cx16/crt0.s @@ -22,7 +22,7 @@ Start: tsx stx spsave ; Save the system stack ptr -; Save space by putting some of the start-up code in the ONCE segment, +; Save space by putting some of the start-up code in the ONCE segment ; which will be re-used by the BSS segment, the heap, and the C stack. jsr init @@ -31,7 +31,7 @@ Start: tsx jsr zerobss -; Push the command-line arguments; and, call main(). +; Push the command-line arguments, and call main(). jsr callmain @@ -46,7 +46,7 @@ _exit: jsr donelib -.if 0 ; We don't need to preserve zero-page space for cc65's variables. +.if 0 ; (We don't need to preserve zero-page space for cc65's variables.) ; Copy back the zero-page stuff. ldx #zpspace-1 @@ -90,7 +90,7 @@ init: lda #$01 sta VIA1::PRA -.if 0 ; We don't need to preserve zero-page space for cc65's variables. +.if 0 ; (We don't need to preserve zero-page space for cc65's variables.) ; Save the zero-page locations that we need. ldx #zpspace-1 diff --git a/libsrc/cx16/exec.c b/libsrc/cx16/exec.c index 17a547e68..a6633a9c3 100644 --- a/libsrc/cx16/exec.c +++ b/libsrc/cx16/exec.c @@ -1,7 +1,7 @@ /* ** Program-chaining function for Commodore platforms. ** -** 2019-12-25, Greg King +** 2020-04-27, Greg King ** ** This function exploits the program-chaining feature in Commander X16 BASIC's ROM. ** @@ -71,26 +71,28 @@ extern void basbuf_len[]; int __fastcall__ exec (const char* progname, const char* cmdline) { +#if 0 static int fd; +#endif static unsigned char dv, n; /* Exclude devices that can't load files. */ /* (Use hand optimization, to make smaller code.) */ dv = getcurrentdevice (); - if (dv < 8 && __AX__ != 1 || __AX__ > 30) { + if (dv < 8 || __A__ > 30) { return _mappederrno (9); /* illegal device number */ } utoa (dv, basic.unit, 10); /* The emulator supports only loading and saving on its file-system. */ - if (dv != 1) { - /* Don't try to run a program that doesn't exist. */ - fd = open (progname, O_RDONLY); - if (fd < 0) { - return _mappederrno (4); /* file not found */ - } - close (fd); +#if 0 + /* Don't try to run a program that doesn't exist. */ + fd = open (progname, O_RDONLY); + if (fd < 0) { + return _mappederrno (4); /* file not found */ } + close (fd); +#endif n = 0; do { diff --git a/libsrc/cx16/get_numbanks.s b/libsrc/cx16/get_numbanks.s index 00490fb72..7654d3139 100644 --- a/libsrc/cx16/get_numbanks.s +++ b/libsrc/cx16/get_numbanks.s @@ -1,11 +1,12 @@ ; -; 2020-01-10, Greg King +; 2020-01-29, Greg King ; -; unsigned char get_numbanks (void); +; unsigned short get_numbanks (void); ; /* Return the number of RAM banks that the machine has. */ ; ; The Commander X16 version of MEMTOP returns with an extra value: ; The accumulator describes the number of RAM banks that exist on the hardware. +; A zero accumulator means that there are 256 RAM banks. ; .export _get_numbanks @@ -17,4 +18,7 @@ _get_numbanks: sec jsr MEMTOP ldx #>$0000 - rts + cmp #<$0100 ; are there 256 banks? + bne :+ + inx ; yes +: rts diff --git a/libsrc/cx16/get_tv.s b/libsrc/cx16/get_tv.s index 291a32cde..6c1cc6ad8 100644 --- a/libsrc/cx16/get_tv.s +++ b/libsrc/cx16/get_tv.s @@ -1,5 +1,5 @@ ; -; 2019-12-22, Greg King +; 2020-05-02, Greg King ; ; unsigned char get_tv (void); ; /* Return the video mode the machine is using. */ @@ -11,17 +11,9 @@ .proc _get_tv - ; Point to the video output register. - - stz VERA::CTRL ; Use port 0 - lda #<VERA::COMPOSER::VIDEO - ldx #>VERA::COMPOSER::VIDEO - ldy #^VERA::COMPOSER::VIDEO - sta VERA::ADDR - stx VERA::ADDR+1 - sty VERA::ADDR+2 - - lda VERA::DATA0 - and #$07 ; Get the type of output signal + stz VERA::CTRL ; Use display register bank 0 + lda VERA::DISP::VIDEO + and #%00000111 ; Get the type of output signal + ldx #>$0000 ; Promote to unsigned int rts .endproc diff --git a/libsrc/cx16/kernal.s b/libsrc/cx16/kernal.s index a6b65ebbd..a252569e5 100644 --- a/libsrc/cx16/kernal.s +++ b/libsrc/cx16/kernal.s @@ -1,11 +1,15 @@ ; -; 2020-01-06, Greg King +; 2020-04-27, Greg King ; ; CX16 Kernal functions ; .include "cbm_kernal.inc" + .export ENTROPY_GET + .export KEYBRD_BUF_PUT + .export CONSOLE_SET_PAGE_MSG + .export CONSOLE_PUT_IMAGE .export CONSOLE_INIT .export CONSOLE_PUT_CHAR .export CONSOLE_GET_CHAR diff --git a/libsrc/cx16/layer_enable.s b/libsrc/cx16/layer_enable.s new file mode 100644 index 000000000..2cbd6714f --- /dev/null +++ b/libsrc/cx16/layer_enable.s @@ -0,0 +1,39 @@ +; +; 2020-05-02, Greg King +; +; unsigned char __fastcall__ vera_layer_enable (unsigned char layers); +; /* Display the layers that are "named" by the bit flags in layers. +; ** A value of 0b01 shows layer 0, a value of 0b10 shows layer 1, +; ** a value of 0b11 shows both layers. Return the previous value. +; */ +; + + .export _vera_layer_enable + + .include "cx16.inc" + + +mask = VERA::DISP::ENABLE::LAYER1 | VERA::DISP::ENABLE::LAYER0 + +.proc _vera_layer_enable + stz VERA::CTRL ; Use display register bank 0 + asl a + asl a ; Shift new flags into position + asl a + asl a + ldy VERA::DISP::VIDEO + + eor VERA::DISP::VIDEO + and #mask + eor VERA::DISP::VIDEO ; Replace old flags with new flags + sta VERA::DISP::VIDEO + + tya + and #mask ; Get old flags + lsr a + lsr a + lsr a + lsr a + ldx #>$0000 + rts +.endproc diff --git a/libsrc/cx16/randomize.s b/libsrc/cx16/randomize.s new file mode 100644 index 000000000..3d965c82a --- /dev/null +++ b/libsrc/cx16/randomize.s @@ -0,0 +1,14 @@ +; +; 2020-05-02, Greg King +; +; void _randomize (void); +; /* Initialize the random number generator */ +; + + .export __randomize + + .import ENTROPY_GET, _srand + +__randomize: + jsr ENTROPY_GET + jmp _srand ; Initialize generator diff --git a/libsrc/cx16/set_tv.s b/libsrc/cx16/set_tv.s index c23568c67..1779e895e 100644 --- a/libsrc/cx16/set_tv.s +++ b/libsrc/cx16/set_tv.s @@ -1,5 +1,5 @@ ; -; 2019-12-22, Greg King +; 2020-05-02, Greg King ; ; void __fastcall__ set_tv (unsigned char); ; /* Set the video mode the machine will use. */ @@ -11,16 +11,10 @@ .proc _set_tv - ; Point to the video output register. - - stz VERA::CTRL ; Use port 0 - ldx #<VERA::COMPOSER::VIDEO - ldy #>VERA::COMPOSER::VIDEO - stx VERA::ADDR - sty VERA::ADDR+1 - ldx #^VERA::COMPOSER::VIDEO - stx VERA::ADDR+2 - - sta VERA::DATA0 + stz VERA::CTRL ; Use display register bank 0 + eor VERA::DISP::VIDEO + and #%00000111 + eor VERA::DISP::VIDEO ; Replace old mode with new mode + sta VERA::DISP::VIDEO rts .endproc diff --git a/libsrc/cx16/sprites_enable.s b/libsrc/cx16/sprites_enable.s new file mode 100644 index 000000000..73924233c --- /dev/null +++ b/libsrc/cx16/sprites_enable.s @@ -0,0 +1,34 @@ +; +; 2020-05-02, Greg King +; +; unsigned char __fastcall__ vera_sprites_enable (unsigned char mode); +; /* Enable the sprite engine when mode is non-zero (true); +; ** disable sprites when mode is zero. Return the previous mode. +; */ +; + + .export _vera_sprites_enable + + .include "cx16.inc" + + +.proc _vera_sprites_enable + stz VERA::CTRL ; Use display register bank 0 + tax ; Is mode true? + beq :+ + lda #VERA::DISP::ENABLE::SPRITES ; Yes +: ldy VERA::DISP::VIDEO + + eor VERA::DISP::VIDEO + and #VERA::DISP::ENABLE::SPRITES + eor VERA::DISP::VIDEO ; Replace old flag with new flag + sta VERA::DISP::VIDEO + + tya + and #VERA::DISP::ENABLE::SPRITES ; Get old value + asl a + asl a + rol a ; Make it boolean + ldx #>$0000 + rts +.endproc From 5b56c6e3a2b1ceff1a55e02793fce46f84b98243 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 4 May 2020 22:22:32 +0200 Subject: [PATCH 1289/2161] Disable potentially enabled double-width graphics. --- asminc/apple2.inc | 22 ++++++++++++++-------- libsrc/apple2/tgi/a2.hi.s | 4 ++++ libsrc/apple2/tgi/a2.lo.s | 4 ++++ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/asminc/apple2.inc b/asminc/apple2.inc index 536a1d851..226a85778 100644 --- a/asminc/apple2.inc +++ b/asminc/apple2.inc @@ -50,15 +50,21 @@ LCBANK2 := $C083 ; Swap in LC bank 2 LCBANK1 := $C08B ; Swap in LC bank 1 ; Video mode switches -TXTCLR := $C050 ; Display graphics -TXTSET := $C051 ; Display text -MIXCLR := $C052 ; Disable 4 lines of text -MIXSET := $C053 ; Enable 4 lines of text -LOWSCR := $C054 ; Page 1 -HISCR := $C055 ; Page 2 -LORES := $C056 ; Lores graphics -HIRES := $C057 ; Hires graphics +TXTCLR := $C050 ; Display graphics +TXTSET := $C051 ; Display text +MIXCLR := $C052 ; Disable 4 lines of text +MIXSET := $C053 ; Enable 4 lines of text +LOWSCR := $C054 ; Page 1 +HISCR := $C055 ; Page 2 +LORES := $C056 ; Lores graphics +HIRES := $C057 ; Hires graphics +DHIRESON := $C05E ; Enable double-width graphics +DHIRESOFF := $C05F ; Disable double-width graphics ; Game controller BUTN0 := $C061 ; Open-Apple Key BUTN1 := $C062 ; Closed-Apple Key + +; IOU +IOUDISON := $C07E ; Disable IOU +IOUDISOFF := $C07F ; Enable IOU diff --git a/libsrc/apple2/tgi/a2.hi.s b/libsrc/apple2/tgi/a2.hi.s index e06b4a617..aeb24f6be 100644 --- a/libsrc/apple2/tgi/a2.hi.s +++ b/libsrc/apple2/tgi/a2.hi.s @@ -175,6 +175,10 @@ INIT: ; Switch into graphics mode bit MIXCLR bit HIRES + .ifdef __APPLE2ENH__ + sta IOUDISON + bit DHIRESOFF + .endif bit TXTCLR ; Beagle Bros Shape Mechanic fonts don't diff --git a/libsrc/apple2/tgi/a2.lo.s b/libsrc/apple2/tgi/a2.lo.s index 2f5485e02..6d1c6aa4a 100644 --- a/libsrc/apple2/tgi/a2.lo.s +++ b/libsrc/apple2/tgi/a2.lo.s @@ -126,6 +126,10 @@ INIT: bit $C082 ; Switch in ROM jsr SETGR bit MIXCLR + .ifdef __APPLE2ENH__ + sta IOUDISON + bit DHIRESOFF + .endif bit $C080 ; Switch in LC bank 2 for R/O ; Done, reset the error code From ad1eadd60ddd174605f88318c0b0faee34ed939d Mon Sep 17 00:00:00 2001 From: Chris Cacciatore <chris.cacciatore@gmail.com> Date: Fri, 8 May 2020 15:33:30 -0700 Subject: [PATCH 1290/2161] Added support for --large-alignment in ld65. Implemented the same way as in ca65. --- doc/ld65.sgml | 7 +++++++ src/ld65/global.c | 6 ++++-- src/ld65/global.h | 2 ++ src/ld65/main.c | 10 ++++++++++ src/ld65/segments.c | 2 +- 5 files changed, 24 insertions(+), 3 deletions(-) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 97233271c..f3ba3bdc9 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -79,6 +79,7 @@ Long options: --end-group End a library group --force-import sym Force an import of symbol 'sym' --help Help (this text) + --large-alignment Don't warn about large alignments --lib file Link this library --lib-path path Specify a library search path --mapfile name Create a map file @@ -298,6 +299,12 @@ Here is a description of all of the command-line options: information generation is currently being developed, so the format of the file and its contents are subject to change without further notice. + <label id="option--large-alignment"> + <tag><tt>--large-alignment</tt></tag> + + Disable warnings about a large combined alignment. See the discussion of the + <tt><ref id=".ALIGN" name=".ALIGN"></tt> directive for futher information. + <tag><tt>--lib file</tt></tag> diff --git a/src/ld65/global.c b/src/ld65/global.c index 59c3754e6..8f43232fe 100644 --- a/src/ld65/global.c +++ b/src/ld65/global.c @@ -52,8 +52,10 @@ unsigned ModuleId = 0; /* Id for o65 module */ unsigned char HaveStartAddr = 0; /* Start address not given */ unsigned long StartAddr = 0x200; /* Start address */ -unsigned char VerboseMap = 0; /* Verbose map file */ -unsigned char AllowMultDef = 0; /* Allow multiple definitions */ +unsigned char VerboseMap = 0; /* Verbose map file */ +unsigned char AllowMultDef = 0; /* Allow multiple definitions */ +unsigned char LargeAlignment = 0; /* Don't warn about large alignments */ + const char* MapFileName = 0; /* Name of the map file */ const char* LabelFileName = 0; /* Name of the label file */ const char* DbgFileName = 0; /* Name of the debug file */ diff --git a/src/ld65/global.h b/src/ld65/global.h index 6af265f45..a923f6de5 100644 --- a/src/ld65/global.h +++ b/src/ld65/global.h @@ -54,6 +54,8 @@ extern unsigned long StartAddr; /* Start address */ extern unsigned char VerboseMap; /* Verbose map file */ extern unsigned char AllowMultDef; /* Allow multiple definitions */ +extern unsigned char LargeAlignment; /* Don't warn about large alignments */ + extern const char* MapFileName; /* Name of the map file */ extern const char* LabelFileName; /* Name of the label file */ extern const char* DbgFileName; /* Name of the debug file */ diff --git a/src/ld65/main.c b/src/ld65/main.c index a3fd81143..f2415a914 100644 --- a/src/ld65/main.c +++ b/src/ld65/main.c @@ -136,6 +136,7 @@ static void Usage (void) " --end-group\t\t\tEnd a library group\n" " --force-import sym\t\tForce an import of symbol 'sym'\n" " --help\t\t\tHelp (this text)\n" + " --large-alignment\t\tDon't warn about large alignments\n" " --lib file\t\t\tLink this library\n" " --lib-path path\t\tSpecify a library search path\n" " --mapfile name\t\tCreate a map file\n" @@ -406,6 +407,14 @@ static void OptHelp (const char* Opt attribute ((unused)), +static void OptLargeAlignment (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Don't warn about large alignments */ +{ + LargeAlignment = 1; +} + + static void OptLib (const char* Opt attribute ((unused)), const char* Arg) /* Link a library */ { @@ -617,6 +626,7 @@ static void ParseCommandLine(void) { "--end-group", 0, CmdlOptEndGroup }, { "--force-import", 1, OptForceImport }, { "--help", 0, OptHelp }, + { "--large-alignment", 0, OptLargeAlignment }, { "--lib", 1, OptLib }, { "--lib-path", 1, OptLibPath }, { "--mapfile", 1, OptMapFile }, diff --git a/src/ld65/segments.c b/src/ld65/segments.c index 56a4719ad..10d2cda2c 100644 --- a/src/ld65/segments.c +++ b/src/ld65/segments.c @@ -230,7 +230,7 @@ Section* ReadSection (FILE* F, ObjData* O) "%lu. Last module requiring alignment was '%s'.", GetString (Name), Alignment, MAX_ALIGNMENT, GetObjFileName (O)); - } else if (Alignment >= LARGE_ALIGNMENT) { + } else if (Alignment >= LARGE_ALIGNMENT && !LargeAlignment) { Warning ("Combined alignment for segment '%s' is suspiciously " "large (%lu). Last module requiring alignment was '%s'.", GetString (Name), Alignment, GetObjFileName (O)); From 3adeb0f90777ab25d95a604dfba9791a8f8486e1 Mon Sep 17 00:00:00 2001 From: Chris Cacciatore <chris.cacciatore@gmail.com> Date: Sun, 10 May 2020 11:40:19 -0700 Subject: [PATCH 1291/2161] Removed invalid link to ca65 document. --- doc/ld65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index f3ba3bdc9..6cdf78800 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -303,7 +303,7 @@ Here is a description of all of the command-line options: <tag><tt>--large-alignment</tt></tag> Disable warnings about a large combined alignment. See the discussion of the - <tt><ref id=".ALIGN" name=".ALIGN"></tt> directive for futher information. + <tt/.ALIGN/ directive in the ca65 Users Guide for futher information. <tag><tt>--lib file</tt></tag> From f8be35b41e2225d64b93da654cc8fb80c75c95b9 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 15 May 2020 21:09:02 -0400 Subject: [PATCH 1292/2161] Fixed some typos in the "large alignment" support. --- doc/ca65.sgml | 2 +- doc/ld65.sgml | 2 +- src/ca65/segment.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index ad72189c0..2c4593d21 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -226,7 +226,7 @@ Here is a description of all the command line options: <tag><tt>--large-alignment</tt></tag> Disable warnings about a large combined alignment. See the discussion of the - <tt><ref id=".ALIGN" name=".ALIGN"></tt> directive for futher information. + <tt><ref id=".ALIGN" name=".ALIGN"></tt> directive for further information. <label id="option--list-bytes"> diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 6cdf78800..d8e296996 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -303,7 +303,7 @@ Here is a description of all of the command-line options: <tag><tt>--large-alignment</tt></tag> Disable warnings about a large combined alignment. See the discussion of the - <tt/.ALIGN/ directive in the ca65 Users Guide for futher information. + <tt/.ALIGN/ directive in the ca65 Users Guide for further information. <tag><tt>--lib file</tt></tag> diff --git a/src/ca65/segment.c b/src/ca65/segment.c index aa9a48512..fa4e97dd0 100644 --- a/src/ca65/segment.c +++ b/src/ca65/segment.c @@ -306,7 +306,7 @@ void SegAlign (unsigned long Alignment, int FillVal) ActiveSeg->Align = CombinedAlignment; /* Output a warning for larger alignments if not suppressed */ - if (CombinedAlignment > LARGE_ALIGNMENT && !LargeAlignment) { + if (CombinedAlignment >= LARGE_ALIGNMENT && !LargeAlignment) { Warning (0, "Combined alignment is suspiciously large (%lu)", CombinedAlignment); } @@ -411,7 +411,7 @@ void SegDone (void) /* We cannot evaluate the expression now, leave the job for ** the linker. However, we can check if the address size - ** matches the fragment size. Mismatches are errors in + ** matches the fragment size. Mismatches are errors in ** most situations. */ if ((F->Len == 1 && ED.AddrSize > ADDR_SIZE_ZP) || From 532240a2db6d494093040b94fbcafccf886d507c Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 24 May 2020 22:47:20 +0200 Subject: [PATCH 1293/2161] Telestrat joystick management --- doc/telestrat.sgml | 13 +++- include/telestrat.h | 8 ++ libsrc/telestrat/joy/telestrat-joy.s | 109 +++++++++++++++++++++++++++ libsrc/telestrat/joy_stat_stddrv.s | 14 ++++ libsrc/telestrat/joy_stddrv.s | 13 ++++ libsrc/telestrat/libref.s | 3 +- 6 files changed, 155 insertions(+), 5 deletions(-) create mode 100644 libsrc/telestrat/joy/telestrat-joy.s create mode 100644 libsrc/telestrat/joy_stat_stddrv.s create mode 100644 libsrc/telestrat/joy_stddrv.s diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index 0cb40c501..6d62ef7b7 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -189,15 +189,20 @@ port cardridge. <sect1>Joystick drivers<p> -Telemon 2.4 & 3.0 manages joysticks but it had been handled yet. This means that -joysticks driver could be written easily. - Telemon 2.4 returns in keyboard buffer the direction of the joysticks. This means that if you get input from keyboard by conio cgetc function, you will get direction from joysticks. +Anyway, if you don't want to use ROM, you can use joysticks standard drivers in your code. + +The standard driver manages two joysticks. Only one button is managed for theses joysticks. + +Telestrat can handle one button for the left port, and three buttons for the right port (but this port was designed for a mouse). + +If you find a Telestrat mouse (which almost impossible :), these driver will work too because there is some extra hardware in the mouse to send direction. + <sect1>Mouse drivers<p> -Telestrat manages also mouse, but it had been no handled yet in this version. +Telestrat manages also mouse (Joystick port) Telestrat mouse is really difficult to find. <sect1>RS232 device drivers<p> diff --git a/include/telestrat.h b/include/telestrat.h index 1865f19a0..38762be1d 100644 --- a/include/telestrat.h +++ b/include/telestrat.h @@ -98,7 +98,15 @@ extern void telestrat_240_200_2_tgi[]; /* Referred to by tgi_static_stddrv[ #define CH_LIRA 95 #define CH_ESC 27 +/* Masks for joy_read */ +#define JOY_UP_MASK 0x10 +#define JOY_DOWN_MASK 0x08 +#define JOY_LEFT_MASK 0x01 +#define JOY_RIGHT_MASK 0x02 +#define JOY_BTN_1_MASK 0x04 +/* The addresses of the static drivers */ +extern void telestrat_joy[]; /* Referred to by joy_static_stddrv[] */ void oups(); void ping(); diff --git a/libsrc/telestrat/joy/telestrat-joy.s b/libsrc/telestrat/joy/telestrat-joy.s new file mode 100644 index 000000000..827e44a3f --- /dev/null +++ b/libsrc/telestrat/joy/telestrat-joy.s @@ -0,0 +1,109 @@ +; +; Telestrat joystick driver +; +; 2002-12-20, Based on Ullrich von Bassewitz's code. +; 2017-11-01, Stefan Haubenthal +; 2020-05-20n, Jede +; + + .include "joy-kernel.inc" + .include "joy-error.inc" + .include "telestrat.inc" + + .macpack module + + +; ------------------------------------------------------------------------ +; Header. Includes jump table + + module_header _telestrat_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 + +.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 #%11000000 + sta VIA2::DDRB + sta VIA2::PRB + ; We could detect joysticks because with previous command bit0,1,2,3,4 should be set to 1 after + ; But if some one press fire or press direction, we could reach others values which could break Joystick détection. + lda #<JOY_ERR_OK + ldx #>JOY_ERR_OK +; 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. +; +; How telestrat joysticks works +; PB7 and PB6 select right or left port +; When PB7 and PB6 are high, it controls two CA3083 (2 NPN transistors array) bases. +; In that case, PB0 to PB4 are set to high (it means no action are pressed) +; When the user press something then bit will be set to 0. +; bit 0 is right +; bit 1 is left +; bit 2 is fire +; ... + +READ: + beq right + lda #%10000000 + ora VIA2::PRB + sta VIA2::PRB + ; then read + lda VIA2::PRB + eor #%10011111 + rts +right: + lda #%01000000 + ora VIA2::PRB + sta VIA2::PRB + ; then read + lda VIA2::PRB + eor #%01011111 + + rts diff --git a/libsrc/telestrat/joy_stat_stddrv.s b/libsrc/telestrat/joy_stat_stddrv.s new file mode 100644 index 000000000..0c4c3667b --- /dev/null +++ b/libsrc/telestrat/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 _telestrat_joy + +.rodata + +_joy_static_stddrv := _telestrat_joy diff --git a/libsrc/telestrat/joy_stddrv.s b/libsrc/telestrat/joy_stddrv.s new file mode 100644 index 000000000..8dfdde36e --- /dev/null +++ b/libsrc/telestrat/joy_stddrv.s @@ -0,0 +1,13 @@ +; +; Name of the standard joystick driver +; +; Oliver Schmidt, 2012-11-01 +; +; const char joy_stddrv[]; +; + + .export _joy_stddrv + +.rodata + +_joy_stddrv: .asciiz "telestrat_joy" diff --git a/libsrc/telestrat/libref.s b/libsrc/telestrat/libref.s index bdd0a671a..c737396a5 100644 --- a/libsrc/telestrat/libref.s +++ b/libsrc/telestrat/libref.s @@ -2,7 +2,8 @@ ; Jede (jede@oric.org), 2017-10-16 ; - .export tgi_libref + .export joy_libref, tgi_libref .import _exit +joy_libref := _exit tgi_libref := _exit From 7ae64307285360c21c0c3c53f50f5f51ecd3237a Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 24 May 2020 22:49:26 +0200 Subject: [PATCH 1294/2161] Fix typo --- doc/telestrat.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/telestrat.sgml b/doc/telestrat.sgml index 6d62ef7b7..eac341880 100644 --- a/doc/telestrat.sgml +++ b/doc/telestrat.sgml @@ -198,7 +198,7 @@ The standard driver manages two joysticks. Only one button is managed for theses Telestrat can handle one button for the left port, and three buttons for the right port (but this port was designed for a mouse). -If you find a Telestrat mouse (which almost impossible :), these driver will work too because there is some extra hardware in the mouse to send direction. +If you find a Telestrat mouse (which is almost impossible :), these driver will work too because there is some extra hardware in the mouse to send direction. <sect1>Mouse drivers<p> From cd7abdb58df76a5bde864c435207a7e20a29666e Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 24 May 2020 22:52:31 +0200 Subject: [PATCH 1295/2161] Fix typo --- libsrc/telestrat/joy/telestrat-joy.s | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libsrc/telestrat/joy/telestrat-joy.s b/libsrc/telestrat/joy/telestrat-joy.s index 827e44a3f..1d1261ea7 100644 --- a/libsrc/telestrat/joy/telestrat-joy.s +++ b/libsrc/telestrat/joy/telestrat-joy.s @@ -53,7 +53,7 @@ INSTALL: sta VIA2::DDRB sta VIA2::PRB ; We could detect joysticks because with previous command bit0,1,2,3,4 should be set to 1 after - ; But if some one press fire or press direction, we could reach others values which could break Joystick détection. + ; But if some one press fire or press direction, we could reach others values which could break joystick detection. lda #<JOY_ERR_OK ldx #>JOY_ERR_OK ; rts ; Run into UNINSTALL instead @@ -84,9 +84,9 @@ COUNT: ; When PB7 and PB6 are high, it controls two CA3083 (2 NPN transistors array) bases. ; In that case, PB0 to PB4 are set to high (it means no action are pressed) ; When the user press something then bit will be set to 0. -; bit 0 is right -; bit 1 is left -; bit 2 is fire +; Bit 0 is right +; Bit 1 is left +; Bit 2 is fire ; ... READ: @@ -97,6 +97,7 @@ READ: ; then read lda VIA2::PRB eor #%10011111 + rts right: lda #%01000000 From e8b1d51d2869783fb8e767987ae11c09c706eed6 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 24 May 2020 23:31:12 +0200 Subject: [PATCH 1296/2161] Fix typo --- libsrc/telestrat/joy/telestrat-joy.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/telestrat/joy/telestrat-joy.s b/libsrc/telestrat/joy/telestrat-joy.s index 1d1261ea7..d15973a05 100644 --- a/libsrc/telestrat/joy/telestrat-joy.s +++ b/libsrc/telestrat/joy/telestrat-joy.s @@ -3,7 +3,7 @@ ; ; 2002-12-20, Based on Ullrich von Bassewitz's code. ; 2017-11-01, Stefan Haubenthal -; 2020-05-20n, Jede +; 2020-05-20, Jede ; .include "joy-kernel.inc" From 1d358a473498c741549346e922d2c7c932ac328e Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 25 May 2020 22:25:14 +0200 Subject: [PATCH 1297/2161] Fix bug --- libsrc/telestrat/joy/telestrat-joy.s | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/libsrc/telestrat/joy/telestrat-joy.s b/libsrc/telestrat/joy/telestrat-joy.s index d15973a05..073a75faf 100644 --- a/libsrc/telestrat/joy/telestrat-joy.s +++ b/libsrc/telestrat/joy/telestrat-joy.s @@ -91,18 +91,22 @@ COUNT: READ: beq right - lda #%10000000 - ora VIA2::PRB + + lda VIA2::PRB + and #%01111111 + ora #%01000000 sta VIA2::PRB ; then read lda VIA2::PRB eor #%10011111 rts -right: - lda #%01000000 - ora VIA2::PRB - sta VIA2::PRB +right: + lda VIA2::PRB + and #%10111111 + ora #%10000000 + sta VIA2::PRB + ; then read lda VIA2::PRB eor #%01011111 From 50192fc65e79156a03c8918a19b5d38e79e3771b Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 25 May 2020 22:28:08 +0200 Subject: [PATCH 1298/2161] Change name of the driver (telestrat-joy.s renamed to telestrat.s --- libsrc/telestrat/joy/{telestrat-joy.s => telestrat.s} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename libsrc/telestrat/joy/{telestrat-joy.s => telestrat.s} (100%) diff --git a/libsrc/telestrat/joy/telestrat-joy.s b/libsrc/telestrat/joy/telestrat.s similarity index 100% rename from libsrc/telestrat/joy/telestrat-joy.s rename to libsrc/telestrat/joy/telestrat.s From 6c2d578c6172a5a384402a2ff240c473308f4116 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Wed, 27 May 2020 22:44:37 +0200 Subject: [PATCH 1299/2161] Fix eor bug --- libsrc/telestrat/joy/telestrat.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/telestrat/joy/telestrat.s b/libsrc/telestrat/joy/telestrat.s index 073a75faf..e4a6d94f2 100644 --- a/libsrc/telestrat/joy/telestrat.s +++ b/libsrc/telestrat/joy/telestrat.s @@ -98,7 +98,7 @@ READ: sta VIA2::PRB ; then read lda VIA2::PRB - eor #%10011111 + eor #%01011111 rts right: @@ -109,6 +109,6 @@ right: ; then read lda VIA2::PRB - eor #%01011111 + eor #%10011111 rts From 6521930880e03ed5bea884d35eb9e9f4525a7aa1 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Wed, 27 May 2020 22:49:10 +0200 Subject: [PATCH 1300/2161] Fixed the name of the driver --- libsrc/telestrat/joy_stddrv.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/telestrat/joy_stddrv.s b/libsrc/telestrat/joy_stddrv.s index 8dfdde36e..c8d8c2495 100644 --- a/libsrc/telestrat/joy_stddrv.s +++ b/libsrc/telestrat/joy_stddrv.s @@ -10,4 +10,4 @@ .rodata -_joy_stddrv: .asciiz "telestrat_joy" +_joy_stddrv: .asciiz "telestrat.joy" From 3890492a9bf9b88c3fce2900c59336ad14ddc8ce Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 28 May 2020 09:59:21 -0400 Subject: [PATCH 1301/2161] Added a JOY_FIRE() macro to the Atmos and Telestrat C headers. --- include/atmos.h | 3 +++ include/telestrat.h | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/include/atmos.h b/include/atmos.h index d9f6d103b..227c387aa 100644 --- a/include/atmos.h +++ b/include/atmos.h @@ -120,6 +120,9 @@ #define JOY_RIGHT_MASK 0x02 #define JOY_BTN_1_MASK 0x20 +#define JOY_FIRE_MASK JOY_BTN_1_MASK +#define JOY_FIRE(v) ((v) & JOY_FIRE_MASK) + /* No support for dynamically loadable drivers */ diff --git a/include/telestrat.h b/include/telestrat.h index 38762be1d..524f7d39f 100644 --- a/include/telestrat.h +++ b/include/telestrat.h @@ -105,6 +105,10 @@ extern void telestrat_240_200_2_tgi[]; /* Referred to by tgi_static_stddrv[ #define JOY_RIGHT_MASK 0x02 #define JOY_BTN_1_MASK 0x04 +#define JOY_FIRE_MASK JOY_BTN_1_MASK +#define JOY_FIRE(v) ((v) & JOY_FIRE_MASK) + + /* The addresses of the static drivers */ extern void telestrat_joy[]; /* Referred to by joy_static_stddrv[] */ From 68eb0f2cdc5c7d9c770c261d0b819de13d29e805 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 28 May 2020 10:33:08 -0400 Subject: [PATCH 1302/2161] Put the Telestrat static drivers names together. --- include/telestrat.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/include/telestrat.h b/include/telestrat.h index 524f7d39f..a4648a3dc 100644 --- a/include/telestrat.h +++ b/include/telestrat.h @@ -55,9 +55,6 @@ #define TGI_COLOR_RED 7 -extern void telestrat_228_200_3_tgi[]; -extern void telestrat_240_200_2_tgi[]; /* Referred to by tgi_static_stddrv[] */ - /* Define hardware */ #include <_6522.h> #define VIA (*(struct __6522*)0x300) @@ -110,7 +107,10 @@ extern void telestrat_240_200_2_tgi[]; /* Referred to by tgi_static_stddrv[ /* The addresses of the static drivers */ -extern void telestrat_joy[]; /* Referred to by joy_static_stddrv[] */ +extern void telestrat_joy[]; /* Referred to by joy_static_stddrv[] */ +extern void telestrat_228_200_3_tgi[]; +extern void telestrat_240_200_2_tgi[]; /* Referred to by tgi_static_stddrv[] */ + void oups(); void ping(); @@ -119,7 +119,3 @@ void shoot(); void explode(); void kbdclick1(); - - - - From 083f3ae26b13e2c15ac559a5be78febca38f06ed Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Mon, 25 May 2020 23:43:28 -0700 Subject: [PATCH 1303/2161] Fix for #928. --- src/ld65/bin.c | 8 +++++++- src/ld65/config.c | 6 ++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/ld65/bin.c b/src/ld65/bin.c index 688622415..f2e741be5 100644 --- a/src/ld65/bin.c +++ b/src/ld65/bin.c @@ -195,7 +195,7 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M) if (DoWrite || (M->Flags & MF_FILL) != 0) { /* Seek in "overwrite" segments */ if (S->Flags & SF_OVERWRITE) { - fseek (D->F, NewAddr - M->Start, SEEK_SET); + fseek (D->F, NewAddr - M->Start + M->FileOffs, SEEK_SET); } else { WriteMult (D->F, M->FillVal, NewAddr-Addr); PrintNumVal ("SF_OFFSET", NewAddr - Addr); @@ -226,6 +226,12 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M) unsigned long P = ftell (D->F); SegWrite (D->Filename, D->F, S->Seg, BinWriteExpr, D); PrintNumVal ("Wrote", (unsigned long) (ftell (D->F) - P)); + /* If we have just written an OVERWRITE segement, move position to the + * end of file, so that subsequent segments are written in the correct + * place. */ + if (S->Flags & SF_OVERWRITE) { + fseek (D->F, 0, SEEK_END); + } } else if (M->Flags & MF_FILL) { WriteMult (D->F, S->Seg->FillVal, S->Seg->Size); PrintNumVal ("Filled", (unsigned long) S->Seg->Size); diff --git a/src/ld65/config.c b/src/ld65/config.c index 6606f6976..79c38a108 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -2107,10 +2107,12 @@ unsigned CfgProcess (void) 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. + ** in the file will be filled, then increase the file size, + ** unless it's an OVERWRITE segment. */ if (S->Load == M && - ((S->Flags & SF_BSS) == 0 || (M->Flags & MF_FILL) != 0)) { + ((S->Flags & SF_BSS) == 0 || (M->Flags & MF_FILL) != 0) + && (S->Flags & SF_OVERWRITE) == 0) { M->F->Size += Addr - StartAddr; } } From dc4142e1a935cb453aa0496bba5a9dd49e0971e4 Mon Sep 17 00:00:00 2001 From: laubzega <mileksmyk@gmail.com> Date: Fri, 29 May 2020 00:04:12 -0700 Subject: [PATCH 1304/2161] Minor formatting changes after review. --- src/ld65/bin.c | 5 +++-- src/ld65/config.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ld65/bin.c b/src/ld65/bin.c index f2e741be5..bd822cc23 100644 --- a/src/ld65/bin.c +++ b/src/ld65/bin.c @@ -227,8 +227,9 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M) SegWrite (D->Filename, D->F, S->Seg, BinWriteExpr, D); PrintNumVal ("Wrote", (unsigned long) (ftell (D->F) - P)); /* If we have just written an OVERWRITE segement, move position to the - * end of file, so that subsequent segments are written in the correct - * place. */ + ** end of file, so that subsequent segments are written in the correct + ** place. + */ if (S->Flags & SF_OVERWRITE) { fseek (D->F, 0, SEEK_END); } diff --git a/src/ld65/config.c b/src/ld65/config.c index 79c38a108..c22ced1ef 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -2111,8 +2111,8 @@ unsigned CfgProcess (void) ** unless it's an OVERWRITE segment. */ if (S->Load == M && - ((S->Flags & SF_BSS) == 0 || (M->Flags & MF_FILL) != 0) - && (S->Flags & SF_OVERWRITE) == 0) { + ((S->Flags & SF_BSS) == 0 || (M->Flags & MF_FILL) != 0) && + (S->Flags & SF_OVERWRITE) == 0) { M->F->Size += Addr - StartAddr; } } From 555282497c3ecf8b313d87d5973093af19c35bd5 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 30 May 2020 21:03:15 +0200 Subject: [PATCH 1305/2161] Removed --lib option from cl65. The general approach of cl65 when generating the command lines to be executed is to first put options and the put files. However, this doesn't work well with the --lib option which would rather need to be put when libraries in general are put. I opted to not add this special behavior to cl65 as * the use case for the --lib option is _VERY_ specific * cl65 is after all a wrapper for ordinary use cases --- doc/cl65.sgml | 1 - src/cl65/main.c | 10 ---------- 2 files changed, 11 deletions(-) diff --git a/doc/cl65.sgml b/doc/cl65.sgml index 989dce702..f00856bda 100644 --- a/doc/cl65.sgml +++ b/doc/cl65.sgml @@ -94,7 +94,6 @@ Long options: --help Help (this text) --include-dir dir Set a compiler include directory path --ld-args options Pass options to the linker - --lib file Link this library --lib-path path Specify a library search path --list-targets List all available targets --listing name Create an assembler listing file diff --git a/src/cl65/main.c b/src/cl65/main.c index 4a65e8729..9d536db82 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -807,7 +807,6 @@ static void Usage (void) " --help\t\t\tHelp (this text)\n" " --include-dir dir\t\tSet a compiler include directory path\n" " --ld-args options\t\tPass options to the linker\n" - " --lib file\t\t\tLink this library\n" " --lib-path path\t\tSpecify a library search path\n" " --list-targets\t\tList all available targets\n" " --listing name\t\tCreate an assembler listing file\n" @@ -1080,14 +1079,6 @@ static void OptLdArgs (const char* Opt attribute ((unused)), const char* Arg) -static void OptLib (const char* Opt attribute ((unused)), const char* Arg) -/* Library file follows (linker) */ -{ - CmdAddArg2 (&LD65, "--lib", Arg); -} - - - static void OptLibPath (const char* Opt attribute ((unused)), const char* Arg) /* Library search path (linker) */ { @@ -1374,7 +1365,6 @@ int main (int argc, char* argv []) { "--help", 0, OptHelp }, { "--include-dir", 1, OptIncludeDir }, { "--ld-args", 1, OptLdArgs }, - { "--lib", 1, OptLib }, { "--lib-path", 1, OptLibPath }, { "--list-targets", 0, OptListTargets }, { "--listing", 1, OptListing }, From 33e103fdc68e116fcf0dc6f64da7c4b52789d2ca Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 1 Jun 2020 01:28:48 +0800 Subject: [PATCH 1306/2161] Fixed Issue #1040: non-byte pointer +=/-= byte codegen bug. --- src/cc65/expr.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index e59f9b4d3..afc3523ae 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3456,28 +3456,32 @@ static void addsubeq (const GenDesc* Gen, ExprDesc *Expr, const char* Op) ** break, so this is the best error recovery. */ } - if (ED_IsConstAbs (&Expr2)) { - /* The resulting value is a constant. Scale it. */ - if (MustScale) { - Expr2.IVal *= CheckedSizeOf (Indirect (Expr->Type)); - } - rflags |= CF_CONST; - lflags |= CF_CONST; - } else { - /* Not constant, load into the primary */ - LoadExpr (CF_NONE, &Expr2); - if (MustScale) { - /* lhs is a pointer, scale rhs */ - g_scale (TypeOf (Expr2.Type), CheckedSizeOf (Indirect (Expr->Type))); - } - } /* Setup the code generator flags */ lflags |= TypeOf (Expr->Type) | GlobalModeFlags (Expr) | CF_FORCECHAR; rflags |= TypeOf (Expr2.Type) | CF_FORCECHAR; - /* Convert the type of the lhs to that of the rhs */ - g_typecast (lflags, rflags); + if (ED_IsConstAbs (&Expr2)) { + /* The resulting value is a constant */ + rflags |= CF_CONST; + lflags |= CF_CONST; + + /* Scale it */ + if (MustScale) { + Expr2.IVal *= CheckedSizeOf (Indirect (Expr->Type)); + } + } else { + /* Not constant, load into the primary */ + LoadExpr (CF_NONE, &Expr2); + + /* Convert the type of the rhs to that of the lhs */ + g_typecast (lflags, rflags & ~CF_FORCECHAR); + + if (MustScale) { + /* lhs is a pointer, scale rhs */ + g_scale (TypeOf (Expr2.Type), CheckedSizeOf (Indirect (Expr->Type))); + } + } /* Output apropriate code depending on the location */ switch (ED_GetLoc (Expr)) { From 68f53e69f1e72b9c70fae4e0612d894b03640247 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 1 Jun 2020 01:28:59 +0800 Subject: [PATCH 1307/2161] Fixed Issues #420 and #919 by always outputing the code segment before the three data segments for functions. --- src/cc65/codeseg.c | 5 ++++- src/cc65/segments.c | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index e2fd84a7c..58586affd 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -1353,7 +1353,7 @@ void CS_OutputEpilogue (const CodeSeg* S) */ { if (S->Func) { - WriteOutput ("\n.endproc\n\n"); + WriteOutput (".endproc\n\n"); } } @@ -1423,6 +1423,9 @@ void CS_Output (CodeSeg* S) CE_Output (E); } + /* Prettyier formatting */ + WriteOutput ("\n"); + /* If debug info is enabled, terminate the last line number information */ if (DebugInfo) { WriteOutput ("\t.dbg\tline\n"); diff --git a/src/cc65/segments.c b/src/cc65/segments.c index 5e493e8f5..6efbf68b7 100644 --- a/src/cc65/segments.c +++ b/src/cc65/segments.c @@ -289,14 +289,14 @@ void OutputSegments (const Segments* S) /* Output the text segment */ TS_Output (S->Text); + /* Output the code segment */ + CS_Output (S->Code); + /* Output the three data segments */ DS_Output (S->Data); DS_Output (S->ROData); DS_Output (S->BSS); - /* Output the code segment */ - CS_Output (S->Code); - /* Output the code segment epiloque */ CS_OutputEpilogue (S->Code); } From 07a5324a81a201fc089e076031f06a221d103f4c Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 1 Jun 2020 01:28:59 +0800 Subject: [PATCH 1308/2161] Fixed Issue #1028 by outputing local literals when exiting the function scope. --- src/cc65/compile.c | 2 +- src/cc65/function.c | 5 +++++ src/cc65/litpool.c | 28 ++++++++++++---------------- src/cc65/litpool.h | 7 +++++-- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d914afb97..ef66d38d2 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -453,7 +453,7 @@ void FinishCompile (void) } /* Output the literal pool */ - OutputLiteralPool (); + OutputGlobalLiteralPool (); /* Emit debug infos if enabled */ EmitDebugInfo (); diff --git a/src/cc65/function.c b/src/cc65/function.c index 3256d7541..8da084ac1 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -582,6 +582,11 @@ void NewFunc (SymEntry* Func) /* Restore the old literal pool, remembering the one for the function */ Func->V.F.LitPool = PopLiteralPool (); + /* If --local-strings was given, output the literals now */ + if (IS_Get (&LocalStrings)) { + OutputLocalLiteralPool (Func->V.F.LitPool); + } + /* Switch back to the old segments */ PopSegments (); diff --git a/src/cc65/litpool.c b/src/cc65/litpool.c index c427310d9..eb31c7ecc 100644 --- a/src/cc65/litpool.c +++ b/src/cc65/litpool.c @@ -147,18 +147,6 @@ Literal* UseLiteral (Literal* L) /* Increase the reference count */ ++L->RefCount; - /* If --local-strings was given, immediately output the literal */ - if (IS_Get (&LocalStrings)) { - /* Switch to the proper data segment */ - if (IS_Get (&WritableStrings)) { - g_usedata (); - } else { - g_userodata (); - } - /* Output the literal */ - OutputLiteral (L); - } - /* Return the literal */ return L; } @@ -454,12 +442,20 @@ static void OutputReadOnlyLiterals (Collection* Literals) -void OutputLiteralPool (void) -/* Output the global literal pool */ +void OutputLocalLiteralPool (LiteralPool* Pool) +/* Output the local literal pool */ { /* Output both sorts of literals */ - OutputWritableLiterals (&GlobalPool->WritableLiterals); - OutputReadOnlyLiterals (&GlobalPool->ReadOnlyLiterals); + OutputWritableLiterals (&Pool->WritableLiterals); + OutputReadOnlyLiterals (&Pool->ReadOnlyLiterals); +} + + + +void OutputGlobalLiteralPool (void) +/* Output the global literal pool */ +{ + OutputLocalLiteralPool (GlobalPool); } diff --git a/src/cc65/litpool.h b/src/cc65/litpool.h index 6efdfb089..78f432138 100644 --- a/src/cc65/litpool.h +++ b/src/cc65/litpool.h @@ -113,8 +113,11 @@ void MoveLiteralPool (LiteralPool* LocalPool); ** function will free LocalPool after moving the used string literals. */ -void OutputLiteralPool (void); -/* Output the literal pool */ +void OutputLocalLiteralPool (LiteralPool* Pool); +/* Output the local literal pool */ + +void OutputGlobalLiteralPool (void); +/* Output the global literal pool */ Literal* AddLiteral (const char* S); /* Add a literal string to the literal pool. Return the literal. */ From 8066cd9ace435932950770ff5bd74aa3b73dcba2 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 16 Apr 2020 17:17:52 +0800 Subject: [PATCH 1309/2161] Fixed wrong case in PreDec codegen, which never seems to be in use though. --- 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 afc3523ae..84f11189e 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1569,7 +1569,7 @@ static void PreDec (ExprDesc* Expr) case E_LOC_PRIMARY: /* The primary register */ - g_inc (Flags, Val); + g_dec (Flags, Val); break; case E_LOC_EXPR: From f9204e5b6fae8843a45013e63fa91c0a72b8d4d2 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 16 Apr 2020 18:38:49 +0800 Subject: [PATCH 1310/2161] Fixed g_addlocal codegen with long types. --- src/cc65/codegen.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index a611f4f6a..35af5281e 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -1541,16 +1541,17 @@ void g_addlocal (unsigned flags, int offs) /* Add a local variable to ax */ { unsigned L; + int NewOff; /* Correct the offset and check it */ - offs -= StackPtr; - CheckLocalOffs (offs); + NewOff = offs - StackPtr; + CheckLocalOffs (NewOff); switch (flags & CF_TYPEMASK) { case CF_CHAR: L = GetLocalLabel(); - AddCodeLine ("ldy #$%02X", offs & 0xFF); + AddCodeLine ("ldy #$%02X", NewOff & 0xFF); AddCodeLine ("clc"); AddCodeLine ("adc (sp),y"); AddCodeLine ("bcc %s", LocalLabelName (L)); @@ -1559,7 +1560,7 @@ void g_addlocal (unsigned flags, int offs) break; case CF_INT: - AddCodeLine ("ldy #$%02X", offs & 0xFF); + AddCodeLine ("ldy #$%02X", NewOff & 0xFF); AddCodeLine ("clc"); AddCodeLine ("adc (sp),y"); AddCodeLine ("pha"); From 14c62f136814009953c3a65abaeb1f06e5d1b406 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 4 Jun 2020 12:58:05 -0400 Subject: [PATCH 1311/2161] Allowed the TGI API to support 256 colors. --- include/tgi.h | 2 +- libsrc/tgi/tgi_setcolor.s | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/include/tgi.h b/include/tgi.h index f458180c5..15a6437cc 100644 --- a/include/tgi.h +++ b/include/tgi.h @@ -134,7 +134,7 @@ void __fastcall__ tgi_setdrawpage (unsigned char page); /* Set the drawable page. Will set an error if the page is not available. */ unsigned char tgi_getcolorcount (void); -/* Get the number of available colors. */ +/* Get the number of available colors. Zero means 256 colors. */ unsigned char tgi_getmaxcolor (void); /* Return the maximum supported color number (the number of colors would diff --git a/libsrc/tgi/tgi_setcolor.s b/libsrc/tgi/tgi_setcolor.s index 8e6fdc555..16f075767 100644 --- a/libsrc/tgi/tgi_setcolor.s +++ b/libsrc/tgi/tgi_setcolor.s @@ -1,5 +1,6 @@ ; -; Ullrich von Bassewitz, 21.06.2002 +; 2002-06-21, Ullrich von Bassewitz +; 2020-06-04, Greg King ; ; void __fastcall__ tgi_setcolor (unsigned char color); ; /* Set the current drawing color */ @@ -11,9 +12,11 @@ cmp _tgi_colorcount ; Compare to available colors bcs @L1 - sta _tgi_color ; Remember the drawing color +@L0: sta _tgi_color ; Remember the drawing color jmp tgi_setcolor ; Call the driver -@L1: jmp tgi_inv_arg ; Invalid argument + +@L1: ldx _tgi_colorcount + beq @L0 ; Zero means 256 colors + jmp tgi_inv_arg ; Invalid argument .endproc - From 15e2afcdf3109dadd8a2802af12cc3ee841ad9dc Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 4 Jun 2020 21:40:40 +0200 Subject: [PATCH 1312/2161] Split libref.s into multiple files to prevent inclusion of unnecessary code. --- libsrc/atari/libref.s | 8 +------- libsrc/atari/tgiref.s | 13 +++++++++++++ 2 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 libsrc/atari/tgiref.s diff --git a/libsrc/atari/libref.s b/libsrc/atari/libref.s index 171bd6de6..933eb5911 100644 --- a/libsrc/atari/libref.s +++ b/libsrc/atari/libref.s @@ -2,14 +2,8 @@ ; Oliver Schmidt, 2013-05-31 ; - .export em_libref, joy_libref, tgi_libref + .export em_libref, joy_libref .import _exit em_libref := _exit joy_libref := _exit -.ifdef __ATARIXL__ - .import CIO_handler -tgi_libref := CIO_handler -.else -tgi_libref := _exit -.endif diff --git a/libsrc/atari/tgiref.s b/libsrc/atari/tgiref.s new file mode 100644 index 000000000..5ac42fb46 --- /dev/null +++ b/libsrc/atari/tgiref.s @@ -0,0 +1,13 @@ +; +; Oliver Schmidt, 2013-05-31 +; + + .export tgi_libref + +.ifdef __ATARIXL__ + .import CIO_handler +tgi_libref := CIO_handler +.else + .import _exit +tgi_libref := _exit +.endif From 7b2e4d0c7f606ce8f5d65eef430c26e6dc95b1e0 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 4 Jun 2020 23:22:47 +0200 Subject: [PATCH 1313/2161] Reflect that the Apple //c supports only one joystick. --- libsrc/apple2/joy/a2.stdjoy.s | 32 +++++++++++++++++++++++++------- libsrc/apple2/joyref.s | 8 ++++++++ libsrc/apple2/libref.s | 3 +-- 3 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 libsrc/apple2/joyref.s diff --git a/libsrc/apple2/joy/a2.stdjoy.s b/libsrc/apple2/joy/a2.stdjoy.s index 7e90f7b98..8aa82ba7d 100644 --- a/libsrc/apple2/joy/a2.stdjoy.s +++ b/libsrc/apple2/joy/a2.stdjoy.s @@ -44,25 +44,37 @@ PREAD := $FB1E ; Read paddle in X, return AD conv. value in Y ; Library reference - .addr $0000 +libref: .addr $0000 ; Jump table .addr INSTALL .addr UNINSTALL .addr COUNT - .addr READJOY + .addr READ ; ------------------------------------------------------------------------ - .code + .data + +maxnum: .byte $00 ; Maximum joystick number (0 or 1) ; 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 + lda libref + ldx libref+1 + sta ostype+1 + stx ostype+2 +ostype: jsr $0000 + and #$F0 ; Mask variants + cmp #$50 ; Any Apple //c + beq :+ ; Only one joystick + inc maxnum + +: lda #<JOY_ERR_OK ldx #>JOY_ERR_OK ; Fall through @@ -71,16 +83,22 @@ INSTALL: UNINSTALL: rts +; ------------------------------------------------------------------------ + + .code + ; COUNT: Return the total number of available joysticks in a/x. COUNT: - lda #$02 ; Number of joysticks we support + ldx maxnum + inx + txa ; Number of joysticks we support ldx #$00 rts ; READ: Read a particular joystick passed in A. -READJOY: +READ: bit $C082 ; Switch in ROM - and #$01 ; Restrict joystick number + and maxnum ; Restrict joystick number ; Read horizontal paddle asl ; Joystick number -> paddle number diff --git a/libsrc/apple2/joyref.s b/libsrc/apple2/joyref.s new file mode 100644 index 000000000..8a9609bd4 --- /dev/null +++ b/libsrc/apple2/joyref.s @@ -0,0 +1,8 @@ +; +; Oliver Schmidt, 2020-06-04 +; + + .export joy_libref + .import _get_ostype + +joy_libref := _get_ostype diff --git a/libsrc/apple2/libref.s b/libsrc/apple2/libref.s index fb22515bd..8aa54abab 100644 --- a/libsrc/apple2/libref.s +++ b/libsrc/apple2/libref.s @@ -2,11 +2,10 @@ ; Oliver Schmidt, 2013-05-31 ; - .export em_libref, joy_libref, mouse_libref, ser_libref, tgi_libref + .export em_libref, mouse_libref, ser_libref, tgi_libref .import _exit em_libref := _exit -joy_libref := _exit mouse_libref := _exit ser_libref := _exit tgi_libref := _exit From 8b5ae001e555cfa8fc9c747b96539cfaff643ae8 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 5 Jun 2020 13:37:20 -0400 Subject: [PATCH 1314/2161] Refactored the TGI demo. Cleared the screen at the beginning of each demo instead of at the end. Setting the colors before clearing makes it more reliable and consistent across platforms. --- samples/tgidemo.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/samples/tgidemo.c b/samples/tgidemo.c index de743314e..93e91899b 100644 --- a/samples/tgidemo.c +++ b/samples/tgidemo.c @@ -38,8 +38,9 @@ static unsigned AspectRatio; static void CheckError (const char* S) { unsigned char Error = tgi_geterror (); + if (Error != TGI_ERR_OK) { - printf ("%s: %d\n", S, Error); + printf ("%s: %u\n", S, Error); if (doesclrscrafterexit ()) { cgetc (); } @@ -74,19 +75,19 @@ static void DoCircles (void) unsigned Y = MaxY / 2; tgi_setpalette (Palette); + tgi_setcolor (COLOR_FORE); + tgi_clear (); + tgi_line (0, 0, MaxX, MaxY); + tgi_line (0, MaxY, MaxX, 0); while (!kbhit ()) { - tgi_setcolor (COLOR_FORE); - tgi_line (0, 0, MaxX, MaxY); - tgi_line (0, MaxY, MaxX, 0); + Color = (Color == COLOR_FORE) ? COLOR_BACK : COLOR_FORE; tgi_setcolor (Color); for (I = 10; I < 240; I += 10) { tgi_ellipse (X, Y, I, tgi_imulround (I, AspectRatio)); } - Color = Color == COLOR_FORE ? COLOR_BACK : COLOR_FORE; } cgetc (); - tgi_clear (); } @@ -95,19 +96,19 @@ static void DoCheckerboard (void) { static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_BLACK }; unsigned X, Y; - unsigned char Color; + unsigned char Color = COLOR_BACK; tgi_setpalette (Palette); - Color = COLOR_BACK; + tgi_clear (); + while (1) { for (Y = 0; Y <= MaxY; Y += 10) { for (X = 0; X <= MaxX; X += 10) { + Color = (Color == COLOR_FORE) ? COLOR_BACK : COLOR_FORE; tgi_setcolor (Color); tgi_bar (X, Y, X+9, Y+9); - Color = Color == COLOR_FORE ? COLOR_BACK : COLOR_FORE; if (kbhit ()) { cgetc (); - tgi_clear (); return; } } @@ -129,6 +130,7 @@ static void DoDiagram (void) tgi_setpalette (Palette); tgi_setcolor (COLOR_FORE); + tgi_clear (); /* Determine zero and aplitude */ YOrigin = MaxY / 2; @@ -158,7 +160,6 @@ static void DoDiagram (void) } cgetc (); - tgi_clear (); } @@ -170,6 +171,7 @@ static void DoLines (void) tgi_setpalette (Palette); tgi_setcolor (COLOR_FORE); + tgi_clear (); for (X = 0; X <= MaxY; X += 10) { tgi_line (0, 0, MaxY, X); @@ -179,7 +181,6 @@ static void DoLines (void) } cgetc (); - tgi_clear (); } @@ -203,7 +204,6 @@ int main (void) tgi_init (); CheckError ("tgi_init"); - tgi_clear (); /* Get stuff from the driver */ MaxX = tgi_getmaxx (); From 20a9c0c336387306fa3bdad9d46a79911de77f4c Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 6 Jun 2020 15:14:56 +0200 Subject: [PATCH 1315/2161] Replaced call to paddle read ROM routine with custom code. As described e.g. in the Apple IIe Technote #6: 'The Apple II Paddle Circuits' it doesn't work to call PREAD several times in immediate succession. However, so far the Apple II joystick driver did just that in order to read the two joystick axis. Therefore the driver now uses a custom routine that reads both paddles _at_the_same_time_. The code doing so requires nearly twice the cycles meaning that the overall time for a joy_read() stays roughly the same. However, twice the cycles in the read loop means half the resolution. But for the cc65 joystick driver use case that doesn't hurt at all as the driver is supposed to only detect neutral vs. left/right and up/down. CPU accelerators are supposed to detect access to $C070 and slow down for some time automatically. However, the IIgs rather comes with a modified ROM routine. Therefore it is necessary to manually slow down the IIgs when replacing the ROM routine. --- asminc/apple2.inc | 16 ++++- libsrc/apple2/joy/a2.stdjoy.s | 112 ++++++++++++++++++++++------------ 2 files changed, 87 insertions(+), 41 deletions(-) diff --git a/asminc/apple2.inc b/asminc/apple2.inc index 226a85778..19906ec2f 100644 --- a/asminc/apple2.inc +++ b/asminc/apple2.inc @@ -62,9 +62,19 @@ DHIRESON := $C05E ; Enable double-width graphics DHIRESOFF := $C05F ; Disable double-width graphics ; Game controller -BUTN0 := $C061 ; Open-Apple Key -BUTN1 := $C062 ; Closed-Apple Key +TAPEIN := $C060 ; Read casette input / Switch input 3 +BUTN0 := $C061 ; Switch input 0 / Open-Apple key +BUTN1 := $C062 ; Switch input 1 / Closed-Apple key +BUTN2 := $C063 ; Switch input 2 / Shift key +PADDL0 := $C064 ; Analog input 0 +PADDL1 := $C065 ; Analog input 1 +PADDL2 := $C066 ; Analog input 2 +PADDL3 := $C067 ; Analog input 3 +PTRIG := $C070 ; Analog input reset -; IOU +; Input/Output Unit IOUDISON := $C07E ; Disable IOU IOUDISOFF := $C07F ; Enable IOU + +; Control Your Apple +CYAREG := $C036 ; Bits 0-3=disk detect 4=shadow all banks 7=fast diff --git a/libsrc/apple2/joy/a2.stdjoy.s b/libsrc/apple2/joy/a2.stdjoy.s index 8aa82ba7d..a3a935e5b 100644 --- a/libsrc/apple2/joy/a2.stdjoy.s +++ b/libsrc/apple2/joy/a2.stdjoy.s @@ -19,13 +19,8 @@ ; Constants -THRESHOLD = 20 ; Deviation from center triggering movement - -; ------------------------------------------------------------------------ - -; ROM entry points - -PREAD := $FB1E ; Read paddle in X, return AD conv. value in Y +LOWER_THRESHOLD = 05 +UPPER_THRESHOLD = 85 ; ------------------------------------------------------------------------ @@ -55,9 +50,16 @@ libref: .addr $0000 ; ------------------------------------------------------------------------ - .data + .bss -maxnum: .byte $00 ; Maximum joystick number (0 or 1) +maxnum: .res 1 ; Maximum joystick number (0 or 1) +iigs: .res 1 +value0: .res 1 +value1: .res 1 + +; ------------------------------------------------------------------------ + + .data ; INSTALL routine. Is called after the driver is loaded into memory. If ; possible, check if the hardware is present and determine the amount of @@ -68,13 +70,19 @@ INSTALL: ldx libref+1 sta ostype+1 stx ostype+2 -ostype: jsr $0000 +ostype: jsr $0000 ; X = 0 and #$F0 ; Mask variants cmp #$50 ; Any Apple //c beq :+ ; Only one joystick - inc maxnum + inx +: stx maxnum + ldx #$00 + cmp #$80 ; Any Apple IIgs + bne :+ + inx +: stx iigs -: lda #<JOY_ERR_OK + lda #<JOY_ERR_OK ldx #>JOY_ERR_OK ; Fall through @@ -87,7 +95,7 @@ UNINSTALL: .code -; COUNT: Return the total number of available joysticks in a/x. +; COUNT routine. Return the total number of available joysticks in a/x. COUNT: ldx maxnum inx @@ -95,51 +103,79 @@ COUNT: ldx #$00 rts -; READ: Read a particular joystick passed in A. +; READ routine. Read a particular joystick passed in A. READ: - bit $C082 ; Switch in ROM - and maxnum ; Restrict joystick number - - ; Read horizontal paddle asl ; Joystick number -> paddle number - tax ; Set paddle number (0, 2) - jsr PREAD ; Read paddle value - lda #$00 ; 0 0 0 0 0 0 0 0 - cpy #127 - THRESHOLD - ror ; !LEFT 0 0 0 0 0 0 0 - cpy #127 + THRESHOLD - ror ; RIGHT !LEFT 0 0 0 0 0 0 + tax + ldy #$00 + sty value0 + sty value1 - ; Read vertical paddle + ; If IIgs -> set speed to normal + lda iigs + beq nogs1 + lda CYAREG pha - inx ; Set paddle number (1, 3) - jsr PREAD ; Read paddle value + and #%01111111 + sta CYAREG + + ; Read both paddles simultaneously +nogs1: lda PTRIG ; Trigger paddles +loop: lda PADDL0,x ; Read paddle (0 or 2) + bmi set0 ; Cycles: 2 3 + nop ; Cycles: 2 + bpl nop0 ; Cycles: 3 +set0: sty value0 ; Cycles: 4 +nop0: ; - - + ; Cycles: 7 7 + lda PADDL1,x ; Read paddle (1 or 3) + bmi set1 ; Cycles: 2 3 + nop ; Cycles: 2 + bpl nop1 ; Cycles: 3 +set1: sty value1 ; Cycles: 4 +nop1: ; - - + ; Cycles: 7 7 + iny + cpy #UPPER_THRESHOLD+1 + bne loop + + ; If IIgs -> restore speed + lda iigs + beq nogs2 pla - cpy #127 - THRESHOLD + sta CYAREG + + ; Transform paddle readings to directions +nogs2: lda #$00 ; 0 0 0 0 0 0 0 0 + ldy value0 + cpy #LOWER_THRESHOLD + ror ; !LEFT 0 0 0 0 0 0 0 + cpy #UPPER_THRESHOLD + ror ; RIGHT !LEFT 0 0 0 0 0 0 + ldy value1 + cpy #LOWER_THRESHOLD ror ; !UP RIGHT !LEFT 0 0 0 0 0 - cpy #127 + THRESHOLD + cpy #UPPER_THRESHOLD ror ; DOWN !UP RIGHT !LEFT 0 0 0 0 ; Read primary button tay - lda BUTN0-1,x ; Check button (1, 3) + lda BUTN0,x ; Check button (0 or 2) asl tya - ror ; BTN DOWN !UP RIGHT !LEFT 0 0 0 + ror ; BTN_1 DOWN !UP RIGHT !LEFT 0 0 0 ; Read secondary button tay - inx txa - and #$03 ; IIgs has fourth button at TAPEIN + eor #$02 ; IIgs has fourth button at TAPEIN tax - lda BUTN0-1,x ; Check button (2, 0) + lda TAPEIN,x ; Check button (1 or 3) asl tya - ror ; BTN2 BTN DOWN !UP RIGHT !LEFT 0 0 + ror ; BTN_2 BTN_1 DOWN !UP RIGHT !LEFT 0 0 ; Finalize - eor #%00010100 ; BTN2 BTN DOWN UP RIGHT LEFT 0 0 + eor #%00010100 ; BTN_2 BTN_1 DOWN UP RIGHT LEFT 0 0 ldx #$00 - bit $C080 ; Switch in LC bank 2 for R/O rts From bc1e884988fa1b3ee802f607511ddf16f6a7a562 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 8 Jun 2020 16:39:11 -0400 Subject: [PATCH 1316/2161] Documented how the TGI API shows when a palette has 256 colors. --- doc/tgi.sgml | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/doc/tgi.sgml b/doc/tgi.sgml index c5878622e..73a0f3bbd 100644 --- a/doc/tgi.sgml +++ b/doc/tgi.sgml @@ -241,14 +241,34 @@ color = tgi_getcolor(); <tag/Function/Get the number of available colors. <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 +<tag/Description/TGI platforms use indexed color palettes. This function returns the number of entries we can use in the palette. + +<tt/tgi_setcolor()/ can accept numbers from <tt/0/ to <tt/255/. That is 256 +possible colors, but an <tt/(unsigned char)/ cannot hold that number. +Therefore, the number zero is used to indicate when a palette has 256 entries. +A portable program should test for that number, and do appropriate actions. +A program might assign the count to an <tt/unsigned int/ (and change a zero to +a 256). Or, it might rely on the fact that <tt/(unsigned char)/ will +"wrap-around" when it is incremented beyond 255. <tag/Availability/cc65 <tag/See also/Other tgi functions -<tag/Example/<verb> +<tag/Examples/<verb> if (tgi_getcolorcount() == 2) { printf("Only monochrome graphics is supported\n"); } + +static unsigned char num_colors; +static unsigned char color; +... +num_colors = tgi_getcolorcount(); +... +++color; +if (num_colors == 0) { + tgi_setcolor(color); +} else { + tgi_setcolor(color % num_colors); +} </verb> </descrip> </quote> From 87144a15dd5b3ccdeee97b987435ef00f7637707 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 8 Jun 2020 17:22:02 -0400 Subject: [PATCH 1317/2161] Fixed the "verbatim" tags in the TGI document. --- doc/tgi.sgml | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/doc/tgi.sgml b/doc/tgi.sgml index 73a0f3bbd..9f37962c3 100644 --- a/doc/tgi.sgml +++ b/doc/tgi.sgml @@ -41,11 +41,11 @@ of range. <ref id="tgi_ellipse" name="tgi_ellipse">, <ref id="tgi_pieslice" name="tgi_pieslice">, <ref id="tgi_setcolor" name="tgi_setcolor"> -<tag/Example/<verb> +<tag/Example/<tscreen><verb> /* Draw the upper half of an ellipse */ tgi_setcolor(TGI_COLOR_BLUE); tgi_arc (50, 50, 40, 20, 0, 180); -</verb> +</verb></tscreen> </descrip> </quote> @@ -66,10 +66,10 @@ be used in presence of a prototype. </itemize> <tag/Availability/cc65 <tag/See also/Other tgi function -<tag/Example/<verb> +<tag/Example/<tscreen><verb> tgi_setcolor(TGI_COLOR_GREEN); tgi_bar(10, 10, 100, 60); -</verb> +</verb></tscreen> </descrip> </quote> @@ -93,10 +93,10 @@ be used in presence of a prototype. <ref id="tgi_ellipse" name="tgi_ellipse">, <ref id="tgi_pieslice" name="tgi_pieslice">, <ref id="tgi_setcolor" name="tgi_setcolor"> -<tag/Example/<verb> +<tag/Example/<tscreen><verb> tgi_setcolor(TGI_COLOR_BLACK); tgi_circle(50, 40, 40); -</verb> +</verb></tscreen> </descrip> </quote> @@ -153,10 +153,10 @@ be used in presence of a prototype. <ref id="tgi_circle" name="tgi_circle">, <ref id="tgi_pieslice" name="tgi_pieslice">, <ref id="tgi_setcolor" name="tgi_setcolor"> -<tag/Example/<verb> +<tag/Example/<tscreen><verb> tgi_setcolor(TGI_COLOR_RED); tgi_ellipse (50, 40, 40, 20); -</verb> +</verb></tscreen> </descrip> </quote> @@ -227,9 +227,9 @@ 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. <tag/Availability/cc65 <tag/See also/Other tgi functions -<tag/Example/<verb> +<tag/Example/<tscreen><verb> color = tgi_getcolor(); -</verb> +</verb></tscreen> </descrip> </quote> @@ -253,7 +253,7 @@ a 256). Or, it might rely on the fact that <tt/(unsigned char)/ will "wrap-around" when it is incremented beyond 255. <tag/Availability/cc65 <tag/See also/Other tgi functions -<tag/Examples/<verb> +<tag/Examples/<tscreen><verb> if (tgi_getcolorcount() == 2) { printf("Only monochrome graphics is supported\n"); } @@ -269,7 +269,7 @@ if (num_colors == 0) { } else { tgi_setcolor(color % num_colors); } -</verb> +</verb></tscreen> </descrip> </quote> @@ -531,10 +531,10 @@ name="tgi_clear">/ after <tt/tgi_init/. </itemize> <tag/Availability/cc65 <tag/See also/Other tgi functions. -<tag/Example/<verb> +<tag/Example/<tscreen><verb> tgi_install(tgi_static_stddrv); //Include the driver statically instead of loading it. tgi_init(); //Set up the default palette and clear the screen. -</verb> +</verb></tscreen> </descrip> </quote> @@ -558,10 +558,10 @@ used in presence of a prototype. <ref id="tgi_load_driver" name="tgi_load_driver">, <ref id="tgi_uninstall" name="tgi_uninstall">, <ref id="tgi_unload" name="tgi_unload"> -<tag/Example/<verb> +<tag/Example/<tscreen><verb> tgi_install(tgi_static_stddrv); //Include the driver statically instead of loading it. tgi_init(); //Set up the default palette and clear the screen. -</verb> +</verb></tscreen> </descrip> </quote> @@ -607,7 +607,7 @@ be used in presence of a prototype. </itemize> <tag/Availability/cc65 <tag/See also/Other tgi functions. -<tag/Example/<verb> +<tag/Example/<tscreen><verb> #define tgi_sprite(spr) tgi_ioctl(0, (void*)(spr)) #define tgi_flip() tgi_ioctl(1, (void*)0) #define tgi_setbgcolor(bgcol) tgi_ioctl(2, (void*)(bgcol)) @@ -620,7 +620,7 @@ if (!tgi_busy()) { tgi_outttextxy(20,40,"Hello World"); tgi_updatedisplay(); } -</verb> +</verb></tscreen> </descrip> </quote> @@ -779,11 +779,11 @@ of range. <ref id="tgi_circle" name="tgi_circle">, <ref id="tgi_ellipse" name="tgi_ellipse">, <ref id="tgi_setcolor" name="tgi_setcolor"> -<tag/Example/<verb> +<tag/Example/<tscreen><verb> /* Draw the closed upper half of an ellipse */ tgi_setcolor(TGI_COLOR_BLUE); tgi_pieslice (50, 50, 40, 20, 0, 180); -</verb> +</verb></tscreen> </descrip> </quote> @@ -834,12 +834,12 @@ be used in presence of a prototype. </itemize> <tag/Availability/cc65 <tag/See also/Other tgi functions. -<tag/Example/<verb> +<tag/Example/<tscreen><verb> tgi_setcolor(TGI_COLOR_BLACK); tgi_bar(0,0,30,30); tgi_setcolor(TGI_COLOR_WHITE); tgi_bar(10,10,20,20); -</verb> +</verb></tscreen> </descrip> </quote> @@ -861,7 +861,7 @@ be used in presence of a prototype. </itemize> <tag/Availability/cc65 <tag/See also/Other tgi functions. -<tag/Example/<verb> +<tag/Example/<tscreen><verb> tgi_setdrawpage(1); tgi_outtextxy(10, 10, "Hello World"); tgi_setviewpage(1); // Show page 1 @@ -869,7 +869,7 @@ tgi_setdrawpage(0); tgi_outtextxy(10, 10, "Creating next frame"); ... tgi_setviewpage(0); // Show page 0 -</verb> +</verb></tscreen> </descrip> </quote> @@ -973,7 +973,7 @@ be used in presence of a prototype. </itemize> <tag/Availability/cc65 <tag/See also/Other tgi functions. -<tag/Example/<verb> +<tag/Example/<tscreen><verb> tgi_setdrawpage(1); tgi_outtextxy(10, 10, "Hello World"); tgi_setviewpage(1); // Show page 1 @@ -981,7 +981,7 @@ tgi_setdrawpage(0); tgi_outtextxy(10, 10, "Creating next frame"); ... tgi_setviewpage(0); // Show page 0 -</verb> +</verb></tscreen> </descrip> </quote> From 2acb3b153bb3a5c29a8abe2c417a68b39a689d1b Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 8 Jun 2020 20:09:45 -0400 Subject: [PATCH 1318/2161] Added some "See also" links to the TGI color-count descriptions. --- doc/tgi.sgml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/doc/tgi.sgml b/doc/tgi.sgml index 9f37962c3..b1497ca70 100644 --- a/doc/tgi.sgml +++ b/doc/tgi.sgml @@ -252,7 +252,12 @@ A program might assign the count to an <tt/unsigned int/ (and change a zero to a 256). Or, it might rely on the fact that <tt/(unsigned char)/ will "wrap-around" when it is incremented beyond 255. <tag/Availability/cc65 -<tag/See also/Other tgi functions +<tag/See also/<ref id="tgi_getcolor" name="tgi_getcolor()">, +<ref id="tgi_getdefpalette" name="tgi_getdefpalette()">, +<ref id="tgi_getmaxcolor" name="tgi_getmaxcolor()">, +<ref id="tgi_getpalette" name="tgi_getpalette()">, +<ref id="tgi_setcolor" name="tgi_setcolor()">, +<ref id="tgi_setpalette" name="tgi_setpalette()"> <tag/Examples/<tscreen><verb> if (tgi_getcolorcount() == 2) { printf("Only monochrome graphics is supported\n"); @@ -336,7 +341,12 @@ be used in presence of a prototype. <tag/Declaration/<tt/unsigned char tgi_getmaxcolor (void);/ <tag/Description/Get the highest index of the palette. <tag/Availability/cc65 -<tag/See also/Other tgi functions +<tag/See also/<ref id="tgi_getcolor" name="tgi_getcolor()">, +<ref id="tgi_getcolorcount" name="tgi_getcolorcount()">, +<ref id="tgi_getdefpalette" name="tgi_getdefpalette()">, +<ref id="tgi_getpalette" name="tgi_getpalette()">, +<ref id="tgi_setcolor" name="tgi_setcolor()">, +<ref id="tgi_setpalette" name="tgi_setpalette()"> <tag/Example/None. </descrip> </quote> From 6adf175691f30cedd6b143dd5b6304206871eb4b Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 14 Jun 2020 21:54:33 +0200 Subject: [PATCH 1319/2161] Optimized get_ostype() return values for asm usage. Making sure that all but //c machines have bit 6 clear allows to use BIT/BVS to detect the //c machines. --- include/apple2.h | 12 ++++++------ libsrc/apple2/get_ostype.s | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/apple2.h b/include/apple2.h index f205fdcb9..dbed3364d 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -111,12 +111,12 @@ #define APPLE_IIIEM 0x20 /* Apple /// (emulation) */ #define APPLE_IIE 0x30 /* Apple //e */ #define APPLE_IIEENH 0x31 /* Apple //e (enhanced) */ -#define APPLE_IIECARD 0x40 /* Apple //e Option Card */ -#define APPLE_IIC 0x50 /* Apple //c */ -#define APPLE_IIC35 0x51 /* Apple //c (3.5 ROM) */ -#define APPLE_IICEXP 0x53 /* Apple //c (Mem. Exp.) */ -#define APPLE_IICREV 0x54 /* Apple //c (Rev. Mem. Exp.) */ -#define APPLE_IICPLUS 0x55 /* Apple //c Plus */ +#define APPLE_IIECARD 0x32 /* Apple //e Option Card */ +#define APPLE_IIC 0x40 /* Apple //c */ +#define APPLE_IIC35 0x41 /* Apple //c (3.5 ROM) */ +#define APPLE_IICEXP 0x43 /* Apple //c (Mem. Exp.) */ +#define APPLE_IICREV 0x44 /* Apple //c (Rev. Mem. Exp.) */ +#define APPLE_IICPLUS 0x45 /* Apple //c Plus */ #define APPLE_IIGS 0x80 /* Apple IIgs */ #define APPLE_IIGS1 0x81 /* Apple IIgs (ROM 1) */ #define APPLE_IIGS3 0x83 /* Apple IIgs (ROM 3) */ diff --git a/libsrc/apple2/get_ostype.s b/libsrc/apple2/get_ostype.s index dd44aa831..71b43d174 100644 --- a/libsrc/apple2/get_ostype.s +++ b/libsrc/apple2/get_ostype.s @@ -49,13 +49,13 @@ value: .byte $38, $10 ; Apple ][ .byte $EA, $AD, $11 ; Apple ][+ .byte $EA, $8A, $20 ; Apple /// (emulation) .byte $06, $EA, $30 ; Apple //e - .byte $06, $E0, $02, $40 ; Apple //e Option Card + .byte $06, $E0, $02, $32 ; Apple //e Option Card .byte $06, $E0, $31 ; Apple //e (enhanced) - .byte $06, $00, $FF, $50 ; Apple //c - .byte $06, $00, $00, $51 ; Apple //c (3.5 ROM) - .byte $06, $00, $03, $53 ; Apple //c (Mem. Exp.) - .byte $06, $00, $04, $54 ; Apple //c (Rev. Mem. Exp.) - .byte $06, $00, $05, $55 ; Apple //c Plus + .byte $06, $00, $FF, $40 ; Apple //c + .byte $06, $00, $00, $41 ; Apple //c (3.5 ROM) + .byte $06, $00, $03, $43 ; Apple //c (Mem. Exp.) + .byte $06, $00, $04, $44 ; Apple //c (Rev. Mem. Exp.) + .byte $06, $00, $05, $45 ; Apple //c Plus .byte $00 .code From e0a0b2dc25bfc55e9f9517f82d7bb4b158c065f3 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 15 Jun 2020 19:07:59 +0200 Subject: [PATCH 1320/2161] Streamlined machine detection. --- libsrc/apple2/joy/a2.stdjoy.s | 40 ++++++++++++++--------------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/libsrc/apple2/joy/a2.stdjoy.s b/libsrc/apple2/joy/a2.stdjoy.s index a3a935e5b..558013910 100644 --- a/libsrc/apple2/joy/a2.stdjoy.s +++ b/libsrc/apple2/joy/a2.stdjoy.s @@ -52,8 +52,7 @@ libref: .addr $0000 .bss -maxnum: .res 1 ; Maximum joystick number (0 or 1) -iigs: .res 1 +ostype: .res 1 value0: .res 1 value1: .res 1 @@ -68,20 +67,10 @@ value1: .res 1 INSTALL: lda libref ldx libref+1 - sta ostype+1 - stx ostype+2 -ostype: jsr $0000 ; X = 0 - and #$F0 ; Mask variants - cmp #$50 ; Any Apple //c - beq :+ ; Only one joystick - inx -: stx maxnum - ldx #$00 - cmp #$80 ; Any Apple IIgs - bne :+ - inx -: stx iigs - + sta gettype+1 + stx gettype+2 +gettype:jsr $0000 + sta ostype lda #<JOY_ERR_OK ldx #>JOY_ERR_OK ; Fall through @@ -97,9 +86,11 @@ UNINSTALL: ; COUNT routine. Return the total number of available joysticks in a/x. COUNT: - ldx maxnum - inx - txa ; Number of joysticks we support + ldx #$02 + bit ostype + bvc noiic ; Not $4x + dex ; Only one joystick for the //c +noiic: txa ; Number of joysticks we support ldx #$00 rts @@ -112,14 +103,15 @@ READ: sty value1 ; If IIgs -> set speed to normal - lda iigs - beq nogs1 + bit ostype + bpl nogs1 ; Not $8x lda CYAREG pha and #%01111111 sta CYAREG - ; Read both paddles simultaneously + ; Read both paddles simultaneously according to: + ; Apple IIe Technote #6, The Apple II Paddle Circuits nogs1: lda PTRIG ; Trigger paddles loop: lda PADDL0,x ; Read paddle (0 or 2) bmi set0 ; Cycles: 2 3 @@ -140,8 +132,8 @@ nop1: ; - - bne loop ; If IIgs -> restore speed - lda iigs - beq nogs2 + bit ostype + bpl nogs2 ; Not $8x pla sta CYAREG From 98c7186221428f5943ad177581cd38200a29a865 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 15 Jun 2020 23:39:50 +0200 Subject: [PATCH 1321/2161] Add description for --debug-opt-output to the --help output --- src/cc65/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc65/main.c b/src/cc65/main.c index a4f794fb5..756c3101f 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -116,6 +116,7 @@ static void Usage (void) " --debug\t\t\tDebug mode\n" " --debug-info\t\t\tAdd debug info to object file\n" " --debug-opt name\t\tDebug optimization steps\n" + " --debug-opt-output\t\t\tOutput extra files containing optimization steps\n" " --dep-target target\t\tUse this dependency target\n" " --disable-opt name\t\tDisable an optimization step\n" " --eagerly-inline-funcs\tEagerly inline some known functions\n" From 349a84d9728512da756aff7982f0a0d6d0492405 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 16 Jun 2020 00:08:55 +0200 Subject: [PATCH 1322/2161] remove superfluous TAB --- src/cc65/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/main.c b/src/cc65/main.c index 756c3101f..dd02eeecf 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -116,7 +116,7 @@ static void Usage (void) " --debug\t\t\tDebug mode\n" " --debug-info\t\t\tAdd debug info to object file\n" " --debug-opt name\t\tDebug optimization steps\n" - " --debug-opt-output\t\t\tOutput extra files containing optimization steps\n" + " --debug-opt-output\t\tOutput extra files containing optimization steps\n" " --dep-target target\t\tUse this dependency target\n" " --disable-opt name\t\tDisable an optimization step\n" " --eagerly-inline-funcs\tEagerly inline some known functions\n" From baa5d051e45260d8a44e6fef66af0ab55f6b305f Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 16 Jun 2020 00:11:07 +0200 Subject: [PATCH 1323/2161] use same description as in the docs --- src/cc65/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/main.c b/src/cc65/main.c index dd02eeecf..e86ae13ba 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -116,7 +116,7 @@ static void Usage (void) " --debug\t\t\tDebug mode\n" " --debug-info\t\t\tAdd debug info to object file\n" " --debug-opt name\t\tDebug optimization steps\n" - " --debug-opt-output\t\tOutput extra files containing optimization steps\n" + " --debug-opt-output\t\tDebug output of each optimization step\n" " --dep-target target\t\tUse this dependency target\n" " --disable-opt name\t\tDisable an optimization step\n" " --eagerly-inline-funcs\tEagerly inline some known functions\n" From 37107174c61425915b02c5f327cdfe9335da2cae Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 18 Jun 2020 21:44:42 +0200 Subject: [PATCH 1324/2161] Added waitvsync() for the Enhanced Apple //e. The implementation is a bit tricky as it requires to take different code paths for the //e, the //c and the IIgs. Additionally the //c only provides a VBL IRQ flag supposed to be used by an IRQ handler to determine what triggered the IRQ. However, masking IRQs on the CPU, activating the VBL IRQ, clearing any pending VBL IRQs and then polling for the IRQ flag does the trick. --- asminc/apple2.inc | 40 ++++++++++++++----------- doc/apple2enh.sgml | 3 +- include/apple2enh.h | 3 ++ libsrc/apple2/get_ostype.s | 2 +- libsrc/apple2/waitvsync.s | 60 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 88 insertions(+), 20 deletions(-) create mode 100644 libsrc/apple2/waitvsync.s diff --git a/asminc/apple2.inc b/asminc/apple2.inc index 19906ec2f..5ebf73164 100644 --- a/asminc/apple2.inc +++ b/asminc/apple2.inc @@ -1,6 +1,6 @@ ;----------------------------------------------------------------------------- -; Zero page stuff +; Zero page WNDLFT := $20 ; Text window left WNDWDTH := $21 ; Text window width @@ -31,35 +31,41 @@ PWREDUP := $03F4 ; This must be = EOR #$A5 of SOFTEV+1 KBD := $C000 ; Read keyboard KBDSTRB := $C010 ; Clear keyboard strobe -; 80 column video switches +; 80 column video CLR80COL:= $C000 ; Disable 80 column store SET80COL:= $C001 ; Enable 80 column store RD80COL := $C018 ; >127 if 80 column store enabled RD80VID := $C01F ; >127 if 80 column video enabled -; Character set switches +; Character set CLRALTCHAR := $C00E ; Normal Apple II char set SETALTCHAR := $C00F ; Norm/inv LC, no flash ALTCHARSET := $C01E ; >127 if alt charset switched in -; Language card switches +; Language card RDLCBNK2:= $C011 ; >127 if LC bank 2 in use RDLCRAM := $C012 ; >127 if LC is read enabled ROMIN := $C081 ; Swap in D000-FFFF ROM LCBANK2 := $C083 ; Swap in LC bank 2 LCBANK1 := $C08B ; Swap in LC bank 1 -; Video mode switches -TXTCLR := $C050 ; Display graphics -TXTSET := $C051 ; Display text -MIXCLR := $C052 ; Disable 4 lines of text -MIXSET := $C053 ; Enable 4 lines of text -LOWSCR := $C054 ; Page 1 -HISCR := $C055 ; Page 2 -LORES := $C056 ; Lores graphics -HIRES := $C057 ; Hires graphics -DHIRESON := $C05E ; Enable double-width graphics -DHIRESOFF := $C05F ; Disable double-width graphics +; Vertical blanking +RDVBLBAR := $C019 ; >127 if not vertical blanking +RDVBLMSK := $C041 ; >127 if VBL interrupts enabled +DISVBL := $C05A ; Disable VBL interrupts +ENVBL := $C05B ; Enable VBL interrupts + +; Video mode +TXTCLR := $C050 ; Display graphics +TXTSET := $C051 ; Display text +MIXCLR := $C052 ; Disable 4 lines of text +MIXSET := $C053 ; Enable 4 lines of text +LOWSCR := $C054 ; Page 1 +HISCR := $C055 ; Page 2 +LORES := $C056 ; Lores graphics +HIRES := $C057 ; Hires graphics +DHIRESON := $C05E ; Enable double-width graphics +DHIRESOFF := $C05F ; Disable double-width graphics ; Game controller TAPEIN := $C060 ; Read casette input / Switch input 3 @@ -73,8 +79,8 @@ PADDL3 := $C067 ; Analog input 3 PTRIG := $C070 ; Analog input reset ; Input/Output Unit -IOUDISON := $C07E ; Disable IOU -IOUDISOFF := $C07F ; Enable IOU +IOUDISON := $C07E ; Disable IOU +IOUDISOFF := $C07F ; Enable IOU ; Control Your Apple CYAREG := $C036 ; Bits 0-3=disk detect 4=shadow all banks 7=fast diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index fa70da4ee..2d4381353 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -332,10 +332,9 @@ usage. <item>get_ostype <item>rebootafterexit <item>ser_apple2_slot -<item>textframe -<item>textframexy <item>tgi_apple2_mix <item>videomode +<item>waitvsync </itemize> diff --git a/include/apple2enh.h b/include/apple2enh.h index 3dd8cffc0..58e0b397f 100644 --- a/include/apple2enh.h +++ b/include/apple2enh.h @@ -116,6 +116,9 @@ unsigned __fastcall__ videomode (unsigned mode); ** constants. */ +void waitvsync (void); +/* Wait for start of next frame */ + /* End of apple2enh.h */ diff --git a/libsrc/apple2/get_ostype.s b/libsrc/apple2/get_ostype.s index 71b43d174..a1b1eb5be 100644 --- a/libsrc/apple2/get_ostype.s +++ b/libsrc/apple2/get_ostype.s @@ -4,7 +4,7 @@ ; unsigned char get_ostype (void) ; - .constructor initostype + .constructor initostype, 9 .export _get_ostype ; Identify machine according to: diff --git a/libsrc/apple2/waitvsync.s b/libsrc/apple2/waitvsync.s new file mode 100644 index 000000000..a4ab5ebb3 --- /dev/null +++ b/libsrc/apple2/waitvsync.s @@ -0,0 +1,60 @@ +; +; Oliver Schmidt, 2020-06-14 +; +; void waitvsync (void); +; + .ifdef __APPLE2ENH__ + + .constructor initvsync + .export _waitvsync + .import _get_ostype + + .include "apple2.inc" + + .segment "ONCE" + +initvsync: + jsr _get_ostype + sta ostype + rts + + .code + +_waitvsync: + bit ostype + bmi iigs ; $8x + bvs iic ; $4x + +: bit RDVBLBAR + bpl :- ; Blanking +: bit RDVBLBAR + bmi :- ; Drawing + rts + + ; Apple IIgs TechNote #40, VBL Signal +iigs: bit RDVBLBAR + bmi iigs ; Blanking +: bit RDVBLBAR + bpl :- ; Drawing + rts + + ; Apple IIc TechNote #9, Detecting VBL +iic: sei + sta IOUDISOFF + lda RDVBLMSK + bit ENVBL + bit PTRIG ; Reset VBL interrupt flag +: bit RDVBLBAR + bpl :- + asl + bcs :+ ; VBL interrupts were already enabled + bit DISVBL +: sta IOUDISON ; IIc Tech Ref Man: The firmware normally leaves IOUDIS on. + cli + rts + + .segment "INIT" + +ostype: .res 1 + + .endif ; __APPLE2ENH__ From 4afc552e1747102f7c5e40755170002edea54eec Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Fri, 19 Jun 2020 09:06:52 +0200 Subject: [PATCH 1325/2161] ParseStructDecl: Make BitOffs unsigned This makes it consistent with SymEntry and removes the need for some casts that were added to avoid warnings about signed vs unsigned comparison. --- src/cc65/declare.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 35ce5d0b2..523aac48a 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -714,7 +714,7 @@ static SymEntry* ParseStructDecl (const char* Name) unsigned StructSize; int FlexibleMember; - int BitOffs; /* Bit offset for bit-fields */ + unsigned BitOffs; /* Bit offset for bit-fields */ int FieldWidth; /* Width in bits, -1 if not a bit-field */ SymTable* FieldTab; @@ -770,7 +770,7 @@ static SymEntry* ParseStructDecl (const char* Name) ** a member with an anonymous name. */ if (BitOffs > 0) { - if (FieldWidth <= 0 || (BitOffs + FieldWidth) > (int) INT_BITS) { + if (FieldWidth <= 0 || (BitOffs + FieldWidth) > INT_BITS) { /* We need an anonymous name */ AnonName (Ident, "bit-field"); @@ -839,7 +839,7 @@ static SymEntry* ParseStructDecl (const char* Name) unsigned Offs = StructSize + (BitOffs / CHAR_BITS); AddBitField (Decl.Ident, Offs, BitOffs % CHAR_BITS, FieldWidth); BitOffs += FieldWidth; - CHECK (BitOffs <= (int) INT_BITS); + CHECK (BitOffs <= INT_BITS); if (BitOffs == INT_BITS) { StructSize += SIZEOF_INT; BitOffs = 0; From 1c2edc543478633fb8a68e224d1f56a76d562487 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Fri, 19 Jun 2020 09:01:24 +0200 Subject: [PATCH 1326/2161] AddBitField: Rename Width arg to BitWidth This makes the arg consistent with the SymEntry field name. --- src/cc65/symtab.c | 4 ++-- src/cc65/symtab.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index a31c11bfc..f19a251bd 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -597,7 +597,7 @@ SymEntry* AddStructSym (const char* Name, unsigned Type, unsigned Size, SymTable -SymEntry* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsigned Width) +SymEntry* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsigned BitWidth) /* Add a bit field to the local symbol table and return the symbol entry */ { /* Do we have an entry with this name already? */ @@ -616,7 +616,7 @@ SymEntry* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsign Entry->Type = type_uint; Entry->V.B.Offs = Offs; Entry->V.B.BitOffs = BitOffs; - Entry->V.B.BitWidth = Width; + Entry->V.B.BitWidth = BitWidth; /* Add the entry to the symbol table */ AddSymEntry (SymTab, Entry); diff --git a/src/cc65/symtab.h b/src/cc65/symtab.h index cd736ec1e..62e731042 100644 --- a/src/cc65/symtab.h +++ b/src/cc65/symtab.h @@ -149,7 +149,7 @@ unsigned short FindSPAdjustment (const char* Name); SymEntry* AddStructSym (const char* Name, unsigned Type, unsigned Size, SymTable* Tab); /* Add a struct/union entry and return it */ -SymEntry* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsigned Width); +SymEntry* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsigned BitWidth); /* Add a bit field to the local symbol table and return the symbol entry */ SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val); From a7a8426a90388f74f89661140d2d464f7e2a472a Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 31 Dec 2019 16:06:52 +0800 Subject: [PATCH 1327/2161] Just keep Lhs loads in OptStackOps and leave them to OptUnusedLoads, whilst Rhs loads must be removed for OptStackOps to work right. Fixed Issue #167 as well as similar issues with tosshift. --- src/cc65/coptstop.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 87514cfdd..28eaafd7b 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -792,10 +792,6 @@ static unsigned Opt_toseqax_tosneax (StackOpData* D, const char* BoolTransformer X = NewCodeEntry (OP65_CMP, LoadA->AM, LoadA->Arg, 0, D->OpEntry->LI); InsertEntry (D, X, D->IP++); - /* Lhs load entries can be removed */ - D->Lhs.X.Flags |= LI_REMOVE; - D->Lhs.A.Flags |= LI_REMOVE; - } else if ((D->Rhs.A.Flags & (LI_DIRECT | LI_RELOAD_Y)) == LI_DIRECT && (D->Rhs.X.Flags & (LI_DIRECT | LI_RELOAD_Y)) == LI_DIRECT) { @@ -816,9 +812,13 @@ static unsigned Opt_toseqax_tosneax (StackOpData* D, const char* BoolTransformer X = NewCodeEntry (OP65_CMP, LoadA->AM, LoadA->Arg, 0, D->OpEntry->LI); InsertEntry (D, X, D->IP++); - /* Rhs load entries can be removed */ - D->Rhs.X.Flags |= LI_REMOVE; - D->Rhs.A.Flags |= LI_REMOVE; + /* Rhs load entries must be removed if they are placed after the push */ + if (D->Rhs.X.LoadIndex > D->PushIndex) { + D->Rhs.X.Flags |= LI_REMOVE; + } + if (D->Rhs.A.LoadIndex > D->PushIndex) { + D->Rhs.A.Flags |= LI_REMOVE; + } } else if ((D->Rhs.A.Flags & LI_DIRECT) != 0 && (D->Rhs.X.Flags & LI_DIRECT) != 0) { @@ -897,11 +897,7 @@ static unsigned Opt_tosshift (StackOpData* D, const char* Name) /* ldx */ X = NewCodeEntry (OP65_LDX, LoadX->AM, LoadX->Arg, 0, D->OpEntry->LI); InsertEntry (D, X, D->IP++); - - /* Lhs load entries can be removed */ - D->Lhs.X.Flags |= LI_REMOVE; - D->Lhs.A.Flags |= LI_REMOVE; - + } else { /* Save lhs into zeropage and reload later */ From b2268765bf3b802ae81153d9e0ada7d03bb14d62 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 1 Jan 2020 23:44:47 +0800 Subject: [PATCH 1328/2161] The ref test cc65141011.c now passes. --- test/misc/Makefile | 4 ---- test/{misc => ref}/cc65141011.c | 0 2 files changed, 4 deletions(-) rename test/{misc => ref}/cc65141011.c (100%) diff --git a/test/misc/Makefile b/test/misc/Makefile index ad39176bd..15999ba3c 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -86,10 +86,6 @@ $(WORKDIR)/sitest.$1.$2.prg: sitest.c | $(WORKDIR) @echo "FIXME: " $$@ "currently will fail." -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) # -$(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) -$(WORKDIR)/cc65141011.$1.$2.prg: cc65141011.c | $(WORKDIR) - @echo "FIXME: " $$@ "currently can fail." - $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - -$(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) endef # PRG_template diff --git a/test/misc/cc65141011.c b/test/ref/cc65141011.c similarity index 100% rename from test/misc/cc65141011.c rename to test/ref/cc65141011.c From 48d3578c24a2017805e7fb1b67e1ea02de6e12c3 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 3 Jan 2020 08:20:07 +0800 Subject: [PATCH 1329/2161] Fixed Issue #784. --- src/cc65/coptstop.c | 51 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 28eaafd7b..7a4e336a2 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -60,6 +60,8 @@ typedef enum { LI_REMOVE = 0x04, /* Load may be removed */ LI_DONT_REMOVE = 0x08, /* Load may not be removed */ LI_DUP_LOAD = 0x10, /* Duplicate load */ + LI_VOLATILE_SRC = 0x20, /* Load src might be modified later */ + LI_SRC_CHG = 0x40, /* Load src is possibly modified */ } LI_FLAGS; /* Structure that tells us how to load the lhs values */ @@ -71,6 +73,7 @@ struct LoadRegInfo { int XferIndex; /* Index of transfer insn */ CodeEntry* XferEntry; /* The actual transfer entry */ int Offs; /* Stack offset if data is on stack */ + const char* Arg; /* Loaded src possibly modified later */ }; /* Now combined for both registers */ @@ -246,6 +249,40 @@ static void AdjustLoadInfo (LoadInfo* LI, int Index, int Change) +static int Affected (LoadRegInfo* RI, const CodeEntry* E) +/* Check if the load src is modified between the pushax and op */ +{ + if (RI->Flags & LI_VOLATILE_SRC) { + if (E->AM == AM65_IMM || E->AM == AM65_ACC || E->AM == AM65_IMP || E->AM == AM65_BRA) { + return 0; + } + if (E->OPC == OP65_JSR) { + if (E->Flags & CEF_USERMARK) { + /* User subs. Play it safe. */ + return 1; + } + /* We could filter the non-modifing functions. */ + /* But why bother optimizating for such rare cases? */ + return 1; + } else if (E->OPC == OP65_DEC || E->OPC == OP65_INC || + E->OPC == OP65_ASL || E->OPC == OP65_LSR || + E->OPC == OP65_ROL || E->OPC == OP65_ROR || + E->OPC == OP65_TRB || E->OPC == OP65_TSB || + E->OPC == OP65_STA || E->OPC == OP65_STX || E->OPC == OP65_STY) { + if ((E->AM == AM65_ABS || E->AM == AM65_ZP) && + strcmp (RI->Arg, E->Arg) != 0) { + return 0; + } + /* We could've check further for more cases where the load target isn't modified */ + /* But for now let's save the trouble and just play it safe */ + return 1; + } + } + return 0; +} + + + static void HonourUseAndChg (LoadRegInfo* RI, unsigned Reg, const CodeEntry* E) /* Honour use and change flags for an instruction */ { @@ -254,6 +291,9 @@ static void HonourUseAndChg (LoadRegInfo* RI, unsigned Reg, const CodeEntry* E) } else if ((E->Use & Reg) && RI->LoadIndex >= 0) { RI->Flags |= LI_DONT_REMOVE; } + if (Affected (RI, E)) { + RI->Flags |= LI_SRC_CHG; + } } @@ -288,10 +328,15 @@ static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I) RI->XferIndex = -1; /* Set load flags */ - RI->Flags &= ~(LI_DIRECT | LI_RELOAD_Y); - if (E->AM == AM65_IMM || E->AM == AM65_ZP || E->AM == AM65_ABS) { + RI->Flags &= ~(LI_DIRECT | LI_RELOAD_Y | LI_VOLATILE_SRC); + if (E->AM == AM65_IMM) { /* These insns are all ok and replaceable */ RI->Flags |= LI_DIRECT; + } else if (E->AM == AM65_ZP || E->AM == AM65_ABS) { + /* These insns are replaceable only if they are not modified later */ + RI->Flags |= LI_VOLATILE_SRC; + /* Watch for any change of the load target */ + RI->Arg = E->Arg; } else if (E->AM == AM65_ZP_INDY && RegValIsKnown (E->RI->In.RegY) && strcmp (E->Arg, "sp") == 0) { @@ -333,7 +378,7 @@ static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I) Tgt->LoadIndex = Src->LoadIndex; Tgt->XferIndex = I; Tgt->Offs = Src->Offs; - Tgt->Flags &= ~(LI_DIRECT | LI_RELOAD_Y); + Tgt->Flags &= ~(LI_DIRECT | LI_RELOAD_Y | LI_VOLATILE_SRC); Tgt->Flags |= Src->Flags & (LI_DIRECT | LI_RELOAD_Y); } else if (CE_IsCallTo (E, "ldaxysp") && RegValIsKnown (E->RI->In.RegY)) { From 49c5cfd65b59c8f69c87a20a10ce22d148ffd837 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 3 Jan 2020 08:20:14 +0800 Subject: [PATCH 1330/2161] Improved fix for Issues #167 and #784 and somehow #781. --- src/cc65/codeent.h | 1 + src/cc65/codeinfo.c | 10 +- src/cc65/codeinfo.h | 13 +- src/cc65/coptstop.c | 682 +++++++++++++++++++++++++++++++------------- 4 files changed, 507 insertions(+), 199 deletions(-) diff --git a/src/cc65/codeent.h b/src/cc65/codeent.h index 4d0289086..96373a8f9 100644 --- a/src/cc65/codeent.h +++ b/src/cc65/codeent.h @@ -61,6 +61,7 @@ /* Flags used */ #define CEF_USERMARK 0x0001U /* Generic mark by user functions */ #define CEF_NUMARG 0x0002U /* Insn has numerical argument */ +#define CEF_DONT_REMOVE 0x0004U /* Insn shouldn't be removed, marked by user functions */ /* Code entry structure */ typedef struct CodeEntry CodeEntry; diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 972d48f6a..b1e5668ce 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -375,7 +375,7 @@ static int CompareFuncInfo (const void* Key, const void* Info) -void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) +fncls_t GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) /* For the given function, lookup register information and store it into ** the given variables. If the function is unknown, assume it will use and ** load all registers. @@ -430,7 +430,7 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) *Chg = REG_ALL; /* Done */ - return; + return FNCLS_GLOBAL; } } else if (IsDigit (Name[0]) || Name[0] == '$') { @@ -441,7 +441,7 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) */ *Use = REG_ALL; *Chg = REG_ALL; - return; + return FNCLS_NUMERIC; } else { @@ -466,7 +466,7 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) *Use = REG_ALL; *Chg = REG_ALL; } - return; + return FNCLS_BUILTIN; } /* Function not found - assume that the primary register is input, and all @@ -474,6 +474,8 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) */ *Use = REG_EAXY; *Chg = REG_ALL; + + return FNCLS_UNKNOWN; } diff --git a/src/cc65/codeinfo.h b/src/cc65/codeinfo.h index be0bfbf01..38e196bcf 100644 --- a/src/cc65/codeinfo.h +++ b/src/cc65/codeinfo.h @@ -120,16 +120,27 @@ typedef enum { +/* Defines for the conditions in a compare */ +typedef enum { + FNCLS_UNKNOWN = -1, /* Unknown */ + FNCLS_BUILTIN, /* Builtin */ + FNCLS_GLOBAL, /* Found in global sym table minus the leading underscore */ + FNCLS_NUMERIC /* A call to a numeric address */ +} fncls_t; + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ -void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg); +fncls_t GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg); /* For the given function, lookup register information and store it into ** the given variables. If the function is unknown, assume it will use and ** load all registers. +** Return the whatever category the function is in. */ const ZPInfo* GetZPInfo (const char* Name); diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 7a4e336a2..46d600dba 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -59,9 +59,12 @@ typedef enum { LI_RELOAD_Y = 0x02, /* Reload index register Y */ LI_REMOVE = 0x04, /* Load may be removed */ LI_DONT_REMOVE = 0x08, /* Load may not be removed */ - LI_DUP_LOAD = 0x10, /* Duplicate load */ - LI_VOLATILE_SRC = 0x20, /* Load src might be modified later */ - LI_SRC_CHG = 0x40, /* Load src is possibly modified */ + LI_MAYBE_DIRECT = 0x10, /* Load src might be modified later */ + LI_SRC_CHG = 0x20, /* Load src is possibly modified */ + LI_LOAD_INSN = 0x40, /* Has a load insn */ + LI_USED_BY_A = 0x100, /* Content used by RegA */ + LI_USED_BY_X = 0x200, /* Content used by RegX */ + LI_USED_BY_Y = 0x400, /* Content used by RegY */ } LI_FLAGS; /* Structure that tells us how to load the lhs values */ @@ -73,7 +76,6 @@ struct LoadRegInfo { int XferIndex; /* Index of transfer insn */ CodeEntry* XferEntry; /* The actual transfer entry */ int Offs; /* Stack offset if data is on stack */ - const char* Arg; /* Loaded src possibly modified later */ }; /* Now combined for both registers */ @@ -94,13 +96,25 @@ struct LoadInfo { /* Flags for the functions */ typedef enum { - OP_NONE = 0x00, /* Nothing special */ - OP_A_KNOWN = 0x01, /* Value of A must be known */ - OP_X_ZERO = 0x02, /* X must be zero */ - OP_LHS_LOAD = 0x04, /* Must have load insns for LHS */ - OP_LHS_LOAD_DIRECT = 0x0C, /* Must have direct load insn for LHS */ - OP_RHS_LOAD = 0x10, /* Must have load insns for RHS */ - OP_RHS_LOAD_DIRECT = 0x30, /* Must have direct load insn for RHS */ + OP_NONE = 0x00, /* Nothing special */ + OP_A_KNOWN = 0x01, /* Value of A must be known */ + OP_X_ZERO = 0x02, /* X must be zero */ + OP_LHS_LOAD = 0x04, /* Must have load insns for LHS */ + OP_LHS_SAME_BY_OP = 0x08, /* Load result of LHS must be the same if relocated to op */ + OP_LHS_LOAD_DIRECT = 0x0C, /* Must have direct load insn for LHS */ + OP_RHS_LOAD = 0x10, /* Must have load insns for RHS */ + OP_RHS_SAME_BY_OP = 0x20, /* Load result of RHS must be the same if relocated to op */ + OP_RHS_LOAD_DIRECT = 0x30, /* Must have direct load insn for RHS */ + OP_AX_INTERCHANGE = 0x40, /* Preconditions of A/X may be interchanged */ + OP_LR_INTERCHANGE = 0x80, /* Preconditions of LHS/RHS may be interchanged */ + OP_LHS_SAME_BY_PUSH = 0x0100, /* LHS must load the same content if relocated to push */ + OP_RHS_SAME_BY_PUSH = 0x0200, /* RHS must load the same content if relocated to push */ + OP_LHS_SAME_BY_RHS = 0x0400, /* LHS must load the same content if relocated to RHS */ + OP_RHS_SAME_BY_LHS = 0x0800, /* RHS must load the same content if relocated to LHS */ + OP_LHS_REMOVE = 0x1000, /* LHS must be removable or RHS may use ZP store/load */ + OP_LHS_REMOVE_DIRECT = 0x3000, /* LHS must be directly removable */ + OP_RHS_REMOVE = 0x4000, /* RHS must be removable or LHS may use ZP store/load */ + OP_RHS_REMOVE_DIRECT = 0xC000, /* RHS must be directly removable */ } OP_FLAGS; /* Structure forward decl */ @@ -126,6 +140,10 @@ struct StackOpData { /* ZP register usage inside the sequence */ unsigned ZPUsage; + unsigned ZPChanged; + + /* Freedom of registers inside the sequence */ + unsigned UsedRegs; /* Registers used */ /* Register load information for lhs and rhs */ LoadInfo Lhs; @@ -159,12 +177,27 @@ static void ClearLoadRegInfo (LoadRegInfo* RI) { RI->Flags = LI_NONE; RI->LoadIndex = -1; + RI->LoadEntry = 0; RI->XferIndex = -1; + RI->XferEntry = 0; RI->Offs = 0; } +static void CopyLoadRegInfo (LoadRegInfo* To, LoadRegInfo* From) +/* Copy a LoadRegInfo struct */ +{ + To->Flags = From->Flags; + To->LoadIndex = From->LoadIndex; + To->LoadEntry = From->LoadEntry; + To->XferIndex = From->XferIndex; + To->XferEntry = From->XferEntry; + To->Offs = From->Offs; +} + + + static void FinalizeLoadRegInfo (LoadRegInfo* RI, CodeSeg* S) /* Prepare a LoadRegInfo struct for use */ { @@ -179,6 +212,10 @@ static void FinalizeLoadRegInfo (LoadRegInfo* RI, CodeSeg* S) } else { RI->XferEntry = 0; } + /* Load from src not modified before op can be treated as direct */ + if ((RI->Flags & (LI_MAYBE_DIRECT | LI_SRC_CHG)) == LI_MAYBE_DIRECT) { + RI->Flags |= LI_DIRECT; + } } @@ -193,6 +230,16 @@ static void ClearLoadInfo (LoadInfo* LI) +static void CopyLoadInfo (LoadInfo* To, LoadInfo* From) +/* Copy a LoadInfo struct */ +{ + CopyLoadRegInfo (&To->A, &From->A); + CopyLoadRegInfo (&To->X, &From->X); + CopyLoadRegInfo (&To->Y, &From->Y); +} + + + static void AdjustLoadRegInfo (LoadRegInfo* RI, int Index, int Change) /* Adjust a load register info struct after deleting or inserting an entry ** with a given index @@ -250,19 +297,27 @@ static void AdjustLoadInfo (LoadInfo* LI, int Index, int Change) static int Affected (LoadRegInfo* RI, const CodeEntry* E) -/* Check if the load src is modified between the pushax and op */ +/* Check if the load src may be modified between the pushax and op */ { - if (RI->Flags & LI_VOLATILE_SRC) { + fncls_t fncls; + unsigned short Use; + unsigned short Chg; + + if (RI->Flags & LI_MAYBE_DIRECT) { if (E->AM == AM65_IMM || E->AM == AM65_ACC || E->AM == AM65_IMP || E->AM == AM65_BRA) { return 0; } + CHECK (RI->LoadEntry != 0); + if (E->OPC == OP65_JSR) { - if (E->Flags & CEF_USERMARK) { - /* User subs. Play it safe. */ - return 1; + /* Try to know about the function */ + fncls = GetFuncInfo (E->Arg, &Use, &Chg); + if ((RI->LoadEntry->Use & Chg & REG_ALL) == 0 && + fncls == FNCLS_BUILTIN) { + /* Builtin functions are known to be harmless */ + return 0; } - /* We could filter the non-modifing functions. */ - /* But why bother optimizating for such rare cases? */ + /* Otherwise play it safe */ return 1; } else if (E->OPC == OP65_DEC || E->OPC == OP65_INC || E->OPC == OP65_ASL || E->OPC == OP65_LSR || @@ -270,11 +325,11 @@ static int Affected (LoadRegInfo* RI, const CodeEntry* E) E->OPC == OP65_TRB || E->OPC == OP65_TSB || E->OPC == OP65_STA || E->OPC == OP65_STX || E->OPC == OP65_STY) { if ((E->AM == AM65_ABS || E->AM == AM65_ZP) && - strcmp (RI->Arg, E->Arg) != 0) { + strcmp (RI->LoadEntry->Arg, E->Arg) != 0) { return 0; } - /* We could've check further for more cases where the load target isn't modified */ - /* But for now let's save the trouble and just play it safe */ + /* We could've check further for more cases where the load target isn't modified, + ** But for now let's save the trouble and just play it safe. */ return 1; } } @@ -283,24 +338,38 @@ static int Affected (LoadRegInfo* RI, const CodeEntry* E) -static void HonourUseAndChg (LoadRegInfo* RI, unsigned Reg, const CodeEntry* E) +static void HonourUseAndChg (LoadRegInfo* RI, unsigned Reg, const CodeEntry* E, int I) /* Honour use and change flags for an instruction */ { - if (E->Chg & Reg) { + if ((E->Chg & Reg) != 0) { + /* Remember this as an indirect load */ ClearLoadRegInfo (RI); - } else if ((E->Use & Reg) && RI->LoadIndex >= 0) { - RI->Flags |= LI_DONT_REMOVE; - } - if (Affected (RI, E)) { + RI->LoadIndex = I; + RI->XferIndex = -1; + RI->Flags = 0; + } else if (Affected (RI, E)) { RI->Flags |= LI_SRC_CHG; } } -static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I) -/* Track loads for a code entry */ +static unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I) +/* Track loads for a code entry. +** Return used registers. +*/ { + unsigned Used; + CodeEntry* E = CS_GetEntry (S, I); + CHECK (E != 0); + + /* By default */ + Used = E->Use; + + /* Whether we had a load or xfer op before or not, the newly loaded value + ** will be the real one used for the pushax/op unless it's overwritten, + ** so we can just reset the flags about it in such cases. + */ if (E->Info & OF_LOAD) { LoadRegInfo* RI = 0; @@ -315,28 +384,20 @@ static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I) } CHECK (RI != 0); - /* If we had a load or xfer op before, this is a duplicate load which - ** can cause problems if it encountered between the pushax and the op, - ** so remember it. - */ - if (RI->LoadIndex >= 0 || RI->XferIndex >= 0) { - RI->Flags |= LI_DUP_LOAD; - } - /* Remember the load */ RI->LoadIndex = I; RI->XferIndex = -1; /* Set load flags */ - RI->Flags &= ~(LI_DIRECT | LI_RELOAD_Y | LI_VOLATILE_SRC); + RI->Flags = LI_LOAD_INSN; if (E->AM == AM65_IMM) { /* These insns are all ok and replaceable */ RI->Flags |= LI_DIRECT; } else if (E->AM == AM65_ZP || E->AM == AM65_ABS) { /* These insns are replaceable only if they are not modified later */ - RI->Flags |= LI_VOLATILE_SRC; + RI->Flags |= LI_MAYBE_DIRECT; /* Watch for any change of the load target */ - RI->Arg = E->Arg; + RI->LoadEntry = CS_GetEntry (S, I); } else if (E->AM == AM65_ZP_INDY && RegValIsKnown (E->RI->In.RegY) && strcmp (E->Arg, "sp") == 0) { @@ -348,8 +409,16 @@ static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I) */ RI->Offs = (unsigned char) E->RI->In.RegY; RI->Flags |= (LI_DIRECT | LI_RELOAD_Y); + + /* Reg Y can be regarded as unused if this load is removed */ + Used &= ~REG_Y; + LI->Y.Flags |= LI_USED_BY_A; } + /* Watch for any change of the load target */ + if ((RI->Flags & LI_MAYBE_DIRECT) != 0) { + RI->LoadEntry = CS_GetEntry (S, I); + } } else if (E->Info & OF_XFR) { @@ -357,60 +426,82 @@ static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I) LoadRegInfo* Src; LoadRegInfo* Tgt; switch (E->OPC) { - case OP65_TAX: Src = &LI->A; Tgt = &LI->X; break; - case OP65_TAY: Src = &LI->A; Tgt = &LI->Y; break; - case OP65_TXA: Src = &LI->X; Tgt = &LI->A; break; - case OP65_TYA: Src = &LI->Y; Tgt = &LI->A; break; - case OP65_TSX: ClearLoadRegInfo (&LI->X); return; - case OP65_TXS: return; + case OP65_TAX: + Src = &LI->A; + Tgt = &LI->X; + Used &= ~REG_A; + Src->Flags |= LI_USED_BY_X; + break; + case OP65_TAY: + Src = &LI->A; + Tgt = &LI->Y; + Used &= ~REG_A; + Src->Flags |= LI_USED_BY_Y; + break; + case OP65_TXA: + Src = &LI->X; + Tgt = &LI->A; + Used &= ~REG_X; + Src->Flags |= LI_USED_BY_A; + break; + case OP65_TYA: + Src = &LI->Y; + Tgt = &LI->A; + Used &= ~REG_Y; + Src->Flags |= LI_USED_BY_A; + break; + case OP65_TSX: + ClearLoadRegInfo (&LI->X); + return Used; + case OP65_TXS: + return Used; default: Internal ("Unknown XFR insn in TrackLoads"); } - /* If we had a load or xfer op before, this is a duplicate load which - ** can cause problems if it encountered between the pushax and the op, - ** so remember it. - */ - if (Tgt->LoadIndex >= 0 || Tgt->XferIndex >= 0) { - Tgt->Flags |= LI_DUP_LOAD; - } - /* Transfer the data */ - Tgt->LoadIndex = Src->LoadIndex; - Tgt->XferIndex = I; - Tgt->Offs = Src->Offs; - Tgt->Flags &= ~(LI_DIRECT | LI_RELOAD_Y | LI_VOLATILE_SRC); - Tgt->Flags |= Src->Flags & (LI_DIRECT | LI_RELOAD_Y); + Tgt->LoadIndex = Src->LoadIndex; + Tgt->LoadEntry = Src->LoadEntry; + Tgt->XferIndex = I; + Tgt->Offs = Src->Offs; + Tgt->Flags = Src->Flags; } else if (CE_IsCallTo (E, "ldaxysp") && RegValIsKnown (E->RI->In.RegY)) { - /* If we had a load or xfer op before, this is a duplicate load which - ** can cause problems if it encountered between the pushax and the op, - ** so remember it for both registers involved. - */ - if (LI->A.LoadIndex >= 0 || LI->A.XferIndex >= 0) { - LI->A.Flags |= LI_DUP_LOAD; - } - if (LI->X.LoadIndex >= 0 || LI->X.XferIndex >= 0) { - LI->X.Flags |= LI_DUP_LOAD; - } - /* Both registers set, Y changed */ LI->A.LoadIndex = I; LI->A.XferIndex = -1; - LI->A.Flags |= (LI_DIRECT | LI_RELOAD_Y); + LI->A.Flags = (LI_LOAD_INSN | LI_DIRECT | LI_RELOAD_Y); LI->A.Offs = (unsigned char) E->RI->In.RegY - 1; LI->X.LoadIndex = I; LI->X.XferIndex = -1; - LI->X.Flags |= (LI_DIRECT | LI_RELOAD_Y); + LI->X.Flags = (LI_LOAD_INSN | LI_DIRECT | LI_RELOAD_Y); LI->X.Offs = (unsigned char) E->RI->In.RegY; - ClearLoadRegInfo (&LI->Y); + /* Reg Y can be regarded as unused if this load is removed */ + Used &= ~REG_Y; + LI->Y.Flags |= LI_USED_BY_A | LI_USED_BY_X; + } else { - HonourUseAndChg (&LI->A, REG_A, E); - HonourUseAndChg (&LI->X, REG_X, E); - HonourUseAndChg (&LI->Y, REG_Y, E); + HonourUseAndChg (&LI->A, REG_A, E, I); + HonourUseAndChg (&LI->X, REG_X, E, I); + HonourUseAndChg (&LI->Y, REG_Y, E, I); + + /* The other operand may be affected too */ + if (LLI != 0) { + if (Affected (&LLI->A, E)) { + LLI->A.Flags |= LI_SRC_CHG; + } + if (Affected (&LLI->X, E)) { + LLI->X.Flags |= LI_SRC_CHG; + } + if (Affected (&LLI->Y, E)) { + LLI->Y.Flags |= LI_SRC_CHG; + } + } } + + return Used; } @@ -574,7 +665,7 @@ static void AdjustStackOffset (StackOpData* D, unsigned Offs) -static void AddStoreA (StackOpData* D) +static void AddStoreLhsA (StackOpData* D) /* Add a store to zero page after the push insn */ { CodeEntry* X = NewCodeEntry (OP65_STA, AM65_ZP, D->ZPLo, 0, D->PushEntry->LI); @@ -583,7 +674,7 @@ static void AddStoreA (StackOpData* D) -static void AddStoreX (StackOpData* D) +static void AddStoreLhsX (StackOpData* D) /* Add a store to zero page after the push insn */ { CodeEntry* X = NewCodeEntry (OP65_STX, AM65_ZP, D->ZPHi, 0, D->PushEntry->LI); @@ -603,10 +694,10 @@ static void ReplacePushByStore (StackOpData* D) ** byte first so that the store is later in A/X order. */ if ((D->Lhs.X.Flags & LI_DIRECT) == 0) { - AddStoreX (D); + AddStoreLhsX (D); } if ((D->Lhs.A.Flags & LI_DIRECT) == 0) { - AddStoreA (D); + AddStoreLhsA (D); } } @@ -725,19 +816,23 @@ static void RemoveRegLoads (StackOpData* D, LoadInfo* LI) /* Both registers may be loaded with one insn, but DelEntry will in this ** case clear the other one. */ - if ((LI->A.Flags & (LI_REMOVE | LI_DONT_REMOVE)) == LI_REMOVE) { - if (LI->A.LoadIndex >= 0) { + if ((LI->A.Flags & LI_REMOVE) == LI_REMOVE) { + if (LI->A.LoadIndex >= 0 && + (LI->A.LoadEntry->Flags & CEF_DONT_REMOVE) == 0) { DelEntry (D, LI->A.LoadIndex); } - if (LI->A.XferIndex >= 0) { + if (LI->A.XferIndex >= 0 && + (LI->A.XferEntry->Flags & CEF_DONT_REMOVE) == 0) { DelEntry (D, LI->A.XferIndex); } } - if ((LI->X.Flags & (LI_REMOVE | LI_DONT_REMOVE)) == LI_REMOVE) { - if (LI->X.LoadIndex >= 0) { + if ((LI->X.Flags & LI_REMOVE) == LI_REMOVE) { + if (LI->X.LoadIndex >= 0 && + (LI->X.LoadEntry->Flags & CEF_DONT_REMOVE) == 0) { DelEntry (D, LI->X.LoadIndex); } - if (LI->X.XferIndex >= 0) { + if (LI->X.XferIndex >= 0 && + (LI->X.XferEntry->Flags & CEF_DONT_REMOVE) == 0) { DelEntry (D, LI->X.XferIndex); } } @@ -748,7 +843,7 @@ static void RemoveRegLoads (StackOpData* D, LoadInfo* LI) static void RemoveRemainders (StackOpData* D) /* Remove the code that is unnecessary after translation of the sequence */ { - /* Remove the register loads for lhs and rhs */ + /* Remove the register loads for lhs and rhs if nothing prevents that */ RemoveRegLoads (D, &D->Lhs); RemoveRegLoads (D, &D->Rhs); @@ -760,15 +855,21 @@ static void RemoveRemainders (StackOpData* D) static int IsRegVar (StackOpData* D) -/* If the value pushed is that of a zeropage variable, replace ZPLo and ZPHi -** in the given StackOpData struct by the variable and return true. Otherwise -** leave D untouched and return false. +/* If the value pushed is that of a zeropage variable that is unchanged until Op, +** replace ZPLo and ZPHi in the given StackOpData struct by the variable and return true. +** Otherwise leave D untouched and return false. */ { CodeEntry* LoadA = D->Lhs.A.LoadEntry; CodeEntry* LoadX = D->Lhs.X.LoadEntry; unsigned Len; + /* Must be unchanged till Op */ + if ((D->Lhs.A.Flags & (LI_DIRECT | LI_RELOAD_Y)) != LI_DIRECT || + (D->Lhs.X.Flags & (LI_DIRECT | LI_RELOAD_Y)) != LI_DIRECT) { + return 0; + } + /* Must have both load insns */ if (LoadA == 0 || LoadX == 0) { return 0; @@ -837,6 +938,10 @@ static unsigned Opt_toseqax_tosneax (StackOpData* D, const char* BoolTransformer X = NewCodeEntry (OP65_CMP, LoadA->AM, LoadA->Arg, 0, D->OpEntry->LI); InsertEntry (D, X, D->IP++); + /* Lhs load entries can be removed if not used later */ + D->Lhs.X.Flags |= LI_REMOVE; + D->Lhs.A.Flags |= LI_REMOVE; + } else if ((D->Rhs.A.Flags & (LI_DIRECT | LI_RELOAD_Y)) == LI_DIRECT && (D->Rhs.X.Flags & (LI_DIRECT | LI_RELOAD_Y)) == LI_DIRECT) { @@ -857,13 +962,9 @@ static unsigned Opt_toseqax_tosneax (StackOpData* D, const char* BoolTransformer X = NewCodeEntry (OP65_CMP, LoadA->AM, LoadA->Arg, 0, D->OpEntry->LI); InsertEntry (D, X, D->IP++); - /* Rhs load entries must be removed if they are placed after the push */ - if (D->Rhs.X.LoadIndex > D->PushIndex) { - D->Rhs.X.Flags |= LI_REMOVE; - } - if (D->Rhs.A.LoadIndex > D->PushIndex) { - D->Rhs.A.Flags |= LI_REMOVE; - } + /* Rhs load entries must be removed */ + D->Rhs.X.Flags |= LI_REMOVE; + D->Rhs.A.Flags |= LI_REMOVE; } else if ((D->Rhs.A.Flags & LI_DIRECT) != 0 && (D->Rhs.X.Flags & LI_DIRECT) != 0) { @@ -883,8 +984,8 @@ static unsigned Opt_toseqax_tosneax (StackOpData* D, const char* BoolTransformer } else { /* Save lhs into zeropage, then compare */ - AddStoreX (D); - AddStoreA (D); + AddStoreLhsX (D); + AddStoreLhsA (D); D->IP = D->OpIndex+1; @@ -943,11 +1044,15 @@ static unsigned Opt_tosshift (StackOpData* D, const char* Name) X = NewCodeEntry (OP65_LDX, LoadX->AM, LoadX->Arg, 0, D->OpEntry->LI); InsertEntry (D, X, D->IP++); + /* Lhs load entries can be removed if not used later */ + D->Lhs.X.Flags |= LI_REMOVE; + D->Lhs.A.Flags |= LI_REMOVE; + } else { /* Save lhs into zeropage and reload later */ - AddStoreX (D); - AddStoreA (D); + AddStoreLhsX (D); + AddStoreLhsA (D); /* Be sure to setup IP after adding the stores, otherwise it will get ** messed up. @@ -991,8 +1096,8 @@ static unsigned Opt___bzero (StackOpData* D) /* Check if we're using a register variable */ if (!IsRegVar (D)) { /* Store the value into the zeropage instead of pushing it */ - AddStoreX (D); - AddStoreA (D); + AddStoreLhsX (D); + AddStoreLhsA (D); } /* If the return value of __bzero is used, we have to add code to reload @@ -1083,8 +1188,8 @@ static unsigned Opt_staspidx (StackOpData* D) /* Check if we're using a register variable */ if (!IsRegVar (D)) { /* Store the value into the zeropage instead of pushing it */ - AddStoreX (D); - AddStoreA (D); + AddStoreLhsX (D); + AddStoreLhsA (D); } /* Replace the store subroutine call by a direct op */ @@ -1108,8 +1213,8 @@ static unsigned Opt_staxspidx (StackOpData* D) /* Check if we're using a register variable */ if (!IsRegVar (D)) { /* Store the value into the zeropage instead of pushing it */ - AddStoreX (D); - AddStoreA (D); + AddStoreLhsX (D); + AddStoreLhsA (D); } /* Inline the store */ @@ -1187,8 +1292,8 @@ static unsigned Opt_tosaddax (StackOpData* D) int Signed = (strcmp (N->Arg, "ldaidx") == 0); /* Store the value into the zeropage instead of pushing it */ - AddStoreX (D); - AddStoreA (D); + AddStoreLhsX (D); + AddStoreLhsA (D); /* Replace the ldy by a tay. Be sure to create the new entry before ** deleting the ldy, since we will reference the line info from this @@ -1386,6 +1491,10 @@ static unsigned Opt_tosgeax (StackOpData* D) X = NewCodeEntry (OP65_ROL, AM65_ACC, "a", 0, D->OpEntry->LI); InsertEntry (D, X, D->IP++); + /* Rhs load entries must be removed */ + D->Rhs.X.Flags |= LI_REMOVE; + D->Rhs.A.Flags |= LI_REMOVE; + /* Remove the push and the call to the tosgeax function */ RemoveRemainders (D); @@ -1440,6 +1549,10 @@ static unsigned Opt_tosltax (StackOpData* D) X = NewCodeEntry (OP65_ROL, AM65_ACC, "a", 0, D->OpEntry->LI); InsertEntry (D, X, D->IP++); + /* Rhs load entries must be removed */ + D->Rhs.X.Flags |= LI_REMOVE; + D->Rhs.A.Flags |= LI_REMOVE; + /* Remove the push and the call to the tosltax function */ RemoveRemainders (D); @@ -1517,6 +1630,10 @@ static unsigned Opt_tossubax (StackOpData* D) /* Add code for high operand */ AddOpHigh (D, OP65_SBC, &D->Rhs, 1); + /* Rhs load entries must be removed */ + D->Rhs.X.Flags |= LI_REMOVE; + D->Rhs.A.Flags |= LI_REMOVE; + /* Remove the push and the call to the tossubax function */ RemoveRemainders (D); @@ -1556,6 +1673,10 @@ static unsigned Opt_tosugeax (StackOpData* D) X = NewCodeEntry (OP65_ROL, AM65_ACC, "a", 0, D->OpEntry->LI); InsertEntry (D, X, D->IP++); + /* Rhs load entries must be removed */ + D->Rhs.X.Flags |= LI_REMOVE; + D->Rhs.A.Flags |= LI_REMOVE; + /* Remove the push and the call to the tosugeax function */ RemoveRemainders (D); @@ -1599,6 +1720,10 @@ static unsigned Opt_tosugtax (StackOpData* D) X = NewCodeEntry (OP65_JSR, AM65_ABS, "boolugt", 0, D->OpEntry->LI); InsertEntry (D, X, D->IP++); + /* Rhs load entries must be removed */ + D->Rhs.X.Flags |= LI_REMOVE; + D->Rhs.A.Flags |= LI_REMOVE; + /* Remove the push and the call to the operator function */ RemoveRemainders (D); @@ -1642,6 +1767,10 @@ static unsigned Opt_tosuleax (StackOpData* D) X = NewCodeEntry (OP65_JSR, AM65_ABS, "boolule", 0, D->OpEntry->LI); InsertEntry (D, X, D->IP++); + /* Rhs load entries must be removed */ + D->Rhs.X.Flags |= LI_REMOVE; + D->Rhs.A.Flags |= LI_REMOVE; + /* Remove the push and the call to the operator function */ RemoveRemainders (D); @@ -1673,6 +1802,10 @@ static unsigned Opt_tosultax (StackOpData* D) X = NewCodeEntry (OP65_JSR, AM65_ABS, "boolult", 0, D->OpEntry->LI); InsertEntry (D, X, D->IP++); + /* Rhs load entries must be removed */ + D->Rhs.X.Flags |= LI_REMOVE; + D->Rhs.A.Flags |= LI_REMOVE; + /* Remove the push and the call to the operator function */ RemoveRemainders (D); @@ -1723,26 +1856,26 @@ static unsigned Opt_tosxorax (StackOpData* D) static const OptFuncDesc FuncTable[] = { - { "__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 }, - { "tosaddax", Opt_tosaddax, REG_NONE, OP_NONE }, - { "tosandax", Opt_tosandax, REG_NONE, OP_NONE }, - { "tosaslax", Opt_tosaslax, REG_NONE, OP_NONE }, - { "tosasrax", Opt_tosasrax, REG_NONE, OP_NONE }, - { "toseqax", Opt_toseqax, REG_NONE, OP_NONE }, - { "tosgeax", Opt_tosgeax, REG_NONE, OP_RHS_LOAD_DIRECT }, - { "tosltax", Opt_tosltax, REG_NONE, OP_RHS_LOAD_DIRECT }, - { "tosneax", Opt_tosneax, REG_NONE, OP_NONE }, - { "tosorax", Opt_tosorax, REG_NONE, OP_NONE }, - { "tosshlax", Opt_tosshlax, REG_NONE, OP_NONE }, - { "tosshrax", Opt_tosshrax, REG_NONE, OP_NONE }, - { "tossubax", Opt_tossubax, REG_NONE, OP_RHS_LOAD_DIRECT }, - { "tosugeax", Opt_tosugeax, REG_NONE, OP_RHS_LOAD_DIRECT }, - { "tosugtax", Opt_tosugtax, REG_NONE, OP_RHS_LOAD_DIRECT }, - { "tosuleax", Opt_tosuleax, REG_NONE, OP_RHS_LOAD_DIRECT }, - { "tosultax", Opt_tosultax, REG_NONE, OP_RHS_LOAD_DIRECT }, - { "tosxorax", Opt_tosxorax, REG_NONE, OP_NONE }, + { "__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 }, + { "tosaddax", Opt_tosaddax, REG_NONE, OP_NONE }, + { "tosandax", Opt_tosandax, REG_NONE, OP_NONE }, + { "tosaslax", Opt_tosaslax, REG_NONE, OP_NONE }, + { "tosasrax", Opt_tosasrax, REG_NONE, OP_NONE }, + { "toseqax", Opt_toseqax, REG_NONE, OP_LR_INTERCHANGE | OP_RHS_REMOVE_DIRECT }, + { "tosgeax", Opt_tosgeax, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT }, + { "tosltax", Opt_tosltax, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT }, + { "tosneax", Opt_tosneax, REG_NONE, OP_LR_INTERCHANGE | OP_RHS_REMOVE_DIRECT }, + { "tosorax", Opt_tosorax, REG_NONE, OP_NONE }, + { "tosshlax", Opt_tosshlax, REG_NONE, OP_NONE }, + { "tosshrax", Opt_tosshrax, REG_NONE, OP_NONE }, + { "tossubax", Opt_tossubax, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT }, + { "tosugeax", Opt_tosugeax, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT }, + { "tosugtax", Opt_tosugtax, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT }, + { "tosuleax", Opt_tosuleax, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT }, + { "tosultax", Opt_tosultax, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT }, + { "tosxorax", Opt_tosxorax, REG_NONE, OP_NONE }, }; #define FUNC_COUNT (sizeof(FuncTable) / sizeof(FuncTable[0])) @@ -1840,6 +1973,8 @@ static void ResetStackOpData (StackOpData* Data) { Data->OptFunc = 0; Data->ZPUsage = REG_NONE; + Data->ZPChanged = REG_NONE; + Data->UsedRegs = REG_NONE; ClearLoadInfo (&Data->Lhs); ClearLoadInfo (&Data->Rhs); @@ -1856,6 +1991,17 @@ static int PreCondOk (StackOpData* D) ** register to use. */ { + LoadInfo* Lhs; + LoadInfo* Rhs; + LoadRegInfo* LhsLo; + LoadRegInfo* LhsHi; + LoadRegInfo* RhsLo; + LoadRegInfo* RhsHi; + short LoVal; + short HiVal; + int I; + int Passed = 0; + /* Check the flags */ unsigned UnusedRegs = D->OptFunc->UnusedRegs; if (UnusedRegs != REG_NONE && @@ -1863,39 +2009,100 @@ static int PreCondOk (StackOpData* D) /* Cannot optimize */ return 0; } - if ((D->OptFunc->Flags & OP_A_KNOWN) != 0 && - RegValIsUnknown (D->OpEntry->RI->In.RegA)) { + + Passed = 0; + LoVal = D->OpEntry->RI->In.RegA; + HiVal = D->OpEntry->RI->In.RegX; + /* Check normally first, then interchange A/X and check again if necessary */ + for (I = (D->OptFunc->Flags & OP_AX_INTERCHANGE ? 0 : 1); !Passed && I < 2; ++I) { + + do { + if ((D->OptFunc->Flags & OP_A_KNOWN) != 0 && + RegValIsUnknown (LoVal)) { + /* Cannot optimize */ + break; + } + if ((D->OptFunc->Flags & OP_X_ZERO) != 0 && + HiVal != 0) { + /* Cannot optimize */ + break; + } + Passed = 1; + } while (0); + + /* Interchange A/X */ + LoVal = D->OpEntry->RI->In.RegX; + HiVal = D->OpEntry->RI->In.RegA; + } + if (!Passed) { /* Cannot optimize */ return 0; } - if ((D->OptFunc->Flags & OP_X_ZERO) != 0 && - D->OpEntry->RI->In.RegX != 0) { - /* Cannot optimize */ - return 0; - } - if ((D->OptFunc->Flags & OP_LHS_LOAD) != 0) { - if (D->Lhs.A.LoadIndex < 0 || D->Lhs.X.LoadIndex < 0) { - /* Cannot optimize */ - return 0; - } else if ((D->OptFunc->Flags & OP_LHS_LOAD_DIRECT) != 0) { - if ((D->Lhs.A.Flags & D->Lhs.X.Flags & LI_DIRECT) == 0) { - /* Cannot optimize */ - return 0; + + Passed = 0; + Lhs = &D->Lhs; + Rhs = &D->Rhs; + /* Check normally first, then interchange LHS/RHS and check again if necessary */ + for (I = (D->OptFunc->Flags & OP_LR_INTERCHANGE ? 0 : 1); !Passed && I < 2; ++I) { + + do { + LhsLo = &Lhs->A; + LhsHi = &Lhs->X; + RhsLo = &Rhs->A; + RhsHi = &Rhs->X; + /* Currently we have only LHS/RHS checks with identical requirements for A/X, + ** so we don't need to check twice for now. + */ + + if ((D->OptFunc->Flags & OP_LHS_LOAD) != 0) { + if ((LhsLo->Flags & LhsHi->Flags & LI_LOAD_INSN) == 0) { + /* Cannot optimize */ + break; + } else if ((D->OptFunc->Flags & OP_LHS_LOAD_DIRECT) != 0) { + if ((LhsLo->Flags & LhsHi->Flags & LI_DIRECT) == 0) { + /* Cannot optimize */ + break; + } + } } - } - } - if ((D->OptFunc->Flags & OP_RHS_LOAD) != 0) { - if (D->Rhs.A.LoadIndex < 0 || D->Rhs.X.LoadIndex < 0) { - /* Cannot optimize */ - return 0; - } else if ((D->OptFunc->Flags & OP_RHS_LOAD_DIRECT) != 0) { - if ((D->Rhs.A.Flags & D->Rhs.X.Flags & LI_DIRECT) == 0) { - /* Cannot optimize */ - return 0; + if ((D->OptFunc->Flags & OP_RHS_LOAD) != 0) { + if ((RhsLo->Flags & RhsHi->Flags & LI_LOAD_INSN) == 0) { + /* Cannot optimize */ + break; + } else if ((D->OptFunc->Flags & OP_RHS_LOAD_DIRECT) != 0) { + if ((RhsLo->Flags & RhsHi->Flags & LI_DIRECT) == 0) { + /* Cannot optimize */ + break; + } + } } - } + if ((D->OptFunc->Flags & OP_LHS_REMOVE) != 0) { + /* Check if the load entries cannot be removed */ + if ((LhsLo->LoadEntry != 0 && (LhsLo->LoadEntry->Flags & CEF_DONT_REMOVE) != 0) || + (LhsHi->LoadEntry != 0 && (LhsHi->LoadEntry->Flags & CEF_DONT_REMOVE) != 0)) { + if ((D->OptFunc->Flags & OP_LHS_REMOVE_DIRECT) != 0) { + /* Cannot optimize */ + break; + } + } + } + if ((D->OptFunc->Flags & OP_RHS_REMOVE) != 0) { + if ((RhsLo->LoadEntry != 0 && (RhsLo->LoadEntry->Flags & CEF_DONT_REMOVE) != 0) || + (RhsHi->LoadEntry != 0 && (RhsHi->LoadEntry->Flags & CEF_DONT_REMOVE) != 0)) { + if ((D->OptFunc->Flags & OP_RHS_REMOVE_DIRECT) != 0) { + /* Cannot optimize */ + break; + } + } + } + Passed = 1; + } while (0); + + /* Interchange LHS/RHS for next round */ + Lhs = &D->Rhs; + Rhs = &D->Lhs; } - if ((D->Rhs.A.Flags | D->Rhs.X.Flags) & LI_DUP_LOAD) { + if (!Passed) { /* Cannot optimize */ return 0; } @@ -1929,6 +2136,52 @@ static int PreCondOk (StackOpData* D) +static void SetDontRemoveEntryFlag (LoadRegInfo* RI) +/* Flag the entry as non-removable according to register flags */ +{ + if (RI->Flags & LI_DONT_REMOVE) { + if (RI->LoadEntry != 0) { + RI->LoadEntry->Flags |= CEF_DONT_REMOVE; + } + } +} + + + +static void ResetDontRemoveEntryFlag (LoadRegInfo* RI) +/* Unflag the entry as non-removable according to register flags */ +{ + if (RI->Flags & LI_DONT_REMOVE) { + if (RI->LoadEntry != 0) { + RI->LoadEntry->Flags &= ~CEF_DONT_REMOVE; + } + } +} + + + +static void SetDontRemoveEntryFlags (StackOpData* D) +/* Flag the entries as non-removable according to register flags */ +{ + SetDontRemoveEntryFlag (&D->Lhs.A); + SetDontRemoveEntryFlag (&D->Lhs.X); + SetDontRemoveEntryFlag (&D->Rhs.A); + SetDontRemoveEntryFlag (&D->Rhs.X); +} + + + +static void ResetDontRemoveEntryFlags (StackOpData* D) +/* Unflag the entries as non-removable according to register flags */ +{ + ResetDontRemoveEntryFlag (&D->Lhs.A); + ResetDontRemoveEntryFlag (&D->Lhs.X); + ResetDontRemoveEntryFlag (&D->Rhs.A); + ResetDontRemoveEntryFlag (&D->Rhs.X); +} + + + unsigned OptStackOps (CodeSeg* S) /* Optimize operations that take operands via the stack */ { @@ -1936,9 +2189,8 @@ unsigned OptStackOps (CodeSeg* S) StackOpData Data; int I; int OldEntryCount; /* Old number of entries */ - unsigned UsedRegs = 0; /* Registers used */ - unsigned ChangedRegs = 0;/* Registers changed */ - + unsigned Used; /* What registers would be used */ + unsigned PushedRegs; /* Track if the same regs are used after the push */ enum { Initialize, @@ -1977,7 +2229,6 @@ unsigned OptStackOps (CodeSeg* S) case Initialize: ResetStackOpData (&Data); - UsedRegs = ChangedRegs = REG_NONE; State = Search; /* FALLTHROUGH */ @@ -1986,15 +2237,39 @@ unsigned OptStackOps (CodeSeg* S) ** what is in a register once pushax is encountered. */ if (CE_HasLabel (E)) { - /* Currently we don't track across branches */ + /* Currently we don't track across branches. + ** Remember this as an indirect load. + */ ClearLoadInfo (&Data.Lhs); + Data.Lhs.A.LoadIndex = I; + Data.Lhs.X.LoadIndex = I; + Data.Lhs.Y.LoadIndex = I; } if (CE_IsCallTo (E, "pushax")) { + /* Disallow removing the loads if the registers are used */ + if (Data.UsedRegs & REG_A) { + Data.Lhs.A.Flags |= LI_DONT_REMOVE; + } + if (Data.UsedRegs & REG_X) { + Data.Lhs.X.Flags |= LI_DONT_REMOVE; + } + if (Data.UsedRegs & REG_Y) { + Data.Lhs.Y.Flags |= LI_DONT_REMOVE; + } + + /* The LHS regs are also used as the default RHS until changed */ + PushedRegs = REG_AXY; + Data.UsedRegs = REG_AXY; + CopyLoadInfo (&Data.Rhs, &Data.Lhs); + Data.PushIndex = I; + Data.PushEntry = E; State = FoundPush; } else { /* Track load insns */ - TrackLoads (&Data.Lhs, E, I); + Used = TrackLoads (&Data.Lhs, 0, Data.Code, I); + Data.UsedRegs &= ~E->Chg; + Data.UsedRegs |= Used; } break; @@ -2004,8 +2279,13 @@ unsigned OptStackOps (CodeSeg* S) ** for code that will disable us from translating the sequence. */ if (CE_HasLabel (E)) { - /* Currently we don't track across branches */ + /* Currently we don't track across branches. + ** Remember this as an indirect load. + */ ClearLoadInfo (&Data.Rhs); + Data.Rhs.A.LoadIndex = I; + Data.Rhs.X.LoadIndex = I; + Data.Rhs.Y.LoadIndex = I; } if (E->OPC == OP65_JSR) { @@ -2014,6 +2294,16 @@ unsigned OptStackOps (CodeSeg* S) */ Data.OptFunc = FindFunc (E->Arg); if (Data.OptFunc) { + /* Disallow removing the loads if the registers are used */ + if (Data.UsedRegs & REG_A) { + Data.Rhs.A.Flags |= LI_DONT_REMOVE; + } + if (Data.UsedRegs & REG_X) { + Data.Rhs.X.Flags |= LI_DONT_REMOVE; + } + if (Data.UsedRegs & REG_Y) { + Data.Rhs.Y.Flags |= LI_DONT_REMOVE; + } /* Remember the op index and go on */ Data.OpIndex = I; Data.OpEntry = E; @@ -2027,22 +2317,9 @@ unsigned OptStackOps (CodeSeg* S) I = Data.PushIndex; State = Initialize; break; - } else { - /* Track register usage */ - Data.ZPUsage |= (E->Use | E->Chg); - TrackLoads (&Data.Rhs, E, I); } - } else if (E->Info & OF_STORE && (E->Chg & REG_ZP) == 0) { - - /* Too dangerous - there may be a change of a variable - ** within the sequence. - */ - I = Data.PushIndex; - State = Initialize; - break; - - } else if ((E->Use & REG_SP) != 0 && + } else if ((E->Use & REG_SP) != 0 && (E->AM != AM65_ZP_INDY || RegValIsUnknown (E->RI->In.RegY) || E->RI->In.RegY < 2)) { @@ -2059,22 +2336,31 @@ unsigned OptStackOps (CodeSeg* S) State = Initialize; break; - } else { - /* Other stuff: Track register usage */ - Data.ZPUsage |= (E->Use | E->Chg); - TrackLoads (&Data.Rhs, E, I); } - /* If the registers from the push (A/X) are used before they're - ** changed, we cannot change the sequence, because this would - ** with a high probability change the register contents. - */ - UsedRegs |= E->Use; - if ((UsedRegs & ~ChangedRegs) & REG_AX) { - I = Data.PushIndex; - State = Initialize; - break; + + /* Track register usage */ + Used = TrackLoads (&Data.Rhs, &Data.Lhs, Data.Code, I); + Data.ZPUsage |= (E->Use | E->Chg); + /* The changes could depend on the use */ + Data.UsedRegs &= ~E->Chg; + Data.UsedRegs |= Used; + Data.ZPChanged |= E->Chg; + + /* Check if any parts of Lhs are used again before overwritten */ + if (PushedRegs != 0) { + if ((PushedRegs & E->Use) != 0) { + if ((PushedRegs & E->Use & REG_A) != 0) { + Data.Lhs.A.Flags |= LI_DONT_REMOVE; + } + if ((PushedRegs & E->Use & REG_X) != 0) { + Data.Lhs.X.Flags |= LI_DONT_REMOVE; + } + if ((PushedRegs & E->Use & REG_Y) != 0) { + Data.Lhs.Y.Flags |= LI_DONT_REMOVE; + } + } + PushedRegs &= ~E->Chg; } - ChangedRegs |= E->Chg; break; case FoundOp: @@ -2093,26 +2379,31 @@ unsigned OptStackOps (CodeSeg* S) ** original zero page locations for the final op, but must ** use another ZP location to save them. */ - ChangedRegs &= REG_ZP; + Data.ZPChanged &= REG_ZP; if (Data.Lhs.A.LoadEntry && Data.Lhs.A.LoadEntry->AM == AM65_ZP) { Data.ZPUsage |= Data.Lhs.A.LoadEntry->Use; - if ((Data.Lhs.A.LoadEntry->Use & ChangedRegs) != 0) { + if ((Data.Lhs.A.LoadEntry->Use & Data.ZPChanged) != 0) { Data.Lhs.A.Flags &= ~(LI_DIRECT | LI_RELOAD_Y); } } if (Data.Lhs.X.LoadEntry && Data.Lhs.X.LoadEntry->AM == AM65_ZP) { Data.ZPUsage |= Data.Lhs.X.LoadEntry->Use; - if ((Data.Lhs.X.LoadEntry->Use & ChangedRegs) != 0) { + if ((Data.Lhs.X.LoadEntry->Use & Data.ZPChanged) != 0) { Data.Lhs.X.Flags &= ~(LI_DIRECT | LI_RELOAD_Y); } } + /* Flag entries that can't be removed */ + SetDontRemoveEntryFlags (&Data); + /* Check the preconditions. If they aren't ok, reset the insn ** pointer to the pushax and start over. We will loose part of ** load tracking but at least a/x has probably lost between ** pushax and here and will be tracked again when restarting. */ if (!PreCondOk (&Data)) { + /* Unflag entries that can't be removed */ + ResetDontRemoveEntryFlags (&Data); I = Data.PushIndex; State = Initialize; break; @@ -2138,6 +2429,9 @@ unsigned OptStackOps (CodeSeg* S) /* Call the optimizer function */ Changes += Data.OptFunc->Func (&Data); + /* Unflag entries that can't be removed */ + ResetDontRemoveEntryFlags (&Data); + /* Since the function may have added or deleted entries, ** correct the index. */ From 53eb6a948db9285c0a8e7e62f42245d2dad2204e Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 3 Jan 2020 08:20:21 +0800 Subject: [PATCH 1331/2161] No more duplicated stores by Opt_tosshift which could result in worse optimizations. --- src/cc65/coptstop.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 46d600dba..b14b23195 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -1017,9 +1017,6 @@ static unsigned Opt_tosshift (StackOpData* D, const char* Name) { CodeEntry* X; - /* Store the value into the zeropage instead of pushing it */ - ReplacePushByStore (D); - /* If the lhs is direct (but not stack relative), we can just reload the ** data later. */ From 2220c58f51d74cfd82d065376ea856a3c5e543cf Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 3 Jan 2020 08:20:28 +0800 Subject: [PATCH 1332/2161] If the previous insn may be skipped, we cannot simply predict the output values of the registers. --- src/cc65/codeseg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 58586affd..f2e0faf15 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -1560,9 +1560,9 @@ void CS_GenRegInfo (CodeSeg* S) /* If this insn is a branch on zero flag, we may have more info on ** register contents for one of both flow directions, but only if - ** there is a previous instruction. + ** we've gone through a previous instruction. */ - if ((E->Info & OF_ZBRA) != 0 && (P = CS_GetPrevEntry (S, I)) != 0) { + if (LabelCount == 0 && (E->Info & OF_ZBRA) != 0 && (P = CS_GetPrevEntry (S, I)) != 0) { /* Get the branch condition */ bc_t BC = GetBranchCond (E->OPC); From 8a166ac82fa790c4607ed326bddc1e97b3ed5a5c Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 11 Feb 2020 18:28:38 +0800 Subject: [PATCH 1333/2161] Fixed register usage tracking interfered by CE_SetArg. --- src/cc65/codeent.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index 51f5f1378..7dd90833b 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -360,6 +360,10 @@ void CE_SetArg (CodeEntry* E, const char* Arg) /* Assign the new one */ E->Arg = GetArgCopy (Arg); + + /* Update the Use and Chg in E */ + const OPCDesc* D = GetOPCDesc (E->OPC); + SetUseChgInfo (E, D); } From e9307ce58e04aff2322adbf2f245abcdb2eeace6 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 22 Jun 2020 08:16:51 +0800 Subject: [PATCH 1334/2161] Moved test/ref/cc65141011.c to test/val/cc65141011.c. --- test/{ref => val}/cc65141011.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{ref => val}/cc65141011.c (100%) diff --git a/test/ref/cc65141011.c b/test/val/cc65141011.c similarity index 100% rename from test/ref/cc65141011.c rename to test/val/cc65141011.c From 76091b96d4100137d8f16f25577834fc28df319c Mon Sep 17 00:00:00 2001 From: Dirk Jagdmann <doj@cubic.org> Date: Tue, 16 Jun 2020 22:10:39 -0700 Subject: [PATCH 1335/2161] C64 Kerberos extended memory driver --- libsrc/c64/emd/c64-kerberos.s | 280 ++++++++++++++++++++++++++++++++++ testcode/lib/em-test.c | 24 ++- 2 files changed, 296 insertions(+), 8 deletions(-) create mode 100644 libsrc/c64/emd/c64-kerberos.s diff --git a/libsrc/c64/emd/c64-kerberos.s b/libsrc/c64/emd/c64-kerberos.s new file mode 100644 index 000000000..be385ef28 --- /dev/null +++ b/libsrc/c64/emd/c64-kerberos.s @@ -0,0 +1,280 @@ +; Extended Memory Driver for the Kerberos MIDI interface. +; http://www.frank-buss.de/kerberos/ +; based on the code for RamCart 64/128KB cartridge. +; 2020-06-16 Dirk Jagdmann <doj@cubic.org> + + .include "zeropage.inc" + .include "em-kernel.inc" + .include "em-error.inc" + + .macpack generic + .macpack module + +; ------------------------------------------------------------------------ +; Header. Includes jump table + + module_header _c64_kerberos_emd + +; Driver signature + + .byte $65, $6d, $64 ; "emd" + .byte EMD_API_VERSION ; EM API version number + +; Library reference + + .addr $0000 + +; Jump table + + .addr INSTALL + .addr UNINSTALL + .addr PAGECOUNT + .addr MAP + .addr USE + .addr COMMIT + .addr COPYFROM + .addr COPYTO + +; ------------------------------------------------------------------------ +; Constants + +RAMC_WINDOW = $DF00 ; Address of Kerberos SRAM +RAMC_PAGE_LO = $DE3E ; Page register low +RAMC_PAGE_HI = $DE3F ; Page register high + +.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 EM_ERR_xx code in a/x. +; + +INSTALL: + ;; write $55 into first page + lda #0 + sta RAMC_PAGE_LO + sta RAMC_PAGE_HI + lda #$55 + sta RAMC_WINDOW + + ;; write $AA into second page + lda #1 + sta RAMC_PAGE_LO + sta RAMC_PAGE_HI + lda #$AA + sta RAMC_WINDOW + + ;; check $55 in first page + lda #0 + sta RAMC_PAGE_LO + sta RAMC_PAGE_HI + lda RAMC_WINDOW + cmp #$55 + bne @notpresent + + ;; check $AA in first page + lda #1 + sta RAMC_PAGE_LO + sta RAMC_PAGE_HI + lda RAMC_WINDOW + cmp #$AA + bne @notpresent + + lda #<EM_ERR_OK + ldx #>EM_ERR_OK + rts + +@notpresent: + lda #<EM_ERR_NO_DEVICE + ldx #>EM_ERR_NO_DEVICE + ; use rts from UNINSTALL below + +; ------------------------------------------------------------------------ +; UNINSTALL routine. Is called before the driver is removed from memory. +; Can do cleanup or whatever. Must not return anything. +; + +UNINSTALL: + rts + +; ------------------------------------------------------------------------ +; PAGECOUNT: Return the total number of available pages in a/x. +; + +PAGECOUNT: + lda #0 + ldx #2 + rts + +; ------------------------------------------------------------------------ +; USE: Tell the driver that the window is now associated with a given page. +; The Kerberos cartridge does not copy but actually map the window, so USE is +; identical to MAP. + +USE = MAP + +; ------------------------------------------------------------------------ +; MAP: Map the page in a/x into memory and return a pointer to the page in +; a/x. The contents of the currently mapped page (if any) may be discarded +; by the driver. +; + +MAP: sta RAMC_PAGE_LO + txa + and #1 + sta RAMC_PAGE_HI + lda #<RAMC_WINDOW + ldx #>RAMC_WINDOW + +; Use the RTS from COMMIT below to save a precious byte of storage + +; ------------------------------------------------------------------------ +; COMMIT: Commit changes in the memory window to extended storage. + +COMMIT: rts + +; ------------------------------------------------------------------------ +; COPYFROM: Copy from extended into linear memory. A pointer to a structure +; describing the request is passed in a/x. +; The function must not return anything. +; + +COPYFROM: + jsr setup + +; Setup is: +; +; - ptr1 contains the struct pointer +; - ptr2 contains the linear memory buffer +; - ptr3 contains -(count-1) +; - tmp1 contains the low page register value +; - tmp2 contains the high page register value +; - X contains the page offset +; - Y contains zero + + jmp @L5 + +@L1: lda RAMC_WINDOW,x + sta (ptr2),y + iny + bne @L2 + inc ptr2+1 +@L2: inx + beq @L4 + +; Bump count and repeat + +@L3: inc ptr3 + bne @L1 + inc ptr3+1 + bne @L1 + rts + +; Bump page register + +@L4: inc tmp1 + bne @L5 + inc tmp2 +@L5: lda tmp1 + sta RAMC_PAGE_LO + lda tmp2 + sta RAMC_PAGE_HI + jmp @L3 + +; ------------------------------------------------------------------------ +; COPYTO: Copy from linear into extended memory. A pointer to a structure +; describing the request is passed in a/x. +; The function must not return anything. +; + +COPYTO: + jsr setup + +; Setup is: +; +; - ptr1 contains the struct pointer +; - ptr2 contains the linear memory buffer +; - ptr3 contains -(count-1) +; - tmp1 contains the low page register value +; - tmp2 contains the high page register value +; - X contains the page offset +; - Y contains zero + + jmp @L5 + +@L1: lda (ptr2),y + sta RAMC_WINDOW,x + iny + bne @L2 + inc ptr2+1 +@L2: inx + beq @L4 + +; Bump count and repeat + +@L3: inc ptr3 + bne @L1 + inc ptr3+1 + bne @L1 + rts + +; Bump page register + +@L4: inc tmp1 + bne @L5 + inc tmp2 +@L5: lda tmp1 + sta RAMC_PAGE_LO + lda tmp2 + sta RAMC_PAGE_HI + jmp @L3 + +; ------------------------------------------------------------------------ +; Helper function for COPYFROM and COPYTO: Store the pointer to the request +; structure and prepare data for the copy + +setup: sta ptr1 + stx ptr1+1 ; Save passed pointer + +; Get the page number from the struct and adjust it so that it may be used +; with the hardware. That is: lower 6 bits in tmp1, high bits in tmp2. + + ldy #EM_COPY::PAGE+1 + lda (ptr1),y + sta tmp2 + dey + lda (ptr1),y + sta tmp1 + +; Get the buffer pointer into ptr2 + + ldy #EM_COPY::BUF + lda (ptr1),y + sta ptr2 + iny + lda (ptr1),y + sta ptr2+1 + +; Get the count, calculate -(count-1) and store it into ptr3 + + ldy #EM_COPY::COUNT + lda (ptr1),y + eor #$FF + sta ptr3 + iny + lda (ptr1),y + eor #$FF + sta ptr3+1 + +; Get the page offset into X and clear Y + + ldy #EM_COPY::OFFS + lda (ptr1),y + tax + ldy #$00 + +; Done + + rts diff --git a/testcode/lib/em-test.c b/testcode/lib/em-test.c index ecee6608c..d71045f7a 100644 --- a/testcode/lib/em-test.c +++ b/testcode/lib/em-test.c @@ -12,16 +12,12 @@ #define BUF_SIZE (PAGE_SIZE + PAGE_SIZE/2) static unsigned buf[BUF_SIZE]; - - static void cleanup (void) /* Remove the driver on exit */ { em_unload (); } - - static void fill (register unsigned* page, register unsigned char count, register unsigned num) { register unsigned char i; @@ -30,8 +26,6 @@ static void fill (register unsigned* page, register unsigned char count, registe } } - - static void cmp (unsigned page, register const unsigned* buf, register unsigned char count, register unsigned num) { @@ -49,6 +43,20 @@ static void cmp (unsigned page, register const unsigned* buf, } } +static const char* em_error(int e) +{ + switch(e) + { + case EM_ERR_OK: return "ok"; + case EM_ERR_NO_DRIVER: return "no driver"; + case EM_ERR_CANNOT_LOAD: return "cannot load"; + case EM_ERR_INV_DRIVER: return "invalid driver"; + case EM_ERR_NO_DEVICE: return "no device"; + case EM_ERR_INSTALLED: return "already installed"; + } + return "unknown"; +} + typedef struct emd_test_s { char key; char *displayname; @@ -88,6 +96,7 @@ static emd_test_t drivers[] = { { '7', "C128 VDC (in C64 mode)", "c64-vdc.emd" }, { '8', "C64DTV himem", "dtv-himem.emd" }, { '9', "65816 extra banks", "c64-65816.emd" }, + { 'k', "Kerberos", "c64-kerberos.emd" }, #endif #if defined(__C128__) @@ -142,7 +151,7 @@ int main (void) clrscr (); Res = em_load_driver (drivers[valid_key].drivername); if (Res != EM_ERR_OK) { - cprintf ("Error in em_load_driver: %u\r\n", Res); + cprintf ("Error in em_load_driver: %u\r\n%s\r\n", Res, em_error(Res)); cprintf ("os: %u, %s\r\n", _oserror, _stroserror (_oserror)); #ifdef __ATARI__ cgetc (); @@ -263,5 +272,4 @@ int main (void) #endif return 0; - } From cb2676665111d7b521747d6998570ab705417129 Mon Sep 17 00:00:00 2001 From: Dirk Jagdmann <doj@cubic.org> Date: Wed, 17 Jun 2020 08:56:07 -0700 Subject: [PATCH 1336/2161] add C64 documentation --- doc/c64.sgml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/c64.sgml b/doc/c64.sgml index 7cd9b2d81..5ad89f9da 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -337,6 +337,10 @@ Note that the graphics drivers are incompatible with the Autodetects the amount of memory available (16 or 64K) and offers 64 or 256 pages of 256 bytes each. + <tag><tt/c64-kerberos.emd (c64_kerberos_emd)/</tag> + A driver for the Kerberos MIDI Cartridge. The cartridge has 256 + pages of 256 bytes for a total of 128KB. + <tag><tt/dtv-himem.emd (dtv_himem_emd)/</tag> A driver for the C64 D2TV (the second or PAL version). This driver offers indeed 7680 pages of 256 bytes each. From ba79b2db9ba4dffc173cf75287ce0f8934109717 Mon Sep 17 00:00:00 2001 From: Dirk Jagdmann <doj@cubic.org> Date: Wed, 17 Jun 2020 15:42:28 -0700 Subject: [PATCH 1337/2161] add kerberos em driver variable. --- include/c64.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/c64.h b/include/c64.h index b1cd2e2c4..ed82e5299 100644 --- a/include/c64.h +++ b/include/c64.h @@ -146,6 +146,7 @@ extern void c64_ram_emd[]; extern void c64_ramcart_emd[]; extern void c64_reu_emd[]; extern void c64_vdc_emd[]; +extern void c64_kerberos_emd[]; extern void dtv_himem_emd[]; extern void c64_hitjoy_joy[]; extern void c64_numpad_joy[]; From 070264acc47dc2e332267d8f177237231ff154e6 Mon Sep 17 00:00:00 2001 From: Dirk Jagdmann <doj@cubic.org> Date: Wed, 17 Jun 2020 15:42:37 -0700 Subject: [PATCH 1338/2161] remove tab characters. --- libsrc/c64/emd/c64-kerberos.s | 62 +++++++++++++++++------------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/libsrc/c64/emd/c64-kerberos.s b/libsrc/c64/emd/c64-kerberos.s index be385ef28..de21a7009 100644 --- a/libsrc/c64/emd/c64-kerberos.s +++ b/libsrc/c64/emd/c64-kerberos.s @@ -52,44 +52,44 @@ RAMC_PAGE_HI = $DE3F ; Page register high ; INSTALL: - ;; write $55 into first page - lda #0 - sta RAMC_PAGE_LO - sta RAMC_PAGE_HI - lda #$55 - sta RAMC_WINDOW + ;; write $55 into first page + lda #0 + sta RAMC_PAGE_LO + sta RAMC_PAGE_HI + lda #$55 + sta RAMC_WINDOW - ;; write $AA into second page - lda #1 - sta RAMC_PAGE_LO - sta RAMC_PAGE_HI - lda #$AA - sta RAMC_WINDOW + ;; write $AA into second page + lda #1 + sta RAMC_PAGE_LO + sta RAMC_PAGE_HI + lda #$AA + sta RAMC_WINDOW - ;; check $55 in first page - lda #0 - sta RAMC_PAGE_LO - sta RAMC_PAGE_HI - lda RAMC_WINDOW - cmp #$55 - bne @notpresent + ;; check $55 in first page + lda #0 + sta RAMC_PAGE_LO + sta RAMC_PAGE_HI + lda RAMC_WINDOW + cmp #$55 + bne @notpresent - ;; check $AA in first page - lda #1 - sta RAMC_PAGE_LO - sta RAMC_PAGE_HI - lda RAMC_WINDOW - cmp #$AA - bne @notpresent + ;; check $AA in first page + lda #1 + sta RAMC_PAGE_LO + sta RAMC_PAGE_HI + lda RAMC_WINDOW + cmp #$AA + bne @notpresent - lda #<EM_ERR_OK + lda #<EM_ERR_OK ldx #>EM_ERR_OK - rts + rts @notpresent: lda #<EM_ERR_NO_DEVICE ldx #>EM_ERR_NO_DEVICE - ; use rts from UNINSTALL below + ; use rts from UNINSTALL below ; ------------------------------------------------------------------------ ; UNINSTALL routine. Is called before the driver is removed from memory. @@ -122,8 +122,8 @@ USE = MAP ; MAP: sta RAMC_PAGE_LO - txa - and #1 + txa + and #1 sta RAMC_PAGE_HI lda #<RAMC_WINDOW ldx #>RAMC_WINDOW From def27ed4e2a35b2fe13b71f5bbac3e60ee2f04df Mon Sep 17 00:00:00 2001 From: Dirk Jagdmann <doj@cubic.org> Date: Wed, 17 Jun 2020 15:45:04 -0700 Subject: [PATCH 1339/2161] change whitespace --- testcode/lib/em-test.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/testcode/lib/em-test.c b/testcode/lib/em-test.c index d71045f7a..2da9138e1 100644 --- a/testcode/lib/em-test.c +++ b/testcode/lib/em-test.c @@ -43,10 +43,9 @@ static void cmp (unsigned page, register const unsigned* buf, } } -static const char* em_error(int e) +static const char* em_error (int e) { - switch(e) - { + switch (e) { case EM_ERR_OK: return "ok"; case EM_ERR_NO_DRIVER: return "no driver"; case EM_ERR_CANNOT_LOAD: return "cannot load"; From 9227b0ccaf6fe90ef5ea80a138a636ff97c9f0c5 Mon Sep 17 00:00:00 2001 From: Dirk Jagdmann <doj@cubic.org> Date: Wed, 17 Jun 2020 15:46:19 -0700 Subject: [PATCH 1340/2161] sort items --- doc/c64.sgml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/c64.sgml b/doc/c64.sgml index 5ad89f9da..e42c1f890 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -318,6 +318,10 @@ Note that the graphics drivers are incompatible with the A driver for the ISEPIC cartridge. This driver offers just 8 pages of 256 bytes each. Written and contributed by Marco van den Heuvel. + <tag><tt/c64-kerberos.emd (c64_kerberos_emd)/</tag> + A driver for the Kerberos MIDI Cartridge. The cartridge has 256 + pages of 256 bytes for a total of 128KB. + <tag><tt/c64-ram.emd (c64_ram_emd)/</tag> A driver for the hidden RAM below the I/O area and kernal ROM. Supports 47 256 byte pages. Please note that this driver is incompatible with any of the @@ -337,10 +341,6 @@ Note that the graphics drivers are incompatible with the Autodetects the amount of memory available (16 or 64K) and offers 64 or 256 pages of 256 bytes each. - <tag><tt/c64-kerberos.emd (c64_kerberos_emd)/</tag> - A driver for the Kerberos MIDI Cartridge. The cartridge has 256 - pages of 256 bytes for a total of 128KB. - <tag><tt/dtv-himem.emd (dtv_himem_emd)/</tag> A driver for the C64 D2TV (the second or PAL version). This driver offers indeed 7680 pages of 256 bytes each. From 6465c3b6874e66029fc664b2c8bde8a8fded9c6b Mon Sep 17 00:00:00 2001 From: Dirk Jagdmann <doj@cubic.org> Date: Wed, 17 Jun 2020 15:50:54 -0700 Subject: [PATCH 1341/2161] change order of declarations. --- include/c64.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/c64.h b/include/c64.h index ed82e5299..afe47ece6 100644 --- a/include/c64.h +++ b/include/c64.h @@ -142,11 +142,11 @@ extern void c64_c256k_emd[]; extern void c64_dqbb_emd[]; extern void c64_georam_emd[]; extern void c64_isepic_emd[]; +extern void c64_kerberos_emd[]; extern void c64_ram_emd[]; extern void c64_ramcart_emd[]; extern void c64_reu_emd[]; extern void c64_vdc_emd[]; -extern void c64_kerberos_emd[]; extern void dtv_himem_emd[]; extern void c64_hitjoy_joy[]; extern void c64_numpad_joy[]; From 3cbe485b94649b80ef6a291af2fa49cf19eb05fc Mon Sep 17 00:00:00 2001 From: Dirk Jagdmann <doj@cubic.org> Date: Sun, 21 Jun 2020 09:05:17 -0700 Subject: [PATCH 1342/2161] fix description of Kerberos memory --- doc/c64.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/c64.sgml b/doc/c64.sgml index e42c1f890..7e00f3b93 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -319,7 +319,7 @@ Note that the graphics drivers are incompatible with the bytes each. Written and contributed by Marco van den Heuvel. <tag><tt/c64-kerberos.emd (c64_kerberos_emd)/</tag> - A driver for the Kerberos MIDI Cartridge. The cartridge has 256 + A driver for the Kerberos MIDI Cartridge. The cartridge has 512 pages of 256 bytes for a total of 128KB. <tag><tt/c64-ram.emd (c64_ram_emd)/</tag> From aaecf3cfec8d95d6d32d66d2a77acebb45aa9a9a Mon Sep 17 00:00:00 2001 From: Dirk Jagdmann <doj@cubic.org> Date: Sun, 21 Jun 2020 10:15:23 -0700 Subject: [PATCH 1343/2161] replace JMP with BEQ to save 1 byte. --- libsrc/c64/emd/c64-kerberos.s | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libsrc/c64/emd/c64-kerberos.s b/libsrc/c64/emd/c64-kerberos.s index de21a7009..30183362f 100644 --- a/libsrc/c64/emd/c64-kerberos.s +++ b/libsrc/c64/emd/c64-kerberos.s @@ -104,8 +104,8 @@ UNINSTALL: ; PAGECOUNT: - lda #0 - ldx #2 + lda #<(128 * 1024 / 256) + ldx #>(128 * 1024 / 256) rts ; ------------------------------------------------------------------------ @@ -154,7 +154,7 @@ COPYFROM: ; - X contains the page offset ; - Y contains zero - jmp @L5 + beq @L5 ; will always branch, because setup ends with ldy #0 @L1: lda RAMC_WINDOW,x sta (ptr2),y @@ -202,7 +202,7 @@ COPYTO: ; - X contains the page offset ; - Y contains zero - jmp @L5 + beq @L5 ; will always branch, because setup ends with ldy #0 @L1: lda (ptr2),y sta RAMC_WINDOW,x From 6e6ce4e5eedfd9f3c0629fc4b069f9a21be47b41 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 23 Jun 2020 00:46:12 +0200 Subject: [PATCH 1344/2161] added various tests related to bug #1045 --- test/val/postdec-16-16.c | 86 ++++++++++++++++++++++++++++++++++++++++ test/val/postdec-16-8.c | 86 ++++++++++++++++++++++++++++++++++++++++ test/val/postdec-8-16.c | 86 ++++++++++++++++++++++++++++++++++++++++ test/val/postdec-8-8.c | 86 ++++++++++++++++++++++++++++++++++++++++ test/val/postinc-16-16.c | 86 ++++++++++++++++++++++++++++++++++++++++ test/val/postinc-16-8.c | 85 +++++++++++++++++++++++++++++++++++++++ test/val/postinc-8-16.c | 86 ++++++++++++++++++++++++++++++++++++++++ test/val/postinc-8-8.c | 86 ++++++++++++++++++++++++++++++++++++++++ test/val/predec-16-16.c | 86 ++++++++++++++++++++++++++++++++++++++++ test/val/predec-16-8.c | 86 ++++++++++++++++++++++++++++++++++++++++ test/val/predec-8-16.c | 86 ++++++++++++++++++++++++++++++++++++++++ test/val/predec-8-8.c | 86 ++++++++++++++++++++++++++++++++++++++++ test/val/preinc-16-16.c | 86 ++++++++++++++++++++++++++++++++++++++++ test/val/preinc-16-8.c | 86 ++++++++++++++++++++++++++++++++++++++++ test/val/preinc-8-16.c | 86 ++++++++++++++++++++++++++++++++++++++++ test/val/preinc-8-8.c | 86 ++++++++++++++++++++++++++++++++++++++++ 16 files changed, 1375 insertions(+) create mode 100644 test/val/postdec-16-16.c create mode 100644 test/val/postdec-16-8.c create mode 100644 test/val/postdec-8-16.c create mode 100644 test/val/postdec-8-8.c create mode 100644 test/val/postinc-16-16.c create mode 100644 test/val/postinc-16-8.c create mode 100644 test/val/postinc-8-16.c create mode 100644 test/val/postinc-8-8.c create mode 100644 test/val/predec-16-16.c create mode 100644 test/val/predec-16-8.c create mode 100644 test/val/predec-8-16.c create mode 100644 test/val/predec-8-8.c create mode 100644 test/val/preinc-16-16.c create mode 100644 test/val/preinc-16-8.c create mode 100644 test/val/preinc-8-16.c create mode 100644 test/val/preinc-8-8.c diff --git a/test/val/postdec-16-16.c b/test/val/postdec-16-16.c new file mode 100644 index 000000000..e55b5765f --- /dev/null +++ b/test/val/postdec-16-16.c @@ -0,0 +1,86 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef __C64__ +#include <conio.h> +#endif + +/* apparently we dont trigger the bug when not using absolute addresses? */ +#ifdef __C64__ +#define TARGETMEM 0x4c8 +#define SOURCEMEM 0x702 +#elif __SIM6502__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#elif __SIM65C02__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#else +static unsigned char mem[0x10]; +#define TARGETMEM &mem[0] +#define SOURCEMEM &mem[8] +#endif + +/* do not put at pos. 1, and 1 byte apart - so we can eventually notice + off-by-one errors */ +static unsigned short u16w = 3; +static unsigned short u16r = 5; + +static unsigned char target[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; +static unsigned char source[8] = { 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; +static unsigned char expect[8] = { 0x0, 0x1, 0xc, 0xd, 0x4, 0x5, 0x6, 0x7 }; + +static unsigned char i; +static unsigned char err = EXIT_SUCCESS; + +void test1(void) +{ + ((unsigned char*)TARGETMEM)[u16w--] = ((unsigned char*)SOURCEMEM)[u16r--]; +} + +void dotest(void) +{ + + memcpy(TARGETMEM, target, 8); + memcpy(SOURCEMEM, source, 8); + + test1(); + + memcpy(target, TARGETMEM, 8); + memcpy(source, SOURCEMEM, 8); +#ifdef __C64__ + clrscr(); +#endif + printf("source:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", source[i]); + } + printf("\n\rtarget:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", target[i]); + } + printf("\n\r"); + + printf("u16w: %d\n\r", u16w); + printf("u16r: %d\n\r", u16r); + +} + +int main(void) +{ + dotest(); + dotest(); + if (memcmp(target, expect, 8) != 0) { + printf("buffer data error\n\r"); + err = EXIT_FAILURE; + } + if (u16w != 1) { + err = EXIT_FAILURE; + } + if (u16r != 3) { + err = EXIT_FAILURE; + } + printf("return: %d\n\r", err); + return err; +} diff --git a/test/val/postdec-16-8.c b/test/val/postdec-16-8.c new file mode 100644 index 000000000..76a64d769 --- /dev/null +++ b/test/val/postdec-16-8.c @@ -0,0 +1,86 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef __C64__ +#include <conio.h> +#endif + +/* apparently we dont trigger the bug when not using absolute addresses? */ +#ifdef __C64__ +#define TARGETMEM 0x4c8 +#define SOURCEMEM 0x702 +#elif __SIM6502__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#elif __SIM65C02__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#else +static unsigned char mem[0x10]; +#define TARGETMEM &mem[0] +#define SOURCEMEM &mem[8] +#endif + +/* do not put at pos. 1, and 1 byte apart - so we can eventually notice + off-by-one errors */ +static unsigned short u16w = 3; +static unsigned char u8r = 5; + +static unsigned char target[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; +static unsigned char source[8] = { 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; +static unsigned char expect[8] = { 0x0, 0x1, 0xc, 0xd, 0x4, 0x5, 0x6, 0x7 }; + +static unsigned char i; +static unsigned char err = EXIT_SUCCESS; + +void test1(void) +{ + ((unsigned char*)TARGETMEM)[u16w--] = ((unsigned char*)SOURCEMEM)[u8r--]; +} + +void dotest(void) +{ + + memcpy(TARGETMEM, target, 8); + memcpy(SOURCEMEM, source, 8); + + test1(); + + memcpy(target, TARGETMEM, 8); + memcpy(source, SOURCEMEM, 8); +#ifdef __C64__ + clrscr(); +#endif + printf("source:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", source[i]); + } + printf("\n\rtarget:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", target[i]); + } + printf("\n\r"); + + printf("u16w: %d\n\r", u16w); + printf("u8r: %d\n\r", u8r); + +} + +int main(void) +{ + dotest(); + dotest(); + if (memcmp(target, expect, 8) != 0) { + printf("buffer data error\n\r"); + err = EXIT_FAILURE; + } + if (u16w != 1) { + err = EXIT_FAILURE; + } + if (u8r != 3) { + err = EXIT_FAILURE; + } + printf("return: %d\n\r", err); + return err; +} diff --git a/test/val/postdec-8-16.c b/test/val/postdec-8-16.c new file mode 100644 index 000000000..f7716ae89 --- /dev/null +++ b/test/val/postdec-8-16.c @@ -0,0 +1,86 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef __C64__ +#include <conio.h> +#endif + +/* apparently we dont trigger the bug when not using absolute addresses? */ +#ifdef __C64__ +#define TARGETMEM 0x4c8 +#define SOURCEMEM 0x702 +#elif __SIM6502__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#elif __SIM65C02__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#else +static unsigned char mem[0x10]; +#define TARGETMEM &mem[0] +#define SOURCEMEM &mem[8] +#endif + +/* do not put at pos. 1, and 1 byte apart - so we can eventually notice + off-by-one errors */ +static unsigned char u8w = 3; +static unsigned short u16r = 5; + +static unsigned char target[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; +static unsigned char source[8] = { 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; +static unsigned char expect[8] = { 0x0, 0x1, 0xc, 0xd, 0x4, 0x5, 0x6, 0x7 }; + +static unsigned char i; +static unsigned char err = EXIT_SUCCESS; + +void test1(void) +{ + ((unsigned char*)TARGETMEM)[u8w--] = ((unsigned char*)SOURCEMEM)[u16r--]; +} + +void dotest(void) +{ + + memcpy(TARGETMEM, target, 8); + memcpy(SOURCEMEM, source, 8); + + test1(); + + memcpy(target, TARGETMEM, 8); + memcpy(source, SOURCEMEM, 8); +#ifdef __C64__ + clrscr(); +#endif + printf("source:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", source[i]); + } + printf("\n\rtarget:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", target[i]); + } + printf("\n\r"); + + printf("u8w: %d\n\r", u8w); + printf("u16r: %d\n\r", u16r); + +} + +int main(void) +{ + dotest(); + dotest(); + if (memcmp(target, expect, 8) != 0) { + printf("buffer data error\n\r"); + err = EXIT_FAILURE; + } + if (u8w != 1) { + err = EXIT_FAILURE; + } + if (u16r != 3) { + err = EXIT_FAILURE; + } + printf("return: %d\n\r", err); + return err; +} diff --git a/test/val/postdec-8-8.c b/test/val/postdec-8-8.c new file mode 100644 index 000000000..b620c46dc --- /dev/null +++ b/test/val/postdec-8-8.c @@ -0,0 +1,86 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef __C64__ +#include <conio.h> +#endif + +/* apparently we dont trigger the bug when not using absolute addresses? */ +#ifdef __C64__ +#define TARGETMEM 0x4c8 +#define SOURCEMEM 0x702 +#elif __SIM6502__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#elif __SIM65C02__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#else +static unsigned char mem[0x10]; +#define TARGETMEM &mem[0] +#define SOURCEMEM &mem[8] +#endif + +/* do not put at pos. 1, and 1 byte apart - so we can eventually notice + off-by-one errors */ +static unsigned char u8w = 3; +static unsigned char u8r = 5; + +static unsigned char target[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; +static unsigned char source[8] = { 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; +static unsigned char expect[8] = { 0x0, 0x1, 0xc, 0xd, 0x4, 0x5, 0x6, 0x7 }; + +static unsigned char i; +static unsigned char err = EXIT_SUCCESS; + +void test1(void) +{ + ((unsigned char*)TARGETMEM)[u8w--] = ((unsigned char*)SOURCEMEM)[u8r--]; +} + +void dotest(void) +{ + + memcpy(TARGETMEM, target, 8); + memcpy(SOURCEMEM, source, 8); + + test1(); + + memcpy(target, TARGETMEM, 8); + memcpy(source, SOURCEMEM, 8); +#ifdef __C64__ + clrscr(); +#endif + printf("source:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", source[i]); + } + printf("\n\rtarget:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", target[i]); + } + printf("\n\r"); + + printf("u8w: %d\n\r", u8w); + printf("u8r: %d\n\r", u8r); + +} + +int main(void) +{ + dotest(); + dotest(); + if (memcmp(target, expect, 8) != 0) { + printf("buffer data error\n\r"); + err = EXIT_FAILURE; + } + if (u8w != 1) { + err = EXIT_FAILURE; + } + if (u8r != 3) { + err = EXIT_FAILURE; + } + printf("return: %d\n\r", err); + return err; +} diff --git a/test/val/postinc-16-16.c b/test/val/postinc-16-16.c new file mode 100644 index 000000000..286e0364b --- /dev/null +++ b/test/val/postinc-16-16.c @@ -0,0 +1,86 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef __C64__ +#include <conio.h> +#endif + +/* apparently we dont trigger the bug when not using absolute addresses? */ +#ifdef __C64__ +#define TARGETMEM 0x4c8 +#define SOURCEMEM 0x702 +#elif __SIM6502__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#elif __SIM65C02__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#else +static unsigned char mem[0x10]; +#define TARGETMEM &mem[0] +#define SOURCEMEM &mem[8] +#endif + +/* do not put at pos. 1, and 1 byte apart - so we can eventually notice + off-by-one errors */ +static unsigned short u16w = 1; +static unsigned short u16r = 3; + +static unsigned char target[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; +static unsigned char source[8] = { 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; +static unsigned char expect[8] = { 0x0, 0xb, 0xc, 0x3, 0x4, 0x5, 0x6, 0x7 }; + +static unsigned char i; +static unsigned char err = EXIT_SUCCESS; + +void test1(void) +{ + ((unsigned char*)TARGETMEM)[u16w++] = ((unsigned char*)SOURCEMEM)[u16r++]; +} + +void dotest(void) +{ + + memcpy(TARGETMEM, target, 8); + memcpy(SOURCEMEM, source, 8); + + test1(); + + memcpy(target, TARGETMEM, 8); + memcpy(source, SOURCEMEM, 8); +#ifdef __C64__ + clrscr(); +#endif + printf("source:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", source[i]); + } + printf("\n\rtarget:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", target[i]); + } + printf("\n\r"); + + printf("u16w: %d\n\r", u16w); + printf("u16r: %d\n\r", u16r); + +} + +int main(void) +{ + dotest(); + dotest(); + if (memcmp(target, expect, 8) != 0) { + printf("buffer data error\n\r"); + err = EXIT_FAILURE; + } + if (u16w != 3) { + err = EXIT_FAILURE; + } + if (u16r != 5) { + err = EXIT_FAILURE; + } + printf("return: %d\n\r", err); + return err; +} diff --git a/test/val/postinc-16-8.c b/test/val/postinc-16-8.c new file mode 100644 index 000000000..dd0a03d6c --- /dev/null +++ b/test/val/postinc-16-8.c @@ -0,0 +1,85 @@ + +#include <stdio.h> +#include <string.h> +#ifdef __C64__ +#include <conio.h> +#endif + +/* apparently we dont trigger the bug when not using absolute addresses? */ +#ifdef __C64__ +#define TARGETMEM 0x4c8 +#define SOURCEMEM 0x702 +#elif __SIM6502__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#elif __SIM65C02__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#else +static unsigned char mem[0x10]; +#define TARGETMEM &mem[0] +#define SOURCEMEM &mem[8] +#endif + +/* do not put at pos. 1, and 1 byte apart - so we can eventually notice + off-by-one errors */ +static unsigned short u16w = 1; +static unsigned char u8r = 3; + +static unsigned char target[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; +static unsigned char source[8] = { 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; +static unsigned char expect[8] = { 0x0, 0xb, 0xc, 0x3, 0x4, 0x5, 0x6, 0x7 }; + +static unsigned char i; +static unsigned char err = 0; + +void test1(void) +{ + ((unsigned char*)TARGETMEM)[u16w++] = ((unsigned char*)SOURCEMEM)[u8r++]; +} + +void dotest(void) +{ + + memcpy(TARGETMEM, target, 8); + memcpy(SOURCEMEM, source, 8); + + test1(); + + memcpy(target, TARGETMEM, 8); + memcpy(source, SOURCEMEM, 8); +#ifdef __C64__ + clrscr(); +#endif + printf("source:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", source[i]); + } + printf("\n\rtarget:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", target[i]); + } + printf("\n\r"); + + printf("u16w: %d\n\r", u16w); + printf("u8r: %d\n\r", u8r); + +} + +int main(void) +{ + dotest(); + dotest(); + if (memcmp(target, expect, 8) != 0) { + printf("buffer data error\n\r"); + err = 1; + } + if (u16w != 3) { + err = 1; + } + if (u8r != 5) { + err = 1; + } + printf("return: %d\n\r", err); + return err; +} diff --git a/test/val/postinc-8-16.c b/test/val/postinc-8-16.c new file mode 100644 index 000000000..57e934ced --- /dev/null +++ b/test/val/postinc-8-16.c @@ -0,0 +1,86 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef __C64__ +#include <conio.h> +#endif + +/* apparently we dont trigger the bug when not using absolute addresses? */ +#ifdef __C64__ +#define TARGETMEM 0x4c8 +#define SOURCEMEM 0x702 +#elif __SIM6502__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#elif __SIM65C02__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#else +static unsigned char mem[0x10]; +#define TARGETMEM &mem[0] +#define SOURCEMEM &mem[8] +#endif + +/* do not put at pos. 1, and 1 byte apart - so we can eventually notice + off-by-one errors */ +static unsigned char u8w = 1; +static unsigned short u16r = 3; + +static unsigned char target[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; +static unsigned char source[8] = { 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; +static unsigned char expect[8] = { 0x0, 0xb, 0xc, 0x3, 0x4, 0x5, 0x6, 0x7 }; + +static unsigned char i; +static unsigned char err = EXIT_SUCCESS; + +void test1(void) +{ + ((unsigned char*)TARGETMEM)[u8w++] = ((unsigned char*)SOURCEMEM)[u16r++]; +} + +void dotest(void) +{ + + memcpy(TARGETMEM, target, 8); + memcpy(SOURCEMEM, source, 8); + + test1(); + + memcpy(target, TARGETMEM, 8); + memcpy(source, SOURCEMEM, 8); +#ifdef __C64__ + clrscr(); +#endif + printf("source:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", source[i]); + } + printf("\n\rtarget:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", target[i]); + } + printf("\n\r"); + + printf("u8w: %d\n\r", u8w); + printf("u16r: %d\n\r", u16r); + +} + +int main(void) +{ + dotest(); + dotest(); + if (memcmp(target, expect, 8) != 0) { + printf("buffer data error\n\r"); + err = EXIT_FAILURE; + } + if (u8w != 3) { + err = EXIT_FAILURE; + } + if (u16r != 5) { + err = EXIT_FAILURE; + } + printf("return: %d\n\r", err); + return err; +} diff --git a/test/val/postinc-8-8.c b/test/val/postinc-8-8.c new file mode 100644 index 000000000..b168af8df --- /dev/null +++ b/test/val/postinc-8-8.c @@ -0,0 +1,86 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef __C64__ +#include <conio.h> +#endif + +/* apparently we dont trigger the bug when not using absolute addresses? */ +#ifdef __C64__ +#define TARGETMEM 0x4c8 +#define SOURCEMEM 0x702 +#elif __SIM6502__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#elif __SIM65C02__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#else +static unsigned char mem[0x10]; +#define TARGETMEM &mem[0] +#define SOURCEMEM &mem[8] +#endif + +/* do not put at pos. 1, and 1 byte apart - so we can eventually notice + off-by-one errors */ +static unsigned char u8w = 1; +static unsigned char u8r = 3; + +static unsigned char target[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; +static unsigned char source[8] = { 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; +static unsigned char expect[8] = { 0x0, 0xb, 0xc, 0x3, 0x4, 0x5, 0x6, 0x7 }; + +static unsigned char i; +static unsigned char err = EXIT_SUCCESS; + +void test1(void) +{ + ((unsigned char*)TARGETMEM)[u8w++] = ((unsigned char*)SOURCEMEM)[u8r++]; +} + +void dotest(void) +{ + + memcpy(TARGETMEM, target, 8); + memcpy(SOURCEMEM, source, 8); + + test1(); + + memcpy(target, TARGETMEM, 8); + memcpy(source, SOURCEMEM, 8); +#ifdef __C64__ + clrscr(); +#endif + printf("source:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", source[i]); + } + printf("\n\rtarget:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", target[i]); + } + printf("\n\r"); + + printf("u8w: %d\n\r", u8w); + printf("u8r: %d\n\r", u8r); + +} + +int main(void) +{ + dotest(); + dotest(); + if (memcmp(target, expect, 8) != 0) { + printf("buffer data error\n\r"); + err = EXIT_FAILURE; + } + if (u8w != 3) { + err = EXIT_FAILURE; + } + if (u8r != 5) { + err = EXIT_FAILURE; + } + printf("return: %d\n\r", err); + return err; +} diff --git a/test/val/predec-16-16.c b/test/val/predec-16-16.c new file mode 100644 index 000000000..7d70b1208 --- /dev/null +++ b/test/val/predec-16-16.c @@ -0,0 +1,86 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef __C64__ +#include <conio.h> +#endif + +/* apparently we dont trigger the bug when not using absolute addresses? */ +#ifdef __C64__ +#define TARGETMEM 0x4c8 +#define SOURCEMEM 0x702 +#elif __SIM6502__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#elif __SIM65C02__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#else +static unsigned char mem[0x10]; +#define TARGETMEM &mem[0] +#define SOURCEMEM &mem[8] +#endif + +/* do not put at pos. 1, and 1 byte apart - so we can eventually notice + off-by-one errors */ +static unsigned short u16w = 3; +static unsigned short u16r = 5; + +static unsigned char target[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; +static unsigned char source[8] = { 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; +static unsigned char expect[8] = { 0x0, 0xb, 0xc, 0x3, 0x4, 0x5, 0x6, 0x7 }; + +static unsigned char i; +static unsigned char err = EXIT_SUCCESS; + +void test1(void) +{ + ((unsigned char*)TARGETMEM)[--u16w] = ((unsigned char*)SOURCEMEM)[--u16r]; +} + +void dotest(void) +{ + + memcpy(TARGETMEM, target, 8); + memcpy(SOURCEMEM, source, 8); + + test1(); + + memcpy(target, TARGETMEM, 8); + memcpy(source, SOURCEMEM, 8); +#ifdef __C64__ + clrscr(); +#endif + printf("source:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", source[i]); + } + printf("\n\rtarget:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", target[i]); + } + printf("\n\r"); + + printf("u16w: %d\n\r", u16w); + printf("u16r: %d\n\r", u16r); + +} + +int main(void) +{ + dotest(); + dotest(); + if (memcmp(target, expect, 8) != 0) { + printf("buffer data error\n\r"); + err = EXIT_FAILURE; + } + if (u16w != 1) { + err = EXIT_FAILURE; + } + if (u16r != 3) { + err = EXIT_FAILURE; + } + printf("return: %d\n\r", err); + return err; +} diff --git a/test/val/predec-16-8.c b/test/val/predec-16-8.c new file mode 100644 index 000000000..69a0a3e28 --- /dev/null +++ b/test/val/predec-16-8.c @@ -0,0 +1,86 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef __C64__ +#include <conio.h> +#endif + +/* apparently we dont trigger the bug when not using absolute addresses? */ +#ifdef __C64__ +#define TARGETMEM 0x4c8 +#define SOURCEMEM 0x702 +#elif __SIM6502__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#elif __SIM65C02__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#else +static unsigned char mem[0x10]; +#define TARGETMEM &mem[0] +#define SOURCEMEM &mem[8] +#endif + +/* do not put at pos. 1, and 1 byte apart - so we can eventually notice + off-by-one errors */ +static unsigned short u16w = 3; +static unsigned char u8r = 5; + +static unsigned char target[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; +static unsigned char source[8] = { 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; +static unsigned char expect[8] = { 0x0, 0xb, 0xc, 0x3, 0x4, 0x5, 0x6, 0x7 }; + +static unsigned char i; +static unsigned char err = EXIT_SUCCESS; + +void test1(void) +{ + ((unsigned char*)TARGETMEM)[--u16w] = ((unsigned char*)SOURCEMEM)[--u8r]; +} + +void dotest(void) +{ + + memcpy(TARGETMEM, target, 8); + memcpy(SOURCEMEM, source, 8); + + test1(); + + memcpy(target, TARGETMEM, 8); + memcpy(source, SOURCEMEM, 8); +#ifdef __C64__ + clrscr(); +#endif + printf("source:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", source[i]); + } + printf("\n\rtarget:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", target[i]); + } + printf("\n\r"); + + printf("u16w: %d\n\r", u16w); + printf("u8r: %d\n\r", u8r); + +} + +int main(void) +{ + dotest(); + dotest(); + if (memcmp(target, expect, 8) != 0) { + printf("buffer data error\n\r"); + err = EXIT_FAILURE; + } + if (u16w != 1) { + err = EXIT_FAILURE; + } + if (u8r != 3) { + err = EXIT_FAILURE; + } + printf("return: %d\n\r", err); + return err; +} diff --git a/test/val/predec-8-16.c b/test/val/predec-8-16.c new file mode 100644 index 000000000..750312215 --- /dev/null +++ b/test/val/predec-8-16.c @@ -0,0 +1,86 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef __C64__ +#include <conio.h> +#endif + +/* apparently we dont trigger the bug when not using absolute addresses? */ +#ifdef __C64__ +#define TARGETMEM 0x4c8 +#define SOURCEMEM 0x702 +#elif __SIM6502__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#elif __SIM65C02__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#else +static unsigned char mem[0x10]; +#define TARGETMEM &mem[0] +#define SOURCEMEM &mem[8] +#endif + +/* do not put at pos. 1, and 1 byte apart - so we can eventually notice + off-by-one errors */ +static unsigned char u8w = 3; +static unsigned short u16r = 5; + +static unsigned char target[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; +static unsigned char source[8] = { 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; +static unsigned char expect[8] = { 0x0, 0xb, 0xc, 0x3, 0x4, 0x5, 0x6, 0x7 }; + +static unsigned char i; +static unsigned char err = EXIT_SUCCESS; + +void test1(void) +{ + ((unsigned char*)TARGETMEM)[--u8w] = ((unsigned char*)SOURCEMEM)[--u16r]; +} + +void dotest(void) +{ + + memcpy(TARGETMEM, target, 8); + memcpy(SOURCEMEM, source, 8); + + test1(); + + memcpy(target, TARGETMEM, 8); + memcpy(source, SOURCEMEM, 8); +#ifdef __C64__ + clrscr(); +#endif + printf("source:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", source[i]); + } + printf("\n\rtarget:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", target[i]); + } + printf("\n\r"); + + printf("u8w: %d\n\r", u8w); + printf("u16r: %d\n\r", u16r); + +} + +int main(void) +{ + dotest(); + dotest(); + if (memcmp(target, expect, 8) != 0) { + printf("buffer data error\n\r"); + err = EXIT_FAILURE; + } + if (u8w != 1) { + err = EXIT_FAILURE; + } + if (u16r != 3) { + err = EXIT_FAILURE; + } + printf("return: %d\n\r", err); + return err; +} diff --git a/test/val/predec-8-8.c b/test/val/predec-8-8.c new file mode 100644 index 000000000..d1069b39e --- /dev/null +++ b/test/val/predec-8-8.c @@ -0,0 +1,86 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef __C64__ +#include <conio.h> +#endif + +/* apparently we dont trigger the bug when not using absolute addresses? */ +#ifdef __C64__ +#define TARGETMEM 0x4c8 +#define SOURCEMEM 0x702 +#elif __SIM6502__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#elif __SIM65C02__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#else +static unsigned char mem[0x10]; +#define TARGETMEM &mem[0] +#define SOURCEMEM &mem[8] +#endif + +/* do not put at pos. 1, and 1 byte apart - so we can eventually notice + off-by-one errors */ +static unsigned char u8w = 3; +static unsigned char u8r = 5; + +static unsigned char target[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; +static unsigned char source[8] = { 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; +static unsigned char expect[8] = { 0x0, 0xb, 0xc, 0x3, 0x4, 0x5, 0x6, 0x7 }; + +static unsigned char i; +static unsigned char err = EXIT_SUCCESS; + +void test1(void) +{ + ((unsigned char*)TARGETMEM)[--u8w] = ((unsigned char*)SOURCEMEM)[--u8r]; +} + +void dotest(void) +{ + + memcpy(TARGETMEM, target, 8); + memcpy(SOURCEMEM, source, 8); + + test1(); + + memcpy(target, TARGETMEM, 8); + memcpy(source, SOURCEMEM, 8); +#ifdef __C64__ + clrscr(); +#endif + printf("source:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", source[i]); + } + printf("\n\rtarget:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", target[i]); + } + printf("\n\r"); + + printf("u8w: %d\n\r", u8w); + printf("u8r: %d\n\r", u8r); + +} + +int main(void) +{ + dotest(); + dotest(); + if (memcmp(target, expect, 8) != 0) { + printf("buffer data error\n\r"); + err = EXIT_FAILURE; + } + if (u8w != 1) { + err = EXIT_FAILURE; + } + if (u8r != 3) { + err = EXIT_FAILURE; + } + printf("return: %d\n\r", err); + return err; +} diff --git a/test/val/preinc-16-16.c b/test/val/preinc-16-16.c new file mode 100644 index 000000000..d9c6dbf62 --- /dev/null +++ b/test/val/preinc-16-16.c @@ -0,0 +1,86 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef __C64__ +#include <conio.h> +#endif + +/* apparently we dont trigger the bug when not using absolute addresses? */ +#ifdef __C64__ +#define TARGETMEM 0x4c8 +#define SOURCEMEM 0x702 +#elif __SIM6502__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#elif __SIM65C02__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#else +static unsigned char mem[0x10]; +#define TARGETMEM &mem[0] +#define SOURCEMEM &mem[8] +#endif + +/* do not put at pos. 1, and 1 byte apart - so we can eventually notice + off-by-one errors */ +static unsigned short u16w = 3; +static unsigned short u16r = 5; + +static unsigned char target[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; +static unsigned char source[8] = { 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; +static unsigned char expect[8] = { 0x0, 0x1, 0x2, 0x3, 0xe, 0xf, 0x6, 0x7 }; + +static unsigned char i; +static unsigned char err = EXIT_SUCCESS; + +void test1(void) +{ + ((unsigned char*)TARGETMEM)[++u16w] = ((unsigned char*)SOURCEMEM)[++u16r]; +} + +void dotest(void) +{ + + memcpy(TARGETMEM, target, 8); + memcpy(SOURCEMEM, source, 8); + + test1(); + + memcpy(target, TARGETMEM, 8); + memcpy(source, SOURCEMEM, 8); +#ifdef __C64__ + clrscr(); +#endif + printf("source:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", source[i]); + } + printf("\n\rtarget:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", target[i]); + } + printf("\n\r"); + + printf("u16w: %d\n\r", u16w); + printf("u16r: %d\n\r", u16r); + +} + +int main(void) +{ + dotest(); + dotest(); + if (memcmp(target, expect, 8) != 0) { + printf("buffer data error\n\r"); + err = EXIT_FAILURE; + } + if (u16w != 5) { + err = EXIT_FAILURE; + } + if (u16r != 7) { + err = EXIT_FAILURE; + } + printf("return: %d\n\r", err); + return err; +} diff --git a/test/val/preinc-16-8.c b/test/val/preinc-16-8.c new file mode 100644 index 000000000..97a5dd306 --- /dev/null +++ b/test/val/preinc-16-8.c @@ -0,0 +1,86 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef __C64__ +#include <conio.h> +#endif + +/* apparently we dont trigger the bug when not using absolute addresses? */ +#ifdef __C64__ +#define TARGETMEM 0x4c8 +#define SOURCEMEM 0x702 +#elif __SIM6502__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#elif __SIM65C02__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#else +static unsigned char mem[0x10]; +#define TARGETMEM &mem[0] +#define SOURCEMEM &mem[8] +#endif + +/* do not put at pos. 1, and 1 byte apart - so we can eventually notice + off-by-one errors */ +static unsigned short u16w = 3; +static unsigned char u8r = 5; + +static unsigned char target[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; +static unsigned char source[8] = { 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; +static unsigned char expect[8] = { 0x0, 0x1, 0x2, 0x3, 0xe, 0xf, 0x6, 0x7 }; + +static unsigned char i; +static unsigned char err = EXIT_SUCCESS; + +void test1(void) +{ + ((unsigned char*)TARGETMEM)[++u16w] = ((unsigned char*)SOURCEMEM)[++u8r]; +} + +void dotest(void) +{ + + memcpy(TARGETMEM, target, 8); + memcpy(SOURCEMEM, source, 8); + + test1(); + + memcpy(target, TARGETMEM, 8); + memcpy(source, SOURCEMEM, 8); +#ifdef __C64__ + clrscr(); +#endif + printf("source:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", source[i]); + } + printf("\n\rtarget:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", target[i]); + } + printf("\n\r"); + + printf("u16w: %d\n\r", u16w); + printf("u8r: %d\n\r", u8r); + +} + +int main(void) +{ + dotest(); + dotest(); + if (memcmp(target, expect, 8) != 0) { + printf("buffer data error\n\r"); + err = EXIT_FAILURE; + } + if (u16w != 5) { + err = EXIT_FAILURE; + } + if (u8r != 7) { + err = EXIT_FAILURE; + } + printf("return: %d\n\r", err); + return err; +} diff --git a/test/val/preinc-8-16.c b/test/val/preinc-8-16.c new file mode 100644 index 000000000..3c3a9b479 --- /dev/null +++ b/test/val/preinc-8-16.c @@ -0,0 +1,86 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef __C64__ +#include <conio.h> +#endif + +/* apparently we dont trigger the bug when not using absolute addresses? */ +#ifdef __C64__ +#define TARGETMEM 0x4c8 +#define SOURCEMEM 0x702 +#elif __SIM6502__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#elif __SIM65C02__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#else +static unsigned char mem[0x10]; +#define TARGETMEM &mem[0] +#define SOURCEMEM &mem[8] +#endif + +/* do not put at pos. 1, and 1 byte apart - so we can eventually notice + off-by-one errors */ +static unsigned char u8w = 3; +static unsigned short u16r = 5; + +static unsigned char target[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; +static unsigned char source[8] = { 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; +static unsigned char expect[8] = { 0x0, 0x1, 0x2, 0x3, 0xe, 0xf, 0x6, 0x7 }; + +static unsigned char i; +static unsigned char err = EXIT_SUCCESS; + +void test1(void) +{ + ((unsigned char*)TARGETMEM)[++u8w] = ((unsigned char*)SOURCEMEM)[++u16r]; +} + +void dotest(void) +{ + + memcpy(TARGETMEM, target, 8); + memcpy(SOURCEMEM, source, 8); + + test1(); + + memcpy(target, TARGETMEM, 8); + memcpy(source, SOURCEMEM, 8); +#ifdef __C64__ + clrscr(); +#endif + printf("source:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", source[i]); + } + printf("\n\rtarget:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", target[i]); + } + printf("\n\r"); + + printf("u8w: %d\n\r", u8w); + printf("u16r: %d\n\r", u16r); + +} + +int main(void) +{ + dotest(); + dotest(); + if (memcmp(target, expect, 8) != 0) { + printf("buffer data error\n\r"); + err = EXIT_FAILURE; + } + if (u8w != 5) { + err = EXIT_FAILURE; + } + if (u16r != 7) { + err = EXIT_FAILURE; + } + printf("return: %d\n\r", err); + return err; +} diff --git a/test/val/preinc-8-8.c b/test/val/preinc-8-8.c new file mode 100644 index 000000000..a700bfc48 --- /dev/null +++ b/test/val/preinc-8-8.c @@ -0,0 +1,86 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef __C64__ +#include <conio.h> +#endif + +/* apparently we dont trigger the bug when not using absolute addresses? */ +#ifdef __C64__ +#define TARGETMEM 0x4c8 +#define SOURCEMEM 0x702 +#elif __SIM6502__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#elif __SIM65C02__ +#define TARGETMEM 0xc4c8 +#define SOURCEMEM 0xc702 +#else +static unsigned char mem[0x10]; +#define TARGETMEM &mem[0] +#define SOURCEMEM &mem[8] +#endif + +/* do not put at pos. 1, and 1 byte apart - so we can eventually notice + off-by-one errors */ +static unsigned char u8w = 3; +static unsigned char u8r = 5; + +static unsigned char target[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; +static unsigned char source[8] = { 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; +static unsigned char expect[8] = { 0x0, 0x1, 0x2, 0x3, 0xe, 0xf, 0x6, 0x7 }; + +static unsigned char i; +static unsigned char err = EXIT_SUCCESS; + +void test1(void) +{ + ((unsigned char*)TARGETMEM)[++u8w] = ((unsigned char*)SOURCEMEM)[++u8r]; +} + +void dotest(void) +{ + + memcpy(TARGETMEM, target, 8); + memcpy(SOURCEMEM, source, 8); + + test1(); + + memcpy(target, TARGETMEM, 8); + memcpy(source, SOURCEMEM, 8); +#ifdef __C64__ + clrscr(); +#endif + printf("source:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", source[i]); + } + printf("\n\rtarget:"); + for(i = 0; i < 8; ++i) { + printf("%0x ", target[i]); + } + printf("\n\r"); + + printf("u8w: %d\n\r", u8w); + printf("u8r: %d\n\r", u8r); + +} + +int main(void) +{ + dotest(); + dotest(); + if (memcmp(target, expect, 8) != 0) { + printf("buffer data error\n\r"); + err = EXIT_FAILURE; + } + if (u8w != 5) { + err = EXIT_FAILURE; + } + if (u8r != 7) { + err = EXIT_FAILURE; + } + printf("return: %d\n\r", err); + return err; +} From 86ba877a990196d978993e34fc3e9d448764d521 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Tue, 23 Jun 2020 21:25:23 +0200 Subject: [PATCH 1345/2161] Define REFCC and REFCC_UNSIGNED_CHARS in reference switch2.c uses these macros. With them unset, signed chars are not tested. --- test/ref/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ref/Makefile b/test/ref/Makefile index 5f0b86164..5da21bb92 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -54,7 +54,7 @@ $(WORKDIR): $(WORKDIR)/%.ref: %.c | $(WORKDIR) $(if $(QUIET),echo ref/$*.host) - $(CC) $(CFLAGS) -o $(WORKDIR)/$*.host $< $(NULLERR) + $(CC) $(CFLAGS) -DREFCC -DREFCC_UNSIGNED_CHARS -o $(WORKDIR)/$*.host $< $(NULLERR) $(WORKDIR)$S$*.host > $@ $(DIFF): ../bdiff.c | $(WORKDIR) From 8fe317e7faf733ab0bab5168c1e0afb5c3623bfb Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Tue, 23 Jun 2020 21:57:03 +0200 Subject: [PATCH 1346/2161] Remove REFCC_UNSIGNED_CHARS from test/ref/ Explicitly use signed char or unsigned char for REFCC. --- test/ref/Makefile | 2 +- test/ref/switch2.c | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/test/ref/Makefile b/test/ref/Makefile index 5da21bb92..be9fbed59 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -54,7 +54,7 @@ $(WORKDIR): $(WORKDIR)/%.ref: %.c | $(WORKDIR) $(if $(QUIET),echo ref/$*.host) - $(CC) $(CFLAGS) -DREFCC -DREFCC_UNSIGNED_CHARS -o $(WORKDIR)/$*.host $< $(NULLERR) + $(CC) $(CFLAGS) -DREFCC -o $(WORKDIR)/$*.host $< $(NULLERR) $(WORKDIR)$S$*.host > $@ $(DIFF): ../bdiff.c | $(WORKDIR) diff --git a/test/ref/switch2.c b/test/ref/switch2.c index 7884f3722..3b2ab23e6 100644 --- a/test/ref/switch2.c +++ b/test/ref/switch2.c @@ -40,11 +40,7 @@ void testdefault1(unsigned char i) { /* we want a signed char */ #ifdef REFCC -#ifdef REFCC_UNSIGNED_CHARS signed char k; -#else -char k; -#endif #else @@ -145,11 +141,7 @@ void testdefault2(unsigned char i) { /* we want a unsigned char */ #ifdef REFCC -#ifdef REFCC_UNSIGNED_CHARS -char k; -#else unsigned char k; -#endif #else From 18246278c5fd65e0daab65de229ea3a3baf71104 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Thu, 25 Jun 2020 08:54:58 +0200 Subject: [PATCH 1347/2161] switch2.c: Remove use of REFCC and UNSIGNED_CHARS Explicitly use `signed char` or `unsigned char`, rather than ``` signed char k; char k; signed char k; char k; ``` This should have resulted in the same thing; however, note that `REFCC` was never defined, and `common.h` was not included, so the old code in fact tested `char` then `unsigned char`, which are the same. The only difference is that a switch using plain `char` is not tested, but since this is the same as either `signed char` or `unsigned char`, the lack of test coverage seems relatively safe. --- test/ref/Makefile | 2 +- test/ref/switch2.c | 28 ++-------------------------- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/test/ref/Makefile b/test/ref/Makefile index be9fbed59..5f0b86164 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -54,7 +54,7 @@ $(WORKDIR): $(WORKDIR)/%.ref: %.c | $(WORKDIR) $(if $(QUIET),echo ref/$*.host) - $(CC) $(CFLAGS) -DREFCC -o $(WORKDIR)/$*.host $< $(NULLERR) + $(CC) $(CFLAGS) -o $(WORKDIR)/$*.host $< $(NULLERR) $(WORKDIR)$S$*.host > $@ $(DIFF): ../bdiff.c | $(WORKDIR) diff --git a/test/ref/switch2.c b/test/ref/switch2.c index 3b2ab23e6..78d383b52 100644 --- a/test/ref/switch2.c +++ b/test/ref/switch2.c @@ -37,20 +37,8 @@ void testlimits(int i) { } void testdefault1(unsigned char i) { -/* we want a signed char */ -#ifdef REFCC -signed char k; - -#else - -#ifdef UNSIGNED_CHARS -signed char k; -#else -char k; -#endif - -#endif + signed char k; for(;i<254;) { k = i; @@ -138,20 +126,8 @@ char k; } void testdefault2(unsigned char i) { -/* we want a unsigned char */ -#ifdef REFCC -unsigned char k; - -#else - -#ifdef UNSIGNED_CHARS -char k; -#else -unsigned char k; -#endif - -#endif + unsigned char k; for(;i<254;) { k = i; From 5277ea0b73c75ce2dae034dff3c1f7a325f2563d Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 27 Jun 2020 02:23:22 +0200 Subject: [PATCH 1348/2161] Add test license description. --- test/CPYRIGHT.LCC | 60 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 test/CPYRIGHT.LCC diff --git a/test/CPYRIGHT.LCC b/test/CPYRIGHT.LCC new file mode 100644 index 000000000..a7527a9d3 --- /dev/null +++ b/test/CPYRIGHT.LCC @@ -0,0 +1,60 @@ +The authors of this software are Christopher W. Fraser and +David R. Hanson. + +Copyright (c) 1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002 +by AT&T, Christopher W. Fraser, and David R. Hanson. All Rights Reserved. + +Permission to use, copy, modify, and distribute this software for any +purpose, subject to the provisions described below, without fee is +hereby granted, provided that this entire notice is included in all +copies of any software that is or includes a copy or modification of +this software and in all copies of the supporting documentation for +such software. + +THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED +WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY +REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY +OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + +lcc is not public-domain software, shareware, and it is not protected +by a `copyleft' agreement, like the code from the Free Software +Foundation. + +lcc is available free for your personal research and instructional use +under the `fair use' provisions of the copyright law. You may, however, +redistribute lcc in whole or in part provided you acknowledge its +source and include this CPYRIGHT file. You may, for example, include +the distribution in a CDROM of free software, provided you charge only +for the media, or mirror the distribution files at your site. + +You may not sell lcc or any product derived from it in which it is a +significant part of the value of the product. Using the lcc front end +to build a C syntax checker is an example of this kind of product. + +You may use parts of lcc in products as long as you charge for only +those components that are entirely your own and you acknowledge the use +of lcc clearly in all product documentation and distribution media. You +must state clearly that your product uses or is based on parts of lcc +and that lcc is available free of charge. You must also request that +bug reports on your product be reported to you. Using the lcc front +end to build a C compiler for the Motorola 88000 chip and charging for +and distributing only the 88000 code generator is an example of this +kind of product. + +Using parts of lcc in other products is more problematic. For example, +using parts of lcc in a C++ compiler could save substantial time and +effort and therefore contribute significantly to the profitability of +the product. This kind of use, or any use where others stand to make a +profit from what is primarily our work, requires a license agreement +with Addison-Wesley. Per-copy and unlimited use licenses are +available; for more information, contact + + Kim Boedigheimer + Addison Wesley + 75 Arlington St., Suite 300 + Boston, MA 02116 + 617/848-6559 kim.boedigheimer@pearsoned.com +----- +Chris Fraser / cwf@aya.yale.edu +David Hanson / drh@drhanson.net +$Revision$ $Date$ From 90d1c89bfff14be6d4921d0fc525060c41d3591c Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jesse.rosenstock@gmail.com> Date: Sat, 27 Jun 2020 15:02:11 +0200 Subject: [PATCH 1349/2161] Allow overlap of bit-field storage units (#1055) * Allow overlap of bit-field storage units Previously, struct s { unsigned int x : 10; unsigned int y : 10; }; had sizeof(struct s) == 4. With this change, allow the storage units of x and y to overlap, so sizeof(struct s) == 3, with y stored immediately after x, with no padding between them. An int bit-field (the only type currently supported) will still never occupy more than two bytes. * ParseStructInit: Fix typo and expand comment Explain why there are at most 30, not 32 bits. * ParseStructDecl: Rewrite AddBitFieldCall No behavior change. Co-authored-by: Jesse Rosenstock <jmr@users.noreply.github.com> --- src/cc65/declare.c | 52 ++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 523aac48a..d8226e604 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -33,6 +33,7 @@ +#include <limits.h> #include <stdio.h> #include <string.h> #include <errno.h> @@ -832,18 +833,18 @@ static SymEntry* ParseStructDecl (const char* Name) /* Add a field entry to the table */ if (FieldWidth > 0) { - /* Add full byte from the bit offset to the variable offset. - ** This simplifies handling he bit-field as a char type - ** in expressions. + /* Full bytes have already been added to the StructSize, + ** which is passed to the offset of AddBitField. BitOffs + ** is always within a char, which simplifies handling the + ** bit-field as a char type in expressions. */ - unsigned Offs = StructSize + (BitOffs / CHAR_BITS); - AddBitField (Decl.Ident, Offs, BitOffs % CHAR_BITS, FieldWidth); + CHECK (BitOffs < CHAR_BITS); + AddBitField (Decl.Ident, StructSize, BitOffs, FieldWidth); BitOffs += FieldWidth; CHECK (BitOffs <= INT_BITS); - if (BitOffs == INT_BITS) { - StructSize += SIZEOF_INT; - BitOffs = 0; - } + /* Add any full bytes to the struct size. */ + StructSize += BitOffs / CHAR_BITS; + BitOffs %= CHAR_BITS; } else { AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize); if (!FlexibleMember) { @@ -1815,10 +1816,15 @@ static void OutputBitFieldData (StructInitData* SI) /* Output the data */ g_defdata (CF_INT | CF_UNSIGNED | CF_CONST, SI->BitVal, 0); - /* Clear the data from SI and account for the size */ - SI->BitVal = 0; - SI->ValBits = 0; - SI->Offs += SIZEOF_INT; + /* Update the data from SI and account for the size */ + if (SI->ValBits >= INT_BITS) { + SI->BitVal >>= INT_BITS; + SI->ValBits -= INT_BITS; + } else { + SI->BitVal = 0; + SI->ValBits = 0; + } + SI->Offs += SIZEOF_INT; } } @@ -2050,10 +2056,14 @@ static unsigned ParseStructInit (Type* T, int AllowFlexibleMembers) ** have an initializer. */ if (IsAnonName (Entry->Name)) { - /* Account for the data and output it if we have a full word */ + /* Account for the data and output it if we have at least a + ** full word. We may have more if there was storage unit + ** overlap, for example two consecutive 10 bit fields. + ** These will be packed into 3 bytes. + */ SI.ValBits += Entry->V.B.BitWidth; - CHECK (SI.ValBits <= INT_BITS); - if (SI.ValBits == INT_BITS) { + CHECK (SI.ValBits <= 2 * (INT_BITS - 1)); + if (SI.ValBits >= INT_BITS) { OutputBitFieldData (&SI); } goto NextMember; @@ -2079,8 +2089,14 @@ static unsigned ParseStructInit (Type* T, int AllowFlexibleMembers) /* Account for the data and output it if we have a full word */ SI.ValBits += Entry->V.B.BitWidth; - CHECK (SI.ValBits <= INT_BITS); - if (SI.ValBits == INT_BITS) { + /* Make sure unsigned is big enough to hold the value, 30 bits. + ** This is 30 and not 32 bits because a 16-bit bit-field will + ** always be byte aligned, so will have padding before it. + ** 15 bits twice is the most we can have. + */ + CHECK (SI.ValBits <= CHAR_BIT * sizeof(SI.BitVal)); + CHECK (SI.ValBits < 2 * (INT_BITS - 1)); + if (SI.ValBits >= INT_BITS) { OutputBitFieldData (&SI); } From a00611798d612eb8e59c100ea912ca46f9a7069e Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Sun, 28 Jun 2020 22:18:12 +0200 Subject: [PATCH 1350/2161] Output bit-field data as chars instead of ints This prepares for #1058, which will pad bit-fields only to the next byte, instead of the next sizeof(int) (two bytes). OutputBitFieldData now outputs chars instead of ints, and calls to this function loop until there is less than one byte to output. A final partial byte is written out with zero padding as a final partial int was previously. --- src/cc65/declare.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index d8226e604..667f12660 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1814,17 +1814,17 @@ static void OutputBitFieldData (StructInitData* SI) if (SI->ValBits > 0) { /* Output the data */ - g_defdata (CF_INT | CF_UNSIGNED | CF_CONST, SI->BitVal, 0); + g_defdata (CF_CHAR | CF_UNSIGNED | CF_CONST, SI->BitVal, 0); /* Update the data from SI and account for the size */ - if (SI->ValBits >= INT_BITS) { - SI->BitVal >>= INT_BITS; - SI->ValBits -= INT_BITS; + if (SI->ValBits >= CHAR_BITS) { + SI->BitVal >>= CHAR_BITS; + SI->ValBits -= CHAR_BITS; } else { SI->BitVal = 0; SI->ValBits = 0; } - SI->Offs += SIZEOF_INT; + SI->Offs += SIZEOF_CHAR; } } @@ -2062,8 +2062,8 @@ static unsigned ParseStructInit (Type* T, int AllowFlexibleMembers) ** These will be packed into 3 bytes. */ SI.ValBits += Entry->V.B.BitWidth; - CHECK (SI.ValBits <= 2 * (INT_BITS - 1)); - if (SI.ValBits >= INT_BITS) { + CHECK (SI.ValBits <= CHAR_BITS + INT_BITS - 2); + while (SI.ValBits >= CHAR_BITS) { OutputBitFieldData (&SI); } goto NextMember; @@ -2089,14 +2089,15 @@ static unsigned ParseStructInit (Type* T, int AllowFlexibleMembers) /* Account for the data and output it if we have a full word */ SI.ValBits += Entry->V.B.BitWidth; - /* Make sure unsigned is big enough to hold the value, 30 bits. - ** This is 30 and not 32 bits because a 16-bit bit-field will - ** always be byte aligned, so will have padding before it. - ** 15 bits twice is the most we can have. + /* Make sure unsigned is big enough to hold the value, 22 bits. + ** This is 22 bits because the most we can have is 7 bits left + ** over from the previous OutputBitField call, plus 15 bits + ** from this field. A 16-bit bit-field will always be byte + ** aligned, so will have padding before it. */ CHECK (SI.ValBits <= CHAR_BIT * sizeof(SI.BitVal)); - CHECK (SI.ValBits < 2 * (INT_BITS - 1)); - if (SI.ValBits >= INT_BITS) { + CHECK (SI.ValBits <= CHAR_BITS + INT_BITS - 2); + while (SI.ValBits >= CHAR_BITS) { OutputBitFieldData (&SI); } From f4a6d088477e1bb7ca298c3312801b7194b056c8 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Mon, 29 Jun 2020 08:59:49 +0200 Subject: [PATCH 1351/2161] Fix full bytes vs full word in comment --- src/cc65/declare.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 667f12660..51490dd7d 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2087,7 +2087,7 @@ static unsigned ParseStructInit (Type* T, int AllowFlexibleMembers) Shift = (Entry->V.B.Offs - SI.Offs) * CHAR_BITS + Entry->V.B.BitOffs; SI.BitVal |= (Val << Shift); - /* Account for the data and output it if we have a full word */ + /* Account for the data and output any full bytes we have. */ SI.ValBits += Entry->V.B.BitWidth; /* Make sure unsigned is big enough to hold the value, 22 bits. ** This is 22 bits because the most we can have is 7 bits left From fae25bc45907a5016457362abfa6cdcef07d50d3 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Mon, 29 Jun 2020 09:00:13 +0200 Subject: [PATCH 1352/2161] CHECK we have at most a partial byte --- src/cc65/declare.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 51490dd7d..06b1e314d 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2137,6 +2137,7 @@ NextMember: ConsumeRCurly (); /* If we have data from a bit-field left, output it now */ + CHECK(SI.ValBits < CHAR_BITS); OutputBitFieldData (&SI); /* If there are struct fields left, reserve additional storage */ From d31171164e0528bdaf5248be4fc59dd2633cd303 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Mon, 29 Jun 2020 17:40:02 +0200 Subject: [PATCH 1353/2161] Fix formatting --- src/cc65/declare.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 06b1e314d..d7940c93b 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2137,7 +2137,7 @@ NextMember: ConsumeRCurly (); /* If we have data from a bit-field left, output it now */ - CHECK(SI.ValBits < CHAR_BITS); + CHECK (SI.ValBits < CHAR_BITS); OutputBitFieldData (&SI); /* If there are struct fields left, reserve additional storage */ From 8891a896b51a4e8adec879da8a1fd991d740b422 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Sat, 27 Jun 2020 21:15:22 +0200 Subject: [PATCH 1354/2161] test/ref: Use separate .out files Use different .out files for different options / targets. This allows make -j N to work. Previously all test.*.*.prgs would use the same test.out file. Now test.*.*.out is also used. --- test/ref/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/ref/Makefile b/test/ref/Makefile index 5f0b86164..a94f65dd8 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -71,8 +71,8 @@ define PRG_template $(WORKDIR)/%.$1.$2.prg: %.c $(WORKDIR)/%.ref $(DIFF) $(if $(QUIET),echo ref/$$*.$1.$2.prg) $(CL65) -t sim$2 $$(CC65FLAGS) -$1 -o $$@ $$< $(NULLERR) - $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/$$*.out - $(DIFF) $(WORKDIR)/$$*.out $(WORKDIR)/$$*.ref + $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/$$*.$1.$2.out + $(DIFF) $(WORKDIR)/$$*.$1.$2.out $(WORKDIR)/$$*.ref endef # PRG_template From 0f8b587bc2586209e875d2b988b5aa379f7fc8e8 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 1 Jul 2020 00:13:55 +0200 Subject: [PATCH 1355/2161] Added directory for currently failing regression tests. --- test/readme.txt | 6 +++++ test/todo/Makefile | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 test/todo/Makefile diff --git a/test/readme.txt b/test/readme.txt index cd3b7501a..2d4413f45 100644 --- a/test/readme.txt +++ b/test/readme.txt @@ -9,6 +9,12 @@ compiler. /err - contains tests that MUST NOT compile +/todo - these tests fail due to open compiler issues + +/asm - contains the assembler regression tests + +/dasm - contains the disassembler regression tests + /misc - a few tests that need special care of some sort diff --git a/test/todo/Makefile b/test/todo/Makefile new file mode 100644 index 000000000..ab5eb598c --- /dev/null +++ b/test/todo/Makefile @@ -0,0 +1,63 @@ +# Makefile for the currently failing regression tests that return an error code on failure + +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) + DEL = del /f $(subst /,\,$1) +else + S = / + NOT = ! + NULLDEV = /dev/null + MKDIR = mkdir -p $1 + RMDIR = $(RM) -r $1 + DEL = $(RM) $1 +endif + +ifdef QUIET + .SILENT: + NULLOUT = >$(NULLDEV) + NULLERR = 2>$(NULLDEV) +endif + +SIM65FLAGS = -x 200000000 + +CL65 := $(if $(wildcard ../../bin/cl65*),..$S..$Sbin$Scl65,cl65) +SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65) + +WORKDIR = ../../testwrk/val + +OPTIONS = g O Os Osi Osir Osr Oi Oir Or + +.PHONY: all clean + +SOURCES := $(wildcard *.c) +TESTS = $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).6502.prg)) +TESTS += $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).65c02.prg)) + +all: $(TESTS) + +$(WORKDIR): + $(call MKDIR,$(WORKDIR)) + +define PRG_template + +$(WORKDIR)/%.$1.$2.prg: %.c | $(WORKDIR) + $(if $(QUIET),echo val/$$*.$1.$2.prg) + $(CL65) -t sim$2 $$(CC65FLAGS) -$1 -o $$@ $$< $(NULLERR) + $(NOT) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) + +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)) + @$(call DEL,$(SOURCES:.c=.o)) From 17c55041291b0deb880cfd4f5322714fdb6a0a30 Mon Sep 17 00:00:00 2001 From: Daniel Serpell <daniel.serpell@gmail.com> Date: Fri, 3 Jul 2020 23:03:19 -0400 Subject: [PATCH 1356/2161] In Atari XEX output format, join memory areas if possible. This makes executables shorter if two memory areas are consecutive. --- doc/ld65.sgml | 3 ++- src/ld65/xex.c | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index d8e296996..cba06fef4 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -932,7 +932,8 @@ the standard format used by Atari DOS 2.0 and upward file managers in the Atari </verb></tscreen> In the Atari segmented file format, the linker will write each <tt/MEMORY/ area -as a new segment, including a header with the start and end address. +as including a header with the start and end address. If two memory areas are +contiguous, the headers will be joined if possible. The necessary o65 or Atari attributes are defined in a special section labeled <ref id="FORMAT" name="FORMAT">. diff --git a/src/ld65/xex.c b/src/ld65/xex.c index c57fa0a8c..94f3920b5 100644 --- a/src/ld65/xex.c +++ b/src/ld65/xex.c @@ -241,9 +241,6 @@ static unsigned long XexWriteMem (XexDesc* D, MemoryArea* M) /* Store initial position to get total file size */ unsigned long StartPos = ftell (D->F); - /* Always write a segment header for each memory area */ - D->HeadPos = 0; - /* Get the start address and size of this memory area */ unsigned long Addr = M->Start; @@ -400,6 +397,7 @@ void XexWriteTarget (XexDesc* D, struct File* F) if (D->F == 0) { Error ("Cannot open `%s': %s", D->Filename, strerror (errno)); } + D->HeadPos = 0; /* Keep the user happy */ Print (stdout, 1, "Opened `%s'...\n", D->Filename); @@ -415,6 +413,8 @@ void XexWriteTarget (XexDesc* D, struct File* F) Write16 (D->F, 0x2E2); Write16 (D->F, 0x2E3); Write16 (D->F, GetExportVal (I->InitAd->Exp)); + /* Always write a new segment header after an INITAD segment */ + D->HeadPos = 0; } } From 286da30a269989be35cfd80a377da64d01ce2a95 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 4 Jul 2020 13:32:28 +0800 Subject: [PATCH 1357/2161] Quick fix for Issue #1071. --- src/cc65/coptstop.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index b14b23195..46ccf020b 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -145,6 +145,9 @@ struct StackOpData { /* Freedom of registers inside the sequence */ unsigned UsedRegs; /* Registers used */ + /* Whether the rhs is changed multiple times */ + int RhsMultiChg; + /* Register load information for lhs and rhs */ LoadInfo Lhs; LoadInfo Rhs; @@ -1972,6 +1975,7 @@ static void ResetStackOpData (StackOpData* Data) Data->ZPUsage = REG_NONE; Data->ZPChanged = REG_NONE; Data->UsedRegs = REG_NONE; + Data->RhsMultiChg = 0; ClearLoadInfo (&Data->Lhs); ClearLoadInfo (&Data->Rhs); @@ -2092,6 +2096,10 @@ static int PreCondOk (StackOpData* D) } } } + if (D->RhsMultiChg && (D->OptFunc->Flags & OP_RHS_REMOVE_DIRECT) != 0) { + /* Cannot optimize */ + break; + } Passed = 1; } while (0); @@ -2188,6 +2196,8 @@ unsigned OptStackOps (CodeSeg* S) int OldEntryCount; /* Old number of entries */ unsigned Used; /* What registers would be used */ unsigned PushedRegs; /* Track if the same regs are used after the push */ + int RhsALoadIndex; /* Track if rhs is changed more than once */ + int RhsXLoadIndex; /* Track if rhs is changed more than once */ enum { Initialize, @@ -2335,6 +2345,10 @@ unsigned OptStackOps (CodeSeg* S) } + /* Memorize the old rhs load indices before refreshing them */ + RhsALoadIndex = Data.Rhs.A.LoadIndex; + RhsXLoadIndex = Data.Rhs.X.LoadIndex; + /* Track register usage */ Used = TrackLoads (&Data.Rhs, &Data.Lhs, Data.Code, I); Data.ZPUsage |= (E->Use | E->Chg); @@ -2358,6 +2372,16 @@ unsigned OptStackOps (CodeSeg* S) } PushedRegs &= ~E->Chg; } + /* Check if rhs is changed again after the push */ + if ((RhsALoadIndex != Data.Lhs.A.LoadIndex && + RhsALoadIndex != Data.Rhs.A.LoadIndex) || + (RhsXLoadIndex != Data.Lhs.X.LoadIndex && + RhsXLoadIndex != Data.Rhs.X.LoadIndex)) { + /* This will disable those sub-opts that require removing + ** the rhs as they can't handle such cases correctly. + */ + Data.RhsMultiChg = 1; + } break; case FoundOp: From 539924249b96557f64e774db7e4ea479f299b801 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 4 Jul 2020 17:44:49 +0800 Subject: [PATCH 1358/2161] More complete fix for Issue #1071. --- src/cc65/coptstop.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 46ccf020b..a4fc0dc65 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -946,7 +946,8 @@ static unsigned Opt_toseqax_tosneax (StackOpData* D, const char* BoolTransformer D->Lhs.A.Flags |= LI_REMOVE; } else if ((D->Rhs.A.Flags & (LI_DIRECT | LI_RELOAD_Y)) == LI_DIRECT && - (D->Rhs.X.Flags & (LI_DIRECT | LI_RELOAD_Y)) == LI_DIRECT) { + (D->Rhs.X.Flags & (LI_DIRECT | LI_RELOAD_Y)) == LI_DIRECT && + D->RhsMultiChg == 0) { CodeEntry* LoadX = D->Rhs.X.LoadEntry; CodeEntry* LoadA = D->Rhs.A.LoadEntry; From d1833cc441c79f018fa496e44672b2b5edb57c8d Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 8 Jul 2020 00:48:39 +0200 Subject: [PATCH 1359/2161] Fix handling of charcodes 254 and 255, fixes issue #988 --- libsrc/c128/cputc.s | 3 +-- libsrc/c64/cputc.s | 3 +-- libsrc/cbm510/cputc.s | 3 +-- libsrc/cbm610/cputc.s | 3 +-- libsrc/plus4/cputc.s | 3 +-- libsrc/vic20/cputc.s | 3 +-- 6 files changed, 6 insertions(+), 12 deletions(-) diff --git a/libsrc/c128/cputc.s b/libsrc/c128/cputc.s index 667260843..5c0760e75 100644 --- a/libsrc/c128/cputc.s +++ b/libsrc/c128/cputc.s @@ -62,10 +62,9 @@ cputdirect: ; Handle character if high bit set L5: and #$7F - cmp #$7E ; PI? + cmp #$7F ; PI? bne L6 lda #$5E ; Load screen code for PI - bne cputdirect L6: ora #$40 bne cputdirect ; Branch always diff --git a/libsrc/c64/cputc.s b/libsrc/c64/cputc.s index d6b49607a..b893f2102 100644 --- a/libsrc/c64/cputc.s +++ b/libsrc/c64/cputc.s @@ -74,10 +74,9 @@ L5: inc CURS_Y ; Handle character if high bit set L10: and #$7F - cmp #$7E ; PI? + cmp #$7F ; PI? bne L11 lda #$5E ; Load screen code for PI - bne cputdirect L11: ora #$40 bne cputdirect diff --git a/libsrc/cbm510/cputc.s b/libsrc/cbm510/cputc.s index 73d45b422..7dd4cddb2 100644 --- a/libsrc/cbm510/cputc.s +++ b/libsrc/cbm510/cputc.s @@ -65,10 +65,9 @@ L3: sty CURS_X ; Handle character if high bit set L10: and #$7F - cmp #$7E ; PI? + cmp #$7F ; PI? bne L11 lda #$5E ; Load screen code for PI - bne cputdirect L11: ora #$40 bne cputdirect ; Branch always diff --git a/libsrc/cbm610/cputc.s b/libsrc/cbm610/cputc.s index 5888580ac..78e2a5581 100644 --- a/libsrc/cbm610/cputc.s +++ b/libsrc/cbm610/cputc.s @@ -73,10 +73,9 @@ L4: inc CURS_Y ; Handle character if high bit set L10: and #$7F - cmp #$7E ; PI? + cmp #$7F ; PI? bne L11 lda #$5E ; Load screen code for PI - bne cputdirect L11: ora #$40 bne cputdirect ; Branch always diff --git a/libsrc/plus4/cputc.s b/libsrc/plus4/cputc.s index 49b3a84dd..a72b4012a 100644 --- a/libsrc/plus4/cputc.s +++ b/libsrc/plus4/cputc.s @@ -74,10 +74,9 @@ L5: inc CURS_Y ; Handle character if high bit set L10: and #$7F - cmp #$7E ; PI? + cmp #$7F ; PI? bne L11 lda #$5E ; Load screen code for PI - bne cputdirect L11: ora #$40 bne cputdirect diff --git a/libsrc/vic20/cputc.s b/libsrc/vic20/cputc.s index 1db818546..9e818032e 100644 --- a/libsrc/vic20/cputc.s +++ b/libsrc/vic20/cputc.s @@ -95,10 +95,9 @@ L5: inc CURS_Y ; Handle character if high bit set L10: and #$7F - cmp #$7E ; PI? + cmp #$7F ; PI? bne L11 lda #$5E ; Load screen code for PI - bne cputdirect L11: ora #$40 bne cputdirect From 410e4502eee98f74d34477b3ce031bfe0f0386df Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 8 Jul 2020 05:55:30 -0400 Subject: [PATCH 1360/2161] Added a 160x192x2 TGI (graphics) driver to the VIC-20 library. The driver requires a special linker configuration: "vic20-tgi.cfg". The VIC-20 computer needs at least 8K of expansion RAM! "tgidemo.c" needed to be adjusted because the VIC-20's vertical (y) range is greater than its horizontal (x) range -- the opposite of most other platforms. Also, the circle demo would jam on the VIC-20. --- cfg/vic20-tgi.cfg | 50 ++ doc/vic20.sgml | 29 +- include/tgi.h | 2 +- include/vic20.h | 43 +- libsrc/vic20/libref.s | 10 +- libsrc/vic20/tgi/vic20-hi.s | 1018 ++++++++++++++++++++++++++++++++ libsrc/vic20/tgi_stat_stddrv.s | 8 + libsrc/vic20/tgi_stddrv.s | 13 + libsrc/vic20/tgihdr.s | 67 +++ samples/Makefile | 14 + samples/tgidemo.c | 22 +- 11 files changed, 1253 insertions(+), 23 deletions(-) create mode 100644 cfg/vic20-tgi.cfg create mode 100644 libsrc/vic20/tgi/vic20-hi.s create mode 100644 libsrc/vic20/tgi_stat_stddrv.s create mode 100644 libsrc/vic20/tgi_stddrv.s create mode 100644 libsrc/vic20/tgihdr.s diff --git a/cfg/vic20-tgi.cfg b/cfg/vic20-tgi.cfg new file mode 100644 index 000000000..bc7845615 --- /dev/null +++ b/cfg/vic20-tgi.cfg @@ -0,0 +1,50 @@ +# Memory configuration which supports the "vic20-hi.tgi" driver. +# Memory configuration for a VIC-20 with, at least, 8K expansion RAM. +FEATURES { + STARTADDRESS: default = $1201; +} +SYMBOLS { + __LOADADDR__: type = import; + __EXEHDR__: type = import; + __TGIHDR__: type = import; + __STACKSIZE__: type = weak, value = $0200; # 512-byte stack + __HIMEM__: type = weak, value = $4000; +} +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 = $003E; + MAIN: file = %O, define = yes, start = $2000, size = __HIMEM__ - __MAIN_START__ - __STACKSIZE__; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + LOADADDR: load = LOADADDR, type = ro; +# The start-up code needs EXEHDR, TGI1HDR, TGI2HDR, +# and STARTUP to be next to each other, in that order. + EXEHDR: load = HEADER, type = ro; + TGI1HDR: load = HEADER, type = ro; + TGI2HDR: load = MAIN, 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; + ONCE: load = MAIN, type = ro, optional = yes, define = yes; + INIT: load = MAIN, type = bss, optional = yes; + 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/doc/vic20.sgml b/doc/vic20.sgml index 4fcd0079c..0a6e85d4a 100644 --- a/doc/vic20.sgml +++ b/doc/vic20.sgml @@ -75,7 +75,6 @@ common to all CBM platforms. There are currently no special VIC20 functions. - <sect1>CBM-specific functions<p> Some functions are available for all (or at least most) of the Commodore @@ -143,7 +142,33 @@ The names in the parentheses denote the symbols to be used for static linking of <sect1>Graphics drivers<p> -No graphics drivers are currently available for the VIC20. +<descrip> + + <tag><tt/vic20-hi.tgi (vic20_hi_tgi)/</tag> + This driver features a resolution of 160×192 with two colors. The + background can be chosen from a sixteen-color palette. The foreground can + be chosen from an eight-color palette. + + The driver will use memory from addresses $1000 to $1FFF as a graphics + buffer. Therefore, the VIC-20 must have, at least, 8K of expansion RAM. + + Programs that use this driver must be linked by the <tt/vic20-tgi.cfg/ + configuration file. It will link a special header into the program. + That header will do the housekeeping that's needed by TGI. + + An example command line: + <tscreen><verb> + cl65 -D DYN_DRV=0 -t vic20 -C vic20-tgi.cfg samples/mandelbrot.c + </verb></tscreen> + + When the program starts, it will move itself up in RAM, to make room for the + buffer. When the program finishes, it will reset the BASIC interpreter. + That means that graphics pictures won't be preserved between the executions + of programs. Also, the graphics buffer shares RAM with the text screen. If + a picture must be saved, then a program must put it somewhere else (such as + a disk file) before returning to the text mode. + +</descrip> <sect1>Extended memory drivers<p> diff --git a/include/tgi.h b/include/tgi.h index 15a6437cc..135ef63f1 100644 --- a/include/tgi.h +++ b/include/tgi.h @@ -216,7 +216,7 @@ void __fastcall__ tgi_arc (int x, int y, unsigned char rx, unsigned char ry, /* Draw an ellipse arc with center at x/y and radii rx/ry using the current ** drawing color. The arc covers the angle between sa and ea (startangle and ** endangle), which must be in the range 0..360 (otherwise the function may -** bevave unextectedly). +** behave unexpectedly). */ void __fastcall__ tgi_pieslice (int x, int y, unsigned char rx, unsigned char ry, diff --git a/include/vic20.h b/include/vic20.h index 44512b3fd..d60c7e270 100644 --- a/include/vic20.h +++ b/include/vic20.h @@ -2,12 +2,12 @@ /* */ /* vic20.h */ /* */ -/* vic20 system specific definitions */ +/* VIC-20 system-specific definitions */ /* */ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -66,14 +66,39 @@ #define COLOR_GREEN 0x05 #define COLOR_BLUE 0x06 #define COLOR_YELLOW 0x07 +/* Only the background and multi-color characters can have these colors. */ #define COLOR_ORANGE 0x08 -#define COLOR_BROWN 0x09 -#define COLOR_LIGHTRED 0x0A -#define COLOR_GRAY1 0x0B -#define COLOR_GRAY2 0x0C +#define COLOR_LIGHTORANGE 0x09 +#define COLOR_PINK 0x0A +#define COLOR_LIGHTCYAN 0x0B +#define COLOR_LIGHTVIOLET 0x0C #define COLOR_LIGHTGREEN 0x0D #define COLOR_LIGHTBLUE 0x0E -#define COLOR_GRAY3 0x0F +#define COLOR_LIGHTYELLOW 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_VIOLET COLOR_VIOLET +#define TGI_COLOR_GREEN COLOR_GREEN +#define TGI_COLOR_BLUE COLOR_BLUE +#define TGI_COLOR_YELLOW COLOR_YELLOW +/* Only the background and multi-color graphics can have these colors. */ +#define TGI_COLOR_ORANGE COLOR_ORANGE +#define TGI_COLOR_LIGHTORANGE COLOR_LIGHTORANGE +#define TGI_COLOR_PINK COLOR_PINK +#define TGI_COLOR_LIGHTCYAN COLOR_LIGHTCYAN +#define TGI_COLOR_LIGHTVIOLET COLOR_LIGHTVIOLET +#define TGI_COLOR_LIGHTGREEN COLOR_LIGHTGREEN +#define TGI_COLOR_LIGHTBLUE COLOR_LIGHTBLUE +#define TGI_COLOR_LIGHTYELLOW COLOR_LIGHTYELLOW + + + +/* tgi_ioctl() commands */ +#define TGI_IOCTL_VIC20_SET_PATTERN 0x01 /* Set 8-byte pattern for tgi_bar(). */ @@ -108,5 +133,9 @@ extern void vic20_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ extern void vic20_rama_emd[]; extern void vic20_georam_emd[]; +extern void vic20_hi_tgi[]; /* Referred to by tgi_static_stddrv[] */ + + + /* End of vic20.h */ #endif diff --git a/libsrc/vic20/libref.s b/libsrc/vic20/libref.s index 468c540f1..333a66894 100644 --- a/libsrc/vic20/libref.s +++ b/libsrc/vic20/libref.s @@ -1,10 +1,14 @@ ; -; Oliver Schmidt, 2013-05-31 +; 2013-05-31, Oliver Schmidt +; 2018-03-11, Sven Michael Klose ; - .export joy_libref .export em_libref + .export joy_libref + .export tgi_libref + .import _exit -joy_libref := _exit em_libref := _exit +joy_libref := _exit +tgi_libref := _exit diff --git a/libsrc/vic20/tgi/vic20-hi.s b/libsrc/vic20/tgi/vic20-hi.s new file mode 100644 index 000000000..8dfa46d6b --- /dev/null +++ b/libsrc/vic20/tgi/vic20-hi.s @@ -0,0 +1,1018 @@ +; +; Graphics driver for a 160x192x2 mode on the VIC-20. +; +; Based on C64 TGI driver +; +; 2018-03-11, Sven Michael Klose +; 2020-07-06, Greg King +; + + .include "zeropage.inc" + .include "vic20.inc" + + .include "tgi-kernel.inc" + .include "tgi-error.inc" + + .macpack generic + .macpack module + + +; ------------------------------------------------------------------------ +; Constants + +COLS = 20 +ROWS = 12 +XRES = COLS * 8 +YRES = ROWS * 16 + +TGI_IOCTL_VIC20_SET_PATTERN = $01 + +; ------------------------------------------------------------------------ +; Header. Includes jump table and constants. + + module_header _vic20_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 ; ASCII "tgi" + .byte TGI_API_VERSION ; TGI API version number + .addr $0000 ; Library reference + .word XRES ; X resolution + .word YRES ; 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 $0180 ; Aspect ratio 2.5:3 + .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 + +POINT := regsave +SOURCE := tmp1 +DEST := tmp3 + +; Absolute variables used in the code + +.bss + +ERROR: .res 1 ; Error code +PALETTE: .res 2 ; The current palette + +CURCOL: .res 1 ; Current color. +BITMASK: .res 1 ; $00 = clear, $FF = set pixels + +; BAR variables + +XPOSR: .res 1 ; Used by BAR. +PATTERN: .res 2 ; Address of pattern. +USERPATTERN: .res 2 ; User-defined pattern set via CONTROL. +COUNTER: .res 2 +TMP: .res 1 +MASKS: .res 1 +MASKD: .res 1 +XCPOS: .res 1 +HEIGHT: .res 1 + +; Line variables + +CHUNK := X2 ; Used in the line routine +OLDCHUNK := X2+1 ; Ditto +TEMP := tmp4 +TEMP2 := sreg +DX: .res 2 +DY: .res 2 + +; Text output stuff + +TEXTMAGX: .res 1 +TEXTMAGY: .res 1 +TEXTDIR: .res 1 + +; Constants and tables + +.rodata + +DEFPALETTE: .byte $00, $01 ; 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 := $8000 ; Character ROM base address +CBASE := $9400 ; Color memory base address +SBASE := $1000 ; Screen memory base address +VBASE := $1100 ; Video memory base address + +; These numbers are added to Kernal's default VIC settings. +; They make the Video Interface Controller show graphics instead of text. + +.proc VICREGS + .byte <+2 ; Left_edge + 2 + .byte <-2 ; Top_edge - 2 + .byte <-2 ; Columns - 2 + .byte <-(11 << 1) + 1 ; Rows - 11, chars. are 8 x 16 pixels + .byte 0 + .byte <+$0C ; Font_address = $1000 +.endproc + +XADDRS_L: + .repeat COLS, n + .byte <(VBASE + YRES * n) + .endrep + +XADDRS_H: + .repeat COLS, n + .byte >(VBASE + YRES * n) + .endrep + +MASKS_LEFT: + .byte %11111111 +MASKD_RIGHT: + .byte %01111111 + .byte %00111111 + .byte %00011111 + .byte %00001111 + .byte %00000111 + .byte %00000011 + .byte %00000001 +MASKD_LEFT: + .byte %00000000 +MASKS_RIGHT: + .byte %10000000 + .byte %11000000 + .byte %11100000 + .byte %11110000 + .byte %11111000 + .byte %11111100 + .byte %11111110 + .byte %11111111 + +PATTERN_EMPTY: + .byte %00000000 + .byte %00000000 + .byte %00000000 + .byte %00000000 + .byte %00000000 + .byte %00000000 + .byte %00000000 + .byte %00000000 + +PATTERN_SOLID: + .byte %11111111 + .byte %11111111 + .byte %11111111 + .byte %11111111 + .byte %11111111 + .byte %11111111 + .byte %11111111 + .byte %11111111 + +.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 +; + +.proc INSTALL + +; Reset user-defined pattern. + + lda #$00 + sta PATTERN + sta PATTERN+1 + rts +.endproc + +; ------------------------------------------------------------------------ +; 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 +; + +.proc UNINSTALL + rts +.endproc + +; ------------------------------------------------------------------------ +; 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 initialize variables and so on must go here. Setting the palette +; is not needed because that is done 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 +; + +.proc INIT + +; Initialize variables + + ldx #$FF + stx BITMASK + +; Make screen columns. + + lda #<SBASE + sta tmp2 + lda #>SBASE + sta tmp2+1 + inx ; (ldx #$00) + stx ERROR ; Set to TGI_ERR_OK + +@NEXT_ROW: + ldy #$00 + txa + clc + adc #$10 + +@NEXT_COLUMN: + sta (tmp2),y + clc + adc #ROWS + iny + cpy #COLS + bne @NEXT_COLUMN + +; Step to next row on screen. + + lda tmp2 + clc + adc #COLS + sta tmp2 + bcc @L1 + inc tmp2+1 + +@L1: inx + cpx #ROWS + bne @NEXT_ROW + +; Set up VIC. + + ldx #.sizeof(VICREGS) - 1 +@L2: clc + lda $EDE4,x + adc VICREGS,x + sta VIC,x + dex + bpl @L2 + + jmp CLEAR +.endproc + +; ------------------------------------------------------------------------ +; 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 +; + +.proc DONE + jmp $E518 ; Kernal console init. +.endproc + +; ------------------------------------------------------------------------ +; GETERROR: Return the error code in A, and clear it. + +.proc GETERROR + ldx #TGI_ERR_OK + lda ERROR + stx ERROR + rts +.endproc + +; ------------------------------------------------------------------------ +; CONTROL: Platform-/driver-specific entry point. +; +; Must set an error code: YES +; + +.proc CONTROL + +; Set user-defined pattern. + + cmp #TGI_IOCTL_VIC20_SET_PATTERN + bne @INVALID_FUNC + + lda ptr1 + sta USERPATTERN + lda ptr1+1 + sta USERPATTERN+1 + + lda #TGI_ERR_OK + .byte $2C ;(bit $1234) + +; Return with error code for invalid function index. + +@INVALID_FUNC: + lda #TGI_ERR_INV_FUNC + sta ERROR + rts +.endproc + +; ------------------------------------------------------------------------ +; CLEAR: Clears the screen. All pixels are set to the background color. +; +; Must set an error code: NO +; + +.proc CLEAR + lda #%00000000 + tay ; (ldy #$00) +@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 + iny + bne @L1 + rts +.endproc + +; ------------------------------------------------------------------------ +; SETVIEWPAGE: Set the visible page. Called with the new page in .A (0..n). +; 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) +; + +.proc SETVIEWPAGE + rts +.endproc + +; ------------------------------------------------------------------------ +; 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) +; + +.proc SETDRAWPAGE + rts +.endproc + +; ------------------------------------------------------------------------ +; 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) +; + +.proc SETCOLOR + sta CURCOL + tax + beq @L1 + lda #$FF +@L1: sta BITMASK + rts +.endproc + +; ------------------------------------------------------------------------ +; 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 +; + +.proc SETPALETTE + ldy #PALETTESIZE - 1 +@L1: lda (ptr1),y ; Copy the palette + and #$0F ; Make a valid color + sta PALETTE,y + dey + bpl @L1 + +; Initialize the color map with the new color settings. + + iny ; Set .Y to $00 + lda PALETTE+1 ; Foreground color +@L2: sta CBASE + $0000,y + sta CBASE + $0100,y + iny + bne @L2 + + lda PALETTE ; Background color + asl a ; Put it in high nybble + asl a + asl a + asl a + sta tmp2 + lda VIC_COLOR + and #$0F + ora tmp2 + sta VIC_COLOR + +; Done, reset the error code + + ;ldy #TGI_ERR_OK ; (Already zero) + sty ERROR + rts +.endproc + +; ------------------------------------------------------------------------ +; 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 +; + +.proc GETPALETTE + lda #<PALETTE + ldx #>PALETTE + rts +.endproc + +; ------------------------------------------------------------------------ +; 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 changeable) palette. +; +; Must set an error code: NO (all drivers must have a default palette) +; + +.proc GETDEFPALETTE + lda #<DEFPALETTE + ldx #>DEFPALETTE + rts +.endproc + +; ------------------------------------------------------------------------ +; 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's no need for clipping inside this function. +; +; Must set an error code: NO +; + +.proc SETPIXEL + jsr CALC ; Calculate co-ordinates + + ldy #$00 + lda (POINT),Y + eor BITMASK + and BITTAB,X + eor (POINT),Y + sta (POINT),Y + rts +.endproc + +; ------------------------------------------------------------------------ +; 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's no need for clipping inside this function. + + +.proc GETPIXEL + jsr CALC ; Calculate co-ordinates + + ldy #$00 + lda (POINT),Y + and BITTAB,X + beq @L1 + iny + tya ; Get color value into .A +@L1: ldx #>$0000 ; Clear high byte + rts +.endproc + +; ------------------------------------------------------------------------ +; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scalings in x and y +; directions are passed in .X/.Y; the text direction is passed in .A. +; +; Must set an error code: NO +; + +.proc TEXTSTYLE + stx TEXTMAGX + sty TEXTMAGY + sta TEXTDIR + rts +.endproc + +; ------------------------------------------------------------------------ +; 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 +; + +.proc OUTTEXT + rts +.endproc + +; ------------------------------------------------------------------------ +; Calculate address and X offset in char. line, to plot the pixel at X1/Y1. + +.proc CALC + lda X1+1 + bne @L1 + lda Y1+1 + bne @L1 + + lda X1 + lsr + lsr + lsr + tay + + lda XADDRS_L,y + clc + adc Y1 + sta POINT + lda XADDRS_H,y + adc #$00 + sta POINT+1 + + lda X1 + and #7 + tax + +@L1: rts +.endproc + +; ------------------------------------------------------------------------ +; 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 +; + +.proc LINE + +@CHECK: lda X2 ; Make sure x1 < x2 + sec + sbc X1 + tax + lda X2+1 + sbc X1+1 + bpl @CONT + lda Y2 ; If not, swap P1 and P2 + ldy Y1 + sta Y1 + sty Y2 + lda Y2+1 + ldy Y1+1 + sta Y1+1 + sty Y2+1 + lda X1 + ldy X2 + sty X1 + sta X2 + lda X2+1 + ldy X1+1 + sta X1+1 + sty X2+1 + bcc @CHECK + +@CONT: sta DX+1 + stx DX + + ldx #$C8 ; INY + lda Y2 ; Calculate dy + sec + sbc Y1 + tay + lda Y2+1 + sbc Y1+1 + bpl @DYPOS ; Is y2 >= y1? + lda Y1 ; Otherwise, dy = y1 - y2 + sec + sbc Y2 + tay + ldx #$88 ; DEY + +@DYPOS: sty DY ; 8-bit DY -- FIX ME? + stx YINCDEC + stx XINCDEC + + lda X1 + lsr + lsr + lsr + tay + lda XADDRS_L,y + sta POINT + lda XADDRS_H,y + sta POINT+1 + ldy Y1 + + lda X1 + and #7 + tax + 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 +; +; X is now counter, Y is y co-ordinate +; +; On entry, X=DY=number of loop iterations, and Y=Y1 +STEPINY: + lda #$00 + sta OLDCHUNK ; So plotting routine will work right + lda CHUNK + lsr ; Strip the bit + eor CHUNK + sta CHUNK + txa + bne @CONT ; If dy=0, it's just a point + inx +@CONT: lsr ; Init. counter to dy/2 +; +; Main loop +; +YLOOP: sta TEMP + + lda (POINT),y ; Plot + eor BITMASK + and CHUNK + eor (POINT),y + sta (POINT),y +YINCDEC: + iny ; Advance Y co-ordinate + 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 + adc #YRES + 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 + +.bss +COUNTHI: + .byte $00 ; Temporary counter, + ; used only 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 #YRES + 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 co-ordinate. +; +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 co-ord + 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 +.endproc + +; In: xpos, ypos, width, height +; ------------------------------------------------------------------------ +; 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 +; + +.proc BAR + +; Set user pattern if available. + + lda USERPATTERN + ora USERPATTERN+1 + beq @GET_PATTERN_BY_COLOR + + lda USERPATTERN + sta PATTERN + lda USERPATTERN+1 + sta PATTERN+1 + jmp @GOT_PATTERN + +; Determine pattern based on current colour. + +@GET_PATTERN_BY_COLOR: + lda #<PATTERN_SOLID + ldx #>PATTERN_SOLID + ldy CURCOL + bne @L2 + lda #<PATTERN_EMPTY + ldx #>PATTERN_EMPTY +@L2: sta PATTERN + stx PATTERN+1 + +@GOT_PATTERN: + +; Get starting POINT on screen. + + jsr CALC + sty XCPOS + lda POINT ; One off for VFILL/VCOPY. + sec + sbc #1 + sta POINT + bcs @L3 + dec POINT+1 +@L3: + +; Get height for VFILL. + + lda Y2 + sec + sbc Y1 + sta HEIGHT + +; Get rightmost char column. + + lda X2 + and #7 + sta XPOSR + +; Get width in characters. + + lda X2 + lsr + lsr + lsr + sec + sbc XCPOS + beq @DRAW_SINGLE_COLUMN + sta COUNTER + +; Draw left end. + + lda X1 + and #7 + tax + lda MASKD_LEFT,x + sta MASKD + lda MASKS_LEFT,x + sta MASKS + jsr VFILL + jsr INCPOINTX + +; Draw middle. + + dec COUNTER + beq @DRAW_RIGHT_END +@L1: jsr VCOPY + jsr INCPOINTX + dec COUNTER + bne @L1 + +; Draw right end. + +@DRAW_RIGHT_END: + ldx XPOSR + lda MASKD_RIGHT,x + sta MASKD + lda MASKS_RIGHT,x + sta MASKS + jmp VFILL + +; Draw left end. + +@DRAW_SINGLE_COLUMN: + lda X1 + and #7 + tax + ldy XPOSR + lda MASKS_LEFT,x + and MASKS_RIGHT,y + sta MASKS + lda MASKD_LEFT,x + ora MASKD_RIGHT,y + sta MASKD + jmp VFILL +.endproc + +; In: HEIGHT, PATTERN +; MASKS: Source mask (ANDed with pattern). +; MASKD: Destination mask (ANDed with screen). +; POINT: Starting address. +; ------------------------------------------------------------------------ +; Fill column with pattern using masks. +; + +.proc VFILL + lda PATTERN + sta @MOD_PATTERN+1 + lda PATTERN+1 + sta @MOD_PATTERN+2 + ldy HEIGHT + lda Y1 + and #7 + tax + +@L1: lda (POINT),y + and MASKD + sta TMP +@MOD_PATTERN: + lda $FFFF,x + and MASKS + ora TMP + sta (POINT),y + inx + txa + and #7 + tax + dey + bne @L1 + + rts +.endproc + +; In: HEIGHT, PATTERN, POINT +; ------------------------------------------------------------------------ +; Fill column with pattern. +; + +.proc VCOPY + lda PATTERN + sta @MOD_PATTERN+1 + lda PATTERN+1 + sta @MOD_PATTERN+2 + ldy HEIGHT + lda Y1 + and #7 + tax + +@MOD_PATTERN: +@L1: lda $FFFF,x + sta (POINT),y + inx + txa + and #7 + tax + dey + bne @L1 + + rts +.endproc + +.proc INCPOINTX + lda POINT + clc + adc #YRES + sta POINT + bcc @L1 + inc POINT+1 +@L1: rts +.endproc diff --git a/libsrc/vic20/tgi_stat_stddrv.s b/libsrc/vic20/tgi_stat_stddrv.s new file mode 100644 index 000000000..6a94d66aa --- /dev/null +++ b/libsrc/vic20/tgi_stat_stddrv.s @@ -0,0 +1,8 @@ +; +; Address of the static standard TGI driver +; +; const void tgi_static_stddrv[]; +; + + .import _vic20_hi_tgi + .export _tgi_static_stddrv := _vic20_hi_tgi diff --git a/libsrc/vic20/tgi_stddrv.s b/libsrc/vic20/tgi_stddrv.s new file mode 100644 index 000000000..d56af37e7 --- /dev/null +++ b/libsrc/vic20/tgi_stddrv.s @@ -0,0 +1,13 @@ +; +; Name of the standard TGI driver +; +; 2018-03-11, Sven Michael Klose +; +; const char tgi_stddrv[]; +; + + .export _tgi_stddrv + +.rodata + +_tgi_stddrv: .asciiz "vic20-hi.tgi" diff --git a/libsrc/vic20/tgihdr.s b/libsrc/vic20/tgihdr.s new file mode 100644 index 000000000..30258162d --- /dev/null +++ b/libsrc/vic20/tgihdr.s @@ -0,0 +1,67 @@ +; +; This code sits immediately after the BASIC stub program. +; Therefore, it's executed by that stub. +; +; 2018-04-17, Greg King +; + + .export __TGIHDR__ : abs = 1 ; Mark as TGI housekeeper + + .import __MAIN_LAST__ + .importzp ptr1, ptr2, tmp1 + + +basic_reset := $C000 ; vector to BASIC's cold-start code + +; This code moves the program to $2000. That move allows $1000 - $1FFF +; to be used by the TGI driver to hold its graphics data. + +.segment "TGI1HDR" + + lda #<(tgi1end + prog_size) ; source + ldx #>(tgi1end + prog_size) + sta ptr1 + stx ptr1+1 + + lda #<(tgi2hdr + prog_size) ; destination + ldx #>(tgi2hdr + prog_size) + sta ptr2 + stx ptr2+1 + + ldx #<~prog_size + lda #>~prog_size ; use -(prog_size + 1) + sta tmp1 + + ldy #<$0000 + +; Copy loop + +@L1: inx ; bump counter's low byte + beq @L4 + +@L2: tya ; will .Y underflow? + bne @L3 + dec ptr1+1 ; yes, do next lower page + dec ptr2+1 +@L3: dey + + lda (ptr1),y + sta (ptr2),y + jmp @L1 + +@L4: inc tmp1 ; bump counter's high byte + bne @L2 + + jmp tgi2hdr ; go to moved program +tgi1end: + +.segment "TGI2HDR" + +tgi2hdr: + jsr tgi2end ; run actual program + jmp (basic_reset) +tgi2end: + +; The length of the TGI program (including the TGI2HDR segment) + +prog_size = __MAIN_LAST__ - tgi2hdr diff --git a/samples/Makefile b/samples/Makefile index adfe870e4..267dc5235 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -230,6 +230,20 @@ ovrldemo: overlaydemo.o OVERLAYLIST := $(foreach I,1 2 3,multdemo.$I ovrldemo.$I) +# -------------------------------------------------------------------------- +# TGI programs on the VIC-20 need a special ld65 configuration file. + +ifeq ($(SYS),vic20) +mandelbrot.o: override CFLAGS += -D DYN_DRV=0 +mandelbrot: mandelbrot.o + $(LD) $(LDFLAGS) -o $@ -C vic20-tgi.cfg -m $@.map $^ $(SYS).lib + +# tgidemo needs at least 16K of RAM expansion. +tgidemo.o: override CFLAGS += -D DYN_DRV=0 +tgidemo: tgidemo.o + $(LD) -D __HIMEM__=0x6000 $(LDFLAGS) -o $@ -C vic20-tgi.cfg -m $@.map $^ $(SYS).lib +endif + # -------------------------------------------------------------------------- # Rule to make a CBM disk with all samples. Needs the c1541 program that comes # with the VICE emulator. diff --git a/samples/tgidemo.c b/samples/tgidemo.c index 93e91899b..b431cfb98 100644 --- a/samples/tgidemo.c +++ b/samples/tgidemo.c @@ -70,9 +70,10 @@ static void DoCircles (void) { static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_ORANGE }; unsigned char I; - unsigned char Color = COLOR_FORE; - unsigned X = MaxX / 2; - unsigned Y = MaxY / 2; + 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); @@ -82,7 +83,7 @@ static void DoCircles (void) while (!kbhit ()) { Color = (Color == COLOR_FORE) ? COLOR_BACK : COLOR_FORE; tgi_setcolor (Color); - for (I = 10; I < 240; I += 10) { + for (I = 10; I <= Limit; I += 10) { tgi_ellipse (X, Y, I, tgi_imulround (I, AspectRatio)); } } @@ -132,7 +133,7 @@ static void DoDiagram (void) tgi_setcolor (COLOR_FORE); tgi_clear (); - /* Determine zero and aplitude */ + /* Determine zero and amplitude */ YOrigin = MaxY / 2; XOrigin = 10; Amp = (MaxY - 19) / 2; @@ -168,16 +169,17 @@ 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 (); - for (X = 0; X <= MaxY; X += 10) { - tgi_line (0, 0, MaxY, X); - tgi_line (0, 0, X, MaxY); - tgi_line (MaxY, MaxY, 0, MaxY-X); - tgi_line (MaxY, MaxY, MaxY-X, 0); + for (X = 0; X <= Min; X += 10) { + tgi_line (0, 0, Min, X); + tgi_line (0, 0, X, Min); + tgi_line (Min, Min, 0, Min-X); + tgi_line (Min, Min, Min-X, 0); } cgetc (); From 021362fb757aa84d0d409bf9bdd4323f7b6e6682 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Thu, 2 Jul 2020 22:41:38 +0200 Subject: [PATCH 1361/2161] cl65: Remove temporary .o files --- src/cl65/main.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/cl65/main.c b/src/cl65/main.c index 9d536db82..c07e93e81 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -112,6 +112,9 @@ static CmdDesc CO65 = { 0, 0, 0, 0, 0, 0, 0 }; static CmdDesc LD65 = { 0, 0, 0, 0, 0, 0, 0 }; static CmdDesc GRC = { 0, 0, 0, 0, 0, 0, 0 }; +/* Pseudo-command to track files we want to delete */ +static CmdDesc RM = { 0, 0, 0, 0, 0, 0, 0 }; + /* Variables controlling the steps we're doing */ static int DoLink = 1; static int DoAssemble = 1; @@ -456,6 +459,19 @@ static void ExecProgram (CmdDesc* Cmd) +static void RemoveTempFiles (void) +{ + unsigned I; + for (I = 0; I < RM.FileCount; ++I) { + if (remove (RM.Files[I]) < 0) { + Warning ("Cannot remove temporary file '%s': %s", + RM.Files[I], strerror (errno)); + } + } +} + + + static void Link (void) /* Link the resulting executable */ { @@ -534,6 +550,8 @@ static void AssembleFile (const char* File, unsigned ArgCount) */ char* ObjName = MakeFilename (File, ".o"); CmdAddFile (&LD65, ObjName); + /* This is just a temporary file, schedule it for removal */ + CmdAddFile (&RM, ObjName); xfree (ObjName); } else { /* This is the final step. If an output name is given, set it */ @@ -1641,6 +1659,8 @@ int main (int argc, char* argv []) Link (); } + RemoveTempFiles (); + /* Return an apropriate exit code */ return EXIT_SUCCESS; } From 416adbce82c5dee998fc592561cd692fd0056174 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Fri, 3 Jul 2020 07:53:51 +0200 Subject: [PATCH 1362/2161] Add blank line --- src/cl65/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cl65/main.c b/src/cl65/main.c index c07e93e81..e7b9d5344 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -462,6 +462,7 @@ static void ExecProgram (CmdDesc* Cmd) static void RemoveTempFiles (void) { unsigned I; + for (I = 0; I < RM.FileCount; ++I) { if (remove (RM.Files[I]) < 0) { Warning ("Cannot remove temporary file '%s': %s", From 527df094caf40db07ac14f7591c8cf91f6d1a511 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Thu, 2 Jul 2020 22:24:57 +0200 Subject: [PATCH 1363/2161] Use xrealloc in cl65 Previously, xmalloc and xfree were used. --- src/cl65/main.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index e7b9d5344..f75200c89 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -231,12 +231,8 @@ static char* CmdAllocArg (const char* Arg, unsigned Len) static void CmdExpand (CmdDesc* Cmd) /* Expand the argument vector */ { - unsigned NewMax = Cmd->ArgMax + 10; - char** NewArgs = xmalloc (NewMax * sizeof (char*)); - memcpy (NewArgs, Cmd->Args, Cmd->ArgMax * sizeof (char*)); - xfree (Cmd->Args); - Cmd->Args = NewArgs; - Cmd->ArgMax = NewMax; + Cmd->ArgMax += 10; + Cmd->Args = xrealloc (Cmd->Args, Cmd->ArgMax * sizeof (char*)); } @@ -324,12 +320,8 @@ static void CmdAddFile (CmdDesc* Cmd, const char* File) { /* Expand the file vector if needed */ if (Cmd->FileCount == Cmd->FileMax) { - unsigned NewMax = Cmd->FileMax + 10; - char** NewFiles = xmalloc (NewMax * sizeof (char*)); - memcpy (NewFiles, Cmd->Files, Cmd->FileMax * sizeof (char*)); - xfree (Cmd->Files); - Cmd->Files = NewFiles; - Cmd->FileMax = NewMax; + Cmd->FileMax += 10; + Cmd->Files = xrealloc(Cmd->Files, Cmd->FileMax * sizeof(char*)); } /* If the file name is not NULL (which is legal and is used to terminate From c273c90bf22b087806f1b6d783b8666263f8766e Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Fri, 3 Jul 2020 07:56:05 +0200 Subject: [PATCH 1364/2161] Fix formatting --- 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 f75200c89..ea5329335 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -321,7 +321,7 @@ static void CmdAddFile (CmdDesc* Cmd, const char* File) /* Expand the file vector if needed */ if (Cmd->FileCount == Cmd->FileMax) { Cmd->FileMax += 10; - Cmd->Files = xrealloc(Cmd->Files, Cmd->FileMax * sizeof(char*)); + Cmd->Files = xrealloc (Cmd->Files, Cmd->FileMax * sizeof(char*)); } /* If the file name is not NULL (which is legal and is used to terminate From 9e881a497e619fc97cbb48a3a163e0eea23fbd52 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Fri, 3 Jul 2020 07:57:53 +0200 Subject: [PATCH 1365/2161] Fix formatting --- 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 ea5329335..dba4915f2 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -321,7 +321,7 @@ static void CmdAddFile (CmdDesc* Cmd, const char* File) /* Expand the file vector if needed */ if (Cmd->FileCount == Cmd->FileMax) { Cmd->FileMax += 10; - Cmd->Files = xrealloc (Cmd->Files, Cmd->FileMax * sizeof(char*)); + Cmd->Files = xrealloc (Cmd->Files, Cmd->FileMax * sizeof (char*)); } /* If the file name is not NULL (which is legal and is used to terminate From 9858e47dfd0d945b750bce7b19716a834f0d78e3 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Sun, 21 Jun 2020 21:28:32 +0200 Subject: [PATCH 1366/2161] Pad bit-fields only to the next byte Fixes #1054. Previously, bit-fields followed by another field were aligned to two bytes. Bit-fields ending the struct were (and continue to be) aligned only to a single byte. ``` struct s { unsigned int x : 4; }; struct t { unsigned int x : 4; unsigned int y; }; ``` Before: `sizeof(struct s) == 1`, sizeof(struct t) == 4` After: `sizeof(struct s) == 1` sizeof(struct t) == 3` --- src/cc65/declare.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index d7940c93b..730406088 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -772,17 +772,19 @@ static SymEntry* ParseStructDecl (const char* Name) */ if (BitOffs > 0) { if (FieldWidth <= 0 || (BitOffs + FieldWidth) > INT_BITS) { + /* Bits needed to byte-align the next field. */ + unsigned PaddingBitWidth = -BitOffs % CHAR_BITS; /* We need an anonymous name */ AnonName (Ident, "bit-field"); /* Add an anonymous bit-field that aligns to the next - ** storage unit. + ** byte. */ - AddBitField (Ident, StructSize, BitOffs, INT_BITS - BitOffs); + AddBitField (Ident, StructSize, BitOffs, PaddingBitWidth); /* No bits left */ - StructSize += SIZEOF_INT; + StructSize += (BitOffs + PaddingBitWidth) / CHAR_BITS; BitOffs = 0; } } From 6dc2bf12265f106d8cd4916a73990873f62f5c36 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Mon, 22 Jun 2020 09:07:39 +0200 Subject: [PATCH 1367/2161] Rename PaddingBitWidth to PaddingBits --- src/cc65/declare.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 730406088..5e2e204cf 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -773,7 +773,7 @@ static SymEntry* ParseStructDecl (const char* Name) if (BitOffs > 0) { if (FieldWidth <= 0 || (BitOffs + FieldWidth) > INT_BITS) { /* Bits needed to byte-align the next field. */ - unsigned PaddingBitWidth = -BitOffs % CHAR_BITS; + unsigned PaddingBits = -BitOffs % CHAR_BITS; /* We need an anonymous name */ AnonName (Ident, "bit-field"); @@ -781,10 +781,10 @@ static SymEntry* ParseStructDecl (const char* Name) /* Add an anonymous bit-field that aligns to the next ** byte. */ - AddBitField (Ident, StructSize, BitOffs, PaddingBitWidth); + AddBitField (Ident, StructSize, BitOffs, PaddingBits); /* No bits left */ - StructSize += (BitOffs + PaddingBitWidth) / CHAR_BITS; + StructSize += (BitOffs + PaddingBits) / CHAR_BITS; BitOffs = 0; } } From a70ac6be307e9de645b6fa7af895b226cb0c11de Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Sat, 27 Jun 2020 20:30:08 +0200 Subject: [PATCH 1368/2161] Add test of bit-field packing for #1054 and #1055 --- test/val/bitfield.c | 124 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 test/val/bitfield.c diff --git a/test/val/bitfield.c b/test/val/bitfield.c new file mode 100644 index 000000000..29e450359 --- /dev/null +++ b/test/val/bitfield.c @@ -0,0 +1,124 @@ +/* + !!DESCRIPTION!! Tests of bit-field packing + !!ORIGIN!! cc65 regression tests + !!LICENCE!! zlib + !!AUTHOR!! Jesse Rosenstock +*/ + +/* + see https://github.com/cc65/cc65/issues/1054 +*/ + +#include <stdio.h> + +static unsigned char failures = 0; + +static struct four_bits { + unsigned int x : 4; +} fb = {1}; + +static void test_four_bits(void) +{ + if (sizeof(struct four_bits) != 1) { + fprintf(stderr, "Got sizeof(struct four_bits) = %zu, expected 1.\n", + sizeof(struct four_bits)); + failures++; + } + + if (fb.x != 1) { + fprintf(stderr, "Got fb.x = %u, expected 1.\n", fb.x); + failures++; + } + + fb.x = 3; + + if (fb.x != 3) { + fprintf(stderr, "Got fb.x = %u, expected 3.\n", fb.x); + failures++; + } +} + +static struct four_bits_with_int { + unsigned int x : 4; + unsigned int y; +} fbi = {1, 2}; + +static void test_four_bits_with_int(void) +{ + /* We would like this to be 3. https://github.com/cc65/cc65/issues/1054 */ + if (sizeof(struct four_bits_with_int) != 4) { + fprintf(stderr, + "Got sizeof(struct four_bits_with_int) = %zu, expected 4.\n", + sizeof(struct four_bits_with_int)); + failures++; + } + + if (fbi.x != 1) { + fprintf(stderr, "Got fbi.x = %u, expected 1.\n", fbi.x); + failures++; + } + + if (fbi.y != 2) { + fprintf(stderr, "Got fbi.y = %u, expected 2.\n", fbi.y); + failures++; + } + + fbi.x = 3; + fbi.y = 17; + + if (fbi.x != 3) { + fprintf(stderr, "Got fbi.x = %u, expected 3.\n", fbi.x); + failures++; + } + + if (fbi.y != 17) { + fprintf(stderr, "Got fbi.y = %u, expected 17.\n", fbi.y); + failures++; + } +} + +static struct overlap { + unsigned int x : 10; + unsigned int y : 10; +} o = {11, 22}; + +/* Tests that bit-fields can share allocation units. */ +static void test_overlap(void) +{ + if (sizeof(struct overlap) != 3) { + fprintf(stderr, "Got sizeof(struct overlap) = %zu, expected 3.\n", + sizeof(struct overlap)); + failures++; + } + + if (o.x != 11) { + fprintf(stderr, "Got o.x = %u, expected 11.\n", o.x); + failures++; + } + + if (o.y != 22) { + fprintf(stderr, "Got o.y = %u, expected 22.\n", o.y); + failures++; + } + + o.x = 33; + o.y = 44; + + if (o.x != 33) { + fprintf(stderr, "Got o.x = %u, expected 33.\n", o.x); + failures++; + } + + if (o.y != 44) { + fprintf(stderr, "Got o.y = %u, expected 44.\n", o.y); + failures++; + } +} + +int main(void) +{ + test_four_bits(); + test_four_bits_with_int(); + test_overlap(); + return failures; +} From 8a331ee7ecf7af1671f406aa87a29456417e1b58 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Sat, 27 Jun 2020 20:39:33 +0200 Subject: [PATCH 1369/2161] Print to stdout instead of stderr Print number of failures. This makes it consistent with the other val/ tests. --- test/val/bitfield.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/test/val/bitfield.c b/test/val/bitfield.c index 29e450359..b203b9cce 100644 --- a/test/val/bitfield.c +++ b/test/val/bitfield.c @@ -20,20 +20,20 @@ static struct four_bits { static void test_four_bits(void) { if (sizeof(struct four_bits) != 1) { - fprintf(stderr, "Got sizeof(struct four_bits) = %zu, expected 1.\n", - sizeof(struct four_bits)); + printf("Got sizeof(struct four_bits) = %zu, expected 1.\n", + sizeof(struct four_bits)); failures++; } if (fb.x != 1) { - fprintf(stderr, "Got fb.x = %u, expected 1.\n", fb.x); + printf("Got fb.x = %u, expected 1.\n", fb.x); failures++; } fb.x = 3; if (fb.x != 3) { - fprintf(stderr, "Got fb.x = %u, expected 3.\n", fb.x); + printf("Got fb.x = %u, expected 3.\n", fb.x); failures++; } } @@ -47,19 +47,18 @@ static void test_four_bits_with_int(void) { /* We would like this to be 3. https://github.com/cc65/cc65/issues/1054 */ if (sizeof(struct four_bits_with_int) != 4) { - fprintf(stderr, - "Got sizeof(struct four_bits_with_int) = %zu, expected 4.\n", - sizeof(struct four_bits_with_int)); + printf("Got sizeof(struct four_bits_with_int) = %zu, expected 4.\n", + sizeof(struct four_bits_with_int)); failures++; } if (fbi.x != 1) { - fprintf(stderr, "Got fbi.x = %u, expected 1.\n", fbi.x); + printf("Got fbi.x = %u, expected 1.\n", fbi.x); failures++; } if (fbi.y != 2) { - fprintf(stderr, "Got fbi.y = %u, expected 2.\n", fbi.y); + printf("Got fbi.y = %u, expected 2.\n", fbi.y); failures++; } @@ -67,12 +66,12 @@ static void test_four_bits_with_int(void) fbi.y = 17; if (fbi.x != 3) { - fprintf(stderr, "Got fbi.x = %u, expected 3.\n", fbi.x); + printf("Got fbi.x = %u, expected 3.\n", fbi.x); failures++; } if (fbi.y != 17) { - fprintf(stderr, "Got fbi.y = %u, expected 17.\n", fbi.y); + printf("Got fbi.y = %u, expected 17.\n", fbi.y); failures++; } } @@ -86,18 +85,18 @@ static struct overlap { static void test_overlap(void) { if (sizeof(struct overlap) != 3) { - fprintf(stderr, "Got sizeof(struct overlap) = %zu, expected 3.\n", - sizeof(struct overlap)); + printf("Got sizeof(struct overlap) = %zu, expected 3.\n", + sizeof(struct overlap)); failures++; } if (o.x != 11) { - fprintf(stderr, "Got o.x = %u, expected 11.\n", o.x); + printf("Got o.x = %u, expected 11.\n", o.x); failures++; } if (o.y != 22) { - fprintf(stderr, "Got o.y = %u, expected 22.\n", o.y); + printf("Got o.y = %u, expected 22.\n", o.y); failures++; } @@ -105,12 +104,12 @@ static void test_overlap(void) o.y = 44; if (o.x != 33) { - fprintf(stderr, "Got o.x = %u, expected 33.\n", o.x); + printf("Got o.x = %u, expected 33.\n", o.x); failures++; } if (o.y != 44) { - fprintf(stderr, "Got o.y = %u, expected 44.\n", o.y); + printf("Got o.y = %u, expected 44.\n", o.y); failures++; } } @@ -120,5 +119,6 @@ int main(void) test_four_bits(); test_four_bits_with_int(); test_overlap(); + printf("failures: %u\n", failures); return failures; } From 2f456ce4e210a4437c8063a3a6579c18dc762afb Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Sun, 28 Jun 2020 21:17:42 +0200 Subject: [PATCH 1370/2161] Add comment explaining four_bits_with_int --- test/val/bitfield.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/val/bitfield.c b/test/val/bitfield.c index b203b9cce..ce791b634 100644 --- a/test/val/bitfield.c +++ b/test/val/bitfield.c @@ -38,6 +38,11 @@ static void test_four_bits(void) } } +/* + Logic is somewhat diferent for bit-fields that end a struct vs + having additional fields. +*/ + static struct four_bits_with_int { unsigned int x : 4; unsigned int y; From 6f85ee9d95b29dbea84fbd641f26acba97a86c3d Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Sun, 28 Jun 2020 21:24:21 +0200 Subject: [PATCH 1371/2161] Add another test for bit-field unit overlap Test when there is another field after bit-fields with allocation unit overlap. --- test/val/bitfield.c | 51 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/test/val/bitfield.c b/test/val/bitfield.c index ce791b634..4298e7d46 100644 --- a/test/val/bitfield.c +++ b/test/val/bitfield.c @@ -119,11 +119,62 @@ static void test_overlap(void) } } +static struct overlap_with_int { + unsigned int x : 10; + unsigned int y : 10; + unsigned int z; +} oi = {111, 222, 333}; + +static void test_overlap_with_int(void) +{ + /* We would like this to be 5. */ + if (sizeof(struct overlap_with_int) != 6) { + printf("Got sizeof(struct overlap_with_int) = %zu, expected 6.\n", + sizeof(struct overlap_with_int)); + failures++; + } + + if (oi.x != 111) { + printf("Got oi.x = %u, expected 111.\n", oi.x); + failures++; + } + + if (oi.y != 222) { + printf("Got oi.y = %u, expected 222.\n", oi.y); + failures++; + } + + if (oi.z != 333) { + printf("Got oi.z = %u, expected 333.\n", oi.z); + failures++; + } + + oi.x = 444; + oi.y = 555; + oi.z = 666; + + if (oi.x != 444) { + printf("Got oi.x = %u, expected 444.\n", oi.x); + failures++; + } + + if (oi.y != 555) { + printf("Got oi.y = %u, expected 555.\n", oi.y); + failures++; + } + + if (oi.z != 666) { + printf("Got oi.z = %u, expected 666.\n", oi.z); + failures++; + } +} + int main(void) { test_four_bits(); test_four_bits_with_int(); test_overlap(); + test_overlap_with_int(); printf("failures: %u\n", failures); return failures; } From 532e6b2554452135dc67ffc5078b5c7ea656991c Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Thu, 2 Jul 2020 09:01:30 +0200 Subject: [PATCH 1372/2161] Add copyright notice --- test/val/bitfield.c | 1 + 1 file changed, 1 insertion(+) diff --git a/test/val/bitfield.c b/test/val/bitfield.c index 4298e7d46..21b45789b 100644 --- a/test/val/bitfield.c +++ b/test/val/bitfield.c @@ -3,6 +3,7 @@ !!ORIGIN!! cc65 regression tests !!LICENCE!! zlib !!AUTHOR!! Jesse Rosenstock + !!COPYRIGHT!! Copyright 2020 Google LLC */ /* From 8449c9eaa03563d64894f462ff604fc9efd498a7 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Thu, 2 Jul 2020 09:08:57 +0200 Subject: [PATCH 1373/2161] Add zlib license text --- test/val/bitfield.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/test/val/bitfield.c b/test/val/bitfield.c index 21b45789b..c249b0f59 100644 --- a/test/val/bitfield.c +++ b/test/val/bitfield.c @@ -1,13 +1,25 @@ /* - !!DESCRIPTION!! Tests of bit-field packing - !!ORIGIN!! cc65 regression tests - !!LICENCE!! zlib - !!AUTHOR!! Jesse Rosenstock - !!COPYRIGHT!! Copyright 2020 Google LLC + Copyright 2020 Google LLC + + 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. */ /* - see https://github.com/cc65/cc65/issues/1054 + Tests of bit-field packing; see https://github.com/cc65/cc65/issues/1054 */ #include <stdio.h> From 359da1ae76fbce6cf017aa48f690c52cfaa26f14 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Wed, 8 Jul 2020 17:11:41 +0200 Subject: [PATCH 1374/2161] Update bit-field tests after #1058 merge --- test/val/bitfield.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/val/bitfield.c b/test/val/bitfield.c index c249b0f59..81d5b2aa1 100644 --- a/test/val/bitfield.c +++ b/test/val/bitfield.c @@ -63,9 +63,9 @@ static struct four_bits_with_int { static void test_four_bits_with_int(void) { - /* We would like this to be 3. https://github.com/cc65/cc65/issues/1054 */ - if (sizeof(struct four_bits_with_int) != 4) { - printf("Got sizeof(struct four_bits_with_int) = %zu, expected 4.\n", + /* The first 4-bit bit-field just takes one byte, so the size is 3. */ + if (sizeof(struct four_bits_with_int) != 3) { + printf("Got sizeof(struct four_bits_with_int) = %zu, expected 3.\n", sizeof(struct four_bits_with_int)); failures++; } @@ -140,9 +140,9 @@ static struct overlap_with_int { static void test_overlap_with_int(void) { - /* We would like this to be 5. */ - if (sizeof(struct overlap_with_int) != 6) { - printf("Got sizeof(struct overlap_with_int) = %zu, expected 6.\n", + /* First two fields in 3 bytes, then another 2 bytes. */ + if (sizeof(struct overlap_with_int) != 5) { + printf("Got sizeof(struct overlap_with_int) = %zu, expected 5.\n", sizeof(struct overlap_with_int)); failures++; } From 9e5b8d99a301066f3c300a48ce836a313693531f Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Wed, 8 Jul 2020 21:28:31 +0200 Subject: [PATCH 1375/2161] Fix MSVC build broken by #1058 MSVC complains about unary negation of unsigned, but it's intended. Suppress the warning. https://github.com/cc65/cc65/pull/1058#discussion_r451757967 "Tested" with godbolt.org. --- src/cc65/declare.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 5e2e204cf..140558ad3 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -772,7 +772,11 @@ static SymEntry* ParseStructDecl (const char* Name) */ if (BitOffs > 0) { if (FieldWidth <= 0 || (BitOffs + FieldWidth) > INT_BITS) { - /* Bits needed to byte-align the next field. */ + /* Bits needed to byte-align the next field. MSVC complains + ** about unary negation of unsigned, but it's intended. + ** Disable the warning for the next line only. + */ + #pragma warning(disable: 4146) unsigned PaddingBits = -BitOffs % CHAR_BITS; /* We need an anonymous name */ From 2c16453a9fab93007d77213d914759120ea36802 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Wed, 8 Jul 2020 22:46:40 +0200 Subject: [PATCH 1376/2161] Guard MSVC pragma with ifdef _MSC_VER Fix broken travis-ci with gcc -Werror [-Werror=unknown-pragmas]. --- src/cc65/declare.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 140558ad3..ab9b45e15 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -776,7 +776,9 @@ static SymEntry* ParseStructDecl (const char* Name) ** about unary negation of unsigned, but it's intended. ** Disable the warning for the next line only. */ + #ifdef _MSC_VER #pragma warning(disable: 4146) + #endif unsigned PaddingBits = -BitOffs % CHAR_BITS; /* We need an anonymous name */ From 82c8bd6e2b9e1c53cfb60462d56ce049a01d0554 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Wed, 8 Jul 2020 23:16:15 +0200 Subject: [PATCH 1377/2161] Replace unary negation with subtraction Remove MSVC pragma. --- src/cc65/declare.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index ab9b45e15..58baaf769 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -772,14 +772,11 @@ static SymEntry* ParseStructDecl (const char* Name) */ if (BitOffs > 0) { if (FieldWidth <= 0 || (BitOffs + FieldWidth) > INT_BITS) { - /* Bits needed to byte-align the next field. MSVC complains - ** about unary negation of unsigned, but it's intended. - ** Disable the warning for the next line only. + /* Bits needed to byte-align the next field. + ** MSVC complains about unary negation of unsigned, + ** so it has been rewritten as subtraction. */ - #ifdef _MSC_VER - #pragma warning(disable: 4146) - #endif - unsigned PaddingBits = -BitOffs % CHAR_BITS; + unsigned PaddingBits = (0 - BitOffs) % CHAR_BITS; /* We need an anonymous name */ AnonName (Ident, "bit-field"); From e98fe04cc282f6d11e0a1b9c208e41917b3d1c2d Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 2 Jul 2020 10:30:02 +0800 Subject: [PATCH 1378/2161] Almost fixed Issue #169. The only denominator not working right now is -2147483648. --- src/cc65/codegen.c | 102 ++++++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 35af5281e..29d14a475 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -1479,48 +1479,9 @@ void g_scale (unsigned flags, long val) /* Scale down */ val = -val; - if ((p2 = PowerOf2 (val)) > 0 && p2 <= 4) { - /* Factor is 2, 4, 8 and 16 use special function */ - switch (flags & CF_TYPEMASK) { - - case CF_CHAR: - if (flags & CF_FORCECHAR) { - if (flags & CF_UNSIGNED) { - while (p2--) { - AddCodeLine ("lsr a"); - } - break; - } else if (p2 <= 2) { - AddCodeLine ("cmp #$80"); - AddCodeLine ("ror a"); - break; - } - } - /* FALLTHROUGH */ - - case CF_INT: - if (flags & CF_UNSIGNED) { - AddCodeLine ("jsr lsrax%d", p2); - } else { - AddCodeLine ("jsr asrax%d", p2); - } - break; - - case CF_LONG: - if (flags & CF_UNSIGNED) { - AddCodeLine ("jsr lsreax%d", p2); - } else { - AddCodeLine ("jsr asreax%d", p2); - } - break; - - default: - typeerror (flags); - - } - - } else if (val != 1) { + /* g_div will use asr if feasible */ + if (val != 1) { /* Use a division instead */ g_div (flags | CF_CONST, val); @@ -2668,11 +2629,52 @@ void g_div (unsigned flags, unsigned long val) "tosdivax", "tosudivax", "tosdiveax", "tosudiveax" }; + unsigned DoShiftLabel, EndLabel; + /* Do strength reduction if the value is constant and a power of two */ int p2; if ((flags & CF_CONST) && (p2 = PowerOf2 (val)) >= 0) { /* Generate a shift instead */ - g_asr (flags, p2); + if (flags & CF_UNSIGNED) { + g_asr (flags, p2); + } else if (p2 > 0) { + /* GitHub #169 - if abs(expr) < abs(val), the result is always 0 */ + DoShiftLabel = GetLocalLabel (); + EndLabel = GetLocalLabel (); + switch (flags & CF_TYPEMASK) { + case CF_CHAR: + if (flags & CF_FORCECHAR) { + AddCodeLine ("cmp #$00"); + AddCodeLine ("bpl %s", LocalLabelName (DoShiftLabel)); + break; + } + /* FALLTHROUGH */ + + case CF_INT: + AddCodeLine ("cpx #$00"); + AddCodeLine ("bpl %s", LocalLabelName (DoShiftLabel)); + break; + + case CF_LONG: + AddCodeLine ("ldy sreg+1"); + AddCodeLine ("bpl %s", LocalLabelName (DoShiftLabel)); + break; + + default: + typeerror (flags); + break; + } + g_save (flags); + g_le (flags, (unsigned long)-(signed long)val); + AddCodeLine ("lsr a"); + g_restore (flags); + AddCodeLine ("bcs %s", LocalLabelName (DoShiftLabel)); + g_getimmed (flags | CF_ABSOLUTE, 0, 0); + g_jump (EndLabel); + g_defcodelabel (DoShiftLabel); + g_asr (flags, p2); + g_defcodelabel (EndLabel); + } } else { /* Generate a division */ if (flags & CF_CONST) { @@ -2956,6 +2958,22 @@ void g_asr (unsigned flags, unsigned long val) switch (flags & CF_TYPEMASK) { case CF_CHAR: + if (flags & CF_FORCECHAR) { + if ((flags & CF_UNSIGNED) != 0 && val <= 4) { + while (val--) { + AddCodeLine ("lsr a"); + } + return; + } else if (val <= 2) { + while (val--) { + AddCodeLine ("cmp #$80"); + AddCodeLine ("ror a"); + } + return; + } + } + /* FALLTHROUGH */ + case CF_INT: val &= 0x0F; if (val >= 8) { From 30835e3d9d929554f443521cd622ce8ac4d1cae8 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 2 Jul 2020 10:30:02 +0800 Subject: [PATCH 1379/2161] More optimized codegen for the correct cases of the Issue #169 fix. --- src/cc65/codegen.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 29d14a475..2e25cb6ad 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -1480,12 +1480,9 @@ void g_scale (unsigned flags, long val) /* Scale down */ val = -val; - /* g_div will use asr if feasible */ + /* Use a division instead */ if (val != 1) { - - /* Use a division instead */ g_div (flags | CF_CONST, val); - } } } @@ -2631,6 +2628,9 @@ void g_div (unsigned flags, unsigned long val) unsigned DoShiftLabel, EndLabel; + /* -Val truncated to the correct size */ + unsigned long NegatedVal; + /* Do strength reduction if the value is constant and a power of two */ int p2; if ((flags & CF_CONST) && (p2 = PowerOf2 (val)) >= 0) { @@ -2641,9 +2641,11 @@ void g_div (unsigned flags, unsigned long val) /* GitHub #169 - if abs(expr) < abs(val), the result is always 0 */ DoShiftLabel = GetLocalLabel (); EndLabel = GetLocalLabel (); + NegatedVal = (unsigned long)-(signed long)val; switch (flags & CF_TYPEMASK) { case CF_CHAR: if (flags & CF_FORCECHAR) { + NegatedVal &= 0xFF; AddCodeLine ("cmp #$00"); AddCodeLine ("bpl %s", LocalLabelName (DoShiftLabel)); break; @@ -2651,11 +2653,13 @@ void g_div (unsigned flags, unsigned long val) /* FALLTHROUGH */ case CF_INT: + NegatedVal &= 0xFFFF; AddCodeLine ("cpx #$00"); AddCodeLine ("bpl %s", LocalLabelName (DoShiftLabel)); break; case CF_LONG: + NegatedVal &= 0xFFFFFFFF; AddCodeLine ("ldy sreg+1"); AddCodeLine ("bpl %s", LocalLabelName (DoShiftLabel)); break; @@ -2665,7 +2669,7 @@ void g_div (unsigned flags, unsigned long val) break; } g_save (flags); - g_le (flags, (unsigned long)-(signed long)val); + g_le (flags | CF_UNSIGNED, NegatedVal); AddCodeLine ("lsr a"); g_restore (flags); AddCodeLine ("bcs %s", LocalLabelName (DoShiftLabel)); From 09bcff08627dc247413ee875519e69455a222320 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 2 Jul 2020 10:30:02 +0800 Subject: [PATCH 1380/2161] Added support for changing divisions by negative power-of-2 denominators into bit shifts, and fixed #169 including the case of -2147483648 which is negative but appears positive. --- src/cc65/codegen.c | 85 +++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 32 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 2e25cb6ad..600bd7bc0 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -2628,24 +2628,34 @@ void g_div (unsigned flags, unsigned long val) unsigned DoShiftLabel, EndLabel; - /* -Val truncated to the correct size */ + /* Deal with negative values as well as different sizes */ + int Negation; unsigned long NegatedVal; + unsigned MaskedVal; /* Do strength reduction if the value is constant and a power of two */ int p2; - if ((flags & CF_CONST) && (p2 = PowerOf2 (val)) >= 0) { - /* Generate a shift instead */ - if (flags & CF_UNSIGNED) { - g_asr (flags, p2); - } else if (p2 > 0) { - /* GitHub #169 - if abs(expr) < abs(val), the result is always 0 */ - DoShiftLabel = GetLocalLabel (); - EndLabel = GetLocalLabel (); - NegatedVal = (unsigned long)-(signed long)val; - switch (flags & CF_TYPEMASK) { + if (flags & CF_CONST) { + Negation = (flags & CF_UNSIGNED) == 0 && (signed long)val < 0; + NegatedVal = (unsigned long)-(signed long)val; + p2 = PowerOf2 (Negation ? NegatedVal : val); + if (p2 >= 0) { + /* Generate a shift instead */ + if (flags & CF_UNSIGNED) { + g_asr (flags, p2); + return; + } + + /* Generate a conditional shift instead */ + if (p2 > 0) { + /* GitHub #169 - if abs(expr) < abs(val), the result is always 0 */ + DoShiftLabel = GetLocalLabel (); + EndLabel = GetLocalLabel (); + MaskedVal = Negation ? val : NegatedVal; + switch (flags & CF_TYPEMASK) { case CF_CHAR: if (flags & CF_FORCECHAR) { - NegatedVal &= 0xFF; + MaskedVal &= 0xFF; AddCodeLine ("cmp #$00"); AddCodeLine ("bpl %s", LocalLabelName (DoShiftLabel)); break; @@ -2653,13 +2663,13 @@ void g_div (unsigned flags, unsigned long val) /* FALLTHROUGH */ case CF_INT: - NegatedVal &= 0xFFFF; + MaskedVal &= 0xFFFF; AddCodeLine ("cpx #$00"); AddCodeLine ("bpl %s", LocalLabelName (DoShiftLabel)); break; case CF_LONG: - NegatedVal &= 0xFFFFFFFF; + MaskedVal &= 0xFFFFFFFF; AddCodeLine ("ldy sreg+1"); AddCodeLine ("bpl %s", LocalLabelName (DoShiftLabel)); break; @@ -2667,27 +2677,38 @@ void g_div (unsigned flags, unsigned long val) default: typeerror (flags); break; + } + g_save (flags); + g_le (flags | CF_UNSIGNED, MaskedVal); + AddCodeLine ("lsr a"); + g_restore (flags); + AddCodeLine ("bcs %s", LocalLabelName (DoShiftLabel)); + g_getimmed (flags | CF_ABSOLUTE, 0, 0); + g_jump (EndLabel); + g_defcodelabel (DoShiftLabel); + g_asr (flags, p2); + g_defcodelabel (EndLabel); } - g_save (flags); - g_le (flags | CF_UNSIGNED, NegatedVal); - AddCodeLine ("lsr a"); - g_restore (flags); - AddCodeLine ("bcs %s", LocalLabelName (DoShiftLabel)); - g_getimmed (flags | CF_ABSOLUTE, 0, 0); - g_jump (EndLabel); - g_defcodelabel (DoShiftLabel); - g_asr (flags, p2); - g_defcodelabel (EndLabel); + + /* Negate the result if val is negative */ + if (Negation) { + g_neg (flags); + } + + /* Done */ + return; } - } else { - /* Generate a division */ - if (flags & CF_CONST) { - /* lhs is not on stack */ - flags &= ~CF_FORCECHAR; /* Handle chars as ints */ - g_push (flags & ~CF_CONST, 0); - } - oper (flags, val, ops); + + /* If we go here, we didn't emit code. Push the lhs on stack and fall + ** into the normal, non-optimized stuff. + */ + flags &= ~CF_FORCECHAR; /* Handle chars as ints */ + g_push (flags & ~CF_CONST, 0); } + + /* Generate a division */ + oper (flags, val, ops); + } From 85e73e91f8eec70c7d598c6b60eabe3fe603edb1 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 3 Jul 2020 16:21:01 +0800 Subject: [PATCH 1381/2161] Only enable signed div replacements with shift according to the code size factor settings. Also with better comments. --- src/cc65/codegen.c | 58 ++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 600bd7bc0..920d8fe90 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -2626,32 +2626,32 @@ void g_div (unsigned flags, unsigned long val) "tosdivax", "tosudivax", "tosdiveax", "tosudiveax" }; - unsigned DoShiftLabel, EndLabel; - - /* Deal with negative values as well as different sizes */ - int Negation; - unsigned long NegatedVal; - unsigned MaskedVal; - /* Do strength reduction if the value is constant and a power of two */ - int p2; if (flags & CF_CONST) { - Negation = (flags & CF_UNSIGNED) == 0 && (signed long)val < 0; - NegatedVal = (unsigned long)-(signed long)val; - p2 = PowerOf2 (Negation ? NegatedVal : val); - if (p2 >= 0) { - /* Generate a shift instead */ - if (flags & CF_UNSIGNED) { - g_asr (flags, p2); - return; - } + /* Deal with negative values as well as different sizes */ + int Negation = (flags & CF_UNSIGNED) == 0 && (long)val < 0; + unsigned long NegatedVal = (unsigned long)-(long)val; + int p2 = PowerOf2 (Negation ? NegatedVal : val); + + /* Generate a shift instead */ + if ((flags & CF_UNSIGNED) != 0 && p2 > 0) { + g_asr (flags, p2); + return; + } + + /* Check if we can afford using shift instead of multiplication at the + ** cost of code size */ + if (p2 == 0 || (p2 > 0 && IS_Get (&CodeSizeFactor) >= (Negation ? 200 : 170))) { /* Generate a conditional shift instead */ if (p2 > 0) { - /* GitHub #169 - if abs(expr) < abs(val), the result is always 0 */ - DoShiftLabel = GetLocalLabel (); - EndLabel = GetLocalLabel (); - MaskedVal = Negation ? val : NegatedVal; + unsigned int DoShiftLabel = GetLocalLabel (); + unsigned int EndLabel = GetLocalLabel (); + unsigned long MaskedVal = Negation ? val : NegatedVal; + + /* GitHub #169 - if abs(expr) < abs(val), the result is always 0. + ** First, check whether expr >= 0 and skip to the shift if true. + */ switch (flags & CF_TYPEMASK) { case CF_CHAR: if (flags & CF_FORCECHAR) { @@ -2678,19 +2678,33 @@ void g_div (unsigned flags, unsigned long val) typeerror (flags); break; } + /* Second, check whether expr <= -asb(val) and skip to the + ** shift if true. The original content of expr has to be saved + ** before the checking comparison and restored after that, as + ** the content in Primary register will be destroyed. + ** The result of the comparison is a boolean. We can store + ** it in the Carry flag with a LSR and branch on it later. + */ g_save (flags); g_le (flags | CF_UNSIGNED, MaskedVal); AddCodeLine ("lsr a"); g_restore (flags); AddCodeLine ("bcs %s", LocalLabelName (DoShiftLabel)); + + /* The result is 0. We can just load 0 and skip the shifting. */ g_getimmed (flags | CF_ABSOLUTE, 0, 0); g_jump (EndLabel); + + /* Do the shift. The sign of the result may need be corrected + ** later. + */ g_defcodelabel (DoShiftLabel); g_asr (flags, p2); g_defcodelabel (EndLabel); } - /* Negate the result if val is negative */ + /* Negate the result as long as val < 0, even if val == -1 and no + ** shift was generated. */ if (Negation) { g_neg (flags); } From 93f0df58e5323be4e4043c5d9e8b6d93ffb7cf9e Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 9 Jul 2020 15:57:51 +0200 Subject: [PATCH 1382/2161] test related to issue #1071 --- test/val/bug1071.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 test/val/bug1071.c diff --git a/test/val/bug1071.c b/test/val/bug1071.c new file mode 100644 index 000000000..02b069de0 --- /dev/null +++ b/test/val/bug1071.c @@ -0,0 +1,87 @@ + +/* test related to issue #1071 */ + +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> + +struct ImageStruct +{ + uint8_t _imageData; + #if !defined(NO_COLOR) + uint8_t _color; + #endif +}; + +typedef struct ImageStruct Image; + +struct CharacterStruct +{ + // character coordinates + uint8_t _x; + uint8_t _y; + + // _status decides whether the character is active + uint8_t _status; + + Image* _imagePtr; +}; + +typedef struct CharacterStruct Character; + +uint16_t ghostLevel; +uint8_t level; +uint16_t loop; + +#define GHOSTS_NUMBER 10 +#define BOMBS_NUMBER 3 + +#define MAX_GHOST_LEVEL_SCALE 3 +#define MAX_GHOST_LEVEL (1400/MAX_GHOST_LEVEL_SCALE) + +#define MAX_GHOST_LOOP_SCALE 3 +#define MAX_GHOST_LOOP (1800/MAX_GHOST_LOOP_SCALE) + +#define INITIAL_GHOST_SLOWDOWN 16000 + +#define ACTION_GHOST_MIN_SLOWDOWN_SCALE 1 +#define GHOST_MIN_SLOWDOWN_SCALE ACTION_GHOST_MIN_SLOWDOWN_SCALE +#define GHOST_MIN_SLOWDOWN (3000/GHOST_MIN_SLOWDOWN_SCALE) + +Character ghosts[GHOSTS_NUMBER]; +Character bombs[BOMBS_NUMBER]; + +uint16_t test1(void) +{ + if((loop<MAX_GHOST_LOOP) && (ghostLevel<MAX_GHOST_LEVEL)) + { + return INITIAL_GHOST_SLOWDOWN-(uint16_t)level*256-ghostLevel*8; + } + return GHOST_MIN_SLOWDOWN; +} + +uint16_t test2(void) +{ + if((loop<MAX_GHOST_LOOP) && (ghostLevel<MAX_GHOST_LEVEL)) + { + return INITIAL_GHOST_SLOWDOWN-(uint16_t)level*256-ghostLevel*16; + } + return GHOST_MIN_SLOWDOWN; +} + +uint16_t res = 0; + +int main(void) +{ + loop = 7; + ghostLevel = 13; + level = 3; + + res = test1(); + printf("test1 res: %d\n", res); + if (res != 15128) return -1; + res = test2(); + printf("test2 res: %d\n", res); + if (res != 15024) return -1; + return 0; +} From 4b8b15a07a96b2daa001081fc7bc3cca5a497957 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 9 Jul 2020 16:05:57 +0200 Subject: [PATCH 1383/2161] tests for issue #169 --- test/val/div-char-char.c | 86 ++++++++++++++++++++++++ test/val/div-common.h | 52 +++++++++++++++ test/val/div-int-int.c | 114 +++++++++++++++++++++++++++++++ test/val/div-long-long.c | 141 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 393 insertions(+) create mode 100644 test/val/div-char-char.c create mode 100644 test/val/div-common.h create mode 100644 test/val/div-int-int.c create mode 100644 test/val/div-long-long.c diff --git a/test/val/div-char-char.c b/test/val/div-char-char.c new file mode 100644 index 000000000..aa86bcd19 --- /dev/null +++ b/test/val/div-char-char.c @@ -0,0 +1,86 @@ +#include <stdint.h> +#include <stdio.h> +#include "div-common.h" + +int res = 0; + +/* we check A_8 and B_8 signed */ +#define TEST(_n,_a,_b,_r) TEST_AB_8(_n,_a,_b,_r) + +#define DO_TEST_A(_n) res += test##_n##a() +#define DO_TEST_B(_n) res += test##_n##b() + +/* arbitrary values */ +TEST(1, 1, 8, 0) +TEST(2, -1, 8, 0) +TEST(3, 1, -8, 0) +TEST(4, -1, -8, 0) +TEST(5, 8, 1, 8) +TEST(6, -8, 1, -8) +TEST(7, 8, -1, -8) +TEST(8, -8, -1, 8) + +TEST(11, 32, 64, 0) +TEST(12, -32, 64, 0) +TEST(13, 32, -64, 0) +TEST(14, -32, -64, 0) +TEST(15, 64, 32, 2) +TEST(16, -64, 32, -2) +TEST(17, 64, -32, -2) +TEST(18, -64, -32, 2) + +/* +128 can't be tested for 8-bit signed char */ +TEST(101, 127, -128, 0) +TEST(102, -127, -128, 0) +TEST(103, -128, -128, 1) + +int main(void) +{ + /* check if the result is correct */ + DO_TEST_A(1); + DO_TEST_A(2); + DO_TEST_A(3); + DO_TEST_A(4); + DO_TEST_A(5); + DO_TEST_A(6); + DO_TEST_A(7); + DO_TEST_A(8); + + DO_TEST_A(11); + DO_TEST_A(12); + DO_TEST_A(13); + DO_TEST_A(14); + DO_TEST_A(15); + DO_TEST_A(16); + DO_TEST_A(17); + DO_TEST_A(18); + + DO_TEST_A(101); + DO_TEST_A(102); + DO_TEST_A(103); + + /* check if the results are equal */ + DO_TEST_B(1); + DO_TEST_B(2); + DO_TEST_B(3); + DO_TEST_B(4); + DO_TEST_B(5); + DO_TEST_B(6); + DO_TEST_B(7); + DO_TEST_B(8); + + DO_TEST_B(11); + DO_TEST_B(12); + DO_TEST_B(13); + DO_TEST_B(14); + DO_TEST_B(15); + DO_TEST_B(16); + DO_TEST_B(17); + DO_TEST_B(18); + + DO_TEST_B(101); + DO_TEST_B(102); + DO_TEST_B(103); + + return res; +} diff --git a/test/val/div-common.h b/test/val/div-common.h new file mode 100644 index 000000000..b67de54dc --- /dev/null +++ b/test/val/div-common.h @@ -0,0 +1,52 @@ +#ifndef DIV_COMMON_H +#define DIV_COMMON_H + +/* check if the result is correct */ +#define TEST_A_T(type, _n,_a,_b,_r) \ + int test##_n##a(void) { \ + typedef type int_t; \ + int_t a = ((int_t)_a), b = ((int_t)_b); \ + if (((a/((int_t)_b)) == ((int_t)_r)) && ((a/b) == ((int_t)_r))) { \ + return 0; \ + } else { \ + printf("%d\tincorrect: a/%ld = %ld, a/b = %ld\n\texpected: %ld/%ld = %ld\n", \ + (_n), (long)((int_t)_b), (long)(a/((int_t)_b)), (long)(a/b), (long)((int_t)_a), (long)((int_t)_b), (long)((int_t)_r)); \ + return 1; \ + } \ + } + +/* check if the results are equal */ +#define TEST_B_T(type, _n,_a,_b,_r) \ + int test##_n##b(void) { \ + typedef type int_t; \ + int_t a = ((int_t)_a), b = ((int_t)_b); \ + if (((a/((int_t)_b)) == (a/b))) { \ + return 0; \ + } else { \ + printf("%d\tnot equal: %ld != %ld, a = %ld, b = %ld\n\texpected: %ld/%ld = %ld\n", \ + (_n), (long)(a/((int_t)_b)), (long)(a/b), (long)(a), (long)(b), (long)((int_t)_a), (long)((int_t)_b), (long)((int_t)_r)); \ + return 1; \ + } \ + } + +#define TEST_A_8(_n,_a,_b,_r) TEST_A_T(int8_t, _n,_a,_b,_r) +#define TEST_B_8(_n,_a,_b,_r) TEST_B_T(int8_t, _n,_a,_b,_r) +#define TEST_A_16(_n,_a,_b,_r) TEST_A_T(int16_t, _n,_a,_b,_r) +#define TEST_B_16(_n,_a,_b,_r) TEST_B_T(int16_t, _n,_a,_b,_r) +#define TEST_A_32(_n,_a,_b,_r) TEST_A_T(int32_t, _n,_a,_b,_r) +#define TEST_B_32(_n,_a,_b,_r) TEST_B_T(int32_t, _n,_a,_b,_r) + +/* A and B */ +#define TEST_AB_8(_n,_a,_b,_r) \ + TEST_A_8(_n,_a,_b,_r) \ + TEST_B_8(_n,_a,_b,_r) + +#define TEST_AB_16(_n,_a,_b,_r) \ + TEST_A_16(_n,_a,_b,_r) \ + TEST_B_16(_n,_a,_b,_r) + +#define TEST_AB_32(_n,_a,_b,_r) \ + TEST_A_32(_n,_a,_b,_r) \ + TEST_B_32(_n,_a,_b,_r) + +#endif diff --git a/test/val/div-int-int.c b/test/val/div-int-int.c new file mode 100644 index 000000000..efcb12a48 --- /dev/null +++ b/test/val/div-int-int.c @@ -0,0 +1,114 @@ +#include <stdint.h> +#include <stdio.h> +#include "div-common.h" + +int res = 0; + +/* we check A_16 and B_16 signed */ +#define TEST(_n,_a,_b,_r) TEST_AB_16(_n,_a,_b,_r) + +#define DO_TEST_A(_n) res += test##_n##a() +#define DO_TEST_B(_n) res += test##_n##b() + +/* arbitrary values */ +TEST(1, 1, 8, 0) +TEST(2, -1, 8, 0) +TEST(3, 1, -8, 0) +TEST(4, -1, -8, 0) +TEST(5, 8, 1, 8) +TEST(6, -8, 1, -8) +TEST(7, 8, -1, -8) +TEST(8, -8, -1, 8) + +TEST(11, 2048, 512, 4) +TEST(12, -2048, 512, -4) +TEST(13, 2048, -512, -4) +TEST(14, -2048, -512, 4) +TEST(15, 512, 2048, 0) +TEST(16, -512, 2048, 0) +TEST(17, 512, -2048, 0) +TEST(18, -512, -2048, 0) + +/* values that are around min/max of the type(s) */ +TEST(101, 127, 128, 0) +TEST(102, -127, 128, 0) +TEST(103, 127, -128, 0) +TEST(104, -127, -128, 0) +TEST(105, 128, 128, 1) +TEST(106, 128, -128, -1) +TEST(107, -128, 128, -1) +TEST(108, -128, -128, 1) + +/* +32768 can't be tested for 16-bit signed short */ +TEST(201, 32767L, -32768L, 0) +TEST(202, 32767L, -32768L, 0) +TEST(203, -32768L, -32768L, 1) + +int main(void) +{ + /* check if the result is correct */ + DO_TEST_A(1); + DO_TEST_A(2); + DO_TEST_A(3); + DO_TEST_A(4); + DO_TEST_A(5); + DO_TEST_A(6); + DO_TEST_A(7); + DO_TEST_A(8); + + DO_TEST_A(11); + DO_TEST_A(12); + DO_TEST_A(13); + DO_TEST_A(14); + DO_TEST_A(15); + DO_TEST_A(16); + DO_TEST_A(17); + DO_TEST_A(18); + + DO_TEST_A(101); + DO_TEST_A(102); + DO_TEST_A(103); + DO_TEST_A(104); + DO_TEST_A(105); + DO_TEST_A(106); + DO_TEST_A(107); + DO_TEST_A(108); + + DO_TEST_A(201); + DO_TEST_A(202); + DO_TEST_A(203); + + /* check if the results are equal */ + DO_TEST_B(1); + DO_TEST_B(2); + DO_TEST_B(3); + DO_TEST_B(4); + DO_TEST_B(5); + DO_TEST_B(6); + DO_TEST_B(7); + DO_TEST_B(8); + + DO_TEST_B(11); + DO_TEST_B(12); + DO_TEST_B(13); + DO_TEST_B(14); + DO_TEST_B(15); + DO_TEST_B(16); + DO_TEST_B(17); + DO_TEST_B(18); + + DO_TEST_B(101); + DO_TEST_B(102); + DO_TEST_B(103); + DO_TEST_B(104); + DO_TEST_B(105); + DO_TEST_B(106); + DO_TEST_B(107); + DO_TEST_B(108); + + DO_TEST_B(201); + DO_TEST_B(202); + DO_TEST_B(203); + + return res; +} diff --git a/test/val/div-long-long.c b/test/val/div-long-long.c new file mode 100644 index 000000000..d2553e3c3 --- /dev/null +++ b/test/val/div-long-long.c @@ -0,0 +1,141 @@ +#include <stdint.h> +#include <stdio.h> +#include "div-common.h" + +int res = 0; + +/* we check A_32 and B_32 signed */ +#define TEST(_n,_a,_b,_r) TEST_AB_32(_n,_a,_b,_r) + +#define DO_TEST_A(_n) res += test##_n##a() +#define DO_TEST_B(_n) res += test##_n##b() + +/* arbitrary values */ +TEST(1, 1, 8, 0) +TEST(2, -1, 8, 0) +TEST(3, 1, -8, 0) +TEST(4, -1, -8, 0) +TEST(5, 8, 1, 8) +TEST(6, -8, 1, -8) +TEST(7, 8, -1, -8) +TEST(8, -8, -1, 8) + +TEST(11, 2048, 512, 4) +TEST(12, -2048, 512, -4) +TEST(13, 2048, -512, -4) +TEST(14, -2048, -512, 4) +TEST(15, 512, 2048, 0) +TEST(16, -512, 2048, 0) +TEST(17, 512, -2048, 0) +TEST(18, -512, -2048, 0) + +/* values that are around min/max of the type(s) */ +TEST(101, 127, 128, 0) +TEST(102, -127, 128, 0) +TEST(103, 127, -128, 0) +TEST(104, -127, -128, 0) +TEST(105, 128, 128, 1) +TEST(106, 128, -128, -1) +TEST(107, -128, 128, -1) +TEST(108, -128, -128, 1) + +TEST(201, 32767L, 32768L, 0) +TEST(202, -32767L, 32768L, 0) +TEST(203, 32767L, -32768L, 0) +TEST(204, 32767L, -32768L, 0) +TEST(205, 32768L, 32768L, 1) +TEST(206, 32768L, -32768L, -1) +TEST(207, -32768L, 32768L, -1) +TEST(208, -32768L, -32768L, 1) + +/* +2147483648 can't be tested for 32-bit signed long */ +TEST(401, 2147483647UL, -2147483648UL, 0) +TEST(402, -2147483647UL, -2147483648UL, 0) +TEST(403, -2147483648UL, -2147483648UL, 1) + +int main(void) +{ + /* check if the result is correct */ + DO_TEST_A(1); + DO_TEST_A(2); + DO_TEST_A(3); + DO_TEST_A(4); + DO_TEST_A(5); + DO_TEST_A(6); + DO_TEST_A(7); + DO_TEST_A(8); + + DO_TEST_A(11); + DO_TEST_A(12); + DO_TEST_A(13); + DO_TEST_A(14); + DO_TEST_A(15); + DO_TEST_A(16); + DO_TEST_A(17); + DO_TEST_A(18); + + DO_TEST_A(101); + DO_TEST_A(102); + DO_TEST_A(103); + DO_TEST_A(104); + DO_TEST_A(105); + DO_TEST_A(106); + DO_TEST_A(107); + DO_TEST_A(108); + + DO_TEST_A(201); + DO_TEST_A(202); + DO_TEST_A(203); + DO_TEST_A(204); + DO_TEST_A(205); + DO_TEST_A(206); + DO_TEST_A(207); + DO_TEST_A(208); + + DO_TEST_A(401); + DO_TEST_A(402); + DO_TEST_A(403); + + /* check if the results are equal */ + DO_TEST_B(1); + DO_TEST_B(2); + DO_TEST_B(3); + DO_TEST_B(4); + DO_TEST_B(5); + DO_TEST_B(6); + DO_TEST_B(7); + DO_TEST_B(8); + + DO_TEST_B(11); + DO_TEST_B(12); + DO_TEST_B(13); + DO_TEST_B(14); + DO_TEST_B(15); + DO_TEST_B(16); + DO_TEST_B(17); + DO_TEST_B(18); + + DO_TEST_B(101); + DO_TEST_B(102); + DO_TEST_B(103); + DO_TEST_B(104); + DO_TEST_B(105); + DO_TEST_B(106); + DO_TEST_B(107); + DO_TEST_B(108); + + DO_TEST_B(201); + DO_TEST_B(202); + DO_TEST_B(203); + DO_TEST_B(204); + DO_TEST_B(205); + DO_TEST_B(206); + DO_TEST_B(207); + DO_TEST_B(208); + + DO_TEST_B(401); + DO_TEST_B(402); + DO_TEST_B(403); + + return res; +} From 5925a7f8eec335b5c566c93c345ab044e1fc8b23 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 9 Jul 2020 16:16:46 +0200 Subject: [PATCH 1384/2161] test for issue #1077 --- test/todo/bug1077.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 test/todo/bug1077.c diff --git a/test/todo/bug1077.c b/test/todo/bug1077.c new file mode 100644 index 000000000..2fb3ef168 --- /dev/null +++ b/test/todo/bug1077.c @@ -0,0 +1,31 @@ +/* bug #1077 - Wrong code: a non-array constant address with a non-constant subscript */ + +#include <stdlib.h> +#include <stdio.h> + +int test1(void) +{ + int a = 0; + (&a)[a] = 42; + return a; +} +int test2(void) +{ + int a = 0; + int b = 0; + (&a)[b] = 42; + return a; +} + +int main(void) +{ + int res, ret = EXIT_SUCCESS; + res = test1(); + printf("%d\n", res); + if (res != 42) ret = EXIT_FAILURE; + res = test2(); + printf("%d\n", res); + if (res != 42) ret = EXIT_FAILURE; + + return ret; +} From ff18218b0a42cc07e42869622fb395d18301ca33 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 9 Jul 2020 16:17:16 +0200 Subject: [PATCH 1385/2161] test for issue #170 --- test/todo/bug170.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 test/todo/bug170.c diff --git a/test/todo/bug170.c b/test/todo/bug170.c new file mode 100644 index 000000000..ac54d54d8 --- /dev/null +++ b/test/todo/bug170.c @@ -0,0 +1,40 @@ +/* bug #170 - Wrong implicit conversion of integers */ + +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> + +int main(void) +{ + uint8_t c = 2; + uint32_t u = 2; + int16_t a = -2; + int32_t l = -2; + + /* Generated code should use tosmulax but uses tosumulax */ + int16_t r = c * a; + /* Generated code should use tosmuleax but uses tosumuleax */ + int32_t lr = u * l; + + int32_t n = -95; + uint16_t d = 3; + int16_t r1 = n / d; // produces 21813 instead of -31 + + int16_t r2 = n / (int32_t) d; // workaround + + printf("r: %d (-4)\n", r); +#ifdef REFERENCE + printf("lr: %d (-4)\n", lr); +#else + printf("lr: %ld (-4)\n", lr); +#endif + printf("r1: %d (-31)\n", r1); + printf("r2: %d (-31)\n", r2); + + if (r != -4) { return EXIT_FAILURE; } + if (lr != -4) { return EXIT_FAILURE; } + if (r1 != -31) { return EXIT_FAILURE; } + if (r2 != -31) { return EXIT_FAILURE; } + + return EXIT_SUCCESS; +} From 2428285694099da27a4a4cff1ed9c446ca2d4f9e Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 9 Jul 2020 16:17:31 +0200 Subject: [PATCH 1386/2161] test for issue #327 --- test/todo/bug327.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 test/todo/bug327.c diff --git a/test/todo/bug327.c b/test/todo/bug327.c new file mode 100644 index 000000000..f6a79962b --- /dev/null +++ b/test/todo/bug327.c @@ -0,0 +1,34 @@ +/* bug #327 - Promoting u8 to s16 gives wrong result */ + +#include <stdio.h> +#include <stdint.h> + +static const uint8_t arr[2] = { + 0, + 255 +}; + +static int16_t get16() { + return -arr[1]; +} + +static int16_t get16_2() { + return -(int16_t) arr[1]; +} + +char res = 0; + +int main() { + + printf("Value %d, should be -255\n", get16()); + printf("Value %d, should be -255\n", get16_2()); + + if (get16() != -255) { + res++; + } + if (get16_2() != -255) { + res++; + } + + return res; +} From 579b50f0c5f068d0194fd6f2a19f7054b7c6945a Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 9 Jul 2020 16:18:08 +0200 Subject: [PATCH 1387/2161] test for issue #927 --- test/todo/bug927.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 test/todo/bug927.c diff --git a/test/todo/bug927.c b/test/todo/bug927.c new file mode 100644 index 000000000..e0f916e66 --- /dev/null +++ b/test/todo/bug927.c @@ -0,0 +1,47 @@ + +/* bug #927: format specifiers related to leading zeros do not work as expected */ + +/* expected output: +0023 +0023 +-0023 +-023 +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +char b1[10]; +char b2[10]; +char b3[10]; +char b4[10]; + +int main(void) { + printf("%.4d\n", 23); + printf("%04d\n", 23); + printf("%.4d\n", -23); + printf("%04d\n\n", -23); + + sprintf(b1, "%.4d", 23); + sprintf(b2, "%04d", 23); + sprintf(b3, "%.4d", -23); + sprintf(b4, "%04d", -23); + + printf("%s\n", b1); + printf("%s\n", b2); + printf("%s\n", b3); + printf("%s\n\n", b4); + + printf("%d\n", strcmp(b1, "0023")); + printf("%d\n", strcmp(b2, "0023")); + printf("%d\n", strcmp(b3, "-0023")); + printf("%d\n", strcmp(b4, "-023")); + + if(strcmp(b1, "0023") != 0) return EXIT_FAILURE; + if(strcmp(b2, "0023") != 0) return EXIT_FAILURE; + if(strcmp(b3, "-0023") != 0) return EXIT_FAILURE; + if(strcmp(b4, "-023") != 0) return EXIT_FAILURE; + + return EXIT_SUCCESS; +} From f5afc75cbdb5cba180467185f1d8a45de6e3a005 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Thu, 9 Jul 2020 21:18:42 +0200 Subject: [PATCH 1388/2161] ar65/LibClose: Include filename in error messages ``` ar65: Error: Problem deleting temporary library file '../lib/apple2enh.lib.temp': No such file or directory ``` is the error I'm getting with `make -j 19` when trying to debug #1080. --- src/ar65/library.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ar65/library.c b/src/ar65/library.c index 4d18168d8..08fdeb563 100644 --- a/src/ar65/library.c +++ b/src/ar65/library.c @@ -399,9 +399,11 @@ void LibClose (void) Error ("Problem closing '%s': %s", LibName, strerror (errno)); } if (NewLib && fclose (NewLib) != 0) { - Error ("Problem closing temporary library file: %s", strerror (errno)); + Error ("Problem closing temporary library file '%s': %s", + NewLibName, strerror (errno)); } if (NewLibName && remove (NewLibName) != 0) { - Error ("Problem deleting temporary library file: %s", strerror (errno)); + Error ("Problem deleting temporary library file '%s': %s", + NewLibName, strerror (errno)); } } From 878e4a57c8197485d02e1be0e90a7144a37e4203 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@users.noreply.github.com> Date: Thu, 2 Jul 2020 08:57:11 +0200 Subject: [PATCH 1389/2161] Make Makefiles more -j friendly Add .$1.$2 to outputs missing them. --- test/Makefile | 2 -- test/asm/Makefile | 3 +++ test/misc/Makefile | 8 ++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/test/Makefile b/test/Makefile index c85883517..fc1ac246c 100644 --- a/test/Makefile +++ b/test/Makefile @@ -16,8 +16,6 @@ WORKDIR = ../testwrk all: dotests -.NOTPARALLEL: - dotests: mostlyclean continue continue: diff --git a/test/asm/Makefile b/test/asm/Makefile index 93210aaee..62f2f8dd1 100644 --- a/test/asm/Makefile +++ b/test/asm/Makefile @@ -41,6 +41,9 @@ CPUDETECT_BINS = $(foreach cpu,$(CPUDETECT_CPUS),$(WORKDIR)/$(cpu)-cpudetect.bin all: $(OPCODE_BINS) $(CPUDETECT_BINS) +# cpudetect.o is written by multiple rules +.NOTPARALLEL: + $(WORKDIR): $(call MKDIR,$(WORKDIR)) diff --git a/test/misc/Makefile b/test/misc/Makefile index 15999ba3c..1d6b2b9d2 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -69,13 +69,13 @@ $(WORKDIR)/endless.$1.$2.prg: endless.c | $(WORKDIR) $(WORKDIR)/limits.$1.$2.prg: limits.c $(DIFF) $(if $(QUIET),echo misc/limits.$1.$2.prg) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/limits.$1.out - $(DIFF) $(WORKDIR)/limits.$1.out limits.ref + $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/limits.$1.$2.out + $(DIFF) $(WORKDIR)/limits.$1.$2.out limits.ref $(WORKDIR)/goto.$1.$2.prg: goto.c $(DIFF) $(if $(QUIET),echo misc/goto.$1.$2.prg) - $(CL65) -t sim$2 -$1 -o $$@ $$< 2>$(WORKDIR)/goto.$1.out - $(DIFF) $(WORKDIR)/goto.$1.out goto.ref + $(CL65) -t sim$2 -$1 -o $$@ $$< 2>$(WORKDIR)/goto.$1.$2.out + $(DIFF) $(WORKDIR)/goto.$1.$2.out goto.ref # the rest are tests that fail currently for one reason or another $(WORKDIR)/fields.$1.$2.prg: fields.c | $(WORKDIR) From 3999f2ad75e053dbddff08b1a98204b9ec6e4ce3 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Fri, 10 Jul 2020 11:48:47 +0200 Subject: [PATCH 1390/2161] Move .NOTPARALLEL closer to rule that needs it --- test/asm/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/asm/Makefile b/test/asm/Makefile index 62f2f8dd1..a0825574c 100644 --- a/test/asm/Makefile +++ b/test/asm/Makefile @@ -41,9 +41,6 @@ CPUDETECT_BINS = $(foreach cpu,$(CPUDETECT_CPUS),$(WORKDIR)/$(cpu)-cpudetect.bin all: $(OPCODE_BINS) $(CPUDETECT_BINS) -# cpudetect.o is written by multiple rules -.NOTPARALLEL: - $(WORKDIR): $(call MKDIR,$(WORKDIR)) @@ -61,6 +58,9 @@ endef # OPCODE_template $(foreach cpu,$(OPCODE_CPUS),$(eval $(call OPCODE_template,$(cpu)))) +# cpudetect.o is written by multiple rules +.NOTPARALLEL: + define CPUDETECT_template $(WORKDIR)/$1-cpudetect.bin: cpudetect.s $(DIFF) From df975704719a92ba58294c8b2c12d14634495078 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Fri, 10 Jul 2020 11:49:19 +0200 Subject: [PATCH 1391/2161] Set .NOTPARALLEL in test/misc and test/val The cl65 intermediate files stomp each other in these directories. --- test/misc/Makefile | 5 +++++ test/val/Makefile | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/test/misc/Makefile b/test/misc/Makefile index 1d6b2b9d2..cda0c789a 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -50,6 +50,11 @@ TESTS += $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).65c02. all: $(TESTS) +# The same input file is processed with different cl65 args, +# but cl65 uses the input file name to make the temp file name, +# and they stomp each other. +.NOTPARALLEL: + $(WORKDIR): $(call MKDIR,$(WORKDIR)) diff --git a/test/val/Makefile b/test/val/Makefile index df1d314e4..417c0b6c8 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -41,6 +41,11 @@ TESTS += $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).65c02. all: $(TESTS) +# The same input file is processed with different cl65 args, +# but cl65 uses the input file name to make the temp file name, +# and they stomp each other. +.NOTPARALLEL: + $(WORKDIR): $(call MKDIR,$(WORKDIR)) From 695b1b01d8deaaf2c4a9122681e95b266a2688f1 Mon Sep 17 00:00:00 2001 From: compyx <b.wassink@ziggo.nl> Date: Fri, 10 Jul 2020 19:35:23 +0200 Subject: [PATCH 1392/2161] C64 soft80 conio: save 6 bytes in `firstinit` As a bonus, save 6 cycles. --- libsrc/c64/soft80_conio.s | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/libsrc/c64/soft80_conio.s b/libsrc/c64/soft80_conio.s index 48039d288..355ae51a0 100644 --- a/libsrc/c64/soft80_conio.s +++ b/libsrc/c64/soft80_conio.s @@ -67,22 +67,20 @@ firstinit: inc soft80_first_init - lda #<soft80_charset + ; save 6 bytes due to soft80_charset, soft80_lo_charset and + ; soft80_hi_charset being page-aligned. + ldy #0 ldx #>soft80_charset - sta ptr1 + sty ptr1 stx ptr1+1 - lda #<soft80_lo_charset ldx #>soft80_lo_charset - sta ptr2 + sty ptr2 stx ptr2+1 - lda #<soft80_hi_charset ldx #>soft80_hi_charset - sta ptr3 + sty ptr3 stx ptr3+1 ldx #4 -@l2: - ldy #0 @l1: lda (ptr1),y sta (ptr2),y @@ -97,17 +95,17 @@ firstinit: inc ptr2+1 inc ptr3+1 dex - bne @l2 + bne @l1 ; copy the kplot tables to ram under I/O ;ldx #0 ; is 0 -@l3: +@l2: lda soft80_tables_data_start,x sta soft80_bitmapxlo,x lda soft80_tables_data_start + (soft80_tables_data_end - soft80_tables_data_start - $0100),x sta soft80_bitmapxlo + (soft80_tables_data_end - soft80_tables_data_start - $0100),x inx - bne @l3 + bne @l2 pla sta $01 From fb7996b0ce66be7675cb856d53780e73b5f3d5fd Mon Sep 17 00:00:00 2001 From: compyx <b.wassink@ziggo.nl> Date: Fri, 10 Jul 2020 19:56:34 +0200 Subject: [PATCH 1393/2161] Revert "C64 soft80 conio: save 6 bytes in `firstinit`" This reverts commit 943e68be6a3b48529540e8f86061f171634f80f9. --- libsrc/c64/soft80_conio.s | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/libsrc/c64/soft80_conio.s b/libsrc/c64/soft80_conio.s index 355ae51a0..48039d288 100644 --- a/libsrc/c64/soft80_conio.s +++ b/libsrc/c64/soft80_conio.s @@ -67,20 +67,22 @@ firstinit: inc soft80_first_init - ; save 6 bytes due to soft80_charset, soft80_lo_charset and - ; soft80_hi_charset being page-aligned. - ldy #0 + lda #<soft80_charset ldx #>soft80_charset - sty ptr1 + sta ptr1 stx ptr1+1 + lda #<soft80_lo_charset ldx #>soft80_lo_charset - sty ptr2 + sta ptr2 stx ptr2+1 + lda #<soft80_hi_charset ldx #>soft80_hi_charset - sty ptr3 + sta ptr3 stx ptr3+1 ldx #4 +@l2: + ldy #0 @l1: lda (ptr1),y sta (ptr2),y @@ -95,17 +97,17 @@ firstinit: inc ptr2+1 inc ptr3+1 dex - bne @l1 + bne @l2 ; copy the kplot tables to ram under I/O ;ldx #0 ; is 0 -@l2: +@l3: lda soft80_tables_data_start,x sta soft80_bitmapxlo,x lda soft80_tables_data_start + (soft80_tables_data_end - soft80_tables_data_start - $0100),x sta soft80_bitmapxlo + (soft80_tables_data_end - soft80_tables_data_start - $0100),x inx - bne @l2 + bne @l3 pla sta $01 From e45e57d7ce95ffce2b39f7bb5bffc974782c93a1 Mon Sep 17 00:00:00 2001 From: compyx <b.wassink@ziggo.nl> Date: Fri, 10 Jul 2020 20:08:44 +0200 Subject: [PATCH 1394/2161] C64 soft80 conio: save 4 bytes in `firstinit` Also save 6 cycles as a very small bonus. --- libsrc/c64/soft80_conio.s | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/libsrc/c64/soft80_conio.s b/libsrc/c64/soft80_conio.s index 48039d288..4291c2078 100644 --- a/libsrc/c64/soft80_conio.s +++ b/libsrc/c64/soft80_conio.s @@ -67,22 +67,21 @@ firstinit: inc soft80_first_init + ; save 4 bytes due to soft80_lo_charset and soft80_hi_charset being + ; page-aligned. + ldy #0 lda #<soft80_charset ldx #>soft80_charset sta ptr1 stx ptr1+1 - lda #<soft80_lo_charset ldx #>soft80_lo_charset - sta ptr2 + sty ptr2 stx ptr2+1 - lda #<soft80_hi_charset ldx #>soft80_hi_charset - sta ptr3 + sty ptr3 stx ptr3+1 ldx #4 -@l2: - ldy #0 @l1: lda (ptr1),y sta (ptr2),y @@ -97,17 +96,17 @@ firstinit: inc ptr2+1 inc ptr3+1 dex - bne @l2 + bne @l1 ; copy the kplot tables to ram under I/O ;ldx #0 ; is 0 -@l3: +@l2: lda soft80_tables_data_start,x sta soft80_bitmapxlo,x lda soft80_tables_data_start + (soft80_tables_data_end - soft80_tables_data_start - $0100),x sta soft80_bitmapxlo + (soft80_tables_data_end - soft80_tables_data_start - $0100),x inx - bne @l3 + bne @l2 pla sta $01 From 2c4dd5decf27ad2c0e10df920e63d9f9fc03cb4a Mon Sep 17 00:00:00 2001 From: compyx <b.wassink@ziggo.nl> Date: Sat, 11 Jul 2020 09:39:21 +0200 Subject: [PATCH 1395/2161] Shorten comment as requested --- libsrc/c64/soft80_conio.s | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libsrc/c64/soft80_conio.s b/libsrc/c64/soft80_conio.s index 4291c2078..7036f384d 100644 --- a/libsrc/c64/soft80_conio.s +++ b/libsrc/c64/soft80_conio.s @@ -67,8 +67,7 @@ firstinit: inc soft80_first_init - ; save 4 bytes due to soft80_lo_charset and soft80_hi_charset being - ; page-aligned. + ; soft80_lo_charset and soft80_hi_charset are page-aligned ldy #0 lda #<soft80_charset ldx #>soft80_charset From 381a32d9aa44fc49c9d34e812212405bde24f4af Mon Sep 17 00:00:00 2001 From: compyx <b.wassink@ziggo.nl> Date: Sat, 11 Jul 2020 13:18:14 +0200 Subject: [PATCH 1396/2161] C64 soft80-conio cgetc: save 14 cycles in `invertcursor` By 'inverting' the loop, we can save 16 cycles by removing the `cpy #8`, saving 16 cycles. But we need an extra `ldy #7` at the start of the loop, so the total cycles saved is 14. Code size doesn't increase due to the addition of the `ldy #7` negating the removal of the `cpy #xx`. --- libsrc/c64/soft80_cgetc.s | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libsrc/c64/soft80_cgetc.s b/libsrc/c64/soft80_cgetc.s index 05e9e5b47..aa12cd8ca 100644 --- a/libsrc/c64/soft80_cgetc.s +++ b/libsrc/c64/soft80_cgetc.s @@ -46,17 +46,16 @@ invertcursor: lda #$34 sta $01 - ldy #$00 jsr setcolor ldx soft80_internal_cursorxlsb + ldy #7 @lp1: lda (SCREEN_PTR),y eor nibble,x sta (SCREEN_PTR),y - iny - cpy #8 - bne @lp1 + dey + bpl @lp1 pla sta $01 ; enable I/O @@ -67,7 +66,7 @@ invertcursor: ; shown using the current textcolor without disturbing the "color voodoo" ; in soft80_cputc setcolor: - ;ldy #0 ; is 0 + ldy #0 bcs @set ; restore old value lda tmp1 From 7d652d42dc7616cf4024aff301e6fc257ee4aa0a Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 2 Jul 2020 10:30:02 +0800 Subject: [PATCH 1397/2161] Added a warning on promoting a decimal constant without a 'u'/'U' suffix to unsigned long. --- src/cc65/scanner.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 3e829aabb..91abd332d 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -530,10 +530,12 @@ static void NumericConst (void) if (!IsFloat) { unsigned Types; - int HaveSuffix; + unsigned WarnTypes = 0; - /* Check for a suffix and determine the possible types */ - HaveSuffix = 1; + /* Check for a suffix and determine the possible types. It is always + ** possible to convert the data to unsigned long even if the IT_ULONG + ** flag were not set, but we are not doing that. + */ if (toupper (CurC) == 'U') { /* Unsigned type */ NextChar (); @@ -548,17 +550,18 @@ static void NumericConst (void) NextChar (); if (toupper (CurC) != 'U') { Types = IT_LONG | IT_ULONG; + WarnTypes = IT_ULONG; } else { NextChar (); Types = IT_ULONG; } } else { - HaveSuffix = 0; if (Prefix == 10) { /* Decimal constants are of any type but uint */ Types = IT_INT | IT_LONG | IT_ULONG; + WarnTypes = IT_LONG | IT_ULONG; } else { - /* Octal or hex constants are of any type */ + /* Binary, octal or hex constants can be of any type */ Types = IT_INT | IT_UINT | IT_LONG | IT_ULONG; } } @@ -568,11 +571,14 @@ static void NumericConst (void) /* Out of range for int */ Types &= ~IT_INT; /* If the value is in the range 0x8000..0xFFFF, unsigned int is not - ** allowed, and we don't have a type specifying suffix, emit a - ** warning, because the constant is of type long. + ** allowed, and we don't have a long type specifying suffix, emit a + ** warning, because the constant is of type long while the user + ** might expect an unsigned int. */ - if (IVal <= 0xFFFF && (Types & IT_UINT) == 0 && !HaveSuffix) { - Warning ("Constant is long"); + if (IVal <= 0xFFFF && + (Types & IT_UINT) == 0 && + (WarnTypes & IT_LONG) != 0) { + Warning ("Integer constant is long"); } } if (IVal > 0xFFFF) { @@ -582,6 +588,15 @@ static void NumericConst (void) if (IVal > 0x7FFFFFFF) { /* Out of range for long int */ Types &= ~IT_LONG; + /* If the value is in the range 0x80000000..0xFFFFFFFF, decimal, + ** and we have no unsigned type specifying suffix, emit a warning, + ** because the constant is of type unsigned long while the user + ** might expect a signed integer constant, especially if there is + ** a preceding unary op or when it is used in constant calculation. + */ + if (WarnTypes & IT_ULONG) { + Warning ("Integer constant is unsigned long"); + } } /* Now set the type string to the smallest type in types */ From 727040d1ac77bff60628b87256c7bb8054fd4c02 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 12 Jul 2020 12:18:55 +0800 Subject: [PATCH 1398/2161] Comment fix. --- 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 91abd332d..5040cdf08 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -561,7 +561,7 @@ static void NumericConst (void) Types = IT_INT | IT_LONG | IT_ULONG; WarnTypes = IT_LONG | IT_ULONG; } else { - /* Binary, octal or hex constants can be of any type */ + /* Binary, octal and hex constants can be of any type */ Types = IT_INT | IT_UINT | IT_LONG | IT_ULONG; } } From 04cc463452de739262b91ef1fa4757ad249d6762 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 12 Jul 2020 22:19:38 +0200 Subject: [PATCH 1399/2161] Implemented some CONIO peek functions. Please refer to https://github.com/cc65/cc65/pull/532 for background info. I wrote in https://sourceforge.net/p/cc65/mailman/message/35873183/ === cputs() wraps to the next line if the strings is too long to fit in the current line. I don't know if it's worth the effort to allow cpeeks() to continue reading from the next line. I'd like to discuss this aspect with the actual implementers. === This is still as unclear today as it was when I wrote the above. Therefore this change just doesn't add cpeeks() at all. Since https://github.com/cc65/cc65/commit/f8c6c58373426551eed096dcfab4eab137fc0430 the Apple II CONIO implementation doesn't "need" revers() anymore - meaning that (nearly) every possible value can be placed in VRAM with a straight cputc() (without the need for a previous revers(1)). The implementation of cpeekc() leverages that cputc() ability by always returning the value that can be fed into cputc() without a previous revers(1). Accordingly, cpeekrevers() always returns 0. So after the sequence revers(1); cputc(x); a cpeekc() will return a value different from x! However, I don't see this behavior braking the cpeekc() contract. I see the cpeekc() contract being defined by the sequence textcolor(cpeekcolor()); revers(cpeekrevers()); cputc(cpeekc()); placing the very same value in VRAM that there was before. And that contract is fulfilled. --- include/apple2.h | 2 ++ include/conio.h | 11 +++++++---- libsrc/apple2/cpeekc.s | 28 ++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 libsrc/apple2/cpeekc.s diff --git a/include/apple2.h b/include/apple2.h index dbed3364d..57d7086ce 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -207,6 +207,8 @@ void rebootafterexit (void); #define _textcolor(color) COLOR_WHITE #define _bgcolor(color) COLOR_BLACK #define _bordercolor(color) COLOR_BLACK +#define _cpeekcolor() COLOR_WHITE +#define _cpeekrevers() 0 diff --git a/include/conio.h b/include/conio.h index 72421af86..bac20e3c5 100644 --- a/include/conio.h +++ b/include/conio.h @@ -201,16 +201,19 @@ void __fastcall__ cputhex16 (unsigned val); */ #ifdef _textcolor -# define textcolor(x) _textcolor(x) +# define textcolor(color) _textcolor(color) #endif #ifdef _bgcolor -# define bgcolor(x) _bgcolor(x) +# define bgcolor(color) _bgcolor(color) #endif #ifdef _bordercolor -# define bordercolor(x) _bordercolor(x) +# define bordercolor(color) _bordercolor(color) #endif #ifdef _cpeekcolor -# define cpeekcolor(x) _cpeekcolor(x) +# define cpeekcolor() _cpeekcolor() +#endif +#ifdef _cpeekrevers +# define cpeekrevers() _cpeekrevers() #endif diff --git a/libsrc/apple2/cpeekc.s b/libsrc/apple2/cpeekc.s new file mode 100644 index 000000000..a547f7867 --- /dev/null +++ b/libsrc/apple2/cpeekc.s @@ -0,0 +1,28 @@ +; +; 2020-07-12, Oliver Schmidt +; +; char cpeekc (void); +; + + .export _cpeekc + + .include "apple2.inc" + +_cpeekc: + ldy CH + .ifdef __APPLE2ENH__ + 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 + bit HISCR ; Assume SET80COL + .endif +peek: lda (BASL),Y ; Get character + .ifdef __APPLE2ENH__ + bit LOWSCR ; Doesn't hurt in 40 column mode + .endif + eor #$80 ; Invert high bit + ldx #$00 + rts From bcb8b4990726e9add92ae54d70204e49977f50e5 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 12 Jul 2020 23:11:43 +0200 Subject: [PATCH 1400/2161] Removed executable bit. --- libsrc/c128/emd/c128-efnram.s | 0 libsrc/c128/emd/c128-ifnram.s | 0 libsrc/c64/acc_c65_speed.s | 0 libsrc/c64/acc_chameleon_speed.s | 0 libsrc/c64/acc_detect_c65.s | 0 libsrc/c64/acc_detect_chameleon.s | 0 libsrc/c64/acc_detect_turbomaster.s | 0 libsrc/c64/acc_turbomaster_speed.s | 0 libsrc/cbm510/pencalib.c | 0 libsrc/vic20/emd/vic20-georam.s | 0 samples/supervisionhello.c | 0 test/ref/cf.in | 0 test/ref/yacc.in | 0 test/val/add3a.c | 0 test/val/casttochar.c | 0 test/val/cc65141002.c | 0 test/val/cc65141011.c | 0 test/val/cc65141022.c | 0 testcode/lib/accelerator/chameleon-test.c | 0 testcode/lib/accelerator/turbomaster-test.c | 0 20 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 libsrc/c128/emd/c128-efnram.s mode change 100755 => 100644 libsrc/c128/emd/c128-ifnram.s mode change 100755 => 100644 libsrc/c64/acc_c65_speed.s mode change 100755 => 100644 libsrc/c64/acc_chameleon_speed.s mode change 100755 => 100644 libsrc/c64/acc_detect_c65.s mode change 100755 => 100644 libsrc/c64/acc_detect_chameleon.s mode change 100755 => 100644 libsrc/c64/acc_detect_turbomaster.s mode change 100755 => 100644 libsrc/c64/acc_turbomaster_speed.s mode change 100755 => 100644 libsrc/cbm510/pencalib.c mode change 100755 => 100644 libsrc/vic20/emd/vic20-georam.s mode change 100755 => 100644 samples/supervisionhello.c mode change 100755 => 100644 test/ref/cf.in mode change 100755 => 100644 test/ref/yacc.in mode change 100755 => 100644 test/val/add3a.c mode change 100755 => 100644 test/val/casttochar.c mode change 100755 => 100644 test/val/cc65141002.c mode change 100755 => 100644 test/val/cc65141011.c mode change 100755 => 100644 test/val/cc65141022.c mode change 100755 => 100644 testcode/lib/accelerator/chameleon-test.c mode change 100755 => 100644 testcode/lib/accelerator/turbomaster-test.c diff --git a/libsrc/c128/emd/c128-efnram.s b/libsrc/c128/emd/c128-efnram.s old mode 100755 new mode 100644 diff --git a/libsrc/c128/emd/c128-ifnram.s b/libsrc/c128/emd/c128-ifnram.s old mode 100755 new mode 100644 diff --git a/libsrc/c64/acc_c65_speed.s b/libsrc/c64/acc_c65_speed.s old mode 100755 new mode 100644 diff --git a/libsrc/c64/acc_chameleon_speed.s b/libsrc/c64/acc_chameleon_speed.s old mode 100755 new mode 100644 diff --git a/libsrc/c64/acc_detect_c65.s b/libsrc/c64/acc_detect_c65.s old mode 100755 new mode 100644 diff --git a/libsrc/c64/acc_detect_chameleon.s b/libsrc/c64/acc_detect_chameleon.s old mode 100755 new mode 100644 diff --git a/libsrc/c64/acc_detect_turbomaster.s b/libsrc/c64/acc_detect_turbomaster.s old mode 100755 new mode 100644 diff --git a/libsrc/c64/acc_turbomaster_speed.s b/libsrc/c64/acc_turbomaster_speed.s old mode 100755 new mode 100644 diff --git a/libsrc/cbm510/pencalib.c b/libsrc/cbm510/pencalib.c old mode 100755 new mode 100644 diff --git a/libsrc/vic20/emd/vic20-georam.s b/libsrc/vic20/emd/vic20-georam.s old mode 100755 new mode 100644 diff --git a/samples/supervisionhello.c b/samples/supervisionhello.c old mode 100755 new mode 100644 diff --git a/test/ref/cf.in b/test/ref/cf.in old mode 100755 new mode 100644 diff --git a/test/ref/yacc.in b/test/ref/yacc.in old mode 100755 new mode 100644 diff --git a/test/val/add3a.c b/test/val/add3a.c old mode 100755 new mode 100644 diff --git a/test/val/casttochar.c b/test/val/casttochar.c old mode 100755 new mode 100644 diff --git a/test/val/cc65141002.c b/test/val/cc65141002.c old mode 100755 new mode 100644 diff --git a/test/val/cc65141011.c b/test/val/cc65141011.c old mode 100755 new mode 100644 diff --git a/test/val/cc65141022.c b/test/val/cc65141022.c old mode 100755 new mode 100644 diff --git a/testcode/lib/accelerator/chameleon-test.c b/testcode/lib/accelerator/chameleon-test.c old mode 100755 new mode 100644 diff --git a/testcode/lib/accelerator/turbomaster-test.c b/testcode/lib/accelerator/turbomaster-test.c old mode 100755 new mode 100644 From a43cac580ed70559b509227a11556deb6db29b5a Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Wed, 8 Jul 2020 21:37:39 +0300 Subject: [PATCH 1401/2161] Tiny optimization --- libsrc/vic20/tgi/vic20-hi.s | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libsrc/vic20/tgi/vic20-hi.s b/libsrc/vic20/tgi/vic20-hi.s index 8dfa46d6b..506de92f7 100644 --- a/libsrc/vic20/tgi/vic20-hi.s +++ b/libsrc/vic20/tgi/vic20-hi.s @@ -261,16 +261,15 @@ PATTERN_SOLID: sta tmp2+1 inx ; (ldx #$00) stx ERROR ; Set to TGI_ERR_OK + clc @NEXT_ROW: ldy #$00 txa - clc adc #$10 @NEXT_COLUMN: sta (tmp2),y - clc adc #ROWS iny cpy #COLS @@ -282,10 +281,8 @@ PATTERN_SOLID: clc adc #COLS sta tmp2 - bcc @L1 - inc tmp2+1 -@L1: inx + inx cpx #ROWS bne @NEXT_ROW From 693e3a710970627baf4ff30bdc6da19b448ab3ad Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 13 Jul 2020 15:12:04 +0200 Subject: [PATCH 1402/2161] added testcase for issue #1048 --- test/misc/bug1048.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 test/misc/bug1048.c diff --git a/test/misc/bug1048.c b/test/misc/bug1048.c new file mode 100644 index 000000000..d022474d6 --- /dev/null +++ b/test/misc/bug1048.c @@ -0,0 +1,15 @@ +/* bug #1048: The following code has two errors: a redeclared enum type and an + undeclared enum type: */ + +#include <stdlib.h> + +// this should NOT compile - but with cc65 it does +enum e { x }; +enum e { y }; + +int f() { return sizeof(enum undeclared); } + +int main(void) +{ + return EXIT_SUCCESS; +} From f5d99106e6610f9cb6bd699aa587c7321ef47074 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 13 Jul 2020 15:12:30 +0200 Subject: [PATCH 1403/2161] added testcase for issue #1075 --- test/misc/bug1075.c | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 test/misc/bug1075.c diff --git a/test/misc/bug1075.c b/test/misc/bug1075.c new file mode 100644 index 000000000..be4cd75f4 --- /dev/null +++ b/test/misc/bug1075.c @@ -0,0 +1,10 @@ +/* bug #1075 Internal compiler error */ + +long rhs; + +int main(void) +{ + /* the whole lhs is errorneously treated as an absolute address (integer + constant) neglecting its dereference */ + return *(char *)0xD77C + rhs; +} From f8873c2508203f4b86954d49e25fffc0fcea51c1 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 13 Jul 2020 15:12:47 +0200 Subject: [PATCH 1404/2161] added testcase for issue #250 --- test/misc/bug250.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test/misc/bug250.c diff --git a/test/misc/bug250.c b/test/misc/bug250.c new file mode 100644 index 000000000..60f3c633d --- /dev/null +++ b/test/misc/bug250.c @@ -0,0 +1,13 @@ +/* bug #250 - Array size compile-time optimization stops halfway */ + +#include <stdlib.h> + +#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b)) +unsigned char c[2*4]; +unsigned char b[2*LZO_MAX(8,sizeof(int))]; // this will not compile + +int main(void) +{ + /* FIXME: add some runtime check */ + return EXIT_SUCCESS; +} From bec140143ba6fc043b1901024ce03bf931af517c Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 13 Jul 2020 15:13:06 +0200 Subject: [PATCH 1405/2161] added testcase for issue #760 --- test/misc/bug264.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 test/misc/bug264.c diff --git a/test/misc/bug264.c b/test/misc/bug264.c new file mode 100644 index 000000000..a114939a4 --- /dev/null +++ b/test/misc/bug264.c @@ -0,0 +1,62 @@ +/* bug #264 - cc65 fails to warn about a function returning struct */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +typedef uint16_t u16; +typedef uint8_t u8; + +typedef struct { + u16 quot; + u16 rem; +} udiv_t; + +udiv_t div3(u16 in) { + + udiv_t u; + u16 q = 0; + + while (in >= 300) { + in -= 300; + q += 100; + } + + while (in >= 30) { + in -= 30; + q += 10; + } + + while (in >= 3) { + in -= 3; + ++q; + } + + u.quot = q; + u.rem = in; + + return u; +} + +int res = 0; + +int main(void) { + + u16 i; + div_t d; + udiv_t u; + + for (i = 1024; i; i--) { + d = div(i, 3); + u = div3(i); + + if (d.quot != u.quot || d.rem != u.rem) { + printf("Mismatch at %u/3, div %u %u, div3 %u %u\n", i, + d.quot, d.rem, u.quot, u.rem); + res++; + } + } + + return res; +} + From 36ff37214993310a832ae75953347b100ef647fe Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 13 Jul 2020 15:13:22 +0200 Subject: [PATCH 1406/2161] added testcase for issue #760 --- test/misc/bug760.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 test/misc/bug760.c diff --git a/test/misc/bug760.c b/test/misc/bug760.c new file mode 100644 index 000000000..dc8573b6d --- /dev/null +++ b/test/misc/bug760.c @@ -0,0 +1,12 @@ +/* bug#760 - Error when using macros as pragma arguments */ + +#include <stdlib.h> + +#define BANK "PRG0" + +#pragma rodata-name(push, BANK) + +int main(void) +{ + return EXIT_SUCCESS; +} From 5597b83d041301554726d329548644b145a80cd8 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 13 Jul 2020 15:13:38 +0200 Subject: [PATCH 1407/2161] added testcase for issue #975 --- test/misc/bug975.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 test/misc/bug975.c diff --git a/test/misc/bug975.c b/test/misc/bug975.c new file mode 100644 index 000000000..458524a5a --- /dev/null +++ b/test/misc/bug975.c @@ -0,0 +1,18 @@ +/* bug #975 - Forward array reference fails to compile */ + +#include <stdlib.h> + +// this works +static const unsigned char array2[3]; +int test2(void) { + return array2[0]; +} +static const unsigned char array2[] = { 0, 1, 2 }; + +// this should work, but does not compile +static const unsigned char array[]; +int main() { + if (test2() != 0) return EXIT_FAILURE; + return array[0]; +} +static const unsigned char array[] = { 0, 1, 2 }; From 390f9720149f13ebfbb5947a8fa2e5d700bcee62 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 13 Jul 2020 15:16:26 +0200 Subject: [PATCH 1408/2161] updated Makefile with exception rules for the added tests --- test/misc/Makefile | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/misc/Makefile b/test/misc/Makefile index cda0c789a..898ea1b2b 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -63,6 +63,36 @@ $(DIFF): ../bdiff.c | $(WORKDIR) define PRG_template +# should compile, but gives an error +$(WORKDIR)/bug975.$1.$2.prg: bug975.c | $(WORKDIR) + $(if $(QUIET),echo misc/bug975.$1.$2.prg) + -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + +# should compile, but gives an error +$(WORKDIR)/bug250.$1.$2.prg: bug250.c | $(WORKDIR) + $(if $(QUIET),echo misc/bug250.$1.$2.prg) + -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + +# should compile, but gives an error +$(WORKDIR)/bug760.$1.$2.prg: bug760.c | $(WORKDIR) + $(if $(QUIET),echo misc/bug760.$1.$2.prg) + -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + +# this should fail to compile, because cc65 does not support returning structs +$(WORKDIR)/bug264.$1.$2.prg: bug264.c | $(WORKDIR) + $(if $(QUIET),echo misc/bug264.$1.$2.prg) + -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + +# this should fail to compile, because there are errors in the code +$(WORKDIR)/bug1048.$1.$2.prg: bug1048.c | $(WORKDIR) + $(if $(QUIET),echo misc/bug1048.$1.$2.prg) + -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + +# internal compiler error +$(WORKDIR)/bug1075.$1.$2.prg: bug1075.c | $(WORKDIR) + $(if $(QUIET),echo misc/bug1075.$1.$2.prg) + -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + # 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) From e758110f6135bd10cf4266fa5c4ec5517d306f7f Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 13 Jul 2020 17:00:17 +0200 Subject: [PATCH 1409/2161] added testcode to check petscii char mapping, related to issue #988 --- testcode/lib/cbm/Makefile | 39 ++++++++++++++++++ testcode/lib/cbm/petscii.c | 82 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 testcode/lib/cbm/Makefile create mode 100644 testcode/lib/cbm/petscii.c diff --git a/testcode/lib/cbm/Makefile b/testcode/lib/cbm/Makefile new file mode 100644 index 000000000..5217f0cc6 --- /dev/null +++ b/testcode/lib/cbm/Makefile @@ -0,0 +1,39 @@ +# Run 'make SYS=<target>'; or, set a SYS env. +# var. to build for another target system. +SYS ?= c64 + +# 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 + +all: petscii.prg + +petscii.prg: petscii.c + $(CL) -t $(SYS) -O -o petscii.prg petscii.c + +clean: + $(DEL) petscii.prg diff --git a/testcode/lib/cbm/petscii.c b/testcode/lib/cbm/petscii.c new file mode 100644 index 000000000..60a12b18b --- /dev/null +++ b/testcode/lib/cbm/petscii.c @@ -0,0 +1,82 @@ + +/* this program prints all available "petscii" characters to screen, once + using putchar (which wraps to kernal i/o) and once using conio (which + will do direct videoram access). after that the produced screencodes + are compared (they should match) (related to issue #988 */ + +#include <conio.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#if defined(__C64__) +#define VRAMPEEK(x) (*(char*)(0x0400 + (x))) +#define CRAMPOKE(x, y) *(char*)(0xd800 + (x)) = (y) +#else +#error "this target is not supported yet" +#endif + +unsigned char x, y, c; +unsigned char c1, c2; +unsigned char *p1, *p2; + +int err = 0; + +int main(void) +{ + clrscr(); + bgcolor(COLOR_BLACK); + bordercolor(COLOR_BLACK); + + /* output all characters using putchar() */ + c = 0; + for (y = 0; y < 16; y++) { + for (x = 0; x < 16; x++) { + /* skip the codes that are unprintable control codes */ + if (!((c < 32) || ((c > 127) && (c < 160)))) { + gotoxy(x, y); putchar(c); + } + c++; + } + } + + /* output all characters using conio */ + c = 0; + for (y = 0; y < 16; y++) { + for (x = 0; x < 16; x++) { + /* skip the codes that are unprintable control codes */ + if (!((c < 32) || ((c > 127) && (c < 160)))) { + gotoxy(x + 20, y); cputc(c); + } + c++; + } + } + + /* compare the two outputs */ + for (y = 0; y < 16; y++) { + for (x = 0; x < 16; x++) { + c1 = VRAMPEEK((y * 40) + x); + c2 = VRAMPEEK((y * 40) + x + 0x14); + if (c1 == c2) { + c = COLOR_GREEN; + } else { + c = COLOR_RED; + err = 1; + } + CRAMPOKE((y * 40) + x, c); + CRAMPOKE((y * 40) + x + 0x14, c); + } + } + + /* show the result */ + textcolor(COLOR_WHITE); + gotoxy(0, 17); + if (err) { + bordercolor(COLOR_RED); + cputs("errors detected"); + } else { + bordercolor(COLOR_GREEN); + cputs("all fine"); + } + return 0; +} From d940c9aa8567f8fc208f770d5a9c95285fefe85b Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 13 Jul 2020 17:04:22 +0200 Subject: [PATCH 1410/2161] added a bit more precise description --- test/readme.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/readme.txt b/test/readme.txt index 2d4413f45..57ebfdd23 100644 --- a/test/readme.txt +++ b/test/readme.txt @@ -9,13 +9,16 @@ compiler. /err - contains tests that MUST NOT compile -/todo - these tests fail due to open compiler issues +/todo - these tests fail due to open compiler issues. + when an issue was fixed, the test should get moved to /var /asm - contains the assembler regression tests /dasm - contains the disassembler regression tests /misc - a few tests that need special care of some sort + tests that (incorrectly) fail to compile and other tests that fail and + do NOT return an exit code are collected here. to run the tests use "make" in this (top) directory, the makefile should exit From 882194c22125d435fcdf46520e3da080d6ad40b5 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 13 Jul 2020 21:25:13 +0200 Subject: [PATCH 1411/2161] move a bunch of tests from testcode/lib to test/val (and a failing one to test/todo) --- {testcode/lib => test/todo}/sprintf-test.c | 0 {testcode/lib => test/val}/atoi-test.c | 0 {testcode/lib => test/val}/shift-test.c | 0 {testcode/lib => test/val}/signal-test.c | 0 {testcode/lib => test/val}/snprintf-test.c | 0 {testcode/lib => test/val}/strncmp-test.c | 0 {testcode/lib => test/val}/strnicmp-test.c | 0 {testcode/lib => test/val}/strpbrk-test.c | 0 {testcode/lib => test/val}/strtol-test.c | 0 {testcode/lib => test/val}/strtoul-test.c | 0 {testcode/lib => test/val}/time-test.c | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename {testcode/lib => test/todo}/sprintf-test.c (100%) rename {testcode/lib => test/val}/atoi-test.c (100%) rename {testcode/lib => test/val}/shift-test.c (100%) rename {testcode/lib => test/val}/signal-test.c (100%) rename {testcode/lib => test/val}/snprintf-test.c (100%) rename {testcode/lib => test/val}/strncmp-test.c (100%) rename {testcode/lib => test/val}/strnicmp-test.c (100%) rename {testcode/lib => test/val}/strpbrk-test.c (100%) rename {testcode/lib => test/val}/strtol-test.c (100%) rename {testcode/lib => test/val}/strtoul-test.c (100%) rename {testcode/lib => test/val}/time-test.c (100%) diff --git a/testcode/lib/sprintf-test.c b/test/todo/sprintf-test.c similarity index 100% rename from testcode/lib/sprintf-test.c rename to test/todo/sprintf-test.c diff --git a/testcode/lib/atoi-test.c b/test/val/atoi-test.c similarity index 100% rename from testcode/lib/atoi-test.c rename to test/val/atoi-test.c diff --git a/testcode/lib/shift-test.c b/test/val/shift-test.c similarity index 100% rename from testcode/lib/shift-test.c rename to test/val/shift-test.c diff --git a/testcode/lib/signal-test.c b/test/val/signal-test.c similarity index 100% rename from testcode/lib/signal-test.c rename to test/val/signal-test.c diff --git a/testcode/lib/snprintf-test.c b/test/val/snprintf-test.c similarity index 100% rename from testcode/lib/snprintf-test.c rename to test/val/snprintf-test.c diff --git a/testcode/lib/strncmp-test.c b/test/val/strncmp-test.c similarity index 100% rename from testcode/lib/strncmp-test.c rename to test/val/strncmp-test.c diff --git a/testcode/lib/strnicmp-test.c b/test/val/strnicmp-test.c similarity index 100% rename from testcode/lib/strnicmp-test.c rename to test/val/strnicmp-test.c diff --git a/testcode/lib/strpbrk-test.c b/test/val/strpbrk-test.c similarity index 100% rename from testcode/lib/strpbrk-test.c rename to test/val/strpbrk-test.c diff --git a/testcode/lib/strtol-test.c b/test/val/strtol-test.c similarity index 100% rename from testcode/lib/strtol-test.c rename to test/val/strtol-test.c diff --git a/testcode/lib/strtoul-test.c b/test/val/strtoul-test.c similarity index 100% rename from testcode/lib/strtoul-test.c rename to test/val/strtoul-test.c diff --git a/testcode/lib/time-test.c b/test/val/time-test.c similarity index 100% rename from testcode/lib/time-test.c rename to test/val/time-test.c From 5ad365c5df9bf743f5672516358d2bf41cdf196c Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 13 Jul 2020 21:26:07 +0200 Subject: [PATCH 1412/2161] some tweaks to the moved tests to make them more suitable for automatic testing --- test/todo/sprintf-test.c | 10 ++--- test/val/signal-test.c | 13 ++++-- test/val/snprintf-test.c | 5 ++- test/val/strncmp-test.c | 14 ++++--- test/val/strnicmp-test.c | 85 ++++++++++++++++++++++------------------ test/val/strpbrk-test.c | 12 +++++- test/val/time-test.c | 33 +++++++++++----- 7 files changed, 108 insertions(+), 64 deletions(-) diff --git a/test/todo/sprintf-test.c b/test/todo/sprintf-test.c index 55354be20..bd5de44b4 100644 --- a/test/todo/sprintf-test.c +++ b/test/todo/sprintf-test.c @@ -1,13 +1,13 @@ #include <stdio.h> #include <string.h> #include <stdarg.h> -#if defined(__CC65__) +#if defined(__CC65__) && !defined(__SIM6502__) && !defined(__SIM65C02__) #include <conio.h> #endif /* Flag to #ifdef the tests out that crash the old implementation */ -/*#define NOCRASH 1 */ +#define NOCRASH 1 @@ -532,9 +532,9 @@ int main (void) /* Alternative form with zero value */ #ifndef NOCRASH OneTest (__LINE__, "0", 1, "%#o", 0U); +#endif OneTest (__LINE__, "0", 1, "%#x", 0U); OneTest (__LINE__, "0", 1, "%#X", 0U); -#endif /* Alternative form with zero value and precision 1 */ OneTest (__LINE__, "0", 1, "%#.1o", 0U); @@ -570,8 +570,8 @@ int main (void) } /* Wait for a key so we can read the result */ -#if defined(__CC65__) +#if defined(__CC65__) && !defined(__SIM6502__) && !defined(__SIM65C02__) cgetc (); #endif - return 0; + return Failures; } diff --git a/test/val/signal-test.c b/test/val/signal-test.c index 4e34a281d..31dd8ed5c 100644 --- a/test/val/signal-test.c +++ b/test/val/signal-test.c @@ -1,12 +1,16 @@ #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <errno.h> #include <signal.h> +int signalcounter = 0; + void __fastcall__ sighandler (int sig) { printf ("Got signal #%d\n", sig); + signalcounter++; } @@ -15,15 +19,18 @@ int main (void) { if (signal (SIGSEGV, sighandler) == SIG_ERR) { printf ("signal failure %d: %s\n", errno, strerror (errno)); - return 1; + return EXIT_FAILURE; } printf ("About to raise SIGSEGV...\n"); raise (SIGSEGV); printf ("Back from signal handler\n"); printf ("About to raise SIGILL...\n"); raise (SIGILL); - printf ("Back from signal handler\n"); - return 0; + printf ("Back from signal handler, signalcounter = %d\n", signalcounter); + if (signalcounter != 1) { + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } diff --git a/test/val/snprintf-test.c b/test/val/snprintf-test.c index d3af47d78..e3a60d99b 100644 --- a/test/val/snprintf-test.c +++ b/test/val/snprintf-test.c @@ -137,8 +137,9 @@ unsigned char main(void) } else { printf("There were no"); } - printf(" failures.\nTap a key. "); + printf(" failures.\nTap a key.\n"); +#if defined(__CC65__) && !defined(__SIM6502__) && !defined(__SIM65C02__) cgetc(); - +#endif return failures; } diff --git a/test/val/strncmp-test.c b/test/val/strncmp-test.c index b15565036..7dbbb4b8c 100644 --- a/test/val/strncmp-test.c +++ b/test/val/strncmp-test.c @@ -10,15 +10,19 @@ static const char S2[] = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '\0', 'B' }; - - +int fails = 0; int main (void) { char I; + int ret; for (I = 0; I < 20; ++I) { - printf ("%02d: %d\n", I, strncmp (S1, S2, I)); + ret = strncmp (S1, S2, I); + printf ("%02d: %d\n", I, ret); + if ((ret != 0) && (I < 7)) { + fails++; + } } - return 0; + printf("fails: %d\n", fails); + return fails; } - diff --git a/test/val/strnicmp-test.c b/test/val/strnicmp-test.c index b2d942a97..6376a39bb 100644 --- a/test/val/strnicmp-test.c +++ b/test/val/strnicmp-test.c @@ -3,70 +3,79 @@ #include <string.h> #include <conio.h> +int fails = 0; + static int do_test(const char *s1, const char *s2, size_t n) { printf("strnicmp(\"%s\", \"%s\", %d): ", s1, s2, (int)n); return strncasecmp(s1, s2, n); } +static void printresult(int ret) +{ + if (ret) { + printf("fail (%d)\n", ret); + fails++; + } else { + printf("OK (%d)\n", ret); + } +} + +static void printresultgt(int ret) +{ + if (ret >= 0) { + printf("fail (%d)\n", ret); + fails++; + } else { + printf("OK (%d)\n", ret); + } +} + +static void printresultlt(int ret) +{ + if (ret <= 0) { + printf("fail (%d)\n", ret); + fails++; + } else { + printf("OK (%d)\n", ret); + } +} + int main(void) { int ret; ret = do_test("Wurzl", "wURZL", 5); - if (ret) - printf("fail (%d)\n", ret); - else - printf("OK (%d)\n", ret); + printresult(ret); ret = do_test("Wurzl", "wURZL", 6); - if (ret) - printf("fail (%d)\n", ret); - else - printf("OK (%d)\n", ret); + printresult(ret); ret = do_test("Wurzl", "wURZL", 10); - if (ret) - printf("fail (%d)\n", ret); - else - printf("OK (%d)\n", ret); + printresult(ret); ret = do_test("Wurzla", "wURZLB", 10); - if (ret >= 0) - printf("fail (%d)\n", ret); - else - printf("OK (%d)\n", ret); + printresultgt(ret); ret = do_test("Wurzla", "wURZLb", 5); - if (ret) - printf("fail (%d)\n", ret); - else - printf("OK (%d)\n", ret); + printresult(ret); ret = do_test("BLI", "bla", 5); - if (ret <= 0) - printf("fail (%d)\n", ret); - else - printf("OK (%d)\n", ret); + printresultlt(ret); ret = do_test("", "bla", 5); - if (ret >= 0) - printf("fail (%d)\n", ret); - else - printf("OK (%d)\n", ret); + printresultgt(ret); ret = do_test("BLI", "", 5); - if (ret <= 0) - printf("fail (%d)\n", ret); - else - printf("OK (%d)\n", ret); + printresultlt(ret); ret = do_test("", "", 5); - if (ret) - printf("fail (%d)\n", ret); - else - printf("OK (%d)\n", ret); - + printresult(ret); + + printf("fails: %d\n", fails); + +#if defined(__CC65__) && !defined(__SIM6502__) && !defined(__SIM65C02__) cgetc(); - return 0; +#endif + return fails; } diff --git a/test/val/strpbrk-test.c b/test/val/strpbrk-test.c index 25c2c2fbe..6a688732d 100644 --- a/test/val/strpbrk-test.c +++ b/test/val/strpbrk-test.c @@ -3,24 +3,32 @@ static const char fox[] = "The quick brown fox jumped over the lazy dogs."; -void main (void) +int fails = 0; + +int main (void) { printf ("Testing strpbrk():\n"); if (strpbrk (fox, "qwerty") != &fox[2]) { printf ("\nThe first 'e' wasn't found.\n"); + fails++; } if (strpbrk (fox, "QWERTY") != &fox[0]) { printf ("The 'T' wasn't found.\n"); + fails++; } if (strpbrk (fox, "asdfg") != &fox[16]) { printf ("The 'f' wasn't found.\n"); + fails++; } if (strpbrk (fox, "nxv,zmb") != &fox[10]) { printf ("The 'b' wasn't found.\n"); + fails++; } if (strpbrk (fox, "!@#$%^&*()-+=[];:',/?<>.") != &fox[45]) { printf ("The '.' wasn't found.\n"); + fails++; } - printf ("\nFinished.\n"); + printf ("\nFinished. fails = %d\n", fails); + return fails; } diff --git a/test/val/time-test.c b/test/val/time-test.c index 99d16be01..304238fa0 100644 --- a/test/val/time-test.c +++ b/test/val/time-test.c @@ -1,7 +1,11 @@ #include <stdio.h> +#include <string.h> #include <time.h> +#define EXPECTSTR "3DD173D1 - Tue Nov 12 21:34:09 2002\n" +char result[0x100]; +int fails = 0; int main (void) { @@ -23,16 +27,27 @@ int main (void) t = mktime (&tm); printf ("Test passes if the following lines are\n" "all identical:\n"); - printf ("3DD173D1 - Tue Nov 12 21:34:09 2002\n"); - printf ("%08lX - %s", t, asctime (&tm)); - printf ("%08lX - %s", t, asctime (gmtime (&t))); + printf (EXPECTSTR); + + sprintf (result, "%08lX - %s", t, asctime (&tm)); + printf (result); + if (strcmp(result, EXPECTSTR) != 0) { fails++; } + + sprintf (result, "%08lX - %s", t, asctime (gmtime (&t))); + printf (result); + if (strcmp(result, EXPECTSTR) != 0) { fails++; } + strftime (buf, sizeof (buf), "%c", &tm); - printf ("%08lX - %s\n", t, buf); + sprintf (result, "%08lX - %s\n", t, buf); + printf (result); + if (strcmp(result, EXPECTSTR) != 0) { fails++; } + strftime (buf, sizeof (buf), "%a %b %d %H:%M:%S %Y", &tm); - printf ("%08lX - %s\n", t, buf); + sprintf (result, "%08lX - %s\n", t, buf); + printf (result); + if (strcmp(result, EXPECTSTR) != 0) { fails++; } + + printf("fails: %d\n", fails); - return 0; + return fails; } - - - From a4f1e37f0c46f1f56c0772d1da85a2c7c6f19b1b Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 13 Jul 2020 21:26:31 +0200 Subject: [PATCH 1413/2161] increase the maximum amount of cycles, else the shift test will fail --- test/val/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/val/Makefile b/test/val/Makefile index 417c0b6c8..be63cd8da 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -24,7 +24,7 @@ ifdef QUIET NULLERR = 2>$(NULLDEV) endif -SIM65FLAGS = -x 200000000 +SIM65FLAGS = -x 5000000000 CL65 := $(if $(wildcard ../../bin/cl65*),..$S..$Sbin$Scl65,cl65) SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65) From 1f2fdbd9b1c103bc57fe057255bdc780b9f51043 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 14 Jul 2020 14:22:29 +0200 Subject: [PATCH 1414/2161] implemented conio peek functions for PCE target --- libsrc/pce/cpeekc.s | 24 +++++++++++++++ libsrc/pce/cpeekcolor.s | 28 ++++++++++++++++++ libsrc/pce/cpeekrevers.s | 26 +++++++++++++++++ libsrc/pce/cpeeks.s | 63 ++++++++++++++++++++++++++++++++++++++++ libsrc/pce/cputc.s | 4 +-- 5 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 libsrc/pce/cpeekc.s create mode 100644 libsrc/pce/cpeekcolor.s create mode 100644 libsrc/pce/cpeekrevers.s create mode 100644 libsrc/pce/cpeeks.s diff --git a/libsrc/pce/cpeekc.s b/libsrc/pce/cpeekc.s new file mode 100644 index 000000000..e144f94ac --- /dev/null +++ b/libsrc/pce/cpeekc.s @@ -0,0 +1,24 @@ +; +; 2020-07-14, Groepaz +; +; char cpeekc (void); +; +; get character from current position, do NOT advance cursor + + .export _cpeekc + + .include "pce.inc" + .include "extzp.inc" + +_cpeekc: + st0 #VDC_MARR ; Memory-Address Read + ldy SCREEN_PTR + ldx SCREEN_PTR+1 + sty VDC_DATA_LO + stx VDC_DATA_HI + + st0 #VDC_VRR ; VRAM Read Register + lda VDC_DATA_LO ; character + and #<~$80 ; remove reverse bit + ldx #0 + rts diff --git a/libsrc/pce/cpeekcolor.s b/libsrc/pce/cpeekcolor.s new file mode 100644 index 000000000..8b96d29d4 --- /dev/null +++ b/libsrc/pce/cpeekcolor.s @@ -0,0 +1,28 @@ +; +; 2020-07-14, Groepaz +; +; unsigned char cpeekcolor (void); +; +; get color from current position, do NOT advance cursor + + .export _cpeekcolor + + .include "pce.inc" + .include "extzp.inc" + +_cpeekcolor: + st0 #VDC_MARR ; Memory-Address Read + ldy SCREEN_PTR + ldx SCREEN_PTR+1 + sty VDC_DATA_LO + stx VDC_DATA_HI + + st0 #VDC_VRR ; VRAM Read Register + lda VDC_DATA_HI + and #<~$02 + lsr a + lsr a + lsr a + lsr a + ldx #0 + rts diff --git a/libsrc/pce/cpeekrevers.s b/libsrc/pce/cpeekrevers.s new file mode 100644 index 000000000..3f208fd10 --- /dev/null +++ b/libsrc/pce/cpeekrevers.s @@ -0,0 +1,26 @@ +; +; 2020-07-14, Groepaz +; +; unsigned char cpeekrevers (void); +; +; get inverse flag from current position, do NOT advance cursor + + .export _cpeekrevers + + .include "pce.inc" + .include "extzp.inc" + +_cpeekrevers: + st0 #VDC_MARR ; Memory-Address Read + ldy SCREEN_PTR + ldx SCREEN_PTR+1 + sty VDC_DATA_LO + stx 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 + rts diff --git a/libsrc/pce/cpeeks.s b/libsrc/pce/cpeeks.s new file mode 100644 index 000000000..fe5e28687 --- /dev/null +++ b/libsrc/pce/cpeeks.s @@ -0,0 +1,63 @@ +; +; 2020-07-14, Groepaz +; +; void cpeeks (char* s, unsigned length); +; +; get string from current position, do NOT advance cursor + + .export _cpeeks + + .import popax + .importzp ptr1, ptr2, tmp1, tmp2 + + .macpack generic + + .include "pce.inc" + .include "extzp.inc" + +_cpeeks: + eor #<$FFFF ; counting a word upward is faster + sta ptr2 ; so, we use -(length + 1) + txa + eor #>$FFFF + sta ptr2+1 + + st0 #VDC_MARR ; Memory-Address Read + ldy SCREEN_PTR + ldx SCREEN_PTR+1 + sty VDC_DATA_LO + stx VDC_DATA_HI + + st0 #VDC_VRR ; VRAM Read Register + + jsr popax + sta tmp1 ; (will be a .Y 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 + and #<~$80 ; remove reverse bit + + ldy tmp1 + sta (ptr1),y + iny + bne L1 + inc ptr1+1 +L1: sty tmp1 + +L2: inc ptr2 ; count length + bne L3 + inc ptr2+1 + bne L3 + + txa ; terminate the string + ldy tmp1 + sta (ptr1),y + rts diff --git a/libsrc/pce/cputc.s b/libsrc/pce/cputc.s index 04d901423..626d3ef8e 100644 --- a/libsrc/pce/cputc.s +++ b/libsrc/pce/cputc.s @@ -68,10 +68,10 @@ putchar: sty VDC_DATA_LO stx VDC_DATA_HI - st0 #VDC_VWR + st0 #VDC_VWR ; VRAM Write Register sta VDC_DATA_LO ; character - lda CHARCOLOR ; pallette number + lda CHARCOLOR ; palette number asl a asl a asl a From f99a44d8e1ab44c6a20a4794b1b2adcafe154655 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 14 Jul 2020 14:24:19 +0200 Subject: [PATCH 1415/2161] added rudimentary testing for the peek functions --- testcode/lib/pce/conio.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/testcode/lib/pce/conio.c b/testcode/lib/pce/conio.c index 858f01918..55f828f26 100644 --- a/testcode/lib/pce/conio.c +++ b/testcode/lib/pce/conio.c @@ -7,6 +7,10 @@ static int datavar = 10; +static char hex[16] = { "0123456789abcdef" }; +static char charbuf[0x20]; +static char colbuf[0x20]; + void main(void) { int stackvar = 42; @@ -21,11 +25,27 @@ void main(void) screensize(&xsize, &ysize); cputs("hello world"); + gotoxy(0,0); + cpeeks(charbuf, 11); + gotoxy(12,0); + cputs(charbuf); + cputsxy(0, 2, "colors:" ); for (i = 0; i < 16; ++i) { textcolor(i); - cputc('X'); + cputc(hex[i]); } + for (i = 0; i < 16; ++i) { + gotoxy(7 + i, 2); + charbuf[i] = cpeekc(); + colbuf[i] = cpeekcolor(); + } + gotoxy(25, 2); + for (i = 0; i < 16; ++i) { + textcolor(colbuf[i]); + cputc(charbuf[i]); + } + textcolor(1); gotoxy(0,4); @@ -115,6 +135,17 @@ void main(void) cputs(" revers"); revers(0); + for (i = 0; i < 9; ++i) { + gotoxy(xsize - 10 + i, 3); + charbuf[i] = cpeekc(); + colbuf[i] = cpeekrevers(); + } + gotoxy(xsize - 10, 4); + for (i = 0; i < 9; ++i) { + revers(colbuf[i]); + cputc(charbuf[i]); + } + if ((n & 0x1f) == 0x00) { nn = p[15]; ((char*)memmove(p + 1, p, 15))[-1] = nn; From 3558c0796dc01f3659b797d1639107ebcad40e69 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 14 Jul 2020 15:00:43 +0200 Subject: [PATCH 1416/2161] added a second test that checks all available characters (including inverse) --- testcode/lib/cbm/petscii.c | 80 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/testcode/lib/cbm/petscii.c b/testcode/lib/cbm/petscii.c index 60a12b18b..7d5ba9528 100644 --- a/testcode/lib/cbm/petscii.c +++ b/testcode/lib/cbm/petscii.c @@ -11,6 +11,8 @@ #if defined(__C64__) #define VRAMPEEK(x) (*(char*)(0x0400 + (x))) +#define VRAMPOKE(x, y) *(char*)(0x0400 + (x)) = (y) +#define CRAMPEEK(x) ((*(char*)(0xd800 + (x))) & 15) #define CRAMPOKE(x, y) *(char*)(0xd800 + (x)) = (y) #else #error "this target is not supported yet" @@ -78,5 +80,83 @@ int main(void) bordercolor(COLOR_GREEN); cputs("all fine"); } + cputs(" - press a key "); + cursor(1); + cgetc(); + cursor(0); + + clrscr(); + bordercolor(COLOR_BLACK); + + /* output all characters directly to the scree */ + c = 0; + for (y = 0; y < 16; y++) { + for (x = 0; x < 16; x++) { + VRAMPOKE((y * 40) + x, c); + CRAMPOKE((y * 40) + x, c & 15); + c++; + } + } + + /* read the characters with conio peek functions and output with conio */ + for (y = 0; y < 16; y++) { + for (x = 0; x < 16; x++) { + gotoxy(x, y); + c1 = cpeekc(); + c2 = cpeekrevers(); + c = cpeekcolor(); + + gotoxy(x + 0x14, y); + revers(c2); + textcolor(c); + cputc(c1); + } + } + + revers(0); + textcolor(COLOR_WHITE); + gotoxy(0, 17); + cputs("press a key to compare "); + cursor(1); + cgetc(); + cursor(0); + + /* compare the two outputs */ + for (y = 0; y < 16; y++) { + for (x = 0; x < 16; x++) { + c = COLOR_GREEN; + c1 = VRAMPEEK((y * 40) + x); + c2 = VRAMPEEK((y * 40) + x + 0x14); + if (c1 != c2) { + c = COLOR_RED; + err = 1; + } + c1 = CRAMPEEK((y * 40) + x); + c2 = CRAMPEEK((y * 40) + x + 0x14); + if (c1 != c2) { + c = COLOR_RED; + err = 1; + } + CRAMPOKE((y * 40) + x, c); + CRAMPOKE((y * 40) + x + 0x14, c); + } + } + + /* show the result */ + revers(0); + textcolor(COLOR_WHITE); + gotoxy(0, 17); + if (err) { + bordercolor(COLOR_RED); + cputs("errors detected"); + } else { + bordercolor(COLOR_GREEN); + cputs("all fine"); + } + cputs(" - press a key "); + cursor(1); + cgetc(); + cursor(0); + return 0; } From 9023e975df8b89384207366521e16979026cfffc Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 14 Jul 2020 16:06:21 -0400 Subject: [PATCH 1417/2161] Stopped the C128 mouse drivers from blocking certain keys such as '1', '2', and 'Q'. This extra fix is needed because the C128 keyboard scanner works a little differently than the C64 scanner works. Fixes #696. Fixes #853. --- libsrc/c128/mou/c128-1351.s | 4 ++-- libsrc/c128/mou/c128-inkwell.s | 6 +++--- libsrc/c128/mou/c128-joy.s | 4 ++-- libsrc/c128/mou/c128-pot.s | 4 ++-- libsrc/c128/mou/callback.inc | 11 ++++++----- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/libsrc/c128/mou/c128-1351.s b/libsrc/c128/mou/c128-1351.s index d06e942c4..79ccbe0de 100644 --- a/libsrc/c128/mou/c128-1351.s +++ b/libsrc/c128/mou/c128-1351.s @@ -4,7 +4,7 @@ ; ; 2009-09-26, Ullrich von Bassewitz ; 2014-04-26, Christian Groessler -; 2014-04-30, Greg King +; 2020-07-14, Greg King ; .include "zeropage.inc" @@ -377,7 +377,7 @@ IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioctls, for now IRQ: jsr CPREP lda KEY_COUNT sta old_key_count - lda #$7F + lda #$FF sta CIA1_PRA lda CIA1_PRB ; Read joystick #0 and #$1F diff --git a/libsrc/c128/mou/c128-inkwell.s b/libsrc/c128/mou/c128-inkwell.s index 45d42f2db..b8e71bbb1 100644 --- a/libsrc/c128/mou/c128-inkwell.s +++ b/libsrc/c128/mou/c128-inkwell.s @@ -2,7 +2,7 @@ ; Driver for the Inkwell Systems 170-C and 184-C lightpens. ; ; 2014-04-26, Christian Groessler -; 2014-09-10, Greg King +; 2020-07-14, Greg King ; .include "zeropage.inc" @@ -414,8 +414,8 @@ IRQ: jsr CPREP ldy #%00000000 ; Set ports A and B to input sty CIA1_DDRB sty CIA1_DDRA ; Keyboard won't look like buttons - ;lda #%01111111 ; (Keyboard scan leaves this in port A) - ;sta CIA1_PRA + lda #%11111111 + sta CIA1_PRA lda CIA1_PRB ; Read Control Port 1 dec CIA1_DDRA ; Set port A back to output eor #%11111111 ; Bit goes up when button goes down diff --git a/libsrc/c128/mou/c128-joy.s b/libsrc/c128/mou/c128-joy.s index 7718b89b7..065674dc0 100644 --- a/libsrc/c128/mou/c128-joy.s +++ b/libsrc/c128/mou/c128-joy.s @@ -3,7 +3,7 @@ ; ; 2009-09-26, Ullrich von Bassewitz ; 2014-04-26, Christian Groessler -; 2014-05-01, Greg King +; 2020-07-14, Greg King ; .include "zeropage.inc" @@ -379,7 +379,7 @@ IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioctls for now IRQ: jsr CPREP lda KEY_COUNT sta old_key_count - lda #$7F + lda #$FF sta CIA1_PRA lda CIA1_PRB ; Read joystick #0 and #$1F diff --git a/libsrc/c128/mou/c128-pot.s b/libsrc/c128/mou/c128-pot.s index f61f88d5d..e582d64fb 100644 --- a/libsrc/c128/mou/c128-pot.s +++ b/libsrc/c128/mou/c128-pot.s @@ -4,7 +4,7 @@ ; 2006-08-20, Stefan Haubenthal ; 2009-09-26, Ullrich von Bassewitz ; 2014-04-26, Christian Groessler -; 2014-05-05, Greg King +; 2020-07-14, Greg King ; .include "zeropage.inc" @@ -385,7 +385,7 @@ IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioctls for now IRQ: jsr CPREP lda KEY_COUNT sta old_key_count - lda #$7F + lda #$FF sta CIA1_PRA lda CIA1_PRB ; Read port #1 eor #%11111111 ; Make all bits active high diff --git a/libsrc/c128/mou/callback.inc b/libsrc/c128/mou/callback.inc index 9f1d749a7..274c145fa 100644 --- a/libsrc/c128/mou/callback.inc +++ b/libsrc/c128/mou/callback.inc @@ -1,11 +1,12 @@ ; -; Callback routine called from the IRQ handler after the ROM IRQ handler -; had been run. +; Callback routine, called from the IRQ handler after the ROM IRQ handler +; has been run. ; -; Christian Groessler, 24.04.2014 +; 2014-04-24, Christian Groessler +; 2020-07-14, Greg King ; ; Check if there was button/joystick activity before and/or after the ROM handler. -; If there was activity, discard the key presses since they are most +; If there was activity, discard the key presses because they are most ; probably "phantom" key presses. callback: @@ -16,7 +17,7 @@ callback: lda OLD_BUTTONS ; keypress before? bne @discard_key ; yes, discard key - lda #$7F + lda #$FF sta CIA1_PRA lda CIA1_PRB ; Read joystick #0 and #$1F From 6035f1cb751a0faf7e813dca35bcee3c2bdb81fc Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 15 Jul 2020 00:17:11 +0200 Subject: [PATCH 1418/2161] added missing gotox/gotoy functions --- libsrc/pce/gotox.s | 14 ++++++++++++++ libsrc/pce/gotoy.s | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 libsrc/pce/gotox.s create mode 100644 libsrc/pce/gotoy.s diff --git a/libsrc/pce/gotox.s b/libsrc/pce/gotox.s new file mode 100644 index 000000000..fe8a23734 --- /dev/null +++ b/libsrc/pce/gotox.s @@ -0,0 +1,14 @@ +; +; void __fastcall__ gotox (unsigned char x); +; + + .export _gotox + + .import plot + + .include "pce.inc" + .include "extzp.inc" + +_gotox: + sta CURS_X ; Set X + jmp plot ; Set the cursor position diff --git a/libsrc/pce/gotoy.s b/libsrc/pce/gotoy.s new file mode 100644 index 000000000..9585b035b --- /dev/null +++ b/libsrc/pce/gotoy.s @@ -0,0 +1,14 @@ +; +; void __fastcall__ gotoy (unsigned char y); +; + + .export _gotoy + + .import plot + + .include "pce.inc" + .include "extzp.inc" + +_gotoy: + sta CURS_Y ; Set Y + jmp plot ; Set the cursor position From e2ec517aae26d48a983010464ad3e094649e98d8 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Mon, 13 Jul 2020 12:09:01 +0300 Subject: [PATCH 1419/2161] Save another 3 bytes --- libsrc/vic20/tgi/vic20-hi.s | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libsrc/vic20/tgi/vic20-hi.s b/libsrc/vic20/tgi/vic20-hi.s index 506de92f7..9d345947b 100644 --- a/libsrc/vic20/tgi/vic20-hi.s +++ b/libsrc/vic20/tgi/vic20-hi.s @@ -270,16 +270,14 @@ PATTERN_SOLID: @NEXT_COLUMN: sta (tmp2),y - adc #ROWS iny - cpy #COLS - bne @NEXT_COLUMN + adc #ROWS + bcc @NEXT_COLUMN ; Step to next row on screen. lda tmp2 - clc - adc #COLS + adc #COLS-1 ; Carry is set sta tmp2 inx From de5678af5de94121bd75fec18ebb354e67fed4eb Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Mon, 13 Jul 2020 16:59:47 +0300 Subject: [PATCH 1420/2161] Added optimizations by dmsc --- libsrc/vic20/tgi/vic20-hi.s | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/libsrc/vic20/tgi/vic20-hi.s b/libsrc/vic20/tgi/vic20-hi.s index 9d345947b..dd540ce88 100644 --- a/libsrc/vic20/tgi/vic20-hi.s +++ b/libsrc/vic20/tgi/vic20-hi.s @@ -136,6 +136,7 @@ BITCHUNK: .byte $FF, $7F, $3F, $1F, $0F, $07, $03, $01 CHARROM := $8000 ; Character ROM base address CBASE := $9400 ; Color memory base address SBASE := $1000 ; Screen memory base address +.assert (<SBASE) = $0, error, "Error, SBASE must be page aligned" VBASE := $1100 ; Video memory base address ; These numbers are added to Kernal's default VIC settings. @@ -250,23 +251,21 @@ PATTERN_SOLID: ; Initialize variables - ldx #$FF - stx BITMASK + ldy #$FF + sty BITMASK ; Make screen columns. - lda #<SBASE - sta tmp2 lda #>SBASE sta tmp2+1 - inx ; (ldx #$00) - stx ERROR ; Set to TGI_ERR_OK + iny ; (ldy #$00) + sty tmp2 + sty ERROR ; Set to TGI_ERR_OK clc + ldx #$10 @NEXT_ROW: - ldy #$00 txa - adc #$10 @NEXT_COLUMN: sta (tmp2),y @@ -276,12 +275,8 @@ PATTERN_SOLID: ; Step to next row on screen. - lda tmp2 - adc #COLS-1 ; Carry is set - sta tmp2 - inx - cpx #ROWS + cpx #ROWS+$10 bne @NEXT_ROW ; Set up VIC. From b3703de983306dbc4a0666cbe69aba246e4b7fc8 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Tue, 14 Jul 2020 12:19:46 +0300 Subject: [PATCH 1421/2161] Code style fixes --- libsrc/vic20/tgi/vic20-hi.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/vic20/tgi/vic20-hi.s b/libsrc/vic20/tgi/vic20-hi.s index dd540ce88..416eb58b0 100644 --- a/libsrc/vic20/tgi/vic20-hi.s +++ b/libsrc/vic20/tgi/vic20-hi.s @@ -253,13 +253,13 @@ PATTERN_SOLID: ldy #$FF sty BITMASK + iny ; (ldy #$00) ; Make screen columns. + sty tmp2 lda #>SBASE sta tmp2+1 - iny ; (ldy #$00) - sty tmp2 sty ERROR ; Set to TGI_ERR_OK clc ldx #$10 From a02bec11e9eacf5a765e5ad2ad51793c15cf6475 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Tue, 14 Jul 2020 21:15:57 +0300 Subject: [PATCH 1422/2161] Another code style fix --- libsrc/vic20/tgi/vic20-hi.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/vic20/tgi/vic20-hi.s b/libsrc/vic20/tgi/vic20-hi.s index 416eb58b0..826a09c14 100644 --- a/libsrc/vic20/tgi/vic20-hi.s +++ b/libsrc/vic20/tgi/vic20-hi.s @@ -254,13 +254,13 @@ PATTERN_SOLID: ldy #$FF sty BITMASK iny ; (ldy #$00) + sty ERROR ; Set to TGI_ERR_OK ; Make screen columns. sty tmp2 lda #>SBASE sta tmp2+1 - sty ERROR ; Set to TGI_ERR_OK clc ldx #$10 From ba0ef5938d267dc47ca6d30af18b596190b4f932 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 15 Jul 2020 04:55:38 -0400 Subject: [PATCH 1423/2161] Moved the font into a separate module in the library. The font can be replaced, at link-time, by a custom file. --- libsrc/pce/conio.s | 8 +++----- libsrc/pce/{vga.inc => vga.s} | 5 +++++ 2 files changed, 8 insertions(+), 5 deletions(-) rename libsrc/pce/{vga.inc => vga.s} (99%) diff --git a/libsrc/pce/conio.s b/libsrc/pce/conio.s index 8fefe01f6..ac306f193 100644 --- a/libsrc/pce/conio.s +++ b/libsrc/pce/conio.s @@ -3,6 +3,7 @@ .import vdc_init .import psg_init .import colors + .import _pce_font .importzp ptr1, tmp1 .include "pce.inc" @@ -53,8 +54,8 @@ load_font: ; rts ; (fall through) ; Point to the font data. -copy: lda #<font - ldx #>font +copy: lda #<_pce_font + ldx #>_pce_font sta ptr1 stx ptr1+1 @@ -84,6 +85,3 @@ fillloop: bne charloop ; next character rts - -.rodata -font: .include "vga.inc" diff --git a/libsrc/pce/vga.inc b/libsrc/pce/vga.s similarity index 99% rename from libsrc/pce/vga.inc rename to libsrc/pce/vga.s index 72c173146..630fbe8db 100644 --- a/libsrc/pce/vga.inc +++ b/libsrc/pce/vga.s @@ -1,10 +1,15 @@ ;---------------------------------------------------------------------------- ; VGA font for the PC-Engine conio implementation + .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. +.rodata + +_pce_font: .byte $00, $00, $00, $00, $00, $00, $00, $00 .byte %00000000 From 72fff0cfbc9a04f6df5de43eb065c8bc984d793f Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 15 Jul 2020 22:23:29 +0200 Subject: [PATCH 1424/2161] atari.h: fix definition of KEY_UP noticed by Stefan Wessels --- include/atari.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/atari.h b/include/atari.h index 582e23be6..1a00a4c67 100644 --- a/include/atari.h +++ b/include/atari.h @@ -209,7 +209,7 @@ #define KEY_CLEAR (KEY_LESSTHAN | KEY_SHIFT) #define KEY_INSERT (KEY_GREATERTHAN | KEY_SHIFT) -#define KEY_UP (KEY_UNDERLINE | KEY_CTRL) +#define KEY_UP (KEY_DASH | KEY_CTRL) #define KEY_DOWN (KEY_EQUALS | KEY_CTRL) #define KEY_LEFT (KEY_PLUS | KEY_CTRL) #define KEY_RIGHT (KEY_ASTERISK | KEY_CTRL) From 4296cbaf82d47bfe1c9d9b100dcdf534601f018b Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 15 Jul 2020 17:11:38 -0400 Subject: [PATCH 1425/2161] Added a 320x200x256 TGI driver to the Commander X16 library. Made the mandelbrot sample program handle the X16's 256 colors. --- doc/cx16.sgml | 37 +++- include/cx16.h | 24 +- libsrc/cx16/tgi/cx320p1.s | 401 ++++++++++++++++++++++++++++++++++ libsrc/cx16/tgi_stat_stddrv.s | 7 +- libsrc/cx16/tgi_stddrv.s | 6 +- samples/mandelbrot.c | 12 +- 6 files changed, 465 insertions(+), 22 deletions(-) create mode 100644 libsrc/cx16/tgi/cx320p1.s diff --git a/doc/cx16.sgml b/doc/cx16.sgml index 20094d609..a73bb3c1e 100644 --- a/doc/cx16.sgml +++ b/doc/cx16.sgml @@ -16,9 +16,12 @@ compiler. <sect>Overview<p> -The Commander X16 is a modern small computer with firmware that is based on -the ROMs in Commodore's VIC-20 and 64C. It has a couple of I/O chips -(WDC65C22 VIA) that are like the ones in the VIC-20. +The Commander X16 is a modern small computer with firmware that is based partly +on the ROMs in Commodore's VIC-20 and 64C. It has a couple of I/O chips +(WDC65C22 VIA) that are like the ones in the VIC-20. It supports file storage +on Secure Digital cards. It allows two joysticks and a mouse. It has three +sound devices. It's VGA screen has twice the range of the C64 (similar to the +C128's 80-column screen), with 256 colors. This file contains an overview of the CX16 run-time system as it comes with the cc65 C compiler. It describes the memory layout, CX16-specific header files, @@ -108,7 +111,7 @@ cl65 -o file.prg -t cx16 -C cx16-asm.cfg source.s To generate code that loads to $A000: <tscreen><verb> -cl65 -o file.prg -Wl -S,$A000 -t cX16 -C cX16-asm.cfg source.s +cl65 -o file.prg -Wl -S,$A000 -t cx16 -C cx16-asm.cfg source.s </verb></tscreen> It also is possible to add a small BASIC header to the program, that uses SYS @@ -208,12 +211,22 @@ structures, accessing the struct fields will access the chip registers. <sect>Loadable drivers<p> -The names in the parentheses denote the symbols to be used for static linking of the drivers. +The names in the parentheses denote the symbols to be used for static linking +of the drivers. The names fit into the 8.3 character limit of the SD-Card's +FAT32 file-system. <sect1>Graphics drivers<p> -No graphics drivers are available currently for the CX16. +The default drivers, <tt/tgi_stddrv (tgi_static_stddrv)/, +point to <tt/cx320p1.tgi (cx320p1_tgi)/. + +<descrip> + <tag><tt/cx320p1.tgi (cx320p1_tgi)/</tag> + This driver features a resolution of 320 across and 200 down with 256 colors, + and a slightly adjustable palette (the order of the colors can be changed in + a way that's compatible with some of the other color drivers). +</descrip><p> <sect1>Extended memory drivers<p> @@ -224,10 +237,10 @@ No extended memory drivers are available currently for the CX16. <sect1>Joystick drivers<p> The default drivers, <tt/joy_stddrv (joy_static_stddrv)/, -point to <tt/cX16-std.joy (cx16_std_joy)/. +point to <tt/cx16-std.joy (cx16_std_joy)/. <descrip> - <tag><tt/cX16-std.joy (cX16_std_joy)/</tag> + <tag><tt/cx16-std.joy (cx16_std_joy)/</tag> Supports up to two NES (and SNES) controllers connected to the joystick ports of the CX16. It reads the four directions, and the <bf/A/, <bf/B/, <bf/Select/, and <bf/Start/ buttons. Buttons <bf/A/ and <bf/B/ are @@ -238,15 +251,15 @@ point to <tt/cX16-std.joy (cx16_std_joy)/. <sect1>Mouse drivers<p> The default drivers, <tt/mouse_stddrv (mouse_static_stddrv)/, -point to <tt/cX16-std.mou (cx16_std_mou)/. +point to <tt/cx16-std.mou (cx16_std_mou)/. <descrip> - <tag><tt/cX16-std.mou (cX16_std_mou)/</tag> + <tag><tt/cx16-std.mou (cx16_std_mou)/</tag> Supports a standard 3-button mouse connected to the PS/2 mouse port of the Commander X16. - Currently (r35), this driver doesn't support <tt/mouse_move()/ - and <tt/mouse_setbox()/. + Currently, this driver doesn't support <tt/mouse_move()/ and + <tt/mouse_setbox()/. </descrip><p> diff --git a/include/cx16.h b/include/cx16.h index 253fa2482..f129b26f4 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -111,6 +111,25 @@ #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_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 + /* NES controller masks for joy_read() */ #define JOY_BTN_1_MASK 0x80 @@ -280,8 +299,9 @@ struct __emul { /* The addresses of the static drivers */ -extern void cx16_std_joy[]; /* Referred to by joy_static_stddrv[] */ -extern void cx16_std_mou[]; /* Referred to by mouse_static_stddrv[] */ +extern void cx16_std_joy[]; /* Referenced by joy_static_stddrv[] */ +extern void cx16_std_mou[]; /* Referenced by mouse_static_stddrv[] */ +extern void cx320p1_tgi[]; /* Referenced by tgi_static_stddrv[] */ diff --git a/libsrc/cx16/tgi/cx320p1.s b/libsrc/cx16/tgi/cx320p1.s new file mode 100644 index 000000000..1ad5c2cbd --- /dev/null +++ b/libsrc/cx16/tgi/cx320p1.s @@ -0,0 +1,401 @@ +; +; Graphics driver for the 320 pixels across, 200 pixels down, 256 colors mode +; on the Commander X16 +; +; 2020-07-02, Greg King <gregdk@users.sf.net> +; + + .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 _cx320p1_tgi ; 320 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 320 ; X resolution + .word 200 ; Y resolution + .byte <$0100 ; Number of drawing colors + .byte 1 ; 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 + +GRAPH320 = $80 + +; ------------------------------------------------------------------------ +; 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 + +; 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. + +defpalette: .res $0100 +palette: .res $0100 + +bcolor := palette + 0 ; Background color +color: .res 1 ; Stroke and fill index +mode: .res 1 ; Old text mode + +.data + +error: .byte TGI_ERR_OK ; Error code + + +.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. + + lda SCREEN_MODE + sta mode + +; Switch into (320 x 200 x 256) graphics mode. + + lda #GRAPH320 + jmp SCREEN_SET_MODE + +; ------------------------------------------------------------------------ +; 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: +; Work around a prerelease 37 Kernal bug. +; VERA (graphics) layer 0 isn't disabled by SCREEN_SET_MODE. + + stz VERA::CTRL + lda VERA::DISP::VIDEO + and #<~VERA::DISP::ENABLE::LAYER0 + sta VERA::DISP::VIDEO + + lda mode + jmp SCREEN_SET_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 := GRAPH_CLEAR + +; ------------------------------------------------------------------------ +; 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 + sta color + lda palette,x ; Set stroke and fill color + tax + ldy bcolor ; Get background color + jmp GRAPH_SET_COLORS + +; ------------------------------------------------------------------------ +; 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 + ldx #>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 + ldx #>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 Point + jsr FB_CURSOR_POSITION + ldx color + lda palette,x + jmp FB_SET_PIXEL + +; ------------------------------------------------------------------------ +; 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 Point + jsr FB_CURSOR_POSITION + jsr FB_GET_PIXEL + ldx #>$0000 + 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. +; +; Must set an error code: NO + +LINE: jsr Point + setReg r2, X2 + setReg r3, Y2 + jmp GRAPH_DRAW_LINE + +; ------------------------------------------------------------------------ +; 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: +; Set the starting corner. + + jsr Point + +; Set the width. + + lda X2 + sub X1 + sta gREG::r2 + lda X2+1 + sbc X1+1 + sta gREG::r2+1 + +; Set the height. + + lda Y2 + sub Y1 + sta gREG::r3 + lda Y2+1 + sbc Y1+1 + sta gREG::r3+1 + +; Set the corner radius. + + stz gREG::r4 + stz gREG::r4+1 + + sec ; Fill the rectangle + jmp GRAPH_DRAW_RECT + +; ------------------------------------------------------------------------ +; 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 diff --git a/libsrc/cx16/tgi_stat_stddrv.s b/libsrc/cx16/tgi_stat_stddrv.s index e501f4c2f..e3cec1c8c 100644 --- a/libsrc/cx16/tgi_stat_stddrv.s +++ b/libsrc/cx16/tgi_stat_stddrv.s @@ -1,10 +1,11 @@ ; ; Address of the static standard TGI driver ; -; 2019-12-22, Greg King +; 2020-06-04, Greg King ; ; const void tgi_static_stddrv[]; ; - .import _cx16_320x8b_tgi - .export _tgi_static_stddrv := _cx16_320x8b_tgi + .import _cx320p1_tgi ; 320 pixels across, 1 pixel per byte + + .export _tgi_static_stddrv := _cx320p1_tgi diff --git a/libsrc/cx16/tgi_stddrv.s b/libsrc/cx16/tgi_stddrv.s index 0e46a6cb3..f05ab7131 100644 --- a/libsrc/cx16/tgi_stddrv.s +++ b/libsrc/cx16/tgi_stddrv.s @@ -1,12 +1,14 @@ ; ; Name of the standard TGI driver ; -; 2019-12-22, Greg King +; 2020-06-04, Greg King ; ; const char tgi_stddrv[]; ; .export _tgi_stddrv +; A FAT32 8+3 file-name (for SD cards) + .rodata -_tgi_stddrv: .asciiz "cx16-320x8b.tgi" +_tgi_stddrv: .asciiz "cx320p1.tgi" diff --git a/samples/mandelbrot.c b/samples/mandelbrot.c index d7291c5b5..595bcfbbb 100644 --- a/samples/mandelbrot.c +++ b/samples/mandelbrot.c @@ -51,6 +51,7 @@ void mandelbrot (signed short x1, signed short y1, signed short x2, register signed short r, r1, i; register signed short xs, ys, xx, yy; register signed short x, y; + register unsigned char maxcol = MAXCOL; /* Calc stepwidth */ xs = ((x2 - x1) / (SCREEN_X)); @@ -76,10 +77,15 @@ void mandelbrot (signed short x1, signed short y1, signed short x2, if (count == maxiterations) { tgi_setcolor (0); } else { - if (MAXCOL == 2) { + switch (maxcol) { + case 2: tgi_setcolor (1); - } else { - tgi_setcolor (count % MAXCOL); + break; + case 0: /* 256 colors */ + tgi_setcolor (count); + break; + default: + tgi_setcolor (count % maxcol); } } /* Set pixel */ From 0e55d33cc309b88e04b739638a0ed68bafe98a80 Mon Sep 17 00:00:00 2001 From: Spiro Trikaliotis <spiro.trikaliotis@gmx.de> Date: Thu, 16 Jul 2020 17:56:58 +0200 Subject: [PATCH 1426/2161] Fix info page building for newer linuxdoc In ca65.sgml, the following pattern was used in tables in order to create an empty row: ||~@ That is, the first two columns are empty, the last one has an   Unfortunately, with newer linuxdoc, this fails, as the empty columns create two @item directly after each other, which is not allowed. Changing this to ~|~|~@ fixes it by adding an " " into each column. Furthermore, the last line had a "newrow" (@) separator, which created an artifact. Removed that one. --- doc/ca65.sgml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 2c4593d21..8d97bddfd 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -622,7 +622,7 @@ problem in most cases. <tabular ca="clc"> <bf/Operator/| <bf/Description/| <bf/Precedence/@<hline> | Built-in string functions| 0@ -||~@ +~|~|~@ | Built-in pseudo-variables| 1@ | Built-in pseudo-functions| 1@ +| Unary positive| 1@ @@ -635,7 +635,7 @@ problem in most cases. .HIBYTE| Unary high-byte operator| 1@ ^<newline> .BANKBYTE| Unary bank-byte operator| 1@ -||~@ +~|~|~@ *| Multiplication| 2@ /| Division| 2@ .MOD| Modulo operator| 2@ @@ -647,28 +647,28 @@ problem in most cases. .SHL| Shift-left operator| 2@ >><newline> .SHR| Shift-right operator| 2@ -||~@ +~|~|~@ +| Binary addition| 3@ -| Binary subtraction| 3@ |<newline> .BITOR| Bitwise or| 3@ -||~@ +~|~|~@ = | Compare operator (equal)| 4@ <>| Compare operator (not equal)| 4@ <| Compare operator (less)| 4@ >| Compare operator (greater)| 4@ <=| Compare operator (less or equal)| 4@ >=| Compare operator (greater or equal)| 4@ -||~@ +~|~|~@ &&<newline> .AND| Boolean and| 5@ .XOR| Boolean xor| 5@ -||~@ +~|~|~@ ||<newline> .OR| Boolean or| 6@ -||~@ +~|~|~@ !<newline> -.NOT| Boolean not| 7@<hline> +.NOT| Boolean not| 7 </tabular> <caption>Available operators, sorted by precedence </table> From ba48dfe65ddab173a00f85bcba272fc227f59824 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 16 Jul 2020 14:06:23 -0400 Subject: [PATCH 1427/2161] Fixed a typo in the CX16 document. --- doc/cx16.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/cx16.sgml b/doc/cx16.sgml index a73bb3c1e..490d07849 100644 --- a/doc/cx16.sgml +++ b/doc/cx16.sgml @@ -20,7 +20,7 @@ The Commander X16 is a modern small computer with firmware that is based partly on the ROMs in Commodore's VIC-20 and 64C. It has a couple of I/O chips (WDC65C22 VIA) that are like the ones in the VIC-20. It supports file storage on Secure Digital cards. It allows two joysticks and a mouse. It has three -sound devices. It's VGA screen has twice the range of the C64 (similar to the +sound devices. Its VGA screen has twice the range of the C64 (similar to the C128's 80-column screen), with 256 colors. This file contains an overview of the CX16 run-time system as it comes with the From 21084895230d137db87f8a4febac8a9359e8e548 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 15 Jul 2020 20:22:28 +0800 Subject: [PATCH 1428/2161] Fix for Issue #1075 and #1077. --- src/cc65/assignment.c | 6 +- src/cc65/codegen.c | 5 + src/cc65/codegen.h | 7 +- src/cc65/declare.c | 9 +- src/cc65/expr.c | 231 +++++++++++++++++++------------------ src/cc65/exprdesc.c | 196 ++++++++++++++++++++++++++----- src/cc65/exprdesc.h | 263 ++++++++++++++++++++++++++++++++---------- src/cc65/loadexpr.c | 80 ++++++++----- src/cc65/locals.c | 2 +- src/cc65/shiftexpr.c | 10 +- src/cc65/stdfunc.c | 30 ++--- src/cc65/typeconv.c | 19 ++- 12 files changed, 598 insertions(+), 260 deletions(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index f0607ac58..8e42a338f 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -98,7 +98,7 @@ void Assignment (ExprDesc* Expr) if (UseReg) { PushAddr (Expr); } else { - ED_MakeRVal (Expr); + ED_MarkExprAsRVal (Expr); LoadExpr (CF_NONE, Expr); g_push (CF_PTR | CF_UNSIGNED, 0); } @@ -127,7 +127,7 @@ void Assignment (ExprDesc* Expr) } else { /* We will use memcpy. Push the address of the rhs */ - ED_MakeRVal (&Expr2); + ED_MarkExprAsRVal (&Expr2); LoadExpr (CF_NONE, &Expr2); /* Push the address (or whatever is in ax in case of errors) */ @@ -264,5 +264,5 @@ void Assignment (ExprDesc* Expr) } /* Value is still in primary and not an lvalue */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); } diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 920d8fe90..7af329b91 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -100,6 +100,11 @@ static const char* GetLabelName (unsigned Flags, uintptr_t Label, long Offs) /* Create the correct label name */ switch (Flags & CF_ADDRMASK) { + case CF_IMM: + /* Immediate constant values */ + xsprintf (Buf, sizeof (Buf), "$%04X", (unsigned)((Offs) & 0xFFFF)); + break; + case CF_STATIC: /* Static memory cell */ if (Offs) { diff --git a/src/cc65/codegen.h b/src/cc65/codegen.h index 6f61b33a6..af539df8b 100644 --- a/src/cc65/codegen.h +++ b/src/cc65/codegen.h @@ -81,11 +81,12 @@ #define CF_TEST 0x0080 /* Test value */ #define CF_FIXARGC 0x0100 /* Function has fixed arg count */ #define CF_FORCECHAR 0x0200 /* Handle chars as chars, not ints */ -#define CF_REG 0x0800 /* Value is in primary register */ /* Type of static address */ -#define CF_ADDRMASK 0xF000 /* Type of address */ -#define CF_STATIC 0x0000 /* Static local */ +#define CF_ADDRMASK 0xFC00 /* Type of address */ +#define CF_IMM 0x0000 /* Value is pure rvalue and has no address */ +#define CF_REG 0x0400 /* Value is in primary register */ +#define CF_STATIC 0x0800 /* Static local */ #define CF_EXTERNAL 0x1000 /* Static external */ #define CF_ABSOLUTE 0x2000 /* Numeric absolute address */ #define CF_LOCAL 0x4000 /* Auto variable */ diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 58baaf769..5827eb6dc 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1773,9 +1773,14 @@ static void DefineData (ExprDesc* Expr) { switch (ED_GetLoc (Expr)) { + case E_LOC_NONE: + /* Immediate numeric value with no storage */ + g_defdata (CF_IMM | TypeOf (Expr->Type) | CF_CONST, Expr->IVal, 0); + break; + case E_LOC_ABS: - /* Absolute: numeric address or const */ - g_defdata (TypeOf (Expr->Type) | CF_CONST, Expr->IVal, 0); + /* Absolute numeric address */ + g_defdata (CF_ABSOLUTE | TypeOf(Expr->Type) | CF_CONST, Expr->IVal, 0); break; case E_LOC_GLOBAL: diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 84f11189e..38a52e744 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -83,6 +83,7 @@ static unsigned GlobalModeFlags (const ExprDesc* Expr) /* Return the addressing mode flags for the given expression */ { switch (ED_GetLoc (Expr)) { + case E_LOC_NONE: return CF_IMM; case E_LOC_ABS: return CF_ABSOLUTE; case E_LOC_GLOBAL: return CF_EXTERNAL; case E_LOC_STATIC: return CF_STATIC; @@ -183,7 +184,7 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); - if (ED_IsLocAbs (lhs)) { + if (ED_IsLocNone (lhs)) { ltype |= CF_CONST; } if (NoPush) { @@ -191,7 +192,7 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) ltype |= CF_REG; } rtype = TypeOf (rhst); - if (ED_IsLocAbs (rhs)) { + if (ED_IsLocNone (rhs)) { rtype |= CF_CONST; } flags = g_typeadjust (ltype, rtype); @@ -506,7 +507,7 @@ static void FunctionCall (ExprDesc* Expr) ** the pointer into the primary and mark it as an expression. */ LoadExpr (CF_NONE, Expr); - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); /* Remember the code position */ GetCodePos (&Mark); @@ -646,7 +647,7 @@ static void FunctionCall (ExprDesc* Expr) } /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); Expr->Type = GetFuncReturn (Expr->Type); } @@ -663,7 +664,7 @@ static void Primary (ExprDesc* E) /* Character and integer constants. */ if (CurTok.Tok == TOK_ICONST || CurTok.Tok == TOK_CCONST) { E->IVal = CurTok.IVal; - E->Flags = E_LOC_ABS | E_RTYPE_RVAL; + E->Flags = E_LOC_NONE | E_RTYPE_RVAL; E->Type = CurTok.Type; NextToken (); return; @@ -672,7 +673,7 @@ static void Primary (ExprDesc* E) /* Floating point constant */ if (CurTok.Tok == TOK_FCONST) { E->FVal = CurTok.FVal; - E->Flags = E_LOC_ABS | E_RTYPE_RVAL; + E->Flags = E_LOC_NONE | E_RTYPE_RVAL; E->Type = CurTok.Type; NextToken (); return; @@ -716,7 +717,7 @@ static void Primary (ExprDesc* E) NextToken (); Entry = AddLabelSym (CurTok.Ident, SC_REF | SC_GOTO_IND); /* output its label */ - E->Flags = E_RTYPE_RVAL | E_LOC_STATIC; + E->Flags = E_RTYPE_RVAL | E_LOC_STATIC | E_ADDRESS_OF; E->Name = Entry->V.L.Label; E->Type = PointerTo (type_void); NextToken (); @@ -756,7 +757,7 @@ static void Primary (ExprDesc* E) /* Check for legal symbol types */ if ((Sym->Flags & SC_CONST) == SC_CONST) { /* Enum or some other numeric constant */ - E->Flags = E_LOC_ABS | E_RTYPE_RVAL; + E->Flags = E_LOC_NONE | E_RTYPE_RVAL; E->IVal = Sym->V.ConstVal; } else if ((Sym->Flags & SC_FUNC) == SC_FUNC) { /* Function */ @@ -797,12 +798,12 @@ static void Primary (ExprDesc* E) /* We've made all variables lvalues above. However, this is ** not always correct: An array is actually the address of its - ** first element, which is a rvalue, and a function is a + ** first element, which is an rvalue, and a function is an ** 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)) { - ED_MakeRVal (E); + ED_AddrExpr (E); } } else { @@ -845,7 +846,7 @@ static void Primary (ExprDesc* E) /* String literal */ E->LVal = UseLiteral (CurTok.SVal); E->Type = GetCharArrayType (GetLiteralSize (CurTok.SVal)); - E->Flags = E_LOC_LITERAL | E_RTYPE_RVAL; + E->Flags = E_LOC_LITERAL | E_RTYPE_RVAL | E_ADDRESS_OF; E->IVal = 0; E->Name = GetLiteralLabel (CurTok.SVal); NextToken (); @@ -854,7 +855,7 @@ static void Primary (ExprDesc* E) case TOK_ASM: /* ASM statement */ AsmStatement (); - E->Flags = E_LOC_EXPR | E_RTYPE_RVAL; + E->Flags = E_RTYPE_RVAL; E->Type = type_void; break; @@ -912,12 +913,11 @@ static void ArrayRef (ExprDesc* Expr) /* We can apply a special treatment for arrays that have a const base ** address. This is true for most arrays and will produce a lot better - ** code. Check if this is a const base address. + ** code. Check if this is a "quasi-const base" address. */ - ConstBaseAddr = ED_IsRVal (Expr) && - (ED_IsLocConst (Expr) || ED_IsLocStack (Expr)); + ConstBaseAddr = ED_IsRVal (Expr) && ED_IsLocQuasiConst (Expr); - /* If we have a constant base, we delay the address fetch */ + /* If we have a quasi-const base address, we delay the address fetch */ GetCodePos (&Mark1); if (!ConstBaseAddr) { /* Get a pointer to the array into the primary */ @@ -984,7 +984,7 @@ static void ArrayRef (ExprDesc* Expr) /* If the subscript is a bit-field, load it and make it an rvalue */ if (ED_IsBitField (&Subscript)) { LoadExpr (CF_NONE, &Subscript); - ED_MakeRValExpr (&Subscript); + ED_FinalizeRValLoad (&Subscript); } /* Check if the subscript is constant absolute value */ @@ -1015,25 +1015,21 @@ static void ArrayRef (ExprDesc* Expr) ** already in Expr. If the base address was a constant, we can even ** remove the code that loaded the address into the primary. */ - if (IsTypeArray (Expr->Type)) { - - /* Adjust the offset */ - Expr->IVal += Subscript.IVal; - - } else { - + if (!IsTypeArray (Expr->Type)) { + /* It's a pointer, so we do have to load it into the primary ** first (if it's not already there). */ - if (ConstBaseAddr || ED_IsLVal (Expr)) { + if (!ConstBaseAddr && ED_IsLVal (Expr)) { LoadExpr (CF_NONE, Expr); - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); } - - /* Use the offset */ - Expr->IVal = Subscript.IVal; } + /* Adjust the offset */ + Expr->IVal += Subscript.IVal; + + } else { /* Scale the rhs value according to the element type */ @@ -1106,7 +1102,7 @@ static void ArrayRef (ExprDesc* Expr) ** subscript was not scaled, that is, if this was a byte array ** or pointer. */ - if ((ED_IsLocConst (&Subscript) || ED_IsLocStack (&Subscript)) && + if (ED_IsLocQuasiConst (&Subscript) && CheckedSizeOf (ElementType) == SIZEOF_CHAR) { unsigned Flags; @@ -1131,12 +1127,13 @@ static void ArrayRef (ExprDesc* Expr) } } else { - if (ED_IsLocAbs (Expr)) { + if (ED_IsLocNone (Expr) || + (ED_IsLocAbs (Expr) && ED_IsAddrExpr (Expr))) { /* Constant numeric address. Just add it */ g_inc (CF_INT, Expr->IVal); } else if (ED_IsLocStack (Expr)) { /* Base address is a local variable address */ - if (IsTypeArray (Expr->Type)) { + if (ED_IsAddrExpr (Expr)) { g_addaddr_local (CF_INT, Expr->IVal); } else { g_addlocal (CF_PTR, Expr->IVal); @@ -1144,7 +1141,7 @@ static void ArrayRef (ExprDesc* Expr) } else { /* Base address is a static variable address */ unsigned Flags = CF_INT | GlobalModeFlags (Expr); - if (ED_IsRVal (Expr)) { + if (ED_IsAddrExpr (Expr)) { /* Add the address of the location */ g_addaddr_static (Flags, Expr->Name, Expr->IVal); } else { @@ -1153,27 +1150,27 @@ static void ArrayRef (ExprDesc* Expr) } } } - - } - /* The result is an expression in the primary */ - ED_MakeRValExpr (Expr); + /* The pointer is an rvalue in the primary */ + ED_FinalizeRValLoad (Expr); } - /* Result is of element type */ + /* The result is usually an lvalue expression of element type referenced in + ** the primary, unless it's an array which is a rare case. We can just + ** assume the usual case first, and change it later if necessary. + */ + ED_IndExpr (Expr); Expr->Type = ElementType; - /* An array element is actually a variable. So the rules for variables - ** with respect to the reference type apply: If it's an array, it is - ** a rvalue, otherwise it's an lvalue. (A function would also be a rvalue, - ** but an array cannot contain functions). + /* An array element is actually a variable. So the rules for variables with + ** respect to the reference type apply: If it's an array, it is virtually + ** an rvalue address, otherwise it's an lvalue reference. (A function would + ** also be an rvalue address, but an array cannot contain functions). */ if (IsTypeArray (Expr->Type)) { - ED_MakeRVal (Expr); - } else { - ED_MakeLVal (Expr); + ED_AddrExpr (Expr); } /* Consume the closing bracket */ @@ -1210,16 +1207,26 @@ static void StructRef (ExprDesc* Expr) return; } - /* If we have a struct pointer that is an lvalue and not already in the - ** primary, load it now. - */ - if (ED_IsLVal (Expr) && IsTypePtr (Expr->Type)) { + if (IsTypePtr (Expr->Type)) { + /* If we have a struct pointer that is an lvalue and not already in the + ** primary, load its content now. + */ + if (!ED_IsConst (Expr)) { + /* Load into the primary */ + LoadExpr (CF_NONE, Expr); - /* Load into the primary */ + /* Clear the offset */ + Expr->IVal = 0; + } + + /* Dereference the expression */ + ED_IndExpr (Expr); + + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { + /* Load the base address into the primary (and use it as a reference + ** later) if it's not quasi-const or in the primary already. + */ LoadExpr (CF_NONE, Expr); - - /* Make it an lvalue expression */ - ED_MakeLValExpr (Expr); } /* The type is the type of the field plus any qualifiers from the struct */ @@ -1235,8 +1242,8 @@ static void StructRef (ExprDesc* Expr) FinalType->C |= Q; } - /* A struct is usually an lvalue. If not, it is a struct in the primary - ** register. + /* A struct is usually an lvalue. If not, it is a struct referenced in the + ** primary register, which is likely to be returned from a function. */ if (ED_IsRVal (Expr) && ED_IsLocExpr (Expr) && !IsTypePtr (Expr->Type)) { @@ -1289,13 +1296,12 @@ static void StructRef (ExprDesc* Expr) /* An struct member is actually a variable. So the rules for variables ** with respect to the reference type apply: If it's an array, it is - ** a rvalue, otherwise it's an lvalue. (A function would also be a rvalue, - ** but a struct field cannot be a function). + ** virtually an rvalue address, otherwise it's an lvalue reference. (A + ** function would also be an rvalue address, but a struct field cannot + ** contain functions). */ if (IsTypeArray (Expr->Type)) { - ED_MakeRVal (Expr); - } else { - ED_MakeLVal (Expr); + ED_AddrExpr (Expr); } /* Make the expression a bit field if necessary */ @@ -1391,7 +1397,7 @@ void Store (ExprDesc* Expr, const Type* StoreType) switch (ED_GetLoc (Expr)) { case E_LOC_ABS: - /* Absolute: numeric address or const */ + /* Absolute numeric addressed variable */ g_putstatic (Flags, Expr->IVal, 0); break; @@ -1421,10 +1427,14 @@ void Store (ExprDesc* Expr, const Type* StoreType) break; case E_LOC_EXPR: - /* An expression in the primary register */ + /* An expression referenced in the primary register */ g_putind (Flags, Expr->IVal); break; + case E_LOC_NONE: + /* We may get here as a result of previous compiler errors */ + break; + default: Internal ("Invalid location in Store(): 0x%04X", ED_GetLoc (Expr)); } @@ -1466,7 +1476,7 @@ static void PreInc (ExprDesc* Expr) switch (ED_GetLoc (Expr)) { case E_LOC_ABS: - /* Absolute: numeric address or const */ + /* Absolute numeric addressed variable */ g_addeqstatic (Flags, Expr->IVal, 0, Val); break; @@ -1497,7 +1507,7 @@ static void PreInc (ExprDesc* Expr) break; case E_LOC_EXPR: - /* An expression in the primary register */ + /* An expression referenced in the primary register */ g_addeqind (Flags, Expr->IVal, Val); break; @@ -1506,7 +1516,7 @@ static void PreInc (ExprDesc* Expr) } /* Result is an expression, no reference */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); } @@ -1542,7 +1552,7 @@ static void PreDec (ExprDesc* Expr) switch (ED_GetLoc (Expr)) { case E_LOC_ABS: - /* Absolute: numeric address or const */ + /* Absolute numeric addressed variable */ g_subeqstatic (Flags, Expr->IVal, 0, Val); break; @@ -1582,7 +1592,7 @@ static void PreDec (ExprDesc* Expr) } /* Result is an expression, no reference */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); } @@ -1638,7 +1648,7 @@ static void PostInc (ExprDesc* Expr) } /* The result is always an expression, no reference */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); } @@ -1694,7 +1704,7 @@ static void PostDec (ExprDesc* Expr) } /* The result is always an expression, no reference */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); } @@ -1741,8 +1751,8 @@ static void UnaryOp (ExprDesc* Expr) default: Internal ("Unexpected token: %d", Tok); } - /* The result is a rvalue in the primary */ - ED_MakeRValExpr (Expr); + /* The result is an rvalue in the primary */ + ED_FinalizeRValLoad (Expr); } } @@ -1776,7 +1786,7 @@ void hie10 (ExprDesc* Expr) Expr->IVal = !Expr->IVal; } else { g_bneg (TypeOf (Expr->Type)); - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); ED_TestDone (Expr); /* bneg will set cc */ } break; @@ -1784,13 +1794,14 @@ void hie10 (ExprDesc* Expr) case TOK_STAR: NextToken (); ExprWithCheck (hie10, Expr); - if (ED_IsLVal (Expr) || !(ED_IsLocConst (Expr) || ED_IsLocStack (Expr))) { - /* Not a const, load it into the primary and make it a + if (ED_IsLVal (Expr) || !ED_IsLocQuasiConst (Expr)) { + /* Not a const, load the pointer into the primary and make it a ** calculated value. */ LoadExpr (CF_NONE, Expr); - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); } + /* If the expression is already a pointer to function, the ** additional dereferencing operator must be ignored. A function ** itself is represented as "pointer to function", so any number @@ -1799,7 +1810,7 @@ void hie10 (ExprDesc* Expr) */ if (IsTypeFuncPtr (Expr->Type) || IsTypeFunc (Expr->Type)) { /* Expression not storable */ - ED_MakeRVal (Expr); + ED_MarkExprAsRVal (Expr); } else { if (IsClassPtr (Expr->Type)) { Expr->Type = Indirect (Expr->Type); @@ -1810,8 +1821,8 @@ void hie10 (ExprDesc* Expr) ** address -- it already is the location of the first element. */ if (!IsTypeArray (Expr->Type)) { - /* The * operator yields an lvalue */ - ED_MakeLVal (Expr); + /* The * operator yields an lvalue reference */ + ED_IndExpr (Expr); } } break; @@ -1831,8 +1842,8 @@ void hie10 (ExprDesc* Expr) Expr->Flags &= ~E_BITFIELD; } Expr->Type = PointerTo (Expr->Type); - /* The & operator yields an rvalue */ - ED_MakeRVal (Expr); + /* The & operator yields an rvalue address */ + ED_AddrExpr (Expr); } break; @@ -2067,8 +2078,8 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */ /* Generate code */ Gen->Func (type, Expr->IVal); - /* We have a rvalue in the primary now */ - ED_MakeRValExpr (Expr); + /* We have an rvalue in the primary now */ + ED_FinalizeRValLoad (Expr); } else { @@ -2100,8 +2111,8 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */ /* Generate code */ Gen->Func (type, Expr2.IVal); - /* We have a rvalue in the primary now */ - ED_MakeRValExpr (Expr); + /* We have an rvalue in the primary now */ + ED_FinalizeRValLoad (Expr); } } } @@ -2441,7 +2452,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ GenFunc (flags, Expr2.IVal); /* The result is an rvalue in the primary */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); } /* Result type is always int */ @@ -2534,7 +2545,7 @@ static void parseadd (ExprDesc* Expr) rhst = Expr2.Type; /* Setup flags */ - if (ED_IsLocAbs (Expr)) { + if (ED_IsLocNone (Expr)) { /* A numerical constant */ flags |= CF_CONST; } else { @@ -2549,7 +2560,7 @@ static void parseadd (ExprDesc* Expr) /* Operate on pointers, result type is a pointer */ flags |= CF_PTR; /* Generate the code for the add */ - if (ED_GetLoc (Expr) == E_LOC_ABS) { + if (ED_GetLoc (Expr) == E_LOC_NONE) { /* Numeric constant */ g_inc (flags, Expr->IVal); } else { @@ -2569,7 +2580,7 @@ static void parseadd (ExprDesc* Expr) ** not a numeric constant, and the scale factor is not one ** (no scaling), we must take the long way over the stack. */ - if (ED_IsLocAbs (Expr)) { + if (ED_IsLocNone (Expr)) { /* Numeric constant, scale lhs */ Expr->IVal *= ScaleFactor; /* Generate the code for the add */ @@ -2588,7 +2599,7 @@ static void parseadd (ExprDesc* Expr) /* Integer addition */ flags |= typeadjust (Expr, &Expr2, 1); /* Generate the code for the add */ - if (ED_IsLocAbs (Expr)) { + if (ED_IsLocNone (Expr)) { /* Numeric constant */ g_inc (flags, Expr->IVal); } else { @@ -2601,8 +2612,8 @@ static void parseadd (ExprDesc* Expr) flags = CF_INT; } - /* Result is a rvalue in primary register */ - ED_MakeRValExpr (Expr); + /* Result is an rvalue in primary register */ + ED_FinalizeRValLoad (Expr); } } else { @@ -2692,8 +2703,8 @@ static void parseadd (ExprDesc* Expr) } - /* Result is a rvalue in primary register */ - ED_MakeRValExpr (Expr); + /* Result is an rvalue in primary register */ + ED_FinalizeRValLoad (Expr); } /* Condition codes not set */ @@ -2825,8 +2836,8 @@ static void parsesub (ExprDesc* Expr) g_scale (flags, -rscale); } - /* Result is a rvalue in the primary register */ - ED_MakeRValExpr (Expr); + /* Result is an rvalue in the primary register */ + ED_FinalizeRValLoad (Expr); ED_MarkAsUntested (Expr); } @@ -2860,8 +2871,8 @@ static void parsesub (ExprDesc* Expr) ** the lhs is const, we have to remove this mark, since this is no ** longer true, lhs is on stack instead. */ - if (ED_IsLocAbs (Expr)) { - ED_MakeRValExpr (Expr); + if (ED_IsLocNone (Expr)) { + ED_FinalizeRValLoad (Expr); } /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -2879,8 +2890,8 @@ static void parsesub (ExprDesc* Expr) g_scale (flags, -rscale); } - /* Result is a rvalue in the primary register */ - ED_MakeRValExpr (Expr); + /* Result is an rvalue in the primary register */ + ED_FinalizeRValLoad (Expr); ED_MarkAsUntested (Expr); } } @@ -3070,7 +3081,7 @@ static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp) g_defcodelabel (FalseLab); /* The result is an rvalue in primary */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); ED_TestDone (Expr); /* Condition codes are set */ } } @@ -3133,7 +3144,7 @@ static void hieOr (ExprDesc *Expr) } /* The result is an rvalue in primary */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); ED_TestDone (Expr); /* Condition codes are set */ } @@ -3189,7 +3200,7 @@ static void hieQuest (ExprDesc* Expr) if (!IsTypeVoid (Expr2.Type)) { /* Load it into the primary */ LoadExpr (CF_NONE, &Expr2); - ED_MakeRValExpr (&Expr2); + ED_FinalizeRValLoad (&Expr2); Expr2.Type = PtrConversion (Expr2.Type); } @@ -3212,7 +3223,7 @@ static void hieQuest (ExprDesc* Expr) if (!IsTypeVoid (Expr3.Type)) { /* Load it into the primary */ LoadExpr (CF_NONE, &Expr3); - ED_MakeRValExpr (&Expr3); + ED_FinalizeRValLoad (&Expr3); Expr3.Type = PtrConversion (Expr3.Type); } @@ -3278,7 +3289,7 @@ static void hieQuest (ExprDesc* Expr) g_defcodelabel (TrueLab); /* Setup the target expression */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); Expr->Type = ResultType; } } @@ -3294,7 +3305,7 @@ static void opeq (const GenDesc* Gen, ExprDesc* Expr, const char* Op) int MustScale; /* op= can only be used with lvalues */ - if (!ED_IsLVal (Expr)) { + if (ED_IsRVal (Expr)) { Error ("Invalid lvalue in assignment"); return; } @@ -3396,7 +3407,7 @@ static void opeq (const GenDesc* Gen, ExprDesc* Expr, const char* Op) Gen->Func (g_typeadjust (flags, TypeOf (Expr2.Type)), 0); } Store (Expr, 0); - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); } @@ -3410,7 +3421,7 @@ static void addsubeq (const GenDesc* Gen, ExprDesc *Expr, const char* Op) int MustScale; - /* We're currently only able to handle some adressing modes */ + /* We're currently only able to handle some addressing modes */ if (ED_GetLoc (Expr) == E_LOC_EXPR || ED_GetLoc (Expr) == E_LOC_PRIMARY) { /* Use generic routine */ opeq (Gen, Expr, Op); @@ -3487,7 +3498,7 @@ static void addsubeq (const GenDesc* Gen, ExprDesc *Expr, const char* Op) switch (ED_GetLoc (Expr)) { case E_LOC_ABS: - /* Absolute: numeric address or const */ + /* Absolute numeric addressed variable */ if (Gen->Tok == TOK_PLUS_ASSIGN) { g_addeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal); } else { @@ -3536,8 +3547,8 @@ static void addsubeq (const GenDesc* Gen, ExprDesc *Expr, const char* Op) Internal ("Invalid location in Store(): 0x%04X", ED_GetLoc (Expr)); } - /* Expression is a rvalue in the primary now */ - ED_MakeRValExpr (Expr); + /* Expression is an rvalue in the primary now */ + ED_FinalizeRValLoad (Expr); } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index 46377ac6b..5ff848fb7 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -80,6 +80,39 @@ void ED_MakeBitField (ExprDesc* Expr, unsigned BitOffs, unsigned BitWidth) +#if !defined(HAVE_INLINE) +int ED_IsLocQuasiConst (const ExprDesc* Expr) +/* Return true if the expression is a constant location of some sort or on the +** stack. +*/ +{ + return ED_IsLocConst (Expr) || ED_IsLocStack (Expr); +} +#endif + + + +#if !defined(HAVE_INLINE) +int ED_IsLocPrimaryOrExpr (const ExprDesc* Expr) +/* Return true if the expression is E_LOC_PRIMARY or E_LOC_EXPR */ +{ + return ED_IsLocPrimary (Expr) || ED_IsLocExpr (Expr); +} +#endif + + + +#if !defined(HAVE_INLINE) +int ED_IsIndExpr (const ExprDesc* Expr) +/* Check if the expression is a reference to its value */ +{ + return (Expr->Flags & E_ADDRESS_OF) == 0 && + !ED_IsLocNone (Expr) && !ED_IsLocPrimary (Expr); +} +#endif + + + void ED_SetCodeRange (ExprDesc* Expr, const CodeMark* Start, const CodeMark* End) /* Set the code range for this expression */ { @@ -115,8 +148,9 @@ const char* ED_GetLabelName (const ExprDesc* Expr, long Offs) /* Generate a label depending on the location */ switch (ED_GetLoc (Expr)) { + case E_LOC_NONE: case E_LOC_ABS: - /* Absolute: numeric address or const */ + /* Absolute numeric addressed variable */ SB_Printf (&Buf, "$%04X", (int)(Offs & 0xFFFF)); break; @@ -168,11 +202,11 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) -/* Make Expr an absolute const with the given value and type. */ +/* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; Expr->Type = Type; - Expr->Flags = E_LOC_ABS | E_RTYPE_RVAL | (Expr->Flags & E_HAVE_MARKS); + Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_HAVE_MARKS); Expr->Name = 0; Expr->IVal = Value; Expr->FVal = FP_D_Make (0.0); @@ -182,11 +216,11 @@ ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value) -/* Make Expr a constant integer expression with the given value */ +/* Replace Expr with a constant integer expression with the given value */ { Expr->Sym = 0; Expr->Type = type_int; - Expr->Flags = E_LOC_ABS | E_RTYPE_RVAL | (Expr->Flags & E_HAVE_MARKS); + Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_HAVE_MARKS); Expr->Name = 0; Expr->IVal = Value; Expr->FVal = FP_D_Make (0.0); @@ -195,14 +229,13 @@ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value) -ExprDesc* ED_MakeRValExpr (ExprDesc* Expr) -/* Convert Expr into a rvalue which is in the primary register without an -** offset. -*/ +ExprDesc* ED_FinalizeRValLoad (ExprDesc* Expr) +/* Finalize the result of LoadExpr to be an rvalue in the primary register */ { Expr->Sym = 0; - Expr->Flags &= ~(E_MASK_LOC | E_MASK_RTYPE | E_BITFIELD | E_NEED_TEST | E_CC_SET); - Expr->Flags |= (E_LOC_EXPR | E_RTYPE_RVAL); + Expr->Flags &= ~(E_MASK_LOC | E_MASK_RTYPE | E_BITFIELD | E_ADDRESS_OF); + Expr->Flags &= ~(E_NEED_TEST | E_CC_SET); + Expr->Flags |= (E_LOC_PRIMARY | E_RTYPE_RVAL); Expr->Name = 0; Expr->IVal = 0; /* No offset */ Expr->FVal = FP_D_Make (0.0); @@ -211,18 +244,106 @@ ExprDesc* ED_MakeRValExpr (ExprDesc* Expr) -ExprDesc* ED_MakeLValExpr (ExprDesc* Expr) -/* Convert Expr into a lvalue which is in the primary register without an -** offset. +ExprDesc* ED_AddrExpr (ExprDesc* Expr) +/* Take address of Expr. The result is always an rvalue */ +{ + switch (Expr->Flags & E_MASK_LOC) { + case E_LOC_NONE: + Error ("Cannot get the address of a numeric constant"); + break; + + case E_LOC_EXPR: + Expr->Flags &= ~(E_MASK_LOC | E_MASK_RTYPE); + Expr->Flags |= E_LOC_PRIMARY | E_RTYPE_RVAL; + break; + + default: + if ((Expr->Flags & E_ADDRESS_OF) == 0) { + Expr->Flags &= ~E_MASK_RTYPE; + Expr->Flags |= E_ADDRESS_OF | E_RTYPE_RVAL; + } else { + /* Due to the way we handle arrays, this may happen if we take + ** the address of a pointer to an array element. + */ + if (!IsTypePtr (Expr->Type)) { + Error ("Cannot get the address of an address"); + } + Expr->Flags &= ~E_MASK_RTYPE; + Expr->Flags |= E_RTYPE_RVAL; + } + break; + } + return Expr; +} + + + +ExprDesc* ED_IndExpr (ExprDesc* Expr) +/* Dereference Expr */ +{ + switch (Expr->Flags & E_MASK_LOC) { + case E_LOC_NONE: + Expr->Flags &= ~(E_MASK_LOC | E_MASK_RTYPE); + Expr->Flags |= E_LOC_ABS | E_RTYPE_LVAL; + break; + + case E_LOC_PRIMARY: + Expr->Flags &= ~(E_MASK_LOC | E_MASK_RTYPE); + Expr->Flags |= E_LOC_EXPR | E_RTYPE_LVAL; + break; + + default: + if ((Expr->Flags & E_ADDRESS_OF) != 0) { + Expr->Flags &= ~(E_MASK_RTYPE | E_ADDRESS_OF); + Expr->Flags |= E_RTYPE_LVAL; + } else { + /* Due to the limitation of LoadExpr, this may happen after we + ** have loaded the value from a referenced address, in which + ** case the content in the primary no longer refers to the + ** original address. We simply mark this as E_LOC_EXPR so that + ** some info about the original location can be retained. + ** If it's really meant to dereference a "pointer value", it + ** should be done in two steps where the pointervalue should + ** be the manually loaded first before a call into this, and + ** the offset should be manually cleared somewhere outside. + */ + Expr->Flags &= ~(E_MASK_LOC | E_MASK_RTYPE); + Expr->Flags |= E_LOC_EXPR | E_RTYPE_LVAL; + } + break; + } + return Expr; +} + + + +#if !defined(HAVE_INLINE) +int ED_IsAbs (const ExprDesc* Expr) +/* Return true if the expression denotes a numeric value or address. */ +{ + return (Expr->Flags & (E_MASK_LOC)) == (E_LOC_NONE) || + (Expr->Flags & (E_MASK_LOC|E_ADDRESS_OF)) == (E_LOC_ABS|E_ADDRESS_OF); +} +#endif + + + +#if !defined(HAVE_INLINE) +int ED_IsConstAbs (const ExprDesc* Expr) +/* Return true if the expression denotes a constant absolute value. This can be +** a numeric constant, cast to any type. */ { - Expr->Sym = 0; - Expr->Flags &= ~(E_MASK_LOC | E_MASK_RTYPE | E_BITFIELD | E_NEED_TEST | E_CC_SET); - Expr->Flags |= (E_LOC_EXPR | E_RTYPE_LVAL); - Expr->Name = 0; - Expr->IVal = 0; /* No offset */ - Expr->FVal = FP_D_Make (0.0); - return Expr; + return ED_IsRVal (Expr) && ED_IsAbs (Expr); +} +#endif + + + +int ED_IsConstAbsInt (const ExprDesc* Expr) +/* Return true if the expression is a constant (numeric) integer. */ +{ + return ED_IsConstAbs (Expr) && IsClassInt (Expr->Type); } @@ -233,16 +354,27 @@ int ED_IsConst (const ExprDesc* Expr) ** similar. */ { - return ED_IsRVal (Expr) && (Expr->Flags & E_LOC_CONST) != 0; + return (Expr->Flags & E_MASK_LOC) == E_LOC_NONE || ED_IsConstAddr (Expr); } -int ED_IsConstAbsInt (const ExprDesc* Expr) -/* Return true if the expression is a constant (numeric) integer. */ +int ED_IsConstAddr (const ExprDesc* Expr) +/* Return true if the expression denotes a constant address of some sort. This +** can be the address of a global variable (maybe with offset) or similar. +*/ { - return (Expr->Flags & (E_MASK_LOC|E_MASK_RTYPE)) == (E_LOC_ABS|E_RTYPE_RVAL) && - IsClassInt (Expr->Type); + return ED_IsAddrExpr (Expr) && ED_IsLocConst (Expr); +} + + + +int ED_IsQuasiConstAddr (const ExprDesc* Expr) +/* Return true if the expression denotes a quasi-constant address of some sort. +** This can be a constant address or a stack variable address. +*/ +{ + return ED_IsAddrExpr (Expr) && ED_IsLocQuasiConst (Expr); } @@ -251,7 +383,7 @@ int ED_IsNullPtr (const ExprDesc* Expr) /* Return true if the given expression is a NULL pointer constant */ { return (Expr->Flags & (E_MASK_LOC|E_MASK_RTYPE|E_BITFIELD)) == - (E_LOC_ABS|E_RTYPE_RVAL) && + (E_LOC_NONE|E_RTYPE_RVAL) && Expr->IVal == 0 && IsClassInt (Expr->Type); } @@ -293,6 +425,11 @@ void PrintExprDesc (FILE* F, ExprDesc* E) Flags = E->Flags; Sep = '('; fprintf (F, "Flags: 0x%04X ", Flags); + if ((Flags & E_MASK_LOC) == E_LOC_NONE) { + fprintf (F, "%cE_LOC_NONE", Sep); + Flags &= ~E_LOC_NONE; + Sep = ','; + } if (Flags & E_LOC_ABS) { fprintf (F, "%cE_LOC_ABS", Sep); Flags &= ~E_LOC_ABS; @@ -353,6 +490,11 @@ void PrintExprDesc (FILE* F, ExprDesc* E) Flags &= ~E_CC_SET; Sep = ','; } + if (Flags & E_ADDRESS_OF) { + fprintf (F, "%cE_ADDRESS_OF", Sep); + Flags &= ~E_ADDRESS_OF; + Sep = ','; + } if (Flags) { fprintf (F, "%c,0x%04X", Sep, Flags); Sep = ','; diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index e86534902..a61c5d814 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -59,22 +59,57 @@ /* Defines for the flags field of the expression descriptor */ enum { - /* Location: Where is the value we're talking about? */ + /* Location: Where is the value we're talking about? + ** + ** Remarks: + ** - E_LOC_<else> refers to any other than E_LOC_NONE and E_LOC_PRIMARY. + ** - E_LOC_EXPR can be regarded as a generalized E_LOC_<else>. + ** - E_LOC_NONE can be regarded as E_LOC_PRIMARY + E_ADDRESS_OF unless + ** remarked otherwise (see below). + ** - An E_LOC_NONE value is not considered to be an "address". + ** - ref-load doesn't change the location, while rval-load puts into the + ** primary register a "temporary" that is the straight integer rvalue or + ** a "delegate" to the real rvalue somewhere else. + ** - ref-load doesn't change the rval/lval category of the expression, + ** while rval-load converts it to an rvalue if it wasn't. + ** - In practice, ref-load is unimplemented, and can be simulated with + ** adding E_ADDRESS_OF temporaily through LoadExpr + FinalizeLoad, + ** whilst val-load is done with LoadExpr + FinalizeRValLoad. + ** + ** E_LOC_NONE -- ref-load -> + E_LOADED (int rvalue) + ** E_LOC_PRIMARY -- ref-load -> + E_LOADED (unchanged) + ** E_LOC_<else> -- ref-load -> + E_LOADED (reference lvalue) + ** + E_ADDRESS_OF -- ref-load -> + E_LOADED (address rvalue) + ** E_LOC_NONE -- val-load -> E_LOC_PRIMARY (int rvalue) + ** E_LOC_PRIMARY -- val-load -> E_LOC_PRIMARY (unchanged) + ** E_LOC_<else> -- val-load -> E_LOC_PRIMARY (rvalue/delegate) + ** + E_ADDRESS_OF -- val-load -> E_LOC_PRIMARY (address rvalue) + ** E_LOC_NONE -- take address -> (error) + ** E_LOC_PRIMARY -- take address -> + E_ADDRESS_OF (or error) + ** E_LOC_EXPR -- take address -> E_LOC_PRIMARY (address) + ** E_LOC_<else> -- take address -> + E_ADDRESS_OF (address) + ** + E_ADDRESS_OF -- take address -> (error) + ** E_LOC_NONE -- dereference -> E_LOC_ABS (lvalue reference) + ** E_LOC_PRIMARY -- dereference -> E_LOC_EXPR (lvalue reference) + ** E_LOC_<else> -- dereference -> E_LOC_EXPR (pointed-to-value, must load) + ** + E_ADDRESS_OF -- dereference -> (lvalue reference) + */ E_MASK_LOC = 0x00FF, - E_LOC_ABS = 0x0001, /* Absolute: numeric address or const */ + 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_REGISTER = 0x0008, /* Register variable */ E_LOC_STACK = 0x0010, /* Value on the stack */ - E_LOC_PRIMARY = 0x0020, /* The primary register */ - E_LOC_EXPR = 0x0040, /* An expression in the primary register */ + E_LOC_PRIMARY = 0x0020, /* Temporary in primary register */ + E_LOC_EXPR = 0x0040, /* A location that the primary register points to */ E_LOC_LITERAL = 0x0080, /* Literal in the literal pool */ /* Constant location of some sort (only if rval) */ - E_LOC_CONST = E_LOC_ABS | E_LOC_GLOBAL | E_LOC_STATIC | + E_LOC_CONST = E_LOC_NONE | E_LOC_ABS | E_LOC_GLOBAL | E_LOC_STATIC | E_LOC_REGISTER | E_LOC_LITERAL, - /* Reference? */ + /* lvalue/rvalue in C language's sense */ E_MASK_RTYPE = 0x0100, E_RTYPE_RVAL = 0x0000, E_RTYPE_LVAL = 0x0100, @@ -88,6 +123,10 @@ enum { E_HAVE_MARKS = 0x1000, /* Code marks are valid */ + E_LOADED = 0x4000, /* Expression is loaded in primary */ + + E_ADDRESS_OF = 0x8000, /* Expression is the address of the lvalue */ + }; /* Forward */ @@ -135,8 +174,18 @@ INLINE int ED_GetLoc (const ExprDesc* Expr) #endif #if defined(HAVE_INLINE) -INLINE int ED_IsLocAbs (const ExprDesc* Expr) +INLINE int ED_IsLocNone (const ExprDesc* Expr) /* Return true if the expression is an absolute value */ +{ + return (Expr->Flags & E_MASK_LOC) == E_LOC_NONE; +} +#else +# define ED_IsLocNone(Expr) (((Expr)->Flags & E_MASK_LOC) == E_LOC_NONE) +#endif + +#if defined(HAVE_INLINE) +INLINE int ED_IsLocAbs (const ExprDesc* Expr) +/* Return true if the expression is referenced with an absolute address */ { return (Expr->Flags & E_MASK_LOC) == E_LOC_ABS; } @@ -151,7 +200,7 @@ INLINE int ED_IsLocRegister (const ExprDesc* Expr) return (Expr->Flags & E_MASK_LOC) == E_LOC_REGISTER; } #else -# define ED_IsLocRegister(Expr) (((Expr)->Flags & E_MASK_LOC) == E_LOC_REGISTER) +# define ED_IsLocRegister(Expr) (((Expr)->Flags & E_MASK_LOC) == E_LOC_REGISTER) #endif #if defined(HAVE_INLINE) @@ -198,50 +247,25 @@ INLINE int ED_IsLocLiteral (const ExprDesc* Expr) INLINE int ED_IsLocConst (const ExprDesc* Expr) /* Return true if the expression is a constant location of some sort */ { - return (Expr->Flags & E_LOC_CONST) != 0; + return ((Expr)->Flags & E_MASK_LOC & ~E_LOC_CONST) == 0; } #else -# define ED_IsLocConst(Expr) (((Expr)->Flags & E_LOC_CONST) != 0) +# define ED_IsLocConst(Expr) (((Expr)->Flags & E_MASK_LOC & ~E_LOC_CONST) == 0) #endif #if defined(HAVE_INLINE) -INLINE int ED_IsLVal (const ExprDesc* Expr) -/* Return true if the expression is a reference */ +INLINE int ED_IsLocQuasiConst (const ExprDesc* Expr) +/* Return true if the expression is a constant location of some sort or on the +** stack. +*/ { - return (Expr->Flags & E_MASK_RTYPE) == E_RTYPE_LVAL; + return ED_IsLocConst (Expr) || ED_IsLocStack (Expr); } #else -# define ED_IsLVal(Expr) (((Expr)->Flags & E_MASK_RTYPE) == E_RTYPE_LVAL) -#endif - -#if defined(HAVE_INLINE) -INLINE int ED_IsRVal (const ExprDesc* Expr) -/* Return true if the expression is a rvalue */ -{ - return (Expr->Flags & E_MASK_RTYPE) == E_RTYPE_RVAL; -} -#else -# define ED_IsRVal(Expr) (((Expr)->Flags & E_MASK_RTYPE) == E_RTYPE_RVAL) -#endif - -#if defined(HAVE_INLINE) -INLINE void ED_MakeLVal (ExprDesc* Expr) -/* Make the expression a lvalue. */ -{ - Expr->Flags |= E_RTYPE_LVAL; -} -#else -# define ED_MakeLVal(Expr) do { (Expr)->Flags |= E_RTYPE_LVAL; } while (0) -#endif - -#if defined(HAVE_INLINE) -INLINE void ED_MakeRVal (ExprDesc* Expr) -/* Make the expression a rvalue. */ -{ - Expr->Flags &= ~E_RTYPE_LVAL; -} -#else -# define ED_MakeRVal(Expr) do { (Expr)->Flags &= ~E_RTYPE_LVAL; } while (0) +int ED_IsLocQuasiConst (const ExprDesc* Expr); +/* Return true if the expression denotes a constant address of some sort. This +** can be the address of a global variable (maybe with offset) or similar. +*/ #endif #if defined(HAVE_INLINE) @@ -308,6 +332,52 @@ INLINE void ED_MarkAsUntested (ExprDesc* Expr) # define ED_MarkAsUntested(Expr) do { (Expr)->Flags &= ~E_CC_SET; } while (0) #endif +#if defined(HAVE_INLINE) +INLINE int ED_IsLoaded (const ExprDesc* Expr) +/* Check if the expression is loaded. +** NOTE: This is currently unused and not working due to code complexity. +*/ +{ + return (Expr->Flags & E_LOADED) != 0; +} +#else +# define ED_IsLoaded(Expr) (((Expr)->Flags & E_LOADED) != 0) +#endif + +#if defined(HAVE_INLINE) +INLINE int ED_IsLocPrimaryOrExpr (const ExprDesc* Expr) +/* Return true if the expression is E_LOC_PRIMARY or E_LOC_EXPR */ +{ + return ED_IsLocPrimary (Expr) || ED_IsLocExpr (Expr); +} +#else +int ED_IsLocPrimaryOrExpr (const ExprDesc* Expr); +/* Return true if the expression is E_LOC_PRIMARY or E_LOC_EXPR */ +#endif + +#if defined(HAVE_INLINE) +INLINE int ED_IsAddrExpr (const ExprDesc* Expr) +/* Check if the expression is taken address of instead of its value. +*/ +{ + return (Expr->Flags & E_ADDRESS_OF) != 0; +} +#else +# define ED_IsAddrExpr(Expr) (((Expr)->Flags & E_ADDRESS_OF) != 0) +#endif + +#if defined(HAVE_INLINE) +INLINE int ED_IsIndExpr (const ExprDesc* Expr) +/* Check if the expression is a reference to its value */ +{ + return (Expr->Flags & E_ADDRESS_OF) == 0 && + !ED_IsLocNone (Expr) && !ED_IsLocPrimary (Expr); +} +#else +int ED_IsIndExpr (const ExprDesc* Expr); +/* Check if the expression is a reference to its value */ +#endif + void ED_SetCodeRange (ExprDesc* Expr, const CodeMark* Start, const CodeMark* End); /* Set the code range for this expression */ @@ -326,26 +396,79 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); */ ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); -/* Make Expr an absolute const with the given value and type. */ +/* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); -/* Make Expr a constant integer expression with the given value */ +/* Replace Expr with an constant integer with the given value */ -ExprDesc* ED_MakeRValExpr (ExprDesc* Expr); -/* Convert Expr into a rvalue which is in the primary register without an -** offset. -*/ +ExprDesc* ED_FinalizeRValLoad (ExprDesc* Expr); +/* Finalize the result of LoadExpr to be an rvalue in the primary register */ -ExprDesc* ED_MakeLValExpr (ExprDesc* Expr); -/* Convert Expr into a lvalue which is in the primary register without an -** offset. -*/ +#if defined(HAVE_INLINE) +INLINE int ED_IsLVal (const ExprDesc* Expr) +/* Return true if the expression is a reference */ +{ + return ((Expr)->Flags & E_MASK_RTYPE) == E_RTYPE_LVAL; +} +#else +# define ED_IsLVal(Expr) (((Expr)->Flags & E_MASK_RTYPE) == E_RTYPE_LVAL) +#endif -int ED_IsConst (const ExprDesc* Expr); -/* Return true if the expression denotes a constant of some sort. This can be a -** numeric constant, the address of a global variable (maybe with offset) or -** similar. +#if defined(HAVE_INLINE) +INLINE int ED_IsRVal (const ExprDesc* Expr) +/* Return true if the expression is an rvalue */ +{ + return ((Expr)->Flags & E_MASK_RTYPE) == E_RTYPE_RVAL; +} +#else +# define ED_IsRVal(Expr) (((Expr)->Flags & E_MASK_RTYPE) == E_RTYPE_RVAL) +#endif + +#if defined(HAVE_INLINE) +INLINE void ED_MarkExprAsLVal (ExprDesc* Expr) +/* Mark the expression as an lvalue. +** HINT: Consider using ED_IndExpr instead of this, unless you know what +** consequence there will be, as there are both a big part in the code +** assuming rvalue = const and a big part assuming rvalue = address. */ +{ + Expr->Flags |= E_RTYPE_LVAL; +} +#else +# define ED_MarkExprAsLVal(Expr) do { (Expr)->Flags |= E_RTYPE_LVAL; } while (0) +#endif + +#if defined(HAVE_INLINE) +INLINE void ED_MarkExprAsRVal (ExprDesc* Expr) +/* Mark the expression as an rvalue. +** HINT: Consider using ED_AddrExpr instead of this, unless you know what +** consequence there will be, as there are both a big part in the code +** assuming rvalue = const and a big part assuming rvalue = address. +*/ +{ + Expr->Flags &= ~E_RTYPE_LVAL; +} +#else +# define ED_MarkExprAsRVal(Expr) do { (Expr)->Flags &= ~E_RTYPE_LVAL; } while (0) +#endif + +ExprDesc* ED_AddrExpr (ExprDesc* Expr); +/* Take address of Expr */ + +ExprDesc* ED_IndExpr (ExprDesc* Expr); +/* Dereference Expr */ + +#if defined(HAVE_INLINE) +INLINE int ED_IsAbs (const ExprDesc* Expr) +/* Return true if the expression denotes a numeric value or address. */ +{ + return (Expr->Flags & (E_MASK_LOC)) == (E_LOC_NONE) || + (Expr->Flags & (E_MASK_LOC|E_ADDRESS_OF)) == (E_LOC_ABS|E_ADDRESS_OF); +} +#else +int ED_IsAbs (const ExprDesc* Expr); +/* Return true if the expression denotes a numeric value or address. */ +#endif #if defined(HAVE_INLINE) INLINE int ED_IsConstAbs (const ExprDesc* Expr) @@ -353,16 +476,34 @@ INLINE int ED_IsConstAbs (const ExprDesc* Expr) ** a numeric constant, cast to any type. */ { - return (Expr->Flags & (E_MASK_LOC|E_MASK_RTYPE)) == (E_LOC_ABS|E_RTYPE_RVAL); + return ED_IsRVal (Expr) && ED_IsAbs (Expr); } #else -# define ED_IsConstAbs(E) \ - (((E)->Flags & (E_MASK_LOC|E_MASK_RTYPE)) == (E_LOC_ABS|E_RTYPE_RVAL)) +int ED_IsConstAbs (const ExprDesc* Expr); +/* Return true if the expression denotes a constant absolute value. This can be +** a numeric constant, cast to any type. +*/ #endif int ED_IsConstAbsInt (const ExprDesc* Expr); /* Return true if the expression is a constant (numeric) integer. */ +int ED_IsConst (const ExprDesc* Expr); +/* Return true if the expression denotes a constant of some sort. This can be a +** numeric constant, the address of a global variable (maybe with offset) or +** similar. +*/ + +int ED_IsConstAddr (const ExprDesc* Expr); +/* Return true if the expression denotes a constant address of some sort. This +** can be the address of a global variable (maybe with offset) or similar. +*/ + +int ED_IsQuasiConstAddr (const ExprDesc* Expr); +/* Return true if the expression denotes a quasi-constant address of some sort. +** This can be a constant address or a stack variable address. +*/ + int ED_IsNullPtr (const ExprDesc* Expr); /* Return true if the given expression is a NULL pointer constant */ diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index fa37c6bbd..7eef174e2 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -48,14 +48,14 @@ -static void LoadConstant (unsigned Flags, ExprDesc* Expr) -/* Load the primary register with some constant value. */ +static void LoadAddress (unsigned Flags, ExprDesc* Expr) +/* Load the primary register with some address value. */ { switch (ED_GetLoc (Expr)) { case E_LOC_ABS: - /* Number constant */ - g_getimmed (Flags | TypeOf (Expr->Type) | CF_CONST, Expr->IVal, 0); + /* Numberic address */ + g_getimmed (Flags | CF_IMM | CF_CONST, Expr->IVal, 0); break; case E_LOC_GLOBAL: @@ -83,25 +83,38 @@ static void LoadConstant (unsigned Flags, ExprDesc* Expr) g_leasp (Expr->IVal); break; + case E_LOC_EXPR: + if (Expr->IVal != 0) { + /* We have an expression in the primary plus a constant + ** offset. Adjust the value in the primary accordingly. + */ + g_inc (Flags | CF_CONST, Expr->IVal); + } + break; + default: - Internal ("Unknown constant type: %04X", Expr->Flags); + Internal ("Unknown address type: %04X", Expr->Flags); } } void LoadExpr (unsigned Flags, struct ExprDesc* Expr) -/* Load an expression into the primary register if it is not already there. */ +/* Load an expression into the primary register if it is not already there. +** Note: This function can't modify the content in Expr since there are many +** instances of the "GetCodePos + LoadExpr (maybe indirectly) + RemoveCode" +** code pattern here and there which assumes that Expr should be unchanged, +** unfortunately. +*/ { - if (ED_IsLVal (Expr)) { + if (!ED_IsAddrExpr (Expr)) { - /* Dereferenced lvalue. If this is a bit field its type is unsigned. - ** But if the field is completely contained in the lower byte, we will - ** throw away the high byte anyway and may therefore load just the - ** low byte. + /* Lvalue. If this is a bit field its type is unsigned. But if the + ** field is completely contained in the lower byte, we will throw away + ** the high byte anyway and may therefore load just the low byte. */ if (ED_IsBitField (Expr)) { - Flags |= (Expr->BitOffs + Expr->BitWidth <= CHAR_BITS)? CF_CHAR : CF_INT; + Flags |= (Expr->BitOffs + Expr->BitWidth <= CHAR_BITS) ? CF_CHAR : CF_INT; Flags |= CF_UNSIGNED; } else { Flags |= TypeOf (Expr->Type); @@ -110,10 +123,16 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) Flags |= CF_TEST; } + /* Load the content of Expr */ switch (ED_GetLoc (Expr)) { + case E_LOC_NONE: + /* Immediate number constant */ + g_getimmed (Flags | CF_IMM | TypeOf (Expr->Type) | CF_CONST, Expr->IVal, 0); + break; + case E_LOC_ABS: - /* Absolute: numeric address or const */ + /* Absolute numeric addressed variable */ g_getstatic (Flags | CF_ABSOLUTE, Expr->IVal, 0); break; @@ -139,7 +158,15 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) break; case E_LOC_PRIMARY: - /* The primary register - just test if necessary */ + /* The primary register */ + if (Expr->IVal != 0) { + /* We have an expression in the primary plus a constant + ** offset. Adjust the value in the primary accordingly. + */ + g_inc (Flags | CF_CONST, Expr->IVal); + + /* We might want to clear the offset, but we can't */ + } if (Flags & CF_TEST) { g_test (Flags); } @@ -148,6 +175,13 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) case E_LOC_EXPR: /* Reference to address in primary with offset in Expr */ g_getind (Flags, Expr->IVal); + + /* Since the content in primary is now overwritten with the + ** dereference value, we might want to change the expression + ** loc to E_LOC_PRIMARY as well. That way we could be able to + ** call this function as many times as we want. Unfortunately, + ** we can't. + */ break; default: @@ -173,24 +207,14 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) ED_TestDone (Expr); } else { - /* An rvalue */ - if (ED_IsLocExpr (Expr)) { - if (Expr->IVal != 0) { - /* We have an expression in the primary plus a constant - ** offset. Adjust the value in the primary accordingly. - */ - Flags |= TypeOf (Expr->Type); - g_inc (Flags | CF_CONST, Expr->IVal); - } - } else { - /* Constant of some sort, load it into the primary */ - LoadConstant (Flags, Expr); - } + /* An address */ + Flags |= CF_INT | CF_UNSIGNED; + /* Constant of some sort, load it into the primary */ + LoadAddress (Flags, Expr); /* Are we testing this value? */ if (ED_NeedsTest (Expr)) { /* Yes, force a test */ - Flags |= TypeOf (Expr->Type); g_test (Flags); ED_TestDone (Expr); } diff --git a/src/cc65/locals.c b/src/cc65/locals.c index d0aab7f9c..9f8ee86ef 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -260,7 +260,7 @@ static void ParseAutoDecl (Declaration* Decl) Flags |= CF_CONST; } else { LoadExpr (CF_NONE, &Expr); - ED_MakeRVal (&Expr); + ED_MarkExprAsRVal (&Expr); } /* Push the value */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index c61514f43..c7aea5255 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -173,8 +173,8 @@ void ShiftExpr (struct ExprDesc* Expr) goto Next; } - /* If we're shifting an integer or unsigned to the right, the - ** lhs has a const address, and the shift count is larger than 8, + /* If we're shifting an integer or unsigned to the right, the lhs + ** has a quasi-const address, and the shift count is larger than 8, ** we can load just the high byte as a char with the correct ** signedness, and reduce the shift count by 8. If the remaining ** shift count is zero, we're done. @@ -182,7 +182,7 @@ void ShiftExpr (struct ExprDesc* Expr) if (Tok == TOK_SHR && IsTypeInt (Expr->Type) && ED_IsLVal (Expr) && - (ED_IsLocConst (Expr) || ED_IsLocStack (Expr)) && + ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { Type* OldType; @@ -227,8 +227,8 @@ void ShiftExpr (struct ExprDesc* Expr) } MakeRVal: - /* We have a rvalue in the primary now */ - ED_MakeRValExpr (Expr); + /* We have an rvalue in the primary now */ + ED_FinalizeRValLoad (Expr); Next: /* Set the type of the result */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 2d4317ef8..6d61f2750 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -343,7 +343,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ** address calculation could overflow in the linker. */ int AllowOneIndex = !ED_IsLocRegister (&Arg2.Expr) && - !(ED_IsLocAbs (&Arg2.Expr) && Arg2.Expr.IVal < 256); + !(ED_IsLocNone (&Arg2.Expr) && Arg2.Expr.IVal < 256); /* Calculate the real stack offset */ Offs = ED_GetStackOffs (&Arg1.Expr, 0); @@ -421,7 +421,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ** address calculation could overflow in the linker. */ int AllowOneIndex = !ED_IsLocRegister (&Arg1.Expr) && - !(ED_IsLocAbs (&Arg1.Expr) && Arg1.Expr.IVal < 256); + !(ED_IsLocNone (&Arg1.Expr) && Arg1.Expr.IVal < 256); /* Calculate the real stack offset */ Offs = ED_GetStackOffs (&Arg2.Expr, 0); @@ -520,7 +520,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("lda ptr1"); /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); Expr->Type = GetFuncReturn (Expr->Type); /* Bail out, no need for further processing */ @@ -529,7 +529,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) } /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); Expr->Type = GetFuncReturn (Expr->Type); ExitPoint: @@ -743,7 +743,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("lda ptr1"); /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); Expr->Type = GetFuncReturn (Expr->Type); /* Bail out, no need for further processing */ @@ -752,7 +752,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) } /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); Expr->Type = GetFuncReturn (Expr->Type); ExitPoint: @@ -955,7 +955,7 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) } /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); Expr->Type = GetFuncReturn (Expr->Type); /* We expect the closing brace */ @@ -1069,7 +1069,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ** address calculation could overflow in the linker. */ int AllowOneIndex = !ED_IsLocRegister (&Arg1.Expr) && - !(ED_IsLocAbs (&Arg1.Expr) && Arg1.Expr.IVal < 256); + !(ED_IsLocNone (&Arg1.Expr) && Arg1.Expr.IVal < 256); /* Calculate the real stack offset */ int Offs = ED_GetStackOffs (&Arg2.Expr, 0); @@ -1116,7 +1116,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ** address calculation could overflow in the linker. */ int AllowOneIndex = !ED_IsLocRegister (&Arg2.Expr) && - !(ED_IsLocAbs (&Arg2.Expr) && Arg2.Expr.IVal < 256); + !(ED_IsLocNone (&Arg2.Expr) && Arg2.Expr.IVal < 256); /* Calculate the real stack offset */ int Offs = ED_GetStackOffs (&Arg1.Expr, 0); @@ -1153,7 +1153,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) } /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); Expr->Type = GetFuncReturn (Expr->Type); ExitPoint: @@ -1250,7 +1250,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("tya"); /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); Expr->Type = type_size_t; /* Bail out, no need for further processing */ @@ -1279,7 +1279,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldx #$00"); /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); Expr->Type = type_size_t; /* Bail out, no need for further processing */ @@ -1304,7 +1304,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("tya"); /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); Expr->Type = type_size_t; /* Bail out, no need for further processing */ @@ -1333,7 +1333,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("tya"); /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); Expr->Type = type_size_t; /* Bail out, no need for further processing */ @@ -1348,7 +1348,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("jsr _%s", Func_strlen); /* The function result is an rvalue in the primary register */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); Expr->Type = type_size_t; ExitPoint: diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 21ad33f12..e8d581f54 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -70,7 +70,7 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) ** conversion void -> void. */ if (IsTypeVoid (NewType)) { - ED_MakeRVal (Expr); /* Never an lvalue */ + ED_MarkExprAsRVal (Expr); /* Never an lvalue */ goto ExitPoint; } @@ -105,10 +105,10 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) g_typecast (TypeOf (NewType), TypeOf (OldType) | CF_FORCECHAR); /* Value is now in primary and an rvalue */ - ED_MakeRValExpr (Expr); + ED_FinalizeRValLoad (Expr); } - } else if (ED_IsLocAbs (Expr)) { + } else if (ED_IsConstAbs (Expr)) { /* A cast of a constant numeric value to another type. Be sure ** to handle sign extension correctly. @@ -136,6 +136,15 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) } } + /* Do the integer constant <-> absolute address conversion if necessary */ + if (IsClassPtr (NewType)) { + Expr->Flags &= ~E_LOC_NONE; + Expr->Flags |= E_LOC_ABS | E_ADDRESS_OF; + } else if (IsClassInt (NewType)) { + Expr->Flags &= ~(E_LOC_ABS | E_ADDRESS_OF); + Expr->Flags |= E_LOC_NONE; + } + } else { /* The value is not a constant. If the sizes of the types are @@ -150,8 +159,8 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit typecast code. */ g_typecast (TypeOf (NewType), TypeOf (OldType) | CF_FORCECHAR); - /* Value is now a rvalue in the primary */ - ED_MakeRValExpr (Expr); + /* Value is now an rvalue in the primary */ + ED_FinalizeRValLoad (Expr); } } From d23b5773312cc9dc2d3b38620ea66aa272786153 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 16 Jul 2020 01:07:53 +0800 Subject: [PATCH 1429/2161] More compiler flags on address types to match the location types of expressions. --- src/cc65/codegen.c | 4 ++-- src/cc65/codegen.h | 39 +++++++++++++++++++++------------------ src/cc65/expr.c | 20 ++++++++++---------- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 7af329b91..20bfdf434 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -1349,7 +1349,7 @@ unsigned g_typeadjust (unsigned lhs, unsigned rhs) rtype = CF_LONG; } else if (ltype != CF_LONG && (lhs & CF_CONST) == 0 && rtype == CF_LONG) { /* We must promote the lhs to long */ - if (lhs & CF_REG) { + if (lhs & CF_PRIMARY) { g_reglong (lhs); } else { g_toslong (lhs); @@ -2338,7 +2338,7 @@ void g_call (unsigned Flags, const char* Label, unsigned ArgSize) void g_callind (unsigned Flags, unsigned ArgSize, int Offs) /* Call subroutine indirect */ { - if ((Flags & CF_LOCAL) == 0) { + if ((Flags & CF_STACK) == 0) { /* Address is in a/x */ if ((Flags & CF_FIXARGC) == 0) { /* Pass arg count */ diff --git a/src/cc65/codegen.h b/src/cc65/codegen.h index af539df8b..c63fc5398 100644 --- a/src/cc65/codegen.h +++ b/src/cc65/codegen.h @@ -62,35 +62,38 @@ #define CF_NONE 0x0000 /* No special flags */ /* Values for the actual type */ -#define CF_CHAR 0x0003 /* Operation on characters */ -#define CF_INT 0x0001 /* Operation on ints */ +#define CF_CHAR 0x0007 /* Operation on characters */ +#define CF_INT 0x0003 /* Operation on ints */ +#define CF_SHORT CF_INT /* Alias */ #define CF_PTR CF_INT /* Alias for readability */ -#define CF_LONG 0x0000 /* Operation on longs */ -#define CF_FLOAT 0x0004 /* Operation on a float */ +#define CF_LONG 0x0001 /* Operation on longs */ +#define CF_FLOAT 0x0010 /* Operation on a float */ /* Signedness */ #define CF_UNSIGNED 0x0008 /* Value is unsigned */ /* Masks for retrieving type information */ -#define CF_TYPEMASK 0x0007 /* Type information */ -#define CF_STYPEMASK 0x000F /* Includes signedness */ +#define CF_TYPEMASK 0x0017 /* Type information */ +#define CF_STYPEMASK 0x001F /* Includes signedness */ -#define CF_NOKEEP 0x0010 /* Value may get destroyed when storing */ -#define CF_CONST 0x0020 /* Constant value available */ -#define CF_CONSTADDR 0x0040 /* Constant address value available */ +#define CF_CONST 0x0040 /* Constant value available */ #define CF_TEST 0x0080 /* Test value */ #define CF_FIXARGC 0x0100 /* Function has fixed arg count */ #define CF_FORCECHAR 0x0200 /* Handle chars as chars, not ints */ +#define CF_NOKEEP 0x0400 /* Value may get destroyed when storing */ -/* Type of static address */ -#define CF_ADDRMASK 0xFC00 /* Type of address */ -#define CF_IMM 0x0000 /* Value is pure rvalue and has no address */ -#define CF_REG 0x0400 /* Value is in primary register */ -#define CF_STATIC 0x0800 /* Static local */ -#define CF_EXTERNAL 0x1000 /* Static external */ -#define CF_ABSOLUTE 0x2000 /* Numeric absolute address */ -#define CF_LOCAL 0x4000 /* Auto variable */ -#define CF_REGVAR 0x8000 /* Register variable */ +/* Type of address */ +#define CF_ADDRMASK 0xF000 /* Bit mask of address type */ +#define CF_IMM 0x0000 /* Value is pure rvalue and has no storage */ +#define CF_ABSOLUTE 0x1000 /* Numeric absolute address */ +#define CF_EXTERNAL 0x2000 /* External */ +#define CF_REGVAR 0x4000 /* Register variable */ +#define CF_LITERAL 0x7000 /* Literal */ +#define CF_PRIMARY 0x8000 /* Value is in primary register */ +#define CF_EXPR 0x9000 /* Value is addressed by primary register */ +#define CF_STATIC 0xA000 /* Local static */ +#define CF_CODE 0xB000 /* C code label location */ +#define CF_STACK 0xC000 /* Function-local auto on stack */ diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 38a52e744..d3b5255d8 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -88,10 +88,10 @@ static unsigned GlobalModeFlags (const ExprDesc* Expr) case E_LOC_GLOBAL: return CF_EXTERNAL; case E_LOC_STATIC: return CF_STATIC; case E_LOC_REGISTER: return CF_REGVAR; - case E_LOC_STACK: return CF_NONE; - case E_LOC_PRIMARY: return CF_NONE; - case E_LOC_EXPR: return CF_NONE; - case E_LOC_LITERAL: return CF_STATIC; /* Same as static */ + case E_LOC_STACK: return CF_STACK; + case E_LOC_PRIMARY: return CF_PRIMARY; + case E_LOC_EXPR: return CF_EXPR; + case E_LOC_LITERAL: return CF_LITERAL; default: Internal ("GlobalModeFlags: Invalid location flags value: 0x%04X", Expr->Flags); /* NOTREACHED */ @@ -189,7 +189,7 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) } if (NoPush) { /* Value is in primary register*/ - ltype |= CF_REG; + ltype |= CF_PRIMARY; } rtype = TypeOf (rhst); if (ED_IsLocNone (rhs)) { @@ -587,7 +587,7 @@ static void FunctionCall (ExprDesc* Expr) ** Since fastcall functions may never be variadic, we can use the ** index register for this purpose. */ - g_callind (CF_LOCAL, ParamSize, PtrOffs); + g_callind (CF_STACK, ParamSize, PtrOffs); } /* If we have a pointer on stack, remove it */ @@ -2068,7 +2068,7 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */ if ((Gen->Flags & GEN_NOPUSH) == 0) { g_push (ltype, 0); } else { - ltype |= CF_REG; /* Value is in register */ + ltype |= CF_PRIMARY; /* Value is in register */ } /* Determine the type of the operation result. */ @@ -2100,7 +2100,7 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */ } if ((Gen->Flags & GEN_NOPUSH) != 0) { RemoveCode (&Mark2); - ltype |= CF_REG; /* Value is in register */ + ltype |= CF_PRIMARY; /* Value is in register */ } } @@ -2276,7 +2276,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ flags |= CF_CONST; if ((Gen->Flags & GEN_NOPUSH) != 0) { RemoveCode (&Mark2); - ltype |= CF_REG; /* Value is in register */ + ltype |= CF_PRIMARY; /* Value is in register */ } } @@ -2550,7 +2550,7 @@ static void parseadd (ExprDesc* Expr) flags |= CF_CONST; } else { /* Constant address label */ - flags |= GlobalModeFlags (Expr) | CF_CONSTADDR; + flags |= GlobalModeFlags (Expr); } /* Check for pointer arithmetic */ From 9198b3be00168d148000a501b4270c39b8fdf598 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 17 Jul 2020 15:10:27 +0800 Subject: [PATCH 1430/2161] Fixed '&function' and '&array'. --- src/cc65/expr.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index d3b5255d8..79650109f 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1841,9 +1841,12 @@ void hie10 (ExprDesc* Expr) /* Do it anyway, just to avoid further warnings */ Expr->Flags &= ~E_BITFIELD; } + /* It's allowed in C to take the address of an array this way */ + if (!IsTypeFunc (Expr->Type) && !IsTypeArray (Expr->Type)) { + /* The & operator yields an rvalue address */ + ED_AddrExpr (Expr); + } Expr->Type = PointerTo (Expr->Type); - /* The & operator yields an rvalue address */ - ED_AddrExpr (Expr); } break; From 333fa9732642787d6ae47f9128b189f77acb1814 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 18 Jul 2020 10:34:57 +0800 Subject: [PATCH 1431/2161] Whitespaces/newlines fixes. --- src/cc65/declare.c | 2 +- src/cc65/expr.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 5827eb6dc..2a21e5a76 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1780,7 +1780,7 @@ static void DefineData (ExprDesc* Expr) case E_LOC_ABS: /* Absolute numeric address */ - g_defdata (CF_ABSOLUTE | TypeOf(Expr->Type) | CF_CONST, Expr->IVal, 0); + g_defdata (CF_ABSOLUTE | TypeOf (Expr->Type) | CF_CONST, Expr->IVal, 0); break; case E_LOC_GLOBAL: diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 79650109f..f6aa5aad6 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1029,7 +1029,6 @@ static void ArrayRef (ExprDesc* Expr) /* Adjust the offset */ Expr->IVal += Subscript.IVal; - } else { /* Scale the rhs value according to the element type */ From 66ecc0e52cc61e5969efc22c0045a739c7f6f9f3 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 18 Jul 2020 23:30:09 +0800 Subject: [PATCH 1432/2161] New utility to get the proper replacement type for passing structs/unions by value. New utility to get basic type names such as 'struct', 'union' and so on. --- src/cc65/datatype.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ src/cc65/datatype.h | 8 ++++++++ 2 files changed, 55 insertions(+) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 2d54316cd..5fcfa7115 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -78,6 +78,33 @@ Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const char* GetBasicTypeName (const Type* T) +/* Return a const name string of the basic type. +** Return "type" for unknown basic types. +*/ +{ + switch (GetType (T)) { + case T_TYPE_CHAR: return "char"; + case T_TYPE_SHORT: return "short"; + case T_TYPE_INT: return "integer"; + case T_TYPE_LONG: return "long"; + case T_TYPE_LONGLONG: return "long long"; + case T_TYPE_ENUM: return "enum"; + case T_TYPE_FLOAT: return "poinfloatter"; + case T_TYPE_DOUBLE: return "double"; + case T_TYPE_VOID: return "void"; + case T_TYPE_STRUCT: return "struct"; + case T_TYPE_UNION: return "union"; + case T_TYPE_ARRAY: return "array"; + case T_TYPE_PTR: return "pointer"; + case T_TYPE_FUNC: return "function"; + case T_TYPE_NONE: /* FALLTHROUGH */ + default: return "type"; + } +} + + + unsigned TypeLen (const Type* T) /* Return the length of the type string */ { @@ -198,6 +225,26 @@ Type* GetImplicitFuncType (void) +const Type* GetReplacementType (const Type* SType) +/* Get a replacement type for passing a struct/union in the primary register */ +{ + const Type* NewType; + /* If the size is less than or equal to that of a long, we will copy the + ** struct using the primary register, otherwise we will use memcpy. + */ + switch (SizeOf (SType)) { + case 1: NewType = type_uchar; break; + case 2: NewType = type_uint; break; + case 3: /* FALLTHROUGH */ + case 4: NewType = type_ulong; break; + default: NewType = SType; break; + } + + return NewType; +} + + + Type* PointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 92b3d0122..62ea8d06d 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -209,6 +209,11 @@ struct SymEntry; +const char* GetBasicTypeName (const Type* T); +/* Return a const name string of the basic type. +** Return "type" for unknown basic types. +*/ + unsigned TypeLen (const Type* T); /* Return the length of the type string */ @@ -238,6 +243,9 @@ Type* GetCharArrayType (unsigned Len); Type* GetImplicitFuncType (void); /* Return a type string for an inplicitly declared function */ +const Type* GetReplacementType (const Type* SType); +/* Get a replacement type for passing a struct/union in the primary register */ + Type* PointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. From 9f67b45ea0abd003a42b241d86bc763ef51b60bc Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 18 Jul 2020 23:30:09 +0800 Subject: [PATCH 1433/2161] Fixed returning by value structs/unions <= 4 bytes in size from functions. Larger ones are forbidden for now. --- src/cc65/assignment.c | 144 +++++++++++++++++++----------------------- src/cc65/expr.c | 57 +++++++++++------ src/cc65/loadexpr.c | 2 +- src/cc65/stmt.c | 16 ++++- 4 files changed, 118 insertions(+), 101 deletions(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index 8e42a338f..2a278f4a5 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -54,6 +54,69 @@ +static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) +/* Copy the struct represented by RExpr to the one represented by LExpr */ +{ + /* If the size is that of a basic type (char, int, long), we will copy + ** the struct using the primary register, otherwise we use memcpy. In + ** the former case, push the address only if really needed. + */ + const Type* ltype = LExpr->Type; + const Type* stype = GetReplacementType (ltype); + int UseReg = (stype != LExpr->Type); + + if (UseReg) { + PushAddr (LExpr); + } else { + ED_MarkExprAsRVal (LExpr); + LoadExpr (CF_NONE, LExpr); + g_push (CF_PTR | CF_UNSIGNED, 0); + } + + /* Get the expression on the right of the '=' into the primary */ + hie1 (RExpr); + + /* Check for equality of the structs */ + if (TypeCmp (ltype, RExpr->Type) < TC_STRICT_COMPATIBLE) { + Error ("Incompatible types"); + } + + /* Do we copy using the primary? */ + if (UseReg) { + + /* Check if the right hand side is an lvalue */ + if (ED_IsLVal (RExpr)) { + /* Just load the value into the primary as the replacement type. */ + LoadExpr (TypeOf (stype) | CF_FORCECHAR, RExpr); + } + + /* Store it into the new location */ + Store (LExpr, stype); + + } else { + + /* Check if the right hand side is an lvalue */ + if (ED_IsLVal (RExpr)) { + /* We will use memcpy. Push the address of the rhs */ + ED_MarkExprAsRVal (RExpr); + LoadExpr (CF_NONE, RExpr); + } + + /* Push the address (or whatever is in ax in case of errors) */ + g_push (CF_PTR | CF_UNSIGNED, 0); + + /* Load the size of the struct into the primary */ + g_getimmed (CF_INT | CF_UNSIGNED | CF_CONST, CheckedSizeOf (ltype), 0); + + /* Call the memcpy function */ + g_call (CF_FIXARGC, Func_memcpy, 4); + } + + return 0; +} + + + void Assignment (ExprDesc* Expr) /* Parse an assignment */ { @@ -79,85 +142,8 @@ void Assignment (ExprDesc* Expr) ** family, allow it here. */ if (IsClassStruct (ltype)) { - - /* Get the size of the left hand side. */ - unsigned Size = SizeOf (ltype); - - /* If the size is that of a basic type (char, int, long), we will copy - ** the struct using the primary register, otherwise we use memcpy. In - ** the former case, push the address only if really needed. - */ - int UseReg = 1; - Type* stype; - switch (Size) { - case SIZEOF_CHAR: stype = type_uchar; break; - case SIZEOF_INT: stype = type_uint; break; - case SIZEOF_LONG: stype = type_ulong; break; - default: stype = ltype; UseReg = 0; break; - } - if (UseReg) { - PushAddr (Expr); - } else { - ED_MarkExprAsRVal (Expr); - LoadExpr (CF_NONE, Expr); - g_push (CF_PTR | CF_UNSIGNED, 0); - } - - /* Get the expression on the right of the '=' into the primary */ - hie1 (&Expr2); - - /* Check for equality of the structs */ - if (TypeCmp (ltype, Expr2.Type) < TC_STRICT_COMPATIBLE) { - Error ("Incompatible types"); - } - - /* Check if the right hand side is an lvalue */ - if (ED_IsLVal (&Expr2)) { - /* We have an lvalue. Do we copy using the primary? */ - if (UseReg) { - /* Just use the replacement type */ - Expr2.Type = stype; - - /* Load the value into the primary */ - LoadExpr (CF_FORCECHAR, &Expr2); - - /* Store it into the new location */ - Store (Expr, stype); - - } else { - - /* We will use memcpy. Push the address of the rhs */ - ED_MarkExprAsRVal (&Expr2); - LoadExpr (CF_NONE, &Expr2); - - /* Push the address (or whatever is in ax in case of errors) */ - g_push (CF_PTR | CF_UNSIGNED, 0); - - /* Load the size of the struct into the primary */ - g_getimmed (CF_INT | CF_UNSIGNED | CF_CONST, CheckedSizeOf (ltype), 0); - - /* Call the memcpy function */ - g_call (CF_FIXARGC, Func_memcpy, 4); - } - - } else { - - /* We have an rvalue. This can only happen if a function returns - ** a struct, since there is no other way to generate an expression - ** that has a struct as an rvalue result. We allow only 1, 2, and 4 - ** byte sized structs, and do direct assignment. - */ - if (UseReg) { - /* Do the store */ - Store (Expr, stype); - } else { - /* Print a diagnostic */ - Error ("Structs of this size are not supported"); - /* Adjust the stack so we won't run in an internal error later */ - pop (CF_PTR); - } - - } + /* Copy the struct by value */ + CopyStruct (Expr, &Expr2); } else if (ED_IsBitField (Expr)) { diff --git a/src/cc65/expr.c b/src/cc65/expr.c index f6aa5aad6..70b28a408 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -470,6 +470,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if it's a fast-call function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ + Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -648,7 +649,19 @@ static void FunctionCall (ExprDesc* Expr) /* The function result is an rvalue in the primary register */ ED_FinalizeRValLoad (Expr); - Expr->Type = GetFuncReturn (Expr->Type); + ReturnType = GetFuncReturn (Expr->Type); + + /* Handle struct specially */ + if (IsTypeStruct (ReturnType)) { + /* If there is no replacement type, then it is just the address */ + if (ReturnType == GetReplacementType (ReturnType)) { + /* Dereference it */ + ED_IndExpr (Expr); + ED_MarkExprAsRVal (Expr); + } + } + + Expr->Type = ReturnType; } @@ -1206,12 +1219,20 @@ static void StructRef (ExprDesc* Expr) return; } - if (IsTypePtr (Expr->Type)) { - /* If we have a struct pointer that is an lvalue and not already in the - ** primary, load its content now. - */ - if (!ED_IsConst (Expr)) { - /* Load into the primary */ + /* A struct is usually an lvalue. If not, it is a struct passed in the + ** primary register, which is usually a result returned from a function. + ** However, it is possible that this rvalue is a result of certain + ** operations on an lvalue, and there are no reasons to disallow that. + ** So we just rely on the check on function returns to catch the errors + ** and dereference the rvalue address of the struct here. + */ + if (IsTypePtr (Expr->Type) || + (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetReplacementType (Expr->Type))) { + + if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* If we have a non-const struct pointer, load its content now */ LoadExpr (CF_NONE, Expr); /* Clear the offset */ @@ -1241,27 +1262,25 @@ static void StructRef (ExprDesc* Expr) FinalType->C |= Q; } - /* A struct is usually an lvalue. If not, it is a struct referenced in the - ** primary register, which is likely to be returned from a function. - */ - if (ED_IsRVal (Expr) && ED_IsLocExpr (Expr) && !IsTypePtr (Expr->Type)) { + if (ED_IsRVal (Expr) && ED_IsLocPrimary (Expr) && !IsTypePtr (Expr->Type)) { unsigned Flags = 0; unsigned BitOffs; /* Get the size of the type */ - unsigned Size = SizeOf (Expr->Type); + unsigned StructSize = SizeOf (Expr->Type); + unsigned FieldSize = SizeOf (Field->Type); /* Safety check */ - CHECK (Field->V.Offs + Size <= SIZEOF_LONG); + CHECK (Field->V.Offs + FieldSize <= StructSize); /* The type of the operation depends on the type of the struct */ - switch (Size) { - case 1: Flags = CF_CHAR | CF_UNSIGNED | CF_CONST; break; - case 2: Flags = CF_INT | CF_UNSIGNED | CF_CONST; break; + switch (StructSize) { + case 1: Flags = CF_CHAR | CF_UNSIGNED | CF_CONST; break; + case 2: Flags = CF_INT | CF_UNSIGNED | CF_CONST; break; case 3: /* FALLTHROUGH */ - case 4: Flags = CF_LONG | CF_UNSIGNED | CF_CONST; break; - default: Internal ("Invalid struct size: %u", Size); break; + case 4: Flags = CF_LONG | CF_UNSIGNED | CF_CONST; break; + default: Internal ("Invalid struct size: %u", StructSize); break; } /* Generate a shift to get the field in the proper position in the @@ -1274,7 +1293,7 @@ static void StructRef (ExprDesc* Expr) /* Mask the value. This is unnecessary if the shift executed above ** moved only zeroes into the value. */ - if (BitOffs + Field->V.B.BitWidth != Size * CHAR_BITS) { + if (BitOffs + Field->V.B.BitWidth != FieldSize * CHAR_BITS) { g_and (CF_INT | CF_UNSIGNED | CF_CONST, (0x0001U << Field->V.B.BitWidth) - 1U); } diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index 7eef174e2..bc0ee1dd0 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -116,7 +116,7 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) if (ED_IsBitField (Expr)) { Flags |= (Expr->BitOffs + Expr->BitWidth <= CHAR_BITS) ? CF_CHAR : CF_INT; Flags |= CF_UNSIGNED; - } else { + } else if ((Flags & CF_TYPEMASK) == 0) { Flags |= TypeOf (Expr->Type); } if (ED_NeedsTest (Expr)) { diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 657bc9963..a1384b0ed 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -309,7 +309,8 @@ static void WhileStatement (void) static void ReturnStatement (void) /* Handle the 'return' statement */ { - ExprDesc Expr; + ExprDesc Expr; + const Type* ReturnType; NextToken (); if (CurTok.Tok != TOK_SEMI) { @@ -328,7 +329,18 @@ static void ReturnStatement (void) TypeConversion (&Expr, F_GetReturnType (CurrentFunc)); /* Load the value into the primary */ - LoadExpr (CF_NONE, &Expr); + if (IsTypeStruct (Expr.Type) || IsTypeUnion (Expr.Type)) { + /* Handle struct/union specially */ + ReturnType = GetReplacementType (Expr.Type); + if (ReturnType == Expr.Type) { + Error ("Returning %s of this size by value is not supported", GetBasicTypeName (Expr.Type)); + } + LoadExpr (TypeOf (ReturnType), &Expr); + + } else { + /* Load the value into the primary */ + LoadExpr (CF_NONE, &Expr); + } } } else if (!F_HasVoidReturn (CurrentFunc) && !F_HasOldStyleIntRet (CurrentFunc)) { From b45d373fd6e9839d86301f539a7c458340eb6769 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 18 Jul 2020 23:30:09 +0800 Subject: [PATCH 1434/2161] Fixed passing by value structs/unions <= 4 bytes in size to functions. Larger ones are forbidden for now. --- src/cc65/expr.c | 16 +++++++++++----- src/cc65/function.c | 26 +++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 70b28a408..44137a773 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -395,12 +395,18 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) } + /* Handle struct/union specially */ + if (IsTypeStruct (Expr.Type) || IsTypeUnion (Expr.Type)) { + /* Use the replacement type */ + Flags |= TypeOf (GetReplacementType (Expr.Type)); + } else { + /* Use the type of the argument for the push */ + Flags |= TypeOf (Expr.Type); + } + /* Load the value into the primary if it is not already there */ LoadExpr (Flags, &Expr); - /* Use the type of the argument for the push */ - Flags |= TypeOf (Expr.Type); - /* If this is a fastcall function, don't push the last argument */ if ((CurTok.Tok == TOK_COMMA && NextTok.Tok != TOK_RPAREN) || !IsFastcall) { unsigned ArgSize = sizeofarg (Flags); @@ -651,8 +657,8 @@ static void FunctionCall (ExprDesc* Expr) ED_FinalizeRValLoad (Expr); ReturnType = GetFuncReturn (Expr->Type); - /* Handle struct specially */ - if (IsTypeStruct (ReturnType)) { + /* Handle struct/union specially */ + if (IsTypeStruct (ReturnType) || IsTypeUnion (ReturnType)) { /* If there is no replacement type, then it is just the address */ if (ReturnType == GetReplacementType (ReturnType)) { /* Dereference it */ diff --git a/src/cc65/function.c b/src/cc65/function.c index 8da084ac1..df667e8fa 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -380,6 +380,7 @@ void NewFunc (SymEntry* Func) { int C99MainFunc = 0;/* Flag for C99 main function returning int */ SymEntry* Param; + const Type* RType; /* Real type used for struct parameters */ /* Get the function descriptor from the function entry */ FuncDesc* D = Func->V.F.Func; @@ -475,7 +476,12 @@ void NewFunc (SymEntry* Func) /* Pointer to function */ Flags = CF_PTR; } else { - Flags = TypeOf (D->LastParam->Type) | CF_FORCECHAR; + /* Handle struct/union specially */ + if (IsTypeStruct (D->LastParam->Type) || IsTypeUnion (D->LastParam->Type)) { + Flags = TypeOf (GetReplacementType (D->LastParam->Type)) | CF_FORCECHAR; + } else { + Flags = TypeOf (D->LastParam->Type) | CF_FORCECHAR; + } } g_push (Flags, 0); } @@ -498,11 +504,25 @@ void NewFunc (SymEntry* Func) Param = D->SymTab->SymHead; while (Param && (Param->Flags & SC_PARAM) != 0) { + /* Check if we need copy for struct/union type */ + RType = Param->Type; + if (IsTypeStruct (RType) || IsTypeUnion (RType)) { + RType = GetReplacementType (RType); + + /* If there is no replacement type, then it is just the address. + ** We don't currently support this case. + */ + if (RType == Param->Type) { + Error ("Passing %s of this size by value is not supported", GetBasicTypeName (Param->Type)); + } + } + + /* Check for a register variable */ if (SymIsRegVar (Param)) { /* Allocate space */ - int Reg = F_AllocRegVar (CurrentFunc, Param->Type); + int Reg = F_AllocRegVar (CurrentFunc, RType); /* Could we allocate a register? */ if (Reg < 0) { @@ -513,7 +533,7 @@ void NewFunc (SymEntry* Func) Param->V.R.RegOffs = Reg; /* Generate swap code */ - g_swap_regvars (Param->V.R.SaveOffs, Reg, CheckedSizeOf (Param->Type)); + g_swap_regvars (Param->V.R.SaveOffs, Reg, CheckedSizeOf (RType)); } } From 0c3e1b491fce1c5ae6ad74ac2e37151c8e9efc03 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 18 Jul 2020 23:30:09 +0800 Subject: [PATCH 1435/2161] Disabled -Wstruct-param by default. --- 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 858a80826..c3ebebf77 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -67,7 +67,7 @@ IntStack WarningsAreErrors = INTSTACK(0); /* Treat warnings as errors */ IntStack WarnConstComparison= INTSTACK(1); /* - constant comparison results */ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ -IntStack WarnStructParam = INTSTACK(1); /* - structs passed by val */ +IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ From 768e03a47415f9c5aef0263175612a43e45b788e Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 19 Jul 2020 13:47:48 +0800 Subject: [PATCH 1436/2161] Small fixes and tidy-up based on PR review. Renamed GetReplacementType() to GetStructReplacementType(). Clarified in comments that most *Struct* facilities work for unions as well. Made it clear in some error messages with regards to structs/unions. --- src/cc65/assignment.c | 17 +++++------ src/cc65/datatype.c | 2 +- src/cc65/datatype.h | 4 +-- src/cc65/expr.c | 66 +++++++++++++++++++++++++------------------ src/cc65/function.c | 4 +-- src/cc65/stmt.c | 2 +- src/cc65/symtab.c | 10 +++---- src/cc65/symtab.h | 2 +- 8 files changed, 60 insertions(+), 47 deletions(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index 2a278f4a5..ed374ef8a 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -55,15 +55,15 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) -/* Copy the struct represented by RExpr to the one represented by LExpr */ +/* Copy the struct/union represented by RExpr to the one represented by LExpr */ { /* If the size is that of a basic type (char, int, long), we will copy ** the struct using the primary register, otherwise we use memcpy. In ** the former case, push the address only if really needed. */ const Type* ltype = LExpr->Type; - const Type* stype = GetReplacementType (ltype); - int UseReg = (stype != LExpr->Type); + const Type* stype = GetStructReplacementType (ltype); + int UseReg = (stype != ltype); if (UseReg) { PushAddr (LExpr); @@ -105,7 +105,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) /* Push the address (or whatever is in ax in case of errors) */ g_push (CF_PTR | CF_UNSIGNED, 0); - /* Load the size of the struct into the primary */ + /* Load the size of the struct or union into the primary */ g_getimmed (CF_INT | CF_UNSIGNED | CF_CONST, CheckedSizeOf (ltype), 0); /* Call the memcpy function */ @@ -137,12 +137,13 @@ void Assignment (ExprDesc* Expr) /* Skip the '=' token */ NextToken (); - /* cc65 does not have full support for handling structs by value. Since - ** assigning structs is one of the more useful operations from this - ** family, allow it here. + /* cc65 does not have full support for handling structs or unions. Since + ** assigning structs is one of the more useful operations from this family, + ** allow it here. + ** Note: IsClassStruct() is also true for union types. */ if (IsClassStruct (ltype)) { - /* Copy the struct by value */ + /* Copy the struct or union by value */ CopyStruct (Expr, &Expr2); } else if (ED_IsBitField (Expr)) { diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 5fcfa7115..2a989e9f8 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -225,7 +225,7 @@ Type* GetImplicitFuncType (void) -const Type* GetReplacementType (const Type* SType) +const Type* GetStructReplacementType (const Type* SType) /* Get a replacement type for passing a struct/union in the primary register */ { const Type* NewType; diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 62ea8d06d..3464e8a16 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -243,7 +243,7 @@ Type* GetCharArrayType (unsigned Len); Type* GetImplicitFuncType (void); /* Return a type string for an inplicitly declared function */ -const Type* GetReplacementType (const Type* SType); +const Type* GetStructReplacementType (const Type* SType); /* Get a replacement type for passing a struct/union in the primary register */ Type* PointerTo (const Type* T); @@ -483,7 +483,7 @@ INLINE int IsClassPtr (const Type* T) #if defined(HAVE_INLINE) INLINE int IsClassStruct (const Type* T) -/* Return true if this is a struct type */ +/* Return true if this is a struct or union type */ { return (GetClass (T) == T_CLASS_STRUCT); } diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 44137a773..828e0fd75 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -398,7 +398,7 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) /* Handle struct/union specially */ if (IsTypeStruct (Expr.Type) || IsTypeUnion (Expr.Type)) { /* Use the replacement type */ - Flags |= TypeOf (GetReplacementType (Expr.Type)); + Flags |= TypeOf (GetStructReplacementType (Expr.Type)); } else { /* Use the type of the argument for the push */ Flags |= TypeOf (Expr.Type); @@ -660,7 +660,7 @@ static void FunctionCall (ExprDesc* Expr) /* Handle struct/union specially */ if (IsTypeStruct (ReturnType) || IsTypeUnion (ReturnType)) { /* If there is no replacement type, then it is just the address */ - if (ReturnType == GetReplacementType (ReturnType)) { + if (ReturnType == GetStructReplacementType (ReturnType)) { /* Dereference it */ ED_IndExpr (Expr); ED_MarkExprAsRVal (Expr); @@ -1198,7 +1198,7 @@ static void ArrayRef (ExprDesc* Expr) static void StructRef (ExprDesc* Expr) -/* Process struct field after . or ->. */ +/* Process struct/union field after . or ->. */ { ident Ident; SymEntry* Field; @@ -1214,38 +1214,41 @@ static void StructRef (ExprDesc* Expr) return; } - /* Get the symbol table entry and check for a struct field */ + /* Get the symbol table entry and check for a struct/union field */ strcpy (Ident, CurTok.Ident); NextToken (); Field = FindStructField (Expr->Type, Ident); if (Field == 0) { - Error ("Struct/union has no field named '%s'", Ident); + Error ("No field named '%s' found in %s", GetBasicTypeName (Expr->Type), Ident); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct is usually an lvalue. If not, it is a struct passed in the - ** primary register, which is usually a result returned from a function. - ** However, it is possible that this rvalue is a result of certain - ** operations on an lvalue, and there are no reasons to disallow that. - ** So we just rely on the check on function returns to catch the errors - ** and dereference the rvalue address of the struct here. + /* A struct/union is usually an lvalue. If not, it is a struct/union passed + ** in the primary register, which is usually the result returned from a + ** function. However, it is possible that this rvalue is the result of + ** certain kind of operations on an lvalue such as assignment, and there + ** are no reasons to disallow such use cases. So we just rely on the check + ** upon function returns to catch the unsupported cases and dereference the + ** rvalue address of the struct/union here all the time. */ if (IsTypePtr (Expr->Type) || (ED_IsRVal (Expr) && ED_IsLocPrimary (Expr) && - Expr->Type == GetReplacementType (Expr->Type))) { + Expr->Type == GetStructReplacementType (Expr->Type))) { if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { - /* If we have a non-const struct pointer, load its content now */ + /* If we have a non-const struct/union pointer that is not in the + ** primary yet, load its content now. + */ LoadExpr (CF_NONE, Expr); /* Clear the offset */ Expr->IVal = 0; } - /* Dereference the expression */ + /* Dereference the address expression */ ED_IndExpr (Expr); } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { @@ -1255,7 +1258,7 @@ static void StructRef (ExprDesc* Expr) LoadExpr (CF_NONE, Expr); } - /* The type is the type of the field plus any qualifiers from the struct */ + /* The type is the field type plus any qualifiers from the struct/union */ if (IsClassStruct (Expr->Type)) { Q = GetQualifier (Expr->Type); } else { @@ -1280,13 +1283,22 @@ static void StructRef (ExprDesc* Expr) /* Safety check */ CHECK (Field->V.Offs + FieldSize <= StructSize); - /* The type of the operation depends on the type of the struct */ + /* The type of the operation depends on the type of the struct/union */ switch (StructSize) { - case 1: Flags = CF_CHAR | CF_UNSIGNED | CF_CONST; break; - case 2: Flags = CF_INT | CF_UNSIGNED | CF_CONST; break; - case 3: /* FALLTHROUGH */ - case 4: Flags = CF_LONG | CF_UNSIGNED | CF_CONST; break; - default: Internal ("Invalid struct size: %u", StructSize); break; + case 1: + Flags = CF_CHAR | CF_UNSIGNED | CF_CONST; + break; + case 2: + Flags = CF_INT | CF_UNSIGNED | CF_CONST; + break; + case 3: + /* FALLTHROUGH */ + case 4: + Flags = CF_LONG | CF_UNSIGNED | CF_CONST; + break; + default: + Internal ("Invalid %s size: %u", GetBasicTypeName (Expr->Type), StructSize); + break; } /* Generate a shift to get the field in the proper position in the @@ -1312,16 +1324,16 @@ static void StructRef (ExprDesc* Expr) } else { - /* Set the struct field offset */ + /* Set the struct/union field offset */ Expr->IVal += Field->V.Offs; /* Use the new type */ Expr->Type = FinalType; - /* An struct member is actually a variable. So the rules for variables - ** with respect to the reference type apply: If it's an array, it is + /* The usual rules for variables with respect to the reference types + ** apply to struct/union fields as well: If a field is an array, it is ** virtually an rvalue address, otherwise it's an lvalue reference. (A - ** function would also be an rvalue address, but a struct field cannot + ** function would also be an rvalue address, but a struct/union cannot ** contain functions). */ if (IsTypeArray (Expr->Type)) { @@ -1376,7 +1388,7 @@ static void hie11 (ExprDesc *Expr) case TOK_DOT: if (!IsClassStruct (Expr->Type)) { - Error ("Struct expected"); + Error ("Struct or union expected"); } StructRef (Expr); break; @@ -1387,7 +1399,7 @@ static void hie11 (ExprDesc *Expr) Expr->Type = ArrayToPtr (Expr->Type); } if (!IsClassPtr (Expr->Type) || !IsClassStruct (Indirect (Expr->Type))) { - Error ("Struct pointer expected"); + Error ("Struct pointer or union pointer expected"); } StructRef (Expr); break; diff --git a/src/cc65/function.c b/src/cc65/function.c index df667e8fa..4cd5565c4 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -478,7 +478,7 @@ void NewFunc (SymEntry* Func) } else { /* Handle struct/union specially */ if (IsTypeStruct (D->LastParam->Type) || IsTypeUnion (D->LastParam->Type)) { - Flags = TypeOf (GetReplacementType (D->LastParam->Type)) | CF_FORCECHAR; + Flags = TypeOf (GetStructReplacementType (D->LastParam->Type)) | CF_FORCECHAR; } else { Flags = TypeOf (D->LastParam->Type) | CF_FORCECHAR; } @@ -507,7 +507,7 @@ void NewFunc (SymEntry* Func) /* Check if we need copy for struct/union type */ RType = Param->Type; if (IsTypeStruct (RType) || IsTypeUnion (RType)) { - RType = GetReplacementType (RType); + RType = GetStructReplacementType (RType); /* If there is no replacement type, then it is just the address. ** We don't currently support this case. diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index a1384b0ed..6c839c420 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -331,7 +331,7 @@ static void ReturnStatement (void) /* Load the value into the primary */ if (IsTypeStruct (Expr.Type) || IsTypeUnion (Expr.Type)) { /* Handle struct/union specially */ - ReturnType = GetReplacementType (Expr.Type); + ReturnType = GetStructReplacementType (Expr.Type); if (ReturnType == Expr.Type) { Error ("Returning %s of this size by value is not supported", GetBasicTypeName (Expr.Type)); } diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index f19a251bd..f363d9134 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -488,24 +488,24 @@ SymEntry* FindTagSym (const char* Name) SymEntry* FindStructField (const Type* T, const char* Name) -/* Find a struct field in the fields list */ +/* Find a struct/union field in the fields list */ { SymEntry* Field = 0; - /* The given type may actually be a pointer to struct */ + /* The given type may actually be a pointer to struct/union */ if (IsTypePtr (T)) { ++T; } - /* Non-structs do not have any struct fields... */ + /* Only structs/unions have struct/union fields... */ if (IsClassStruct (T)) { /* Get a pointer to the struct/union type */ const SymEntry* Struct = GetSymEntry (T); CHECK (Struct != 0); - /* Now search in the struct symbol table. Beware: The table may not - ** exist. + /* Now search in the struct/union symbol table. Beware: The table may + ** not exist. */ if (Struct->V.S.SymTab) { Field = FindSymInTable (Struct->V.S.SymTab, Name, HashStr (Name)); diff --git a/src/cc65/symtab.h b/src/cc65/symtab.h index 62e731042..94e5f2d9b 100644 --- a/src/cc65/symtab.h +++ b/src/cc65/symtab.h @@ -134,7 +134,7 @@ SymEntry* FindTagSym (const char* Name); /* Find the symbol with the given name in the tag table */ SymEntry* FindStructField (const Type* TypeArray, const char* Name); -/* Find a struct field in the fields list */ +/* Find a struct/union field in the fields list */ unsigned short FindSPAdjustment (const char* Name); /* Search for an entry in the table of SP adjustments */ From bbcb39978cf3f6ed14487a3c0195b0de25429bd2 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sat, 18 Jul 2020 23:12:07 +0200 Subject: [PATCH 1437/2161] Add test of signed bitfields for #1095 --- test/todo/bug1095.c | 101 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 test/todo/bug1095.c diff --git a/test/todo/bug1095.c b/test/todo/bug1095.c new file mode 100644 index 000000000..a00a10585 --- /dev/null +++ b/test/todo/bug1095.c @@ -0,0 +1,101 @@ +/* + Copyright 2020 Google LLC + + 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. +*/ + +/* + Tests of signed bit-fields; see https://github.com/cc65/cc65/issues/1095 +*/ + +#include <stdio.h> + +static unsigned char failures = 0; + +static struct signed_ints { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} si = {-4, -1, 3}; + +static void test_signed_bitfield(void) +{ + if (si.a >= 0) { + printf("Got si.a = %d, expected negative.\n", si.a); + failures++; + } + if (si.a != -4) { + printf("Got si.a = %d, expected -4.\n", si.a); + failures++; + } + + if (si.b >= 0) { + printf("Got si.b = %d, expected negative.\n", si.b); + failures++; + } + if (si.b != -1) { + printf("Got si.b = %d, expected -1.\n", si.b); + failures++; + } + + if (si.b <= 0) { + printf("Got si.c = %d, expected positive.\n", si.c); + failures++; + } + if (si.c != 3) { + printf("Got si.c = %d, expected 3.\n", si.c); + failures++; + } + + si.a = -3; + si.b = 1; + si.c = -2; + + if (si.a >= 0) { + printf("Got si.a = %d, expected negative.\n", si.a); + failures++; + } + if (si.a != -3) { + printf("Got si.a = %d, expected -3.\n", si.a); + failures++; + } + + if (si.b <= 0) { + printf("Got si.b = %d, expected positive.\n", si.b); + failures++; + } + if (si.b != 1) { + printf("Got si.b = %d, expected 1.\n", si.b); + failures++; + } + + if (si.b >= 0) { + printf("Got si.c = %d, expected negative.\n", si.c); + failures++; + } + if (si.c != -2) { + printf("Got si.c = %d, expected -2.\n", si.c); + failures++; + } +} + +int main(void) +{ + test_signed_bitfield(); + printf("failures: %u\n", failures); + return failures; +} From 29c50ab25f24deb168cb0293c8c3259dad4c4b8f Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 19 Jul 2020 17:56:15 +0800 Subject: [PATCH 1438/2161] Corrected the error message about struct/union members not found. --- 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 828e0fd75..f28aa3965 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1219,7 +1219,7 @@ static void StructRef (ExprDesc* Expr) NextToken (); Field = FindStructField (Expr->Type, Ident); if (Field == 0) { - Error ("No field named '%s' found in %s", GetBasicTypeName (Expr->Type), Ident); + Error ("No field named '%s' found in %s", Ident, GetBasicTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; From ee208aecd6285848a8470d42ce2a7213fcf63e90 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 19 Jul 2020 13:16:12 +0200 Subject: [PATCH 1439/2161] Removed unnecessary tool. It's not the domain of cc65 to provide tools already available elsewhere. --- util/cbm/cbmcvt.c | 55 ----------------------------------------------- 1 file changed, 55 deletions(-) delete mode 100644 util/cbm/cbmcvt.c diff --git a/util/cbm/cbmcvt.c b/util/cbm/cbmcvt.c deleted file mode 100644 index 11c0325e4..000000000 --- a/util/cbm/cbmcvt.c +++ /dev/null @@ -1,55 +0,0 @@ -/* cbmcvt.c -- PetSCII <--> ISO-8859-1 Conversion Filter Tool */ -/* 2010-09-06, Greg King */ - -#include <stdio.h> -#include <unistd.h> - -/* Translation table ISO-8859-1 -> PetSCII */ -static const unsigned char CTPET[256] = { - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x14,0x09,0x0D,0x11,0x93,0x0A,0x0E,0x0F, - 0x10,0x0B,0x12,0x13,0x08,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, - 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, - 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F, - 0x40,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,0x5B,0xBF,0x5D,0x5E,0xA4, - 0xAD,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,0xB3,0xDD,0xAB,0xB1,0xDF, - 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, - 0x90,0x91,0x92,0x0C,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, - 0xA0,0xA1,0xA2,0xA3,0x5F,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0x7D,0xAC,0x60,0xAE,0xAF, - 0xB0,0x7E,0xB2,0x7B,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0x5C, - 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,0xDC,0x7C,0xDE,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 -}; - -static unsigned char CTISO[256]; - - -int main (int argc, char *argv[]) { - int C; - size_t I = 0u; - - if (isatty(fileno(stdin))) { - fputs("cbmcvt v2.1 -- Conversion Filter (stdin --> stdout)\n" - " -p converts ISO-8859-1 to PetSCII\n" - " else, converts in other direction.\n", stderr); - return 0; - } - if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'p') { - while ((C = fgetc (stdin)) != EOF) { - fputc (CTPET[C], stdout); - } - } else { - /* Create translation table PetSCII -> ISO-8859-1 */ - for (; I < sizeof CTPET; ++I) { - CTISO[CTPET[I]] = I; - } - - while ((C = fgetc (stdin)) != EOF) { - fputc (CTISO[C], stdout); - } - } - return 0; -} From fd0a6955da15c2dfd2beeab1f25fc2ed8aa319dc Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 19 Jul 2020 14:30:22 -0400 Subject: [PATCH 1440/2161] Changed "IsTypeStruct() || IsTypeUnion()" expressions into shorter "IsClassStruct()" expressions. Type-classes are groups of types that can be handled in the same way (similar syntax). --- src/cc65/expr.c | 4 ++-- src/cc65/function.c | 4 ++-- src/cc65/stmt.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index f28aa3965..ad3710e80 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -396,7 +396,7 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) } /* Handle struct/union specially */ - if (IsTypeStruct (Expr.Type) || IsTypeUnion (Expr.Type)) { + if (IsClassStruct (Expr.Type)) { /* Use the replacement type */ Flags |= TypeOf (GetStructReplacementType (Expr.Type)); } else { @@ -658,7 +658,7 @@ static void FunctionCall (ExprDesc* Expr) ReturnType = GetFuncReturn (Expr->Type); /* Handle struct/union specially */ - if (IsTypeStruct (ReturnType) || IsTypeUnion (ReturnType)) { + if (IsClassStruct (ReturnType)) { /* If there is no replacement type, then it is just the address */ if (ReturnType == GetStructReplacementType (ReturnType)) { /* Dereference it */ diff --git a/src/cc65/function.c b/src/cc65/function.c index 4cd5565c4..ff4c23656 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -477,7 +477,7 @@ void NewFunc (SymEntry* Func) Flags = CF_PTR; } else { /* Handle struct/union specially */ - if (IsTypeStruct (D->LastParam->Type) || IsTypeUnion (D->LastParam->Type)) { + if (IsClassStruct (D->LastParam->Type)) { Flags = TypeOf (GetStructReplacementType (D->LastParam->Type)) | CF_FORCECHAR; } else { Flags = TypeOf (D->LastParam->Type) | CF_FORCECHAR; @@ -506,7 +506,7 @@ void NewFunc (SymEntry* Func) /* Check if we need copy for struct/union type */ RType = Param->Type; - if (IsTypeStruct (RType) || IsTypeUnion (RType)) { + if (IsClassStruct (RType)) { RType = GetStructReplacementType (RType); /* If there is no replacement type, then it is just the address. diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 6c839c420..b02ae1cd6 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -329,7 +329,7 @@ static void ReturnStatement (void) TypeConversion (&Expr, F_GetReturnType (CurrentFunc)); /* Load the value into the primary */ - if (IsTypeStruct (Expr.Type) || IsTypeUnion (Expr.Type)) { + if (IsClassStruct (Expr.Type)) { /* Handle struct/union specially */ ReturnType = GetStructReplacementType (Expr.Type); if (ReturnType == Expr.Type) { From 3c52ad1d9ef15170589f4d348072fa6bd3a9caa9 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 19 Jul 2020 21:23:08 +0800 Subject: [PATCH 1441/2161] New utility ED_DisBitField() to make an expression no longer a bit-field. --- src/cc65/exprdesc.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a61c5d814..1541c2e4e 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -278,6 +278,16 @@ INLINE int ED_IsBitField (const ExprDesc* Expr) # define ED_IsBitField(Expr) (((Expr)->Flags & E_BITFIELD) != 0) #endif +#if defined(HAVE_INLINE) +INLINE void ED_DisBitField (ExprDesc* Expr) +/* Make the expression no longer a bit field */ +{ + Expr->Flags &= ~E_BITFIELD; +} +#else +# define ED_DisBitField(Expr) ((Expr)->Flags &= ~E_BITFIELD) +#endif + void ED_MakeBitField (ExprDesc* Expr, unsigned BitOffs, unsigned BitWidth); /* Make this expression a bit field expression */ From 62a6e3748737ab864759744b0a15d536c98a8fb2 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 19 Jul 2020 21:23:08 +0800 Subject: [PATCH 1442/2161] Made the code handling '&expression' slightly tidier. --- src/cc65/expr.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index ad3710e80..b05083323 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1867,23 +1867,23 @@ void hie10 (ExprDesc* Expr) NextToken (); ExprWithCheck (hie10, Expr); /* The & operator may be applied to any lvalue, and it may be - ** applied to functions, even if they're no lvalues. + ** applied to functions and arrays, even if they're not lvalues. */ - if (ED_IsRVal (Expr) && !IsTypeFunc (Expr->Type) && !IsTypeArray (Expr->Type)) { - Error ("Illegal address"); - } else { + if (!IsTypeFunc (Expr->Type) && !IsTypeArray (Expr->Type)) { + if (ED_IsRVal (Expr)) { + Error ("Illegal address"); + break; + } + if (ED_IsBitField (Expr)) { Error ("Cannot take address of bit-field"); /* Do it anyway, just to avoid further warnings */ - Expr->Flags &= ~E_BITFIELD; + ED_DisBitField (Expr); } - /* It's allowed in C to take the address of an array this way */ - if (!IsTypeFunc (Expr->Type) && !IsTypeArray (Expr->Type)) { - /* The & operator yields an rvalue address */ - ED_AddrExpr (Expr); - } - Expr->Type = PointerTo (Expr->Type); + /* The & operator yields an rvalue address */ + ED_AddrExpr (Expr); } + Expr->Type = PointerTo (Expr->Type); break; case TOK_SIZEOF: From b67b8ddd38c5f974ef686c29fdf2798ac7f77faf Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 19 Jul 2020 21:23:20 +0800 Subject: [PATCH 1443/2161] Disabled applying 'sizeof' to bit-fields. --- src/cc65/expr.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index b05083323..0b668f402 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1898,14 +1898,19 @@ void hie10 (ExprDesc* Expr) CodeMark Mark; GetCodePos (&Mark); hie10 (Expr); - /* If the expression is a literal string, release it, so it - ** won't be output as data if not used elsewhere. - */ - if (ED_IsLocLiteral (Expr)) { - ReleaseLiteral (Expr->LVal); + if (ED_IsBitField (Expr)) { + Error ("Cannot apply 'sizeof' to bit-field"); + Size = 0; + } else { + /* If the expression is a literal string, release it, so it + ** won't be output as data if not used elsewhere. + */ + if (ED_IsLocLiteral (Expr)) { + ReleaseLiteral (Expr->LVal); + } + /* Calculate the size */ + Size = CheckedSizeOf (Expr->Type); } - /* Calculate the size */ - Size = CheckedSizeOf (Expr->Type); /* Remove any generated code */ RemoveCode (&Mark); } From 22457833459ed453579a318aef9d5b3f68224fe4 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 19 Jul 2020 21:26:55 +0800 Subject: [PATCH 1444/2161] Fixed ability to do actual type conversion from bit-fields to integers. Note this doesn't try to fix the signedness issues. --- src/cc65/typeconv.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index e8d581f54..3bc7d47cb 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -59,8 +59,8 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { Type* OldType; - unsigned OldSize; - unsigned NewSize; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -83,8 +83,12 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Get the sizes of the types. Since we've excluded void types, checking ** for known sizes makes sense here. */ - OldSize = CheckedSizeOf (OldType); - NewSize = CheckedSizeOf (NewType); + if (ED_IsBitField (Expr)) { + OldBits = Expr->BitWidth; + } else { + OldBits = CheckedSizeOf (OldType) * CHAR_BITS; + } + NewBits = CheckedSizeOf (NewType) * CHAR_BITS; /* lvalue? */ if (ED_IsLVal (Expr)) { @@ -97,7 +101,7 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) ** If both sizes are equal, do also leave the value alone. ** If the new size is larger, we must convert the value. */ - if (NewSize > OldSize) { + if (NewBits > OldBits) { /* Load the value into the primary */ LoadExpr (CF_NONE, Expr); @@ -114,10 +118,6 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) ** to handle sign extension correctly. */ - /* Get the current and new size of the value */ - unsigned OldBits = OldSize * 8; - unsigned NewBits = NewSize * 8; - /* Check if the new datatype will have a smaller range. If it ** has a larger range, things are OK, since the value is ** internally already represented by a long. @@ -151,7 +151,7 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) ** not equal, add conversion code. Be sure to convert chars ** correctly. */ - if (OldSize != NewSize) { + if (OldBits != NewBits) { /* Load the value into the primary */ LoadExpr (CF_NONE, Expr); @@ -167,6 +167,11 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) ExitPoint: /* The expression has always the new type */ ReplaceType (Expr, NewType); + + /* Bit-fields are converted to integers */ + if (ED_IsBitField (Expr)) { + ED_DisBitField (Expr); + } } From 71c2d27705fafeacfcf04fac554925328cd01fbb Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 20 Jul 2020 07:36:14 +0800 Subject: [PATCH 1445/2161] Removed an ED_IsBitField() test according to PR review. --- src/cc65/typeconv.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 3bc7d47cb..e915d7392 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -169,9 +169,7 @@ ExitPoint: ReplaceType (Expr, NewType); /* Bit-fields are converted to integers */ - if (ED_IsBitField (Expr)) { - ED_DisBitField (Expr); - } + ED_DisBitField (Expr); } From 78342fa82c3d7e6c9b586cfacbf229d1642860ed Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 20 Jul 2020 20:40:41 +0800 Subject: [PATCH 1446/2161] Fix for "auto" variables made "static" with the "-Cl" options. --- src/cc65/locals.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 9f8ee86ef..0007879d8 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -340,7 +340,7 @@ static void ParseAutoDecl (Declaration* Decl) LoadExpr (CF_NONE, &Expr); /* Store the value into the variable */ - g_putstatic (TypeOf (Sym->Type), DataLabel, 0); + g_putstatic (CF_STATIC | TypeOf (Sym->Type), DataLabel, 0); } /* Mark the variable as referenced */ From 5a9d76ad5211c944d5ef004c5742139f8cdc8dcd Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 20 Jul 2020 15:50:11 +0200 Subject: [PATCH 1447/2161] added test for issue #1108 --- test/val/bug1108.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 test/val/bug1108.c diff --git a/test/val/bug1108.c b/test/val/bug1108.c new file mode 100644 index 000000000..17ef022c3 --- /dev/null +++ b/test/val/bug1108.c @@ -0,0 +1,40 @@ + +/* bug #1108 - Problem with static locals? */ + +#include <stdio.h> + +#pragma static-locals (on) + +unsigned char x = 0; + +unsigned char PrintVar1(void) +{ + unsigned char cx = x + 1; + printf("cx:%d x:%d\n", cx, x); + return cx == 0; +} + +unsigned char PrintVar2(void) +{ + unsigned char cx = x + 1; + unsigned char cy; + cy = x + 1; + printf("cx:%d cy:%d x:%d\n", cx, cy, x); + return cx != cy; +} + +#pragma static-locals (off) + +unsigned char n; +unsigned char ret = 0; + +int main(void) +{ + for (n = 0; n < 10; n++) { + ++x; + ret |= PrintVar1(); + ret |= PrintVar2(); + } + return ret; +} + From 517df130ccdba93d99d27ab7fb42676cc84ce18e Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 20 Jul 2020 17:16:11 -0400 Subject: [PATCH 1448/2161] Made a regression test increment a variable after, instead of before, using it. That change allows the initial value of zero to be tested. --- test/val/bug1108.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/test/val/bug1108.c b/test/val/bug1108.c index 17ef022c3..1cd23c8e5 100644 --- a/test/val/bug1108.c +++ b/test/val/bug1108.c @@ -7,34 +7,31 @@ unsigned char x = 0; -unsigned char PrintVar1(void) +static unsigned char PrintVar1(void) { unsigned char cx = x + 1; + printf("cx:%d x:%d\n", cx, x); return cx == 0; } -unsigned char PrintVar2(void) +static unsigned char PrintVar2(void) { unsigned char cx = x + 1; unsigned char cy; + cy = x + 1; printf("cx:%d cy:%d x:%d\n", cx, cy, x); return cx != cy; } -#pragma static-locals (off) - -unsigned char n; -unsigned char ret = 0; +static unsigned char ret = 0; int main(void) { - for (n = 0; n < 10; n++) { - ++x; + do { ret |= PrintVar1(); ret |= PrintVar2(); - } + } while (++x < 10); return ret; } - From b60b303c5d24f718b0c14022b47ca1a838112ceb Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 20 Jul 2020 21:40:44 -0400 Subject: [PATCH 1449/2161] Added a missing asterisk to a "hardware" struct definition. --- include/cx16.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cx16.h b/include/cx16.h index f129b26f4..87a6d37ca 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -290,7 +290,7 @@ struct __emul { unsigned char keymap; /* Keyboard layout number */ const char detect[2]; /* "16" if running on x16emu */ }; -#define EMULATOR (*(volatile struct __emul)0x9FB0) +#define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ #define BANK_RAM ((unsigned char[0x2000])0xA000) From 638e2546684f466495a253b37325ace82cb79ced Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 21 Jul 2020 14:48:49 +0200 Subject: [PATCH 1450/2161] rework pptest2 into a runable test and move to test/misc (since it does not compile with cc65) --- test/misc/Makefile | 5 +++ test/misc/pptest2.c | 73 +++++++++++++++++++++++++++++++++++++ testcode/compiler/pptest2.c | 19 ---------- 3 files changed, 78 insertions(+), 19 deletions(-) create mode 100644 test/misc/pptest2.c delete mode 100644 testcode/compiler/pptest2.c diff --git a/test/misc/Makefile b/test/misc/Makefile index 898ea1b2b..96f61dba1 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -78,6 +78,11 @@ $(WORKDIR)/bug760.$1.$2.prg: bug760.c | $(WORKDIR) $(if $(QUIET),echo misc/bug760.$1.$2.prg) -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) +# should compile, but gives an error +$(WORKDIR)/pptest2.$1.$2.prg: pptest2.c | $(WORKDIR) + $(if $(QUIET),echo misc/pptest2.$1.$2.prg) + -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + # this should fail to compile, because cc65 does not support returning structs $(WORKDIR)/bug264.$1.$2.prg: bug264.c | $(WORKDIR) $(if $(QUIET),echo misc/bug264.$1.$2.prg) diff --git a/test/misc/pptest2.c b/test/misc/pptest2.c new file mode 100644 index 000000000..7857c67b2 --- /dev/null +++ b/test/misc/pptest2.c @@ -0,0 +1,73 @@ + +/* preprocessor test #2 */ + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +int y = 7; +int z[] = {1, 2, 3}; +int res; + +int f(int i) { + printf("f: %d\n", i); + return i + 1; +} +int t(int i) { + printf("t: %d\n", i); + return i + 1; +} +int m(int i, int j) { + printf("m: %d %d\n", i, j); + return i + j + 1; +} + +#define x 3 +#define f(a) f(x * (a)) +#undef x +#define x 2 +#define g f +#define z z[0] +#define h g(~ +#define m(a) a(w) +#define w 0,1 +#define t(a) a +#define p() int +#define q(x) x +#define r(x,y) x ## y +#define str(x) # x + +int main(void) +{ + res = f(y+1) + f(f(z)) % t(t(g) (0) + t)(1); + printf("res: %d expected: 19\n", res); + if (res != 19) { + return EXIT_FAILURE; + } + + res = g(x+(3,4)-w) | h 5) & m(f)^m(m); + printf("res: %d expected: 3\n", res); + if (res != 3) { + return EXIT_FAILURE; + } + + p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) }; + printf("i[]: %d %d %d %d\n", i[0], i[1], i[2], i[3]); + printf("expected: %d %d %d %d\n", 1, 23, 4, 5); + if ((i[0] != 1) || (i[1] != 23) || (i[2] != 4) || (i[3] != 5)) { + return EXIT_FAILURE; + } + + char c[2][6] = { str(hello), str() }; + printf ("c[0]: %s expected: %s\n", c[0], "hello"); + printf ("c[1]: %s expected: %s\n", c[1], ""); + if (strcmp(c[0], "hello") != 0) { + return EXIT_FAILURE; + } + if (strcmp(c[1], "") != 0) { + return EXIT_FAILURE; + } + + printf("all fine\n"); + return EXIT_SUCCESS; +} diff --git a/testcode/compiler/pptest2.c b/testcode/compiler/pptest2.c deleted file mode 100644 index e127d53fb..000000000 --- a/testcode/compiler/pptest2.c +++ /dev/null @@ -1,19 +0,0 @@ -#define x 3 -#define f(a) f(x * (a)) -#undef x -#define x 2 -#define g f -#define z z[0] -#define h g(~ -#define m(a) a(w) -#define w 0,1 -#define t(a) a -#define p() int -#define q(x) x -#define r(x,y) x ## y -#define str(x) # x - -f(y+1) + f(f(z)) % t(t(g) (0) + t)(1); -g(x+(3,4)-w) | h 5) & m(f)^m(m); -p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) }; -char c[2][6] = { str(hello), str() }; From 010ed6d7290c9939495f8feb0d6ad3fba9510a05 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 21 Jul 2020 14:58:15 +0200 Subject: [PATCH 1451/2161] reworked pptest1/4/5 into executable tests and moved to test/val --- test/val/pptest1.c | 27 +++++++++++++++++++++++++++ test/val/pptest4.c | 24 ++++++++++++++++++++++++ test/val/pptest5.c | 24 ++++++++++++++++++++++++ testcode/compiler/pptest1.c | 6 ------ testcode/compiler/pptest4.c | 3 --- testcode/compiler/pptest5.c | 3 --- 6 files changed, 75 insertions(+), 12 deletions(-) create mode 100644 test/val/pptest1.c create mode 100644 test/val/pptest4.c create mode 100644 test/val/pptest5.c delete mode 100644 testcode/compiler/pptest1.c delete mode 100644 testcode/compiler/pptest4.c delete mode 100644 testcode/compiler/pptest5.c diff --git a/test/val/pptest1.c b/test/val/pptest1.c new file mode 100644 index 000000000..52b381b0b --- /dev/null +++ b/test/val/pptest1.c @@ -0,0 +1,27 @@ + +/* preprocessor test #1 */ + +#define hash_hash # ## # +#define mkstr(a) # a +#define in_between(a) mkstr(a) +#define join(c, d) in_between(c hash_hash d) + +#define x "first" +#define y "second" + +char p[] = join(x, y); // Comment + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +int main(void) +{ + printf("expected: %s\n", "\"first\" ## \"second\""); + printf("p: %s\n", p); + if (!strcmp(p, "\"first\" ## \"second\"")) { + return EXIT_SUCCESS; + } + printf("all fine\n"); + return EXIT_FAILURE; +} diff --git a/test/val/pptest4.c b/test/val/pptest4.c new file mode 100644 index 000000000..827be7200 --- /dev/null +++ b/test/val/pptest4.c @@ -0,0 +1,24 @@ + +/* preprocessor test #4 */ + +#define t(x,y,z) x ## y ## z +int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), + t(10,,), t(,11,), t(,,12), t(,,) }; + +int e[] = { 123, 45, 67, 89, 10, 11, 12, }; + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +unsigned char i; + +int main(void) +{ + for (i = 0; i < 7; ++i) { + printf("j: %d expect: %d\n", j[i], e[i]); + if (j[i] != e[i]) return EXIT_FAILURE; + } + printf("all fine\n"); + return EXIT_SUCCESS; +} diff --git a/test/val/pptest5.c b/test/val/pptest5.c new file mode 100644 index 000000000..82f642c8e --- /dev/null +++ b/test/val/pptest5.c @@ -0,0 +1,24 @@ + +/* preprocessor test #5 */ + +#define t(x,y,z) x ## y ## z +int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), + t(10,,), t(,11,), t(,,12), t(,,) }; + +int e[] = { 123, 45, 67, 89, 10, 11, 12, }; + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +unsigned char i; + +int main(void) +{ + for (i = 0; i < 7; ++i) { + printf("j: %d expect: %d\n", j[i], e[i]); + if (j[i] != e[i]) return EXIT_FAILURE; + } + printf("all fine\n"); + return EXIT_SUCCESS; +} diff --git a/testcode/compiler/pptest1.c b/testcode/compiler/pptest1.c deleted file mode 100644 index e42135688..000000000 --- a/testcode/compiler/pptest1.c +++ /dev/null @@ -1,6 +0,0 @@ -#define hash_hash # ## # -#define mkstr(a) # a -#define in_between(a) mkstr(a) -#define join(c, d) in_between(c hash_hash d) - -char p[] = join(x, y); // Comment diff --git a/testcode/compiler/pptest4.c b/testcode/compiler/pptest4.c deleted file mode 100644 index b8540b5c5..000000000 --- a/testcode/compiler/pptest4.c +++ /dev/null @@ -1,3 +0,0 @@ -#define t(x,y,z) x ## y ## z -int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), - t(10,,), t(,11,), t(,,12), t(,,) }; diff --git a/testcode/compiler/pptest5.c b/testcode/compiler/pptest5.c deleted file mode 100644 index 1f0bd4328..000000000 --- a/testcode/compiler/pptest5.c +++ /dev/null @@ -1,3 +0,0 @@ -#define t(x,y,z) x ## y ## z -int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), - t(10,,), t(,11,), t(,,12), t(,,) }; From e4fc7a0feca596d18098c08598a97f388617e89f Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 21 Jul 2020 15:30:35 +0200 Subject: [PATCH 1452/2161] reworked pptest3 into an exectutable test and moved to test/val --- test/val/pptest3.c | 44 +++++++++++++++++++++++++++++++++++++ testcode/compiler/pptest3.c | 16 -------------- 2 files changed, 44 insertions(+), 16 deletions(-) create mode 100644 test/val/pptest3.c delete mode 100644 testcode/compiler/pptest3.c diff --git a/test/val/pptest3.c b/test/val/pptest3.c new file mode 100644 index 000000000..b48677703 --- /dev/null +++ b/test/val/pptest3.c @@ -0,0 +1,44 @@ + +/* preprocessor test #3 */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +char *x1 = "123"; +char *x2 = "456"; +FILE *s; +char *str = "789"; + +#define str(s) # s +#define xstr(s) str(s) +#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \ + x ## s, x ## t) +#define INCFILE(n) vers ## n // Comment +#define glue(a,b) a ## b +#define xglue(a,b) glue(a,b) +#define HIGHLOW "hello" +#define LOW LOW ", world" + +int main(void) { + s = stdout; + + debug (1, 2); + + fputs (str (strncmp("abc\0d", "abc", '\4') // Comment + == 0) str (: @\n), s); + + str = glue (HIGH, LOW); + printf("str: %s\n", str); + if (strcmp(str, "hello") != 0) { + return EXIT_FAILURE; + } + + str = xglue (HIGH, LOW); + printf("str: %s\n", str); + if (strcmp(str, "hello, world") != 0) { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/testcode/compiler/pptest3.c b/testcode/compiler/pptest3.c deleted file mode 100644 index 62aa7f705..000000000 --- a/testcode/compiler/pptest3.c +++ /dev/null @@ -1,16 +0,0 @@ -#define str(s) # s -#define xstr(s) str(s) -#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \ - x ## s, x ## t) -#define INCFILE(n) vers ## n // Comment -#define glue(a,b) a ## b -#define xglue(a,b) glue(a,b) -#define HIGHLOW "hello" -#define LOW LOW ", world" - -debug (1, 2); -fputs (str (strncmp("abc\0d", "abc", '\4') // Comment - == 0) str (: @\n), s); -glue (HIGH, LOW); -xglue (HIGH, LOW); - From 0250c87ac6326d0a9114457d9d9af5b259044baa Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 20 Jul 2020 22:34:57 +0800 Subject: [PATCH 1453/2161] Fixed SC_* type masks by making them all bitwise-exclusive. --- src/cc65/compile.c | 2 +- src/cc65/declare.c | 2 +- src/cc65/expr.c | 2 +- src/cc65/symentry.h | 49 ++++++++++++++++++++++++--------------------- src/cc65/symtab.c | 6 +++--- 5 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index ef66d38d2..4806017eb 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -112,7 +112,7 @@ static void Parse (void) ParseDeclSpec (&Spec, SC_EXTERN | SC_STATIC, T_INT); /* Don't accept illegal storage classes */ - if ((Spec.StorageClass & SC_TYPE) == 0) { + if ((Spec.StorageClass & SC_TYPEMASK) == 0) { if ((Spec.StorageClass & SC_AUTO) != 0 || (Spec.StorageClass & SC_REGISTER) != 0) { Error ("Illegal storage class"); diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 2a21e5a76..3b1cf63e7 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -490,7 +490,7 @@ static void ParseEnumDecl (void) } /* Add an entry to the symbol table */ - AddConstSym (Ident, type_int, SC_ENUM, EnumVal++); + AddConstSym (Ident, type_int, SC_ENUM|SC_CONST, EnumVal++); /* Check for end of definition */ if (CurTok.Tok != TOK_COMMA) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 0b668f402..d31b153a5 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -758,7 +758,7 @@ static void Primary (ExprDesc* E) /* Check for illegal symbol types */ CHECK ((Sym->Flags & SC_LABEL) != SC_LABEL); - if (Sym->Flags & SC_TYPE) { + if (Sym->Flags & SC_ESUTYPEMASK) { /* Cannot use type symbols */ Error ("Variable identifier expected"); /* Assume an int type to make E valid */ diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 62bf0b0e7..27c6ccc1e 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -69,39 +69,42 @@ struct CodeEntry; /* Storage classes and flags */ -#define SC_AUTO 0x0001U /* Auto variable */ -#define SC_REGISTER 0x0002U /* Register variable */ -#define SC_STATIC 0x0004U /* Static */ -#define SC_EXTERN 0x0008U /* Extern linkage */ +#define SC_NONE 0x0000U /* Nothing */ +#define SC_STRUCT 0x0001U /* Struct */ +#define SC_UNION 0x0002U /* Union */ +#define SC_TYPEDEF 0x0004U /* A typedef */ +#define SC_ESUTYPEMASK 0x0007U /* Mask for above types */ +#define SC_ENUM 0x0008U /* An enum */ +#define SC_BITFIELD 0x0010U /* A bit-field inside a struct or union */ +#define SC_TYPEMASK 0x001FU /* Mask for above types */ -#define SC_ENUM 0x0030U /* An enum */ #define SC_CONST 0x0020U /* A numeric constant with a type */ -#define SC_LABEL 0x0040U /* A goto label */ +#define SC_LABEL 0x0040U /* A goto code label */ #define SC_PARAM 0x0080U /* A function parameter */ #define SC_FUNC 0x0100U /* A function */ - #define SC_DEFTYPE 0x0200U /* Parameter has default type (=int, old style) */ -#define SC_STORAGE 0x0400U /* Symbol with associated storage */ -#define SC_DEFAULT 0x0800U /* Flag: default storage class was used */ +#define SC_STRUCTFIELD 0x0400U /* Struct or union field */ + +#define SC_DECL 0x0800U /* Symbol is declared in global scope */ #define SC_DEF 0x1000U /* Symbol is defined */ #define SC_REF 0x2000U /* Symbol is referenced */ -#define SC_TYPE 0x4000U /* This is a type, struct, typedef, etc. */ -#define SC_STRUCT 0x4001U /* Struct */ -#define SC_UNION 0x4002U /* Union */ -#define SC_STRUCTFIELD 0x4003U /* Struct or union field */ -#define SC_BITFIELD 0x4004U /* A bit-field inside a struct or union */ -#define SC_TYPEDEF 0x4005U /* A typedef */ -#define SC_TYPEMASK 0x400FU /* Mask for above types */ +#define SC_ZEROPAGE 0x4000U /* Symbol marked as zeropage */ -#define SC_ZEROPAGE 0x8000U /* Symbol marked as zeropage */ +#define SC_STORAGE 0x8000U /* Symbol with associated storage */ -#define SC_HAVEATTR 0x10000U /* Symbol has attributes */ +#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 */ -#define SC_GOTO 0x20000U -#define SC_SPADJUSTMENT 0x40000U -#define SC_GOTO_IND 0x80000U /* Indirect goto */ +#define SC_HAVEATTR 0x100000U /* Symbol has attributes */ + +#define SC_GOTO 0x200000U +#define SC_SPADJUSTMENT 0x400000U +#define SC_GOTO_IND 0x800000U /* Indirect goto */ @@ -245,10 +248,10 @@ 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_TYPE)) == SC_REGISTER); + return ((Sym->Flags & (SC_REGISTER|SC_TYPEMASK)) == SC_REGISTER); } #else -# define SymIsRegVar(Sym) (((Sym)->Flags & (SC_REGISTER|SC_TYPE)) == SC_REGISTER) +# define SymIsRegVar(Sym) (((Sym)->Flags & (SC_REGISTER|SC_ESUTYPEMASK)) == SC_REGISTER) #endif int SymIsOutputFunc (const SymEntry* Sym); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index f363d9134..1408f9f4c 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -821,7 +821,7 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs /* Set the symbol attributes */ Entry->Type = TypeDup (T); - if ((Flags & SC_AUTO) == SC_AUTO) { + if ((Flags & SC_AUTO) == SC_AUTO || (Flags & SC_TYPEDEF) == SC_TYPEDEF) { Entry->V.Offs = Offs; } else if ((Flags & SC_REGISTER) == SC_REGISTER) { Entry->V.R.RegOffs = Offs; @@ -872,7 +872,7 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) } /* We have a symbol with this name already */ - if (Entry->Flags & SC_TYPE) { + if (Entry->Flags & SC_TYPEMASK) { Error ("Multiple definition for '%s'", Name); return Entry; } @@ -1109,7 +1109,7 @@ void EmitDebugInfo (void) } Sym = SymTab->SymHead; while (Sym) { - if ((Sym->Flags & (SC_CONST|SC_TYPE)) == 0) { + if ((Sym->Flags & (SC_CONST|SC_TYPEMASK)) == 0) { if (Sym->Flags & SC_AUTO) { AddTextLine ("%s, \"%s\", \"00\", auto, %d", Head, Sym->Name, Sym->V.Offs); From 65081aebed14588cf048bc5fe6fcff474c6e38e8 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 20 Jul 2020 22:34:57 +0800 Subject: [PATCH 1454/2161] Made able to recognize global declarations of static arrays. Fixed Issue #975. --- src/cc65/compile.c | 25 ++++++++++++++++--------- src/cc65/expr.c | 2 +- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 4806017eb..f7e4bd35d 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -151,14 +151,17 @@ static void Parse (void) ** This means that "extern int i;" will not get storage allocated. */ if ((Decl.StorageClass & SC_FUNC) != SC_FUNC && - (Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF && - ((Spec.Flags & DS_DEF_STORAGE) != 0 || - (Decl.StorageClass & (SC_EXTERN|SC_STATIC)) == SC_STATIC || - ((Decl.StorageClass & SC_EXTERN) != 0 && - CurTok.Tok == TOK_ASSIGN))) { - - /* We will allocate storage */ - Decl.StorageClass |= SC_STORAGE; + (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 && + CurTok.Tok == TOK_ASSIGN)) { + /* We will allocate storage */ + Decl.StorageClass |= SC_STORAGE; + } else { + /* It's a declaration */ + Decl.StorageClass |= SC_DECL; + } } /* If this is a function declarator that is not followed by a comma @@ -243,7 +246,11 @@ static void Parse (void) if (!IsTypeArray (Decl.Type)) { Error ("Variable '%s' has unknown size", Decl.Ident); } - Entry->Flags &= ~(SC_STORAGE | SC_DEF); + /* Do this only if the same array has not been defined */ + if (!SymIsDef (Entry)) { + Entry->Flags &= ~(SC_STORAGE | SC_DEF); + Entry->Flags |= SC_DECL; + } } else { /* A global (including static) uninitialized variable is ** only a tentative definition. For example, this is valid: diff --git a/src/cc65/expr.c b/src/cc65/expr.c index d31b153a5..a35ad59a9 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -802,7 +802,7 @@ static void Primary (ExprDesc* E) E->Name = Sym->V.R.RegOffs; } else if ((Sym->Flags & SC_STATIC) == SC_STATIC) { /* Static variable */ - if (Sym->Flags & (SC_EXTERN | SC_STORAGE)) { + if (Sym->Flags & (SC_EXTERN | SC_STORAGE | SC_DECL)) { E->Flags = E_LOC_GLOBAL | E_RTYPE_LVAL; E->Name = (uintptr_t) Sym->Name; } else { From 18bd76bb9043c7549bbd2db35c6218f9f228f3f2 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 21 Jul 2020 13:09:41 +0800 Subject: [PATCH 1455/2161] Minor fixes and improvements. --- src/cc65/pragma.c | 2 +- src/cc65/symentry.c | 24 +++++++++++++++++++----- src/cc65/symentry.h | 20 +++++++++----------- src/cc65/symtab.c | 2 +- 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index b05ef6122..93c83906f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -523,7 +523,7 @@ static void WrappedCallPragma (StrBuf* B) Entry = FindSym(Name); /* Check if the name is valid */ - if (Entry && Entry->Flags & SC_FUNC) { + if (Entry && (Entry->Flags & SC_FUNC) == SC_FUNC) { PushWrappedCall(Entry, (unsigned char) Val); Entry->Flags |= SC_REF; diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index 18cc026ea..fbcc84c98 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -104,16 +104,21 @@ void FreeSymEntry (SymEntry* E) void DumpSymEntry (FILE* F, const SymEntry* E) /* Dump the given symbol table entry to the file in readable form */ { - static const struct { + typedef const struct { const char* Name; unsigned Val; - } Flags [] = { - /* Beware: Order is important! */ + } SCFlagTable; + + static SCFlagTable ESUTypes[] = { { "SC_TYPEDEF", SC_TYPEDEF }, - { "SC_BITFIELD", SC_BITFIELD }, - { "SC_STRUCTFIELD", SC_STRUCTFIELD }, { "SC_UNION", SC_UNION }, { "SC_STRUCT", SC_STRUCT }, + }; + + static SCFlagTable Flags[] = { + /* Beware: Order is important! */ + { "SC_BITFIELD", SC_BITFIELD }, + { "SC_STRUCTFIELD", SC_STRUCTFIELD }, { "SC_AUTO", SC_AUTO }, { "SC_REGISTER", SC_REGISTER }, { "SC_STATIC", SC_STATIC }, @@ -124,6 +129,7 @@ void DumpSymEntry (FILE* F, const SymEntry* E) { "SC_PARAM", SC_PARAM }, { "SC_FUNC", SC_FUNC }, { "SC_STORAGE", SC_STORAGE }, + { "SC_DECL", SC_DECL }, { "SC_DEF", SC_DEF }, { "SC_REF", SC_REF }, { "SC_ZEROPAGE", SC_ZEROPAGE }, @@ -143,6 +149,14 @@ void DumpSymEntry (FILE* F, const SymEntry* E) /* Print the flags */ SymFlags = E->Flags; fprintf (F, " Flags:"); + 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); + } + } + } for (I = 0; I < sizeof (Flags) / sizeof (Flags[0]) && SymFlags != 0; ++I) { if ((SymFlags & Flags[I].Val) == Flags[I].Val) { SymFlags &= ~Flags[I].Val; diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 27c6ccc1e..820ed5025 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -74,24 +74,22 @@ struct CodeEntry; #define SC_UNION 0x0002U /* Union */ #define SC_TYPEDEF 0x0004U /* A typedef */ #define SC_ESUTYPEMASK 0x0007U /* Mask for above types */ -#define SC_ENUM 0x0008U /* An enum */ +#define SC_ENUM 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_CONST 0x0020U /* A numeric constant with a type */ +#define SC_FUNC 0x0020U /* A function */ #define SC_LABEL 0x0040U /* A goto code label */ -#define SC_PARAM 0x0080U /* A function parameter */ -#define SC_FUNC 0x0100U /* A function */ +#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 */ -#define SC_DECL 0x0800U /* Symbol is declared in global scope */ +#define SC_ZEROPAGE 0x0800U /* Symbol marked as zeropage */ #define SC_DEF 0x1000U /* Symbol is defined */ #define SC_REF 0x2000U /* Symbol is referenced */ - -#define SC_ZEROPAGE 0x4000U /* Symbol marked as zeropage */ - +#define SC_DECL 0x4000U /* Symbol is declared in global scope */ #define SC_STORAGE 0x8000U /* Symbol with associated storage */ #define SC_AUTO 0x010000U /* Auto variable */ @@ -217,10 +215,10 @@ INLINE int SymIsBitField (const SymEntry* Sym) INLINE int SymIsTypeDef (const SymEntry* Sym) /* Return true if the given entry is a typedef entry */ { - return ((Sym->Flags & SC_TYPEDEF) == SC_TYPEDEF); + return ((Sym->Flags & SC_TYPEMASK) == SC_TYPEDEF); } #else -# define SymIsTypeDef(Sym) (((Sym)->Flags & SC_TYPEDEF) == SC_TYPEDEF) +# define SymIsTypeDef(Sym) (((Sym)->Flags & SC_TYPEMASK) == SC_TYPEDEF) #endif #if defined(HAVE_INLINE) @@ -251,7 +249,7 @@ INLINE int SymIsRegVar (const SymEntry* Sym) return ((Sym->Flags & (SC_REGISTER|SC_TYPEMASK)) == SC_REGISTER); } #else -# define SymIsRegVar(Sym) (((Sym)->Flags & (SC_REGISTER|SC_ESUTYPEMASK)) == SC_REGISTER) +# define SymIsRegVar(Sym) (((Sym)->Flags & (SC_REGISTER|SC_TYPEMASK)) == SC_REGISTER) #endif int SymIsOutputFunc (const SymEntry* Sym); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 1408f9f4c..6395f9a4a 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -821,7 +821,7 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs /* Set the symbol attributes */ Entry->Type = TypeDup (T); - if ((Flags & SC_AUTO) == SC_AUTO || (Flags & SC_TYPEDEF) == SC_TYPEDEF) { + if ((Flags & SC_AUTO) == SC_AUTO || (Flags & SC_TYPEMASK) == SC_TYPEDEF) { Entry->V.Offs = Offs; } else if ((Flags & SC_REGISTER) == SC_REGISTER) { Entry->V.R.RegOffs = Offs; From c66d0881b9bc34f3d2213eedcedc236b56da1f03 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 21 Jul 2020 15:16:47 +0800 Subject: [PATCH 1456/2161] Made the enum/enumerator types clearer and improved DumpSymEntry() output. --- src/cc65/declare.c | 2 +- src/cc65/symentry.c | 37 +++++++++++++++++++++++++------------ src/cc65/symentry.h | 5 +++-- src/cc65/symtab.c | 6 +++--- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 3b1cf63e7..cd5142952 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -490,7 +490,7 @@ static void ParseEnumDecl (void) } /* Add an entry to the symbol table */ - AddConstSym (Ident, type_int, SC_ENUM|SC_CONST, EnumVal++); + AddConstSym (Ident, type_int, SC_ENUMERATOR|SC_CONST, EnumVal++); /* Check for end of definition */ if (CurTok.Tok != TOK_COMMA) diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index fbcc84c98..c8d4f9e2a 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -113,26 +113,29 @@ void DumpSymEntry (FILE* F, const SymEntry* E) { "SC_TYPEDEF", SC_TYPEDEF }, { "SC_UNION", SC_UNION }, { "SC_STRUCT", SC_STRUCT }, + { "SC_ENUM", SC_ENUM }, }; - static SCFlagTable Flags[] = { - /* Beware: Order is important! */ + static SCFlagTable Types[] = { { "SC_BITFIELD", SC_BITFIELD }, { "SC_STRUCTFIELD", SC_STRUCTFIELD }, - { "SC_AUTO", SC_AUTO }, - { "SC_REGISTER", SC_REGISTER }, - { "SC_STATIC", SC_STATIC }, - { "SC_EXTERN", SC_EXTERN }, - { "SC_ENUM", SC_ENUM }, + { "SC_ENUMERATOR", SC_ENUMERATOR }, { "SC_CONST", SC_CONST }, { "SC_LABEL", SC_LABEL }, { "SC_PARAM", SC_PARAM }, { "SC_FUNC", SC_FUNC }, + }; + + static SCFlagTable Storages[] = { + { "SC_AUTO", SC_AUTO }, + { "SC_REGISTER", SC_REGISTER }, + { "SC_STATIC", SC_STATIC }, + { "SC_EXTERN", SC_EXTERN }, { "SC_STORAGE", SC_STORAGE }, + { "SC_ZEROPAGE", SC_ZEROPAGE }, { "SC_DECL", SC_DECL }, { "SC_DEF", SC_DEF }, { "SC_REF", SC_REF }, - { "SC_ZEROPAGE", SC_ZEROPAGE }, }; unsigned I; @@ -149,18 +152,28 @@ 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); + break; } } } - for (I = 0; I < sizeof (Flags) / sizeof (Flags[0]) && SymFlags != 0; ++I) { - if ((SymFlags & Flags[I].Val) == Flags[I].Val) { - SymFlags &= ~Flags[I].Val; - fprintf (F, " %s", Flags[I].Name); + /* 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 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); } } if (SymFlags != 0) { diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 820ed5025..c112ff013 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -72,9 +72,10 @@ struct CodeEntry; #define SC_NONE 0x0000U /* Nothing */ #define SC_STRUCT 0x0001U /* Struct */ #define SC_UNION 0x0002U /* Union */ -#define SC_TYPEDEF 0x0004U /* A typedef */ +#define SC_ENUM 0x0003U /* Enum */ +#define SC_TYPEDEF 0x0004U /* Typedef */ #define SC_ESUTYPEMASK 0x0007U /* Mask for above types */ -#define SC_ENUM 0x0008U /* An enumerator */ +#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 */ diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6395f9a4a..fdbbff7dc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -633,7 +633,7 @@ SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val /* Add an constant symbol to the symbol table and return it */ { /* Enums must be inserted in the global symbol table */ - SymTable* Tab = ((Flags & SC_ENUM) == SC_ENUM)? SymTab0 : SymTab; + SymTable* Tab = ((Flags & SC_ENUMERATOR) == SC_ENUMERATOR) ? SymTab0 : SymTab; /* Do we have an entry with this name already? */ SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name)); @@ -867,8 +867,8 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) /* If the existing symbol is an enumerated constant, ** then avoid a compiler crash. See GitHub issue #728. */ - if (Entry->Flags & SC_ENUM) { - Fatal ("Can't redeclare enum constant '%s' as global variable", Name); + if (Entry->Flags & SC_ENUMERATOR) { + Fatal ("Can't redeclare enumerator constant '%s' as global variable", Name); } /* We have a symbol with this name already */ From 07e18774f76e09d8cc149366c6b420e002348de0 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 21 Jul 2020 22:41:31 +0800 Subject: [PATCH 1457/2161] Added spaces around '|' with regex replacement. --- src/cc65/declare.c | 2 +- src/cc65/symentry.h | 4 ++-- src/cc65/symtab.c | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index cd5142952..323e9af14 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -490,7 +490,7 @@ static void ParseEnumDecl (void) } /* Add an entry to the symbol table */ - AddConstSym (Ident, type_int, SC_ENUMERATOR|SC_CONST, EnumVal++); + AddConstSym (Ident, type_int, SC_ENUMERATOR | SC_CONST, EnumVal++); /* Check for end of definition */ if (CurTok.Tok != TOK_COMMA) diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index c112ff013..13829e958 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -247,10 +247,10 @@ 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_REGISTER | SC_TYPEMASK)) == SC_REGISTER); } #else -# define SymIsRegVar(Sym) (((Sym)->Flags & (SC_REGISTER|SC_TYPEMASK)) == SC_REGISTER) +# define SymIsRegVar(Sym) (((Sym)->Flags & (SC_REGISTER | SC_TYPEMASK)) == SC_REGISTER) #endif int SymIsOutputFunc (const SymEntry* Sym); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index fdbbff7dc..26a09cd87 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -717,7 +717,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) for (i = 0; i < CollCount (Entry->V.L.DefsOrRefs); i++) { DOR = CollAt (Entry->V.L.DefsOrRefs, i); - if ((DOR->Flags & SC_DEF) && (Flags & SC_REF) && (Flags & (SC_GOTO|SC_GOTO_IND))) { + if ((DOR->Flags & SC_DEF) && (Flags & SC_REF) && (Flags & (SC_GOTO | SC_GOTO_IND))) { /* We're processing a goto and here is its destination label. ** This means the difference between SP values is already known, ** so we simply emit the SP adjustment code. @@ -739,7 +739,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) } - if ((DOR->Flags & SC_REF) && (DOR->Flags & (SC_GOTO|SC_GOTO_IND)) && (Flags & SC_DEF)) { + if ((DOR->Flags & SC_REF) && (DOR->Flags & (SC_GOTO | SC_GOTO_IND)) && (Flags & SC_DEF)) { /* We're processing a label, let's update all gotos encountered ** so far */ @@ -1109,7 +1109,7 @@ void EmitDebugInfo (void) } Sym = SymTab->SymHead; while (Sym) { - if ((Sym->Flags & (SC_CONST|SC_TYPEMASK)) == 0) { + if ((Sym->Flags & (SC_CONST | SC_TYPEMASK)) == 0) { if (Sym->Flags & SC_AUTO) { AddTextLine ("%s, \"%s\", \"00\", auto, %d", Head, Sym->Name, Sym->V.Offs); From b2d799824197bb899459e34fbfdf085f20880cf1 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 21 Jul 2020 19:15:41 +0200 Subject: [PATCH 1458/2161] update makefile to use $(NOT) as discussed with Oliver --- test/misc/Makefile | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/test/misc/Makefile b/test/misc/Makefile index 96f61dba1..1405e05bf 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -66,37 +66,42 @@ define PRG_template # should compile, but gives an error $(WORKDIR)/bug975.$1.$2.prg: bug975.c | $(WORKDIR) $(if $(QUIET),echo misc/bug975.$1.$2.prg) - -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) # should compile, but gives an error $(WORKDIR)/bug250.$1.$2.prg: bug250.c | $(WORKDIR) + @echo "FIXME: " $$@ "currently does not compile." $(if $(QUIET),echo misc/bug250.$1.$2.prg) - -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(NOT) $(CL65) -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) - -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) # should compile, but gives an error $(WORKDIR)/pptest2.$1.$2.prg: pptest2.c | $(WORKDIR) + @echo "FIXME: " $$@ "currently does not compile." $(if $(QUIET),echo misc/pptest2.$1.$2.prg) - -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) # this should fail to compile, because cc65 does not support returning structs $(WORKDIR)/bug264.$1.$2.prg: bug264.c | $(WORKDIR) + @echo "FIXME: " $$@ "compiles but should give an error." $(if $(QUIET),echo misc/bug264.$1.$2.prg) - -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) # this should fail to compile, because there are errors in the code $(WORKDIR)/bug1048.$1.$2.prg: bug1048.c | $(WORKDIR) + @echo "FIXME: " $$@ "compiles but should give an error." $(if $(QUIET),echo misc/bug1048.$1.$2.prg) - -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) # internal compiler error $(WORKDIR)/bug1075.$1.$2.prg: bug1075.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1075.$1.$2.prg) - -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) # should compile, but then hangs in an endless loop $(WORKDIR)/endless.$1.$2.prg: endless.c | $(WORKDIR) @@ -106,13 +111,13 @@ $(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)/limits.$1.$2.prg: limits.c $(DIFF) +$(WORKDIR)/limits.$1.$2.prg: limits.c $(DIFF) | $(WORKDIR) $(if $(QUIET),echo misc/limits.$1.$2.prg) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/limits.$1.$2.out $(DIFF) $(WORKDIR)/limits.$1.$2.out limits.ref -$(WORKDIR)/goto.$1.$2.prg: goto.c $(DIFF) +$(WORKDIR)/goto.$1.$2.prg: goto.c $(DIFF) | $(WORKDIR) $(if $(QUIET),echo misc/goto.$1.$2.prg) $(CL65) -t sim$2 -$1 -o $$@ $$< 2>$(WORKDIR)/goto.$1.$2.out $(DIFF) $(WORKDIR)/goto.$1.$2.out goto.ref @@ -121,11 +126,12 @@ $(WORKDIR)/goto.$1.$2.prg: goto.c $(DIFF) $(WORKDIR)/fields.$1.$2.prg: fields.c | $(WORKDIR) @echo "FIXME: " $$@ "currently will fail." $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - -$(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) + $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) + $(WORKDIR)/sitest.$1.$2.prg: sitest.c | $(WORKDIR) - @echo "FIXME: " $$@ "currently will fail." - -$(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) -# -$(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) + @echo "FIXME: " $$@ "currently does not compile." + $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) +# $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) endef # PRG_template From a0c80a8c7248e76744056e3495519629c988fe28 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 21 Jul 2020 19:24:39 +0200 Subject: [PATCH 1459/2161] move (now working) tests to test/val --- test/misc/Makefile | 12 +----------- test/{misc => val}/bug975.c | 0 test/{misc => val}/fields.c | 0 3 files changed, 1 insertion(+), 11 deletions(-) rename test/{misc => val}/bug975.c (100%) rename test/{misc => val}/fields.c (100%) diff --git a/test/misc/Makefile b/test/misc/Makefile index 1405e05bf..42fbe2c55 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -63,11 +63,6 @@ $(DIFF): ../bdiff.c | $(WORKDIR) define PRG_template -# should compile, but gives an error -$(WORKDIR)/bug975.$1.$2.prg: bug975.c | $(WORKDIR) - $(if $(QUIET),echo misc/bug975.$1.$2.prg) - $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - # should compile, but gives an error $(WORKDIR)/bug250.$1.$2.prg: bug250.c | $(WORKDIR) @echo "FIXME: " $$@ "currently does not compile." @@ -98,7 +93,7 @@ $(WORKDIR)/bug1048.$1.$2.prg: bug1048.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1048.$1.$2.prg) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) -# internal compiler error +# compiles, but we cant easily check if it works $(WORKDIR)/bug1075.$1.$2.prg: bug1075.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1075.$1.$2.prg) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) @@ -123,11 +118,6 @@ $(WORKDIR)/goto.$1.$2.prg: goto.c $(DIFF) | $(WORKDIR) $(DIFF) $(WORKDIR)/goto.$1.$2.out goto.ref # the rest are tests that fail currently for one reason or another -$(WORKDIR)/fields.$1.$2.prg: fields.c | $(WORKDIR) - @echo "FIXME: " $$@ "currently will fail." - $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) - $(WORKDIR)/sitest.$1.$2.prg: sitest.c | $(WORKDIR) @echo "FIXME: " $$@ "currently does not compile." $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) diff --git a/test/misc/bug975.c b/test/val/bug975.c similarity index 100% rename from test/misc/bug975.c rename to test/val/bug975.c diff --git a/test/misc/fields.c b/test/val/fields.c similarity index 100% rename from test/misc/fields.c rename to test/val/fields.c From 42c162c15e8d30eea651118c059a43de3b721cb9 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 21 Jul 2020 19:58:36 +0200 Subject: [PATCH 1460/2161] rework test for issue #1075 to return an exit code --- test/misc/Makefile | 1 + test/misc/bug1075.c | 25 +++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/test/misc/Makefile b/test/misc/Makefile index 42fbe2c55..879ca7945 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -97,6 +97,7 @@ $(WORKDIR)/bug1048.$1.$2.prg: bug1048.c | $(WORKDIR) $(WORKDIR)/bug1075.$1.$2.prg: bug1075.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1075.$1.$2.prg) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) # should compile, but then hangs in an endless loop $(WORKDIR)/endless.$1.$2.prg: endless.c | $(WORKDIR) diff --git a/test/misc/bug1075.c b/test/misc/bug1075.c index be4cd75f4..6ff5ec8e7 100644 --- a/test/misc/bug1075.c +++ b/test/misc/bug1075.c @@ -1,10 +1,31 @@ /* bug #1075 Internal compiler error */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + long rhs; -int main(void) +int test(void) { /* the whole lhs is errorneously treated as an absolute address (integer constant) neglecting its dereference */ return *(char *)0xD77C + rhs; -} +} + +int res; + +int main(void) +{ + memset(*(char *)0xD76C, 11, 0x80); + rhs = 0x10; + *(char *)(0xD77C + rhs) = 13; + *(char *)0xD77C = 23; + *(char *)0xD78C = 42; + res = test(); + printf("res: %d\n", res); + if (res != (23 + 0x10)) { + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} From 145084c41c1b1ea2b559ac4ec62654756ceb2404 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 21 Jul 2020 20:02:51 +0200 Subject: [PATCH 1461/2161] move test for issue #1075 to test/var --- test/misc/Makefile | 6 ------ test/{misc => val}/bug1075.c | 0 2 files changed, 6 deletions(-) rename test/{misc => val}/bug1075.c (100%) diff --git a/test/misc/Makefile b/test/misc/Makefile index 879ca7945..7e19d6360 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -93,12 +93,6 @@ $(WORKDIR)/bug1048.$1.$2.prg: bug1048.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1048.$1.$2.prg) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) -# compiles, but we cant easily check if it works -$(WORKDIR)/bug1075.$1.$2.prg: bug1075.c | $(WORKDIR) - $(if $(QUIET),echo misc/bug1075.$1.$2.prg) - $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) - # 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) diff --git a/test/misc/bug1075.c b/test/val/bug1075.c similarity index 100% rename from test/misc/bug1075.c rename to test/val/bug1075.c From 9e43c0a56977c69885b31f3c9710103fafb7a042 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 21 Jul 2020 21:04:41 +0200 Subject: [PATCH 1462/2161] added a test related to pr#1102 - we can now return structs by value when they are max. 4 bytes --- test/val/pr1102.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 test/val/pr1102.c diff --git a/test/val/pr1102.c b/test/val/pr1102.c new file mode 100644 index 000000000..2a78e997b --- /dev/null +++ b/test/val/pr1102.c @@ -0,0 +1,77 @@ + +/* pr#1102 - Passing structs/unions <= 4 bytes to/from functions */ + +#include <stdlib.h> +#include <stdio.h> + +typedef struct test1_s { + char a; + int b; + char c; +} test1_t; + +test1_t test1(int a, int b, int c) +{ + test1_t res; + res.a = a; + res.b = b; + res.c = c; + return res; +} + +int test2(test1_t s) +{ + printf("a: %d b: %d c: %d\n", s.a, s.b, s.c); + if ((s.a != 13) || (s.b != 4711) || (s.c != 99)) { + return 0; + } + return 1; +} + +typedef struct test2_s { + char a; + char b; + char c; + char d; +} test2_t; + +test2_t test3(test1_t s) +{ + test2_t ret; + printf("a: %d b: %d c: %d\n", s.a, s.b, s.c); + ret.a = s.c; + ret.b = s.b & 0xff; + ret.c = s.b >> 8; + ret.d = s.a; + return ret; +} + +int main(void) { + test1_t t1; + test2_t t2; + + t1 = test1(12, 1842, 23); + printf("a: %d b: %d c: %d\n", t1.a, t1.b, t1.c); + if ((t1.a != 12) || (t1.b != 1842) || (t1.c != 23)) { + return EXIT_FAILURE; + } + + t1.a = 13; + t1.b = 4711; + t1.c = 99; + if (test2(t1) != 1) { + return EXIT_FAILURE; + } + + t1.a = 66; + t1.b = 0x7788; + t1.c = 22; + t2 = test3(t1); + printf("a: %d b: %d c: %d d: %d\n", t2.a, t2.b, t2.c, t2.d); + if ((t2.a != 22) || (t2.b != 0x88) || (t2.c != 0x77) || (t2.d != 66)) { + return EXIT_FAILURE; + } + + printf("all fine\n"); + return EXIT_SUCCESS; +} From 2bbea6779a0034e7353907776d89ef71dc1bf695 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 21 Jul 2020 23:04:03 +0200 Subject: [PATCH 1463/2161] properly configure sitest so it could work, if we had the respective features :) --- test/misc/sitest.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/test/misc/sitest.c b/test/misc/sitest.c index 3332c064e..d13acf92c 100644 --- a/test/misc/sitest.c +++ b/test/misc/sitest.c @@ -19,8 +19,9 @@ NOTE: This is not a thorough validation test of the facilities. */ +#define STANDARD_CC65 +#define NO_WCHAR #define NO_INTERNAL_WCHAR -/*#define STANDALONE*/ #include <errno.h> #include <limits.h> /* for CHAR_BIT */ @@ -37,7 +38,7 @@ #ifdef NO_WCHAR -#warn "this test checks C99 features, but NO_WCHAR is defined so the test will most definetly fails." +#warn "this test checks C99 features, but NO_WCHAR is defined so the test will most definitely fail." #endif @@ -51,16 +52,6 @@ #include <inttypes.h> /* test idempotency */ -#ifdef STANDALONE - -FILE *outfile=NULL; -#define opentest(x) outfile=stdout; -#define closetest(x) - -#else - -#endif - #if __STDC_VERSION__ >= 199901 #ifndef __Q8_QT #define __Q8_QT long long @@ -1588,4 +1579,4 @@ main() { return status; } -#endif \ No newline at end of file +#endif From 7e1f4760e75d679aee7b4e325ca72b34dde92646 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 21 Jul 2020 23:31:58 +0200 Subject: [PATCH 1464/2161] remove common.h from test/misc, its no more used --- test/misc/common.h | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 test/misc/common.h diff --git a/test/misc/common.h b/test/misc/common.h deleted file mode 100644 index dada61a14..000000000 --- a/test/misc/common.h +++ /dev/null @@ -1,22 +0,0 @@ - -#include <stdio.h> -#include <stdlib.h> - -#define NO_OLD_FUNC_DECL -#define NO_TYPELESS_INT -#define NO_TYPELESS_INT_PTR -#define MAIN_RETURNS_INT -#define NO_IMPLICIT_FUNC_PROTOTYPES -#define NO_FLOATS -#define NO_WCHAR -#define NO_EMPTY_FUNC_ARGS -#define NO_SLOPPY_STRUCT_INIT -#define NO_FUNCS_TAKE_STRUCTS -#define NO_FUNCS_RETURN_STRUCTS -#define CAST_STRUCT_PTR -#define NO_TYPELESS_STRUCT_PTR -#define NO_IMPLICIT_FUNCPTR_CONV -#define SIZEOF_INT_16BIT -#define SIZEOF_LONG_32BIT -#define UNSIGNED_CHARS -#define UNSIGNED_BITFIELDS From 041f981960a7bbe79654fc5617a9ca208c4ffde8 Mon Sep 17 00:00:00 2001 From: Brad Smith <bbbradsmith@users.noreply.github.com> Date: Tue, 21 Jul 2020 17:38:18 -0400 Subject: [PATCH 1465/2161] rand() use XOR to break up unwanted pair correlation (#1107) * rand() use XOR to break up unwanted pair correlation This form of rand() cannot return the same value twice in a row. Two additonal EOR instructions produce a more even distribution of successive pairs. see comments on #951 * rand.s document purpose of XOR * suggested srand() optimization: zero fill unnecessary * test to validate implementation of rand() * srand() improving behaviour and adding startup test * srand() with a tail call to rand() for better initial shuffle * srand() can fall through to rand() instead of tail call --- libsrc/common/rand.s | 32 ++++++------- test/val/rand.c | 110 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 17 deletions(-) create mode 100644 test/val/rand.c diff --git a/libsrc/common/rand.s b/libsrc/common/rand.s index a272af80a..798d6343a 100644 --- a/libsrc/common/rand.s +++ b/libsrc/common/rand.s @@ -15,14 +15,14 @@ ; Multiplier must be 1 (mod 4) ; Added value must be 1 (mod 2) ; This guarantees max. period (2**32) -; The lowest bits have poor entropy and -; exhibit easily detectable patterns, so -; only the upper bits 16-22 and 24-31 of the -; 4-byte state are returned. +; The quality of entropy in the bits of the seed are poorest in the lowest +; bits, and best in the highest bits. ; -; The best 8 bits, 24-31 are returned in the -; low byte A to provide the best entropy in the -; most commonly used part of the return value. +; The high 8 bits are used for the low byte A to provide the best entropy in +; the most commonly used part of the return value. +; +; Finally XOR with the lower 2 bytes is used on the output, which breaks up +; some minor deficient sequential patterns. (#951) ; ; Uses the following LCG values for ax + c (mod m) ; a = $01010101 @@ -42,10 +42,15 @@ ; The seed. When srand() is not called, the C standard says that that rand() ; should behave as if srand() was called with an argument of 1 before. -rand: .dword 1 +rand: .dword $B5B5B4B4 .code +_srand: sta rand+0 ; Store the seed + stx rand+1 + sta rand+2 ; argument << 16 is convenient fill for MSW + stx rand+3 + ; fall through to rand() to sufficiently "shuffle" first rand() result _rand: clc lda rand+0 adc #$B3 @@ -54,18 +59,11 @@ _rand: clc sta rand+1 adc rand+2 sta rand+2 + eor rand+0 and #$7f ; Suppress sign bit (make it positive) tax lda rand+2 adc rand+3 sta rand+3 + eor rand+1 rts ; return bit (16-22,24-31) in (X,A) - -_srand: sta rand+0 ; Store the seed - stx rand+1 - lda #0 - sta rand+2 ; Set MSW to zero - sta rand+3 - rts - - diff --git a/test/val/rand.c b/test/val/rand.c new file mode 100644 index 000000000..f2f604449 --- /dev/null +++ b/test/val/rand.c @@ -0,0 +1,110 @@ +/* This test verifies that the assembly implementation of rand() matches its + * theoretical high level equivalent. + * + * This does about 3000 tests from various starting srand() seeds. + * A more thorough test might visit the entire sequence with 2^32 tests, but + * that takes hours to simulate, and this should be a sufficient sampling. + * + * This will also fail if rand() is ever altered, which might be a warning to + * tread carefully. Some past discussion of RNG here: + * https://github.com/cc65/cc65/pull/951 + */ + +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> + +/* for faster execution */ +#pragma static-locals (on) + +/* values tested per seed */ +#define SUBTESTS 50 + +/* increments used between tested seeds */ +/* 653 is prime and divides 32768 by ~50 */ +#define TESTINC 653 + +static uint32_t seed; + +int ref_rand() +{ + uint16_t output; + /* seed follows the LCG sequence * 0x01010101 + 0xB3B3B3B3 */ + seed = seed * 0x01010101UL + 0xB3B3B3B3UL; + /* output uses the top two bytes (reversed) XOR with bottom two bytes */ + { + uint16_t s0 = (seed >> 0) & 0xFF; + uint16_t s1 = (seed >> 8) & 0xFF; + uint16_t s2 = (seed >> 16) & 0xFF; + uint16_t s3 = (seed >> 24) & 0xFF; + uint16_t o0 = s3 ^ s1; + uint16_t o1 = s2 ^ s0; + output = o0 | (o1 << 8); + } + return (int)(output & 0x7FFF); +} + +void ref_srand(int ax) +{ + uint32_t s = (unsigned int)ax; + seed = s | (s << 16); /* low 16 bits is convenient filler for high 16 bits */ + ref_rand(); /* one pre-call "shuffles" the first rand() result so it isn't too predictable */ +} + +int main(void) +{ + unsigned int i,j; + int a,b; + + /* test that startup state is equivalent to srand(1) */ + { + //srand(1); // implied + ref_srand(1); + for (j=0; j<SUBTESTS; ++j) + { + a = rand(); + b = ref_rand(); + if (a != b) + { + printf("failed startup seed at test %d. rand()=%d reference=%d\n",j,a,b); + return EXIT_FAILURE; + } + } + } + + /* test every power of 2 seed */ + for (i = 0; i < 16; ++i) + { + srand(1<<i); + ref_srand(1<<i); + for (j=0; j<SUBTESTS; ++j) + { + a = rand(); + b = ref_rand(); + if (a != b) + { + printf("failed seed %d at test %d. rand()=%d reference=%d\n",(1<<i),j,a,b); + return EXIT_FAILURE; + } + } + } + + /* test a sampling of seeds*/ + for (i = 0; i < 32768UL; i += TESTINC) + { + srand(i); + ref_srand(i); + for (j=0; j<SUBTESTS; ++j) + { + a = rand(); + b = ref_rand(); + if (a != b) + { + printf("failed seed %d at test %d. rand()=%d reference=%d\n",(1<<i),j,a,b); + return EXIT_FAILURE; + } + } + } + + return EXIT_SUCCESS; +} From 77674352f6d4884c0619ebd812f795f54606c869 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 21 Jul 2020 23:44:36 +0200 Subject: [PATCH 1466/2161] Minor style change. --- libsrc/common/rand.s | 1 + 1 file changed, 1 insertion(+) diff --git a/libsrc/common/rand.s b/libsrc/common/rand.s index 798d6343a..ec1df9860 100644 --- a/libsrc/common/rand.s +++ b/libsrc/common/rand.s @@ -51,6 +51,7 @@ _srand: sta rand+0 ; Store the seed sta rand+2 ; argument << 16 is convenient fill for MSW stx rand+3 ; fall through to rand() to sufficiently "shuffle" first rand() result + _rand: clc lda rand+0 adc #$B3 From df900e30b85b1b8f27e1a4d997555d07333591e7 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 21 Jul 2020 23:50:23 +0200 Subject: [PATCH 1467/2161] removed references to macros from common.h --- test/ref/cc65110210.c | 17 ----------------- test/ref/wf1.c | 22 ---------------------- 2 files changed, 39 deletions(-) diff --git a/test/ref/cc65110210.c b/test/ref/cc65110210.c index ca5b39203..319b2c529 100644 --- a/test/ref/cc65110210.c +++ b/test/ref/cc65110210.c @@ -20,27 +20,10 @@ cl65: Subprocess 'ld65' aborted by signal 11 */ -/* #define STANDALONE */ - #include <stdio.h> #include <limits.h> -#ifdef STANDALONE - -#define NO_IMPLICIT_FUNCPTR_CONV - -#define OPENTEST() -#define CLOSETEST() - -#else - -#endif - -#ifdef NO_IMPLICIT_FUNCPTR_CONV -void (*p1func)(void); -#else void (*p1func)(); -#endif void func(void) { diff --git a/test/ref/wf1.c b/test/ref/wf1.c index e1ed7a417..574e7205f 100644 --- a/test/ref/wf1.c +++ b/test/ref/wf1.c @@ -25,35 +25,21 @@ int next; /* index of next free entry in words */ /*struct node *lookup();*/ -#if defined(NO_NEW_PROTOTYPES_FOR_OLD_FUNC_DECL) && !defined(NO_OLD_FUNC_DECL) - -#else - int err(char *s); int getword(char *buf); void tprint(struct node *tree); struct node *lookup(char *word, struct node **p); -#endif - int isletter(char c); /* err - print error message s and die */ -#ifndef NO_OLD_FUNC_DECL err(s) char *s; { -#else -int err(char *s) { -#endif printf("? %s\n", s); exit(EXIT_FAILURE); } /* getword - get next input word into buf, return 0 on EOF */ -#ifndef NO_OLD_FUNC_DECL int getword(buf) char *buf; -#else -int getword(char *buf) -#endif { char *s; int c; @@ -77,12 +63,8 @@ int isletter(char c) } /* lookup - lookup word in tree; install if necessary */ -#ifndef NO_OLD_FUNC_DECL struct node *lookup(word, p) char *word; struct node **p; -#else -struct node *lookup(char *word, struct node **p) -#endif { int cond; /* char *malloc(); */ @@ -108,11 +90,7 @@ struct node *lookup(char *word, struct node **p) } /* tprint - print tree */ -#ifndef NO_OLD_FUNC_DECL void tprint(tree) struct node *tree; { -#else -void tprint(struct node *tree) { -#endif if (tree) { tprint(tree->left); printf("%d:%s\n", tree->count, tree->word); From 4a9c5ff63b7752b6c4210e6f0748558581aa3845 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 21 Jul 2020 23:59:05 +0200 Subject: [PATCH 1468/2161] use uint16_t instead of magic ifdefs, leaving support for bit type in there incase we support it some day --- test/val/add2.c | 29 +++++++---------------------- test/val/compare4.c | 20 +++++--------------- test/val/rotate3.c | 19 +++++-------------- test/val/rotate4.c | 19 +++++-------------- test/val/rotate5.c | 19 +++++-------------- test/val/rotate6.c | 19 +++++-------------- test/val/rotate7.c | 19 +++---------------- test/val/sub1.c | 18 ++++++------------ 8 files changed, 41 insertions(+), 121 deletions(-) diff --git a/test/val/add2.c b/test/val/add2.c index 90f0f4175..6fc23e5da 100644 --- a/test/val/add2.c +++ b/test/val/add2.c @@ -6,33 +6,18 @@ #include <stdio.h> #include <limits.h> +#include <stdint.h> + +/* #define SUPPORT_BIT_TYPES */ unsigned char success=0; unsigned char failures=0; unsigned char dummy=0; -#ifdef SIZEOF_INT_16BIT -#if defined(__LINUX__) || defined(LINUX) -unsigned short aint0 = 0; -unsigned short aint1 = 0; -unsigned short aint2 = 0; -unsigned short aint3 = 0; - -#else -unsigned int aint0 = 0; -unsigned int aint1 = 0; -unsigned int aint2 = 0; -unsigned int aint3 = 0; - -#endif - -#else -unsigned int aint0 = 0; -unsigned int aint1 = 0; -unsigned int aint2 = 0; -unsigned int aint3 = 0; - -#endif +uint16_t aint0 = 0; +uint16_t aint1 = 0; +uint16_t aint2 = 0; +uint16_t aint3 = 0; unsigned char achar0 = 0; unsigned char achar1 = 0; diff --git a/test/val/compare4.c b/test/val/compare4.c index 47948c3a3..8e3baad5d 100644 --- a/test/val/compare4.c +++ b/test/val/compare4.c @@ -6,11 +6,14 @@ #include <stdio.h> #include <limits.h> +#include <stdint.h> /* compare4.c */ +/*#define SUPPORT_BIT_TYPES */ + /*#define COMPARE_OUT_OF_RANGE 1*/ unsigned char success = 0; @@ -20,22 +23,9 @@ unsigned char dummy = 0; #ifdef SUPPORT_BIT_TYPES bit bit0 = 0; #endif -#ifdef SIZEOF_INT_16BIT -#if defined(__LINUX__) || defined(LINUX) -short int0 = 0; -short int1 = 0; -#else -int int0 = 0; -int int1 = 0; - -#endif - -#else -int int0 = 0; -int int1 = 0; - -#endif +int16_t int0 = 0; +int16_t int1 = 0; signed char char0 = 0; signed char char1 = 0; diff --git a/test/val/rotate3.c b/test/val/rotate3.c index 21b2dc370..8ac2581e9 100644 --- a/test/val/rotate3.c +++ b/test/val/rotate3.c @@ -6,6 +6,9 @@ #include <stdio.h> #include <limits.h> +#include <stdint.h> + +/* #define SUPPORT_BIT_TYPES */ unsigned char success=0; unsigned char failures=0; @@ -14,22 +17,10 @@ unsigned char dummy=0; #ifdef SUPPORT_BIT_TYPES bit bit0 = 0; #endif -#ifdef SIZEOF_INT_16BIT -#if defined(__LINUX__) || defined(LINUX) -unsigned short aint0 = 0; -unsigned short aint1 = 0; -#else -unsigned int aint0 = 0; -unsigned int aint1 = 0; +uint16_t aint0 = 0; +uint16_t aint1 = 0; -#endif - -#else -unsigned int aint0 = 0; -unsigned int aint1 = 0; - -#endif unsigned char achar0 = 0; unsigned char achar1 = 0; unsigned char achar2 = 0; diff --git a/test/val/rotate4.c b/test/val/rotate4.c index 09b1ebf4c..4b50b0d1c 100644 --- a/test/val/rotate4.c +++ b/test/val/rotate4.c @@ -6,6 +6,9 @@ #include <stdio.h> #include <limits.h> +#include <stdint.h> + +/* #define SUPPORT_BIT_TYPES */ unsigned char success=0; unsigned char failures=0; @@ -14,22 +17,10 @@ unsigned char dummy=0; #ifdef SUPPORT_BIT_TYPES bit bit0 = 0; #endif -#ifdef SIZEOF_INT_16BIT -#if defined(__LINUX__) || defined(LINUX) -unsigned short aint0 = 0; -unsigned short aint1 = 0; -#else -unsigned int aint0 = 0; -unsigned int aint1 = 0; +uint16_t aint0 = 0; +uint16_t aint1 = 0; -#endif - -#else -unsigned int aint0 = 0; -unsigned int aint1 = 0; - -#endif unsigned char uchar0 = 0; unsigned char uchar1 = 0; unsigned char uchar2 = 0; diff --git a/test/val/rotate5.c b/test/val/rotate5.c index 501e2e567..9de897321 100644 --- a/test/val/rotate5.c +++ b/test/val/rotate5.c @@ -6,6 +6,9 @@ #include <stdio.h> #include <limits.h> +#include <stdint.h> + +/* #define SUPPORT_BIT_TYPES */ unsigned char success=0; unsigned char failures=0; @@ -14,22 +17,10 @@ unsigned char dummy=0; #ifdef SUPPORT_BIT_TYPES bit bit0 = 0; #endif -#ifdef SIZEOF_INT_16BIT -#if defined(__LINUX__) || defined(LINUX) -signed short aint0 = 0; -signed short aint1 = 0; -#else -signed int aint0 = 0; -signed int aint1 = 0; +int16_t aint0 = 0; +int16_t aint1 = 0; -#endif - -#else -signed int aint0 = 0; -signed int aint1 = 0; - -#endif signed char achar0 = 0; signed char achar1 = 0; signed char achar2 = 0; diff --git a/test/val/rotate6.c b/test/val/rotate6.c index 9109e124e..93a770d99 100644 --- a/test/val/rotate6.c +++ b/test/val/rotate6.c @@ -6,6 +6,9 @@ #include <stdio.h> #include <limits.h> +#include <stdint.h> + +/* #define SUPPORT_BIT_TYPES */ unsigned char success=0; unsigned char failures=0; @@ -14,22 +17,10 @@ unsigned char dummy=0; #ifdef SUPPORT_BIT_TYPES bit bit0 = 0; #endif -#ifdef SIZEOF_INT_16BIT -#if defined(__LINUX__) || defined(LINUX) -signed short aint0 = 0; -signed short aint1 = 0; -#else -signed int aint0 = 0; -signed int aint1 = 0; +int16_t aint0 = 0; +int16_t aint1 = 0; -#endif - -#else -signed int aint0 = 0; -signed int aint1 = 0; - -#endif signed char achar0 = 0; signed char achar1 = 0; signed char achar2 = 0; diff --git a/test/val/rotate7.c b/test/val/rotate7.c index 2b30b86dd..4a044c16a 100644 --- a/test/val/rotate7.c +++ b/test/val/rotate7.c @@ -6,27 +6,14 @@ #include <stdio.h> #include <limits.h> +#include <stdint.h> unsigned char success=0; unsigned char failures=0; unsigned char dummy=0; -#ifdef SIZEOF_INT_16BIT -#if defined(__LINUX__) || defined(LINUX) -signed short aint0 = 0; -signed short aint1 = 0; - -#else -signed int aint0 = 0; -signed int aint1 = 0; - -#endif - -#else -signed int aint0 = 0; -signed int aint1 = 0; - -#endif +int16_t aint0 = 0; +int16_t aint1 = 0; /* signed char achar0 = 0; diff --git a/test/val/sub1.c b/test/val/sub1.c index f1ae9394f..5dbba97df 100644 --- a/test/val/sub1.c +++ b/test/val/sub1.c @@ -6,6 +6,10 @@ #include <stdio.h> #include <limits.h> +#include <stdint.h> + +/* #define SUPPORT_BIT_TYPES */ +/* #define SUPPORT_BIT_ARITHMETIC */ unsigned char success=0; unsigned char failures=0; @@ -28,19 +32,9 @@ bit bit11 = 0; #endif -#ifdef SIZEOF_INT_16BIT -#if defined(__LINUX__) || defined(LINUX) -unsigned short aint0 = 0; -unsigned short aint1 = 0; -#else -unsigned int aint0 = 0; -unsigned int aint1 = 0; -#endif +uint16_t aint0 = 0; +uint16_t aint1 = 0; -#else -unsigned int aint0 = 0; -unsigned int aint1 = 0; -#endif unsigned char achar0 = 0; unsigned char achar1 = 0; unsigned char achar2 = 0; From eb094ecf6a07f4aa8063c5ed96f9eb4875456807 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 22 Jul 2020 00:21:23 +0200 Subject: [PATCH 1469/2161] remove ifdef magic --- test/val/ptrfunc.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/test/val/ptrfunc.c b/test/val/ptrfunc.c index 4aa23b77b..78e53e254 100644 --- a/test/val/ptrfunc.c +++ b/test/val/ptrfunc.c @@ -6,7 +6,7 @@ #include <stdio.h> -#define NO_IMPLICIT_FUNCPTR_CONV +/* #define SUPPORT_BIT_TYPES */ unsigned char success=0; unsigned char failures=0; @@ -33,15 +33,9 @@ volatile unsigned char uchar1 = 0; volatile unsigned char uchar2 = 0; #endif -#ifdef NO_IMPLICIT_FUNCPTR_CONV void (*pfunc)(void); void (*p1func)(void); unsigned char (*pcfunc)(void); -#else -void (*pfunc)(); -void (*p1func)(); -unsigned char (*pcfunc)(); -#endif void done() { @@ -79,11 +73,7 @@ void docall1() } } -#ifdef NO_IMPLICIT_FUNCPTR_CONV -void docall2( void(*pf)(void) ) -#else void docall2( void(*pf)() ) -#endif { unsigned char i; for(i = 0; i < 2; i++) { From 44c82eb1c3f0360aa70d1ce77a16989e5567b59b Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 21 Jul 2020 18:25:26 -0400 Subject: [PATCH 1470/2161] Made da65 disassemble branch instructions with relative address expression operands if there's no label. --- src/da65/handler.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/da65/handler.c b/src/da65/handler.c index f8a778b22..255b8da86 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -346,7 +346,12 @@ void OH_Relative (const OpcDesc* D) GenerateLabel (D->Flags, Addr); /* Output the line */ - OneLine (D, "%s", GetAddrArg (D->Flags, 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); + } } From e22e9c403c7bbbb99c46ff961d91d46a5ab03221 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 22 Jul 2020 14:57:40 +0200 Subject: [PATCH 1471/2161] added testcase for issue #1098 --- test/misc/Makefile | 18 ++++++++++++++++++ test/misc/bug1098.c | 13 +++++++++++++ test/misc/bug1098a.c | 13 +++++++++++++ test/misc/bug1098b.c | 13 +++++++++++++ 4 files changed, 57 insertions(+) create mode 100644 test/misc/bug1098.c create mode 100644 test/misc/bug1098a.c create mode 100644 test/misc/bug1098b.c diff --git a/test/misc/Makefile b/test/misc/Makefile index 7e19d6360..19768d5aa 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -93,6 +93,24 @@ $(WORKDIR)/bug1048.$1.$2.prg: bug1048.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1048.$1.$2.prg) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) +# this should fail to compile, because there are errors in the code +$(WORKDIR)/bug1098.$1.$2.prg: bug1098.c | $(WORKDIR) + @echo "FIXME: " $$@ "compiles but should give an error." + $(if $(QUIET),echo misc/bug1098.$1.$2.prg) + $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + +# this should fail to compile, because there are errors in the code +$(WORKDIR)/bug1098a.$1.$2.prg: bug1098a.c | $(WORKDIR) + @echo "FIXME: " $$@ "compiles but should give an error." + $(if $(QUIET),echo misc/bug1098a.$1.$2.prg) + $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + +# this should fail to compile, because there are errors in the code +$(WORKDIR)/bug1098b.$1.$2.prg: bug1098b.c | $(WORKDIR) + @echo "FIXME: " $$@ "compiles but should give an error." + $(if $(QUIET),echo misc/bug1098b.$1.$2.prg) + $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + # 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) diff --git a/test/misc/bug1098.c b/test/misc/bug1098.c new file mode 100644 index 000000000..c49296245 --- /dev/null +++ b/test/misc/bug1098.c @@ -0,0 +1,13 @@ + +/* bug #1098 Empty enumerator-list */ + +/* The C Standard requires that something exists between the braces for + * enum, struct, and union. */ + +enum { +}; + +int main(void) +{ + return 0; +} diff --git a/test/misc/bug1098a.c b/test/misc/bug1098a.c new file mode 100644 index 000000000..63c1c8da0 --- /dev/null +++ b/test/misc/bug1098a.c @@ -0,0 +1,13 @@ + +/* bug #1098 Empty enumerator-list */ + +/* The C Standard requires that something exists between the braces for + * enum, struct, and union. */ + +struct { +}; + +int main(void) +{ + return 0; +} diff --git a/test/misc/bug1098b.c b/test/misc/bug1098b.c new file mode 100644 index 000000000..ebd3e94c8 --- /dev/null +++ b/test/misc/bug1098b.c @@ -0,0 +1,13 @@ + +/* bug #1098 Empty enumerator-list */ + +/* The C Standard requires that something exists between the braces for + * enum, struct, and union. */ + +union { +}; + +int main(void) +{ + return 0; +} From 6abf24e25eac975765524441e7f0dc9528372911 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 22 Jul 2020 15:12:02 +0200 Subject: [PATCH 1472/2161] move test for issue #1077 to test/val --- test/{todo => val}/bug1077.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{todo => val}/bug1077.c (100%) diff --git a/test/todo/bug1077.c b/test/val/bug1077.c similarity index 100% rename from test/todo/bug1077.c rename to test/val/bug1077.c From 844f5a9d337ad80cac3489e62499598bf4020182 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 22 Jul 2020 15:12:29 +0200 Subject: [PATCH 1473/2161] hook up test/todo in the toplevel test makefile --- test/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/Makefile b/test/Makefile index fc1ac246c..be6e60013 100644 --- a/test/Makefile +++ b/test/Makefile @@ -25,6 +25,7 @@ continue: @$(MAKE) -C ref all @$(MAKE) -C err all @$(MAKE) -C misc all + @$(MAKE) -C todo all mostlyclean: @$(MAKE) -C asm clean @@ -33,6 +34,7 @@ mostlyclean: @$(MAKE) -C ref clean @$(MAKE) -C err clean @$(MAKE) -C misc clean + @$(MAKE) -C todo clean clean: mostlyclean @$(call RMDIR,$(WORKDIR)) From ce06b20c6c696f781332c45958a082b5a7b1983e Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 22 Jul 2020 15:31:39 +0200 Subject: [PATCH 1474/2161] add some details to the readme --- test/readme.txt | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/test/readme.txt b/test/readme.txt index 57ebfdd23..21b13fc62 100644 --- a/test/readme.txt +++ b/test/readme.txt @@ -2,29 +2,40 @@ This directory contains test code for automatic regression testing of the CC65 compiler. -/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 +/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. -/ref - these tests produce output that must be compared with reference output +/ref - These tests produce output that must be compared with reference output. /err - contains tests that MUST NOT compile -/todo - these tests fail due to open compiler issues. - when an issue was fixed, the test should get moved to /var +/todo - These tests fail due to open compiler issues. + + The makefile in this directory _expects_ the tests to fail, because of + that when an issue was fixed it will break the CI. The test should get + moved to /var in the PR fixing the issue, which will make CI pass again. + No changes to makefiles are required! /asm - contains the assembler regression tests /dasm - contains the disassembler regression tests /misc - a few tests that need special care of some sort - tests that (incorrectly) fail to compile and other tests that fail and - do NOT return an exit code are collected here. + + Tests that (incorrectly) fail to compile and other tests that fail and + do NOT return an exit code are collected here. The makefile _expects_ + those tests to fail, so when an issue is fixed it will break the CI. + When this happens, the PR fixing the issue should also "invert" the + failing condition in the makefile by removing the $(NOT) before the + offending line (or removing it when it is already there), which will + make the CI pass again. The test should then be moved elsewhere later, + which will require additional changes to the makefile(s). -to run the tests use "make" in this (top) directory, the makefile should exit +To run the tests use "make" in this (top) directory, the makefile should exit with no error. -when a test failed you can use "make continue" to run further tests +When a test failed you can use "make continue" to run further tests. -------------------------------------------------------------------------------- From 98b2d43c2bd03be06da700b1f9dd4cac0ebf3f4c Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 22 Jul 2020 15:52:04 +0200 Subject: [PATCH 1475/2161] added tests related to pr #1110 --- test/err/pr1110.c | 15 +++++++++++++++ test/val/pr1110a.c | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 test/err/pr1110.c create mode 100644 test/val/pr1110a.c diff --git a/test/err/pr1110.c b/test/err/pr1110.c new file mode 100644 index 000000000..86955c720 --- /dev/null +++ b/test/err/pr1110.c @@ -0,0 +1,15 @@ + +/* pr #1110 - not only should the current test case for #975 compile and work, + * but also the code piece below fail to compile and generate errors like commented: */ + +static const unsigned char array[3]; /* OK */ +static const unsigned char array[] = { 0, 1, 2 }; /* OK - complete definition*/ +static const unsigned char array[3]; /* OK */ +static const unsigned char array[]; /* OK */ +static const unsigned char array[] = { 1, 2, 3 }; /* Error - redefinition */ +static const unsigned char array[4]; /* Error - conflicting size */ + +int main(void) +{ + return 0; +} diff --git a/test/val/pr1110a.c b/test/val/pr1110a.c new file mode 100644 index 000000000..0e0d91f85 --- /dev/null +++ b/test/val/pr1110a.c @@ -0,0 +1,19 @@ + +/* pr #1110 - the part of the redefinition that should compile */ + +static const unsigned char array[3]; /* OK */ +static const unsigned char array[] = { 0, 1, 2 }; /* OK - complete definition*/ +static const unsigned char array[3]; /* OK */ +static const unsigned char array[]; /* OK */ + +#include <stdlib.h> +#include <stdio.h> + +int main(void) +{ + printf("%u %u %u\n", array[0], array[1], array[2]); + if ((array[0] != 0) || (array[1] != 1) || (array[2] != 2)) { + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} From afe455238c17b0796365e4de5eb777be362798d2 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 22 Jul 2020 15:55:55 +0200 Subject: [PATCH 1476/2161] added test related to issue #1113 --- test/misc/Makefile | 7 +++++++ test/misc/bug1113.c | 12 ++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 test/misc/bug1113.c diff --git a/test/misc/Makefile b/test/misc/Makefile index 19768d5aa..9045e4e4f 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -111,6 +111,13 @@ $(WORKDIR)/bug1098b.$1.$2.prg: bug1098b.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1098b.$1.$2.prg) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) +# this should fail to compile, because there are errors in the code +# instead, the compiler crashes +$(WORKDIR)/bug1113.$1.$2.prg: bug1113.c | $(WORKDIR) + @echo "FIXME: " $$@ "compiler crashes but should give an error." + $(if $(QUIET),echo misc/bug1113.$1.$2.prg) + $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + # 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) diff --git a/test/misc/bug1113.c b/test/misc/bug1113.c new file mode 100644 index 000000000..d1aecaa0b --- /dev/null +++ b/test/misc/bug1113.c @@ -0,0 +1,12 @@ + +/* bug #1113 - Compiler crashes when calling functions "redefined" as other types */ + +void f() {} + +int f; + +int main(void) +{ + f(); + return 0; +} From 5df2de06290e9b7181c03eeb311f7687ef469b80 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 22 Jul 2020 23:27:04 +0200 Subject: [PATCH 1477/2161] Added test target. --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 206f853fc..3331f6fb9 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: all mostlyclean clean install zip avail unavail bin lib doc html info samples +.PHONY: all mostlyclean clean install zip avail unavail bin lib doc html info samples test .SUFFIXES: @@ -20,6 +20,9 @@ doc html info: samples: @$(MAKE) -C samples --no-print-directory $@ +test: + @$(MAKE) -C test --no-print-directory $@ + %65: @$(MAKE) -C src --no-print-directory $@ From 294b5d1cf1e79ed2b4a21000e37d4e423214cfa1 Mon Sep 17 00:00:00 2001 From: compyx <b.wassink@ziggo.nl> Date: Wed, 15 Jul 2020 21:39:29 +0200 Subject: [PATCH 1478/2161] C64 soft80 conio: shave off a few bytes and cycles --- libsrc/c64/soft80_cgetc.s | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/libsrc/c64/soft80_cgetc.s b/libsrc/c64/soft80_cgetc.s index aa12cd8ca..1bca57bec 100644 --- a/libsrc/c64/soft80_cgetc.s +++ b/libsrc/c64/soft80_cgetc.s @@ -46,8 +46,18 @@ invertcursor: lda #$34 sta $01 - jsr setcolor - + ldy #0 + bcs @set + ; restore old value + lda tmp1 + bcc @lp0 +@set: + ; save old value + lda (CRAM_PTR),y ; vram + sta tmp1 + lda soft80_internal_cellcolor +@lp0: + sta (CRAM_PTR),y ; vram ldx soft80_internal_cursorxlsb ldy #7 @lp1: @@ -65,20 +75,7 @@ invertcursor: ; do not use soft80_putcolor here to make sure the cursor is always ; shown using the current textcolor without disturbing the "color voodoo" ; in soft80_cputc -setcolor: - ldy #0 - bcs @set - ; restore old value - lda tmp1 - sta (CRAM_PTR),y ; vram - rts -@set: - ; save old value - lda (CRAM_PTR),y ; vram - sta tmp1 - lda soft80_internal_cellcolor - sta (CRAM_PTR),y ; vram - rts + .rodata nibble: .byte $f0, $0f From 81d3dedb4109cd3da845ec77b1fddcc3f83c5aa3 Mon Sep 17 00:00:00 2001 From: compyx <b.wassink@ziggo.nl> Date: Wed, 15 Jul 2020 22:44:34 +0200 Subject: [PATCH 1479/2161] Move comment block as requested --- libsrc/c64/soft80_cgetc.s | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libsrc/c64/soft80_cgetc.s b/libsrc/c64/soft80_cgetc.s index 1bca57bec..28e6b0042 100644 --- a/libsrc/c64/soft80_cgetc.s +++ b/libsrc/c64/soft80_cgetc.s @@ -46,6 +46,9 @@ invertcursor: lda #$34 sta $01 + ; do not use soft80_putcolor here to make sure the cursor is always + ; shown using the current textcolor without disturbing the "color voodoo" + ; in soft80_cputc ldy #0 bcs @set ; restore old value @@ -72,11 +75,6 @@ invertcursor: cli rts - ; do not use soft80_putcolor here to make sure the cursor is always - ; shown using the current textcolor without disturbing the "color voodoo" - ; in soft80_cputc - - .rodata nibble: .byte $f0, $0f From ed3f281b9e9983f381c1c72b029e525e220e68eb Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 27 Jul 2020 14:40:27 +0200 Subject: [PATCH 1480/2161] fix wording --- test/readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/readme.txt b/test/readme.txt index 21b13fc62..a8746ba60 100644 --- a/test/readme.txt +++ b/test/readme.txt @@ -26,7 +26,7 @@ compiler. do NOT return an exit code are collected here. The makefile _expects_ those tests to fail, so when an issue is fixed it will break the CI. When this happens, the PR fixing the issue should also "invert" the - failing condition in the makefile by removing the $(NOT) before the + failing condition in the makefile by adding a $(NOT) before the offending line (or removing it when it is already there), which will make the CI pass again. The test should then be moved elsewhere later, which will require additional changes to the makefile(s). From 4316242d7ee3d1471bfdbef6469cee5a2190336a Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 27 Jul 2020 17:47:14 +0200 Subject: [PATCH 1481/2161] Adjusted to https://github.com/cc65/cc65/commit/5df2de06290e9b7181c03eeb311f7687ef469b80 (and slightly simplified). --- test/Makefile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/Makefile b/test/Makefile index be6e60013..abc70d58f 100644 --- a/test/Makefile +++ b/test/Makefile @@ -12,11 +12,9 @@ endif WORKDIR = ../testwrk -.PHONY: all dotests continue mostlyclean clean +.PHONY: test continue mostlyclean clean -all: dotests - -dotests: mostlyclean continue +test: mostlyclean continue continue: @$(MAKE) -C asm all From cdd23edd37f44e730fe00acd66ccffeb626d3499 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 27 Jul 2020 17:59:24 +0200 Subject: [PATCH 1482/2161] Added building of samples. --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c84eb0cc2..630466cc0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,11 @@ install: script: - make bin USER_CFLAGS=-Werror - make lib QUIET=1 - - make -C test QUIET=1 + - make test QUIET=1 + - make samples - make -C src clean - make bin USER_CFLAGS=-Werror CROSS_COMPILE=i686-w64-mingw32- + - make -C samples clean - make doc zip after_success: - make -f Makefile.travis From 04d16b3740d962ecfe0f1c9cc83e3b702835fa58 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Tue, 28 Jul 2020 13:38:49 +0200 Subject: [PATCH 1483/2161] Make $WORKDIR for tests/err Without this, if there is a test that can compile, it will still fail because the WORKDIR does not exist: ``` pass.c(1): Fatal: Cannot open output file '../../testwrk/err/pass.s': No such file or directory ``` --- test/err/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/err/Makefile b/test/err/Makefile index 4b05ca5db..1273bbb2c 100644 --- a/test/err/Makefile +++ b/test/err/Makefile @@ -34,7 +34,10 @@ TESTS = $(patsubst %.c,$(WORKDIR)/%.s,$(SOURCES)) all: $(TESTS) -$(WORKDIR)/%.s: %.c +$(WORKDIR): + $(call MKDIR,$(WORKDIR)) + +$(WORKDIR)/%.s: %.c | $(WORKDIR) $(if $(QUIET),echo err/$*.s) $(NOT) $(CC65) -o $@ $< $(NULLERR) From c0f2b69bef0c47cdbcbfa9b2291b68768c294529 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sun, 19 Jul 2020 22:59:44 +0200 Subject: [PATCH 1484/2161] Add test case for sign extending < 1 byte --- test/todo/bug1095.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/test/todo/bug1095.c b/test/todo/bug1095.c index a00a10585..0803c2d1c 100644 --- a/test/todo/bug1095.c +++ b/test/todo/bug1095.c @@ -30,7 +30,8 @@ static struct signed_ints { signed int a : 3; signed int b : 3; signed int c : 3; -} si = {-4, -1, 3}; + signed int d : 10; +} si = {-4, -1, 3, -500}; static void test_signed_bitfield(void) { @@ -61,9 +62,19 @@ static void test_signed_bitfield(void) failures++; } + if (si.d >= 0) { + printf("Got si.d = %d, expected negative.\n", si.d); + failures++; + } + if (si.d != -500) { + printf("Got si.d = %d, expected -500.\n", si.d); + failures++; + } + si.a = -3; si.b = 1; si.c = -2; + si.d = 500; if (si.a >= 0) { printf("Got si.a = %d, expected negative.\n", si.a); @@ -91,6 +102,15 @@ static void test_signed_bitfield(void) printf("Got si.c = %d, expected -2.\n", si.c); failures++; } + + if (si.d <= 0) { + printf("Got si.d = %d, expected positive.\n", si.d); + failures++; + } + if (si.d != 500) { + printf("Got si.d = %d, expected 500.\n", si.d); + failures++; + } } int main(void) From c272c73686e940ef9caf608c6a437904bb874349 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Tue, 28 Jul 2020 13:47:47 +0200 Subject: [PATCH 1485/2161] Add err test for char bit-fields #1047 --- test/err/bug1047.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 test/err/bug1047.c diff --git a/test/err/bug1047.c b/test/err/bug1047.c new file mode 100644 index 000000000..3fb11250f --- /dev/null +++ b/test/err/bug1047.c @@ -0,0 +1,82 @@ +/* + Copyright 2020 Google LLC + + 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. +*/ + +/* + Tests of char bit-fields; see https://github.com/cc65/cc65/issues/1047 +*/ + +#include <stdio.h> + +static unsigned char failures = 0; + +static struct chars { + unsigned char a : 3; + unsigned char b : 3; + unsigned char c : 3; +} cs = {4, 1, 3}; + +static void test_char_bitfield(void) +{ + if (sizeof (cs) != 2) { + printf("Got sizeof (cs) = %zu, expected 2.\n", sizeof (cs)); + failures++; + } + + if (cs.a != 4) { + printf("Got cs.a = %u, expected 4.\n", cs.a); + failures++; + } + + if (cs.b != 1) { + printf("Got cs.b = %u, expected 1.\n", cs.b); + failures++; + } + + if (cs.c != 3) { + printf("Got cs.c = %u, expected 3.\n", cs.c); + failures++; + } + + cs.a = -1; + cs.b = 6; + cs.c = 1; + + if (cs.a != 7) { + printf("Got cs.a = %u, expected 7.\n", cs.a); + failures++; + } + + if (cs.b != 6) { + printf("Got cs.b = %u, expected 6.\n", cs.b); + failures++; + } + + if (cs.c != 1) { + printf("Got cs.c = %u, expected 1.\n", cs.c); + failures++; + } +} + +int main(void) +{ + test_char_bitfield(); + printf("failures: %u\n", failures); + return failures; +} From daa65199b34974302eee410ae68e604291e48a69 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 26 Jul 2020 20:12:55 +0800 Subject: [PATCH 1486/2161] Fixed underlying types of enums. Made enumerator diagnostics more sensible. Fixed Issue #1048 as a natural result. --- src/cc65/datatype.c | 176 +++++++++++++++++++++++++++---- src/cc65/datatype.h | 158 +++++++++++++++++++--------- src/cc65/declare.c | 247 ++++++++++++++++++++++++++++++++++---------- src/cc65/function.c | 2 +- src/cc65/swstmt.c | 2 +- src/cc65/symentry.h | 6 ++ src/cc65/symtab.c | 48 ++++++++- src/cc65/symtab.h | 3 + src/cc65/typecmp.c | 8 +- 9 files changed, 526 insertions(+), 124 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 2a989e9f8..3f2725659 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -83,14 +83,9 @@ const char* GetBasicTypeName (const Type* T) ** Return "type" for unknown basic types. */ { - switch (GetType (T)) { - case T_TYPE_CHAR: return "char"; - case T_TYPE_SHORT: return "short"; - case T_TYPE_INT: return "integer"; - case T_TYPE_LONG: return "long"; - case T_TYPE_LONGLONG: return "long long"; + switch (GetRawType (T)) { case T_TYPE_ENUM: return "enum"; - case T_TYPE_FLOAT: return "poinfloatter"; + case T_TYPE_FLOAT: return "float"; case T_TYPE_DOUBLE: return "double"; case T_TYPE_VOID: return "void"; case T_TYPE_STRUCT: return "struct"; @@ -99,8 +94,42 @@ const char* GetBasicTypeName (const Type* T) case T_TYPE_PTR: return "pointer"; case T_TYPE_FUNC: return "function"; case T_TYPE_NONE: /* FALLTHROUGH */ - default: return "type"; + default: break; } + if (IsClassInt (T)) { + if (IsSignSigned (T)) { + switch (GetRawType (T)) { + case T_TYPE_CHAR: return "signed char"; + case T_TYPE_SHORT: return "short"; + case T_TYPE_INT: return "int"; + case T_TYPE_LONG: return "long"; + case T_TYPE_LONGLONG: return "long long"; + default: + return "signed integer"; + } + } else if (IsSignUnsigned (T)) { + switch (GetRawType (T)) { + case T_TYPE_CHAR: return "unsigned char"; + case T_TYPE_SHORT: return "unsigned short"; + case T_TYPE_INT: return "unsigned int"; + case T_TYPE_LONG: return "unsigned long"; + case T_TYPE_LONGLONG: return "unsigned long long"; + default: + return "unsigned integer"; + } + } else { + switch (GetRawType (T)) { + case T_TYPE_CHAR: return "char"; + case T_TYPE_SHORT: return "short"; + case T_TYPE_INT: return "int"; + case T_TYPE_LONG: return "long"; + case T_TYPE_LONGLONG: return "long long"; + default: + return "integer"; + } + } + } + return "type"; } @@ -245,6 +274,49 @@ const Type* GetStructReplacementType (const Type* SType) +long GetIntegerTypeMin (const Type* Type) +/* Get the smallest possible value of the integer type */ +{ + if (IsSignSigned (Type)) { + return (long)(0xFFFFFFFF << (CHAR_BITS * SizeOf (Type) - 1U)); + } else { + return 0; + } +} + + + +unsigned long GetIntegerTypeMax (const Type* Type) +/* Get the largest possible value of the integer type */ +{ + if (IsSignSigned (Type)) { + return (1UL << (CHAR_BITS * SizeOf (Type) - 1U)) - 1UL; + } else { + return (1UL << (CHAR_BITS * SizeOf (Type))) - 1UL; + } +} + + + +static unsigned TypeOfBySize (const Type* Type) +/* Get the code generator replacement type of the object by its size */ +{ + unsigned NewType; + /* If the size is less than or equal to that of a a long, we will copy + ** the struct using the primary register, otherwise we use memcpy. + */ + switch (SizeOf (Type)) { + case 1: NewType = CF_CHAR; break; + case 2: NewType = CF_INT; break; + case 3: /* FALLTHROUGH */ + case 4: NewType = CF_LONG; break; + default: NewType = CF_NONE; break; + } + + return NewType; +} + + Type* PointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. @@ -321,6 +393,9 @@ void PrintType (FILE* F, const Type* T) case T_TYPE_LONGLONG: fprintf (F, "long long"); break; + case T_TYPE_ENUM: + fprintf (F, "enum"); + break; case T_TYPE_FLOAT: fprintf (F, "float"); break; @@ -430,10 +505,68 @@ int TypeHasAttr (const Type* T) +const Type* GetUnderlyingType (const Type* Type) +/* Get the underlying type of an enum or other integer class type */ +{ + if (IsTypeEnum (Type)) { + + /* This should not happen, but just in case */ + if (Type->A.P == 0) { + Internal ("Enum tag type error in GetUnderlyingTypeCode"); + } + + return ((SymEntry*)Type->A.P)->V.E.Type; + } + + return Type; +} + + + +TypeCode GetUnderlyingTypeCode (const Type* Type) +/* Get the type code of the unqualified underlying type of TCode. +** Return UnqualifiedType (TCode) if TCode is not scalar. +*/ +{ + TypeCode Underlying = UnqualifiedType (Type->C); + TypeCode TCode; + + /* We could also support other T_CLASS_INT types, but just enums for now */ + if (IsTypeEnum (Type)) { + + /* This should not happen, but just in case */ + if (Type->A.P == 0) { + Internal ("Enum tag type error in GetUnderlyingTypeCode"); + } + + /* Inspect the underlying type of the enum */ + if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + /* Incomplete enum type is used */ + return Underlying; + } + TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + + /* Replace the type code with integer */ + Underlying = (TCode & ~T_MASK_TYPE); + switch (TCode & T_MASK_SIZE) { + case T_SIZE_INT: Underlying |= T_TYPE_INT; break; + case T_SIZE_LONG: Underlying |= T_TYPE_LONG; break; + case T_SIZE_SHORT: Underlying |= T_TYPE_SHORT; break; + case T_SIZE_CHAR: Underlying |= T_TYPE_CHAR; break; + case T_SIZE_LONGLONG: Underlying |= T_TYPE_LONGLONG; break; + default: Underlying |= T_TYPE_INT; break; + } + } + + return Underlying; +} + + + unsigned SizeOf (const Type* T) /* Compute size of object represented by type array. */ { - switch (UnqualifiedType (T->C)) { + switch (GetUnderlyingTypeCode (T)) { case T_VOID: /* A void variable is a cc65 extension. @@ -470,9 +603,6 @@ unsigned SizeOf (const Type* T) case T_ULONGLONG: return SIZEOF_LONGLONG; - case T_ENUM: - return SIZEOF_INT; - case T_FLOAT: return SIZEOF_FLOAT; @@ -491,7 +621,12 @@ unsigned SizeOf (const Type* T) return T->A.U * SizeOf (T + 1); } + case T_ENUM: + /* Incomplete enum type */ + return 0; + default: + Internal ("Unknown type in SizeOf: %04lX", T->C); return 0; @@ -547,7 +682,9 @@ unsigned CheckedPSizeOf (const Type* T) unsigned TypeOf (const Type* T) /* Get the code generator base type of the object */ { - switch (UnqualifiedType (T->C)) { + unsigned NewType; + + switch (GetUnderlyingTypeCode (T)) { case T_SCHAR: return CF_CHAR; @@ -557,7 +694,6 @@ unsigned TypeOf (const Type* T) case T_SHORT: case T_INT: - case T_ENUM: return CF_INT; case T_USHORT: @@ -582,6 +718,10 @@ unsigned TypeOf (const Type* T) case T_STRUCT: case T_UNION: + NewType = TypeOfBySize (T); + if (NewType != CF_NONE) { + return NewType; + } /* Address of ... */ return CF_INT | CF_UNSIGNED; @@ -726,8 +866,8 @@ Type* GetBaseElementType (Type* T) SymEntry* GetSymEntry (const Type* T) /* Return a SymEntry pointer from a type */ { - /* Only structs or unions have a SymEntry attribute */ - CHECK (IsClassStruct (T)); + /* Only enums, structs or unions have a SymEntry attribute */ + CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ return T->A.P; @@ -738,8 +878,8 @@ SymEntry* GetSymEntry (const Type* T) void SetSymEntry (Type* T, SymEntry* S) /* Set the SymEntry pointer for a type */ { - /* Only structs or unions have a SymEntry attribute */ - CHECK (IsClassStruct (T)); + /* Only enums, structs or unions have a SymEntry attribute */ + CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ T->A.P = S; diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 3464e8a16..361f5e0a6 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -96,37 +96,39 @@ enum { /* Type size modifiers */ T_SIZE_NONE = 0x000000, - T_SIZE_SHORT = 0x000200, - T_SIZE_LONG = 0x000400, - T_SIZE_LONGLONG = 0x000600, - T_MASK_SIZE = 0x000600, + T_SIZE_CHAR = 0x000200, + T_SIZE_SHORT = 0x000400, + T_SIZE_INT = 0x000600, + T_SIZE_LONG = 0x000800, + T_SIZE_LONGLONG = 0x000A00, + T_MASK_SIZE = 0x000E00, /* Type qualifiers */ T_QUAL_NONE = 0x000000, - T_QUAL_CONST = 0x000800, - T_QUAL_VOLATILE = 0x001000, - T_QUAL_RESTRICT = 0x002000, - T_QUAL_NEAR = 0x004000, - T_QUAL_FAR = 0x008000, + T_QUAL_CONST = 0x001000, + T_QUAL_VOLATILE = 0x002000, + T_QUAL_RESTRICT = 0x004000, + T_QUAL_NEAR = 0x008000, + T_QUAL_FAR = 0x010000, T_QUAL_ADDRSIZE = T_QUAL_NEAR | T_QUAL_FAR, - T_QUAL_FASTCALL = 0x010000, - T_QUAL_CDECL = 0x020000, + T_QUAL_FASTCALL = 0x020000, + T_QUAL_CDECL = 0x040000, T_QUAL_CCONV = T_QUAL_FASTCALL | T_QUAL_CDECL, - T_MASK_QUAL = 0x03F800, + T_MASK_QUAL = 0x07F000, /* Types */ - T_CHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_NONE, - T_SCHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_NONE, - T_UCHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_NONE, + T_CHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_CHAR, + T_SCHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_CHAR, + T_UCHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_CHAR, T_SHORT = T_TYPE_SHORT | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_SHORT, T_USHORT = T_TYPE_SHORT | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_SHORT, - T_INT = T_TYPE_INT | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_NONE, - T_UINT = T_TYPE_INT | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_NONE, + T_INT = T_TYPE_INT | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_INT, + T_UINT = T_TYPE_INT | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_INT, T_LONG = T_TYPE_LONG | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_LONG, T_ULONG = T_TYPE_LONG | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_LONG, T_LONGLONG = T_TYPE_LONGLONG | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_LONGLONG, T_ULONGLONG = T_TYPE_LONGLONG | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_LONGLONG, - T_ENUM = T_TYPE_ENUM | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_NONE, + T_ENUM = T_TYPE_ENUM | T_CLASS_INT | T_SIGN_NONE | T_SIZE_NONE, T_FLOAT = T_TYPE_FLOAT | T_CLASS_FLOAT | T_SIGN_NONE | T_SIZE_NONE, T_DOUBLE = T_TYPE_DOUBLE | T_CLASS_FLOAT | T_SIGN_NONE | T_SIZE_NONE, T_VOID = T_TYPE_VOID | T_CLASS_NONE | T_SIGN_NONE | T_SIZE_NONE, @@ -246,6 +248,12 @@ Type* GetImplicitFuncType (void); const Type* GetStructReplacementType (const Type* SType); /* Get a replacement type for passing a struct/union in the primary register */ +long GetIntegerTypeMin (const Type* Type); +/* Get the smallest possible value of the integer type */ + +unsigned long GetIntegerTypeMax (const Type* Type); +/* Get the largest possible value of the integer type */ + Type* PointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. @@ -283,6 +291,14 @@ INLINE TypeCode UnqualifiedType (TypeCode T) # define UnqualifiedType(T) ((T) & ~T_MASK_QUAL) #endif +const Type* GetUnderlyingType (const Type* Type); +/* Get the underlying type of an enum or other integer class type */ + +TypeCode GetUnderlyingTypeCode (const Type* Type); +/* Get the type code of the unqualified underlying type of TCode. +** Return TCode if it is not scalar. +*/ + unsigned SizeOf (const Type* T); /* Compute size of object represented by type array. */ @@ -312,123 +328,163 @@ Type* ArrayToPtr (Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) -INLINE TypeCode GetType (const Type* T) +INLINE TypeCode GetRawType (const Type* T) /* Get the raw type */ { return (T->C & T_MASK_TYPE); } #else -# define GetType(T) ((T)->C & T_MASK_TYPE) +# define GetRawType(T) ((T)->C & T_MASK_TYPE) #endif #if defined(HAVE_INLINE) INLINE int IsTypeChar (const Type* T) /* Return true if this is a character type */ { - return (GetType (T) == T_TYPE_CHAR); + return (GetRawType (GetUnderlyingType (T)) == T_TYPE_CHAR); } #else -# define IsTypeChar(T) (GetType (T) == T_TYPE_CHAR) +# define IsTypeChar(T) (GetRawType (GetUnderlyingType (T)) == T_TYPE_CHAR) #endif #if defined(HAVE_INLINE) INLINE int IsTypeInt (const Type* T) /* Return true if this is an int type (signed or unsigned) */ { - return (GetType (T) == T_TYPE_INT); + return (GetRawType (GetUnderlyingType (T)) == T_TYPE_INT); } #else -# define IsTypeInt(T) (GetType (T) == T_TYPE_INT) +# define IsTypeInt(T) (GetRawType (GetUnderlyingType (T)) == T_TYPE_INT) #endif #if defined(HAVE_INLINE) INLINE int IsTypeLong (const Type* T) /* Return true if this is a long type (signed or unsigned) */ { - return (GetType (T) == T_TYPE_LONG); + return (GetRawType (GetUnderlyingType (T)) == T_TYPE_LONG); } #else -# define IsTypeLong(T) (GetType (T) == T_TYPE_LONG) +# define IsTypeLong(T) (GetRawType (GetUnderlyingType (T)) == T_TYPE_LONG) +#endif + +#if defined(HAVE_INLINE) +INLINE int IsRawTypeChar (const Type* T) +/* Return true if this is a character raw type */ +{ + return (GetRawType (T) == T_TYPE_CHAR); +} +#else +# define IsRawTypeChar(T) (GetRawType (T) == T_TYPE_CHAR) +#endif + +#if defined(HAVE_INLINE) +INLINE int IsRawTypeInt (const Type* T) +/* Return true if this is an int raw type (signed or unsigned) */ +{ + return (GetRawType (T) == T_TYPE_INT); +} +#else +# define IsRawTypeInt(T) (GetRawType (T) == T_TYPE_INT) +#endif + +#if defined(HAVE_INLINE) +INLINE int IsRawTypeLong (const Type* T) +/* Return true if this is a long raw type (signed or unsigned) */ +{ + return (GetRawType (T) == T_TYPE_LONG); +} +#else +# define IsRawTypeLong(T) (GetRawType (T) == T_TYPE_LONG) #endif #if defined(HAVE_INLINE) INLINE int IsTypeFloat (const Type* T) /* Return true if this is a float type */ { - return (GetType (T) == T_TYPE_FLOAT); + return (GetRawType (T) == T_TYPE_FLOAT); } #else -# define IsTypeFloat(T) (GetType (T) == T_TYPE_FLOAT) +# define IsTypeFloat(T) (GetRawType (T) == T_TYPE_FLOAT) #endif #if defined(HAVE_INLINE) INLINE int IsTypeDouble (const Type* T) /* Return true if this is a double type */ { - return (GetType (T) == T_TYPE_DOUBLE); + return (GetRawType (T) == T_TYPE_DOUBLE); } #else -# define IsTypeDouble(T) (GetType (T) == T_TYPE_DOUBLE) +# define IsTypeDouble(T) (GetRawType (T) == T_TYPE_DOUBLE) #endif #if defined(HAVE_INLINE) INLINE int IsTypePtr (const Type* T) /* Return true if this is a pointer type */ { - return (GetType (T) == T_TYPE_PTR); + return (GetRawType (T) == T_TYPE_PTR); } #else -# define IsTypePtr(T) (GetType (T) == T_TYPE_PTR) +# define IsTypePtr(T) (GetRawType (T) == T_TYPE_PTR) +#endif + +#if defined(HAVE_INLINE) +INLINE int IsTypeEnum (const Type* T) +/* Return true if this is an enum type */ +{ + return (GetRawType (T) == T_TYPE_ENUM); +} +#else +# define IsTypeEnum(T) (GetRawType (T) == T_TYPE_ENUM) #endif #if defined(HAVE_INLINE) INLINE int IsTypeStruct (const Type* T) /* Return true if this is a struct type */ { - return (GetType (T) == T_TYPE_STRUCT); + return (GetRawType (T) == T_TYPE_STRUCT); } #else -# define IsTypeStruct(T) (GetType (T) == T_TYPE_STRUCT) +# define IsTypeStruct(T) (GetRawType (T) == T_TYPE_STRUCT) #endif #if defined(HAVE_INLINE) INLINE int IsTypeUnion (const Type* T) /* Return true if this is a union type */ { - return (GetType (T) == T_TYPE_UNION); + return (GetRawType (T) == T_TYPE_UNION); } #else -# define IsTypeUnion(T) (GetType (T) == T_TYPE_UNION) +# define IsTypeUnion(T) (GetRawType (T) == T_TYPE_UNION) #endif #if defined(HAVE_INLINE) INLINE int IsTypeArray (const Type* T) /* Return true if this is an array type */ { - return (GetType (T) == T_TYPE_ARRAY); + return (GetRawType (T) == T_TYPE_ARRAY); } #else -# define IsTypeArray(T) (GetType (T) == T_TYPE_ARRAY) +# define IsTypeArray(T) (GetRawType (T) == T_TYPE_ARRAY) #endif #if defined(HAVE_INLINE) INLINE int IsTypeVoid (const Type* T) /* Return true if this is a void type */ { - return (GetType (T) == T_TYPE_VOID); + return (GetRawType (T) == T_TYPE_VOID); } #else -# define IsTypeVoid(T) (GetType (T) == T_TYPE_VOID) +# define IsTypeVoid(T) (GetRawType (T) == T_TYPE_VOID) #endif #if defined(HAVE_INLINE) INLINE int IsTypeFunc (const Type* T) /* Return true if this is a function class */ { - return (GetType (T) == T_TYPE_FUNC); + return (GetRawType (T) == T_TYPE_FUNC); } #else -# define IsTypeFunc(T) (GetType (T) == T_TYPE_FUNC) +# define IsTypeFunc(T) (GetRawType (T) == T_TYPE_FUNC) #endif #if defined(HAVE_INLINE) @@ -502,13 +558,23 @@ INLINE int IsClassFunc (const Type* T) #endif #if defined(HAVE_INLINE) -INLINE TypeCode GetSignedness (const Type* T) -/* Get the sign of a type */ +INLINE TypeCode GetRawSignedness (const Type* T) +/* Get the raw signedness of a type */ { - return (T->C & T_MASK_SIGN); + return ((T)->C & T_MASK_SIGN); } #else -# define GetSignedness(T) ((T)->C & T_MASK_SIGN) +# define GetRawSignedness(T) ((T)->C & T_MASK_SIGN) +#endif + +#if defined(HAVE_INLINE) +INLINE TypeCode GetSignedness (const Type* T) +/* Get the signedness of a type */ +{ + return (GetUnderlyingTypeCode (T) & T_MASK_SIGN); +} +#else +# define GetSignedness(T) (GetUnderlyingTypeCode (T) & T_MASK_SIGN) #endif #if defined(HAVE_INLINE) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 323e9af14..734256b97 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -453,27 +453,99 @@ static void ParseStorageClass (DeclSpec* D, unsigned DefStorage) -static void ParseEnumDecl (void) -/* Process an enum declaration . */ +static SymEntry* ESUForwardDecl (const char* Name, unsigned Type) +/* Handle an enum, struct or union forward decl */ { - int EnumVal; - ident Ident; + /* Try to find an enum/struct/union with the given name. If there is none, + ** insert a forward declaration into the current lexical level. + */ + SymEntry* Entry = FindTagSym (Name); + if (Entry == 0) { + if (Type != SC_ENUM) { + Entry = AddStructSym (Name, Type, 0, 0); + } else { + Entry = AddEnumSym (Name, 0, 0); + } + } else if ((Entry->Flags & SC_TYPEMASK) != Type) { + /* Already defined, but not the same type class */ + Error ("Symbol '%s' is already different kind", Name); + } + return Entry; +} + + + +static const Type* GetEnumeratorType (long Min, unsigned long Max, int Signed) +/* GitHub #1093 - We use unsigned types to save spaces whenever possible. +** If both the signed and unsigned integer types of the same minimum size +** capable of representing all values of the enum, we prefer the unsigned +** one. +** Return 0 if impossible to represent Min and Max as the same integer type. +*/ +{ + const Type* Underlying = type_int; /* default type */ + + /* Change the underlying type if necessary */ + if (Min < 0 || Signed) { + /* We can't use unsigned types if there are any negative values */ + if (Max > (unsigned long)INT32_MAX) { + /* No way to represent both Min and Max as the same integer type */ + Underlying = 0; + } else if (Min < INT16_MIN || Max > (unsigned long)INT16_MAX) { + Underlying = type_long; + } else if (Min < INT8_MIN || Max > (unsigned long)INT8_MAX) { + Underlying = type_int; + } else { + Underlying = type_schar; + } + } else { + if (Max > UINT16_MAX) { + Underlying = type_ulong; + } else if (Max > UINT8_MAX) { + Underlying = type_uint; + } else { + Underlying = type_uchar; + } + } + + return Underlying; +} + + + +static SymEntry* ParseEnumDecl (const char* Name) +/* Process an enum declaration */ +{ + SymTable* FieldTab; + long EnumVal; + int IsSigned; + int IsIncremented; + ident Ident; + long MinConstant = 0; + unsigned long MaxConstant = 0; + const Type* NewType = type_int; /* new enumerator type */ + const Type* MemberType = type_int; /* default enumerator type */ /* Accept forward definitions */ if (CurTok.Tok != TOK_LCURLY) { - return; + return ESUForwardDecl (Name, SC_ENUM); } + /* Add the enum tag */ + AddEnumSym (Name, 0, 0); + /* Skip the opening curly brace */ NextToken (); /* Read the enum tags */ - EnumVal = 0; + EnumVal = -1L; while (CurTok.Tok != TOK_RCURLY) { /* We expect an identifier */ if (CurTok.Tok != TOK_IDENT) { - Error ("Identifier expected"); + Error ("Identifier expected for enumerator declarator"); + /* Avoid excessive errors */ + NextToken (); continue; } @@ -483,21 +555,116 @@ static void ParseEnumDecl (void) /* Check for an assigned value */ if (CurTok.Tok == TOK_ASSIGN) { + ExprDesc Expr; NextToken (); ConstAbsIntExpr (hie1, &Expr); - EnumVal = Expr.IVal; + EnumVal = Expr.IVal; + MemberType = Expr.Type; + IsSigned = IsSignSigned (MemberType); + IsIncremented = 0; + + } else { + + /* Defaulted with the same signedness as the previous member's */ + IsSigned = IsSignSigned (MemberType) && + (unsigned long)EnumVal != GetIntegerTypeMax (MemberType); + + /* Enumerate. Signed integer overflow is UB but unsigned integers + ** are guaranteed to wrap around. + */ + EnumVal = (long)((unsigned long)EnumVal + 1UL); + + if (UnqualifiedType (MemberType->C) == T_ULONG && EnumVal == 0) { + /* Warn on 'unsigned long' overflow in enumeration */ + Warning ("Enumerator '%s' overflows the range of '%s'", + Ident, + GetBasicTypeName (type_ulong)); + } + + IsIncremented = 1; } - /* Add an entry to the symbol table */ - AddConstSym (Ident, type_int, SC_ENUMERATOR | SC_CONST, EnumVal++); + /* Track down the min/max values and evaluate the type of EnumVal + ** using GetEnumeratorType in a tricky way. + */ + if (!IsSigned || EnumVal >= 0) { + if ((unsigned long)EnumVal > MaxConstant) { + MaxConstant = (unsigned long)EnumVal; + } + NewType = GetEnumeratorType (0, EnumVal, IsSigned); + } else { + if (EnumVal < MinConstant) { + MinConstant = EnumVal; + } + NewType = GetEnumeratorType (EnumVal, 0, 1); + } + + /* GetEnumeratorType above should never fail, but just in case */ + if (NewType == 0) { + Internal ("Unexpected failure with GetEnumeratorType: %lx", EnumVal); + NewType = type_ulong; + } else if (SizeOf (NewType) < SizeOf (type_int)) { + /* Integer constants are not shorter than int */ + NewType = type_int; + } + + /* Warn if the incremented value exceeds the range of the previous + ** type. + */ + if (IsIncremented && + EnumVal >= 0 && + NewType->C != UnqualifiedType (MemberType->C)) { + /* The possible overflow here can only be when EnumVal > 0 */ + Warning ("Enumerator '%s' (value = %lu) is of type '%s'", + Ident, + (unsigned long)EnumVal, + GetBasicTypeName (NewType)); + } + + /* Warn if the value exceeds range of 'int' in standard mode */ + if (IS_Get (&Standard) != STD_CC65 && NewType->C != T_INT) { + if (!IsSigned || EnumVal >= 0) { + Warning ("ISO C restricts enumerator values to range of 'int'\n" + "\tEnumerator '%s' (value = %lu) is too large", + Ident, + (unsigned long)EnumVal); + } else { + Warning ("ISO C restricts enumerator values to range of 'int'\n" + "\tEnumerator '%s' (value = %ld) is too small", + Ident, + EnumVal); + } + } + + /* Add an entry of the enumerator to the symbol table */ + AddConstSym (Ident, NewType, SC_ENUMERATOR | SC_CONST, EnumVal); + + /* Use this type for following members */ + MemberType = NewType; /* Check for end of definition */ - if (CurTok.Tok != TOK_COMMA) + if (CurTok.Tok != TOK_COMMA) { break; + } NextToken (); } ConsumeRCurly (); + + /* This evaluates the underlying type of the whole enum */ + MemberType = GetEnumeratorType (MinConstant, MaxConstant, 0); + if (MemberType == 0) { + /* It is very likely that the program is wrong */ + Error ("Enumeration values cannot be represented all as 'long'\n" + "\tMin enumerator value = %ld, Max enumerator value = %lu", + MinConstant, MaxConstant); + + /* Avoid more errors */ + MemberType = type_long; + } + + FieldTab = GetSymTab (); + return AddEnumSym (Name, MemberType, FieldTab); } @@ -541,24 +708,6 @@ static int ParseFieldWidth (Declaration* Decl) -static SymEntry* StructOrUnionForwardDecl (const char* Name, unsigned Type) -/* Handle a struct or union forward decl */ -{ - /* Try to find a struct/union with the given name. If there is none, - ** insert a forward declaration into the current lexical level. - */ - SymEntry* Entry = FindTagSym (Name); - if (Entry == 0) { - Entry = AddStructSym (Name, Type, 0, 0); - } else if ((Entry->Flags & SC_TYPEMASK) != Type) { - /* Already defined, but no struct */ - Error ("Symbol '%s' is already different kind", Name); - } - return Entry; -} - - - static unsigned CopyAnonStructFields (const Declaration* Decl, int Offs) /* Copy fields from an anon union/struct into the current lexical level. The ** function returns the size of the embedded struct/union. @@ -617,7 +766,7 @@ static SymEntry* ParseUnionDecl (const char* Name) if (CurTok.Tok != TOK_LCURLY) { /* Just a forward declaration. */ - return StructOrUnionForwardDecl (Name, SC_UNION); + return ESUForwardDecl (Name, SC_UNION); } /* Add a forward declaration for the struct in the current lexical level */ @@ -722,7 +871,7 @@ static SymEntry* ParseStructDecl (const char* Name) if (CurTok.Tok != TOK_LCURLY) { /* Just a forward declaration. */ - return StructOrUnionForwardDecl (Name, SC_STRUCT); + return ESUForwardDecl (Name, SC_STRUCT); } /* Add a forward declaration for the struct in the current lexical level */ @@ -1069,29 +1218,23 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers) case TOK_ENUM: NextToken (); - if (CurTok.Tok != TOK_LCURLY) { - /* Named enum */ - if (CurTok.Tok == TOK_IDENT) { - /* Find an entry with this name */ - Entry = FindTagSym (CurTok.Ident); - if (Entry) { - if (SymIsLocal (Entry) && (Entry->Flags & SC_ENUM) == 0) { - Error ("Symbol '%s' is already different kind", Entry->Name); - } - } else { - /* Insert entry into table ### */ - } - /* Skip the identifier */ - NextToken (); - } else { + /* Named enum */ + if (CurTok.Tok == TOK_IDENT) { + strcpy (Ident, CurTok.Ident); + NextToken (); + } else { + if (CurTok.Tok != TOK_LCURLY) { Error ("Identifier expected"); + } else { + AnonName (Ident, "enum"); } } /* Remember we have an extra type decl */ D->Flags |= DS_EXTRA_TYPE; /* Parse the enum decl */ - ParseEnumDecl (); - D->Type[0].C = T_INT; + Entry = ParseEnumDecl (Ident); + D->Type[0].C |= T_ENUM; + SetSymEntry (D->Type, Entry); D->Type[1].C = T_END; break; @@ -1624,7 +1767,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* The return type must not be qualified */ if (GetQualifier (RetType) != T_QUAL_NONE && RetType[1].C == T_END) { - if (GetType (RetType) == T_TYPE_VOID) { + if (GetRawType (RetType) == T_TYPE_VOID) { /* A qualified void type is always an error */ Error ("function definition has qualified void return type"); } else { @@ -1916,7 +2059,7 @@ static unsigned ParseArrayInit (Type* T, int AllowFlexibleMembers) long ElementCount = GetElementCount (T); /* Special handling for a character array initialized by a literal */ - if (IsTypeChar (ElementType) && + if (IsRawTypeChar (ElementType) && (CurTok.Tok == TOK_SCONST || CurTok.Tok == TOK_WCSCONST || (CurTok.Tok == TOK_LCURLY && (NextTok.Tok == TOK_SCONST || NextTok.Tok == TOK_WCSCONST)))) { @@ -2180,7 +2323,7 @@ static unsigned ParseVoidInit (Type* T) Size = 0; do { ConstExpr (hie1, &Expr); - switch (UnqualifiedType (Expr.Type[0].C)) { + switch (GetUnderlyingTypeCode (&Expr.Type[0])) { case T_SCHAR: case T_UCHAR: @@ -2244,7 +2387,7 @@ static unsigned ParseVoidInit (Type* T) static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers) /* Parse initialization of variables. Return the number of data bytes. */ { - switch (UnqualifiedType (T->C)) { + switch (GetUnderlyingTypeCode (T)) { case T_SCHAR: case T_UCHAR: diff --git a/src/cc65/function.c b/src/cc65/function.c index ff4c23656..d6e11fea3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -452,7 +452,7 @@ void NewFunc (SymEntry* Func) /* Determine if this is a main function in a C99 environment that ** returns an int. */ - if (IsTypeInt (F_GetReturnType (CurrentFunc)) && + if (IsRawTypeInt (F_GetReturnType (CurrentFunc)) && IS_Get (&Standard) == STD_C99) { C99MainFunc = 1; } diff --git a/src/cc65/swstmt.c b/src/cc65/swstmt.c index 4a3730283..8cab93bba 100644 --- a/src/cc65/swstmt.c +++ b/src/cc65/swstmt.c @@ -132,7 +132,7 @@ void SwitchStatement (void) /* Setup the control structure, save the old and activate the new one */ SwitchData.Nodes = NewCollection (); - SwitchData.ExprType = UnqualifiedType (SwitchExpr.Type[0].C); + SwitchData.ExprType = GetUnderlyingTypeCode (&SwitchExpr.Type[0]); SwitchData.Depth = SizeOf (SwitchExpr.Type); SwitchData.DefaultLabel = 0; OldSwitch = Switch; diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 13829e958..b030d8b8b 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -165,6 +165,12 @@ struct SymEntry { unsigned Size; /* Size of the union/struct */ } S; + /* Data for enums */ + struct { + struct SymTable* SymTab; /* Member symbol table */ + const Type* Type; /* Underlying type */ + } E; + /* Data for bit fields */ struct { unsigned Offs; /* Byte offset into struct */ diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 26a09cd87..87a33760b 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -551,6 +551,50 @@ static void AddSymEntry (SymTable* T, SymEntry* S) +SymEntry* AddEnumSym (const char* Name, const Type* Type, SymTable* Tab) +/* Add an enum entry and return it */ +{ + /* Do we have an entry with this name already? */ + SymEntry* Entry = FindSymInTable (TagTab, Name, HashStr (Name)); + if (Entry) { + + /* We do have an entry. This may be a forward, so check it. */ + if ((Entry->Flags & SC_TYPEMASK) != SC_ENUM) { + /* Existing symbol is not an enum */ + Error ("Symbol '%s' is already different kind", Name); + } else { + /* Define the struct size if the underlying type is given. */ + if (Type != 0) { + if (Type !=0 && Entry->V.E.Type != 0) { + /* Both are definitions. */ + Error ("Multiple definition for enum '%s'", Name); + } + Entry->Type = 0; + Entry->V.E.SymTab = Tab; + Entry->V.E.Type = Type; + } + } + + } else { + + /* Create a new entry */ + Entry = NewSymEntry (Name, SC_ENUM); + + /* Set the enum type data */ + Entry->Type = 0; + Entry->V.E.SymTab = Tab; + Entry->V.E.Type = Type; + + /* Add it to the current table */ + AddSymEntry (TagTab, Entry); + } + + /* Return the entry */ + return Entry; +} + + + SymEntry* AddStructSym (const char* Name, unsigned Type, unsigned Size, SymTable* Tab) /* Add a struct/union entry and return it */ { @@ -649,10 +693,10 @@ SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val /* Create a new entry */ Entry = NewSymEntry (Name, Flags); - /* Enum values are ints */ + /* We only have integer constants for now */ Entry->Type = TypeDup (T); - /* Set the enum data */ + /* Set the constant data */ Entry->V.ConstVal = Val; /* Add the entry to the symbol table */ diff --git a/src/cc65/symtab.h b/src/cc65/symtab.h index 94e5f2d9b..dd4b3aa37 100644 --- a/src/cc65/symtab.h +++ b/src/cc65/symtab.h @@ -146,6 +146,9 @@ unsigned short FindSPAdjustment (const char* Name); +SymEntry* AddEnumSym (const char* Name, const Type* Type, SymTable* Tab); +/* Add an enum entry and return it */ + SymEntry* AddStructSym (const char* Name, unsigned Type, unsigned Size, SymTable* Tab); /* Add a struct/union entry and return it */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 673dfa163..af04d8232 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -214,9 +214,9 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) return; } - /* Get the raw left and right types, signs and qualifiers */ - LeftType = GetType (lhs); - RightType = GetType (rhs); + /* Get the left and right types, signs and qualifiers */ + LeftType = GetUnderlyingTypeCode (lhs); + RightType = GetUnderlyingTypeCode (rhs); LeftSign = GetSignedness (lhs); RightSign = GetSignedness (rhs); LeftQual = GetQualifier (lhs); @@ -229,7 +229,7 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) RightType = T_TYPE_PTR; } - /* If the raw types are not identical, the types are incompatible */ + /* If the underlying types are not identical, the types are incompatible */ if (LeftType != RightType) { SetResult (Result, TC_INCOMPATIBLE); return; From d8184fbe543d2e72538e6af179f900098bc19ce6 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 26 Jul 2020 20:12:59 +0800 Subject: [PATCH 1487/2161] No longer insert all enums in the global symbol table. --- src/cc65/symtab.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 87a33760b..4169e6280 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -676,11 +676,8 @@ SymEntry* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsign SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val) /* Add an constant symbol to the symbol table and return it */ { - /* Enums must be inserted in the global symbol table */ - SymTable* Tab = ((Flags & SC_ENUMERATOR) == SC_ENUMERATOR) ? SymTab0 : SymTab; - /* Do we have an entry with this name already? */ - SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name)); + SymEntry* Entry = FindSymInTable (SymTab, Name, HashStr (Name)); if (Entry) { if ((Entry->Flags & SC_CONST) != SC_CONST) { Error ("Symbol '%s' is already different kind", Name); @@ -700,7 +697,7 @@ SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val Entry->V.ConstVal = Val; /* Add the entry to the symbol table */ - AddSymEntry (Tab, Entry); + AddSymEntry (SymTab, Entry); /* Return the entry */ return Entry; From 7e243e0f2c8d4b210cd6d6b43d8914587f631d1f Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 26 Jul 2020 20:12:59 +0800 Subject: [PATCH 1488/2161] Allowed using all integer types including enum and char types to define bit-fields, but kept the currently behavior that all of them are treated as unsigned int. --- src/cc65/declare.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 734256b97..49e233a56 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -684,21 +684,31 @@ static int ParseFieldWidth (Declaration* Decl) /* Read the width */ NextToken (); ConstAbsIntExpr (hie1, &Expr); + if (!IsClassInt (Decl->Type)) { + /* Only integer types may be used for bit-fields */ + Error ("Bit-field has invalid type ''"); + return -1; + } if (Expr.IVal < 0) { Error ("Negative width in bit-field"); return -1; } - if (Expr.IVal > (int) INT_BITS) { + /* FIXME: We should compare with the width of the specified type */ +#if 0 + /* Use is when we really support non-uint16_t bit-fields */ + if (Expr.IVal > (long)(SizeOf (Decl->Type) * CHAR_BITS)) { Error ("Width of bit-field exceeds its type"); return -1; } - if (Expr.IVal == 0 && Decl->Ident[0] != '\0') { - Error ("Zero width for named bit-field"); +#else + /* This is what we currenty do */ + if (Expr.IVal > (long)(SizeOf (type_uint) * CHAR_BITS)) { + Error ("Width of bit-field exceeds 16"); return -1; } - if (!IsTypeInt (Decl->Type)) { - /* Only integer types may be used for bit-fields */ - Error ("Bit-field has invalid type"); +#endif + if (Expr.IVal == 0 && Decl->Ident[0] != '\0') { + Error ("Zero width for named bit-field"); return -1; } From 35e1efc7f2576bc579cb27a187d1a35aadbbe85b Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 26 Jul 2020 20:40:27 +0800 Subject: [PATCH 1489/2161] Moved misc/bug1048 as it is already correctly rejected by the compiler. --- test/{misc => err}/bug1048.c | 0 test/misc/Makefile | 6 ------ 2 files changed, 6 deletions(-) rename test/{misc => err}/bug1048.c (100%) diff --git a/test/misc/bug1048.c b/test/err/bug1048.c similarity index 100% rename from test/misc/bug1048.c rename to test/err/bug1048.c diff --git a/test/misc/Makefile b/test/misc/Makefile index 9045e4e4f..3c5045753 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -87,12 +87,6 @@ $(WORKDIR)/bug264.$1.$2.prg: bug264.c | $(WORKDIR) $(if $(QUIET),echo misc/bug264.$1.$2.prg) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) -# this should fail to compile, because there are errors in the code -$(WORKDIR)/bug1048.$1.$2.prg: bug1048.c | $(WORKDIR) - @echo "FIXME: " $$@ "compiles but should give an error." - $(if $(QUIET),echo misc/bug1048.$1.$2.prg) - $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - # this should fail to compile, because there are errors in the code $(WORKDIR)/bug1098.$1.$2.prg: bug1098.c | $(WORKDIR) @echo "FIXME: " $$@ "compiles but should give an error." From 0f412b6beb1319255834b7062c000a1295140e4b Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 27 Jul 2020 18:25:28 +0800 Subject: [PATCH 1490/2161] Small fixes according to PR review. --- src/cc65/datatype.c | 10 ++++++++-- src/cc65/declare.c | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 3f2725659..4da9a8727 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -278,7 +278,8 @@ long GetIntegerTypeMin (const Type* Type) /* Get the smallest possible value of the integer type */ { if (IsSignSigned (Type)) { - return (long)(0xFFFFFFFF << (CHAR_BITS * SizeOf (Type) - 1U)); + /* The smallest possible signed value of N-byte integer is -pow(2, 8*N-1) */ + return (long)((unsigned long)(-1L) << (CHAR_BITS * SizeOf (Type) - 1U)); } else { return 0; } @@ -290,9 +291,14 @@ unsigned long GetIntegerTypeMax (const Type* Type) /* Get the largest possible value of the integer type */ { if (IsSignSigned (Type)) { + /* Min signed value of N-byte integer is pow(2, 8*N-1) - 1 */ return (1UL << (CHAR_BITS * SizeOf (Type) - 1U)) - 1UL; } else { - return (1UL << (CHAR_BITS * SizeOf (Type))) - 1UL; + /* Max signed value of N-byte integer is pow(2, 8*N) - 1. However, + ** workaround is needed as in ISO C it is UB if the shift count is + ** equal to the bit width of the left operand type. + */ + return (1UL << 1U << (CHAR_BITS * SizeOf (Type) - 1U)) - 1UL; } } diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 49e233a56..ba4091c3b 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -686,7 +686,7 @@ static int ParseFieldWidth (Declaration* Decl) ConstAbsIntExpr (hie1, &Expr); if (!IsClassInt (Decl->Type)) { /* Only integer types may be used for bit-fields */ - Error ("Bit-field has invalid type ''"); + Error ("Bit-field has invalid type '%s'", GetBasicTypeName (Decl->Type)); return -1; } if (Expr.IVal < 0) { From c37f9f1a41f9e6ab853cfbac7438cf5f41fb91f8 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 27 Jul 2020 19:20:07 +0800 Subject: [PATCH 1491/2161] Check if the integer size is known in GetIntegerTypeMin/Max() to prevent potential misuse. --- src/cc65/datatype.c | 16 ++++++++++++++-- src/cc65/datatype.h | 8 ++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 4da9a8727..1e2859ba7 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -275,8 +275,14 @@ const Type* GetStructReplacementType (const Type* SType) long GetIntegerTypeMin (const Type* Type) -/* Get the smallest possible value of the integer type */ +/* Get the smallest possible value of the integer type. +** The type must have a known size. +*/ { + if (SizeOf (Type) == 0) { + Internal ("Incomplete type used in GetIntegerTypeMin"); + } + if (IsSignSigned (Type)) { /* The smallest possible signed value of N-byte integer is -pow(2, 8*N-1) */ return (long)((unsigned long)(-1L) << (CHAR_BITS * SizeOf (Type) - 1U)); @@ -288,8 +294,14 @@ long GetIntegerTypeMin (const Type* Type) unsigned long GetIntegerTypeMax (const Type* Type) -/* Get the largest possible value of the integer type */ +/* Get the largest possible value of the integer type. +** The type must have a known size. +*/ { + if (SizeOf (Type) == 0) { + Internal ("Incomplete type used in GetIntegerTypeMax"); + } + if (IsSignSigned (Type)) { /* Min signed value of N-byte integer is pow(2, 8*N-1) - 1 */ return (1UL << (CHAR_BITS * SizeOf (Type) - 1U)) - 1UL; diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 361f5e0a6..2f2ed136e 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -249,10 +249,14 @@ const Type* GetStructReplacementType (const Type* SType); /* Get a replacement type for passing a struct/union in the primary register */ long GetIntegerTypeMin (const Type* Type); -/* Get the smallest possible value of the integer type */ +/* Get the smallest possible value of the integer type. +** The type must have a known size. +*/ unsigned long GetIntegerTypeMax (const Type* Type); -/* Get the largest possible value of the integer type */ +/* Get the largest possible value of the integer type. +** The type must have a known size. +*/ Type* PointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated From cbb33f86e85d82f3ebe22c486e9b1bbcacb584d9 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 28 Jul 2020 11:17:17 +0800 Subject: [PATCH 1492/2161] Disabled using non-int-size types to declare bit-fields. --- src/cc65/datatype.h | 30 ++++++++++++++++++++---------- src/cc65/declare.c | 7 +++++++ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 2f2ed136e..1997b5c89 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -601,6 +601,26 @@ INLINE int IsSignSigned (const Type* T) # define IsSignSigned(T) (GetSignedness (T) == T_SIGN_SIGNED) #endif +#if defined(HAVE_INLINE) +INLINE TypeCode GetRawSizeModifier(const Type* T) +/* Get the size modifier of a raw type */ +{ + return (T->C & T_MASK_SIZE); +} +#else +# define GetRawSizeModifier(T) ((T)->C & T_MASK_SIZE) +#endif + +#if defined(HAVE_INLINE) +INLINE TypeCode GetSizeModifier (const Type* T) +/* Get the size modifier of a type */ +{ + return (GetUnderlyingTypeCode (T) & T_MASK_SIZE); +} +#else +# define GetSizeModifier(T) (GetUnderlyingTypeCode (T) & T_MASK_SIZE) +#endif + #if defined(HAVE_INLINE) INLINE TypeCode GetQualifier (const Type* T) /* Get the qualifier from the given type string */ @@ -696,16 +716,6 @@ int IsVariadicFunc (const Type* T) attribute ((const)); ** variable parameter list */ -#if defined(HAVE_INLINE) -INLINE TypeCode GetSizeModifier (const Type* T) -/* Get the size modifier of a type */ -{ - return (T->C & T_MASK_SIZE); -} -#else -# define GetSizeModifier(T) ((T)->C & T_MASK_SIZE) -#endif - FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); /* Get the FuncDesc pointer from a function or pointer-to-function type */ diff --git a/src/cc65/declare.c b/src/cc65/declare.c index ba4091c3b..cb3aa0ab3 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -689,6 +689,13 @@ static int ParseFieldWidth (Declaration* Decl) Error ("Bit-field has invalid type '%s'", GetBasicTypeName (Decl->Type)); return -1; } + + if (SizeOf (Decl->Type) != SizeOf (type_uint)) { + /* Only int sized types may be used for bit-fields for now */ + Error ("CC65 currently only supports unsigned int bit-fields"); + return -1; + } + if (Expr.IVal < 0) { Error ("Negative width in bit-field"); return -1; From 8eab28012a36516bab4682cd1797193fe721d51a Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 28 Jul 2020 23:29:16 +0200 Subject: [PATCH 1493/2161] Adjusted project name. --- src/cc65/declare.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index cb3aa0ab3..48db64e61 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -692,7 +692,7 @@ static int ParseFieldWidth (Declaration* Decl) if (SizeOf (Decl->Type) != SizeOf (type_uint)) { /* Only int sized types may be used for bit-fields for now */ - Error ("CC65 currently only supports unsigned int bit-fields"); + Error ("cc65 currently only supports unsigned int bit-fields"); return -1; } From 74dda01919dd1f84c1fcbd9ebb808312976de83a Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Wed, 29 Jul 2020 13:32:26 +0200 Subject: [PATCH 1494/2161] Add test that plain int bitfields are unsigned We want to make sure this doesn't change when #1095 is fixed; unsigned is much more efficient. --- test/val/plain-int-bitfield.c | 63 +++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 test/val/plain-int-bitfield.c diff --git a/test/val/plain-int-bitfield.c b/test/val/plain-int-bitfield.c new file mode 100644 index 000000000..afc7121bb --- /dev/null +++ b/test/val/plain-int-bitfield.c @@ -0,0 +1,63 @@ +/* + Copyright 2020 Google LLC + + 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. +*/ + +/* + Tests that plain int bit-fields are unsigned. +*/ + +#include <stdio.h> + +static unsigned char failures = 0; + +static struct plain_ints { + int x : 4; + int y : 10; +} pi = {15, 700}; + +static void test_plain_int_bitfields (void) +{ + if (pi.x != 15) { + printf ("Got pi.x = %u, expected 15.\n", pi.x); + failures++; + } + if (pi.y != 700) { + printf ("Got pi.y = %u, expected 700.\n", pi.y); + failures++; + } + + pi.x = 3; + pi.y = 1023; + + if (pi.x != 3) { + printf ("Got pi.x = %u, expected 3.\n", pi.x); + failures++; + } + if (pi.y != 1023) { + printf ("Got pi.y = %u, expected 1023.\n", pi.y); + failures++; + } +} + +int main (void) +{ + test_plain_int_bitfields (); + printf ("failures: %u\n", failures); + return failures; +} From a2561d07f3b6c07de0db312ed32d26c01b429d89 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Wed, 29 Jul 2020 14:04:52 +0200 Subject: [PATCH 1495/2161] Remove special-case bit-field width code cbb33f8 restricted allowed bit-field types to int, so this is equivalent for now, but forward-compatible. Fixes FIXME Also move the int type check before parsing the colon. --- src/cc65/declare.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 48db64e61..b8ad09cfd 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -681,14 +681,16 @@ static int ParseFieldWidth (Declaration* Decl) return -1; } + if (!IsClassInt (Decl->Type)) { + /* Only integer types may be used for bit-fields */ + Error ("Bit-field has invalid type '%s', must be integral", + GetBasicTypeName (Decl->Type)); + return -1; + } + /* Read the width */ NextToken (); ConstAbsIntExpr (hie1, &Expr); - if (!IsClassInt (Decl->Type)) { - /* Only integer types may be used for bit-fields */ - Error ("Bit-field has invalid type '%s'", GetBasicTypeName (Decl->Type)); - return -1; - } if (SizeOf (Decl->Type) != SizeOf (type_uint)) { /* Only int sized types may be used for bit-fields for now */ @@ -700,20 +702,10 @@ static int ParseFieldWidth (Declaration* Decl) Error ("Negative width in bit-field"); return -1; } - /* FIXME: We should compare with the width of the specified type */ -#if 0 - /* Use is when we really support non-uint16_t bit-fields */ if (Expr.IVal > (long)(SizeOf (Decl->Type) * CHAR_BITS)) { Error ("Width of bit-field exceeds its type"); return -1; } -#else - /* This is what we currenty do */ - if (Expr.IVal > (long)(SizeOf (type_uint) * CHAR_BITS)) { - Error ("Width of bit-field exceeds 16"); - return -1; - } -#endif if (Expr.IVal == 0 && Decl->Ident[0] != '\0') { Error ("Zero width for named bit-field"); return -1; From aaa0cf5448fc55e5b2bb925d0ac41779d8b50b56 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Wed, 29 Jul 2020 22:41:46 +0200 Subject: [PATCH 1496/2161] Add err tests for bitfield width errors ! ../../bin/cc65 -o ../../testwrk/err/bitfield-named-zero-width.s bitfield-named-zero-width.c bitfield-named-zero-width.c(27): Error: Zero width for named bit-field ! ../../bin/cc65 -o ../../testwrk/err/bitfield-negative-width.s bitfield-negative-width.c bitfield-negative-width.c(26): Error: Negative width in bit-field ! ../../bin/cc65 -o ../../testwrk/err/bitfield-too-wide.s bitfield-too-wide.c bitfield-too-wide.c(26): Error: Width of bit-field exceeds its type --- test/err/bitfield-named-zero-width.c | 29 ++++++++++++++++++++++++++++ test/err/bitfield-negative-width.c | 27 ++++++++++++++++++++++++++ test/err/bitfield-too-wide.c | 27 ++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 test/err/bitfield-named-zero-width.c create mode 100644 test/err/bitfield-negative-width.c create mode 100644 test/err/bitfield-too-wide.c diff --git a/test/err/bitfield-named-zero-width.c b/test/err/bitfield-named-zero-width.c new file mode 100644 index 000000000..b9b9db88d --- /dev/null +++ b/test/err/bitfield-named-zero-width.c @@ -0,0 +1,29 @@ +/* + Copyright 2020 Google LLC + + 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 bit-field with zero-width named field +*/ + +struct s { + unsigned int x : 4; + unsigned int y : 0; + unsigned int z : 4; +}; diff --git a/test/err/bitfield-negative-width.c b/test/err/bitfield-negative-width.c new file mode 100644 index 000000000..dd83b3fc4 --- /dev/null +++ b/test/err/bitfield-negative-width.c @@ -0,0 +1,27 @@ +/* + Copyright 2020 Google LLC + + 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 bit-field with negative width. +*/ + +struct s { + unsigned int x : -1; +}; diff --git a/test/err/bitfield-too-wide.c b/test/err/bitfield-too-wide.c new file mode 100644 index 000000000..6c9c229fc --- /dev/null +++ b/test/err/bitfield-too-wide.c @@ -0,0 +1,27 @@ +/* + Copyright 2020 Google LLC + + 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 bit-field with too large width. +*/ + +struct s { + unsigned int x : 17; +}; From fb9b50ff9c63c2eefcef298348882fc3c2261587 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Wed, 29 Jul 2020 22:45:59 +0200 Subject: [PATCH 1497/2161] Move type checks before bit-field width parsing --- src/cc65/declare.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index b8ad09cfd..5c5c5c01e 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -688,16 +688,16 @@ static int ParseFieldWidth (Declaration* Decl) return -1; } - /* Read the width */ - NextToken (); - ConstAbsIntExpr (hie1, &Expr); - if (SizeOf (Decl->Type) != SizeOf (type_uint)) { /* Only int sized types may be used for bit-fields for now */ Error ("cc65 currently only supports unsigned int bit-fields"); return -1; } + /* Read the width */ + NextToken (); + ConstAbsIntExpr (hie1, &Expr); + if (Expr.IVal < 0) { Error ("Negative width in bit-field"); return -1; From 19c81ed8665f1062c176bcc75cb2f23a32f9ae03 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 29 Jul 2020 19:51:47 +0800 Subject: [PATCH 1498/2161] Fixed type mask usage. --- src/cc65/typecmp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index af04d8232..66dd9039b 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -215,8 +215,8 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) } /* Get the left and right types, signs and qualifiers */ - LeftType = GetUnderlyingTypeCode (lhs); - RightType = GetUnderlyingTypeCode (rhs); + LeftType = (GetUnderlyingTypeCode (lhs) & T_MASK_TYPE); + RightType = (GetUnderlyingTypeCode (rhs) & T_MASK_TYPE); LeftSign = GetSignedness (lhs); RightSign = GetSignedness (rhs); LeftQual = GetQualifier (lhs); From 92de4fa0d0f8ae1c4d863a7191037bd0dea8cc0b Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 29 Jul 2020 15:08:54 +0800 Subject: [PATCH 1499/2161] Enabled to recognize labels when parsing local variable declarations. --- src/cc65/declare.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 5c5c5c01e..1ebae4123 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1248,11 +1248,23 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers) break; case TOK_IDENT: - Entry = FindSym (CurTok.Ident); - if (Entry && SymIsTypeDef (Entry)) { - /* It's a typedef */ - NextToken (); - TypeCopy (D->Type, Entry->Type); + /* This could be a label */ + if (NextTok.Tok != TOK_COLON) { + Entry = FindSym (CurTok.Ident); + if (Entry && SymIsTypeDef (Entry)) { + /* It's a typedef */ + NextToken (); + TypeCopy (D->Type, Entry->Type); + break; + } + } 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. + */ + D->Flags |= DS_DEF_TYPE; + D->Type[0].C = T_QUAL_NONE; + D->Type[1].C = T_END; break; } /* FALL THROUGH */ From d6d667a688b3831e17ec0b4ec4b77a99cc0def88 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 29 Jul 2020 18:07:16 +0800 Subject: [PATCH 1500/2161] Improved error handling with symbol redefinitions. --- src/cc65/symtab.c | 282 ++++++++++++++++++++++++++++++---------------- 1 file changed, 183 insertions(+), 99 deletions(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 4169e6280..6472a0792 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -93,6 +93,7 @@ static SymTable* TagTab0 = 0; static SymTable* TagTab = 0; static SymTable* LabelTab = 0; static SymTable* SPAdjustTab = 0; +static SymTable* FailSafeTab = 0; /* For errors */ /*****************************************************************************/ @@ -141,7 +142,6 @@ static void FreeSymTable (SymTable* S) } - /*****************************************************************************/ /* Check symbols in a table */ /*****************************************************************************/ @@ -228,6 +228,9 @@ void EnterGlobalLevel (void) /* Create and assign the table of SP adjustment symbols */ SPAdjustTab = NewSymTable (SYMTAB_SIZE_GLOBAL); + + /* Create and assign the table of fictitious symbols used with errors */ + FailSafeTab = NewSymTable (SYMTAB_SIZE_GLOBAL); } @@ -523,6 +526,111 @@ SymEntry* FindStructField (const Type* T, const char* Name) +static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags) +/* Check and handle redefinition of existing symbols. +** Return ture if there *is* an error. +*/ +{ + /* Get the type info of the existing symbol */ + Type* E_Type = Entry->Type; + unsigned E_SCType = Entry->Flags & SC_TYPEMASK; + unsigned SCType = Flags & SC_TYPEMASK; + + /* Some symbols may be redeclared if certain requirements are met */ + if (IsTypeArray (T) && IsTypeArray (E_Type)) { + + /* Get the array sizes */ + long Size = GetElementCount (T); + long ESize = GetElementCount (E_Type); + + /* If we are handling arrays, the old entry or the new entry may be + ** an incomplete declaration. Accept this, and if the exsting entry + ** is incomplete, complete it. + */ + if ((Size != UNSPECIFIED && ESize != UNSPECIFIED && Size != ESize) || + TypeCmp (T + 1, E_Type + 1) < TC_EQUAL) { + /* Types not identical: Conflicting types */ + Error ("Conflicting array types for '%s[]'", Entry->Name); + Entry = 0; + } else { + /* Check if we have a size in the existing definition */ + if (ESize == UNSPECIFIED) { + /* Existing, size not given, use size from new def */ + SetElementCount (E_Type, Size); + } + } + + } else { + + /* We have a symbol with this name already */ + if ((Entry->Flags & SC_FUNC) == 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 + ** an actual function definition follows. Be sure not to use the + ** new descriptor if it contains a function declaration with an + ** empty parameter list. + */ + if (IsTypeFunc (T)) { + + /* New type must be identical */ + if (TypeCmp (Entry->Type, T) < TC_EQUAL) { + Error ("Conflicting function types for '%s'", Entry->Name); + Entry = 0; + } else { + /* Get the function descriptor from the new type */ + FuncDesc* F = GetFuncDesc (T); + /* Use this new function descriptor if it doesn't contain + ** an empty parameter list. + */ + if ((F->Flags & FD_EMPTY) == 0) { + Entry->V.F.Func = F; + SetFuncDesc (E_Type, F); + } + } + + } else { + Error ("Redefinition of function '%s' as different kind of symbol", Entry->Name); + Entry = 0; + } + } else if (E_SCType == SC_TYPEDEF) { + + if (SCType == SC_TYPEDEF) { + /* New typedef must be identical */ + if (TypeCmp (E_Type, T) < TC_EQUAL) { + Error ("Conflicting types for typedef '%s'", Entry->Name); + Entry = 0; + } + + } else { + + Error ("Redefinition of typedef '%s' as different kind of symbol", Entry->Name); + Entry = 0; + } + + } else { + + /* New type must be identical */ + if (SCType != E_SCType) { + Error ("Redefinition of '%s' as different kind of symbol", Entry->Name); + Entry = 0; + } else if (TypeCmp (E_Type, T) < TC_EQUAL) { + Error ("Conflicting types for '%s'", Entry->Name); + Entry = 0; + } else if (E_SCType == SC_ENUMERATOR) { + /* Current code logic won't reach here, but still... */ + Error ("Redeclaration of enumerator constant '%s'", Entry->Name); + Entry = 0; + } + } + } + + /* Return if there are any errors */ + return Entry == 0; +} + + + static void AddSymEntry (SymTable* T, SymEntry* S) /* Add a symbol to a symbol table */ { @@ -554,28 +662,39 @@ static void AddSymEntry (SymTable* T, SymEntry* S) SymEntry* AddEnumSym (const char* Name, const Type* Type, SymTable* Tab) /* Add an enum entry and return it */ { + SymTable* CurTagTab = TagTab; + /* Do we have an entry with this name already? */ - SymEntry* Entry = FindSymInTable (TagTab, Name, HashStr (Name)); + SymEntry* Entry = FindSymInTable (CurTagTab, Name, HashStr (Name)); if (Entry) { /* We do have an entry. This may be a forward, so check it. */ if ((Entry->Flags & SC_TYPEMASK) != SC_ENUM) { /* Existing symbol is not an enum */ Error ("Symbol '%s' is already different kind", Name); + Entry = 0; } else { /* Define the struct size if the underlying type is given. */ if (Type != 0) { if (Type !=0 && Entry->V.E.Type != 0) { /* Both are definitions. */ Error ("Multiple definition for enum '%s'", Name); + Entry = 0; + } else { + Entry->Type = 0; + Entry->V.E.SymTab = Tab; + Entry->V.E.Type = Type; } - Entry->Type = 0; - Entry->V.E.SymTab = Tab; - Entry->V.E.Type = Type; } } - } else { + if (Entry == 0) { + /* Use the fail-safe table for fictitious symbols */ + CurTagTab = FailSafeTab; + } + } + + if (Entry == 0) { /* Create a new entry */ Entry = NewSymEntry (Name, SC_ENUM); @@ -586,7 +705,7 @@ SymEntry* AddEnumSym (const char* Name, const Type* Type, SymTable* Tab) Entry->V.E.Type = Type; /* Add it to the current table */ - AddSymEntry (TagTab, Entry); + AddSymEntry (CurTagTab, Entry); } /* Return the entry */ @@ -598,22 +717,25 @@ SymEntry* AddEnumSym (const char* Name, const Type* Type, SymTable* Tab) SymEntry* AddStructSym (const char* Name, unsigned Type, unsigned Size, SymTable* Tab) /* Add a struct/union entry and return it */ { + SymTable* CurTagTab = TagTab; SymEntry* Entry; /* Type must be struct or union */ PRECONDITION (Type == SC_STRUCT || Type == SC_UNION); /* Do we have an entry with this name already? */ - Entry = FindSymInTable (TagTab, Name, HashStr (Name)); + Entry = FindSymInTable (CurTagTab, Name, HashStr (Name)); if (Entry) { /* We do have an entry. This may be a forward, so check it. */ if ((Entry->Flags & SC_TYPEMASK) != Type) { /* Existing symbol is not a struct */ Error ("Symbol '%s' is already different kind", Name); + Entry = 0; } else if (Size > 0 && Entry->V.S.Size > 0) { /* Both structs are definitions. */ Error ("Multiple definition for '%s'", Name); + Entry = 0; } else { /* Define the struct size if it is given */ if (Size > 0) { @@ -622,7 +744,13 @@ SymEntry* AddStructSym (const char* Name, unsigned Type, unsigned Size, SymTable } } - } else { + if (Entry == 0) { + /* Use the fail-safe table for fictitious symbols */ + CurTagTab = FailSafeTab; + } + } + + if (Entry == 0) { /* Create a new entry */ Entry = NewSymEntry (Name, Type); @@ -631,8 +759,8 @@ SymEntry* AddStructSym (const char* Name, unsigned Type, unsigned Size, SymTable Entry->V.S.SymTab = Tab; Entry->V.S.Size = Size; - /* Add it to the current table */ - AddSymEntry (TagTab, Entry); + /* Add it to the current tag table */ + AddSymEntry (CurTagTab, Entry); } /* Return the entry */ @@ -704,6 +832,7 @@ SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val } + DefOrRef* AddDefOrRef (SymEntry* E, unsigned Flags) /* Add definition or reference to the SymEntry and preserve its attributes */ { @@ -721,6 +850,8 @@ DefOrRef* AddDefOrRef (SymEntry* E, unsigned Flags) return DOR; } + + unsigned short FindSPAdjustment (const char* Name) /* Search for an entry in the table of SP adjustments */ { @@ -733,6 +864,8 @@ unsigned short FindSPAdjustment (const char* Name) return Entry->V.SPAdjustment; } + + SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* Add a goto label to the label table */ { @@ -848,15 +981,21 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs) /* Add a local symbol and return the symbol entry */ { + SymTable* Tab = SymTab; + /* Do we have an entry with this name already? */ - SymEntry* Entry = FindSymInTable (SymTab, Name, HashStr (Name)); + SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name)); if (Entry) { /* We have a symbol with this name already */ - Error ("Multiple definition for '%s'", Name); - - } else { - + if (HandleSymRedefinition (Entry, T, Flags)) { + /* Use the fail-safe table for fictitious symbols */ + Tab = FailSafeTab; + Entry = 0; + } + } + + if (Entry == 0) { /* Create a new entry */ Entry = NewSymEntry (Name, Flags); @@ -881,7 +1020,7 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs } /* Add the entry to the symbol table */ - AddSymEntry (SymTab, Entry); + AddSymEntry (Tab, Entry); } @@ -898,101 +1037,46 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) int IsFunc = IsTypeFunc (T); /* Functions must be inserted in the global symbol table */ - SymTable* Tab = IsFunc? SymTab0 : SymTab; + SymTable* Tab = IsFunc ? SymTab0 : SymTab; /* Do we have an entry with this name already? */ SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name)); if (Entry) { - Type* EType; - - /* If the existing symbol is an enumerated constant, - ** then avoid a compiler crash. See GitHub issue #728. - */ - if (Entry->Flags & SC_ENUMERATOR) { - Fatal ("Can't redeclare enumerator constant '%s' as global variable", Name); - } /* We have a symbol with this name already */ - if (Entry->Flags & SC_TYPEMASK) { - Error ("Multiple definition for '%s'", Name); - return Entry; - } - - /* Get the type string of the existing symbol */ - EType = Entry->Type; - - /* If we are handling arrays, the old entry or the new entry may be an - ** incomplete declaration. Accept this, and if the exsting entry is - ** incomplete, complete it. - */ - if (IsTypeArray (T) && IsTypeArray (EType)) { - - /* Get the array sizes */ - long Size = GetElementCount (T); - long ESize = GetElementCount (EType); - - if ((Size != UNSPECIFIED && ESize != UNSPECIFIED && Size != ESize) || - TypeCmp (T + 1, EType + 1) < TC_EQUAL) { - /* Types not identical: Conflicting types */ - Error ("Conflicting types for '%s'", Name); - return Entry; - } else { - /* Check if we have a size in the existing definition */ - if (ESize == UNSPECIFIED) { - /* Existing, size not given, use size from new def */ - SetElementCount (EType, Size); - } - } + if (HandleSymRedefinition (Entry, T, Flags)) { + /* Use the fail-safe table for fictitious symbols */ + Tab = FailSafeTab; + Entry = 0; } else { - /* New type must be identical */ - if (TypeCmp (EType, T) < TC_EQUAL) { - Error ("Conflicting types for '%s'", Name); - return Entry; - } - /* In case of a function, use the new type descriptor, since it - ** contains pointers to the new symbol tables that are needed if - ** an actual function definition follows. Be sure not to use the - ** new descriptor if it contains a function declaration with an - ** empty parameter list. + /* If a static declaration follows a non-static declaration, then + ** warn about the conflict. (It will compile a public declaration.) */ - if (IsFunc) { - /* Get the function descriptor from the new type */ - FuncDesc* F = GetFuncDesc (T); - /* Use this new function descriptor if it doesn't contain - ** an empty parameter list. - */ - if ((F->Flags & FD_EMPTY) == 0) { - Entry->V.F.Func = F; - SetFuncDesc (EType, F); - } + if ((Flags & SC_EXTERN) == 0 && (Entry->Flags & SC_EXTERN) != 0) { + Warning ("static declaration follows non-static declaration of '%s'.", Name); } + + /* An extern declaration must not change the current linkage. */ + if (IsFunc || (Flags & (SC_EXTERN | SC_STORAGE)) == SC_EXTERN) { + Flags &= ~SC_EXTERN; + } + + /* If a public declaration follows a static declaration, then + ** warn about the conflict. (It will compile a public declaration.) + */ + if ((Flags & SC_EXTERN) != 0 && (Entry->Flags & SC_EXTERN) == 0) { + Warning ("public declaration follows static declaration of '%s'.", Name); + } + + /* Add the new flags */ + Entry->Flags |= Flags; } - /* If a static declaration follows a non-static declaration, then - ** warn about the conflict. (It will compile a public declaration.) - */ - if ((Flags & SC_EXTERN) == 0 && (Entry->Flags & SC_EXTERN) != 0) { - Warning ("static declaration follows non-static declaration of '%s'.", Name); - } - - /* An extern declaration must not change the current linkage. */ - if (IsFunc || (Flags & (SC_EXTERN | SC_STORAGE)) == SC_EXTERN) { - Flags &= ~SC_EXTERN; - } - - /* If a public declaration follows a static declaration, then - ** warn about the conflict. (It will compile a public declaration.) - */ - if ((Flags & SC_EXTERN) != 0 && (Entry->Flags & SC_EXTERN) == 0) { - Warning ("public declaration follows static declaration of '%s'.", Name); - } - - /* Add the new flags */ - Entry->Flags |= Flags; - - } else { + } + + if (Entry == 0) { /* Create a new entry */ Entry = NewSymEntry (Name, Flags); From 25d10d9d9ad033c793f0857b465774a42c3613a3 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 29 Jul 2020 15:09:53 +0800 Subject: [PATCH 1501/2161] Fixed nested struct/union initialization. Fixed bit-fields offsets in anonymous structs. --- src/cc65/anonname.c | 11 +++ src/cc65/anonname.h | 5 ++ src/cc65/declare.c | 203 +++++++++++++++++++++++++++----------------- src/cc65/expr.c | 31 ++++--- src/cc65/symentry.h | 10 +++ src/cc65/symtab.c | 39 +++++++-- src/cc65/symtab.h | 7 +- 7 files changed, 201 insertions(+), 105 deletions(-) diff --git a/src/cc65/anonname.c b/src/cc65/anonname.c index d02253d82..23891bf0e 100644 --- a/src/cc65/anonname.c +++ b/src/cc65/anonname.c @@ -61,6 +61,17 @@ static const char AnonTag[] = "$anon"; +char* AnonFieldName (char* Buf, const char* Spec, int ANumber) +/* Get a name for an anonymous field of a struct or union. The given buffer is +** expected to be IDENTSIZE characters long. A pointer to the buffer is returned. +*/ +{ + xsprintf (Buf, IDENTSIZE, "%s-%s-%04X", AnonTag, Spec, ANumber); + return Buf; +} + + + char* AnonName (char* Buf, const char* Spec) /* Get a name for an anonymous variable or type. The given buffer is expected ** to be IDENTSIZE characters long. A pointer to the buffer is returned. diff --git a/src/cc65/anonname.h b/src/cc65/anonname.h index dfaa1bdaa..a88b131b5 100644 --- a/src/cc65/anonname.h +++ b/src/cc65/anonname.h @@ -44,6 +44,11 @@ +char* AnonFieldName (char* Buf, const char* Spec, int ANumber); +/* Get a name for an anonymous field of a struct or union. The given buffer is +** expected to be IDENTSIZE characters long. A pointer to the buffer is returned. +*/ + char* AnonName (char* Buf, const char* Spec); /* Get a name for an anonymous variable or type. The given buffer is expected ** to be IDENTSIZE characters long. A pointer to the buffer is returned. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 1ebae4123..a1d23c20b 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -89,7 +89,7 @@ struct StructInitData { static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers); /* Parse a type specifier */ -static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers); +static unsigned ParseInitInternal (Type* T, int* Braces, int AllowFlexibleMembers); /* Parse initialization of variables. Return the number of data bytes. */ @@ -717,24 +717,24 @@ static int ParseFieldWidth (Declaration* Decl) -static unsigned CopyAnonStructFields (const Declaration* Decl, int Offs) -/* Copy fields from an anon union/struct into the current lexical level. The -** function returns the size of the embedded struct/union. +static unsigned AliasAnonStructFields (const Declaration* Decl, SymEntry* Anon) +/* Create alias fields from an anon union/struct in the current lexical level. +** The function returns the count of created aliases. */ { + unsigned Count = 0; + SymEntry* Alias; + /* Get the pointer to the symbol table entry of the anon struct */ SymEntry* Entry = GetSymEntry (Decl->Type); - /* Get the size of the anon struct */ - unsigned Size = Entry->V.S.Size; - /* Get the symbol table containing the fields. If it is empty, there has ** been an error before, so bail out. */ SymTable* Tab = Entry->V.S.SymTab; if (Tab == 0) { /* Incomplete definition - has been flagged before */ - return Size; + return 0; } /* Get a pointer to the list of symbols. Then walk the list adding copies @@ -743,10 +743,13 @@ static unsigned CopyAnonStructFields (const Declaration* Decl, int Offs) Entry = Tab->SymHead; while (Entry) { - /* Enter a copy of this symbol adjusting the offset. We will just - ** reuse the type string here. - */ - AddLocalSym (Entry->Name, Entry->Type, SC_STRUCTFIELD, Offs + Entry->V.Offs); + /* Enter an alias of this symbol */ + if (!IsAnonName (Entry->Name)) { + Alias = AddLocalSym (Entry->Name, Entry->Type, SC_STRUCTFIELD|SC_ALIAS, 0); + Alias->V.A.Field = Entry; + Alias->V.A.Offs = Anon->V.Offs + Entry->V.Offs; + ++Count; + } /* Currently, there can not be any attributes, but if there will be ** some in the future, we want to know this. @@ -757,8 +760,8 @@ static unsigned CopyAnonStructFields (const Declaration* Decl, int Offs) Entry = Entry->NextSym; } - /* Return the size of the embedded struct */ - return Size; + /* Return the count of created aliases */ + return Count; } @@ -771,6 +774,8 @@ static SymEntry* ParseUnionDecl (const char* Name) unsigned FieldSize; int FieldWidth; /* Width in bits, -1 if not a bit-field */ SymTable* FieldTab; + SymEntry* StructTypeEntry; + SymEntry* Entry; if (CurTok.Tok != TOK_LCURLY) { @@ -779,7 +784,9 @@ static SymEntry* ParseUnionDecl (const char* Name) } /* Add a forward declaration for the struct in the current lexical level */ - AddStructSym (Name, SC_UNION, 0, 0); + StructTypeEntry = AddStructSym (Name, SC_UNION, 0, 0); + + StructTypeEntry->V.S.ACount = 0; /* Skip the curly brace */ NextToken (); @@ -821,16 +828,11 @@ static SymEntry* ParseUnionDecl (const char* Name) /* This is an anonymous struct or union. Copy the fields ** into the current level. */ - FieldSize = CopyAnonStructFields (&Decl, 0); - if (FieldSize > UnionSize) { - UnionSize = FieldSize; - } - + AnonFieldName (Decl.Ident, "field", StructTypeEntry->V.S.ACount); } else { /* A non bit-field without a name is legal but useless */ Warning ("Declaration does not declare anything"); } - goto NextMember; } /* Handle sizes */ @@ -843,7 +845,13 @@ static SymEntry* ParseUnionDecl (const char* Name) if (FieldWidth > 0) { AddBitField (Decl.Ident, 0, 0, FieldWidth); } else { - AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0); + if (IsAnonName (Decl.Ident)) { + Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0); + Entry->V.A.ANumber = StructTypeEntry->V.S.ACount++; + AliasAnonStructFields (&Decl, Entry); + } else { + AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0); + } } NextMember: if (CurTok.Tok != TOK_COMMA) { @@ -876,6 +884,8 @@ static SymEntry* ParseStructDecl (const char* Name) unsigned BitOffs; /* Bit offset for bit-fields */ int FieldWidth; /* Width in bits, -1 if not a bit-field */ SymTable* FieldTab; + SymEntry* StructTypeEntry; + SymEntry* Entry; if (CurTok.Tok != TOK_LCURLY) { @@ -884,7 +894,9 @@ static SymEntry* ParseStructDecl (const char* Name) } /* Add a forward declaration for the struct in the current lexical level */ - AddStructSym (Name, SC_STRUCT, 0, 0); + StructTypeEntry = AddStructSym (Name, SC_STRUCT, 0, 0); + + StructTypeEntry->V.S.ACount = 0; /* Skip the curly brace */ NextToken (); @@ -981,13 +993,11 @@ static SymEntry* ParseStructDecl (const char* Name) /* This is an anonymous struct or union. Copy the ** fields into the current level. */ - StructSize += CopyAnonStructFields (&Decl, StructSize); - + AnonFieldName (Decl.Ident, "field", StructTypeEntry->V.S.ACount); } else { /* A non bit-field without a name is legal but useless */ Warning ("Declaration does not declare anything"); } - goto NextMember; } else { /* A bit-field without a name will get an anonymous one */ AnonName (Decl.Ident, "bit-field"); @@ -1009,7 +1019,13 @@ static SymEntry* ParseStructDecl (const char* Name) StructSize += BitOffs / CHAR_BITS; BitOffs %= CHAR_BITS; } else { - AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize); + if (IsAnonName (Decl.Ident)) { + Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize); + Entry->V.A.ANumber = StructTypeEntry->V.S.ACount++; + AliasAnonStructFields (&Decl, Entry); + } else { + AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize); + } if (!FlexibleMember) { StructSize += CheckedSizeOf (Decl.Type); } @@ -1874,18 +1890,20 @@ void CheckEmptyDecl (const DeclSpec* D) -static void SkipInitializer (unsigned BracesExpected) +static void SkipInitializer (int BracesExpected) /* Skip the remainder of an initializer in case of errors. Try to be somewhat ** smart so we don't have too many following errors. */ { - while (CurTok.Tok != TOK_CEOF && CurTok.Tok != TOK_SEMI && BracesExpected > 0) { + while (CurTok.Tok != TOK_CEOF && CurTok.Tok != TOK_SEMI && BracesExpected >= 0) { switch (CurTok.Tok) { case TOK_RCURLY: --BracesExpected; break; case TOK_LCURLY: ++BracesExpected; break; default: break; } - NextToken (); + if (BracesExpected >= 0) { + NextToken (); + } } } @@ -1917,6 +1935,7 @@ static void ClosingCurlyBraces (unsigned BracesExpected) */ { while (BracesExpected) { + /* TODO: Skip all excess initializers until next closing curly brace */ if (CurTok.Tok == TOK_RCURLY) { NextToken (); } else if (CurTok.Tok == TOK_COMMA && NextTok.Tok == TOK_RCURLY) { @@ -2069,7 +2088,7 @@ static unsigned ParsePointerInit (Type* T) -static unsigned ParseArrayInit (Type* T, int AllowFlexibleMembers) +static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) /* Parse initializaton for arrays. Return the number of data bytes. */ { int Count; @@ -2135,7 +2154,7 @@ static unsigned ParseArrayInit (Type* T, int AllowFlexibleMembers) ** an array (because the size of each element may differ ** otherwise). */ - ParseInitInternal (ElementType, 0); + ParseInitInternal (ElementType, Braces, 0); ++Count; if (CurTok.Tok != TOK_COMMA) break; @@ -2158,23 +2177,29 @@ static unsigned ParseArrayInit (Type* T, int AllowFlexibleMembers) } else if (Count < ElementCount) { g_zerobytes ((ElementCount - Count) * ElementSize); } else if (Count > ElementCount) { - Error ("Too many initializers"); + Error ("Excess elements in array initializer"); } return ElementCount * ElementSize; } -static unsigned ParseStructInit (Type* T, int AllowFlexibleMembers) +static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) /* Parse initialization of a struct or union. Return the number of data bytes. */ { SymEntry* Entry; SymTable* Tab; StructInitData SI; + int HasCurly = 0; + int SkipComma = 0; - /* Consume the opening curly brace */ - ConsumeLCurly (); + /* Fields can be initialized without a pair of curly braces */ + if (*Braces == 0 || CurTok.Tok == TOK_LCURLY) { + /* Consume the opening curly brace */ + HasCurly = ConsumeLCurly (); + *Braces += HasCurly; + } /* Get a pointer to the struct entry from the type */ Entry = GetSymEntry (T); @@ -2189,7 +2214,7 @@ static unsigned ParseStructInit (Type* T, int AllowFlexibleMembers) if (Tab == 0) { Error ("Cannot initialize variables with incomplete type"); /* Try error recovery */ - SkipInitializer (1); + SkipInitializer (HasCurly); /* Nothing initialized */ return 0; } @@ -2203,18 +2228,50 @@ static unsigned ParseStructInit (Type* T, int AllowFlexibleMembers) SI.ValBits = 0; while (CurTok.Tok != TOK_RCURLY) { - /* */ + /* Check for excess elements */ if (Entry == 0) { - Error ("Too many initializers"); - SkipInitializer (1); + if (HasCurly) { + Error ("Excess elements in %s initializer", GetBasicTypeName (T)); + SkipInitializer (HasCurly); + } return SI.Offs; } - /* Parse initialization of one field. Bit-fields need a special - ** handling. + /* Check for special members that don't consume the initializer */ + if ((Entry->Flags & SC_ALIAS) == SC_ALIAS) { + /* Just skip */ + goto NextMember; + } + + /* This may be an anonymous bit-field, in which case it doesn't + ** have an initializer. */ + if (SymIsBitField (Entry) && (IsAnonName (Entry->Name))) { + /* Account for the data and output it if we have at least a full + ** word. We may have more if there was storage unit overlap, for + ** example two consecutive 10 bit fields. These will be packed + ** into 3 bytes. + */ + SI.ValBits += Entry->V.B.BitWidth; + CHECK (SI.ValBits <= CHAR_BITS + INT_BITS - 2); + while (SI.ValBits >= CHAR_BITS) { + OutputBitFieldData (&SI); + } + /* Avoid consuming the comma if any */ + goto NextMember; + } + + /* Skip comma this round */ + if (SkipComma) { + NextToken (); + SkipComma = 0; + } + if (SymIsBitField (Entry)) { + /* Parse initialization of one field. Bit-fields need a special + ** handling. + */ ExprDesc ED; unsigned Val; unsigned Shift; @@ -2226,36 +2283,17 @@ static unsigned ParseStructInit (Type* T, int AllowFlexibleMembers) CHECK (Entry->V.B.Offs * CHAR_BITS + Entry->V.B.BitOffs == SI.Offs * CHAR_BITS + SI.ValBits); - /* This may be an anonymous bit-field, in which case it doesn't - ** have an initializer. - */ - if (IsAnonName (Entry->Name)) { - /* Account for the data and output it if we have at least a - ** full word. We may have more if there was storage unit - ** overlap, for example two consecutive 10 bit fields. - ** These will be packed into 3 bytes. - */ - SI.ValBits += Entry->V.B.BitWidth; - CHECK (SI.ValBits <= CHAR_BITS + INT_BITS - 2); - while (SI.ValBits >= CHAR_BITS) { - OutputBitFieldData (&SI); - } - goto NextMember; - } else { - /* Read the data, check for a constant integer, do a range - ** check. - */ - ParseScalarInitInternal (type_uint, &ED); - if (!ED_IsConstAbsInt (&ED)) { - Error ("Constant initializer expected"); - ED_MakeConstAbsInt (&ED, 1); - } - if (ED.IVal > (long) Mask) { - Warning ("Truncating value in bit-field initializer"); - ED.IVal &= (long) Mask; - } - Val = (unsigned) ED.IVal; + /* Read the data, check for a constant integer, do a range check */ + ParseScalarInitInternal (type_uint, &ED); + if (!ED_IsConstAbsInt (&ED)) { + Error ("Constant initializer expected"); + ED_MakeConstAbsInt (&ED, 1); } + if (ED.IVal > (long) Mask) { + Warning ("Truncating value in bit-field initializer"); + ED.IVal &= (long) Mask; + } + Val = (unsigned) ED.IVal; /* Add the value to the currently stored bit-field value */ Shift = (Entry->V.B.Offs - SI.Offs) * CHAR_BITS + Entry->V.B.BitOffs; @@ -2285,7 +2323,7 @@ static unsigned ParseStructInit (Type* T, int AllowFlexibleMembers) /* Flexible array members may only be initialized if they are ** the last field (or part of the last struct field). */ - SI.Offs += ParseInitInternal (Entry->Type, AllowFlexibleMembers && Entry->NextSym == 0); + SI.Offs += ParseInitInternal (Entry->Type, Braces, AllowFlexibleMembers && Entry->NextSym == 0); } /* More initializers? */ @@ -2293,8 +2331,8 @@ static unsigned ParseStructInit (Type* T, int AllowFlexibleMembers) break; } - /* Skip the comma */ - NextToken (); + /* Skip the comma next round */ + SkipComma = 1; NextMember: /* Next member. For unions, only the first one can be initialized */ @@ -2307,8 +2345,10 @@ NextMember: } } - /* Consume the closing curly brace */ - ConsumeRCurly (); + if (HasCurly) { + /* Consume the closing curly brace */ + ConsumeRCurly (); + } /* If we have data from a bit-field left, output it now */ CHECK (SI.ValBits < CHAR_BITS); @@ -2405,7 +2445,7 @@ static unsigned ParseVoidInit (Type* T) -static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers) +static unsigned ParseInitInternal (Type* T, int *Braces, int AllowFlexibleMembers) /* Parse initialization of variables. Return the number of data bytes. */ { switch (GetUnderlyingTypeCode (T)) { @@ -2426,11 +2466,11 @@ static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers) return ParsePointerInit (T); case T_ARRAY: - return ParseArrayInit (T, AllowFlexibleMembers); + return ParseArrayInit (T, Braces, AllowFlexibleMembers); case T_STRUCT: case T_UNION: - return ParseStructInit (T, AllowFlexibleMembers); + return ParseStructInit (T, Braces, AllowFlexibleMembers); case T_VOID: if (IS_Get (&Standard) == STD_CC65) { @@ -2451,10 +2491,13 @@ static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers) unsigned ParseInit (Type* T) /* Parse initialization of variables. Return the number of data bytes. */ { + /* Current curly braces layers */ + int Braces = 0; + /* Parse the initialization. Flexible array members can only be initialized ** in cc65 mode. */ - unsigned Size = ParseInitInternal (T, IS_Get (&Standard) == STD_CC65); + unsigned Size = ParseInitInternal (T, &Braces, IS_Get (&Standard) == STD_CC65); /* The initialization may not generate code on global level, because code ** outside function scope will never get executed. diff --git a/src/cc65/expr.c b/src/cc65/expr.c index a35ad59a9..fd8a48002 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1201,7 +1201,6 @@ static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { ident Ident; - SymEntry* Field; Type* FinalType; TypeCode Q; @@ -1217,8 +1216,8 @@ static void StructRef (ExprDesc* Expr) /* Get the symbol table entry and check for a struct/union field */ strcpy (Ident, CurTok.Ident); NextToken (); - Field = FindStructField (Expr->Type, Ident); - if (Field == 0) { + const SymEntry Field = FindStructField (Expr->Type, Ident); + if (Field.Type == 0) { Error ("No field named '%s' found in %s", Ident, GetBasicTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); @@ -1264,10 +1263,10 @@ static void StructRef (ExprDesc* Expr) } else { Q = GetQualifier (Indirect (Expr->Type)); } - if (GetQualifier (Field->Type) == (GetQualifier (Field->Type) | Q)) { - FinalType = Field->Type; + if (GetQualifier (Field.Type) == (GetQualifier (Field.Type) | Q)) { + FinalType = Field.Type; } else { - FinalType = TypeDup (Field->Type); + FinalType = TypeDup (Field.Type); FinalType->C |= Q; } @@ -1278,10 +1277,10 @@ static void StructRef (ExprDesc* Expr) /* Get the size of the type */ unsigned StructSize = SizeOf (Expr->Type); - unsigned FieldSize = SizeOf (Field->Type); + unsigned FieldSize = SizeOf (Field.Type); /* Safety check */ - CHECK (Field->V.Offs + FieldSize <= StructSize); + CHECK (Field.V.Offs + FieldSize <= StructSize); /* The type of the operation depends on the type of the struct/union */ switch (StructSize) { @@ -1304,16 +1303,16 @@ static void StructRef (ExprDesc* Expr) /* Generate a shift to get the field in the proper position in the ** primary. For bit fields, mask the value. */ - BitOffs = Field->V.Offs * CHAR_BITS; - if (SymIsBitField (Field)) { - BitOffs += Field->V.B.BitOffs; + BitOffs = Field.V.Offs * CHAR_BITS; + if (SymIsBitField (&Field)) { + BitOffs += Field.V.B.BitOffs; g_asr (Flags, BitOffs); /* Mask the value. This is unnecessary if the shift executed above ** moved only zeroes into the value. */ - if (BitOffs + Field->V.B.BitWidth != FieldSize * CHAR_BITS) { + if (BitOffs + Field.V.B.BitWidth != FieldSize * CHAR_BITS) { g_and (CF_INT | CF_UNSIGNED | CF_CONST, - (0x0001U << Field->V.B.BitWidth) - 1U); + (0x0001U << Field.V.B.BitWidth) - 1U); } } else { g_asr (Flags, BitOffs); @@ -1325,7 +1324,7 @@ static void StructRef (ExprDesc* Expr) } else { /* Set the struct/union field offset */ - Expr->IVal += Field->V.Offs; + Expr->IVal += Field.V.Offs; /* Use the new type */ Expr->Type = FinalType; @@ -1341,8 +1340,8 @@ static void StructRef (ExprDesc* Expr) } /* Make the expression a bit field if necessary */ - if (SymIsBitField (Field)) { - ED_MakeBitField (Expr, Field->V.B.BitOffs, Field->V.B.BitWidth); + if (SymIsBitField (&Field)) { + ED_MakeBitField (Expr, Field.V.B.BitOffs, Field.V.B.BitWidth); } } diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index b030d8b8b..e59bf2a35 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -105,6 +105,7 @@ struct CodeEntry; #define SC_SPADJUSTMENT 0x400000U #define SC_GOTO_IND 0x800000U /* Indirect goto */ +#define SC_ALIAS 0x01000000U /* Alias of anonymous field */ @@ -138,6 +139,14 @@ struct SymEntry { /* Offset for locals or struct members */ int Offs; + /* Data for anonymous struct or union members */ + struct { + int Offs; /* Byte offset into struct */ + unsigned ANumber; /* Numeric ID */ + SymEntry* Field; /* The real field aliased */ + } A; + + /* Label name for static symbols */ struct { unsigned Label; @@ -163,6 +172,7 @@ struct SymEntry { struct { struct SymTable* SymTab; /* Member symbol table */ unsigned Size; /* Size of the union/struct */ + unsigned ACount; /* Count of anonymous fields */ } S; /* Data for enums */ diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6472a0792..f7a7862cf 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -490,10 +490,15 @@ SymEntry* FindTagSym (const char* Name) -SymEntry* FindStructField (const Type* T, const char* Name) -/* Find a struct/union field in the fields list */ +SymEntry FindStructField (const Type* T, const char* Name) +/* Find a struct/union field in the fields list. +** Return the info about the found field symbol filled in an entry struct by +** value, or an empty entry struct if the field is not found. +*/ { - SymEntry* Field = 0; + SymEntry* Entry = 0; + SymEntry Field; + int Offs = 0; /* The given type may actually be a pointer to struct/union */ if (IsTypePtr (T)) { @@ -511,10 +516,26 @@ SymEntry* FindStructField (const Type* T, const char* Name) ** not exist. */ if (Struct->V.S.SymTab) { - Field = FindSymInTable (Struct->V.S.SymTab, Name, HashStr (Name)); + Entry = FindSymInTable (Struct->V.S.SymTab, Name, HashStr (Name)); + + if (Entry != 0) { + Offs = Entry->V.Offs; + } + + while (Entry != 0 && (Entry->Flags & SC_ALIAS) == SC_ALIAS) { + /* Get the real field */ + Entry = Entry->V.A.Field; + } } } + if (Entry != 0) { + Field = *Entry; + Field.V.Offs = Offs; + } else { + memset (&Field, 0, sizeof(SymEntry)); + } + return Field; } @@ -1001,7 +1022,13 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs /* Set the symbol attributes */ Entry->Type = TypeDup (T); - if ((Flags & SC_AUTO) == SC_AUTO || (Flags & SC_TYPEMASK) == SC_TYPEDEF) { + + if ((Flags & SC_STRUCTFIELD) == SC_STRUCTFIELD || + (Flags & SC_TYPEDEF) == SC_TYPEDEF) { + if ((Flags & SC_ALIAS) != SC_ALIAS) { + Entry->V.Offs = Offs; + } + } else if ((Flags & SC_AUTO) == SC_AUTO) { Entry->V.Offs = Offs; } else if ((Flags & SC_REGISTER) == SC_REGISTER) { Entry->V.R.RegOffs = Offs; @@ -1013,8 +1040,6 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs /* Generate the assembler name from the label number */ Entry->V.L.Label = Offs; Entry->AsmName = xstrdup (LocalLabelName (Entry->V.L.Label)); - } else if ((Flags & SC_STRUCTFIELD) == SC_STRUCTFIELD) { - Entry->V.Offs = Offs; } else { Internal ("Invalid flags in AddLocalSym: %04X", Flags); } diff --git a/src/cc65/symtab.h b/src/cc65/symtab.h index dd4b3aa37..79f656f95 100644 --- a/src/cc65/symtab.h +++ b/src/cc65/symtab.h @@ -133,8 +133,11 @@ SymEntry* FindLocalSym (const char* Name); SymEntry* FindTagSym (const char* Name); /* Find the symbol with the given name in the tag table */ -SymEntry* FindStructField (const Type* TypeArray, const char* Name); -/* Find a struct/union field in the fields list */ +SymEntry FindStructField (const Type* TypeArray, const char* Name); +/* Find a struct/union field in the fields list. +** Return the info about the found field symbol filled in an entry struct by +** value, or an empty entry struct if the field is not found. +*/ unsigned short FindSPAdjustment (const char* Name); /* Search for an entry in the table of SP adjustments */ From 9075a853dc919e2d028b4cf67af61183555dad13 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 29 Jul 2020 15:09:53 +0800 Subject: [PATCH 1502/2161] Allows one trailing comma before the closing curly of a struct/union initializer. --- src/cc65/declare.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index a1d23c20b..0c489dab4 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2230,6 +2230,13 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) /* Check for excess elements */ if (Entry == 0) { + /* Is there just one trailing comma before a closing curly? */ + if (NextTok.Tok == TOK_RCURLY && CurTok.Tok == TOK_COMMA) { + /* Skip comma and exit scope */ + NextToken (); + break; + } + if (HasCurly) { Error ("Excess elements in %s initializer", GetBasicTypeName (T)); SkipInitializer (HasCurly); From 8a511bb63ddcfefa71700bada01a02cd863396a0 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 29 Jul 2020 15:09:53 +0800 Subject: [PATCH 1503/2161] Fixed nested array initializers. --- src/cc65/declare.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c489dab4..c15041cbf 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2092,6 +2092,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) /* Parse initializaton for arrays. Return the number of data bytes. */ { int Count; + int HasCurly = 0; /* Get the array data */ Type* ElementType = GetElementType (T); @@ -2144,8 +2145,12 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) } else { - /* Curly brace */ - ConsumeLCurly (); + /* Arrays can be initialized without a pair of curly braces */ + if (*Braces == 0 || CurTok.Tok == TOK_LCURLY) { + /* Consume the opening curly brace */ + HasCurly = ConsumeLCurly (); + *Braces += HasCurly; + } /* Initialize the array members */ Count = 0; @@ -2161,8 +2166,10 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) NextToken (); } - /* Closing curly braces */ - ConsumeRCurly (); + if (HasCurly) { + /* Closing curly braces */ + ConsumeRCurly (); + } } if (ElementCount == UNSPECIFIED) { @@ -2176,7 +2183,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) ElementCount = Count; } else if (Count < ElementCount) { g_zerobytes ((ElementCount - Count) * ElementSize); - } else if (Count > ElementCount) { + } else if (Count > ElementCount && HasCurly) { Error ("Excess elements in array initializer"); } return ElementCount * ElementSize; From e38f601fcc5db52355a2c8afb498723699c6e3bf Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 29 Jul 2020 15:09:53 +0800 Subject: [PATCH 1504/2161] Fixed padding at the ends of structs with bit-fields. --- src/cc65/declare.c | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index c15041cbf..9e77ea63e 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -717,6 +717,29 @@ static int ParseFieldWidth (Declaration* Decl) +static unsigned PadWithBitField (unsigned StructSize, unsigned BitOffs) +/* Pad the current struct with an anonymous bit-field aligned to the next byte. +** Return how many bits are used to pad. +*/ +{ + /* MSVC complains about unary negation of unsigned, + ** so it has been rewritten as subtraction. + */ + unsigned PaddingBits = (0 - BitOffs) % CHAR_BITS; + + /* We need an anonymous name */ + ident Ident; + AnonName (Ident, "bit-field"); + + /* Add an anonymous bit-field that aligns to the next + ** byte. + */ + AddBitField (Ident, StructSize, BitOffs, PaddingBits); + + return PaddingBits; +} + + static unsigned AliasAnonStructFields (const Declaration* Decl, SymEntry* Anon) /* Create alias fields from an anon union/struct in the current lexical level. ** The function returns the count of created aliases. @@ -919,7 +942,6 @@ static SymEntry* ParseStructDecl (const char* Name) while (1) { Declaration Decl; - ident Ident; /* If we had a flexible array member before, no other fields can ** follow. @@ -942,19 +964,10 @@ static SymEntry* ParseStructDecl (const char* Name) */ if (BitOffs > 0) { if (FieldWidth <= 0 || (BitOffs + FieldWidth) > INT_BITS) { - /* Bits needed to byte-align the next field. - ** MSVC complains about unary negation of unsigned, - ** so it has been rewritten as subtraction. - */ - unsigned PaddingBits = (0 - BitOffs) % CHAR_BITS; - - /* We need an anonymous name */ - AnonName (Ident, "bit-field"); - /* Add an anonymous bit-field that aligns to the next ** byte. */ - AddBitField (Ident, StructSize, BitOffs, PaddingBits); + unsigned PaddingBits = PadWithBitField (StructSize, BitOffs); /* No bits left */ StructSize += (BitOffs + PaddingBits) / CHAR_BITS; @@ -1039,9 +1052,12 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { ConsumeSemi (); } - /* If we have bits from bit-fields left, add them to the size. */ if (BitOffs > 0) { - StructSize += ((BitOffs + CHAR_BITS - 1) / CHAR_BITS); + /* If we have bits from bit-fields left, pad the struct to next byte */ + unsigned PaddingBits = PadWithBitField (StructSize, BitOffs); + + /* No bits left */ + StructSize += (BitOffs + PaddingBits) / CHAR_BITS; } /* Skip the closing brace */ From 2d5fd0fc6301ab0d0ee4cb3517f9e0c9dce540a5 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Thu, 30 Jul 2020 12:00:21 +0200 Subject: [PATCH 1505/2161] Use char ops if possible for bit-field loads Set CF_FORCECHAR and change type to char once we have shifted into a char. This saves some unnecessary ldx #0 instructions. --- src/cc65/loadexpr.c | 20 +++++++++- test/val/bitfield.c | 92 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 2 deletions(-) diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index bc0ee1dd0..807a5cbe5 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -193,10 +193,26 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) ** operations. */ if (ED_IsBitField (Expr)) { - unsigned F = CF_INT | CF_UNSIGNED | CF_CONST | (Flags & CF_TEST); + /* If the field was loaded as a char, force the shift/mask ops to be char ops. + ** If it is a char, the load has already put 0 in the upper byte, so that can remain. + ** CF_FORCECHAR does nothing if the type is not CF_CHAR. + */ + unsigned F = Flags | CF_FORCECHAR | CF_CONST; + /* Shift right by the bit offset */ g_asr (F, Expr->BitOffs); - /* And by the width if the field doesn't end on an int boundary */ + + /* Since we have now shifted down, we can do char ops as long as the width fits in + ** a char. + */ + if (Expr->BitWidth <= CHAR_BITS) { + F |= CF_CHAR; + } + + /* And by the width if the field doesn't end on a char or int boundary. If it does + ** end on a boundary, then zeros have already been shifted in. g_and emits no code + ** if the mask is all ones. + */ if (Expr->BitOffs + Expr->BitWidth != CHAR_BITS && Expr->BitOffs + Expr->BitWidth != INT_BITS) { g_and (F, (0x0001U << Expr->BitWidth) - 1U); diff --git a/test/val/bitfield.c b/test/val/bitfield.c index 81d5b2aa1..67747ed5b 100644 --- a/test/val/bitfield.c +++ b/test/val/bitfield.c @@ -182,12 +182,104 @@ static void test_overlap_with_int(void) } } +static struct full_width { + unsigned int x : 8; + unsigned int y : 16; +} fw = {255, 17}; + +static void test_full_width(void) +{ + if (sizeof(struct full_width) != 3) { + printf("Got sizeof(struct full_width) = %zu, expected 3.\n", + sizeof(struct full_width)); + failures++; + } + + if (fw.x != 255) { + printf("Got fw.x = %u, expected 255.\n", fw.x); + failures++; + } + + if (fw.y != 17) { + printf("Got fw.y = %u, expected 17.\n", fw.y); + failures++; + } + + fw.x = 42; + fw.y = 1023; + + if (fw.x != 42) { + printf("Got fw.x = %u, expected 42.\n", fw.x); + failures++; + } + + if (fw.y != 1023) { + printf("Got fw.y = %u, expected 1023.\n", fw.y); + failures++; + } +} + +static struct aligned_end { + unsigned int : 2; + unsigned int x : 6; + unsigned int : 3; + unsigned int y : 13; + /* z crosses a byte boundary, but fits in a byte when shifted. */ + unsigned int : 6; + unsigned int z : 7; +} ae = {63, 17, 100}; + +static void test_aligned_end(void) +{ + if (sizeof(struct aligned_end) != 5) { + printf("Got sizeof(struct aligned_end) = %zu, expected 5.\n", + sizeof(struct aligned_end)); + failures++; + } + + if (ae.x != 63) { + printf("Got ae.x = %u, expected 63.\n", ae.x); + failures++; + } + + if (ae.y != 17) { + printf("Got ae.y = %u, expected 17.\n", ae.y); + failures++; + } + + if (ae.z != 100) { + printf("Got ae.z = %u, expected 100.\n", ae.z); + failures++; + } + + ae.x = 42; + ae.y = 1023; + ae.z = 66; + + if (ae.x != 42) { + printf("Got ae.x = %u, expected 42.\n", ae.x); + failures++; + } + + if (ae.y != 1023) { + printf("Got ae.y = %u, expected 1023.\n", ae.y); + failures++; + } + + if (ae.z != 66) { + printf("Got ae.z = %u, expected 66.\n", ae.z); + failures++; + } +} + int main(void) { test_four_bits(); test_four_bits_with_int(); test_overlap(); test_overlap_with_int(); + test_full_width(); + test_aligned_end(); printf("failures: %u\n", failures); return failures; } From c72fa735b96a832852e2b7f60c3677463e3f8f20 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Thu, 30 Jul 2020 17:21:56 +0200 Subject: [PATCH 1506/2161] Add test for #1139 --- test/todo/bug1139.c | 52 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 test/todo/bug1139.c diff --git a/test/todo/bug1139.c b/test/todo/bug1139.c new file mode 100644 index 000000000..222a9ab51 --- /dev/null +++ b/test/todo/bug1139.c @@ -0,0 +1,52 @@ +/* + Copyright 2020 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. +*/ + +/* + Tests bit-field in if condition; see https://github.com/cc65/cc65/issues/1139 +*/ + +#include <stdio.h> + +static unsigned char failures = 0; + +static struct overlap { + unsigned int x : 10; + unsigned int y : 10; +} o = {11, 22}; + +/* Test using bit-fields in if conditions. */ +static void test_if(void) +{ + o.x = 0; + o.y = 44; + if (o.x) { + printf("Bad, o.x is false\n"); + failures++; + } else { + printf("Good\n"); + } +} + +int main(void) +{ + test_if(); + printf("failures: %u\n", failures); + return failures; +} From 3df6c383c0b9c387ef5d9be8f6fe479ce714c51f Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sun, 26 Jul 2020 22:16:47 +0200 Subject: [PATCH 1507/2161] Add support for static_assert Add C11's _Static_assert and static_assert macro. This is like #error, but is handled at a later stage of translation, so it is possible to check sizes of types, values of enums, etc. https://en.cppreference.com/w/c/language/_Static_assert https://port70.net/~nsz/c/c11/n1570.html#6.7.10 --- include/assert.h | 6 +++ src/cc65/compile.c | 7 +++ src/cc65/declare.c | 8 ++++ src/cc65/locals.c | 8 ++++ src/cc65/scanner.c | 1 + src/cc65/scanner.h | 1 + src/cc65/staticassert.c | 96 +++++++++++++++++++++++++++++++++++++++++ src/cc65/staticassert.h | 51 ++++++++++++++++++++++ test/err/staticassert.c | 26 +++++++++++ test/val/staticassert.c | 70 ++++++++++++++++++++++++++++++ 10 files changed, 274 insertions(+) create mode 100644 src/cc65/staticassert.c create mode 100644 src/cc65/staticassert.h create mode 100644 test/err/staticassert.c create mode 100644 test/val/staticassert.c diff --git a/include/assert.h b/include/assert.h index 504964dc2..3f8b46ac0 100644 --- a/include/assert.h +++ b/include/assert.h @@ -46,6 +46,12 @@ extern void __fastcall__ _afailed (const char*, unsigned); # define assert(expr) ((expr)? (void)0 : _afailed(__FILE__, __LINE__)) #endif +/* +** TODO: Guard with #if __STDC_VERSION__ >= 201112L or similar when there +** is a C11 mode. +*/ +#define static_assert _Static_assert + /* End of assert.h */ diff --git a/src/cc65/compile.c b/src/cc65/compile.c index f7e4bd35d..3d2f82c51 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -61,6 +61,7 @@ #include "pragma.h" #include "preproc.h" #include "standard.h" +#include "staticassert.h" #include "symtab.h" @@ -108,6 +109,12 @@ static void Parse (void) continue; } + /* Check for a _Static_assert */ + if (CurTok.Tok == TOK_STATIC_ASSERT) { + ParseStaticAssert (); + continue; + } + /* Read variable defs and functions */ ParseDeclSpec (&Spec, SC_EXTERN | SC_STATIC, T_INT); diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 9e77ea63e..ada3ddaae 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -58,6 +58,7 @@ #include "pragma.h" #include "scanner.h" #include "standard.h" +#include "staticassert.h" #include "symtab.h" #include "wrappedcall.h" #include "typeconv.h" @@ -935,6 +936,13 @@ static SymEntry* ParseStructDecl (const char* Name) /* Get the type of the entry */ DeclSpec Spec; + + /* Check for a _Static_assert */ + if (CurTok.Tok == TOK_STATIC_ASSERT) { + ParseStaticAssert (); + continue; + } + InitDeclSpec (&Spec); ParseTypeSpec (&Spec, -1, T_QUAL_NONE); diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 0007879d8..3fa26021f 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -50,6 +50,7 @@ #include "locals.h" #include "stackptr.h" #include "standard.h" +#include "staticassert.h" #include "symtab.h" #include "typeconv.h" #include "input.h" @@ -511,6 +512,13 @@ void DeclareLocals (void) ** declarations. */ DeclSpec Spec; + + /* Check for a _Static_assert */ + if (CurTok.Tok == TOK_STATIC_ASSERT) { + ParseStaticAssert (); + continue; + } + ParseDeclSpec (&Spec, SC_AUTO, T_INT); if ((Spec.Flags & DS_DEF_STORAGE) != 0 && /* No storage spec */ (Spec.Flags & DS_DEF_TYPE) != 0 && /* No type given */ diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 5040cdf08..70203d027 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -86,6 +86,7 @@ static const struct Keyword { unsigned char Std; /* Token supported in which standards? */ } Keywords [] = { { "_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 }, { "__A__", TOK_A, TT_C89 | TT_C99 | TT_CC65 }, { "__EAX__", TOK_EAX, TT_C89 | TT_C99 | TT_CC65 }, diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1242d78fd..1c95b3d33 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -173,6 +173,7 @@ typedef enum token_t { TOK_WCSCONST, TOK_ATTRIBUTE, + TOK_STATIC_ASSERT, TOK_FAR, TOK_NEAR, TOK_A, diff --git a/src/cc65/staticassert.c b/src/cc65/staticassert.c new file mode 100644 index 000000000..d7e608b06 --- /dev/null +++ b/src/cc65/staticassert.c @@ -0,0 +1,96 @@ +/*****************************************************************************/ +/* */ +/* staticassert.h */ +/* */ +/* _Static_assert handling for the cc65 C compiler */ +/* */ +/* */ +/* */ +/* Copyright 2020 Google LLC */ +/* */ +/* */ +/* 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. */ +/* */ +/*****************************************************************************/ + + + +/* cc65 */ +#include "error.h" +#include "expr.h" +#include "litpool.h" +#include "scanner.h" +#include "staticassert.h" + + + +/*****************************************************************************/ +/* _Static_assert handling functions */ +/*****************************************************************************/ + + + +void ParseStaticAssert () +{ + /* + ** static_assert-declaration ::= + ** _Static_assert ( constant-expression , string-literal ) ; + */ + ExprDesc Expr; + int failed; + + /* Skip the _Static_assert token itself */ + CHECK (CurTok.Tok == TOK_STATIC_ASSERT); + NextToken (); + + /* We expect an opening paren */ + if (!ConsumeLParen ()) { + return; + } + + /* Parse assertion condition */ + ConstAbsIntExpr (hie1, &Expr); + failed = !Expr.IVal; + + /* We expect a comma */ + if (!ConsumeComma ()) { + return; + } + + /* String literal */ + if (CurTok.Tok != TOK_SCONST) { + Error ("String literal expected for static_assert message"); + return; + } + + /* 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; + } + + /* Closing paren and semi-colon needed */ + ConsumeRParen (); + ConsumeSemi (); +} diff --git a/src/cc65/staticassert.h b/src/cc65/staticassert.h new file mode 100644 index 000000000..955255bfe --- /dev/null +++ b/src/cc65/staticassert.h @@ -0,0 +1,51 @@ +/*****************************************************************************/ +/* */ +/* staticassert.h */ +/* */ +/* _Static_assert handling for the cc65 C compiler */ +/* */ +/* */ +/* */ +/* Copyright 2020 Google LLC */ +/* */ +/* */ +/* 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 STATICASSERT_H +#define STATICASSERT_H + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +void ParseStaticAssert (void); +/* Handle _Static_assert. These are a C11 feature. */ + + + +/* End of staticassert.h */ + +#endif diff --git a/test/err/staticassert.c b/test/err/staticassert.c new file mode 100644 index 000000000..df9bab6d8 --- /dev/null +++ b/test/err/staticassert.c @@ -0,0 +1,26 @@ +/* + Copyright 2020 Google LLC + + 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 failing _Static_assert. +**/ + + +_Static_assert(0, "0 should be false."); diff --git a/test/val/staticassert.c b/test/val/staticassert.c new file mode 100644 index 000000000..a02ba27e8 --- /dev/null +++ b/test/val/staticassert.c @@ -0,0 +1,70 @@ +/* + Copyright 2020 Google LLC + + 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. +*/ + +/* +** Tests of passing _Static_asserts. +**/ + + + +#include <assert.h> + +_Static_assert (1, "1 should be true."); +_Static_assert (!0, "!0 should be true."); +_Static_assert (1 == 1, "1 == 1 should be true."); +_Static_assert (1 == 1L, "1 == 1L should be true."); +_Static_assert (1 != 0, "1 != 0 should be true."); +_Static_assert (sizeof (char) == 1, "sizeof (char) should be 1."); +_Static_assert (sizeof (int) == 2, "sizeof (int) should be 2."); + +/* Make sure we can also do structs. */ +struct sc { char a; }; +_Static_assert (sizeof (struct sc) == 1, "sizeof (struct sc) should be 1."); +struct si { int a; }; +_Static_assert (sizeof (struct si) == 2, "sizeof (struct si) should be 2."); + +/* Try enums. */ +enum { k = 1 }; +_Static_assert (k == 1, "k should be 1."); + +/* Just test the macro version once. */ +static_assert (1, "1 should be true."); + +/* _Static_assert can appear anywhere a declaration can. */ +void f (void) +{ + _Static_assert (1, "1 should still be true."); + if (1) { + _Static_assert (1, "1 should still be true."); + } +} + +/* _Static_assert can also appear in structs. */ +struct S { + int a; + _Static_assert (1, "1 should still be true."); + int b; +}; + + +int main (void) +{ + return 0; +} From d0c7108dcf64403d4256372ed9b5a1faa7b76c14 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Thu, 30 Jul 2020 13:27:57 +0200 Subject: [PATCH 1508/2161] Change copyright notice to "The cc65 Authors" --- src/cc65/staticassert.c | 2 +- src/cc65/staticassert.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65/staticassert.c b/src/cc65/staticassert.c index d7e608b06..95a2d4a6e 100644 --- a/src/cc65/staticassert.c +++ b/src/cc65/staticassert.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* Copyright 2020 Google LLC */ +/* Copyright 2020 The cc65 Authors */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ diff --git a/src/cc65/staticassert.h b/src/cc65/staticassert.h index 955255bfe..cf6314424 100644 --- a/src/cc65/staticassert.h +++ b/src/cc65/staticassert.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* Copyright 2020 Google LLC */ +/* Copyright 2020 The cc65 Authors */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ From 847982c6bf1323f801140b71f16d0477cb19ea7e Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Fri, 31 Jul 2020 08:41:05 +0200 Subject: [PATCH 1509/2161] Handle bit-field test after shift/mask Previously, bit-field tests were incorrectly combined with load in `if (x.bitfield)`. Delay the test until after the shift/mask is done. Still combine tests with load if no shift/mask is required. Fixes #1139 --- src/cc65/loadexpr.c | 77 +++++++--- test/todo/bug1139.c | 52 ------- test/val/bug1139.c | 353 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 409 insertions(+), 73 deletions(-) delete mode 100644 test/todo/bug1139.c create mode 100644 test/val/bug1139.c diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index 807a5cbe5..394e0a562 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -33,6 +33,8 @@ +#include <limits.h> + /* cc65 */ #include "codegen.h" #include "error.h" @@ -113,13 +115,23 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) ** field is completely contained in the lower byte, we will throw away ** the high byte anyway and may therefore load just the low byte. */ + unsigned EndBit = 0; /* End bit for bit-fields, or zero if non-bit-field. */ + int AdjustBitField = 0; if (ED_IsBitField (Expr)) { - Flags |= (Expr->BitOffs + Expr->BitWidth <= CHAR_BITS) ? CF_CHAR : CF_INT; + EndBit = Expr->BitOffs + Expr->BitWidth; + AdjustBitField = Expr->BitOffs != 0 || (EndBit != CHAR_BITS && EndBit != INT_BITS); + + Flags |= (EndBit <= CHAR_BITS) ? CF_CHAR : CF_INT; Flags |= CF_UNSIGNED; } else if ((Flags & CF_TYPEMASK) == 0) { Flags |= TypeOf (Expr->Type); } - if (ED_NeedsTest (Expr)) { + + /* Setting CF_TEST will cause the load to perform optimizations and not actually load all + ** bits of the bit-field, instead just computing the condition codes. Therefore, if + ** adjustment is required, we do not set CF_TEST here, but handle it below. + */ + if (ED_NeedsTest (Expr) && !AdjustBitField) { Flags |= CF_TEST; } @@ -188,34 +200,57 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) Internal ("Invalid location in LoadExpr: 0x%04X", ED_GetLoc (Expr)); } - /* Handle bit fields. The actual type may have been casted or - ** converted, so be sure to always use unsigned ints for the - ** operations. + /* Handle bit fields if necessary. The actual type may have been casted or converted, + ** so be sure to always use unsigned ints for the operations. */ - if (ED_IsBitField (Expr)) { + if (AdjustBitField) { /* If the field was loaded as a char, force the shift/mask ops to be char ops. ** If it is a char, the load has already put 0 in the upper byte, so that can remain. ** CF_FORCECHAR does nothing if the type is not CF_CHAR. */ unsigned F = Flags | CF_FORCECHAR | CF_CONST; - /* Shift right by the bit offset */ - g_asr (F, Expr->BitOffs); - - /* Since we have now shifted down, we can do char ops as long as the width fits in - ** a char. + /* We always need to do something with the low byte, so there is no opportunity + ** for optimization by skipping it. */ - if (Expr->BitWidth <= CHAR_BITS) { - F |= CF_CHAR; - } + CHECK (Expr->BitOffs < CHAR_BITS); - /* And by the width if the field doesn't end on a char or int boundary. If it does - ** end on a boundary, then zeros have already been shifted in. g_and emits no code - ** if the mask is all ones. - */ - if (Expr->BitOffs + Expr->BitWidth != CHAR_BITS && - Expr->BitOffs + Expr->BitWidth != INT_BITS) { - g_and (F, (0x0001U << Expr->BitWidth) - 1U); + if (ED_NeedsTest (Expr)) { + /* If we need to do a test, then we avoid shifting (ASR only shifts one bit + ** at a time, so is slow) and just AND with the appropriate mask, then test + ** the result of that. + */ + + /* Avoid overly large shift. */ + if (EndBit == sizeof (unsigned long) * CHAR_BIT) { + g_and (F, (~0UL << Expr->BitOffs)); + } else { + g_and (F, ((1UL << EndBit) - 1) & (~0UL << Expr->BitOffs)); + } + + /* TODO: When long bit-fields are supported, an optimization to test only 3 bytes + ** when EndBit <= 24 is possible. + */ + g_test (F); + ED_TestDone (Expr); + } else { + /* Shift right by the bit offset; no code is emitted if BitOffs is zero */ + g_asr (F, Expr->BitOffs); + + /* Since we have now shifted down, we can do char ops as long as the width fits in + ** a char. + */ + if (Expr->BitWidth <= CHAR_BITS) { + F |= CF_CHAR; + } + + /* And by the width if the field doesn't end on a char or int boundary. + ** If it does end on a boundary, then zeros have already been shifted in. + ** g_and emits no code if the mask is all ones. + */ + if (EndBit != CHAR_BITS && EndBit != INT_BITS) { + g_and (F, (0x0001U << Expr->BitWidth) - 1U); + } } } diff --git a/test/todo/bug1139.c b/test/todo/bug1139.c deleted file mode 100644 index 222a9ab51..000000000 --- a/test/todo/bug1139.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright 2020 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. -*/ - -/* - Tests bit-field in if condition; see https://github.com/cc65/cc65/issues/1139 -*/ - -#include <stdio.h> - -static unsigned char failures = 0; - -static struct overlap { - unsigned int x : 10; - unsigned int y : 10; -} o = {11, 22}; - -/* Test using bit-fields in if conditions. */ -static void test_if(void) -{ - o.x = 0; - o.y = 44; - if (o.x) { - printf("Bad, o.x is false\n"); - failures++; - } else { - printf("Good\n"); - } -} - -int main(void) -{ - test_if(); - printf("failures: %u\n", failures); - return failures; -} diff --git a/test/val/bug1139.c b/test/val/bug1139.c new file mode 100644 index 000000000..5aef3924d --- /dev/null +++ b/test/val/bug1139.c @@ -0,0 +1,353 @@ +/* + Copyright 2020 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. +*/ + +/* + Tests bit-field in if condition; see https://github.com/cc65/cc65/issues/1139 +*/ + +#include <stdio.h> + +static unsigned char failures = 0; + +static struct four_bits { + unsigned int x : 4; +} fb = {1}; + +static struct overlap { + unsigned int x : 10; + unsigned int y : 10; +} o = {11, 22}; + +static struct full_width { + unsigned int x : 8; + unsigned int y : 16; +} fw = {255, 17}; + +static struct aligned_end { + unsigned int : 2; + unsigned int x : 6; + unsigned int : 3; + unsigned int y : 13; + /* z crosses a byte boundary, but fits in a byte when shifted. */ + unsigned int : 6; + unsigned int z : 7; +} ae = {63, 17, 100}; + +/* Test using bit-fields in if conditions. */ +static void test_if(void) +{ + /* Original test case for the bug. */ + o.x = 0; + o.y = 44; + if (o.x) { + printf("Bad, o.x is false\n"); + failures++; + } else { + printf("Good\n"); + } + + /* Additionally, test most fields from bitfield.c to try to cover all start/end situations. */ + /* four_bits */ + fb.x = 1; + if (fb.x) { + printf("Good\n"); + } else { + printf("Bad, fb.x is true (1)\n"); + failures++; + } + + fb.x = 0; + if (fb.x) { + printf("Bad, fb.x is false\n"); + failures++; + } else { + printf("Good\n"); + } + + /* overlap */ + o.x = 123; + if (o.x) { + printf("Good\n"); + } else { + printf("Bad, o.x is true (123)\n"); + failures++; + } + + o.x = 0; + if (o.x) { + printf("Bad, o.x is false\n"); + failures++; + } else { + printf("Good\n"); + } + + o.y = 321; + if (o.y) { + printf("Good\n"); + } else { + printf("Bad, o.y is true (321)\n"); + failures++; + } + + o.y = 0; + if (o.y) { + printf("Bad, o.y is false\n"); + failures++; + } else { + printf("Good\n"); + } + + /* full_width */ + fw.x = 117; + if (fw.x) { + printf("Good\n"); + } else { + printf("Bad, fw.x is true (117)\n"); + failures++; + } + + fw.x = 0; + if (fw.x) { + printf("Bad, fw.x is false\n"); + failures++; + } else { + printf("Good\n"); + } + + fw.y = 32123; + if (fw.y) { + printf("Good\n"); + } else { + printf("Bad, fw.y is true (32123)\n"); + failures++; + } + + fw.y = 0; + if (fw.y) { + printf("Bad, fw.y is false\n"); + failures++; + } else { + printf("Good\n"); + } + + /* aligned_end */ + ae.x = 2; + if (ae.x) { + printf("Good\n"); + } else { + printf("Bad, ae.x is true (2)\n"); + failures++; + } + + ae.x = 0; + if (ae.x) { + printf("Bad, ae.x is false\n"); + failures++; + } else { + printf("Good\n"); + } + + ae.y = 2222; + if (ae.y) { + printf("Good\n"); + } else { + printf("Bad, ae.y is true (2222)\n"); + failures++; + } + + ae.y = 0; + if (ae.y) { + printf("Bad, ae.y is false\n"); + failures++; + } else { + printf("Good\n"); + } + + ae.z = 111; + if (ae.z) { + printf("Good\n"); + } else { + printf("Bad, ae.z is true (111)\n"); + failures++; + } + + ae.z = 0; + if (ae.z) { + printf("Bad, ae.z is false\n"); + failures++; + } else { + printf("Good\n"); + } +} + +/* Test using bit-fields in inverted if conditions. */ +static void test_if_not(void) +{ + /* Original test case for the bug, inverted. */ + o.x = 0; + o.y = 44; + if (!o.x) { + printf("Good\n"); + } else { + printf("Bad, o.x is false\n"); + failures++; + } + + /* Additionally, test most fields from bitfield.c to try to cover all start/end situations. */ + /* four_bits */ + fb.x = 1; + if (!fb.x) { + printf("Bad, fb.x is true (1)\n"); + failures++; + } else { + printf("Good\n"); + } + + fb.x = 0; + if (!fb.x) { + printf("Good\n"); + } else { + printf("Bad, fb.x is false\n"); + failures++; + } + + /* overlap */ + o.x = 123; + if (!o.x) { + printf("Bad, o.x is true (123)\n"); + failures++; + } else { + printf("Good\n"); + } + + o.x = 0; + if (!o.x) { + printf("Good\n"); + } else { + printf("Bad, o.x is false\n"); + failures++; + } + + o.y = 321; + if (!o.y) { + printf("Bad, o.y is true (321)\n"); + failures++; + } else { + printf("Good\n"); + } + + o.y = 0; + if (!o.y) { + printf("Good\n"); + } else { + printf("Bad, o.y is false\n"); + failures++; + } + + /* full_width */ + fw.x = 117; + if (!fw.x) { + printf("Bad, fw.x is true (117)\n"); + failures++; + } else { + printf("Good\n"); + } + + fw.x = 0; + if (!fw.x) { + printf("Good\n"); + } else { + printf("Bad, fw.x is false\n"); + failures++; + } + + fw.y = 32123; + if (!fw.y) { + printf("Bad, fw.y is true (32123)\n"); + failures++; + } else { + printf("Good\n"); + } + + fw.y = 0; + if (!fw.y) { + printf("Good\n"); + } else { + printf("Bad, fw.y is false\n"); + failures++; + } + + /* aligned_end */ + ae.x = 2; + if (!ae.x) { + printf("Bad, ae.x is true (2)\n"); + failures++; + } else { + printf("Good\n"); + } + + ae.x = 0; + if (!ae.x) { + printf("Good\n"); + } else { + printf("Bad, ae.x is false\n"); + failures++; + } + + ae.y = 2222; + if (!ae.y) { + printf("Bad, ae.y is true (2222)\n"); + failures++; + } else { + printf("Good\n"); + } + + ae.y = 0; + if (!ae.y) { + printf("Good\n"); + } else { + printf("Bad, ae.y is false\n"); + failures++; + } + + ae.z = 111; + if (!ae.z) { + printf("Bad, ae.z is true (111)\n"); + failures++; + } else { + printf("Good\n"); + } + + ae.z = 0; + if (!ae.z) { + printf("Good\n"); + } else { + printf("Bad, ae.z is false\n"); + failures++; + } +} + +int main(void) +{ + test_if(); + test_if_not(); + printf("failures: %u\n", failures); + return failures; +} From 9c70bd44a6fecf99aefe888f95e0645b82324b24 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Fri, 31 Jul 2020 16:52:22 +0200 Subject: [PATCH 1510/2161] Clarify comment about large shift This is to avoid overflow on host platform. --- src/cc65/loadexpr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index 394e0a562..15be997df 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -221,7 +221,7 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) ** the result of that. */ - /* Avoid overly large shift. */ + /* Avoid overly large shift on host platform. */ if (EndBit == sizeof (unsigned long) * CHAR_BIT) { g_and (F, (~0UL << Expr->BitOffs)); } else { From e1043fac12151cdec415e76d78e23114d8f0b070 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 1 Aug 2020 10:55:49 +0200 Subject: [PATCH 1511/2161] Adjusted to https://github.com/cc65/cc65/pull/1124. --- src/cc65.vcxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index a56ecf880..d566c8bc1 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -135,6 +135,7 @@ <ClInclude Include="cc65\shiftexpr.h" /> <ClInclude Include="cc65\stackptr.h" /> <ClInclude Include="cc65\standard.h" /> + <ClInclude Include="cc65\staticassert.h" /> <ClInclude Include="cc65\stdfunc.h" /> <ClInclude Include="cc65\stdnames.h" /> <ClInclude Include="cc65\stmt.h" /> @@ -209,6 +210,7 @@ <ClCompile Include="cc65\shiftexpr.c" /> <ClCompile Include="cc65\stackptr.c" /> <ClCompile Include="cc65\standard.c" /> + <ClCompile Include="cc65\staticassert.c" /> <ClCompile Include="cc65\stdfunc.c" /> <ClCompile Include="cc65\stdnames.c" /> <ClCompile Include="cc65\stmt.c" /> From 633cd17a3e8df1f20fd918a1529b61049efa0594 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sat, 1 Aug 2020 22:30:36 +0200 Subject: [PATCH 1512/2161] Add enum size test case for #1050 --- test/val/bug1050.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 test/val/bug1050.c diff --git a/test/val/bug1050.c b/test/val/bug1050.c new file mode 100644 index 000000000..af9e4f6b2 --- /dev/null +++ b/test/val/bug1050.c @@ -0,0 +1,32 @@ +/* + Copyright 2020 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. +*/ + +/* + Tests enum sizes; see https://github.com/cc65/cc65/issues/1050 +*/ + +enum e { k }; +_Static_assert(sizeof(enum e) == 1, "This should fit in a byte."); +_Static_assert(sizeof(k) == 2, "Enumerators are still ints."); + +int main (void) +{ + return 0; +} From e526cbbff6c2588287dad7af94b3f2326300fd58 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 1 Aug 2020 22:08:19 +0800 Subject: [PATCH 1513/2161] Fixed handling multiple storage specifiers in one declaration. --- src/cc65/declare.c | 89 +++++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 32 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index ada3ddaae..a525e1f86 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -410,6 +410,48 @@ static void FixQualifiers (Type* DataType) +static unsigned ParseOneStorageClass (void) +/* Parse and return a storage class */ +{ + unsigned StorageClass = 0; + + /* Check the storage class given */ + switch (CurTok.Tok) { + + case TOK_EXTERN: + StorageClass = SC_EXTERN | SC_STATIC; + NextToken (); + break; + + case TOK_STATIC: + StorageClass = SC_STATIC; + NextToken (); + break; + + case TOK_REGISTER: + StorageClass = SC_REGISTER | SC_STATIC; + NextToken (); + break; + + case TOK_AUTO: + StorageClass = SC_AUTO; + NextToken (); + break; + + case TOK_TYPEDEF: + StorageClass = SC_TYPEDEF; + NextToken (); + break; + + default: + break; + } + + return StorageClass; +} + + + static void ParseStorageClass (DeclSpec* D, unsigned DefStorage) /* Parse a storage class */ { @@ -417,38 +459,21 @@ static void ParseStorageClass (DeclSpec* D, unsigned DefStorage) D->Flags &= ~DS_DEF_STORAGE; /* Check the storage class given */ - switch (CurTok.Tok) { - - case TOK_EXTERN: - D->StorageClass = SC_EXTERN | SC_STATIC; - NextToken (); - break; - - case TOK_STATIC: - D->StorageClass = SC_STATIC; - NextToken (); - break; - - case TOK_REGISTER: - D->StorageClass = SC_REGISTER | SC_STATIC; - NextToken (); - break; - - case TOK_AUTO: - D->StorageClass = SC_AUTO; - NextToken (); - break; - - case TOK_TYPEDEF: - D->StorageClass = SC_TYPEDEF; - NextToken (); - break; - - default: - /* No storage class given, use default */ - D->Flags |= DS_DEF_STORAGE; - D->StorageClass = DefStorage; - break; + D->StorageClass = ParseOneStorageClass (); + if (D->StorageClass == 0) { + /* No storage class given, use default */ + D->Flags |= DS_DEF_STORAGE; + D->StorageClass = DefStorage; + } else { + unsigned StorageClass = ParseOneStorageClass (); + while (StorageClass != 0) { + if (D->StorageClass == StorageClass) { + Warning ("Duplicate storage class specifier"); + } else { + Error ("Conflicting storage class specifier"); + } + StorageClass = ParseOneStorageClass (); + } } } From 30fd8592ae6332b9b4eaa64abd87c11d81f2d586 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 1 Aug 2020 22:06:14 +0800 Subject: [PATCH 1514/2161] Avoid internal errors when using function-type objects in expressions. --- src/cc65/datatype.c | 19 ++++++++++++++++++- src/cc65/datatype.h | 3 +++ src/cc65/expr.c | 6 +++--- src/cc65/function.c | 2 +- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 1e2859ba7..18dd0a6b1 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -732,7 +732,8 @@ unsigned TypeOf (const Type* T) return CF_FLOAT; case T_FUNC: - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC)? 0 : CF_FIXARGC; + /* Treat this as a function pointer */ + return CF_INT | CF_UNSIGNED; case T_STRUCT: case T_UNION: @@ -751,6 +752,22 @@ unsigned TypeOf (const Type* T) +unsigned FuncTypeOf (const Type* T) +/* Get the code generator flag for calling the function */ +{ + switch (GetUnderlyingTypeCode (T)) { + + case T_FUNC: + return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + + default: + Error ("Illegal function type %04lX", T->C); + return 0; + } +} + + + Type* Indirect (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 1997b5c89..33c66d65d 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -323,6 +323,9 @@ unsigned CheckedPSizeOf (const Type* T); unsigned TypeOf (const Type* T); /* Get the code generator base type of the object */ +unsigned FuncTypeOf (const Type* T); +/* Get the code generator flag for calling the function */ + Type* Indirect (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. diff --git a/src/cc65/expr.c b/src/cc65/expr.c index fd8a48002..1d123ce9b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -585,7 +585,7 @@ static void FunctionCall (ExprDesc* Expr) } /* Call the function */ - g_callind (TypeOf (Expr->Type+1), ParamSize, PtrOffs); + g_callind (FuncTypeOf (Expr->Type+1), ParamSize, PtrOffs); } else { @@ -646,9 +646,9 @@ static void FunctionCall (ExprDesc* Expr) SB_Done (&S); - g_call (TypeOf (Expr->Type), Func->WrappedCall->Name, ParamSize); + g_call (FuncTypeOf (Expr->Type), Func->WrappedCall->Name, ParamSize); } else { - g_call (TypeOf (Expr->Type), (const char*) Expr->Name, ParamSize); + g_call (FuncTypeOf (Expr->Type), (const char*) Expr->Name, ParamSize); } } diff --git a/src/cc65/function.c b/src/cc65/function.c index d6e11fea3..e6a974f98 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -487,7 +487,7 @@ void NewFunc (SymEntry* Func) } /* Generate function entry code if needed */ - g_enter (TypeOf (Func->Type), F_GetParamSize (CurrentFunc)); + g_enter (FuncTypeOf (Func->Type), F_GetParamSize (CurrentFunc)); /* If stack checking code is requested, emit a call to the helper routine */ if (IS_Get (&CheckStack)) { From 2a555d198cd4bf5ac916dc77ad1c095077627551 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 2 Aug 2020 13:24:46 +0800 Subject: [PATCH 1515/2161] Changed 'switch' to 'if' according PR review comments. --- src/cc65/datatype.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 18dd0a6b1..444902e60 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -755,14 +755,11 @@ unsigned TypeOf (const Type* T) unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { - switch (GetUnderlyingTypeCode (T)) { - - case T_FUNC: - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; - - default: - Error ("Illegal function type %04lX", T->C); - return 0; + if (GetUnderlyingTypeCode (T) == T_FUNC) { + return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + } else { + Error ("Illegal function type %04lX", T->C); + return 0; } } From adda28f5c5ce8de5a7a778723361b36545dcf92e Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sun, 2 Aug 2020 09:03:21 +0200 Subject: [PATCH 1516/2161] LoadExpr: Set CF_FORCECHAR if test is required If we are testing, we do not need to load the high byte(s). --- src/cc65/loadexpr.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index 15be997df..1a6e43779 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -127,12 +127,19 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) Flags |= TypeOf (Expr->Type); } - /* Setting CF_TEST will cause the load to perform optimizations and not actually load all - ** bits of the bit-field, instead just computing the condition codes. Therefore, if - ** adjustment is required, we do not set CF_TEST here, but handle it below. - */ - if (ED_NeedsTest (Expr) && !AdjustBitField) { - Flags |= CF_TEST; + if (ED_NeedsTest (Expr)) { + /* If we're only testing, we do not need to promote char to int. + ** CF_FORCECHAR does nothing if the type is not CF_CHAR. + */ + Flags |= CF_FORCECHAR; + + /* Setting CF_TEST will cause the load to perform optimizations and not actually load + ** all bits of the bit-field, instead just computing the condition codes. Therefore, + ** if adjustment is required, we do not set CF_TEST here, but handle it below. + */ + if (!AdjustBitField) { + Flags |= CF_TEST; + } } /* Load the content of Expr */ @@ -206,7 +213,6 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) if (AdjustBitField) { /* If the field was loaded as a char, force the shift/mask ops to be char ops. ** If it is a char, the load has already put 0 in the upper byte, so that can remain. - ** CF_FORCECHAR does nothing if the type is not CF_CHAR. */ unsigned F = Flags | CF_FORCECHAR | CF_CONST; From ce19d7b84f6ad8780135d374d63377f30214bdf3 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 2 Aug 2020 15:50:17 +0200 Subject: [PATCH 1517/2161] Made use of Travis CI's Windows support. At least for now there seems to be no point in trying to build the libraries (and run the tests) on Windows. Rather we only want to check that the MSVC solution is still valid. --- .travis.yml | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 630466cc0..efeca96b4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,24 @@ -language: - - c -install: - - sudo apt-get update - - sudo apt-get install linuxdoc-tools linuxdoc-tools-info binutils-mingw-w64-i686 gcc-mingw-w64-i686 sshpass -script: - - make bin USER_CFLAGS=-Werror - - make lib QUIET=1 - - make test QUIET=1 - - make samples - - make -C src clean - - make bin USER_CFLAGS=-Werror CROSS_COMPILE=i686-w64-mingw32- - - make -C samples clean - - make doc zip -after_success: - - make -f Makefile.travis +language: c + +jobs: + include: + + - os: linux + install: + - sudo apt-get update + - sudo apt-get install linuxdoc-tools linuxdoc-tools-info binutils-mingw-w64-i686 gcc-mingw-w64-i686 sshpass + script: + - make bin USER_CFLAGS=-Werror + - make lib QUIET=1 + - make test QUIET=1 + - make samples + - make -C src clean + - make bin USER_CFLAGS=-Werror CROSS_COMPILE=i686-w64-mingw32- + - make -C samples clean + - make doc zip + after_success: + - make -f Makefile.travis + + - os: windows + script: + - MSBuild.exe scr/cc65.sln From 992596c981a3027b1d9320b854ea1fd5fb523b53 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 2 Aug 2020 17:32:36 +0200 Subject: [PATCH 1518/2161] Initialize MSVC 2017 environment before build. --- .travis.yml | 4 +++- src/msbuild.cmd | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 src/msbuild.cmd diff --git a/.travis.yml b/.travis.yml index efeca96b4..4096d783a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ jobs: include: - os: linux + name: Linux install: - sudo apt-get update - sudo apt-get install linuxdoc-tools linuxdoc-tools-info binutils-mingw-w64-i686 gcc-mingw-w64-i686 sshpass @@ -20,5 +21,6 @@ jobs: - make -f Makefile.travis - os: windows + name: Windows script: - - MSBuild.exe scr/cc65.sln + - src/msbuild.cmd scr/cc65.sln diff --git a/src/msbuild.cmd b/src/msbuild.cmd new file mode 100644 index 000000000..129817d6a --- /dev/null +++ b/src/msbuild.cmd @@ -0,0 +1,2 @@ +call "%VS140COMNTOOLS%vsvars32.bat" +msbuild.exe %* From 35d6a75b37d021a2084edfb96c2bbd3dd9791d84 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 2 Aug 2020 17:49:18 +0200 Subject: [PATCH 1519/2161] Fixed Windows path notation. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4096d783a..0b25e5d16 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,4 +23,4 @@ jobs: - os: windows name: Windows script: - - src/msbuild.cmd scr/cc65.sln + - src/msbuild.cmd src\\cc65.sln From c831f40e9b1c2bcc3d1fdb5c5dfff5d51524447a Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 2 Aug 2020 18:44:13 +0200 Subject: [PATCH 1520/2161] Unfortunately there's no other way than using the absolute path to init the correct MSVC 2017 environment. --- src/msbuild.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/msbuild.cmd b/src/msbuild.cmd index 129817d6a..5736846da 100644 --- a/src/msbuild.cmd +++ b/src/msbuild.cmd @@ -1,2 +1,2 @@ -call "%VS140COMNTOOLS%vsvars32.bat" +call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools\VsDevCmd.bat" msbuild.exe %* From 0df45fe2f2db73eb0e09985381462bb4f91d7566 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 2 Aug 2020 21:08:50 +0800 Subject: [PATCH 1521/2161] Utility for getting ESU tag type symbols. --- src/cc65/datatype.c | 8 ++++---- src/cc65/datatype.h | 8 ++++---- src/cc65/declare.c | 11 ++++++----- src/cc65/symentry.c | 32 ++++++++++++++++++++++++++++++++ src/cc65/symentry.h | 10 ++++++++++ src/cc65/symtab.c | 2 +- src/cc65/typecmp.c | 4 ++-- 7 files changed, 59 insertions(+), 16 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 444902e60..5ac2ec4b4 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -895,8 +895,8 @@ Type* GetBaseElementType (Type* T) -SymEntry* GetSymEntry (const Type* T) -/* Return a SymEntry pointer from a type */ +SymEntry* GetESUSymEntry (const Type* T) +/* Return a SymEntry pointer from an enum/struct/union type */ { /* Only enums, structs or unions have a SymEntry attribute */ CHECK (IsClassStruct (T) || IsTypeEnum (T)); @@ -907,8 +907,8 @@ SymEntry* GetSymEntry (const Type* T) -void SetSymEntry (Type* T, SymEntry* S) -/* Set the SymEntry pointer for a type */ +void SetESUSymEntry (Type* T, SymEntry* S) +/* Set the SymEntry pointer for an enum/struct/union type */ { /* Only enums, structs or unions have a SymEntry attribute */ CHECK (IsClassStruct (T) || IsTypeEnum (T)); diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 33c66d65d..4839be5d2 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -747,11 +747,11 @@ Type* GetBaseElementType (Type* T); ** the element type that is not an array. */ -struct SymEntry* GetSymEntry (const Type* T) attribute ((const)); -/* Return a SymEntry pointer from a type */ +struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); +/* Return a SymEntry pointer from an enum/struct/union type */ -void SetSymEntry (Type* T, struct SymEntry* S); -/* Set the SymEntry pointer for a type */ +void SetESUSymEntry (Type* T, struct SymEntry* S); +/* Set the SymEntry pointer for an enum/struct/union type */ Type* IntPromotion (Type* T); /* Apply the integer promotions to T and return the result. The returned type diff --git a/src/cc65/declare.c b/src/cc65/declare.c index a525e1f86..5ecfeb04f 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -766,6 +766,7 @@ static unsigned PadWithBitField (unsigned StructSize, unsigned BitOffs) } + static unsigned AliasAnonStructFields (const Declaration* Decl, SymEntry* Anon) /* Create alias fields from an anon union/struct in the current lexical level. ** The function returns the count of created aliases. @@ -775,7 +776,7 @@ static unsigned AliasAnonStructFields (const Declaration* Decl, SymEntry* Anon) SymEntry* Alias; /* Get the pointer to the symbol table entry of the anon struct */ - SymEntry* Entry = GetSymEntry (Decl->Type); + SymEntry* Entry = GetESUSymEntry (Decl->Type); /* Get the symbol table containing the fields. If it is empty, there has ** been an error before, so bail out. @@ -1267,7 +1268,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers) Entry = ParseUnionDecl (Ident); /* Encode the union entry into the type */ D->Type[0].C = T_UNION; - SetSymEntry (D->Type, Entry); + SetESUSymEntry (D->Type, Entry); D->Type[1].C = T_END; break; @@ -1286,7 +1287,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers) Entry = ParseStructDecl (Ident); /* Encode the struct entry into the type */ D->Type[0].C = T_STRUCT; - SetSymEntry (D->Type, Entry); + SetESUSymEntry (D->Type, Entry); D->Type[1].C = T_END; break; @@ -1308,7 +1309,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers) /* Parse the enum decl */ Entry = ParseEnumDecl (Ident); D->Type[0].C |= T_ENUM; - SetSymEntry (D->Type, Entry); + SetESUSymEntry (D->Type, Entry); D->Type[1].C = T_END; break; @@ -2258,7 +2259,7 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) } /* Get a pointer to the struct entry from the type */ - Entry = GetSymEntry (T); + Entry = GetESUSymEntry (T); /* Get the size of the struct from the symbol table entry */ SI.Size = Entry->V.S.Size; diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index c8d4f9e2a..6486ab764 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -278,6 +278,38 @@ void CvtRegVarToAuto (SymEntry* Sym) +SymEntry* GetSymType (const Type* T) +/* Get the symbol entry of the enum/struct/union type +** Return 0 if it is not an enum/struct/union. +*/ +{ + if ((IsClassStruct (T) || IsTypeEnum (T))) { + return T->A.P; + } + return 0; +} + + + +const char* GetSymTypeName (const Type* T) +/* Return a name string of the type or the symbol name if it is an ESU type. +** Note: This may use a static buffer that could be overwritten by other calls. +*/ +{ + static char TypeName [IDENTSIZE + 16]; + SymEntry* Sym; + + Sym = GetSymType (T); + if (Sym == 0) { + return GetBasicTypeName (T); + } + sprintf (TypeName, "%s %s", GetBasicTypeName (T), Sym->Name ? Sym->Name : "<unknown>"); + + return TypeName; +} + + + void ChangeSymType (SymEntry* Entry, Type* T) /* Change the type of the given symbol */ { diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index e59bf2a35..1d8af3f50 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -304,6 +304,16 @@ void SymSetAsmName (SymEntry* Sym); void CvtRegVarToAuto (SymEntry* Sym); /* Convert a register variable to an auto variable */ +SymEntry* GetSymType (const Type* T); +/* Get the symbol entry of the enum/struct/union type +** Return 0 if it is not an enum/struct/union. +*/ + +const char* GetSymTypeName (const Type* T); +/* Return a name string of the type or the symbol name if it is an ESU type. +** Note: This may use a static buffer that could be overwritten by other calls. +*/ + void ChangeSymType (SymEntry* Entry, Type* T); /* Change the type of the given symbol */ diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index f7a7862cf..735cb854f 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -509,7 +509,7 @@ SymEntry FindStructField (const Type* T, const char* Name) if (IsClassStruct (T)) { /* Get a pointer to the struct/union type */ - const SymEntry* Struct = GetSymEntry (T); + const SymEntry* Struct = GetESUSymEntry (T); CHECK (Struct != 0); /* Now search in the struct/union symbol table. Beware: The table may diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 66dd9039b..0eddf2988 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -368,8 +368,8 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) ** pointer to the struct definition from the type, and compare ** the fields. */ - Sym1 = GetSymEntry (lhs); - Sym2 = GetSymEntry (rhs); + Sym1 = GetESUSymEntry (lhs); + Sym2 = GetESUSymEntry (rhs); /* If one symbol has a name, the names must be identical */ if (!HasAnonName (Sym1) || !HasAnonName (Sym2)) { From 4ccf10f3fa43f28555168b9b7730deb73a7aaa6a Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 2 Aug 2020 21:51:26 +0800 Subject: [PATCH 1522/2161] Utility to get full type names. --- src/cc65/datatype.c | 233 ++++++++++++++++++++++++++++++++++++++++++++ src/cc65/datatype.h | 16 +++ 2 files changed, 249 insertions(+) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 5ac2ec4b4..2c2167188 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -78,6 +78,144 @@ Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +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. +*/ +{ + struct StrBuf Buf = STATIC_STRBUF_INITIALIZER; + + if (IsTypeArray (T)) { + + long Count = GetElementCount (T); + if (!SB_IsEmpty (East)) { + if (Count > 0) { + SB_Printf (&Buf, "[%ld]", Count); + } else { + SB_Printf (&Buf, "[]"); + } + SB_Append (East, &Buf); + SB_Terminate (East); + + } else { + if (Count > 0) { + SB_Printf (East, "[%ld]", Count); + } else { + SB_Printf (East, "[]"); + } + + if (!SB_IsEmpty (West)) { + /* Add parentheses to West */ + SB_Printf (&Buf, "(%s)", SB_GetConstBuf (West)); + SB_Copy (West, &Buf); + SB_Terminate (West); + } + } + + /* Get element type */ + GetFullTypeNameWestEast (West, East, T + 1); + + } else if (IsTypeFunc (T)) { + + FuncDesc* F = GetFuncDesc (T); + struct StrBuf ParamList = STATIC_STRBUF_INITIALIZER; + + /* First argument */ + SymEntry* Param = F->SymTab->SymHead; + for (unsigned I = 1; I < F->ParamCount; ++I) { + CHECK (Param->NextSym != 0 && (Param->Flags & SC_PARAM) != 0); + SB_AppendStr (&ParamList, SB_GetConstBuf (GetFullTypeNameBuf (&Buf, Param->Type))); + SB_AppendStr (&ParamList, ", "); + SB_Clear (&Buf); + /* Next argument */ + Param = Param->NextSym; + } + if ((F->Flags & FD_VARIADIC) == 0) { + if (F->ParamCount > 0) { + SB_AppendStr (&ParamList, SB_GetConstBuf (GetFullTypeNameBuf (&Buf, Param->Type))); + } else { + SB_AppendStr (&ParamList, "void"); + } + } else { + if (F->ParamCount > 0) { + SB_AppendStr (&ParamList, SB_GetConstBuf (GetFullTypeNameBuf (&Buf, Param->Type))); + SB_AppendStr (&ParamList, ", ..."); + } else { + SB_AppendStr (&ParamList, "..."); + } + } + SB_Terminate (&ParamList); + + /* Join the existing West and East together */ + if (!SB_IsEmpty (East)) { + SB_Append (West, East); + SB_Terminate (West); + SB_Clear (East); + } + + if (SB_IsEmpty (West)) { + /* Just use the param list */ + SB_Printf (West, "(%s)", 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)); + } + SB_Done (&ParamList); + + /* Return type */ + GetFullTypeNameWestEast (West, East, T + 1); + + } else if (IsTypePtr (T)) { + + int QualCount = 0; + + SB_Printf (&Buf, "*"); + + /* Add qualifiers */ + if ((GetQualifier (T) & ~T_QUAL_NEAR) != T_QUAL_NONE) { + QualCount = GetQualifierTypeCodeNameBuf (&Buf, T->C, T_QUAL_NEAR); + } + + if (!SB_IsEmpty (West)) { + if (QualCount > 0) { + SB_AppendChar (&Buf, ' '); + } + SB_Append (&Buf, West); + } + + SB_Copy (West, &Buf); + SB_Terminate (West); + + /* Get indirection type */ + GetFullTypeNameWestEast (West, East, T + 1); + + } else { + + /* Add qualifiers */ + if ((GetQualifier (T) & ~T_QUAL_NEAR) != 0) { + if (GetQualifierTypeCodeNameBuf (&Buf, T->C, T_QUAL_NEAR) > 0) { + SB_AppendChar (&Buf, ' '); + } + } + + SB_AppendStr (&Buf, GetSymTypeName (T)); + + if (!SB_IsEmpty (West)) { + SB_AppendChar (&Buf, ' '); + SB_Append (&Buf, West); + } + + SB_Copy (West, &Buf); + SB_Terminate (West); + } + + SB_Done (&Buf); + return West; +} + + + const char* GetBasicTypeName (const Type* T) /* Return a const name string of the basic type. ** Return "type" for unknown basic types. @@ -134,6 +272,101 @@ const char* GetBasicTypeName (const Type* T) +const char* GetFullTypeName (const Type* T) +/* Return the full name string of the given type. +** Note: This may use a static buffer that could be overwritten by other calls. +*/ +{ + static struct StrBuf Buf = STATIC_STRBUF_INITIALIZER; + SB_Clear (&Buf); + GetFullTypeNameBuf (&Buf, T); + + return SB_GetConstBuf (&Buf); +} + + + +struct StrBuf* GetFullTypeNameBuf (struct StrBuf* S, const Type* T) +/* Return the full name string of the given type */ +{ + struct StrBuf East = STATIC_STRBUF_INITIALIZER; + GetFullTypeNameWestEast (S, &East, T); + + /* Join West and East */ + SB_Append (S, &East); + SB_Terminate (S); + SB_Done (&East); + + return S; +} + + + +int GetQualifierTypeCodeNameBuf (struct StrBuf* S, TypeCode Qual, TypeCode IgnoredQual) +/* Return the names of the qualifiers of the type. +** Qualifiers to be ignored can be specified with the IgnoredQual flags. +** Return the count of added qualifier names. +*/ +{ + int Count = 0; + + Qual &= T_MASK_QUAL & ~IgnoredQual; + if (Qual & T_QUAL_CONST) { + if (!SB_IsEmpty (S)) { + SB_AppendChar (S, ' '); + } + SB_AppendStr (S, "const"); + ++Count; + } + if (Qual & T_QUAL_VOLATILE) { + if (Count > 0) { + SB_AppendChar (S, ' '); + } + SB_AppendStr (S, "volatile"); + ++Count; + } + if (Qual & T_QUAL_RESTRICT) { + if (Count > 0) { + SB_AppendChar (S, ' '); + } + SB_AppendStr (S, "restrict"); + ++Count; + } + if (Qual & T_QUAL_NEAR) { + if (Count > 0) { + SB_AppendChar (S, ' '); + } + SB_AppendStr (S, "__near__"); + ++Count; + } + if (Qual & T_QUAL_FAR) { + SB_AppendStr (S, "__far__"); + ++Count; + } + if (Qual & T_QUAL_FASTCALL) { + if (Count > 0) { + SB_AppendChar (S, ' '); + } + SB_AppendStr (S, "__fastcall__"); + ++Count; + } + if (Qual & T_QUAL_CDECL) { + if (Count > 0) { + SB_AppendChar (S, ' '); + } + SB_AppendStr (S, "__cdecl__"); + ++Count; + } + + if (Count > 0) { + SB_Terminate (S); + } + + return Count; +} + + + unsigned TypeLen (const Type* T) /* Return the length of the type string */ { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 4839be5d2..8e32d6404 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -203,6 +203,8 @@ extern Type type_double[]; /* Forward for the SymEntry struct */ struct SymEntry; +/* Forward for the StrBuf struct */ +struct StrBuf; /*****************************************************************************/ @@ -216,6 +218,20 @@ const char* GetBasicTypeName (const Type* T); ** Return "type" for unknown basic types. */ +const char* GetFullTypeName (const Type* T); +/* Return the full name string of the given type. +** Note: This may use a static buffer that could be overwritten by other calls. +*/ + +struct StrBuf* GetFullTypeNameBuf (struct StrBuf* S, const Type* T); +/* Return the full name string of the given type */ + +int GetQualifierTypeCodeNameBuf (struct StrBuf* S, TypeCode Qual, TypeCode IgnoredQual); +/* Return the names of the qualifiers of the type. +** Qualifiers to be ignored can be specified with the IgnoredQual flags. +** Return the count of added qualifier names. +*/ + unsigned TypeLen (const Type* T); /* Return the length of the type string */ From 52051f444e6b1bfff20d5dd8967cd1f3effad610 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 2 Aug 2020 21:51:32 +0800 Subject: [PATCH 1523/2161] Using tracked individual string buffers instead of a shared static string buffer for full type names. --- src/cc65/datatype.c | 11 ++++------ src/cc65/datatype.h | 4 +--- src/cc65/error.c | 51 +++++++++++++++++++++++++++++++++++++++++++++ src/cc65/error.h | 15 +++++++++++++ src/cc65/main.c | 6 ++++++ 5 files changed, 77 insertions(+), 10 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 2c2167188..d1c34c825 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -273,15 +273,12 @@ const char* GetBasicTypeName (const Type* T) const char* GetFullTypeName (const Type* T) -/* Return the full name string of the given type. -** Note: This may use a static buffer that could be overwritten by other calls. -*/ +/* Return the full name string of the given type */ { - static struct StrBuf Buf = STATIC_STRBUF_INITIALIZER; - SB_Clear (&Buf); - GetFullTypeNameBuf (&Buf, T); + struct StrBuf* Buf = NewDiagnosticStrBuf (); + GetFullTypeNameBuf (Buf, T); - return SB_GetConstBuf (&Buf); + return SB_GetConstBuf (Buf); } diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 8e32d6404..ad382d50f 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -219,9 +219,7 @@ const char* GetBasicTypeName (const Type* T); */ const char* GetFullTypeName (const Type* T); -/* Return the full name string of the given type. -** Note: This may use a static buffer that could be overwritten by other calls. -*/ +/* Return the full name string of the given type */ struct StrBuf* GetFullTypeNameBuf (struct StrBuf* S, const Type* T); /* Return the full name string of the given type */ diff --git a/src/cc65/error.c b/src/cc65/error.c index c3ebebf77..10d20a34b 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -38,7 +38,9 @@ #include <stdarg.h> /* common */ +#include "coll.h" #include "print.h" +#include "strbuf.h" /* cc65 */ #include "global.h" @@ -92,6 +94,8 @@ static WarnMapEntry WarnMap[] = { { &WarnUnusedVar, "unused-var" }, }; +Collection DiagnosticStrBufs; + /*****************************************************************************/ @@ -323,3 +327,50 @@ void ErrorReport (void) { Print (stdout, 1, "%u errors, %u warnings\n", ErrorCount, WarningCount); } + + + +/*****************************************************************************/ +/* Tracked StrBufs */ +/*****************************************************************************/ + + + +void InitDiagnosticStrBufs (void) +/* Init tracking string buffers used for diagnostics */ +{ + InitCollection (&DiagnosticStrBufs); +} + + + +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); +} + + + +struct StrBuf* NewDiagnosticStrBuf (void) +/* Get a new tracked string buffer */ +{ + StrBuf *Buf = NewStrBuf (); + CollAppend (&DiagnosticStrBufs, Buf); + return Buf; +} diff --git a/src/cc65/error.h b/src/cc65/error.h index 97ee09591..a443aeff8 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -72,6 +72,9 @@ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ +/* Forward */ +struct StrBuf; + /*****************************************************************************/ @@ -115,6 +118,18 @@ void ListWarnings (FILE* F); void ErrorReport (void); /* Report errors (called at end of compile) */ +void InitDiagnosticStrBufs (void); +/* Init tracking string buffers used for diagnostics */ + +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 */ + /* End of error.h */ diff --git a/src/cc65/main.c b/src/cc65/main.c index e86ae13ba..ed2e9d7ba 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -1060,6 +1060,9 @@ int main (int argc, char* argv[]) IS_Set (&Standard, STD_DEFAULT); } + /* Track string buffer allocation */ + InitDiagnosticStrBufs (); + /* Go! */ Compile (InputFile); @@ -1083,6 +1086,9 @@ int main (int argc, char* argv[]) CreateDependencies (); } + /* Done with tracked string buffer allocation */ + DoneDiagnosticStrBufs (); + /* Return an apropriate exit code */ return (ErrorCount > 0)? EXIT_FAILURE : EXIT_SUCCESS; } From d841bbe49825f604d0d52365675d2332ed76fae7 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 2 Aug 2020 21:51:32 +0800 Subject: [PATCH 1524/2161] Utility to check for castability. --- src/cc65/datatype.c | 16 ++++++++++++++++ src/cc65/datatype.h | 6 ++++++ 2 files changed, 22 insertions(+) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d1c34c825..cffec7880 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -1018,6 +1018,22 @@ Type* ArrayToPtr (Type* T) +int IsClassArithmetic (const Type* T) +/* Return true if this is an arithmetic type */ +{ + return IsClassInt (T) || IsClassFloat (T); +} + + + +int IsCastType (const Type* T) +/* Return true if this type can be used for casting */ +{ + return IsClassArithmetic (T) || IsClassPtr (T) || IsTypeVoid (T); +} + + + int IsVariadicFunc (const Type* T) /* Return true if this is a function type or pointer to function type with ** variable parameter list diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index ad382d50f..66f1b8b05 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -578,6 +578,12 @@ INLINE int IsClassFunc (const Type* T) # define IsClassFunc(T) (GetClass (T) == T_CLASS_FUNC) #endif +int IsClassArithmetic (const Type* T); +/* Return true if this is an arithmetic type */ + +int IsCastType (const Type* T); +/* Return true if this type can be used for casting */ + #if defined(HAVE_INLINE) INLINE TypeCode GetRawSignedness (const Type* T) /* Get the raw signedness of a type */ From 003d47cc8b661cfb8dcfd89ae02eb7e7022e0196 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 2 Aug 2020 21:51:32 +0800 Subject: [PATCH 1525/2161] Improved type conversion diagnostic messages. Allowed incompatible pointer assignments with warnings. Fixed Issue #1089. --- src/cc65/assignment.c | 3 +- src/cc65/expr.c | 12 ++++-- src/cc65/typeconv.c | 96 +++++++++++++++++++++++++++++++------------ src/cc65/typeconv.h | 3 ++ 4 files changed, 82 insertions(+), 32 deletions(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index ed374ef8a..c67ac1ce5 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -78,7 +78,8 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) /* Check for equality of the structs */ if (TypeCmp (ltype, RExpr->Type) < TC_STRICT_COMPATIBLE) { - Error ("Incompatible types"); + TypeCompatibilityDiagnostic (ltype, RExpr->Type, 1, + "Incompatible types in assignment to '%s' from '%s'"); } /* Do we copy using the primary? */ diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 1d123ce9b..a99f17b55 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -2242,7 +2242,8 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* Make sure, the types are compatible */ if (IsClassInt (Expr->Type)) { if (!IsClassInt (Expr2.Type) && !(IsClassPtr(Expr2.Type) && ED_IsNullPtr(Expr))) { - Error ("Incompatible types"); + TypeCompatibilityDiagnostic (Expr->Type, Expr2.Type, 1, + "Incompatible types comparing '%s' with '%s'"); } } else if (IsClassPtr (Expr->Type)) { if (IsClassPtr (Expr2.Type)) { @@ -2253,10 +2254,12 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ Type* right = Indirect (Expr2.Type); if (TypeCmp (left, right) < TC_QUAL_DIFF && left->C != T_VOID && right->C != T_VOID) { /* Incompatible pointers */ - Error ("Incompatible types"); + TypeCompatibilityDiagnostic (Expr->Type, Expr2.Type, 1, + "Incompatible pointer types comparing '%s' with '%s'"); } } else if (!ED_IsNullPtr (&Expr2)) { - Error ("Incompatible types"); + TypeCompatibilityDiagnostic (Expr->Type, Expr2.Type, 1, + "Comparing pointer type '%s' with '%s'"); } } @@ -3324,7 +3327,8 @@ static void hieQuest (ExprDesc* Expr) /* Result type is void */ ResultType = Expr3.Type; } else { - Error ("Incompatible types"); + TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, + "Incompatible types in ternary '%s' with '%s'"); ResultType = Expr2.Type; /* Doesn't matter here */ } diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index e915d7392..c3c1a2528 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -55,6 +55,24 @@ +void TypeCompatibilityDiagnostic (const Type* NewType, const Type* OldType, int IsError, const char* Msg) +/* Print error or warning message about type conversion with proper type names */ +{ + StrBuf NewTypeName = STATIC_STRBUF_INITIALIZER; + StrBuf OldTypeName = STATIC_STRBUF_INITIALIZER; + GetFullTypeNameBuf (&NewTypeName, NewType); + GetFullTypeNameBuf (&OldTypeName, OldType); + if (IsError) { + Error (Msg, SB_GetConstBuf (&NewTypeName), SB_GetConstBuf (&OldTypeName)); + } else { + Warning (Msg, SB_GetConstBuf (&NewTypeName), SB_GetConstBuf (&OldTypeName)); + } + SB_Done (&OldTypeName); + SB_Done (&NewTypeName); +} + + + static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { @@ -189,6 +207,11 @@ void TypeConversion (ExprDesc* Expr, Type* NewType) printf ("\n"); PrintRawType (stdout, NewType); #endif + int HasWarning = 0; + int HasError = 0; + const char* Msg = 0; + const Type* OldType = Expr->Type; + /* First, do some type checking */ if (IsTypeVoid (NewType) || IsTypeVoid (Expr->Type)) { @@ -199,7 +222,7 @@ void TypeConversion (ExprDesc* Expr, Type* NewType) } /* If Expr is a function, convert it to pointer to function */ - if (IsTypeFunc(Expr->Type)) { + if (IsTypeFunc (Expr->Type)) { Expr->Type = PointerTo (Expr->Type); } @@ -220,15 +243,12 @@ void TypeConversion (ExprDesc* Expr, Type* NewType) } Warning ("Converting pointer to integer without a cast"); } else if (!IsClassInt (Expr->Type) && !IsClassFloat (Expr->Type)) { - Error ("Incompatible types"); + HasError = 1; } - } else if (IsClassFloat (NewType)) { - if (!IsClassFloat (Expr->Type) && !IsClassInt (Expr->Type)) { - Error ("Incompatible types"); + HasError = 1; } - } else if (IsClassPtr (NewType)) { /* Handle conversions to pointer type */ @@ -248,17 +268,19 @@ void TypeConversion (ExprDesc* Expr, Type* NewType) /* Compare the types */ switch (TypeCmp (NewType, Expr->Type)) { - case TC_INCOMPATIBLE: - Error ("Incompatible pointer types at '%s'", (Expr->Sym? Expr->Sym->Name : "Unknown")); - break; + case TC_INCOMPATIBLE: + HasWarning = 1; + Msg = "Incompatible pointer assignment to '%s' from '%s'"; + break; - case TC_QUAL_DIFF: - Error ("Pointer types differ in type qualifiers"); - break; + case TC_QUAL_DIFF: + HasWarning = 1; + Msg = "Pointer assignment to '%s' from '%s' discards qualifiers"; + break; - default: - /* Ok */ - break; + default: + /* Ok */ + break; } } @@ -268,18 +290,28 @@ void TypeConversion (ExprDesc* Expr, Type* NewType) Warning ("Converting integer to pointer without a cast"); } } else { - Error ("Incompatible types"); + HasError = 1; } } else { - - /* Invalid automatic conversion */ - Error ("Incompatible types"); - + /* Invalid automatic conversion */ + HasError = 1; } - /* Do the actual conversion */ - DoConversion (Expr, NewType); + if (Msg == 0) { + Msg = "Converting to '%s' from '%s'"; + } + + if (HasError) { + TypeCompatibilityDiagnostic (NewType, OldType, 1, Msg); + } else { + if (HasWarning) { + TypeCompatibilityDiagnostic (NewType, OldType, 0, Msg); + } + + /* Do the actual conversion */ + DoConversion (Expr, NewType); + } } @@ -301,9 +333,19 @@ void TypeCast (ExprDesc* Expr) /* Read the expression we have to cast */ hie10 (Expr); - /* Convert functions and arrays to "pointer to" object */ - Expr->Type = PtrConversion (Expr->Type); - - /* Convert the value. */ - DoConversion (Expr, NewType); + /* Only allow casts to arithmetic or pointer types, or just changing the + ** qualifiers. + */ + if (TypeCmp (NewType, Expr->Type) >= TC_QUAL_DIFF) { + /* The expression has always the new type */ + ReplaceType (Expr, NewType); + } else if (IsCastType (NewType)) { + /* Convert functions and arrays to "pointer to" object */ + Expr->Type = PtrConversion (Expr->Type); + /* Convert the value */ + DoConversion (Expr, NewType); + } else { + Error ("Arithmetic or pointer type expected but '%s' is used", + GetFullTypeName (NewType)); + } } diff --git a/src/cc65/typeconv.h b/src/cc65/typeconv.h index 8321aded4..5c94069a3 100644 --- a/src/cc65/typeconv.h +++ b/src/cc65/typeconv.h @@ -49,6 +49,9 @@ +void TypeCompatibilityDiagnostic (const Type* NewType, const Type* OldType, int IsError, const char* Msg); +/* Print error or warning message about type conversion with proper type names */ + void TypeConversion (ExprDesc* Expr, Type* NewType); /* Do an automatic conversion of the given expression to the new type. Output ** warnings or errors where this automatic conversion is suspicious or From 80b0e57543eeddd32485a015208aee160f7594f9 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 2 Aug 2020 21:51:32 +0800 Subject: [PATCH 1526/2161] Changed parameter constness of TypeConversion(). --- src/cc65/datatype.c | 14 ++++++++++++++ src/cc65/datatype.h | 5 +++++ src/cc65/typeconv.c | 4 ++-- src/cc65/typeconv.h | 2 +- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index cffec7880..005e6109b 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -1009,6 +1009,20 @@ Type* Indirect (Type* T) +const Type* IndirectConst (const Type* T) +/* Do one indirection for the given type, that is, return the type where the +** given type points to. +*/ +{ + /* We are expecting a pointer expression */ + CHECK (IsClassPtr (T)); + + /* Skip the pointer or array token itself */ + return T + 1; +} + + + Type* ArrayToPtr (Type* T) /* Convert an array to a pointer to it's first element */ { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 66f1b8b05..6cbad302f 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -345,6 +345,11 @@ Type* Indirect (Type* T); ** given type points to. */ +const Type* IndirectConst (const Type* T); +/* Do one indirection for the given type, that is, return the type where the +** given type points to. +*/ + Type* ArrayToPtr (Type* T); /* Convert an array to a pointer to it's first element */ diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index c3c1a2528..7e2787529 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -192,7 +192,7 @@ ExitPoint: -void TypeConversion (ExprDesc* Expr, Type* NewType) +void TypeConversion (ExprDesc* Expr, const Type* NewType) /* Do an automatic conversion of the given expression to the new type. Output ** warnings or errors where this automatic conversion is suspicious or ** impossible. @@ -264,7 +264,7 @@ void TypeConversion (ExprDesc* Expr, Type* NewType) ** - the rhs pointer is a void pointer, or ** - the lhs pointer is a void pointer. */ - if (!IsTypeVoid (Indirect (NewType)) && !IsTypeVoid (Indirect (Expr->Type))) { + if (!IsTypeVoid (IndirectConst (NewType)) && !IsTypeVoid (Indirect (Expr->Type))) { /* Compare the types */ switch (TypeCmp (NewType, Expr->Type)) { diff --git a/src/cc65/typeconv.h b/src/cc65/typeconv.h index 5c94069a3..0a82eac27 100644 --- a/src/cc65/typeconv.h +++ b/src/cc65/typeconv.h @@ -52,7 +52,7 @@ void TypeCompatibilityDiagnostic (const Type* NewType, const Type* OldType, int IsError, const char* Msg); /* Print error or warning message about type conversion with proper type names */ -void TypeConversion (ExprDesc* Expr, Type* NewType); +void TypeConversion (ExprDesc* Expr, const Type* NewType); /* Do an automatic conversion of the given expression to the new type. Output ** warnings or errors where this automatic conversion is suspicious or ** impossible. From 00c16d34a4ea1a7906ef716c6db5d52effdb8ef1 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 01:15:57 +0800 Subject: [PATCH 1527/2161] Minor fixes for HandleSymRedefinition(). --- src/cc65/symtab.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 735cb854f..2104c017b 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -549,7 +549,8 @@ SymEntry FindStructField (const Type* T, const char* Name) static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags) /* Check and handle redefinition of existing symbols. -** Return ture if there *is* an error. +** Complete array sizes and function descriptors as well. +** Return true if there *is* an error. */ { /* Get the type info of the existing symbol */ @@ -594,8 +595,8 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags */ if (IsTypeFunc (T)) { - /* New type must be identical */ - if (TypeCmp (Entry->Type, T) < TC_EQUAL) { + /* New type must be equivalent */ + if (TypeCmp (E_Type, T) < TC_EQUAL) { Error ("Conflicting function types for '%s'", Entry->Name); Entry = 0; } else { @@ -614,6 +615,7 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags Error ("Redefinition of function '%s' as different kind of symbol", Entry->Name); Entry = 0; } + } else if (E_SCType == SC_TYPEDEF) { if (SCType == SC_TYPEDEF) { @@ -622,9 +624,7 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags Error ("Conflicting types for typedef '%s'", Entry->Name); Entry = 0; } - } else { - Error ("Redefinition of typedef '%s' as different kind of symbol", Entry->Name); Entry = 0; } @@ -639,7 +639,10 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags Error ("Conflicting types for '%s'", Entry->Name); Entry = 0; } else if (E_SCType == SC_ENUMERATOR) { - /* Current code logic won't reach here, but still... */ + /* Enumerators aren't allowed to be redeclared at all, even if + ** all occurences are identical. The current code logic won't + ** get here, but let's just do it. + */ Error ("Redeclaration of enumerator constant '%s'", Entry->Name); Entry = 0; } From 44e3080ea93676e761093da37e4d16465e9c27b3 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 01:15:57 +0800 Subject: [PATCH 1528/2161] Increased upper limit of allowed errors before aborting. --- 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 10d20a34b..b0ca97c89 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -184,7 +184,7 @@ 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 (ErrorCount > 10) { + if (ErrorCount > 20) { Fatal ("Too many errors"); } } From 99ac1c46da0e9d19c32855409200067992e7b1a4 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 01:15:57 +0800 Subject: [PATCH 1529/2161] Made errors/warnings statistic message visible when there are errors. --- src/cc65/error.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc65/error.c b/src/cc65/error.c index b0ca97c89..132bf331d 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -325,7 +325,8 @@ void ListWarnings (FILE* F) void ErrorReport (void) /* Report errors (called at end of compile) */ { - Print (stdout, 1, "%u errors, %u warnings\n", ErrorCount, WarningCount); + unsigned int V = (ErrorCount != 0 ? 0 : 1); + Print (stdout, V, "%u errors and %u warnings generated.\n", ErrorCount, WarningCount); } From 2ab727267385f4e51e26c682e69ab98af607a562 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 01:15:57 +0800 Subject: [PATCH 1530/2161] Improved warning on comparison of unsigned type < 0. --- 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 20bfdf434..8a879745d 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -3642,7 +3642,7 @@ void g_lt (unsigned flags, unsigned long val) /* Give a warning in some special cases */ if (val == 0) { - Warning ("Condition is never true"); + Warning ("Comparison of unsigned type < 0 is always false"); AddCodeLine ("jsr return0"); return; } From ef5a4db12e547d4758151f58606d4eb5f5b59297 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 01:15:57 +0800 Subject: [PATCH 1531/2161] Improved warning messages on UB shifts. --- src/cc65/shiftexpr.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index c7aea5255..9fe9d1188 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -139,9 +139,14 @@ void ShiftExpr (struct ExprDesc* Expr) ** the operand, the behaviour is undefined according to the ** standard. */ - if (Expr2.IVal < 0 || Expr2.IVal >= (long) ExprBits) { + if (Expr2.IVal < 0) { - Warning ("Shift count too large for operand type"); + Warning ("Shift count '%ld' is negative", Expr2.IVal); + Expr2.IVal &= ExprBits - 1; + + } else if (Expr2.IVal >= (long) ExprBits) { + + Warning ("Shift count '%ld' >= width of type", Expr2.IVal); Expr2.IVal &= ExprBits - 1; } From e8c28864554248095ff71f10be383a258755838e Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 01:15:57 +0800 Subject: [PATCH 1532/2161] Improved error messages on redefinitions of constants and bit-fields. --- src/cc65/symtab.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 2104c017b..ee95a77b7 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -801,7 +801,7 @@ SymEntry* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsign if (Entry) { /* We have a symbol with this name already */ - Error ("Multiple definition for '%s'", Name); + Error ("Multiple definition for bit-field '%s'", Name); } else { @@ -834,7 +834,7 @@ SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val if ((Entry->Flags & SC_CONST) != SC_CONST) { Error ("Symbol '%s' is already different kind", Name); } else { - Error ("Multiple definition for '%s'", Name); + Error ("Multiple definition for constant '%s'", Name); } return Entry; } From 7e68a246251d04027319c0f5305bcab4b292018f Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 01:15:57 +0800 Subject: [PATCH 1533/2161] Clearer warning messages on unused symbols. --- src/cc65/symtab.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index ee95a77b7..a673bc3dd 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -172,7 +172,7 @@ static void CheckSymTable (SymTable* Tab) } } else { if (IS_Get (&WarnUnusedVar)) { - Warning ("'%s' is defined but never used", Entry->Name); + Warning ("Variable '%s' is defined but never used", Entry->Name); } } } @@ -186,7 +186,7 @@ static void CheckSymTable (SymTable* Tab) } else if (!SymIsRef (Entry)) { /* Defined but not used */ if (IS_Get (&WarnUnusedLabel)) { - Warning ("'%s' is defined but never used", Entry->Name); + Warning ("Label '%s' is defined but never used", Entry->Name); } } } From 11a5f0edf156bf2bb828ede170a0d03aa2b4befd Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 01:15:57 +0800 Subject: [PATCH 1534/2161] No "Statement has no effect" warnings on statements with errors. --- src/cc65/stmt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index b02ae1cd6..27665e619 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -581,6 +581,7 @@ int Statement (int* PendingToken) ExprDesc Expr; int GotBreak; CodeMark Start, End; + unsigned PrevErrorCount = ErrorCount; /* Assume no pending token */ if (PendingToken) { @@ -681,7 +682,8 @@ int Statement (int* PendingToken) GetCodePos (&End); if (CodeRangeIsEmpty (&Start, &End) && !IsTypeVoid (Expr.Type) && - IS_Get (&WarnNoEffect)) { + IS_Get (&WarnNoEffect) && + PrevErrorCount == ErrorCount) { Warning ("Statement has no effect"); } CheckSemi (PendingToken); From 6df4f1996b52e1d09111ff6078fab1ff1ea76f3d Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 01:16:00 +0800 Subject: [PATCH 1535/2161] Improved diagnostics with more detailed type names. --- src/cc65/assignment.c | 8 +++++++- src/cc65/datatype.c | 4 ++-- src/cc65/expr.c | 4 ++-- src/cc65/function.c | 2 +- src/cc65/stmt.c | 2 +- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c67ac1ce5..207e01588 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -127,7 +127,13 @@ void Assignment (ExprDesc* Expr) /* We must have an lvalue for an assignment */ if (ED_IsRVal (Expr)) { - Error ("Invalid lvalue in assignment"); + if (IsTypeArray (Expr->Type)) { + Error ("Array type '%s' is not assignable", GetFullTypeName (Expr->Type)); + } else if (IsTypeFunc (Expr->Type)) { + Error ("Function type '%s' is not assignable", GetFullTypeName (Expr->Type)); + } else { + Error ("Assignment to rvalue"); + } } /* Check for assignment to const */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 005e6109b..aaee7260f 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -903,7 +903,7 @@ unsigned CheckedSizeOf (const Type* T) { unsigned Size = SizeOf (T); if (Size == 0) { - Error ("Size of data type is unknown"); + Error ("Size of type '%s' is unknown", GetFullTypeName (T)); Size = SIZEOF_CHAR; /* Don't return zero */ } return Size; @@ -919,7 +919,7 @@ unsigned CheckedPSizeOf (const Type* T) { unsigned Size = PSizeOf (T); if (Size == 0) { - Error ("Size of data type is unknown"); + Error ("Size of type '%s' is unknown", GetFullTypeName (T)); Size = SIZEOF_CHAR; /* Don't return zero */ } return Size; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index a99f17b55..8cd332173 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1218,7 +1218,7 @@ static void StructRef (ExprDesc* Expr) NextToken (); const SymEntry Field = FindStructField (Expr->Type, Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in %s", Ident, GetBasicTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; @@ -1296,7 +1296,7 @@ static void StructRef (ExprDesc* Expr) Flags = CF_LONG | CF_UNSIGNED | CF_CONST; break; default: - Internal ("Invalid %s size: %u", GetBasicTypeName (Expr->Type), StructSize); + Internal ("Invalid '%s' size: %u", GetFullTypeName (Expr->Type), StructSize); break; } diff --git a/src/cc65/function.c b/src/cc65/function.c index e6a974f98..5d0b09380 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -513,7 +513,7 @@ void NewFunc (SymEntry* Func) ** We don't currently support this case. */ if (RType == Param->Type) { - Error ("Passing %s of this size by value is not supported", GetBasicTypeName (Param->Type)); + Error ("Passing '%s' of this size by value is not supported", GetFullTypeName (Param->Type)); } } diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 27665e619..036cc2d89 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -333,7 +333,7 @@ static void ReturnStatement (void) /* Handle struct/union specially */ ReturnType = GetStructReplacementType (Expr.Type); if (ReturnType == Expr.Type) { - Error ("Returning %s of this size by value is not supported", GetBasicTypeName (Expr.Type)); + Error ("Returning '%s' of this size by value is not supported", GetFullTypeName (Expr.Type)); } LoadExpr (TypeOf (ReturnType), &Expr); From d6aa446b541cbfa909187b6eb0243e95712c37e4 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 01:24:38 +0800 Subject: [PATCH 1536/2161] Error info for loading expressions of incomplete enum types. No more "Illegal type 0016". --- src/cc65/datatype.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index aaee7260f..bcaf3ab64 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -974,6 +974,11 @@ unsigned TypeOf (const Type* T) /* Address of ... */ return CF_INT | CF_UNSIGNED; + case T_ENUM: + /* Incomplete enum type */ + Error ("Incomplete enum type"); + return CF_INT; + default: Error ("Illegal type %04lX", T->C); return CF_INT; From e3d913b81aced6b50976b6aa5d24ef523527a0eb Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 02:23:35 +0800 Subject: [PATCH 1537/2161] Fixed the reference output of test/misc/goto.c (test/misc/goto.ref). --- test/misc/goto.ref | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/misc/goto.ref b/test/misc/goto.ref index 85dc20a61..d0a978436 100644 --- a/test/misc/goto.ref +++ b/test/misc/goto.ref @@ -1,7 +1,7 @@ goto.c(8): Warning: Goto at line 8 to label start jumps into a block with initialization of an object that has automatic storage duration -goto.c(97): Warning: 'a' is defined but never used -goto.c(117): Warning: 'a' is defined but never used -goto.c(137): Warning: 'a' is defined but never used +goto.c(97): Warning: Variable 'a' is defined but never used +goto.c(117): Warning: Variable 'a' is defined but never used +goto.c(137): Warning: Variable 'a' is defined but never used goto.c(159): Warning: Goto at line 23 to label l8 jumps into a block with initialization of an object that has automatic storage duration goto.c(159): Warning: Goto at line 44 to label l8 jumps into a block with initialization of an object that has automatic storage duration goto.c(159): Warning: Goto at line 65 to label l8 jumps into a block with initialization of an object that has automatic storage duration From bae431eab0f3cdb3d47aa47164f0d870a0ecc2ba Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 08:09:50 +0800 Subject: [PATCH 1538/2161] Fixed error message of CheckedPSizeOf(). --- 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 bcaf3ab64..18bf41bca 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -919,7 +919,7 @@ unsigned CheckedPSizeOf (const Type* T) { unsigned Size = PSizeOf (T); if (Size == 0) { - Error ("Size of type '%s' is unknown", GetFullTypeName (T)); + Error ("Size of type '%s' is unknown", GetFullTypeName (T + 1)); Size = SIZEOF_CHAR; /* Don't return zero */ } return Size; From 0c72647edda327df6970773cefb28d3c7c6a41d9 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Mon, 3 Aug 2020 09:07:36 +0200 Subject: [PATCH 1539/2161] Remove extra ED_TestDone call Accidentally added in #1141. --- src/cc65/loadexpr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index 1a6e43779..1ea86fa2d 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -238,7 +238,6 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) ** when EndBit <= 24 is possible. */ g_test (F); - ED_TestDone (Expr); } else { /* Shift right by the bit offset; no code is emitted if BitOffs is zero */ g_asr (F, Expr->BitOffs); From d8f9201ecd82165299b8fe758f57c1c515da313f Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sun, 2 Aug 2020 09:35:33 +0200 Subject: [PATCH 1540/2161] LoadExpr: Optimize <= 8-bit bit-field loads Set CF_FORCECHAR to do as many operations as char ops as possible. Clear high byte at the end. --- src/cc65/loadexpr.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index 1ea86fa2d..ba585d3e3 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -117,12 +117,27 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) */ unsigned EndBit = 0; /* End bit for bit-fields, or zero if non-bit-field. */ int AdjustBitField = 0; + unsigned BitFieldFullWidthFlags = 0; if (ED_IsBitField (Expr)) { EndBit = Expr->BitOffs + Expr->BitWidth; AdjustBitField = Expr->BitOffs != 0 || (EndBit != CHAR_BITS && EndBit != INT_BITS); + /* TODO: This probably needs to be guarded by AdjustBitField when long bit-fields are + ** supported. + */ Flags |= (EndBit <= CHAR_BITS) ? CF_CHAR : CF_INT; Flags |= CF_UNSIGNED; + + /* Flags we need operate on the whole bit-field, without CF_FORCECHAR. */ + BitFieldFullWidthFlags = Flags; + + /* If we're adjusting, then only load a char (not an int) and do only char ops; + ** We will clear the high byte in the adjustment. CF_FORCECHAR does nothing if the + ** type is not CF_CHAR. + */ + if (AdjustBitField) { + Flags |= CF_FORCECHAR; + } } else if ((Flags & CF_TYPEMASK) == 0) { Flags |= TypeOf (Expr->Type); } @@ -211,10 +226,7 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) ** so be sure to always use unsigned ints for the operations. */ if (AdjustBitField) { - /* If the field was loaded as a char, force the shift/mask ops to be char ops. - ** If it is a char, the load has already put 0 in the upper byte, so that can remain. - */ - unsigned F = Flags | CF_FORCECHAR | CF_CONST; + unsigned F = Flags | CF_CONST; /* We always need to do something with the low byte, so there is no opportunity ** for optimization by skipping it. @@ -242,19 +254,21 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) /* Shift right by the bit offset; no code is emitted if BitOffs is zero */ g_asr (F, Expr->BitOffs); - /* Since we have now shifted down, we can do char ops as long as the width fits in - ** a char. + /* Since we have now shifted down, we could do char ops when the width fits in + ** a char, but we also need to clear the high byte since we've been using + ** CF_FORCECHAR up to now. */ - if (Expr->BitWidth <= CHAR_BITS) { - F |= CF_CHAR; - } /* And by the width if the field doesn't end on a char or int boundary. - ** If it does end on a boundary, then zeros have already been shifted in. - ** g_and emits no code if the mask is all ones. + ** If it does end on a boundary, then zeros have already been shifted in, + ** but we need to clear the high byte for char. g_and emits no code if the mask + ** is all ones. */ - if (EndBit != CHAR_BITS && EndBit != INT_BITS) { - g_and (F, (0x0001U << Expr->BitWidth) - 1U); + if (EndBit == CHAR_BITS) { + /* We need to clear the high byte, since CF_FORCECHAR was set. */ + g_and (BitFieldFullWidthFlags | CF_CONST, 0xFF); + } else if (EndBit != INT_BITS) { + g_and (BitFieldFullWidthFlags | CF_CONST, (0x0001U << Expr->BitWidth) - 1U); } } } From cdfc1afd89be8fdcd14377aac996589432345fce Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Wed, 5 Aug 2020 12:57:49 +0200 Subject: [PATCH 1541/2161] Fix vacuous comparison warning from 0df45fe cc65/symentry.c:306:60: warning: address of array 'Sym->Name' will always evaluate to 'true' [-Wpointer-bool-conversion] sprintf (TypeName, "%s %s", GetBasicTypeName (T), Sym->Name ? Sym->Name : "<unknown>"); ~~~~~^~~~ ~ --- src/cc65/symentry.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index 6486ab764..ea08a860c 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -303,7 +303,8 @@ const char* GetSymTypeName (const Type* T) if (Sym == 0) { return GetBasicTypeName (T); } - sprintf (TypeName, "%s %s", GetBasicTypeName (T), Sym->Name ? Sym->Name : "<unknown>"); + sprintf (TypeName, "%s %s", GetBasicTypeName (T), + Sym->Name[0] != '\0' ? Sym->Name : "<unknown>"); return TypeName; } From f59d6b8f6ab79a0ed1e6d1e473f325cc5d8974c3 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 01:31:52 +0800 Subject: [PATCH 1542/2161] Redefining enums/structs/unions of 0 size is no longer treated as declarations and thus forbidden. --- src/cc65/declare.c | 4 ++-- src/cc65/symtab.c | 20 +++++++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 5ecfeb04f..5f5fdeac4 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -920,7 +920,7 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { LeaveStructLevel (); /* Make a real entry from the forward decl and return it */ - return AddStructSym (Name, SC_UNION, UnionSize, FieldTab); + return AddStructSym (Name, SC_UNION | SC_DEF, UnionSize, FieldTab); } @@ -1102,7 +1102,7 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { LeaveStructLevel (); /* Make a real entry from the forward decl and return it */ - return AddStructSym (Name, SC_STRUCT, StructSize, FieldTab); + return AddStructSym (Name, SC_STRUCT | SC_DEF, StructSize, FieldTab); } diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index a673bc3dd..08c909121 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -52,13 +52,13 @@ #include "declare.h" #include "error.h" #include "funcdesc.h" +#include "function.h" #include "global.h" +#include "input.h" #include "stackptr.h" #include "symentry.h" #include "typecmp.h" #include "symtab.h" -#include "function.h" -#include "input.h" @@ -728,6 +728,10 @@ SymEntry* AddEnumSym (const char* Name, const Type* Type, SymTable* Tab) Entry->V.E.SymTab = Tab; Entry->V.E.Type = Type; + if (Type != 0) { + Entry->Flags |= SC_DEF; + } + /* Add it to the current table */ AddSymEntry (CurTagTab, Entry); } @@ -738,11 +742,12 @@ SymEntry* AddEnumSym (const char* Name, const Type* Type, SymTable* Tab) -SymEntry* AddStructSym (const char* Name, unsigned Type, unsigned Size, SymTable* Tab) +SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTable* Tab) /* Add a struct/union entry and return it */ { SymTable* CurTagTab = TagTab; SymEntry* Entry; + unsigned Type = (Flags & SC_TYPEMASK); /* Type must be struct or union */ PRECONDITION (Type == SC_STRUCT || Type == SC_UNION); @@ -756,13 +761,14 @@ SymEntry* AddStructSym (const char* Name, unsigned Type, unsigned Size, SymTable /* Existing symbol is not a struct */ Error ("Symbol '%s' is already different kind", Name); Entry = 0; - } else if (Size > 0 && Entry->V.S.Size > 0) { + } else if ((Entry->Flags & Flags & SC_DEF) == SC_DEF) { /* Both structs are definitions. */ Error ("Multiple definition for '%s'", Name); Entry = 0; } else { - /* Define the struct size if it is given */ - if (Size > 0) { + /* Define the struct size if it is a definition */ + if ((Flags & SC_DEF) == SC_DEF) { + Entry->Flags = Flags; Entry->V.S.SymTab = Tab; Entry->V.S.Size = Size; } @@ -777,7 +783,7 @@ SymEntry* AddStructSym (const char* Name, unsigned Type, unsigned Size, SymTable if (Entry == 0) { /* Create a new entry */ - Entry = NewSymEntry (Name, Type); + Entry = NewSymEntry (Name, Flags); /* Set the struct data */ Entry->V.S.SymTab = Tab; From fdd120db4905611e552cadd1bbeca984a3100e0b Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 01:36:19 +0800 Subject: [PATCH 1543/2161] Enabled to output errors and warnings about tentative definitions. --- src/cc65/compile.c | 52 ++++++++++++++++++++++++++-------------------- src/cc65/compile.h | 2 +- src/cc65/main.c | 2 +- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 3d2f82c51..d70e38e00 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -415,9 +415,36 @@ void Compile (const char* FileName) } else { + /* Used for emitting externals */ + SymEntry* Entry; + /* Ok, start the ball rolling... */ Parse (); + /* Reset the BSS segment name to its default; so that the below strcmp() + ** will work as expected, at the beginning of the list of variables + */ + SetSegName (SEG_BSS, SEGNAME_BSS); + + /* Walk over all global symbols and generate code for uninitialized + ** global variables. + */ + for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) { + if ((Entry->Flags & (SC_STORAGE | SC_DEF | SC_STATIC)) == (SC_STORAGE | SC_STATIC)) { + /* Assembly definition of uninitialized global variable */ + + /* Set the segment name only when it changes */ + if (strcmp (GetSegName (SEG_BSS), Entry->V.BssName) != 0) { + SetSegName (SEG_BSS, Entry->V.BssName); + g_segname (SEG_BSS); + } + g_usebss (); + g_defgloblabel (Entry->Name); + g_res (SizeOf (Entry->Type)); + /* Mark as defined; so that it will be exported, not imported */ + Entry->Flags |= SC_DEF; + } + } } if (Debug) { @@ -431,18 +458,12 @@ void Compile (const char* FileName) void FinishCompile (void) -/* Emit literals, externals, debug info, do cleanup and optimizations */ +/* Emit literals, debug info, do cleanup and optimizations */ { SymEntry* Entry; - /* Reset the BSS segment name to its default; so that the below strcmp() - ** will work as expected, at the beginning of the list of variables - */ - SetSegName (SEG_BSS, SEGNAME_BSS); - - /* Walk over all global symbols: - ** - for functions, do clean-up and optimizations - ** - generate code for uninitialized global variables + /* Walk over all global symbols and do clean-up and optimizations for + ** functions. */ for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) { if (SymIsOutputFunc (Entry)) { @@ -450,19 +471,6 @@ void FinishCompile (void) MoveLiteralPool (Entry->V.F.LitPool); CS_MergeLabels (Entry->V.F.Seg->Code); RunOpt (Entry->V.F.Seg->Code); - } else if ((Entry->Flags & (SC_STORAGE | SC_DEF | SC_STATIC)) == (SC_STORAGE | SC_STATIC)) { - /* Assembly definition of uninitialized global variable */ - - /* Set the segment name only when it changes */ - if (strcmp (GetSegName (SEG_BSS), Entry->V.BssName) != 0) { - SetSegName (SEG_BSS, Entry->V.BssName); - g_segname (SEG_BSS); - } - g_usebss (); - g_defgloblabel (Entry->Name); - g_res (SizeOf (Entry->Type)); - /* Mark as defined; so that it will be exported, not imported */ - Entry->Flags |= SC_DEF; } } diff --git a/src/cc65/compile.h b/src/cc65/compile.h index 2d15c8200..7af14ef7e 100644 --- a/src/cc65/compile.h +++ b/src/cc65/compile.h @@ -48,7 +48,7 @@ void Compile (const char* FileName); /* Top level compile routine. Will setup things and call the parser. */ void FinishCompile (void); -/* Emit literals, externals, do cleanup and optimizations */ +/* Emit literals, debug info, do cleanup and optimizations */ diff --git a/src/cc65/main.c b/src/cc65/main.c index ed2e9d7ba..3e60bcb95 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -1069,7 +1069,7 @@ int main (int argc, char* argv[]) /* Create the output file if we didn't had any errors */ if (PreprocessOnly == 0 && (ErrorCount == 0 || Debug)) { - /* Emit literals, externals, do cleanup and optimizations */ + /* Emit literals, do cleanup and optimizations */ FinishCompile (); /* Open the file */ From fdef06762938c3edbfcba45ef96a05b04d42e0f3 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 01:36:19 +0800 Subject: [PATCH 1544/2161] Fixed tentative definition of variables of incomplete types that may be completed later. Tenative arrays that never get completed are now assumed each to have one element. --- src/cc65/compile.c | 50 ++++++++++++++++++++++++++++++++-------------- src/cc65/expr.c | 21 +++++++++++++++++-- 2 files changed, 54 insertions(+), 17 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d70e38e00..a28c3e848 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -248,16 +248,11 @@ static void Parse (void) /* We cannot declare variables of type void */ Error ("Illegal type for variable '%s'", Decl.Ident); Entry->Flags &= ~(SC_STORAGE | SC_DEF); - } else if (Size == 0) { + } else if (Size == 0 && SymIsDef (Entry)) { /* Size is unknown. Is it an array? */ if (!IsTypeArray (Decl.Type)) { Error ("Variable '%s' has unknown size", Decl.Ident); } - /* Do this only if the same array has not been defined */ - if (!SymIsDef (Entry)) { - Entry->Flags &= ~(SC_STORAGE | SC_DEF); - Entry->Flags |= SC_DECL; - } } else { /* A global (including static) uninitialized variable is ** only a tentative definition. For example, this is valid: @@ -432,17 +427,42 @@ void Compile (const char* FileName) for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) { if ((Entry->Flags & (SC_STORAGE | SC_DEF | SC_STATIC)) == (SC_STORAGE | SC_STATIC)) { /* Assembly definition of uninitialized global variable */ + SymEntry* Sym = GetSymType (Entry->Type); + unsigned Size = SizeOf (Entry->Type); + if (Size == 0 && IsTypeArray (Entry->Type)) { + if (GetElementCount (Entry->Type) == UNSPECIFIED) { + /* Assume array size of 1 */ + SetElementCount (Entry->Type, 1); + Size = SizeOf (Entry->Type); + Warning ("Tentative array '%s[]' assumed to have one element", Entry->Name); + } - /* Set the segment name only when it changes */ - if (strcmp (GetSegName (SEG_BSS), Entry->V.BssName) != 0) { - SetSegName (SEG_BSS, Entry->V.BssName); - g_segname (SEG_BSS); + Sym = GetSymType (GetElementType (Entry->Type)); + if (Size == 0 && Sym != 0 && SymIsDef (Sym)) { + /* Array of 0-size elements */ + Warning ("Array '%s[]' has 0-sized elements", Entry->Name); + } + } + + /* For non-ESU types, Size != 0 */ + if (Size != 0 || (Sym != 0 && SymIsDef (Sym))) { + /* Set the segment name only when it changes */ + if (strcmp (GetSegName (SEG_BSS), Entry->V.BssName) != 0) { + SetSegName (SEG_BSS, Entry->V.BssName); + g_segname (SEG_BSS); + } + g_usebss (); + g_defgloblabel (Entry->Name); + g_res (Size); + + /* Mark as defined; so that it will be exported, not imported */ + Entry->Flags |= SC_DEF; + } else { + /* Tentative declared variable is still of incomplete type */ + Error ("Tentative definition of '%s' of type '%s' is incomplete", + Entry->Name, + GetFullTypeName (Entry->Type)); } - g_usebss (); - g_defgloblabel (Entry->Name); - g_res (SizeOf (Entry->Type)); - /* Mark as defined; so that it will be exported, not imported */ - Entry->Flags |= SC_DEF; } } } diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 8cd332173..65238af61 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -244,6 +244,23 @@ static int TypeSpecAhead (void) +static unsigned ExprCheckedSizeOf (const Type* T) +/* Specially checked SizeOf() used in 'sizeof' expressions */ +{ + unsigned Size = SizeOf (T); + SymEntry* Sym; + + if (Size == 0) { + Sym = GetSymType (T); + if (Sym == 0 || !SymIsDef (Sym)) { + Error ("Cannot apply 'sizeof' to incomplete type '%s'", GetFullTypeName (T)); + } + } + return Size; +} + + + void PushAddr (const ExprDesc* Expr) /* If the expression contains an address that was somehow evaluated, ** push this address on the stack. This is a helper function for all @@ -1890,7 +1907,7 @@ void hie10 (ExprDesc* Expr) if (TypeSpecAhead ()) { Type T[MAXTYPELEN]; NextToken (); - Size = CheckedSizeOf (ParseType (T)); + Size = ExprCheckedSizeOf (ParseType (T)); ConsumeRParen (); } else { /* Remember the output queue pointer */ @@ -1908,7 +1925,7 @@ void hie10 (ExprDesc* Expr) ReleaseLiteral (Expr->LVal); } /* Calculate the size */ - Size = CheckedSizeOf (Expr->Type); + Size = ExprCheckedSizeOf (Expr->Type); } /* Remove any generated code */ RemoveCode (&Mark); From 8cdffc1944d743455310fae7dac7470229106759 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 01:36:19 +0800 Subject: [PATCH 1545/2161] No storage for unsuccessfully parsed variables. --- src/cc65/compile.c | 6 ++++++ src/cc65/declare.c | 11 +++++++++-- src/cc65/locals.c | 21 +++++++++++---------- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index a28c3e848..ef7dea149 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -148,6 +148,11 @@ static void Parse (void) break; } + if ((Decl.StorageClass & SC_ALIAS) == SC_ALIAS) { + /* Failed parsing */ + goto SkipOneDecl; + } + /* Check if we must reserve storage for the variable. We do this, ** ** - if it is not a typedef or function, @@ -276,6 +281,7 @@ static void Parse (void) } +SkipOneDecl: /* Check for end of declaration list */ if (CurTok.Tok == TOK_COMMA) { NextToken (); diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 5f5fdeac4..7b868380d 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1814,6 +1814,9 @@ Type* ParseType (Type* T) void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Parse a variable, type or function declaration */ { + /* Used to check if we have any errors during parsing this */ + unsigned PrevErrorCount = ErrorCount; + /* Initialize the Declaration struct */ InitDeclaration (D); @@ -1891,8 +1894,8 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) } } - /* Check the size of the generated type */ if (!IsTypeFunc (D->Type) && !IsTypeVoid (D->Type)) { + /* Check the size of the generated type */ unsigned Size = SizeOf (D->Type); if (Size >= 0x10000) { if (D->Ident[0] != '\0') { @@ -1901,8 +1904,12 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) Error ("Invalid size in declaration (0x%06X)", Size); } } - } + if (PrevErrorCount != ErrorCount) { + /* Don't give storage if the declaration is not parsed correctly */ + D->StorageClass |= SC_DECL | SC_ALIAS; + } + } } diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 3fa26021f..03bc80f21 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -443,13 +443,14 @@ static void ParseOneDecl (const DeclSpec* Spec) } /* If the symbol is not marked as external, it will be defined now */ - if ((Decl.StorageClass & SC_EXTERN) == 0) { + if ((Decl.StorageClass & SC_ALIAS) == 0 && + (Decl.StorageClass & SC_EXTERN) == 0) { Decl.StorageClass |= SC_DEF; } /* Handle anything that needs storage (no functions, no typdefs) */ - if ((Decl.StorageClass & SC_FUNC) != SC_FUNC && - (Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF) { + if ((Decl.StorageClass & SC_DEF) == SC_DEF && + (Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF) { /* If we have a register variable, try to allocate a register and ** convert the declaration to "auto" if this is not possible. @@ -468,13 +469,6 @@ static void ParseOneDecl (const DeclSpec* Spec) } else if ((Decl.StorageClass & SC_AUTO) == SC_AUTO) { /* Auto variable */ ParseAutoDecl (&Decl); - } else if ((Decl.StorageClass & SC_EXTERN) == SC_EXTERN) { - /* External identifier - may not get initialized */ - if (CurTok.Tok == TOK_ASSIGN) { - Error ("Cannot initialize externals"); - } - /* Add the external symbol to the symbol table */ - AddLocalSym (Decl.Ident, Decl.Type, Decl.StorageClass, 0); } else if ((Decl.StorageClass & SC_STATIC) == SC_STATIC) { /* Static variable */ ParseStaticDecl (&Decl); @@ -484,6 +478,13 @@ static void ParseOneDecl (const DeclSpec* Spec) } else { + if ((Decl.StorageClass & SC_EXTERN) == SC_EXTERN) { + /* External identifier - may not get initialized */ + if (CurTok.Tok == TOK_ASSIGN) { + Error ("Cannot initialize externals"); + } + } + /* Add the symbol to the symbol table */ AddLocalSym (Decl.Ident, Decl.Type, Decl.StorageClass, 0); From b2d3b8379cd3aee9d99ac07080da2d0f73b03638 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 01:38:54 +0800 Subject: [PATCH 1546/2161] Warning about forward declaration of enum types in non-cc65 modes. --- src/cc65/compile.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index ef7dea149..5332caedb 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -276,6 +276,15 @@ static void Parse (void) Entry->Name, Entry->V.BssName); } Entry->V.BssName = xstrdup (bssName); + + /* Check for enum forward declaration. + ** Warn about it when extensions are not allowed. + */ + if (Size == 0 && IsTypeEnum (Decl.Type)) { + if (IS_Get (&Standard) != STD_CC65) { + Warning ("ISO C forbids forward references to 'enum' types"); + } + } } } From 43efc256f16c96d27a750793547b8d99e4fada66 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 5 Aug 2020 00:19:28 +0800 Subject: [PATCH 1547/2161] Changed error/warning messages not using the term 'tentative' according to PR reviews. --- src/cc65/compile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 5332caedb..d045473ff 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -449,7 +449,7 @@ void Compile (const char* FileName) /* Assume array size of 1 */ SetElementCount (Entry->Type, 1); Size = SizeOf (Entry->Type); - Warning ("Tentative array '%s[]' assumed to have one element", Entry->Name); + Warning ("Incomplete array '%s[]' assumed to have one element", Entry->Name); } Sym = GetSymType (GetElementType (Entry->Type)); @@ -474,7 +474,7 @@ void Compile (const char* FileName) Entry->Flags |= SC_DEF; } else { /* Tentative declared variable is still of incomplete type */ - Error ("Tentative definition of '%s' of type '%s' is incomplete", + Error ("Definition of '%s' has type '%s' that is never completed", Entry->Name, GetFullTypeName (Entry->Type)); } From d68cd90e47bfe96a5b85bd57328a25687a59f016 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 6 Aug 2020 17:22:19 +0800 Subject: [PATCH 1548/2161] Function declaration in functions cannot have storage classes other than 'extern'. --- src/cc65/locals.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 03bc80f21..6b4c13fce 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -426,13 +426,25 @@ static void ParseOneDecl (const DeclSpec* Spec) /* Read the declaration */ ParseDecl (Spec, &Decl, DM_NEED_IDENT); - /* Set the correct storage class for functions */ + /* Check if there are any non-extern storage classes set for function + ** declarations. The only valid storage class for function declarations + ** inside functions is 'extern'. + */ if ((Decl.StorageClass & SC_FUNC) == SC_FUNC) { - /* Function prototypes are always external */ - if ((Decl.StorageClass & SC_EXTERN) == 0) { - Warning ("Function must be extern"); + + /* Check if there are explicitly specified non-external storage classes */ + if ((Spec->Flags & DS_DEF_STORAGE) != DS_DEF_STORAGE && + (Decl.StorageClass & SC_EXTERN) == 0 && + (Decl.StorageClass & SC_STORAGEMASK) != 0) { + Error ("Illegal storage class on function"); } + + /* The default storage class could be wrong. Just use 'extern' in all + ** cases. + */ + Decl.StorageClass &= ~SC_STORAGEMASK; Decl.StorageClass |= SC_EXTERN; + } /* If we don't have a name, this was flagged as an error earlier. From 1dd899c7c9e78597f065b4ec085e7bddd244254e Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 8 Aug 2020 06:44:36 +0800 Subject: [PATCH 1549/2161] Fixed non-file-scope multiple definition checking. --- src/cc65/symtab.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 08c909121..25f3b2428 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -1019,9 +1019,18 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs /* We have a symbol with this name already */ if (HandleSymRedefinition (Entry, T, Flags)) { - /* Use the fail-safe table for fictitious symbols */ - Tab = FailSafeTab; Entry = 0; + } else if ((Flags & SC_ESUTYPEMASK) != SC_TYPEDEF) { + /* Redefinitions are not allowed */ + if (SymIsDef (Entry) && (Flags & SC_DEF) == SC_DEF) { + Error ("Multiple definition of '%s'", Entry->Name); + Entry = 0; + } + } + + if (Entry == 0) { + /* Use the fail-safe table for fictitious symbols */ + Tab = FailSafeTab; } } @@ -1033,7 +1042,7 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs Entry->Type = TypeDup (T); if ((Flags & SC_STRUCTFIELD) == SC_STRUCTFIELD || - (Flags & SC_TYPEDEF) == SC_TYPEDEF) { + (Flags & SC_ESUTYPEMASK) == SC_TYPEDEF) { if ((Flags & SC_ALIAS) != SC_ALIAS) { Entry->V.Offs = Offs; } From 0f1a5e0520eccf6d97c0de1c0d1b92a3679274fa Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 8 Aug 2020 06:45:45 +0800 Subject: [PATCH 1550/2161] Set enum tag definition flags. --- src/cc65/symtab.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 25f3b2428..de17c6487 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -697,18 +697,17 @@ SymEntry* AddEnumSym (const char* Name, const Type* Type, SymTable* Tab) /* Existing symbol is not an enum */ Error ("Symbol '%s' is already different kind", Name); Entry = 0; - } else { + } else if (Type != 0) { /* Define the struct size if the underlying type is given. */ - if (Type != 0) { - if (Type !=0 && Entry->V.E.Type != 0) { - /* Both are definitions. */ - Error ("Multiple definition for enum '%s'", Name); - Entry = 0; - } else { - Entry->Type = 0; - Entry->V.E.SymTab = Tab; - Entry->V.E.Type = Type; - } + if (Entry->V.E.Type != 0) { + /* Both are definitions. */ + Error ("Multiple definition for 'enum %s'", Name); + Entry = 0; + } else { + Entry->V.E.SymTab = Tab; + Entry->V.E.Type = Type; + Entry->Flags &= ~SC_DECL; + Entry->Flags |= SC_DEF; } } @@ -724,7 +723,6 @@ SymEntry* AddEnumSym (const char* Name, const Type* Type, SymTable* Tab) Entry = NewSymEntry (Name, SC_ENUM); /* Set the enum type data */ - Entry->Type = 0; Entry->V.E.SymTab = Tab; Entry->V.E.Type = Type; From 68d63b089d9be2e69defac2b9f6002af459bda3a Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 01:34:02 +0800 Subject: [PATCH 1551/2161] Reduced error flood raised by misplaced variable declarations. --- src/cc65/declare.c | 2 +- src/cc65/declare.h | 3 +++ src/cc65/expr.c | 31 +++++++++++++++++++++++++++++-- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 7b868380d..f6aa9c430 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -263,7 +263,7 @@ static void OptionalSigned (void) -static void InitDeclSpec (DeclSpec* D) +void InitDeclSpec (DeclSpec* D) /* Initialize the DeclSpec struct for use */ { D->StorageClass = 0; diff --git a/src/cc65/declare.h b/src/cc65/declare.h index 117ac14a6..615f16a4a 100644 --- a/src/cc65/declare.h +++ b/src/cc65/declare.h @@ -93,6 +93,9 @@ typedef enum { +void InitDeclSpec (DeclSpec* D); +/* Initialize the DeclSpec struct for use */ + Type* ParseType (Type* Type); /* Parse a complete type specification */ diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 65238af61..7b9fd0b9d 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -920,8 +920,35 @@ static void Primary (ExprDesc* E) /* Illegal primary. Be sure to skip the token to avoid endless ** error loops. */ - Error ("Expression expected"); - NextToken (); + { + /* Let's see if this is a C99-style declaration */ + DeclSpec Spec; + InitDeclSpec (&Spec); + ParseDeclSpec (&Spec, -1, T_QUAL_NONE); + + if (Spec.Type->C != T_END) { + + Error ("Mixed declarations and code are not supported in cc65"); + while (CurTok.Tok != TOK_SEMI) { + Declaration Decl; + + /* Parse one declaration */ + ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT); + if (CurTok.Tok == TOK_ASSIGN) { + NextToken (); + ParseInit (Decl.Type); + } + if (CurTok.Tok == TOK_COMMA) { + NextToken (); + } else { + break; + } + } + } else { + Error ("Expression expected"); + NextToken (); + } + } ED_MakeConstAbsInt (E, 1); break; } From 9fcfa3fc49f97c7cbbd6d5840cfa3c9097b77c08 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 8 Aug 2020 06:46:22 +0800 Subject: [PATCH 1552/2161] Fixed full type names of functions with "empty" parameter list. --- 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 18bf41bca..65a0c0cbb 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -133,7 +133,7 @@ static struct StrBuf* GetFullTypeNameWestEast (struct StrBuf* West, struct StrBu if ((F->Flags & FD_VARIADIC) == 0) { if (F->ParamCount > 0) { SB_AppendStr (&ParamList, SB_GetConstBuf (GetFullTypeNameBuf (&Buf, Param->Type))); - } else { + } else if ((F->Flags & FD_EMPTY) == 0) { SB_AppendStr (&ParamList, "void"); } } else { From 9317db6642a512cb0318d134daeb6d7f07299ab7 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 8 Aug 2020 06:46:22 +0800 Subject: [PATCH 1553/2161] Slightly improved type error messages of 'op='. --- 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 7b9fd0b9d..817234ec8 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3408,7 +3408,7 @@ static void opeq (const GenDesc* Gen, ExprDesc* Expr, const char* Op) /* There must be an integer or pointer on the left side */ if (!IsClassInt (Expr->Type) && !IsTypePtr (Expr->Type)) { - Error ("Invalid left operand type"); + Error ("Invalid left operand for binary operator '%s'", Op); /* Continue. Wrong code will be generated, but the compiler won't ** break, so this is the best error recovery. */ @@ -3532,7 +3532,7 @@ static void addsubeq (const GenDesc* Gen, ExprDesc *Expr, const char* Op) /* There must be an integer or pointer on the left side */ if (!IsClassInt (Expr->Type) && !IsTypePtr (Expr->Type)) { - Error ("Invalid left operand type"); + Error ("Invalid left operand for binary operator '%s'", Op); /* Continue. Wrong code will be generated, but the compiler won't ** break, so this is the best error recovery. */ From 0d53806490cf65bccc9420507795a3be2d973847 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 8 Aug 2020 06:46:22 +0800 Subject: [PATCH 1554/2161] Avoided excess errors in incomplete struct assignment. --- 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 207e01588..53e0653ed 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -107,13 +107,13 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) g_push (CF_PTR | CF_UNSIGNED, 0); /* Load the size of the struct or union into the primary */ - g_getimmed (CF_INT | CF_UNSIGNED | CF_CONST, CheckedSizeOf (ltype), 0); + g_getimmed (CF_INT | CF_UNSIGNED | CF_CONST, SizeOf (ltype), 0); /* Call the memcpy function */ g_call (CF_FIXARGC, Func_memcpy, 4); } - return 0; + return 1; } From fe3f726fd695860d1534cd7819632e0fbf3bc944 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 8 Aug 2020 07:04:29 +0800 Subject: [PATCH 1555/2161] Improved incomplete enum typed diagnostics. --- src/cc65/datatype.c | 2 +- src/cc65/declare.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 65a0c0cbb..5794bf5a6 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -976,7 +976,7 @@ unsigned TypeOf (const Type* T) case T_ENUM: /* Incomplete enum type */ - Error ("Incomplete enum type"); + Error ("Incomplete type '%s'", GetFullTypeName (T)); return CF_INT; default: diff --git a/src/cc65/declare.c b/src/cc65/declare.c index f6aa9c430..9539a09b6 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2543,6 +2543,12 @@ static unsigned ParseInitInternal (Type* T, int *Braces, int AllowFlexibleMember case T_UNION: return ParseStructInit (T, Braces, AllowFlexibleMembers); + case T_ENUM: + /* Incomplete enum type must have already raised errors. + ** Just proceed to consume the value. + */ + return ParseScalarInit (T); + case T_VOID: if (IS_Get (&Standard) == STD_CC65) { /* Special cc65 extension in non-ANSI mode */ From b62b1650f57d10611368dc7f70b75599b96888e1 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 8 Aug 2020 20:12:04 +0800 Subject: [PATCH 1556/2161] Improved error messages on struct/union type multiple definitions. --- src/cc65/symtab.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index de17c6487..30fab0593 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -761,7 +761,11 @@ SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTabl Entry = 0; } else if ((Entry->Flags & Flags & SC_DEF) == SC_DEF) { /* Both structs are definitions. */ - Error ("Multiple definition for '%s'", Name); + if (Type == SC_STRUCT) { + Error ("Multiple definition for 'struct %s'", Name); + } else { + Error ("Multiple definition for 'union %s'", Name); + } Entry = 0; } else { /* Define the struct size if it is a definition */ From bde5be67933e247a6362de21e011c7f4147fbea6 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 9 Aug 2020 06:25:36 +0800 Subject: [PATCH 1557/2161] Improved error message on initializing extern variables inside functions. --- src/cc65/locals.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 6b4c13fce..de2074211 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -493,7 +493,10 @@ static void ParseOneDecl (const DeclSpec* Spec) if ((Decl.StorageClass & SC_EXTERN) == SC_EXTERN) { /* External identifier - may not get initialized */ if (CurTok.Tok == TOK_ASSIGN) { - Error ("Cannot initialize externals"); + Error ("Cannot initialize extern variable '%s'", Decl.Ident); + /* Avoid excess errors */ + NextToken (); + ParseInit (Decl.Type); } } From 4dfc1a5ded78e4c2b75e3bf34d3f6ae749ecd5a2 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 10 Aug 2020 09:32:47 +0800 Subject: [PATCH 1558/2161] Using a dedicated SC_FICTITIOUS flag in case of parsing errors. --- src/cc65/compile.c | 2 +- src/cc65/declare.c | 2 +- src/cc65/locals.c | 2 +- src/cc65/symentry.h | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d045473ff..6c881d9a8 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -148,7 +148,7 @@ static void Parse (void) break; } - if ((Decl.StorageClass & SC_ALIAS) == SC_ALIAS) { + if ((Decl.StorageClass & SC_FICTITIOUS) == SC_FICTITIOUS) { /* Failed parsing */ goto SkipOneDecl; } diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 9539a09b6..ac58948bf 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1907,7 +1907,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (PrevErrorCount != ErrorCount) { /* Don't give storage if the declaration is not parsed correctly */ - D->StorageClass |= SC_DECL | SC_ALIAS; + D->StorageClass |= SC_DECL | SC_FICTITIOUS; } } } diff --git a/src/cc65/locals.c b/src/cc65/locals.c index de2074211..12caa7aa2 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -455,7 +455,7 @@ static void ParseOneDecl (const DeclSpec* Spec) } /* If the symbol is not marked as external, it will be defined now */ - if ((Decl.StorageClass & SC_ALIAS) == 0 && + if ((Decl.StorageClass & SC_FICTITIOUS) == 0 && (Decl.StorageClass & SC_EXTERN) == 0) { Decl.StorageClass |= SC_DEF; } diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 1d8af3f50..cfc6379d3 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -106,6 +106,7 @@ struct CodeEntry; #define SC_GOTO_IND 0x800000U /* Indirect goto */ #define SC_ALIAS 0x01000000U /* Alias of anonymous field */ +#define SC_FICTITIOUS 0x02000000U /* Symbol is fictitious */ From 97065faf1a8ca3906d587ef404b6395bee111f83 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 5 Aug 2020 00:19:28 +0800 Subject: [PATCH 1559/2161] Disallowed struct/union types of 0 size as cc65 is not ready to support them. --- src/cc65/declare.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index ac58948bf..636e0d61d 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -919,6 +919,11 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { FieldTab = GetSymTab (); LeaveStructLevel (); + /* 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, UnionSize, FieldTab); } @@ -1101,6 +1106,11 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { FieldTab = GetSymTab (); LeaveStructLevel (); + /* 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, StructSize, FieldTab); } From fe44fe963fa2285096ba8c59d975feef474bd830 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 7 Aug 2020 17:40:40 +0800 Subject: [PATCH 1560/2161] Disallowed empty enums. --- src/cc65/declare.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 636e0d61d..41f96c20a 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -549,8 +549,8 @@ static SymEntry* ParseEnumDecl (const char* Name) ident Ident; long MinConstant = 0; unsigned long MaxConstant = 0; - const Type* NewType = type_int; /* new enumerator type */ - const Type* MemberType = type_int; /* default enumerator type */ + const Type* NewType = 0; /* new member type */ + const Type* MemberType = type_int; /* default member type */ /* Accept forward definitions */ if (CurTok.Tok != TOK_LCURLY) { @@ -677,6 +677,11 @@ static SymEntry* ParseEnumDecl (const char* Name) } ConsumeRCurly (); + /* Check if there have been any members. Error if none */ + if (NewType == 0) { + Error ("Empty enum is invalid"); + } + /* This evaluates the underlying type of the whole enum */ MemberType = GetEnumeratorType (MinConstant, MaxConstant, 0); if (MemberType == 0) { From 8b8561161c09139df076a19609d58312d111a3ce Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 7 Aug 2020 19:35:37 +0800 Subject: [PATCH 1561/2161] Moved #1098 bug tests from test/misc to test/err as they are fixed now. --- test/{misc => err}/bug1098.c | 0 test/{misc => err}/bug1098a.c | 0 test/{misc => err}/bug1098b.c | 0 test/misc/Makefile | 18 ------------------ 4 files changed, 18 deletions(-) rename test/{misc => err}/bug1098.c (100%) rename test/{misc => err}/bug1098a.c (100%) rename test/{misc => err}/bug1098b.c (100%) diff --git a/test/misc/bug1098.c b/test/err/bug1098.c similarity index 100% rename from test/misc/bug1098.c rename to test/err/bug1098.c diff --git a/test/misc/bug1098a.c b/test/err/bug1098a.c similarity index 100% rename from test/misc/bug1098a.c rename to test/err/bug1098a.c diff --git a/test/misc/bug1098b.c b/test/err/bug1098b.c similarity index 100% rename from test/misc/bug1098b.c rename to test/err/bug1098b.c diff --git a/test/misc/Makefile b/test/misc/Makefile index 3c5045753..1d98e2d62 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -87,24 +87,6 @@ $(WORKDIR)/bug264.$1.$2.prg: bug264.c | $(WORKDIR) $(if $(QUIET),echo misc/bug264.$1.$2.prg) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) -# this should fail to compile, because there are errors in the code -$(WORKDIR)/bug1098.$1.$2.prg: bug1098.c | $(WORKDIR) - @echo "FIXME: " $$@ "compiles but should give an error." - $(if $(QUIET),echo misc/bug1098.$1.$2.prg) - $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - -# this should fail to compile, because there are errors in the code -$(WORKDIR)/bug1098a.$1.$2.prg: bug1098a.c | $(WORKDIR) - @echo "FIXME: " $$@ "compiles but should give an error." - $(if $(QUIET),echo misc/bug1098a.$1.$2.prg) - $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - -# this should fail to compile, because there are errors in the code -$(WORKDIR)/bug1098b.$1.$2.prg: bug1098b.c | $(WORKDIR) - @echo "FIXME: " $$@ "compiles but should give an error." - $(if $(QUIET),echo misc/bug1098b.$1.$2.prg) - $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - # this should fail to compile, because there are errors in the code # instead, the compiler crashes $(WORKDIR)/bug1113.$1.$2.prg: bug1113.c | $(WORKDIR) From eb4464e8283cfeedeb560b7b0e0cc0561e4e3c3d Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 3 Aug 2020 01:38:54 +0800 Subject: [PATCH 1562/2161] Fixed type comparisons of ESU types with stricter rules. --- src/cc65/typecmp.c | 111 +++++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 65 deletions(-) diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 0eddf2988..39f13b79e 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -148,41 +148,6 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) -static int EqualSymTables (SymTable* Tab1, SymTable* Tab2) -/* Compare two symbol tables. Return 1 if they are equal and 0 otherwise */ -{ - /* Compare the parameter lists */ - SymEntry* Sym1 = Tab1->SymHead; - SymEntry* Sym2 = Tab2->SymHead; - - /* Compare the fields */ - while (Sym1 && Sym2) { - - /* Compare the names of this field */ - if (!HasAnonName (Sym1) || !HasAnonName (Sym2)) { - if (strcmp (Sym1->Name, Sym2->Name) != 0) { - /* Names are not identical */ - return 0; - } - } - - /* Compare the types of this field */ - if (TypeCmp (Sym1->Type, Sym2->Type) < TC_EQUAL) { - /* Field types not equal */ - return 0; - } - - /* Get the pointers to the next fields */ - Sym1 = Sym1->NextSym; - Sym2 = Sym2->NextSym; - } - - /* Check both pointers against NULL to compare the field count */ - return (Sym1 == 0 && Sym2 == 0); -} - - - static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) /* Recursively compare two types. */ { @@ -190,8 +155,6 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) unsigned ElementCount; SymEntry* Sym1; SymEntry* Sym2; - SymTable* Tab1; - SymTable* Tab2; FuncDesc* F1; FuncDesc* F2; @@ -235,6 +198,40 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) return; } + /* Enums must be handled specially */ + if ((IsTypeEnum (lhs) || IsTypeEnum (rhs))) { + + /* Compare the tag types */ + Sym1 = GetESUSymEntry (lhs); + Sym2 = GetESUSymEntry (rhs); + + if (Sym1 != Sym2) { + if (Sym1 == 0 || Sym2 == 0) { + + /* Only one is an enum. So they can't be identical */ + SetResult (Result, TC_STRICT_COMPATIBLE); + + } else { + /* For the two to be identical, they must be in the same + ** scope and have the same name. + */ + if (Sym1->Owner != Sym2->Owner || + strcmp (Sym1->Name, Sym2->Name) != 0) { + + /* If any one of the two is incomplete, we can't guess + ** their underlying types and have to assume that they + ** be incompatible. + */ + if (SizeOf (lhs) == 0 || SizeOf (rhs) == 0) { + SetResult (Result, TC_INCOMPATIBLE); + return; + } + } + } + } + + } + /* On indirection level zero, a qualifier or sign difference is ** accepted. The types are no longer equal, but compatible. */ @@ -364,41 +361,25 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) case T_TYPE_STRUCT: case T_TYPE_UNION: - /* Compare the fields recursively. To do that, we fetch the - ** pointer to the struct definition from the type, and compare - ** the fields. - */ + /* Compare the tag types */ Sym1 = GetESUSymEntry (lhs); Sym2 = GetESUSymEntry (rhs); - /* If one symbol has a name, the names must be identical */ - if (!HasAnonName (Sym1) || !HasAnonName (Sym2)) { - if (strcmp (Sym1->Name, Sym2->Name) != 0) { - /* Names are not identical */ + CHECK (Sym1 != 0 || Sym2 != 0); + + if (Sym1 != Sym2) { + /* Both must be in the same scope and have the same name to + ** be identical. This shouldn't happen in the current code + ** base, but we still do this to be future-proof. + */ + if (Sym1->Owner != Sym2->Owner || + strcmp (Sym1->Name, Sym2->Name) != 0) { SetResult (Result, TC_INCOMPATIBLE); return; } } - /* Get the field tables from the struct entry */ - Tab1 = Sym1->V.S.SymTab; - Tab2 = Sym2->V.S.SymTab; - - /* One or both structs may be forward definitions. In this case, - ** the symbol tables are both non existant. Assume that the - ** structs are equal in this case. - */ - if (Tab1 != 0 && Tab2 != 0) { - - if (EqualSymTables (Tab1, Tab2) == 0) { - /* Field lists are not equal */ - SetResult (Result, TC_INCOMPATIBLE); - return; - } - - } - - /* Structs are equal */ + /* Both are identical */ break; } @@ -410,7 +391,7 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) /* Check if end of rhs reached */ if (rhs->C == T_END) { - SetResult (Result, TC_EQUAL); + SetResult (Result, TC_IDENTICAL); } else { SetResult (Result, TC_INCOMPATIBLE); } From 03b37cf7127deab8c5c7a659550e08b793610302 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 8 Aug 2020 06:46:55 +0800 Subject: [PATCH 1563/2161] Fixed type comparisons of typedefs and arrays. --- src/cc65/symtab.c | 71 +++++++++++++++++++++++----------------------- src/cc65/typecmp.c | 15 ++++++---- src/cc65/typecmp.h | 2 +- 3 files changed, 45 insertions(+), 43 deletions(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 30fab0593..316963ee9 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -558,34 +558,46 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags unsigned E_SCType = Entry->Flags & SC_TYPEMASK; unsigned SCType = Flags & SC_TYPEMASK; - /* Some symbols may be redeclared if certain requirements are met */ - if (IsTypeArray (T) && IsTypeArray (E_Type)) { + /* Existing typedefs cannot be redeclared as anything different */ + if (E_SCType == SC_TYPEDEF) { - /* Get the array sizes */ - long Size = GetElementCount (T); - long ESize = GetElementCount (E_Type); - - /* If we are handling arrays, the old entry or the new entry may be - ** an incomplete declaration. Accept this, and if the exsting entry - ** is incomplete, complete it. - */ - if ((Size != UNSPECIFIED && ESize != UNSPECIFIED && Size != ESize) || - TypeCmp (T + 1, E_Type + 1) < TC_EQUAL) { - /* Types not identical: Conflicting types */ - Error ("Conflicting array types for '%s[]'", Entry->Name); - Entry = 0; - } else { - /* Check if we have a size in the existing definition */ - if (ESize == UNSPECIFIED) { - /* Existing, size not given, use size from new def */ - SetElementCount (E_Type, Size); + if (SCType == SC_TYPEDEF) { + if (TypeCmp (E_Type, T) < TC_IDENTICAL) { + Error ("Conflicting types for typedef '%s'", Entry->Name); + Entry = 0; } + } else { + Error ("Redefinition of typedef '%s' as different kind of symbol", Entry->Name); + Entry = 0; } } else { - /* We have a symbol with this name already */ - if ((Entry->Flags & SC_FUNC) == SC_FUNC) { + /* Some symbols may be redeclared if certain requirements are met */ + if (IsTypeArray (T) && IsTypeArray (E_Type)) { + + /* Get the array sizes */ + long Size = GetElementCount (T); + long ESize = GetElementCount (E_Type); + + /* If we are handling arrays, the old entry or the new entry may be + ** an incomplete declaration. Accept this, and if the exsting entry + ** is incomplete, complete it. + */ + if ((Size != UNSPECIFIED && ESize != UNSPECIFIED && Size != ESize) || + TypeCmp (T + 1, E_Type + 1) < TC_EQUAL) { + /* Conflicting element types */ + Error ("Conflicting array types for '%s[]'", Entry->Name); + Entry = 0; + } else { + /* Check if we have a size in the existing definition */ + if (ESize == UNSPECIFIED) { + /* Existing, size not given, use size from new def */ + SetElementCount (E_Type, Size); + } + } + + } else if ((Entry->Flags & SC_FUNC) == 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 @@ -616,22 +628,9 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags Entry = 0; } - } else if (E_SCType == SC_TYPEDEF) { - - if (SCType == SC_TYPEDEF) { - /* New typedef must be identical */ - if (TypeCmp (E_Type, T) < TC_EQUAL) { - Error ("Conflicting types for typedef '%s'", Entry->Name); - Entry = 0; - } - } else { - Error ("Redefinition of typedef '%s' as different kind of symbol", Entry->Name); - Entry = 0; - } - } else { - /* New type must be identical */ + /* New type must be equivalent */ if (SCType != E_SCType) { Error ("Redefinition of '%s' as different kind of symbol", Entry->Name); Entry = 0; diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 39f13b79e..e14ace6b9 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -190,6 +190,7 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) */ if (LeftType == T_TYPE_PTR && RightType == T_TYPE_ARRAY) { RightType = T_TYPE_PTR; + SetResult (Result, TC_STRICT_COMPATIBLE); } /* If the underlying types are not identical, the types are incompatible */ @@ -350,12 +351,14 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) /* Check member count */ LeftCount = GetElementCount (lhs); RightCount = GetElementCount (rhs); - if (LeftCount != UNSPECIFIED && - RightCount != UNSPECIFIED && - LeftCount != RightCount) { - /* Member count given but different */ - SetResult (Result, TC_INCOMPATIBLE); - return; + if (LeftCount != RightCount) { + if (LeftCount != UNSPECIFIED && + RightCount != UNSPECIFIED) { + /* Member count given but different */ + SetResult (Result, TC_INCOMPATIBLE); + return; + } + SetResult (Result, TC_EQUAL); } break; diff --git a/src/cc65/typecmp.h b/src/cc65/typecmp.h index 5f95e42a1..3e95adb3f 100644 --- a/src/cc65/typecmp.h +++ b/src/cc65/typecmp.h @@ -55,7 +55,7 @@ typedef enum { TC_COMPATIBLE = TC_SIGN_DIFF, /* Compatible types */ TC_QUAL_DIFF, /* Types differ in qualifier of pointer */ TC_STRICT_COMPATIBLE, /* Strict compatibility */ - TC_EQUAL, /* Types are equal */ + TC_EQUAL, /* Types are equivalent */ TC_IDENTICAL /* Types are identical */ } typecmp_t; From 0fa18886c066278b6e1129b588dc9ff9e408f4d0 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 13 Aug 2020 09:27:53 +0800 Subject: [PATCH 1564/2161] Fixed copying structs/unions > 4 bytes. --- src/cc65/assignment.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index 53e0653ed..6e25eaa56 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -58,22 +58,23 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) /* Copy the struct/union represented by RExpr to the one represented by LExpr */ { /* If the size is that of a basic type (char, int, long), we will copy - ** the struct using the primary register, otherwise we use memcpy. In - ** the former case, push the address only if really needed. + ** the struct using the primary register, otherwise we will use memcpy. */ const Type* ltype = LExpr->Type; const Type* stype = GetStructReplacementType (ltype); int UseReg = (stype != ltype); if (UseReg) { + /* Back up the address of lhs only if it is in the primary */ PushAddr (LExpr); } else { - ED_MarkExprAsRVal (LExpr); + /* Push the address of lhs as the destination of memcpy */ + ED_AddrExpr (LExpr); LoadExpr (CF_NONE, LExpr); g_push (CF_PTR | CF_UNSIGNED, 0); } - /* Get the expression on the right of the '=' into the primary */ + /* Get the expression on the right of the '=' */ hie1 (RExpr); /* Check for equality of the structs */ @@ -82,28 +83,27 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) "Incompatible types in assignment to '%s' from '%s'"); } - /* Do we copy using the primary? */ + /* Do we copy the value directly using the primary? */ if (UseReg) { - /* Check if the right hand side is an lvalue */ - if (ED_IsLVal (RExpr)) { + /* Check if the value of the rhs is not in the primary yet */ + if (!ED_IsLocPrimary (RExpr)) { /* Just load the value into the primary as the replacement type. */ LoadExpr (TypeOf (stype) | CF_FORCECHAR, RExpr); } - /* Store it into the new location */ + /* Store it into the location referred in the primary */ Store (LExpr, stype); } else { - /* Check if the right hand side is an lvalue */ - if (ED_IsLVal (RExpr)) { - /* We will use memcpy. Push the address of the rhs */ - ED_MarkExprAsRVal (RExpr); + /* The only way this can happen is in chained assignments */ + if (!ED_IsLocPrimary (RExpr)) { + ED_AddrExpr (RExpr); LoadExpr (CF_NONE, RExpr); } - /* Push the address (or whatever is in ax in case of errors) */ + /* Push the address of the rhs as the source of memcpy */ g_push (CF_PTR | CF_UNSIGNED, 0); /* Load the size of the struct or union into the primary */ @@ -111,6 +111,9 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) /* Call the memcpy function */ g_call (CF_FIXARGC, Func_memcpy, 4); + + /* Restore the indirection level of lhs */ + ED_IndExpr (LExpr); } return 1; @@ -257,6 +260,6 @@ void Assignment (ExprDesc* Expr) } - /* Value is still in primary and not an lvalue */ + /* Value might be still in primary and not an lvalue */ ED_FinalizeRValLoad (Expr); } From 0dfe9ff5fe8ac5056aa37d727b2f986e4732faab Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 14 Aug 2020 08:32:22 +0800 Subject: [PATCH 1565/2161] Fixed testing 'struct->field'. --- src/cc65/assignment.c | 8 +++++++- src/cc65/expr.c | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index 6e25eaa56..0151a9000 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -77,7 +77,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) /* Get the expression on the right of the '=' */ hie1 (RExpr); - /* Check for equality of the structs */ + /* Check for equality of the structs/unions */ if (TypeCmp (ltype, RExpr->Type) < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (ltype, RExpr->Type, 1, "Incompatible types in assignment to '%s' from '%s'"); @@ -114,6 +114,12 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) /* Restore the indirection level of lhs */ ED_IndExpr (LExpr); + + /* Clear the tested flag set during loading. This is not neccessary + ** currently (and probably ever) as a struct/union cannot be converted + ** to a boolean in C, but there is no harm to be future-proof. + */ + ED_MarkAsUntested (LExpr); } return 1; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 817234ec8..f75015305 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1301,6 +1301,9 @@ static void StructRef (ExprDesc* Expr) LoadExpr (CF_NONE, Expr); } + /* Clear the tested flag set during loading */ + ED_MarkAsUntested (Expr); + /* The type is the field type plus any qualifiers from the struct/union */ if (IsClassStruct (Expr->Type)) { Q = GetQualifier (Expr->Type); From dc83eb15aff2eaf0cab5f3964d93846740eb7feb Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 14 Aug 2020 16:12:17 +0200 Subject: [PATCH 1566/2161] added test related to issue #1181 --- test/val/bug1181.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 test/val/bug1181.c diff --git a/test/val/bug1181.c b/test/val/bug1181.c new file mode 100644 index 000000000..4ea2d54bf --- /dev/null +++ b/test/val/bug1181.c @@ -0,0 +1,86 @@ + +/* bug #1181 - Testing struct member against NULL is broken */ + +#include <stdio.h> +#include <stdlib.h> + +struct { + int a; +} s = { 256 }, *ps = &s; + +int res = EXIT_SUCCESS; + +void test1(void) +{ + if (ps->a) { + printf("OK\n"); + } else { + printf("ERROR: %d\n", ps->a); + res = EXIT_FAILURE; + } +} + +typedef struct _MENUITEM +{ + char *name; +} MENUITEM; + +typedef struct _MENU +{ + struct _MENUITEM *items; +} MENU; + +/* note: the behaviour changes when these strings are changed! */ +static unsigned char oi31[] = {"Browser Exec Setup"}; +static unsigned char oi36[] = {"Browser auto sort"}; +static unsigned char oi47[] = {"Browser startup"}; +static unsigned char oi49[] = {"Browser charset"}; +static unsigned char oi55[] = {"Menu color scheme"}; +static unsigned char oi63[] = {"Menu input scheme"}; +static unsigned char oi35[] = {"back"}; + +MENUITEM optionsitems_menu[] = { + {oi31}, + {oi36}, + {oi47}, + {oi49}, + {oi55}, + {oi63}, + {oi35}, + {NULL} +}; + +static MENU optionsmenu_menu = { + &optionsitems_menu[0], +}; + +unsigned char __fastcall__ menu_getnumitems(MENU *menu) +{ +static unsigned char numitems; +MENUITEM *items; + numitems = 0; + items = menu->items; + while(items->name) + { + ++numitems; + ++items; + } + return numitems; +} + +int main(void) +{ + unsigned char i = 0; + + i = menu_getnumitems(&optionsmenu_menu); + printf("numitems (expected 7): %d\n", i); + + if (i != 7) { + printf("failed\n"); + res = EXIT_FAILURE; + } + printf("passed\n"); + + test1(); + return res; +} From 8a417ff03952b30ed478d4414c42fbf3bed5c28b Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 12 Aug 2020 21:33:46 +0800 Subject: [PATCH 1567/2161] Improved ESU declaration failure handling. --- src/cc65/declare.c | 73 ++++++++++++++++++++++++++++++---------------- src/cc65/symtab.c | 25 ++++++++++++---- src/cc65/symtab.h | 4 +-- 3 files changed, 70 insertions(+), 32 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 41f96c20a..259f8b8ac 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -479,7 +479,7 @@ static void ParseStorageClass (DeclSpec* D, unsigned DefStorage) -static SymEntry* ESUForwardDecl (const char* Name, unsigned Type) +static SymEntry* ESUForwardDecl (const char* Name, unsigned Flags) /* Handle an enum, struct or union forward decl */ { /* Try to find an enum/struct/union with the given name. If there is none, @@ -487,12 +487,12 @@ static SymEntry* ESUForwardDecl (const char* Name, unsigned Type) */ SymEntry* Entry = FindTagSym (Name); if (Entry == 0) { - if (Type != SC_ENUM) { - Entry = AddStructSym (Name, Type, 0, 0); + if ((Flags & SC_ESUTYPEMASK) != SC_ENUM) { + Entry = AddStructSym (Name, Flags, 0, 0); } else { - Entry = AddEnumSym (Name, 0, 0); + Entry = AddEnumSym (Name, Flags, 0, 0); } - } else if ((Entry->Flags & SC_TYPEMASK) != Type) { + } else if ((Entry->Flags & SC_TYPEMASK) != (Flags & SC_ESUTYPEMASK)) { /* Already defined, but not the same type class */ Error ("Symbol '%s' is already different kind", Name); } @@ -551,14 +551,17 @@ static SymEntry* ParseEnumDecl (const char* Name) unsigned long MaxConstant = 0; const Type* NewType = 0; /* new member type */ const Type* MemberType = type_int; /* default member type */ + unsigned Flags = 0; + unsigned PrevErrorCount = ErrorCount; + - /* Accept forward definitions */ if (CurTok.Tok != TOK_LCURLY) { + /* Just a forward definition */ return ESUForwardDecl (Name, SC_ENUM); } - /* Add the enum tag */ - AddEnumSym (Name, 0, 0); + /* Add a forward declaration for the enum tag in the current lexical level */ + AddEnumSym (Name, 0, 0, 0); /* Skip the opening curly brace */ NextToken (); @@ -695,7 +698,13 @@ static SymEntry* ParseEnumDecl (const char* Name) } FieldTab = GetSymTab (); - return AddEnumSym (Name, MemberType, FieldTab); + + /* Return a fictitious symbol if errors occurred during parsing */ + if (PrevErrorCount != ErrorCount) { + Flags |= SC_FICTITIOUS; + } + + return AddEnumSym (Name, Flags, MemberType, FieldTab); } @@ -829,19 +838,21 @@ static SymEntry* ParseUnionDecl (const char* Name) unsigned FieldSize; int FieldWidth; /* Width in bits, -1 if not a bit-field */ SymTable* FieldTab; - SymEntry* StructTypeEntry; + SymEntry* UnionTagEntry; SymEntry* Entry; + unsigned Flags = 0; + unsigned PrevErrorCount = ErrorCount; if (CurTok.Tok != TOK_LCURLY) { - /* Just a forward declaration. */ + /* Just a forward declaration */ return ESUForwardDecl (Name, SC_UNION); } - /* Add a forward declaration for the struct in the current lexical level */ - StructTypeEntry = AddStructSym (Name, SC_UNION, 0, 0); + /* Add a forward declaration for the union tag in the current lexical level */ + UnionTagEntry = AddStructSym (Name, SC_UNION, 0, 0); - StructTypeEntry->V.S.ACount = 0; + UnionTagEntry->V.S.ACount = 0; /* Skip the curly brace */ NextToken (); @@ -883,7 +894,7 @@ static SymEntry* ParseUnionDecl (const char* Name) /* This is an anonymous struct or union. Copy the fields ** into the current level. */ - AnonFieldName (Decl.Ident, "field", StructTypeEntry->V.S.ACount); + AnonFieldName (Decl.Ident, "field", UnionTagEntry->V.S.ACount); } else { /* A non bit-field without a name is legal but useless */ Warning ("Declaration does not declare anything"); @@ -902,7 +913,7 @@ static SymEntry* ParseUnionDecl (const char* Name) } else { if (IsAnonName (Decl.Ident)) { Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0); - Entry->V.A.ANumber = StructTypeEntry->V.S.ACount++; + Entry->V.A.ANumber = UnionTagEntry->V.S.ACount++; AliasAnonStructFields (&Decl, Entry); } else { AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0); @@ -929,8 +940,13 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { Error ("Empty union type '%s' is not supported", Name); } + /* Return a fictitious symbol if errors occurred during parsing */ + if (PrevErrorCount != ErrorCount) { + Flags |= SC_FICTITIOUS; + } + /* Make a real entry from the forward decl and return it */ - return AddStructSym (Name, SC_UNION | SC_DEF, UnionSize, FieldTab); + return AddStructSym (Name, SC_UNION | SC_DEF | Flags, UnionSize, FieldTab); } @@ -944,19 +960,21 @@ static SymEntry* ParseStructDecl (const char* Name) unsigned BitOffs; /* Bit offset for bit-fields */ int FieldWidth; /* Width in bits, -1 if not a bit-field */ SymTable* FieldTab; - SymEntry* StructTypeEntry; + SymEntry* StructTagEntry; SymEntry* Entry; + unsigned Flags = 0; + unsigned PrevErrorCount = ErrorCount; if (CurTok.Tok != TOK_LCURLY) { - /* Just a forward declaration. */ + /* Just a forward declaration */ return ESUForwardDecl (Name, SC_STRUCT); } - /* Add a forward declaration for the struct in the current lexical level */ - StructTypeEntry = AddStructSym (Name, SC_STRUCT, 0, 0); + /* Add a forward declaration for the struct tag in the current lexical level */ + StructTagEntry = AddStructSym (Name, SC_STRUCT, 0, 0); - StructTypeEntry->V.S.ACount = 0; + StructTagEntry->V.S.ACount = 0; /* Skip the curly brace */ NextToken (); @@ -1050,7 +1068,7 @@ static SymEntry* ParseStructDecl (const char* Name) /* This is an anonymous struct or union. Copy the ** fields into the current level. */ - AnonFieldName (Decl.Ident, "field", StructTypeEntry->V.S.ACount); + AnonFieldName (Decl.Ident, "field", StructTagEntry->V.S.ACount); } else { /* A non bit-field without a name is legal but useless */ Warning ("Declaration does not declare anything"); @@ -1078,7 +1096,7 @@ static SymEntry* ParseStructDecl (const char* Name) } else { if (IsAnonName (Decl.Ident)) { Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize); - Entry->V.A.ANumber = StructTypeEntry->V.S.ACount++; + Entry->V.A.ANumber = StructTagEntry->V.S.ACount++; AliasAnonStructFields (&Decl, Entry); } else { AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize); @@ -1116,8 +1134,13 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { Error ("Empty struct type '%s' is not supported", Name); } + /* Return a fictitious symbol if errors occurred during parsing */ + if (PrevErrorCount != ErrorCount) { + Flags |= SC_FICTITIOUS; + } + /* Make a real entry from the forward decl and return it */ - return AddStructSym (Name, SC_STRUCT | SC_DEF, StructSize, FieldTab); + return AddStructSym (Name, SC_STRUCT | SC_DEF | Flags, StructSize, FieldTab); } diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 316963ee9..53c30254d 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -682,13 +682,21 @@ static void AddSymEntry (SymTable* T, SymEntry* S) -SymEntry* AddEnumSym (const char* Name, const Type* Type, SymTable* Tab) +SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTable* Tab) /* Add an enum entry and return it */ { SymTable* CurTagTab = TagTab; + SymEntry* Entry; + + if ((Flags & SC_FICTITIOUS) == 0) { + /* Do we have an entry with this name already? */ + Entry = FindSymInTable (CurTagTab, Name, HashStr (Name)); + } else { + /* Add a fictitious symbol in the fail-safe table */ + Entry = 0; + CurTagTab = FailSafeTab; + } - /* Do we have an entry with this name already? */ - SymEntry* Entry = FindSymInTable (CurTagTab, Name, HashStr (Name)); if (Entry) { /* We do have an entry. This may be a forward, so check it. */ @@ -749,8 +757,15 @@ SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTabl /* Type must be struct or union */ PRECONDITION (Type == SC_STRUCT || Type == SC_UNION); - /* Do we have an entry with this name already? */ - Entry = FindSymInTable (CurTagTab, Name, HashStr (Name)); + if ((Flags & SC_FICTITIOUS) == 0) { + /* Do we have an entry with this name already? */ + Entry = FindSymInTable (CurTagTab, Name, HashStr (Name)); + } else { + /* Add a fictitious symbol in the fail-safe table */ + Entry = 0; + CurTagTab = FailSafeTab; + } + if (Entry) { /* We do have an entry. This may be a forward, so check it. */ diff --git a/src/cc65/symtab.h b/src/cc65/symtab.h index 79f656f95..f04517fed 100644 --- a/src/cc65/symtab.h +++ b/src/cc65/symtab.h @@ -149,10 +149,10 @@ unsigned short FindSPAdjustment (const char* Name); -SymEntry* AddEnumSym (const char* Name, const Type* Type, SymTable* Tab); +SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTable* Tab); /* Add an enum entry and return it */ -SymEntry* AddStructSym (const char* Name, unsigned Type, unsigned Size, SymTable* Tab); +SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTable* Tab); /* Add a struct/union entry and return it */ SymEntry* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsigned BitWidth); From 44d52935dafde30886caf03d8c4b1fe1f3832870 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 12 Aug 2020 21:35:44 +0800 Subject: [PATCH 1568/2161] Utility for getting the composite types of functions. --- src/cc65/typecmp.c | 134 +++++++++++++++++++++++++++++++++++++++++++++ src/cc65/typecmp.h | 2 + 2 files changed, 136 insertions(+) diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index e14ace6b9..e3e42e67f 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -421,3 +421,137 @@ typecmp_t TypeCmp (const Type* lhs, const Type* rhs) /* Return the result */ return Result; } + + + +static Type* DoComposite (Type* lhs, const Type* rhs); + +static void CompositeFuncParams (const FuncDesc* F1, const FuncDesc* F2) +/* Composite two function symbol tables regarding function parameters */ +{ + /* Get the symbol tables */ + const SymTable* Tab1 = F1->SymTab; + const SymTable* Tab2 = F2->SymTab; + + /* Composite the parameter lists */ + const SymEntry* Sym1 = Tab1->SymHead; + const SymEntry* Sym2 = Tab2->SymHead; + + /* Composite the fields */ + while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { + + /* Get the symbol types */ + Type* Type1 = Sym1->Type; + Type* Type2 = Sym2->Type; + + /* If either of both functions is old style, apply the default + ** promotions to the parameter type. + */ + if (F1->Flags & FD_OLDSTYLE) { + if (IsClassInt (Type1)) { + Type1 = IntPromotion (Type1); + } + } + if (F2->Flags & FD_OLDSTYLE) { + if (IsClassInt (Type2)) { + Type2 = IntPromotion (Type2); + } + } + + /* Composite this field */ + DoComposite (Type1, Type2); + + /* Get the pointers to the next fields */ + Sym1 = Sym1->NextSym; + Sym2 = Sym2->NextSym; + } +} + + + +static Type* DoComposite (Type* lhs, const Type* rhs) +/* Recursively composite two types into lhs */ +{ + FuncDesc* F1; + FuncDesc* F2; + long LeftCount, RightCount; + + /* Composite two types */ + while (lhs->C != T_END) { + + /* Check if the end of the type string is reached */ + if (rhs->C == T_END) { + return lhs; + } + + /* Check for sanity */ + CHECK (GetUnderlyingTypeCode (lhs) == GetUnderlyingTypeCode (rhs)); + + /* Check for special type elements */ + + if (IsTypeFunc (lhs)) { + /* Composite the function descriptors */ + F1 = GetFuncDesc (lhs); + F2 = GetFuncDesc (rhs); + + /* If one of both functions has an empty parameter list (which + ** does also mean, it is not a function definition, because the + ** flag is reset in this case), it is replaced by the other + ** definition, provided that the other has no default + ** promotions in the parameter list. If none of both parameter + ** lists is empty, we have to composite the parameter lists and + ** other attributes. + */ + if ((F1->Flags & FD_EMPTY) == FD_EMPTY) { + if ((F2->Flags & FD_EMPTY) == 0) { + /* Copy the parameters and flags */ + TypeCopy (lhs, rhs); + F1->Flags = F2->Flags; + } + } else if ((F2->Flags & FD_EMPTY) == 0) { + /* Composite the parameter lists */ + CompositeFuncParams (F1, F2); + } + + } else if (IsTypeArray (lhs)) { + /* Check member count */ + LeftCount = GetElementCount (lhs); + RightCount = GetElementCount (rhs); + + /* Set composite type if it is requested */ + if (LeftCount != UNSPECIFIED) { + SetElementCount (lhs, LeftCount); + } else if (RightCount != UNSPECIFIED) { + SetElementCount (lhs, RightCount); + } + } + + /* Next type string element */ + ++lhs; + ++rhs; + } + + return lhs; +} + + + +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) { + DoComposite (OldType, NewType); + } else { + TypeCopy (OldType, NewType); + Old->Flags &= ~FD_EMPTY; + } + } + + return Old; +} diff --git a/src/cc65/typecmp.h b/src/cc65/typecmp.h index 3e95adb3f..f4a87bcf6 100644 --- a/src/cc65/typecmp.h +++ b/src/cc65/typecmp.h @@ -70,6 +70,8 @@ typedef enum { typecmp_t TypeCmp (const Type* lhs, const Type* rhs); /* Compare two types and return the result */ +FuncDesc* RefineFuncDesc (Type* OldType, const Type* NewType); +/* Refine the existing function descriptor with a new one */ /* End of typecmp.h */ From 13ed557b92586765ccc35b43ddc2359521bcca70 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 12 Aug 2020 21:35:47 +0800 Subject: [PATCH 1569/2161] Fixed compatibility checking of function declarations by using the composite types of them. --- src/cc65/codeinfo.c | 2 +- src/cc65/compile.c | 32 ++++++------ src/cc65/datatype.c | 22 ++++++++ src/cc65/datatype.h | 6 +++ src/cc65/declare.c | 2 +- src/cc65/function.c | 4 +- src/cc65/locals.c | 22 +++++--- src/cc65/pragma.c | 2 +- src/cc65/symentry.h | 2 +- src/cc65/symtab.c | 123 ++++++++++++++++++++++++-------------------- 10 files changed, 129 insertions(+), 88 deletions(-) diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index b1e5668ce..c9dea5071 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -392,7 +392,7 @@ fncls_t GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) /* Did we find it in the top-level table? */ if (E && IsTypeFunc (E->Type)) { - FuncDesc* D = E->V.F.Func; + FuncDesc* D = GetFuncCompositeDesc (E); /* A variadic function will use the Y register (the parameter list ** size is passed there). A fastcall function will use the A or A/X diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 6c881d9a8..54918fb21 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -177,18 +177,23 @@ static void Parse (void) } /* If this is a function declarator that is not followed by a comma - ** or semicolon, it must be followed by a function body. If this is - ** the case, convert an empty parameter list into one accepting no - ** parameters (same as void) as required by the standard. + ** or semicolon, it must be followed by a function body. */ - if ((Decl.StorageClass & SC_FUNC) != 0 && - (CurTok.Tok != TOK_COMMA) && - (CurTok.Tok != TOK_SEMI)) { + if ((Decl.StorageClass & SC_FUNC) != 0) { + if (CurTok.Tok != TOK_COMMA && CurTok.Tok != TOK_SEMI) { + /* A definition */ + Decl.StorageClass |= SC_DEF; - FuncDesc* D = GetFuncDesc (Decl.Type); - - if (D->Flags & FD_EMPTY) { - D->Flags = (D->Flags & ~FD_EMPTY) | FD_VOID_PARAM; + /* Convert an empty parameter list into one accepting no + ** parameters (same as void) as required by the standard. + */ + FuncDesc* D = GetFuncDesc (Decl.Type); + if (D->Flags & FD_EMPTY) { + D->Flags = (D->Flags & ~FD_EMPTY) | FD_VOID_PARAM; + } + } else { + /* Just a declaration */ + Decl.StorageClass |= SC_DECL; } } @@ -309,13 +314,6 @@ SkipOneDecl: /* Prototype only */ NextToken (); } else { - - /* Function body. Check for duplicate function definitions */ - if (SymIsDef (Entry)) { - Error ("Body for function '%s' has already been defined", - Entry->Name); - } - /* Parse the function body */ NewFunc (Entry); } diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 5794bf5a6..94aea9cc1 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -1115,6 +1115,28 @@ Type* GetFuncReturn (Type* T) +Type* GetFuncCompositeType (SymEntry* Func) +/* Get the composite function type */ +{ + /* Be sure it's a function type */ + CHECK (IsClassFunc (Func->Type)); + + return Func->V.F.Composite->Type; +} + + + +FuncDesc* GetFuncCompositeDesc (SymEntry* Func) +/* Get the composite function type descriptor */ +{ + /* Be sure it's a function type */ + CHECK (IsClassFunc (Func->Type)); + + return GetFuncDesc (Func->V.F.Composite->Type); +} + + + long GetElementCount (const Type* T) /* Get the element count of the array specified in T (which must be of ** array type). diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 6cbad302f..1ff8333c6 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -753,6 +753,12 @@ void SetFuncDesc (Type* T, FuncDesc* F); Type* GetFuncReturn (Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ +Type* GetFuncCompositeType (struct SymEntry* Func); +/* Get the composite function type */ + +FuncDesc* GetFuncCompositeDesc (struct SymEntry* Func); +/* Get the composite function type descriptor */ + long GetElementCount (const Type* T); /* Get the element count of the array specified in T (which must be of ** array type). diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 259f8b8ac..36286b6d5 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1749,7 +1749,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Was there a previous entry? If so, copy WrappedCall info from it */ PrevEntry = FindGlobalSym (D->Ident); if (PrevEntry && PrevEntry->Flags & SC_FUNC) { - FuncDesc* D = PrevEntry->V.F.Func; + FuncDesc* D = GetFuncDesc (PrevEntry->Type); if (D->WrappedCall && !F->WrappedCall) { F->WrappedCall = D->WrappedCall; F->WrappedCallData = D->WrappedCallData; diff --git a/src/cc65/function.c b/src/cc65/function.c index 5d0b09380..b2291b312 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -295,7 +295,7 @@ static void F_RestoreRegVars (Function* F) } /* Get the first symbol from the function symbol table */ - Sym = F->FuncEntry->V.F.Func->SymTab->SymHead; + Sym = GetFuncDesc (F->FuncEntry->Type)->SymTab->SymHead; /* Walk through all symbols checking for register variables */ while (Sym) { @@ -383,7 +383,7 @@ void NewFunc (SymEntry* Func) const Type* RType; /* Real type used for struct parameters */ /* Get the function descriptor from the function entry */ - FuncDesc* D = Func->V.F.Func; + FuncDesc* D = GetFuncDesc (Func->Type); /* Allocate the function activation record for the function */ CurrentFunc = NewFunction (Func); diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 12caa7aa2..a21a09e8e 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -427,8 +427,8 @@ static void ParseOneDecl (const DeclSpec* Spec) ParseDecl (Spec, &Decl, DM_NEED_IDENT); /* Check if there are any non-extern storage classes set for function - ** declarations. The only valid storage class for function declarations - ** inside functions is 'extern'. + ** declarations. Function can only be declared inside functions with the + ** 'extern' storage class specifier or no storage class specifier at all. */ if ((Decl.StorageClass & SC_FUNC) == SC_FUNC) { @@ -439,12 +439,11 @@ static void ParseOneDecl (const DeclSpec* Spec) Error ("Illegal storage class on function"); } - /* The default storage class could be wrong. Just use 'extern' in all - ** cases. - */ + /* The default storage class could be wrong. Just clear them */ Decl.StorageClass &= ~SC_STORAGEMASK; - Decl.StorageClass |= SC_EXTERN; + /* This is always a declaration */ + Decl.StorageClass |= SC_DECL; } /* If we don't have a name, this was flagged as an error earlier. @@ -456,6 +455,7 @@ static void ParseOneDecl (const DeclSpec* Spec) /* If the symbol is not marked as external, it will be defined now */ if ((Decl.StorageClass & SC_FICTITIOUS) == 0 && + (Decl.StorageClass & SC_DECL) == 0 && (Decl.StorageClass & SC_EXTERN) == 0) { Decl.StorageClass |= SC_DEF; } @@ -500,8 +500,14 @@ static void ParseOneDecl (const DeclSpec* Spec) } } - /* Add the symbol to the symbol table */ - AddLocalSym (Decl.Ident, Decl.Type, Decl.StorageClass, 0); + if ((Decl.StorageClass & SC_EXTERN) == SC_EXTERN || + (Decl.StorageClass & SC_FUNC) == SC_FUNC) { + /* Add the global symbol to the local symbol table */ + AddGlobalSym (Decl.Ident, Decl.Type, Decl.StorageClass); + } else { + /* Add the local symbol to the local symbol table */ + AddLocalSym (Decl.Ident, Decl.Type, Decl.StorageClass, 0); + } } } diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 93c83906f..a0876a550 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -527,7 +527,7 @@ static void WrappedCallPragma (StrBuf* B) PushWrappedCall(Entry, (unsigned char) Val); Entry->Flags |= SC_REF; - Entry->V.F.Func->Flags |= FD_CALL_WRAPPER; + GetFuncCompositeDesc (Entry)->Flags |= FD_CALL_WRAPPER; } else { diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index cfc6379d3..6b05dd72b 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -191,7 +191,7 @@ struct SymEntry { /* Data for functions */ struct { - struct FuncDesc* Func; /* Function descriptor */ + SymEntry* Composite;/* Entry to hold composite function type */ struct Segments* Seg; /* Segments for this function */ struct LiteralPool* LitPool; /* Literal pool for this function */ } F; diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 53c30254d..10ec88d79 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -45,6 +45,7 @@ #include "xmalloc.h" /* cc65 */ +#include "anonname.h" #include "asmcode.h" #include "asmlabel.h" #include "codegen.h" @@ -558,9 +559,10 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags unsigned E_SCType = Entry->Flags & SC_TYPEMASK; unsigned SCType = Flags & SC_TYPEMASK; - /* Existing typedefs cannot be redeclared as anything different */ + /* Some symbols may be redeclared if certain requirements are met */ if (E_SCType == SC_TYPEDEF) { + /* Existing typedefs cannot be redeclared as anything different */ if (SCType == SC_TYPEDEF) { if (TypeCmp (E_Type, T) < TC_IDENTICAL) { Error ("Conflicting types for typedef '%s'", Entry->Name); @@ -571,9 +573,42 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags Entry = 0; } + } else if ((Entry->Flags & SC_FUNC) == 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 + ** an actual function definition follows. Be sure not to use the + ** new descriptor if it contains a function declaration with an + ** empty parameter list. + */ + if (IsTypeFunc (T)) { + + /* Check for duplicate function definitions */ + if (SymIsDef (Entry) && (Flags & SC_DEF) == SC_DEF) { + Error ("Body for function '%s' has already been defined", + Entry->Name); + Entry = 0; + } else { + /* New type must be compatible with the composite prototype */ + if (TypeCmp (GetFuncCompositeType (Entry), T) < TC_EQUAL) { + Error ("Conflicting function types for '%s'", Entry->Name); + Entry = 0; + } else { + /* Refine the existing composite prototype with this new + ** one. + */ + RefineFuncDesc (GetFuncCompositeType (Entry), T); + } + } + + } else { + Error ("Redefinition of function '%s' as different kind of symbol", Entry->Name); + Entry = 0; + } + } else { - /* Some symbols may be redeclared if certain requirements are met */ + /* Redeclarations of ESU types are checked elsewhere */ if (IsTypeArray (T) && IsTypeArray (E_Type)) { /* Get the array sizes */ @@ -597,37 +632,6 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags } } - } else if ((Entry->Flags & SC_FUNC) == 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 - ** an actual function definition follows. Be sure not to use the - ** new descriptor if it contains a function declaration with an - ** empty parameter list. - */ - if (IsTypeFunc (T)) { - - /* New type must be equivalent */ - if (TypeCmp (E_Type, T) < TC_EQUAL) { - Error ("Conflicting function types for '%s'", Entry->Name); - Entry = 0; - } else { - /* Get the function descriptor from the new type */ - FuncDesc* F = GetFuncDesc (T); - /* Use this new function descriptor if it doesn't contain - ** an empty parameter list. - */ - if ((F->Flags & FD_EMPTY) == 0) { - Entry->V.F.Func = F; - SetFuncDesc (E_Type, F); - } - } - - } else { - Error ("Redefinition of function '%s' as different kind of symbol", Entry->Name); - Entry = 0; - } - } else { /* New type must be equivalent */ @@ -1067,7 +1071,8 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs } else if ((Flags & SC_REGISTER) == SC_REGISTER) { Entry->V.R.RegOffs = Offs; Entry->V.R.SaveOffs = StackPtr; - } else if ((Flags & SC_EXTERN) == SC_EXTERN) { + } else if ((Flags & SC_EXTERN) == SC_EXTERN || + (Flags & SC_FUNC) == SC_FUNC) { Entry->V.L.Label = Offs; SymSetAsmName (Entry); } else if ((Flags & SC_STATIC) == SC_STATIC) { @@ -1080,7 +1085,6 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs /* Add the entry to the symbol table */ AddSymEntry (Tab, Entry); - } /* Return the entry */ @@ -1092,16 +1096,12 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) /* Add an external or global symbol to the symbol table and return the entry */ { - /* There is some special handling for functions, so check if it is one */ - int IsFunc = IsTypeFunc (T); - - /* Functions must be inserted in the global symbol table */ - SymTable* Tab = IsFunc ? SymTab0 : SymTab; + /* Use the global symbol table */ + SymTable* Tab = SymTab; /* Do we have an entry with this name already? */ - SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name)); + SymEntry* Entry = FindSymInTree (Tab, Name); if (Entry) { - /* We have a symbol with this name already */ if (HandleSymRedefinition (Entry, T, Flags)) { /* Use the fail-safe table for fictitious symbols */ @@ -1111,31 +1111,34 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) } else { /* If a static declaration follows a non-static declaration, then - ** warn about the conflict. (It will compile a public declaration.) + ** warn about the conflict. It will compile an extern declaration. */ if ((Flags & SC_EXTERN) == 0 && (Entry->Flags & SC_EXTERN) != 0) { Warning ("static declaration follows non-static declaration of '%s'.", Name); } - /* An extern declaration must not change the current linkage. */ - if (IsFunc || (Flags & (SC_EXTERN | SC_STORAGE)) == SC_EXTERN) { - Flags &= ~SC_EXTERN; - } - - /* If a public declaration follows a static declaration, then - ** warn about the conflict. (It will compile a public declaration.) + /* If an extern declaration follows a static declaration, then + ** warn about the conflict. It will compile an extern declaration. */ if ((Flags & SC_EXTERN) != 0 && (Entry->Flags & SC_EXTERN) == 0) { - Warning ("public declaration follows static declaration of '%s'.", Name); + Warning ("extern declaration follows static declaration of '%s'.", Name); + } + + /* Update existing function type if this is a definition */ + if (IsTypeFunc (Entry->Type) && + !SymIsDef (Entry) && + (Flags & SC_DEF) == SC_DEF) { + TypeFree (Entry->Type); + Entry->Type = TypeDup (T); } /* Add the new flags */ - Entry->Flags |= Flags; + Entry->Flags |= Flags & ~SC_EXTERN; } } - if (Entry == 0) { + if (Entry == 0 || Entry->Owner != Tab) { /* Create a new entry */ Entry = NewSymEntry (Name, Flags); @@ -1143,12 +1146,18 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) /* Set the symbol attributes */ Entry->Type = TypeDup (T); - /* If this is a function, set the function descriptor and clear + /* If this is a function, set the function composite typeand clear ** additional fields. */ - if (IsFunc) { - Entry->V.F.Func = GetFuncDesc (Entry->Type); - Entry->V.F.Seg = 0; + if (IsTypeFunc (T)) { + /* GitHub #1167 - Make a composite prototype */ + ident Ident; + AnonName (Ident, "prototype"); + Entry->V.F.Composite = NewSymEntry (Ident, SC_EXTERN | SC_DECL | SC_ALIAS | SC_FUNC); + Entry->V.F.Composite->Type = TypeDup (T); + AddSymEntry (SymTab0, Entry->V.F.Composite); + + Entry->V.F.Seg = 0; } /* Add the assembler name of the symbol */ From b19bb14348b2394bbd504c5c987c475bfb35de3a Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 12 Aug 2020 21:35:50 +0800 Subject: [PATCH 1570/2161] Fixed checking conflitcing declarations with external vs other linkage. --- src/cc65/symtab.c | 86 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 23 deletions(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 10ec88d79..443d0a21c 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -1045,6 +1045,22 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs if (SymIsDef (Entry) && (Flags & SC_DEF) == SC_DEF) { Error ("Multiple definition of '%s'", Entry->Name); Entry = 0; + } else if ((Flags & (SC_AUTO | SC_REGISTER)) != 0 && + (Entry->Flags & SC_EXTERN) != 0) { + /* Check for local storage class conflict */ + Error ("Declaration of '%s' with no linkage follows extern declaration", + Name); + Entry = 0; + } else { + /* If a static declaration follows a non-static declaration, + ** then it is an error. + */ + if ((Flags & SC_DEF) && + (Flags & SC_EXTERN) == 0 && + (Entry->Flags & SC_EXTERN) != 0) { + Error ("Static declaration of '%s' follows extern declaration", Name); + Entry = 0; + } } } @@ -1104,38 +1120,62 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) if (Entry) { /* We have a symbol with this name already */ if (HandleSymRedefinition (Entry, T, Flags)) { - /* Use the fail-safe table for fictitious symbols */ - Tab = FailSafeTab; Entry = 0; - - } else { - + } else if ((Entry->Flags & (SC_AUTO | SC_REGISTER)) != 0) { + /* Check for local storage class conflict */ + 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 - ** warn about the conflict. It will compile an extern declaration. + ** diagnose the conflict. It will warn and compile an extern + ** declaration if both declarations are global, otherwise give an + ** error. */ - if ((Flags & SC_EXTERN) == 0 && (Entry->Flags & SC_EXTERN) != 0) { - Warning ("static declaration follows non-static declaration of '%s'.", Name); + if (Tab == SymTab0 && + (Flags & SC_EXTERN) == 0 && + (Entry->Flags & SC_EXTERN) != 0) { + Warning ("Static declaration of '%s' follows non-static declaration", Name); + } 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->Owner == SymTab0) { + if ((Flags & SC_STORAGE) == 0) { + /* Linkage must be unchanged */ + Flags &= ~SC_EXTERN; + } else { + Error ("Non-static declaration of '%s' follows static declaration", Name); + } + } else { + Error ("Extern declaration of '%s' follows static declaration", Name); + Entry = 0; + } } - /* If an extern declaration follows a static declaration, then - ** warn about the conflict. It will compile an extern declaration. - */ - if ((Flags & SC_EXTERN) != 0 && (Entry->Flags & SC_EXTERN) == 0) { - Warning ("extern declaration follows static declaration of '%s'.", Name); - } + if (Entry) { + /* Update existing function type if this is a definition */ + if (IsTypeFunc (Entry->Type) && + !SymIsDef (Entry) && + (Flags & SC_DEF) == SC_DEF) { + TypeFree (Entry->Type); + Entry->Type = TypeDup (T); + } - /* Update existing function type if this is a definition */ - if (IsTypeFunc (Entry->Type) && - !SymIsDef (Entry) && - (Flags & SC_DEF) == SC_DEF) { - TypeFree (Entry->Type); - Entry->Type = TypeDup (T); + /* Add the new flags */ + Entry->Flags |= Flags; } - - /* Add the new flags */ - Entry->Flags |= Flags & ~SC_EXTERN; } + if (Entry == 0) { + /* Use the fail-safe table for fictitious symbols */ + Tab = FailSafeTab; + } } if (Entry == 0 || Entry->Owner != Tab) { From 1d28e8e3deff8d69c4e9b8ab09b5fbe0bf726a72 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 13 Aug 2020 00:00:32 +0800 Subject: [PATCH 1571/2161] Improved test case for Issue #191. --- test/val/static-1.c | 1 + 1 file changed, 1 insertion(+) diff --git a/test/val/static-1.c b/test/val/static-1.c index ae2ba6289..6918e0033 100644 --- a/test/val/static-1.c +++ b/test/val/static-1.c @@ -13,6 +13,7 @@ static int n = 0; extern int n; /* should not give an error */ +static int n; /* should not give an error */ int main(void) { From f0e4053a0d5a5a3749b4043283f912801d3914f8 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 14 Aug 2020 19:58:58 +0200 Subject: [PATCH 1572/2161] added test related to issue #1178 --- test/val/bug1178.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 test/val/bug1178.c diff --git a/test/val/bug1178.c b/test/val/bug1178.c new file mode 100644 index 000000000..043767e4c --- /dev/null +++ b/test/val/bug1178.c @@ -0,0 +1,81 @@ + +/* bug #1178 - copying structs/unions > 4 bytes is broken */ + +#include <stdio.h> +#include <stdlib.h> + +typedef struct +{ + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; + unsigned char e; +} +TestStruct1; + +TestStruct1 StructArray1[2]; +TestStruct1 test1; + +typedef struct +{ + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; +} +TestStruct2; + +TestStruct2 StructArray2[2]; +TestStruct2 test2; + +int res = EXIT_SUCCESS; + +void dotest1(void) +{ + test1.a = 42; + test1.b = 11; + test1.c = 23; + test1.d = 47; + test1.e = 13; + + StructArray1[0] = test1; + + printf ("test1: %d, %d, %d, %d, %d\n", + (int)StructArray1[0].a, (int)StructArray1[0].b, (int)StructArray1[0].c, + (int)StructArray1[0].d, (int)StructArray1[0].e); + if ((StructArray1[0].a != 42) || + (StructArray1[0].b != 11) || + (StructArray1[0].c != 23) || + (StructArray1[0].d != 47) || + (StructArray1[0].e != 13)) { + res = EXIT_FAILURE; + } +} + +void dotest2(void) +{ + test2.a = 42; + test2.b = 11; + test2.c = 23; + test2.d = 47; + + StructArray2[0] = test2; + + printf ("test2: %d, %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) || + (StructArray2[0].b != 11) || + (StructArray2[0].c != 23) || + (StructArray2[0].d != 47)) { + res = EXIT_FAILURE; + } +} + +int main(void) +{ + dotest1(); + dotest2(); + return res; +} From 8197e3c7cdeb373ae69ce80f368eb76ada6d6102 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 14 Aug 2020 21:07:39 +0200 Subject: [PATCH 1573/2161] make it actually compile again :) --- testcode/lib/strdup-test.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/testcode/lib/strdup-test.c b/testcode/lib/strdup-test.c index 5514471f9..e30841c3e 100644 --- a/testcode/lib/strdup-test.c +++ b/testcode/lib/strdup-test.c @@ -3,34 +3,25 @@ #include <string.h> #include <time.h> - -/* From _heap.h */ -extern unsigned _horg; /* Bottom of heap */ -extern unsigned _hptr; /* Current top */ -extern unsigned _hend; /* Upper limit */ -extern unsigned _hfirst; /* First free block in list */ -extern unsigned _hlast; /* Last free block in list */ - +#include <_heap.h> static unsigned char* V[256]; - - static void ShowInfo (void) /* Show heap info */ { /* Count free blocks */ unsigned Count = 0; - unsigned** P = (unsigned**) _hfirst; + unsigned** P = (unsigned**) _heapfirst; while (P) { ++Count; P = P[1]; } printf ("%04X %04X %04X %04X %04X %u\n", - _horg, _hptr, _hend, _hfirst, _hlast, Count); + _heaporg, _heapptr, _heapend, _heapfirst, _heaplast, Count); if (Count) { - P = (unsigned**) _hfirst; + P = (unsigned**) _heapfirst; while (P) { printf ("%04X %04X %04X %04X(%u)\n", (unsigned) P, P[2], P[1], P[0], P[0]); From c4698dfd07383e4ffa50d6c1fa5d158052b167a9 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Fri, 14 Aug 2020 14:54:10 +0200 Subject: [PATCH 1574/2161] Use C89 semantics for integer conversions Previously, the following rules were used for binary operators: * If one of the values is a long, the result is long. * If one of the values is unsigned, the result is also unsigned. * Otherwise the result is an int. C89 specifies the "usual arithmetic conversions" as: * The integral promotions are performed on both operands. * Then the following rules are applied: * If either operand has type unsigned long int, the other operand is converted to unsigned long int. * Otherwise, if one operand has type long int and the other has type unsigned int, if a long int can represent all values of an unsigned int, the operand of type unsigned int is converted to long int; if a long int cannot represent all the values of an unsigned int, both operands are converted to unsigned long int. * Otherwise, if either operand has type long int, the other operand is converted to long int. * Otherwise, if either operand has type unsigned int, the other operand is converted to unsigned int. * Otherwise, both operands have type int. https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 As one example, these rules give a different result for an operator with one long operand and one unsigned int operand. Previously, the result type was unsigned long. With C89 semantics, it is just long, since long can represent all unsigned ints. Integral promotions convert types shorter than int to int (or unsigned int). Both char and unsigned char are promoted to int since int can represent all unsigned chars. https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.1 Rename promoteint to ArithmeticConvert, since this is more accurate. Fixes #170 --- src/cc65/codegen.c | 111 ++++++++++++++++++++++++++++-------- src/cc65/datatype.c | 18 +++++- src/cc65/datatype.h | 10 ++++ src/cc65/expr.c | 78 ++++++++++++++++++------- test/{todo => val}/bug170.c | 0 5 files changed, 170 insertions(+), 47 deletions(-) rename test/{todo => val}/bug170.c (100%) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 8a879745d..2c6624a5c 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -1327,26 +1327,52 @@ void g_reglong (unsigned Flags) +static unsigned g_intpromotion (unsigned flags) +/* Return new flags for integral promotions for types smaller than int. */ +{ + /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.1 + ** A char, a short int, or an int bit-field, or their signed or unsigned varieties, or an + ** object that has enumeration type, may be used in an expression wherever an int or + ** unsigned int may be used. If an int can represent all values of the original type, the value + ** is converted to an int; otherwise it is converted to an unsigned int. + ** These are called the integral promotions. + */ + + if ((flags & CF_TYPEMASK) == CF_CHAR) { + /* int can represent all unsigned chars, so unsigned char is promoted to int. */ + flags &= ~CF_TYPEMASK; + flags &= ~CF_UNSIGNED; + flags |= CF_INT; + return flags; + } else if ((flags & CF_TYPEMASK) == CF_SHORT) { + /* int cannot represent all unsigned shorts, so unsigned short is promoted to + ** unsigned int. + */ + flags &= ~CF_TYPEMASK; + flags |= CF_INT; + return flags; + } else { + /* Otherwise, the type is not smaller than int, so leave it alone. */ + return flags; + } +} + + + unsigned g_typeadjust (unsigned lhs, unsigned rhs) /* Adjust the integer operands before doing a binary operation. lhs is a flags ** value, that corresponds to the value on TOS, rhs corresponds to the value ** in (e)ax. The return value is the the flags value for the resulting type. */ { - unsigned ltype, rtype; - unsigned result; - /* Get the type spec from the flags */ - ltype = lhs & CF_TYPEMASK; - rtype = rhs & CF_TYPEMASK; + unsigned ltype = lhs & CF_TYPEMASK; + unsigned rtype = rhs & CF_TYPEMASK; /* Check if a conversion is needed */ if (ltype == CF_LONG && rtype != CF_LONG && (rhs & CF_CONST) == 0) { /* We must promote the primary register to long */ g_reglong (rhs); - /* Get the new rhs type */ - rhs = (rhs & ~CF_TYPEMASK) | CF_LONG; - rtype = CF_LONG; } else if (ltype != CF_LONG && (lhs & CF_CONST) == 0 && rtype == CF_LONG) { /* We must promote the lhs to long */ if (lhs & CF_PRIMARY) { @@ -1354,25 +1380,64 @@ unsigned g_typeadjust (unsigned lhs, unsigned rhs) } else { g_toslong (lhs); } - /* Get the new rhs type */ - lhs = (lhs & ~CF_TYPEMASK) | CF_LONG; - ltype = CF_LONG; } - /* Determine the result type for the operation: - ** - The result is const if both operands are const. - ** - The result is unsigned if one of the operands is unsigned. - ** - The result is long if one of the operands is long. - ** - Otherwise the result is int sized. + /* Result is const if both operands are const. */ + unsigned const_flag = (lhs & CF_CONST) & (rhs & CF_CONST); + + /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 + ** Many binary operators that expect operands of arithmetic type cause conversions and yield + ** result types in a similar way. The purpose is to yield a common type, which is also the type + ** of the result. This pattern is called the usual arithmetic conversions. */ - result = (lhs & CF_CONST) & (rhs & CF_CONST); - result |= (lhs & CF_UNSIGNED) | (rhs & CF_UNSIGNED); - if (rtype == CF_LONG || ltype == CF_LONG) { - result |= CF_LONG; - } else { - result |= CF_INT; + + /* Note that this logic is largely duplicated by ArithmeticConvert. */ + + /* Apply integral promotions for types char/short. */ + lhs = g_intpromotion (lhs); + rhs = g_intpromotion (rhs); + ltype = lhs & CF_TYPEMASK; + rtype = rhs & CF_TYPEMASK; + + /* If either operand has type unsigned long int, the other operand is converted to + ** unsigned long int. + */ + if ((ltype == CF_LONG && (lhs & CF_UNSIGNED)) || + (rtype == CF_LONG && (rhs & CF_UNSIGNED))) { + return const_flag | CF_UNSIGNED | CF_LONG; } - return result; + + /* Otherwise, if one operand has type long int and the other has type unsigned int, + ** if a long int can represent all values of an unsigned int, the operand of type unsigned int + ** is converted to long int ; if a long int cannot represent all the values of an unsigned int, + ** 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))) { + /* long can represent all unsigneds, so we are in the first sub-case. */ + return const_flag | CF_LONG; + } + + /* Otherwise, if either operand has type long int, the other operand is converted to long int. + */ + if (ltype == CF_LONG || rtype == CF_LONG) { + return const_flag | CF_LONG; + } + + /* Otherwise, if either operand has type unsigned int, the other operand is converted to + ** unsigned int. + */ + if ((ltype == CF_INT && (lhs & CF_UNSIGNED)) || + (rtype == CF_INT && (rhs & CF_UNSIGNED))) { + return const_flag | CF_UNSIGNED | CF_INT; + } + + /* Otherwise, both operands have type int. */ + CHECK (ltype == CF_INT); + CHECK (!(lhs & CF_UNSIGNED)); + CHECK (rtype == CF_INT); + CHECK (!(rhs & CF_UNSIGNED)); + return const_flag | CF_INT; } diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 94aea9cc1..58b673fab 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -1214,12 +1214,26 @@ Type* IntPromotion (Type* T) /* We must have an int to apply int promotions */ PRECONDITION (IsClassInt (T)); - /* An integer can represent all values from either signed or unsigned char, - ** so convert chars to int and leave all other types alone. + /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.1 + ** A char, a short int, or an int bit-field, or their signed or unsigned varieties, or an + ** object that has enumeration type, may be used in an expression wherever an int or + ** unsigned int may be used. If an int can represent all values of the original type, the value + ** is converted to an int; otherwise it is converted to an unsigned int. + ** These are called the integral promotions. */ + if (IsTypeChar (T)) { + /* An integer can represent all values from either signed or unsigned char, so convert + ** chars to int. + */ return type_int; + } else if (IsTypeShort (T)) { + /* An integer cannot represent all values from unsigned short, so convert unsigned short + ** to unsigned int. + */ + return IsSignUnsigned (T) ? type_uint : type_int; } else { + /* Otherwise, the type is not smaller than int, so leave it alone. */ return T; } } diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 1ff8333c6..fbd52e761 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -373,6 +373,16 @@ INLINE int IsTypeChar (const Type* T) # define IsTypeChar(T) (GetRawType (GetUnderlyingType (T)) == T_TYPE_CHAR) #endif +#if defined(HAVE_INLINE) +INLINE int IsTypeShort (const Type* T) +/* Return true if this is a short type (signed or unsigned) */ +{ + return (GetRawType (GetUnderlyingType (T)) == T_TYPE_SHORT); +} +#else +# define IsTypeShort(T) (GetRawType (GetUnderlyingType (T)) == T_TYPE_SHORT) +#endif + #if defined(HAVE_INLINE) INLINE int IsTypeInt (const Type* T) /* Return true if this is an int type (signed or unsigned) */ diff --git a/src/cc65/expr.c b/src/cc65/expr.c index f75015305..efed934f8 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -140,27 +140,61 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* promoteint (Type* lhst, Type* rhst) -/* In an expression with two ints, return the type of the result */ +static Type* ArithmeticConvert (Type* lhst, Type* rhst) +/* Perform the usual arithmetic conversions for binary operators. */ { - /* Rules for integer types: - ** - If one of the values is a long, the result is long. - ** - If one of the values is unsigned, the result is also unsigned. - ** - Otherwise the result is an int. + /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 + ** Many binary operators that expect operands of arithmetic type cause conversions and yield + ** result types in a similar way. The purpose is to yield a common type, which is also the type + ** of the result. This pattern is called the usual arithmetic conversions. + */ + + /* There are additional rules for floating point types that we don't bother with, since + ** floating point types are not (yet) supported. + ** The integral promotions are performed on both operands. + */ + lhst = IntPromotion (lhst); + rhst = IntPromotion (rhst); + + /* If either operand has type unsigned long int, the other operand is converted to + ** unsigned long int. + */ + if ((IsTypeLong (lhst) && IsSignUnsigned (lhst)) || + (IsTypeLong (rhst) && IsSignUnsigned (rhst))) { + return type_ulong; + } + + /* Otherwise, if one operand has type long int and the other has type unsigned int, + ** if a long int can represent all values of an unsigned int, the operand of type unsigned int + ** is converted to long int ; if a long int cannot represent all the values of an unsigned int, + ** both operands are converted to unsigned long int. + */ + if ((IsTypeLong (lhst) && IsTypeInt (rhst) && IsSignUnsigned (rhst)) || + (IsTypeLong (rhst) && IsTypeInt (lhst) && IsSignUnsigned (lhst))) { + /* long can represent all unsigneds, so we are in the first sub-case. */ + return type_long; + } + + /* Otherwise, if either operand has type long int, the other operand is converted to long int. */ if (IsTypeLong (lhst) || IsTypeLong (rhst)) { - if (IsSignUnsigned (lhst) || IsSignUnsigned (rhst)) { - return type_ulong; - } else { - return type_long; - } - } else { - if (IsSignUnsigned (lhst) || IsSignUnsigned (rhst)) { - return type_uint; - } else { - return type_int; - } + return type_long; } + + /* Otherwise, if either operand has type unsigned int, the other operand is converted to + ** unsigned int. + */ + if ((IsTypeInt (lhst) && IsSignUnsigned (lhst)) || + (IsTypeInt (rhst) && IsSignUnsigned (rhst))) { + return type_uint; + } + + /* Otherwise, both operands have type int. */ + CHECK (IsTypeInt (lhst)); + CHECK (IsSignSigned (lhst)); + CHECK (IsTypeInt (rhst)); + CHECK (IsSignSigned (rhst)); + return type_int; } @@ -198,7 +232,7 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) flags = g_typeadjust (ltype, rtype); /* Set the type of the result */ - lhs->Type = promoteint (lhst, rhst); + lhs->Type = ArithmeticConvert (lhst, rhst); /* Return the code generator flags */ return flags; @@ -2066,7 +2100,7 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */ RemoveCode (&Mark1); /* Get the type of the result */ - Expr->Type = promoteint (Expr->Type, Expr2.Type); + Expr->Type = ArithmeticConvert (Expr->Type, Expr2.Type); /* Handle the op differently for signed and unsigned types */ if (IsSignSigned (Expr->Type)) { @@ -2163,7 +2197,7 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */ /* Determine the type of the operation result. */ type |= g_typeadjust (ltype, rtype); - Expr->Type = promoteint (Expr->Type, Expr2.Type); + Expr->Type = ArithmeticConvert (Expr->Type, Expr2.Type); /* Generate code */ Gen->Func (type, Expr->IVal); @@ -2196,7 +2230,7 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */ /* Determine the type of the operation result. */ type |= g_typeadjust (ltype, rtype); - Expr->Type = promoteint (Expr->Type, Expr2.Type); + Expr->Type = ArithmeticConvert (Expr->Type, Expr2.Type); /* Generate code */ Gen->Func (type, Expr2.IVal); @@ -3340,7 +3374,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = promoteint (Expr2.Type, Expr3.Type); + ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); diff --git a/test/todo/bug170.c b/test/val/bug170.c similarity index 100% rename from test/todo/bug170.c rename to test/val/bug170.c From 1cf9404c19d504fa7230f6fbb14bfa8ee8204282 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sat, 15 Aug 2020 21:05:51 +0200 Subject: [PATCH 1575/2161] Support C2X _Static_assert(expr) syntax This makes the message in _Static_assert(expr, message) optional. Fixes #1188. --- src/cc65/staticassert.c | 49 ++++++++++++++++++++++++----------------- test/val/staticassert.c | 2 ++ 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/cc65/staticassert.c b/src/cc65/staticassert.c index 95a2d4a6e..68f0a41bc 100644 --- a/src/cc65/staticassert.c +++ b/src/cc65/staticassert.c @@ -49,6 +49,7 @@ void ParseStaticAssert () { /* ** static_assert-declaration ::= + ** _Static_assert ( constant-expression ) ; ** _Static_assert ( constant-expression , string-literal ) ; */ ExprDesc Expr; @@ -67,27 +68,35 @@ void ParseStaticAssert () ConstAbsIntExpr (hie1, &Expr); failed = !Expr.IVal; - /* We expect a comma */ - if (!ConsumeComma ()) { - return; - } - - /* String literal */ - if (CurTok.Tok != TOK_SCONST) { - Error ("String literal expected for static_assert message"); - return; - } - - /* 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 there is a comma, we also have an error message. The message is optional because we + ** support the C2X syntax with only an expression. */ - if (!Consume (TOK_SCONST, "String literal expected")) { - return; + if (CurTok.Tok == TOK_COMMA) { + /* Skip the comma. */ + NextToken (); + + /* String literal */ + if (CurTok.Tok != TOK_SCONST) { + Error ("String literal expected for static_assert message"); + return; + } + + /* 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; + } + } else { + /* No message. */ + if (failed) { + Error ("static_assert failed"); + } } /* Closing paren and semi-colon needed */ diff --git a/test/val/staticassert.c b/test/val/staticassert.c index a02ba27e8..5d44fed6b 100644 --- a/test/val/staticassert.c +++ b/test/val/staticassert.c @@ -27,6 +27,7 @@ #include <assert.h> _Static_assert (1, "1 should be true."); +_Static_assert (1); /* Support C2x syntax with no message. */ _Static_assert (!0, "!0 should be true."); _Static_assert (1 == 1, "1 == 1 should be true."); _Static_assert (1 == 1L, "1 == 1L should be true."); @@ -46,6 +47,7 @@ _Static_assert (k == 1, "k should be 1."); /* Just test the macro version once. */ static_assert (1, "1 should be true."); +static_assert (1); /* _Static_assert can appear anywhere a declaration can. */ void f (void) From 7e61b11f23abe1a2b0f5e826c0832a291895df4a Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sat, 15 Aug 2020 21:22:31 +0200 Subject: [PATCH 1576/2161] Add _Static_assert docs to cc65 extensions Fixes #1149. --- doc/cc65.sgml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index dba0a0288..a81358510 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -792,6 +792,21 @@ This cc65 version has some extensions to the ISO C standard. size zero, even if it is initialized. <p> +<item> cc65 supports <tt/_Static_assert/ from C11 and C2X. This is similar + to <tt/#error/ but happens at a later stage of translation, so types + can be used. + + <tscreen><verb> + /* C11 version with message. */ + _Static_assert (sizeof (int) == 2, "Expected 2-bytes ints."); + + /* C2X version without message. */ + _Static_assert (sizeof (int) == 2); + </verb></tscreen> + + <tt/_Static_assert/ is also available as the macro <tt/static_assert/ in + <tt/assert.h/. + <item> Computed gotos, a GCC extension, has limited support. With it you can use fast jump tables from C. You can take the address of a label with a double ampersand, putting them in a static const array of type void *. From 11cd3e5cbd29ddfd796452a4d30a116adcedce47 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 12 Aug 2020 21:50:34 +0800 Subject: [PATCH 1577/2161] Utility for checking general datatype categories, incomplete ESU types and arrays of unknown sizes. --- src/cc65/datatype.c | 100 +++++++++++++++++++++++++++++++++++++++++++- src/cc65/datatype.h | 35 +++++++++++++++- 2 files changed, 132 insertions(+), 3 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 58b673fab..9b30eba70 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -1037,18 +1037,114 @@ Type* ArrayToPtr (Type* T) +int IsClassObject (const Type* T) +/* Return true if this is a fully described object type */ +{ + return !IsTypeFunc (T) && !IsClassIncomplete (T); +} + + + +int IsClassIncomplete (const Type* T) +/* Return true if this is an object type lacking size info */ +{ + if (IsTypeArray (T)) { + return GetElementCount (T) == UNSPECIFIED; + } + return IsTypeVoid (T) || IsIncompleteESUType (T); +} + + + int IsClassArithmetic (const Type* T) -/* Return true if this is an arithmetic type */ +/* Return true if this is an integer or real floating type */ { return IsClassInt (T) || IsClassFloat (T); } +int IsClassBasic (const Type* T) +/* Return true if this is a char, integer or floating type */ +{ + return IsRawTypeChar (T) || IsClassInt (T) || IsClassFloat (T); +} + + + +int IsClassScalar (const Type* T) +/* Return true if this is an arithmetic or pointer type */ +{ + return IsClassArithmetic (T) || IsTypePtr (T); +} + + + +int IsClassDerived (const Type* T) +/* Return true if this is an array, struct, union, function or pointer type */ +{ + return IsTypeArray (T) || IsClassStruct (T) || IsClassFunc (T) || IsTypePtr (T); +} + + + +int IsClassAggregate (const Type* T) +/* Return true if this is an array or struct type */ +{ + return IsTypeArray (T) || IsTypeStruct (T); +} + + + +int IsRelationType (const Type* T) +/* Return true if this is an arithmetic, array or pointer type */ +{ + return IsClassArithmetic (T) || IsClassPtr (T); +} + + + int IsCastType (const Type* T) /* Return true if this type can be used for casting */ { - return IsClassArithmetic (T) || IsClassPtr (T) || IsTypeVoid (T); + return IsClassScalar (T) || IsTypeVoid (T); +} + + + +int IsESUType (const Type* T) +/* Return true if this is an enum/struct/union type */ +{ + return IsClassStruct (T) || IsTypeEnum (T); +} + + + +int IsIncompleteESUType (const Type* T) +/* Return true if this is an incomplete ESU type */ +{ + SymEntry* Sym = GetSymType (T); + + return Sym != 0 && !SymIsDef (Sym); +} + + + +int IsEmptiableObjectType (const Type* T) +/* Return true if this is a struct/union/void type that can have zero size */ +{ + return IsClassStruct (T) || IsTypeVoid (T); +} + + + +int HasUnknownSize (const Type* T) +/* Return true if this is an incomplete ESU type or an array of unknown size */ +{ + if (IsTypeArray (T)) { + return GetElementCount (T) == UNSPECIFIED; + } + return IsIncompleteESUType (T); } diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index fbd52e761..7aa1d77be 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -593,12 +593,45 @@ INLINE int IsClassFunc (const Type* T) # define IsClassFunc(T) (GetClass (T) == T_CLASS_FUNC) #endif +int IsClassObject (const Type* T); +/* Return true if this is a fully described object type */ + +int IsClassIncomplete (const Type* T); +/* Return true if this is an object type lacking size info */ + int IsClassArithmetic (const Type* T); -/* Return true if this is an arithmetic type */ +/* Return true if this is an integer or real floating type */ + +int IsClassBasic (const Type* T); +/* Return true if this is a char, integer or floating type */ + +int IsClassScalar (const Type* T); +/* Return true if this is an arithmetic or pointer type */ + +int IsClassDerived (const Type* T); +/* Return true if this is an array, struct, union, function or pointer type */ + +int IsClassAggregate (const Type* T); +/* Return true if this is an array or struct type */ + +int IsRelationType (const Type* T); +/* Return true if this is an arithmetic, array or pointer type */ int IsCastType (const Type* T); /* Return true if this type can be used for casting */ +int IsESUType (const Type* T); +/* Return true if this is an enum/struct/union type */ + +int IsIncompleteESUType (const Type* T); +/* Return true if this is an incomplete ESU type */ + +int IsEmptiableObjectType (const Type* T); +/* Return true if this is a struct/union/void type that can have zero size */ + +int HasUnknownSize (const Type* T); +/* Return true if this is an incomplete ESU type or an array of unknown size */ + #if defined(HAVE_INLINE) INLINE TypeCode GetRawSignedness (const Type* T) /* Get the raw signedness of a type */ From 15f28c3a8cbf95a6bb9abb908b17de90576c7a49 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 13 Aug 2020 08:24:40 +0800 Subject: [PATCH 1578/2161] Fixed getting the basic raw type names. --- src/cc65/datatype.c | 4 ++-- src/cc65/datatype.h | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 9b30eba70..20c4abc56 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -235,7 +235,7 @@ const char* GetBasicTypeName (const Type* T) default: break; } if (IsClassInt (T)) { - if (IsSignSigned (T)) { + if (IsRawSignSigned (T)) { switch (GetRawType (T)) { case T_TYPE_CHAR: return "signed char"; case T_TYPE_SHORT: return "short"; @@ -245,7 +245,7 @@ const char* GetBasicTypeName (const Type* T) default: return "signed integer"; } - } else if (IsSignUnsigned (T)) { + } else if (IsRawSignUnsigned (T)) { switch (GetRawType (T)) { case T_TYPE_CHAR: return "unsigned char"; case T_TYPE_SHORT: return "unsigned short"; diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 7aa1d77be..660681909 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -652,6 +652,16 @@ INLINE TypeCode GetSignedness (const Type* T) # define GetSignedness(T) (GetUnderlyingTypeCode (T) & T_MASK_SIGN) #endif +#if defined(HAVE_INLINE) +INLINE int IsRawSignUnsigned (const Type* T) +/* Return true if this is an unsigned raw type */ +{ + return (GetRawSignedness (T) == T_SIGN_UNSIGNED); +} +#else +# define IsRawSignUnsigned(T) (GetRawSignedness (T) == T_SIGN_UNSIGNED) +#endif + #if defined(HAVE_INLINE) INLINE int IsSignUnsigned (const Type* T) /* Return true if this is an unsigned type */ @@ -662,6 +672,16 @@ INLINE int IsSignUnsigned (const Type* T) # define IsSignUnsigned(T) (GetSignedness (T) == T_SIGN_UNSIGNED) #endif +#if defined(HAVE_INLINE) +INLINE int IsRawSignSigned (const Type* T) +/* Return true if this is a signed raw type */ +{ + return (GetRawSignedness (T) == T_SIGN_SIGNED); +} +#else +# define IsRawSignSigned(T) (GetRawSignedness (T) == T_SIGN_SIGNED) +#endif + #if defined(HAVE_INLINE) INLINE int IsSignSigned (const Type* T) /* Return true if this is a signed type */ @@ -673,7 +693,7 @@ INLINE int IsSignSigned (const Type* T) #endif #if defined(HAVE_INLINE) -INLINE TypeCode GetRawSizeModifier(const Type* T) +INLINE TypeCode GetRawSizeModifier (const Type* T) /* Get the size modifier of a raw type */ { return (T->C & T_MASK_SIZE); From 6db93d58cffc8bfd2a320111d96f7ca5a1751519 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Mon, 17 Aug 2020 09:22:15 +0200 Subject: [PATCH 1579/2161] Add test of union of bit-field from mailing list https://sourceforge.net/p/cc65/mailman/message/36152700/ This currently works, but add a test to prevent future regressions. --- test/val/bitfield-union.c | 71 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 test/val/bitfield-union.c diff --git a/test/val/bitfield-union.c b/test/val/bitfield-union.c new file mode 100644 index 000000000..1fd201456 --- /dev/null +++ b/test/val/bitfield-union.c @@ -0,0 +1,71 @@ +/* + Copyright 2020 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. +*/ + +/* + Tests of union of bit-fields; see https://sourceforge.net/p/cc65/mailman/message/36152700/ +*/ + +#include <stdio.h> + +typedef union { + unsigned int bf; + + struct { + unsigned int a : 1; + unsigned int b : 1; + unsigned int c : 1; + }; +} bitfield_t; + +static unsigned char failures = 0; + +int main (void) +{ + bitfield_t bitfield = {0}; + + printf ("Bitfield: %u\n", bitfield.bf); + if (bitfield.bf != 0) failures++; + + bitfield.a = bitfield.a ^ 1; + printf ("a=1: %u\n", bitfield.bf); + if (bitfield.bf != 1) failures++; + + bitfield.a = bitfield.a ^ 1; + printf ("a=0: %u\n\n", bitfield.bf); + if (bitfield.bf != 0) failures++; + + bitfield.b = bitfield.b ^ 1; + printf ("b=1: %u\n", bitfield.bf); + if (bitfield.bf != 2) failures++; + + bitfield.b = bitfield.b ^ 1; + printf ("b=0: %u\n\n", bitfield.bf); + if (bitfield.bf != 0) failures++; + + bitfield.c = bitfield.c ^ 1; + printf ("c=1: %u\n", bitfield.bf); + if (bitfield.bf != 4) failures++; + + bitfield.c = bitfield.c ^ 1; + printf ("c=0: %u\n\n", bitfield.bf); + if (bitfield.bf != 0) failures++; + + return failures; +} From ebae994dc9e384aa680ab297eec33b9161e7ca92 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 15 Aug 2020 22:59:26 +0800 Subject: [PATCH 1580/2161] Fixed CHECK failure when calling functions defined with repeated parameter names. Clarified the terms "parameter" vs "argument" in FunctionParamList(). --- src/cc65/expr.c | 55 +++++++++++++++++++++++------------------------ src/cc65/symtab.c | 10 +++++++-- 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index efed934f8..db50e14b0 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -330,32 +330,30 @@ static void WarnConstCompareResult (void) static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) -/* Parse a function parameter list, and pass the parameters to the called +/* Parse a function parameter list, and pass the arguments to the called ** function. Depending on several criteria, this may be done by just pushing -** each parameter separately, or creating the parameter frame once, and then -** storing into this frame. -** The function returns the size of the parameters pushed. +** into each parameter separately, or creating the parameter frame once, and +** then storing into this frame. +** The function returns the size of the arguments pushed in bytes. */ { - ExprDesc Expr; - /* Initialize variables */ SymEntry* Param = 0; /* Keep gcc silent */ - unsigned ParamSize = 0; /* Size of parameters pushed */ - unsigned ParamCount = 0; /* Number of parameters pushed */ + unsigned PushedSize = 0; /* Size of arguments pushed */ + unsigned PushedCount = 0; /* Number of arguments pushed */ unsigned FrameSize = 0; /* Size of parameter frame */ - unsigned FrameParams = 0; /* Number of params in frame */ + unsigned FrameParams = 0; /* Number of parameters in frame */ int FrameOffs = 0; /* Offset into parameter frame */ int Ellipsis = 0; /* Function is variadic */ /* As an optimization, we may allocate the complete parameter frame at - ** once instead of pushing each parameter as it comes. We may do that, + ** once instead of pushing into each parameter as it comes. We may do that, ** if... ** ** - optimizations that increase code size are enabled (allocating the ** stack frame at once gives usually larger code). - ** - we have more than one parameter to push (don't count the last param - ** for __fastcall__ functions). + ** - we have more than one parameter to push into (don't count the last + ** parameter for __fastcall__ functions). ** ** The FrameSize variable will contain a value > 0 if storing into a frame ** (instead of pushing) is enabled. @@ -367,7 +365,7 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) FrameParams = Func->ParamCount; FrameSize = Func->ParamSize; if (FrameParams > 0 && IsFastcall) { - /* Last parameter is not pushed */ + /* Last parameter is not pushed into */ FrameSize -= CheckedSizeOf (Func->LastParam->Type); --FrameParams; } @@ -384,25 +382,26 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) } } - /* Parse the actual parameter list */ + /* Parse the actual argument list */ while (CurTok.Tok != TOK_RPAREN) { unsigned Flags; + ExprDesc Expr; /* Count arguments */ - ++ParamCount; + ++PushedCount; /* Fetch the pointer to the next argument, check for too many args */ - if (ParamCount <= Func->ParamCount) { + if (PushedCount <= Func->ParamCount) { /* Beware: If there are parameters with identical names, they ** cannot go into the same symbol table, which means that, in this ** case of errorneous input, the number of nodes in the symbol - ** table and ParamCount are NOT equal. We have to handle this case + ** table and PushedCount are NOT equal. We have to handle this case ** below to avoid segmentation violations. Since we know that this ** problem can only occur if there is more than one parameter, ** we will just use the last one. */ - if (ParamCount == 1) { + if (PushedCount == 1) { /* First argument */ Param = Func->SymTab->SymHead; } else if (Param->NextSym != 0) { @@ -422,11 +421,11 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) Ellipsis = 1; } - /* Evaluate the parameter expression */ + /* Evaluate the argument expression */ hie1 (&Expr); - /* If we don't have an argument spec., accept anything; otherwise, - ** convert the actual argument to the type needed. + /* If we don't have a prototype, accept anything; otherwise, convert + ** the actual argument to the parameter type needed. */ Flags = CF_NONE; if (!Ellipsis) { @@ -483,7 +482,7 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) } /* Calculate total parameter size */ - ParamSize += ArgSize; + PushedSize += ArgSize; } /* Check for end of argument list */ @@ -499,20 +498,20 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) } } - /* Check if we had enough parameters */ - if (ParamCount < Func->ParamCount) { + /* Check if we had enough arguments */ + if (PushedCount < Func->ParamCount) { Error ("Too few arguments in function call"); } - /* The function returns the size of all parameters pushed onto the stack. - ** However, if there are parameters missing (which is an error, and was + /* The function returns the size of all arguments pushed onto the stack. + ** However, if there are parameters missed (which is an error, and was ** flagged by the compiler), AND a stack frame was preallocated above, ** we would loose track of the stackpointer, and generate an internal error ** later. So we correct the value by the parameters that should have been - ** pushed, to avoid an internal compiler error. Since an error was + ** pushed into, to avoid an internal compiler error. Since an error was ** generated before, no code will be output anyway. */ - return ParamSize + FrameSize; + return PushedSize + FrameSize; } diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 443d0a21c..02e96cf21 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -1032,6 +1032,7 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs /* Add a local symbol and return the symbol entry */ { SymTable* Tab = SymTab; + ident Ident; /* Do we have an entry with this name already? */ SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name)); @@ -1065,8 +1066,13 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs } if (Entry == 0) { - /* Use the fail-safe table for fictitious symbols */ - Tab = FailSafeTab; + if ((Flags & SC_PARAM) != 0) { + /* Use anonymous names */ + Name = AnonName (Ident, "param"); + } else { + /* Use the fail-safe table for fictitious symbols */ + Tab = FailSafeTab; + } } } From 0afa1a9a95815430b444e0221f5836d8f97020db Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 15 Aug 2020 01:50:04 +0800 Subject: [PATCH 1581/2161] Fixed function signatures in asm output. Improved full type name production. --- src/cc65/datatype.c | 213 +++++++++++++++----------------------------- src/cc65/datatype.h | 10 +-- 2 files changed, 76 insertions(+), 147 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 20c4abc56..48773cba5 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -83,7 +83,7 @@ static struct StrBuf* GetFullTypeNameWestEast (struct StrBuf* West, struct StrBu ** eastern part. */ { - struct StrBuf Buf = STATIC_STRBUF_INITIALIZER; + struct StrBuf Buf = AUTO_STRBUF_INITIALIZER; if (IsTypeArray (T)) { @@ -117,28 +117,27 @@ static struct StrBuf* GetFullTypeNameWestEast (struct StrBuf* West, struct StrBu } else if (IsTypeFunc (T)) { - FuncDesc* F = GetFuncDesc (T); - struct StrBuf ParamList = STATIC_STRBUF_INITIALIZER; + FuncDesc* D = GetFuncDesc (T); + struct StrBuf ParamList = AUTO_STRBUF_INITIALIZER; /* First argument */ - SymEntry* Param = F->SymTab->SymHead; - for (unsigned I = 1; I < F->ParamCount; ++I) { - CHECK (Param->NextSym != 0 && (Param->Flags & SC_PARAM) != 0); + SymEntry* Param = D->SymTab->SymHead; + for (unsigned 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_AppendStr (&ParamList, ", "); SB_Clear (&Buf); /* Next argument */ Param = Param->NextSym; } - if ((F->Flags & FD_VARIADIC) == 0) { - if (F->ParamCount > 0) { - SB_AppendStr (&ParamList, SB_GetConstBuf (GetFullTypeNameBuf (&Buf, Param->Type))); - } else if ((F->Flags & FD_EMPTY) == 0) { + if ((D->Flags & FD_VARIADIC) == 0) { + if (D->ParamCount == 0 && (D->Flags & FD_EMPTY) == 0) { SB_AppendStr (&ParamList, "void"); } } else { - if (F->ParamCount > 0) { - SB_AppendStr (&ParamList, SB_GetConstBuf (GetFullTypeNameBuf (&Buf, Param->Type))); + if (D->ParamCount > 0) { SB_AppendStr (&ParamList, ", ..."); } else { SB_AppendStr (&ParamList, "..."); @@ -286,7 +285,7 @@ const char* GetFullTypeName (const Type* T) struct StrBuf* GetFullTypeNameBuf (struct StrBuf* S, const Type* T) /* Return the full name string of the given type */ { - struct StrBuf East = STATIC_STRBUF_INITIALIZER; + struct StrBuf East = AUTO_STRBUF_INITIALIZER; GetFullTypeNameWestEast (S, &East, T); /* Join West and East */ @@ -586,155 +585,85 @@ Type* PointerTo (const Type* T) -static TypeCode PrintTypeComp (FILE* F, TypeCode C, TypeCode Mask, const char* Name) -/* Check for a specific component of the type. If it is there, print the -** name and remove it. Return the type with the component removed. -*/ -{ - if ((C & Mask) == Mask) { - fprintf (F, "%s ", Name); - C &= ~Mask; - } - return C; -} - - - void PrintType (FILE* F, const Type* T) -/* Output translation of type array. */ +/* Print fulle name of the type */ { - /* Walk over the type string */ - while (T->C != T_END) { - - /* Get the type code */ - TypeCode C = T->C; - - /* Print any qualifiers */ - C = PrintTypeComp (F, C, T_QUAL_CONST, "const"); - C = PrintTypeComp (F, C, T_QUAL_VOLATILE, "volatile"); - C = PrintTypeComp (F, C, T_QUAL_RESTRICT, "restrict"); - C = PrintTypeComp (F, C, T_QUAL_NEAR, "__near__"); - C = PrintTypeComp (F, C, T_QUAL_FAR, "__far__"); - C = PrintTypeComp (F, C, T_QUAL_FASTCALL, "__fastcall__"); - C = PrintTypeComp (F, C, T_QUAL_CDECL, "__cdecl__"); - - /* Signedness. Omit the signedness specifier for long and int */ - if ((C & T_MASK_TYPE) != T_TYPE_INT && (C & T_MASK_TYPE) != T_TYPE_LONG) { - C = PrintTypeComp (F, C, T_SIGN_SIGNED, "signed"); - } - C = PrintTypeComp (F, C, T_SIGN_UNSIGNED, "unsigned"); - - /* Now check the real type */ - switch (C & T_MASK_TYPE) { - case T_TYPE_CHAR: - fprintf (F, "char"); - break; - case T_TYPE_SHORT: - fprintf (F, "short"); - break; - case T_TYPE_INT: - fprintf (F, "int"); - break; - case T_TYPE_LONG: - fprintf (F, "long"); - break; - case T_TYPE_LONGLONG: - fprintf (F, "long long"); - break; - case T_TYPE_ENUM: - fprintf (F, "enum"); - break; - case T_TYPE_FLOAT: - fprintf (F, "float"); - break; - case T_TYPE_DOUBLE: - fprintf (F, "double"); - break; - case T_TYPE_VOID: - fprintf (F, "void"); - break; - case T_TYPE_STRUCT: - fprintf (F, "struct %s", ((SymEntry*) T->A.P)->Name); - break; - case T_TYPE_UNION: - fprintf (F, "union %s", ((SymEntry*) T->A.P)->Name); - break; - case T_TYPE_ARRAY: - /* Recursive call */ - PrintType (F, T + 1); - if (T->A.L == UNSPECIFIED) { - fprintf (F, " []"); - } else { - fprintf (F, " [%ld]", T->A.L); - } - return; - case T_TYPE_PTR: - /* Recursive call */ - PrintType (F, T + 1); - fprintf (F, " *"); - return; - case T_TYPE_FUNC: - fprintf (F, "function returning "); - break; - default: - fprintf (F, "unknown type: %04lX", T->C); - } - - /* Next element */ - ++T; - } + StrBuf Buf = AUTO_STRBUF_INITIALIZER; + fprintf (F, "%s", SB_GetConstBuf (GetFullTypeNameBuf (&Buf, T))); + SB_Done (&Buf); } void PrintFuncSig (FILE* F, const char* Name, Type* T) -/* Print a function signature. */ +/* Print a function signature */ { + StrBuf Buf = AUTO_STRBUF_INITIALIZER; + StrBuf ParamList = AUTO_STRBUF_INITIALIZER; + StrBuf East = AUTO_STRBUF_INITIALIZER; + StrBuf West = AUTO_STRBUF_INITIALIZER; + /* Get the function descriptor */ const FuncDesc* D = GetFuncDesc (T); - /* Print a comment with the function signature */ - PrintType (F, GetFuncReturn (T)); - if (IsQualNear (T)) { - fprintf (F, " __near__"); + /* Get the parameter list string. Start from the first parameter */ + SymEntry* Param = D->SymTab->SymHead; + for (unsigned 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 (!HasAnonName (Param)) { + SB_AppendStr (&Buf, Param->Name); + } + SB_AppendStr (&ParamList, SB_GetConstBuf (GetFullTypeNameBuf (&Buf, Param->Type))); + SB_Clear (&Buf); + /* Next argument */ + Param = Param->NextSym; } - if (IsQualFar (T)) { - fprintf (F, " __far__"); - } - if (IsQualFastcall (T)) { - fprintf (F, " __fastcall__"); - } - if (IsQualCDecl (T)) { - fprintf (F, " __cdecl__"); - } - fprintf (F, " %s (", Name); - - /* Parameters */ - if (D->Flags & FD_VOID_PARAM) { - fprintf (F, "void"); + if ((D->Flags & FD_VARIADIC) == 0) { + if (D->ParamCount == 0 && (D->Flags & FD_EMPTY) == 0) { + SB_AppendStr (&ParamList, "void"); + } } else { - unsigned I; - SymEntry* E = D->SymTab->SymHead; - for (I = 0; I < D->ParamCount; ++I) { - if (I > 0) { - fprintf (F, ", "); - } - if (SymIsRegVar (E)) { - fprintf (F, "register "); - } - PrintType (F, E->Type); - E = E->NextSym; + if (D->ParamCount > 0) { + SB_AppendStr (&ParamList, ", ..."); + } else { + SB_AppendStr (&ParamList, "..."); } } + SB_Terminate (&ParamList); - /* End of parameter list */ - fprintf (F, ")"); + /* Get the function qualifiers */ + if (GetQualifierTypeCodeNameBuf (&Buf, T->C, T_QUAL_NONE) > 0) { + /* Append a space between the qualifiers and the name */ + SB_AppendChar (&Buf, ' '); + } + SB_Terminate (&Buf); + + /* 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, GetFuncReturn (T)); + SB_Append (&West, &East); + SB_Terminate (&West); + + /* Output */ + fprintf (F, "%s", SB_GetConstBuf (&West)); + SB_Done (&East); + SB_Done (&West); } void PrintRawType (FILE* F, const Type* T) -/* Print a type string in raw format (for debugging) */ +/* Print a type string in raw hex format (for debugging) */ { while (T->C != T_END) { fprintf (F, "%04lX ", T->C); diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 660681909..00a43fbe1 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -278,13 +278,13 @@ Type* PointerTo (const Type* T); */ void PrintType (FILE* F, const Type* T); -/* Output translation of type array. */ - -void PrintRawType (FILE* F, const Type* T); -/* Print a type string in raw format (for debugging) */ +/* Print fulle name of the type */ void PrintFuncSig (FILE* F, const char* Name, Type* T); -/* Print a function signature. */ +/* Print a function signature */ + +void PrintRawType (FILE* F, const Type* T); +/* Print a type string in raw hex format (for debugging) */ int TypeHasAttr (const Type* T); /* Return true if the given type has attribute data */ From f206833a2028362557da2e06dc982a1aace943d3 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 15 Aug 2020 09:10:17 +0800 Subject: [PATCH 1582/2161] Alternative fix for Issue #1167. --- src/cc65/codeinfo.c | 2 +- src/cc65/compile.c | 9 +++++---- src/cc65/datatype.c | 22 ---------------------- src/cc65/datatype.h | 6 ------ src/cc65/function.c | 13 +++++-------- src/cc65/function.h | 5 ++++- src/cc65/pragma.c | 2 +- src/cc65/symentry.h | 1 - src/cc65/symtab.c | 23 +++-------------------- 9 files changed, 19 insertions(+), 64 deletions(-) diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index c9dea5071..3e1d58709 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -392,7 +392,7 @@ fncls_t GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) /* Did we find it in the top-level table? */ if (E && IsTypeFunc (E->Type)) { - FuncDesc* D = GetFuncCompositeDesc (E); + FuncDesc* D = GetFuncDesc (E->Type); /* A variadic function will use the Y register (the parameter list ** size is passed there). A fastcall function will use the A or A/X diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 54918fb21..82dc7ec63 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -77,6 +77,7 @@ static void Parse (void) { int comma; SymEntry* Entry; + FuncDesc* FuncDef = 0; /* Go... */ NextToken (); @@ -187,9 +188,9 @@ static void Parse (void) /* Convert an empty parameter list into one accepting no ** parameters (same as void) as required by the standard. */ - FuncDesc* D = GetFuncDesc (Decl.Type); - if (D->Flags & FD_EMPTY) { - D->Flags = (D->Flags & ~FD_EMPTY) | FD_VOID_PARAM; + FuncDef = GetFuncDesc (Decl.Type); + if (FuncDef->Flags & FD_EMPTY) { + FuncDef->Flags = (FuncDef->Flags & ~FD_EMPTY) | FD_VOID_PARAM; } } else { /* Just a declaration */ @@ -315,7 +316,7 @@ SkipOneDecl: NextToken (); } else { /* Parse the function body */ - NewFunc (Entry); + NewFunc (Entry, FuncDef); } } diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 48773cba5..0f3c3e5f9 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -1140,28 +1140,6 @@ Type* GetFuncReturn (Type* T) -Type* GetFuncCompositeType (SymEntry* Func) -/* Get the composite function type */ -{ - /* Be sure it's a function type */ - CHECK (IsClassFunc (Func->Type)); - - return Func->V.F.Composite->Type; -} - - - -FuncDesc* GetFuncCompositeDesc (SymEntry* Func) -/* Get the composite function type descriptor */ -{ - /* Be sure it's a function type */ - CHECK (IsClassFunc (Func->Type)); - - return GetFuncDesc (Func->V.F.Composite->Type); -} - - - long GetElementCount (const Type* T) /* Get the element count of the array specified in T (which must be of ** array type). diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 00a43fbe1..54f601364 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -816,12 +816,6 @@ void SetFuncDesc (Type* T, FuncDesc* F); Type* GetFuncReturn (Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -Type* GetFuncCompositeType (struct SymEntry* Func); -/* Get the composite function type */ - -FuncDesc* GetFuncCompositeDesc (struct SymEntry* Func); -/* Get the composite function type descriptor */ - long GetElementCount (const Type* T); /* Get the element count of the array specified in T (which must be of ** array type). diff --git a/src/cc65/function.c b/src/cc65/function.c index b2291b312..fc113b29a 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -72,7 +72,7 @@ Function* CurrentFunc = 0; -static Function* NewFunction (struct SymEntry* Sym) +static Function* NewFunction (struct SymEntry* Sym, FuncDesc* D) /* Create a new function activation structure and return it */ { /* Allocate a new structure */ @@ -81,7 +81,7 @@ static Function* NewFunction (struct SymEntry* Sym) /* Initialize the fields */ F->FuncEntry = Sym; F->ReturnType = GetFuncReturn (Sym->Type); - F->Desc = GetFuncDesc (Sym->Type); + F->Desc = D; F->Reserved = 0; F->RetLab = GetLocalLabel (); F->TopLevelSP = 0; @@ -295,7 +295,7 @@ static void F_RestoreRegVars (Function* F) } /* Get the first symbol from the function symbol table */ - Sym = GetFuncDesc (F->FuncEntry->Type)->SymTab->SymHead; + Sym = F->Desc->SymTab->SymHead; /* Walk through all symbols checking for register variables */ while (Sym) { @@ -375,18 +375,15 @@ static void F_EmitDebugInfo (void) -void NewFunc (SymEntry* Func) +void NewFunc (SymEntry* Func, FuncDesc* D) /* Parse argument declarations and function body. */ { int C99MainFunc = 0;/* Flag for C99 main function returning int */ SymEntry* Param; const Type* RType; /* Real type used for struct parameters */ - /* Get the function descriptor from the function entry */ - FuncDesc* D = GetFuncDesc (Func->Type); - /* Allocate the function activation record for the function */ - CurrentFunc = NewFunction (Func); + CurrentFunc = NewFunction (Func, D); /* Reenter the lexical level */ ReenterFunctionLevel (D); diff --git a/src/cc65/function.h b/src/cc65/function.h index 0954322ac..8231a1970 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -67,6 +67,9 @@ struct Function { /* Structure that holds all data needed for function activation */ typedef struct Function Function; +/* Forward declaration */ +struct FuncDesc; + /* Function activation data for current function (or NULL) */ extern Function* CurrentFunc; @@ -138,7 +141,7 @@ int F_AllocRegVar (Function* F, const Type* Type); ** bank (zero page storage). If there is no register space left, return -1. */ -void NewFunc (struct SymEntry* Func); +void NewFunc (struct SymEntry* Func, struct FuncDesc* D); /* Parse argument declarations and function body. */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index a0876a550..c614bbfdd 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -527,7 +527,7 @@ static void WrappedCallPragma (StrBuf* B) PushWrappedCall(Entry, (unsigned char) Val); Entry->Flags |= SC_REF; - GetFuncCompositeDesc (Entry)->Flags |= FD_CALL_WRAPPER; + GetFuncDesc (Entry->Type)->Flags |= FD_CALL_WRAPPER; } else { diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 6b05dd72b..94fe66032 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -191,7 +191,6 @@ struct SymEntry { /* Data for functions */ struct { - SymEntry* Composite;/* Entry to hold composite function type */ struct Segments* Seg; /* Segments for this function */ struct LiteralPool* LitPool; /* Literal pool for this function */ } F; diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 02e96cf21..6e0654576 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -590,14 +590,14 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags Entry = 0; } else { /* New type must be compatible with the composite prototype */ - if (TypeCmp (GetFuncCompositeType (Entry), T) < TC_EQUAL) { + if (TypeCmp (Entry->Type, T) < TC_EQUAL) { Error ("Conflicting function types for '%s'", Entry->Name); Entry = 0; } else { /* Refine the existing composite prototype with this new ** one. */ - RefineFuncDesc (GetFuncCompositeType (Entry), T); + RefineFuncDesc (Entry->Type, T); } } @@ -1165,14 +1165,6 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) } if (Entry) { - /* Update existing function type if this is a definition */ - if (IsTypeFunc (Entry->Type) && - !SymIsDef (Entry) && - (Flags & SC_DEF) == SC_DEF) { - TypeFree (Entry->Type); - Entry->Type = TypeDup (T); - } - /* Add the new flags */ Entry->Flags |= Flags; } @@ -1192,17 +1184,8 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) /* Set the symbol attributes */ Entry->Type = TypeDup (T); - /* If this is a function, set the function composite typeand clear - ** additional fields. - */ + /* If this is a function, clear additional fields */ if (IsTypeFunc (T)) { - /* GitHub #1167 - Make a composite prototype */ - ident Ident; - AnonName (Ident, "prototype"); - Entry->V.F.Composite = NewSymEntry (Ident, SC_EXTERN | SC_DECL | SC_ALIAS | SC_FUNC); - Entry->V.F.Composite->Type = TypeDup (T); - AddSymEntry (SymTab0, Entry->V.F.Composite); - Entry->V.F.Seg = 0; } From cf41fccc0aee2c67fc47baffdc376a8122cdff5c Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 18 Aug 2020 00:40:29 +0200 Subject: [PATCH 1583/2161] added test related to issue #1143 --- test/err/bug1143err.c | 11 +++++++++++ test/val/bug1143warn.c | 9 +++++++++ 2 files changed, 20 insertions(+) create mode 100644 test/err/bug1143err.c create mode 100644 test/val/bug1143warn.c diff --git a/test/err/bug1143err.c b/test/err/bug1143err.c new file mode 100644 index 000000000..03a6e6d35 --- /dev/null +++ b/test/err/bug1143err.c @@ -0,0 +1,11 @@ + +/* bug #1143 - Multiple storage class specifiers in one declaration? */ + +static static void* y[1]; /* warning */ +extern static int a; /* error */ +extern typedef int A; /* error */ + +int main(void) +{ + return 0; +} diff --git a/test/val/bug1143warn.c b/test/val/bug1143warn.c new file mode 100644 index 000000000..9bbc8ea8b --- /dev/null +++ b/test/val/bug1143warn.c @@ -0,0 +1,9 @@ + +/* bug #1143 - Multiple storage class specifiers in one declaration? */ + +static static void* y[1]; /* warning */ + +int main(void) +{ + return 0; +} From 6d8860b9de994607e4cebaf38350a7ac0b1c8c50 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 18 Aug 2020 00:41:07 +0200 Subject: [PATCH 1584/2161] added test related to issue #1145 --- test/err/bug1145.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test/err/bug1145.c diff --git a/test/err/bug1145.c b/test/err/bug1145.c new file mode 100644 index 000000000..23401f91b --- /dev/null +++ b/test/err/bug1145.c @@ -0,0 +1,13 @@ + +/* bug #1145 - Internal error with function type object */ + +void f() +{ + f = 0; /* internal error */ +} + +int main(void) +{ + f(); + return 0; +} From 2663561c623c9666a89d82ca9d435680312e4f71 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 18 Aug 2020 00:41:35 +0200 Subject: [PATCH 1585/2161] added test related to pr #1135 --- test/err/pr1135.c | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 test/err/pr1135.c diff --git a/test/err/pr1135.c b/test/err/pr1135.c new file mode 100644 index 000000000..01eff7d93 --- /dev/null +++ b/test/err/pr1135.c @@ -0,0 +1,8 @@ + +void f(void) {} +void f(int); /* Should fail */ + +int main(void) +{ + return 0; +} From 87889df9e90646db40a86eadf34c50d5fde1f324 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 15 Aug 2020 06:27:11 +0800 Subject: [PATCH 1586/2161] Fixed type checking in relation operations. --- src/cc65/expr.c | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index db50e14b0..84d709eb9 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -2303,16 +2303,21 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ LoadExpr (CF_NONE, &Expr2); } + /* Check if operands have allowed types for this operation */ + if (!IsRelationType (Expr->Type) || !IsRelationType (Expr2.Type)) { + /* Output only one message even if both sides are wrong */ + TypeCompatibilityDiagnostic (Expr->Type, Expr2.Type, 1, + "Comparing types '%s' with '%s' is invalid"); + /* Avoid further errors */ + ED_MakeConstAbsInt (Expr, 0); + ED_MakeConstAbsInt (&Expr2, 0); + } + /* Some operations aren't allowed on function pointers */ if ((Gen->Flags & GEN_NOFUNC) != 0) { - /* Output only one message even if both sides are wrong */ - if (IsTypeFuncPtr (Expr->Type)) { - Error ("Invalid left operand for relational operator"); - /* Avoid further errors */ - ED_MakeConstAbsInt (Expr, 0); - ED_MakeConstAbsInt (&Expr2, 0); - } else if (IsTypeFuncPtr (Expr2.Type)) { - Error ("Invalid right operand for relational operator"); + if ((IsTypeFuncPtr (Expr->Type) || IsTypeFuncPtr (Expr2.Type))) { + /* Output only one message even if both sides are wrong */ + Error ("Cannot use function pointers in this relation operation"); /* Avoid further errors */ ED_MakeConstAbsInt (Expr, 0); ED_MakeConstAbsInt (&Expr2, 0); @@ -2321,9 +2326,14 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* Make sure, the types are compatible */ if (IsClassInt (Expr->Type)) { - if (!IsClassInt (Expr2.Type) && !(IsClassPtr(Expr2.Type) && ED_IsNullPtr(Expr))) { - TypeCompatibilityDiagnostic (Expr->Type, Expr2.Type, 1, - "Incompatible types comparing '%s' with '%s'"); + if (!IsClassInt (Expr2.Type) && !ED_IsNullPtr (Expr)) { + if (IsClassPtr (Expr2.Type)) { + TypeCompatibilityDiagnostic (Expr->Type, PtrConversion (Expr2.Type), 0, + "Comparing integer '%s' with pointer '%s'"); + } else { + TypeCompatibilityDiagnostic (Expr->Type, Expr2.Type, 1, + "Comparing types '%s' with '%s' is invalid"); + } } } else if (IsClassPtr (Expr->Type)) { if (IsClassPtr (Expr2.Type)) { @@ -2334,12 +2344,17 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ Type* right = Indirect (Expr2.Type); if (TypeCmp (left, right) < TC_QUAL_DIFF && left->C != T_VOID && right->C != T_VOID) { /* Incompatible pointers */ - TypeCompatibilityDiagnostic (Expr->Type, Expr2.Type, 1, + TypeCompatibilityDiagnostic (PtrConversion (Expr->Type), PtrConversion (Expr2.Type), 0, "Incompatible pointer types comparing '%s' with '%s'"); } } else if (!ED_IsNullPtr (&Expr2)) { - TypeCompatibilityDiagnostic (Expr->Type, Expr2.Type, 1, - "Comparing pointer type '%s' with '%s'"); + if (IsClassInt (Expr2.Type)) { + TypeCompatibilityDiagnostic (PtrConversion (Expr->Type), Expr2.Type, 0, + "Comparing pointer type '%s' with integer type '%s'"); + } else { + TypeCompatibilityDiagnostic (Expr->Type, Expr2.Type, 1, + "Comparing types '%s' with '%s' is invalid"); + } } } From 56b659c0be743a2630993bf4b7eaaff1c8415a2d Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 15 Aug 2020 06:27:11 +0800 Subject: [PATCH 1587/2161] Made char type a distinct type. --- src/cc65/datatype.c | 25 +++++++++++-------------- src/cc65/datatype.h | 34 +++++++++++++++++++++++++++------- src/cc65/declare.c | 4 ++-- src/cc65/global.h | 2 +- src/cc65/main.c | 2 +- src/cc65/stdfunc.c | 10 +++++----- src/cc65/typecmp.c | 6 ++++++ 7 files changed, 53 insertions(+), 30 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 0f3c3e5f9..b95e37f87 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,6 +59,7 @@ /* Predefined type strings */ +Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; @@ -431,14 +432,6 @@ int SignExtendChar (int C) -TypeCode GetDefaultChar (void) -/* Return the default char type (signed/unsigned) depending on the settings */ -{ - return IS_Get (&SignedChars)? T_SCHAR : T_UCHAR; -} - - - Type* GetCharArrayType (unsigned Len) /* Return the type for a char array of the given length */ { @@ -448,7 +441,7 @@ Type* GetCharArrayType (unsigned Len) /* Fill the type string */ T[0].C = T_ARRAY; T[0].A.L = Len; /* Array length is in the L attribute */ - T[1].C = GetDefaultChar (); + T[1].C = T_CHAR; T[2].C = T_END; /* Return the new type */ @@ -685,8 +678,9 @@ int TypeHasAttr (const Type* T) const Type* GetUnderlyingType (const Type* Type) /* Get the underlying type of an enum or other integer class type */ { - if (IsTypeEnum (Type)) { - + if (IsISOChar (Type)) { + return IS_Get (&SignedChars) ? type_schar : type_uchar; + } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ if (Type->A.P == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); @@ -708,8 +702,11 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) TypeCode Underlying = UnqualifiedType (Type->C); TypeCode TCode; - /* We could also support other T_CLASS_INT types, but just enums for now */ - if (IsTypeEnum (Type)) { + if (IsISOChar (Type)) { + + return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; + + } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ if (Type->A.P == 0) { @@ -996,7 +993,7 @@ int IsClassArithmetic (const Type* T) int IsClassBasic (const Type* T) /* Return true if this is a char, integer or floating type */ { - return IsRawTypeChar (T) || IsClassInt (T) || IsClassFloat (T); + return IsClassChar (T) || IsClassInt (T) || IsClassFloat (T); } diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 54f601364..472098788 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -117,7 +117,7 @@ enum { T_MASK_QUAL = 0x07F000, /* Types */ - T_CHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_CHAR, + T_CHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_NONE | T_SIZE_CHAR, T_SCHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_CHAR, T_UCHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_CHAR, T_SHORT = T_TYPE_SHORT | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_SHORT, @@ -189,6 +189,7 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ +extern Type type_char[]; extern Type type_schar[]; extern Type type_uchar[]; extern Type type_int[]; @@ -250,9 +251,6 @@ void TypeFree (Type* T); int SignExtendChar (int C); /* Do correct sign extension of a character */ -TypeCode GetDefaultChar (void); -/* Return the default char type (signed/unsigned) depending on the settings */ - Type* GetCharArrayType (unsigned Len); /* Return the type for a char array of the given length */ @@ -365,7 +363,7 @@ INLINE TypeCode GetRawType (const Type* T) #if defined(HAVE_INLINE) INLINE int IsTypeChar (const Type* T) -/* Return true if this is a character type */ +/* Return true if this is a char type */ { return (GetRawType (GetUnderlyingType (T)) == T_TYPE_CHAR); } @@ -395,7 +393,7 @@ INLINE int IsTypeInt (const Type* T) #if defined(HAVE_INLINE) INLINE int IsTypeLong (const Type* T) -/* Return true if this is a long type (signed or unsigned) */ +/* Return true if this is a long int type (signed or unsigned) */ { return (GetRawType (GetUnderlyingType (T)) == T_TYPE_LONG); } @@ -403,9 +401,31 @@ INLINE int IsTypeLong (const Type* T) # define IsTypeLong(T) (GetRawType (GetUnderlyingType (T)) == T_TYPE_LONG) #endif +#if defined(HAVE_INLINE) +INLINE int IsISOChar (const Type* T) +/* Return true if this is a narrow character type (without signed/unsigned) */ +{ + return (UnqualifiedType (T->C) == T_CHAR); +} +#else +# define IsISOChar(T) (UnqualifiedType ((T)->C) == T_CHAR) +#endif + +#if defined(HAVE_INLINE) +INLINE int IsClassChar (const Type* T) +/* Return true if this is a narrow character type (including signed/unsigned). +** For now this is the same as IsRawTypeChar(T). +*/ +{ + return (GetRawType (T) == T_TYPE_CHAR); +} +#else +# define IsClassChar(T) (GetRawType (T) == T_TYPE_CHAR) +#endif + #if defined(HAVE_INLINE) INLINE int IsRawTypeChar (const Type* T) -/* Return true if this is a character raw type */ +/* Return true if this is a char raw type (including signed/unsigned) */ { return (GetRawType (T) == T_TYPE_CHAR); } diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 36286b6d5..44d4e4142 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1169,7 +1169,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers) case TOK_CHAR: NextToken (); - D->Type[0].C = GetDefaultChar(); + D->Type[0].C = T_CHAR; D->Type[1].C = T_END; break; @@ -2195,7 +2195,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) long ElementCount = GetElementCount (T); /* Special handling for a character array initialized by a literal */ - if (IsRawTypeChar (ElementType) && + if (IsClassChar (ElementType) && (CurTok.Tok == TOK_SCONST || CurTok.Tok == TOK_WCSCONST || (CurTok.Tok == TOK_LCURLY && (NextTok.Tok == TOK_SCONST || NextTok.Tok == TOK_WCSCONST)))) { diff --git a/src/cc65/global.h b/src/cc65/global.h index 4ffc84a39..b9bcf5550 100644 --- a/src/cc65/global.h +++ b/src/cc65/global.h @@ -67,7 +67,7 @@ extern IntStack EnableRegVars; /* Enable register variables */ extern IntStack AllowRegVarAddr; /* Allow taking addresses of register vars */ extern IntStack RegVarsToCallStack; /* Save reg variables on call stack */ extern IntStack StaticLocals; /* Make local variables static */ -extern IntStack SignedChars; /* Make characters signed by default */ +extern IntStack SignedChars; /* Use 'signed char' as the underlying type of 'char' */ extern IntStack CheckStack; /* Generate stack overflow checks */ extern IntStack Optimize; /* Optimize flag */ extern IntStack CodeSizeFactor; /* Size factor for generated code */ diff --git a/src/cc65/main.c b/src/cc65/main.c index 3e60bcb95..26dd721be 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -731,7 +731,7 @@ static void OptRodataName (const char* Opt attribute ((unused)), const char* Arg static void OptSignedChars (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) -/* Make default characters signed */ +/* Use 'signed char' as the underlying type of 'char' */ { IS_Set (&SignedChars, 1); } diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 6d61f2750..94e56a625 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -783,8 +783,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int Offs; /* Setup the argument type string */ - Arg1Type[1].C = GetDefaultChar () | T_QUAL_CONST; - Arg2Type[1].C = GetDefaultChar () | T_QUAL_CONST; + Arg1Type[1].C = T_CHAR | T_QUAL_CONST; + Arg2Type[1].C = T_CHAR | T_QUAL_CONST; /* Argument #1 */ ParseArg (&Arg1, Arg1Type); @@ -983,8 +983,8 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) unsigned L1; /* Setup the argument type string */ - Arg1Type[1].C = GetDefaultChar (); - Arg2Type[1].C = GetDefaultChar () | T_QUAL_CONST; + Arg1Type[1].C = T_CHAR; + Arg2Type[1].C = T_CHAR | T_QUAL_CONST; /* Argument #1 */ ParseArg (&Arg1, Arg1Type); @@ -1181,7 +1181,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) unsigned L; /* Setup the argument type string */ - ArgType[1].C = GetDefaultChar () | T_QUAL_CONST; + ArgType[1].C = T_CHAR | T_QUAL_CONST; /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index e3e42e67f..24d9a385f 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -233,6 +233,12 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) } + /* 'char' is neither 'signed char' nor 'unsigned char' */ + if ((IsISOChar (lhs) && !IsISOChar (rhs)) || + (!IsISOChar (lhs) && IsISOChar (rhs))) { + SetResult (Result, TC_COMPATIBLE); + } + /* On indirection level zero, a qualifier or sign difference is ** accepted. The types are no longer equal, but compatible. */ From 55cebc7b9e8d5e34dc80d638405b29968e89c309 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Mon, 17 Aug 2020 22:29:52 +0200 Subject: [PATCH 1588/2161] Move bit-field adjustment to codegen.c Extract functions g_testbitfield and g_extractbitfield from LoadExpr. This helps prepare for #1192, since g_extractbitfield will get much longer and call AddCodeLine. --- src/cc65/codegen.c | 58 +++++++++++++++++++++++++++++++++++++++++++++ src/cc65/codegen.h | 11 +++++++++ src/cc65/loadexpr.c | 44 +++------------------------------- 3 files changed, 72 insertions(+), 41 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 2c6624a5c..a81b2cf46 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -33,6 +33,7 @@ +#include <limits.h> #include <stdio.h> #include <string.h> #include <stdarg.h> @@ -4424,6 +4425,63 @@ void g_initstatic (unsigned InitLabel, unsigned VarLabel, unsigned Size) +/*****************************************************************************/ +/* Bit-fields */ +/*****************************************************************************/ + + + +void g_testbitfield (unsigned Flags, unsigned BitOffs, unsigned BitWidth) +/* Test bit-field in ax. */ +{ + unsigned EndBit = BitOffs + BitWidth; + + /* If we need to do a test, then we avoid shifting (ASR only shifts one bit at a time, + ** so is slow) and just AND with the appropriate mask, then test the result of that. + */ + + /* Avoid overly large shift on host platform. */ + if (EndBit == sizeof (unsigned long) * CHAR_BIT) { + g_and (Flags | CF_CONST, (~0UL << BitOffs)); + } else { + g_and (Flags | CF_CONST, ((1UL << EndBit) - 1) & (~0UL << BitOffs)); + } + + /* TODO: When long bit-fields are supported, an optimization to test only 3 bytes when + ** EndBit <= 24 is possible. + */ + g_test (Flags | CF_CONST); +} + + + +void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, + unsigned BitOffs, unsigned BitWidth) +/* Extract bits from bit-field in ax. */ +{ + unsigned EndBit = BitOffs + BitWidth; + + /* Shift right by the bit offset; no code is emitted if BitOffs is zero */ + g_asr (Flags | CF_CONST, BitOffs); + + /* Since we have now shifted down, we could do char ops when the width fits in a char, but we + ** also need to clear the high byte since we've been using CF_FORCECHAR up to now. + */ + + /* And by the width if the field doesn't end on a char or int boundary. If it does end on + ** a boundary, then zeros have already been shifted in, but we need to clear the high byte + ** for char. g_and emits no code if the mask is all ones. + */ + if (EndBit == CHAR_BITS) { + /* We need to clear the high byte, since CF_FORCECHAR was set. */ + g_and (FullWidthFlags | CF_CONST, 0xFF); + } else if (EndBit != INT_BITS) { + g_and (FullWidthFlags | CF_CONST, (0x0001U << BitWidth) - 1U); + } +} + + + /*****************************************************************************/ /* Switch statement */ /*****************************************************************************/ diff --git a/src/cc65/codegen.h b/src/cc65/codegen.h index c63fc5398..6581fc54e 100644 --- a/src/cc65/codegen.h +++ b/src/cc65/codegen.h @@ -471,6 +471,17 @@ void g_initstatic (unsigned InitLabel, unsigned VarLabel, unsigned Size); +/*****************************************************************************/ +/* Bit-fields */ +/*****************************************************************************/ + +void g_testbitfield (unsigned Flags, unsigned BitOffs, unsigned BitWidth); +/* Test bit-field in ax. */ + +void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, + unsigned BitOffs, unsigned BitWidth); +/* Extract bits from bit-field in ax. */ + /*****************************************************************************/ /* Switch statement */ /*****************************************************************************/ diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index ba585d3e3..452d9a9a3 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -33,8 +33,6 @@ -#include <limits.h> - /* cc65 */ #include "codegen.h" #include "error.h" @@ -115,11 +113,10 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) ** field is completely contained in the lower byte, we will throw away ** the high byte anyway and may therefore load just the low byte. */ - unsigned EndBit = 0; /* End bit for bit-fields, or zero if non-bit-field. */ int AdjustBitField = 0; unsigned BitFieldFullWidthFlags = 0; if (ED_IsBitField (Expr)) { - EndBit = Expr->BitOffs + Expr->BitWidth; + unsigned EndBit = Expr->BitOffs + Expr->BitWidth; AdjustBitField = Expr->BitOffs != 0 || (EndBit != CHAR_BITS && EndBit != INT_BITS); /* TODO: This probably needs to be guarded by AdjustBitField when long bit-fields are @@ -226,50 +223,15 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) ** so be sure to always use unsigned ints for the operations. */ if (AdjustBitField) { - unsigned F = Flags | CF_CONST; - /* We always need to do something with the low byte, so there is no opportunity ** for optimization by skipping it. */ CHECK (Expr->BitOffs < CHAR_BITS); if (ED_NeedsTest (Expr)) { - /* If we need to do a test, then we avoid shifting (ASR only shifts one bit - ** at a time, so is slow) and just AND with the appropriate mask, then test - ** the result of that. - */ - - /* Avoid overly large shift on host platform. */ - if (EndBit == sizeof (unsigned long) * CHAR_BIT) { - g_and (F, (~0UL << Expr->BitOffs)); - } else { - g_and (F, ((1UL << EndBit) - 1) & (~0UL << Expr->BitOffs)); - } - - /* TODO: When long bit-fields are supported, an optimization to test only 3 bytes - ** when EndBit <= 24 is possible. - */ - g_test (F); + g_testbitfield (Flags, Expr->BitOffs, Expr->BitWidth); } else { - /* Shift right by the bit offset; no code is emitted if BitOffs is zero */ - g_asr (F, Expr->BitOffs); - - /* Since we have now shifted down, we could do char ops when the width fits in - ** a char, but we also need to clear the high byte since we've been using - ** CF_FORCECHAR up to now. - */ - - /* And by the width if the field doesn't end on a char or int boundary. - ** If it does end on a boundary, then zeros have already been shifted in, - ** but we need to clear the high byte for char. g_and emits no code if the mask - ** is all ones. - */ - if (EndBit == CHAR_BITS) { - /* We need to clear the high byte, since CF_FORCECHAR was set. */ - g_and (BitFieldFullWidthFlags | CF_CONST, 0xFF); - } else if (EndBit != INT_BITS) { - g_and (BitFieldFullWidthFlags | CF_CONST, (0x0001U << Expr->BitWidth) - 1U); - } + g_extractbitfield (Flags, BitFieldFullWidthFlags, Expr->BitOffs, Expr->BitWidth); } } From ff535b8e1a79205fe877904d922068ab6d3467d2 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sun, 19 Jul 2020 22:59:44 +0200 Subject: [PATCH 1589/2161] Treat signed int bit-fields as signed Prior to this PR, `int`, `signed int`, and `unsigned int` bitfields are all treated as `unsigned int`. With this PR, `signed int` will be treated as `signed int`, and the others remain unsigned. Since `Type` does not distinguish between `int` and `signed int`, add an extra `int* SignenessSpecified` param to `ParseTypeSpec` so we can tell these apart for bit-fields and treat plain `int : N` as `unsigned int : N` since it is more efficient to zero-extend than sign-extend. Fixes #1095 --- src/cc65/codegen.c | 75 +++++++++++++++++++++++--- src/cc65/codegen.h | 2 +- src/cc65/declare.c | 102 +++++++++++++++++++++++++++-------- src/cc65/loadexpr.c | 13 +++-- src/cc65/symtab.c | 16 ++++-- src/cc65/symtab.h | 3 +- test/{todo => val}/bug1095.c | 47 ++++++++++++++-- 7 files changed, 218 insertions(+), 40 deletions(-) rename test/{todo => val}/bug1095.c (74%) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index a81b2cf46..a0dbc498b 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -4455,7 +4455,7 @@ void g_testbitfield (unsigned Flags, unsigned BitOffs, unsigned BitWidth) -void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, +void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, int IsSigned, unsigned BitOffs, unsigned BitWidth) /* Extract bits from bit-field in ax. */ { @@ -4465,18 +4465,79 @@ void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, g_asr (Flags | CF_CONST, BitOffs); /* Since we have now shifted down, we could do char ops when the width fits in a char, but we - ** also need to clear the high byte since we've been using CF_FORCECHAR up to now. + ** also need to clear (or set) the high byte since we've been using CF_FORCECHAR up to now. */ + unsigned Mask = (1U << BitWidth) - 1; - /* And by the width if the field doesn't end on a char or int boundary. If it does end on - ** a boundary, then zeros have already been shifted in, but we need to clear the high byte - ** for char. g_and emits no code if the mask is all ones. + /* To zero-extend, we will and by the width if the field doesn't end on a char or + ** int boundary. If it does end on a boundary, then zeros will have already been shifted in, + ** but we need to clear the high byte for char. g_and emits no code if the mask is all ones. + ** This is here so the signed and unsigned branches can use it. */ + unsigned ZeroExtendMask = 0; /* Zero if we don't need to zero-extend. */ if (EndBit == CHAR_BITS) { /* We need to clear the high byte, since CF_FORCECHAR was set. */ - g_and (FullWidthFlags | CF_CONST, 0xFF); + ZeroExtendMask = 0xFF; } else if (EndBit != INT_BITS) { - g_and (FullWidthFlags | CF_CONST, (0x0001U << BitWidth) - 1U); + ZeroExtendMask = (1U << BitWidth) - 1; + } + + /* Handle signed bit-fields. */ + if (IsSigned) { + /* Push A, since the sign bit test will destroy it. */ + AddCodeLine ("pha"); + + /* Check sign bit */ + unsigned SignBitPos = BitWidth - 1U; + unsigned SignBitByte = SignBitPos / CHAR_BITS; + unsigned SignBitPosInByte = SignBitPos % CHAR_BITS; + unsigned SignBitMask = 1U << SignBitPosInByte; + + /* Move the correct byte to A. This can only be X for now, + ** but more cases will be needed to support long. + */ + switch (SignBitByte) { + case 0: + break; + case 1: + AddCodeLine ("txa"); + break; + default: + FAIL ("Invalid Byte for sign bit"); + } + + /* Test the sign bit */ + AddCodeLine ("and #$%02X", SignBitMask); + unsigned ZeroExtendLabel = GetLocalLabel (); + AddCodeLine ("beq %s", LocalLabelName (ZeroExtendLabel)); + + /* Pop A back and sign extend if required; operating on the full result need + ** to sign-extend into high byte, too. + */ + AddCodeLine ("pla"); + g_or (FullWidthFlags | CF_CONST, ~Mask); + + /* Apparently, there is no unconditional branch BRA, so use JMP. */ + unsigned DoneLabel = GetLocalLabel (); + AddCodeLine ("jmp %s", LocalLabelName (DoneLabel)); + + /* Pop A back, then zero-extend; we need to duplicate the PLA rather than move it before + ** the branch to share with the other label because PLA sets the condition codes. + */ + g_defcodelabel (ZeroExtendLabel); + AddCodeLine ("pla"); + + /* Zero the upper bits, the same as the unsigned path. */ + if (ZeroExtendMask != 0) { + g_and (FullWidthFlags | CF_CONST, ZeroExtendMask); + } + + g_defcodelabel (DoneLabel); + } else { + /* Unsigned bit-field, only needs zero-extension. */ + if (ZeroExtendMask != 0) { + g_and (FullWidthFlags | CF_CONST, ZeroExtendMask); + } } } diff --git a/src/cc65/codegen.h b/src/cc65/codegen.h index 6581fc54e..ec4756f2d 100644 --- a/src/cc65/codegen.h +++ b/src/cc65/codegen.h @@ -478,7 +478,7 @@ void g_initstatic (unsigned InitLabel, unsigned VarLabel, unsigned Size); void g_testbitfield (unsigned Flags, unsigned BitOffs, unsigned BitWidth); /* Test bit-field in ax. */ -void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, +void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, int IsSigned, unsigned BitOffs, unsigned BitWidth); /* Extract bits from bit-field in ax. */ diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 44d4e4142..ccd4e9004 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -41,6 +41,7 @@ /* common */ #include "addrsize.h" #include "mmodel.h" +#include "shift.h" #include "xmalloc.h" /* cc65 */ @@ -87,7 +88,8 @@ struct StructInitData { -static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers); +static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, + int* SignednessSpecified); /* Parse a type specifier */ static unsigned ParseInitInternal (Type* T, int* Braces, int AllowFlexibleMembers); @@ -252,12 +254,15 @@ static void OptionalInt (void) -static void OptionalSigned (void) +static void OptionalSigned (int* SignednessSpecified) /* Eat an optional "signed" token */ { if (CurTok.Tok == TOK_SIGNED) { /* Skip it */ NextToken (); + if (SignednessSpecified != NULL) { + *SignednessSpecified = 1; + } } } @@ -728,6 +733,9 @@ static int ParseFieldWidth (Declaration* Decl) return -1; } + /* TODO: This can be relaxed to be any integral type, but + ** ParseStructInit currently only supports up to int. + */ if (SizeOf (Decl->Type) != SizeOf (type_uint)) { /* Only int sized types may be used for bit-fields for now */ Error ("cc65 currently only supports unsigned int bit-fields"); @@ -774,7 +782,8 @@ static unsigned PadWithBitField (unsigned StructSize, unsigned BitOffs) /* Add an anonymous bit-field that aligns to the next ** byte. */ - AddBitField (Ident, StructSize, BitOffs, PaddingBits); + AddBitField (Ident, type_uchar, StructSize, BitOffs, PaddingBits, + /*SignednessSpecified=*/1); return PaddingBits; } @@ -866,8 +875,9 @@ static SymEntry* ParseUnionDecl (const char* Name) /* Get the type of the entry */ DeclSpec Spec; + int SignednessSpecified = 0; InitDeclSpec (&Spec); - ParseTypeSpec (&Spec, -1, T_QUAL_NONE); + ParseTypeSpec (&Spec, -1, T_QUAL_NONE, &SignednessSpecified); /* Read fields with this type */ while (1) { @@ -909,7 +919,11 @@ static SymEntry* ParseUnionDecl (const char* Name) /* Add a field entry to the table. */ if (FieldWidth > 0) { - AddBitField (Decl.Ident, 0, 0, FieldWidth); + /* For a union, allocate space for the type specified by the + ** bit-field. + */ + AddBitField (Decl.Ident, Decl.Type, 0, 0, FieldWidth, + SignednessSpecified); } else { if (IsAnonName (Decl.Ident)) { Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0); @@ -997,8 +1011,9 @@ static SymEntry* ParseStructDecl (const char* Name) continue; } + int SignednessSpecified = 0; InitDeclSpec (&Spec); - ParseTypeSpec (&Spec, -1, T_QUAL_NONE); + ParseTypeSpec (&Spec, -1, T_QUAL_NONE, &SignednessSpecified); /* Read fields with this type */ while (1) { @@ -1020,12 +1035,13 @@ static SymEntry* ParseStructDecl (const char* Name) FieldWidth = ParseFieldWidth (&Decl); /* If this is not a bit field, or the bit field is too large for - ** the remainder of the current member, or we have a bit field + ** the remainder of the allocated unit, or we have a bit field ** with width zero, align the struct to the next member by adding ** a member with an anonymous name. */ if (BitOffs > 0) { - if (FieldWidth <= 0 || (BitOffs + FieldWidth) > INT_BITS) { + if (FieldWidth <= 0 || + (BitOffs + FieldWidth) > CHAR_BITS * SizeOf (Decl.Type)) { /* Add an anonymous bit-field that aligns to the next ** byte. */ @@ -1087,9 +1103,10 @@ static SymEntry* ParseStructDecl (const char* Name) ** bit-field as a char type in expressions. */ CHECK (BitOffs < CHAR_BITS); - AddBitField (Decl.Ident, StructSize, BitOffs, FieldWidth); + AddBitField (Decl.Ident, Decl.Type, StructSize, BitOffs, + FieldWidth, SignednessSpecified); BitOffs += FieldWidth; - CHECK (BitOffs <= INT_BITS); + CHECK (BitOffs <= CHAR_BITS * SizeOf (Decl.Type)); /* Add any full bytes to the struct size. */ StructSize += BitOffs / CHAR_BITS; BitOffs %= CHAR_BITS; @@ -1145,12 +1162,20 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { -static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers) -/* Parse a type specifier */ +static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, + int* SignednessSpecified) +/* 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. +*/ { ident Ident; SymEntry* Entry; + if (SignednessSpecified != NULL) { + *SignednessSpecified = 0; + } + /* Assume we have an explicit type */ D->Flags &= ~DS_DEF_TYPE; @@ -1176,12 +1201,15 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers) case TOK_LONG: NextToken (); if (CurTok.Tok == TOK_UNSIGNED) { + if (SignednessSpecified != NULL) { + *SignednessSpecified = 1; + } NextToken (); OptionalInt (); D->Type[0].C = T_ULONG; D->Type[1].C = T_END; } else { - OptionalSigned (); + OptionalSigned (SignednessSpecified); OptionalInt (); D->Type[0].C = T_LONG; D->Type[1].C = T_END; @@ -1191,12 +1219,15 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers) case TOK_SHORT: NextToken (); if (CurTok.Tok == TOK_UNSIGNED) { + if (SignednessSpecified != NULL) { + *SignednessSpecified = 1; + } NextToken (); OptionalInt (); D->Type[0].C = T_USHORT; D->Type[1].C = T_END; } else { - OptionalSigned (); + OptionalSigned (SignednessSpecified); OptionalInt (); D->Type[0].C = T_SHORT; D->Type[1].C = T_END; @@ -1210,6 +1241,9 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers) break; case TOK_SIGNED: + if (SignednessSpecified != NULL) { + *SignednessSpecified = 1; + } NextToken (); switch (CurTok.Tok) { @@ -1245,6 +1279,9 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers) break; case TOK_UNSIGNED: + if (SignednessSpecified != NULL) { + *SignednessSpecified = 1; + } NextToken (); switch (CurTok.Tok) { @@ -1835,7 +1872,7 @@ Type* ParseType (Type* T) /* Get a type without a default */ InitDeclSpec (&Spec); - ParseTypeSpec (&Spec, -1, T_QUAL_NONE); + ParseTypeSpec (&Spec, -1, T_QUAL_NONE, NULL); /* Parse additional declarators */ ParseDecl (&Spec, &Decl, DM_NO_IDENT); @@ -1967,7 +2004,7 @@ void ParseDeclSpec (DeclSpec* D, unsigned DefStorage, long DefType) ParseStorageClass (D, DefStorage); /* Parse the type specifiers passing any initial type qualifiers */ - ParseTypeSpec (D, DefType, Qualifiers); + ParseTypeSpec (D, DefType, Qualifiers, NULL); } @@ -2362,6 +2399,7 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) ** into 3 bytes. */ SI.ValBits += Entry->V.B.BitWidth; + /* TODO: Generalize this so any type can be used. */ CHECK (SI.ValBits <= CHAR_BITS + INT_BITS - 2); while (SI.ValBits >= CHAR_BITS) { OutputBitFieldData (&SI); @@ -2393,16 +2431,34 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) SI.Offs * CHAR_BITS + SI.ValBits); /* Read the data, check for a constant integer, do a range check */ - ParseScalarInitInternal (type_uint, &ED); + ParseScalarInitInternal (Entry->Type, &ED); if (!ED_IsConstAbsInt (&ED)) { Error ("Constant initializer expected"); ED_MakeConstAbsInt (&ED, 1); } - if (ED.IVal > (long) Mask) { - Warning ("Truncating value in bit-field initializer"); - ED.IVal &= (long) Mask; + + /* Truncate the initializer value to the width of the bit-field and check if we lost + ** any useful bits. + */ + Val = (unsigned) ED.IVal & Mask; + if (IsSignUnsigned (Entry->Type)) { + if (ED.IVal < 0 || (unsigned long) ED.IVal != Val) { + Warning ("Implicit truncation from '%s' to '%s : %u' in bit-field initializer" + " changes value from %ld to %u", + GetFullTypeName (ED.Type), GetFullTypeName (Entry->Type), + Entry->V.B.BitWidth, ED.IVal, Val); + } + } else { + /* Sign extend back to full width of host long. */ + unsigned ShiftBits = sizeof (long) * CHAR_BIT - Entry->V.B.BitWidth; + long RestoredVal = asr_l(asl_l (Val, ShiftBits), ShiftBits); + if (ED.IVal != RestoredVal) { + Warning ("Implicit truncation from '%s' to '%s : %u' in bit-field initializer " + "changes value from %ld to %d", + GetFullTypeName (ED.Type), GetFullTypeName (Entry->Type), + Entry->V.B.BitWidth, ED.IVal, Val); + } } - Val = (unsigned) ED.IVal; /* Add the value to the currently stored bit-field value */ Shift = (Entry->V.B.Offs - SI.Offs) * CHAR_BITS + Entry->V.B.BitOffs; @@ -2417,6 +2473,7 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) ** aligned, so will have padding before it. */ CHECK (SI.ValBits <= CHAR_BIT * sizeof(SI.BitVal)); + /* TODO: Generalize this so any type can be used. */ CHECK (SI.ValBits <= CHAR_BITS + INT_BITS - 2); while (SI.ValBits >= CHAR_BITS) { OutputBitFieldData (&SI); @@ -2425,7 +2482,8 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) } else { /* Standard member. We should never have stuff from a - ** bit-field left + ** bit-field left because an anonymous member was added + ** for padding by ParseStructDecl. */ CHECK (SI.ValBits == 0); diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index 452d9a9a3..f3a1a6add 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -123,7 +123,9 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) ** supported. */ Flags |= (EndBit <= CHAR_BITS) ? CF_CHAR : CF_INT; - Flags |= CF_UNSIGNED; + if (IsSignUnsigned (Expr->Type)) { + Flags |= CF_UNSIGNED; + } /* Flags we need operate on the whole bit-field, without CF_FORCECHAR. */ BitFieldFullWidthFlags = Flags; @@ -133,7 +135,11 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) ** type is not CF_CHAR. */ if (AdjustBitField) { - Flags |= CF_FORCECHAR; + /* If adjusting, then we're sign extending manually, so do everything unsigned + ** to make shifts faster. + */ + Flags |= CF_UNSIGNED | CF_FORCECHAR; + BitFieldFullWidthFlags |= CF_UNSIGNED; } } else if ((Flags & CF_TYPEMASK) == 0) { Flags |= TypeOf (Expr->Type); @@ -231,7 +237,8 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) if (ED_NeedsTest (Expr)) { g_testbitfield (Flags, Expr->BitOffs, Expr->BitWidth); } else { - g_extractbitfield (Flags, BitFieldFullWidthFlags, Expr->BitOffs, Expr->BitWidth); + g_extractbitfield (Flags, BitFieldFullWidthFlags, IsSignSigned (Expr->Type), + Expr->BitOffs, Expr->BitWidth); } } diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6e0654576..7e6a9f5bb 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -819,7 +819,8 @@ SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTabl -SymEntry* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsigned BitWidth) +SymEntry* AddBitField (const char* Name, const Type* T, unsigned Offs, + unsigned BitOffs, unsigned BitWidth, int SignednessSpecified) /* Add a bit field to the local symbol table and return the symbol entry */ { /* Do we have an entry with this name already? */ @@ -834,12 +835,21 @@ SymEntry* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsign /* Create a new entry */ Entry = NewSymEntry (Name, SC_BITFIELD); - /* Set the symbol attributes. Bit-fields are always of type unsigned */ - Entry->Type = type_uint; + /* Set the symbol attributes. Bit-fields are always integral types. */ + Entry->Type = TypeDup (T); Entry->V.B.Offs = Offs; Entry->V.B.BitOffs = BitOffs; Entry->V.B.BitWidth = BitWidth; + if (!SignednessSpecified) { + /* int is treated as signed int everywhere except bit-fields; switch it to unsigned, + ** since this is allowed for bit-fields and avoids sign-extension, so is much faster. + */ + CHECK ((Entry->Type->C & T_MASK_SIGN) == T_SIGN_SIGNED); + Entry->Type->C &= ~T_MASK_SIGN; + Entry->Type->C |= T_SIGN_UNSIGNED; + } + /* Add the entry to the symbol table */ AddSymEntry (SymTab, Entry); diff --git a/src/cc65/symtab.h b/src/cc65/symtab.h index f04517fed..750e41b54 100644 --- a/src/cc65/symtab.h +++ b/src/cc65/symtab.h @@ -155,7 +155,8 @@ SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTab SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTable* Tab); /* Add a struct/union entry and return it */ -SymEntry* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsigned BitWidth); +SymEntry* AddBitField (const char* Name, const Type* Type, unsigned Offs, + unsigned BitOffs, unsigned BitWidth, int SignednessSpecified); /* Add a bit field to the local symbol table and return the symbol entry */ SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val); diff --git a/test/todo/bug1095.c b/test/val/bug1095.c similarity index 74% rename from test/todo/bug1095.c rename to test/val/bug1095.c index 0803c2d1c..8c184cd1d 100644 --- a/test/todo/bug1095.c +++ b/test/val/bug1095.c @@ -31,7 +31,10 @@ static struct signed_ints { signed int b : 3; signed int c : 3; signed int d : 10; -} si = {-4, -1, 3, -500}; + signed int : 0; + signed int e : 8; + signed int f : 16; +} si = {-4, -1, 3, -500, -100, -5000}; static void test_signed_bitfield(void) { @@ -53,7 +56,7 @@ static void test_signed_bitfield(void) failures++; } - if (si.b <= 0) { + if (si.c <= 0) { printf("Got si.c = %d, expected positive.\n", si.c); failures++; } @@ -71,10 +74,30 @@ static void test_signed_bitfield(void) failures++; } + if (si.e >= 0) { + printf("Got si.e = %d, expected negative.\n", si.e); + failures++; + } + if (si.e != -100) { + printf("Got si.e = %d, expected -100.\n", si.e); + failures++; + } + + if (si.f >= 0) { + printf("Got si.f = %d, expected negative.\n", si.f); + failures++; + } + if (si.f != -5000) { + printf("Got si.f = %d, expected -5000.\n", si.f); + failures++; + } + si.a = -3; si.b = 1; si.c = -2; si.d = 500; + si.e = 100; + si.f = 5000; if (si.a >= 0) { printf("Got si.a = %d, expected negative.\n", si.a); @@ -94,7 +117,7 @@ static void test_signed_bitfield(void) failures++; } - if (si.b >= 0) { + if (si.c >= 0) { printf("Got si.c = %d, expected negative.\n", si.c); failures++; } @@ -111,6 +134,24 @@ static void test_signed_bitfield(void) printf("Got si.d = %d, expected 500.\n", si.d); failures++; } + + if (si.e <= 0) { + printf("Got si.e = %d, expected positive.\n", si.e); + failures++; + } + if (si.e != 100) { + printf("Got si.e = %d, expected 100.\n", si.e); + failures++; + } + + if (si.f <= 0) { + printf("Got si.f = %d, expected positive.\n", si.f); + failures++; + } + if (si.f != 5000) { + printf("Got si.f = %d, expected 5000.\n", si.f); + failures++; + } } int main(void) From ab89c168decdb959251c28314bd29f20943fba33 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 18 Aug 2020 17:47:35 +0200 Subject: [PATCH 1590/2161] replace "Copyright 2020 Google LLC" by "Copyright 2020 the cc65 authors" --- test/err/bitfield-named-zero-width.c | 2 +- test/err/bitfield-negative-width.c | 2 +- test/err/bitfield-too-wide.c | 2 +- test/err/bug1047.c | 2 +- test/err/staticassert.c | 2 +- test/val/bitfield.c | 2 +- test/val/bug1095.c | 2 +- test/val/plain-int-bitfield.c | 2 +- test/val/staticassert.c | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/err/bitfield-named-zero-width.c b/test/err/bitfield-named-zero-width.c index b9b9db88d..323c3d49c 100644 --- a/test/err/bitfield-named-zero-width.c +++ b/test/err/bitfield-named-zero-width.c @@ -1,5 +1,5 @@ /* - Copyright 2020 Google LLC + Copyright 2020 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 diff --git a/test/err/bitfield-negative-width.c b/test/err/bitfield-negative-width.c index dd83b3fc4..5b14ea7e3 100644 --- a/test/err/bitfield-negative-width.c +++ b/test/err/bitfield-negative-width.c @@ -1,5 +1,5 @@ /* - Copyright 2020 Google LLC + Copyright 2020 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 diff --git a/test/err/bitfield-too-wide.c b/test/err/bitfield-too-wide.c index 6c9c229fc..da7f69dc2 100644 --- a/test/err/bitfield-too-wide.c +++ b/test/err/bitfield-too-wide.c @@ -1,5 +1,5 @@ /* - Copyright 2020 Google LLC + Copyright 2020 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 diff --git a/test/err/bug1047.c b/test/err/bug1047.c index 3fb11250f..4020189e0 100644 --- a/test/err/bug1047.c +++ b/test/err/bug1047.c @@ -1,5 +1,5 @@ /* - Copyright 2020 Google LLC + Copyright 2020 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 diff --git a/test/err/staticassert.c b/test/err/staticassert.c index df9bab6d8..be991e744 100644 --- a/test/err/staticassert.c +++ b/test/err/staticassert.c @@ -1,5 +1,5 @@ /* - Copyright 2020 Google LLC + Copyright 2020 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 diff --git a/test/val/bitfield.c b/test/val/bitfield.c index 67747ed5b..cf96d8929 100644 --- a/test/val/bitfield.c +++ b/test/val/bitfield.c @@ -1,5 +1,5 @@ /* - Copyright 2020 Google LLC + Copyright 2020 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 diff --git a/test/val/bug1095.c b/test/val/bug1095.c index 8c184cd1d..6872d151c 100644 --- a/test/val/bug1095.c +++ b/test/val/bug1095.c @@ -1,5 +1,5 @@ /* - Copyright 2020 Google LLC + Copyright 2020 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 diff --git a/test/val/plain-int-bitfield.c b/test/val/plain-int-bitfield.c index afc7121bb..75e65590c 100644 --- a/test/val/plain-int-bitfield.c +++ b/test/val/plain-int-bitfield.c @@ -1,5 +1,5 @@ /* - Copyright 2020 Google LLC + Copyright 2020 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 diff --git a/test/val/staticassert.c b/test/val/staticassert.c index 5d44fed6b..a31a9e646 100644 --- a/test/val/staticassert.c +++ b/test/val/staticassert.c @@ -1,5 +1,5 @@ /* - Copyright 2020 Google LLC + Copyright 2020 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 From 0c22d5011e9d8d92d251072c9dc59009c773ac91 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 18 Aug 2020 17:58:29 +0200 Subject: [PATCH 1591/2161] added test related to pr #1190 --- test/err/staticassert-nomsg.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 test/err/staticassert-nomsg.c diff --git a/test/err/staticassert-nomsg.c b/test/err/staticassert-nomsg.c new file mode 100644 index 000000000..e0a1ede69 --- /dev/null +++ b/test/err/staticassert-nomsg.c @@ -0,0 +1,26 @@ +/* + Copyright 2020 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 failing _Static_assert. +**/ + + +_Static_assert(0 == 1); From 0690a12ad2fb998ad6e012ed6e9f391f0580b914 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 18 Aug 2020 22:41:42 +0200 Subject: [PATCH 1592/2161] change "the cc65 authors" to "The cc65 Authors" as per jmrs request --- test/err/bitfield-named-zero-width.c | 2 +- test/err/bitfield-negative-width.c | 2 +- test/err/bitfield-too-wide.c | 2 +- test/err/bug1047.c | 2 +- test/err/staticassert-nomsg.c | 2 +- test/err/staticassert.c | 2 +- test/val/bitfield.c | 2 +- test/val/bug1095.c | 2 +- test/val/plain-int-bitfield.c | 2 +- test/val/staticassert.c | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/err/bitfield-named-zero-width.c b/test/err/bitfield-named-zero-width.c index 323c3d49c..108b195d0 100644 --- a/test/err/bitfield-named-zero-width.c +++ b/test/err/bitfield-named-zero-width.c @@ -1,5 +1,5 @@ /* - Copyright 2020 the cc65 authors + Copyright 2020 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 diff --git a/test/err/bitfield-negative-width.c b/test/err/bitfield-negative-width.c index 5b14ea7e3..a90199f38 100644 --- a/test/err/bitfield-negative-width.c +++ b/test/err/bitfield-negative-width.c @@ -1,5 +1,5 @@ /* - Copyright 2020 the cc65 authors + Copyright 2020 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 diff --git a/test/err/bitfield-too-wide.c b/test/err/bitfield-too-wide.c index da7f69dc2..424cf9c05 100644 --- a/test/err/bitfield-too-wide.c +++ b/test/err/bitfield-too-wide.c @@ -1,5 +1,5 @@ /* - Copyright 2020 the cc65 authors + Copyright 2020 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 diff --git a/test/err/bug1047.c b/test/err/bug1047.c index 4020189e0..3f1d3cf63 100644 --- a/test/err/bug1047.c +++ b/test/err/bug1047.c @@ -1,5 +1,5 @@ /* - Copyright 2020 the cc65 authors + Copyright 2020 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 diff --git a/test/err/staticassert-nomsg.c b/test/err/staticassert-nomsg.c index e0a1ede69..8cdcb09a4 100644 --- a/test/err/staticassert-nomsg.c +++ b/test/err/staticassert-nomsg.c @@ -1,5 +1,5 @@ /* - Copyright 2020 the cc65 authors + Copyright 2020 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 diff --git a/test/err/staticassert.c b/test/err/staticassert.c index be991e744..60cb37529 100644 --- a/test/err/staticassert.c +++ b/test/err/staticassert.c @@ -1,5 +1,5 @@ /* - Copyright 2020 the cc65 authors + Copyright 2020 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 diff --git a/test/val/bitfield.c b/test/val/bitfield.c index cf96d8929..939d90dff 100644 --- a/test/val/bitfield.c +++ b/test/val/bitfield.c @@ -1,5 +1,5 @@ /* - Copyright 2020 the cc65 authors + Copyright 2020 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 diff --git a/test/val/bug1095.c b/test/val/bug1095.c index 6872d151c..cecbf0329 100644 --- a/test/val/bug1095.c +++ b/test/val/bug1095.c @@ -1,5 +1,5 @@ /* - Copyright 2020 the cc65 authors + Copyright 2020 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 diff --git a/test/val/plain-int-bitfield.c b/test/val/plain-int-bitfield.c index 75e65590c..4d158eca9 100644 --- a/test/val/plain-int-bitfield.c +++ b/test/val/plain-int-bitfield.c @@ -1,5 +1,5 @@ /* - Copyright 2020 the cc65 authors + Copyright 2020 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 diff --git a/test/val/staticassert.c b/test/val/staticassert.c index a31a9e646..e43eeec8d 100644 --- a/test/val/staticassert.c +++ b/test/val/staticassert.c @@ -1,5 +1,5 @@ /* - Copyright 2020 the cc65 authors + Copyright 2020 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 From 36dd82f0e61a2c288bf4dda16ef9a3a69bc6c044 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 18 Aug 2020 19:07:29 -0400 Subject: [PATCH 1593/2161] Added g_branch() to cc65's code generator. It uses BRA if the platform's CPU has BRA. Else, it generates a JMP. (Used it in the bitfield sign-extending code.) --- src/cc65/codegen.c | 34 +++++++++++++++++++++++++--------- src/cc65/codegen.h | 7 ++++++- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index a0dbc498b..6b6b292b0 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -2207,7 +2207,7 @@ void g_restore (unsigned flags) void g_cmp (unsigned flags, unsigned long val) -/* Immidiate compare. The primary register will not be changed, Z flag +/* Immediate compare. The primary register will not be changed, Z flag ** will be set. */ { @@ -2455,6 +2455,21 @@ void g_falsejump (unsigned flags attribute ((unused)), unsigned label) } + +void g_branch (unsigned Label) +/* Branch unconditionally to Label if the CPU has the BRA instruction. +** Otherwise, jump to Label. +*/ +{ + if ((CPUIsets[CPU] & CPU_ISET_65SC02) != 0) { + AddCodeLine ("bra %s", LocalLabelName (Label)); + } else { + g_jump (Label); + } +} + + + void g_lateadjustSP (unsigned label) /* Adjust stack based on non-immediate data */ { @@ -2761,12 +2776,14 @@ void g_div (unsigned flags, unsigned long val) AddCodeLine ("lsr a"); g_restore (flags); AddCodeLine ("bcs %s", LocalLabelName (DoShiftLabel)); - + /* The result is 0. We can just load 0 and skip the shifting. */ g_getimmed (flags | CF_ABSOLUTE, 0, 0); + + /* TODO: replace with BEQ? Would it be optimized? */ g_jump (EndLabel); - /* Do the shift. The sign of the result may need be corrected + /* Do the shift. The sign of the result may need to be corrected ** later. */ g_defcodelabel (DoShiftLabel); @@ -4511,18 +4528,17 @@ void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, int IsSigned, unsigned ZeroExtendLabel = GetLocalLabel (); AddCodeLine ("beq %s", LocalLabelName (ZeroExtendLabel)); - /* Pop A back and sign extend if required; operating on the full result need + /* Pop A back and sign-extend if required; operating on the full result needs ** to sign-extend into high byte, too. */ AddCodeLine ("pla"); g_or (FullWidthFlags | CF_CONST, ~Mask); - /* Apparently, there is no unconditional branch BRA, so use JMP. */ unsigned DoneLabel = GetLocalLabel (); - AddCodeLine ("jmp %s", LocalLabelName (DoneLabel)); + g_branch (DoneLabel); - /* Pop A back, then zero-extend; we need to duplicate the PLA rather than move it before - ** the branch to share with the other label because PLA sets the condition codes. + /* Pop A back, then zero-extend. We need to duplicate the PLA, rather than move it before + ** the branch to share with the other label, because PLA changes some condition codes. */ g_defcodelabel (ZeroExtendLabel); AddCodeLine ("pla"); @@ -4534,7 +4550,7 @@ void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, int IsSigned, g_defcodelabel (DoneLabel); } else { - /* Unsigned bit-field, only needs zero-extension. */ + /* Unsigned bit-field, needs only zero-extension. */ if (ZeroExtendMask != 0) { g_and (FullWidthFlags | CF_CONST, ZeroExtendMask); } diff --git a/src/cc65/codegen.h b/src/cc65/codegen.h index ec4756f2d..d946a9a10 100644 --- a/src/cc65/codegen.h +++ b/src/cc65/codegen.h @@ -380,7 +380,7 @@ void g_restore (unsigned flags); /* Copy hold register to primary. */ void g_cmp (unsigned flags, unsigned long val); -/* Immidiate compare. The primary register will not be changed, Z flag +/* Immediate compare. The primary register will not be changed, Z flag ** will be set. */ @@ -410,6 +410,11 @@ void g_truejump (unsigned flags, unsigned label); void g_falsejump (unsigned flags, unsigned label); /* Jump to label if zero flag set */ +void g_branch (unsigned Label); +/* Branch unconditionally to Label if the CPU has the BRA instruction. +** Otherwise, jump to Label. +*/ + void g_lateadjustSP (unsigned label); /* Adjust stack based on non-immediate data */ From 9fcde120aa1fca60c19f09210adf2557f8888502 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 18 Aug 2020 20:43:19 +0800 Subject: [PATCH 1594/2161] Made function signatures in asm output use the parameter lists from original definitions instead of the composites. --- src/cc65/datatype.c | 18 ++++++++++++++++-- src/cc65/datatype.h | 3 +++ src/cc65/funcdesc.c | 1 + src/cc65/funcdesc.h | 1 + src/cc65/function.c | 3 +++ 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index b95e37f87..ad008cfd3 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -596,8 +596,8 @@ void PrintFuncSig (FILE* F, const char* Name, Type* T) StrBuf East = AUTO_STRBUF_INITIALIZER; StrBuf West = AUTO_STRBUF_INITIALIZER; - /* Get the function descriptor */ - const FuncDesc* D = GetFuncDesc (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; @@ -1137,6 +1137,20 @@ Type* GetFuncReturn (Type* T) +FuncDesc* GetFuncDefinitionDesc (Type* T) +/* Get the function descriptor of the function definition */ +{ + FuncDesc* D; + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + D = GetFuncDesc (T); + return D->FuncDef != 0 ? D->FuncDef : D; +} + + + long GetElementCount (const Type* T) /* Get the element count of the array specified in T (which must be of ** array type). diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 472098788..8e9ee4c33 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -836,6 +836,9 @@ void SetFuncDesc (Type* T, FuncDesc* F); Type* GetFuncReturn (Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ +FuncDesc* GetFuncDefinitionDesc (struct Type* T); +/* Get the function descriptor of the function definition */ + long GetElementCount (const Type* T); /* Get the element count of the array specified in T (which must be of ** array type). diff --git a/src/cc65/funcdesc.c b/src/cc65/funcdesc.c index 273263dec..4c959fb6c 100644 --- a/src/cc65/funcdesc.c +++ b/src/cc65/funcdesc.c @@ -60,6 +60,7 @@ FuncDesc* NewFuncDesc (void) F->ParamCount = 0; F->ParamSize = 0; F->LastParam = 0; + F->FuncDef = 0; F->WrappedCall = 0; F->WrappedCallData = 0; diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h index a04ffb14a..1cfb2bd09 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -68,6 +68,7 @@ struct FuncDesc { unsigned ParamCount; /* Number of parameters */ 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 char WrappedCallData;/* The WrappedCall's user data */ }; diff --git a/src/cc65/function.c b/src/cc65/function.c index fc113b29a..290916cd2 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -382,6 +382,9 @@ void NewFunc (SymEntry* Func, FuncDesc* D) SymEntry* Param; const Type* RType; /* Real type used for struct parameters */ + /* Remember this function descriptor used for definition */ + GetFuncDesc (Func->Type)->FuncDef = D; + /* Allocate the function activation record for the function */ CurrentFunc = NewFunction (Func, D); From 85e8a6cb9fde50cfc54854fb8161fcb0af722d6c Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Wed, 19 Aug 2020 09:29:30 +0200 Subject: [PATCH 1595/2161] Clarify docs that bss is zero-initialized Addresses comment raised in #1202. --- doc/cc65.sgml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index a81358510..e7b8f260d 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1043,8 +1043,8 @@ parameter with the <tt/#pragma/. <sect1><tt>#pragma bss-name ([push,] <name>)</tt><label id="pragma-bss-name"><p> This pragma changes the name used for the BSS segment (the BSS segment - is used to store uninitialized data). The argument is a string enclosed - in double quotes. + is used to store variables with static storage duration and no explicit + initializer). The argument is a string enclosed in double quotes. Note: The default linker configuration file does only map the standard segments. If you use other segments, you have to create a new linker @@ -1052,7 +1052,8 @@ parameter with the <tt/#pragma/. Beware: The startup code will zero only the default BSS segment. If you use another BSS segment, you have to do that yourself, otherwise - uninitialized variables do not have the value zero. + variables with static storage duration and no explicit initializer will + not have the value zero. The <tt/#pragma/ understands the push and pop parameters as explained above. From 1a92368aedd6229e298c6d191f7faaaea17b5489 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 19 Aug 2020 14:50:12 +0200 Subject: [PATCH 1596/2161] rename bdiff.c to isequal.c, make it handle different line-endings as equal --- test/asm/Makefile | 4 ++-- test/bdiff.c | 28 ------------------------ test/dasm/Makefile | 4 ++-- test/isequal.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++ test/misc/Makefile | 4 ++-- test/ref/Makefile | 4 ++-- 6 files changed, 62 insertions(+), 36 deletions(-) delete mode 100644 test/bdiff.c create mode 100644 test/isequal.c diff --git a/test/asm/Makefile b/test/asm/Makefile index a0825574c..94a925376 100644 --- a/test/asm/Makefile +++ b/test/asm/Makefile @@ -24,7 +24,7 @@ CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) WORKDIR = ../../testwrk/asm -DIFF = $(WORKDIR)/bdiff$(EXE) +DIFF = $(WORKDIR)/isequal$(EXE) CC = gcc CFLAGS = -O2 @@ -44,7 +44,7 @@ all: $(OPCODE_BINS) $(CPUDETECT_BINS) $(WORKDIR): $(call MKDIR,$(WORKDIR)) -$(DIFF): ../bdiff.c | $(WORKDIR) +$(DIFF): ../isequal.c | $(WORKDIR) $(CC) $(CFLAGS) -o $@ $< define OPCODE_template diff --git a/test/bdiff.c b/test/bdiff.c deleted file mode 100644 index 797ba4302..000000000 --- a/test/bdiff.c +++ /dev/null @@ -1,28 +0,0 @@ - -// minimal tool to compare two binaries - -#include <stdlib.h> -#include <stdio.h> - -int main(int argc, char *argv[]) -{ - FILE *f1, *f2; - if (argc < 3) { - return EXIT_FAILURE; - } - f1 = fopen(argv[1], "rb"); - f2 = fopen(argv[2], "rb"); - if ((f1 == NULL) || (f2 == NULL)) { - return EXIT_FAILURE; - } - for(;;) { - if (feof(f1) && feof(f2)) { - return EXIT_SUCCESS; - } else if (feof(f1) || feof(f2)) { - return EXIT_FAILURE; - } - if (fgetc(f1) != fgetc(f2)) { - return EXIT_FAILURE; - } - } -} diff --git a/test/dasm/Makefile b/test/dasm/Makefile index d70711491..faa6b7fa0 100644 --- a/test/dasm/Makefile +++ b/test/dasm/Makefile @@ -25,7 +25,7 @@ DA65 := $(if $(wildcard ../../bin/da65*),../../bin/da65,da65) WORKDIR = ../../testwrk/dasm -DIFF = $(WORKDIR)/bdiff$(EXE) +DIFF = $(WORKDIR)/isequal$(EXE) CC = gcc CFLAGS = -O2 @@ -44,7 +44,7 @@ all: $(BINS) $(WORKDIR): $(call MKDIR,$(WORKDIR)) -$(DIFF): ../bdiff.c | $(WORKDIR) +$(DIFF): ../isequal.c | $(WORKDIR) $(CC) $(CFLAGS) -o $@ $< define DISASS_template diff --git a/test/isequal.c b/test/isequal.c new file mode 100644 index 000000000..b3806c7e4 --- /dev/null +++ b/test/isequal.c @@ -0,0 +1,54 @@ + +// minimal tool to compare two text files + +#include <stdlib.h> +#include <stdio.h> + +/* get the next character from FILE and convert commonly used line-endings all + into the same value (0x0a, as used on *nix systems) + + recognized values/pairs: + + 0x0a (LF) Linux, macOS + 0x0d, 0x0a (CR, LF) Windows, MSDOS, OS/2 + 0x0d (CR) classic MacOS +*/ + +int getnext(FILE *f) +{ + int c = fgetc(f); + if (c == 0x0d) { + if (!feof(f)) { + int n = fgetc(f); + if (n != 0x0a) { + ungetc(n, f); + } + clearerr(f); /* clears EOF when we did not push back */ + } + return 0x0a; + } + return c; +} + +int main(int argc, char *argv[]) +{ + FILE *f1, *f2; + if (argc < 3) { + return EXIT_FAILURE; + } + f1 = fopen(argv[1], "rb"); + f2 = fopen(argv[2], "rb"); + if ((f1 == NULL) || (f2 == NULL)) { + return EXIT_FAILURE; + } + for(;;) { + if (feof(f1) && feof(f2)) { + return EXIT_SUCCESS; + } else if (feof(f1) || feof(f2)) { + return EXIT_FAILURE; + } + if (getnext(f1) != getnext(f2)) { + return EXIT_FAILURE; + } + } +} diff --git a/test/misc/Makefile b/test/misc/Makefile index 1d98e2d62..55c19704e 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -37,7 +37,7 @@ WORKDIR = ..$S..$Stestwrk$Smisc OPTIONS = g O Os Osi Osir Osr Oi Oir Or -DIFF = $(WORKDIR)$Sbdiff$(EXE) +DIFF = $(WORKDIR)$Sisequal$(EXE) CC = gcc CFLAGS = -O2 @@ -58,7 +58,7 @@ all: $(TESTS) $(WORKDIR): $(call MKDIR,$(WORKDIR)) -$(DIFF): ../bdiff.c | $(WORKDIR) +$(DIFF): ../isequal.c | $(WORKDIR) $(CC) $(CFLAGS) -o $@ $< define PRG_template diff --git a/test/ref/Makefile b/test/ref/Makefile index a94f65dd8..f88821f64 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -35,7 +35,7 @@ WORKDIR = ..$S..$Stestwrk$Sref OPTIONS = g O Os Osi Osir Osr Oi Oir Or -DIFF = $(WORKDIR)$Sbdiff$(EXE) +DIFF = $(WORKDIR)$Sisequal$(EXE) CC = gcc CFLAGS = -O2 -Wall -W -Wextra -funsigned-char -fwrapv -fno-strict-overflow @@ -57,7 +57,7 @@ $(WORKDIR)/%.ref: %.c | $(WORKDIR) $(CC) $(CFLAGS) -o $(WORKDIR)/$*.host $< $(NULLERR) $(WORKDIR)$S$*.host > $@ -$(DIFF): ../bdiff.c | $(WORKDIR) +$(DIFF): ../isequal.c | $(WORKDIR) $(CC) $(CFLAGS) -o $@ $< # "yaccdbg.c" includes "yacc.c". From e6b8f4d71581883083d0bb34e67141ad0b2e53c5 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 19 Aug 2020 22:25:18 +0200 Subject: [PATCH 1597/2161] move/fix bug264.c as suggested in issue #1122 --- test/err/bug264.c | 62 +++++++++++++++++++++ test/{misc/bug264.c => val/return-struct.c} | 0 2 files changed, 62 insertions(+) create mode 100644 test/err/bug264.c rename test/{misc/bug264.c => val/return-struct.c} (100%) diff --git a/test/err/bug264.c b/test/err/bug264.c new file mode 100644 index 000000000..6898f3790 --- /dev/null +++ b/test/err/bug264.c @@ -0,0 +1,62 @@ +/* bug #264 - cc65 fails to warn about a function returning struct */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +typedef uint32_t u32; +typedef uint16_t u16; + +/* this struct is too large, we can only handle max 4 bytes right now */ +typedef struct { + u32 quot; + u32 rem; +} udiv_t; + +udiv_t div3(u32 in) { + + udiv_t u; + u32 q = 0; + + while (in >= 300) { + in -= 300; + q += 100; + } + + while (in >= 30) { + in -= 30; + q += 10; + } + + while (in >= 3) { + in -= 3; + ++q; + } + + u.quot = q; + u.rem = in; + + return u; /* error */ +} + +int res = 0; + +int main(void) { + + u32 i; + div_t d; + udiv_t u; + + for (i = 1024; i; i--) { + d = div((u16)i, 3); + u = div3(i); + + if (d.quot != u.quot || d.rem != u.rem) { + printf("Mismatch at %u/3, div %u %u, div3 %u %u\n", i, + d.quot, d.rem, u.quot, u.rem); + res++; + } + } + + return res; +} diff --git a/test/misc/bug264.c b/test/val/return-struct.c similarity index 100% rename from test/misc/bug264.c rename to test/val/return-struct.c From 794adcc512e8f80eda9de0e852a0443a9c08fc5d Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 19 Aug 2020 22:33:10 +0200 Subject: [PATCH 1598/2161] remove unneeded rule --- test/misc/Makefile | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/misc/Makefile b/test/misc/Makefile index 55c19704e..b21384b68 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -81,12 +81,6 @@ $(WORKDIR)/pptest2.$1.$2.prg: pptest2.c | $(WORKDIR) $(if $(QUIET),echo misc/pptest2.$1.$2.prg) $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) -# this should fail to compile, because cc65 does not support returning structs -$(WORKDIR)/bug264.$1.$2.prg: bug264.c | $(WORKDIR) - @echo "FIXME: " $$@ "compiles but should give an error." - $(if $(QUIET),echo misc/bug264.$1.$2.prg) - $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - # this should fail to compile, because there are errors in the code # instead, the compiler crashes $(WORKDIR)/bug1113.$1.$2.prg: bug1113.c | $(WORKDIR) From 17bbba7327f3dddbe555c44df964c6ce0f587f53 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 20 Aug 2020 07:52:03 +0800 Subject: [PATCH 1599/2161] Added integer boolean type string. No longer set the "expression tested" flag with constant results in comparison. --- src/cc65/datatype.c | 1 + src/cc65/datatype.h | 1 + src/cc65/expr.c | 10 +++++----- src/cc65/exprdesc.c | 14 ++++++++++++++ src/cc65/exprdesc.h | 3 +++ 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index ad008cfd3..f4f978a3c 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -66,6 +66,7 @@ Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 8e9ee4c33..5c3e71da5 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -196,6 +196,7 @@ extern Type type_int[]; extern Type type_uint[]; extern Type type_long[]; extern Type type_ulong[]; +extern Type type_bool[]; extern Type type_void[]; extern Type type_size_t[]; extern Type type_float[]; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 12a0c0b57..3d4a5eb1b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -2595,13 +2595,13 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* The result is an rvalue in the primary */ ED_FinalizeRValLoad (Expr); + + /* Condition codes are set */ + ED_TestDone (Expr); } - /* Result type is always int */ - Expr->Type = type_int; - -Done: /* Condition codes are set */ - ED_TestDone (Expr); + /* Result type is always boolean */ +Done: Expr->Type = type_bool; } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index 5ff848fb7..d0ee2789a 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -229,6 +229,20 @@ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value) +ExprDesc* ED_MakeConstBool (ExprDesc* Expr, long Value) +/* Replace Expr with a constant boolean expression with the given value */ +{ + Expr->Sym = 0; + Expr->Type = type_bool; + Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_HAVE_MARKS); + Expr->Name = 0; + Expr->IVal = Value; + Expr->FVal = FP_D_Make (0.0); + return Expr; +} + + + ExprDesc* ED_FinalizeRValLoad (ExprDesc* Expr) /* Finalize the result of LoadExpr to be an rvalue in the primary register */ { diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index 1541c2e4e..0a0f970a6 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -411,6 +411,9 @@ ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); /* Replace Expr with an constant integer with the given value */ +ExprDesc* ED_MakeConstBool (ExprDesc* Expr, long Value); +/* Replace Expr with a constant boolean expression with the given value */ + ExprDesc* ED_FinalizeRValLoad (ExprDesc* Expr); /* Finalize the result of LoadExpr to be an rvalue in the primary register */ From b15ab348ba51100933d1b0b726f88e61f3f44caa Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 26 Aug 2020 08:23:05 +0800 Subject: [PATCH 1600/2161] Moved bug250.c from test/misc as it is to be fixed. --- test/misc/Makefile | 6 ------ test/misc/bug250.c | 13 ------------- 2 files changed, 19 deletions(-) delete mode 100644 test/misc/bug250.c diff --git a/test/misc/Makefile b/test/misc/Makefile index b21384b68..e48d86e30 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -63,12 +63,6 @@ $(DIFF): ../isequal.c | $(WORKDIR) define PRG_template -# should compile, but gives an error -$(WORKDIR)/bug250.$1.$2.prg: bug250.c | $(WORKDIR) - @echo "FIXME: " $$@ "currently does not compile." - $(if $(QUIET),echo misc/bug250.$1.$2.prg) - $(NOT) $(CL65) -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." diff --git a/test/misc/bug250.c b/test/misc/bug250.c deleted file mode 100644 index 60f3c633d..000000000 --- a/test/misc/bug250.c +++ /dev/null @@ -1,13 +0,0 @@ -/* bug #250 - Array size compile-time optimization stops halfway */ - -#include <stdlib.h> - -#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b)) -unsigned char c[2*4]; -unsigned char b[2*LZO_MAX(8,sizeof(int))]; // this will not compile - -int main(void) -{ - /* FIXME: add some runtime check */ - return EXIT_SUCCESS; -} From 3ea3887c77d8a6bc0bc784b0fa5bc2917b988be4 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 20 Aug 2020 07:52:06 +0800 Subject: [PATCH 1601/2161] Fixed warnings on const comparison. Warnings on expressions with no effects. Fixed const ternary. Fixed ternary with struct/union types as the true/false-branch expressions. --- src/cc65/asmstmt.c | 8 ++ src/cc65/assignment.c | 1 + src/cc65/declare.c | 11 +- src/cc65/expr.c | 263 ++++++++++++++++++++++++++++------------ src/cc65/exprdesc.c | 27 ++++- src/cc65/exprdesc.h | 131 +++++++++++++++++--- src/cc65/goto.c | 2 + src/cc65/loadexpr.c | 6 +- src/cc65/locals.c | 15 ++- src/cc65/preproc.c | 1 + src/cc65/shiftexpr.c | 5 +- src/cc65/staticassert.c | 2 + src/cc65/stdfunc.c | 5 + src/cc65/stmt.c | 36 +++--- src/cc65/swstmt.c | 5 +- src/cc65/testexpr.c | 8 +- src/cc65/typeconv.c | 5 + 17 files changed, 399 insertions(+), 132 deletions(-) diff --git a/src/cc65/asmstmt.c b/src/cc65/asmstmt.c index ae4308522..20de6033e 100644 --- a/src/cc65/asmstmt.c +++ b/src/cc65/asmstmt.c @@ -132,6 +132,8 @@ static void ParseByteArg (StrBuf* T, unsigned Arg) ExprDesc Expr; char Buf [16]; + ED_Init (&Expr); + /* We expect an argument separated by a comma */ ConsumeComma (); @@ -166,6 +168,8 @@ static void ParseWordArg (StrBuf* T, unsigned Arg) ExprDesc Expr; char Buf [16]; + ED_Init (&Expr); + /* We expect an argument separated by a comma */ ConsumeComma (); @@ -200,6 +204,8 @@ static void ParseLongArg (StrBuf* T, unsigned Arg attribute ((unused))) ExprDesc Expr; char Buf [16]; + ED_Init (&Expr); + /* We expect an argument separated by a comma */ ConsumeComma (); @@ -309,6 +315,8 @@ static void ParseStrArg (StrBuf* T, unsigned Arg attribute ((unused))) ExprDesc Expr; char Buf [64]; + ED_Init (&Expr); + /* We expect an argument separated by a comma */ ConsumeComma (); diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index 6acab3fe8..71df0c4f2 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -139,6 +139,7 @@ void Assignment (ExprDesc* Expr) ExprDesc Expr2; Type* ltype = Expr->Type; + ED_Init (&Expr2); /* We must have an lvalue for an assignment */ if (ED_IsRVal (Expr)) { diff --git a/src/cc65/declare.c b/src/cc65/declare.c index ccd4e9004..7e5f24b24 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -591,6 +591,7 @@ static SymEntry* ParseEnumDecl (const char* Name) if (CurTok.Tok == TOK_ASSIGN) { ExprDesc Expr; + ED_Init (&Expr); NextToken (); ConstAbsIntExpr (hie1, &Expr); EnumVal = Expr.IVal; @@ -720,6 +721,7 @@ static int ParseFieldWidth (Declaration* Decl) */ { ExprDesc Expr; + ED_Init (&Expr); if (CurTok.Tok != TOK_COLON) { /* No bit-field declaration */ @@ -1818,6 +1820,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Read the size if it is given */ if (CurTok.Tok != TOK_RBRACK) { ExprDesc Expr; + ED_Init (&Expr); ConstAbsIntExpr (hie1, &Expr); if (Expr.IVal <= 0) { if (D->Ident[0] != '\0') { @@ -2184,6 +2187,7 @@ static unsigned ParseScalarInit (Type* T) /* Parse initializaton for scalar data types. Return the number of data bytes. */ { ExprDesc ED; + ED_Init (&ED); /* Parse initialization */ ParseScalarInitInternal (T, &ED); @@ -2205,6 +2209,8 @@ static unsigned ParsePointerInit (Type* T) /* Expression */ ExprDesc ED; + ED_Init (&ED); + ConstExpr (hie1, &ED); TypeConversion (&ED, T); @@ -2420,6 +2426,7 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) ** handling. */ ExprDesc ED; + ED_Init (&ED); unsigned Val; unsigned Shift; @@ -2541,7 +2548,6 @@ static unsigned ParseVoidInit (Type* T) ** Return the number of bytes initialized. */ { - ExprDesc Expr; unsigned Size; /* Opening brace */ @@ -2550,6 +2556,9 @@ static unsigned ParseVoidInit (Type* T) /* Allow an arbitrary list of values */ Size = 0; do { + ExprDesc Expr; + ED_Init (&Expr); + ConstExpr (hie1, &Expr); switch (GetUnderlyingTypeCode (&Expr.Type[0])) { diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 3d4a5eb1b..62136e122 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -311,13 +311,15 @@ void PushAddr (const ExprDesc* Expr) -static void WarnConstCompareResult (void) +static void WarnConstCompareResult (const ExprDesc* Expr) /* If the result of a comparison is constant, this is suspicious when not in ** preprocessor mode. */ { - if (!Preprocessing && IS_Get (&WarnConstComparison) != 0) { - Warning ("Result of comparison is constant"); + if (!Preprocessing && + !ED_NeedsConst (Expr) && + IS_Get (&WarnConstComparison) != 0) { + Warning ("Result of comparison is always %s", Expr->IVal != 0 ? "true" : "false"); } } @@ -387,6 +389,7 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) unsigned Flags; ExprDesc Expr; + ED_Init (&Expr); /* Count arguments */ ++PushedCount; @@ -727,23 +730,20 @@ static void Primary (ExprDesc* E) { SymEntry* Sym; - /* Initialize fields in the expression stucture */ - ED_Init (E); - /* Character and integer constants. */ if (CurTok.Tok == TOK_ICONST || CurTok.Tok == TOK_CCONST) { - E->IVal = CurTok.IVal; - E->Flags = E_LOC_NONE | E_RTYPE_RVAL; - E->Type = CurTok.Type; + E->IVal = CurTok.IVal; + E->Flags |= E_LOC_NONE | E_RTYPE_RVAL; + E->Type = CurTok.Type; NextToken (); return; } /* Floating point constant */ if (CurTok.Tok == TOK_FCONST) { - E->FVal = CurTok.FVal; - E->Flags = E_LOC_NONE | E_RTYPE_RVAL; - E->Type = CurTok.Type; + E->FVal = CurTok.FVal; + E->Flags |= E_LOC_NONE | E_RTYPE_RVAL; + E->Type = CurTok.Type; NextToken (); return; } @@ -777,6 +777,8 @@ static void Primary (ExprDesc* E) return; } + unsigned Flags = E->Flags & E_MASK_KEEP_MAKE; + switch (CurTok.Tok) { case TOK_BOOL_AND: @@ -812,8 +814,8 @@ static void Primary (ExprDesc* E) /* Cannot use type symbols */ Error ("Variable identifier expected"); /* Assume an int type to make E valid */ - E->Flags = E_LOC_STACK | E_RTYPE_LVAL; - E->Type = type_int; + E->Flags |= E_LOC_STACK | E_RTYPE_LVAL; + E->Type = type_int; return; } @@ -924,7 +926,7 @@ static void Primary (ExprDesc* E) case TOK_ASM: /* ASM statement */ AsmStatement (); - E->Flags = E_RTYPE_RVAL; + E->Flags = E_RTYPE_RVAL | E_EVAL_MAYBE_UNUSED; E->Type = type_void; break; @@ -985,6 +987,8 @@ static void Primary (ExprDesc* E) ED_MakeConstAbsInt (E, 1); break; } + + E->Flags |= Flags; } @@ -1000,6 +1004,8 @@ static void ArrayRef (ExprDesc* Expr) Type* ElementType; Type* tptr1; + ED_Init (&Subscript); + Subscript.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; /* Skip the bracket */ NextToken (); @@ -2029,7 +2035,6 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */ int* UsedGen) /* Helper function */ { - ExprDesc Expr2; CodeMark Mark1; CodeMark Mark2; const GenDesc* Gen; @@ -2044,6 +2049,10 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */ *UsedGen = 0; while ((Gen = FindGen (CurTok.Tok, Ops)) != 0) { + ExprDesc Expr2; + ED_Init (&Expr2); + Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; + /* Tell the caller that we handled it's ops */ *UsedGen = 1; @@ -2248,7 +2257,6 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ void (*hienext) (ExprDesc*)) /* Helper function for the compare operators */ { - ExprDesc Expr2; CodeMark Mark0; CodeMark Mark1; CodeMark Mark2; @@ -2263,6 +2271,10 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ while ((Gen = FindGen (CurTok.Tok, Ops)) != 0) { + ExprDesc Expr2; + ED_Init (&Expr2); + Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; + /* Remember the generator function */ void (*GenFunc) (unsigned, unsigned long) = Gen->Func; @@ -2362,11 +2374,6 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* Check for const operands */ if (ED_IsConstAbs (Expr) && rconst) { - /* If the result is constant, this is suspicious when not in - ** preprocessor mode. - */ - WarnConstCompareResult (); - /* Both operands are constant, remove the generated code */ RemoveCode (&Mark1); @@ -2403,6 +2410,11 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ } } + /* If the result is constant, this is suspicious when not in + ** preprocessor mode. + */ + WarnConstCompareResult (Expr); + } else { /* Determine the signedness of the operands */ @@ -2461,7 +2473,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ case TOK_EQ: if (Expr2.IVal < LeftMin || Expr2.IVal > LeftMax) { ED_MakeConstAbsInt (Expr, 0); - WarnConstCompareResult (); + WarnConstCompareResult (Expr); goto Done; } break; @@ -2469,7 +2481,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ case TOK_NE: if (Expr2.IVal < LeftMin || Expr2.IVal > LeftMax) { ED_MakeConstAbsInt (Expr, 1); - WarnConstCompareResult (); + WarnConstCompareResult (Expr); goto Done; } break; @@ -2477,7 +2489,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ case TOK_LT: if (Expr2.IVal <= LeftMin || Expr2.IVal > LeftMax) { ED_MakeConstAbsInt (Expr, Expr2.IVal > LeftMax); - WarnConstCompareResult (); + WarnConstCompareResult (Expr); goto Done; } break; @@ -2485,7 +2497,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ case TOK_LE: if (Expr2.IVal < LeftMin || Expr2.IVal >= LeftMax) { ED_MakeConstAbsInt (Expr, Expr2.IVal >= LeftMax); - WarnConstCompareResult (); + WarnConstCompareResult (Expr); goto Done; } break; @@ -2493,7 +2505,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ case TOK_GE: if (Expr2.IVal <= LeftMin || Expr2.IVal > LeftMax) { ED_MakeConstAbsInt (Expr, Expr2.IVal <= LeftMin); - WarnConstCompareResult (); + WarnConstCompareResult (Expr); goto Done; } break; @@ -2501,7 +2513,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ case TOK_GT: if (Expr2.IVal < LeftMin || Expr2.IVal >= LeftMax) { ED_MakeConstAbsInt (Expr, Expr2.IVal < LeftMin); - WarnConstCompareResult (); + WarnConstCompareResult (Expr); goto Done; } break; @@ -2635,6 +2647,9 @@ static void parseadd (ExprDesc* Expr) Type* lhst; /* Type of left hand side */ Type* rhst; /* Type of right hand side */ + ED_Init (&Expr2); + Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; + /* Skip the PLUS token */ NextToken (); @@ -2869,6 +2884,8 @@ static void parsesub (ExprDesc* Expr) CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for the result */ + ED_Init (&Expr2); + Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; /* lhs cannot be function or pointer to function */ if (IsTypeFunc (Expr->Type) || IsTypeFuncPtr (Expr->Type)) { @@ -3130,11 +3147,12 @@ static void hieAndPP (ExprDesc* Expr) ** called recursively from the preprocessor. */ { - ExprDesc Expr2; - ConstAbsIntExpr (hie2, Expr); while (CurTok.Tok == TOK_BOOL_AND) { + ExprDesc Expr2; + ED_Init (&Expr2); + /* Skip the && */ NextToken (); @@ -3153,11 +3171,12 @@ static void hieOrPP (ExprDesc *Expr) ** called recursively from the preprocessor. */ { - ExprDesc Expr2; - ConstAbsIntExpr (hieAndPP, Expr); while (CurTok.Tok == TOK_BOOL_OR) { + ExprDesc Expr2; + ED_Init (&Expr2); + /* Skip the && */ NextToken (); @@ -3175,8 +3194,6 @@ static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp) /* Process "exp && exp" */ { int FalseLab; - ExprDesc Expr2; - ExprWithCheck (hie2, Expr); if (CurTok.Tok == TOK_BOOL_AND) { @@ -3186,10 +3203,8 @@ static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp) /* Get a label that we will use for false expressions */ FalseLab = GetLocalLabel (); - /* If the expr hasn't set condition codes, set the force-test flag */ - if (!ED_IsTested (Expr)) { - ED_MarkForTest (Expr); - } + /* Set the test flag */ + ED_RequireTest (Expr); /* Load the value */ LoadExpr (CF_FORCECHAR, Expr); @@ -3200,14 +3215,15 @@ static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp) /* Parse more boolean and's */ while (CurTok.Tok == TOK_BOOL_AND) { + ExprDesc Expr2; + ED_Init (&Expr2); + /* Skip the && */ NextToken (); /* Get rhs */ hie2 (&Expr2); - if (!ED_IsTested (&Expr2)) { - ED_MarkForTest (&Expr2); - } + ED_RequireTest (&Expr2); LoadExpr (CF_FORCECHAR, &Expr2); /* Do short circuit evaluation */ @@ -3233,7 +3249,6 @@ static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp) static void hieOr (ExprDesc *Expr) /* Process "exp || exp". */ { - ExprDesc Expr2; int BoolOp = 0; /* Did we have a boolean op? */ int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ @@ -3248,10 +3263,8 @@ static void hieOr (ExprDesc *Expr) /* Any boolean or's? */ if (CurTok.Tok == TOK_BOOL_OR) { - /* If the expr hasn't set condition codes, set the force-test flag */ - if (!ED_IsTested (Expr)) { - ED_MarkForTest (Expr); - } + /* Set the test flag */ + ED_RequireTest (Expr); /* Get first expr */ LoadExpr (CF_FORCECHAR, Expr); @@ -3269,15 +3282,16 @@ static void hieOr (ExprDesc *Expr) /* while there's more expr */ while (CurTok.Tok == TOK_BOOL_OR) { + ExprDesc Expr2; + ED_Init (&Expr2); + /* skip the || */ NextToken (); /* Get a subexpr */ AndOp = 0; hieAnd (&Expr2, TrueLab, &AndOp); - if (!ED_IsTested (&Expr2)) { - ED_MarkForTest (&Expr2); - } + ED_RequireTest (&Expr2); LoadExpr (CF_FORCECHAR, &Expr2); /* If there is more to come, add shortcut boolean eval. */ @@ -3308,6 +3322,7 @@ static void hieQuest (ExprDesc* Expr) { int FalseLab; int TrueLab; + CodeMark SkippedBranch; CodeMark TrueCodeEnd; ExprDesc Expr2; /* Expression 2 */ ExprDesc Expr3; /* Expression 3 */ @@ -3315,6 +3330,10 @@ static void hieQuest (ExprDesc* Expr) int Expr3IsNULL; /* Expression 3 is a NULL pointer */ Type* ResultType; /* Type of result */ + ED_Init (&Expr2); + Expr2.Flags = Expr->Flags & E_MASK_KEEP_RESULT; + ED_Init (&Expr3); + Expr3.Flags = Expr->Flags & E_MASK_KEEP_RESULT; /* Call the lower level eval routine */ if (Preprocessing) { @@ -3325,14 +3344,20 @@ static void hieQuest (ExprDesc* Expr) /* Check if it's a ternary expression */ if (CurTok.Tok == TOK_QUEST) { + + int ConstantCond = ED_IsConstAbsInt (Expr); NextToken (); - if (!ED_IsTested (Expr)) { + + if (!ConstantCond) { /* Condition codes not set, request a test */ - ED_MarkForTest (Expr); + ED_RequireTest (Expr); + LoadExpr (CF_NONE, Expr); + FalseLab = GetLocalLabel (); + g_falsejump (CF_NONE, FalseLab); + } else if (Expr->IVal == 0) { + /* Remember the current code position */ + GetCodePos (&SkippedBranch); } - LoadExpr (CF_NONE, Expr); - FalseLab = GetLocalLabel (); - g_falsejump (CF_NONE, FalseLab); /* Parse second expression. Remember for later if it is a NULL pointer ** expression, then load it into the primary. @@ -3340,22 +3365,37 @@ static void hieQuest (ExprDesc* Expr) ExprWithCheck (hie1, &Expr2); Expr2IsNULL = ED_IsNullPtr (&Expr2); if (!IsTypeVoid (Expr2.Type)) { - /* Load it into the primary */ - LoadExpr (CF_NONE, &Expr2); - ED_FinalizeRValLoad (&Expr2); + if (!ConstantCond || !ED_IsConst (&Expr2)) { + /* Load it into the primary */ + LoadExpr (CF_NONE, &Expr2); + ED_FinalizeRValLoad (&Expr2); + } Expr2.Type = PtrConversion (Expr2.Type); } - /* Remember the current code position */ - GetCodePos (&TrueCodeEnd); + if (!ConstantCond) { + /* Remember the current code position */ + GetCodePos (&TrueCodeEnd); - /* Jump around the evaluation of the third expression */ - TrueLab = GetLocalLabel (); - ConsumeColon (); - g_jump (TrueLab); + /* Jump around the evaluation of the third expression */ + TrueLab = GetLocalLabel (); - /* Jump here if the first expression was false */ - g_defcodelabel (FalseLab); + ConsumeColon (); + + g_jump (TrueLab); + + /* Jump here if the first expression was false */ + g_defcodelabel (FalseLab); + } else { + if (Expr->IVal == 0) { + /* Remove the load code of Expr2 */ + RemoveCode (&SkippedBranch); + } else { + /* Remember the current code position */ + GetCodePos (&SkippedBranch); + } + ConsumeColon(); + } /* Parse third expression. Remember for later if it is a NULL pointer ** expression, then load it into the primary. @@ -3363,12 +3403,19 @@ static void hieQuest (ExprDesc* Expr) ExprWithCheck (hie1, &Expr3); Expr3IsNULL = ED_IsNullPtr (&Expr3); if (!IsTypeVoid (Expr3.Type)) { - /* Load it into the primary */ - LoadExpr (CF_NONE, &Expr3); - ED_FinalizeRValLoad (&Expr3); + if (!ConstantCond || !ED_IsConst (&Expr3)) { + /* Load it into the primary */ + LoadExpr (CF_NONE, &Expr3); + ED_FinalizeRValLoad (&Expr3); + } Expr3.Type = PtrConversion (Expr3.Type); } + if (ConstantCond && Expr->IVal != 0) { + /* Remove the load code of Expr3 */ + RemoveCode (&SkippedBranch); + } + /* Check if any conversions are needed, if so, do them. ** Conversion rules for ?: expression are: ** - if both expressions are int expressions, default promotion @@ -3401,9 +3448,11 @@ static void hieQuest (ExprDesc* Expr) TypeConversion (&Expr2, ResultType); GetCodePos (&CvtCodeEnd); - /* If we had conversion code, move it to the right place */ - if (!CodeRangeIsEmpty (&CvtCodeStart, &CvtCodeEnd)) { - MoveCode (&CvtCodeStart, &CvtCodeEnd, &TrueCodeEnd); + if (!ConstantCond) { + /* If we had conversion code, move it to the right place */ + if (!CodeRangeIsEmpty (&CvtCodeStart, &CvtCodeEnd)) { + MoveCode (&CvtCodeStart, &CvtCodeEnd, &TrueCodeEnd); + } } } else if (IsClassPtr (Expr2.Type) && IsClassPtr (Expr3.Type)) { @@ -3423,16 +3472,30 @@ static void hieQuest (ExprDesc* Expr) /* Result type is void */ ResultType = Expr3.Type; } else { - TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, - "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && + TypeCmp (Expr2.Type, Expr3.Type) == TC_IDENTICAL) { + /* Result type is struct/union */ + ResultType = Expr2.Type; + } else { + TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, + "Incompatible types in ternary '%s' with '%s'"); + ResultType = Expr2.Type; /* Doesn't matter here */ + } } - /* Define the final label */ - g_defcodelabel (TrueLab); + if (!ConstantCond) { + /* Define the final label */ + g_defcodelabel (TrueLab); + ED_FinalizeRValLoad (Expr); + } else { + if (Expr->IVal != 0) { + *Expr = Expr2; + } else { + *Expr = Expr3; + } + } /* Setup the target expression */ - ED_FinalizeRValLoad (Expr); Expr->Type = ResultType; } } @@ -3442,7 +3505,6 @@ static void hieQuest (ExprDesc* Expr) static void opeq (const GenDesc* Gen, ExprDesc* Expr, const char* Op) /* Process "op=" operators. */ { - ExprDesc Expr2; unsigned flags; CodeMark Mark; int MustScale; @@ -3483,6 +3545,10 @@ static void opeq (const GenDesc* Gen, ExprDesc* Expr, const char* Op) GetCodePos (&Mark); g_push (flags, 0); + ExprDesc Expr2; + ED_Init (&Expr2); + Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; + /* Evaluate the rhs */ MarkedExprWithCheck (hie1, &Expr2); @@ -3563,6 +3629,8 @@ static void addsubeq (const GenDesc* Gen, ExprDesc *Expr, const char* Op) unsigned rflags; int MustScale; + ED_Init (&Expr2); + Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; /* We're currently only able to handle some addressing modes */ if (ED_GetLoc (Expr) == E_LOC_EXPR || ED_GetLoc (Expr) == E_LOC_PRIMARY) { @@ -3756,8 +3824,33 @@ void hie1 (ExprDesc* Expr) void hie0 (ExprDesc *Expr) /* Parse comma operator. */ { + unsigned Flags = Expr->Flags & E_MASK_KEEP_MAKE; + unsigned PrevErrorCount = ErrorCount; + CodeMark Start, End; + + /* Remember the current code position */ + GetCodePos (&Start); + hie1 (Expr); while (CurTok.Tok == TOK_COMMA) { + /* If the expression didn't generate code or isn't cast to type void, + ** emit a warning. + */ + GetCodePos (&End); + if (!ED_MayHaveNoEffect (Expr) && + CodeRangeIsEmpty (&Start, &End) && + IS_Get (&WarnNoEffect) && + PrevErrorCount == ErrorCount) { + Warning ("Expression result unused"); + } + + PrevErrorCount = ErrorCount; + /* Remember the current code position */ + GetCodePos (&Start); + + /* Reset the expression */ + ED_Init (Expr); + Expr->Flags = Flags; NextToken (); hie1 (Expr); } @@ -3791,8 +3884,18 @@ int evalexpr (unsigned Flags, void (*Func) (ExprDesc*), ExprDesc* Expr) void Expression0 (ExprDesc* Expr) /* Evaluate an expression via hie0 and put the result into the primary register */ { + unsigned Flags = Expr->Flags & E_MASK_KEEP_RESULT; + + /* Only check further after the expression is evaluated */ ExprWithCheck (hie0, Expr); - LoadExpr (CF_NONE, Expr); + + if ((Expr->Flags & Flags & E_MASK_EVAL) != (Flags & E_MASK_EVAL)) { + Internal ("Expression flags tampered: %08X", Flags); + } + + if (ED_YetToLoad (Expr)) { + LoadExpr (CF_NONE, Expr); + } } @@ -3804,6 +3907,7 @@ void ConstExpr (void (*Func) (ExprDesc*), ExprDesc* Expr) ** result from this input error. */ { + Expr->Flags |= E_EVAL_CONST; ExprWithCheck (Func, Expr); if (!ED_IsConst (Expr)) { Error ("Constant expression expected"); @@ -3838,6 +3942,7 @@ void ConstAbsIntExpr (void (*Func) (ExprDesc*), ExprDesc* Expr) ** errors that result from this input error. */ { + Expr->Flags |= E_EVAL_CONST; ExprWithCheck (Func, Expr); if (!ED_IsConstAbsInt (Expr)) { Error ("Constant integer expression expected"); diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d0ee2789a..c3f4c63f7 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -58,7 +58,7 @@ ExprDesc* ED_Init (ExprDesc* Expr) { Expr->Sym = 0; Expr->Type = 0; - Expr->Flags = 0; + Expr->Flags = E_NEED_EAX; Expr->Name = 0; Expr->IVal = 0; Expr->FVal = FP_D_Make (0.0); @@ -113,6 +113,24 @@ int ED_IsIndExpr (const ExprDesc* Expr) +int ED_YetToLoad (const ExprDesc* Expr) +/* Check if the expression needs to be loaded somehow. */ +{ + return ED_NeedsPrimary (Expr) || + ED_YetToTest (Expr) || + (ED_IsLVal (Expr) && IsQualVolatile (Expr->Type)); +} + + + +void ED_MarkForUneval (ExprDesc* Expr) +/* Mark the expression as not to be evaluated */ +{ + Expr->Flags = (Expr->Flags & ~E_MASK_EVAL) | E_EVAL_UNEVAL; +} + + + void ED_SetCodeRange (ExprDesc* Expr, const CodeMark* Start, const CodeMark* End) /* Set the code range for this expression */ { @@ -206,7 +224,7 @@ ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) { Expr->Sym = 0; Expr->Type = Type; - Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_HAVE_MARKS); + Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_MASK_KEEP_MAKE); Expr->Name = 0; Expr->IVal = Value; Expr->FVal = FP_D_Make (0.0); @@ -220,7 +238,7 @@ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value) { Expr->Sym = 0; Expr->Type = type_int; - Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_HAVE_MARKS); + Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_MASK_KEEP_MAKE); Expr->Name = 0; Expr->IVal = Value; Expr->FVal = FP_D_Make (0.0); @@ -412,7 +430,8 @@ int ED_IsBool (const ExprDesc* Expr) /* Either ints, floats, or pointers can be used in a boolean context */ return IsClassInt (Expr->Type) || IsClassFloat (Expr->Type) || - IsClassPtr (Expr->Type); + IsClassPtr (Expr->Type) || + IsClassFunc (Expr->Type); } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index 0a0f970a6..68db8b2fe 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -94,7 +94,7 @@ enum { ** E_LOC_<else> -- dereference -> E_LOC_EXPR (pointed-to-value, must load) ** + E_ADDRESS_OF -- dereference -> (lvalue reference) */ - E_MASK_LOC = 0x00FF, + E_MASK_LOC = 0x01FF, E_LOC_NONE = 0x0000, /* Pure rvalue with no storage */ E_LOC_ABS = 0x0001, /* Absolute numeric addressed variable */ E_LOC_GLOBAL = 0x0002, /* Global variable */ @@ -104,29 +104,58 @@ enum { E_LOC_PRIMARY = 0x0020, /* Temporary in primary register */ E_LOC_EXPR = 0x0040, /* A location that the primary register points to */ E_LOC_LITERAL = 0x0080, /* Literal in the literal pool */ + E_LOC_CODE = 0x0100, /* C code label location (&&Label) */ - /* Constant location of some sort (only if rval) */ + /* Immutable location addresses (immutable bases and offsets) */ E_LOC_CONST = E_LOC_NONE | E_LOC_ABS | E_LOC_GLOBAL | E_LOC_STATIC | - E_LOC_REGISTER | E_LOC_LITERAL, + E_LOC_REGISTER | E_LOC_LITERAL | E_LOC_CODE, + + /* Not-so-immutable location addresses (stack offsets can change) */ + E_LOC_QUASICONST = E_LOC_CONST | E_LOC_STACK, + + /* Expression type modifiers */ + E_BITFIELD = 0x0200, /* Expression is a bit-field */ + E_ADDRESS_OF = 0x0400, /* Expression is the address of the lvalue */ /* lvalue/rvalue in C language's sense */ - E_MASK_RTYPE = 0x0100, + E_MASK_RTYPE = 0x0800, E_RTYPE_RVAL = 0x0000, - E_RTYPE_LVAL = 0x0100, + E_RTYPE_LVAL = 0x0800, - /* Bit-field? */ - E_BITFIELD = 0x0200, + /* Expression status */ + E_LOADED = 0x1000, /* Expression is loaded in primary */ + E_CC_SET = 0x2000, /* Condition codes are set */ + E_HAVE_MARKS = 0x4000, /* Code marks are valid */ - /* Test */ - E_NEED_TEST = 0x0400, /* Expression needs a test to set cc */ - E_CC_SET = 0x0800, /* Condition codes are set */ + /* Optimization hints */ + E_MASK_NEED = 0x030000, + E_NEED_EAX = 0x000000, /* Expression needs to be loaded in Primary */ + E_NEED_NONE = 0x010000, /* Expression value is unused */ + E_NEED_TEST = 0x020000, /* Expression needs a test to set cc */ - E_HAVE_MARKS = 0x1000, /* Code marks are valid */ + /* Expression evaluation requirements. + ** Usage: (Flags & E_EVAL_<Flag>) == E_EVAL_<Flag> + */ + E_MASK_EVAL = 0xFC0000, + E_EVAL_NONE = 0x000000, /* No requirements */ + E_EVAL_CONST = 0x040000, /* Result must be immutable */ + E_EVAL_COMPILE_TIME = 0x0C0000, /* Result must be known at compile time */ + E_EVAL_PURE = 0x100000, /* Evaluation must have no side effects */ + E_EVAL_STATIC = 0x340000, /* Evaluation must generate no code */ + E_EVAL_MAYBE_UNUSED = 0x400000, /* Result may be unused */ + E_EVAL_UNEVAL = 0xC00000, /* Expression is unevaluated */ - E_LOADED = 0x4000, /* Expression is loaded in primary */ + /* Expression must be static and have result known at compile time */ + E_EVAL_C_CONST = E_EVAL_COMPILE_TIME | E_EVAL_STATIC, - E_ADDRESS_OF = 0x8000, /* Expression is the address of the lvalue */ + /* Flags to keep in subexpressions */ + E_MASK_KEEP_SUBEXPR = E_MASK_EVAL, + /* Flags to keep in ternary subexpressions */ + E_MASK_KEEP_RESULT = E_MASK_NEED | E_MASK_EVAL, + + /* Flags to keep when using the ED_Make functions */ + E_MASK_KEEP_MAKE = E_HAVE_MARKS | E_MASK_KEEP_RESULT, }; /* Forward */ @@ -292,13 +321,33 @@ void ED_MakeBitField (ExprDesc* Expr, unsigned BitOffs, unsigned BitWidth); /* Make this expression a bit field expression */ #if defined(HAVE_INLINE) -INLINE void ED_MarkForTest (ExprDesc* Expr) +INLINE void ED_RequireTest (ExprDesc* Expr) /* Mark the expression for a test. */ { Expr->Flags |= E_NEED_TEST; } #else -# define ED_MarkForTest(Expr) do { (Expr)->Flags |= E_NEED_TEST; } while (0) +# define ED_RequireTest(Expr) do { (Expr)->Flags |= E_NEED_TEST; } while (0) +#endif + +#if defined(HAVE_INLINE) +INLINE int ED_GetNeeds (const ExprDesc* Expr) +/* Get flags about what the expression needs. */ +{ + return (Expr->Flags & E_MASK_NEED); +} +#else +# define ED_GetNeeds(Expr) ((Expr)->Flags & E_MASK_NEED) +#endif + +#if defined(HAVE_INLINE) +INLINE int ED_NeedsPrimary (const ExprDesc* Expr) +/* Check if the expression needs to be in Primary. */ +{ + return (Expr->Flags & E_MASK_NEED) == E_NEED_EAX; +} +#else +# define ED_NeedsPrimary(Expr) (((Expr)->Flags & E_MASK_NEED) == E_NEED_EAX) #endif #if defined(HAVE_INLINE) @@ -311,15 +360,25 @@ INLINE int ED_NeedsTest (const ExprDesc* Expr) # define ED_NeedsTest(Expr) (((Expr)->Flags & E_NEED_TEST) != 0) #endif +#if defined(HAVE_INLINE) +INLINE int ED_YetToTest (const ExprDesc* Expr) +/* Check if the expression needs to be tested but not yet. */ +{ + return ((Expr)->Flags & (E_NEED_TEST | E_CC_SET)) == E_NEED_TEST; +} +#else +# define ED_YetToTest(Expr) (((Expr)->Flags & (E_NEED_TEST | E_CC_SET)) == E_NEED_TEST) +#endif + #if defined(HAVE_INLINE) INLINE void ED_TestDone (ExprDesc* Expr) /* Mark the expression as tested and condition codes set. */ { - Expr->Flags = (Expr->Flags & ~E_NEED_TEST) | E_CC_SET; + Expr->Flags |= E_CC_SET; } #else # define ED_TestDone(Expr) \ - do { (Expr)->Flags = ((Expr)->Flags & ~E_NEED_TEST) | E_CC_SET; } while (0) + do { (Expr)->Flags |= E_CC_SET; } while (0) #endif #if defined(HAVE_INLINE) @@ -354,6 +413,42 @@ INLINE int ED_IsLoaded (const ExprDesc* Expr) # define ED_IsLoaded(Expr) (((Expr)->Flags & E_LOADED) != 0) #endif +int ED_YetToLoad (const ExprDesc* Expr); +/* Check if the expression is yet to be loaded somehow. */ + +#if defined(HAVE_INLINE) +INLINE int ED_NeedsConst (const ExprDesc* Expr) +/* Check if the expression need be immutable */ +{ + return (Expr->Flags & E_EVAL_CONST) == E_EVAL_CONST; +} +#else +# define ED_NeedsConst(Expr) (((Expr)->Flags & E_EVAL_CONST) == E_EVAL_CONST) +#endif + +void ED_MarkForUneval (ExprDesc* Expr); +/* Mark the expression as not to be evaluated */ + +#if defined(HAVE_INLINE) +INLINE int ED_MayBeUneval (const ExprDesc* Expr) +/* Check if the expression may be uevaluated */ +{ + return (Expr->Flags & E_EVAL_UNEVAL) == E_EVAL_UNEVAL; +} +#else +# define ED_MayBeUneval(Expr) (((Expr)->Flags & E_EVAL_UNEVAL) == E_EVAL_UNEVAL) +#endif + +#if defined(HAVE_INLINE) +INLINE int ED_MayHaveNoEffect (const ExprDesc* Expr) +/* Check if the expression may be present without effects */ +{ + return (Expr->Flags & E_EVAL_MAYBE_UNUSED) == E_EVAL_MAYBE_UNUSED; +} +#else +# define ED_MayHaveNoEffect(Expr) (((Expr)->Flags & E_EVAL_MAYBE_UNUSED) == E_EVAL_MAYBE_UNUSED) +#endif + #if defined(HAVE_INLINE) INLINE int ED_IsLocPrimaryOrExpr (const ExprDesc* Expr) /* Return true if the expression is E_LOC_PRIMARY or E_LOC_EXPR */ @@ -522,7 +617,7 @@ int ED_IsNullPtr (const ExprDesc* Expr); int ED_IsBool (const ExprDesc* Expr); /* Return true of the expression can be treated as a boolean, that is, it can -** be an operand to a compare operation. +** be an operand to a compare operation with 0/NULL. */ void PrintExprDesc (FILE* F, ExprDesc* Expr); diff --git a/src/cc65/goto.c b/src/cc65/goto.c index f1fb725d2..06364068f 100644 --- a/src/cc65/goto.c +++ b/src/cc65/goto.c @@ -80,6 +80,8 @@ void GotoStatement (void) CodeEntry *E; unsigned char val; + ED_Init (&desc); + NextToken (); /* arr[foo], we only support simple foo for now */ diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index f3a1a6add..5c5434393 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -145,7 +145,7 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) Flags |= TypeOf (Expr->Type); } - if (ED_NeedsTest (Expr)) { + if (ED_YetToTest (Expr)) { /* If we're only testing, we do not need to promote char to int. ** CF_FORCECHAR does nothing if the type is not CF_CHAR. */ @@ -234,7 +234,7 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) */ CHECK (Expr->BitOffs < CHAR_BITS); - if (ED_NeedsTest (Expr)) { + if (ED_YetToTest (Expr)) { g_testbitfield (Flags, Expr->BitOffs, Expr->BitWidth); } else { g_extractbitfield (Flags, BitFieldFullWidthFlags, IsSignSigned (Expr->Type), @@ -252,7 +252,7 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) LoadAddress (Flags, Expr); /* Are we testing this value? */ - if (ED_NeedsTest (Expr)) { + if (ED_YetToTest (Expr)) { /* Yes, force a test */ g_test (Flags); ED_TestDone (Expr); diff --git a/src/cc65/locals.c b/src/cc65/locals.c index a21a09e8e..87c8e6cb9 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -122,8 +122,6 @@ static void ParseRegisterDecl (Declaration* Decl, int Reg) /* Check for an optional initialization */ if (CurTok.Tok == TOK_ASSIGN) { - ExprDesc Expr; - /* Skip the '=' */ NextToken (); @@ -152,6 +150,9 @@ static void ParseRegisterDecl (Declaration* Decl, int Reg) } else { + ExprDesc Expr; + ED_Init (&Expr); + /* Parse the expression */ hie1 (&Expr); @@ -203,8 +204,6 @@ static void ParseAutoDecl (Declaration* Decl) /* Check for an optional initialization */ if (CurTok.Tok == TOK_ASSIGN) { - ExprDesc Expr; - /* Skip the '=' */ NextToken (); @@ -242,6 +241,9 @@ static void ParseAutoDecl (Declaration* Decl) } else { + ExprDesc Expr; + ED_Init (&Expr); + /* Allocate previously reserved local space */ F_AllocLocalSpace (CurrentFunc); @@ -303,8 +305,6 @@ static void ParseAutoDecl (Declaration* Decl) /* Allow assignments */ if (CurTok.Tok == TOK_ASSIGN) { - ExprDesc Expr; - /* Skip the '=' */ NextToken (); @@ -328,6 +328,9 @@ static void ParseAutoDecl (Declaration* Decl) } else { + ExprDesc Expr; + ED_Init (&Expr); + /* Allocate space for the variable */ AllocStorage (DataLabel, g_usebss, Size); diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index 1c4837d94..518570ff5 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -1043,6 +1043,7 @@ static int DoIf (int Skip) /* Process #if directive */ { ExprDesc Expr; + ED_Init (&Expr); /* We're about to abuse the compiler expression parser to evaluate the ** #if expression. Save the current tokens to come back here later. diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index 9fe9d1188..0c69e96e5 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -61,7 +61,6 @@ void ShiftExpr (struct ExprDesc* Expr) /* Parse the << and >> operators. */ { - ExprDesc Expr2; CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ @@ -78,6 +77,10 @@ void ShiftExpr (struct ExprDesc* Expr) while (CurTok.Tok == TOK_SHL || CurTok.Tok == TOK_SHR) { + ExprDesc Expr2; + ED_Init (&Expr2); + Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; + /* All operators that call this function expect an int on the lhs */ if (!IsClassInt (Expr->Type)) { Error ("Integer expression expected"); diff --git a/src/cc65/staticassert.c b/src/cc65/staticassert.c index 68f0a41bc..b963947b6 100644 --- a/src/cc65/staticassert.c +++ b/src/cc65/staticassert.c @@ -55,6 +55,8 @@ void ParseStaticAssert () ExprDesc Expr; int failed; + ED_Init (&Expr); + /* Skip the _Static_assert token itself */ CHECK (CurTok.Tok == TOK_STATIC_ASSERT); NextToken (); diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 94e56a625..8335177bb 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -152,6 +152,9 @@ static void ParseArg (ArgDesc* Arg, Type* Type) /* Remember the required argument type */ Arg->ArgType = Type; + /* Init expression */ + ED_Init (&Arg->Expr); + /* Read the expression we're going to pass to the function */ MarkedExprWithCheck (hie1, &Arg->Expr); @@ -1180,6 +1183,8 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) long ECount; unsigned L; + ED_Init (&Arg); + /* Setup the argument type string */ ArgType[1].C = T_CHAR | T_QUAL_CONST; diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 036cc2d89..ba9ae389f 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -312,6 +312,7 @@ static void ReturnStatement (void) ExprDesc Expr; const Type* ReturnType; + ED_Init (&Expr); NextToken (); if (CurTok.Tok != TOK_SEMI) { @@ -424,8 +425,6 @@ static void ContinueStatement (void) static void ForStatement (void) /* Handle a 'for' statement */ { - ExprDesc lval1; - ExprDesc lval3; int HaveIncExpr; CodeMark IncExprStart; CodeMark IncExprEnd; @@ -450,6 +449,10 @@ static void ForStatement (void) /* Parse the initializer expression */ if (CurTok.Tok != TOK_SEMI) { + /* The value of the expression is unused */ + ExprDesc lval1; + ED_Init (&lval1); + lval1.Flags = E_NEED_NONE; Expression0 (&lval1); } ConsumeSemi (); @@ -475,6 +478,10 @@ static void ForStatement (void) /* Parse the increment expression */ HaveIncExpr = (CurTok.Tok != TOK_RPAREN); if (HaveIncExpr) { + /* The value of the expression is unused */ + ExprDesc lval3; + ED_Init (&lval3); + lval3.Flags = E_NEED_NONE; Expression0 (&lval3); } @@ -580,8 +587,10 @@ int Statement (int* PendingToken) { ExprDesc Expr; int GotBreak; + unsigned PrevErrorCount; CodeMark Start, End; - unsigned PrevErrorCount = ErrorCount; + + ED_Init (&Expr); /* Assume no pending token */ if (PendingToken) { @@ -666,25 +675,24 @@ int Statement (int* PendingToken) break; default: - /* Remember the current code position */ + /* Remember the current error count and code position */ + PrevErrorCount = ErrorCount; GetCodePos (&Start); + /* Actual statement */ - ExprWithCheck (hie0, &Expr); - /* Load the result only if it is an lvalue and the type is - ** marked as volatile. Otherwise the load is useless. - */ - if (ED_IsLVal (&Expr) && IsQualVolatile (Expr.Type)) { - LoadExpr (CF_NONE, &Expr); - } + Expr.Flags |= E_NEED_NONE; + Expression0 (&Expr); + /* If the statement didn't generate code, and is not of type ** void, emit a warning. */ GetCodePos (&End); - if (CodeRangeIsEmpty (&Start, &End) && - !IsTypeVoid (Expr.Type) && + if (!ED_YetToLoad (&Expr) && + !ED_MayHaveNoEffect (&Expr) && + CodeRangeIsEmpty (&Start, &End) && IS_Get (&WarnNoEffect) && PrevErrorCount == ErrorCount) { - Warning ("Statement has no effect"); + Warning ("Expression result unused"); } CheckSemi (PendingToken); } diff --git a/src/cc65/swstmt.c b/src/cc65/swstmt.c index 8cab93bba..524a31ddf 100644 --- a/src/cc65/swstmt.c +++ b/src/cc65/swstmt.c @@ -97,7 +97,6 @@ void SwitchStatement (void) SwitchCtrl* OldSwitch; /* Pointer to old switch control data */ SwitchCtrl SwitchData; /* New switch data */ - /* Eat the "switch" token */ NextToken (); @@ -105,6 +104,8 @@ void SwitchStatement (void) ** integer type. */ ConsumeLParen (); + + ED_Init (&SwitchExpr); Expression0 (&SwitchExpr); if (!IsClassInt (SwitchExpr.Type)) { Error ("Switch quantity is not an integer"); @@ -211,11 +212,11 @@ void CaseLabel (void) long Val; /* Case label value */ unsigned CodeLabel; /* Code label for this case */ - /* Skip the "case" token */ NextToken (); /* Read the selector expression */ + ED_Init (&CaseExpr); ConstAbsIntExpr (hie1, &CaseExpr); Val = CaseExpr.IVal; diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 5bb7bf7e4..b924eaa40 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -58,6 +58,8 @@ unsigned Test (unsigned Label, int Invert) ExprDesc Expr; unsigned Result; + ED_Init (&Expr); + /* Read a boolean expression */ BoolExpr (hie0, &Expr); @@ -80,10 +82,8 @@ unsigned Test (unsigned Label, int Invert) /* Result is unknown */ Result = TESTEXPR_UNKNOWN; - /* If the expr hasn't set condition codes, set the force-test flag */ - if (!ED_IsTested (&Expr)) { - ED_MarkForTest (&Expr); - } + /* Set the test flag */ + ED_RequireTest (&Expr); /* Load the value into the primary register */ LoadExpr (CF_FORCECHAR, &Expr); diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 0f67db107..930aef8d4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -371,6 +371,11 @@ void TypeCast (ExprDesc* Expr) GetBasicTypeName (NewType)); } + /* If the new type is void, the cast expression can have no effects */ + if (IsTypeVoid (NewType)) { + Expr->Flags |= E_EVAL_MAYBE_UNUSED; + } + /* The result is always an rvalue */ ED_MarkExprAsRVal (Expr); } From 1abb9da2b23b4de4b2e138818c1db7f7c537be96 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 26 Aug 2020 09:40:32 +0800 Subject: [PATCH 1602/2161] Moved bug250.c to test/val as it is fixed. --- test/val/bug250.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test/val/bug250.c diff --git a/test/val/bug250.c b/test/val/bug250.c new file mode 100644 index 000000000..60f3c633d --- /dev/null +++ b/test/val/bug250.c @@ -0,0 +1,13 @@ +/* bug #250 - Array size compile-time optimization stops halfway */ + +#include <stdlib.h> + +#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b)) +unsigned char c[2*4]; +unsigned char b[2*LZO_MAX(8,sizeof(int))]; // this will not compile + +int main(void) +{ + /* FIXME: add some runtime check */ + return EXIT_SUCCESS; +} From 725511131a40737c33fe7731194f7481ebbbc69d Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 20 Aug 2020 07:52:11 +0800 Subject: [PATCH 1603/2161] Fixed constant expression checks with no-code requirement. Used return-by-value initialization for ExprDesc. --- src/cc65/asmstmt.c | 19 +++------- src/cc65/declare.c | 38 +++++++------------- src/cc65/expr.c | 80 ++++++++++++++++++++++------------------- src/cc65/expr.h | 20 +++++------ src/cc65/preproc.c | 5 +-- src/cc65/preproc.h | 2 +- src/cc65/staticassert.c | 4 +-- src/cc65/swstmt.c | 3 +- 8 files changed, 73 insertions(+), 98 deletions(-) diff --git a/src/cc65/asmstmt.c b/src/cc65/asmstmt.c index 20de6033e..148d62d9c 100644 --- a/src/cc65/asmstmt.c +++ b/src/cc65/asmstmt.c @@ -129,16 +129,13 @@ static SymEntry* AsmGetSym (unsigned Arg, unsigned Type) static void ParseByteArg (StrBuf* T, unsigned Arg) /* Parse the %b format specifier */ { - ExprDesc Expr; char Buf [16]; - ED_Init (&Expr); - /* We expect an argument separated by a comma */ ConsumeComma (); /* Evaluate the expression */ - ConstAbsIntExpr (hie1, &Expr); + ExprDesc Expr = StaticConstAbsIntExpr (hie1); /* Check the range but allow negative values if the type is signed */ if (IsSignUnsigned (Expr.Type)) { @@ -165,16 +162,13 @@ static void ParseByteArg (StrBuf* T, unsigned Arg) static void ParseWordArg (StrBuf* T, unsigned Arg) /* Parse the %w format specifier */ { - ExprDesc Expr; char Buf [16]; - ED_Init (&Expr); - /* We expect an argument separated by a comma */ ConsumeComma (); /* Evaluate the expression */ - ConstAbsIntExpr (hie1, &Expr); + ExprDesc Expr = StaticConstAbsIntExpr (hie1); /* Check the range but allow negative values if the type is signed */ if (IsSignUnsigned (Expr.Type)) { @@ -201,16 +195,13 @@ static void ParseWordArg (StrBuf* T, unsigned Arg) static void ParseLongArg (StrBuf* T, unsigned Arg attribute ((unused))) /* Parse the %l format specifier */ { - ExprDesc Expr; char Buf [16]; - ED_Init (&Expr); - /* We expect an argument separated by a comma */ ConsumeComma (); /* Evaluate the expression */ - ConstAbsIntExpr (hie1, &Expr); + ExprDesc Expr = StaticConstAbsIntExpr (hie1); /* Convert into a hex number */ xsprintf (Buf, sizeof (Buf), "$%08lX", Expr.IVal & 0xFFFFFFFF); @@ -315,8 +306,6 @@ static void ParseStrArg (StrBuf* T, unsigned Arg attribute ((unused))) ExprDesc Expr; char Buf [64]; - ED_Init (&Expr); - /* We expect an argument separated by a comma */ ConsumeComma (); @@ -336,7 +325,7 @@ static void ParseStrArg (StrBuf* T, unsigned Arg attribute ((unused))) break; default: - ConstAbsIntExpr (hie1, &Expr); + Expr = StaticConstAbsIntExpr (hie1); xsprintf (Buf, sizeof (Buf), "%ld", Expr.IVal); SB_AppendStr (T, Buf); break; diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 7e5f24b24..8d24b168e 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -590,10 +590,8 @@ static SymEntry* ParseEnumDecl (const char* Name) /* Check for an assigned value */ if (CurTok.Tok == TOK_ASSIGN) { - ExprDesc Expr; - ED_Init (&Expr); NextToken (); - ConstAbsIntExpr (hie1, &Expr); + ExprDesc Expr = StaticConstAbsIntExpr (hie1); EnumVal = Expr.IVal; MemberType = Expr.Type; IsSigned = IsSignSigned (MemberType); @@ -720,9 +718,6 @@ static int ParseFieldWidth (Declaration* Decl) ** otherwise the width of the field. */ { - ExprDesc Expr; - ED_Init (&Expr); - if (CurTok.Tok != TOK_COLON) { /* No bit-field declaration */ return -1; @@ -746,7 +741,7 @@ static int ParseFieldWidth (Declaration* Decl) /* Read the width */ NextToken (); - ConstAbsIntExpr (hie1, &Expr); + ExprDesc Expr = StaticConstAbsIntExpr (hie1); if (Expr.IVal < 0) { Error ("Negative width in bit-field"); @@ -1819,9 +1814,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Read the size if it is given */ if (CurTok.Tok != TOK_RBRACK) { - ExprDesc Expr; - ED_Init (&Expr); - ConstAbsIntExpr (hie1, &Expr); + ExprDesc Expr = StaticConstAbsIntExpr (hie1); if (Expr.IVal <= 0) { if (D->Ident[0] != '\0') { Error ("Size of array '%s' is invalid", D->Ident); @@ -2158,7 +2151,7 @@ static void OutputBitFieldData (StructInitData* SI) -static void ParseScalarInitInternal (Type* T, ExprDesc* ED) +static ExprDesc ParseScalarInitInternal (Type* T) /* Parse initializaton for scalar data types. This function will not output the ** data but return it in ED. */ @@ -2174,11 +2167,13 @@ static void ParseScalarInitInternal (Type* T, ExprDesc* ED) } /* Get the expression and convert it to the target type */ - ConstExpr (hie1, ED); - TypeConversion (ED, T); + ExprDesc ED = StaticConstExpr (hie1); + TypeConversion (&ED, T); /* Close eventually opening braces */ ClosingCurlyBraces (BraceCount); + + return ED; } @@ -2186,11 +2181,8 @@ static void ParseScalarInitInternal (Type* T, ExprDesc* ED) static unsigned ParseScalarInit (Type* T) /* Parse initializaton for scalar data types. Return the number of data bytes. */ { - ExprDesc ED; - ED_Init (&ED); - /* Parse initialization */ - ParseScalarInitInternal (T, &ED); + ExprDesc ED = ParseScalarInitInternal (T); /* Output the data */ DefineData (&ED); @@ -2208,10 +2200,7 @@ static unsigned ParsePointerInit (Type* T) unsigned BraceCount = OpeningCurlyBraces (0); /* Expression */ - ExprDesc ED; - ED_Init (&ED); - - ConstExpr (hie1, &ED); + ExprDesc ED = StaticConstExpr (hie1); TypeConversion (&ED, T); /* Output the data */ @@ -2438,7 +2427,7 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) SI.Offs * CHAR_BITS + SI.ValBits); /* Read the data, check for a constant integer, do a range check */ - ParseScalarInitInternal (Entry->Type, &ED); + ED = ParseScalarInitInternal (Entry->Type); if (!ED_IsConstAbsInt (&ED)) { Error ("Constant initializer expected"); ED_MakeConstAbsInt (&ED, 1); @@ -2556,10 +2545,7 @@ static unsigned ParseVoidInit (Type* T) /* Allow an arbitrary list of values */ Size = 0; do { - ExprDesc Expr; - ED_Init (&Expr); - - ConstExpr (hie1, &Expr); + ExprDesc Expr = StaticConstExpr (hie1); switch (GetUnderlyingTypeCode (&Expr.Type[0])) { case T_SCHAR: diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 62136e122..dfc8007e4 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3147,17 +3147,14 @@ static void hieAndPP (ExprDesc* Expr) ** called recursively from the preprocessor. */ { - ConstAbsIntExpr (hie2, Expr); + *Expr = StaticConstAbsIntExpr (hie2); while (CurTok.Tok == TOK_BOOL_AND) { - ExprDesc Expr2; - ED_Init (&Expr2); - /* Skip the && */ NextToken (); /* Get rhs */ - ConstAbsIntExpr (hie2, &Expr2); + ExprDesc Expr2 = StaticConstAbsIntExpr (hie2); /* Combine the two */ Expr->IVal = (Expr->IVal && Expr2.IVal); @@ -3171,17 +3168,14 @@ static void hieOrPP (ExprDesc *Expr) ** called recursively from the preprocessor. */ { - ConstAbsIntExpr (hieAndPP, Expr); + *Expr = StaticConstAbsIntExpr (hieAndPP); while (CurTok.Tok == TOK_BOOL_OR) { - ExprDesc Expr2; - ED_Init (&Expr2); - /* Skip the && */ NextToken (); /* Get rhs */ - ConstAbsIntExpr (hieAndPP, &Expr2); + ExprDesc Expr2 = StaticConstAbsIntExpr (hieAndPP); /* Combine the two */ Expr->IVal = (Expr->IVal || Expr2.IVal); @@ -3900,24 +3894,6 @@ void Expression0 (ExprDesc* Expr) -void ConstExpr (void (*Func) (ExprDesc*), ExprDesc* Expr) -/* Will evaluate an expression via the given function. If the result is not -** a constant of some sort, a diagnostic will be printed, and the value is -** replaced by a constant one to make sure there are no internal errors that -** result from this input error. -*/ -{ - Expr->Flags |= E_EVAL_CONST; - ExprWithCheck (Func, Expr); - if (!ED_IsConst (Expr)) { - Error ("Constant expression expected"); - /* To avoid any compiler errors, make the expression a valid const */ - ED_MakeConstAbsInt (Expr, 1); - } -} - - - void BoolExpr (void (*Func) (ExprDesc*), ExprDesc* Expr) /* Will evaluate an expression via the given function. If the result is not ** something that may be evaluated in a boolean context, a diagnostic will be @@ -3927,26 +3903,56 @@ void BoolExpr (void (*Func) (ExprDesc*), ExprDesc* Expr) { ExprWithCheck (Func, Expr); if (!ED_IsBool (Expr)) { - Error ("Boolean expression expected"); + Error ("Scalar expression expected"); /* To avoid any compiler errors, make the expression a valid int */ - ED_MakeConstAbsInt (Expr, 1); + ED_MakeConstBool (Expr, 1); } } -void ConstAbsIntExpr (void (*Func) (ExprDesc*), ExprDesc* Expr) -/* Will evaluate an expression via the given function. If the result is not -** a constant numeric integer value, a diagnostic will be printed, and the +ExprDesc StaticConstExpr (void (*Func) (ExprDesc*)) +/* Will evaluate an expression via the given function. If the result is not a +** static constant expression, a diagnostic will be printed, and the value is +** replaced by a constant one to make sure there are no internal errors that +** result from this input error. +*/ +{ + ExprDesc Expr; + ED_Init (&Expr); + + Expr.Flags |= E_EVAL_C_CONST; + MarkedExprWithCheck (Func, &Expr); + if (!ED_IsConst (&Expr) || !ED_CodeRangeIsEmpty (&Expr)) { + Error ("Constant expression expected"); + /* To avoid any compiler errors, make the expression a valid const */ + ED_MakeConstAbsInt (&Expr, 1); + } + + /* Return by value */ + return Expr; +} + + + +ExprDesc StaticConstAbsIntExpr (void (*Func) (ExprDesc*)) +/* Will evaluate an expression via the given function. If the result is not a +** static constant numeric integer value, a diagnostic will be printed, and the ** value is replaced by a constant one to make sure there are no internal ** errors that result from this input error. */ { - Expr->Flags |= E_EVAL_CONST; - ExprWithCheck (Func, Expr); - if (!ED_IsConstAbsInt (Expr)) { + ExprDesc Expr; + ED_Init (&Expr); + + Expr.Flags |= E_EVAL_C_CONST; + MarkedExprWithCheck (Func, &Expr); + if (!ED_IsConstAbsInt (&Expr) || !ED_CodeRangeIsEmpty (&Expr)) { Error ("Constant integer expression expected"); /* To avoid any compiler errors, make the expression a valid const */ - ED_MakeConstAbsInt (Expr, 1); + ED_MakeConstAbsInt (&Expr, 1); } + + /* Return by value */ + return Expr; } diff --git a/src/cc65/expr.h b/src/cc65/expr.h index a6c183cbd..8f7eb6f09 100644 --- a/src/cc65/expr.h +++ b/src/cc65/expr.h @@ -54,13 +54,6 @@ int evalexpr (unsigned flags, void (*Func) (ExprDesc*), ExprDesc* Expr); void Expression0 (ExprDesc* Expr); /* Evaluate an expression via hie0 and put the result into the primary register */ -void ConstExpr (void (*Func) (ExprDesc*), ExprDesc* Expr); -/* Will evaluate an expression via the given function. If the result is not -** a constant of some sort, a diagnostic will be printed, and the value is -** replaced by a constant one to make sure there are no internal errors that -** result from this input error. -*/ - void BoolExpr (void (*Func) (ExprDesc*), ExprDesc* Expr); /* Will evaluate an expression via the given function. If the result is not ** something that may be evaluated in a boolean context, a diagnostic will be @@ -68,9 +61,16 @@ void BoolExpr (void (*Func) (ExprDesc*), ExprDesc* Expr); ** are no internal errors that result from this input error. */ -void ConstAbsIntExpr (void (*Func) (ExprDesc*), ExprDesc* Expr); -/* Will evaluate an expression via the given function. If the result is not -** a constant numeric integer value, a diagnostic will be printed, and the +ExprDesc StaticConstExpr (void (*Func) (ExprDesc*)); +/* Get an expression evaluated via the given function. If the result is not a +** static constant expression, a diagnostic will be printed, and the value is +** replaced by a constant one to make sure there are no internal errors that +** result from this input error. +*/ + +ExprDesc StaticConstAbsIntExpr (void (*Func) (ExprDesc*)); +/* Get an expression evaluate via the given function. If the result is not a +** static constant numeric integer value, a diagnostic will be printed, and the ** value is replaced by a constant one to make sure there are no internal ** errors that result from this input error. */ diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index 518570ff5..2d2f316d7 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -1042,9 +1042,6 @@ static void DoError (void) static int DoIf (int Skip) /* Process #if directive */ { - ExprDesc Expr; - ED_Init (&Expr); - /* We're about to abuse the compiler expression parser to evaluate the ** #if expression. Save the current tokens to come back here later. ** NOTE: Yes, this is a hack, but it saves a complete separate expression @@ -1079,7 +1076,7 @@ static int DoIf (int Skip) NextToken (); /* Call the expression parser */ - ConstExpr (hie1, &Expr); + ExprDesc Expr = StaticConstExpr (hie1); /* End preprocessing mode */ Preprocessing = 0; diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 8d7b3c374..464b02337 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -44,7 +44,7 @@ -/* Set when the preprocessor calls ConstExpr() recursively */ +/* Set when the preprocessor calls StaticConstExpr() recursively */ extern unsigned char Preprocessing; diff --git a/src/cc65/staticassert.c b/src/cc65/staticassert.c index b963947b6..3372c59a1 100644 --- a/src/cc65/staticassert.c +++ b/src/cc65/staticassert.c @@ -55,8 +55,6 @@ void ParseStaticAssert () ExprDesc Expr; int failed; - ED_Init (&Expr); - /* Skip the _Static_assert token itself */ CHECK (CurTok.Tok == TOK_STATIC_ASSERT); NextToken (); @@ -67,7 +65,7 @@ void ParseStaticAssert () } /* Parse assertion condition */ - ConstAbsIntExpr (hie1, &Expr); + Expr = StaticConstAbsIntExpr (hie1); failed = !Expr.IVal; /* If there is a comma, we also have an error message. The message is optional because we diff --git a/src/cc65/swstmt.c b/src/cc65/swstmt.c index 524a31ddf..559e168c3 100644 --- a/src/cc65/swstmt.c +++ b/src/cc65/swstmt.c @@ -216,8 +216,7 @@ void CaseLabel (void) NextToken (); /* Read the selector expression */ - ED_Init (&CaseExpr); - ConstAbsIntExpr (hie1, &CaseExpr); + CaseExpr = StaticConstAbsIntExpr (hie1); Val = CaseExpr.IVal; /* Now check if we're inside a switch statement */ From 85ea06687b7ba638841aeb83a0d22ae9112d5425 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 20 Aug 2020 07:52:15 +0800 Subject: [PATCH 1604/2161] Fixed logical AND and logical OR. --- src/cc65/expr.c | 253 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 196 insertions(+), 57 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index dfc8007e4..b27a1c6fc 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3184,58 +3184,135 @@ static void hieOrPP (ExprDesc *Expr) -static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp) -/* Process "exp && exp" */ +static int hieAnd (ExprDesc* Expr, unsigned TrueLab, int* UsedTrueLab) +/* Process "exp && exp". This should only be called within hieOr. +** Return true if logic AND does occur. +*/ { - int FalseLab; + unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; + int HasFalseJump = 0, HasTrueJump = 0; + CodeMark Start; + + /* Get a label that we will use for false expressions */ + int FalseLab = GetLocalLabel (); + + /* Get lhs */ + GetCodePos (&Start); ExprWithCheck (hie2, Expr); + if ((Flags & E_EVAL_UNEVAL) == E_EVAL_UNEVAL) { + RemoveCode (&Start); + } + if (CurTok.Tok == TOK_BOOL_AND) { - /* Tell our caller that we're evaluating a boolean */ - *BoolOp = 1; + ExprDesc Expr2; - /* Get a label that we will use for false expressions */ - FalseLab = GetLocalLabel (); + /* Check type */ + if (!ED_IsBool (Expr)) { + Error ("Scalar expression expected"); + ED_MakeConstBool (Expr, 0); + } else if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + if (!ED_IsConstAbs (Expr)) { + /* Set the test flag */ + ED_RequireTest (Expr); - /* Set the test flag */ - ED_RequireTest (Expr); + /* Load the value */ + LoadExpr (CF_FORCECHAR, Expr); - /* Load the value */ - LoadExpr (CF_FORCECHAR, Expr); + /* Remember that the jump is used */ + HasFalseJump = 1; - /* Generate the jump */ - g_falsejump (CF_NONE, FalseLab); + /* Generate the jump */ + g_falsejump (CF_NONE, FalseLab); + } else if (Expr->IVal == 0) { + /* Skip remaining */ + Flags |= E_EVAL_UNEVAL; + } + } /* Parse more boolean and's */ while (CurTok.Tok == TOK_BOOL_AND) { - ExprDesc Expr2; ED_Init (&Expr2); + Expr2.Flags = Flags; /* Skip the && */ NextToken (); /* Get rhs */ + GetCodePos (&Start); hie2 (&Expr2); - ED_RequireTest (&Expr2); - LoadExpr (CF_FORCECHAR, &Expr2); + if ((Flags & E_EVAL_UNEVAL) == E_EVAL_UNEVAL) { + RemoveCode (&Start); + } - /* Do short circuit evaluation */ - if (CurTok.Tok == TOK_BOOL_AND) { - g_falsejump (CF_NONE, FalseLab); - } else { - /* Last expression - will evaluate to true */ - g_truejump (CF_NONE, TrueLab); + /* Check type */ + if (!ED_IsBool (&Expr2)) { + Error ("Scalar expression expected"); + ED_MakeConstBool (&Expr2, 0); + } else if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + if (!ED_IsConstAbs (&Expr2)) { + ED_RequireTest (&Expr2); + LoadExpr (CF_FORCECHAR, &Expr2); + + /* Do short circuit evaluation */ + if (CurTok.Tok == TOK_BOOL_AND) { + HasFalseJump = 1; + g_falsejump (CF_NONE, FalseLab); + } else { + /* We need the true label for the last expression */ + HasTrueJump = 1; + } + } else if (Expr2.IVal == 0) { + /* Skip remaining */ + Flags |= E_EVAL_UNEVAL; + /* The value of the expression will be false */ + ED_MakeConstBool (Expr, 0); + } } } - /* Define the false jump label here */ - g_defcodelabel (FalseLab); + /* Last expression */ + if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + if (HasFalseJump || HasTrueJump) { + /* In either case we need the true label anyways */ + HasTrueJump = 1; + if (!ED_IsConstAbs (&Expr2)) { + /* Will branch to true and fall to false */ + g_truejump (CF_NONE, TrueLab); + } else { + /* Will jump away */ + g_jump (TrueLab); + } + /* The result is an rvalue in primary */ + ED_FinalizeRValLoad (Expr); + /* No need to test as the result will be jumped to */ + ED_TestDone (Expr); + } + } - /* The result is an rvalue in primary */ - ED_FinalizeRValLoad (Expr); - ED_TestDone (Expr); /* Condition codes are set */ + if (HasFalseJump) { + /* Define the false jump label here */ + g_defcodelabel (FalseLab); + } + + /* Convert to bool */ + if (ED_IsConstAbs (Expr) && Expr->IVal != 0) { + ED_MakeConstBool (Expr, 1); + } else { + Expr->Type = type_bool; + } + + /* Tell our caller that we're used the true label */ + if (HasTrueJump) { + *UsedTrueLab = 1; + } + + /* Tell our caller that we're evaluating a boolean */ + return 1; } + + return 0; } @@ -3243,69 +3320,131 @@ static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp) static void hieOr (ExprDesc *Expr) /* Process "exp || exp". */ { - int BoolOp = 0; /* Did we have a boolean op? */ - int AndOp; /* Did we have a && operation? */ + unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; + int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ unsigned DoneLab; + int HasTrueJump = 0; + int HasNewTrueJump; + CodeMark Start; - /* Get a label */ + /* Get a label that we will use for true expressions */ TrueLab = GetLocalLabel (); /* Call the next level parser */ - hieAnd (Expr, TrueLab, &BoolOp); + GetCodePos (&Start); + AndOp = hieAnd (Expr, TrueLab, &HasNewTrueJump); + if ((Flags & E_EVAL_UNEVAL) == E_EVAL_UNEVAL) { + RemoveCode (&Start); + } else { + /* Remember the jump */ + HasTrueJump = HasNewTrueJump; + } /* Any boolean or's? */ if (CurTok.Tok == TOK_BOOL_OR) { - /* Set the test flag */ - ED_RequireTest (Expr); + /* Check type */ + if (!ED_IsBool (Expr)) { + Error ("Scalar expression expected"); + ED_MakeConstBool (Expr, 0); + } else if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + + if (!ED_IsConstAbs (Expr)) { + /* Test the lhs if we haven't had && operators. If we had them, the + ** jump is already in place and there's no need to do the test. + */ + if (!AndOp) { + /* Set the test flag */ + ED_RequireTest (Expr); - /* Get first expr */ - LoadExpr (CF_FORCECHAR, Expr); + /* Get first expr */ + LoadExpr (CF_FORCECHAR, Expr); - /* For each expression jump to TrueLab if true. Beware: If we - ** had && operators, the jump is already in place! - */ - if (!BoolOp) { - g_truejump (CF_NONE, TrueLab); + /* Remember that the jump is used */ + HasTrueJump = 1; + + /* Jump to TrueLab if true */ + g_truejump (CF_NONE, TrueLab); + } + } else if (Expr->IVal != 0) { + /* Skip remaining */ + Flags |= E_EVAL_UNEVAL; + } } - /* Remember that we had a boolean op */ - BoolOp = 1; - /* while there's more expr */ while (CurTok.Tok == TOK_BOOL_OR) { ExprDesc Expr2; ED_Init (&Expr2); + Expr2.Flags = Flags; /* skip the || */ NextToken (); - /* Get a subexpr */ - AndOp = 0; - hieAnd (&Expr2, TrueLab, &AndOp); - ED_RequireTest (&Expr2); - LoadExpr (CF_FORCECHAR, &Expr2); + /* Get rhs subexpression */ + GetCodePos (&Start); + AndOp = hieAnd (&Expr2, TrueLab, &HasNewTrueJump); + if ((Flags & E_EVAL_UNEVAL) == E_EVAL_UNEVAL) { + RemoveCode (&Start); + } else { + /* Remember the jump */ + HasTrueJump = HasTrueJump || HasNewTrueJump; + } - /* If there is more to come, add shortcut boolean eval. */ - g_truejump (CF_NONE, TrueLab); + /* Check type */ + if (!ED_IsBool (&Expr2)) { + Error ("Scalar expression expected"); + ED_MakeConstBool (&Expr2, 0); + } else if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + + if (!ED_IsConstAbs (&Expr2)) { + /* If there is more to come, add shortcut boolean eval */ + if (!AndOp) { + ED_RequireTest (&Expr2); + LoadExpr (CF_FORCECHAR, &Expr2); + + HasTrueJump = 1; + g_truejump (CF_NONE, TrueLab); + } + } else if (Expr2.IVal != 0) { + /* Skip remaining */ + Flags |= E_EVAL_UNEVAL; + /* The result is always true */ + ED_MakeConstBool (Expr, 1); + } + } } - /* The result is an rvalue in primary */ - ED_FinalizeRValLoad (Expr); - ED_TestDone (Expr); /* Condition codes are set */ + /* Convert to bool */ + if (ED_IsConstAbs (Expr) && Expr->IVal != 0) { + ED_MakeConstBool (Expr, 1); + } else { + Expr->Type = type_bool; + } } - /* If we really had boolean ops, generate the end sequence */ - if (BoolOp) { + /* If we really had boolean ops, generate the end sequence if necessary */ + if (HasTrueJump) { + /* False case needs to jump over true case */ DoneLab = GetLocalLabel (); - g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ - g_falsejump (CF_NONE, DoneLab); + if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* Load false only if the result is not true */ + g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ + g_falsejump (CF_NONE, DoneLab); + } + + /* Load the true value */ g_defcodelabel (TrueLab); g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ g_defcodelabel (DoneLab); + + /* The result is an rvalue in primary */ + ED_FinalizeRValLoad (Expr); + /* Condition codes are set */ + ED_TestDone (Expr); } } From 75dc2349882c563e7646715bf2933ac50cf6753f Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 21 Aug 2020 15:15:19 -0400 Subject: [PATCH 1605/2161] Guarded the static_assert macro with a C standards test. --- include/assert.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/include/assert.h b/include/assert.h index 3f8b46ac0..a4dcd5d7f 100644 --- a/include/assert.h +++ b/include/assert.h @@ -46,16 +46,14 @@ extern void __fastcall__ _afailed (const char*, unsigned); # define assert(expr) ((expr)? (void)0 : _afailed(__FILE__, __LINE__)) #endif -/* -** TODO: Guard with #if __STDC_VERSION__ >= 201112L or similar when there +/* TODO: Guard with #if __CC65_STD__ >= __CC65_STD_C11__ if there ** is a C11 mode. */ -#define static_assert _Static_assert +#if __CC65_STD__ > __CC65_STD_C99__ +# define static_assert _Static_assert +#endif /* End of assert.h */ #endif - - - From ea7336591cc807d63351a223896a3d9d84ae7d9a Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 2 Jul 2020 10:30:02 +0800 Subject: [PATCH 1606/2161] Removed special-casing code for scaling up. Now it uses the normal multiplying code. --- src/cc65/codegen.c | 53 +++++++++------------------------------------- 1 file changed, 10 insertions(+), 43 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 6b6b292b0..a2dbf12b4 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -1496,54 +1496,14 @@ void g_scale (unsigned flags, long val) ** pointer points to. */ { - int p2; - /* Value may not be zero */ if (val == 0) { Internal ("Data type has no size"); } else if (val > 0) { - /* Scale up */ - if ((p2 = PowerOf2 (val)) > 0 && p2 <= 4) { - - /* Factor is 2, 4, 8 and 16, use special function */ - switch (flags & CF_TYPEMASK) { - - case CF_CHAR: - if (flags & CF_FORCECHAR) { - while (p2--) { - AddCodeLine ("asl a"); - } - break; - } - /* FALLTHROUGH */ - - case CF_INT: - if (flags & CF_UNSIGNED) { - AddCodeLine ("jsr shlax%d", p2); - } else { - AddCodeLine ("jsr aslax%d", p2); - } - break; - - case CF_LONG: - if (flags & CF_UNSIGNED) { - AddCodeLine ("jsr shleax%d", p2); - } else { - AddCodeLine ("jsr asleax%d", p2); - } - break; - - default: - typeerror (flags); - - } - - } else if (val != 1) { - - /* Use a multiplication instead */ + /* Use a multiplication instead */ + if (val != 1) { g_mul (flags | CF_CONST, val); - } } else { @@ -3224,7 +3184,6 @@ void g_asl (unsigned flags, unsigned long val) "tosaslax", "tosshlax", "tosasleax", "tosshleax" }; - /* If the right hand side is const, the lhs is not on stack but still ** in the primary register. */ @@ -3233,6 +3192,14 @@ void g_asl (unsigned flags, unsigned long val) switch (flags & CF_TYPEMASK) { case CF_CHAR: + if ((flags & CF_FORCECHAR) != 0 && val <= 4) { + while (val--) { + AddCodeLine ("asl a"); + } + return; + } + /* FALLTHROUGH */ + case CF_INT: val &= 0x0F; if (val >= 8) { From f59c2a08d998cc1dcfb2442a79d076b113ae9ad4 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 2 Jul 2020 10:30:02 +0800 Subject: [PATCH 1607/2161] Added support for changing multiplications with certain negative multipliers into bit-shifts. Only enable certain kinds of signed mul replacements with shift according to the code size factor settings. --- src/cc65/codegen.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index a2dbf12b4..6cd8f5c43 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -2565,13 +2565,26 @@ void g_mul (unsigned flags, unsigned long val) "tosmulax", "tosumulax", "tosmuleax", "tosumuleax" }; - int p2; - /* Do strength reduction if the value is constant and a power of two */ - if (flags & CF_CONST && (p2 = PowerOf2 (val)) >= 0) { - /* Generate a shift instead */ - g_asl (flags, p2); - return; + if (flags & CF_CONST) { + + /* Deal with negative values if it's signed multiplication */ + int Negation = (flags & CF_UNSIGNED) == 0 && (signed long)val < 0; + int p2 = PowerOf2 (Negation ? (unsigned long)-(signed long)val : val); + + /* Check if we can use shift instead of multiplication */ + if (p2 == 0 || (p2 > 0 && IS_Get (&CodeSizeFactor) >= (Negation ? 100 : 0))) { + /* Generate a shift instead */ + g_asl (flags, p2); + + /* Negate the result if val is negative */ + if (Negation) { + g_neg (flags); + } + + /* Done */ + return; + } } /* If the right hand side is const, the lhs is not on stack but still From 63256fd15d0b54258a9df515bc62fca140eac201 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 20 Aug 2020 22:47:08 +0800 Subject: [PATCH 1608/2161] Changed negation of signed long stored in unsigned long to unsigned subtraction. --- src/cc65/codegen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 6cd8f5c43..48cf02319 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -2569,8 +2569,8 @@ void g_mul (unsigned flags, unsigned long val) if (flags & CF_CONST) { /* Deal with negative values if it's signed multiplication */ - int Negation = (flags & CF_UNSIGNED) == 0 && (signed long)val < 0; - int p2 = PowerOf2 (Negation ? (unsigned long)-(signed long)val : val); + int Negation = (flags & CF_UNSIGNED) == 0 && (long)val < 0; + int p2 = PowerOf2 (Negation ? 0UL - val : val); /* Check if we can use shift instead of multiplication */ if (p2 == 0 || (p2 > 0 && IS_Get (&CodeSizeFactor) >= (Negation ? 100 : 0))) { @@ -2690,7 +2690,7 @@ void g_div (unsigned flags, unsigned long val) /* Deal with negative values as well as different sizes */ int Negation = (flags & CF_UNSIGNED) == 0 && (long)val < 0; - unsigned long NegatedVal = (unsigned long)-(long)val; + unsigned long NegatedVal = 0UL - val; int p2 = PowerOf2 (Negation ? NegatedVal : val); /* Generate a shift instead */ From 0536f4f9bdf9ce5bf7dd6d5dbfeaafda3c228f12 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 20 Aug 2020 07:52:27 +0800 Subject: [PATCH 1609/2161] Minor fixes on constant expression checking and comments. --- src/cc65/expr.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 84d709eb9..12a0c0b57 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -557,7 +557,7 @@ static void FunctionCall (ExprDesc* Expr) ** For fastcall functions we do also need to place a copy of the ** pointer on stack, since we cannot use a/x. */ - PtrOnStack = IsFastcall || !ED_IsConst (Expr); + PtrOnStack = IsFastcall || !ED_IsConstAddr (Expr); if (PtrOnStack) { /* Not a global or local variable, or a fastcall function. Load @@ -1083,12 +1083,13 @@ static void ArrayRef (ExprDesc* Expr) ED_FinalizeRValLoad (&Subscript); } - /* Check if the subscript is constant absolute value */ + /* Make the address of the array element from the base and subscript */ if (ED_IsConstAbs (&Subscript) && ED_CodeRangeIsEmpty (&Subscript)) { - /* The array subscript is a numeric constant. If we had pushed the - ** array base address onto the stack before, we can remove this value, - ** since we can generate expression+offset. + /* The array subscript is a constant. Since we can have the element + ** address directly as base+offset, we can remove the array address + ** push onto the stack before if loading subscript doesn't tamper that + ** address in the primary. */ if (!ConstBaseAddr) { RemoveCode (&Mark2); @@ -1127,7 +1128,7 @@ static void ArrayRef (ExprDesc* Expr) } else { - /* Scale the rhs value according to the element type */ + /* Scale the lhs value according to the element type */ g_scale (TypeOf (tptr1), CheckedSizeOf (ElementType)); /* Add the subscript. Since arrays are indexed by integers, @@ -1247,13 +1248,13 @@ static void ArrayRef (ExprDesc* Expr) } } - /* The pointer is an rvalue in the primary */ + /* The address of the element is an rvalue in the primary */ ED_FinalizeRValLoad (Expr); } - /* The result is usually an lvalue expression of element type referenced in - ** the primary, unless it's an array which is a rare case. We can just + /* The final result is usually an lvalue expression of element type + ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); From f289ea6c148341fc4d09fa46a55435668901c8a0 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 22 Aug 2020 11:10:17 +0800 Subject: [PATCH 1610/2161] Avoided generating unnecessary true-case labels in logic AND/OR. --- src/cc65/expr.c | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index b27a1c6fc..416d383d0 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3184,7 +3184,7 @@ static void hieOrPP (ExprDesc *Expr) -static int hieAnd (ExprDesc* Expr, unsigned TrueLab, int* UsedTrueLab) +static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) /* Process "exp && exp". This should only be called within hieOr. ** Return true if logic AND does occur. */ @@ -3275,14 +3275,17 @@ static int hieAnd (ExprDesc* Expr, unsigned TrueLab, int* UsedTrueLab) /* Last expression */ if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { if (HasFalseJump || HasTrueJump) { - /* In either case we need the true label anyways */ - HasTrueJump = 1; + if (*TrueLabAllocated == 0) { + /* Get a label that we will use for true expressions */ + *TrueLab = GetLocalLabel (); + *TrueLabAllocated = 1; + } if (!ED_IsConstAbs (&Expr2)) { /* Will branch to true and fall to false */ - g_truejump (CF_NONE, TrueLab); + g_truejump (CF_NONE, *TrueLab); } else { /* Will jump away */ - g_jump (TrueLab); + g_jump (*TrueLab); } /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); @@ -3303,11 +3306,6 @@ static int hieAnd (ExprDesc* Expr, unsigned TrueLab, int* UsedTrueLab) Expr->Type = type_bool; } - /* Tell our caller that we're used the true label */ - if (HasTrueJump) { - *UsedTrueLab = 1; - } - /* Tell our caller that we're evaluating a boolean */ return 1; } @@ -3325,20 +3323,13 @@ static void hieOr (ExprDesc *Expr) unsigned TrueLab; /* Jump to this label if true */ unsigned DoneLab; int HasTrueJump = 0; - int HasNewTrueJump; CodeMark Start; - /* Get a label that we will use for true expressions */ - TrueLab = GetLocalLabel (); - /* Call the next level parser */ GetCodePos (&Start); - AndOp = hieAnd (Expr, TrueLab, &HasNewTrueJump); + AndOp = hieAnd (Expr, &TrueLab, &HasTrueJump); if ((Flags & E_EVAL_UNEVAL) == E_EVAL_UNEVAL) { RemoveCode (&Start); - } else { - /* Remember the jump */ - HasTrueJump = HasNewTrueJump; } /* Any boolean or's? */ @@ -3361,8 +3352,11 @@ static void hieOr (ExprDesc *Expr) /* Get first expr */ LoadExpr (CF_FORCECHAR, Expr); - /* Remember that the jump is used */ - HasTrueJump = 1; + if (HasTrueJump == 0) { + /* Get a label that we will use for true expressions */ + TrueLab = GetLocalLabel(); + HasTrueJump = 1; + } /* Jump to TrueLab if true */ g_truejump (CF_NONE, TrueLab); @@ -3385,12 +3379,9 @@ static void hieOr (ExprDesc *Expr) /* Get rhs subexpression */ GetCodePos (&Start); - AndOp = hieAnd (&Expr2, TrueLab, &HasNewTrueJump); + AndOp = hieAnd (&Expr2, &TrueLab, &HasTrueJump); if ((Flags & E_EVAL_UNEVAL) == E_EVAL_UNEVAL) { RemoveCode (&Start); - } else { - /* Remember the jump */ - HasTrueJump = HasTrueJump || HasNewTrueJump; } /* Check type */ @@ -3405,7 +3396,10 @@ static void hieOr (ExprDesc *Expr) ED_RequireTest (&Expr2); LoadExpr (CF_FORCECHAR, &Expr2); - HasTrueJump = 1; + if (HasTrueJump == 0) { + TrueLab = GetLocalLabel(); + HasTrueJump = 1; + } g_truejump (CF_NONE, TrueLab); } } else if (Expr2.IVal != 0) { From 0486d28abc155c32253b5fab0a00e5e35f81e053 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 15 Aug 2020 07:52:58 +0800 Subject: [PATCH 1611/2161] Fixed Issue #327. --- src/cc65/typeconv.c | 4 ++-- test/{todo => val}/bug327.c | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename test/{todo => val}/bug327.c (100%) diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 7e2787529..c9163eb51 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -124,7 +124,7 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) LoadExpr (CF_NONE, Expr); /* Emit typecast code */ - g_typecast (TypeOf (NewType), TypeOf (OldType) | CF_FORCECHAR); + g_typecast (TypeOf (NewType), TypeOf (OldType)); /* Value is now in primary and an rvalue */ ED_FinalizeRValLoad (Expr); @@ -175,7 +175,7 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) LoadExpr (CF_NONE, Expr); /* Emit typecast code. */ - g_typecast (TypeOf (NewType), TypeOf (OldType) | CF_FORCECHAR); + g_typecast (TypeOf (NewType), TypeOf (OldType)); /* Value is now an rvalue in the primary */ ED_FinalizeRValLoad (Expr); diff --git a/test/todo/bug327.c b/test/val/bug327.c similarity index 100% rename from test/todo/bug327.c rename to test/val/bug327.c From 23621f3299f213117e0b14358ea3bf66d69b980b Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sat, 22 Aug 2020 10:48:25 +0200 Subject: [PATCH 1612/2161] Add test case for #1209 Change err/ tests to use cl65 and .prg instead of cc65 and .s since this test only fails at the link stage. --- test/err/Makefile | 8 ++--- test/err/bug1209-ind-goto-rev.c | 53 +++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 test/err/bug1209-ind-goto-rev.c diff --git a/test/err/Makefile b/test/err/Makefile index 1273bbb2c..6fa53a1db 100644 --- a/test/err/Makefile +++ b/test/err/Makefile @@ -23,23 +23,23 @@ ifdef QUIET NULLERR = 2>$(NULLDEV) endif -CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65) +CL65 := $(if $(wildcard ../../bin/cl65*),..$S..$Sbin$Scl65,cl65) WORKDIR = ../../testwrk/err .PHONY: all clean SOURCES := $(wildcard *.c) -TESTS = $(patsubst %.c,$(WORKDIR)/%.s,$(SOURCES)) +TESTS = $(patsubst %.c,$(WORKDIR)/%.prg,$(SOURCES)) all: $(TESTS) $(WORKDIR): $(call MKDIR,$(WORKDIR)) -$(WORKDIR)/%.s: %.c | $(WORKDIR) +$(WORKDIR)/%.prg: %.c | $(WORKDIR) $(if $(QUIET),echo err/$*.s) - $(NOT) $(CC65) -o $@ $< $(NULLERR) + $(NOT) $(CL65) -o $@ $< $(NULLERR) clean: @$(call RMDIR,$(WORKDIR)) diff --git a/test/err/bug1209-ind-goto-rev.c b/test/err/bug1209-ind-goto-rev.c new file mode 100644 index 000000000..39d8639bd --- /dev/null +++ b/test/err/bug1209-ind-goto-rev.c @@ -0,0 +1,53 @@ +/* + Copyright 2020 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. +*/ + +/* + Tests of indirect goto with the label before the goto. + https://github.com/cc65/cc65/issues/1209 + This should compile and should be moved to tests/val/ when the bug is fixed. +*/ + +#include <stdio.h> +#include <stdlib.h> + +/* When operating correctly, this returns 0. */ +int f (void) +{ + static void *x[1]; + /* Define the label before referencing it with indirect label syntax. */ + L: if (x[0] != 0) return 0; + x[0] = &&L; + goto *x[0]; +} + +static unsigned char failures = 0; + +int main (void) +{ + if (f () != 0) failures++; + + if (failures == 0) { + printf ("PASS\n"); + } else { + printf ("FAIL: %d failures\n", failures); + } + + return failures; +} From 911a79796dded8777953d8da63b98d04a3117b37 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 15 Aug 2020 06:27:11 +0800 Subject: [PATCH 1613/2161] Fixed checks and diagnostics on type-casting. --- src/cc65/typeconv.c | 92 ++++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 35 deletions(-) diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index c9163eb51..3af092d42 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -207,27 +207,30 @@ void TypeConversion (ExprDesc* Expr, const Type* NewType) printf ("\n"); PrintRawType (stdout, NewType); #endif + /* First, do some type checking */ int HasWarning = 0; int HasError = 0; const char* Msg = 0; const Type* OldType = Expr->Type; - /* First, do some type checking */ - if (IsTypeVoid (NewType) || IsTypeVoid (Expr->Type)) { - /* If one of the sides are of type void, output a more apropriate - ** error message. - */ - Error ("Illegal type"); + /* If one of the sides is of type void, it is an error */ + if (IsTypeVoid (NewType) || IsTypeVoid (OldType)) { + HasError = 1; } - /* If Expr is a function, convert it to pointer to function */ - if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + /* If both types are strictly compatible, no conversion is needed */ + if (TypeCmp (NewType, OldType) >= TC_STRICT_COMPATIBLE) { + /* We're already done */ + return; } - /* If both types are equal, no conversion is needed */ - if (TypeCmp (Expr->Type, NewType) >= TC_EQUAL) { + /* If Expr is an array or a function, convert it to a pointer */ + Expr->Type = PtrConversion (Expr->Type); + + /* If we have changed the type, check again for strictly compatibility */ + if (Expr->Type != OldType && + TypeCmp (NewType, Expr->Type) >= TC_STRICT_COMPATIBLE) { /* We're already done */ return; } @@ -237,10 +240,6 @@ void TypeConversion (ExprDesc* Expr, const Type* NewType) /* Handle conversions to int type */ if (IsClassPtr (Expr->Type)) { - /* Pointer -> int conversion. Convert array to pointer */ - if (IsTypeArray (Expr->Type)) { - Expr->Type = ArrayToPtr (Expr->Type); - } Warning ("Converting pointer to integer without a cast"); } else if (!IsClassInt (Expr->Type) && !IsClassFloat (Expr->Type)) { HasError = 1; @@ -254,11 +253,6 @@ void TypeConversion (ExprDesc* Expr, const Type* NewType) /* Handle conversions to pointer type */ if (IsClassPtr (Expr->Type)) { - /* Convert array to pointer */ - if (IsTypeArray (Expr->Type)) { - Expr->Type = ArrayToPtr (Expr->Type); - } - /* Pointer to pointer assignment is valid, if: ** - both point to the same types, or ** - the rhs pointer is a void pointer, or @@ -271,11 +265,15 @@ void TypeConversion (ExprDesc* Expr, const Type* NewType) case TC_INCOMPATIBLE: HasWarning = 1; Msg = "Incompatible pointer assignment to '%s' from '%s'"; + /* Use the pointer type in the diagnostic */ + OldType = Expr->Type; break; case TC_QUAL_DIFF: HasWarning = 1; Msg = "Pointer assignment to '%s' from '%s' discards qualifiers"; + /* Use the pointer type in the diagnostic */ + OldType = Expr->Type; break; default: @@ -309,8 +307,21 @@ void TypeConversion (ExprDesc* Expr, const Type* NewType) TypeCompatibilityDiagnostic (NewType, OldType, 0, Msg); } - /* Do the actual conversion */ - DoConversion (Expr, NewType); + /* Both types must be complete */ + if (!IsIncompleteESUType (NewType) && !IsIncompleteESUType (Expr->Type)) { + /* Do the actual conversion */ + DoConversion (Expr, NewType); + } else { + /* We should have already generated error elsewhere so that we + ** could just silently fail here to avoid excess errors, but to + ** be safe, we must ensure that we do have errors. + */ + if (IsIncompleteESUType (NewType)) { + Error ("Conversion to incomplete type '%s'", GetFullTypeName (NewType)); + } else { + Error ("Conversion from incomplete type '%s'", GetFullTypeName (Expr->Type)); + } + } } } @@ -333,19 +344,30 @@ void TypeCast (ExprDesc* Expr) /* Read the expression we have to cast */ hie10 (Expr); - /* Only allow casts to arithmetic or pointer types, or just changing the - ** qualifiers. - */ - if (TypeCmp (NewType, Expr->Type) >= TC_QUAL_DIFF) { - /* The expression has always the new type */ - ReplaceType (Expr, NewType); - } else if (IsCastType (NewType)) { - /* Convert functions and arrays to "pointer to" object */ - Expr->Type = PtrConversion (Expr->Type); - /* Convert the value */ - DoConversion (Expr, NewType); + /* Only allow casts to arithmetic, pointer or void types */ + if (IsCastType (NewType)) { + if (!IsIncompleteESUType (NewType)) { + /* Convert functions and arrays to "pointer to" object */ + Expr->Type = PtrConversion (Expr->Type); + + if (TypeCmp (NewType, Expr->Type) >= TC_QUAL_DIFF) { + /* If the new type only differs in qualifiers, just use it to + ** replace the old one. + */ + ReplaceType (Expr, NewType); + } else if (IsCastType (Expr->Type)) { + /* Convert the value. The rsult has always the new type */ + DoConversion (Expr, NewType); + } else { + TypeCompatibilityDiagnostic (NewType, Expr->Type, 1, + "Cast to incompatible type '%s' from '%s'"); + } + } else { + Error ("Cast to incomplete type '%s'", + GetFullTypeName (NewType)); + } } else { - Error ("Arithmetic or pointer type expected but '%s' is used", - GetFullTypeName (NewType)); + Error ("Arithmetic or pointer type expected but %s is used", + GetBasicTypeName (NewType)); } } From 63fa9a5a429385fceba1d97f8dfdbf92accb21fd Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 22 Aug 2020 01:30:52 +0800 Subject: [PATCH 1614/2161] Fixed usage of "lvalue-cast" in _scanf implementation. --- libsrc/common/_scanf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libsrc/common/_scanf.c b/libsrc/common/_scanf.c index c18f1e289..ac89e3cb3 100644 --- a/libsrc/common/_scanf.c +++ b/libsrc/common/_scanf.c @@ -183,7 +183,7 @@ static void PushBack (void) asm ("jsr pushax"); /* Copy D into the zero-page. */ - (const struct scanfdata*) __AX__ = D_; + __AX__ = (unsigned) D_; asm ("sta ptr1"); asm ("stx ptr1+1"); @@ -272,7 +272,7 @@ static void __fastcall__ Error (unsigned char /* Code */) /* Does a longjmp using the given code */ { asm ("pha"); - (char*) __AX__ = JumpBuf; + __AX__ = (unsigned) JumpBuf; asm ("jsr pushax"); asm ("pla"); asm ("ldx #>$0000"); @@ -389,7 +389,7 @@ static void AssignInt (void) if (NoAssign == false) { /* Get the next argument pointer */ - (void*) __AX__ = va_arg (ap, void*); + __AX__ = (unsigned) va_arg (ap, void*); /* Put the argument pointer into the zero-page. */ asm ("sta ptr1"); @@ -468,7 +468,7 @@ static char GetFormat (void) /* Pick up the next character from the format string. */ { /* return (F = *format++); */ - (const char*) __AX__ = format; + __AX__ = (unsigned) format; asm ("sta regsave"); asm ("stx regsave+1"); ++format; From d1995fc81aee6047a05418f89d4ee57a73fcb09c Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 15 Aug 2020 06:27:11 +0800 Subject: [PATCH 1615/2161] Fixed rvalue-ness of cast results. --- src/cc65/typeconv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 3af092d42..0f67db107 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -370,4 +370,7 @@ void TypeCast (ExprDesc* Expr) Error ("Arithmetic or pointer type expected but %s is used", GetBasicTypeName (NewType)); } + + /* The result is always an rvalue */ + ED_MarkExprAsRVal (Expr); } From c3a6b399456937093eda9994f19b7f722731528d Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 20 Aug 2020 07:56:11 +0800 Subject: [PATCH 1616/2161] Made struct assignment less hackish. --- src/cc65/assignment.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index 0151a9000..6acab3fe8 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -95,10 +95,13 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) /* Store it into the location referred in the primary */ Store (LExpr, stype); + /* Value is in primary as an rvalue */ + ED_FinalizeRValLoad (LExpr); + } else { - /* The only way this can happen is in chained assignments */ - if (!ED_IsLocPrimary (RExpr)) { + /* The rhs cannot happen to be loaded in the primary as it is too big */ + if (!ED_IsLocExpr (RExpr)) { ED_AddrExpr (RExpr); LoadExpr (CF_NONE, RExpr); } @@ -112,16 +115,19 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) /* Call the memcpy function */ g_call (CF_FIXARGC, Func_memcpy, 4); + /* The result is an rvalue referenced in the primary */ + ED_FinalizeRValLoad (LExpr); + /* Restore the indirection level of lhs */ ED_IndExpr (LExpr); - - /* Clear the tested flag set during loading. This is not neccessary - ** currently (and probably ever) as a struct/union cannot be converted - ** to a boolean in C, but there is no harm to be future-proof. - */ - ED_MarkAsUntested (LExpr); } + /* Clear the tested flag set during loading. This is not neccessary + ** currently (and probably ever) as a struct/union cannot be converted + ** to a boolean in C, but there is no harm to be future-proof. + */ + ED_MarkAsUntested (LExpr); + return 1; } @@ -247,6 +253,9 @@ void Assignment (ExprDesc* Expr) /* Restore the expression type */ Expr->Type = ltype; + /* Value is in primary as an rvalue */ + ED_FinalizeRValLoad (Expr); + } else { /* Get the address on stack if needed */ @@ -264,8 +273,8 @@ void Assignment (ExprDesc* Expr) /* Generate a store instruction */ Store (Expr, 0); - } + /* Value is in primary as an rvalue */ + ED_FinalizeRValLoad (Expr); - /* Value might be still in primary and not an lvalue */ - ED_FinalizeRValLoad (Expr); + } } From 4b7cd491e3631e7e827f7d416ef38d17ac5c341f Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Mon, 24 Aug 2020 16:33:50 +0200 Subject: [PATCH 1617/2161] Move #1209 test from err/ to misc/ misc/ is the correct place for tests that should compile but do not. Revert err/Makefile changes from #1210. --- test/err/Makefile | 8 ++++---- test/misc/Makefile | 6 ++++++ test/{err => misc}/bug1209-ind-goto-rev.c | 0 3 files changed, 10 insertions(+), 4 deletions(-) rename test/{err => misc}/bug1209-ind-goto-rev.c (100%) diff --git a/test/err/Makefile b/test/err/Makefile index 6fa53a1db..1273bbb2c 100644 --- a/test/err/Makefile +++ b/test/err/Makefile @@ -23,23 +23,23 @@ ifdef QUIET NULLERR = 2>$(NULLDEV) endif -CL65 := $(if $(wildcard ../../bin/cl65*),..$S..$Sbin$Scl65,cl65) +CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65) WORKDIR = ../../testwrk/err .PHONY: all clean SOURCES := $(wildcard *.c) -TESTS = $(patsubst %.c,$(WORKDIR)/%.prg,$(SOURCES)) +TESTS = $(patsubst %.c,$(WORKDIR)/%.s,$(SOURCES)) all: $(TESTS) $(WORKDIR): $(call MKDIR,$(WORKDIR)) -$(WORKDIR)/%.prg: %.c | $(WORKDIR) +$(WORKDIR)/%.s: %.c | $(WORKDIR) $(if $(QUIET),echo err/$*.s) - $(NOT) $(CL65) -o $@ $< $(NULLERR) + $(NOT) $(CC65) -o $@ $< $(NULLERR) clean: @$(call RMDIR,$(WORKDIR)) diff --git a/test/misc/Makefile b/test/misc/Makefile index b21384b68..80cbcdf9e 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -75,6 +75,12 @@ $(WORKDIR)/bug760.$1.$2.prg: bug760.c | $(WORKDIR) $(if $(QUIET),echo misc/bug760.$1.$2.prg) $(NOT) $(CL65) -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." + $(if $(QUIET),echo misc/bug1209-ind-goto-rev.$1.$2.prg) + $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + # should compile, but gives an error $(WORKDIR)/pptest2.$1.$2.prg: pptest2.c | $(WORKDIR) @echo "FIXME: " $$@ "currently does not compile." diff --git a/test/err/bug1209-ind-goto-rev.c b/test/misc/bug1209-ind-goto-rev.c similarity index 100% rename from test/err/bug1209-ind-goto-rev.c rename to test/misc/bug1209-ind-goto-rev.c From d38e5858f01f67e3ad096135312de8a9e7814a74 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Mon, 24 Aug 2020 10:01:58 +0200 Subject: [PATCH 1618/2161] Add tests for #1211 CL_MoveRefs: Add CHECK (E->JumpTo != NULL) to make failure clearer. --- src/cc65/codelab.c | 1 + test/err/bug1211-ice-move-refs-1.c | 52 ++++++++++++++++++++++++++++++ test/err/bug1211-ice-move-refs-2.c | 51 +++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 test/err/bug1211-ice-move-refs-1.c create mode 100644 test/err/bug1211-ice-move-refs-2.c diff --git a/src/cc65/codelab.c b/src/cc65/codelab.c index f36520835..ff26645dc 100644 --- a/src/cc65/codelab.c +++ b/src/cc65/codelab.c @@ -112,6 +112,7 @@ void CL_MoveRefs (CodeLabel* OldLabel, CodeLabel* NewLabel) CodeEntry* E = CL_GetRef (OldLabel, Count); /* Change the reference to the new label */ + CHECK (E->JumpTo != NULL); CHECK (E->JumpTo == OldLabel); CL_AddRef (NewLabel, E); diff --git a/test/err/bug1211-ice-move-refs-1.c b/test/err/bug1211-ice-move-refs-1.c new file mode 100644 index 000000000..f28d1fcbc --- /dev/null +++ b/test/err/bug1211-ice-move-refs-1.c @@ -0,0 +1,52 @@ +/* + Copyright 2020 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 indirect goto with label merge ICE. + https://github.com/cc65/cc65/issues/1211 + This should compile and should be moved to tests/val/ when the bug is fixed. +*/ + +#include <stdio.h> + +/* When operating correctly, f(0) = 31 and f(1) = 41. */ +int f (int x) +{ + static const void *const labels[] = {&&L0, &&L1}; + goto *labels[x]; +L0: if (labels[0] != labels[1]) return 31; + else return 13; +L1: return 41; +} + +static unsigned char failures = 0; + +int main (void) +{ + if (f (0) != 31) failures++; + + if (failures == 0) { + printf ("PASS\n"); + } else { + printf ("FAIL\n"); + } + + return failures; +} diff --git a/test/err/bug1211-ice-move-refs-2.c b/test/err/bug1211-ice-move-refs-2.c new file mode 100644 index 000000000..504433f45 --- /dev/null +++ b/test/err/bug1211-ice-move-refs-2.c @@ -0,0 +1,51 @@ +/* + Copyright 2020 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 indirect goto with label merge ICE. + https://github.com/cc65/cc65/issues/1211 + This should compile and should be moved to tests/val/ when the bug is fixed. +*/ + +#include <stdio.h> + +/* When operating correctly, this returns 0. */ +int f (void) +{ + static const void *const x[2] = {&&L0, &&L1}; + goto *x[0]; +L0: +L1: return 0; +} + +static unsigned char failures = 0; + +int main (void) +{ + if (f () != 0) failures++; + + if (failures == 0) { + printf ("PASS\n"); + } else { + printf ("FAIL\n"); + } + + return failures; +} From 344aea06693130a41f348a56f3e85337b15bb96a Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sun, 23 Aug 2020 21:50:54 +0200 Subject: [PATCH 1619/2161] Add additional test cases for #1209 These test cases don't use dynamic labels. https://github.com/cc65/cc65/issues/1209#issuecomment-678738971 Also update the original test case for consistency: * Change failure message to just "FAIL", as there is only one failure * Outdent label definitions * Clarify description --- test/misc/Makefile | 12 +++++++ test/misc/bug1209-ind-goto-rev-2.c | 54 ++++++++++++++++++++++++++++++ test/misc/bug1209-ind-goto-rev-3.c | 52 ++++++++++++++++++++++++++++ test/misc/bug1209-ind-goto-rev.c | 6 ++-- 4 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 test/misc/bug1209-ind-goto-rev-2.c create mode 100644 test/misc/bug1209-ind-goto-rev-3.c diff --git a/test/misc/Makefile b/test/misc/Makefile index 80cbcdf9e..b28fc4d06 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -81,6 +81,18 @@ $(WORKDIR)/bug1209-ind-goto-rev.$1.$2.prg: bug1209-ind-goto-rev.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1209-ind-goto-rev.$1.$2.prg) $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) +# should compile, but gives an error +$(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) + $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + +# should compile, but gives an error +$(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) + $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + # should compile, but gives an error $(WORKDIR)/pptest2.$1.$2.prg: pptest2.c | $(WORKDIR) @echo "FIXME: " $$@ "currently does not compile." diff --git a/test/misc/bug1209-ind-goto-rev-2.c b/test/misc/bug1209-ind-goto-rev-2.c new file mode 100644 index 000000000..8918e5878 --- /dev/null +++ b/test/misc/bug1209-ind-goto-rev-2.c @@ -0,0 +1,54 @@ +/* + Copyright 2020 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 indirect goto without dynamic labels and order label def, label ref, goto. + https://github.com/cc65/cc65/issues/1209 + This should compile and should be moved to tests/val/ when the bug is fixed. +*/ + +#include <stdio.h> +#include <stdlib.h> + +/* When operating correctly, this returns 0. */ +static unsigned char y = 0; +int f (void) { +L: if (y) return 0; + { + static const void *const x[1] = {&&L}; + y = 1; + goto *x[0]; + } +} + +static unsigned char failures = 0; + +int main (void) +{ + if (f () != 0) failures++; + + if (failures == 0) { + printf ("PASS\n"); + } else { + printf ("FAIL\n"); + } + + return failures; +} diff --git a/test/misc/bug1209-ind-goto-rev-3.c b/test/misc/bug1209-ind-goto-rev-3.c new file mode 100644 index 000000000..4c3268c9a --- /dev/null +++ b/test/misc/bug1209-ind-goto-rev-3.c @@ -0,0 +1,52 @@ +/* + Copyright 2020 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 indirect goto without dynamic labels and order label ref, label def, goto. + https://github.com/cc65/cc65/issues/1209 + This should compile and should be moved to tests/val/ when the bug is fixed. +*/ + +#include <stdio.h> +#include <stdlib.h> + +/* When operating correctly, this returns 0. */ +static unsigned char y = 0; +int f (void) { + static const void *const x[1] = {&&L}; +L: if (y) return 0; + y = 1; + goto *x[0]; +} + +static unsigned char failures = 0; + +int main (void) +{ + if (f () != 0) failures++; + + if (failures == 0) { + printf ("PASS\n"); + } else { + printf ("FAIL\n"); + } + + return failures; +} diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/misc/bug1209-ind-goto-rev.c index 39d8639bd..ab8213a30 100644 --- a/test/misc/bug1209-ind-goto-rev.c +++ b/test/misc/bug1209-ind-goto-rev.c @@ -19,7 +19,7 @@ */ /* - Tests of indirect goto with the label before the goto. + Test of indirect goto with dynamic labels and order label def, label ref, goto. https://github.com/cc65/cc65/issues/1209 This should compile and should be moved to tests/val/ when the bug is fixed. */ @@ -32,7 +32,7 @@ int f (void) { static void *x[1]; /* Define the label before referencing it with indirect label syntax. */ - L: if (x[0] != 0) return 0; +L: if (x[0] != 0) return 0; x[0] = &&L; goto *x[0]; } @@ -46,7 +46,7 @@ int main (void) if (failures == 0) { printf ("PASS\n"); } else { - printf ("FAIL: %d failures\n", failures); + printf ("FAIL\n"); } return failures; From d68925c6a8708e0bf2d4ca825bac8ded2f0af903 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 25 Aug 2020 22:34:25 +0800 Subject: [PATCH 1620/2161] Bug #1113 was fixed long ago. --- test/{misc => err}/bug1113.c | 0 test/misc/Makefile | 7 ------- 2 files changed, 7 deletions(-) rename test/{misc => err}/bug1113.c (100%) diff --git a/test/misc/bug1113.c b/test/err/bug1113.c similarity index 100% rename from test/misc/bug1113.c rename to test/err/bug1113.c diff --git a/test/misc/Makefile b/test/misc/Makefile index b28fc4d06..f4beec452 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -99,13 +99,6 @@ $(WORKDIR)/pptest2.$1.$2.prg: pptest2.c | $(WORKDIR) $(if $(QUIET),echo misc/pptest2.$1.$2.prg) $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) -# this should fail to compile, because there are errors in the code -# instead, the compiler crashes -$(WORKDIR)/bug1113.$1.$2.prg: bug1113.c | $(WORKDIR) - @echo "FIXME: " $$@ "compiler crashes but should give an error." - $(if $(QUIET),echo misc/bug1113.$1.$2.prg) - $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - # 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) From b6a4715a38932c928db839bd511bb957c74788ed Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 26 Aug 2020 08:45:01 +0800 Subject: [PATCH 1621/2161] Added test/ref/pr1220 for testing constant AND/OR code generation. --- test/ref/pr1220.c | 344 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 344 insertions(+) create mode 100644 test/ref/pr1220.c diff --git a/test/ref/pr1220.c b/test/ref/pr1220.c new file mode 100644 index 000000000..c594b5ac2 --- /dev/null +++ b/test/ref/pr1220.c @@ -0,0 +1,344 @@ +/* PR #1220 - test constant AND/OR */ + +#include <stdio.h> + +#define CONTEXT_A(x) do {\ + s = 0, flags = 0, t = (x),\ + printf("%3d %2X: %d\n", s, flags, t);\ + } while (0) + +#define CONTEXT_B(x) do {\ + s = 0, flags = 0,\ + (x ? printf("%3d %2X: 1\n", s, flags) : printf("%3d %2X: 0\n", s, flags));\ + } while (0) + +int s, t; +void *p; +unsigned flags; + +int f(x) +{ + flags |= 1U << s; + ++s; + return x; +} + +#define _A f(a) +#define _B f(b) +#define _C f(c) +#define _D f(d) +#define _T (f(0), -1) +#define _F (f(-1), 0) + +void f0() +{ + printf("f0()\n"); + + CONTEXT_A(_T && _T && _T); + CONTEXT_A(_F && _F && _F); + + CONTEXT_A(_T || _T || _T); + CONTEXT_A(_F || _F || _F); + + CONTEXT_A(_T && _T || _T && _T); + CONTEXT_A(_F && _F || _F && _F); + CONTEXT_A(_T && _F || _T && _F); + CONTEXT_A(_F && _T || _F && _T); + + CONTEXT_A((_T && _T) || (_T && _T)); + CONTEXT_A((_F && _F) || (_F && _F)); + CONTEXT_A((_T && _F) || (_T && _F)); + CONTEXT_A((_F && _T) || (_F && _T)); + + CONTEXT_A((_T || _T) && (_T || _T)); + CONTEXT_A((_F || _F) && (_F || _F)); + CONTEXT_A((_T || _F) && (_T || _F)); + CONTEXT_A((_F || _T) && (_F || _T)); + + printf("\n"); +} + +void f1(int a, int b, int c) +{ + printf("f1(%d, %d, %d)\n", a, b, c); + + CONTEXT_A(_A && _B && _C); + + CONTEXT_A(_T && _B && _C); + CONTEXT_A(_A && _T && _C); + CONTEXT_A(_A && _B && _T); + + CONTEXT_A(_F && _B && _C); + CONTEXT_A(_A && _F && _C); + CONTEXT_A(_A && _B && _F); + + CONTEXT_A(_T && _T && _C); + CONTEXT_A(_A && _T && _T); + CONTEXT_A(_T && _B && _T); + + printf("\n"); +} + +void f2(int a, int b, int c) +{ + printf("f2(%d, %d, %d)\n", a, b, c); + + CONTEXT_A(_A || _B || _C); + + CONTEXT_A(_T || _B || _C); + CONTEXT_A(_A || _T || _C); + CONTEXT_A(_A || _B || _T); + + CONTEXT_A(_F || _B || _C); + CONTEXT_A(_A || _F || _C); + CONTEXT_A(_A || _B || _F); + + CONTEXT_A(_F || _F || _C); + CONTEXT_A(_A || _F || _F); + CONTEXT_A(_F || _B || _F); + + printf("\n"); +} + +void f3(int a, int b, int c, int d) +{ + printf("f3(%d, %d, %d, %d)\n", a, b, c, d); + + CONTEXT_A(_A && _B || _C && _D); + CONTEXT_A(_T && _T || _C && _D); + CONTEXT_A(_A && _B || _T && _T); + + CONTEXT_A(_T && _B || _C && _D); + CONTEXT_A(_A && _T || _C && _D); + CONTEXT_A(_A && _B || _T && _D); + CONTEXT_A(_A && _B || _C && _T); + + CONTEXT_A(_F && _B || _C && _D); + CONTEXT_A(_A && _F || _C && _D); + CONTEXT_A(_A && _B || _F && _D); + CONTEXT_A(_A && _B || _C && _F); + + printf("\n"); +} + +void f4(int a, int b, int c, int d) +{ + printf("f4(%d, %d, %d, %d)\n", a, b, c, d); + + CONTEXT_A((_A && _B) || (_C && _D)); + CONTEXT_A((_T && _T) || (_C && _D)); + CONTEXT_A((_A && _B) || (_T && _T)); + + CONTEXT_A((_T && _B) || (_C && _D)); + CONTEXT_A((_A && _T) || (_C && _D)); + CONTEXT_A((_A && _B) || (_T && _D)); + CONTEXT_A((_A && _B) || (_C && _T)); + + CONTEXT_A((_F && _B) || (_C && _D)); + CONTEXT_A((_A && _F) || (_C && _D)); + CONTEXT_A((_A && _B) || (_F && _D)); + CONTEXT_A((_A && _B) || (_C && _F)); + + printf("\n"); +} + +void f5(int a, int b, int c, int d) +{ + printf("f5(%d, %d, %d, %d)\n", a, b, c, d); + + CONTEXT_A((_A || _B) && (_C || _D)); + CONTEXT_A((_F || _F) && (_C || _D)); + CONTEXT_A((_A || _B) && (_F || _F)); + + CONTEXT_A((_T || _B) && (_C || _D)); + CONTEXT_A((_A || _T) && (_C || _D)); + CONTEXT_A((_A || _B) && (_T || _D)); + CONTEXT_A((_A || _B) && (_C || _T)); + + CONTEXT_A((_F || _B) && (_C || _D)); + CONTEXT_A((_A || _F) && (_C || _D)); + CONTEXT_A((_A || _B) && (_F || _D)); + CONTEXT_A((_A || _B) && (_C || _F)); + + printf("\n"); +} + +void f0_B() +{ + printf("f0()\n"); + + CONTEXT_B(_T && _T && _T); + CONTEXT_B(_F && _F && _F); + + CONTEXT_B(_T || _T || _T); + CONTEXT_B(_F || _F || _F); + + CONTEXT_B(_T && _T || _T && _T); + CONTEXT_B(_F && _F || _F && _F); + CONTEXT_B(_T && _F || _T && _F); + CONTEXT_B(_F && _T || _F && _T); + + CONTEXT_B((_T && _T) || (_T && _T)); + CONTEXT_B((_F && _F) || (_F && _F)); + CONTEXT_B((_T && _F) || (_T && _F)); + CONTEXT_B((_F && _T) || (_F && _T)); + + CONTEXT_B((_T || _T) && (_T || _T)); + CONTEXT_B((_F || _F) && (_F || _F)); + CONTEXT_B((_T || _F) && (_T || _F)); + CONTEXT_B((_F || _T) && (_F || _T)); + + printf("\n"); +} + +void f1_B(int a, int b, int c) +{ + printf("f1(%d, %d, %d)\n", a, b, c); + + CONTEXT_B(_A && _B && _C); + + CONTEXT_B(_T && _B && _C); + CONTEXT_B(_A && _T && _C); + CONTEXT_B(_A && _B && _T); + + CONTEXT_B(_F && _B && _C); + CONTEXT_B(_A && _F && _C); + CONTEXT_B(_A && _B && _F); + + CONTEXT_B(_T && _T && _C); + CONTEXT_B(_A && _T && _T); + CONTEXT_B(_T && _B && _T); + + printf("\n"); +} + +void f2_B(int a, int b, int c) +{ + printf("f2(%d, %d, %d)\n", a, b, c); + + CONTEXT_B(_A || _B || _C); + + CONTEXT_B(_T || _B || _C); + CONTEXT_B(_A || _T || _C); + CONTEXT_B(_A || _B || _T); + + CONTEXT_B(_F || _B || _C); + CONTEXT_B(_A || _F || _C); + CONTEXT_B(_A || _B || _F); + + CONTEXT_B(_F || _F || _C); + CONTEXT_B(_A || _F || _F); + CONTEXT_B(_F || _B || _F); + + printf("\n"); +} + +void f3_B(int a, int b, int c, int d) +{ + printf("f3(%d, %d, %d, %d)\n", a, b, c, d); + + CONTEXT_B(_A && _B || _C && _D); + CONTEXT_B(_T && _T || _C && _D); + CONTEXT_B(_A && _B || _T && _T); + + CONTEXT_B(_T && _B || _C && _D); + CONTEXT_B(_A && _T || _C && _D); + CONTEXT_B(_A && _B || _T && _D); + CONTEXT_B(_A && _B || _C && _T); + + CONTEXT_B(_F && _B || _C && _D); + CONTEXT_B(_A && _F || _C && _D); + CONTEXT_B(_A && _B || _F && _D); + CONTEXT_B(_A && _B || _C && _F); + + printf("\n"); +} + +void f4_B(int a, int b, int c, int d) +{ + printf("f4(%d, %d, %d, %d)\n", a, b, c, d); + + CONTEXT_B((_A && _B) || (_C && _D)); + CONTEXT_B((_T && _T) || (_C && _D)); + CONTEXT_B((_A && _B) || (_T && _T)); + + CONTEXT_B((_T && _B) || (_C && _D)); + CONTEXT_B((_A && _T) || (_C && _D)); + CONTEXT_B((_A && _B) || (_T && _D)); + CONTEXT_B((_A && _B) || (_C && _T)); + + CONTEXT_B((_F && _B) || (_C && _D)); + CONTEXT_B((_A && _F) || (_C && _D)); + CONTEXT_B((_A && _B) || (_F && _D)); + CONTEXT_B((_A && _B) || (_C && _F)); + + printf("\n"); +} + +void f5_B(int a, int b, int c, int d) +{ + printf("f5(%d, %d, %d, %d)\n", a, b, c, d); + + CONTEXT_B((_A || _B) && (_C || _D)); + CONTEXT_B((_F || _F) && (_C || _D)); + CONTEXT_B((_A || _B) && (_F || _F)); + + CONTEXT_B((_T || _B) && (_C || _D)); + CONTEXT_B((_A || _T) && (_C || _D)); + CONTEXT_B((_A || _B) && (_T || _D)); + CONTEXT_B((_A || _B) && (_C || _T)); + + CONTEXT_B((_F || _B) && (_C || _D)); + CONTEXT_B((_A || _F) && (_C || _D)); + CONTEXT_B((_A || _B) && (_F || _D)); + CONTEXT_B((_A || _B) && (_C || _F)); + + printf("\n"); +} + +int main() +{ + f0(); + + f1(0, 0, 0); + f2(0, 0, 0); + f3(0, 0, 0, 0); + f4(0, 0, 0, 0); + f5(0, 0, 0, 0); + + f1(1, 1, 1); + f2(1, 1, 1); + f3(1, 1, 1, 1); + f4(1, 1, 1, 1); + f5(1, 1, 1, 1); + + f3(1, 0, 1, 0); + f4(1, 0, 1, 0); + f5(1, 0, 1, 0); + f3(0, 1, 0, 1); + f4(0, 1, 0, 1); + f5(0, 1, 0, 1); + + f0_B(); + + f1_B(0, 0, 0); + f2_B(0, 0, 0); + f3_B(0, 0, 0, 0); + f4_B(0, 0, 0, 0); + f5_B(0, 0, 0, 0); + + f1_B(1, 1, 1); + f2_B(1, 1, 1); + f3_B(1, 1, 1, 1); + f4_B(1, 1, 1, 1); + f5_B(1, 1, 1, 1); + + f3_B(1, 0, 1, 0); + f4_B(1, 0, 1, 0); + f5_B(1, 0, 1, 0); + f3_B(0, 1, 0, 1); + f4_B(0, 1, 0, 1); + f5_B(0, 1, 0, 1); + + return 0; +} From c216b3534b0a419b8fcad55e0c94dca2c7705d0c Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 26 Aug 2020 13:36:43 +0200 Subject: [PATCH 1622/2161] fix compilation, fixes issue #1184 --- testcode/lib/scanf-test.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/testcode/lib/scanf-test.c b/testcode/lib/scanf-test.c index 9fce01b77..f17b62294 100644 --- a/testcode/lib/scanf-test.c +++ b/testcode/lib/scanf-test.c @@ -14,9 +14,7 @@ /* Define USE_STDIO, when you want to use the stdio functions. ** Do not define it, when you want to use the conio functions. */ -/* #define USE_STDIO -*/ #include <stdio.h> #include <string.h> @@ -35,22 +33,23 @@ #define ARRAYSIZE(a) (sizeof (a) / sizeof (a)[0]) +typedef enum { + INT, + CHAR +} TYPE; + +typedef union { + int nvalue; + const char *svalue; +} VALUE; + static const struct { const char *input, *format; int rvalue; - enum TYPE { - INT, - CHAR - } type1; - union { - int nvalue; - const char *svalue; - } v1; - enum TYPE type2; - union { - int nvalue; - const char *svalue; - } v2; + TYPE type1; + VALUE v1; + TYPE type2; + VALUE v2; } test_data[] = { /* Input sequences for character specifiers must be less than 80 characters ** long. These format strings are allowwed a maximum of two assignment From e5a1755133b679c2cd67de9c64f0a05b7aa83b8b Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 26 Aug 2020 15:08:17 +0200 Subject: [PATCH 1623/2161] added some ifdefs to make testcode compile for apple2 and atari targets --- testcode/lib/dir-test.c | 16 +++++++++++++--- testcode/lib/heaptest.c | 7 ++++--- testcode/lib/mouse-test.c | 2 +- testcode/lib/strdup-test.c | 6 ++++-- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/testcode/lib/dir-test.c b/testcode/lib/dir-test.c index 9102fc74d..61e42247e 100644 --- a/testcode/lib/dir-test.c +++ b/testcode/lib/dir-test.c @@ -19,9 +19,13 @@ #include <string.h> #include <errno.h> #include <dirent.h> -#include <cbm.h> #include <conio.h> +#if defined(__CBM__) +#include <cbm.h> +#elif defined(__APPLE2__) +#include <apple2.h> +#endif int main(void) { @@ -51,9 +55,13 @@ int main(void) printf("contents of \"%s\":\n", name); while ((E = readdir (D)) != 0) { printf ("dirent.d_name[] : \"%s\"\n", E->d_name); +#if !defined(__ATARI__) printf ("dirent.d_blocks : %10u\n", E->d_blocks); +#endif printf ("dirent.d_type : %10d\n", E->d_type); +#if !defined(__APPLE2__) && !defined(__ATARI__) printf ("telldir() : %10lu\n", telldir (D)); +#endif printf ("---\n"); if (!go) { switch (cgetc ()) { @@ -63,14 +71,16 @@ int main(void) case 'q': goto done; - +#if !defined(__APPLE2__) && !defined(__ATARI__) case 'r': seekdir (D, E->d_off); break; - +#endif +#if !defined(__ATARI__) case 's': rewinddir (D); break; +#endif } } diff --git a/testcode/lib/heaptest.c b/testcode/lib/heaptest.c index d776e2f0c..560694bee 100644 --- a/testcode/lib/heaptest.c +++ b/testcode/lib/heaptest.c @@ -214,10 +214,10 @@ int main (void) /* Show info at start */ ShowInfo (); - +#if !defined(__APPLE2__) /* Remember the time */ T = clock (); - +#endif /* Do the tests */ Test1 (); Test2 (); @@ -226,10 +226,11 @@ int main (void) Test5 (); Test6 (); +#if !defined(__APPLE2__) /* Calculate the time and print it */ T = clock () - T; printf ("Time needed: %lu ticks\n", T); - +#endif /* Done */ return EXIT_SUCCESS; } diff --git a/testcode/lib/mouse-test.c b/testcode/lib/mouse-test.c index ea8311d19..64482b937 100644 --- a/testcode/lib/mouse-test.c +++ b/testcode/lib/mouse-test.c @@ -190,7 +190,7 @@ int main (void) #endif /* Set dark-on-light colors. Clear the screen. */ -#ifdef __CBM__ +#if defined(__CBM__) && !defined(__VIC20__) (void) bordercolor (COLOR_GRAY2); (void) bgcolor (COLOR_WHITE); (void) textcolor (COLOR_GRAY1); diff --git a/testcode/lib/strdup-test.c b/testcode/lib/strdup-test.c index e30841c3e..2fcc9816f 100644 --- a/testcode/lib/strdup-test.c +++ b/testcode/lib/strdup-test.c @@ -84,19 +84,21 @@ int main (void) /* Show info at start */ ShowInfo (); - +#if !defined(__APPLE2__) /* Remember the time */ T = clock (); - +#endif /* Do the tests */ FillArray (); ShowInfo (); FreeArray (); ShowInfo (); +#if !defined(__APPLE2__) /* Calculate the time and print it */ T = clock () - T; printf ("Time needed: %lu ticks\n", T); +#endif /* Done */ return EXIT_SUCCESS; From 83cc1151121d775cef368fffa3c15bf4b13bbf03 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 26 Aug 2020 15:51:20 +0200 Subject: [PATCH 1624/2161] re-add define for pad bits hw address, which was accidently removed in some refactor commit --- include/gamate.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/gamate.h b/include/gamate.h index 0af21623d..8b9790e39 100644 --- a/include/gamate.h +++ b/include/gamate.h @@ -170,6 +170,8 @@ /* No support for dynamically loadable drivers */ #define DYN_DRV 0 +#define JOY_DATA 0x4400 /* hw register to read the pad bits from */ + /* Masks for joy_read */ #define JOY_UP_MASK 0x01 #define JOY_DOWN_MASK 0x02 From 4c912a0fbe3ff74be793c09d7eee9ae92fe9bbad Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 26 Aug 2020 15:59:52 +0200 Subject: [PATCH 1625/2161] make gamate testcode compile again --- testcode/lib/gamate/ctest.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/testcode/lib/gamate/ctest.c b/testcode/lib/gamate/ctest.c index 793770cee..bff3f5986 100644 --- a/testcode/lib/gamate/ctest.c +++ b/testcode/lib/gamate/ctest.c @@ -25,19 +25,19 @@ int main(int argc, char *argv[]) gotoxy(0,2);cprintf("%04x %02x %02x %02x", n, x, y, *((unsigned char*)JOY_DATA)); switch((*((unsigned char*)JOY_DATA))) { - case 0xff ^ JOY_DATA_UP: + case 0xff ^ JOY_UP_MASK: ++y; if (y == 0xc8) y = 0; break; - case 0xff ^ JOY_DATA_DOWN: + case 0xff ^ JOY_DOWN_MASK: --y; if (y == 0xff) y = 0xc7; break; - case 0xff ^ JOY_DATA_LEFT: + case 0xff ^ JOY_LEFT_MASK: ++x; break; - case 0xff ^ JOY_DATA_RIGHT: + case 0xff ^ JOY_RIGHT_MASK: --x; break; - case 0xff ^ JOY_DATA_FIRE_A: + case 0xff ^ JOY_BTN_A_MASK: break; } From c658acbf850e32508ea0e14f0f62d675a009c7d9 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 26 Aug 2020 20:37:28 +0200 Subject: [PATCH 1626/2161] Avoid cl65 in tests. cl65 creates intermediate files based on the source file name in the source file directory. Calling cl65 in parallel with the same source file causes those intermediate files to get overwritten. Fixes #1080 --- test/asm/Makefile | 27 ++++++++++++-------------- test/dasm/Makefile | 11 ++++------- test/misc/Makefile | 48 ++++++++++++++++++++++------------------------ test/ref/Makefile | 19 +++++++++--------- test/todo/Makefile | 11 ++++++----- test/val/Makefile | 16 ++++++---------- 6 files changed, 61 insertions(+), 71 deletions(-) diff --git a/test/asm/Makefile b/test/asm/Makefile index 94a925376..b157bb672 100644 --- a/test/asm/Makefile +++ b/test/asm/Makefile @@ -8,23 +8,22 @@ ifdef CMD_EXE EXE = .exe MKDIR = mkdir $(subst /,\,$1) RMDIR = -rmdir /s /q $(subst /,\,$1) - DEL = del /f $(subst /,\,$1) else EXE = MKDIR = mkdir -p $1 RMDIR = $(RM) -r $1 - DEL = $(RM) $1 endif ifdef QUIET .SILENT: endif -CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) +CA65 := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65) +LD65 := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) WORKDIR = ../../testwrk/asm -DIFF = $(WORKDIR)/isequal$(EXE) +ISEQUAL = $(WORKDIR)/isequal$(EXE) CC = gcc CFLAGS = -O2 @@ -44,29 +43,28 @@ all: $(OPCODE_BINS) $(CPUDETECT_BINS) $(WORKDIR): $(call MKDIR,$(WORKDIR)) -$(DIFF): ../isequal.c | $(WORKDIR) +$(ISEQUAL): ../isequal.c | $(WORKDIR) $(CC) $(CFLAGS) -o $@ $< define OPCODE_template -$(WORKDIR)/$1-opcodes.bin: $1-opcodes.s $(DIFF) +$(WORKDIR)/$1-opcodes.bin: $1-opcodes.s $(ISEQUAL) $(if $(QUIET),echo asm/$1-opcodes.bin) - $(CL65) --cpu $1 -t none -l $(WORKDIR)/$1-opcodes.lst -o $$@ $$< - $(DIFF) $$@ $1-opcodes.ref + $(CA65) --cpu $1 -t none -l $(WORKDIR)/$1-opcodes.lst -o $(WORKDIR)/$1-opcodes.o $$< + $(LD65) -t none -o $$@ $(WORKDIR)/$1-opcodes.o none.lib + $(ISEQUAL) $$@ $1-opcodes.ref endef # OPCODE_template $(foreach cpu,$(OPCODE_CPUS),$(eval $(call OPCODE_template,$(cpu)))) -# cpudetect.o is written by multiple rules -.NOTPARALLEL: - define CPUDETECT_template -$(WORKDIR)/$1-cpudetect.bin: cpudetect.s $(DIFF) +$(WORKDIR)/$1-cpudetect.bin: cpudetect.s $(ISEQUAL) $(if $(QUIET),echo asm/$1-cpudetect.bin) - $(CL65) --cpu $1 -t none -l $(WORKDIR)/$1-cpudetect.lst -o $$@ $$< - $(DIFF) $$@ $1-cpudetect.ref + $(CA65) --cpu $1 -t none -l $(WORKDIR)/$1-cpudetect.lst -o $(WORKDIR)/$1-cpudetect.o $$< + $(LD65) -t none -o $$@ $(WORKDIR)/$1-cpudetect.o none.lib + $(ISEQUAL) $$@ $1-cpudetect.ref endef # CPUDETECT_template @@ -74,4 +72,3 @@ $(foreach cpu,$(CPUDETECT_CPUS),$(eval $(call CPUDETECT_template,$(cpu)))) clean: @$(call RMDIR,$(WORKDIR)) - @$(call DEL,$(OPCODE_REFS:.ref=.o) cpudetect.o) diff --git a/test/dasm/Makefile b/test/dasm/Makefile index faa6b7fa0..dc0b57c76 100644 --- a/test/dasm/Makefile +++ b/test/dasm/Makefile @@ -8,12 +8,10 @@ ifdef CMD_EXE EXE = .exe MKDIR = mkdir $(subst /,\,$1) RMDIR = -rmdir /s /q $(subst /,\,$1) - DEL = del /f $(subst /,\,$1) else EXE = MKDIR = mkdir -p $1 RMDIR = $(RM) -r $1 - DEL = $(RM) $1 endif ifdef QUIET @@ -25,7 +23,7 @@ DA65 := $(if $(wildcard ../../bin/da65*),../../bin/da65,da65) WORKDIR = ../../testwrk/dasm -DIFF = $(WORKDIR)/isequal$(EXE) +ISEQUAL = $(WORKDIR)/isequal$(EXE) CC = gcc CFLAGS = -O2 @@ -44,7 +42,7 @@ all: $(BINS) $(WORKDIR): $(call MKDIR,$(WORKDIR)) -$(DIFF): ../isequal.c | $(WORKDIR) +$(ISEQUAL): ../isequal.c | $(WORKDIR) $(CC) $(CFLAGS) -o $@ $< define DISASS_template @@ -55,10 +53,10 @@ $(WORKDIR)/$1-disass.bin: $1-disass.s | $(WORKDIR) $(WORKDIR)/$1-reass.s: $(WORKDIR)/$1-disass.bin $(DA65) --cpu $1 $(START) -o $$@ $$< -$(WORKDIR)/$1-reass.bin: $(WORKDIR)/$1-reass.s $(DIFF) +$(WORKDIR)/$1-reass.bin: $(WORKDIR)/$1-reass.s $(ISEQUAL) $(if $(QUIET),echo dasm/$1-reass.bin) $(CL65) --cpu $1 -t none $(START) -o $$@ $$< - $(DIFF) $$@ $(WORKDIR)/$1-disass.bin + $(ISEQUAL) $$@ $(WORKDIR)/$1-disass.bin endef # DISASS_template @@ -66,4 +64,3 @@ $(foreach cpu,$(CPUS),$(eval $(call DISASS_template,$(cpu)))) clean: @$(call RMDIR,$(WORKDIR)) - @$(call DEL,$(SOURCES:.s=.o)) diff --git a/test/misc/Makefile b/test/misc/Makefile index f4beec452..993a46bd4 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -11,7 +11,6 @@ ifdef CMD_EXE NULLDEV = nul: MKDIR = mkdir $(subst /,\,$1) RMDIR = -rmdir /s /q $(subst /,\,$1) - DEL = del /f $(subst /,\,$1) else S = / NOT = ! @@ -19,7 +18,6 @@ else NULLDEV = /dev/null MKDIR = mkdir -p $1 RMDIR = $(RM) -r $1 - DEL = $(RM) $1 endif ifdef QUIET @@ -30,14 +28,16 @@ endif SIM65FLAGS = -x 200000000 -CL65 := $(if $(wildcard ../../bin/cl65*),..$S..$Sbin$Scl65,cl65) +CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65) +CA65 := $(if $(wildcard ../../bin/ca65*),..$S..$Sbin$Sca65,ca65) +LD65 := $(if $(wildcard ../../bin/ld65*),..$S..$Sbin$Sld65,ld65) SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65) WORKDIR = ..$S..$Stestwrk$Smisc OPTIONS = g O Os Osi Osir Osr Oi Oir Or -DIFF = $(WORKDIR)$Sisequal$(EXE) +ISEQUAL = $(WORKDIR)$Sisequal$(EXE) CC = gcc CFLAGS = -O2 @@ -50,15 +50,10 @@ TESTS += $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).65c02. all: $(TESTS) -# The same input file is processed with different cl65 args, -# but cl65 uses the input file name to make the temp file name, -# and they stomp each other. -.NOTPARALLEL: - $(WORKDIR): $(call MKDIR,$(WORKDIR)) -$(DIFF): ../isequal.c | $(WORKDIR) +$(ISEQUAL): ../isequal.c | $(WORKDIR) $(CC) $(CFLAGS) -o $@ $< define PRG_template @@ -67,61 +62,65 @@ define PRG_template $(WORKDIR)/bug250.$1.$2.prg: bug250.c | $(WORKDIR) @echo "FIXME: " $$@ "currently does not compile." $(if $(QUIET),echo misc/bug250.$1.$2.prg) - $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(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) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(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." $(if $(QUIET),echo misc/bug1209-ind-goto-rev.$1.$2.prg) - $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) # should compile, but gives an error $(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) - $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) # should compile, but gives an error $(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) - $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) # should compile, but gives an error $(WORKDIR)/pptest2.$1.$2.prg: pptest2.c | $(WORKDIR) @echo "FIXME: " $$@ "currently does not compile." $(if $(QUIET),echo misc/pptest2.$1.$2.prg) - $(NOT) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) # 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) - $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(CC65) -t sim$2 -$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) $(NOT) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) # these need reference data that can't be generated by a host-compiled program, # in a useful way -$(WORKDIR)/limits.$1.$2.prg: limits.c $(DIFF) | $(WORKDIR) +$(WORKDIR)/limits.$1.$2.prg: limits.c $(ISEQUAL) | $(WORKDIR) $(if $(QUIET),echo misc/limits.$1.$2.prg) - $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(CC65) -t sim$2 -$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)/limits.$1.$2.out - $(DIFF) $(WORKDIR)/limits.$1.$2.out limits.ref + $(ISEQUAL) $(WORKDIR)/limits.$1.$2.out limits.ref -$(WORKDIR)/goto.$1.$2.prg: goto.c $(DIFF) | $(WORKDIR) +$(WORKDIR)/goto.$1.$2.prg: goto.c $(ISEQUAL) | $(WORKDIR) $(if $(QUIET),echo misc/goto.$1.$2.prg) - $(CL65) -t sim$2 -$1 -o $$@ $$< 2>$(WORKDIR)/goto.$1.$2.out - $(DIFF) $(WORKDIR)/goto.$1.$2.out goto.ref + $(CC65) -t sim$2 -$1 -o $$@ $$< 2>$(WORKDIR)/goto.$1.$2.out + $(ISEQUAL) $(WORKDIR)/goto.$1.$2.out goto.ref # 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) $(CL65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) # $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) endef # PRG_template @@ -131,4 +130,3 @@ $(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option),65c02))) clean: @$(call RMDIR,$(WORKDIR)) - @$(call DEL,$(SOURCES:.c=.o)) diff --git a/test/ref/Makefile b/test/ref/Makefile index f88821f64..5faf9fb19 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -11,14 +11,12 @@ ifdef CMD_EXE NULLDEV = nul: MKDIR = mkdir $(subst /,\,$1) RMDIR = -rmdir /s /q $(subst /,\,$1) - DEL = del /f $(subst /,\,$1) else S = / EXE = NULLDEV = /dev/null MKDIR = mkdir -p $1 RMDIR = $(RM) -r $1 - DEL = $(RM) $1 endif ifdef QUIET @@ -28,14 +26,16 @@ endif SIM65FLAGS = -x 200000000 -CL65 := $(if $(wildcard ../../bin/cl65*),..$S..$Sbin$Scl65,cl65) +CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65) +CA65 := $(if $(wildcard ../../bin/ca65*),..$S..$Sbin$Sca65,ca65) +LD65 := $(if $(wildcard ../../bin/ld65*),..$S..$Sbin$Sld65,ld65) SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65) WORKDIR = ..$S..$Stestwrk$Sref OPTIONS = g O Os Osi Osir Osr Oi Oir Or -DIFF = $(WORKDIR)$Sisequal$(EXE) +ISEQUAL = $(WORKDIR)$Sisequal$(EXE) CC = gcc CFLAGS = -O2 -Wall -W -Wextra -funsigned-char -fwrapv -fno-strict-overflow @@ -57,7 +57,7 @@ $(WORKDIR)/%.ref: %.c | $(WORKDIR) $(CC) $(CFLAGS) -o $(WORKDIR)/$*.host $< $(NULLERR) $(WORKDIR)$S$*.host > $@ -$(DIFF): ../isequal.c | $(WORKDIR) +$(ISEQUAL): ../isequal.c | $(WORKDIR) $(CC) $(CFLAGS) -o $@ $< # "yaccdbg.c" includes "yacc.c". @@ -68,11 +68,13 @@ $(WORKDIR)/yaccdbg.%.prg: yacc.c define PRG_template -$(WORKDIR)/%.$1.$2.prg: %.c $(WORKDIR)/%.ref $(DIFF) +$(WORKDIR)/%.$1.$2.prg: %.c $(WORKDIR)/%.ref $(ISEQUAL) $(if $(QUIET),echo ref/$$*.$1.$2.prg) - $(CL65) -t sim$2 $$(CC65FLAGS) -$1 -o $$@ $$< $(NULLERR) + $(CC65) -t sim$2 $$(CC65FLAGS) -$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)/$$*.$1.$2.out - $(DIFF) $(WORKDIR)/$$*.$1.$2.out $(WORKDIR)/$$*.ref + $(ISEQUAL) $(WORKDIR)/$$*.$1.$2.out $(WORKDIR)/$$*.ref endef # PRG_template @@ -81,4 +83,3 @@ $(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option),65c02))) clean: @$(call RMDIR,$(WORKDIR)) - @$(call DEL,$(SOURCES:.c=.o)) diff --git a/test/todo/Makefile b/test/todo/Makefile index ab5eb598c..17561f8f4 100644 --- a/test/todo/Makefile +++ b/test/todo/Makefile @@ -10,14 +10,12 @@ ifdef CMD_EXE NULLDEV = nul: MKDIR = mkdir $(subst /,\,$1) RMDIR = -rmdir /s /q $(subst /,\,$1) - DEL = del /f $(subst /,\,$1) else S = / NOT = ! NULLDEV = /dev/null MKDIR = mkdir -p $1 RMDIR = $(RM) -r $1 - DEL = $(RM) $1 endif ifdef QUIET @@ -28,7 +26,9 @@ endif SIM65FLAGS = -x 200000000 -CL65 := $(if $(wildcard ../../bin/cl65*),..$S..$Sbin$Scl65,cl65) +CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65) +CA65 := $(if $(wildcard ../../bin/ca65*),..$S..$Sbin$Sca65,ca65) +LD65 := $(if $(wildcard ../../bin/ld65*),..$S..$Sbin$Sld65,ld65) SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65) WORKDIR = ../../testwrk/val @@ -50,7 +50,9 @@ define PRG_template $(WORKDIR)/%.$1.$2.prg: %.c | $(WORKDIR) $(if $(QUIET),echo val/$$*.$1.$2.prg) - $(CL65) -t sim$2 $$(CC65FLAGS) -$1 -o $$@ $$< $(NULLERR) + $(CC65) -t sim$2 $$(CC65FLAGS) -$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) $(NOT) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) endef # PRG_template @@ -60,4 +62,3 @@ $(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option),65c02))) clean: @$(call RMDIR,$(WORKDIR)) - @$(call DEL,$(SOURCES:.c=.o)) diff --git a/test/val/Makefile b/test/val/Makefile index be63cd8da..1a9fa9a45 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -9,13 +9,11 @@ ifdef CMD_EXE NULLDEV = nul: MKDIR = mkdir $(subst /,\,$1) RMDIR = -rmdir /s /q $(subst /,\,$1) - DEL = del /f $(subst /,\,$1) else S = / NULLDEV = /dev/null MKDIR = mkdir -p $1 RMDIR = $(RM) -r $1 - DEL = $(RM) $1 endif ifdef QUIET @@ -26,7 +24,9 @@ endif SIM65FLAGS = -x 5000000000 -CL65 := $(if $(wildcard ../../bin/cl65*),..$S..$Sbin$Scl65,cl65) +CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65) +CA65 := $(if $(wildcard ../../bin/ca65*),..$S..$Sbin$Sca65,ca65) +LD65 := $(if $(wildcard ../../bin/ld65*),..$S..$Sbin$Sld65,ld65) SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65) WORKDIR = ../../testwrk/val @@ -41,11 +41,6 @@ TESTS += $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).65c02. all: $(TESTS) -# The same input file is processed with different cl65 args, -# but cl65 uses the input file name to make the temp file name, -# and they stomp each other. -.NOTPARALLEL: - $(WORKDIR): $(call MKDIR,$(WORKDIR)) @@ -53,7 +48,9 @@ define PRG_template $(WORKDIR)/%.$1.$2.prg: %.c | $(WORKDIR) $(if $(QUIET),echo val/$$*.$1.$2.prg) - $(CL65) -t sim$2 $$(CC65FLAGS) -$1 -o $$@ $$< $(NULLERR) + $(CC65) -t sim$2 $$(CC65FLAGS) -$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) $$@ $(NULLOUT) endef # PRG_template @@ -63,4 +60,3 @@ $(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option),65c02))) clean: @$(call RMDIR,$(WORKDIR)) - @$(call DEL,$(SOURCES:.c=.o)) From c6adf4364fe0ce299a9ef415c3653231045560ad Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 26 Aug 2020 20:53:45 +0200 Subject: [PATCH 1627/2161] make atari testcode compile again, added makefile --- testcode/lib/atari/Makefile | 32 ++++++++++++++++++++++++++++++++ testcode/lib/atari/multi.xex | Bin 157 -> 0 bytes testcode/lib/atari/scrcode.s | 5 +++++ testcode/lib/atari/sys.c | 2 ++ 4 files changed, 39 insertions(+) create mode 100644 testcode/lib/atari/Makefile delete mode 100644 testcode/lib/atari/multi.xex diff --git a/testcode/lib/atari/Makefile b/testcode/lib/atari/Makefile new file mode 100644 index 000000000..e9ec853b8 --- /dev/null +++ b/testcode/lib/atari/Makefile @@ -0,0 +1,32 @@ + +all: charmapping.xex defdev.xex displaylist.xex mem.xex multi.xex ostype.xex \ + scrcode.com sys.xex + +charmapping.xex: charmapping.c + cl65 -t atari -o charmapping.xex charmapping.c +defdev.xex: defdev.c + cl65 -t atari -o defdev.xex defdev.c +displaylist.xex: displaylist.c + cl65 -t atari -o displaylist.xex displaylist.c +mem.xex: mem.c ../getsp.s + cl65 -t atari -o mem.xex mem.c ../getsp.s +multi.xex: multi-xex.s multi-xex.cfg + cl65 -t atari -C multi-xex.cfg multi-xex.s -o multi.xex +ostype.xex: ostype.c + cl65 -t atari -o ostype.xex ostype.c +scrcode.com: scrcode.s + ca65 -t atari -o scrcode.o scrcode.s + ld65 -C atari-asm.cfg -o scrcode.com scrcode.o +sys.xex: sys.c + cl65 -t atari -o sys.xex sys.c + +clean: + $(RM) charmapping.xex + $(RM) defdev.xex + $(RM) displaylist.xex + $(RM) mem.xex + $(RM) multi.xex + $(RM) ostype.xex + $(RM) scrcode.o + $(RM) scrcode.com + $(RM) sys.xex diff --git a/testcode/lib/atari/multi.xex b/testcode/lib/atari/multi.xex deleted file mode 100644 index 7da39ad47af630bef4edab9f21e06b7162e98e88..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 157 zcmezWzkzKz+aiXQbLP4*uVkC+%DnRbTo2~Cp3Eyb=Q=U_ggx=ePfW?oOV<N}*^ihW zGc~XsVLHJi=EjiK#K7jkRsaTWylhO43~UTQppmMRqt8&TU!;@52;#$ln>%(0lQ&>8 UWCEI?$E4@Op!b03Arpfh0RH4B!2kdN diff --git a/testcode/lib/atari/scrcode.s b/testcode/lib/atari/scrcode.s index cd4290781..ba778579b 100644 --- a/testcode/lib/atari/scrcode.s +++ b/testcode/lib/atari/scrcode.s @@ -43,15 +43,20 @@ key: lda CH dispdata: scrcode "fooBa", 'r', $66, 3+4 disp_len = * - dispdata +.export __AUTOSTART__: absolute = 1 .segment "AUTOSTRT" .word $02E0 .word $02E1 .word __CODE_LOAD__+1 +.export __EXEHDR__: absolute = 1 .segment "EXEHDR" .word $FFFF + +.segment "MAINHDR" + .word __CODE_LOAD__ .word __BSS_LOAD__ - 1 diff --git a/testcode/lib/atari/sys.c b/testcode/lib/atari/sys.c index 9ec7aa631..59debd758 100644 --- a/testcode/lib/atari/sys.c +++ b/testcode/lib/atari/sys.c @@ -10,6 +10,8 @@ #include <6502.h> #include <conio.h> +#define IOCB (OS.iocb[0]) + static struct regs regs; static struct __iocb *iocb = &IOCB; /* use IOCB #0 */ From b0d3b19a6a1c1e56589f1453ccb99dcde63257e2 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 26 Aug 2020 20:58:44 +0200 Subject: [PATCH 1628/2161] The bug1209 test fails at link stage. --- test/misc/Makefile | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/test/misc/Makefile b/test/misc/Makefile index 993a46bd4..1f7a788ba 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -74,19 +74,25 @@ $(WORKDIR)/bug760.$1.$2.prg: bug760.c | $(WORKDIR) $(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) - $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLERR) + $(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLERR) + $(NOT) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) # should compile, but gives an error $(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) - $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLERR) + $(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLERR) + $(NOT) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) # should compile, but gives an error $(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) - $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLERR) + $(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLERR) + $(NOT) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) # should compile, but gives an error $(WORKDIR)/pptest2.$1.$2.prg: pptest2.c | $(WORKDIR) From 8649859bc544d9ebb1c4f8215f00cd303a23438b Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 26 Aug 2020 21:28:19 +0200 Subject: [PATCH 1629/2161] added/updated Makefiles, preparing for CI (later) --- testcode/lib/accelerator/Makefile | 31 +++++++++++++++++++- testcode/lib/apple2/Makefile | 33 +++++++++++++++++++++- testcode/lib/atari/Makefile | 47 +++++++++++++++++++++++++------ testcode/lib/atari5200/Makefile | 36 +++++++++++++++++++++++ testcode/lib/gamate/Makefile | 41 +++++++++++++++++++++++---- testcode/lib/pce/Makefile | 29 +++++++++++++++++++ 6 files changed, 200 insertions(+), 17 deletions(-) create mode 100644 testcode/lib/atari5200/Makefile diff --git a/testcode/lib/accelerator/Makefile b/testcode/lib/accelerator/Makefile index 6b90a9556..f4f651535 100644 --- a/testcode/lib/accelerator/Makefile +++ b/testcode/lib/accelerator/Makefile @@ -1,4 +1,30 @@ -CL ?= cl65 +# 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 all: c64-scpu-test.prg c128-scpu-test.prg c64dtv-test.prg \ c64-c128-test.prg c128-test.prg chameleon-test.prg \ @@ -27,3 +53,6 @@ c65-test.prg: c65-test.c turbomaster-test.prg: turbomaster-test.c $(CL) -t c64 turbomaster-test.c -o turbomaster-test.prg + +clean: + $(RM) *.prg diff --git a/testcode/lib/apple2/Makefile b/testcode/lib/apple2/Makefile index 9d551aa62..3ea2463f1 100644 --- a/testcode/lib/apple2/Makefile +++ b/testcode/lib/apple2/Makefile @@ -1,7 +1,33 @@ # For this one see https://applecommander.github.io/ AC ?= ac.jar -CL ?= cl65 +# 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 all: hgr.dsk dhgr.dsk @@ -35,3 +61,8 @@ dhgr.dsk: dhgrshow dhgrshow: dhgrshow.c $(CL) -Oirs -t apple2enh --start-addr 0x4000 -m dhgrshow.map $^ + +clean: + $(RM) hgr.dsk dhgr.dsk + $(RM) hgrshow hgrshow.map + $(RM) hgrtest hgrtest.map diff --git a/testcode/lib/atari/Makefile b/testcode/lib/atari/Makefile index e9ec853b8..a34a5f2d9 100644 --- a/testcode/lib/atari/Makefile +++ b/testcode/lib/atari/Makefile @@ -1,24 +1,53 @@ +# 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 + all: charmapping.xex defdev.xex displaylist.xex mem.xex multi.xex ostype.xex \ scrcode.com sys.xex charmapping.xex: charmapping.c - cl65 -t atari -o charmapping.xex charmapping.c + $(CL) -t atari -o charmapping.xex charmapping.c defdev.xex: defdev.c - cl65 -t atari -o defdev.xex defdev.c + $(CL) -t atari -o defdev.xex defdev.c displaylist.xex: displaylist.c - cl65 -t atari -o displaylist.xex displaylist.c + $(CL) -t atari -o displaylist.xex displaylist.c mem.xex: mem.c ../getsp.s - cl65 -t atari -o mem.xex mem.c ../getsp.s + $(CL) -t atari -o mem.xex mem.c ../getsp.s multi.xex: multi-xex.s multi-xex.cfg - cl65 -t atari -C multi-xex.cfg multi-xex.s -o multi.xex + $(CL) -t atari -C multi-xex.cfg multi-xex.s -o multi.xex ostype.xex: ostype.c - cl65 -t atari -o ostype.xex ostype.c + $(CL) -t atari -o ostype.xex ostype.c scrcode.com: scrcode.s - ca65 -t atari -o scrcode.o scrcode.s - ld65 -C atari-asm.cfg -o scrcode.com scrcode.o +# 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 - cl65 -t atari -o sys.xex sys.c + $(CL) -t atari -o sys.xex sys.c clean: $(RM) charmapping.xex diff --git a/testcode/lib/atari5200/Makefile b/testcode/lib/atari5200/Makefile new file mode 100644 index 000000000..990ced689 --- /dev/null +++ b/testcode/lib/atari5200/Makefile @@ -0,0 +1,36 @@ + +# 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 + +all: hello + +hello: hello.c + $(CL) -t atari5200 -o hello hello.c + +clean: + $(RM) hello diff --git a/testcode/lib/gamate/Makefile b/testcode/lib/gamate/Makefile index 2cf98d189..d4f1b9673 100644 --- a/testcode/lib/gamate/Makefile +++ b/testcode/lib/gamate/Makefile @@ -1,14 +1,42 @@ +# 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 + all: audiotest.bin lcdtest.bin ctest.bin audiotest.bin: audiotest.s - ../../../bin/cl65 -l audiotest.lst -t gamate -o audiotest.bin audiotest.s + $(CL) -l audiotest.lst -t gamate -o audiotest.bin audiotest.s lcdtest.bin: lcdtest.s - ../../../bin/cl65 -l lcdtest.lst -t gamate -o lcdtest.bin lcdtest.s + $(CL) -l lcdtest.lst -t gamate -o lcdtest.bin lcdtest.s ctest.bin: ctest.c - ../../../bin/cl65 -l ctest.lst -t gamate -o ctest.bin ctest.c + $(CL) -l ctest.lst -t gamate -o ctest.bin ctest.c nachtm.bin: nachtm.c - ../../../bin/cl65 -Os -l nachtm.lst -t gamate -o nachtm.bin nachtm.c + $(CL) -Os -l nachtm.lst -t gamate -o nachtm.bin nachtm.c gamate-fixcart nachtm.bin test1: lcdtest.bin @@ -21,5 +49,6 @@ testn: nachtm.bin cd ~/Desktop/mame/winmess/ && wine mess.exe gamate -window -skip_gameinfo -cart ~/Desktop/cc65/github/cc65/testcode/lib/gamate/nachtm.bin clean: - rm -f lcdtest.o audiotest.o ctest.o - rm -f lcdtest.bin audiotest.bin ctest.bin nachtm.bin + $(RM) lcdtest.o audiotest.o ctest.o + $(RM) lcdtest.bin audiotest.bin ctest.bin nachtm.bin + $(RM) audiotest.lst lcdtest.lst ctest.lst diff --git a/testcode/lib/pce/Makefile b/testcode/lib/pce/Makefile index a4a495c9a..0c41778cc 100644 --- a/testcode/lib/pce/Makefile +++ b/testcode/lib/pce/Makefile @@ -1,3 +1,32 @@ + +# 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 + .PHONY: all clean test # Size of cartridge to generate. From f5b1b69376f978223dfabe535f23a5ec03bb3dc2 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 15 Aug 2020 06:27:11 +0800 Subject: [PATCH 1630/2161] Forbid struct/union fields of incomplete types. --- src/cc65/declare.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index ccd4e9004..6c1dbd751 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -911,8 +911,15 @@ static SymEntry* ParseUnionDecl (const char* Name) } } + /* Check for incomplete type */ + if (IsIncompleteESUType (Decl.Type)) { + Error ("Field '%s' has incomplete type '%s'", + Decl.Ident, + GetFullTypeName (Decl.Type)); + } + /* Handle sizes */ - FieldSize = CheckedSizeOf (Decl.Type); + FieldSize = SizeOf (Decl.Type); if (FieldSize > UnionSize) { UnionSize = FieldSize; } @@ -1095,6 +1102,13 @@ static SymEntry* ParseStructDecl (const char* Name) } } + /* Check for incomplete type */ + if (IsIncompleteESUType (Decl.Type)) { + Error ("Field '%s' has incomplete type '%s'", + Decl.Ident, + GetFullTypeName (Decl.Type)); + } + /* Add a field entry to the table */ if (FieldWidth > 0) { /* Full bytes have already been added to the StructSize, @@ -1119,7 +1133,7 @@ static SymEntry* ParseStructDecl (const char* Name) AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize); } if (!FlexibleMember) { - StructSize += CheckedSizeOf (Decl.Type); + StructSize += SizeOf (Decl.Type); } } From 1957dc7a5c36bab15fd2021ce52b5b7e4f2f7479 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 15 Aug 2020 06:27:11 +0800 Subject: [PATCH 1631/2161] Disallowed arrays of incomplete types. Fixed diagnostics on incomplete local arrays. --- src/cc65/compile.c | 21 +++------------ src/cc65/declare.c | 67 ++++++++++++++++++++++++++++++++++++---------- src/cc65/locals.c | 18 ++++++++++--- 3 files changed, 72 insertions(+), 34 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 82dc7ec63..3296968f6 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -140,19 +140,10 @@ static void Parse (void) comma = 0; while (1) { - Declaration Decl; + Declaration Decl; /* Read the next declaration */ ParseDecl (&Spec, &Decl, DM_NEED_IDENT); - if (Decl.Ident[0] == '\0') { - NextToken (); - break; - } - - if ((Decl.StorageClass & SC_FICTITIOUS) == SC_FICTITIOUS) { - /* Failed parsing */ - goto SkipOneDecl; - } /* Check if we must reserve storage for the variable. We do this, ** @@ -163,8 +154,9 @@ static void Parse (void) ** ** This means that "extern int i;" will not get storage allocated. */ - if ((Decl.StorageClass & SC_FUNC) != SC_FUNC && - (Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF) { + if ((Decl.StorageClass & SC_FUNC) != SC_FUNC && + (Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF && + (Decl.StorageClass & SC_FICTITIOUS) != SC_FICTITIOUS) { if ((Spec.Flags & DS_DEF_STORAGE) != 0 || (Decl.StorageClass & (SC_EXTERN|SC_STATIC)) == SC_STATIC || ((Decl.StorageClass & SC_EXTERN) != 0 && @@ -296,7 +288,6 @@ static void Parse (void) } -SkipOneDecl: /* Check for end of declaration list */ if (CurTok.Tok == TOK_COMMA) { NextToken (); @@ -452,10 +443,6 @@ void Compile (const char* FileName) } Sym = GetSymType (GetElementType (Entry->Type)); - if (Size == 0 && Sym != 0 && SymIsDef (Sym)) { - /* Array of 0-size elements */ - Warning ("Array '%s[]' has 0-sized elements", Entry->Name); - } } /* For non-ESU types, Size != 0 */ diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 6c1dbd751..0bfbcedd2 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -457,6 +457,37 @@ static unsigned ParseOneStorageClass (void) +static void CheckArrayElementType (Type* DataType) +/* Check if data type consists of arrays of incomplete element types */ +{ + Type* T = DataType; + + while (T->C != T_END) { + if (IsTypeArray (T)) { + ++T; + if (IsIncompleteESUType (T)) { + /* We cannot have an array of incomplete elements */ + Error ("Array of incomplete element type '%s'", GetFullTypeName (T)); + } else if (SizeOf (T) == 0) { + /* If the array is multi-dimensional, try to get the true + ** element type. + */ + if (IsTypeArray (T)) { + continue; + } + /* We could support certain 0-size element types as an extension */ + if (!IsTypeVoid (T) || IS_Get (&Standard) != STD_CC65) { + Error ("Array of 0-size element type '%s'", GetFullTypeName (T)); + } + } + } else { + ++T; + } + } +} + + + static void ParseStorageClass (DeclSpec* D, unsigned DefStorage) /* Parse a storage class */ { @@ -956,16 +987,16 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { FieldTab = GetSymTab (); LeaveStructLevel (); - /* Empty union is not supported now */ - if (UnionSize == 0) { - Error ("Empty union type '%s' is not supported", Name); - } - /* Return a fictitious symbol if errors occurred during parsing */ if (PrevErrorCount != ErrorCount) { 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); } @@ -1160,16 +1191,16 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { FieldTab = GetSymTab (); LeaveStructLevel (); - /* Empty struct is not supported now */ - if (StructSize == 0) { - Error ("Empty struct type '%s' is not supported", Name); - } - /* Return a fictitious symbol if errors occurred during parsing */ if (PrevErrorCount != ErrorCount) { 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); } @@ -1922,6 +1953,9 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Do several fixes on qualifiers */ FixQualifiers (D->Type); + /* Check if the data type consists of any arrays of forbidden types */ + CheckArrayElementType (D->Type); + /* If we have a function, add a special storage class */ if (IsTypeFunc (D->Type)) { D->StorageClass |= SC_FUNC; @@ -1993,10 +2027,15 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) Error ("Invalid size in declaration (0x%06X)", Size); } } + } - if (PrevErrorCount != ErrorCount) { - /* Don't give storage if the declaration is not parsed correctly */ - D->StorageClass |= SC_DECL | SC_FICTITIOUS; + if (PrevErrorCount != ErrorCount) { + /* Make the declaration fictitious if is is not parsed correctly */ + D->StorageClass |= SC_DECL | SC_FICTITIOUS; + + if (Mode == DM_NEED_IDENT && D->Ident[0] == '\0') { + /* Use a fictitious name for the identifier if it is missing */ + AnonName (D->Ident, "global"); } } } @@ -2242,7 +2281,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) /* Get the array data */ Type* ElementType = GetElementType (T); - unsigned ElementSize = CheckedSizeOf (ElementType); + unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); /* Special handling for a character array initialized by a literal */ diff --git a/src/cc65/locals.c b/src/cc65/locals.c index a21a09e8e..4323943a1 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -172,7 +172,11 @@ static void ParseRegisterDecl (Declaration* Decl, int Reg) /* Cannot allocate a variable of zero size */ if (Size == 0) { - Error ("Variable '%s' has unknown size", Decl->Ident); + if (IsTypeArray (Decl->Type)) { + Error ("Array '%s' has unknown size", Decl->Ident); + } else { + Error ("Variable '%s' has unknown size", Decl->Ident); + } } } @@ -357,7 +361,11 @@ static void ParseAutoDecl (Declaration* Decl) /* Cannot allocate a variable of zero size */ if (Size == 0) { - Error ("Variable '%s' has unknown size", Decl->Ident); + if (IsTypeArray (Decl->Type)) { + Error ("Array '%s' has unknown size", Decl->Ident); + } else { + Error ("Variable '%s' has unknown size", Decl->Ident); + } } } @@ -411,7 +419,11 @@ static void ParseStaticDecl (Declaration* Decl) /* Cannot allocate a variable of zero size */ if (Size == 0) { - Error ("Variable '%s' has unknown size", Decl->Ident); + if (IsTypeArray (Decl->Type)) { + Error ("Array '%s' has unknown size", Decl->Ident); + } else { + Error ("Variable '%s' has unknown size", Decl->Ident); + } } } From 43cb092a68004768baa28cdb41831c1d2d1a52e7 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 22 Aug 2020 05:56:33 +0800 Subject: [PATCH 1632/2161] Fixed CHECK failures on certain usage of incomplete enums. --- src/cc65/datatype.c | 14 +++++++++++--- src/cc65/loadexpr.c | 4 ++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index ad008cfd3..9efb142ee 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -686,7 +686,10 @@ const Type* GetUnderlyingType (const Type* Type) Internal ("Enum tag type error in GetUnderlyingTypeCode"); } - return ((SymEntry*)Type->A.P)->V.E.Type; + /* If incomplete enum type is used, just return its raw type */ + if (((SymEntry*)Type->A.P)->V.E.Type != 0) { + return ((SymEntry*)Type->A.P)->V.E.Type; + } } return Type; @@ -1246,9 +1249,14 @@ Type* IntPromotion (Type* T) ** to unsigned int. */ return IsSignUnsigned (T) ? type_uint : type_int; - } else { - /* Otherwise, the type is not smaller than int, so leave it alone. */ + } else if (!IsIncompleteESUType (T)) { + /* The type is a complete type not smaller than int, so leave it alone. */ return T; + } else { + /* Otherwise, this is an incomplete enum, and there is expceted to be an error already. + ** Assume int to avoid further errors. + */ + return type_int; } } diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index f3a1a6add..07f88acbc 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -142,6 +142,10 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) BitFieldFullWidthFlags |= CF_UNSIGNED; } } else if ((Flags & CF_TYPEMASK) == 0) { + /* If Expr is an incomplete ESY type, bail out */ + if (IsIncompleteESUType (Expr->Type)) { + return; + } Flags |= TypeOf (Expr->Type); } From 8d225c32b194f1bb3e2c1606ec55b41b3eca6c76 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 22 Aug 2020 05:57:12 +0800 Subject: [PATCH 1633/2161] Fixed checks on assignment to incomplete types. --- src/cc65/assignment.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index 6acab3fe8..633083669 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -156,6 +156,11 @@ void Assignment (ExprDesc* Expr) Error ("Assignment to const"); } + /* Check for assignment to incomplete type */ + if (IsIncompleteESUType (ltype)) { + Error ("Assignment to incomplete type '%s'", GetFullTypeName (ltype)); + } + /* Skip the '=' token */ NextToken (); From bb9c2032224a9abd034f8fcb17699048ac351e00 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 15 Aug 2020 07:53:28 +0800 Subject: [PATCH 1634/2161] Fixed integer promotion of unary operations. --- src/cc65/expr.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 12a0c0b57..9f7902284 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1856,8 +1856,8 @@ static void UnaryOp (ExprDesc* Expr) /* Value is not constant */ LoadExpr (CF_NONE, Expr); - /* Get the type of the expression */ - Flags = TypeOf (Expr->Type); + /* Adjust the type of the value */ + Flags = g_typeadjust (TypeOf (Expr->Type), TypeOf (type_int) | CF_CONST); /* Handle the operation */ switch (Tok) { @@ -1870,6 +1870,9 @@ static void UnaryOp (ExprDesc* Expr) /* The result is an rvalue in the primary */ ED_FinalizeRValLoad (Expr); } + + /* Adjust the type of the expression */ + Expr->Type = IntPromotion (Expr->Type); } From bf5384a7124de8b44847f57ae7e209e85de5cc4d Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 26 Aug 2020 22:46:45 +0200 Subject: [PATCH 1635/2161] some more refactoring of Makefiles, preparing for CI --- testcode/assembler/Makefile | 37 ++++++++++++++++++++++ testcode/disasm/Makefile | 58 ++++++++++++++++++++++++++++++++++ testcode/disasm/sample-unix.mk | 28 ---------------- 3 files changed, 95 insertions(+), 28 deletions(-) create mode 100644 testcode/assembler/Makefile create mode 100644 testcode/disasm/Makefile delete mode 100644 testcode/disasm/sample-unix.mk diff --git a/testcode/assembler/Makefile b/testcode/assembler/Makefile new file mode 100644 index 000000000..6cb3fe1f2 --- /dev/null +++ b/testcode/assembler/Makefile @@ -0,0 +1,37 @@ + +# 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 + +all: paramcount.o + +paramcount.o: paramcount.s + $(AS) -o paramcount.o -l paramcount.lst paramcount.s + +clean: + $(RM) paramcount.o + $(RM) paramcount.lst diff --git a/testcode/disasm/Makefile b/testcode/disasm/Makefile new file mode 100644 index 000000000..05e5b8373 --- /dev/null +++ b/testcode/disasm/Makefile @@ -0,0 +1,58 @@ +# Sample makefile using a preprocessor against info files +# and the --sync-lines option + +# 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 + DA = $(CC65_HOME)/bin/da65 +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) + DA := $(if $(wildcard ../../../bin/da65*),../../../bin/da65,da65) +endif + +CPP = env LANG=C cpp +CPPFLAGS = # -DTEST_ERROR + +ASMS = fixed.s bank0.s bank1.s +DAIS = fixed.dai bank0.dai bank1.dai + +.SUFFIXES: .da .dai .s +.PHONY: all clean maintainer-clean +.SECONDARY: $(DAIS) + +.da.dai: + $(CPP) -o $@ $(CPPFLAGS) $< + +.dai.s: + $(DA) --sync-lines -o $@ -i $< image.bin + +all: $(ASMS) + +clean: + $(RM) $(ASMS) + +maintainer-clean: clean + $(RM) $(DAIS) + +$(DAIS): fixed.da diff --git a/testcode/disasm/sample-unix.mk b/testcode/disasm/sample-unix.mk deleted file mode 100644 index 0ef64a5e5..000000000 --- a/testcode/disasm/sample-unix.mk +++ /dev/null @@ -1,28 +0,0 @@ -# Sample makefile using a preprocessor against info files -# and the --sync-lines option - -CPP = env LANG=C cpp -CPPFLAGS = # -DTEST_ERROR - -ASMS = fixed.s bank0.s bank1.s -DAIS = fixed.dai bank0.dai bank1.dai - -.SUFFIXES: .da .dai .s -.PHONY: all clean maintainer-clean -.SECONDARY: $(DAIS) - -.da.dai: - $(CPP) -o $@ $(CPPFLAGS) $< - -.dai.s: - da65 --sync-lines -o $@ -i $< image.bin - -all: $(ASMS) - -clean: - rm -f $(ASMS) - -maintainer-clean: clean - rm -f $(DAIS) - -$(DAIS): fixed.da From 39a3de3119bda406c8a51625b35f20851a02060a Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 26 Aug 2020 22:47:47 +0200 Subject: [PATCH 1636/2161] made geoslib testcode compile again, added the required linker config and a Makefile --- testcode/grc/Makefile | 43 ++++++++++++++++ testcode/grc/geos-cbm-overlay.cfg | 84 +++++++++++++++++++++++++++++++ testcode/grc/vlir0.s | 8 +-- testcode/grc/vlir1.s | 8 +-- testcode/grc/vlir2.s | 8 +-- 5 files changed, 139 insertions(+), 12 deletions(-) create mode 100644 testcode/grc/Makefile create mode 100644 testcode/grc/geos-cbm-overlay.cfg diff --git a/testcode/grc/Makefile b/testcode/grc/Makefile new file mode 100644 index 000000000..4df2f17bc --- /dev/null +++ b/testcode/grc/Makefile @@ -0,0 +1,43 @@ + +# 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 + GRC = $(CC65_HOME)/bin/grc65 +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) + GRC := $(if $(wildcard ../../../bin/grc65*),../../../bin/grc65,grc65) +endif + +all: test.s vlir.cvt + +test.s: test.grc + $(GRC) -s test.s test.grc + +vlir.cvt: vlir.grc + $(GRC) -s vlir.s test.grc + $(CL) -t geos -C geos-cbm-overlay.cfg -o vlir.cvt vlir.s vlir0.s vlir1.s vlir2.s + +clean: + $(RM) test.s test.h + $(RM) vlir.s vlir.cvt diff --git a/testcode/grc/geos-cbm-overlay.cfg b/testcode/grc/geos-cbm-overlay.cfg new file mode 100644 index 000000000..ddf1d1e1f --- /dev/null +++ b/testcode/grc/geos-cbm-overlay.cfg @@ -0,0 +1,84 @@ +FEATURES { + STARTADDRESS: default = $0400; +} +SYMBOLS { + __BACKBUFSIZE__: type = weak, value = $2000; + __HIMEM__: type = weak, value = $8000 - __BACKBUFSIZE__; + __OVERLAYSIZE__: type = weak, value = $1000; + __OVERLAYADDR__: type = weak, value = __HIMEM__ - __OVERLAYSIZE__; + __STACKSIZE__: type = weak, value = $0400; # 1k stack + __STACKADDR__: type = weak, value = __OVERLAYADDR__ - __STACKSIZE__; +} +MEMORY { + CVT: file = %O, start = $0, size = $40000; + ZP: define = yes, start = $58, size = $1A + $06; + VLIR0: define = yes, start = %S, size = __STACKADDR__ - %S; + VLIR1: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR2: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR3: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR4: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR5: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR6: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR7: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR8: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR9: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR10: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR11: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR12: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR13: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR14: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR15: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR16: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR17: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR18: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; + VLIR19: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; +} +SEGMENTS { + ZEROPAGE: type = zp, load = ZP; + EXTZP: type = zp, load = ZP, optional = yes; + DIRENTRY: type = ro, load = CVT, align = $FE; + FILEINFO: type = ro, load = CVT, align = $FE; + RECORDS: type = ro, load = CVT, align = $FE, optional = yes; + STARTUP: type = ro, run = VLIR0, load = CVT, align_load = $FE, define = yes; + LOWCODE: type = ro, run = VLIR0, load = CVT, optional = yes; + ONCE: type = ro, run = VLIR0, load = CVT, optional = yes; + CODE: type = ro, run = VLIR0, load = CVT; + RODATA: type = ro, run = VLIR0, load = CVT; + DATA: type = rw, run = VLIR0, load = CVT; + INIT: type = bss, load = VLIR0, optional = yes; + BSS: type = bss, load = VLIR0, define = yes; + OVERLAY1: type = ro, run = VLIR1, load = CVT, align_load = $FE, optional = yes; + OVERLAY2: type = ro, run = VLIR2, load = CVT, align_load = $FE, optional = yes; + OVERLAY3: type = ro, run = VLIR3, load = CVT, align_load = $FE, optional = yes; + OVERLAY4: type = ro, run = VLIR4, load = CVT, align_load = $FE, optional = yes; + OVERLAY5: type = ro, run = VLIR5, load = CVT, align_load = $FE, optional = yes; + OVERLAY6: type = ro, run = VLIR6, load = CVT, align_load = $FE, optional = yes; + OVERLAY7: type = ro, run = VLIR7, load = CVT, align_load = $FE, optional = yes; + OVERLAY8: type = ro, run = VLIR8, load = CVT, align_load = $FE, optional = yes; + OVERLAY9: type = ro, run = VLIR9, load = CVT, align_load = $FE, optional = yes; + OVERLAY10: type = ro, run = VLIR10, load = CVT, align_load = $FE, optional = yes; + OVERLAY11: type = ro, run = VLIR11, load = CVT, align_load = $FE, optional = yes; + OVERLAY12: type = ro, run = VLIR12, load = CVT, align_load = $FE, optional = yes; + OVERLAY13: type = ro, run = VLIR13, load = CVT, align_load = $FE, optional = yes; + OVERLAY14: type = ro, run = VLIR14, load = CVT, align_load = $FE, optional = yes; + OVERLAY15: type = ro, run = VLIR15, load = CVT, align_load = $FE, optional = yes; + OVERLAY16: type = ro, run = VLIR16, load = CVT, align_load = $FE, optional = yes; + OVERLAY17: type = ro, run = VLIR17, load = CVT, align_load = $FE, optional = yes; + OVERLAY18: type = ro, run = VLIR18, load = CVT, align_load = $FE, optional = yes; + OVERLAY19: type = ro, run = VLIR19, load = CVT, align_load = $FE, optional = 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/testcode/grc/vlir0.s b/testcode/grc/vlir0.s index 2e9a3ffd9..a54d406df 100644 --- a/testcode/grc/vlir0.s +++ b/testcode/grc/vlir0.s @@ -5,10 +5,10 @@ ; include some GEOS defines - .include "../../libsrc/geos/inc/const.inc" - .include "../../libsrc/geos/inc/jumptab.inc" - .include "../../libsrc/geos/inc/geossym.inc" - .include "../../libsrc/geos/inc/geosmac.inc" + .include "../../libsrc/geos-common/const.inc" + .include "../../libsrc/geos-cbm/jumptab.inc" + .include "../../libsrc/geos-cbm/geossym.inc" + .include "../../libsrc/geos-common/geosmac.inc" ; import load addresses for all VLIR chains ; these labels are defined upon linking with ld65 diff --git a/testcode/grc/vlir1.s b/testcode/grc/vlir1.s index eae34565e..6ee3cca37 100644 --- a/testcode/grc/vlir1.s +++ b/testcode/grc/vlir1.s @@ -5,10 +5,10 @@ ; include some GEOS defines - .include "../../libsrc/geos/inc/const.inc" - .include "../../libsrc/geos/inc/jumptab.inc" - .include "../../libsrc/geos/inc/geossym.inc" - .include "../../libsrc/geos/inc/geosmac.inc" + .include "../../libsrc/geos-common/const.inc" + .include "../../libsrc/geos-cbm/jumptab.inc" + .include "../../libsrc/geos-cbm/geossym.inc" + .include "../../libsrc/geos-common/geosmac.inc" ; export names of functions that will be used in the main program diff --git a/testcode/grc/vlir2.s b/testcode/grc/vlir2.s index 9d180c847..4c02983ff 100644 --- a/testcode/grc/vlir2.s +++ b/testcode/grc/vlir2.s @@ -5,10 +5,10 @@ ; similar to vlir1.s except the fact that this is chain #2 - .include "../../libsrc/geos/inc/const.inc" - .include "../../libsrc/geos/inc/jumptab.inc" - .include "../../libsrc/geos/inc/geossym.inc" - .include "../../libsrc/geos/inc/geosmac.inc" + .include "../../libsrc/geos-common/const.inc" + .include "../../libsrc/geos-cbm/jumptab.inc" + .include "../../libsrc/geos-cbm/geossym.inc" + .include "../../libsrc/geos-common/geosmac.inc" .export OVERLAY2_Function1 .export OVERLAY2_Function2 From c1a514c0f8c6a41b0b971cd772ce724f9dfc888f Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 26 Aug 2020 23:20:28 +0200 Subject: [PATCH 1637/2161] added test related to issue #1201 --- test/val/bug1201.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 test/val/bug1201.c diff --git a/test/val/bug1201.c b/test/val/bug1201.c new file mode 100644 index 000000000..6d194fbee --- /dev/null +++ b/test/val/bug1201.c @@ -0,0 +1,25 @@ + +/* bug #1201 - The unary operators +, - and ~ should do integer promote on the result types. */ + +char a; +short b; +int c; +long d; +enum E { + Z +} e; +struct S { + int a : 1; +} f; + +_Static_assert(sizeof(+a) == sizeof(int), "Result type should be int"); +_Static_assert(sizeof(+b) == sizeof(int), "Result type should be int"); +_Static_assert(sizeof(+c) == sizeof(int), "Result type should be int"); +_Static_assert(sizeof(+d) == sizeof(long), "Result type should be long"); +_Static_assert(sizeof(+e) == sizeof(int), "Result type should be int"); +_Static_assert(sizeof(+f.a) == sizeof(int), "Result type should be int"); + +int main(void) +{ + return 0; +} From 41dbd31b02b00c3b4120b7dfafedc85b6c879dca Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 27 Aug 2020 00:04:34 +0200 Subject: [PATCH 1638/2161] fix makefile, remove the unneeded .cfg again. oops :) --- testcode/grc/Makefile | 17 +++++-- testcode/grc/geos-cbm-overlay.cfg | 84 ------------------------------- 2 files changed, 13 insertions(+), 88 deletions(-) delete mode 100644 testcode/grc/geos-cbm-overlay.cfg diff --git a/testcode/grc/Makefile b/testcode/grc/Makefile index 4df2f17bc..793506890 100644 --- a/testcode/grc/Makefile +++ b/testcode/grc/Makefile @@ -34,10 +34,19 @@ all: test.s vlir.cvt test.s: test.grc $(GRC) -s test.s test.grc -vlir.cvt: vlir.grc - $(GRC) -s vlir.s test.grc - $(CL) -t geos -C geos-cbm-overlay.cfg -o vlir.cvt vlir.s vlir0.s vlir1.s vlir2.s +vlir.cvt: vlir.grc vlir0.s vlir1.s vlir2.s +# using seperate calls here for demonstration purposes: + $(GRC) -t geos-cbm -s vlir.s vlir.grc + $(AS) -t geos-cbm vlir.s + $(AS) -t geos-cbm vlir0.s + $(AS) -t geos-cbm vlir1.s + $(AS) -t geos-cbm vlir2.s + $(LD) -t geos-cbm -o vlir.cvt vlir.o vlir0.o vlir1.o vlir2.o geos-cbm.lib + +# you can also do the above in one command: +# $(CL) -t geos-cbm -o vlir.cvt vlir.grc vlir0.s vlir1.s vlir2.s clean: $(RM) test.s test.h - $(RM) vlir.s vlir.cvt + $(RM) vlir.s vlir.cvt vlir.c vlir.h + $(RM) *.o diff --git a/testcode/grc/geos-cbm-overlay.cfg b/testcode/grc/geos-cbm-overlay.cfg deleted file mode 100644 index ddf1d1e1f..000000000 --- a/testcode/grc/geos-cbm-overlay.cfg +++ /dev/null @@ -1,84 +0,0 @@ -FEATURES { - STARTADDRESS: default = $0400; -} -SYMBOLS { - __BACKBUFSIZE__: type = weak, value = $2000; - __HIMEM__: type = weak, value = $8000 - __BACKBUFSIZE__; - __OVERLAYSIZE__: type = weak, value = $1000; - __OVERLAYADDR__: type = weak, value = __HIMEM__ - __OVERLAYSIZE__; - __STACKSIZE__: type = weak, value = $0400; # 1k stack - __STACKADDR__: type = weak, value = __OVERLAYADDR__ - __STACKSIZE__; -} -MEMORY { - CVT: file = %O, start = $0, size = $40000; - ZP: define = yes, start = $58, size = $1A + $06; - VLIR0: define = yes, start = %S, size = __STACKADDR__ - %S; - VLIR1: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR2: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR3: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR4: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR5: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR6: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR7: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR8: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR9: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR10: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR11: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR12: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR13: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR14: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR15: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR16: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR17: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR18: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; - VLIR19: define = yes, start = __OVERLAYADDR__, size = __OVERLAYSIZE__; -} -SEGMENTS { - ZEROPAGE: type = zp, load = ZP; - EXTZP: type = zp, load = ZP, optional = yes; - DIRENTRY: type = ro, load = CVT, align = $FE; - FILEINFO: type = ro, load = CVT, align = $FE; - RECORDS: type = ro, load = CVT, align = $FE, optional = yes; - STARTUP: type = ro, run = VLIR0, load = CVT, align_load = $FE, define = yes; - LOWCODE: type = ro, run = VLIR0, load = CVT, optional = yes; - ONCE: type = ro, run = VLIR0, load = CVT, optional = yes; - CODE: type = ro, run = VLIR0, load = CVT; - RODATA: type = ro, run = VLIR0, load = CVT; - DATA: type = rw, run = VLIR0, load = CVT; - INIT: type = bss, load = VLIR0, optional = yes; - BSS: type = bss, load = VLIR0, define = yes; - OVERLAY1: type = ro, run = VLIR1, load = CVT, align_load = $FE, optional = yes; - OVERLAY2: type = ro, run = VLIR2, load = CVT, align_load = $FE, optional = yes; - OVERLAY3: type = ro, run = VLIR3, load = CVT, align_load = $FE, optional = yes; - OVERLAY4: type = ro, run = VLIR4, load = CVT, align_load = $FE, optional = yes; - OVERLAY5: type = ro, run = VLIR5, load = CVT, align_load = $FE, optional = yes; - OVERLAY6: type = ro, run = VLIR6, load = CVT, align_load = $FE, optional = yes; - OVERLAY7: type = ro, run = VLIR7, load = CVT, align_load = $FE, optional = yes; - OVERLAY8: type = ro, run = VLIR8, load = CVT, align_load = $FE, optional = yes; - OVERLAY9: type = ro, run = VLIR9, load = CVT, align_load = $FE, optional = yes; - OVERLAY10: type = ro, run = VLIR10, load = CVT, align_load = $FE, optional = yes; - OVERLAY11: type = ro, run = VLIR11, load = CVT, align_load = $FE, optional = yes; - OVERLAY12: type = ro, run = VLIR12, load = CVT, align_load = $FE, optional = yes; - OVERLAY13: type = ro, run = VLIR13, load = CVT, align_load = $FE, optional = yes; - OVERLAY14: type = ro, run = VLIR14, load = CVT, align_load = $FE, optional = yes; - OVERLAY15: type = ro, run = VLIR15, load = CVT, align_load = $FE, optional = yes; - OVERLAY16: type = ro, run = VLIR16, load = CVT, align_load = $FE, optional = yes; - OVERLAY17: type = ro, run = VLIR17, load = CVT, align_load = $FE, optional = yes; - OVERLAY18: type = ro, run = VLIR18, load = CVT, align_load = $FE, optional = yes; - OVERLAY19: type = ro, run = VLIR19, load = CVT, align_load = $FE, optional = 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 7a453d1f901da8d0686d30b13d6bd672e471a39c Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 27 Aug 2020 00:08:22 +0200 Subject: [PATCH 1639/2161] add a "disk" target to build the disk images as suggested by Oliver --- testcode/lib/apple2/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/testcode/lib/apple2/Makefile b/testcode/lib/apple2/Makefile index 3ea2463f1..0020b4ec5 100644 --- a/testcode/lib/apple2/Makefile +++ b/testcode/lib/apple2/Makefile @@ -29,7 +29,9 @@ else LD := $(if $(wildcard ../../../bin/ld65*),../../../bin/ld65,ld65) endif -all: hgr.dsk dhgr.dsk +all: hgrshow hgrtest dhgrshow + +disk: hgr.dsk dhgr.dsk hgr.dsk: hgrshow hgrtest cp prodos.dsk $@ @@ -66,3 +68,4 @@ clean: $(RM) hgr.dsk dhgr.dsk $(RM) hgrshow hgrshow.map $(RM) hgrtest hgrtest.map + $(RM) dhgrshow dhgrshow.map From f34644186f0dd55b647acc9171e1b1d9b4f42bd7 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 27 Aug 2020 01:19:33 +0200 Subject: [PATCH 1640/2161] build a bogus "ROM image" that can be disassembled, fix the makefile, remove generated files --- testcode/disasm/Makefile | 17 +++++++++-------- testcode/disasm/bank0.dai | 33 --------------------------------- testcode/disasm/bank1.dai | 33 --------------------------------- testcode/disasm/fixed.da | 2 +- testcode/disasm/fixed.dai | 25 ------------------------- testcode/disasm/image.cfg | 15 +++++++++++++++ 6 files changed, 25 insertions(+), 100 deletions(-) delete mode 100644 testcode/disasm/bank0.dai delete mode 100644 testcode/disasm/bank1.dai delete mode 100644 testcode/disasm/fixed.dai create mode 100644 testcode/disasm/image.cfg diff --git a/testcode/disasm/Makefile b/testcode/disasm/Makefile index 05e5b8373..61b37e314 100644 --- a/testcode/disasm/Makefile +++ b/testcode/disasm/Makefile @@ -31,15 +31,17 @@ else DA := $(if $(wildcard ../../../bin/da65*),../../../bin/da65,da65) endif -CPP = env LANG=C cpp -CPPFLAGS = # -DTEST_ERROR +CPP = cpp +#CPPFLAGS = -DTEST_ERROR ASMS = fixed.s bank0.s bank1.s DAIS = fixed.dai bank0.dai bank1.dai .SUFFIXES: .da .dai .s -.PHONY: all clean maintainer-clean -.SECONDARY: $(DAIS) + +all: image.bin $(ASMS) + +$(DAIS): fixed.da .da.dai: $(CPP) -o $@ $(CPPFLAGS) $< @@ -47,12 +49,11 @@ DAIS = fixed.dai bank0.dai bank1.dai .dai.s: $(DA) --sync-lines -o $@ -i $< image.bin -all: $(ASMS) +image.bin: image.s image.cfg + $(CL) -t none -C image.cfg -o image.bin image.s clean: $(RM) $(ASMS) - -maintainer-clean: clean $(RM) $(DAIS) + $(RM) image.bin -$(DAIS): fixed.da diff --git a/testcode/disasm/bank0.dai b/testcode/disasm/bank0.dai deleted file mode 100644 index 2d865e77c..000000000 --- a/testcode/disasm/bank0.dai +++ /dev/null @@ -1,33 +0,0 @@ -# 1 "bank0.da" -# 1 "<built-in>" -# 1 "<command-line>" -# 1 "bank0.da" - - - - -global { - inputoffs $00010; - inputsize $4000; - startaddr $8000; - cpu "6502"; -}; - -# 1 "fixed.da" 1 -# 18 "fixed.da" -label { addr $00; name "VariableA"; }; -label { addr $01; name "VariableB"; }; -label { addr $0100; name "Stack"; size $0100; }; - - - - - -label { addr $C000; name "CommonProcA"; }; -label { addr $C123; name "CommonProcB"; }; -range { start $E123; end $FFFF; name "CommonData"; type ByteTable; }; -# 13 "bank0.da" 2 - -label { addr $8000; name "Bank0ProcA"; }; -label { addr $8123; name "Bank0ProcB"; }; -range { start $A000; end $BFFF; name "Bank0Data"; type ByteTable; }; diff --git a/testcode/disasm/bank1.dai b/testcode/disasm/bank1.dai deleted file mode 100644 index 2b5b68532..000000000 --- a/testcode/disasm/bank1.dai +++ /dev/null @@ -1,33 +0,0 @@ -# 1 "bank1.da" -# 1 "<built-in>" -# 1 "<command-line>" -# 1 "bank1.da" - - - - -global { - inputoffs $04010; - inputsize $4000; - startaddr $8000; - cpu "6502"; -}; - -# 1 "fixed.da" 1 -# 18 "fixed.da" -label { addr $00; name "VariableA"; }; -label { addr $01; name "VariableB"; }; -label { addr $0100; name "Stack"; size $0100; }; - - - - - -label { addr $C000; name "CommonProcA"; }; -label { addr $C123; name "CommonProcB"; }; -range { start $E123; end $FFFF; name "CommonData"; type ByteTable; }; -# 13 "bank1.da" 2 - -range { start $8000; end $AFFF; name "Bank1Data"; type ByteTable; }; -label { addr $B000; name "Bank1ProcA"; }; -label { addr $B123; name "Bank1ProcB"; }; diff --git a/testcode/disasm/fixed.da b/testcode/disasm/fixed.da index e8aa03427..f8ad4ba27 100644 --- a/testcode/disasm/fixed.da +++ b/testcode/disasm/fixed.da @@ -7,7 +7,7 @@ #ifndef TARGET_BANK #define TARGET_BANK -1 global { - inputoffs $1C010; + inputoffs $0C010; inputsize $4000; startaddr $C000; cpu "6502"; diff --git a/testcode/disasm/fixed.dai b/testcode/disasm/fixed.dai deleted file mode 100644 index d73155cf0..000000000 --- a/testcode/disasm/fixed.dai +++ /dev/null @@ -1,25 +0,0 @@ -# 1 "fixed.da" -# 1 "<built-in>" -# 1 "<command-line>" -# 1 "fixed.da" -# 9 "fixed.da" -global { - inputoffs $1C010; - inputsize $4000; - startaddr $C000; - cpu "6502"; -}; - - - -label { addr $00; name "VariableA"; }; -label { addr $01; name "VariableB"; }; -label { addr $0100; name "Stack"; size $0100; }; - - - - - -label { addr $C000; name "CommonProcA"; }; -label { addr $C123; name "CommonProcB"; }; -range { start $E123; end $FFFF; name "CommonData"; type ByteTable; }; diff --git a/testcode/disasm/image.cfg b/testcode/disasm/image.cfg new file mode 100644 index 000000000..2225c722f --- /dev/null +++ b/testcode/disasm/image.cfg @@ -0,0 +1,15 @@ + +MEMORY { + HEADER: file = %O, start = $0000, size = $0010, fill = yes; + BANK00: file = %O, start = $8000, size = $4000, fill = yes; + BANK01: file = %O, start = $8000, size = $4000, fill = yes; + BANK02: file = %O, start = $8000, size = $4000, fill = yes; + FIXED: file = %O, start = $c000, size = $4000, fill = yes; +} +SEGMENTS { + HDR: load = HEADER, type = rw, optional = yes, define = yes; + BANK0: load = BANK00, type = rw, optional = yes, define = yes; + BANK1: load = BANK01, type = rw, optional = yes, define = yes; + BANK2: load = BANK02, type = rw, optional = yes, define = yes; + FIX: load = FIXED, type = rw, optional = yes, define = yes; +} From 4008ab556cd725cc7d24f5b443d3224b2d8957eb Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 27 Aug 2020 01:34:18 +0200 Subject: [PATCH 1641/2161] added a Makefile --- samples/tutorial/Makefile | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 samples/tutorial/Makefile diff --git a/samples/tutorial/Makefile b/samples/tutorial/Makefile new file mode 100644 index 000000000..8ed91697f --- /dev/null +++ b/samples/tutorial/Makefile @@ -0,0 +1,40 @@ + +# Run 'make SYS=<target>'; or, set a SYS env. +# var. to build for another target system. +SYS ?= c64 + +# 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 + +all: hello + +hello: hello.c text.s + $(CL) -t $(SYS) -o hello hello.c text.s + +clean: + $(RM) hello From 5e2d2a54f631c3d3855c927d11dd8f39506fb986 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 27 Aug 2020 14:25:33 +0200 Subject: [PATCH 1642/2161] added makefile for the GEOS samples. geosconio.c and rmvprot.c do not compile right now, someone with more GEOS knowledge should look at them --- samples/geos/Makefile | 82 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 samples/geos/Makefile diff --git a/samples/geos/Makefile b/samples/geos/Makefile new file mode 100644 index 000000000..32a28e118 --- /dev/null +++ b/samples/geos/Makefile @@ -0,0 +1,82 @@ + +# Run 'make SYS=<target>'; or, set a SYS env. +# var. to build for another target system. +SYS ?= geos-cbm + +# 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 + SP = $(CC65_HOME)/bin/sp65 +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) + SP := $(if $(wildcard ../bin/sp65*),../bin/sp65,sp65) +endif + +# omitted: dialog.c grphstr.c inittab.c menu.c + +# TODO: geosconio.cvt rmvprot.cvt +all: bitmap-demo.cvt filesel.cvt geosver.cvt getid.cvt hello1.cvt hello2.cvt \ + overlay-demo.cvt vector-demo.cvt yesno.cvt + +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 + $(CL) -t $(SYS) -O -o bitmap-demo.cvt -m bitmap-demo.map bitmap-demores.grc bitmap-demo.c + +filesel.cvt: fileselres.grc filesel.c + $(CL) -t $(SYS) -O -o filesel.cvt -m filesel.map fileselres.grc filesel.c + +geosconio.cvt: geosconiores.grc geosconio.c + $(CL) -t $(SYS) -O -o geosconio.cvt -m geosconio.map geosconiores.grc geosconio.c + +geosver.cvt: geosverres.grc geosver.c + $(CL) -t $(SYS) -O -o geover.cvt -m geosver.map geosverres.grc geosver.c + +getid.cvt: getidres.grc getid.c + $(CL) -t $(SYS) -O -o getid.cvt -m getid.map getidres.grc getid.c + +hello1.cvt: hello1res.grc hello1.c + $(CL) -t $(SYS) -O -o hello1.cvt -m hello1.map hello1res.grc hello1.c + +hello2.cvt: hello2res.grc hello2.c + $(CL) -t $(SYS) -O -o hello2.cvt -m hello2.map hello2res.grc hello2.c + +overlay-demo.cvt: overlay-demores.grc overlay-demo.c + $(CL) -t $(SYS) -O -o overlay-demo.cvt -m overlay-demo.map overlay-demores.grc overlay-demo.c + +rmvprot.cvt: rmvprotres.grc rmvprot.c + $(CL) -t $(SYS) -O -o rmvprot.cvt -m rmvprot.map rmvprotres.grc rmvprot.c + +vector-demo.cvt: vector-demores.grc vector-demo.c + $(CL) -t $(SYS) -O -o vector-demo.cvt -m vector-demo.map vector-demores.grc vector-demo.c + +yesno.cvt: yesnores.grc yesno.c + $(CL) -t $(SYS) -O -o yesno.cvt -m yesno.map yesnores.grc yesno.c + + +clean: + $(RM) bitmap.c + $(RM) *.cvt + $(RM) *.map From 5158ee2092442ad458ccf2a522b8a8fd8b6f4099 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 27 Aug 2020 14:50:00 +0200 Subject: [PATCH 1643/2161] preliminary makefile to build all programs in the testcode directory --- testcode/lib/Makefile | 395 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 395 insertions(+) create mode 100644 testcode/lib/Makefile diff --git a/testcode/lib/Makefile b/testcode/lib/Makefile new file mode 100644 index 000000000..33f725f6a --- /dev/null +++ b/testcode/lib/Makefile @@ -0,0 +1,395 @@ +# +# Makefile for cc65 testcode +# +# This Makefile requires GNU make +# + +# Run 'make SYS=<target>'; or, set a SYS env. +# var. to build for another target system. +SYS ?= c64 + +# Just the usual way to define a variable +# containing a single space character. +SPACE := +SPACE += + +# 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 + +ifneq ($(filter disk testcode.%,$(MAKECMDGOALS)),) + ifdef CC65_HOME + TARGET_PATH = $(CC65_HOME)/target + else + TARGET_PATH := $(if $(wildcard ../target),../target,$(shell $(CL) --print-target-path)) + endif + + # If TARGET_PATH contains spaces then it is presumed to contain escaped spaces. GNU make + # has very limited support for paths containing spaces. $(wildcard) is the only function + # that is aware of escaped spaces. However, $(wildcard) never returns paths with escaped + # spaces !!! So if it e.g. finds 4 files in a path with 2 spaces then one ends up with a + # return value consisting of 12 plain words :-(( + # + # Fortunately we can work around that behaviour here because we know that the files we + # are looking for have known extensions. So we can $(filter) the in our example above 12 + # words for file extensions so we come up with 4 path fragments. Then we remove those + # path fragments with $(notdir) from the file names. + # + # So far so good. But here we want to process files from different paths in a single + # recipe further down below and therefore want to prepend the paths to the files with + # $(addprefix). However, $(foreach) isn't aware of escaped spaces (only $(wildcard) is). + # Therefore, we need to replace the spaces with some other character temporarily in order + # to have $(foreach) generate one invocation per file. We use the character '?' for that + # purpose here, just because it is known to not be part of file names. + # + # Inside the recipe generated per file we then replace the '?' again with a space. As we + # want to be compatible with cmd.exe for execution we're not using an escaped space but + # rather double-quote the whole path. + # + # Note: The "strange" $(wildcard) further down below just serves the purpose to unescape + # spaces for cmd.exe. This could have as well been done with another $(subst). + + SUBST_TARGET_PATH := $(subst \$(SPACE),?,$(TARGET_PATH)) + + EMD := $(wildcard $(TARGET_PATH)/$(SYS)/drv/emd/*) + MOU := $(wildcard $(TARGET_PATH)/$(SYS)/drv/mou/*) + TGI := $(wildcard $(TARGET_PATH)/$(SYS)/drv/tgi/*) + + 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)))) + + # This one comes with the VICE emulator. + # See http://vice-emu.sourceforge.net/ + C1541 ?= c1541 + + # For this one, see https://applecommander.github.io/ + AC ?= ac.jar + + # For this one, see https://www.horus.com/~hias/atari/ + DIR2ATR ?= dir2atr +endif + +DISK_c64 = testcode.d64 +DISK_apple2 = testcode.dsk +DISK_apple2enh = testcode.dsk +DISK_atari = testcode.atr +DISK_atarixl = testcode.atr + +# -------------------------------------------------------------------------- +# System-dependent settings +# For convenience, these groups and lines are sorted alphabetically, first +# by target-machine group, then by mission, then by program and sub-target. + +# -------------------------------------------------------------------------- +# Generic rules + +.PHONY: all mostlyclean clean zip testcode disk + +%: %.c +%: %.s + +.c.o: + $(CC) $(CFLAGS) -Ors --codesize 500 -T -g -t $(SYS) $< + $(AS) $(<:.c=.s) + +.s.o: + $(AS) $(ASFLAGS) -t $(SYS) $< + +.PRECIOUS: %.o + +.o: +ifeq ($(SYS),vic20) + $(LD) $(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 +endif + +# -------------------------------------------------------------------------- +# Lists of executables + +# omitted: seek +EXELIST_c64 = \ + arg-test \ + clock \ + clock-test \ + conio \ + 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 \ + ser-test \ + strdup-test \ + stroserror-test \ + strqtok-test \ + tinyshell \ + uname-test + +# omitted: seek clock-test mouse-test ser-test +EXELIST_vic20 = \ + arg-test \ + clock \ + conio \ + 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 \ + mul-test \ + posixio-test \ + rename-test \ + scanf-test \ + strdup-test \ + stroserror-test \ + strqtok-test \ + tinyshell \ + uname-test + +# omitted: cpeek-test, clock +EXELIST_apple2 = \ + arg-test \ + clock-test \ + conio \ + 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 \ + stroserror-test \ + strqtok-test \ + tinyshell \ + uname-test + +EXELIST_apple2enh = $(EXELIST_apple2) + +# omitted: cpeek-test +EXELIST_atari = \ + arg-test \ + clock-test \ + clock \ + conio \ + 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 \ + stroserror-test \ + strqtok-test \ + tinyshell \ + uname-test + +EXELIST_atarixl = $(EXELIST_atari) + +# none of the testcode can work on the 2600 +# EXELIST_atari2600 = + +# none of the testcode can work on supervision +# EXELIST_supervision = + +# Unlisted targets will try to build everything. +# That lets us learn what they cannot build, and what settings +# we need to use for programs that can be built and run. +ifndef EXELIST_$(SYS) +EXELIST_$(SYS) := ${patsubst %.c,%,$(wildcard *.c)} +endif + +# -------------------------------------------------------------------------- +# Rules to make the binaries and the disk + +testcode: $(EXELIST_$(SYS)) + +disk: $(DISK_$(SYS)) + +all: testcode + make -C accelerator + make -C apple2 + make -C atari + make -C atari5200 + make -C cbm SYS=$(SYS) + make -C gamate + make -C pce + +# -------------------------------------------------------------------------- +# some programs link against getsp.o + +mouse-test: mouse-test.o getsp.o + $(LD) $(LDFLAGS) -t $(SYS) -o $@ $^ $(SYS).lib + +ifneq ($(SYS),vic20) +ft: ft.o getsp.o + $(LD) $(LDFLAGS) -t $(SYS) -o $@ $^ $(SYS).lib + +tinyshell: tinyshell.o getsp.o + $(LD) $(LDFLAGS) -t $(SYS) -o $@ $^ $(SYS).lib +endif + +# some programs need more memory on the vic20 + +ifeq ($(SYS),vic20) +ft: ft.o getsp.o + $(LD) $(LDFLAGS) -o $@ -C vic20-32k.cfg -m $@.map $^ $(SYS).lib + +tinyshell: tinyshell.o getsp.o + $(LD) $(LDFLAGS) -o $@ -C vic20-32k.cfg -m $@.map $^ $(SYS).lib +endif + +# -------------------------------------------------------------------------- +# Rule to make a CBM disk with all testcode. Needs the c1541 program that comes +# with the VICE emulator. + +define D64_WRITE_recipe + +$(C1541) -attach $@ -write "$(subst ?,$(SPACE),$(file))" $(notdir $(file)) >$(NULLDEV) + +endef # D64_WRITE_recipe + +testcode.d64: testcode + @$(C1541) -format testcode,AA d64 $@ >$(NULLDEV) + $(foreach file,$(EXELIST_$(SYS)),$(D64_WRITE_recipe)) +# $(foreach file,$(EMD) $(MOU) $(TGI),$(D64_WRITE_recipe)) + +# -------------------------------------------------------------------------- +# Rule to make an Apple II disk with all testcode. Needs the AppleCommander +# program, available at https://applecommander.github.io/, and a template disk +# named 'prodos.dsk'. + +define DSK_WRITE_BIN_recipe + +$(if $(findstring BF00,$(LDFLAGS_$(notdir $(file))_$(SYS))), \ + java -jar $(AC) -p $@ $(notdir $(file)).system sys <"$(wildcard $(TARGET_PATH)/$(SYS)/util/loader.system)") +java -jar $(AC) -as $@ $(notdir $(file)) <"$(file)" + +endef # DSK_WRITE_BIN_recipe + +define DSK_WRITE_REL_recipe + +java -jar $(AC) -p $@ $(notdir $(file)) rel 0 <"$(subst ?,$(SPACE),$(file))" + +endef # DSK_WRITE_REL_recipe + +testcode.dsk: testcode + cp prodos.dsk $@ + $(foreach file,$(EXELIST_$(SYS)),$(DSK_WRITE_BIN_recipe)) +# $(foreach file,$(EMD) $(MOU) $(TGI),$(DSK_WRITE_REL_recipe)) + +# -------------------------------------------------------------------------- +# Rule to make an Atari disk with all testcode. Needs the dir2atr program +# available at http://www.horus.com/~hias/atari/ and the MyDos4534 variant +# of dos.sys and dup.sys. + +define ATR_WRITE_recipe + +cp "$(subst ?,$(SPACE),$(file))" atr/$(notdir $(file)) + +endef # ATR_WRITE_recipe + +testcode.atr: testcode + @mkdir atr + cp "dos.sys" atr/dos.sys + cp "dup.sys" atr/dup.sys + @$(foreach file,$(EXELIST_$(SYS)),$(ATR_WRITE_recipe)) +# @$(foreach file,$(EMD) $(MOU) $(TGI),$(ATR_WRITE_recipe)) + $(DIR2ATR) -d -b MyDos4534 3200 $@ atr + @$(RMDIR) atr + +# -------------------------------------------------------------------------- +# Clean-up rules + +mostlyclean: + @$(DEL) *.lbl *.map *.o 2>$(NULLDEV) +# we cant use .s since we have asm files in the directory that we want to keep + @$(DEL) ${patsubst %.c,%.s,$(wildcard *.c)} 2>$(NULLDEV) + +clean: mostlyclean + @$(DEL) $(EXELIST_$(SYS)) $(DISK_$(SYS)) 2>$(NULLDEV) + make -C accelerator clean + make -C apple2 clean + make -C atari clean + make -C atari5200 clean + make -C cbm SYS=$(SYS) clean + make -C gamate clean + make -C pce clean From f54e01781b6d0daa9ba51a642c5a2e4d0bb21d22 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Sat, 29 Aug 2020 16:21:45 +0200 Subject: [PATCH 1644/2161] Tiny optimizations for multiplication. --- libsrc/runtime/lmul.s | 4 ++-- libsrc/runtime/umul8x16r24.s | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/libsrc/runtime/lmul.s b/libsrc/runtime/lmul.s index 860d58cba..d3c34637c 100644 --- a/libsrc/runtime/lmul.s +++ b/libsrc/runtime/lmul.s @@ -63,7 +63,7 @@ L0: lsr tmp4 bcc L1 clc adc ptr3 - pha + tax lda ptr3+1 adc tmp2 sta tmp2 @@ -73,7 +73,7 @@ L0: lsr tmp4 lda ptr4+1 adc tmp4 sta tmp4 - pla + txa L1: dey bpl L0 lda ptr1 ; Load the low result word diff --git a/libsrc/runtime/umul8x16r24.s b/libsrc/runtime/umul8x16r24.s index c006082a4..54d730558 100644 --- a/libsrc/runtime/umul8x16r24.s +++ b/libsrc/runtime/umul8x16r24.s @@ -41,20 +41,19 @@ umul8x16r16m: .endif ldy #8 ; Number of bits - ldx ptr3 ; Get into register for speed lda ptr1 ror a ; Get next bit into carry @L0: bcc @L1 clc - pha - txa + tax + lda ptr3 adc ptr1+1 sta ptr1+1 lda ptr3+1 adc sreg sta sreg - pla + txa @L1: ror sreg ror ptr1+1 From 632da3f4eefc6675484fc547b34c525983ba9d34 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 15 Aug 2020 06:27:11 +0800 Subject: [PATCH 1645/2161] Fixed tracking and checking flexible array members. --- src/cc65/declare.c | 45 ++++++++++++++++++++++++++++++++++----------- src/cc65/symentry.h | 11 +++++++++++ 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0bfbcedd2..d7851bd44 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -963,12 +963,19 @@ static SymEntry* ParseUnionDecl (const char* Name) AddBitField (Decl.Ident, Decl.Type, 0, 0, FieldWidth, SignednessSpecified); } else { + Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0); if (IsAnonName (Decl.Ident)) { - Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0); Entry->V.A.ANumber = UnionTagEntry->V.S.ACount++; AliasAnonStructFields (&Decl, Entry); - } else { - AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0); + } + + /* Check if the field itself has a flexible array member */ + if (IsClassStruct (Decl.Type)) { + SymEntry* Sym = GetSymType (Decl.Type); + if (Sym && SymHasFlexibleArrayMember (Sym)) { + Entry->Flags |= SC_HAVEFAM; + Flags |= SC_HAVEFAM; + } } } @@ -1107,6 +1114,8 @@ static SymEntry* ParseStructDecl (const char* Name) Error ("Flexible array member cannot be first struct field"); } FlexibleMember = 1; + Flags |= SC_HAVEFAM; + /* Assume zero for size calculations */ SetElementCount (Decl.Type, FLEXIBLE); } @@ -1156,13 +1165,21 @@ static SymEntry* ParseStructDecl (const char* Name) StructSize += BitOffs / CHAR_BITS; BitOffs %= CHAR_BITS; } else { + Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize); if (IsAnonName (Decl.Ident)) { - Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize); Entry->V.A.ANumber = StructTagEntry->V.S.ACount++; AliasAnonStructFields (&Decl, Entry); - } else { - AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize); } + + /* Check if the field itself has a flexible array member */ + if (IsClassStruct (Decl.Type)) { + SymEntry* Sym = GetSymType (Decl.Type); + if (Sym && SymHasFlexibleArrayMember (Sym)) { + Entry->Flags |= SC_HAVEFAM; + Flags |= SC_HAVEFAM; + } + } + if (!FlexibleMember) { StructSize += SizeOf (Decl.Type); } @@ -2361,11 +2378,17 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) /* Number of elements determined by initializer */ SetElementCount (T, Count); ElementCount = Count; - } else if (ElementCount == FLEXIBLE && AllowFlexibleMembers) { - /* In non ANSI mode, allow initialization of flexible array - ** members. - */ - ElementCount = Count; + } else if (ElementCount == FLEXIBLE) { + if (AllowFlexibleMembers) { + /* In non ANSI mode, allow initialization of flexible array + ** members. + */ + ElementCount = Count; + } else { + /* Forbid */ + Error ("Initializing flexible array member is forbidden"); + ElementCount = Count; + } } else if (Count < ElementCount) { g_zerobytes ((ElementCount - Count) * ElementSize); } else if (Count > ElementCount && HasCurly) { diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 94fe66032..0224507ac 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -107,6 +107,7 @@ struct CodeEntry; #define SC_ALIAS 0x01000000U /* Alias of anonymous field */ #define SC_FICTITIOUS 0x02000000U /* Symbol is fictitious */ +#define SC_HAVEFAM 0x04000000U /* Type has a Flexible Array Member */ @@ -272,6 +273,16 @@ INLINE int SymIsRegVar (const SymEntry* Sym) 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 */ +{ + return ((Sym->Flags & SC_HAVEFAM) == SC_HAVEFAM); +} +#else +# define SymHasFlexibleArrayMember(Sym) (((Sym)->Flags & SC_HAVEFAM) == SC_HAVEFAM) +#endif + #if defined(HAVE_INLINE) INLINE const char* SymGetAsmName (const SymEntry* Sym) /* Return the assembler label name for the symbol (beware: may be NULL!) */ From 4e61ae5b3620a1003985d53e28d9dd160e51b915 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 15 Aug 2020 06:27:11 +0800 Subject: [PATCH 1646/2161] Fixed function parameter type conversion. --- src/cc65/declare.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index d7851bd44..4e8446176 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1492,13 +1492,27 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, static Type* ParamTypeCvt (Type* T) -/* If T is an array, convert it to a pointer else do nothing. Return the -** resulting type. +/* 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)) { - T->C = T_PTR; + Tmp = ArrayToPtr (T); + } else if (IsTypeFunc (T)) { + Tmp = PointerTo (T); } + + if (Tmp != 0) { + /* Do several fixes on qualifiers */ + FixQualifiers (Tmp); + + /* Replace the type */ + TypeCopy (T, Tmp); + TypeFree (Tmp); + } + return T; } From 0a96ffc8786726ca6d492fd70ceaf5dfdae7b3a7 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 15 Aug 2020 06:27:11 +0800 Subject: [PATCH 1647/2161] Fixed function parameter checking. Fixed function return type checking. --- src/cc65/codeinfo.c | 6 +- src/cc65/declare.c | 20 +----- src/cc65/expr.c | 112 ++++++++++++++++--------------- src/cc65/function.c | 156 ++++++++++++++++++++++++++++++++------------ src/cc65/function.h | 6 ++ src/cc65/stmt.c | 40 +++++++----- 6 files changed, 210 insertions(+), 130 deletions(-) diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 3e1d58709..d7d85a12d 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -410,8 +410,10 @@ fncls_t GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) (AutoCDecl ? IsQualFastcall (E->Type) : !IsQualCDecl (E->Type))) { - /* Will use registers depending on the last param. */ - switch (CheckedSizeOf (D->LastParam->Type)) { + /* Will use registers depending on the last param. If the last + ** param has incomplete type, just assume __EAX__. + */ + switch (SizeOf (D->LastParam->Type)) { case 1u: *Use = REG_A; break; diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 4e8446176..218ba6017 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1704,7 +1704,6 @@ static void ParseAnsiParamList (FuncDesc* F) static FuncDesc* ParseFuncDecl (void) /* Parse the argument list of a function. */ { - unsigned Offs; SymEntry* Sym; SymEntry* WrappedCall; unsigned char WrappedCallData; @@ -1751,23 +1750,10 @@ static FuncDesc* ParseFuncDecl (void) */ F->LastParam = GetSymTab()->SymTail; - /* Assign offsets. If the function has a variable parameter list, - ** there's one additional byte (the arg size). + /* 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. */ - Offs = (F->Flags & FD_VARIADIC)? 1 : 0; - Sym = F->LastParam; - while (Sym) { - unsigned Size = CheckedSizeOf (Sym->Type); - if (SymIsRegVar (Sym)) { - Sym->V.R.SaveOffs = Offs; - } else { - Sym->V.Offs = Offs; - } - Offs += Size; - F->ParamSize += Size; - Sym = Sym->PrevSym; - } - + /* Leave the lexical level remembering the symbol tables */ RememberFunctionLevel (F); diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9f7902284..89c7ff108 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -346,6 +346,9 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) int FrameOffs = 0; /* Offset into parameter frame */ int Ellipsis = 0; /* Function is variadic */ + /* Make sure the size of all parameters are known */ + int ParamComplete = F_CheckParamList (Func, 1); + /* As an optimization, we may allocate the complete parameter frame at ** once instead of pushing into each parameter as it comes. We may do that, ** if... @@ -359,7 +362,7 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) ** (instead of pushing) is enabled. ** */ - if (IS_Get (&CodeSizeFactor) >= 200) { + if (ParamComplete && IS_Get (&CodeSizeFactor) >= 200) { /* Calculate the number and size of the parameters */ FrameParams = Func->ParamCount; @@ -424,65 +427,68 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) /* Evaluate the argument expression */ hie1 (&Expr); - /* If we don't have a prototype, accept anything; otherwise, convert - ** the actual argument to the parameter type needed. - */ - Flags = CF_NONE; - if (!Ellipsis) { - - /* Convert the argument to the parameter type if needed */ - TypeConversion (&Expr, Param->Type); - - /* If we have a prototype, chars may be pushed as chars */ - Flags |= CF_FORCECHAR; - - } else { - - /* No prototype available. Convert array to "pointer to first - ** element", and function to "pointer to function". + /* Skip to the next parameter if there are any incomplete types */ + if (ParamComplete) { + /* If we don't have an argument spec., accept anything; otherwise, + ** convert the actual argument to the type needed. */ - Expr.Type = PtrConversion (Expr.Type); + Flags = CF_NONE; + if (!Ellipsis) { - } + /* Convert the argument to the parameter type if needed */ + TypeConversion (&Expr, Param->Type); - /* Handle struct/union specially */ - if (IsClassStruct (Expr.Type)) { - /* Use the replacement type */ - Flags |= TypeOf (GetStructReplacementType (Expr.Type)); - } else { - /* Use the type of the argument for the push */ - Flags |= TypeOf (Expr.Type); - } + /* If we have a prototype, chars may be pushed as chars */ + Flags |= CF_FORCECHAR; - /* Load the value into the primary if it is not already there */ - LoadExpr (Flags, &Expr); - - /* If this is a fastcall function, don't push the last argument */ - if ((CurTok.Tok == TOK_COMMA && NextTok.Tok != TOK_RPAREN) || !IsFastcall) { - unsigned ArgSize = sizeofarg (Flags); - - if (FrameSize > 0) { - /* We have the space already allocated, store in the frame. - ** Because of invalid type conversions (that have produced an - ** error before), we can end up here with a non-aligned stack - ** frame. Since no output will be generated anyway, handle - ** these cases gracefully instead of doing a CHECK. - */ - if (FrameSize >= ArgSize) { - FrameSize -= ArgSize; - } else { - FrameSize = 0; - } - FrameOffs -= ArgSize; - /* Store */ - g_putlocal (Flags | CF_NOKEEP, FrameOffs, Expr.IVal); } else { - /* Push the argument */ - g_push (Flags, Expr.IVal); + + /* No prototype available. Convert array to "pointer to first + ** element", and function to "pointer to function". + */ + Expr.Type = PtrConversion (Expr.Type); + } - /* Calculate total parameter size */ - PushedSize += ArgSize; + /* Handle struct/union specially */ + if (IsClassStruct (Expr.Type)) { + /* Use the replacement type */ + Flags |= TypeOf (GetStructReplacementType (Expr.Type)); + } else { + /* Use the type of the argument for the push */ + Flags |= TypeOf (Expr.Type); + } + + /* Load the value into the primary if it is not already there */ + LoadExpr (Flags, &Expr); + + /* If this is a fastcall function, don't push the last argument */ + if ((CurTok.Tok == TOK_COMMA && NextTok.Tok != TOK_RPAREN) || !IsFastcall) { + unsigned ArgSize = sizeofarg (Flags); + + if (FrameSize > 0) { + /* We have the space already allocated, store in the frame. + ** Because of invalid type conversions (that have produced an + ** error before), we can end up here with a non-aligned stack + ** frame. Since no output will be generated anyway, handle + ** these cases gracefully instead of doing a CHECK. + */ + if (FrameSize >= ArgSize) { + FrameSize -= ArgSize; + } else { + FrameSize = 0; + } + FrameOffs -= ArgSize; + /* Store */ + g_putlocal (Flags | CF_NOKEEP, FrameOffs, Expr.IVal); + } else { + /* Push the argument */ + g_push (Flags, Expr.IVal); + } + + /* Calculate total parameter size */ + PushedSize += ArgSize; + } } /* Check for end of argument list */ diff --git a/src/cc65/function.c b/src/cc65/function.c index 290916cd2..451efc54d 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -105,6 +105,62 @@ static void FreeFunction (Function* F) +int F_CheckParamList (FuncDesc* D, int RequireAll) +/* Check and set the parameter sizes. +** If RequireAll is true, emit errors on parameters of incomplete types. +** Return true if all parameters have complete types. +*/ +{ + unsigned I = 0; + unsigned Offs; + SymEntry* Param; + unsigned ParamSize = 0; + unsigned IncompleteCount = 0; + + /* Assign offsets. If the function has a variable parameter list, + ** there's one additional byte (the arg size). + */ + Offs = (D->Flags & FD_VARIADIC) ? 1 : 0; + Param = D->LastParam; + while (Param) { + unsigned Size = SizeOf (Param->Type); + if (RequireAll && IsIncompleteESUType (Param->Type)) { + if (D->Flags & FD_UNNAMED_PARAMS) { + Error ("Parameter %u has incomplete type '%s'", + D->ParamCount - I, + GetFullTypeName (Param->Type)); + } else { + Error ("Parameter '%s' has incomplete type '%s'", + Param->Name, + GetFullTypeName (Param->Type)); + } + ++IncompleteCount; + } + if (SymIsRegVar (Param)) { + Param->V.R.SaveOffs = Offs; + } else { + Param->V.Offs = Offs; + } + Offs += Size; + ParamSize += Size; + Param = Param->PrevSym; + ++I; + } + + /* If all parameters have complete types, set the total size description + ** and return true. + */ + if (IncompleteCount == 0) { + D->ParamSize = ParamSize; + return 1; + } + + /* Otherwise return false */ + return 0; +} + + + const char* F_GetFuncName (const Function* F) /* Return the name of the current function */ { @@ -378,9 +434,11 @@ static void F_EmitDebugInfo (void) 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 */ /* Remember this function descriptor used for definition */ GetFuncDesc (Func->Type)->FuncDef = D; @@ -391,6 +449,21 @@ void NewFunc (SymEntry* Func, FuncDesc* D) /* Reenter the lexical level */ ReenterFunctionLevel (D); + /* Check return type */ + ReturnType = F_GetReturnType (CurrentFunc); + if (IsIncompleteESUType (ReturnType)) { + /* There are already diagnostics on returning arrays or functions */ + if (!IsTypeArray (ReturnType) && !IsTypeFunc (ReturnType)) { + Error ("Function has incomplete return type '%s'", + GetFullTypeName (ReturnType)); + } + } + + /* Check and set the parameter sizes. All parameter must have complete + ** types now. + */ + ParamComplete = F_CheckParamList (D, 1); + /* Check if the function header contains unnamed parameters. These are ** only allowed in cc65 mode. */ @@ -429,7 +502,7 @@ void NewFunc (SymEntry* Func, FuncDesc* D) /* If cc65 extensions aren't enabled, don't allow a main function that ** doesn't return an int. */ - if (IS_Get (&Standard) != STD_CC65 && CurrentFunc->ReturnType[0].C != T_INT) { + if (IS_Get (&Standard) != STD_CC65 && ReturnType[0].C != T_INT) { Error ("'main' must always return an int"); } @@ -472,16 +545,11 @@ void NewFunc (SymEntry* Func, FuncDesc* D) unsigned Flags; /* Generate the push */ - if (IsTypeFunc (D->LastParam->Type)) { - /* Pointer to function */ - Flags = CF_PTR; + /* Handle struct/union specially */ + if (IsClassStruct (D->LastParam->Type)) { + Flags = TypeOf (GetStructReplacementType (D->LastParam->Type)) | CF_FORCECHAR; } else { - /* Handle struct/union specially */ - if (IsClassStruct (D->LastParam->Type)) { - Flags = TypeOf (GetStructReplacementType (D->LastParam->Type)) | CF_FORCECHAR; - } else { - Flags = TypeOf (D->LastParam->Type) | CF_FORCECHAR; - } + Flags = TypeOf (D->LastParam->Type) | CF_FORCECHAR; } g_push (Flags, 0); } @@ -497,48 +565,50 @@ void NewFunc (SymEntry* Func, FuncDesc* D) /* Setup the stack */ StackPtr = 0; - /* Walk through the parameter list and allocate register variable space - ** for parameters declared as register. Generate code to swap the contents - ** of the register bank with the save area on the stack. - */ - Param = D->SymTab->SymHead; - while (Param && (Param->Flags & SC_PARAM) != 0) { + /* Emit code to handle the parameters if all of them have complete types */ + if (ParamComplete) { + /* Walk through the parameter list and allocate register variable space + ** for parameters declared as register. Generate code to swap the contents + ** of the register bank with the save area on the stack. + */ + Param = D->SymTab->SymHead; + while (Param && (Param->Flags & SC_PARAM) != 0) { - /* Check if we need copy for struct/union type */ - RType = Param->Type; - if (IsClassStruct (RType)) { - RType = GetStructReplacementType (RType); + /* Check if we need copy for struct/union type */ + RType = Param->Type; + if (IsClassStruct (RType)) { + RType = GetStructReplacementType (RType); - /* If there is no replacement type, then it is just the address. - ** We don't currently support this case. - */ - if (RType == Param->Type) { - Error ("Passing '%s' of this size by value is not supported", GetFullTypeName (Param->Type)); + /* If there is no replacement type, then it is just the address. + ** We don't currently support this case. + */ + if (RType == Param->Type) { + Error ("Passing '%s' of this size by value is not supported", GetFullTypeName (Param->Type)); + } } - } + /* Check for a register variable */ + if (SymIsRegVar (Param)) { - /* Check for a register variable */ - if (SymIsRegVar (Param)) { + /* Allocate space */ + int Reg = F_AllocRegVar (CurrentFunc, RType); - /* Allocate space */ - int Reg = F_AllocRegVar (CurrentFunc, RType); + /* Could we allocate a register? */ + if (Reg < 0) { + /* No register available: Convert parameter to auto */ + CvtRegVarToAuto (Param); + } else { + /* Remember the register offset */ + Param->V.R.RegOffs = Reg; - /* Could we allocate a register? */ - if (Reg < 0) { - /* No register available: Convert parameter to auto */ - CvtRegVarToAuto (Param); - } else { - /* Remember the register offset */ - Param->V.R.RegOffs = Reg; - - /* Generate swap code */ - g_swap_regvars (Param->V.R.SaveOffs, Reg, CheckedSizeOf (RType)); + /* Generate swap code */ + g_swap_regvars (Param->V.R.SaveOffs, Reg, CheckedSizeOf (RType)); + } } - } - /* Next parameter */ - Param = Param->NextSym; + /* Next parameter */ + Param = Param->NextSym; + } } /* Need a starting curly brace */ diff --git a/src/cc65/function.h b/src/cc65/function.h index 8231a1970..e0b7ef0a2 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -81,6 +81,12 @@ extern Function* CurrentFunc; +int F_CheckParamList (FuncDesc* D, int RequireAll); +/* Check and set the parameter sizes. +** If RequireAll is true, emit errors on parameters of incomplete types. +** Return true if all parameters have complete types. +*/ + const char* F_GetFuncName (const Function* F); /* Return the name of the current function */ diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 036cc2d89..0925c6d3d 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -318,28 +318,38 @@ static void ReturnStatement (void) /* Evaluate the return expression */ hie0 (&Expr); - /* If we return something in a void function, print an error and - ** ignore the value. Otherwise convert the value to the type of the - ** return. + /* If we return something in a function with void or incomplete return + ** type, print an error and ignore the value. Otherwise convert the + ** value to the type of the return. */ if (F_HasVoidReturn (CurrentFunc)) { - Error ("Returning a value in function with return type void"); + Error ("Returning a value in function with return type 'void'"); } else { - /* Convert the return value to the type of the function result */ - TypeConversion (&Expr, F_GetReturnType (CurrentFunc)); - /* Load the value into the primary */ - if (IsClassStruct (Expr.Type)) { - /* Handle struct/union specially */ - ReturnType = GetStructReplacementType (Expr.Type); - if (ReturnType == Expr.Type) { - Error ("Returning '%s' of this size by value is not supported", GetFullTypeName (Expr.Type)); + /* Check the return type first */ + ReturnType = F_GetReturnType (CurrentFunc); + if (IsIncompleteESUType (ReturnType)) { + /* Avoid excess errors */ + if (ErrorCount == 0) { + Error ("Returning a value in function with incomplete return type"); } - LoadExpr (TypeOf (ReturnType), &Expr); - } else { + /* Convert the return value to the type of the function result */ + TypeConversion (&Expr, ReturnType); + /* Load the value into the primary */ - LoadExpr (CF_NONE, &Expr); + if (IsClassStruct (Expr.Type)) { + /* Handle struct/union specially */ + ReturnType = GetStructReplacementType (Expr.Type); + if (ReturnType == Expr.Type) { + Error ("Returning '%s' of this size by value is not supported", GetFullTypeName (Expr.Type)); + } + LoadExpr (TypeOf (ReturnType), &Expr); + + } else { + /* Load the value into the primary */ + LoadExpr (CF_NONE, &Expr); + } } } From 33a75e0a7315f5dc3a5cd1bf6db2b691e655da7b Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 15 Aug 2020 06:27:11 +0800 Subject: [PATCH 1648/2161] Optimized parameter list checking. Fixed function type comparison between ANSI and K&R styles. --- src/cc65/declare.c | 1 + src/cc65/funcdesc.h | 3 ++- src/cc65/function.c | 10 ++++++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 218ba6017..8d3e0f458 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1753,6 +1753,7 @@ static FuncDesc* ParseFuncDecl (void) /* 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); diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h index 1cfb2bd09..423e7621f 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -49,13 +49,14 @@ #define FD_EMPTY 0x0001U /* Function with empty param list */ #define FD_VOID_PARAM 0x0002U /* Function with a void param list */ #define FD_VARIADIC 0x0004U /* Function with variable param list */ +#define FD_INCOMPLETE_PARAM 0x0008U /* Function with param of unknown size */ #define FD_OLDSTYLE 0x0010U /* Old style (K&R) function */ #define FD_OLDSTYLE_INTRET 0x0020U /* K&R func has implicit int return */ #define FD_UNNAMED_PARAMS 0x0040U /* Function has unnamed params */ #define FD_CALL_WRAPPER 0x0080U /* This function is used as a wrapper */ /* Bits that must be ignored when comparing funcs */ -#define FD_IGNORE (FD_OLDSTYLE | FD_OLDSTYLE_INTRET | FD_UNNAMED_PARAMS | FD_CALL_WRAPPER) +#define FD_IGNORE (FD_INCOMPLETE_PARAM | FD_OLDSTYLE | FD_OLDSTYLE_INTRET | FD_UNNAMED_PARAMS | FD_CALL_WRAPPER) diff --git a/src/cc65/function.c b/src/cc65/function.c index 451efc54d..9d4f8c2f9 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -117,6 +117,11 @@ int F_CheckParamList (FuncDesc* D, int RequireAll) unsigned ParamSize = 0; unsigned IncompleteCount = 0; + /* Don't bother to check unnecessarily */ + if ((D->Flags & FD_INCOMPLETE_PARAM) == 0) { + return 1; + } + /* Assign offsets. If the function has a variable parameter list, ** there's one additional byte (the arg size). */ @@ -147,11 +152,12 @@ int F_CheckParamList (FuncDesc* D, int RequireAll) ++I; } - /* If all parameters have complete types, set the total size description - ** and return true. + /* If all parameters have complete types, set the total size description, + ** clear the FD_INCOMPLETE_PARAM flag and return true. */ if (IncompleteCount == 0) { D->ParamSize = ParamSize; + D->Flags &= ~FD_INCOMPLETE_PARAM; return 1; } From df755df44dfc97188dfea755d4c01b06d6656b5a Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 15 Aug 2020 06:27:11 +0800 Subject: [PATCH 1649/2161] Warning about ESU types declared inside parameter list as they are invisble outside. --- src/cc65/declare.c | 50 +++++++++++++++++++++++++++++----------------- src/cc65/declare.h | 3 +++ src/cc65/symtab.c | 30 ++++++++++++++++++++++++++-- src/cc65/symtab.h | 4 ++-- 4 files changed, 65 insertions(+), 22 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 8d3e0f458..6aff1960e 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -515,7 +515,7 @@ static void ParseStorageClass (DeclSpec* D, unsigned DefStorage) -static SymEntry* ESUForwardDecl (const char* Name, unsigned Flags) +static SymEntry* ESUForwardDecl (const char* Name, unsigned Flags, unsigned* DSFlags) /* Handle an enum, struct or union forward decl */ { /* Try to find an enum/struct/union with the given name. If there is none, @@ -524,9 +524,9 @@ static SymEntry* ESUForwardDecl (const char* Name, unsigned Flags) SymEntry* Entry = FindTagSym (Name); if (Entry == 0) { if ((Flags & SC_ESUTYPEMASK) != SC_ENUM) { - Entry = AddStructSym (Name, Flags, 0, 0); + Entry = AddStructSym (Name, Flags, 0, 0, DSFlags); } else { - Entry = AddEnumSym (Name, Flags, 0, 0); + Entry = AddEnumSym (Name, Flags, 0, 0, DSFlags); } } else if ((Entry->Flags & SC_TYPEMASK) != (Flags & SC_ESUTYPEMASK)) { /* Already defined, but not the same type class */ @@ -575,7 +575,7 @@ static const Type* GetEnumeratorType (long Min, unsigned long Max, int Signed) -static SymEntry* ParseEnumDecl (const char* Name) +static SymEntry* ParseEnumDecl (const char* Name, unsigned* DSFlags) /* Process an enum declaration */ { SymTable* FieldTab; @@ -593,11 +593,11 @@ static SymEntry* ParseEnumDecl (const char* Name) if (CurTok.Tok != TOK_LCURLY) { /* Just a forward definition */ - return ESUForwardDecl (Name, SC_ENUM); + return ESUForwardDecl (Name, SC_ENUM, DSFlags); } /* Add a forward declaration for the enum tag in the current lexical level */ - AddEnumSym (Name, 0, 0, 0); + AddEnumSym (Name, 0, 0, 0, DSFlags); /* Skip the opening curly brace */ NextToken (); @@ -740,7 +740,7 @@ static SymEntry* ParseEnumDecl (const char* Name) Flags |= SC_FICTITIOUS; } - return AddEnumSym (Name, Flags, MemberType, FieldTab); + return AddEnumSym (Name, Flags, MemberType, FieldTab, DSFlags); } @@ -870,7 +870,7 @@ static unsigned AliasAnonStructFields (const Declaration* Decl, SymEntry* Anon) -static SymEntry* ParseUnionDecl (const char* Name) +static SymEntry* ParseUnionDecl (const char* Name, unsigned* DSFlags) /* Parse a union declaration. */ { @@ -886,11 +886,11 @@ static SymEntry* ParseUnionDecl (const char* Name) if (CurTok.Tok != TOK_LCURLY) { /* Just a forward declaration */ - return ESUForwardDecl (Name, SC_UNION); + return ESUForwardDecl (Name, SC_UNION, DSFlags); } /* Add a forward declaration for the union tag in the current lexical level */ - UnionTagEntry = AddStructSym (Name, SC_UNION, 0, 0); + UnionTagEntry = AddStructSym (Name, SC_UNION, 0, 0, DSFlags); UnionTagEntry->V.S.ACount = 0; @@ -1005,12 +1005,12 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { } /* Make a real entry from the forward decl and return it */ - return AddStructSym (Name, SC_UNION | SC_DEF | Flags, UnionSize, FieldTab); + return AddStructSym (Name, SC_UNION | SC_DEF | Flags, UnionSize, FieldTab, DSFlags); } -static SymEntry* ParseStructDecl (const char* Name) +static SymEntry* ParseStructDecl (const char* Name, unsigned* DSFlags) /* Parse a struct declaration. */ { @@ -1027,11 +1027,11 @@ static SymEntry* ParseStructDecl (const char* Name) if (CurTok.Tok != TOK_LCURLY) { /* Just a forward declaration */ - return ESUForwardDecl (Name, SC_STRUCT); + return ESUForwardDecl (Name, SC_STRUCT, DSFlags); } /* Add a forward declaration for the struct tag in the current lexical level */ - StructTagEntry = AddStructSym (Name, SC_STRUCT, 0, 0); + StructTagEntry = AddStructSym (Name, SC_STRUCT, 0, 0, DSFlags); StructTagEntry->V.S.ACount = 0; @@ -1219,7 +1219,7 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { } /* Make a real entry from the forward decl and return it */ - return AddStructSym (Name, SC_STRUCT | SC_DEF | Flags, StructSize, FieldTab); + return AddStructSym (Name, SC_STRUCT | SC_DEF | Flags, StructSize, FieldTab, DSFlags); } @@ -1402,7 +1402,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, /* Remember we have an extra type decl */ D->Flags |= DS_EXTRA_TYPE; /* Declare the union in the current scope */ - Entry = ParseUnionDecl (Ident); + Entry = ParseUnionDecl (Ident, &D->Flags); /* Encode the union entry into the type */ D->Type[0].C = T_UNION; SetESUSymEntry (D->Type, Entry); @@ -1421,7 +1421,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, /* Remember we have an extra type decl */ D->Flags |= DS_EXTRA_TYPE; /* Declare the struct in the current scope */ - Entry = ParseStructDecl (Ident); + Entry = ParseStructDecl (Ident, &D->Flags); /* Encode the struct entry into the type */ D->Type[0].C = T_STRUCT; SetESUSymEntry (D->Type, Entry); @@ -1444,7 +1444,8 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, /* Remember we have an extra type decl */ D->Flags |= DS_EXTRA_TYPE; /* Parse the enum decl */ - Entry = ParseEnumDecl (Ident); + Entry = ParseEnumDecl (Ident, &D->Flags); + /* Encode the enum entry into the type */ D->Type[0].C |= T_ENUM; SetESUSymEntry (D->Type, Entry); D->Type[1].C = T_END; @@ -1583,6 +1584,13 @@ static void ParseOldStyleParamList (FuncDesc* F) /* Read the parameter */ ParseDecl (&Spec, &Decl, DM_NEED_IDENT); + + /* Warn about new local type declaration */ + if ((Spec.Flags & DS_NEW_TYPE_DECL) != 0) { + Warning ("'%s' will be invisible out of this function", + GetFullTypeName (Spec.Type)); + } + if (Decl.Ident[0] != '\0') { /* We have a name given. Search for the symbol */ @@ -1650,6 +1658,12 @@ static void ParseAnsiParamList (FuncDesc* F) Spec.StorageClass = SC_AUTO | SC_PARAM | SC_DEF; } + /* Warn about new local type declaration */ + if ((Spec.Flags & DS_NEW_TYPE_DECL) != 0) { + Warning ("'%s' will be invisible out of this function", + GetFullTypeName (Spec.Type)); + } + /* Allow parameters without a name, but remember if we had some to ** eventually print an error message later. */ diff --git a/src/cc65/declare.h b/src/cc65/declare.h index 615f16a4a..3293a0dcb 100644 --- a/src/cc65/declare.h +++ b/src/cc65/declare.h @@ -57,6 +57,9 @@ #define DS_DEF_STORAGE 0x0001U /* Default storage class used */ #define DS_DEF_TYPE 0x0002U /* Default type used */ #define DS_EXTRA_TYPE 0x0004U /* Extra type declared */ +#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) /* Result of ParseDeclSpec */ typedef struct DeclSpec DeclSpec; diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 7e6a9f5bb..6a02fc0ce 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -686,7 +686,7 @@ static void AddSymEntry (SymTable* T, SymEntry* S) -SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTable* Tab) +SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTable* Tab, unsigned* DSFlags) /* Add an enum entry and return it */ { SymTable* CurTagTab = TagTab; @@ -719,6 +719,11 @@ SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTab Entry->V.E.Type = Type; Entry->Flags &= ~SC_DECL; Entry->Flags |= SC_DEF; + + /* Remember this is the first definition of this type */ + if (DSFlags != 0) { + *DSFlags |= DS_NEW_TYPE_DEF; + } } } @@ -741,6 +746,14 @@ SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTab Entry->Flags |= SC_DEF; } + /* Remember this is the first definition of this type */ + if (CurTagTab != FailSafeTab && DSFlags != 0) { + if ((Entry->Flags & SC_DEF) != 0) { + *DSFlags |= DS_NEW_TYPE_DEF; + } + *DSFlags |= DS_NEW_TYPE_DECL; + } + /* Add it to the current table */ AddSymEntry (CurTagTab, Entry); } @@ -751,7 +764,7 @@ SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTab -SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTable* Tab) +SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTable* Tab, unsigned* DSFlags) /* Add a struct/union entry and return it */ { SymTable* CurTagTab = TagTab; @@ -791,6 +804,11 @@ SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTabl Entry->Flags = Flags; Entry->V.S.SymTab = Tab; Entry->V.S.Size = Size; + + /* Remember this is the first definition of this type */ + if (DSFlags != 0) { + *DSFlags |= DS_NEW_TYPE_DEF; + } } } @@ -809,6 +827,14 @@ SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTabl Entry->V.S.SymTab = Tab; Entry->V.S.Size = Size; + /* Remember this is the first definition of this type */ + if (CurTagTab != FailSafeTab && DSFlags != 0) { + if ((Entry->Flags & SC_DEF) != 0) { + *DSFlags |= DS_NEW_TYPE_DEF; + } + *DSFlags |= DS_NEW_TYPE_DECL; + } + /* Add it to the current tag table */ AddSymEntry (CurTagTab, Entry); } diff --git a/src/cc65/symtab.h b/src/cc65/symtab.h index 750e41b54..1231eb528 100644 --- a/src/cc65/symtab.h +++ b/src/cc65/symtab.h @@ -149,10 +149,10 @@ unsigned short FindSPAdjustment (const char* Name); -SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTable* Tab); +SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTable* Tab, unsigned* DSFlags); /* Add an enum entry and return it */ -SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTable* Tab); +SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTable* Tab, unsigned* DSFlags); /* Add a struct/union entry and return it */ SymEntry* AddBitField (const char* Name, const Type* Type, unsigned Offs, From 492ee7fc455dbef2b5a3e52c37a20a5ecdbd3eee Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 30 Aug 2020 03:10:24 +0800 Subject: [PATCH 1650/2161] Improved test/ref/pr1220.c. --- test/ref/pr1220.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/test/ref/pr1220.c b/test/ref/pr1220.c index c594b5ac2..4f88ada73 100644 --- a/test/ref/pr1220.c +++ b/test/ref/pr1220.c @@ -1,24 +1,28 @@ -/* PR #1220 - test constant AND/OR */ +/* PR #1220 - test constant ternary, AND and OR */ #include <stdio.h> +/* test AND/OR, results as integers */ #define CONTEXT_A(x) do {\ s = 0, flags = 0, t = (x),\ printf("%3d %2X: %d\n", s, flags, t);\ } while (0) +/* test AND/OR in ternary context */ #define CONTEXT_B(x) do {\ s = 0, flags = 0,\ (x ? printf("%3d %2X: 1\n", s, flags) : printf("%3d %2X: 0\n", s, flags));\ } while (0) int s, t; -void *p; unsigned flags; int f(x) +/* The call to this function should be and only be skipped strictly according to +** the short-circuit evaluation rule. +*/ { - flags |= 1U << s; + flags |= (x != 0) << s; ++s; return x; } @@ -31,6 +35,7 @@ int f(x) #define _F (f(-1), 0) void f0() +/* constant short-circuit */ { printf("f0()\n"); @@ -59,6 +64,7 @@ void f0() } void f1(int a, int b, int c) +/* AND */ { printf("f1(%d, %d, %d)\n", a, b, c); @@ -80,6 +86,7 @@ void f1(int a, int b, int c) } void f2(int a, int b, int c) +/* OR */ { printf("f2(%d, %d, %d)\n", a, b, c); @@ -101,6 +108,7 @@ void f2(int a, int b, int c) } void f3(int a, int b, int c, int d) +/* AND and OR */ { printf("f3(%d, %d, %d, %d)\n", a, b, c, d); @@ -122,6 +130,7 @@ void f3(int a, int b, int c, int d) } void f4(int a, int b, int c, int d) +/* AND as top-level expression inside OR context */ { printf("f4(%d, %d, %d, %d)\n", a, b, c, d); @@ -143,6 +152,7 @@ void f4(int a, int b, int c, int d) } void f5(int a, int b, int c, int d) +/* OR as top-level expression inside AND context */ { printf("f5(%d, %d, %d, %d)\n", a, b, c, d); @@ -164,6 +174,7 @@ void f5(int a, int b, int c, int d) } void f0_B() +/* constant short-circuit */ { printf("f0()\n"); @@ -192,6 +203,7 @@ void f0_B() } void f1_B(int a, int b, int c) +/* AND */ { printf("f1(%d, %d, %d)\n", a, b, c); @@ -213,6 +225,7 @@ void f1_B(int a, int b, int c) } void f2_B(int a, int b, int c) +/* OR */ { printf("f2(%d, %d, %d)\n", a, b, c); @@ -234,6 +247,7 @@ void f2_B(int a, int b, int c) } void f3_B(int a, int b, int c, int d) +/* AND and OR */ { printf("f3(%d, %d, %d, %d)\n", a, b, c, d); @@ -255,6 +269,7 @@ void f3_B(int a, int b, int c, int d) } void f4_B(int a, int b, int c, int d) +/* AND as top-level expression inside OR context */ { printf("f4(%d, %d, %d, %d)\n", a, b, c, d); @@ -276,6 +291,7 @@ void f4_B(int a, int b, int c, int d) } void f5_B(int a, int b, int c, int d) +/* OR as top-level expression inside AND context */ { printf("f5(%d, %d, %d, %d)\n", a, b, c, d); From 60c59f59a3957e819f1c4889b01142d9b7d3c981 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 30 Aug 2020 00:26:52 +0800 Subject: [PATCH 1651/2161] Renamed StaticConstExpr() and StaticConstAbsIntExpr() with clearer comments. --- src/cc65/asmstmt.c | 8 ++++---- src/cc65/declare.c | 12 ++++++------ src/cc65/expr.c | 28 ++++++++++++++-------------- src/cc65/expr.h | 18 +++++++++--------- src/cc65/preproc.c | 2 +- src/cc65/preproc.h | 2 +- src/cc65/staticassert.c | 2 +- src/cc65/swstmt.c | 2 +- 8 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/cc65/asmstmt.c b/src/cc65/asmstmt.c index 148d62d9c..9dd1f906a 100644 --- a/src/cc65/asmstmt.c +++ b/src/cc65/asmstmt.c @@ -135,7 +135,7 @@ static void ParseByteArg (StrBuf* T, unsigned Arg) ConsumeComma (); /* Evaluate the expression */ - ExprDesc Expr = StaticConstAbsIntExpr (hie1); + ExprDesc Expr = NoCodeConstAbsIntExpr (hie1); /* Check the range but allow negative values if the type is signed */ if (IsSignUnsigned (Expr.Type)) { @@ -168,7 +168,7 @@ static void ParseWordArg (StrBuf* T, unsigned Arg) ConsumeComma (); /* Evaluate the expression */ - ExprDesc Expr = StaticConstAbsIntExpr (hie1); + ExprDesc Expr = NoCodeConstAbsIntExpr (hie1); /* Check the range but allow negative values if the type is signed */ if (IsSignUnsigned (Expr.Type)) { @@ -201,7 +201,7 @@ static void ParseLongArg (StrBuf* T, unsigned Arg attribute ((unused))) ConsumeComma (); /* Evaluate the expression */ - ExprDesc Expr = StaticConstAbsIntExpr (hie1); + ExprDesc Expr = NoCodeConstAbsIntExpr (hie1); /* Convert into a hex number */ xsprintf (Buf, sizeof (Buf), "$%08lX", Expr.IVal & 0xFFFFFFFF); @@ -325,7 +325,7 @@ static void ParseStrArg (StrBuf* T, unsigned Arg attribute ((unused))) break; default: - Expr = StaticConstAbsIntExpr (hie1); + Expr = NoCodeConstAbsIntExpr (hie1); xsprintf (Buf, sizeof (Buf), "%ld", Expr.IVal); SB_AppendStr (T, Buf); break; diff --git a/src/cc65/declare.c b/src/cc65/declare.c index d1ac0e43f..b184c31a6 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -622,7 +622,7 @@ static SymEntry* ParseEnumDecl (const char* Name) if (CurTok.Tok == TOK_ASSIGN) { NextToken (); - ExprDesc Expr = StaticConstAbsIntExpr (hie1); + ExprDesc Expr = NoCodeConstAbsIntExpr (hie1); EnumVal = Expr.IVal; MemberType = Expr.Type; IsSigned = IsSignSigned (MemberType); @@ -772,7 +772,7 @@ static int ParseFieldWidth (Declaration* Decl) /* Read the width */ NextToken (); - ExprDesc Expr = StaticConstAbsIntExpr (hie1); + ExprDesc Expr = NoCodeConstAbsIntExpr (hie1); if (Expr.IVal < 0) { Error ("Negative width in bit-field"); @@ -1859,7 +1859,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Read the size if it is given */ if (CurTok.Tok != TOK_RBRACK) { - ExprDesc Expr = StaticConstAbsIntExpr (hie1); + ExprDesc Expr = NoCodeConstAbsIntExpr (hie1); if (Expr.IVal <= 0) { if (D->Ident[0] != '\0') { Error ("Size of array '%s' is invalid", D->Ident); @@ -2220,7 +2220,7 @@ static ExprDesc ParseScalarInitInternal (Type* T) } /* Get the expression and convert it to the target type */ - ExprDesc ED = StaticConstExpr (hie1); + ExprDesc ED = NoCodeConstExpr (hie1); TypeConversion (&ED, T); /* Close eventually opening braces */ @@ -2253,7 +2253,7 @@ static unsigned ParsePointerInit (Type* T) unsigned BraceCount = OpeningCurlyBraces (0); /* Expression */ - ExprDesc ED = StaticConstExpr (hie1); + ExprDesc ED = NoCodeConstExpr (hie1); TypeConversion (&ED, T); /* Output the data */ @@ -2598,7 +2598,7 @@ static unsigned ParseVoidInit (Type* T) /* Allow an arbitrary list of values */ Size = 0; do { - ExprDesc Expr = StaticConstExpr (hie1); + ExprDesc Expr = NoCodeConstExpr (hie1); switch (GetUnderlyingTypeCode (&Expr.Type[0])) { case T_SCHAR: diff --git a/src/cc65/expr.c b/src/cc65/expr.c index d1ceb27c5..e627b6606 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3150,14 +3150,14 @@ static void hieAndPP (ExprDesc* Expr) ** called recursively from the preprocessor. */ { - *Expr = StaticConstAbsIntExpr (hie2); + *Expr = NoCodeConstAbsIntExpr (hie2); while (CurTok.Tok == TOK_BOOL_AND) { /* Skip the && */ NextToken (); /* Get rhs */ - ExprDesc Expr2 = StaticConstAbsIntExpr (hie2); + ExprDesc Expr2 = NoCodeConstAbsIntExpr (hie2); /* Combine the two */ Expr->IVal = (Expr->IVal && Expr2.IVal); @@ -3171,14 +3171,14 @@ static void hieOrPP (ExprDesc *Expr) ** called recursively from the preprocessor. */ { - *Expr = StaticConstAbsIntExpr (hieAndPP); + *Expr = NoCodeConstAbsIntExpr (hieAndPP); while (CurTok.Tok == TOK_BOOL_OR) { /* Skip the && */ NextToken (); /* Get rhs */ - ExprDesc Expr2 = StaticConstAbsIntExpr (hieAndPP); + ExprDesc Expr2 = NoCodeConstAbsIntExpr (hieAndPP); /* Combine the two */ Expr->IVal = (Expr->IVal || Expr2.IVal); @@ -4047,11 +4047,11 @@ void BoolExpr (void (*Func) (ExprDesc*), ExprDesc* Expr) -ExprDesc StaticConstExpr (void (*Func) (ExprDesc*)) -/* Will evaluate an expression via the given function. If the result is not a -** static constant expression, a diagnostic will be printed, and the value is -** replaced by a constant one to make sure there are no internal errors that -** result from this input error. +ExprDesc NoCodeConstExpr (void (*Func) (ExprDesc*)) +/* Get an expression evaluated via the given function. If the result is not a +** constant expression without runtime code generated, a diagnostic will be +** printed, and the value is replaced by a constant one to make sure there are +** no internal errors that result from this input error. */ { ExprDesc Expr; @@ -4071,11 +4071,11 @@ ExprDesc StaticConstExpr (void (*Func) (ExprDesc*)) -ExprDesc StaticConstAbsIntExpr (void (*Func) (ExprDesc*)) -/* Will evaluate an expression via the given function. If the result is not a -** static constant numeric integer value, a diagnostic will be printed, and the -** value is replaced by a constant one to make sure there are no internal -** errors that result from this input error. +ExprDesc NoCodeConstAbsIntExpr (void (*Func) (ExprDesc*)) +/* Get an expression evaluated via the given function. If the result is not a +** constant numeric integer value without runtime code generated, a diagnostic +** will be printed, and the value is replaced by a constant one to make sure +** there are no internal errors that result from this input error. */ { ExprDesc Expr; diff --git a/src/cc65/expr.h b/src/cc65/expr.h index 8f7eb6f09..806a376bb 100644 --- a/src/cc65/expr.h +++ b/src/cc65/expr.h @@ -61,18 +61,18 @@ void BoolExpr (void (*Func) (ExprDesc*), ExprDesc* Expr); ** are no internal errors that result from this input error. */ -ExprDesc StaticConstExpr (void (*Func) (ExprDesc*)); +ExprDesc NoCodeConstExpr (void (*Func) (ExprDesc*)); /* Get an expression evaluated via the given function. If the result is not a -** static constant expression, a diagnostic will be printed, and the value is -** replaced by a constant one to make sure there are no internal errors that -** result from this input error. +** constant expression without runtime code generated, a diagnostic will be +** printed, and the value is replaced by a constant one to make sure there are +** no internal errors that result from this input error. */ -ExprDesc StaticConstAbsIntExpr (void (*Func) (ExprDesc*)); -/* Get an expression evaluate via the given function. If the result is not a -** static constant numeric integer value, a diagnostic will be printed, and the -** value is replaced by a constant one to make sure there are no internal -** errors that result from this input error. +ExprDesc NoCodeConstAbsIntExpr (void (*Func) (ExprDesc*)); +/* Get an expression evaluated via the given function. If the result is not a +** constant numeric integer value without runtime code generated, a diagnostic +** will be printed, and the value is replaced by a constant one to make sure +** there are no internal errors that result from this input error. */ void hie10 (ExprDesc* lval); diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index 2d2f316d7..cc160c1c3 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -1076,7 +1076,7 @@ static int DoIf (int Skip) NextToken (); /* Call the expression parser */ - ExprDesc Expr = StaticConstExpr (hie1); + ExprDesc Expr = NoCodeConstExpr (hie1); /* End preprocessing mode */ Preprocessing = 0; diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 464b02337..1487179f4 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -44,7 +44,7 @@ -/* Set when the preprocessor calls StaticConstExpr() recursively */ +/* Set when the preprocessor calls NoCodeConstExpr() recursively */ extern unsigned char Preprocessing; diff --git a/src/cc65/staticassert.c b/src/cc65/staticassert.c index 3372c59a1..1bf8dd4c5 100644 --- a/src/cc65/staticassert.c +++ b/src/cc65/staticassert.c @@ -65,7 +65,7 @@ void ParseStaticAssert () } /* Parse assertion condition */ - Expr = StaticConstAbsIntExpr (hie1); + Expr = NoCodeConstAbsIntExpr (hie1); failed = !Expr.IVal; /* If there is a comma, we also have an error message. The message is optional because we diff --git a/src/cc65/swstmt.c b/src/cc65/swstmt.c index 559e168c3..3878f7b67 100644 --- a/src/cc65/swstmt.c +++ b/src/cc65/swstmt.c @@ -216,7 +216,7 @@ void CaseLabel (void) NextToken (); /* Read the selector expression */ - CaseExpr = StaticConstAbsIntExpr (hie1); + CaseExpr = NoCodeConstAbsIntExpr (hie1); Val = CaseExpr.IVal; /* Now check if we're inside a switch statement */ From d87846e1e1d1f083a1f01be41e4514a15cdd2dbd Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 30 Aug 2020 22:12:30 +0800 Subject: [PATCH 1652/2161] Improved comments according to PR reviews. --- src/cc65/exprdesc.h | 86 +++++++++++++++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 26 deletions(-) diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index 68db8b2fe..f04be6a8d 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -65,16 +65,16 @@ enum { ** - E_LOC_<else> refers to any other than E_LOC_NONE and E_LOC_PRIMARY. ** - E_LOC_EXPR can be regarded as a generalized E_LOC_<else>. ** - E_LOC_NONE can be regarded as E_LOC_PRIMARY + E_ADDRESS_OF unless - ** remarked otherwise (see below). + ** remarked otherwise (see below). ** - An E_LOC_NONE value is not considered to be an "address". ** - ref-load doesn't change the location, while rval-load puts into the - ** primary register a "temporary" that is the straight integer rvalue or - ** a "delegate" to the real rvalue somewhere else. + ** primary register a "temporary" that is the straight integer rvalue or + ** a "delegate" to the real rvalue somewhere else. ** - ref-load doesn't change the rval/lval category of the expression, - ** while rval-load converts it to an rvalue if it wasn't. + ** while rval-load converts it to an rvalue if it wasn't. ** - In practice, ref-load is unimplemented, and can be simulated with - ** adding E_ADDRESS_OF temporaily through LoadExpr + FinalizeLoad, - ** whilst val-load is done with LoadExpr + FinalizeRValLoad. + ** adding E_ADDRESS_OF temporaily through LoadExpr + FinalizeLoad, + ** whilst val-load is done with LoadExpr + FinalizeRValLoad. ** ** E_LOC_NONE -- ref-load -> + E_LOADED (int rvalue) ** E_LOC_PRIMARY -- ref-load -> + E_LOADED (unchanged) @@ -110,7 +110,7 @@ enum { E_LOC_CONST = E_LOC_NONE | E_LOC_ABS | E_LOC_GLOBAL | E_LOC_STATIC | E_LOC_REGISTER | E_LOC_LITERAL | E_LOC_CODE, - /* Not-so-immutable location addresses (stack offsets can change) */ + /* Not-so-immutable location addresses (stack offsets may change dynamically) */ E_LOC_QUASICONST = E_LOC_CONST | E_LOC_STACK, /* Expression type modifiers */ @@ -129,33 +129,67 @@ enum { /* Optimization hints */ E_MASK_NEED = 0x030000, - E_NEED_EAX = 0x000000, /* Expression needs to be loaded in Primary */ - E_NEED_NONE = 0x010000, /* Expression value is unused */ + E_NEED_EAX = 0x000000, /* Expression result needs to be loaded in Primary */ + E_NEED_NONE = 0x010000, /* Expression result is unused */ E_NEED_TEST = 0x020000, /* Expression needs a test to set cc */ /* Expression evaluation requirements. ** Usage: (Flags & E_EVAL_<Flag>) == E_EVAL_<Flag> + ** + ** Remark: + ** - Expression result, that is the "final value" of the expression, is no + ** more than one of the effects of the whole expression. Effects other + ** than it are usually consided "side-effects" in this regard. + ** - The compiler front end cannot know things determined by the linker, + ** such as the actual address of an object with static storage. What it + ** can know is categorized as "compiler-known" here. + ** - The concept "immutable" here means that once something is determined + ** (not necessarily by the compiler), it will never change. This is not + ** the same meaning as the "constant" word in the C standard. + ** - The concept "compile-time" ( not to be confued with "compiler-known"), + ** or "static" (compared to "run-time" as in "_Static_assert" in C, not + ** to be confused with the "static" storage) here means that something + ** has no run-time behaviors, enforced by the fact that it generates no + ** target code (hence "no-code"). It is closely related to the concepts + ** above but not the same. + ** - An "unevaluated" expression is special and different from the above: + ** while it generates no code, cannot change its "value" (it actually has + ** no value), and must be completely handled by the compiler front-end, + ** it is unique in that it is not "evaluated" while the others are, and + ** the codegen routine of such an expression is usually separated from + ** the normally evaluated ones. Therefore it is treated differently from + ** the above and uses a separate flag that implies none of the above. + ** - The "maybe-unused" flag is to suppress the checking and warning on + ** expressions with no effects. It doesn't have any special meanings + ** beyond that, and is independent from the E_NEED_<flag>s. All + ** "unevaluated" expressions are flagged as "maybe-unused" just to + ** avoid unnecessary warnings. + ** + ** Relationship of some concepts: + ** - "no-code" implies "no-side-effects" + ** - "immutable" = "compiler-known" OR "no-code" + ** - "constant expression" in C = "compiler-known" AND "no-code", with minor differences */ - E_MASK_EVAL = 0xFC0000, - E_EVAL_NONE = 0x000000, /* No requirements */ - E_EVAL_CONST = 0x040000, /* Result must be immutable */ - E_EVAL_COMPILE_TIME = 0x0C0000, /* Result must be known at compile time */ - E_EVAL_PURE = 0x100000, /* Evaluation must have no side effects */ - E_EVAL_STATIC = 0x340000, /* Evaluation must generate no code */ - E_EVAL_MAYBE_UNUSED = 0x400000, /* Result may be unused */ - E_EVAL_UNEVAL = 0xC00000, /* Expression is unevaluated */ + E_MASK_EVAL = 0xFC0000, + E_EVAL_NONE = 0x000000, /* No requirements */ + E_EVAL_IMMUTABLE_RESULT = 0x040000, /* Expression result must be immutable */ + E_EVAL_COMPILER_KNOWN = 0x0C0000, /* Expression result must be known to the compiler */ + E_EVAL_NO_SIDE_EFFECTS = 0x100000, /* Evaluation must have no side effects */ + E_EVAL_NO_CODE = 0x340000, /* Evaluation must generate no code */ + E_EVAL_MAYBE_UNUSED = 0x400000, /* Expression result may be unused */ + E_EVAL_UNEVAL = 0xC00000, /* Expression is unevaluated */ - /* Expression must be static and have result known at compile time */ - E_EVAL_C_CONST = E_EVAL_COMPILE_TIME | E_EVAL_STATIC, + /* Expression result must be known to the compiler and generate no code to load */ + E_EVAL_C_CONST = E_EVAL_COMPILER_KNOWN | E_EVAL_NO_CODE, - /* Flags to keep in subexpressions */ - E_MASK_KEEP_SUBEXPR = E_MASK_EVAL, + /* Flags to keep in subexpressions of most operations other than ternary */ + E_MASK_KEEP_SUBEXPR = E_MASK_EVAL, - /* Flags to keep in ternary subexpressions */ - E_MASK_KEEP_RESULT = E_MASK_NEED | E_MASK_EVAL, + /* Flags to keep for the two result subexpressions of the ternary operation */ + E_MASK_KEEP_RESULT = E_MASK_NEED | E_MASK_EVAL, /* Flags to keep when using the ED_Make functions */ - E_MASK_KEEP_MAKE = E_HAVE_MARKS | E_MASK_KEEP_RESULT, + E_MASK_KEEP_MAKE = E_HAVE_MARKS | E_MASK_KEEP_RESULT, }; /* Forward */ @@ -420,10 +454,10 @@ int ED_YetToLoad (const ExprDesc* Expr); INLINE int ED_NeedsConst (const ExprDesc* Expr) /* Check if the expression need be immutable */ { - return (Expr->Flags & E_EVAL_CONST) == E_EVAL_CONST; + return (Expr->Flags & E_EVAL_IMMUTABLE_RESULT) == E_EVAL_IMMUTABLE_RESULT; } #else -# define ED_NeedsConst(Expr) (((Expr)->Flags & E_EVAL_CONST) == E_EVAL_CONST) +# define ED_NeedsConst(Expr) (((Expr)->Flags & E_EVAL_IMMUTABLE_RESULT) == E_EVAL_IMMUTABLE_RESULT) #endif void ED_MarkForUneval (ExprDesc* Expr); From abcc2a8f1a06083dd8847dab5fd974cd50eba4d8 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 20 Aug 2020 07:46:08 +0800 Subject: [PATCH 1653/2161] Disallowed void arrays of elements of variant sizes. --- src/cc65/declare.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 6aff1960e..e32c880cc 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2389,6 +2389,11 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) } } + /* Size of 'void' elements are determined after initialization */ + if (ElementSize == 0) { + ElementSize = SizeOf (ElementType); + } + if (ElementCount == UNSPECIFIED) { /* Number of elements determined by initializer */ SetElementCount (T, Count); @@ -2695,7 +2700,11 @@ static unsigned ParseVoidInit (Type* T) ConsumeRCurly (); /* Number of bytes determined by initializer */ - T->A.U = Size; + if (T->A.U != 0 && T->A.U != Size) { + Error ("'void' array initialized with elements of variant sizes"); + } else { + T->A.U = Size; + } /* Return the number of bytes initialized */ return Size; From 8541f18340f01cece75fbffea3f3d8febd7cd7f9 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 26 Aug 2020 00:12:23 +0800 Subject: [PATCH 1654/2161] Improved diagnostic info on assignment to void types. --- src/cc65/datatype.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 9efb142ee..522b653c6 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -903,6 +903,7 @@ unsigned TypeOf (const Type* T) /* Address of ... */ return CF_INT | CF_UNSIGNED; + case T_VOID: case T_ENUM: /* Incomplete enum type */ Error ("Incomplete type '%s'", GetFullTypeName (T)); From f1161daee91890aeb4f028fe81637a4bf73079f3 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 30 Aug 2020 02:30:43 +0800 Subject: [PATCH 1655/2161] Recursively checking for incomplete/unknown-sized types. --- src/cc65/datatype.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 522b653c6..c5fb784a2 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -979,7 +979,7 @@ int IsClassIncomplete (const Type* T) /* Return true if this is an object type lacking size info */ { if (IsTypeArray (T)) { - return GetElementCount (T) == UNSPECIFIED; + return GetElementCount (T) == UNSPECIFIED || IsClassIncomplete (T + 1); } return IsTypeVoid (T) || IsIncompleteESUType (T); } @@ -1072,7 +1072,7 @@ int HasUnknownSize (const Type* T) /* Return true if this is an incomplete ESU type or an array of unknown size */ { if (IsTypeArray (T)) { - return GetElementCount (T) == UNSPECIFIED; + return GetElementCount (T) == UNSPECIFIED || HasUnknownSize (T + 1); } return IsIncompleteESUType (T); } From 8b580e1191cad7d6da0ef97be60105d659514d6e Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 30 Aug 2020 02:31:09 +0800 Subject: [PATCH 1656/2161] Disabled struct/union fields of 'void' type. --- src/cc65/declare.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index e32c880cc..f65702e91 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -942,8 +942,8 @@ static SymEntry* ParseUnionDecl (const char* Name, unsigned* DSFlags) } } - /* Check for incomplete type */ - if (IsIncompleteESUType (Decl.Type)) { + /* Check for incomplete types including 'void' */ + if (IsClassIncomplete (Decl.Type)) { Error ("Field '%s' has incomplete type '%s'", Decl.Ident, GetFullTypeName (Decl.Type)); @@ -1142,8 +1142,8 @@ static SymEntry* ParseStructDecl (const char* Name, unsigned* DSFlags) } } - /* Check for incomplete type */ - if (IsIncompleteESUType (Decl.Type)) { + /* Check for incomplete types including 'void' */ + if (IsClassIncomplete (Decl.Type)) { Error ("Field '%s' has incomplete type '%s'", Decl.Ident, GetFullTypeName (Decl.Type)); From c0a873e0c8198a1c0111e766f15e028a527c01bb Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 27 Aug 2020 08:02:05 +0800 Subject: [PATCH 1657/2161] Reduced exess errors on wrong initializations with curly braces. --- src/cc65/expr.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 89c7ff108..75d695623 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -959,7 +959,16 @@ static void Primary (ExprDesc* E) /* Illegal primary. Be sure to skip the token to avoid endless ** error loops. */ - { + if (CurTok.Tok == TOK_LCURLY) { + /* Statement block */ + NextToken (); + Error ("Expression expected"); + hie0 (E); + if (CurTok.Tok == TOK_RCURLY) { + NextToken (); + } + break; + } else { /* Let's see if this is a C99-style declaration */ DeclSpec Spec; InitDeclSpec (&Spec); From 74def4608aab0065d118e4a072e8aab9b6918cd6 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 31 Aug 2020 02:30:12 +0800 Subject: [PATCH 1658/2161] The 'E_NEED_TEST' flag shouldn't be overwritten when loading the expression result. --- src/cc65/expr.c | 15 ++++++++++----- src/cc65/exprdesc.c | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index e627b6606..0b34ba237 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3460,11 +3460,6 @@ static void hieQuest (ExprDesc* Expr) int Expr3IsNULL; /* Expression 3 is a NULL pointer */ Type* ResultType; /* Type of result */ - ED_Init (&Expr2); - Expr2.Flags = Expr->Flags & E_MASK_KEEP_RESULT; - ED_Init (&Expr3); - Expr3.Flags = Expr->Flags & E_MASK_KEEP_RESULT; - /* Call the lower level eval routine */ if (Preprocessing) { ExprWithCheck (hieOrPP, Expr); @@ -3476,6 +3471,13 @@ static void hieQuest (ExprDesc* Expr) if (CurTok.Tok == TOK_QUEST) { int ConstantCond = ED_IsConstAbsInt (Expr); + unsigned Flags = Expr->Flags & E_MASK_KEEP_RESULT; + + ED_Init (&Expr2); + Expr2.Flags = Flags; + ED_Init (&Expr3); + Expr3.Flags = Flags; + NextToken (); if (!ConstantCond) { @@ -3616,7 +3618,10 @@ static void hieQuest (ExprDesc* Expr) if (!ConstantCond) { /* Define the final label */ g_defcodelabel (TrueLab); + /* Set up the result expression type */ ED_FinalizeRValLoad (Expr); + /* Restore the original evaluation flags */ + Expr->Flags = (Expr->Flags & ~E_MASK_KEEP_RESULT) | Flags; } else { if (Expr->IVal != 0) { *Expr = Expr2; diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index c3f4c63f7..ac19873e7 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -266,7 +266,7 @@ ExprDesc* ED_FinalizeRValLoad (ExprDesc* Expr) { Expr->Sym = 0; Expr->Flags &= ~(E_MASK_LOC | E_MASK_RTYPE | E_BITFIELD | E_ADDRESS_OF); - Expr->Flags &= ~(E_NEED_TEST | E_CC_SET); + Expr->Flags &= ~E_CC_SET; Expr->Flags |= (E_LOC_PRIMARY | E_RTYPE_RVAL); Expr->Name = 0; Expr->IVal = 0; /* No offset */ From 9398e1cd33496e9fcc61b9db386f684b0da1946b Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 23 Aug 2020 01:35:06 +0800 Subject: [PATCH 1659/2161] Use a dedicated label pool for literals. --- src/cc65/asmlabel.c | 29 +++++++++++++++++++++++ src/cc65/asmlabel.h | 8 +++++++ src/cc65/codegen.c | 57 ++++++++++++++++++++++++++++++--------------- src/cc65/codegen.h | 9 ++++--- src/cc65/declare.c | 8 +++++-- src/cc65/exprdesc.c | 4 ++-- src/cc65/litpool.c | 8 +++---- src/cc65/loadexpr.c | 16 +++++++++---- 8 files changed, 105 insertions(+), 34 deletions(-) diff --git a/src/cc65/asmlabel.c b/src/cc65/asmlabel.c index 09aee3b92..1dda96fb0 100644 --- a/src/cc65/asmlabel.c +++ b/src/cc65/asmlabel.c @@ -98,3 +98,32 @@ int IsLocalLabelName (const char* Name) /* Local label name */ return 1; } + + + +unsigned GetPooledLiteralLabel (void) +/* Get an unused literal label. Will never return zero. */ +{ + /* Number to generate unique labels */ + static unsigned NextLabel = 0; + + /* Check for an overflow */ + if (NextLabel >= 0xFFFF) { + Internal ("Literal label overflow"); + } + + /* Return the next label */ + return ++NextLabel; +} + + + +const char* PooledLiteralLabelName (unsigned L) +/* Make a litral label name from the given label number. The label name will be +** created in static storage and overwritten when calling the function again. +*/ +{ + static char Buf[64]; + sprintf (Buf, "S%04X", L); + return Buf; +} diff --git a/src/cc65/asmlabel.h b/src/cc65/asmlabel.h index 4a76643a5..31b1f311a 100644 --- a/src/cc65/asmlabel.h +++ b/src/cc65/asmlabel.h @@ -56,6 +56,14 @@ const char* LocalLabelName (unsigned L); int IsLocalLabelName (const char* Name); /* Return true if Name is the name of a local label */ +unsigned GetPooledLiteralLabel (void); +/* Get an unused literal label. Will never return zero. */ + +const char* PooledLiteralLabelName (unsigned L); +/* Make a litral label name from the given label number. The label name will be +** created in static storage and overwritten when calling the function again. +*/ + /* End of asmlabel.h */ diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 48cf02319..b48d815d8 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -124,6 +124,16 @@ static const char* GetLabelName (unsigned Flags, uintptr_t Label, long Offs) } break; + case CF_LITERAL: + /* Literal */ + /* Static memory cell */ + if (Offs) { + xsprintf (Buf, sizeof (Buf), "%s%+ld", PooledLiteralLabelName (Label), Offs); + } else { + xsprintf (Buf, sizeof (Buf), "%s", PooledLiteralLabelName (Label)); + } + break; + case CF_ABSOLUTE: /* Absolute address */ xsprintf (Buf, sizeof (Buf), "$%04X", (unsigned)((Label+Offs) & 0xFFFF)); @@ -355,24 +365,6 @@ void g_defdatalabel (unsigned label) -void g_aliasdatalabel (unsigned label, unsigned baselabel, long offs) -/* Define label as a local alias for baselabel+offs */ -{ - /* We need an intermediate buffer here since LocalLabelName uses a - ** static buffer which changes with each call. - */ - StrBuf L = AUTO_STRBUF_INITIALIZER; - SB_AppendStr (&L, LocalLabelName (label)); - SB_Terminate (&L); - AddDataLine ("%s\t:=\t%s+%ld", - SB_GetConstBuf (&L), - LocalLabelName (baselabel), - offs); - SB_Done (&L); -} - - - /*****************************************************************************/ /* Functions handling global labels */ /*****************************************************************************/ @@ -388,6 +380,33 @@ void g_defgloblabel (const char* Name) +void g_defliterallabel (unsigned label) +/* Define a literal data label */ +{ + /* Literal labels are always data labels */ + AddDataLine ("%s:", PooledLiteralLabelName (label)); +} + + + +void g_aliasliterallabel (unsigned label, unsigned baselabel, long offs) +/* Define label as an alias for baselabel+offs */ +{ + /* We need an intermediate buffer here since LocalLabelName uses a + ** static buffer which changes with each call. + */ + StrBuf L = AUTO_STRBUF_INITIALIZER; + SB_AppendStr (&L, PooledLiteralLabelName (label)); + SB_Terminate (&L); + AddDataLine ("%s\t:=\t%s+%ld", + SB_GetConstBuf (&L), + PooledLiteralLabelName (baselabel), + offs); + SB_Done (&L); +} + + + void g_defexport (const char* Name, int ZP) /* Export the given label */ { @@ -2364,7 +2383,7 @@ void g_call (unsigned Flags, const char* Label, unsigned ArgSize) void g_callind (unsigned Flags, unsigned ArgSize, int Offs) /* Call subroutine indirect */ { - if ((Flags & CF_STACK) == 0) { + if ((Flags & CF_ADDRMASK) != CF_STACK) { /* Address is in a/x */ if ((Flags & CF_FIXARGC) == 0) { /* Pass arg count */ diff --git a/src/cc65/codegen.h b/src/cc65/codegen.h index d946a9a10..3054a39b3 100644 --- a/src/cc65/codegen.h +++ b/src/cc65/codegen.h @@ -148,9 +148,6 @@ void g_defcodelabel (unsigned label); void g_defdatalabel (unsigned label); /* Define a local data label */ -void g_aliasdatalabel (unsigned label, unsigned baselabel, long offs); -/* Define label as a local alias for baselabel+offs */ - /*****************************************************************************/ @@ -162,6 +159,12 @@ void g_aliasdatalabel (unsigned label, unsigned baselabel, long offs); void g_defgloblabel (const char* Name); /* Define a global label with the given name */ +void g_defliterallabel (unsigned label); +/* Define a literal data label */ + +void g_aliasliterallabel (unsigned label, unsigned baselabel, long offs); +/* Define label as an alias for baselabel+offs */ + void g_defexport (const char* Name, int ZP); /* Export the given label */ diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 6953afa3c..e81c761ed 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2185,11 +2185,15 @@ static void DefineData (ExprDesc* Expr) break; case E_LOC_STATIC: - case E_LOC_LITERAL: - /* Static variable or literal in the literal pool */ + /* Static variable */ g_defdata (CF_STATIC, Expr->Name, Expr->IVal); break; + case E_LOC_LITERAL: + /* Literal in the literal pool */ + g_defdata (CF_LITERAL, Expr->Name, Expr->IVal); + break; + case E_LOC_REGISTER: /* Register variable. Taking the address is usually not ** allowed. diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index ac19873e7..b9b5ba5fb 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -190,9 +190,9 @@ const char* ED_GetLabelName (const ExprDesc* Expr, long Offs) case E_LOC_LITERAL: /* Literal in the literal pool */ if (Offs) { - SB_Printf (&Buf, "%s%+ld", LocalLabelName (Expr->Name), Offs); + SB_Printf (&Buf, "%s%+ld", PooledLiteralLabelName (Expr->Name), Offs); } else { - SB_Printf (&Buf, "%s", LocalLabelName (Expr->Name)); + SB_Printf (&Buf, "%s", PooledLiteralLabelName (Expr->Name)); } break; diff --git a/src/cc65/litpool.c b/src/cc65/litpool.c index eb31c7ecc..95228179d 100644 --- a/src/cc65/litpool.c +++ b/src/cc65/litpool.c @@ -99,7 +99,7 @@ static Literal* NewLiteral (const void* Buf, unsigned Len) Literal* L = xmalloc (sizeof (*L)); /* Initialize the fields */ - L->Label = GetLocalLabel (); + L->Label = GetPooledLiteralLabel (); L->RefCount = 0; L->Output = 0; SB_Init (&L->Data); @@ -130,7 +130,7 @@ static void OutputLiteral (Literal* L) TranslateLiteral (L); /* Define the label for the literal */ - g_defdatalabel (L->Label); + g_defliterallabel (L->Label); /* Output the literal data */ g_defbytes (SB_GetConstBuf (&L->Data), SB_GetLen (&L->Data)); @@ -423,12 +423,12 @@ static void OutputReadOnlyLiterals (Collection* Literals) if (C != 0) { /* This literal is part of a longer literal, merge them */ - g_aliasdatalabel (L->Label, C->Label, GetLiteralSize (C) - GetLiteralSize (L)); + g_aliasliterallabel (L->Label, C->Label, GetLiteralSize (C) - GetLiteralSize (L)); } else { /* Define the label for the literal */ - g_defdatalabel (L->Label); + g_defliterallabel (L->Label); /* Output the literal data */ g_defbytes (SB_GetConstBuf (&L->Data), SB_GetLen (&L->Data)); diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index 17b0dd0fe..07acb3cbc 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -64,11 +64,15 @@ static void LoadAddress (unsigned Flags, ExprDesc* Expr) break; case E_LOC_STATIC: - case E_LOC_LITERAL: - /* Static symbol or literal, load address */ + /* Static symbol, load address */ g_getimmed ((Flags | CF_STATIC) & ~CF_CONST, Expr->Name, Expr->IVal); break; + case E_LOC_LITERAL: + /* Literal, load address */ + g_getimmed ((Flags | CF_LITERAL) & ~CF_CONST, Expr->Name, Expr->IVal); + break; + case E_LOC_REGISTER: /* Register variable. Taking the address is usually not ** allowed. @@ -183,11 +187,15 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) break; case E_LOC_STATIC: - case E_LOC_LITERAL: - /* Static variable or literal in the literal pool */ + /* Static variable */ g_getstatic (Flags | CF_STATIC, Expr->Name, Expr->IVal); break; + case E_LOC_LITERAL: + /* Literal in the literal pool */ + g_getstatic (Flags | CF_LITERAL, Expr->Name, Expr->IVal); + break; + case E_LOC_REGISTER: /* Register variable */ g_getstatic (Flags | CF_REGVAR, Expr->Name, Expr->IVal); From 6b64b4339579839ba919bfb1ba52a4e065d9a798 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 23 Aug 2020 01:35:11 +0800 Subject: [PATCH 1660/2161] Made local static data use a separated label pool from the code label pool. --- src/cc65/asmlabel.c | 29 +++++++++++++++++++++++++++++ src/cc65/asmlabel.h | 8 ++++++++ src/cc65/asmstmt.c | 2 +- src/cc65/codegen.c | 21 +++++++++++++++------ src/cc65/declare.c | 5 +++++ src/cc65/expr.c | 15 ++++++++++----- src/cc65/exprdesc.c | 20 +++++++++++++++++--- src/cc65/loadexpr.c | 10 ++++++++++ src/cc65/locals.c | 20 ++++++++++---------- src/cc65/symtab.c | 10 +++++----- 10 files changed, 110 insertions(+), 30 deletions(-) diff --git a/src/cc65/asmlabel.c b/src/cc65/asmlabel.c index 1dda96fb0..f561036ce 100644 --- a/src/cc65/asmlabel.c +++ b/src/cc65/asmlabel.c @@ -101,6 +101,35 @@ int IsLocalLabelName (const char* Name) +unsigned GetLocalDataLabel (void) +/* Get an unused local data label. Will never return zero. */ +{ + /* Number to generate unique labels */ + static unsigned NextLabel = 0; + + /* Check for an overflow */ + if (NextLabel >= 0xFFFF) { + Internal ("Local data label overflow"); + } + + /* Return the next label */ + return ++NextLabel; +} + + + +const char* LocalDataLabelName (unsigned L) +/* Make a label name from the given data label number. The label name will be +** created in static storage and overwritten when calling the function again. +*/ +{ + static char Buf[64]; + sprintf (Buf, "M%04X", L); + return Buf; +} + + + unsigned GetPooledLiteralLabel (void) /* Get an unused literal label. Will never return zero. */ { diff --git a/src/cc65/asmlabel.h b/src/cc65/asmlabel.h index 31b1f311a..a79071400 100644 --- a/src/cc65/asmlabel.h +++ b/src/cc65/asmlabel.h @@ -56,6 +56,14 @@ const char* LocalLabelName (unsigned L); int IsLocalLabelName (const char* Name); /* Return true if Name is the name of a local label */ +unsigned GetLocalDataLabel (void); +/* Get an unused local data label. Will never return zero. */ + +const char* LocalDataLabelName (unsigned L); +/* Make a label name from the given data label number. The label name will be +** created in static storage and overwritten when calling the function again. +*/ + unsigned GetPooledLiteralLabel (void); /* Get an unused literal label. Will never return zero. */ diff --git a/src/cc65/asmstmt.c b/src/cc65/asmstmt.c index 9dd1f906a..bf5a0815b 100644 --- a/src/cc65/asmstmt.c +++ b/src/cc65/asmstmt.c @@ -286,7 +286,7 @@ static void ParseLabelArg (StrBuf* T, unsigned Arg attribute ((unused))) } else { - /* Add a new label symbol if we don't have one until now */ + /* Add a new C label symbol if we don't have one until now */ SymEntry* Entry = AddLabelSym (CurTok.Ident, SC_REF); /* Append the label name to the buffer */ diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index b48d815d8..031e4e81a 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -107,11 +107,11 @@ static const char* GetLabelName (unsigned Flags, uintptr_t Label, long Offs) break; case CF_STATIC: - /* Static memory cell */ + /* Local static memory cell */ if (Offs) { - xsprintf (Buf, sizeof (Buf), "%s%+ld", LocalLabelName (Label), Offs); + xsprintf (Buf, sizeof (Buf), "%s%+ld", LocalDataLabelName (Label), Offs); } else { - xsprintf (Buf, sizeof (Buf), "%s", LocalLabelName (Label)); + xsprintf (Buf, sizeof (Buf), "%s", LocalDataLabelName (Label)); } break; @@ -144,6 +144,15 @@ static const char* GetLabelName (unsigned Flags, uintptr_t Label, long Offs) xsprintf (Buf, sizeof (Buf), "regbank+%u", (unsigned)((Label+Offs) & 0xFFFF)); break; + case CF_CODE: + /* Code label location */ + if (Offs) { + xsprintf (Buf, sizeof (Buf), "%s%+ld", LocalLabelName (Label), Offs); + } else { + xsprintf (Buf, sizeof (Buf), "%s", LocalLabelName (Label)); + } + break; + default: Internal ("Invalid address flags: %04X", Flags); } @@ -360,7 +369,7 @@ void g_defcodelabel (unsigned label) void g_defdatalabel (unsigned label) /* Define a local data label */ { - AddDataLine ("%s:", LocalLabelName (label)); + AddDataLine ("%s:", LocalDataLabelName (label)); } @@ -2453,11 +2462,11 @@ void g_lateadjustSP (unsigned label) /* Adjust stack based on non-immediate data */ { AddCodeLine ("pha"); - AddCodeLine ("lda %s", LocalLabelName (label)); + AddCodeLine ("lda %s", LocalDataLabelName (label)); AddCodeLine ("clc"); AddCodeLine ("adc sp"); AddCodeLine ("sta sp"); - AddCodeLine ("lda %s+1", LocalLabelName (label)); + AddCodeLine ("lda %s+1", LocalDataLabelName (label)); AddCodeLine ("adc sp+1"); AddCodeLine ("sta sp+1"); AddCodeLine ("pla"); diff --git a/src/cc65/declare.c b/src/cc65/declare.c index e81c761ed..d6286e62d 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2204,6 +2204,11 @@ static void DefineData (ExprDesc* Expr) g_defdata (CF_REGVAR, Expr->Name, Expr->IVal); break; + case E_LOC_CODE: + /* Code label location */ + g_defdata (CF_CODE, Expr->Name, Expr->IVal); + break; + case E_LOC_STACK: case E_LOC_PRIMARY: case E_LOC_EXPR: diff --git a/src/cc65/expr.c b/src/cc65/expr.c index d1dfa62ec..44b0f49be 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -92,6 +92,7 @@ static unsigned GlobalModeFlags (const ExprDesc* Expr) case E_LOC_PRIMARY: return CF_PRIMARY; case E_LOC_EXPR: return CF_EXPR; case E_LOC_LITERAL: return CF_LITERAL; + case E_LOC_CODE: return CF_CODE; default: Internal ("GlobalModeFlags: Invalid location flags value: 0x%04X", Expr->Flags); /* NOTREACHED */ @@ -794,7 +795,7 @@ static void Primary (ExprDesc* E) NextToken (); Entry = AddLabelSym (CurTok.Ident, SC_REF | SC_GOTO_IND); /* output its label */ - E->Flags = E_RTYPE_RVAL | E_LOC_STATIC | E_ADDRESS_OF; + E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; E->Type = PointerTo (type_void); NextToken (); @@ -1545,7 +1546,8 @@ void Store (ExprDesc* Expr, const Type* StoreType) case E_LOC_STATIC: case E_LOC_LITERAL: - /* Static variable or literal in the literal pool */ + case E_LOC_CODE: + /* Static variable, pooled literal or code label location */ g_putstatic (Flags, Expr->Name, Expr->IVal); break; @@ -1624,7 +1626,8 @@ static void PreInc (ExprDesc* Expr) case E_LOC_STATIC: case E_LOC_LITERAL: - /* Static variable or literal in the literal pool */ + case E_LOC_CODE: + /* Static variable, pooled literal or code label location */ g_addeqstatic (Flags, Expr->Name, Expr->IVal, Val); break; @@ -1700,7 +1703,8 @@ static void PreDec (ExprDesc* Expr) case E_LOC_STATIC: case E_LOC_LITERAL: - /* Static variable or literal in the literal pool */ + case E_LOC_CODE: + /* Static variable, pooled literal or code label location */ g_subeqstatic (Flags, Expr->Name, Expr->IVal, Val); break; @@ -3878,7 +3882,8 @@ static void addsubeq (const GenDesc* Gen, ExprDesc *Expr, const char* Op) case E_LOC_STATIC: case E_LOC_LITERAL: - /* Static variable or literal in the literal pool */ + case E_LOC_CODE: + /* Static variable, pooled literal or code label location */ if (Gen->Tok == TOK_PLUS_ASSIGN) { g_addeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal); } else { diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index b9b5ba5fb..62738bed7 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -196,6 +196,15 @@ const char* ED_GetLabelName (const ExprDesc* Expr, long Offs) } break; + case E_LOC_CODE: + /* Code label location */ + if (Offs) { + SB_Printf (&Buf, "%s%+ld", LocalLabelName (Expr->Name), Offs); + } else { + SB_Printf (&Buf, "%s", LocalLabelName (Expr->Name)); + } + break; + default: Internal ("Invalid location in ED_GetLabelName: 0x%04X", ED_GetLoc (Expr)); } @@ -503,9 +512,9 @@ void PrintExprDesc (FILE* F, ExprDesc* E) Flags &= ~E_LOC_LITERAL; Sep = ','; } - if (Flags & E_RTYPE_LVAL) { - fprintf (F, "%cE_RTYPE_LVAL", Sep); - Flags &= ~E_RTYPE_LVAL; + if (Flags & E_LOC_CODE) { + fprintf (F, "%cE_LOC_CODE", Sep); + Flags &= ~E_LOC_CODE; Sep = ','; } if (Flags & E_BITFIELD) { @@ -523,6 +532,11 @@ void PrintExprDesc (FILE* F, ExprDesc* E) Flags &= ~E_CC_SET; Sep = ','; } + if (Flags & E_RTYPE_LVAL) { + fprintf (F, "%cE_RTYPE_LVAL", Sep); + Flags &= ~E_RTYPE_LVAL; + Sep = ','; + } if (Flags & E_ADDRESS_OF) { fprintf (F, "%cE_ADDRESS_OF", Sep); Flags &= ~E_ADDRESS_OF; diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index 07acb3cbc..95617f596 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -83,6 +83,11 @@ static void LoadAddress (unsigned Flags, ExprDesc* Expr) g_getimmed ((Flags | CF_REGVAR) & ~CF_CONST, Expr->Name, Expr->IVal); break; + case E_LOC_CODE: + /* Code label, load address */ + g_getimmed ((Flags | CF_CODE) & ~CF_CONST, Expr->Name, Expr->IVal); + break; + case E_LOC_STACK: g_leasp (Expr->IVal); break; @@ -201,6 +206,11 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) g_getstatic (Flags | CF_REGVAR, Expr->Name, Expr->IVal); break; + case E_LOC_CODE: + /* Code label location */ + g_getstatic (Flags | CF_CODE, Expr->Name, Expr->IVal); + break; + case E_LOC_STACK: /* Value on the stack */ g_getlocal (Flags, Expr->IVal); diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 255a23b6d..81d0cea09 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -64,31 +64,31 @@ static unsigned AllocLabel (void (*UseSeg) ()) -/* Switch to a segment, define a local label and return it */ +/* Switch to a segment, define a local data label and return it */ { - unsigned Label; + unsigned DataLabel; /* Switch to the segment */ UseSeg (); /* Define the variable label */ - Label = GetLocalLabel (); - g_defdatalabel (Label); + DataLabel = GetLocalDataLabel (); + g_defdatalabel (DataLabel); /* Return the label */ - return Label; + return DataLabel; } -static void AllocStorage (unsigned Label, void (*UseSeg) (), unsigned Size) -/* Reserve Size bytes of BSS storage prefixed by a local label. */ +static void AllocStorage (unsigned DataLabel, void (*UseSeg) (), unsigned Size) +/* Reserve Size bytes of BSS storage prefixed by a local data label. */ { /* Switch to the segment */ UseSeg (); /* Define the variable label */ - g_defdatalabel (Label); + g_defdatalabel (DataLabel); /* Reserve space for the data */ g_res (Size); @@ -301,7 +301,7 @@ static void ParseAutoDecl (Declaration* Decl) Decl->StorageClass = (Decl->StorageClass & ~SC_AUTO) | SC_STATIC; /* Generate a label, but don't define it */ - DataLabel = GetLocalLabel (); + DataLabel = GetLocalDataLabel (); /* Add the symbol to the symbol table. */ Sym = AddLocalSym (Decl->Ident, Decl->Type, Decl->StorageClass, DataLabel); @@ -380,7 +380,7 @@ static void ParseStaticDecl (Declaration* Decl) unsigned Size; /* Generate a label, but don't define it */ - unsigned DataLabel = GetLocalLabel (); + unsigned DataLabel = GetLocalDataLabel (); /* Add the symbol to the symbol table. */ SymEntry* Sym = AddLocalSym (Decl->Ident, Decl->Type, diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6a02fc0ce..10dc0d3ff 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -931,7 +931,7 @@ DefOrRef* AddDefOrRef (SymEntry* E, unsigned Flags) DOR->Flags = Flags; DOR->StackPtr = StackPtr; DOR->Depth = CollCount (&CurrentFunc->LocalsBlockStack); - DOR->LateSP_Label = GetLocalLabel (); + DOR->LateSP_Label = GetLocalDataLabel (); return DOR; } @@ -953,7 +953,7 @@ unsigned short FindSPAdjustment (const char* Name) SymEntry* AddLabelSym (const char* Name, unsigned Flags) -/* Add a goto label to the label table */ +/* Add a C goto label to the label table */ { unsigned i; DefOrRef *DOR, *NewDOR; @@ -1012,7 +1012,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 (LocalLabelName (DOR->LateSP_Label), SC_SPADJUSTMENT); + E = NewSymEntry (LocalDataLabelName (DOR->LateSP_Label), SC_SPADJUSTMENT); E->V.SPAdjustment = StackPtr - DOR->StackPtr; AddSymEntry (SPAdjustTab, E); } @@ -1134,9 +1134,9 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs Entry->V.L.Label = Offs; SymSetAsmName (Entry); } else if ((Flags & SC_STATIC) == SC_STATIC) { - /* Generate the assembler name from the label number */ + /* Generate the assembler name from the data label number */ Entry->V.L.Label = Offs; - Entry->AsmName = xstrdup (LocalLabelName (Entry->V.L.Label)); + Entry->AsmName = xstrdup (LocalDataLabelName (Entry->V.L.Label)); } else { Internal ("Invalid flags in AddLocalSym: %04X", Flags); } From 28de3423eb205a2f4125c61e47c256c6c4010cff Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 23 Aug 2020 01:35:13 +0800 Subject: [PATCH 1661/2161] Merged some switch cases in code generation subroutines. --- src/cc65/expr.c | 73 ++++++++++++------------------------------------- 1 file changed, 17 insertions(+), 56 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 44b0f49be..38df16faf 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1540,19 +1540,13 @@ void Store (ExprDesc* Expr, const Type* StoreType) break; case E_LOC_GLOBAL: - /* Global variable */ - g_putstatic (Flags, Expr->Name, Expr->IVal); - break; - case E_LOC_STATIC: + case E_LOC_REGISTER: case E_LOC_LITERAL: case E_LOC_CODE: - /* Static variable, pooled literal or code label location */ - g_putstatic (Flags, Expr->Name, Expr->IVal); - break; - - case E_LOC_REGISTER: - /* Register variable */ + /* Global variabl, static variable, register variable, pooled + ** literal or code label location. + */ g_putstatic (Flags, Expr->Name, Expr->IVal); break; @@ -1620,19 +1614,13 @@ static void PreInc (ExprDesc* Expr) break; case E_LOC_GLOBAL: - /* Global variable */ - g_addeqstatic (Flags, Expr->Name, Expr->IVal, Val); - break; - case E_LOC_STATIC: + case E_LOC_REGISTER: case E_LOC_LITERAL: case E_LOC_CODE: - /* Static variable, pooled literal or code label location */ - g_addeqstatic (Flags, Expr->Name, Expr->IVal, Val); - break; - - case E_LOC_REGISTER: - /* Register variable */ + /* Global variabl, static variable, register variable, pooled + ** literal or code label location. + */ g_addeqstatic (Flags, Expr->Name, Expr->IVal, Val); break; @@ -1697,19 +1685,13 @@ static void PreDec (ExprDesc* Expr) break; case E_LOC_GLOBAL: - /* Global variable */ - g_subeqstatic (Flags, Expr->Name, Expr->IVal, Val); - break; - case E_LOC_STATIC: + case E_LOC_REGISTER: case E_LOC_LITERAL: case E_LOC_CODE: - /* Static variable, pooled literal or code label location */ - g_subeqstatic (Flags, Expr->Name, Expr->IVal, Val); - break; - - case E_LOC_REGISTER: - /* Register variable */ + /* Global variabl, static variable, register variable, pooled + ** literal or code label location. + */ g_subeqstatic (Flags, Expr->Name, Expr->IVal, Val); break; @@ -3863,36 +3845,15 @@ static void addsubeq (const GenDesc* Gen, ExprDesc *Expr, const char* Op) switch (ED_GetLoc (Expr)) { case E_LOC_ABS: - /* Absolute numeric addressed variable */ - if (Gen->Tok == TOK_PLUS_ASSIGN) { - g_addeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal); - } else { - g_subeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal); - } - break; - case E_LOC_GLOBAL: - /* Global variable */ - if (Gen->Tok == TOK_PLUS_ASSIGN) { - g_addeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal); - } else { - g_subeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal); - } - break; - case E_LOC_STATIC: + case E_LOC_REGISTER: case E_LOC_LITERAL: case E_LOC_CODE: - /* Static variable, pooled literal or code label location */ - if (Gen->Tok == TOK_PLUS_ASSIGN) { - g_addeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal); - } else { - g_subeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal); - } - break; - - case E_LOC_REGISTER: - /* Register variable */ + /* Absolute numeric addressed variable, global variable, local + ** static variable, register variable, pooled literal or code + ** label location. + */ if (Gen->Tok == TOK_PLUS_ASSIGN) { g_addeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal); } else { From 23795044498cce8f4b821c910f17db33445f99bd Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 31 Aug 2020 20:31:54 +0800 Subject: [PATCH 1662/2161] Fixed AND/OR in certain cases where the 'E_NEED_TEST' flag set for usage only in subexpressions should be cleared. --- src/cc65/expr.c | 6 ++++++ src/cc65/exprdesc.h | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 38df16faf..4071728ac 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3223,6 +3223,9 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) /* Load the value */ LoadExpr (CF_FORCECHAR, Expr); + /* Clear the test flag */ + ED_RequireNoTest (Expr); + /* Remember that the jump is used */ HasFalseJump = 1; @@ -3356,6 +3359,9 @@ static void hieOr (ExprDesc *Expr) /* Get first expr */ LoadExpr (CF_FORCECHAR, Expr); + /* Clear the test flag */ + ED_RequireNoTest (Expr); + if (HasTrueJump == 0) { /* Get a label that we will use for true expressions */ TrueLab = GetLocalLabel(); diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index f04be6a8d..c435b3c38 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -364,6 +364,16 @@ INLINE void ED_RequireTest (ExprDesc* Expr) # define ED_RequireTest(Expr) do { (Expr)->Flags |= E_NEED_TEST; } while (0) #endif +#if defined(HAVE_INLINE) +INLINE void ED_RequireNoTest (ExprDesc* Expr) +/* Mark the expression not for a test. */ +{ + Expr->Flags &= ~E_NEED_TEST; +} +#else +# define ED_RequireNoTest(Expr) do { (Expr)->Flags &= ~E_NEED_TEST; } while (0) +#endif + #if defined(HAVE_INLINE) INLINE int ED_GetNeeds (const ExprDesc* Expr) /* Get flags about what the expression needs. */ From fb6bc275bc500aeb5705cf67fb2955633aec11a7 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 31 Aug 2020 20:33:58 +0800 Subject: [PATCH 1663/2161] Fixed evaluation flags propagation to subexpressions in assignments and function calls. --- src/cc65/assignment.c | 3 ++- src/cc65/expr.c | 7 ++++--- src/cc65/stdfunc.c | 24 +++++++++++++----------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index 1ada3af0b..09a10a642 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,10 +136,11 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - ExprDesc Expr2; Type* ltype = Expr->Type; + ExprDesc Expr2; ED_Init (&Expr2); + Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; /* We must have an lvalue for an assignment */ if (ED_IsRVal (Expr)) { diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 4071728ac..b91fab8a8 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -332,7 +332,7 @@ static void WarnConstCompareResult (const ExprDesc* Expr) -static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) +static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) /* Parse a function parameter list, and pass the arguments to the called ** function. Depending on several criteria, this may be done by just pushing ** into each parameter separately, or creating the parameter frame once, and @@ -391,9 +391,10 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) /* Parse the actual argument list */ while (CurTok.Tok != TOK_RPAREN) { - unsigned Flags; + unsigned Flags; /* Code generator flags, not expression flags */ ExprDesc Expr; ED_Init (&Expr); + Expr.Flags |= ED->Flags & E_MASK_KEEP_SUBEXPR; /* Count arguments */ ++PushedCount; @@ -609,7 +610,7 @@ static void FunctionCall (ExprDesc* Expr) } /* Parse the parameter list */ - ParamSize = FunctionParamList (Func, IsFastcall); + ParamSize = FunctionParamList (Func, IsFastcall, Expr); /* We need the closing paren here */ ConsumeRParen (); diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 8335177bb..74579212e 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type) +static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -154,6 +154,7 @@ static void ParseArg (ArgDesc* Arg, Type* Type) /* Init expression */ ED_Init (&Arg->Expr); + Arg->Expr.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; /* Read the expression we're going to pass to the function */ MarkedExprWithCheck (hie1, &Arg->Expr); @@ -221,14 +222,14 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int Offs; /* Argument #1 */ - ParseArg (&Arg1, Arg1Type); + ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); GetCodePos (&Arg1.End); ParamSize += SizeOf (Arg1Type); ConsumeComma (); /* Argument #2 */ - ParseArg (&Arg2, Arg2Type); + ParseArg (&Arg2, Arg2Type, Expr); g_push (Arg2.Flags, Arg2.Expr.IVal); GetCodePos (&Arg2.End); ParamSize += SizeOf (Arg2Type); @@ -239,7 +240,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ** also ignored for the calculation of the parameter size, since it is ** not passed via the stack. */ - ParseArg (&Arg3, Arg3Type); + ParseArg (&Arg3, Arg3Type, Expr); if (Arg3.Flags & CF_CONST) { LoadExpr (CF_NONE, &Arg3.Expr); } @@ -562,7 +563,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) unsigned Label; /* Argument #1 */ - ParseArg (&Arg1, Arg1Type); + ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); GetCodePos (&Arg1.End); ParamSize += SizeOf (Arg1Type); @@ -571,7 +572,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Argument #2. This argument is special in that we will call another ** function if it is a constant zero. */ - ParseArg (&Arg2, Arg2Type); + ParseArg (&Arg2, Arg2Type, Expr); if ((Arg2.Flags & CF_CONST) != 0 && Arg2.Expr.IVal == 0) { /* Don't call memset, call bzero instead */ MemSet = 0; @@ -588,7 +589,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ** also ignored for the calculation of the parameter size, since it is ** not passed via the stack. */ - ParseArg (&Arg3, Arg3Type); + ParseArg (&Arg3, Arg3Type, Expr); if (Arg3.Flags & CF_CONST) { LoadExpr (CF_NONE, &Arg3.Expr); } @@ -790,13 +791,13 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) Arg2Type[1].C = T_CHAR | T_QUAL_CONST; /* Argument #1 */ - ParseArg (&Arg1, Arg1Type); + ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); ParamSize += SizeOf (Arg1Type); ConsumeComma (); /* Argument #2. */ - ParseArg (&Arg2, Arg2Type); + ParseArg (&Arg2, Arg2Type, Expr); /* Since strcmp is a fastcall function, we must load the ** arg into the primary if it is not already there. This parameter is @@ -990,7 +991,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) Arg2Type[1].C = T_CHAR | T_QUAL_CONST; /* Argument #1 */ - ParseArg (&Arg1, Arg1Type); + ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); GetCodePos (&Arg1.End); ParamSize += SizeOf (Arg1Type); @@ -1001,7 +1002,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ** also ignored for the calculation of the parameter size, since it is ** not passed via the stack. */ - ParseArg (&Arg2, Arg2Type); + ParseArg (&Arg2, Arg2Type, Expr); if (Arg2.Flags & CF_CONST) { LoadExpr (CF_NONE, &Arg2.Expr); } @@ -1184,6 +1185,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) unsigned L; ED_Init (&Arg); + Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; /* Setup the argument type string */ ArgType[1].C = T_CHAR | T_QUAL_CONST; From 2a3d996077453c3171d67223271bd3ed8aaaf926 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 31 Aug 2020 20:41:36 +0800 Subject: [PATCH 1664/2161] Improved test case for PR #1220. --- test/ref/pr1220.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/test/ref/pr1220.c b/test/ref/pr1220.c index 4f88ada73..eb9f7c7f5 100644 --- a/test/ref/pr1220.c +++ b/test/ref/pr1220.c @@ -10,14 +10,14 @@ /* test AND/OR in ternary context */ #define CONTEXT_B(x) do {\ - s = 0, flags = 0,\ - (x ? printf("%3d %2X: 1\n", s, flags) : printf("%3d %2X: 0\n", s, flags));\ + s = 0, flags = 0, t = (x ? 42 : -42),\ + printf("%3d %2X: %d\n", s, flags, t);\ } while (0) int s, t; unsigned flags; -int f(x) +int f(int x) /* The call to this function should be and only be skipped strictly according to ** the short-circuit evaluation rule. */ @@ -31,8 +31,8 @@ int f(x) #define _B f(b) #define _C f(c) #define _D f(d) -#define _T (f(0), -1) -#define _F (f(-1), 0) +#define _T (f(0), 256) +#define _F (f(256), 0) void f0() /* constant short-circuit */ @@ -176,7 +176,7 @@ void f5(int a, int b, int c, int d) void f0_B() /* constant short-circuit */ { - printf("f0()\n"); + printf("f0_B()\n"); CONTEXT_B(_T && _T && _T); CONTEXT_B(_F && _F && _F); @@ -205,7 +205,7 @@ void f0_B() void f1_B(int a, int b, int c) /* AND */ { - printf("f1(%d, %d, %d)\n", a, b, c); + printf("f1_B(%d, %d, %d)\n", a, b, c); CONTEXT_B(_A && _B && _C); @@ -227,7 +227,7 @@ void f1_B(int a, int b, int c) void f2_B(int a, int b, int c) /* OR */ { - printf("f2(%d, %d, %d)\n", a, b, c); + printf("f2_B(%d, %d, %d)\n", a, b, c); CONTEXT_B(_A || _B || _C); @@ -249,7 +249,7 @@ void f2_B(int a, int b, int c) void f3_B(int a, int b, int c, int d) /* AND and OR */ { - printf("f3(%d, %d, %d, %d)\n", a, b, c, d); + printf("f3_B(%d, %d, %d, %d)\n", a, b, c, d); CONTEXT_B(_A && _B || _C && _D); CONTEXT_B(_T && _T || _C && _D); @@ -271,7 +271,7 @@ void f3_B(int a, int b, int c, int d) void f4_B(int a, int b, int c, int d) /* AND as top-level expression inside OR context */ { - printf("f4(%d, %d, %d, %d)\n", a, b, c, d); + printf("f4_B(%d, %d, %d, %d)\n", a, b, c, d); CONTEXT_B((_A && _B) || (_C && _D)); CONTEXT_B((_T && _T) || (_C && _D)); @@ -293,7 +293,7 @@ void f4_B(int a, int b, int c, int d) void f5_B(int a, int b, int c, int d) /* OR as top-level expression inside AND context */ { - printf("f5(%d, %d, %d, %d)\n", a, b, c, d); + printf("f5_B(%d, %d, %d, %d)\n", a, b, c, d); CONTEXT_B((_A || _B) && (_C || _D)); CONTEXT_B((_F || _F) && (_C || _D)); From f45d2515eb9191f21bc21c8449e407ebfb3ee415 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 31 Aug 2020 01:56:57 +0800 Subject: [PATCH 1665/2161] Fixed OptPush1 in case later code would rely on that pushax zeroes register Y. --- src/cc65/coptpush.c | 19 +++++++++++++++++-- src/cc65/coptpush.h | 6 +++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/cc65/coptpush.c b/src/cc65/coptpush.c index 5c3daffca..34d794c64 100644 --- a/src/cc65/coptpush.c +++ b/src/cc65/coptpush.c @@ -56,12 +56,14 @@ unsigned OptPush1 (CodeSeg* S) ** ** ldy #xx+2 ** jsr pushwysp +** ldy #$00 ; present if later code expects Y = 0 ** -** saving 3 bytes and several cycles. +** saving several cycles. */ { unsigned I; unsigned Changes = 0; + unsigned R; /* Walk over the entries */ I = 0; @@ -79,7 +81,7 @@ unsigned OptPush1 (CodeSeg* S) (L[1] = CS_GetNextEntry (S, I)) != 0 && !CE_HasLabel (L[1]) && CE_IsCallTo (L[1], "pushax") && - !RegAXUsed (S, I+2)) { + ((R = (GetRegInfo (S, I+2, REG_AXY))) & REG_AX) == 0) { /* Insert new code behind the pushax */ const char* Arg; @@ -94,12 +96,25 @@ unsigned OptPush1 (CodeSeg* S) X = NewCodeEntry (OP65_JSR, AM65_ABS, "pushwysp", 0, L[1]->LI); CS_InsertEntry (S, X, I+3); + /* pushax sets Y = 0 and following code might rely on this */ + if ((R & REG_Y) != 0) { + /* ldy #0 */ + X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (0), 0, L[1]->LI); + CS_InsertEntry (S, X, I+4); + } + /* Delete the old code */ CS_DelEntries (S, I, 2); /* Remember, we had changes */ ++Changes; + /* Skip the handled lines */ + if ((R & REG_Y) == 0) { + ++I; + } else { + I += 2; + } } /* Next entry */ diff --git a/src/cc65/coptpush.h b/src/cc65/coptpush.h index 0d637e824..aa5548517 100644 --- a/src/cc65/coptpush.h +++ b/src/cc65/coptpush.h @@ -52,16 +52,16 @@ unsigned OptPush1 (CodeSeg* S); /* Given a sequence ** -** ldy #xx ** jsr ldaxysp ** jsr pushax ** -** If a/x are not used later, replace that by +** If a/x are not used later, and Y is known, replace that by ** ** ldy #xx+2 ** jsr pushwysp +** ldy #$00 ; present if later code expects Y = 0 ** -** saving 3 bytes and several cycles. +** saving several cycles. */ unsigned OptPush2 (CodeSeg* S); From ae340703f2fa517ee69a6cf7a73ac24b0de857a6 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 31 Aug 2020 01:57:01 +0800 Subject: [PATCH 1666/2161] OptDupLoads shouldn't silently do optimizations. --- src/cc65/coptind.c | 17 +++++++++++++---- src/cc65/opcodes.h | 5 ++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index 04deb0119..811adff04 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -1147,8 +1147,9 @@ unsigned OptDupLoads (CodeSeg* S) /* Get next entry */ CodeEntry* E = CS_GetEntry (S, I); - /* Assume we won't delete the entry */ + /* Assume we won't delete or replace the entry */ int Delete = 0; + opc_t NewOPC = OP65_INVALID; /* Get a pointer to the input registers of the insn */ const RegContents* In = &E->RI->In; @@ -1218,7 +1219,7 @@ unsigned OptDupLoads (CodeSeg* S) E->AM != AM65_ABSY && E->AM != AM65_ZPY) { /* Use the A register instead */ - CE_ReplaceOPC (E, OP65_STA); + NewOPC = OP65_STA; } break; @@ -1242,11 +1243,11 @@ unsigned OptDupLoads (CodeSeg* S) */ } else if (RegValIsKnown (In->RegY)) { if (In->RegY == In->RegA) { - CE_ReplaceOPC (E, OP65_STA); + NewOPC = OP65_STA; } else if (In->RegY == In->RegX && E->AM != AM65_ABSX && E->AM != AM65_ZPX) { - CE_ReplaceOPC (E, OP65_STX); + NewOPC = OP65_STX; } } break; @@ -1319,6 +1320,14 @@ unsigned OptDupLoads (CodeSeg* S) } else { + if (NewOPC != OP65_INVALID) { + /* Replace the opcode */ + CE_ReplaceOPC (E, NewOPC); + + /* Remember, we had changes */ + ++Changes; + } + /* Next entry */ ++I; diff --git a/src/cc65/opcodes.h b/src/cc65/opcodes.h index bdb0c28a2..24a289c26 100644 --- a/src/cc65/opcodes.h +++ b/src/cc65/opcodes.h @@ -128,7 +128,10 @@ typedef enum { OP65_TYA, /* Number of opcodes available */ - OP65_COUNT + OP65_COUNT, + + /* Invalid opcode */ + OP65_INVALID = OP65_COUNT, } opc_t; /* 65XX addressing modes */ From 761d00b7dc873b74bb7c99a2be716098ee1e0f0a Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 31 Aug 2020 06:16:28 +0800 Subject: [PATCH 1667/2161] Ignore running removed old optimization steps. Neither list them in help info. --- src/cc65/codeopt.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 498aa0ff2..b3b0d064b 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -1029,7 +1029,9 @@ void ListOptSteps (FILE* F) fprintf (F, "any\n"); for (I = 0; I < OPTFUNC_COUNT; ++I) { - fprintf (F, "%s\n", OptFuncs[I]->Name); + if (OptFuncs[I]->Func != 0) { + fprintf (F, "%s\n", OptFuncs[I]->Name); + } } } @@ -1190,10 +1192,10 @@ static unsigned RunOptFunc (CodeSeg* S, OptFunc* F, unsigned Max) { unsigned Changes, C; - /* Don't run the function if it is disabled or if it is prohibited by the + /* Don't run the function if it is removed, disabled or prohibited by the ** code size factor */ - if (F->Disabled || F->CodeSizeFactor > S->CodeSizeFactor) { + if (F->Func == 0 || F->Disabled || F->CodeSizeFactor > S->CodeSizeFactor) { return 0; } From 29d1999947f0fb89e08b1f696dd6f97746659d13 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 31 Aug 2020 06:16:32 +0800 Subject: [PATCH 1668/2161] Rearranged the OptFunc's in alphabetic order. --- src/cc65/codeopt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index b3b0d064b..dfb42e5db 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -796,9 +796,6 @@ static OptFunc DOptLoad2 = { OptLoad2, "OptLoad2", 200, 0, static OptFunc DOptLoad3 = { OptLoad3, "OptLoad3", 0, 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 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 }; 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 }; @@ -822,6 +819,9 @@ static OptFunc DOptPtrStore3 = { OptPtrStore3, "OptPtrStore3", 100, 0, static OptFunc DOptPush1 = { OptPush1, "OptPush1", 65, 0, 0, 0, 0, 0 }; static OptFunc DOptPush2 = { OptPush2, "OptPush2", 50, 0, 0, 0, 0, 0 }; static OptFunc DOptPushPop = { OptPushPop, "OptPushPop", 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 }; static OptFunc DOptShift1 = { OptShift1, "OptShift1", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptShift2 = { OptShift2, "OptShift2", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptShift3 = { OptShift3, "OptShift3", 17, 0, 0, 0, 0, 0 }; From 676b14429dcb1357602639ea7ed455fcc48c73df Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 31 Aug 2020 06:16:36 +0800 Subject: [PATCH 1669/2161] Better opt chance for certain optimization steps e.g. OptPtrStore1 etc. --- src/cc65/codeopt.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index dfb42e5db..69ac35005 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -1241,10 +1241,10 @@ static unsigned RunOptGroup1 (CodeSeg* S) Changes += RunOptFunc (S, &DOptGotoSPAdj, 1); Changes += RunOptFunc (S, &DOptStackPtrOps, 5); + Changes += RunOptFunc (S, &DOptAdd3, 1); /* Before OptPtrLoad5! */ Changes += RunOptFunc (S, &DOptPtrStore1, 1); Changes += RunOptFunc (S, &DOptPtrStore2, 1); Changes += RunOptFunc (S, &DOptPtrStore3, 1); - Changes += RunOptFunc (S, &DOptAdd3, 1); /* Before OptPtrLoad5! */ Changes += RunOptFunc (S, &DOptPtrLoad1, 1); Changes += RunOptFunc (S, &DOptPtrLoad2, 1); Changes += RunOptFunc (S, &DOptPtrLoad3, 1); @@ -1332,7 +1332,6 @@ static unsigned RunOptGroup3 (CodeSeg* S) C += RunOptFunc (S, &DOptAdd6, 1); C += RunOptFunc (S, &DOptJumpCascades, 1); C += RunOptFunc (S, &DOptDeadJumps, 1); - C += RunOptFunc (S, &DOptRTS, 1); C += RunOptFunc (S, &DOptDeadCode, 1); C += RunOptFunc (S, &DOptBoolTrans, 1); C += RunOptFunc (S, &DOptJumpTarget1, 1); @@ -1487,11 +1486,16 @@ static unsigned RunOptGroup7 (CodeSeg* S) /* Adjust branch distances */ Changes += RunOptFunc (S, &DOptBranchDist, 3); - /* Replace conditional branches to RTS. If we had changes, we must run dead - ** code elimination again, since the change may have introduced dead code. - */ + /* Replace conditional branches to RTS */ C = RunOptFunc (S, &DOptRTSJumps2, 1); + + /* Replace JSR followed by RTS to JMP */ + C += RunOptFunc (S, &DOptRTS, 1); + Changes += C; + /* If we had changes, we must run dead code elimination again, + ** since the changes may have introduced dead code. + */ if (C) { Changes += RunOptFunc (S, &DOptDeadCode, 1); } From 44b719d957a9f02c44207a4f922012405fff0200 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Thu, 3 Sep 2020 09:16:51 +0200 Subject: [PATCH 1670/2161] Change line endings from CRLF to LF test/ref/pr1220.c was somehow added with CRLFs. Other files use just LF. --- test/ref/pr1220.c | 720 +++++++++++++++++++++++----------------------- 1 file changed, 360 insertions(+), 360 deletions(-) diff --git a/test/ref/pr1220.c b/test/ref/pr1220.c index eb9f7c7f5..0d5c1d800 100644 --- a/test/ref/pr1220.c +++ b/test/ref/pr1220.c @@ -1,360 +1,360 @@ -/* PR #1220 - test constant ternary, AND and OR */ - -#include <stdio.h> - -/* test AND/OR, results as integers */ -#define CONTEXT_A(x) do {\ - s = 0, flags = 0, t = (x),\ - printf("%3d %2X: %d\n", s, flags, t);\ - } while (0) - -/* test AND/OR in ternary context */ -#define CONTEXT_B(x) do {\ - s = 0, flags = 0, t = (x ? 42 : -42),\ - printf("%3d %2X: %d\n", s, flags, t);\ - } while (0) - -int s, t; -unsigned flags; - -int f(int x) -/* The call to this function should be and only be skipped strictly according to -** the short-circuit evaluation rule. -*/ -{ - flags |= (x != 0) << s; - ++s; - return x; -} - -#define _A f(a) -#define _B f(b) -#define _C f(c) -#define _D f(d) -#define _T (f(0), 256) -#define _F (f(256), 0) - -void f0() -/* constant short-circuit */ -{ - printf("f0()\n"); - - CONTEXT_A(_T && _T && _T); - CONTEXT_A(_F && _F && _F); - - CONTEXT_A(_T || _T || _T); - CONTEXT_A(_F || _F || _F); - - CONTEXT_A(_T && _T || _T && _T); - CONTEXT_A(_F && _F || _F && _F); - CONTEXT_A(_T && _F || _T && _F); - CONTEXT_A(_F && _T || _F && _T); - - CONTEXT_A((_T && _T) || (_T && _T)); - CONTEXT_A((_F && _F) || (_F && _F)); - CONTEXT_A((_T && _F) || (_T && _F)); - CONTEXT_A((_F && _T) || (_F && _T)); - - CONTEXT_A((_T || _T) && (_T || _T)); - CONTEXT_A((_F || _F) && (_F || _F)); - CONTEXT_A((_T || _F) && (_T || _F)); - CONTEXT_A((_F || _T) && (_F || _T)); - - printf("\n"); -} - -void f1(int a, int b, int c) -/* AND */ -{ - printf("f1(%d, %d, %d)\n", a, b, c); - - CONTEXT_A(_A && _B && _C); - - CONTEXT_A(_T && _B && _C); - CONTEXT_A(_A && _T && _C); - CONTEXT_A(_A && _B && _T); - - CONTEXT_A(_F && _B && _C); - CONTEXT_A(_A && _F && _C); - CONTEXT_A(_A && _B && _F); - - CONTEXT_A(_T && _T && _C); - CONTEXT_A(_A && _T && _T); - CONTEXT_A(_T && _B && _T); - - printf("\n"); -} - -void f2(int a, int b, int c) -/* OR */ -{ - printf("f2(%d, %d, %d)\n", a, b, c); - - CONTEXT_A(_A || _B || _C); - - CONTEXT_A(_T || _B || _C); - CONTEXT_A(_A || _T || _C); - CONTEXT_A(_A || _B || _T); - - CONTEXT_A(_F || _B || _C); - CONTEXT_A(_A || _F || _C); - CONTEXT_A(_A || _B || _F); - - CONTEXT_A(_F || _F || _C); - CONTEXT_A(_A || _F || _F); - CONTEXT_A(_F || _B || _F); - - printf("\n"); -} - -void f3(int a, int b, int c, int d) -/* AND and OR */ -{ - printf("f3(%d, %d, %d, %d)\n", a, b, c, d); - - CONTEXT_A(_A && _B || _C && _D); - CONTEXT_A(_T && _T || _C && _D); - CONTEXT_A(_A && _B || _T && _T); - - CONTEXT_A(_T && _B || _C && _D); - CONTEXT_A(_A && _T || _C && _D); - CONTEXT_A(_A && _B || _T && _D); - CONTEXT_A(_A && _B || _C && _T); - - CONTEXT_A(_F && _B || _C && _D); - CONTEXT_A(_A && _F || _C && _D); - CONTEXT_A(_A && _B || _F && _D); - CONTEXT_A(_A && _B || _C && _F); - - printf("\n"); -} - -void f4(int a, int b, int c, int d) -/* AND as top-level expression inside OR context */ -{ - printf("f4(%d, %d, %d, %d)\n", a, b, c, d); - - CONTEXT_A((_A && _B) || (_C && _D)); - CONTEXT_A((_T && _T) || (_C && _D)); - CONTEXT_A((_A && _B) || (_T && _T)); - - CONTEXT_A((_T && _B) || (_C && _D)); - CONTEXT_A((_A && _T) || (_C && _D)); - CONTEXT_A((_A && _B) || (_T && _D)); - CONTEXT_A((_A && _B) || (_C && _T)); - - CONTEXT_A((_F && _B) || (_C && _D)); - CONTEXT_A((_A && _F) || (_C && _D)); - CONTEXT_A((_A && _B) || (_F && _D)); - CONTEXT_A((_A && _B) || (_C && _F)); - - printf("\n"); -} - -void f5(int a, int b, int c, int d) -/* OR as top-level expression inside AND context */ -{ - printf("f5(%d, %d, %d, %d)\n", a, b, c, d); - - CONTEXT_A((_A || _B) && (_C || _D)); - CONTEXT_A((_F || _F) && (_C || _D)); - CONTEXT_A((_A || _B) && (_F || _F)); - - CONTEXT_A((_T || _B) && (_C || _D)); - CONTEXT_A((_A || _T) && (_C || _D)); - CONTEXT_A((_A || _B) && (_T || _D)); - CONTEXT_A((_A || _B) && (_C || _T)); - - CONTEXT_A((_F || _B) && (_C || _D)); - CONTEXT_A((_A || _F) && (_C || _D)); - CONTEXT_A((_A || _B) && (_F || _D)); - CONTEXT_A((_A || _B) && (_C || _F)); - - printf("\n"); -} - -void f0_B() -/* constant short-circuit */ -{ - printf("f0_B()\n"); - - CONTEXT_B(_T && _T && _T); - CONTEXT_B(_F && _F && _F); - - CONTEXT_B(_T || _T || _T); - CONTEXT_B(_F || _F || _F); - - CONTEXT_B(_T && _T || _T && _T); - CONTEXT_B(_F && _F || _F && _F); - CONTEXT_B(_T && _F || _T && _F); - CONTEXT_B(_F && _T || _F && _T); - - CONTEXT_B((_T && _T) || (_T && _T)); - CONTEXT_B((_F && _F) || (_F && _F)); - CONTEXT_B((_T && _F) || (_T && _F)); - CONTEXT_B((_F && _T) || (_F && _T)); - - CONTEXT_B((_T || _T) && (_T || _T)); - CONTEXT_B((_F || _F) && (_F || _F)); - CONTEXT_B((_T || _F) && (_T || _F)); - CONTEXT_B((_F || _T) && (_F || _T)); - - printf("\n"); -} - -void f1_B(int a, int b, int c) -/* AND */ -{ - printf("f1_B(%d, %d, %d)\n", a, b, c); - - CONTEXT_B(_A && _B && _C); - - CONTEXT_B(_T && _B && _C); - CONTEXT_B(_A && _T && _C); - CONTEXT_B(_A && _B && _T); - - CONTEXT_B(_F && _B && _C); - CONTEXT_B(_A && _F && _C); - CONTEXT_B(_A && _B && _F); - - CONTEXT_B(_T && _T && _C); - CONTEXT_B(_A && _T && _T); - CONTEXT_B(_T && _B && _T); - - printf("\n"); -} - -void f2_B(int a, int b, int c) -/* OR */ -{ - printf("f2_B(%d, %d, %d)\n", a, b, c); - - CONTEXT_B(_A || _B || _C); - - CONTEXT_B(_T || _B || _C); - CONTEXT_B(_A || _T || _C); - CONTEXT_B(_A || _B || _T); - - CONTEXT_B(_F || _B || _C); - CONTEXT_B(_A || _F || _C); - CONTEXT_B(_A || _B || _F); - - CONTEXT_B(_F || _F || _C); - CONTEXT_B(_A || _F || _F); - CONTEXT_B(_F || _B || _F); - - printf("\n"); -} - -void f3_B(int a, int b, int c, int d) -/* AND and OR */ -{ - printf("f3_B(%d, %d, %d, %d)\n", a, b, c, d); - - CONTEXT_B(_A && _B || _C && _D); - CONTEXT_B(_T && _T || _C && _D); - CONTEXT_B(_A && _B || _T && _T); - - CONTEXT_B(_T && _B || _C && _D); - CONTEXT_B(_A && _T || _C && _D); - CONTEXT_B(_A && _B || _T && _D); - CONTEXT_B(_A && _B || _C && _T); - - CONTEXT_B(_F && _B || _C && _D); - CONTEXT_B(_A && _F || _C && _D); - CONTEXT_B(_A && _B || _F && _D); - CONTEXT_B(_A && _B || _C && _F); - - printf("\n"); -} - -void f4_B(int a, int b, int c, int d) -/* AND as top-level expression inside OR context */ -{ - printf("f4_B(%d, %d, %d, %d)\n", a, b, c, d); - - CONTEXT_B((_A && _B) || (_C && _D)); - CONTEXT_B((_T && _T) || (_C && _D)); - CONTEXT_B((_A && _B) || (_T && _T)); - - CONTEXT_B((_T && _B) || (_C && _D)); - CONTEXT_B((_A && _T) || (_C && _D)); - CONTEXT_B((_A && _B) || (_T && _D)); - CONTEXT_B((_A && _B) || (_C && _T)); - - CONTEXT_B((_F && _B) || (_C && _D)); - CONTEXT_B((_A && _F) || (_C && _D)); - CONTEXT_B((_A && _B) || (_F && _D)); - CONTEXT_B((_A && _B) || (_C && _F)); - - printf("\n"); -} - -void f5_B(int a, int b, int c, int d) -/* OR as top-level expression inside AND context */ -{ - printf("f5_B(%d, %d, %d, %d)\n", a, b, c, d); - - CONTEXT_B((_A || _B) && (_C || _D)); - CONTEXT_B((_F || _F) && (_C || _D)); - CONTEXT_B((_A || _B) && (_F || _F)); - - CONTEXT_B((_T || _B) && (_C || _D)); - CONTEXT_B((_A || _T) && (_C || _D)); - CONTEXT_B((_A || _B) && (_T || _D)); - CONTEXT_B((_A || _B) && (_C || _T)); - - CONTEXT_B((_F || _B) && (_C || _D)); - CONTEXT_B((_A || _F) && (_C || _D)); - CONTEXT_B((_A || _B) && (_F || _D)); - CONTEXT_B((_A || _B) && (_C || _F)); - - printf("\n"); -} - -int main() -{ - f0(); - - f1(0, 0, 0); - f2(0, 0, 0); - f3(0, 0, 0, 0); - f4(0, 0, 0, 0); - f5(0, 0, 0, 0); - - f1(1, 1, 1); - f2(1, 1, 1); - f3(1, 1, 1, 1); - f4(1, 1, 1, 1); - f5(1, 1, 1, 1); - - f3(1, 0, 1, 0); - f4(1, 0, 1, 0); - f5(1, 0, 1, 0); - f3(0, 1, 0, 1); - f4(0, 1, 0, 1); - f5(0, 1, 0, 1); - - f0_B(); - - f1_B(0, 0, 0); - f2_B(0, 0, 0); - f3_B(0, 0, 0, 0); - f4_B(0, 0, 0, 0); - f5_B(0, 0, 0, 0); - - f1_B(1, 1, 1); - f2_B(1, 1, 1); - f3_B(1, 1, 1, 1); - f4_B(1, 1, 1, 1); - f5_B(1, 1, 1, 1); - - f3_B(1, 0, 1, 0); - f4_B(1, 0, 1, 0); - f5_B(1, 0, 1, 0); - f3_B(0, 1, 0, 1); - f4_B(0, 1, 0, 1); - f5_B(0, 1, 0, 1); - - return 0; -} +/* PR #1220 - test constant ternary, AND and OR */ + +#include <stdio.h> + +/* test AND/OR, results as integers */ +#define CONTEXT_A(x) do {\ + s = 0, flags = 0, t = (x),\ + printf("%3d %2X: %d\n", s, flags, t);\ + } while (0) + +/* test AND/OR in ternary context */ +#define CONTEXT_B(x) do {\ + s = 0, flags = 0, t = (x ? 42 : -42),\ + printf("%3d %2X: %d\n", s, flags, t);\ + } while (0) + +int s, t; +unsigned flags; + +int f(int x) +/* The call to this function should be and only be skipped strictly according to +** the short-circuit evaluation rule. +*/ +{ + flags |= (x != 0) << s; + ++s; + return x; +} + +#define _A f(a) +#define _B f(b) +#define _C f(c) +#define _D f(d) +#define _T (f(0), 256) +#define _F (f(256), 0) + +void f0() +/* constant short-circuit */ +{ + printf("f0()\n"); + + CONTEXT_A(_T && _T && _T); + CONTEXT_A(_F && _F && _F); + + CONTEXT_A(_T || _T || _T); + CONTEXT_A(_F || _F || _F); + + CONTEXT_A(_T && _T || _T && _T); + CONTEXT_A(_F && _F || _F && _F); + CONTEXT_A(_T && _F || _T && _F); + CONTEXT_A(_F && _T || _F && _T); + + CONTEXT_A((_T && _T) || (_T && _T)); + CONTEXT_A((_F && _F) || (_F && _F)); + CONTEXT_A((_T && _F) || (_T && _F)); + CONTEXT_A((_F && _T) || (_F && _T)); + + CONTEXT_A((_T || _T) && (_T || _T)); + CONTEXT_A((_F || _F) && (_F || _F)); + CONTEXT_A((_T || _F) && (_T || _F)); + CONTEXT_A((_F || _T) && (_F || _T)); + + printf("\n"); +} + +void f1(int a, int b, int c) +/* AND */ +{ + printf("f1(%d, %d, %d)\n", a, b, c); + + CONTEXT_A(_A && _B && _C); + + CONTEXT_A(_T && _B && _C); + CONTEXT_A(_A && _T && _C); + CONTEXT_A(_A && _B && _T); + + CONTEXT_A(_F && _B && _C); + CONTEXT_A(_A && _F && _C); + CONTEXT_A(_A && _B && _F); + + CONTEXT_A(_T && _T && _C); + CONTEXT_A(_A && _T && _T); + CONTEXT_A(_T && _B && _T); + + printf("\n"); +} + +void f2(int a, int b, int c) +/* OR */ +{ + printf("f2(%d, %d, %d)\n", a, b, c); + + CONTEXT_A(_A || _B || _C); + + CONTEXT_A(_T || _B || _C); + CONTEXT_A(_A || _T || _C); + CONTEXT_A(_A || _B || _T); + + CONTEXT_A(_F || _B || _C); + CONTEXT_A(_A || _F || _C); + CONTEXT_A(_A || _B || _F); + + CONTEXT_A(_F || _F || _C); + CONTEXT_A(_A || _F || _F); + CONTEXT_A(_F || _B || _F); + + printf("\n"); +} + +void f3(int a, int b, int c, int d) +/* AND and OR */ +{ + printf("f3(%d, %d, %d, %d)\n", a, b, c, d); + + CONTEXT_A(_A && _B || _C && _D); + CONTEXT_A(_T && _T || _C && _D); + CONTEXT_A(_A && _B || _T && _T); + + CONTEXT_A(_T && _B || _C && _D); + CONTEXT_A(_A && _T || _C && _D); + CONTEXT_A(_A && _B || _T && _D); + CONTEXT_A(_A && _B || _C && _T); + + CONTEXT_A(_F && _B || _C && _D); + CONTEXT_A(_A && _F || _C && _D); + CONTEXT_A(_A && _B || _F && _D); + CONTEXT_A(_A && _B || _C && _F); + + printf("\n"); +} + +void f4(int a, int b, int c, int d) +/* AND as top-level expression inside OR context */ +{ + printf("f4(%d, %d, %d, %d)\n", a, b, c, d); + + CONTEXT_A((_A && _B) || (_C && _D)); + CONTEXT_A((_T && _T) || (_C && _D)); + CONTEXT_A((_A && _B) || (_T && _T)); + + CONTEXT_A((_T && _B) || (_C && _D)); + CONTEXT_A((_A && _T) || (_C && _D)); + CONTEXT_A((_A && _B) || (_T && _D)); + CONTEXT_A((_A && _B) || (_C && _T)); + + CONTEXT_A((_F && _B) || (_C && _D)); + CONTEXT_A((_A && _F) || (_C && _D)); + CONTEXT_A((_A && _B) || (_F && _D)); + CONTEXT_A((_A && _B) || (_C && _F)); + + printf("\n"); +} + +void f5(int a, int b, int c, int d) +/* OR as top-level expression inside AND context */ +{ + printf("f5(%d, %d, %d, %d)\n", a, b, c, d); + + CONTEXT_A((_A || _B) && (_C || _D)); + CONTEXT_A((_F || _F) && (_C || _D)); + CONTEXT_A((_A || _B) && (_F || _F)); + + CONTEXT_A((_T || _B) && (_C || _D)); + CONTEXT_A((_A || _T) && (_C || _D)); + CONTEXT_A((_A || _B) && (_T || _D)); + CONTEXT_A((_A || _B) && (_C || _T)); + + CONTEXT_A((_F || _B) && (_C || _D)); + CONTEXT_A((_A || _F) && (_C || _D)); + CONTEXT_A((_A || _B) && (_F || _D)); + CONTEXT_A((_A || _B) && (_C || _F)); + + printf("\n"); +} + +void f0_B() +/* constant short-circuit */ +{ + printf("f0_B()\n"); + + CONTEXT_B(_T && _T && _T); + CONTEXT_B(_F && _F && _F); + + CONTEXT_B(_T || _T || _T); + CONTEXT_B(_F || _F || _F); + + CONTEXT_B(_T && _T || _T && _T); + CONTEXT_B(_F && _F || _F && _F); + CONTEXT_B(_T && _F || _T && _F); + CONTEXT_B(_F && _T || _F && _T); + + CONTEXT_B((_T && _T) || (_T && _T)); + CONTEXT_B((_F && _F) || (_F && _F)); + CONTEXT_B((_T && _F) || (_T && _F)); + CONTEXT_B((_F && _T) || (_F && _T)); + + CONTEXT_B((_T || _T) && (_T || _T)); + CONTEXT_B((_F || _F) && (_F || _F)); + CONTEXT_B((_T || _F) && (_T || _F)); + CONTEXT_B((_F || _T) && (_F || _T)); + + printf("\n"); +} + +void f1_B(int a, int b, int c) +/* AND */ +{ + printf("f1_B(%d, %d, %d)\n", a, b, c); + + CONTEXT_B(_A && _B && _C); + + CONTEXT_B(_T && _B && _C); + CONTEXT_B(_A && _T && _C); + CONTEXT_B(_A && _B && _T); + + CONTEXT_B(_F && _B && _C); + CONTEXT_B(_A && _F && _C); + CONTEXT_B(_A && _B && _F); + + CONTEXT_B(_T && _T && _C); + CONTEXT_B(_A && _T && _T); + CONTEXT_B(_T && _B && _T); + + printf("\n"); +} + +void f2_B(int a, int b, int c) +/* OR */ +{ + printf("f2_B(%d, %d, %d)\n", a, b, c); + + CONTEXT_B(_A || _B || _C); + + CONTEXT_B(_T || _B || _C); + CONTEXT_B(_A || _T || _C); + CONTEXT_B(_A || _B || _T); + + CONTEXT_B(_F || _B || _C); + CONTEXT_B(_A || _F || _C); + CONTEXT_B(_A || _B || _F); + + CONTEXT_B(_F || _F || _C); + CONTEXT_B(_A || _F || _F); + CONTEXT_B(_F || _B || _F); + + printf("\n"); +} + +void f3_B(int a, int b, int c, int d) +/* AND and OR */ +{ + printf("f3_B(%d, %d, %d, %d)\n", a, b, c, d); + + CONTEXT_B(_A && _B || _C && _D); + CONTEXT_B(_T && _T || _C && _D); + CONTEXT_B(_A && _B || _T && _T); + + CONTEXT_B(_T && _B || _C && _D); + CONTEXT_B(_A && _T || _C && _D); + CONTEXT_B(_A && _B || _T && _D); + CONTEXT_B(_A && _B || _C && _T); + + CONTEXT_B(_F && _B || _C && _D); + CONTEXT_B(_A && _F || _C && _D); + CONTEXT_B(_A && _B || _F && _D); + CONTEXT_B(_A && _B || _C && _F); + + printf("\n"); +} + +void f4_B(int a, int b, int c, int d) +/* AND as top-level expression inside OR context */ +{ + printf("f4_B(%d, %d, %d, %d)\n", a, b, c, d); + + CONTEXT_B((_A && _B) || (_C && _D)); + CONTEXT_B((_T && _T) || (_C && _D)); + CONTEXT_B((_A && _B) || (_T && _T)); + + CONTEXT_B((_T && _B) || (_C && _D)); + CONTEXT_B((_A && _T) || (_C && _D)); + CONTEXT_B((_A && _B) || (_T && _D)); + CONTEXT_B((_A && _B) || (_C && _T)); + + CONTEXT_B((_F && _B) || (_C && _D)); + CONTEXT_B((_A && _F) || (_C && _D)); + CONTEXT_B((_A && _B) || (_F && _D)); + CONTEXT_B((_A && _B) || (_C && _F)); + + printf("\n"); +} + +void f5_B(int a, int b, int c, int d) +/* OR as top-level expression inside AND context */ +{ + printf("f5_B(%d, %d, %d, %d)\n", a, b, c, d); + + CONTEXT_B((_A || _B) && (_C || _D)); + CONTEXT_B((_F || _F) && (_C || _D)); + CONTEXT_B((_A || _B) && (_F || _F)); + + CONTEXT_B((_T || _B) && (_C || _D)); + CONTEXT_B((_A || _T) && (_C || _D)); + CONTEXT_B((_A || _B) && (_T || _D)); + CONTEXT_B((_A || _B) && (_C || _T)); + + CONTEXT_B((_F || _B) && (_C || _D)); + CONTEXT_B((_A || _F) && (_C || _D)); + CONTEXT_B((_A || _B) && (_F || _D)); + CONTEXT_B((_A || _B) && (_C || _F)); + + printf("\n"); +} + +int main() +{ + f0(); + + f1(0, 0, 0); + f2(0, 0, 0); + f3(0, 0, 0, 0); + f4(0, 0, 0, 0); + f5(0, 0, 0, 0); + + f1(1, 1, 1); + f2(1, 1, 1); + f3(1, 1, 1, 1); + f4(1, 1, 1, 1); + f5(1, 1, 1, 1); + + f3(1, 0, 1, 0); + f4(1, 0, 1, 0); + f5(1, 0, 1, 0); + f3(0, 1, 0, 1); + f4(0, 1, 0, 1); + f5(0, 1, 0, 1); + + f0_B(); + + f1_B(0, 0, 0); + f2_B(0, 0, 0); + f3_B(0, 0, 0, 0); + f4_B(0, 0, 0, 0); + f5_B(0, 0, 0, 0); + + f1_B(1, 1, 1); + f2_B(1, 1, 1); + f3_B(1, 1, 1, 1); + f4_B(1, 1, 1, 1); + f5_B(1, 1, 1, 1); + + f3_B(1, 0, 1, 0); + f4_B(1, 0, 1, 0); + f5_B(1, 0, 1, 0); + f3_B(0, 1, 0, 1); + f4_B(0, 1, 0, 1); + f5_B(0, 1, 0, 1); + + return 0; +} From bc5570b708a8ea99f3e50ccdfbbc52e3739bdf0f Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 20 Aug 2020 07:52:17 +0800 Subject: [PATCH 1671/2161] Fixed logical-NOT in constant context. --- src/cc65/expr.c | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index b91fab8a8..7fb6e455f 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1908,14 +1908,19 @@ void hie10 (ExprDesc* Expr) case TOK_BOOL_NOT: NextToken (); - if (evalexpr (CF_NONE, hie10, Expr) == 0) { + BoolExpr (hie10, Expr); + if (ED_IsConstAbs (Expr)) { /* Constant expression */ Expr->IVal = !Expr->IVal; } else { + /* Not constant, load into the primary */ + LoadExpr (CF_NONE, Expr); g_bneg (TypeOf (Expr->Type)); ED_FinalizeRValLoad (Expr); ED_TestDone (Expr); /* bneg will set cc */ } + /* The result type is always boolean */ + Expr->Type = type_bool; break; case TOK_STAR: @@ -3981,29 +3986,6 @@ void hie0 (ExprDesc *Expr) -int evalexpr (unsigned Flags, void (*Func) (ExprDesc*), ExprDesc* Expr) -/* Will evaluate an expression via the given function. If the result is a -** constant, 0 is returned and the value is put in the Expr struct. If the -** result is not constant, LoadExpr is called to bring the value into the -** primary register and 1 is returned. -*/ -{ - /* Evaluate */ - ExprWithCheck (Func, Expr); - - /* Check for a constant expression */ - if (ED_IsConstAbs (Expr)) { - /* Constant expression */ - return 0; - } else { - /* Not constant, load into the primary */ - LoadExpr (Flags, Expr); - return 1; - } -} - - - void Expression0 (ExprDesc* Expr) /* Evaluate an expression via hie0 and put the result into the primary register */ { From 8e0b2f083356f206b6f5529d0d60b32fff3a7a0a Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 20 Aug 2020 07:52:20 +0800 Subject: [PATCH 1672/2161] Object addresses as non-NULL in boolean context. --- src/cc65/expr.c | 32 +++++++++++++++++++++----------- src/cc65/exprdesc.c | 8 ++++++++ src/cc65/exprdesc.h | 3 +++ src/cc65/testexpr.c | 5 +++++ 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 7fb6e455f..94109d559 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1912,6 +1912,9 @@ void hie10 (ExprDesc* Expr) if (ED_IsConstAbs (Expr)) { /* Constant expression */ Expr->IVal = !Expr->IVal; + } else if (ED_IsAddrExpr (Expr)) { + /* Address != NULL, so !Address == 0 */ + ED_MakeConstBool (Expr, 0); } else { /* Not constant, load into the primary */ LoadExpr (CF_NONE, Expr); @@ -3222,7 +3225,7 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) Error ("Scalar expression expected"); ED_MakeConstBool (Expr, 0); } else if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { - if (!ED_IsConstAbs (Expr)) { + if (!ED_IsConstBool (Expr)) { /* Set the test flag */ ED_RequireTest (Expr); @@ -3237,7 +3240,7 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) /* Generate the jump */ g_falsejump (CF_NONE, FalseLab); - } else if (Expr->IVal == 0) { + } else if (Expr->IVal == 0 && !ED_IsAddrExpr (Expr)) { /* Skip remaining */ Flags |= E_EVAL_UNEVAL; } @@ -3264,7 +3267,7 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) Error ("Scalar expression expected"); ED_MakeConstBool (&Expr2, 0); } else if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { - if (!ED_IsConstAbs (&Expr2)) { + if (!ED_IsConstBool (&Expr2)) { ED_RequireTest (&Expr2); LoadExpr (CF_FORCECHAR, &Expr2); @@ -3276,7 +3279,7 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) /* We need the true label for the last expression */ HasTrueJump = 1; } - } else if (Expr2.IVal == 0) { + } else if (Expr2.IVal == 0 && !ED_IsAddrExpr (&Expr2)) { /* Skip remaining */ Flags |= E_EVAL_UNEVAL; /* The value of the expression will be false */ @@ -3313,7 +3316,8 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) } /* Convert to bool */ - if (ED_IsConstAbs (Expr) && Expr->IVal != 0) { + if ((ED_IsConstAbs (Expr) && Expr->IVal != 0) || + ED_IsAddrExpr (Expr)) { ED_MakeConstBool (Expr, 1); } else { Expr->Type = type_bool; @@ -3354,7 +3358,7 @@ static void hieOr (ExprDesc *Expr) ED_MakeConstBool (Expr, 0); } else if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { - if (!ED_IsConstAbs (Expr)) { + if (!ED_IsConstBool (Expr)) { /* Test the lhs if we haven't had && operators. If we had them, the ** jump is already in place and there's no need to do the test. */ @@ -3377,7 +3381,7 @@ static void hieOr (ExprDesc *Expr) /* Jump to TrueLab if true */ g_truejump (CF_NONE, TrueLab); } - } else if (Expr->IVal != 0) { + } else if (Expr->IVal != 0 || ED_IsAddrExpr (Expr)) { /* Skip remaining */ Flags |= E_EVAL_UNEVAL; } @@ -3406,7 +3410,7 @@ static void hieOr (ExprDesc *Expr) ED_MakeConstBool (&Expr2, 0); } else if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { - if (!ED_IsConstAbs (&Expr2)) { + if (!ED_IsConstBool (&Expr2)) { /* If there is more to come, add shortcut boolean eval */ if (!AndOp) { ED_RequireTest (&Expr2); @@ -3418,7 +3422,7 @@ static void hieOr (ExprDesc *Expr) } g_truejump (CF_NONE, TrueLab); } - } else if (Expr2.IVal != 0) { + } else if (Expr2.IVal != 0 || ED_IsAddrExpr (&Expr2)) { /* Skip remaining */ Flags |= E_EVAL_UNEVAL; /* The result is always true */ @@ -3429,7 +3433,8 @@ static void hieOr (ExprDesc *Expr) } /* Convert to bool */ - if (ED_IsConstAbs (Expr) && Expr->IVal != 0) { + if ((ED_IsConstAbs (Expr) && Expr->IVal != 0) || + ED_IsAddrExpr (Expr)) { ED_MakeConstBool (Expr, 1); } else { Expr->Type = type_bool; @@ -3483,7 +3488,7 @@ static void hieQuest (ExprDesc* Expr) /* Check if it's a ternary expression */ if (CurTok.Tok == TOK_QUEST) { - int ConstantCond = ED_IsConstAbsInt (Expr); + int ConstantCond = ED_IsConstBool (Expr); unsigned Flags = Expr->Flags & E_MASK_KEEP_RESULT; ED_Init (&Expr2); @@ -3493,6 +3498,11 @@ static void hieQuest (ExprDesc* Expr) NextToken (); + /* Convert non-integer constant boolean */ + if (ED_IsAddrExpr (Expr)) { + ED_MakeConstBool (Expr, 1); + } + if (!ConstantCond) { /* Condition codes not set, request a test */ ED_RequireTest (Expr); diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index 62738bed7..e82d0fafc 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -389,6 +389,14 @@ int ED_IsConstAbsInt (const ExprDesc* Expr) +int ED_IsConstBool (const ExprDesc* Expr) +/* Return true if the expression can be constantly evaluated as a boolean. */ +{ + return ED_IsConstAbsInt (Expr) || ED_IsAddrExpr (Expr); +} + + + int ED_IsConst (const ExprDesc* Expr) /* Return true if the expression denotes a constant of some sort. This can be a ** numeric constant, the address of a global variable (maybe with offset) or diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index c435b3c38..463828db6 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -640,6 +640,9 @@ int ED_IsConstAbs (const ExprDesc* Expr); int ED_IsConstAbsInt (const ExprDesc* Expr); /* Return true if the expression is a constant (numeric) integer. */ +int ED_IsConstBool (const ExprDesc* Expr); +/* Return true if the expression can be constantly evaluated as a boolean. */ + int ED_IsConst (const ExprDesc* Expr); /* Return true if the expression denotes a constant of some sort. This can be a ** numeric constant, the address of a global variable (maybe with offset) or diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index b924eaa40..80fe4bc3d 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -77,6 +77,11 @@ unsigned Test (unsigned Label, int Invert) g_jump (Label); } + } else if (ED_IsAddrExpr (&Expr)) { + + /* Object addresses are non-NULL */ + Result = 1; + } else { /* Result is unknown */ From f849de6769ac4f887c35fc9561fd38c4e584f708 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 20 Aug 2020 07:52:22 +0800 Subject: [PATCH 1673/2161] Object addresses as non-NULL for comparison with NULL. --- src/cc65/expr.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 94109d559..a562dfa76 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -2428,6 +2428,33 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ */ WarnConstCompareResult (Expr); + } else if (ED_CodeRangeIsEmpty (&Expr2) && + ((ED_IsAddrExpr (Expr) && ED_IsNullPtr (&Expr2)) || + (ED_IsNullPtr (Expr) && (ED_IsAddrExpr (&Expr2))))) { + + /* Object addresses are inequal to null pointer */ + Expr->IVal = (Tok != TOK_EQ); + if (ED_IsNullPtr (&Expr2)) { + if (Tok == TOK_LT || Tok == TOK_LE) { + Expr->IVal = 0; + } + } else { + if (Tok == TOK_GT || Tok == TOK_GE) { + Expr->IVal = 0; + } + } + + /* Get rid of unwanted flags */ + ED_MakeConstBool (Expr, Expr->IVal); + + /* If the result is constant, this is suspicious when not in + ** preprocessor mode. + */ + WarnConstCompareResult (Expr); + + /* Both operands are static, remove the generated code */ + RemoveCode (&Mark1); + } else { /* Determine the signedness of the operands */ @@ -2485,7 +2512,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ case TOK_EQ: if (Expr2.IVal < LeftMin || Expr2.IVal > LeftMax) { - ED_MakeConstAbsInt (Expr, 0); + ED_MakeConstBool (Expr, 0); WarnConstCompareResult (Expr); goto Done; } @@ -2493,7 +2520,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ case TOK_NE: if (Expr2.IVal < LeftMin || Expr2.IVal > LeftMax) { - ED_MakeConstAbsInt (Expr, 1); + ED_MakeConstBool (Expr, 1); WarnConstCompareResult (Expr); goto Done; } @@ -2501,7 +2528,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ case TOK_LT: if (Expr2.IVal <= LeftMin || Expr2.IVal > LeftMax) { - ED_MakeConstAbsInt (Expr, Expr2.IVal > LeftMax); + ED_MakeConstBool (Expr, Expr2.IVal > LeftMax); WarnConstCompareResult (Expr); goto Done; } @@ -2509,7 +2536,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ case TOK_LE: if (Expr2.IVal < LeftMin || Expr2.IVal >= LeftMax) { - ED_MakeConstAbsInt (Expr, Expr2.IVal >= LeftMax); + ED_MakeConstBool (Expr, Expr2.IVal >= LeftMax); WarnConstCompareResult (Expr); goto Done; } @@ -2517,7 +2544,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ case TOK_GE: if (Expr2.IVal <= LeftMin || Expr2.IVal > LeftMax) { - ED_MakeConstAbsInt (Expr, Expr2.IVal <= LeftMin); + ED_MakeConstBool (Expr, Expr2.IVal <= LeftMin); WarnConstCompareResult (Expr); goto Done; } @@ -2525,7 +2552,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ case TOK_GT: if (Expr2.IVal < LeftMin || Expr2.IVal >= LeftMax) { - ED_MakeConstAbsInt (Expr, Expr2.IVal < LeftMin); + ED_MakeConstBool (Expr, Expr2.IVal < LeftMin); WarnConstCompareResult (Expr); goto Done; } From df07e23f2c523838723e5c69cdcf35ef88d4ad59 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 5 Sep 2020 11:15:17 +0800 Subject: [PATCH 1674/2161] Fixed bnegeax funcinfo on register usage. --- src/cc65/codeinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d7d85a12d..a89f6d54c 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -102,7 +102,7 @@ static const FuncInfo FuncInfoTable[] = { { "asreax4", REG_EAX, REG_EAXY | REG_TMP1 }, { "bnega", REG_A, REG_AX }, { "bnegax", REG_AX, REG_AX }, - { "bnegeax", REG_EAX, REG_EAX }, + { "bnegeax", REG_EAX, REG_EAX | REG_TMP1 }, { "booleq", REG_NONE, REG_AX }, { "boolge", REG_NONE, REG_AX }, { "boolgt", REG_NONE, REG_AX }, From 903e84c24cb9887a6d5029f78c3daeba50b70cea Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 31 Aug 2020 17:45:25 +0800 Subject: [PATCH 1675/2161] Std-functions are no longer inlined if they are unevaluated. --- src/cc65/expr.c | 2 +- src/cc65/exprdesc.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index a562dfa76..d39c9ebb6 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -593,7 +593,7 @@ static void FunctionCall (ExprDesc* Expr) } /* Check for known standard functions and inline them */ - if (Expr->Name != 0) { + if (Expr->Name != 0 && !ED_IsUneval (Expr)) { int StdFunc = FindStdFunc ((const char*) Expr->Name); if (StdFunc >= 0) { /* Inline this function */ diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index 463828db6..810d68965 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -474,13 +474,13 @@ void ED_MarkForUneval (ExprDesc* Expr); /* Mark the expression as not to be evaluated */ #if defined(HAVE_INLINE) -INLINE int ED_MayBeUneval (const ExprDesc* Expr) -/* Check if the expression may be uevaluated */ +INLINE int ED_IsUneval (const ExprDesc* Expr) +/* Check if the expression is not to be evaluated */ { return (Expr->Flags & E_EVAL_UNEVAL) == E_EVAL_UNEVAL; } #else -# define ED_MayBeUneval(Expr) (((Expr)->Flags & E_EVAL_UNEVAL) == E_EVAL_UNEVAL) +# define ED_IsUneval(Expr) (((Expr)->Flags & E_EVAL_UNEVAL) == E_EVAL_UNEVAL) #endif #if defined(HAVE_INLINE) From e2f950b15e323bb89b31b2a0259c684df3edf262 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 31 Aug 2020 17:45:36 +0800 Subject: [PATCH 1676/2161] Avoided referencing string literals with sizeof so that they are not output if unused elsewhere. --- src/cc65/expr.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index d39c9ebb6..e1b22ac50 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -923,7 +923,11 @@ static void Primary (ExprDesc* E) case TOK_SCONST: case TOK_WCSCONST: /* String literal */ - E->LVal = UseLiteral (CurTok.SVal); + if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + E->LVal = UseLiteral (CurTok.SVal); + } else { + E->LVal = CurTok.SVal; + } E->Type = GetCharArrayType (GetLiteralSize (CurTok.SVal)); E->Flags = E_LOC_LITERAL | E_RTYPE_RVAL | E_ADDRESS_OF; E->IVal = 0; @@ -1996,19 +2000,18 @@ void hie10 (ExprDesc* Expr) /* Remember the output queue pointer */ CodeMark Mark; GetCodePos (&Mark); - hie10 (Expr); - if (ED_IsBitField (Expr)) { + + /* The expression shall be unevaluated */ + ExprDesc Uneval; + ED_Init (&Uneval); + ED_MarkForUneval (&Uneval); + hie10 (&Uneval); + if (ED_IsBitField (&Uneval)) { Error ("Cannot apply 'sizeof' to bit-field"); Size = 0; } else { - /* If the expression is a literal string, release it, so it - ** won't be output as data if not used elsewhere. - */ - if (ED_IsLocLiteral (Expr)) { - ReleaseLiteral (Expr->LVal); - } /* Calculate the size */ - Size = ExprCheckedSizeOf (Expr->Type); + Size = ExprCheckedSizeOf (Uneval.Type); } /* Remove any generated code */ RemoveCode (&Mark); From 6e0fb630d75b517faa48eea4a01b7edf76ac5d59 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 5 Sep 2020 21:31:22 +0800 Subject: [PATCH 1677/2161] Fixed check for processor flags usage in case of PHP. --- src/cc65/codeent.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index 7dd90833b..09ca0a9c5 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -476,6 +476,11 @@ int CE_UseLoadFlags (CodeEntry* E) } } + /* PHP will use all flags */ + if (E->OPC == OP65_PHP) { + return 1; + } + /* Anything else */ return 0; } From 1cde952cf52a4c606680d1aebe9d9d0eaa146c4d Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 7 Sep 2020 04:19:27 +0800 Subject: [PATCH 1678/2161] Fixed comparing an enum type with a non-enum type in DoCompare(). --- src/cc65/typecmp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 24d9a385f..f179bff14 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -203,8 +203,8 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) if ((IsTypeEnum (lhs) || IsTypeEnum (rhs))) { /* Compare the tag types */ - Sym1 = GetESUSymEntry (lhs); - Sym2 = GetESUSymEntry (rhs); + Sym1 = IsTypeEnum (lhs) ? GetESUSymEntry (lhs) : 0; + Sym2 = IsTypeEnum (rhs) ? GetESUSymEntry (rhs) : 0; if (Sym1 != Sym2) { if (Sym1 == 0 || Sym2 == 0) { From 6bb2d1d5d1d67e63af8e84619eaa261bfda5d952 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 7 Sep 2020 04:19:27 +0800 Subject: [PATCH 1679/2161] Fixed a comment on struct/union types in DoCompare(). --- src/cc65/typecmp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index f179bff14..1f4643e73 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -378,11 +378,13 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) if (Sym1 != Sym2) { /* Both must be in the same scope and have the same name to - ** be identical. This shouldn't happen in the current code - ** base, but we still do this to be future-proof. + ** be identical. */ if (Sym1->Owner != Sym2->Owner || strcmp (Sym1->Name, Sym2->Name) != 0) { + /* This shouldn't happen in the current code base, but + ** we still handle this case to be future-proof. + */ SetResult (Result, TC_INCOMPATIBLE); return; } From 23a8b2c303f7329b29c7d9eb0604b056f66c75a4 Mon Sep 17 00:00:00 2001 From: Tevo <estevan.cps@gmail.com> Date: Thu, 3 Sep 2020 00:06:31 -0300 Subject: [PATCH 1680/2161] Define integer size macros for lacking systems Define integer size macros for lacking systems --- src/common/inttypes.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/common/inttypes.h b/src/common/inttypes.h index 29ac778ef..a36543e63 100644 --- a/src/common/inttypes.h +++ b/src/common/inttypes.h @@ -57,6 +57,16 @@ typedef size_t uintptr_t; typedef ptrdiff_t intmax_t; typedef size_t uintmax_t; +#define INT8_MAX (0x7F) +#define INT16_MAX (0x7FFF) +#define INT32_MAX (0x7FFFFFFF) + +#define INT8_MIN (-INT8_MAX - 1) +#define INT16_MIN (-INT16_MAX - 1) + +#define UINT8_MAX (0xFF) +#define UINT16_MAX (0xFFFF) + #endif From 1e7a9e44afeefdcd3746ac0ff1ec304a0b9e785b Mon Sep 17 00:00:00 2001 From: Tevo <estevan.cps@gmail.com> Date: Sun, 6 Sep 2020 21:19:01 -0300 Subject: [PATCH 1681/2161] Update comment to reflect addition of integer boundary constants --- src/common/inttypes.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/inttypes.h b/src/common/inttypes.h index a36543e63..0d8caf32a 100644 --- a/src/common/inttypes.h +++ b/src/common/inttypes.h @@ -38,7 +38,8 @@ -/* If we have <stdint.h>, include it; otherwise, adapt types from <stddef.h>. +/* If we have <stdint.h>, include it; otherwise, adapt types from <stddef.h> +** and define integer boundary constants. ** gcc and msvc don't define __STDC_VERSION__ without special flags, so check ** for them explicitly. Undefined symbols are replaced by zero; so, checks for ** defined(__GNUC__) and defined(_MSC_VER) aren't necessary. From 9a0e4a35e1c1083f3c3c900c1d3888a048b30a96 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sat, 5 Sep 2020 20:03:24 +0200 Subject: [PATCH 1682/2161] Fix enum bit-field ICE #1244 This previously resulted in an ICE: cc65: Check failed: (Entry->Type->C & T_MASK_SIGN) == T_SIGN_SIGNED, file 'cc65/symtab.c', line 874 This CHECK is in the code that deals with changing `int` bitfields to `unsigned int`. Work around this by treating enum bit-fields as having their signedness specified, so this type change code does not get called. Fixes #1244. --- src/cc65/declare.c | 6 ++ src/cc65/symtab.c | 1 + test/val/enum-bitfield.c | 158 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 test/val/enum-bitfield.c diff --git a/src/cc65/declare.c b/src/cc65/declare.c index d6286e62d..857021671 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1446,6 +1446,12 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, D->Type[0].C |= T_ENUM; SetESUSymEntry (D->Type, Entry); D->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. + */ + if (SignednessSpecified) { + *SignednessSpecified = 1; + } break; case TOK_IDENT: diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 10dc0d3ff..5546d450c 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -870,6 +870,7 @@ SymEntry* AddBitField (const char* Name, const Type* T, unsigned Offs, if (!SignednessSpecified) { /* int is treated as signed int everywhere except bit-fields; switch it to unsigned, ** since this is allowed for bit-fields and avoids sign-extension, so is much faster. + ** enums set SignednessSpecified to 1 to avoid this adjustment. */ CHECK ((Entry->Type->C & T_MASK_SIGN) == T_SIGN_SIGNED); Entry->Type->C &= ~T_MASK_SIGN; diff --git a/test/val/enum-bitfield.c b/test/val/enum-bitfield.c new file mode 100644 index 000000000..62e05f71f --- /dev/null +++ b/test/val/enum-bitfield.c @@ -0,0 +1,158 @@ +/* + Copyright 2020 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. +*/ + +/* + Tests of enum bit-fields; see https://github.com/cc65/cc65/issues/1244 +*/ + +#include <stdio.h> + +static unsigned char failures = 0; + +/* Enum with underlying type unsigned int. */ +enum e10u { + E10U_200 = 200, + E10U_1000 = 1000, +}; + +static struct enum_bitfield_uint { + enum e10u x : 1; + enum e10u y : 8; + enum e10u z : 16; +} e10ubf = {0, E10U_200, E10U_1000}; + +static void test_enum_bitfield_uint(void) +{ + if (sizeof (struct enum_bitfield_uint) != 4) { + printf ("Got sizeof(struct enum_bitfield_uint) = %zu, expected 4.\n", + sizeof(struct enum_bitfield_uint)); + failures++; + } + + if (e10ubf.x != 0) { + printf ("Got e10ubf.x = %u, expected 0.\n", e10ubf.x); + failures++; + } + if (e10ubf.y != 200) { + printf ("Got e10ubf.y = %u, expected 200.\n", e10ubf.y); + failures++; + } + if (e10ubf.z != 1000) { + printf ("Got e10ubf.z = %u, expected 1000.\n", e10ubf.z); + failures++; + } + + e10ubf.x = 1; + e10ubf.y = 17; + e10ubf.z = 1023; + + if (e10ubf.x != 1) { + printf ("Got e10ubf.x = %u, expected 1.\n", e10ubf.x); + failures++; + } + + /* Check signedness, should be unsigned. */ + { + long v = e10ubf.x - 2; + if (v < 0) { + printf ("Got negative v = %ld, expected large positive.\n", v); + failures++; + } + } + + if (e10ubf.y != 17) { + printf ("Got e10ubf.y = %u, expected 17.\n", e10ubf.y); + failures++; + } + if (e10ubf.z != 1023) { + printf ("Got e10ubf.z = %u, expected 1023.\n", e10ubf.z); + failures++; + } +} + +/* Enum with underlying type signed int. */ +enum e11i { + E11I_M1 = -1, + E11I_100 = 100, + E11I_1000 = 1000, +}; + +static struct enum_bitfield_int { + enum e11i x : 2; + enum e11i y : 8; + enum e11i z : 16; +} e11ibf = {E11I_M1, E11I_100, E11I_1000}; + +static void test_enum_bitfield_int(void) +{ + if (sizeof (struct enum_bitfield_int) != 4) { + printf ("Got sizeof(struct enum_bitfield_int) = %zu, expected 4.\n", + sizeof(struct enum_bitfield_int)); + failures++; + } + + if (e11ibf.x != -1) { + printf ("Got e11ibf.x = %d, expected -1.\n", e11ibf.x); + failures++; + } + if (e11ibf.y != 100) { + printf ("Got e11ibf.y = %d, expected 100.\n", e11ibf.y); + failures++; + } + if (e11ibf.z != 1000) { + printf ("Got e11ibf.z = %d, expected 1000.\n", e11ibf.z); + failures++; + } + + e11ibf.x = 1; + e11ibf.y = 17; + e11ibf.z = 1023; + + if (e11ibf.x != 1) { + printf ("Got e11ibf.x = %d, expected 1.\n", e11ibf.x); + failures++; + } + + /* Check signedness, should be signed. */ + { + long v = e11ibf.x - 2; + if (v > 0) { + printf ("Got positive v = %ld, expected negative.\n", v); + failures++; + } + } + + if (e11ibf.y != 17) { + printf ("Got e11ibf.y = %d, expected 17.\n", e11ibf.y); + failures++; + } + if (e11ibf.z != 1023) { + printf ("Got e11ibf.z = %d, expected 1023.\n", e11ibf.z); + failures++; + } +} + +int main(void) +{ + test_enum_bitfield_uint(); + test_enum_bitfield_int(); + printf("failures: %u\n", failures); + return failures; +} From 64ef562fa76cb89487f67fe7568ba350132f4696 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 7 Sep 2020 05:11:48 +0800 Subject: [PATCH 1683/2161] Moved all optimization steps from codeopt.c and some optimization steps from coptind.c into new separate files. --- src/cc65.vcxproj | 4 + src/cc65/codeopt.c | 655 +------------------------ src/cc65/coptind.c | 1105 +++---------------------------------------- src/cc65/coptind.h | 87 +--- src/cc65/coptjmp.c | 1009 +++++++++++++++++++++++++++++++++++++++ src/cc65/coptjmp.h | 116 +++++ src/cc65/coptmisc.c | 735 ++++++++++++++++++++++++++++ src/cc65/coptmisc.h | 113 +++++ 8 files changed, 2046 insertions(+), 1778 deletions(-) create mode 100644 src/cc65/coptjmp.c create mode 100644 src/cc65/coptjmp.h create mode 100644 src/cc65/coptmisc.c create mode 100644 src/cc65/coptmisc.h diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index d566c8bc1..1015b389f 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -93,6 +93,8 @@ <ClInclude Include="cc65\coptc02.h" /> <ClInclude Include="cc65\coptcmp.h" /> <ClInclude Include="cc65\coptind.h" /> + <ClInclude Include="cc65\coptjmp.h" /> + <ClInclude Include="cc65\coptmisc.h" /> <ClInclude Include="cc65\coptneg.h" /> <ClInclude Include="cc65\coptptrload.h" /> <ClInclude Include="cc65\coptptrstore.h" /> @@ -167,6 +169,8 @@ <ClCompile Include="cc65\coptc02.c" /> <ClCompile Include="cc65\coptcmp.c" /> <ClCompile Include="cc65\coptind.c" /> + <ClCompile Include="cc65\coptjmp.c" /> + <ClCompile Include="cc65\coptmisc.c" /> <ClCompile Include="cc65\coptneg.c" /> <ClCompile Include="cc65\coptptrload.c" /> <ClCompile Include="cc65\coptptrstore.c" /> diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 69ac35005..4a7722830 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -48,7 +48,6 @@ #include "xsprintf.h" /* cc65 */ -#include "asmlabel.h" #include "codeent.h" #include "codeinfo.h" #include "codeopt.h" @@ -56,6 +55,8 @@ #include "coptc02.h" #include "coptcmp.h" #include "coptind.h" +#include "coptjmp.h" +#include "coptmisc.h" #include "coptneg.h" #include "coptptrload.h" #include "coptptrstore.h" @@ -69,660 +70,8 @@ #include "error.h" #include "global.h" #include "output.h" -#include "symtab.h" -/*****************************************************************************/ -/* Optimize loads */ -/*****************************************************************************/ - - - -static 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. -*/ -{ - unsigned I; - unsigned Changes = 0; - - /* Walk over the entries */ - I = 0; - while (I < CS_GetEntryCount (S)) { - - CodeEntry* E; - - /* Get next entry */ - E = CS_GetEntry (S, I); - - /* Check for the sequence */ - if (CE_IsCallTo (E, "ldaxysp") && - RegValIsKnown (E->RI->In.RegY) && - !RegXUsed (S, I+1)) { - - CodeEntry* X; - - /* Reload the Y register */ - const char* Arg = MakeHexArg (E->RI->In.RegY - 1); - X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); - CS_InsertEntry (S, X, I+1); - - /* Load from stack */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, E->LI); - CS_InsertEntry (S, X, I+2); - - /* Now remove the call to the subroutine */ - CS_DelEntry (S, I); - - /* Remember, we had changes */ - ++Changes; - - } - - /* Next entry */ - ++I; - - } - - /* Return the number of changes made */ - return Changes; -} - - - -static unsigned OptLoad2 (CodeSeg* S) -/* Replace calls to ldaxysp by inline code */ -{ - unsigned I; - unsigned Changes = 0; - - /* Walk over the entries */ - I = 0; - while (I < CS_GetEntryCount (S)) { - - CodeEntry* L[3]; - - /* Get next entry */ - L[0] = CS_GetEntry (S, I); - - /* Check for the sequence */ - if (CE_IsCallTo (L[0], "ldaxysp")) { - - CodeEntry* X; - - /* Followed by sta abs/stx abs? */ - if (CS_GetEntries (S, L+1, I+1, 2) && - L[1]->OPC == OP65_STA && - L[2]->OPC == OP65_STX && - (L[1]->Arg == 0 || - L[2]->Arg == 0 || - strcmp (L[1]->Arg, L[2]->Arg) != 0) && - !CS_RangeHasLabel (S, I+1, 2) && - !RegXUsed (S, I+3)) { - - /* A/X are stored into memory somewhere and X is not used - ** later - */ - - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[0]->LI); - CS_InsertEntry (S, X, I+3); - - /* sta abs */ - X = NewCodeEntry (OP65_STA, L[2]->AM, L[2]->Arg, 0, L[2]->LI); - CS_InsertEntry (S, X, I+4); - - /* dey */ - 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); - CS_InsertEntry (S, X, I+6); - - /* sta abs */ - X = NewCodeEntry (OP65_STA, L[1]->AM, L[1]->Arg, 0, L[1]->LI); - CS_InsertEntry (S, X, I+7); - - /* Now remove the call to the subroutine and the sta/stx */ - CS_DelEntries (S, I, 3); - - } else { - - /* Standard replacement */ - - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[0]->LI); - CS_InsertEntry (S, X, I+1); - - /* tax */ - X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, L[0]->LI); - CS_InsertEntry (S, X, I+2); - - /* dey */ - 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); - CS_InsertEntry (S, X, I+4); - - /* Now remove the call to the subroutine */ - CS_DelEntry (S, I); - - } - - /* Remember, we had changes */ - ++Changes; - - } - - /* Next entry */ - ++I; - } - - /* Return the number of changes made */ - return Changes; -} - - - -static unsigned OptLoad3 (CodeSeg* S) -/* Remove repeated loads from one and the same memory location */ -{ - unsigned Changes = 0; - CodeEntry* Load = 0; - - /* Walk over the entries */ - unsigned I = 0; - while (I < CS_GetEntryCount (S)) { - - /* Get next entry */ - CodeEntry* E = CS_GetEntry (S, I); - - /* Forget a preceeding load if we have a label */ - if (Load && CE_HasLabel (E)) { - Load = 0; - } - - /* Check if this insn is a load */ - if (E->Info & OF_LOAD) { - - CodeEntry* N; - - /* If we had a preceeding load that is identical, remove this one. - ** If it is not identical, or we didn't have one, remember it. - */ - if (Load != 0 && - E->OPC == Load->OPC && - E->AM == Load->AM && - ((E->Arg == 0 && Load->Arg == 0) || - strcmp (E->Arg, Load->Arg) == 0) && - (N = CS_GetNextEntry (S, I)) != 0 && - (N->Info & OF_CBRA) == 0) { - - /* Now remove the call to the subroutine */ - CS_DelEntry (S, I); - - /* Remember, we had changes */ - ++Changes; - - /* Next insn */ - continue; - - } else { - - Load = E; - - } - - } else if ((E->Info & OF_CMP) == 0 && (E->Info & OF_CBRA) == 0) { - /* Forget the first load on occurance of any insn we don't like */ - Load = 0; - } - - /* Next entry */ - ++I; - } - - /* Return the number of changes made */ - return Changes; -} - - - -/*****************************************************************************/ -/* Decouple operations */ -/*****************************************************************************/ - - - -static unsigned OptDecouple (CodeSeg* S) -/* Decouple operations, that is, do the following replacements: -** -** dex -> ldx #imm -** inx -> ldx #imm -** dey -> ldy #imm -** iny -> ldy #imm -** tax -> ldx #imm -** txa -> lda #imm -** tay -> ldy #imm -** tya -> lda #imm -** lda zp -> lda #imm -** ldx zp -> ldx #imm -** ldy zp -> ldy #imm -** -** Provided that the register values are known of course. -*/ -{ - unsigned Changes = 0; - unsigned I; - - /* Walk over the entries */ - I = 0; - while (I < CS_GetEntryCount (S)) { - - const char* Arg; - - /* Get next entry and it's input register values */ - CodeEntry* E = CS_GetEntry (S, I); - const RegContents* In = &E->RI->In; - - /* Assume we have no replacement */ - CodeEntry* X = 0; - - /* Check the instruction */ - switch (E->OPC) { - - case OP65_DEA: - if (RegValIsKnown (In->RegA)) { - Arg = MakeHexArg ((In->RegA - 1) & 0xFF); - X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); - } - break; - - case OP65_DEX: - if (RegValIsKnown (In->RegX)) { - Arg = MakeHexArg ((In->RegX - 1) & 0xFF); - X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI); - } - break; - - case OP65_DEY: - if (RegValIsKnown (In->RegY)) { - Arg = MakeHexArg ((In->RegY - 1) & 0xFF); - X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); - } - break; - - case OP65_INA: - if (RegValIsKnown (In->RegA)) { - Arg = MakeHexArg ((In->RegA + 1) & 0xFF); - X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); - } - break; - - case OP65_INX: - if (RegValIsKnown (In->RegX)) { - Arg = MakeHexArg ((In->RegX + 1) & 0xFF); - X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI); - } - break; - - case OP65_INY: - if (RegValIsKnown (In->RegY)) { - Arg = MakeHexArg ((In->RegY + 1) & 0xFF); - X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); - } - break; - - case OP65_LDA: - if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Use & REG_ZP, In)) { - case REG_TMP1: - Arg = MakeHexArg (In->Tmp1); - X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); - break; - - case REG_PTR1_LO: - Arg = MakeHexArg (In->Ptr1Lo); - X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); - break; - - case REG_PTR1_HI: - Arg = MakeHexArg (In->Ptr1Hi); - X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); - break; - - case REG_SREG_LO: - Arg = MakeHexArg (In->SRegLo); - X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); - break; - - case REG_SREG_HI: - Arg = MakeHexArg (In->SRegHi); - X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); - break; - } - } - break; - - case OP65_LDX: - if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Use & REG_ZP, In)) { - case REG_TMP1: - Arg = MakeHexArg (In->Tmp1); - X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI); - break; - - case REG_PTR1_LO: - Arg = MakeHexArg (In->Ptr1Lo); - X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI); - break; - - case REG_PTR1_HI: - Arg = MakeHexArg (In->Ptr1Hi); - X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI); - break; - - case REG_SREG_LO: - Arg = MakeHexArg (In->SRegLo); - X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI); - break; - - case REG_SREG_HI: - Arg = MakeHexArg (In->SRegHi); - X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI); - break; - } - } - break; - - case OP65_LDY: - if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Use, In)) { - case REG_TMP1: - Arg = MakeHexArg (In->Tmp1); - X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); - break; - - case REG_PTR1_LO: - Arg = MakeHexArg (In->Ptr1Lo); - X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); - break; - - case REG_PTR1_HI: - Arg = MakeHexArg (In->Ptr1Hi); - X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); - break; - - case REG_SREG_LO: - Arg = MakeHexArg (In->SRegLo); - X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); - break; - - case REG_SREG_HI: - Arg = MakeHexArg (In->SRegHi); - X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); - break; - } - } - break; - - case OP65_TAX: - if (E->RI->In.RegA >= 0) { - Arg = MakeHexArg (In->RegA); - X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI); - } - break; - - case OP65_TAY: - if (E->RI->In.RegA >= 0) { - Arg = MakeHexArg (In->RegA); - X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); - } - break; - - case OP65_TXA: - if (E->RI->In.RegX >= 0) { - Arg = MakeHexArg (In->RegX); - X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); - } - break; - - case OP65_TYA: - if (E->RI->In.RegY >= 0) { - Arg = MakeHexArg (In->RegY); - X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); - } - break; - - default: - /* Avoid gcc warnings */ - break; - - } - - /* Insert the replacement if we have one */ - if (X) { - CS_InsertEntry (S, X, I+1); - CS_DelEntry (S, I); - ++Changes; - } - - /* Next entry */ - ++I; - - } - - /* Return the number of changes made */ - return Changes; -} - - - -/*****************************************************************************/ -/* Optimize stack pointer ops */ -/*****************************************************************************/ - - - -static unsigned IsDecSP (const CodeEntry* E) -/* Check if this is an insn that decrements the stack pointer. If so, return -** the decrement. If not, return zero. -** The function expects E to be a subroutine call. -*/ -{ - if (strncmp (E->Arg, "decsp", 5) == 0) { - if (E->Arg[5] >= '1' && E->Arg[5] <= '8') { - return (E->Arg[5] - '0'); - } - } else if (strcmp (E->Arg, "subysp") == 0 && RegValIsKnown (E->RI->In.RegY)) { - return E->RI->In.RegY; - } - - /* If we come here, it's not a decsp op */ - return 0; -} - - - -static unsigned OptStackPtrOps (CodeSeg* S) -/* Merge adjacent calls to decsp into one. NOTE: This function won't merge all -** known cases! -*/ -{ - unsigned Changes = 0; - unsigned I; - - /* Walk over the entries */ - I = 0; - while (I < CS_GetEntryCount (S)) { - - unsigned Dec1; - unsigned Dec2; - const CodeEntry* N; - - /* Get the next entry */ - const CodeEntry* E = CS_GetEntry (S, I); - - /* Check for decspn or subysp */ - if (E->OPC == OP65_JSR && - (Dec1 = IsDecSP (E)) > 0 && - (N = CS_GetNextEntry (S, I)) != 0 && - (Dec2 = IsDecSP (N)) > 0 && - (Dec1 += Dec2) <= 255 && - !CE_HasLabel (N)) { - - CodeEntry* X; - char Buf[20]; - - /* We can combine the two */ - if (Dec1 <= 8) { - /* Insert a call to decsp */ - xsprintf (Buf, sizeof (Buf), "decsp%u", Dec1); - X = NewCodeEntry (OP65_JSR, AM65_ABS, Buf, 0, N->LI); - CS_InsertEntry (S, X, I+2); - } else { - /* Insert a call to subysp */ - const char* Arg = MakeHexArg (Dec1); - X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, N->LI); - CS_InsertEntry (S, X, I+2); - X = NewCodeEntry (OP65_JSR, AM65_ABS, "subysp", 0, N->LI); - CS_InsertEntry (S, X, I+3); - } - - /* Delete the old code */ - CS_DelEntries (S, I, 2); - - /* Regenerate register info */ - CS_GenRegInfo (S); - - /* Remember we had changes */ - ++Changes; - - } else { - - /* Next entry */ - ++I; - } - - } - - /* Return the number of changes made */ - return Changes; -} - -static unsigned OptGotoSPAdj (CodeSeg* S) -/* Optimize SP adjustment for forward 'goto' */ -{ - unsigned Changes = 0; - unsigned I; - - /* Walk over the entries */ - I = 0; - while (I < CS_GetEntryCount (S)) { - - CodeEntry* L[10], *X; - unsigned short adjustment; - const char* Arg; - - /* Get next entry */ - L[0] = CS_GetEntry (S, I); - - /* Check for the sequence generated by g_lateadjustSP */ - if (L[0]->OPC == OP65_PHA && - CS_GetEntries (S, L+1, I+1, 9) && - L[1]->OPC == OP65_LDA && - L[1]->AM == AM65_ABS && - L[2]->OPC == OP65_CLC && - L[3]->OPC == OP65_ADC && - strcmp (L[3]->Arg, "sp") == 0 && - L[6]->OPC == OP65_ADC && - strcmp (L[6]->Arg, "sp+1") == 0 && - L[9]->OPC == OP65_JMP) { - adjustment = FindSPAdjustment (L[1]->Arg); - - if (adjustment == 0) { - /* No SP adjustment needed, remove the whole sequence */ - CS_DelEntries (S, I, 9); - } - else if (adjustment >= 65536 - 8) { - /* If adjustment is in range [-8, 0) we use decsp* calls */ - char Buf[20]; - adjustment = 65536 - adjustment; - xsprintf (Buf, sizeof (Buf), "decsp%u", adjustment); - X = NewCodeEntry (OP65_JSR, AM65_ABS, Buf, 0, L[1]->LI); - CS_InsertEntry (S, X, I + 9); - - /* Delete the old code */ - CS_DelEntries (S, I, 9); - } - else if (adjustment >= 65536 - 255) { - /* For range [-255, -8) we have ldy #, jsr subysp */ - adjustment = 65536 - adjustment; - Arg = MakeHexArg (adjustment); - X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI); - CS_InsertEntry (S, X, I + 9); - X = NewCodeEntry (OP65_JSR, AM65_ABS, "subysp", 0, L[1]->LI); - CS_InsertEntry (S, X, I + 10); - - /* Delete the old code */ - CS_DelEntries (S, I, 9); - } - else if (adjustment > 255) { - /* For ranges [-32768, 255) and (255, 32767) the only modification - ** is to replace the absolute with immediate addressing - */ - Arg = MakeHexArg (adjustment & 0xff); - X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, L[1]->LI); - CS_InsertEntry (S, X, I + 1); - Arg = MakeHexArg (adjustment >> 8); - X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, L[5]->LI); - CS_InsertEntry (S, X, I + 6); - - /* Delete the old code */ - CS_DelEntry (S, I + 2); - CS_DelEntry (S, I + 6); - } - else if (adjustment > 8) { - /* For range (8, 255] we have ldy #, jsr addysp */ - Arg = MakeHexArg (adjustment & 0xff); - X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI); - CS_InsertEntry (S, X, I + 9); - X = NewCodeEntry (OP65_JSR, AM65_ABS, "addysp", 0, L[1]->LI); - CS_InsertEntry (S, X, I + 10); - - /* Delete the old code */ - CS_DelEntries (S, I, 9); - } - else { - /* If adjustment is in range (0, 8] we use incsp* calls */ - char Buf[20]; - xsprintf (Buf, sizeof (Buf), "incsp%u", adjustment); - X = NewCodeEntry (OP65_JSR, AM65_ABS, Buf, 0, L[1]->LI); - CS_InsertEntry (S, X, I + 9); - - /* Delete the old code */ - CS_DelEntries (S, I, 9); - } - /* Regenerate register info */ - CS_GenRegInfo (S); - - /* Remember we had changes */ - Changes++; - - } else { - - /* Next entry */ - ++I; - } - - } - - /* Return the number of changes made */ - return Changes; -} /*****************************************************************************/ /* struct OptFunc */ diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index 811adff04..b506a21ca 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -124,46 +124,6 @@ static int MemAccess (CodeSeg* S, unsigned From, unsigned To, const CodeEntry* N -static int GetBranchDist (CodeSeg* S, unsigned From, CodeEntry* To) -/* Get the branch distance between the two entries and return it. The distance -** will be negative for backward jumps and positive for forward jumps. -*/ -{ - /* Get the index of the branch target */ - unsigned TI = CS_GetEntryIndex (S, To); - - /* Determine the branch distance */ - int Distance = 0; - if (TI >= From) { - /* Forward branch, do not count the current insn */ - unsigned J = From+1; - while (J < TI) { - CodeEntry* N = CS_GetEntry (S, J++); - Distance += N->Size; - } - } else { - /* Backward branch */ - unsigned J = TI; - while (J < From) { - CodeEntry* N = CS_GetEntry (S, J++); - Distance -= N->Size; - } - } - - /* Return the calculated distance */ - return Distance; -} - - - -static int IsShortDist (int Distance) -/* Return true if the given distance is a short branch distance */ -{ - return (Distance >= -125 && Distance <= 125); -} - - - static short ZPRegVal (unsigned short Use, const RegContents* RC) /* Return the contents of the given zeropage register */ { @@ -184,838 +144,6 @@ static short ZPRegVal (unsigned short Use, const RegContents* RC) -static short RegVal (unsigned short Use, const RegContents* RC) -/* Return the contents of the given register */ -{ - if ((Use & REG_A) != 0) { - return RC->RegA; - } else if ((Use & REG_X) != 0) { - return RC->RegX; - } else if ((Use & REG_Y) != 0) { - return RC->RegY; - } else { - return ZPRegVal (Use, RC); - } -} - - - -/*****************************************************************************/ -/* Replace jumps to RTS by RTS */ -/*****************************************************************************/ - - - -unsigned OptRTSJumps1 (CodeSeg* S) -/* Replace jumps to RTS by RTS */ -{ - unsigned Changes = 0; - - /* Walk over all entries minus the last one */ - unsigned I = 0; - while (I < CS_GetEntryCount (S)) { - - /* Get the next entry */ - CodeEntry* E = CS_GetEntry (S, I); - - /* Check if it's an unconditional branch to a local target */ - if ((E->Info & OF_UBRA) != 0 && - E->JumpTo != 0 && - E->JumpTo->Owner->OPC == OP65_RTS) { - - /* Insert an RTS instruction */ - CodeEntry* X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, E->LI); - CS_InsertEntry (S, X, I+1); - - /* Delete the jump */ - CS_DelEntry (S, I); - - /* Remember, we had changes */ - ++Changes; - - } - - /* Next entry */ - ++I; - - } - - /* Return the number of changes made */ - return Changes; -} - - - -unsigned OptRTSJumps2 (CodeSeg* S) -/* Replace long conditional jumps to RTS or to a final target */ -{ - unsigned Changes = 0; - - /* Walk over all entries minus the last one */ - unsigned I = 0; - while (I < CS_GetEntryCount (S) - 1) { - - /* Get the next entry */ - CodeEntry* E = CS_GetEntry (S, I); - - /* Check if it's an conditional branch to a local target */ - if ((E->Info & OF_CBRA) != 0 && /* Conditional branch */ - (E->Info & OF_LBRA) != 0 && /* Long branch */ - E->JumpTo != 0) { /* Local label */ - - - /* Get the jump target and the next entry. There's always a next - ** entry, because we don't cover the last entry in the loop. - */ - CodeEntry* X = 0; - CodeEntry* T = E->JumpTo->Owner; - CodeEntry* N = CS_GetNextEntry (S, I); - - /* Check if it's a jump to an RTS insn */ - if (T->OPC == OP65_RTS) { - - /* It's a jump to RTS. Create a conditional branch around an - ** RTS insn. - */ - X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, T->LI); - - } else if (T->OPC == OP65_JMP && T->JumpTo == 0) { - - /* It's a jump to a label outside the function. Create a - ** conditional branch around a jump to the external label. - */ - X = NewCodeEntry (OP65_JMP, AM65_ABS, T->Arg, T->JumpTo, T->LI); - - } - - /* If we have a replacement insn, insert it */ - if (X) { - - CodeLabel* LN; - opc_t NewBranch; - - /* Insert the new insn */ - CS_InsertEntry (S, X, I+1); - - /* Create a conditional branch with the inverse condition - ** around the replacement insn - */ - - /* Get the new branch opcode */ - NewBranch = MakeShortBranch (GetInverseBranch (E->OPC)); - - /* Get the label attached to N, create a new one if needed */ - LN = CS_GenLabel (S, N); - - /* Generate the branch */ - X = NewCodeEntry (NewBranch, AM65_BRA, LN->Name, LN, E->LI); - CS_InsertEntry (S, X, I+1); - - /* Delete the long branch */ - CS_DelEntry (S, I); - - /* Remember, we had changes */ - ++Changes; - - } - } - - /* Next entry */ - ++I; - - } - - /* Return the number of changes made */ - return Changes; -} - - - -/*****************************************************************************/ -/* Remove dead jumps */ -/*****************************************************************************/ - - - -unsigned OptDeadJumps (CodeSeg* S) -/* Remove dead jumps (jumps to the next instruction) */ -{ - unsigned Changes = 0; - - /* Walk over all entries minus the last one */ - unsigned I = 0; - while (I < CS_GetEntryCount (S)) { - - /* Get the next entry */ - CodeEntry* E = CS_GetEntry (S, I); - - /* Check if it's a branch, if it has a local target, and if the target - ** is the next instruction. - */ - if (E->AM == AM65_BRA && - E->JumpTo && - E->JumpTo->Owner == CS_GetNextEntry (S, I)) { - - /* Delete the dead jump */ - CS_DelEntry (S, I); - - /* Remember, we had changes */ - ++Changes; - - } else { - - /* Next entry */ - ++I; - - } - } - - /* Return the number of changes made */ - return Changes; -} - - - -/*****************************************************************************/ -/* Remove dead code */ -/*****************************************************************************/ - - - -unsigned OptDeadCode (CodeSeg* S) -/* Remove dead code (code that follows an unconditional jump or an rts/rti -** and has no label) -*/ -{ - unsigned Changes = 0; - - /* Walk over all entries */ - unsigned I = 0; - while (I < CS_GetEntryCount (S)) { - - CodeEntry* N; - CodeLabel* LN; - - /* Get this entry */ - CodeEntry* E = CS_GetEntry (S, I); - - /* Check if it's an unconditional branch, and if the next entry has - ** no labels attached, or if the label is just used so that the insn - ** can jump to itself. - */ - if ((E->Info & OF_DEAD) != 0 && /* Dead code follows */ - (N = CS_GetNextEntry (S, I)) != 0 && /* Has next entry */ - (!CE_HasLabel (N) || /* Don't has a label */ - ((N->Info & OF_UBRA) != 0 && /* Uncond branch */ - (LN = N->JumpTo) != 0 && /* Jumps to known label */ - LN->Owner == N && /* Attached to insn */ - CL_GetRefCount (LN) == 1))) { /* Only reference */ - - /* Delete the next entry */ - CS_DelEntry (S, I+1); - - /* Remember, we had changes */ - ++Changes; - - } else { - - /* Next entry */ - ++I; - - } - } - - /* Return the number of changes made */ - return Changes; -} - - - -/*****************************************************************************/ -/* Optimize jump cascades */ -/*****************************************************************************/ - - - -unsigned OptJumpCascades (CodeSeg* S) -/* Optimize jump cascades (jumps to jumps). In such a case, the jump is -** replaced by a jump to the final location. This will in some cases produce -** worse code, because some jump targets are no longer reachable by short -** branches, but this is quite rare, so there are more advantages than -** disadvantages. -*/ -{ - unsigned Changes = 0; - - /* Walk over all entries */ - unsigned I = 0; - while (I < CS_GetEntryCount (S)) { - - CodeEntry* N; - CodeLabel* OldLabel; - - /* Get this entry */ - CodeEntry* E = CS_GetEntry (S, I); - - /* Check: - ** - if it's a branch, - ** - if it has a jump label, - ** - if this jump label is not attached to the instruction itself, - ** - if the target instruction is itself a branch, - ** - if either the first branch is unconditional or the target of - ** the second branch is internal to the function. - ** The latter condition will avoid conditional branches to targets - ** outside of the function (usually incspx), which won't simplify the - ** code, since conditional far branches are emulated by a short branch - ** around a jump. - */ - if ((E->Info & OF_BRA) != 0 && - (OldLabel = E->JumpTo) != 0 && - (N = OldLabel->Owner) != E && - (N->Info & OF_BRA) != 0 && - ((E->Info & OF_CBRA) == 0 || - N->JumpTo != 0)) { - - /* Check if we can use the final target label. That is the case, - ** if the target branch is an absolute branch; or, if it is a - ** conditional branch checking the same condition as the first one. - */ - if ((N->Info & OF_UBRA) != 0 || - ((E->Info & OF_CBRA) != 0 && - GetBranchCond (E->OPC) == GetBranchCond (N->OPC))) { - - /* This is a jump cascade and we may jump to the final target, - ** provided that the other insn does not jump to itself. If - ** this is the case, we can also jump to ourselves, otherwise - ** insert a jump to the new instruction and remove the old one. - */ - CodeEntry* X; - CodeLabel* LN = N->JumpTo; - - if (LN != 0 && LN->Owner == N) { - - /* We found a jump to a jump to itself. Replace our jump - ** by a jump to itself. - */ - CodeLabel* LE = CS_GenLabel (S, E); - X = NewCodeEntry (E->OPC, E->AM, LE->Name, LE, E->LI); - - } else { - - /* Jump to the final jump target */ - X = NewCodeEntry (E->OPC, E->AM, N->Arg, N->JumpTo, E->LI); - - } - - /* Insert it behind E */ - CS_InsertEntry (S, X, I+1); - - /* Remove E */ - CS_DelEntry (S, I); - - /* Remember, we had changes */ - ++Changes; - - /* Check if both are conditional branches, and the condition of - ** the second is the inverse of that of the first. In this case, - ** the second branch will never be taken, and we may jump directly - ** to the instruction behind this one. - */ - } else if ((E->Info & OF_CBRA) != 0 && (N->Info & OF_CBRA) != 0) { - - CodeEntry* X; /* Instruction behind N */ - CodeLabel* LX; /* Label attached to X */ - - /* Get the branch conditions of both branches */ - bc_t BC1 = GetBranchCond (E->OPC); - bc_t BC2 = GetBranchCond (N->OPC); - - /* Check the branch conditions */ - if (BC1 != GetInverseCond (BC2)) { - /* Condition not met */ - goto NextEntry; - } - - /* We may jump behind this conditional branch. Get the - ** pointer to the next instruction - */ - if ((X = CS_GetNextEntry (S, CS_GetEntryIndex (S, N))) == 0) { - /* N is the last entry, bail out */ - goto NextEntry; - } - - /* Get the label attached to X, create a new one if needed */ - LX = CS_GenLabel (S, X); - - /* Move the reference from E to the new label */ - CS_MoveLabelRef (S, E, LX); - - /* Remember, we had changes */ - ++Changes; - } - } - -NextEntry: - /* Next entry */ - ++I; - - } - - /* Return the number of changes made */ - return Changes; -} - - - -/*****************************************************************************/ -/* Optimize jsr/rts */ -/*****************************************************************************/ - - - -unsigned OptRTS (CodeSeg* S) -/* Optimize subroutine calls followed by an RTS. The subroutine call will get -** replaced by a jump. Don't bother to delete the RTS if it does not have a -** label, the dead code elimination should take care of it. -*/ -{ - unsigned Changes = 0; - - /* Walk over all entries minus the last one */ - unsigned I = 0; - while (I < CS_GetEntryCount (S)) { - - CodeEntry* N; - - /* Get this entry */ - CodeEntry* E = CS_GetEntry (S, I); - - /* Check if it's a subroutine call and if the following insn is RTS */ - if (E->OPC == OP65_JSR && - (N = CS_GetNextEntry (S, I)) != 0 && - N->OPC == OP65_RTS) { - - /* Change the jsr to a jmp and use the additional info for a jump */ - E->AM = AM65_BRA; - CE_ReplaceOPC (E, OP65_JMP); - - /* Remember, we had changes */ - ++Changes; - - } - - /* Next entry */ - ++I; - - } - - /* Return the number of changes made */ - return Changes; -} - - - -/*****************************************************************************/ -/* Optimize jump targets */ -/*****************************************************************************/ - - - -unsigned OptJumpTarget1 (CodeSeg* S) -/* If the instruction preceeding an unconditional branch is the same as the -** instruction preceeding the jump target, the jump target may be moved -** one entry back. This is a size optimization, since the instruction before -** the branch gets removed. -*/ -{ - unsigned Changes = 0; - CodeEntry* E1; /* Entry 1 */ - CodeEntry* E2; /* Entry 2 */ - CodeEntry* T1; /* Jump target entry 1 */ - CodeLabel* TL1; /* Target label 1 */ - - /* Walk over the entries */ - unsigned I = 0; - while (I < CS_GetEntryCount (S)) { - - /* Get next entry */ - E2 = CS_GetNextEntry (S, I); - - /* Check if we have a jump or branch without a label attached, and - ** a jump target, which is not attached to the jump itself - */ - if (E2 != 0 && - (E2->Info & OF_UBRA) != 0 && - !CE_HasLabel (E2) && - E2->JumpTo && - E2->JumpTo->Owner != E2) { - - /* Get the entry preceeding the branch target */ - T1 = CS_GetPrevEntry (S, CS_GetEntryIndex (S, E2->JumpTo->Owner)); - if (T1 == 0) { - /* There is no such entry */ - goto NextEntry; - } - - /* The entry preceeding the branch target may not be the branch - ** insn. - */ - if (T1 == E2) { - goto NextEntry; - } - - /* Get the entry preceeding the jump */ - E1 = CS_GetEntry (S, I); - - /* Check if both preceeding instructions are identical */ - if (!CodeEntriesAreEqual (E1, T1)) { - /* Not equal, try next */ - goto NextEntry; - } - - /* Get the label for the instruction preceeding the jump target. - ** This routine will create a new label if the instruction does - ** not already have one. - */ - TL1 = CS_GenLabel (S, T1); - - /* Change the jump target to point to this new label */ - CS_MoveLabelRef (S, E2, TL1); - - /* If the instruction preceeding the jump has labels attached, - ** move references to this label to the new label. - */ - if (CE_HasLabel (E1)) { - CS_MoveLabels (S, E1, T1); - } - - /* Remove the entry preceeding the jump */ - CS_DelEntry (S, I); - - /* Remember, we had changes */ - ++Changes; - - } else { -NextEntry: - /* Next entry */ - ++I; - } - } - - /* Return the number of changes made */ - return Changes; -} - - - -unsigned OptJumpTarget2 (CodeSeg* S) -/* If a bcs jumps to a sec insn or a bcc jumps to clc, skip this insn, since -** it's job is already done. -*/ -{ - unsigned Changes = 0; - - /* Walk over the entries */ - unsigned I = 0; - while (I < CS_GetEntryCount (S)) { - - /* OP that may be skipped */ - opc_t OPC; - - /* Jump target insn, old and new */ - CodeEntry* T; - CodeEntry* N; - - /* New jump label */ - CodeLabel* L; - - /* Get next entry */ - CodeEntry* E = CS_GetEntry (S, I); - - /* Check if this is a bcc insn */ - if (E->OPC == OP65_BCC || E->OPC == OP65_JCC) { - OPC = OP65_CLC; - } else if (E->OPC == OP65_BCS || E->OPC == OP65_JCS) { - OPC = OP65_SEC; - } else { - /* Not what we're looking for */ - goto NextEntry; - } - - /* Must have a jump target */ - if (E->JumpTo == 0) { - goto NextEntry; - } - - /* Get the owner insn of the jump target and check if it's the one, we - ** will skip if present. - */ - T = E->JumpTo->Owner; - if (T->OPC != OPC) { - goto NextEntry; - } - - /* Get the entry following the branch target */ - N = CS_GetNextEntry (S, CS_GetEntryIndex (S, T)); - if (N == 0) { - /* There is no such entry */ - goto NextEntry; - } - - /* Get the label for the instruction following the jump target. - ** This routine will create a new label if the instruction does - ** not already have one. - */ - L = CS_GenLabel (S, N); - - /* Change the jump target to point to this new label */ - CS_MoveLabelRef (S, E, L); - - /* Remember that we had changes */ - ++Changes; - -NextEntry: - /* Next entry */ - ++I; - } - - /* Return the number of changes made */ - return Changes; -} - - - -unsigned OptJumpTarget3 (CodeSeg* S) -/* Jumps to load instructions of a register, that do already have the matching -** register contents may skip the load instruction, since it's job is already -** done. -*/ -{ - 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 if this is a load insn with a label and the next insn is not - ** a conditional branch that needs the flags from the load. - */ - if ((E->Info & OF_LOAD) != 0 && - CE_IsConstImm (E) && - CE_HasLabel (E) && - (N = CS_GetNextEntry (S, I)) != 0 && - !CE_UseLoadFlags (N)) { - - unsigned J; - int K; - - /* New jump label */ - CodeLabel* LN = 0; - - /* Walk over all insn that jump here */ - for (J = 0; J < CE_GetLabelCount (E); ++J) { - - /* Get the label */ - CodeLabel* L = CE_GetLabel (E, J); - - /* Loop over all insn that reference this label. Since we may - ** eventually remove a reference in the loop, we must loop - ** from end down to start. - */ - for (K = CL_GetRefCount (L) - 1; K >= 0; --K) { - - /* Get the entry that jumps here */ - CodeEntry* Jump = CL_GetRef (L, K); - - /* Get the register info from this insn */ - short Val = RegVal (E->Chg, &Jump->RI->Out2); - - /* Check if the outgoing value is the one thats's loaded */ - if (Val == (unsigned char) E->Num) { - - /* OK, skip the insn. First, generate a label for the - ** next insn after E. - */ - if (LN == 0) { - LN = CS_GenLabel (S, N); - } - - /* Change the jump target to point to this new label */ - CS_MoveLabelRef (S, Jump, LN); - - /* Remember that we had changes */ - ++Changes; - } - } - } - - } - - /* Next entry */ - ++I; - } - - /* Return the number of changes made */ - return Changes; -} - - - -/*****************************************************************************/ -/* Optimize conditional branches */ -/*****************************************************************************/ - - - -unsigned OptCondBranches1 (CodeSeg* S) -/* Performs several optimization steps: -** -** - If an immediate load of a register is followed by a conditional jump that -** is never taken because the load of the register sets the flags in such a -** manner, remove the conditional branch. -** - If the conditional branch is always taken because of the register load, -** replace it by a jmp. -** - If a conditional branch jumps around an unconditional branch, remove the -** conditional branch and make the jump a conditional branch with the -** inverse condition of the first one. -*/ -{ - unsigned Changes = 0; - - /* Walk over the entries */ - unsigned I = 0; - while (I < CS_GetEntryCount (S)) { - - CodeEntry* N; - CodeLabel* L; - - /* Get next entry */ - CodeEntry* E = CS_GetEntry (S, I); - - /* Check if it's a register load */ - if ((E->Info & OF_LOAD) != 0 && /* It's a load instruction */ - E->AM == AM65_IMM && /* ..with immidiate addressing */ - (E->Flags & CEF_NUMARG) != 0 && /* ..and a numeric argument. */ - (N = CS_GetNextEntry (S, I)) != 0 && /* There is a following entry */ - (N->Info & OF_CBRA) != 0 && /* ..which is a conditional branch */ - !CE_HasLabel (N)) { /* ..and does not have a label */ - - /* Get the branch condition */ - bc_t BC = GetBranchCond (N->OPC); - - /* Check the argument against the branch condition */ - if ((BC == BC_EQ && E->Num != 0) || - (BC == BC_NE && E->Num == 0) || - (BC == BC_PL && (E->Num & 0x80) != 0) || - (BC == BC_MI && (E->Num & 0x80) == 0)) { - - /* Remove the conditional branch */ - CS_DelEntry (S, I+1); - - /* Remember, we had changes */ - ++Changes; - - } else if ((BC == BC_EQ && E->Num == 0) || - (BC == BC_NE && E->Num != 0) || - (BC == BC_PL && (E->Num & 0x80) == 0) || - (BC == BC_MI && (E->Num & 0x80) != 0)) { - - /* The branch is always taken, replace it by a jump */ - CE_ReplaceOPC (N, OP65_JMP); - - /* Remember, we had changes */ - ++Changes; - } - - } - - if ((E->Info & OF_CBRA) != 0 && /* It's a conditional branch */ - (L = E->JumpTo) != 0 && /* ..referencing a local label */ - (N = CS_GetNextEntry (S, I)) != 0 && /* There is a following entry */ - (N->Info & OF_UBRA) != 0 && /* ..which is an uncond branch, */ - !CE_HasLabel (N) && /* ..has no label attached */ - L->Owner == CS_GetNextEntry (S, I+1)) { /* ..and jump target follows */ - - /* Replace the jump by a conditional branch with the inverse branch - ** condition than the branch around it. - */ - CE_ReplaceOPC (N, GetInverseBranch (E->OPC)); - - /* Remove the conditional branch */ - CS_DelEntry (S, I); - - /* Remember, we had changes */ - ++Changes; - - } - - /* Next entry */ - ++I; - - } - - /* Return the number of changes made */ - return Changes; -} - - - -unsigned OptCondBranches2 (CodeSeg* S) -/* If on entry to a "rol a" instruction the accu is zero, and a beq/bne follows, -** we can remove the rol and branch on the state of the carry flag. -*/ -{ - 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 if it's a rol insn with A in accu and a branch follows */ - if (E->OPC == OP65_ROL && - E->AM == AM65_ACC && - E->RI->In.RegA == 0 && - !CE_HasLabel (E) && - (N = CS_GetNextEntry (S, I)) != 0 && - (N->Info & OF_ZBRA) != 0 && - !RegAUsed (S, I+1)) { - - /* Replace the branch condition */ - switch (GetBranchCond (N->OPC)) { - case BC_EQ: CE_ReplaceOPC (N, OP65_JCC); break; - case BC_NE: CE_ReplaceOPC (N, OP65_JCS); break; - default: Internal ("Unknown branch condition in OptCondBranches2"); - } - - /* Delete the rol insn */ - CS_DelEntry (S, I); - - /* Remember, we had changes */ - ++Changes; - } - - /* Next entry */ - ++I; - } - - /* Return the number of changes made */ - return Changes; -} - - - /*****************************************************************************/ /* Remove unused loads and stores */ /*****************************************************************************/ @@ -1132,6 +260,70 @@ unsigned OptUnusedStores (CodeSeg* S) +unsigned OptLoad3 (CodeSeg* S) +/* Remove repeated loads from one and the same memory location */ +{ + unsigned Changes = 0; + CodeEntry* Load = 0; + + /* Walk over the entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + /* Get next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Forget a preceeding load if we have a label */ + if (Load && CE_HasLabel (E)) { + Load = 0; + } + + /* Check if this insn is a load */ + if (E->Info & OF_LOAD) { + + CodeEntry* N; + + /* If we had a preceeding load that is identical, remove this one. + ** If it is not identical, or we didn't have one, remember it. + */ + if (Load != 0 && + E->OPC == Load->OPC && + E->AM == Load->AM && + ((E->Arg == 0 && Load->Arg == 0) || + strcmp (E->Arg, Load->Arg) == 0) && + (N = CS_GetNextEntry (S, I)) != 0 && + (N->Info & OF_CBRA) == 0) { + + /* Now remove the call to the subroutine */ + CS_DelEntry (S, I); + + /* Remember, we had changes */ + ++Changes; + + /* Next insn */ + continue; + + } else { + + Load = E; + + } + + } else if ((E->Info & OF_CMP) == 0 && (E->Info & OF_CBRA) == 0) { + /* Forget the first load on occurance of any insn we don't like */ + Load = 0; + } + + /* Next entry */ + ++I; + } + + /* Return the number of changes made */ + return Changes; +} + + + unsigned OptDupLoads (CodeSeg* S) /* Remove loads of registers where the value loaded is already in the register. */ { @@ -2138,172 +1330,3 @@ unsigned OptPrecalc (CodeSeg* S) /* Return the number of changes made */ return Changes; } - - - -/*****************************************************************************/ -/* Optimize branch types */ -/*****************************************************************************/ - - - -unsigned OptBranchDist (CodeSeg* S) -/* Change branches for the distance needed. */ -{ - unsigned Changes = 0; - - /* Walk over the entries */ - unsigned I = 0; - while (I < CS_GetEntryCount (S)) { - - /* Get next entry */ - CodeEntry* E = CS_GetEntry (S, I); - - /* Check if it's a conditional branch to a local label. */ - if (E->Info & OF_CBRA) { - - /* Is this a branch to a local symbol? */ - if (E->JumpTo != 0) { - - /* Check if the branch distance is short */ - int IsShort = IsShortDist (GetBranchDist (S, I, E->JumpTo->Owner)); - - /* Make the branch short/long according to distance */ - if ((E->Info & OF_LBRA) == 0 && !IsShort) { - /* Short branch but long distance */ - CE_ReplaceOPC (E, MakeLongBranch (E->OPC)); - ++Changes; - } else if ((E->Info & OF_LBRA) != 0 && IsShort) { - /* Long branch but short distance */ - CE_ReplaceOPC (E, MakeShortBranch (E->OPC)); - ++Changes; - } - - } else if ((E->Info & OF_LBRA) == 0) { - - /* Short branch to external symbol - make it long */ - CE_ReplaceOPC (E, MakeLongBranch (E->OPC)); - ++Changes; - - } - - } else if ((CPUIsets[CPU] & CPU_ISET_65SC02) != 0 && - (E->Info & OF_UBRA) != 0 && - E->JumpTo != 0 && - IsShortDist (GetBranchDist (S, I, E->JumpTo->Owner))) { - - /* The jump is short and may be replaced by a BRA on the 65C02 CPU */ - CE_ReplaceOPC (E, OP65_BRA); - ++Changes; - } - - /* Next entry */ - ++I; - - } - - /* Return the number of changes made */ - return Changes; -} - - - -/*****************************************************************************/ -/* Optimize indirect loads */ -/*****************************************************************************/ - - - -unsigned OptIndLoads1 (CodeSeg* S) -/* Change -** -** lda (zp),y -** -** into -** -** lda (zp,x) -** -** provided that x and y are both zero. -*/ -{ - unsigned Changes = 0; - unsigned I; - - /* Walk over the entries */ - I = 0; - while (I < CS_GetEntryCount (S)) { - - /* Get next entry */ - CodeEntry* E = CS_GetEntry (S, I); - - /* Check if it's what we're looking for */ - if (E->OPC == OP65_LDA && - E->AM == AM65_ZP_INDY && - E->RI->In.RegY == 0 && - E->RI->In.RegX == 0) { - - /* Replace by the same insn with other addressing mode */ - CodeEntry* X = NewCodeEntry (E->OPC, AM65_ZPX_IND, E->Arg, 0, E->LI); - CS_InsertEntry (S, X, I+1); - - /* Remove the old insn */ - CS_DelEntry (S, I); - ++Changes; - } - - /* Next entry */ - ++I; - - } - - /* Return the number of changes made */ - return Changes; -} - - - -unsigned OptIndLoads2 (CodeSeg* S) -/* Change -** -** lda (zp,x) -** -** into -** -** lda (zp),y -** -** provided that x and y are both zero. -*/ -{ - unsigned Changes = 0; - unsigned I; - - /* Walk over the entries */ - I = 0; - while (I < CS_GetEntryCount (S)) { - - /* Get next entry */ - CodeEntry* E = CS_GetEntry (S, I); - - /* Check if it's what we're looking for */ - if (E->OPC == OP65_LDA && - E->AM == AM65_ZPX_IND && - E->RI->In.RegY == 0 && - E->RI->In.RegX == 0) { - - /* Replace by the same insn with other addressing mode */ - CodeEntry* X = NewCodeEntry (E->OPC, AM65_ZP_INDY, E->Arg, 0, E->LI); - CS_InsertEntry (S, X, I+1); - - /* Remove the old insn */ - CS_DelEntry (S, I); - ++Changes; - } - - /* Next entry */ - ++I; - - } - - /* Return the number of changes made */ - return Changes; -} diff --git a/src/cc65/coptind.h b/src/cc65/coptind.h index 90e27d547..64acb10d8 100644 --- a/src/cc65/coptind.h +++ b/src/cc65/coptind.h @@ -49,69 +49,15 @@ -unsigned OptRTSJumps1 (CodeSeg* S); -/* Replace jumps to RTS by RTS */ - -unsigned OptRTSJumps2 (CodeSeg* S); -/* Replace long conditional jumps to RTS */ - -unsigned OptDeadJumps (CodeSeg* S); -/* Remove dead jumps (jumps to the next instruction) */ - -unsigned OptDeadCode (CodeSeg* S); -/* Remove dead code (code that follows an unconditional jump or an rts/rti -** and has no label) -*/ - -unsigned OptJumpCascades (CodeSeg* S); -/* Optimize jump cascades (jumps to jumps). In such a case, the jump is -** replaced by a jump to the final location. This will in some cases produce -** worse code, because some jump targets are no longer reachable by short -** branches, but this is quite rare, so there are more advantages than -** disadvantages. -*/ - -unsigned OptRTS (CodeSeg* S); -/* Optimize subroutine calls followed by an RTS. The subroutine call will get -** replaced by a jump. Don't bother to delete the RTS if it does not have a -** label, the dead code elimination should take care of it. -*/ - -unsigned OptJumpTarget1 (CodeSeg* S); -/* If the instruction preceeding an unconditional branch is the same as the -** instruction preceeding the jump target, the jump target may be moved -** one entry back. This is a size optimization, since the instruction before -** the branch gets removed. -*/ - -unsigned OptJumpTarget2 (CodeSeg* S); -/* If a bcs jumps to a sec insn or a bcc jumps to clc, skip this insn, since -** it's job is already done. -*/ - -unsigned OptJumpTarget3 (CodeSeg* S); -/* Jumps to load instructions of a register, that do already have the matching -** register contents may skip the load instruction, since it's job is already -** done. -*/ - -unsigned OptCondBranches1 (CodeSeg* S); -/* If an immidiate load of a register is followed by a conditional jump that -** is never taken because the load of the register sets the flags in such a -** manner, remove the conditional branch. -*/ - -unsigned OptCondBranches2 (CodeSeg* S); -/* If on entry to a "rol a" instruction the accu is zero, and a beq/bne follows, -** we can remove the rol and branch on the state of the carry. -*/ - unsigned OptUnusedLoads (CodeSeg* S); /* Remove loads of registers where the value loaded is not used later. */ unsigned OptUnusedStores (CodeSeg* S); /* Remove stores into zero page registers that aren't used later */ +unsigned OptLoad3 (CodeSeg* S); +/* Remove repeated loads from one and the same memory location */ + unsigned OptDupLoads (CodeSeg* S); /* Remove loads of registers where the value loaded is already in the register. */ @@ -144,33 +90,6 @@ unsigned OptPrecalc (CodeSeg* S); ** known by a load of the final value. */ -unsigned OptBranchDist (CodeSeg* S); -/* Change branches for the distance needed. */ - -unsigned OptIndLoads1 (CodeSeg* S); -/* Change -** -** lda (zp),y -** -** into -** -** lda (zp,x) -** -** provided that x and y are both zero. -*/ - -unsigned OptIndLoads2 (CodeSeg* S); -/* Change -** -** lda (zp,x) -** -** into -** -** lda (zp),y -** -** provided that x and y are both zero. -*/ - /* End of coptind.h */ diff --git a/src/cc65/coptjmp.c b/src/cc65/coptjmp.c new file mode 100644 index 000000000..693c7eb79 --- /dev/null +++ b/src/cc65/coptjmp.c @@ -0,0 +1,1009 @@ +/*****************************************************************************/ +/* */ +/* coptjmp.c */ +/* */ +/* Low level optimizations regarding branches and jumps */ +/* */ +/* */ +/* */ +/* (C) 2001-2009, 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. */ +/* */ +/*****************************************************************************/ + + + +/* common */ +#include "cpu.h" + +/* cc65 */ +#include "codeent.h" +#include "coptjmp.h" +#include "codeinfo.h" +#include "codeopt.h" +#include "error.h" + + + +/*****************************************************************************/ +/* Helper functions */ +/*****************************************************************************/ + + + +static int GetBranchDist (CodeSeg* S, unsigned From, CodeEntry* To) +/* Get the branch distance between the two entries and return it. The distance +** will be negative for backward jumps and positive for forward jumps. +*/ +{ + /* Get the index of the branch target */ + unsigned TI = CS_GetEntryIndex (S, To); + + /* Determine the branch distance */ + int Distance = 0; + if (TI >= From) { + /* Forward branch, do not count the current insn */ + unsigned J = From+1; + while (J < TI) { + CodeEntry* N = CS_GetEntry (S, J++); + Distance += N->Size; + } + } else { + /* Backward branch */ + unsigned J = TI; + while (J < From) { + CodeEntry* N = CS_GetEntry (S, J++); + Distance -= N->Size; + } + } + + /* Return the calculated distance */ + return Distance; +} + + + +static int IsShortDist (int Distance) +/* Return true if the given distance is a short branch distance */ +{ + return (Distance >= -125 && Distance <= 125); +} + + + +static short ZPRegVal (unsigned short Use, const RegContents* RC) +/* Return the contents of the given zeropage register */ +{ + if ((Use & REG_TMP1) != 0) { + return RC->Tmp1; + } else if ((Use & REG_PTR1_LO) != 0) { + return RC->Ptr1Lo; + } else if ((Use & REG_PTR1_HI) != 0) { + return RC->Ptr1Hi; + } else if ((Use & REG_SREG_LO) != 0) { + return RC->SRegLo; + } else if ((Use & REG_SREG_HI) != 0) { + return RC->SRegHi; + } else { + return UNKNOWN_REGVAL; + } +} + + + +static short RegVal (unsigned short Use, const RegContents* RC) +/* Return the contents of the given register */ +{ + if ((Use & REG_A) != 0) { + return RC->RegA; + } else if ((Use & REG_X) != 0) { + return RC->RegX; + } else if ((Use & REG_Y) != 0) { + return RC->RegY; + } else { + return ZPRegVal (Use, RC); + } +} + + + +/*****************************************************************************/ +/* Optimize branch types */ +/*****************************************************************************/ + + + +unsigned OptBranchDist (CodeSeg* S) +/* Change branches for the distance needed. */ +{ + unsigned Changes = 0; + + /* Walk over the entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + /* Get next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Check if it's a conditional branch to a local label. */ + if (E->Info & OF_CBRA) { + + /* Is this a branch to a local symbol? */ + if (E->JumpTo != 0) { + + /* Check if the branch distance is short */ + int IsShort = IsShortDist (GetBranchDist (S, I, E->JumpTo->Owner)); + + /* Make the branch short/long according to distance */ + if ((E->Info & OF_LBRA) == 0 && !IsShort) { + /* Short branch but long distance */ + CE_ReplaceOPC (E, MakeLongBranch (E->OPC)); + ++Changes; + } else if ((E->Info & OF_LBRA) != 0 && IsShort) { + /* Long branch but short distance */ + CE_ReplaceOPC (E, MakeShortBranch (E->OPC)); + ++Changes; + } + + } else if ((E->Info & OF_LBRA) == 0) { + + /* Short branch to external symbol - make it long */ + CE_ReplaceOPC (E, MakeLongBranch (E->OPC)); + ++Changes; + + } + + } else if ((CPUIsets[CPU] & CPU_ISET_65SC02) != 0 && + (E->Info & OF_UBRA) != 0 && + E->JumpTo != 0 && + IsShortDist (GetBranchDist (S, I, E->JumpTo->Owner))) { + + /* The jump is short and may be replaced by a BRA on the 65C02 CPU */ + CE_ReplaceOPC (E, OP65_BRA); + ++Changes; + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + + +/*****************************************************************************/ +/* Replace jumps to RTS by RTS */ +/*****************************************************************************/ + + + +unsigned OptRTSJumps1 (CodeSeg* S) +/* Replace jumps to RTS by RTS */ +{ + unsigned Changes = 0; + + /* Walk over all entries minus the last one */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + /* Get the next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Check if it's an unconditional branch to a local target */ + if ((E->Info & OF_UBRA) != 0 && + E->JumpTo != 0 && + E->JumpTo->Owner->OPC == OP65_RTS) { + + /* Insert an RTS instruction */ + CodeEntry* X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, I+1); + + /* Delete the jump */ + CS_DelEntry (S, I); + + /* Remember, we had changes */ + ++Changes; + + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + + +unsigned OptRTSJumps2 (CodeSeg* S) +/* Replace long conditional jumps to RTS or to a final target */ +{ + unsigned Changes = 0; + + /* Walk over all entries minus the last one */ + unsigned I = 0; + while (I < CS_GetEntryCount (S) - 1) { + + /* Get the next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Check if it's an conditional branch to a local target */ + if ((E->Info & OF_CBRA) != 0 && /* Conditional branch */ + (E->Info & OF_LBRA) != 0 && /* Long branch */ + E->JumpTo != 0) { /* Local label */ + + + /* Get the jump target and the next entry. There's always a next + ** entry, because we don't cover the last entry in the loop. + */ + CodeEntry* X = 0; + CodeEntry* T = E->JumpTo->Owner; + CodeEntry* N = CS_GetNextEntry (S, I); + + /* Check if it's a jump to an RTS insn */ + if (T->OPC == OP65_RTS) { + + /* It's a jump to RTS. Create a conditional branch around an + ** RTS insn. + */ + X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, T->LI); + + } else if (T->OPC == OP65_JMP && T->JumpTo == 0) { + + /* It's a jump to a label outside the function. Create a + ** conditional branch around a jump to the external label. + */ + X = NewCodeEntry (OP65_JMP, AM65_ABS, T->Arg, T->JumpTo, T->LI); + + } + + /* If we have a replacement insn, insert it */ + if (X) { + + CodeLabel* LN; + opc_t NewBranch; + + /* Insert the new insn */ + CS_InsertEntry (S, X, I+1); + + /* Create a conditional branch with the inverse condition + ** around the replacement insn + */ + + /* Get the new branch opcode */ + NewBranch = MakeShortBranch (GetInverseBranch (E->OPC)); + + /* Get the label attached to N, create a new one if needed */ + LN = CS_GenLabel (S, N); + + /* Generate the branch */ + X = NewCodeEntry (NewBranch, AM65_BRA, LN->Name, LN, E->LI); + CS_InsertEntry (S, X, I+1); + + /* Delete the long branch */ + CS_DelEntry (S, I); + + /* Remember, we had changes */ + ++Changes; + + } + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + + +/*****************************************************************************/ +/* Remove dead jumps */ +/*****************************************************************************/ + + + +unsigned OptDeadJumps (CodeSeg* S) +/* Remove dead jumps (jumps to the next instruction) */ +{ + unsigned Changes = 0; + + /* Walk over all entries minus the last one */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + /* Get the next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Check if it's a branch, if it has a local target, and if the target + ** is the next instruction. + */ + if (E->AM == AM65_BRA && + E->JumpTo && + E->JumpTo->Owner == CS_GetNextEntry (S, I)) { + + /* Delete the dead jump */ + CS_DelEntry (S, I); + + /* Remember, we had changes */ + ++Changes; + + } else { + + /* Next entry */ + ++I; + + } + } + + /* Return the number of changes made */ + return Changes; +} + + + +/*****************************************************************************/ +/* Remove dead code */ +/*****************************************************************************/ + + + +unsigned OptDeadCode (CodeSeg* S) +/* Remove dead code (code that follows an unconditional jump or an rts/rti +** and has no label) +*/ +{ + unsigned Changes = 0; + + /* Walk over all entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* N; + CodeLabel* LN; + + /* Get this entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Check if it's an unconditional branch, and if the next entry has + ** no labels attached, or if the label is just used so that the insn + ** can jump to itself. + */ + if ((E->Info & OF_DEAD) != 0 && /* Dead code follows */ + (N = CS_GetNextEntry (S, I)) != 0 && /* Has next entry */ + (!CE_HasLabel (N) || /* Don't has a label */ + ((N->Info & OF_UBRA) != 0 && /* Uncond branch */ + (LN = N->JumpTo) != 0 && /* Jumps to known label */ + LN->Owner == N && /* Attached to insn */ + CL_GetRefCount (LN) == 1))) { /* Only reference */ + + /* Delete the next entry */ + CS_DelEntry (S, I+1); + + /* Remember, we had changes */ + ++Changes; + + } else { + + /* Next entry */ + ++I; + + } + } + + /* Return the number of changes made */ + return Changes; +} + + + +/*****************************************************************************/ +/* Optimize jump cascades */ +/*****************************************************************************/ + + + +unsigned OptJumpCascades (CodeSeg* S) +/* Optimize jump cascades (jumps to jumps). In such a case, the jump is +** replaced by a jump to the final location. This will in some cases produce +** worse code, because some jump targets are no longer reachable by short +** branches, but this is quite rare, so there are more advantages than +** disadvantages. +*/ +{ + unsigned Changes = 0; + + /* Walk over all entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* N; + CodeLabel* OldLabel; + + /* Get this entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Check: + ** - if it's a branch, + ** - if it has a jump label, + ** - if this jump label is not attached to the instruction itself, + ** - if the target instruction is itself a branch, + ** - if either the first branch is unconditional or the target of + ** the second branch is internal to the function. + ** The latter condition will avoid conditional branches to targets + ** outside of the function (usually incspx), which won't simplify the + ** code, since conditional far branches are emulated by a short branch + ** around a jump. + */ + if ((E->Info & OF_BRA) != 0 && + (OldLabel = E->JumpTo) != 0 && + (N = OldLabel->Owner) != E && + (N->Info & OF_BRA) != 0 && + ((E->Info & OF_CBRA) == 0 || + N->JumpTo != 0)) { + + /* Check if we can use the final target label. That is the case, + ** if the target branch is an absolute branch; or, if it is a + ** conditional branch checking the same condition as the first one. + */ + if ((N->Info & OF_UBRA) != 0 || + ((E->Info & OF_CBRA) != 0 && + GetBranchCond (E->OPC) == GetBranchCond (N->OPC))) { + + /* This is a jump cascade and we may jump to the final target, + ** provided that the other insn does not jump to itself. If + ** this is the case, we can also jump to ourselves, otherwise + ** insert a jump to the new instruction and remove the old one. + */ + CodeEntry* X; + CodeLabel* LN = N->JumpTo; + + if (LN != 0 && LN->Owner == N) { + + /* We found a jump to a jump to itself. Replace our jump + ** by a jump to itself. + */ + CodeLabel* LE = CS_GenLabel (S, E); + X = NewCodeEntry (E->OPC, E->AM, LE->Name, LE, E->LI); + + } else { + + /* Jump to the final jump target */ + X = NewCodeEntry (E->OPC, E->AM, N->Arg, N->JumpTo, E->LI); + + } + + /* Insert it behind E */ + CS_InsertEntry (S, X, I+1); + + /* Remove E */ + CS_DelEntry (S, I); + + /* Remember, we had changes */ + ++Changes; + + /* Check if both are conditional branches, and the condition of + ** the second is the inverse of that of the first. In this case, + ** the second branch will never be taken, and we may jump directly + ** to the instruction behind this one. + */ + } else if ((E->Info & OF_CBRA) != 0 && (N->Info & OF_CBRA) != 0) { + + CodeEntry* X; /* Instruction behind N */ + CodeLabel* LX; /* Label attached to X */ + + /* Get the branch conditions of both branches */ + bc_t BC1 = GetBranchCond (E->OPC); + bc_t BC2 = GetBranchCond (N->OPC); + + /* Check the branch conditions */ + if (BC1 != GetInverseCond (BC2)) { + /* Condition not met */ + goto NextEntry; + } + + /* We may jump behind this conditional branch. Get the + ** pointer to the next instruction + */ + if ((X = CS_GetNextEntry (S, CS_GetEntryIndex (S, N))) == 0) { + /* N is the last entry, bail out */ + goto NextEntry; + } + + /* Get the label attached to X, create a new one if needed */ + LX = CS_GenLabel (S, X); + + /* Move the reference from E to the new label */ + CS_MoveLabelRef (S, E, LX); + + /* Remember, we had changes */ + ++Changes; + } + } + +NextEntry: + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + + +/*****************************************************************************/ +/* Optimize jsr/rts */ +/*****************************************************************************/ + + + +unsigned OptRTS (CodeSeg* S) +/* Optimize subroutine calls followed by an RTS. The subroutine call will get +** replaced by a jump. Don't bother to delete the RTS if it does not have a +** label, the dead code elimination should take care of it. +*/ +{ + unsigned Changes = 0; + + /* Walk over all entries minus the last one */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* N; + + /* Get this entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Check if it's a subroutine call and if the following insn is RTS */ + if (E->OPC == OP65_JSR && + (N = CS_GetNextEntry (S, I)) != 0 && + N->OPC == OP65_RTS) { + + /* Change the jsr to a jmp and use the additional info for a jump */ + E->AM = AM65_BRA; + CE_ReplaceOPC (E, OP65_JMP); + + /* Remember, we had changes */ + ++Changes; + + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + + +/*****************************************************************************/ +/* Optimize jump targets */ +/*****************************************************************************/ + + + +unsigned OptJumpTarget1 (CodeSeg* S) +/* If the instruction preceeding an unconditional branch is the same as the +** instruction preceeding the jump target, the jump target may be moved +** one entry back. This is a size optimization, since the instruction before +** the branch gets removed. +*/ +{ + unsigned Changes = 0; + CodeEntry* E1; /* Entry 1 */ + CodeEntry* E2; /* Entry 2 */ + CodeEntry* T1; /* Jump target entry 1 */ + CodeLabel* TL1; /* Target label 1 */ + + /* Walk over the entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + /* Get next entry */ + E2 = CS_GetNextEntry (S, I); + + /* Check if we have a jump or branch without a label attached, and + ** a jump target, which is not attached to the jump itself + */ + if (E2 != 0 && + (E2->Info & OF_UBRA) != 0 && + !CE_HasLabel (E2) && + E2->JumpTo && + E2->JumpTo->Owner != E2) { + + /* Get the entry preceeding the branch target */ + T1 = CS_GetPrevEntry (S, CS_GetEntryIndex (S, E2->JumpTo->Owner)); + if (T1 == 0) { + /* There is no such entry */ + goto NextEntry; + } + + /* The entry preceeding the branch target may not be the branch + ** insn. + */ + if (T1 == E2) { + goto NextEntry; + } + + /* Get the entry preceeding the jump */ + E1 = CS_GetEntry (S, I); + + /* Check if both preceeding instructions are identical */ + if (!CodeEntriesAreEqual (E1, T1)) { + /* Not equal, try next */ + goto NextEntry; + } + + /* Get the label for the instruction preceeding the jump target. + ** This routine will create a new label if the instruction does + ** not already have one. + */ + TL1 = CS_GenLabel (S, T1); + + /* Change the jump target to point to this new label */ + CS_MoveLabelRef (S, E2, TL1); + + /* If the instruction preceeding the jump has labels attached, + ** move references to this label to the new label. + */ + if (CE_HasLabel (E1)) { + CS_MoveLabels (S, E1, T1); + } + + /* Remove the entry preceeding the jump */ + CS_DelEntry (S, I); + + /* Remember, we had changes */ + ++Changes; + + } else { +NextEntry: + /* Next entry */ + ++I; + } + } + + /* Return the number of changes made */ + return Changes; +} + + + +unsigned OptJumpTarget2 (CodeSeg* S) +/* If a bcs jumps to a sec insn or a bcc jumps to clc, skip this insn, since +** it's job is already done. +*/ +{ + unsigned Changes = 0; + + /* Walk over the entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + /* OP that may be skipped */ + opc_t OPC; + + /* Jump target insn, old and new */ + CodeEntry* T; + CodeEntry* N; + + /* New jump label */ + CodeLabel* L; + + /* Get next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Check if this is a bcc insn */ + if (E->OPC == OP65_BCC || E->OPC == OP65_JCC) { + OPC = OP65_CLC; + } else if (E->OPC == OP65_BCS || E->OPC == OP65_JCS) { + OPC = OP65_SEC; + } else { + /* Not what we're looking for */ + goto NextEntry; + } + + /* Must have a jump target */ + if (E->JumpTo == 0) { + goto NextEntry; + } + + /* Get the owner insn of the jump target and check if it's the one, we + ** will skip if present. + */ + T = E->JumpTo->Owner; + if (T->OPC != OPC) { + goto NextEntry; + } + + /* Get the entry following the branch target */ + N = CS_GetNextEntry (S, CS_GetEntryIndex (S, T)); + if (N == 0) { + /* There is no such entry */ + goto NextEntry; + } + + /* Get the label for the instruction following the jump target. + ** This routine will create a new label if the instruction does + ** not already have one. + */ + L = CS_GenLabel (S, N); + + /* Change the jump target to point to this new label */ + CS_MoveLabelRef (S, E, L); + + /* Remember that we had changes */ + ++Changes; + +NextEntry: + /* Next entry */ + ++I; + } + + /* Return the number of changes made */ + return Changes; +} + + + +unsigned OptJumpTarget3 (CodeSeg* S) +/* Jumps to load instructions of a register, that do already have the matching +** register contents may skip the load instruction, since it's job is already +** done. +*/ +{ + 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 if this is a load insn with a label and the next insn is not + ** a conditional branch that needs the flags from the load. + */ + if ((E->Info & OF_LOAD) != 0 && + CE_IsConstImm (E) && + CE_HasLabel (E) && + (N = CS_GetNextEntry (S, I)) != 0 && + !CE_UseLoadFlags (N)) { + + unsigned J; + int K; + + /* New jump label */ + CodeLabel* LN = 0; + + /* Walk over all insn that jump here */ + for (J = 0; J < CE_GetLabelCount (E); ++J) { + + /* Get the label */ + CodeLabel* L = CE_GetLabel (E, J); + + /* Loop over all insn that reference this label. Since we may + ** eventually remove a reference in the loop, we must loop + ** from end down to start. + */ + for (K = CL_GetRefCount (L) - 1; K >= 0; --K) { + + /* Get the entry that jumps here */ + CodeEntry* Jump = CL_GetRef (L, K); + + /* Get the register info from this insn */ + short Val = RegVal (E->Chg, &Jump->RI->Out2); + + /* Check if the outgoing value is the one thats's loaded */ + if (Val == (unsigned char) E->Num) { + + /* OK, skip the insn. First, generate a label for the + ** next insn after E. + */ + if (LN == 0) { + LN = CS_GenLabel (S, N); + } + + /* Change the jump target to point to this new label */ + CS_MoveLabelRef (S, Jump, LN); + + /* Remember that we had changes */ + ++Changes; + } + } + } + + } + + /* Next entry */ + ++I; + } + + /* Return the number of changes made */ + return Changes; +} + + + +/*****************************************************************************/ +/* Optimize conditional branches */ +/*****************************************************************************/ + + + +unsigned OptCondBranches1 (CodeSeg* S) +/* Performs several optimization steps: +** +** - If an immediate load of a register is followed by a conditional jump that +** is never taken because the load of the register sets the flags in such a +** manner, remove the conditional branch. +** - If the conditional branch is always taken because of the register load, +** replace it by a jmp. +** - If a conditional branch jumps around an unconditional branch, remove the +** conditional branch and make the jump a conditional branch with the +** inverse condition of the first one. +*/ +{ + unsigned Changes = 0; + + /* Walk over the entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* N; + CodeLabel* L; + + /* Get next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Check if it's a register load */ + if ((E->Info & OF_LOAD) != 0 && /* It's a load instruction */ + E->AM == AM65_IMM && /* ..with immidiate addressing */ + CE_HasNumArg (E) && /* ..and a numeric argument. */ + (N = CS_GetNextEntry (S, I)) != 0 && /* There is a following entry */ + (N->Info & OF_CBRA) != 0 && /* ..which is a conditional branch */ + !CE_HasLabel (N)) { /* ..and does not have a label */ + + /* Get the branch condition */ + bc_t BC = GetBranchCond (N->OPC); + + /* Check the argument against the branch condition */ + if ((BC == BC_EQ && E->Num != 0) || + (BC == BC_NE && E->Num == 0) || + (BC == BC_PL && (E->Num & 0x80) != 0) || + (BC == BC_MI && (E->Num & 0x80) == 0)) { + + /* Remove the conditional branch */ + CS_DelEntry (S, I+1); + + /* Remember, we had changes */ + ++Changes; + + } else if ((BC == BC_EQ && E->Num == 0) || + (BC == BC_NE && E->Num != 0) || + (BC == BC_PL && (E->Num & 0x80) == 0) || + (BC == BC_MI && (E->Num & 0x80) != 0)) { + + /* The branch is always taken, replace it by a jump */ + CE_ReplaceOPC (N, OP65_JMP); + + /* Remember, we had changes */ + ++Changes; + } + + } + + if ((E->Info & OF_CBRA) != 0 && /* It's a conditional branch */ + (L = E->JumpTo) != 0 && /* ..referencing a local label */ + (N = CS_GetNextEntry (S, I)) != 0 && /* There is a following entry */ + (N->Info & OF_UBRA) != 0 && /* ..which is an uncond branch, */ + !CE_HasLabel (N) && /* ..has no label attached */ + L->Owner == CS_GetNextEntry (S, I+1)) { /* ..and jump target follows */ + + /* Replace the jump by a conditional branch with the inverse branch + ** condition than the branch around it. + */ + CE_ReplaceOPC (N, GetInverseBranch (E->OPC)); + + /* Remove the conditional branch */ + CS_DelEntry (S, I); + + /* Remember, we had changes */ + ++Changes; + + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + + +unsigned OptCondBranches2 (CodeSeg* S) +/* If on entry to a "rol a" instruction the accu is zero, and a beq/bne follows, +** we can remove the rol and branch on the state of the carry flag. +*/ +{ + 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 if it's a rol insn with A in accu and a branch follows */ + if (E->OPC == OP65_ROL && + E->AM == AM65_ACC && + E->RI->In.RegA == 0 && + !CE_HasLabel (E) && + (N = CS_GetNextEntry (S, I)) != 0 && + (N->Info & OF_ZBRA) != 0 && + !RegAUsed (S, I+1)) { + + /* Replace the branch condition */ + switch (GetBranchCond (N->OPC)) { + case BC_EQ: CE_ReplaceOPC (N, OP65_JCC); break; + case BC_NE: CE_ReplaceOPC (N, OP65_JCS); break; + default: Internal ("Unknown branch condition in OptCondBranches2"); + } + + /* Delete the rol insn */ + CS_DelEntry (S, I); + + /* Remember, we had changes */ + ++Changes; + } + + /* Next entry */ + ++I; + } + + /* Return the number of changes made */ + return Changes; +} diff --git a/src/cc65/coptjmp.h b/src/cc65/coptjmp.h new file mode 100644 index 000000000..4cb7a2792 --- /dev/null +++ b/src/cc65/coptjmp.h @@ -0,0 +1,116 @@ +/*****************************************************************************/ +/* */ +/* coptjmp.h */ +/* */ +/* Low level optimizations regarding branches and jumps */ +/* */ +/* */ +/* */ +/* (C) 2001-2009, 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 COPTJMP_H +#define COPTJMP_H + + + +/* cc65 */ +#include "codeseg.h" + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +unsigned OptBranchDist (CodeSeg* S); +/* Change branches for the distance needed. */ + +unsigned OptRTSJumps1 (CodeSeg* S); +/* Replace jumps to RTS by RTS */ + +unsigned OptRTSJumps2 (CodeSeg* S); +/* Replace long conditional jumps to RTS */ + +unsigned OptDeadJumps (CodeSeg* S); +/* Remove dead jumps (jumps to the next instruction) */ + +unsigned OptDeadCode (CodeSeg* S); +/* Remove dead code (code that follows an unconditional jump or an rts/rti +** and has no label) +*/ + +unsigned OptJumpCascades (CodeSeg* S); +/* Optimize jump cascades (jumps to jumps). In such a case, the jump is +** replaced by a jump to the final location. This will in some cases produce +** worse code, because some jump targets are no longer reachable by short +** branches, but this is quite rare, so there are more advantages than +** disadvantages. +*/ + +unsigned OptRTS (CodeSeg* S); +/* Optimize subroutine calls followed by an RTS. The subroutine call will get +** replaced by a jump. Don't bother to delete the RTS if it does not have a +** label, the dead code elimination should take care of it. +*/ + +unsigned OptJumpTarget1 (CodeSeg* S); +/* If the instruction preceeding an unconditional branch is the same as the +** instruction preceeding the jump target, the jump target may be moved +** one entry back. This is a size optimization, since the instruction before +** the branch gets removed. +*/ + +unsigned OptJumpTarget2 (CodeSeg* S); +/* If a bcs jumps to a sec insn or a bcc jumps to clc, skip this insn, since +** it's job is already done. +*/ + +unsigned OptJumpTarget3 (CodeSeg* S); +/* Jumps to load instructions of a register, that do already have the matching +** register contents may skip the load instruction, since it's job is already +** done. +*/ + +unsigned OptCondBranches1 (CodeSeg* S); +/* If an immidiate load of a register is followed by a conditional jump that +** is never taken because the load of the register sets the flags in such a +** manner, remove the conditional branch. +*/ + +unsigned OptCondBranches2 (CodeSeg* S); +/* If on entry to a "rol a" instruction the accu is zero, and a beq/bne follows, +** we can remove the rol and branch on the state of the carry. +*/ + + + +/* End of coptjmp.h */ + +#endif diff --git a/src/cc65/coptmisc.c b/src/cc65/coptmisc.c new file mode 100644 index 000000000..523fbf17c --- /dev/null +++ b/src/cc65/coptmisc.c @@ -0,0 +1,735 @@ +/*****************************************************************************/ +/* */ +/* codemisc.c */ +/* */ +/* Miscellaneous optimization operations */ +/* */ +/* */ +/* */ +/* (C) 2001-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. */ +/* */ +/*****************************************************************************/ + + + +#include <stdlib.h> + +/* common */ +#include "chartype.h" +#include "xsprintf.h" + +/* cc65 */ +#include "codeent.h" +#include "codeinfo.h" +#include "coptmisc.h" +#include "error.h" +#include "symtab.h" + + + +/*****************************************************************************/ +/* Decouple operations */ +/*****************************************************************************/ + + + +unsigned OptDecouple (CodeSeg* S) +/* Decouple operations, that is, do the following replacements: +** +** dex -> ldx #imm +** inx -> ldx #imm +** dey -> ldy #imm +** iny -> ldy #imm +** tax -> ldx #imm +** txa -> lda #imm +** tay -> ldy #imm +** tya -> lda #imm +** lda zp -> lda #imm +** ldx zp -> ldx #imm +** ldy zp -> ldy #imm +** +** Provided that the register values are known of course. +*/ +{ + unsigned Changes = 0; + unsigned I; + + /* Walk over the entries */ + I = 0; + while (I < CS_GetEntryCount (S)) { + + const char* Arg; + + /* Get next entry and it's input register values */ + CodeEntry* E = CS_GetEntry (S, I); + const RegContents* In = &E->RI->In; + + /* Assume we have no replacement */ + CodeEntry* X = 0; + + /* Check the instruction */ + switch (E->OPC) { + + case OP65_DEA: + if (RegValIsKnown (In->RegA)) { + Arg = MakeHexArg ((In->RegA - 1) & 0xFF); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); + } + break; + + case OP65_DEX: + if (RegValIsKnown (In->RegX)) { + Arg = MakeHexArg ((In->RegX - 1) & 0xFF); + X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI); + } + break; + + case OP65_DEY: + if (RegValIsKnown (In->RegY)) { + Arg = MakeHexArg ((In->RegY - 1) & 0xFF); + X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + } + break; + + case OP65_INA: + if (RegValIsKnown (In->RegA)) { + Arg = MakeHexArg ((In->RegA + 1) & 0xFF); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); + } + break; + + case OP65_INX: + if (RegValIsKnown (In->RegX)) { + Arg = MakeHexArg ((In->RegX + 1) & 0xFF); + X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI); + } + break; + + case OP65_INY: + if (RegValIsKnown (In->RegY)) { + Arg = MakeHexArg ((In->RegY + 1) & 0xFF); + X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + } + break; + + case OP65_LDA: + if (E->AM == AM65_ZP) { + switch (GetKnownReg (E->Use & REG_ZP, In)) { + case REG_TMP1: + Arg = MakeHexArg (In->Tmp1); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); + break; + + case REG_PTR1_LO: + Arg = MakeHexArg (In->Ptr1Lo); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); + break; + + case REG_PTR1_HI: + Arg = MakeHexArg (In->Ptr1Hi); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); + break; + + case REG_SREG_LO: + Arg = MakeHexArg (In->SRegLo); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); + break; + + case REG_SREG_HI: + Arg = MakeHexArg (In->SRegHi); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); + break; + } + } + break; + + case OP65_LDX: + if (E->AM == AM65_ZP) { + switch (GetKnownReg (E->Use & REG_ZP, In)) { + case REG_TMP1: + Arg = MakeHexArg (In->Tmp1); + X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI); + break; + + case REG_PTR1_LO: + Arg = MakeHexArg (In->Ptr1Lo); + X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI); + break; + + case REG_PTR1_HI: + Arg = MakeHexArg (In->Ptr1Hi); + X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI); + break; + + case REG_SREG_LO: + Arg = MakeHexArg (In->SRegLo); + X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI); + break; + + case REG_SREG_HI: + Arg = MakeHexArg (In->SRegHi); + X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI); + break; + } + } + break; + + case OP65_LDY: + if (E->AM == AM65_ZP) { + switch (GetKnownReg (E->Use, In)) { + case REG_TMP1: + Arg = MakeHexArg (In->Tmp1); + X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + break; + + case REG_PTR1_LO: + Arg = MakeHexArg (In->Ptr1Lo); + X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + break; + + case REG_PTR1_HI: + Arg = MakeHexArg (In->Ptr1Hi); + X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + break; + + case REG_SREG_LO: + Arg = MakeHexArg (In->SRegLo); + X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + break; + + case REG_SREG_HI: + Arg = MakeHexArg (In->SRegHi); + X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + break; + } + } + break; + + case OP65_TAX: + if (E->RI->In.RegA >= 0) { + Arg = MakeHexArg (In->RegA); + X = NewCodeEntry (OP65_LDX, AM65_IMM, Arg, 0, E->LI); + } + break; + + case OP65_TAY: + if (E->RI->In.RegA >= 0) { + Arg = MakeHexArg (In->RegA); + X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + } + break; + + case OP65_TXA: + if (E->RI->In.RegX >= 0) { + Arg = MakeHexArg (In->RegX); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); + } + break; + + case OP65_TYA: + if (E->RI->In.RegY >= 0) { + Arg = MakeHexArg (In->RegY); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); + } + break; + + default: + /* Avoid gcc warnings */ + break; + + } + + /* Insert the replacement if we have one */ + if (X) { + CS_InsertEntry (S, X, I+1); + CS_DelEntry (S, I); + ++Changes; + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + + +unsigned OptIndLoads1 (CodeSeg* S) +/* Change +** +** lda (zp),y +** +** into +** +** lda (zp,x) +** +** provided that x and y are both zero. +*/ +{ + unsigned Changes = 0; + unsigned I; + + /* Walk over the entries */ + I = 0; + while (I < CS_GetEntryCount (S)) { + + /* Get next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Check if it's what we're looking for */ + if (E->OPC == OP65_LDA && + E->AM == AM65_ZP_INDY && + E->RI->In.RegY == 0 && + E->RI->In.RegX == 0) { + + /* Replace by the same insn with other addressing mode */ + CodeEntry* X = NewCodeEntry (E->OPC, AM65_ZPX_IND, E->Arg, 0, E->LI); + CS_InsertEntry (S, X, I+1); + + /* Remove the old insn */ + CS_DelEntry (S, I); + ++Changes; + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + + +unsigned OptIndLoads2 (CodeSeg* S) +/* Change +** +** lda (zp,x) +** +** into +** +** lda (zp),y +** +** provided that x and y are both zero. +*/ +{ + unsigned Changes = 0; + unsigned I; + + /* Walk over the entries */ + I = 0; + while (I < CS_GetEntryCount (S)) { + + /* Get next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Check if it's what we're looking for */ + if (E->OPC == OP65_LDA && + E->AM == AM65_ZPX_IND && + E->RI->In.RegY == 0 && + E->RI->In.RegX == 0) { + + /* Replace by the same insn with other addressing mode */ + CodeEntry* X = NewCodeEntry (E->OPC, AM65_ZP_INDY, E->Arg, 0, E->LI); + CS_InsertEntry (S, X, I+1); + + /* Remove the old insn */ + CS_DelEntry (S, I); + ++Changes; + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + + +/*****************************************************************************/ +/* Optimize stack pointer ops */ +/*****************************************************************************/ + + + +static unsigned IsDecSP (const CodeEntry* E) +/* Check if this is an insn that decrements the stack pointer. If so, return +** the decrement. If not, return zero. +** The function expects E to be a subroutine call. +*/ +{ + if (strncmp (E->Arg, "decsp", 5) == 0) { + if (E->Arg[5] >= '1' && E->Arg[5] <= '8') { + return (E->Arg[5] - '0'); + } + } else if (strcmp (E->Arg, "subysp") == 0 && RegValIsKnown (E->RI->In.RegY)) { + return E->RI->In.RegY; + } + + /* If we come here, it's not a decsp op */ + return 0; +} + + + +unsigned OptStackPtrOps (CodeSeg* S) +/* Merge adjacent calls to decsp into one. NOTE: This function won't merge all +** known cases! +*/ +{ + unsigned Changes = 0; + unsigned I; + + /* Walk over the entries */ + I = 0; + while (I < CS_GetEntryCount (S)) { + + unsigned Dec1; + unsigned Dec2; + const CodeEntry* N; + + /* Get the next entry */ + const CodeEntry* E = CS_GetEntry (S, I); + + /* Check for decspn or subysp */ + if (E->OPC == OP65_JSR && + (Dec1 = IsDecSP (E)) > 0 && + (N = CS_GetNextEntry (S, I)) != 0 && + (Dec2 = IsDecSP (N)) > 0 && + (Dec1 += Dec2) <= 255 && + !CE_HasLabel (N)) { + + CodeEntry* X; + char Buf[20]; + + /* We can combine the two */ + if (Dec1 <= 8) { + /* Insert a call to decsp */ + xsprintf (Buf, sizeof (Buf), "decsp%u", Dec1); + X = NewCodeEntry (OP65_JSR, AM65_ABS, Buf, 0, N->LI); + CS_InsertEntry (S, X, I+2); + } else { + /* Insert a call to subysp */ + const char* Arg = MakeHexArg (Dec1); + X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, N->LI); + CS_InsertEntry (S, X, I+2); + X = NewCodeEntry (OP65_JSR, AM65_ABS, "subysp", 0, N->LI); + CS_InsertEntry (S, X, I+3); + } + + /* Delete the old code */ + CS_DelEntries (S, I, 2); + + /* Regenerate register info */ + CS_GenRegInfo (S); + + /* Remember we had changes */ + ++Changes; + + } else { + + /* Next entry */ + ++I; + } + + } + + /* Return the number of changes made */ + return Changes; +} + + + +unsigned OptGotoSPAdj (CodeSeg* S) +/* Optimize SP adjustment for forward 'goto' */ +{ + unsigned Changes = 0; + unsigned I; + + /* Walk over the entries */ + I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* L[10], *X; + unsigned short adjustment; + const char* Arg; + + /* Get next entry */ + L[0] = CS_GetEntry (S, I); + + /* Check for the sequence generated by g_lateadjustSP */ + if (L[0]->OPC == OP65_PHA && + CS_GetEntries (S, L+1, I+1, 9) && + L[1]->OPC == OP65_LDA && + L[1]->AM == AM65_ABS && + L[2]->OPC == OP65_CLC && + L[3]->OPC == OP65_ADC && + strcmp (L[3]->Arg, "sp") == 0 && + L[6]->OPC == OP65_ADC && + strcmp (L[6]->Arg, "sp+1") == 0 && + L[9]->OPC == OP65_JMP) { + adjustment = FindSPAdjustment (L[1]->Arg); + + if (adjustment == 0) { + /* No SP adjustment needed, remove the whole sequence */ + CS_DelEntries (S, I, 9); + } + else if (adjustment >= 65536 - 8) { + /* If adjustment is in range [-8, 0) we use decsp* calls */ + char Buf[20]; + adjustment = 65536 - adjustment; + xsprintf (Buf, sizeof (Buf), "decsp%u", adjustment); + X = NewCodeEntry (OP65_JSR, AM65_ABS, Buf, 0, L[1]->LI); + CS_InsertEntry (S, X, I + 9); + + /* Delete the old code */ + CS_DelEntries (S, I, 9); + } + else if (adjustment >= 65536 - 255) { + /* For range [-255, -8) we have ldy #, jsr subysp */ + adjustment = 65536 - adjustment; + Arg = MakeHexArg (adjustment); + X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI); + CS_InsertEntry (S, X, I + 9); + X = NewCodeEntry (OP65_JSR, AM65_ABS, "subysp", 0, L[1]->LI); + CS_InsertEntry (S, X, I + 10); + + /* Delete the old code */ + CS_DelEntries (S, I, 9); + } + else if (adjustment > 255) { + /* For ranges [-32768, 255) and (255, 32767) the only modification + ** is to replace the absolute with immediate addressing + */ + Arg = MakeHexArg (adjustment & 0xff); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, L[1]->LI); + CS_InsertEntry (S, X, I + 1); + Arg = MakeHexArg (adjustment >> 8); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, L[5]->LI); + CS_InsertEntry (S, X, I + 6); + + /* Delete the old code */ + CS_DelEntry (S, I + 2); + CS_DelEntry (S, I + 6); + } + else if (adjustment > 8) { + /* For range (8, 255] we have ldy #, jsr addysp */ + Arg = MakeHexArg (adjustment & 0xff); + X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI); + CS_InsertEntry (S, X, I + 9); + X = NewCodeEntry (OP65_JSR, AM65_ABS, "addysp", 0, L[1]->LI); + CS_InsertEntry (S, X, I + 10); + + /* Delete the old code */ + CS_DelEntries (S, I, 9); + } + else { + /* If adjustment is in range (0, 8] we use incsp* calls */ + char Buf[20]; + xsprintf (Buf, sizeof (Buf), "incsp%u", adjustment); + X = NewCodeEntry (OP65_JSR, AM65_ABS, Buf, 0, L[1]->LI); + CS_InsertEntry (S, X, I + 9); + + /* Delete the old code */ + CS_DelEntries (S, I, 9); + } + /* Regenerate register info */ + CS_GenRegInfo (S); + + /* Remember we had changes */ + Changes++; + + } else { + + /* Next entry */ + ++I; + } + + } + + /* Return the number of changes made */ + return Changes; +} + + + +/*****************************************************************************/ +/* Optimize stack load ops */ +/*****************************************************************************/ + + + +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. +*/ +{ + unsigned I; + unsigned Changes = 0; + + /* Walk over the entries */ + I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* E; + + /* Get next entry */ + E = CS_GetEntry (S, I); + + /* Check for the sequence */ + if (CE_IsCallTo (E, "ldaxysp") && + RegValIsKnown (E->RI->In.RegY) && + !RegXUsed (S, I+1)) { + + CodeEntry* X; + + /* Reload the Y register */ + const char* Arg = MakeHexArg (E->RI->In.RegY - 1); + X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + CS_InsertEntry (S, X, I+1); + + /* Load from stack */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, E->LI); + CS_InsertEntry (S, X, I+2); + + /* Now remove the call to the subroutine */ + CS_DelEntry (S, I); + + /* Remember, we had changes */ + ++Changes; + + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + + +unsigned OptLoad2 (CodeSeg* S) +/* Replace calls to ldaxysp by inline code */ +{ + unsigned I; + unsigned Changes = 0; + + /* Walk over the entries */ + I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* L[3]; + + /* Get next entry */ + L[0] = CS_GetEntry (S, I); + + /* Check for the sequence */ + if (CE_IsCallTo (L[0], "ldaxysp")) { + + CodeEntry* X; + + /* Followed by sta abs/stx abs? */ + if (CS_GetEntries (S, L+1, I+1, 2) && + L[1]->OPC == OP65_STA && + L[2]->OPC == OP65_STX && + (L[1]->Arg == 0 || + L[2]->Arg == 0 || + strcmp (L[1]->Arg, L[2]->Arg) != 0) && + !CS_RangeHasLabel (S, I+1, 2) && + !RegXUsed (S, I+3)) { + + /* A/X are stored into memory somewhere and X is not used + ** later + */ + + /* lda (sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[0]->LI); + CS_InsertEntry (S, X, I+3); + + /* sta abs */ + X = NewCodeEntry (OP65_STA, L[2]->AM, L[2]->Arg, 0, L[2]->LI); + CS_InsertEntry (S, X, I+4); + + /* dey */ + 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); + CS_InsertEntry (S, X, I+6); + + /* sta abs */ + X = NewCodeEntry (OP65_STA, L[1]->AM, L[1]->Arg, 0, L[1]->LI); + CS_InsertEntry (S, X, I+7); + + /* Now remove the call to the subroutine and the sta/stx */ + CS_DelEntries (S, I, 3); + + } else { + + /* Standard replacement */ + + /* lda (sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[0]->LI); + CS_InsertEntry (S, X, I+1); + + /* tax */ + X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, L[0]->LI); + CS_InsertEntry (S, X, I+2); + + /* dey */ + 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); + CS_InsertEntry (S, X, I+4); + + /* Now remove the call to the subroutine */ + CS_DelEntry (S, I); + + } + + /* 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 new file mode 100644 index 000000000..89242351c --- /dev/null +++ b/src/cc65/coptmisc.h @@ -0,0 +1,113 @@ +/*****************************************************************************/ +/* */ +/* codemisc.h */ +/* */ +/* Miscellaneous optimization operations */ +/* */ +/* */ +/* */ +/* (C) 2001-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 COPTMISC_H +#define COPTMISC_H + + + +/* cc65 */ +#include "codeseg.h" + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +unsigned OptDecouple (CodeSeg* S); +/* Decouple operations, that is, do the following replacements: +** +** dex -> ldx #imm +** inx -> ldx #imm +** dey -> ldy #imm +** iny -> ldy #imm +** tax -> ldx #imm +** txa -> lda #imm +** tay -> ldy #imm +** tya -> lda #imm +** lda zp -> lda #imm +** ldx zp -> ldx #imm +** ldy zp -> ldy #imm +** +** Provided that the register values are known of course. +*/ + +unsigned OptIndLoads1 (CodeSeg* S); +/* Change +** +** lda (zp),y +** +** into +** +** lda (zp,x) +** +** provided that x and y are both zero. +*/ + +unsigned OptIndLoads2 (CodeSeg* S); +/* Change +** +** lda (zp,x) +** +** into +** +** lda (zp),y +** +** provided that x and y are both zero. +*/ + +unsigned OptStackPtrOps (CodeSeg* S); +/* Merge adjacent calls to decsp into one. NOTE: This function won't merge all +** known cases! +*/ + +unsigned OptGotoSPAdj (CodeSeg* S); +/* Optimize SP adjustment for forward 'goto' */ + +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. +*/ + +unsigned OptLoad2 (CodeSeg* S); +/* Replace calls to ldaxysp by inline code */ + + +/* End of coptmisc.h */ + +#endif From 57117fa687de59234d299d76f406f4e666844f1f Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 23 Jan 2020 06:39:37 +0800 Subject: [PATCH 1684/2161] Utility functions about compare conditions. --- src/cc65/codeinfo.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ src/cc65/codeinfo.h | 14 ++++++++++- src/cc65/coptcmp.c | 6 +---- 3 files changed, 73 insertions(+), 6 deletions(-) diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index a89f6d54c..6bc62757e 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -64,6 +64,13 @@ static const char CmpSuffixTab [][4] = { "eq", "ne", "gt", "ge", "lt", "le", "ugt", "uge", "ult", "ule" }; +/* Table with the bool transformers */ +static const char BoolTransformerTab [][8] = { + "booleq", "boolne", + "boolgt", "boolge", "boollt", "boolle", + "boolugt", "booluge", "boolult", "boolule" +}; + /* Table listing the function names and code info values for known internally ** used functions. This table should get auto-generated in the future. */ @@ -840,3 +847,55 @@ cmp_t FindTosCmpCond (const char* Name) return CMP_INV; } } + + + +const char* GetBoolTransformer (cmp_t Cond) +/* Get the bool transformer corresponding to the given compare condition */ +{ + if (Cond > CMP_INV && Cond < CMP_END) { + return BoolTransformerTab[Cond]; + } + + /* Not found */ + return 0; +} + + +cmp_t GetNegatedCond (cmp_t Cond) +/* Get the logically opposite compare condition */ +{ + switch (Cond) { + case CMP_EQ: return CMP_NE; + case CMP_NE: return CMP_EQ; + case CMP_GT: return CMP_LE; + case CMP_GE: return CMP_LT; + case CMP_LT: return CMP_GE; + case CMP_LE: return CMP_GT; + case CMP_UGT: return CMP_ULE; + case CMP_UGE: return CMP_ULT; + case CMP_ULT: return CMP_UGE; + case CMP_ULE: return CMP_UGT; + default: return CMP_INV; + } +} + + + +cmp_t GetRevertedCond (cmp_t Cond) +/* Get the compare condition in reverted order of operands */ +{ + switch (Cond) { + case CMP_EQ: return CMP_EQ; + case CMP_NE: return CMP_NE; + case CMP_GT: return CMP_LT; + case CMP_GE: return CMP_LE; + case CMP_LT: return CMP_GT; + case CMP_LE: return CMP_GE; + case CMP_UGT: return CMP_ULT; + case CMP_UGE: return CMP_ULE; + case CMP_ULT: return CMP_UGT; + case CMP_ULE: return CMP_UGE; + default: return CMP_INV; + } +} diff --git a/src/cc65/codeinfo.h b/src/cc65/codeinfo.h index 38e196bcf..3dda3a6bc 100644 --- a/src/cc65/codeinfo.h +++ b/src/cc65/codeinfo.h @@ -115,7 +115,10 @@ typedef enum { CMP_UGT, CMP_UGE, CMP_ULT, - CMP_ULE + CMP_ULE, + + /* End of the enumeration */ + CMP_END } cmp_t; @@ -185,6 +188,15 @@ cmp_t FindTosCmpCond (const char* Name); ** Return the condition code or CMP_INV on failure. */ +const char* GetBoolTransformer (cmp_t Cond); +/* Get the bool transformer corresponding to the given compare condition */ + +cmp_t GetNegatedCond (cmp_t Cond); +/* Get the logically opposite compare condition */ + +cmp_t GetRevertedCond (cmp_t Cond); +/* Get the compare condition in reverted order of operands */ + /* End of codeinfo.h */ diff --git a/src/cc65/coptcmp.c b/src/cc65/coptcmp.c index dbc71bcd5..ca0ba39a8 100644 --- a/src/cc65/coptcmp.c +++ b/src/cc65/coptcmp.c @@ -448,11 +448,7 @@ unsigned OptCmp3 (CodeSeg* S) Delete = 1; break; - case CMP_UGT: - case CMP_UGE: - case CMP_ULT: - case CMP_ULE: - case CMP_INV: + default: /* Leave it alone */ break; } From 7553b60ef07a53c797974a73627cd6bebcc8e8fe Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 23 Jan 2020 06:53:52 +0800 Subject: [PATCH 1685/2161] Improved OptStackOps for optimizating further when operands have equal hi-bytes. --- src/cc65/coptstop.c | 515 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 500 insertions(+), 15 deletions(-) diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index a4fc0dc65..c366d5dde 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -898,6 +898,67 @@ static int IsRegVar (StackOpData* D) +static RegInfo* GetLastChangedRegInfo (StackOpData* D, LoadRegInfo* Reg) +/* Get RegInfo of the last load insn entry */ +{ + CodeEntry* E; + + if (Reg->LoadIndex >= 0 && (E = CS_GetEntry (D->Code, Reg->LoadIndex)) != 0) { + return E->RI; + } + + return 0; +} + + + +static int SameRegAValue (StackOpData* D) +/* Check if Rhs Reg A == Lhs Reg A */ +{ + RegInfo* LRI = GetLastChangedRegInfo (D, &D->Lhs.A); + RegInfo* RRI = GetLastChangedRegInfo (D, &D->Rhs.A); + + /* RHS can have a -1 LoadIndex only if it is carried over from LHS */ + if (RRI == 0 || + (D->Rhs.A.LoadIndex >= 0 && + D->Rhs.A.LoadIndex == D->Lhs.A.LoadIndex) || + (LRI != 0 && + RegValIsKnown (LRI->Out.RegA) && + RegValIsKnown (RRI->Out.RegA) && + (LRI->Out.RegA & 0xFF) == (RRI->Out.RegA & 0xFF))) { + + return 1; + } + + return 0; + +} + + + +static int SameRegXValue (StackOpData* D) +/* Check if Rhs Reg X == Lhs Reg X */ +{ + RegInfo* LRI = GetLastChangedRegInfo (D, &D->Lhs.X); + RegInfo* RRI = GetLastChangedRegInfo (D, &D->Rhs.X); + + if (RRI == 0 || + (D->Rhs.X.LoadIndex >= 0 && + D->Rhs.X.LoadIndex == D->Lhs.X.LoadIndex) || + (LRI != 0 && + RegValIsKnown (LRI->Out.RegX) && + RegValIsKnown (RRI->Out.RegX) && + (LRI->Out.RegX & 0xFF) == (RRI->Out.RegX & 0xFF))) { + + return 1; + } + + return 0; + +} + + + /*****************************************************************************/ /* Actual optimization functions */ /*****************************************************************************/ @@ -1850,6 +1911,251 @@ static unsigned Opt_tosxorax (StackOpData* D) +/*****************************************************************************/ +/* Optimization functions when hi-bytes can be ignored */ +/*****************************************************************************/ + + + +static unsigned Opt_a_toscmpbool (StackOpData* D, const char* BoolTransformer) +/* Optimize the tos compare sequence with a bool transformer */ +{ + CodeEntry* X; + cmp_t Cond; + + D->IP = D->OpIndex + 1; + + if (!D->RhsMultiChg && + (D->Rhs.A.LoadEntry->Flags & CEF_DONT_REMOVE) == 0 && + (D->Rhs.A.Flags & LI_DIRECT) != 0) { + + /* cmp */ + AddOpLow (D, OP65_CMP, &D->Rhs); + + /* Rhs low-byte load must be removed and hi-byte load may be removed */ + D->Rhs.X.Flags |= LI_REMOVE; + D->Rhs.A.Flags |= LI_REMOVE; + + } else if ((D->Lhs.A.Flags & LI_DIRECT) != 0) { + + /* If the lhs is direct (but not stack relative), encode compares with lhs + ** effectively reverting the order (which doesn't matter for ==). + */ + Cond = FindBoolCmpCond (BoolTransformer); + Cond = GetRevertedCond (Cond); + BoolTransformer = GetBoolTransformer (Cond); + + /* This shouldn't fail */ + CHECK (BoolTransformer); + + /* cmp */ + AddOpLow (D, OP65_CMP, &D->Lhs); + + /* Lhs load entries can be removed if not used later */ + D->Lhs.X.Flags |= LI_REMOVE; + D->Lhs.A.Flags |= LI_REMOVE; + + } else { + + /* We'll do reverse-compare */ + Cond = FindBoolCmpCond (BoolTransformer); + Cond = GetRevertedCond (Cond); + BoolTransformer = GetBoolTransformer (Cond); + + /* This shouldn't fail */ + CHECK (BoolTransformer); + + /* Save lhs into zeropage */ + AddStoreLhsA (D); + + /* cmp */ + X = NewCodeEntry (OP65_CMP, AM65_ZP, D->ZPLo, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + + } + + /* Create a call to the boolean transformer function. This is needed for all + ** variants. + */ + X = NewCodeEntry (OP65_JSR, AM65_ABS, BoolTransformer, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + + /* Remove the push and the call to the tosgeax function */ + RemoveRemainders (D); + + /* We changed the sequence */ + return 1; +} + + + +static unsigned Opt_a_toseq (StackOpData* D) +/* Optimize the toseqax sequence */ +{ + return Opt_a_toscmpbool (D, "booleq"); +} + + + +static unsigned Opt_a_tosge (StackOpData* D) +/* Optimize the tosgeax sequence */ +{ + return Opt_a_toscmpbool (D, "boolge"); +} + + + +static unsigned Opt_a_tosgt (StackOpData* D) +/* Optimize the tosgtax sequence */ +{ + return Opt_a_toscmpbool (D, "boolgt"); +} + + + +static unsigned Opt_a_tosicmp (StackOpData* D) +/* Replace tosicmp with CMP */ +{ + CodeEntry* X; + RegInfo* RI; + const char* Arg; + + if (!SameRegAValue (D)) { + /* Because of SameRegAValue */ + CHECK (D->Rhs.A.LoadIndex >= 0); + + /* Store LHS in ZP and reload it before op */ + X = NewCodeEntry (OP65_STA, AM65_ZP, D->ZPLo, 0, D->PushEntry->LI); + InsertEntry (D, X, D->PushIndex + 1); + X = NewCodeEntry (OP65_LDA, AM65_ZP, D->ZPLo, 0, D->PushEntry->LI); + InsertEntry (D, X, D->OpIndex); + + D->IP = D->OpIndex + 1; + + if ((D->Rhs.A.Flags & LI_DIRECT) == 0) { + /* RHS src is not directly comparable */ + X = NewCodeEntry (OP65_STA, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI); + InsertEntry (D, X, D->Rhs.A.LoadIndex + 1); + + /* Cmp with stored RHS */ + X = NewCodeEntry (OP65_CMP, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + } else { + if ((D->Rhs.A.Flags & LI_RELOAD_Y) == 0) { + /* Cmp directly with RHS src */ + X = NewCodeEntry (OP65_CMP, AM65_ZP, D->Rhs.A.LoadEntry->Arg, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + } else { + /* ldy #offs */ + X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (D->Rhs.A.Offs), 0, D->OpEntry->LI); + InsertEntry(D, X, D->IP++); + + /* cmp (sp),y */ + X = NewCodeEntry (OP65_CMP, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI); + InsertEntry(D, X, D->IP++); + } + + /* RHS may be removed */ + D->Rhs.A.Flags |= LI_REMOVE; + D->Rhs.X.Flags |= LI_REMOVE; + } + + /* Fix up the N/V flags: N = ~C, V = 0 */ + Arg = MakeHexArg (0); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + X = NewCodeEntry (OP65_SBC, AM65_IMM, Arg, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + Arg = MakeHexArg (0x01); + X = NewCodeEntry (OP65_ORA, AM65_IMM, Arg, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + + /* jeq L1 */ + CodeLabel* Label = CS_GenLabel (D->Code, CS_GetEntry (D->Code, D->IP)); + X = NewCodeEntry (OP65_JEQ, AM65_BRA, Label->Name, Label, X->LI); + InsertEntry (D, X, D->IP-3); + + } else { + /* Just clear A,Z,N and set C */ + if ((RI = GetLastChangedRegInfo (D, &D->Lhs.A)) != 0 && + RegValIsKnown (RI->Out.RegA) && + (RI->Out.RegA & 0xFF) == 0) { + Arg = MakeHexArg (0); + X = NewCodeEntry (OP65_CMP, AM65_IMM, Arg, 0, D->OpEntry->LI); + InsertEntry (D, X, D->OpIndex + 1); + } else { + Arg = MakeHexArg (0); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, D->OpEntry->LI); + InsertEntry (D, X, D->OpIndex + 1); + X = NewCodeEntry (OP65_CMP, AM65_IMM, Arg, 0, D->OpEntry->LI); + InsertEntry (D, X, D->OpIndex + 2); + } + } + + /* Remove the push and the call to the operator function */ + RemoveRemainders (D); + + return 1; +} + + + +static unsigned Opt_a_tosle (StackOpData* D) +/* Optimize the tosleax sequence */ +{ + return Opt_a_toscmpbool (D, "boolle"); +} + + + +static unsigned Opt_a_toslt (StackOpData* D) +/* Optimize the tosltax sequence */ +{ + return Opt_a_toscmpbool (D, "boollt"); +} + + + +static unsigned Opt_a_tosne (StackOpData* D) +/* Optimize the toseqax sequence */ +{ + return Opt_a_toscmpbool (D, "boolne"); +} + + + +static unsigned Opt_a_tosuge (StackOpData* D) +/* Optimize the tosugeax sequence */ +{ + return Opt_a_toscmpbool (D, "booluge"); +} + + + +static unsigned Opt_a_tosugt (StackOpData* D) +/* Optimize the tosugtax sequence */ +{ + return Opt_a_toscmpbool (D, "boolugt"); +} + + + +static unsigned Opt_a_tosule (StackOpData* D) +/* Optimize the tosuleax sequence */ +{ + return Opt_a_toscmpbool (D, "boolule"); +} + + + +static unsigned Opt_a_tosult (StackOpData* D) +/* Optimize the tosultax sequence */ +{ + return Opt_a_toscmpbool (D, "boolult"); +} + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -1878,7 +2184,22 @@ static const OptFuncDesc FuncTable[] = { { "tosultax", Opt_tosultax, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT }, { "tosxorax", Opt_tosxorax, REG_NONE, OP_NONE }, }; -#define FUNC_COUNT (sizeof(FuncTable) / sizeof(FuncTable[0])) + +static const OptFuncDesc FuncRegATable[] = { + { "toseqax", Opt_a_toseq, REG_NONE, OP_NONE }, + { "tosgeax", Opt_a_tosge, REG_NONE, OP_NONE }, + { "tosgtax", Opt_a_tosgt, REG_NONE, OP_NONE }, + { "tosicmp", Opt_a_tosicmp, REG_NONE, OP_NONE }, + { "tosleax", Opt_a_tosle, REG_NONE, OP_NONE }, + { "tosltax", Opt_a_toslt, REG_NONE, OP_NONE }, + { "tosneax", Opt_a_tosne, REG_NONE, OP_NONE }, + { "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 }, +}; + +#define FUNC_COUNT(Table) (sizeof(Table) / sizeof(Table[0])) @@ -1890,12 +2211,12 @@ static int CmpFunc (const void* Key, const void* Func) -static const OptFuncDesc* FindFunc (const char* Name) +static const OptFuncDesc* FindFunc (const OptFuncDesc FuncTable[], size_t Count, const char* Name) /* Find the function with the given name. Return a pointer to the table entry ** or NULL if the function was not found. */ { - return bsearch (Name, FuncTable, FUNC_COUNT, sizeof(OptFuncDesc), CmpFunc); + return bsearch (Name, FuncTable, Count, sizeof(OptFuncDesc), CmpFunc); } @@ -1990,7 +2311,7 @@ static void ResetStackOpData (StackOpData* Data) static int PreCondOk (StackOpData* D) /* Check if the preconditions for a call to the optimizer subfunction are ** satisfied. As a side effect, this function will also choose the zero page -** register to use. +** register to use for temporary storage. */ { LoadInfo* Lhs; @@ -2136,6 +2457,160 @@ static int PreCondOk (StackOpData* D) +static int RegAPreCondOk (StackOpData* D) +/* Check if the preconditions for a call to the RegA-only optimizer subfunction +** are satisfied. As a side effect, this function will also choose the zero page +** register to use for temporary storage. +*/ +{ + LoadInfo* Lhs; + LoadInfo* Rhs; + LoadRegInfo* LhsLo; + LoadRegInfo* RhsLo; + short LhsLoVal, LhsHiVal; + short RhsLoVal, RhsHiVal; + int I; + int Passed = 0; + + /* Check the flags */ + unsigned UnusedRegs = D->OptFunc->UnusedRegs; + if (UnusedRegs != REG_NONE && + (GetRegInfo (D->Code, D->OpIndex+1, UnusedRegs) & UnusedRegs) != 0) { + /* Cannot optimize */ + return 0; + } + + Passed = 0; + LhsLoVal = D->PushEntry->RI->In.RegA; + LhsHiVal = D->PushEntry->RI->In.RegX; + RhsLoVal = D->OpEntry->RI->In.RegA; + RhsHiVal = D->OpEntry->RI->In.RegX; + /* Check normally first, then interchange A/X and check again if necessary */ + for (I = (D->OptFunc->Flags & OP_AX_INTERCHANGE ? 0 : 1); !Passed && I < 2; ++I) { + + do { + if (LhsHiVal != RhsHiVal) { + /* Cannot optimize */ + break; + } + if ((D->OptFunc->Flags & OP_A_KNOWN) != 0 && + RegValIsUnknown (LhsLoVal)) { + /* Cannot optimize */ + break; + } + if ((D->OptFunc->Flags & OP_X_ZERO) != 0 && + LhsHiVal != 0) { + /* Cannot optimize */ + break; + } + Passed = 1; + } while (0); + + /* Suppress warning about unused assignment in GCC */ + (void)RhsLoVal; + + /* Interchange A/X */ + LhsLoVal = D->PushEntry->RI->In.RegX; + LhsHiVal = D->PushEntry->RI->In.RegA; + RhsLoVal = D->OpEntry->RI->In.RegX; + RhsHiVal = D->OpEntry->RI->In.RegA; + } + if (!Passed) { + /* Cannot optimize */ + return 0; + } + + Passed = 0; + Lhs = &D->Lhs; + Rhs = &D->Rhs; + /* Check normally first, then interchange LHS/RHS and check again if necessary */ + for (I = (D->OptFunc->Flags & OP_LR_INTERCHANGE ? 0 : 1); !Passed && I < 2; ++I) { + + do { + LhsLo = &Lhs->A; + RhsLo = &Rhs->A; + /* Currently we have only LHS/RHS checks with identical requirements for A/X, + ** so we don't need to check twice for now. + */ + + if ((D->OptFunc->Flags & OP_LHS_LOAD) != 0) { + if ((LhsLo->Flags & LI_LOAD_INSN) == 0) { + /* Cannot optimize */ + break; + } else if ((D->OptFunc->Flags & OP_LHS_LOAD_DIRECT) != 0) { + if ((LhsLo->Flags & LI_DIRECT) == 0) { + /* Cannot optimize */ + break; + } + } + } + if ((D->OptFunc->Flags & OP_RHS_LOAD) != 0) { + if ((RhsLo->Flags & LI_LOAD_INSN) == 0) { + /* Cannot optimize */ + break; + } else if ((D->OptFunc->Flags & OP_RHS_LOAD_DIRECT) != 0) { + if ((RhsLo->Flags & LI_DIRECT) == 0) { + /* Cannot optimize */ + break; + } + } + } + if ((D->OptFunc->Flags & OP_LHS_REMOVE) != 0) { + /* Check if the load entries cannot be removed */ + if ((LhsLo->LoadEntry != 0 && (LhsLo->LoadEntry->Flags & CEF_DONT_REMOVE) != 0)) { + if ((D->OptFunc->Flags & OP_LHS_REMOVE_DIRECT) != 0) { + /* Cannot optimize */ + break; + } + } + } + if ((D->OptFunc->Flags & OP_RHS_REMOVE) != 0) { + if ((RhsLo->LoadEntry != 0 && (RhsLo->LoadEntry->Flags & CEF_DONT_REMOVE) != 0)) { + if ((D->OptFunc->Flags & OP_RHS_REMOVE_DIRECT) != 0) { + /* Cannot optimize */ + break; + } + } + } + if (D->RhsMultiChg && (D->OptFunc->Flags & OP_RHS_REMOVE_DIRECT) != 0) { + /* Cannot optimize */ + break; + } + Passed = 1; + } while (0); + + /* Interchange LHS/RHS for next round */ + Lhs = &D->Rhs; + Rhs = &D->Lhs; + } + if (!Passed) { + /* Cannot optimize */ + return 0; + } + + /* Determine the zero page locations to use. We've tracked the used + ** ZP locations, so try to find some for us that are unused. + */ + if ((D->ZPUsage & REG_PTR1) == REG_NONE) { + D->ZPLo = "ptr1"; + D->ZPHi = "ptr1+1"; + } else if ((D->ZPUsage & REG_SREG) == REG_NONE) { + D->ZPLo = "sreg"; + D->ZPHi = "sreg+1"; + } else if ((D->ZPUsage & REG_PTR2) == REG_NONE) { + D->ZPLo = "ptr2"; + D->ZPHi = "ptr2+1"; + } else { + /* No registers available */ + return 0; + } + + /* Determine if we have a basic block */ + return CS_IsBasicBlock (D->Code, D->PushIndex, D->OpIndex); +} + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -2191,14 +2666,15 @@ static void ResetDontRemoveEntryFlags (StackOpData* D) unsigned OptStackOps (CodeSeg* S) /* Optimize operations that take operands via the stack */ { - unsigned Changes = 0; /* Number of changes in one run */ - StackOpData Data; - int I; - int OldEntryCount; /* Old number of entries */ - unsigned Used; /* What registers would be used */ - unsigned PushedRegs; /* Track if the same regs are used after the push */ - int RhsALoadIndex; /* Track if rhs is changed more than once */ - int RhsXLoadIndex; /* Track if rhs is changed more than once */ + unsigned Changes = 0; /* Number of changes in one run */ + StackOpData Data; + int I; + int OldEntryCount; /* Old number of entries */ + unsigned Used; /* What registers would be used */ + unsigned PushedRegs; /* Track if the same regs are used after the push */ + int RhsALoadIndex; /* Track if rhs is changed more than once */ + int RhsXLoadIndex; /* Track if rhs is changed more than once */ + int IsRegAOptFunc = 0; /* Whether to use the RegA-only optimizations */ enum { Initialize, @@ -2225,6 +2701,8 @@ unsigned OptStackOps (CodeSeg* S) ** ** Since we need a zero page register later, do also check the ** intermediate code for zero page use. + ** When hibytes of both oprands are equal, we may have more specialized + ** optimization for the op. */ I = 0; while (I < (int)CS_GetEntryCount (S)) { @@ -2300,7 +2778,14 @@ unsigned OptStackOps (CodeSeg* S) /* Subroutine call: Check if this is one of the functions, ** we're going to replace. */ - Data.OptFunc = FindFunc (E->Arg); + if (SameRegXValue (&Data)) { + Data.OptFunc = FindFunc (FuncRegATable, FUNC_COUNT (FuncRegATable), E->Arg); + IsRegAOptFunc = 1; + } + if (Data.OptFunc == 0) { + Data.OptFunc = FindFunc (FuncTable, FUNC_COUNT (FuncTable), E->Arg); + IsRegAOptFunc = 0; + } if (Data.OptFunc) { /* Disallow removing the loads if the registers are used */ if (Data.UsedRegs & REG_A) { @@ -2419,11 +2904,11 @@ unsigned OptStackOps (CodeSeg* S) SetDontRemoveEntryFlags (&Data); /* Check the preconditions. If they aren't ok, reset the insn - ** pointer to the pushax and start over. We will loose part of + ** pointer to the pushax and start over. We will lose part of ** load tracking but at least a/x has probably lost between ** pushax and here and will be tracked again when restarting. */ - if (!PreCondOk (&Data)) { + if (IsRegAOptFunc ? !RegAPreCondOk (&Data) : !PreCondOk (&Data)) { /* Unflag entries that can't be removed */ ResetDontRemoveEntryFlags (&Data); I = Data.PushIndex; From 41cee0eb44de6f98910ca98255244f1d4731352d Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 23 Jan 2020 06:54:34 +0800 Subject: [PATCH 1686/2161] Extended support for more addressing modes in tos* optimizations. --- src/cc65/coptstop.c | 185 ++++++++++++++++++++++++++++++++------------ 1 file changed, 134 insertions(+), 51 deletions(-) diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index c366d5dde..f4f34d163 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -59,12 +59,14 @@ typedef enum { LI_RELOAD_Y = 0x02, /* Reload index register Y */ LI_REMOVE = 0x04, /* Load may be removed */ LI_DONT_REMOVE = 0x08, /* Load may not be removed */ - LI_MAYBE_DIRECT = 0x10, /* Load src might be modified later */ + LI_CHECK_ARG = 0x10, /* Load src might be modified later */ LI_SRC_CHG = 0x20, /* Load src is possibly modified */ LI_LOAD_INSN = 0x40, /* Has a load insn */ + LI_CHECK_Y = 0x80, /* Indexed load src might be modified later */ LI_USED_BY_A = 0x100, /* Content used by RegA */ LI_USED_BY_X = 0x200, /* Content used by RegX */ LI_USED_BY_Y = 0x400, /* Content used by RegY */ + LI_SP = 0x800, /* Content on stack */ } LI_FLAGS; /* Structure that tells us how to load the lhs values */ @@ -73,6 +75,8 @@ struct LoadRegInfo { LI_FLAGS Flags; /* Tells us how to load */ int LoadIndex; /* Index of load insn, -1 if invalid */ CodeEntry* LoadEntry; /* The actual entry, 0 if invalid */ + int LoadYIndex; /* Index of Y-load insn, -1 if invalid */ + CodeEntry* LoadYEntry; /* The actual Y-load entry, 0 if invalid */ int XferIndex; /* Index of transfer insn */ CodeEntry* XferEntry; /* The actual transfer entry */ int Offs; /* Stack offset if data is on stack */ @@ -178,12 +182,14 @@ struct StackOpData { static void ClearLoadRegInfo (LoadRegInfo* RI) /* Clear a LoadRegInfo struct */ { - RI->Flags = LI_NONE; - RI->LoadIndex = -1; - RI->LoadEntry = 0; - RI->XferIndex = -1; - RI->XferEntry = 0; - RI->Offs = 0; + RI->Flags = LI_NONE; + RI->LoadIndex = -1; + RI->LoadEntry = 0; + RI->LoadYIndex = -1; + RI->LoadYEntry = 0; + RI->XferIndex = -1; + RI->XferEntry = 0; + RI->Offs = 0; } @@ -191,12 +197,14 @@ static void ClearLoadRegInfo (LoadRegInfo* RI) static void CopyLoadRegInfo (LoadRegInfo* To, LoadRegInfo* From) /* Copy a LoadRegInfo struct */ { - To->Flags = From->Flags; - To->LoadIndex = From->LoadIndex; - To->LoadEntry = From->LoadEntry; - To->XferIndex = From->XferIndex; - To->XferEntry = From->XferEntry; - To->Offs = From->Offs; + To->Flags = From->Flags; + To->LoadIndex = From->LoadIndex; + To->LoadEntry = From->LoadEntry; + To->LoadYIndex = From->LoadYIndex; + To->LoadYEntry = From->LoadYEntry; + To->XferIndex = From->XferIndex; + To->XferEntry = From->XferEntry; + To->Offs = From->Offs; } @@ -216,8 +224,18 @@ static void FinalizeLoadRegInfo (LoadRegInfo* RI, CodeSeg* S) RI->XferEntry = 0; } /* Load from src not modified before op can be treated as direct */ - if ((RI->Flags & (LI_MAYBE_DIRECT | LI_SRC_CHG)) == LI_MAYBE_DIRECT) { + if ((RI->Flags & LI_SRC_CHG) == 0 && + (RI->Flags & (LI_CHECK_ARG | LI_CHECK_Y)) != 0) { RI->Flags |= LI_DIRECT; + if ((RI->Flags & LI_CHECK_Y) != 0) { + RI->Flags |= LI_RELOAD_Y; + } + } + /* We cannot ldy src,y */ + if ((RI->Flags & LI_RELOAD_Y) != 0 && + RI->LoadYEntry != 0 && + (RI->LoadYEntry->Use & REG_Y) == REG_Y) { + RI->Flags &= ~LI_DIRECT; } } @@ -305,17 +323,27 @@ static int Affected (LoadRegInfo* RI, const CodeEntry* E) fncls_t fncls; unsigned short Use; unsigned short Chg; + unsigned short UseToCheck = 0; - if (RI->Flags & LI_MAYBE_DIRECT) { + if ((RI->Flags & (LI_CHECK_ARG | LI_CHECK_Y)) != 0) { if (E->AM == AM65_IMM || E->AM == AM65_ACC || E->AM == AM65_IMP || E->AM == AM65_BRA) { return 0; } - CHECK (RI->LoadEntry != 0); + CHECK ((RI->Flags & LI_CHECK_ARG) == 0 || RI->LoadEntry != 0); + CHECK ((RI->Flags & LI_CHECK_Y) == 0 || RI->LoadYEntry != 0); + + if ((RI->Flags & LI_CHECK_ARG) != 0) { + UseToCheck |= RI->LoadEntry->Use; + } + + if ((RI->Flags & LI_CHECK_Y) != 0) { + UseToCheck |= RI->LoadYEntry->Use; + } if (E->OPC == OP65_JSR) { /* Try to know about the function */ fncls = GetFuncInfo (E->Arg, &Use, &Chg); - if ((RI->LoadEntry->Use & Chg & REG_ALL) == 0 && + if ((UseToCheck & Chg & REG_ALL) == 0 && fncls == FNCLS_BUILTIN) { /* Builtin functions are known to be harmless */ return 0; @@ -327,8 +355,15 @@ static int Affected (LoadRegInfo* RI, const CodeEntry* E) E->OPC == OP65_ROL || E->OPC == OP65_ROR || E->OPC == OP65_TRB || E->OPC == OP65_TSB || E->OPC == OP65_STA || E->OPC == OP65_STX || E->OPC == OP65_STY) { - if ((E->AM == AM65_ABS || E->AM == AM65_ZP) && - strcmp (RI->LoadEntry->Arg, E->Arg) != 0) { + if ((E->AM == AM65_ABS || E->AM == AM65_ZP)) { + if ((RI->Flags & LI_CHECK_ARG) != 0 && + strcmp (RI->LoadEntry->Arg, E->Arg) == 0) { + return 1; + } + if ((RI->Flags & LI_CHECK_Y) != 0 && + strcmp (RI->LoadYEntry->Arg, E->Arg) == 0) { + return 1; + } return 0; } /* We could've check further for more cases where the load target isn't modified, @@ -398,11 +433,11 @@ static unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I) RI->Flags |= LI_DIRECT; } else if (E->AM == AM65_ZP || E->AM == AM65_ABS) { /* These insns are replaceable only if they are not modified later */ - RI->Flags |= LI_MAYBE_DIRECT; - /* Watch for any change of the load target */ - RI->LoadEntry = CS_GetEntry (S, I); + RI->Flags |= LI_CHECK_ARG; + } else if (E->AM == AM65_ZPY || E->AM == AM65_ABSY) { + /* These insns are replaceable only if they are not modified later */ + RI->Flags |= LI_CHECK_ARG | LI_CHECK_Y; } else if (E->AM == AM65_ZP_INDY && - RegValIsKnown (E->RI->In.RegY) && strcmp (E->Arg, "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 @@ -410,16 +445,34 @@ static unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I) ** these locations may change between the push and the actual ** operation. */ - RI->Offs = (unsigned char) E->RI->In.RegY; - RI->Flags |= (LI_DIRECT | LI_RELOAD_Y); + RI->Flags |= LI_DIRECT | LI_CHECK_Y | LI_SP; /* Reg Y can be regarded as unused if this load is removed */ Used &= ~REG_Y; - LI->Y.Flags |= LI_USED_BY_A; + if (RI == &LI->A) { + LI->Y.Flags |= LI_USED_BY_A; + } else { + LI->Y.Flags |= LI_USED_BY_X; + } + } + + /* If the load offset has a known value, we can just remember and reload + ** it into the index register later. + */ + if ((RI->Flags & LI_CHECK_Y) != 0) { + if (RegValIsKnown (E->RI->In.RegY)) { + RI->Offs = (unsigned char)E->RI->In.RegY; + RI->Flags &= ~LI_CHECK_Y; + RI->Flags |= LI_RELOAD_Y; + } else { + /* We need to check if the src of Y is changed */ + RI->LoadYIndex = LI->Y.LoadIndex; + RI->LoadYEntry = CS_GetEntry (S, RI->LoadYIndex); + } } /* Watch for any change of the load target */ - if ((RI->Flags & LI_MAYBE_DIRECT) != 0) { + if ((RI->Flags & LI_CHECK_ARG) != 0) { RI->LoadEntry = CS_GetEntry (S, I); } @@ -462,23 +515,25 @@ static unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I) } /* Transfer the data */ - Tgt->LoadIndex = Src->LoadIndex; - Tgt->LoadEntry = Src->LoadEntry; - Tgt->XferIndex = I; - Tgt->Offs = Src->Offs; - Tgt->Flags = Src->Flags; + Tgt->LoadIndex = Src->LoadIndex; + Tgt->LoadEntry = Src->LoadEntry; + Tgt->LoadYIndex = Src->LoadYIndex; + Tgt->LoadYEntry = Src->LoadYEntry; + Tgt->XferIndex = I; + Tgt->Offs = Src->Offs; + Tgt->Flags = Src->Flags; } else if (CE_IsCallTo (E, "ldaxysp") && RegValIsKnown (E->RI->In.RegY)) { /* Both registers set, Y changed */ LI->A.LoadIndex = I; LI->A.XferIndex = -1; - LI->A.Flags = (LI_LOAD_INSN | LI_DIRECT | LI_RELOAD_Y); + LI->A.Flags = (LI_LOAD_INSN | LI_DIRECT | LI_RELOAD_Y | LI_SP); LI->A.Offs = (unsigned char) E->RI->In.RegY - 1; LI->X.LoadIndex = I; LI->X.XferIndex = -1; - LI->X.Flags = (LI_LOAD_INSN | LI_DIRECT | LI_RELOAD_Y); + LI->X.Flags = (LI_LOAD_INSN | LI_DIRECT | LI_RELOAD_Y | LI_SP); LI->X.Offs = (unsigned char) E->RI->In.RegY; /* Reg Y can be regarded as unused if this load is removed */ @@ -658,10 +713,10 @@ static void AdjustStackOffset (StackOpData* D, unsigned Offs) /* If we have rhs load insns that load from stack, we'll have to adjust ** the offsets for these also. */ - if (D->Rhs.A.Flags & LI_RELOAD_Y) { + if ((D->Rhs.A.Flags & (LI_RELOAD_Y | LI_SP | LI_CHECK_Y)) == (LI_RELOAD_Y | LI_SP)) { D->Rhs.A.Offs -= Offs; } - if (D->Rhs.X.Flags & LI_RELOAD_Y) { + if ((D->Rhs.X.Flags & (LI_RELOAD_Y | LI_SP | LI_CHECK_Y)) == (LI_RELOAD_Y | LI_SP)) { D->Rhs.X.Offs -= Offs; } } @@ -727,13 +782,22 @@ static void AddOpLow (StackOpData* D, opc_t OPC, LoadInfo* LI) } else { - /* ldy #offs */ - const char* Arg = MakeHexArg (LI->A.Offs); - X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, D->OpEntry->LI); + if ((LI->A.Flags & LI_CHECK_Y) == 0) { + /* ldy #offs */ + X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (LI->A.Offs), 0, D->OpEntry->LI); + } else { + /* ldy src */ + X = NewCodeEntry (OP65_LDY, LI->A.LoadYEntry->AM, LI->A.LoadYEntry->Arg, 0, D->OpEntry->LI); + } InsertEntry (D, X, D->IP++); - /* opc (sp),y */ - X = NewCodeEntry (OPC, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI); + if (LI->A.LoadEntry->OPC == OP65_JSR) { + /* opc (sp),y */ + X = NewCodeEntry (OPC, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI); + } else { + /* opc src,y */ + X = NewCodeEntry (OPC, LI->A.LoadEntry->AM, LI->A.LoadEntry->Arg, 0, D->OpEntry->LI); + } InsertEntry (D, X, D->IP++); } @@ -781,13 +845,22 @@ static void AddOpHigh (StackOpData* D, opc_t OPC, LoadInfo* LI, int KeepResult) } else { - /* ldy #const */ - const char* Arg = MakeHexArg (LI->X.Offs); - X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, D->OpEntry->LI); + if ((LI->A.Flags & LI_CHECK_Y) == 0) { + /* ldy #const */ + X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (LI->X.Offs), 0, D->OpEntry->LI); + } else { + /* ldy src */ + X = NewCodeEntry (OP65_LDY, LI->X.LoadYEntry->AM, LI->X.LoadYEntry->Arg, 0, D->OpEntry->LI); + } InsertEntry (D, X, D->IP++); - /* opc (sp),y */ - X = NewCodeEntry (OPC, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI); + if (LI->X.LoadEntry->OPC == OP65_JSR) { + /* opc (sp),y */ + X = NewCodeEntry (OPC, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI); + } else { + /* opc src,y */ + X = NewCodeEntry (OPC, LI->A.LoadEntry->AM, LI->A.LoadEntry->Arg, 0, D->OpEntry->LI); + } InsertEntry (D, X, D->IP++); } @@ -2047,12 +2120,22 @@ static unsigned Opt_a_tosicmp (StackOpData* D) InsertEntry (D, X, D->IP++); } else { /* ldy #offs */ - X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (D->Rhs.A.Offs), 0, D->OpEntry->LI); - InsertEntry(D, X, D->IP++); + if ((D->Rhs.A.Flags & LI_CHECK_Y) == 0) { + X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (D->Rhs.A.Offs), 0, D->OpEntry->LI); + } else { + X = NewCodeEntry (OP65_LDY, D->Rhs.A.LoadYEntry->AM, D->Rhs.A.LoadYEntry->Arg, 0, D->OpEntry->LI); + } + InsertEntry (D, X, D->IP++); - /* cmp (sp),y */ - X = NewCodeEntry (OP65_CMP, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI); - InsertEntry(D, X, D->IP++); + /* cmp src,y OR cmp (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); + } else { + /* opc src,y */ + X = NewCodeEntry (OP65_CMP, D->Rhs.A.LoadEntry->AM, D->Rhs.A.LoadEntry->Arg, 0, D->OpEntry->LI); + } + InsertEntry (D, X, D->IP++); } /* RHS may be removed */ From 4e4e4c2d2194c2c1f73d8c4503b4c6c56e1aa9a7 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sun, 30 Aug 2020 20:47:25 +0200 Subject: [PATCH 1687/2161] Allow char bit-fields These are not required to be supported (only int, signed int, and unsigned int are required), but most compilers support it. https://port70.net/~nsz/c/c89/c89-draft.html#3.5.2.1 https://port70.net/~nsz/c/c89/c89-draft.html#A.6.5.8 For consistency with other integral types, plain `char` bit-fields are unsigned, regardless of the `--signed-chars` option. Fixes #1047 --- doc/cc65.sgml | 5 + src/cc65/declare.c | 6 +- src/cc65/symtab.c | 8 +- test/{err => val}/bug1047.c | 0 test/val/char-bitfield.c | 280 ++++++++++++++++++++++++++++++++++++ test/val/enum-bitfield.c | 107 ++++++++++++++ 6 files changed, 401 insertions(+), 5 deletions(-) rename test/{err => val}/bug1047.c (100%) create mode 100644 test/val/char-bitfield.c diff --git a/doc/cc65.sgml b/doc/cc65.sgml index e7b8f260d..e3d9694fe 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -807,6 +807,11 @@ This cc65 version has some extensions to the ISO C standard. <tt/_Static_assert/ is also available as the macro <tt/static_assert/ in <tt/assert.h/. +<item> cc65 supports bit-fields of any integral type that is int-sized or + smaller, and enumerated types with those types as their underlying + type. (Only <tt/int/, <tt/signed int/, and <tt/unsigned int/ are + required.) + <item> Computed gotos, a GCC extension, has limited support. With it you can use fast jump tables from C. You can take the address of a label with a double ampersand, putting them in a static const array of type void *. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 857021671..8d0a1097c 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -764,9 +764,9 @@ static int ParseFieldWidth (Declaration* Decl) /* TODO: This can be relaxed to be any integral type, but ** ParseStructInit currently only supports up to int. */ - if (SizeOf (Decl->Type) != SizeOf (type_uint)) { - /* Only int sized types may be used for bit-fields for now */ - Error ("cc65 currently only supports unsigned int bit-fields"); + if (SizeOf (Decl->Type) > SizeOf (type_uint)) { + /* Only int-sized or smaller types may be used for bit-fields for now */ + Error ("cc65 currently only supports char-sized and int-sized bit-fields"); return -1; } diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 5546d450c..56c868b2a 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -870,9 +870,13 @@ SymEntry* AddBitField (const char* Name, const Type* T, unsigned Offs, if (!SignednessSpecified) { /* int is treated as signed int everywhere except bit-fields; switch it to unsigned, ** since this is allowed for bit-fields and avoids sign-extension, so is much faster. - ** enums set SignednessSpecified to 1 to avoid this adjustment. + ** enums set SignednessSpecified to 1 to avoid this adjustment. Character types + ** actually distinguish 3 types of char; char may either be signed or unsigned, which + ** is controlled by `--signed-chars`. In bit-fields, however, we perform the same + ** `char -> unsigned char` adjustment that is performed with other integral types. */ - CHECK ((Entry->Type->C & T_MASK_SIGN) == T_SIGN_SIGNED); + CHECK ((Entry->Type->C & T_MASK_SIGN) == T_SIGN_SIGNED || + IsTypeChar (Entry->Type)); Entry->Type->C &= ~T_MASK_SIGN; Entry->Type->C |= T_SIGN_UNSIGNED; } diff --git a/test/err/bug1047.c b/test/val/bug1047.c similarity index 100% rename from test/err/bug1047.c rename to test/val/bug1047.c diff --git a/test/val/char-bitfield.c b/test/val/char-bitfield.c new file mode 100644 index 000000000..0d611f127 --- /dev/null +++ b/test/val/char-bitfield.c @@ -0,0 +1,280 @@ +/* + Copyright 2020 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. +*/ + +/* + Tests of char bit-fields; see https://github.com/cc65/cc65/issues/1047 +*/ + +#include <stdio.h> + +static unsigned char failures = 0; + +static struct four_bits { + unsigned char x : 4; +} fb = {1}; + +static void test_four_bits (void) +{ + if (sizeof (struct four_bits) != 1) { + printf ("Got sizeof (struct four_bits) = %zu, expected 1.\n", + sizeof (struct four_bits)); + failures++; + } + + if (fb.x != 1) { + printf ("Got fb.x = %u, expected 1.\n", fb.x); + failures++; + } + + fb.x = 3; + + if (fb.x != 3) { + printf ("Got fb.x = %u, expected 3.\n", fb.x); + failures++; + } +} + +static struct four_bits_signed { + signed char x : 4; +} fbs = {1}; + +static void test_four_bits_signed (void) +{ + if (sizeof (struct four_bits_signed) != 1) { + printf ("Got sizeof (struct four_bits_signed) = %zu, expected 1.\n", + sizeof (struct four_bits)); + failures++; + } + + if (fbs.x != 1) { + printf ("Got fbs.x = %d, expected 1.\n", fbs.x); + failures++; + } + + fbs.x = 3; + + if (fbs.x != 3) { + printf ("Got fbs.x = %d, expected 3.\n", fbs.x); + failures++; + } +} + +static struct four_bits_plain { + char x : 4; +} fbp = {1}; + +static void test_four_bits_plain (void) +{ + if (sizeof (struct four_bits_plain) != 1) { + printf ("Got sizeof (struct four_bits_plain) = %zu, expected 1.\n", + sizeof (struct four_bits)); + failures++; + } + + if (fbp.x != 1) { + printf ("Got fbp.x = %d, expected 1.\n", fbp.x); + failures++; + } + + fbp.x = 3; + + if (fbp.x != 3) { + printf ("Got fbp.x = %d, expected 3.\n", fbp.x); + failures++; + } +} + +/* + Logic is somewhat diferent for bit-fields that end a struct vs + having additional fields. +*/ + +static struct four_bits_with_char { + unsigned char x : 4; + unsigned char y; +} fbi = {1, 2}; + +static void test_four_bits_with_char (void) +{ + if (sizeof (struct four_bits_with_char) != 2) { + printf ("Got sizeof (struct four_bits_with_char) = %zu, expected 2.\n", + sizeof (struct four_bits_with_char)); + failures++; + } + + if (fbi.x != 1) { + printf ("Got fbi.x = %u, expected 1.\n", fbi.x); + failures++; + } + + if (fbi.y != 2) { + printf ("Got fbi.y = %u, expected 2.\n", fbi.y); + failures++; + } + + fbi.x = 3; + fbi.y = 17; + + if (fbi.x != 3) { + printf ("Got fbi.x = %u, expected 3.\n", fbi.x); + failures++; + } + + if (fbi.y != 17) { + printf ("Got fbi.y = %u, expected 17.\n", fbi.y); + failures++; + } +} + +static struct two_chars { + unsigned char x : 4; + unsigned char y : 4; +} o = {11, 7}; + +/* Tests that bit-fields can share allocation units. */ +static void test_two_chars (void) +{ + if (sizeof (struct two_chars) != 1) { + printf ("Got sizeof (struct two_chars) = %zu, expected 1.\n", + sizeof (struct two_chars)); + failures++; + } + + if (o.x != 11) { + printf ("Got o.x = %u, expected 11.\n", o.x); + failures++; + } + + if (o.y != 7) { + printf ("Got o.y = %u, expected 7.\n", o.y); + failures++; + } + + o.x = 3; + o.y = 4; + + if (o.x != 3) { + printf ("Got o.x = %u, expected 3.\n", o.x); + failures++; + } + + if (o.y != 4) { + printf ("Got o.y = %u, expected 4.\n", o.y); + failures++; + } +} + +static struct full_width { + unsigned char x : 8; +} fw = {255}; + +static void test_full_width (void) +{ + if (sizeof (struct full_width) != 1) { + printf ("Got sizeof (struct full_width) = %zu, expected 1.\n", + sizeof (struct full_width)); + failures++; + } + + if (fw.x != 255) { + printf ("Got fw.x = %u, expected 255.\n", fw.x); + failures++; + } + + fw.x = 42; + + if (fw.x != 42) { + printf ("Got fw.x = %u, expected 42.\n", fw.x); + failures++; + } +} + +static struct aligned_end { + unsigned char : 2; + unsigned char x : 6; + unsigned char : 3; + unsigned char y : 5; +} ae = {63, 17}; + +static void test_aligned_end (void) +{ + if (sizeof (struct aligned_end) != 2) { + printf ("Got sizeof (struct aligned_end) = %zu, expected 2.\n", + sizeof (struct aligned_end)); + failures++; + } + + if (ae.x != 63) { + printf ("Got ae.x = %u, expected 63.\n", ae.x); + failures++; + } + + if (ae.y != 17) { + printf ("Got ae.y = %u, expected 17.\n", ae.y); + failures++; + } + + ae.x = 42; + ae.y = 15; + + if (ae.x != 42) { + printf ("Got ae.x = %u, expected 42.\n", ae.x); + failures++; + } + + if (ae.y != 15) { + printf ("Got ae.y = %u, expected 15.\n", ae.y); + failures++; + } +} + +struct { signed char x : 1; } sc = {-1}; +struct { unsigned char x : 1; } uc = {1}; +struct { char x : 1; } pc = {1}; + +static void test_signedness (void) +{ + if (sc.x != -1) { + printf ("Got sc.x = %d, expected -1.\n", sc.x); + failures++; + } + + if (uc.x != 1) { + printf ("Got uc.x = %u, expected 1.\n", uc.x); + failures++; + } + + if (pc.x != 1) { + printf ("Got pc.x = %u, expected 1.\n", pc.x); + failures++; + } +} + +int main (void) +{ + test_four_bits (); + test_four_bits_with_char (); + test_two_chars (); + test_full_width (); + test_aligned_end (); + test_signedness (); + printf ("failures: %u\n", failures); + return failures; +} diff --git a/test/val/enum-bitfield.c b/test/val/enum-bitfield.c index 62e05f71f..a942091c2 100644 --- a/test/val/enum-bitfield.c +++ b/test/val/enum-bitfield.c @@ -149,10 +149,117 @@ static void test_enum_bitfield_int(void) } } +/* Enum with underlying type unsigned char. */ +enum e7uc { + E7UC_100 = 100, +}; + +static struct enum_bitfield_uchar { + enum e7uc x : 1; + enum e7uc y : 4; + enum e7uc z : 8; +} e7ucbf = {0, 10, E7UC_100}; + +static void test_enum_bitfield_uchar(void) +{ + if (sizeof (struct enum_bitfield_uchar) != 2) { + printf ("Got sizeof(struct enum_bitfield_uchar) = %zu, expected 2.\n", + sizeof(struct enum_bitfield_uchar)); + failures++; + } + + if (e7ucbf.x != 0) { + printf ("Got e7ucbf.x = %u, expected 0.\n", e7ucbf.x); + failures++; + } + if (e7ucbf.y != 10) { + printf ("Got e7ucbf.y = %u, expected 10.\n", e7ucbf.y); + failures++; + } + if (e7ucbf.z != 100) { + printf ("Got e7ucbf.z = %u, expected 100.\n", e7ucbf.z); + failures++; + } + + e7ucbf.x = -1; /* Will store 1. */ + e7ucbf.y = -1; /* Will store 15. */ + e7ucbf.z = 127; + + /* Both signed char and unsigned char are converted to int in arithmetic expressions, + ** so we write this test differently to enum_bitfield_int. + */ + if (e7ucbf.x != 1) { + printf ("Got e7ucbf.x = %u, expected 1.\n", e7ucbf.x); + failures++; + } + + if (e7ucbf.y != 15) { + printf ("Got e7ucbf.y = %u, expected 15.\n", e7ucbf.y); + failures++; + } + if (e7ucbf.z != 127) { + printf ("Got e7ucbf.z = %u, expected 127.\n", e7ucbf.z); + failures++; + } +} + +/* Enum with underlying type signed char. */ +enum e8sc { + E8SC_M1 = -1, + E8SC_100 = 100, +}; + +static struct enum_bitfield_char { + enum e8sc x : 1; + enum e8sc y : 4; + enum e8sc z : 8; +} e8scbf = {0, 5, E8SC_100}; + +static void test_enum_bitfield_char(void) +{ + if (sizeof (struct enum_bitfield_char) != 2) { + printf ("Got sizeof(struct enum_bitfield_char) = %zu, expected 2.\n", + sizeof(struct enum_bitfield_char)); + failures++; + } + + if (e8scbf.x != 0) { + printf ("Got e8scbf.x = %d, expected 0.\n", e8scbf.x); + failures++; + } + if (e8scbf.y != 5) { + printf ("Got e8scbf.y = %d, expected 10.\n", e8scbf.y); + failures++; + } + if (e8scbf.z != 100) { + printf ("Got e8scbf.z = %d, expected 100.\n", e8scbf.z); + failures++; + } + + e8scbf.x = -1; + e8scbf.y = -3; + e8scbf.z = 127; + + if (e8scbf.x != -1) { + printf ("Got e8scbf.x = %d, expected -1.\n", e8scbf.x); + failures++; + } + if (e8scbf.y != -3) { + printf ("Got e8scbf.y = %d, expected -3.\n", e8scbf.y); + failures++; + } + if (e8scbf.z != 127) { + printf ("Got e8scbf.z = %d, expected 127.\n", e8scbf.z); + failures++; + } +} + int main(void) { test_enum_bitfield_uint(); test_enum_bitfield_int(); + test_enum_bitfield_uchar(); + test_enum_bitfield_char(); printf("failures: %u\n", failures); return failures; } From ab7e9f84241c6f686999eb61069273c27dc0add5 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 8 Sep 2020 21:36:38 +0800 Subject: [PATCH 1688/2161] Hotfix for Issue #1250. --- src/cc65/expr.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index e1b22ac50..826e72b09 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1933,13 +1933,6 @@ void hie10 (ExprDesc* Expr) case TOK_STAR: NextToken (); ExprWithCheck (hie10, Expr); - if (ED_IsLVal (Expr) || !ED_IsLocQuasiConst (Expr)) { - /* Not a const, load the pointer into the primary and make it a - ** calculated value. - */ - LoadExpr (CF_NONE, Expr); - ED_FinalizeRValLoad (Expr); - } /* If the expression is already a pointer to function, the ** additional dereferencing operator must be ignored. A function @@ -1951,6 +1944,14 @@ void hie10 (ExprDesc* Expr) /* Expression not storable */ ED_MarkExprAsRVal (Expr); } else { + if (!ED_IsQuasiConstAddr (Expr)) { + /* Not a constant address, load the pointer into the primary + ** and make it a calculated value. + */ + LoadExpr (CF_NONE, Expr); + ED_FinalizeRValLoad (Expr); + } + if (IsClassPtr (Expr->Type)) { Expr->Type = Indirect (Expr->Type); } else { From ae6696fcb9beed9e2c5d8c2207e861ac1a0861db Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 8 Sep 2020 10:24:27 -0400 Subject: [PATCH 1689/2161] Removed some ambiguity from a statement. A limited number of bit-field types are required by the C standard, not by cc65. --- doc/cc65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index e3d9694fe..578217307 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -810,7 +810,7 @@ This cc65 version has some extensions to the ISO C standard. <item> cc65 supports bit-fields of any integral type that is int-sized or smaller, and enumerated types with those types as their underlying type. (Only <tt/int/, <tt/signed int/, and <tt/unsigned int/ are - required.) + required by the standard.) <item> Computed gotos, a GCC extension, has limited support. With it you can use fast jump tables from C. You can take the address of a label with From 142b0bf9b35103361bac5a50d8c74c29335943b9 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 5 Sep 2020 11:26:00 +0800 Subject: [PATCH 1690/2161] Added utility functions to get names of comparison function/transformer subroutines. --- src/cc65/codeinfo.c | 57 +++++++++++++++++++++++++++++++++++++++++++++ src/cc65/codeinfo.h | 14 +++++++++++ 2 files changed, 71 insertions(+) diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 6bc62757e..24e27ee10 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -850,6 +850,63 @@ cmp_t FindTosCmpCond (const char* Name) +const char* GetCmpSuffix (cmp_t Cond) +/* Return the compare suffix by the given a compare condition or 0 on failure */ +{ + /* Check for the correct subroutine name */ + if (Cond >= 0 && + Cond != CMP_INV && + (unsigned)Cond < sizeof (CmpSuffixTab) / sizeof (CmpSuffixTab[0])) { + return CmpSuffixTab[Cond]; + } else { + /* Not found */ + return 0; + } +} + + + +char* GetBoolCmpSuffix (char* Buf, cmp_t Cond) +/* Search for a boolean transformer subroutine (eg. booleq) by the given compare +** condition. +** Return the output buffer filled with the name of the correct subroutine or 0 +** on failure. +*/ +{ + /* Check for the correct boolean transformer subroutine name */ + const char* Suf = GetCmpSuffix (Cond); + + if (Suf != 0) { + sprintf (Buf, "bool%s", Suf); + return Buf; + } else { + /* Not found */ + return 0; + } +} + + + +char* GetTosCmpSuffix (char* Buf, cmp_t Cond) +/* Search for a TOS compare function (eg. tosgtax) by the given compare condition. +** Return the output buffer filled with the name of the correct function or 0 on +** failure. +*/ +{ + /* Check for the correct TOS function name */ + const char* Suf = GetCmpSuffix (Cond); + + if (Suf != 0) { + sprintf (Buf, "tos%sax", Suf); + return Buf; + } else { + /* Not found */ + return 0; + } +} + + + const char* GetBoolTransformer (cmp_t Cond) /* Get the bool transformer corresponding to the given compare condition */ { diff --git a/src/cc65/codeinfo.h b/src/cc65/codeinfo.h index 3dda3a6bc..763b947bf 100644 --- a/src/cc65/codeinfo.h +++ b/src/cc65/codeinfo.h @@ -197,7 +197,21 @@ cmp_t GetNegatedCond (cmp_t Cond); cmp_t GetRevertedCond (cmp_t Cond); /* Get the compare condition in reverted order of operands */ +const char* GetCmpSuffix (cmp_t Cond); +/* Return the compare suffix by the given a compare condition or 0 on failure */ +char* GetBoolCmpSuffix (char* Buf, cmp_t Cond); +/* Search for a boolean transformer subroutine (eg. booleq) by the given compare +** condition. +** Return the output buffer filled with the name of the correct subroutine or 0 +** on failure. +*/ + +char* GetTosCmpSuffix (char* Buf, cmp_t Cond); +/* Search for a TOS compare function (eg. tosgtax) by the given compare condition. +** Return the output buffer filled with the name of the correct function or 0 on +** failure. +*/ /* End of codeinfo.h */ From fe3f267233fe7651ae1c4acbb626ec626bd1c7a4 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 5 Sep 2020 11:28:38 +0800 Subject: [PATCH 1691/2161] Added new runtime sub bcasta/bcastax/bcasteax opposing to bnega/bnegax/bnegeax. --- libsrc/runtime/bcast.s | 21 +++++++++++++++++++++ libsrc/runtime/lbcast.s | 20 ++++++++++++++++++++ src/cc65/codeent.c | 4 +++- src/cc65/codeinfo.c | 3 +++ src/cc65/coptstop.c | 1 + 5 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 libsrc/runtime/bcast.s create mode 100644 libsrc/runtime/lbcast.s diff --git a/libsrc/runtime/bcast.s b/libsrc/runtime/bcast.s new file mode 100644 index 000000000..bb37b6ec0 --- /dev/null +++ b/libsrc/runtime/bcast.s @@ -0,0 +1,21 @@ +; +; acqn, 01.16.2020 +; +; CC65 runtime: boolean cast +; + + .export bcasta, bcastax + +bcastax: + cpx #0 + bne L1 + +bcasta: + tax + beq L0 ; Zero already in X + +L1: ldx #0 + lda #1 + +L0: rts + diff --git a/libsrc/runtime/lbcast.s b/libsrc/runtime/lbcast.s new file mode 100644 index 000000000..3dee8d956 --- /dev/null +++ b/libsrc/runtime/lbcast.s @@ -0,0 +1,20 @@ +; +; acqn, 01.16.2020 +; +; CC65 runtime: boolean cast for longs +; + + .export bcasteax + .importzp sreg, tmp1 + +bcasteax: + stx tmp1 + ldx #0 ; High byte of result + ora tmp1 + ora sreg + ora sreg+1 + beq L0 + + lda #1 +L0: rts + diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index 09ca0a9c5..0e3094962 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -851,7 +851,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) if ((In->RegA & 0x0F) >= 8) { Out->RegA = 0; } - } else if (FindBoolCmpCond (E->Arg) != CMP_INV || + } else if (strcmp (E->Arg, "bcastax") == 0 || + strcmp (E->Arg, "bnegax") == 0 || + FindBoolCmpCond (E->Arg) != CMP_INV || FindTosCmpCond (E->Arg) != CMP_INV) { /* Result is boolean value, so X is zero on output */ Out->RegX = 0; diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 24e27ee10..f51189293 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -107,6 +107,9 @@ static const FuncInfo FuncInfoTable[] = { { "asreax2", REG_EAX, REG_EAX | REG_TMP1 }, { "asreax3", REG_EAX, REG_EAX | REG_TMP1 }, { "asreax4", REG_EAX, REG_EAXY | REG_TMP1 }, + { "bcasta", REG_A, REG_AX }, + { "bcastax", REG_AX, REG_AX }, + { "bcasteax", REG_EAX, REG_EAX | REG_TMP1 }, { "bnega", REG_A, REG_AX }, { "bnegax", REG_AX, REG_AX }, { "bnegeax", REG_EAX, REG_EAX | REG_TMP1 }, diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index f4f34d163..34a9b88d6 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -2328,6 +2328,7 @@ static int HarmlessCall (const char* Name) "asrax3", "asrax4", "asraxy", + "bcastax", "bnegax", "complax", "decax1", From 66c5faeb9a5ddef4b1622679a971e8f7a0ee1090 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 8 Sep 2020 23:40:58 +0800 Subject: [PATCH 1692/2161] Added processor flags usage tracking. Added ZNRegs for tracking what register(s) Z/N flags currently reflect. Added utility functions to check if the specified processor state is known to be a certain value. --- src/cc65/codeent.c | 698 ++++++++++++++++++++++++++++++++++++++------ src/cc65/codeent.h | 4 +- src/cc65/codeinfo.c | 532 ++++++++++++++++----------------- src/cc65/codeinfo.h | 27 +- src/cc65/codeseg.c | 6 + src/cc65/coptsize.c | 584 ++++++++++++++++++------------------ src/cc65/coptstop.c | 8 +- src/cc65/reginfo.c | 50 ++++ src/cc65/reginfo.h | 118 ++++++++ 9 files changed, 1371 insertions(+), 656 deletions(-) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index 0e3094962..085130001 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -498,6 +498,228 @@ void CE_FreeRegInfo (CodeEntry* E) +static void DeduceZ (RegContents* C, short Val) +/* Auto-set Z flag */ +{ + if (RegValIsUnknown (Val)) { + C->PFlags |= UNKNOWN_PFVAL_Z; + } else { + C->PFlags &= ~UNKNOWN_PFVAL_Z; + if (Val == 0) { + C->PFlags |= PFVAL_Z; + } + } +} + + + +static void DeduceZN (RegContents* C, short Val) +/* Auto-set Z/N flags */ +{ + if (RegValIsUnknown (Val)) { + C->PFlags |= UNKNOWN_PFVAL_ZN; + } else { + C->PFlags &= ~UNKNOWN_PFVAL_ZN; + if (Val == 0) { + C->PFlags |= PFVAL_Z; + } else if (Val & PFVAL_N) { + C->PFlags |= PFVAL_N; + } + } +} + + + +static short KnownOpADCDeduceCZVN (RegContents* Out, RegContents* In, short Rhs) +/* Do the ADC and auto-set C/Z/V/N flags. +** Both operands and the C flag must be known. +*/ +{ + short SVal, UVal; + SVal = (signed char)(In->RegA & 0xFF) + (signed char)(Rhs & 0xFF); + UVal = (In->RegA & 0xFF) + (Rhs & 0xFF); + if (In->PFlags & PFVAL_C) { + ++SVal; + ++UVal; + } + + Out->PFlags &= ~UNKNOWN_PFVAL_CZVN; + if (UVal > 0xFF) { + Out->PFlags |= PFVAL_C; + } + + if (SVal < -128 || SVal > 127) { + Out->PFlags |= PFVAL_V; + } + + DeduceZN (Out, UVal); + + return UVal; +} + + + +static short KnownOpSBCDeduceCZVN (RegContents* Out, RegContents* In, short Rhs) +/* Do the SBC and auto-set C/Z/V/N flags. +** Both operands and the C flag must be known. +*/ +{ + short SVal, UVal; + SVal = (signed char)(In->RegA & 0xFF) - (signed char)(Rhs & 0xFF); + UVal = (In->RegA & 0xFF) - (Rhs & 0xFF); + if ((In->PFlags & PFVAL_C) == 0) { + --SVal; + --UVal; + } + + Out->PFlags &= ~UNKNOWN_PFVAL_CZVN; + if (UVal >= 0) { + Out->PFlags |= PFVAL_C; + } + + if (SVal < -128 || SVal > 127) { + Out->PFlags |= PFVAL_V; + } + + DeduceZN (Out, UVal); + + return UVal; +} + + + +static short KnownOpCmpDeduceCZN (RegContents* C, short Lhs, short Rhs) +/* Do the CMP and auto-set C/Z/N flags. +** Both operands must be known. + */ +{ + short Val = (Lhs & 0xFF) - (Rhs & 0xFF); + + C->PFlags &= ~UNKNOWN_PFVAL_C; + if (Val >= 0) { + C->PFlags |= PFVAL_C; + } + DeduceZN (C, Val); + + return Val; +} + + + +static short AnyOpASLDeduceCZN (RegContents* C, short Shiftee) +/* Do the ASL and auto-set C/Z/N flags */ +{ + if (RegValIsKnown (Shiftee)) { + C->PFlags &= ~UNKNOWN_PFVAL_C; + if (Shiftee & 0x80U) { + C->PFlags |= PFVAL_C; + } + Shiftee = (Shiftee << 1) & 0xFF; + } + DeduceZN (C, Shiftee); + + return Shiftee; +} + + + +static short AnyOpLSRDeduceCZN (RegContents* C, short Shiftee) +/* Do the LSR and auto-set C/Z/N flags */ +{ + if (RegValIsKnown (Shiftee)) { + C->PFlags &= ~UNKNOWN_PFVAL_C; + if (Shiftee & 0x01U) { + C->PFlags |= PFVAL_C; + } + Shiftee = (Shiftee >> 1) & 0xFF; + } + DeduceZN (C, Shiftee); + + return Shiftee; +} + + + +static short AnyOpROLDeduceCZN (RegContents* C, short PFlags, short Shiftee) +/* Do the ROL and auto-set C/Z/N flags */ +{ + if (RegValIsKnown (Shiftee) && PStatesAreKnown (PFlags, PSTATE_C)) { + C->PFlags &= ~UNKNOWN_PFVAL_C; + if (Shiftee & 0x80U) { + C->PFlags |= PFVAL_C; + } + Shiftee = (Shiftee << 1) & 0xFF; + if (PFlags & PFVAL_C) { + Shiftee |= 0x01U; + } + } else { + Shiftee = UNKNOWN_REGVAL; + } + DeduceZN (C, Shiftee); + + return Shiftee; +} + + + +static short AnyOpRORDeduceCZN (RegContents* C, short PFlags, short Shiftee) +/* Do the ROR and auto-set C/Z/N flags */ +{ + if (RegValIsKnown (Shiftee) && PStatesAreKnown (PFlags, PSTATE_C)) { + C->PFlags &= ~UNKNOWN_PFVAL_C; + if (Shiftee & 0x01U) { + C->PFlags |= PFVAL_C; + } + Shiftee = (Shiftee >> 1) & 0xFF; + if (PFlags & PFVAL_C) { + Shiftee |= 0x80U; + } + } else { + Shiftee = UNKNOWN_REGVAL; + } + DeduceZN (C, Shiftee); + + return Shiftee; +} + + + +static void BranchDeduceOnProcessorFlag (RegContents* True, RegContents* False, unsigned short PTrueFlag) +/* Auto-set the corresponding C/Z/V/N flag output for both True/Flase code flows */ +{ + PTrueFlag &= 0xFF; + unsigned short Mask = ~(PTrueFlag * 0x0101U) & 0xFFFFU; + True->PFlags &= Mask; + True->PFlags |= PTrueFlag; + False->PFlags &= Mask; +} + + + +static int MightAffectKnownZP (CodeEntry* E, RegContents* In) +/* TODO: This is supposed to check if any builtin ZP could be affected. +** It simply returns TRUE in most cases for now. +*/ +{ + unsigned Index = 0; + + if (E->AM == AM65_ZP || + E->AM == AM65_ABS || + (E->AM == AM65_ZPX && RegValIsKnown (In->RegX) && (Index = In->RegX & 0xFF)) || + (E->AM == AM65_ZPY && RegValIsKnown (In->RegY) && (Index = In->RegY & 0xFF)) || + (E->AM == AM65_ABSX && RegValIsKnown (In->RegX) && (Index = In->RegX & 0xFF)) || + (E->AM == AM65_ABSY && RegValIsKnown (In->RegY) && (Index = In->RegY & 0xFF))) { + return 1; + } else if ((E->AM == AM65_ZP_IND) || + (E->AM == AM65_ZPX_IND && RegValIsKnown (In->RegX) && (Index = In->RegX & 0xFF)) || + (E->AM == AM65_ZP_INDY && RegValIsKnown (In->RegY) && (Index = In->RegY & 0xFF))) { + return 1; + } + return 1; +} + + + void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) /* Generate register info for this instruction. If an old info exists, it is ** overwritten. @@ -506,9 +728,13 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) /* Pointers to the register contents */ RegContents* In; RegContents* Out; + RegContents* BranchOut; /* Function register usage */ - unsigned short Use, Chg; + unsigned Use, Chg; + + /* Value in question */ + short Val = UNKNOWN_REGVAL; /* If we don't have a register info struct, allocate one. */ if (E->RI == 0) { @@ -525,18 +751,46 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) /* Get pointers to the register contents */ In = &E->RI->In; Out = &E->RI->Out; + BranchOut = &E->RI->Out2; /* Handle the different instructions */ switch (E->OPC) { case OP65_ADC: - /* We don't know the value of the carry, so the result is - ** always unknown. - */ Out->RegA = UNKNOWN_REGVAL; + Out->PFlags |= UNKNOWN_PFVAL_CZVN; + Out->ZNRegs = ZNREG_A; + if (PStatesAreKnown (In->PFlags, PSTATE_C) && + RegValIsKnown (In->RegA)) { + if (CE_IsConstImm (E)) { + Out->RegA = KnownOpADCDeduceCZVN (Out, In, (short) E->Num); + } else if (E->AM == AM65_ZP) { + switch (GetKnownReg (E->Use & REG_ZP, In)) { + case REG_TMP1: + Out->RegA = KnownOpADCDeduceCZVN (Out, In, In->Tmp1); + break; + case REG_PTR1_LO: + Out->RegA = KnownOpADCDeduceCZVN (Out, In, In->Ptr1Lo); + break; + case REG_PTR1_HI: + Out->RegA = KnownOpADCDeduceCZVN (Out, In, In->Ptr1Hi); + break; + case REG_SREG_LO: + Out->RegA = KnownOpADCDeduceCZVN (Out, In, In->SRegLo); + break; + case REG_SREG_HI: + Out->RegA = KnownOpADCDeduceCZVN (Out, In, In->SRegHi); + break; + default: + break; + } + } + } break; case OP65_AND: + Out->RegA = UNKNOWN_REGVAL; + Out->ZNRegs = ZNREG_A; if (RegValIsKnown (In->RegA)) { if (CE_IsConstImm (E)) { Out->RegA = In->RegA & (short) E->Num; @@ -558,145 +812,289 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->RegA = In->RegA & In->SRegHi; break; default: - Out->RegA = UNKNOWN_REGVAL; break; } - } else { - Out->RegA = UNKNOWN_REGVAL; } } else if (CE_IsKnownImm (E, 0)) { /* A and $00 does always give zero */ Out->RegA = 0; } + DeduceZN (Out, Out->RegA); break; case OP65_ASL: - if (E->AM == AM65_ACC && RegValIsKnown (In->RegA)) { - Out->RegA = (In->RegA << 1) & 0xFF; + Out->PFlags |= UNKNOWN_PFVAL_CZN; + Out->ZNRegs = ZNREG_NONE; + if (E->AM == AM65_ACC) { + Out->RegA = AnyOpASLDeduceCZN (Out, In->RegA); + Out->ZNRegs = ZNREG_A; } else if (E->AM == AM65_ZP) { switch (GetKnownReg (E->Chg & REG_ZP, In)) { case REG_TMP1: - Out->Tmp1 = (In->Tmp1 << 1) & 0xFF; + Out->Tmp1 = AnyOpASLDeduceCZN (Out, In->Tmp1); + Out->ZNRegs = ZNREG_TMP1; break; case REG_PTR1_LO: - Out->Ptr1Lo = (In->Ptr1Lo << 1) & 0xFF; + Out->Ptr1Lo = AnyOpASLDeduceCZN (Out, In->Ptr1Lo); + Out->ZNRegs = ZNREG_PTR1_LO; break; case REG_PTR1_HI: - Out->Ptr1Hi = (In->Ptr1Hi << 1) & 0xFF; + Out->Ptr1Hi = AnyOpASLDeduceCZN (Out, In->Ptr1Hi); + Out->ZNRegs = ZNREG_PTR1_HI; break; case REG_SREG_LO: - Out->SRegLo = (In->SRegLo << 1) & 0xFF; + Out->SRegLo = AnyOpASLDeduceCZN (Out, In->SRegLo); + Out->ZNRegs = ZNREG_SREG_LO; break; case REG_SREG_HI: - Out->SRegHi = (In->SRegHi << 1) & 0xFF; + Out->SRegHi = AnyOpASLDeduceCZN (Out, In->SRegHi); + Out->ZNRegs = ZNREG_SREG_HI; break; } - } else if (E->AM == AM65_ZPX) { + } else if (MightAffectKnownZP (E, In)) { /* Invalidates all ZP registers */ RC_InvalidateZP (Out); } break; case OP65_BCC: + BranchDeduceOnProcessorFlag (Out, BranchOut, PFVAL_C); break; case OP65_BCS: + BranchDeduceOnProcessorFlag (BranchOut, Out, PFVAL_C); break; case OP65_BEQ: + BranchDeduceOnProcessorFlag (BranchOut, Out, PFVAL_Z); break; case OP65_BIT: + Out->ZNRegs = ZNREG_NONE; + if (E->AM == AM65_ZP) { + switch (GetKnownReg (E->Chg & REG_ZP, In)) { + case REG_TMP1: + Val = In->Tmp1; + break; + case REG_PTR1_LO: + Val = In->Ptr1Lo; + break; + case REG_PTR1_HI: + Val = In->Ptr1Hi; + break; + case REG_SREG_LO: + Val = In->SRegLo; + break; + case REG_SREG_HI: + Val = In->SRegHi; + break; + } + } + Out->PFlags &= ~UNKNOWN_PFVAL_V; + if (Val & PFVAL_V) { + Out->PFlags |= PFVAL_V; + } + DeduceZN (Out, Val); break; case OP65_BMI: + BranchDeduceOnProcessorFlag (BranchOut, Out, PFVAL_N); break; case OP65_BNE: + BranchDeduceOnProcessorFlag (Out, BranchOut, PFVAL_Z); break; case OP65_BPL: + BranchDeduceOnProcessorFlag (Out, BranchOut, PFVAL_N); break; case OP65_BRA: break; case OP65_BRK: + Out->PFlags &= ~UNKNOWN_PFVAL_B; + Out->PFlags |= PFVAL_B; break; case OP65_BVC: + BranchDeduceOnProcessorFlag (Out, BranchOut, PFVAL_V); break; case OP65_BVS: + BranchDeduceOnProcessorFlag (BranchOut, Out, PFVAL_V); break; case OP65_CLC: + Out->PFlags &= ~UNKNOWN_PFVAL_C; break; case OP65_CLD: + Out->PFlags &= ~UNKNOWN_PFVAL_D; break; case OP65_CLI: + Out->PFlags &= ~UNKNOWN_PFVAL_I; break; case OP65_CLV: + Out->PFlags &= ~UNKNOWN_PFVAL_V; break; case OP65_CMP: + Out->PFlags |= UNKNOWN_PFVAL_CZN; + Out->ZNRegs = ZNREG_NONE; + if (RegValIsKnown (In->RegA)) { + if (CE_IsConstImm (E)) { + KnownOpCmpDeduceCZN (Out, In->RegA, (short)E->Num); + } else if (E->AM == AM65_ZP) { + switch (GetKnownReg (E->Use & REG_ZP, In)) { + case REG_TMP1: + KnownOpCmpDeduceCZN (Out, In->RegA, In->Tmp1); + break; + case REG_PTR1_LO: + KnownOpCmpDeduceCZN (Out, In->RegA, In->Ptr1Lo); + break; + case REG_PTR1_HI: + KnownOpCmpDeduceCZN (Out, In->RegA, In->Ptr1Hi); + break; + case REG_SREG_LO: + KnownOpCmpDeduceCZN (Out, In->RegA, In->SRegLo); + break; + case REG_SREG_HI: + KnownOpCmpDeduceCZN (Out, In->RegA, In->SRegHi); + break; + default: + break; + } + } + } break; case OP65_CPX: + Out->PFlags |= UNKNOWN_PFVAL_CZN; + Out->ZNRegs = ZNREG_NONE; + if (RegValIsKnown (In->RegX)) { + if (CE_IsConstImm (E)) { + KnownOpCmpDeduceCZN (Out, In->RegX, (short)E->Num); + } else if (E->AM == AM65_ZP) { + switch (GetKnownReg (E->Use & REG_ZP, In)) { + case REG_TMP1: + KnownOpCmpDeduceCZN (Out, In->RegX, In->Tmp1); + break; + case REG_PTR1_LO: + KnownOpCmpDeduceCZN (Out, In->RegX, In->Ptr1Lo); + break; + case REG_PTR1_HI: + KnownOpCmpDeduceCZN (Out, In->RegX, In->Ptr1Hi); + break; + case REG_SREG_LO: + KnownOpCmpDeduceCZN (Out, In->RegX, In->SRegLo); + break; + case REG_SREG_HI: + KnownOpCmpDeduceCZN (Out, In->RegX, In->SRegHi); + break; + default: + break; + } + } + } break; case OP65_CPY: + Out->PFlags |= UNKNOWN_PFVAL_CZN; + Out->ZNRegs = ZNREG_NONE; + if (RegValIsKnown (In->RegY)) { + if (CE_IsConstImm (E)) { + KnownOpCmpDeduceCZN (Out, In->RegY, (short)E->Num); + } else if (E->AM == AM65_ZP) { + switch (GetKnownReg (E->Use & REG_ZP, In)) { + case REG_TMP1: + KnownOpCmpDeduceCZN (Out, In->RegY, In->Tmp1); + break; + case REG_PTR1_LO: + KnownOpCmpDeduceCZN (Out, In->RegY, In->Ptr1Lo); + break; + case REG_PTR1_HI: + KnownOpCmpDeduceCZN (Out, In->RegY, In->Ptr1Hi); + break; + case REG_SREG_LO: + KnownOpCmpDeduceCZN (Out, In->RegY, In->SRegLo); + break; + case REG_SREG_HI: + KnownOpCmpDeduceCZN (Out, In->RegY, In->SRegHi); + break; + default: + break; + } + } + } break; case OP65_DEA: + Out->ZNRegs = ZNREG_A; if (RegValIsKnown (In->RegA)) { Out->RegA = (In->RegA - 1) & 0xFF; } + DeduceZN (Out, Out->RegA); break; case OP65_DEC: - if (E->AM == AM65_ACC && RegValIsKnown (In->RegA)) { - Out->RegA = (In->RegA - 1) & 0xFF; + Out->ZNRegs = ZNREG_NONE; + if (E->AM == AM65_ACC) { + if (RegValIsKnown (In->RegA)) { + Val = Out->RegA = (In->RegA - 1) & 0xFF; + } + Out->ZNRegs = ZNREG_A; } else if (E->AM == AM65_ZP) { switch (GetKnownReg (E->Chg & REG_ZP, In)) { case REG_TMP1: - Out->Tmp1 = (In->Tmp1 - 1) & 0xFF; + Val = Out->Tmp1 = (In->Tmp1 - 1) & 0xFF; + Out->ZNRegs = ZNREG_TMP1; break; case REG_PTR1_LO: - Out->Ptr1Lo = (In->Ptr1Lo - 1) & 0xFF; + Val = Out->Ptr1Lo = (In->Ptr1Lo - 1) & 0xFF; + Out->ZNRegs = ZNREG_PTR1_LO; break; case REG_PTR1_HI: - Out->Ptr1Hi = (In->Ptr1Hi - 1) & 0xFF; + Val = Out->Ptr1Hi = (In->Ptr1Hi - 1) & 0xFF; + Out->ZNRegs = ZNREG_PTR1_HI; break; case REG_SREG_LO: - Out->SRegLo = (In->SRegLo - 1) & 0xFF; + Val = Out->SRegLo = (In->SRegLo - 1) & 0xFF; + Out->ZNRegs = ZNREG_SREG_LO; break; case REG_SREG_HI: - Out->SRegHi = (In->SRegHi - 1) & 0xFF; + Val = Out->SRegHi = (In->SRegHi - 1) & 0xFF; + Out->ZNRegs = ZNREG_SREG_HI; break; } - } else if (E->AM == AM65_ZPX) { + } else if (MightAffectKnownZP (E, In)) { /* Invalidates all ZP registers */ RC_InvalidateZP (Out); } + DeduceZN (Out, Val); break; case OP65_DEX: + Out->ZNRegs = ZNREG_X; if (RegValIsKnown (In->RegX)) { Out->RegX = (In->RegX - 1) & 0xFF; } + DeduceZN (Out, Out->RegX); break; case OP65_DEY: + Out->ZNRegs = ZNREG_Y; if (RegValIsKnown (In->RegY)) { Out->RegY = (In->RegY - 1) & 0xFF; } + DeduceZN (Out, Out->RegY); break; case OP65_EOR: + Out->RegA = UNKNOWN_REGVAL; + Out->ZNRegs = ZNREG_A; if (RegValIsKnown (In->RegA)) { if (CE_IsConstImm (E)) { Out->RegA = In->RegA ^ (short) E->Num; @@ -718,82 +1116,104 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->RegA = In->RegA ^ In->SRegHi; break; default: - Out->RegA = UNKNOWN_REGVAL; break; } - } else { - Out->RegA = UNKNOWN_REGVAL; } } + DeduceZN (Out, Out->RegA); break; case OP65_INA: + Out->ZNRegs = ZNREG_A; if (RegValIsKnown (In->RegA)) { Out->RegA = (In->RegA + 1) & 0xFF; } + DeduceZN (Out, Out->RegA); break; case OP65_INC: - if (E->AM == AM65_ACC && RegValIsKnown (In->RegA)) { - Out->RegA = (In->RegA + 1) & 0xFF; + Out->ZNRegs = ZNREG_NONE; + if (E->AM == AM65_ACC) { + if (RegValIsKnown (In->RegA)) { + Val = Out->RegA = (In->RegA + 1) & 0xFF; + } + Out->ZNRegs = ZNREG_A; } else if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Chg & REG_ZP, In)) { + switch (GetKnownReg (E->Chg & REG_ZP, 0)) { case REG_TMP1: - Out->Tmp1 = (In->Tmp1 + 1) & 0xFF; + Val = Out->Tmp1 = (In->Tmp1 + 1) & 0xFF; + Out->ZNRegs = ZNREG_TMP1; break; case REG_PTR1_LO: - Out->Ptr1Lo = (In->Ptr1Lo + 1) & 0xFF; + Val = Out->Ptr1Lo = (In->Ptr1Lo + 1) & 0xFF; + Out->ZNRegs = ZNREG_PTR1_LO; break; case REG_PTR1_HI: - Out->Ptr1Hi = (In->Ptr1Hi + 1) & 0xFF; + Val = Out->Ptr1Hi = (In->Ptr1Hi + 1) & 0xFF; + Out->ZNRegs = ZNREG_PTR1_HI; break; case REG_SREG_LO: - Out->SRegLo = (In->SRegLo + 1) & 0xFF; + Val = Out->SRegLo = (In->SRegLo + 1) & 0xFF; + Out->ZNRegs = ZNREG_SREG_LO; break; case REG_SREG_HI: - Out->SRegHi = (In->SRegHi + 1) & 0xFF; + Val = Out->SRegHi = (In->SRegHi + 1) & 0xFF; + Out->ZNRegs = ZNREG_SREG_HI; break; } - } else if (E->AM == AM65_ZPX) { + } else if (MightAffectKnownZP (E, In)) { /* Invalidates all ZP registers */ RC_InvalidateZP (Out); } + DeduceZN (Out, Val); break; case OP65_INX: + Out->ZNRegs = ZNREG_X; if (RegValIsKnown (In->RegX)) { Out->RegX = (In->RegX + 1) & 0xFF; } + DeduceZN (Out, Out->RegX); break; case OP65_INY: + Out->ZNRegs = ZNREG_Y; if (RegValIsKnown (In->RegY)) { Out->RegY = (In->RegY + 1) & 0xFF; } + DeduceZN (Out, Out->RegY); break; case OP65_JCC: + BranchDeduceOnProcessorFlag (Out, BranchOut, PFVAL_C); break; case OP65_JCS: + BranchDeduceOnProcessorFlag (BranchOut, Out, PFVAL_C); break; case OP65_JEQ: + BranchDeduceOnProcessorFlag (BranchOut, Out, PFVAL_Z); break; case OP65_JMI: + BranchDeduceOnProcessorFlag (BranchOut, Out, PFVAL_N); break; case OP65_JMP: break; case OP65_JNE: + BranchDeduceOnProcessorFlag (Out, BranchOut, PFVAL_Z); break; case OP65_JPL: + BranchDeduceOnProcessorFlag (Out, BranchOut, PFVAL_N); break; case OP65_JSR: + Out->ZNRegs = ZNREG_NONE; + /* Get the code info for the function */ GetFuncInfo (E->Arg, &Use, &Chg); if (Chg & REG_A) { @@ -820,6 +1240,9 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) if (Chg & REG_SREG_HI) { Out->SRegHi = UNKNOWN_REGVAL; } + /* FIXME: Quick hack to set flags on process status: */ + Out->PFlags |= ((Chg & PSTATE_ALL) >> PSTATE_BITS_SHIFT) * 0x0101U; + /* ## FIXME: Quick hack for some known functions: */ if (strcmp (E->Arg, "complax") == 0) { if (RegValIsKnown (In->RegA)) { @@ -861,12 +1284,16 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; case OP65_JVC: + BranchDeduceOnProcessorFlag (Out, BranchOut, PFVAL_V); break; case OP65_JVS: + BranchDeduceOnProcessorFlag (BranchOut, Out, PFVAL_V); break; case OP65_LDA: + Out->RegA = UNKNOWN_REGVAL; + Out->ZNRegs = ZNREG_A; if (CE_IsConstImm (E)) { Out->RegA = (unsigned char) E->Num; } else if (E->AM == AM65_ZP) { @@ -887,16 +1314,15 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->RegA = In->SRegHi; break; default: - Out->RegA = UNKNOWN_REGVAL; break; } - } else { - /* A is now unknown */ - Out->RegA = UNKNOWN_REGVAL; } + DeduceZN (Out, Out->RegA); break; case OP65_LDX: + Out->RegX = UNKNOWN_REGVAL; + Out->ZNRegs = ZNREG_X; if (CE_IsConstImm (E)) { Out->RegX = (unsigned char) E->Num; } else if (E->AM == AM65_ZP) { @@ -917,16 +1343,15 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->RegX = In->SRegHi; break; default: - Out->RegX = UNKNOWN_REGVAL; break; } - } else { - /* X is now unknown */ - Out->RegX = UNKNOWN_REGVAL; } + DeduceZN (Out, Out->RegX); break; case OP65_LDY: + Out->RegY = UNKNOWN_REGVAL; + Out->ZNRegs = ZNREG_Y; if (CE_IsConstImm (E)) { Out->RegY = (unsigned char) E->Num; } else if (E->AM == AM65_ZP) { @@ -947,37 +1372,42 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->RegY = In->SRegHi; break; default: - Out->RegY = UNKNOWN_REGVAL; break; } - } else { - /* Y is now unknown */ - Out->RegY = UNKNOWN_REGVAL; } + DeduceZN (Out, Out->RegY); break; case OP65_LSR: - if (E->AM == AM65_ACC && RegValIsKnown (In->RegA)) { - Out->RegA = (In->RegA >> 1) & 0xFF; + Out->PFlags |= UNKNOWN_PFVAL_CZN; + Out->ZNRegs = ZNREG_NONE; + if (E->AM == AM65_ACC) { + Out->RegA = AnyOpLSRDeduceCZN (Out, In->RegA); + Out->ZNRegs = ZNREG_A; } else if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Chg & REG_ZP, In)) { + switch (GetKnownReg (E->Chg & REG_ZP, 0)) { case REG_TMP1: - Out->Tmp1 = (In->Tmp1 >> 1) & 0xFF; + Out->Tmp1 = AnyOpLSRDeduceCZN (Out, In->Tmp1); + Out->ZNRegs = ZNREG_TMP1; break; case REG_PTR1_LO: - Out->Ptr1Lo = (In->Ptr1Lo >> 1) & 0xFF; + Out->Ptr1Lo = AnyOpLSRDeduceCZN (Out, In->Ptr1Lo); + Out->ZNRegs = ZNREG_PTR1_LO; break; case REG_PTR1_HI: - Out->Ptr1Hi = (In->Ptr1Hi >> 1) & 0xFF; + Out->Ptr1Hi = AnyOpLSRDeduceCZN (Out, In->Ptr1Hi); + Out->ZNRegs = ZNREG_PTR1_HI; break; case REG_SREG_LO: - Out->SRegLo = (In->SRegLo >> 1) & 0xFF; + Out->SRegLo = AnyOpLSRDeduceCZN (Out, In->SRegLo); + Out->ZNRegs = ZNREG_SREG_LO; break; case REG_SREG_HI: - Out->SRegHi = (In->SRegHi >> 1) & 0xFF; + Out->SRegHi = AnyOpLSRDeduceCZN (Out, In->SRegHi); + Out->ZNRegs = ZNREG_SREG_HI; break; } - } else if (E->AM == AM65_ZPX) { + } else if (MightAffectKnownZP (E, In)) { /* Invalidates all ZP registers */ RC_InvalidateZP (Out); } @@ -987,6 +1417,8 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; case OP65_ORA: + Out->RegA = UNKNOWN_REGVAL; + Out->ZNRegs = ZNREG_A; if (RegValIsKnown (In->RegA)) { if (CE_IsConstImm (E)) { Out->RegA = In->RegA | (short) E->Num; @@ -1008,17 +1440,14 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->RegA = In->RegA | In->SRegHi; break; default: - Out->RegA = UNKNOWN_REGVAL; break; } - } else { - /* A is now unknown */ - Out->RegA = UNKNOWN_REGVAL; } } else if (CE_IsKnownImm (E, 0xFF)) { /* ORA with 0xFF does always give 0xFF */ Out->RegA = 0xFF; } + DeduceZN (Out, Out->RegA); break; case OP65_PHA: @@ -1035,93 +1464,150 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) case OP65_PLA: Out->RegA = UNKNOWN_REGVAL; + Out->PFlags |= UNKNOWN_PFVAL_ZN; + Out->ZNRegs = ZNREG_A; break; case OP65_PLP: + Out->PFlags = UNKNOWN_PFVAL_ALL; + Out->ZNRegs = ZNREG_NONE; break; case OP65_PLX: Out->RegX = UNKNOWN_REGVAL; + Out->PFlags |= UNKNOWN_PFVAL_ZN; + Out->ZNRegs = ZNREG_X; break; case OP65_PLY: Out->RegY = UNKNOWN_REGVAL; + Out->PFlags |= UNKNOWN_PFVAL_ZN; + Out->ZNRegs = ZNREG_Y; break; case OP65_ROL: - /* We don't know the value of the carry bit */ + Out->PFlags |= UNKNOWN_PFVAL_CZN; + Out->ZNRegs = ZNREG_NONE; if (E->AM == AM65_ACC) { - Out->RegA = UNKNOWN_REGVAL; + Out->RegA = AnyOpROLDeduceCZN (Out, In->PFlags, In->RegA); + Out->ZNRegs = ZNREG_A; } else if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Chg & REG_ZP, In)) { + switch (GetKnownReg (E->Chg & REG_ZP, 0)) { case REG_TMP1: - Out->Tmp1 = UNKNOWN_REGVAL; + Out->Tmp1 = AnyOpROLDeduceCZN (Out, In->PFlags, In->Tmp1); + Out->ZNRegs = ZNREG_TMP1; break; case REG_PTR1_LO: - Out->Ptr1Lo = UNKNOWN_REGVAL; + Out->Ptr1Lo = AnyOpROLDeduceCZN (Out, In->PFlags, In->Ptr1Lo); + Out->ZNRegs = ZNREG_PTR1_LO; break; case REG_PTR1_HI: - Out->Ptr1Hi = UNKNOWN_REGVAL; + Out->Ptr1Hi = AnyOpROLDeduceCZN (Out, In->PFlags, In->Ptr1Hi); + Out->ZNRegs = ZNREG_PTR1_HI; break; case REG_SREG_LO: - Out->SRegLo = UNKNOWN_REGVAL; + Out->SRegLo = AnyOpROLDeduceCZN (Out, In->PFlags, In->SRegLo); + Out->ZNRegs = ZNREG_SREG_LO; break; case REG_SREG_HI: - Out->SRegHi = UNKNOWN_REGVAL; + Out->SRegHi = AnyOpROLDeduceCZN (Out, In->PFlags, In->SRegHi); + Out->ZNRegs = ZNREG_SREG_HI; break; } - } else if (E->AM == AM65_ZPX) { + } else if (MightAffectKnownZP (E, In)) { /* Invalidates all ZP registers */ RC_InvalidateZP (Out); } break; case OP65_ROR: - /* We don't know the value of the carry bit */ + Out->PFlags |= UNKNOWN_PFVAL_CZN; + Out->ZNRegs = ZNREG_NONE; if (E->AM == AM65_ACC) { - Out->RegA = UNKNOWN_REGVAL; + Out->RegA = AnyOpRORDeduceCZN (Out, In->PFlags, In->RegA); + Out->ZNRegs = ZNREG_A; } else if (E->AM == AM65_ZP) { - switch (GetKnownReg (E->Chg & REG_ZP, In)) { + switch (GetKnownReg (E->Chg & REG_ZP, 0)) { case REG_TMP1: - Out->Tmp1 = UNKNOWN_REGVAL; + Out->Tmp1 = AnyOpRORDeduceCZN (Out, In->PFlags, In->Tmp1); + Out->ZNRegs = ZNREG_TMP1; break; case REG_PTR1_LO: - Out->Ptr1Lo = UNKNOWN_REGVAL; + Out->Ptr1Lo = AnyOpRORDeduceCZN (Out, In->PFlags, In->Ptr1Lo); + Out->ZNRegs = ZNREG_PTR1_LO; break; case REG_PTR1_HI: - Out->Ptr1Hi = UNKNOWN_REGVAL; + Out->Ptr1Hi = AnyOpRORDeduceCZN (Out, In->PFlags, In->Ptr1Hi); + Out->ZNRegs = ZNREG_PTR1_HI; break; case REG_SREG_LO: - Out->SRegLo = UNKNOWN_REGVAL; + Out->SRegLo = AnyOpRORDeduceCZN (Out, In->PFlags, In->SRegLo); + Out->ZNRegs = ZNREG_SREG_LO; break; case REG_SREG_HI: - Out->SRegHi = UNKNOWN_REGVAL; + Out->SRegHi = AnyOpRORDeduceCZN (Out, In->PFlags, In->SRegHi); + Out->ZNRegs = ZNREG_SREG_HI; break; } - } else if (E->AM == AM65_ZPX) { + } else if (MightAffectKnownZP (E, In)) { /* Invalidates all ZP registers */ RC_InvalidateZP (Out); } break; case OP65_RTI: + Out->PFlags |= UNKNOWN_PFVAL_ALL; break; case OP65_RTS: break; case OP65_SBC: - /* We don't know the value of the carry bit */ Out->RegA = UNKNOWN_REGVAL; + Out->PFlags |= UNKNOWN_PFVAL_CZVN; + Out->ZNRegs = ZNREG_A; + if (PStatesAreKnown (In->PFlags, PSTATE_C) && + RegValIsKnown (In->RegA)) { + if (CE_IsConstImm (E)) { + Out->RegA = KnownOpSBCDeduceCZVN (Out, In, (short) E->Num); + } + else if (E->AM == AM65_ZP) { + switch (GetKnownReg(E->Use & REG_ZP, In)) { + case REG_TMP1: + Out->RegA = KnownOpSBCDeduceCZVN (Out, In, In->Tmp1); + break; + case REG_PTR1_LO: + Out->RegA = KnownOpSBCDeduceCZVN (Out, In, In->Ptr1Lo); + break; + case REG_PTR1_HI: + Out->RegA = KnownOpSBCDeduceCZVN (Out, In, In->Ptr1Hi); + break; + case REG_SREG_LO: + Out->RegA = KnownOpSBCDeduceCZVN (Out, In, In->SRegLo); + break; + case REG_SREG_HI: + Out->RegA = KnownOpSBCDeduceCZVN (Out, In, In->SRegHi); + break; + default: + break; + } + } + } break; case OP65_SEC: + Out->PFlags &= ~UNKNOWN_PFVAL_C; + Out->PFlags |= PFVAL_C; break; case OP65_SED: + Out->PFlags &= ~UNKNOWN_PFVAL_D; + Out->PFlags |= PFVAL_D; break; case OP65_SEI: + Out->PFlags &= ~UNKNOWN_PFVAL_I; + Out->PFlags |= PFVAL_I; break; case OP65_STA: @@ -1143,7 +1629,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->SRegHi = In->RegA; break; } - } else if (E->AM == AM65_ZPX) { + } else if (MightAffectKnownZP (E, In)) { /* Invalidates all ZP registers */ RC_InvalidateZP (Out); } @@ -1171,7 +1657,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->SRegHi = In->RegX; break; } - } else if (E->AM == AM65_ZPX) { + } else if (MightAffectKnownZP (E, In)) { /* Invalidates all ZP registers */ RC_InvalidateZP (Out); } @@ -1196,7 +1682,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->SRegHi = In->RegY; break; } - } else if (E->AM == AM65_ZPX) { + } else if (MightAffectKnownZP (E, In)) { /* Invalidates all ZP registers */ RC_InvalidateZP (Out); } @@ -1221,7 +1707,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->SRegHi = 0; break; } - } else if (E->AM == AM65_ZPX) { + } else if (MightAffectKnownZP (E, In)) { /* Invalidates all ZP registers */ RC_InvalidateZP (Out); } @@ -1229,37 +1715,44 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) case OP65_TAX: Out->RegX = In->RegA; + Out->ZNRegs = ZNREG_AX; + DeduceZN (Out, Out->RegX); break; case OP65_TAY: Out->RegY = In->RegA; + Out->ZNRegs = ZNREG_AY; + DeduceZN (Out, Out->RegY); break; case OP65_TRB: - if (E->AM == AM65_ZPX) { - /* Invalidates all ZP registers */ - RC_InvalidateZP (Out); - } else if (E->AM == AM65_ZP) { + Out->ZNRegs = ZNREG_NONE; + if (E->AM == AM65_ZP) { if (RegValIsKnown (In->RegA)) { switch (GetKnownReg (E->Chg & REG_ZP, In)) { case REG_TMP1: + Val = Out->Tmp1 & In->RegA; Out->Tmp1 &= ~In->RegA; break; case REG_PTR1_LO: + Val = Out->Ptr1Lo & In->RegA; Out->Ptr1Lo &= ~In->RegA; break; case REG_PTR1_HI: + Val = Out->Ptr1Hi & In->RegA; Out->Ptr1Hi &= ~In->RegA; break; case REG_SREG_LO: + Val = Out->SRegLo & In->RegA; Out->SRegLo &= ~In->RegA; break; case REG_SREG_HI: + Val = Out->SRegHi & In->RegA; Out->SRegHi &= ~In->RegA; break; } } else { - switch (GetKnownReg (E->Chg & REG_ZP, In)) { + switch (GetKnownReg (E->Chg & REG_ZP, 0)) { case REG_TMP1: Out->Tmp1 = UNKNOWN_REGVAL; break; @@ -1277,34 +1770,41 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; } } + } else if (MightAffectKnownZP (E, In)) { + /* Invalidates all ZP registers */ + RC_InvalidateZP (Out); } + DeduceZ (Out, Val); break; case OP65_TSB: - if (E->AM == AM65_ZPX) { - /* Invalidates all ZP registers */ - RC_InvalidateZP (Out); - } else if (E->AM == AM65_ZP) { + Out->ZNRegs = ZNREG_NONE; + if (E->AM == AM65_ZP) { if (RegValIsKnown (In->RegA)) { switch (GetKnownReg (E->Chg & REG_ZP, In)) { case REG_TMP1: + Val = Out->Tmp1 & In->RegA; Out->Tmp1 |= In->RegA; break; case REG_PTR1_LO: + Val = Out->Ptr1Lo & In->RegA; Out->Ptr1Lo |= In->RegA; break; case REG_PTR1_HI: + Val = Out->Ptr1Hi & In->RegA; Out->Ptr1Hi |= In->RegA; break; case REG_SREG_LO: + Val = Out->SRegLo & In->RegA; Out->SRegLo |= In->RegA; break; case REG_SREG_HI: + Val = Out->SRegHi & In->RegA; Out->SRegHi |= In->RegA; break; } } else { - switch (GetKnownReg (E->Chg & REG_ZP, In)) { + switch (GetKnownReg (E->Chg & REG_ZP, 0)) { case REG_TMP1: Out->Tmp1 = UNKNOWN_REGVAL; break; @@ -1322,22 +1822,34 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) break; } } + } else if (MightAffectKnownZP (E, In)) { + /* Invalidates all ZP registers */ + RC_InvalidateZP (Out); } + DeduceZ (Out, Val); break; case OP65_TSX: Out->RegX = UNKNOWN_REGVAL; + Out->PFlags |= UNKNOWN_PFVAL_ZN; + Out->ZNRegs = ZNREG_X; break; case OP65_TXA: Out->RegA = In->RegX; + Out->ZNRegs = ZNREG_AX; + DeduceZN (Out, Out->RegA); break; case OP65_TXS: + Out->ZNRegs = ZNREG_X; + DeduceZN (Out, In->RegX); break; case OP65_TYA: Out->RegA = In->RegY; + Out->ZNRegs = ZNREG_AY; + DeduceZN (Out, Out->RegA); break; default: diff --git a/src/cc65/codeent.h b/src/cc65/codeent.h index 96373a8f9..3d07670d7 100644 --- a/src/cc65/codeent.h +++ b/src/cc65/codeent.h @@ -73,8 +73,8 @@ struct CodeEntry { char* Arg; /* Argument as string */ unsigned long Num; /* Numeric argument */ unsigned short Info; /* Additional code info */ - unsigned short Use; /* Registers used */ - unsigned short Chg; /* Registers changed/destroyed */ + unsigned int Use; /* Registers used */ + unsigned int Chg; /* Registers changed/destroyed */ CodeLabel* JumpTo; /* Jump label */ Collection Labels; /* Labels for this instruction */ LineInfo* LI; /* Source line info for this insn */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index f51189293..892f4cd5f 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -77,8 +77,8 @@ static const char BoolTransformerTab [][8] = { typedef struct FuncInfo FuncInfo; struct FuncInfo { const char* Name; /* Function name */ - unsigned short Use; /* Register usage */ - unsigned short Chg; /* Changed/destroyed registers */ + unsigned Use; /* Register usage */ + unsigned Chg; /* Changed/destroyed registers */ }; /* Note for the shift functions: Shifts are done modulo 32, so all shift @@ -86,264 +86,264 @@ struct FuncInfo { ** anyway. */ static const FuncInfo FuncInfoTable[] = { - { "addeq0sp", REG_AX, REG_AXY }, - { "addeqysp", REG_AXY, REG_AXY }, - { "addysp", REG_Y, REG_NONE }, - { "aslax1", REG_AX, REG_AX | REG_TMP1 }, - { "aslax2", REG_AX, REG_AX | REG_TMP1 }, - { "aslax3", REG_AX, REG_AX | REG_TMP1 }, - { "aslax4", REG_AX, REG_AX | REG_TMP1 }, - { "aslaxy", REG_AXY, REG_AXY | REG_TMP1 }, - { "asleax1", REG_EAX, REG_EAX | REG_TMP1 }, - { "asleax2", REG_EAX, REG_EAX | REG_TMP1 }, - { "asleax3", REG_EAX, REG_EAX | REG_TMP1 }, - { "asleax4", REG_EAX, REG_EAXY | REG_TMP1 }, - { "asrax1", REG_AX, REG_AX | REG_TMP1 }, - { "asrax2", REG_AX, REG_AX | REG_TMP1 }, - { "asrax3", REG_AX, REG_AX | REG_TMP1 }, - { "asrax4", REG_AX, REG_AX | REG_TMP1 }, - { "asraxy", REG_AXY, REG_AXY | REG_TMP1 }, - { "asreax1", REG_EAX, REG_EAX | REG_TMP1 }, - { "asreax2", REG_EAX, REG_EAX | REG_TMP1 }, - { "asreax3", REG_EAX, REG_EAX | REG_TMP1 }, - { "asreax4", REG_EAX, REG_EAXY | REG_TMP1 }, - { "bcasta", REG_A, REG_AX }, - { "bcastax", REG_AX, REG_AX }, - { "bcasteax", REG_EAX, REG_EAX | REG_TMP1 }, - { "bnega", REG_A, REG_AX }, - { "bnegax", REG_AX, REG_AX }, - { "bnegeax", REG_EAX, REG_EAX | REG_TMP1 }, - { "booleq", REG_NONE, REG_AX }, - { "boolge", REG_NONE, REG_AX }, - { "boolgt", REG_NONE, REG_AX }, - { "boolle", REG_NONE, REG_AX }, - { "boollt", REG_NONE, REG_AX }, - { "boolne", REG_NONE, REG_AX }, - { "booluge", REG_NONE, REG_AX }, - { "boolugt", REG_NONE, REG_AX }, - { "boolule", REG_NONE, REG_AX }, - { "boolult", REG_NONE, REG_AX }, - { "callax", REG_AX, REG_ALL }, - { "complax", REG_AX, REG_AX }, - { "decax1", REG_AX, REG_AX }, - { "decax2", REG_AX, REG_AX }, - { "decax3", REG_AX, REG_AX }, - { "decax4", REG_AX, REG_AX }, - { "decax5", REG_AX, REG_AX }, - { "decax6", REG_AX, REG_AX }, - { "decax7", REG_AX, REG_AX }, - { "decax8", REG_AX, REG_AX }, - { "decaxy", REG_AXY, REG_AX | REG_TMP1 }, - { "deceaxy", REG_EAXY, REG_EAX }, - { "decsp1", REG_NONE, REG_Y }, - { "decsp2", REG_NONE, REG_A }, - { "decsp3", REG_NONE, REG_A }, - { "decsp4", REG_NONE, REG_A }, - { "decsp5", REG_NONE, REG_A }, - { "decsp6", REG_NONE, REG_A }, - { "decsp7", REG_NONE, REG_A }, - { "decsp8", REG_NONE, REG_A }, - { "incax1", REG_AX, REG_AX }, - { "incax2", REG_AX, REG_AX }, - { "incax3", REG_AX, REG_AXY | REG_TMP1 }, - { "incax4", REG_AX, REG_AXY | REG_TMP1 }, - { "incax5", REG_AX, REG_AXY | REG_TMP1 }, - { "incax6", REG_AX, REG_AXY | REG_TMP1 }, - { "incax7", REG_AX, REG_AXY | REG_TMP1 }, - { "incax8", REG_AX, REG_AXY | REG_TMP1 }, - { "incaxy", REG_AXY, REG_AXY | REG_TMP1 }, - { "incsp1", REG_NONE, REG_NONE }, - { "incsp2", REG_NONE, REG_Y }, - { "incsp3", REG_NONE, REG_Y }, - { "incsp4", REG_NONE, REG_Y }, - { "incsp5", REG_NONE, REG_Y }, - { "incsp6", REG_NONE, REG_Y }, - { "incsp7", REG_NONE, REG_Y }, - { "incsp8", REG_NONE, REG_Y }, - { "laddeq", REG_EAXY|REG_PTR1_LO, REG_EAXY | REG_PTR1_HI }, - { "laddeq0sp", REG_EAX, REG_EAXY }, - { "laddeq1", REG_Y | REG_PTR1_LO, REG_EAXY | REG_PTR1_HI }, - { "laddeqa", REG_AY | REG_PTR1_LO, REG_EAXY | REG_PTR1_HI }, - { "laddeqysp", REG_EAXY, REG_EAXY }, - { "ldaidx", REG_AXY, REG_AX | REG_PTR1 }, - { "ldauidx", REG_AXY, REG_AX | REG_PTR1 }, - { "ldax0sp", REG_NONE, REG_AXY }, - { "ldaxi", REG_AX, REG_AXY | REG_PTR1 }, - { "ldaxidx", REG_AXY, REG_AXY | REG_PTR1 }, - { "ldaxysp", REG_Y, REG_AXY }, - { "ldeax0sp", REG_NONE, REG_EAXY }, - { "ldeaxi", REG_AX, REG_EAXY | REG_PTR1 }, - { "ldeaxidx", REG_AXY, REG_EAXY | REG_PTR1 }, - { "ldeaxysp", REG_Y, REG_EAXY }, - { "leaa0sp", REG_A, REG_AX }, - { "leaaxsp", REG_AX, REG_AX }, - { "lsubeq", REG_EAXY|REG_PTR1_LO, REG_EAXY | REG_PTR1_HI }, - { "lsubeq0sp", REG_EAX, REG_EAXY }, - { "lsubeq1", REG_Y | REG_PTR1_LO, REG_EAXY | REG_PTR1_HI }, - { "lsubeqa", REG_AY | REG_PTR1_LO, REG_EAXY | REG_PTR1_HI }, - { "lsubeqysp", REG_EAXY, REG_EAXY }, - { "mulax10", REG_AX, REG_AX | REG_PTR1 }, - { "mulax3", REG_AX, REG_AX | REG_PTR1 }, - { "mulax5", REG_AX, REG_AX | REG_PTR1 }, - { "mulax6", REG_AX, REG_AX | REG_PTR1 }, - { "mulax7", REG_AX, REG_AX | REG_PTR1 }, - { "mulax9", REG_AX, REG_AX | REG_PTR1 }, - { "negax", REG_AX, REG_AX }, - { "push0", REG_NONE, REG_AXY }, - { "push0ax", REG_AX, REG_Y | REG_SREG }, - { "push1", REG_NONE, REG_AXY }, - { "push2", REG_NONE, REG_AXY }, - { "push3", REG_NONE, REG_AXY }, - { "push4", REG_NONE, REG_AXY }, - { "push5", REG_NONE, REG_AXY }, - { "push6", REG_NONE, REG_AXY }, - { "push7", REG_NONE, REG_AXY }, - { "pusha", REG_A, REG_Y }, - { "pusha0", REG_A, REG_XY }, - { "pusha0sp", REG_NONE, REG_AY }, - { "pushaFF", REG_A, REG_Y }, - { "pushax", REG_AX, REG_Y }, - { "pushaysp", REG_Y, REG_AY }, - { "pushc0", REG_NONE, REG_A | REG_Y }, - { "pushc1", REG_NONE, REG_A | REG_Y }, - { "pushc2", REG_NONE, REG_A | REG_Y }, - { "pusheax", REG_EAX, REG_Y }, - { "pushl0", REG_NONE, REG_AXY }, - { "pushw", REG_AX, REG_AXY | REG_PTR1 }, - { "pushw0sp", REG_NONE, REG_AXY }, - { "pushwidx", REG_AXY, REG_AXY | REG_PTR1 }, - { "pushwysp", REG_Y, REG_AXY }, - { "regswap", REG_AXY, REG_AXY | REG_TMP1 }, - { "regswap1", REG_XY, REG_A }, - { "regswap2", REG_XY, REG_A | REG_Y }, - { "return0", REG_NONE, REG_AX }, - { "return1", REG_NONE, REG_AX }, - { "shlax1", REG_AX, REG_AX | REG_TMP1 }, - { "shlax2", REG_AX, REG_AX | REG_TMP1 }, - { "shlax3", REG_AX, REG_AX | REG_TMP1 }, - { "shlax4", REG_AX, REG_AX | REG_TMP1 }, - { "shlaxy", REG_AXY, REG_AXY | REG_TMP1 }, - { "shleax1", REG_EAX, REG_EAX | REG_TMP1 }, - { "shleax2", REG_EAX, REG_EAX | REG_TMP1 }, - { "shleax3", REG_EAX, REG_EAX | REG_TMP1 }, - { "shleax4", REG_EAX, REG_EAXY | REG_TMP1 }, - { "shrax1", REG_AX, REG_AX | REG_TMP1 }, - { "shrax2", REG_AX, REG_AX | REG_TMP1 }, - { "shrax3", REG_AX, REG_AX | REG_TMP1 }, - { "shrax4", REG_AX, REG_AX | REG_TMP1 }, - { "shraxy", REG_AXY, REG_AXY | REG_TMP1 }, - { "shreax1", REG_EAX, REG_EAX | REG_TMP1 }, - { "shreax2", REG_EAX, REG_EAX | REG_TMP1 }, - { "shreax3", REG_EAX, REG_EAX | REG_TMP1 }, - { "shreax4", REG_EAX, REG_EAXY | REG_TMP1 }, - { "staspidx", REG_A | REG_Y, REG_Y | REG_TMP1 | REG_PTR1 }, - { "stax0sp", REG_AX, REG_Y }, - { "staxspidx", REG_AXY, REG_TMP1 | REG_PTR1 }, - { "staxysp", REG_AXY, REG_Y }, - { "steax0sp", REG_EAX, REG_Y }, - { "steaxysp", REG_EAXY, REG_Y }, - { "subeq0sp", REG_AX, REG_AXY }, - { "subeqysp", REG_AXY, REG_AXY }, - { "subysp", REG_Y, REG_AY }, - { "tosadd0ax", REG_AX, REG_EAXY | REG_TMP1 }, - { "tosadda0", REG_A, REG_AXY }, - { "tosaddax", REG_AX, REG_AXY }, - { "tosaddeax", REG_EAX, REG_EAXY | REG_TMP1 }, - { "tosand0ax", REG_AX, REG_EAXY | REG_TMP1 }, - { "tosanda0", REG_A, REG_AXY }, - { "tosandax", REG_AX, REG_AXY }, - { "tosandeax", REG_EAX, REG_EAXY | REG_TMP1 }, - { "tosaslax", REG_A, REG_AXY | REG_TMP1 }, - { "tosasleax", REG_A, REG_EAXY | REG_TMP1 }, - { "tosasrax", REG_A, REG_AXY | REG_TMP1 }, - { "tosasreax", REG_A, REG_EAXY | REG_TMP1 }, - { "tosdiv0ax", REG_AX, REG_ALL }, - { "tosdiva0", REG_A, REG_ALL }, - { "tosdivax", REG_AX, REG_ALL }, - { "tosdiveax", REG_EAX, REG_ALL }, - { "toseq00", REG_NONE, REG_AXY | REG_SREG }, - { "toseqa0", REG_A, REG_AXY | REG_SREG }, - { "toseqax", REG_AX, REG_AXY | REG_SREG }, - { "toseqeax", REG_EAX, REG_AXY | REG_PTR1 }, - { "tosge00", REG_NONE, REG_AXY | REG_SREG }, - { "tosgea0", REG_A, REG_AXY | REG_SREG }, - { "tosgeax", REG_AX, REG_AXY | REG_SREG }, - { "tosgeeax", REG_EAX, REG_AXY | REG_PTR1 }, - { "tosgt00", REG_NONE, REG_AXY | REG_SREG }, - { "tosgta0", REG_A, REG_AXY | REG_SREG }, - { "tosgtax", REG_AX, REG_AXY | REG_SREG }, - { "tosgteax", REG_EAX, REG_AXY | REG_PTR1 }, - { "tosicmp", REG_AX, REG_AXY | REG_SREG }, - { "tosicmp0", REG_A, REG_AXY | REG_SREG }, - { "toslcmp", REG_EAX, REG_A | REG_Y | REG_PTR1 }, - { "tosle00", REG_NONE, REG_AXY | REG_SREG }, - { "toslea0", REG_A, REG_AXY | REG_SREG }, - { "tosleax", REG_AX, REG_AXY | REG_SREG }, - { "tosleeax", REG_EAX, REG_AXY | REG_PTR1 }, - { "toslt00", REG_NONE, REG_AXY | REG_SREG }, - { "toslta0", REG_A, REG_AXY | REG_SREG }, - { "tosltax", REG_AX, REG_AXY | REG_SREG }, - { "toslteax", REG_EAX, REG_AXY | REG_PTR1 }, - { "tosmod0ax", REG_AX, REG_ALL }, - { "tosmodeax", REG_EAX, REG_ALL }, - { "tosmul0ax", REG_AX, REG_ALL }, - { "tosmula0", REG_A, REG_ALL }, - { "tosmulax", REG_AX, REG_ALL }, - { "tosmuleax", REG_EAX, REG_ALL }, - { "tosne00", REG_NONE, REG_AXY | REG_SREG }, - { "tosnea0", REG_A, REG_AXY | REG_SREG }, - { "tosneax", REG_AX, REG_AXY | REG_SREG }, - { "tosneeax", REG_EAX, REG_AXY | REG_PTR1 }, - { "tosor0ax", REG_AX, REG_EAXY | REG_TMP1 }, - { "tosora0", REG_A, REG_AXY | REG_TMP1 }, - { "tosorax", REG_AX, REG_AXY | REG_TMP1 }, - { "tosoreax", REG_EAX, REG_EAXY | REG_TMP1 }, - { "tosrsub0ax", REG_AX, REG_EAXY | REG_TMP1 }, - { "tosrsuba0", REG_A, REG_AXY | REG_TMP1 }, - { "tosrsubax", REG_AX, REG_AXY | REG_TMP1 }, - { "tosrsubeax", REG_EAX, REG_EAXY | REG_TMP1 }, - { "tosshlax", REG_A, REG_AXY | REG_TMP1 }, - { "tosshleax", REG_A, REG_EAXY | REG_TMP1 }, - { "tosshrax", REG_A, REG_AXY | REG_TMP1 }, - { "tosshreax", REG_A, REG_EAXY | REG_TMP1 }, - { "tossub0ax", REG_AX, REG_EAXY }, - { "tossuba0", REG_A, REG_AXY }, - { "tossubax", REG_AX, REG_AXY }, - { "tossubeax", REG_EAX, REG_EAXY }, - { "tosudiv0ax", REG_AX, REG_ALL & ~REG_SAVE }, - { "tosudiva0", REG_A, REG_EAXY | REG_PTR1 }, /* also ptr4 */ - { "tosudivax", REG_AX, REG_EAXY | REG_PTR1 }, /* also ptr4 */ - { "tosudiveax", REG_EAX, REG_ALL & ~REG_SAVE }, - { "tosuge00", REG_NONE, REG_AXY | REG_SREG }, - { "tosugea0", REG_A, REG_AXY | REG_SREG }, - { "tosugeax", REG_AX, REG_AXY | REG_SREG }, - { "tosugeeax", REG_EAX, REG_AXY | REG_PTR1 }, - { "tosugt00", REG_NONE, REG_AXY | REG_SREG }, - { "tosugta0", REG_A, REG_AXY | REG_SREG }, - { "tosugtax", REG_AX, REG_AXY | REG_SREG }, - { "tosugteax", REG_EAX, REG_AXY | REG_PTR1 }, - { "tosule00", REG_NONE, REG_AXY | REG_SREG }, - { "tosulea0", REG_A, REG_AXY | REG_SREG }, - { "tosuleax", REG_AX, REG_AXY | REG_SREG }, - { "tosuleeax", REG_EAX, REG_AXY | REG_PTR1 }, - { "tosult00", REG_NONE, REG_AXY | REG_SREG }, - { "tosulta0", REG_A, REG_AXY | REG_SREG }, - { "tosultax", REG_AX, REG_AXY | REG_SREG }, - { "tosulteax", REG_EAX, REG_AXY | REG_PTR1 }, - { "tosumod0ax", REG_AX, REG_ALL & ~REG_SAVE }, - { "tosumoda0", REG_A, REG_EAXY | REG_PTR1 }, /* also ptr4 */ - { "tosumodax", REG_AX, REG_EAXY | REG_PTR1 }, /* also ptr4 */ - { "tosumodeax", REG_EAX, REG_ALL & ~REG_SAVE }, - { "tosumul0ax", REG_AX, REG_ALL }, - { "tosumula0", REG_A, REG_ALL }, - { "tosumulax", REG_AX, REG_ALL }, - { "tosumuleax", REG_EAX, REG_ALL }, - { "tosxor0ax", REG_AX, REG_EAXY | REG_TMP1 }, - { "tosxora0", REG_A, REG_AXY | REG_TMP1 }, - { "tosxorax", REG_AX, REG_AXY | REG_TMP1 }, - { "tosxoreax", REG_EAX, REG_EAXY | REG_TMP1 }, - { "tsteax", REG_EAX, REG_Y }, - { "utsteax", REG_EAX, REG_Y }, + { "addeq0sp", REG_AX, PSTATE_ALL | REG_AXY }, + { "addeqysp", REG_AXY, PSTATE_ALL | REG_AXY }, + { "addysp", REG_Y, PSTATE_ALL | REG_NONE }, + { "aslax1", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, + { "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 }, + { "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 }, + { "asleax3", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, + { "asleax4", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "asrax1", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, + { "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 }, + { "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 }, + { "asreax3", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, + { "asreax4", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "bcasta", REG_A, PSTATE_ALL | REG_AX }, + { "bcastax", REG_AX, PSTATE_ALL | REG_AX }, + { "bcasteax", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, + { "bnega", REG_A, PSTATE_ALL | REG_AX }, + { "bnegax", REG_AX, PSTATE_ALL | REG_AX }, + { "bnegeax", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, + { "booleq", PSTATE_Z, PSTATE_ALL | REG_AX }, + { "boolge", PSTATE_N, PSTATE_ALL | REG_AX }, + { "boolgt", PSTATE_ZN, PSTATE_ALL | REG_AX }, + { "boolle", PSTATE_ZN, PSTATE_ALL | REG_AX }, + { "boollt", PSTATE_N, PSTATE_ALL | REG_AX }, + { "boolne", PSTATE_Z, PSTATE_ALL | REG_AX }, + { "booluge", PSTATE_C, PSTATE_ALL | REG_AX }, + { "boolugt", PSTATE_CZ, PSTATE_ALL | REG_AX }, + { "boolule", PSTATE_CZ, PSTATE_ALL | REG_AX }, + { "boolult", PSTATE_C, PSTATE_ALL | REG_AX }, + { "callax", REG_AX, PSTATE_ALL | REG_ALL }, + { "complax", REG_AX, PSTATE_ALL | REG_AX }, + { "decax1", REG_AX, PSTATE_ALL | REG_AX }, + { "decax2", REG_AX, PSTATE_ALL | REG_AX }, + { "decax3", REG_AX, PSTATE_ALL | REG_AX }, + { "decax4", REG_AX, PSTATE_ALL | REG_AX }, + { "decax5", REG_AX, PSTATE_ALL | REG_AX }, + { "decax6", REG_AX, PSTATE_ALL | REG_AX }, + { "decax7", REG_AX, PSTATE_ALL | REG_AX }, + { "decax8", REG_AX, PSTATE_ALL | REG_AX }, + { "decaxy", REG_AXY, PSTATE_ALL | REG_AX | REG_TMP1 }, + { "deceaxy", REG_EAXY, PSTATE_ALL | REG_EAX }, + { "decsp1", REG_NONE, PSTATE_ALL | REG_Y }, + { "decsp2", REG_NONE, PSTATE_ALL | REG_A }, + { "decsp3", REG_NONE, PSTATE_ALL | REG_A }, + { "decsp4", REG_NONE, PSTATE_ALL | REG_A }, + { "decsp5", REG_NONE, PSTATE_ALL | REG_A }, + { "decsp6", REG_NONE, PSTATE_ALL | REG_A }, + { "decsp7", REG_NONE, PSTATE_ALL | REG_A }, + { "decsp8", REG_NONE, PSTATE_ALL | REG_A }, + { "incax1", REG_AX, PSTATE_ALL | REG_AX }, + { "incax2", REG_AX, PSTATE_ALL | REG_AX }, + { "incax3", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "incax4", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "incax5", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "incax6", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "incax7", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "incax8", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "incaxy", REG_AXY, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "incsp1", REG_NONE, PSTATE_ALL | REG_NONE }, + { "incsp2", REG_NONE, PSTATE_ALL | REG_Y }, + { "incsp3", REG_NONE, PSTATE_ALL | REG_Y }, + { "incsp4", REG_NONE, PSTATE_ALL | REG_Y }, + { "incsp5", REG_NONE, PSTATE_ALL | REG_Y }, + { "incsp6", REG_NONE, PSTATE_ALL | REG_Y }, + { "incsp7", REG_NONE, PSTATE_ALL | REG_Y }, + { "incsp8", REG_NONE, PSTATE_ALL | REG_Y }, + { "laddeq", REG_EAXY|REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI }, + { "laddeq0sp", REG_EAX, PSTATE_ALL | REG_EAXY }, + { "laddeq1", REG_Y | REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI }, + { "laddeqa", REG_AY | REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI }, + { "laddeqysp", REG_EAXY, PSTATE_ALL | REG_EAXY }, + { "ldaidx", REG_AXY, PSTATE_ALL | REG_AX | REG_PTR1 }, + { "ldauidx", REG_AXY, PSTATE_ALL | REG_AX | REG_PTR1 }, + { "ldax0sp", REG_NONE, PSTATE_ALL | REG_AXY }, + { "ldaxi", REG_AX, PSTATE_ALL | REG_AXY | REG_PTR1 }, + { "ldaxidx", REG_AXY, PSTATE_ALL | REG_AXY | REG_PTR1 }, + { "ldaxysp", REG_Y, PSTATE_ALL | REG_AXY }, + { "ldeax0sp", REG_NONE, PSTATE_ALL | REG_EAXY }, + { "ldeaxi", REG_AX, PSTATE_ALL | REG_EAXY | REG_PTR1 }, + { "ldeaxidx", REG_AXY, PSTATE_ALL | REG_EAXY | REG_PTR1 }, + { "ldeaxysp", REG_Y, PSTATE_ALL | REG_EAXY }, + { "leaa0sp", REG_A, PSTATE_ALL | REG_AX }, + { "leaaxsp", REG_AX, PSTATE_ALL | REG_AX }, + { "lsubeq", REG_EAXY|REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI }, + { "lsubeq0sp", REG_EAX, PSTATE_ALL | REG_EAXY }, + { "lsubeq1", REG_Y | REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI }, + { "lsubeqa", REG_AY | REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI }, + { "lsubeqysp", REG_EAXY, PSTATE_ALL | REG_EAXY }, + { "mulax10", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, + { "mulax3", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, + { "mulax5", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, + { "mulax6", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, + { "mulax7", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, + { "mulax9", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, + { "negax", REG_AX, PSTATE_ALL | REG_AX }, + { "push0", REG_NONE, PSTATE_ALL | REG_AXY }, + { "push0ax", REG_AX, PSTATE_ALL | REG_Y | REG_SREG }, + { "push1", REG_NONE, PSTATE_ALL | REG_AXY }, + { "push2", REG_NONE, PSTATE_ALL | REG_AXY }, + { "push3", REG_NONE, PSTATE_ALL | REG_AXY }, + { "push4", REG_NONE, PSTATE_ALL | REG_AXY }, + { "push5", REG_NONE, PSTATE_ALL | REG_AXY }, + { "push6", REG_NONE, PSTATE_ALL | REG_AXY }, + { "push7", REG_NONE, PSTATE_ALL | REG_AXY }, + { "pusha", REG_A, PSTATE_ALL | REG_Y }, + { "pusha0", REG_A, PSTATE_ALL | REG_XY }, + { "pusha0sp", REG_NONE, PSTATE_ALL | REG_AY }, + { "pushaFF", REG_A, PSTATE_ALL | REG_Y }, + { "pushax", REG_AX, PSTATE_ALL | REG_Y }, + { "pushaysp", REG_Y, PSTATE_ALL | REG_AY }, + { "pushc0", REG_NONE, PSTATE_ALL | REG_A | REG_Y }, + { "pushc1", REG_NONE, PSTATE_ALL | REG_A | REG_Y }, + { "pushc2", REG_NONE, PSTATE_ALL | REG_A | REG_Y }, + { "pusheax", REG_EAX, PSTATE_ALL | REG_Y }, + { "pushl0", REG_NONE, PSTATE_ALL | REG_AXY }, + { "pushw", REG_AX, PSTATE_ALL | REG_AXY | REG_PTR1 }, + { "pushw0sp", REG_NONE, PSTATE_ALL | REG_AXY }, + { "pushwidx", REG_AXY, PSTATE_ALL | REG_AXY | REG_PTR1 }, + { "pushwysp", REG_Y, PSTATE_ALL | REG_AXY }, + { "regswap", REG_AXY, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "regswap1", REG_XY, PSTATE_ALL | REG_A }, + { "regswap2", REG_XY, PSTATE_ALL | REG_A | REG_Y }, + { "return0", REG_NONE, PSTATE_ALL | REG_AX }, + { "return1", REG_NONE, PSTATE_ALL | REG_AX }, + { "shlax1", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, + { "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 }, + { "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 }, + { "shleax3", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, + { "shleax4", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "shrax1", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, + { "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 }, + { "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 }, + { "shreax3", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, + { "shreax4", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "staspidx", REG_A | REG_Y, PSTATE_ALL | REG_Y | REG_TMP1 | REG_PTR1 }, + { "stax0sp", REG_AX, PSTATE_ALL | REG_Y }, + { "staxspidx", REG_AXY, PSTATE_ALL | REG_TMP1 | REG_PTR1 }, + { "staxysp", REG_AXY, PSTATE_ALL | REG_Y }, + { "steax0sp", REG_EAX, PSTATE_ALL | REG_Y }, + { "steaxysp", REG_EAXY, PSTATE_ALL | REG_Y }, + { "subeq0sp", REG_AX, PSTATE_ALL | REG_AXY }, + { "subeqysp", REG_AXY, PSTATE_ALL | REG_AXY }, + { "subysp", REG_Y, PSTATE_ALL | REG_AY }, + { "tosadd0ax", REG_AX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "tosadda0", REG_A, PSTATE_ALL | REG_AXY }, + { "tosaddax", REG_AX, PSTATE_ALL | REG_AXY }, + { "tosaddeax", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "tosand0ax", REG_AX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "tosanda0", REG_A, PSTATE_ALL | REG_AXY }, + { "tosandax", REG_AX, PSTATE_ALL | REG_AXY }, + { "tosandeax", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "tosaslax", REG_A, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "tosasleax", REG_A, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "tosasrax", REG_A, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "tosasreax", REG_A, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "tosdiv0ax", REG_AX, PSTATE_ALL | REG_ALL }, + { "tosdiva0", REG_A, PSTATE_ALL | REG_ALL }, + { "tosdivax", REG_AX, PSTATE_ALL | REG_ALL }, + { "tosdiveax", REG_EAX, PSTATE_ALL | REG_ALL }, + { "toseq00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, + { "toseqa0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, + { "toseqax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, + { "toseqeax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, + { "tosge00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosgea0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosgeax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosgeeax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, + { "tosgt00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosgta0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosgtax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosgteax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, + { "tosicmp", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosicmp0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, + { "toslcmp", REG_EAX, PSTATE_ALL | REG_A | REG_Y | REG_PTR1 }, + { "tosle00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, + { "toslea0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosleax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosleeax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, + { "toslt00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, + { "toslta0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosltax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, + { "toslteax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, + { "tosmod0ax", REG_AX, PSTATE_ALL | REG_ALL }, + { "tosmodeax", REG_EAX, PSTATE_ALL | REG_ALL }, + { "tosmul0ax", REG_AX, PSTATE_ALL | REG_ALL }, + { "tosmula0", REG_A, PSTATE_ALL | REG_ALL }, + { "tosmulax", REG_AX, PSTATE_ALL | REG_ALL }, + { "tosmuleax", REG_EAX, PSTATE_ALL | REG_ALL }, + { "tosne00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosnea0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosneax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosneeax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, + { "tosor0ax", REG_AX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "tosora0", REG_A, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "tosorax", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "tosoreax", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "tosrsub0ax", REG_AX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "tosrsuba0", REG_A, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "tosrsubax", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "tosrsubeax", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "tosshlax", REG_A, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "tosshleax", REG_A, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "tosshrax", REG_A, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "tosshreax", REG_A, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "tossub0ax", REG_AX, PSTATE_ALL | REG_EAXY }, + { "tossuba0", REG_A, PSTATE_ALL | REG_AXY }, + { "tossubax", REG_AX, PSTATE_ALL | REG_AXY }, + { "tossubeax", REG_EAX, PSTATE_ALL | REG_EAXY }, + { "tosudiv0ax", REG_AX, PSTATE_ALL | (REG_ALL & ~REG_SAVE) }, + { "tosudiva0", REG_A, PSTATE_ALL | REG_EAXY | REG_PTR1 }, /* also ptr4 */ + { "tosudivax", REG_AX, PSTATE_ALL | REG_EAXY | REG_PTR1 }, /* also ptr4 */ + { "tosudiveax", REG_EAX, PSTATE_ALL | (REG_ALL & ~REG_SAVE) }, + { "tosuge00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosugea0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosugeax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosugeeax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, + { "tosugt00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosugta0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosugtax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosugteax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, + { "tosule00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosulea0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosuleax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosuleeax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, + { "tosult00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosulta0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosultax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, + { "tosulteax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, + { "tosumod0ax", REG_AX, PSTATE_ALL | (REG_ALL & ~REG_SAVE) }, + { "tosumoda0", REG_A, PSTATE_ALL | REG_EAXY | REG_PTR1 }, /* also ptr4 */ + { "tosumodax", REG_AX, PSTATE_ALL | REG_EAXY | REG_PTR1 }, /* also ptr4 */ + { "tosumodeax", REG_EAX, PSTATE_ALL | (REG_ALL & ~REG_SAVE) }, + { "tosumul0ax", REG_AX, PSTATE_ALL | REG_ALL }, + { "tosumula0", REG_A, PSTATE_ALL | REG_ALL }, + { "tosumulax", REG_AX, PSTATE_ALL | REG_ALL }, + { "tosumuleax", REG_EAX, PSTATE_ALL | REG_ALL }, + { "tosxor0ax", REG_AX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "tosxora0", REG_A, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "tosxorax", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "tosxoreax", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "tsteax", REG_EAX, PSTATE_ALL | REG_Y }, + { "utsteax", REG_EAX, PSTATE_ALL | REG_Y }, }; #define FuncInfoCount (sizeof(FuncInfoTable) / sizeof(FuncInfoTable[0])) @@ -385,10 +385,10 @@ static int CompareFuncInfo (const void* Key, const void* Info) -fncls_t GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) +fncls_t GetFuncInfo (const char* Name, unsigned int* Use, unsigned int* Chg) /* For the given function, lookup register information and store it into ** the given variables. If the function is unknown, assume it will use and -** load all registers. +** load all registers as well as touching the processor flags. */ { /* If the function name starts with an underline, it is an external @@ -441,6 +441,9 @@ fncls_t GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) /* Will destroy all registers */ *Chg = REG_ALL; + /* and will destroy all processor flags */ + *Chg |= PSTATE_ALL; + /* Done */ return FNCLS_GLOBAL; } @@ -453,6 +456,7 @@ fncls_t GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) */ *Use = REG_ALL; *Chg = REG_ALL; + *Chg |= PSTATE_ALL; return FNCLS_NUMERIC; } else { @@ -477,15 +481,17 @@ fncls_t GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) } *Use = REG_ALL; *Chg = REG_ALL; + *Chg |= PSTATE_ALL; } return FNCLS_BUILTIN; } /* Function not found - assume that the primary register is input, and all - ** registers are changed + ** registers and processor flags are changed */ *Use = REG_EAXY; *Chg = REG_ALL; + *Chg |= PSTATE_ALL; return FNCLS_UNKNOWN; } diff --git a/src/cc65/codeinfo.h b/src/cc65/codeinfo.h index 763b947bf..32bc5dd9c 100644 --- a/src/cc65/codeinfo.h +++ b/src/cc65/codeinfo.h @@ -57,7 +57,7 @@ struct CodeSeg; /* Forward to struct RegContents */ struct RegContents; -/* Defines for registers. */ +/* Defines for registers */ #define REG_NONE 0x0000U #define REG_A 0x0001U #define REG_X 0x0002U @@ -74,6 +74,21 @@ struct RegContents; #define REG_SP_LO 0x1000U #define REG_SP_HI 0x2000U +/* Defines for some special register usage */ +#define SLV_SP65 0x00200000U /* Accesses 6502 stack pointer */ +#define SLV_PH65 0x00400000U /* Pushes onto 6502 stack */ +#define SLV_PL65 0x00800000U /* Pops from 6502 stack */ + +/* Defines for processor states */ +#define PSTATE_NONE 0x00000000U +#define PSTATE_C 0x01000000U /* Carry */ +#define PSTATE_Z 0x02000000U /* Zero */ +#define PSTATE_I 0x04000000U /* Interrupt */ +#define PSTATE_D 0x08000000U /* Decimal */ +#define PSTATE_U 0x10000000U /* Unused */ +#define PSTATE_B 0x20000000U /* Break */ +#define PSTATE_V 0x40000000U /* Overflow */ +#define PSTATE_N 0x80000000U /* Negative */ /* Combined register defines */ #define REG_PTR1 (REG_PTR1_LO | REG_PTR1_HI) @@ -89,6 +104,14 @@ struct RegContents; #define REG_EAXY (REG_EAX | REG_Y) #define REG_ZP 0xFFF8U #define REG_ALL 0xFFFFU +#define PSTATE_CZ (PSTATE_C | PSTATE_Z) +#define PSTATE_CZN (PSTATE_C | PSTATE_Z | PSTATE_N) +#define PSTATE_CZVN (PSTATE_C | PSTATE_Z | PSTATE_V | PSTATE_N) +#define PSTATE_ZN (PSTATE_Z | PSTATE_N) +#define PSTATE_ZVN (PSTATE_Z | PSTATE_V | PSTATE_N) +#define PSTATE_6502 0xE7000000U +#define PSTATE_ALL 0xFF000000U +#define REG_EVERYTHING 0xFFFFFFFFU @@ -139,7 +162,7 @@ typedef enum { -fncls_t GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg); +fncls_t GetFuncInfo (const char* Name, unsigned int* Use, unsigned int* Chg); /* For the given function, lookup register information and store it into ** the given variables. If the function is unknown, assume it will use and ** load all registers. diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index f2e0faf15..ad8a3148c 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -1468,6 +1468,7 @@ void CS_GenRegInfo (CodeSeg* S) /* On entry, the register contents are unknown */ RC_Invalidate (&Regs); + RC_InvalidatePS (&Regs); CurrentRegs = &Regs; /* Walk over all insns and note just the changes from one insn to the @@ -1502,6 +1503,7 @@ void CS_GenRegInfo (CodeSeg* S) Regs = J->RI->Out2; } else { RC_Invalidate (&Regs); + RC_InvalidatePS (&Regs); } Entry = 1; } else { @@ -1521,6 +1523,7 @@ void CS_GenRegInfo (CodeSeg* S) */ Done = 0; RC_Invalidate (&Regs); + RC_InvalidatePS (&Regs); break; } if (J->RI->Out2.RegA != Regs.RegA) { @@ -1541,6 +1544,9 @@ void CS_GenRegInfo (CodeSeg* S) if (J->RI->Out2.Tmp1 != Regs.Tmp1) { Regs.Tmp1 = UNKNOWN_REGVAL; } + unsigned PF = J->RI->Out2.PFlags ^ Regs.PFlags; + Regs.PFlags |= ((PF >> 8) | PF | (PF << 8)) & UNKNOWN_PFVAL_ALL; + Regs.ZNRegs &= J->RI->Out2.ZNRegs; ++Entry; } diff --git a/src/cc65/coptsize.c b/src/cc65/coptsize.c index 5c23e637c..a5da4736d 100644 --- a/src/cc65/coptsize.c +++ b/src/cc65/coptsize.c @@ -76,730 +76,730 @@ static const CallDesc CallTable [] = { { "addeqysp", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "addeq0sp" },{ "laddeq", { - /* A X Y SRegLo */ - 1, 0, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 1, 0, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "laddeq1" },{ "laddeq", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "laddeqa" },{ "laddeqysp", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "laddeq0sp" },{ "ldaxidx", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "ldaxi" },{ "ldaxysp", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "ldax0sp" },{ "ldeaxidx", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "ldeaxi" },{ "ldeaxysp", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "ldeax0sp" },{ "leaaxsp", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "leaa0sp" },{ "lsubeq", { - /* A X Y SRegLo */ - 1, 0, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 1, 0, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "lsubeq1" },{ "lsubeq", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "lsubeqa" },{ "lsubeqysp", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "lsubeq0sp" },{ "pusha", { - /* A X Y SRegLo */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_SLOWER, "pushc0" },{ "pusha", { - /* A X Y SRegLo */ - 1, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 1, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_SLOWER, "pushc1" },{ "pusha", { - /* A X Y SRegLo */ - 2, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 2, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_SLOWER, "pushc2" },{ "pushax", { - /* A X Y SRegLo */ - 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "push0" },{ "pushax", { - /* A X Y SRegLo */ - 1, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 1, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_SLOWER, "push1" },{ "pushax", { - /* A X Y SRegLo */ - 2, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 2, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_SLOWER, "push2" },{ "pushax", { - /* A X Y SRegLo */ - 3, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 3, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_SLOWER, "push3" },{ "pushax", { - /* A X Y SRegLo */ - 4, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 4, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_SLOWER, "push4" },{ "pushax", { - /* A X Y SRegLo */ - 5, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 5, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_SLOWER, "push5" },{ "pushax", { - /* A X Y SRegLo */ - 6, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 6, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_SLOWER, "push6" },{ "pushax", { - /* A X Y SRegLo */ - 7, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 7, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_SLOWER, "push7" },{ "pushax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "pusha0" },{ "pushax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0xFF, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0xFF, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_SLOWER, "pushaFF" },{ "pushaysp", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "pusha0sp" },{ "pusheax", { - /* A X Y SRegLo */ - 0, 0, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 0, 0, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "pushl0" },{ "pusheax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "push0ax" },{ "pushwidx", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "pushw" },{ "pushwysp", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "pushw0sp" },{ "staxysp", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "stax0sp" },{ "steaxysp", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "steax0sp" },{ "subeqysp", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "subeq0sp" },{ "tosaddax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosadda0" },{ "tosaddeax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosadd0ax" },{ "tosandax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosanda0" },{ "tosandeax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosand0ax" },{ "tosdivax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosdiva0" },{ "tosdiveax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosdiv0ax" },{ "toseqax", { - /* A X Y SRegLo */ - 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "toseq00" },{ "toseqax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "toseqa0" },{ "tosgeax", { - /* A X Y SRegLo */ - 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosge00" },{ "tosgeax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosgea0" },{ "tosgtax", { - /* A X Y SRegLo */ - 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosgt00" },{ "tosgtax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosgta0" },{ "tosicmp", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosicmp0" },{ "tosleax", { - /* A X Y SRegLo */ - 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosle00" },{ "tosleax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "toslea0" },{ "tosltax", { - /* A X Y SRegLo */ - 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "toslt00" },{ "tosltax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "toslta0" },{ "tosmodax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosmoda0" },{ "tosmodeax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosmod0ax" },{ "tosmulax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosmula0" },{ "tosmuleax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosmul0ax" },{ "tosneax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosnea0" },{ "tosorax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosora0" },{ "tosoreax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosor0ax" },{ "tosrsubax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosrsuba0" },{ "tosrsubeax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosrsub0ax" },{ "tossubax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tossuba0" },{ "tossubeax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tossub0ax" },{ "tosudivax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosudiva0" },{ "tosudiveax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosudiv0ax" },{ "tosugeax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosugea0" },{ "tosugtax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosugta0" },{ "tosuleax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosulea0" },{ "tosultax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosulta0" },{ "tosumodax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosumoda0" },{ "tosumodeax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosumod0ax" },{ "tosumulax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosumula0" },{ "tosumuleax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosumul0ax" },{ "tosxorax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosxora0" },{ "tosxoreax", { - /* A X Y SRegLo */ - UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, - /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */ - 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL + /* A X Y SRegLo SRegHi */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, 0, + /* Ptr1Lo Ptr1Hi Tmp1 PFlags ZNRegs */ + UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_PFVAL_ALL, ZNREG_NONE }, F_NONE, "tosxor0ax" diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 34a9b88d6..c31b0ec97 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -320,10 +320,10 @@ static void AdjustLoadInfo (LoadInfo* LI, int Index, int Change) static int Affected (LoadRegInfo* RI, const CodeEntry* E) /* Check if the load src may be modified between the pushax and op */ { - fncls_t fncls; - unsigned short Use; - unsigned short Chg; - unsigned short UseToCheck = 0; + fncls_t fncls; + unsigned int Use; + unsigned int Chg; + unsigned int UseToCheck = 0; if ((RI->Flags & (LI_CHECK_ARG | LI_CHECK_Y)) != 0) { if (E->AM == AM65_IMM || E->AM == AM65_ACC || E->AM == AM65_IMP || E->AM == AM65_BRA) { diff --git a/src/cc65/reginfo.c b/src/cc65/reginfo.c index 383c6ec24..601f0f688 100644 --- a/src/cc65/reginfo.c +++ b/src/cc65/reginfo.c @@ -74,6 +74,15 @@ void RC_InvalidateZP (RegContents* C) +void RC_InvalidatePS (RegContents* C) +/* Invalidate processor status */ +{ + C->PFlags = UNKNOWN_PFVAL_ALL; + C->ZNRegs = ZNREG_NONE; +} + + + static void RC_Dump1 (FILE* F, const char* Desc, short Val) /* Dump one register value */ { @@ -102,6 +111,44 @@ void RC_Dump (FILE* F, const RegContents* RC) +#if !defined(HAVE_INLINE) +int PStatesAreKnown (unsigned short PFlags, unsigned WhatStates) +/* Return true if all queried processor states are known. +** Note: WhatStates takes PSTATE_* rather than PFVAL_*. +*/ +{ + return ((PFlags << (PSTATE_BITS_SHIFT - 8)) & WhatStates & PSTATE_BITS_MASK) == 0; +} +#endif + + + +#if !defined(HAVE_INLINE) +int PStatesAreSet (unsigned short PFlags, unsigned WhatStates) +/* Return true if all queried processor states are known to be set. +** Note: WhatStates takes PSTATE_* rather than PFVAL_*. +*/ +{ + return (PFlags & (WhatStates >> (PSTATE_BITS_SHIFT - 8))) == 0 && + (PFlags & (WhatStates >> PSTATE_BITS_SHIFT)) == WhatStates >> PSTATE_BITS_SHIFT; +} +#endif + + + +#if !defined(HAVE_INLINE) +int PStatesAreClear (unsigned short PFlags, unsigned WhatStates) +/* Return true if all queried processor states are known to be cleared. +** Note: WhatStates takes PSTATE_* rather than PFVAL_*. +*/ +{ + return (PFlags & (WhatStates >> (PSTATE_BITS_SHIFT - 8))) == 0 && + (PFlags & (WhatStates >> PSTATE_BITS_SHIFT)) == 0; +} +#endif + + + RegInfo* NewRegInfo (const RegContents* RC) /* Allocate a new register info, initialize and return it. If RC is not ** a NULL pointer, it is used to initialize both, the input and output @@ -120,6 +167,9 @@ RegInfo* NewRegInfo (const RegContents* RC) RC_Invalidate (&RI->In); RC_Invalidate (&RI->Out); RC_Invalidate (&RI->Out2); + RC_InvalidatePS (&RI->In); + RC_InvalidatePS (&RI->Out); + RC_InvalidatePS (&RI->Out2); } /* Return the new struct */ diff --git a/src/cc65/reginfo.h b/src/cc65/reginfo.h index 7354c301f..28b948e04 100644 --- a/src/cc65/reginfo.h +++ b/src/cc65/reginfo.h @@ -54,6 +54,69 @@ /* Encoding for an unknown register value */ #define UNKNOWN_REGVAL -1 +/* Encoding for an unknown processor status: +** For Bit N in the flags, ((flags >> N) & 0x0101) == 0x0101 means 'unknown' +*/ +#define UNKNOWN_PFVAL_C 0x0101U /* Carray */ +#define UNKNOWN_PFVAL_Z 0x0202U /* Zero */ +#define UNKNOWN_PFVAL_I 0x0404U /* Interrupt */ +#define UNKNOWN_PFVAL_D 0x0808U /* Decimal */ +#define UNKNOWN_PFVAL_U 0x1010U /* Unused */ +#define UNKNOWN_PFVAL_B 0x2020U /* Break */ +#define UNKNOWN_PFVAL_V 0x4040U /* Overflow */ +#define UNKNOWN_PFVAL_N 0x8080U /* Negative */ +#define UNKNOWN_PFVAL_CZ (UNKNOWN_PFVAL_C | UNKNOWN_PFVAL_Z) +#define UNKNOWN_PFVAL_CZN (UNKNOWN_PFVAL_N | UNKNOWN_PFVAL_CZ) +#define UNKNOWN_PFVAL_CZVN (UNKNOWN_PFVAL_V | UNKNOWN_PFVAL_CZN) +#define UNKNOWN_PFVAL_ZN (UNKNOWN_PFVAL_Z | UNKNOWN_PFVAL_N) +#define UNKNOWN_PFVAL_ZVN (UNKNOWN_PFVAL_V | UNKNOWN_PFVAL_ZN) +#define UNKNOWN_PFVAL_6502 0xE7E7U +#define UNKNOWN_PFVAL_ALL 0xFFFFU + +/* Encoding for a known processor status */ +#define PFVAL_C 0x0001U /* Carray set */ +#define PFVAL_Z 0x0002U /* Zero set */ +#define PFVAL_I 0x0004U /* Interrupt set */ +#define PFVAL_D 0x0008U /* Decimal set */ +#define PFVAL_U 0x0010U /* Unused set */ +#define PFVAL_B 0x0020U /* Break set */ +#define PFVAL_V 0x0040U /* Overflow set */ +#define PFVAL_N 0x0080U /* Negative set */ +#define PFVAL_CZ (PFVAL_C | PFVAL_Z) +#define PFVAL_CZN (PFVAL_N | PFVAL_CZ) +#define PFVAL_CZVN (PFVAL_V | PFVAL_CZN) +#define PFVAL_ZN (PFVAL_Z | PFVAL_N) +#define PFVAL_ZVN (PFVAL_V | PFVAL_ZN) +#define PFVAL_6502 0x00E7U +#define PFVAL_ALL 0x00FFU + +/* Used for functions to convert the processor states to processor flags */ +#define PSTATE_BITS_SHIFT 24 +#define PSTATE_BITS_MASK (0xFFU << PSTATE_BITS_SHIFT) + +/* Encoding for unknown Z/N status origin */ +#define UNKNOWN_ZNREG 0x0000U + +/* Encoding for known register Z/N status origins */ +#define ZNREG_NONE 0x0000U /* None */ +#define ZNREG_A REG_A +#define ZNREG_X REG_X +#define ZNREG_Y REG_Y +#define ZNREG_TMP1 REG_TMP1 +#define ZNREG_PTR1_LO REG_PTR1_LO +#define ZNREG_PTR1_HI REG_PTR1_HI +#define ZNREG_PTR2_LO REG_PTR2_LO +#define ZNREG_PTR2_HI REG_PTR2_HI +#define ZNREG_SREG_LO REG_SREG_LO +#define ZNREG_SREG_HI REG_SREG_HI +#define ZNREG_SAVE_LO REG_SAVE_LO +#define ZNREG_SAVE_HI REG_SAVE_HI +#define ZNREG_AX (REG_A | REG_X) +#define ZNREG_AY (REG_A | REG_Y) +#define ZNREG_AXY (REG_A | REG_X | REG_Y) + + + /* Register contents */ typedef struct RegContents RegContents; struct RegContents { @@ -65,6 +128,8 @@ struct RegContents { short Ptr1Lo; short Ptr1Hi; short Tmp1; + unsigned short PFlags; /* Processor flags */ + unsigned short ZNRegs; /* Which register(s) the Z/N flags reflect */ }; /* Register change info */ @@ -89,6 +154,9 @@ void RC_Invalidate (RegContents* C); void RC_InvalidateZP (RegContents* C); /* Invalidate all ZP registers */ +void RC_InvalidatePS (RegContents* C); +/* Invalidate processor status */ + void RC_Dump (FILE* F, const RegContents* RC); /* Dump the contents of the given RegContents struct */ @@ -112,6 +180,56 @@ INLINE int RegValIsUnknown (short Val) # define RegValIsUnknown(S) ((S) < 0) #endif +#if defined(HAVE_INLINE) +INLINE int PStatesAreKnown (unsigned short PFlags, unsigned WhatStates) +/* Return true if all queried processor states are known. +** Note: WhatStates takes PSTATE_* rather than PFVAL_*. +*/ +{ + return ((PFlags << (PSTATE_BITS_SHIFT - 8)) & WhatStates & PSTATE_BITS_MASK) == 0; +} +#else +int PStatesAreKnown (unsigned short PFlags, unsigned WhatStates); +#endif + +#if defined(HAVE_INLINE) +INLINE int PStatesAreUnknown (unsigned short PFlags, unsigned WhatStates) +/* Return true if any queried processor states are unknown. +** Note: WhatStates takes PSTATE_* rather than PFVAL_*. +*/ +{ + return !PStatesAreKnown (PFlags, WhatStates); +} +#else +# define PStatesAreUnknown(V, B) (!PStatesAreKnown (V, B)) +#endif + +#if defined(HAVE_INLINE) +INLINE int PStatesAreSet (unsigned short PFlags, unsigned WhatStates) +/* Return true if all queried processor states are known to be set. +** Note: WhatStates takes PSTATE_* rather than PFVAL_*. +*/ +{ + return (PFlags & (WhatStates >> (PSTATE_BITS_SHIFT - 8))) == 0 && + (PFlags & (WhatStates >> PSTATE_BITS_SHIFT)) == WhatStates >> PSTATE_BITS_SHIFT; +} +#else +int PStatesAreSet (unsigned short PFlags, unsigned WhatStates); +#endif + +#if defined(HAVE_INLINE) +INLINE int PStatesAreClear (unsigned short PFlags, unsigned WhatStates) +/* Return true if the queried processor states are known to be cleared. +** Note: WhatStates takes PSTATE_* rather than PFVAL_*. +*/ +{ + return (PFlags & (WhatStates >> (PSTATE_BITS_SHIFT - 8))) == 0 && + (PFlags & (WhatStates >> PSTATE_BITS_SHIFT)) == 0; +} +#else +int PStatesAreClear (unsigned short PFlags, unsigned WhatStates); +#endif + RegInfo* NewRegInfo (const RegContents* RC); /* Allocate a new register info, initialize and return it. If RC is not ** a NULL pointer, it is used to initialize both, the input and output From 810e17edfefba76b3b3241e121b936572bf14a69 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 8 Sep 2020 23:41:02 +0800 Subject: [PATCH 1693/2161] Fixed processor states tracking for the BIT/TRB/TSB opcode. Added new opcode descriptions about whether and how the opcode accesses memory. --- src/cc65/codeent.c | 34 ++++++++++++++++++++++++++---- src/cc65/opcodes.c | 52 +++++++++++++++++++++++----------------------- src/cc65/opcodes.h | 5 ++++- 3 files changed, 60 insertions(+), 31 deletions(-) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index 085130001..d54be039a 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -889,12 +889,38 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Val = In->SRegHi; break; } + } else if (CE_IsConstImm (E)) { + /* 65C02 special */ + Val = (short) E->Num; } - Out->PFlags &= ~UNKNOWN_PFVAL_V; - if (Val & PFVAL_V) { - Out->PFlags |= PFVAL_V; + + /* BIT is unique with regards to the Z/V/N flags: + ** - The Z is set/cleared according to whether the AND result is zero. + ** - The V is coped directly from Bit 6 of the orginal argument. + ** - The N is coped directly from Bit 7 of the orginal argument. + ** Note the V/N flags are not affected in imm addressing mode supported by 65c02! + */ + if (E->AM == AM65_IMM) { + if (RegValIsKnown (Val)) { + Out->PFlags &= ~(UNKNOWN_PFVAL_V | UNKNOWN_PFVAL_N); + if (Val & PFVAL_V) { + Out->PFlags |= PFVAL_V; + } + Out->PFlags &= ~UNKNOWN_PFVAL_V; + if (Val & PFVAL_V) { + Out->PFlags |= PFVAL_V; + } + } else { + Out->PFlags |= UNKNOWN_PFVAL_V | UNKNOWN_PFVAL_N; + } } - DeduceZN (Out, Val); + if ((RegValIsKnown (Val) && RegValIsKnown (In->RegA))) { + Val &= In->RegA; + } else if (((RegValIsKnown (Val) && Val == 0) || + (RegValIsKnown (In->RegA) && In->RegA == 0))) { + Val = 0; + } + DeduceZ (Out, Val); break; case OP65_BMI: diff --git a/src/cc65/opcodes.c b/src/cc65/opcodes.c index 792b92f7c..4ec25f3bd 100644 --- a/src/cc65/opcodes.c +++ b/src/cc65/opcodes.c @@ -63,21 +63,21 @@ const OPCDesc OPCTable[OP65_COUNT] = { 0, /* size */ REG_A, /* use */ REG_A, /* chg */ - OF_SETF /* flags */ + OF_SETF | OF_READ /* flags */ }, { OP65_AND, /* opcode */ "and", /* mnemonic */ 0, /* size */ REG_A, /* use */ REG_A, /* chg */ - OF_SETF /* flags */ + OF_SETF | OF_READ /* flags */ }, { OP65_ASL, /* opcode */ "asl", /* mnemonic */ 0, /* size */ REG_NONE, /* use */ REG_NONE, /* chg */ - OF_SETF | OF_NOIMP /* flags */ + OF_SETF | OF_NOIMP | OF_RMW /* flags */ }, { OP65_BCC, /* opcode */ "bcc", /* mnemonic */ @@ -105,7 +105,7 @@ const OPCDesc OPCTable[OP65_COUNT] = { 0, /* size */ REG_A, /* use */ REG_NONE, /* chg */ - OF_SETF /* flags */ + OF_READ /* flags */ }, { OP65_BMI, /* opcode */ "bmi", /* mnemonic */ @@ -189,21 +189,21 @@ const OPCDesc OPCTable[OP65_COUNT] = { 0, /* size */ REG_A, /* use */ REG_NONE, /* chg */ - OF_SETF | OF_CMP /* flags */ + OF_SETF | OF_CMP | OF_READ /* flags */ }, { OP65_CPX, /* opcode */ "cpx", /* mnemonic */ 0, /* size */ REG_X, /* use */ REG_NONE, /* chg */ - OF_SETF | OF_CMP /* flags */ + OF_SETF | OF_CMP | OF_READ /* flags */ }, { OP65_CPY, /* opcode */ "cpy", /* mnemonic */ 0, /* size */ REG_Y, /* use */ REG_NONE, /* chg */ - OF_SETF | OF_CMP /* flags */ + OF_SETF | OF_CMP | OF_READ /* flags */ }, { OP65_DEA, /* opcode */ "dea", /* mnemonic */ @@ -217,7 +217,7 @@ const OPCDesc OPCTable[OP65_COUNT] = { 0, /* size */ REG_NONE, /* use */ REG_NONE, /* chg */ - OF_SETF | OF_NOIMP /* flags */ + OF_SETF | OF_NOIMP | OF_RMW /* flags */ }, { OP65_DEX, /* opcode */ "dex", /* mnemonic */ @@ -238,7 +238,7 @@ const OPCDesc OPCTable[OP65_COUNT] = { 0, /* size */ REG_A, /* use */ REG_A, /* chg */ - OF_SETF /* flags */ + OF_SETF | OF_READ /* flags */ }, { OP65_INA, /* opcode */ "ina", /* mnemonic */ @@ -252,7 +252,7 @@ const OPCDesc OPCTable[OP65_COUNT] = { 0, /* size */ REG_NONE, /* use */ REG_NONE, /* chg */ - OF_SETF | OF_NOIMP /* flags */ + OF_SETF | OF_NOIMP | OF_RMW /* flags */ }, { OP65_INX, /* opcode */ "inx", /* mnemonic */ @@ -301,7 +301,7 @@ const OPCDesc OPCTable[OP65_COUNT] = { 3, /* size */ REG_NONE, /* use */ REG_NONE, /* chg */ - OF_UBRA | OF_LBRA /* flags */ + OF_UBRA | OF_LBRA | OF_READ /* flags */ }, { OP65_JNE, /* opcode */ "jne", /* mnemonic */ @@ -322,7 +322,7 @@ const OPCDesc OPCTable[OP65_COUNT] = { 3, /* size */ REG_NONE, /* use */ REG_NONE, /* chg */ - OF_CALL /* flags */ + OF_CALL | OF_READ /* flags */ }, { OP65_JVC, /* opcode */ "jvc", /* mnemonic */ @@ -343,28 +343,28 @@ const OPCDesc OPCTable[OP65_COUNT] = { 0, /* size */ REG_NONE, /* use */ REG_A, /* chg */ - OF_LOAD | OF_SETF /* flags */ + OF_LOAD | OF_SETF | OF_READ /* flags */ }, { OP65_LDX, /* opcode */ "ldx", /* mnemonic */ 0, /* size */ REG_NONE, /* use */ REG_X, /* chg */ - OF_LOAD | OF_SETF /* flags */ + OF_LOAD | OF_SETF | OF_READ /* flags */ }, { OP65_LDY, /* opcode */ "ldy", /* mnemonic */ 0, /* size */ REG_NONE, /* use */ REG_Y, /* chg */ - OF_LOAD | OF_SETF /* flags */ + OF_LOAD | OF_SETF | OF_READ /* flags */ }, { OP65_LSR, /* opcode */ "lsr", /* mnemonic */ 0, /* size */ REG_NONE, /* use */ REG_NONE, /* chg */ - OF_SETF | OF_NOIMP /* flags */ + OF_SETF | OF_NOIMP | OF_RMW /* flags */ }, { OP65_NOP, /* opcode */ "nop", /* mnemonic */ @@ -378,7 +378,7 @@ const OPCDesc OPCTable[OP65_COUNT] = { 0, /* size */ REG_A, /* use */ REG_A, /* chg */ - OF_SETF /* flags */ + OF_SETF | OF_READ /* flags */ }, { OP65_PHA, /* opcode */ "pha", /* mnemonic */ @@ -441,14 +441,14 @@ const OPCDesc OPCTable[OP65_COUNT] = { 0, /* size */ REG_NONE, /* use */ REG_NONE, /* chg */ - OF_SETF | OF_NOIMP /* flags */ + OF_SETF | OF_NOIMP | OF_RMW /* flags */ }, { OP65_ROR, /* opcode */ "ror", /* mnemonic */ 0, /* size */ REG_NONE, /* use */ REG_NONE, /* chg */ - OF_SETF | OF_NOIMP /* flags */ + OF_SETF | OF_NOIMP | OF_RMW /* flags */ }, /* Mark RTI as "uses all registers but doesn't change them", so the ** optimizer won't remove preceeding loads. @@ -472,7 +472,7 @@ const OPCDesc OPCTable[OP65_COUNT] = { 0, /* size */ REG_A, /* use */ REG_A, /* chg */ - OF_SETF /* flags */ + OF_SETF | OF_READ /* flags */ }, { OP65_SEC, /* opcode */ "sec", /* mnemonic */ @@ -500,7 +500,7 @@ const OPCDesc OPCTable[OP65_COUNT] = { 0, /* size */ REG_A, /* use */ REG_NONE, /* chg */ - OF_STORE /* flags */ + OF_STORE | OF_WRITE /* flags */ }, { OP65_STP, /* opcode */ "stp", /* mnemonic */ @@ -514,21 +514,21 @@ const OPCDesc OPCTable[OP65_COUNT] = { 0, /* size */ REG_X, /* use */ REG_NONE, /* chg */ - OF_STORE /* flags */ + OF_STORE | OF_WRITE /* flags */ }, { OP65_STY, /* opcode */ "sty", /* mnemonic */ 0, /* size */ REG_Y, /* use */ REG_NONE, /* chg */ - OF_STORE /* flags */ + OF_STORE | OF_WRITE /* flags */ }, { OP65_STZ, /* opcode */ "stz", /* mnemonic */ 0, /* size */ REG_NONE, /* use */ REG_NONE, /* chg */ - OF_STORE /* flags */ + OF_STORE | OF_WRITE /* flags */ }, { OP65_TAX, /* opcode */ "tax", /* mnemonic */ @@ -549,14 +549,14 @@ const OPCDesc OPCTable[OP65_COUNT] = { 0, /* size */ REG_A, /* use */ REG_NONE, /* chg */ - OF_SETF /* flags */ + OF_RMW /* flags */ }, { OP65_TSB, /* opcode */ "tsb", /* mnemonic */ 0, /* size */ REG_A, /* use */ REG_NONE, /* chg */ - OF_SETF /* flags */ + OF_RMW /* flags */ }, { OP65_TSX, /* opcode */ "tsx", /* mnemonic */ diff --git a/src/cc65/opcodes.h b/src/cc65/opcodes.h index 24a289c26..162647eff 100644 --- a/src/cc65/opcodes.h +++ b/src/cc65/opcodes.h @@ -176,13 +176,16 @@ typedef enum { #define OF_XFR 0x0100U /* Transfer instruction */ #define OF_CALL 0x0200U /* A subroutine call */ #define OF_REG_INCDEC 0x0400U /* A register increment or decrement */ -#define OF_SETF 0x0800U /* Insn will set all load flags (not carry) */ +#define OF_SETF 0x0800U /* Insn will set both Z and N flags according to the result */ #define OF_CMP 0x1000U /* A compare A/X/Y instruction */ #define OF_NOIMP 0x2000U /* Implicit addressing mode is actually A */ +#define OF_READ 0x4000U /* Read from the memory address */ +#define OF_WRITE 0x8000U /* Write to the memory address */ /* Combined infos */ #define OF_BRA (OF_UBRA | OF_CBRA) /* Operation is a jump/branch */ #define OF_DEAD (OF_UBRA | OF_RET) /* Dead end - no exec behind this point */ +#define OF_RMW (OF_READ | OF_WRITE) /* Read, Modify and Write */ /* Opcode description */ typedef struct { From b8ae5c28fe18ba5d5e0791eecded61d0a16f0d0e Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 8 Sep 2020 23:41:04 +0800 Subject: [PATCH 1694/2161] Added debug output support for processor flags. --- src/cc65/codeent.c | 60 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index d54be039a..0f537bbaf 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -50,6 +50,7 @@ #include "codelab.h" #include "opcodes.h" #include "output.h" +#include "reginfo.h" @@ -1901,6 +1902,7 @@ static char* RegInfoDesc (unsigned U, char* Buf) strcat (Buf, U & REG_PTR2? "2" : "_"); strcat (Buf, U & REG_SAVE? "V" : "_"); strcat (Buf, U & REG_SP? "S" : "_"); + sprintf (Buf + 10, "_%02X", (U & PSTATE_ALL) >> PSTATE_BITS_SHIFT); return Buf; } @@ -1925,11 +1927,59 @@ static char* RegContentDesc (const RegContents* RC, char* Buf) } B += 5; if (RegValIsUnknown (RC->RegY)) { - strcpy (B, "Y:XX"); + strcpy (B, "Y:XX "); } else { - sprintf (B, "Y:%02X", RC->RegY); + sprintf (B, "Y:%02X ", RC->RegY); } - B += 4; + B += 5; + if (PStatesAreUnknown (RC->PFlags, PSTATE_C)) { + strcpy (B, "~"); + } else { + strcpy (B, RC->PFlags & PFVAL_C ? "C" : "_"); + } + B += 1; + if (PStatesAreUnknown (RC->PFlags, PSTATE_Z)) { + strcpy (B, "~"); + } else { + strcpy (B, RC->PFlags & PFVAL_Z ? "Z" : "_"); + } + B += 1; + if (PStatesAreUnknown (RC->PFlags, PSTATE_I)) { + strcpy (B, "~"); + } else { + strcpy (B, RC->PFlags & PFVAL_I ? "I" : "_"); + } + B += 1; + if (PStatesAreUnknown (RC->PFlags, PSTATE_D)) { + strcpy (B, "~"); + } else { + strcpy (B, RC->PFlags & PFVAL_D ? "D" : "_"); + } + B += 1; + if (PStatesAreUnknown (RC->PFlags, PSTATE_U)) { + strcpy (B, "~"); + } else { + strcpy (B, RC->PFlags & PFVAL_U ? "U" : "_"); + } + B += 1; + if (PStatesAreUnknown (RC->PFlags, PSTATE_B)) { + strcpy (B, "~"); + } else { + strcpy (B, RC->PFlags & PFVAL_B ? "B" : "_"); + } + B += 1; + if (PStatesAreUnknown (RC->PFlags, PSTATE_V)) { + strcpy (B, "~"); + } else { + strcpy (B, RC->PFlags & PFVAL_V ? "V" : "_"); + } + B += 1; + if (PStatesAreUnknown (RC->PFlags, PSTATE_N)) { + strcpy (B, "~"); + } else { + strcpy (B, RC->PFlags & PFVAL_N ? "N" : "_"); + } + B += 1; return Buf; } @@ -2024,7 +2074,7 @@ void CE_Output (const CodeEntry* E) if (Debug) { char Use [128]; char Chg [128]; - WriteOutput ("%*s; USE: %-12s CHG: %-12s SIZE: %u", + WriteOutput ("%*s; USE: %-15s CHG: %-15s SIZE: %u", (int)(30-Chars), "", RegInfoDesc (E->Use, Use), RegInfoDesc (E->Chg, Chg), @@ -2033,7 +2083,7 @@ void CE_Output (const CodeEntry* E) if (E->RI) { char RegIn[32]; char RegOut[32]; - WriteOutput (" In %s Out %s", + WriteOutput (" In %s Out %s", RegContentDesc (&E->RI->In, RegIn), RegContentDesc (&E->RI->Out, RegOut)); } From 0482e4d6e4e2bcba3116e2eee9a98e3d374b28f5 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Fri, 18 Sep 2020 08:42:56 +0200 Subject: [PATCH 1695/2161] Fix CRLFs introduced by fe3f267 --- libsrc/runtime/bcast.s | 42 ++++++++++++++++++++--------------------- libsrc/runtime/lbcast.s | 40 +++++++++++++++++++-------------------- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/libsrc/runtime/bcast.s b/libsrc/runtime/bcast.s index bb37b6ec0..bc228d1b7 100644 --- a/libsrc/runtime/bcast.s +++ b/libsrc/runtime/bcast.s @@ -1,21 +1,21 @@ -; -; acqn, 01.16.2020 -; -; CC65 runtime: boolean cast -; - - .export bcasta, bcastax - -bcastax: - cpx #0 - bne L1 - -bcasta: - tax - beq L0 ; Zero already in X - -L1: ldx #0 - lda #1 - -L0: rts - +; +; acqn, 01.16.2020 +; +; CC65 runtime: boolean cast +; + + .export bcasta, bcastax + +bcastax: + cpx #0 + bne L1 + +bcasta: + tax + beq L0 ; Zero already in X + +L1: ldx #0 + lda #1 + +L0: rts + diff --git a/libsrc/runtime/lbcast.s b/libsrc/runtime/lbcast.s index 3dee8d956..208442c44 100644 --- a/libsrc/runtime/lbcast.s +++ b/libsrc/runtime/lbcast.s @@ -1,20 +1,20 @@ -; -; acqn, 01.16.2020 -; -; CC65 runtime: boolean cast for longs -; - - .export bcasteax - .importzp sreg, tmp1 - -bcasteax: - stx tmp1 - ldx #0 ; High byte of result - ora tmp1 - ora sreg - ora sreg+1 - beq L0 - - lda #1 -L0: rts - +; +; acqn, 01.16.2020 +; +; CC65 runtime: boolean cast for longs +; + + .export bcasteax + .importzp sreg, tmp1 + +bcasteax: + stx tmp1 + ldx #0 ; High byte of result + ora tmp1 + ora sreg + ora sreg+1 + beq L0 + + lda #1 +L0: rts + From 86ced2bd4c35087c118c6a48bdbe7be555ff4a1c Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 13 Sep 2020 17:01:57 +0800 Subject: [PATCH 1696/2161] Avoided unnecessarily boosting the code label numbers with boolean AND. --- src/cc65/expr.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 826e72b09..a88710f34 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3237,8 +3237,8 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) int HasFalseJump = 0, HasTrueJump = 0; CodeMark Start; - /* Get a label that we will use for false expressions */ - int FalseLab = GetLocalLabel (); + /* The label that we will use for false expressions */ + int FalseLab = 0; /* Get lhs */ GetCodePos (&Start); @@ -3266,8 +3266,12 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) /* Clear the test flag */ ED_RequireNoTest (Expr); - /* Remember that the jump is used */ - HasFalseJump = 1; + if (HasFalseJump == 0) { + /* Remember that the jump is used */ + HasFalseJump = 1; + /* Get a label for false expressions */ + FalseLab = GetLocalLabel (); + } /* Generate the jump */ g_falsejump (CF_NONE, FalseLab); @@ -3304,7 +3308,12 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) /* Do short circuit evaluation */ if (CurTok.Tok == TOK_BOOL_AND) { - HasFalseJump = 1; + if (HasFalseJump == 0) { + /* Remember that the jump is used */ + HasFalseJump = 1; + /* Get a label for false expressions */ + FalseLab = GetLocalLabel (); + } g_falsejump (CF_NONE, FalseLab); } else { /* We need the true label for the last expression */ From d02b12fa6c18259b2e8ca82bbff79cd06a6d6359 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 23 Aug 2020 01:35:18 +0800 Subject: [PATCH 1697/2161] Made local code/data labels really local to the functions where they live in. --- src/cc65/asmlabel.c | 37 +++++++++++++++++++++++++++---------- src/cc65/asmlabel.h | 15 ++++++++++++++- src/cc65/compile.c | 9 +++++++++ src/cc65/function.c | 16 +++++++++++++++- src/cc65/function.h | 3 +++ src/cc65/segments.c | 14 ++++++++------ src/cc65/segments.h | 2 ++ 7 files changed, 78 insertions(+), 18 deletions(-) diff --git a/src/cc65/asmlabel.c b/src/cc65/asmlabel.c index f561036ce..7d5db75e6 100644 --- a/src/cc65/asmlabel.c +++ b/src/cc65/asmlabel.c @@ -42,6 +42,17 @@ /* cc65 */ #include "asmlabel.h" #include "error.h" +#include "segments.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +static struct Segments* CurrentFunctionSegment; @@ -51,19 +62,26 @@ -unsigned GetLocalLabel (void) -/* Get an unused label. Will never return zero. */ +void UseLabelPoolFromSegments (struct Segments* Seg) +/* Use the info in segments for generating new label numbers */ { - /* Number to generate unique labels */ - static unsigned NextLabel = 0; + CurrentFunctionSegment = Seg; +} + + + +unsigned GetLocalLabel (void) +/* Get an unused assembler label for the function. Will never return zero. */ +{ + PRECONDITION (CurrentFunctionSegment != 0); /* Check for an overflow */ - if (NextLabel >= 0xFFFF) { + if (CurrentFunctionSegment->NextLabel >= 0xFFFF) { Internal ("Local label overflow"); } /* Return the next label */ - return ++NextLabel; + return ++CurrentFunctionSegment->NextLabel; } @@ -104,16 +122,15 @@ int IsLocalLabelName (const char* Name) unsigned GetLocalDataLabel (void) /* Get an unused local data label. Will never return zero. */ { - /* Number to generate unique labels */ - static unsigned NextLabel = 0; + PRECONDITION (CurrentFunctionSegment != 0); /* Check for an overflow */ - if (NextLabel >= 0xFFFF) { + if (CurrentFunctionSegment->NextDataLabel >= 0xFFFF) { Internal ("Local data label overflow"); } /* Return the next label */ - return ++NextLabel; + return ++CurrentFunctionSegment->NextDataLabel; } diff --git a/src/cc65/asmlabel.h b/src/cc65/asmlabel.h index a79071400..dbfe2f443 100644 --- a/src/cc65/asmlabel.h +++ b/src/cc65/asmlabel.h @@ -38,14 +38,27 @@ +/*****************************************************************************/ +/* Forwards */ +/*****************************************************************************/ + + + +struct Segments; + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ +void UseLabelPoolFromSegments (struct Segments* Seg); +/* Use the info in segments for generating new label numbers */ + unsigned GetLocalLabel (void); -/* Get an unused assembler label. Will never return zero. */ +/* Get an unused assembler label for the function. Will never return zero. */ const char* LocalLabelName (unsigned L); /* Make a label name from the given label number. The label name will be diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 3296968f6..00e78c2bd 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -389,6 +389,12 @@ void Compile (const char* FileName) /* Create the global code and data segments */ CreateGlobalSegments (); + /* There shouldn't be needs for local labels outside a function, but the + ** current code generator still tries to get some at times even though the + ** code were ill-formed. So just set it up with the global segment list. + */ + UseLabelPoolFromSegments (GS); + /* Initialize the literal pool */ InitLiteralPool (); @@ -488,6 +494,9 @@ void FinishCompile (void) */ for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) { if (SymIsOutputFunc (Entry)) { + /* Continue with previous label numbers */ + UseLabelPoolFromSegments (Entry->V.F.Seg); + /* Function which is defined and referenced or extern */ MoveLiteralPool (Entry->V.F.LitPool); CS_MergeLabels (Entry->V.F.Seg->Code); diff --git a/src/cc65/function.c b/src/cc65/function.c index 9d4f8c2f9..00755ae65 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -83,7 +83,7 @@ static Function* NewFunction (struct SymEntry* Sym, FuncDesc* D) F->ReturnType = GetFuncReturn (Sym->Type); F->Desc = D; F->Reserved = 0; - F->RetLab = GetLocalLabel (); + F->RetLab = 0; F->TopLevelSP = 0; F->RegOffs = RegisterSpace; F->Flags = IsTypeVoid (F->ReturnType) ? FF_VOID_RETURN : FF_NONE; @@ -255,6 +255,14 @@ int F_HasOldStyleIntRet (const Function* F) +void F_SetRetLab (Function* F, unsigned NewRetLab) +/* Change the return jump label */ +{ + F->RetLab = NewRetLab; +} + + + unsigned F_GetRetLab (const Function* F) /* Return the return jump label */ { @@ -540,6 +548,12 @@ void NewFunc (SymEntry* Func, FuncDesc* D) /* Allocate code and data segments for this function */ Func->V.F.Seg = PushSegments (Func); + /* Use the info in the segments for generating new local labels */ + UseLabelPoolFromSegments (Func->V.F.Seg); + + /* Set return label. This has to be done after the segments are pushed */ + F_SetRetLab (CurrentFunc, GetLocalLabel ()); + /* Allocate a new literal pool */ PushLiteralPool (Func); diff --git a/src/cc65/function.h b/src/cc65/function.h index e0b7ef0a2..825257a60 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -120,6 +120,9 @@ int F_IsOldStyle (const Function* F); int F_HasOldStyleIntRet (const Function* F); /* Return true if this is an old style (K&R) function with an implicit int return */ +void F_SetRetLab (Function* F, unsigned NewRetLab); +/* Change the return jump label */ + unsigned F_GetRetLab (const Function* F); /* Return the return jump label */ diff --git a/src/cc65/segments.c b/src/cc65/segments.c index 6efbf68b7..7a9e32eb8 100644 --- a/src/cc65/segments.c +++ b/src/cc65/segments.c @@ -143,12 +143,14 @@ static Segments* NewSegments (SymEntry* Func) Segments* S = xmalloc (sizeof (Segments)); /* Initialize the fields */ - S->Text = NewTextSeg (Func); - S->Code = NewCodeSeg (GetSegName (SEG_CODE), Func); - S->Data = NewDataSeg (GetSegName (SEG_DATA), Func); - S->ROData = NewDataSeg (GetSegName (SEG_RODATA), Func); - S->BSS = NewDataSeg (GetSegName (SEG_BSS), Func); - S->CurDSeg = SEG_DATA; + S->Text = NewTextSeg (Func); + S->Code = NewCodeSeg (GetSegName (SEG_CODE), Func); + S->Data = NewDataSeg (GetSegName (SEG_DATA), Func); + S->ROData = NewDataSeg (GetSegName (SEG_RODATA), Func); + S->BSS = NewDataSeg (GetSegName (SEG_BSS), Func); + S->CurDSeg = SEG_DATA; + S->NextLabel = 0; + S->NextDataLabel = 0; /* Return the new struct */ return S; diff --git a/src/cc65/segments.h b/src/cc65/segments.h index f55be688b..777073559 100644 --- a/src/cc65/segments.h +++ b/src/cc65/segments.h @@ -86,6 +86,8 @@ struct Segments { struct DataSeg* ROData; /* Readonly data segment */ struct DataSeg* BSS; /* Segment for uninitialized data */ segment_t CurDSeg; /* Current data segment */ + unsigned NextLabel; /* Number to generate unique code labels */ + unsigned NextDataLabel; /* Number to generate unique data labels */ }; /* Pointer to the current segment list. Output goes here. */ From a7d6eb9190b8356597f008783e8aaa6121cf4f6b Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 13 Sep 2020 08:41:05 +0800 Subject: [PATCH 1698/2161] Added processor flag usage/change-tracking for non-JSR/RTS code entries. Some existing optimizations are impacted and need fixes in order to work correctly again. Fixed and improved OptPrecalc. Now it respects the C/V/Z/N flags. Fixed optimizations impacted by added support of tracking processor flags. --- src/cc65/codeent.c | 139 ++++++++++++++++++++++++++++++++++++++++++++ src/cc65/coptind.c | 121 +++++++++++++++++++++++++++----------- src/cc65/copttest.c | 2 +- 3 files changed, 228 insertions(+), 34 deletions(-) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index 0f537bbaf..195f7199f 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -206,6 +206,145 @@ static void SetUseChgInfo (CodeEntry* E, const OPCDesc* D) /* Keep gcc silent */ break; } + + /* Append processor flags as well as special usages */ + switch (E->OPC) { + + case OP65_ADC: + case OP65_SBC: + E->Use |= PSTATE_C; + E->Chg |= PSTATE_CZVN; + break; + case OP65_ROL: + case OP65_ROR: + E->Use |= PSTATE_C; + E->Chg |= PSTATE_CZN; + break; + case OP65_ASL: + case OP65_LSR: + E->Chg |= PSTATE_CZN; + break; + case OP65_CMP: + case OP65_CPX: + case OP65_CPY: + E->Chg |= PSTATE_CZN; + break; + case OP65_BIT: + E->Chg |= PSTATE_ZVN; + if (E->AM != AM65_IMM) { + E->Chg &= ~(PSTATE_V | PSTATE_N); + } + break; + case OP65_BRK: + E->Chg |= PSTATE_B; + break; + case OP65_CLC: + case OP65_SEC: + E->Chg |= PSTATE_C; + break; + case OP65_CLD: + case OP65_SED: + E->Chg |= PSTATE_D; + break; + case OP65_CLI: + case OP65_SEI: + E->Chg |= PSTATE_I; + break; + case OP65_CLV: + E->Chg |= PSTATE_V; + break; + case OP65_TRB: + case OP65_TSB: + E->Chg |= PSTATE_Z; + break; + case OP65_BCC: + case OP65_BCS: + case OP65_JCC: + case OP65_JCS: + E->Use |= PSTATE_C; + break; + case OP65_BEQ: + case OP65_BNE: + case OP65_JEQ: + case OP65_JNE: + E->Use |= PSTATE_Z; + break; + case OP65_BMI: + case OP65_BPL: + case OP65_JMI: + case OP65_JPL: + E->Use |= PSTATE_N; + break; + case OP65_BVC: + case OP65_BVS: + case OP65_JVC: + case OP65_JVS: + E->Use |= PSTATE_V; + break; + case OP65_BRA: + case OP65_JMP: + break; + case OP65_AND: + case OP65_EOR: + case OP65_ORA: + case OP65_DEA: + case OP65_DEC: + case OP65_DEX: + case OP65_DEY: + case OP65_INA: + case OP65_INC: + case OP65_INX: + case OP65_INY: + case OP65_LDA: + case OP65_LDX: + case OP65_LDY: + case OP65_TAX: + case OP65_TAY: + case OP65_TXA: + case OP65_TYA: + E->Chg |= PSTATE_ZN; + break; + case OP65_TSX: + E->Use |= SLV_SP65; + E->Chg |= PSTATE_ZN; + break; + case OP65_TXS: + E->Chg |= SLV_SP65; + break; + case OP65_PLA: + case OP65_PLX: + case OP65_PLY: + E->Use |= SLV_SP65; + E->Chg |= SLV_PL65 | PSTATE_ZN; + break; + case OP65_PLP: + E->Use |= SLV_SP65; + E->Chg |= SLV_PL65 | PSTATE_ALL; + break; + case OP65_PHA: + case OP65_PHX: + case OP65_PHY: + E->Use |= SLV_SP65; + E->Chg |= SLV_PH65; + break; + case OP65_PHP: + E->Use |= SLV_SP65 | PSTATE_ALL; + E->Chg |= SLV_PH65; + break; + case OP65_RTI: + E->Chg |= PSTATE_ALL; + break; + case OP65_RTS: + break; + case OP65_STA: + case OP65_STX: + case OP65_STY: + case OP65_STZ: + case OP65_JSR: + case OP65_NOP: + default: + break; + } } } diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index b506a21ca..eada61871 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -672,7 +672,7 @@ unsigned OptTransfers2 (CodeSeg* S) (N = CS_GetNextEntry (S, I)) != 0 && !CE_HasLabel (N) && (N->Info & OF_XFR) != 0 && - (GetRegInfo (S, I+2, E->Chg) & E->Chg) == 0) { + (GetRegInfo (S, I+2, E->Chg & REG_ALL) & E->Chg & REG_ALL) == 0) { CodeEntry* X = 0; @@ -796,7 +796,7 @@ unsigned OptTransfers3 (CodeSeg* S) } /* Does this insn change the target register of the transfer? */ - } else if (E->Chg & XferEntry->Chg) { + } else if (E->Chg & XferEntry->Chg & ~PSTATE_ZN) { /* We *may* add code here to remove the transfer, but I'm ** currently not sure about the consequences, so I won't @@ -823,8 +823,9 @@ unsigned OptTransfers3 (CodeSeg* S) ** isn't used later, and we have an address mode match, we can ** replace the transfer by a store and remove the store here. */ - if ((GetRegInfo (S, I, XferEntry->Chg) & XferEntry->Chg) == 0 && - (StoreEntry->AM == AM65_ABS || + if ((GetRegInfo (S, I, XferEntry->Chg & REG_ALL) & + XferEntry->Chg & REG_ALL) == 0 && + (StoreEntry->AM == AM65_ABS || StoreEntry->AM == AM65_ZP) && (StoreEntry->AM != AM65_ZP || (StoreEntry->Chg & UsedRegs) == 0) && @@ -973,7 +974,7 @@ unsigned OptTransfers4 (CodeSeg* S) } /* Does this insn change the target register of the load? */ - } else if (E->Chg & LoadEntry->Chg) { + } else if (E->Chg & LoadEntry->Chg & ~PSTATE_ZN) { /* We *may* add code here to remove the load, but I'm ** currently not sure about the consequences, so I won't @@ -989,9 +990,10 @@ unsigned OptTransfers4 (CodeSeg* S) ** isn't used later, and we have an address mode match, we can ** replace the transfer by a load and remove the initial load. */ - if ((GetRegInfo (S, I, LoadEntry->Chg) & LoadEntry->Chg) == 0 && - (LoadEntry->AM == AM65_ABS || - LoadEntry->AM == AM65_ZP || + if ((GetRegInfo (S, I, LoadEntry->Chg & REG_ALL) & + LoadEntry->Chg & REG_ALL) == 0 && + (LoadEntry->AM == AM65_ABS || + LoadEntry->AM == AM65_ZP || LoadEntry->AM == AM65_IMM) && !MemAccess (S, Load+1, Xfer-1, LoadEntry)) { @@ -1246,36 +1248,70 @@ unsigned OptPrecalc (CodeSeg* S) } break; - case OP65_EOR: - if (RegValIsKnown (Out->RegA)) { - /* Accu op zp with known contents */ - Arg = MakeHexArg (Out->RegA); - } - break; - case OP65_ADC: case OP65_SBC: - /* If this is an operation with an immediate operand of zero, - ** and the register is zero, the operation won't give us any - ** results we don't already have (including the flags), so - ** remove it. Something like this is generated as a result of - ** a compare where parts of the values are known to be zero. - ** The only situation where we need to leave things as they are - ** is when V flag is being tested in the next instruction, - ** because ADC/SBC #0 always clears it. - */ - if (In->RegA == 0 && CE_IsKnownImm (E, 0x00) && - (E = CS_GetEntry (S, I + 1)) && - E->OPC != OP65_BVC && - E->OPC != OP65_BVS ) { - /* 0-0 or 0+0 -> remove */ - CS_DelEntry (S, I); - ++Changes; + if (CE_IsKnownImm (E, 0x00)) { + /* If this is an operation with an immediate operand of zero, + ** and the Z/N flags reflect the current states of the content + ** in A, then the operation won't give us any results we don't + ** already have (including the flags) as long as the C flag is + ** set normally (cleared for ADC and set for SBC) for the + ** operation. So we can remove the operation if it is the + ** normal case or the result in A is not used later. + ** Something like this is generated as a result of a compare + ** where parts of the values are known to be zero. + ** The only situation where we need to leave things as they + ** are is when an indeterminate V flag is being tested later, + ** because ADC/SBC #0 always clears it. + */ + int CondC = PStatesAreKnown (In->PFlags, PSTATE_C) && + ((E->OPC == OP65_ADC && (In->PFlags & PFVAL_C) == 0) || + (E->OPC == OP65_SBC && (In->PFlags & PFVAL_C) != 0)); + int CondV = PStatesAreKnown (In->PFlags, PSTATE_V) && (In->PFlags & PFVAL_V) == 0; + int CondZN = (In->ZNRegs & ZNREG_A) != 0; + unsigned R = 0; + if (CondC) { + R = (CondV ? 0 : PSTATE_V) | (CondZN ? 0 : PSTATE_ZN); + } else { + R = REG_A | PSTATE_CZVN; + } + if (R != 0) { + /* Collect info on all flags in one round to save time */ + R = GetRegInfo (S, I + 1, R); + } + CondV = (CondC && CondV) || (R & PSTATE_V) == 0; + CondZN = (CondC && CondZN) || (R & PSTATE_ZN) == 0; + /* This is done last as it could change the info used by the two above */ + CondC = CondC || (R & (REG_A | PSTATE_C)) == 0; + if (CondC && CondV && CondZN) { + /* ?+0, ?-0 or result unused -> remove */ + CS_DelEntry (S, I); + ++Changes; + } + } else if (E->OPC == OP65_ADC && In->RegA == 0) { + /* 0 + arg. In this case we need only care about the C/V flags and + ** let the load set the Z/N flags properly. + */ + int CondC = PStatesAreClear (In->PFlags, PSTATE_C); + int CondV = PStatesAreClear (In->PFlags, PSTATE_V); + unsigned R = (CondC ? 0 : REG_A | PSTATE_C) | (CondC && CondV ? 0 : PSTATE_V); + if (R) { + R = GetRegInfo (S, I + 1, R); + } + CondV = (CondC && CondV) || (R & PSTATE_V) == 0; + CondC = CondC || (R & (REG_A | PSTATE_C)) == 0; + if (CondC && CondV) { + /* 0 + arg -> replace with lda arg */ + CE_ReplaceOPC (E, OP65_LDA); + ++Changes; + } } break; case OP65_AND: - if (CE_IsKnownImm (E, 0xFF)) { + if (CE_IsKnownImm (E, 0xFF) && + ((In->ZNRegs & ZNREG_A) != 0 || + (GetRegInfo (S, I + 1, PSTATE_ZN) & PSTATE_ZN) == 0)) { /* AND with 0xFF, remove */ CS_DelEntry (S, I); ++Changes; @@ -1293,7 +1329,9 @@ unsigned OptPrecalc (CodeSeg* S) break; case OP65_ORA: - if (CE_IsKnownImm (E, 0x00)) { + if (CE_IsKnownImm (E, 0x00) && + ((In->ZNRegs & ZNREG_A) != 0 || + (GetRegInfo (S, I + 1, PSTATE_ZN) & PSTATE_ZN) == 0)) { /* ORA with zero, remove */ CS_DelEntry (S, I); ++Changes; @@ -1310,6 +1348,23 @@ unsigned OptPrecalc (CodeSeg* S) } break; + case OP65_EOR: + if (CE_IsKnownImm (E, 0x00) && + ((In->ZNRegs & ZNREG_A) != 0 || + (GetRegInfo (S, I + 1, PSTATE_ZN) & PSTATE_ZN) == 0)) { + /* EOR with zero, remove */ + CS_DelEntry (S, I); + ++Changes; + } else if (RegValIsKnown (Out->RegA)) { + /* Accu op zp with known contents */ + Arg = MakeHexArg (Out->RegA); + } else if (In->RegA == 0) { + /* EOR but A contains 0x00 - replace by lda */ + CE_ReplaceOPC (E, OP65_LDA); + ++Changes; + } + break; + default: break; diff --git a/src/cc65/copttest.c b/src/cc65/copttest.c index 5628a42c3..f2d55244f 100644 --- a/src/cc65/copttest.c +++ b/src/cc65/copttest.c @@ -153,7 +153,7 @@ unsigned OptTest2 (CodeSeg* S) (L[2]->Info & OF_FBRA) != 0 && L[1]->AM == L[0]->AM && strcmp (L[0]->Arg, L[1]->Arg) == 0 && - (GetRegInfo (S, I+2, L[1]->Chg) & L[1]->Chg) == 0) { + (GetRegInfo (S, I+2, L[1]->Chg & ~PSTATE_ZN) & L[1]->Chg & ~PSTATE_ZN) == 0) { /* Remove the load */ CS_DelEntry (S, I+1); From 079f4a99dd32444d95fd916dca966827c6a07b65 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 13 Sep 2020 09:14:51 +0800 Subject: [PATCH 1699/2161] Added processor state info to the OPCDesc table. However, since some opcodes are affected by the addressing mode, this info is unused in codegen/optimizer but just as quick in-code documentation/hints. --- src/cc65/opcodes.c | 342 ++++++++++++++++++++++----------------------- src/cc65/opcodes.h | 4 +- 2 files changed, 173 insertions(+), 173 deletions(-) diff --git a/src/cc65/opcodes.c b/src/cc65/opcodes.c index 4ec25f3bd..3c02c84c4 100644 --- a/src/cc65/opcodes.c +++ b/src/cc65/opcodes.c @@ -61,394 +61,394 @@ const OPCDesc OPCTable[OP65_COUNT] = { { OP65_ADC, /* opcode */ "adc", /* mnemonic */ 0, /* size */ - REG_A, /* use */ - REG_A, /* chg */ - OF_SETF | OF_READ /* flags */ + OF_SETF | OF_READ, /* flags */ + REG_A | PSTATE_C, /* use */ + REG_A | PSTATE_CZVN /* chg */ }, { OP65_AND, /* opcode */ "and", /* mnemonic */ 0, /* size */ + OF_SETF | OF_READ, /* flags */ REG_A, /* use */ - REG_A, /* chg */ - OF_SETF | OF_READ /* flags */ + REG_A | PSTATE_ZN /* chg */ }, { OP65_ASL, /* opcode */ "asl", /* mnemonic */ 0, /* size */ + OF_SETF | OF_NOIMP | OF_RMW, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_SETF | OF_NOIMP | OF_RMW /* flags */ + PSTATE_CZN /* chg */ }, { OP65_BCC, /* opcode */ "bcc", /* mnemonic */ 2, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CBRA /* flags */ + OF_CBRA, /* flags */ + PSTATE_C, /* use */ + REG_NONE /* chg */ }, { OP65_BCS, /* opcode */ "bcs", /* mnemonic */ 2, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CBRA /* flags */ + OF_CBRA, /* flags */ + PSTATE_C, /* use */ + REG_NONE /* chg */ }, { OP65_BEQ, /* opcode */ "beq", /* mnemonic */ 2, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CBRA | OF_ZBRA | OF_FBRA /* flags */ + OF_CBRA | OF_ZBRA | OF_FBRA, /* flags */ + PSTATE_Z, /* use */ + REG_NONE /* chg */ }, { OP65_BIT, /* opcode */ "bit", /* mnemonic */ 0, /* size */ + OF_READ, /* flags */ REG_A, /* use */ - REG_NONE, /* chg */ - OF_READ /* flags */ + PSTATE_ZVN /* chg */ }, { OP65_BMI, /* opcode */ "bmi", /* mnemonic */ 2, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CBRA | OF_FBRA /* flags */ + OF_CBRA | OF_FBRA, /* flags */ + PSTATE_N, /* use */ + REG_NONE /* chg */ }, { OP65_BNE, /* opcode */ "bne", /* mnemonic */ 2, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CBRA | OF_ZBRA | OF_FBRA /* flags */ + OF_CBRA | OF_ZBRA | OF_FBRA, /* flags */ + PSTATE_Z, /* use */ + REG_NONE /* chg */ }, { OP65_BPL, /* opcode */ "bpl", /* mnemonic */ 2, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CBRA | OF_FBRA /* flags */ + OF_CBRA | OF_FBRA, /* flags */ + PSTATE_N, /* use */ + REG_NONE /* chg */ }, { OP65_BRA, /* opcode */ "bra", /* mnemonic */ 2, /* size */ + OF_UBRA, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_UBRA /* flags */ + REG_NONE /* chg */ }, { OP65_BRK, /* opcode */ "brk", /* mnemonic */ 1, /* size */ + OF_NONE, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_NONE /* flags */ + PSTATE_B /* chg */ }, { OP65_BVC, /* opcode */ "bvc", /* mnemonic */ 2, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CBRA /* flags */ + OF_CBRA, /* flags */ + PSTATE_V, /* use */ + REG_NONE /* chg */ }, { OP65_BVS, /* opcode */ "bvs", /* mnemonic */ 2, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CBRA /* flags */ + OF_CBRA, /* flags */ + PSTATE_V, /* use */ + REG_NONE /* chg */ }, { OP65_CLC, /* opcode */ "clc", /* mnemonic */ 1, /* size */ + OF_NONE, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_NONE /* flags */ + PSTATE_C /* chg */ }, { OP65_CLD, /* opcode */ "cld", /* mnemonic */ 1, /* size */ + OF_NONE, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_NONE /* flags */ + PSTATE_D /* chg */ }, { OP65_CLI, /* opcode */ "cli", /* mnemonic */ 1, /* size */ + OF_NONE, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_NONE /* flags */ + PSTATE_I /* chg */ }, { OP65_CLV, /* opcode */ "clv", /* mnemonic */ 1, /* size */ + OF_NONE, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_NONE /* flags */ + PSTATE_V /* chg */ }, { OP65_CMP, /* opcode */ "cmp", /* mnemonic */ 0, /* size */ + OF_SETF | OF_CMP | OF_READ, /* flags */ REG_A, /* use */ - REG_NONE, /* chg */ - OF_SETF | OF_CMP | OF_READ /* flags */ + PSTATE_CZN /* chg */ }, { OP65_CPX, /* opcode */ "cpx", /* mnemonic */ 0, /* size */ + OF_SETF | OF_CMP | OF_READ, /* flags */ REG_X, /* use */ - REG_NONE, /* chg */ - OF_SETF | OF_CMP | OF_READ /* flags */ + PSTATE_CZN /* chg */ }, { OP65_CPY, /* opcode */ "cpy", /* mnemonic */ 0, /* size */ + OF_SETF | OF_CMP | OF_READ, /* flags */ REG_Y, /* use */ - REG_NONE, /* chg */ - OF_SETF | OF_CMP | OF_READ /* flags */ + PSTATE_CZN /* chg */ }, { OP65_DEA, /* opcode */ "dea", /* mnemonic */ 1, /* size */ + OF_REG_INCDEC | OF_SETF, /* flags */ REG_A, /* use */ - REG_A, /* chg */ - OF_REG_INCDEC | OF_SETF /* flags */ + REG_A | PSTATE_ZN /* chg */ }, { OP65_DEC, /* opcode */ "dec", /* mnemonic */ 0, /* size */ + OF_SETF | OF_NOIMP | OF_RMW, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_SETF | OF_NOIMP | OF_RMW /* flags */ + PSTATE_ZN /* chg */ }, { OP65_DEX, /* opcode */ "dex", /* mnemonic */ 1, /* size */ + OF_REG_INCDEC | OF_SETF, /* flags */ REG_X, /* use */ - REG_X, /* chg */ - OF_REG_INCDEC | OF_SETF /* flags */ + REG_X | PSTATE_ZN /* chg */ }, { OP65_DEY, /* opcode */ "dey", /* mnemonic */ 1, /* size */ + OF_REG_INCDEC | OF_SETF, /* flags */ REG_Y, /* use */ - REG_Y, /* chg */ - OF_REG_INCDEC | OF_SETF /* flags */ + REG_Y | PSTATE_ZN /* chg */ }, { OP65_EOR, /* opcode */ "eor", /* mnemonic */ 0, /* size */ + OF_SETF | OF_READ, /* flags */ REG_A, /* use */ - REG_A, /* chg */ - OF_SETF | OF_READ /* flags */ + REG_A | PSTATE_ZN /* chg */ }, { OP65_INA, /* opcode */ "ina", /* mnemonic */ 1, /* size */ + OF_REG_INCDEC | OF_SETF, /* flags */ REG_A, /* use */ - REG_A, /* chg */ - OF_REG_INCDEC | OF_SETF /* flags */ + REG_A | PSTATE_ZN /* chg */ }, { OP65_INC, /* opcode */ "inc", /* mnemonic */ 0, /* size */ + OF_SETF | OF_NOIMP | OF_RMW, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_SETF | OF_NOIMP | OF_RMW /* flags */ + PSTATE_ZN /* chg */ }, { OP65_INX, /* opcode */ "inx", /* mnemonic */ 1, /* size */ + OF_REG_INCDEC | OF_SETF, /* flags */ REG_X, /* use */ - REG_X, /* chg */ - OF_REG_INCDEC | OF_SETF /* flags */ + REG_X | PSTATE_ZN /* chg */ }, { OP65_INY, /* opcode */ "iny", /* mnemonic */ 1, /* size */ + OF_REG_INCDEC | OF_SETF, /* flags */ REG_Y, /* use */ - REG_Y, /* chg */ - OF_REG_INCDEC | OF_SETF /* flags */ + REG_Y | PSTATE_ZN /* chg */ }, { OP65_JCC, /* opcode */ "jcc", /* mnemonic */ 5, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CBRA | OF_LBRA /* flags */ + OF_CBRA | OF_LBRA, /* flags */ + PSTATE_C, /* use */ + REG_NONE /* chg */ }, { OP65_JCS, /* opcode */ "jcs", /* mnemonic */ 5, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CBRA | OF_LBRA /* flags */ + OF_CBRA | OF_LBRA, /* flags */ + PSTATE_C, /* use */ + REG_NONE /* chg */ }, { OP65_JEQ, /* opcode */ "jeq", /* mnemonic */ 5, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CBRA | OF_LBRA | OF_ZBRA | OF_FBRA /* flags */ + OF_CBRA | OF_LBRA | OF_ZBRA | OF_FBRA, /* flags */ + PSTATE_Z, /* use */ + REG_NONE /* chg */ }, { OP65_JMI, /* opcode */ "jmi", /* mnemonic */ 5, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CBRA | OF_LBRA | OF_FBRA /* flags */ + OF_CBRA | OF_LBRA | OF_FBRA, /* flags */ + PSTATE_N, /* use */ + REG_NONE /* chg */ }, { OP65_JMP, /* opcode */ "jmp", /* mnemonic */ 3, /* size */ + OF_UBRA | OF_LBRA | OF_READ, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_UBRA | OF_LBRA | OF_READ /* flags */ + REG_NONE /* chg */ }, { OP65_JNE, /* opcode */ "jne", /* mnemonic */ 5, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CBRA | OF_LBRA | OF_ZBRA | OF_FBRA /* flags */ + OF_CBRA | OF_LBRA | OF_ZBRA | OF_FBRA, /* flags */ + PSTATE_Z, /* use */ + REG_NONE /* chg */ }, { OP65_JPL, /* opcode */ "jpl", /* mnemonic */ 5, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CBRA | OF_LBRA | OF_FBRA /* flags */ + OF_CBRA | OF_LBRA | OF_FBRA, /* flags */ + PSTATE_N, /* use */ + REG_NONE /* chg */ }, { OP65_JSR, /* opcode */ "jsr", /* mnemonic */ 3, /* size */ + OF_CALL | OF_READ, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CALL | OF_READ /* flags */ + REG_NONE /* chg */ }, { OP65_JVC, /* opcode */ "jvc", /* mnemonic */ 5, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CBRA | OF_LBRA /* flags */ + OF_CBRA | OF_LBRA, /* flags */ + PSTATE_V, /* use */ + REG_NONE /* chg */ }, { OP65_JVS, /* opcode */ "jvs", /* mnemonic */ 5, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_CBRA | OF_LBRA /* flags */ + OF_CBRA | OF_LBRA, /* flags */ + PSTATE_V, /* use */ + REG_NONE /* chg */ }, { OP65_LDA, /* opcode */ "lda", /* mnemonic */ 0, /* size */ + OF_LOAD | OF_SETF | OF_READ, /* flags */ REG_NONE, /* use */ - REG_A, /* chg */ - OF_LOAD | OF_SETF | OF_READ /* flags */ + REG_A | PSTATE_ZN /* chg */ }, { OP65_LDX, /* opcode */ "ldx", /* mnemonic */ 0, /* size */ + OF_LOAD | OF_SETF | OF_READ, /* flags */ REG_NONE, /* use */ - REG_X, /* chg */ - OF_LOAD | OF_SETF | OF_READ /* flags */ + REG_X | PSTATE_ZN /* chg */ }, { OP65_LDY, /* opcode */ "ldy", /* mnemonic */ 0, /* size */ + OF_LOAD | OF_SETF | OF_READ, /* flags */ REG_NONE, /* use */ - REG_Y, /* chg */ - OF_LOAD | OF_SETF | OF_READ /* flags */ + REG_Y | PSTATE_ZN /* chg */ }, { OP65_LSR, /* opcode */ "lsr", /* mnemonic */ 0, /* size */ + OF_SETF | OF_NOIMP | OF_RMW, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_SETF | OF_NOIMP | OF_RMW /* flags */ + PSTATE_CZN /* chg */ }, { OP65_NOP, /* opcode */ "nop", /* mnemonic */ 1, /* size */ + OF_NONE, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_NONE /* flags */ + REG_NONE /* chg */ }, { OP65_ORA, /* opcode */ "ora", /* mnemonic */ 0, /* size */ + OF_SETF | OF_READ, /* flags */ REG_A, /* use */ - REG_A, /* chg */ - OF_SETF | OF_READ /* flags */ + REG_A | PSTATE_ZN /* chg */ }, { OP65_PHA, /* opcode */ "pha", /* mnemonic */ 1, /* size */ + OF_NONE, /* flags */ REG_A, /* use */ - REG_NONE, /* chg */ - OF_NONE /* flags */ + REG_NONE /* chg */ }, { OP65_PHP, /* opcode */ "php", /* mnemonic */ 1, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_NONE /* flags */ + OF_NONE, /* flags */ + PSTATE_ALL, /* use */ + REG_NONE /* chg */ }, { OP65_PHX, /* opcode */ "phx", /* mnemonic */ 1, /* size */ + OF_NONE, /* flags */ REG_X, /* use */ - REG_NONE, /* chg */ - OF_NONE /* flags */ + REG_NONE /* chg */ }, { OP65_PHY, /* opcode */ "phy", /* mnemonic */ 1, /* size */ + OF_NONE, /* flags */ REG_Y, /* use */ - REG_NONE, /* chg */ - OF_NONE /* flags */ + REG_NONE /* chg */ }, { OP65_PLA, /* opcode */ "pla", /* mnemonic */ 1, /* size */ + OF_SETF, /* flags */ REG_NONE, /* use */ - REG_A, /* chg */ - OF_SETF /* flags */ + REG_A | PSTATE_ZN /* chg */ }, { OP65_PLP, /* opcode */ "plp", /* mnemonic */ 1, /* size */ + OF_NONE, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_NONE /* flags */ + PSTATE_ALL /* chg */ }, { OP65_PLX, /* opcode */ "plx", /* mnemonic */ 1, /* size */ + OF_SETF, /* flags */ REG_NONE, /* use */ - REG_X, /* chg */ - OF_SETF /* flags */ + REG_X | PSTATE_ZN /* chg */ }, { OP65_PLY, /* opcode */ "ply", /* mnemonic */ 1, /* size */ + OF_SETF, /* flags */ REG_NONE, /* use */ - REG_Y, /* chg */ - OF_SETF /* flags */ + REG_Y | PSTATE_ZN /* chg */ }, { OP65_ROL, /* opcode */ "rol", /* mnemonic */ 0, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_SETF | OF_NOIMP | OF_RMW /* flags */ + OF_SETF | OF_NOIMP | OF_RMW, /* flags */ + PSTATE_C, /* use */ + PSTATE_CZN /* chg */ }, { OP65_ROR, /* opcode */ "ror", /* mnemonic */ 0, /* size */ - REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_SETF | OF_NOIMP | OF_RMW /* flags */ + OF_SETF | OF_NOIMP | OF_RMW, /* flags */ + PSTATE_C, /* use */ + PSTATE_CZN /* chg */ }, /* Mark RTI as "uses all registers but doesn't change them", so the ** optimizer won't remove preceeding loads. @@ -456,135 +456,135 @@ const OPCDesc OPCTable[OP65_COUNT] = { { OP65_RTI, /* opcode */ "rti", /* mnemonic */ 1, /* size */ + OF_RET, /* flags */ REG_AXY, /* use */ - REG_NONE, /* chg */ - OF_RET /* flags */ + PSTATE_ALL /* chg */ }, { OP65_RTS, /* opcode */ "rts", /* mnemonic */ 1, /* size */ + OF_RET, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_RET /* flags */ + REG_NONE /* chg */ }, { OP65_SBC, /* opcode */ "sbc", /* mnemonic */ 0, /* size */ - REG_A, /* use */ - REG_A, /* chg */ - OF_SETF | OF_READ /* flags */ + OF_SETF | OF_READ, /* flags */ + REG_A | PSTATE_C, /* use */ + REG_A | PSTATE_CZVN /* chg */ }, { OP65_SEC, /* opcode */ "sec", /* mnemonic */ 1, /* size */ + OF_NONE, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_NONE /* flags */ + PSTATE_C /* chg */ }, { OP65_SED, /* opcode */ "sed", /* mnemonic */ 1, /* size */ + OF_NONE, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_NONE /* flags */ + PSTATE_D /* chg */ }, { OP65_SEI, /* opcode */ "sei", /* mnemonic */ 1, /* size */ + OF_NONE, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_NONE /* flags */ + PSTATE_I /* chg */ }, { OP65_STA, /* opcode */ "sta", /* mnemonic */ 0, /* size */ + OF_STORE | OF_WRITE, /* flags */ REG_A, /* use */ - REG_NONE, /* chg */ - OF_STORE | OF_WRITE /* flags */ + REG_NONE /* chg */ }, { OP65_STP, /* opcode */ "stp", /* mnemonic */ 1, /* size */ + OF_NONE, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_NONE /* flags */ + REG_NONE /* chg */ }, { OP65_STX, /* opcode */ "stx", /* mnemonic */ 0, /* size */ + OF_STORE | OF_WRITE, /* flags */ REG_X, /* use */ - REG_NONE, /* chg */ - OF_STORE | OF_WRITE /* flags */ + REG_NONE /* chg */ }, { OP65_STY, /* opcode */ "sty", /* mnemonic */ 0, /* size */ + OF_STORE | OF_WRITE, /* flags */ REG_Y, /* use */ - REG_NONE, /* chg */ - OF_STORE | OF_WRITE /* flags */ + REG_NONE /* chg */ }, { OP65_STZ, /* opcode */ "stz", /* mnemonic */ 0, /* size */ + OF_STORE | OF_WRITE, /* flags */ REG_NONE, /* use */ - REG_NONE, /* chg */ - OF_STORE | OF_WRITE /* flags */ + REG_NONE /* chg */ }, { OP65_TAX, /* opcode */ "tax", /* mnemonic */ 1, /* size */ + OF_XFR | OF_SETF, /* flags */ REG_A, /* use */ - REG_X, /* chg */ - OF_XFR | OF_SETF /* flags */ + REG_X | PSTATE_ZN /* chg */ }, { OP65_TAY, /* opcode */ "tay", /* mnemonic */ 1, /* size */ + OF_XFR | OF_SETF, /* flags */ REG_A, /* use */ - REG_Y, /* chg */ - OF_XFR | OF_SETF /* flags */ + REG_Y | PSTATE_ZN /* chg */ }, { OP65_TRB, /* opcode */ "trb", /* mnemonic */ 0, /* size */ + OF_RMW, /* flags */ REG_A, /* use */ - REG_NONE, /* chg */ - OF_RMW /* flags */ + PSTATE_Z /* chg */ }, { OP65_TSB, /* opcode */ "tsb", /* mnemonic */ 0, /* size */ + OF_RMW, /* flags */ REG_A, /* use */ - REG_NONE, /* chg */ - OF_RMW /* flags */ + PSTATE_Z /* chg */ }, { OP65_TSX, /* opcode */ "tsx", /* mnemonic */ 1, /* size */ + OF_XFR | OF_SETF, /* flags */ REG_NONE, /* use */ - REG_X, /* chg */ - OF_XFR | OF_SETF /* flags */ + REG_X | PSTATE_ZN /* chg */ }, { OP65_TXA, /* opcode */ "txa", /* mnemonic */ 1, /* size */ + OF_XFR | OF_SETF, /* flags */ REG_X, /* use */ - REG_A, /* chg */ - OF_XFR | OF_SETF /* flags */ + REG_A | PSTATE_ZN /* chg */ }, { OP65_TXS, /* opcode */ "txs", /* mnemonic */ 1, /* size */ + OF_XFR, /* flags */ REG_X, /* use */ - REG_NONE, /* chg */ - OF_XFR /* flags */ + REG_NONE /* chg */ }, { OP65_TYA, /* opcode */ "tya", /* mnemonic */ 1, /* size */ + OF_XFR | OF_SETF, /* flags */ REG_Y, /* use */ - REG_A, /* chg */ - OF_XFR | OF_SETF /* flags */ + REG_A | PSTATE_ZN /* chg */ }, }; diff --git a/src/cc65/opcodes.h b/src/cc65/opcodes.h index 162647eff..980cc649a 100644 --- a/src/cc65/opcodes.h +++ b/src/cc65/opcodes.h @@ -192,9 +192,9 @@ typedef struct { opc_t OPC; /* Opcode */ char Mnemo[9]; /* Mnemonic */ unsigned char Size; /* Size, 0 = check addressing mode */ - unsigned short Use; /* Registers used by this insn */ - unsigned short Chg; /* Registers changed by this insn */ unsigned short Info; /* Additional information */ + unsigned int Use; /* Registers used by this insn */ + unsigned int Chg; /* Registers changed by this insn */ } OPCDesc; /* Opcode description table */ From de630a12452d76ac3ab9fd88482925d9428d8d5c Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 13 Sep 2020 09:15:07 +0800 Subject: [PATCH 1700/2161] Fixed quick hack for known registers after calling certain runtime functions, and new quick hack for tosshrax. --- src/cc65/codeent.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index 195f7199f..3de694829 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -1418,10 +1418,10 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->RegX = (In->RegX ^ 0xFF); } } else if (strcmp (E->Arg, "tosandax") == 0) { - if (In->RegA == 0) { + if (RegValIsKnown (In->RegA) && In->RegA == 0) { Out->RegA = 0; } - if (In->RegX == 0) { + if (RegValIsKnown (In->RegX) && In->RegX == 0) { Out->RegX = 0; } } else if (strcmp (E->Arg, "tosaslax") == 0) { @@ -1430,16 +1430,20 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) Out->RegA = 0; } } else if (strcmp (E->Arg, "tosorax") == 0) { - if (In->RegA == 0xFF) { + if (RegValIsKnown (In->RegA) && In->RegA == 0xFF) { Out->RegA = 0xFF; } - if (In->RegX == 0xFF) { + if (RegValIsKnown (In->RegX) && In->RegX == 0xFF) { Out->RegX = 0xFF; } } else if (strcmp (E->Arg, "tosshlax") == 0) { - if ((In->RegA & 0x0F) >= 8) { + if (RegValIsKnown (In->RegA) && (In->RegA & 0x0F) >= 8) { Out->RegA = 0; } + } else if (strcmp (E->Arg, "tosshrax") == 0) { + if (RegValIsKnown (In->RegA) && (In->RegA & 0x0F) >= 8) { + Out->RegX = 0; + } } else if (strcmp (E->Arg, "bcastax") == 0 || strcmp (E->Arg, "bnegax") == 0 || FindBoolCmpCond (E->Arg) != CMP_INV || From bf4b19501699fe1ab286878ff8c23f4296cf82d2 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 18 Sep 2020 15:50:26 -0400 Subject: [PATCH 1701/2161] Added some comments that explain where the g_branch() code generator can and can't be used. --- src/cc65/codegen.c | 6 ++++++ src/cc65/codegen.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 031e4e81a..cb448d738 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -2447,6 +2447,8 @@ void g_falsejump (unsigned flags attribute ((unused)), unsigned label) void g_branch (unsigned Label) /* Branch unconditionally to Label if the CPU has the BRA instruction. ** Otherwise, jump to Label. +** Use this function, instead of g_jump(), only where it is certain that +** the label cannot be farther away from the branch than -128/+127 bytes. */ { if ((CPUIsets[CPU] & CPU_ISET_65SC02) != 0) { @@ -4542,6 +4544,10 @@ void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, int IsSigned, AddCodeLine ("pla"); g_or (FullWidthFlags | CF_CONST, ~Mask); + /* We can generate a branch, instead of a jump, here because we know + ** that only a few instructions will be put between here and where + ** DoneLabel will be defined. + */ unsigned DoneLabel = GetLocalLabel (); g_branch (DoneLabel); diff --git a/src/cc65/codegen.h b/src/cc65/codegen.h index 3054a39b3..d6d3d2370 100644 --- a/src/cc65/codegen.h +++ b/src/cc65/codegen.h @@ -416,6 +416,8 @@ void g_falsejump (unsigned flags, unsigned label); void g_branch (unsigned Label); /* Branch unconditionally to Label if the CPU has the BRA instruction. ** Otherwise, jump to Label. +** Use this function, instead of g_jump(), only where it is certain that +** the label cannot be farther away from the branch than -128/+127 bytes. */ void g_lateadjustSP (unsigned label); From 0b64ca0d7dfba4e13f5b75634704415e77054b59 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 20 Sep 2020 16:09:58 -0400 Subject: [PATCH 1702/2161] Fixed the ld65 cx16 Assembly configuration file. The CODE segment immediately follows the EXEHDR segment. Added a segment for the zero-page area that's free when the BASIC ROM isn't used. --- cfg/cx16-asm.cfg | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cfg/cx16-asm.cfg b/cfg/cx16-asm.cfg index 3c24bd56f..c3c08aec3 100644 --- a/cfg/cx16-asm.cfg +++ b/cfg/cx16-asm.cfg @@ -1,22 +1,27 @@ +# Assembly configuration for R38 + FEATURES { STARTADDRESS: default = $0801; } SYMBOLS { __LOADADDR__: type = import; +# Putting "-u __EXEHDR__" on cl65's command line will add a BASIC RUN stub to your program. +# __EXEHDR__: type = import; __HIMEM__: type = weak, value = $9F00; } MEMORY { ZP: file = "", start = $0022, size = $0080 - $0022, define = yes; + ZP2: file = "", start = $00A9, size = $0100 - $00A9; LOADADDR: file = %O, start = %S - 2, size = $0002; MAIN: file = %O, start = %S, size = __HIMEM__ - %S; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = zp, optional = yes; + EXTZP: load = ZP2, type = zp, optional = yes; # OK if BASIC functions not used LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = MAIN, type = ro, optional = yes; - LOWCODE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; + LOWCODE: load = MAIN, type = ro, optional = yes; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; BSS: load = MAIN, type = bss, define = yes; From 41bd8d909b8b43a31187d9720a83b768096c153d Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 20 Sep 2020 19:55:25 -0400 Subject: [PATCH 1703/2161] Added ld65's bank attribute to the cx16 library's bank (overlay) configuration file. That attribute makes it easier for Assembly code to know which bank holds a label. --- cfg/cx16-bank.cfg | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/cfg/cx16-bank.cfg b/cfg/cx16-bank.cfg index 1f998f188..36b0edb02 100644 --- a/cfg/cx16-bank.cfg +++ b/cfg/cx16-bank.cfg @@ -19,35 +19,35 @@ MEMORY { # BRAM00ADDR: file = "%O.00", start = __BANKRAMSTART__ - 2, size = $0002; # BRAM00: file = "%O.00", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; BRAM01ADDR: file = "%O.01", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM01: file = "%O.01", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM01: file = "%O.01", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $01; BRAM02ADDR: file = "%O.02", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM02: file = "%O.02", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM02: file = "%O.02", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $02; BRAM03ADDR: file = "%O.03", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM03: file = "%O.03", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM03: file = "%O.03", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $03; BRAM04ADDR: file = "%O.04", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM04: file = "%O.04", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM04: file = "%O.04", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $04; BRAM05ADDR: file = "%O.05", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM05: file = "%O.05", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM05: file = "%O.05", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $05; BRAM06ADDR: file = "%O.06", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM06: file = "%O.06", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM06: file = "%O.06", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $06; BRAM07ADDR: file = "%O.07", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM07: file = "%O.07", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM07: file = "%O.07", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $07; BRAM08ADDR: file = "%O.08", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM08: file = "%O.08", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM08: file = "%O.08", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $08; BRAM09ADDR: file = "%O.09", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM09: file = "%O.09", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM09: file = "%O.09", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $09; BRAM0AADDR: file = "%O.0a", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0A: file = "%O.0a", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM0A: file = "%O.0a", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0A; BRAM0BADDR: file = "%O.0b", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0B: file = "%O.0b", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM0B: file = "%O.0b", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0B; BRAM0CADDR: file = "%O.0c", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0C: file = "%O.0c", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM0C: file = "%O.0c", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0C; BRAM0DADDR: file = "%O.0d", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0D: file = "%O.0d", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM0D: file = "%O.0d", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0D; BRAM0EADDR: file = "%O.0e", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0E: file = "%O.0e", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM0E: file = "%O.0e", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0E; BRAM0FADDR: file = "%O.0f", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0F: file = "%O.0f", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; + BRAM0F: file = "%O.0f", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0F; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; From dc147519542736efa003ec6a7e627eba86914640 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 22 Sep 2020 00:02:12 -0400 Subject: [PATCH 1704/2161] Exported the direct Kernal entries that were moved from target headers to "cbm_kernal.inc". --- libsrc/c128/kernal.s | 11 ++++++++++- libsrc/c16/kernal.s | 5 ++++- libsrc/c64/kernal.s | 7 ++++++- libsrc/vic20/kernal.s | 6 +++++- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/libsrc/c128/kernal.s b/libsrc/c128/kernal.s index f74ab3b1a..138473218 100644 --- a/libsrc/c128/kernal.s +++ b/libsrc/c128/kernal.s @@ -1,11 +1,20 @@ ; ; Ullrich von Bassewitz, 19.11.2002 ; -; C128 kernal functions +; C128 Kernal functions ; .include "cbm_kernal.inc" + .export KBDREAD + .export CLRSCR + .export PRINT + .export NEWLINE + .export CURS_SET + .export CURS_ON + .export CURS_OFF + .export NMIEXIT + .export C64MODE .export SWAPPER .export SETBNK diff --git a/libsrc/c16/kernal.s b/libsrc/c16/kernal.s index f814b2c1f..15ce35772 100644 --- a/libsrc/c16/kernal.s +++ b/libsrc/c16/kernal.s @@ -1,11 +1,14 @@ ; ; Ullrich von Bassewitz, 19.11.2002 ; -; C16 kernal functions +; C16 Kernal functions ; .include "cbm_kernal.inc" + .export CLRSCR + .export KBDREAD + .export CINT .export IOINIT .export RAMTAS diff --git a/libsrc/c64/kernal.s b/libsrc/c64/kernal.s index acbf22370..771872082 100644 --- a/libsrc/c64/kernal.s +++ b/libsrc/c64/kernal.s @@ -1,11 +1,16 @@ ; ; Ullrich von Bassewitz, 19.11.2002 ; -; C64 kernal functions +; C64 Kernal functions ; .include "cbm_kernal.inc" + .export CLRSCR + .export KBDREAD + .export UPDCRAMPTR + .export NMIEXIT + .export CINT .export IOINIT .export RAMTAS diff --git a/libsrc/vic20/kernal.s b/libsrc/vic20/kernal.s index ff16a019c..4539495b1 100644 --- a/libsrc/vic20/kernal.s +++ b/libsrc/vic20/kernal.s @@ -1,11 +1,15 @@ ; ; Ullrich von Bassewitz, 19.11.2002 ; -; VIC20 kernal functions +; VIC20 Kernal functions ; .include "cbm_kernal.inc" + .export CLRSCR + .export KBDREAD + .export UPDCRAMPTR + .export CINT .export IOINIT .export RAMTAS From d906204e84861149c363a82d205de4164271760c Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 22 Sep 2020 12:31:27 -0400 Subject: [PATCH 1705/2161] Allowed UPDCRAMPTR to be exported as a constuctor in the VIC-20 library. --- libsrc/vic20/kernal.s | 1 - 1 file changed, 1 deletion(-) diff --git a/libsrc/vic20/kernal.s b/libsrc/vic20/kernal.s index 4539495b1..94a5ec1a4 100644 --- a/libsrc/vic20/kernal.s +++ b/libsrc/vic20/kernal.s @@ -8,7 +8,6 @@ .export CLRSCR .export KBDREAD - .export UPDCRAMPTR .export CINT .export IOINIT From 07ea5259ac1cfe1ee2fcdd363fb75cc2cf251175 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 4 Sep 2020 12:06:42 -0400 Subject: [PATCH 1706/2161] Changed a cc65 error message to say that the sizes of bit-field types (not bit-fields) are limited. --- src/cc65/declare.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 8d0a1097c..6c001c117 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -762,11 +762,11 @@ static int ParseFieldWidth (Declaration* Decl) } /* TODO: This can be relaxed to be any integral type, but - ** ParseStructInit currently only supports up to int. + ** ParseStructInit currently supports only up to int. */ if (SizeOf (Decl->Type) > SizeOf (type_uint)) { - /* Only int-sized or smaller types may be used for bit-fields for now */ - Error ("cc65 currently only supports char-sized and int-sized bit-fields"); + /* Only int-sized or smaller types may be used for bit-fields, for now */ + Error ("cc65 currently supports only char-sized and int-sized bit-field types"); return -1; } From ea957283308d45dbde8001c3067d5a2f985b36fe Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 8 Sep 2020 11:51:51 -0400 Subject: [PATCH 1707/2161] Avoided an avalanche of messages from bad bit-field declarations. Made cc65 replace a bad bit-field type with a good one, and always parse the field width. Shortenned a parameter name to a spelling that's consistent with other function headers. --- src/cc65/declare.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 6c001c117..0f604d45e 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -744,7 +744,7 @@ static SymEntry* ParseEnumDecl (const char* Name, unsigned* DSFlags) -static int ParseFieldWidth (Declaration* Decl) +static int ParseFieldWidth (Declaration* D) /* Parse an optional field width. Returns -1 if no field width is specified, ** otherwise the width of the field. */ @@ -754,20 +754,26 @@ static int ParseFieldWidth (Declaration* Decl) return -1; } - if (!IsClassInt (Decl->Type)) { + if (!IsClassInt (D->Type)) { /* Only integer types may be used for bit-fields */ Error ("Bit-field has invalid type '%s', must be integral", - GetBasicTypeName (Decl->Type)); - return -1; + GetBasicTypeName (D->Type)); + + /* Avoid a diagnostic storm by giving the bit-field the widest valid + ** signed type, and continuing to parse. + */ + D->Type[0].C = T_INT; } /* TODO: This can be relaxed to be any integral type, but ** ParseStructInit currently supports only up to int. */ - if (SizeOf (Decl->Type) > SizeOf (type_uint)) { + if (SizeOf (D->Type) > SizeOf (type_uint)) { /* Only int-sized or smaller types may be used for bit-fields, for now */ Error ("cc65 currently supports only char-sized and int-sized bit-field types"); - return -1; + + /* Avoid a diagnostic storm */ + D->Type[0].C = T_INT; } /* Read the width */ @@ -778,11 +784,11 @@ static int ParseFieldWidth (Declaration* Decl) Error ("Negative width in bit-field"); return -1; } - if (Expr.IVal > (long)(SizeOf (Decl->Type) * CHAR_BITS)) { + if (Expr.IVal > (long)(SizeOf (D->Type) * CHAR_BITS)) { Error ("Width of bit-field exceeds its type"); return -1; } - if (Expr.IVal == 0 && Decl->Ident[0] != '\0') { + if (Expr.IVal == 0 && D->Ident[0] != '\0') { Error ("Zero width for named bit-field"); return -1; } @@ -818,7 +824,7 @@ static unsigned PadWithBitField (unsigned StructSize, unsigned BitOffs) -static unsigned AliasAnonStructFields (const Declaration* Decl, SymEntry* Anon) +static unsigned AliasAnonStructFields (const Declaration* D, SymEntry* Anon) /* Create alias fields from an anon union/struct in the current lexical level. ** The function returns the count of created aliases. */ @@ -827,7 +833,7 @@ static unsigned AliasAnonStructFields (const Declaration* Decl, SymEntry* Anon) SymEntry* Alias; /* Get the pointer to the symbol table entry of the anon struct */ - SymEntry* Entry = GetESUSymEntry (Decl->Type); + SymEntry* Entry = GetESUSymEntry (D->Type); /* Get the symbol table containing the fields. If it is empty, there has ** been an error before, so bail out. From 81ac28ff71b05bd829db36f544a144a83ad1d481 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 18 Sep 2020 16:33:12 -0400 Subject: [PATCH 1708/2161] Used TAY/TYA instead of PHA/PLA when extracting a bit-field. Without optimization, it saves a few CPU cycles. With optimization, it saves more cycles and a few bytes. --- src/cc65/codegen.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index cb448d738..bc85ba1de 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -4511,8 +4511,8 @@ void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, int IsSigned, /* Handle signed bit-fields. */ if (IsSigned) { - /* Push A, since the sign bit test will destroy it. */ - AddCodeLine ("pha"); + /* Save .A because the sign-bit test will destroy it. */ + AddCodeLine ("tay"); /* Check sign bit */ unsigned SignBitPos = BitWidth - 1U; @@ -4520,7 +4520,7 @@ void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, int IsSigned, unsigned SignBitPosInByte = SignBitPos % CHAR_BITS; unsigned SignBitMask = 1U << SignBitPosInByte; - /* Move the correct byte to A. This can only be X for now, + /* Move the correct byte to .A. This can be only .X for now, ** but more cases will be needed to support long. */ switch (SignBitByte) { @@ -4538,10 +4538,10 @@ void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, int IsSigned, unsigned ZeroExtendLabel = GetLocalLabel (); AddCodeLine ("beq %s", LocalLabelName (ZeroExtendLabel)); - /* Pop A back and sign-extend if required; operating on the full result needs - ** to sign-extend into high byte, too. + /* Get back .A and sign-extend if required; operating on the full result needs + ** to sign-extend into the high byte, too. */ - AddCodeLine ("pla"); + AddCodeLine ("tya"); g_or (FullWidthFlags | CF_CONST, ~Mask); /* We can generate a branch, instead of a jump, here because we know @@ -4551,11 +4551,11 @@ void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, int IsSigned, unsigned DoneLabel = GetLocalLabel (); g_branch (DoneLabel); - /* Pop A back, then zero-extend. We need to duplicate the PLA, rather than move it before - ** the branch to share with the other label, because PLA changes some condition codes. + /* Get back .A, then zero-extend. We need to duplicate the TYA, rather than move it before + ** the branch to share with the other label, because TYA changes some condition codes. */ g_defcodelabel (ZeroExtendLabel); - AddCodeLine ("pla"); + AddCodeLine ("tya"); /* Zero the upper bits, the same as the unsigned path. */ if (ZeroExtendMask != 0) { From 99121688f82318b966929afac278c69411054b80 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 23 Sep 2020 23:51:24 +0200 Subject: [PATCH 1709/2161] added test related to issue #1263 --- test/misc/Makefile | 6 ++++++ test/misc/bug1263.c | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 test/misc/bug1263.c diff --git a/test/misc/Makefile b/test/misc/Makefile index 735f83065..f8832e77e 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -94,6 +94,12 @@ $(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: pptest2.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 then hangs in an endless loop $(WORKDIR)/endless.$1.$2.prg: endless.c | $(WORKDIR) $(if $(QUIET),echo misc/endless.$1.$2.prg) diff --git a/test/misc/bug1263.c b/test/misc/bug1263.c new file mode 100644 index 000000000..457e64034 --- /dev/null +++ b/test/misc/bug1263.c @@ -0,0 +1,17 @@ + +/* bug #1263 - erroneous error for implicit function declaration */ + +#include <stdlib.h> + +enum E { I }; +extern int f(enum E); +int f(e) + enum E e; +{ + return 1; +} + +int main(void) +{ + return f(1) ? EXIT_SUCCESS : EXIT_FAILURE; +} From 6fdd90fa632a58edcbc08b6a44c4bad4aaa87338 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 23 Sep 2020 23:51:37 +0200 Subject: [PATCH 1710/2161] fix typo --- test/readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/readme.txt b/test/readme.txt index a8746ba60..0523482fd 100644 --- a/test/readme.txt +++ b/test/readme.txt @@ -13,7 +13,7 @@ compiler. The makefile in this directory _expects_ the tests to fail, because of that when an issue was fixed it will break the CI. The test should get - moved to /var in the PR fixing the issue, which will make CI pass again. + moved to /val in the PR fixing the issue, which will make CI pass again. No changes to makefiles are required! /asm - contains the assembler regression tests From 46ebb15c76f56fd9482058432039c391ce2f0f7a Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 23 Sep 2020 23:57:25 +0200 Subject: [PATCH 1711/2161] test related to issue #1245 --- test/val/bug1245.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 test/val/bug1245.c diff --git a/test/val/bug1245.c b/test/val/bug1245.c new file mode 100644 index 000000000..2dda93790 --- /dev/null +++ b/test/val/bug1245.c @@ -0,0 +1,12 @@ +/* bug #1245 - ICE for enums with int initializers */ + +#include <stdlib.h> + +enum E { + X = 1000, +} e = 3; + +int main(void) +{ + return EXIT_SUCCESS; +} From b3491e3d9a5d85ca6e62516398c329dcaa6cfe3d Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 23 Sep 2020 23:57:36 +0200 Subject: [PATCH 1712/2161] test related to issue #1244 --- test/val/bug1244.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 test/val/bug1244.c diff --git a/test/val/bug1244.c b/test/val/bug1244.c new file mode 100644 index 000000000..fb499a0c8 --- /dev/null +++ b/test/val/bug1244.c @@ -0,0 +1,18 @@ + +/* bug #1244 - ICE for enum bit-fields */ + +#include <stdlib.h> + +enum E { + L = 65535L /* or U = 65535U */ +}; + +struct S { + enum E a : 16; +} s; + +int main(void) +{ + return EXIT_SUCCESS; +} + From a86644eff1b0102a95eada977b7fb23b5d2e56fb Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 24 Sep 2020 00:08:36 +0200 Subject: [PATCH 1713/2161] test related to issue #1221 --- test/val/bug1221.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 test/val/bug1221.c diff --git a/test/val/bug1221.c b/test/val/bug1221.c new file mode 100644 index 000000000..360a71162 --- /dev/null +++ b/test/val/bug1221.c @@ -0,0 +1,12 @@ +/* bug #1221 - Structs/unions as ternary operands */ + +int a; +struct S { int a; } s1, s2; +struct U { int a; } u1, u2; + +int main() +{ + a ? s1 : s2; /* BUG: should be OK */ + a ? u1 : u2; /* BUG: should be OK */ + return 0; +} From fb8b45e4794ee491cc92376e23eef082ad8ab31d Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 24 Sep 2020 00:18:28 +0200 Subject: [PATCH 1714/2161] added note on how to manage the sample programs --- samples/README | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/samples/README b/samples/README index 73d048fca..3c9247c39 100644 --- a/samples/README +++ b/samples/README @@ -18,6 +18,10 @@ Please note: * Use "make disk" to build a disk image with all sample programs. + * All programs in the root of the "samples" directory have been written to + be portable and work on more than one target. Programs that are specific + to a certain target live in a subdirectory with the name of the target. + List of supplied sample programs: ----------------------------------------------------------------------------- From 97a1093ee09f5efd3569fc8bba9c10a55f4cfb36 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 24 Sep 2020 12:23:18 +0200 Subject: [PATCH 1715/2161] test related to issue #1222 --- test/val/bug1222.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 test/val/bug1222.c diff --git a/test/val/bug1222.c b/test/val/bug1222.c new file mode 100644 index 000000000..5e47e452e --- /dev/null +++ b/test/val/bug1222.c @@ -0,0 +1,12 @@ +/* bug #1222 - 'sizeof' issues */ + +#include <stdlib.h> + +int a[1]; +int b[sizeof ++a[42]]; /* should work as '++a[42]' is actually unevaluated */ + +int main(void) +{ + return EXIT_SUCCESS; +} + From 5ba9d28488a217d121cf334bb67897b71243c652 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 24 Sep 2020 16:16:16 +0200 Subject: [PATCH 1716/2161] test related to pr #1189 --- test/err/pr1189.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 test/err/pr1189.c diff --git a/test/err/pr1189.c b/test/err/pr1189.c new file mode 100644 index 000000000..af1d237f1 --- /dev/null +++ b/test/err/pr1189.c @@ -0,0 +1,12 @@ +/* pr #1189 - Fixed compiler CHECK failure when calling functions defined with duplicate param names */ + +void f(int a, int a) +{ + +} + +int main(void) +{ + f(0, 1); /* Check failed: (Param->Flags & SC_PARAM) != 0 */ + return 0; +} From 6fdb356db743dd986d479fffe994fff5e9045518 Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Thu, 24 Sep 2020 18:01:56 +0200 Subject: [PATCH 1717/2161] Simplify Gamate tile redefinition (as already done for PCE) --- libsrc/gamate/conio.s | 6 +----- libsrc/gamate/{vga.inc => vga.s} | 7 ++++++- 2 files changed, 7 insertions(+), 6 deletions(-) rename libsrc/gamate/{vga.inc => vga.s} (99%) mode change 100644 => 100755 diff --git a/libsrc/gamate/conio.s b/libsrc/gamate/conio.s index 6ac439490..33437cc04 100644 --- a/libsrc/gamate/conio.s +++ b/libsrc/gamate/conio.s @@ -1,6 +1,7 @@ .include "gamate.inc" .include "extzp.inc" + .import fontdata .import colors .importzp ptr1, tmp1 @@ -24,8 +25,3 @@ initconio: sta BGCOLOR rts - .segment "RODATA" - - .export fontdata -fontdata: - .include "vga.inc" diff --git a/libsrc/gamate/vga.inc b/libsrc/gamate/vga.s old mode 100644 new mode 100755 similarity index 99% rename from libsrc/gamate/vga.inc rename to libsrc/gamate/vga.s index da20dd4aa..39a8df173 --- a/libsrc/gamate/vga.inc +++ b/libsrc/gamate/vga.s @@ -1,6 +1,11 @@ - ; VGA charset for the Gamate conio implementation +.export fontdata + +.rodata + +fontdata: + .byte $00, $00, $00, $00, $00, $00, $00, $00 ; 1 From 61ebe2c34b6755fa0c71f89bfeee873a51f636f5 Mon Sep 17 00:00:00 2001 From: Fabrizio Caruso <fabrizio_caruso@hotmail.com> Date: Thu, 24 Sep 2020 19:32:15 +0200 Subject: [PATCH 1718/2161] Indentation in vga.s for gamate --- libsrc/gamate/vga.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/gamate/vga.s b/libsrc/gamate/vga.s index 39a8df173..310560015 100755 --- a/libsrc/gamate/vga.s +++ b/libsrc/gamate/vga.s @@ -1,8 +1,8 @@ ; VGA charset for the Gamate conio implementation -.export fontdata + .export fontdata -.rodata + .rodata fontdata: From 47ee1792732def69c8ba6255a3078f0492e4ddd3 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 25 Sep 2020 00:30:49 -0400 Subject: [PATCH 1719/2161] Fixed a copy & paste error in the test/misc/ makefile. Fixed a warning that's changed to an error in Travis CI tests. --- test/misc/Makefile | 2 +- test/misc/bug1263.c | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/test/misc/Makefile b/test/misc/Makefile index f8832e77e..deacc9464 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -95,7 +95,7 @@ $(WORKDIR)/pptest2.$1.$2.prg: pptest2.c | $(WORKDIR) $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) # should compile, but gives an error -$(WORKDIR)/bug1263.$1.$2.prg: pptest2.c | $(WORKDIR) +$(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) diff --git a/test/misc/bug1263.c b/test/misc/bug1263.c index 457e64034..4e5987c58 100644 --- a/test/misc/bug1263.c +++ b/test/misc/bug1263.c @@ -1,17 +1,15 @@ +/* bug #1263 - erroneous error for K & R function declaration */ -/* bug #1263 - erroneous error for implicit function declaration */ - -#include <stdlib.h> - -enum E { I }; +enum E { I = 0 }; extern int f(enum E); + int f(e) enum E e; { - return 1; + return e; } int main(void) { - return f(1) ? EXIT_SUCCESS : EXIT_FAILURE; + return f(I); } From 61d934fd7bba94f79a297567053c81621bbf3c3b Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 25 Sep 2020 16:25:32 +0200 Subject: [PATCH 1720/2161] test related to issue #1265 --- test/misc/Makefile | 9 ++++++++ test/misc/bug1265.c | 51 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 test/misc/bug1265.c diff --git a/test/misc/Makefile b/test/misc/Makefile index f8832e77e..f04bcadbd 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -100,6 +100,15 @@ $(WORKDIR)/bug1263.$1.$2.prg: pptest2.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1263.$1.$2.prg) $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) +# this one requires --std=c89, it fails with --std=c99 +# it fails currently at runtime +$(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) + $(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) + # 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) diff --git a/test/misc/bug1265.c b/test/misc/bug1265.c new file mode 100644 index 000000000..469946739 --- /dev/null +++ b/test/misc/bug1265.c @@ -0,0 +1,51 @@ +/* bug #1265 - misadjusted stack from unprototyped function call */ + +#include <stdio.h> +#include <string.h> + +int failures = 0; + +char str1[10]; +char str2[10]; + +int f2 (int x) { return x == 2345 ? 23 : -1; } + +int main (void) { + int x, n; + + sprintf (str1, "%p\n", &x); + puts(str1); + x = 1234; + n = f1 (x); + sprintf (str2, "%p\n", &x); + puts(str2); + + if (strcmp(str1, str2)) { + puts("not equal"); + failures++; + } + if (n != 42) { + puts("f1 returns wrong value"); + failures++; + } + + sprintf (str1, "%p\n", &x); + puts(str1); + x = 2345; + n = f2 (x); + sprintf (str2, "%p\n", &x); + puts(str2); + + if (strcmp(str1, str2)) { + puts("not equal"); + failures++; + } + if (n != 23) { + puts("f2 returns wrong value"); + failures++; + } + + return failures; +} + +int f1 (int x) { return x == 1234 ? 42 : -1; } From 34177d9eddc81eb90c582690eafd3ae4d6510204 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 25 Sep 2020 20:08:32 +0200 Subject: [PATCH 1721/2161] test related to issue #1094 --- test/misc/Makefile | 6 +++ test/misc/bug1094.c | 99 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 test/misc/bug1094.c diff --git a/test/misc/Makefile b/test/misc/Makefile index b8c578405..06046af3c 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -100,6 +100,12 @@ $(WORKDIR)/bug1263.$1.$2.prg: bug1263.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1263.$1.$2.prg) $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) +# should compile, but gives an error +$(WORKDIR)/bug1094.$1.$2.prg: bug1094.c | $(WORKDIR) + @echo "FIXME: " $$@ "currently does not compile." + $(if $(QUIET),echo misc/bug1094.$1.$2.prg) + $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + # this one requires --std=c89, it fails with --std=c99 # it fails currently at runtime $(WORKDIR)/bug1265.$1.$2.prg: bug1265.c | $(WORKDIR) diff --git a/test/misc/bug1094.c b/test/misc/bug1094.c new file mode 100644 index 000000000..05e3e6430 --- /dev/null +++ b/test/misc/bug1094.c @@ -0,0 +1,99 @@ + +/* bug #1094 - Nested struct/union initializers don't compile */ + +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <stdint.h> + +typedef uint16_t u16; +typedef uint8_t u8; + +struct WW { + int a : 4; + struct { + unsigned int b : 4; + unsigned int c : 8; + } x[2]; +} wwqq = { 0, {2, 5, {3, 4}}, }; + +typedef struct { + u16 quot; + u16 rem; +} udiv_t; + +typedef struct { + u16 quot; + u16 rem; + char m[8]; +} big_t; + +union U { + struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; + }; + int u; +}; + +union U g = { 5, 3, 1 }; + +struct S { + struct { + unsigned int a : 3; + unsigned int b : 3; + unsigned int c : 3; + }; +}; + +struct S h = { 5, 3, 1 }; + +union X { + struct { + uint16_t a : 3; + union { + struct { + uint16_t b : 3; + uint16_t c : 3; + }; + uint16_t d; + }; + }; + uint16_t e; +} x = { 4, {5, 6} }; + + +udiv_t div3(udiv_t u) +{ + udiv_t v = {}; + + u.quot = 341 + u.quot; + u.rem = 1 + u.rem; + + v = u; + + return v; +} + +int main(void) +{ + udiv_t v = { 141, 32 }; + big_t b = { 141, 32 }; + + v = div3(*(udiv_t*)&b); + + printf("%d %d %d\n", (int)wwqq.a, wwqq.x[0].b, wwqq.x[0].c); + printf("%d %d %d\n", (int)wwqq.a, wwqq.x[1].b, wwqq.x[1].c); + printf("quot = %u, rem = %u\n", div3(v).quot, div3(v).rem); + printf("quot = %u, rem = %u\n", v.quot, v.rem); + printf("quot = %u, rem = %u\n", b.quot, b.rem); + printf("g.a = %u, g.b = %u, g.c = %d\n", g.a, g.b, g.c); + x.e = 1467; + printf("x.a = %d, x.b = %d, x.c = %d\n", x.a, x.b, x.c); + printf("(long)x.b = %ld, sizeof(x) = %u, sizeof((long)x.a) = %u\n", (long)x.b, sizeof(x), sizeof((long)x.a)); + printf("-x.d = %d, (long)(-x.c + 1) = %ld\n", -x.d, (long)(-x.c + 1)); + printf("h.a = %u, h.b = %u, h.c = %u\n", h.a, h.b, h.c); + + return 0; +} From d0089aef954907141bc9344558dea83577daef73 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sat, 26 Sep 2020 08:36:17 +0200 Subject: [PATCH 1722/2161] Fix bit-field truncation warning message Fix copy & paste bug with warning message. struct X { signed int a : 3; }; struct X g = { 5 }; Before: s.c(4): Warning: Implicit truncation from 'int' to 'int : 3' in bit-field initializer changes value from 5 to 5 After: s.c(4): Warning: Implicit truncation from 'int' to 'int : 3' in bit-field initializer changes value from 5 to -3 Fixes #1268 --- src/cc65/declare.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0f604d45e..8623fa08f 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2567,9 +2567,9 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) long RestoredVal = asr_l(asl_l (Val, ShiftBits), ShiftBits); if (ED.IVal != RestoredVal) { Warning ("Implicit truncation from '%s' to '%s : %u' in bit-field initializer " - "changes value from %ld to %d", + "changes value from %ld to %ld", GetFullTypeName (ED.Type), GetFullTypeName (Entry->Type), - Entry->V.B.BitWidth, ED.IVal, Val); + Entry->V.B.BitWidth, ED.IVal, RestoredVal); } } From c45a6b3685815de0bc76f9cdbf9fb7d9deb500f5 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 16 Apr 2020 17:16:47 +0800 Subject: [PATCH 1723/2161] Utility function ParseOpcArgStr(). --- src/cc65/codeent.c | 100 +++++++++++++++++++++++++++++++++++++++++++++ src/cc65/codeent.h | 8 ++++ 2 files changed, 108 insertions(+) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index 3de694829..aa3a960df 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -356,6 +356,106 @@ static void SetUseChgInfo (CodeEntry* E, const OPCDesc* D) +int ParseOpcArgStr (const char* Arg, struct StrBuf* Name, int* Offset) +/* Break the opcode argument string into a symbol name/label part plus an offset. +** Both parts are optional, but if there are any characters in the string that +** can't be parsed, it's an failure. +** The caller is responsible for managing the StrBuf. +** Return whether parsing succeeds or not. +*/ +{ + int NewOff = 0; + const char* OffsetPart = 0; + const char* NameEnd = 0; + int Negative = 0; + + /* A numeric address is treated as an unnamed address with the numeric part as the offset */ + if (IsDigit (Arg[0]) || Arg[0] == '$') { + /* A call to a numeric address */ + SB_Clear (Name); + SB_Terminate (Name); + OffsetPart = Arg; + } else { + /* If the symbol name starts with an underline, it is an external symbol. + ** If the symbol does not start with an underline, it may be a built-in + ** symbol. + */ + if (Arg[0] == '_') { + /* Skip the underscore */ + ++Arg; + } + + /* Rip off the offset if present. */ + OffsetPart = strchr (Arg, '+'); + if (OffsetPart == 0) { + OffsetPart = strchr (Arg, '-'); + } + if (OffsetPart != 0) { + /* Get the real arg name */ + NameEnd = strchr (Arg, ' '); + if (NameEnd == 0 || NameEnd > OffsetPart) { + NameEnd = OffsetPart; + } + SB_CopyBuf (Name, Arg, NameEnd - Arg); + SB_Terminate (Name); + + } else { + /* No offset */ + *Offset = 0; + + SB_CopyStr (Name, Arg); + SB_Terminate (Name); + + return 1; + } + } + + *Offset = 0; + + /* Get the offset */ + while (OffsetPart != 0 && OffsetPart[0] != '\0') { + if (OffsetPart[0] == '+') { + Negative = 0; + ++OffsetPart; + } else if (OffsetPart[0] == '-') { + Negative = 1; + ++OffsetPart; + } + + /* Skip spaces */ + while (OffsetPart[0] == ' ') { + ++OffsetPart; + } + + if (OffsetPart[0] == '$') { + if (sscanf (OffsetPart + 1, "%X", &NewOff) != 1) { + return 0; + } + } else { + if (sscanf (OffsetPart, "%u", &NewOff) != 1) { + return 0; + } + } + + if (Negative) { + NewOff = -NewOff; + } + + *Offset += NewOff; + + /* See if there are more */ + Arg = OffsetPart; + OffsetPart = strchr (Arg, '+'); + if (OffsetPart == 0) { + OffsetPart = strchr (Arg, '-'); + } + } + + return 1; +} + + + const char* MakeHexArg (unsigned Num) /* Convert Num into a string in the form $XY, suitable for passing it as an ** argument to NewCodeEntry, and return a pointer to the string. diff --git a/src/cc65/codeent.h b/src/cc65/codeent.h index 3d07670d7..57a7677bb 100644 --- a/src/cc65/codeent.h +++ b/src/cc65/codeent.h @@ -89,6 +89,14 @@ struct CodeEntry { +int ParseOpcArgStr (const char* Arg, struct StrBuf* Name, int* Offset); +/* Break the opcode argument string into a symbol name/label part plus an offset. +** Both parts are optional, but if there are any characters in the string that +** can't be parsed, it's an failure. +** The caller is responsible for managing the StrBuf. +** Return whether parsing succeeds or not. +*/ + const char* MakeHexArg (unsigned Num); /* Convert Num into a string in the form $XY, suitable for passing it as an ** argument to NewCodeEntry, and return a pointer to the string. From 28c7aa2bc8b18aeb0291acbbc3a34f6996a60d25 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 16 Apr 2020 17:17:52 +0800 Subject: [PATCH 1724/2161] Replaced direct CEF_NUMARG flag checks on code entries with CE_HasNumArg(). --- src/cc65/coptcmp.c | 4 ++-- src/cc65/coptneg.c | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/cc65/coptcmp.c b/src/cc65/coptcmp.c index ca0ba39a8..a4a8c6a9b 100644 --- a/src/cc65/coptcmp.c +++ b/src/cc65/coptcmp.c @@ -176,14 +176,14 @@ static int IsImmCmp16 (CodeEntry** L) { return (L[0]->OPC == OP65_CPX && L[0]->AM == AM65_IMM && - (L[0]->Flags & CEF_NUMARG) != 0 && + CE_HasNumArg (L[0]) && !CE_HasLabel (L[0]) && (L[1]->OPC == OP65_JNE || L[1]->OPC == OP65_BNE) && L[1]->JumpTo != 0 && !CE_HasLabel (L[1]) && L[2]->OPC == OP65_CMP && L[2]->AM == AM65_IMM && - (L[2]->Flags & CEF_NUMARG) != 0 && + CE_HasNumArg (L[2]) && (L[3]->Info & OF_CBRA) != 0 && L[3]->JumpTo != 0 && (L[1]->JumpTo->Owner == L[3] || L[1]->JumpTo == L[3]->JumpTo)); diff --git a/src/cc65/coptneg.c b/src/cc65/coptneg.c index 03b39eb42..0f5d589f7 100644 --- a/src/cc65/coptneg.c +++ b/src/cc65/coptneg.c @@ -68,15 +68,15 @@ unsigned OptBNegA1 (CodeSeg* S) CodeEntry* E = CS_GetEntry (S, I); /* Check for a ldx */ - if (E->OPC == OP65_LDX && - E->AM == AM65_IMM && - (E->Flags & CEF_NUMARG) != 0 && - E->Num == 0 && - CS_GetEntries (S, L, I+1, 2) && - L[0]->OPC == OP65_LDA && - (L[0]->Use & REG_X) == 0 && - !CE_HasLabel (L[0]) && - CE_IsCallTo (L[1], "bnega") && + if (E->OPC == OP65_LDX && + E->AM == AM65_IMM && + CE_HasNumArg (E) && + E->Num == 0 && + CS_GetEntries (S, L, I+1, 2) && + L[0]->OPC == OP65_LDA && + (L[0]->Use & REG_X) == 0 && + !CE_HasLabel (L[0]) && + CE_IsCallTo (L[1], "bnega") && !CE_HasLabel (L[1])) { /* Remove the ldx instruction */ From d379affc4b53d91e366bc6b17901633eb0d092eb Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 16 Apr 2020 17:17:08 +0800 Subject: [PATCH 1725/2161] Moved some reusable code from cc65/coptstop.c into new files. --- src/cc65.vcxproj | 2 + src/cc65/codeoptutil.c | 993 ++++++++++++++++++++++++++++++++++++++ src/cc65/codeoptutil.h | 257 ++++++++++ src/cc65/coptstop.c | 1027 +--------------------------------------- 4 files changed, 1253 insertions(+), 1026 deletions(-) create mode 100644 src/cc65/codeoptutil.c create mode 100644 src/cc65/codeoptutil.h diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 1015b389f..0f63a1022 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -87,6 +87,7 @@ <ClInclude Include="cc65\codeinfo.h" /> <ClInclude Include="cc65\codelab.h" /> <ClInclude Include="cc65\codeopt.h" /> + <ClInclude Include="cc65\codeoptutil.h" /> <ClInclude Include="cc65\codeseg.h" /> <ClInclude Include="cc65\compile.h" /> <ClInclude Include="cc65\coptadd.h" /> @@ -163,6 +164,7 @@ <ClCompile Include="cc65\codeinfo.c" /> <ClCompile Include="cc65\codelab.c" /> <ClCompile Include="cc65\codeopt.c" /> + <ClCompile Include="cc65\codeoptutil.c" /> <ClCompile Include="cc65\codeseg.c" /> <ClCompile Include="cc65\compile.c" /> <ClCompile Include="cc65\coptadd.c" /> diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c new file mode 100644 index 000000000..999c18d33 --- /dev/null +++ b/src/cc65/codeoptutil.c @@ -0,0 +1,993 @@ +/*****************************************************************************/ +/* */ +/* codeoptutil.c */ +/* */ +/* Optimize operations that take operands via the stack */ +/* */ +/* */ +/* */ +/* (C) 2001 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* 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. */ +/* */ +/*****************************************************************************/ + + + +#include <stdlib.h> + +/* common */ +#include "chartype.h" +#include "xmalloc.h" + +/* cc65 */ +#include "codeinfo.h" +#include "codeoptutil.h" +#include "error.h" + + + +/*****************************************************************************/ +/* Load tracking code */ +/*****************************************************************************/ + + + +void ClearLoadRegInfo (LoadRegInfo* RI) +/* Clear a LoadRegInfo struct */ +{ + RI->Flags = LI_NONE; + RI->LoadIndex = -1; + RI->LoadEntry = 0; + RI->LoadYIndex = -1; + RI->LoadYEntry = 0; + RI->XferIndex = -1; + RI->XferEntry = 0; + RI->Offs = 0; +} + + + +void CopyLoadRegInfo (LoadRegInfo* To, LoadRegInfo* From) +/* Copy a LoadRegInfo struct */ +{ + To->Flags = From->Flags; + To->LoadIndex = From->LoadIndex; + To->LoadEntry = From->LoadEntry; + To->LoadYIndex = From->LoadYIndex; + To->LoadYEntry = From->LoadYEntry; + To->XferIndex = From->XferIndex; + To->XferEntry = From->XferEntry; + To->Offs = From->Offs; +} + + + +void FinalizeLoadRegInfo (LoadRegInfo* RI, CodeSeg* S) +/* Prepare a LoadRegInfo struct for use */ +{ + /* Get the entries */ + if (RI->LoadIndex >= 0) { + RI->LoadEntry = CS_GetEntry (S, RI->LoadIndex); + } else { + RI->LoadEntry = 0; + } + if (RI->XferIndex >= 0) { + RI->XferEntry = CS_GetEntry (S, RI->XferIndex); + } else { + RI->XferEntry = 0; + } + /* Load from src not modified before op can be treated as direct */ + if ((RI->Flags & LI_SRC_CHG) == 0 && + (RI->Flags & (LI_CHECK_ARG | LI_CHECK_Y)) != 0) { + RI->Flags |= LI_DIRECT; + if ((RI->Flags & LI_CHECK_Y) != 0) { + RI->Flags |= LI_RELOAD_Y; + } + } + /* We cannot ldy src,y */ + if ((RI->Flags & LI_RELOAD_Y) != 0 && + RI->LoadYEntry != 0 && + (RI->LoadYEntry->Use & REG_Y) == REG_Y) { + RI->Flags &= ~LI_DIRECT; + } +} + + + +void AdjustLoadRegInfo (LoadRegInfo* RI, int Index, int Change) +/* Adjust a load register info struct after deleting or inserting an entry +** with a given index +*/ +{ + CHECK (abs (Change) == 1); + if (Change < 0) { + /* Deletion */ + if (Index < RI->LoadIndex) { + --RI->LoadIndex; + } else if (Index == RI->LoadIndex) { + /* Has been removed */ + RI->LoadIndex = -1; + RI->LoadEntry = 0; + } + if (Index < RI->XferIndex) { + --RI->XferIndex; + } else if (Index == RI->XferIndex) { + /* Has been removed */ + RI->XferIndex = -1; + RI->XferEntry = 0; + } + } else { + /* Insertion */ + if (Index <= RI->LoadIndex) { + ++RI->LoadIndex; + } + if (Index <= RI->XferIndex) { + ++RI->XferIndex; + } + } +} + + + +void ClearLoadInfo (LoadInfo* LI) +/* Clear a LoadInfo struct */ +{ + ClearLoadRegInfo (&LI->A); + ClearLoadRegInfo (&LI->X); + ClearLoadRegInfo (&LI->Y); +} + + + +void CopyLoadInfo (LoadInfo* To, LoadInfo* From) +/* Copy a LoadInfo struct */ +{ + CopyLoadRegInfo (&To->A, &From->A); + CopyLoadRegInfo (&To->X, &From->X); + CopyLoadRegInfo (&To->Y, &From->Y); +} + + + +void FinalizeLoadInfo (LoadInfo* LI, CodeSeg* S) +/* Prepare a LoadInfo struct for use */ +{ + /* Get the entries */ + FinalizeLoadRegInfo (&LI->A, S); + FinalizeLoadRegInfo (&LI->X, S); + FinalizeLoadRegInfo (&LI->Y, S); +} + + + +void AdjustLoadInfo (LoadInfo* LI, int Index, int Change) +/* Adjust a load info struct after deleting entry with a given index */ +{ + AdjustLoadRegInfo (&LI->A, Index, Change); + AdjustLoadRegInfo (&LI->X, Index, Change); + AdjustLoadRegInfo (&LI->Y, Index, Change); +} + + + +RegInfo* GetLastChangedRegInfo (StackOpData* D, LoadRegInfo* Reg) +/* Get RegInfo of the last load insn entry */ +{ + CodeEntry* E; + + if (Reg->LoadIndex >= 0 && (E = CS_GetEntry (D->Code, Reg->LoadIndex)) != 0) { + return E->RI; + } + + return 0; +} + + + +static int Affected (LoadRegInfo* RI, const CodeEntry* E) +/* Check if the load src may be modified between the pushax and op */ +{ + fncls_t fncls; + unsigned int Use; + unsigned int Chg; + unsigned int UseToCheck = 0; + + if ((RI->Flags & (LI_CHECK_ARG | LI_CHECK_Y)) != 0) { + if (E->AM == AM65_IMM || E->AM == AM65_ACC || E->AM == AM65_IMP || E->AM == AM65_BRA) { + return 0; + } + CHECK ((RI->Flags & LI_CHECK_ARG) == 0 || RI->LoadEntry != 0); + CHECK ((RI->Flags & LI_CHECK_Y) == 0 || RI->LoadYEntry != 0); + + if ((RI->Flags & LI_CHECK_ARG) != 0) { + UseToCheck |= RI->LoadEntry->Use; + } + + if ((RI->Flags & LI_CHECK_Y) != 0) { + UseToCheck |= RI->LoadYEntry->Use; + } + + if (E->OPC == OP65_JSR) { + /* Try to know about the function */ + fncls = GetFuncInfo (E->Arg, &Use, &Chg); + if ((UseToCheck & Chg & REG_ALL) == 0 && + fncls == FNCLS_BUILTIN) { + /* Builtin functions are known to be harmless */ + return 0; + } + /* Otherwise play it safe */ + return 1; + } else if (E->OPC == OP65_DEC || E->OPC == OP65_INC || + E->OPC == OP65_ASL || E->OPC == OP65_LSR || + E->OPC == OP65_ROL || E->OPC == OP65_ROR || + E->OPC == OP65_TRB || E->OPC == OP65_TSB || + E->OPC == OP65_STA || E->OPC == OP65_STX || E->OPC == OP65_STY) { + if ((E->AM == AM65_ABS || E->AM == AM65_ZP)) { + if ((RI->Flags & LI_CHECK_ARG) != 0 && + strcmp (RI->LoadEntry->Arg, E->Arg) == 0) { + return 1; + } + if ((RI->Flags & LI_CHECK_Y) != 0 && + strcmp (RI->LoadYEntry->Arg, E->Arg) == 0) { + return 1; + } + return 0; + } + /* We could've check further for more cases where the load target isn't modified, + ** But for now let's save the trouble and just play it safe. */ + return 1; + } + } + return 0; +} + + + +static void HonourUseAndChg (LoadRegInfo* RI, unsigned Reg, const CodeEntry* E, int I) +/* Honour use and change flags for an instruction */ +{ + if ((E->Chg & Reg) != 0) { + /* Remember this as an indirect load */ + ClearLoadRegInfo (RI); + RI->LoadIndex = I; + RI->XferIndex = -1; + RI->Flags = 0; + } else if (Affected (RI, E)) { + RI->Flags |= LI_SRC_CHG; + } +} + + + +unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I) +/* Track loads for a code entry. +** Return used registers. +*/ +{ + unsigned Used; + CodeEntry* E = CS_GetEntry (S, I); + CHECK (E != 0); + + /* By default */ + Used = E->Use; + + /* Whether we had a load or xfer op before or not, the newly loaded value + ** will be the real one used for the pushax/op unless it's overwritten, + ** so we can just reset the flags about it in such cases. + */ + if (E->Info & OF_LOAD) { + + LoadRegInfo* RI = 0; + + /* Determine, which register was loaded */ + if (E->Chg & REG_A) { + RI = &LI->A; + } else if (E->Chg & REG_X) { + RI = &LI->X; + } else if (E->Chg & REG_Y) { + RI = &LI->Y; + } + CHECK (RI != 0); + + /* Remember the load */ + RI->LoadIndex = I; + RI->XferIndex = -1; + + /* Set load flags */ + RI->Flags = LI_LOAD_INSN; + if (E->AM == AM65_IMM) { + /* These insns are all ok and replaceable */ + RI->Flags |= LI_DIRECT; + } else if (E->AM == AM65_ZP || E->AM == AM65_ABS) { + /* These insns are replaceable only if they are not modified later */ + RI->Flags |= LI_CHECK_ARG; + } else if (E->AM == AM65_ZPY || E->AM == AM65_ABSY) { + /* These insns are replaceable only if they are not modified later */ + RI->Flags |= LI_CHECK_ARG | LI_CHECK_Y; + } else if (E->AM == AM65_ZP_INDY && + strcmp (E->Arg, "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 + ** these locations may change between the push and the actual + ** operation. + */ + RI->Flags |= LI_DIRECT | LI_CHECK_Y | LI_SP; + + /* Reg Y can be regarded as unused if this load is removed */ + Used &= ~REG_Y; + if (RI == &LI->A) { + LI->Y.Flags |= LI_USED_BY_A; + } else { + LI->Y.Flags |= LI_USED_BY_X; + } + } + + /* If the load offset has a known value, we can just remember and reload + ** it into the index register later. + */ + if ((RI->Flags & LI_CHECK_Y) != 0) { + if (RegValIsKnown (E->RI->In.RegY)) { + RI->Offs = (unsigned char)E->RI->In.RegY; + RI->Flags &= ~LI_CHECK_Y; + RI->Flags |= LI_RELOAD_Y; + } else { + /* We need to check if the src of Y is changed */ + RI->LoadYIndex = LI->Y.LoadIndex; + RI->LoadYEntry = CS_GetEntry (S, RI->LoadYIndex); + } + } + + /* Watch for any change of the load target */ + if ((RI->Flags & LI_CHECK_ARG) != 0) { + RI->LoadEntry = CS_GetEntry (S, I); + } + + } else if (E->Info & OF_XFR) { + + /* Determine source and target of the transfer and handle the TSX insn */ + LoadRegInfo* Src; + LoadRegInfo* Tgt; + switch (E->OPC) { + case OP65_TAX: + Src = &LI->A; + Tgt = &LI->X; + Used &= ~REG_A; + Src->Flags |= LI_USED_BY_X; + break; + case OP65_TAY: + Src = &LI->A; + Tgt = &LI->Y; + Used &= ~REG_A; + Src->Flags |= LI_USED_BY_Y; + break; + case OP65_TXA: + Src = &LI->X; + Tgt = &LI->A; + Used &= ~REG_X; + Src->Flags |= LI_USED_BY_A; + break; + case OP65_TYA: + Src = &LI->Y; + Tgt = &LI->A; + Used &= ~REG_Y; + Src->Flags |= LI_USED_BY_A; + break; + case OP65_TSX: + ClearLoadRegInfo (&LI->X); + return Used; + case OP65_TXS: + return Used; + default: Internal ("Unknown XFR insn in TrackLoads"); + } + + /* Transfer the data */ + Tgt->LoadIndex = Src->LoadIndex; + Tgt->LoadEntry = Src->LoadEntry; + Tgt->LoadYIndex = Src->LoadYIndex; + Tgt->LoadYEntry = Src->LoadYEntry; + Tgt->XferIndex = I; + Tgt->Offs = Src->Offs; + Tgt->Flags = Src->Flags; + + } else if (CE_IsCallTo (E, "ldaxysp") && RegValIsKnown (E->RI->In.RegY)) { + + /* Both registers set, Y changed */ + LI->A.LoadIndex = I; + LI->A.XferIndex = -1; + LI->A.Flags = (LI_LOAD_INSN | LI_DIRECT | LI_RELOAD_Y | LI_SP); + LI->A.Offs = (unsigned char) E->RI->In.RegY - 1; + + LI->X.LoadIndex = I; + LI->X.XferIndex = -1; + LI->X.Flags = (LI_LOAD_INSN | LI_DIRECT | LI_RELOAD_Y | LI_SP); + LI->X.Offs = (unsigned char) E->RI->In.RegY; + + /* Reg Y can be regarded as unused if this load is removed */ + Used &= ~REG_Y; + LI->Y.Flags |= LI_USED_BY_A | LI_USED_BY_X; + + } else { + HonourUseAndChg (&LI->A, REG_A, E, I); + HonourUseAndChg (&LI->X, REG_X, E, I); + HonourUseAndChg (&LI->Y, REG_Y, E, I); + + /* The other operand may be affected too */ + if (LLI != 0) { + if (Affected (&LLI->A, E)) { + LLI->A.Flags |= LI_SRC_CHG; + } + if (Affected (&LLI->X, E)) { + LLI->X.Flags |= LI_SRC_CHG; + } + if (Affected (&LLI->Y, E)) { + LLI->Y.Flags |= LI_SRC_CHG; + } + } + } + + return Used; +} + + + +void SetDontRemoveEntryFlag (LoadRegInfo* RI) +/* Flag the entry as non-removable according to register flags */ +{ + if (RI->Flags & LI_DONT_REMOVE) { + if (RI->LoadEntry != 0) { + RI->LoadEntry->Flags |= CEF_DONT_REMOVE; + } + } +} + + + +void ResetDontRemoveEntryFlag (LoadRegInfo* RI) +/* Unflag the entry as non-removable according to register flags */ +{ + if (RI->Flags & LI_DONT_REMOVE) { + if (RI->LoadEntry != 0) { + RI->LoadEntry->Flags &= ~CEF_DONT_REMOVE; + } + } +} + + + +void SetDontRemoveEntryFlags (StackOpData* D) +/* Flag the entries as non-removable according to register flags */ +{ + SetDontRemoveEntryFlag (&D->Lhs.A); + SetDontRemoveEntryFlag (&D->Lhs.X); + SetDontRemoveEntryFlag (&D->Rhs.A); + SetDontRemoveEntryFlag (&D->Rhs.X); +} + + + +void ResetDontRemoveEntryFlags (StackOpData* D) +/* Unflag the entries as non-removable according to register flags */ +{ + ResetDontRemoveEntryFlag (&D->Lhs.A); + ResetDontRemoveEntryFlag (&D->Lhs.X); + ResetDontRemoveEntryFlag (&D->Rhs.A); + ResetDontRemoveEntryFlag (&D->Rhs.X); +} + + + +void ResetStackOpData (StackOpData* Data) +/* Reset the given data structure */ +{ + Data->OptFunc = 0; + Data->ZPUsage = REG_NONE; + Data->ZPChanged = REG_NONE; + Data->UsedRegs = REG_NONE; + Data->RhsMultiChg = 0; + + ClearLoadInfo (&Data->Lhs); + ClearLoadInfo (&Data->Rhs); + + Data->PushIndex = -1; + Data->OpIndex = -1; +} + + + +/*****************************************************************************/ +/* Helpers */ +/*****************************************************************************/ + + + +void InsertEntry (StackOpData* D, CodeEntry* E, int Index) +/* Insert a new entry. Depending on Index, D->PushIndex and D->OpIndex will +** be adjusted by this function. +*/ +{ + /* Insert the entry into the code segment */ + CS_InsertEntry (D->Code, E, Index); + + /* Adjust register loads if necessary */ + AdjustLoadInfo (&D->Lhs, Index, 1); + AdjustLoadInfo (&D->Rhs, Index, 1); + + /* Adjust the indices if necessary */ + if (D->PushEntry && Index <= D->PushIndex) { + ++D->PushIndex; + } + if (D->OpEntry && Index <= D->OpIndex) { + ++D->OpIndex; + } +} + + + +void DelEntry (StackOpData* D, int Index) +/* Delete an entry. Depending on Index, D->PushIndex and D->OpIndex will be +** adjusted by this function, and PushEntry/OpEntry may get invalidated. +*/ +{ + /* Delete the entry from the code segment */ + CS_DelEntry (D->Code, Index); + + /* Adjust register loads if necessary */ + AdjustLoadInfo (&D->Lhs, Index, -1); + AdjustLoadInfo (&D->Rhs, Index, -1); + + /* Adjust the other indices if necessary */ + if (Index < D->PushIndex) { + --D->PushIndex; + } else if (Index == D->PushIndex) { + D->PushEntry = 0; + } + if (Index < D->OpIndex) { + --D->OpIndex; + } else if (Index == D->OpIndex) { + D->OpEntry = 0; + } +} + + + +void AdjustStackOffset (StackOpData* D, unsigned Offs) +/* Adjust the offset for all stack accesses in the range PushIndex to OpIndex. +** OpIndex is adjusted according to the insertions. +*/ +{ + /* Walk over all entries */ + int I = D->PushIndex + 1; + while (I < D->OpIndex) { + + CodeEntry* E = CS_GetEntry (D->Code, I); + + /* Check if this entry does a stack access, and if so, if it's a plain + ** load from stack, since this is needed later. + */ + int Correction = 0; + if ((E->Use & REG_SP) != 0) { + + /* Check for some things that should not happen */ + CHECK (E->AM == AM65_ZP_INDY || E->RI->In.RegY >= (short) Offs); + CHECK (strcmp (E->Arg, "sp") == 0); + /* We need to correct this one */ + Correction = (E->OPC == OP65_LDA)? 2 : 1; + + } else if (CE_IsCallTo (E, "ldaxysp")) { + /* We need to correct this one */ + Correction = 1; + } + + if (Correction) { + /* Get the code entry before this one. If it's a LDY, adjust the + ** value. + */ + CodeEntry* P = CS_GetPrevEntry (D->Code, I); + if (P && P->OPC == OP65_LDY && CE_IsConstImm (P)) { + /* The Y load is just before the stack access, adjust it */ + CE_SetNumArg (P, P->Num - Offs); + } else { + /* Insert a new load instruction before the stack access */ + const char* Arg = MakeHexArg (E->RI->In.RegY - Offs); + CodeEntry* X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + InsertEntry (D, X, I++); + } + + /* If we need the value of Y later, be sure to reload it */ + if (RegYUsed (D->Code, I+1)) { + CodeEntry* N; + const char* Arg = MakeHexArg (E->RI->In.RegY); + if (Correction == 2 && (N = CS_GetNextEntry(D->Code, I)) != 0 && + ((N->Info & OF_ZBRA) != 0) && N->JumpTo != 0) { + /* The Y register is used but the load instruction loads A + ** and is followed by a branch that evaluates the zero flag. + ** This means that we cannot just insert the load insn + ** for the Y register at this place, because it would + ** destroy the Z flag. Instead place load insns at the + ** target of the branch and after it. + ** Note: There is a chance that this code won't work. The + ** jump may be a backwards jump (in which case the stack + ** offset has already been adjusted) or there may be other + ** instructions between the load and the conditional jump. + ** Currently the compiler does not generate such code, but + ** it is possible to force the optimizer into something + ** invalid by use of inline assembler. + */ + + /* Add load insn after the branch */ + CodeEntry* X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + InsertEntry (D, X, I+2); + + /* Add load insn before branch target */ + CodeEntry* Y = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + int J = CS_GetEntryIndex (D->Code, N->JumpTo->Owner); + CHECK (J > I); /* Must not happen */ + InsertEntry (D, Y, J); + + /* Move the label to the new insn */ + CodeLabel* L = CS_GenLabel (D->Code, Y); + CS_MoveLabelRef (D->Code, N, L); + } else { + CodeEntry* X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + InsertEntry (D, X, I+1); + /* Skip this instruction in the next round */ + ++I; + } + } + } + + /* Next entry */ + ++I; + } + + /* If we have rhs load insns that load from stack, we'll have to adjust + ** the offsets for these also. + */ + if ((D->Rhs.A.Flags & (LI_RELOAD_Y | LI_SP | LI_CHECK_Y)) == (LI_RELOAD_Y | LI_SP)) { + D->Rhs.A.Offs -= Offs; + } + if ((D->Rhs.X.Flags & (LI_RELOAD_Y | LI_SP | LI_CHECK_Y)) == (LI_RELOAD_Y | LI_SP)) { + D->Rhs.X.Offs -= Offs; + } +} + + + +int IsRegVar (StackOpData* D) +/* If the value pushed is that of a zeropage variable that is unchanged until Op, +** replace ZPLo and ZPHi in the given StackOpData struct by the variable and return true. +** Otherwise leave D untouched and return false. +*/ +{ + CodeEntry* LoadA = D->Lhs.A.LoadEntry; + CodeEntry* LoadX = D->Lhs.X.LoadEntry; + unsigned Len; + + /* Must be unchanged till Op */ + if ((D->Lhs.A.Flags & (LI_DIRECT | LI_RELOAD_Y)) != LI_DIRECT || + (D->Lhs.X.Flags & (LI_DIRECT | LI_RELOAD_Y)) != LI_DIRECT) { + return 0; + } + + /* Must have both load insns */ + if (LoadA == 0 || LoadX == 0) { + return 0; + } + + /* Must be loads from zp */ + if (LoadA->AM != AM65_ZP || LoadX->AM != AM65_ZP) { + return 0; + } + + /* Must be the same zp loc with high byte in X */ + Len = strlen (LoadA->Arg); + if (strncmp (LoadA->Arg, LoadX->Arg, Len) != 0 || + strcmp (LoadX->Arg + Len, "+1") != 0) { + return 0; + } + + /* Use the zero page location directly */ + D->ZPLo = LoadA->Arg; + D->ZPHi = LoadX->Arg; + return 1; +} + + + +void AddStoreLhsA (StackOpData* D) +/* Add a store to zero page after the push insn */ +{ + CodeEntry* X = NewCodeEntry (OP65_STA, AM65_ZP, D->ZPLo, 0, D->PushEntry->LI); + InsertEntry (D, X, D->PushIndex+1); +} + + + +void AddStoreLhsX (StackOpData* D) +/* Add a store to zero page after the push insn */ +{ + CodeEntry* X = NewCodeEntry (OP65_STX, AM65_ZP, D->ZPHi, 0, D->PushEntry->LI); + InsertEntry (D, X, D->PushIndex+1); +} + + + +void ReplacePushByStore (StackOpData* D) +/* Replace the call to the push subroutine by a store into the zero page +** location (actually, the push is not replaced, because we need it for +** later, but the name is still ok since the push will get removed at the +** end of each routine). +*/ +{ + /* Store the value into the zeropage instead of pushing it. Check high + ** byte first so that the store is later in A/X order. + */ + if ((D->Lhs.X.Flags & LI_DIRECT) == 0) { + AddStoreLhsX (D); + } + if ((D->Lhs.A.Flags & LI_DIRECT) == 0) { + AddStoreLhsA (D); + } +} + + + +void AddOpLow (StackOpData* D, opc_t OPC, LoadInfo* LI) +/* Add an op for the low byte of an operator. This function honours the +** OP_DIRECT and OP_RELOAD_Y flags and generates the necessary instructions. +** All code is inserted at the current insertion point. +*/ +{ + CodeEntry* X; + + if ((LI->A.Flags & LI_DIRECT) != 0) { + /* Op with a variable location. If the location is on the stack, we + ** need to reload the Y register. + */ + if ((LI->A.Flags & LI_RELOAD_Y) == 0) { + + /* opc ... */ + CodeEntry* LoadA = LI->A.LoadEntry; + X = NewCodeEntry (OPC, LoadA->AM, LoadA->Arg, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + + } else { + + if ((LI->A.Flags & LI_CHECK_Y) == 0) { + /* ldy #offs */ + X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (LI->A.Offs), 0, D->OpEntry->LI); + } else { + /* ldy src */ + X = NewCodeEntry (OP65_LDY, LI->A.LoadYEntry->AM, LI->A.LoadYEntry->Arg, 0, D->OpEntry->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); + } else { + /* opc src,y */ + X = NewCodeEntry (OPC, LI->A.LoadEntry->AM, LI->A.LoadEntry->Arg, 0, D->OpEntry->LI); + } + InsertEntry (D, X, D->IP++); + + } + + /* In both cases, we can remove the load */ + LI->A.Flags |= LI_REMOVE; + + } else { + + /* Op with temp storage */ + X = NewCodeEntry (OPC, AM65_ZP, D->ZPLo, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + + } +} + + + +void AddOpHigh (StackOpData* D, opc_t OPC, LoadInfo* LI, int KeepResult) +/* Add an op for the high byte of an operator. Special cases (constant values +** or similar) have to be checked separately, the function covers only the +** generic case. Code is inserted at the insertion point. +*/ +{ + CodeEntry* X; + + if (KeepResult) { + /* pha */ + X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + } + + /* txa */ + X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + + if ((LI->X.Flags & LI_DIRECT) != 0) { + + if ((LI->X.Flags & LI_RELOAD_Y) == 0) { + + /* opc xxx */ + CodeEntry* LoadX = LI->X.LoadEntry; + X = NewCodeEntry (OPC, LoadX->AM, LoadX->Arg, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + + } else { + + if ((LI->A.Flags & LI_CHECK_Y) == 0) { + /* ldy #const */ + X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (LI->X.Offs), 0, D->OpEntry->LI); + } else { + /* ldy src */ + X = NewCodeEntry (OP65_LDY, LI->X.LoadYEntry->AM, LI->X.LoadYEntry->Arg, 0, D->OpEntry->LI); + } + 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); + } else { + /* opc src,y */ + X = NewCodeEntry (OPC, LI->A.LoadEntry->AM, LI->A.LoadEntry->Arg, 0, D->OpEntry->LI); + } + InsertEntry (D, X, D->IP++); + } + + /* In both cases, we can remove the load */ + LI->X.Flags |= LI_REMOVE; + + } else { + /* opc zphi */ + X = NewCodeEntry (OPC, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + } + + if (KeepResult) { + /* tax */ + X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + + /* pla */ + X = NewCodeEntry (OP65_PLA, AM65_IMP, 0, 0, D->OpEntry->LI); + InsertEntry (D, X, D->IP++); + } +} + + + +void RemoveRegLoads (StackOpData* D, LoadInfo* LI) +/* Remove register load insns */ +{ + /* Both registers may be loaded with one insn, but DelEntry will in this + ** case clear the other one. + */ + if ((LI->A.Flags & LI_REMOVE) == LI_REMOVE) { + if (LI->A.LoadIndex >= 0 && + (LI->A.LoadEntry->Flags & CEF_DONT_REMOVE) == 0) { + DelEntry (D, LI->A.LoadIndex); + } + if (LI->A.XferIndex >= 0 && + (LI->A.XferEntry->Flags & CEF_DONT_REMOVE) == 0) { + DelEntry (D, LI->A.XferIndex); + } + } + if ((LI->X.Flags & LI_REMOVE) == LI_REMOVE) { + if (LI->X.LoadIndex >= 0 && + (LI->X.LoadEntry->Flags & CEF_DONT_REMOVE) == 0) { + DelEntry (D, LI->X.LoadIndex); + } + if (LI->X.XferIndex >= 0 && + (LI->X.XferEntry->Flags & CEF_DONT_REMOVE) == 0) { + DelEntry (D, LI->X.XferIndex); + } + } +} + + + +void RemoveRemainders (StackOpData* D) +/* Remove the code that is unnecessary after translation of the sequence */ +{ + /* Remove the register loads for lhs and rhs if nothing prevents that */ + RemoveRegLoads (D, &D->Lhs); + RemoveRegLoads (D, &D->Rhs); + + /* Remove the push and the operator routine */ + DelEntry (D, D->OpIndex); + DelEntry (D, D->PushIndex); +} + + + +static int CmpHarmless (const void* Key, const void* Entry) +/* Compare function for bsearch */ +{ + return strcmp (Key, *(const char**)Entry); +} + + + +int HarmlessCall (const char* Name) +/* Check if this is a call to a harmless subroutine that will not interrupt +** the pushax/op sequence when encountered. +*/ +{ + const char* const Tab[] = { + "aslax1", + "aslax2", + "aslax3", + "aslax4", + "aslaxy", + "asrax1", + "asrax2", + "asrax3", + "asrax4", + "asraxy", + "bcastax", + "bnegax", + "complax", + "decax1", + "decax2", + "decax3", + "decax4", + "decax5", + "decax6", + "decax7", + "decax8", + "decaxy", + "incax1", + "incax2", + "incax3", + "incax4", + "incax5", + "incax6", + "incax7", + "incax8", + "incaxy", + "ldaxidx", + "ldaxysp", + "negax", + "shlax1", + "shlax2", + "shlax3", + "shlax4", + "shlaxy", + "shrax1", + "shrax2", + "shrax3", + "shrax4", + "shraxy", + }; + + void* R = bsearch (Name, + Tab, + sizeof (Tab) / sizeof (Tab[0]), + sizeof (Tab[0]), + CmpHarmless); + return (R != 0); +} + + diff --git a/src/cc65/codeoptutil.h b/src/cc65/codeoptutil.h new file mode 100644 index 000000000..49a8ce60f --- /dev/null +++ b/src/cc65/codeoptutil.h @@ -0,0 +1,257 @@ +/*****************************************************************************/ +/* */ +/* codeoptutil.h */ +/* */ +/* Optimize operations that take operands via the stack */ +/* */ +/* */ +/* */ +/* (C) 2001 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* 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 CODEOPTUTIL_H +#define CODEOPTUTIL_H + + + +/* cc65 */ +#include "codeent.h" +#include "codeseg.h" + + + +/*****************************************************************************/ +/* Load tracking data */ +/*****************************************************************************/ + + + +/* LoadRegInfo flags set by DirectOp */ +typedef enum { + LI_NONE = 0x00, + LI_DIRECT = 0x01, /* Direct op may be used */ + LI_RELOAD_Y = 0x02, /* Reload index register Y */ + LI_REMOVE = 0x04, /* Load may be removed */ + LI_DONT_REMOVE = 0x08, /* Load may not be removed */ + LI_CHECK_ARG = 0x10, /* Load src might be modified later */ + LI_SRC_CHG = 0x20, /* Load src is possibly modified */ + LI_LOAD_INSN = 0x40, /* Has a load insn */ + LI_CHECK_Y = 0x80, /* Indexed load src might be modified later */ + LI_USED_BY_A = 0x100, /* Content used by RegA */ + LI_USED_BY_X = 0x200, /* Content used by RegX */ + LI_USED_BY_Y = 0x400, /* Content used by RegY */ + LI_SP = 0x800, /* Content on stack */ +} LI_FLAGS; + +/* Structure that tells us how to load the lhs values */ +typedef struct LoadRegInfo LoadRegInfo; +struct LoadRegInfo { + LI_FLAGS Flags; /* Tells us how to load */ + int LoadIndex; /* Index of load insn, -1 if invalid */ + CodeEntry* LoadEntry; /* The actual entry, 0 if invalid */ + int LoadYIndex; /* Index of Y-load insn, -1 if invalid */ + CodeEntry* LoadYEntry; /* The actual Y-load entry, 0 if invalid */ + int XferIndex; /* Index of transfer insn */ + CodeEntry* XferEntry; /* The actual transfer entry */ + int Offs; /* Stack offset if data is on stack */ +}; + +/* Now combined for both registers */ +typedef struct LoadInfo LoadInfo; +struct LoadInfo { + LoadRegInfo A; /* Info for A register */ + LoadRegInfo X; /* Info for X register */ + LoadRegInfo Y; /* Info for Y register */ +}; + +/* Structure forward decl */ +typedef struct StackOpData StackOpData; +typedef struct OptFuncDesc OptFuncDesc; + +/* Structure that holds the needed data */ +struct StackOpData { + CodeSeg* Code; /* Pointer to code segment */ + unsigned Flags; /* Flags to remember things */ + + /* Pointer to optimizer subfunction description */ + const OptFuncDesc* OptFunc; + + /* ZP register usage inside the sequence */ + unsigned ZPUsage; + unsigned ZPChanged; + + /* Freedom of registers inside the sequence */ + unsigned UsedRegs; /* Registers used */ + + /* Whether the rhs is changed multiple times */ + int RhsMultiChg; + + /* Register load information for lhs and rhs */ + LoadInfo Lhs; + LoadInfo Rhs; + + /* Several indices of insns in the code segment */ + int PushIndex; /* Index of call to pushax in codeseg */ + int OpIndex; /* Index of actual operation */ + + /* Pointers to insns in the code segment */ + CodeEntry* PrevEntry; /* Entry before the call to pushax */ + CodeEntry* PushEntry; /* Pointer to entry with call to pushax */ + CodeEntry* OpEntry; /* Pointer to entry with op */ + CodeEntry* NextEntry; /* Entry after the op */ + + const char* ZPLo; /* Lo byte of zero page loc to use */ + const char* ZPHi; /* Hi byte of zero page loc to use */ + unsigned IP; /* Insertion point used by some routines */ +}; + + + +/*****************************************************************************/ +/* Load tracking code */ +/*****************************************************************************/ + + + +void ClearLoadRegInfo (LoadRegInfo* LRI); +/* Clear a LoadRegInfo struct */ + +void CopyLoadRegInfo (LoadRegInfo* To, LoadRegInfo* From); +/* Copy a LoadRegInfo struct */ + +void FinalizeLoadRegInfo (LoadRegInfo* LRI, CodeSeg* S); +/* Prepare a LoadRegInfo struct for use */ + +void AdjustLoadRegInfo (LoadRegInfo* LRI, int Index, int Change); +/* Adjust a load register info struct after deleting or inserting an entry +** with a given index +*/ + +void ClearLoadInfo (LoadInfo* LI); +/* Clear a LoadInfo struct */ + +void CopyLoadInfo (LoadInfo* To, LoadInfo* From); +/* Copy a LoadInfo struct */ + +void FinalizeLoadInfo (LoadInfo* LI, CodeSeg* S); +/* Prepare a LoadInfo struct for use */ + +void AdjustLoadInfo (LoadInfo* LI, int Index, int Change); +/* Adjust a load info struct after deleting entry with a given index */ + +RegInfo* GetLastChangedRegInfo (StackOpData* D, LoadRegInfo* Reg); +/* Get RegInfo of the last insn entry that changed the reg */ + +unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I); +/* Track loads for a code entry. +** Return used registers. +*/ + +void SetDontRemoveEntryFlag (LoadRegInfo* LRI); +/* Flag the entry as non-removable according to register flags */ + +void ResetDontRemoveEntryFlag (LoadRegInfo* LRI); +/* Unflag the entry as non-removable according to register flags */ + +void SetDontRemoveEntryFlags (StackOpData* D); +/* Flag the entries as non-removable according to register flags */ + +void ResetDontRemoveEntryFlags (StackOpData* D); +/* Unflag the entries as non-removable according to register flags */ + +void ResetStackOpData (StackOpData* Data); +/* Reset the given data structure */ + + + +/*****************************************************************************/ +/* Helpers */ +/*****************************************************************************/ + + + +void InsertEntry (StackOpData* D, CodeEntry* E, int Index); +/* Insert a new entry. Depending on Index, D->PushIndex and D->OpIndex will +** be adjusted by this function. +*/ + +void DelEntry (StackOpData* D, int Index); +/* Delete an entry. Depending on Index, D->PushIndex and D->OpIndex will be +** adjusted by this function, and PushEntry/OpEntry may get invalidated. +*/ + +void AdjustStackOffset (StackOpData* D, unsigned Offs); +/* Adjust the offset for all stack accesses in the range PushIndex to OpIndex. +** OpIndex is adjusted according to the insertions. +*/ + +int IsRegVar (StackOpData* D); +/* If the value pushed is that of a zeropage variable that is unchanged until Op, +** replace ZPLo and ZPHi in the given StackOpData struct by the variable and return true. +** Otherwise leave D untouched and return false. +*/ + +void AddStoreLhsA (StackOpData* D); +/* Add a store to zero page after the push insn */ + +void AddStoreLhsX (StackOpData* D); +/* Add a store to zero page after the push insn */ + +void ReplacePushByStore (StackOpData* D); +/* Replace the call to the push subroutine by a store into the zero page +** location (actually, the push is not replaced, because we need it for +** later, but the name is still ok since the push will get removed at the +** end of each routine). +*/ + +void AddOpLow (StackOpData* D, opc_t OPC, LoadInfo* LI); +/* Add an op for the low byte of an operator. This function honours the +** OP_DIRECT and OP_RELOAD_Y flags and generates the necessary instructions. +** All code is inserted at the current insertion point. +*/ + +void AddOpHigh (StackOpData* D, opc_t OPC, LoadInfo* LI, int KeepResult); +/* Add an op for the high byte of an operator. Special cases (constant values +** or similar) have to be checked separately, the function covers only the +** generic case. Code is inserted at the insertion point. +*/ + +void RemoveRegLoads (StackOpData* D, LoadInfo* LI); +/* Remove register load insns */ + + +void RemoveRemainders (StackOpData* D); +/* Remove the code that is unnecessary after translation of the sequence */ + +int HarmlessCall (const char* Name); +/* Check if this is a call to a harmless subroutine that will not interrupt +** the pushax/op sequence when encountered. +*/ + +/* End of codeoptutil.h */ + +#endif diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index c31b0ec97..457f9ff1f 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -41,57 +41,12 @@ /* cc65 */ #include "codeent.h" #include "codeinfo.h" +#include "codeoptutil.h" #include "coptstop.h" #include "error.h" -/*****************************************************************************/ -/* Load tracking data */ -/*****************************************************************************/ - - - -/* LoadRegInfo flags set by DirectOp */ -typedef enum { - LI_NONE = 0x00, - LI_DIRECT = 0x01, /* Direct op may be used */ - LI_RELOAD_Y = 0x02, /* Reload index register Y */ - LI_REMOVE = 0x04, /* Load may be removed */ - LI_DONT_REMOVE = 0x08, /* Load may not be removed */ - LI_CHECK_ARG = 0x10, /* Load src might be modified later */ - LI_SRC_CHG = 0x20, /* Load src is possibly modified */ - LI_LOAD_INSN = 0x40, /* Has a load insn */ - LI_CHECK_Y = 0x80, /* Indexed load src might be modified later */ - LI_USED_BY_A = 0x100, /* Content used by RegA */ - LI_USED_BY_X = 0x200, /* Content used by RegX */ - LI_USED_BY_Y = 0x400, /* Content used by RegY */ - LI_SP = 0x800, /* Content on stack */ -} LI_FLAGS; - -/* Structure that tells us how to load the lhs values */ -typedef struct LoadRegInfo LoadRegInfo; -struct LoadRegInfo { - LI_FLAGS Flags; /* Tells us how to load */ - int LoadIndex; /* Index of load insn, -1 if invalid */ - CodeEntry* LoadEntry; /* The actual entry, 0 if invalid */ - int LoadYIndex; /* Index of Y-load insn, -1 if invalid */ - CodeEntry* LoadYEntry; /* The actual Y-load entry, 0 if invalid */ - int XferIndex; /* Index of transfer insn */ - CodeEntry* XferEntry; /* The actual transfer entry */ - int Offs; /* Stack offset if data is on stack */ -}; - -/* Now combined for both registers */ -typedef struct LoadInfo LoadInfo; -struct LoadInfo { - LoadRegInfo A; /* Info for A register */ - LoadRegInfo X; /* Info for X register */ - LoadRegInfo Y; /* Info for Y register */ -}; - - - /*****************************************************************************/ /* Data */ /*****************************************************************************/ @@ -121,9 +76,6 @@ typedef enum { OP_RHS_REMOVE_DIRECT = 0xC000, /* RHS must be directly removable */ } OP_FLAGS; -/* Structure forward decl */ -typedef struct StackOpData StackOpData; - /* Structure that describes an optimizer subfunction for a specific op */ typedef unsigned (*OptFunc) (StackOpData* D); typedef struct OptFuncDesc OptFuncDesc; @@ -134,434 +86,6 @@ struct OptFuncDesc { OP_FLAGS Flags; /* Flags */ }; -/* Structure that holds the needed data */ -struct StackOpData { - CodeSeg* Code; /* Pointer to code segment */ - unsigned Flags; /* Flags to remember things */ - - /* Pointer to optimizer subfunction description */ - const OptFuncDesc* OptFunc; - - /* ZP register usage inside the sequence */ - unsigned ZPUsage; - unsigned ZPChanged; - - /* Freedom of registers inside the sequence */ - unsigned UsedRegs; /* Registers used */ - - /* Whether the rhs is changed multiple times */ - int RhsMultiChg; - - /* Register load information for lhs and rhs */ - LoadInfo Lhs; - LoadInfo Rhs; - - /* Several indices of insns in the code segment */ - int PushIndex; /* Index of call to pushax in codeseg */ - int OpIndex; /* Index of actual operation */ - - /* Pointers to insns in the code segment */ - CodeEntry* PrevEntry; /* Entry before the call to pushax */ - CodeEntry* PushEntry; /* Pointer to entry with call to pushax */ - CodeEntry* OpEntry; /* Pointer to entry with op */ - CodeEntry* NextEntry; /* Entry after the op */ - - const char* ZPLo; /* Lo byte of zero page loc to use */ - const char* ZPHi; /* Hi byte of zero page loc to use */ - unsigned IP; /* Insertion point used by some routines */ -}; - - - -/*****************************************************************************/ -/* Load tracking code */ -/*****************************************************************************/ - - - -static void ClearLoadRegInfo (LoadRegInfo* RI) -/* Clear a LoadRegInfo struct */ -{ - RI->Flags = LI_NONE; - RI->LoadIndex = -1; - RI->LoadEntry = 0; - RI->LoadYIndex = -1; - RI->LoadYEntry = 0; - RI->XferIndex = -1; - RI->XferEntry = 0; - RI->Offs = 0; -} - - - -static void CopyLoadRegInfo (LoadRegInfo* To, LoadRegInfo* From) -/* Copy a LoadRegInfo struct */ -{ - To->Flags = From->Flags; - To->LoadIndex = From->LoadIndex; - To->LoadEntry = From->LoadEntry; - To->LoadYIndex = From->LoadYIndex; - To->LoadYEntry = From->LoadYEntry; - To->XferIndex = From->XferIndex; - To->XferEntry = From->XferEntry; - To->Offs = From->Offs; -} - - - -static void FinalizeLoadRegInfo (LoadRegInfo* RI, CodeSeg* S) -/* Prepare a LoadRegInfo struct for use */ -{ - /* Get the entries */ - if (RI->LoadIndex >= 0) { - RI->LoadEntry = CS_GetEntry (S, RI->LoadIndex); - } else { - RI->LoadEntry = 0; - } - if (RI->XferIndex >= 0) { - RI->XferEntry = CS_GetEntry (S, RI->XferIndex); - } else { - RI->XferEntry = 0; - } - /* Load from src not modified before op can be treated as direct */ - if ((RI->Flags & LI_SRC_CHG) == 0 && - (RI->Flags & (LI_CHECK_ARG | LI_CHECK_Y)) != 0) { - RI->Flags |= LI_DIRECT; - if ((RI->Flags & LI_CHECK_Y) != 0) { - RI->Flags |= LI_RELOAD_Y; - } - } - /* We cannot ldy src,y */ - if ((RI->Flags & LI_RELOAD_Y) != 0 && - RI->LoadYEntry != 0 && - (RI->LoadYEntry->Use & REG_Y) == REG_Y) { - RI->Flags &= ~LI_DIRECT; - } -} - - - -static void ClearLoadInfo (LoadInfo* LI) -/* Clear a LoadInfo struct */ -{ - ClearLoadRegInfo (&LI->A); - ClearLoadRegInfo (&LI->X); - ClearLoadRegInfo (&LI->Y); -} - - - -static void CopyLoadInfo (LoadInfo* To, LoadInfo* From) -/* Copy a LoadInfo struct */ -{ - CopyLoadRegInfo (&To->A, &From->A); - CopyLoadRegInfo (&To->X, &From->X); - CopyLoadRegInfo (&To->Y, &From->Y); -} - - - -static void AdjustLoadRegInfo (LoadRegInfo* RI, int Index, int Change) -/* Adjust a load register info struct after deleting or inserting an entry -** with a given index -*/ -{ - CHECK (abs (Change) == 1); - if (Change < 0) { - /* Deletion */ - if (Index < RI->LoadIndex) { - --RI->LoadIndex; - } else if (Index == RI->LoadIndex) { - /* Has been removed */ - RI->LoadIndex = -1; - RI->LoadEntry = 0; - } - if (Index < RI->XferIndex) { - --RI->XferIndex; - } else if (Index == RI->XferIndex) { - /* Has been removed */ - RI->XferIndex = -1; - RI->XferEntry = 0; - } - } else { - /* Insertion */ - if (Index <= RI->LoadIndex) { - ++RI->LoadIndex; - } - if (Index <= RI->XferIndex) { - ++RI->XferIndex; - } - } -} - - - -static void FinalizeLoadInfo (LoadInfo* LI, CodeSeg* S) -/* Prepare a LoadInfo struct for use */ -{ - /* Get the entries */ - FinalizeLoadRegInfo (&LI->A, S); - FinalizeLoadRegInfo (&LI->X, S); - FinalizeLoadRegInfo (&LI->Y, S); -} - - - -static void AdjustLoadInfo (LoadInfo* LI, int Index, int Change) -/* Adjust a load info struct after deleting entry with a given index */ -{ - AdjustLoadRegInfo (&LI->A, Index, Change); - AdjustLoadRegInfo (&LI->X, Index, Change); - AdjustLoadRegInfo (&LI->Y, Index, Change); -} - - - -static int Affected (LoadRegInfo* RI, const CodeEntry* E) -/* Check if the load src may be modified between the pushax and op */ -{ - fncls_t fncls; - unsigned int Use; - unsigned int Chg; - unsigned int UseToCheck = 0; - - if ((RI->Flags & (LI_CHECK_ARG | LI_CHECK_Y)) != 0) { - if (E->AM == AM65_IMM || E->AM == AM65_ACC || E->AM == AM65_IMP || E->AM == AM65_BRA) { - return 0; - } - CHECK ((RI->Flags & LI_CHECK_ARG) == 0 || RI->LoadEntry != 0); - CHECK ((RI->Flags & LI_CHECK_Y) == 0 || RI->LoadYEntry != 0); - - if ((RI->Flags & LI_CHECK_ARG) != 0) { - UseToCheck |= RI->LoadEntry->Use; - } - - if ((RI->Flags & LI_CHECK_Y) != 0) { - UseToCheck |= RI->LoadYEntry->Use; - } - - if (E->OPC == OP65_JSR) { - /* Try to know about the function */ - fncls = GetFuncInfo (E->Arg, &Use, &Chg); - if ((UseToCheck & Chg & REG_ALL) == 0 && - fncls == FNCLS_BUILTIN) { - /* Builtin functions are known to be harmless */ - return 0; - } - /* Otherwise play it safe */ - return 1; - } else if (E->OPC == OP65_DEC || E->OPC == OP65_INC || - E->OPC == OP65_ASL || E->OPC == OP65_LSR || - E->OPC == OP65_ROL || E->OPC == OP65_ROR || - E->OPC == OP65_TRB || E->OPC == OP65_TSB || - E->OPC == OP65_STA || E->OPC == OP65_STX || E->OPC == OP65_STY) { - if ((E->AM == AM65_ABS || E->AM == AM65_ZP)) { - if ((RI->Flags & LI_CHECK_ARG) != 0 && - strcmp (RI->LoadEntry->Arg, E->Arg) == 0) { - return 1; - } - if ((RI->Flags & LI_CHECK_Y) != 0 && - strcmp (RI->LoadYEntry->Arg, E->Arg) == 0) { - return 1; - } - return 0; - } - /* We could've check further for more cases where the load target isn't modified, - ** But for now let's save the trouble and just play it safe. */ - return 1; - } - } - return 0; -} - - - -static void HonourUseAndChg (LoadRegInfo* RI, unsigned Reg, const CodeEntry* E, int I) -/* Honour use and change flags for an instruction */ -{ - if ((E->Chg & Reg) != 0) { - /* Remember this as an indirect load */ - ClearLoadRegInfo (RI); - RI->LoadIndex = I; - RI->XferIndex = -1; - RI->Flags = 0; - } else if (Affected (RI, E)) { - RI->Flags |= LI_SRC_CHG; - } -} - - - -static unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I) -/* Track loads for a code entry. -** Return used registers. -*/ -{ - unsigned Used; - CodeEntry* E = CS_GetEntry (S, I); - CHECK (E != 0); - - /* By default */ - Used = E->Use; - - /* Whether we had a load or xfer op before or not, the newly loaded value - ** will be the real one used for the pushax/op unless it's overwritten, - ** so we can just reset the flags about it in such cases. - */ - if (E->Info & OF_LOAD) { - - LoadRegInfo* RI = 0; - - /* Determine, which register was loaded */ - if (E->Chg & REG_A) { - RI = &LI->A; - } else if (E->Chg & REG_X) { - RI = &LI->X; - } else if (E->Chg & REG_Y) { - RI = &LI->Y; - } - CHECK (RI != 0); - - /* Remember the load */ - RI->LoadIndex = I; - RI->XferIndex = -1; - - /* Set load flags */ - RI->Flags = LI_LOAD_INSN; - if (E->AM == AM65_IMM) { - /* These insns are all ok and replaceable */ - RI->Flags |= LI_DIRECT; - } else if (E->AM == AM65_ZP || E->AM == AM65_ABS) { - /* These insns are replaceable only if they are not modified later */ - RI->Flags |= LI_CHECK_ARG; - } else if (E->AM == AM65_ZPY || E->AM == AM65_ABSY) { - /* These insns are replaceable only if they are not modified later */ - RI->Flags |= LI_CHECK_ARG | LI_CHECK_Y; - } else if (E->AM == AM65_ZP_INDY && - strcmp (E->Arg, "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 - ** these locations may change between the push and the actual - ** operation. - */ - RI->Flags |= LI_DIRECT | LI_CHECK_Y | LI_SP; - - /* Reg Y can be regarded as unused if this load is removed */ - Used &= ~REG_Y; - if (RI == &LI->A) { - LI->Y.Flags |= LI_USED_BY_A; - } else { - LI->Y.Flags |= LI_USED_BY_X; - } - } - - /* If the load offset has a known value, we can just remember and reload - ** it into the index register later. - */ - if ((RI->Flags & LI_CHECK_Y) != 0) { - if (RegValIsKnown (E->RI->In.RegY)) { - RI->Offs = (unsigned char)E->RI->In.RegY; - RI->Flags &= ~LI_CHECK_Y; - RI->Flags |= LI_RELOAD_Y; - } else { - /* We need to check if the src of Y is changed */ - RI->LoadYIndex = LI->Y.LoadIndex; - RI->LoadYEntry = CS_GetEntry (S, RI->LoadYIndex); - } - } - - /* Watch for any change of the load target */ - if ((RI->Flags & LI_CHECK_ARG) != 0) { - RI->LoadEntry = CS_GetEntry (S, I); - } - - } else if (E->Info & OF_XFR) { - - /* Determine source and target of the transfer and handle the TSX insn */ - LoadRegInfo* Src; - LoadRegInfo* Tgt; - switch (E->OPC) { - case OP65_TAX: - Src = &LI->A; - Tgt = &LI->X; - Used &= ~REG_A; - Src->Flags |= LI_USED_BY_X; - break; - case OP65_TAY: - Src = &LI->A; - Tgt = &LI->Y; - Used &= ~REG_A; - Src->Flags |= LI_USED_BY_Y; - break; - case OP65_TXA: - Src = &LI->X; - Tgt = &LI->A; - Used &= ~REG_X; - Src->Flags |= LI_USED_BY_A; - break; - case OP65_TYA: - Src = &LI->Y; - Tgt = &LI->A; - Used &= ~REG_Y; - Src->Flags |= LI_USED_BY_A; - break; - case OP65_TSX: - ClearLoadRegInfo (&LI->X); - return Used; - case OP65_TXS: - return Used; - default: Internal ("Unknown XFR insn in TrackLoads"); - } - - /* Transfer the data */ - Tgt->LoadIndex = Src->LoadIndex; - Tgt->LoadEntry = Src->LoadEntry; - Tgt->LoadYIndex = Src->LoadYIndex; - Tgt->LoadYEntry = Src->LoadYEntry; - Tgt->XferIndex = I; - Tgt->Offs = Src->Offs; - Tgt->Flags = Src->Flags; - - } else if (CE_IsCallTo (E, "ldaxysp") && RegValIsKnown (E->RI->In.RegY)) { - - /* Both registers set, Y changed */ - LI->A.LoadIndex = I; - LI->A.XferIndex = -1; - LI->A.Flags = (LI_LOAD_INSN | LI_DIRECT | LI_RELOAD_Y | LI_SP); - LI->A.Offs = (unsigned char) E->RI->In.RegY - 1; - - LI->X.LoadIndex = I; - LI->X.XferIndex = -1; - LI->X.Flags = (LI_LOAD_INSN | LI_DIRECT | LI_RELOAD_Y | LI_SP); - LI->X.Offs = (unsigned char) E->RI->In.RegY; - - /* Reg Y can be regarded as unused if this load is removed */ - Used &= ~REG_Y; - LI->Y.Flags |= LI_USED_BY_A | LI_USED_BY_X; - - } else { - HonourUseAndChg (&LI->A, REG_A, E, I); - HonourUseAndChg (&LI->X, REG_X, E, I); - HonourUseAndChg (&LI->Y, REG_Y, E, I); - - /* The other operand may be affected too */ - if (LLI != 0) { - if (Affected (&LLI->A, E)) { - LLI->A.Flags |= LI_SRC_CHG; - } - if (Affected (&LLI->X, E)) { - LLI->X.Flags |= LI_SRC_CHG; - } - if (Affected (&LLI->Y, E)) { - LLI->Y.Flags |= LI_SRC_CHG; - } - } - } - - return Used; -} - /*****************************************************************************/ @@ -570,421 +94,6 @@ static unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I) -static void InsertEntry (StackOpData* D, CodeEntry* E, int Index) -/* Insert a new entry. Depending on Index, D->PushIndex and D->OpIndex will -** be adjusted by this function. -*/ -{ - /* Insert the entry into the code segment */ - CS_InsertEntry (D->Code, E, Index); - - /* Adjust register loads if necessary */ - AdjustLoadInfo (&D->Lhs, Index, 1); - AdjustLoadInfo (&D->Rhs, Index, 1); - - /* Adjust the indices if necessary */ - if (D->PushEntry && Index <= D->PushIndex) { - ++D->PushIndex; - } - if (D->OpEntry && Index <= D->OpIndex) { - ++D->OpIndex; - } -} - - - -static void DelEntry (StackOpData* D, int Index) -/* Delete an entry. Depending on Index, D->PushIndex and D->OpIndex will be -** adjusted by this function, and PushEntry/OpEntry may get invalidated. -*/ -{ - /* Delete the entry from the code segment */ - CS_DelEntry (D->Code, Index); - - /* Adjust register loads if necessary */ - AdjustLoadInfo (&D->Lhs, Index, -1); - AdjustLoadInfo (&D->Rhs, Index, -1); - - /* Adjust the other indices if necessary */ - if (Index < D->PushIndex) { - --D->PushIndex; - } else if (Index == D->PushIndex) { - D->PushEntry = 0; - } - if (Index < D->OpIndex) { - --D->OpIndex; - } else if (Index == D->OpIndex) { - D->OpEntry = 0; - } -} - - - -static void AdjustStackOffset (StackOpData* D, unsigned Offs) -/* Adjust the offset for all stack accesses in the range PushIndex to OpIndex. -** OpIndex is adjusted according to the insertions. -*/ -{ - /* Walk over all entries */ - int I = D->PushIndex + 1; - while (I < D->OpIndex) { - - CodeEntry* E = CS_GetEntry (D->Code, I); - - /* Check if this entry does a stack access, and if so, if it's a plain - ** load from stack, since this is needed later. - */ - int Correction = 0; - if ((E->Use & REG_SP) != 0) { - - /* Check for some things that should not happen */ - CHECK (E->AM == AM65_ZP_INDY || E->RI->In.RegY >= (short) Offs); - CHECK (strcmp (E->Arg, "sp") == 0); - /* We need to correct this one */ - Correction = (E->OPC == OP65_LDA)? 2 : 1; - - } else if (CE_IsCallTo (E, "ldaxysp")) { - /* We need to correct this one */ - Correction = 1; - } - - if (Correction) { - /* Get the code entry before this one. If it's a LDY, adjust the - ** value. - */ - CodeEntry* P = CS_GetPrevEntry (D->Code, I); - if (P && P->OPC == OP65_LDY && CE_IsConstImm (P)) { - /* The Y load is just before the stack access, adjust it */ - CE_SetNumArg (P, P->Num - Offs); - } else { - /* Insert a new load instruction before the stack access */ - const char* Arg = MakeHexArg (E->RI->In.RegY - Offs); - CodeEntry* X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); - InsertEntry (D, X, I++); - } - - /* If we need the value of Y later, be sure to reload it */ - if (RegYUsed (D->Code, I+1)) { - CodeEntry* N; - const char* Arg = MakeHexArg (E->RI->In.RegY); - if (Correction == 2 && (N = CS_GetNextEntry(D->Code, I)) != 0 && - ((N->Info & OF_ZBRA) != 0) && N->JumpTo != 0) { - /* The Y register is used but the load instruction loads A - ** and is followed by a branch that evaluates the zero flag. - ** This means that we cannot just insert the load insn - ** for the Y register at this place, because it would - ** destroy the Z flag. Instead place load insns at the - ** target of the branch and after it. - ** Note: There is a chance that this code won't work. The - ** jump may be a backwards jump (in which case the stack - ** offset has already been adjusted) or there may be other - ** instructions between the load and the conditional jump. - ** Currently the compiler does not generate such code, but - ** it is possible to force the optimizer into something - ** invalid by use of inline assembler. - */ - - /* Add load insn after the branch */ - CodeEntry* X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); - InsertEntry (D, X, I+2); - - /* Add load insn before branch target */ - CodeEntry* Y = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); - int J = CS_GetEntryIndex (D->Code, N->JumpTo->Owner); - CHECK (J > I); /* Must not happen */ - InsertEntry (D, Y, J); - - /* Move the label to the new insn */ - CodeLabel* L = CS_GenLabel (D->Code, Y); - CS_MoveLabelRef (D->Code, N, L); - } else { - CodeEntry* X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); - InsertEntry (D, X, I+1); - /* Skip this instruction in the next round */ - ++I; - } - } - } - - /* Next entry */ - ++I; - } - - /* If we have rhs load insns that load from stack, we'll have to adjust - ** the offsets for these also. - */ - if ((D->Rhs.A.Flags & (LI_RELOAD_Y | LI_SP | LI_CHECK_Y)) == (LI_RELOAD_Y | LI_SP)) { - D->Rhs.A.Offs -= Offs; - } - if ((D->Rhs.X.Flags & (LI_RELOAD_Y | LI_SP | LI_CHECK_Y)) == (LI_RELOAD_Y | LI_SP)) { - D->Rhs.X.Offs -= Offs; - } -} - - - -static void AddStoreLhsA (StackOpData* D) -/* Add a store to zero page after the push insn */ -{ - CodeEntry* X = NewCodeEntry (OP65_STA, AM65_ZP, D->ZPLo, 0, D->PushEntry->LI); - InsertEntry (D, X, D->PushIndex+1); -} - - - -static void AddStoreLhsX (StackOpData* D) -/* Add a store to zero page after the push insn */ -{ - CodeEntry* X = NewCodeEntry (OP65_STX, AM65_ZP, D->ZPHi, 0, D->PushEntry->LI); - InsertEntry (D, X, D->PushIndex+1); -} - - - -static void ReplacePushByStore (StackOpData* D) -/* Replace the call to the push subroutine by a store into the zero page -** location (actually, the push is not replaced, because we need it for -** later, but the name is still ok since the push will get removed at the -** end of each routine). -*/ -{ - /* Store the value into the zeropage instead of pushing it. Check high - ** byte first so that the store is later in A/X order. - */ - if ((D->Lhs.X.Flags & LI_DIRECT) == 0) { - AddStoreLhsX (D); - } - if ((D->Lhs.A.Flags & LI_DIRECT) == 0) { - AddStoreLhsA (D); - } -} - - - -static void AddOpLow (StackOpData* D, opc_t OPC, LoadInfo* LI) -/* Add an op for the low byte of an operator. This function honours the -** OP_DIRECT and OP_RELOAD_Y flags and generates the necessary instructions. -** All code is inserted at the current insertion point. -*/ -{ - CodeEntry* X; - - if ((LI->A.Flags & LI_DIRECT) != 0) { - /* Op with a variable location. If the location is on the stack, we - ** need to reload the Y register. - */ - if ((LI->A.Flags & LI_RELOAD_Y) == 0) { - - /* opc ... */ - CodeEntry* LoadA = LI->A.LoadEntry; - X = NewCodeEntry (OPC, LoadA->AM, LoadA->Arg, 0, D->OpEntry->LI); - InsertEntry (D, X, D->IP++); - - } else { - - if ((LI->A.Flags & LI_CHECK_Y) == 0) { - /* ldy #offs */ - X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (LI->A.Offs), 0, D->OpEntry->LI); - } else { - /* ldy src */ - X = NewCodeEntry (OP65_LDY, LI->A.LoadYEntry->AM, LI->A.LoadYEntry->Arg, 0, D->OpEntry->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); - } else { - /* opc src,y */ - X = NewCodeEntry (OPC, LI->A.LoadEntry->AM, LI->A.LoadEntry->Arg, 0, D->OpEntry->LI); - } - InsertEntry (D, X, D->IP++); - - } - - /* In both cases, we can remove the load */ - LI->A.Flags |= LI_REMOVE; - - } else { - - /* Op with temp storage */ - X = NewCodeEntry (OPC, AM65_ZP, D->ZPLo, 0, D->OpEntry->LI); - InsertEntry (D, X, D->IP++); - - } -} - - - -static void AddOpHigh (StackOpData* D, opc_t OPC, LoadInfo* LI, int KeepResult) -/* Add an op for the high byte of an operator. Special cases (constant values -** or similar) have to be checked separately, the function covers only the -** generic case. Code is inserted at the insertion point. -*/ -{ - CodeEntry* X; - - if (KeepResult) { - /* pha */ - X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, D->OpEntry->LI); - InsertEntry (D, X, D->IP++); - } - - /* txa */ - X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, D->OpEntry->LI); - InsertEntry (D, X, D->IP++); - - if ((LI->X.Flags & LI_DIRECT) != 0) { - - if ((LI->X.Flags & LI_RELOAD_Y) == 0) { - - /* opc xxx */ - CodeEntry* LoadX = LI->X.LoadEntry; - X = NewCodeEntry (OPC, LoadX->AM, LoadX->Arg, 0, D->OpEntry->LI); - InsertEntry (D, X, D->IP++); - - } else { - - if ((LI->A.Flags & LI_CHECK_Y) == 0) { - /* ldy #const */ - X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (LI->X.Offs), 0, D->OpEntry->LI); - } else { - /* ldy src */ - X = NewCodeEntry (OP65_LDY, LI->X.LoadYEntry->AM, LI->X.LoadYEntry->Arg, 0, D->OpEntry->LI); - } - 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); - } else { - /* opc src,y */ - X = NewCodeEntry (OPC, LI->A.LoadEntry->AM, LI->A.LoadEntry->Arg, 0, D->OpEntry->LI); - } - InsertEntry (D, X, D->IP++); - } - - /* In both cases, we can remove the load */ - LI->X.Flags |= LI_REMOVE; - - } else { - /* opc zphi */ - X = NewCodeEntry (OPC, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI); - InsertEntry (D, X, D->IP++); - } - - if (KeepResult) { - /* tax */ - X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, D->OpEntry->LI); - InsertEntry (D, X, D->IP++); - - /* pla */ - X = NewCodeEntry (OP65_PLA, AM65_IMP, 0, 0, D->OpEntry->LI); - InsertEntry (D, X, D->IP++); - } -} - - - -static void RemoveRegLoads (StackOpData* D, LoadInfo* LI) -/* Remove register load insns */ -{ - /* Both registers may be loaded with one insn, but DelEntry will in this - ** case clear the other one. - */ - if ((LI->A.Flags & LI_REMOVE) == LI_REMOVE) { - if (LI->A.LoadIndex >= 0 && - (LI->A.LoadEntry->Flags & CEF_DONT_REMOVE) == 0) { - DelEntry (D, LI->A.LoadIndex); - } - if (LI->A.XferIndex >= 0 && - (LI->A.XferEntry->Flags & CEF_DONT_REMOVE) == 0) { - DelEntry (D, LI->A.XferIndex); - } - } - if ((LI->X.Flags & LI_REMOVE) == LI_REMOVE) { - if (LI->X.LoadIndex >= 0 && - (LI->X.LoadEntry->Flags & CEF_DONT_REMOVE) == 0) { - DelEntry (D, LI->X.LoadIndex); - } - if (LI->X.XferIndex >= 0 && - (LI->X.XferEntry->Flags & CEF_DONT_REMOVE) == 0) { - DelEntry (D, LI->X.XferIndex); - } - } -} - - - -static void RemoveRemainders (StackOpData* D) -/* Remove the code that is unnecessary after translation of the sequence */ -{ - /* Remove the register loads for lhs and rhs if nothing prevents that */ - RemoveRegLoads (D, &D->Lhs); - RemoveRegLoads (D, &D->Rhs); - - /* Remove the push and the operator routine */ - DelEntry (D, D->OpIndex); - DelEntry (D, D->PushIndex); -} - - - -static int IsRegVar (StackOpData* D) -/* If the value pushed is that of a zeropage variable that is unchanged until Op, -** replace ZPLo and ZPHi in the given StackOpData struct by the variable and return true. -** Otherwise leave D untouched and return false. -*/ -{ - CodeEntry* LoadA = D->Lhs.A.LoadEntry; - CodeEntry* LoadX = D->Lhs.X.LoadEntry; - unsigned Len; - - /* Must be unchanged till Op */ - if ((D->Lhs.A.Flags & (LI_DIRECT | LI_RELOAD_Y)) != LI_DIRECT || - (D->Lhs.X.Flags & (LI_DIRECT | LI_RELOAD_Y)) != LI_DIRECT) { - return 0; - } - - /* Must have both load insns */ - if (LoadA == 0 || LoadX == 0) { - return 0; - } - - /* Must be loads from zp */ - if (LoadA->AM != AM65_ZP || LoadX->AM != AM65_ZP) { - return 0; - } - - /* Must be the same zp loc with high byte in X */ - Len = strlen (LoadA->Arg); - if (strncmp (LoadA->Arg, LoadX->Arg, Len) != 0 || - strcmp (LoadX->Arg + Len, "+1") != 0) { - return 0; - } - - /* Use the zero page location directly */ - D->ZPLo = LoadA->Arg; - D->ZPHi = LoadX->Arg; - return 1; -} - - - -static RegInfo* GetLastChangedRegInfo (StackOpData* D, LoadRegInfo* Reg) -/* Get RegInfo of the last load insn entry */ -{ - CodeEntry* E; - - if (Reg->LoadIndex >= 0 && (E = CS_GetEntry (D->Code, Reg->LoadIndex)) != 0) { - return E->RI; - } - - return 0; -} - - - static int SameRegAValue (StackOpData* D) /* Check if Rhs Reg A == Lhs Reg A */ { @@ -2304,94 +1413,6 @@ static const OptFuncDesc* FindFunc (const OptFuncDesc FuncTable[], size_t Count, -static int CmpHarmless (const void* Key, const void* Entry) -/* Compare function for bsearch */ -{ - return strcmp (Key, *(const char**)Entry); -} - - - -static int HarmlessCall (const char* Name) -/* Check if this is a call to a harmless subroutine that will not interrupt -** the pushax/op sequence when encountered. -*/ -{ - static const char* const Tab[] = { - "aslax1", - "aslax2", - "aslax3", - "aslax4", - "aslaxy", - "asrax1", - "asrax2", - "asrax3", - "asrax4", - "asraxy", - "bcastax", - "bnegax", - "complax", - "decax1", - "decax2", - "decax3", - "decax4", - "decax5", - "decax6", - "decax7", - "decax8", - "decaxy", - "incax1", - "incax2", - "incax3", - "incax4", - "incax5", - "incax6", - "incax7", - "incax8", - "incaxy", - "ldaxidx", - "ldaxysp", - "negax", - "shlax1", - "shlax2", - "shlax3", - "shlax4", - "shlaxy", - "shrax1", - "shrax2", - "shrax3", - "shrax4", - "shraxy", - }; - - void* R = bsearch (Name, - Tab, - sizeof (Tab) / sizeof (Tab[0]), - sizeof (Tab[0]), - CmpHarmless); - return (R != 0); -} - - - -static void ResetStackOpData (StackOpData* Data) -/* Reset the given data structure */ -{ - Data->OptFunc = 0; - Data->ZPUsage = REG_NONE; - Data->ZPChanged = REG_NONE; - Data->UsedRegs = REG_NONE; - Data->RhsMultiChg = 0; - - ClearLoadInfo (&Data->Lhs); - ClearLoadInfo (&Data->Rhs); - - Data->PushIndex = -1; - Data->OpIndex = -1; -} - - - static int PreCondOk (StackOpData* D) /* Check if the preconditions for a call to the optimizer subfunction are ** satisfied. As a side effect, this function will also choose the zero page @@ -2701,52 +1722,6 @@ static int RegAPreCondOk (StackOpData* D) -static void SetDontRemoveEntryFlag (LoadRegInfo* RI) -/* Flag the entry as non-removable according to register flags */ -{ - if (RI->Flags & LI_DONT_REMOVE) { - if (RI->LoadEntry != 0) { - RI->LoadEntry->Flags |= CEF_DONT_REMOVE; - } - } -} - - - -static void ResetDontRemoveEntryFlag (LoadRegInfo* RI) -/* Unflag the entry as non-removable according to register flags */ -{ - if (RI->Flags & LI_DONT_REMOVE) { - if (RI->LoadEntry != 0) { - RI->LoadEntry->Flags &= ~CEF_DONT_REMOVE; - } - } -} - - - -static void SetDontRemoveEntryFlags (StackOpData* D) -/* Flag the entries as non-removable according to register flags */ -{ - SetDontRemoveEntryFlag (&D->Lhs.A); - SetDontRemoveEntryFlag (&D->Lhs.X); - SetDontRemoveEntryFlag (&D->Rhs.A); - SetDontRemoveEntryFlag (&D->Rhs.X); -} - - - -static void ResetDontRemoveEntryFlags (StackOpData* D) -/* Unflag the entries as non-removable according to register flags */ -{ - ResetDontRemoveEntryFlag (&D->Lhs.A); - ResetDontRemoveEntryFlag (&D->Lhs.X); - ResetDontRemoveEntryFlag (&D->Rhs.A); - ResetDontRemoveEntryFlag (&D->Rhs.X); -} - - - unsigned OptStackOps (CodeSeg* S) /* Optimize operations that take operands via the stack */ { From f3771a465d9bb001ff8c636b6e8856d36023fa73 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 16 Apr 2020 17:17:08 +0800 Subject: [PATCH 1726/2161] Fixed various issues in the usage-tracking code. Added some utility functions. --- src/cc65/codeoptutil.c | 2348 +++++++++++++++++++++++++++++++++++++--- src/cc65/codeoptutil.h | 283 ++++- src/cc65/coptstop.c | 156 ++- 3 files changed, 2509 insertions(+), 278 deletions(-) diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index 999c18d33..46acbaaff 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -52,17 +52,17 @@ -void ClearLoadRegInfo (LoadRegInfo* RI) +void ClearLoadRegInfo (LoadRegInfo* LRI) /* Clear a LoadRegInfo struct */ { - RI->Flags = LI_NONE; - RI->LoadIndex = -1; - RI->LoadEntry = 0; - RI->LoadYIndex = -1; - RI->LoadYEntry = 0; - RI->XferIndex = -1; - RI->XferEntry = 0; - RI->Offs = 0; + LRI->Flags = LI_NONE; + LRI->LoadIndex = -1; + LRI->LoadEntry = 0; + LRI->LoadYIndex = -1; + LRI->LoadYEntry = 0; + LRI->ChgIndex = -1; + LRI->ChgEntry = 0; + LRI->Offs = 0; } @@ -75,46 +75,52 @@ void CopyLoadRegInfo (LoadRegInfo* To, LoadRegInfo* From) To->LoadEntry = From->LoadEntry; To->LoadYIndex = From->LoadYIndex; To->LoadYEntry = From->LoadYEntry; - To->XferIndex = From->XferIndex; - To->XferEntry = From->XferEntry; + To->ChgIndex = From->ChgIndex; + To->ChgEntry = From->ChgEntry; To->Offs = From->Offs; } -void FinalizeLoadRegInfo (LoadRegInfo* RI, CodeSeg* S) +void FinalizeLoadRegInfo (LoadRegInfo* LRI, CodeSeg* S) /* Prepare a LoadRegInfo struct for use */ { /* Get the entries */ - if (RI->LoadIndex >= 0) { - RI->LoadEntry = CS_GetEntry (S, RI->LoadIndex); + if (LRI->LoadIndex >= 0) { + LRI->LoadEntry = CS_GetEntry (S, LRI->LoadIndex); } else { - RI->LoadEntry = 0; + LRI->LoadEntry = 0; } - if (RI->XferIndex >= 0) { - RI->XferEntry = CS_GetEntry (S, RI->XferIndex); + if (LRI->LoadYIndex >= 0) { + LRI->LoadYEntry = CS_GetEntry (S, LRI->LoadYIndex); } else { - RI->XferEntry = 0; + LRI->LoadYEntry = 0; } + if (LRI->ChgIndex >= 0) { + LRI->ChgEntry = CS_GetEntry (S, LRI->ChgIndex); + } else { + LRI->ChgEntry = 0; + } + /* Load from src not modified before op can be treated as direct */ - if ((RI->Flags & LI_SRC_CHG) == 0 && - (RI->Flags & (LI_CHECK_ARG | LI_CHECK_Y)) != 0) { - RI->Flags |= LI_DIRECT; - if ((RI->Flags & LI_CHECK_Y) != 0) { - RI->Flags |= LI_RELOAD_Y; + if ((LRI->Flags & LI_SRC_CHG) == 0 && + (LRI->Flags & (LI_CHECK_ARG | LI_CHECK_Y)) != 0) { + LRI->Flags |= LI_DIRECT; + if ((LRI->Flags & LI_CHECK_Y) != 0) { + LRI->Flags |= LI_RELOAD_Y; } } - /* We cannot ldy src,y */ - if ((RI->Flags & LI_RELOAD_Y) != 0 && - RI->LoadYEntry != 0 && - (RI->LoadYEntry->Use & REG_Y) == REG_Y) { - RI->Flags &= ~LI_DIRECT; + /* We cannot ldy ??? or ldy src,y */ + if ((LRI->Flags & LI_CHECK_Y) != 0 && + (LRI->LoadYEntry == 0 || + (LRI->LoadYEntry->Use & REG_Y) == REG_Y)) { + LRI->Flags &= ~LI_DIRECT; } } -void AdjustLoadRegInfo (LoadRegInfo* RI, int Index, int Change) +void AdjustLoadRegInfo (LoadRegInfo* LRI, int Index, int Change) /* Adjust a load register info struct after deleting or inserting an entry ** with a given index */ @@ -122,27 +128,37 @@ void AdjustLoadRegInfo (LoadRegInfo* RI, int Index, int Change) CHECK (abs (Change) == 1); if (Change < 0) { /* Deletion */ - if (Index < RI->LoadIndex) { - --RI->LoadIndex; - } else if (Index == RI->LoadIndex) { + if (Index < LRI->LoadIndex) { + --LRI->LoadIndex; + } else if (Index == LRI->LoadIndex) { /* Has been removed */ - RI->LoadIndex = -1; - RI->LoadEntry = 0; + LRI->LoadIndex = -1; + LRI->LoadEntry = 0; } - if (Index < RI->XferIndex) { - --RI->XferIndex; - } else if (Index == RI->XferIndex) { + if (Index < LRI->LoadYIndex) { + --LRI->LoadIndex; + } else if (Index == LRI->LoadYIndex) { /* Has been removed */ - RI->XferIndex = -1; - RI->XferEntry = 0; + LRI->LoadYIndex = -1; + LRI->LoadYEntry = 0; + } + if (Index < LRI->ChgIndex) { + --LRI->ChgIndex; + } else if (Index == LRI->ChgIndex) { + /* Has been removed */ + LRI->ChgIndex = -1; + LRI->ChgEntry = 0; } } else { /* Insertion */ - if (Index <= RI->LoadIndex) { - ++RI->LoadIndex; + if (Index <= LRI->LoadIndex) { + ++LRI->LoadIndex; } - if (Index <= RI->XferIndex) { - ++RI->XferIndex; + if (Index <= LRI->LoadYIndex) { + ++LRI->LoadYIndex; + } + if (Index <= LRI->ChgIndex) { + ++LRI->ChgIndex; } } } @@ -191,11 +207,11 @@ void AdjustLoadInfo (LoadInfo* LI, int Index, int Change) RegInfo* GetLastChangedRegInfo (StackOpData* D, LoadRegInfo* Reg) -/* Get RegInfo of the last load insn entry */ +/* Get RegInfo of the last insn entry that changed the reg */ { CodeEntry* E; - if (Reg->LoadIndex >= 0 && (E = CS_GetEntry (D->Code, Reg->LoadIndex)) != 0) { + if (Reg->ChgIndex >= 0 && (E = CS_GetEntry (D->Code, Reg->ChgIndex)) != 0) { return E->RI; } @@ -204,82 +220,265 @@ RegInfo* GetLastChangedRegInfo (StackOpData* D, LoadRegInfo* Reg) -static int Affected (LoadRegInfo* RI, const CodeEntry* E) -/* Check if the load src may be modified between the pushax and op */ +static int Affected (LoadRegInfo* LRI, const CodeEntry* E) +/* Check if the result of the same loading code as in LRI may be changed by E */ { - fncls_t fncls; - unsigned int Use; - unsigned int Chg; - unsigned int UseToCheck = 0; + fncls_t fncls; + unsigned int Use; + unsigned int Chg; + unsigned int UseToCheck = 0; + StrBuf Src, YSrc, New; + int SrcOff = 0, YSrcOff = 0, NewOff = 0; + const ZPInfo* ZI = 0; - if ((RI->Flags & (LI_CHECK_ARG | LI_CHECK_Y)) != 0) { - if (E->AM == AM65_IMM || E->AM == AM65_ACC || E->AM == AM65_IMP || E->AM == AM65_BRA) { - return 0; + SB_Init (&Src); + SB_Init (&YSrc); + SB_Init (&New); + + if ((LRI->Flags & (LI_CHECK_ARG | LI_CHECK_Y)) != 0) { + if (E->AM == AM65_ACC || E->AM == AM65_BRA || E->AM == AM65_IMM || E->AM == AM65_IMP) { + return (LRI->Flags & LI_CHECK_Y) != 0 && (E->Chg & REG_Y) != 0; } - CHECK ((RI->Flags & LI_CHECK_ARG) == 0 || RI->LoadEntry != 0); - CHECK ((RI->Flags & LI_CHECK_Y) == 0 || RI->LoadYEntry != 0); + CHECK ((LRI->Flags & LI_CHECK_ARG) == 0 || LRI->LoadIndex < 0 || LRI->LoadEntry != 0); + CHECK ((LRI->Flags & LI_CHECK_Y) == 0 || LRI->LoadYIndex < 0 || LRI->LoadYEntry != 0); - if ((RI->Flags & LI_CHECK_ARG) != 0) { - UseToCheck |= RI->LoadEntry->Use; + if ((LRI->Flags & LI_CHECK_ARG) != 0) { + if (LRI->LoadEntry != 0) { + /* We ignore processor flags for loading args. + ** Further more, Reg A can't be used as the index. + */ + UseToCheck |= LRI->LoadEntry->Use & ~REG_A & REG_ALL; + SB_InitFromString (&Src, xstrdup (LRI->LoadEntry->Arg)); + if (!ParseOpcArgStr (LRI->LoadEntry->Arg, &Src, &SrcOff)) { + /* Bail out and play it safe*/ + goto L_Affected; + } + ZI = GetZPInfo (SB_GetConstBuf (&Src)); + if (ZI != 0) { + UseToCheck |= ZI->ByteUse; + } + } else { + /* We don't know what regs could have been used for the src. + ** So we just assume all. + */ + UseToCheck |= ~REG_A & REG_ALL; + } } - if ((RI->Flags & LI_CHECK_Y) != 0) { - UseToCheck |= RI->LoadYEntry->Use; + if ((LRI->Flags & LI_CHECK_Y) != 0) { + if (LRI->LoadYEntry != 0) { + UseToCheck |= LRI->LoadYEntry->Use; + SB_InitFromString (&YSrc, xstrdup (LRI->LoadYEntry->Arg)); + if (!ParseOpcArgStr (LRI->LoadYEntry->Arg, &YSrc, &YSrcOff)) { + /* Bail out and play it safe*/ + goto L_Affected; + } + ZI = GetZPInfo (SB_GetConstBuf (&YSrc)); + if (ZI != 0) { + UseToCheck |= ZI->ByteUse; + } + } else { + /* We don't know what regs could have been used by Y. + ** So we just assume all. + */ + UseToCheck |= ~REG_A & REG_ALL; + } } if (E->OPC == OP65_JSR) { /* Try to know about the function */ - fncls = GetFuncInfo (E->Arg, &Use, &Chg); + fncls = GetFuncInfo (E->Arg, &Use, &Chg); if ((UseToCheck & Chg & REG_ALL) == 0 && fncls == FNCLS_BUILTIN) { /* Builtin functions are known to be harmless */ - return 0; + goto L_NotAffected; } /* Otherwise play it safe */ - return 1; - } else if (E->OPC == OP65_DEC || E->OPC == OP65_INC || - E->OPC == OP65_ASL || E->OPC == OP65_LSR || - E->OPC == OP65_ROL || E->OPC == OP65_ROR || - E->OPC == OP65_TRB || E->OPC == OP65_TSB || - E->OPC == OP65_STA || E->OPC == OP65_STX || E->OPC == OP65_STY) { - if ((E->AM == AM65_ABS || E->AM == AM65_ZP)) { - if ((RI->Flags & LI_CHECK_ARG) != 0 && - strcmp (RI->LoadEntry->Arg, E->Arg) == 0) { - return 1; + goto L_Affected; + + } else { + if (E->OPC == OP65_DEC || E->OPC == OP65_INC || + E->OPC == OP65_ASL || E->OPC == OP65_LSR || + E->OPC == OP65_ROL || E->OPC == OP65_ROR || + E->OPC == OP65_TRB || E->OPC == OP65_TSB || + E->OPC == OP65_STA || E->OPC == OP65_STX || + E->OPC == OP65_STY || E->OPC == OP65_STZ) { + + SB_InitFromString (&New, xstrdup (E->Arg)); + if (!ParseOpcArgStr (E->Arg, &New, &NewOff)) { + /* Bail out and play it safe*/ + goto L_Affected; } - if ((RI->Flags & LI_CHECK_Y) != 0 && - strcmp (RI->LoadYEntry->Arg, E->Arg) == 0) { - return 1; + + /* These opc may operate on memory locations */ + if ((E->AM == AM65_ABS || E->AM == AM65_ZP)) { + /* If we don't know what memory locations could have been used for the src, + ** we just assume all. + */ + if ((LRI->Flags & LI_CHECK_ARG) != 0) { + if (LRI->LoadEntry == 0 || + (LRI->LoadEntry->AM != AM65_ABS && + LRI->LoadEntry->AM != AM65_ZP && + (LRI->LoadEntry->AM != AM65_ZP_INDY || + SB_CompareStr (&Src, "sp") != 0)) || + (SB_Compare (&Src, &New) == 0 && + SrcOff == NewOff)) { + goto L_Affected; + } + } + + /* If we don't know what memory location could have been used by Y, + ** we just assume all. + */ + if ((LRI->Flags & LI_CHECK_Y) != 0) { + if (LRI->LoadYEntry == 0 || + (LRI->LoadYEntry->AM != AM65_ABS && + LRI->LoadYEntry->AM != AM65_ZP) || + (SB_Compare (&YSrc, &New) == 0 && + YSrcOff == NewOff)) { + goto L_Affected; + } + } + + /* Not affected */ + goto L_NotAffected; + + } else if (E->AM == AM65_ZP_INDY && SB_CompareStr (&New, "sp") == 0) { + if ((LRI->Flags & LI_CHECK_ARG) != 0) { + if (LRI->LoadEntry == 0 || + (LRI->LoadEntry->AM != AM65_ABS && + LRI->LoadEntry->AM != AM65_ZP && + (LRI->LoadEntry->AM != AM65_ZP_INDY || + SB_Compare (&Src, &New) == 0) && + SrcOff == NewOff)) { + goto L_Affected; + } + } + + /* Not affected */ + goto L_NotAffected; } - return 0; + /* We could've check further for more cases where the load target isn't modified, + ** But for now let's save the trouble and just play it safe. */ + goto L_Affected; } - /* We could've check further for more cases where the load target isn't modified, - ** But for now let's save the trouble and just play it safe. */ - return 1; } } + +L_NotAffected: + SB_Done (&Src); + SB_Done (&YSrc); + SB_Done (&New); return 0; + +L_Affected: + SB_Done (&Src); + SB_Done (&YSrc); + SB_Done (&New); + return 1; } -static void HonourUseAndChg (LoadRegInfo* RI, unsigned Reg, const CodeEntry* E, int I) +static void HonourUseAndChg (LoadRegInfo* LRI, unsigned Reg, const CodeEntry* E, int I) /* Honour use and change flags for an instruction */ { if ((E->Chg & Reg) != 0) { - /* Remember this as an indirect load */ - ClearLoadRegInfo (RI); - RI->LoadIndex = I; - RI->XferIndex = -1; - RI->Flags = 0; - } else if (Affected (RI, E)) { - RI->Flags |= LI_SRC_CHG; + /* This changes the content of the reg */ + ClearLoadRegInfo (LRI); + LRI->ChgIndex = I; + LRI->Flags = 0; + } else if (Affected (LRI, E)) { + LRI->Flags |= LI_SRC_CHG; } } -unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I) +void PrepairLoadRegInfoForArgCheck (CodeSeg* S, LoadRegInfo* LRI, CodeEntry* E) +/* Set the load src flags and remember to check for load src change if necessary */ +{ + if (E->AM == AM65_IMM) { + /* These insns are all ok and replaceable */ + LRI->Flags |= LI_DIRECT; + } else if (E->AM == AM65_ZP || E->AM == AM65_ABS) { + /* These insns are replaceable only if they are not modified later */ + LRI->Flags |= LI_CHECK_ARG; + } else if (E->AM == AM65_ZPY || E->AM == AM65_ABSY) { + /* 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) { + /* 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 + ** these locations may change between the push and the actual + ** operation. + */ + LRI->Flags |= LI_CHECK_ARG | LI_CHECK_Y; + } + + /* If the load offset has a known value, we can just remember and reload + ** it into the index register later. + */ + if ((LRI->Flags & LI_CHECK_Y) != 0) { + if (RegValIsKnown (E->RI->In.RegY)) { + LRI->Offs = (unsigned char)E->RI->In.RegY; + LRI->Flags &= ~LI_CHECK_Y; + LRI->Flags |= LI_RELOAD_Y; + } + } + + /* Watch for any change of the load target */ + if ((LRI->Flags & LI_CHECK_ARG) != 0) { + LRI->LoadIndex = CS_GetEntryIndex (S, E); + LRI->LoadEntry = E; + } + + /* We need to check if the src of Y is changed */ + if (LRI->LoadYIndex >= 0) { + LRI->LoadYEntry = CS_GetEntry (S, LRI->LoadYIndex); + } else { + LRI->LoadYEntry = 0; + } +} + + + +void SetIfOperandSrcAffected (LoadInfo* LLI, CodeEntry* E) +/* Check and flag operand src that may be affected */ +{ + if (Affected (&LLI->A, E)) { + LLI->A.Flags |= LI_SRC_CHG; + } + if (Affected (&LLI->X, E)) { + LLI->X.Flags |= LI_SRC_CHG; + } + if (Affected (&LLI->Y, E)) { + LLI->Y.Flags |= LI_SRC_CHG; + } +} + + + +void SetIfOperandLoadUnremovable (LoadInfo* LI, unsigned Used) +/* Check and flag operand load that may be unremovable */ +{ + /* Disallow removing the loads if the registers are used */ + if ((Used & REG_A) != 0) { + LI->A.Flags |= LI_DONT_REMOVE; + } + if ((Used & REG_X) != 0) { + LI->X.Flags |= LI_DONT_REMOVE; + } + if ((Used & REG_Y) != 0) { + LI->Y.Flags |= LI_DONT_REMOVE; + } +} + + + +unsigned int TrackLoads (LoadInfo* LI, CodeSeg* S, int I) /* Track loads for a code entry. ** Return used registers. */ @@ -297,33 +496,34 @@ unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I) */ if (E->Info & OF_LOAD) { - LoadRegInfo* RI = 0; + LoadRegInfo* LRI = 0; /* Determine, which register was loaded */ if (E->Chg & REG_A) { - RI = &LI->A; + LRI = &LI->A; } else if (E->Chg & REG_X) { - RI = &LI->X; + LRI = &LI->X; } else if (E->Chg & REG_Y) { - RI = &LI->Y; + LRI = &LI->Y; } - CHECK (RI != 0); + CHECK (LRI != 0); /* Remember the load */ - RI->LoadIndex = I; - RI->XferIndex = -1; + LRI->LoadIndex = I; + LRI->ChgIndex = I; + LRI->LoadYIndex = -1; /* Set load flags */ - RI->Flags = LI_LOAD_INSN; + LRI->Flags = LI_LOAD_INSN; if (E->AM == AM65_IMM) { /* These insns are all ok and replaceable */ - RI->Flags |= LI_DIRECT; + LRI->Flags |= LI_DIRECT; } else if (E->AM == AM65_ZP || E->AM == AM65_ABS) { /* These insns are replaceable only if they are not modified later */ - RI->Flags |= LI_CHECK_ARG; + LRI->Flags |= LI_CHECK_ARG; } else if (E->AM == AM65_ZPY || E->AM == AM65_ABSY) { /* These insns are replaceable only if they are not modified later */ - RI->Flags |= LI_CHECK_ARG | LI_CHECK_Y; + LRI->Flags |= LI_CHECK_ARG | LI_CHECK_Y; } else if (E->AM == AM65_ZP_INDY && strcmp (E->Arg, "sp") == 0) { /* A load from the stack with known offset is also ok, but in this @@ -332,11 +532,11 @@ unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I) ** these locations may change between the push and the actual ** operation. */ - RI->Flags |= LI_DIRECT | LI_CHECK_Y | LI_SP; + LRI->Flags |= LI_CHECK_ARG | LI_CHECK_Y | LI_SP; /* Reg Y can be regarded as unused if this load is removed */ Used &= ~REG_Y; - if (RI == &LI->A) { + if (LRI == &LI->A) { LI->Y.Flags |= LI_USED_BY_A; } else { LI->Y.Flags |= LI_USED_BY_X; @@ -346,21 +546,26 @@ unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I) /* If the load offset has a known value, we can just remember and reload ** it into the index register later. */ - if ((RI->Flags & LI_CHECK_Y) != 0) { + if ((LRI->Flags & LI_CHECK_Y) != 0) { if (RegValIsKnown (E->RI->In.RegY)) { - RI->Offs = (unsigned char)E->RI->In.RegY; - RI->Flags &= ~LI_CHECK_Y; - RI->Flags |= LI_RELOAD_Y; + LRI->Offs = (unsigned char)E->RI->In.RegY; + LRI->Flags &= ~LI_CHECK_Y; + LRI->Flags |= LI_RELOAD_Y; } else { /* We need to check if the src of Y is changed */ - RI->LoadYIndex = LI->Y.LoadIndex; - RI->LoadYEntry = CS_GetEntry (S, RI->LoadYIndex); + LRI->LoadYIndex = LI->Y.LoadIndex; } } /* Watch for any change of the load target */ - if ((RI->Flags & LI_CHECK_ARG) != 0) { - RI->LoadEntry = CS_GetEntry (S, I); + if ((LRI->Flags & LI_CHECK_ARG) != 0) { + LRI->LoadEntry = CS_GetEntry (S, I); + } + + if (LRI->LoadYIndex >= 0) { + LRI->LoadYEntry = CS_GetEntry (S, LRI->LoadYIndex); + } else { + LRI->LoadYEntry = 0; } } else if (E->Info & OF_XFR) { @@ -376,9 +581,9 @@ unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I) Src->Flags |= LI_USED_BY_X; break; case OP65_TAY: - Src = &LI->A; + Src = &LI->A; Tgt = &LI->Y; - Used &= ~REG_A; + Used &= ~REG_A; Src->Flags |= LI_USED_BY_Y; break; case OP65_TXA: @@ -406,7 +611,7 @@ unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I) Tgt->LoadEntry = Src->LoadEntry; Tgt->LoadYIndex = Src->LoadYIndex; Tgt->LoadYEntry = Src->LoadYEntry; - Tgt->XferIndex = I; + Tgt->ChgIndex = I; Tgt->Offs = Src->Offs; Tgt->Flags = Src->Flags; @@ -414,12 +619,12 @@ unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I) /* Both registers set, Y changed */ LI->A.LoadIndex = I; - LI->A.XferIndex = -1; + LI->A.ChgIndex = I; LI->A.Flags = (LI_LOAD_INSN | LI_DIRECT | LI_RELOAD_Y | LI_SP); LI->A.Offs = (unsigned char) E->RI->In.RegY - 1; LI->X.LoadIndex = I; - LI->X.XferIndex = -1; + LI->X.ChgIndex = I; LI->X.Flags = (LI_LOAD_INSN | LI_DIRECT | LI_RELOAD_Y | LI_SP); LI->X.Offs = (unsigned char) E->RI->In.RegY; @@ -431,19 +636,6 @@ unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I) HonourUseAndChg (&LI->A, REG_A, E, I); HonourUseAndChg (&LI->X, REG_X, E, I); HonourUseAndChg (&LI->Y, REG_Y, E, I); - - /* The other operand may be affected too */ - if (LLI != 0) { - if (Affected (&LLI->A, E)) { - LLI->A.Flags |= LI_SRC_CHG; - } - if (Affected (&LLI->X, E)) { - LLI->X.Flags |= LI_SRC_CHG; - } - if (Affected (&LLI->Y, E)) { - LLI->Y.Flags |= LI_SRC_CHG; - } - } } return Used; @@ -451,25 +643,36 @@ unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I) -void SetDontRemoveEntryFlag (LoadRegInfo* RI) +void SetDontRemoveEntryFlag (LoadRegInfo* LRI) /* Flag the entry as non-removable according to register flags */ { - if (RI->Flags & LI_DONT_REMOVE) { - if (RI->LoadEntry != 0) { - RI->LoadEntry->Flags |= CEF_DONT_REMOVE; + if (LRI->Flags & LI_DONT_REMOVE) { + if (LRI->LoadEntry != 0) { + LRI->LoadEntry->Flags |= CEF_DONT_REMOVE; + + /* If the load requires Y, then Y shouldn't be removed either */ + if (LRI->LoadYEntry != 0) { + LRI->LoadYEntry->Flags |= CEF_DONT_REMOVE; + } } } } -void ResetDontRemoveEntryFlag (LoadRegInfo* RI) +void ResetDontRemoveEntryFlag (LoadRegInfo* LRI) /* Unflag the entry as non-removable according to register flags */ { - if (RI->Flags & LI_DONT_REMOVE) { - if (RI->LoadEntry != 0) { - RI->LoadEntry->Flags &= ~CEF_DONT_REMOVE; - } + if (LRI->LoadEntry != 0) { + LRI->LoadEntry->Flags &= ~CEF_DONT_REMOVE; + } + + if (LRI->LoadYEntry != 0) { + LRI->LoadYEntry->Flags &= ~CEF_DONT_REMOVE; + } + + if (LRI->ChgEntry != 0) { + LRI->ChgEntry->Flags &= ~CEF_DONT_REMOVE; } } @@ -480,8 +683,13 @@ void SetDontRemoveEntryFlags (StackOpData* D) { SetDontRemoveEntryFlag (&D->Lhs.A); SetDontRemoveEntryFlag (&D->Lhs.X); + SetDontRemoveEntryFlag (&D->Lhs.Y); SetDontRemoveEntryFlag (&D->Rhs.A); SetDontRemoveEntryFlag (&D->Rhs.X); + SetDontRemoveEntryFlag (&D->Rhs.Y); + SetDontRemoveEntryFlag (&D->Rv.A); + SetDontRemoveEntryFlag (&D->Rv.X); + SetDontRemoveEntryFlag (&D->Rv.Y); } @@ -491,8 +699,13 @@ void ResetDontRemoveEntryFlags (StackOpData* D) { ResetDontRemoveEntryFlag (&D->Lhs.A); ResetDontRemoveEntryFlag (&D->Lhs.X); + ResetDontRemoveEntryFlag (&D->Lhs.Y); ResetDontRemoveEntryFlag (&D->Rhs.A); ResetDontRemoveEntryFlag (&D->Rhs.X); + ResetDontRemoveEntryFlag (&D->Rhs.Y); + ResetDontRemoveEntryFlag (&D->Rv.A); + ResetDontRemoveEntryFlag (&D->Rv.X); + ResetDontRemoveEntryFlag (&D->Rv.Y); } @@ -508,6 +721,7 @@ void ResetStackOpData (StackOpData* Data) ClearLoadInfo (&Data->Lhs); ClearLoadInfo (&Data->Rhs); + ClearLoadInfo (&Data->Rv); Data->PushIndex = -1; Data->OpIndex = -1; @@ -881,28 +1095,50 @@ void AddOpHigh (StackOpData* D, opc_t OPC, LoadInfo* LI, int KeepResult) void RemoveRegLoads (StackOpData* D, LoadInfo* LI) /* Remove register load insns */ { - /* Both registers may be loaded with one insn, but DelEntry will in this - ** case clear the other one. - */ if ((LI->A.Flags & LI_REMOVE) == LI_REMOVE) { if (LI->A.LoadIndex >= 0 && (LI->A.LoadEntry->Flags & CEF_DONT_REMOVE) == 0) { DelEntry (D, LI->A.LoadIndex); + LI->A.LoadEntry = 0; } - if (LI->A.XferIndex >= 0 && - (LI->A.XferEntry->Flags & CEF_DONT_REMOVE) == 0) { - DelEntry (D, LI->A.XferIndex); + if (LI->A.LoadYIndex >= 0 && + (LI->A.LoadYEntry->Flags & CEF_DONT_REMOVE) == 0) { + DelEntry (D, LI->A.LoadYIndex); + } + if (LI->A.ChgIndex >= 0 && + (LI->A.ChgEntry->Flags & CEF_DONT_REMOVE) == 0) { + DelEntry (D, LI->A.ChgIndex); } } + + if (LI->A.LoadEntry != 0 && + (LI->A.Flags & LI_RELOAD_Y) != 0 && + LI->A.LoadYIndex >= 0) { + /* If an entry is using Y and not removed, then its Y load mustn't be removed */ + LI->A.LoadYEntry->Flags |= CEF_DONT_REMOVE; + } + if ((LI->X.Flags & LI_REMOVE) == LI_REMOVE) { if (LI->X.LoadIndex >= 0 && (LI->X.LoadEntry->Flags & CEF_DONT_REMOVE) == 0) { DelEntry (D, LI->X.LoadIndex); + LI->X.LoadEntry = 0; } - if (LI->X.XferIndex >= 0 && - (LI->X.XferEntry->Flags & CEF_DONT_REMOVE) == 0) { - DelEntry (D, LI->X.XferIndex); + if (LI->X.LoadYIndex >= 0 && + (LI->X.LoadYEntry->Flags & CEF_DONT_REMOVE) == 0) { + DelEntry (D, LI->X.LoadYIndex); } + if (LI->X.ChgIndex >= 0 && + (LI->X.ChgEntry->Flags & CEF_DONT_REMOVE) == 0) { + DelEntry (D, LI->X.ChgIndex); + } + } + + if (LI->X.LoadEntry != 0 && + (LI->X.Flags & LI_RELOAD_Y) != 0 && + LI->X.LoadYIndex >= 0) { + /* If an entry is using Y and not removed, then its Y load mustn't be removed */ + LI->X.LoadYEntry->Flags |= CEF_DONT_REMOVE; } } @@ -935,7 +1171,7 @@ int HarmlessCall (const char* Name) ** the pushax/op sequence when encountered. */ { - const char* const Tab[] = { + static const char* const Tab[] = { "aslax1", "aslax2", "aslax3", @@ -967,6 +1203,8 @@ int HarmlessCall (const char* Name) "incax7", "incax8", "incaxy", + "ldaidx", + "ldauidx", "ldaxidx", "ldaxysp", "negax", @@ -991,3 +1229,1821 @@ int HarmlessCall (const char* Name) } + +/*****************************************************************************/ +/* Load tracking code */ +/*****************************************************************************/ + + + +/*****************************************************************************/ +/* Helpers */ +/*****************************************************************************/ + + + +const char* GetZPName (unsigned ZPLoc) +/* Get the name strings of certain known ZP Regs */ +{ + if ((ZPLoc & REG_TMP1) != 0) { + return "tmp1"; + } + if ((ZPLoc & REG_PTR1_LO) != 0) { + return "ptr1"; + } + if ((ZPLoc & REG_PTR1_HI) != 0) { + return "ptr1+1"; + } + if ((ZPLoc & REG_PTR2_LO) != 0) { + return "ptr2"; + } + if ((ZPLoc & REG_PTR2_HI) != 0) { + return "ptr2+1"; + } + if ((ZPLoc & REG_SREG_LO) != 0) { + return "sreg"; + } + if ((ZPLoc & REG_SREG_HI) != 0) { + return "sreg+1"; + } + if ((ZPLoc & REG_SAVE_LO) != 0) { + return "save"; + } + if ((ZPLoc & REG_SAVE_HI) != 0) { + return "save+1"; + } + if ((ZPLoc & REG_SP_LO) != 0) { + return "sp"; + } + if ((ZPLoc & REG_SP_HI) != 0) { + return "sp+1"; + } + + return 0; +} + +unsigned FindAvailableBackupLoc (BackupInfo* B, unsigned Type) +/* Find a ZP loc for storing the backup and fill in the info. +** The allowed types are specified with the Type parameter. +** For convenience, all types are aloowed if none is specified. +** Return the type of the found loc. +*/ +{ + unsigned SizeType = Type & BU_SIZE_MASK; + Type &= BU_TYPE_MASK; + if (Type == 0) { + Type = BU_TYPE_MASK; + } + + if (SizeType == BU_B8 && (Type & BU_REG) != 0 && (B->ZPUsage & REG_Y) == 0) { + /* Use the Y Reg only */ + B->Type = BU_REG | SizeType; + B->Where = REG_Y; + B->ZPUsage |= REG_Y; + return B->Type; + } + + if (SizeType == BU_B8 && (Type & BU_ZP) != 0) { + /* For now we only check for tmp1 and sreg */ + if ((B->ZPUsage & REG_TMP1) == 0) { + B->Type = BU_ZP | BU_B8; + B->Where = REG_TMP1; + B->ZPUsage |= REG_TMP1; + return B->Type; + } + if ((B->ZPUsage & REG_SREG_LO) == 0) { + B->Type = BU_ZP | BU_B8; + B->Where = REG_SREG_LO; + B->ZPUsage |= REG_SREG_LO; + return B->Type; + } + if ((B->ZPUsage & REG_SREG_HI) == 0) { + B->Type = BU_ZP | BU_B8; + B->Where = REG_SREG_HI; + B->ZPUsage |= REG_SREG_HI; + return B->Type; + } + } + + if (SizeType == BU_B16 && (Type & BU_ZP) != 0) { + /* For now we only check for ptr1, sreg and ptr2 */ + if ((B->ZPUsage & REG_PTR1) == 0) { + B->Type = BU_ZP | BU_B16; + B->Where = REG_PTR1; + B->ZPUsage |= REG_PTR1; + return B->Type; + } + if ((B->ZPUsage & REG_SREG) == 0) { + B->Type = BU_ZP | BU_B16; + B->Where = REG_SREG; + B->ZPUsage |= REG_SREG; + return B->Type; + } + if ((B->ZPUsage & REG_PTR2) == 0) { + B->Type = BU_ZP | BU_B16; + B->Where = REG_PTR2; + B->ZPUsage |= REG_PTR2; + return B->Type; + } + } + + if (SizeType == BU_B24 && (Type & BU_ZP) != 0) { + /* For now we only check for certain combinations of + ** tmp1 + (ptr1, sreg or ptr2). + */ + if ((B->ZPUsage & (REG_TMP1 | REG_PTR1)) == 0) { + B->Type = BU_ZP | BU_B24; + B->Where = REG_TMP1 | REG_PTR1; + B->ZPUsage |= REG_TMP1 | REG_PTR1; + return B->Type; + } + if ((B->ZPUsage & (REG_TMP1 | REG_SREG)) == 0) { + B->Type = BU_ZP | BU_B24; + B->Where = REG_TMP1 | REG_SREG; + B->ZPUsage |= REG_TMP1 | REG_SREG; + return B->Type; + } + if ((B->ZPUsage & (REG_TMP1 | REG_PTR2)) == 0) { + B->Type = BU_ZP | BU_B24; + B->Where = REG_TMP1 | REG_PTR2; + B->ZPUsage |= REG_TMP1 | REG_PTR2; + return B->Type; + } + } + + if (SizeType < BU_B32 && (Type & BU_SP6502) != 0) { + /* Even for BU_B24, we just push/pop all 3 of AXY */ + B->Type = BU_SP6502 | BU_B16; + B->Where = 0; + return B->Type; + } + + if (SizeType != BU_B24 && SizeType <= BU_B32 && (Type & BU_SP) != 0) { + /* We may also use pusha/popa, pushax/popax and pusheax/popeax */ + B->Type = BU_SP | SizeType; + B->Where = 0; + return B->Type; + } + + /* No available */ + return BU_UNKNOWN; +} + + + +void AdjustEntryIndices (Collection* Indices, int Index, int Change) +/* Adjust a load register info struct after deleting or inserting successive +** entries with a given index. +*/ +{ + int I; + int* IndexPtr; + + if (Change > 0) { + /* Insertion */ + for (I = 0; I < (int)CollCount (Indices); ++I) { + IndexPtr = CollAtUnchecked (Indices, I); + if (Index <= *IndexPtr) { + *IndexPtr += Change; + } + } + } else if (Change < 0) { + /* Deletion */ + for (I = 0; I < (int)CollCount (Indices); ++I) { + IndexPtr = CollAtUnchecked (Indices, I); + if (Index <= *IndexPtr + Change) { + *IndexPtr += Change; + } else if (Index <= *IndexPtr) { + /* Has been removed */ + *IndexPtr = -1; + //CollDelete (Indices, I); + --I; + } + } + } +} + + + +void DelEntryIdx (CodeSeg* S, int Idx, Collection* Indices) +/* Delete an entry and adjust Indices if necessary */ +{ + CS_DelEntry (S, Idx); + AdjustEntryIndices (Indices, Idx, -1); +} + + + +void DelEntriesIdx (CodeSeg* S, int Idx, int Count, Collection* Indices) +/* Delete entries and adjust Indices if necessary */ +{ + CS_DelEntries (S, Idx, Count); + AdjustEntryIndices (Indices, Idx, -Count); +} + + + +void RemoveFlaggedRegLoads (CodeSeg* S, LoadRegInfo* LRI, Collection* Indices) +/* Remove flagged register load insns */ +{ + if ((LRI->Flags & LI_REMOVE) == LI_REMOVE) { + if (LRI->LoadIndex >= 0 && + (LRI->LoadEntry->Flags & CEF_DONT_REMOVE) == 0) { + DelEntryIdx (S, LRI->LoadIndex, Indices); + LRI->LoadEntry = 0; + } + if (LRI->LoadYIndex >= 0 && + (LRI->LoadYEntry->Flags & CEF_DONT_REMOVE) == 0) { + DelEntryIdx (S, LRI->LoadYIndex, Indices); + } + if (LRI->ChgIndex >= 0 && + (LRI->ChgEntry->Flags & CEF_DONT_REMOVE) == 0) { + DelEntryIdx (S, LRI->ChgIndex, Indices); + } + } + + if (LRI->LoadEntry != 0 && + (LRI->Flags & LI_RELOAD_Y) != 0 && + LRI->LoadYIndex >= 0) { + /* If an entry is using Y and not removed, then its Y load mustn't be removed */ + LRI->LoadYEntry->Flags |= CEF_DONT_REMOVE; + } +} + + +void RemoveFlaggedLoads (CodeSeg* S, LoadInfo* LI, Collection* Indices) +/* Remove flagged load insns */ +{ + RemoveFlaggedRegLoads (S, &LI->A, Indices); + RemoveFlaggedRegLoads (S, &LI->X, Indices); + RemoveFlaggedRegLoads (S, &LI->Y, Indices); +} + + + +static int BackupAAt (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices, int After) +/* Backup the content of A Before or After the specified index Idx depending on the After param */ +{ + CodeEntry* E; + CodeEntry* X; + int OldIdx; + + /* Adjust the insertion point if necessary */ + if (After) { + ++Idx; + } + OldIdx = Idx; + + /* Cannot insert after the last insn */ + CHECK ((unsigned)Idx < CollCount (&S->Entries)); + + /* Get the entry at Idx */ + E = CS_GetEntry (S, Idx); + + if (E->RI != 0 && RegValIsKnown (E->RI->In.RegA)) { + /* Just memorize the value */ + B->Type = BU_IMM | BU_B8; + B->Imm = E->RI->In.RegA; + + } else { + FindAvailableBackupLoc (B, BU_B8); + switch (B->Type & BU_TYPE_MASK) { + case BU_REG: + if ((B->Where & REG_X) != 0) { + X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } else if ((B->Where & REG_Y) != 0) { + X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } + break; + + case BU_ZP: + X = NewCodeEntry (OP65_STA, AM65_ZP, GetZPName (B->Where), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + case BU_SP6502: + X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + case BU_SP: + if ((B->ZPUsage & REG_Y) == 0) { + X = NewCodeEntry (OP65_JSR, AM65_ABS, "pusha", 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } + + /* Unable to do backup */ + return 0; + + default: + /* Unable to do backup */ + return 0; + } + } + + /* Adjust all indices at once */ + AdjustEntryIndices (Indices, OldIdx, Idx - OldIdx); + + /* Move labels if it was an insertion before Idx */ + if (!After) { + CS_MoveLabels (S, E, CS_GetEntry (S, OldIdx)); + } + + /* Done */ + return 1; +} + + + +static int BackupXAt (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices, int After) +/* Backup the content of X before or after the specified index Idx depending on the param After */ +{ + CodeEntry* E; + CodeEntry* X; + int OldIdx; + + /* Adjust the insertion point if necessary */ + if (After) { + ++Idx; + } + OldIdx = Idx; + + /* Cannot insert after the last insn */ + CHECK ((unsigned)Idx < CollCount (&S->Entries)); + + /* Get the entry at Idx */ + E = CS_GetEntry (S, Idx); + + if (E->RI != 0 && RegValIsKnown (E->RI->In.RegX)) { + /* Just memorize the value */ + B->Type = BU_IMM | BU_B8; + B->Imm = E->RI->In.RegX; + + } else { + FindAvailableBackupLoc (B, BU_B8); + switch (B->Type & BU_TYPE_MASK) { + case BU_ZP: + X = NewCodeEntry (OP65_STX, AM65_ZP, GetZPName(B->Where), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + case BU_SP6502: + if ((B->ZPUsage & REG_A) == 0) { + X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } + + /* Unable to do backup */ + return 0; + + case BU_SP: + if ((B->ZPUsage & REG_A) == 0) { + X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_JSR, AM65_ABS, "pusha", 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } + + /* Unable to do backup */ + return 0; + + case BU_REG: + /* Fallthrough */ + default: + + /* Unable to do backup */ + return 0; + } + } + + /* Adjust all indices at once */ + AdjustEntryIndices (Indices, OldIdx, Idx - OldIdx); + + /* Move labels if it was an insertion before Idx */ + if (!After) { + CS_MoveLabels (S, E, CS_GetEntry (S, OldIdx)); + } + + /* Done */ + return 1; +} + + + +static int BackupYAt (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices, int After) +/* Backup the content of Y before or after the specified index Idx depending on the param After */ +{ + CodeEntry* E; + CodeEntry* X; + int OldIdx; + + /* Adjust the insertion point if necessary */ + if (After) { + ++Idx; + } + OldIdx = Idx; + + /* Cannot insert after the last insn */ + CHECK ((unsigned)Idx < CollCount (&S->Entries)); + + /* Get the entry at Idx */ + E = CS_GetEntry (S, Idx); + + if (E->RI != 0 && RegValIsKnown (E->RI->In.RegY)) { + /* Just memorize the value */ + B->Type = BU_IMM | BU_B8; + B->Imm = E->RI->In.RegY; + + } else { + FindAvailableBackupLoc (B, BU_B8); + switch (B->Type & BU_TYPE_MASK) { + case BU_ZP: + X = NewCodeEntry (OP65_STY, AM65_ZP, GetZPName(B->Where), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + case BU_SP6502: + if ((B->ZPUsage & REG_A) == 0) { + X = NewCodeEntry (OP65_TYA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } + + /* Unable to do backup */ + return 0; + + case BU_SP: + if ((B->ZPUsage & REG_A) == 0) { + X = NewCodeEntry (OP65_TYA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_JSR, AM65_ABS, "pusha", 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } + + /* Unable to do backup */ + return 0; + + case BU_REG: + /* Fallthrough */ + default: + + /* Unable to do backup */ + return 0; + } + } + + /* Adjust all indices at once */ + AdjustEntryIndices (Indices, OldIdx, Idx - OldIdx); + + /* Move labels if it was an insertion before Idx */ + if (!After) { + CS_MoveLabels (S, E, CS_GetEntry (S, OldIdx)); + } + + /* Done */ + return 1; +} + + + +static int BackupAXAt (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices, int After) +/* Backup the content of AX Before or After the specified index Idx depending on the After param */ +{ + CodeEntry* E; + CodeEntry* X; + int OldIdx; + StrBuf Arg; + + SB_Init (&Arg); + + /* Adjust the insertion point if necessary */ + if (After) { + ++Idx; + } + OldIdx = Idx; + + /* Cannot insert after the last insn */ + CHECK ((unsigned)Idx < CollCount (&S->Entries)); + + /* Get the entry at Idx */ + E = CS_GetEntry (S, Idx); + + if (E->RI != 0 && RegValIsKnown (E->RI->In.RegA) && RegValIsKnown (E->RI->In.RegX)) { + /* Just memorize the value */ + B->Type = BU_IMM | BU_B16; + B->Imm = E->RI->In.RegA | (E->RI->In.RegX << 8); + + } else { + FindAvailableBackupLoc (B, BU_B16); + switch (B->Type & BU_TYPE_MASK) { + case BU_ZP: + SB_AppendStr (&Arg, GetZPName (B->Where)); + SB_Terminate (&Arg); + X = NewCodeEntry (OP65_STA, AM65_ZP, SB_GetConstBuf (&Arg), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + SB_AppendStr (&Arg, "+1"); + SB_Terminate (&Arg); + X = NewCodeEntry (OP65_STX, AM65_ZP, SB_GetConstBuf (&Arg), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + case BU_SP6502: + if ((B->ZPUsage & REG_A) == 0) { + X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } + + /* Unable to do backup */ + return 0; + + case BU_SP: + if ((B->ZPUsage & REG_Y) == 0) { + X = NewCodeEntry (OP65_JSR, AM65_ABS, "pushax", 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } + + /* Unable to do backup */ + return 0; + + case BU_REG: + /* Fallthrough */ + + default: + /* Unable to do backup */ + return 0; + } + } + + /* Adjust all indices at once */ + AdjustEntryIndices (Indices, OldIdx, Idx - OldIdx); + + /* Move labels if it was an insertion before Idx */ + if (!After) { + CS_MoveLabels (S, E, CS_GetEntry (S, OldIdx)); + } + + SB_Done (&Arg); + + /* Done */ + return 1; +} + + + +static int BackupAXYAt (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices, int After) +/* Backup the content of AXY before or after the specified index Idx depending on the param After. +** This doesn't allow separating the backup of Y from that of AX for now. +*/ +{ + CodeEntry* E; + CodeEntry* X; + int OldIdx; + StrBuf Arg; + + SB_Init (&Arg); + + /* Adjust the insertion point if necessary */ + if (After) { + ++Idx; + } + OldIdx = Idx; + + /* Cannot insert after the last insn */ + CHECK ((unsigned)Idx < CollCount (&S->Entries)); + + /* Get the entry at Idx */ + E = CS_GetEntry (S, Idx); + + if (E->RI != 0 && + RegValIsKnown (E->RI->In.RegA) && + RegValIsKnown (E->RI->In.RegX) && + RegValIsKnown (E->RI->In.RegY)) { + /* Just memorize the value */ + B->Type = BU_IMM | BU_B24; + B->Imm = E->RI->In.RegA | (E->RI->In.RegX << 8) | (E->RI->In.RegY << 16); + + } else { + FindAvailableBackupLoc (B, BU_B24); + switch (B->Type & BU_TYPE_MASK) { + case BU_ZP: + CHECK ((B->Where & REG_TMP1) != 0); + SB_AppendStr (&Arg, GetZPName (B->Where & ~REG_TMP1)); + SB_Terminate (&Arg); + X = NewCodeEntry (OP65_STA, AM65_ZP, SB_GetConstBuf (&Arg), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + SB_AppendStr (&Arg, "+1"); + SB_Terminate (&Arg); + X = NewCodeEntry (OP65_STX, AM65_ZP, SB_GetConstBuf (&Arg), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_STY, AM65_ZP, GetZPName (B->Where & REG_TMP1), 0, E->LI); + CS_InsertEntry(S, X, Idx++); + break; + + case BU_SP6502: + if ((B->ZPUsage & REG_A) == 0) { + X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TYA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } + + /* Unable to do backup */ + return 0; + + case BU_SP: + if ((B->ZPUsage & REG_AY) == 0) { + X = NewCodeEntry (OP65_JSR, AM65_ABS, "pushax", 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TYA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_JSR, AM65_ABS, "pusha", 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } + + /* Unable to do backup */ + return 0; + + case BU_REG: + /* Fallthrough */ + + default: + /* Unable to do backup */ + return 0; + } + } + + /* Adjust all indices at once */ + AdjustEntryIndices (Indices, OldIdx, Idx - OldIdx); + + /* Move labels if it was an insertion before Idx */ + if (!After) { + CS_MoveLabels (S, E, CS_GetEntry (S, OldIdx)); + } + + SB_Done (&Arg); + + /* Done */ + return 1; +} + + + +int BackupABefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices) +/* Backup the content of A Before the specified index Idx */ +{ + return BackupAAt (S, B, Idx, Indices, 0); +} + + + +int BackupXBefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices) +/* Backup the content of X before the specified index Idx */ +{ + return BackupXAt (S, B, Idx, Indices, 0); +} + + + +int BackupYBefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices) +/* Backup the content of Y before the specified index Idx */ +{ + return BackupYAt (S, B, Idx, Indices, 0); +} + + + +int BackupAXBefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices) +/* Backup the content of AX before the specified index Idx */ +{ + return BackupAXAt (S, B, Idx, Indices, 0); +} + + + +int BackupAXYBefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices) +/* Backup the content of AXY before the specified index Idx. +** This doesn't allow separating the backup of Y from that of AX for now. +*/ +{ + return BackupAXYAt (S, B, Idx, Indices, 0); +} + + + +int BackupAAfter (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices) +/* Backup the content of A after the specified index Idx */ +{ + return BackupAAt (S, B, Idx, Indices, 1); +} + + + +int BackupXAfter (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices) +/* Backup the content of X after the specified index Idx */ +{ + return BackupXAt (S, B, Idx, Indices, 1); +} + + + +int BackupYAfter (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices) +/* Backup the content of Y after the specified index Idx */ +{ + return BackupYAt (S, B, Idx, Indices, 1); +} + + + +int BackupAXAfter (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices) +/* Backup the content of AX after the specified index Idx */ +{ + return BackupAXAt (S, B, Idx, Indices, 1); +} + + + +int BackupAXYAfter (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices) +/* Backup the content of AXY after the specified index Idx. +** This doesn't allow separating the backup of Y from that of AX for now. +*/ +{ + return BackupAXYAt (S, B, Idx, Indices, 1); +} + + + +int RestoreABefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices) +/* Restore the content of Y before the specified index Idx */ +{ + CodeEntry* E; + CodeEntry* X; + int OldIdx = Idx; + + /* Get the entry at Idx */ + E = CS_GetEntry (S, Idx); + + switch (B->Type & BU_TYPE_MASK) { + case BU_IMM: + /* Just use the memorized value */ + X = NewCodeEntry (OP65_LDA, AM65_IMM, MakeHexArg (B->Imm & 0xFF), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + case BU_REG: + if ((B->Where & REG_X) != 0) { + X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + } else if ((B->Where & REG_Y) != 0) { + X = NewCodeEntry (OP65_TYA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + } + break; + + case BU_ZP: + X = NewCodeEntry (OP65_LDA, AM65_ZP, GetZPName (B->Where), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + case BU_SP6502: + X = NewCodeEntry (OP65_PLA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + case BU_SP: + if ((B->ZPUsage & REG_Y) == 0) { + X = NewCodeEntry (OP65_JSR, AM65_ABS, "popa", 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } + + /* Unable to restore */ + return 0; + + default: + /* Unable to restore */ + return 0; + } + + /* Adjust all indices at once */ + AdjustEntryIndices (Indices, OldIdx, Idx - OldIdx); + + /* Done */ + return 1; +} + + + +int RestoreXBefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices) +/* Restore the content of X before the specified index Idx */ +{ + CodeEntry* E; + CodeEntry* X; + int OldIdx = Idx; + + /* Get the entry at Idx */ + E = CS_GetEntry (S, Idx); + + switch (B->Type & BU_TYPE_MASK) { + case BU_IMM: + /* Just use the memorized value */ + X = NewCodeEntry (OP65_LDX, AM65_IMM, MakeHexArg (B->Imm & 0xFF), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + case BU_REG: + if ((B->Where & REG_A) != 0) { + X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + } else if ((B->Where & REG_Y) != 0) { + if ((B->ZPUsage & REG_A) == 0) { + X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + } + X = NewCodeEntry (OP65_TYA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + if ((B->ZPUsage & REG_A) == 0) { + X = NewCodeEntry (OP65_PLA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + } + } + break; + + case BU_ZP: + X = NewCodeEntry (OP65_LDX, AM65_ZP, GetZPName (B->Where), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + case BU_SP6502: + if ((B->ZPUsage & REG_A) == 0) { + X = NewCodeEntry (OP65_PLA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } + + /* Unable to restore */ + return 0; + + case BU_SP: + if ((B->ZPUsage & REG_A) == 0) { + X = NewCodeEntry (OP65_JSR, AM65_ABS, "popa", 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } + + /* Unable to restore */ + return 0; + + default: + /* Unable to restore */ + return 0; + } + + /* Adjust all indices at once */ + AdjustEntryIndices (Indices, OldIdx, Idx - OldIdx); + + /* Done */ + return 1; +} + + + +int RestoreYBefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices) +/* Restore the content of Y before the specified index Idx */ +{ + CodeEntry* E; + CodeEntry* X; + int OldIdx = Idx; + + /* Get the entry at Idx */ + E = CS_GetEntry (S, Idx); + + switch (B->Type & BU_TYPE_MASK) { + case BU_IMM: + /* Just use the memorized value */ + X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (B->Imm & 0xFF), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + case BU_REG: + if ((B->Where & REG_A) != 0) { + X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + } else if ((B->Where & REG_X) != 0) { + if ((B->ZPUsage & REG_A) == 0) { + X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + } + X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + if ((B->ZPUsage & REG_A) == 0) { + X = NewCodeEntry (OP65_PLA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + } + } + break; + + case BU_ZP: + X = NewCodeEntry (OP65_LDY, AM65_ZP, GetZPName (B->Where), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + case BU_SP6502: + if ((B->ZPUsage & REG_A) == 0) { + X = NewCodeEntry (OP65_PLA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } + + /* Unable to restore */ + return 0; + + case BU_SP: + if ((B->ZPUsage & REG_A) == 0) { + X = NewCodeEntry (OP65_JSR, AM65_ABS, "popa", 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } + + /* Unable to restore */ + return 0; + + default: + /* Unable to restore */ + return 0; + } + + /* Adjust all indices at once */ + AdjustEntryIndices (Indices, OldIdx, Idx - OldIdx); + + /* Done */ + return 1; +} + + + +int RestoreAXBefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices) +/* Restore the content of AX before the specified index Idx */ +{ + CodeEntry* E; + CodeEntry* X; + StrBuf Arg; + int OldIdx = Idx; + + SB_Init (&Arg); + + /* Get the entry at Idx */ + E = CS_GetEntry (S, Idx); + + switch (B->Type & BU_TYPE_MASK) { + case BU_REG: + /* Just use the memorized value */ + X = NewCodeEntry (OP65_LDA, AM65_IMM, MakeHexArg (B->Imm & 0xFF), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_LDX, AM65_IMM, MakeHexArg ((B->Imm >> 8) & 0xFF), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + case BU_ZP: + SB_AppendStr (&Arg, GetZPName (B->Where)); + SB_Terminate (&Arg); + X = NewCodeEntry (OP65_LDA, AM65_ZP, SB_GetConstBuf (&Arg), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + SB_AppendStr (&Arg, "+1"); + SB_Terminate (&Arg); + X = NewCodeEntry (OP65_LDX, AM65_ZP, SB_GetConstBuf (&Arg), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + case BU_SP6502: + if ((B->ZPUsage & REG_A) == 0) { + X = NewCodeEntry (OP65_PLA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_PLA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } + + /* Unable to restore */ + return 0; + + case BU_SP: + if ((B->ZPUsage & REG_Y) == 0) { + X = NewCodeEntry (OP65_JSR, AM65_ABS, "popax", 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + } + + /* Unable to restore */ + return 0; + + default: + /* Unable to restore */ + return 0; + } + + /* Adjust all indices at once */ + AdjustEntryIndices (Indices, OldIdx, Idx - OldIdx); + + SB_Done (&Arg); + + return 1; +} + + + +int RestoreAXYBefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices) +/* Restore the content of AXY before the specified index Idx. +** This only allows restore from compacted AXY backup for now. +*/ +{ + CodeEntry* E; + CodeEntry* X; + int OldIdx = Idx; + StrBuf Arg; + + SB_Init (&Arg); + + /* Get the entry at Idx */ + E = CS_GetEntry (S, Idx); + + switch (B->Type & BU_TYPE_MASK) { + case BU_IMM: + /* Just use memorized value */ + X = NewCodeEntry (OP65_LDA, AM65_IMM, MakeHexArg (B->Imm & 0xFF), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_LDX, AM65_IMM, MakeHexArg ((B->Imm >> 8) & 0xFF), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg ((B->Imm >> 16) & 0xFF), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + case BU_ZP: + CHECK ((B->Where & REG_TMP1) != 0); + SB_AppendStr (&Arg, GetZPName (B->Where & ~REG_TMP1)); + SB_Terminate (&Arg); + X = NewCodeEntry (OP65_LDA, AM65_ZP, SB_GetConstBuf (&Arg), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + SB_AppendStr (&Arg, "+1"); + SB_Terminate (&Arg); + X = NewCodeEntry (OP65_LDX, AM65_ZP, SB_GetConstBuf (&Arg), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_LDY, AM65_ZP, GetZPName (B->Where & REG_TMP1), 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + case BU_SP6502: + X = NewCodeEntry (OP65_PLA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_PLA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_PLA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + case BU_SP: + X = NewCodeEntry (OP65_JSR, AM65_ABS, "popa", 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_JSR, AM65_ABS, "popax", 0, E->LI); + CS_InsertEntry (S, X, Idx++); + break; + + default: + /* Unable to restorep */ + return 0; + } + + /* Adjust all indices at once */ + AdjustEntryIndices (Indices, OldIdx, Idx - OldIdx); + + SB_Done (&Arg); + + /* Done */ + return 1; +} + + + +int BackupArgAfter (CodeSeg* S, BackupInfo* B, int Idx, const CodeEntry* E, Collection* Indices) +/* Backup the content of the opc arg of the entry E after the specified index Idx. +** Reg A/Y will be used to transfer the content from a memory location to another +** regardless of whether it is in use. +*/ +{ + CodeEntry* X; + int OldIdx = Idx; + unsigned ArgSize; + unsigned Use, Chg; + StrBuf SrcArg; + StrBuf DstArg; + + SB_Init (&SrcArg); + SB_Init (&DstArg); + + /* We only recognize opc with an arg for now, as well as a special case for ldaxysp */ + if ((E->OPC != OP65_JSR || strcmp (E->Arg, "ldaxysp") == 0) && + E->AM != AM65_BRA) { + /* Get size of the arg */ + if ((E->Info & OF_LBRA) != 0 || strcmp (E->Arg, "ldaxysp") == 0) { + ArgSize = BU_B16; + } else { + ArgSize = BU_B8; + } + + if (E->AM == AM65_IMM && CE_HasNumArg (E)) { + /* Just memorize the value */ + B->Type = BU_IMM | ArgSize; + B->Imm = E->Num; + + /* Adjust all indices at once */ + AdjustEntryIndices (Indices, OldIdx + 1, Idx - OldIdx); + + /* Done */ + return 1; + + } + + if (E->Size != 1 && E->AM != AM65_IMP) { + + /* We only recognize opc with an arg for now */ + FindAvailableBackupLoc (B, ArgSize); + switch (B->Type & BU_TYPE_MASK) { + case BU_ZP: + X = NewCodeEntry (OP65_LDA, E->AM, E->Arg, 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + SB_AppendStr (&DstArg, GetZPName (B->Where)); + SB_Terminate (&DstArg); + X = NewCodeEntry (OP65_STA, AM65_ZP, SB_GetConstBuf (&DstArg), 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + if (ArgSize == BU_B16) { + SB_AppendStr (&SrcArg, E->Arg); + SB_AppendStr (&SrcArg, "+1"); + SB_Terminate (&SrcArg); + X = NewCodeEntry (OP65_LDA, E->AM, SB_GetConstBuf (&SrcArg), 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + SB_AppendStr (&DstArg, "+1"); + SB_Terminate (&DstArg); + X = NewCodeEntry (OP65_STA, AM65_ZP, SB_GetConstBuf (&DstArg), 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + } + break; + + case BU_REG: + CHECK (ArgSize == BU_B8 && B->Where == REG_Y); + if (E->AM == AM65_ZP || E->AM == AM65_ABS) { + X = NewCodeEntry (OP65_LDY, E->AM, E->Arg, 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + } else { + X = NewCodeEntry (OP65_LDA, E->AM, E->Arg, 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + } + break; + + case BU_SP6502: + X = NewCodeEntry (OP65_LDA, E->AM, E->Arg, 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + if (ArgSize == BU_B16) { + SB_AppendStr (&SrcArg, E->Arg); + SB_AppendStr (&SrcArg, "+1"); + SB_Terminate (&SrcArg); + X = NewCodeEntry (OP65_LDA, E->AM, SB_GetConstBuf (&SrcArg), 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + } + break; + + case BU_SP: + X = NewCodeEntry (OP65_LDA, E->AM, E->Arg, 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + if (ArgSize != BU_B16) { + X = NewCodeEntry (OP65_JSR, AM65_ABS, "pusha", 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + } else { + SB_AppendStr (&SrcArg, E->Arg); + SB_AppendStr (&SrcArg, "+1"); + SB_Terminate (&SrcArg); + if ((B->ZPUsage & REG_X) == 0) { + if (E->AM == AM65_ZP) { + X = NewCodeEntry (OP65_LDX, E->AM, SB_GetConstBuf (&SrcArg), 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + X = NewCodeEntry (OP65_JSR, AM65_ABS, "pushax", 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + } else { + X = NewCodeEntry (OP65_LDA, E->AM, SB_GetConstBuf (&SrcArg), 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + X = NewCodeEntry (OP65_JSR, AM65_ABS, "pushax", 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + } + } else { + X = NewCodeEntry (OP65_JSR, AM65_ABS, "pusha", 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + X = NewCodeEntry (OP65_LDA, AM65_ZP, SB_GetConstBuf (&DstArg), 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + X = NewCodeEntry (OP65_JSR, AM65_ABS, "pusha", 0, E->LI); + CS_InsertEntry (S, X, ++Idx); + } + } + break; + } + + /* Adjust all indices at once */ + AdjustEntryIndices (Indices, OldIdx + 1, Idx - OldIdx); + + /* Done */ + return 1; + } + } else if (E->OPC == OP65_JSR) { + /* For function calls we load their arguments instead */ + GetFuncInfo (E->Arg, &Use, &Chg); + if ((Use & ~REG_AXY) == 0) { + if (Use == REG_A) { + ArgSize = BU_B8; + return BackupAAfter (S, B, Idx, Indices); + } else if (Use == REG_AX) { + ArgSize = BU_B16; + return BackupAXAfter (S, B, Idx, Indices); + } else if (Use == REG_AXY) { + /* This is actually a 16-bit word plus a 8-bit byte */ + ArgSize = BU_B24; + return BackupAXYAfter (S, B, Idx, Indices); + } + + /* We don't recognize other usage patterns for now */ + } + } + + SB_Done (&SrcArg); + SB_Done (&DstArg); + + /* Unable to do backup */ + return 0; +} + +static int LoadAAt (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices, int After) +/* Reload into A the same arg according to LoadRegInfo before or after Idx +** depending on the After param. +*/ +{ + CodeEntry* E; + CodeEntry* O; /* Old entry at Idx */ + CodeEntry* X; + int Success = 0; + int OldIdx; + unsigned Use, Chg; + + /* Adjust the insertion point if necessary */ + if (After) { + ++Idx; + } + OldIdx = Idx; + + E = LRI->LoadEntry; + CHECK (E != 0); + + O = CS_GetEntry (S, OldIdx); + + /* We only recognize opc with an arg for now, as well as a special case for ldaxysp */ + if ((E->OPC != OP65_JSR || strcmp (E->Arg, "ldaxysp") == 0) && + E->AM != AM65_BRA && E->AM != AM65_IMP) { + if (E->Size != 1 && E->AM != AM65_IMP) { + + /* FIXME: The load flags only reflect the situation by the time it reaches the range end */ + if ((LRI->Flags & (LI_DIRECT | LI_CHECK_ARG | LI_CHECK_Y)) != 0) { + if ((LRI->Flags & LI_RELOAD_Y) != 0) { + if ((LRI->Flags & LI_CHECK_Y) == 0) { + X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (LRI->Offs), 0, E->LI); + } else { + X = NewCodeEntry (OP65_LDY, LRI->LoadYEntry->AM, LRI->LoadYEntry->Arg, 0, E->LI); + } + CS_InsertEntry (S, X, Idx++); + } + X = NewCodeEntry (OP65_LDA, E->AM, E->Arg, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + + Success = 1; + } + } + } else if (E->OPC == OP65_JSR) { + + /* For other function calls we load their arguments instead */ + GetFuncInfo (E->Arg, &Use, &Chg); + if ((Use & ~REG_AXY) == 0) { + if (Use == REG_X) { + X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + } else if (Use == REG_A) { + X = NewCodeEntry (OP65_TYA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + } else if (Use == REG_A) { + /* nothing to do */ + } else { + /* We don't recognize other usage patterns for now */ + return 0; + } + + Success = 1; + } + } + + if (Success) { + /* Adjust all indices at once */ + AdjustEntryIndices (Indices, OldIdx, Idx - OldIdx); + + /* Move labels if it was an insertion before Idx */ + CS_MoveLabels (S, O, CS_GetEntry (S, OldIdx)); + + /* Done */ + return 1; + } + + /* Unable to load */ + return 0; +} + + + +static int LoadXAt (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices, int After) +/* Reload into X the same arg according to LoadRegInfo before or after Idx +** depending on the After param. +*/ +{ + CodeEntry* E; + CodeEntry* O; /* Old entry at Idx */ + CodeEntry* X; + int Success = 0; + int OldIdx; + unsigned Use, Chg; + + /* Adjust the insertion point if necessary */ + if (After) { + ++Idx; + } + OldIdx = Idx; + + E = LRI->LoadEntry; + CHECK (E != 0); + + O = CS_GetEntry (S, OldIdx); + + /* We only recognize opc with an arg for now, as well as a special case for ldaxysp */ + if ((E->OPC != OP65_JSR || strcmp (E->Arg, "ldaxysp") == 0) && + E->AM != AM65_BRA && E->AM != AM65_IMP) { + if (E->Size != 1 && E->AM != AM65_IMP) { + + /* FIXME: The load flags only reflect the situation by the time it reaches the range end */ + if ((LRI->Flags & (LI_DIRECT | LI_CHECK_ARG | LI_CHECK_Y)) != 0) { + if ((LRI->Flags & LI_RELOAD_Y) != 0) { + if ((LRI->Flags & LI_CHECK_Y) == 0) { + X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (LRI->Offs), 0, E->LI); + } else { + X = NewCodeEntry (OP65_LDY, LRI->LoadYEntry->AM, LRI->LoadYEntry->Arg, 0, E->LI); + } + CS_InsertEntry (S, X, Idx++); + + /* ldx does support AM65_ZPY and AM65_ABSY */ + if (E->AM == AM65_ZPY || E->AM == AM65_ABSY) { + X = NewCodeEntry (OP65_LDX, E->AM, E->Arg, 0, E->LI); + } else { + X = NewCodeEntry (OP65_LDA, E->AM, E->Arg, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, E->LI); + } + CS_InsertEntry (S, X, Idx++); + } else { + X = NewCodeEntry (OP65_LDX, E->AM, E->Arg, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + } + + Success = 1; + } + } + } else if (E->OPC == OP65_JSR) { + /* For function calls we load their arguments instead */ + GetFuncInfo (E->Arg, &Use, &Chg); + if ((Use & ~REG_AXY) == 0) { + if (Use == REG_A) { + X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + } else if (Use == REG_Y) { + X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TYA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_PLA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + } else if (Use == REG_X) { + /* nothing to do */ + } else { + /* We don't recognize other usage patterns for now */ + return 0; + } + + Success = 1; + } + } + + if (Success) { + /* Adjust all indices at once */ + AdjustEntryIndices (Indices, OldIdx, Idx - OldIdx); + + /* Move labels if it was an insertion before Idx */ + CS_MoveLabels (S, O, CS_GetEntry (S, OldIdx)); + + /* Done */ + return 1; + } + + /* Unable to load */ + return 0; +} + + + +static int LoadYAt (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices, int After) +/* Reload into Y the same arg according to LoadRegInfo before or after Idx +** depending on the After param. +*/ +{ + CodeEntry* E; + CodeEntry* O; /* Old entry at Idx */ + CodeEntry* X; + int Success = 0; + int OldIdx; + unsigned Use, Chg; + + /* Adjust the insertion point if necessary */ + if (After) { + ++Idx; + } + OldIdx = Idx; + + E = LRI->LoadEntry; + CHECK (E != 0); + + O = CS_GetEntry (S, OldIdx); + + /* We only recognize opc with an arg for now, as well as a special case for ldaxysp */ + if ((E->OPC != OP65_JSR || strcmp (E->Arg, "ldaxysp") == 0) && + E->AM != AM65_BRA && E->AM != AM65_IMP) { + if (E->Size != 1 && E->AM != AM65_IMP) { + + /* FIXME: The load flags only reflect the situation by the time it reaches the range end */ + if ((LRI->Flags & (LI_DIRECT | LI_CHECK_ARG | LI_CHECK_Y)) != 0) { + if ((LRI->Flags & LI_RELOAD_Y) != 0) { + if ((LRI->Flags & LI_CHECK_Y) == 0) { + X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (LRI->Offs), 0, E->LI); + } else { + X = NewCodeEntry (OP65_LDY, LRI->LoadYEntry->AM, LRI->LoadYEntry->Arg, 0, E->LI); + } + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_LDA, E->AM, E->Arg, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + } else { + X = NewCodeEntry (OP65_LDY, E->AM, E->Arg, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + } + + Success = 1; + } + } + } else if (E->OPC == OP65_JSR) { + /* For function calls we load their arguments instead */ + GetFuncInfo (E->Arg, &Use, &Chg); + if ((Use & ~REG_AXY) == 0) { + if (Use == REG_A) { + X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + } else if (Use == REG_X) { + X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + X = NewCodeEntry (OP65_PLA, AM65_IMP, 0, 0, E->LI); + CS_InsertEntry (S, X, Idx++); + } else if (Use == REG_Y) { + /* nothing to do */ + } else { + /* We don't recognize other usage patterns for now */ + return 0; + } + + Success = 1; + } + } + + if (Success) { + /* Adjust all indices at once */ + AdjustEntryIndices (Indices, OldIdx, Idx - OldIdx); + + /* Move labels if it was an insertion before Idx */ + CS_MoveLabels (S, O, CS_GetEntry (S, OldIdx)); + + /* Done */ + return 1; + } + + /* Unable to load */ + return 0; +} + + + +int LoadABefore (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices) +/* Reload into A the same arg according to LoadRegInfo at Idx */ +{ + return LoadAAt (S, Idx, LRI, Indices, 0); +} + + + +int LoadXBefore (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices) +/* Reload into X the same arg according to LoadRegInfo at Idx */ +{ + return LoadXAt (S, Idx, LRI, Indices, 0); +} + + + +int LoadYBefore (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices) +/* Reload into Y the same arg according to LoadRegInfo at Idx */ +{ + return LoadYAt (S, Idx, LRI, Indices, 0); +} + + + +int LoadAAfter (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices) +/* Reload into A the same arg according to LoadRegInfo after Idx */ +{ + return LoadAAt (S, Idx, LRI, Indices, 1); +} + + + +int LoadXAfter (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices) +/* Reload into X the same arg according to LoadRegInfo after Idx */ +{ + return LoadXAt (S, Idx, LRI, Indices, 1); +} + + + +int LoadYAfter (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices) +/* Reload into Y the same arg according to LoadRegInfo after Idx */ +{ + return LoadYAt (S, Idx, LRI, Indices, 1); +} + + + +unsigned GetRegAccessedInOpenRange (CodeSeg* S, int First, int Last) +/* Get what ZPs, registers or processor states are used or changed in the range +** (First, Last). +** The code block must be basic without any jump backwards. +*/ +{ + CodeEntry* X; + unsigned ZPAccessed = 0; + + CHECK (Last <= (int)CollCount (&S->Entries)); + + while (++First < Last) { + X = CS_GetEntry (S, First); + ZPAccessed |= X->Use | X->Chg; + } + + return ZPAccessed; +} + + + +unsigned GetRegUsageInOpenRange (CodeSeg* S, int First, int Last, unsigned* Use, unsigned* Chg) +/* Get what ZPs, registers or processor states are used or changed in the range +** (First, Last) in output parameters Use and Chg. +** Return what ZP regs are used before changed in this range. +** The code block must be basic without any jump backwards. +*/ +{ + CodeEntry* X; + unsigned U = 0; + unsigned C = 0; + + CHECK (Last <= (int)CollCount (&S->Entries)); + + /* Clear the output flags first */ + if (Use != 0) { + *Use = 0; + } + if (Chg != 0) { + *Chg = 0; + } + + while (++First < Last) { + X = CS_GetEntry (S, First); + if (Use != 0) { + *Use |= X->Use; + } + if (Chg != 0) { + *Chg |= X->Chg; + } + /* Used before changed */ + U |= ~C & X->Use; + C |= X->Chg; + } + + return U; +} + + + +int FindArgFirstChangeInOpenRange (CodeSeg* S, int First, int Last, CodeEntry* E) +/* Find the first possible spot where the loaded arg of E might be changed in +** the range (First, Last). The code block in the range must be basic without +** any jump backwards. +** Return the index of the found entry, or Last if not found. +*/ +{ + LoadRegInfo LRI; + CodeEntry* X; + + CHECK (Last <= (int)CollCount (&S->Entries)); + + /* TODO: We'll currently give up finding the src of Y */ + ClearLoadRegInfo (&LRI); + PrepairLoadRegInfoForArgCheck (S, &LRI, E); + + /* TODO: We don't currently check for all cases */ + if ((LRI.Flags & (LI_DIRECT | LI_CHECK_ARG | LI_CHECK_Y)) == 0) { + /* Just bail out as if the src would change right away */ + return First + 1; + } + + /* If there's no need to check */ + if ((LRI.Flags & (LI_CHECK_ARG | LI_CHECK_Y)) == 0) { + return Last; + } + + while (++First < Last) { + X = CS_GetEntry (S, First); + if (Affected (&LRI, X)) { + return First; + } + } + + /* Not found */ + return Last; +} + + + +int FindRegFirstChangeInOpenRange (CodeSeg* S, int First, int Last, unsigned what) +/* Find the first possible spot where the queried ZPs, registers and/or processor +** states might be changed in the range (First, Last). The code block in the +** range must be basic without any jump backwards. +** Return the index of the found entry, or Last if not found. +*/ +{ + CodeEntry* X; + + CHECK (Last <= (int)CollCount (&S->Entries)); + + while (++First < Last) { + X = CS_GetEntry (S, First); + if ((X->Chg & what) != 0) { + return First; + } + } + + /* Not found */ + return Last; +} + + + +int FindRegFirstUseInOpenRange (CodeSeg* S, int First, int Last, unsigned what) +/* Find the first possible spot where the queried ZPs, registers and/or processor +** states might be used in the range (First, Last). The code block in the range +** must be basic without any jump backwards. +** Return the index of the found entry, or Last if not found. +*/ +{ + CodeEntry* X; + + CHECK (Last <= (int)CollCount (&S->Entries)); + + while (++First < Last) { + X = CS_GetEntry (S, First); + if ((X->Use & what) != 0) { + return First; + } + } + + /* Not found */ + return Last; +} + + + +int FindRegLastChangeInOpenRange (CodeSeg* S, int First, int Last, unsigned what) +/* Find the last possible spot where the queried ZPs, registers and/or processor +** states might be changed in the range (First, Last). The code block in the +** range must be basic without any jump backwards. +** Return the index of the found entry, or -1 if not found. +*/ +{ + CodeEntry* X; + int Found = -1; + + CHECK (Last <= (int)CollCount (&S->Entries)); + + while (++First < Last) { + X = CS_GetEntry (S, First); + if ((X->Chg & what) != 0) { + Found = First; + } + } + + return Found; +} + + + +int FindRegLastUseInOpenRange (CodeSeg* S, int First, int Last, unsigned what) +/* Find the last possible spot where the queried ZPs, registers and/or processor +** states might be used in the range (First, Last). The code block in the range +** must be basic without any jump backwards. +** Return the index of the found entry, or -1 if not found. +*/ +{ + CodeEntry* X; + int Found = -1; + + CHECK (Last <= (int)CollCount (&S->Entries)); + + while (++First < Last) { + X = CS_GetEntry (S, First); + if ((X->Use & what) != 0) { + Found = First; + } + } + + return Found; +} diff --git a/src/cc65/codeoptutil.h b/src/cc65/codeoptutil.h index 49a8ce60f..bb5158f1b 100644 --- a/src/cc65/codeoptutil.h +++ b/src/cc65/codeoptutil.h @@ -52,81 +52,81 @@ /* LoadRegInfo flags set by DirectOp */ typedef enum { - LI_NONE = 0x00, - LI_DIRECT = 0x01, /* Direct op may be used */ - LI_RELOAD_Y = 0x02, /* Reload index register Y */ - LI_REMOVE = 0x04, /* Load may be removed */ - LI_DONT_REMOVE = 0x08, /* Load may not be removed */ - LI_CHECK_ARG = 0x10, /* Load src might be modified later */ - LI_SRC_CHG = 0x20, /* Load src is possibly modified */ - LI_LOAD_INSN = 0x40, /* Has a load insn */ - LI_CHECK_Y = 0x80, /* Indexed load src might be modified later */ - LI_USED_BY_A = 0x100, /* Content used by RegA */ - LI_USED_BY_X = 0x200, /* Content used by RegX */ - LI_USED_BY_Y = 0x400, /* Content used by RegY */ - LI_SP = 0x800, /* Content on stack */ + LI_NONE = 0x00, + LI_DIRECT = 0x01, /* Direct op may be used */ + LI_RELOAD_Y = 0x02, /* Reload index register Y */ + LI_REMOVE = 0x04, /* Load may be removed */ + LI_DONT_REMOVE = 0x08, /* Load may not be removed */ + LI_CHECK_ARG = 0x10, /* Load src might be modified later */ + LI_SRC_CHG = 0x20, /* Load src is possibly modified */ + LI_LOAD_INSN = 0x40, /* Has a load insn */ + LI_CHECK_Y = 0x80, /* Indexed load src might be modified later */ + LI_USED_BY_A = 0x100, /* Content used by RegA */ + LI_USED_BY_X = 0x200, /* Content used by RegX */ + LI_USED_BY_Y = 0x400, /* Content used by RegY */ + LI_SP = 0x800, /* Content on stack */ } LI_FLAGS; /* Structure that tells us how to load the lhs values */ typedef struct LoadRegInfo LoadRegInfo; struct LoadRegInfo { - LI_FLAGS Flags; /* Tells us how to load */ - int LoadIndex; /* Index of load insn, -1 if invalid */ - CodeEntry* LoadEntry; /* The actual entry, 0 if invalid */ - int LoadYIndex; /* Index of Y-load insn, -1 if invalid */ - CodeEntry* LoadYEntry; /* The actual Y-load entry, 0 if invalid */ - int XferIndex; /* Index of transfer insn */ - CodeEntry* XferEntry; /* The actual transfer entry */ - int Offs; /* Stack offset if data is on stack */ + LI_FLAGS Flags; /* Tells us how to load */ + int LoadIndex; /* Index of load insn, -1 if invalid */ + CodeEntry* LoadEntry; /* The actual entry, 0 if invalid */ + int LoadYIndex; /* Index of Y-load insn, -1 if invalid */ + CodeEntry* LoadYEntry; /* The actual Y-load entry, 0 if invalid */ + int ChgIndex; /* Index of last change */ + CodeEntry* ChgEntry; /* The actual change entry */ + int Offs; /* Stack offset if data is on stack */ }; /* Now combined for both registers */ typedef struct LoadInfo LoadInfo; struct LoadInfo { - LoadRegInfo A; /* Info for A register */ - LoadRegInfo X; /* Info for X register */ - LoadRegInfo Y; /* Info for Y register */ + LoadRegInfo A; /* Info for A register */ + LoadRegInfo X; /* Info for X register */ + LoadRegInfo Y; /* Info for Y register */ }; /* Structure forward decl */ typedef struct StackOpData StackOpData; -typedef struct OptFuncDesc OptFuncDesc; /* Structure that holds the needed data */ struct StackOpData { - CodeSeg* Code; /* Pointer to code segment */ - unsigned Flags; /* Flags to remember things */ + CodeSeg* Code; /* Pointer to code segment */ + unsigned Flags; /* Flags to remember things */ /* Pointer to optimizer subfunction description */ - const OptFuncDesc* OptFunc; + const void* OptFunc; /* ZP register usage inside the sequence */ - unsigned ZPUsage; - unsigned ZPChanged; + unsigned ZPUsage; + unsigned ZPChanged; /* Freedom of registers inside the sequence */ - unsigned UsedRegs; /* Registers used */ + unsigned UsedRegs; /* Registers used */ /* Whether the rhs is changed multiple times */ - int RhsMultiChg; + int RhsMultiChg; - /* Register load information for lhs and rhs */ - LoadInfo Lhs; - LoadInfo Rhs; + /* Register load information for lhs, rhs and rv */ + LoadInfo Lhs; + LoadInfo Rhs; + LoadInfo Rv; /* Several indices of insns in the code segment */ - int PushIndex; /* Index of call to pushax in codeseg */ - int OpIndex; /* Index of actual operation */ + int PushIndex; /* Index of call to pushax in codeseg */ + int OpIndex; /* Index of actual operation */ /* Pointers to insns in the code segment */ - CodeEntry* PrevEntry; /* Entry before the call to pushax */ - CodeEntry* PushEntry; /* Pointer to entry with call to pushax */ - CodeEntry* OpEntry; /* Pointer to entry with op */ - CodeEntry* NextEntry; /* Entry after the op */ + CodeEntry* PrevEntry; /* Entry before the call to pushax */ + CodeEntry* PushEntry; /* Pointer to entry with call to pushax */ + CodeEntry* OpEntry; /* Pointer to entry with op */ + CodeEntry* NextEntry; /* Entry after the op */ - const char* ZPLo; /* Lo byte of zero page loc to use */ - const char* ZPHi; /* Hi byte of zero page loc to use */ - unsigned IP; /* Insertion point used by some routines */ + const char* ZPLo; /* Lo byte of zero page loc to use */ + const char* ZPHi; /* Hi byte of zero page loc to use */ + unsigned IP; /* Insertion point used by some routines */ }; @@ -166,7 +166,16 @@ void AdjustLoadInfo (LoadInfo* LI, int Index, int Change); RegInfo* GetLastChangedRegInfo (StackOpData* D, LoadRegInfo* Reg); /* Get RegInfo of the last insn entry that changed the reg */ -unsigned int TrackLoads (LoadInfo* LI, LoadInfo* LLI, CodeSeg* S, int I); +void PrepairLoadRegInfoForArgCheck (CodeSeg* S, LoadRegInfo* LRI, CodeEntry* E); +/* Set the load src flags and remember to check for load src change if necessary */ + +void SetIfOperandSrcAffected (LoadInfo* LLI, CodeEntry* E); +/* Check and flag operand src that may be affected */ + +void SetIfOperandLoadUnremovable (LoadInfo* LI, unsigned Used); +/* Check and flag operand load that may be unremovable */ + +unsigned int TrackLoads (LoadInfo* LI, CodeSeg* S, int I); /* Track loads for a code entry. ** Return used registers. */ @@ -252,6 +261,190 @@ int HarmlessCall (const char* Name); ** the pushax/op sequence when encountered. */ + + +/*****************************************************************************/ +/* Helpers */ +/*****************************************************************************/ + + + +/* Backup location types */ +#define BU_UNKNOWN 0x00000000U /* Unknown */ +#define BU_IMM 0x00000000U /* Immediate */ +#define BU_REG 0x01000000U /* In register */ +#define BU_ZP 0x02000000U /* On ZP */ +#define BU_SP6502 0x04000000U /* On 6502 stack */ +#define BU_SP 0x08000000U /* On CC65 stack */ +#define BU_B8 0x00000000U /* Size of 8-bit */ +#define BU_B16 0x10000000U /* Size of 16-bit */ +#define BU_B24 0x20000000U /* Size of 24-bit */ +#define BU_B32 0x30000000U /* Size of 32-bit */ +#define BU_TYPE_MASK 0x0F000000U /* Type mask */ +#define BU_SIZE_MASK 0xF0000000U /* Size mask */ + +typedef struct { + unsigned Type; /* Backup location type and size */ + unsigned ZPUsage; /* ZP unusable for backup */ + union { + unsigned Where; /* Backup location */ + unsigned Imm; /* Backed-up value */ + unsigned char* Bytes; /* Pointer to backed-up value */ + }; +} BackupInfo; + + + +const char* GetZPName (unsigned ZPLoc); +/* Get the name strings of certain known ZP Regs */ + +unsigned FindAvailableBackupLoc (BackupInfo* B, unsigned Type); +/* Find a ZP loc for storing the backup and fill in the info. +** The allowed types are specified with the Type parameter. +** For convenience, all types are aloowed if none is specified. +** Return the type of the found loc. +*/ + +void AdjustEntryIndices (Collection* Indices, int Index, int Change); +/* Adjust a load register info struct after deleting or inserting successive +** entries with a given index. +*/ + +void DelEntryIdx (CodeSeg* S, int Idx, Collection* Indices); +/* Delete an entry and adjust Indices if necessary */ + +void DelEntriesIdx (CodeSeg* S, int Idx, int Count, Collection* Indices); +/* Delete entries and adjust Indices if necessary */ + +void RemoveFlaggedRegLoads (CodeSeg* S, LoadRegInfo* LRI, Collection* Indices); +/* Remove flagged register load insns */ + +void RemoveFlaggedLoads (CodeSeg* S, LoadInfo* LI, Collection* Indices); +/* Remove flagged load insns */ + +int BackupABefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices); +/* Backup the content of A before the specified index Idx */ + +int BackupXBefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices); +/* Backup the content of X before the specified index Idx */ + +int BackupYBefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices); +/* Backup the content of Y before the specified index Idx */ + +int BackupAXBefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices); +/* Backup the content of AX before the specified index Idx */ + +int BackupAXYBefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices); +/* Backup the content of AXY before the specified index Idx. +** This doesn't allow separating the backup of Y from that of AX for now. +*/ + +int BackupAAfter (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices); +/* Backup the content of A after the specified index Idx */ + +int BackupXAfter (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices); +/* Backup the content of X after the specified index Idx */ + +int BackupYAfter (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices); +/* Backup the content of Y after the specified index Idx */ + +int BackupAXAfter (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices); +/* Backup the content of AX after the specified index Idx */ + +int BackupAXYAfter (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices); +/* Backup the content of AXY after the specified index Idx. +** This doesn't allow separating the backup of Y from that of AX for now. +*/ + +int RestoreABefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices); +/* Restore the content of Y before the specified index Idx */ + +int RestoreXBefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices); +/* Restore the content of X before the specified index Idx */ + +int RestoreYBefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices); +/* Restore the content of Y before the specified index Idx */ + +int RestoreAXBefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices); +/* Restore the content of AX before the specified index Idx */ + +int RestoreAXYBefore (CodeSeg* S, BackupInfo* B, int Idx, Collection* Indices); +/* Restore the content of AXY before the specified index Idx. +** This only allows restore from compacted AXY backup for now. +*/ + +int BackupArgAfter (CodeSeg* S, BackupInfo* B, int Idx, const CodeEntry* E, Collection* Indices); +/* Backup the content of the opc arg of the entry E after the specified index Idx. +** Reg A/Y will be used to transfer the content from a memory location to another +** regardless of whether it is in use. +*/ + +int LoadABefore (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices); +/* Reload into A the same arg according to LoadRegInfo at Idx */ + +int LoadXBefore (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices); +/* Reload into X the same arg according to LoadRegInfo at Idx */ + +int LoadYBefore (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices); +/* Reload into Y the same arg according to LoadRegInfo at Idx */ + +int LoadAAfter (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices); +/* Reload into A the same arg according to LoadRegInfo after Idx */ + +int LoadXAfter (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices); +/* Reload into X the same arg according to LoadRegInfo after Idx */ + +int LoadYAfter (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices); +/* Reload into Y the same arg according to LoadRegInfo after Idx */ + +unsigned GetRegAccessedInOpenRange (CodeSeg* S, int First, int Last); +/* Get what ZPs, registers or processor states are used or changed in the range +** (First, Last). +** The code block must be basic without any jump backwards. +*/ + +unsigned GetRegUsageInOpenRange (CodeSeg* S, int First, int Last, unsigned* Use, unsigned* Chg); +/* Get what ZPs, registers or processor states are used or changed in the range +** (First, Last) in output parameters Use and Chg. +** Return what ZP regs are used before changed in this range. +** The code block must be basic without any jump backwards. +*/ + +int FindArgFirstChangeInOpenRange (CodeSeg* S, int First, int Last, CodeEntry* E); +/* Find the first possible spot where the loaded arg of E might be changed in +** the range (First, Last). The code block in the range must be basic without +** any jump backwards. +** Return the index of the found entry, or Last if not found. +*/ + +int FindRegFirstChangeInOpenRange (CodeSeg* S, int First, int Last, unsigned what); +/* Find the first possible spot where the queried ZPs, registers and/or processor +** states might be changed in the range (First, Last). The code block in the +** range must be basic without any jump backwards. +** Return the index of the found entry, or Last if not found. +*/ + +int FindRegFirstUseInOpenRange (CodeSeg* S, int First, int Last, unsigned what); +/* Find the first possible spot where the queried ZPs, registers and/or processor +** states might be used in the range (First, Last). The code block in the range +** must be basic without any jump backwards. +** Return the index of the found entry, or Last if not found. +*/ + +int FindRegLastChangeInOpenRange (CodeSeg* S, int First, int Last, unsigned what); +/* Find the last possible spot where the queried ZPs, registers and/or processor +** states might be changed in the range (First, Last). The code block in the +** range must be basic without any jump backwards. +** Return the index of the found entry, or -1 if not found. +*/ + +int FindRegLastUseInOpenRange (CodeSeg* S, int First, int Last, unsigned what); +/* Find the last possible spot where the queried ZPs, registers and/or processor +** states might be used in the range (First, Last). The code block in the range +** must be basic without any jump backwards. +** Return the index of the found entry, or -1 if not found. +*/ + /* End of codeoptutil.h */ #endif diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 457f9ff1f..41dfb5526 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -100,10 +100,10 @@ static int SameRegAValue (StackOpData* D) RegInfo* LRI = GetLastChangedRegInfo (D, &D->Lhs.A); RegInfo* RRI = GetLastChangedRegInfo (D, &D->Rhs.A); - /* RHS can have a -1 LoadIndex only if it is carried over from LHS */ + /* RHS can have a -1 ChgIndex only if it is carried over from LHS */ if (RRI == 0 || - (D->Rhs.A.LoadIndex >= 0 && - D->Rhs.A.LoadIndex == D->Lhs.A.LoadIndex) || + (D->Rhs.A.ChgIndex >= 0 && + D->Rhs.A.ChgIndex == D->Lhs.A.ChgIndex) || (LRI != 0 && RegValIsKnown (LRI->Out.RegA) && RegValIsKnown (RRI->Out.RegA) && @@ -125,8 +125,8 @@ static int SameRegXValue (StackOpData* D) RegInfo* RRI = GetLastChangedRegInfo (D, &D->Rhs.X); if (RRI == 0 || - (D->Rhs.X.LoadIndex >= 0 && - D->Rhs.X.LoadIndex == D->Lhs.X.LoadIndex) || + (D->Rhs.X.ChgIndex >= 0 && + D->Rhs.X.ChgIndex == D->Lhs.X.ChgIndex) || (LRI != 0 && RegValIsKnown (LRI->Out.RegX) && RegValIsKnown (RRI->Out.RegX) && @@ -1204,7 +1204,7 @@ static unsigned Opt_a_tosicmp (StackOpData* D) if (!SameRegAValue (D)) { /* Because of SameRegAValue */ - CHECK (D->Rhs.A.LoadIndex >= 0); + CHECK (D->Rhs.A.ChgIndex >= 0); /* Store LHS in ZP and reload it before op */ X = NewCodeEntry (OP65_STA, AM65_ZP, D->ZPLo, 0, D->PushEntry->LI); @@ -1217,7 +1217,7 @@ static unsigned Opt_a_tosicmp (StackOpData* D) if ((D->Rhs.A.Flags & LI_DIRECT) == 0) { /* RHS src is not directly comparable */ X = NewCodeEntry (OP65_STA, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI); - InsertEntry (D, X, D->Rhs.A.LoadIndex + 1); + InsertEntry (D, X, D->Rhs.A.ChgIndex + 1); /* Cmp with stored RHS */ X = NewCodeEntry (OP65_CMP, AM65_ZP, D->ZPHi, 0, D->OpEntry->LI); @@ -1431,7 +1431,8 @@ static int PreCondOk (StackOpData* D) int Passed = 0; /* Check the flags */ - unsigned UnusedRegs = D->OptFunc->UnusedRegs; + const OptFuncDesc* Desc = D->OptFunc; + unsigned UnusedRegs = Desc->UnusedRegs; if (UnusedRegs != REG_NONE && (GetRegInfo (D->Code, D->OpIndex+1, UnusedRegs) & UnusedRegs) != 0) { /* Cannot optimize */ @@ -1442,15 +1443,15 @@ static int PreCondOk (StackOpData* D) LoVal = D->OpEntry->RI->In.RegA; HiVal = D->OpEntry->RI->In.RegX; /* Check normally first, then interchange A/X and check again if necessary */ - for (I = (D->OptFunc->Flags & OP_AX_INTERCHANGE ? 0 : 1); !Passed && I < 2; ++I) { + for (I = (Desc->Flags & OP_AX_INTERCHANGE ? 0 : 1); !Passed && I < 2; ++I) { do { - if ((D->OptFunc->Flags & OP_A_KNOWN) != 0 && + if ((Desc->Flags & OP_A_KNOWN) != 0 && RegValIsUnknown (LoVal)) { /* Cannot optimize */ break; } - if ((D->OptFunc->Flags & OP_X_ZERO) != 0 && + if ((Desc->Flags & OP_X_ZERO) != 0 && HiVal != 0) { /* Cannot optimize */ break; @@ -1471,7 +1472,7 @@ static int PreCondOk (StackOpData* D) Lhs = &D->Lhs; Rhs = &D->Rhs; /* Check normally first, then interchange LHS/RHS and check again if necessary */ - for (I = (D->OptFunc->Flags & OP_LR_INTERCHANGE ? 0 : 1); !Passed && I < 2; ++I) { + for (I = (Desc->Flags & OP_LR_INTERCHANGE ? 0 : 1); !Passed && I < 2; ++I) { do { LhsLo = &Lhs->A; @@ -1482,48 +1483,48 @@ static int PreCondOk (StackOpData* D) ** so we don't need to check twice for now. */ - if ((D->OptFunc->Flags & OP_LHS_LOAD) != 0) { + if ((Desc->Flags & OP_LHS_LOAD) != 0) { if ((LhsLo->Flags & LhsHi->Flags & LI_LOAD_INSN) == 0) { /* Cannot optimize */ break; - } else if ((D->OptFunc->Flags & OP_LHS_LOAD_DIRECT) != 0) { + } else if ((Desc->Flags & OP_LHS_LOAD_DIRECT) != 0) { if ((LhsLo->Flags & LhsHi->Flags & LI_DIRECT) == 0) { /* Cannot optimize */ break; } } } - if ((D->OptFunc->Flags & OP_RHS_LOAD) != 0) { + if ((Desc->Flags & OP_RHS_LOAD) != 0) { if ((RhsLo->Flags & RhsHi->Flags & LI_LOAD_INSN) == 0) { /* Cannot optimize */ break; - } else if ((D->OptFunc->Flags & OP_RHS_LOAD_DIRECT) != 0) { + } else if ((Desc->Flags & OP_RHS_LOAD_DIRECT) != 0) { if ((RhsLo->Flags & RhsHi->Flags & LI_DIRECT) == 0) { /* Cannot optimize */ break; } } } - if ((D->OptFunc->Flags & OP_LHS_REMOVE) != 0) { + if ((Desc->Flags & OP_LHS_REMOVE) != 0) { /* Check if the load entries cannot be removed */ if ((LhsLo->LoadEntry != 0 && (LhsLo->LoadEntry->Flags & CEF_DONT_REMOVE) != 0) || (LhsHi->LoadEntry != 0 && (LhsHi->LoadEntry->Flags & CEF_DONT_REMOVE) != 0)) { - if ((D->OptFunc->Flags & OP_LHS_REMOVE_DIRECT) != 0) { + if ((Desc->Flags & OP_LHS_REMOVE_DIRECT) != 0) { /* Cannot optimize */ break; } } } - if ((D->OptFunc->Flags & OP_RHS_REMOVE) != 0) { + if ((Desc->Flags & OP_RHS_REMOVE) != 0) { if ((RhsLo->LoadEntry != 0 && (RhsLo->LoadEntry->Flags & CEF_DONT_REMOVE) != 0) || (RhsHi->LoadEntry != 0 && (RhsHi->LoadEntry->Flags & CEF_DONT_REMOVE) != 0)) { - if ((D->OptFunc->Flags & OP_RHS_REMOVE_DIRECT) != 0) { + if ((Desc->Flags & OP_RHS_REMOVE_DIRECT) != 0) { /* Cannot optimize */ break; } } } - if (D->RhsMultiChg && (D->OptFunc->Flags & OP_RHS_REMOVE_DIRECT) != 0) { + if (D->RhsMultiChg && (Desc->Flags & OP_RHS_REMOVE_DIRECT) != 0) { /* Cannot optimize */ break; } @@ -1578,7 +1579,8 @@ static int RegAPreCondOk (StackOpData* D) int Passed = 0; /* Check the flags */ - unsigned UnusedRegs = D->OptFunc->UnusedRegs; + const OptFuncDesc* Desc = D->OptFunc; + unsigned UnusedRegs = Desc->UnusedRegs; if (UnusedRegs != REG_NONE && (GetRegInfo (D->Code, D->OpIndex+1, UnusedRegs) & UnusedRegs) != 0) { /* Cannot optimize */ @@ -1591,19 +1593,19 @@ static int RegAPreCondOk (StackOpData* D) RhsLoVal = D->OpEntry->RI->In.RegA; RhsHiVal = D->OpEntry->RI->In.RegX; /* Check normally first, then interchange A/X and check again if necessary */ - for (I = (D->OptFunc->Flags & OP_AX_INTERCHANGE ? 0 : 1); !Passed && I < 2; ++I) { + for (I = (Desc->Flags & OP_AX_INTERCHANGE ? 0 : 1); !Passed && I < 2; ++I) { do { if (LhsHiVal != RhsHiVal) { /* Cannot optimize */ break; } - if ((D->OptFunc->Flags & OP_A_KNOWN) != 0 && + if ((Desc->Flags & OP_A_KNOWN) != 0 && RegValIsUnknown (LhsLoVal)) { /* Cannot optimize */ break; } - if ((D->OptFunc->Flags & OP_X_ZERO) != 0 && + if ((Desc->Flags & OP_X_ZERO) != 0 && LhsHiVal != 0) { /* Cannot optimize */ break; @@ -1629,7 +1631,7 @@ static int RegAPreCondOk (StackOpData* D) Lhs = &D->Lhs; Rhs = &D->Rhs; /* Check normally first, then interchange LHS/RHS and check again if necessary */ - for (I = (D->OptFunc->Flags & OP_LR_INTERCHANGE ? 0 : 1); !Passed && I < 2; ++I) { + for (I = (Desc->Flags & OP_LR_INTERCHANGE ? 0 : 1); !Passed && I < 2; ++I) { do { LhsLo = &Lhs->A; @@ -1638,46 +1640,46 @@ static int RegAPreCondOk (StackOpData* D) ** so we don't need to check twice for now. */ - if ((D->OptFunc->Flags & OP_LHS_LOAD) != 0) { + if ((Desc->Flags & OP_LHS_LOAD) != 0) { if ((LhsLo->Flags & LI_LOAD_INSN) == 0) { /* Cannot optimize */ break; - } else if ((D->OptFunc->Flags & OP_LHS_LOAD_DIRECT) != 0) { + } else if ((Desc->Flags & OP_LHS_LOAD_DIRECT) != 0) { if ((LhsLo->Flags & LI_DIRECT) == 0) { /* Cannot optimize */ break; } } } - if ((D->OptFunc->Flags & OP_RHS_LOAD) != 0) { + if ((Desc->Flags & OP_RHS_LOAD) != 0) { if ((RhsLo->Flags & LI_LOAD_INSN) == 0) { /* Cannot optimize */ break; - } else if ((D->OptFunc->Flags & OP_RHS_LOAD_DIRECT) != 0) { + } else if ((Desc->Flags & OP_RHS_LOAD_DIRECT) != 0) { if ((RhsLo->Flags & LI_DIRECT) == 0) { /* Cannot optimize */ break; } } } - if ((D->OptFunc->Flags & OP_LHS_REMOVE) != 0) { + if ((Desc->Flags & OP_LHS_REMOVE) != 0) { /* Check if the load entries cannot be removed */ if ((LhsLo->LoadEntry != 0 && (LhsLo->LoadEntry->Flags & CEF_DONT_REMOVE) != 0)) { - if ((D->OptFunc->Flags & OP_LHS_REMOVE_DIRECT) != 0) { + if ((Desc->Flags & OP_LHS_REMOVE_DIRECT) != 0) { /* Cannot optimize */ break; } } } - if ((D->OptFunc->Flags & OP_RHS_REMOVE) != 0) { + if ((Desc->Flags & OP_RHS_REMOVE) != 0) { if ((RhsLo->LoadEntry != 0 && (RhsLo->LoadEntry->Flags & CEF_DONT_REMOVE) != 0)) { - if ((D->OptFunc->Flags & OP_RHS_REMOVE_DIRECT) != 0) { + if ((Desc->Flags & OP_RHS_REMOVE_DIRECT) != 0) { /* Cannot optimize */ break; } } } - if (D->RhsMultiChg && (D->OptFunc->Flags & OP_RHS_REMOVE_DIRECT) != 0) { + if (D->RhsMultiChg && (Desc->Flags & OP_RHS_REMOVE_DIRECT) != 0) { /* Cannot optimize */ break; } @@ -1731,8 +1733,8 @@ unsigned OptStackOps (CodeSeg* S) int OldEntryCount; /* Old number of entries */ unsigned Used; /* What registers would be used */ unsigned PushedRegs; /* Track if the same regs are used after the push */ - int RhsALoadIndex; /* Track if rhs is changed more than once */ - int RhsXLoadIndex; /* Track if rhs is changed more than once */ + int RhsAChgIndex; /* Track if rhs is changed more than once */ + int RhsXChgIndex; /* Track if rhs is changed more than once */ int IsRegAOptFunc = 0; /* Whether to use the RegA-only optimizations */ enum { @@ -1783,28 +1785,19 @@ unsigned OptStackOps (CodeSeg* S) */ if (CE_HasLabel (E)) { /* Currently we don't track across branches. - ** Remember this as an indirect load. + ** Treat this as a change to all regs. */ ClearLoadInfo (&Data.Lhs); - Data.Lhs.A.LoadIndex = I; - Data.Lhs.X.LoadIndex = I; - Data.Lhs.Y.LoadIndex = I; + Data.Lhs.A.ChgIndex = I; + Data.Lhs.X.ChgIndex = I; + Data.Lhs.Y.ChgIndex = I; } if (CE_IsCallTo (E, "pushax")) { - /* Disallow removing the loads if the registers are used */ - if (Data.UsedRegs & REG_A) { - Data.Lhs.A.Flags |= LI_DONT_REMOVE; - } - if (Data.UsedRegs & REG_X) { - Data.Lhs.X.Flags |= LI_DONT_REMOVE; - } - if (Data.UsedRegs & REG_Y) { - Data.Lhs.Y.Flags |= LI_DONT_REMOVE; - } + /* Disallow removing Lhs loads if the registers are used */ + SetIfOperandLoadUnremovable (&Data.Lhs, Data.UsedRegs); - /* The LHS regs are also used as the default RHS until changed */ - PushedRegs = REG_AXY; - Data.UsedRegs = REG_AXY; + /* The Lhs regs are also used as the default Rhs until changed */ + PushedRegs = REG_AXY; CopyLoadInfo (&Data.Rhs, &Data.Lhs); Data.PushIndex = I; @@ -1812,7 +1805,7 @@ unsigned OptStackOps (CodeSeg* S) State = FoundPush; } else { /* Track load insns */ - Used = TrackLoads (&Data.Lhs, 0, Data.Code, I); + Used = TrackLoads (&Data.Lhs, S, I); Data.UsedRegs &= ~E->Chg; Data.UsedRegs |= Used; } @@ -1825,15 +1818,14 @@ unsigned OptStackOps (CodeSeg* S) */ if (CE_HasLabel (E)) { /* Currently we don't track across branches. - ** Remember this as an indirect load. + ** Treat this as a change to all regs. */ ClearLoadInfo (&Data.Rhs); - Data.Rhs.A.LoadIndex = I; - Data.Rhs.X.LoadIndex = I; - Data.Rhs.Y.LoadIndex = I; + Data.Rhs.A.ChgIndex = I; + Data.Rhs.X.ChgIndex = I; + Data.Rhs.Y.ChgIndex = I; } if (E->OPC == OP65_JSR) { - /* Subroutine call: Check if this is one of the functions, ** we're going to replace. */ @@ -1846,16 +1838,9 @@ unsigned OptStackOps (CodeSeg* S) IsRegAOptFunc = 0; } if (Data.OptFunc) { - /* Disallow removing the loads if the registers are used */ - if (Data.UsedRegs & REG_A) { - Data.Rhs.A.Flags |= LI_DONT_REMOVE; - } - if (Data.UsedRegs & REG_X) { - Data.Rhs.X.Flags |= LI_DONT_REMOVE; - } - if (Data.UsedRegs & REG_Y) { - Data.Rhs.Y.Flags |= LI_DONT_REMOVE; - } + /* Disallow removing Rhs loads if the registers are used */ + SetIfOperandLoadUnremovable (&Data.Rhs, Data.UsedRegs); + /* Remember the op index and go on */ Data.OpIndex = I; Data.OpEntry = E; @@ -1891,11 +1876,15 @@ unsigned OptStackOps (CodeSeg* S) } /* Memorize the old rhs load indices before refreshing them */ - RhsALoadIndex = Data.Rhs.A.LoadIndex; - RhsXLoadIndex = Data.Rhs.X.LoadIndex; + RhsAChgIndex = Data.Rhs.A.ChgIndex; + RhsXChgIndex = Data.Rhs.X.ChgIndex; + + /* Keep tracking Lhs src if necessary */ + SetIfOperandSrcAffected (&Data.Lhs, E); /* Track register usage */ - Used = TrackLoads (&Data.Rhs, &Data.Lhs, Data.Code, I); + Used = TrackLoads (&Data.Rhs, S, I); + Data.ZPUsage |= (E->Use | E->Chg); /* The changes could depend on the use */ Data.UsedRegs &= ~E->Chg; @@ -1905,23 +1894,15 @@ unsigned OptStackOps (CodeSeg* S) /* Check if any parts of Lhs are used again before overwritten */ if (PushedRegs != 0) { if ((PushedRegs & E->Use) != 0) { - if ((PushedRegs & E->Use & REG_A) != 0) { - Data.Lhs.A.Flags |= LI_DONT_REMOVE; - } - if ((PushedRegs & E->Use & REG_X) != 0) { - Data.Lhs.X.Flags |= LI_DONT_REMOVE; - } - if ((PushedRegs & E->Use & REG_Y) != 0) { - Data.Lhs.Y.Flags |= LI_DONT_REMOVE; - } + SetIfOperandLoadUnremovable (&Data.Lhs, PushedRegs & E->Use); } PushedRegs &= ~E->Chg; } /* Check if rhs is changed again after the push */ - if ((RhsALoadIndex != Data.Lhs.A.LoadIndex && - RhsALoadIndex != Data.Rhs.A.LoadIndex) || - (RhsXLoadIndex != Data.Lhs.X.LoadIndex && - RhsXLoadIndex != Data.Rhs.X.LoadIndex)) { + if ((RhsAChgIndex != Data.Lhs.A.ChgIndex && + RhsAChgIndex != Data.Rhs.A.ChgIndex) || + (RhsXChgIndex != Data.Lhs.X.ChgIndex && + RhsXChgIndex != Data.Rhs.X.ChgIndex)) { /* This will disable those sub-opts that require removing ** the rhs as they can't handle such cases correctly. */ @@ -1993,7 +1974,8 @@ unsigned OptStackOps (CodeSeg* S) CS_GenRegInfo (S); /* Call the optimizer function */ - Changes += Data.OptFunc->Func (&Data); + const OptFuncDesc* Desc = Data.OptFunc; + Changes += Desc->Func (&Data); /* Unflag entries that can't be removed */ ResetDontRemoveEntryFlags (&Data); From cc0f8422f23b076b2046f0cc531dbaab9ba1f17f Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 16 Apr 2020 17:17:52 +0800 Subject: [PATCH 1727/2161] More fixes and new utils to check if opcode arguments can be used elsewhere. Fixed tracking with LI_RELOAD_Y and LI_DIRECT. Fixed tracking with LI_CHECK_Y and LI_RELOAD_Y. --- src/cc65/codeoptutil.c | 442 +++++++++++++++++++++++++++-------------- src/cc65/codeoptutil.h | 33 ++- 2 files changed, 321 insertions(+), 154 deletions(-) diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index 46acbaaff..503f33859 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -103,15 +103,15 @@ void FinalizeLoadRegInfo (LoadRegInfo* LRI, CodeSeg* S) } /* Load from src not modified before op can be treated as direct */ - if ((LRI->Flags & LI_SRC_CHG) == 0 && + if ((LRI->Flags & (LI_SRC_CHG | LI_Y_SRC_CHG)) == 0 && (LRI->Flags & (LI_CHECK_ARG | LI_CHECK_Y)) != 0) { LRI->Flags |= LI_DIRECT; if ((LRI->Flags & LI_CHECK_Y) != 0) { LRI->Flags |= LI_RELOAD_Y; } } - /* We cannot ldy ??? or ldy src,y */ - if ((LRI->Flags & LI_CHECK_Y) != 0 && + /* We cannot ldy src,y or reload unknown Y */ + if ((LRI->Flags & (LI_CHECK_Y | LI_RELOAD_Y)) == (LI_CHECK_Y | LI_RELOAD_Y) && (LRI->LoadYEntry == 0 || (LRI->LoadYEntry->Use & REG_Y) == REG_Y)) { LRI->Flags &= ~LI_DIRECT; @@ -221,161 +221,205 @@ RegInfo* GetLastChangedRegInfo (StackOpData* D, LoadRegInfo* Reg) static int Affected (LoadRegInfo* LRI, const CodeEntry* E) -/* Check if the result of the same loading code as in LRI may be changed by E */ +/* Check if the result of the same loading code as in LRI may be changed by E. +** If any part of the arg is used, it could be unsafe to add such a store before E. +** If any part of the arg is changed, it could be unsafe to add such a load after E. +*/ { fncls_t fncls; unsigned int Use; unsigned int Chg; unsigned int UseToCheck = 0; + unsigned int ChgToCheck = 0; StrBuf Src, YSrc, New; int SrcOff = 0, YSrcOff = 0, NewOff = 0; - const ZPInfo* ZI = 0; + const ZPInfo* ZI = 0; + unsigned Res = 0; + CodeEntry* AE = 0; + CodeEntry* YE = 0; + + if ((LRI->Flags & (LI_CHECK_ARG | LI_CHECK_Y | LI_RELOAD_Y)) == 0) { + /* Nothing to check */ + return 0; + } SB_Init (&Src); SB_Init (&YSrc); SB_Init (&New); - if ((LRI->Flags & (LI_CHECK_ARG | LI_CHECK_Y)) != 0) { - if (E->AM == AM65_ACC || E->AM == AM65_BRA || E->AM == AM65_IMM || E->AM == AM65_IMP) { - return (LRI->Flags & LI_CHECK_Y) != 0 && (E->Chg & REG_Y) != 0; - } - CHECK ((LRI->Flags & LI_CHECK_ARG) == 0 || LRI->LoadIndex < 0 || LRI->LoadEntry != 0); - CHECK ((LRI->Flags & LI_CHECK_Y) == 0 || LRI->LoadYIndex < 0 || LRI->LoadYEntry != 0); + if (E->AM == AM65_ACC || E->AM == AM65_BRA || E->AM == AM65_IMM || E->AM == AM65_IMP) { + goto L_Result; + } + CHECK ((LRI->Flags & LI_CHECK_ARG) == 0 || LRI->LoadIndex < 0 || LRI->LoadEntry != 0); + CHECK ((LRI->Flags & (LI_CHECK_Y | LI_RELOAD_Y)) == 0 || LRI->LoadYIndex < 0 || LRI->LoadYEntry != 0); - if ((LRI->Flags & LI_CHECK_ARG) != 0) { - if (LRI->LoadEntry != 0) { - /* We ignore processor flags for loading args. - ** Further more, Reg A can't be used as the index. - */ - UseToCheck |= LRI->LoadEntry->Use & ~REG_A & REG_ALL; - SB_InitFromString (&Src, xstrdup (LRI->LoadEntry->Arg)); - if (!ParseOpcArgStr (LRI->LoadEntry->Arg, &Src, &SrcOff)) { - /* Bail out and play it safe*/ - goto L_Affected; - } - ZI = GetZPInfo (SB_GetConstBuf (&Src)); - if (ZI != 0) { - UseToCheck |= ZI->ByteUse; - } - } else { - /* We don't know what regs could have been used for the src. - ** So we just assume all. - */ - UseToCheck |= ~REG_A & REG_ALL; + if ((LRI->Flags & LI_CHECK_ARG) != 0) { + AE = LRI->LoadEntry; + if (AE != 0) { + /* We ignore processor flags for loading args. + ** Further more, Reg A can't be used as the index. + */ + UseToCheck |= AE->Use & ~REG_A & REG_ALL; + ChgToCheck |= AE->Chg & ~REG_A & REG_ALL; + + SB_InitFromString (&Src, xstrdup (AE->Arg)); + if (!ParseOpcArgStr (AE->Arg, &Src, &SrcOff)) { + /* Bail out and play it safe*/ + Res |= LI_SRC_USE | LI_SRC_CHG; + goto L_Result; } - } - - if ((LRI->Flags & LI_CHECK_Y) != 0) { - if (LRI->LoadYEntry != 0) { - UseToCheck |= LRI->LoadYEntry->Use; - SB_InitFromString (&YSrc, xstrdup (LRI->LoadYEntry->Arg)); - if (!ParseOpcArgStr (LRI->LoadYEntry->Arg, &YSrc, &YSrcOff)) { - /* Bail out and play it safe*/ - goto L_Affected; - } - ZI = GetZPInfo (SB_GetConstBuf (&YSrc)); - if (ZI != 0) { - UseToCheck |= ZI->ByteUse; - } - } else { - /* We don't know what regs could have been used by Y. - ** So we just assume all. - */ - UseToCheck |= ~REG_A & REG_ALL; + /* We have to manually set up the use/chg flags for builtin functions */ + ZI = GetZPInfo (SB_GetConstBuf (&Src)); + if (ZI != 0) { + UseToCheck |= ZI->ByteUse; + ChgToCheck |= ZI->ByteUse; } - } - - if (E->OPC == OP65_JSR) { - /* Try to know about the function */ - fncls = GetFuncInfo (E->Arg, &Use, &Chg); - if ((UseToCheck & Chg & REG_ALL) == 0 && - fncls == FNCLS_BUILTIN) { - /* Builtin functions are known to be harmless */ - goto L_NotAffected; - } - /* Otherwise play it safe */ - goto L_Affected; - } else { - if (E->OPC == OP65_DEC || E->OPC == OP65_INC || - E->OPC == OP65_ASL || E->OPC == OP65_LSR || - E->OPC == OP65_ROL || E->OPC == OP65_ROR || - E->OPC == OP65_TRB || E->OPC == OP65_TSB || - E->OPC == OP65_STA || E->OPC == OP65_STX || - E->OPC == OP65_STY || E->OPC == OP65_STZ) { - - SB_InitFromString (&New, xstrdup (E->Arg)); - if (!ParseOpcArgStr (E->Arg, &New, &NewOff)) { - /* Bail out and play it safe*/ - goto L_Affected; - } - - /* These opc may operate on memory locations */ - if ((E->AM == AM65_ABS || E->AM == AM65_ZP)) { - /* If we don't know what memory locations could have been used for the src, - ** we just assume all. - */ - if ((LRI->Flags & LI_CHECK_ARG) != 0) { - if (LRI->LoadEntry == 0 || - (LRI->LoadEntry->AM != AM65_ABS && - LRI->LoadEntry->AM != AM65_ZP && - (LRI->LoadEntry->AM != AM65_ZP_INDY || - SB_CompareStr (&Src, "sp") != 0)) || - (SB_Compare (&Src, &New) == 0 && - SrcOff == NewOff)) { - goto L_Affected; - } - } - - /* If we don't know what memory location could have been used by Y, - ** we just assume all. - */ - if ((LRI->Flags & LI_CHECK_Y) != 0) { - if (LRI->LoadYEntry == 0 || - (LRI->LoadYEntry->AM != AM65_ABS && - LRI->LoadYEntry->AM != AM65_ZP) || - (SB_Compare (&YSrc, &New) == 0 && - YSrcOff == NewOff)) { - goto L_Affected; - } - } - - /* Not affected */ - goto L_NotAffected; - - } else if (E->AM == AM65_ZP_INDY && SB_CompareStr (&New, "sp") == 0) { - if ((LRI->Flags & LI_CHECK_ARG) != 0) { - if (LRI->LoadEntry == 0 || - (LRI->LoadEntry->AM != AM65_ABS && - LRI->LoadEntry->AM != AM65_ZP && - (LRI->LoadEntry->AM != AM65_ZP_INDY || - SB_Compare (&Src, &New) == 0) && - SrcOff == NewOff)) { - goto L_Affected; - } - } - - /* Not affected */ - goto L_NotAffected; - } - /* We could've check further for more cases where the load target isn't modified, - ** But for now let's save the trouble and just play it safe. */ - goto L_Affected; - } + /* We don't know what regs could have been used for the src. + ** So we just assume all. + */ + UseToCheck |= ~REG_A & REG_ALL; + ChgToCheck |= ~REG_A & REG_ALL; } } -L_NotAffected: - SB_Done (&Src); - SB_Done (&YSrc); - SB_Done (&New); - return 0; + if ((LRI->Flags & LI_CHECK_Y) != 0) { + YE = LRI->LoadYEntry; + if (YE != 0) { + UseToCheck |= YE->Use; + SB_InitFromString (&YSrc, xstrdup (YE->Arg)); + if (!ParseOpcArgStr (YE->Arg, &YSrc, &YSrcOff)) { + /* Bail out and play it safe*/ + Res |= LI_SRC_USE | LI_SRC_CHG; + goto L_Result; + } + /* We have to manually set up the use/chg flags for builtin functions */ + ZI = GetZPInfo (SB_GetConstBuf (&YSrc)); + if (ZI != 0) { + UseToCheck |= ZI->ByteUse; + ChgToCheck |= ZI->ByteUse; + } + } else { + /* We don't know what regs could have been used by Y. + ** So we just assume all. + */ + UseToCheck |= ~REG_A & REG_ALL; + ChgToCheck |= ~REG_A & REG_ALL; + } + } + + if (E->OPC == OP65_JSR) { + /* Try to know about the function */ + fncls = GetFuncInfo (E->Arg, &Use, &Chg); + if (fncls == FNCLS_BUILTIN) { + /* Builtin functions are usually harmless */ + if ((ChgToCheck & Use & REG_ALL) != 0) { + Res |= LI_SRC_USE; + } + if ((UseToCheck & Chg & REG_ALL) != 0) { + Res |= LI_SRC_CHG; + } + goto L_Result; + } + /* Otherwise play it safe */ + Res |= LI_SRC_USE | LI_SRC_CHG; + goto L_Result; + + } else { + if ((E->Info & (OF_READ | OF_WRITE)) != 0) { + + SB_InitFromString (&New, xstrdup (E->Arg)); + if (!ParseOpcArgStr (E->Arg, &New, &NewOff)) { + /* Bail out and play it safe*/ + goto L_Affected; + } + + /* These opc may operate on memory locations. In some cases we can + ** be sure that the src is unaffected as E doesn't overlap with it. + ** However, if we don't know what memory locations could have been + ** used for the src, we just assume all. + */ + if (E->AM == AM65_ABS || + E->AM == AM65_ZP || + (E->AM == AM65_ZP_INDY && SB_CompareStr (&New, "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 || + SB_CompareStr (&Src, "sp") != 0)) || + (SrcOff == NewOff && + SB_Compare (&Src, &New) == 0)) { + + if ((E->Info & OF_READ) != 0) { + /* Used */ + Res |= LI_SRC_USE; + } + if ((E->Info & OF_WRITE) != 0) { + /* Changed */ + Res |= LI_SRC_CHG; + } + } + } + + if ((LRI->Flags & LI_CHECK_Y) != 0) { + /* If we don't know what memory location could have been used by Y, + ** we just assume all. */ + if (YE == 0 || + (YSrcOff == NewOff && SB_Compare (&YSrc, &New) == 0)) { + + if ((E->Info & OF_READ) != 0) { + /* Used */ + Res |= LI_Y_SRC_USE; + } + if ((E->Info & OF_WRITE) != 0) { + /* Changed */ + Res |= LI_Y_SRC_CHG; + } + } + } + + /* Otherwise unaffected */ + goto L_Result; + } + /* We could've check further for more cases where the load target isn't + ** modified, but for now let's save the trouble and just play it safe. + */ + goto L_Affected; + } + } L_Affected: + if ((E->Info & OF_READ) != 0) { + /* Used */ + Res |= LI_SRC_USE; + if ((LRI->Flags & LI_CHECK_Y) != 0) { + Res |= LI_Y_SRC_USE; + } + } + if ((E->Info & OF_WRITE) != 0) { + /* Changed */ + Res |= LI_SRC_CHG; + if ((LRI->Flags & LI_CHECK_Y) != 0) { + Res |= LI_Y_SRC_CHG; + } + } + +L_Result: + if ((LRI->Flags & LI_RELOAD_Y) != 0 && + (E->Use & REG_Y) != 0) { + Res |= LI_Y_USE; + } + if ((LRI->Flags & LI_CHECK_Y) != 0 && + (E->Chg & REG_Y) != 0) { + Res |= LI_Y_CHG; + } SB_Done (&Src); SB_Done (&YSrc); SB_Done (&New); - return 1; + + return Res; } @@ -388,15 +432,17 @@ static void HonourUseAndChg (LoadRegInfo* LRI, unsigned Reg, const CodeEntry* E, ClearLoadRegInfo (LRI); LRI->ChgIndex = I; LRI->Flags = 0; - } else if (Affected (LRI, E)) { - LRI->Flags |= LI_SRC_CHG; + } else { + LRI->Flags |= Affected (LRI, E); } } void PrepairLoadRegInfoForArgCheck (CodeSeg* S, LoadRegInfo* LRI, CodeEntry* E) -/* Set the load src flags and remember to check for load src change if necessary */ +/* Set the load src flags and remember to check for load src change if necessary. +** Note: this doesn't assume reloading Y. +*/ { if (E->AM == AM65_IMM) { /* These insns are all ok and replaceable */ @@ -448,15 +494,9 @@ void PrepairLoadRegInfoForArgCheck (CodeSeg* S, LoadRegInfo* LRI, CodeEntry* E) void SetIfOperandSrcAffected (LoadInfo* LLI, CodeEntry* E) /* Check and flag operand src that may be affected */ { - if (Affected (&LLI->A, E)) { - LLI->A.Flags |= LI_SRC_CHG; - } - if (Affected (&LLI->X, E)) { - LLI->X.Flags |= LI_SRC_CHG; - } - if (Affected (&LLI->Y, E)) { - LLI->Y.Flags |= LI_SRC_CHG; - } + LLI->A.Flags |= Affected (&LLI->A, E); + LLI->X.Flags |= Affected (&LLI->X, E); + LLI->Y.Flags |= Affected (&LLI->Y, E); } @@ -2914,15 +2954,64 @@ unsigned GetRegUsageInOpenRange (CodeSeg* S, int First, int Last, unsigned* Use, +int IsArgSameInOpenRange (CodeSeg* S, int First, int Last, CodeEntry* E) +/* Check if the loading the opc arg gives the same result everywhere between (First, Last). +** The code block in the range must be basic without any jump backwards. +** Note: this always checks Y if any of the LI_CHECK_Y / LI_RELOAD_Y flags is set. +*/ +{ + LoadRegInfo LRI; + CodeEntry* X; + unsigned CheckedFlags = LI_SRC_CHG; + + CHECK (Last <= (int)CollCount (&S->Entries)); + + /* TODO: We'll currently give up finding the src of Y */ + ClearLoadRegInfo (&LRI); + PrepairLoadRegInfoForArgCheck (S, &LRI, E); + + /* TODO: We don't currently check for all cases */ + if ((LRI.Flags & (LI_DIRECT | LI_CHECK_ARG | LI_CHECK_Y | LI_RELOAD_Y)) == 0) { + /* Just bail out as if the src would change right away */ + return 0; + } + + /* If there's no need to check */ + if ((LRI.Flags & (LI_CHECK_ARG | LI_CHECK_Y | LI_RELOAD_Y)) == 0) { + return 1; + } + + /* This always checks Y */ + if ((LRI.Flags & (LI_CHECK_Y | LI_RELOAD_Y)) != 0) { + LRI.Flags |= LI_CHECK_Y; + LRI.Flags &= ~LI_RELOAD_Y; + CheckedFlags |= LI_Y_CHG; + } + + while (++First < Last) { + X = CS_GetEntry (S, First); + if ((Affected (&LRI, X) & CheckedFlags) != 0) { + return 0; + } + } + + /* No change found */ + return 1; +} + + + int FindArgFirstChangeInOpenRange (CodeSeg* S, int First, int Last, CodeEntry* E) /* Find the first possible spot where the loaded arg of E might be changed in ** the range (First, Last). The code block in the range must be basic without ** any jump backwards. ** Return the index of the found entry, or Last if not found. +** Note: changes of Y are always ignored even if the LI_RELOAD_Y flag is not set. */ { LoadRegInfo LRI; CodeEntry* X; + unsigned CheckedFlags = LI_SRC_CHG; CHECK (Last <= (int)CollCount (&S->Entries)); @@ -2943,7 +3032,7 @@ int FindArgFirstChangeInOpenRange (CodeSeg* S, int First, int Last, CodeEntry* E while (++First < Last) { X = CS_GetEntry (S, First); - if (Affected (&LRI, X)) { + if ((Affected (&LRI, X) & CheckedFlags) != 0) { return First; } } @@ -2954,6 +3043,65 @@ int FindArgFirstChangeInOpenRange (CodeSeg* S, int First, int Last, CodeEntry* E +int FindArgLastUsageInOpenRange (CodeSeg* S, int First, int Last, CodeEntry* E, int ReloadY) +/* Find the last index where the arg of E might be used or changed in the range (First, Last). +** ReloadY indicates whether Y is supposed to be reloaded. +** The code block in the range must be basic without any jump backwards. +** Return the index of the found entry, or -1 if not found. +*/ +{ + LoadRegInfo LRI; + CodeEntry* X; + unsigned CheckedFlags = LI_SRC_USE | LI_SRC_CHG; + int Found = -1; + + CHECK (Last <= (int)CollCount (&S->Entries)); + + /* TODO: We'll currently give up finding the src of Y */ + ClearLoadRegInfo (&LRI); + PrepairLoadRegInfoForArgCheck (S, &LRI, E); + + /* Whether Y is to be reloaded */ + if (ReloadY) { + /* Always reload Y */ + if ((LRI.Flags & LI_CHECK_Y) != 0) { + LRI.Flags |= LI_RELOAD_Y; + } + } else if ((LRI.Flags & LI_RELOAD_Y) != 0) { + /* Always check Y */ + LRI.Flags |= LI_CHECK_Y; + LRI.Flags &= ~LI_RELOAD_Y; + } + + /* TODO: We don't currently check for all cases */ + if ((LRI.Flags & (LI_DIRECT | LI_CHECK_ARG | LI_CHECK_Y | LI_RELOAD_Y)) == 0) { + /* Just bail out as if the src would change right away */ + return 0; + } + + if ((LRI.Flags & LI_CHECK_Y) != 0) { + CheckedFlags |= LI_Y_SRC_USE | LI_Y_SRC_CHG; + } + + if ((LRI.Flags & LI_RELOAD_Y) != 0) { + CheckedFlags |= LI_Y_USE; + } else if ((LRI.Flags & LI_CHECK_Y) != 0) { + CheckedFlags |= LI_Y_CHG; + } + + while (++First < Last) { + X = CS_GetEntry (S, First); + if ((Affected (&LRI, X) & CheckedFlags) != 0) { + Found = First; + } + } + + /* Result */ + return Found; +} + + + int FindRegFirstChangeInOpenRange (CodeSeg* S, int First, int Last, unsigned what) /* Find the first possible spot where the queried ZPs, registers and/or processor ** states might be changed in the range (First, Last). The code block in the diff --git a/src/cc65/codeoptutil.h b/src/cc65/codeoptutil.h index bb5158f1b..c3596acd4 100644 --- a/src/cc65/codeoptutil.h +++ b/src/cc65/codeoptutil.h @@ -58,13 +58,18 @@ typedef enum { LI_REMOVE = 0x04, /* Load may be removed */ LI_DONT_REMOVE = 0x08, /* Load may not be removed */ LI_CHECK_ARG = 0x10, /* Load src might be modified later */ - LI_SRC_CHG = 0x20, /* Load src is possibly modified */ - LI_LOAD_INSN = 0x40, /* Has a load insn */ - LI_CHECK_Y = 0x80, /* Indexed load src might be modified later */ - LI_USED_BY_A = 0x100, /* Content used by RegA */ - LI_USED_BY_X = 0x200, /* Content used by RegX */ - LI_USED_BY_Y = 0x400, /* Content used by RegY */ - LI_SP = 0x800, /* Content on stack */ + LI_CHECK_Y = 0x20, /* Indexed load src might be modified later */ + LI_SRC_USE = 0x40, /* src of Opc argument is possibly used */ + LI_SRC_CHG = 0x80, /* src of Opc argument is possibly modified */ + LI_Y_SRC_USE = 0x0100, /* src of Opc addressing Y is possibly used */ + LI_Y_SRC_CHG = 0x0200, /* src of Opc addressing Y is possibly modified */ + LI_Y_USE = 0x0400, /* Opc addressing Y is possibly used */ + LI_Y_CHG = 0x0800, /* Opc addressing Y is possibly modified */ + LI_USED_BY_A = 0x1000, /* Content used by RegA */ + LI_USED_BY_X = 0x2000, /* Content used by RegX */ + LI_USED_BY_Y = 0x4000, /* Content used by RegY */ + LI_SP = 0x8000, /* Content on stack */ + LI_LOAD_INSN = 0x010000, /* Is a load insn */ } LI_FLAGS; /* Structure that tells us how to load the lhs values */ @@ -410,11 +415,25 @@ unsigned GetRegUsageInOpenRange (CodeSeg* S, int First, int Last, unsigned* Use, ** The code block must be basic without any jump backwards. */ +int IsArgSameInOpenRange (CodeSeg* S, int First, int Last, CodeEntry* E); +/* Check if the loading the opc arg gives the same result everywhere between (First, Last). +** The code block in the range must be basic without any jump backwards. +** Note: this always checks Y if any of the LI_CHECK_Y / LI_RELOAD_Y flags is set. +*/ + int FindArgFirstChangeInOpenRange (CodeSeg* S, int First, int Last, CodeEntry* E); /* Find the first possible spot where the loaded arg of E might be changed in ** the range (First, Last). The code block in the range must be basic without ** any jump backwards. ** Return the index of the found entry, or Last if not found. +** Note: changes of Y are always ignored even if the LI_RELOAD_Y flag is not set. +*/ + +int FindArgLastUsageInOpenRange (CodeSeg* S, int First, int Last, CodeEntry* E, int ReloadY); +/* Find the last index where the arg of E might be used or changed in the range (First, Last). +** ReloadY indicates whether Y is supposed to be reloaded. +** The code block in the range must be basic without any jump backwards. +** Return the index of the found entry, or -1 if not found. */ int FindRegFirstChangeInOpenRange (CodeSeg* S, int First, int Last, unsigned what); From 688342e194367cee9864b5772825063c9decd236 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 16 Apr 2020 17:17:53 +0800 Subject: [PATCH 1728/2161] Now every code entry has its argument parsed to tell some info. It fixes the compiling performance regression as well. Built-in ZPs are recognized. --- src/cc65/codeent.c | 330 +++++++++++++++++++++++++++++++---------- src/cc65/codeent.h | 45 +++++- src/cc65/codelab.c | 8 +- src/cc65/codeoptutil.c | 45 +++--- 4 files changed, 319 insertions(+), 109 deletions(-) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index aa3a960df..2ffe4e685 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -33,6 +33,8 @@ +#include <errno.h> +#include <limits.h> #include <stdlib.h> /* common */ @@ -43,11 +45,13 @@ #include "xsprintf.h" /* cc65 */ +#include "asmlabel.h" #include "codeent.h" #include "codeinfo.h" +#include "codelab.h" #include "error.h" #include "global.h" -#include "codelab.h" +#include "ident.h" #include "opcodes.h" #include "output.h" #include "reginfo.h" @@ -95,42 +99,11 @@ static char* GetArgCopy (const char* Arg) -static int NumArg (const char* Arg, unsigned long* Num) -/* If the given argument is numerical, convert it and return true. Otherwise -** set Num to zero and return false. -*/ +static void FreeParsedArg (char* ArgBase) +/* Free a code entry parsed argument */ { - char* End; - unsigned long Val; - - /* Determine the base */ - int Base = 10; - if (*Arg == '$') { - ++Arg; - Base = 16; - } else if (*Arg == '%') { - ++Arg; - Base = 2; - } - - /* Convert the value. strtol is not exactly what we want here, but it's - ** cheap and may be replaced by something fancier later. - */ - Val = strtoul (Arg, &End, Base); - - /* Check if the conversion was successful */ - if (*End != '\0') { - - /* Could not convert */ - *Num = 0; - return 0; - - } else { - - /* Conversion ok */ - *Num = Val; - return 1; - + if (ArgBase != 0 && ArgBase != EmptyArg) { + xfree (ArgBase); } } @@ -356,7 +329,7 @@ static void SetUseChgInfo (CodeEntry* E, const OPCDesc* D) -int ParseOpcArgStr (const char* Arg, struct StrBuf* Name, int* Offset) +int ParseOpcArgStr (const char* Arg, unsigned short* ArgInfo, struct StrBuf* Name, long* Offset) /* Break the opcode argument string into a symbol name/label part plus an offset. ** Both parts are optional, but if there are any characters in the string that ** can't be parsed, it's an failure. @@ -364,10 +337,18 @@ int ParseOpcArgStr (const char* Arg, struct StrBuf* Name, int* Offset) ** Return whether parsing succeeds or not. */ { - int NewOff = 0; - const char* OffsetPart = 0; - const char* NameEnd = 0; - int Negative = 0; + unsigned short Flags = 0; + const char* OffsetPart = 0; + const char* NameEnd = 0; + int Negative = 0; + unsigned long NumVal = 0; + long long AccOffset = 0; + char* End; /* Used for checking errors */ + + if (ArgInfo != 0) { + *ArgInfo = 0; + } + *Offset = 0; /* A numeric address is treated as an unnamed address with the numeric part as the offset */ if (IsDigit (Arg[0]) || Arg[0] == '$') { @@ -381,8 +362,9 @@ int ParseOpcArgStr (const char* Arg, struct StrBuf* Name, int* Offset) ** symbol. */ if (Arg[0] == '_') { - /* Skip the underscore */ - ++Arg; + Flags |= AIF_EXTERNAL; + } else { + Flags |= AIF_BUILTIN; } /* Rip off the offset if present. */ @@ -390,6 +372,7 @@ int ParseOpcArgStr (const char* Arg, struct StrBuf* Name, int* Offset) if (OffsetPart == 0) { OffsetPart = strchr (Arg, '-'); } + if (OffsetPart != 0) { /* Get the real arg name */ NameEnd = strchr (Arg, ' '); @@ -401,21 +384,43 @@ int ParseOpcArgStr (const char* Arg, struct StrBuf* Name, int* Offset) } else { /* No offset */ - *Offset = 0; - SB_CopyStr (Name, Arg); SB_Terminate (Name); + } - return 1; + if ((Flags & AIF_EXTERNAL) == 0) { + if (SB_GetLen (Name) > 0) { + Flags |= AIF_HAS_NAME; + + /* See if the name is a local label */ + if (IsLocalLabelName (SB_GetConstBuf (Name))) { + Flags |= AIF_LOCAL; + } + } + + } else { + if (SB_GetLen (Name) <= 0) { + /* Invalid external name */ + Flags &= ~AIF_EXTERNAL; + *Offset = 0; + if (ArgInfo != 0) { + *ArgInfo = Flags | AIF_FAILURE; + } + return 0; + } + Flags |= AIF_HAS_NAME; } } - *Offset = 0; - /* Get the offset */ while (OffsetPart != 0 && OffsetPart[0] != '\0') { + /* Skip spaces */ + while (OffsetPart[0] == ' ') { + ++OffsetPart; + } + + Negative = 0; if (OffsetPart[0] == '+') { - Negative = 0; ++OffsetPart; } else if (OffsetPart[0] == '-') { Negative = 1; @@ -427,22 +432,50 @@ int ParseOpcArgStr (const char* Arg, struct StrBuf* Name, int* Offset) ++OffsetPart; } + /* Determine the base and convert the value. strtol/strtoul is not + ** exactly what we want here, but it's cheap and may be replaced by + ** something fancier later. + */ if (OffsetPart[0] == '$') { - if (sscanf (OffsetPart + 1, "%X", &NewOff) != 1) { - return 0; - } + /* Base 16 hexedemical */ + NumVal = strtoul (OffsetPart+1, &End, 16); + } else if (OffsetPart[0] != '%') { + /* Base 10 decimal */ + NumVal = strtoul (OffsetPart, &End, 10); } else { - if (sscanf (OffsetPart, "%u", &NewOff) != 1) { - return 0; - } + /* Base 2 binary */ + NumVal = strtoul (OffsetPart+1, &End, 2); } + /* Check if the conversion was successful */ + if (*End != '\0' && *End != ' ' && *End != '+' && *End != '-') { + /* Could not convert */ + *Offset = 0; + if (ArgInfo != 0) { + *ArgInfo = Flags | AIF_FAILURE; + } + return 0; + } + + /* Check for out of range result */ + if (NumVal == ULONG_MAX && errno == ERANGE) { + /* Could not convert */ + *Offset = 0; + if (ArgInfo != 0) { + *ArgInfo = Flags | AIF_FAILURE; + } + return 0; + } + + /* This argument does have an offset */ + Flags |= AIF_HAS_OFFSET; + if (Negative) { - NewOff = -NewOff; + AccOffset -= (long long)NumVal; + } else { + AccOffset += (long long)NumVal; } - *Offset += NewOff; - /* See if there are more */ Arg = OffsetPart; OffsetPart = strchr (Arg, '+'); @@ -451,6 +484,19 @@ int ParseOpcArgStr (const char* Arg, struct StrBuf* Name, int* Offset) } } + if (AccOffset > LONG_MAX || AccOffset < LONG_MIN) { + /* Could not convert */ + *Offset = 0; + if (ArgInfo != 0) { + *ArgInfo = Flags | AIF_FAILURE; + } + return 0; + } + *Offset = (long)AccOffset; + if (ArgInfo != 0) { + *ArgInfo = Flags & ~AIF_FAILURE; + } + return 1; } @@ -471,6 +517,35 @@ const char* MakeHexArg (unsigned Num) +void PreparseArg (CodeEntry* E) +/* Parse the argument string and memorize the result for the code entry */ +{ + StrBuf B; + SB_InitFromString (&B, xmalloc (strlen (E->Arg) + 1)); + + /* Parse the argument string */ + if (ParseOpcArgStr (E->Arg, &E->ArgInfo, &B, &E->ArgOff)) { + E->ArgBase = SB_GetBuf (&B); + + if ((E->ArgInfo & (AIF_HAS_NAME | AIF_HAS_OFFSET)) == AIF_HAS_OFFSET) { + E->Flags |= CEF_NUMARG; + + /* Use the new numerical value */ + E->Num = E->ArgOff; + } + + } else { + /* Parsing fails. Issue an error/warning so that this could be spotted and fixed. */ + E->ArgBase = EmptyArg; + SB_Done (&B); + if (Debug) { + Warning ("Parsing argument \"%s\" failed!", E->Arg); + } + } +} + + + CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg, CodeLabel* JumpTo, LineInfo* LI) /* Create a new code entry, initialize and return it */ @@ -482,15 +557,24 @@ CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg, CodeEntry* E = xmalloc (sizeof (CodeEntry)); /* Initialize the fields */ - E->OPC = D->OPC; - E->AM = AM; - E->Size = GetInsnSize (E->OPC, E->AM); - E->Arg = GetArgCopy (Arg); - E->Flags = NumArg (E->Arg, &E->Num)? CEF_NUMARG : 0; /* Needs E->Arg */ - E->Info = D->Info; - E->JumpTo = JumpTo; - E->LI = UseLineInfo (LI); - E->RI = 0; + E->OPC = D->OPC; + E->AM = AM; + E->Size = GetInsnSize (E->OPC, E->AM); + E->Arg = GetArgCopy (Arg); + E->Flags = 0; + E->Info = D->Info; + E->ArgInfo = 0; + E->JumpTo = JumpTo; + E->LI = UseLineInfo (LI); + E->RI = 0; + + /* Parse the argument string if it's given */ + if (Arg == 0 || Arg[0] == '\0') { + E->ArgBase = EmptyArg; + } else { + PreparseArg (E); + } + SetUseChgInfo (E, D); InitCollection (&E->Labels); @@ -508,6 +592,9 @@ CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg, void FreeCodeEntry (CodeEntry* E) /* Free the given code entry */ { + /* Free the argument base string if we have one */ + FreeParsedArg (E->ArgBase); + /* Free the string argument if we have one */ FreeArg (E->Arg); @@ -572,9 +659,8 @@ void CE_ClearJumpTo (CodeEntry* E) /* Clear the JumpTo entry */ E->JumpTo = 0; - /* Clear the argument and assign the empty one */ - FreeArg (E->Arg); - E->Arg = EmptyArg; + /* Clear the argument */ + CE_SetArg (E, 0); } @@ -593,17 +679,84 @@ void CE_MoveLabel (CodeLabel* L, CodeEntry* E) void CE_SetArg (CodeEntry* E, const char* Arg) -/* Replace the argument by the new one. */ +/* Replace the whole argument by the new one. */ { + /* Free the old parsed argument base */ + FreeParsedArg (E->ArgBase); + /* Free the old argument */ FreeArg (E->Arg); /* Assign the new one */ E->Arg = GetArgCopy (Arg); + /* Parse the new argument string */ + PreparseArg (E); + /* Update the Use and Chg in E */ - const OPCDesc* D = GetOPCDesc (E->OPC); - SetUseChgInfo (E, D); + SetUseChgInfo (E, GetOPCDesc (E->OPC)); +} + + + +void CE_SetArgBaseAndOff (CodeEntry* E, const char* ArgBase, long ArgOff) +/* Replace the new argument base and offset. Argument base is always applied. +** Argument offset is applied if and only if E has the AIF_HAS_OFFSET flag set. +*/ +{ + if (ArgBase != 0 && ArgBase[0] != '\0') { + + /* The argument base is not blank */ + char Buf[IDENTSIZE + 16]; + char* Str = Buf; + size_t Len = strlen (ArgBase) + 16; + if (Len >= sizeof (Buf)) { + Str = xmalloc (Len); + } + + if (CE_HasArgOffset (E)) { + sprintf (Str, "%s%+ld", ArgBase, ArgOff); + } else { + sprintf (Str, "%s", ArgBase); + } + CE_SetArg (E, Str); + + if (Str != Buf) { + xfree (Str); + } + + } else { + /* The argument has no base */ + if ((E->ArgInfo & AIF_HAS_OFFSET) != 0) { + /* This is a numeric argument */ + E->Flags |= CEF_NUMARG; + CE_SetNumArg (E, ArgOff); + } else { + /* Empty argument */ + CE_SetArg (E, EmptyArg); + } + } +} + + + +void CE_SetArgBase (CodeEntry* E, const char* ArgBase) +/* Replace the argument base by the new one. +** The entry must have an existing base. +*/ +{ + /* Check that the entry has a base name */ + CHECK (CE_HasArgBase (E)); + + CE_SetArgBaseAndOff (E, ArgBase, E->ArgOff); +} + + + +void CE_SetArgOffset (CodeEntry* E, long ArgOff) +/* Replace the argument offset by the new one */ +{ + CE_SetArgBaseAndOff (E, E->ArgBase, ArgOff); } @@ -616,24 +769,45 @@ void CE_SetNumArg (CodeEntry* E, long Num) char Buf[16]; /* Check that the entry has a numerical argument */ - CHECK (E->Flags & CEF_NUMARG); + CHECK (CE_HasNumArg (E)); /* Make the new argument string */ if (E->Size == 2) { Num &= 0xFF; xsprintf (Buf, sizeof (Buf), "$%02X", (unsigned) Num); - } else if (E->Size == 3) { + } else if (E->Size == 3 || E->Size == 5) { Num &= 0xFFFF; xsprintf (Buf, sizeof (Buf), "$%04X", (unsigned) Num); } else { Internal ("Invalid instruction size in CE_SetNumArg"); } - /* Replace the argument by the new one */ + /* Replace the whole argument by the new one */ CE_SetArg (E, Buf); +} - /* Use the new numerical value */ - E->Num = Num; + + +int CE_IsArgStrParsed (const CodeEntry* E) +/* Return true if the argument of E was successfully parsed last time */ +{ + return (E->ArgInfo & AIF_FAILURE) == 0; +} + + + +int CE_HasArgBase (const CodeEntry* E) +/* Return true if the argument of E has a non-blank base name */ +{ + return (E->ArgInfo & AIF_HAS_NAME) != 0 && E->ArgBase[0] != '\0'; +} + + + +int CE_HasArgOffset (const CodeEntry* E) +/* Return true if the argument of E has a non-zero offset */ +{ + return (E->ArgInfo & AIF_HAS_OFFSET) != 0 && E->ArgOff != 0; } diff --git a/src/cc65/codeent.h b/src/cc65/codeent.h index 57a7677bb..173118a7f 100644 --- a/src/cc65/codeent.h +++ b/src/cc65/codeent.h @@ -73,14 +73,32 @@ struct CodeEntry { char* Arg; /* Argument as string */ unsigned long Num; /* Numeric argument */ unsigned short Info; /* Additional code info */ + unsigned short ArgInfo; /* Additional argument info */ unsigned int Use; /* Registers used */ unsigned int Chg; /* Registers changed/destroyed */ CodeLabel* JumpTo; /* Jump label */ Collection Labels; /* Labels for this instruction */ LineInfo* LI; /* Source line info for this insn */ RegInfo* RI; /* Register info for this insn */ + char* ArgBase; /* Argument broken into a base and an offset, */ + long ArgOff; /* only done when requested. */ }; +/* */ +#define AIF_HAS_NAME 0x0001U /* Argument has a name part */ +#define AIF_HAS_OFFSET 0x0002U /* Argument has a numeric part */ +#define AIF_BUILTIN 0x0004U /* The name is built-in */ +#define AIF_EXTERNAL 0x0008U /* The name is external */ +#define AIF_LOCAL 0x0010U /* The name is a local label */ +#define AIF_ZP_NAME 0x0020U /* The name is a zp location */ +#define AIF_LOBYTE 0x0100U +#define AIF_HIBYTE 0x0200U +#define AIF_BANKBYTE 0x0400U +#define AIF_FAILURE 0x8000U /* Argument was not parsed successfully */ + +#define AIF_WORD (AIF_LOBYTE | AIF_HIBYTE) +#define AIF_FAR (AIF_LOBYTE | AIF_HIBYTE | AIF_BANKBYTE) + /*****************************************************************************/ @@ -89,7 +107,7 @@ struct CodeEntry { -int ParseOpcArgStr (const char* Arg, struct StrBuf* Name, int* Offset); +int ParseOpcArgStr (const char* Arg, unsigned short* ArgInfo, struct StrBuf* Name, long* Offset); /* Break the opcode argument string into a symbol name/label part plus an offset. ** Both parts are optional, but if there are any characters in the string that ** can't be parsed, it's an failure. @@ -105,6 +123,9 @@ const char* MakeHexArg (unsigned Num); ** safe). */ +void PreparseArg (CodeEntry* E); +/* Parse the argument string and memorize the result for the code entry */ + CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg, CodeLabel* JumpTo, LineInfo* LI); /* Create a new code entry, initialize and return it */ @@ -205,11 +226,33 @@ INLINE int CE_HasNumArg (const CodeEntry* E) void CE_SetArg (CodeEntry* E, const char* Arg); /* Replace the argument by the new one. */ +void CE_SetArgBaseAndOff (CodeEntry* E, const char* ArgBase, long ArgOff); +/* Replace the new argument base and offset. Argument base is always applied. +** Argument offset is applied if and only if E has the AIF_HAS_OFFSET flag set. +*/ + +void CE_SetArgBase (CodeEntry* E, const char* ArgBase); +/* Replace the argument base by the new one. +** The entry must have an existing base. +*/ + +void CE_SetArgOffset (CodeEntry* E, long ArgOff); +/* Replace the argument offset by the new one */ + void CE_SetNumArg (CodeEntry* E, long Num); /* Set a new numeric argument for the given code entry that must already ** have a numeric argument. */ +int CE_IsArgStrParsed (const CodeEntry* E); +/* Return true if the argument of E was successfully parsed last time */ + +int CE_HasArgBase (const CodeEntry* E); +/* Return true if the argument of E has a non-blank base name */ + +int CE_HasArgOffset (const CodeEntry* E); +/* Return true if the argument of E has a non-zero offset */ + int CE_IsConstImm (const CodeEntry* E); /* Return true if the argument of E is a constant immediate value */ diff --git a/src/cc65/codelab.c b/src/cc65/codelab.c index ff26645dc..0909702fd 100644 --- a/src/cc65/codelab.c +++ b/src/cc65/codelab.c @@ -90,8 +90,12 @@ void CL_AddRef (CodeLabel* L, struct CodeEntry* E) /* The insn at E jumps to this label */ E->JumpTo = L; - /* Replace the code entry argument with the name of the new label */ - CE_SetArg (E, L->Name); + if (CE_HasArgBase (E)) { + /* Replace the code entry argument base with the name of the new label */ + CE_SetArgBase (E, L->Name); + } else { + CE_SetArgBaseAndOff (E, L->Name, 0); + } /* Remember that in the label */ CollAppend (&L->JumpFrom, E); diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index 503f33859..3df762eeb 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -231,8 +231,6 @@ static int Affected (LoadRegInfo* LRI, const CodeEntry* E) unsigned int Chg; unsigned int UseToCheck = 0; unsigned int ChgToCheck = 0; - StrBuf Src, YSrc, New; - int SrcOff = 0, YSrcOff = 0, NewOff = 0; const ZPInfo* ZI = 0; unsigned Res = 0; CodeEntry* AE = 0; @@ -243,10 +241,6 @@ static int Affected (LoadRegInfo* LRI, const CodeEntry* E) return 0; } - SB_Init (&Src); - SB_Init (&YSrc); - SB_Init (&New); - if (E->AM == AM65_ACC || E->AM == AM65_BRA || E->AM == AM65_IMM || E->AM == AM65_IMP) { goto L_Result; } @@ -262,14 +256,13 @@ static int Affected (LoadRegInfo* LRI, const CodeEntry* E) UseToCheck |= AE->Use & ~REG_A & REG_ALL; ChgToCheck |= AE->Chg & ~REG_A & REG_ALL; - SB_InitFromString (&Src, xstrdup (AE->Arg)); - if (!ParseOpcArgStr (AE->Arg, &Src, &SrcOff)) { + /* Check if the argument has been parsed successfully */ + if (!CE_IsArgStrParsed (AE)) { /* Bail out and play it safe*/ - Res |= LI_SRC_USE | LI_SRC_CHG; - goto L_Result; + goto L_Affected; } /* We have to manually set up the use/chg flags for builtin functions */ - ZI = GetZPInfo (SB_GetConstBuf (&Src)); + ZI = GetZPInfo (AE->ArgBase); if (ZI != 0) { UseToCheck |= ZI->ByteUse; ChgToCheck |= ZI->ByteUse; @@ -287,14 +280,14 @@ static int Affected (LoadRegInfo* LRI, const CodeEntry* E) YE = LRI->LoadYEntry; if (YE != 0) { UseToCheck |= YE->Use; - SB_InitFromString (&YSrc, xstrdup (YE->Arg)); - if (!ParseOpcArgStr (YE->Arg, &YSrc, &YSrcOff)) { + + /* Check if the argument has been parsed successfully */ + if (!CE_IsArgStrParsed (YE)) { /* Bail out and play it safe*/ - Res |= LI_SRC_USE | LI_SRC_CHG; - goto L_Result; + goto L_Affected; } /* We have to manually set up the use/chg flags for builtin functions */ - ZI = GetZPInfo (SB_GetConstBuf (&YSrc)); + ZI = GetZPInfo (YE->ArgBase); if (ZI != 0) { UseToCheck |= ZI->ByteUse; ChgToCheck |= ZI->ByteUse; @@ -322,14 +315,13 @@ static int Affected (LoadRegInfo* LRI, const CodeEntry* E) goto L_Result; } /* Otherwise play it safe */ - Res |= LI_SRC_USE | LI_SRC_CHG; - goto L_Result; + goto L_Affected; } else { if ((E->Info & (OF_READ | OF_WRITE)) != 0) { - SB_InitFromString (&New, xstrdup (E->Arg)); - if (!ParseOpcArgStr (E->Arg, &New, &NewOff)) { + /* Check if the argument has been parsed successfully */ + if (!CE_IsArgStrParsed (E)) { /* Bail out and play it safe*/ goto L_Affected; } @@ -341,16 +333,16 @@ static int Affected (LoadRegInfo* LRI, const CodeEntry* E) */ if (E->AM == AM65_ABS || E->AM == AM65_ZP || - (E->AM == AM65_ZP_INDY && SB_CompareStr (&New, "sp") == 0) + (E->AM == AM65_ZP_INDY && strcmp (E->ArgBase, "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 || - SB_CompareStr (&Src, "sp") != 0)) || - (SrcOff == NewOff && - SB_Compare (&Src, &New) == 0)) { + strcmp (AE->ArgBase, "sp") != 0)) || + (AE->ArgOff == E->ArgOff && + strcmp (AE->ArgBase, E->ArgBase) == 0)) { if ((E->Info & OF_READ) != 0) { /* Used */ @@ -367,7 +359,7 @@ static int Affected (LoadRegInfo* LRI, const CodeEntry* E) /* If we don't know what memory location could have been used by Y, ** we just assume all. */ if (YE == 0 || - (YSrcOff == NewOff && SB_Compare (&YSrc, &New) == 0)) { + (YE->ArgOff == E->ArgOff && strcmp (YE->ArgBase, E->ArgBase) == 0)) { if ((E->Info & OF_READ) != 0) { /* Used */ @@ -415,9 +407,6 @@ L_Result: (E->Chg & REG_Y) != 0) { Res |= LI_Y_CHG; } - SB_Done (&Src); - SB_Done (&YSrc); - SB_Done (&New); return Res; } From b525554bfee3c3ddc5ddd7e58b4a20728f6c9cb1 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 16 Apr 2020 17:19:17 +0800 Subject: [PATCH 1729/2161] Added support for parsing asm byte size expressions with a pair of parentheses. --- src/cc65/codeent.c | 99 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 93 insertions(+), 6 deletions(-) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index 2ffe4e685..f3a910652 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -341,6 +341,7 @@ int ParseOpcArgStr (const char* Arg, unsigned short* ArgInfo, struct StrBuf* Nam const char* OffsetPart = 0; const char* NameEnd = 0; int Negative = 0; + int Parentheses = 0; unsigned long NumVal = 0; long long AccOffset = 0; char* End; /* Used for checking errors */ @@ -357,6 +358,49 @@ int ParseOpcArgStr (const char* Arg, unsigned short* ArgInfo, struct StrBuf* Nam SB_Terminate (Name); OffsetPart = Arg; } else { + /* <, >, ^ */ + if (Arg[0] == '<') { + Flags |= AIF_LOBYTE; + } else if (Arg[0] == '>') { + Flags |= AIF_HIBYTE; + } else if (Arg[0] == '^') { + Flags |= AIF_BANKBYTE; + } + + if ((Flags & (AIF_FAR)) != 0) { + /* Skip this char */ + ++Arg; + } + + /* Skip spaces */ + while (Arg[0] == ' ') { + ++Arg; + } + + /* Strip parentheses off if exist */ + if (Arg[0] == '(') { + /* Skip this char */ + ++Arg; + + End = strchr (Arg, ')'); + if (End == 0 || End[1] != '\0') { + /* Not closed at the end, bail out */ + *Offset = 0; + if (ArgInfo != 0) { + *ArgInfo = Flags | AIF_FAILURE; + } + return 0; + } + + /* Found */ + Parentheses = 1; + + /* Skip spaces */ + while (Arg[0] == ' ') { + ++Arg; + } + } + /* If the symbol name starts with an underline, it is an external symbol. ** If the symbol does not start with an underline, it may be a built-in ** symbol. @@ -384,7 +428,11 @@ int ParseOpcArgStr (const char* Arg, unsigned short* ArgInfo, struct StrBuf* Nam } else { /* No offset */ - SB_CopyStr (Name, Arg); + if (Parentheses == 0) { + SB_CopyStr (Name, Arg); + } else { + SB_CopyBuf (Name, Arg, End - Arg); + } SB_Terminate (Name); } @@ -410,10 +458,27 @@ int ParseOpcArgStr (const char* Arg, unsigned short* ArgInfo, struct StrBuf* Nam } Flags |= AIF_HAS_NAME; } + + /* A byte size expression with no parentheses but an offset is not + ** handled correctly for now, so just bail out in such cases. + */ + if ((Flags & AIF_FAR) != 0 && + Parentheses == 0 && + OffsetPart != 0 && + OffsetPart[0] != '\0') { + /* Bail out */ + *Offset = 0; + if (ArgInfo != 0) { + *ArgInfo = Flags | AIF_FAILURE; + } + return 0; + } } /* Get the offset */ - while (OffsetPart != 0 && OffsetPart[0] != '\0') { + while (OffsetPart != 0 && + OffsetPart[0] != '\0' && + OffsetPart[0] != ')') { /* Skip spaces */ while (OffsetPart[0] == ' ') { ++OffsetPart; @@ -448,7 +513,7 @@ int ParseOpcArgStr (const char* Arg, unsigned short* ArgInfo, struct StrBuf* Nam } /* Check if the conversion was successful */ - if (*End != '\0' && *End != ' ' && *End != '+' && *End != '-') { + if (*End != '\0' && *End != ' ' && *End != '+' && *End != '-' && *End != ')') { /* Could not convert */ *Offset = 0; if (ArgInfo != 0) { @@ -714,11 +779,33 @@ void CE_SetArgBaseAndOff (CodeEntry* E, const char* ArgBase, long ArgOff) Str = xmalloc (Len); } - if (CE_HasArgOffset (E)) { - sprintf (Str, "%s%+ld", ArgBase, ArgOff); + if ((E->ArgInfo & AIF_FAR) == 0) { + if (CE_HasArgOffset (E)) { + sprintf (Str, "%s%+ld", ArgBase, ArgOff); + } else { + sprintf (Str, "%s", ArgBase); + } + CE_SetArg (E, Str); } else { - sprintf (Str, "%s", ArgBase); + /* A byte expression */ + const char* Expr = ""; + if ((E->ArgInfo & AIF_FAR) == AIF_LOBYTE) { + Expr = "<"; + } else if ((E->ArgInfo & AIF_FAR) == AIF_HIBYTE) { + Expr = ">"; + } else if ((E->ArgInfo & AIF_FAR) == AIF_BANKBYTE) { + Expr = "^"; + } else { + Internal ("Invalid byte size flag in CE_SetArgBaseAndOff"); + } + + if (CE_HasArgOffset (E)) { + sprintf (Str, "%s(%s%+ld)", Expr, ArgBase, ArgOff); + } else { + sprintf (Str, "%s(%s)", Expr, ArgBase); + } } + CE_SetArg (E, Str); if (Str != Buf) { From eb87c6d3734a804f8cccb1a4bb4947ba5f998a8e Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 29 Sep 2020 18:54:30 +0200 Subject: [PATCH 1730/2161] rename README to readme.txt --- samples/{README => readme.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename samples/{README => readme.txt} (100%) diff --git a/samples/README b/samples/readme.txt similarity index 100% rename from samples/README rename to samples/readme.txt From b549e83fb27faeddeb8910b7267ee7e5531cf0e9 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 29 Sep 2020 19:03:42 +0200 Subject: [PATCH 1731/2161] move program from testcode/assembler to test/asm and remove testcode/assembler --- test/asm/Makefile | 5 ++- {testcode/assembler => test/asm}/paramcount.s | 0 test/asm/{README => readme.txt} | 0 testcode/assembler/Makefile | 37 ------------------- 4 files changed, 4 insertions(+), 38 deletions(-) rename {testcode/assembler => test/asm}/paramcount.s (100%) rename test/asm/{README => readme.txt} (100%) delete mode 100644 testcode/assembler/Makefile diff --git a/test/asm/Makefile b/test/asm/Makefile index b157bb672..028254b68 100644 --- a/test/asm/Makefile +++ b/test/asm/Makefile @@ -38,7 +38,7 @@ CPUDETECT_REFS := $(wildcard *-cpudetect.ref) CPUDETECT_CPUS = $(foreach ref,$(CPUDETECT_REFS),$(ref:%-cpudetect.ref=%)) CPUDETECT_BINS = $(foreach cpu,$(CPUDETECT_CPUS),$(WORKDIR)/$(cpu)-cpudetect.bin) -all: $(OPCODE_BINS) $(CPUDETECT_BINS) +all: $(OPCODE_BINS) $(CPUDETECT_BINS) paramcount.o $(WORKDIR): $(call MKDIR,$(WORKDIR)) @@ -70,5 +70,8 @@ endef # CPUDETECT_template $(foreach cpu,$(CPUDETECT_CPUS),$(eval $(call CPUDETECT_template,$(cpu)))) +paramcount.o: paramcount.s + $(CA65) -o $(WORKDIR)/paramcount.o -l $(WORKDIR)/paramcount.lst paramcount.s + clean: @$(call RMDIR,$(WORKDIR)) diff --git a/testcode/assembler/paramcount.s b/test/asm/paramcount.s similarity index 100% rename from testcode/assembler/paramcount.s rename to test/asm/paramcount.s diff --git a/test/asm/README b/test/asm/readme.txt similarity index 100% rename from test/asm/README rename to test/asm/readme.txt diff --git a/testcode/assembler/Makefile b/testcode/assembler/Makefile deleted file mode 100644 index 6cb3fe1f2..000000000 --- a/testcode/assembler/Makefile +++ /dev/null @@ -1,37 +0,0 @@ - -# 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 - -all: paramcount.o - -paramcount.o: paramcount.s - $(AS) -o paramcount.o -l paramcount.lst paramcount.s - -clean: - $(RM) paramcount.o - $(RM) paramcount.lst From bbece736f5a1ad2a2f805a72f26cfb75125b9c97 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 29 Sep 2020 19:06:05 +0200 Subject: [PATCH 1732/2161] move testcode/disasm into samples/ instead --- {testcode => samples}/disasm/.gitignore | 0 {testcode => samples}/disasm/Makefile | 0 {testcode => samples}/disasm/bank0.da | 0 {testcode => samples}/disasm/bank1.da | 0 {testcode => samples}/disasm/fixed.da | 0 {testcode => samples}/disasm/image.cfg | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename {testcode => samples}/disasm/.gitignore (100%) rename {testcode => samples}/disasm/Makefile (100%) rename {testcode => samples}/disasm/bank0.da (100%) rename {testcode => samples}/disasm/bank1.da (100%) rename {testcode => samples}/disasm/fixed.da (100%) rename {testcode => samples}/disasm/image.cfg (100%) diff --git a/testcode/disasm/.gitignore b/samples/disasm/.gitignore similarity index 100% rename from testcode/disasm/.gitignore rename to samples/disasm/.gitignore diff --git a/testcode/disasm/Makefile b/samples/disasm/Makefile similarity index 100% rename from testcode/disasm/Makefile rename to samples/disasm/Makefile diff --git a/testcode/disasm/bank0.da b/samples/disasm/bank0.da similarity index 100% rename from testcode/disasm/bank0.da rename to samples/disasm/bank0.da diff --git a/testcode/disasm/bank1.da b/samples/disasm/bank1.da similarity index 100% rename from testcode/disasm/bank1.da rename to samples/disasm/bank1.da diff --git a/testcode/disasm/fixed.da b/samples/disasm/fixed.da similarity index 100% rename from testcode/disasm/fixed.da rename to samples/disasm/fixed.da diff --git a/testcode/disasm/image.cfg b/samples/disasm/image.cfg similarity index 100% rename from testcode/disasm/image.cfg rename to samples/disasm/image.cfg From 3d8e787e66d1e3b67bcac5cbdb0d869a71e3c214 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 29 Sep 2020 19:08:40 +0200 Subject: [PATCH 1733/2161] move testcode/grc to samples/geos --- {testcode => samples/geos}/grc/Makefile | 0 {testcode => samples/geos}/grc/test.grc | 0 {testcode => samples/geos}/grc/vlir.grc | 0 {testcode => samples/geos}/grc/vlir0.s | 0 {testcode => samples/geos}/grc/vlir1.s | 0 {testcode => samples/geos}/grc/vlir2.s | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename {testcode => samples/geos}/grc/Makefile (100%) rename {testcode => samples/geos}/grc/test.grc (100%) rename {testcode => samples/geos}/grc/vlir.grc (100%) rename {testcode => samples/geos}/grc/vlir0.s (100%) rename {testcode => samples/geos}/grc/vlir1.s (100%) rename {testcode => samples/geos}/grc/vlir2.s (100%) diff --git a/testcode/grc/Makefile b/samples/geos/grc/Makefile similarity index 100% rename from testcode/grc/Makefile rename to samples/geos/grc/Makefile diff --git a/testcode/grc/test.grc b/samples/geos/grc/test.grc similarity index 100% rename from testcode/grc/test.grc rename to samples/geos/grc/test.grc diff --git a/testcode/grc/vlir.grc b/samples/geos/grc/vlir.grc similarity index 100% rename from testcode/grc/vlir.grc rename to samples/geos/grc/vlir.grc diff --git a/testcode/grc/vlir0.s b/samples/geos/grc/vlir0.s similarity index 100% rename from testcode/grc/vlir0.s rename to samples/geos/grc/vlir0.s diff --git a/testcode/grc/vlir1.s b/samples/geos/grc/vlir1.s similarity index 100% rename from testcode/grc/vlir1.s rename to samples/geos/grc/vlir1.s diff --git a/testcode/grc/vlir2.s b/samples/geos/grc/vlir2.s similarity index 100% rename from testcode/grc/vlir2.s rename to samples/geos/grc/vlir2.s From dcee493e945a0154f73e1f3cb612026a82fcf1d9 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 29 Sep 2020 19:12:34 +0200 Subject: [PATCH 1734/2161] move remaining stuff from testcode/lib/ one level up to testcode/ --- testcode/{lib => }/Makefile | 0 testcode/{lib => }/accelerator/Makefile | 0 testcode/{lib => }/accelerator/c64-c128-scpu-test.c | 0 testcode/{lib => }/accelerator/c64-c128-test.c | 0 testcode/{lib => }/accelerator/c64dtv-test.c | 0 testcode/{lib => }/accelerator/c65-test.c | 0 testcode/{lib => }/accelerator/chameleon-test.c | 0 testcode/{lib => }/accelerator/turbo-test.c | 0 testcode/{lib => }/accelerator/turbomaster-test.c | 0 testcode/{lib => }/apple2/Makefile | 0 testcode/{lib => }/apple2/astronaut.hgr | Bin testcode/{lib => }/apple2/catface.dhgr | Bin testcode/{lib => }/apple2/chips.hgr | Bin testcode/{lib => }/apple2/dhgrshow.c | 0 testcode/{lib => }/apple2/gatsby.dhgr | Bin testcode/{lib => }/apple2/girl.dhgr | Bin testcode/{lib => }/apple2/hgrshow.c | 0 testcode/{lib => }/apple2/hgrtest.c | 0 testcode/{lib => }/apple2/macrometer.hgr | Bin testcode/{lib => }/apple2/mariner.hgr | Bin testcode/{lib => }/apple2/monarch.dhgr | Bin testcode/{lib => }/apple2/rose.hgr | Bin testcode/{lib => }/apple2/superman.dhgr | Bin testcode/{lib => }/apple2/venice.dhgr | Bin testcode/{lib => }/apple2/werner.hgr | Bin testcode/{lib => }/apple2/werner.s | 0 testcode/{lib => }/apple2/winston.hgr | Bin testcode/{lib => }/arg-test.c | 0 testcode/{lib => }/atari/Makefile | 0 testcode/{lib => }/atari/asm-xex.s | 0 testcode/{lib => }/atari/charmapping.c | 0 testcode/{lib => }/atari/defdev.c | 0 testcode/{lib => }/atari/displaylist.c | 0 testcode/{lib => }/atari/mem.c | 0 testcode/{lib => }/atari/multi-xex.cfg | 0 testcode/{lib => }/atari/multi-xex.s | 0 testcode/{lib => }/atari/ostype.c | 0 testcode/{lib => }/atari/scrcode.s | 0 testcode/{lib => }/atari/sys.c | 0 testcode/{lib => }/atari5200/Makefile | 0 testcode/{lib => }/atari5200/hello.c | 0 testcode/{lib => }/cbm/Makefile | 0 testcode/{lib => }/cbm/petscii.c | 0 testcode/{lib => }/clock-test.c | 0 testcode/{lib => }/clock.c | 0 testcode/{lib => }/conio.c | 0 testcode/{lib => }/cpeek-test.c | 0 testcode/{lib => }/cprintf.c | 0 testcode/{lib => }/cursor.c | 0 testcode/{lib => }/deb.c | 0 testcode/{lib => }/dir-test.c | 0 testcode/{lib => }/div-test.c | 0 testcode/{lib => }/em-test.c | 0 testcode/{lib => }/exec-test1.c | 0 testcode/{lib => }/exec-test2.c | 0 testcode/{lib => }/fileio-test.c | 0 testcode/{lib => }/ft.c | 0 testcode/{lib => }/gamate/Makefile | 0 testcode/{lib => }/gamate/audiotest.s | 0 testcode/{lib => }/gamate/cga2.chr | Bin testcode/{lib => }/gamate/ctest.c | 0 testcode/{lib => }/gamate/lcdtest.s | 0 testcode/{lib => }/gamate/nachtm.c | 0 testcode/{lib => }/getopt-test.c | 0 testcode/{lib => }/getsp.s | 0 testcode/{lib => }/heaptest.c | 0 testcode/{lib => }/joy-test.c | 0 testcode/lib/.gitignore | 2 -- testcode/{lib => }/moddiv-test.c | 0 testcode/{lib => }/mouse-test.c | 0 testcode/{lib => }/mul-test.c | 0 testcode/{lib => }/pce/Makefile | 0 testcode/{lib => }/pce/conio.c | 0 testcode/{lib => }/posixio-test.c | 0 testcode/{lib => }/rename-test.c | 0 testcode/{lib => }/scanf-test.c | 0 testcode/{lib => }/seek.c | 0 testcode/{lib => }/ser-test.c | 0 testcode/{lib => }/strdup-test.c | 0 testcode/{lib => }/stroserror-test.c | 0 testcode/{lib => }/strqtok-test.c | 0 testcode/{lib => }/tinyshell.c | 0 testcode/{lib => }/uname-test.c | 0 83 files changed, 2 deletions(-) rename testcode/{lib => }/Makefile (100%) rename testcode/{lib => }/accelerator/Makefile (100%) rename testcode/{lib => }/accelerator/c64-c128-scpu-test.c (100%) rename testcode/{lib => }/accelerator/c64-c128-test.c (100%) rename testcode/{lib => }/accelerator/c64dtv-test.c (100%) rename testcode/{lib => }/accelerator/c65-test.c (100%) rename testcode/{lib => }/accelerator/chameleon-test.c (100%) rename testcode/{lib => }/accelerator/turbo-test.c (100%) rename testcode/{lib => }/accelerator/turbomaster-test.c (100%) rename testcode/{lib => }/apple2/Makefile (100%) rename testcode/{lib => }/apple2/astronaut.hgr (100%) rename testcode/{lib => }/apple2/catface.dhgr (100%) rename testcode/{lib => }/apple2/chips.hgr (100%) rename testcode/{lib => }/apple2/dhgrshow.c (100%) rename testcode/{lib => }/apple2/gatsby.dhgr (100%) rename testcode/{lib => }/apple2/girl.dhgr (100%) rename testcode/{lib => }/apple2/hgrshow.c (100%) rename testcode/{lib => }/apple2/hgrtest.c (100%) rename testcode/{lib => }/apple2/macrometer.hgr (100%) rename testcode/{lib => }/apple2/mariner.hgr (100%) rename testcode/{lib => }/apple2/monarch.dhgr (100%) rename testcode/{lib => }/apple2/rose.hgr (100%) rename testcode/{lib => }/apple2/superman.dhgr (100%) rename testcode/{lib => }/apple2/venice.dhgr (100%) rename testcode/{lib => }/apple2/werner.hgr (100%) rename testcode/{lib => }/apple2/werner.s (100%) rename testcode/{lib => }/apple2/winston.hgr (100%) rename testcode/{lib => }/arg-test.c (100%) rename testcode/{lib => }/atari/Makefile (100%) rename testcode/{lib => }/atari/asm-xex.s (100%) rename testcode/{lib => }/atari/charmapping.c (100%) rename testcode/{lib => }/atari/defdev.c (100%) rename testcode/{lib => }/atari/displaylist.c (100%) rename testcode/{lib => }/atari/mem.c (100%) rename testcode/{lib => }/atari/multi-xex.cfg (100%) rename testcode/{lib => }/atari/multi-xex.s (100%) rename testcode/{lib => }/atari/ostype.c (100%) rename testcode/{lib => }/atari/scrcode.s (100%) rename testcode/{lib => }/atari/sys.c (100%) rename testcode/{lib => }/atari5200/Makefile (100%) rename testcode/{lib => }/atari5200/hello.c (100%) rename testcode/{lib => }/cbm/Makefile (100%) rename testcode/{lib => }/cbm/petscii.c (100%) rename testcode/{lib => }/clock-test.c (100%) rename testcode/{lib => }/clock.c (100%) rename testcode/{lib => }/conio.c (100%) rename testcode/{lib => }/cpeek-test.c (100%) rename testcode/{lib => }/cprintf.c (100%) rename testcode/{lib => }/cursor.c (100%) rename testcode/{lib => }/deb.c (100%) rename testcode/{lib => }/dir-test.c (100%) rename testcode/{lib => }/div-test.c (100%) rename testcode/{lib => }/em-test.c (100%) rename testcode/{lib => }/exec-test1.c (100%) rename testcode/{lib => }/exec-test2.c (100%) rename testcode/{lib => }/fileio-test.c (100%) rename testcode/{lib => }/ft.c (100%) rename testcode/{lib => }/gamate/Makefile (100%) rename testcode/{lib => }/gamate/audiotest.s (100%) rename testcode/{lib => }/gamate/cga2.chr (100%) rename testcode/{lib => }/gamate/ctest.c (100%) rename testcode/{lib => }/gamate/lcdtest.s (100%) rename testcode/{lib => }/gamate/nachtm.c (100%) rename testcode/{lib => }/getopt-test.c (100%) rename testcode/{lib => }/getsp.s (100%) rename testcode/{lib => }/heaptest.c (100%) rename testcode/{lib => }/joy-test.c (100%) delete mode 100644 testcode/lib/.gitignore rename testcode/{lib => }/moddiv-test.c (100%) rename testcode/{lib => }/mouse-test.c (100%) rename testcode/{lib => }/mul-test.c (100%) rename testcode/{lib => }/pce/Makefile (100%) rename testcode/{lib => }/pce/conio.c (100%) rename testcode/{lib => }/posixio-test.c (100%) rename testcode/{lib => }/rename-test.c (100%) rename testcode/{lib => }/scanf-test.c (100%) rename testcode/{lib => }/seek.c (100%) rename testcode/{lib => }/ser-test.c (100%) rename testcode/{lib => }/strdup-test.c (100%) rename testcode/{lib => }/stroserror-test.c (100%) rename testcode/{lib => }/strqtok-test.c (100%) rename testcode/{lib => }/tinyshell.c (100%) rename testcode/{lib => }/uname-test.c (100%) diff --git a/testcode/lib/Makefile b/testcode/Makefile similarity index 100% rename from testcode/lib/Makefile rename to testcode/Makefile diff --git a/testcode/lib/accelerator/Makefile b/testcode/accelerator/Makefile similarity index 100% rename from testcode/lib/accelerator/Makefile rename to testcode/accelerator/Makefile diff --git a/testcode/lib/accelerator/c64-c128-scpu-test.c b/testcode/accelerator/c64-c128-scpu-test.c similarity index 100% rename from testcode/lib/accelerator/c64-c128-scpu-test.c rename to testcode/accelerator/c64-c128-scpu-test.c diff --git a/testcode/lib/accelerator/c64-c128-test.c b/testcode/accelerator/c64-c128-test.c similarity index 100% rename from testcode/lib/accelerator/c64-c128-test.c rename to testcode/accelerator/c64-c128-test.c diff --git a/testcode/lib/accelerator/c64dtv-test.c b/testcode/accelerator/c64dtv-test.c similarity index 100% rename from testcode/lib/accelerator/c64dtv-test.c rename to testcode/accelerator/c64dtv-test.c diff --git a/testcode/lib/accelerator/c65-test.c b/testcode/accelerator/c65-test.c similarity index 100% rename from testcode/lib/accelerator/c65-test.c rename to testcode/accelerator/c65-test.c diff --git a/testcode/lib/accelerator/chameleon-test.c b/testcode/accelerator/chameleon-test.c similarity index 100% rename from testcode/lib/accelerator/chameleon-test.c rename to testcode/accelerator/chameleon-test.c diff --git a/testcode/lib/accelerator/turbo-test.c b/testcode/accelerator/turbo-test.c similarity index 100% rename from testcode/lib/accelerator/turbo-test.c rename to testcode/accelerator/turbo-test.c diff --git a/testcode/lib/accelerator/turbomaster-test.c b/testcode/accelerator/turbomaster-test.c similarity index 100% rename from testcode/lib/accelerator/turbomaster-test.c rename to testcode/accelerator/turbomaster-test.c diff --git a/testcode/lib/apple2/Makefile b/testcode/apple2/Makefile similarity index 100% rename from testcode/lib/apple2/Makefile rename to testcode/apple2/Makefile diff --git a/testcode/lib/apple2/astronaut.hgr b/testcode/apple2/astronaut.hgr similarity index 100% rename from testcode/lib/apple2/astronaut.hgr rename to testcode/apple2/astronaut.hgr diff --git a/testcode/lib/apple2/catface.dhgr b/testcode/apple2/catface.dhgr similarity index 100% rename from testcode/lib/apple2/catface.dhgr rename to testcode/apple2/catface.dhgr diff --git a/testcode/lib/apple2/chips.hgr b/testcode/apple2/chips.hgr similarity index 100% rename from testcode/lib/apple2/chips.hgr rename to testcode/apple2/chips.hgr diff --git a/testcode/lib/apple2/dhgrshow.c b/testcode/apple2/dhgrshow.c similarity index 100% rename from testcode/lib/apple2/dhgrshow.c rename to testcode/apple2/dhgrshow.c diff --git a/testcode/lib/apple2/gatsby.dhgr b/testcode/apple2/gatsby.dhgr similarity index 100% rename from testcode/lib/apple2/gatsby.dhgr rename to testcode/apple2/gatsby.dhgr diff --git a/testcode/lib/apple2/girl.dhgr b/testcode/apple2/girl.dhgr similarity index 100% rename from testcode/lib/apple2/girl.dhgr rename to testcode/apple2/girl.dhgr diff --git a/testcode/lib/apple2/hgrshow.c b/testcode/apple2/hgrshow.c similarity index 100% rename from testcode/lib/apple2/hgrshow.c rename to testcode/apple2/hgrshow.c diff --git a/testcode/lib/apple2/hgrtest.c b/testcode/apple2/hgrtest.c similarity index 100% rename from testcode/lib/apple2/hgrtest.c rename to testcode/apple2/hgrtest.c diff --git a/testcode/lib/apple2/macrometer.hgr b/testcode/apple2/macrometer.hgr similarity index 100% rename from testcode/lib/apple2/macrometer.hgr rename to testcode/apple2/macrometer.hgr diff --git a/testcode/lib/apple2/mariner.hgr b/testcode/apple2/mariner.hgr similarity index 100% rename from testcode/lib/apple2/mariner.hgr rename to testcode/apple2/mariner.hgr diff --git a/testcode/lib/apple2/monarch.dhgr b/testcode/apple2/monarch.dhgr similarity index 100% rename from testcode/lib/apple2/monarch.dhgr rename to testcode/apple2/monarch.dhgr diff --git a/testcode/lib/apple2/rose.hgr b/testcode/apple2/rose.hgr similarity index 100% rename from testcode/lib/apple2/rose.hgr rename to testcode/apple2/rose.hgr diff --git a/testcode/lib/apple2/superman.dhgr b/testcode/apple2/superman.dhgr similarity index 100% rename from testcode/lib/apple2/superman.dhgr rename to testcode/apple2/superman.dhgr diff --git a/testcode/lib/apple2/venice.dhgr b/testcode/apple2/venice.dhgr similarity index 100% rename from testcode/lib/apple2/venice.dhgr rename to testcode/apple2/venice.dhgr diff --git a/testcode/lib/apple2/werner.hgr b/testcode/apple2/werner.hgr similarity index 100% rename from testcode/lib/apple2/werner.hgr rename to testcode/apple2/werner.hgr diff --git a/testcode/lib/apple2/werner.s b/testcode/apple2/werner.s similarity index 100% rename from testcode/lib/apple2/werner.s rename to testcode/apple2/werner.s diff --git a/testcode/lib/apple2/winston.hgr b/testcode/apple2/winston.hgr similarity index 100% rename from testcode/lib/apple2/winston.hgr rename to testcode/apple2/winston.hgr diff --git a/testcode/lib/arg-test.c b/testcode/arg-test.c similarity index 100% rename from testcode/lib/arg-test.c rename to testcode/arg-test.c diff --git a/testcode/lib/atari/Makefile b/testcode/atari/Makefile similarity index 100% rename from testcode/lib/atari/Makefile rename to testcode/atari/Makefile diff --git a/testcode/lib/atari/asm-xex.s b/testcode/atari/asm-xex.s similarity index 100% rename from testcode/lib/atari/asm-xex.s rename to testcode/atari/asm-xex.s diff --git a/testcode/lib/atari/charmapping.c b/testcode/atari/charmapping.c similarity index 100% rename from testcode/lib/atari/charmapping.c rename to testcode/atari/charmapping.c diff --git a/testcode/lib/atari/defdev.c b/testcode/atari/defdev.c similarity index 100% rename from testcode/lib/atari/defdev.c rename to testcode/atari/defdev.c diff --git a/testcode/lib/atari/displaylist.c b/testcode/atari/displaylist.c similarity index 100% rename from testcode/lib/atari/displaylist.c rename to testcode/atari/displaylist.c diff --git a/testcode/lib/atari/mem.c b/testcode/atari/mem.c similarity index 100% rename from testcode/lib/atari/mem.c rename to testcode/atari/mem.c diff --git a/testcode/lib/atari/multi-xex.cfg b/testcode/atari/multi-xex.cfg similarity index 100% rename from testcode/lib/atari/multi-xex.cfg rename to testcode/atari/multi-xex.cfg diff --git a/testcode/lib/atari/multi-xex.s b/testcode/atari/multi-xex.s similarity index 100% rename from testcode/lib/atari/multi-xex.s rename to testcode/atari/multi-xex.s diff --git a/testcode/lib/atari/ostype.c b/testcode/atari/ostype.c similarity index 100% rename from testcode/lib/atari/ostype.c rename to testcode/atari/ostype.c diff --git a/testcode/lib/atari/scrcode.s b/testcode/atari/scrcode.s similarity index 100% rename from testcode/lib/atari/scrcode.s rename to testcode/atari/scrcode.s diff --git a/testcode/lib/atari/sys.c b/testcode/atari/sys.c similarity index 100% rename from testcode/lib/atari/sys.c rename to testcode/atari/sys.c diff --git a/testcode/lib/atari5200/Makefile b/testcode/atari5200/Makefile similarity index 100% rename from testcode/lib/atari5200/Makefile rename to testcode/atari5200/Makefile diff --git a/testcode/lib/atari5200/hello.c b/testcode/atari5200/hello.c similarity index 100% rename from testcode/lib/atari5200/hello.c rename to testcode/atari5200/hello.c diff --git a/testcode/lib/cbm/Makefile b/testcode/cbm/Makefile similarity index 100% rename from testcode/lib/cbm/Makefile rename to testcode/cbm/Makefile diff --git a/testcode/lib/cbm/petscii.c b/testcode/cbm/petscii.c similarity index 100% rename from testcode/lib/cbm/petscii.c rename to testcode/cbm/petscii.c diff --git a/testcode/lib/clock-test.c b/testcode/clock-test.c similarity index 100% rename from testcode/lib/clock-test.c rename to testcode/clock-test.c diff --git a/testcode/lib/clock.c b/testcode/clock.c similarity index 100% rename from testcode/lib/clock.c rename to testcode/clock.c diff --git a/testcode/lib/conio.c b/testcode/conio.c similarity index 100% rename from testcode/lib/conio.c rename to testcode/conio.c diff --git a/testcode/lib/cpeek-test.c b/testcode/cpeek-test.c similarity index 100% rename from testcode/lib/cpeek-test.c rename to testcode/cpeek-test.c diff --git a/testcode/lib/cprintf.c b/testcode/cprintf.c similarity index 100% rename from testcode/lib/cprintf.c rename to testcode/cprintf.c diff --git a/testcode/lib/cursor.c b/testcode/cursor.c similarity index 100% rename from testcode/lib/cursor.c rename to testcode/cursor.c diff --git a/testcode/lib/deb.c b/testcode/deb.c similarity index 100% rename from testcode/lib/deb.c rename to testcode/deb.c diff --git a/testcode/lib/dir-test.c b/testcode/dir-test.c similarity index 100% rename from testcode/lib/dir-test.c rename to testcode/dir-test.c diff --git a/testcode/lib/div-test.c b/testcode/div-test.c similarity index 100% rename from testcode/lib/div-test.c rename to testcode/div-test.c diff --git a/testcode/lib/em-test.c b/testcode/em-test.c similarity index 100% rename from testcode/lib/em-test.c rename to testcode/em-test.c diff --git a/testcode/lib/exec-test1.c b/testcode/exec-test1.c similarity index 100% rename from testcode/lib/exec-test1.c rename to testcode/exec-test1.c diff --git a/testcode/lib/exec-test2.c b/testcode/exec-test2.c similarity index 100% rename from testcode/lib/exec-test2.c rename to testcode/exec-test2.c diff --git a/testcode/lib/fileio-test.c b/testcode/fileio-test.c similarity index 100% rename from testcode/lib/fileio-test.c rename to testcode/fileio-test.c diff --git a/testcode/lib/ft.c b/testcode/ft.c similarity index 100% rename from testcode/lib/ft.c rename to testcode/ft.c diff --git a/testcode/lib/gamate/Makefile b/testcode/gamate/Makefile similarity index 100% rename from testcode/lib/gamate/Makefile rename to testcode/gamate/Makefile diff --git a/testcode/lib/gamate/audiotest.s b/testcode/gamate/audiotest.s similarity index 100% rename from testcode/lib/gamate/audiotest.s rename to testcode/gamate/audiotest.s diff --git a/testcode/lib/gamate/cga2.chr b/testcode/gamate/cga2.chr similarity index 100% rename from testcode/lib/gamate/cga2.chr rename to testcode/gamate/cga2.chr diff --git a/testcode/lib/gamate/ctest.c b/testcode/gamate/ctest.c similarity index 100% rename from testcode/lib/gamate/ctest.c rename to testcode/gamate/ctest.c diff --git a/testcode/lib/gamate/lcdtest.s b/testcode/gamate/lcdtest.s similarity index 100% rename from testcode/lib/gamate/lcdtest.s rename to testcode/gamate/lcdtest.s diff --git a/testcode/lib/gamate/nachtm.c b/testcode/gamate/nachtm.c similarity index 100% rename from testcode/lib/gamate/nachtm.c rename to testcode/gamate/nachtm.c diff --git a/testcode/lib/getopt-test.c b/testcode/getopt-test.c similarity index 100% rename from testcode/lib/getopt-test.c rename to testcode/getopt-test.c diff --git a/testcode/lib/getsp.s b/testcode/getsp.s similarity index 100% rename from testcode/lib/getsp.s rename to testcode/getsp.s diff --git a/testcode/lib/heaptest.c b/testcode/heaptest.c similarity index 100% rename from testcode/lib/heaptest.c rename to testcode/heaptest.c diff --git a/testcode/lib/joy-test.c b/testcode/joy-test.c similarity index 100% rename from testcode/lib/joy-test.c rename to testcode/joy-test.c diff --git a/testcode/lib/.gitignore b/testcode/lib/.gitignore deleted file mode 100644 index 9bb8eaa3e..000000000 --- a/testcode/lib/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.o -em-test-* diff --git a/testcode/lib/moddiv-test.c b/testcode/moddiv-test.c similarity index 100% rename from testcode/lib/moddiv-test.c rename to testcode/moddiv-test.c diff --git a/testcode/lib/mouse-test.c b/testcode/mouse-test.c similarity index 100% rename from testcode/lib/mouse-test.c rename to testcode/mouse-test.c diff --git a/testcode/lib/mul-test.c b/testcode/mul-test.c similarity index 100% rename from testcode/lib/mul-test.c rename to testcode/mul-test.c diff --git a/testcode/lib/pce/Makefile b/testcode/pce/Makefile similarity index 100% rename from testcode/lib/pce/Makefile rename to testcode/pce/Makefile diff --git a/testcode/lib/pce/conio.c b/testcode/pce/conio.c similarity index 100% rename from testcode/lib/pce/conio.c rename to testcode/pce/conio.c diff --git a/testcode/lib/posixio-test.c b/testcode/posixio-test.c similarity index 100% rename from testcode/lib/posixio-test.c rename to testcode/posixio-test.c diff --git a/testcode/lib/rename-test.c b/testcode/rename-test.c similarity index 100% rename from testcode/lib/rename-test.c rename to testcode/rename-test.c diff --git a/testcode/lib/scanf-test.c b/testcode/scanf-test.c similarity index 100% rename from testcode/lib/scanf-test.c rename to testcode/scanf-test.c diff --git a/testcode/lib/seek.c b/testcode/seek.c similarity index 100% rename from testcode/lib/seek.c rename to testcode/seek.c diff --git a/testcode/lib/ser-test.c b/testcode/ser-test.c similarity index 100% rename from testcode/lib/ser-test.c rename to testcode/ser-test.c diff --git a/testcode/lib/strdup-test.c b/testcode/strdup-test.c similarity index 100% rename from testcode/lib/strdup-test.c rename to testcode/strdup-test.c diff --git a/testcode/lib/stroserror-test.c b/testcode/stroserror-test.c similarity index 100% rename from testcode/lib/stroserror-test.c rename to testcode/stroserror-test.c diff --git a/testcode/lib/strqtok-test.c b/testcode/strqtok-test.c similarity index 100% rename from testcode/lib/strqtok-test.c rename to testcode/strqtok-test.c diff --git a/testcode/lib/tinyshell.c b/testcode/tinyshell.c similarity index 100% rename from testcode/lib/tinyshell.c rename to testcode/tinyshell.c diff --git a/testcode/lib/uname-test.c b/testcode/uname-test.c similarity index 100% rename from testcode/lib/uname-test.c rename to testcode/uname-test.c From 4777e98f570b5227de20bac41d2721e762352b44 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 29 Sep 2020 19:14:46 +0200 Subject: [PATCH 1735/2161] rename testcode/ to targettest/ --- {testcode => targettest}/Makefile | 0 {testcode => targettest}/accelerator/Makefile | 0 .../accelerator/c64-c128-scpu-test.c | 0 .../accelerator/c64-c128-test.c | 0 {testcode => targettest}/accelerator/c64dtv-test.c | 0 {testcode => targettest}/accelerator/c65-test.c | 0 .../accelerator/chameleon-test.c | 0 {testcode => targettest}/accelerator/turbo-test.c | 0 .../accelerator/turbomaster-test.c | 0 {testcode => targettest}/apple2/Makefile | 0 {testcode => targettest}/apple2/astronaut.hgr | Bin {testcode => targettest}/apple2/catface.dhgr | Bin {testcode => targettest}/apple2/chips.hgr | Bin {testcode => targettest}/apple2/dhgrshow.c | 0 {testcode => targettest}/apple2/gatsby.dhgr | Bin {testcode => targettest}/apple2/girl.dhgr | Bin {testcode => targettest}/apple2/hgrshow.c | 0 {testcode => targettest}/apple2/hgrtest.c | 0 {testcode => targettest}/apple2/macrometer.hgr | Bin {testcode => targettest}/apple2/mariner.hgr | Bin {testcode => targettest}/apple2/monarch.dhgr | Bin {testcode => targettest}/apple2/rose.hgr | Bin {testcode => targettest}/apple2/superman.dhgr | Bin {testcode => targettest}/apple2/venice.dhgr | Bin {testcode => targettest}/apple2/werner.hgr | Bin {testcode => targettest}/apple2/werner.s | 0 {testcode => targettest}/apple2/winston.hgr | Bin {testcode => targettest}/arg-test.c | 0 {testcode => targettest}/atari/Makefile | 0 {testcode => targettest}/atari/asm-xex.s | 0 {testcode => targettest}/atari/charmapping.c | 0 {testcode => targettest}/atari/defdev.c | 0 {testcode => targettest}/atari/displaylist.c | 0 {testcode => targettest}/atari/mem.c | 0 {testcode => targettest}/atari/multi-xex.cfg | 0 {testcode => targettest}/atari/multi-xex.s | 0 {testcode => targettest}/atari/ostype.c | 0 {testcode => targettest}/atari/scrcode.s | 0 {testcode => targettest}/atari/sys.c | 0 {testcode => targettest}/atari5200/Makefile | 0 {testcode => targettest}/atari5200/hello.c | 0 {testcode => targettest}/cbm/Makefile | 0 {testcode => targettest}/cbm/petscii.c | 0 {testcode => targettest}/clock-test.c | 0 {testcode => targettest}/clock.c | 0 {testcode => targettest}/conio.c | 0 {testcode => targettest}/cpeek-test.c | 0 {testcode => targettest}/cprintf.c | 0 {testcode => targettest}/cursor.c | 0 {testcode => targettest}/deb.c | 0 {testcode => targettest}/dir-test.c | 0 {testcode => targettest}/div-test.c | 0 {testcode => targettest}/em-test.c | 0 {testcode => targettest}/exec-test1.c | 0 {testcode => targettest}/exec-test2.c | 0 {testcode => targettest}/fileio-test.c | 0 {testcode => targettest}/ft.c | 0 {testcode => targettest}/gamate/Makefile | 0 {testcode => targettest}/gamate/audiotest.s | 0 {testcode => targettest}/gamate/cga2.chr | Bin {testcode => targettest}/gamate/ctest.c | 0 {testcode => targettest}/gamate/lcdtest.s | 0 {testcode => targettest}/gamate/nachtm.c | 0 {testcode => targettest}/getopt-test.c | 0 {testcode => targettest}/getsp.s | 0 {testcode => targettest}/heaptest.c | 0 {testcode => targettest}/joy-test.c | 0 {testcode => targettest}/moddiv-test.c | 0 {testcode => targettest}/mouse-test.c | 0 {testcode => targettest}/mul-test.c | 0 {testcode => targettest}/pce/Makefile | 0 {testcode => targettest}/pce/conio.c | 0 {testcode => targettest}/posixio-test.c | 0 {testcode => targettest}/rename-test.c | 0 {testcode => targettest}/scanf-test.c | 0 {testcode => targettest}/seek.c | 0 {testcode => targettest}/ser-test.c | 0 {testcode => targettest}/strdup-test.c | 0 {testcode => targettest}/stroserror-test.c | 0 {testcode => targettest}/strqtok-test.c | 0 {testcode => targettest}/tinyshell.c | 0 {testcode => targettest}/uname-test.c | 0 82 files changed, 0 insertions(+), 0 deletions(-) rename {testcode => targettest}/Makefile (100%) rename {testcode => targettest}/accelerator/Makefile (100%) rename {testcode => targettest}/accelerator/c64-c128-scpu-test.c (100%) rename {testcode => targettest}/accelerator/c64-c128-test.c (100%) rename {testcode => targettest}/accelerator/c64dtv-test.c (100%) rename {testcode => targettest}/accelerator/c65-test.c (100%) rename {testcode => targettest}/accelerator/chameleon-test.c (100%) rename {testcode => targettest}/accelerator/turbo-test.c (100%) rename {testcode => targettest}/accelerator/turbomaster-test.c (100%) rename {testcode => targettest}/apple2/Makefile (100%) rename {testcode => targettest}/apple2/astronaut.hgr (100%) rename {testcode => targettest}/apple2/catface.dhgr (100%) rename {testcode => targettest}/apple2/chips.hgr (100%) rename {testcode => targettest}/apple2/dhgrshow.c (100%) rename {testcode => targettest}/apple2/gatsby.dhgr (100%) rename {testcode => targettest}/apple2/girl.dhgr (100%) rename {testcode => targettest}/apple2/hgrshow.c (100%) rename {testcode => targettest}/apple2/hgrtest.c (100%) rename {testcode => targettest}/apple2/macrometer.hgr (100%) rename {testcode => targettest}/apple2/mariner.hgr (100%) rename {testcode => targettest}/apple2/monarch.dhgr (100%) rename {testcode => targettest}/apple2/rose.hgr (100%) rename {testcode => targettest}/apple2/superman.dhgr (100%) rename {testcode => targettest}/apple2/venice.dhgr (100%) rename {testcode => targettest}/apple2/werner.hgr (100%) rename {testcode => targettest}/apple2/werner.s (100%) rename {testcode => targettest}/apple2/winston.hgr (100%) rename {testcode => targettest}/arg-test.c (100%) rename {testcode => targettest}/atari/Makefile (100%) rename {testcode => targettest}/atari/asm-xex.s (100%) rename {testcode => targettest}/atari/charmapping.c (100%) rename {testcode => targettest}/atari/defdev.c (100%) rename {testcode => targettest}/atari/displaylist.c (100%) rename {testcode => targettest}/atari/mem.c (100%) rename {testcode => targettest}/atari/multi-xex.cfg (100%) rename {testcode => targettest}/atari/multi-xex.s (100%) rename {testcode => targettest}/atari/ostype.c (100%) rename {testcode => targettest}/atari/scrcode.s (100%) rename {testcode => targettest}/atari/sys.c (100%) rename {testcode => targettest}/atari5200/Makefile (100%) rename {testcode => targettest}/atari5200/hello.c (100%) rename {testcode => targettest}/cbm/Makefile (100%) rename {testcode => targettest}/cbm/petscii.c (100%) rename {testcode => targettest}/clock-test.c (100%) rename {testcode => targettest}/clock.c (100%) rename {testcode => targettest}/conio.c (100%) rename {testcode => targettest}/cpeek-test.c (100%) rename {testcode => targettest}/cprintf.c (100%) rename {testcode => targettest}/cursor.c (100%) rename {testcode => targettest}/deb.c (100%) rename {testcode => targettest}/dir-test.c (100%) rename {testcode => targettest}/div-test.c (100%) rename {testcode => targettest}/em-test.c (100%) rename {testcode => targettest}/exec-test1.c (100%) rename {testcode => targettest}/exec-test2.c (100%) rename {testcode => targettest}/fileio-test.c (100%) rename {testcode => targettest}/ft.c (100%) rename {testcode => targettest}/gamate/Makefile (100%) rename {testcode => targettest}/gamate/audiotest.s (100%) rename {testcode => targettest}/gamate/cga2.chr (100%) rename {testcode => targettest}/gamate/ctest.c (100%) rename {testcode => targettest}/gamate/lcdtest.s (100%) rename {testcode => targettest}/gamate/nachtm.c (100%) rename {testcode => targettest}/getopt-test.c (100%) rename {testcode => targettest}/getsp.s (100%) rename {testcode => targettest}/heaptest.c (100%) rename {testcode => targettest}/joy-test.c (100%) rename {testcode => targettest}/moddiv-test.c (100%) rename {testcode => targettest}/mouse-test.c (100%) rename {testcode => targettest}/mul-test.c (100%) rename {testcode => targettest}/pce/Makefile (100%) rename {testcode => targettest}/pce/conio.c (100%) rename {testcode => targettest}/posixio-test.c (100%) rename {testcode => targettest}/rename-test.c (100%) rename {testcode => targettest}/scanf-test.c (100%) rename {testcode => targettest}/seek.c (100%) rename {testcode => targettest}/ser-test.c (100%) rename {testcode => targettest}/strdup-test.c (100%) rename {testcode => targettest}/stroserror-test.c (100%) rename {testcode => targettest}/strqtok-test.c (100%) rename {testcode => targettest}/tinyshell.c (100%) rename {testcode => targettest}/uname-test.c (100%) diff --git a/testcode/Makefile b/targettest/Makefile similarity index 100% rename from testcode/Makefile rename to targettest/Makefile diff --git a/testcode/accelerator/Makefile b/targettest/accelerator/Makefile similarity index 100% rename from testcode/accelerator/Makefile rename to targettest/accelerator/Makefile diff --git a/testcode/accelerator/c64-c128-scpu-test.c b/targettest/accelerator/c64-c128-scpu-test.c similarity index 100% rename from testcode/accelerator/c64-c128-scpu-test.c rename to targettest/accelerator/c64-c128-scpu-test.c diff --git a/testcode/accelerator/c64-c128-test.c b/targettest/accelerator/c64-c128-test.c similarity index 100% rename from testcode/accelerator/c64-c128-test.c rename to targettest/accelerator/c64-c128-test.c diff --git a/testcode/accelerator/c64dtv-test.c b/targettest/accelerator/c64dtv-test.c similarity index 100% rename from testcode/accelerator/c64dtv-test.c rename to targettest/accelerator/c64dtv-test.c diff --git a/testcode/accelerator/c65-test.c b/targettest/accelerator/c65-test.c similarity index 100% rename from testcode/accelerator/c65-test.c rename to targettest/accelerator/c65-test.c diff --git a/testcode/accelerator/chameleon-test.c b/targettest/accelerator/chameleon-test.c similarity index 100% rename from testcode/accelerator/chameleon-test.c rename to targettest/accelerator/chameleon-test.c diff --git a/testcode/accelerator/turbo-test.c b/targettest/accelerator/turbo-test.c similarity index 100% rename from testcode/accelerator/turbo-test.c rename to targettest/accelerator/turbo-test.c diff --git a/testcode/accelerator/turbomaster-test.c b/targettest/accelerator/turbomaster-test.c similarity index 100% rename from testcode/accelerator/turbomaster-test.c rename to targettest/accelerator/turbomaster-test.c diff --git a/testcode/apple2/Makefile b/targettest/apple2/Makefile similarity index 100% rename from testcode/apple2/Makefile rename to targettest/apple2/Makefile diff --git a/testcode/apple2/astronaut.hgr b/targettest/apple2/astronaut.hgr similarity index 100% rename from testcode/apple2/astronaut.hgr rename to targettest/apple2/astronaut.hgr diff --git a/testcode/apple2/catface.dhgr b/targettest/apple2/catface.dhgr similarity index 100% rename from testcode/apple2/catface.dhgr rename to targettest/apple2/catface.dhgr diff --git a/testcode/apple2/chips.hgr b/targettest/apple2/chips.hgr similarity index 100% rename from testcode/apple2/chips.hgr rename to targettest/apple2/chips.hgr diff --git a/testcode/apple2/dhgrshow.c b/targettest/apple2/dhgrshow.c similarity index 100% rename from testcode/apple2/dhgrshow.c rename to targettest/apple2/dhgrshow.c diff --git a/testcode/apple2/gatsby.dhgr b/targettest/apple2/gatsby.dhgr similarity index 100% rename from testcode/apple2/gatsby.dhgr rename to targettest/apple2/gatsby.dhgr diff --git a/testcode/apple2/girl.dhgr b/targettest/apple2/girl.dhgr similarity index 100% rename from testcode/apple2/girl.dhgr rename to targettest/apple2/girl.dhgr diff --git a/testcode/apple2/hgrshow.c b/targettest/apple2/hgrshow.c similarity index 100% rename from testcode/apple2/hgrshow.c rename to targettest/apple2/hgrshow.c diff --git a/testcode/apple2/hgrtest.c b/targettest/apple2/hgrtest.c similarity index 100% rename from testcode/apple2/hgrtest.c rename to targettest/apple2/hgrtest.c diff --git a/testcode/apple2/macrometer.hgr b/targettest/apple2/macrometer.hgr similarity index 100% rename from testcode/apple2/macrometer.hgr rename to targettest/apple2/macrometer.hgr diff --git a/testcode/apple2/mariner.hgr b/targettest/apple2/mariner.hgr similarity index 100% rename from testcode/apple2/mariner.hgr rename to targettest/apple2/mariner.hgr diff --git a/testcode/apple2/monarch.dhgr b/targettest/apple2/monarch.dhgr similarity index 100% rename from testcode/apple2/monarch.dhgr rename to targettest/apple2/monarch.dhgr diff --git a/testcode/apple2/rose.hgr b/targettest/apple2/rose.hgr similarity index 100% rename from testcode/apple2/rose.hgr rename to targettest/apple2/rose.hgr diff --git a/testcode/apple2/superman.dhgr b/targettest/apple2/superman.dhgr similarity index 100% rename from testcode/apple2/superman.dhgr rename to targettest/apple2/superman.dhgr diff --git a/testcode/apple2/venice.dhgr b/targettest/apple2/venice.dhgr similarity index 100% rename from testcode/apple2/venice.dhgr rename to targettest/apple2/venice.dhgr diff --git a/testcode/apple2/werner.hgr b/targettest/apple2/werner.hgr similarity index 100% rename from testcode/apple2/werner.hgr rename to targettest/apple2/werner.hgr diff --git a/testcode/apple2/werner.s b/targettest/apple2/werner.s similarity index 100% rename from testcode/apple2/werner.s rename to targettest/apple2/werner.s diff --git a/testcode/apple2/winston.hgr b/targettest/apple2/winston.hgr similarity index 100% rename from testcode/apple2/winston.hgr rename to targettest/apple2/winston.hgr diff --git a/testcode/arg-test.c b/targettest/arg-test.c similarity index 100% rename from testcode/arg-test.c rename to targettest/arg-test.c diff --git a/testcode/atari/Makefile b/targettest/atari/Makefile similarity index 100% rename from testcode/atari/Makefile rename to targettest/atari/Makefile diff --git a/testcode/atari/asm-xex.s b/targettest/atari/asm-xex.s similarity index 100% rename from testcode/atari/asm-xex.s rename to targettest/atari/asm-xex.s diff --git a/testcode/atari/charmapping.c b/targettest/atari/charmapping.c similarity index 100% rename from testcode/atari/charmapping.c rename to targettest/atari/charmapping.c diff --git a/testcode/atari/defdev.c b/targettest/atari/defdev.c similarity index 100% rename from testcode/atari/defdev.c rename to targettest/atari/defdev.c diff --git a/testcode/atari/displaylist.c b/targettest/atari/displaylist.c similarity index 100% rename from testcode/atari/displaylist.c rename to targettest/atari/displaylist.c diff --git a/testcode/atari/mem.c b/targettest/atari/mem.c similarity index 100% rename from testcode/atari/mem.c rename to targettest/atari/mem.c diff --git a/testcode/atari/multi-xex.cfg b/targettest/atari/multi-xex.cfg similarity index 100% rename from testcode/atari/multi-xex.cfg rename to targettest/atari/multi-xex.cfg diff --git a/testcode/atari/multi-xex.s b/targettest/atari/multi-xex.s similarity index 100% rename from testcode/atari/multi-xex.s rename to targettest/atari/multi-xex.s diff --git a/testcode/atari/ostype.c b/targettest/atari/ostype.c similarity index 100% rename from testcode/atari/ostype.c rename to targettest/atari/ostype.c diff --git a/testcode/atari/scrcode.s b/targettest/atari/scrcode.s similarity index 100% rename from testcode/atari/scrcode.s rename to targettest/atari/scrcode.s diff --git a/testcode/atari/sys.c b/targettest/atari/sys.c similarity index 100% rename from testcode/atari/sys.c rename to targettest/atari/sys.c diff --git a/testcode/atari5200/Makefile b/targettest/atari5200/Makefile similarity index 100% rename from testcode/atari5200/Makefile rename to targettest/atari5200/Makefile diff --git a/testcode/atari5200/hello.c b/targettest/atari5200/hello.c similarity index 100% rename from testcode/atari5200/hello.c rename to targettest/atari5200/hello.c diff --git a/testcode/cbm/Makefile b/targettest/cbm/Makefile similarity index 100% rename from testcode/cbm/Makefile rename to targettest/cbm/Makefile diff --git a/testcode/cbm/petscii.c b/targettest/cbm/petscii.c similarity index 100% rename from testcode/cbm/petscii.c rename to targettest/cbm/petscii.c diff --git a/testcode/clock-test.c b/targettest/clock-test.c similarity index 100% rename from testcode/clock-test.c rename to targettest/clock-test.c diff --git a/testcode/clock.c b/targettest/clock.c similarity index 100% rename from testcode/clock.c rename to targettest/clock.c diff --git a/testcode/conio.c b/targettest/conio.c similarity index 100% rename from testcode/conio.c rename to targettest/conio.c diff --git a/testcode/cpeek-test.c b/targettest/cpeek-test.c similarity index 100% rename from testcode/cpeek-test.c rename to targettest/cpeek-test.c diff --git a/testcode/cprintf.c b/targettest/cprintf.c similarity index 100% rename from testcode/cprintf.c rename to targettest/cprintf.c diff --git a/testcode/cursor.c b/targettest/cursor.c similarity index 100% rename from testcode/cursor.c rename to targettest/cursor.c diff --git a/testcode/deb.c b/targettest/deb.c similarity index 100% rename from testcode/deb.c rename to targettest/deb.c diff --git a/testcode/dir-test.c b/targettest/dir-test.c similarity index 100% rename from testcode/dir-test.c rename to targettest/dir-test.c diff --git a/testcode/div-test.c b/targettest/div-test.c similarity index 100% rename from testcode/div-test.c rename to targettest/div-test.c diff --git a/testcode/em-test.c b/targettest/em-test.c similarity index 100% rename from testcode/em-test.c rename to targettest/em-test.c diff --git a/testcode/exec-test1.c b/targettest/exec-test1.c similarity index 100% rename from testcode/exec-test1.c rename to targettest/exec-test1.c diff --git a/testcode/exec-test2.c b/targettest/exec-test2.c similarity index 100% rename from testcode/exec-test2.c rename to targettest/exec-test2.c diff --git a/testcode/fileio-test.c b/targettest/fileio-test.c similarity index 100% rename from testcode/fileio-test.c rename to targettest/fileio-test.c diff --git a/testcode/ft.c b/targettest/ft.c similarity index 100% rename from testcode/ft.c rename to targettest/ft.c diff --git a/testcode/gamate/Makefile b/targettest/gamate/Makefile similarity index 100% rename from testcode/gamate/Makefile rename to targettest/gamate/Makefile diff --git a/testcode/gamate/audiotest.s b/targettest/gamate/audiotest.s similarity index 100% rename from testcode/gamate/audiotest.s rename to targettest/gamate/audiotest.s diff --git a/testcode/gamate/cga2.chr b/targettest/gamate/cga2.chr similarity index 100% rename from testcode/gamate/cga2.chr rename to targettest/gamate/cga2.chr diff --git a/testcode/gamate/ctest.c b/targettest/gamate/ctest.c similarity index 100% rename from testcode/gamate/ctest.c rename to targettest/gamate/ctest.c diff --git a/testcode/gamate/lcdtest.s b/targettest/gamate/lcdtest.s similarity index 100% rename from testcode/gamate/lcdtest.s rename to targettest/gamate/lcdtest.s diff --git a/testcode/gamate/nachtm.c b/targettest/gamate/nachtm.c similarity index 100% rename from testcode/gamate/nachtm.c rename to targettest/gamate/nachtm.c diff --git a/testcode/getopt-test.c b/targettest/getopt-test.c similarity index 100% rename from testcode/getopt-test.c rename to targettest/getopt-test.c diff --git a/testcode/getsp.s b/targettest/getsp.s similarity index 100% rename from testcode/getsp.s rename to targettest/getsp.s diff --git a/testcode/heaptest.c b/targettest/heaptest.c similarity index 100% rename from testcode/heaptest.c rename to targettest/heaptest.c diff --git a/testcode/joy-test.c b/targettest/joy-test.c similarity index 100% rename from testcode/joy-test.c rename to targettest/joy-test.c diff --git a/testcode/moddiv-test.c b/targettest/moddiv-test.c similarity index 100% rename from testcode/moddiv-test.c rename to targettest/moddiv-test.c diff --git a/testcode/mouse-test.c b/targettest/mouse-test.c similarity index 100% rename from testcode/mouse-test.c rename to targettest/mouse-test.c diff --git a/testcode/mul-test.c b/targettest/mul-test.c similarity index 100% rename from testcode/mul-test.c rename to targettest/mul-test.c diff --git a/testcode/pce/Makefile b/targettest/pce/Makefile similarity index 100% rename from testcode/pce/Makefile rename to targettest/pce/Makefile diff --git a/testcode/pce/conio.c b/targettest/pce/conio.c similarity index 100% rename from testcode/pce/conio.c rename to targettest/pce/conio.c diff --git a/testcode/posixio-test.c b/targettest/posixio-test.c similarity index 100% rename from testcode/posixio-test.c rename to targettest/posixio-test.c diff --git a/testcode/rename-test.c b/targettest/rename-test.c similarity index 100% rename from testcode/rename-test.c rename to targettest/rename-test.c diff --git a/testcode/scanf-test.c b/targettest/scanf-test.c similarity index 100% rename from testcode/scanf-test.c rename to targettest/scanf-test.c diff --git a/testcode/seek.c b/targettest/seek.c similarity index 100% rename from testcode/seek.c rename to targettest/seek.c diff --git a/testcode/ser-test.c b/targettest/ser-test.c similarity index 100% rename from testcode/ser-test.c rename to targettest/ser-test.c diff --git a/testcode/strdup-test.c b/targettest/strdup-test.c similarity index 100% rename from testcode/strdup-test.c rename to targettest/strdup-test.c diff --git a/testcode/stroserror-test.c b/targettest/stroserror-test.c similarity index 100% rename from testcode/stroserror-test.c rename to targettest/stroserror-test.c diff --git a/testcode/strqtok-test.c b/targettest/strqtok-test.c similarity index 100% rename from testcode/strqtok-test.c rename to targettest/strqtok-test.c diff --git a/testcode/tinyshell.c b/targettest/tinyshell.c similarity index 100% rename from testcode/tinyshell.c rename to targettest/tinyshell.c diff --git a/testcode/uname-test.c b/targettest/uname-test.c similarity index 100% rename from testcode/uname-test.c rename to targettest/uname-test.c From c05a750f470e21558cc0eab561b0017c7456c52d Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 1 Oct 2020 07:25:08 -0400 Subject: [PATCH 1736/2161] Fixed some copy-&-paste typo mistakes about HuC6280's TMA mnemonic. --- src/ca65/instr.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 58011eb8f..d71476799 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -92,7 +92,7 @@ static void PutSEP (const InsDesc* Ins); /* Emit a SEP instruction (65816), track register sizes */ static void PutTAMn (const InsDesc* Ins); -/* Emit a TAMn instruction (HuC6280). Since this is a two byte instruction with +/* Emit a TAMn instruction (HuC6280). Because this is a two-byte instruction with ** implicit addressing mode, the opcode byte in the table is actually the ** second operand byte. The TAM instruction is the more generic form, it takes ** an immediate argument. @@ -104,9 +104,9 @@ static void PutTMA (const InsDesc* Ins); */ static void PutTMAn (const InsDesc* Ins); -/* Emit a TMAn instruction (HuC6280). Since this is a two byte instruction with +/* Emit a TMAn instruction (HuC6280). Because this is a two-byte instruction with ** implicit addressing mode, the opcode byte in the table is actually the -** second operand byte. The TAM instruction is the more generic form, it takes +** second operand byte. The TMA instruction is the more generic form, it takes ** an immediate argument. */ @@ -1093,7 +1093,7 @@ static int EvalEA (const InsDesc* Ins, EffAddr* A) A->AddrModeSet &= Ins->AddrMode; /* If we have an expression, check it and remove any addressing modes that - ** are too small for the expression size. Since we have to study the + ** are too small for the expression size. Because we have to study the ** expression anyway, do also replace it by a simpler one if possible. */ if (A->Expr) { @@ -1414,7 +1414,7 @@ static void PutSEP (const InsDesc* Ins) static void PutTAMn (const InsDesc* Ins) -/* Emit a TAMn instruction (HuC6280). Since this is a two byte instruction with +/* Emit a TAMn instruction (HuC6280). Because this is a two-byte instruction with ** implicit addressing mode, the opcode byte in the table is actually the ** second operand byte. The TAM instruction is the more generic form, it takes ** an immediate argument. @@ -1444,7 +1444,7 @@ static void PutTMA (const InsDesc* Ins) } else { /* Make sure just one bit is set */ if ((Val & (Val - 1)) != 0) { - Error ("Argument to TAM must be a power of two"); + Error ("Argument of TMA must be a power of two"); } } } @@ -1452,9 +1452,9 @@ static void PutTMA (const InsDesc* Ins) static void PutTMAn (const InsDesc* Ins) -/* Emit a TMAn instruction (HuC6280). Since this is a two byte instruction with +/* Emit a TMAn instruction (HuC6280). Because this is a two-byte instruction with ** implicit addressing mode, the opcode byte in the table is actually the -** second operand byte. The TAM instruction is the more generic form, it takes +** second operand byte. The TMA instruction is the more generic form, it takes ** an immediate argument. */ { From 4acdc9ced9ded4c37e46d2bc531bea31894c1ccc Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 3 Oct 2020 14:55:30 +0200 Subject: [PATCH 1737/2161] Fixed paramcount build. --- test/asm/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/asm/Makefile b/test/asm/Makefile index 028254b68..9b0aa582e 100644 --- a/test/asm/Makefile +++ b/test/asm/Makefile @@ -38,7 +38,7 @@ CPUDETECT_REFS := $(wildcard *-cpudetect.ref) CPUDETECT_CPUS = $(foreach ref,$(CPUDETECT_REFS),$(ref:%-cpudetect.ref=%)) CPUDETECT_BINS = $(foreach cpu,$(CPUDETECT_CPUS),$(WORKDIR)/$(cpu)-cpudetect.bin) -all: $(OPCODE_BINS) $(CPUDETECT_BINS) paramcount.o +all: $(OPCODE_BINS) $(CPUDETECT_BINS) $(WORKDIR)/paramcount.o $(WORKDIR): $(call MKDIR,$(WORKDIR)) @@ -70,8 +70,8 @@ endef # CPUDETECT_template $(foreach cpu,$(CPUDETECT_CPUS),$(eval $(call CPUDETECT_template,$(cpu)))) -paramcount.o: paramcount.s - $(CA65) -o $(WORKDIR)/paramcount.o -l $(WORKDIR)/paramcount.lst paramcount.s +$(WORKDIR)/%.o: %.s | $(WORKDIR) + $(CA65) -l $(@:.o=.lst) -o $(WORKDIR)/$@ $< clean: @$(call RMDIR,$(WORKDIR)) From b931e658117189cf62662d4919618bb0ffb00144 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sat, 26 Sep 2020 14:56:28 +0200 Subject: [PATCH 1738/2161] Fix ICE for bit-fields with typedef Fixes #1267 Avoid ICE, but treat plain int bit-fields declared via typedef as signed rather than unsigned. It is more efficient to treat them as unsigned, but this requires distinguishing int from signed int, and this is curently not done. --- src/cc65/declare.c | 9 ++++ test/misc/Makefile | 6 --- test/{misc => val}/bug1094.c | 0 test/val/bug1267.c | 79 ++++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 6 deletions(-) rename test/{misc => val}/bug1094.c (100%) create mode 100644 test/val/bug1267.c diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 8623fa08f..bf27f9c90 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1468,6 +1468,15 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, /* It's a typedef */ NextToken (); TypeCopy (D->Type, Entry->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. + */ + if (SignednessSpecified) { + *SignednessSpecified = 1; + } break; } } else { diff --git a/test/misc/Makefile b/test/misc/Makefile index 06046af3c..b8c578405 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -100,12 +100,6 @@ $(WORKDIR)/bug1263.$1.$2.prg: bug1263.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1263.$1.$2.prg) $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) -# should compile, but gives an error -$(WORKDIR)/bug1094.$1.$2.prg: bug1094.c | $(WORKDIR) - @echo "FIXME: " $$@ "currently does not compile." - $(if $(QUIET),echo misc/bug1094.$1.$2.prg) - $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - # this one requires --std=c89, it fails with --std=c99 # it fails currently at runtime $(WORKDIR)/bug1265.$1.$2.prg: bug1265.c | $(WORKDIR) diff --git a/test/misc/bug1094.c b/test/val/bug1094.c similarity index 100% rename from test/misc/bug1094.c rename to test/val/bug1094.c diff --git a/test/val/bug1267.c b/test/val/bug1267.c new file mode 100644 index 000000000..382903594 --- /dev/null +++ b/test/val/bug1267.c @@ -0,0 +1,79 @@ +/* + Copyright 2020 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. +*/ + +/* + Tests of bit-field signedness with typedefs; see https://github.com/cc65/cc65/issues/1267 +*/ + +#include <stdio.h> + +static unsigned char failures = 0; + +typedef int i16; +typedef unsigned int u16; +typedef signed int s16; + +static struct ints { + i16 i : 4; + u16 u : 4; + s16 s : 4; +} si = {1, 2, 3}; + +static void test_bitfield_typedefs (void) +{ + if (si.i != 1) { + /* Note that this is another bug that i is signed. */ + printf ("Got si.a = %d, expected 1.\n", si.i); + failures++; + } + if (si.u != 2) { + printf ("Got si.u = %u, expected 2.\n", si.u); + failures++; + } + if (si.s != 3) { + printf ("Got si.s = %d, expected 3.\n", si.s); + failures++; + } + + si.i = -1; + si.u = -2; + si.s = -3; + + /* Note that this is another bug that i is signed. */ + if (si.i != -1) { + printf ("Got si.a = %d, expected -1.\n", si.i); + failures++; + } + if (si.u != 14) { + printf ("Got si.u = %u, expected 14.\n", si.u); + failures++; + } + if (si.s != -3) { + printf ("Got si.s = %d, expected -3.\n", si.s); + failures++; + } +} + +int main (void) +{ + test_bitfield_typedefs (); + printf ("failures: %u\n", failures); + return failures; +} From fd208fdf0b6f968ba7491dcec1f53be71af08abd Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 3 Oct 2020 19:35:23 +0200 Subject: [PATCH 1739/2161] - Added support for calling subdir Makefiles for the make targets 'samples' and 'clean'. - Adjusted the 'tutorial' Makefile to actually work as expected. Note: The 'disasm' and 'geos' Makefiles don't seem to work so they are not called as of now. --- samples/Makefile | 13 +++++++++++++ samples/tutorial/Makefile | 14 +++++++------- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index 267dc5235..2d1e25475 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -150,6 +150,11 @@ else $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib endif +# -------------------------------------------------------------------------- +# Lists of subdirectories + +DIRLIST = tutorial + # -------------------------------------------------------------------------- # Lists of executables @@ -209,10 +214,17 @@ ifndef EXELIST_$(SYS) EXELIST_$(SYS) := ${patsubst %.c,%,$(wildcard *.c)} endif +define SUBDIR_recipe + +@$(MAKE) -C $(dir) --no-print-directory $@ + +endef # SUBDIR_recipe + # -------------------------------------------------------------------------- # Rules to make the binaries and the disk samples: $(EXELIST_$(SYS)) + $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) disk: $(DISK_$(SYS)) @@ -338,3 +350,4 @@ mostlyclean: clean: mostlyclean @$(DEL) $(EXELIST_$(SYS)) $(DISK_$(SYS)) 2>$(NULLDEV) @$(DEL) multdemo.? ovrldemo.? 2>$(NULLDEV) + $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) diff --git a/samples/tutorial/Makefile b/samples/tutorial/Makefile index 8ed91697f..2c4bcb988 100644 --- a/samples/tutorial/Makefile +++ b/samples/tutorial/Makefile @@ -25,16 +25,16 @@ ifdef CC65_HOME 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) + 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 -all: hello +samples: hello hello: hello.c text.s $(CL) -t $(SYS) -o hello hello.c text.s - + clean: - $(RM) hello + @$(DEL) hello 2>$(NULLDEV) From a85d5330fab3ffd8053f6d6f54b46da18de766f8 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 4 Oct 2020 12:15:59 +0800 Subject: [PATCH 1740/2161] Fixed StrBuf initialization in PreparseArg(). --- src/cc65/codeent.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index f3a910652..dd2000db0 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -585,8 +585,7 @@ const char* MakeHexArg (unsigned Num) void PreparseArg (CodeEntry* E) /* Parse the argument string and memorize the result for the code entry */ { - StrBuf B; - SB_InitFromString (&B, xmalloc (strlen (E->Arg) + 1)); + StrBuf B = AUTO_STRBUF_INITIALIZER; /* Parse the argument string */ if (ParseOpcArgStr (E->Arg, &E->ArgInfo, &B, &E->ArgOff)) { From dbba5f3fc9ec1256b7226f458531b81bac25e983 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 4 Oct 2020 17:01:20 +0800 Subject: [PATCH 1741/2161] Fixed handling of %v in inline asm parser. --- src/cc65/asmstmt.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/cc65/asmstmt.c b/src/cc65/asmstmt.c index bf5a0815b..d182140fd 100644 --- a/src/cc65/asmstmt.c +++ b/src/cc65/asmstmt.c @@ -213,7 +213,9 @@ static void ParseLongArg (StrBuf* T, unsigned Arg attribute ((unused))) static void ParseGVarArg (StrBuf* T, unsigned Arg) -/* Parse the %v format specifier */ +/* Parse the %v format specifier. +** ### FIXME: Asm names should be generated in the same place. +*/ { /* Parse the symbol name parameter and check the type */ SymEntry* Sym = AsmGetSym (Arg, SC_STATIC); @@ -225,7 +227,6 @@ static void ParseGVarArg (StrBuf* T, unsigned Arg) /* Check for external linkage */ if (Sym->Flags & (SC_EXTERN | SC_STORAGE | SC_FUNC)) { /* External linkage or a function */ - /* ### FIXME: Asm name should be generated by codegen */ SB_AppendChar (T, '_'); SB_AppendStr (T, Sym->Name); } else if (Sym->Flags & SC_REGISTER) { @@ -234,9 +235,7 @@ static void ParseGVarArg (StrBuf* T, unsigned Arg) SB_AppendStr (T, Buf); } else { /* Static variable */ - char Buf [16]; - xsprintf (Buf, sizeof (Buf), "L%04X", Sym->V.L.Label); - SB_AppendStr (T, Buf); + SB_AppendStr (T, LocalDataLabelName (Sym->V.L.Label)); } } From 037a806036a1af63e5e6f0d2752f507ae2c4d235 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 4 Oct 2020 17:20:40 +0200 Subject: [PATCH 1742/2161] also rename README to readme.txt in the Makefile :) --- samples/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Makefile b/samples/Makefile index 2d1e25475..c9d205bf1 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -330,7 +330,7 @@ install: $(INSTALL) -d $(DESTDIR)$(samplesdir)/geos $(INSTALL) -d $(DESTDIR)$(samplesdir)/tutorial $(INSTALL) -m0644 *.* $(DESTDIR)$(samplesdir) - $(INSTALL) -m0644 README $(DESTDIR)$(samplesdir) + $(INSTALL) -m0644 readme.txt $(DESTDIR)$(samplesdir) $(INSTALL) -m0644 Makefile $(DESTDIR)$(samplesdir) $(INSTALL) -m0644 geos/*.* $(DESTDIR)$(samplesdir)/geos $(INSTALL) -m0644 tutorial/*.* $(DESTDIR)$(samplesdir)/tutorial From 81550ca1ee6b7520539c047b5aaeea5a86118df4 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Mon, 24 Aug 2020 22:24:00 +0200 Subject: [PATCH 1743/2161] CS_MergeLabels: Keep labels referenced by data Partial fix for ICE in #1211. This may fix enough to allow #1049 to be fixed. When merging labels, keep the first label with a ref that has no JumpTo; this is a data segment label, used by computed gotos. The real fix is to track and rewrite labels in data, but this is more involved. --- src/cc65/codeent.h | 10 ++++++ src/cc65/codeseg.c | 37 +++++++++++++++++++-- test/{err => val}/bug1211-ice-move-refs-1.c | 3 +- 3 files changed, 47 insertions(+), 3 deletions(-) rename test/{err => val}/bug1211-ice-move-refs-1.c (91%) diff --git a/src/cc65/codeent.h b/src/cc65/codeent.h index 173118a7f..bd542cc4c 100644 --- a/src/cc65/codeent.h +++ b/src/cc65/codeent.h @@ -180,6 +180,16 @@ INLINE CodeLabel* CE_GetLabel (CodeEntry* E, unsigned Index) # define CE_GetLabel(E, Index) CollAt (&(E)->Labels, (Index)) #endif +#if defined(HAVE_INLINE) +INLINE void CE_ReplaceLabel (CodeEntry* E, CodeLabel* L, unsigned Index) +/* Replace the code label at the specified index with L */ +{ + return CollReplace (&E->Labels, L, Index); +} +#else +# define CE_ReplaceLabel(E, L, Index) CollReplace (&(E)->Labels, (L), (Index)) +#endif + void CE_MoveLabel (CodeLabel* L, CodeEntry* E); /* Move the code label L from it's former owner to the code entry E. */ diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index ad8a3148c..8177d4fd4 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -183,6 +183,37 @@ static void CS_RemoveLabelFromHash (CodeSeg* S, CodeLabel* L) +static CodeLabel* PickRefLab (CodeEntry* E) +/* Pick a reference label and move it to index 0 in E. */ +{ + unsigned I; + unsigned LabelCount = CE_GetLabelCount (E); + CHECK (LabelCount > 0); + /* Use either the first one as reference label, or a label with a Ref that has no JumpTo. + ** This is a hack to partially work around #1211. Refs with no JumpTo are labels used + ** in data segments. (They are not tracked.) If a data segment is the only reference, + ** the label will be pruned away, but the data reference will remain, causing linking to fail. + */ + CodeLabel* L0 = CE_GetLabel (E, 0); + for (I = 1; I < LabelCount; ++I) { + unsigned J; + CodeLabel* L = CE_GetLabel (E, I); + unsigned RefCount = CL_GetRefCount (L); + for (J = 0; J < RefCount; ++J) { + CodeEntry* EJ = CL_GetRef (L, J); + if (EJ->JumpTo == NULL) { + /* Move it to the beginning since it's simpler to handle the removal this way. */ + CE_ReplaceLabel (E, L, 0); + CE_ReplaceLabel (E, L0, I); + return L; + } + } + } + return L0; +} + + + /*****************************************************************************/ /* Functions for parsing instructions */ /*****************************************************************************/ @@ -935,8 +966,10 @@ void CS_MergeLabels (CodeSeg* S) continue; } - /* We have at least one label. Use the first one as reference label. */ - RefLab = CE_GetLabel (E, 0); + /* Pick a label to keep, all references will be moved to this one, and the other labels + ** will be deleted. PickRefLab moves this to index 0. + */ + RefLab = PickRefLab (E); /* Walk through the remaining labels and change references to these ** labels to a reference to the one and only label. Delete the labels diff --git a/test/err/bug1211-ice-move-refs-1.c b/test/val/bug1211-ice-move-refs-1.c similarity index 91% rename from test/err/bug1211-ice-move-refs-1.c rename to test/val/bug1211-ice-move-refs-1.c index f28d1fcbc..9be1696ee 100644 --- a/test/err/bug1211-ice-move-refs-1.c +++ b/test/val/bug1211-ice-move-refs-1.c @@ -21,7 +21,8 @@ /* Test of indirect goto with label merge ICE. https://github.com/cc65/cc65/issues/1211 - This should compile and should be moved to tests/val/ when the bug is fixed. + This test case works because CS_MergeLabels has a hack to keep the "unreferenced" label + (i.e. the one referenced in a data segment). */ #include <stdio.h> From f8c9dde989e501d11ebef2ec4befbe2857371e1f Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 21 Jan 2020 10:39:19 +0800 Subject: [PATCH 1744/2161] The instruction parser can now recognize ZP locations and set the addressing mode for them. --- src/cc65/codeinfo.c | 111 +++++++++++++++++++++++++++++++++++++------- src/cc65/codeinfo.h | 6 ++- src/cc65/codeseg.c | 7 ++- src/cc65/opcodes.c | 1 + 4 files changed, 105 insertions(+), 20 deletions(-) diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 892f4cd5f..e0cda84e9 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -349,23 +349,23 @@ static const FuncInfo FuncInfoTable[] = { /* Table with names of zero page locations used by the compiler */ static const ZPInfo ZPInfoTable[] = { - { 0, "ptr1", REG_PTR1_LO, REG_PTR1 }, - { 0, "ptr1+1", REG_PTR1_HI, REG_PTR1 }, - { 0, "ptr2", REG_PTR2_LO, REG_PTR2 }, - { 0, "ptr2+1", REG_PTR2_HI, REG_PTR2 }, - { 4, "ptr3", REG_NONE, REG_NONE }, - { 4, "ptr4", REG_NONE, REG_NONE }, - { 7, "regbank", REG_NONE, REG_NONE }, - { 0, "regsave", REG_SAVE_LO, REG_SAVE }, - { 0, "regsave+1", REG_SAVE_HI, REG_SAVE }, - { 0, "sp", REG_SP_LO, REG_SP }, - { 0, "sp+1", REG_SP_HI, REG_SP }, - { 0, "sreg", REG_SREG_LO, REG_SREG }, - { 0, "sreg+1", REG_SREG_HI, REG_SREG }, - { 0, "tmp1", REG_TMP1, REG_TMP1 }, - { 0, "tmp2", REG_NONE, REG_NONE }, - { 0, "tmp3", REG_NONE, REG_NONE }, - { 0, "tmp4", REG_NONE, REG_NONE }, + { 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 }, + { 0, "ptr2+1", 1, REG_PTR2_HI, REG_PTR2 }, + { 4, "ptr3", 2, REG_NONE, REG_NONE }, + { 4, "ptr4", 2, REG_NONE, REG_NONE }, + { 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 }, + { 0, "tmp2", 1, REG_NONE, REG_NONE }, + { 0, "tmp3", 1, REG_NONE, REG_NONE }, + { 0, "tmp4", 1, REG_NONE, REG_NONE }, }; #define ZPInfoCount (sizeof(ZPInfoTable) / sizeof(ZPInfoTable[0])) @@ -377,6 +377,83 @@ static const ZPInfo ZPInfoTable[] = { +static int IsAddrOnZP (long Address) +/* Return true if the Address is within the ZP range. +** FIXME: ZP range may vary depending on the CPU settings. +*/ +{ + /* ZP in range [0x00, 0xFF] */ + return Address >= 0 && Address < 0x100; +} + + + +int IsZPArg (const char* Name) +/* Exam if the main part of the arg string indicates a ZP loc */ +{ + unsigned short ArgInfo = 0; + long Offset = 0; + StrBuf NameBuf = AUTO_STRBUF_INITIALIZER; + SymEntry* E = 0; + const ZPInfo* Info = 0; + + if (!ParseOpcArgStr (Name, &ArgInfo, &NameBuf, &Offset)) { + /* Parsing failed */ + SB_Done (&NameBuf); + return 0; + } + + if ((ArgInfo & AIF_HAS_NAME) == 0) { + /* Numeric locs have no names */ + SB_Done (&NameBuf); + + /* We can check it against the ZP boundary if it is known */ + return IsAddrOnZP (Offset); + } + + if ((ArgInfo & AIF_BUILTIN) != 0) { + /* Search for the name in the list of builtin ZPs */ + Info = GetZPInfo (SB_GetConstBuf (&NameBuf)); + + SB_Done (&NameBuf); + + /* Do we know the ZP? */ + if (Info != 0) { + /* Use the information we have */ + return Offset >= 0 && Offset < (int)Info->Size; + } + + /* Assume it be non-ZP */ + return 0; + } + + if ((ArgInfo & AIF_EXTERNAL) == 0) { + /* We don't support local variables on ZP */ + SB_Done (&NameBuf); + return 0; + } + + /* Search for the symbol in the global symbol table skipping the underline + ** in its name. + */ + E = FindGlobalSym (SB_GetConstBuf (&NameBuf) + 1); + + SB_Done (&NameBuf); + + /* We are checking the offset against the symbol size rather than the actual + ** zeropage boundary, since we can't magically ensure that until linking and + ** can only trust the user in writing the correct code for now. + */ + if (E != 0 && (E->Flags & SC_ZEROPAGE) != 0) { + return Offset >= 0 && (unsigned)Offset < CheckedSizeOf (E->Type); + } + + /* Not found on ZP */ + return 0; +} + + + static int CompareFuncInfo (const void* Key, const void* Info) /* Compare function for bsearch */ { diff --git a/src/cc65/codeinfo.h b/src/cc65/codeinfo.h index 32bc5dd9c..88e26cdf4 100644 --- a/src/cc65/codeinfo.h +++ b/src/cc65/codeinfo.h @@ -119,7 +119,8 @@ struct RegContents; typedef struct ZPInfo ZPInfo; struct ZPInfo { unsigned char Len; /* Length of the following string */ - char Name[11]; /* Name of zero page symbol */ + char Name[10]; /* 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 */ }; @@ -162,6 +163,9 @@ typedef enum { +int IsZPArg (const char* Arg); +/* Exam if the main part of the arg string indicates a ZP loc */ + fncls_t GetFuncInfo (const char* Name, unsigned int* Use, unsigned int* Chg); /* For the given function, lookup register information and store it into ** the given variables. If the function is unknown, assume it will use and diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 8177d4fd4..0626f3d18 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -403,7 +403,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) if ((OPC->Info & OF_BRA) != 0) { /* Branch */ AM = AM65_BRA; - } else if (GetZPInfo(Arg) != 0) { + } else if (IsZPArg (Arg)) { AM = AM65_ZP; } else { /* Check for subroutine call to local label */ @@ -424,12 +424,15 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) Reg = toupper (*L); L = SkipSpace (L+1); if (Reg == 'X') { - if (GetZPInfo(Arg) != 0) { + if (IsZPArg (Arg)) { AM = AM65_ZPX; } else { AM = AM65_ABSX; } } else if (Reg == 'Y') { + /* On 6502 only LDX and STX support AM65_ZPY. + ** We just play it simple and safe for now. + */ AM = AM65_ABSY; } else { Error ("ASM code error: syntax error"); diff --git a/src/cc65/opcodes.c b/src/cc65/opcodes.c index 3c02c84c4..86b904df9 100644 --- a/src/cc65/opcodes.c +++ b/src/cc65/opcodes.c @@ -649,6 +649,7 @@ unsigned GetInsnSize (opc_t OPC, am_t AM) case AM65_IMM: return 2; case AM65_ZP: return 2; case AM65_ZPX: return 2; + case AM65_ZPY: return 2; case AM65_ABS: return 3; case AM65_ABSX: return 3; case AM65_ABSY: return 3; From e58c84acf7958c7e21879fea9daceef423da2e6e Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 21 Jan 2020 10:39:19 +0800 Subject: [PATCH 1745/2161] Support for optionally specifying address size for segments with: #pragma ***-name([push,] "name"[, "addrsize"]) where "addrsize" is any addressing size supported in ca65. --- src/cc65/codegen.c | 12 +++++- src/cc65/main.c | 6 +++ src/cc65/pragma.c | 30 ++++++++++++++- src/cc65/segments.c | 90 +++++++++++++++++++++++++++++++++++++++++++++ src/cc65/segments.h | 13 +++++++ 5 files changed, 148 insertions(+), 3 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index bc85ba1de..539309283 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -39,6 +39,7 @@ #include <stdarg.h> /* common */ +#include "addrsize.h" #include "check.h" #include "cpu.h" #include "inttypes.h" @@ -260,6 +261,9 @@ void g_usebss (void) void g_segname (segment_t Seg) /* Emit the name of a segment if necessary */ { + unsigned char AddrSize; + const char* Name; + /* Emit a segment directive for the data style segments */ DataSeg* S; switch (Seg) { @@ -269,7 +273,13 @@ void g_segname (segment_t Seg) default: S = 0; break; } if (S) { - DS_AddLine (S, ".segment\t\"%s\"", GetSegName (Seg)); + Name = GetSegName (Seg); + AddrSize = GetSegAddrSize (Name); + if (AddrSize != ADDR_SIZE_INVALID) { + DS_AddLine (S, ".segment\t\"%s\": %s", Name, AddrSizeToStr (AddrSize)); + } else { + DS_AddLine (S, ".segment\t\"%s\"", Name); + } } } diff --git a/src/cc65/main.c b/src/cc65/main.c index 26dd721be..fabd71ef7 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -897,6 +897,9 @@ int main (int argc, char* argv[]) /* Initialize the default segment names */ InitSegNames (); + /* Initialize the segment address sizes table */ + InitSegAddrSizes (); + /* Initialize the include search paths */ InitIncludePaths (); @@ -1089,6 +1092,9 @@ int main (int argc, char* argv[]) /* Done with tracked string buffer allocation */ DoneDiagnosticStrBufs (); + /* Free up the segment address sizes table */ + DoneSegAddrSizes (); + /* Return an apropriate exit code */ return (ErrorCount > 0)? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index c614bbfdd..cf463a832 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -37,6 +37,7 @@ #include <string.h> /* common */ +#include "addrsize.h" #include "chartype.h" #include "segnames.h" #include "tgttrans.h" @@ -389,7 +390,9 @@ static void SegNamePragma (StrBuf* B, segment_t Seg) /* Handle a pragma that expects a segment name parameter */ { const char* Name; + unsigned char AddrSize = ADDR_SIZE_INVALID; StrBuf S = AUTO_STRBUF_INITIALIZER; + StrBuf A = AUTO_STRBUF_INITIALIZER; int Push = 0; /* Check for the "push" or "pop" keywords */ @@ -430,13 +433,35 @@ static void SegNamePragma (StrBuf* B, segment_t Seg) goto ExitPoint; } - /* Get the string */ + /* Get the name string of the segment */ Name = SB_GetConstBuf (&S); /* Check if the name is valid */ if (ValidSegName (Name)) { - /* Set the new name */ + /* Skip the following comma */ + SB_SkipWhite (B); + if (SB_Peek (B) == ',') { + SB_Skip (B); + SB_SkipWhite (B); + + /* A string argument must follow */ + if (!GetString (B, &A)) { + goto ExitPoint; + } + + /* Get the address size for the segment */ + AddrSize = AddrSizeFromStr (SB_GetConstBuf (&A)); + + /* Set the address size for the segment if valid */ + if (AddrSize != ADDR_SIZE_INVALID) { + SetSegAddrSize (Name, AddrSize); + } else { + Warning ("Invalid address size for segment!"); + } + } + + /* Set the new name and optionally address size */ if (Push) { PushSegName (Seg, Name); } else { @@ -460,6 +485,7 @@ static void SegNamePragma (StrBuf* B, segment_t Seg) ExitPoint: /* Call the string buf destructor */ SB_Done (&S); + SB_Done (&A); } diff --git a/src/cc65/segments.c b/src/cc65/segments.c index 7a9e32eb8..8283b9da5 100644 --- a/src/cc65/segments.c +++ b/src/cc65/segments.c @@ -37,6 +37,7 @@ #include <string.h> /* common */ +#include "addrsize.h" #include "chartype.h" #include "check.h" #include "coll.h" @@ -61,6 +62,13 @@ +/* Table struct for address sizes of segments */ +typedef struct { + StrBuf Name; + unsigned char AddrSize; +} SegAddrSize_t; + + /* Pointer to the current segment list. Output goes here. */ Segments* CS = 0; @@ -70,6 +78,9 @@ Segments* GS = 0; /* Actual names for the segments */ static StrStack SegmentNames[SEG_COUNT]; +/* Address size for the segments */ +static Collection SegmentAddrSizes; + /* We're using a collection for the stack instead of a linked list. Since ** functions may not be nested (at least in the current implementation), the ** maximum stack depth is 2, so there is not really a need for a better @@ -85,6 +96,85 @@ static Collection SegmentStack = STATIC_COLLECTION_INITIALIZER; +void InitSegAddrSizes (void) +/* Initialize the segment address sizes */ +{ + InitCollection (&SegmentAddrSizes); +} + + + +void DoneSegAddrSizes (void) +/* Free the segment address sizes */ +{ + SegAddrSize_t* A; + int I; + for (I = 0; I < (int)CollCount (&SegmentAddrSizes); ++I) { + A = CollAtUnchecked (&SegmentAddrSizes, I); + SB_Done (&A->Name); + xfree (A); + } + DoneCollection (&SegmentAddrSizes); +} + + + +static SegAddrSize_t* FindSegAddrSize (const char* Name) +/* Find already specified address size for a segment by name. +** Return the found struct or 0 if not found. +*/ +{ + SegAddrSize_t* A; + int I; + for (I = 0; I < (int)CollCount (&SegmentAddrSizes); ++I) { + A = CollAtUnchecked (&SegmentAddrSizes, I); + if (A && strcmp (SB_GetConstBuf (&A->Name), Name) == 0) { + return A; + } + } + return 0; +} + + + +void SetSegAddrSize (const char* Name, unsigned char AddrSize) +/* Set the address size for a segment */ +{ + SegAddrSize_t* A = FindSegAddrSize (Name); + if (!A) { + /* New one */ + A = xmalloc (sizeof (SegAddrSize_t)); + SB_Init (&A->Name); + SB_CopyStr (&A->Name, Name); + SB_Terminate (&A->Name); + CollAppend (&SegmentAddrSizes, A); + } else { + /* Check for mismatching address sizes */ + if (A->AddrSize != AddrSize) { + Warning ("Segment address size changed from last time!"); + } + } + + /* Set the address size anyway */ + A->AddrSize = AddrSize; +} + + + +unsigned char GetSegAddrSize (const char* Name) +/* Get the address size of the given segment. +** Return ADDR_SIZE_INVALID if not found. +*/ +{ + SegAddrSize_t* A = FindSegAddrSize (Name); + if (A) { + return A->AddrSize; + } + return ADDR_SIZE_INVALID; +} + + + void InitSegNames (void) /* Initialize the segment names */ { diff --git a/src/cc65/segments.h b/src/cc65/segments.h index 777073559..91d702df6 100644 --- a/src/cc65/segments.h +++ b/src/cc65/segments.h @@ -103,6 +103,19 @@ extern Segments* GS; /*****************************************************************************/ +void InitSegAddrSizes (void); +/* Initialize the segment address sizes */ + +void DoneSegAddrSizes (void); +/* Free the segment address sizes */ + +void SetSegAddrSize (const char* Name, unsigned char AddrSize); +/* Set the address size for a segment */ + +unsigned char GetSegAddrSize (const char* Name); +/* Get the address size of the given segment. +** Return ADDR_SIZE_INVALID if not found. +*/ void InitSegNames (void); /* Initialize the segment names */ From 262c4235dfd41eead0e5702c0510b7ed72fc6962 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 21 Jan 2020 10:50:12 +0800 Subject: [PATCH 1746/2161] Symbols in ZP segments will use '.exportzp' instead of '.export' if exported. --- src/cc65/compile.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 00e78c2bd..ec90e4b2d 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -37,6 +37,7 @@ #include <time.h> /* common */ +#include "addrsize.h" #include "debugflag.h" #include "segnames.h" #include "version.h" @@ -275,6 +276,17 @@ static void Parse (void) } Entry->V.BssName = xstrdup (bssName); + /* This is to make the automatical zeropage setting of the symbol + ** work right. + */ + g_usebss (); + } + } + + /* Make the symbol zeropage according to the segment address size */ + if ((Entry->Flags & SC_EXTERN) != 0) { + if (GetSegAddrSize (GetSegName (CS->CurDSeg)) == ADDR_SIZE_ZP) { + Entry->Flags |= SC_ZEROPAGE; /* Check for enum forward declaration. ** Warn about it when extensions are not allowed. */ From 4905329ff6b934a3e14415f35ecf3d7c4b6fdd8b Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 12 Oct 2020 08:33:45 -0400 Subject: [PATCH 1747/2161] Fixed the misspelling of "height" in a GEOS header. --- include/geos/gstruct.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/geos/gstruct.h b/include/geos/gstruct.h index 9e5f0ddda..6d9cb1f14 100644 --- a/include/geos/gstruct.h +++ b/include/geos/gstruct.h @@ -126,8 +126,8 @@ struct VLIR_info { /* VLIR information */ }; struct process { /* process info, declare table of that type */ - unsigned pointer; /* (like: struct process proctab[2]=... */ - unsigned jiffies; /* last entry HAVE TO BE {0,0} */ + unsigned pointer; /* (like: struct process proctab[2]= ... */ + unsigned jiffies; /* last entry MUST BE {0,0} */ }; struct iconpic { /* icon/encoded bitmap description */ @@ -135,7 +135,7 @@ struct iconpic { /* icon/encoded bitmap description */ char x; /* position in cards (*8 pixels) */ char y; char width; /* in cards */ - char heigth; /* in lines (pixels) */ + char height; /* in lines (pixels) */ }; struct icondef { /* icon definition for DoIcons */ @@ -143,7 +143,7 @@ struct icondef { /* icon definition for DoIcons */ char x; /* position in cards (*8 pixels) */ char y; char width; /* of icon (in cards) */ - char heigth; /* of icon in lines (pixels) */ + char height; /* of icon in lines (pixels) */ unsigned proc_ptr; /* pointer to function handling that icon */ }; From e72e44d14fa713eef4238f9ad1066c6c9d890a78 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 13 Oct 2020 07:55:20 -0400 Subject: [PATCH 1748/2161] Shortenned the VIC-20's cputc() by 17 bytes. Changed to a modified table look-up method to convert PetSCII to screen-codes. --- libsrc/vic20/cputc.s | 81 ++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/libsrc/vic20/cputc.s b/libsrc/vic20/cputc.s index 9e818032e..a6919ceaf 100644 --- a/libsrc/vic20/cputc.s +++ b/libsrc/vic20/cputc.s @@ -1,5 +1,6 @@ ; -; Ullrich von Bassewitz, 06.08.1998 +; 1998-08-06, Ullrich von Bassewitz +; 2020-10-09, Greg King ; ; void cputcxy (unsigned char x, unsigned char y, char c); ; void cputc (char c); @@ -39,69 +40,64 @@ _cputcxy: jsr gotoxy ; Set cursor, drop x and y pla ; Restore C -; Plot a character - also used as internal function +; Plot a character -- also used as an internal function -_cputc: cmp #$0A ; CR? - bne L1 - lda #0 - sta CURS_X - beq plot ; Recalculate pointers - -L1: cmp #$0D ; LF? +_cputc: cmp #$0D ; Is it CBM '\n'? beq newline ; Recalculate pointers + cmp #$0A ; Is it CBM '\r'? + beq cr -; Printable char of some sort +; Printable char. of some sort +; Convert it from PetSCII into a screen-code - cmp #' ' - bcc cputdirect ; Other control char + cmp #$FF ; BASIC token? + bne convert + lda #$DE ; Pi symbol +convert: tay - bmi L10 - cmp #$60 - bcc L2 - and #$DF - bne cputdirect ; Branch always -L2: and #$3F + lsr a ; Divide by 256/8 + lsr a + lsr a + lsr a + lsr a + tax ; .X = %00000xxx + tya + eor pet_to_screen,x cputdirect: jsr putchar ; Write the character to the screen -; Advance cursor position +; Advance the cursor position advance: iny cpy #XSIZE bne L3 - jsr newline ; new line - ldy #0 ; + cr + jsr newline ; Wrap around + +cr: ldy #$00 ; Do carriage-return L3: sty CURS_X rts + +; Move down by one full screen-line. Note: this routine doesn't scroll. +; +; (Both screen RAM and color RAM are aligned to page boundaries. +; Therefore, the lower bytes of their addresses have the same values. +; Shorten the code by taking advantage of that fact.) + 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 SCREEN_PTR+1 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 @@ -111,14 +107,19 @@ plot: ldy CURS_X jmp PLOT ; Set the new cursor - -; Write one character to the screen without doing anything else, return X -; position in Y +; Write one character to the screen without doing anything else, +; return the X position in .Y putchar: ora RVS ; Set revers bit ldy CURS_X - sta (SCREEN_PTR),y ; Set char + sta (SCREEN_PTR),y ; Set char. lda CHARCOLOR sta (CRAM_PTR),y ; Set color rts + + + .rodata +pet_to_screen: + .byte %10000000,%00000000,%01000000,%00100000 ; PetSCII -> screen-code + .byte %01000000,%11000000,%10000000,%10000000 From 095de4ea52c2b488182645fda8ae0b4f7ac5e1c8 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 15 Oct 2020 12:54:01 +0200 Subject: [PATCH 1749/2161] Write o65 files as SEQ files. --- samples/Makefile | 18 ++++++++++++------ targettest/Makefile | 16 +++++++++++----- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index c9d205bf1..e66850d35 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -260,17 +260,23 @@ endif # Rule to make a CBM disk with all samples. Needs the c1541 program that comes # with the VICE emulator. -define D64_WRITE_recipe +define D64_WRITE_PRG_recipe -$(C1541) -attach $@ -write "$(subst ?,$(SPACE),$(file))" $(notdir $(file)) >$(NULLDEV) +$(C1541) -attach $@ -write "$(subst ?,$(SPACE),$(file))" $(notdir $(file)),p >$(NULLDEV) -endef # D64_WRITE_recipe +endef # D64_WRITE_PRG_recipe + +define D64_WRITE_SEQ_recipe + +$(C1541) -attach $@ -write "$(subst ?,$(SPACE),$(file))" $(notdir $(file)),s >$(NULLDEV) + +endef # D64_WRITE_SEQ_recipe samples.d64: samples @$(C1541) -format samples,AA d64 $@ >$(NULLDEV) - $(foreach file,$(EXELIST_$(SYS)),$(D64_WRITE_recipe)) - $(foreach file,$(OVERLAYLIST),$(D64_WRITE_recipe)) - $(foreach file,$(EMD) $(MOU) $(TGI),$(D64_WRITE_recipe)) + $(foreach file,$(EXELIST_$(SYS)),$(D64_WRITE_PRG_recipe)) + $(foreach file,$(OVERLAYLIST),$(D64_WRITE_PRG_recipe)) + $(foreach file,$(EMD) $(MOU) $(TGI),$(D64_WRITE_SEQ_recipe)) # -------------------------------------------------------------------------- # Rule to make an Apple II disk with all samples. Needs the AppleCommander diff --git a/targettest/Makefile b/targettest/Makefile index 33f725f6a..f3694335c 100644 --- a/targettest/Makefile +++ b/targettest/Makefile @@ -321,16 +321,22 @@ endif # Rule to make a CBM disk with all testcode. Needs the c1541 program that comes # with the VICE emulator. -define D64_WRITE_recipe +define D64_WRITE_PRG_recipe -$(C1541) -attach $@ -write "$(subst ?,$(SPACE),$(file))" $(notdir $(file)) >$(NULLDEV) +$(C1541) -attach $@ -write "$(subst ?,$(SPACE),$(file))" $(notdir $(file)),p >$(NULLDEV) -endef # D64_WRITE_recipe +endef # D64_WRITE_PRG_recipe + +define D64_WRITE_SEQ_recipe + +$(C1541) -attach $@ -write "$(subst ?,$(SPACE),$(file))" $(notdir $(file)),s >$(NULLDEV) + +endef # D64_WRITE_SEQ_recipe testcode.d64: testcode @$(C1541) -format testcode,AA d64 $@ >$(NULLDEV) - $(foreach file,$(EXELIST_$(SYS)),$(D64_WRITE_recipe)) -# $(foreach file,$(EMD) $(MOU) $(TGI),$(D64_WRITE_recipe)) + $(foreach file,$(EXELIST_$(SYS)),$(D64_WRITE_PRG_recipe)) +# $(foreach file,$(EMD) $(MOU) $(TGI),$(D64_WRITE_SEQ_recipe)) # -------------------------------------------------------------------------- # Rule to make an Apple II disk with all testcode. Needs the AppleCommander From f60af0301afed94a61036c5500934a2f5b977152 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 15 Oct 2020 18:35:54 +0200 Subject: [PATCH 1750/2161] fix non working Makefiles --- samples/Makefile | 3 ++- samples/disasm/Makefile | 12 ++++++------ samples/geos/Makefile | 12 ++++++------ samples/geos/grc/Makefile | 12 +++++++++++- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index e66850d35..6e89cb802 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -153,7 +153,8 @@ endif # -------------------------------------------------------------------------- # Lists of subdirectories -DIRLIST = tutorial +# disasm depends on cpp +DIRLIST = tutorial geos # -------------------------------------------------------------------------- # Lists of executables diff --git a/samples/disasm/Makefile b/samples/disasm/Makefile index 61b37e314..5f19e943d 100644 --- a/samples/disasm/Makefile +++ b/samples/disasm/Makefile @@ -24,11 +24,11 @@ ifdef CC65_HOME LD = $(CC65_HOME)/bin/ld65 DA = $(CC65_HOME)/bin/da65 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) - DA := $(if $(wildcard ../../../bin/da65*),../../../bin/da65,da65) + 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) + DA := $(if $(wildcard ../../bin/da65*),../../bin/da65,da65) endif CPP = cpp @@ -39,7 +39,7 @@ DAIS = fixed.dai bank0.dai bank1.dai .SUFFIXES: .da .dai .s -all: image.bin $(ASMS) +samples: image.bin $(ASMS) $(DAIS): fixed.da diff --git a/samples/geos/Makefile b/samples/geos/Makefile index 32a28e118..cc0d52a4e 100644 --- a/samples/geos/Makefile +++ b/samples/geos/Makefile @@ -26,17 +26,17 @@ ifdef CC65_HOME LD = $(CC65_HOME)/bin/ld65 SP = $(CC65_HOME)/bin/sp65 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) - SP := $(if $(wildcard ../bin/sp65*),../bin/sp65,sp65) + 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) + SP := $(if $(wildcard ../../bin/sp65*),../../bin/sp65,sp65) endif # omitted: dialog.c grphstr.c inittab.c menu.c # TODO: geosconio.cvt rmvprot.cvt -all: bitmap-demo.cvt filesel.cvt geosver.cvt getid.cvt hello1.cvt hello2.cvt \ +samples: bitmap-demo.cvt filesel.cvt geosver.cvt getid.cvt hello1.cvt hello2.cvt \ overlay-demo.cvt vector-demo.cvt yesno.cvt bitmap.c: logo.pcx diff --git a/samples/geos/grc/Makefile b/samples/geos/grc/Makefile index 793506890..0e5eabd81 100644 --- a/samples/geos/grc/Makefile +++ b/samples/geos/grc/Makefile @@ -29,7 +29,16 @@ else GRC := $(if $(wildcard ../../../bin/grc65*),../../../bin/grc65,grc65) endif -all: test.s vlir.cvt +DIRLIST = grc + +define SUBDIR_recipe + +@$(MAKE) -C $(dir) --no-print-directory $@ + +endef # SUBDIR_recipe + +samples: test.s vlir.cvt + $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) test.s: test.grc $(GRC) -s test.s test.grc @@ -50,3 +59,4 @@ clean: $(RM) test.s test.h $(RM) vlir.s vlir.cvt vlir.c vlir.h $(RM) *.o + $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) From a0dc7cd9e471be3864cddc67ea1d7e13f073065a Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 15 Oct 2020 18:41:17 +0200 Subject: [PATCH 1751/2161] fix grc example, fix makefiles to compile grc example correctly --- samples/geos/Makefile | 11 +++++++++++ samples/geos/grc/Makefile | 10 ---------- samples/geos/grc/vlir0.s | 8 ++++---- samples/geos/grc/vlir1.s | 8 ++++---- samples/geos/grc/vlir2.s | 8 ++++---- 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/samples/geos/Makefile b/samples/geos/Makefile index cc0d52a4e..cbc1e9885 100644 --- a/samples/geos/Makefile +++ b/samples/geos/Makefile @@ -33,11 +33,20 @@ else SP := $(if $(wildcard ../../bin/sp65*),../../bin/sp65,sp65) endif +DIRLIST = grc + +define SUBDIR_recipe + +@$(MAKE) -C $(dir) --no-print-directory $@ + +endef # SUBDIR_recipe + # omitted: dialog.c grphstr.c inittab.c menu.c # TODO: geosconio.cvt rmvprot.cvt samples: bitmap-demo.cvt filesel.cvt geosver.cvt getid.cvt hello1.cvt hello2.cvt \ overlay-demo.cvt vector-demo.cvt yesno.cvt + $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) bitmap.c: logo.pcx $(SP) -r logo.pcx -c geos-bitmap -w bitmap.c,ident=bitmap @@ -77,6 +86,8 @@ yesno.cvt: yesnores.grc yesno.c clean: + $(RM) overlay-demores.h $(RM) bitmap.c $(RM) *.cvt $(RM) *.map + $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) diff --git a/samples/geos/grc/Makefile b/samples/geos/grc/Makefile index 0e5eabd81..4dbe51d10 100644 --- a/samples/geos/grc/Makefile +++ b/samples/geos/grc/Makefile @@ -29,16 +29,7 @@ else GRC := $(if $(wildcard ../../../bin/grc65*),../../../bin/grc65,grc65) endif -DIRLIST = grc - -define SUBDIR_recipe - -@$(MAKE) -C $(dir) --no-print-directory $@ - -endef # SUBDIR_recipe - samples: test.s vlir.cvt - $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) test.s: test.grc $(GRC) -s test.s test.grc @@ -59,4 +50,3 @@ clean: $(RM) test.s test.h $(RM) vlir.s vlir.cvt vlir.c vlir.h $(RM) *.o - $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) diff --git a/samples/geos/grc/vlir0.s b/samples/geos/grc/vlir0.s index a54d406df..fd869835c 100644 --- a/samples/geos/grc/vlir0.s +++ b/samples/geos/grc/vlir0.s @@ -5,10 +5,10 @@ ; include some GEOS defines - .include "../../libsrc/geos-common/const.inc" - .include "../../libsrc/geos-cbm/jumptab.inc" - .include "../../libsrc/geos-cbm/geossym.inc" - .include "../../libsrc/geos-common/geosmac.inc" + .include "../../../libsrc/geos-common/const.inc" + .include "../../../libsrc/geos-cbm/jumptab.inc" + .include "../../../libsrc/geos-cbm/geossym.inc" + .include "../../../libsrc/geos-common/geosmac.inc" ; import load addresses for all VLIR chains ; these labels are defined upon linking with ld65 diff --git a/samples/geos/grc/vlir1.s b/samples/geos/grc/vlir1.s index 6ee3cca37..170442af7 100644 --- a/samples/geos/grc/vlir1.s +++ b/samples/geos/grc/vlir1.s @@ -5,10 +5,10 @@ ; include some GEOS defines - .include "../../libsrc/geos-common/const.inc" - .include "../../libsrc/geos-cbm/jumptab.inc" - .include "../../libsrc/geos-cbm/geossym.inc" - .include "../../libsrc/geos-common/geosmac.inc" + .include "../../../libsrc/geos-common/const.inc" + .include "../../../libsrc/geos-cbm/jumptab.inc" + .include "../../../libsrc/geos-cbm/geossym.inc" + .include "../../../libsrc/geos-common/geosmac.inc" ; export names of functions that will be used in the main program diff --git a/samples/geos/grc/vlir2.s b/samples/geos/grc/vlir2.s index 4c02983ff..8dfb79464 100644 --- a/samples/geos/grc/vlir2.s +++ b/samples/geos/grc/vlir2.s @@ -5,10 +5,10 @@ ; similar to vlir1.s except the fact that this is chain #2 - .include "../../libsrc/geos-common/const.inc" - .include "../../libsrc/geos-cbm/jumptab.inc" - .include "../../libsrc/geos-cbm/geossym.inc" - .include "../../libsrc/geos-common/geosmac.inc" + .include "../../../libsrc/geos-common/const.inc" + .include "../../../libsrc/geos-cbm/jumptab.inc" + .include "../../../libsrc/geos-cbm/geossym.inc" + .include "../../../libsrc/geos-common/geosmac.inc" .export OVERLAY2_Function1 .export OVERLAY2_Function2 From 6920b8be78c1a60b141de123dbd54c78438fd54c Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 15 Oct 2020 18:53:56 +0200 Subject: [PATCH 1752/2161] $(RM) abc -> @$(DEL) abc 2>$(NULLDEV) --- samples/disasm/Makefile | 6 +++--- samples/geos/Makefile | 8 ++++---- samples/geos/grc/Makefile | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/samples/disasm/Makefile b/samples/disasm/Makefile index 5f19e943d..0ae2e4b00 100644 --- a/samples/disasm/Makefile +++ b/samples/disasm/Makefile @@ -53,7 +53,7 @@ image.bin: image.s image.cfg $(CL) -t none -C image.cfg -o image.bin image.s clean: - $(RM) $(ASMS) - $(RM) $(DAIS) - $(RM) image.bin + $(DEL) $(ASMS) 2>$(NULLDEV) + $(DEL) $(DAIS) 2>$(NULLDEV) + $(DEL) image.bin 2>$(NULLDEV) diff --git a/samples/geos/Makefile b/samples/geos/Makefile index cbc1e9885..2ae53b0bd 100644 --- a/samples/geos/Makefile +++ b/samples/geos/Makefile @@ -86,8 +86,8 @@ yesno.cvt: yesnores.grc yesno.c clean: - $(RM) overlay-demores.h - $(RM) bitmap.c - $(RM) *.cvt - $(RM) *.map + $(DEL) overlay-demores.h 2>$(NULLDEV) + $(DEL) bitmap.c 2>$(NULLDEV) + $(DEL) *.cvt 2>$(NULLDEV) + $(DEL) *.map 2>$(NULLDEV) $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) diff --git a/samples/geos/grc/Makefile b/samples/geos/grc/Makefile index 4dbe51d10..5b95d9a36 100644 --- a/samples/geos/grc/Makefile +++ b/samples/geos/grc/Makefile @@ -47,6 +47,6 @@ vlir.cvt: vlir.grc vlir0.s vlir1.s vlir2.s # $(CL) -t geos-cbm -o vlir.cvt vlir.grc vlir0.s vlir1.s vlir2.s clean: - $(RM) test.s test.h - $(RM) vlir.s vlir.cvt vlir.c vlir.h - $(RM) *.o + $(DEL) test.s test.h 2>$(NULLDEV) + $(DEL) vlir.s vlir.cvt vlir.c vlir.h 2>$(NULLDEV) + $(DEL) *.o 2>$(NULLDEV) From b773bb9ded55f02ab8ddd874aefa449bb529af26 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 15 Oct 2020 19:34:40 +0200 Subject: [PATCH 1753/2161] some more $(RM) vs $(DEL) fixing --- samples/disasm/Makefile | 6 +++--- samples/geos/Makefile | 8 ++++---- samples/geos/grc/Makefile | 6 +++--- targettest/accelerator/Makefile | 2 +- targettest/apple2/Makefile | 8 ++++---- targettest/atari/Makefile | 18 +++++++++--------- targettest/atari5200/Makefile | 2 +- targettest/cbm/Makefile | 2 +- targettest/gamate/Makefile | 6 +++--- targettest/pce/Makefile | 2 +- 10 files changed, 30 insertions(+), 30 deletions(-) diff --git a/samples/disasm/Makefile b/samples/disasm/Makefile index 0ae2e4b00..f1d93f5da 100644 --- a/samples/disasm/Makefile +++ b/samples/disasm/Makefile @@ -53,7 +53,7 @@ image.bin: image.s image.cfg $(CL) -t none -C image.cfg -o image.bin image.s clean: - $(DEL) $(ASMS) 2>$(NULLDEV) - $(DEL) $(DAIS) 2>$(NULLDEV) - $(DEL) image.bin 2>$(NULLDEV) + @$(DEL) $(ASMS) 2>$(NULLDEV) + @$(DEL) $(DAIS) 2>$(NULLDEV) + @$(DEL) image.bin 2>$(NULLDEV) diff --git a/samples/geos/Makefile b/samples/geos/Makefile index 2ae53b0bd..00841ee8f 100644 --- a/samples/geos/Makefile +++ b/samples/geos/Makefile @@ -86,8 +86,8 @@ yesno.cvt: yesnores.grc yesno.c clean: - $(DEL) overlay-demores.h 2>$(NULLDEV) - $(DEL) bitmap.c 2>$(NULLDEV) - $(DEL) *.cvt 2>$(NULLDEV) - $(DEL) *.map 2>$(NULLDEV) + @$(DEL) overlay-demores.h 2>$(NULLDEV) + @$(DEL) bitmap.c 2>$(NULLDEV) + @$(DEL) *.cvt 2>$(NULLDEV) + @$(DEL) *.map 2>$(NULLDEV) $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) diff --git a/samples/geos/grc/Makefile b/samples/geos/grc/Makefile index 5b95d9a36..81f9ca045 100644 --- a/samples/geos/grc/Makefile +++ b/samples/geos/grc/Makefile @@ -47,6 +47,6 @@ vlir.cvt: vlir.grc vlir0.s vlir1.s vlir2.s # $(CL) -t geos-cbm -o vlir.cvt vlir.grc vlir0.s vlir1.s vlir2.s clean: - $(DEL) test.s test.h 2>$(NULLDEV) - $(DEL) vlir.s vlir.cvt vlir.c vlir.h 2>$(NULLDEV) - $(DEL) *.o 2>$(NULLDEV) + @$(DEL) test.s test.h 2>$(NULLDEV) + @$(DEL) vlir.s vlir.cvt vlir.c vlir.h 2>$(NULLDEV) + @$(DEL) *.o 2>$(NULLDEV) diff --git a/targettest/accelerator/Makefile b/targettest/accelerator/Makefile index f4f651535..527b13f33 100644 --- a/targettest/accelerator/Makefile +++ b/targettest/accelerator/Makefile @@ -55,4 +55,4 @@ turbomaster-test.prg: turbomaster-test.c $(CL) -t c64 turbomaster-test.c -o turbomaster-test.prg clean: - $(RM) *.prg + @$(DEL) *.prg 2>$(NULLDEV) diff --git a/targettest/apple2/Makefile b/targettest/apple2/Makefile index 0020b4ec5..f8167b47c 100644 --- a/targettest/apple2/Makefile +++ b/targettest/apple2/Makefile @@ -65,7 +65,7 @@ dhgrshow: dhgrshow.c $(CL) -Oirs -t apple2enh --start-addr 0x4000 -m dhgrshow.map $^ clean: - $(RM) hgr.dsk dhgr.dsk - $(RM) hgrshow hgrshow.map - $(RM) hgrtest hgrtest.map - $(RM) dhgrshow dhgrshow.map + @$(DEL) hgr.dsk dhgr.dsk 2>$(NULLDEV) + @$(DEL) hgrshow hgrshow.map 2>$(NULLDEV) + @$(DEL) hgrtest hgrtest.map 2>$(NULLDEV) + @$(DEL) dhgrshow dhgrshow.map 2>$(NULLDEV) diff --git a/targettest/atari/Makefile b/targettest/atari/Makefile index a34a5f2d9..18ddf55ce 100644 --- a/targettest/atari/Makefile +++ b/targettest/atari/Makefile @@ -50,12 +50,12 @@ sys.xex: sys.c $(CL) -t atari -o sys.xex sys.c clean: - $(RM) charmapping.xex - $(RM) defdev.xex - $(RM) displaylist.xex - $(RM) mem.xex - $(RM) multi.xex - $(RM) ostype.xex - $(RM) scrcode.o - $(RM) scrcode.com - $(RM) sys.xex + @$(DEL) charmapping.xex 2>$(NULLDEV) + @$(DEL) defdev.xex 2>$(NULLDEV) + @$(DEL) displaylist.xex 2>$(NULLDEV) + @$(DEL) mem.xex 2>$(NULLDEV) + @$(DEL) multi.xex 2>$(NULLDEV) + @$(DEL) ostype.xex 2>$(NULLDEV) + @$(DEL) scrcode.o 2>$(NULLDEV) + @$(DEL) scrcode.com 2>$(NULLDEV) + @$(DEL) sys.xex 2>$(NULLDEV) diff --git a/targettest/atari5200/Makefile b/targettest/atari5200/Makefile index 990ced689..3a8114975 100644 --- a/targettest/atari5200/Makefile +++ b/targettest/atari5200/Makefile @@ -33,4 +33,4 @@ hello: hello.c $(CL) -t atari5200 -o hello hello.c clean: - $(RM) hello + @$(DEL) hello 2>$(NULLDEV) diff --git a/targettest/cbm/Makefile b/targettest/cbm/Makefile index 5217f0cc6..fb7af1a9a 100644 --- a/targettest/cbm/Makefile +++ b/targettest/cbm/Makefile @@ -36,4 +36,4 @@ petscii.prg: petscii.c $(CL) -t $(SYS) -O -o petscii.prg petscii.c clean: - $(DEL) petscii.prg + @$(DEL) petscii.prg 2>$(NULLDEV) diff --git a/targettest/gamate/Makefile b/targettest/gamate/Makefile index d4f1b9673..6cd9a3cdb 100644 --- a/targettest/gamate/Makefile +++ b/targettest/gamate/Makefile @@ -49,6 +49,6 @@ testn: nachtm.bin cd ~/Desktop/mame/winmess/ && wine mess.exe gamate -window -skip_gameinfo -cart ~/Desktop/cc65/github/cc65/testcode/lib/gamate/nachtm.bin clean: - $(RM) lcdtest.o audiotest.o ctest.o - $(RM) lcdtest.bin audiotest.bin ctest.bin nachtm.bin - $(RM) audiotest.lst lcdtest.lst ctest.lst + @$(DEL) lcdtest.o audiotest.o ctest.o 2>$(NULLDEV) + @$(DEL) lcdtest.bin audiotest.bin ctest.bin nachtm.bin 2>$(NULLDEV) + @$(DEL) audiotest.lst lcdtest.lst ctest.lst 2>$(NULLDEV) diff --git a/targettest/pce/Makefile b/targettest/pce/Makefile index 0c41778cc..f7b828e92 100644 --- a/targettest/pce/Makefile +++ b/targettest/pce/Makefile @@ -52,7 +52,7 @@ all: conio.pce ../../../bin/cl65 -t pce $< -Wl -D__CARTSIZE__=${CARTSIZE} -m $*.map -o $@ clean: - $(RM) conio.o conio.??? + @$(DEL) conio.o conio.??? 2>$(NULLDEV) test: conio.pce mednafen -force_module pce $< From e682f7c8c30189a3844da1082669e63a371e2d08 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 15 Oct 2020 14:00:25 -0400 Subject: [PATCH 1754/2161] Protect the C stack from overlays on the c64 target. --- cfg/c64-overlay.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/c64-overlay.cfg b/cfg/c64-overlay.cfg index e88bffe00..0f42434ad 100644 --- a/cfg/c64-overlay.cfg +++ b/cfg/c64-overlay.cfg @@ -14,7 +14,7 @@ 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 = $000D; - MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__; + MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __OVERLAYSTART__ - __HEADER_LAST__; BSS: file = "", start = __ONCE_RUN__, size = __OVERLAYSTART__ - __STACKSIZE__ - __ONCE_RUN__; OVL1ADDR: file = "%O.1", start = __OVERLAYSTART__ - 2, size = $0002; OVL1: file = "%O.1", start = __OVERLAYSTART__, size = __OVERLAYSIZE__; From a25b28a9726c0e0c8c9c5201dcad2e00ba0f6a5d Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 15 Oct 2020 21:22:04 -0400 Subject: [PATCH 1755/2161] Added files to the pet library that support the overlay demo sample program. cbm_load() is needed because the Pet/CBM Kernals don't have a LOAD function that can be used by machine code programs. --- cfg/pet-overlay.cfg | 82 +++++++++++++++++++++++++++++++++++++++++++ libsrc/pet/cbm_load.c | 59 +++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 cfg/pet-overlay.cfg create mode 100644 libsrc/pet/cbm_load.c diff --git a/cfg/pet-overlay.cfg b/cfg/pet-overlay.cfg new file mode 100644 index 000000000..afd351a42 --- /dev/null +++ b/cfg/pet-overlay.cfg @@ -0,0 +1,82 @@ +FEATURES { + STARTADDRESS: default = $0401; +} +SYMBOLS { + __LOADADDR__: type = import; + __EXEHDR__: type = import; + __OVERLAYADDR__: type = import; + __STACKSIZE__: type = weak, value = $0800; # 2K stack + __OVERLAYSIZE__: type = weak, value = $0800; # 2K overlay + __HIMEM__: type = weak, value = $8000; + __OVERLAYSTART__: type = export, value = __HIMEM__ - __STACKSIZE__ - __OVERLAYSIZE__; +} +MEMORY { + ZP: file = "", define = yes, start = $0055, 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 = __OVERLAYSTART__ - __HEADER_LAST__; + OVL1ADDR: file = "%O.1", start = __OVERLAYSTART__ - 2, size = $0002; + OVL1: file = "%O.1", start = __OVERLAYSTART__, size = __OVERLAYSIZE__; + OVL2ADDR: file = "%O.2", start = __OVERLAYSTART__ - 2, size = $0002; + OVL2: file = "%O.2", start = __OVERLAYSTART__, size = __OVERLAYSIZE__; + OVL3ADDR: file = "%O.3", start = __OVERLAYSTART__ - 2, size = $0002; + OVL3: file = "%O.3", start = __OVERLAYSTART__, size = __OVERLAYSIZE__; + OVL4ADDR: file = "%O.4", start = __OVERLAYSTART__ - 2, size = $0002; + OVL4: file = "%O.4", start = __OVERLAYSTART__, size = __OVERLAYSIZE__; + OVL5ADDR: file = "%O.5", start = __OVERLAYSTART__ - 2, size = $0002; + OVL5: file = "%O.5", start = __OVERLAYSTART__, size = __OVERLAYSIZE__; + OVL6ADDR: file = "%O.6", start = __OVERLAYSTART__ - 2, size = $0002; + OVL6: file = "%O.6", start = __OVERLAYSTART__, size = __OVERLAYSIZE__; + OVL7ADDR: file = "%O.7", start = __OVERLAYSTART__ - 2, size = $0002; + OVL7: file = "%O.7", start = __OVERLAYSTART__, size = __OVERLAYSIZE__; + OVL8ADDR: file = "%O.8", start = __OVERLAYSTART__ - 2, size = $0002; + OVL8: file = "%O.8", start = __OVERLAYSTART__, size = __OVERLAYSIZE__; + OVL9ADDR: file = "%O.9", start = __OVERLAYSTART__ - 2, size = $0002; + OVL9: file = "%O.9", start = __OVERLAYSTART__, size = __OVERLAYSIZE__; +} +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; + OVL1ADDR: load = OVL1ADDR, type = ro; + OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; + OVL2ADDR: load = OVL2ADDR, type = ro; + OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes; + OVL3ADDR: load = OVL3ADDR, type = ro; + OVERLAY3: load = OVL3, type = ro, define = yes, optional = yes; + OVL4ADDR: load = OVL4ADDR, type = ro; + OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes; + OVL5ADDR: load = OVL5ADDR, type = ro; + OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes; + OVL6ADDR: load = OVL6ADDR, type = ro; + OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes; + OVL7ADDR: load = OVL7ADDR, type = ro; + OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes; + OVL8ADDR: load = OVL8ADDR, type = ro; + OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes; + OVL9ADDR: load = OVL9ADDR, type = ro; + OVERLAY9: load = OVL9, type = ro, define = yes, optional = 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/libsrc/pet/cbm_load.c b/libsrc/pet/cbm_load.c new file mode 100644 index 000000000..1823f6537 --- /dev/null +++ b/libsrc/pet/cbm_load.c @@ -0,0 +1,59 @@ +/* +** 2020-10-15, Greg King +** +** unsigned int __fastcall__ cbm_load (const char* name, +** unsigned char device, +** void* data); +*/ + +#include <cbm.h> +#include <limits.h> + +/* Loads file "name" from the given device to the given address, or to the load +** address of the file if "data" is the null pointer (like load"name",8,1 +** in BASIC). +** Returns the number of bytes that were loaded if loading was successful; +** otherwise 0; "_oserror" contains an error-code, then. +*/ +unsigned int __fastcall__ cbm_load (const char* name, unsigned char device, void* data) +{ + void* load; + int length; + unsigned int size = 0; + + if (cbm_open (1, device, CBM_READ, name) != 0) { + /* Can't load from a file that can't be openned. */ + 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.) + */ + cbm_close (1); + return 0; + } + + /* If "data" doesn't hold an address, then use the file's address. */ + if (data == (void*)0x0000) { + data = load; + } + + /* Pull the file into RAM. [Note that, if cbm_read() grabbed more + ** than 32767 bytes at a time, then its result would look negative, + ** which would cancel the load.] + */ + do { + size += (length = cbm_read (1, data, INT_MAX)); + data = (unsigned char*)data + length; + } while (length == INT_MAX && cbm_k_readst() == 0); + cbm_close (1); + + /* "length" is -1 if there was an error. */ + if (length < 0) { + size = 0; + } + + return size; +} From 77bfd163cd2460b46d4e31b17eb5e5e7ec6ab8aa Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 16 Oct 2020 15:50:18 +0200 Subject: [PATCH 1756/2161] makefile cleanup --- targettest/gamate/Makefile | 9 --------- targettest/pce/Makefile | 7 ++----- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/targettest/gamate/Makefile b/targettest/gamate/Makefile index 6cd9a3cdb..a14b8a854 100644 --- a/targettest/gamate/Makefile +++ b/targettest/gamate/Makefile @@ -39,15 +39,6 @@ nachtm.bin: nachtm.c $(CL) -Os -l nachtm.lst -t gamate -o nachtm.bin nachtm.c gamate-fixcart nachtm.bin -test1: lcdtest.bin - cd ~/Desktop/mame/winmess/ && wine mess.exe gamate -window -skip_gameinfo -cart ~/Desktop/cc65/github/cc65/testcode/lib/gamate/lcdtest.bin -test2: audiotest.bin - cd ~/Desktop/mame/winmess/ && wine mess.exe gamate -window -skip_gameinfo -cart ~/Desktop/cc65/github/cc65/testcode/lib/gamate/audiotest.bin -testc: ctest.bin - cd ~/Desktop/mame/winmess/ && wine mess.exe gamate -window -skip_gameinfo -cart ~/Desktop/cc65/github/cc65/testcode/lib/gamate/ctest.bin -testn: nachtm.bin - cd ~/Desktop/mame/winmess/ && wine mess.exe gamate -window -skip_gameinfo -cart ~/Desktop/cc65/github/cc65/testcode/lib/gamate/nachtm.bin - clean: @$(DEL) lcdtest.o audiotest.o ctest.o 2>$(NULLDEV) @$(DEL) lcdtest.bin audiotest.bin ctest.bin nachtm.bin 2>$(NULLDEV) diff --git a/targettest/pce/Makefile b/targettest/pce/Makefile index f7b828e92..1ecc0566f 100644 --- a/targettest/pce/Makefile +++ b/targettest/pce/Makefile @@ -48,11 +48,8 @@ all: conio.pce dd if=$< bs=8K skip=${COUNT} > $@ dd if=$< bs=8K count=${COUNT} >> $@ -%.bin: %.c ../../../lib/pce.lib - ../../../bin/cl65 -t pce $< -Wl -D__CARTSIZE__=${CARTSIZE} -m $*.map -o $@ +%.bin: %.c + $(CL) -t pce $< -Wl -D__CARTSIZE__=${CARTSIZE} -m $*.map -o $@ clean: @$(DEL) conio.o conio.??? 2>$(NULLDEV) - -test: conio.pce - mednafen -force_module pce $< From 0f66f7569e3cb53a314a9d8ae4df9f1768400725 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 17 Oct 2020 10:36:11 -0400 Subject: [PATCH 1757/2161] Updated the cx16 library to the upstream project's prerelease 38. --- asminc/cbm_kernal.inc | 1 + asminc/cx16.inc | 10 ++++---- include/cx16.h | 14 ++++++----- libsrc/cx16/cputc.s | 56 +++++++++++++++++++++---------------------- 4 files changed, 43 insertions(+), 38 deletions(-) diff --git a/asminc/cbm_kernal.inc b/asminc/cbm_kernal.inc index 981687206..5f41c6267 100644 --- a/asminc/cbm_kernal.inc +++ b/asminc/cbm_kernal.inc @@ -46,6 +46,7 @@ GRAPH_SET_FONT := $FF3B GRAPH_GET_CHAR_SIZE := $FF3E GRAPH_PUT_CHAR := $FF41 + MULTI_ACPTR := $FF44 RESTORE_BASIC := $FF47 CLOCK_SET_DATE_TIME := $FF4D CLOCK_GET_DATE_TIME := $FF50 diff --git a/asminc/cx16.inc b/asminc/cx16.inc index 8891c1761..4d9ce89db 100644 --- a/asminc/cx16.inc +++ b/asminc/cx16.inc @@ -1,5 +1,5 @@ ; -; CX16 r37 definitions +; CX16 r38 definitions ; ; --------------------------------------------------------------------------- @@ -439,7 +439,7 @@ NMIVec := $0318 .scope PSG ; Programmable Sound Generator .struct PITCH .word - VOL .byte ; Left, right channels; volume + VOL .byte ; Right, left sides; volume WAVEFORM .byte ; Wave shape, pulse width .endstruct LEFT = %01 << 6 @@ -544,9 +544,11 @@ NMIVec := $0318 VERALOG .byte ; Boolean: log VERA activity KEYBOARDLOG .byte ; Boolean: log keyboard data ECHO .byte ; Type of echo that's enabled - SAVEXIT .byte ; Boolean: save on exit + SAVEXIT .byte ; Boolean: save machine state on exit GIFREC .byte ; Method of recording GIF movie - .org $9FBD + .res 2 + CYCLECOUNT .dword ; Running count of CPU cycles (Read-Only) + .res 1 KEYMAP .byte ; Current keyboard layout number (Read-Only) DETECT .byte 2 ; If is "16" string, then running on emulator (RO) .endstruct diff --git a/include/cx16.h b/include/cx16.h index 87a6d37ca..f3d02bd28 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -3,7 +3,7 @@ /* cx16.h */ /* */ /* CX16 system-specific definitions */ -/* For prerelease 37 */ +/* For prerelease 38 */ /* */ /* */ /* This software is provided "as-is", without any expressed or implied */ @@ -283,12 +283,14 @@ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ unsigned char vera_action; /* Boolean: displaying VERA activity */ unsigned char keyboard; /* Boolean: displaying typed keys */ - unsigned char echo; /* How Kernal output should be echoed to host */ - unsigned char save_on_exit; /* Boolean: save SD card when quitting */ + unsigned char echo; /* How to send Kernal output to host */ + unsigned char save_on_exit; /* Boolean: save machine state on exit */ unsigned char gif_method; /* How GIF movie is being recorded */ - unsigned char unused[0xD - 0x6]; - unsigned char keymap; /* Keyboard layout number */ - const char detect[2]; /* "16" if running on x16emu */ + unsigned char const unused1[2]; + unsigned long const cycle_count; /* Running total of CPU cycles (8 MHz.) */ + unsigned char const unused2[1]; + unsigned char const keymap; /* Keyboard layout number */ + char const detect[2]; /* "16" if running on x16emu */ }; #define EMULATOR (*(volatile struct __emul *)0x9FB0) diff --git a/libsrc/cx16/cputc.s b/libsrc/cx16/cputc.s index 034c3e389..4a7034e59 100644 --- a/libsrc/cx16/cputc.s +++ b/libsrc/cx16/cputc.s @@ -1,5 +1,5 @@ ; -; 2019-09-23, Greg King +; 2020-10-13, Greg King ; ; void __fastcall__ cputcxy (unsigned char x, unsigned char y, char c); ; void __fastcall__ cputc (char c); @@ -11,52 +11,47 @@ .import gotoxy, PLOT .include "cx16.inc" - .macpack generic -; First, move to a new position. +; Move to a cursor position, then print a character. _cputcxy: pha ; Save C jsr gotoxy ; Set cursor, drop x and y - pla ; Restore C + pla -; Print a character. +; Print a character -- also used as an internal function. -_cputc: cmp #$0D ; LF? +_cputc: cmp #$0D ; X16 '\n'? beq newline - cmp #$0A ; CR? - beq plotx0 + cmp #$0A ; X16 '\r'? + beq cr -; Printable char of some sort +; Printable char. of some sort. +; Convert it from PetSCII into a screen-code. - cmp #' ' - blt cputdirect ; Other control char +convert: tay - bmi L10 - cmp #$60 - blt L2 - and #<~%00100000 - bra cputdirect - -; Handle character if high bit set - -L10: and #<~%10000000 ; Remove high bit - ora #%01000000 - bra cputdirect - -L2: and #<~%01000000 + lsr a ; Divide by 256/8 + lsr a + lsr a + lsr a + lsr a + tax ; .X = %00000xxx + tya + eor pet_to_screen,x cputdirect: jsr putchar ; Write character to screen, return .Y -; Advance cursor position. +; Advance the cursor position. iny cpy LLEN ; Reached end of line? bne L3 - jsr newline ; Next line - ldy #$00 ; + CR + jsr newline ; Wrap around + +cr: ldy #$00 L3: sty CURS_X rts @@ -70,7 +65,6 @@ newline: ; Set the cursor's position, calculate RAM pointer. -plotx0: stz CURS_X plot: ldy CURS_X ldx CURS_Y clc @@ -96,3 +90,9 @@ putchar: lda CHARCOLOR sta VERA::DATA0 rts + + + .rodata +pet_to_screen: + .byte %10000000,%00000000,%01000000,%00100000 ; PetSCII -> screen-code + .byte %01000000,%11000000,%10000000,%10000000 From 4f3a96a535a94b91813ce7651dcd08de9dc95cd3 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 18 Sep 2020 20:22:58 +0800 Subject: [PATCH 1758/2161] Added new opt OptPushPop2. Also renamed OptPushPop to OptPushPop1. --- src/cc65/codeopt.c | 8 ++-- src/cc65/coptind.c | 93 +++++++++++++++++++++++++++++++++++++++++++++- src/cc65/coptind.h | 7 +++- 3 files changed, 101 insertions(+), 7 deletions(-) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 4a7722830..f83a8d9f8 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -167,7 +167,8 @@ static OptFunc DOptPtrStore2 = { OptPtrStore2, "OptPtrStore2", 65, 0, static OptFunc DOptPtrStore3 = { OptPtrStore3, "OptPtrStore3", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptPush1 = { OptPush1, "OptPush1", 65, 0, 0, 0, 0, 0 }; static OptFunc DOptPush2 = { OptPush2, "OptPush2", 50, 0, 0, 0, 0, 0 }; -static OptFunc DOptPushPop = { OptPushPop, "OptPushPop", 0, 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 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 }; @@ -269,7 +270,7 @@ static OptFunc* OptFuncs[] = { &DOptPtrStore3, &DOptPush1, &DOptPush2, - &DOptPushPop, + &DOptPushPop1, &DOptRTS, &DOptRTSJumps1, &DOptRTSJumps2, @@ -709,7 +710,8 @@ static unsigned RunOptGroup3 (CodeSeg* S) C += RunOptFunc (S, &DOptTransfers4, 1); C += RunOptFunc (S, &DOptStore1, 1); C += RunOptFunc (S, &DOptStore5, 1); - C += RunOptFunc (S, &DOptPushPop, 1); + C += RunOptFunc (S, &DOptPushPop1, 1); + C += RunOptFunc (S, &DOptPushPop2, 1); C += RunOptFunc (S, &DOptPrecalc, 1); Changes += C; diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index eada61871..4bb236692 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -1069,8 +1069,8 @@ unsigned OptTransfers4 (CodeSeg* S) -unsigned OptPushPop (CodeSeg* S) -/* Remove a PHA/PLA sequence were A is not used later */ +unsigned OptPushPop1 (CodeSeg* S) +/* Remove a PHA/PLA sequence were A not used later */ { unsigned Changes = 0; unsigned Push = 0; /* Index of push insn */ @@ -1199,6 +1199,95 @@ unsigned OptPushPop (CodeSeg* S) +unsigned OptPushPop2 (CodeSeg* S) +/* Remove a PHP/PLP sequence were no processor flags changed inside */ +{ + unsigned Changes = 0; + unsigned Push = 0; /* Index of push insn */ + unsigned Pop = 0; /* Index of pop insn */ + enum { + Searching, + FoundPush, + FoundPop + } State = Searching; + + /* Walk over the entries. Look for a push instruction that is followed by + ** a pop later, where the pop is not followed by an conditional branch, + ** and where the value of the A register is not used later on. + ** Look out for the following problems: + ** + ** - There may be another PHP/PLP inside the sequence: Restart it. + ** - All jumps inside the sequence must not go outside the sequence, + ** otherwise it would be too complicated to remove the PHP/PLP. + */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + /* Get next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + switch (State) { + + case Searching: + if (E->OPC == OP65_PHP) { + /* Found start of sequence */ + Push = I; + State = FoundPush; + } + break; + + case FoundPush: + if (E->OPC == OP65_PHP) { + /* Inner push/pop, restart */ + Push = I; + } else if (E->OPC == OP65_PLP) { + /* Found a matching pop */ + Pop = I; + /* Check that the block between Push and Pop is a basic + ** block (one entry, one exit). Otherwise ignore it. + */ + if (CS_IsBasicBlock (S, Push, Pop)) { + State = FoundPop; + } else { + /* Go into searching mode again */ + State = Searching; + } + } else if ((E->Info & OF_BRA) == 0 && + (E->Info & OF_STORE) == 0 && + E->OPC != OP65_NOP && + E->OPC != OP65_TSX) { + /* Don't bother skipping dead code */ + State = Searching; + } + break; + + case FoundPop: + /* We can remove the PHP and PLP instructions */ + CS_DelEntry (S, Pop); + CS_DelEntry (S, Push); + + /* Correct I so we continue with THIS insn */ + I -= 3; + + /* Remember we had changes */ + ++Changes; + + /* Go into search mode again */ + 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 64acb10d8..ab9179e96 100644 --- a/src/cc65/coptind.h +++ b/src/cc65/coptind.h @@ -82,8 +82,11 @@ unsigned OptTransfers4 (CodeSeg* S); ** by a load of the second register if possible. */ -unsigned OptPushPop (CodeSeg* S); -/* Remove a PHA/PLA sequence were A is not used later */ +unsigned OptPushPop1 (CodeSeg* S); +/* Remove a PHA/PLA sequence were A not used later */ + +unsigned OptPushPop2 (CodeSeg* S); +/* Remove a PHP/PLP sequence were no processor flags changed inside */ unsigned OptPrecalc (CodeSeg* S); /* Replace immediate operations with the accu where the current contents are From 9c776a24e5e14dd34c4f30f96a6383f54442c7a9 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 18 Sep 2020 20:22:58 +0800 Subject: [PATCH 1759/2161] Use bcc instead of bne in OptNegAX2 to ease optimizations. --- src/cc65/coptneg.c | 6 +++--- src/cc65/coptneg.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc65/coptneg.c b/src/cc65/coptneg.c index 0f5d589f7..27171c68d 100644 --- a/src/cc65/coptneg.c +++ b/src/cc65/coptneg.c @@ -480,7 +480,7 @@ unsigned OptNegAX2 (CodeSeg* S) ** eor #$FF ** clc ** adc #$01 -** bne L1 +** bcc L1 ** inx ** L1: ** @@ -528,8 +528,8 @@ unsigned OptNegAX2 (CodeSeg* S) /* Get the label attached to the insn following the call */ L = CS_GenLabel (S, P); - /* bne L */ - X = NewCodeEntry (OP65_BNE, AM65_BRA, L->Name, L, E->LI); + /* bcc L */ + X = NewCodeEntry (OP65_BCC, AM65_BRA, L->Name, L, E->LI); CS_InsertEntry (S, X, I+5); /* inx */ diff --git a/src/cc65/coptneg.h b/src/cc65/coptneg.h index f549fc553..844d8b886 100644 --- a/src/cc65/coptneg.h +++ b/src/cc65/coptneg.h @@ -155,7 +155,7 @@ unsigned OptNegAX2 (CodeSeg* S); ** eor #$FF ** clc ** adc #$01 -** bne L1 +** bcc L1 ** inx ** L1: ** From 0354322413db6b958b801690f593cc2ce1fdde4c Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 18 Sep 2020 20:22:58 +0800 Subject: [PATCH 1760/2161] Added OptSignExtened for testing signness right after sign extention. --- src/cc65/codeopt.c | 3 ++ src/cc65/coptind.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++ src/cc65/coptind.h | 25 +++++++++++++ 3 files changed, 120 insertions(+) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index f83a8d9f8..07764cd40 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -178,6 +178,7 @@ static OptFunc DOptShift3 = { OptShift3, "OptShift3", 17, 0, static OptFunc DOptShift4 = { OptShift4, "OptShift4", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptShift5 = { OptShift5, "OptShift5", 110, 0, 0, 0, 0, 0 }; static OptFunc DOptShift6 = { OptShift6, "OptShift6", 200, 0, 0, 0, 0, 0 }; +static OptFunc DOptSignExtended = { OptSignExtended, "OptSignExtended", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptSize1 = { OptSize1, "OptSize1", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptSize2 = { OptSize2, "OptSize2", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptStackOps = { OptStackOps, "OptStackOps", 100, 0, 0, 0, 0, 0 }; @@ -280,6 +281,7 @@ static OptFunc* OptFuncs[] = { &DOptShift4, &DOptShift5, &DOptShift6, + &DOptSignExtended, &DOptSize1, &DOptSize2, &DOptStackOps, @@ -713,6 +715,7 @@ static unsigned RunOptGroup3 (CodeSeg* S) C += RunOptFunc (S, &DOptPushPop1, 1); C += RunOptFunc (S, &DOptPushPop2, 1); C += RunOptFunc (S, &DOptPrecalc, 1); + C += RunOptFunc (S, &DOptSignExtended, 1); Changes += C; diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index 4bb236692..5fe3b5c03 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -1474,3 +1474,95 @@ unsigned OptPrecalc (CodeSeg* S) /* Return the number of changes made */ return Changes; } + + + +unsigned OptSignExtended (CodeSeg* S) +/* Change +** +** lda xxx ; X is 0 +** bpl L1 +** dex/ldx #$FF +** L1: cpx #$00 +** bpl L2 +** +** or +** +** lda xxx ; X is 0 +** bpl L1 +** dex/ldx #$FF +** L1: cpx #$80 +** bcc/bmi L2 +** +** into +** lda xxx ; X is 0 +** bpl L2 +** dex/ldx #$FF +** +** provided the C flag isn't used later. +*/ +{ + unsigned Changes = 0; + CodeEntry* L[5]; + CodeEntry* X; + unsigned CheckStates; + + /* Walk over the entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + /* Get next entry */ + L[0] = CS_GetEntry (S, I); + + /* Check if it's a register load or transfer insn */ + if (L[0]->OPC == OP65_LDA && + CS_GetEntries (S, L+1, I+1, 4) && + !CS_RangeHasLabel (S, I+1, 2) && + CE_GetLabelCount (L[3]) == 1 && + L[1]->JumpTo == CE_GetLabel (L[3], 0) && + (L[1]->Info & OF_CBRA) != 0 && + GetBranchCond (L[1]->OPC) == BC_PL && + RegValIsKnown (L[2]->RI->Out.RegX) && + L[2]->RI->Out.RegX == 0xFF && + L[2]->OPC != OP65_JSR && + (L[2]->Chg & REG_AXY) == REG_X) { + + /* We find a sign extention */ + CheckStates = PSTATE_CZN; + if (L[3]->OPC == OP65_CPX && + CE_IsConstImm (L[3]) && + (L[4]->Info & OF_CBRA) != 0 && + ((L[3]->Num == 0x00 && + GetBranchCond (L[4]->OPC) == BC_PL) || + ((L[3]->Num == 0x80 && + GetBranchCond (L[4]->OPC) == BC_CC && + GetBranchCond (L[4]->OPC) == BC_MI)))) { + + /* Check if the processor states set by the CPX are unused later */ + if ((GetRegInfo (S, I+5, CheckStates) & CheckStates) == 0) { + + /* Change the target of the sign extention branch */ + X = NewCodeEntry (OP65_JPL, L[4]->AM, L[4]->Arg, L[4]->JumpTo, L[4]->LI); + CS_InsertEntry (S, X, I+1); + CS_DelEntry (S, I+2); + + /* Remove the old conditional branch */ + CS_DelEntries (S, I+3, 2); + + /* Remember, we had changes */ + ++Changes; + + /* Continue with the current insn */ + continue; + } + } + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} diff --git a/src/cc65/coptind.h b/src/cc65/coptind.h index ab9179e96..496b23447 100644 --- a/src/cc65/coptind.h +++ b/src/cc65/coptind.h @@ -93,6 +93,31 @@ unsigned OptPrecalc (CodeSeg* S); ** known by a load of the final value. */ +unsigned OptSignExtended (CodeSeg* S); +/* Change +** +** lda xxx ; X is 0 +** bpl L1 +** dex/ldx #$FF +** L1: cpx #$00 +** bpl L2 +** +** or +** +** lda xxx ; X is 0 +** bpl L1 +** dex/ldx #$FF +** L1: cpx #$80 +** bcc/bmi L2 +** +** into +** lda xxx ; X is 0 +** bpl L2 +** dex/ldx #$FF +** +** provided the C flag isn't used later. +*/ + /* End of coptind.h */ From bb7b69f513e3f3612d185c3daef3d83650158ddb Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 18 Sep 2020 20:22:58 +0800 Subject: [PATCH 1761/2161] Added OptShiftBack for shifting the C flag into register A and back. --- src/cc65/codeopt.c | 3 +++ src/cc65/coptind.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++ src/cc65/coptind.h | 5 +++++ 3 files changed, 62 insertions(+) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 07764cd40..3c10183e4 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -178,6 +178,7 @@ static OptFunc DOptShift3 = { OptShift3, "OptShift3", 17, 0, static OptFunc DOptShift4 = { OptShift4, "OptShift4", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptShift5 = { OptShift5, "OptShift5", 110, 0, 0, 0, 0, 0 }; static OptFunc DOptShift6 = { OptShift6, "OptShift6", 200, 0, 0, 0, 0, 0 }; +static OptFunc DOptShiftBack = { OptShiftBack, "OptShiftBack", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptSignExtended = { OptSignExtended, "OptSignExtended", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptSize1 = { OptSize1, "OptSize1", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptSize2 = { OptSize2, "OptSize2", 100, 0, 0, 0, 0, 0 }; @@ -281,6 +282,7 @@ static OptFunc* OptFuncs[] = { &DOptShift4, &DOptShift5, &DOptShift6, + &DOptShiftBack, &DOptSignExtended, &DOptSize1, &DOptSize2, @@ -715,6 +717,7 @@ static unsigned RunOptGroup3 (CodeSeg* S) C += RunOptFunc (S, &DOptPushPop1, 1); C += RunOptFunc (S, &DOptPushPop2, 1); C += RunOptFunc (S, &DOptPrecalc, 1); + C += RunOptFunc (S, &DOptShiftBack, 1); C += RunOptFunc (S, &DOptSignExtended, 1); Changes += C; diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index 5fe3b5c03..f3e17fc87 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -1477,6 +1477,60 @@ unsigned OptPrecalc (CodeSeg* S) +unsigned OptShiftBack (CodeSeg* S) +/* Remove a pair of shifts to the opposite directions if none of the bits of +** the register A or the Z/N flags modified by these shifts are used later. +*/ +{ + unsigned Changes = 0; + CodeEntry* E; + CodeEntry* N; + unsigned CheckStates; + + /* Walk over the entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + /* Get next entry */ + E = CS_GetEntry (S, I); + + /* Check if it's a register load or transfer insn */ + if (E->OPC == OP65_ROL && + (N = CS_GetNextEntry (S, I)) != 0 && + (N->OPC == OP65_LSR || + N->OPC == OP65_ROR) && + !CE_HasLabel (N)) { + + CheckStates = PSTATE_ZN; + + if (N->OPC == OP65_LSR && + !PStatesAreClear (E->RI->Out.PFlags, PSTATE_C)) { + CheckStates |= REG_A; + } + + if ((GetRegInfo (S, I+2, CheckStates) & CheckStates) == 0) { + + /* Remove the shifts */ + CS_DelEntries (S, I, 2); + + /* Remember, we had changes */ + ++Changes; + + /* Continue with next insn */ + continue; + } + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + unsigned OptSignExtended (CodeSeg* S) /* Change ** diff --git a/src/cc65/coptind.h b/src/cc65/coptind.h index 496b23447..c7ecf4194 100644 --- a/src/cc65/coptind.h +++ b/src/cc65/coptind.h @@ -93,6 +93,11 @@ unsigned OptPrecalc (CodeSeg* S); ** known by a load of the final value. */ +unsigned OptShiftBack (CodeSeg* S); +/* Remove a pair of shifts to the opposite directions if none of the bits of +** the register A or the Z/N flags modified by these shifts are used later. +*/ + unsigned OptSignExtended (CodeSeg* S); /* Change ** From 5c43d1e04f48c51c743fb3fa66cb00b58ccc0f33 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 16 Apr 2020 17:19:16 +0800 Subject: [PATCH 1762/2161] Changed codegen for postfix inc/dec operations by deferring them till sequence points. This usually allows faster & smaller code. Note that deferred operations must still be called at sequence points even if the whole expressions containing them had constant values. --- src/cc65/compile.c | 7 + src/cc65/declare.c | 6 + src/cc65/expr.c | 493 +++++++++++++++++++++++++++++++++++++++----- src/cc65/expr.h | 34 ++- src/cc65/goto.c | 7 + src/cc65/locals.c | 10 + src/cc65/stdfunc.c | 15 ++ src/cc65/stmt.c | 3 + src/cc65/testexpr.c | 9 + 9 files changed, 526 insertions(+), 58 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index ec90e4b2d..d93de96b4 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -320,6 +320,9 @@ static void Parse (void) } else { /* Parse the function body */ NewFunc (Entry, FuncDef); + + /* Make sure we aren't omitting any work */ + CheckDeferredOpAllDone (); } } @@ -395,6 +398,8 @@ void Compile (const char* FileName) /* DefineNumericMacro ("__STDC__", 1); <- not now */ DefineNumericMacro ("__STDC_HOSTED__", 1); + InitDeferredOps (); + /* Create the base lexical level */ EnterGlobalLevel (); @@ -486,6 +491,8 @@ void Compile (const char* FileName) } } + DoneDeferredOps (); + if (Debug) { PrintMacroStats (stdout); } diff --git a/src/cc65/declare.c b/src/cc65/declare.c index bf27f9c90..08739f333 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2302,6 +2302,9 @@ static unsigned ParseScalarInit (Type* T) /* Output the data */ DefineData (&ED); + /* Do this anyways for safety */ + DoDeferred (SQP_KEEP_NONE, &ED); + /* Done */ return SizeOf (T); } @@ -2321,6 +2324,9 @@ static unsigned ParsePointerInit (Type* T) /* Output the data */ DefineData (&ED); + /* Do this anyways for safety */ + DoDeferred (SQP_KEEP_NONE, &ED); + /* Close eventually opening braces */ ClosingCurlyBraces (BraceCount); diff --git a/src/cc65/expr.c b/src/cc65/expr.c index a88710f34..19572944e 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -332,6 +332,264 @@ static void WarnConstCompareResult (const ExprDesc* Expr) +typedef enum { + DOT_INC, + DOT_DEC, +} DeferredOpType; + + +typedef struct { + ExprDesc Expr; + DeferredOpType OpType; +} DeferredOp; + +Collection DeferredOps; + + + +void InitDeferredOps (void) +/* Init the collection for storing deferred ops */ +{ + InitCollection (&DeferredOps); +} + + + +void DoneDeferredOps (void) +/* Deinit the collection for storing deferred ops */ +{ + DoneCollection (&DeferredOps); +} + + + +static void DeferInc (const ExprDesc* Expr) +/* Defer the post-inc and put it in a queue */ +{ + DeferredOp* Op = xmalloc (sizeof (DeferredOp)); + memcpy (&Op->Expr, Expr, sizeof (ExprDesc)); + Op->OpType = DOT_INC; + CollAppend (&DeferredOps, Op); +} + + + +static void DeferDec (const ExprDesc* Expr) +/* Defer the post-dec and put it in a queue */ +{ + DeferredOp* Op = xmalloc (sizeof (DeferredOp)); + memcpy (&Op->Expr, Expr, sizeof (ExprDesc)); + Op->OpType = DOT_DEC; + CollAppend (&DeferredOps, Op); +} + + + +static void DeferredInc (ExprDesc* Expr) +/* Do the deferred post-inc */ +{ + unsigned Flags; + unsigned long Val; + + /* Get the flags */ + Flags = TypeOf (Expr->Type) | GlobalModeFlags (Expr) | CF_FORCECHAR | CF_CONST | CF_NOKEEP; + + /* Get the increment value in bytes */ + Val = IsTypePtr (Expr->Type) ? CheckedSizeOf (Expr->Type + 1) : 1; + + /* Check the location of the data */ + switch (ED_GetLoc (Expr)) { + + case E_LOC_ABS: + /* Absolute: numeric address or const */ + g_addeqstatic (Flags, Expr->IVal, 0, Val); + break; + + case E_LOC_GLOBAL: + /* Global variable */ + g_addeqstatic (Flags, Expr->Name, Expr->IVal, Val); + break; + + case E_LOC_STATIC: + case E_LOC_LITERAL: + /* Static variable or literal in the literal pool */ + g_addeqstatic (Flags, Expr->Name, Expr->IVal, Val); + break; + + case E_LOC_REGISTER: + /* Register variable */ + g_addeqstatic (Flags, Expr->Name, Expr->IVal, Val); + break; + + case E_LOC_STACK: + /* Value on the stack */ + g_addeqlocal (Flags, Expr->IVal, Val); + break; + + case E_LOC_PRIMARY: + /* The primary register */ + g_inc (Flags, Val); + break; + + case E_LOC_EXPR: + /* An expression in the primary register */ + g_addeqind (Flags, Expr->IVal, Val); + break; + + default: + Internal ("Invalid location in DeferredInc(): 0x%04X", ED_GetLoc (Expr)); + } +} + + + +static void DeferredDec (ExprDesc* Expr) +/* Do the deferred post-dec */ +{ + unsigned Flags; + unsigned long Val; + + /* Get the flags */ + Flags = TypeOf (Expr->Type) | GlobalModeFlags (Expr) | CF_FORCECHAR | CF_CONST | CF_NOKEEP; + + /* Get the increment value in bytes */ + Val = IsTypePtr (Expr->Type) ? CheckedSizeOf (Expr->Type + 1) : 1; + + /* Check the location of the data */ + switch (ED_GetLoc (Expr)) { + + case E_LOC_ABS: + /* Absolute: numeric address or const */ + g_subeqstatic (Flags, Expr->IVal, 0, Val); + break; + + case E_LOC_GLOBAL: + /* Global variable */ + g_subeqstatic (Flags, Expr->Name, Expr->IVal, Val); + break; + + case E_LOC_STATIC: + case E_LOC_LITERAL: + /* Static variable or literal in the literal pool */ + g_subeqstatic (Flags, Expr->Name, Expr->IVal, Val); + break; + + case E_LOC_REGISTER: + /* Register variable */ + g_subeqstatic (Flags, Expr->Name, Expr->IVal, Val); + break; + + case E_LOC_STACK: + /* Value on the stack */ + g_subeqlocal (Flags, Expr->IVal, Val); + break; + + case E_LOC_PRIMARY: + /* The primary register */ + g_dec (Flags, Val); + break; + + case E_LOC_EXPR: + /* An expression in the primary register */ + g_subeqind (Flags, Expr->IVal, Val); + break; + + default: + Internal ("Invalid location in DeferredDec(): 0x%04X", ED_GetLoc (Expr)); + } +} + + + +int GetDeferredOpCount (void) +/* Return how many deferred operations are still waiting in the queque */ +{ + return (int)CollCount (&DeferredOps); +} + + + +void CheckDeferredOpAllDone (void) +/* Check if all deferred operations are done at sequence points. +** Die off if check fails. +*/ +{ + if (GetDeferredOpCount () > 0) { + Internal ("Code generation messed up: missing operations past sequence points."); + } +} + + + +void DoDeferred (unsigned Flags, ExprDesc* Expr) +/* Do deferred operations such as post-inc/dec at sequence points */ +{ + int I; + unsigned Size = 0; + int Count = GetDeferredOpCount (); + + /* Nothing to be done */ + if (Count <= 0) { + return; + } + + /* Backup some regs/processor flags around the inc/dec */ + if ((Flags & SQP_KEEP_TEST) != 0 && ED_NeedsTest (Expr)) { + /* Sufficient to add a pair of PHP/PLP for all cases */ + AddCodeLine ("php"); + } + + /* Backup the content of EAX around the inc/dec */ + if ((Flags & SQP_KEEP_EAX) != 0 && ED_NeedsPrimary (Expr)) { + /* Get the size */ + Size = CheckedSizeOf (Expr->Type); + + if (Size < 2) { + AddCodeLine ("pha"); + } else if (Size < 3) { + AddCodeLine ("sta regsave"); + AddCodeLine ("stx regsave+1"); + } else { + AddCodeLine ("jsr saveeax"); + } + } + + for (I = 0; I < Count; ++I) { + DeferredOp* Op = CollAtUnchecked (&DeferredOps, I); + switch (Op->OpType) { + + case DOT_INC: + DeferredInc (&Op->Expr); + break; + + case DOT_DEC: + DeferredDec (&Op->Expr); + break; + } + xfree (&Op->Expr); + } + CollDeleteAll (&DeferredOps); + + /* Restore the content of EAX around the inc/dec */ + if ((Flags & SQP_KEEP_EAX) != 0 && ED_NeedsPrimary (Expr)) { + if (Size < 2) { + AddCodeLine ("pla"); + } else if (Size < 3) { + AddCodeLine ("lda regsave"); + AddCodeLine ("ldx regsave+1"); + } else { + AddCodeLine ("jsr resteax"); + } + } + + /* Restore the regs/processor flags around the inc/dec */ + if ((Flags & SQP_KEEP_TEST) != 0 && ED_NeedsTest (Expr)) { + /* Sufficient to pop the processor flags */ + AddCodeLine ("plp"); + } +} + + static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) /* Parse a function parameter list, and pass the arguments to the called ** function. Depending on several criteria, this may be done by just pushing @@ -388,11 +646,17 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) } } + /* The info of the last argument could be needed out of the loop */ + ExprDesc Expr; + ED_Init (&Expr); + Expr.Flags |= ED->Flags & E_MASK_KEEP_SUBEXPR; + /* Parse the actual argument list */ while (CurTok.Tok != TOK_RPAREN) { unsigned Flags; /* Code generator flags, not expression flags */ - ExprDesc Expr; + + /* This way the info of the last parameter won't be cleared */ ED_Init (&Expr); Expr.Flags |= ED->Flags & E_MASK_KEEP_SUBEXPR; @@ -514,6 +778,11 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) Error ("Too few arguments in function call"); } + /* Append deferred inc/dec before the function is called. + ** The last parameter needs to be restored if it is passed with AX/EAX Regs. + */ + DoDeferred (IsFastcall ? SQP_KEEP_EAX : SQP_KEEP_NONE, &Expr); + /* The function returns the size of all arguments pushed onto the stack. ** However, if there are parameters missed (which is an error, and was ** flagged by the compiler), AND a stack frame was preallocated above, @@ -1728,7 +1997,7 @@ static void PreDec (ExprDesc* Expr) static void PostInc (ExprDesc* Expr) /* Handle the postincrement operator */ { - unsigned Flags; + unsigned Flags, Loc; NextToken (); @@ -1746,33 +2015,49 @@ static void PostInc (ExprDesc* Expr) /* Get the data type */ Flags = TypeOf (Expr->Type); + /* We are allowed by the C standard to defer the inc operation until + ** the this expression is used, so that we don't need to save and reload + ** the original value. + */ + /* Emit smaller code if a char variable is at a constant location */ - if ((Flags & CF_CHAR) == CF_CHAR && ED_IsLocConst(Expr)) { + if ((Flags & CF_CHAR) == CF_CHAR && ED_IsLocConst (Expr)) { LoadExpr (CF_NONE, Expr); - AddCodeLine ("inc %s", ED_GetLabelName(Expr, 0)); + AddCodeLine ("inc %s", ED_GetLabelName (Expr, 0)); } else { - /* Push the address if needed */ - PushAddr (Expr); + Loc = ED_GetLoc (Expr); + if (Loc == E_LOC_PRIMARY || Loc == E_LOC_EXPR) { + /* Push the address if needed */ + PushAddr (Expr); - /* Fetch the value and save it (since it's the result of the expression) */ - LoadExpr (CF_NONE, Expr); - g_save (Flags | CF_FORCECHAR); + /* Fetch the value and save it (since it's the result of the expression) */ + LoadExpr (CF_NONE, Expr); + g_save (Flags | CF_FORCECHAR); + + /* If we have a pointer expression, increment by the size of the type */ + if (IsTypePtr (Expr->Type)) { + g_inc (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1)); + } else { + g_inc (Flags | CF_CONST | CF_FORCECHAR, 1); + } + + /* Store the result back */ + Store (Expr, 0); + + /* Restore the original value in the primary register */ + g_restore (Flags | CF_FORCECHAR); - /* If we have a pointer expression, increment by the size of the type */ - if (IsTypePtr (Expr->Type)) { - g_inc (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1)); } else { - g_inc (Flags | CF_CONST | CF_FORCECHAR, 1); + + /* Fetch the value and use it (since it's the result of the expression) */ + LoadExpr (CF_NONE, Expr); + + /* Defer the increment until the value of this expression is used */; + DeferInc (Expr); } - - /* Store the result back */ - Store (Expr, 0); - - /* Restore the original value in the primary register */ - g_restore (Flags | CF_FORCECHAR); } /* The result is always an expression, no reference */ @@ -1784,7 +2069,7 @@ static void PostInc (ExprDesc* Expr) static void PostDec (ExprDesc* Expr) /* Handle the postdecrement operator */ { - unsigned Flags; + unsigned Flags, Loc; NextToken (); @@ -1803,32 +2088,43 @@ static void PostDec (ExprDesc* Expr) Flags = TypeOf (Expr->Type); /* Emit smaller code if a char variable is at a constant location */ - if ((Flags & CF_CHAR) == CF_CHAR && ED_IsLocConst(Expr)) { + if ((Flags & CF_CHAR) == CF_CHAR && ED_IsLocConst (Expr)) { LoadExpr (CF_NONE, Expr); - AddCodeLine ("dec %s", ED_GetLabelName(Expr, 0)); + AddCodeLine ("dec %s", ED_GetLabelName (Expr, 0)); } else { - /* Push the address if needed */ - PushAddr (Expr); + Loc = ED_GetLoc (Expr); + if (Loc == E_LOC_PRIMARY || Loc == E_LOC_EXPR) { + /* Push the address if needed */ + PushAddr (Expr); - /* Fetch the value and save it (since it's the result of the expression) */ - LoadExpr (CF_NONE, Expr); - g_save (Flags | CF_FORCECHAR); + /* Fetch the value and save it (since it's the result of the expression) */ + LoadExpr (CF_NONE, Expr); + g_save (Flags | CF_FORCECHAR); + + /* If we have a pointer expression, increment by the size of the type */ + if (IsTypePtr (Expr->Type)) { + g_dec (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1)); + } else { + g_dec (Flags | CF_CONST | CF_FORCECHAR, 1); + } + + /* Store the result back */ + Store (Expr, 0); + + /* Restore the original value in the primary register */ + g_restore (Flags | CF_FORCECHAR); - /* If we have a pointer expression, increment by the size of the type */ - if (IsTypePtr (Expr->Type)) { - g_dec (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1)); } else { - g_dec (Flags | CF_CONST | CF_FORCECHAR, 1); + + /* Fetch the value and save it (since it's the result of the expression) */ + LoadExpr (CF_NONE, Expr); + + /* Defer the decrement until the value of this expression is used */; + DeferDec (Expr); } - - /* Store the result back */ - Store (Expr, 0); - - /* Restore the original value in the primary register */ - g_restore (Flags | CF_FORCECHAR); } /* The result is always an expression, no reference */ @@ -3263,6 +3559,9 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) /* Load the value */ LoadExpr (CF_FORCECHAR, Expr); + /* Append deferred inc/dec at sequence point */ + DoDeferred (SQP_KEEP_TEST, Expr); + /* Clear the test flag */ ED_RequireNoTest (Expr); @@ -3275,9 +3574,17 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) /* Generate the jump */ g_falsejump (CF_NONE, FalseLab); - } else if (Expr->IVal == 0 && !ED_IsAddrExpr (Expr)) { - /* Skip remaining */ - Flags |= E_EVAL_UNEVAL; + } else { + /* Constant boolean subexpression could still have deferred inc/dec + ** operations, so just flush their side-effects at this sequence + ** point. + */ + DoDeferred (SQP_KEEP_NONE, Expr); + + if (Expr->IVal == 0 && !ED_IsAddrExpr (Expr)) { + /* Skip remaining */ + Flags |= E_EVAL_UNEVAL; + } } } @@ -3306,6 +3613,9 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) ED_RequireTest (&Expr2); LoadExpr (CF_FORCECHAR, &Expr2); + /* Append deferred inc/dec at sequence point */ + DoDeferred (SQP_KEEP_TEST, &Expr2); + /* Do short circuit evaluation */ if (CurTok.Tok == TOK_BOOL_AND) { if (HasFalseJump == 0) { @@ -3319,11 +3629,19 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) /* We need the true label for the last expression */ HasTrueJump = 1; } - } else if (Expr2.IVal == 0 && !ED_IsAddrExpr (&Expr2)) { - /* Skip remaining */ - Flags |= E_EVAL_UNEVAL; - /* The value of the expression will be false */ - ED_MakeConstBool (Expr, 0); + } else { + /* Constant boolean subexpression could still have deferred inc/ + ** dec operations, so just flush their side-effects at this + ** sequence point. + */ + DoDeferred (SQP_KEEP_NONE, &Expr2); + + if (Expr2.IVal == 0 && !ED_IsAddrExpr (&Expr2)) { + /* Skip remaining */ + Flags |= E_EVAL_UNEVAL; + /* The value of the expression will be false */ + ED_MakeConstBool (Expr, 0); + } } } } @@ -3408,6 +3726,9 @@ static void hieOr (ExprDesc *Expr) /* Get first expr */ LoadExpr (CF_FORCECHAR, Expr); + + /* Append deferred inc/dec at sequence point */ + DoDeferred (SQP_KEEP_TEST, Expr); /* Clear the test flag */ ED_RequireNoTest (Expr); @@ -3421,9 +3742,17 @@ static void hieOr (ExprDesc *Expr) /* Jump to TrueLab if true */ g_truejump (CF_NONE, TrueLab); } - } else if (Expr->IVal != 0 || ED_IsAddrExpr (Expr)) { - /* Skip remaining */ - Flags |= E_EVAL_UNEVAL; + } else { + /* Constant boolean subexpression could still have deferred inc/dec + ** operations, so just flush their side-effects at this sequence + ** point. + */ + DoDeferred (SQP_KEEP_NONE, Expr); + + if (Expr->IVal != 0 || ED_IsAddrExpr (Expr)) { + /* Skip remaining */ + Flags |= E_EVAL_UNEVAL; + } } } @@ -3456,17 +3785,28 @@ static void hieOr (ExprDesc *Expr) ED_RequireTest (&Expr2); LoadExpr (CF_FORCECHAR, &Expr2); + /* Append deferred inc/dec at sequence point */ + DoDeferred (SQP_KEEP_TEST, &Expr2); + if (HasTrueJump == 0) { TrueLab = GetLocalLabel(); HasTrueJump = 1; } g_truejump (CF_NONE, TrueLab); } - } else if (Expr2.IVal != 0 || ED_IsAddrExpr (&Expr2)) { - /* Skip remaining */ - Flags |= E_EVAL_UNEVAL; - /* The result is always true */ - ED_MakeConstBool (Expr, 1); + } else { + /* Constant boolean subexpression could still have deferred inc/ + ** dec operations, so just flush their side-effects at this + ** sequence point. + */ + DoDeferred (SQP_KEEP_NONE, &Expr2); + + if (Expr2.IVal != 0 || ED_IsAddrExpr (&Expr2)) { + /* Skip remaining */ + Flags |= E_EVAL_UNEVAL; + /* The result is always true */ + ED_MakeConstBool (Expr, 1); + } } } @@ -3547,11 +3887,22 @@ static void hieQuest (ExprDesc* Expr) /* Condition codes not set, request a test */ ED_RequireTest (Expr); LoadExpr (CF_NONE, Expr); + + /* Append deferred inc/dec at sequence point */ + DoDeferred (SQP_KEEP_TEST, Expr); + FalseLab = GetLocalLabel (); g_falsejump (CF_NONE, FalseLab); - } else if (Expr->IVal == 0) { - /* Remember the current code position */ - GetCodePos (&SkippedBranch); + } else { + /* Constant boolean subexpression could still have deferred inc/dec + ** operations, so just flush their side-effects at this sequence point. + */ + DoDeferred (SQP_KEEP_NONE, Expr); + + if (Expr->IVal == 0) { + /* Remember the current code position */ + GetCodePos (&SkippedBranch); + } } /* Parse second expression. Remember for later if it is a NULL pointer @@ -3563,7 +3914,17 @@ static void hieQuest (ExprDesc* Expr) if (!ConstantCond || !ED_IsConst (&Expr2)) { /* Load it into the primary */ LoadExpr (CF_NONE, &Expr2); + + /* Append deferred inc/dec at sequence point */ + DoDeferred (SQP_KEEP_EXPR, &Expr2); + ED_FinalizeRValLoad (&Expr2); + } else { + /* Constant boolean subexpression could still have deferred inc/ + ** dec operations, so just flush their side-effects at this + ** sequence point. + */ + DoDeferred (SQP_KEEP_NONE, &Expr2); } Expr2.Type = PtrConversion (Expr2.Type); } @@ -3601,7 +3962,17 @@ static void hieQuest (ExprDesc* Expr) if (!ConstantCond || !ED_IsConst (&Expr3)) { /* Load it into the primary */ LoadExpr (CF_NONE, &Expr3); + + /* Append deferred inc/dec at sequence point */ + DoDeferred (SQP_KEEP_EXPR, &Expr3); + ED_FinalizeRValLoad (&Expr3); + } else { + /* Constant boolean subexpression could still have deferred inc/ + ** dec operations, so just flush their side-effects at this + ** sequence point. + */ + DoDeferred (SQP_KEEP_NONE, &Expr3); } Expr3.Type = PtrConversion (Expr3.Type); } @@ -4011,6 +4382,9 @@ void hie0 (ExprDesc *Expr) hie1 (Expr); while (CurTok.Tok == TOK_COMMA) { + /* Append deferred inc/dec at sequence point */ + DoDeferred (SQP_KEEP_NONE, Expr); + /* If the expression didn't generate code or isn't cast to type void, ** emit a warning. */ @@ -4037,7 +4411,9 @@ void hie0 (ExprDesc *Expr) void Expression0 (ExprDesc* Expr) -/* Evaluate an expression via hie0 and put the result into the primary register */ +/* Evaluate an expression via hie0 and put the result into the primary register. +** The expression is completely evaluated and all side effects complete. +*/ { unsigned Flags = Expr->Flags & E_MASK_KEEP_RESULT; @@ -4051,6 +4427,9 @@ void Expression0 (ExprDesc* Expr) if (ED_YetToLoad (Expr)) { LoadExpr (CF_NONE, Expr); } + + /* Append deferred inc/dec at sequence point */ + DoDeferred (SQP_KEEP_EXPR, Expr); } diff --git a/src/cc65/expr.h b/src/cc65/expr.h index 806a376bb..d0a9988af 100644 --- a/src/cc65/expr.h +++ b/src/cc65/expr.h @@ -17,6 +17,19 @@ +/*****************************************************************************/ +/* data */ +/*****************************************************************************/ + + + +#define SQP_KEEP_NONE 0x00 +#define SQP_KEEP_TEST 0x01U +#define SQP_KEEP_EAX 0x02U +#define SQP_KEEP_EXPR 0x03U /* SQP_KEEP_TEST | SQP_KEEP_EAX */ + + + /*****************************************************************************/ /* code */ /*****************************************************************************/ @@ -38,6 +51,23 @@ void PushAddr (const ExprDesc* Expr); ** must be saved if it's not constant, before evaluating the rhs. */ +void InitDeferredOps (void); +/* Init the collection for storing deferred ops */ + +void DoneDeferredOps (void); +/* Deinit the collection for storing deferred ops */ + +int GetDeferredOpCount (void); +/* Return how many deferred operations are still waiting in the queque */ + +void CheckDeferredOpAllDone (void); +/* Check if all deferred operations are done at sequence points. +** Die off if check fails. +*/ + +void DoDeferred (unsigned Flags, ExprDesc* Expr); +/* Do deferred operations such as post-inc/dec at sequence points */ + void Store (ExprDesc* Expr, const Type* StoreType); /* Store the primary register into the location denoted by lval. If StoreType ** is given, use this type when storing instead of lval->Type. If StoreType @@ -52,7 +82,9 @@ int evalexpr (unsigned flags, void (*Func) (ExprDesc*), ExprDesc* Expr); */ void Expression0 (ExprDesc* Expr); -/* Evaluate an expression via hie0 and put the result into the primary register */ +/* Evaluate an expression via hie0 and put the result into the primary register. +** The expression is completely evaluated and all side effects complete. +*/ void BoolExpr (void (*Func) (ExprDesc*), ExprDesc* Expr); /* Will evaluate an expression via the given function. If the result is not diff --git a/src/cc65/goto.c b/src/cc65/goto.c index 06364068f..7d3ff1a6a 100644 --- a/src/cc65/goto.c +++ b/src/cc65/goto.c @@ -105,6 +105,9 @@ void GotoStatement (void) val = (unsigned char)CurTok.IVal; NextToken (); + /* Append deferred inc/dec at sequence point */ + DoDeferred (SQP_KEEP_NONE, &desc); + if (CPUIsets[CPU] & CPU_ISET_65SC02) { AddCodeLine ("ldx #$%02X", val * 2); AddCodeLine ("jmp (.loword(%s),x)", arr->AsmName); @@ -118,6 +121,10 @@ void GotoStatement (void) (idx = FindSym (CurTok.Ident))) { hie10 (&desc); LoadExpr (CF_NONE, &desc); + + /* Append deferred inc/dec at sequence point */ + DoDeferred (SQP_KEEP_EAX, &desc); + AddCodeLine ("asl a"); if (CPUIsets[CPU] & CPU_ISET_65SC02) { diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 81d0cea09..7812acebd 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -165,6 +165,8 @@ static void ParseRegisterDecl (Declaration* Decl, int Reg) /* Store the value into the variable */ g_putstatic (CF_REGVAR | TypeOf (Sym->Type), Reg, 0); + /* This has to be done at sequence point */ + DoDeferred (SQP_KEEP_NONE, &Expr); } /* Mark the variable as referenced */ @@ -273,6 +275,8 @@ static void ParseAutoDecl (Declaration* Decl) /* Push the value */ g_push (Flags | TypeOf (Sym->Type), Expr.IVal); + /* This has to be done at sequence point */ + DoDeferred (SQP_KEEP_NONE, &Expr); } /* Mark the variable as referenced */ @@ -349,6 +353,9 @@ static void ParseAutoDecl (Declaration* Decl) /* Store the value into the variable */ g_putstatic (CF_STATIC | TypeOf (Sym->Type), DataLabel, 0); + + /* This has to be done at sequence point */ + DoDeferred (SQP_KEEP_NONE, &Expr); } /* Mark the variable as referenced */ @@ -525,6 +532,9 @@ static void ParseOneDecl (const DeclSpec* Spec) } } + + /* Make sure we aren't missing some work */ + CheckDeferredOpAllDone (); } diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 74579212e..c1fb6c735 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -245,6 +245,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) LoadExpr (CF_NONE, &Arg3.Expr); } + /* We still need to append deferred inc/dec before calling into the function */ + DoDeferred (SQP_KEEP_EAX, &Arg3.Expr); + /* Emit the actual function call. This will also cleanup the stack. */ g_call (CF_FIXARGC, Func_memcpy, ParamSize); @@ -594,6 +597,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) LoadExpr (CF_NONE, &Arg3.Expr); } + /* We still need to append deferred inc/dec before calling into the function */ + DoDeferred (SQP_KEEP_EAX, &Arg3.Expr); + /* Emit the actual function call. This will also cleanup the stack. */ g_call (CF_FIXARGC, MemSet? Func_memset : Func__bzero, ParamSize); @@ -808,6 +814,9 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) LoadExpr (CF_NONE, &Arg2.Expr); } + /* We still need to append deferred inc/dec before calling into the function */ + DoDeferred (SQP_KEEP_EAX, &Arg2.Expr); + /* Emit the actual function call. This will also cleanup the stack. */ g_call (CF_FIXARGC, Func_strcmp, ParamSize); @@ -1007,6 +1016,9 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) LoadExpr (CF_NONE, &Arg2.Expr); } + /* We still need to append deferred inc/dec before calling into the function */ + DoDeferred (SQP_KEEP_EAX, &Arg2.Expr); + /* Emit the actual function call. This will also cleanup the stack. */ g_call (CF_FIXARGC, Func_strcpy, ParamSize); @@ -1193,6 +1205,9 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Evaluate the parameter */ hie1 (&Arg); + /* We still need to append deferred inc/dec before calling into the function */ + DoDeferred (SQP_KEEP_EAX, &Arg); + /* Check if the argument is an array. If so, remember the element count. ** Otherwise set the element count to undefined. */ diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 74b841493..9890c5467 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -352,6 +352,9 @@ static void ReturnStatement (void) LoadExpr (CF_NONE, &Expr); } } + + /* Append deferred inc/dec at sequence point */ + DoDeferred (SQP_KEEP_EAX, &Expr); } } else if (!F_HasVoidReturn (CurrentFunc) && !F_HasOldStyleIntRet (CurrentFunc)) { diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 80fe4bc3d..eefaeb74a 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -66,6 +66,9 @@ unsigned Test (unsigned Label, int Invert) /* Check for a constant expression */ if (ED_IsConstAbs (&Expr)) { + /* Append deferred inc/dec at sequence point */ + DoDeferred (SQP_KEEP_NONE, &Expr); + /* Result is constant, so we know the outcome */ Result = (Expr.IVal != 0); @@ -79,6 +82,9 @@ unsigned Test (unsigned Label, int Invert) } else if (ED_IsAddrExpr (&Expr)) { + /* Append deferred inc/dec at sequence point */ + DoDeferred (SQP_KEEP_NONE, &Expr); + /* Object addresses are non-NULL */ Result = 1; @@ -93,6 +99,9 @@ unsigned Test (unsigned Label, int Invert) /* Load the value into the primary register */ LoadExpr (CF_FORCECHAR, &Expr); + /* Append deferred inc/dec at sequence point */ + DoDeferred (SQP_KEEP_TEST, &Expr); + /* Generate the jump */ if (Invert) { g_truejump (CF_NONE, Label); From 947dd9aca040076b3b073ce43951875a31dc48da Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 22 Oct 2020 08:54:07 +0200 Subject: [PATCH 1763/2161] Adjusted ChkDkGEOS. --- doc/geos.sgml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/geos.sgml b/doc/geos.sgml index ec9d66b1a..a10ade5d5 100644 --- a/doc/geos.sgml +++ b/doc/geos.sgml @@ -722,9 +722,9 @@ disk. Otherwise they will be lost. Operating area is the <tt/curDirHead/. This function returns the number of free blocks on the current disk. It is counted using data in <tt/curDirHead/ so you must initialize the disk before calling it. -<sect3>ChkDskGEOS +<sect3>ChkDkGEOS <p> -<tt/char ChkDskGEOS (void)/ +<tt/char ChkDkGEOS (void)/ <p> This functions checks <tt/curDirHead/ for the GEOS Format identifier. It returns either true or false, and also sets <tt/isGEOS/ properly. You must initialize the disk before using this. @@ -987,7 +987,7 @@ a particular file. <p> In GEOS there can be only one file opened at a time. Upon opening a VLIR file some information about it is copied into memory. You can retrieve the records table at <tt/fileTrScTab/ (table of -128 <tt/struct tr_se/) and from <tt/VLIRInfo/ (<tt/struct VLIR_info/. +128 <tt/struct tr_se/) and from <tt/VLIRInfo/ (<tt/struct VLIR_info/). E.g. the size of whole VLIR file can be retrieved by reading <tt/VLIRInfo.fileSize/. <sect3>OpenRecordFile From 8e685a00717348d5b1af9cac180269b15fa25b71 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 23 Oct 2020 18:35:14 +0200 Subject: [PATCH 1764/2161] Mention recursion. --- doc/cc65.sgml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 578217307..115f0a30c 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -446,10 +446,10 @@ Here is a description of all the command line options: Use static storage for local variables instead of storage on the stack. Since the stack is emulated in software, this gives shorter and usually - faster code, but the code is no longer reentrant. The difference between - <tt/-Cl/ and declaring local variables as static yourself is, that - initializer code is executed each time, the function is entered. So when - using + faster code, but the code is no longer reentrant as required for recursion. + The difference between <tt/-Cl/ and declaring local variables as static + yourself is, that initializer code is executed each time, the function is + entered. So when using <tscreen><verb> void f (void) From b8889bf37ecffce7946917bb6291d983fcc2d0ce Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Fri, 23 Oct 2020 23:47:30 +0200 Subject: [PATCH 1765/2161] Now getchar works --- libsrc/telestrat/read.s | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/libsrc/telestrat/read.s b/libsrc/telestrat/read.s index 76de9d0ac..0782c4d21 100644 --- a/libsrc/telestrat/read.s +++ b/libsrc/telestrat/read.s @@ -8,21 +8,33 @@ .include "zeropage.inc" .include "telestrat.inc" + .include "fcntl.inc" ;int read (int fd, void* buf, unsigned count); .proc _read - sta ptr1 ; count - stx ptr1+1 ; count - jsr popax ; get buf + sta ptr1 ; count + stx ptr1+1 ; count + jsr popax ; get buf sta PTR_READ_DEST stx PTR_READ_DEST+1 - sta ptr2 ; in order to calculate nb of bytes read + sta ptr2 ; in order to calculate nb of bytes read stx ptr2+1 ; - ; jsr popax ; fp pointer don't care in this version + jsr popax ; fp pointer don't care in this version + cpx #$00 + bne @is_not_stdin + cmp #STDIN_FILENO + bne @is_not_stdin + ; stdin +@L1: + BRK_TELEMON XRD0 ; waits until key is pressed + bcs @L1 + + rts +@is_not_stdin: lda ptr1 ; ldy ptr1+1 ; BRK_TELEMON XFREAD ; calls telemon30 routine From 2fcd8b934ac4cbc577a02a83cc4c83f9f90d7561 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 24 Oct 2020 13:55:10 +0200 Subject: [PATCH 1766/2161] Made HGR segment obligatory. Requiring the HGR segment makes the configs a little less flexible, but for the intended use case the HGR segment actually is necessary. And as we learned now, making the HGR segment obligatory helps users to not shoot themselves in the foot. --- cfg/apple2-hgr.cfg | 4 ++-- cfg/apple2enh-hgr.cfg | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cfg/apple2-hgr.cfg b/cfg/apple2-hgr.cfg index 3ccf7b6f3..cfe577e00 100644 --- a/cfg/apple2-hgr.cfg +++ b/cfg/apple2-hgr.cfg @@ -23,8 +23,8 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro, optional = yes; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; - HGR: load = MAIN, type = rw, optional = yes, start = $2000; - CODE: load = MAIN, type = ro start = $4000; + HGR: load = MAIN, type = rw, start = $2000; + CODE: load = MAIN, type = ro start = $4000; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; INIT: load = MAIN, type = rw; diff --git a/cfg/apple2enh-hgr.cfg b/cfg/apple2enh-hgr.cfg index 3ccf7b6f3..cfe577e00 100644 --- a/cfg/apple2enh-hgr.cfg +++ b/cfg/apple2enh-hgr.cfg @@ -23,8 +23,8 @@ SEGMENTS { EXEHDR: load = HEADER, type = ro, optional = yes; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; - HGR: load = MAIN, type = rw, optional = yes, start = $2000; - CODE: load = MAIN, type = ro start = $4000; + HGR: load = MAIN, type = rw, start = $2000; + CODE: load = MAIN, type = ro start = $4000; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; INIT: load = MAIN, type = rw; From 07cc6a3d208b28ba6bcb42f9a02b8cb765c61bd8 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 18 Sep 2020 20:23:02 +0800 Subject: [PATCH 1767/2161] Made optimization steps aware of long branches better. --- src/cc65/coptcmp.c | 4 +++- src/cc65/coptptrload.c | 2 +- src/cc65/coptshift.c | 5 ++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/cc65/coptcmp.c b/src/cc65/coptcmp.c index a4a8c6a9b..fda23ae0a 100644 --- a/src/cc65/coptcmp.c +++ b/src/cc65/coptcmp.c @@ -944,7 +944,9 @@ unsigned OptCmp9 (CodeSeg* S) if (L[0]->OPC == OP65_SBC && CS_GetEntries (S, L+1, I+1, 4) && (L[1]->OPC == OP65_BVC || - L[1]->OPC == OP65_BVS) && + L[1]->OPC == OP65_BVS || + L[1]->OPC == OP65_JVC || + L[1]->OPC == OP65_JVS) && L[1]->JumpTo != 0 && L[1]->JumpTo->Owner == L[3] && L[2]->OPC == OP65_EOR && diff --git a/src/cc65/coptptrload.c b/src/cc65/coptptrload.c index 0534a1fa2..046e65d79 100644 --- a/src/cc65/coptptrload.c +++ b/src/cc65/coptptrload.c @@ -988,7 +988,7 @@ unsigned OptPtrLoad12 (CodeSeg* S) L[4]->OPC == OP65_CLC && L[5]->OPC == OP65_ADC && CE_IsKnownImm (L[5], 1) && - L[6]->OPC == OP65_BCC && + (L[6]->OPC == OP65_BCC || L[6]->OPC == OP65_JCC) && L[6]->JumpTo != 0 && L[6]->JumpTo->Owner == L[8] && L[7]->OPC == OP65_INX && diff --git a/src/cc65/coptshift.c b/src/cc65/coptshift.c index 92210ebb5..aef3f64bc 100644 --- a/src/cc65/coptshift.c +++ b/src/cc65/coptshift.c @@ -341,7 +341,10 @@ unsigned OptShift2 (CodeSeg* S) L[0] = CS_GetEntry (S, I); /* Check for the sequence */ - if ((L[0]->OPC == OP65_BPL || L[0]->OPC == OP65_BCC) && + if ((L[0]->OPC == OP65_BPL || + L[0]->OPC == OP65_BCC || + L[0]->OPC == OP65_JPL || + L[0]->OPC == OP65_JCC) && L[0]->JumpTo != 0 && CS_GetEntries (S, L+1, I+1, 3) && L[1]->OPC == OP65_DEX && From f723147f04f19ddc7e39bad9211a6f26082ffbc5 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 25 Oct 2020 14:06:44 +0100 Subject: [PATCH 1768/2161] Streamlined clock rate handling. * Docs say that CLK_TCK is an obsolete alias of CLOCKS_PER_SEC so there's no point in individual definitions. * All targets determining the clock rate at runtime can use a common handling. --- include/time.h | 46 ++++++++++++---------------------------- libsrc/atari/clock.s | 8 ++++--- libsrc/atari5200/clock.s | 1 - libsrc/lynx/clock.s | 14 +++++------- 4 files changed, 24 insertions(+), 45 deletions(-) diff --git a/include/time.h b/include/time.h index 4ee658da9..49d7e6870 100644 --- a/include/time.h +++ b/include/time.h @@ -83,46 +83,31 @@ extern struct _timezone { -#if defined(__ATARI__) -/* The clock depends on the video standard, so read it at runtime */ -unsigned _clocks_per_sec (void); -# define CLK_TCK _clocks_per_sec() -# define CLOCKS_PER_SEC _clocks_per_sec() -#elif defined(__ATARI5200__) -# define CLK_TCK 60 /* POSIX */ -# define CLOCKS_PER_SEC 60 /* ANSI */ +#if defined(__ATARI5200__) +# define CLOCKS_PER_SEC 60 #elif defined(__ATMOS__) -# define CLK_TCK 100 /* POSIX */ -# define CLOCKS_PER_SEC 100 /* ANSI */ +# define CLOCKS_PER_SEC 100 #elif defined(__CBM__) # if defined(__CBM510__) || defined(__CBM610__) /* The 510/610 gets its clock from the AC current */ -# define CLK_TCK 50 /* POSIX */ -# define CLOCKS_PER_SEC 50 /* ANSI */ +# define CLOCKS_PER_SEC 50 # else -# define CLK_TCK 60 /* POSIX */ -# define CLOCKS_PER_SEC 60 /* ANSI */ +# define CLOCKS_PER_SEC 60 # endif #elif defined(__NES__) -# define CLK_TCK 50 /* POSIX */ -# define CLOCKS_PER_SEC 50 /* ANSI */ +# define CLOCKS_PER_SEC 50 #elif defined(__PCE__) -# define CLK_TCK 60 /* POSIX */ -# define CLOCKS_PER_SEC 60 /* ANSI */ +# define CLOCKS_PER_SEC 60 #elif defined(__GAMATE__) -# define CLK_TCK 135 /* POSIX */ /* FIXME */ -# define CLOCKS_PER_SEC 135 /* ANSI */ /* FIXME */ +# define CLOCKS_PER_SEC 135 /* FIXME */ #elif defined(__GEOS__) -# define CLK_TCK 1 /* POSIX */ -# define CLOCKS_PER_SEC 1 /* ANSI */ -#elif defined(__LYNX__) -/* The clock-rate depends on the video scan-rate; -** so, read it at run-time. -*/ -extern clock_t _clk_tck (void); -# define CLK_TCK _clk_tck() -# define CLOCKS_PER_SEC _clk_tck() +# define CLOCKS_PER_SEC 1 +#else +/* Read the clock rate at runtime */ +clock_t _clocks_per_sec (void); +# define CLOCKS_PER_SEC _clocks_per_sec() #endif +#define CLK_TCK CLOCKS_PER_SEC #define CLOCK_REALTIME 0 @@ -149,6 +134,3 @@ int __fastcall__ clock_settime (clockid_t clock_id, const struct timespec *tp); /* End of time.h */ #endif - - - diff --git a/libsrc/atari/clock.s b/libsrc/atari/clock.s index e04416c18..853870520 100644 --- a/libsrc/atari/clock.s +++ b/libsrc/atari/clock.s @@ -3,7 +3,7 @@ ; originally by Ullrich von Bassewitz and Sidney Cadot ; ; clock_t clock (void); -; unsigned _clocks_per_sec (void); +; clock_t _clocks_per_sec (void); ; .export _clock, __clocks_per_sec @@ -30,8 +30,10 @@ .proc __clocks_per_sec - ldx #$00 ; Clear high byte of return value - lda PAL ; use hw register, PALNTS is only supported on XL/XE ROM + ldx #$00 ; Clear byte 1 of return value + stx sreg ; Clear byte 2 of return value + stx sreg+1 ; Clear byte 3 of return value + lda PAL ; Use hw register, PALNTS is only supported on XL/XE ROM and #$0e bne @NTSC lda #50 diff --git a/libsrc/atari5200/clock.s b/libsrc/atari5200/clock.s index f2ef85b0b..fff766093 100644 --- a/libsrc/atari5200/clock.s +++ b/libsrc/atari5200/clock.s @@ -2,7 +2,6 @@ ; from Atari computer version by Christian Groessler, 2014 ; ; clock_t clock (void); -; unsigned _clocks_per_sec (void); ; .export _clock diff --git a/libsrc/lynx/clock.s b/libsrc/lynx/clock.s index dbccb32cb..e29799df6 100644 --- a/libsrc/lynx/clock.s +++ b/libsrc/lynx/clock.s @@ -2,18 +2,14 @@ ; 2003-04-13, Ullrich von Bassewitz ; 2012-02-06, Greg King ; -; #include <time.h> +; clock_t clock (void); +; clock_t _clocks_per_sec (void); ; -; typedef unsigned long int clock_t; -; clock_t _clk_tck(void); -; #define CLOCKS_PER_SEC _clk_tck() -; clock_t clock(void); -; -; clk_tck()'s test-values are based on the numbers in "set_tv.s". +; clocks_per_sec()'s test-values are based on the numbers in "set_tv.s". ; If you change the numbers there, then change them here, too. ; - .export _clock, __clk_tck, clock_count + .export _clock, __clocks_per_sec, clock_count .interruptor update_clock, 2 ; (low priority) .constructor init_clock @@ -42,7 +38,7 @@ ;----------------------------------------------------------------------------- ; Return the number of clock ticks in one second. ; -__clk_tck: +__clocks_per_sec: ldx #$00 ; >50, >60, >75 ldy PBKUP lda #<75 From 79cf1e13a7afe1f2bf9e3a0010e9caca776cf347 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 25 Oct 2020 21:33:08 +0100 Subject: [PATCH 1769/2161] Adjusted to recent change in time.h --- samples/mandelbrot.c | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/mandelbrot.c b/samples/mandelbrot.c index 595bcfbbb..519f3d823 100644 --- a/samples/mandelbrot.c +++ b/samples/mandelbrot.c @@ -31,6 +31,7 @@ /* Workaround missing clock stuff */ #ifdef __APPLE2__ # define clock() 0 +# undef CLK_TCK # define CLK_TCK 1 #endif From 353721067470fa1671a0413944dd38b744e9f0bb Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 27 Oct 2020 22:25:58 +0100 Subject: [PATCH 1770/2161] add waitvsync() for atari and atari5200 --- doc/atari.sgml | 1 + doc/atari5200.sgml | 2 +- include/atari.h | 1 + include/atari5200.h | 3 +++ libsrc/atari/waitvsync.s | 15 +++++++++++++++ libsrc/atari5200/waitvsync.s | 15 +++++++++++++++ 6 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 libsrc/atari/waitvsync.s create mode 100644 libsrc/atari5200/waitvsync.s diff --git a/doc/atari.sgml b/doc/atari.sgml index eecd1b803..7fc929f42 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -332,6 +332,7 @@ See the <url url="funcref.html" name="function reference"> for declaration and u <item>_scroll <item>_setcolor <item>_setcolor_low +<item>waitvsync </itemize> diff --git a/doc/atari5200.sgml b/doc/atari5200.sgml index 00d3dfbd2..032b0ef6c 100644 --- a/doc/atari5200.sgml +++ b/doc/atari5200.sgml @@ -77,7 +77,7 @@ Programs containing Atari 5200 specific code may use the <tt/atari5200.h/ header <sect1>Atari 5200 specific functions<p> <itemize> -<item>TBD. +<item>waitvsync </itemize> diff --git a/include/atari.h b/include/atari.h index 1a00a4c67..b2fca0b0e 100644 --- a/include/atari.h +++ b/include/atari.h @@ -227,6 +227,7 @@ extern 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); /* numlines > 0 scrolls up */ diff --git a/include/atari5200.h b/include/atari5200.h index d6c2561b2..9662fe98e 100644 --- a/include/atari5200.h +++ b/include/atari5200.h @@ -89,5 +89,8 @@ extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */ */ #define _bordercolor(color) 0 +extern void waitvsync (void); +/* Wait for start of next frame */ + /* End of atari5200.h */ #endif diff --git a/libsrc/atari/waitvsync.s b/libsrc/atari/waitvsync.s new file mode 100644 index 000000000..a19b2375d --- /dev/null +++ b/libsrc/atari/waitvsync.s @@ -0,0 +1,15 @@ +; +; Written by Christian Groessler <chris@groessler.org> +; +; void waitvsync (void); +; + + .include "atari.inc" + .export _waitvsync + +.proc _waitvsync + lda RTCLOK+2 +@lp: cmp RTCLOK+2 + beq @lp + rts +.endproc diff --git a/libsrc/atari5200/waitvsync.s b/libsrc/atari5200/waitvsync.s new file mode 100644 index 000000000..9a67c6429 --- /dev/null +++ b/libsrc/atari5200/waitvsync.s @@ -0,0 +1,15 @@ +; +; Written by Christian Groessler <chris@groessler.org> +; +; void waitvsync (void); +; + + .include "atari5200.inc" + .export _waitvsync + +.proc _waitvsync + lda RTCLOK+1 +@lp: cmp RTCLOK+1 + beq @lp + rts +.endproc From 262631039dca1c7440457586d3a64d10ae9248db Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 28 Oct 2020 17:37:50 +0100 Subject: [PATCH 1771/2161] atari.h, atari5200.h: style fixes --- include/atari.h | 2 +- include/atari5200.h | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/atari.h b/include/atari.h index b2fca0b0e..f5916a284 100644 --- a/include/atari.h +++ b/include/atari.h @@ -227,7 +227,7 @@ extern unsigned char __fastcall__ _getcolor (unsigned char color_reg); /* Other screen functions */ /*****************************************************************************/ -extern void waitvsync (void); /* Wait for start of next frame */ +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); /* numlines > 0 scrolls up */ diff --git a/include/atari5200.h b/include/atari5200.h index 9662fe98e..a18360c61 100644 --- a/include/atari5200.h +++ b/include/atari5200.h @@ -35,7 +35,7 @@ -/* Check for errors */ +/* check for errors */ #if !defined(__ATARI5200__) # error This module may only be used when compiling for the Atari 5200! #endif @@ -46,14 +46,14 @@ /* the addresses of the static drivers */ extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */ -/* Masks for joy_read */ +/* 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 -/* Character codes */ +/* character codes */ #define CH_ULCORNER 0x0B /* '+' sign */ #define CH_URCORNER 0x0B #define CH_LLCORNER 0x0B @@ -65,7 +65,7 @@ extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */ #define AT_NTSC 0 #define AT_PAL 1 -/* Define hardware */ +/* define hardware */ #include <_gtia.h> #define GTIA_READ (*(struct __gtia_read*)0xC000) #define GTIA_WRITE (*(struct __gtia_write*)0xC000) @@ -89,8 +89,8 @@ extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */ */ #define _bordercolor(color) 0 +/* wait for start of next frame */ extern void waitvsync (void); -/* Wait for start of next frame */ -/* End of atari5200.h */ +/* end of atari5200.h */ #endif From a686988d0ebb0b42d965ed006b9d3a78b78d947c Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Wed, 28 Oct 2020 09:35:49 +0100 Subject: [PATCH 1772/2161] Add test cases for integral promotion of chars Both signed and unsigned chars are promoted to int by C's evaluation rules. It is more efficient to use unsigned operations when possible, however. These tests will help test the correctness of optimizations doing that. See #1308. --- test/val/char-promote.c | 127 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 test/val/char-promote.c diff --git a/test/val/char-promote.c b/test/val/char-promote.c new file mode 100644 index 000000000..1d6360d45 --- /dev/null +++ b/test/val/char-promote.c @@ -0,0 +1,127 @@ +/* + Copyright 2020 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. +*/ + +/* + Tests of promotions of character types. +*/ + +#include <stdio.h> + +typedef unsigned char u8; + +static unsigned char failures = 0; + +void test_sub (void) +{ + const u8 one = 1, two = 2; + + /* For any unsigned type other than unsigned char, (T) 1 - (T) 2 > 0. */ + if (1U - 2U < 0) { + fprintf (stderr, "Expected 1U - 2U > 0\n"); + failures++; + } + + /* The unsigned chars get promoted to int, so this is negative. */ + if (one - two > 0) { + fprintf (stderr, "Expected one - two < 0\n"); + failures++; + } + + /* Test the constant expression code paths. */ + if ((u8) 1 - (u8) 2 > 0) { + fprintf (stderr, "Expected (u8) 1 - (u8) 2 < 0\n"); + failures++; + } +} + +void test_mul (void) +{ + const u8 two_fifty_five = 255; + + if (255U * 255U != 65025U) { + fprintf (stderr, "Expected 255U * 255U == 65025U\n"); + failures++; + } +#if 0 + /* Disabled pending fix of #1310. */ + if (255 * 255 != -511) { + fprintf (stderr, "Expected 255 * 255 == -511, got: %d\n", 255 * 255); + failures++; + } +#endif + + /* The unsigned chars get promoted to int, so this is -511. + ** We should also be able to observe that the generated code uses mul, not umul. + */ + if (two_fifty_five * two_fifty_five != -511) { + fprintf (stderr, "Expected two_fifty_five * two_fifty_five == -511\n"); + failures++; + } +#if 0 + /* Disabled pending fix of #1310. */ + if ((u8) 255 * (u8) 255 != -511) { + fprintf (stderr, "Expected (u8) 255 * (u8) 255 == -511, got: %d\n", + (u8) 255 * (u8) 255); + failures++; + } +#endif +} + +void test_div (void) +{ + const u8 seventeen = 17; + const u8 three = 3; + + /* We should also be able to observe that the generated code uses div, not udiv. */ + if (seventeen / three != 5) { + fprintf (stderr, "Expected seventeen / three == 5, got: %d\n", seventeen / three); + failures++; + } + if ((u8) 17 / (u8) 3 != 5) { + fprintf (stderr, "Expected (u8) 17 / (u8) 3 == 5, got: %d\n", (u8) 17 / (u8) 3); + failures++; + } +} + +void test_shr (void) +{ + const unsigned int forty_two = 42; + const unsigned int two = 2; + + /* We should also be able to observe that the generated code uses asr, not shr. */ + if (forty_two >> two != 10) { + fprintf (stderr, "Expected forty_two / two == 10, got: %d\n", forty_two >> two); + failures++; + } + if ((u8) 42 >> (u8) 2 != 10) { + fprintf (stderr, "Expected (u8) 42 >> (u8) 2 == 10, got: %d\n", (u8) 42 >> (u8) 3); + failures++; + } +} + +int main (void) +{ + test_sub (); + test_mul (); + test_div (); + test_shr (); + printf ("failures: %u\n", failures); + return failures; +} From 944ebbc23cf6d74ffe1f5f1d5a9ca001066d7d23 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 29 Oct 2020 16:19:38 +0100 Subject: [PATCH 1773/2161] atarixl configs: make size of CHARGEN configurable If text mode is not used, its space can be reclaimed by setting __CHARGENSIZE__ to 0. Following a suggestion from issue #1314. --- cfg/atarixl-largehimem.cfg | 33 +++++++++++++++++---------------- cfg/atarixl-overlay.cfg | 37 +++++++++++++++++++------------------ cfg/atarixl-xex.cfg | 21 +++++++++++---------- cfg/atarixl.cfg | 29 +++++++++++++++-------------- 4 files changed, 62 insertions(+), 58 deletions(-) diff --git a/cfg/atarixl-largehimem.cfg b/cfg/atarixl-largehimem.cfg index 56d2af15b..5e60f32bd 100644 --- a/cfg/atarixl-largehimem.cfg +++ b/cfg/atarixl-largehimem.cfg @@ -8,39 +8,40 @@ FEATURES { } SYMBOLS { __EXEHDR__: type = import; - __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk - __AUTOSTART__: type = import; # force inclusion of autostart "trailer" - __STACKSIZE__: type = weak, value = $0800; # 2k stack + __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk + __AUTOSTART__: type = import; # force inclusion of autostart "trailer" + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __CHARGENSIZE__: type = weak, value = $0400; __STARTADDRESS__: type = export, value = %S; } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # just $FFFF - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $0002; # "system check" load chunk - SYSCHKHDR: file = %O, start = $0000, size = $0004; - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; - SYSCHKTRL: file = %O, start = $0000, size = $0006; + SYSCHKHDR: file = %O, start = $0000, size = $0004; + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + SYSCHKTRL: file = %O, start = $0000, size = $0006; # "shadow RAM preparation" load chunk - SRPREPHDR: file = %O, start = $0000, size = $0004; - SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned - SRPREPTRL: file = %O, start = $0000, size = $0006; + SRPREPHDR: file = %O, start = $0000, size = $0004; + SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned + SRPREPTRL: file = %O, start = $0000, size = $0006; # "main program" load chunk - MAINHDR: file = %O, start = $0000, size = $0004; - MAIN: file = %O, define = yes, start = %S + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __LOWBSS_SIZE__; + MAINHDR: file = %O, start = $0000, size = $0004; + MAIN: file = %O, define = yes, start = %S + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __LOWBSS_SIZE__; # defines entry point into program - TRAILER: file = %O, start = $0000, size = $0006; + TRAILER: file = %O, start = $0000, size = $0006; # address of relocated character generator - CHARGEN: file = "", define = yes, start = $D800, size = $0400; + CHARGEN: file = "", define = yes, start = $D800, size = __CHARGENSIZE__; # memory beneath the ROM - HIDDEN_RAM: file = "", define = yes, start = $DC00, size = $FFFA - $DC00; + HIDDEN_RAM: file = "", define = yes, start = $D800 + __CHARGENSIZE__, size = $FFFA - $D800 - __CHARGENSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; diff --git a/cfg/atarixl-overlay.cfg b/cfg/atarixl-overlay.cfg index 923436497..2bb4105cd 100644 --- a/cfg/atarixl-overlay.cfg +++ b/cfg/atarixl-overlay.cfg @@ -3,44 +3,45 @@ FEATURES { } SYMBOLS { __EXEHDR__: type = import; - __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk - __AUTOSTART__: type = import; # force inclusion of autostart "trailer" - __STACKSIZE__: type = weak, value = $0800; # 2k stack - __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay + __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk + __AUTOSTART__: type = import; # force inclusion of autostart "trailer" + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __CHARGENSIZE__: type = weak, value = $0400; + __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay __STARTADDRESS__: type = export, value = %S; } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # just $FFFF - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $0002; # "system check" load chunk - SYSCHKHDR: file = %O, start = $0000, size = $0004; - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; - SYSCHKTRL: file = %O, start = $0000, size = $0006; + SYSCHKHDR: file = %O, start = $0000, size = $0004; + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + SYSCHKTRL: file = %O, start = $0000, size = $0006; # "shadow RAM preparation" load chunk - SRPREPHDR: file = %O, start = $0000, size = $0004; - SRPREPCHNK: file = %O, define = yes, start = %S + __OVERLAYSIZE__, size = $7C20 - %S - __OVERLAYSIZE__ - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned - SRPREPTRL: file = %O, start = $0000, size = $0006; + SRPREPHDR: file = %O, start = $0000, size = $0004; + SRPREPCHNK: file = %O, define = yes, start = %S + __OVERLAYSIZE__, size = $7C20 - %S - __OVERLAYSIZE__ - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned + SRPREPTRL: file = %O, start = $0000, size = $0006; # "main program" load chunk - MAINHDR: file = %O, start = $0000, size = $0004; + MAINHDR: file = %O, start = $0000, size = $0004; MAIN: file = %O, define = yes, start = %S + __OVERLAYSIZE__ + - __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __OVERLAYSIZE__ - __LOWBSS_SIZE__; + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __OVERLAYSIZE__ - __LOWBSS_SIZE__; # defines entry point into program - TRAILER: file = %O, start = $0000, size = $0006; + TRAILER: file = %O, start = $0000, size = $0006; # memory beneath the ROM preceeding the character generator - HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; + HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; # address of relocated character generator (same addess as ROM version) - CHARGEN: file = "", define = yes, start = $E000, size = $0400; + CHARGEN: file = "", define = yes, start = $E000, size = __CHARGENSIZE__; # memory beneath the ROM - HIDDEN_RAM: file = "", define = yes, start = $E400, size = $FFFA - $E400; + HIDDEN_RAM: file = "", define = yes, start = $E000 + __CHARGENSIZE__, size = $FFFA - $E000 - __CHARGENSIZE__; # overlays OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__; diff --git a/cfg/atarixl-xex.cfg b/cfg/atarixl-xex.cfg index 0b1fe9ca1..6b6601c59 100644 --- a/cfg/atarixl-xex.cfg +++ b/cfg/atarixl-xex.cfg @@ -4,35 +4,36 @@ FEATURES { STARTADDRESS: default = $2400; } SYMBOLS { - __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk - __STACKSIZE__: type = weak, value = $0800; # 2k stack + __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk + __STACKSIZE__: type = weak, value = $0800; # 2k stack __STARTADDRESS__: type = export, value = %S; + __CHARGENSIZE__: type = weak, value = $0400; __SYSCHKHDR__: type = export, value = 0; # Disable system check header __SYSCHKTRL__: type = export, value = 0; # Disable system check trailer } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # "system check" load chunk - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; # "shadow RAM preparation" load chunk - SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned + SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned # "main program" load chunk - MAIN: file = %O, define = yes, start = %S + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __LOWBSS_SIZE__; + MAIN: file = %O, define = yes, start = %S + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __LOWBSS_SIZE__; # memory beneath the ROM preceeding the character generator - HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; + HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; # address of relocated character generator (same addess as ROM version) - CHARGEN: file = "", define = yes, start = $E000, size = $0400; + CHARGEN: file = "", define = yes, start = $E000, size = __CHARGENSIZE__; # memory beneath the ROM - HIDDEN_RAM: file = "", define = yes, start = $E400, size = $FFFA - $E400; + HIDDEN_RAM: file = "", define = yes, start = $E000 + __CHARGENSIZE__, size = $FFFA - $E000 - __CHARGENSIZE__; # UNUSED - hide - UNUSED: file = "", start = $0, size = $10; + UNUSED: file = "", start = $0, size = $10; } FILES { %O: format = atari; diff --git a/cfg/atarixl.cfg b/cfg/atarixl.cfg index 197daace6..d4e466ae1 100644 --- a/cfg/atarixl.cfg +++ b/cfg/atarixl.cfg @@ -6,39 +6,40 @@ SYMBOLS { __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk __AUTOSTART__: type = import; # force inclusion of autostart "trailer" __STACKSIZE__: type = weak, value = $0800; # 2k stack + __CHARGENSIZE__: type = weak, value = $0400; __STARTADDRESS__: type = export, value = %S; } MEMORY { - ZP: file = "", define = yes, start = $0082, size = $007E; + ZP: file = "", define = yes, start = $0082, size = $007E; # just $FFFF - HEADER: file = %O, start = $0000, size = $0002; + HEADER: file = %O, start = $0000, size = $0002; # "system check" load chunk - SYSCHKHDR: file = %O, start = $0000, size = $0004; - SYSCHKCHNK: file = %O, start = $2E00, size = $0300; - SYSCHKTRL: file = %O, start = $0000, size = $0006; + SYSCHKHDR: file = %O, start = $0000, size = $0004; + SYSCHKCHNK: file = %O, start = $2E00, size = $0300; + SYSCHKTRL: file = %O, start = $0000, size = $0006; # "shadow RAM preparation" load chunk - SRPREPHDR: file = %O, start = $0000, size = $0004; - SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned - SRPREPTRL: file = %O, start = $0000, size = $0006; + SRPREPHDR: file = %O, start = $0000, size = $0004; + SRPREPCHNK: file = %O, define = yes, start = %S, size = $7C20 - %S - $07FF; # $07FF: space for temp. chargen buffer, 1K aligned + SRPREPTRL: file = %O, start = $0000, size = $0006; # "main program" load chunk - MAINHDR: file = %O, start = $0000, size = $0004; - MAIN: file = %O, define = yes, start = %S + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __LOWBSS_SIZE__; + MAINHDR: file = %O, start = $0000, size = $0004; + MAIN: file = %O, define = yes, start = %S + __LOWBSS_SIZE__, size = $D000 - __STACKSIZE__ - %S - __LOWBSS_SIZE__; # defines entry point into program - TRAILER: file = %O, start = $0000, size = $0006; + TRAILER: file = %O, start = $0000, size = $0006; # memory beneath the ROM preceeding the character generator - HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; + HIDDEN_RAM2: file = "", define = yes, start = $D800, size = $0800; # address of relocated character generator (same addess as ROM version) - CHARGEN: file = "", define = yes, start = $E000, size = $0400; + CHARGEN: file = "", define = yes, start = $E000, size = __CHARGENSIZE__; # memory beneath the ROM - HIDDEN_RAM: file = "", define = yes, start = $E400, size = $FFFA - $E400; + HIDDEN_RAM: file = "", define = yes, start = $E000 + __CHARGENSIZE__, size = $FFFA - $E000 - __CHARGENSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; From d8e6fa61bbcbb86c7bcf287a988f42246f22376f Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 29 Oct 2020 17:42:36 +0100 Subject: [PATCH 1774/2161] Return NULL on error (or end of directory). --- libsrc/geos-common/file/get1stdirentry.s | 8 ++++++-- libsrc/geos-common/file/getnxtdirentry.s | 10 ++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/libsrc/geos-common/file/get1stdirentry.s b/libsrc/geos-common/file/get1stdirentry.s index 3b99554eb..381a35c6d 100644 --- a/libsrc/geos-common/file/get1stdirentry.s +++ b/libsrc/geos-common/file/get1stdirentry.s @@ -5,7 +5,7 @@ ; struct filehandle* Get1stDirEntry (void); - .import __oserror + .import __oserror, return0 .export _Get1stDirEntry .include "diskdrv.inc" @@ -14,6 +14,10 @@ _Get1stDirEntry: jsr Get1stDirEntry stx __oserror - lda r5L + txa + beq L0 ; error? + jmp return0 ; return NULL + +L0: lda r5L ldx r5H rts diff --git a/libsrc/geos-common/file/getnxtdirentry.s b/libsrc/geos-common/file/getnxtdirentry.s index 912f48ca4..16a31edcf 100644 --- a/libsrc/geos-common/file/getnxtdirentry.s +++ b/libsrc/geos-common/file/getnxtdirentry.s @@ -5,7 +5,7 @@ ; struct filehandle* GetNxtDirEntry (void); - .import __oserror + .import __oserror, return0 .export _GetNxtDirEntry .include "diskdrv.inc" @@ -14,6 +14,12 @@ _GetNxtDirEntry: jsr GetNxtDirEntry stx __oserror - lda r5L + txa + beq L0 ; error? + tya + beq L0 ; end of dir? + jmp return0 ; return NULL + +L0: lda r5L ldx r5H rts From aad17a6f057dc57424c010c0d832e1f49592f044 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 29 Oct 2020 17:54:56 -0400 Subject: [PATCH 1775/2161] Made two GEOS directory functions return NULL if they can't give a valid entry. --- doc/geos.sgml | 19 ++++++++++--------- libsrc/geos-common/file/get1stdirentry.s | 12 ++++++------ libsrc/geos-common/file/getnxtdirentry.s | 14 +++++++------- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/doc/geos.sgml b/doc/geos.sgml index a10ade5d5..11ff9c534 100644 --- a/doc/geos.sgml +++ b/doc/geos.sgml @@ -858,20 +858,21 @@ The functions described here are common for SEQ and VLIR structures. <p> <tt/struct filehandle *GetNxtDirEntry (void)/ <p> -These two functions are best suited for scanning the whole directory for particular files. Note that -the returned filehandles describe all file slots in the directory - even those with deleted files. -The return value can be obtained by casting both sides to <tt/unsigned/ - as in the <tt/SetNextFree/ -function or read directly after a call to those two functions from <tt/r5/. The current sector number -is in <tt/r1/ and the sector data itself is in <tt/diskBlkBuf/. +Those two functions are best suited for scanning the whole directory for particular files. Note that +the returned filehandles describe all file slots in the directory -- even those with deleted files. +The return value is <tt/NULL/ if there are no more slots, or if there was a disk error. The +<tt/_oserror/ variable is non-zero if it was a disk error (see <tt>geos/gdisk.h</tt>). The current +directory track and sector numbers are in <tt/r1L/ and <tt/r1H/. The sector data itself is in +<tt/diskBlkBuf/. <sect3>FindFile <p> <tt/char FindFile (char *fName)/ <p> -This function scans the whole directory for the given filename. It returns either 0 (success) or 5 -(FILE_NOT_FOUND, defined in <tt/gdisk.h/) or any other fatal disk read error. After a successful -<tt/FindFile/ you will have <tt/struct filehandle/ at <tt/dirEntryBuf/ filled with the file's data and -other registers set as described in <tt/GetNxtDirEntry/. +This function scans the whole directory for the given filename. It returns either 0 (success), 5 +(FILE_NOT_FOUND, defined in <tt>geos/gdisk.h</tt>), or any other fatal disk read error. After a successful +<tt/FindFile()/, you will have <tt/struct filehandle/ at <tt/dirEntryBuf/ filled with the file's data, and +other registers set as described in <tt/GetNxtDirEntry()/. <sect3>FindFTypes <p> diff --git a/libsrc/geos-common/file/get1stdirentry.s b/libsrc/geos-common/file/get1stdirentry.s index 381a35c6d..f0ad59388 100644 --- a/libsrc/geos-common/file/get1stdirentry.s +++ b/libsrc/geos-common/file/get1stdirentry.s @@ -1,7 +1,7 @@ ; -; Maciej 'YTM/Alliance' Witkowiak +; 1999-10-26, Maciej 'YTM/Alliance' Witkowiak +; 2020-10-29, Greg King ; -; 26.10.99 ; struct filehandle* Get1stDirEntry (void); @@ -15,9 +15,9 @@ _Get1stDirEntry: jsr Get1stDirEntry stx __oserror txa - beq L0 ; error? - jmp return0 ; return NULL - -L0: lda r5L + bne L1 ; jump if disk error + lda r5L ldx r5H rts + +L1: jmp return0 ; return NULL if not valid entry diff --git a/libsrc/geos-common/file/getnxtdirentry.s b/libsrc/geos-common/file/getnxtdirentry.s index 16a31edcf..e8ccbf3a2 100644 --- a/libsrc/geos-common/file/getnxtdirentry.s +++ b/libsrc/geos-common/file/getnxtdirentry.s @@ -1,7 +1,7 @@ ; -; Maciej 'YTM/Alliance' Witkowiak +; 1999-10-26, Maciej 'YTM/Alliance' Witkowiak +; 2020-10-29, Greg King ; -; 26.10.99 ; struct filehandle* GetNxtDirEntry (void); @@ -15,11 +15,11 @@ _GetNxtDirEntry: jsr GetNxtDirEntry stx __oserror txa - beq L0 ; error? + bne L1 ; jump if disk error tya - beq L0 ; end of dir? - jmp return0 ; return NULL - -L0: lda r5L + bne L1 ; jump when no more entries + lda r5L ldx r5H rts + +L1: jmp return0 ; return NULL if not valid entry From 39c0abed549708a127a0211d94aab204dde681c2 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Fri, 30 Oct 2020 15:01:47 +0100 Subject: [PATCH 1776/2161] atarixl: fix compilation problem when CHARGEN_RELOC is defined --- libsrc/atari/shadow_ram_timerirq1.s | 1 + libsrc/atari/shadow_ram_timerirq2.s | 1 + 2 files changed, 2 insertions(+) diff --git a/libsrc/atari/shadow_ram_timerirq1.s b/libsrc/atari/shadow_ram_timerirq1.s index f8a3e9b4d..e1b7d831b 100644 --- a/libsrc/atari/shadow_ram_timerirq1.s +++ b/libsrc/atari/shadow_ram_timerirq1.s @@ -11,6 +11,7 @@ SHRAM_HANDLERS = 1 .include "atari.inc" .include "romswitch.inc" + .import __CHARGEN_START__ .export set_VTIMR1_handler diff --git a/libsrc/atari/shadow_ram_timerirq2.s b/libsrc/atari/shadow_ram_timerirq2.s index b2cdaecd2..d6d581937 100644 --- a/libsrc/atari/shadow_ram_timerirq2.s +++ b/libsrc/atari/shadow_ram_timerirq2.s @@ -11,6 +11,7 @@ SHRAM_HANDLERS = 1 .include "atari.inc" .include "romswitch.inc" + .import __CHARGEN_START__ .export set_VTIMR2_handler From 0e482c7f922b3563113ea68839054f518f852fda Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Wed, 28 Oct 2020 09:52:54 +0100 Subject: [PATCH 1777/2161] Add test for issue #1310 --- test/todo/bug1310.c | 73 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 test/todo/bug1310.c diff --git a/test/todo/bug1310.c b/test/todo/bug1310.c new file mode 100644 index 000000000..936145928 --- /dev/null +++ b/test/todo/bug1310.c @@ -0,0 +1,73 @@ +/* + Copyright 2020 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. +*/ + +/* + Tests of constant expressions. https://github.com/cc65/cc65/issues/1310 +*/ + +#include <stdio.h> + +static unsigned char failures = 0; + +int main (void) +{ + /* 255 * 255 is signed integer overflow, so UB, but it would be nice if + ** (1) there were a warning, and (2) it did the "obvious" thing. + */ + const int two_fifty_five = 255; + const int two_fifty_five_squared = 255 * 255; + + /* Unsigned overflow is not UB, but has similar problems with comparison. */ + const int two_fifty_six = 256U; + const int two_fifty_six_squared = 256U * 256U; + + if (255 * 255 != -511) { + fprintf (stderr, "Expected 255 * 255 == -511, got: %d\n", 255 * 255); + failures++; + } + if (two_fifty_five * two_fifty_five != -511) { + fprintf (stderr, "Expected two_fifty_five * two_fifty_five == -511, got: %d\n", + two_fifty_five * two_fifty_five); + failures++; + } + if (two_fifty_five_squared != -511) { + fprintf (stderr, "Expected two_fifty_five_squared == -511, got: %d\n", + two_fifty_five_squared); + failures++; + } + + if (256U * 256U != 0) { + fprintf (stderr, "Expected 256U * 256U == 0, got: %d\n", 256U * 256U); + failures++; + } + if (two_fifty_six * two_fifty_six != 0) { + fprintf (stderr, "Expected two_fifty_six * two_fifty_six == 0, got: %d\n", + two_fifty_six * two_fifty_six); + failures++; + } + if (two_fifty_six_squared != 0) { + fprintf (stderr, "Expected two_fifty_six_squared == 0, got: %d\n", + two_fifty_six_squared); + failures++; + } + + printf ("failures: %u\n", failures); + return failures; +} From 65193c6aaf6227b731b8da03cccab521f6ffe3cd Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Mon, 2 Nov 2020 09:03:06 +0100 Subject: [PATCH 1778/2161] Add stdint.h constants INT32_MIN and UINT32_MAX These were missing before --- src/common/inttypes.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/inttypes.h b/src/common/inttypes.h index 0d8caf32a..ca30ceb71 100644 --- a/src/common/inttypes.h +++ b/src/common/inttypes.h @@ -64,9 +64,11 @@ typedef size_t uintmax_t; #define INT8_MIN (-INT8_MAX - 1) #define INT16_MIN (-INT16_MAX - 1) +#define INT32_MIN (-INT32_MAX - 1) #define UINT8_MAX (0xFF) #define UINT16_MAX (0xFFFF) +#define UINT32_MAX (0xFFFFFFFF) #endif From b5f0c0468dd4191415a37e29acf91995d714ee6b Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Tue, 3 Nov 2020 08:26:31 +0100 Subject: [PATCH 1779/2161] Add stdint.h types for C89 compilers Add `intN_t` and `uintN_t` for N = 8, 16, 32. --- src/common/inttypes.h | 45 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/common/inttypes.h b/src/common/inttypes.h index ca30ceb71..28ffb2cc5 100644 --- a/src/common/inttypes.h +++ b/src/common/inttypes.h @@ -51,6 +51,7 @@ /* Assume that ptrdiff_t and size_t are wide enough to hold pointers. ** Assume that they are the widest type. */ +#include <limits.h> #include <stddef.h> typedef ptrdiff_t intptr_t; @@ -70,6 +71,50 @@ typedef size_t uintmax_t; #define UINT16_MAX (0xFFFF) #define UINT32_MAX (0xFFFFFFFF) +#if UCHAR_MAX == UINT8_MAX +typedef unsigned char uint8_t; +#else +#error "No suitable type for uint8_t found." +#endif + +#if SCHAR_MIN == INT8_MIN && SCHAR_MAX == INT8_MAX +typedef signed char int8_t; +#else +#error "No suitable type for int8_t found." +#endif + +#if UINT_MAX == UINT16_MAX +typedef unsigned int uint16_t; +#elif USHRT_MAX == UINT16_MAX +typedef unsigned short uint16_t; +#else +#error "No suitable type for uint16_t found." +#endif + +#if INT_MIN == INT16_MIN && INT_MAX == INT16_MAX +typedef int int16_t; +#elif SHRT_MIN == INT16_MIN && SHRT_MAX == INT16_MAX +typedef short int16_t; +#else +#error "No suitable type for int16_t found." +#endif + +#if UINT_MAX == UINT32_MAX +typedef unsigned int uint32_t; +#elif ULONG_MAX == UINT32_MAX +typedef unsigned long uint32_t; +#else +#error "No suitable type for uint32_t found." +#endif + +#if INT_MIN == INT32_MIN && INT_MAX == INT32_MAX +typedef int int32_t; +#elif LONG_MIN == INT32_MIN && LONG_MAX == INT32_MAX +typedef long int32_t; +#else +#error "No suitable type for int32_t found." +#endif + #endif From 81edc3f582767134253d378cc2e9aa4cea8c0cab Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 8 Nov 2020 17:45:54 -0500 Subject: [PATCH 1780/2161] Updated a comment about Kernal's STATUS variable. --- libsrc/cx16/getdevice.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/cx16/getdevice.s b/libsrc/cx16/getdevice.s index 9b554900f..5f2e74af4 100644 --- a/libsrc/cx16/getdevice.s +++ b/libsrc/cx16/getdevice.s @@ -51,7 +51,7 @@ next: inx jsr closecmdchannel ldx tmp2 -; As we had to reference ST above anyway, we can do so, as well, +; As we had to reference STATUS above anyway, we can do so, as well, ; here too (instead of calling READST). lda STATUS From 5db74b4b195cd6f730a0866e4f7b4c7bfcefb98f Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Wed, 28 Oct 2020 08:13:30 +0100 Subject: [PATCH 1781/2161] Use u16 codegen for u8 x u8 ops In g_typeadjust, before we apply the integral promotions, we check if both types are unsigned char. If so, we promote to unsigned int, rather than int, which would be chosen by the standard rules. This is only a performance optimization and does not affect correctness, as the flags returned by g_typeadjust are only used for code generation, and not to determine types of other expressions containing this one. All unsigned char bit-patterns are valid as both int and unsigned int and represent the same value, so either signed or unsigned int operations can be used. This special case part is not duplicated by ArithmeticConvert. Partial fix for #1308. --- src/cc65/codegen.c | 13 +++++++++++++ test/val/char-promote.c | 11 ++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 539309283..7a25594b6 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -1432,6 +1432,19 @@ unsigned g_typeadjust (unsigned lhs, unsigned rhs) /* Note that this logic is largely duplicated by ArithmeticConvert. */ + /* Before we apply the integral promotions, we check if both types are unsigned char. + ** If so, we return unsigned int, rather than int, which would be returned by the standard + ** rules. This is only a performance optimization and does not affect correctness, as + ** the flags are only used for code generation, and not to determine types of other + ** expressions containing this one. All unsigned char bit-patterns are valid as both int + ** and unsigned int and represent the same value, so either signed or unsigned int operations + ** can be used. This special case part is not duplicated by ArithmeticConvert. + */ + if ((lhs & CF_TYPEMASK) == CF_CHAR && (lhs & CF_UNSIGNED) && + (rhs & CF_TYPEMASK) == CF_CHAR && (rhs & CF_UNSIGNED)) { + return const_flag | CF_UNSIGNED | CF_INT; + } + /* Apply integral promotions for types char/short. */ lhs = g_intpromotion (lhs); rhs = g_intpromotion (rhs); diff --git a/test/val/char-promote.c b/test/val/char-promote.c index 1d6360d45..380a13378 100644 --- a/test/val/char-promote.c +++ b/test/val/char-promote.c @@ -68,7 +68,8 @@ void test_mul (void) #endif /* The unsigned chars get promoted to int, so this is -511. - ** We should also be able to observe that the generated code uses mul, not umul. + ** We should also be able to observe that, due to optimizations from #1315, the generated code + ** uses umul, not mul. */ if (two_fifty_five * two_fifty_five != -511) { fprintf (stderr, "Expected two_fifty_five * two_fifty_five == -511\n"); @@ -89,7 +90,9 @@ void test_div (void) const u8 seventeen = 17; const u8 three = 3; - /* We should also be able to observe that the generated code uses div, not udiv. */ + /* We should also be able to observe that, due to optimizations from #1315, the generated code + ** uses udiv, not div. + */ if (seventeen / three != 5) { fprintf (stderr, "Expected seventeen / three == 5, got: %d\n", seventeen / three); failures++; @@ -105,7 +108,9 @@ void test_shr (void) const unsigned int forty_two = 42; const unsigned int two = 2; - /* We should also be able to observe that the generated code uses asr, not shr. */ + /* We should also be able to observe that, due to optimizations from #1315, the generated code + ** uses shr, not asr. + */ if (forty_two >> two != 10) { fprintf (stderr, "Expected forty_two / two == 10, got: %d\n", forty_two >> two); failures++; From 93145246fd3533cab0525def93ac4825ec6c405c Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sat, 31 Oct 2020 18:20:15 +0100 Subject: [PATCH 1782/2161] Add tests for u8 op s16_const Test expressions like `unsigned char x = ...; ... = x / 2;` These use `int` constants with values representable by `unsigned int` / `unsigned char`, so using unsigned codegen should be possible. Additional tests for #1308. These are things we want to generate better code for, so add tests that the behavior doesn't change. --- test/val/char-promote.c | 46 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/test/val/char-promote.c b/test/val/char-promote.c index 380a13378..0d2dad04e 100644 --- a/test/val/char-promote.c +++ b/test/val/char-promote.c @@ -54,6 +54,8 @@ void test_sub (void) void test_mul (void) { const u8 two_fifty_five = 255; + const u8 sixteen = 16; + int x; if (255U * 255U != 65025U) { fprintf (stderr, "Expected 255U * 255U == 65025U\n"); @@ -83,12 +85,20 @@ void test_mul (void) failures++; } #endif + + /* This should compile to a shift. */ + x = sixteen * 4; + if (x != 64) { + fprintf (stderr, "Expected sixteen * 4 == 64, got: %d\n", x); + failures++; + } } void test_div (void) { const u8 seventeen = 17; const u8 three = 3; + int x; /* We should also be able to observe that, due to optimizations from #1315, the generated code ** uses udiv, not div. @@ -101,24 +111,57 @@ void test_div (void) fprintf (stderr, "Expected (u8) 17 / (u8) 3 == 5, got: %d\n", (u8) 17 / (u8) 3); failures++; } + + /* Ideally, this would compile to a logical shift, but that does not happen currently. */ + x = seventeen / 4; + if (x != 4) { + fprintf (stderr, "Expected seventeen / 4 == 4, got: %d\n", x); + failures++; + } +} + +void test_mod (void) +{ + const u8 seventeen = 17; + /* Ideally, this would compile to a bitwise and, but that does not happen currently. */ + int x = seventeen % 4; + if (x != 1) { + fprintf (stderr, "Expected seventeen %% 4 == 1, got: %d\n", x); + failures++; + } } void test_shr (void) { const unsigned int forty_two = 42; const unsigned int two = 2; + int x; /* We should also be able to observe that, due to optimizations from #1315, the generated code ** uses shr, not asr. */ if (forty_two >> two != 10) { - fprintf (stderr, "Expected forty_two / two == 10, got: %d\n", forty_two >> two); + fprintf (stderr, "Expected forty_two >> two == 10, got: %d\n", forty_two >> two); failures++; } if ((u8) 42 >> (u8) 2 != 10) { fprintf (stderr, "Expected (u8) 42 >> (u8) 2 == 10, got: %d\n", (u8) 42 >> (u8) 3); failures++; } + + /* Ideally, this would compile to a logical shift, but that does not happen currently. */ + x = forty_two >> 2; + if (x != 10) { + fprintf (stderr, "Expected forty_two >> 2 == 10, got: %d\n", x); + failures++; + } + + /* Ideally, this would compile to a logical shift, but that does not happen currently. */ + x = 42 >> two; + if (x != 10) { + fprintf (stderr, "Expected 42 >> two == 10, got: %d\n", x); + failures++; + } } int main (void) @@ -126,6 +169,7 @@ int main (void) test_sub (); test_mul (); test_div (); + test_mod (); test_shr (); printf ("failures: %u\n", failures); return failures; From 53f055fb1d9dd614888260a0ecd57d7e0b1cb9fa Mon Sep 17 00:00:00 2001 From: Sven Michael Klose <pixel@hugbox.org> Date: Wed, 11 Nov 2020 12:15:09 +0100 Subject: [PATCH 1783/2161] Reduce stack size to 256B for unexpanded VICs. --- cfg/vic20.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/vic20.cfg b/cfg/vic20.cfg index ceaee3a87..a14491e9f 100644 --- a/cfg/vic20.cfg +++ b/cfg/vic20.cfg @@ -1,7 +1,7 @@ SYMBOLS { __LOADADDR__: type = import; __EXEHDR__: type = import; - __STACKSIZE__: type = weak, value = $0400; # 1k stack + __STACKSIZE__: type = weak, value = $0100 } MEMORY { ZP: file = "", define = yes, start = $0002, size = $001A; From 77da8d5490ea88396cc003417bbfdafa8a1973f6 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 11 Nov 2020 17:20:25 +0100 Subject: [PATCH 1784/2161] vic20.cfg: add missing comma --- cfg/vic20.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/vic20.cfg b/cfg/vic20.cfg index a14491e9f..8efeae229 100644 --- a/cfg/vic20.cfg +++ b/cfg/vic20.cfg @@ -1,7 +1,7 @@ SYMBOLS { __LOADADDR__: type = import; __EXEHDR__: type = import; - __STACKSIZE__: type = weak, value = $0100 + __STACKSIZE__: type = weak, value = $0100; } MEMORY { ZP: file = "", define = yes, start = $0002, size = $001A; From b33b05330713a46adad4f0cbb137da06f15dfd1a Mon Sep 17 00:00:00 2001 From: Zsolt Branyiczky <brazso@zematix.hu> Date: Tue, 10 Nov 2020 10:32:29 +0100 Subject: [PATCH 1785/2161] add c64dtv support --- asminc/cpu.mac | 2 + asminc/opcodes.inc | 8 ++ doc/ca65.sgml | 2 +- src/ca65/instr.c | 92 +++++++++++++ src/cc65/codegen.c | 3 +- src/cc65/coptjmp.c | 2 +- src/cc65/main.c | 3 +- src/cc65/opcodes.c | 2 +- src/common/cpu.c | 2 + src/common/cpu.h | 2 + src/da65.vcxproj | 2 + src/da65/opc6502dtv.c | 308 ++++++++++++++++++++++++++++++++++++++++++ src/da65/opc6502dtv.h | 61 +++++++++ src/da65/opctable.c | 2 + 14 files changed, 486 insertions(+), 5 deletions(-) create mode 100644 src/da65/opc6502dtv.c create mode 100644 src/da65/opc6502dtv.h diff --git a/asminc/cpu.mac b/asminc/cpu.mac index 6b9cb9947..55727c93e 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -9,6 +9,7 @@ CPU_ISET_SWEET16 = $0040 CPU_ISET_HUC6280 = $0080 ;CPU_ISET_M740 = $0100 not actually implemented CPU_ISET_4510 = $0200 +CPU_ISET_6502DTV = $0400 ; CPU capabilities CPU_NONE = CPU_ISET_NONE @@ -20,3 +21,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_6502DTV = CPU_ISET_6502|CPU_ISET_6502X|CPU_ISET_6502DTV diff --git a/asminc/opcodes.inc b/asminc/opcodes.inc index aa7a65f00..e6b7e73df 100644 --- a/asminc/opcodes.inc +++ b/asminc/opcodes.inc @@ -505,4 +505,12 @@ OPC_ISC_aby = $FB OPC_NOP_abx = $FC OPC_ISC_abx = $FF +.if (.cpu .bitand ::CPU_ISET_6502DTV) + +OPC_BRA = $12 +OPC_SAC_imm = $32 +OPC_SIR_imm = $42 + +.endif + .endif diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 8d97bddfd..25a47b29a 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -151,7 +151,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, 65SC02, 65C02, 65816, sweet16, HuC6280, 4510 + 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, sweet16, HuC6280, 4510 <label id="option-create-dep"> diff --git a/src/ca65/instr.c b/src/ca65/instr.c index d71476799..99c0412b0 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -303,6 +303,97 @@ static const struct { } }; +/* Instruction table for the 6502 with illegal instructions (X) and DTV +** extra opcodes (DTV). Some illegal instructions (X, -DTV?) might be not +** supported by DTV. They should be tested on the DTV hardware. +*/ +static const struct { + unsigned Count; + InsDesc Ins[78]; +} InsTab6502DTV = { + sizeof (InsTab6502DTV.Ins) / sizeof (InsTab6502DTV.Ins[0]), + { + { "ADC", 0x080A26C, 0x60, 0, PutAll }, + { "ALR", 0x0800000, 0x4B, 0, PutAll }, /* X */ + { "ANC", 0x0800000, 0x0B, 0, PutAll }, /* X -DTV? */ + { "AND", 0x080A26C, 0x20, 0, PutAll }, + { "ANE", 0x0800000, 0x8B, 0, PutAll }, /* X */ + { "ARR", 0x0800000, 0x6B, 0, PutAll }, /* X */ + { "ASL", 0x000006e, 0x02, 1, PutAll }, + { "AXS", 0x0800000, 0xCB, 0, PutAll }, /* X, -DTV? */ + { "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, 0x12, 0, PutPCRel8 }, /* DTV */ + { "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 }, + { "CLV", 0x0000001, 0xb8, 0, PutAll }, + { "CMP", 0x080A26C, 0xc0, 0, PutAll }, + { "CPX", 0x080000C, 0xe0, 1, PutAll }, + { "CPY", 0x080000C, 0xc0, 1, PutAll }, + { "DCP", 0x000A26C, 0xC3, 0, PutAll }, /* X */ + { "DEC", 0x000006C, 0x00, 3, PutAll }, + { "DEX", 0x0000001, 0xca, 0, PutAll }, + { "DEY", 0x0000001, 0x88, 0, PutAll }, + { "EOR", 0x080A26C, 0x40, 0, PutAll }, + { "INC", 0x000006c, 0x00, 4, PutAll }, + { "INX", 0x0000001, 0xe8, 0, PutAll }, + { "INY", 0x0000001, 0xc8, 0, PutAll }, + { "ISC", 0x000A26C, 0xE3, 0, PutAll }, /* X */ + { "JAM", 0x0000001, 0x02, 0, PutAll }, /* X, -DTV? */ + { "JMP", 0x0000808, 0x4c, 6, PutJMP }, + { "JSR", 0x0000008, 0x20, 7, PutAll }, + { "LAS", 0x0000200, 0xBB, 0, PutAll }, /* X, -DTV? */ + { "LAX", 0x080A30C, 0xA3, 11, PutAll }, /* X */ + { "LDA", 0x080A26C, 0xa0, 0, PutAll }, + { "LDX", 0x080030C, 0xa2, 1, PutAll }, + { "LDY", 0x080006C, 0xa0, 1, PutAll }, + { "LSR", 0x000006F, 0x42, 1, PutAll }, + { "NOP", 0x080006D, 0x00, 10, PutAll }, /* X */ + { "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 }, + { "RLA", 0x000A26C, 0x23, 0, PutAll }, /* X */ + { "ROL", 0x000006F, 0x22, 1, PutAll }, + { "ROR", 0x000006F, 0x62, 1, PutAll }, + { "RRA", 0x000A26C, 0x63, 0, PutAll }, /* X */ + { "RTI", 0x0000001, 0x40, 0, PutAll }, + { "RTS", 0x0000001, 0x60, 0, PutAll }, + { "SAC", 0x0800000, 0x32, 0, PutAll }, /* DTV */ + { "SAX", 0x000810C, 0x83, 1, PutAll }, /* X */ + { "SBC", 0x080A26C, 0xe0, 0, PutAll }, + { "SEC", 0x0000001, 0x38, 0, PutAll }, + { "SED", 0x0000001, 0xf8, 0, PutAll }, + { "SEI", 0x0000001, 0x78, 0, PutAll }, + { "SHA", 0x0002200, 0x93, 1, PutAll }, /* X, -DTV? */ + { "SHX", 0x0000200, 0x9e, 1, PutAll }, /* X, -DTV? */ + { "SHY", 0x0000040, 0x9c, 1, PutAll }, /* X, -DTV? */ + { "SIR", 0x0800000, 0x32, 0, PutAll }, /* DTV */ + { "SLO", 0x000A26C, 0x03, 0, PutAll }, /* X */ + { "SRE", 0x000A26C, 0x43, 0, PutAll }, /* X */ + { "STA", 0x000A26C, 0x80, 0, PutAll }, + { "STX", 0x000010c, 0x82, 1, PutAll }, + { "STY", 0x000002c, 0x80, 1, PutAll }, + { "TAS", 0x0000200, 0x9b, 0, PutAll }, /* X */ + { "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 } + } +}; + /* Instruction table for the 65SC02 */ static const struct { unsigned Count; @@ -930,6 +1021,7 @@ static const InsTable* InsTabs[CPU_COUNT] = { (const InsTable*) &InsTabNone, (const InsTable*) &InsTab6502, (const InsTable*) &InsTab6502X, + (const InsTable*) &InsTab6502DTV, (const InsTable*) &InsTab65SC02, (const InsTable*) &InsTab65C02, (const InsTable*) &InsTab65816, diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 7a25594b6..aee6141fc 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -186,6 +186,7 @@ void g_preamble (void) switch (CPU) { case CPU_6502: AddTextLine ("\t.setcpu\t\t\"6502\""); break; case CPU_6502X: AddTextLine ("\t.setcpu\t\t\"6502X\""); break; + 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_65816: AddTextLine ("\t.setcpu\t\t\"65816\""); break; @@ -2474,7 +2475,7 @@ void g_branch (unsigned Label) ** the label cannot be farther away from the branch than -128/+127 bytes. */ { - if ((CPUIsets[CPU] & CPU_ISET_65SC02) != 0) { + if ((CPUIsets[CPU] & (CPU_ISET_65SC02 | CPU_ISET_6502DTV)) != 0) { AddCodeLine ("bra %s", LocalLabelName (Label)); } else { g_jump (Label); diff --git a/src/cc65/coptjmp.c b/src/cc65/coptjmp.c index 693c7eb79..dd092a5ad 100644 --- a/src/cc65/coptjmp.c +++ b/src/cc65/coptjmp.c @@ -173,7 +173,7 @@ unsigned OptBranchDist (CodeSeg* S) } - } else if ((CPUIsets[CPU] & CPU_ISET_65SC02) != 0 && + } else if ((CPUIsets[CPU] & (CPU_ISET_65SC02 |CPU_ISET_6502DTV)) != 0 && (E->Info & OF_UBRA) != 0 && E->JumpTo != 0 && IsShortDist (GetBranchDist (S, I, E->JumpTo->Owner))) { diff --git a/src/cc65/main.c b/src/cc65/main.c index fabd71ef7..0b156fb74 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -463,7 +463,8 @@ static void OptCPU (const char* Opt, const char* Arg) /* Find the CPU from the given name */ CPU = FindCPU (Arg); if (CPU != CPU_6502 && CPU != CPU_6502X && CPU != CPU_65SC02 && - CPU != CPU_65C02 && CPU != CPU_65816 && CPU != CPU_HUC6280) { + CPU != CPU_65C02 && CPU != CPU_65816 && CPU != CPU_HUC6280 && + CPU != CPU_6502DTV) { AbEnd ("Invalid argument for %s: '%s'", Opt, Arg); } } diff --git a/src/cc65/opcodes.c b/src/cc65/opcodes.c index 86b904df9..aeea0297b 100644 --- a/src/cc65/opcodes.c +++ b/src/cc65/opcodes.c @@ -734,7 +734,7 @@ opc_t MakeShortBranch (opc_t OPC) case OP65_BVS: case OP65_JVS: return OP65_BVS; case OP65_BRA: - case OP65_JMP: return (CPUIsets[CPU] & CPU_ISET_65SC02)? OP65_BRA : OP65_JMP; + case OP65_JMP: return (CPUIsets[CPU] & (CPU_ISET_65SC02 | CPU_ISET_6502DTV)) ? OP65_BRA : OP65_JMP; default: Internal ("MakeShortBranch: Invalid opcode: %d", OPC); return 0; diff --git a/src/common/cpu.c b/src/common/cpu.c index b4c5c8dfe..16578543b 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -55,6 +55,7 @@ const char* CPUNames[CPU_COUNT] = { "none", "6502", "6502X", + "6502DTV", "65SC02", "65C02", "65816", @@ -69,6 +70,7 @@ const unsigned CPUIsets[CPU_COUNT] = { CPU_ISET_NONE, CPU_ISET_6502, CPU_ISET_6502 | CPU_ISET_6502X, + CPU_ISET_6502 | CPU_ISET_6502X | 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, diff --git a/src/common/cpu.h b/src/common/cpu.h index dcf1815db..706b4544e 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -50,6 +50,7 @@ typedef enum { CPU_NONE, /* No CPU - for assembler */ CPU_6502, CPU_6502X, /* "Extended", that is: with illegal opcodes */ + CPU_6502DTV, /* CPU_6502X + C64DTV extra opcodes */ CPU_65SC02, CPU_65C02, CPU_65816, @@ -65,6 +66,7 @@ enum { CPU_ISET_NONE = 1 << CPU_NONE, CPU_ISET_6502 = 1 << CPU_6502, CPU_ISET_6502X = 1 << CPU_6502X, + CPU_ISET_6502DTV = 1 << CPU_6502DTV, CPU_ISET_65SC02 = 1 << CPU_65SC02, CPU_ISET_65C02 = 1 << CPU_65C02, CPU_ISET_65816 = 1 << CPU_65816, diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 7a8b0de68..090c3030f 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -90,6 +90,7 @@ <ClCompile Include="da65\opc4510.c" /> <ClCompile Include="da65\opc6502.c" /> <ClCompile Include="da65\opc6502x.c" /> + <ClCompile Include="da65\opc6502dtv.c" /> <ClCompile Include="da65\opc65816.c" /> <ClCompile Include="da65\opc65c02.c" /> <ClCompile Include="da65\opc65sc02.c" /> @@ -114,6 +115,7 @@ <ClInclude Include="da65\opc4510.h" /> <ClInclude Include="da65\opc6502.h" /> <ClInclude Include="da65\opc6502x.h" /> + <ClInclude Include="da65\opc6502dtv.h" /> <ClInclude Include="da65\opc65816.h" /> <ClInclude Include="da65\opc65c02.h" /> <ClInclude Include="da65\opc65sc02.h" /> diff --git a/src/da65/opc6502dtv.c b/src/da65/opc6502dtv.c new file mode 100644 index 000000000..73bce7f4d --- /dev/null +++ b/src/da65/opc6502dtv.c @@ -0,0 +1,308 @@ +/*****************************************************************************/ +/* */ +/* opc6502dtv.c */ +/* */ +/* 6502 opcode description table with NMOS illegals and DTV opcodes */ +/* */ +/* */ +/* */ +/* (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 "opc6502dtv.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Descriptions for all opcodes. Base table from opc6502.c with illegal +** opcodes from http://www.oxyron.de/html/opcodes02.html and DTV opcodes +*/ +const OpcDesc OpcTable_6502DTV[256] = { + { "brk", 1, flNone, OH_Implicit }, /* $00 */ + { "ora", 2, flUseLabel, OH_DirectXIndirect }, /* $01 */ + { "jam", 1, flNone, OH_Implicit }, /* $02 */ + { "slo", 2, flUseLabel, OH_DirectXIndirect }, /* $03 */ + { "nop", 2, flUseLabel, OH_Direct }, /* $04 */ + { "ora", 2, flUseLabel, OH_Direct }, /* $05 */ + { "asl", 2, flUseLabel, OH_Direct }, /* $06 */ + { "slo", 2, flUseLabel, OH_Direct }, /* $07 */ + { "php", 1, flNone, OH_Implicit }, /* $08 */ + { "ora", 2, flNone, OH_Immediate }, /* $09 */ + { "asl", 1, flNone, OH_Accumulator }, /* $0a */ + { "anc", 2, flNone, OH_Immediate }, /* $0b */ + { "nop", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0c */ + { "ora", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0d */ + { "asl", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0e */ + { "slo", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0f */ + { "bpl", 2, flLabel, OH_Relative }, /* $10 */ + { "ora", 2, flUseLabel, OH_DirectIndirectY }, /* $11 */ + { "bra", 2, flLabel, OH_Relative }, /* $12 */ + { "slo", 2, flUseLabel, OH_DirectIndirectY }, /* $13 */ + { "nop", 2, flUseLabel, OH_DirectX }, /* $14 */ + { "ora", 2, flUseLabel, OH_DirectX }, /* $15 */ + { "asl", 2, flUseLabel, OH_DirectX }, /* $16 */ + { "slo", 2, flUseLabel, OH_DirectX }, /* $17 */ + { "clc", 1, flNone, OH_Implicit }, /* $18 */ + { "ora", 3, flUseLabel, OH_AbsoluteY }, /* $19 */ + { "nop", 1, flNone, OH_Implicit }, /* $1a */ + { "slo", 3, flUseLabel, OH_AbsoluteY }, /* $1b */ + { "nop", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1c */ + { "ora", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1d */ + { "asl", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1e */ + { "slo", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1f */ + { "jsr", 3, flLabel, OH_Absolute }, /* $20 */ + { "and", 2, flUseLabel, OH_DirectXIndirect }, /* $21 */ + { "jam", 1, flNone, OH_Implicit, }, /* $22 */ + { "rla", 2, flUseLabel, OH_DirectXIndirect }, /* $23 */ + { "bit", 2, flUseLabel, OH_Direct }, /* $24 */ + { "and", 2, flUseLabel, OH_Direct }, /* $25 */ + { "rol", 2, flUseLabel, OH_Direct }, /* $26 */ + { "rla", 2, flUseLabel, OH_Direct }, /* $27 */ + { "plp", 1, flNone, OH_Implicit }, /* $28 */ + { "and", 2, flNone, OH_Immediate }, /* $29 */ + { "rol", 1, flNone, OH_Accumulator }, /* $2a */ + { "anc", 2, flNone, OH_Immediate }, /* $2b */ + { "bit", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2c */ + { "and", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2d */ + { "rol", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2e */ + { "rla", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2f */ + { "bmi", 2, flLabel, OH_Relative }, /* $30 */ + { "and", 2, flUseLabel, OH_DirectIndirectY }, /* $31 */ + { "sac", 2, flNone, OH_Immediate }, /* $32 */ + { "rla", 2, flUseLabel, OH_DirectIndirectY }, /* $33 */ + { "nop", 2, flUseLabel, OH_DirectX }, /* $34 */ + { "and", 2, flUseLabel, OH_DirectX }, /* $35 */ + { "rol", 2, flUseLabel, OH_DirectX }, /* $36 */ + { "rla", 2, flUseLabel, OH_DirectX }, /* $37 */ + { "sec", 1, flNone, OH_Implicit }, /* $38 */ + { "and", 3, flUseLabel, OH_AbsoluteY }, /* $39 */ + { "nop", 1, flNone, OH_Implicit }, /* $3a */ + { "rla", 3, flUseLabel, OH_AbsoluteY }, /* $3b */ + { "nop", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3c */ + { "and", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3d */ + { "rol", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3e */ + { "rla", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3f */ + { "rti", 1, flNone, OH_Rts }, /* $40 */ + { "eor", 2, flUseLabel, OH_DirectXIndirect }, /* $41 */ + { "sir", 1, flNone, OH_Implicit }, /* $42 */ + { "sre", 2, flUseLabel, OH_DirectXIndirect }, /* $43 */ + { "nop", 2, flUseLabel, OH_Direct }, /* $44 */ + { "eor", 2, flUseLabel, OH_Direct }, /* $45 */ + { "lsr", 2, flUseLabel, OH_Direct }, /* $46 */ + { "sre", 2, flUseLabel, OH_Direct }, /* $47 */ + { "pha", 1, flNone, OH_Implicit }, /* $48 */ + { "eor", 2, flNone, OH_Immediate }, /* $49 */ + { "lsr", 1, flNone, OH_Accumulator }, /* $4a */ + { "alr", 2, flNone, OH_Immediate }, /* $4b */ + { "jmp", 3, flLabel, OH_JmpAbsolute }, /* $4c */ + { "eor", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4d */ + { "lsr", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4e */ + { "sre", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4f */ + { "bvc", 2, flLabel, OH_Relative }, /* $50 */ + { "eor", 2, flUseLabel, OH_DirectIndirectY }, /* $51 */ + { "jam", 1, flNone, OH_Implicit }, /* $52 */ + { "sre", 2, flUseLabel, OH_DirectIndirectY }, /* $53 */ + { "nop", 2, flUseLabel, OH_DirectX }, /* $54 */ + { "eor", 2, flUseLabel, OH_DirectX }, /* $55 */ + { "lsr", 2, flUseLabel, OH_DirectX }, /* $56 */ + { "sre", 2, flUseLabel, OH_DirectX }, /* $57 */ + { "cli", 1, flNone, OH_Implicit }, /* $58 */ + { "eor", 3, flUseLabel, OH_AbsoluteY }, /* $59 */ + { "nop", 1, flNone, OH_Implicit }, /* $5a */ + { "sre", 3, flUseLabel, OH_AbsoluteY }, /* $5b */ + { "nop", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5c */ + { "eor", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5d */ + { "lsr", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5e */ + { "sre", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5f */ + { "rts", 1, flNone, OH_Rts }, /* $60 */ + { "adc", 2, flUseLabel, OH_DirectXIndirect }, /* $61 */ + { "jam", 1, flNone, OH_Implicit }, /* $62 */ + { "rra", 2, flUseLabel, OH_DirectXIndirect }, /* $63 */ + { "nop", 2, flUseLabel, OH_Direct }, /* $64 */ + { "adc", 2, flUseLabel, OH_Direct }, /* $65 */ + { "ror", 2, flUseLabel, OH_Direct }, /* $66 */ + { "rra", 2, flUseLabel, OH_Direct }, /* $67 */ + { "pla", 1, flNone, OH_Implicit }, /* $68 */ + { "adc", 2, flNone, OH_Immediate }, /* $69 */ + { "ror", 1, flNone, OH_Accumulator }, /* $6a */ + { "arr", 2, flNone, OH_Immediate }, /* $6b */ + { "jmp", 3, flLabel, OH_JmpAbsoluteIndirect }, /* $6c */ + { "adc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $6d */ + { "ror", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $6e */ + { "rra", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $6f */ + { "bvs", 2, flLabel, OH_Relative }, /* $70 */ + { "adc", 2, flUseLabel, OH_DirectIndirectY }, /* $71 */ + { "jam", 1, flNone, OH_Implicit }, /* $72 */ + { "rra", 2, flUseLabel, OH_DirectIndirectY }, /* $73 */ + { "nop", 2, flUseLabel, OH_DirectX }, /* $74 */ + { "adc", 2, flUseLabel, OH_DirectX }, /* $75 */ + { "ror", 2, flUseLabel, OH_DirectX }, /* $76 */ + { "rra", 2, flUseLabel, OH_DirectX }, /* $77 */ + { "sei", 1, flNone, OH_Implicit }, /* $78 */ + { "adc", 3, flUseLabel, OH_AbsoluteY }, /* $79 */ + { "nop", 1, flNone, OH_Implicit }, /* $7a */ + { "rra", 3, flUseLabel, OH_AbsoluteY }, /* $7b */ + { "nop", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7c */ + { "adc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7d */ + { "ror", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7e */ + { "rra", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7f */ + { "nop", 2, flNone, OH_Immediate }, /* $80 */ + { "sta", 2, flUseLabel, OH_DirectXIndirect }, /* $81 */ + { "nop", 2, flNone, OH_Immediate }, /* $82 */ + { "sax", 2, flUseLabel, OH_DirectXIndirect }, /* $83 */ + { "sty", 2, flUseLabel, OH_Direct }, /* $84 */ + { "sta", 2, flUseLabel, OH_Direct }, /* $85 */ + { "stx", 2, flUseLabel, OH_Direct }, /* $86 */ + { "sax", 2, flUseLabel, OH_Direct }, /* $87 */ + { "dey", 1, flNone, OH_Implicit }, /* $88 */ + { "nop", 2, flNone, OH_Immediate }, /* $89 */ + { "txa", 1, flNone, OH_Implicit }, /* $8a */ + { "xaa", 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 */ + { "sax", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8f */ + { "bcc", 2, flLabel, OH_Relative }, /* $90 */ + { "sta", 2, flUseLabel, OH_DirectIndirectY }, /* $91 */ + { "jam", 1, flNone, OH_Implicit }, /* $92 */ + { "ahx", 2, flUseLabel, OH_DirectIndirectY }, /* $93 */ + { "sty", 2, flUseLabel, OH_DirectX }, /* $94 */ + { "sta", 2, flUseLabel, OH_DirectX }, /* $95 */ + { "stx", 2, flUseLabel, OH_DirectY }, /* $96 */ + { "sax", 2, flUseLabel, OH_DirectY }, /* $97 */ + { "tya", 1, flNone, OH_Implicit }, /* $98 */ + { "sta", 3, flUseLabel, OH_AbsoluteY }, /* $99 */ + { "txs", 1, flNone, OH_Implicit }, /* $9a */ + { "tas", 3, flUseLabel, OH_AbsoluteY }, /* $9b */ + { "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 */ + { "ldy", 2, flNone, OH_Immediate }, /* $a0 */ + { "lda", 2, flUseLabel, OH_DirectXIndirect }, /* $a1 */ + { "ldx", 2, flNone, OH_Immediate }, /* $a2 */ + { "lax", 2, flUseLabel, OH_DirectXIndirect }, /* $a3 */ + { "ldy", 2, flUseLabel, OH_Direct }, /* $a4 */ + { "lda", 2, flUseLabel, OH_Direct }, /* $a5 */ + { "ldx", 2, flUseLabel, OH_Direct }, /* $a6 */ + { "lax", 2, flUseLabel, OH_Direct }, /* $a7 */ + { "tay", 1, flNone, OH_Implicit }, /* $a8 */ + { "lda", 2, flNone, OH_Immediate }, /* $a9 */ + { "tax", 1, flNone, OH_Implicit }, /* $aa */ + { "lax", 2, flNone, OH_Immediate }, /* $ab */ + { "ldy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ac */ + { "lda", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ad */ + { "ldx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ae */ + { "lax", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $af */ + { "bcs", 2, flLabel, OH_Relative }, /* $b0 */ + { "lda", 2, flUseLabel, OH_DirectIndirectY }, /* $b1 */ + { "jam", 1, flNone, OH_Implicit }, /* $b2 */ + { "lax", 2, flUseLabel, OH_DirectIndirectY }, /* $b3 */ + { "ldy", 2, flUseLabel, OH_DirectX }, /* $b4 */ + { "lda", 2, flUseLabel, OH_DirectX }, /* $b5 */ + { "ldx", 2, flUseLabel, OH_DirectY }, /* $b6 */ + { "lax", 2, flUseLabel, OH_DirectY }, /* $b7 */ + { "clv", 1, flNone, OH_Implicit }, /* $b8 */ + { "lda", 3, flUseLabel, OH_AbsoluteY }, /* $b9 */ + { "tsx", 1, flNone, OH_Implicit }, /* $ba */ + { "las", 3, flUseLabel, OH_AbsoluteY }, /* $bb */ + { "ldy", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bc */ + { "lda", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bd */ + { "ldx", 3, flUseLabel|flAbsOverride, OH_AbsoluteY }, /* $be */ + { "lax", 3, flUseLabel|flAbsOverride, OH_AbsoluteY }, /* $bf */ + { "cpy", 2, flNone, OH_Immediate }, /* $c0 */ + { "cmp", 2, flUseLabel, OH_DirectXIndirect }, /* $c1 */ + { "nop", 2, flNone, OH_Immediate }, /* $c2 */ + { "dcp", 2, flUseLabel, OH_DirectXIndirect }, /* $c3 */ + { "cpy", 2, flUseLabel, OH_Direct }, /* $c4 */ + { "cmp", 2, flUseLabel, OH_Direct }, /* $c5 */ + { "dec", 2, flUseLabel, OH_Direct }, /* $c6 */ + { "dcp", 2, flUseLabel, OH_Direct }, /* $c7 */ + { "iny", 1, flNone, OH_Implicit }, /* $c8 */ + { "cmp", 2, flNone, OH_Immediate }, /* $c9 */ + { "dex", 1, flNone, OH_Implicit }, /* $ca */ + { "axs", 2, flNone, OH_Immediate }, /* $cb */ + { "cpy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cc */ + { "cmp", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cd */ + { "dec", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ce */ + { "dcp", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cf */ + { "bne", 2, flLabel, OH_Relative }, /* $d0 */ + { "cmp", 2, flUseLabel, OH_DirectIndirectY }, /* $d1 */ + { "jam", 1, flNone, OH_Implicit }, /* $d2 */ + { "dcp", 2, flUseLabel, OH_DirectIndirectY }, /* $d3 */ + { "nop", 2, flUseLabel, OH_DirectX }, /* $d4 */ + { "cmp", 2, flUseLabel, OH_DirectX }, /* $d5 */ + { "dec", 2, flUseLabel, OH_DirectX }, /* $d6 */ + { "dcp", 2, flUseLabel, OH_DirectX }, /* $d7 */ + { "cld", 1, flNone, OH_Implicit }, /* $d8 */ + { "cmp", 3, flUseLabel, OH_AbsoluteY }, /* $d9 */ + { "nop", 1, flNone, OH_Implicit }, /* $da */ + { "dcp", 3, flUseLabel, OH_AbsoluteY }, /* $db */ + { "nop", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $dc */ + { "cmp", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $dd */ + { "dec", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $de */ + { "dcp", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $df */ + { "cpx", 2, flNone, OH_Immediate }, /* $e0 */ + { "sbc", 2, flUseLabel, OH_DirectXIndirect }, /* $e1 */ + { "nop", 2, flNone, OH_Immediate }, /* $e2 */ + { "isc", 2, flUseLabel, OH_DirectXIndirect }, /* $e3 */ + { "cpx", 2, flUseLabel, OH_Direct }, /* $e4 */ + { "sbc", 2, flUseLabel, OH_Direct }, /* $e5 */ + { "inc", 2, flUseLabel, OH_Direct }, /* $e6 */ + { "isc", 2, flUseLabel, OH_Direct }, /* $e7 */ + { "inx", 1, flNone, OH_Implicit }, /* $e8 */ + { "sbc", 2, flNone, OH_Immediate }, /* $e9 */ + { "nop", 1, flNone, OH_Implicit }, /* $ea */ + { "sbc", 2, flNone, OH_Immediate }, /* $eb */ + { "cpx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ec */ + { "sbc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ed */ + { "inc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ee */ + { "isc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ef */ + { "beq", 2, flLabel, OH_Relative }, /* $f0 */ + { "sbc", 2, flUseLabel, OH_DirectIndirectY }, /* $f1 */ + { "jam", 1, flNone, OH_Implicit }, /* $f2 */ + { "isc", 2, flUseLabel, OH_DirectIndirectY }, /* $f3 */ + { "nop", 2, flUseLabel, OH_DirectX }, /* $f4 */ + { "sbc", 2, flUseLabel, OH_DirectX }, /* $f5 */ + { "inc", 2, flUseLabel, OH_DirectX }, /* $f6 */ + { "isc", 2, flUseLabel, OH_DirectX }, /* $f7 */ + { "sed", 1, flNone, OH_Implicit }, /* $f8 */ + { "sbc", 3, flUseLabel, OH_AbsoluteY }, /* $f9 */ + { "nop", 1, flNone, OH_Implicit }, /* $fa */ + { "isc", 3, flUseLabel, OH_AbsoluteY }, /* $fb */ + { "nop", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fc */ + { "sbc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fd */ + { "inc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fe */ + { "isc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $ff */ +}; diff --git a/src/da65/opc6502dtv.h b/src/da65/opc6502dtv.h new file mode 100644 index 000000000..e63e4e44c --- /dev/null +++ b/src/da65/opc6502dtv.h @@ -0,0 +1,61 @@ +/*****************************************************************************/ +/* */ +/* opc6502dtv.h */ +/* */ +/* 6502 opcode description table with NMOS illegals and DTV opcodes */ +/* */ +/* */ +/* */ +/* (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. */ +/* */ +/*****************************************************************************/ + + + +#ifndef OPC6502DTV_H +#define OPC6502DTV_H + + + +#include "opcdesc.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Descriptions for all opcodes */ +extern const OpcDesc OpcTable_6502DTV[256]; + + + +/* End of opc6502dtv.h */ +#endif + + + + diff --git a/src/da65/opctable.c b/src/da65/opctable.c index 031b1239b..255a3557f 100644 --- a/src/da65/opctable.c +++ b/src/da65/opctable.c @@ -38,6 +38,7 @@ #include "opc4510.h" #include "opc6502.h" #include "opc6502x.h" +#include "opc6502dtv.h" #include "opc65816.h" #include "opc65c02.h" #include "opc65sc02.h" @@ -70,6 +71,7 @@ void SetOpcTable (cpu_t CPU) switch (CPU) { case CPU_6502: OpcTable = OpcTable_6502; break; case CPU_6502X: OpcTable = OpcTable_6502X; break; + case CPU_6502DTV: OpcTable = OpcTable_6502DTV; break; case CPU_65SC02: OpcTable = OpcTable_65SC02; break; case CPU_65C02: OpcTable = OpcTable_65C02; break; case CPU_HUC6280: OpcTable = OpcTable_HuC6280; break; From 92c013944e40f0c0e956112050be42fc30386651 Mon Sep 17 00:00:00 2001 From: Zsolt Branyiczky <brazso@zematix.hu> Date: Fri, 13 Nov 2020 14:53:18 +0100 Subject: [PATCH 1786/2161] Mistyped comment, missing comma --- 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 99c0412b0..555c0a47b 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -315,7 +315,7 @@ static const struct { { { "ADC", 0x080A26C, 0x60, 0, PutAll }, { "ALR", 0x0800000, 0x4B, 0, PutAll }, /* X */ - { "ANC", 0x0800000, 0x0B, 0, PutAll }, /* X -DTV? */ + { "ANC", 0x0800000, 0x0B, 0, PutAll }, /* X, -DTV? */ { "AND", 0x080A26C, 0x20, 0, PutAll }, { "ANE", 0x0800000, 0x8B, 0, PutAll }, /* X */ { "ARR", 0x0800000, 0x6B, 0, PutAll }, /* X */ From 06dfef81a146c26e412eef76b67c6611bd1821ad Mon Sep 17 00:00:00 2001 From: Zsolt Branyiczky <brazso@zematix.hu> Date: Fri, 13 Nov 2020 16:24:17 +0100 Subject: [PATCH 1787/2161] Added 6502dtv description to cpu option --- doc/da65.sgml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/da65.sgml b/doc/da65.sgml index 466b41984..2394031d2 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -112,15 +112,17 @@ Here is a description of all the command line options: <itemize> <item>6502 <item>6502x + <item>6502dtv <item>65sc02 <item>65c02 <item>huc6280 <item>4510 </itemize> - 6502x is for the NMOS 6502 with unofficial opcodes. huc6280 is the CPU of - the PC engine. 4510 is the CPU of the Commodore C65. Support for the 65816 - currently is not available. + 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. Support for the 65816 currently + is not available. <label id="option--formfeeds"> @@ -251,7 +253,8 @@ 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. +manipulation and bit test-and-branch commands. Using 6502x as CPU the illegal opopcodes of 6502 CPU are detected and displayed. 6502dtv setting recognizes the emulated CPU instructons of the C64DTV device. + 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 From dd44dc4d7766dbd9b4fa39d5bcb39a28bcb5fbf5 Mon Sep 17 00:00:00 2001 From: Zsolt Branyiczky <brazso@zematix.hu> Date: Fri, 13 Nov 2020 16:28:59 +0100 Subject: [PATCH 1788/2161] Fix typo --- doc/da65.sgml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/da65.sgml b/doc/da65.sgml index 2394031d2..b46ee9dd3 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -253,7 +253,9 @@ 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 opopcodes of 6502 CPU are detected and displayed. 6502dtv setting recognizes the emulated CPU instructons of the C64DTV device. +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. When disassembling 4510 code, due to handling of 16-bit wide branches, da65 From 0f7cf87bfa4d60242095bd6d632f428b9e82a47f Mon Sep 17 00:00:00 2001 From: Zsolt Branyiczky <brazso@zematix.hu> Date: Fri, 13 Nov 2020 18:30:23 +0100 Subject: [PATCH 1789/2161] Synchronizin InsTab6502DTV instructions table for DTV with the illegal opcodes verified by VICE-emu tests --- src/ca65/instr.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 555c0a47b..c5e3b7fef 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -303,24 +303,25 @@ static const struct { } }; -/* Instruction table for the 6502 with illegal instructions (X) and DTV -** extra opcodes (DTV). Some illegal instructions (X, -DTV?) might be not -** supported by DTV. They should be tested on the DTV hardware. +/* Instruction table for the 6502 with DTV extra opcodes (DTV) and +** those illegal instructions (X) which are supported by DTV. +** Note: illegals opcodes which contain more subinstructions +** (ASO, DCM, LSE, LXA, SBX and SHS) are not enlisted. */ static const struct { unsigned Count; - InsDesc Ins[78]; + InsDesc Ins[71]; } InsTab6502DTV = { sizeof (InsTab6502DTV.Ins) / sizeof (InsTab6502DTV.Ins[0]), { { "ADC", 0x080A26C, 0x60, 0, PutAll }, { "ALR", 0x0800000, 0x4B, 0, PutAll }, /* X */ - { "ANC", 0x0800000, 0x0B, 0, PutAll }, /* X, -DTV? */ + { "ANC", 0x0800000, 0x0B, 0, PutAll }, /* X */ { "AND", 0x080A26C, 0x20, 0, PutAll }, { "ANE", 0x0800000, 0x8B, 0, PutAll }, /* X */ { "ARR", 0x0800000, 0x6B, 0, PutAll }, /* X */ { "ASL", 0x000006e, 0x02, 1, PutAll }, - { "AXS", 0x0800000, 0xCB, 0, PutAll }, /* X, -DTV? */ + { "AXS", 0x0800000, 0xCB, 0, PutAll }, /* X */ { "BCC", 0x0020000, 0x90, 0, PutPCRel8 }, { "BCS", 0x0020000, 0xb0, 0, PutPCRel8 }, { "BEQ", 0x0020000, 0xf0, 0, PutPCRel8 }, @@ -339,7 +340,6 @@ static const struct { { "CMP", 0x080A26C, 0xc0, 0, PutAll }, { "CPX", 0x080000C, 0xe0, 1, PutAll }, { "CPY", 0x080000C, 0xc0, 1, PutAll }, - { "DCP", 0x000A26C, 0xC3, 0, PutAll }, /* X */ { "DEC", 0x000006C, 0x00, 3, PutAll }, { "DEX", 0x0000001, 0xca, 0, PutAll }, { "DEY", 0x0000001, 0x88, 0, PutAll }, @@ -347,11 +347,9 @@ static const struct { { "INC", 0x000006c, 0x00, 4, PutAll }, { "INX", 0x0000001, 0xe8, 0, PutAll }, { "INY", 0x0000001, 0xc8, 0, PutAll }, - { "ISC", 0x000A26C, 0xE3, 0, PutAll }, /* X */ - { "JAM", 0x0000001, 0x02, 0, PutAll }, /* X, -DTV? */ { "JMP", 0x0000808, 0x4c, 6, PutJMP }, { "JSR", 0x0000008, 0x20, 7, PutAll }, - { "LAS", 0x0000200, 0xBB, 0, PutAll }, /* X, -DTV? */ + { "LAS", 0x0000200, 0xBB, 0, PutAll }, /* X */ { "LAX", 0x080A30C, 0xA3, 11, PutAll }, /* X */ { "LDA", 0x080A26C, 0xa0, 0, PutAll }, { "LDX", 0x080030C, 0xa2, 1, PutAll }, @@ -370,21 +368,17 @@ static const struct { { "RTI", 0x0000001, 0x40, 0, PutAll }, { "RTS", 0x0000001, 0x60, 0, PutAll }, { "SAC", 0x0800000, 0x32, 0, PutAll }, /* DTV */ - { "SAX", 0x000810C, 0x83, 1, PutAll }, /* X */ { "SBC", 0x080A26C, 0xe0, 0, PutAll }, { "SEC", 0x0000001, 0x38, 0, PutAll }, { "SED", 0x0000001, 0xf8, 0, PutAll }, { "SEI", 0x0000001, 0x78, 0, PutAll }, - { "SHA", 0x0002200, 0x93, 1, PutAll }, /* X, -DTV? */ - { "SHX", 0x0000200, 0x9e, 1, PutAll }, /* X, -DTV? */ - { "SHY", 0x0000040, 0x9c, 1, PutAll }, /* X, -DTV? */ + { "SHA", 0x0002200, 0x93, 1, PutAll }, /* X */ + { "SHX", 0x0000200, 0x9e, 1, PutAll }, /* X */ + { "SHY", 0x0000040, 0x9c, 1, PutAll }, /* X */ { "SIR", 0x0800000, 0x32, 0, PutAll }, /* DTV */ - { "SLO", 0x000A26C, 0x03, 0, PutAll }, /* X */ - { "SRE", 0x000A26C, 0x43, 0, PutAll }, /* X */ { "STA", 0x000A26C, 0x80, 0, PutAll }, { "STX", 0x000010c, 0x82, 1, PutAll }, { "STY", 0x000002c, 0x80, 1, PutAll }, - { "TAS", 0x0000200, 0x9b, 0, PutAll }, /* X */ { "TAX", 0x0000001, 0xaa, 0, PutAll }, { "TAY", 0x0000001, 0xa8, 0, PutAll }, { "TSX", 0x0000001, 0xba, 0, PutAll }, From 2d7777b6045415845c34bc5fd1f654f7727144df Mon Sep 17 00:00:00 2001 From: Zsolt Branyiczky <brazso@zematix.hu> Date: Sat, 14 Nov 2020 11:00:50 +0100 Subject: [PATCH 1790/2161] Instruction table is synchronized with the c65's one --- src/da65/opc6502dtv.c | 94 +++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/src/da65/opc6502dtv.c b/src/da65/opc6502dtv.c index 73bce7f4d..15b860c4e 100644 --- a/src/da65/opc6502dtv.c +++ b/src/da65/opc6502dtv.c @@ -45,18 +45,18 @@ -/* Descriptions for all opcodes. Base table from opc6502.c with illegal -** opcodes from http://www.oxyron.de/html/opcodes02.html and DTV opcodes +/* Descriptions for all opcodes. Base table from opc6502x.c with DTV opcodes, +** where illegal opcodes are filtered based on their support on DTV. */ const OpcDesc OpcTable_6502DTV[256] = { { "brk", 1, flNone, OH_Implicit }, /* $00 */ { "ora", 2, flUseLabel, OH_DirectXIndirect }, /* $01 */ - { "jam", 1, flNone, OH_Implicit }, /* $02 */ - { "slo", 2, flUseLabel, OH_DirectXIndirect }, /* $03 */ + { "", 1, flIllegal, OH_Illegal, }, /* $02 */ + { "", 1, flIllegal, OH_Illegal, }, /* $03 */ { "nop", 2, flUseLabel, OH_Direct }, /* $04 */ { "ora", 2, flUseLabel, OH_Direct }, /* $05 */ { "asl", 2, flUseLabel, OH_Direct }, /* $06 */ - { "slo", 2, flUseLabel, OH_Direct }, /* $07 */ + { "", 1, flIllegal, OH_Illegal, }, /* $07 */ { "php", 1, flNone, OH_Implicit }, /* $08 */ { "ora", 2, flNone, OH_Immediate }, /* $09 */ { "asl", 1, flNone, OH_Accumulator }, /* $0a */ @@ -64,26 +64,26 @@ const OpcDesc OpcTable_6502DTV[256] = { { "nop", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0c */ { "ora", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0d */ { "asl", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0e */ - { "slo", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0f */ + { "", 1, flIllegal, OH_Illegal, }, /* $0f */ { "bpl", 2, flLabel, OH_Relative }, /* $10 */ { "ora", 2, flUseLabel, OH_DirectIndirectY }, /* $11 */ { "bra", 2, flLabel, OH_Relative }, /* $12 */ - { "slo", 2, flUseLabel, OH_DirectIndirectY }, /* $13 */ + { "", 1, flIllegal, OH_Illegal, }, /* $13 */ { "nop", 2, flUseLabel, OH_DirectX }, /* $14 */ { "ora", 2, flUseLabel, OH_DirectX }, /* $15 */ { "asl", 2, flUseLabel, OH_DirectX }, /* $16 */ - { "slo", 2, flUseLabel, OH_DirectX }, /* $17 */ + { "", 1, flIllegal, OH_Illegal, }, /* $17 */ { "clc", 1, flNone, OH_Implicit }, /* $18 */ { "ora", 3, flUseLabel, OH_AbsoluteY }, /* $19 */ { "nop", 1, flNone, OH_Implicit }, /* $1a */ - { "slo", 3, flUseLabel, OH_AbsoluteY }, /* $1b */ + { "", 1, flIllegal, OH_Illegal, }, /* $1b */ { "nop", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1c */ { "ora", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1d */ { "asl", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1e */ - { "slo", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1f */ + { "", 1, flIllegal, OH_Illegal, }, /* $1f */ { "jsr", 3, flLabel, OH_Absolute }, /* $20 */ { "and", 2, flUseLabel, OH_DirectXIndirect }, /* $21 */ - { "jam", 1, flNone, OH_Implicit, }, /* $22 */ + { "", 1, flIllegal, OH_Illegal, }, /* $22 */ { "rla", 2, flUseLabel, OH_DirectXIndirect }, /* $23 */ { "bit", 2, flUseLabel, OH_Direct }, /* $24 */ { "and", 2, flUseLabel, OH_Direct }, /* $25 */ @@ -116,11 +116,11 @@ const OpcDesc OpcTable_6502DTV[256] = { { "rti", 1, flNone, OH_Rts }, /* $40 */ { "eor", 2, flUseLabel, OH_DirectXIndirect }, /* $41 */ { "sir", 1, flNone, OH_Implicit }, /* $42 */ - { "sre", 2, flUseLabel, OH_DirectXIndirect }, /* $43 */ + { "", 1, flIllegal, OH_Illegal, }, /* $43 */ { "nop", 2, flUseLabel, OH_Direct }, /* $44 */ { "eor", 2, flUseLabel, OH_Direct }, /* $45 */ { "lsr", 2, flUseLabel, OH_Direct }, /* $46 */ - { "sre", 2, flUseLabel, OH_Direct }, /* $47 */ + { "", 1, flIllegal, OH_Illegal, }, /* $47 */ { "pha", 1, flNone, OH_Implicit }, /* $48 */ { "eor", 2, flNone, OH_Immediate }, /* $49 */ { "lsr", 1, flNone, OH_Accumulator }, /* $4a */ @@ -128,26 +128,26 @@ const OpcDesc OpcTable_6502DTV[256] = { { "jmp", 3, flLabel, OH_JmpAbsolute }, /* $4c */ { "eor", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4d */ { "lsr", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4e */ - { "sre", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4f */ + { "", 1, flIllegal, OH_Illegal, }, /* $4f */ { "bvc", 2, flLabel, OH_Relative }, /* $50 */ { "eor", 2, flUseLabel, OH_DirectIndirectY }, /* $51 */ - { "jam", 1, flNone, OH_Implicit }, /* $52 */ - { "sre", 2, flUseLabel, OH_DirectIndirectY }, /* $53 */ + { "", 1, flIllegal, OH_Illegal, }, /* $52 */ + { "", 1, flIllegal, OH_Illegal, }, /* $53 */ { "nop", 2, flUseLabel, OH_DirectX }, /* $54 */ { "eor", 2, flUseLabel, OH_DirectX }, /* $55 */ { "lsr", 2, flUseLabel, OH_DirectX }, /* $56 */ - { "sre", 2, flUseLabel, OH_DirectX }, /* $57 */ + { "", 1, flIllegal, OH_Illegal, }, /* $57 */ { "cli", 1, flNone, OH_Implicit }, /* $58 */ { "eor", 3, flUseLabel, OH_AbsoluteY }, /* $59 */ { "nop", 1, flNone, OH_Implicit }, /* $5a */ - { "sre", 3, flUseLabel, OH_AbsoluteY }, /* $5b */ + { "", 1, flIllegal, OH_Illegal, }, /* $5b */ { "nop", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5c */ { "eor", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5d */ { "lsr", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5e */ - { "sre", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5f */ + { "", 1, flIllegal, OH_Illegal, }, /* $5f */ { "rts", 1, flNone, OH_Rts }, /* $60 */ { "adc", 2, flUseLabel, OH_DirectXIndirect }, /* $61 */ - { "jam", 1, flNone, OH_Implicit }, /* $62 */ + { "", 1, flIllegal, OH_Illegal, }, /* $62 */ { "rra", 2, flUseLabel, OH_DirectXIndirect }, /* $63 */ { "nop", 2, flUseLabel, OH_Direct }, /* $64 */ { "adc", 2, flUseLabel, OH_Direct }, /* $65 */ @@ -163,7 +163,7 @@ const OpcDesc OpcTable_6502DTV[256] = { { "rra", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $6f */ { "bvs", 2, flLabel, OH_Relative }, /* $70 */ { "adc", 2, flUseLabel, OH_DirectIndirectY }, /* $71 */ - { "jam", 1, flNone, OH_Implicit }, /* $72 */ + { "", 1, flIllegal, OH_Illegal, }, /* $72 */ { "rra", 2, flUseLabel, OH_DirectIndirectY }, /* $73 */ { "nop", 2, flUseLabel, OH_DirectX }, /* $74 */ { "adc", 2, flUseLabel, OH_DirectX }, /* $75 */ @@ -180,35 +180,35 @@ const OpcDesc OpcTable_6502DTV[256] = { { "nop", 2, flNone, OH_Immediate }, /* $80 */ { "sta", 2, flUseLabel, OH_DirectXIndirect }, /* $81 */ { "nop", 2, flNone, OH_Immediate }, /* $82 */ - { "sax", 2, flUseLabel, OH_DirectXIndirect }, /* $83 */ + { "", 1, flIllegal, OH_Illegal, }, /* $83 */ { "sty", 2, flUseLabel, OH_Direct }, /* $84 */ { "sta", 2, flUseLabel, OH_Direct }, /* $85 */ { "stx", 2, flUseLabel, OH_Direct }, /* $86 */ - { "sax", 2, flUseLabel, OH_Direct }, /* $87 */ + { "", 1, flIllegal, OH_Illegal, }, /* $87 */ { "dey", 1, flNone, OH_Implicit }, /* $88 */ { "nop", 2, flNone, OH_Immediate }, /* $89 */ { "txa", 1, flNone, OH_Implicit }, /* $8a */ - { "xaa", 2, flNone, OH_Immediate }, /* $8b */ + { "", 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 */ - { "sax", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8f */ + { "", 1, flIllegal, OH_Illegal, }, /* $8f */ { "bcc", 2, flLabel, OH_Relative }, /* $90 */ { "sta", 2, flUseLabel, OH_DirectIndirectY }, /* $91 */ - { "jam", 1, flNone, OH_Implicit }, /* $92 */ - { "ahx", 2, flUseLabel, OH_DirectIndirectY }, /* $93 */ + { "", 1, flIllegal, OH_Illegal, }, /* $92 */ + { "", 1, flIllegal, OH_Illegal, }, /* $93 */ { "sty", 2, flUseLabel, OH_DirectX }, /* $94 */ { "sta", 2, flUseLabel, OH_DirectX }, /* $95 */ { "stx", 2, flUseLabel, OH_DirectY }, /* $96 */ - { "sax", 2, flUseLabel, OH_DirectY }, /* $97 */ + { "", 1, flIllegal, OH_Illegal, }, /* $97 */ { "tya", 1, flNone, OH_Implicit }, /* $98 */ { "sta", 3, flUseLabel, OH_AbsoluteY }, /* $99 */ { "txs", 1, flNone, OH_Implicit }, /* $9a */ - { "tas", 3, flUseLabel, OH_AbsoluteY }, /* $9b */ + { "", 1, flIllegal, OH_Illegal, }, /* $9b */ { "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 */ + { "", 1, flIllegal, OH_Illegal, }, /* $9f */ { "ldy", 2, flNone, OH_Immediate }, /* $a0 */ { "lda", 2, flUseLabel, OH_DirectXIndirect }, /* $a1 */ { "ldx", 2, flNone, OH_Immediate }, /* $a2 */ @@ -227,7 +227,7 @@ const OpcDesc OpcTable_6502DTV[256] = { { "lax", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $af */ { "bcs", 2, flLabel, OH_Relative }, /* $b0 */ { "lda", 2, flUseLabel, OH_DirectIndirectY }, /* $b1 */ - { "jam", 1, flNone, OH_Implicit }, /* $b2 */ + { "", 1, flIllegal, OH_Illegal, }, /* $b2 */ { "lax", 2, flUseLabel, OH_DirectIndirectY }, /* $b3 */ { "ldy", 2, flUseLabel, OH_DirectX }, /* $b4 */ { "lda", 2, flUseLabel, OH_DirectX }, /* $b5 */ @@ -244,11 +244,11 @@ const OpcDesc OpcTable_6502DTV[256] = { { "cpy", 2, flNone, OH_Immediate }, /* $c0 */ { "cmp", 2, flUseLabel, OH_DirectXIndirect }, /* $c1 */ { "nop", 2, flNone, OH_Immediate }, /* $c2 */ - { "dcp", 2, flUseLabel, OH_DirectXIndirect }, /* $c3 */ + { "", 1, flIllegal, OH_Illegal, }, /* $c3 */ { "cpy", 2, flUseLabel, OH_Direct }, /* $c4 */ { "cmp", 2, flUseLabel, OH_Direct }, /* $c5 */ { "dec", 2, flUseLabel, OH_Direct }, /* $c6 */ - { "dcp", 2, flUseLabel, OH_Direct }, /* $c7 */ + { "", 1, flIllegal, OH_Illegal, }, /* $c7 */ { "iny", 1, flNone, OH_Implicit }, /* $c8 */ { "cmp", 2, flNone, OH_Immediate }, /* $c9 */ { "dex", 1, flNone, OH_Implicit }, /* $ca */ @@ -256,31 +256,31 @@ const OpcDesc OpcTable_6502DTV[256] = { { "cpy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cc */ { "cmp", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cd */ { "dec", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ce */ - { "dcp", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cf */ + { "", 1, flIllegal, OH_Illegal, }, /* $cf */ { "bne", 2, flLabel, OH_Relative }, /* $d0 */ { "cmp", 2, flUseLabel, OH_DirectIndirectY }, /* $d1 */ - { "jam", 1, flNone, OH_Implicit }, /* $d2 */ - { "dcp", 2, flUseLabel, OH_DirectIndirectY }, /* $d3 */ + { "", 1, flIllegal, OH_Illegal, }, /* $d2 */ + { "", 1, flIllegal, OH_Illegal, }, /* $d3 */ { "nop", 2, flUseLabel, OH_DirectX }, /* $d4 */ { "cmp", 2, flUseLabel, OH_DirectX }, /* $d5 */ { "dec", 2, flUseLabel, OH_DirectX }, /* $d6 */ - { "dcp", 2, flUseLabel, OH_DirectX }, /* $d7 */ + { "", 1, flIllegal, OH_Illegal, }, /* $d7 */ { "cld", 1, flNone, OH_Implicit }, /* $d8 */ { "cmp", 3, flUseLabel, OH_AbsoluteY }, /* $d9 */ { "nop", 1, flNone, OH_Implicit }, /* $da */ - { "dcp", 3, flUseLabel, OH_AbsoluteY }, /* $db */ + { "", 1, flIllegal, OH_Illegal, }, /* $db */ { "nop", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $dc */ { "cmp", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $dd */ { "dec", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $de */ - { "dcp", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $df */ + { "", 1, flIllegal, OH_Illegal, }, /* $df */ { "cpx", 2, flNone, OH_Immediate }, /* $e0 */ { "sbc", 2, flUseLabel, OH_DirectXIndirect }, /* $e1 */ { "nop", 2, flNone, OH_Immediate }, /* $e2 */ - { "isc", 2, flUseLabel, OH_DirectXIndirect }, /* $e3 */ + { "", 1, flIllegal, OH_Illegal, }, /* $e3 */ { "cpx", 2, flUseLabel, OH_Direct }, /* $e4 */ { "sbc", 2, flUseLabel, OH_Direct }, /* $e5 */ { "inc", 2, flUseLabel, OH_Direct }, /* $e6 */ - { "isc", 2, flUseLabel, OH_Direct }, /* $e7 */ + { "", 1, flIllegal, OH_Illegal, }, /* $e7 */ { "inx", 1, flNone, OH_Implicit }, /* $e8 */ { "sbc", 2, flNone, OH_Immediate }, /* $e9 */ { "nop", 1, flNone, OH_Implicit }, /* $ea */ @@ -288,21 +288,21 @@ const OpcDesc OpcTable_6502DTV[256] = { { "cpx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ec */ { "sbc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ed */ { "inc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ee */ - { "isc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ef */ + { "", 1, flIllegal, OH_Illegal, }, /* $ef */ { "beq", 2, flLabel, OH_Relative }, /* $f0 */ { "sbc", 2, flUseLabel, OH_DirectIndirectY }, /* $f1 */ - { "jam", 1, flNone, OH_Implicit }, /* $f2 */ - { "isc", 2, flUseLabel, OH_DirectIndirectY }, /* $f3 */ + { "", 1, flIllegal, OH_Illegal, }, /* $f2 */ + { "", 1, flIllegal, OH_Illegal, }, /* $f3 */ { "nop", 2, flUseLabel, OH_DirectX }, /* $f4 */ { "sbc", 2, flUseLabel, OH_DirectX }, /* $f5 */ { "inc", 2, flUseLabel, OH_DirectX }, /* $f6 */ - { "isc", 2, flUseLabel, OH_DirectX }, /* $f7 */ + { "", 1, flIllegal, OH_Illegal, }, /* $f7 */ { "sed", 1, flNone, OH_Implicit }, /* $f8 */ { "sbc", 3, flUseLabel, OH_AbsoluteY }, /* $f9 */ { "nop", 1, flNone, OH_Implicit }, /* $fa */ - { "isc", 3, flUseLabel, OH_AbsoluteY }, /* $fb */ + { "", 1, flIllegal, OH_Illegal, }, /* $fb */ { "nop", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fc */ { "sbc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fd */ { "inc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fe */ - { "isc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $ff */ + { "", 1, flIllegal, OH_Illegal, }, /* $ff */ }; From 5f65252fa6197c5ec635a9f5b4bec2cad60c70fb Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 15 Nov 2020 11:44:12 -0500 Subject: [PATCH 1791/2161] Added the cputdirect entry point to the cputc() functions in the two Oric libraries. It now is available in all libraries that have cputc(). --- libsrc/atmos/cputc.s | 6 +++--- libsrc/telestrat/cputc.s | 10 ++++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/libsrc/atmos/cputc.s b/libsrc/atmos/cputc.s index f1ce5f2b7..db3fa373d 100644 --- a/libsrc/atmos/cputc.s +++ b/libsrc/atmos/cputc.s @@ -7,7 +7,7 @@ ; .export _cputcxy, _cputc - .export setscrptr, putchar + .export setscrptr, cputdirect, putchar .constructor initcputc .import rvs .import popax @@ -32,13 +32,13 @@ _cputc: cmp #$0D ; CR? rts L1: cmp #$0A ; LF? - bne output + bne cputdirect inc CURS_Y ; Newline rts ; Output the character, then advance the cursor position -output: +cputdirect: jsr putchar advance: diff --git a/libsrc/telestrat/cputc.s b/libsrc/telestrat/cputc.s index 38f8af84b..4b2fc4024 100644 --- a/libsrc/telestrat/cputc.s +++ b/libsrc/telestrat/cputc.s @@ -4,15 +4,17 @@ ; void cputc (char c); ; - .export _cputc, CHARCOLOR, OLD_CHARCOLOR, BGCOLOR, OLD_BGCOLOR + .export _cputc, cputdirect + .export CHARCOLOR, OLD_CHARCOLOR, BGCOLOR, OLD_BGCOLOR .include "telestrat.inc" +cputdirect: .proc _cputc ldx CHARCOLOR cpx OLD_CHARCOLOR beq do_not_change_color_foreground - + stx OLD_CHARCOLOR ; Store CHARCOLOR into OLD_CHARCOLOR dec SCRX @@ -47,8 +49,8 @@ do_not_change_color: CHARCOLOR: .res 1 OLD_CHARCOLOR: - .res 1 + .res 1 BGCOLOR: - .res 1 + .res 1 OLD_BGCOLOR: .res 1 From 2915464667e3098478f94d1a7b46e88f4fa8c6b5 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 15 Nov 2020 15:22:23 -0500 Subject: [PATCH 1792/2161] Fixed cc65's generation of char-type bit-shift code. Fixed CHAR-to-INT type conversions in the right-shift code generator. Also fixed some printf-style format specifiers. --- src/cc65/codegen.c | 52 ++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index aee6141fc..f56abcd95 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -3104,16 +3104,14 @@ void g_asr (unsigned flags, unsigned long val) "tosasrax", "tosshrax", "tosasreax", "tosshreax" }; - /* If the right hand side is const, the lhs is not on stack but still + /* If the right hand side is const, the lhs is not on stack, but still ** in the primary register. */ if (flags & CF_CONST) { - switch (flags & CF_TYPEMASK) { - case CF_CHAR: if (flags & CF_FORCECHAR) { - if ((flags & CF_UNSIGNED) != 0 && val <= 4) { + if ((flags & CF_UNSIGNED) != 0 && val < 8) { while (val--) { AddCodeLine ("lsr a"); } @@ -3125,19 +3123,28 @@ void g_asr (unsigned flags, unsigned long val) } return; } + AddCodeLine ("ldx #$00"); + if ((flags & CF_UNSIGNED) == 0) { + unsigned L = GetLocalLabel (); + + AddCodeLine ("cmp #$80"); /* Sign bit into carry */ + AddCodeLine ("bcc %s", LocalLabelName (L)); + AddCodeLine ("dex"); /* Make $FF */ + g_defcodelabel (L); + } } /* FALLTHROUGH */ case CF_INT: val &= 0x0F; if (val >= 8) { + AddCodeLine ("txa"); if (flags & CF_UNSIGNED) { - AddCodeLine ("txa"); AddCodeLine ("ldx #$00"); } else { - unsigned L = GetLocalLabel(); + unsigned L = GetLocalLabel (); + AddCodeLine ("cpx #$80"); /* Sign bit into carry */ - AddCodeLine ("txa"); AddCodeLine ("ldx #$00"); AddCodeLine ("bcc %s", LocalLabelName (L)); AddCodeLine ("dex"); /* Make $FF */ @@ -3155,9 +3162,9 @@ void g_asr (unsigned flags, unsigned long val) } if (val > 0) { if (flags & CF_UNSIGNED) { - AddCodeLine ("jsr shrax%ld", val); + AddCodeLine ("jsr shrax%lu", val); } else { - AddCodeLine ("jsr asrax%ld", val); + AddCodeLine ("jsr asrax%lu", val); } } return; @@ -3168,7 +3175,8 @@ void g_asr (unsigned flags, unsigned long val) AddCodeLine ("ldx #$00"); AddCodeLine ("lda sreg+1"); if ((flags & CF_UNSIGNED) == 0) { - unsigned L = GetLocalLabel(); + unsigned L = GetLocalLabel (); + AddCodeLine ("bpl %s", LocalLabelName (L)); AddCodeLine ("dex"); g_defcodelabel (L); @@ -3181,7 +3189,8 @@ void g_asr (unsigned flags, unsigned long val) AddCodeLine ("ldy #$00"); AddCodeLine ("ldx sreg+1"); if ((flags & CF_UNSIGNED) == 0) { - unsigned L = GetLocalLabel(); + unsigned L = GetLocalLabel (); + AddCodeLine ("bpl %s", LocalLabelName (L)); AddCodeLine ("dey"); g_defcodelabel (L); @@ -3197,7 +3206,8 @@ void g_asr (unsigned flags, unsigned long val) AddCodeLine ("ldy sreg+1"); AddCodeLine ("sty sreg"); if ((flags & CF_UNSIGNED) == 0) { - unsigned L = GetLocalLabel(); + unsigned L = GetLocalLabel (); + AddCodeLine ("cpy #$80"); AddCodeLine ("ldy #$00"); AddCodeLine ("bcc %s", LocalLabelName (L)); @@ -3219,9 +3229,9 @@ void g_asr (unsigned flags, unsigned long val) } if (val > 0) { if (flags & CF_UNSIGNED) { - AddCodeLine ("jsr shreax%ld", val); + AddCodeLine ("jsr shreax%lu", val); } else { - AddCodeLine ("jsr asreax%ld", val); + AddCodeLine ("jsr asreax%lu", val); } } return; @@ -3251,15 +3261,13 @@ void g_asl (unsigned flags, unsigned long val) "tosaslax", "tosshlax", "tosasleax", "tosshleax" }; - /* If the right hand side is const, the lhs is not on stack but still + /* If the right hand side is const, the lhs is not on stack, but still ** in the primary register. */ if (flags & CF_CONST) { - switch (flags & CF_TYPEMASK) { - case CF_CHAR: - if ((flags & CF_FORCECHAR) != 0 && val <= 4) { + if ((flags & CF_FORCECHAR) != 0 && val <= 6) { while (val--) { AddCodeLine ("asl a"); } @@ -3284,9 +3292,9 @@ void g_asl (unsigned flags, unsigned long val) } if (val > 0) { if (flags & CF_UNSIGNED) { - AddCodeLine ("jsr shlax%ld", val); + AddCodeLine ("jsr shlax%lu", val); } else { - AddCodeLine ("jsr aslax%ld", val); + AddCodeLine ("jsr aslax%lu", val); } } return; @@ -3325,9 +3333,9 @@ void g_asl (unsigned flags, unsigned long val) } if (val > 0) { if (flags & CF_UNSIGNED) { - AddCodeLine ("jsr shleax%ld", val); + AddCodeLine ("jsr shleax%lu", val); } else { - AddCodeLine ("jsr asleax%ld", val); + AddCodeLine ("jsr asleax%lu", val); } } return; From 83ac2755fecfc22f4261433b7f38ca4d6e171d4c Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sun, 15 Nov 2020 10:16:32 +0100 Subject: [PATCH 1793/2161] Add test case for #1332 --- test/todo/bug1332.c | 72 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 test/todo/bug1332.c diff --git a/test/todo/bug1332.c b/test/todo/bug1332.c new file mode 100644 index 000000000..9714e0782 --- /dev/null +++ b/test/todo/bug1332.c @@ -0,0 +1,72 @@ +/* + Copyright 2020 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. +*/ + +/* + Tests bit-field bug. https://github.com/cc65/cc65/issues/1332 +*/ + +#include <stdio.h> +#include <string.h> + +static unsigned char failures = 0; + +static const struct bitfield { + unsigned lsb : 1; + unsigned pad : 14; + unsigned msb : 1; +} b = {1, 0, 1}; + +static unsigned v; + +void test_if_val (void) +{ + /* Gets appropriate garbage (0x12) into .X so the test fails. */ + v = 0x1234; + + if (b.msb == 1) { + fprintf (stderr, "if (msb == 1) OK\n"); + } else { + fprintf (stderr, "if (msb == 1) FAILED\n"); + failures++; + } +} + +void test_sprintf (void) +/* This test case is similar to the original bug report. */ +{ + char buf[10]; + snprintf (buf, sizeof (buf), "%u", b.msb); + + if (strcmp (buf, "1") != 0) { + fprintf (stderr, "Expected: sprintf (msb) == \"1\", got: %s\n", buf); + failures++; + } else { + fprintf (stderr, "sprintf (msb) OK\n"); + } +} + +int main (void) +{ + test_if_val (); + test_sprintf (); + + printf ("failures: %u\n", failures); + return failures; +} From 060417b0dc1018adc79fd16d0eb97c61d729aea3 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sat, 31 Oct 2020 21:27:41 +0100 Subject: [PATCH 1794/2161] Adjust type of int constants that fit in char When there is an integral constant like `3` in an expression, it has type `int` according to the C spec, even though it can be represented as an `unsigned char`. Change codegen (`hie_internal` and `typeadjust`) to treat it as `unsigned char` instead of `int` so that faster, unsigned operations can be used. For the test case in #1298, reduces the cycles per iteration from 4311 to 1884. This is a great improvement, but still much worse than the 1053 cycles/iter from `c4698df~`, so more work remains to be done. Further partial fix for #1298 and #1308. --- src/cc65/expr.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 19572944e..7ddd8f43a 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -219,6 +219,13 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); + if (ED_IsConstAbsInt (lhs) && ltype == CF_INT && lhs->IVal >= 0 && lhs->IVal < 256) { + /* If the lhs is a int constant that fits in an unsigned char, use unsigned char. + ** g_typeadjust will either promote this to int or unsigned int as appropriate + ** based on the other operand. See comment in hie_internal. + */ + ltype = CF_CHAR | CF_UNSIGNED; + } if (ED_IsLocNone (lhs)) { ltype |= CF_CONST; } @@ -227,6 +234,9 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) ltype |= CF_PRIMARY; } rtype = TypeOf (rhst); + if (ED_IsConstAbsInt (rhs) && rtype == CF_INT && rhs->IVal >= 0 && rhs->IVal < 256) { + rtype = CF_CHAR | CF_UNSIGNED; + } if (ED_IsLocNone (rhs)) { rtype |= CF_CONST; } @@ -2502,6 +2512,15 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */ } } else if (lconst && (Gen->Flags & GEN_COMM) && !rconst) { + /* If the LHS constant is an int that fits into an unsigned char, change the + ** codegen type to unsigned char. If the RHS is also an unsigned char, then + ** g_typeadjust will return unsigned int (instead of int, which would be + ** returned without this modification). This allows more efficient operations, + ** but does not affect correctness for the same reasons explained in g_typeadjust. + */ + if (ltype == CF_INT && Expr->IVal >= 0 && Expr->IVal < 256) { + ltype = CF_CHAR | CF_UNSIGNED; + } /* The left side is constant, the right side is not, and the ** operator allows swapping the operands. We haven't pushed the @@ -2536,6 +2555,10 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */ unsigned rtype = TypeOf (Expr2.Type); type = 0; if (rconst) { + /* As above, but for the RHS. */ + if (rtype == CF_INT && Expr2.IVal >= 0 && Expr2.IVal < 256) { + rtype = CF_CHAR | CF_UNSIGNED; + } /* Second value is constant - check for div */ type |= CF_CONST; rtype |= CF_CONST; From c2c73e7d06f53ab6d0c5613fd9ef7ff4793200bf Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Mon, 16 Nov 2020 09:10:53 +0100 Subject: [PATCH 1795/2161] Move #1332 test from todo/ to val/ This bug was fixed by 2915464. --- test/{todo => val}/bug1332.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{todo => val}/bug1332.c (100%) diff --git a/test/todo/bug1332.c b/test/val/bug1332.c similarity index 100% rename from test/todo/bug1332.c rename to test/val/bug1332.c From 116682c19022ff6d7e314569c62b15cb31fd4215 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 16 Nov 2020 18:07:39 +0100 Subject: [PATCH 1796/2161] Avoid C99 idioms. --- src/cc65/datatype.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index e5e20ac1f..413007a85 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -124,7 +124,8 @@ static struct StrBuf* GetFullTypeNameWestEast (struct StrBuf* West, struct StrBu /* First argument */ SymEntry* Param = D->SymTab->SymHead; - for (unsigned I = 0; I < D->ParamCount; ++I) { + unsigned I; + for (I = 0; I < D->ParamCount; ++I) { CHECK (Param != 0 && (Param->Flags & SC_PARAM) != 0); if (I > 0) { SB_AppendStr (&ParamList, ", "); @@ -602,7 +603,8 @@ void PrintFuncSig (FILE* F, const char* Name, Type* T) /* Get the parameter list string. Start from the first parameter */ SymEntry* Param = D->SymTab->SymHead; - for (unsigned I = 0; I < D->ParamCount; ++I) { + unsigned I; + for (I = 0; I < D->ParamCount; ++I) { CHECK (Param != 0 && (Param->Flags & SC_PARAM) != 0); if (I > 0) { SB_AppendStr (&ParamList, ", "); From 69c0363c7e0be4a230f00616da69ea9fdcf80c0b Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 16 Nov 2020 18:50:15 +0100 Subject: [PATCH 1797/2161] Fixed CPU bitmask constants to match the CPU instruction set bitmasks computed in src/common/cpu.h. --- asminc/cpu.mac | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/asminc/cpu.mac b/asminc/cpu.mac index 55727c93e..31170fbed 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -2,23 +2,23 @@ CPU_ISET_NONE = $0001 CPU_ISET_6502 = $0002 CPU_ISET_6502X = $0004 -CPU_ISET_65SC02 = $0008 -CPU_ISET_65C02 = $0010 -CPU_ISET_65816 = $0020 -CPU_ISET_SWEET16 = $0040 -CPU_ISET_HUC6280 = $0080 -;CPU_ISET_M740 = $0100 not actually implemented -CPU_ISET_4510 = $0200 -CPU_ISET_6502DTV = $0400 +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 not actually implemented +CPU_ISET_4510 = $0400 ; CPU capabilities 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_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 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_6502DTV = CPU_ISET_6502|CPU_ISET_6502X|CPU_ISET_6502DTV From 0cd8d3761310b0c1b3fdfc349611333a502587bb Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 17 Nov 2020 08:53:48 +0100 Subject: [PATCH 1798/2161] Fixed comment. --- libsrc/atari/doesclrscr.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/atari/doesclrscr.s b/libsrc/atari/doesclrscr.s index 2e19e4b98..f937f9ac5 100644 --- a/libsrc/atari/doesclrscr.s +++ b/libsrc/atari/doesclrscr.s @@ -1,7 +1,7 @@ ; ; Christian Groessler, June-2016 ; -; unsigned char doesclrscr(void); +; unsigned char doesclrscrafterexit (void); ; ; returns 0/1 if after program termination the screen isn't/is cleared ; From 68cb15d0f91df5508ea783214110d98bc3433c3f Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Mon, 16 Nov 2020 13:29:07 +0100 Subject: [PATCH 1799/2161] Add test case for #1320 From https://github.com/cc65/cc65/issues/1320#issuecomment-726866015 --- test/err/bug1320.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 test/err/bug1320.c diff --git a/test/err/bug1320.c b/test/err/bug1320.c new file mode 100644 index 000000000..14e72fe99 --- /dev/null +++ b/test/err/bug1320.c @@ -0,0 +1,35 @@ +/* + Copyright 2020 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 access violation. + https://github.com/cc65/cc65/issues/1320 + This should compile and should be moved to tests/val/ when the bug is fixed. +*/ + +char *var; + +void foo (char, char); +char bar (void); + +void main (void) +{ + foo (*var++, bar ()); +} From 2ffb6af5d9dc699477b539e759e597205ca4ed93 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 17 Nov 2020 08:15:34 -0500 Subject: [PATCH 1800/2161] Simplified a bug test. Gave it an appropriate description, --- test/err/bug1320.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/test/err/bug1320.c b/test/err/bug1320.c index 14e72fe99..15482434c 100644 --- a/test/err/bug1320.c +++ b/test/err/bug1320.c @@ -1,35 +1,38 @@ /* Copyright 2020 The cc65 Authors - This software is provided 'as-is', without any express or implied + 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 + 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. + 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 access violation. + Test of a post-counted pointer argument, + followed by a (nested) function-call argument. + https://github.com/cc65/cc65/issues/1320 - This should compile and should be moved to tests/val/ when the bug is fixed. + + After the bug is fixed, this file should be moved to "test/misc/". */ -char *var; +static char *var; -void foo (char, char); +void foo (char *, char); char bar (void); void main (void) { - foo (*var++, bar ()); + foo (var++, bar ()); } From 47bceb0eab4bd040ca9516d8c5eca8a2ca2f24d4 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 17 Nov 2020 13:34:22 -0500 Subject: [PATCH 1801/2161] Streamlined some makefiles. foreach isn't needed because make automatically iterates through lists of words when substituting patterns. --- test/asm/Makefile | 26 +++++++++++++------------- test/dasm/Makefile | 11 +++++------ 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/test/asm/Makefile b/test/asm/Makefile index 9b0aa582e..0cf65f9ca 100644 --- a/test/asm/Makefile +++ b/test/asm/Makefile @@ -7,7 +7,7 @@ endif ifdef CMD_EXE EXE = .exe MKDIR = mkdir $(subst /,\,$1) - RMDIR = -rmdir /s /q $(subst /,\,$1) + RMDIR = -rmdir /q /s $(subst /,\,$1) else EXE = MKDIR = mkdir -p $1 @@ -23,7 +23,7 @@ LD65 := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) WORKDIR = ../../testwrk/asm -ISEQUAL = $(WORKDIR)/isequal$(EXE) +ISEQUAL = ../../testwrk/isequal$(EXE) CC = gcc CFLAGS = -O2 @@ -31,12 +31,12 @@ CFLAGS = -O2 .PHONY: all clean OPCODE_REFS := $(wildcard *-opcodes.ref) -OPCODE_CPUS = $(foreach ref,$(OPCODE_REFS),$(ref:%-opcodes.ref=%)) -OPCODE_BINS = $(foreach cpu,$(OPCODE_CPUS),$(WORKDIR)/$(cpu)-opcodes.bin) +OPCODE_BINS = $(OPCODE_REFS:%.ref=$(WORKDIR)/%.bin) +OPCODE_CPUS = $(OPCODE_REFS:%-opcodes.ref=%) CPUDETECT_REFS := $(wildcard *-cpudetect.ref) -CPUDETECT_CPUS = $(foreach ref,$(CPUDETECT_REFS),$(ref:%-cpudetect.ref=%)) -CPUDETECT_BINS = $(foreach cpu,$(CPUDETECT_CPUS),$(WORKDIR)/$(cpu)-cpudetect.bin) +CPUDETECT_BINS = $(CPUDETECT_REFS:%.ref=$(WORKDIR)/%.bin) +CPUDETECT_CPUS = $(CPUDETECT_REFS:%-cpudetect.ref=%) all: $(OPCODE_BINS) $(CPUDETECT_BINS) $(WORKDIR)/paramcount.o @@ -50,9 +50,9 @@ define OPCODE_template $(WORKDIR)/$1-opcodes.bin: $1-opcodes.s $(ISEQUAL) $(if $(QUIET),echo asm/$1-opcodes.bin) - $(CA65) --cpu $1 -t none -l $(WORKDIR)/$1-opcodes.lst -o $(WORKDIR)/$1-opcodes.o $$< - $(LD65) -t none -o $$@ $(WORKDIR)/$1-opcodes.o none.lib - $(ISEQUAL) $$@ $1-opcodes.ref + $(CA65) -t none --cpu $1 -l $$(@:.bin=.lst) -o $$(@:.bin=.o) $$< + $(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib + $(ISEQUAL) $1-opcodes.ref $$@ endef # OPCODE_template @@ -62,16 +62,16 @@ define CPUDETECT_template $(WORKDIR)/$1-cpudetect.bin: cpudetect.s $(ISEQUAL) $(if $(QUIET),echo asm/$1-cpudetect.bin) - $(CA65) --cpu $1 -t none -l $(WORKDIR)/$1-cpudetect.lst -o $(WORKDIR)/$1-cpudetect.o $$< - $(LD65) -t none -o $$@ $(WORKDIR)/$1-cpudetect.o none.lib - $(ISEQUAL) $$@ $1-cpudetect.ref + $(CA65) -t none --cpu $1 -l $$(@:.bin=.lst) -o $$(@:.bin=.o) $$< + $(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib + $(ISEQUAL) $1-cpudetect.ref $$@ endef # CPUDETECT_template $(foreach cpu,$(CPUDETECT_CPUS),$(eval $(call CPUDETECT_template,$(cpu)))) $(WORKDIR)/%.o: %.s | $(WORKDIR) - $(CA65) -l $(@:.o=.lst) -o $(WORKDIR)/$@ $< + $(CA65) -l $(@:.o=.lst) -o $@ $< clean: @$(call RMDIR,$(WORKDIR)) diff --git a/test/dasm/Makefile b/test/dasm/Makefile index dc0b57c76..542ce7d5e 100644 --- a/test/dasm/Makefile +++ b/test/dasm/Makefile @@ -7,7 +7,7 @@ endif ifdef CMD_EXE EXE = .exe MKDIR = mkdir $(subst /,\,$1) - RMDIR = -rmdir /s /q $(subst /,\,$1) + RMDIR = -rmdir /q /s $(subst /,\,$1) else EXE = MKDIR = mkdir -p $1 @@ -23,7 +23,7 @@ DA65 := $(if $(wildcard ../../bin/da65*),../../bin/da65,da65) WORKDIR = ../../testwrk/dasm -ISEQUAL = $(WORKDIR)/isequal$(EXE) +ISEQUAL = ../../testwrk/isequal$(EXE) CC = gcc CFLAGS = -O2 @@ -33,10 +33,9 @@ START = --start-addr 0x8000 .PHONY: all clean SOURCES := $(wildcard *.s) -CPUS = $(foreach src,$(SOURCES),$(src:%-disass.s=%)) -BINS = $(foreach cpu,$(CPUS),$(WORKDIR)/$(cpu)-reass.bin) +BINS = $(SOURCES:%disass.s=$(WORKDIR)/%reass.bin) +CPUS = $(SOURCES:%-disass.s=%) -# default target defined later all: $(BINS) $(WORKDIR): @@ -56,7 +55,7 @@ $(WORKDIR)/$1-reass.s: $(WORKDIR)/$1-disass.bin $(WORKDIR)/$1-reass.bin: $(WORKDIR)/$1-reass.s $(ISEQUAL) $(if $(QUIET),echo dasm/$1-reass.bin) $(CL65) --cpu $1 -t none $(START) -o $$@ $$< - $(ISEQUAL) $$@ $(WORKDIR)/$1-disass.bin + $(ISEQUAL) $(WORKDIR)/$1-disass.bin $$@ endef # DISASS_template From b0497f40b27f509a3c965ce866bbc38ffcb4a259 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 17 Nov 2020 13:40:36 -0500 Subject: [PATCH 1802/2161] 'test/isequal.c' doesn't change. Don't rebuild it for each test subdirectory. --- test/misc/Makefile | 2 +- test/ref/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/misc/Makefile b/test/misc/Makefile index b8c578405..bd4826d54 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -37,7 +37,7 @@ WORKDIR = ..$S..$Stestwrk$Smisc OPTIONS = g O Os Osi Osir Osr Oi Oir Or -ISEQUAL = $(WORKDIR)$Sisequal$(EXE) +ISEQUAL = ..$S..$Stestwrk$Sisequal$(EXE) CC = gcc CFLAGS = -O2 diff --git a/test/ref/Makefile b/test/ref/Makefile index 5faf9fb19..d9c9817ee 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -35,7 +35,7 @@ WORKDIR = ..$S..$Stestwrk$Sref OPTIONS = g O Os Osi Osir Osr Oi Oir Or -ISEQUAL = $(WORKDIR)$Sisequal$(EXE) +ISEQUAL = ..$S..$Stestwrk$Sisequal$(EXE) CC = gcc CFLAGS = -O2 -Wall -W -Wextra -funsigned-char -fwrapv -fno-strict-overflow From 5ba16654a35bd08734ad34bf72d932ccfce1de2d Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 17 Nov 2020 15:06:05 -0500 Subject: [PATCH 1803/2161] Refined the hints about making new test reference files. --- test/asm/Makefile | 2 +- test/asm/readme.txt | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/test/asm/Makefile b/test/asm/Makefile index 0cf65f9ca..e951c2015 100644 --- a/test/asm/Makefile +++ b/test/asm/Makefile @@ -60,7 +60,7 @@ $(foreach cpu,$(OPCODE_CPUS),$(eval $(call OPCODE_template,$(cpu)))) define CPUDETECT_template -$(WORKDIR)/$1-cpudetect.bin: cpudetect.s $(ISEQUAL) +$(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 diff --git a/test/asm/readme.txt b/test/asm/readme.txt index a2b1e9a41..0bbadeab9 100644 --- a/test/asm/readme.txt +++ b/test/asm/readme.txt @@ -1,4 +1,3 @@ - Assembler Testcases =================== @@ -7,7 +6,7 @@ Opcode Tests: These testcases are inspired by the ones now removed from test/assembler. The main purpose is to have each possible opcode generated at least once, -either by an assembly instruction or a ".byte"-placeholder. Typically +either by an Assembly instruction or a ".byte"-placeholder. Typically generated by disassembling a binary dump that contains data in the form of the pattern that each opcode is stated once in order followed by easy to recognise: @@ -28,21 +27,21 @@ m740 instructions set. Still to do is to find a way to implement an opcode testcase for the 65816 processor, since it's capable of executing instructions with an 8-bit and -a 16-bit operator alike, only distinguished by one processor flag. +a 16-bit operator alike, distinguished by only one processor flag. -CPU detect Tests +CPU Detect Tests ---------------- These tests all assemble the same file "cpudetect.s" which contains several conditionals for several CPUs, only using every option known to the "--cpu" -commandline switch of ca65/cl65. +command-line switch of ca65/cl65. Reference (".ref") Files ------------------------ -A hint on creating these files: when running the test, it will fail due to -the missing ".ref" file. Review the output of the ".lst" very pedantic, then -copy the ".bin" to the ".ref" file. - +Some hints about creating new files: +Make an empty file with the CPU's name prepended to "-cpudetect.ref". Run the +tests; one of them will fail due to a mismatch. Review the output of the +".lst" file pedantically, then copy the ".bin" over the empty ".ref" file. From bd6e5927c46335663efcf3d78f80c715526b9e79 Mon Sep 17 00:00:00 2001 From: Polluks <polluks@sdf.lonestar.org> Date: Wed, 18 Nov 2020 01:01:17 +0100 Subject: [PATCH 1804/2161] Fixed #1341 --- src/cc65/coptstop.c | 2 +- src/cc65/expr.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 41dfb5526..59bbe6dc9 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -1732,7 +1732,7 @@ unsigned OptStackOps (CodeSeg* S) int I; int OldEntryCount; /* Old number of entries */ unsigned Used; /* What registers would be used */ - unsigned PushedRegs; /* Track if the same regs are used after the push */ + unsigned PushedRegs = 0; /* Track if the same regs are used after the push */ int RhsAChgIndex; /* Track if rhs is changed more than once */ int RhsXChgIndex; /* Track if rhs is changed more than once */ int IsRegAOptFunc = 0; /* Whether to use the RegA-only optimizations */ diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 7ddd8f43a..1c8c25020 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3871,8 +3871,8 @@ static void hieOr (ExprDesc *Expr) static void hieQuest (ExprDesc* Expr) /* Parse the ternary operator */ { - int FalseLab; - int TrueLab; + int FalseLab = 0; + int TrueLab = 0; CodeMark SkippedBranch; CodeMark TrueCodeEnd; ExprDesc Expr2; /* Expression 2 */ From a0596eae6e0b96bc02a6c9dae8cb675bfc93dfba Mon Sep 17 00:00:00 2001 From: Polluks <polluks@sdf.lonestar.org> Date: Wed, 18 Nov 2020 01:05:40 +0100 Subject: [PATCH 1805/2161] Added waitvsync for PET --- libsrc/pet/waitvsync.s | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 libsrc/pet/waitvsync.s diff --git a/libsrc/pet/waitvsync.s b/libsrc/pet/waitvsync.s new file mode 100644 index 000000000..39b562e43 --- /dev/null +++ b/libsrc/pet/waitvsync.s @@ -0,0 +1,16 @@ +; +; Written by Robin Harbron, requires 12" monitor +; +; void waitvsync (void); +; + + .export _waitvsync + + .include "pet.inc" + +_waitvsync: +@l1: + lda VIA_PB + and #%00100000 + bne @l1 + rts From c59e8277ae3e8565e5f1bb9c47d81a2530980284 Mon Sep 17 00:00:00 2001 From: Polluks <polluks@sdf.lonestar.org> Date: Wed, 18 Nov 2020 01:13:10 +0100 Subject: [PATCH 1806/2161] Added prototype --- doc/pet.sgml | 1 + include/cbm.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/pet.sgml b/doc/pet.sgml index eb13d9fb9..6bedf6a0f 100644 --- a/doc/pet.sgml +++ b/doc/pet.sgml @@ -105,6 +105,7 @@ declaration and usage. <item>cbm_save <item>cbm_write <item>get_tv +<item>waitvsync </itemize> diff --git a/include/cbm.h b/include/cbm.h index ac3615c38..5bcef8e60 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -166,7 +166,7 @@ unsigned char get_tv (void); unsigned char __fastcall__ kbrepeat (unsigned char mode); /* Changes which keys have automatic repeat. */ -#if !defined(__CBM610__) && !defined(__PET__) +#if !defined(__CBM610__) void waitvsync (void); /* Wait for the start of the next video field. */ #endif From 4205a04a34caae838fba8daee65269aac87ecf26 Mon Sep 17 00:00:00 2001 From: Zsolt Branyiczky <brazso@zematix.hu> Date: Mon, 16 Nov 2020 22:15:47 +0100 Subject: [PATCH 1807/2161] 6502DTV is not a superset of 6502X more --- src/common/cpu.c | 2 +- src/common/cpu.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index 16578543b..b55a5ab00 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -70,7 +70,7 @@ const unsigned CPUIsets[CPU_COUNT] = { CPU_ISET_NONE, CPU_ISET_6502, CPU_ISET_6502 | CPU_ISET_6502X, - CPU_ISET_6502 | CPU_ISET_6502X | CPU_ISET_6502DTV, + 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, diff --git a/src/common/cpu.h b/src/common/cpu.h index 706b4544e..2e75feaaf 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -50,7 +50,7 @@ typedef enum { CPU_NONE, /* No CPU - for assembler */ CPU_6502, CPU_6502X, /* "Extended", that is: with illegal opcodes */ - CPU_6502DTV, /* CPU_6502X + C64DTV extra opcodes */ + CPU_6502DTV, /* CPU_6502 + DTV extra and illegal opcodes */ CPU_65SC02, CPU_65C02, CPU_65816, From 130d3b52a245897b84aa7423a75b3e32301d70eb Mon Sep 17 00:00:00 2001 From: Zsolt Branyiczky <brazso@zematix.hu> Date: Mon, 16 Nov 2020 22:16:14 +0100 Subject: [PATCH 1808/2161] new macros supporting 6502DTV cpu --- doc/ca65.sgml | 21 ++++++++++++++++++++- src/ca65/condasm.c | 11 +++++++++++ src/ca65/pseudo.c | 10 ++++++++++ src/ca65/scanner.c | 2 ++ src/ca65/token.h | 2 ++ 5 files changed, 45 insertions(+), 1 deletion(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 25a47b29a..9f45f8c54 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -419,6 +419,8 @@ The assembler accepts <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 + <tt><ref id=".PDTV" name=".PDTV"></tt> command was given). <item>all valid 65SC02 mnemonics when in 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 @@ -3153,6 +3155,12 @@ Here's a list of all control commands and a description, what they do: (see <tt><ref id=".PC02" name=".PC02"></tt> command). +<sect1><tt>.IFPDTV</tt><label id=".IFPDTV"><p> + + Conditional assembly: Check if the assembler is currently in 6502DTV mode + (see <tt><ref id=".PDTV" name=".PDTV"></tt> command). + + <sect1><tt>.IFPSC02</tt><label id=".IFPSC02"><p> Conditional assembly: Check if the assembler is currently in 65SC02 mode @@ -3585,6 +3593,14 @@ Here's a list of all control commands and a description, what they do: <tt><ref id=".P4510" name=".P4510"></tt> +<sect1><tt>.PDTV</tt><label id=".PDTV"><p> + + Enable the 6502DTV instruction set. This is a superset of the 6502 + instruction set. + + See: <tt><ref id=".P02" name=".P02"></tt></tt> + + <sect1><tt>.POPCPU</tt><label id=".POPCPU"><p> Pop the last CPU setting from the stack, and activate it. @@ -3848,10 +3864,11 @@ Here's a list of all control commands and a description, what they do: 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, 65SC02, 65C02, 65816, 4510 and HuC6280. + namely: 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, 4510 and HuC6280. See: <tt><ref id=".CPU" name=".CPU"></tt>, <tt><ref id=".IFP02" 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=".IFPSC02" name=".IFPSC02"></tt>, @@ -4586,6 +4603,7 @@ each supported CPU a constant similar to CPU_SWEET16 CPU_HUC6280 CPU_4510 + CPU_6502DTV </verb></tscreen> is defined. These constants may be used to determine the exact type of the @@ -4600,6 +4618,7 @@ another constant is defined: CPU_ISET_SWEET16 CPU_ISET_HUC6280 CPU_ISET_4510 + CPU_ISET_6502DTV </verb></tscreen> The value read from the <tt/<ref id=".CPU" name=".CPU">/ pseudo variable may diff --git a/src/ca65/condasm.c b/src/ca65/condasm.c index b8bda4c7d..6198f4017 100644 --- a/src/ca65/condasm.c +++ b/src/ca65/condasm.c @@ -416,6 +416,16 @@ void DoConditionals (void) CalcOverallIfCond (); break; + case TOK_IFPDTV: + D = AllocIf (".IFPDTV", 1); + NextTok (); + if (IfCond) { + SetIfCond (D, GetCPU() == CPU_6502DTV); + } + ExpectSep (); + CalcOverallIfCond (); + break; + case TOK_IFPSC02: D = AllocIf (".IFPSC02", 1); NextTok (); @@ -470,6 +480,7 @@ int CheckConditionals (void) case TOK_IFP4510: case TOK_IFP816: case TOK_IFPC02: + case TOK_IFPDTV: case TOK_IFPSC02: case TOK_IFREF: DoConditionals (); diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 5b2ef0573..26d01cbf1 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1552,6 +1552,14 @@ static void DoP4510 (void) +static void DoPDTV (void) +/* Switch to C64DTV CPU */ +{ + SetCPU (CPU_6502DTV); +} + + + static void DoPageLength (void) /* Set the page length for the listing */ { @@ -2058,6 +2066,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccKeepToken, DoConditionals }, /* .IFP4510 */ { ccKeepToken, DoConditionals }, /* .IFP816 */ { ccKeepToken, DoConditionals }, /* .IFPC02 */ + { ccKeepToken, DoConditionals }, /* .IFPDTV */ { ccKeepToken, DoConditionals }, /* .IFPSC02 */ { ccKeepToken, DoConditionals }, /* .IFREF */ { ccNone, DoImport }, @@ -2091,6 +2100,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoPageLength }, { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, + { ccNone, DoPDTV }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 361a817c1..fb9905809 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -219,6 +219,7 @@ struct DotKeyword { { ".IFP4510", TOK_IFP4510 }, { ".IFP816", TOK_IFP816 }, { ".IFPC02", TOK_IFPC02 }, + { ".IFPDTV", TOK_IFPDTV }, { ".IFPSC02", TOK_IFPSC02 }, { ".IFREF", TOK_IFREF }, { ".IMPORT", TOK_IMPORT }, @@ -258,6 +259,7 @@ struct DotKeyword { { ".PAGELENGTH", TOK_PAGELENGTH }, { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, + { ".PDTV", TOK_PDTV }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, diff --git a/src/ca65/token.h b/src/ca65/token.h index 8998cc162..ab36028fd 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -196,6 +196,7 @@ typedef enum token_t { TOK_IFP4510, TOK_IFP816, TOK_IFPC02, + TOK_IFPDTV, TOK_IFPSC02, TOK_IFREF, TOK_IMPORT, @@ -229,6 +230,7 @@ typedef enum token_t { TOK_PAGELENGTH, TOK_PARAMCOUNT, TOK_PC02, + TOK_PDTV, TOK_POPCPU, TOK_POPSEG, TOK_PROC, From 843b94388a792b1343ca1f5824b29c0ab8401419 Mon Sep 17 00:00:00 2001 From: Zsolt Branyiczky <brazso@zematix.hu> Date: Mon, 16 Nov 2020 22:16:40 +0100 Subject: [PATCH 1809/2161] added asm test for 6502DTV cpu --- test/asm/cpudetect.s | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/asm/cpudetect.s b/test/asm/cpudetect.s index adad7c1dc..6362b98bc 100644 --- a/test/asm/cpudetect.s +++ b/test/asm/cpudetect.s @@ -24,6 +24,10 @@ taz .endif +.ifpdtv + sac #00 +.endif + ; step 2: check for bitwise compatibility of instructions sets ; (made verbose for better reading with hexdump/hd(1)) @@ -64,3 +68,7 @@ .byte 0,"CPU_ISET_4510" .endif +.if (.cpu .bitand CPU_ISET_6502DTV) + .byte 0,"CPU_ISET_6502DTV" +.endif + From 1c5c07406ca3c0a203b57df49f73c1f4067f78ee Mon Sep 17 00:00:00 2001 From: Zsolt Branyiczky <brazso@zematix.hu> Date: Wed, 18 Nov 2020 09:51:01 +0100 Subject: [PATCH 1810/2161] cpudetect.s needs this file to run its test for 6502dtv cpu --- test/asm/6502dtv-cpudetect.ref | Bin 0 -> 33 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/asm/6502dtv-cpudetect.ref diff --git a/test/asm/6502dtv-cpudetect.ref b/test/asm/6502dtv-cpudetect.ref new file mode 100644 index 0000000000000000000000000000000000000000..59278e80a126c65cc81e93110e153813468d5455 GIT binary patch literal 33 ccmcC!U~moyjrR<84T(21H84WuxrBrP0EvDGdH?_b literal 0 HcmV?d00001 From 0e98818db54b93c0db7c4918068146bacfa1e1fb Mon Sep 17 00:00:00 2001 From: Zsolt Branyiczky <brazso@zematix.hu> Date: Wed, 18 Nov 2020 15:26:23 +0100 Subject: [PATCH 1811/2161] assembled SAC and SIR opcodes of 6502DTV cpu were wrong --- src/ca65/instr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index c5e3b7fef..77a865319 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -367,7 +367,7 @@ static const struct { { "RRA", 0x000A26C, 0x63, 0, PutAll }, /* X */ { "RTI", 0x0000001, 0x40, 0, PutAll }, { "RTS", 0x0000001, 0x60, 0, PutAll }, - { "SAC", 0x0800000, 0x32, 0, PutAll }, /* DTV */ + { "SAC", 0x0800000, 0x32, 1, PutAll }, /* DTV */ { "SBC", 0x080A26C, 0xe0, 0, PutAll }, { "SEC", 0x0000001, 0x38, 0, PutAll }, { "SED", 0x0000001, 0xf8, 0, PutAll }, @@ -375,7 +375,7 @@ static const struct { { "SHA", 0x0002200, 0x93, 1, PutAll }, /* X */ { "SHX", 0x0000200, 0x9e, 1, PutAll }, /* X */ { "SHY", 0x0000040, 0x9c, 1, PutAll }, /* X */ - { "SIR", 0x0800000, 0x32, 0, PutAll }, /* DTV */ + { "SIR", 0x0800000, 0x42, 1, PutAll }, /* DTV */ { "STA", 0x000A26C, 0x80, 0, PutAll }, { "STX", 0x000010c, 0x82, 1, PutAll }, { "STY", 0x000002c, 0x80, 1, PutAll }, @@ -1031,9 +1031,9 @@ const InsTable* InsTab = (const InsTable*) &InsTab6502; */ static unsigned char EATab[12][AM65I_COUNT] = { { /* Table 0 */ - 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, 0x05 /*zp*/, 0x0D /*abs*/, 0x0F, 0x15 /*zpx*/, 0x1D /*abx*/, 0x1F, + 0x00, 0x19 /*aby*/, 0x12, 0x00, 0x07, 0x11 /*izy*/, 0x17, 0x01 /*izx*/, + 0x00, 0x00, 0x00, 0x03, 0x13, 0x09 /*imm*/, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00 }, { /* Table 1 */ From 527500cedca1d18163e969e5acefb0f5e4ac5151 Mon Sep 17 00:00:00 2001 From: Zsolt Branyiczky <brazso@zematix.hu> Date: Wed, 18 Nov 2020 15:28:15 +0100 Subject: [PATCH 1812/2161] instruction table contained wrong parameters at SIR opcode --- src/da65/opc6502dtv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/da65/opc6502dtv.c b/src/da65/opc6502dtv.c index 15b860c4e..fe83ad598 100644 --- a/src/da65/opc6502dtv.c +++ b/src/da65/opc6502dtv.c @@ -115,7 +115,7 @@ const OpcDesc OpcTable_6502DTV[256] = { { "rla", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3f */ { "rti", 1, flNone, OH_Rts }, /* $40 */ { "eor", 2, flUseLabel, OH_DirectXIndirect }, /* $41 */ - { "sir", 1, flNone, OH_Implicit }, /* $42 */ + { "sir", 2, flNone, OH_Immediate }, /* $42 */ { "", 1, flIllegal, OH_Illegal, }, /* $43 */ { "nop", 2, flUseLabel, OH_Direct }, /* $44 */ { "eor", 2, flUseLabel, OH_Direct }, /* $45 */ From 36f5dcbb6e2265ff1b2409b2ced05af23460e35a Mon Sep 17 00:00:00 2001 From: Zsolt Branyiczky <brazso@zematix.hu> Date: Wed, 18 Nov 2020 15:29:56 +0100 Subject: [PATCH 1813/2161] added 6502dtv opdoces testcases and corrected cpudetect --- test/asm/6502dtv-cpudetect.ref | Bin 33 -> 33 bytes test/asm/6502dtv-opcodes.ref | Bin 0 -> 498 bytes test/asm/6502dtv-opcodes.s | 258 +++++++++++++++++++++++++++++++++ test/asm/readme.txt | 2 +- 4 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 test/asm/6502dtv-opcodes.ref create mode 100644 test/asm/6502dtv-opcodes.s diff --git a/test/asm/6502dtv-cpudetect.ref b/test/asm/6502dtv-cpudetect.ref index 59278e80a126c65cc81e93110e153813468d5455..77a865eb42566cdbce5cd3ef00c8654346e2c889 100644 GIT binary patch delta 7 OcmY#XWHg${r~m*2Rskpg delta 7 OcmY#XWVD{hr~m*2dI2#2 diff --git a/test/asm/6502dtv-opcodes.ref b/test/asm/6502dtv-opcodes.ref new file mode 100644 index 0000000000000000000000000000000000000000..408d89be2e4dd43683a6e8e3401d01e8020b6039 GIT binary patch literal 498 zcmV~$0{~D507cPk-fUwTFMHX3Vc9l*_TrXpZnf-X+qP|6=Y$AJsL){uOE|(uh)AT! zM6se;(X8k(f|wA*icK8i5-)xND`BF<RuU_zl`OfHf|RL9O&ZdYj`Y8gAtRZr%vKgF ztCcOtP7ZP+a*>-n<jrU0FJKk43R#7%B3992{7&%_l%y1;%ao;Dc`8^Htx8tqDnV7M zRj)x!Os(2=th#^Hv+7$7tcHym)1)cQXif`S(yBFW+S1NyZ*{ObTAhN<bm>Yry3>Q6 z1ih@@eXPD#KdZkrz#7OP1~X(R!}ycoBStc6^cd?e>u+o9xL`aJCQf29Q<yq!x;10w zENiwk$C^8j`7B@|i&)GO{^8%HEc=h;)(UH-waQu@tYPgs*0X_)Y-02O)|Rc-Hfy`J z!`f->VmEu(yN~@G;NYRd968D{>$r8oI(aHM&6%_3IL`$xUb<{uxq8jIZr!kM-r_cQ uxO<QLJmBG@$2@t;GwZqa!g~2Cc+H!)?|9D#K7RUaefj#$`fmNOe*OZ~w613W literal 0 HcmV?d00001 diff --git a/test/asm/6502dtv-opcodes.s b/test/asm/6502dtv-opcodes.s new file mode 100644 index 000000000..f2446cbe0 --- /dev/null +++ b/test/asm/6502dtv-opcodes.s @@ -0,0 +1,258 @@ +.setcpu "6502DTV" + + brk + ora ($12,x) + .byte $02 + .byte $03 + nop $12 + ora $12 + asl $12 + .byte $07 + php + ora #$12 + asl a + anc #$12 + nop $3456 + ora $3456 + asl $3456 + .byte $0f + bpl *+122 + ora ($12),y + bra *+122 + .byte $13 + nop $12,x + ora $12,x + asl $12,x + .byte $17 + clc + ora $3456,y + .byte $1a ; nop + .byte $1b + nop $3456,x + ora $3456,x + asl $3456,x + .byte $1f + jsr $3456 + and ($12,x) + .byte $22 + rla ($12,x) + bit $12 + and $12 + rol $12 + rla $12 + plp + and #$12 + rol a + .byte $2b,$12 ; anc #$12 + bit $3456 + and $3456 + rol $3456 + rla $3456 + bmi *+122 + and ($12),y + sac #$12 + rla ($12),y + .byte $34,$12 ; nop $12,x + and $12,x + rol $12,x + rla $12,x + sec + and $3456,y + .byte $3a ; nop + rla $3456,y + .byte $3c,$56,$34 ; nop $3456,x + and $3456,x + rol $3456,x + rla $3456,x + rti + eor ($12,x) + sir #$12 + .byte $43 + .byte $44,$12 ; nop $12 + eor $12 + lsr $12 + .byte $47 + pha + eor #$12 + lsr a + alr #$12 + jmp $3456 + eor $3456 + lsr $3456 + .byte $4f + bvc *+122 + eor ($12),y + .byte $52 + .byte $53 + .byte $54,$12 ; nop $12,x + eor $12,x + lsr $12,x + .byte $57 + cli + eor $3456,y + .byte $5a ; nop + .byte $5b + .byte $5c,$56,$34 ; nop $3456,x + eor $3456,x + lsr $3456,x + .byte $5f + rts + adc ($12,x) + .byte $62 + rra ($12,x) + .byte $64,$12 ; nop $12 + adc $12 + ror $12 + rra $12 + pla + adc #$12 + ror a + arr #$12 + jmp ($3456) + adc $3456 + ror $3456 + rra $3456 + bvs *+122 + adc ($12),y + .byte $72 + rra ($12),y + .byte $74,$12 ; nop $12,x + adc $12,x + ror $12,x + rra $12,x + sei + adc $3456,y + .byte $7a ; nop + rra $3456,y + .byte $7c,$56,$34 ; nop $3456,x + adc $3456,x + ror $3456,x + rra $3456,x + nop #$12 + sta ($12,x) + .byte $82,$12 ; nop #$12 + .byte $83 + sty $12 + sta $12 + stx $12 + .byte $87 + dey + .byte $89,$12 ; nop #$12 + txa + .byte $8b + sty $3456 + sta $3456 + stx $3456 + .byte $8f + bcc *+122 + sta ($12),y + .byte $92 + .byte $93 + sty $12,x + sta $12,x + stx $12,y + .byte $97 + tya + sta $3456,y + txs + .byte $9b + shy $3456,x + sta $3456,x + shx $3456,y + .byte $9f + 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 *+122 + lda ($12),y + .byte $b2 + 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) + .byte $c2,$12 ; nop #$12 + .byte $c3 + cpy $12 + cmp $12 + dec $12 + .byte $c7 + iny + cmp #$12 + dex + axs #$12 + cpy $3456 + cmp $3456 + dec $3456 + .byte $cf + bne *+122 + cmp ($12),y + .byte $d2 + .byte $d3 + .byte $d4,$12 ; nop $12,x + cmp $12,x + dec $12,x + .byte $d7 + cld + cmp $3456,y + .byte $da ; nop + .byte $db + .byte $dc,$56,$34 ; nop $3456,x + cmp $3456,x + dec $3456,x + .byte $df + cpx #$12 + sbc ($12,x) + .byte $e2,$12 ; nop #$12 + .byte $e3 + cpx $12 + sbc $12 + inc $12 + .byte $e7 + inx + sbc #$12 + nop + .byte $eb,$12 ; sbc #$12 + cpx $3456 + sbc $3456 + inc $3456 + .byte $ef + beq *+122 + sbc ($12),y + .byte $f2 + .byte $f3 + .byte $f4,$12 ; nop $12,x + sbc $12,x + inc $12,x + .byte $f7 + sed + sbc $3456,y + .byte $fa ; nop + .byte $fb + .byte $fc,$56,$34 ; nop $3456,x + sbc $3456,x + inc $3456,x + .byte $ff diff --git a/test/asm/readme.txt b/test/asm/readme.txt index 0bbadeab9..1d135c895 100644 --- a/test/asm/readme.txt +++ b/test/asm/readme.txt @@ -23,7 +23,7 @@ leftover dummy opcode parameters with something more recognizable. The testcases for 6502, 6502x, 65sc02, 65c02, 4510, and huc6280 have been put together by Sven Oliver ("SvOlli") Moll, as well as a template for the -m740 instructions set. +m740 instructions set. Later 6502dtv support was also added. Still to do is to find a way to implement an opcode testcase for the 65816 processor, since it's capable of executing instructions with an 8-bit and From b2c55c3338c582c103bfffa7a7f1fa37b085492c Mon Sep 17 00:00:00 2001 From: Zsolt Branyiczky <brazso@zematix.hu> Date: Wed, 18 Nov 2020 15:47:09 +0100 Subject: [PATCH 1814/2161] adding c64dtv device to the supported ones --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3d78fda50..3d7b32289 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ including - VIC20 - C16/C116 and Plus/4 - C64 + - C64DTV - C128 - CBM 510 (aka P500) - the 600/700 family From adad3d2e870ea09551681a8b020660f36fbaa9af Mon Sep 17 00:00:00 2001 From: Zsolt Branyiczky <brazso@zematix.hu> Date: Thu, 19 Nov 2020 12:37:51 +0100 Subject: [PATCH 1815/2161] Revert "adding c64dtv device to the supported ones" This reverts commit 1d9e378fe3e3304000763d821d72afa841f954a3. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 3d7b32289..3d78fda50 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,6 @@ including - VIC20 - C16/C116 and Plus/4 - C64 - - C64DTV - C128 - CBM 510 (aka P500) - the 600/700 family From 63543dee07d5f0f7c7096b3251ef4095e16060e8 Mon Sep 17 00:00:00 2001 From: Zsolt Branyiczky <brazso@zematix.hu> Date: Thu, 19 Nov 2020 12:44:33 +0100 Subject: [PATCH 1816/2161] Revert transient modification of EATab Table 0 comment --- src/ca65/instr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 77a865319..faeff2026 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -1031,9 +1031,9 @@ const InsTable* InsTab = (const InsTable*) &InsTab6502; */ static unsigned char EATab[12][AM65I_COUNT] = { { /* Table 0 */ - 0x00, 0x00, 0x05 /*zp*/, 0x0D /*abs*/, 0x0F, 0x15 /*zpx*/, 0x1D /*abx*/, 0x1F, - 0x00, 0x19 /*aby*/, 0x12, 0x00, 0x07, 0x11 /*izy*/, 0x17, 0x01 /*izx*/, - 0x00, 0x00, 0x00, 0x03, 0x13, 0x09 /*imm*/, 0x00, 0x09, + 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 }, { /* Table 1 */ From 032b4e3979c378af81dfed2c6aa2ad0edb8a8fee Mon Sep 17 00:00:00 2001 From: Zsolt Branyiczky <brazso@zematix.hu> Date: Thu, 19 Nov 2020 21:22:40 +0100 Subject: [PATCH 1817/2161] Fixed typo --- doc/ca65.sgml | 2 +- test/asm/cpudetect.s | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 9f45f8c54..cebdca12e 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -3598,7 +3598,7 @@ Here's a list of all control commands and a description, what they do: Enable the 6502DTV instruction set. This is a superset of the 6502 instruction set. - See: <tt><ref id=".P02" name=".P02"></tt></tt> + See: <tt><ref id=".P02" name=".P02"></tt> <sect1><tt>.POPCPU</tt><label id=".POPCPU"><p> diff --git a/test/asm/cpudetect.s b/test/asm/cpudetect.s index 6362b98bc..7b2363b7f 100644 --- a/test/asm/cpudetect.s +++ b/test/asm/cpudetect.s @@ -25,7 +25,7 @@ .endif .ifpdtv - sac #00 + sac #$00 .endif From 23273584a0a49867d5975aa59edc7a9853f7f8d4 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 19 Nov 2020 23:12:16 +0100 Subject: [PATCH 1818/2161] testcase for issue #1348 --- test/misc/Makefile | 8 +++++++ test/misc/bug1348.c | 54 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 test/misc/bug1348.c diff --git a/test/misc/Makefile b/test/misc/Makefile index bd4826d54..853e9d1e0 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -117,6 +117,14 @@ $(WORKDIR)/endless.$1.$2.prg: endless.c | $(WORKDIR) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) $(NOT) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) +# this one fails when optimization are enabled +$(WORKDIR)/bug1348.$1.$2.prg: bug1348.c | $(WORKDIR) + $(if $(QUIET),echo misc/bug1348.$1.$2.prg) + $(CC65) -Osr -t sim$2 -$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) + $(NOT) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) + # these need reference data that can't be generated by a host-compiled program, # in a useful way $(WORKDIR)/limits.$1.$2.prg: limits.c $(ISEQUAL) | $(WORKDIR) diff --git a/test/misc/bug1348.c b/test/misc/bug1348.c new file mode 100644 index 000000000..913849482 --- /dev/null +++ b/test/misc/bug1348.c @@ -0,0 +1,54 @@ + +/* bug#1348, wrongly optimized integer promotion in comparison */ + +#include <stdio.h> + +int notrandtab[] = { + 0xffff, 0x7fff, 0x3fff, 0x1fff, + 0x0fff, 0x07ff, 0x03ff, 0x01ff, + 0x00ff, 0x007f, 0x003f, 0x001f, + 0x000f, 0x0007, 0x0003, 0x0001 +}; + +unsigned char notrandcount = 0; + +int notrand(void) +{ + return notrandtab[notrandcount & 0x0f]; +} + +unsigned char n1, n2; +unsigned char i, ii, s; +unsigned char err = 0; + +unsigned char cmptab[] = { + 0xff, 0x7f, 0x3f, 0x1f, + 0x0f, 0x07, 0x03, 0x01, + 0x80, 0x40, 0x20, 0x10, + 0x08, 0x04, 0x02, 0x01 +}; + +int main(void) +{ + for (ii = 0; ii < 16; ++ii) { + s = cmptab[ii]; + for (i = 0; i < 16; ++i) { + n1 = n2 = 0; + if ((notrand() & 0xff) > s) { + n1 = 1; + } + if ((notrand() & 0xffu) > s) { + n2 = 1; + } + printf("%5d>%3d %d(%02x) %d(%02x) %s\n", + notrandtab[notrandcount & 0x0f], s, + n1, (notrand() & 0xff), + n2, (notrand() & 0xffu), + n1 == n2 ? "=" : "!=" + ); + if (n1 != n2) err = 1; + notrandcount++; + } + } + return err; +} From 48710af55ae0df0a5ed81f50da40a34b314978ac Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 19 Nov 2020 23:21:06 +0100 Subject: [PATCH 1819/2161] make plasma sample work again despite issue #1348 --- samples/plasma.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/samples/plasma.c b/samples/plasma.c index ac17265f3..f48d6dc77 100644 --- a/samples/plasma.c +++ b/samples/plasma.c @@ -1,7 +1,7 @@ /*****************************************************************************\ ** plasma test program for cc65. ** ** ** -** (w)2001 by groepaz/hitmen ** +** (w)2001 by groepaz ** ** ** ** Cleanup and porting by Ullrich von Bassewitz. ** ** ** @@ -54,7 +54,6 @@ #pragma static-locals (1); - static const unsigned char sinustable[0x100] = { 0x80, 0x7d, 0x7a, 0x77, 0x74, 0x70, 0x6d, 0x6a, 0x67, 0x64, 0x61, 0x5e, 0x5b, 0x58, 0x55, 0x52, @@ -131,8 +130,6 @@ static void doplasma (register unsigned char* scrn) } } - - static void makechar (void) { static const unsigned char bittab[8] = { @@ -147,7 +144,7 @@ static void makechar (void) for (i = 0; i < 8; ++i){ b = 0; for (ii = 0; ii < 8; ++ii) { - if ((rand() & 0xFF) > s) { + if ((rand() & 0xFFu) > s) { b |= bittab[ii]; } } From c11e389a9400a32a4cf4a0672e23fe5fcfd8c426 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 20 Nov 2020 17:25:10 +0100 Subject: [PATCH 1820/2161] move testcase for issue #1320 into test/misc --- test/misc/Makefile | 6 ++++++ test/{err => misc}/bug1320.c | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) rename test/{err => misc}/bug1320.c (93%) diff --git a/test/misc/Makefile b/test/misc/Makefile index 853e9d1e0..3fab957cb 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -100,6 +100,12 @@ $(WORKDIR)/bug1263.$1.$2.prg: bug1263.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1263.$1.$2.prg) $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) +# should compile, but gives an error (segfault) +$(WORKDIR)/bug1320.$1.$2.prg: bug1320.c | $(WORKDIR) + @echo "FIXME: " $$@ "currently does not compile." + $(if $(QUIET),echo misc/bug1320.$1.$2.prg) + $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + # this one requires --std=c89, it fails with --std=c99 # it fails currently at runtime $(WORKDIR)/bug1265.$1.$2.prg: bug1265.c | $(WORKDIR) diff --git a/test/err/bug1320.c b/test/misc/bug1320.c similarity index 93% rename from test/err/bug1320.c rename to test/misc/bug1320.c index 15482434c..3599d60de 100644 --- a/test/err/bug1320.c +++ b/test/misc/bug1320.c @@ -24,7 +24,7 @@ https://github.com/cc65/cc65/issues/1320 - After the bug is fixed, this file should be moved to "test/misc/". + After the bug is fixed, this file should be moved to "test/val/". */ static char *var; @@ -35,4 +35,5 @@ char bar (void); void main (void) { foo (var++, bar ()); + return 0; } From cffcbce60fc41d26c25891edc8992e23a4a8d4c9 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 20 Nov 2020 19:11:20 +0100 Subject: [PATCH 1821/2161] Bumped version. I placed the Git tag V2.19 in hindsight at https://github.com/cc65/cc65/commit/555282497c3ecf8b313d87d5973093af19c35bd5. But I certainly don't want to rewrite the Git history just for the reported version, so I simply set the reported version at today's HEAD to 2.19. --- src/common/version.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/version.c b/src/common/version.c index 202c61cc3..992be45ee 100644 --- a/src/common/version.c +++ b/src/common/version.c @@ -47,7 +47,7 @@ #define VER_MAJOR 2U -#define VER_MINOR 18U +#define VER_MINOR 19U From 79bdc2d51f1bf67830ef6fcde3e6cc6bf9c72bfa Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 20 Nov 2020 19:19:55 +0100 Subject: [PATCH 1822/2161] Set correct prerequisite. See https://github.com/cc65/cc65/issues/1318 --- libsrc/geos-common/disk/calcblksfree.s | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libsrc/geos-common/disk/calcblksfree.s b/libsrc/geos-common/disk/calcblksfree.s index 520c8ca61..5d7b98aba 100644 --- a/libsrc/geos-common/disk/calcblksfree.s +++ b/libsrc/geos-common/disk/calcblksfree.s @@ -13,6 +13,10 @@ .include "geossym.inc" _CalcBlksFree: + lda #<curDirHead + ldx #>curDirHead + sta r5L + stx r5H jsr CalcBlksFree stx __oserror lda r4L From 8b42f570e998df727c75d3cac7cfe6683478d900 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 20 Nov 2020 17:29:26 -0500 Subject: [PATCH 1823/2161] Fixed code that caused a seg-fault after parsing a (deferred) post-count argument followed by a (nested) function-call argument. The old broken code defers the count until the end of the (parent function's) argument list. But, a nested function call clears the pointer to the deferred type. That leads to an access violation. The new code defers only until the end of each argument. Fixes #1320. --- src/cc65/expr.c | 44 +++++++++++++++++------------------- test/misc/Makefile | 10 ++------ test/{misc => val}/bug1320.c | 17 +++++++++----- 3 files changed, 34 insertions(+), 37 deletions(-) rename test/{misc => val}/bug1320.c (85%) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 1c8c25020..0cf650d3b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1,7 +1,7 @@ /* expr.c ** ** 1998-06-21, Ullrich von Bassewitz -** 2020-01-25, Greg King +** 2020-11-20, Greg King */ @@ -608,6 +608,8 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) ** The function returns the size of the arguments pushed in bytes. */ { + ExprDesc Expr; + /* Initialize variables */ SymEntry* Param = 0; /* Keep gcc silent */ unsigned PushedSize = 0; /* Size of arguments pushed */ @@ -634,7 +636,6 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) ** */ if (ParamComplete && IS_Get (&CodeSizeFactor) >= 200) { - /* Calculate the number and size of the parameters */ FrameParams = Func->ParamCount; FrameSize = Func->ParamSize; @@ -656,18 +657,13 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) } } - /* The info of the last argument could be needed out of the loop */ - ExprDesc Expr; - ED_Init (&Expr); - Expr.Flags |= ED->Flags & E_MASK_KEEP_SUBEXPR; - /* Parse the actual argument list */ while (CurTok.Tok != TOK_RPAREN) { - unsigned Flags; /* Code generator flags, not expression flags */ - - /* This way the info of the last parameter won't be cleared */ + ED_Init (&Expr); + + /* This way, the info of the last parameter won't be cleared */ Expr.Flags |= ED->Flags & E_MASK_KEEP_SUBEXPR; /* Count arguments */ @@ -781,18 +777,20 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) Error ("Argument expected after comma"); break; } + + DoDeferred (SQP_KEEP_NONE, &Expr); } + /* Append last deferred inc/dec before the function is called. + ** The last parameter needs to be preserved if it is passed in AX/EAX Regs. + */ + DoDeferred (IsFastcall ? SQP_KEEP_EAX : SQP_KEEP_NONE, &Expr); + /* Check if we had enough arguments */ if (PushedCount < Func->ParamCount) { Error ("Too few arguments in function call"); } - /* Append deferred inc/dec before the function is called. - ** The last parameter needs to be restored if it is passed with AX/EAX Regs. - */ - DoDeferred (IsFastcall ? SQP_KEEP_EAX : SQP_KEEP_NONE, &Expr); - /* The function returns the size of all arguments pushed onto the stack. ** However, if there are parameters missed (which is an error, and was ** flagged by the compiler), AND a stack frame was preallocated above, @@ -1395,7 +1393,7 @@ static void ArrayRef (ExprDesc* Expr) /* The array subscript is a constant. Since we can have the element ** address directly as base+offset, we can remove the array address ** push onto the stack before if loading subscript doesn't tamper that - ** address in the primary. + ** address in the primary. */ if (!ConstBaseAddr) { RemoveCode (&Mark2); @@ -1419,7 +1417,7 @@ static void ArrayRef (ExprDesc* Expr) ** remove the code that loaded the address into the primary. */ if (!IsTypeArray (Expr->Type)) { - + /* It's a pointer, so we do have to load it into the primary ** first (if it's not already there). */ @@ -2025,8 +2023,8 @@ static void PostInc (ExprDesc* Expr) /* Get the data type */ Flags = TypeOf (Expr->Type); - /* We are allowed by the C standard to defer the inc operation until - ** the this expression is used, so that we don't need to save and reload + /* We are allowed by the C standard to defer the inc operation until after + ** the expression is used, so that we don't need to save and reload ** the original value. */ @@ -2065,7 +2063,7 @@ static void PostInc (ExprDesc* Expr) /* Fetch the value and use it (since it's the result of the expression) */ LoadExpr (CF_NONE, Expr); - /* Defer the increment until the value of this expression is used */; + /* Defer the increment until after the value of this expression is used */ DeferInc (Expr); } } @@ -2132,7 +2130,7 @@ static void PostDec (ExprDesc* Expr) /* Fetch the value and save it (since it's the result of the expression) */ LoadExpr (CF_NONE, Expr); - /* Defer the decrement until the value of this expression is used */; + /* Defer the decrement until after the value of this expression is used */ DeferDec (Expr); } } @@ -3738,7 +3736,7 @@ static void hieOr (ExprDesc *Expr) Error ("Scalar expression expected"); ED_MakeConstBool (Expr, 0); } else if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { - + if (!ED_IsConstBool (Expr)) { /* Test the lhs if we haven't had && operators. If we had them, the ** jump is already in place and there's no need to do the test. @@ -3749,7 +3747,7 @@ static void hieOr (ExprDesc *Expr) /* Get first expr */ LoadExpr (CF_FORCECHAR, Expr); - + /* Append deferred inc/dec at sequence point */ DoDeferred (SQP_KEEP_TEST, Expr); diff --git a/test/misc/Makefile b/test/misc/Makefile index 3fab957cb..ad31e8554 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -100,12 +100,6 @@ $(WORKDIR)/bug1263.$1.$2.prg: bug1263.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1263.$1.$2.prg) $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) -# should compile, but gives an error (segfault) -$(WORKDIR)/bug1320.$1.$2.prg: bug1320.c | $(WORKDIR) - @echo "FIXME: " $$@ "currently does not compile." - $(if $(QUIET),echo misc/bug1320.$1.$2.prg) - $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - # this one requires --std=c89, it fails with --std=c99 # it fails currently at runtime $(WORKDIR)/bug1265.$1.$2.prg: bug1265.c | $(WORKDIR) @@ -114,7 +108,7 @@ $(WORKDIR)/bug1265.$1.$2.prg: bug1265.c | $(WORKDIR) $(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) - + # 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) @@ -130,7 +124,7 @@ $(WORKDIR)/bug1348.$1.$2.prg: bug1348.c | $(WORKDIR) $(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) - + # these need reference data that can't be generated by a host-compiled program, # in a useful way $(WORKDIR)/limits.$1.$2.prg: limits.c $(ISEQUAL) | $(WORKDIR) diff --git a/test/misc/bug1320.c b/test/val/bug1320.c similarity index 85% rename from test/misc/bug1320.c rename to test/val/bug1320.c index 3599d60de..824b50071 100644 --- a/test/misc/bug1320.c +++ b/test/val/bug1320.c @@ -1,5 +1,5 @@ /* - Copyright 2020 The cc65 Authors + Copyright 2020, 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 @@ -21,18 +21,23 @@ /* Test of a post-counted pointer argument, followed by a (nested) function-call argument. + Test that compiling it doesn't cause a seg-fault. https://github.com/cc65/cc65/issues/1320 - - After the bug is fixed, this file should be moved to "test/val/". */ static char *var; -void foo (char *, char); -char bar (void); +static void foo (char *, char) +{ +} -void main (void) +static char bar (void) +{ + return 'b'; +} + +int main (void) { foo (var++, bar ()); return 0; From a0d986faf8a646b8d01ed43e88727a42f1476be7 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 27 Nov 2020 21:19:49 -0500 Subject: [PATCH 1824/2161] Fixed the horizontal movement of the mouse pointer on platforms with the VIC-II display chip. ca65's logical (Boolean) NOT operator was used where bitwise NOT should be used. The effect was that all sprites were shifted to the left side of a screen when the mouse sprite was put on the left side. --- libsrc/c128/mcbdefault.s | 12 ++++++------ libsrc/c64/mcbdefault.s | 10 +++++----- libsrc/cbm510/mcbdefault.s | 12 ++++++------ 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/libsrc/c128/mcbdefault.s b/libsrc/c128/mcbdefault.s index eb521eb3a..a3ca3d0d1 100644 --- a/libsrc/c128/mcbdefault.s +++ b/libsrc/c128/mcbdefault.s @@ -19,12 +19,12 @@ ; Sprite definitions. The first value can be changed to adjust the number ; of the sprite used for the mouse. All others depend on this value. -MOUSE_SPR = 0 ; Sprite used for the mouse -MOUSE_SPR_MEM = $0E00 ; Memory location -MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask -MOUSE_SPR_NMASK = .lobyte(.not MOUSE_SPR_MASK) ; Negative mask -VIC_SPR_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register -VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register +MOUSE_SPR = 0 ; Sprite used for the mouse +MOUSE_SPR_MEM = $0E00 ; Memory location +MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask +MOUSE_SPR_NMASK = .lobyte(.bitnot MOUSE_SPR_MASK) ; Negative mask +VIC_SPR_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register +VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register ; -------------------------------------------------------------------------- ; Initialize the mouse sprite. diff --git a/libsrc/c64/mcbdefault.s b/libsrc/c64/mcbdefault.s index dd2f7cee7..79a8d93e5 100644 --- a/libsrc/c64/mcbdefault.s +++ b/libsrc/c64/mcbdefault.s @@ -21,11 +21,11 @@ ; Sprite definitions. The first value can be changed to adjust the number ; of the sprite used for the mouse. All others depend on this value. -MOUSE_SPR = 0 ; Sprite used for the mouse -MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask -MOUSE_SPR_NMASK = .lobyte(.not MOUSE_SPR_MASK) ; Negative mask -VIC_SPR_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register -VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register +MOUSE_SPR = 0 ; Sprite used for the mouse +MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask +MOUSE_SPR_NMASK = .lobyte(.bitnot MOUSE_SPR_MASK) ; Negative mask +VIC_SPR_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register +VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register ; -------------------------------------------------------------------------- ; Initialize the mouse sprite. diff --git a/libsrc/cbm510/mcbdefault.s b/libsrc/cbm510/mcbdefault.s index 700dcebb1..53eb804c0 100644 --- a/libsrc/cbm510/mcbdefault.s +++ b/libsrc/cbm510/mcbdefault.s @@ -21,12 +21,12 @@ ; Sprite definitions. The first value can be changed to adjust the number ; of the sprite used for the mouse. All others depend on that value. -MOUSE_SPR = 0 ; Sprite used for the mouse -MOUSE_SPR_MEM = $F400 ; Memory location -MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask -MOUSE_SPR_NMASK = .lobyte(.not MOUSE_SPR_MASK) ; Negative mask -VIC_SPR_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register -VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register +MOUSE_SPR = 0 ; Sprite used for the mouse +MOUSE_SPR_MEM = $F400 ; Memory location +MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask +MOUSE_SPR_NMASK = .lobyte(.bitnot MOUSE_SPR_MASK) ; Negative mask +VIC_SPR_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register +VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register ; -------------------------------------------------------------------------- ; Initialize the mouse sprite. From 9538ca29b214ac2881adf2cb5a43b1c95467e062 Mon Sep 17 00:00:00 2001 From: Polluks <polluks@sdf.lonestar.org> Date: Fri, 20 Nov 2020 00:54:15 +0100 Subject: [PATCH 1825/2161] Unified #1345 --- cfg/supervision-128k.cfg | 2 +- cfg/supervision-16k.cfg | 2 +- cfg/supervision-64k.cfg | 2 +- cfg/supervision.cfg | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cfg/supervision-128k.cfg b/cfg/supervision-128k.cfg index a03ab0e1b..3d7a9efd0 100644 --- a/cfg/supervision-128k.cfg +++ b/cfg/supervision-128k.cfg @@ -33,5 +33,5 @@ SEGMENTS { ZEROPAGE: load = RAM, type = bss, define = yes; DATA: load = RAM, type = bss, define = yes, offset = $0200; BSS: load = RAM, type = bss, define = yes; - VECTOR: load = ROM, type = ro, offset = $3FFA; + VECTORS: load = ROM, type = ro, start = $3FFA; } diff --git a/cfg/supervision-16k.cfg b/cfg/supervision-16k.cfg index e0b54be23..4a431621f 100644 --- a/cfg/supervision-16k.cfg +++ b/cfg/supervision-16k.cfg @@ -21,7 +21,7 @@ SEGMENTS { RODATA: load = ROM, type = ro, define = yes; DATA: load = ROM, run = RAM, type = rw, define = yes; FFF0: load = ROM, type = ro, offset = $3FF0; - VECTOR: load = ROM, type = ro, offset = $3FFA; + VECTORS: load = ROM, type = ro, start = $3FFA; BSS: load = RAM, type = bss, define = yes; } FEATURES { diff --git a/cfg/supervision-64k.cfg b/cfg/supervision-64k.cfg index 9d5f15e45..e0cb68a6f 100644 --- a/cfg/supervision-64k.cfg +++ b/cfg/supervision-64k.cfg @@ -26,5 +26,5 @@ SEGMENTS { ZEROPAGE: load = RAM, type = bss, define = yes; DATA: load = RAM, type = bss, define = yes, offset = $0200; BSS: load = RAM, type = bss, define = yes; - VECTOR: load = ROM, type = ro, offset = $3FFA; + VECTORS: load = ROM, type = ro, start = $3FFA; } diff --git a/cfg/supervision.cfg b/cfg/supervision.cfg index d9f189f2b..4ec3e49c7 100644 --- a/cfg/supervision.cfg +++ b/cfg/supervision.cfg @@ -20,7 +20,7 @@ SEGMENTS { RODATA: load = ROM, type = ro, define = yes; DATA: load = ROM, run = RAM, type = rw, define = yes; FFF0: load = ROM, type = ro, offset = $7FF0; - VECTOR: load = ROM, type = ro, offset = $7FFA; + VECTORS: load = ROM, type = ro, start = $7FFA; BSS: load = RAM, type = bss, define = yes; } FEATURES { From a538188d90239235600e76ceb62bd55343a114d0 Mon Sep 17 00:00:00 2001 From: Polluks <polluks@sdf.lonestar.org> Date: Thu, 26 Nov 2020 12:48:58 +0100 Subject: [PATCH 1826/2161] Fixed some config mistakes --- cfg/supervision-128k.cfg | 6 +++--- cfg/supervision-16k.cfg | 2 +- cfg/supervision-64k.cfg | 6 +++--- cfg/supervision.cfg | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cfg/supervision-128k.cfg b/cfg/supervision-128k.cfg index 3d7a9efd0..535e93c1d 100644 --- a/cfg/supervision-128k.cfg +++ b/cfg/supervision-128k.cfg @@ -30,8 +30,8 @@ SEGMENTS { BANK5: load = BANKROM5, type = ro; BANK6: load = BANKROM6, type = ro; BANK7: load = BANKROM7, type = ro; - ZEROPAGE: load = RAM, type = bss, define = yes; - DATA: load = RAM, type = bss, define = yes, offset = $0200; + ZEROPAGE: load = RAM, type = zp, define = yes; + DATA: load = RAM, type = rw, define = yes, offset = $0200; BSS: load = RAM, type = bss, define = yes; - VECTORS: load = ROM, type = ro, start = $3FFA; + VECTORS: load = ROM, type = ro, start = $FFFA; } diff --git a/cfg/supervision-16k.cfg b/cfg/supervision-16k.cfg index 4a431621f..0a9bdf0f9 100644 --- a/cfg/supervision-16k.cfg +++ b/cfg/supervision-16k.cfg @@ -21,7 +21,7 @@ SEGMENTS { RODATA: load = ROM, type = ro, define = yes; DATA: load = ROM, run = RAM, type = rw, define = yes; FFF0: load = ROM, type = ro, offset = $3FF0; - VECTORS: load = ROM, type = ro, start = $3FFA; + VECTORS: load = ROM, type = ro, start = $FFFA; BSS: load = RAM, type = bss, define = yes; } FEATURES { diff --git a/cfg/supervision-64k.cfg b/cfg/supervision-64k.cfg index e0cb68a6f..404ece6fc 100644 --- a/cfg/supervision-64k.cfg +++ b/cfg/supervision-64k.cfg @@ -23,8 +23,8 @@ SEGMENTS { BANK1: load = BANKROM1, type = ro; BANK2: load = BANKROM2, type = ro; BANK3: load = BANKROM3, type = ro; - ZEROPAGE: load = RAM, type = bss, define = yes; - DATA: load = RAM, type = bss, define = yes, offset = $0200; + ZEROPAGE: load = RAM, type = zp, define = yes; + DATA: load = RAM, type = rw, define = yes, offset = $0200; BSS: load = RAM, type = bss, define = yes; - VECTORS: load = ROM, type = ro, start = $3FFA; + VECTORS: load = ROM, type = ro, start = $FFFA; } diff --git a/cfg/supervision.cfg b/cfg/supervision.cfg index 4ec3e49c7..1a745234f 100644 --- a/cfg/supervision.cfg +++ b/cfg/supervision.cfg @@ -20,7 +20,7 @@ SEGMENTS { RODATA: load = ROM, type = ro, define = yes; DATA: load = ROM, run = RAM, type = rw, define = yes; FFF0: load = ROM, type = ro, offset = $7FF0; - VECTORS: load = ROM, type = ro, start = $7FFA; + VECTORS: load = ROM, type = ro, start = $FFFA; BSS: load = RAM, type = bss, define = yes; } FEATURES { From c663f64542d49cd5000aa01c41cc151b442f065a Mon Sep 17 00:00:00 2001 From: Polluks <polluks@sdf.lonestar.org> Date: Fri, 27 Nov 2020 15:05:07 +0100 Subject: [PATCH 1827/2161] Added features; changed FFF0 segments --- cfg/supervision-128k.cfg | 17 ++++++++++++++++- cfg/supervision-16k.cfg | 2 +- cfg/supervision-64k.cfg | 15 +++++++++++++++ cfg/supervision.cfg | 2 +- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/cfg/supervision-128k.cfg b/cfg/supervision-128k.cfg index 535e93c1d..c90367aa1 100644 --- a/cfg/supervision-128k.cfg +++ b/cfg/supervision-128k.cfg @@ -1,4 +1,4 @@ -# supervision 1284kbyte cartridge with bankswitching +# supervision 128kbyte cartridge with bankswitching # for assembler # ld65 config file @@ -35,3 +35,18 @@ SEGMENTS { BSS: load = RAM, type = bss, define = yes; VECTORS: load = ROM, type = ro, start = $FFFA; } +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/supervision-16k.cfg b/cfg/supervision-16k.cfg index 0a9bdf0f9..dc6130b33 100644 --- a/cfg/supervision-16k.cfg +++ b/cfg/supervision-16k.cfg @@ -20,7 +20,7 @@ SEGMENTS { CODE: load = ROM, type = ro, define = yes; RODATA: load = ROM, type = ro, define = yes; DATA: load = ROM, run = RAM, type = rw, define = yes; - FFF0: load = ROM, type = ro, offset = $3FF0; + FFF0: load = ROM, type = ro, start = $FFF0; VECTORS: load = ROM, type = ro, start = $FFFA; BSS: load = RAM, type = bss, define = yes; } diff --git a/cfg/supervision-64k.cfg b/cfg/supervision-64k.cfg index 404ece6fc..d252c5d25 100644 --- a/cfg/supervision-64k.cfg +++ b/cfg/supervision-64k.cfg @@ -28,3 +28,18 @@ SEGMENTS { BSS: load = RAM, type = bss, define = yes; VECTORS: load = ROM, type = ro, start = $FFFA; } +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/supervision.cfg b/cfg/supervision.cfg index 1a745234f..1177660b8 100644 --- a/cfg/supervision.cfg +++ b/cfg/supervision.cfg @@ -19,7 +19,7 @@ SEGMENTS { CODE: load = ROM, type = ro, define = yes; RODATA: load = ROM, type = ro, define = yes; DATA: load = ROM, run = RAM, type = rw, define = yes; - FFF0: load = ROM, type = ro, offset = $7FF0; + FFF0: load = ROM, type = ro, start = $FFF0; VECTORS: load = ROM, type = ro, start = $FFFA; BSS: load = RAM, type = bss, define = yes; } From 2646c06f61b46ed142bbefc723acb8c2113a23f9 Mon Sep 17 00:00:00 2001 From: Tim Gates <tim.gates@iress.com> Date: Sun, 29 Nov 2020 18:23:52 +1100 Subject: [PATCH 1828/2161] docs: fix simple typo, paramater -> parameter There is a small typo in src/cc65/pragma.c. Should read `parameter` rather than `paramater`. --- src/cc65/pragma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index cf463a832..1ea86545d 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -677,7 +677,7 @@ static void WarnPragma (StrBuf* B) static void FlagPragma (StrBuf* B, IntStack* Stack) -/* Handle a pragma that expects a boolean paramater */ +/* Handle a pragma that expects a boolean parameter */ { StrBuf Ident = AUTO_STRBUF_INITIALIZER; long Val; @@ -727,7 +727,7 @@ ExitPoint: static void IntPragma (StrBuf* B, IntStack* Stack, long Low, long High) -/* Handle a pragma that expects an int paramater */ +/* Handle a pragma that expects an int parameter */ { long Val; int Push; From 95635418707e5a6ed270a341c02a743751631099 Mon Sep 17 00:00:00 2001 From: Polluks <polluks@sdf.lonestar.org> Date: Sun, 29 Nov 2020 17:10:34 +0100 Subject: [PATCH 1829/2161] crt0 clean-up --- libsrc/atari5200/crt0.s | 1 - libsrc/c16/crt0.s | 1 - libsrc/c64/crt0.s | 1 - libsrc/pet/crt0.s | 1 - libsrc/plus4/crt0.s | 2 -- libsrc/supervision/crt0.s | 2 -- libsrc/telestrat/crt0.s | 1 - libsrc/vic20/crt0.s | 1 - 8 files changed, 10 deletions(-) diff --git a/libsrc/atari5200/crt0.s b/libsrc/atari5200/crt0.s index ee3d0de4f..9538d3bb4 100644 --- a/libsrc/atari5200/crt0.s +++ b/libsrc/atari5200/crt0.s @@ -13,7 +13,6 @@ .import zerobss, copydata .include "zeropage.inc" - .include "atari5200.inc" start: diff --git a/libsrc/c16/crt0.s b/libsrc/c16/crt0.s index bee81a113..1df1e5c62 100644 --- a/libsrc/c16/crt0.s +++ b/libsrc/c16/crt0.s @@ -13,7 +13,6 @@ .importzp ST .include "zeropage.inc" - .include "plus4.inc" ; ------------------------------------------------------------------------ ; Startup code diff --git a/libsrc/c64/crt0.s b/libsrc/c64/crt0.s index 7bd294ca7..4e5c7c9d4 100644 --- a/libsrc/c64/crt0.s +++ b/libsrc/c64/crt0.s @@ -13,7 +13,6 @@ .importzp ST .include "zeropage.inc" - .include "c64.inc" ; ------------------------------------------------------------------------ diff --git a/libsrc/pet/crt0.s b/libsrc/pet/crt0.s index 520a147f7..e56a7eca4 100644 --- a/libsrc/pet/crt0.s +++ b/libsrc/pet/crt0.s @@ -12,7 +12,6 @@ .include "zeropage.inc" .include "pet.inc" - .include "../cbm/cbm.inc" ; ------------------------------------------------------------------------ ; Startup code diff --git a/libsrc/plus4/crt0.s b/libsrc/plus4/crt0.s index 2262b4c42..6b44a2b7e 100644 --- a/libsrc/plus4/crt0.s +++ b/libsrc/plus4/crt0.s @@ -198,5 +198,3 @@ irqcount: .byte 0 .segment "INIT" zpsave: .res zpspace - - diff --git a/libsrc/supervision/crt0.s b/libsrc/supervision/crt0.s index ac61c8215..203c681b8 100644 --- a/libsrc/supervision/crt0.s +++ b/libsrc/supervision/crt0.s @@ -78,5 +78,3 @@ not_dma: .word nmi .word reset32kcode .word irq - - diff --git a/libsrc/telestrat/crt0.s b/libsrc/telestrat/crt0.s index 59b1ea642..df75520ce 100644 --- a/libsrc/telestrat/crt0.s +++ b/libsrc/telestrat/crt0.s @@ -12,7 +12,6 @@ .import __MAIN_START__, __MAIN_SIZE__ .include "zeropage.inc" - .include "telestrat.inc" ; ------------------------------------------------------------------------ ; Place the startup code in a special segment. diff --git a/libsrc/vic20/crt0.s b/libsrc/vic20/crt0.s index 68ab3ed12..c5486063b 100644 --- a/libsrc/vic20/crt0.s +++ b/libsrc/vic20/crt0.s @@ -13,7 +13,6 @@ .importzp ST .include "zeropage.inc" - .include "vic20.inc" ; ------------------------------------------------------------------------ ; Startup code From b22d8c7441d29657fa772cd4da08b2ca5dd61946 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Sat, 28 Nov 2020 13:03:48 +0200 Subject: [PATCH 1830/2161] Added STATUS (0) definition --- asminc/c128.inc | 1 + asminc/c64.inc | 1 + asminc/plus4.inc | 1 + asminc/vic20.inc | 1 + 4 files changed, 4 insertions(+) diff --git a/asminc/c128.inc b/asminc/c128.inc index 2852631f3..749b4168c 100644 --- a/asminc/c128.inc +++ b/asminc/c128.inc @@ -7,6 +7,7 @@ ; 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 diff --git a/asminc/c64.inc b/asminc/c64.inc index 1d10f673d..2cfc50db4 100644 --- a/asminc/c64.inc +++ b/asminc/c64.inc @@ -9,6 +9,7 @@ VARTAB := $2D ; Pointer to start of BASIC variables MEMSIZE := $37 ; Pointer to highest BASIC RAM location (+1) TXTPTR := $7A ; Pointer into BASIC source code +STATUS := $90 ; Kernal I/O completion status TIME := $A0 ; 60 HZ clock FNAM_LEN := $B7 ; Length of filename SECADR := $B9 ; Secondary address diff --git a/asminc/plus4.inc b/asminc/plus4.inc index 774722e93..6c6017a78 100644 --- a/asminc/plus4.inc +++ b/asminc/plus4.inc @@ -10,6 +10,7 @@ TMPPTR := $22 ; Temporary ptr used by BASIC VARTAB := $2D ; Pointer to start of BASIC variables MEMSIZE := $37 ; Pointer to highest BASIC RAM location (+1) TXTPTR := $3B ; Pointer into BASIC source code +STATUS := $90 ; Kernal I/O completion status TIME := $A3 ; 60HZ clock FNAM_LEN := $AB ; Length of filename LFN := $AC ; Logical file number diff --git a/asminc/vic20.inc b/asminc/vic20.inc index b82874f56..fa9fdfa8d 100644 --- a/asminc/vic20.inc +++ b/asminc/vic20.inc @@ -9,6 +9,7 @@ VARTAB := $2D ; Pointer to start of BASIC variables MEMSIZE := $37 ; Pointer to highest BASIC RAM location (+1) TXTPTR := $7A ; 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 From 59c58acbe3229a4e860981e97d3d5f3a23adf2bc Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 5 Dec 2020 23:04:48 -0500 Subject: [PATCH 1831/2161] Documented the address size argument of the bss-name, code-name, data-name, and rodata-name pragmas. --- doc/cc65.sgml | 143 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 96 insertions(+), 47 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 115f0a30c..e273ced9c 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -6,8 +6,9 @@ <url url="mailto:gregdk@users.sf.net" name="Greg King"> <abstract> -cc65 is a C compiler for 6502 targets. It supports several 6502 based home -computers like the Commodore and Atari machines, but it is easily retargetable. +cc65 is a C compiler for 6502 targets. It supports several 6502-based home +computers such as the Commodore and Atari machines, but it easily is +retargetable. </abstract> <!-- Table of contents --> @@ -1011,7 +1012,7 @@ The compiler defines several macros at startup: <tag><tt>__TELESTRAT__</tt></tag> This macro is defined if the target is the Telestrat (-t telestrat). - + <tag><tt>__TIME__</tt></tag> This macro expands to the time of translation of the preprocessing @@ -1045,26 +1046,39 @@ parameter with the <tt/#pragma/. The <tt/#pragma/ understands the push and pop parameters as explained above. -<sect1><tt>#pragma bss-name ([push,] <name>)</tt><label id="pragma-bss-name"><p> +<sect1><tt>#pragma bss-name ([push, ]<name>[ ,<addrsize>])</tt><label id="pragma-bss-name"><p> - This pragma changes the name used for the BSS segment (the BSS segment - is used to store variables with static storage duration and no explicit - initializer). The argument is a string enclosed in double quotes. + This pragma changes the name used for the BSS segment (the BSS segment is + used to store variables with static storage duration and no explicit + initializers). The <tt/name/ argument is a string enclosed in quotation + marks. - Note: The default linker configuration file does only map the standard - segments. If you use other segments, you have to create a new linker - configuration file. + <tt/addrsize/ is an optional string that gives a hint about where the + <tt/name/ segment will be put in the CPU's address space. It describes the + width of address numbers that point into that segment. Only words that + are known to ca65 are allowed: + <enum> + <item>"zp", "zeropage", "direct" + <item>"abs", "absolute", "near", "default" + <item>"far" + <item>"long", "dword" + </enum> - Beware: The startup code will zero only the default BSS segment. If you - use another BSS segment, you have to do that yourself, otherwise - variables with static storage duration and no explicit initializer will - not have the value zero. + Note: The default linker configuration file maps only the standard segments. + If you use other segments, you must create a new linker configuration file. - The <tt/#pragma/ understands the push and pop parameters as explained above. + Beware: The start-up code will zero only the default BSS segment. If you use + another BSS segment, then you must do that yourself; otherwise, variables + with static storage duration and no explicit initializer will not have the + value zero. - Example: + The <tt/#pragma/ understands the push and pop parameters, as explained above. + + Examples: <tscreen><verb> - #pragma bss-name ("MyBSS") + #pragma bss-name ("MyBSS") + #pragma bss-name (push, "MyBSS") + #pragma bss-name ("MyBSS", "zp") </verb></tscreen> @@ -1120,21 +1134,33 @@ parameter with the <tt/#pragma/. The <tt/#pragma/ understands the push and pop parameters as explained above. -<sect1><tt>#pragma code-name ([push,] <name>)</tt><label id="pragma-code-name"><p> +<sect1><tt>#pragma code-name ([push, ]<name>[ ,<addrsize>])</tt><label id="pragma-code-name"><p> - This pragma changes the name used for the CODE segment (the CODE segment - is used to store executable code). The argument is a string enclosed in - double quotes. + This pragma changes the name used for the CODE segment (the CODE segment is + used to store executable code). The <tt/name/ argument is a string enclosed + in quotation marks. - Note: The default linker configuration file does only map the standard - segments. If you use other segments, you have to create a new linker - configuration file. + <tt/addrsize/ is an optional string that gives a hint about where the + <tt/name/ segment will be put in the CPU's address space. It describes the + width of address numbers that point into that segment. Only words that + are known to ca65 are allowed: + <enum> + <item>"zp", "zeropage", "direct" + <item>"abs", "absolute", "near", "default" + <item>"far" + <item>"long", "dword" + </enum> - The <tt/#pragma/ understands the push and pop parameters as explained above. + Note: The default linker configuration file maps only the standard segments. + If you use other segments, you must create a new linker configuration file. - Example: + The <tt/#pragma/ understands the push and pop parameters, as explained above. + + Examples: <tscreen><verb> - #pragma code-name ("MyCODE") + #pragma code-name ("MyCODE") + #pragma code-name (push, "MyCODE") + #pragma code-name (push, "MyCODE", "far") </verb></tscreen> @@ -1148,21 +1174,33 @@ parameter with the <tt/#pragma/. The <tt/#pragma/ understands the push and pop parameters as explained above. -<sect1><tt>#pragma data-name ([push,] <name>)</tt><label id="pragma-data-name"><p> +<sect1><tt>#pragma data-name ([push, ]<name>[ ,<addrsize>])</tt><label id="pragma-data-name"><p> - This pragma changes the name used for the DATA segment (the DATA segment - is used to store initialized data). The argument is a string enclosed in - double quotes. + This pragma changes the name used for the DATA segment (the DATA segment is + used to store initialized data). The <tt/name/ argument is a string enclosed + in quotation marks. - Note: The default linker configuration file does only map the standard - segments. If you use other segments, you have to create a new linker - configuration file. + <tt/addrsize/ is an optional string that gives a hint about where the + <tt/name/ segment will be put in the CPU's address space. It describes the + width of address numbers that point into that segment. Only words that + are known to ca65 are allowed: + <enum> + <item>"zp", "zeropage", "direct" + <item>"abs", "absolute", "near", "default" + <item>"far" + <item>"long", "dword" + </enum> - The <tt/#pragma/ understands the push and pop parameters as explained above. + Note: The default linker configuration file maps only the standard segments. + If you use other segments, you must create a new linker configuration file. - Example: + The <tt/#pragma/ understands the push and pop parameters, as explained above. + + Examples: <tscreen><verb> - #pragma data-name ("MyDATA") + #pragma data-name ("MyDATA") + #pragma data-name (push, "MyDATA") + #pragma data-name ("MyDATA", "zeropage") </verb></tscreen> @@ -1224,21 +1262,32 @@ parameter with the <tt/#pragma/. The <tt/#pragma/ understands the push and pop parameters as explained above. -<sect1><tt>#pragma rodata-name ([push,] <name>)</tt><label id="pragma-rodata-name"><p> +<sect1><tt>#pragma rodata-name ([push, ]<name>[ ,<addrsize>])</tt><label id="pragma-rodata-name"><p> - This pragma changes the name used for the RODATA segment (the RODATA - segment is used to store readonly data). The argument is a string - enclosed in double quotes. + This pragma changes the name used for the RODATA segment (the RODATA segment + is used to store read-only data). The <tt/name/ argument is a string enclosed + in quotation marks. - Note: The default linker configuration file does only map the standard - segments. If you use other segments, you have to create a new linker - configuration file. + <tt/addrsize/ is an optional string that gives a hint about where the + <tt/name/ segment will be put in the CPU's address space. It describes the + width of address numbers that point into that segment. Only words that + are known to ca65 are allowed: + <enum> + <item>"zp", "zeropage", "direct" + <item>"abs", "absolute", "near", "default" + <item>"far" + <item>"long", "dword" + </enum> - The <tt/#pragma/ understands the push and pop parameters as explained above. + Note: The default linker configuration file maps only the standard segments. + If you use other segments, you must create a new linker configuration file. - Example: + The <tt/#pragma/ understands the push and pop parameters, as explained above. + + Examples: <tscreen><verb> - #pragma rodata-name ("MyRODATA") + #pragma rodata-name ("MyRODATA") + #pragma rodata-name (push, "MyRODATA") </verb></tscreen> From 0f4cb443b4d34dfceef35c0f9b31abcf69d00c67 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 19 Dec 2020 19:54:12 +0100 Subject: [PATCH 1832/2161] Improved device I/O under DOS 3.3 Certain scenarios (e.g. not running any Applesoft program at all since booting DOS 3.3) can make DOS 3.3 consider cc65 device input (e.g. getchar()) that reads a CR interpreting the command in the keyboard buffer. Setting the hibyte of the Applesoft currently executed line number to some value <> $FF (beside setting the input prompt to some value <> ']') makes DOS 3.3 understand that we're not in intermediate mode and that therefore I/O not preceded with ctrl-d mustn't be fiddled with (see DOS 3.3 routine at $A65E). --- asminc/apple2.inc | 1 + libsrc/apple2/read.s | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/asminc/apple2.inc b/asminc/apple2.inc index 5ebf73164..528c463a1 100644 --- a/asminc/apple2.inc +++ b/asminc/apple2.inc @@ -15,6 +15,7 @@ PROMPT := $33 ; Used by GETLN RNDL := $4E ; Random counter low RNDH := $4F ; Random counter high HIMEM := $73 ; Highest available memory address+1 +CURLIN := $75 ; Current line number being executed ;----------------------------------------------------------------------------- ; Vectors diff --git a/libsrc/apple2/read.s b/libsrc/apple2/read.s index 14c80b7e2..99c189cbd 100644 --- a/libsrc/apple2/read.s +++ b/libsrc/apple2/read.s @@ -19,11 +19,14 @@ .segment "ONCE" initprompt: - ; Set prompt <> ']' to let DOS 3.3 know that we're - ; not in Applesoft immediate mode and thus keep it - ; from scanning our device I/O for DOS commands. + ; Set prompt <> ']' and currently executed Applesoft + ; line number hibyte <> $FF to let DOS 3.3 (at $A65E) + ; know that we're not in Applesoft immediate mode and + ; thus keep it from scanning our device I/O for DOS + ; commands. lda #$80 ; Same value used at $D52C sta PROMPT + sta CURLIN+1 ; Any value <> $FF will do rts .code From b2c1a77bb389bf20b5043f796f2dee496c07fdbd Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 24 Dec 2020 12:27:09 -0500 Subject: [PATCH 1833/2161] Fixed the cc65 code that optimizes 16-bit compares when the high bytes are known to be equal. Only the low bytes are compared. Originally, signed 16-bit compares were optimized into signed 8-bit compares. But, the sign bits are in the high bytes; and, they're equal. Therefore, the low bytes always must be compared as unsigned numbers. Fixes #1348. --- src/cc65/coptstop.c | 78 +++++++++++------------------------- test/misc/Makefile | 8 ---- test/{misc => val}/bug1348.c | 28 ++++++------- 3 files changed, 37 insertions(+), 77 deletions(-) rename test/{misc => val}/bug1348.c (61%) diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 59bbe6dc9..77b79281b 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -287,7 +287,7 @@ static unsigned Opt_tosshift (StackOpData* D, const char* Name) /* ldx */ X = NewCodeEntry (OP65_LDX, LoadX->AM, LoadX->Arg, 0, D->OpEntry->LI); InsertEntry (D, X, D->IP++); - + /* Lhs load entries can be removed if not used later */ D->Lhs.X.Flags |= LI_REMOVE; D->Lhs.A.Flags |= LI_REMOVE; @@ -1100,7 +1100,7 @@ static unsigned Opt_tosxorax (StackOpData* D) static unsigned Opt_a_toscmpbool (StackOpData* D, const char* BoolTransformer) -/* Optimize the tos compare sequence with a bool transformer */ +/* Optimize the TOS compare sequence with a bool transformer */ { CodeEntry* X; cmp_t Cond; @@ -1119,9 +1119,8 @@ static unsigned Opt_a_toscmpbool (StackOpData* D, const char* BoolTransformer) D->Rhs.A.Flags |= LI_REMOVE; } else if ((D->Lhs.A.Flags & LI_DIRECT) != 0) { - - /* If the lhs is direct (but not stack relative), encode compares with lhs - ** effectively reverting the order (which doesn't matter for ==). + /* If the lhs is direct (but not stack relative), encode compares with lhs, + ** effectively reversing the order (which doesn't matter for == and !=). */ Cond = FindBoolCmpCond (BoolTransformer); Cond = GetRevertedCond (Cond); @@ -1138,7 +1137,6 @@ static unsigned Opt_a_toscmpbool (StackOpData* D, const char* BoolTransformer) D->Lhs.A.Flags |= LI_REMOVE; } else { - /* We'll do reverse-compare */ Cond = FindBoolCmpCond (BoolTransformer); Cond = GetRevertedCond (Cond); @@ -1162,7 +1160,7 @@ static unsigned Opt_a_toscmpbool (StackOpData* D, const char* BoolTransformer) X = NewCodeEntry (OP65_JSR, AM65_ABS, BoolTransformer, 0, D->OpEntry->LI); InsertEntry (D, X, D->IP++); - /* Remove the push and the call to the tosgeax function */ + /* Remove the push and the call to the TOS function */ RemoveRemainders (D); /* We changed the sequence */ @@ -1179,22 +1177,6 @@ static unsigned Opt_a_toseq (StackOpData* D) -static unsigned Opt_a_tosge (StackOpData* D) -/* Optimize the tosgeax sequence */ -{ - return Opt_a_toscmpbool (D, "boolge"); -} - - - -static unsigned Opt_a_tosgt (StackOpData* D) -/* Optimize the tosgtax sequence */ -{ - return Opt_a_toscmpbool (D, "boolgt"); -} - - - static unsigned Opt_a_tosicmp (StackOpData* D) /* Replace tosicmp with CMP */ { @@ -1236,7 +1218,7 @@ static unsigned Opt_a_tosicmp (StackOpData* D) } InsertEntry (D, X, D->IP++); - /* cmp src,y OR cmp (sp),y*/ + /* cmp src,y OR cmp (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); @@ -1268,18 +1250,18 @@ static unsigned Opt_a_tosicmp (StackOpData* D) InsertEntry (D, X, D->IP-3); } else { - /* Just clear A,Z,N and set C */ + /* Just clear A,Z,N; and set C */ + Arg = MakeHexArg (0); if ((RI = GetLastChangedRegInfo (D, &D->Lhs.A)) != 0 && RegValIsKnown (RI->Out.RegA) && (RI->Out.RegA & 0xFF) == 0) { - Arg = MakeHexArg (0); - X = NewCodeEntry (OP65_CMP, AM65_IMM, Arg, 0, D->OpEntry->LI); + + X = NewCodeEntry (OP65_CMP, AM65_IMM, Arg, 0, D->OpEntry->LI); InsertEntry (D, X, D->OpIndex + 1); } else { - Arg = MakeHexArg (0); - X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, D->OpEntry->LI); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, D->OpEntry->LI); InsertEntry (D, X, D->OpIndex + 1); - X = NewCodeEntry (OP65_CMP, AM65_IMM, Arg, 0, D->OpEntry->LI); + X = NewCodeEntry (OP65_CMP, AM65_IMM, Arg, 0, D->OpEntry->LI); InsertEntry (D, X, D->OpIndex + 2); } } @@ -1292,24 +1274,8 @@ static unsigned Opt_a_tosicmp (StackOpData* D) -static unsigned Opt_a_tosle (StackOpData* D) -/* Optimize the tosleax sequence */ -{ - return Opt_a_toscmpbool (D, "boolle"); -} - - - -static unsigned Opt_a_toslt (StackOpData* D) -/* Optimize the tosltax sequence */ -{ - return Opt_a_toscmpbool (D, "boollt"); -} - - - static unsigned Opt_a_tosne (StackOpData* D) -/* Optimize the toseqax sequence */ +/* Optimize the tosneax sequence */ { return Opt_a_toscmpbool (D, "boolne"); } @@ -1317,7 +1283,7 @@ static unsigned Opt_a_tosne (StackOpData* D) static unsigned Opt_a_tosuge (StackOpData* D) -/* Optimize the tosugeax sequence */ +/* Optimize the tosgeax and tosugeax sequences */ { return Opt_a_toscmpbool (D, "booluge"); } @@ -1325,7 +1291,7 @@ static unsigned Opt_a_tosuge (StackOpData* D) static unsigned Opt_a_tosugt (StackOpData* D) -/* Optimize the tosugtax sequence */ +/* Optimize the tosgtax and tosugtax sequences */ { return Opt_a_toscmpbool (D, "boolugt"); } @@ -1333,7 +1299,7 @@ static unsigned Opt_a_tosugt (StackOpData* D) static unsigned Opt_a_tosule (StackOpData* D) -/* Optimize the tosuleax sequence */ +/* Optimize the tosleax and tosuleax sequences */ { return Opt_a_toscmpbool (D, "boolule"); } @@ -1341,7 +1307,7 @@ static unsigned Opt_a_tosule (StackOpData* D) static unsigned Opt_a_tosult (StackOpData* D) -/* Optimize the tosultax sequence */ +/* Optimize the tosltax and tosultax sequences */ { return Opt_a_toscmpbool (D, "boolult"); } @@ -1354,6 +1320,8 @@ static unsigned Opt_a_tosult (StackOpData* D) +/* The first column of these two tables must be sorted in lexical order */ + static const OptFuncDesc FuncTable[] = { { "__bzero", Opt___bzero, REG_NONE, OP_X_ZERO | OP_A_KNOWN }, { "staspidx", Opt_staspidx, REG_NONE, OP_NONE }, @@ -1379,11 +1347,11 @@ static const OptFuncDesc FuncTable[] = { static const OptFuncDesc FuncRegATable[] = { { "toseqax", Opt_a_toseq, REG_NONE, OP_NONE }, - { "tosgeax", Opt_a_tosge, REG_NONE, OP_NONE }, - { "tosgtax", Opt_a_tosgt, REG_NONE, OP_NONE }, + { "tosgeax", Opt_a_tosuge, REG_NONE, OP_NONE }, + { "tosgtax", Opt_a_tosugt, REG_NONE, OP_NONE }, { "tosicmp", Opt_a_tosicmp, REG_NONE, OP_NONE }, - { "tosleax", Opt_a_tosle, REG_NONE, OP_NONE }, - { "tosltax", Opt_a_toslt, REG_NONE, OP_NONE }, + { "tosleax", Opt_a_tosule, REG_NONE, OP_NONE }, + { "tosltax", Opt_a_tosult, REG_NONE, OP_NONE }, { "tosneax", Opt_a_tosne, REG_NONE, OP_NONE }, { "tosugeax", Opt_a_tosuge, REG_NONE, OP_NONE }, { "tosugtax", Opt_a_tosugt, REG_NONE, OP_NONE }, diff --git a/test/misc/Makefile b/test/misc/Makefile index ad31e8554..81a09c693 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -117,14 +117,6 @@ $(WORKDIR)/endless.$1.$2.prg: endless.c | $(WORKDIR) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) $(NOT) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) -# this one fails when optimization are enabled -$(WORKDIR)/bug1348.$1.$2.prg: bug1348.c | $(WORKDIR) - $(if $(QUIET),echo misc/bug1348.$1.$2.prg) - $(CC65) -Osr -t sim$2 -$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) - $(NOT) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) - # these need reference data that can't be generated by a host-compiled program, # in a useful way $(WORKDIR)/limits.$1.$2.prg: limits.c $(ISEQUAL) | $(WORKDIR) diff --git a/test/misc/bug1348.c b/test/val/bug1348.c similarity index 61% rename from test/misc/bug1348.c rename to test/val/bug1348.c index 913849482..c40d9ac84 100644 --- a/test/misc/bug1348.c +++ b/test/val/bug1348.c @@ -1,27 +1,26 @@ - -/* bug#1348, wrongly optimized integer promotion in comparison */ +/* bug #1348, wrongly optimized integer promotion in comparison */ #include <stdio.h> -int notrandtab[] = { +static const int notrandtab[] = { 0xffff, 0x7fff, 0x3fff, 0x1fff, 0x0fff, 0x07ff, 0x03ff, 0x01ff, 0x00ff, 0x007f, 0x003f, 0x001f, 0x000f, 0x0007, 0x0003, 0x0001 }; -unsigned char notrandcount = 0; +static unsigned char notrandcount = 0; -int notrand(void) +static int notrand(void) { return notrandtab[notrandcount & 0x0f]; } -unsigned char n1, n2; -unsigned char i, ii, s; -unsigned char err = 0; +static unsigned char n1, n2; +static unsigned char i, ii, s; +static unsigned char err = 0; -unsigned char cmptab[] = { +static const unsigned char cmptab[] = { 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x80, 0x40, 0x20, 0x10, @@ -40,13 +39,14 @@ int main(void) if ((notrand() & 0xffu) > s) { n2 = 1; } - printf("%5d>%3d %d(%02x) %d(%02x) %s\n", - notrandtab[notrandcount & 0x0f], s, + printf("%5d > %3d %u(%02x) %u(%02x) %s\n", + notrandtab[i], s, n1, (notrand() & 0xff), n2, (notrand() & 0xffu), - n1 == n2 ? "=" : "!=" - ); - if (n1 != n2) err = 1; + n1 == n2 ? "=" : "!="); + if (n1 != n2) { + err = 1; + } notrandcount++; } } From dfd047ce6a693a2bc32a8778b06bd08c3d39aa0b Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Fri, 13 Nov 2020 09:01:26 +0100 Subject: [PATCH 1834/2161] g_typeadjust: Use CF_CHAR for char args If lhs and rhs are either both signed char or both unsigned char, return flags for that type instead of (unsigned) int. The flags are used only for codegen. Currently, this does nothing, since codegen treats chars as ints unless CF_FORCECHAR is set, but it allows more efficient char x char -> int codegen to be added in the future. --- src/cc65/codegen.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index f56abcd95..a58484cf1 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -1433,17 +1433,20 @@ unsigned g_typeadjust (unsigned lhs, unsigned rhs) /* Note that this logic is largely duplicated by ArithmeticConvert. */ - /* Before we apply the integral promotions, we check if both types are unsigned char. - ** If so, we return unsigned int, rather than int, which would be returned by the standard - ** rules. This is only a performance optimization and does not affect correctness, as - ** the flags are only used for code generation, and not to determine types of other - ** expressions containing this one. All unsigned char bit-patterns are valid as both int - ** and unsigned int and represent the same value, so either signed or unsigned int operations - ** can be used. This special case part is not duplicated by ArithmeticConvert. + /* Before we apply the integral promotions, we check if both types are the same character type. + ** If so, we return that type, rather than int, which would be returned by the standard + ** rules. This is only a performance optimization allowing the use of unsigned and/or char + ** operations; it does not affect correctness, as the flags are only used for code generation, + ** and not to determine types of other expressions containing this one. For codgen, CF_CHAR + ** means the operands are char and the result is int (unless CF_FORCECHAR is also set, in + ** which case the result is char). This special case part is not duplicated by + ** ArithmeticConvert. */ - if ((lhs & CF_TYPEMASK) == CF_CHAR && (lhs & CF_UNSIGNED) && - (rhs & CF_TYPEMASK) == CF_CHAR && (rhs & CF_UNSIGNED)) { - return const_flag | CF_UNSIGNED | CF_INT; + if ((lhs & CF_TYPEMASK) == CF_CHAR && (rhs & CF_TYPEMASK) == CF_CHAR && + (lhs & CF_UNSIGNED) == (rhs & CF_UNSIGNED)) { + /* Signedness flags are the same, so just use one of them. */ + const unsigned unsigned_flag = lhs & CF_UNSIGNED; + return const_flag | unsigned_flag | CF_CHAR; } /* Apply integral promotions for types char/short. */ From 1c72da490479b6876557c3cf75577e7ed55f5e15 Mon Sep 17 00:00:00 2001 From: baktrasf <zylon@post.cz> Date: Mon, 21 Dec 2020 21:31:53 +0100 Subject: [PATCH 1835/2161] Add operating system symbols for the Atari 5200 target --- include/_atari5200os.h | 80 ++++++++++++++++++++++++++++++++++++++++++ include/atari5200.h | 4 +++ 2 files changed, 84 insertions(+) create mode 100644 include/_atari5200os.h diff --git a/include/_atari5200os.h b/include/_atari5200os.h new file mode 100644 index 000000000..77ccf14ed --- /dev/null +++ b/include/_atari5200os.h @@ -0,0 +1,80 @@ +/*****************************************************************************/ +/* */ +/* _atari5200os.h */ +/* */ +/* Internal include file, do not use directly */ +/* */ +/* */ +/* 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 __ATARI5200OS_H +#define __ATARI5200OS_H + + +struct __os { + + /*Page zero*/ + unsigned char pokmsk; // = $00 System mask for POKEY IRQ enable + unsigned char rtclok[2]; // = $01,$02 Real time clock + unsigned char critic; // = $03 Critical section flag + unsigned char atract; // = $04 Attract mode counter + + union { + struct { + unsigned char sdlstl; // = $05 Save display list LO + unsigned char sdlsth; // = $06 Save display list HI + }; + void* sdlst; // = $05,$06 Display list shadow + }; + + unsigned char sdmctl; // = $07 DMACTL shadow + unsigned char pcolr0; // = $08 PM color 0 + unsigned char pcolr1; // = $09 PM color 1 + unsigned char pcolr2; // = $0A PM color 2 + unsigned char pcolr3; // = $0B PM color 3 + unsigned char color0; // = $0C PF Color 0 + unsigned char color1; // = $0D PF Color 1 + unsigned char color2; // = $0E PF Color 2 + unsigned char color3; // = $0F PF Color 3 + unsigned char color4; // = $10 PF Color 4 + unsigned char __filler[0xEF]; // = $11-$FF Filler + + /*Stack*/ + unsigned char stack[0x100]; // = $100-$1FF Stack + + /*Page 2 OS variables*/ + void (*vinter)(void); // = $200 Immediate IRQ vector + void (*vvblki)(void); // = $202 Immediate VBI vector + void (*vvblkd)(void); // = $204 Deferred VBI vector + void (*vdslst)(void); // = $206 DLI vector + void (*vkeybd)(void); // = $208 Keyboard IRQ vector + void (*vkeypd)(void); // = $20A Keypad continue vector + void (*vbrkky)(void); // = $20C Break key interrupt vector + void (*vbreak)(void); // = $20E Break instruction interrupt vector + void (*vserin)(void); // = $210 Serial input ready vector + void (*vseror)(void); // = $212 Serial output data needed vector + void (*vseroc)(void); // = $214 Serial output completed vector + void (*vtimr1)(void); // = $216 POKEY timer 1 IRQ vector + void (*vtimr2)(void); // = $218 POKEY timer 2 IRQ vector + void (*vtimr4)(void); // = $21A POKEY timer 4 IRQ vector + +}; + +#endif \ No newline at end of file diff --git a/include/atari5200.h b/include/atari5200.h index a18360c61..ff176c15b 100644 --- a/include/atari5200.h +++ b/include/atari5200.h @@ -65,6 +65,10 @@ extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */ #define AT_NTSC 0 #define AT_PAL 1 +/* Define variables used by the OS*/ +#include <_atari5200os.h> +#define OS (*(struct __os*)0x0000) + /* define hardware */ #include <_gtia.h> #define GTIA_READ (*(struct __gtia_read*)0xC000) From 2e9bada1f20b645ea94343adaf03d85da15a1d45 Mon Sep 17 00:00:00 2001 From: baktrasf <zylon@post.cz> Date: Wed, 23 Dec 2020 23:35:09 +0100 Subject: [PATCH 1836/2161] Atari 5200 OS header refinements --- doc/atari5200.sgml | 10 ++++++++++ include/_atari5200os.h | 18 +++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/doc/atari5200.sgml b/doc/atari5200.sgml index 032b0ef6c..2ec3d08f0 100644 --- a/doc/atari5200.sgml +++ b/doc/atari5200.sgml @@ -73,7 +73,17 @@ Special locations: Programs containing Atari 5200 specific code may use the <tt/atari5200.h/ header file. +This also includes access to operating system locations (e.g. hardware shadow registers) by a structure called +"<tt/OS/". +The names are the usual ones you can find in system reference manuals. Example: +<tscreen><verb> +... + OS.sdmctl = 0x00; // screen off + OS.color4 = 14; // white frame +... tics = OS.rtclok[1] // get ticks +</verb></tscreen> + <sect1>Atari 5200 specific functions<p> <itemize> diff --git a/include/_atari5200os.h b/include/_atari5200os.h index 77ccf14ed..db0f7f0c9 100644 --- a/include/_atari5200os.h +++ b/include/_atari5200os.h @@ -49,12 +49,12 @@ struct __os { unsigned char pcolr1; // = $09 PM color 1 unsigned char pcolr2; // = $0A PM color 2 unsigned char pcolr3; // = $0B PM color 3 - unsigned char color0; // = $0C PF Color 0 - unsigned char color1; // = $0D PF Color 1 - unsigned char color2; // = $0E PF Color 2 - unsigned char color3; // = $0F PF Color 3 - unsigned char color4; // = $10 PF Color 4 - unsigned char __filler[0xEF]; // = $11-$FF Filler + unsigned char color0; // = $0C PF color 0 + unsigned char color1; // = $0D PF color 1 + unsigned char color2; // = $0E PF color 2 + unsigned char color3; // = $0F PF color 3 + unsigned char color4; // = $10 PF color 4 + unsigned char _free_1[0xEF]; // = $11-$FF User space /*Stack*/ unsigned char stack[0x100]; // = $100-$1FF Stack @@ -65,9 +65,9 @@ struct __os { void (*vvblkd)(void); // = $204 Deferred VBI vector void (*vdslst)(void); // = $206 DLI vector void (*vkeybd)(void); // = $208 Keyboard IRQ vector - void (*vkeypd)(void); // = $20A Keypad continue vector + void (*vkeypd)(void); // = $20A Keyboard continuation vector void (*vbrkky)(void); // = $20C Break key interrupt vector - void (*vbreak)(void); // = $20E Break instruction interrupt vector + void (*vbreak)(void); // = $20E BRK instruction interrupt vector void (*vserin)(void); // = $210 Serial input ready vector void (*vseror)(void); // = $212 Serial output data needed vector void (*vseroc)(void); // = $214 Serial output completed vector @@ -77,4 +77,4 @@ struct __os { }; -#endif \ No newline at end of file +#endif From d67b955e528d032d287b1bdec450643b0d5a8a6c Mon Sep 17 00:00:00 2001 From: michael <zylon@post.cz> Date: Wed, 23 Dec 2020 23:50:10 +0100 Subject: [PATCH 1837/2161] Fixed example of the OS struct usage for Atari 5200 --- doc/atari5200.sgml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/atari5200.sgml b/doc/atari5200.sgml index 2ec3d08f0..aff212b15 100644 --- a/doc/atari5200.sgml +++ b/doc/atari5200.sgml @@ -81,7 +81,8 @@ The names are the usual ones you can find in system reference manuals. Example: ... OS.sdmctl = 0x00; // screen off OS.color4 = 14; // white frame -... tics = OS.rtclok[1] // get ticks + tics = OS.rtclok[1] // get ticks +... </verb></tscreen> <sect1>Atari 5200 specific functions<p> From ef258bdc1913b2bc97011e64affb7925b80c1e5a Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Fri, 25 Dec 2020 07:16:26 +0100 Subject: [PATCH 1838/2161] remove TABs which again slipped in.... --- src/cc65/expr.h | 8 +- test/val/binlit.c | 1044 ++++++++++++++++++++++---------------------- test/val/bug1071.c | 40 +- test/val/rand.c | 134 +++--- 4 files changed, 613 insertions(+), 613 deletions(-) diff --git a/src/cc65/expr.h b/src/cc65/expr.h index d0a9988af..71dbe8e0d 100644 --- a/src/cc65/expr.h +++ b/src/cc65/expr.h @@ -23,10 +23,10 @@ -#define SQP_KEEP_NONE 0x00 -#define SQP_KEEP_TEST 0x01U -#define SQP_KEEP_EAX 0x02U -#define SQP_KEEP_EXPR 0x03U /* SQP_KEEP_TEST | SQP_KEEP_EAX */ +#define SQP_KEEP_NONE 0x00 +#define SQP_KEEP_TEST 0x01U +#define SQP_KEEP_EAX 0x02U +#define SQP_KEEP_EXPR 0x03U /* SQP_KEEP_TEST | SQP_KEEP_EAX */ diff --git a/test/val/binlit.c b/test/val/binlit.c index 47e7a196e..f89ca60fc 100644 --- a/test/val/binlit.c +++ b/test/val/binlit.c @@ -3,531 +3,531 @@ static unsigned big[256]; int main() { - unsigned i; + unsigned i; - small[0] = 0b0; - small[1] = 0b1; - small[2] = 0b10; - small[3] = 0b11; - small[4] = 0b100; - small[5] = 0b101; - small[6] = 0b110; - small[7] = 0b000111; - small[8] = 0b1000; - small[9] = 0b1001; - small[10] = 0b0001010; - small[11] = 0b0001011; - small[12] = 0b1100; - small[13] = 0b1101; - small[14] = 0b1110; - small[15] = 0b1111; - small[16] = 0b10000; - small[17] = 0b10001; - small[18] = 0b00010010; - small[19] = 0b00010011; - small[20] = 0b00010100; - small[21] = 0b00010101; - small[22] = 0b10110; - small[23] = 0b10111; - small[24] = 0b11000; - small[25] = 0b11001; - small[26] = 0b11010; - small[27] = 0b11011; - small[28] = 0b11100; - small[29] = 0b11101; - small[30] = 0b11110; - small[31] = 0b11111; - small[32] = 0b00000000100000; - small[33] = 0b00000000100001; - small[34] = 0b100010; - small[35] = 0b100011; - small[36] = 0b100100; - small[37] = 0b100101; - small[38] = 0b100110; - small[39] = 0b100111; - small[40] = 0b101000; - small[41] = 0b101001; - small[42] = 0b101010; - small[43] = 0b101011; - small[44] = 0b101100; - small[45] = 0b101101; - small[46] = 0b101110; - small[47] = 0b101111; - small[48] = 0b110000; - small[49] = 0b110001; - small[50] = 0b110010; - small[51] = 0b110011; - small[52] = 0b110100; - small[53] = 0b110101; - small[54] = 0b110110; - small[55] = 0b110111; - small[56] = 0b111000; - small[57] = 0b111001; - small[58] = 0b111010; - small[59] = 0b111011; - small[60] = 0b111100; - small[61] = 0b111101; - small[62] = 0b111110; - small[63] = 0b111111; - small[64] = 0b1000000; - small[65] = 0b1000001; - small[66] = 0b1000010; - small[67] = 0b1000011; - small[68] = 0b1000100; - small[69] = 0b1000101; - small[70] = 0b1000110; - small[71] = 0b1000111; - small[72] = 0b1001000; - small[73] = 0b1001001; - small[74] = 0b1001010; - small[75] = 0b1001011; - small[76] = 0b1001100; - small[77] = 0b1001101; - small[78] = 0b1001110; - small[79] = 0b1001111; - small[80] = 0b1010000; - small[81] = 0b1010001; - small[82] = 0b1010010; - small[83] = 0b1010011; - small[84] = 0b1010100; - small[85] = 0b1010101; - small[86] = 0b1010110; - small[87] = 0b1010111; - small[88] = 0b1011000; - small[89] = 0b1011001; - small[90] = 0b1011010; - small[91] = 0b1011011; - small[92] = 0b1011100; - small[93] = 0b1011101; - small[94] = 0b1011110; - small[95] = 0b1011111; - small[96] = 0b1100000; - small[97] = 0b1100001; - small[98] = 0b1100010; - small[99] = 0b1100011; - small[100] = 0b1100100; - small[101] = 0b1100101; - small[102] = 0b1100110; - small[103] = 0b1100111; - small[104] = 0b1101000; - small[105] = 0b1101001; - small[106] = 0b1101010; - small[107] = 0b1101011; - small[108] = 0b1101100; - small[109] = 0b1101101; - small[110] = 0b1101110; - small[111] = 0b1101111; - small[112] = 0b1110000; - small[113] = 0b1110001; - small[114] = 0b1110010; - small[115] = 0b1110011; - small[116] = 0b1110100; - small[117] = 0b1110101; - small[118] = 0b1110110; - small[119] = 0b1110111; - small[120] = 0b1111000; - small[121] = 0b1111001; - small[122] = 0b1111010; - small[123] = 0b1111011; - small[124] = 0b1111100; - small[125] = 0b1111101; - small[126] = 0b1111110; - small[127] = 0b1111111; - small[128] = 0b10000000; - small[129] = 0b10000001; - small[130] = 0b10000010; - small[131] = 0b10000011; - small[132] = 0b10000100; - small[133] = 0b10000101; - small[134] = 0b10000110; - small[135] = 0b10000111; - small[136] = 0b10001000; - small[137] = 0b10001001; - small[138] = 0b10001010; - small[139] = 0b10001011; - small[140] = 0b10001100; - small[141] = 0b10001101; - small[142] = 0b10001110; - small[143] = 0b10001111; - small[144] = 0b10010000; - small[145] = 0b10010001; - small[146] = 0b10010010; - small[147] = 0b10010011; - small[148] = 0b10010100; - small[149] = 0b10010101; - small[150] = 0b10010110; - small[151] = 0b10010111; - small[152] = 0b10011000; - small[153] = 0b10011001; - small[154] = 0b10011010; - small[155] = 0b10011011; - small[156] = 0b10011100; - small[157] = 0b10011101; - small[158] = 0b10011110; - small[159] = 0b10011111; - small[160] = 0b10100000; - small[161] = 0b10100001; - small[162] = 0b10100010; - small[163] = 0b10100011; - small[164] = 0b10100100; - small[165] = 0b10100101; - small[166] = 0b10100110; - small[167] = 0b10100111; - small[168] = 0b10101000; - small[169] = 0b10101001; - small[170] = 0b10101010; - small[171] = 0b10101011; - small[172] = 0b10101100; - small[173] = 0b10101101; - small[174] = 0b10101110; - small[175] = 0b10101111; - small[176] = 0b10110000; - small[177] = 0b10110001; - small[178] = 0b10110010; - small[179] = 0b10110011; - small[180] = 0b10110100; - small[181] = 0b10110101; - small[182] = 0b10110110; - small[183] = 0b10110111; - small[184] = 0b10111000; - small[185] = 0b10111001; - small[186] = 0b10111010; - small[187] = 0b10111011; - small[188] = 0b10111100; - small[189] = 0b10111101; - small[190] = 0b10111110; - small[191] = 0b10111111; - small[192] = 0b11000000; - small[193] = 0b11000001; - small[194] = 0b11000010; - small[195] = 0b11000011; - small[196] = 0b11000100; - small[197] = 0b11000101; - small[198] = 0b11000110; - small[199] = 0b11000111; - small[200] = 0b11001000; - small[201] = 0b11001001; - small[202] = 0b11001010; - small[203] = 0b11001011; - small[204] = 0b11001100; - small[205] = 0b11001101; - small[206] = 0b11001110; - small[207] = 0b11001111; - small[208] = 0b11010000; - small[209] = 0b11010001; - small[210] = 0b11010010; - small[211] = 0b11010011; - small[212] = 0b11010100; - small[213] = 0b11010101; - small[214] = 0b11010110; - small[215] = 0b11010111; - small[216] = 0b11011000; - small[217] = 0b11011001; - small[218] = 0b11011010; - small[219] = 0b11011011; - small[220] = 0b11011100; - small[221] = 0b11011101; - small[222] = 0b11011110; - small[223] = 0b11011111; - small[224] = 0b11100000; - small[225] = 0b11100001; - small[226] = 0b11100010; - small[227] = 0b11100011; - small[228] = 0b11100100; - small[229] = 0b11100101; - small[230] = 0b11100110; - small[231] = 0b11100111; - small[232] = 0b11101000; - small[233] = 0b11101001; - small[234] = 0b11101010; - small[235] = 0b11101011; - small[236] = 0b11101100; - small[237] = 0b11101101; - small[238] = 0b11101110; - small[239] = 0b11101111; - small[240] = 0b11110000; - small[241] = 0b11110001; - small[242] = 0b11110010; - small[243] = 0b11110011; - small[244] = 0b11110100; - small[245] = 0b11110101; - small[246] = 0b11110110; - small[247] = 0b11110111; - small[248] = 0b11111000; - small[249] = 0b11111001; - small[250] = 0b11111010; - small[251] = 0b11111011; - small[252] = 0b11111100; - small[253] = 0b11111101; - small[254] = 0b11111110; - small[255] = 0b11111111; + small[0] = 0b0; + small[1] = 0b1; + small[2] = 0b10; + small[3] = 0b11; + small[4] = 0b100; + small[5] = 0b101; + small[6] = 0b110; + small[7] = 0b000111; + small[8] = 0b1000; + small[9] = 0b1001; + small[10] = 0b0001010; + small[11] = 0b0001011; + small[12] = 0b1100; + small[13] = 0b1101; + small[14] = 0b1110; + small[15] = 0b1111; + small[16] = 0b10000; + small[17] = 0b10001; + small[18] = 0b00010010; + small[19] = 0b00010011; + small[20] = 0b00010100; + small[21] = 0b00010101; + small[22] = 0b10110; + small[23] = 0b10111; + small[24] = 0b11000; + small[25] = 0b11001; + small[26] = 0b11010; + small[27] = 0b11011; + small[28] = 0b11100; + small[29] = 0b11101; + small[30] = 0b11110; + small[31] = 0b11111; + small[32] = 0b00000000100000; + small[33] = 0b00000000100001; + small[34] = 0b100010; + small[35] = 0b100011; + small[36] = 0b100100; + small[37] = 0b100101; + small[38] = 0b100110; + small[39] = 0b100111; + small[40] = 0b101000; + small[41] = 0b101001; + small[42] = 0b101010; + small[43] = 0b101011; + small[44] = 0b101100; + small[45] = 0b101101; + small[46] = 0b101110; + small[47] = 0b101111; + small[48] = 0b110000; + small[49] = 0b110001; + small[50] = 0b110010; + small[51] = 0b110011; + small[52] = 0b110100; + small[53] = 0b110101; + small[54] = 0b110110; + small[55] = 0b110111; + small[56] = 0b111000; + small[57] = 0b111001; + small[58] = 0b111010; + small[59] = 0b111011; + small[60] = 0b111100; + small[61] = 0b111101; + small[62] = 0b111110; + small[63] = 0b111111; + small[64] = 0b1000000; + small[65] = 0b1000001; + small[66] = 0b1000010; + small[67] = 0b1000011; + small[68] = 0b1000100; + small[69] = 0b1000101; + small[70] = 0b1000110; + small[71] = 0b1000111; + small[72] = 0b1001000; + small[73] = 0b1001001; + small[74] = 0b1001010; + small[75] = 0b1001011; + small[76] = 0b1001100; + small[77] = 0b1001101; + small[78] = 0b1001110; + small[79] = 0b1001111; + small[80] = 0b1010000; + small[81] = 0b1010001; + small[82] = 0b1010010; + small[83] = 0b1010011; + small[84] = 0b1010100; + small[85] = 0b1010101; + small[86] = 0b1010110; + small[87] = 0b1010111; + small[88] = 0b1011000; + small[89] = 0b1011001; + small[90] = 0b1011010; + small[91] = 0b1011011; + small[92] = 0b1011100; + small[93] = 0b1011101; + small[94] = 0b1011110; + small[95] = 0b1011111; + small[96] = 0b1100000; + small[97] = 0b1100001; + small[98] = 0b1100010; + small[99] = 0b1100011; + small[100] = 0b1100100; + small[101] = 0b1100101; + small[102] = 0b1100110; + small[103] = 0b1100111; + small[104] = 0b1101000; + small[105] = 0b1101001; + small[106] = 0b1101010; + small[107] = 0b1101011; + small[108] = 0b1101100; + small[109] = 0b1101101; + small[110] = 0b1101110; + small[111] = 0b1101111; + small[112] = 0b1110000; + small[113] = 0b1110001; + small[114] = 0b1110010; + small[115] = 0b1110011; + small[116] = 0b1110100; + small[117] = 0b1110101; + small[118] = 0b1110110; + small[119] = 0b1110111; + small[120] = 0b1111000; + small[121] = 0b1111001; + small[122] = 0b1111010; + small[123] = 0b1111011; + small[124] = 0b1111100; + small[125] = 0b1111101; + small[126] = 0b1111110; + small[127] = 0b1111111; + small[128] = 0b10000000; + small[129] = 0b10000001; + small[130] = 0b10000010; + small[131] = 0b10000011; + small[132] = 0b10000100; + small[133] = 0b10000101; + small[134] = 0b10000110; + small[135] = 0b10000111; + small[136] = 0b10001000; + small[137] = 0b10001001; + small[138] = 0b10001010; + small[139] = 0b10001011; + small[140] = 0b10001100; + small[141] = 0b10001101; + small[142] = 0b10001110; + small[143] = 0b10001111; + small[144] = 0b10010000; + small[145] = 0b10010001; + small[146] = 0b10010010; + small[147] = 0b10010011; + small[148] = 0b10010100; + small[149] = 0b10010101; + small[150] = 0b10010110; + small[151] = 0b10010111; + small[152] = 0b10011000; + small[153] = 0b10011001; + small[154] = 0b10011010; + small[155] = 0b10011011; + small[156] = 0b10011100; + small[157] = 0b10011101; + small[158] = 0b10011110; + small[159] = 0b10011111; + small[160] = 0b10100000; + small[161] = 0b10100001; + small[162] = 0b10100010; + small[163] = 0b10100011; + small[164] = 0b10100100; + small[165] = 0b10100101; + small[166] = 0b10100110; + small[167] = 0b10100111; + small[168] = 0b10101000; + small[169] = 0b10101001; + small[170] = 0b10101010; + small[171] = 0b10101011; + small[172] = 0b10101100; + small[173] = 0b10101101; + small[174] = 0b10101110; + small[175] = 0b10101111; + small[176] = 0b10110000; + small[177] = 0b10110001; + small[178] = 0b10110010; + small[179] = 0b10110011; + small[180] = 0b10110100; + small[181] = 0b10110101; + small[182] = 0b10110110; + small[183] = 0b10110111; + small[184] = 0b10111000; + small[185] = 0b10111001; + small[186] = 0b10111010; + small[187] = 0b10111011; + small[188] = 0b10111100; + small[189] = 0b10111101; + small[190] = 0b10111110; + small[191] = 0b10111111; + small[192] = 0b11000000; + small[193] = 0b11000001; + small[194] = 0b11000010; + small[195] = 0b11000011; + small[196] = 0b11000100; + small[197] = 0b11000101; + small[198] = 0b11000110; + small[199] = 0b11000111; + small[200] = 0b11001000; + small[201] = 0b11001001; + small[202] = 0b11001010; + small[203] = 0b11001011; + small[204] = 0b11001100; + small[205] = 0b11001101; + small[206] = 0b11001110; + small[207] = 0b11001111; + small[208] = 0b11010000; + small[209] = 0b11010001; + small[210] = 0b11010010; + small[211] = 0b11010011; + small[212] = 0b11010100; + small[213] = 0b11010101; + small[214] = 0b11010110; + small[215] = 0b11010111; + small[216] = 0b11011000; + small[217] = 0b11011001; + small[218] = 0b11011010; + small[219] = 0b11011011; + small[220] = 0b11011100; + small[221] = 0b11011101; + small[222] = 0b11011110; + small[223] = 0b11011111; + small[224] = 0b11100000; + small[225] = 0b11100001; + small[226] = 0b11100010; + small[227] = 0b11100011; + small[228] = 0b11100100; + small[229] = 0b11100101; + small[230] = 0b11100110; + small[231] = 0b11100111; + small[232] = 0b11101000; + small[233] = 0b11101001; + small[234] = 0b11101010; + small[235] = 0b11101011; + small[236] = 0b11101100; + small[237] = 0b11101101; + small[238] = 0b11101110; + small[239] = 0b11101111; + small[240] = 0b11110000; + small[241] = 0b11110001; + small[242] = 0b11110010; + small[243] = 0b11110011; + small[244] = 0b11110100; + small[245] = 0b11110101; + small[246] = 0b11110110; + small[247] = 0b11110111; + small[248] = 0b11111000; + small[249] = 0b11111001; + small[250] = 0b11111010; + small[251] = 0b11111011; + small[252] = 0b11111100; + small[253] = 0b11111101; + small[254] = 0b11111110; + small[255] = 0b11111111; - for (i = 0; i < 256; i++) { - if (small[i] != i) - return 1; - } + for (i = 0; i < 256; i++) { + if (small[i] != i) + return 1; + } - big[0] = 0b1111111100000000; - big[1] = 0b1111111100000001; - big[2] = 0b1111111100000010; - big[3] = 0b1111111100000011; - big[4] = 0b1111111100000100; - big[5] = 0b1111111100000101; - big[6] = 0b1111111100000110; - big[7] = 0b1111111100000111; - big[8] = 0b1111111100001000; - big[9] = 0b1111111100001001; - big[10] = 0b1111111100001010; - big[11] = 0b1111111100001011; - big[12] = 0b1111111100001100; - big[13] = 0b1111111100001101; - big[14] = 0b1111111100001110; - big[15] = 0b1111111100001111; - big[16] = 0b1111111100010000; - big[17] = 0b1111111100010001; - big[18] = 0b1111111100010010; - big[19] = 0b1111111100010011; - big[20] = 0b1111111100010100; - big[21] = 0b1111111100010101; - big[22] = 0b1111111100010110; - big[23] = 0b1111111100010111; - big[24] = 0b1111111100011000; - big[25] = 0b1111111100011001; - big[26] = 0b1111111100011010; - big[27] = 0b1111111100011011; - big[28] = 0b1111111100011100; - big[29] = 0b1111111100011101; - big[30] = 0b1111111100011110; - big[31] = 0b1111111100011111; - big[32] = 0b1111111100100000; - big[33] = 0b1111111100100001; - big[34] = 0b1111111100100010; - big[35] = 0b1111111100100011; - big[36] = 0b1111111100100100; - big[37] = 0b1111111100100101; - big[38] = 0b1111111100100110; - big[39] = 0b1111111100100111; - big[40] = 0b1111111100101000; - big[41] = 0b1111111100101001; - big[42] = 0b1111111100101010; - big[43] = 0b1111111100101011; - big[44] = 0b1111111100101100; - big[45] = 0b1111111100101101; - big[46] = 0b1111111100101110; - big[47] = 0b1111111100101111; - big[48] = 0b1111111100110000; - big[49] = 0b1111111100110001; - big[50] = 0b1111111100110010; - big[51] = 0b1111111100110011; - big[52] = 0b1111111100110100; - big[53] = 0b1111111100110101; - big[54] = 0b1111111100110110; - big[55] = 0b1111111100110111; - big[56] = 0b1111111100111000; - big[57] = 0b1111111100111001; - big[58] = 0b1111111100111010; - big[59] = 0b1111111100111011; - big[60] = 0b1111111100111100; - big[61] = 0b1111111100111101; - big[62] = 0b1111111100111110; - big[63] = 0b1111111100111111; - big[64] = 0b1111111101000000; - big[65] = 0b1111111101000001; - big[66] = 0b1111111101000010; - big[67] = 0b1111111101000011; - big[68] = 0b1111111101000100; - big[69] = 0b1111111101000101; - big[70] = 0b1111111101000110; - big[71] = 0b1111111101000111; - big[72] = 0b1111111101001000; - big[73] = 0b1111111101001001; - big[74] = 0b1111111101001010; - big[75] = 0b1111111101001011; - big[76] = 0b1111111101001100; - big[77] = 0b1111111101001101; - big[78] = 0b1111111101001110; - big[79] = 0b1111111101001111; - big[80] = 0b1111111101010000; - big[81] = 0b1111111101010001; - big[82] = 0b1111111101010010; - big[83] = 0b1111111101010011; - big[84] = 0b1111111101010100; - big[85] = 0b1111111101010101; - big[86] = 0b1111111101010110; - big[87] = 0b1111111101010111; - big[88] = 0b1111111101011000; - big[89] = 0b1111111101011001; - big[90] = 0b1111111101011010; - big[91] = 0b1111111101011011; - big[92] = 0b1111111101011100; - big[93] = 0b1111111101011101; - big[94] = 0b1111111101011110; - big[95] = 0b1111111101011111; - big[96] = 0b1111111101100000; - big[97] = 0b1111111101100001; - big[98] = 0b1111111101100010; - big[99] = 0b1111111101100011; - big[100] = 0b1111111101100100; - big[101] = 0b1111111101100101; - big[102] = 0b1111111101100110; - big[103] = 0b1111111101100111; - big[104] = 0b1111111101101000; - big[105] = 0b1111111101101001; - big[106] = 0b1111111101101010; - big[107] = 0b1111111101101011; - big[108] = 0b1111111101101100; - big[109] = 0b1111111101101101; - big[110] = 0b1111111101101110; - big[111] = 0b1111111101101111; - big[112] = 0b1111111101110000; - big[113] = 0b1111111101110001; - big[114] = 0b1111111101110010; - big[115] = 0b1111111101110011; - big[116] = 0b1111111101110100; - big[117] = 0b1111111101110101; - big[118] = 0b1111111101110110; - big[119] = 0b1111111101110111; - big[120] = 0b1111111101111000; - big[121] = 0b1111111101111001; - big[122] = 0b1111111101111010; - big[123] = 0b1111111101111011; - big[124] = 0b1111111101111100; - big[125] = 0b1111111101111101; - big[126] = 0b1111111101111110; - big[127] = 0b1111111101111111; - big[128] = 0b1111111110000000; - big[129] = 0b1111111110000001; - big[130] = 0b1111111110000010; - big[131] = 0b1111111110000011; - big[132] = 0b1111111110000100; - big[133] = 0b1111111110000101; - big[134] = 0b1111111110000110; - big[135] = 0b1111111110000111; - big[136] = 0b1111111110001000; - big[137] = 0b1111111110001001; - big[138] = 0b1111111110001010; - big[139] = 0b1111111110001011; - big[140] = 0b1111111110001100; - big[141] = 0b1111111110001101; - big[142] = 0b1111111110001110; - big[143] = 0b1111111110001111; - big[144] = 0b1111111110010000; - big[145] = 0b1111111110010001; - big[146] = 0b1111111110010010; - big[147] = 0b1111111110010011; - big[148] = 0b1111111110010100; - big[149] = 0b1111111110010101; - big[150] = 0b1111111110010110; - big[151] = 0b1111111110010111; - big[152] = 0b1111111110011000; - big[153] = 0b1111111110011001; - big[154] = 0b1111111110011010; - big[155] = 0b1111111110011011; - big[156] = 0b1111111110011100; - big[157] = 0b1111111110011101; - big[158] = 0b1111111110011110; - big[159] = 0b1111111110011111; - big[160] = 0b1111111110100000; - big[161] = 0b1111111110100001; - big[162] = 0b1111111110100010; - big[163] = 0b1111111110100011; - big[164] = 0b1111111110100100; - big[165] = 0b1111111110100101; - big[166] = 0b1111111110100110; - big[167] = 0b1111111110100111; - big[168] = 0b1111111110101000; - big[169] = 0b1111111110101001; - big[170] = 0b1111111110101010; - big[171] = 0b1111111110101011; - big[172] = 0b1111111110101100; - big[173] = 0b1111111110101101; - big[174] = 0b1111111110101110; - big[175] = 0b1111111110101111; - big[176] = 0b1111111110110000; - big[177] = 0b1111111110110001; - big[178] = 0b1111111110110010; - big[179] = 0b1111111110110011; - big[180] = 0b1111111110110100; - big[181] = 0b1111111110110101; - big[182] = 0b1111111110110110; - big[183] = 0b1111111110110111; - big[184] = 0b1111111110111000; - big[185] = 0b1111111110111001; - big[186] = 0b1111111110111010; - big[187] = 0b1111111110111011; - big[188] = 0b1111111110111100; - big[189] = 0b1111111110111101; - big[190] = 0b1111111110111110; - big[191] = 0b1111111110111111; - big[192] = 0b1111111111000000; - big[193] = 0b1111111111000001; - big[194] = 0b1111111111000010; - big[195] = 0b1111111111000011; - big[196] = 0b1111111111000100; - big[197] = 0b1111111111000101; - big[198] = 0b1111111111000110; - big[199] = 0b1111111111000111; - big[200] = 0b1111111111001000; - big[201] = 0b1111111111001001; - big[202] = 0b1111111111001010; - big[203] = 0b1111111111001011; - big[204] = 0b1111111111001100; - big[205] = 0b1111111111001101; - big[206] = 0b1111111111001110; - big[207] = 0b1111111111001111; - big[208] = 0b1111111111010000; - big[209] = 0b1111111111010001; - big[210] = 0b1111111111010010; - big[211] = 0b1111111111010011; - big[212] = 0b1111111111010100; - big[213] = 0b1111111111010101; - big[214] = 0b1111111111010110; - big[215] = 0b1111111111010111; - big[216] = 0b1111111111011000; - big[217] = 0b1111111111011001; - big[218] = 0b1111111111011010; - big[219] = 0b1111111111011011; - big[220] = 0b1111111111011100; - big[221] = 0b1111111111011101; - big[222] = 0b1111111111011110; - big[223] = 0b1111111111011111; - big[224] = 0b1111111111100000; - big[225] = 0b1111111111100001; - big[226] = 0b1111111111100010; - big[227] = 0b1111111111100011; - big[228] = 0b1111111111100100; - big[229] = 0b1111111111100101; - big[230] = 0b1111111111100110; - big[231] = 0b1111111111100111; - big[232] = 0b1111111111101000; - big[233] = 0b1111111111101001; - big[234] = 0b1111111111101010; - big[235] = 0b1111111111101011; - big[236] = 0b1111111111101100; - big[237] = 0b1111111111101101; - big[238] = 0b1111111111101110; - big[239] = 0b1111111111101111; - big[240] = 0b1111111111110000; - big[241] = 0b1111111111110001; - big[242] = 0b1111111111110010; - big[243] = 0b1111111111110011; - big[244] = 0b1111111111110100; - big[245] = 0b1111111111110101; - big[246] = 0b1111111111110110; - big[247] = 0b1111111111110111; - big[248] = 0b1111111111111000; - big[249] = 0b1111111111111001; - big[250] = 0b1111111111111010; - big[251] = 0b1111111111111011; - big[252] = 0b1111111111111100; - big[253] = 0b1111111111111101; - big[254] = 0b1111111111111110; - big[255] = 0b1111111111111111; + big[0] = 0b1111111100000000; + big[1] = 0b1111111100000001; + big[2] = 0b1111111100000010; + big[3] = 0b1111111100000011; + big[4] = 0b1111111100000100; + big[5] = 0b1111111100000101; + big[6] = 0b1111111100000110; + big[7] = 0b1111111100000111; + big[8] = 0b1111111100001000; + big[9] = 0b1111111100001001; + big[10] = 0b1111111100001010; + big[11] = 0b1111111100001011; + big[12] = 0b1111111100001100; + big[13] = 0b1111111100001101; + big[14] = 0b1111111100001110; + big[15] = 0b1111111100001111; + big[16] = 0b1111111100010000; + big[17] = 0b1111111100010001; + big[18] = 0b1111111100010010; + big[19] = 0b1111111100010011; + big[20] = 0b1111111100010100; + big[21] = 0b1111111100010101; + big[22] = 0b1111111100010110; + big[23] = 0b1111111100010111; + big[24] = 0b1111111100011000; + big[25] = 0b1111111100011001; + big[26] = 0b1111111100011010; + big[27] = 0b1111111100011011; + big[28] = 0b1111111100011100; + big[29] = 0b1111111100011101; + big[30] = 0b1111111100011110; + big[31] = 0b1111111100011111; + big[32] = 0b1111111100100000; + big[33] = 0b1111111100100001; + big[34] = 0b1111111100100010; + big[35] = 0b1111111100100011; + big[36] = 0b1111111100100100; + big[37] = 0b1111111100100101; + big[38] = 0b1111111100100110; + big[39] = 0b1111111100100111; + big[40] = 0b1111111100101000; + big[41] = 0b1111111100101001; + big[42] = 0b1111111100101010; + big[43] = 0b1111111100101011; + big[44] = 0b1111111100101100; + big[45] = 0b1111111100101101; + big[46] = 0b1111111100101110; + big[47] = 0b1111111100101111; + big[48] = 0b1111111100110000; + big[49] = 0b1111111100110001; + big[50] = 0b1111111100110010; + big[51] = 0b1111111100110011; + big[52] = 0b1111111100110100; + big[53] = 0b1111111100110101; + big[54] = 0b1111111100110110; + big[55] = 0b1111111100110111; + big[56] = 0b1111111100111000; + big[57] = 0b1111111100111001; + big[58] = 0b1111111100111010; + big[59] = 0b1111111100111011; + big[60] = 0b1111111100111100; + big[61] = 0b1111111100111101; + big[62] = 0b1111111100111110; + big[63] = 0b1111111100111111; + big[64] = 0b1111111101000000; + big[65] = 0b1111111101000001; + big[66] = 0b1111111101000010; + big[67] = 0b1111111101000011; + big[68] = 0b1111111101000100; + big[69] = 0b1111111101000101; + big[70] = 0b1111111101000110; + big[71] = 0b1111111101000111; + big[72] = 0b1111111101001000; + big[73] = 0b1111111101001001; + big[74] = 0b1111111101001010; + big[75] = 0b1111111101001011; + big[76] = 0b1111111101001100; + big[77] = 0b1111111101001101; + big[78] = 0b1111111101001110; + big[79] = 0b1111111101001111; + big[80] = 0b1111111101010000; + big[81] = 0b1111111101010001; + big[82] = 0b1111111101010010; + big[83] = 0b1111111101010011; + big[84] = 0b1111111101010100; + big[85] = 0b1111111101010101; + big[86] = 0b1111111101010110; + big[87] = 0b1111111101010111; + big[88] = 0b1111111101011000; + big[89] = 0b1111111101011001; + big[90] = 0b1111111101011010; + big[91] = 0b1111111101011011; + big[92] = 0b1111111101011100; + big[93] = 0b1111111101011101; + big[94] = 0b1111111101011110; + big[95] = 0b1111111101011111; + big[96] = 0b1111111101100000; + big[97] = 0b1111111101100001; + big[98] = 0b1111111101100010; + big[99] = 0b1111111101100011; + big[100] = 0b1111111101100100; + big[101] = 0b1111111101100101; + big[102] = 0b1111111101100110; + big[103] = 0b1111111101100111; + big[104] = 0b1111111101101000; + big[105] = 0b1111111101101001; + big[106] = 0b1111111101101010; + big[107] = 0b1111111101101011; + big[108] = 0b1111111101101100; + big[109] = 0b1111111101101101; + big[110] = 0b1111111101101110; + big[111] = 0b1111111101101111; + big[112] = 0b1111111101110000; + big[113] = 0b1111111101110001; + big[114] = 0b1111111101110010; + big[115] = 0b1111111101110011; + big[116] = 0b1111111101110100; + big[117] = 0b1111111101110101; + big[118] = 0b1111111101110110; + big[119] = 0b1111111101110111; + big[120] = 0b1111111101111000; + big[121] = 0b1111111101111001; + big[122] = 0b1111111101111010; + big[123] = 0b1111111101111011; + big[124] = 0b1111111101111100; + big[125] = 0b1111111101111101; + big[126] = 0b1111111101111110; + big[127] = 0b1111111101111111; + big[128] = 0b1111111110000000; + big[129] = 0b1111111110000001; + big[130] = 0b1111111110000010; + big[131] = 0b1111111110000011; + big[132] = 0b1111111110000100; + big[133] = 0b1111111110000101; + big[134] = 0b1111111110000110; + big[135] = 0b1111111110000111; + big[136] = 0b1111111110001000; + big[137] = 0b1111111110001001; + big[138] = 0b1111111110001010; + big[139] = 0b1111111110001011; + big[140] = 0b1111111110001100; + big[141] = 0b1111111110001101; + big[142] = 0b1111111110001110; + big[143] = 0b1111111110001111; + big[144] = 0b1111111110010000; + big[145] = 0b1111111110010001; + big[146] = 0b1111111110010010; + big[147] = 0b1111111110010011; + big[148] = 0b1111111110010100; + big[149] = 0b1111111110010101; + big[150] = 0b1111111110010110; + big[151] = 0b1111111110010111; + big[152] = 0b1111111110011000; + big[153] = 0b1111111110011001; + big[154] = 0b1111111110011010; + big[155] = 0b1111111110011011; + big[156] = 0b1111111110011100; + big[157] = 0b1111111110011101; + big[158] = 0b1111111110011110; + big[159] = 0b1111111110011111; + big[160] = 0b1111111110100000; + big[161] = 0b1111111110100001; + big[162] = 0b1111111110100010; + big[163] = 0b1111111110100011; + big[164] = 0b1111111110100100; + big[165] = 0b1111111110100101; + big[166] = 0b1111111110100110; + big[167] = 0b1111111110100111; + big[168] = 0b1111111110101000; + big[169] = 0b1111111110101001; + big[170] = 0b1111111110101010; + big[171] = 0b1111111110101011; + big[172] = 0b1111111110101100; + big[173] = 0b1111111110101101; + big[174] = 0b1111111110101110; + big[175] = 0b1111111110101111; + big[176] = 0b1111111110110000; + big[177] = 0b1111111110110001; + big[178] = 0b1111111110110010; + big[179] = 0b1111111110110011; + big[180] = 0b1111111110110100; + big[181] = 0b1111111110110101; + big[182] = 0b1111111110110110; + big[183] = 0b1111111110110111; + big[184] = 0b1111111110111000; + big[185] = 0b1111111110111001; + big[186] = 0b1111111110111010; + big[187] = 0b1111111110111011; + big[188] = 0b1111111110111100; + big[189] = 0b1111111110111101; + big[190] = 0b1111111110111110; + big[191] = 0b1111111110111111; + big[192] = 0b1111111111000000; + big[193] = 0b1111111111000001; + big[194] = 0b1111111111000010; + big[195] = 0b1111111111000011; + big[196] = 0b1111111111000100; + big[197] = 0b1111111111000101; + big[198] = 0b1111111111000110; + big[199] = 0b1111111111000111; + big[200] = 0b1111111111001000; + big[201] = 0b1111111111001001; + big[202] = 0b1111111111001010; + big[203] = 0b1111111111001011; + big[204] = 0b1111111111001100; + big[205] = 0b1111111111001101; + big[206] = 0b1111111111001110; + big[207] = 0b1111111111001111; + big[208] = 0b1111111111010000; + big[209] = 0b1111111111010001; + big[210] = 0b1111111111010010; + big[211] = 0b1111111111010011; + big[212] = 0b1111111111010100; + big[213] = 0b1111111111010101; + big[214] = 0b1111111111010110; + big[215] = 0b1111111111010111; + big[216] = 0b1111111111011000; + big[217] = 0b1111111111011001; + big[218] = 0b1111111111011010; + big[219] = 0b1111111111011011; + big[220] = 0b1111111111011100; + big[221] = 0b1111111111011101; + big[222] = 0b1111111111011110; + big[223] = 0b1111111111011111; + big[224] = 0b1111111111100000; + big[225] = 0b1111111111100001; + big[226] = 0b1111111111100010; + big[227] = 0b1111111111100011; + big[228] = 0b1111111111100100; + big[229] = 0b1111111111100101; + big[230] = 0b1111111111100110; + big[231] = 0b1111111111100111; + big[232] = 0b1111111111101000; + big[233] = 0b1111111111101001; + big[234] = 0b1111111111101010; + big[235] = 0b1111111111101011; + big[236] = 0b1111111111101100; + big[237] = 0b1111111111101101; + big[238] = 0b1111111111101110; + big[239] = 0b1111111111101111; + big[240] = 0b1111111111110000; + big[241] = 0b1111111111110001; + big[242] = 0b1111111111110010; + big[243] = 0b1111111111110011; + big[244] = 0b1111111111110100; + big[245] = 0b1111111111110101; + big[246] = 0b1111111111110110; + big[247] = 0b1111111111110111; + big[248] = 0b1111111111111000; + big[249] = 0b1111111111111001; + big[250] = 0b1111111111111010; + big[251] = 0b1111111111111011; + big[252] = 0b1111111111111100; + big[253] = 0b1111111111111101; + big[254] = 0b1111111111111110; + big[255] = 0b1111111111111111; - for (i = 0; i < 256; i++) { - if (big[i] != i + 65280U) - return 1; - } + for (i = 0; i < 256; i++) { + if (big[i] != i + 65280U) + return 1; + } - return 0; + return 0; } diff --git a/test/val/bug1071.c b/test/val/bug1071.c index 02b069de0..66e298b25 100644 --- a/test/val/bug1071.c +++ b/test/val/bug1071.c @@ -7,24 +7,24 @@ struct ImageStruct { - uint8_t _imageData; - #if !defined(NO_COLOR) - uint8_t _color; - #endif + uint8_t _imageData; + #if !defined(NO_COLOR) + uint8_t _color; + #endif }; typedef struct ImageStruct Image; struct CharacterStruct { - // character coordinates - uint8_t _x; - uint8_t _y; + // character coordinates + uint8_t _x; + uint8_t _y; - // _status decides whether the character is active - uint8_t _status; + // _status decides whether the character is active + uint8_t _status; - Image* _imagePtr; + Image* _imagePtr; }; typedef struct CharacterStruct Character; @@ -53,20 +53,20 @@ Character bombs[BOMBS_NUMBER]; uint16_t test1(void) { - if((loop<MAX_GHOST_LOOP) && (ghostLevel<MAX_GHOST_LEVEL)) - { - return INITIAL_GHOST_SLOWDOWN-(uint16_t)level*256-ghostLevel*8; - } - return GHOST_MIN_SLOWDOWN; + if((loop<MAX_GHOST_LOOP) && (ghostLevel<MAX_GHOST_LEVEL)) + { + return INITIAL_GHOST_SLOWDOWN-(uint16_t)level*256-ghostLevel*8; + } + return GHOST_MIN_SLOWDOWN; } uint16_t test2(void) { - if((loop<MAX_GHOST_LOOP) && (ghostLevel<MAX_GHOST_LEVEL)) - { - return INITIAL_GHOST_SLOWDOWN-(uint16_t)level*256-ghostLevel*16; - } - return GHOST_MIN_SLOWDOWN; + if((loop<MAX_GHOST_LOOP) && (ghostLevel<MAX_GHOST_LEVEL)) + { + return INITIAL_GHOST_SLOWDOWN-(uint16_t)level*256-ghostLevel*16; + } + return GHOST_MIN_SLOWDOWN; } uint16_t res = 0; diff --git a/test/val/rand.c b/test/val/rand.c index f2f604449..ac2ab0d17 100644 --- a/test/val/rand.c +++ b/test/val/rand.c @@ -28,83 +28,83 @@ static uint32_t seed; int ref_rand() { - uint16_t output; - /* seed follows the LCG sequence * 0x01010101 + 0xB3B3B3B3 */ - seed = seed * 0x01010101UL + 0xB3B3B3B3UL; - /* output uses the top two bytes (reversed) XOR with bottom two bytes */ - { - uint16_t s0 = (seed >> 0) & 0xFF; - uint16_t s1 = (seed >> 8) & 0xFF; - uint16_t s2 = (seed >> 16) & 0xFF; - uint16_t s3 = (seed >> 24) & 0xFF; - uint16_t o0 = s3 ^ s1; - uint16_t o1 = s2 ^ s0; - output = o0 | (o1 << 8); - } - return (int)(output & 0x7FFF); + uint16_t output; + /* seed follows the LCG sequence * 0x01010101 + 0xB3B3B3B3 */ + seed = seed * 0x01010101UL + 0xB3B3B3B3UL; + /* output uses the top two bytes (reversed) XOR with bottom two bytes */ + { + uint16_t s0 = (seed >> 0) & 0xFF; + uint16_t s1 = (seed >> 8) & 0xFF; + uint16_t s2 = (seed >> 16) & 0xFF; + uint16_t s3 = (seed >> 24) & 0xFF; + uint16_t o0 = s3 ^ s1; + uint16_t o1 = s2 ^ s0; + output = o0 | (o1 << 8); + } + return (int)(output & 0x7FFF); } void ref_srand(int ax) { - uint32_t s = (unsigned int)ax; - seed = s | (s << 16); /* low 16 bits is convenient filler for high 16 bits */ - ref_rand(); /* one pre-call "shuffles" the first rand() result so it isn't too predictable */ + uint32_t s = (unsigned int)ax; + seed = s | (s << 16); /* low 16 bits is convenient filler for high 16 bits */ + ref_rand(); /* one pre-call "shuffles" the first rand() result so it isn't too predictable */ } int main(void) { - unsigned int i,j; - int a,b; + unsigned int i,j; + int a,b; - /* test that startup state is equivalent to srand(1) */ - { - //srand(1); // implied - ref_srand(1); - for (j=0; j<SUBTESTS; ++j) - { - a = rand(); - b = ref_rand(); - if (a != b) - { - printf("failed startup seed at test %d. rand()=%d reference=%d\n",j,a,b); - return EXIT_FAILURE; - } - } - } + /* test that startup state is equivalent to srand(1) */ + { + //srand(1); // implied + ref_srand(1); + for (j=0; j<SUBTESTS; ++j) + { + a = rand(); + b = ref_rand(); + if (a != b) + { + printf("failed startup seed at test %d. rand()=%d reference=%d\n",j,a,b); + return EXIT_FAILURE; + } + } + } - /* test every power of 2 seed */ - for (i = 0; i < 16; ++i) - { - srand(1<<i); - ref_srand(1<<i); - for (j=0; j<SUBTESTS; ++j) - { - a = rand(); - b = ref_rand(); - if (a != b) - { - printf("failed seed %d at test %d. rand()=%d reference=%d\n",(1<<i),j,a,b); - return EXIT_FAILURE; - } - } - } + /* test every power of 2 seed */ + for (i = 0; i < 16; ++i) + { + srand(1<<i); + ref_srand(1<<i); + for (j=0; j<SUBTESTS; ++j) + { + a = rand(); + b = ref_rand(); + if (a != b) + { + printf("failed seed %d at test %d. rand()=%d reference=%d\n",(1<<i),j,a,b); + return EXIT_FAILURE; + } + } + } - /* test a sampling of seeds*/ - for (i = 0; i < 32768UL; i += TESTINC) - { - srand(i); - ref_srand(i); - for (j=0; j<SUBTESTS; ++j) - { - a = rand(); - b = ref_rand(); - if (a != b) - { - printf("failed seed %d at test %d. rand()=%d reference=%d\n",(1<<i),j,a,b); - return EXIT_FAILURE; - } - } - } + /* test a sampling of seeds*/ + for (i = 0; i < 32768UL; i += TESTINC) + { + srand(i); + ref_srand(i); + for (j=0; j<SUBTESTS; ++j) + { + a = rand(); + b = ref_rand(); + if (a != b) + { + printf("failed seed %d at test %d. rand()=%d reference=%d\n",(1<<i),j,a,b); + return EXIT_FAILURE; + } + } + } - return EXIT_SUCCESS; + return EXIT_SUCCESS; } From e0c12c90cd7b729d416f6dd76e1f9185a339b088 Mon Sep 17 00:00:00 2001 From: Jesse Rosenstock <jmr@google.com> Date: Sun, 15 Nov 2020 23:03:01 +0100 Subject: [PATCH 1839/2161] g_asr, g_asl: Use ROL/ROR for char shifts by >= 6 Instead of `val` right (left) shifts, we can also do `9 - val` left (right) rotates and a mask. This saves 3 bytes and 8 cycles for `val == 7` and 1 byte and 4 cycles for `val == 6`. --- src/cc65/codegen.c | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index a58484cf1..3ca9d81e6 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -3114,9 +3114,26 @@ void g_asr (unsigned flags, unsigned long val) switch (flags & CF_TYPEMASK) { case CF_CHAR: if (flags & CF_FORCECHAR) { - if ((flags & CF_UNSIGNED) != 0 && val < 8) { - while (val--) { - AddCodeLine ("lsr a"); + val &= 7; + if ((flags & CF_UNSIGNED) != 0) { + /* Instead of `val` right shifts, we can also do `9 - val` left rotates + ** and a mask. This saves 3 bytes and 8 cycles for `val == 7` and + ** 1 byte and 4 cycles for `val == 6`. + */ + if (val < 6) { + while (val--) { + AddCodeLine ("lsr a"); /* 1 byte, 2 cycles */ + } + } else { + unsigned i; + /* The first ROL shifts in garbage and sets carry to the high bit. + ** The garbage is cleaned up by the mask. + */ + for (i = val; i < 9; ++i) { + AddCodeLine ("rol a"); /* 1 byte, 2 cycles */ + } + /* 2 bytes, 2 cycles */ + AddCodeLine ("and #$%02X", 0xFF >> val); } return; } else if (val <= 2) { @@ -3270,9 +3287,21 @@ void g_asl (unsigned flags, unsigned long val) if (flags & CF_CONST) { switch (flags & CF_TYPEMASK) { case CF_CHAR: - if ((flags & CF_FORCECHAR) != 0 && val <= 6) { - while (val--) { - AddCodeLine ("asl a"); + if ((flags & CF_FORCECHAR) != 0) { + val &= 7; + /* Large shifts are faster and smaller with ROR. See g_asr for detailed + ** byte and cycle counts. + */ + if (val < 6) { + while (val--) { + AddCodeLine ("asl a"); + } + } else { + unsigned i; + for (i = val; i < 9; ++i) { + AddCodeLine ("ror a"); + } + AddCodeLine ("and #$%02X", (~0U << val) & 0xFF); } return; } From 39573109500d06b415026af2d07de4b3c8b52a47 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose <pixel@hugbox.org> Date: Sun, 25 Oct 2020 14:27:26 +0100 Subject: [PATCH 1840/2161] Knock off two bytes from getcwd(), cbm_read() and cbm_write(). --- libsrc/cbm/cbm_read.s | 14 +++++++------- libsrc/cbm/cbm_write.s | 14 +++++++------- libsrc/common/getcwd.s | 16 ++++++++-------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/libsrc/cbm/cbm_read.s b/libsrc/cbm/cbm_read.s index b010966a3..a30983302 100644 --- a/libsrc/cbm/cbm_read.s +++ b/libsrc/cbm/cbm_read.s @@ -45,11 +45,11 @@ _cbm_read: - eor #$FF - sta ptr1 - txa - eor #$FF - sta ptr1+1 ; Save -size-1 + inx + stx ptr1+1 + tax + inx + stx ptr1 ; Save size with each byte incremented. jsr popax sta ptr2 @@ -92,9 +92,9 @@ _cbm_read: bne @L3 inc ptr3+1 ; ++bytesread; -@L3: inc ptr1 +@L3: dec ptr1 bne @L1 - inc ptr1+1 + dec ptr1+1 bne @L1 @L4: jsr CLRCH diff --git a/libsrc/cbm/cbm_write.s b/libsrc/cbm/cbm_write.s index 2d932d04a..a199c1d90 100644 --- a/libsrc/cbm/cbm_write.s +++ b/libsrc/cbm/cbm_write.s @@ -39,11 +39,11 @@ _cbm_write: sta ptr3 stx ptr3+1 ; Save size - eor #$FF - sta ptr1 - txa - eor #$FF - sta ptr1+1 ; Save -size-1 + inx + stx ptr1+1 + tax + inx + stx ptr1 ; Save size with each byte incremented jsr popax sta ptr2 @@ -69,9 +69,9 @@ _cbm_write: @L2: jsr BSOUT ; cbm_k_bsout (A); -@L3: inc ptr1 ; --size; +@L3: dec ptr1 ; --size; bne @L1 - inc ptr1+1 + dec ptr1+1 bne @L1 jsr CLRCH diff --git a/libsrc/common/getcwd.s b/libsrc/common/getcwd.s index 22b6ceded..c0a1c3634 100644 --- a/libsrc/common/getcwd.s +++ b/libsrc/common/getcwd.s @@ -17,22 +17,22 @@ .proc _getcwd -; Remember -size-1 because this simplifies the following loop +; Remember size with each byte incremented because this simplifies the following loop - eor #$FF - sta ptr2 - txa - eor #$FF - sta ptr2+1 + inx + stx ptr2+1 + tax + inx + stx ptr2 jsr popptr1 ; Get buf to ptr1 ; Copy __cwd to the given buffer checking the length ; ldy #$00 is guaranteed by popptr1 -loop: inc ptr2 +loop: dec ptr2 bne @L1 - inc ptr2+1 + dec ptr2+1 beq overflow ; Copy one character, end the loop if the zero terminator is reached. We From 99c0815cdb6b55ee89a1945e58674a5eefbb8126 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose <pixel@hugbox.org> Date: Tue, 27 Oct 2020 06:08:04 +0100 Subject: [PATCH 1841/2161] Clear up comments a bit. --- libsrc/cbm/cbm_read.s | 2 +- libsrc/cbm/cbm_write.s | 2 +- libsrc/common/getcwd.s | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libsrc/cbm/cbm_read.s b/libsrc/cbm/cbm_read.s index a30983302..29e0e1f19 100644 --- a/libsrc/cbm/cbm_read.s +++ b/libsrc/cbm/cbm_read.s @@ -49,7 +49,7 @@ _cbm_read: stx ptr1+1 tax inx - stx ptr1 ; Save size with each byte incremented. + stx ptr1 ; Save size with both bytes incremented separately. jsr popax sta ptr2 diff --git a/libsrc/cbm/cbm_write.s b/libsrc/cbm/cbm_write.s index a199c1d90..5ac07209c 100644 --- a/libsrc/cbm/cbm_write.s +++ b/libsrc/cbm/cbm_write.s @@ -43,7 +43,7 @@ _cbm_write: stx ptr1+1 tax inx - stx ptr1 ; Save size with each byte incremented + stx ptr1 ; Save size with both bytes incremented separately jsr popax sta ptr2 diff --git a/libsrc/common/getcwd.s b/libsrc/common/getcwd.s index c0a1c3634..4bfc0a5b6 100644 --- a/libsrc/common/getcwd.s +++ b/libsrc/common/getcwd.s @@ -23,7 +23,7 @@ stx ptr2+1 tax inx - stx ptr2 + stx ptr2 ; Save size with each byte incremented separately jsr popptr1 ; Get buf to ptr1 From f59cb9af0660e5401f18fe9e86329b2d0fd6b739 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose <pixel@hugbox.org> Date: Sun, 1 Nov 2020 22:59:07 +0100 Subject: [PATCH 1842/2161] Use more compact loops. --- libsrc/atmos/read.s | 15 ++++++++------- libsrc/atmos/write.s | 14 +++++++------- libsrc/cbm/read.s | 4 ++-- libsrc/cbm/rwcommon.s | 10 +++++----- libsrc/cbm/write.s | 4 ++-- libsrc/common/memcmp.s | 15 +++++++-------- libsrc/common/strncat.s | 22 +++++++++++----------- libsrc/common/strncpy.s | 18 +++++++++--------- libsrc/common/strnicmp.s | 20 +++++++------------- libsrc/conio/vcprintf.s | 16 ++++++++-------- libsrc/geos-common/drivers/fio_module.s | 15 ++++++++------- libsrc/osic1p/bootstrap.s | 17 +++++++++-------- libsrc/telestrat/write.s | 14 +++++++------- 13 files changed, 90 insertions(+), 94 deletions(-) diff --git a/libsrc/atmos/read.s b/libsrc/atmos/read.s index 83aa8024e..3f22d8d0e 100644 --- a/libsrc/atmos/read.s +++ b/libsrc/atmos/read.s @@ -20,18 +20,19 @@ sta ptr3 stx ptr3+1 ; save count as result - eor #$FF - sta ptr2 - txa - eor #$FF - sta ptr2+1 ; Remember -count-1 + + inx + stx ptr2+1 + tax + inx + stx ptr2 ; save count with each byte incremented separately jsr popptr1 ; get buf jsr popax ; get fd and discard -L1: inc ptr2 +L1: dec ptr2 bnz L2 - inc ptr2+1 + dec ptr2+1 bze L9 ; no more room in buf ; If there are no more characters in BASIC's input buffer, then get a line from diff --git a/libsrc/atmos/write.s b/libsrc/atmos/write.s index 7865b5698..4a68994ec 100644 --- a/libsrc/atmos/write.s +++ b/libsrc/atmos/write.s @@ -17,17 +17,17 @@ sta ptr3 stx ptr3+1 ; save count as result - eor #$FF - sta ptr2 - txa - eor #$FF - sta ptr2+1 ; Remember -count-1 + inx + stx ptr2+1 + tax + inx + stx ptr2 ; save count with each byte incremented separately jsr popptr1 ; get buf jsr popax ; get fd and discard -L1: inc ptr2 +L1: dec ptr2 bne L2 - inc ptr2+1 + dec ptr2+1 beq L9 L2: ldy #0 lda (ptr1),y diff --git a/libsrc/cbm/read.s b/libsrc/cbm/read.s index ee01596aa..fb0bb3171 100644 --- a/libsrc/cbm/read.s +++ b/libsrc/cbm/read.s @@ -106,9 +106,9 @@ ; Decrement the count -@L3: inc ptr2 +@L3: dec ptr2 bne @L0 - inc ptr2+1 + dec ptr2+1 bne @L0 beq done ; Branch always diff --git a/libsrc/cbm/rwcommon.s b/libsrc/cbm/rwcommon.s index a1f92be8c..d13c478b5 100644 --- a/libsrc/cbm/rwcommon.s +++ b/libsrc/cbm/rwcommon.s @@ -21,11 +21,11 @@ .proc rwcommon - eor #$FF - sta ptr2 - txa - eor #$FF - sta ptr2+1 ; Remember -count-1 + inx + stx ptr2+1 + tax + inx + stx ptr2 ; Save count with each byte incremented separately jsr popptr1 ; Get buf to ptr1, Y=0 by call diff --git a/libsrc/cbm/write.s b/libsrc/cbm/write.s index 7a27f0044..ebc44a0ac 100644 --- a/libsrc/cbm/write.s +++ b/libsrc/cbm/write.s @@ -83,9 +83,9 @@ ; Decrement count -@L2: inc ptr2 +@L2: dec ptr2 bne @L0 - inc ptr2+1 + dec ptr2+1 bne @L0 ; Wrote all chars or disk full. Close the output channel diff --git a/libsrc/common/memcmp.s b/libsrc/common/memcmp.s index 93a2c28dc..5879a433d 100644 --- a/libsrc/common/memcmp.s +++ b/libsrc/common/memcmp.s @@ -13,11 +13,11 @@ _memcmp: ; Calculate (-count-1) and store it into ptr3. This is some overhead here but ; saves time in the compare loop - eor #$FF - sta ptr3 - txa - eor #$FF - sta ptr3+1 + inx + stx ptr3+1 + tax + inx + stx ptr3 ; Save count with each byte incremented separately ; Get the pointer parameters @@ -33,7 +33,7 @@ _memcmp: ; Head of compare loop: Test for the end condition -Loop: inx ; Bump low byte of (-count-1) +Loop: dex ; Bump low byte of (-count-1) beq BumpHiCnt ; Jump on overflow ; Do the compare @@ -53,7 +53,7 @@ Comp: lda (ptr1),y ; Entry on low counter byte overflow BumpHiCnt: - inc ptr3+1 ; Bump high byte of (-count-1) + dec ptr3+1 ; Bump high byte of (-count-1) bne Comp ; Jump if not done jmp return0 ; Count is zero, areas are identical @@ -67,4 +67,3 @@ NotEqual: Greater: ldx #$01 ; Make result positive rts - diff --git a/libsrc/common/strncat.s b/libsrc/common/strncat.s index caa6804fc..060378442 100644 --- a/libsrc/common/strncat.s +++ b/libsrc/common/strncat.s @@ -5,17 +5,17 @@ ; char* strncat (char* dest, const char* src, size_t n); ; - .export _strncat - .import popax, popptr1 - .importzp ptr1, ptr2, ptr3, tmp1, tmp2 - .macpack cpu +.export _strncat +.import popax, popptr1 +.importzp ptr1, ptr2, ptr3, tmp1, tmp2 +.macpack cpu _strncat: - eor #$FF ; one's complement to count upwards - sta tmp1 - txa - eor #$FF - sta tmp2 + inx + stx tmp2 + tax + inx + stx tmp1 ; save count with each byte incremented separately jsr popptr1 ; get src @@ -49,9 +49,9 @@ L2: sty ptr2 L3: ldy #0 ldx tmp1 ; low counter byte -L4: inx +L4: dex bne L5 - inc tmp2 + dec tmp2 beq L6 ; jump if done L5: lda (ptr1),y sta (ptr2),y diff --git a/libsrc/common/strncpy.s b/libsrc/common/strncpy.s index 56387f880..49bd90b32 100644 --- a/libsrc/common/strncpy.s +++ b/libsrc/common/strncpy.s @@ -10,11 +10,11 @@ .proc _strncpy - eor #$FF - sta tmp1 - txa - eor #$FF - sta tmp2 ; Store -size - 1 + inx + stx tmp2 + tax + inx + stx tmp1 ; save count with each byte incremented separately jsr popptr1 ; get src jsr popax ; get dest @@ -26,9 +26,9 @@ ldx tmp1 ; Load low byte of ones complement of size ldy #$00 -L1: inx +L1: dex bne L2 - inc tmp2 + dec tmp2 beq L9 L2: lda (ptr1),y ; Copy one character @@ -42,7 +42,7 @@ L2: lda (ptr1),y ; Copy one character ; Fill the remaining bytes. -L3: inx ; Counter low byte +L3: dex ; Counter low byte beq L6 ; Branch on overflow L4: sta (ptr2),y ; Clear one byte L5: iny ; Bump pointer @@ -52,7 +52,7 @@ L5: iny ; Bump pointer ; Bump the counter high byte -L6: inc tmp2 +L6: dec tmp2 bne L4 ; Done, return dest diff --git a/libsrc/common/strnicmp.s b/libsrc/common/strnicmp.s index 43d6d0d50..f447b9683 100644 --- a/libsrc/common/strnicmp.s +++ b/libsrc/common/strnicmp.s @@ -15,17 +15,11 @@ _strnicmp: _strncasecmp: -; Convert the given counter value in a/x from a downward counter into an -; upward counter, so we can increment the counter in the loop below instead -; of decrementing it. This adds some overhead now, but is cheaper than -; executing a more complex test in each iteration of the loop. We do also -; correct the value by one, so we can do the test on top of the loop. - - eor #$FF - sta ptr3 - txa - eor #$FF - sta ptr3+1 + inx + stx ptr3+1 + tax + inx + stx ptr3 ; save count with each byte incremented separately ; Get the remaining arguments @@ -40,7 +34,7 @@ _strncasecmp: ; Start of compare loop. Check the counter. -Loop: inc ptr3 +Loop: dec ptr3 beq IncHi ; increment high byte ; Compare a byte from the strings @@ -79,7 +73,7 @@ L2: ldx tmp1 ; Increment hi byte -IncHi: inc ptr3+1 +IncHi: dec ptr3+1 bne Comp ; jump if counter not zero ; Exit code if strings are equal. a/x not set diff --git a/libsrc/conio/vcprintf.s b/libsrc/conio/vcprintf.s index 3a9ddf9d7..084efe089 100644 --- a/libsrc/conio/vcprintf.s +++ b/libsrc/conio/vcprintf.s @@ -47,12 +47,12 @@ outdesc: ; Static outdesc structure out: jsr popax ; count sta ptr2 - eor #$FF - sta outdesc+6 - txa - sta ptr2+1 - eor #$FF - sta outdesc+7 + stx ptr2+1 + inx + stx outdesc+7 + tax + inx + stx outdesc+6 jsr popptr1 ; buf @@ -74,7 +74,7 @@ out: jsr popax ; count ; Loop outputting characters -@L1: inc outdesc+6 +@L1: dec outdesc+6 beq @L4 @L2: ldy tmp1 lda (ptr1),y @@ -85,7 +85,7 @@ out: jsr popax ; count jsr _cputc jmp @L1 -@L4: inc outdesc+7 +@L4: dec outdesc+7 bne @L2 rts diff --git a/libsrc/geos-common/drivers/fio_module.s b/libsrc/geos-common/drivers/fio_module.s index 0be5015a7..937ef292e 100644 --- a/libsrc/geos-common/drivers/fio_module.s +++ b/libsrc/geos-common/drivers/fio_module.s @@ -94,11 +94,12 @@ _read: ; popax - fd, must be == to the above one ; return -1+__oserror or number of bytes read - eor #$ff - sta ptr1 - txa - eor #$ff - sta ptr1+1 ; -(# of bytes to read)-1 + inx + stx ptr1+1 + tax + inx + stx ptr1 ; save count with each byte incremented separately + jsr popax sta ptr2 stx ptr2+1 ; buffer ptr @@ -152,9 +153,9 @@ _read: beq @done ; yes, we're done jmp __mappederrno ; no, we're screwed -@L3: inc ptr1 ; decrement the count +@L3: dec ptr1 ; decrement the count bne @L0 - inc ptr1+1 + dec ptr1+1 bne @L0 @done: diff --git a/libsrc/osic1p/bootstrap.s b/libsrc/osic1p/bootstrap.s index ed2ade222..efb480cb8 100644 --- a/libsrc/osic1p/bootstrap.s +++ b/libsrc/osic1p/bootstrap.s @@ -50,16 +50,17 @@ LINEDIST = $20 ; Offset in video RAM between two lines ldx #>load_addr sta load stx load+1 - lda #<load_size - eor #$FF - sta count ; store (-size - 1) - lda #>load_size - eor #$FF - sta count+1 -L1: inc count ; pre-count one's-complement upwards + ldx #<load_size + inx + stx count + ldx #>load_size + inx + stx count+1 ; save size with each byte incremented separately + +L1: dec count ; pre-count one's-complement upwards bnz L2 - inc count+1 + dec count+1 bze L3 L2: jsr GETCHAR ; (doesn't change .Y) sta (load),y diff --git a/libsrc/telestrat/write.s b/libsrc/telestrat/write.s index 68aef42d6..215db3e52 100644 --- a/libsrc/telestrat/write.s +++ b/libsrc/telestrat/write.s @@ -13,11 +13,11 @@ sta ptr3 stx ptr3+1 ; save count as result - eor #$FF - sta ptr2 - txa - eor #$FF - sta ptr2+1 ; remember -count-1 + inx + stx ptr2+1 + tax + inx + stx ptr2 ; save count with each byte incremented separately jsr popptr1 ; get buf jsr popax ; get fd and discard @@ -51,9 +51,9 @@ next: rts -L1: inc ptr2 +L1: dec ptr2 bne L2 - inc ptr2+1 + dec ptr2+1 beq L9 L2: ldy #0 lda (ptr1),y From 6201300816b3c6bcd9cd688f40c0f34b10d3584e Mon Sep 17 00:00:00 2001 From: Sven Michael Klose <pixel@hugbox.org> Date: Tue, 3 Nov 2020 11:52:58 +0100 Subject: [PATCH 1843/2161] Fold constant calculation. --- libsrc/osic1p/bootstrap.s | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libsrc/osic1p/bootstrap.s b/libsrc/osic1p/bootstrap.s index efb480cb8..031c4f651 100644 --- a/libsrc/osic1p/bootstrap.s +++ b/libsrc/osic1p/bootstrap.s @@ -51,11 +51,9 @@ LINEDIST = $20 ; Offset in video RAM between two lines sta load stx load+1 - ldx #<load_size - inx + ldx #(<load_size) + 1 stx count - ldx #>load_size - inx + ldx #(>load_size) + 1 stx count+1 ; save size with each byte incremented separately L1: dec count ; pre-count one's-complement upwards From db312049503dc0effa872d66467b4f36de11831b Mon Sep 17 00:00:00 2001 From: Sven Michael Klose <pixel@hugbox.org> Date: Tue, 3 Nov 2020 11:53:56 +0100 Subject: [PATCH 1844/2161] Remove stale comment. --- libsrc/osic1p/bootstrap.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/osic1p/bootstrap.s b/libsrc/osic1p/bootstrap.s index 031c4f651..e88e257fd 100644 --- a/libsrc/osic1p/bootstrap.s +++ b/libsrc/osic1p/bootstrap.s @@ -56,7 +56,7 @@ LINEDIST = $20 ; Offset in video RAM between two lines ldx #(>load_size) + 1 stx count+1 ; save size with each byte incremented separately -L1: dec count ; pre-count one's-complement upwards +L1: dec count bnz L2 dec count+1 bze L3 From 9d62abb7ac19e2e117d7d162cb4d73482bca06ca Mon Sep 17 00:00:00 2001 From: Sven Michael Klose <pixel@hugbox.org> Date: Tue, 3 Nov 2020 11:54:50 +0100 Subject: [PATCH 1845/2161] Fix comment. --- libsrc/common/strnicmp.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/common/strnicmp.s b/libsrc/common/strnicmp.s index f447b9683..477aa3d66 100644 --- a/libsrc/common/strnicmp.s +++ b/libsrc/common/strnicmp.s @@ -34,8 +34,8 @@ _strncasecmp: ; Start of compare loop. Check the counter. -Loop: dec ptr3 - beq IncHi ; increment high byte +Loop: dec ptr3 ; decrement high byte + beq IncHi ; Compare a byte from the strings From 9800555bbb399decb5aaf50260a831076517332d Mon Sep 17 00:00:00 2001 From: Sven Michael Klose <pixel@hugbox.org> Date: Fri, 20 Nov 2020 03:50:19 +0100 Subject: [PATCH 1846/2161] Remove stale comments. --- libsrc/common/strncpy.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/common/strncpy.s b/libsrc/common/strncpy.s index 49bd90b32..138413ecb 100644 --- a/libsrc/common/strncpy.s +++ b/libsrc/common/strncpy.s @@ -24,7 +24,7 @@ ; Copy src -> dest up to size bytes - ldx tmp1 ; Load low byte of ones complement of size + ldx tmp1 ldy #$00 L1: dex bne L2 @@ -43,7 +43,7 @@ L2: lda (ptr1),y ; Copy one character ; Fill the remaining bytes. L3: dex ; Counter low byte - beq L6 ; Branch on overflow + beq L6 L4: sta (ptr2),y ; Clear one byte L5: iny ; Bump pointer bne L3 From d90cd112125a0a51c286b019c4e76f2131499683 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 27 Dec 2020 18:22:12 -0500 Subject: [PATCH 1847/2161] Fixed outdated comments. --- libsrc/common/memcmp.s | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libsrc/common/memcmp.s b/libsrc/common/memcmp.s index 5879a433d..d651a3cfc 100644 --- a/libsrc/common/memcmp.s +++ b/libsrc/common/memcmp.s @@ -10,8 +10,8 @@ _memcmp: -; Calculate (-count-1) and store it into ptr3. This is some overhead here but -; saves time in the compare loop +; Calculate a special count, and store it into ptr3. That is some overhead here, +; but saves time in the compare loop inx stx ptr3+1 @@ -29,12 +29,12 @@ _memcmp: ; Loop initialization ;ldy #$00 ; Initialize pointer (Y=0 guaranteed by popptr1) - ldx ptr3 ; Load low counter byte into X + ldx ptr3 ; Load inner counter byte into .X ; Head of compare loop: Test for the end condition -Loop: dex ; Bump low byte of (-count-1) - beq BumpHiCnt ; Jump on overflow +Loop: dex + beq BumpHiCnt ; Jump on end of inner count ; Do the compare @@ -50,10 +50,10 @@ Comp: lda (ptr1),y inc ptr2+1 bne Loop ; Branch always (pointer wrap is illegal) -; Entry on low counter byte overflow +; Entry on inner loop end BumpHiCnt: - dec ptr3+1 ; Bump high byte of (-count-1) + dec ptr3+1 bne Comp ; Jump if not done jmp return0 ; Count is zero, areas are identical From a9b71b6207c837833aacda2e5252dac4fd8fa8e5 Mon Sep 17 00:00:00 2001 From: Rocky <rocky@AvBook.local> Date: Fri, 1 Jan 2021 15:39:23 +0100 Subject: [PATCH 1848/2161] return-type - new warning suppression type added --- src/cc65/error.c | 2 ++ src/cc65/error.h | 1 + src/cc65/function.c | 4 ++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cc65/error.c b/src/cc65/error.c index 132bf331d..feb43565d 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -74,6 +74,7 @@ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,6 +93,7 @@ static WarnMapEntry WarnMap[] = { { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, + { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a443aeff8..898793651 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -71,6 +71,7 @@ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ /* Forward */ struct StrBuf; diff --git a/src/cc65/function.c b/src/cc65/function.c index 00755ae65..9269d4c62 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -654,8 +654,8 @@ void NewFunc (SymEntry* Func, FuncDesc* D) ** environment returning int, output a warning if we didn't see a return ** statement. */ - if (!F_HasVoidReturn (CurrentFunc) && !F_HasReturn (CurrentFunc) && !C99MainFunc) { - Warning ("Control reaches end of non-void function"); + if (!F_HasVoidReturn (CurrentFunc) && !F_HasReturn (CurrentFunc) && !C99MainFunc && IS_Get (&WarnReturnType)) { + Warning ("Control reaches end of non-void function [-Wreturn-type]"); } /* If this is the main function in a C99 environment returning an int, let From 96624699577c7497fda3592088f3928867dff381 Mon Sep 17 00:00:00 2001 From: Piotr Kaczorowski <piotr.kaczorowski@gmail.com> Date: Mon, 4 Jan 2021 22:05:55 +0100 Subject: [PATCH 1849/2161] Return-type warning and pseudo variable __A__ documentation added. --- doc/cc65.sgml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index e273ced9c..211aa21b3 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -549,6 +549,8 @@ Here is a description of all the command line options: <tag><tt/remap-zero/</tag> Warn about a <tt/<ref id="pragma-charmap" name="#pragma charmap()">/ that changes a character's code number from/to 0x00. + <tag><tt/return-type/</tag> + Warn about no return statement in function returning non-void.. <tag><tt/struct-param/</tag> Warn when passing structs by value. <tag><tt/unknown-pragma/</tag> @@ -726,6 +728,29 @@ This cc65 version has some extensions to the ISO C standard. will give the high byte of any unsigned value. <p> +<item> There is pseudo variable named <tt/__A__/ that indicates accumulator register. + It can be used to highlight the returned variable in non-void + function where result is hidden in the <tt/asm/ section. + every other variable. They are most useful together with short + sequences of assembler code. + + For example, in the function below + + <tscreen><verb> + BYTE get_key_via_atarixl_romcall_device_k(void) \ + asm("LDA $E425"); \ + asm("PHA"); \ + asm("LDA $E424"); \ + asm("PHA"); \ + asm("RTA"); \ + return __A__; + </verb></tscreen> + + <tt/return __A__;/ will indicate that result is stored in the accumulator + and suppress warning that function has no return statement. Instead, you can + also use <tt/#pragma warn (return-type, off) ... pragma warn (return-type, on)/ + <p> + <item> Inside a function, the identifier <tt/__func__/ gives the name of the current function as a string. Outside of functions, <tt/__func__/ is undefined. From 68e1faa2c815696c5cebdb033593b3dcdbb9fff3 Mon Sep 17 00:00:00 2001 From: Piotr Kaczorowski <piotr.kaczorowski@gmail.com> Date: Mon, 4 Jan 2021 22:10:16 +0100 Subject: [PATCH 1850/2161] Fix typo in cc65.sgml --- doc/cc65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 211aa21b3..0b36812d4 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -550,7 +550,7 @@ Here is a description of all the command line options: Warn about a <tt/<ref id="pragma-charmap" name="#pragma charmap()">/ that changes a character's code number from/to 0x00. <tag><tt/return-type/</tag> - Warn about no return statement in function returning non-void.. + Warn about no return statement in function returning non-void. <tag><tt/struct-param/</tag> Warn when passing structs by value. <tag><tt/unknown-pragma/</tag> From 601e6283436e00314b00fc0b2fb9a549535200ea Mon Sep 17 00:00:00 2001 From: Piotr Kaczorowski <piotr.kaczorowski@gmail.com> Date: Mon, 4 Jan 2021 22:16:07 +0100 Subject: [PATCH 1851/2161] Another fix typo in cc65.sgml --- doc/cc65.sgml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 0b36812d4..82da74f49 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -731,10 +731,7 @@ This cc65 version has some extensions to the ISO C standard. <item> There is pseudo variable named <tt/__A__/ that indicates accumulator register. It can be used to highlight the returned variable in non-void function where result is hidden in the <tt/asm/ section. - every other variable. They are most useful together with short - sequences of assembler code. - - For example, in the function below + For example, in the function below <tscreen><verb> BYTE get_key_via_atarixl_romcall_device_k(void) \ From e3fa247012a5664e6aa113dc8dd9d245bb51bf38 Mon Sep 17 00:00:00 2001 From: Piotr Kaczorowski <piotr.kaczorowski@gmail.com> Date: Tue, 5 Jan 2021 17:48:46 +0100 Subject: [PATCH 1852/2161] Yet another fix typo in cc65.sgml --- doc/cc65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 82da74f49..36b6d1071 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -739,7 +739,7 @@ This cc65 version has some extensions to the ISO C standard. asm("PHA"); \ asm("LDA $E424"); \ asm("PHA"); \ - asm("RTA"); \ + asm("RTS"); \ return __A__; </verb></tscreen> From 0884278ae3583f43c80611b06aae618cac688122 Mon Sep 17 00:00:00 2001 From: Piotr Kaczorowski <piotr.kaczorowski@gmail.com> Date: Wed, 6 Jan 2021 16:02:25 +0100 Subject: [PATCH 1853/2161] Correction in documentation regarding __A__ pseudo variable --- doc/cc65.sgml | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 36b6d1071..f2fd69eba 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -709,7 +709,7 @@ This cc65 version has some extensions to the ISO C standard. places. <p> -<item> There are two pseudo variables named <tt/__AX__/ and <tt/__EAX__/. +<item> There are two pseudo variables named <tt/__A__, __AX__/ and <tt/__EAX__/. Both refer to the primary register that is used by the compiler to evaluate expressions or return function results. <tt/__AX__/ is of type <tt/unsigned int/ and <tt/__EAX__/ of type <tt/long unsigned int/ @@ -728,26 +728,6 @@ This cc65 version has some extensions to the ISO C standard. will give the high byte of any unsigned value. <p> -<item> There is pseudo variable named <tt/__A__/ that indicates accumulator register. - It can be used to highlight the returned variable in non-void - function where result is hidden in the <tt/asm/ section. - For example, in the function below - - <tscreen><verb> - BYTE get_key_via_atarixl_romcall_device_k(void) \ - asm("LDA $E425"); \ - asm("PHA"); \ - asm("LDA $E424"); \ - asm("PHA"); \ - asm("RTS"); \ - return __A__; - </verb></tscreen> - - <tt/return __A__;/ will indicate that result is stored in the accumulator - and suppress warning that function has no return statement. Instead, you can - also use <tt/#pragma warn (return-type, off) ... pragma warn (return-type, on)/ - <p> - <item> Inside a function, the identifier <tt/__func__/ gives the name of the current function as a string. Outside of functions, <tt/__func__/ is undefined. From a861d84011df82ac5f81a8c87ae3181fee393993 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 6 Jan 2021 16:09:55 +0100 Subject: [PATCH 1854/2161] Fixed recent addition of __A__. --- doc/cc65.sgml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index f2fd69eba..24f4422f4 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -709,12 +709,13 @@ This cc65 version has some extensions to the ISO C standard. places. <p> -<item> There are two pseudo variables named <tt/__A__, __AX__/ and <tt/__EAX__/. - Both refer to the primary register that is used by the compiler to - evaluate expressions or return function results. <tt/__AX__/ is of - type <tt/unsigned int/ and <tt/__EAX__/ of type <tt/long unsigned int/ - respectively. The pseudo variables may be used as lvalue and rvalue as - every other variable. They are most useful together with short +<item> There are three pseudo variables named <tt/__A__/, <tt/__AX__/ and + <tt/__EAX__/. They all refer to the primary register that is used + by the compiler to evaluate expressions or return function results. + <tt/__A__/ is of type <tt/unsigned char/, <tt/__AX__/ is of type + <tt/unsigned int/ and <tt/__EAX__/ of type <tt/long unsigned int/ + respectively. The pseudo variables may be used as lvalue and rvalue + as every other variable. They are most useful together with short sequences of assembler code. For example, the macro <tscreen><verb> From 084621967259fc7bb185913adbe48f8a456c262a Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 16 Jan 2021 16:40:58 +0100 Subject: [PATCH 1855/2161] added testprogram for issue #1374 --- test/misc/Makefile | 22 ++++++++++++ test/misc/bug1374.c | 83 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 test/misc/bug1374.c diff --git a/test/misc/Makefile b/test/misc/Makefile index 81a09c693..1bb8c42ad 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -109,6 +109,28 @@ $(WORKDIR)/bug1265.$1.$2.prg: bug1265.c | $(WORKDIR) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) $(NOT) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) +# this one fails with optimizations enabled +$(WORKDIR)/bug1374.g.6502.prg: bug1374.c | $(WORKDIR) + $(if $(QUIET),echo misc/bug1374.g.6502.prg) + $(CC65) -t sim$2 -g -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) $$@ $(NULLOUT) $(NULLERR) + +$(WORKDIR)/bug1374.g.65c02.prg: bug1374.c | $(WORKDIR) + $(if $(QUIET),echo misc/bug1374.g.65c02.prg) + $(CC65) -t sim$2 -g -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) $$@ $(NULLOUT) $(NULLERR) + +$(WORKDIR)/bug1374.$1.$2.prg: bug1374.c | $(WORKDIR) + $(if $(QUIET),echo misc/bug1374.$1.$2.prg) + $(CC65) -t sim$2 -$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) + $(NOT) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) + # 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) diff --git a/test/misc/bug1374.c b/test/misc/bug1374.c new file mode 100644 index 000000000..b55e75fee --- /dev/null +++ b/test/misc/bug1374.c @@ -0,0 +1,83 @@ + +/* test for bug#1374 */ + +#include <stdint.h> +#include <stdio.h> + +static int res = 0; + +int test1(void) +{ + uint8_t x = 0x89; + uint8_t y = 0xab; + uint16_t z = (x << 8) | y; + printf("%x\n", z); + return (z == 0x89ab) ? 0 : 1; +} + +int test1b(void) +{ + uint8_t x = 0x89; + uint8_t y = 0xab; + uint16_t z = (x * 256) | y; + printf("%x\n", z); + return (z == 0x89ab) ? 0 : 1; +} + +int test2(void) +{ + uint16_t x = 0x8900; + uint8_t y = 0xab; + uint16_t z = x | y; + printf("%x\n", z); + return (z == 0x89ab) ? 0 : 1; +} + +int test3(void) +{ + uint16_t x = 0x89; + uint8_t y = 0xab; + uint16_t z = (x << 8) | y; + printf("%x\n", z); + return (z == 0x89ab) ? 0 : 1; +} + +int test3b(void) +{ + uint16_t x = 0x89; + uint8_t y = 0xab; + uint16_t z = (x * 256) | y; + printf("%x\n", z); + return (z == 0x89ab) ? 0 : 1; +} + +int test4(void) +{ + uint8_t x = 0x89; + uint16_t y = 0xab; + uint16_t z = (x << 8) | y; + printf("%x\n", z); + return (z == 0x89ab) ? 0 : 1; +} + +int test4b(void) +{ + uint8_t x = 0x89; + uint16_t y = 0xab; + uint16_t z = (x * 256) | y; + printf("%x\n", z); + return (z == 0x89ab) ? 0 : 1; +} + +int main(void) +{ + res |= test1(); + res |= test2(); + res |= test3(); + res |= test4(); + res |= test1b(); + res |= test3b(); + res |= test4b(); + printf("res: %d\n", res); + return res; +} From b99455cc4787ddd2a139f65317fdabcdf4f5611b Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 19 Jan 2021 20:47:11 +0800 Subject: [PATCH 1856/2161] Fixed Issue #1374. --- src/cc65/codeoptutil.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index 3df762eeb..375fdf541 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -1080,7 +1080,7 @@ void AddOpHigh (StackOpData* D, opc_t OPC, LoadInfo* LI, int KeepResult) } else { - if ((LI->A.Flags & LI_CHECK_Y) == 0) { + if ((LI->X.Flags & LI_CHECK_Y) == 0) { /* ldy #const */ X = NewCodeEntry (OP65_LDY, AM65_IMM, MakeHexArg (LI->X.Offs), 0, D->OpEntry->LI); } else { @@ -1094,7 +1094,7 @@ void AddOpHigh (StackOpData* D, opc_t OPC, LoadInfo* LI, int KeepResult) X = NewCodeEntry (OPC, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI); } else { /* opc src,y */ - X = NewCodeEntry (OPC, LI->A.LoadEntry->AM, LI->A.LoadEntry->Arg, 0, D->OpEntry->LI); + X = NewCodeEntry (OPC, LI->X.LoadEntry->AM, LI->X.LoadEntry->Arg, 0, D->OpEntry->LI); } InsertEntry (D, X, D->IP++); } From a040c28cc449a2e5c9820ce276e0cb5795cfb562 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 19 Jan 2021 20:55:56 +0800 Subject: [PATCH 1857/2161] Moved test for #1374. --- test/misc/Makefile | 22 ---------------------- test/{misc => val}/bug1374.c | 0 2 files changed, 22 deletions(-) rename test/{misc => val}/bug1374.c (100%) diff --git a/test/misc/Makefile b/test/misc/Makefile index 1bb8c42ad..81a09c693 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -109,28 +109,6 @@ $(WORKDIR)/bug1265.$1.$2.prg: bug1265.c | $(WORKDIR) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) $(NOT) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) -# this one fails with optimizations enabled -$(WORKDIR)/bug1374.g.6502.prg: bug1374.c | $(WORKDIR) - $(if $(QUIET),echo misc/bug1374.g.6502.prg) - $(CC65) -t sim$2 -g -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) $$@ $(NULLOUT) $(NULLERR) - -$(WORKDIR)/bug1374.g.65c02.prg: bug1374.c | $(WORKDIR) - $(if $(QUIET),echo misc/bug1374.g.65c02.prg) - $(CC65) -t sim$2 -g -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) $$@ $(NULLOUT) $(NULLERR) - -$(WORKDIR)/bug1374.$1.$2.prg: bug1374.c | $(WORKDIR) - $(if $(QUIET),echo misc/bug1374.$1.$2.prg) - $(CC65) -t sim$2 -$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) - $(NOT) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) - # 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) diff --git a/test/misc/bug1374.c b/test/val/bug1374.c similarity index 100% rename from test/misc/bug1374.c rename to test/val/bug1374.c From a1992702f895632abd0906a05ab22c07fddb5bed Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 24 Jan 2021 18:19:48 +0800 Subject: [PATCH 1858/2161] Declarations of 'extern' object and function should be visible in the file scope. --- src/cc65/symtab.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 56c868b2a..3c000f3a1 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -1159,12 +1159,13 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) /* Add an external or global symbol to the symbol table and return the entry */ { - /* Use the global symbol table */ + /* Start from the local symbol table */ SymTable* Tab = SymTab; /* Do we have an entry with this name already? */ SymEntry* Entry = FindSymInTree (Tab, Name); if (Entry) { + /* We have a symbol with this name already */ if (HandleSymRedefinition (Entry, T, Flags)) { Entry = 0; @@ -1215,7 +1216,11 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) /* Use the fail-safe table for fictitious symbols */ Tab = FailSafeTab; } - } + + } else if ((Flags & (SC_EXTERN | SC_FUNC)) != 0) { + /* Add the new declaration to the global symbol table instead */ + Tab = SymTab0; + } if (Entry == 0 || Entry->Owner != Tab) { From c9ac5152869114dadd3e73f502b7c2ac8783ae6d Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 24 Jan 2021 18:19:51 +0800 Subject: [PATCH 1859/2161] Functions with no prototypes might use EAX registers. --- src/cc65/codeinfo.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index e0cda84e9..90d4f4d68 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -493,22 +493,28 @@ fncls_t GetFuncInfo (const char* Name, unsigned int* Use, unsigned int* Chg) ** registers. */ *Use = REG_EAXY; - } else if (D->ParamCount > 0 && + } else if ((D->ParamCount > 0 || + (D->Flags & FD_EMPTY) != 0) && (AutoCDecl ? IsQualFastcall (E->Type) : !IsQualCDecl (E->Type))) { /* Will use registers depending on the last param. If the last - ** param has incomplete type, just assume __EAX__. + ** param has incomplete type, or if the function has not been + ** prototyped yet, just assume __EAX__. */ - switch (SizeOf (D->LastParam->Type)) { - case 1u: - *Use = REG_A; - break; - case 2u: - *Use = REG_AX; - break; - default: - *Use = REG_EAX; + if (D->LastParam != 0) { + switch (SizeOf(D->LastParam->Type)) { + case 1u: + *Use = REG_A; + break; + case 2u: + *Use = REG_AX; + break; + default: + *Use = REG_EAX; + } + } else { + *Use = REG_EAX; } } else { /* Will not use any registers */ From bfc7a51a44641760dfcf77a7e3407ac52ad3f3a9 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 10 Oct 2020 19:54:18 +0800 Subject: [PATCH 1860/2161] Fixed Issue #1265 according to C89/C99 standards. --- src/cc65/datatype.c | 2 +- src/cc65/expr.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 413007a85..d78bfe116 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -462,7 +462,7 @@ Type* GetImplicitFuncType (void) Type* T = TypeAlloc (3); /* func/returns int/terminator */ /* Prepare the function descriptor */ - F->Flags = FD_EMPTY | FD_VARIADIC; + F->Flags = FD_EMPTY; F->SymTab = &EmptySymTab; F->TagTab = &EmptySymTab; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 0cf650d3b..751014af3 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1171,16 +1171,16 @@ static void Primary (ExprDesc* E) /* IDENT is either an auto-declared function or an undefined variable. */ if (CurTok.Tok == TOK_LPAREN) { - /* C99 doesn't allow calls to undefined functions, so + /* C99 doesn't allow calls to undeclared functions, so ** generate an error and otherwise a warning. Declare a ** function returning int. For that purpose, prepare a ** function signature for a function having an empty param ** list and returning int. */ if (IS_Get (&Standard) >= STD_C99) { - Error ("Call to undefined function '%s'", Ident); + Error ("Call to undeclared function '%s'", Ident); } else { - Warning ("Call to undefined function '%s'", Ident); + Warning ("Call to undeclared function '%s'", Ident); } Sym = AddGlobalSym (Ident, GetImplicitFuncType(), SC_EXTERN | SC_REF | SC_FUNC); E->Type = Sym->Type; From 95830cce29c9ae2503b60ae7244b460e1a302f53 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 24 Jan 2021 18:19:54 +0800 Subject: [PATCH 1861/2161] Fixed test/misc/bug1265.c with its output. --- test/misc/Makefile | 3 +-- test/misc/bug1265.c | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/test/misc/Makefile b/test/misc/Makefile index 81a09c693..7a1b82d5f 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -101,13 +101,12 @@ $(WORKDIR)/bug1263.$1.$2.prg: bug1263.c | $(WORKDIR) $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) # this one requires --std=c89, it fails with --std=c99 -# it fails currently at runtime $(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) $(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) + $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) # should compile, but then hangs in an endless loop $(WORKDIR)/endless.$1.$2.prg: endless.c | $(WORKDIR) diff --git a/test/misc/bug1265.c b/test/misc/bug1265.c index 469946739..36d1459a7 100644 --- a/test/misc/bug1265.c +++ b/test/misc/bug1265.c @@ -14,11 +14,9 @@ int main (void) { int x, n; sprintf (str1, "%p\n", &x); - puts(str1); x = 1234; n = f1 (x); sprintf (str2, "%p\n", &x); - puts(str2); if (strcmp(str1, str2)) { puts("not equal"); @@ -30,11 +28,9 @@ int main (void) { } sprintf (str1, "%p\n", &x); - puts(str1); x = 2345; n = f2 (x); sprintf (str2, "%p\n", &x); - puts(str2); if (strcmp(str1, str2)) { puts("not equal"); From 6c59a6254f315cd7d82112d1d7e042242c14237d Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Fri, 23 Oct 2020 23:47:30 +0200 Subject: [PATCH 1862/2161] Now getchar works --- libsrc/telestrat/read.s | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/libsrc/telestrat/read.s b/libsrc/telestrat/read.s index 76de9d0ac..0782c4d21 100644 --- a/libsrc/telestrat/read.s +++ b/libsrc/telestrat/read.s @@ -8,21 +8,33 @@ .include "zeropage.inc" .include "telestrat.inc" + .include "fcntl.inc" ;int read (int fd, void* buf, unsigned count); .proc _read - sta ptr1 ; count - stx ptr1+1 ; count - jsr popax ; get buf + sta ptr1 ; count + stx ptr1+1 ; count + jsr popax ; get buf sta PTR_READ_DEST stx PTR_READ_DEST+1 - sta ptr2 ; in order to calculate nb of bytes read + sta ptr2 ; in order to calculate nb of bytes read stx ptr2+1 ; - ; jsr popax ; fp pointer don't care in this version + jsr popax ; fp pointer don't care in this version + cpx #$00 + bne @is_not_stdin + cmp #STDIN_FILENO + bne @is_not_stdin + ; stdin +@L1: + BRK_TELEMON XRD0 ; waits until key is pressed + bcs @L1 + + rts +@is_not_stdin: lda ptr1 ; ldy ptr1+1 ; BRK_TELEMON XFREAD ; calls telemon30 routine From f622783ae19178c4500593993531823483abaf9c Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 1 Feb 2021 17:53:07 +0100 Subject: [PATCH 1863/2161] kbhit added for telestrat target --- libsrc/telestrat/kbhit.s | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 libsrc/telestrat/kbhit.s diff --git a/libsrc/telestrat/kbhit.s b/libsrc/telestrat/kbhit.s new file mode 100644 index 000000000..431b9a957 --- /dev/null +++ b/libsrc/telestrat/kbhit.s @@ -0,0 +1,19 @@ +; +; Jede, 2021-02-01 +; +; int kbhit (void); +; + + .export _kbhit + + .include "telestrat.inc" + +_kbhit: + BRK_TELEMON XRD0 + bcs @no_char_action + lda #$01 + rts +@no_char_action: + lda #$00 + rts + From b52ee25385a33c42c502fd7632b6521c615cac7a Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 1 Feb 2021 23:21:41 +0100 Subject: [PATCH 1864/2161] Rollback read.s --- libsrc/telestrat/read.s | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/libsrc/telestrat/read.s b/libsrc/telestrat/read.s index 0782c4d21..76de9d0ac 100644 --- a/libsrc/telestrat/read.s +++ b/libsrc/telestrat/read.s @@ -8,33 +8,21 @@ .include "zeropage.inc" .include "telestrat.inc" - .include "fcntl.inc" ;int read (int fd, void* buf, unsigned count); .proc _read - sta ptr1 ; count - stx ptr1+1 ; count - jsr popax ; get buf + sta ptr1 ; count + stx ptr1+1 ; count + jsr popax ; get buf sta PTR_READ_DEST stx PTR_READ_DEST+1 - sta ptr2 ; in order to calculate nb of bytes read + sta ptr2 ; in order to calculate nb of bytes read stx ptr2+1 ; - jsr popax ; fp pointer don't care in this version - cpx #$00 - bne @is_not_stdin - cmp #STDIN_FILENO - bne @is_not_stdin - ; stdin -@L1: - BRK_TELEMON XRD0 ; waits until key is pressed - bcs @L1 - - rts + ; jsr popax ; fp pointer don't care in this version -@is_not_stdin: lda ptr1 ; ldy ptr1+1 ; BRK_TELEMON XFREAD ; calls telemon30 routine From a9dac3b1efeab8da38bb86beaae55354a35b6101 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Tue, 2 Feb 2021 12:32:42 +0100 Subject: [PATCH 1865/2161] Fix X register for kbhit --- libsrc/telestrat/kbhit.s | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libsrc/telestrat/kbhit.s b/libsrc/telestrat/kbhit.s index 431b9a957..bb88af4b2 100644 --- a/libsrc/telestrat/kbhit.s +++ b/libsrc/telestrat/kbhit.s @@ -11,9 +11,11 @@ _kbhit: BRK_TELEMON XRD0 bcs @no_char_action + ldx #$00 lda #$01 rts @no_char_action: - lda #$00 + lda #$00 + tax rts From 855143123347fad6a09d08f995d7a2d5c7bd84de Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 5 Feb 2021 11:54:07 +0100 Subject: [PATCH 1866/2161] Optimized based on https://github.com/cc65/cc65/pull/1393. --- libsrc/telestrat/kbhit.s | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/libsrc/telestrat/kbhit.s b/libsrc/telestrat/kbhit.s index bb88af4b2..54e4bf4d8 100644 --- a/libsrc/telestrat/kbhit.s +++ b/libsrc/telestrat/kbhit.s @@ -10,12 +10,8 @@ _kbhit: BRK_TELEMON XRD0 - bcs @no_char_action - ldx #$00 - lda #$01 + ldx #$00 + txa + rol + eor #$01 rts -@no_char_action: - lda #$00 - tax - rts - From 6c90f3e2d20ea47a28a7faa2378a917cefac749e Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 9 Feb 2021 11:22:58 +0100 Subject: [PATCH 1867/2161] atarixl configs: RAM memory area was renamed to MAIN in d8c31cf1d3b724b83bd411736472e1c16fb1b0c0 adjust comments accordingly --- cfg/atarixl-largehimem.cfg | 2 +- cfg/atarixl-overlay.cfg | 2 +- cfg/atarixl-xex.cfg | 2 +- cfg/atarixl.cfg | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cfg/atarixl-largehimem.cfg b/cfg/atarixl-largehimem.cfg index 5e60f32bd..38fb68db9 100644 --- a/cfg/atarixl-largehimem.cfg +++ b/cfg/atarixl-largehimem.cfg @@ -54,7 +54,7 @@ SEGMENTS { SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes; SRPREPHDR: load = SRPREPHDR, type = ro; - LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and RAM, not zero initialized + LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and MAIN, not zero initialized SRPREP: load = SRPREPCHNK, type = rw, define = yes; SHADOW_RAM: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = yes; SHADOW_RAM2: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = yes; diff --git a/cfg/atarixl-overlay.cfg b/cfg/atarixl-overlay.cfg index 2bb4105cd..339228ea0 100644 --- a/cfg/atarixl-overlay.cfg +++ b/cfg/atarixl-overlay.cfg @@ -65,7 +65,7 @@ SEGMENTS { SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes; SRPREPHDR: load = SRPREPHDR, type = ro; - LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and RAM, not zero initialized + LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and MAIN, not zero initialized SRPREP: load = SRPREPCHNK, type = rw, define = yes; SHADOW_RAM: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = yes; SHADOW_RAM2: load = SRPREPCHNK, run = HIDDEN_RAM2, type = rw, define = yes, optional = yes; diff --git a/cfg/atarixl-xex.cfg b/cfg/atarixl-xex.cfg index 6b6601c59..1b76855d0 100644 --- a/cfg/atarixl-xex.cfg +++ b/cfg/atarixl-xex.cfg @@ -48,7 +48,7 @@ SEGMENTS { EXTZP: load = ZP, type = zp, optional = yes; SYSCHK: load = SYSCHKCHNK, type = rw, define = yes, optional = yes; - LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and RAM, not zero initialized + LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and MAIN, not zero initialized SRPREP: load = SRPREPCHNK, type = rw, define = yes; SHADOW_RAM: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = yes; SHADOW_RAM2: load = SRPREPCHNK, run = HIDDEN_RAM2, type = rw, define = yes, optional = yes; diff --git a/cfg/atarixl.cfg b/cfg/atarixl.cfg index d4e466ae1..cece23555 100644 --- a/cfg/atarixl.cfg +++ b/cfg/atarixl.cfg @@ -52,7 +52,7 @@ SEGMENTS { SYSCHKTRL: load = SYSCHKTRL, type = ro, optional = yes; SRPREPHDR: load = SRPREPHDR, type = ro; - LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and RAM, not zero initialized + LOWBSS: load = SRPREPCHNK, type = bss, define = yes; # shared btw. SRPREPCHNK and MAIN, not zero initialized SRPREP: load = SRPREPCHNK, type = rw, define = yes; SHADOW_RAM: load = SRPREPCHNK, run = HIDDEN_RAM, type = rw, define = yes, optional = yes; SHADOW_RAM2: load = SRPREPCHNK, run = HIDDEN_RAM2, type = rw, define = yes, optional = yes; From ab8bb26868159af14ec5fd3345789c23a6e72e49 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 9 Feb 2021 19:50:08 +0100 Subject: [PATCH 1868/2161] added testcase for issue #1937 --- test/misc/Makefile | 8 +++++++ test/misc/bug1397.c | 55 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 test/misc/bug1397.c diff --git a/test/misc/Makefile b/test/misc/Makefile index 7a1b82d5f..3142dcfb8 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -108,6 +108,14 @@ $(WORKDIR)/bug1265.$1.$2.prg: bug1265.c | $(WORKDIR) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) +# this one fails with optimizations, without OptBoolTrans it works +$(WORKDIR)/bug1397.$1.$2.prg: bug1397.c | $(WORKDIR) + $(if $(QUIET),echo misc/bug1397.$1.$2.prg) + $(CC65) -O --disable-opt OptBoolTrans -t sim$2 -$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) $$@ $(NULLOUT) $(NULLERR) + # 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) diff --git a/test/misc/bug1397.c b/test/misc/bug1397.c new file mode 100644 index 000000000..4f8fb8697 --- /dev/null +++ b/test/misc/bug1397.c @@ -0,0 +1,55 @@ + +/* bug #1937 - Incorrect Behavior Related to OptBoolTrans */ + +#include <stdio.h> + +unsigned char c; +int *p; + +void f1(void) { + int i = 1; + int *pa = (int *)0xaaaa; + int *pb = (int *)0xbbbb; + + p = (i == 0) ? pa : pb; + c = 0x5a; +} + + +struct data_t { + unsigned char c; + int *p; +}; + +struct data_t data; + +void f2(void) { + int i = 1; + int *pa = (int *)0xcccc; + int *pb = (int *)0xdddd; + struct data_t *po = &data; + + po->p = (i == 0) ? pa : pb; + po->c = 0xa5; +} + +int ret = 0; + +int main(void) { + f1(); + if (c != 0x5a) { + ret++; + } + printf("c: %hhx\n", c); + printf("p: %p\n", p); + f2(); + if (data.c != 0xa5) { + ret++; + } + printf("c: %hhx\n", data.c); + printf("p: %p\n", data.p); + + printf("failures: %d\n", ret); + return ret; +} + From 9cd1ffa6a6131455e419f5436f1396e140cff005 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 11 Feb 2021 19:20:11 +0100 Subject: [PATCH 1869/2161] doc/ld65.sgml: document the INIT segment - re-arrange the segments in the "Special segments" section alphabetically - some small changes in section 5.8 (FILE) regarding Atari XEX format --- doc/ld65.sgml | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index cba06fef4..c2e990dc2 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -921,9 +921,8 @@ name="6502 binary relocation format specification">). It is defined like this: } </verb></tscreen> -The other format available is the Atari (xex) segmented file format, this is -the standard format used by Atari DOS 2.0 and upward file managers in the Atari -8-bit computers, and it is defined like this: +The other format available is the Atari segmented file format (xex), this is +the standard format used by Atari DOS 2.0 and upwards, and it is defined like this: <tscreen><verb> FILES { @@ -1140,6 +1139,19 @@ The builtin config files do contain segments that have a special meaning for the compiler and the libraries that come with it. If you replace the builtin config files, you will need the following information. +<sect1>INIT<p> + +The INIT segment is some kind of 'bss' segment since it contains +uninitialized data. Unlike <tt>.bss</tt> itself, its contents aren't +initialized to zero at program startup . It's mostly used by +constructors in the startup code. An example for the use of the INIT +segment is saving/restoring the zero page area used by cc65. + +<sect1>LOWCODE<p> + +For the LOWCODE segment, it is guaranteed that it won't be banked out, so it +is reachable at any time by interrupt handlers or similar. + <sect1>ONCE<p> The ONCE segment is used for initialization code run only once before @@ -1147,11 +1159,6 @@ execution reaches main() - provided that the program runs in RAM. You may for example add the ONCE segment to the heap in really memory constrained systems. -<sect1>LOWCODE<p> - -For the LOWCODE segment, it is guaranteed that it won't be banked out, so it -is reachable at any time by interrupt handlers or similar. - <sect1>STARTUP<p> This segment contains the startup code which initializes the C software stack From 43881afca22e2e8d2fc5a36a8519befd97ff1a4b Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 11 Feb 2021 20:56:28 +0100 Subject: [PATCH 1870/2161] doc/atari5200.sgml: document splash screen user changeable settings --- doc/atari5200.sgml | 50 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/doc/atari5200.sgml b/doc/atari5200.sgml index aff212b15..c7e5be73e 100644 --- a/doc/atari5200.sgml +++ b/doc/atari5200.sgml @@ -30,7 +30,7 @@ information. <sect>Binary format<p> -The standard binary output format generated by the linker for the Atari 5200 target +The binary output format generated by the linker for the Atari 5200 target is a cartridge image. It is of course possible to change this behaviour by using a modified startup file and linker config. @@ -219,10 +219,58 @@ you cannot use any of the following functions (and a few others): <sect>Other hints<p> +<sect1>CAR format<p> + AtariROMMaker (<url url="https://www.wudsn.com/index.php/productions-atari800/tools/atarirommaker"> ) can be used to create a <tt/.CAR/ file from the binary ROM image cc65 generates. This might be more convenient when working with emulators. +<sect1>Changing the splash screen<p> + +The 5200 ROM displays a splash screen at startup with the name of the +game and the copyright year. The year information has a 'Year-2000' +problem, the first two digits are fixed in the ROM and are always "19". + +<sect2>Changing the game name<p> + +The runtime library provides a default game name which is "cc65 +compiled". To change that, one has to link a file which puts data into +the "<tt/CARTNAME/" segment. + +For reference, here's the default version used by the cc65 libary: +<tscreen><verb> +.export __CART_NAME__: absolute = 1 +.macpack atari +.segment "CARTNAME" + scrcode " cc" + .byte '6' + 32, '5' + 32 ; use playfield 1 + scrcode " compiled" +</verb></tscreen> + +'<tt/__CART_NAME__/' needs to be defined in order that the linker is +satisfied and doesn't try to include the version of the runtime library. + +20 bytes are available in the <tt/CARTNAME/ segment (one line) for the +game/program name. + +<sect2>Changing the copyright year / changing the cartridge type<p> + +The century is hard-coded to 1900 by the ROM. + +There are two digits which can be changed. For example "92" will give +"1992" on the screen. + +The default used by the runtime library is + +<tscreen><verb> +.export __CART_YEAR__: absolute = 1 +.segment "CARTYEAR" + .byte '9' + 32,'8' + 32 ; "98", using playfield 1 +</verb></tscreen> + +If the second byte of the year in the <tt/CARTYEAR/ segment is 255, +the cartridge is seen as a 'diagnostic' cartridge, and the splash +screen and most of the other startup initializations are bypassed. <sect>License<p> From 98f8064b8311753fab468aaf2c1b6d2e339a4391 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 15 Feb 2021 08:50:34 -0500 Subject: [PATCH 1871/2161] Made the directory functions compatible with the Commander X16's DOS. It's directory listing's last line says, "mb free." --- include/cbm.h | 12 +++++++++++- libsrc/cbm/c_basin.s | 4 +++- libsrc/cbm/c_bsout.s | 6 ++++-- libsrc/cbm/cbm_dir.c | 9 +++++---- libsrc/cbm/readdir.c | 20 ++++++++++---------- 5 files changed, 33 insertions(+), 18 deletions(-) diff --git a/include/cbm.h b/include/cbm.h index 5bcef8e60..cceb76b1b 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -191,6 +191,8 @@ unsigned char cbm_k_acptr (void); unsigned char cbm_k_basin (void); void __fastcall__ cbm_k_bsout (unsigned char C); unsigned char __fastcall__ cbm_k_chkin (unsigned char FN); +unsigned char cbm_k_chrin (void); +void __fastcall__ cbm_k_chrout (unsigned char C); void __fastcall__ cbm_k_ciout (unsigned char C); unsigned char __fastcall__ cbm_k_ckout (unsigned char FN); void cbm_k_clall (void); @@ -295,7 +297,15 @@ unsigned char __fastcall__ cbm_readdir (unsigned char lfn, /* Reads one directory line into cbm_dirent structure. ** Returns 0 if reading directory-line was successful. ** Returns non-zero if reading directory failed, or no more file-names to read. -** Returns 2 on last line. Then, l_dirent->size = the number of "blocks free." +** Returns 2 on last line. Then, l_dirent->size = the number of "blocks free", +** "blocks used", or "mb free". Return codes: +** 0 = read file-name +** 1 = couldn't read directory +** 2 = read "blocks free", "blocks used", or "mb free" +** 3 = couldn't find start of file-name +** 4 = couldn't find end of file-name +** 5 = couldn't read file-type +** 6 = premature end of file */ void __fastcall__ cbm_closedir (unsigned char lfn); diff --git a/libsrc/cbm/c_basin.s b/libsrc/cbm/c_basin.s index da925a1a4..c2211e9ce 100644 --- a/libsrc/cbm/c_basin.s +++ b/libsrc/cbm/c_basin.s @@ -2,14 +2,16 @@ ; Ullrich von Bassewitz, 03.06.1999 ; ; unsigned char cbm_k_basin (void); +; unsigned char cbm_k_chrin (void); ; .include "cbm.inc" - .export _cbm_k_basin + .export _cbm_k_basin, _cbm_k_chrin _cbm_k_basin: +_cbm_k_chrin: jsr BASIN ldx #0 ; Clear high byte rts diff --git a/libsrc/cbm/c_bsout.s b/libsrc/cbm/c_bsout.s index 104878453..cec46bf90 100644 --- a/libsrc/cbm/c_bsout.s +++ b/libsrc/cbm/c_bsout.s @@ -2,10 +2,12 @@ ; Ullrich von Bassewitz, 03.06.1999 ; ; void __fastcall__ cbm_k_bsout (unsigned char C); +; void __fastcall__ cbm_k_chrout (unsigned char C); ; .include "cbm.inc" - .export _cbm_k_bsout + .export _cbm_k_bsout, _cbm_k_chrout -_cbm_k_bsout = BSOUT +_cbm_k_bsout := BSOUT +_cbm_k_chrout := CHROUT diff --git a/libsrc/cbm/cbm_dir.c b/libsrc/cbm/cbm_dir.c index 8f31c502a..4b8927f98 100644 --- a/libsrc/cbm/cbm_dir.c +++ b/libsrc/cbm/cbm_dir.c @@ -6,6 +6,7 @@ /* 2009-10-10 -- Version 0.3 */ /* 2011-04-07 -- Version 0.4, groepaz */ /* 2011-04-14 -- Version 0.5, Greg King */ +/* 2021-02-15 -- Version 0.6, Greg King */ /* Tested with floppy-drive and IDE64 devices. */ /* Not tested with messed (buggy) directory listings. */ @@ -29,7 +30,7 @@ unsigned char cbm_opendir (unsigned char lfn, unsigned char device, ...) va_list ap; const char* name = "$"; - /* The name used in cbm_open may optionally be passed */ + /* The name used in cbm_open() optionally may be passed */ if (__argsize__ == 4) { va_start (ap, device); name = va_arg (ap, const char*); @@ -76,9 +77,10 @@ unsigned char __fastcall__ cbm_readdir (unsigned char lfn, register struct cbm_d byte = cbm_k_basin(); switch (byte) { - - /* "B" BLOCKS FREE. */ + /* "B" BLOCKS FREE/USED. */ + /* "M" MB FREE. */ case 'b': + case 'm': /* Read until end; careless callers might call us again. */ while (!cbm_k_readst()) { cbm_k_basin(); @@ -168,7 +170,6 @@ unsigned char __fastcall__ cbm_readdir (unsigned char lfn, register struct cbm_d } rv = 0; - goto ret_val; } } diff --git a/libsrc/cbm/readdir.c b/libsrc/cbm/readdir.c index 8d6968977..1512edc4e 100644 --- a/libsrc/cbm/readdir.c +++ b/libsrc/cbm/readdir.c @@ -1,5 +1,7 @@ /* -** Ullrich von Bassewitz, 2012-05-30. Based on code by Groepaz. +** Based on code by Groepaz. +** 2012-05-30, Ullrich von Bassewitz +** 2021-02-15, Greg King */ @@ -52,12 +54,14 @@ struct dirent* __fastcall__ readdir (register DIR* dir) /* Bump the directory offset and include the bytes for line-link and size */ dir->off += count + 4; - /* End of directory is reached if the buffer contains "blocks free". It is - ** sufficient here to check for the leading 'b'. buffer will contain at - ** least one byte if we come here. + /* End of directory is reached if the buffer contains "blocks free/used" or + ** "mb free.". It is sufficient here to check for the leading 'b' and 'm'. + ** buffer will contain at least one byte if we come here. */ - if (buffer[0] == 'b') { - goto exitpoint; + switch (buffer[0]) { + case 'b': + case 'm': + goto exitpoint; } /* Parse the buffer for the filename and file type */ @@ -67,7 +71,6 @@ struct dirent* __fastcall__ readdir (register DIR* dir) b = buffer; while (i < count) { switch (s) { - case 0: /* Searching for start of file name */ if (*b == '"') { @@ -127,6 +130,3 @@ struct dirent* __fastcall__ readdir (register DIR* dir) exitpoint: return 0; } - - - From b12758fe5355b62285675628a043fe0625fff47b Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 16 Feb 2021 14:07:47 +0100 Subject: [PATCH 1872/2161] include/atari.h: fix typo in _setcolor() prototype --- include/atari.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/atari.h b/include/atari.h index f5916a284..86c7b9706 100644 --- a/include/atari.h +++ b/include/atari.h @@ -6,10 +6,11 @@ /* */ /* */ /* */ -/* (C) 2000-2019 Mark Keates <markk@dendrite.co.uk> */ +/* (C) 2000-2021 Mark Keates <markk@dendrite.co.uk> */ /* Freddy Offenga <taf_offenga@yahoo.com> */ /* Christian Groessler <chris@groessler.org> */ /* Bill Kendrick <nbs@sonic.net> */ +/* et al. */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -219,7 +220,7 @@ /* Color register functions */ /*****************************************************************************/ -extern void __fastcall__ _setcolor (unsigned char color_reg, unsigned char hue, unsigned char luminace); +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); From 3a7282544e0a818bf8fe39970df912a8eb4ed87f Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 17 Feb 2021 10:49:53 +0100 Subject: [PATCH 1873/2161] Moved convert.system from geos-apple to apple2[enh]. The target util convert.system is to be used in conjunction with GEOS on the Apple II but has to be built as an "ordinary" Apple II program. The way the cc65 library build system is designed there's no way to define dependencies between targets. The solution used so far was to explicitly trigger a build of the target 'apple2enh' from the target 'geos-apple'. However, that approach tends to break parallel builds which may be in the middle of building 'appple2enh' at the time it is triggered by 'geos-apple'. There might be ways to get this fixed - but the the cc65 library build systrem is already (more than) complex enough, so I really don't want to add anything special to it. On the other hand there are easier ways (outside the scope of cc65) to archive what convert.system does so I don't presume convert.system to be actually used - it's more a reference type of thing. Putting all facts together the decision was easy: Just move convert.system from the target it is used with to the target(s) it is built with. --- libsrc/Makefile | 3 +-- libsrc/apple2/targetutil/Makefile.inc | 12 ++++++++++-- libsrc/{geos-apple => apple2}/targetutil/convert.c | 0 libsrc/geos-apple/targetutil/Makefile.inc | 14 -------------- 4 files changed, 11 insertions(+), 18 deletions(-) rename libsrc/{geos-apple => apple2}/targetutil/convert.c (100%) delete mode 100644 libsrc/geos-apple/targetutil/Makefile.inc diff --git a/libsrc/Makefile b/libsrc/Makefile index d9ddb3ccd..3fac513af 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -133,8 +133,7 @@ MKINC = $(GEOS) \ TARGETUTIL = apple2 \ apple2enh \ - atari \ - geos-apple + atari GEOSDIRS = common \ conio \ diff --git a/libsrc/apple2/targetutil/Makefile.inc b/libsrc/apple2/targetutil/Makefile.inc index d9d727b0a..b53139a3d 100644 --- a/libsrc/apple2/targetutil/Makefile.inc +++ b/libsrc/apple2/targetutil/Makefile.inc @@ -1,9 +1,17 @@ -DEPS += ../libwrk/$(TARGET)/loader.d +DEPS += ../libwrk/$(TARGET)/convert.d \ + ../libwrk/$(TARGET)/loader.d + +../libwrk/$(TARGET)/convert.o: $(SRCDIR)/targetutil/convert.c | ../libwrk/$(TARGET) + $(COMPILE_recipe) ../libwrk/$(TARGET)/loader.o: $(SRCDIR)/targetutil/loader.s | ../libwrk/$(TARGET) $(ASSEMBLE_recipe) +../target/$(TARGET)/util/convert.system: ../libwrk/$(TARGET)/convert.o ../lib/$(TARGET).lib | ../target/$(TARGET)/util + $(LD65) -o $@ -C $(TARGET)-system.cfg $^ + ../target/$(TARGET)/util/loader.system: ../libwrk/$(TARGET)/loader.o $(SRCDIR)/targetutil/loader.cfg | ../target/$(TARGET)/util $(LD65) -o $@ -C $(filter %.cfg,$^) $(filter-out %.cfg,$^) -$(TARGET): ../target/$(TARGET)/util/loader.system +$(TARGET): ../target/$(TARGET)/util/convert.system \ + ../target/$(TARGET)/util/loader.system diff --git a/libsrc/geos-apple/targetutil/convert.c b/libsrc/apple2/targetutil/convert.c similarity index 100% rename from libsrc/geos-apple/targetutil/convert.c rename to libsrc/apple2/targetutil/convert.c diff --git a/libsrc/geos-apple/targetutil/Makefile.inc b/libsrc/geos-apple/targetutil/Makefile.inc deleted file mode 100644 index 3d366f913..000000000 --- a/libsrc/geos-apple/targetutil/Makefile.inc +++ /dev/null @@ -1,14 +0,0 @@ -DEPS += ../libwrk/$(TARGET)/convert.d - -../libwrk/$(TARGET)/convert.o: TARGET = apple2enh - -../libwrk/$(TARGET)/convert.o: $(SRCDIR)/targetutil/convert.c | ../libwrk/$(TARGET) - $(COMPILE_recipe) - -../lib/apple2enh.lib: - @$(MAKE) --no-print-directory apple2enh - -../target/$(TARGET)/util/convert.system: ../libwrk/$(TARGET)/convert.o ../lib/apple2enh.lib | ../target/$(TARGET)/util - $(LD65) -o $@ -C apple2enh-system.cfg $^ - -$(TARGET): ../target/$(TARGET)/util/convert.system From 55ae350fedaf1769ecc766cfb9dc4fa163d38392 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 13 Feb 2021 22:02:52 +0800 Subject: [PATCH 1874/2161] Fixed 'Opt_staxspidx' for the invariant of 'staxspidx'. --- src/cc65/coptstop.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 77b79281b..01d0b039c 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -453,6 +453,7 @@ static unsigned Opt_staxspidx (StackOpData* D) /* Optimize the staxspidx sequence */ { CodeEntry* X; + const char* Arg = 0; /* Check if we're using a register variable */ if (!IsRegVar (D)) { @@ -469,7 +470,7 @@ static unsigned Opt_staxspidx (StackOpData* D) if (RegValIsKnown (D->OpEntry->RI->In.RegY)) { /* Value of Y is known */ - const char* Arg = MakeHexArg (D->OpEntry->RI->In.RegY + 1); + Arg = MakeHexArg (D->OpEntry->RI->In.RegY + 1); X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, D->OpEntry->LI); } else { X = NewCodeEntry (OP65_INY, AM65_IMP, 0, 0, D->OpEntry->LI); @@ -478,7 +479,7 @@ static unsigned Opt_staxspidx (StackOpData* D) if (RegValIsKnown (D->OpEntry->RI->In.RegX)) { /* Value of X is known */ - const char* Arg = MakeHexArg (D->OpEntry->RI->In.RegX); + Arg = MakeHexArg (D->OpEntry->RI->In.RegX); X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, D->OpEntry->LI); } else { /* Value unknown */ @@ -493,7 +494,12 @@ static unsigned Opt_staxspidx (StackOpData* D) /* If we remove staxspidx, we must restore the Y register to what the ** function would return. */ - X = NewCodeEntry (OP65_LDY, AM65_IMM, "$00", 0, D->OpEntry->LI); + if (RegValIsKnown (D->OpEntry->RI->In.RegY)) { + Arg = MakeHexArg (D->OpEntry->RI->In.RegY); + X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, D->OpEntry->LI); + } else { + X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, D->OpEntry->LI); + } InsertEntry (D, X, D->OpIndex+5); /* Remove the push and the call to the staxspidx function */ From 131f96eb1eda192623b1b3e323a2a0739645b641 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 13 Feb 2021 22:11:01 +0800 Subject: [PATCH 1875/2161] Moved testcase for issue #1397. --- test/misc/Makefile | 8 -------- test/{misc => val}/bug1397.c | 0 2 files changed, 8 deletions(-) rename test/{misc => val}/bug1397.c (100%) diff --git a/test/misc/Makefile b/test/misc/Makefile index 3142dcfb8..7a1b82d5f 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -108,14 +108,6 @@ $(WORKDIR)/bug1265.$1.$2.prg: bug1265.c | $(WORKDIR) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) -# this one fails with optimizations, without OptBoolTrans it works -$(WORKDIR)/bug1397.$1.$2.prg: bug1397.c | $(WORKDIR) - $(if $(QUIET),echo misc/bug1397.$1.$2.prg) - $(CC65) -O --disable-opt OptBoolTrans -t sim$2 -$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) $$@ $(NULLOUT) $(NULLERR) - # 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) diff --git a/test/misc/bug1397.c b/test/val/bug1397.c similarity index 100% rename from test/misc/bug1397.c rename to test/val/bug1397.c From acb5af539fd5134adebb770c9ca0500195fad5ba Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 21 Feb 2021 14:02:49 -0500 Subject: [PATCH 1876/2161] Fixed the ld65 configure files for the cx16 platform. * Added ONCE and INIT segments to the Assembly configuration. * Made more segments optional in the standard and the banked configurations. That will make them a little easier to use with Assembly-source programs. --- cfg/cx16-asm.cfg | 4 +- cfg/cx16-bank.cfg | 100 ++++++++++++++++++++++------------------------ cfg/cx16.cfg | 12 +++--- 3 files changed, 57 insertions(+), 59 deletions(-) diff --git a/cfg/cx16-asm.cfg b/cfg/cx16-asm.cfg index c3c08aec3..92c9d96f7 100644 --- a/cfg/cx16-asm.cfg +++ b/cfg/cx16-asm.cfg @@ -22,9 +22,11 @@ SEGMENTS { EXEHDR: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; - BSS: load = MAIN, type = bss, define = yes; + INIT: load = MAIN, type = bss, optional = yes; + BSS: load = MAIN, type = bss, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/cx16-bank.cfg b/cfg/cx16-bank.cfg index 36b0edb02..d3c2c02ae 100644 --- a/cfg/cx16-bank.cfg +++ b/cfg/cx16-bank.cfg @@ -16,8 +16,6 @@ MEMORY { HEADER: file = %O, define = yes, start = %S, size = $000D; MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__; BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __ONCE_RUN__ - __STACKSIZE__; -# BRAM00ADDR: file = "%O.00", start = __BANKRAMSTART__ - 2, size = $0002; -# BRAM00: file = "%O.00", start = __BANKRAMSTART__, size = __BANKRAMSIZE__; BRAM01ADDR: file = "%O.01", start = __BANKRAMSTART__ - 2, size = $0002; BRAM01: file = "%O.01", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $01; BRAM02ADDR: file = "%O.02", start = __BANKRAMSTART__ - 2, size = $0002; @@ -36,64 +34,62 @@ MEMORY { BRAM08: file = "%O.08", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $08; BRAM09ADDR: file = "%O.09", start = __BANKRAMSTART__ - 2, size = $0002; BRAM09: file = "%O.09", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $09; - BRAM0AADDR: file = "%O.0a", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0A: file = "%O.0a", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0A; - BRAM0BADDR: file = "%O.0b", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0B: file = "%O.0b", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0B; - BRAM0CADDR: file = "%O.0c", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0C: file = "%O.0c", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0C; - BRAM0DADDR: file = "%O.0d", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0D: file = "%O.0d", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0D; - BRAM0EADDR: file = "%O.0e", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0E: file = "%O.0e", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0E; - BRAM0FADDR: file = "%O.0f", start = __BANKRAMSTART__ - 2, size = $0002; - BRAM0F: file = "%O.0f", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0F; + BRAM0AADDR: file = "%O.0A", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0A: file = "%O.0A", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0A; + BRAM0BADDR: file = "%O.0B", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0B: file = "%O.0B", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0B; + BRAM0CADDR: file = "%O.0C", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0C: file = "%O.0C", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0C; + BRAM0DADDR: file = "%O.0D", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0D: file = "%O.0D", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0D; + BRAM0EADDR: file = "%O.0E", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0E: file = "%O.0E", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0E; + BRAM0FADDR: file = "%O.0F", start = __BANKRAMSTART__ - 2, size = $0002; + BRAM0F: file = "%O.0F", start = __BANKRAMSTART__, size = __BANKRAMSIZE__, bank = $0F; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = zp, optional = yes; + EXTZP: load = ZP, type = zp, optional = yes; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; - STARTUP: load = MAIN, type = ro; - LOWCODE: load = MAIN, 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; - ONCE: load = MAIN, type = ro, define = yes; - BSS: load = BSS, type = bss, define = yes; -# BRAM00ADDR: load = BRAM00ADDR, type = ro, optional = yes; -# BANKRAM00: load = BRAM00, type = rw, define = yes, optional = yes; - BRAM01ADDR: load = BRAM01ADDR, type = ro, optional = yes; - BANKRAM01: load = BRAM01, type = rw, define = yes, optional = yes; - BRAM02ADDR: load = BRAM02ADDR, type = ro, optional = yes; - BANKRAM02: load = BRAM02, type = rw, define = yes, optional = yes; - BRAM03ADDR: load = BRAM03ADDR, type = ro, optional = yes; - BANKRAM03: load = BRAM03, type = rw, define = yes, optional = yes; - BRAM04ADDR: load = BRAM04ADDR, type = ro, optional = yes; - BANKRAM04: load = BRAM04, type = rw, define = yes, optional = yes; - BRAM05ADDR: load = BRAM05ADDR, type = ro, optional = yes; - BANKRAM05: load = BRAM05, type = rw, define = yes, optional = yes; - BRAM06ADDR: load = BRAM06ADDR, type = ro, optional = yes; - BANKRAM06: load = BRAM06, type = rw, define = yes, optional = yes; - BRAM07ADDR: load = BRAM07ADDR, type = ro, optional = yes; - BANKRAM07: load = BRAM07, type = rw, define = yes, optional = yes; - BRAM08ADDR: load = BRAM08ADDR, type = ro, optional = yes; - BANKRAM08: load = BRAM08, type = rw, define = yes, optional = yes; - BRAM09ADDR: load = BRAM09ADDR, type = ro, optional = yes; - BANKRAM09: load = BRAM09, type = rw, define = yes, optional = yes; - BRAM0AADDR: load = BRAM0AADDR, type = ro, optional = yes; - BANKRAM0A: load = BRAM0A, type = rw, define = yes, optional = yes; - BRAM0BADDR: load = BRAM0BADDR, type = ro, optional = yes; - BANKRAM0B: load = BRAM0B, type = rw, define = yes, optional = yes; - BRAM0CADDR: load = BRAM0CADDR, type = ro, optional = yes; - BANKRAM0C: load = BRAM0C, type = rw, define = yes, optional = yes; - BRAM0DADDR: load = BRAM0DADDR, type = ro, optional = yes; - BANKRAM0D: load = BRAM0D, type = rw, define = yes, optional = yes; - BRAM0EADDR: load = BRAM0EADDR, type = ro, optional = yes; - BANKRAM0E: load = BRAM0E, type = rw, define = yes, optional = yes; - BRAM0FADDR: load = BRAM0FADDR, type = ro, optional = yes; - BANKRAM0F: load = BRAM0F, type = rw, define = yes, optional = yes; + INIT: load = MAIN, type = rw, optional = yes; + ONCE: load = MAIN, type = ro, define = yes; + BSS: load = BSS, type = bss, define = yes; + BRAM01ADDR: load = BRAM01ADDR, type = ro, optional = yes; + BANKRAM01: load = BRAM01, type = rw, optional = yes, define = yes; + BRAM02ADDR: load = BRAM02ADDR, type = ro, optional = yes; + BANKRAM02: load = BRAM02, type = rw, optional = yes, define = yes; + BRAM03ADDR: load = BRAM03ADDR, type = ro, optional = yes; + BANKRAM03: load = BRAM03, type = rw, optional = yes, define = yes; + BRAM04ADDR: load = BRAM04ADDR, type = ro, optional = yes; + BANKRAM04: load = BRAM04, type = rw, optional = yes, define = yes; + BRAM05ADDR: load = BRAM05ADDR, type = ro, optional = yes; + BANKRAM05: load = BRAM05, type = rw, optional = yes, define = yes; + BRAM06ADDR: load = BRAM06ADDR, type = ro, optional = yes; + BANKRAM06: load = BRAM06, type = rw, optional = yes, define = yes; + BRAM07ADDR: load = BRAM07ADDR, type = ro, optional = yes; + BANKRAM07: load = BRAM07, type = rw, optional = yes, define = yes; + BRAM08ADDR: load = BRAM08ADDR, type = ro, optional = yes; + BANKRAM08: load = BRAM08, type = rw, optional = yes, define = yes; + BRAM09ADDR: load = BRAM09ADDR, type = ro, optional = yes; + BANKRAM09: load = BRAM09, type = rw, optional = yes, define = yes; + BRAM0AADDR: load = BRAM0AADDR, type = ro, optional = yes; + BANKRAM0A: load = BRAM0A, type = rw, optional = yes, define = yes; + BRAM0BADDR: load = BRAM0BADDR, type = ro, optional = yes; + BANKRAM0B: load = BRAM0B, type = rw, optional = yes, define = yes; + BRAM0CADDR: load = BRAM0CADDR, type = ro, optional = yes; + BANKRAM0C: load = BRAM0C, type = rw, optional = yes, define = yes; + BRAM0DADDR: load = BRAM0DADDR, type = ro, optional = yes; + BANKRAM0D: load = BRAM0D, type = rw, optional = yes, define = yes; + BRAM0EADDR: load = BRAM0EADDR, type = ro, optional = yes; + BANKRAM0E: load = BRAM0E, type = rw, optional = yes, define = yes; + BRAM0FADDR: load = BRAM0FADDR, type = ro, optional = yes; + BANKRAM0F: load = BRAM0F, type = rw, optional = yes, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/cx16.cfg b/cfg/cx16.cfg index 72fc2fe91..4b6025fb6 100644 --- a/cfg/cx16.cfg +++ b/cfg/cx16.cfg @@ -16,17 +16,17 @@ MEMORY { } SEGMENTS { ZEROPAGE: load = ZP, type = zp; - EXTZP: load = ZP, type = zp, optional = yes; + EXTZP: load = ZP, type = zp, optional = yes; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; - STARTUP: load = MAIN, type = ro; - LOWCODE: load = MAIN, 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; - ONCE: load = MAIN, type = ro, define = yes; - BSS: load = BSS, type = bss, define = yes; + 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, From bb3a2db5a03fb258d8994b70916680b95e746056 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 21 Feb 2021 15:44:59 -0500 Subject: [PATCH 1877/2161] Fixed an ambiguous statement about CONDES segments. --- doc/ld65.sgml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index c2e990dc2..538948fc0 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -1009,7 +1009,8 @@ The <tt/CONDES/ feature has several attributes: <tag><tt>segment</tt></tag> This attribute tells the linker into which segment the table should be - placed. If the segment does not exist, it is created. + placed. If the segment does not exist in any object file, it is created + in the final object code. <tag><tt>type</tt></tag> @@ -1058,7 +1059,7 @@ The <tt/CONDES/ feature has several attributes: Without specifying the <tt/CONDES/ feature, the linker will not create any tables, even if there are <tt/condes/ entries in the object files. -For more information see the <tt/.CONDES/ command in the <url +For more information, see the <tt/.CONDES/ command in the <url url="ca65.html" name="ca65 manual">. From eadaf2fef845afdc6b8540af4c558444d8c7315d Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 21 Feb 2021 16:43:46 +0800 Subject: [PATCH 1878/2161] Fixed deferred post-inc and post-dec in unevaluated context such as 'sizeof(i++)'. --- src/cc65/expr.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 751014af3..67d64e138 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -376,6 +376,9 @@ void DoneDeferredOps (void) static void DeferInc (const ExprDesc* Expr) /* Defer the post-inc and put it in a queue */ { + if (ED_IsUneval (Expr)) { + return; + } DeferredOp* Op = xmalloc (sizeof (DeferredOp)); memcpy (&Op->Expr, Expr, sizeof (ExprDesc)); Op->OpType = DOT_INC; @@ -387,6 +390,9 @@ static void DeferInc (const ExprDesc* Expr) static void DeferDec (const ExprDesc* Expr) /* Defer the post-dec and put it in a queue */ { + if (ED_IsUneval (Expr)) { + return; + } DeferredOp* Op = xmalloc (sizeof (DeferredOp)); memcpy (&Op->Expr, Expr, sizeof (ExprDesc)); Op->OpType = DOT_DEC; From 24985f1b33936841350322a3f7aa580f53c6a587 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 22 Feb 2021 12:00:10 +0800 Subject: [PATCH 1879/2161] Added testcase for the "deferred ops in unevaluated context" bug. --- test/val/uneval.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 test/val/uneval.c diff --git a/test/val/uneval.c b/test/val/uneval.c new file mode 100644 index 000000000..50e00973a --- /dev/null +++ b/test/val/uneval.c @@ -0,0 +1,46 @@ +/* + Copyright 2021, 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 deferred operations in unevaluated context resulted from 'sizeof' and + short-circuited code-paths in AND, OR and tenary operations. + + https://github.com/cc65/cc65/issues/1406 +*/ + +#include <stdio.h> + +int main(void) +{ + int i = 0; + int j = 0; + + sizeof(i++ | j--); + 0 && (i++ | j--); + 1 || (i++ | j--); + 0 ? i++ | j-- : 0; + 1 ? 0 : i++ | j--; + + if (i != 0 || j != 0) { + printf("i = %d, j = %d\n", i, j); + printf("Failures: %d\n", i - j); + } + return i - j; +} From 81d6321cd7a725009f4537d990d3f1156b8c8a51 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 29 Oct 2020 21:12:48 +0800 Subject: [PATCH 1880/2161] Fixed internal representation of calculated constant results. Minor clean-up. --- src/cc65/expr.c | 66 ++++++++++++++++++++++++++++++++++++++------- src/cc65/testexpr.c | 2 +- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 67d64e138..4f8a09bec 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -251,6 +251,42 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static void LimitExprValue (ExprDesc* Expr) +/* Limit the constant value of the expression to the range of its type */ +{ + switch (GetUnderlyingTypeCode (Expr->Type)) { + case T_INT: + case T_SHORT: + Expr->IVal = (int16_t)Expr->IVal; + break; + + case T_UINT: + case T_USHORT: + case T_PTR: + case T_ARRAY: + Expr->IVal = (uint16_t)Expr->IVal; + break; + + case T_LONG: + case T_ULONG: + /* No need to do anything */ + break; + + case T_SCHAR: + Expr->IVal = (int8_t)Expr->IVal; + break; + + case T_UCHAR: + Expr->IVal = (uint8_t)Expr->IVal; + break; + + default: + Internal ("hie_internal: constant result type %s\n", GetFullTypeName (Expr->Type)); + } +} + + + static const GenDesc* FindGen (token_t Tok, const GenDesc* Table) /* Find a token in a generator table */ { @@ -2165,15 +2201,19 @@ static void UnaryOp (ExprDesc* Expr) ED_MakeConstAbsInt (Expr, 1); } - /* Check for a constant expression */ + /* Check for a constant numeric expression */ if (ED_IsConstAbs (Expr)) { - /* Value is constant */ + /* Value is numeric */ switch (Tok) { case TOK_MINUS: Expr->IVal = -Expr->IVal; break; case TOK_PLUS: break; case TOK_COMP: Expr->IVal = ~Expr->IVal; break; default: Internal ("Unexpected token: %d", Tok); } + + /* Limit the calculated value to the range of its type */ + LimitExprValue (Expr); + } else { /* Value is not constant */ LoadExpr (CF_NONE, Expr); @@ -2224,7 +2264,7 @@ void hie10 (ExprDesc* Expr) NextToken (); BoolExpr (hie10, Expr); if (ED_IsConstAbs (Expr)) { - /* Constant expression */ + /* Constant numeric expression */ Expr->IVal = !Expr->IVal; } else if (ED_IsAddrExpr (Expr)) { /* Address != NULL, so !Address == 0 */ @@ -2515,6 +2555,9 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */ } } + /* Limit the calculated value to the range of its type */ + LimitExprValue (Expr); + } else if (lconst && (Gen->Flags & GEN_COMM) && !rconst) { /* If the LHS constant is an int that fits into an unsigned char, change the ** codegen type to unsigned char. If the RHS is also an unsigned char, then @@ -3048,6 +3091,9 @@ static void parseadd (ExprDesc* Expr) /* Integer addition */ Expr->IVal += Expr2.IVal; typeadjust (Expr, &Expr2, 1); + + /* Limit the calculated value to the range of its type */ + LimitExprValue (Expr); } else { /* OOPS */ Error ("Invalid operands for binary operator '+'"); @@ -3231,7 +3277,7 @@ static void parseadd (ExprDesc* Expr) ED_FinalizeRValLoad (Expr); } - /* Condition codes not set */ + /* Condition code not set */ ED_MarkAsUntested (Expr); } @@ -3315,14 +3361,14 @@ static void parsesub (ExprDesc* Expr) /* Integer subtraction */ typeadjust (Expr, &Expr2, 1); Expr->IVal -= Expr2.IVal; + + /* Limit the calculated value to the range of its type */ + LimitExprValue (Expr); } else { /* OOPS */ Error ("Invalid operands for binary operator '-'"); } - /* Result is constant, condition codes not set */ - ED_MarkAsUntested (Expr); - } else { /* Left hand side is not constant, right hand side is. @@ -3364,8 +3410,6 @@ static void parsesub (ExprDesc* Expr) /* Result is an rvalue in the primary register */ ED_FinalizeRValLoad (Expr); - ED_MarkAsUntested (Expr); - } } else { @@ -3418,8 +3462,10 @@ static void parsesub (ExprDesc* Expr) /* Result is an rvalue in the primary register */ ED_FinalizeRValLoad (Expr); - ED_MarkAsUntested (Expr); } + + /* Condition code not set */ + ED_MarkAsUntested (Expr); } diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index eefaeb74a..02ee98dae 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -63,7 +63,7 @@ unsigned Test (unsigned Label, int Invert) /* Read a boolean expression */ BoolExpr (hie0, &Expr); - /* Check for a constant expression */ + /* Check for a constant numeric expression */ if (ED_IsConstAbs (&Expr)) { /* Append deferred inc/dec at sequence point */ From da4cc08b7812c66097aee74ba6c73c50d3117036 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 3 Feb 2021 12:22:46 +0800 Subject: [PATCH 1881/2161] Moved and improved test case for Issue #1310. --- test/{todo => val}/bug1310.c | 8 ++++++++ 1 file changed, 8 insertions(+) rename test/{todo => val}/bug1310.c (90%) diff --git a/test/todo/bug1310.c b/test/val/bug1310.c similarity index 90% rename from test/todo/bug1310.c rename to test/val/bug1310.c index 936145928..dc9e47b5c 100644 --- a/test/todo/bug1310.c +++ b/test/val/bug1310.c @@ -68,6 +68,14 @@ int main (void) failures++; } + if (-32768U != 32768U) { + fprintf (stderr, "Expected -32768U == 32768U, got: %ld\n", (long)-32768U); + failures++; + } + if (~32767U != 32768U) { + fprintf (stderr, "Expected ~32767U == 32768U, got: %ld\n", (long)~32767U); + failures++; + } printf ("failures: %u\n", failures); return failures; } From f1c715c4559f9033352e51d3b75358463ac9c864 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 7 Feb 2021 11:35:36 +0800 Subject: [PATCH 1882/2161] Fixed a bug that pointer subtraction results from two absolute addresses are calculated as unsigned long. --- src/cc65/expr.c | 2 +- test/val/bug1310.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 4f8a09bec..30eda8707 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3353,7 +3353,7 @@ static void parsesub (ExprDesc* Expr) Error ("Incompatible pointer types"); } else { Expr->IVal = (Expr->IVal - Expr2.IVal) / - CheckedPSizeOf (lhst); + (long)CheckedPSizeOf (lhst); } /* Operate on pointers, result type is an integer */ Expr->Type = type_int; diff --git a/test/val/bug1310.c b/test/val/bug1310.c index dc9e47b5c..306c91fb6 100644 --- a/test/val/bug1310.c +++ b/test/val/bug1310.c @@ -76,6 +76,12 @@ int main (void) fprintf (stderr, "Expected ~32767U == 32768U, got: %ld\n", (long)~32767U); failures++; } + + if ((long*)0x1000 - (long*)0x2000 >= 0) { + fprintf (stderr, "Expected (long*)0x1000 - (long*)0x2000 < 0, got: %ld\n", (long*)0x1000 - (long*)0x2000); + failures++; + } printf ("failures: %u\n", failures); + return failures; } From d628772cd1c7f1f72cdfc1335dc11eb42480fbe6 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 22 Feb 2021 23:46:26 +0800 Subject: [PATCH 1883/2161] Fixed signed char type comparison with unsigned numeric constants. --- src/cc65/expr.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 30eda8707..083d1dc99 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -2845,7 +2845,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ } /* Determine the type of the operation. */ - if (IsTypeChar (Expr->Type) && rconst) { + if (IsTypeChar (Expr->Type) && rconst && RightSigned) { /* Left side is unsigned char, right side is constant. ** Determine the minimum and maximum values @@ -2858,20 +2858,6 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ LeftMin = 0; LeftMax = 255; } - /* An integer value is always represented as a signed in the - ** ExprDesc structure. This may lead to false results below, - ** if it is actually unsigned, but interpreted as signed - ** because of the representation. Fortunately, in this case, - ** the actual value doesn't matter, since it's always greater - ** than what can be represented in a char. So correct the - ** value accordingly. - */ - if (!RightSigned && Expr2.IVal < 0) { - /* Correct the value so it is an unsigned. It will then - ** anyway match one of the cases below. - */ - Expr2.IVal = LeftMax + 1; - } /* Comparing a char against a constant may have a constant ** result. Please note: It is not possible to remove the code @@ -2951,7 +2937,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ if (rconst) { flags |= CF_FORCECHAR; } - if (!LeftSigned) { + if (!LeftSigned || !RightSigned) { flags |= CF_UNSIGNED; } } else { @@ -2959,11 +2945,11 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ flags |= g_typeadjust (ltype, rtype); } - /* If the left side is an unsigned and the right is a constant, - ** we may be able to change the compares to something more + /* If the comparison is made as unsigned types and the right is a + ** constant, we may be able to change the compares to something more ** effective. */ - if (!LeftSigned && rconst) { + if ((!LeftSigned || !RightSigned) && rconst) { switch (Tok) { From 6f5ad518165085d2b6fe4d20cba3cefc229bb656 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 23 Feb 2021 13:47:39 +0800 Subject: [PATCH 1884/2161] Added testcase for Issue #1408. --- test/val/bug1408.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 test/val/bug1408.c diff --git a/test/val/bug1408.c b/test/val/bug1408.c new file mode 100644 index 000000000..8ecc1be68 --- /dev/null +++ b/test/val/bug1408.c @@ -0,0 +1,41 @@ +/* Bug #1408: Signed char type comparisons with unsigned numeric constants */ + +#include <stdio.h> + +static int failures = 0; +static signed char x = -1; + +int main(void) +{ + if (!(x > -2u)) { + printf("x > -2u should be true\n"); + ++failures; + } + if (!(x > 0u)) { + printf("x > 0u should be true\n"); + ++failures; + } + if (!(x > 255u)) { + printf("x > 255u should be true\n"); + ++failures; + } + + if (!(-2u < x)) { + printf("-2u < x should be true\n"); + ++failures; + } + if (!(0u < x)) { + printf("0u < x should be true\n"); + ++failures; + } + if (!(255u < x)) { + printf("255u < x should be true\n"); + ++failures; + } + + if (failures != 0) { + printf("Failures: %d\n", failures); + } + + return failures; +} From ea0c634e12cb122113a9b97eb66a0efbda082aa6 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 23 Feb 2021 17:39:02 +0800 Subject: [PATCH 1885/2161] Improved codegen for unsigned char type comparison with numeric constants. --- 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 083d1dc99..66c633d2e 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -2845,7 +2845,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ } /* Determine the type of the operation. */ - if (IsTypeChar (Expr->Type) && rconst && RightSigned) { + if (IsTypeChar (Expr->Type) && rconst && (!LeftSigned || RightSigned)) { /* Left side is unsigned char, right side is constant. ** Determine the minimum and maximum values @@ -2923,7 +2923,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ ** since the right side constant is in a valid range. */ flags |= (CF_CHAR | CF_FORCECHAR); - if (!LeftSigned) { + if (!LeftSigned || !RightSigned) { flags |= CF_UNSIGNED; } From f2eed38fc8e05f5f46165571c408496f1dda3200 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 15 Feb 2021 09:50:40 +0800 Subject: [PATCH 1886/2161] Fixed expression type of the result of numeric constant comparison. --- src/cc65/expr.c | 3 +++ src/cc65/exprdesc.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 66c633d2e..c932ba622 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -2793,6 +2793,9 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ } } + /* Get rid of unwanted flags */ + ED_MakeConstBool (Expr, Expr->IVal); + /* If the result is constant, this is suspicious when not in ** preprocessor mode. */ diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index e82d0fafc..f5d8cd779 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -261,7 +261,7 @@ ExprDesc* ED_MakeConstBool (ExprDesc* Expr, long Value) { Expr->Sym = 0; Expr->Type = type_bool; - Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_HAVE_MARKS); + Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_MASK_KEEP_MAKE); Expr->Name = 0; Expr->IVal = Value; Expr->FVal = FP_D_Make (0.0); From 3caceb8174110110ba5b0c4c45a885d8c1c5711b Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 15 Feb 2021 17:30:17 +0800 Subject: [PATCH 1887/2161] Fixed result type in certain contant expression addition cases. --- src/cc65/expr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index c932ba622..09a7a1f39 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3171,6 +3171,9 @@ static void parseadd (ExprDesc* Expr) flags = CF_INT; } + /* Array and function types must be converted to pointer types */ + Expr->Type = PtrConversion (Expr->Type); + /* Result is an rvalue in primary register */ ED_FinalizeRValLoad (Expr); } From 02e52fe24df3fabc16c4eadb452a2839d0feefc1 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 1 Mar 2021 22:33:12 +0100 Subject: [PATCH 1888/2161] Fix many bugs --- include/telestrat.h | 2 ++ libsrc/telestrat/cclear.s | 4 +-- libsrc/telestrat/chline.s | 40 +++++++++++++-------- libsrc/telestrat/clrscr.s | 27 ++++++++------- libsrc/telestrat/cputc.s | 67 ++++++++++++++++++++++++++++++------ libsrc/telestrat/gotox.s | 4 --- libsrc/telestrat/gotoxy.s | 17 +++------ libsrc/telestrat/textcolor.s | 3 +- 8 files changed, 109 insertions(+), 55 deletions(-) diff --git a/include/telestrat.h b/include/telestrat.h index a4648a3dc..5ad1d3bef 100644 --- a/include/telestrat.h +++ b/include/telestrat.h @@ -85,6 +85,8 @@ #define CH_LTEE '+' #define CH_RTEE '+' #define CH_CROSS '+' +#define CH_HLINE '-' +#define CH_VLINE '|' #define CH_CURS_UP 11 #define CH_CURS_DOWN 10 #define CH_CURS_LEFT 8 diff --git a/libsrc/telestrat/cclear.s b/libsrc/telestrat/cclear.s index a32919962..b9fce4708 100644 --- a/libsrc/telestrat/cclear.s +++ b/libsrc/telestrat/cclear.s @@ -6,7 +6,7 @@ ; .export _cclearxy, _cclear - .import update_adscr + .import update_adscr, display_conio .importzp tmp1 .import popax @@ -27,7 +27,7 @@ _cclear: @L1: stx tmp1 ; Save X lda #' ' ; Erase current char - BRK_TELEMON XFWR + jsr display_conio ldx tmp1 dex bne @L1 diff --git a/libsrc/telestrat/chline.s b/libsrc/telestrat/chline.s index 6ead10eee..91f3bdc9f 100644 --- a/libsrc/telestrat/chline.s +++ b/libsrc/telestrat/chline.s @@ -1,22 +1,34 @@ ; -; jede jede@oric.org 2018-04-17 -; - +; void chlinexy (unsigned char x, unsigned char y, unsigned char length); ; void chline (unsigned char length); ; - .export _chline + .export _chlinexy, _chline + + .import rvs, display_conio, update_adscr + .import popax + .include "telestrat.inc" - .include "zeropage.inc" -.proc _chline - sta tmp1 -@loop: - lda #'-' ; horizontal line screen code - BRK_TELEMON XWR0 ; macro send char to screen (channel 0 in telemon terms) - dec tmp1 - bne @loop - rts -.endproc +_chlinexy: + pha ; Save the length + jsr popax ; Get X and Y + sta SCRY ; Store Y + stx SCRX ; Store X + jsr update_adscr + pla ; Restore the length and run into _chline + +_chline: + tax ; Is the length zero? + beq @L9 ; Jump if done +@L1: + lda #'-' ; Horizontal line screen code + ora rvs + + jsr display_conio + +@L2: dex + bne @L1 +@L9: rts diff --git a/libsrc/telestrat/clrscr.s b/libsrc/telestrat/clrscr.s index 39c2f7724..363aa2761 100644 --- a/libsrc/telestrat/clrscr.s +++ b/libsrc/telestrat/clrscr.s @@ -3,7 +3,7 @@ ; .export _clrscr - .import OLD_CHARCOLOR, OLD_BGCOLOR + .import OLD_CHARCOLOR, OLD_BGCOLOR, BGCOLOR, CHARCOLOR .include "telestrat.inc" @@ -23,22 +23,25 @@ ; reset prompt position - lda #<(SCREEN+40) - sta ADSCRL - lda #>(SCREEN+40) - sta ADSCRH + lda #<(SCREEN) + sta ADSCR + lda #>(SCREEN) + sta ADSCR+1 + + lda #$00 + sta SCRDY ; reset display position - ldx #$01 + ldx #$00 stx SCRY - dex stx SCRX - ; At this step X is equal to $00 - dex - ; At this step X is equal to $FF - stx OLD_BGCOLOR + stx OLD_BGCOLOR ; black + stx BGCOLOR + + ldx #$07 ; white stx OLD_CHARCOLOR - + stx CHARCOLOR + rts .endproc diff --git a/libsrc/telestrat/cputc.s b/libsrc/telestrat/cputc.s index 38f8af84b..a1ab145c2 100644 --- a/libsrc/telestrat/cputc.s +++ b/libsrc/telestrat/cputc.s @@ -4,24 +4,50 @@ ; void cputc (char c); ; - .export _cputc, CHARCOLOR, OLD_CHARCOLOR, BGCOLOR, OLD_BGCOLOR + .export _cputc, _cputcxy, display_conio, CHARCOLOR, OLD_CHARCOLOR, BGCOLOR, OLD_BGCOLOR + + + .import update_adscr + .import popax .include "telestrat.inc" +_cputcxy: + pha ; Save C + jsr popax ; Get X and Y + sta SCRY ; Store Y + stx SCRX ; Store X + jsr update_adscr + pla + .proc _cputc + cmp #$0D + bne @not_CR + ldy #$00 + sty SCRX + rts +@not_CR: + cmp #$0A + bne @not_LF + + inc SCRY + jmp update_adscr + + +@not_LF: + ldx CHARCOLOR cpx OLD_CHARCOLOR beq do_not_change_color_foreground stx OLD_CHARCOLOR ; Store CHARCOLOR into OLD_CHARCOLOR - dec SCRX - dec SCRX pha txa ; Swap X to A because, X contains CHARCOLOR - BRK_TELEMON XFWR ; Change color on the screen (foreground) - inc SCRX + + jsr display_conio + pla do_not_change_color_foreground: @@ -31,18 +57,38 @@ do_not_change_color_foreground: stx OLD_BGCOLOR - dec SCRX ; Dec SCRX in order to place attribute before the right position - pha txa ; Swap X to A because, X contains BGCOLOR - ORA #%00010000 ; Add 16 because background color is an attribute between 16 and 23. 17 is red background for example - BRK_TELEMON XFWR ; Change color on the screen (background) + ora #%00010000 ; Add 16 because background color is an attribute between 16 and 23. 17 is red background for example + + jsr display_conio pla do_not_change_color: - BRK_TELEMON XFWR ; Macro send char to screen (channel 0) + ; it continues to display_conio + +.endproc + + + +.proc display_conio + ldy SCRX + sta (ADSCR),y + iny + cpy #SCREEN_XSIZE + bne @no_inc + ldy #$00 + sty SCRX + + jmp update_adscr + +@no_inc: + sty SCRX rts .endproc + + + .bss CHARCOLOR: .res 1 @@ -52,3 +98,4 @@ BGCOLOR: .res 1 OLD_BGCOLOR: .res 1 + diff --git a/libsrc/telestrat/gotox.s b/libsrc/telestrat/gotox.s index 7a172071c..72004bc0a 100644 --- a/libsrc/telestrat/gotox.s +++ b/libsrc/telestrat/gotox.s @@ -8,9 +8,5 @@ .proc _gotox sta SCRX - - lda #$FF - sta OLD_CHARCOLOR - sta OLD_BGCOLOR rts .endproc diff --git a/libsrc/telestrat/gotoxy.s b/libsrc/telestrat/gotoxy.s index 3387efe40..ea7ed5623 100644 --- a/libsrc/telestrat/gotoxy.s +++ b/libsrc/telestrat/gotoxy.s @@ -29,30 +29,23 @@ gotoxy: jsr popa ; Get Y .endproc .proc update_adscr -; Force to set again color if cursor moves -; $FF is used because we know that it's impossible to have this value with a color -; It prevents a bug : If bgcolor or textcolor is set to black for example with no char displays, -; next cputsxy will not set the attribute if y coordinate changes - lda #$FF - sta OLD_CHARCOLOR - sta OLD_BGCOLOR lda #<SCREEN - sta ADSCRL + sta ADSCR lda #>SCREEN - sta ADSCRH + sta ADSCR+1 ldy SCRY beq out loop: - lda ADSCRL + lda ADSCR clc adc #SCREEN_XSIZE bcc skip - inc ADSCRH + inc ADSCR+1 skip: - sta ADSCRL + sta ADSCR dey bne loop out: diff --git a/libsrc/telestrat/textcolor.s b/libsrc/telestrat/textcolor.s index 7d16c9e19..d851aaaab 100644 --- a/libsrc/telestrat/textcolor.s +++ b/libsrc/telestrat/textcolor.s @@ -2,12 +2,13 @@ ; .export _textcolor - .import CHARCOLOR + .import CHARCOLOR, OLD_CHARCOLOR .include "telestrat.inc" .proc _textcolor ldx CHARCOLOR ; Get previous color sta CHARCOLOR + stx OLD_CHARCOLOR txa ; Return previous color rts .endproc From 256b22f1c7017f5f30c3e6046cf4e641825788ef Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 1 Mar 2021 22:36:09 +0100 Subject: [PATCH 1889/2161] Add bordercolor and cvline --- libsrc/telestrat/bordercolor.s | 15 ++++++++++++++ libsrc/telestrat/cvline.s | 36 ++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 libsrc/telestrat/bordercolor.s create mode 100644 libsrc/telestrat/cvline.s diff --git a/libsrc/telestrat/bordercolor.s b/libsrc/telestrat/bordercolor.s new file mode 100644 index 000000000..7055e6ba9 --- /dev/null +++ b/libsrc/telestrat/bordercolor.s @@ -0,0 +1,15 @@ +; +; Ullrich von Bassewitz, 06.08.1998 +; +; unsigned char __fastcall__ bordercolor (unsigned char color); +; + + + .export _bordercolor + + .include "telestrat.inc" + +_bordercolor: + ; Nothing to do + ; Oric can't handle his border + rts \ No newline at end of file diff --git a/libsrc/telestrat/cvline.s b/libsrc/telestrat/cvline.s new file mode 100644 index 000000000..159eb9d27 --- /dev/null +++ b/libsrc/telestrat/cvline.s @@ -0,0 +1,36 @@ +; +; Ullrich von Bassewitz, 2003-04-13 +; +; void cvlinexy (unsigned char x, unsigned char y, unsigned char length); +; void cvline (unsigned char length); +; + + .export _cvlinexy, _cvline + + .import rvs, display_conio, update_adscr + + .import popax + + .include "telestrat.inc" + + +_cvlinexy: + pha ; Save the length + jsr popax ; Get X and Y + sta SCRY ; Store Y + stx SCRX ; Store X + jsr update_adscr + pla ; Restore the length and run into _cvline + +_cvline: + tax ; Is the length zero? + beq @L9 ; Jump if done +@L1: + lda #'|' + ora rvs + jsr display_conio +@L2: dex + bne @L1 +@L9: rts + + From 8ec6d28f92d50703f365fac57fa4b95d12f39c74 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 1 Mar 2021 22:44:06 +0100 Subject: [PATCH 1890/2161] Revert read.s --- libsrc/telestrat/read.s | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/libsrc/telestrat/read.s b/libsrc/telestrat/read.s index 0782c4d21..76de9d0ac 100644 --- a/libsrc/telestrat/read.s +++ b/libsrc/telestrat/read.s @@ -8,33 +8,21 @@ .include "zeropage.inc" .include "telestrat.inc" - .include "fcntl.inc" ;int read (int fd, void* buf, unsigned count); .proc _read - sta ptr1 ; count - stx ptr1+1 ; count - jsr popax ; get buf + sta ptr1 ; count + stx ptr1+1 ; count + jsr popax ; get buf sta PTR_READ_DEST stx PTR_READ_DEST+1 - sta ptr2 ; in order to calculate nb of bytes read + sta ptr2 ; in order to calculate nb of bytes read stx ptr2+1 ; - jsr popax ; fp pointer don't care in this version - cpx #$00 - bne @is_not_stdin - cmp #STDIN_FILENO - bne @is_not_stdin - ; stdin -@L1: - BRK_TELEMON XRD0 ; waits until key is pressed - bcs @L1 - - rts + ; jsr popax ; fp pointer don't care in this version -@is_not_stdin: lda ptr1 ; ldy ptr1+1 ; BRK_TELEMON XFREAD ; calls telemon30 routine From abef6566e7feaac9287a75b2a3bc177dc7fa3c3f Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 1 Mar 2021 22:45:05 +0100 Subject: [PATCH 1891/2161] Add revers.s --- libsrc/telestrat/revers.s | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 libsrc/telestrat/revers.s diff --git a/libsrc/telestrat/revers.s b/libsrc/telestrat/revers.s new file mode 100644 index 000000000..ad3e1f909 --- /dev/null +++ b/libsrc/telestrat/revers.s @@ -0,0 +1,37 @@ +; +; Ullrich von Bassewitz, 07.08.1998 +; +; unsigned char revers (unsigned char onoff); +; + + .export _revers + .export rvs + +; ------------------------------------------------------------------------ +; + +.code +.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 + +; ------------------------------------------------------------------------ +; + +.bss +rvs: .res 1 + + From 185c4510005f974980a4725d03c097b0c5d244f5 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 1 Mar 2021 23:19:30 +0100 Subject: [PATCH 1892/2161] Fix cputdirect --- libsrc/telestrat/cputc.s | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libsrc/telestrat/cputc.s b/libsrc/telestrat/cputc.s index a1ab145c2..f7bf5e2b6 100644 --- a/libsrc/telestrat/cputc.s +++ b/libsrc/telestrat/cputc.s @@ -4,7 +4,7 @@ ; void cputc (char c); ; - .export _cputc, _cputcxy, display_conio, CHARCOLOR, OLD_CHARCOLOR, BGCOLOR, OLD_BGCOLOR + .export _cputc, _cputcxy, cputdirect, display_conio, CHARCOLOR, OLD_CHARCOLOR, BGCOLOR, OLD_BGCOLOR .import update_adscr @@ -12,6 +12,7 @@ .include "telestrat.inc" +cputdirect: _cputcxy: pha ; Save C jsr popax ; Get X and Y @@ -69,9 +70,8 @@ do_not_change_color: .endproc - - .proc display_conio + ; This routine is used to displays char on screen ldy SCRX sta (ADSCR),y iny From cdbe23c351658d2e2f874ee8dfcbb70e87ebc6f3 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 1 Mar 2021 23:21:58 +0100 Subject: [PATCH 1893/2161] Fix missing new line in bordercolr --- libsrc/telestrat/bordercolor.s | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libsrc/telestrat/bordercolor.s b/libsrc/telestrat/bordercolor.s index 7055e6ba9..9e49b057f 100644 --- a/libsrc/telestrat/bordercolor.s +++ b/libsrc/telestrat/bordercolor.s @@ -12,4 +12,5 @@ _bordercolor: ; Nothing to do ; Oric can't handle his border - rts \ No newline at end of file + rts + From 2aad72af90e9cc6b4bfc6c444233233433589395 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 15 Feb 2021 18:37:01 +0800 Subject: [PATCH 1894/2161] Removed trailing whitespaces. --- src/cc65/assignment.c | 2 +- src/cc65/codeopt.c | 2 +- src/cc65/codeoptutil.c | 10 +++++----- src/cc65/coptind.c | 7 ++----- src/cc65/coptptrload.h | 2 +- src/cc65/declare.c | 4 ++-- src/cc65/exprdesc.h | 6 +++--- src/cc65/hexval.h | 2 +- src/cc65/ident.c | 2 +- src/cc65/lineinfo.h | 4 ++-- src/cc65/loop.c | 2 +- src/cc65/pragma.c | 2 +- src/cc65/reginfo.h | 2 +- src/cc65/scanstrbuf.c | 2 +- src/cc65/shiftexpr.c | 2 +- src/cc65/symtab.c | 9 ++++----- src/cc65/testexpr.c | 2 +- src/cc65/typecmp.c | 2 +- 18 files changed, 30 insertions(+), 34 deletions(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index 09a10a642..737d059a0 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -169,7 +169,7 @@ void Assignment (ExprDesc* Expr) /* cc65 does not have full support for handling structs or unions. Since ** assigning structs is one of the more useful operations from this family, ** allow it here. - ** Note: IsClassStruct() is also true for union types. + ** Note: IsClassStruct() is also true for union types. */ if (IsClassStruct (ltype)) { /* Copy the struct or union by value */ diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 3c10183e4..29fa79d26 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -380,7 +380,7 @@ void ListOptSteps (FILE* F) /* List all optimization steps */ { unsigned I; - + fprintf (F, "any\n"); for (I = 0; I < OPTFUNC_COUNT; ++I) { if (OptFuncs[I]->Func != 0) { diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index 375fdf541..140420e97 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -678,7 +678,7 @@ void SetDontRemoveEntryFlag (LoadRegInfo* LRI) if (LRI->Flags & LI_DONT_REMOVE) { if (LRI->LoadEntry != 0) { LRI->LoadEntry->Flags |= CEF_DONT_REMOVE; - + /* If the load requires Y, then Y shouldn't be removed either */ if (LRI->LoadYEntry != 0) { LRI->LoadYEntry->Flags |= CEF_DONT_REMOVE; @@ -2562,7 +2562,7 @@ int BackupArgAfter (CodeSeg* S, BackupInfo* B, int Idx, const CodeEntry* E, Coll static int LoadAAt (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices, int After) /* Reload into A the same arg according to LoadRegInfo before or after Idx -** depending on the After param. +** depending on the After param. */ { CodeEntry* E; @@ -2582,7 +2582,7 @@ static int LoadAAt (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Ind CHECK (E != 0); O = CS_GetEntry (S, OldIdx); - + /* We only recognize opc with an arg for now, as well as a special case for ldaxysp */ if ((E->OPC != OP65_JSR || strcmp (E->Arg, "ldaxysp") == 0) && E->AM != AM65_BRA && E->AM != AM65_IMP) { @@ -2645,7 +2645,7 @@ static int LoadAAt (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Ind static int LoadXAt (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices, int After) /* Reload into X the same arg according to LoadRegInfo before or after Idx -** depending on the After param. +** depending on the After param. */ { CodeEntry* E; @@ -2744,7 +2744,7 @@ static int LoadXAt (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Ind static int LoadYAt (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Indices, int After) /* Reload into Y the same arg according to LoadRegInfo before or after Idx -** depending on the After param. +** depending on the After param. */ { CodeEntry* E; diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index f3e17fc87..a080cfb20 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -990,7 +990,7 @@ unsigned OptTransfers4 (CodeSeg* S) ** isn't used later, and we have an address mode match, we can ** replace the transfer by a load and remove the initial load. */ - if ((GetRegInfo (S, I, LoadEntry->Chg & REG_ALL) & + if ((GetRegInfo (S, I, LoadEntry->Chg & REG_ALL) & LoadEntry->Chg & REG_ALL) == 0 && (LoadEntry->AM == AM65_ABS || LoadEntry->AM == AM65_ZP || @@ -1252,7 +1252,7 @@ unsigned OptPushPop2 (CodeSeg* S) /* Go into searching mode again */ State = Searching; } - } else if ((E->Info & OF_BRA) == 0 && + } else if ((E->Info & OF_BRA) == 0 && (E->Info & OF_STORE) == 0 && E->OPC != OP65_NOP && E->OPC != OP65_TSX) { @@ -1500,14 +1500,11 @@ unsigned OptShiftBack (CodeSeg* S) (N->OPC == OP65_LSR || N->OPC == OP65_ROR) && !CE_HasLabel (N)) { - CheckStates = PSTATE_ZN; - if (N->OPC == OP65_LSR && !PStatesAreClear (E->RI->Out.PFlags, PSTATE_C)) { CheckStates |= REG_A; } - if ((GetRegInfo (S, I+2, CheckStates) & CheckStates) == 0) { /* Remove the shifts */ diff --git a/src/cc65/coptptrload.h b/src/cc65/coptptrload.h index 84d7cc19f..d4e0e2ed4 100644 --- a/src/cc65/coptptrload.h +++ b/src/cc65/coptptrload.h @@ -233,7 +233,7 @@ unsigned OptPtrLoad11 (CodeSeg* S); */ unsigned OptPtrLoad12 (CodeSeg* S); -/* Search for the sequence: +/* Search for the sequence: ** ** lda regbank+n ** ldx regbank+n+1 diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 08739f333..d952d1049 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1522,7 +1522,7 @@ static Type* ParamTypeCvt (Type* T) } else if (IsTypeFunc (T)) { Tmp = PointerTo (T); } - + if (Tmp != 0) { /* Do several fixes on qualifiers */ FixQualifiers (Tmp); @@ -1786,7 +1786,7 @@ static FuncDesc* ParseFuncDecl (void) ** 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); diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index 810d68965..e1bf3117f 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -73,7 +73,7 @@ enum { ** - ref-load doesn't change the rval/lval category of the expression, ** while rval-load converts it to an rvalue if it wasn't. ** - In practice, ref-load is unimplemented, and can be simulated with - ** adding E_ADDRESS_OF temporaily through LoadExpr + FinalizeLoad, + ** adding E_ADDRESS_OF temporaily through LoadExpr + FinalizeLoad, ** whilst val-load is done with LoadExpr + FinalizeRValLoad. ** ** E_LOC_NONE -- ref-load -> + E_LOADED (int rvalue) @@ -142,7 +142,7 @@ enum { ** than it are usually consided "side-effects" in this regard. ** - The compiler front end cannot know things determined by the linker, ** such as the actual address of an object with static storage. What it - ** can know is categorized as "compiler-known" here. + ** can know is categorized as "compiler-known" here. ** - The concept "immutable" here means that once something is determined ** (not necessarily by the compiler), it will never change. This is not ** the same meaning as the "constant" word in the C standard. @@ -299,7 +299,7 @@ INLINE int ED_IsLocExpr (const ExprDesc* Expr) #if defined(HAVE_INLINE) INLINE int ED_IsLocLiteral (const ExprDesc* Expr) /* Return true if the expression is a string from the literal pool */ -{ +{ return (Expr->Flags & E_MASK_LOC) == E_LOC_LITERAL; } #else diff --git a/src/cc65/hexval.h b/src/cc65/hexval.h index 0361ee0cf..68ea5e40f 100644 --- a/src/cc65/hexval.h +++ b/src/cc65/hexval.h @@ -45,7 +45,7 @@ unsigned HexVal (int C); -/* Convert a hex digit into a value. The function will emit an error for +/* Convert a hex digit into a value. The function will emit an error for ** invalid hex digits. */ diff --git a/src/cc65/ident.c b/src/cc65/ident.c index 7748095c7..dc59c4868 100644 --- a/src/cc65/ident.c +++ b/src/cc65/ident.c @@ -35,7 +35,7 @@ /* common */ #include "chartype.h" - + /* cc65 */ #include "ident.h" diff --git a/src/cc65/lineinfo.h b/src/cc65/lineinfo.h index 8dbe06846..f365b4f01 100644 --- a/src/cc65/lineinfo.h +++ b/src/cc65/lineinfo.h @@ -37,7 +37,7 @@ #define LINEINFO_H - + /* common */ #include "strbuf.h" @@ -50,7 +50,7 @@ /* Input file structure */ -struct IFile; +struct IFile; diff --git a/src/cc65/loop.c b/src/cc65/loop.c index c15c37a79..f6c53ddc4 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -39,7 +39,7 @@ /* cc65 */ #include "error.h" -#include "loop.h" +#include "loop.h" #include "stackptr.h" diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 1ea86545d..2dd923cf1 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -460,7 +460,7 @@ static void SegNamePragma (StrBuf* B, segment_t Seg) Warning ("Invalid address size for segment!"); } } - + /* Set the new name and optionally address size */ if (Push) { PushSegName (Seg, Name); diff --git a/src/cc65/reginfo.h b/src/cc65/reginfo.h index 28b948e04..2066ab505 100644 --- a/src/cc65/reginfo.h +++ b/src/cc65/reginfo.h @@ -102,7 +102,7 @@ #define ZNREG_A REG_A #define ZNREG_X REG_X #define ZNREG_Y REG_Y -#define ZNREG_TMP1 REG_TMP1 +#define ZNREG_TMP1 REG_TMP1 #define ZNREG_PTR1_LO REG_PTR1_LO #define ZNREG_PTR1_HI REG_PTR1_HI #define ZNREG_PTR2_LO REG_PTR2_LO diff --git a/src/cc65/scanstrbuf.c b/src/cc65/scanstrbuf.c index bbee569d2..2e3be8854 100644 --- a/src/cc65/scanstrbuf.c +++ b/src/cc65/scanstrbuf.c @@ -185,7 +185,7 @@ int SB_GetSym (StrBuf* B, StrBuf* Ident, const char* SpecialChars) SB_AppendChar (Ident, C); SB_Skip (B); C = SB_Peek (B); - } while (IsIdent (C) || IsDigit (C) || + } while (IsIdent (C) || IsDigit (C) || (C != '\0' && strchr (SpecialChars, C) != 0)); SB_Terminate (Ident); return 1; diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index 0c69e96e5..d7b43dde2 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 3c000f3a1..db2b04f17 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -518,7 +518,7 @@ SymEntry FindStructField (const Type* T, const char* Name) */ if (Struct->V.S.SymTab) { Entry = FindSymInTable (Struct->V.S.SymTab, Name, HashStr (Name)); - + if (Entry != 0) { Offs = Entry->V.Offs; } @@ -732,7 +732,7 @@ SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTab CurTagTab = FailSafeTab; } } - + if (Entry == 0) { /* Create a new entry */ @@ -817,7 +817,7 @@ SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTabl CurTagTab = FailSafeTab; } } - + if (Entry == 0) { /* Create a new entry */ @@ -1116,7 +1116,7 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs } } } - + if (Entry == 0) { /* Create a new entry */ Entry = NewSymEntry (Name, Flags); @@ -1221,7 +1221,6 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) /* Add the new declaration to the global symbol table instead */ Tab = SymTab0; } - if (Entry == 0 || Entry->Owner != Tab) { /* Create a new entry */ diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 02ee98dae..e5db488de 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -32,7 +32,7 @@ /*****************************************************************************/ - + /* cc65 */ #include "codegen.h" #include "error.h" diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 1f4643e73..f204b9a0b 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -228,7 +228,7 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) return; } } - } + } } } From 047d0f479bfee28b6e43be84d5b2a6b35b89398f Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 1 Mar 2021 15:26:51 +0800 Subject: [PATCH 1895/2161] Comments format fix. --- src/cc65/codegen.c | 3 ++- src/cc65/codeoptutil.c | 10 ++++++---- src/cc65/datatype.c | 5 +++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 3ca9d81e6..bf7c900ab 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -2822,7 +2822,8 @@ void g_div (unsigned flags, unsigned long val) } /* Negate the result as long as val < 0, even if val == -1 and no - ** shift was generated. */ + ** shift was generated. + */ if (Negation) { g_neg (flags); } diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index 140420e97..2f79b131b 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -356,8 +356,9 @@ static int Affected (LoadRegInfo* LRI, const CodeEntry* E) } if ((LRI->Flags & LI_CHECK_Y) != 0) { - /* If we don't know what memory location could have been used by Y, - ** we just assume all. */ + /* If we don't know what memory location could have been + ** used by Y, we just assume all. + */ if (YE == 0 || (YE->ArgOff == E->ArgOff && strcmp (YE->ArgBase, E->ArgBase) == 0)) { @@ -375,8 +376,9 @@ static int Affected (LoadRegInfo* LRI, const CodeEntry* E) /* Otherwise unaffected */ goto L_Result; } - /* We could've check further for more cases where the load target isn't - ** modified, but for now let's save the trouble and just play it safe. + /* We could've check further for more cases where the load target + ** isn't modified, but for now let's save the trouble and just play + ** it safe. */ goto L_Affected; } diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d78bfe116..6e42057dc 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -755,8 +755,9 @@ unsigned SizeOf (const Type* T) return T->A.U; /* Beware: There's a chance that this triggers problems in other parts - of the compiler. The solution is to fix the callers, because calling - SizeOf() with a function type as argument is bad. */ + ** of the compiler. The solution is to fix the callers, because calling + ** SizeOf() with a function type as argument is bad. + */ case T_FUNC: return 0; /* Size of function is unknown */ From 872739b5f4d9c91137f49f6a99f27493b6b72bc1 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Wed, 3 Mar 2021 22:14:29 +0100 Subject: [PATCH 1896/2161] Fix comments, return line and bordercolor return --- include/telestrat.h | 6 ++++++ libsrc/telestrat/bordercolor.s | 5 +---- libsrc/telestrat/clrscr.s | 8 ++++---- libsrc/telestrat/cputc.s | 15 ++++++--------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/include/telestrat.h b/include/telestrat.h index 5ad1d3bef..465517f30 100644 --- a/include/telestrat.h +++ b/include/telestrat.h @@ -121,3 +121,9 @@ void shoot(); void explode(); void kbdclick1(); + +/* 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 _bordercolor(color) COLOR_BLACK diff --git a/libsrc/telestrat/bordercolor.s b/libsrc/telestrat/bordercolor.s index 9e49b057f..84e167bc9 100644 --- a/libsrc/telestrat/bordercolor.s +++ b/libsrc/telestrat/bordercolor.s @@ -9,8 +9,5 @@ .include "telestrat.inc" -_bordercolor: - ; Nothing to do - ; Oric can't handle his border - rts +_bordercolor := return0 diff --git a/libsrc/telestrat/clrscr.s b/libsrc/telestrat/clrscr.s index 363aa2761..c02c26647 100644 --- a/libsrc/telestrat/clrscr.s +++ b/libsrc/telestrat/clrscr.s @@ -23,9 +23,9 @@ ; reset prompt position - lda #<(SCREEN) + lda #<SCREEN sta ADSCR - lda #>(SCREEN) + lda #>SCREEN sta ADSCR+1 lda #$00 @@ -36,10 +36,10 @@ stx SCRY stx SCRX - stx OLD_BGCOLOR ; black + stx OLD_BGCOLOR ; Black stx BGCOLOR - ldx #$07 ; white + ldx #$07 ; White stx OLD_CHARCOLOR stx CHARCOLOR diff --git a/libsrc/telestrat/cputc.s b/libsrc/telestrat/cputc.s index aa756aaf5..994a2b9d4 100644 --- a/libsrc/telestrat/cputc.s +++ b/libsrc/telestrat/cputc.s @@ -4,7 +4,8 @@ ; void cputc (char c); ; - .export _cputc, _cputcxy, cputdirect, display_conio, CHARCOLOR, OLD_CHARCOLOR, BGCOLOR, OLD_BGCOLOR + .export _cputc, _cputcxy, cputdirect, display_conio + .export CHARCOLOR, OLD_CHARCOLOR, BGCOLOR, OLD_BGCOLOR .import update_adscr @@ -14,10 +15,10 @@ cputdirect: _cputcxy: - pha ; Save C - jsr popax ; Get X and Y - sta SCRY ; Store Y - stx SCRX ; Store X + pha ; Save C + jsr popax ; Get X and Y + sta SCRY ; Store Y + stx SCRX ; Store X jsr update_adscr pla @@ -34,9 +35,7 @@ _cputcxy: inc SCRY jmp update_adscr - @not_LF: - ldx CHARCOLOR cpx OLD_CHARCOLOR beq do_not_change_color_foreground @@ -87,8 +86,6 @@ do_not_change_color: rts .endproc - - .bss CHARCOLOR: .res 1 From 5f145542b05fd08b81dac089757c206159e828c7 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 3 Mar 2021 17:39:53 -0500 Subject: [PATCH 1897/2161] Exported the Commodore CHRIN and CHROUT Kernal functions, in the CBM libraries. This commit complements commit 98f8064b8311753fab468aaf2c1b6d2e339a4391. --- libsrc/c128/kernal.s | 2 ++ libsrc/c16/kernal.s | 2 ++ libsrc/c64/kernal.s | 2 ++ libsrc/cbm510/kernal.s | 2 ++ libsrc/cbm610/kernal.s | 2 ++ libsrc/pet/kbsout.s | 7 +++++-- libsrc/pet/kernal.s | 1 + libsrc/plus4/kbasin.s | 7 ++++--- libsrc/plus4/kbsout.s | 5 +++-- libsrc/vic20/kernal.s | 2 ++ 10 files changed, 25 insertions(+), 7 deletions(-) diff --git a/libsrc/c128/kernal.s b/libsrc/c128/kernal.s index 138473218..47e80c559 100644 --- a/libsrc/c128/kernal.s +++ b/libsrc/c128/kernal.s @@ -46,7 +46,9 @@ .export CKOUT .export CLRCH .export BASIN + .export CHRIN .export BSOUT + .export CHROUT .export LOAD .export SAVE .export SETTIM diff --git a/libsrc/c16/kernal.s b/libsrc/c16/kernal.s index 15ce35772..5f70123a2 100644 --- a/libsrc/c16/kernal.s +++ b/libsrc/c16/kernal.s @@ -35,7 +35,9 @@ .export CKOUT .export CLRCH .export BASIN + .export CHRIN .export BSOUT + .export CHROUT .export LOAD .export SAVE .export SETTIM diff --git a/libsrc/c64/kernal.s b/libsrc/c64/kernal.s index 771872082..cf5511ce8 100644 --- a/libsrc/c64/kernal.s +++ b/libsrc/c64/kernal.s @@ -38,7 +38,9 @@ .export CKOUT .export CLRCH .export BASIN + .export CHRIN .export BSOUT + .export CHROUT .export LOAD .export SAVE .export SETTIM diff --git a/libsrc/cbm510/kernal.s b/libsrc/cbm510/kernal.s index 7908c40ec..705422709 100644 --- a/libsrc/cbm510/kernal.s +++ b/libsrc/cbm510/kernal.s @@ -28,7 +28,9 @@ .export CKOUT .export CLRCH .export BASIN + .export CHRIN .export BSOUT + .export CHROUT .export LOAD .export SAVE .export STOP diff --git a/libsrc/cbm610/kernal.s b/libsrc/cbm610/kernal.s index 921bf524e..30156e79c 100644 --- a/libsrc/cbm610/kernal.s +++ b/libsrc/cbm610/kernal.s @@ -28,7 +28,9 @@ .export CKOUT .export CLRCH .export BASIN + .export CHRIN .export BSOUT + .export CHROUT .export LOAD .export SAVE .export STOP diff --git a/libsrc/pet/kbsout.s b/libsrc/pet/kbsout.s index 178ac8205..8b21378af 100644 --- a/libsrc/pet/kbsout.s +++ b/libsrc/pet/kbsout.s @@ -1,17 +1,20 @@ ; ; Ullrich von Bassewitz, 19.11.2002 ; -; BSOUT replacement function for the PETs +; BSOUT/CHROUT replacement function for the PETs ; .export BSOUT + .export CHROUT + .import checkst .proc BSOUT - jsr $FFD2 ; Call kernal function + jsr $FFD2 ; Call Kernal function jmp checkst ; Check status, return carry on error .endproc +CHROUT := BSOUT diff --git a/libsrc/pet/kernal.s b/libsrc/pet/kernal.s index ba66c4653..fc8d62c4a 100644 --- a/libsrc/pet/kernal.s +++ b/libsrc/pet/kernal.s @@ -8,6 +8,7 @@ .export CLRCH .export BASIN + .export CHRIN .export STOP .export GETIN .export CLALL diff --git a/libsrc/plus4/kbasin.s b/libsrc/plus4/kbasin.s index 507043866..3bbee9f74 100644 --- a/libsrc/plus4/kbasin.s +++ b/libsrc/plus4/kbasin.s @@ -1,10 +1,11 @@ ; ; Ullrich von Bassewitz, 22.11.2002 ; -; BASIN replacement function +; BASIN/CHRIN replacement function ; - + .export BASIN + .export CHRIN .include "plus4.inc" @@ -17,4 +18,4 @@ rts ; Return to caller .endproc - +CHRIN := BASIN diff --git a/libsrc/plus4/kbsout.s b/libsrc/plus4/kbsout.s index a86a334b2..8b6df19ff 100644 --- a/libsrc/plus4/kbsout.s +++ b/libsrc/plus4/kbsout.s @@ -1,10 +1,11 @@ ; ; Ullrich von Bassewitz, 22.11.2002 ; -; BSOUT replacement function +; BSOUT/CHROUT replacement function ; .export BSOUT + .export CHROUT .include "plus4.inc" @@ -17,4 +18,4 @@ rts ; Return to caller .endproc - +CHROUT := BSOUT diff --git a/libsrc/vic20/kernal.s b/libsrc/vic20/kernal.s index 94a5ec1a4..7c54b205f 100644 --- a/libsrc/vic20/kernal.s +++ b/libsrc/vic20/kernal.s @@ -36,7 +36,9 @@ .export CKOUT .export CLRCH .export BASIN + .export CHRIN .export BSOUT + .export CHROUT .export LOAD .export SAVE .export SETTIM From 1fc16cb9ed6f9a27f4aaa6337b98e27a57a77fcd Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Fri, 23 Oct 2020 23:47:30 +0200 Subject: [PATCH 1898/2161] Now getchar works --- libsrc/telestrat/read.s | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/libsrc/telestrat/read.s b/libsrc/telestrat/read.s index 76de9d0ac..0782c4d21 100644 --- a/libsrc/telestrat/read.s +++ b/libsrc/telestrat/read.s @@ -8,21 +8,33 @@ .include "zeropage.inc" .include "telestrat.inc" + .include "fcntl.inc" ;int read (int fd, void* buf, unsigned count); .proc _read - sta ptr1 ; count - stx ptr1+1 ; count - jsr popax ; get buf + sta ptr1 ; count + stx ptr1+1 ; count + jsr popax ; get buf sta PTR_READ_DEST stx PTR_READ_DEST+1 - sta ptr2 ; in order to calculate nb of bytes read + sta ptr2 ; in order to calculate nb of bytes read stx ptr2+1 ; - ; jsr popax ; fp pointer don't care in this version + jsr popax ; fp pointer don't care in this version + cpx #$00 + bne @is_not_stdin + cmp #STDIN_FILENO + bne @is_not_stdin + ; stdin +@L1: + BRK_TELEMON XRD0 ; waits until key is pressed + bcs @L1 + + rts +@is_not_stdin: lda ptr1 ; ldy ptr1+1 ; BRK_TELEMON XFREAD ; calls telemon30 routine From d83e8a3f0e8f71f627b20639c85e4e7a386cbb32 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 1 Mar 2021 22:49:20 +0100 Subject: [PATCH 1899/2161] add syschdir --- libsrc/telestrat/syschdir.s | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 libsrc/telestrat/syschdir.s diff --git a/libsrc/telestrat/syschdir.s b/libsrc/telestrat/syschdir.s new file mode 100644 index 000000000..1676f5c88 --- /dev/null +++ b/libsrc/telestrat/syschdir.s @@ -0,0 +1,34 @@ +; +; Jede (jede@oric.org), 2021-02-22 +; +; unsigned char _syschdir (const char* name, ...); +; + + .export __syschdir + .import addysp, popax + .importzp tmp1 + + .include "telestrat.inc" + .include "zeropage.inc" + + +__syschdir: + ; Throw away all parameters except the name + dey + dey + jsr addysp + + ; Get name + jsr popax + + stx tmp1 + ldy tmp1 + + ; Call telemon primitive + + BRK_TELEMON(XPUTCWD) + + rts + + + From 65d5786da564e3937795361cbdc8e1f48f0b0272 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 1 Mar 2021 22:51:59 +0100 Subject: [PATCH 1900/2161] revert read.s --- libsrc/telestrat/read.s | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/libsrc/telestrat/read.s b/libsrc/telestrat/read.s index 0782c4d21..76de9d0ac 100644 --- a/libsrc/telestrat/read.s +++ b/libsrc/telestrat/read.s @@ -8,33 +8,21 @@ .include "zeropage.inc" .include "telestrat.inc" - .include "fcntl.inc" ;int read (int fd, void* buf, unsigned count); .proc _read - sta ptr1 ; count - stx ptr1+1 ; count - jsr popax ; get buf + sta ptr1 ; count + stx ptr1+1 ; count + jsr popax ; get buf sta PTR_READ_DEST stx PTR_READ_DEST+1 - sta ptr2 ; in order to calculate nb of bytes read + sta ptr2 ; in order to calculate nb of bytes read stx ptr2+1 ; - jsr popax ; fp pointer don't care in this version - cpx #$00 - bne @is_not_stdin - cmp #STDIN_FILENO - bne @is_not_stdin - ; stdin -@L1: - BRK_TELEMON XRD0 ; waits until key is pressed - bcs @L1 - - rts + ; jsr popax ; fp pointer don't care in this version -@is_not_stdin: lda ptr1 ; ldy ptr1+1 ; BRK_TELEMON XFREAD ; calls telemon30 routine From 973a5337ac29f8fb1c8abfc68f4a4fa632b721d6 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 1 Mar 2021 22:53:35 +0100 Subject: [PATCH 1901/2161] remove extra line --- libsrc/telestrat/syschdir.s | 3 --- 1 file changed, 3 deletions(-) diff --git a/libsrc/telestrat/syschdir.s b/libsrc/telestrat/syschdir.s index 1676f5c88..37ee0cc81 100644 --- a/libsrc/telestrat/syschdir.s +++ b/libsrc/telestrat/syschdir.s @@ -29,6 +29,3 @@ __syschdir: BRK_TELEMON(XPUTCWD) rts - - - From d417baf826b9a6eae86d4de69f149b9f105954e9 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 1 Mar 2021 23:26:35 +0100 Subject: [PATCH 1902/2161] Now we update __cwd --- libsrc/telestrat/initcwd.s | 3 +-- libsrc/telestrat/syschdir.s | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libsrc/telestrat/initcwd.s b/libsrc/telestrat/initcwd.s index dc3c53257..7d38dd563 100644 --- a/libsrc/telestrat/initcwd.s +++ b/libsrc/telestrat/initcwd.s @@ -10,8 +10,7 @@ initcwd: - ldx #PWD_PTR - BRK_TELEMON XVARS + BRK_TELEMON(XGETCWD) sta ptr1 sty ptr1+1 diff --git a/libsrc/telestrat/syschdir.s b/libsrc/telestrat/syschdir.s index 37ee0cc81..2437ac80e 100644 --- a/libsrc/telestrat/syschdir.s +++ b/libsrc/telestrat/syschdir.s @@ -7,6 +7,7 @@ .export __syschdir .import addysp, popax .importzp tmp1 + .import initcwd .include "telestrat.inc" .include "zeropage.inc" @@ -27,5 +28,7 @@ __syschdir: ; Call telemon primitive BRK_TELEMON(XPUTCWD) + + jsr initcwd ; Update cwd rts From 17ca09ba9afe520cd88c1c156e6e29d836fc5722 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 1 Mar 2021 23:37:09 +0100 Subject: [PATCH 1903/2161] Fix tab --- libsrc/telestrat/syschdir.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/telestrat/syschdir.s b/libsrc/telestrat/syschdir.s index 2437ac80e..c032fc648 100644 --- a/libsrc/telestrat/syschdir.s +++ b/libsrc/telestrat/syschdir.s @@ -6,7 +6,7 @@ .export __syschdir .import addysp, popax - .importzp tmp1 + .importzp tmp1 .import initcwd .include "telestrat.inc" From 9b365654852a390f00a9521c8d3654c18c68d78b Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 1 Mar 2021 23:37:50 +0100 Subject: [PATCH 1904/2161] Fix another tab --- libsrc/telestrat/syschdir.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/telestrat/syschdir.s b/libsrc/telestrat/syschdir.s index c032fc648..1e42bcbab 100644 --- a/libsrc/telestrat/syschdir.s +++ b/libsrc/telestrat/syschdir.s @@ -22,7 +22,7 @@ __syschdir: ; Get name jsr popax - stx tmp1 + stx tmp1 ldy tmp1 ; Call telemon primitive From 2ae41e0a558bfc4b511f17b1df40092a6a0e253a Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Tue, 2 Mar 2021 08:21:12 +0100 Subject: [PATCH 1905/2161] Fix tab --- libsrc/telestrat/syschdir.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/telestrat/syschdir.s b/libsrc/telestrat/syschdir.s index 1e42bcbab..eef11d9e3 100644 --- a/libsrc/telestrat/syschdir.s +++ b/libsrc/telestrat/syschdir.s @@ -22,7 +22,7 @@ __syschdir: ; Get name jsr popax - stx tmp1 + stx tmp1 ldy tmp1 ; Call telemon primitive From bf9d4ac3bbc0a3f23ec09ba90cfae36289bd7556 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Wed, 3 Mar 2021 22:20:20 +0100 Subject: [PATCH 1906/2161] Fix tab and jmp --- libsrc/telestrat/syschdir.s | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libsrc/telestrat/syschdir.s b/libsrc/telestrat/syschdir.s index eef11d9e3..149957215 100644 --- a/libsrc/telestrat/syschdir.s +++ b/libsrc/telestrat/syschdir.s @@ -6,7 +6,7 @@ .export __syschdir .import addysp, popax - .importzp tmp1 + .importzp tmp1 .import initcwd .include "telestrat.inc" @@ -29,6 +29,4 @@ __syschdir: BRK_TELEMON(XPUTCWD) - jsr initcwd ; Update cwd - - rts + jmp initcwd ; Update cwd From 1d8479b411633eeda9952805daac23177640b425 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 6 Mar 2021 11:56:22 +0100 Subject: [PATCH 1907/2161] Revert "Fix tab and jmp" This reverts commit bf9d4ac3bbc0a3f23ec09ba90cfae36289bd7556. --- libsrc/telestrat/syschdir.s | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libsrc/telestrat/syschdir.s b/libsrc/telestrat/syschdir.s index 149957215..eef11d9e3 100644 --- a/libsrc/telestrat/syschdir.s +++ b/libsrc/telestrat/syschdir.s @@ -6,7 +6,7 @@ .export __syschdir .import addysp, popax - .importzp tmp1 + .importzp tmp1 .import initcwd .include "telestrat.inc" @@ -29,4 +29,6 @@ __syschdir: BRK_TELEMON(XPUTCWD) - jmp initcwd ; Update cwd + jsr initcwd ; Update cwd + + rts From f9ca091bd040b3dd7dd65a4722d9ef0d561b0f28 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 6 Mar 2021 11:56:22 +0100 Subject: [PATCH 1908/2161] Revert "Fix tab" This reverts commit 2ae41e0a558bfc4b511f17b1df40092a6a0e253a. --- libsrc/telestrat/syschdir.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/telestrat/syschdir.s b/libsrc/telestrat/syschdir.s index eef11d9e3..1e42bcbab 100644 --- a/libsrc/telestrat/syschdir.s +++ b/libsrc/telestrat/syschdir.s @@ -22,7 +22,7 @@ __syschdir: ; Get name jsr popax - stx tmp1 + stx tmp1 ldy tmp1 ; Call telemon primitive From 24d63a96b1c7d8418b3f2b7f8c60f8a572738864 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 6 Mar 2021 11:56:22 +0100 Subject: [PATCH 1909/2161] Revert "Fix another tab" This reverts commit 9b365654852a390f00a9521c8d3654c18c68d78b. --- libsrc/telestrat/syschdir.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/telestrat/syschdir.s b/libsrc/telestrat/syschdir.s index 1e42bcbab..c032fc648 100644 --- a/libsrc/telestrat/syschdir.s +++ b/libsrc/telestrat/syschdir.s @@ -22,7 +22,7 @@ __syschdir: ; Get name jsr popax - stx tmp1 + stx tmp1 ldy tmp1 ; Call telemon primitive From 558dfa285e9a768b22860113e083528870d48500 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 6 Mar 2021 11:56:22 +0100 Subject: [PATCH 1910/2161] Revert "Fix tab" This reverts commit 17ca09ba9afe520cd88c1c156e6e29d836fc5722. --- libsrc/telestrat/syschdir.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/telestrat/syschdir.s b/libsrc/telestrat/syschdir.s index c032fc648..2437ac80e 100644 --- a/libsrc/telestrat/syschdir.s +++ b/libsrc/telestrat/syschdir.s @@ -6,7 +6,7 @@ .export __syschdir .import addysp, popax - .importzp tmp1 + .importzp tmp1 .import initcwd .include "telestrat.inc" From ab4ca51848560efdea292837d2dd74ffebd22470 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 6 Mar 2021 11:56:22 +0100 Subject: [PATCH 1911/2161] Revert "Now we update __cwd" This reverts commit d417baf826b9a6eae86d4de69f149b9f105954e9. --- libsrc/telestrat/initcwd.s | 3 ++- libsrc/telestrat/syschdir.s | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/libsrc/telestrat/initcwd.s b/libsrc/telestrat/initcwd.s index 7d38dd563..dc3c53257 100644 --- a/libsrc/telestrat/initcwd.s +++ b/libsrc/telestrat/initcwd.s @@ -10,7 +10,8 @@ initcwd: - BRK_TELEMON(XGETCWD) + ldx #PWD_PTR + BRK_TELEMON XVARS sta ptr1 sty ptr1+1 diff --git a/libsrc/telestrat/syschdir.s b/libsrc/telestrat/syschdir.s index 2437ac80e..37ee0cc81 100644 --- a/libsrc/telestrat/syschdir.s +++ b/libsrc/telestrat/syschdir.s @@ -7,7 +7,6 @@ .export __syschdir .import addysp, popax .importzp tmp1 - .import initcwd .include "telestrat.inc" .include "zeropage.inc" @@ -28,7 +27,5 @@ __syschdir: ; Call telemon primitive BRK_TELEMON(XPUTCWD) - - jsr initcwd ; Update cwd rts From 8ae5a4a1345db0947ed327b9ce4103963b2670e3 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 6 Mar 2021 11:56:22 +0100 Subject: [PATCH 1912/2161] Revert "remove extra line" This reverts commit 973a5337ac29f8fb1c8abfc68f4a4fa632b721d6. --- libsrc/telestrat/syschdir.s | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libsrc/telestrat/syschdir.s b/libsrc/telestrat/syschdir.s index 37ee0cc81..1676f5c88 100644 --- a/libsrc/telestrat/syschdir.s +++ b/libsrc/telestrat/syschdir.s @@ -29,3 +29,6 @@ __syschdir: BRK_TELEMON(XPUTCWD) rts + + + From d6f2fda5757ee0786579cd76b6b50f2926e9836e Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 6 Mar 2021 11:56:22 +0100 Subject: [PATCH 1913/2161] Revert "revert read.s" This reverts commit 65d5786da564e3937795361cbdc8e1f48f0b0272. --- libsrc/telestrat/read.s | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/libsrc/telestrat/read.s b/libsrc/telestrat/read.s index 76de9d0ac..0782c4d21 100644 --- a/libsrc/telestrat/read.s +++ b/libsrc/telestrat/read.s @@ -8,21 +8,33 @@ .include "zeropage.inc" .include "telestrat.inc" + .include "fcntl.inc" ;int read (int fd, void* buf, unsigned count); .proc _read - sta ptr1 ; count - stx ptr1+1 ; count - jsr popax ; get buf + sta ptr1 ; count + stx ptr1+1 ; count + jsr popax ; get buf sta PTR_READ_DEST stx PTR_READ_DEST+1 - sta ptr2 ; in order to calculate nb of bytes read + sta ptr2 ; in order to calculate nb of bytes read stx ptr2+1 ; - ; jsr popax ; fp pointer don't care in this version + jsr popax ; fp pointer don't care in this version + cpx #$00 + bne @is_not_stdin + cmp #STDIN_FILENO + bne @is_not_stdin + ; stdin +@L1: + BRK_TELEMON XRD0 ; waits until key is pressed + bcs @L1 + + rts +@is_not_stdin: lda ptr1 ; ldy ptr1+1 ; BRK_TELEMON XFREAD ; calls telemon30 routine From f122837955170516c629f5d97c82c984a883b5b8 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 6 Mar 2021 11:56:22 +0100 Subject: [PATCH 1914/2161] Revert "add syschdir" This reverts commit d83e8a3f0e8f71f627b20639c85e4e7a386cbb32. --- libsrc/telestrat/syschdir.s | 34 ---------------------------------- 1 file changed, 34 deletions(-) delete mode 100644 libsrc/telestrat/syschdir.s diff --git a/libsrc/telestrat/syschdir.s b/libsrc/telestrat/syschdir.s deleted file mode 100644 index 1676f5c88..000000000 --- a/libsrc/telestrat/syschdir.s +++ /dev/null @@ -1,34 +0,0 @@ -; -; Jede (jede@oric.org), 2021-02-22 -; -; unsigned char _syschdir (const char* name, ...); -; - - .export __syschdir - .import addysp, popax - .importzp tmp1 - - .include "telestrat.inc" - .include "zeropage.inc" - - -__syschdir: - ; Throw away all parameters except the name - dey - dey - jsr addysp - - ; Get name - jsr popax - - stx tmp1 - ldy tmp1 - - ; Call telemon primitive - - BRK_TELEMON(XPUTCWD) - - rts - - - From bc8cca9fc48d7da6d93035b38f57b62f6e9a6043 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sat, 6 Mar 2021 11:56:22 +0100 Subject: [PATCH 1915/2161] Revert "Now getchar works" This reverts commit 1fc16cb9ed6f9a27f4aaa6337b98e27a57a77fcd. --- libsrc/telestrat/read.s | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/libsrc/telestrat/read.s b/libsrc/telestrat/read.s index 0782c4d21..76de9d0ac 100644 --- a/libsrc/telestrat/read.s +++ b/libsrc/telestrat/read.s @@ -8,33 +8,21 @@ .include "zeropage.inc" .include "telestrat.inc" - .include "fcntl.inc" ;int read (int fd, void* buf, unsigned count); .proc _read - sta ptr1 ; count - stx ptr1+1 ; count - jsr popax ; get buf + sta ptr1 ; count + stx ptr1+1 ; count + jsr popax ; get buf sta PTR_READ_DEST stx PTR_READ_DEST+1 - sta ptr2 ; in order to calculate nb of bytes read + sta ptr2 ; in order to calculate nb of bytes read stx ptr2+1 ; - jsr popax ; fp pointer don't care in this version - cpx #$00 - bne @is_not_stdin - cmp #STDIN_FILENO - bne @is_not_stdin - ; stdin -@L1: - BRK_TELEMON XRD0 ; waits until key is pressed - bcs @L1 - - rts + ; jsr popax ; fp pointer don't care in this version -@is_not_stdin: lda ptr1 ; ldy ptr1+1 ; BRK_TELEMON XFREAD ; calls telemon30 routine From 48badc081679a19bec9ad6edbc1b39f36fd50e79 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sat, 6 Mar 2021 21:40:26 +0100 Subject: [PATCH 1916/2161] Fix import return0 --- libsrc/telestrat/bordercolor.s | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libsrc/telestrat/bordercolor.s b/libsrc/telestrat/bordercolor.s index 84e167bc9..c29ecc0e7 100644 --- a/libsrc/telestrat/bordercolor.s +++ b/libsrc/telestrat/bordercolor.s @@ -4,9 +4,10 @@ ; unsigned char __fastcall__ bordercolor (unsigned char color); ; - .export _bordercolor + .import return0 + .include "telestrat.inc" _bordercolor := return0 From df64fd859c7477ebd7d0ed8b377c84b0510e5e77 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Sun, 7 Mar 2021 23:00:15 +0100 Subject: [PATCH 1917/2161] Fix cvline bug --- libsrc/telestrat/cvline.s | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libsrc/telestrat/cvline.s b/libsrc/telestrat/cvline.s index 159eb9d27..0d6086216 100644 --- a/libsrc/telestrat/cvline.s +++ b/libsrc/telestrat/cvline.s @@ -28,7 +28,11 @@ _cvline: @L1: lda #'|' ora rvs - jsr display_conio + ldy SCRX + sta (ADSCR),y + ; compute next line + inc SCRY + jsr update_adscr @L2: dex bne @L1 @L9: rts From facc1b4914425baee3019035189b29beca649cb5 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Mon, 8 Mar 2021 21:16:44 +0100 Subject: [PATCH 1918/2161] Fix cputdirect --- libsrc/telestrat/cputc.s | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libsrc/telestrat/cputc.s b/libsrc/telestrat/cputc.s index 994a2b9d4..6049d1174 100644 --- a/libsrc/telestrat/cputc.s +++ b/libsrc/telestrat/cputc.s @@ -6,14 +6,13 @@ .export _cputc, _cputcxy, cputdirect, display_conio .export CHARCOLOR, OLD_CHARCOLOR, BGCOLOR, OLD_BGCOLOR - .import update_adscr .import popax .include "telestrat.inc" -cputdirect: + _cputcxy: pha ; Save C jsr popax ; Get X and Y @@ -22,7 +21,7 @@ _cputcxy: jsr update_adscr pla -.proc _cputc +_cputc: cmp #$0D bne @not_CR ldy #$00 @@ -30,12 +29,13 @@ _cputcxy: rts @not_CR: cmp #$0A - bne @not_LF + bne not_LF inc SCRY jmp update_adscr -@not_LF: +cputdirect: +not_LF: ldx CHARCOLOR cpx OLD_CHARCOLOR beq do_not_change_color_foreground @@ -67,7 +67,7 @@ do_not_change_color_foreground: do_not_change_color: ; it continues to display_conio -.endproc + .proc display_conio ; This routine is used to displays char on screen From a05dddd0d6ac759eee695d54a8ef2632e6220108 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Tue, 9 Mar 2021 22:02:26 +0100 Subject: [PATCH 1919/2161] Fix next column --- libsrc/telestrat/cputc.s | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libsrc/telestrat/cputc.s b/libsrc/telestrat/cputc.s index 6049d1174..16b13f8cd 100644 --- a/libsrc/telestrat/cputc.s +++ b/libsrc/telestrat/cputc.s @@ -78,6 +78,8 @@ do_not_change_color: bne @no_inc ldy #$00 sty SCRX + + inc SCRY jmp update_adscr From 4f26650228506b746fce11895eaa6fa6befb2b31 Mon Sep 17 00:00:00 2001 From: jedeoric <jede@oric.org> Date: Thu, 11 Mar 2021 09:42:14 +0100 Subject: [PATCH 1920/2161] [Telestrat] chdir management (#1419) * add syschdir * revert read.s * remove extra line * Now we update __cwd * Fix tab * Fix another tab * Fix tab * Fix tab and jmp * fix xgetcwd * Fix comments --- asminc/telestrat.inc | 2 ++ libsrc/telestrat/initcwd.s | 3 +-- libsrc/telestrat/read.s | 12 ++++++------ libsrc/telestrat/syschdir.s | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 8 deletions(-) create mode 100644 libsrc/telestrat/syschdir.s diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 2036574a4..556b41f7c 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -284,6 +284,8 @@ XSOUND = $44 XMUSIC = $45 XZAP = $46 ; Send Zap sound to PSG XSHOOT = $47 +XGETCWD = $48 ; Get current CWD +XPUTCWD = $49 ; Chdir XMKDIR = $4B ; Create a folder. Only available in TELEMON 3.x (bank 7 of Orix) XRM = $4D ; Remove a folder or a file. Only available in TELEMON 3.x (bank 7 of Orix) XFWR = $4E ; Put a char on the first screen. Only available in TELEMON 3.x (bank 7 of Orix) diff --git a/libsrc/telestrat/initcwd.s b/libsrc/telestrat/initcwd.s index dc3c53257..7d38dd563 100644 --- a/libsrc/telestrat/initcwd.s +++ b/libsrc/telestrat/initcwd.s @@ -10,8 +10,7 @@ initcwd: - ldx #PWD_PTR - BRK_TELEMON XVARS + BRK_TELEMON(XGETCWD) sta ptr1 sty ptr1+1 diff --git a/libsrc/telestrat/read.s b/libsrc/telestrat/read.s index 76de9d0ac..db764fc84 100644 --- a/libsrc/telestrat/read.s +++ b/libsrc/telestrat/read.s @@ -12,21 +12,21 @@ ;int read (int fd, void* buf, unsigned count); .proc _read - sta ptr1 ; count - stx ptr1+1 ; count - jsr popax ; get buf + + sta ptr1 ; Count + stx ptr1+1 ; Count + jsr popax ; Get buf sta PTR_READ_DEST stx PTR_READ_DEST+1 - sta ptr2 ; in order to calculate nb of bytes read + sta ptr2 ; In order to calculate nb of bytes read stx ptr2+1 ; - ; jsr popax ; fp pointer don't care in this version lda ptr1 ; ldy ptr1+1 ; BRK_TELEMON XFREAD ; calls telemon30 routine - ; compute nb of bytes read + ; Compute nb of bytes read lda PTR_READ_DEST+1 sec sbc ptr2+1 diff --git a/libsrc/telestrat/syschdir.s b/libsrc/telestrat/syschdir.s new file mode 100644 index 000000000..149957215 --- /dev/null +++ b/libsrc/telestrat/syschdir.s @@ -0,0 +1,32 @@ +; +; Jede (jede@oric.org), 2021-02-22 +; +; unsigned char _syschdir (const char* name, ...); +; + + .export __syschdir + .import addysp, popax + .importzp tmp1 + .import initcwd + + .include "telestrat.inc" + .include "zeropage.inc" + + +__syschdir: + ; Throw away all parameters except the name + dey + dey + jsr addysp + + ; Get name + jsr popax + + stx tmp1 + ldy tmp1 + + ; Call telemon primitive + + BRK_TELEMON(XPUTCWD) + + jmp initcwd ; Update cwd From c0d638a26d36152d861b3078444f94852987b34c Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Thu, 11 Mar 2021 22:48:05 +0100 Subject: [PATCH 1921/2161] add clock for Telestrat target and add some Telemon primitives --- asminc/telestrat.inc | 41 ++++++++++++++++++++++++++++++++++++---- libsrc/telestrat/clock.s | 30 +++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 libsrc/telestrat/clock.s diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 556b41f7c..f48600b38 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -63,7 +63,7 @@ PTR_READ_DEST := $2C ; Used for XFREAD and XWRITE only in TELEMON 3. ADCLK := $40 ; Address for clock display TIMEUS := $42 -TIMEUD := $44 +TIMEUD := $44 ; Counter clock (1/10 of a second) HRSX := $46 @@ -277,6 +277,7 @@ XRECLK = $3C ; Reset clock XCLCL = $3D ; Close clock XWRCLK = $3E ; Displays clock in the adress in A & Y registers +; Sound primitives XSONPS = $40 ; Send data to PSG register (14 values) XOUPS = $42 ; Send Oups sound into PSG XPLAY = $43 ; Play a sound @@ -284,12 +285,25 @@ XSOUND = $44 XMUSIC = $45 XZAP = $46 ; Send Zap sound to PSG XSHOOT = $47 + +; Path Management XGETCWD = $48 ; Get current CWD XPUTCWD = $49 ; Chdir + +; File management XMKDIR = $4B ; Create a folder. Only available in TELEMON 3.x (bank 7 of Orix) + +XHCHRS = $4C ; Hard copy hires + +; File management XRM = $4D ; Remove a folder or a file. Only available in TELEMON 3.x (bank 7 of Orix) + XFWR = $4E ; Put a char on the first screen. Only available in TELEMON 3.x (bank 7 of Orix) -XGOKBD = $52 + +; Keyboard primitives +XALLKB = $50 ; Read Keyboard, and populate KBDCOL +XKBDAS = $51 ; Ascii conversion +XGOKBD = $52 ; Swap keyboard type (Qwerty, French ...) ; Buffer management XECRBU = $54 ; Write A or AY in the buffer @@ -301,8 +315,27 @@ XDEFBU = $59 ; Reset all value of the buffer XBUSY = $5A ; Test if the buffer is empty XMALLOC = $5B ; Only in TELEMON 3.x (bank 7 of Orix) + +; RS232 primitives +XSDUMP = $5C ; RS232 input dump +XCONSO = $5D ; Swap screen into RS232 terminal +XSLOAD = $5E ; Read a file from RS232 +XSSAVE = $5F ; Write a file to RS232 + +; Minitel primitives +XMLOAD = $60 ; Read a file from Minitel +XMSAVE = $61 ; Write a file to Minitel + XFREE = $62 ; Only in TELEMON 3.x (bank 7 of Orix) + +; Next Minitel primitives +XWCXFI = $63 ; Wait connection +XLIGNE = $64 ; +XDECON = $65 ; Minitel disconnection +XMOUT = $66 ; Send a byte to minitel (from A) + XSOUT = $67 ; Send accumulator value (A) to RS232, available in TELEMON 2.4 & 3.x : if RS232 buffer is full, the Oric Telestrat freezes + XHRSSE = $8C ; Set hires position cursor XDRAWA = $8D ; Draw a line absolute XDRAWR = $8E ; Draw a line (relative) @@ -326,7 +359,7 @@ PWD_PTR = $00 ; --------------------------------------------------------------------------- ; -BUFTRV := $100 +BUFTRV := $100 ; --------------------------------------------------------------------------- @@ -339,7 +372,7 @@ FLGTEL := $20D KOROM := $20E ; Used to compute the size of all rom bank. The result is store here. The value is in KB KORAM := $20F ; Used to compute the size of all ram bank. The result is store here. The value is in KB ; Time management -TIMED := $210 +TIMED := $210 ; Clock (1/10 of seconds) TIMES := $211 TIMEM := $212 TIMEH := $213 diff --git a/libsrc/telestrat/clock.s b/libsrc/telestrat/clock.s new file mode 100644 index 000000000..1e107027f --- /dev/null +++ b/libsrc/telestrat/clock.s @@ -0,0 +1,30 @@ +; +; Jede, 2021-03-10 +; +; clock_t clock (void); +; + + .export _clock + .importzp sreg + + .include "telestrat.inc" + +.proc _clock + +; Clear the timer high 16 bits + + ldy #$00 + sty sreg + sty sreg+1 + +; Read the timer + + sei ; Disable interrupts + lda TIMEUD ; TIMED contains 1/10 of a second from clock. Telestrat main cardridge simulate a clock from VIA6522 timer + ldx TIMEUD+1 + cli ; Reenable interrupts + + rts +.endproc + + From b9fd318985d12904b3facba8f82dc4cb37295f65 Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Thu, 11 Mar 2021 22:52:41 +0100 Subject: [PATCH 1922/2161] fix space/column --- asminc/telestrat.inc | 22 +++++++++++----------- libsrc/telestrat/clock.s | 4 +--- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index f48600b38..7d4c1e31d 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -48,33 +48,33 @@ TR7 := $13 DEFAFF := $14 -IRQSVA := $21 ; Used to save A when a BRK call occurs -IRQSVX := $22 ; Used to save X when a BRK call occurs -IRQSVY := $23 ; Used to save Y when a BRK call occurs -IRQSVP := $24 ; Used to save P when a BRK call occurs +IRQSVA := $21 ; Used to save A when a BRK call occurs +IRQSVX := $22 ; Used to save X when a BRK call occurs +IRQSVY := $23 ; Used to save Y when a BRK call occurs +IRQSVP := $24 ; Used to save P when a BRK call occurs ADSCR := $26 -SCRNB := $28 ; Id of the current window +SCRNB := $28 ; Id of the current window -ADKBD := $2A ; Address ASCII conversion table +ADKBD := $2A ; Address ASCII conversion table -PTR_READ_DEST := $2C ; Used for XFREAD and XWRITE only in TELEMON 3.x +PTR_READ_DEST := $2C ; Used for XFREAD and XWRITE only in TELEMON 3.x -ADCLK := $40 ; Address for clock display +ADCLK := $40 ; Address for clock display TIMEUS := $42 -TIMEUD := $44 ; Counter clock (1/10 of a second) +TIMEUD := $44 ; Counter clock (1/10 of a second) HRSX := $46 HRSY := $47 -XLPRBI := $48 ; Printer flag (b7) +XLPRBI := $48 ; Printer flag (b7) HRSX40 := $49 HRSX6 := $4A -ADHRS := $4B ; Hires screen address (word) +ADHRS := $4B ; Hires screen address (word) HRS1 := $4D HRS2 := $4F diff --git a/libsrc/telestrat/clock.s b/libsrc/telestrat/clock.s index 1e107027f..c5478c7ac 100644 --- a/libsrc/telestrat/clock.s +++ b/libsrc/telestrat/clock.s @@ -20,11 +20,9 @@ ; Read the timer sei ; Disable interrupts - lda TIMEUD ; TIMED contains 1/10 of a second from clock. Telestrat main cardridge simulate a clock from VIA6522 timer + lda TIMEUD ; TIMED contains 1/10 of a second from clock. Telestrat main cardridge simulate a clock from VIA6522 timer ldx TIMEUD+1 cli ; Reenable interrupts rts .endproc - - From 41f796bbe1a825c3c8ecffc598c484be0304347e Mon Sep 17 00:00:00 2001 From: jede <jede@oric.org> Date: Tue, 16 Mar 2021 00:53:34 +0100 Subject: [PATCH 1923/2161] left and right mask are inverted : fix in telestrat.h --- include/telestrat.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/telestrat.h b/include/telestrat.h index 465517f30..c1e0996bc 100644 --- a/include/telestrat.h +++ b/include/telestrat.h @@ -100,8 +100,8 @@ /* Masks for joy_read */ #define JOY_UP_MASK 0x10 #define JOY_DOWN_MASK 0x08 -#define JOY_LEFT_MASK 0x01 -#define JOY_RIGHT_MASK 0x02 +#define JOY_LEFT_MASK 0x02 +#define JOY_RIGHT_MASK 0x01 #define JOY_BTN_1_MASK 0x04 #define JOY_FIRE_MASK JOY_BTN_1_MASK From bd5d5b738569f3159c9c7f5632e68c55db105a93 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 13 Mar 2021 14:31:23 +0800 Subject: [PATCH 1924/2161] Removed the prototype of evalexpr() that no longer exists. --- src/cc65/expr.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/cc65/expr.h b/src/cc65/expr.h index 71dbe8e0d..02f9f7a5f 100644 --- a/src/cc65/expr.h +++ b/src/cc65/expr.h @@ -74,13 +74,6 @@ void Store (ExprDesc* Expr, const Type* StoreType); ** is NULL, use lval->Type instead. */ -int evalexpr (unsigned flags, void (*Func) (ExprDesc*), ExprDesc* Expr); -/* Will evaluate an expression via the given function. If the result is a -** constant, 0 is returned and the value is put in the Expr struct. If the -** result is not constant, LoadExpr is called to bring the value into the -** primary register and 1 is returned. -*/ - void Expression0 (ExprDesc* Expr); /* Evaluate an expression via hie0 and put the result into the primary register. ** The expression is completely evaluated and all side effects complete. From 4376b833908d2280aac1df75c0098690ae70d681 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 13 Mar 2021 14:31:23 +0800 Subject: [PATCH 1925/2161] Fixed LoadAAt(). --- src/cc65/codeoptutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index 2f79b131b..36232bf3a 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -2614,7 +2614,7 @@ static int LoadAAt (CodeSeg* S, int Idx, const LoadRegInfo* LRI, Collection* Ind if (Use == REG_X) { X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, E->LI); CS_InsertEntry (S, X, Idx++); - } else if (Use == REG_A) { + } else if (Use == REG_Y) { X = NewCodeEntry (OP65_TYA, AM65_IMP, 0, 0, E->LI); CS_InsertEntry (S, X, Idx++); } else if (Use == REG_A) { From 0a8ca3041a80768590af5e18f5a6b7763c685cb4 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 13 Mar 2021 14:31:23 +0800 Subject: [PATCH 1926/2161] Changd all Find*Last*InOpenRange() to return the beginning of the open range. Fixed FindArgLastUsageInOpenRange(). --- src/cc65/codeoptutil.c | 16 ++++++++-------- src/cc65/codeoptutil.h | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index 36232bf3a..23c759fd1 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -3038,13 +3038,13 @@ int FindArgLastUsageInOpenRange (CodeSeg* S, int First, int Last, CodeEntry* E, /* Find the last index where the arg of E might be used or changed in the range (First, Last). ** ReloadY indicates whether Y is supposed to be reloaded. ** The code block in the range must be basic without any jump backwards. -** Return the index of the found entry, or -1 if not found. +** Return the index of the found entry, or First if not found. */ { LoadRegInfo LRI; CodeEntry* X; unsigned CheckedFlags = LI_SRC_USE | LI_SRC_CHG; - int Found = -1; + int Found = First; CHECK (Last <= (int)CollCount (&S->Entries)); @@ -3066,8 +3066,8 @@ int FindArgLastUsageInOpenRange (CodeSeg* S, int First, int Last, CodeEntry* E, /* TODO: We don't currently check for all cases */ if ((LRI.Flags & (LI_DIRECT | LI_CHECK_ARG | LI_CHECK_Y | LI_RELOAD_Y)) == 0) { - /* Just bail out as if the src would change right away */ - return 0; + /* Just bail out as if the src would change everywhere */ + return First < Last ? Last - 1 : First; } if ((LRI.Flags & LI_CHECK_Y) != 0) { @@ -3145,11 +3145,11 @@ int FindRegLastChangeInOpenRange (CodeSeg* S, int First, int Last, unsigned what /* Find the last possible spot where the queried ZPs, registers and/or processor ** states might be changed in the range (First, Last). The code block in the ** range must be basic without any jump backwards. -** Return the index of the found entry, or -1 if not found. +** Return the index of the found entry, or First if not found. */ { CodeEntry* X; - int Found = -1; + int Found = First; CHECK (Last <= (int)CollCount (&S->Entries)); @@ -3169,11 +3169,11 @@ int FindRegLastUseInOpenRange (CodeSeg* S, int First, int Last, unsigned what) /* Find the last possible spot where the queried ZPs, registers and/or processor ** states might be used in the range (First, Last). The code block in the range ** must be basic without any jump backwards. -** Return the index of the found entry, or -1 if not found. +** Return the index of the found entry, or First if not found. */ { CodeEntry* X; - int Found = -1; + int Found = First; CHECK (Last <= (int)CollCount (&S->Entries)); diff --git a/src/cc65/codeoptutil.h b/src/cc65/codeoptutil.h index c3596acd4..70aa5f462 100644 --- a/src/cc65/codeoptutil.h +++ b/src/cc65/codeoptutil.h @@ -433,7 +433,7 @@ int FindArgLastUsageInOpenRange (CodeSeg* S, int First, int Last, CodeEntry* E, /* Find the last index where the arg of E might be used or changed in the range (First, Last). ** ReloadY indicates whether Y is supposed to be reloaded. ** The code block in the range must be basic without any jump backwards. -** Return the index of the found entry, or -1 if not found. +** Return the index of the found entry, or First if not found. */ int FindRegFirstChangeInOpenRange (CodeSeg* S, int First, int Last, unsigned what); @@ -454,14 +454,14 @@ int FindRegLastChangeInOpenRange (CodeSeg* S, int First, int Last, unsigned what /* Find the last possible spot where the queried ZPs, registers and/or processor ** states might be changed in the range (First, Last). The code block in the ** range must be basic without any jump backwards. -** Return the index of the found entry, or -1 if not found. +** Return the index of the found entry, or First if not found. */ int FindRegLastUseInOpenRange (CodeSeg* S, int First, int Last, unsigned what); /* Find the last possible spot where the queried ZPs, registers and/or processor ** states might be used in the range (First, Last). The code block in the range ** must be basic without any jump backwards. -** Return the index of the found entry, or -1 if not found. +** Return the index of the found entry, or First if not found. */ /* End of codeoptutil.h */ From c4a2620e2925516929cccbe3be532561d282cde7 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 8 Feb 2021 22:47:51 +0800 Subject: [PATCH 1927/2161] Added an utility function to check for quasi-constant addresses (of stack variables). --- src/cc65/exprdesc.c | 9 +++++++++ src/cc65/exprdesc.h | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index f5d8cd779..aa98e1531 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -408,6 +408,15 @@ int ED_IsConst (const ExprDesc* Expr) +int ED_IsQuasiConst (const ExprDesc* Expr) +/* Return true if the expression denotes a quasi-constant of some sort. This +** can be a numeric constant, a constant address or a stack variable address. +*/ +{ + return (Expr->Flags & E_MASK_LOC) == E_LOC_NONE || ED_IsQuasiConstAddr (Expr); +} + + int ED_IsConstAddr (const ExprDesc* Expr) /* Return true if the expression denotes a constant address of some sort. This ** can be the address of a global variable (maybe with offset) or similar. diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index e1bf3117f..844af1566 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -649,6 +649,11 @@ int ED_IsConst (const ExprDesc* Expr); ** similar. */ +int ED_IsQuasiConst (const ExprDesc* Expr); +/* Return true if the expression denotes a quasi-constant of some sort. This +** can be a numeric constant, a constant address or a stack variable address. +*/ + int ED_IsConstAddr (const ExprDesc* Expr); /* Return true if the expression denotes a constant address of some sort. This ** can be the address of a global variable (maybe with offset) or similar. From aa6fdf58b8a17b747090fb521f3d9106e0c56d1c Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 8 Feb 2021 09:03:19 +0800 Subject: [PATCH 1928/2161] Addresses in constant subtraction expressions now work. Fixed codegen for cast type subtraction in constant expressions. --- src/cc65/expr.c | 211 +++++++++++++++++++++++++++++++----------------- 1 file changed, 138 insertions(+), 73 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 09a7a1f39..a38efab53 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3287,7 +3287,8 @@ static void parsesub (ExprDesc* Expr) Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ - int rscale; /* Scale factor for the result */ + int rscale; /* Scale factor for pointer arithmetics */ + int SubDone; /* No need to generate runtime code */ ED_Init (&Expr2); Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; @@ -3304,7 +3305,9 @@ static void parsesub (ExprDesc* Expr) /* Get the left hand side type, initialize operation flags */ lhst = Expr->Type; + flags = CF_INT; /* Default result type */ rscale = 1; /* Scale by 1, that is, don't scale */ + SubDone = 0; /* Generate runtime code by default */ /* Remember the output queue position, then bring the value onto the stack */ GetCodePos (&Mark1); @@ -3322,67 +3325,148 @@ static void parsesub (ExprDesc* Expr) Expr2.Type = type_uchar; } - /* Check for a constant rhs expression */ - if (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) { + /* Get the rhs type */ + rhst = Expr2.Type; - /* The right hand side is constant. Get the rhs type. */ - rhst = Expr2.Type; + /* We can only do constant expressions for: + ** - integer subtraction: + ** - numeric - numeric + ** - (integer)(base + offset) - numeric + ** - (integer)(same_base + offset) - (integer)(same_base + offset) + ** - pointer offset: + ** - (pointer)numeric - numeric * scale + ** - (base + offset) - numeric * scale + ** - (same_base + offset) - (integer)(same_base + offset) * 1 + ** - pointer diff: + ** - (numeric - numeric) / scale + ** - ((same_base + offset) - (same_base + offset)) / scale + ** - ((base + offset) - (pointer)numeric) / 1 + */ + if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Check left hand side */ - if (ED_IsConstAbs (Expr)) { + /* Pointer diff */ + if (TypeCmp (Indirect (lhst), Indirect (rhst)) < TC_QUAL_DIFF) { + Error ("Incompatible pointer types"); + } - /* Both sides are constant, remove generated code */ + /* Operate on pointers, result type is an integer */ + flags = CF_PTR; + Expr->Type = type_int; + + /* We'll have to scale the result */ + rscale = CheckedPSizeOf (lhst); + + /* Check for a constant rhs expression */ + if (ED_IsQuasiConst (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) { + /* 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) { + Expr->IVal = (Expr->IVal - Expr2.IVal) / rscale; + /* Get rid of unneeded flags etc. */ + ED_MakeConstAbsInt (Expr, Expr->IVal); + /* No runtime code */ + SubDone = 1; + } else if (rscale == 1 && ED_IsConstAbs (&Expr2)) { + Expr->IVal = (Expr->IVal - Expr2.IVal) / rscale; + /* No runtime code */ + SubDone = 1; + } + } + } + + if (!SubDone) { + /* We'll do runtime code */ + if (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) { + /* Remove pushed value from stack */ + RemoveCode (&Mark2); + /* Do the subtraction */ + g_dec (CF_INT | CF_CONST, Expr2.IVal); + } else { + /* load into the primary */ + LoadExpr (CF_NONE, &Expr2); + /* Generate code for the sub */ + g_sub (CF_INT, 0); + } + /* We must scale the result */ + if (rscale != 1) { + g_scale (CF_INT, -rscale); + } + /* Result is an rvalue in the primary register */ + ED_FinalizeRValLoad (Expr); + } else { + /* Remove pushed value from stack */ RemoveCode (&Mark1); + /* The result is always an rvalue */ + ED_MarkExprAsRVal (Expr); + } - /* Check for pointer arithmetic */ + } else if (ED_IsQuasiConst (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) { + + /* Right hand side is constant. Check left hand side. */ + if (ED_IsQuasiConst (Expr)) { + + /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - Expr->IVal -= Expr2.IVal * CheckedPSizeOf (lhst); + rscale = CheckedPSizeOf (lhst); /* Operate on pointers, result type is a pointer */ - } else if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Left is pointer, right is pointer, must scale result */ - if (TypeCmp (Indirect (lhst), Indirect (rhst)) < TC_QUAL_DIFF) { - Error ("Incompatible pointer types"); - } else { - Expr->IVal = (Expr->IVal - Expr2.IVal) / - (long)CheckedPSizeOf (lhst); - } - /* Operate on pointers, result type is an integer */ - Expr->Type = type_int; + flags = CF_PTR; } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction */ - typeadjust (Expr, &Expr2, 1); - Expr->IVal -= Expr2.IVal; - - /* Limit the calculated value to the range of its type */ - LimitExprValue (Expr); + flags = typeadjust (Expr, &Expr2, 1); } else { /* OOPS */ Error ("Invalid operands for binary operator '-'"); } + /* We can't make all subtraction expressions constant */ + if (ED_IsConstAbs (&Expr2)) { + Expr->IVal -= Expr2.IVal * rscale; + /* No runtime code */ + SubDone = 1; + } else if (rscale == 1 && Expr->Sym == Expr2.Sym) { + /* The result is the diff of the offsets */ + Expr->IVal -= Expr2.IVal; + /* Get rid of unneeded bases and flags etc. */ + ED_MakeConstAbs (Expr, Expr->IVal, Expr->Type); + /* No runtime code */ + SubDone = 1; + } + + if (SubDone) { + /* Remove pushed value from stack */ + RemoveCode (&Mark1); + if (IsClassInt (lhst)) { + /* Limit the calculated value to the range of its type */ + LimitExprValue (Expr); + } + /* The result is always an rvalue */ + ED_MarkExprAsRVal (Expr); + } else { + if (ED_IsConstAbs (&Expr2)) { + /* Remove pushed value from stack */ + RemoveCode (&Mark2); + /* Do the subtraction */ + g_dec (flags | CF_CONST, Expr2.IVal); + } else { + /* Load into the primary */ + LoadExpr (CF_NONE, &Expr2); + /* Generate code for the sub (the & is a hack here) */ + g_sub (flags & ~CF_CONST, 0); + } + /* Result is an rvalue in the primary register */ + ED_FinalizeRValLoad (Expr); + } + } else { - /* Left hand side is not constant, right hand side is. - ** Remove pushed value from stack. - */ - RemoveCode (&Mark2); - + /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ Expr2.IVal *= CheckedPSizeOf (lhst); /* Operate on pointers, result type is a pointer */ flags = CF_PTR; - } else if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Left is pointer, right is pointer, must scale result */ - if (TypeCmp (Indirect (lhst), Indirect (rhst)) < TC_QUAL_DIFF) { - Error ("Incompatible pointer types"); - } else { - rscale = CheckedPSizeOf (lhst); - } - /* Operate on pointers, result type is an integer */ - flags = CF_PTR; - Expr->Type = type_int; } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction */ flags = typeadjust (Expr, &Expr2, 1); @@ -3392,12 +3476,16 @@ static void parsesub (ExprDesc* Expr) flags = CF_INT; } - /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); - - /* If this was a pointer subtraction, we must scale the result */ - if (rscale != 1) { - g_scale (flags, -rscale); + if (ED_IsConstAbs (&Expr2)) { + /* Remove pushed value from stack */ + RemoveCode (&Mark2); + /* Do the subtraction */ + g_dec (flags | CF_CONST, Expr2.IVal); + } else { + /* Rhs is not numeric, load into the primary */ + LoadExpr (CF_NONE, &Expr2); + /* Generate code for the sub (the & is a hack here) */ + g_sub (flags & ~CF_CONST, 0); } /* Result is an rvalue in the primary register */ @@ -3406,56 +3494,33 @@ static void parsesub (ExprDesc* Expr) } else { - /* Not constant, load into the primary */ + /* Right hand side is not constant, load into the primary */ LoadExpr (CF_NONE, &Expr2); - /* Right hand side is not constant. Get the rhs type. */ - rhst = Expr2.Type; - /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ g_scale (CF_INT, CheckedPSizeOf (lhst)); /* Operate on pointers, result type is a pointer */ flags = CF_PTR; - } else if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Left is pointer, right is pointer, must scale result */ - if (TypeCmp (Indirect (lhst), Indirect (rhst)) < TC_QUAL_DIFF) { - Error ("Incompatible pointer types"); - } else { - rscale = CheckedPSizeOf (lhst); - } - /* Operate on pointers, result type is an integer */ - flags = CF_PTR; - Expr->Type = type_int; } else if (IsClassInt (lhst) && IsClassInt (rhst)) { - /* Integer subtraction. If the left hand side descriptor says that - ** the lhs is const, we have to remove this mark, since this is no - ** longer true, lhs is on stack instead. - */ - if (ED_IsLocNone (Expr)) { - ED_FinalizeRValLoad (Expr); - } /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); } else { /* OOPS */ Error ("Invalid operands for binary operator '-'"); - flags = CF_INT; } /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); - /* If this was a pointer subtraction, we must scale the result */ - if (rscale != 1) { - g_scale (flags, -rscale); - } - /* Result is an rvalue in the primary register */ ED_FinalizeRValLoad (Expr); } + /* Result type is either a pointer or an integer */ + Expr->Type = PtrConversion (Expr->Type); + /* Condition code not set */ ED_MarkAsUntested (Expr); } From f5972dfd084d4669dc4d936b19c52819efcdcbed Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 8 Feb 2021 09:03:13 +0800 Subject: [PATCH 1929/2161] Made int+pointer work in constant expressions. Fixed codegen for cast type addition in constant expressions. Calls on swapstk in 'i+ptr' is avoided when possible. --- src/cc65/expr.c | 295 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 210 insertions(+), 85 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index a38efab53..2d410581c 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3045,6 +3045,9 @@ static void parseadd (ExprDesc* Expr) CodeMark Mark; /* Remember code position */ Type* lhst; /* Type of left hand side */ Type* rhst; /* Type of right hand side */ + int lscale; + int rscale; + int AddDone; /* No need to generate runtime code */ ED_Init (&Expr2); Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; @@ -3055,44 +3058,133 @@ static void parseadd (ExprDesc* Expr) /* Get the left hand side type, initialize operation flags */ lhst = Expr->Type; flags = 0; + lscale = rscale = 1; + AddDone = 0; - /* Check for constness on both sides */ - if (ED_IsConst (Expr)) { + /* We can only do constant expressions for: + ** - integer addition: + ** - numeric + numeric + ** - (integer)(base + offset) + numeric + ** - numeric + (integer)(base + offset) + ** - pointer offset: + ** - (pointer)numeric + numeric * scale + ** - (base + offset) + numeric * scale + ** - (pointer)numeric + (integer)(base + offset) * 1 + ** - numeric * scale + (pointer)numeric + ** - numeric * scale + (base + offset) + ** - (integer)(base + offset) * 1 + (pointer)numeric + */ + if (ED_IsQuasiConst (Expr)) { /* The left hand side is a constant of some sort. Good. Get rhs */ ExprWithCheck (hie9, &Expr2); - if (ED_IsConstAbs (&Expr2)) { - /* Right hand side is a constant numeric value. Get the rhs type */ - rhst = Expr2.Type; + /* Right hand side is constant. Get the rhs type */ + rhst = Expr2.Type; + if (ED_IsQuasiConst (&Expr2)) { /* Both expressions are constants. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - Expr->IVal += Expr2.IVal * CheckedPSizeOf (lhst); - /* Result type is a pointer */ + rscale = CheckedPSizeOf (lhst); + /* Operate on pointers, result type is a pointer */ + flags = CF_PTR; } else if (IsClassInt (lhst) && IsClassPtr (rhst)) { /* Left is int, right is pointer, must scale lhs */ - Expr->IVal = Expr->IVal * CheckedPSizeOf (rhst) + Expr2.IVal; - /* Result type is a pointer */ - Expr->Type = Expr2.Type; + lscale = CheckedPSizeOf (rhst); + /* Operate on pointers, result type is a pointer */ + flags = CF_PTR; } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer addition */ - Expr->IVal += Expr2.IVal; - typeadjust (Expr, &Expr2, 1); - - /* Limit the calculated value to the range of its type */ - LimitExprValue (Expr); + flags = CF_INT; } else { /* OOPS */ - Error ("Invalid operands for binary operator '+'"); + AddDone = -1; + } + + if (ED_IsAbs (&Expr2) && + (ED_IsAbs (Expr) || lscale == 1)) { + if (IsClassInt (lhst) && IsClassInt (rhst)) { + typeadjust (Expr, &Expr2, 1); + } + Expr->IVal = Expr->IVal * lscale + Expr2.IVal * rscale; + AddDone = 1; + } else if (ED_IsAbs (Expr) && + (ED_IsAbs (&Expr2) || rscale == 1)) { + if (IsClassInt (lhst) && IsClassInt (rhst)) { + typeadjust (&Expr2, Expr, 1); + } + Expr2.IVal = Expr->IVal * lscale + Expr2.IVal * rscale; + /* Adjust the flags */ + Expr2.Flags |= Expr->Flags & ~E_MASK_KEEP_SUBEXPR; + /* Get the symbol and the name */ + *Expr = Expr2; + AddDone = 1; + } + + if (AddDone) { + /* Adjust the result */ + if (IsClassPtr (lhst)) { + /* Result type is a pointer */ + Expr->Type = PtrConversion (lhst); + } else if (IsClassPtr (rhst)) { + /* Result type is a pointer */ + Expr->Type = PtrConversion (rhst); + } else { + /* Limit the calculated value to the range of its type */ + LimitExprValue (Expr); + } + + /* The result is always an rvalue */ + ED_MarkExprAsRVal (Expr); + } else { + /* Decide the order */ + if (!ED_IsAbs (&Expr2) && rscale > 1) { + /* Rhs needs scaling but is not numeric. Load it. */ + LoadExpr (CF_NONE, &Expr2); + /* Scale rhs */ + g_scale (CF_INT, rscale); + /* Generate the code for the add */ + if (ED_IsAbs (Expr)) { + /* Numeric constant */ + g_inc (flags | CF_CONST, Expr->IVal); + } else if (ED_IsLocStack (Expr)) { + /* Local stack address */ + g_addaddr_local (flags, Expr->IVal); + } else { + /* Static address */ + g_addaddr_static (flags | GlobalModeFlags (Expr), Expr->Name, Expr->IVal); + } + } else { + /* Lhs is not numeric. Load it. */ + LoadExpr (CF_NONE, Expr); + /* Scale lhs if necessary */ + if (lscale != 1) { + g_scale (CF_INT, lscale); + } + /* Generate the code for the add */ + if (ED_IsAbs (&Expr2)) { + /* Numeric constant */ + g_inc (flags | CF_CONST, Expr2.IVal); + } else if (ED_IsLocStack (&Expr2)) { + /* Local stack address */ + g_addaddr_local (flags, Expr2.IVal); + } else { + /* Static address */ + g_addaddr_static (flags | GlobalModeFlags (&Expr2), Expr2.Name, Expr2.IVal); + } + } + + /* Result is an rvalue in primary register */ + ED_FinalizeRValLoad (Expr); } } else { - /* lhs is a constant and rhs is not constant. Load rhs into - ** the primary. + /* lhs is constant and rhs is not constant. Load rhs into the + ** primary. */ + GetCodePos (&Mark); LoadExpr (CF_NONE, &Expr2); /* Beware: The check above (for lhs) lets not only pass numeric @@ -3100,11 +3192,8 @@ static void parseadd (ExprDesc* Expr) ** with an offset. We have to check for that here. */ - /* First, get the rhs type. */ - rhst = Expr2.Type; - /* Setup flags */ - if (ED_IsLocNone (Expr)) { + if (ED_IsAbs (Expr)) { /* A numerical constant */ flags |= CF_CONST; } else { @@ -3115,62 +3204,72 @@ static void parseadd (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); + rscale = CheckedPSizeOf (lhst); + g_scale (CF_INT, rscale); /* Operate on pointers, result type is a pointer */ flags |= CF_PTR; - /* Generate the code for the add */ - if (ED_GetLoc (Expr) == E_LOC_NONE) { - /* Numeric constant */ - g_inc (flags, Expr->IVal); - } else { - /* Constant address */ - g_addaddr_static (flags, Expr->Name, Expr->IVal); - } } else if (IsClassInt (lhst) && IsClassPtr (rhst)) { - /* Left is int, right is pointer, must scale lhs. */ - unsigned ScaleFactor = CheckedPSizeOf (rhst); - + lscale = CheckedPSizeOf (rhst); /* Operate on pointers, result type is a pointer */ flags |= CF_PTR; Expr->Type = Expr2.Type; - - /* Since we do already have rhs in the primary, if lhs is - ** not a numeric constant, and the scale factor is not one - ** (no scaling), we must take the long way over the stack. - */ - if (ED_IsLocNone (Expr)) { - /* Numeric constant, scale lhs */ - Expr->IVal *= ScaleFactor; - /* Generate the code for the add */ - g_inc (flags, Expr->IVal); - } else if (ScaleFactor == 1) { - /* Constant address but no need to scale */ - g_addaddr_static (flags, Expr->Name, Expr->IVal); - } else { - /* Constant address that must be scaled */ - g_push (TypeOf (Expr2.Type), 0); /* rhs --> stack */ - g_getimmed (flags, Expr->Name, Expr->IVal); - g_scale (CF_PTR, ScaleFactor); - g_add (CF_PTR, 0); - } } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer addition */ flags |= typeadjust (Expr, &Expr2, 1); - /* Generate the code for the add */ - if (ED_IsLocNone (Expr)) { - /* Numeric constant */ - g_inc (flags, Expr->IVal); - } else { - /* Constant address */ - g_addaddr_static (flags, Expr->Name, Expr->IVal); - } } else { /* OOPS */ - Error ("Invalid operands for binary operator '+'"); - flags = CF_INT; + AddDone = -1; } + /* Generate the code for the add */ + if (!AddDone) { + if (ED_IsAbs (Expr) && + Expr->IVal >= 0 && + Expr->IVal * lscale < 256) { + /* Numeric constant */ + g_inc (flags, Expr->IVal * lscale); + AddDone = 1; + } + } + + if (!AddDone) { + if (ED_IsLocQuasiConst (&Expr2) && + rscale == 1 && + CheckedSizeOf (rhst) == SIZEOF_CHAR) { + /* Change the order back */ + RemoveCode (&Mark); + /* Load lhs */ + LoadExpr (CF_NONE, Expr); + /* Use new flags */ + flags = CF_CHAR | GlobalModeFlags (&Expr2); + /* Add the variable */ + if (ED_IsLocStack (&Expr2)) { + g_addlocal (flags, Expr2.IVal); + } else { + g_addstatic (flags, Expr2.Name, Expr2.IVal); + } + } else if (ED_IsAbs (Expr)) { + /* Numeric constant */ + g_inc (flags, Expr->IVal * lscale); + } else if (lscale == 1) { + if (ED_IsLocStack (Expr)) { + /* Constant address */ + g_addaddr_local (flags, Expr->IVal); + } else { + g_addaddr_static (flags, Expr->Name, Expr->IVal); + } + } else { + /* Since we do already have rhs in the primary, if lhs is + ** not a numeric constant, and the scale factor is not one + ** (no scaling), we must take the long way over the stack. + */ + g_push (TypeOf (Expr2.Type), 0); /* rhs --> stack */ + LoadExpr (CF_NONE, Expr); + g_scale (CF_PTR, lscale); + g_add (CF_PTR, 0); + } + } /* Array and function types must be converted to pointer types */ Expr->Type = PtrConversion (Expr->Type); @@ -3181,20 +3280,21 @@ static void parseadd (ExprDesc* Expr) } else { /* Left hand side is not constant. Get the value onto the stack. */ - LoadExpr (CF_NONE, Expr); /* --> primary register */ + LoadExpr (CF_NONE, Expr); /* --> primary register */ GetCodePos (&Mark); - g_push (TypeOf (Expr->Type), 0); /* --> stack */ + flags = TypeOf (Expr->Type); /* default codegen type */ + g_push (flags, 0); /* --> stack */ /* Evaluate the rhs */ MarkedExprWithCheck (hie9, &Expr2); + /* Get the rhs type */ + rhst = Expr2.Type; + /* Check for a constant rhs expression */ if (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) { - /* Right hand side is a constant. Get the rhs type */ - rhst = Expr2.Type; - - /* Remove pushed value from stack */ + /* Rhs is a constant. Remove pushed lhs from stack. */ RemoveCode (&Mark); /* Check for pointer arithmetic */ @@ -3214,8 +3314,7 @@ static void parseadd (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } else { /* OOPS */ - Error ("Invalid operands for binary operator '+'"); - flags = CF_INT; + AddDone = -1; } /* Generate code for the add */ @@ -3223,23 +3322,37 @@ static void parseadd (ExprDesc* Expr) } else { - /* Not constant, load into the primary */ - LoadExpr (CF_NONE, &Expr2); - - /* lhs and rhs are not constant. Get the rhs type. */ - rhst = Expr2.Type; - - /* Check for pointer arithmetic */ + /* Lhs and rhs are not so constant. Check for pointer arithmetic. */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); + rscale = CheckedPSizeOf (lhst); + if (ED_IsAbs (&Expr2)) { + Expr2.IVal *= rscale; + /* Load rhs into the primary */ + LoadExpr (CF_NONE, &Expr2); + } else { + /* Load rhs into the primary */ + LoadExpr (CF_NONE, &Expr2); + g_scale (CF_INT, rscale); + } /* Operate on pointers, result type is a pointer */ flags = CF_PTR; } else if (IsClassInt (lhst) && IsClassPtr (rhst)) { /* Left is int, right is pointer, must scale lhs */ - g_tosint (TypeOf (lhst)); /* Make sure TOS is int */ - g_swap (CF_INT); /* Swap TOS and primary */ - g_scale (CF_INT, CheckedPSizeOf (rhst)); + lscale = CheckedPSizeOf (rhst); + if (ED_CodeRangeIsEmpty (&Expr2)) { + RemoveCode (&Mark); /* Remove pushed value from stack */ + g_scale (CF_INT, lscale); + g_push (CF_PTR, 0); /* --> stack */ + LoadExpr (CF_NONE, &Expr2); /* Load rhs into primary register */ + } else { + g_tosint (TypeOf (lhst)); /* Make sure TOS is int */ + LoadExpr (CF_NONE, &Expr2); /* Load rhs into primary register */ + if (lscale != 1) { + g_swap (CF_INT); /* Swap TOS and primary */ + g_scale (CF_INT, CheckedPSizeOf (rhst)); + } + } /* Operate on pointers, result type is a pointer */ flags = CF_PTR; Expr->Type = Expr2.Type; @@ -3254,10 +3367,12 @@ static void parseadd (ExprDesc* Expr) ** when trying to apply another solution. */ flags = typeadjust (Expr, &Expr2, 0) & ~CF_CONST; + /* Load rhs into the primary */ + LoadExpr (CF_NONE, &Expr2); } else { /* OOPS */ - Error ("Invalid operands for binary operator '+'"); - flags = CF_INT; + AddDone = -1; + /* We can't just goto End as that would leave the stack unbalanced */ } /* Generate code for the add */ @@ -3265,10 +3380,20 @@ static void parseadd (ExprDesc* Expr) } + /* Array and function types must be converted to pointer types */ + Expr->Type = PtrConversion (Expr->Type); + /* Result is an rvalue in primary register */ ED_FinalizeRValLoad (Expr); } + if (AddDone < 0) { + Error ("Invalid operands for binary operator '+'"); + } else { + /* Array and function types must be converted to pointer types */ + Expr->Type = PtrConversion (Expr->Type); + } + /* Condition code not set */ ED_MarkAsUntested (Expr); } From 99c7fe0ada96dd7283e60cc16cc63b23ab919014 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 8 Feb 2021 09:03:23 +0800 Subject: [PATCH 1930/2161] Reusing code from parseadd() for ArrayRef(). Now index[ptr] works in constant expressions. Fixed codegen for cast type in constant expressions. Calls on swapstk in 'i[ptr]' is avoided when possible. --- src/cc65/expr.c | 423 +++++++++++------------------------------------- 1 file changed, 98 insertions(+), 325 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 2d410581c..e2cd09468 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -74,11 +74,20 @@ static GenDesc GenOASGN = { TOK_OR_ASSIGN, GEN_NOPUSH, g_or }; /*****************************************************************************/ -/* Helper functions */ +/* Forward declarations */ /*****************************************************************************/ +static void parseadd (ExprDesc* Expr, int DoArrayRef); + + + +/*****************************************************************************/ +/* Helper functions */ +/*****************************************************************************/ + + static unsigned GlobalModeFlags (const ExprDesc* Expr) /* Return the addressing mode flags for the given expression */ { @@ -1333,294 +1342,6 @@ static void Primary (ExprDesc* E) -static void ArrayRef (ExprDesc* Expr) -/* Handle an array reference. This function needs a rewrite. */ -{ - int ConstBaseAddr; - ExprDesc Subscript; - CodeMark Mark1; - CodeMark Mark2; - TypeCode Qualifiers; - Type* ElementType; - Type* tptr1; - - ED_Init (&Subscript); - Subscript.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - - /* Skip the bracket */ - NextToken (); - - /* Get the type of left side */ - tptr1 = Expr->Type; - - /* We can apply a special treatment for arrays that have a const base - ** address. This is true for most arrays and will produce a lot better - ** code. Check if this is a "quasi-const base" address. - */ - ConstBaseAddr = ED_IsRVal (Expr) && ED_IsLocQuasiConst (Expr); - - /* If we have a quasi-const base address, we delay the address fetch */ - GetCodePos (&Mark1); - if (!ConstBaseAddr) { - /* Get a pointer to the array into the primary */ - LoadExpr (CF_NONE, Expr); - - /* Get the array pointer on stack. Do not push more than 16 - ** bit, even if this value is greater, since we cannot handle - ** other than 16bit stuff when doing indexing. - */ - GetCodePos (&Mark2); - g_push (CF_PTR, 0); - } - - /* TOS now contains ptr to array elements. Get the subscript. */ - MarkedExprWithCheck (hie0, &Subscript); - - /* Check the types of array and subscript. We can either have a - ** pointer/array to the left, in which case the subscript must be of an - ** integer type, or we have an integer to the left, in which case the - ** subscript must be a pointer/array. - ** Since we do the necessary checking here, we can rely later on the - ** correct types. - */ - Qualifiers = T_QUAL_NONE; - if (IsClassPtr (Expr->Type)) { - if (!IsClassInt (Subscript.Type)) { - Error ("Array subscript is not an integer"); - /* To avoid any compiler errors, make the expression a valid int */ - ED_MakeConstAbsInt (&Subscript, 0); - } - if (IsTypeArray (Expr->Type)) { - Qualifiers = GetQualifier (Expr->Type); - } - ElementType = Indirect (Expr->Type); - } else if (IsClassInt (Expr->Type)) { - if (!IsClassPtr (Subscript.Type)) { - Error ("Subscripted value is neither array nor pointer"); - /* To avoid compiler errors, make the subscript a char[] at - ** address 0. - */ - ED_MakeConstAbs (&Subscript, 0, GetCharArrayType (1)); - } else if (IsTypeArray (Subscript.Type)) { - Qualifiers = GetQualifier (Subscript.Type); - } - ElementType = Indirect (Subscript.Type); - } else { - Error ("Cannot subscript"); - /* To avoid compiler errors, fake both the array and the subscript, so - ** we can just proceed. - */ - ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - ED_MakeConstAbsInt (&Subscript, 0); - ElementType = Indirect (Expr->Type); - } - - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - - /* If the subscript is a bit-field, load it and make it an rvalue */ - if (ED_IsBitField (&Subscript)) { - LoadExpr (CF_NONE, &Subscript); - ED_FinalizeRValLoad (&Subscript); - } - - /* Make the address of the array element from the base and subscript */ - if (ED_IsConstAbs (&Subscript) && ED_CodeRangeIsEmpty (&Subscript)) { - - /* The array subscript is a constant. Since we can have the element - ** address directly as base+offset, we can remove the array address - ** push onto the stack before if loading subscript doesn't tamper that - ** address in the primary. - */ - if (!ConstBaseAddr) { - RemoveCode (&Mark2); - } else { - /* Get an array pointer into the primary */ - LoadExpr (CF_NONE, Expr); - } - - if (IsClassPtr (Expr->Type)) { - - /* Lhs is pointer/array. Scale the subscript value according to - ** the element size. - */ - Subscript.IVal *= CheckedSizeOf (ElementType); - - /* Remove the address load code */ - RemoveCode (&Mark1); - - /* In case of an array, we can adjust the offset of the expression - ** already in Expr. If the base address was a constant, we can even - ** remove the code that loaded the address into the primary. - */ - if (!IsTypeArray (Expr->Type)) { - - /* It's a pointer, so we do have to load it into the primary - ** first (if it's not already there). - */ - if (!ConstBaseAddr && ED_IsLVal (Expr)) { - LoadExpr (CF_NONE, Expr); - ED_FinalizeRValLoad (Expr); - } - } - - /* Adjust the offset */ - Expr->IVal += Subscript.IVal; - - } else { - - /* Scale the lhs value according to the element type */ - g_scale (TypeOf (tptr1), CheckedSizeOf (ElementType)); - - /* Add the subscript. Since arrays are indexed by integers, - ** we will ignore the true type of the subscript here and - ** use always an int. #### Use offset but beware of LoadExpr! - */ - g_inc (CF_INT | CF_CONST, Subscript.IVal); - - } - - } else { - - /* Array subscript is not constant. Load it into the primary */ - GetCodePos (&Mark2); - LoadExpr (CF_NONE, &Subscript); - - /* Do scaling */ - if (IsClassPtr (Expr->Type)) { - - /* Indexing is based on unsigneds, so we will just use the integer - ** portion of the index (which is in (e)ax, so there's no further - ** action required). - */ - g_scale (CF_INT, CheckedSizeOf (ElementType)); - - } else { - - /* Get the int value on top. If we come here, we're sure, both - ** values are 16 bit (the first one was truncated if necessary - ** and the second one is a pointer). Note: If ConstBaseAddr is - ** true, we don't have a value on stack, so to "swap" both, just - ** push the subscript. - */ - if (ConstBaseAddr) { - g_push (CF_INT, 0); - LoadExpr (CF_NONE, Expr); - ConstBaseAddr = 0; - } else { - g_swap (CF_INT); - } - - /* Scale it */ - g_scale (TypeOf (tptr1), CheckedSizeOf (ElementType)); - - } - - /* The offset is now in the primary register. It we didn't have a - ** constant base address for the lhs, the lhs address is already - ** on stack, and we must add the offset. If the base address was - ** constant, we call special functions to add the address to the - ** offset value. - */ - if (!ConstBaseAddr) { - - /* The array base address is on stack and the subscript is in the - ** primary. Add both. - */ - g_add (CF_INT, 0); - - } else { - - /* The subscript is in the primary, and the array base address is - ** in Expr. If the subscript has itself a constant address, it is - ** often a better idea to reverse again the order of the - ** evaluation. This will generate better code if the subscript is - ** a byte sized variable. But beware: This is only possible if the - ** subscript was not scaled, that is, if this was a byte array - ** or pointer. - */ - if (ED_IsLocQuasiConst (&Subscript) && - CheckedSizeOf (ElementType) == SIZEOF_CHAR) { - - unsigned Flags; - - /* Reverse the order of evaluation */ - if (CheckedSizeOf (Subscript.Type) == SIZEOF_CHAR) { - Flags = CF_CHAR; - } else { - Flags = CF_INT; - } - RemoveCode (&Mark2); - - /* Get a pointer to the array into the primary. */ - LoadExpr (CF_NONE, Expr); - - /* Add the variable */ - if (ED_IsLocStack (&Subscript)) { - g_addlocal (Flags, Subscript.IVal); - } else { - Flags |= GlobalModeFlags (&Subscript); - g_addstatic (Flags, Subscript.Name, Subscript.IVal); - } - } else { - - if (ED_IsLocNone (Expr) || - (ED_IsLocAbs (Expr) && ED_IsAddrExpr (Expr))) { - /* Constant numeric address. Just add it */ - g_inc (CF_INT, Expr->IVal); - } else if (ED_IsLocStack (Expr)) { - /* Base address is a local variable address */ - if (ED_IsAddrExpr (Expr)) { - g_addaddr_local (CF_INT, Expr->IVal); - } else { - g_addlocal (CF_PTR, Expr->IVal); - } - } else { - /* Base address is a static variable address */ - unsigned Flags = CF_INT | GlobalModeFlags (Expr); - if (ED_IsAddrExpr (Expr)) { - /* Add the address of the location */ - g_addaddr_static (Flags, Expr->Name, Expr->IVal); - } else { - /* Add the contents of the location */ - g_addstatic (Flags, Expr->Name, Expr->IVal); - } - } - } - } - - /* The address of the element is an rvalue in the primary */ - ED_FinalizeRValLoad (Expr); - - } - - /* The final result is usually an lvalue expression of element type - ** referenced in the primary, unless it is once again an array. We can just - ** assume the usual case first, and change it later if necessary. - */ - ED_IndExpr (Expr); - Expr->Type = ElementType; - - /* An array element is actually a variable. So the rules for variables with - ** respect to the reference type apply: If it's an array, it is virtually - ** an rvalue address, otherwise it's an lvalue reference. (A function would - ** also be an rvalue address, but an array cannot contain functions). - */ - if (IsTypeArray (Expr->Type)) { - ED_AddrExpr (Expr); - } - - /* Consume the closing bracket */ - ConsumeRBrack (); -} - - - static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { @@ -1793,7 +1514,7 @@ static void hie11 (ExprDesc *Expr) case TOK_LBRACK: /* Array reference */ - ArrayRef (Expr); + parseadd (Expr, 1); break; case TOK_LPAREN: @@ -3034,10 +2755,11 @@ static void hie9 (ExprDesc *Expr) -static void parseadd (ExprDesc* Expr) -/* Parse an expression with the binary plus operator. Expr contains the -** unprocessed left hand side of the expression and will contain the -** result of the expression on return. +static void parseadd (ExprDesc* Expr, int DoArrayRef) +/* Parse an expression with the binary plus or subscript operator. Expr contains +** the unprocessed left hand side of the expression and will contain the result +** of the expression on return. If DoArrayRef is zero, this evaluates the binary +** plus operation. Otherwise, this evaluates the subscript operation. */ { ExprDesc Expr2; @@ -3052,7 +2774,7 @@ static void parseadd (ExprDesc* Expr) ED_Init (&Expr2); Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Skip the PLUS token */ + /* Skip the PLUS or opening bracket token */ NextToken (); /* Get the left hand side type, initialize operation flags */ @@ -3077,7 +2799,7 @@ static void parseadd (ExprDesc* Expr) if (ED_IsQuasiConst (Expr)) { /* The left hand side is a constant of some sort. Good. Get rhs */ - ExprWithCheck (hie9, &Expr2); + ExprWithCheck (DoArrayRef ? hie0 : hie9, &Expr2); /* Right hand side is constant. Get the rhs type */ rhst = Expr2.Type; @@ -3094,7 +2816,7 @@ static void parseadd (ExprDesc* Expr) lscale = CheckedPSizeOf (rhst); /* Operate on pointers, result type is a pointer */ flags = CF_PTR; - } else if (IsClassInt (lhst) && IsClassInt (rhst)) { + } else if (!DoArrayRef && IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer addition */ flags = CF_INT; } else { @@ -3123,20 +2845,22 @@ static void parseadd (ExprDesc* Expr) } if (AddDone) { - /* Adjust the result */ - if (IsClassPtr (lhst)) { - /* Result type is a pointer */ - Expr->Type = PtrConversion (lhst); - } else if (IsClassPtr (rhst)) { - /* Result type is a pointer */ - Expr->Type = PtrConversion (rhst); - } else { - /* Limit the calculated value to the range of its type */ - LimitExprValue (Expr); - } + /* Adjust the result for addition */ + if (!DoArrayRef) { + if (IsClassPtr (lhst)) { + /* Result type is a pointer */ + Expr->Type = lhst; + } else if (IsClassPtr (rhst)) { + /* Result type is a pointer */ + Expr->Type = rhst; + } else { + /* Limit the calculated value to the range of its type */ + LimitExprValue (Expr); + } - /* The result is always an rvalue */ - ED_MarkExprAsRVal (Expr); + /* The result is always an rvalue */ + ED_MarkExprAsRVal (Expr); + } } else { /* Decide the order */ if (!ED_IsAbs (&Expr2) && rscale > 1) { @@ -3214,7 +2938,7 @@ static void parseadd (ExprDesc* Expr) /* Operate on pointers, result type is a pointer */ flags |= CF_PTR; Expr->Type = Expr2.Type; - } else if (IsClassInt (lhst) && IsClassInt (rhst)) { + } else if (!DoArrayRef && IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer addition */ flags |= typeadjust (Expr, &Expr2, 1); } else { @@ -3270,8 +2994,6 @@ static void parseadd (ExprDesc* Expr) g_add (CF_PTR, 0); } } - /* Array and function types must be converted to pointer types */ - Expr->Type = PtrConversion (Expr->Type); /* Result is an rvalue in primary register */ ED_FinalizeRValLoad (Expr); @@ -3286,7 +3008,7 @@ static void parseadd (ExprDesc* Expr) g_push (flags, 0); /* --> stack */ /* Evaluate the rhs */ - MarkedExprWithCheck (hie9, &Expr2); + MarkedExprWithCheck (DoArrayRef ? hie0 : hie9, &Expr2); /* Get the rhs type */ rhst = Expr2.Type; @@ -3309,7 +3031,7 @@ static void parseadd (ExprDesc* Expr) /* Operate on pointers, result type is a pointer */ flags = CF_PTR; Expr->Type = Expr2.Type; - } else if (IsClassInt (lhst) && IsClassInt (rhst)) { + } else if (!DoArrayRef && IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer addition */ flags = typeadjust (Expr, &Expr2, 1); } else { @@ -3356,7 +3078,7 @@ static void parseadd (ExprDesc* Expr) /* Operate on pointers, result type is a pointer */ flags = CF_PTR; Expr->Type = Expr2.Type; - } else if (IsClassInt (lhst) && IsClassInt (rhst)) { + } else if (!DoArrayRef && IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer addition. Note: Result is never constant. ** Problem here is that typeadjust does not know if the ** variable is an rvalue or lvalue, so if both operands @@ -3380,18 +3102,69 @@ static void parseadd (ExprDesc* Expr) } - /* Array and function types must be converted to pointer types */ - Expr->Type = PtrConversion (Expr->Type); - /* Result is an rvalue in primary register */ ED_FinalizeRValLoad (Expr); } - if (AddDone < 0) { - Error ("Invalid operands for binary operator '+'"); + /* Deal with array ref */ + if (DoArrayRef) { + TypeCode Qualifiers = T_QUAL_NONE; + Type* ElementType; + + /* Check the types of array and subscript */ + if (IsClassPtr (lhst)) { + if (!IsClassInt (rhst)) { + Error ("Array subscript is not an integer"); + ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); + } else if (IsTypeArray (lhst)) { + Qualifiers = GetQualifier (lhst); + } + } else if (IsClassInt (lhst)) { + if (!IsClassPtr (rhst)) { + Error ("Subscripted value is neither array nor pointer"); + ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); + } else if (IsTypeArray (rhst)) { + Qualifiers = GetQualifier (rhst); + } + } else { + Error ("Cannot subscript"); + ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); + } + + /* The element type has the combined qualifiers from itself and the array, + ** it is a member of (if any). + */ + ElementType = Indirect (Expr->Type); + if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { + ElementType = TypeDup (ElementType); + ElementType->C |= Qualifiers; + } + + /* The final result is usually an lvalue expression of element type + ** referenced in the primary, unless it is once again an array. We can just + ** assume the usual case first, and change it later if necessary. + */ + ED_IndExpr (Expr); + Expr->Type = ElementType; + + /* An array element is actually a variable. So the rules for variables with + ** respect to the reference type apply: If it's an array, it is virtually + ** an rvalue address, otherwise it's an lvalue reference. (A function would + ** also be an rvalue address, but an array cannot contain functions). + */ + if (IsTypeArray (Expr->Type)) { + ED_AddrExpr (Expr); + } + + /* Consume the closing bracket */ + ConsumeRBrack (); } else { - /* Array and function types must be converted to pointer types */ - Expr->Type = PtrConversion (Expr->Type); + if (AddDone < 0) { + Error ("Invalid operands for binary operator '+'"); + } else { + /* Array and function types must be converted to pointer types */ + Expr->Type = PtrConversion (Expr->Type); + } } /* Condition code not set */ @@ -3436,7 +3209,7 @@ static void parsesub (ExprDesc* Expr) /* Remember the output queue position, then bring the value onto the stack */ GetCodePos (&Mark1); - LoadExpr (CF_NONE, Expr); /* --> primary register */ + LoadExpr (CF_NONE, Expr); /* --> primary register */ GetCodePos (&Mark2); g_push (TypeOf (lhst), 0); /* --> stack */ @@ -3658,7 +3431,7 @@ void hie8 (ExprDesc* Expr) ExprWithCheck (hie9, Expr); while (CurTok.Tok == TOK_PLUS || CurTok.Tok == TOK_MINUS) { if (CurTok.Tok == TOK_PLUS) { - parseadd (Expr); + parseadd (Expr, 0); } else { parsesub (Expr); } From 8eeaaa3f36a973fdae29e7c66cc519104376c4d4 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 15 Feb 2021 09:50:46 +0800 Subject: [PATCH 1931/2161] Made certain types of comparison between addresses in constant expressions work. --- src/cc65/expr.c | 109 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 73 insertions(+), 36 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index e2cd09468..6684d9c56 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -2361,7 +2361,6 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ void (*hienext) (ExprDesc*)) /* Helper function for the compare operators */ { - CodeMark Mark0; CodeMark Mark1; CodeMark Mark2; const GenDesc* Gen; @@ -2370,7 +2369,6 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ int rconst; /* Operand is a constant */ - GetCodePos (&Mark0); ExprWithCheck (hienext, Expr); while ((Gen = FindGen (CurTok.Tok, Ops)) != 0) { @@ -2395,11 +2393,11 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ GetCodePos (&Mark1); ltype = TypeOf (Expr->Type); if (ED_IsConstAbs (Expr)) { - /* Constant value */ + /* Numeric constant value */ GetCodePos (&Mark2); g_push (ltype | CF_CONST, Expr->IVal); } else { - /* Value not constant */ + /* Value not numeric constant */ LoadExpr (CF_NONE, Expr); GetCodePos (&Mark2); g_push (ltype, 0); @@ -2413,10 +2411,10 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ Expr2.Type = PointerTo (Expr2.Type); } - /* Check for a constant expression */ + /* Check for a numeric constant expression */ rconst = (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)); if (!rconst) { - /* Not constant, load into the primary */ + /* Not numeric constant, load into the primary */ LoadExpr (CF_NONE, &Expr2); } @@ -2475,10 +2473,76 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ } } - /* Check for const operands */ - if (ED_IsConstAbs (Expr) && rconst) { + /* Check for numeric constant operands */ + if ((ED_IsAddrExpr (Expr) && ED_IsNullPtr (&Expr2)) || + (ED_IsNullPtr (Expr) && ED_IsAddrExpr (&Expr2))) { - /* Both operands are constant, remove the generated code */ + /* Object addresses are inequal to null pointer */ + Expr->IVal = (Tok != TOK_EQ); + if (ED_IsNullPtr (&Expr2)) { + if (Tok == TOK_LT || Tok == TOK_LE) { + Expr->IVal = 0; + } + } else { + if (Tok == TOK_GT || Tok == TOK_GE) { + Expr->IVal = 0; + } + } + + /* Get rid of unwanted flags */ + ED_MakeConstBool (Expr, Expr->IVal); + + /* The result is constant, this is suspicious when not in + ** preprocessor mode. + */ + WarnConstCompareResult (Expr); + + if (ED_CodeRangeIsEmpty (&Expr2)) { + /* Both operands are static, remove the load code */ + RemoveCode (&Mark1); + } else { + /* Drop pushed lhs */ + g_drop (sizeofarg (ltype)); + pop (ltype); + } + + } else if (ED_IsAddrExpr (Expr) && + ED_IsAddrExpr (&Expr2) && + Expr->Sym == Expr2.Sym) { + + /* Evaluate the result for static addresses */ + unsigned long Val1 = Expr->IVal; + unsigned long Val2 = Expr2.IVal; + switch (Tok) { + case TOK_EQ: Expr->IVal = (Val1 == Val2); break; + case TOK_NE: Expr->IVal = (Val1 != Val2); break; + case TOK_LT: Expr->IVal = (Val1 < Val2); break; + case TOK_LE: Expr->IVal = (Val1 <= Val2); break; + case TOK_GE: Expr->IVal = (Val1 >= Val2); break; + case TOK_GT: Expr->IVal = (Val1 > Val2); break; + default: Internal ("hie_compare: got token 0x%X\n", Tok); + } + + /* Get rid of unwanted flags */ + ED_MakeConstBool (Expr, Expr->IVal); + + /* If the result is constant, this is suspicious when not in + ** preprocessor mode. + */ + WarnConstCompareResult (Expr); + + if (ED_CodeRangeIsEmpty (&Expr2)) { + /* Both operands are static, remove the load code */ + RemoveCode (&Mark1); + } else { + /* Drop pushed lhs */ + g_drop (sizeofarg (ltype)); + pop (ltype); + } + + } else if (ED_IsConstAbs (Expr) && rconst) { + + /* Both operands are numeric constant, remove the generated code */ RemoveCode (&Mark1); /* Determine if this is a signed or unsigned compare */ @@ -2522,33 +2586,6 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ */ WarnConstCompareResult (Expr); - } else if (ED_CodeRangeIsEmpty (&Expr2) && - ((ED_IsAddrExpr (Expr) && ED_IsNullPtr (&Expr2)) || - (ED_IsNullPtr (Expr) && (ED_IsAddrExpr (&Expr2))))) { - - /* Object addresses are inequal to null pointer */ - Expr->IVal = (Tok != TOK_EQ); - if (ED_IsNullPtr (&Expr2)) { - if (Tok == TOK_LT || Tok == TOK_LE) { - Expr->IVal = 0; - } - } else { - if (Tok == TOK_GT || Tok == TOK_GE) { - Expr->IVal = 0; - } - } - - /* Get rid of unwanted flags */ - ED_MakeConstBool (Expr, Expr->IVal); - - /* If the result is constant, this is suspicious when not in - ** preprocessor mode. - */ - WarnConstCompareResult (Expr); - - /* Both operands are static, remove the generated code */ - RemoveCode (&Mark1); - } else { /* Determine the signedness of the operands */ From b02838439c0c4a237e6094b71415193e44485be4 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 22 Feb 2021 12:33:26 +0800 Subject: [PATCH 1932/2161] Changed g_addaddr_local() codegen to reduce code size. --- src/cc65/codegen.c | 51 +++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index bf7c900ab..f8a1dcdf6 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -2112,29 +2112,38 @@ void g_addaddr_local (unsigned flags attribute ((unused)), int offs) /* Add the offset */ offs -= StackPtr; - if (offs != 0) { - /* We cannot address more then 256 bytes of locals anyway */ - L = GetLocalLabel(); - CheckLocalOffs (offs); - AddCodeLine ("clc"); - AddCodeLine ("adc #$%02X", offs & 0xFF); - /* Do also skip the CLC insn below */ - AddCodeLine ("bcc %s", LocalLabelName (L)); - AddCodeLine ("inx"); - } + if (IS_Get (&CodeSizeFactor) <= 100) { + if (offs != 0) { + /* We cannot address more then 256 bytes of locals anyway */ + g_inc (CF_INT | CF_CONST, offs); + } + /* Add the current stackpointer value */ + AddCodeLine ("jsr leaaxsp"); + } else { + if (offs != 0) { + /* We cannot address more then 256 bytes of locals anyway */ + L = GetLocalLabel(); + CheckLocalOffs (offs); + AddCodeLine ("clc"); + AddCodeLine ("adc #$%02X", offs & 0xFF); + /* Do also skip the CLC insn below */ + AddCodeLine ("bcc %s", LocalLabelName (L)); + AddCodeLine ("inx"); + } - /* Add the current stackpointer value */ - AddCodeLine ("clc"); - if (L != 0) { - /* Label was used above */ - g_defcodelabel (L); + /* Add the current stackpointer value */ + AddCodeLine ("clc"); + if (L != 0) { + /* Label was used above */ + g_defcodelabel (L); + } + AddCodeLine ("adc sp"); + AddCodeLine ("tay"); + AddCodeLine ("txa"); + AddCodeLine ("adc sp+1"); + AddCodeLine ("tax"); + AddCodeLine ("tya"); } - AddCodeLine ("adc sp"); - AddCodeLine ("tay"); - AddCodeLine ("txa"); - AddCodeLine ("adc sp+1"); - AddCodeLine ("tax"); - AddCodeLine ("tya"); } From d3c495e8b99a385231720358f5f4464866cd3ea8 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 16 Feb 2021 22:19:34 +0100 Subject: [PATCH 1933/2161] ar65: fix parallel builds by using a per-process temp file --- src/ar65/library.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ar65/library.c b/src/ar65/library.c index 08fdeb563..fd761d04e 100644 --- a/src/ar65/library.c +++ b/src/ar65/library.c @@ -249,9 +249,10 @@ void LibOpen (const char* Name, int MustExist, int NeedTemp) if (NeedTemp) { /* Create the temporary library name */ - NewLibName = xmalloc (strlen (Name) + strlen (".temp") + 1); + NewLibName = xmalloc (strlen (Name) + strlen (".temp-") + 8 + 1); strcpy (NewLibName, Name); - strcat (NewLibName, ".temp"); + strcat (NewLibName, ".temp-"); + sprintf (NewLibName + strlen (NewLibName), "%X", (unsigned int)getpid()); /* Create the temporary library */ NewLib = fopen (NewLibName, "w+b"); From 64449f0f54496908d183510ac617da8a8b11acca Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 17 Feb 2021 00:36:58 +0100 Subject: [PATCH 1934/2161] ar65: better version of last change --- src/ar65/library.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ar65/library.c b/src/ar65/library.c index fd761d04e..c142df99a 100644 --- a/src/ar65/library.c +++ b/src/ar65/library.c @@ -249,10 +249,8 @@ void LibOpen (const char* Name, int MustExist, int NeedTemp) if (NeedTemp) { /* Create the temporary library name */ - NewLibName = xmalloc (strlen (Name) + strlen (".temp-") + 8 + 1); - strcpy (NewLibName, Name); - strcat (NewLibName, ".temp-"); - sprintf (NewLibName + strlen (NewLibName), "%X", (unsigned int)getpid()); + NewLibName = xmalloc (strlen (Name) + (sizeof (".temp-") - 1) + 2 * sizeof (unsigned int) + 1); + sprintf (NewLibName, "%s.temp-%X", Name, (unsigned int)getpid ()); /* Create the temporary library */ NewLib = fopen (NewLibName, "w+b"); From 358d750b3e8379b3f36d8bf9c514532e4d51743a Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 16 Feb 2021 22:19:34 +0100 Subject: [PATCH 1935/2161] ar65: fix parallel builds by using a per-process temp file --- src/ar65/library.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ar65/library.c b/src/ar65/library.c index c142df99a..991cfe110 100644 --- a/src/ar65/library.c +++ b/src/ar65/library.c @@ -36,6 +36,8 @@ #include <stdio.h> #include <string.h> #include <errno.h> +#include <sys/types.h> +#include <unistd.h> /* common */ #include "cmdline.h" From 9b05fe9982a1c377d224071e4f68a813283a7b50 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 18 Mar 2021 20:08:22 +0100 Subject: [PATCH 1936/2161] src/ar65/library.c: fix compilation on Windows --- src/ar65/library.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ar65/library.c b/src/ar65/library.c index 991cfe110..342bc25d3 100644 --- a/src/ar65/library.c +++ b/src/ar65/library.c @@ -36,8 +36,12 @@ #include <stdio.h> #include <string.h> #include <errno.h> +#if defined(_WIN32) +#include <process.h> +#else #include <sys/types.h> #include <unistd.h> +#endif /* common */ #include "cmdline.h" From cd116e5ba06293b1b0dff81b6b3bebaff6b6e765 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 18 Mar 2021 20:18:23 +0100 Subject: [PATCH 1937/2161] src/ar65/library.c: style fix --- src/ar65/library.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ar65/library.c b/src/ar65/library.c index 342bc25d3..d12fb198a 100644 --- a/src/ar65/library.c +++ b/src/ar65/library.c @@ -37,10 +37,10 @@ #include <string.h> #include <errno.h> #if defined(_WIN32) -#include <process.h> +# include <process.h> #else -#include <sys/types.h> -#include <unistd.h> +# include <sys/types.h> +# include <unistd.h> #endif /* common */ From 6974c1ff12981f29b74ca183ac405edd293360f6 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 19 Mar 2021 15:02:53 +0800 Subject: [PATCH 1938/2161] Fixed and cleaned up codegen logic with arithmetic conversion in addition and subtraction. --- src/cc65/expr.c | 60 +++++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 6684d9c56..4f579b7ae 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -2861,17 +2861,18 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) AddDone = -1; } + /* Do constant calculation if we can */ if (ED_IsAbs (&Expr2) && (ED_IsAbs (Expr) || lscale == 1)) { if (IsClassInt (lhst) && IsClassInt (rhst)) { - typeadjust (Expr, &Expr2, 1); + Expr->Type = ArithmeticConvert (Expr->Type, Expr2.Type); } Expr->IVal = Expr->IVal * lscale + Expr2.IVal * rscale; AddDone = 1; } else if (ED_IsAbs (Expr) && (ED_IsAbs (&Expr2) || rscale == 1)) { if (IsClassInt (lhst) && IsClassInt (rhst)) { - typeadjust (&Expr2, Expr, 1); + Expr2.Type = ArithmeticConvert (Expr2.Type, Expr->Type); } Expr2.IVal = Expr->IVal * lscale + Expr2.IVal * rscale; /* Adjust the flags */ @@ -3053,7 +3054,7 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Check for a constant rhs expression */ if (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) { - /* Rhs is a constant. Remove pushed lhs from stack. */ + /* Rhs is a numeric constant. Remove pushed lhs from stack. */ RemoveCode (&Mark); /* Check for pointer arithmetic */ @@ -3081,7 +3082,7 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) } else { - /* Lhs and rhs are not so constant. Check for pointer arithmetic. */ + /* Lhs and rhs are not so "numeric constant". Check for pointer arithmetic. */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ rscale = CheckedPSizeOf (lhst); @@ -3116,16 +3117,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) flags = CF_PTR; Expr->Type = Expr2.Type; } else if (!DoArrayRef && IsClassInt (lhst) && IsClassInt (rhst)) { - /* Integer addition. Note: Result is never constant. - ** Problem here is that typeadjust does not know if the - ** variable is an rvalue or lvalue, so if both operands - ** are dereferenced constant numeric addresses, typeadjust - ** thinks the operation works on constants. Removing - ** CF_CONST here means handling the symptoms, however, the - ** whole parser is such a mess that I fear to break anything - ** when trying to apply another solution. - */ - flags = typeadjust (Expr, &Expr2, 0) & ~CF_CONST; + /* Integer addition */ + flags = typeadjust (Expr, &Expr2, 0); /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); } else { @@ -3134,8 +3127,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* We can't just goto End as that would leave the stack unbalanced */ } - /* Generate code for the add */ - g_add (flags, 0); + /* Generate code for the add (the & is a hack here) */ + g_add (flags & ~CF_CONST, 0); } @@ -3348,8 +3341,7 @@ static void parsesub (ExprDesc* Expr) /* Operate on pointers, result type is a pointer */ flags = CF_PTR; } else if (IsClassInt (lhst) && IsClassInt (rhst)) { - /* Integer subtraction */ - flags = typeadjust (Expr, &Expr2, 1); + /* Integer subtraction. We'll adjust the types later */ } else { /* OOPS */ Error ("Invalid operands for binary operator '-'"); @@ -3370,10 +3362,12 @@ static void parsesub (ExprDesc* Expr) } if (SubDone) { - /* Remove pushed value from stack */ + /* Remove loaded and pushed value from stack */ RemoveCode (&Mark1); if (IsClassInt (lhst)) { - /* Limit the calculated value to the range of its type */ + /* Just adjust the result type */ + Expr->Type = ArithmeticConvert (Expr->Type, Expr2.Type); + /* And limit the calculated value to the range of it */ LimitExprValue (Expr); } /* The result is always an rvalue */ @@ -3382,10 +3376,18 @@ static void parsesub (ExprDesc* Expr) if (ED_IsConstAbs (&Expr2)) { /* Remove pushed value from stack */ RemoveCode (&Mark2); + if (IsClassInt (lhst)) { + /* Adjust the types */ + flags = typeadjust (Expr, &Expr2, 1); + } /* Do the subtraction */ g_dec (flags | CF_CONST, Expr2.IVal); } else { - /* Load into the primary */ + if (IsClassInt (lhst)) { + /* Adjust the types */ + flags = typeadjust (Expr, &Expr2, 0); + } + /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); @@ -3403,8 +3405,7 @@ static void parsesub (ExprDesc* Expr) /* Operate on pointers, result type is a pointer */ flags = CF_PTR; } else if (IsClassInt (lhst) && IsClassInt (rhst)) { - /* Integer subtraction */ - flags = typeadjust (Expr, &Expr2, 1); + /* Integer subtraction. We'll adjust the types later */ } else { /* OOPS */ Error ("Invalid operands for binary operator '-'"); @@ -3414,10 +3415,18 @@ static void parsesub (ExprDesc* Expr) if (ED_IsConstAbs (&Expr2)) { /* Remove pushed value from stack */ RemoveCode (&Mark2); + if (IsClassInt (lhst)) { + /* Adjust the types */ + flags = typeadjust (Expr, &Expr2, 1); + } /* Do the subtraction */ g_dec (flags | CF_CONST, Expr2.IVal); } else { - /* Rhs is not numeric, load into the primary */ + if (IsClassInt (lhst)) { + /* Adjust the types */ + flags = typeadjust (Expr, &Expr2, 0); + } + /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); @@ -3429,6 +3438,9 @@ static void parsesub (ExprDesc* Expr) } else { + /* We'll use the pushed lhs on stack instead of the original source */ + ED_FinalizeRValLoad (Expr); + /* Right hand side is not constant, load into the primary */ LoadExpr (CF_NONE, &Expr2); From 9ec9d1e20c5c730869371766aae6be96e4404db4 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 19 Mar 2021 20:53:52 +0100 Subject: [PATCH 1939/2161] test for issue #1431 / pr #1424 --- test/val/bug1431.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 test/val/bug1431.c diff --git a/test/val/bug1431.c b/test/val/bug1431.c new file mode 100644 index 000000000..9eae3bdbd --- /dev/null +++ b/test/val/bug1431.c @@ -0,0 +1,33 @@ +/* +$ cl65 -Osir --codesize 180 -S -o main.s main.c +main.c(9): Internal compiler error: +Code generation messed up: StackPtr is -2, should be -4 + +Input: if (wcnt > btw) { + +$ git bisect bad +aa6fdf58b8a17b747090fb521f3d9106e0c56d1c is the first bad commit +commit aa6fdf58b8a17b747090fb521f3d9106e0c56d1c +Author: acqn <acqn163@outlook.com> +Date: Mon Feb 8 09:03:19 2021 +0800 + + Addresses in constant subtraction expressions now work. + Fixed codegen for cast type subtraction in constant expressions. +*/ + +unsigned long fptr = 0x40001; + +int main(void) +{ + unsigned int btw = 500; + unsigned int wcnt; + + wcnt = 512U - (fptr % 512U); + + if (wcnt > btw) { + wcnt = btw; + } + + return wcnt == 500 ? 0 : 1; +} + From 7d528d9eb0e3e667e198850ce46ca98c7adf0ca7 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 19 Mar 2021 22:26:49 +0100 Subject: [PATCH 1940/2161] fix typo --- include/cbm_screen_charmap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cbm_screen_charmap.h b/include/cbm_screen_charmap.h index 76e0d7d7b..5bf4c3f90 100644 --- a/include/cbm_screen_charmap.h +++ b/include/cbm_screen_charmap.h @@ -8,7 +8,7 @@ /* from ASCII to screen-code mapping, so you can write directly */ /* to the screen memory. */ /* */ -/* If this include is used, no additional macroes are needed. */ +/* If this include is used, no additional macros are needed. */ /* */ /*****************************************************************************/ From 57e69d964710593ccdee028104e9a5aa0b04760f Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 19 Mar 2021 23:35:34 +0100 Subject: [PATCH 1941/2161] test related to pr #1425 --- test/val/pr1425.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 test/val/pr1425.c diff --git a/test/val/pr1425.c b/test/val/pr1425.c new file mode 100644 index 000000000..e3ae23ba3 --- /dev/null +++ b/test/val/pr1425.c @@ -0,0 +1,45 @@ + +/* pr #1425 - Ternary fixes */ + +unsigned char fails = 0; + +void test1(void) +{ + int x = 0; + x ? (void)x-- : (void)1; + if (x != 0) { + fails++; + } +} + +int test2(void) +{ + int x = 0, y = 0; + x ? (void)x--, (void)y++ : (void)1; + if (x != 0) { + fails++; + } + if (y != 0) { + fails++; + } +} + +void test3(void) +{ + int x = 0, y = 0; + x ? ((void)x--, (void)y++) : (void)1; + if (x != 0) { + fails++; + } + if (y != 0) { + fails++; + } +} + +int main(void) +{ + test1(); + test2(); + test3(); + return fails; +} From cc040ca04a861030de751c70a52dc2fcd2c06727 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 19 Mar 2021 23:39:56 +0100 Subject: [PATCH 1942/2161] remove, fucking git --- test/val/pr1425.c | 45 --------------------------------------------- 1 file changed, 45 deletions(-) delete mode 100644 test/val/pr1425.c diff --git a/test/val/pr1425.c b/test/val/pr1425.c deleted file mode 100644 index e3ae23ba3..000000000 --- a/test/val/pr1425.c +++ /dev/null @@ -1,45 +0,0 @@ - -/* pr #1425 - Ternary fixes */ - -unsigned char fails = 0; - -void test1(void) -{ - int x = 0; - x ? (void)x-- : (void)1; - if (x != 0) { - fails++; - } -} - -int test2(void) -{ - int x = 0, y = 0; - x ? (void)x--, (void)y++ : (void)1; - if (x != 0) { - fails++; - } - if (y != 0) { - fails++; - } -} - -void test3(void) -{ - int x = 0, y = 0; - x ? ((void)x--, (void)y++) : (void)1; - if (x != 0) { - fails++; - } - if (y != 0) { - fails++; - } -} - -int main(void) -{ - test1(); - test2(); - test3(); - return fails; -} From a51d6d40de4a6a60d27c472358cd4e1ece5f5986 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 14 Mar 2021 02:39:40 +0800 Subject: [PATCH 1943/2161] Ternary fix for some obscure cases. --- src/cc65/expr.c | 66 +++++++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 4f579b7ae..422159c4b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3987,24 +3987,24 @@ static void hieQuest (ExprDesc* Expr) */ ExprWithCheck (hie1, &Expr2); Expr2IsNULL = ED_IsNullPtr (&Expr2); - if (!IsTypeVoid (Expr2.Type)) { - if (!ConstantCond || !ED_IsConst (&Expr2)) { - /* Load it into the primary */ - LoadExpr (CF_NONE, &Expr2); + if (!IsTypeVoid (Expr2.Type) && + ED_YetToLoad (&Expr2) && + (!ConstantCond || !ED_IsConst (&Expr2))) { + /* Load it into the primary */ + LoadExpr (CF_NONE, &Expr2); - /* Append deferred inc/dec at sequence point */ - DoDeferred (SQP_KEEP_EXPR, &Expr2); + /* Append deferred inc/dec at sequence point */ + DoDeferred (SQP_KEEP_EXPR, &Expr2); - ED_FinalizeRValLoad (&Expr2); - } else { - /* Constant boolean subexpression could still have deferred inc/ - ** dec operations, so just flush their side-effects at this - ** sequence point. - */ - DoDeferred (SQP_KEEP_NONE, &Expr2); - } - Expr2.Type = PtrConversion (Expr2.Type); + ED_FinalizeRValLoad (&Expr2); + } else { + /* Constant boolean subexpression could still have deferred inc/ + ** dec operations, so just flush their side-effects at this + ** sequence point. + */ + DoDeferred (SQP_KEEP_NONE, &Expr2); } + Expr2.Type = PtrConversion (Expr2.Type); if (!ConstantCond) { /* Remember the current code position */ @@ -4021,6 +4021,9 @@ static void hieQuest (ExprDesc* Expr) g_defcodelabel (FalseLab); } else { if (Expr->IVal == 0) { + /* Expr2 is unevaluated when the condition is false */ + Expr2.Flags |= E_EVAL_UNEVAL; + /* Remove the load code of Expr2 */ RemoveCode (&SkippedBranch); } else { @@ -4035,26 +4038,29 @@ static void hieQuest (ExprDesc* Expr) */ ExprWithCheck (hie1, &Expr3); Expr3IsNULL = ED_IsNullPtr (&Expr3); - if (!IsTypeVoid (Expr3.Type)) { - if (!ConstantCond || !ED_IsConst (&Expr3)) { - /* Load it into the primary */ - LoadExpr (CF_NONE, &Expr3); + if (!IsTypeVoid (Expr3.Type) && + ED_YetToLoad (&Expr3) && + (!ConstantCond || !ED_IsConst (&Expr3))) { + /* Load it into the primary */ + LoadExpr (CF_NONE, &Expr3); - /* Append deferred inc/dec at sequence point */ - DoDeferred (SQP_KEEP_EXPR, &Expr3); + /* Append deferred inc/dec at sequence point */ + DoDeferred (SQP_KEEP_EXPR, &Expr3); - ED_FinalizeRValLoad (&Expr3); - } else { - /* Constant boolean subexpression could still have deferred inc/ - ** dec operations, so just flush their side-effects at this - ** sequence point. - */ - DoDeferred (SQP_KEEP_NONE, &Expr3); - } - Expr3.Type = PtrConversion (Expr3.Type); + ED_FinalizeRValLoad (&Expr3); + } else { + /* Constant boolean subexpression could still have deferred inc/ + ** dec operations, so just flush their side-effects at this + ** sequence point. + */ + DoDeferred (SQP_KEEP_NONE, &Expr3); } + Expr3.Type = PtrConversion (Expr3.Type); if (ConstantCond && Expr->IVal != 0) { + /* Expr3 is unevaluated when the condition is true */ + Expr3.Flags |= E_EVAL_UNEVAL; + /* Remove the load code of Expr3 */ RemoveCode (&SkippedBranch); } From 325b7b4ab3cecfafd67efadf1d5ffdc784e4635b Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 14 Mar 2021 03:25:40 +0800 Subject: [PATCH 1944/2161] Enabled 'a ? b, c : d'. --- 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 422159c4b..44b0d17e8 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3985,7 +3985,7 @@ static void hieQuest (ExprDesc* Expr) /* Parse second expression. Remember for later if it is a NULL pointer ** expression, then load it into the primary. */ - ExprWithCheck (hie1, &Expr2); + ExprWithCheck (hie0, &Expr2); Expr2IsNULL = ED_IsNullPtr (&Expr2); if (!IsTypeVoid (Expr2.Type) && ED_YetToLoad (&Expr2) && From bbfc24770eaa1893da7bf8ae10f7bd9cfa44db65 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 19 Mar 2021 23:42:25 +0100 Subject: [PATCH 1945/2161] test related to pr #1425 --- test/val/pr1425.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 test/val/pr1425.c diff --git a/test/val/pr1425.c b/test/val/pr1425.c new file mode 100644 index 000000000..e3ae23ba3 --- /dev/null +++ b/test/val/pr1425.c @@ -0,0 +1,45 @@ + +/* pr #1425 - Ternary fixes */ + +unsigned char fails = 0; + +void test1(void) +{ + int x = 0; + x ? (void)x-- : (void)1; + if (x != 0) { + fails++; + } +} + +int test2(void) +{ + int x = 0, y = 0; + x ? (void)x--, (void)y++ : (void)1; + if (x != 0) { + fails++; + } + if (y != 0) { + fails++; + } +} + +void test3(void) +{ + int x = 0, y = 0; + x ? ((void)x--, (void)y++) : (void)1; + if (x != 0) { + fails++; + } + if (y != 0) { + fails++; + } +} + +int main(void) +{ + test1(); + test2(); + test3(); + return fails; +} From 82fb9aa41847d08556cfe12cc51a54a3ca2e2536 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 20 Mar 2021 00:55:55 +0100 Subject: [PATCH 1946/2161] testcase related to pr #1423 --- test/val/pr1423.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 test/val/pr1423.c diff --git a/test/val/pr1423.c b/test/val/pr1423.c new file mode 100644 index 000000000..3135b64a3 --- /dev/null +++ b/test/val/pr1423.c @@ -0,0 +1,41 @@ +/* pr #1423 - Codegen fix for certain cases of object addresses as boolean */ + +unsigned char fails = 0; + +void test1(void) +{ + int a; + while (&a) { + return; + } + fails++; + return; +} + +void test2(void) +{ + int a; + do { + return; + } while (&a); + fails++; + return; +} + +void test3(void) +{ + int a; + for (;&a;) { + return; + } + fails++; + return; +} + +int main(void) +{ + test1(); + test2(); + test3(); + return fails; +} From f8835d2867d428484fd7a300fbbc1213a8af1c70 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 13 Mar 2021 14:25:51 +0800 Subject: [PATCH 1947/2161] Fixed codegen with addresses as boolean test conditions. Fixed warning on unreachable code of if body. --- src/cc65/testexpr.c | 9 +++++++-- src/cc65/testexpr.h | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index e5db488de..243f3ebf9 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -70,7 +70,7 @@ unsigned Test (unsigned Label, int Invert) DoDeferred (SQP_KEEP_NONE, &Expr); /* Result is constant, so we know the outcome */ - Result = (Expr.IVal != 0); + Result = (Expr.IVal != 0) ? TESTEXPR_TRUE : TESTEXPR_FALSE; /* Constant rvalue */ if (!Invert && Expr.IVal == 0) { @@ -86,7 +86,12 @@ unsigned Test (unsigned Label, int Invert) DoDeferred (SQP_KEEP_NONE, &Expr); /* Object addresses are non-NULL */ - Result = 1; + Result = TESTEXPR_TRUE; + + /* Condition is always true */ + if (Invert) { + g_jump (Label); + } } else { diff --git a/src/cc65/testexpr.h b/src/cc65/testexpr.h index 478280a28..84b957af2 100644 --- a/src/cc65/testexpr.h +++ b/src/cc65/testexpr.h @@ -44,9 +44,9 @@ -#define TESTEXPR_UNKNOWN 0 /* Result of expression unknown */ +#define TESTEXPR_UNKNOWN -1 /* Result of expression unknown */ #define TESTEXPR_TRUE 1 /* Expression yields true */ -#define TESTEXPR_FALSE 2 /* Expression yields false */ +#define TESTEXPR_FALSE 0 /* Expression yields false */ From 3c2e7ce41cb54f3a751bbf07a1b84fd51fa89104 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 13 Mar 2021 14:27:11 +0800 Subject: [PATCH 1948/2161] More reliable test for true/false with addresses for AND, OR and ternary operators. Minor comment typo fix. --- src/cc65/expr.c | 17 +++++++++++------ src/cc65/exprdesc.c | 26 +++++++++++++++++++++++++- src/cc65/exprdesc.h | 12 +++++++++++- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 44b0d17e8..048819d50 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3658,7 +3658,7 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) */ DoDeferred (SQP_KEEP_NONE, Expr); - if (Expr->IVal == 0 && !ED_IsAddrExpr (Expr)) { + if (ED_IsConstFalse (Expr)) { /* Skip remaining */ Flags |= E_EVAL_UNEVAL; } @@ -3713,7 +3713,7 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) */ DoDeferred (SQP_KEEP_NONE, &Expr2); - if (Expr2.IVal == 0 && !ED_IsAddrExpr (&Expr2)) { + if (ED_IsConstFalse (&Expr2)) { /* Skip remaining */ Flags |= E_EVAL_UNEVAL; /* The value of the expression will be false */ @@ -3826,7 +3826,7 @@ static void hieOr (ExprDesc *Expr) */ DoDeferred (SQP_KEEP_NONE, Expr); - if (Expr->IVal != 0 || ED_IsAddrExpr (Expr)) { + if (ED_IsConstTrue (Expr)) { /* Skip remaining */ Flags |= E_EVAL_UNEVAL; } @@ -3878,7 +3878,7 @@ static void hieOr (ExprDesc *Expr) */ DoDeferred (SQP_KEEP_NONE, &Expr2); - if (Expr2.IVal != 0 || ED_IsAddrExpr (&Expr2)) { + if (ED_IsConstTrue (&Expr2)) { /* Skip remaining */ Flags |= E_EVAL_UNEVAL; /* The result is always true */ @@ -3945,6 +3945,7 @@ static void hieQuest (ExprDesc* Expr) /* Check if it's a ternary expression */ if (CurTok.Tok == TOK_QUEST) { + /* The constant condition must be compile-time known as well */ int ConstantCond = ED_IsConstBool (Expr); unsigned Flags = Expr->Flags & E_MASK_KEEP_RESULT; @@ -3955,9 +3956,13 @@ static void hieQuest (ExprDesc* Expr) NextToken (); - /* Convert non-integer constant boolean */ - if (ED_IsAddrExpr (Expr)) { + /* Convert non-integer constant to boolean constant, so that we may just + ** check it in the same way. + */ + if (ED_IsConstTrue (Expr)) { ED_MakeConstBool (Expr, 1); + } else if (ED_IsConstFalse (Expr)) { + ED_MakeConstBool (Expr, 0); } if (!ConstantCond) { diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index aa98e1531..d1113d9a5 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -397,6 +397,30 @@ int ED_IsConstBool (const ExprDesc* Expr) +int ED_IsConstTrue (const ExprDesc* Expr) +/* Return true if the constant expression can be evaluated as boolean true at +** compile time. +*/ +{ + /* Non-zero arithmetics and objects addresses are boolean true */ + return (ED_IsConstAbsInt (Expr) && Expr->IVal != 0) || + (ED_IsAddrExpr (Expr)); +} + + + +int ED_IsConstFalse (const ExprDesc* Expr) +/* Return true if the constant expression can be evaluated as boolean false at +** compile time. +*/ +{ + /* Zero arithmetics and null pointers are boolean false */ + return (ED_IsConstAbsInt (Expr) && Expr->IVal == 0) || + ED_IsNullPtr (Expr); +} + + + int ED_IsConst (const ExprDesc* Expr) /* Return true if the expression denotes a constant of some sort. This can be a ** numeric constant, the address of a global variable (maybe with offset) or @@ -449,7 +473,7 @@ int ED_IsNullPtr (const ExprDesc* Expr) int ED_IsBool (const ExprDesc* Expr) -/* Return true of the expression can be treated as a boolean, that is, it can +/* Return true if the expression can be treated as a boolean, that is, it can ** be an operand to a compare operation. */ { diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index 844af1566..a4f5eb848 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -643,6 +643,16 @@ int ED_IsConstAbsInt (const ExprDesc* Expr); int ED_IsConstBool (const ExprDesc* Expr); /* Return true if the expression can be constantly evaluated as a boolean. */ +int ED_IsConstTrue (const ExprDesc* Expr); +/* Return true if the constant expression can be evaluated as boolean true at +** compile time. +*/ + +int ED_IsConstFalse (const ExprDesc* Expr); +/* Return true if the constant expression can be evaluated as boolean false at +** compile time. +*/ + int ED_IsConst (const ExprDesc* Expr); /* Return true if the expression denotes a constant of some sort. This can be a ** numeric constant, the address of a global variable (maybe with offset) or @@ -668,7 +678,7 @@ int ED_IsNullPtr (const ExprDesc* Expr); /* Return true if the given expression is a NULL pointer constant */ int ED_IsBool (const ExprDesc* Expr); -/* Return true of the expression can be treated as a boolean, that is, it can +/* Return true if the expression can be treated as a boolean, that is, it can ** be an operand to a compare operation with 0/NULL. */ From 531a31722e2e6183e060ca4dc7d3c2c56bc9106d Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Mon, 22 Mar 2021 14:06:40 +0100 Subject: [PATCH 1949/2161] fix typo --- doc/atari.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/atari.sgml b/doc/atari.sgml index 7fc929f42..f2ced13e1 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -1170,7 +1170,7 @@ When using cl65, you can leave it out with this command line: cl65 -Wl -D__SYSTEM_CHECK__=1 <arguments> </verb></tscreen> -The value you assign to <tt/__SYSTEM_CHECK_/ doesn't matter. If the +The value you assign to <tt/__SYSTEM_CHECK__/ doesn't matter. If the <tt/__SYSTEM_CHECK__/ symbol is defined, the load chunk won't be included. From 55e89416cdd18bae1e687c97fc9b106105866a5e Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 22 Mar 2021 19:12:44 +0100 Subject: [PATCH 1950/2161] test related to issue #1196 and pr #1424 respectively --- test/val/constexpr.c | 112 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 test/val/constexpr.c diff --git a/test/val/constexpr.c b/test/val/constexpr.c new file mode 100644 index 000000000..c92302a58 --- /dev/null +++ b/test/val/constexpr.c @@ -0,0 +1,112 @@ + +/* + +This tests a couple of expressions which yield constant results. While we cant +really check if the compiler figures out they are constant, we can still check +if they are being compiled/evaluated correctly. + +related: + +pr #1424 - More compile-time constant expressions regarding object addresses +issue #1196 - Constant expressions in general + +*/ + +#include <stdio.h> + +int fails = 0; + +#define TESTEXPR(expr) \ + if (!(expr)) { \ + printf("fail line %d\n", __LINE__); \ + fails++; \ + } + +#define TESTEXPRFALSE(expr) \ + if (expr) { \ + printf("fail line %d\n", __LINE__); \ + fails++; \ + } + +int a; +volatile int b; +const int c = 1; +#define d 1 +enum { e = 1 }; +int f() { return 1; } + +/* we cant really test these at runtime (because the result is constant, but not + * compile-time known), so compile only */ +void test0(void) +{ + TESTEXPR(a); /* Pure: Yes; Static: No; Immutable: No; Compile-Time-Known: No */ + TESTEXPR(b); /* Pure: No?; Static: No; Immutable: No; Compile-Time-Known: No */ + TESTEXPR(&a > &b); /* Pure: Yes; Static: Yes; Immutable: Yes; Compile-Time-Known: No */ +} + +void test1(void) +{ + TESTEXPR(1); /* Pure: Yes; Static: Yes; Immutable: Yes; Compile-Time-Known: Yes */ + TESTEXPR(c); /* Pure: Yes; Static: ???; Immutable: ???; Compile-Time-Known: ??? */ + TESTEXPR(d); /* Pure: Yes; Static: Yes; Immutable: Yes; Compile-Time-Known: Yes */ + TESTEXPR(e); /* Pure: Yes; Static: Yes; Immutable: Yes; Compile-Time-Known: Yes */ + TESTEXPR(c == c); /* Pure: Yes; Static: Yes; Immutable: Yes; Compile-Time-Known: Yes */ + TESTEXPRFALSE(c != c); + TESTEXPR(f() == f()); /* Pure: Yes; Static: Yes?; Immutable: Yes; Compile-Time-Known: Yes? */ + TESTEXPRFALSE(f() != f()); + TESTEXPR(&a == &a); /* Pure: Yes; Static: Yes; Immutable: Yes; Compile-Time-Known: Yes */ + TESTEXPRFALSE(&a != &a); + TESTEXPR(&a != 0); /* Pure: Yes; Static: Yes; Immutable: Yes; Compile-Time-Known: Yes* */ + TESTEXPRFALSE(&a == 0); +/* in a real program we cant rely on these, but in this test we can */ + TESTEXPR(&a); /* Pure: Yes; Static: Yes; Immutable: Yes; Compile-Time-Known: No */ + TESTEXPR((int)&a != 0); /* Pure: Yes; Static: Yes; Immutable: Yes; Compile-Time-Known: No */ + TESTEXPRFALSE((int)&a == 0); + TESTEXPR(&a != &b); /* Pure: Yes; Static: Yes; Immutable: Yes; Compile-Time-Known: ??** */ + TESTEXPRFALSE(&a == &b); +/* this may fail in a real world program, but here we can rely on it anyway */ + TESTEXPR(b == b); /* Pure: No?; Static: No; Immutable: No; Compile-Time-Known: No */ + TESTEXPRFALSE(b != b); +/* NOT detected by the compiler as constant */ + TESTEXPR(a == a); /* Pure: Yes; Static: Yes; Immutable: Yes; Compile-Time-Known: Yes */ + TESTEXPRFALSE(a != a); + TESTEXPR(f()); /* Pure: Yes; Static: Yes?; Immutable: Yes; Compile-Time-Known: Yes? */ +} + +/* Taken from #1196 reply */ +struct S { + int a; + int b; +} s[2]; + +void test2(void) +{ + TESTEXPR((void*)&s == (void*)&s[0]); + TESTEXPRFALSE((void*)&s != (void*)&s[0]); + TESTEXPR(&s[0] < &s[1]); + TESTEXPR(&s[0].b > &s[0].a); + TESTEXPR(&s[0].b < &s[1].a); +} + +/* FIXME: how to deal with the extern stuff in the testbench? */ +extern int g(); + +void test3(void) +{ +#if 0 + TESTEXPR(g()); /* Pure: No; Static: No; Immutable: No; Compile-Time-Known: No */ + TESTEXPR(g(), 1); /* Pure: No; Static: No; Immutable: Yes; Compile-Time-Known: Yes */ + TESTEXPR((void)g()); /* Pure: No; Static: No; Immutable: Yes; Compile-Time-Known: Yes */ + TESTEXPR(sizeof(g())); /* Pure: Yes; Static: Yes; Immutable: Yes; Compile-Time-Known: Yes */ + /* NOT detected by the compiler as constant */ + TESTEXPR(g() * 0); /* Pure: No; Static: No; Immutable: Yes; Compile-Time-Known: Yes */ +#endif +} + +int main(void) +{ + test1(); + test2(); + test3(); + return fails; +} From d3cd668585ab920fd9a6067a4cfce0e336eefbeb Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 22 Mar 2021 23:37:33 +0100 Subject: [PATCH 1951/2161] also test (some of) the cases with an external function --- test/val/constexpr.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/test/val/constexpr.c b/test/val/constexpr.c index c92302a58..4338717f4 100644 --- a/test/val/constexpr.c +++ b/test/val/constexpr.c @@ -88,19 +88,18 @@ void test2(void) TESTEXPR(&s[0].b < &s[1].a); } -/* FIXME: how to deal with the extern stuff in the testbench? */ -extern int g(); +/* we abuse the close function here, close(-1) will return -1 */ +extern int close(int fd); void test3(void) { -#if 0 - TESTEXPR(g()); /* Pure: No; Static: No; Immutable: No; Compile-Time-Known: No */ - TESTEXPR(g(), 1); /* Pure: No; Static: No; Immutable: Yes; Compile-Time-Known: Yes */ - TESTEXPR((void)g()); /* Pure: No; Static: No; Immutable: Yes; Compile-Time-Known: Yes */ - TESTEXPR(sizeof(g())); /* Pure: Yes; Static: Yes; Immutable: Yes; Compile-Time-Known: Yes */ + TESTEXPR(close(-1)); /* Pure: No; Static: No; Immutable: No; Compile-Time-Known: No */ + TESTEXPR((close(-1), 1)) /* Pure: No; Static: No; Immutable: Yes; Compile-Time-Known: Yes */ +/* Error: Scalar expression expected */ +// TESTEXPR((void)close(-1)); /* Pure: No; Static: No; Immutable: Yes; Compile-Time-Known: Yes */ + TESTEXPR(sizeof(close(-1))); /* Pure: Yes; Static: Yes; Immutable: Yes; Compile-Time-Known: Yes */ /* NOT detected by the compiler as constant */ - TESTEXPR(g() * 0); /* Pure: No; Static: No; Immutable: Yes; Compile-Time-Known: Yes */ -#endif + TESTEXPRFALSE(close(-1) * 0); /* Pure: No; Static: No; Immutable: Yes; Compile-Time-Known: Yes */ } int main(void) From 3755e4a863da973a7de60fa1abd6dde5d4379aef Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 24 Mar 2021 14:35:44 +0800 Subject: [PATCH 1952/2161] Replaced checking for __fastcall__ aginst AutoCDecl etc. with IsFastcallFunc(). --- src/cc65/codeinfo.c | 9 +++------ src/cc65/datatype.c | 21 ++++++++++++++++++--- src/cc65/datatype.h | 9 ++++++++- src/cc65/expr.c | 14 ++++---------- src/cc65/function.c | 5 +---- 5 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 90d4f4d68..d81f46001 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -493,17 +493,14 @@ fncls_t GetFuncInfo (const char* Name, unsigned int* Use, unsigned int* Chg) ** registers. */ *Use = REG_EAXY; - } else if ((D->ParamCount > 0 || - (D->Flags & FD_EMPTY) != 0) && - (AutoCDecl ? - IsQualFastcall (E->Type) : - !IsQualCDecl (E->Type))) { + } else if ((D->ParamCount > 0 || (D->Flags & FD_EMPTY) != 0) && + IsFastcallFunc (E->Type)) { /* Will use registers depending on the last param. If the last ** param has incomplete type, or if the function has not been ** prototyped yet, just assume __EAX__. */ if (D->LastParam != 0) { - switch (SizeOf(D->LastParam->Type)) { + switch (SizeOf (D->LastParam->Type)) { case 1u: *Use = REG_A; break; diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 6e42057dc..d29a0d807 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -1085,11 +1085,26 @@ int HasUnknownSize (const Type* T) int IsVariadicFunc (const Type* T) /* Return true if this is a function type or pointer to function type with -** variable parameter list +** variable parameter list. +** Check fails if the type is not a function or a pointer to function. */ { - FuncDesc* F = GetFuncDesc (T); - return (F->Flags & FD_VARIADIC) != 0; + return (GetFuncDesc (T)->Flags & FD_VARIADIC) != 0; +} + + + +int IsFastcallFunc (const Type* T) +/* Return true if this is a function type or pointer to function type by +** __fastcall__ calling convention. +** Check fails if the type is not a function or a pointer to function. +*/ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + return !IsVariadicFunc (T) && (AutoCDecl ? IsQualFastcall (T) : !IsQualCDecl (T)); } diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 5c3e71da5..ac6edeeb5 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -825,7 +825,14 @@ INLINE int IsQualCConv (const Type* T) int IsVariadicFunc (const Type* T) attribute ((const)); /* Return true if this is a function type or pointer to function type with -** variable parameter list +** variable parameter list. +** Check fails if the type is not a function or a pointer to function. +*/ + +int IsFastcallFunc (const Type* T) attribute ((const)); +/* Return true if this is a function type or pointer to function type by +** __fastcall__ calling convention. +** Check fails if the type is not a function or a pointer to function. */ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 048819d50..9b95efda6 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -863,7 +863,7 @@ static void FunctionCall (ExprDesc* Expr) unsigned ParamSize; /* Number of parameter bytes */ CodeMark Mark; int PtrOffs = 0; /* Offset of function pointer on stack */ - int IsFastcall = 0; /* True if it's a fast-call function */ + int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ Type* ReturnType; @@ -882,11 +882,8 @@ static void FunctionCall (ExprDesc* Expr) ** parameter count is zero. Handle K & R functions as though there are ** parameters. */ - IsFastcall = (Func->Flags & FD_VARIADIC) == 0 && - (Func->ParamCount > 0 || (Func->Flags & FD_EMPTY)) && - (AutoCDecl ? - IsQualFastcall (Expr->Type + 1) : - !IsQualCDecl (Expr->Type + 1)); + IsFastcall = (Func->ParamCount > 0 || (Func->Flags & FD_EMPTY) != 0) && + IsFastcallFunc (Expr->Type + 1); /* Things may be difficult, depending on where the function pointer ** resides. If the function pointer is an expression of some sort @@ -931,10 +928,7 @@ static void FunctionCall (ExprDesc* Expr) } /* If we didn't inline the function, get fastcall info */ - IsFastcall = (Func->Flags & FD_VARIADIC) == 0 && - (AutoCDecl ? - IsQualFastcall (Expr->Type) : - !IsQualCDecl (Expr->Type)); + IsFastcall = IsFastcallFunc (Expr->Type); } /* Parse the parameter list */ diff --git a/src/cc65/function.c b/src/cc65/function.c index 9269d4c62..cad1df629 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -558,10 +558,7 @@ void NewFunc (SymEntry* Func, FuncDesc* D) PushLiteralPool (Func); /* If this is a fastcall function, push the last parameter onto the stack */ - if ((D->Flags & FD_VARIADIC) == 0 && D->ParamCount > 0 && - (AutoCDecl ? - IsQualFastcall (Func->Type) : - !IsQualCDecl (Func->Type))) { + if (D->ParamCount > 0 && IsFastcallFunc (Func->Type)) { unsigned Flags; /* Generate the push */ From 0f1386ff4c0d88a533050138de2f3a4f2796863f Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 25 Mar 2021 08:28:15 -0400 Subject: [PATCH 1953/2161] Added documentation about the slightly different behavior of cpeekcolor() on the cx16 platform. --- doc/cx16.sgml | 69 ++++++++++++++++++++++++++---------------------- doc/funcref.sgml | 2 ++ 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/doc/cx16.sgml b/doc/cx16.sgml index 490d07849..9e743064f 100644 --- a/doc/cx16.sgml +++ b/doc/cx16.sgml @@ -142,13 +142,20 @@ The functions listed below are special for the CX16. See the <url url="funcref.html" name="function reference"> for declarations and usage. <itemize> -<item>get_ostype -<item>set_tv -<item>videomode -<item>vpeek -<item>vpoke +<item>get_ostype() +<item>set_tv() +<item>videomode() +<item>vpeek() +<item>vpoke() </itemize> +<tt/cpeekcolor()/ works differently on the Commander X16 than it does on other +platforms. Each character has two colors: background and text (foreground). +<tt/cpeekcolor()/ returns both colors. The high nybble describes the +background color, the low nybble describes the text color. For example, if the +function is used on the default screen, then it returns $61, which means +white-on-blue. + <sect1>CBM-specific functions<p> @@ -157,32 +164,32 @@ machines. See the <url url="funcref.html" name="function reference"> for declarations and usage. <itemize> -<item>cbm_close -<item>cbm_closedir -<item>cbm_k_basin -<item>cbm_k_bsout -<item>cbm_k_chkin -<item>cbm_k_ckout -<item>cbm_k_close -<item>cbm_k_clrch -<item>cbm_k_getin -<item>cbm_k_load -<item>cbm_k_open -<item>cbm_k_readst -<item>cbm_k_save -<item>cbm_k_second -<item>cbm_k_setlfs -<item>cbm_k_setnam -<item>cbm_k_tksa -<item>cbm_load -<item>cbm_open -<item>cbm_opendir -<item>cbm_read -<item>cbm_readdir -<item>cbm_save -<item>cbm_write -<item>get_tv -<item>waitvsync +<item>cbm_close() +<item>cbm_closedir() +<item>cbm_k_basin() +<item>cbm_k_bsout() +<item>cbm_k_chkin() +<item>cbm_k_ckout() +<item>cbm_k_close() +<item>cbm_k_clrch() +<item>cbm_k_getin() +<item>cbm_k_load() +<item>cbm_k_open() +<item>cbm_k_readst() +<item>cbm_k_save() +<item>cbm_k_second() +<item>cbm_k_setlfs() +<item>cbm_k_setnam() +<item>cbm_k_tksa() +<item>cbm_load() +<item>cbm_open() +<item>cbm_opendir() +<item>cbm_read() +<item>cbm_readdir() +<item>cbm_save() +<item>cbm_write() +<item>get_tv() +<item>waitvsync() </itemize> diff --git a/doc/funcref.sgml b/doc/funcref.sgml index a954c6581..3b3db2e09 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -2813,6 +2813,8 @@ location of the cursor in the display screen RAM. That number can be passed to done to make it obvious that peeking doesn't move the cursor in any way. Your program must place the cursor where it wants to peek before it calls any of those functions. +<item>On the cx16 (Commander X16) target, this function returns two values: the +background color, in the high nybble, and the text color, in the low nybble. </itemize> <tag/Availability/cc65 <tag/See also/ From 710c6c6f2f08f7d938f552a0272d2424cf9fdc68 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 13 Jan 2021 03:20:19 -0500 Subject: [PATCH 1954/2161] Fixed cbm_k_readst() to work around a VIC-20 Kernal bug. It properly returns the RS-232 device's status. --- asminc/vic20.inc | 9 +++++---- libsrc/cbm/c_readst.s | 8 ++++---- libsrc/vic20/c_readst.s | 28 ++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 8 deletions(-) create mode 100644 libsrc/vic20/c_readst.s diff --git a/asminc/vic20.inc b/asminc/vic20.inc index fa9fdfa8d..91da083f1 100644 --- a/asminc/vic20.inc +++ b/asminc/vic20.inc @@ -1,8 +1,7 @@ ; -; Vic20 generic definitions. Stolen mostly from c64.inc - Steve Schmidtke +; VIC-20 generic definitions. Stolen mostly from c64.inc -- Steve Schmidtke ; - ; --------------------------------------------------------------------------- ; Zero page, Commodore stuff @@ -12,8 +11,8 @@ TXTPTR := $7A ; 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 +SECADR := $B9 ; Second address +DEVNUM := $BA ; Device number (first address) FNAM := $BB ; Pointer to filename KEY_COUNT := $C6 ; Number of keys in input buffer RVS := $C7 ; Reverse flag @@ -36,6 +35,8 @@ KBDREPEAT := $28a KBDREPEATRATE := $28b KBDREPEATDELAY := $28c +RSSTAT := $297 ; RS-232 device driver status + ; --------------------------------------------------------------------------- ; Screen size diff --git a/libsrc/cbm/c_readst.s b/libsrc/cbm/c_readst.s index 85211dd2f..bcaacbbae 100644 --- a/libsrc/cbm/c_readst.s +++ b/libsrc/cbm/c_readst.s @@ -1,5 +1,6 @@ ; -; Ullrich von Bassewitz, 03.06.1999 +; 1999-06-03, Ullrich von Bassewitz +; 2021-01-12, Greg King ; ; unsigned char cbm_k_readst (void); ; @@ -10,6 +11,5 @@ _cbm_k_readst: - jsr READST - ldx #0 ; Clear high byte - rts + ldx #>$0000 + jmp READST diff --git a/libsrc/vic20/c_readst.s b/libsrc/vic20/c_readst.s new file mode 100644 index 000000000..2cb11bb21 --- /dev/null +++ b/libsrc/vic20/c_readst.s @@ -0,0 +1,28 @@ +; +; 1999-06-03, Ullrich von Bassewitz +; 2021-01-12, Greg King +; +; unsigned char cbm_k_readst (void); +; +; This version works around a bug in VIC-20 Kernal's READST function. +; + + .include "vic20.inc" + .include "../cbm/cbm.inc" + + .export _cbm_k_readst + + +_cbm_k_readst: + ldx #>$0000 + lda DEVNUM + cmp #CBMDEV_RS232 + beq @L1 + + jmp READST + +; Work-around: Read the RS-232 status variable directly. + +@L1: lda RSSTAT + stx RSSTAT ; reset the status bits + rts From f273b1ebcb578a936ba19924fdc233f51607f1d6 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 26 Mar 2021 11:02:46 +0800 Subject: [PATCH 1955/2161] Fixed crash with non-inlined __fastcall__ function invocation with no arguments. --- src/cc65/expr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9b95efda6..0bb393cf1 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -835,7 +835,7 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) /* Append last deferred inc/dec before the function is called. ** The last parameter needs to be preserved if it is passed in AX/EAX Regs. */ - DoDeferred (IsFastcall ? SQP_KEEP_EAX : SQP_KEEP_NONE, &Expr); + DoDeferred (IsFastcall && PushedCount > 0 ? SQP_KEEP_EAX : SQP_KEEP_NONE, &Expr); /* Check if we had enough arguments */ if (PushedCount < Func->ParamCount) { @@ -928,7 +928,8 @@ static void FunctionCall (ExprDesc* Expr) } /* If we didn't inline the function, get fastcall info */ - IsFastcall = IsFastcallFunc (Expr->Type); + IsFastcall = (Func->ParamCount > 0 || (Func->Flags & FD_EMPTY) != 0) && + IsFastcallFunc (Expr->Type); } /* Parse the parameter list */ From 02392d62207ee63dc332daf4dafc6e9eff0b163f Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 26 Mar 2021 22:18:05 +0100 Subject: [PATCH 1956/2161] added test related to issue #1437 --- test/misc/Makefile | 5 +++++ test/misc/bug1437.c | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 test/misc/bug1437.c diff --git a/test/misc/Makefile b/test/misc/Makefile index 7a1b82d5f..397635afd 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -64,6 +64,11 @@ $(WORKDIR)/bug760.$1.$2.prg: bug760.c | $(WORKDIR) $(if $(QUIET),echo misc/bug760.$1.$2.prg) $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) +$(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." diff --git a/test/misc/bug1437.c b/test/misc/bug1437.c new file mode 100644 index 000000000..de6c7008d --- /dev/null +++ b/test/misc/bug1437.c @@ -0,0 +1,23 @@ + +/* bug #1437 enum declaration in struct does not compile */ + +struct nodelist1 { + enum { DEAD1, LIVE1, ONCE1, TWICE1 } live1; +} firstnode1 = {ONCE1}; + +enum nodestate2 { DEAD2, LIVE2, ONCE2, TWICE2 } live2; + +struct nodelist2 { + enum nodestate2 live2; +} firstnode2 = {TWICE2}; + +int main (void) +{ + if (firstnode1.live1 != ONCE1) { + return 1; + } + if (firstnode2.live2 != TWICE2) { + return 1; + } + return 0; +} From 54920193e5e00574179a27abf9b4fc39f71b7a89 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 27 Mar 2021 15:11:47 +0100 Subject: [PATCH 1957/2161] added test for issue #1438 --- test/val/bug1438.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 test/val/bug1438.c diff --git a/test/val/bug1438.c b/test/val/bug1438.c new file mode 100644 index 000000000..93addb877 --- /dev/null +++ b/test/val/bug1438.c @@ -0,0 +1,35 @@ + +/* Issue #1438 fix #1439 - crash in cc65, related to delayed post-counting + + this is an odd issue, the compile would crash *sometimes*, perhaps in one + of ten compilation runs. +*/ + +#define __fastcall__ + +unsigned short a[10] = {0,1,2,3,4,5,6,7,8,9}; + +unsigned short __fastcall__ func2(void) +{ + return 42; +} + +void func1(unsigned short *wp) +{ + *wp++ = func2(); +} + +int main(void) +{ + func1(&a[3]); + if (a[2] != 2) { + return 1; + } + if (a[3] != 42) { + return 1; + } + if (a[4] != 4) { + return 1; + } + return 0; +} From bf1bb7a0325d91712a724cb369cf34505bed7a8a Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 27 Mar 2021 15:13:32 +0100 Subject: [PATCH 1958/2161] ooopsie :) --- test/val/bug1438.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/val/bug1438.c b/test/val/bug1438.c index 93addb877..3894f87f1 100644 --- a/test/val/bug1438.c +++ b/test/val/bug1438.c @@ -5,7 +5,7 @@ of ten compilation runs. */ -#define __fastcall__ +/* #define __fastcall__ */ unsigned short a[10] = {0,1,2,3,4,5,6,7,8,9}; From edecbc86b84dcf75edf21725d9cc3ff791ce1262 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 27 Mar 2021 13:34:39 -0400 Subject: [PATCH 1959/2161] Reverted "Second address" back to "Secondary address". --- asminc/vic20.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asminc/vic20.inc b/asminc/vic20.inc index 91da083f1..41a935238 100644 --- a/asminc/vic20.inc +++ b/asminc/vic20.inc @@ -11,8 +11,8 @@ TXTPTR := $7A ; Pointer into BASIC source code STATUS := $90 ; Kernal I/O completion status TIME := $A0 ; 60HZ clock FNAM_LEN := $B7 ; Length of filename -SECADR := $B9 ; Second address -DEVNUM := $BA ; Device number (first address) +SECADR := $B9 ; Secondary address +DEVNUM := $BA ; Device number FNAM := $BB ; Pointer to filename KEY_COUNT := $C6 ; Number of keys in input buffer RVS := $C7 ; Reverse flag From cb8fbf4772a0f2bbb1c04393662a5cacaaeea4f4 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 29 Mar 2021 12:35:29 +0800 Subject: [PATCH 1960/2161] Removed the non-existing-in-C "struct/union scope" for structs/unions. Fixed handling of struct/union field declarations without identifiers, which do nothing. --- src/cc65/declare.c | 8 ++++---- src/cc65/symtab.c | 27 +++++++++++++++++++-------- src/cc65/symtab.h | 5 ++++- test/misc/bug1437.c | 23 ----------------------- test/val/bug1437.c | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 36 deletions(-) delete mode 100644 test/misc/bug1437.c create mode 100644 test/val/bug1437.c diff --git a/src/cc65/declare.c b/src/cc65/declare.c index d952d1049..787ed62b7 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -965,7 +965,7 @@ static SymEntry* ParseUnionDecl (const char* Name, unsigned* DSFlags) */ AddBitField (Decl.Ident, Decl.Type, 0, 0, FieldWidth, SignednessSpecified); - } else { + } else if (Decl.Ident[0] != '\0') { Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0); if (IsAnonName (Decl.Ident)) { Entry->V.A.ANumber = UnionTagEntry->V.S.ACount++; @@ -994,7 +994,7 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { NextToken (); /* Remember the symbol table and leave the struct level */ - FieldTab = GetSymTab (); + FieldTab = GetFieldSymTab (); LeaveStructLevel (); /* Return a fictitious symbol if errors occurred during parsing */ @@ -1167,7 +1167,7 @@ static SymEntry* ParseStructDecl (const char* Name, unsigned* DSFlags) /* Add any full bytes to the struct size. */ StructSize += BitOffs / CHAR_BITS; BitOffs %= CHAR_BITS; - } else { + } else if (Decl.Ident[0] != '\0') { Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize); if (IsAnonName (Decl.Ident)) { Entry->V.A.ANumber = StructTagEntry->V.S.ACount++; @@ -1208,7 +1208,7 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { NextToken (); /* Remember the symbol table and leave the struct level */ - FieldTab = GetSymTab (); + FieldTab = GetFieldSymTab (); LeaveStructLevel (); /* Return a fictitious symbol if errors occurred during parsing */ diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index db2b04f17..3d7176a83 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -92,6 +92,7 @@ static SymTable* SymTab0 = 0; static SymTable* SymTab = 0; static SymTable* TagTab0 = 0; static SymTable* TagTab = 0; +static SymTable* FieldTab = 0; static SymTable* LabelTab = 0; static SymTable* SPAdjustTab = 0; static SymTable* FailSafeTab = 0; /* For errors */ @@ -390,9 +391,9 @@ void EnterStructLevel (void) ** nested in struct scope are NOT local to the struct but visible in the ** outside scope. So we will NOT create a new struct or enum table. */ - S = NewSymTable (SYMTAB_SIZE_BLOCK); - S->PrevTab = SymTab; - SymTab = S; + S = NewSymTable (SYMTAB_SIZE_STRUCT); + S->PrevTab = FieldTab; + FieldTab = S; } @@ -401,7 +402,7 @@ void LeaveStructLevel (void) /* Leave a nested block for a struct definition */ { /* Don't delete the table */ - SymTab = SymTab->PrevTab; + FieldTab = FieldTab->PrevTab; } @@ -850,7 +851,7 @@ SymEntry* AddBitField (const char* Name, const Type* T, unsigned Offs, /* Add a bit field to the local symbol table and return the symbol entry */ { /* Do we have an entry with this name already? */ - SymEntry* Entry = FindSymInTable (SymTab, Name, HashStr (Name)); + SymEntry* Entry = FindSymInTable (FieldTab, Name, HashStr (Name)); if (Entry) { /* We have a symbol with this name already */ @@ -882,7 +883,7 @@ SymEntry* AddBitField (const char* Name, const Type* T, unsigned Offs, } /* Add the entry to the symbol table */ - AddSymEntry (SymTab, Entry); + AddSymEntry (FieldTab, Entry); } @@ -1070,9 +1071,9 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs) -/* Add a local symbol and return the symbol entry */ +/* Add a local or struct/union field symbol and return the symbol entry */ { - SymTable* Tab = SymTab; + SymTable* Tab = (Flags & SC_STRUCTFIELD) == 0 ? SymTab : FieldTab; ident Ident; /* Do we have an entry with this name already? */ @@ -1267,6 +1268,16 @@ SymTable* GetGlobalSymTab (void) return SymTab0; } + + +SymTable* GetFieldSymTab (void) +/* Return the current field symbol table */ +{ + return FieldTab; +} + + + SymTable* GetLabelSymTab (void) /* Return the global symbol table */ { diff --git a/src/cc65/symtab.h b/src/cc65/symtab.h index 1231eb528..469a4ba77 100644 --- a/src/cc65/symtab.h +++ b/src/cc65/symtab.h @@ -166,7 +166,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags); /* Add a goto label to the symbol table */ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs); -/* Add a local symbol and return the symbol entry */ +/* Add a local or struct/union field symbol and return the symbol entry */ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags); /* Add an external or global symbol to the symbol table and return the entry */ @@ -185,6 +185,9 @@ SymTable* GetSymTab (void); SymTable* GetGlobalSymTab (void); /* Return the global symbol table */ +SymTable* GetFieldSymTab (void); +/* Return the current field symbol table */ + SymTable* GetLabelSymTab (void); /* Return the label symbol table */ diff --git a/test/misc/bug1437.c b/test/misc/bug1437.c deleted file mode 100644 index de6c7008d..000000000 --- a/test/misc/bug1437.c +++ /dev/null @@ -1,23 +0,0 @@ - -/* bug #1437 enum declaration in struct does not compile */ - -struct nodelist1 { - enum { DEAD1, LIVE1, ONCE1, TWICE1 } live1; -} firstnode1 = {ONCE1}; - -enum nodestate2 { DEAD2, LIVE2, ONCE2, TWICE2 } live2; - -struct nodelist2 { - enum nodestate2 live2; -} firstnode2 = {TWICE2}; - -int main (void) -{ - if (firstnode1.live1 != ONCE1) { - return 1; - } - if (firstnode2.live2 != TWICE2) { - return 1; - } - return 0; -} diff --git a/test/val/bug1437.c b/test/val/bug1437.c new file mode 100644 index 000000000..3424079e1 --- /dev/null +++ b/test/val/bug1437.c @@ -0,0 +1,35 @@ + +/* bug #1437 enum declaration in a struct/union is invisible in the scope where the struct/union is declared */ + +struct nodelist1 { + struct { + enum { DEAD1, LIVE1, ONCE1, TWICE1 } live1; + } s; +} firstnode1 = {ONCE1}; + +enum nodestate2 { DEAD2, LIVE2, ONCE2, TWICE2 } live2; + +union nodelist2 { + enum nodestate2 live2; +} firstnode2 = { {TWICE2} }; + +struct T { + int I; + int; + enum E { + I + }; +}; + +int failures = 0; + +int main (void) +{ + if (firstnode1.s.live1 != ONCE1) { + ++failures; + } + if (firstnode2.live2 != TWICE2) { + ++failures; + } + return failures; +} From 31c1172a3aad97f9adbf127caca7dc74db01ffc0 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 23 Mar 2021 15:30:08 +0800 Subject: [PATCH 1961/2161] zlib: Use correct (un)signedness of char in prototypes and functions. Also ensure we are using the same constness qualifiers. --- include/zlib.h | 6 ++++-- libsrc/zlib/adler32.s | 3 ++- libsrc/zlib/crc32.s | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/zlib.h b/include/zlib.h index 3f6c2b27b..68439b290 100644 --- a/include/zlib.h +++ b/include/zlib.h @@ -114,7 +114,8 @@ int __fastcall__ uncompress (unsigned char* dest, unsigned* destLen, */ -unsigned long __fastcall__ adler32 (unsigned long adler, const char* buf, +unsigned long __fastcall__ adler32 (unsigned long adler, + const unsigned char* buf, unsigned len); /* @@ -140,7 +141,8 @@ unsigned long __fastcall__ adler32 (unsigned long adler, const char* buf, */ -unsigned long __fastcall__ crc32 (unsigned long crc, const char* buf, +unsigned long __fastcall__ crc32 (unsigned long crc, + const unsigned char* buf, unsigned len); /* Original zlib description: diff --git a/libsrc/zlib/adler32.s b/libsrc/zlib/adler32.s index 8aa641a13..1bb5588db 100644 --- a/libsrc/zlib/adler32.s +++ b/libsrc/zlib/adler32.s @@ -2,7 +2,8 @@ ; 2001-11-18, Piotr Fusik ; 2018-05-20, Christian Kruger ; -; unsigned long __fastcall__ adler32 (unsigned long adler, unsigned char* buf, +; unsigned long __fastcall__ adler32 (unsigned long adler, +; const unsigned char* buf, ; unsigned len); ; diff --git a/libsrc/zlib/crc32.s b/libsrc/zlib/crc32.s index f019736ad..41b5fe9db 100644 --- a/libsrc/zlib/crc32.s +++ b/libsrc/zlib/crc32.s @@ -2,7 +2,8 @@ ; 2001-11-14, Piotr Fusik ; 2018-05-20, Christian Kruger ; -; unsigned long __fastcall__ crc32 (unsigned long crc, unsigned char* buf, +; unsigned long __fastcall__ crc32 (unsigned long crc, +; const unsigned char* buf, ; unsigned len); ; From b802efde5446433af827dd46241dc7cf18b6a83b Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 15 Mar 2021 16:59:08 +0800 Subject: [PATCH 1962/2161] Fixed ternary result type detection with pointer types. Fixed pointer type comparison and conversion, especially regarding qualifiers. Improved diagnostics about type comparison and conversion. Reorganized some type-comparison/conversion functions. --- src/cc65/assignment.c | 2 +- src/cc65/datatype.h | 1 + src/cc65/declare.c | 2 +- src/cc65/expr.c | 78 +++++--- src/cc65/symtab.c | 22 ++- src/cc65/typecmp.c | 403 +++++++++++++++++++----------------------- src/cc65/typecmp.h | 48 +++-- src/cc65/typeconv.c | 235 +++++++++++++++++------- src/cc65/typeconv.h | 11 +- 9 files changed, 466 insertions(+), 336 deletions(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index 737d059a0..c642b4ce9 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -78,7 +78,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) hie1 (RExpr); /* Check for equality of the structs/unions */ - if (TypeCmp (ltype, RExpr->Type) < TC_STRICT_COMPATIBLE) { + if (TypeCmp (ltype, RExpr->Type).C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (ltype, RExpr->Type, 1, "Incompatible types in assignment to '%s' from '%s'"); } diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index ac6edeeb5..e6ff9b7ce 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -108,6 +108,7 @@ enum { T_QUAL_CONST = 0x001000, T_QUAL_VOLATILE = 0x002000, T_QUAL_RESTRICT = 0x004000, + T_QUAL_CVR = T_QUAL_CONST | T_QUAL_VOLATILE | T_QUAL_RESTRICT, T_QUAL_NEAR = 0x008000, T_QUAL_FAR = 0x010000, T_QUAL_ADDRSIZE = T_QUAL_NEAR | T_QUAL_FAR, diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 787ed62b7..0c00f56d4 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1821,7 +1821,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) NextToken (); /* Allow const, restrict, and volatile qualifiers */ - Qualifiers |= OptionalQualifiers (T_QUAL_CONST | T_QUAL_VOLATILE | T_QUAL_RESTRICT); + Qualifiers |= OptionalQualifiers (T_QUAL_CVR); /* Parse the type that the pointer points to */ Declarator (Spec, D, Mode); diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 0bb393cf1..be53b22f9 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -2447,15 +2447,11 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ } } else if (IsClassPtr (Expr->Type)) { if (IsClassPtr (Expr2.Type)) { - /* Both pointers are allowed in comparison if they point to - ** the same type, or if one of them is a void pointer. - */ - Type* left = Indirect (Expr->Type); - Type* right = Indirect (Expr2.Type); - if (TypeCmp (left, right) < TC_QUAL_DIFF && left->C != T_VOID && right->C != T_VOID) { - /* Incompatible pointers */ + /* Pointers are allowed in comparison */ + if (TypeCmp (Expr->Type, Expr2.Type).C < TC_STRICT_COMPATIBLE) { + /* Warn about distinct pointer types */ TypeCompatibilityDiagnostic (PtrConversion (Expr->Type), PtrConversion (Expr2.Type), 0, - "Incompatible pointer types comparing '%s' with '%s'"); + "Distinct pointer types comparing '%s' with '%s'"); } } else if (!ED_IsNullPtr (&Expr2)) { if (IsClassInt (Expr2.Type)) { @@ -3268,17 +3264,25 @@ static void parsesub (ExprDesc* Expr) if (IsClassPtr (lhst) && IsClassPtr (rhst)) { /* Pointer diff */ - if (TypeCmp (Indirect (lhst), Indirect (rhst)) < TC_QUAL_DIFF) { - Error ("Incompatible pointer types"); + if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + } else { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ flags = CF_PTR; Expr->Type = type_int; - /* We'll have to scale the result */ - rscale = CheckedPSizeOf (lhst); - /* Check for a constant rhs expression */ if (ED_IsQuasiConst (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) { /* The right hand side is constant. Check left hand side. */ @@ -4069,13 +4073,17 @@ static void hieQuest (ExprDesc* Expr) ** Conversion rules for ?: expression are: ** - if both expressions are int expressions, default promotion ** rules for ints apply. - ** - if both expressions are pointers of the same type, the - ** result of the expression is of this type. + ** - if both expressions have the same structure, union or void type, + ** the result has the same type. + ** - if both expressions are pointers to compatible types (possibly + ** qualified differently), the result of the expression is an + ** appropriately qualified version of the composite type. + ** - if one of the expressions is a pointer and the other is a + ** pointer to (possibly qualified) void, the resulting type is a + ** pointer to appropriately qualified void. ** - if one of the expressions is a pointer and the other is - ** a zero constant, the resulting type is that of the pointer - ** type. - ** - if both expressions are void expressions, the result is of - ** type void. + ** a null pointer constant, the resulting type is that of the + ** pointer type. ** - all other cases are flagged by an error. */ if (IsClassInt (Expr2.Type) && IsClassInt (Expr3.Type)) { @@ -4105,12 +4113,28 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && IsClassPtr (Expr3.Type)) { - /* Must point to same type */ - if (TypeCmp (Indirect (Expr2.Type), Indirect (Expr3.Type)) < TC_EQUAL) { - Error ("Incompatible pointer types"); + /* If one of the two is 'void *', the result type is a pointer to + ** appropriately qualified void. + */ + if (IsTypeVoid (Indirect (Expr2.Type))) { + ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); + } else if (IsTypeVoid (Indirect (Expr3.Type))) { + ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); + } else { + /* Must point to compatible types */ + if (TypeCmp (Expr2.Type, Expr3.Type).C < TC_VOID_PTR) { + TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, + 1, "Incompatible pointer types in ternary: '%s' and '%s'"); + /* Avoid further errors */ + ResultType = PointerTo (type_void); + } else { + /* Result has the composite type */ + ResultType = TypeDup (Expr2.Type); + TypeComposition (ResultType, Expr3.Type); + } } - /* Result has the common type */ - ResultType = Expr2.Type; } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ ResultType = Expr2.Type; @@ -4119,10 +4143,10 @@ static void hieQuest (ExprDesc* Expr) ResultType = Expr3.Type; } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = Expr3.Type; + ResultType = type_void; } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && - TypeCmp (Expr2.Type, Expr3.Type) == TC_IDENTICAL) { + TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ ResultType = Expr2.Type; } else { @@ -4148,7 +4172,7 @@ static void hieQuest (ExprDesc* Expr) } /* Setup the target expression */ - Expr->Type = ResultType; + Expr->Type = ResultType; } } diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 3d7176a83..6ec255497 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -59,6 +59,7 @@ #include "stackptr.h" #include "symentry.h" #include "typecmp.h" +#include "typeconv.h" #include "symtab.h" @@ -549,6 +550,19 @@ SymEntry FindStructField (const Type* T, const char* Name) +static int IsDistinctRedef (const Type* lhst, const Type* rhst, typecmpcode_t Code, typecmpflag_t Flags) +/* Return if type compatibility result is "worse" than Code or if any bit of +** qualifier Flags is set. +*/ +{ + typecmp_t Result = TypeCmp (lhst, rhst); + if (Result.C < Code || (Result.F & TCF_MASK_QUAL & Flags) != 0) { + return 1; + } + return 0; +} + + static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags) /* Check and handle redefinition of existing symbols. ** Complete array sizes and function descriptors as well. @@ -565,7 +579,7 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags /* Existing typedefs cannot be redeclared as anything different */ if (SCType == SC_TYPEDEF) { - if (TypeCmp (E_Type, T) < TC_IDENTICAL) { + if (IsDistinctRedef (E_Type, T, TC_IDENTICAL, TCF_MASK_QUAL)) { Error ("Conflicting types for typedef '%s'", Entry->Name); Entry = 0; } @@ -591,7 +605,7 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags Entry = 0; } else { /* New type must be compatible with the composite prototype */ - if (TypeCmp (Entry->Type, T) < TC_EQUAL) { + if (IsDistinctRedef (E_Type, T, TC_EQUAL, TCF_MASK_QUAL)) { Error ("Conflicting function types for '%s'", Entry->Name); Entry = 0; } else { @@ -621,7 +635,7 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags ** is incomplete, complete it. */ if ((Size != UNSPECIFIED && ESize != UNSPECIFIED && Size != ESize) || - TypeCmp (T + 1, E_Type + 1) < TC_EQUAL) { + IsDistinctRedef (E_Type + 1, T + 1, TC_IDENTICAL, TCF_MASK_QUAL)) { /* Conflicting element types */ Error ("Conflicting array types for '%s[]'", Entry->Name); Entry = 0; @@ -639,7 +653,7 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags if (SCType != E_SCType) { Error ("Redefinition of '%s' as different kind of symbol", Entry->Name); Entry = 0; - } else if (TypeCmp (E_Type, T) < TC_EQUAL) { + } else if (IsDistinctRedef (E_Type, T, TC_EQUAL, TCF_MASK_QUAL)) { Error ("Conflicting types for '%s'", Entry->Name); Entry = 0; } else if (E_SCType == SC_ENUMERATOR) { diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index f204b9a0b..7aae7fefe 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -36,7 +36,7 @@ #include <string.h> /* cc65 */ -#include "funcdesc.h" +#include "error.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -49,17 +49,6 @@ -static void SetResult (typecmp_t* Result, typecmp_t Val) -/* Set a new result value if it is less than the existing one */ -{ - if (Val < *Result) { - /* printf ("SetResult = %d\n", Val); */ - *Result = Val; - } -} - - - static int ParamsHaveDefaultPromotions (const FuncDesc* F) /* Check if any of the parameters of function F has a default promotion. In ** this case, the function is not compatible with an empty parameter name list @@ -129,7 +118,7 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) } /* Compare this field */ - if (TypeCmp (Type1, Type2) < TC_EQUAL) { + if (TypeCmp (Type1, Type2).C < TC_EQUAL) { /* Field types not equal */ return 0; } @@ -148,48 +137,169 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) +static void SetResult (typecmp_t* Result, typecmpcode_t Val) +/* Set a new result value if it is less than the existing one */ +{ + if (Val < Result->C) { + if (Result->Indirections > 0) { + if (Val >= TC_STRICT_COMPATIBLE) { + Result->C = Val; + } else if (Result->Indirections == 1) { + /* C Standard allows implicit conversion as long as one side is + ** a pointer to void type, but doesn't care which side is. + */ + if ((Result->F & TCF_MASK_VOID_PTR) != 0) { + Result->C = TC_VOID_PTR; + } else { + Result->C = TC_PTR_INCOMPATIBLE; + } + } else { + Result->C = TC_PTR_INCOMPATIBLE; + } + } else { + Result->C = Val; + } + /* printf ("SetResult = %d\n", Val); */ + } +} + + + +static typecmp_t* CmpQuals (const Type* lhst, const Type* rhst, typecmp_t* Result) +/* Copare the types regarding thier qualifiers. Return the Result */ +{ + TypeCode LeftQual, RightQual; + + /* Get the left and right qualifiers */ + LeftQual = GetQualifier (lhst); + RightQual = GetQualifier (rhst); + + /* If type is function without a calling convention set explicitly, + ** then assume the default one. + */ + if (IsTypeFunc (lhst)) { + if ((LeftQual & T_QUAL_CCONV) == T_QUAL_NONE) { + LeftQual |= (AutoCDecl || IsVariadicFunc (lhst)) ? T_QUAL_CDECL : T_QUAL_FASTCALL; + } + } + if (IsTypeFunc (rhst)) { + if ((RightQual & T_QUAL_CCONV) == T_QUAL_NONE) { + RightQual |= (AutoCDecl || IsVariadicFunc (rhst)) ? T_QUAL_CDECL : T_QUAL_FASTCALL; + } + } + + /* Default address size qualifiers */ + if ((LeftQual & T_QUAL_ADDRSIZE) == T_QUAL_NONE) { + LeftQual |= (IsTypeFunc (lhst) ? CodeAddrSizeQualifier () : DataAddrSizeQualifier ()); + } + if ((RightQual & T_QUAL_ADDRSIZE) == T_QUAL_NONE) { + RightQual |= (IsTypeFunc (rhst) ? CodeAddrSizeQualifier () : DataAddrSizeQualifier ()); + } + + /* Just return if nothing to do */ + if (LeftQual == RightQual) { + return Result; + } + + /* On the first indirection level, different qualifiers mean that the types + ** are still compatible. On the second level, that is a (maybe minor) error. + ** We create a special return-code if a qualifier is dropped from a pointer. + ** But, different calling conventions are incompatible. Starting from the + ** next level, the types are incompatible if the qualifiers differ. + */ + /* (Debugging statement) */ + /* printf ("Ind = %d %06X != %06X\n", Result->Indirections, LeftQual, RightQual); */ + switch (Result->Indirections) { + case 0: + /* Compare C qualifiers */ + if ((LeftQual & T_QUAL_CVR) > (RightQual & T_QUAL_CVR)) { + Result->F |= TCF_QUAL_IMPLICIT; + } else if ((LeftQual & T_QUAL_CVR) != (RightQual & T_QUAL_CVR)) { + Result->F |= TCF_QUAL_DIFF; + } + + /* Compare address size qualifiers */ + if ((LeftQual & T_QUAL_ADDRSIZE) != (RightQual & T_QUAL_ADDRSIZE)) { + Result->F |= TCF_ADDRSIZE_QUAL_DIFF; + } + + /* Compare function calling conventions */ + if ((LeftQual & T_QUAL_CCONV) != (RightQual & T_QUAL_CCONV)) { + SetResult (Result, TC_INCOMPATIBLE); + } + break; + + case 1: + /* A non-const value on the right is compatible to a + ** const one to the left, same for volatile. + */ + if ((LeftQual & T_QUAL_CVR) > (RightQual & T_QUAL_CVR)) { + Result->F |= TCF_PTR_QUAL_IMPLICIT; + } else if ((LeftQual & T_QUAL_CVR) != (RightQual & T_QUAL_CVR)) { + Result->F |= TCF_PTR_QUAL_DIFF; + } + + /* Compare address size qualifiers */ + if ((LeftQual & T_QUAL_ADDRSIZE) != (RightQual & T_QUAL_ADDRSIZE)) { + Result->F |= TCF_ADDRSIZE_QUAL_DIFF; + } + + /* Compare function calling conventions */ + if ((!IsTypeFunc (lhst) && !IsTypeFunc (rhst)) || + (LeftQual & T_QUAL_CCONV) == (RightQual & T_QUAL_CCONV)) { + break; + } + /* else fall through */ + + default: + /* Pointer types mismatch */ + SetResult (Result, TC_INCOMPATIBLE); + break; + } + + return Result; +} + + + static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) /* Recursively compare two types. */ { - unsigned Indirections; - unsigned ElementCount; SymEntry* Sym1; SymEntry* Sym2; FuncDesc* F1; FuncDesc* F2; + TypeCode LeftType, RightType; + long LeftCount, RightCount; - /* Initialize stuff */ - Indirections = 0; - ElementCount = 0; - /* Compare two types. Determine, where they differ */ while (lhs->C != T_END) { - TypeCode LeftType, RightType; - TypeCode LeftSign, RightSign; - TypeCode LeftQual, RightQual; - long LeftCount, RightCount; - /* Check if the end of the type string is reached */ if (rhs->C == T_END) { /* End of comparison reached */ + break; + } + + /* Compare qualifiers */ + if (CmpQuals (lhs, rhs, Result)->C == TC_INCOMPATIBLE) { return; } - /* Get the left and right types, signs and qualifiers */ + /* Get the left and right types */ LeftType = (GetUnderlyingTypeCode (lhs) & T_MASK_TYPE); RightType = (GetUnderlyingTypeCode (rhs) & T_MASK_TYPE); - LeftSign = GetSignedness (lhs); - RightSign = GetSignedness (rhs); - LeftQual = GetQualifier (lhs); - RightQual = GetQualifier (rhs); - /* If the left type is a pointer and the right is an array, both - ** are compatible. + /* If one side is a pointer and the other side is an array, both are + ** compatible. */ if (LeftType == T_TYPE_PTR && RightType == T_TYPE_ARRAY) { RightType = T_TYPE_PTR; + SetResult (Result, TC_PTR_DECAY); + } + if (LeftType == T_TYPE_ARRAY && RightType == T_TYPE_PTR) { + LeftType = T_TYPE_PTR; SetResult (Result, TC_STRICT_COMPATIBLE); } @@ -236,74 +346,30 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) /* 'char' is neither 'signed char' nor 'unsigned char' */ if ((IsISOChar (lhs) && !IsISOChar (rhs)) || (!IsISOChar (lhs) && IsISOChar (rhs))) { - SetResult (Result, TC_COMPATIBLE); + SetResult (Result, TC_SIGN_DIFF); } - /* On indirection level zero, a qualifier or sign difference is - ** accepted. The types are no longer equal, but compatible. + /* On indirection level zero, a sign difference is accepted. + ** The types are no longer equal, but compatible. */ - if (LeftSign != RightSign) { - if (ElementCount == 0) { - SetResult (Result, TC_SIGN_DIFF); - } else { - SetResult (Result, TC_INCOMPATIBLE); - return; - } - } - - if (LeftType == T_TYPE_FUNC) { - /* If a calling convention wasn't set explicitly, - ** then assume the default one. - */ - if ((LeftQual & T_QUAL_CCONV) == T_QUAL_NONE) { - LeftQual |= (AutoCDecl || IsVariadicFunc (lhs)) ? T_QUAL_CDECL : T_QUAL_FASTCALL; - } - if ((RightQual & T_QUAL_CCONV) == T_QUAL_NONE) { - RightQual |= (AutoCDecl || IsVariadicFunc (rhs)) ? T_QUAL_CDECL : T_QUAL_FASTCALL; - } - } - - if (LeftQual != RightQual) { - /* On the first indirection level, different qualifiers mean - ** that the types still are compatible. On the second level, - ** that is a (maybe minor) error. We create a special return-code - ** if a qualifier is dropped from a pointer. But, different calling - ** conventions are incompatible. Starting from the next level, - ** the types are incompatible if the qualifiers differ. - */ - /* (Debugging statement) */ - /* printf ("Ind = %d %06X != %06X\n", Indirections, LeftQual, RightQual); */ - switch (Indirections) { - case 0: - SetResult (Result, TC_STRICT_COMPATIBLE); - break; - - case 1: - /* A non-const value on the right is compatible to a - ** const one to the left, same for volatile. - */ - if ((LeftQual & T_QUAL_CONST) < (RightQual & T_QUAL_CONST) || - (LeftQual & T_QUAL_VOLATILE) < (RightQual & T_QUAL_VOLATILE)) { - SetResult (Result, TC_QUAL_DIFF); - } else { - SetResult (Result, TC_STRICT_COMPATIBLE); - } - - if (LeftType != T_TYPE_FUNC || (LeftQual & T_QUAL_CCONV) == (RightQual & T_QUAL_CCONV)) { - break; - } - /* else fall through */ - - default: - SetResult (Result, TC_INCOMPATIBLE); - return; - } + if (GetSignedness (lhs) != GetSignedness (rhs)) { + SetResult (Result, TC_SIGN_DIFF); } /* Check for special type elements */ switch (LeftType) { case T_TYPE_PTR: - ++Indirections; + ++Result->Indirections; + if (Result->Indirections == 1) { + if ((GetUnderlyingTypeCode (lhs + 1) & T_MASK_TYPE) == T_TYPE_VOID) { + Result->F |= TCF_VOID_PTR_ON_LEFT; + } + if ((GetUnderlyingTypeCode (rhs + 1) & T_MASK_TYPE) == T_TYPE_VOID) { + Result->F |= TCF_VOID_PTR_ON_RIGHT; + } + } else { + Result->F &= ~TCF_MASK_VOID_PTR; + } break; case T_TYPE_FUNC: @@ -364,7 +430,13 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) SetResult (Result, TC_INCOMPATIBLE); return; } - SetResult (Result, TC_EQUAL); + + /* We take into account which side is more specified */ + if (LeftCount == UNSPECIFIED) { + SetResult (Result, TC_UNSPECIFY); + } else { + SetResult (Result, TC_EQUAL); + } } break; @@ -397,11 +469,10 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) /* Next type string element */ ++lhs; ++rhs; - ++ElementCount; } - /* Check if end of rhs reached */ - if (rhs->C == T_END) { + /* Check if lhs and rhs both reached ends */ + if (lhs->C == T_END && rhs->C == T_END) { SetResult (Result, TC_IDENTICAL); } else { SetResult (Result, TC_INCOMPATIBLE); @@ -414,7 +485,7 @@ typecmp_t TypeCmp (const Type* lhs, const Type* rhs) /* Compare two types and return the result */ { /* Assume the types are identical */ - typecmp_t Result = TC_IDENTICAL; + typecmp_t Result = TYPECMP_INITIALIZER; #if 0 printf ("Left : "); PrintRawType (stdout, lhs); @@ -432,134 +503,18 @@ typecmp_t TypeCmp (const Type* lhs, const Type* rhs) -static Type* DoComposite (Type* lhs, const Type* rhs); - -static void CompositeFuncParams (const FuncDesc* F1, const FuncDesc* F2) -/* Composite two function symbol tables regarding function parameters */ +void TypeCompatibilityDiagnostic (const Type* NewType, const Type* OldType, int IsError, const char* Msg) +/* Print error or warning message about type compatibility with proper type names */ { - /* Get the symbol tables */ - const SymTable* Tab1 = F1->SymTab; - const SymTable* Tab2 = F2->SymTab; - - /* Composite the parameter lists */ - const SymEntry* Sym1 = Tab1->SymHead; - const SymEntry* Sym2 = Tab2->SymHead; - - /* Composite the fields */ - while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { - - /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; - - /* If either of both functions is old style, apply the default - ** promotions to the parameter type. - */ - if (F1->Flags & FD_OLDSTYLE) { - if (IsClassInt (Type1)) { - Type1 = IntPromotion (Type1); - } - } - if (F2->Flags & FD_OLDSTYLE) { - if (IsClassInt (Type2)) { - Type2 = IntPromotion (Type2); - } - } - - /* Composite this field */ - DoComposite (Type1, Type2); - - /* Get the pointers to the next fields */ - Sym1 = Sym1->NextSym; - Sym2 = Sym2->NextSym; + StrBuf NewTypeName = STATIC_STRBUF_INITIALIZER; + StrBuf OldTypeName = STATIC_STRBUF_INITIALIZER; + GetFullTypeNameBuf (&NewTypeName, NewType); + GetFullTypeNameBuf (&OldTypeName, OldType); + if (IsError) { + Error (Msg, SB_GetConstBuf (&NewTypeName), SB_GetConstBuf (&OldTypeName)); + } else { + Warning (Msg, SB_GetConstBuf (&NewTypeName), SB_GetConstBuf (&OldTypeName)); } -} - - - -static Type* DoComposite (Type* lhs, const Type* rhs) -/* Recursively composite two types into lhs */ -{ - FuncDesc* F1; - FuncDesc* F2; - long LeftCount, RightCount; - - /* Composite two types */ - while (lhs->C != T_END) { - - /* Check if the end of the type string is reached */ - if (rhs->C == T_END) { - return lhs; - } - - /* Check for sanity */ - CHECK (GetUnderlyingTypeCode (lhs) == GetUnderlyingTypeCode (rhs)); - - /* Check for special type elements */ - - if (IsTypeFunc (lhs)) { - /* Composite the function descriptors */ - F1 = GetFuncDesc (lhs); - F2 = GetFuncDesc (rhs); - - /* If one of both functions has an empty parameter list (which - ** does also mean, it is not a function definition, because the - ** flag is reset in this case), it is replaced by the other - ** definition, provided that the other has no default - ** promotions in the parameter list. If none of both parameter - ** lists is empty, we have to composite the parameter lists and - ** other attributes. - */ - if ((F1->Flags & FD_EMPTY) == FD_EMPTY) { - if ((F2->Flags & FD_EMPTY) == 0) { - /* Copy the parameters and flags */ - TypeCopy (lhs, rhs); - F1->Flags = F2->Flags; - } - } else if ((F2->Flags & FD_EMPTY) == 0) { - /* Composite the parameter lists */ - CompositeFuncParams (F1, F2); - } - - } else if (IsTypeArray (lhs)) { - /* Check member count */ - LeftCount = GetElementCount (lhs); - RightCount = GetElementCount (rhs); - - /* Set composite type if it is requested */ - if (LeftCount != UNSPECIFIED) { - SetElementCount (lhs, LeftCount); - } else if (RightCount != UNSPECIFIED) { - SetElementCount (lhs, RightCount); - } - } - - /* Next type string element */ - ++lhs; - ++rhs; - } - - return lhs; -} - - - -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) { - DoComposite (OldType, NewType); - } else { - TypeCopy (OldType, NewType); - Old->Flags &= ~FD_EMPTY; - } - } - - return Old; + SB_Done (&OldTypeName); + SB_Done (&NewTypeName); } diff --git a/src/cc65/typecmp.h b/src/cc65/typecmp.h index f4a87bcf6..e1ca699cf 100644 --- a/src/cc65/typecmp.h +++ b/src/cc65/typecmp.h @@ -48,18 +48,43 @@ -/* Degree of type compatibility. Must be in ascending order */ +/* Degree of type compatibility affected. Must be in ascending order */ typedef enum { - TC_INCOMPATIBLE, /* Distinct types */ - TC_SIGN_DIFF, /* Signedness differs */ - TC_COMPATIBLE = TC_SIGN_DIFF, /* Compatible types */ - TC_QUAL_DIFF, /* Types differ in qualifier of pointer */ - TC_STRICT_COMPATIBLE, /* Strict compatibility */ - TC_EQUAL, /* Types are equivalent */ - TC_IDENTICAL /* Types are identical */ + TC_INCOMPATIBLE, /* Distinct types */ + TC_SIGN_DIFF, /* Signedness differs */ + TC_PTR_INCOMPATIBLE, /* Distinct pointer types */ + TC_VOID_PTR, /* Non-void and void pointers */ + TC_STRICT_COMPATIBLE, /* Strict compatibility according to the C Standard */ + TC_PTR_DECAY, /* rhs is an array and lhs is a pointer */ + TC_EQUAL, /* Array types with unspecified lengths */ + TC_UNSPECIFY, /* lhs has unspecified length while rhs has specified length */ + TC_IDENTICAL /* Types are identical */ +} typecmpcode_t; + +/* Degree of type compatibility affected by qualifiers as well as some extra info */ +typedef enum { + TCF_NONE = 0x00, /* None of the below */ + 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_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_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, +} typecmpflag_t; + +typedef struct { + typecmpcode_t C; + typecmpflag_t F; + int Indirections; } typecmp_t; - +#define TYPECMP_INITIALIZER { TC_IDENTICAL, TCF_NONE, 0 } /*****************************************************************************/ /* Code */ @@ -70,8 +95,9 @@ typedef enum { typecmp_t TypeCmp (const Type* lhs, const Type* rhs); /* Compare two types and return the result */ -FuncDesc* RefineFuncDesc (Type* OldType, const Type* NewType); -/* Refine the existing function descriptor with a new one */ +void TypeCompatibilityDiagnostic (const Type* NewType, const Type* OldType, int IsError, const char* Msg); +/* Print error or warning message about type compatibility with proper type names */ + /* End of typecmp.h */ diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 930aef8d4..d75d13cd1 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -43,7 +43,6 @@ #include "error.h" #include "expr.h" #include "loadexpr.h" -#include "scanner.h" #include "typecmp.h" #include "typeconv.h" @@ -55,24 +54,6 @@ -void TypeCompatibilityDiagnostic (const Type* NewType, const Type* OldType, int IsError, const char* Msg) -/* Print error or warning message about type conversion with proper type names */ -{ - StrBuf NewTypeName = STATIC_STRBUF_INITIALIZER; - StrBuf OldTypeName = STATIC_STRBUF_INITIALIZER; - GetFullTypeNameBuf (&NewTypeName, NewType); - GetFullTypeNameBuf (&OldTypeName, OldType); - if (IsError) { - Error (Msg, SB_GetConstBuf (&NewTypeName), SB_GetConstBuf (&OldTypeName)); - } else { - Warning (Msg, SB_GetConstBuf (&NewTypeName), SB_GetConstBuf (&OldTypeName)); - } - SB_Done (&OldTypeName); - SB_Done (&NewTypeName); -} - - - static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { @@ -208,9 +189,10 @@ void TypeConversion (ExprDesc* Expr, const Type* NewType) PrintRawType (stdout, NewType); #endif /* First, do some type checking */ - int HasWarning = 0; - int HasError = 0; - const char* Msg = 0; + typecmp_t Result = TYPECMP_INITIALIZER; + int HasWarning = 0; + int HasError = 0; + const char* Msg = 0; const Type* OldType = Expr->Type; @@ -219,20 +201,13 @@ void TypeConversion (ExprDesc* Expr, const Type* NewType) HasError = 1; } - /* If both types are strictly compatible, no conversion is needed */ - if (TypeCmp (NewType, OldType) >= TC_STRICT_COMPATIBLE) { - /* We're already done */ - return; - } - - /* If Expr is an array or a function, convert it to a pointer */ - Expr->Type = PtrConversion (Expr->Type); - - /* If we have changed the type, check again for strictly compatibility */ - if (Expr->Type != OldType && - TypeCmp (NewType, Expr->Type) >= TC_STRICT_COMPATIBLE) { - /* We're already done */ - return; + /* If both types are the same, no conversion is needed */ + Result = TypeCmp (NewType, OldType); + if (Result.C < TC_IDENTICAL && (IsTypeArray (OldType) || IsTypeFunc (OldType))) { + /* If Expr is an array or a function, convert it to a pointer */ + Expr->Type = PtrConversion (Expr->Type); + /* Recompare */ + Result = TypeCmp (NewType, Expr->Type); } /* Check for conversion problems */ @@ -253,37 +228,27 @@ void TypeConversion (ExprDesc* Expr, const Type* NewType) /* Handle conversions to pointer type */ if (IsClassPtr (Expr->Type)) { - /* Pointer to pointer assignment is valid, if: + /* Implicit pointer-to-pointer conversion is valid, if: ** - both point to the same types, or ** - the rhs pointer is a void pointer, or ** - the lhs pointer is a void pointer. */ - if (!IsTypeVoid (IndirectConst (NewType)) && !IsTypeVoid (Indirect (Expr->Type))) { - /* Compare the types */ - switch (TypeCmp (NewType, Expr->Type)) { - - case TC_INCOMPATIBLE: - HasWarning = 1; - Msg = "Incompatible pointer assignment to '%s' from '%s'"; - /* Use the pointer type in the diagnostic */ - OldType = Expr->Type; - break; - - case TC_QUAL_DIFF: - HasWarning = 1; - Msg = "Pointer assignment to '%s' from '%s' discards qualifiers"; - /* Use the pointer type in the diagnostic */ - OldType = Expr->Type; - break; - - default: - /* Ok */ - break; - } + if (Result.C <= TC_PTR_INCOMPATIBLE || + (Result.F & TCF_INCOMPATIBLE_QUAL) != 0) + { + HasWarning = 1; + Msg = "Incompatible pointer conversion to '%s' from '%s'"; + /* Use the pointer type in the diagnostic */ + OldType = Expr->Type; + } else if ((Result.F & TCF_PTR_QUAL_DIFF) != 0) { + HasWarning = 1; + Msg = "Pointer conversion to '%s' from '%s' discards qualifiers"; + /* Use the pointer type in the diagnostic */ + OldType = Expr->Type; } } else if (IsClassInt (Expr->Type)) { - /* Int to pointer assignment is valid only for constant zero */ + /* Int to pointer conversion is valid only for constant zero */ if (!ED_IsConstAbsInt (Expr) || Expr->IVal != 0) { Warning ("Converting integer to pointer without a cast"); } @@ -291,11 +256,12 @@ void TypeConversion (ExprDesc* Expr, const Type* NewType) HasError = 1; } - } else { + } else if (Result.C < TC_IDENTICAL) { /* Invalid automatic conversion */ HasError = 1; } + /* Set default diagnostic message */ if (Msg == 0) { Msg = "Converting to '%s' from '%s'"; } @@ -350,13 +316,13 @@ void TypeCast (ExprDesc* Expr) /* Convert functions and arrays to "pointer to" object */ Expr->Type = PtrConversion (Expr->Type); - if (TypeCmp (NewType, Expr->Type) >= TC_QUAL_DIFF) { - /* If the new type only differs in qualifiers, just use it to - ** replace the old one. + if (TypeCmp (NewType, Expr->Type).C >= TC_PTR_INCOMPATIBLE) { + /* If the new type has the same underlying presentation, just + ** use it to replace the old one. */ ReplaceType (Expr, NewType); } else if (IsCastType (Expr->Type)) { - /* Convert the value. The rsult has always the new type */ + /* Convert the value. The result has always the new type */ DoConversion (Expr, NewType); } else { TypeCompatibilityDiagnostic (NewType, Expr->Type, 1, @@ -379,3 +345,142 @@ void TypeCast (ExprDesc* Expr) /* The result is always an rvalue */ ED_MarkExprAsRVal (Expr); } + + + +static void CompositeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) +/* Composite two function symbol tables regarding function parameters */ +{ + /* Get the symbol tables */ + const SymTable* Tab1 = F1->SymTab; + const SymTable* Tab2 = F2->SymTab; + + /* Composite the parameter lists */ + const SymEntry* Sym1 = Tab1->SymHead; + const SymEntry* Sym2 = Tab2->SymHead; + + /* Composite the fields */ + while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { + + /* Get the symbol types */ + Type* Type1 = Sym1->Type; + Type* Type2 = Sym2->Type; + + /* If either of both functions is old style, apply the default + ** promotions to the parameter type. + */ + if (F1->Flags & FD_OLDSTYLE) { + if (IsClassInt (Type1)) { + Type1 = IntPromotion (Type1); + } + } + if (F2->Flags & FD_OLDSTYLE) { + if (IsClassInt (Type2)) { + Type2 = IntPromotion (Type2); + } + } + + /* Compose this field */ + TypeComposition (Type1, Type2); + + /* Get the pointers to the next fields */ + Sym1 = Sym1->NextSym; + Sym2 = Sym2->NextSym; + } +} + + + +void TypeComposition (Type* lhs, const Type* rhs) +/* Recursively compose two types into lhs. The two types must have compatible +** type or this fails with a critical check. +*/ +{ + FuncDesc* F1; + FuncDesc* F2; + long LeftCount, RightCount; + + /* Composite two types */ + while (lhs->C != T_END) { + + /* Check if the end of the type string is reached */ + if (rhs->C == T_END) { + break; + } + + /* Check for sanity */ + CHECK (GetUnderlyingTypeCode (lhs) == GetUnderlyingTypeCode (rhs)); + + /* Check for special type elements */ + if (IsTypeFunc (lhs)) { + /* Composite the function descriptors */ + F1 = GetFuncDesc (lhs); + F2 = GetFuncDesc (rhs); + + /* If one of both functions has an empty parameter list (which + ** does also mean, it is not a function definition, because the + ** flag is reset in this case), it is replaced by the other + ** definition, provided that the other has no default + ** promotions in the parameter list. If none of both parameter + ** lists is empty, we have to composite the parameter lists and + ** other attributes. + */ + if ((F1->Flags & FD_EMPTY) == FD_EMPTY) { + if ((F2->Flags & FD_EMPTY) == 0) { + /* Copy the parameters and flags */ + TypeCopy (lhs, rhs); + F1->Flags = F2->Flags; + } + } else if ((F2->Flags & FD_EMPTY) == 0) { + /* Composite the parameter lists */ + CompositeFuncParamList (F1, F2); + } + } else if (IsTypeArray (lhs)) { + /* Check member count */ + LeftCount = GetElementCount (lhs); + RightCount = GetElementCount (rhs); + + /* Set composite type if it is requested */ + if (LeftCount != UNSPECIFIED) { + SetElementCount (lhs, LeftCount); + } else if (RightCount != UNSPECIFIED) { + SetElementCount (lhs, RightCount); + } + } else { + /* Combine the qualifiers */ + if (IsClassPtr (lhs)) { + ++lhs; + ++rhs; + lhs->C |= GetQualifier (rhs); + } + } + + /* Next type string element */ + ++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 0a82eac27..839c5e43e 100644 --- a/src/cc65/typeconv.h +++ b/src/cc65/typeconv.h @@ -49,9 +49,6 @@ -void TypeCompatibilityDiagnostic (const Type* NewType, const Type* OldType, int IsError, const char* Msg); -/* Print error or warning message about type conversion with proper type names */ - void TypeConversion (ExprDesc* Expr, const Type* NewType); /* Do an automatic conversion of the given expression to the new type. Output ** warnings or errors where this automatic conversion is suspicious or @@ -61,6 +58,14 @@ void TypeConversion (ExprDesc* Expr, const Type* NewType); void TypeCast (ExprDesc* Expr); /* Handle an explicit cast. */ +void TypeComposition (Type* lhs, const Type* rhs); +/* Recursively compose two types into lhs. The two types must have compatible +** 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 4a3896538409ec6a186bbabbd3f94e9dec7e70b4 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 25 Mar 2021 13:32:46 +0800 Subject: [PATCH 1963/2161] Warnings on discarding pointer qualifiers always. Added new -W options to turn on/off warnings on certain pointer conversion cases: - pointer-sign: to a pointer type differing in pointee signedness. Default on. - pointer-types: to a pointer type incompatible. Default on. --- src/cc65/error.c | 4 ++++ src/cc65/error.h | 2 ++ src/cc65/typecmp.c | 8 ++++++++ src/cc65/typecmp.h | 1 + src/cc65/typeconv.c | 38 +++++++++++++++++++++----------------- 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/cc65/error.c b/src/cc65/error.c index feb43565d..ec665b319 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -68,6 +68,8 @@ IntStack WarningsAreErrors = INTSTACK(0); /* Treat warnings as errors */ /* Warn about: */ IntStack WarnConstComparison= INTSTACK(1); /* - constant comparison results */ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ +IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ +IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ @@ -87,6 +89,8 @@ static WarnMapEntry WarnMap[] = { { &WarnConstComparison, "const-comparison" }, { &WarningsAreErrors, "error" }, { &WarnNoEffect, "no-effect" }, + { &WarnPointerSign, "pointer-sign" }, + { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, diff --git a/src/cc65/error.h b/src/cc65/error.h index 898793651..a7592b366 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -64,6 +64,8 @@ extern IntStack WarnEnable; /* Enable warnings */ extern IntStack WarningsAreErrors; /* Treat warnings as errors */ /* Warn about: */ extern IntStack WarnConstComparison; /* - constant comparison results */ +extern IntStack WarnPointerSign; /* - pointer conversion to pointer differing in signedness */ +extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ extern IntStack WarnStructParam; /* - structs passed by val */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 7aae7fefe..567ab4e87 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -143,6 +143,7 @@ static void SetResult (typecmp_t* Result, typecmpcode_t Val) if (Val < Result->C) { if (Result->Indirections > 0) { if (Val >= TC_STRICT_COMPATIBLE) { + /* Arrays etc. */ Result->C = Val; } else if (Result->Indirections == 1) { /* C Standard allows implicit conversion as long as one side is @@ -150,10 +151,17 @@ static void SetResult (typecmp_t* Result, typecmpcode_t Val) */ if ((Result->F & TCF_MASK_VOID_PTR) != 0) { Result->C = TC_VOID_PTR; + } else if (Val == TC_SIGN_DIFF) { + /* Special treatment with pointee signedness difference */ + Result->C = TC_PTR_SIGN_DIFF; } else { + /* Incompatible */ Result->C = TC_PTR_INCOMPATIBLE; } } else { + /* Pointer-to-pointer types must have compatible pointte types, + ** or they are just incompatible. + */ Result->C = TC_PTR_INCOMPATIBLE; } } else { diff --git a/src/cc65/typecmp.h b/src/cc65/typecmp.h index e1ca699cf..367df5245 100644 --- a/src/cc65/typecmp.h +++ b/src/cc65/typecmp.h @@ -52,6 +52,7 @@ typedef enum { TC_INCOMPATIBLE, /* Distinct types */ TC_SIGN_DIFF, /* Signedness differs */ + TC_PTR_SIGN_DIFF, /* Pointee signedness differs */ TC_PTR_INCOMPATIBLE, /* Distinct pointer types */ TC_VOID_PTR, /* Non-void and void pointers */ TC_STRICT_COMPATIBLE, /* Strict compatibility according to the C Standard */ diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index d75d13cd1..91a1f022d 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -190,7 +190,6 @@ void TypeConversion (ExprDesc* Expr, const Type* NewType) #endif /* First, do some type checking */ typecmp_t Result = TYPECMP_INITIALIZER; - int HasWarning = 0; int HasError = 0; const char* Msg = 0; const Type* OldType = Expr->Type; @@ -232,19 +231,28 @@ void TypeConversion (ExprDesc* Expr, const Type* NewType) ** - both point to the same types, or ** - the rhs pointer is a void pointer, or ** - the lhs pointer is a void pointer. + ** Note: We additionally allow converting function pointers to and from + ** void pointers, just with warnings. */ - if (Result.C <= TC_PTR_INCOMPATIBLE || - (Result.F & TCF_INCOMPATIBLE_QUAL) != 0) - { - HasWarning = 1; - Msg = "Incompatible pointer conversion to '%s' from '%s'"; - /* Use the pointer type in the diagnostic */ - OldType = Expr->Type; - } else if ((Result.F & TCF_PTR_QUAL_DIFF) != 0) { - HasWarning = 1; - Msg = "Pointer conversion to '%s' from '%s' discards qualifiers"; - /* Use the pointer type in the diagnostic */ - OldType = Expr->Type; + if (Result.C == TC_PTR_SIGN_DIFF) { + /* Specific warning for pointee signedness difference */ + if (IS_Get (&WarnPointerSign)) { + TypeCompatibilityDiagnostic (NewType, Expr->Type, + 0, "Pointer conversion to '%s' from '%s' changes pointee signedness"); + } + } else if ((Result.C <= TC_PTR_INCOMPATIBLE || + (Result.F & TCF_INCOMPATIBLE_QUAL) != 0)) { + /* Incompatible pointee types or qualifiers */ + if (IS_Get (&WarnPointerTypes)) { + TypeCompatibilityDiagnostic (NewType, Expr->Type, + 0, "Incompatible pointer conversion to '%s' from '%s'"); + } + } + + if ((Result.F & TCF_PTR_QUAL_DIFF) != 0) { + /* Discarding qualifiers is a bad thing and we always warn */ + TypeCompatibilityDiagnostic (NewType, Expr->Type, + 0, "Pointer conversion to '%s' from '%s' discards qualifiers"); } } else if (IsClassInt (Expr->Type)) { @@ -269,10 +277,6 @@ void TypeConversion (ExprDesc* Expr, const Type* NewType) if (HasError) { TypeCompatibilityDiagnostic (NewType, OldType, 1, Msg); } else { - if (HasWarning) { - TypeCompatibilityDiagnostic (NewType, OldType, 0, Msg); - } - /* Both types must be complete */ if (!IsIncompleteESUType (NewType) && !IsIncompleteESUType (Expr->Type)) { /* Do the actual conversion */ From 200b42056216457a4f79097bf76195ef5bbb3da2 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 1 Apr 2021 15:06:47 +0200 Subject: [PATCH 1964/2161] Export LMARGN_save to C. People might want to preserve this setting in their program. In turn rearrange startup code in order that LMARGN can be set by a 'constructor' (Do "initlib" later.) --- libsrc/atari/crt0.s | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libsrc/atari/crt0.s b/libsrc/atari/crt0.s index 97b7d7e95..381aa699f 100644 --- a/libsrc/atari/crt0.s +++ b/libsrc/atari/crt0.s @@ -10,6 +10,7 @@ .export __STARTUP__ : absolute = 1 ; Mark as startup .export _exit, start, excexit, SP_save + .export __LMARGN_save ; original LMARGN setting .import initlib, donelib .import callmain, zerobss @@ -82,14 +83,10 @@ start: .endif -; Call the module constructors. - - jsr initlib - ; Set the left margin to 0. lda LMARGN - sta LMARGN_save + sta __LMARGN_save ldy #0 sty LMARGN @@ -104,6 +101,10 @@ start: dey ; Set Y to $FF sty CH ; remove keypress which might be in the input buffer +; Call the module constructors. + + jsr initlib + ; Push the command-line arguments; and, call main(). jsr callmain @@ -119,7 +120,7 @@ excexit:jsr donelib ; Run module destructors; 'excexit' is called fr ; Restore the left margin. - lda LMARGN_save + lda __LMARGN_save sta LMARGN ; Restore the kb mode. @@ -196,7 +197,7 @@ excexit:jsr donelib ; Run module destructors; 'excexit' is called fr SP_save: .res 1 SHFLOK_save: .res 1 -LMARGN_save: .res 1 +__LMARGN_save: .res 1 .ifndef __ATARIXL__ APPMHI_save: .res 2 .endif From 91fd30611a3e24a8d0702d5345812cdbf1a79671 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 29 Mar 2021 14:30:44 +0800 Subject: [PATCH 1965/2161] Fixed ICE on error cases such as '&func + int a'. --- src/cc65/expr.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index be53b22f9..58de0d891 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -2850,27 +2850,31 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) } else { /* OOPS */ AddDone = -1; + /* Avoid further errors */ + ED_MakeConstAbsInt (Expr, 0); } - /* Do constant calculation if we can */ - if (ED_IsAbs (&Expr2) && - (ED_IsAbs (Expr) || lscale == 1)) { - if (IsClassInt (lhst) && IsClassInt (rhst)) { - Expr->Type = ArithmeticConvert (Expr->Type, Expr2.Type); + if (!AddDone) { + /* Do constant calculation if we can */ + if (ED_IsAbs (&Expr2) && + (ED_IsAbs (Expr) || lscale == 1)) { + if (IsClassInt (lhst) && IsClassInt (rhst)) { + Expr->Type = ArithmeticConvert (Expr->Type, Expr2.Type); + } + Expr->IVal = Expr->IVal * lscale + Expr2.IVal * rscale; + AddDone = 1; + } else if (ED_IsAbs (Expr) && + (ED_IsAbs (&Expr2) || rscale == 1)) { + if (IsClassInt (lhst) && IsClassInt (rhst)) { + Expr2.Type = ArithmeticConvert (Expr2.Type, Expr->Type); + } + Expr2.IVal = Expr->IVal * lscale + Expr2.IVal * rscale; + /* Adjust the flags */ + Expr2.Flags |= Expr->Flags & ~E_MASK_KEEP_SUBEXPR; + /* Get the symbol and the name */ + *Expr = Expr2; + AddDone = 1; } - Expr->IVal = Expr->IVal * lscale + Expr2.IVal * rscale; - AddDone = 1; - } else if (ED_IsAbs (Expr) && - (ED_IsAbs (&Expr2) || rscale == 1)) { - if (IsClassInt (lhst) && IsClassInt (rhst)) { - Expr2.Type = ArithmeticConvert (Expr2.Type, Expr->Type); - } - Expr2.IVal = Expr->IVal * lscale + Expr2.IVal * rscale; - /* Adjust the flags */ - Expr2.Flags |= Expr->Flags & ~E_MASK_KEEP_SUBEXPR; - /* Get the symbol and the name */ - *Expr = Expr2; - AddDone = 1; } if (AddDone) { From 2864b3ef8a1722b4eda017a74ac964136279f82a Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 30 Mar 2021 10:59:44 +0800 Subject: [PATCH 1966/2161] Fixed composition of prototypes and old-style function definitions with default promotions. Fixed function parameter list comparison with empty ones. --- src/cc65/typecmp.c | 65 +++++++-------------------------------------- src/cc65/typeconv.c | 52 +++++++++++++++++++++++------------- 2 files changed, 43 insertions(+), 74 deletions(-) diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 567ab4e87..58f41d3ca 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -49,40 +49,6 @@ -static int ParamsHaveDefaultPromotions (const FuncDesc* F) -/* Check if any of the parameters of function F has a default promotion. In -** this case, the function is not compatible with an empty parameter name list -** declaration. -*/ -{ - /* Get the symbol table */ - const SymTable* Tab = F->SymTab; - - /* Get the first parameter in the list */ - const SymEntry* Sym = Tab->SymHead; - - /* Walk over all parameters */ - while (Sym && (Sym->Flags & SC_PARAM)) { - - /* If this is an integer type, check if the promoted type is equal - ** to the original type. If not, we have a default promotion. - */ - if (IsClassInt (Sym->Type)) { - if (IntPromotion (Sym->Type) != Sym->Type) { - return 1; - } - } - - /* Get the pointer to the next param */ - Sym = Sym->NextSym; - } - - /* No default promotions in the parameter list */ - return 0; -} - - - static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) /* Compare two function symbol tables regarding function parameters. Return 1 ** if they are equal and 0 otherwise. @@ -385,29 +351,16 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) F1 = GetFuncDesc (lhs); F2 = GetFuncDesc (rhs); - /* If one of both functions has an empty parameter list (which - ** does also mean, it is not a function definition, because the - ** flag is reset in this case), it is considered equal to any - ** other definition, provided that the other has no default - ** promotions in the parameter list. If none of both parameter - ** lists is empty, we have to check the parameter lists and - ** other attributes. + /* If one of both function declarations has an empty parameter + ** list (which does also mean, it is not a function definition, + ** because the flag is reset in this case), it is ignored for + ** parameter comparison and considered equal to the other one, + ** provided both have the same return type and other attributes. + ** If neither of both parameter lists is empty, we have to check + ** the parameter lists. */ - if (F1->Flags & FD_EMPTY) { - if ((F2->Flags & FD_EMPTY) == 0) { - if (ParamsHaveDefaultPromotions (F2)) { - /* Flags differ */ - SetResult (Result, TC_INCOMPATIBLE); - return; - } - } - } else if (F2->Flags & FD_EMPTY) { - if (ParamsHaveDefaultPromotions (F1)) { - /* Flags differ */ - SetResult (Result, TC_INCOMPATIBLE); - return; - } - } else { + if ((F1->Flags & FD_EMPTY) == 0 && + (F2->Flags & FD_EMPTY) == 0) { /* Check the remaining flags */ if ((F1->Flags & ~FD_IGNORE) != (F2->Flags & ~FD_IGNORE)) { diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 91a1f022d..8bdef8d03 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -352,18 +352,21 @@ void TypeCast (ExprDesc* Expr) -static void CompositeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) -/* Composite two function symbol tables regarding function parameters */ +static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) +/* Compose two function symbol tables regarding function parameters into F1 */ { /* Get the symbol tables */ const SymTable* Tab1 = F1->SymTab; const SymTable* Tab2 = F2->SymTab; - /* Composite the parameter lists */ - const SymEntry* Sym1 = Tab1->SymHead; - const SymEntry* Sym2 = Tab2->SymHead; + /* Compose the parameter lists */ + SymEntry* Sym1 = Tab1->SymHead; + SymEntry* Sym2 = Tab2->SymHead; - /* Composite the fields */ + /* Sanity check */ + CHECK ((F1->Flags & FD_EMPTY) == 0 && (F2->Flags & FD_EMPTY) == 0); + + /* Compose the fields */ while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ @@ -384,8 +387,19 @@ static void CompositeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) } } + /* When we compose two function parameter lists with any FD_OLDSTYLE + ** flags set, we are either refining the declaration of the function + ** with its definition seen, or determining the result type of a + ** ternary operation. In either case, we can just replace the types + ** with the promoted ones since the original types of the parameters + ** only matters inside the function definition. + */ + if (Type1 != Sym1->Type) { + Sym1->Type = TypeDup (Type1); + } + /* Compose this field */ - TypeComposition (Type1, Type2); + TypeComposition (Sym1->Type, Type2); /* Get the pointers to the next fields */ Sym1 = Sym1->NextSym; @@ -404,7 +418,7 @@ void TypeComposition (Type* lhs, const Type* rhs) FuncDesc* F2; long LeftCount, RightCount; - /* Composite two types */ + /* Compose two types */ while (lhs->C != T_END) { /* Check if the end of the type string is reached */ @@ -417,17 +431,15 @@ void TypeComposition (Type* lhs, const Type* rhs) /* Check for special type elements */ if (IsTypeFunc (lhs)) { - /* Composite the function descriptors */ + /* Compose the function descriptors */ F1 = GetFuncDesc (lhs); F2 = GetFuncDesc (rhs); - /* If one of both functions has an empty parameter list (which - ** does also mean, it is not a function definition, because the - ** flag is reset in this case), it is replaced by the other - ** definition, provided that the other has no default - ** promotions in the parameter list. If none of both parameter - ** lists is empty, we have to composite the parameter lists and - ** other attributes. + /* If F1 has an empty parameter list (which does also mean, it is + ** not a function definition, because the flag is reset in this + ** case), its declaration is replaced by the other declaration. If + ** neither of the parameter lists is empty, we have to compose them + ** as well as other attributes. */ if ((F1->Flags & FD_EMPTY) == FD_EMPTY) { if ((F2->Flags & FD_EMPTY) == 0) { @@ -436,8 +448,12 @@ void TypeComposition (Type* lhs, const Type* rhs) F1->Flags = F2->Flags; } } else if ((F2->Flags & FD_EMPTY) == 0) { - /* Composite the parameter lists */ - CompositeFuncParamList (F1, F2); + /* Compose the parameter lists */ + ComposeFuncParamList (F1, F2); + /* Prefer non-old-style */ + if ((F2->Flags & FD_OLDSTYLE) == 0) { + F1->Flags &= ~FD_OLDSTYLE; + } } } else if (IsTypeArray (lhs)) { /* Check member count */ From 1a3628df1a6417156feefcbdf19dd24856d5e073 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 30 Mar 2021 10:59:44 +0800 Subject: [PATCH 1967/2161] Fixed the term 'argument' vs 'parameter' in function parser. --- src/cc65/expr.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 58de0d891..9e08faeeb 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -651,11 +651,11 @@ void DoDeferred (unsigned Flags, ExprDesc* Expr) } -static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) -/* Parse a function parameter list, and pass the arguments to the called -** function. Depending on several criteria, this may be done by just pushing -** into each parameter separately, or creating the parameter frame once, and -** then storing into this frame. +static unsigned FunctionArgList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) +/* Parse the argument list of the called function and pass the arguments to it. +** Depending on several criteria, this may be done by just pushing into each +** parameter separately, or creating the parameter frame once and then storing +** arguments into this frame one by one. ** The function returns the size of the arguments pushed in bytes. */ { @@ -860,7 +860,7 @@ static void FunctionCall (ExprDesc* Expr) { FuncDesc* Func; /* Function descriptor */ int IsFuncPtr; /* Flag */ - unsigned ParamSize; /* Number of parameter bytes */ + unsigned ArgSize; /* Number of arguments bytes */ CodeMark Mark; int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ @@ -932,8 +932,8 @@ static void FunctionCall (ExprDesc* Expr) IsFastcallFunc (Expr->Type); } - /* Parse the parameter list */ - ParamSize = FunctionParamList (Func, IsFastcall, Expr); + /* Parse the argument list and pass them to the called function */ + ArgSize = FunctionArgList (Func, IsFastcall, Expr); /* We need the closing paren here */ ConsumeRParen (); @@ -952,11 +952,11 @@ static void FunctionCall (ExprDesc* Expr) /* Not a fastcall function - we may use the primary */ if (PtrOnStack) { - /* If we have no parameters, the pointer is still in the + /* If we have no arguments, the pointer is still in the ** primary. Remove the code to push it and correct the ** stack pointer. */ - if (ParamSize == 0) { + if (ArgSize == 0) { RemoveCode (&Mark); PtrOnStack = 0; } else { @@ -969,7 +969,7 @@ static void FunctionCall (ExprDesc* Expr) } /* Call the function */ - g_callind (FuncTypeOf (Expr->Type+1), ParamSize, PtrOffs); + g_callind (FuncTypeOf (Expr->Type+1), ArgSize, PtrOffs); } else { @@ -978,7 +978,7 @@ static void FunctionCall (ExprDesc* Expr) ** Since fastcall functions may never be variadic, we can use the ** index register for this purpose. */ - g_callind (CF_STACK, ParamSize, PtrOffs); + g_callind (CF_STACK, ArgSize, PtrOffs); } /* If we have a pointer on stack, remove it */ @@ -1030,9 +1030,9 @@ static void FunctionCall (ExprDesc* Expr) SB_Done (&S); - g_call (FuncTypeOf (Expr->Type), Func->WrappedCall->Name, ParamSize); + g_call (FuncTypeOf (Expr->Type), Func->WrappedCall->Name, ArgSize); } else { - g_call (FuncTypeOf (Expr->Type), (const char*) Expr->Name, ParamSize); + g_call (FuncTypeOf (Expr->Type), (const char*) Expr->Name, ArgSize); } } From 5d05451ab2e5e4b9e52c99a5d6d04dfb5ac7ca7e Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 1 Apr 2021 11:41:55 +0800 Subject: [PATCH 1968/2161] Fixed test case for Issue #1263. --- test/{misc => val}/bug1263.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) rename test/{misc => val}/bug1263.c (59%) diff --git a/test/misc/bug1263.c b/test/val/bug1263.c similarity index 59% rename from test/misc/bug1263.c rename to test/val/bug1263.c index 4e5987c58..740b19250 100644 --- a/test/misc/bug1263.c +++ b/test/val/bug1263.c @@ -1,15 +1,22 @@ /* bug #1263 - erroneous error for K & R function declaration */ enum E { I = 0 }; -extern int f(enum E); +extern int f(); int f(e) enum E e; { return e; } +extern int g(int); +int g(e) + enum E e; +{ + return e; +} + int main(void) { - return f(I); + return f(I) + g(I); } From f5365c7ffdcafda91b7f84d3b4d04555ba458816 Mon Sep 17 00:00:00 2001 From: polluks2 <74630735+polluks2@users.noreply.github.com> Date: Sun, 4 Apr 2021 03:13:45 +0200 Subject: [PATCH 1969/2161] Update README.md Commander X16 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3d78fda50..2c84b7430 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ including - the Oric Telestrat. - the Lynx console. - the Ohio Scientific Challenger 1P. +- the Commander X16. The libraries are fairly portable, so creating a version for other 6502s shouldn't be too much work. From bd8eae67f1616ca8fcb434a8ba932731c21891f8 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 5 Apr 2021 16:40:32 +0800 Subject: [PATCH 1970/2161] Fixed local struct field access via the address of the struct. --- src/cc65/expr.c | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..74524c47a 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. From 39700c77ee8eb0c2e162b81155c5066c6a4c81fe Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 5 Apr 2021 17:31:18 +0800 Subject: [PATCH 1971/2161] Added test case for Issue #1451. --- test/val/bug1451.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 test/val/bug1451.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include <stdio.h> + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} From 0ed41db478ccf77b89aca8c6e9e959b0c113336c Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 5 Apr 2021 23:50:07 +0200 Subject: [PATCH 1972/2161] Some minor clarifications. --- doc/apple2.sgml | 14 +++++--------- doc/apple2enh.sgml | 14 +++++--------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 91c02c7ad..f957e1247 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -575,15 +575,13 @@ url="ca65.html" name="assembler manual">. <tag>Explanation of File Types</tag> - ProDOS associates a file type and an auxiliary type with each file. + ProDOS 8 associates a file type and an auxiliary type with each file. These type specifications are separate from the file's name, unlike Windows which uses the file name's suffix (a.k.a. extension) to specify the file type. For example, <tt/.exe/, <tt/.doc/, or <tt/.bat/. - The ProDOS low-level - Machine-Language Interface (MLI) functions for creating and opening - files require these types to be specified. And if they don't match - with the file being opened, the operation may fail. + The ProDOS 8 Machine-Language Interface (MLI) function for creating a + file require these types to be specified. In contrast, the ISO C function <tt/fopen()/ and the POSIX function <tt/open()/ have no parameter to specify either a file type or an @@ -606,8 +604,6 @@ url="ca65.html" name="assembler manual">. The header file <tt/apple2_filetype.h/ also defines many values that can be used to set these variables. It is included in <tt/apple2.h/, which is in turn included in <tt/apple2enh.h/. - So it isn't necessary to include it directly. Just - include one of <tt/apple2.h/ or <tt/apple2enh.h/. <tag>Example</tag> @@ -624,8 +620,8 @@ url="ca65.html" name="assembler manual">. carriage return instead of a line-feed (Linux/BSD/MacOS) or carriage return, line-feed pair (Windows). - The "sequential" text file terminology is in contrast to a - "random-access" text file which would + The 'sequential' text file terminology is in contrast to a + 'random-access' text file which would have a fixed-length, non-zero record length, so that the file position of any individual record can be calculated. diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 2d4381353..4aafbc256 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -580,15 +580,13 @@ url="ca65.html" name="assembler manual">. <tag>Explanation of File Types</tag> - ProDOS associates a file type and an auxiliary type with each file. + ProDOS 8 associates a file type and an auxiliary type with each file. These type specifications are separate from the file's name, unlike Windows which uses the file name's suffix (a.k.a. extension) to specify the file type. For example, <tt/.exe/, <tt/.doc/, or <tt/.bat/. - The ProDOS low-level - Machine-Language Interface (MLI) functions for creating and opening - files require these types to be specified. And if they don't match - with the file being opened, the operation may fail. + The ProDOS 8 Machine-Language Interface (MLI) function for creating a + file require these types to be specified. In contrast, the ISO C function <tt/fopen()/ and the POSIX function <tt/open()/ have no parameter to specify either a file type or an @@ -611,8 +609,6 @@ url="ca65.html" name="assembler manual">. The header file <tt/apple2_filetype.h/ also defines many values that can be used to set these variables. It is included in <tt/apple2.h/, which is in turn included in <tt/apple2enh.h/. - So it isn't necessary to include it directly. Just - include one of <tt/apple2.h/ or <tt/apple2enh.h/. <tag>Example</tag> @@ -629,8 +625,8 @@ url="ca65.html" name="assembler manual">. carriage return instead of a line-feed (Linux/BSD/MacOS) or carriage return, line-feed pair (Windows). - The "sequential" text file terminology is in contrast to a - "random-access" text file which would + The 'sequential' text file terminology is in contrast to a + 'random-access' text file which would have a fixed-length, non-zero record length, so that the file position of any individual record can be calculated. From e435da623460d3baaad0c8f5f0b609f53cb96bb3 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 18 Sep 2020 20:21:51 +0800 Subject: [PATCH 1973/2161] Interim fix for Issue #897. --- src/cc65/codeseg.c | 49 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); From 5f8d1630458f76f17862ed1fff6a30a635e93218 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 1 Apr 2021 18:46:00 +0800 Subject: [PATCH 1974/2161] Moved one test case for #1209. --- test/{misc => val}/bug1209-ind-goto-rev.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{misc => val}/bug1209-ind-goto-rev.c (100%) diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c From eb1cf750f285dffd3d3b6de227482e69f1b79c01 Mon Sep 17 00:00:00 2001 From: Dirk Lehmann <develop@dj-l.de> Date: Mon, 12 Apr 2021 17:05:31 +0200 Subject: [PATCH 1975/2161] -W-unreachable-code option added, alphabetic order of --list-warnings --- doc/cc65.sgml | 2 ++ src/cc65/error.c | 6 ++++-- src/cc65/error.h | 3 ++- src/cc65/stmt.c | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..240c2bc09 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -555,6 +555,8 @@ Here is a description of all the command line options: Warn when passing structs by value. <tag><tt/unknown-pragma/</tag> Warn about #pragmas that aren't recognized by cc65. + <tag><tt/unreachable-code/</tag> + Warn about unreachable code in cases of comparing constants, etc. <tag><tt/unused-label/</tag> Warn about unused labels. <tag><tt/unused-param/</tag> diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..0118d50b8 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,13 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +93,13 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..31c46f513 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,13 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ /* Forward */ struct StrBuf; diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ 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) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } From 6bb1b6953f77bcf07e337ccd988b562a9cd611f3 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 17 Apr 2021 01:59:09 -0400 Subject: [PATCH 1976/2161] Documented the options to control cc65's warnings about induced pointer type changes. --- doc/cc65.sgml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 240c2bc09..dc754cb31 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. <tag><tt/no-effect/</tag> Warn about statements that don't have an effect. + <tag><tt/pointer-sign/</tag> + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + <tag><tt/pointer-types/</tag> + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. <tag><tt/remap-zero/</tag> Warn about a <tt/<ref id="pragma-charmap" name="#pragma charmap()">/ that changes a character's code number from/to 0x00. From 6e61093e7934098959e846758c0bec132fbe8d10 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 15 Apr 2021 21:38:30 +0800 Subject: [PATCH 1977/2161] Fixed pointer subtraction in certain very rare cases. --- src/cc65/expr.c | 50 ++++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 74524c47a..b0ebbf191 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3250,6 +3250,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3266,24 +3280,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3338,10 +3342,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3383,7 +3384,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3391,6 +3392,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3402,10 +3404,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3422,7 +3421,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3430,6 +3429,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3449,9 +3449,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); From ffc30c0c6ea220d8adaedcdcc9517436fdb98f86 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 18 Apr 2021 01:39:44 -0400 Subject: [PATCH 1978/2161] Added RAM_BANK and ROM_BANK macro definitions to cx16.h header. --- include/cx16.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) From c915b5d7f3bc5bc66e481001de240aae408acd6d Mon Sep 17 00:00:00 2001 From: Marco Aurelio da Costa <costa@gamic.com> Date: Fri, 16 Apr 2021 14:42:16 -0300 Subject: [PATCH 1979/2161] Implemented charmap stack New commands: .PUSHCHARMAP: will push the current charmap state into an internal stack .POPCHARMAP: will restore the current charmap to the last pushed charmap Details: The push and pop facilities are implemented directly inside the tgttrans.h, to facilitate its reuse on the C compiler. --- src/ca65/pseudo.c | 28 ++++++++++++++++++++++ src/ca65/scanner.c | 2 ++ src/ca65/token.h | 2 ++ src/common/tgttrans.c | 56 +++++++++++++++++++++++++++++++++++++++++++ src/common/tgttrans.h | 13 ++++++++++ 5 files changed, 101 insertions(+) diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..df0482a5a 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1568,6 +1568,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1670,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -2101,10 +2124,12 @@ static CtrlDesc CtrlCmdTab [] = { { 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 */ @@ -2183,4 +2208,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..0452bb368 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -260,10 +260,12 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..a94254bfd 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -231,10 +231,12 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..af5bdf725 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -76,6 +81,8 @@ static unsigned char Tab[256] = { + + void TgtTranslateInit (void) /* Initialize the translation tables */ { @@ -127,3 +134,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ From 83ee928fb155c53d32ac532d959d6e17bbfb945b Mon Sep 17 00:00:00 2001 From: Marco Aurelio da Costa <costa@gamic.com> Date: Sun, 18 Apr 2021 12:52:26 -0300 Subject: [PATCH 1980/2161] mc: Formatting, remove stray lines --- src/common/tgttrans.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index af5bdf725..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -81,8 +81,6 @@ static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; - - void TgtTranslateInit (void) /* Initialize the translation tables */ { From 1993d5c091d85af22fe5c7fd5ac13599ce1cd90b Mon Sep 17 00:00:00 2001 From: Marco Aurelio da Costa <costa@gamic.com> Date: Sun, 18 Apr 2021 14:18:39 -0300 Subject: [PATCH 1981/2161] mc: Documentation for .PUSHCHARMAP/.POPCHARMAP --- doc/ca65.sgml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index cebdca12e..ebd6c7135 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -3601,6 +3601,21 @@ Here's a list of all control commands and a description, what they do: 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. + + This command will switch back to the character mapping that was last pushed onto the + character mapping stack using the <tt><ref id=".PUSHCHARMAP" name=".PUSHCHARMAP"></tt> + command, and remove this entry from the stack. + + The assembler will print an error message if the mappting stack is empty when + this command is issued. + + See: <tt><ref id=".CHARMAP" name=".CHARMAP"></tt>, <tt><ref id=".PUSHCHARMAP" + name=".PUSHCHARMAP"></tt> + + <sect1><tt>.POPCPU</tt><label id=".POPCPU"><p> Pop the last CPU setting from the stack, and activate it. @@ -3675,6 +3690,22 @@ Here's a list of all control commands and a description, what they do: <tt><ref id=".P4510" name=".P4510"></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 + entries. + + <tt/.PUSHCHARMAP/ allows together with <tt><ref id=".POPCHARMAP" + name=".POPCHARMAP"></tt> to switch to another character mapping and to restore the old + characther mapping later, without knowledge of the current mapping. + + The assembler will print an error message if the character mapping stack is already full, + when this command is issued. + + See: <tt><ref id=".CHARMAP" name=".CHARMAP"></tt>, <tt><ref id=".POPCHARMAP" + name=".POPCHARMAP"></tt> + + <sect1><tt>.PUSHCPU</tt><label id=".PUSHCPU"><p> Push the currently active CPU onto a stack. The stack has a size of 8 From f7613b529c389808ffc49f77ccb21630d4912072 Mon Sep 17 00:00:00 2001 From: Marco Aurelio da Costa <costa@gamic.com> Date: Sun, 18 Apr 2021 15:16:24 -0300 Subject: [PATCH 1982/2161] mc: Added default charmap include files for assembler --- asminc/ascii_charmap.inc | 291 +++++++++++++++++++++++++++++ asminc/atari_atascii_charmap.inc | 303 ++++++++++++++++++++++++++++++ asminc/atari_screen_charmap.inc | 305 ++++++++++++++++++++++++++++++ asminc/cbm_petscii_charmap.inc | 293 +++++++++++++++++++++++++++++ asminc/cbm_screen_charmap.inc | 307 +++++++++++++++++++++++++++++++ 5 files changed, 1499 insertions(+) create mode 100644 asminc/ascii_charmap.inc create mode 100644 asminc/atari_atascii_charmap.inc create mode 100644 asminc/atari_screen_charmap.inc create mode 100644 asminc/cbm_petscii_charmap.inc create mode 100644 asminc/cbm_screen_charmap.inc diff --git a/asminc/ascii_charmap.inc b/asminc/ascii_charmap.inc new file mode 100644 index 000000000..57728b0d4 --- /dev/null +++ b/asminc/ascii_charmap.inc @@ -0,0 +1,291 @@ +;/*****************************************************************************/ +;/* */ +;/* ascii_charmap.inc */ +;/* */ +;/* No translations, encodings are stored as they were typed in the host. */ +;/* */ +;/* */ +;/* 2019-09-07, Greg King */ +;/* */ +;/* 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 must not be removed or altered from any source */ +;/* distribution. */ +;/* */ +;/*****************************************************************************/ + +;/* No include guard here. Each charmap header +;** may be included many times in a source file. +;*/ + +;/* ASCII */ +.charmap $00, $00 +.charmap $01, $01 +.charmap $02, $02 +.charmap $03, $03 +.charmap $04, $04 +.charmap $05, $05 +.charmap $06, $06 +.charmap $07, $07 +.charmap $08, $08 +.charmap $09, $09 +.charmap $0A, $0A +.charmap $0B, $0B +.charmap $0C, $0C +.charmap $0D, $0D +.charmap $0E, $0E +.charmap $0F, $0F +.charmap $10, $10 +.charmap $11, $11 +.charmap $12, $12 +.charmap $13, $13 +.charmap $14, $14 +.charmap $15, $15 +.charmap $16, $16 +.charmap $17, $17 +.charmap $18, $18 +.charmap $19, $19 +.charmap $1A, $1A +.charmap $1B, $1B +.charmap $1C, $1C +.charmap $1D, $1D +.charmap $1E, $1E +.charmap $1F, $1F +.charmap $20, $20 +.charmap $21, $21 +.charmap $22, $22 +.charmap $23, $23 +.charmap $24, $24 +.charmap $25, $25 +.charmap $26, $26 +.charmap $27, $27 +.charmap $28, $28 +.charmap $29, $29 +.charmap $2A, $2A +.charmap $2B, $2B +.charmap $2C, $2C +.charmap $2D, $2D +.charmap $2E, $2E +.charmap $2F, $2F +.charmap $30, $30 +.charmap $31, $31 +.charmap $32, $32 +.charmap $33, $33 +.charmap $34, $34 +.charmap $35, $35 +.charmap $36, $36 +.charmap $37, $37 +.charmap $38, $38 +.charmap $39, $39 +.charmap $3A, $3A +.charmap $3B, $3B +.charmap $3C, $3C +.charmap $3D, $3D +.charmap $3E, $3E +.charmap $3F, $3F +.charmap $40, $40 +.charmap $41, $41 +.charmap $42, $42 +.charmap $43, $43 +.charmap $44, $44 +.charmap $45, $45 +.charmap $46, $46 +.charmap $47, $47 +.charmap $48, $48 +.charmap $49, $49 +.charmap $4A, $4A +.charmap $4B, $4B +.charmap $4C, $4C +.charmap $4D, $4D +.charmap $4E, $4E +.charmap $4F, $4F +.charmap $50, $50 +.charmap $51, $51 +.charmap $52, $52 +.charmap $53, $53 +.charmap $54, $54 +.charmap $55, $55 +.charmap $56, $56 +.charmap $57, $57 +.charmap $58, $58 +.charmap $59, $59 +.charmap $5A, $5A +.charmap $5B, $5B +.charmap $5C, $5C +.charmap $5D, $5D +.charmap $5E, $5E +.charmap $5F, $5F +.charmap $60, $60 +.charmap $61, $61 +.charmap $62, $62 +.charmap $63, $63 +.charmap $64, $64 +.charmap $65, $65 +.charmap $66, $66 +.charmap $67, $67 +.charmap $68, $68 +.charmap $69, $69 +.charmap $6A, $6A +.charmap $6B, $6B +.charmap $6C, $6C +.charmap $6D, $6D +.charmap $6E, $6E +.charmap $6F, $6F +.charmap $70, $70 +.charmap $71, $71 +.charmap $72, $72 +.charmap $73, $73 +.charmap $74, $74 +.charmap $75, $75 +.charmap $76, $76 +.charmap $77, $77 +.charmap $78, $78 +.charmap $79, $79 +.charmap $7A, $7A +.charmap $7B, $7B +.charmap $7C, $7C +.charmap $7D, $7D +.charmap $7E, $7E +.charmap $7F, $7F + +;/* beyond ASCII */ +.charmap $80, $80 +.charmap $81, $81 +.charmap $82, $82 +.charmap $83, $83 +.charmap $84, $84 +.charmap $85, $85 +.charmap $86, $86 +.charmap $87, $87 +.charmap $88, $88 +.charmap $89, $89 +.charmap $8A, $8A +.charmap $8B, $8B +.charmap $8C, $8C +.charmap $8D, $8D +.charmap $8E, $8E +.charmap $8F, $8F +.charmap $90, $90 +.charmap $91, $91 +.charmap $92, $92 +.charmap $93, $93 +.charmap $94, $94 +.charmap $95, $95 +.charmap $96, $96 +.charmap $97, $97 +.charmap $98, $98 +.charmap $99, $99 +.charmap $9A, $9A +.charmap $9B, $9B +.charmap $9C, $9C +.charmap $9D, $9D +.charmap $9E, $9E +.charmap $9F, $9F +.charmap $A0, $A0 +.charmap $A1, $A1 +.charmap $A2, $A2 +.charmap $A3, $A3 +.charmap $A4, $A4 +.charmap $A5, $A5 +.charmap $A6, $A6 +.charmap $A7, $A7 +.charmap $A8, $A8 +.charmap $A9, $A9 +.charmap $AA, $AA +.charmap $AB, $AB +.charmap $AC, $AC +.charmap $AD, $AD +.charmap $AE, $AE +.charmap $AF, $AF +.charmap $B0, $B0 +.charmap $B1, $B1 +.charmap $B2, $B2 +.charmap $B3, $B3 +.charmap $B4, $B4 +.charmap $B5, $B5 +.charmap $B6, $B6 +.charmap $B7, $B7 +.charmap $B8, $B8 +.charmap $B9, $B9 +.charmap $BA, $BA +.charmap $BB, $BB +.charmap $BC, $BC +.charmap $BD, $BD +.charmap $BE, $BE +.charmap $BF, $BF +.charmap $C0, $C0 +.charmap $C1, $C1 +.charmap $C2, $C2 +.charmap $C3, $C3 +.charmap $C4, $C4 +.charmap $C5, $C5 +.charmap $C6, $C6 +.charmap $C7, $C7 +.charmap $C8, $C8 +.charmap $C9, $C9 +.charmap $CA, $CA +.charmap $CB, $CB +.charmap $CC, $CC +.charmap $CD, $CD +.charmap $CE, $CE +.charmap $CF, $CF +.charmap $D0, $D0 +.charmap $D1, $D1 +.charmap $D2, $D2 +.charmap $D3, $D3 +.charmap $D4, $D4 +.charmap $D5, $D5 +.charmap $D6, $D6 +.charmap $D7, $D7 +.charmap $D8, $D8 +.charmap $D9, $D9 +.charmap $DA, $DA +.charmap $DB, $DB +.charmap $DC, $DC +.charmap $DD, $DD +.charmap $DE, $DE +.charmap $DF, $DF +.charmap $E0, $E0 +.charmap $E1, $E1 +.charmap $E2, $E2 +.charmap $E3, $E3 +.charmap $E4, $E4 +.charmap $E5, $E5 +.charmap $E6, $E6 +.charmap $E7, $E7 +.charmap $E8, $E8 +.charmap $E9, $E9 +.charmap $EA, $EA +.charmap $EB, $EB +.charmap $EC, $EC +.charmap $ED, $ED +.charmap $EE, $EE +.charmap $EF, $EF +.charmap $F0, $F0 +.charmap $F1, $F1 +.charmap $F2, $F2 +.charmap $F3, $F3 +.charmap $F4, $F4 +.charmap $F5, $F5 +.charmap $F6, $F6 +.charmap $F7, $F7 +.charmap $F8, $F8 +.charmap $F9, $F9 +.charmap $FA, $FA +.charmap $FB, $FB +.charmap $FC, $FC +.charmap $FD, $FD +.charmap $FE, $FE +.charmap $FF, $FF diff --git a/asminc/atari_atascii_charmap.inc b/asminc/atari_atascii_charmap.inc new file mode 100644 index 000000000..8c3222dd6 --- /dev/null +++ b/asminc/atari_atascii_charmap.inc @@ -0,0 +1,303 @@ +;/*****************************************************************************/ +;/* */ +;/* atari_atascii_charmap.inc */ +;/* */ +;/* Atari system standard string mapping ISO-8859-1 -> AtASCII */ +;/* */ +;/* */ +;/* */ +;/* C 2016 Christian Krueger */ +;/* */ +;/* */ +;/* 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. */ +;/* */ +;/*****************************************************************************/ + +;/* No include guard here! Multiple use in one file may be intentional. */ + +.charmap $00, $00 +.charmap $01, $01 +.charmap $02, $02 +.charmap $03, $03 +.charmap $04, $04 +.charmap $05, $05 +.charmap $06, $06 +.charmap $07, $FD +.charmap $08, $08 +.charmap $09, $7F +.charmap $0A, $9B +.charmap $0B, $0B +.charmap $0C, $7D +.charmap $0D, $0D +.charmap $0E, $0E +.charmap $0F, $0F + +.charmap $10, $10 +.charmap $11, $11 +.charmap $12, $12 +.charmap $13, $13 +.charmap $14, $14 +.charmap $15, $15 +.charmap $16, $16 +.charmap $17, $17 +.charmap $18, $18 +.charmap $19, $19 +.charmap $1A, $1A +.charmap $1B, $1B +.charmap $1C, $1C +.charmap $1D, $1D +.charmap $1E, $1E +.charmap $1F, $1F + +.charmap $20, $20 +.charmap $21, $21 +.charmap $22, $22 +.charmap $23, $23 +.charmap $24, $24 +.charmap $25, $25 +.charmap $26, $26 +.charmap $27, $27 +.charmap $28, $28 +.charmap $29, $29 +.charmap $2A, $2A +.charmap $2B, $2B +.charmap $2C, $2C +.charmap $2D, $2D +.charmap $2E, $2E +.charmap $2F, $2F + +.charmap $30, $30 +.charmap $31, $31 +.charmap $32, $32 +.charmap $33, $33 +.charmap $34, $34 +.charmap $35, $35 +.charmap $36, $36 +.charmap $37, $37 +.charmap $38, $38 +.charmap $39, $39 +.charmap $3A, $3A +.charmap $3B, $3B +.charmap $3C, $3C +.charmap $3D, $3D +.charmap $3E, $3E +.charmap $3F, $3F + +.charmap $40, $40 +.charmap $41, $41 +.charmap $42, $42 +.charmap $43, $43 +.charmap $44, $44 +.charmap $45, $45 +.charmap $46, $46 +.charmap $47, $47 +.charmap $48, $48 +.charmap $49, $49 +.charmap $4A, $4A +.charmap $4B, $4B +.charmap $4C, $4C +.charmap $4D, $4D +.charmap $4E, $4E +.charmap $4F, $4F + +.charmap $50, $50 +.charmap $51, $51 +.charmap $52, $52 +.charmap $53, $53 +.charmap $54, $54 +.charmap $55, $55 +.charmap $56, $56 +.charmap $57, $57 +.charmap $58, $58 +.charmap $59, $59 +.charmap $5A, $5A +.charmap $5B, $5B +.charmap $5C, $5C +.charmap $5D, $5D +.charmap $5E, $5E +.charmap $5F, $5F + +.charmap $60, $60 +.charmap $61, $61 +.charmap $62, $62 +.charmap $63, $63 +.charmap $64, $64 +.charmap $65, $65 +.charmap $66, $66 +.charmap $67, $67 +.charmap $68, $68 +.charmap $69, $69 +.charmap $6A, $6A +.charmap $6B, $6B +.charmap $6C, $6C +.charmap $6D, $6D +.charmap $6E, $6E +.charmap $6F, $6F + +.charmap $70, $70 +.charmap $71, $71 +.charmap $72, $72 +.charmap $73, $73 +.charmap $74, $74 +.charmap $75, $75 +.charmap $76, $76 +.charmap $77, $77 +.charmap $78, $78 +.charmap $79, $79 +.charmap $7A, $7A +.charmap $7B, $7B +.charmap $7C, $7C +.charmap $7D, $7D +.charmap $7E, $7E +.charmap $7F, $7F + +.charmap $80, $80 +.charmap $81, $81 +.charmap $82, $82 +.charmap $83, $83 +.charmap $84, $84 +.charmap $85, $85 +.charmap $86, $86 +.charmap $87, $87 +.charmap $88, $88 +.charmap $89, $89 +.charmap $8A, $8A +.charmap $8B, $8B +.charmap $8C, $8C +.charmap $8D, $8D +.charmap $8E, $8E +.charmap $8F, $8F + +.charmap $90, $90 +.charmap $91, $91 +.charmap $92, $92 +.charmap $93, $93 +.charmap $94, $94 +.charmap $95, $95 +.charmap $96, $96 +.charmap $97, $97 +.charmap $98, $98 +.charmap $99, $99 +.charmap $9A, $9A +.charmap $9B, $9B +.charmap $9C, $9C +.charmap $9D, $9D +.charmap $9E, $9E +.charmap $9F, $9F + +.charmap $A0, $A0 +.charmap $A1, $A1 +.charmap $A2, $A2 +.charmap $A3, $A3 +.charmap $A4, $A4 +.charmap $A5, $A5 +.charmap $A6, $A6 +.charmap $A7, $A7 +.charmap $A8, $A8 +.charmap $A9, $A9 +.charmap $AA, $AA +.charmap $AB, $AB +.charmap $AC, $AC +.charmap $AD, $AD +.charmap $AE, $AE +.charmap $AF, $AF + +.charmap $B0, $B0 +.charmap $B1, $B1 +.charmap $B2, $B2 +.charmap $B3, $B3 +.charmap $B4, $B4 +.charmap $B5, $B5 +.charmap $B6, $B6 +.charmap $B7, $B7 +.charmap $B8, $B8 +.charmap $B9, $B9 +.charmap $BA, $BA +.charmap $BB, $BB +.charmap $BC, $BC +.charmap $BD, $BD +.charmap $BE, $BE +.charmap $BF, $BF + +.charmap $C0, $C0 +.charmap $C1, $C1 +.charmap $C2, $C2 +.charmap $C3, $C3 +.charmap $C4, $C4 +.charmap $C5, $C5 +.charmap $C6, $C6 +.charmap $C7, $C7 +.charmap $C8, $C8 +.charmap $C9, $C9 +.charmap $CA, $CA +.charmap $CB, $CB +.charmap $CC, $CC +.charmap $CD, $CD +.charmap $CE, $CE +.charmap $CF, $CF + +.charmap $D0, $D0 +.charmap $D1, $D1 +.charmap $D2, $D2 +.charmap $D3, $D3 +.charmap $D4, $D4 +.charmap $D5, $D5 +.charmap $D6, $D6 +.charmap $D7, $D7 +.charmap $D8, $D8 +.charmap $D9, $D9 +.charmap $DA, $DA +.charmap $DB, $DB +.charmap $DC, $DC +.charmap $DD, $DD +.charmap $DE, $DE +.charmap $DF, $DF + +.charmap $E0, $E0 +.charmap $E1, $E1 +.charmap $E2, $E2 +.charmap $E3, $E3 +.charmap $E4, $E4 +.charmap $E5, $E5 +.charmap $E6, $E6 +.charmap $E7, $E7 +.charmap $E8, $E8 +.charmap $E9, $E9 +.charmap $EA, $EA +.charmap $EB, $EB +.charmap $EC, $EC +.charmap $ED, $ED +.charmap $EE, $EE +.charmap $EF, $EF + +.charmap $F0, $F0 +.charmap $F1, $F1 +.charmap $F2, $F2 +.charmap $F3, $F3 +.charmap $F4, $F4 +.charmap $F5, $F5 +.charmap $F6, $F6 +.charmap $F7, $F7 +.charmap $F8, $F8 +.charmap $F9, $F9 +.charmap $FA, $FA +.charmap $FB, $FB +.charmap $FC, $FC +.charmap $FD, $FD +.charmap $FE, $FE +.charmap $FF, $FF diff --git a/asminc/atari_screen_charmap.inc b/asminc/atari_screen_charmap.inc new file mode 100644 index 000000000..ca4f9e1d7 --- /dev/null +++ b/asminc/atari_screen_charmap.inc @@ -0,0 +1,305 @@ +;/*****************************************************************************/ +;/* */ +;/* atari_screen_charmap.inc */ +;/* */ +;/* Atari system internal string mapping ISO-8859-1 -> Internal/Screen-Code */ +;/* */ +;/* */ +;/* */ +;/* C 2016 Christian Krueger */ +;/* */ +;/* */ +;/* 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. */ +;/* */ +;/*****************************************************************************/ + +;/* No include guard here! Multiple use in one file may be intentional. */ + +.charmap $00, $40 +.charmap $01, $41 +.charmap $02, $42 +.charmap $03, $43 +.charmap $04, $44 +.charmap $05, $45 +.charmap $06, $46 +.charmap $07, $FD +.charmap $08, $48 +.charmap $09, $7F +.charmap $0A, $DB +.charmap $0B, $4B +.charmap $0C, $7D +.charmap $0D, $4D +.charmap $0E, $4E +.charmap $0F, $4F + +.charmap $10, $50 +.charmap $11, $51 +.charmap $12, $52 +.charmap $13, $53 +.charmap $14, $54 +.charmap $15, $55 +.charmap $16, $56 +.charmap $17, $57 +.charmap $18, $58 +.charmap $19, $59 +.charmap $1A, $5A +.charmap $1B, $5B +.charmap $1C, $5C +.charmap $1D, $5D +.charmap $1E, $5E +.charmap $1F, $5F + +.charmap $20, $00 + +.charmap $21, $01 +.charmap $22, $02 +.charmap $23, $03 +.charmap $24, $04 +.charmap $25, $05 +.charmap $26, $06 +.charmap $27, $07 +.charmap $28, $08 +.charmap $29, $09 +.charmap $2A, $0A +.charmap $2B, $0B +.charmap $2C, $0C +.charmap $2D, $0D +.charmap $2E, $0E +.charmap $2F, $0F + +.charmap $30, $10 +.charmap $31, $11 +.charmap $32, $12 +.charmap $33, $13 +.charmap $34, $14 +.charmap $35, $15 +.charmap $36, $16 +.charmap $37, $17 +.charmap $38, $18 +.charmap $39, $19 +.charmap $3A, $1A +.charmap $3B, $1B +.charmap $3C, $1C +.charmap $3D, $1D +.charmap $3E, $1E +.charmap $3F, $1F + +.charmap $40, $20 +.charmap $41, $21 +.charmap $42, $22 +.charmap $43, $23 +.charmap $44, $24 +.charmap $45, $25 +.charmap $46, $26 +.charmap $47, $27 +.charmap $48, $28 +.charmap $49, $29 +.charmap $4A, $2A +.charmap $4B, $2B +.charmap $4C, $2C +.charmap $4D, $2D +.charmap $4E, $2E +.charmap $4F, $2F + +.charmap $50, $30 +.charmap $51, $31 +.charmap $52, $32 +.charmap $53, $33 +.charmap $54, $34 +.charmap $55, $35 +.charmap $56, $36 +.charmap $57, $37 +.charmap $58, $38 +.charmap $59, $39 +.charmap $5A, $3A +.charmap $5B, $3B +.charmap $5C, $3C +.charmap $5D, $3D +.charmap $5E, $3E +.charmap $5F, $3F + +.charmap $60, $60 +.charmap $61, $61 +.charmap $62, $62 +.charmap $63, $63 +.charmap $64, $64 +.charmap $65, $65 +.charmap $66, $66 +.charmap $67, $67 +.charmap $68, $68 +.charmap $69, $69 +.charmap $6A, $6A +.charmap $6B, $6B +.charmap $6C, $6C +.charmap $6D, $6D +.charmap $6E, $6E +.charmap $6F, $6F + +.charmap $70, $70 +.charmap $71, $71 +.charmap $72, $72 +.charmap $73, $73 +.charmap $74, $74 +.charmap $75, $75 +.charmap $76, $76 +.charmap $77, $77 +.charmap $78, $78 +.charmap $79, $79 +.charmap $7A, $7A +.charmap $7B, $7B +.charmap $7C, $7C +.charmap $7D, $7D +.charmap $7E, $7E +.charmap $7F, $7F + +.charmap $80, $C0 +.charmap $81, $C1 +.charmap $82, $C2 +.charmap $83, $C3 +.charmap $84, $C4 +.charmap $85, $C5 +.charmap $86, $C6 +.charmap $87, $C7 +.charmap $88, $C8 +.charmap $89, $C9 +.charmap $8A, $CA +.charmap $8B, $CB +.charmap $8C, $CC +.charmap $8D, $CD +.charmap $8E, $CE +.charmap $8F, $CF + +.charmap $90, $D0 +.charmap $91, $D1 +.charmap $92, $D2 +.charmap $93, $D3 +.charmap $94, $D4 +.charmap $95, $D5 +.charmap $96, $D6 +.charmap $97, $D7 +.charmap $98, $D8 +.charmap $99, $D9 +.charmap $9A, $DA +.charmap $9B, $DB +.charmap $9C, $DC +.charmap $9D, $DD +.charmap $9E, $DE +.charmap $9F, $DF + +.charmap $A0, $80 +.charmap $A1, $81 +.charmap $A2, $82 +.charmap $A3, $83 +.charmap $A4, $84 +.charmap $A5, $85 +.charmap $A6, $86 +.charmap $A7, $87 +.charmap $A8, $88 +.charmap $A9, $89 +.charmap $AA, $8A +.charmap $AB, $8B +.charmap $AC, $8C +.charmap $AD, $8D +.charmap $AE, $8E +.charmap $AF, $8F + +.charmap $B0, $90 +.charmap $B1, $91 +.charmap $B2, $92 +.charmap $B3, $93 +.charmap $B4, $94 +.charmap $B5, $95 +.charmap $B6, $96 +.charmap $B7, $97 +.charmap $B8, $98 +.charmap $B9, $99 +.charmap $BA, $9A +.charmap $BB, $9B +.charmap $BC, $9C +.charmap $BD, $9D +.charmap $BE, $9E +.charmap $BF, $9F + +.charmap $C0, $A0 +.charmap $C1, $A1 +.charmap $C2, $A2 +.charmap $C3, $A3 +.charmap $C4, $A4 +.charmap $C5, $A5 +.charmap $C6, $A6 +.charmap $C7, $A7 +.charmap $C8, $A8 +.charmap $C9, $A9 +.charmap $CA, $AA +.charmap $CB, $AB +.charmap $CC, $AC +.charmap $CD, $AD +.charmap $CE, $AE +.charmap $CF, $AF + +.charmap $D0, $B0 +.charmap $D1, $B1 +.charmap $D2, $B2 +.charmap $D3, $B3 +.charmap $D4, $B4 +.charmap $D5, $B5 +.charmap $D6, $B6 +.charmap $D7, $B7 +.charmap $D8, $B8 +.charmap $D9, $B9 +.charmap $DA, $BA +.charmap $DB, $BB +.charmap $DC, $BC +.charmap $DD, $BD +.charmap $DE, $BE +.charmap $DF, $BF + +.charmap $E0, $E0 +.charmap $E1, $E1 +.charmap $E2, $E2 +.charmap $E3, $E3 +.charmap $E4, $E4 +.charmap $E5, $E5 +.charmap $E6, $E6 +.charmap $E7, $E7 +.charmap $E8, $E8 +.charmap $E9, $E9 +.charmap $EA, $EA +.charmap $EB, $EB +.charmap $EC, $EC +.charmap $ED, $ED +.charmap $EE, $EE +.charmap $EF, $EF + +.charmap $F0, $F0 +.charmap $F1, $F1 +.charmap $F2, $F2 +.charmap $F3, $F3 +.charmap $F4, $F4 +.charmap $F5, $F5 +.charmap $F6, $F6 +.charmap $F7, $F7 +.charmap $F8, $F8 +.charmap $F9, $F9 +.charmap $FA, $FA +.charmap $FB, $FB +.charmap $FC, $FC +.charmap $FD, $FD +.charmap $FE, $FE +.charmap $FF, $FF + diff --git a/asminc/cbm_petscii_charmap.inc b/asminc/cbm_petscii_charmap.inc new file mode 100644 index 000000000..15fde0d8c --- /dev/null +++ b/asminc/cbm_petscii_charmap.inc @@ -0,0 +1,293 @@ +;/*****************************************************************************/ +;/* */ +;/* cbm_petscii_charmap.inc */ +;/* */ +;/* CBM system standard string mapping ISO-8859-1 -> PetSCII */ +;/* */ +;/* */ +;/* 2019-03-10, Greg King */ +;/* */ +;/* 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 must not be removed or altered from any source */ +;/* distribution. */ +;/* */ +;/*****************************************************************************/ + +;/* No include guard here! Multiple use in one file might be intentional. */ + +.charmap $00, $00 +.charmap $01, $01 +.charmap $02, $02 +.charmap $03, $03 +.charmap $04, $04 +.charmap $05, $05 +.charmap $06, $06 +.charmap $07, $07 +.charmap $08, $14 +.charmap $09, $09 +.charmap $0A, $0D +.charmap $0B, $11 +.charmap $0C, $93 +.charmap $0D, $0A +.charmap $0E, $0E +.charmap $0F, $0F +.charmap $10, $10 +.charmap $11, $0B +.charmap $12, $12 +.charmap $13, $13 +.charmap $14, $08 +.charmap $15, $15 +.charmap $16, $16 +.charmap $17, $17 +.charmap $18, $18 +.charmap $19, $19 +.charmap $1A, $1A +.charmap $1B, $1B +.charmap $1C, $1C +.charmap $1D, $1D +.charmap $1E, $1E +.charmap $1F, $1F + +.charmap $20, $20 +.charmap $21, $21 +.charmap $22, $22 +.charmap $23, $23 +.charmap $24, $24 +.charmap $25, $25 +.charmap $26, $26 +.charmap $27, $27 +.charmap $28, $28 +.charmap $29, $29 +.charmap $2A, $2A +.charmap $2B, $2B +.charmap $2C, $2C +.charmap $2D, $2D +.charmap $2E, $2E +.charmap $2F, $2F +.charmap $30, $30 +.charmap $31, $31 +.charmap $32, $32 +.charmap $33, $33 +.charmap $34, $34 +.charmap $35, $35 +.charmap $36, $36 +.charmap $37, $37 +.charmap $38, $38 +.charmap $39, $39 +.charmap $3A, $3A +.charmap $3B, $3B +.charmap $3C, $3C +.charmap $3D, $3D +.charmap $3E, $3E +.charmap $3F, $3F + +.charmap $40, $40 +.charmap $41, $C1 +.charmap $42, $C2 +.charmap $43, $C3 +.charmap $44, $C4 +.charmap $45, $C5 +.charmap $46, $C6 +.charmap $47, $C7 +.charmap $48, $C8 +.charmap $49, $C9 +.charmap $4A, $CA +.charmap $4B, $CB +.charmap $4C, $CC +.charmap $4D, $CD +.charmap $4E, $CE +.charmap $4F, $CF +.charmap $50, $D0 +.charmap $51, $D1 +.charmap $52, $D2 +.charmap $53, $D3 +.charmap $54, $D4 +.charmap $55, $D5 +.charmap $56, $D6 +.charmap $57, $D7 +.charmap $58, $D8 +.charmap $59, $D9 +.charmap $5A, $DA +.charmap $5B, $5B +.charmap $5C, $BF +.charmap $5D, $5D +.charmap $5E, $5E +.charmap $5F, $A4 + +.charmap $60, $AD +.charmap $61, $41 +.charmap $62, $42 +.charmap $63, $43 +.charmap $64, $44 +.charmap $65, $45 +.charmap $66, $46 +.charmap $67, $47 +.charmap $68, $48 +.charmap $69, $49 +.charmap $6A, $4A +.charmap $6B, $4B +.charmap $6C, $4C +.charmap $6D, $4D +.charmap $6E, $4E +.charmap $6F, $4F +.charmap $70, $50 +.charmap $71, $51 +.charmap $72, $52 +.charmap $73, $53 +.charmap $74, $54 +.charmap $75, $55 +.charmap $76, $56 +.charmap $77, $57 +.charmap $78, $58 +.charmap $79, $59 +.charmap $7A, $5A +.charmap $7B, $B3 +.charmap $7C, $DD +.charmap $7D, $AB +.charmap $7E, $B1 +.charmap $7F, $DF + +.charmap $80, $80 +.charmap $81, $81 +.charmap $82, $82 +.charmap $83, $83 +.charmap $84, $84 +.charmap $85, $85 +.charmap $86, $86 +.charmap $87, $87 +.charmap $88, $88 +.charmap $89, $89 +.charmap $8A, $8A +.charmap $8B, $8B +.charmap $8C, $8C +.charmap $8D, $8D +.charmap $8E, $8E +.charmap $8F, $8F +.charmap $90, $90 +.charmap $91, $91 +.charmap $92, $92 +.charmap $93, $0C +.charmap $94, $94 +.charmap $95, $95 +.charmap $96, $96 +.charmap $97, $97 +.charmap $98, $98 +.charmap $99, $99 +.charmap $9A, $9A +.charmap $9B, $9B +.charmap $9C, $9C +.charmap $9D, $9D +.charmap $9E, $9E +.charmap $9F, $9F + +.charmap $A0, $A0 +.charmap $A1, $A1 +.charmap $A2, $A2 +.charmap $A3, $A3 +.charmap $A4, $A4 +.charmap $A5, $A5 +.charmap $A6, $A6 +.charmap $A7, $A7 +.charmap $A8, $A8 +.charmap $A9, $A9 +.charmap $AA, $AA +.charmap $AB, $AB +.charmap $AC, $AC +.charmap $AD, $AD +.charmap $AE, $AE +.charmap $AF, $AF +.charmap $B0, $B0 +.charmap $B1, $B1 +.charmap $B2, $B2 +.charmap $B3, $B3 +.charmap $B4, $B4 +.charmap $B5, $B5 +.charmap $B6, $B6 +.charmap $B7, $B7 +.charmap $B8, $B8 +.charmap $B9, $B9 +.charmap $BA, $BA +.charmap $BB, $BB +.charmap $BC, $BC +.charmap $BD, $BD +.charmap $BE, $BE +.charmap $BF, $BF + +.charmap $C0, $60 +.charmap $C1, $61 +.charmap $C2, $62 +.charmap $C3, $63 +.charmap $C4, $64 +.charmap $C5, $65 +.charmap $C6, $66 +.charmap $C7, $67 +.charmap $C8, $68 +.charmap $C9, $69 +.charmap $CA, $6A +.charmap $CB, $6B +.charmap $CC, $6C +.charmap $CD, $6D +.charmap $CE, $6E +.charmap $CF, $6F +.charmap $D0, $70 +.charmap $D1, $71 +.charmap $D2, $72 +.charmap $D3, $73 +.charmap $D4, $74 +.charmap $D5, $75 +.charmap $D6, $76 +.charmap $D7, $77 +.charmap $D8, $78 +.charmap $D9, $79 +.charmap $DA, $7A +.charmap $DB, $7B +.charmap $DC, $7C +.charmap $DD, $7D +.charmap $DE, $7E +.charmap $DF, $7F + +.charmap $E0, $E0 +.charmap $E1, $E1 +.charmap $E2, $E2 +.charmap $E3, $E3 +.charmap $E4, $E4 +.charmap $E5, $E5 +.charmap $E6, $E6 +.charmap $E7, $E7 +.charmap $E8, $E8 +.charmap $E9, $E9 +.charmap $EA, $EA +.charmap $EB, $EB +.charmap $EC, $EC +.charmap $ED, $ED +.charmap $EE, $EE +.charmap $EF, $EF +.charmap $F0, $F0 +.charmap $F1, $F1 +.charmap $F2, $F2 +.charmap $F3, $F3 +.charmap $F4, $F4 +.charmap $F5, $F5 +.charmap $F6, $F6 +.charmap $F7, $F7 +.charmap $F8, $F8 +.charmap $F9, $F9 +.charmap $FA, $FA +.charmap $FB, $FB +.charmap $FC, $FC +.charmap $FD, $FD +.charmap $FE, $FE +.charmap $FF, $FF diff --git a/asminc/cbm_screen_charmap.inc b/asminc/cbm_screen_charmap.inc new file mode 100644 index 000000000..cacce10db --- /dev/null +++ b/asminc/cbm_screen_charmap.inc @@ -0,0 +1,307 @@ +;/*****************************************************************************/ +;/* */ +;/* cbm_screen_charmap.inc */ +;/* */ +;/* c Copyright 2019, Gerhard W. Gruber (sparhawk@gmx.at) */ +;/* */ +;/* When using CBM mode, this include converts character literals */ +;/* from ASCII to screen-code mapping, so you can write directly */ +;/* to the screen memory. */ +;/* */ +;/* If this include is used, no additional macros are needed. */ +;/* */ +;/*****************************************************************************/ + +;/* No include guard here! Multiple use in one file may be intentional. */ + +; Char $00 -> c + 128 +.charmap $00, $80 + +; Char $01 ... $1A -> c + 128 + 64 control alphabet +.charmap $01, $C1 +.charmap $02, $C2 +.charmap $03, $C3 +.charmap $04, $C4 +.charmap $05, $C5 +.charmap $06, $C6 +.charmap $07, $C7 +.charmap $08, $C8 +.charmap $09, $C9 +.charmap $0A, $CA +.charmap $0B, $CB +.charmap $0C, $CC +.charmap $0D, $CD +.charmap $0E, $CE +.charmap $0F, $CF +.charmap $10, $D0 +.charmap $11, $D1 +.charmap $12, $D2 +.charmap $13, $D3 +.charmap $14, $D4 +.charmap $15, $D5 +.charmap $16, $D6 +.charmap $17, $D7 +.charmap $18, $D8 +.charmap $19, $D9 +.charmap $1A, $DA + +; Char $1B ... $1F -> c + 128 +.charmap $1B, $9B +.charmap $1C, $9C +.charmap $1D, $9D +.charmap $1E, $9E +.charmap $1F, $9F + +; Char $20 ... $3F -> c +.charmap $20, $20 +.charmap $21, $21 +.charmap $22, $22 +.charmap $23, $23 +.charmap $24, $24 +.charmap $25, $25 +.charmap $26, $26 +.charmap $27, $27 +.charmap $28, $28 +.charmap $29, $29 +.charmap $2A, $2A +.charmap $2B, $2B +.charmap $2C, $2C +.charmap $2D, $2D +.charmap $2E, $2E +.charmap $2F, $2F +.charmap $30, $30 +.charmap $31, $31 +.charmap $32, $32 +.charmap $33, $33 +.charmap $34, $34 +.charmap $35, $35 +.charmap $36, $36 +.charmap $37, $37 +.charmap $38, $38 +.charmap $39, $39 +.charmap $3A, $3A +.charmap $3B, $3B +.charmap $3C, $3C +.charmap $3D, $3D +.charmap $3E, $3E +.charmap $3F, $3F + +; Char $40 -> c - 64 +.charmap $40, $00 + +; Char $41 ... $5A -> c upper-case alphabet +.charmap $41, $41 +.charmap $42, $42 +.charmap $43, $43 +.charmap $44, $44 +.charmap $45, $45 +.charmap $46, $46 +.charmap $47, $47 +.charmap $48, $48 +.charmap $49, $49 +.charmap $4A, $4A +.charmap $4B, $4B +.charmap $4C, $4C +.charmap $4D, $4D +.charmap $4E, $4E +.charmap $4F, $4F +.charmap $50, $50 +.charmap $51, $51 +.charmap $52, $52 +.charmap $53, $53 +.charmap $54, $54 +.charmap $55, $55 +.charmap $56, $56 +.charmap $57, $57 +.charmap $58, $58 +.charmap $59, $59 +.charmap $5A, $5A + +; Char $5B ... $5F -> c - 64 +.charmap $5B, $1B +.charmap $5C, $1C +.charmap $5D, $1D +.charmap $5E, $1E +.charmap $5F, $1F + +; Char $60 -> c - 32 +.charmap $60, $40 + +; Char $61 ... $7A -> c - 32 - 64 lower-case alphabet +.charmap $61, $01 +.charmap $62, $02 +.charmap $63, $03 +.charmap $64, $04 +.charmap $65, $05 +.charmap $66, $06 +.charmap $67, $07 +.charmap $68, $08 +.charmap $69, $09 +.charmap $6A, $0A +.charmap $6B, $0B +.charmap $6C, $0C +.charmap $6D, $0D +.charmap $6E, $0E +.charmap $6F, $0F +.charmap $70, $10 +.charmap $71, $11 +.charmap $72, $12 +.charmap $73, $13 +.charmap $74, $14 +.charmap $75, $15 +.charmap $76, $16 +.charmap $77, $17 +.charmap $78, $18 +.charmap $79, $19 +.charmap $7A, $1A + +; Char $7B ... $7F -> c - 32 +.charmap $7B, $5B +.charmap $7C, $5C +.charmap $7D, $5D +.charmap $7E, $5E +.charmap $7F, $5F + +; Char $80 -> c + 64 +.charmap $80, $C0 + +; Char $81 ... $9A -> c control alphabet +.charmap $81, $81 +.charmap $82, $82 +.charmap $83, $83 +.charmap $84, $84 +.charmap $85, $85 +.charmap $86, $86 +.charmap $87, $87 +.charmap $88, $88 +.charmap $89, $89 +.charmap $8A, $8A +.charmap $8B, $8B +.charmap $8C, $8C +.charmap $8D, $8D +.charmap $8E, $8E +.charmap $8F, $8F +.charmap $90, $90 +.charmap $91, $91 +.charmap $92, $92 +.charmap $93, $93 +.charmap $94, $94 +.charmap $95, $95 +.charmap $96, $96 +.charmap $97, $97 +.charmap $98, $98 +.charmap $99, $99 +.charmap $9A, $9A + +; Char $9B ... $9F -> c + 64 +.charmap $9B, $DB +.charmap $9C, $DC +.charmap $9D, $DD +.charmap $9E, $DE +.charmap $9F, $DF + +; Char $A0 ... $BF -> c - 64 +.charmap $A0, $60 +.charmap $A1, $61 +.charmap $A2, $62 +.charmap $A3, $63 +.charmap $A4, $64 +.charmap $A5, $65 +.charmap $A6, $66 +.charmap $A7, $67 +.charmap $A8, $68 +.charmap $A9, $69 +.charmap $AA, $6A +.charmap $AB, $6B +.charmap $AC, $6C +.charmap $AD, $6D +.charmap $AE, $6E +.charmap $AF, $6F +.charmap $B0, $70 +.charmap $B1, $71 +.charmap $B2, $72 +.charmap $B3, $73 +.charmap $B4, $74 +.charmap $B5, $75 +.charmap $B6, $76 +.charmap $B7, $77 +.charmap $B8, $78 +.charmap $B9, $79 +.charmap $BA, $7A +.charmap $BB, $7B +.charmap $BC, $7C +.charmap $BD, $7D +.charmap $BE, $7E +.charmap $BF, $7F + +; Char $C0 ... $DF -> c - 128 +.charmap $C0, $40 + +; Char $C1 ... $DA -> c - 128 - 64 lower-case alphabet +.charmap $C1, $01 +.charmap $C2, $02 +.charmap $C3, $03 +.charmap $C4, $04 +.charmap $C5, $05 +.charmap $C6, $06 +.charmap $C7, $07 +.charmap $C8, $08 +.charmap $C9, $09 +.charmap $CA, $0A +.charmap $CB, $0B +.charmap $CC, $0C +.charmap $CD, $0D +.charmap $CE, $0E +.charmap $CF, $0F +.charmap $D0, $10 +.charmap $D1, $11 +.charmap $D2, $12 +.charmap $D3, $13 +.charmap $D4, $14 +.charmap $D5, $15 +.charmap $D6, $16 +.charmap $D7, $17 +.charmap $D8, $18 +.charmap $D9, $19 +.charmap $DA, $1A + +; Char $DB ... $DF -> c - 128 +.charmap $DB, $5B +.charmap $DC, $5C +.charmap $DD, $5D +.charmap $DE, $5E +.charmap $DF, $5F + +; Char $E0 ... $FF -> c - 128 +.charmap $E0, $60 +.charmap $E1, $61 +.charmap $E2, $62 +.charmap $E3, $63 +.charmap $E4, $64 +.charmap $E5, $65 +.charmap $E6, $66 +.charmap $E7, $67 +.charmap $E8, $68 +.charmap $E9, $69 +.charmap $EA, $6A +.charmap $EB, $6B +.charmap $EC, $6C +.charmap $ED, $6D +.charmap $EE, $6E +.charmap $EF, $6F +.charmap $F0, $70 +.charmap $F1, $71 +.charmap $F2, $72 +.charmap $F3, $73 +.charmap $F4, $74 +.charmap $F5, $75 +.charmap $F6, $76 +.charmap $F7, $77 +.charmap $F8, $78 +.charmap $F9, $79 +.charmap $FA, $7A +.charmap $FB, $7B +.charmap $FC, $7C +.charmap $FD, $7D +.charmap $FE, $7E +.charmap $FF, $7F From 9941855dc612ca60f7bbdf31a460f4a7df173cd2 Mon Sep 17 00:00:00 2001 From: Marco Aurelio da Costa <costa@gamic.com> Date: Sun, 18 Apr 2021 15:30:41 -0300 Subject: [PATCH 1983/2161] mc: Removed original version comment, not relevant for assembler --- asminc/ascii_charmap.inc | 4 ---- asminc/atari_atascii_charmap.inc | 2 -- asminc/atari_screen_charmap.inc | 2 -- asminc/cbm_petscii_charmap.inc | 2 -- asminc/cbm_screen_charmap.inc | 2 -- 5 files changed, 12 deletions(-) diff --git a/asminc/ascii_charmap.inc b/asminc/ascii_charmap.inc index 57728b0d4..ecbf2640f 100644 --- a/asminc/ascii_charmap.inc +++ b/asminc/ascii_charmap.inc @@ -26,10 +26,6 @@ ;/* */ ;/*****************************************************************************/ -;/* No include guard here. Each charmap header -;** may be included many times in a source file. -;*/ - ;/* ASCII */ .charmap $00, $00 .charmap $01, $01 diff --git a/asminc/atari_atascii_charmap.inc b/asminc/atari_atascii_charmap.inc index 8c3222dd6..7c6b5e542 100644 --- a/asminc/atari_atascii_charmap.inc +++ b/asminc/atari_atascii_charmap.inc @@ -28,8 +28,6 @@ ;/* */ ;/*****************************************************************************/ -;/* No include guard here! Multiple use in one file may be intentional. */ - .charmap $00, $00 .charmap $01, $01 .charmap $02, $02 diff --git a/asminc/atari_screen_charmap.inc b/asminc/atari_screen_charmap.inc index ca4f9e1d7..193ea0685 100644 --- a/asminc/atari_screen_charmap.inc +++ b/asminc/atari_screen_charmap.inc @@ -28,8 +28,6 @@ ;/* */ ;/*****************************************************************************/ -;/* No include guard here! Multiple use in one file may be intentional. */ - .charmap $00, $40 .charmap $01, $41 .charmap $02, $42 diff --git a/asminc/cbm_petscii_charmap.inc b/asminc/cbm_petscii_charmap.inc index 15fde0d8c..525bffb01 100644 --- a/asminc/cbm_petscii_charmap.inc +++ b/asminc/cbm_petscii_charmap.inc @@ -26,8 +26,6 @@ ;/* */ ;/*****************************************************************************/ -;/* No include guard here! Multiple use in one file might be intentional. */ - .charmap $00, $00 .charmap $01, $01 .charmap $02, $02 diff --git a/asminc/cbm_screen_charmap.inc b/asminc/cbm_screen_charmap.inc index cacce10db..12d02553d 100644 --- a/asminc/cbm_screen_charmap.inc +++ b/asminc/cbm_screen_charmap.inc @@ -12,8 +12,6 @@ ;/* */ ;/*****************************************************************************/ -;/* No include guard here! Multiple use in one file may be intentional. */ - ; Char $00 -> c + 128 .charmap $00, $80 From 2120dd662c919a884e73e68736cb9b806c818367 Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky <me@veg.by> Date: Sun, 18 Apr 2021 20:07:43 +0300 Subject: [PATCH 1984/2161] Move all common project settings into cc65.props. --- src/.gitignore | 1 + src/ar65.vcxproj | 35 ++------------ src/ca65.vcxproj | 35 ++------------ src/cc65.props | 62 +++++++++++++++++++++++++ src/cc65.vcxproj | 35 ++------------ src/chrcvt65.vcxproj | 35 ++------------ src/cl65.vcxproj | 35 ++------------ src/co65.vcxproj | 35 ++------------ src/common.vcxproj | 106 +++++++++++++------------------------------ src/da65.vcxproj | 35 ++------------ src/grc65.vcxproj | 35 ++------------ src/ld65.vcxproj | 37 ++------------- src/od65.vcxproj | 35 ++------------ src/sim65.vcxproj | 36 ++------------- src/sp65.vcxproj | 35 ++------------ 15 files changed, 132 insertions(+), 460 deletions(-) create mode 100644 src/cc65.props diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..6f2d5329a 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,37 @@ <PropertyGroup Label="Globals"> <ProjectGuid>{5E8C19C6-B167-440C-8BEF-3CBF109CDB49}</ProjectGuid> <Keyword>Win32Proj</Keyword> - <RootNamespace>ar65</RootNamespace> - <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> + <Import Project="cc65.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> <PropertyGroup Label="UserMacros" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> - <PrecompiledHeader> - </PrecompiledHeader> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>false</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemGroup> diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..c4d8c17ef 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,37 @@ <PropertyGroup Label="Globals"> <ProjectGuid>{D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC}</ProjectGuid> <Keyword>Win32Proj</Keyword> - <RootNamespace>ca65</RootNamespace> - <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> + <Import Project="cc65.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> <PropertyGroup Label="UserMacros" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <LinkIncremental>true</LinkIncremental> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> - <OutDir>$(SolutionDir)..\bin\</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG</PreprocessorDefinitions> - <TreatWarningAsError>true</TreatWarningAsError> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CONSOLE;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> - <PrecompiledHeader> - </PrecompiledHeader> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG</PreprocessorDefinitions> - <TreatWarningAsError>true</TreatWarningAsError> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CONSOLE;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>false</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemGroup> diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..bd0eb6024 --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ +<Project> + + <!-- VS2017 compatibility. --> + <PropertyGroup Condition="$(MSBuildVersion.Split('.')[0]) == '15'"> + <PlatformToolset Condition="'$(PlatformToolset)' == ''">v141</PlatformToolset> + <WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">$([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0'))</WindowsTargetPlatformVersion> + </PropertyGroup> + + <!-- Common settings. --> + <PropertyGroup> + <PlatformToolset Condition="'$(PlatformToolset)' == ''">v142</PlatformToolset> + <WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">10.0</WindowsTargetPlatformVersion> + <IntDir>$(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\</IntDir> + <OutDir>$(SolutionDir)..\bin\</OutDir> + <OutDir Condition="$(MSBuildProjectName) == 'common'">$(IntDir)</OutDir> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <PrecompiledHeader></PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories Condition="$(MSBuildProjectName) != 'common'">common</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <AdditionalDependencies Condition="$(MSBuildProjectName) != 'common'">$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + + <!-- Debug settings. --> + <PropertyGroup Condition="'$(Configuration)'=='Debug'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + + <!-- Release settings. --> + <PropertyGroup Condition="'$(Configuration)'=='Release'"> + <LinkIncremental>false</LinkIncremental> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'"> + <ClCompile> + <FunctionLevelLinking>true</FunctionLevelLinking> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + </ClCompile> + <Link> + <GenerateDebugInformation>false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> + </Link> + </ItemDefinitionGroup> +</Project> \ No newline at end of file diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..f631672aa 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,37 @@ <PropertyGroup Label="Globals"> <ProjectGuid>{B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA}</ProjectGuid> <Keyword>Win32Proj</Keyword> - <RootNamespace>cc65</RootNamespace> - <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> + <Import Project="cc65.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> <PropertyGroup Label="UserMacros" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <LinkIncremental>true</LinkIncremental> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> - <OutDir>$(SolutionDir)..\bin\</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <WarningLevel>Level3</WarningLevel> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> - <PrecompiledHeader> - </PrecompiledHeader> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>false</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemGroup> diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1f517e11a 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,37 @@ <PropertyGroup Label="Globals"> <ProjectGuid>{1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC}</ProjectGuid> <Keyword>Win32Proj</Keyword> - <RootNamespace>chrcvt65</RootNamespace> - <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> + <Import Project="cc65.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> <PropertyGroup Label="UserMacros" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> - <PrecompiledHeader> - </PrecompiledHeader> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>false</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemGroup> diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..14fcf06bd 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,37 @@ <PropertyGroup Label="Globals"> <ProjectGuid>{F657912F-050A-488B-B203-50ED5715CDD7}</ProjectGuid> <Keyword>Win32Proj</Keyword> - <RootNamespace>cl65</RootNamespace> - <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> + <Import Project="cc65.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> <PropertyGroup Label="UserMacros" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> - <PrecompiledHeader> - </PrecompiledHeader> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>false</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemGroup> diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..8fab51c53 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,37 @@ <PropertyGroup Label="Globals"> <ProjectGuid>{F5DB5D1A-05BC-48FE-B346-4E96DD522AA2}</ProjectGuid> <Keyword>Win32Proj</Keyword> - <RootNamespace>co65</RootNamespace> - <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> + <Import Project="cc65.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> <PropertyGroup Label="UserMacros" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> - <PrecompiledHeader> - </PrecompiledHeader> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>false</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemGroup> diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..957ba55ad 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,38 @@ <Platform>Win32</Platform> </ProjectConfiguration> </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{71DC1F68-BFC4-478C-8655-C8E9C9654D2B}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="cc65.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PreprocessorDefinitions>_LIB;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PreprocessorDefinitions>_LIB;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + </ItemDefinitionGroup> <ItemGroup> <ClInclude Include="common\abend.h" /> <ClInclude Include="common\addrsize.h" /> @@ -106,80 +138,6 @@ <ClCompile Include="common\xmalloc.c" /> <ClCompile Include="common\xsprintf.c" /> </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{71DC1F68-BFC4-478C-8655-C8E9C9654D2B}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>common</RootNamespace> - <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <ConfigurationType>StaticLibrary</ConfigurationType> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> - <OutDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</OutDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> - <OutDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</OutDir> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG</PreprocessorDefinitions> - <TreatWarningAsError>true</TreatWarningAsError> - </ClCompile> - <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - <Lib /> - <Lib> - <OutputFile>$(IntDir)$(TargetName)$(TargetExt)</OutputFile> - </Lib> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <WarningLevel>Level3</WarningLevel> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG</PreprocessorDefinitions> - <TreatWarningAsError>true</TreatWarningAsError> - </ClCompile> - <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - </Link> - <Lib /> - <Lib> - <OutputFile>$(IntDir)$(TargetName)$(TargetExt)</OutputFile> - </Lib> - </ItemDefinitionGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..ae7c9a7f4 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,37 @@ <PropertyGroup Label="Globals"> <ProjectGuid>{0BCFB793-2B25-40E2-B265-75848824AC4C}</ProjectGuid> <Keyword>Win32Proj</Keyword> - <RootNamespace>da65</RootNamespace> - <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> + <Import Project="cc65.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> <PropertyGroup Label="UserMacros" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> - <PrecompiledHeader> - </PrecompiledHeader> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>false</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemGroup> diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..1c61bc82e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,37 @@ <PropertyGroup Label="Globals"> <ProjectGuid>{E0FD0AB3-3BEE-496F-8108-A8E0F8933F39}</ProjectGuid> <Keyword>Win32Proj</Keyword> - <RootNamespace>grc65</RootNamespace> - <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> + <Import Project="cc65.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> <PropertyGroup Label="UserMacros" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> - <PrecompiledHeader> - </PrecompiledHeader> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>false</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemGroup> diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..0e7ac7346 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,37 @@ <PropertyGroup Label="Globals"> <ProjectGuid>{26C749A0-814C-47A2-9D36-AE92AE932FE4}</ProjectGuid> <Keyword>Win32Proj</Keyword> - <RootNamespace>ld65</RootNamespace> - <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> + <Import Project="cc65.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> <PropertyGroup Label="UserMacros" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> - <PrecompiledHeader> - </PrecompiledHeader> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>false</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemGroup> @@ -145,4 +116,4 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project> +</Project> \ No newline at end of file diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..125452e5b 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,37 @@ <PropertyGroup Label="Globals"> <ProjectGuid>{FF8576C2-1253-44FE-A51B-D9AE35F3CEAD}</ProjectGuid> <Keyword>Win32Proj</Keyword> - <RootNamespace>od65</RootNamespace> - <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> + <Import Project="cc65.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> <PropertyGroup Label="UserMacros" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> - <PrecompiledHeader> - </PrecompiledHeader> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>false</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemGroup> diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..26bf3cf5b 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,37 @@ <PropertyGroup Label="Globals"> <ProjectGuid>{002A366E-2863-46A8-BDDE-DDF534AAEC73}</ProjectGuid> <Keyword>Win32Proj</Keyword> - <RootNamespace>sim65</RootNamespace> - <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> + <Import Project="cc65.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> <PropertyGroup Label="UserMacros" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> - <PrecompiledHeader> - </PrecompiledHeader> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>false</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemGroup> diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..12b45c9e1 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,37 @@ <PropertyGroup Label="Globals"> <ProjectGuid>{4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF}</ProjectGuid> <Keyword>Win32Proj</Keyword> - <RootNamespace>sp65</RootNamespace> - <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> </PropertyGroup> + <Import Project="cc65.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>v141</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> <PropertyGroup Label="UserMacros" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <IntDir>$(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\</IntDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <WarningLevel>Level3</WarningLevel> - <PrecompiledHeader> - </PrecompiledHeader> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>common</AdditionalIncludeDirectories> - <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CONSOLE;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>false</GenerateDebugInformation> - <AdditionalDependencies>$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemGroup> From 7be3b53f72cabb74c9e16035fee41da603c28be6 Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky <me@veg.by> Date: Sun, 18 Apr 2021 20:29:30 +0300 Subject: [PATCH 1985/2161] cc65.props uses spaces instead of tabs. --- src/cc65.props | 112 ++++++++++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/src/cc65.props b/src/cc65.props index bd0eb6024..9d56b06bd 100644 --- a/src/cc65.props +++ b/src/cc65.props @@ -1,62 +1,62 @@ <Project> - <!-- VS2017 compatibility. --> - <PropertyGroup Condition="$(MSBuildVersion.Split('.')[0]) == '15'"> - <PlatformToolset Condition="'$(PlatformToolset)' == ''">v141</PlatformToolset> - <WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">$([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0'))</WindowsTargetPlatformVersion> - </PropertyGroup> + <!-- VS2017 compatibility. --> + <PropertyGroup Condition="$(MSBuildVersion.Split('.')[0]) == '15'"> + <PlatformToolset Condition="'$(PlatformToolset)' == ''">v141</PlatformToolset> + <WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">$([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0'))</WindowsTargetPlatformVersion> + </PropertyGroup> - <!-- Common settings. --> - <PropertyGroup> - <PlatformToolset Condition="'$(PlatformToolset)' == ''">v142</PlatformToolset> - <WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">10.0</WindowsTargetPlatformVersion> - <IntDir>$(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\</IntDir> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <OutDir Condition="$(MSBuildProjectName) == 'common'">$(IntDir)</OutDir> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <PrecompiledHeader></PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <TreatWarningAsError>true</TreatWarningAsError> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="$(MSBuildProjectName) != 'common'">common</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <AdditionalDependencies Condition="$(MSBuildProjectName) != 'common'">$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> + <!-- Common settings. --> + <PropertyGroup> + <PlatformToolset Condition="'$(PlatformToolset)' == ''">v142</PlatformToolset> + <WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">10.0</WindowsTargetPlatformVersion> + <IntDir>$(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\</IntDir> + <OutDir>$(SolutionDir)..\bin\</OutDir> + <OutDir Condition="$(MSBuildProjectName) == 'common'">$(IntDir)</OutDir> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <PrecompiledHeader></PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories Condition="$(MSBuildProjectName) != 'common'">common</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <AdditionalDependencies Condition="$(MSBuildProjectName) != 'common'">$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> - <!-- Debug settings. --> - <PropertyGroup Condition="'$(Configuration)'=='Debug'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'"> - <ClCompile> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <BufferSecurityCheck>true</BufferSecurityCheck> - </ClCompile> - <Link> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> + <!-- Debug settings. --> + <PropertyGroup Condition="'$(Configuration)'=='Debug'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> - <!-- Release settings. --> - <PropertyGroup Condition="'$(Configuration)'=='Release'"> - <LinkIncremental>false</LinkIncremental> - <WholeProgramOptimization>true</WholeProgramOptimization> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'"> - <ClCompile> - <FunctionLevelLinking>true</FunctionLevelLinking> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <BufferSecurityCheck>false</BufferSecurityCheck> - </ClCompile> - <Link> - <GenerateDebugInformation>false</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - </Link> - </ItemDefinitionGroup> + <!-- Release settings. --> + <PropertyGroup Condition="'$(Configuration)'=='Release'"> + <LinkIncremental>false</LinkIncremental> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'"> + <ClCompile> + <FunctionLevelLinking>true</FunctionLevelLinking> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <BufferSecurityCheck>false</BufferSecurityCheck> + </ClCompile> + <Link> + <GenerateDebugInformation>false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> + </Link> + </ItemDefinitionGroup> </Project> \ No newline at end of file From ee8c7b47bc5c1e2c28300f4f245b44e38af127c1 Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky <me@veg.by> Date: Sun, 18 Apr 2021 20:47:21 +0300 Subject: [PATCH 1986/2161] Add new lines at the end of the project files. --- src/cc65.props | 2 +- src/ld65.vcxproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65.props b/src/cc65.props index 9d56b06bd..20c5e9622 100644 --- a/src/cc65.props +++ b/src/cc65.props @@ -59,4 +59,4 @@ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> </Link> </ItemDefinitionGroup> -</Project> \ No newline at end of file +</Project> diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index 0e7ac7346..d4597de4f 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -116,4 +116,4 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project> \ No newline at end of file +</Project> From ac08482fa38f645e2cfd2cd520b91e3aba3a6344 Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky <me@veg.by> Date: Sun, 18 Apr 2021 21:33:46 +0300 Subject: [PATCH 1987/2161] Allow editing cc65.props from Property Manager. --- src/ar65.vcxproj | 4 +- src/ca65.vcxproj | 4 +- src/cc65.props | 120 +++++++++++++++++++++---------------------- src/cc65.vcxproj | 4 +- src/chrcvt65.vcxproj | 4 +- src/cl65.vcxproj | 4 +- src/co65.vcxproj | 4 +- src/common.vcxproj | 4 +- src/da65.vcxproj | 4 +- src/grc65.vcxproj | 4 +- src/ld65.vcxproj | 4 +- src/od65.vcxproj | 4 +- src/sim65.vcxproj | 4 +- src/sp65.vcxproj | 4 +- 14 files changed, 99 insertions(+), 73 deletions(-) diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index 6f2d5329a..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -14,7 +14,9 @@ <ProjectGuid>{5E8C19C6-B167-440C-8BEF-3CBF109CDB49}</ProjectGuid> <Keyword>Win32Proj</Keyword> </PropertyGroup> - <Import Project="cc65.props" /> + <ImportGroup Label="PropertySheets"> + <Import Project="cc65.props" /> + </ImportGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index c4d8c17ef..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -14,7 +14,9 @@ <ProjectGuid>{D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC}</ProjectGuid> <Keyword>Win32Proj</Keyword> </PropertyGroup> - <Import Project="cc65.props" /> + <ImportGroup Label="PropertySheets"> + <Import Project="cc65.props" /> + </ImportGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> diff --git a/src/cc65.props b/src/cc65.props index 20c5e9622..ef5a37fea 100644 --- a/src/cc65.props +++ b/src/cc65.props @@ -1,62 +1,62 @@ <Project> - - <!-- VS2017 compatibility. --> - <PropertyGroup Condition="$(MSBuildVersion.Split('.')[0]) == '15'"> - <PlatformToolset Condition="'$(PlatformToolset)' == ''">v141</PlatformToolset> - <WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">$([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0'))</WindowsTargetPlatformVersion> - </PropertyGroup> - - <!-- Common settings. --> - <PropertyGroup> - <PlatformToolset Condition="'$(PlatformToolset)' == ''">v142</PlatformToolset> - <WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">10.0</WindowsTargetPlatformVersion> - <IntDir>$(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\</IntDir> - <OutDir>$(SolutionDir)..\bin\</OutDir> - <OutDir Condition="$(MSBuildProjectName) == 'common'">$(IntDir)</OutDir> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <PrecompiledHeader></PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <TreatWarningAsError>true</TreatWarningAsError> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories Condition="$(MSBuildProjectName) != 'common'">common</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <AdditionalDependencies Condition="$(MSBuildProjectName) != 'common'">$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - - <!-- Debug settings. --> - <PropertyGroup Condition="'$(Configuration)'=='Debug'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'"> - <ClCompile> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <BufferSecurityCheck>true</BufferSecurityCheck> - </ClCompile> - <Link> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - - <!-- Release settings. --> - <PropertyGroup Condition="'$(Configuration)'=='Release'"> - <LinkIncremental>false</LinkIncremental> - <WholeProgramOptimization>true</WholeProgramOptimization> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'"> - <ClCompile> - <FunctionLevelLinking>true</FunctionLevelLinking> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <BufferSecurityCheck>false</BufferSecurityCheck> - </ClCompile> - <Link> - <GenerateDebugInformation>false</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - </Link> - </ItemDefinitionGroup> + <PropertyGroup Label="UserMacros"> + </PropertyGroup> + <!-- VS2017 compatibility. --> + <PropertyGroup Condition="$(MSBuildVersion.Split('.')[0]) == '15'"> + <PlatformToolset Condition="'$(PlatformToolset)' == ''">v141</PlatformToolset> + <WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">$([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0'))</WindowsTargetPlatformVersion> + </PropertyGroup> + <!-- Common settings. --> + <PropertyGroup> + <PlatformToolset Condition="'$(PlatformToolset)' == ''">v142</PlatformToolset> + <WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">10.0</WindowsTargetPlatformVersion> + <IntDir>$(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\</IntDir> + <OutDir>$(SolutionDir)..\bin\</OutDir> + <OutDir Condition="$(MSBuildProjectName) == 'common'">$(IntDir)</OutDir> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories Condition="$(MSBuildProjectName) != 'common'">common</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <AdditionalDependencies Condition="$(MSBuildProjectName) != 'common'">$(IntDir)..\..\common\$(Configuration)\common.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <!-- Debug settings. --> + <PropertyGroup Condition="'$(Configuration)'=='Debug'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <!-- Release settings. --> + <PropertyGroup Condition="'$(Configuration)'=='Release'"> + <LinkIncremental>false</LinkIncremental> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <BufferSecurityCheck>false</BufferSecurityCheck> + <ControlFlowGuard>false</ControlFlowGuard> + </ClCompile> + <Link> + <GenerateDebugInformation>false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> + </Link> + </ItemDefinitionGroup> </Project> diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index f631672aa..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -14,7 +14,9 @@ <ProjectGuid>{B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA}</ProjectGuid> <Keyword>Win32Proj</Keyword> </PropertyGroup> - <Import Project="cc65.props" /> + <ImportGroup Label="PropertySheets"> + <Import Project="cc65.props" /> + </ImportGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 1f517e11a..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -14,7 +14,9 @@ <ProjectGuid>{1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC}</ProjectGuid> <Keyword>Win32Proj</Keyword> </PropertyGroup> - <Import Project="cc65.props" /> + <ImportGroup Label="PropertySheets"> + <Import Project="cc65.props" /> + </ImportGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index 14fcf06bd..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -14,7 +14,9 @@ <ProjectGuid>{F657912F-050A-488B-B203-50ED5715CDD7}</ProjectGuid> <Keyword>Win32Proj</Keyword> </PropertyGroup> - <Import Project="cc65.props" /> + <ImportGroup Label="PropertySheets"> + <Import Project="cc65.props" /> + </ImportGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 8fab51c53..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -14,7 +14,9 @@ <ProjectGuid>{F5DB5D1A-05BC-48FE-B346-4E96DD522AA2}</ProjectGuid> <Keyword>Win32Proj</Keyword> </PropertyGroup> - <Import Project="cc65.props" /> + <ImportGroup Label="PropertySheets"> + <Import Project="cc65.props" /> + </ImportGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> diff --git a/src/common.vcxproj b/src/common.vcxproj index 957ba55ad..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -14,7 +14,9 @@ <ProjectGuid>{71DC1F68-BFC4-478C-8655-C8E9C9654D2B}</ProjectGuid> <Keyword>Win32Proj</Keyword> </PropertyGroup> - <Import Project="cc65.props" /> + <ImportGroup Label="PropertySheets"> + <Import Project="cc65.props" /> + </ImportGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> diff --git a/src/da65.vcxproj b/src/da65.vcxproj index ae7c9a7f4..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -14,7 +14,9 @@ <ProjectGuid>{0BCFB793-2B25-40E2-B265-75848824AC4C}</ProjectGuid> <Keyword>Win32Proj</Keyword> </PropertyGroup> - <Import Project="cc65.props" /> + <ImportGroup Label="PropertySheets"> + <Import Project="cc65.props" /> + </ImportGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 1c61bc82e..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -14,7 +14,9 @@ <ProjectGuid>{E0FD0AB3-3BEE-496F-8108-A8E0F8933F39}</ProjectGuid> <Keyword>Win32Proj</Keyword> </PropertyGroup> - <Import Project="cc65.props" /> + <ImportGroup Label="PropertySheets"> + <Import Project="cc65.props" /> + </ImportGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index d4597de4f..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -14,7 +14,9 @@ <ProjectGuid>{26C749A0-814C-47A2-9D36-AE92AE932FE4}</ProjectGuid> <Keyword>Win32Proj</Keyword> </PropertyGroup> - <Import Project="cc65.props" /> + <ImportGroup Label="PropertySheets"> + <Import Project="cc65.props" /> + </ImportGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 125452e5b..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -14,7 +14,9 @@ <ProjectGuid>{FF8576C2-1253-44FE-A51B-D9AE35F3CEAD}</ProjectGuid> <Keyword>Win32Proj</Keyword> </PropertyGroup> - <Import Project="cc65.props" /> + <ImportGroup Label="PropertySheets"> + <Import Project="cc65.props" /> + </ImportGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 26bf3cf5b..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -14,7 +14,9 @@ <ProjectGuid>{002A366E-2863-46A8-BDDE-DDF534AAEC73}</ProjectGuid> <Keyword>Win32Proj</Keyword> </PropertyGroup> - <Import Project="cc65.props" /> + <ImportGroup Label="PropertySheets"> + <Import Project="cc65.props" /> + </ImportGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 12b45c9e1..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -14,7 +14,9 @@ <ProjectGuid>{4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF}</ProjectGuid> <Keyword>Win32Proj</Keyword> </PropertyGroup> - <Import Project="cc65.props" /> + <ImportGroup Label="PropertySheets"> + <Import Project="cc65.props" /> + </ImportGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <UseDebugLibraries>true</UseDebugLibraries> From a982f6a668258850d0f1e40f7733d91a3729af20 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 6 Apr 2021 22:35:51 +0200 Subject: [PATCH 1988/2161] Removed obsolete file. https://github.com/cc65/cc65/commit/c658acbf850e32508ea0e14f0f62d675a009c7d9 made this file unnecessary. --- test/.gitignore | 1 - 1 file changed, 1 deletion(-) delete mode 100644 test/.gitignore diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o From bfb7c936aa9ba5fe93c9923af1f1a8dc2deacf22 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 30 Mar 2021 16:47:57 +0800 Subject: [PATCH 1989/2161] Preparation for constness-correction. --- src/cc65/expr.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index b0ebbf191..64980aceb 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -4094,7 +4094,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4138,22 +4138,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } From 896f463a23e2a58695e23562b7c6f3a46489c9b2 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 30 Mar 2021 16:47:52 +0800 Subject: [PATCH 1990/2161] Used more specific pointers instead of the "arbitary attribute pointer" used in type strings. --- src/cc65/codeinfo.c | 1 + src/cc65/compile.c | 1 + src/cc65/datatype.c | 26 +++++++++++++------------- src/cc65/datatype.h | 16 ++++++++++++---- src/cc65/declare.c | 2 +- src/cc65/pragma.c | 1 + src/cc65/symentry.c | 2 +- src/cc65/typecmp.c | 1 + src/cc65/typeconv.c | 1 + 9 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..901e2ce13 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -468,7 +468,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -685,13 +685,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -715,16 +715,16 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +792,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +925,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -1121,7 +1121,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,7 +1138,7 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } @@ -1226,7 +1226,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,7 +1238,7 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..77dad47ac 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -153,7 +160,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..e15c59d40 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* 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.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..5bce488c5 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..f0958d7e0 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..210f02565 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" From 24d36854d2810c787d81350f9d6beeff3b2df300 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 5 Apr 2021 16:40:32 +0800 Subject: [PATCH 1991/2161] Minor cleanups with array element qualifiers. --- src/cc65/expr.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 64980aceb..6a4b44795 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3132,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually From 328345b9c3e0adb7bc46968acba4184626572331 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 5 Apr 2021 16:40:32 +0800 Subject: [PATCH 1992/2161] Removed a helper function that is no longer used. --- src/cc65/datatype.c | 14 -------------- src/cc65/datatype.h | 5 ----- 2 files changed, 19 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 901e2ce13..393177897 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -948,20 +948,6 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) -/* Do one indirection for the given type, that is, return the type where the -** given type points to. -*/ -{ - /* We are expecting a pointer expression */ - CHECK (IsClassPtr (T)); - - /* Skip the pointer or array token itself */ - return T + 1; -} - - - Type* ArrayToPtr (Type* T) /* Convert an array to a pointer to it's first element */ { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 77dad47ac..de4314347 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -353,11 +353,6 @@ Type* Indirect (Type* T); ** given type points to. */ -const Type* IndirectConst (const Type* T); -/* Do one indirection for the given type, that is, return the type where the -** given type points to. -*/ - Type* ArrayToPtr (Type* T); /* Convert an array to a pointer to it's first element */ From cb64aaf20c6128aa69b95feec5e64de646c167a1 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 5 Apr 2021 16:40:32 +0800 Subject: [PATCH 1993/2161] Made the code more constness-correct with 'Type' usage for inlined std functions. --- src/cc65/stdfunc.c | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..117214a24 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; + static const Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; + static const Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; + static const Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; + static const Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; + static const Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); From 9cea9ce5e210fce8fcfc4d0b41cfdd6406fd4b4e Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 5 Apr 2021 16:40:32 +0800 Subject: [PATCH 1994/2161] Made the code more constness-correct with 'Type' usage. --- src/cc65/assignment.c | 2 +- src/cc65/datatype.c | 83 +++++++++++++++++++++++++++++-------------- src/cc65/datatype.h | 52 +++++++++++++++------------ src/cc65/declare.c | 8 ++--- src/cc65/expr.c | 32 ++++++++--------- src/cc65/exprdesc.c | 6 ++-- src/cc65/exprdesc.h | 6 ++-- src/cc65/function.c | 2 +- src/cc65/function.h | 4 +-- src/cc65/scanner.h | 2 +- src/cc65/shiftexpr.c | 6 ++-- src/cc65/symentry.c | 2 +- src/cc65/symentry.h | 2 +- src/cc65/typecmp.c | 4 +-- src/cc65/typeconv.c | 10 +++--- 15 files changed, 130 insertions(+), 91 deletions(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 393177897..8240a4e60 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,18 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; @@ -559,7 +559,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +591,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -713,7 +714,6 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); @@ -934,7 +934,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,11 +948,25 @@ Type* Indirect (Type* T) -Type* ArrayToPtr (Type* T) +Type* IndirectModifiable (Type* T) +/* Do one indirection for the given type, that is, return the type where the +** given type points to. +*/ +{ + /* We are expecting a pointer expression */ + CHECK (IsClassPtr (T)); + + /* Skip the pointer or array token itself */ + return T + 1; +} + + + +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1129,7 +1143,7 @@ void SetFuncDesc (Type* T, FuncDesc* F) -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1146,10 +1160,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1182,7 +1213,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1191,7 +1222,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1229,7 +1260,7 @@ void SetESUSymEntry (Type* T, SymEntry* S) -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1268,14 +1299,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index de4314347..b65cbdd05 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -198,18 +198,18 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -280,7 +280,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -288,7 +288,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -348,12 +348,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* IndirectModifiable (Type* T); +/* Do one indirection for the given type, that is, return the type where the +** given type points to. +*/ + +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -845,10 +850,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -861,10 +869,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -876,12 +884,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index e15c59d40..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (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. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 6a4b44795..c0a9081f9 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -2052,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2380,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2402,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2792,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3189,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -4102,10 +4102,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4113,7 +4113,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index 5bce488c5..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index f0958d7e0..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -67,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 210f02565..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -58,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -371,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. From f901adba2212cf00f5abc3d23d3726731e05fa6f Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 5 Apr 2021 16:40:32 +0800 Subject: [PATCH 1995/2161] Predefined type strings for inlined std function parameters. --- src/cc65/datatype.c | 6 ++++++ src/cc65/datatype.h | 10 ++++++++++ src/cc65/stdfunc.c | 22 +++++++++++----------- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 8240a4e60..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -72,6 +72,12 @@ const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; + /*****************************************************************************/ diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index b65cbdd05..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -146,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -211,6 +215,12 @@ extern const Type type_size_t[]; extern const Type type_float[]; extern const Type type_double[]; +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; + /* Forward for the SymEntry struct */ struct SymEntry; diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 117214a24..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static const Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static const Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static const Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static const Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static const Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static const Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static const Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static const Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -983,8 +983,8 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static const Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static const Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -1180,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static const Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; From fd3d5d35fb4d7fb0f38508f3593f892ad301a8ff Mon Sep 17 00:00:00 2001 From: Marco Aurelio da Costa <costa@gamic.com> Date: Sun, 18 Apr 2021 17:24:29 -0300 Subject: [PATCH 1996/2161] mc: Implemented .LITERAL --- doc/ca65.sgml | 34 ++++++++++++++++++++++++++++++---- src/ca65/pseudo.c | 29 +++++++++++++++++++++++++---- src/ca65/scanner.c | 1 + src/ca65/token.h | 1 + 4 files changed, 57 insertions(+), 8 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index ebd6c7135..f3a3c218f 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -2084,7 +2084,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: <tt><ref id=".BYTE" name=".BYTE"></tt>,<tt><ref id=".CHARMAP" name=".CHARMAP"></tt>, + <tt><ref id=".LITERAL" name=".LITERAL"></tt> <sect1><tt>.ASSERT</tt><label id=".ASSERT"><p> @@ -2180,7 +2184,8 @@ Here's a list of all control commands and a description, what they do: <sect1><tt>.BYT, .BYTE</tt><label id=".BYTE"><p> Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2194,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 </verb></tscreen> +See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CHARMAP"></tt> + <tt><ref id=".LITERAL" name=".LITERAL"></tt> + <sect1><tt>.CASE</tt><label id=".CASE"><p> @@ -2207,8 +2215,10 @@ Here's a list of all control commands and a description, what they do: <sect1><tt>.CHARMAP</tt><label id=".CHARMAP"><p> - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands <tt><ref id=".ASCIIZ" + name=".ASCIIZ"></tt> and <tt><ref id=".BYTE" name=".BYTE"></tt>. The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants <em/when/ they generate output; and, overrides a mapping table specified with the <tt><ref id="option-t" name="-t"></tt> @@ -3356,6 +3366,22 @@ Here's a list of all control commands and a description, what they do: </verb></tscreen> +<sect1><tt>.LITERAL</tt><label id=".LITERAL"><p> + + Define byte sized data. Must be followed by a sequence of (byte ranged) + expressions or strings. Strings will disregard the current character + mapping definition and will be interpreted literally. + + Example: + + <tscreen><verb> + .literal "Hello " + .literal "world", $0D, $00 + </verb></tscreen> + +See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE"></tt> + + <sect1><tt>.LOBYTES</tt><label id=".LOBYTES"><p> Define byte sized data by extracting only the low byte (that is, bits 0-7) from diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index df0482a5a..7e24d814d 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -2103,6 +2123,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 0452bb368..0a7d433b2 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, diff --git a/src/ca65/token.h b/src/ca65/token.h index a94254bfd..02fc8d491 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, From f272bc8f42ebe26b7bab8e44665957eb690dfcf3 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 19 Apr 2021 15:50:52 +0200 Subject: [PATCH 1997/2161] Removed non-ASCII chars. --- asminc/joy-kernel.inc | 2 +- include/fcntl.h | 2 +- include/mouse/mouse-kernel.h | 2 +- include/signal.h | 2 +- src/ar65/error.c | 2 +- src/ca65/enum.h | 2 +- src/ca65/struct.h | 2 +- src/cc65/loadexpr.h | 2 +- src/cc65/loop.c | 2 +- src/cc65/loop.h | 2 +- src/cc65/preproc.h | 2 +- src/cc65/shiftexpr.h | 2 +- src/cc65/stackptr.c | 2 +- src/cc65/stackptr.h | 2 +- src/cc65/testexpr.c | 2 +- src/common/inline.h | 2 +- src/common/strstack.c | 2 +- src/common/strstack.h | 2 +- src/common/xmalloc.h | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/asminc/joy-kernel.inc b/asminc/joy-kernel.inc index ef729fe3c..791934197 100644 --- a/asminc/joy-kernel.inc +++ b/asminc/joy-kernel.inc @@ -7,7 +7,7 @@ ;/* */ ;/* */ ;/* (C) 2002-2006, Ullrich von Bassewitz */ -;/* Römerstraße 52 */ +;/* Roemerstrasse 52 */ ;/* D-70794 Filderstadt */ ;/* EMail: uz@cc65.org */ ;/* */ diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ From 5d84a4ba137e32163390ccd058c32ad169b4ca94 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Mon, 19 Apr 2021 16:06:10 +0200 Subject: [PATCH 1998/2161] Removed non-ASCII chars. --- asminc/em-kernel.inc | 2 +- asminc/ser-kernel.inc | 2 +- asminc/stdio.inc | 2 +- asminc/utsname.inc | 2 +- include/_ted.h | 2 +- include/cbm264.h | 2 +- include/locale.h | 2 +- include/peekpoke.h | 2 +- include/plus4.h | 2 +- include/stdarg.h | 2 +- include/sys/stat.h | 2 +- include/sys/types.h | 2 +- libsrc/common/_poserror.c | 2 +- src/ar65/error.h | 2 +- src/ca65/ea.h | 2 +- src/ca65/ea65.h | 2 +- src/ca65/easw16.h | 2 +- src/cc65/assignment.h | 2 +- src/cc65/coptadd.c | 2 +- src/cc65/coptsub.c | 2 +- src/cl65/error.h | 2 +- src/co65/convert.h | 2 +- src/co65/error.c | 2 +- src/co65/error.h | 2 +- src/co65/fileio.c | 2 +- src/co65/fileio.h | 2 +- src/co65/global.c | 2 +- src/co65/global.h | 2 +- src/common/fragdefs.h | 2 +- src/common/optdefs.h | 2 +- src/common/segnames.c | 2 +- src/common/segnames.h | 2 +- src/common/va_copy.h | 2 +- src/common/xmalloc.c | 2 +- src/da65/asminc.h | 2 +- src/da65/code.h | 2 +- src/da65/comments.c | 2 +- src/da65/comments.h | 2 +- src/da65/error.h | 2 +- src/da65/global.c | 2 +- src/da65/infofile.h | 2 +- src/da65/opc4510.h | 2 +- src/da65/opc6502.h | 2 +- src/da65/opc65816.h | 2 +- src/da65/opc65c02.h | 2 +- src/da65/opc65sc02.h | 2 +- src/da65/opcdesc.h | 2 +- src/da65/opctable.h | 2 +- src/ld65/dbgfile.h | 2 +- src/ld65/error.h | 2 +- src/ld65/o65.h | 2 +- src/od65/error.h | 2 +- src/od65/fileio.h | 2 +- src/sim65/error.c | 2 +- src/sim65/error.h | 2 +- src/sim65/paravirt.c | 2 +- src/sim65/paravirt.h | 2 +- 57 files changed, 57 insertions(+), 57 deletions(-) diff --git a/asminc/em-kernel.inc b/asminc/em-kernel.inc index e7cdf9a70..889ffba98 100644 --- a/asminc/em-kernel.inc +++ b/asminc/em-kernel.inc @@ -7,7 +7,7 @@ ;/* */ ;/* */ ;/* (C) 2002-2003 Ullrich von Bassewitz */ -;/* Römerstrasse 52 */ +;/* Roemerstrasse 52 */ ;/* D-70794 Filderstadt */ ;/* EMail: uz@cc65.org */ ;/* */ diff --git a/asminc/ser-kernel.inc b/asminc/ser-kernel.inc index 546587515..79ace64e9 100644 --- a/asminc/ser-kernel.inc +++ b/asminc/ser-kernel.inc @@ -7,7 +7,7 @@ ;* * ;* * ;*(C) 2003-2006, Ullrich von Bassewitz * -;* Römerstrasse 52 * +;* Roemerstrasse 52 * ;* D-70794 Filderstadt * ;*EMail: uz@cc65.org * ;* * diff --git a/asminc/stdio.inc b/asminc/stdio.inc index 3b22c47f6..c727e8d0b 100644 --- a/asminc/stdio.inc +++ b/asminc/stdio.inc @@ -7,7 +7,7 @@ ;* */ ;* */ ;* (C) 2003-2005, Ullrich von Bassewitz */ -;* Römerstrasse 52 */ +;* Roemerstrasse 52 */ ;* D-70794 Filderstadt */ ;* EMail: uz@cc65.org */ ;* */ diff --git a/asminc/utsname.inc b/asminc/utsname.inc index 6e2289244..2c7052ce1 100644 --- a/asminc/utsname.inc +++ b/asminc/utsname.inc @@ -7,7 +7,7 @@ ;/* */ ;/* */ ;/* (C) 2003 Ullrich von Bassewitz */ -;/* Römerstrasse 52 */ +;/* Roemerstrasse 52 */ ;/* D-70794 Filderstadt */ ;/* EMail: uz@cc65.org */ ;/* */ diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ From 080cb1bac9b748810e528db62b74fca9394db4d0 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 23 Apr 2021 21:52:36 +0200 Subject: [PATCH 1999/2161] added testcase for issue #1462 --- test/todo/bug1462.c | 67 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 test/todo/bug1462.c diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include <stdio.h> + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + From 4866ee53e69767aa911b4ab94738c5430ea98a0a Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 24 Apr 2021 13:20:10 -0400 Subject: [PATCH 2000/2161] Moved some Assembly function descriptions out of the "Control commands" section, and into the "Pseudo functions" section. --- doc/ca65.sgml | 144 +++++++++++++++++++++++++------------------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index f3a3c218f..137404919 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1353,15 +1353,15 @@ writable. <sect>Pseudo functions<label id="pseudo-functions"><p> -Pseudo functions expect their arguments in parenthesis, and they have a result, -either a string or an expression. +Pseudo functions expect their arguments in parentheses, and they have a result, +either a string or an expression value. <sect1><tt>.ADDRSIZE</tt><label id=".ADDRSIZE"><p> - The <tt/.ADDRSIZE/ function is used to return the interal address size + The <tt/.ADDRSIZE/ function is used to return the internal address size associated with a symbol. This can be helpful in macros when knowing the address - size of symbol can help with custom instructions. + size of a symbol can help with custom instructions. Example: @@ -1389,7 +1389,7 @@ either a string or an expression. <sect1><tt>.BANK</tt><label id=".BANK"><p> The <tt/.BANK/ function is used to support systems with banked memory. The - argument is an expression with exactly one segment reference - usually a + argument is an expression with exactly one segment reference -- usually a label. The function result is the value of the <tt/bank/ attribute assigned to the run memory area of the segment. Please see the linker documentation for more information about memory areas and their attributes. @@ -1397,13 +1397,13 @@ either a string or an expression. The value of <tt/.BANK/ can be used to switch memory so that a memory bank containing specific data is available. - The <tt/bank/ attribute is a 32 bit integer and so is the result of the + The <tt/bank/ attribute is a 32-bit integer, and so is the result of the <tt/.BANK/ function. You will have to use <tt><ref id=".LOBYTE" name=".LOBYTE"></tt> or similar functions to address just part of it. - Please note that <tt/.BANK/ will always get evaluated in the link stage, so - an expression containing <tt/.BANK/ can never be used where a constant known - result is expected (for example with <tt/.RES/). + Please note that <tt/.BANK/ always will get evaluated in the link stage, so + an expression containing <tt/.BANK/ never can be used where a constant, known + result is expected (for example, with <tt/.RES/). Example: @@ -1440,7 +1440,7 @@ either a string or an expression. <sect1><tt>.BLANK</tt><label id=".BLANK"><p> - Builtin function. The function evaluates its argument in braces and yields + Builtin function. The function evaluates its argument in parentheses and yields "false" if the argument is non blank (there is an argument), and "true" if there is no argument. The token list that makes up the function argument may optionally be enclosed in curly braces. This allows the inclusion of @@ -1479,7 +1479,7 @@ either a string or an expression. <sect1><tt>.CONST</tt><label id=".CONST"><p> - Builtin function. The function evaluates its argument in braces and + Builtin function. The function evaluates its argument in parentheses and yields "true" if the argument is a constant expression (that is, an expression that yields a constant value at assembly time) and "false" otherwise. As an example, the .IFCONST statement may be replaced by @@ -1489,6 +1489,41 @@ either a string or an expression. </verb></tscreen> +<sect1><tt>.DEF, .DEFINED</tt><label id=".DEFINED"><p> + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is a symbol that already is defined somewhere in the source file up to the + current position. Otherwise, the function yields false. As an example, the + <tt><ref id=".IFDEF" name=".IFDEF"></tt> statement may be replaced by + + <tscreen><verb> + .if .defined(a) + </verb></tscreen> + + +<sect1><tt>.DEFINEDMACRO</tt><label id=".DEFINEDMACRO"><p> + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + already has been defined as the name of a macro. Otherwise, the function yields + false. Example: + + <tscreen><verb> + .macro add foo + clc + adc foo + .endmacro + + .if .definedmacro(add) + add #$01 + .else + clc + adc #$01 + .endif + </verb></tscreen> + + <sect1><tt>.HIBYTE</tt><label id=".HIBYTE"><p> The function returns the high byte (that is, bits 8-15) of its argument. @@ -1525,6 +1560,23 @@ either a string or an expression. </verb></tscreen> +<sect1><tt>.ISMNEM, .ISMNEMONIC</tt><label id=".ISMNEMONIC"><p> + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is defined as an instruction mnemonic that is recognized by the assembler. + Example: + + <tscreen><verb> + .if .not .ismnemonic(ina) + .macro ina + clc + adc #$01 + .endmacro + .endif + </verb></tscreen> + + <sect1><tt>.LEFT</tt><label id=".LEFT"><p> Builtin function. Extracts the left part of a given token list. @@ -1719,7 +1771,7 @@ either a string or an expression. <sect1><tt>.REF, .REFERENCED</tt><label id=".REFERENCED"><p> - Builtin function. The function expects an identifier as argument in braces. + Builtin function. The function expects an identifier as argument in parentheses. The argument is evaluated, and the function yields "true" if the identifier is a symbol that has already been referenced somewhere in the source file up to the current position. Otherwise the function yields false. As an example, @@ -1865,7 +1917,7 @@ either a string or an expression. <sect1><tt>.STRING</tt><label id=".STRING"><p> - Builtin function. The function accepts an argument in braces and converts + Builtin function. The function accepts an argument in parentheses and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value. @@ -1884,7 +1936,7 @@ either a string or an expression. <sect1><tt>.STRLEN</tt><label id=".STRLEN"><p> - Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. <sect1><tt>.TCOUNT</tt><label id=".TCOUNT"><p> - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2366,7 +2418,7 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH Start a define style macro definition. The command is followed by an identifier (the macro name) and optionally by a list of formal arguments - in braces. + in parentheses. Please note that <tt/.DEFINE/ shares most disadvantages with its C counterpart, so the general advice is, <bf/NOT/ do use <tt/.DEFINE/ if you @@ -2390,41 +2442,6 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH See also section <ref id="macros" name="Macros">. -<sect1><tt>.DEF, .DEFINED</tt><label id=".DEFINED"><p> - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - is a symbol that is already defined somewhere in the source file up to the - current position. Otherwise the function yields false. As an example, the - <tt><ref id=".IFDEF" name=".IFDEF"></tt> statement may be replaced by - - <tscreen><verb> - .if .defined(a) - </verb></tscreen> - - -<sect1><tt>.DEFINEDMACRO</tt><label id=".DEFINEDMACRO"><p> - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - has already been defined as the name of a macro. Otherwise the function yields - false. Example: - - <tscreen><verb> - .macro add foo - clc - adc foo - .endmacro - - .if .definedmacro(add) - add #$01 - .else - clc - adc #$01 - .endif - </verb></tscreen> - - <sect1><tt>.DESTRUCTOR</tt><label id=".DESTRUCTOR"><p> Export a symbol and mark it as a module destructor. This may be used @@ -3294,23 +3311,6 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH the feature in more detail. -<sect1><tt>.ISMNEM, .ISMNEMONIC</tt><label id=".ISMNEMONIC"><p> - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - is defined as an instruction mnemonic that is recognized by the assembler. - Example: - - <tscreen><verb> - .if .not .ismnemonic(ina) - .macro ina - clc - adc #$01 - .endmacro - .endif - </verb></tscreen> - - <sect1><tt>.LINECONT</tt><label id=".LINECONT"><p> Switch on or off line continuations using the backslash character @@ -4399,8 +4399,8 @@ different: For this macro type, the number of actual parameters must match exactly the number of formal parameters. - To make this possible, formal parameters are enclosed in braces when - defining the macro. If there are no parameters, the empty braces may + To make this possible, formal parameters are enclosed in parentheses when + defining the macro. If there are no parameters, the empty parentheses may be omitted. <item> Since <tt><ref id=".DEFINE" name=".DEFINE"></tt> style macros may not @@ -4450,8 +4450,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that From 1f4ce4184607dcc530db5f7577ae219874079532 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 24 Apr 2021 13:48:42 -0400 Subject: [PATCH 2001/2161] Fixed the alphabetic sorting of the "Pseudo functions" section. --- doc/ca65.sgml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 137404919..b6d577472 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1878,24 +1878,6 @@ either a string or an expression value. </descrip> -<sect1><tt>.STRAT</tt><label id=".STRAT"><p> - - Builtin function. The function accepts a string and an index as - arguments and returns the value of the character at the given position - as an integer value. The index is zero based. - - Example: - - <tscreen><verb> - .macro M Arg - ; Check if the argument string starts with '#' - .if (.strat (Arg, 0) = '#') - ... - .endif - .endmacro - </verb></tscreen> - - <sect1><tt>.SPRINTF</tt><label id=".SPRINTF"><p> Builtin function. It expects a format string as first argument. The number @@ -1915,6 +1897,24 @@ either a string or an expression value. </verb></tscreen> +<sect1><tt>.STRAT</tt><label id=".STRAT"><p> + + Builtin function. The function accepts a string and an index as + arguments and returns the value of the character at the given position + as an integer value. The index is zero based. + + Example: + + <tscreen><verb> + .macro M Arg + ; Check if the argument string starts with '#' + .if (.strat (Arg, 0) = '#') + ... + .endif + .endmacro + </verb></tscreen> + + <sect1><tt>.STRING</tt><label id=".STRING"><p> Builtin function. The function accepts an argument in parentheses and converts From 71bd6415d6e203f941f200ceb5b8764aafe155fe Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 17 Apr 2021 16:50:59 +0800 Subject: [PATCH 2002/2161] No more unnecessary jump-over labels generated for logical OR false cases. --- src/cc65/expr.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index c0a9081f9..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3757,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3884,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ From f3663b8d2e8b1f9d035fd612865379aed23730bd Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 28 Apr 2021 14:21:48 +0200 Subject: [PATCH 2003/2161] added test for issue #1461 --- test/val/pr1461.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 test/val/pr1461.c diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include <stdlib.h> +#include <stdio.h> + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +} From e9a72b2462936fb929617766218b85bc7834c3b6 Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky <me@veg.by> Date: Sat, 24 Apr 2021 16:34:21 +0300 Subject: [PATCH 2004/2161] Add .REF control command implementation. --- src/ca65/pseudo.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 7e24d814d..971faf2a8 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1730,6 +1730,18 @@ static void DoPushSeg (void) +static void DoReferenced (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) + { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2153,7 +2165,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, - { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferenced }, /* .REFERENCED */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, From 83e7c372775b8594bd0069116511fcddfbcf98d0 Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky <me@veg.by> Date: Sat, 24 Apr 2021 20:51:11 +0300 Subject: [PATCH 2005/2161] Use .REFERTO instead of .REF as the command. --- src/ca65/pseudo.c | 5 +++-- src/ca65/scanner.c | 1 + src/ca65/token.h | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 971faf2a8..0c9e623a1 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1730,7 +1730,7 @@ static void DoPushSeg (void) -static void DoReferenced (void) +static void DoReferTo (void) /* Mark given symbol as referenced */ { SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); @@ -2165,7 +2165,8 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, - { ccNone, DoReferenced }, /* .REFERENCED */ + { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 0a7d433b2..2c099a517 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -271,6 +271,7 @@ struct DotKeyword { { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/token.h b/src/ca65/token.h index 02fc8d491..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -241,6 +241,7 @@ typedef enum token_t { TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, From 50a58e77067f6653a283ada6c680ef6189593bd0 Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky <me@veg.by> Date: Sat, 24 Apr 2021 21:26:52 +0300 Subject: [PATCH 2006/2161] Added documentation for the .REFERTO. --- doc/ca65.sgml | 30 +++++++++++++++++++++++++++++- src/ca65/pseudo.c | 3 +-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index b6d577472..978aaf159 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -3213,7 +3213,8 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH .endif </verb></tscreen> - See also: <tt><ref id=".REFERENCED" name=".REFERENCED"></tt> + See also: <tt><ref id=".REFERENCED" name=".REFERENCED"></tt>, and + <tt><ref id=".REFERTO" name=".REFERTO"></tt> <sect1><tt>.IMPORT</tt><label id=".IMPORT"><p> @@ -3764,6 +3765,33 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" See: <tt><ref id=".POPSEG" name=".POPSEG"></tt> +<sect1><tt>.REFERTO</tt><label id=".REFERTO"><p> + + Mark a symbol as referenced. + + It is useful in combination with the <tt><ref id=".IFREF" name=".IFREF"></tt> + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. <tt>.REFERTO</tt> helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + <tscreen><verb> + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .referto SetValue ; Ensure that SetValue will be included + .endif + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + </verb></tscreen> + + <sect1><tt>.RELOC</tt><label id=".RELOC"><p> Switch back to relocatable mode. See the <tt><ref id=".ORG" diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 0c9e623a1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1734,8 +1734,7 @@ static void DoReferTo (void) /* Mark given symbol as referenced */ { SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); - if (Sym) - { + if (Sym) { SymRef (Sym); } } From 8e02f8f5ec110ca6adff138d52fb85873cd44ad5 Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky <me@veg.by> Date: Wed, 28 Apr 2021 21:38:23 +0300 Subject: [PATCH 2007/2161] Add .REFTO as an alias to .REFERTO. Update the docs related to it. --- doc/ca65.sgml | 17 +++++++++++++++-- src/ca65/scanner.c | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 978aaf159..3fc534066 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -3765,7 +3765,7 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" See: <tt><ref id=".POPSEG" name=".POPSEG"></tt> -<sect1><tt>.REFERTO</tt><label id=".REFERTO"><p> +<sect1><tt>.REFERTO, .REFTO</tt><label id=".REFERTO"><p> Mark a symbol as referenced. @@ -3779,11 +3779,24 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" Example: <tscreen><verb> + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + .ifref ResetValue ; If this subroutine is used ResetValue: ; Define it lda #0 ; Set a default value - .referto SetValue ; Ensure that SetValue will be included + .refto SetValue ; Ensure that SetValue will be included .endif + .ifref SetValue ; If this or previous subroutine is used SetValue: sta Value diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 2c099a517..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -272,6 +272,7 @@ struct DotKeyword { { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, From b9a3c7888822732a0de92741cfe1a3e1b6bb272f Mon Sep 17 00:00:00 2001 From: Marco Aurelio da Costa <costa@gamic.com> Date: Mon, 26 Apr 2021 13:30:54 -0300 Subject: [PATCH 2008/2161] Parse file included inside a macro at definition time --- src/ca65/macro.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..56791eb66 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -510,6 +510,22 @@ void MacDef (unsigned Style) } } + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for a .LOCAL declaration */ if (CurTok.Tok == TOK_LOCAL && Style == MAC_STYLE_CLASSIC) { From 04cd884f8f08e98cd9826287d2d272a23f68510f Mon Sep 17 00:00:00 2001 From: Marco Aurelio da Costa <costa@gamic.com> Date: Tue, 27 Apr 2021 08:21:06 -0300 Subject: [PATCH 2009/2161] Prevent missed .ENDMACRO in included file --- src/ca65/macro.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 56791eb66..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ @@ -510,22 +527,6 @@ void MacDef (unsigned Style) } } - if (CurTok.Tok == TOK_INCLUDE) { - /* Include another file */ - NextTok (); - /* Name must follow */ - if (CurTok.Tok != TOK_STRCON) { - ErrorSkip ("String constant expected"); - } else { - SB_Terminate (&CurTok.SVal); - if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { - /* Error opening the file, skip remainder of line */ - SkipUntilSep (); - } - } - NextTok (); - } - /* Check for a .LOCAL declaration */ if (CurTok.Tok == TOK_LOCAL && Style == MAC_STYLE_CLASSIC) { From 216bb22b20e67f6ab12a74ad3a15f8bc13151c39 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Tue, 4 May 2021 11:54:06 -0400 Subject: [PATCH 2010/2161] Added a special version of a function which uses an absolute addressing mode to access the zero page. The PCEngine needs such operands to be redirected to RAM page $20 explicitly. Fixes #1482; fixes #1483. --- libsrc/common/_printf.s | 49 ++- libsrc/pce/_printf.s | 791 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 814 insertions(+), 26 deletions(-) create mode 100644 libsrc/pce/_printf.s diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #<CharArg + ldx #>CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #<Buf + ldx #>Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #<Buf + stx Str + ldx #>Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 From c9f242e566f5a86c0bf4809aa5f1e2ddbc617b63 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 5 May 2021 14:42:29 +0200 Subject: [PATCH 2011/2161] Extend #pragma wrapped-call to support "bank" argument --- src/cc65/declare.c | 4 +++- src/cc65/expr.c | 13 ++++++++++--- src/cc65/funcdesc.h | 1 + src/cc65/pragma.c | 10 +++++++--- src/cc65/wrappedcall.c | 9 +++++---- src/cc65/wrappedcall.h | 4 ++-- 6 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0868c2082..0b705a320 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1739,6 +1739,7 @@ static FuncDesc* ParseFuncDecl (void) SymEntry* Sym; SymEntry* WrappedCall; unsigned char WrappedCallData; + int WrappedCallUseBank; /* Create a new function descriptor */ FuncDesc* F = NewFuncDesc (); @@ -1791,10 +1792,11 @@ static FuncDesc* ParseFuncDecl (void) RememberFunctionLevel (F); /* Did we have a WrappedCall for this function? */ - GetWrappedCall((void **) &WrappedCall, &WrappedCallData); + GetWrappedCall((void **) &WrappedCall, &WrappedCallData, &WrappedCallUseBank); if (WrappedCall) { F->WrappedCall = WrappedCall; F->WrappedCallData = WrappedCallData; + F->WrappedCallUseBank = WrappedCallUseBank; } /* Return the function descriptor */ diff --git a/src/cc65/expr.c b/src/cc65/expr.c index bc277f13b..d2cd4ca5c 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -997,9 +997,16 @@ static void FunctionCall (ExprDesc* Expr) char tmp[64]; StrBuf S = AUTO_STRBUF_INITIALIZER; - /* Store the WrappedCall data in tmp4 */ - sprintf(tmp, "ldy #%u", Func->WrappedCallData); - SB_AppendStr (&S, tmp); + if (Func->WrappedCallUseBank) { + /* 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); + SB_AppendStr (&S, tmp); + } g_asmcode (&S); SB_Clear(&S); diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h index 423e7621f..5875723fb 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -72,6 +72,7 @@ struct FuncDesc { struct FuncDesc* FuncDef; /* Descriptor used in definition */ struct SymEntry* WrappedCall; /* Pointer to the WrappedCall */ unsigned char WrappedCallData;/* The WrappedCall's user data */ + int WrappedCallUseBank;/* Flag: does WrappedCall use .bank() or literal value */ }; diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index f0f7ed36f..249e4f1b4 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -497,6 +497,7 @@ static void WrappedCallPragma (StrBuf* B) const char *Name; long Val; SymEntry *Entry; + int UseBank = 0; /* Check for the "push" or "pop" keywords */ switch (ParsePushPop (B)) { @@ -535,12 +536,15 @@ static void WrappedCallPragma (StrBuf* B) goto ExitPoint; } - if (!GetNumber (B, &Val)) { + /* Next must be either a numeric value, or "bank" */ + if (HasStr (B, "bank")) { + UseBank = 1; + } else if (!GetNumber (B, &Val)) { Error ("Value required for wrapped-call identifier"); goto ExitPoint; } - if (Val < 0 || Val > 255) { + if (!UseBank && (Val < 0 || Val > 255)) { Error ("Identifier must be between 0-255"); goto ExitPoint; } @@ -552,7 +556,7 @@ static void WrappedCallPragma (StrBuf* B) /* Check if the name is valid */ if (Entry && (Entry->Flags & SC_FUNC) == SC_FUNC) { - PushWrappedCall(Entry, (unsigned char) Val); + PushWrappedCall(Entry, (unsigned char) Val, UseBank); Entry->Flags |= SC_REF; GetFuncDesc (Entry->Type)->Flags |= FD_CALL_WRAPPER; diff --git a/src/cc65/wrappedcall.c b/src/cc65/wrappedcall.c index 18cb507ac..a67f9815d 100644 --- a/src/cc65/wrappedcall.c +++ b/src/cc65/wrappedcall.c @@ -64,13 +64,13 @@ static IntPtrStack WrappedCalls; -void PushWrappedCall (void *Ptr, unsigned char Val) +void PushWrappedCall (void *Ptr, unsigned char Val, int UseBank) /* Push the current WrappedCall */ { if (IPS_IsFull (&WrappedCalls)) { Error ("WrappedCall stack overflow"); } else { - IPS_Push (&WrappedCalls, Val, Ptr); + IPS_Push (&WrappedCalls, Val | (UseBank << 8), Ptr); } } @@ -88,7 +88,7 @@ void PopWrappedCall (void) -void GetWrappedCall (void **Ptr, unsigned char *Val) +void GetWrappedCall (void **Ptr, unsigned char *Val, int *UseBank) /* Get the current WrappedCall */ { if (IPS_GetCount (&WrappedCalls) < 1) { @@ -97,6 +97,7 @@ void GetWrappedCall (void **Ptr, unsigned char *Val) } else { long Temp; IPS_Get (&WrappedCalls, &Temp, Ptr); - *Val = (unsigned char) Temp; + *UseBank = (int) Temp >> 8; + *Val = (unsigned char) Temp & 0xff; } } diff --git a/src/cc65/wrappedcall.h b/src/cc65/wrappedcall.h index 3517c2465..ddf6dd2b9 100644 --- a/src/cc65/wrappedcall.h +++ b/src/cc65/wrappedcall.h @@ -50,13 +50,13 @@ -void PushWrappedCall (void *Ptr, unsigned char Val); +void PushWrappedCall (void *Ptr, unsigned char Val, int usebank); /* Push the current WrappedCall */ void PopWrappedCall (void); /* Pop the current WrappedCall */ -void GetWrappedCall (void **Ptr, unsigned char *Val); +void GetWrappedCall (void **Ptr, unsigned char *Val, int *usebank); /* Get the current WrappedCall, if any */ From 729690e9e97a9eefa06d744fb1762caa3351f548 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 5 May 2021 16:07:47 +0200 Subject: [PATCH 2012/2161] document the wrapped-call extension --- doc/cc65.sgml | 5 ++++- doc/ld65.sgml | 3 +-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index dc754cb31..f4b31b8bc 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1388,7 +1388,10 @@ parameter with the <tt/#pragma/. the <tt/Y/ register if it wraps any variadic functions (they have "<tt/.../" in their prototypes). - The identifier is an 8-bit number that's set into <tt/tmp4/. + The identifier is an 8-bit number that's set into <tt/tmp4/. If the identifier + is "bank", then a <tt><htmlurl url="ca65.html#.BANK" name=".bank"></tt> operator will be used + to determine the number from the bank attribute defined in the linker config, + see <htmlurl url="ld65.html#MEMORY" name="Other MEMORY area attributes">. The address of a wrapped function is passed in <tt/ptr4/. The wrapper can call that function by using "<tt/jsr callptr4/". diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 538948fc0..56d77ca63 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -760,7 +760,7 @@ There's a library subroutine called <tt/copydata/ (in a module named look at it's inner workings before using it! -<sect1>Other MEMORY area attributes<p> +<sect1>Other MEMORY area attributes<label id="MEMORY"><p> There are some other attributes not covered above. Before starting the reference section, I will discuss the remaining things here. @@ -822,7 +822,6 @@ that has a segment reference (for example a symbol). The result of this function is the value of the bank attribute for the run memory area of the segment. - <sect1>Other SEGMENT attributes<p> Segments may be aligned to some memory boundary. Specify "<tt/align = num/" to From 0fbf2af09d9cdff1f73a47d79b7735258db4a34b Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 7 May 2021 18:38:26 +0200 Subject: [PATCH 2013/2161] Fix the warning that is produced for unused functions --- src/cc65/error.c | 2 ++ src/cc65/error.h | 1 + src/cc65/symtab.c | 4 ++++ 3 files changed, 7 insertions(+) diff --git a/src/cc65/error.c b/src/cc65/error.c index 0118d50b8..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -78,6 +78,7 @@ IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -97,6 +98,7 @@ static WarnMapEntry WarnMap[] = { { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, diff --git a/src/cc65/error.h b/src/cc65/error.h index 31c46f513..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -75,6 +75,7 @@ extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); From 3ea330f15fb3829dcab038647dd930481d51b7d1 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 7 May 2021 21:32:04 +0200 Subject: [PATCH 2014/2161] update docs --- doc/cc65.sgml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index dc754cb31..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -563,6 +563,8 @@ Here is a description of all the command line options: Warn about #pragmas that aren't recognized by cc65. <tag><tt/unreachable-code/</tag> Warn about unreachable code in cases of comparing constants, etc. + <tag><tt/unused-func/</tag> + Warn about unused functions. <tag><tt/unused-label/</tag> Warn about unused labels. <tag><tt/unused-param/</tag> From 4c37f12a4d5a35e113a59b9f8299801f616564da Mon Sep 17 00:00:00 2001 From: Polluks <polluks@sdf.lonestar.org> Date: Sat, 8 May 2021 18:23:19 +0200 Subject: [PATCH 2015/2161] Optimised strlen --- libsrc/common/strlen.s | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libsrc/common/strlen.s b/libsrc/common/strlen.s index e89039179..8d5bc20fc 100644 --- a/libsrc/common/strlen.s +++ b/libsrc/common/strlen.s @@ -5,17 +5,27 @@ ; the usage of only ptr2 here! Keep in mind when appling changes ; and check the other implementations too! ; -; int strlen (const char* s); +; size_t __fastcall__ strlen (const char* s); ; .export _strlen .importzp ptr2 + .macpack cpu _strlen: sta ptr2 ; Save s stx ptr2+1 +.if (.cpu .bitand ::CPU_ISET_HUC6280) + clx + cly +.else ldx #0 ; YX used as counter +.if (.cpu .bitand ::CPU_ISET_65816) + txy +.else ldy #0 +.endif +.endif L1: lda (ptr2),y beq L9 From b1f81d5e21c1965b9d1592d1c20b0c2940edc9e3 Mon Sep 17 00:00:00 2001 From: polluks2 <74630735+polluks2@users.noreply.github.com> Date: Sat, 8 May 2021 16:50:08 +0000 Subject: [PATCH 2016/2161] Optimised code --- libsrc/atari5200/y2k.inc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libsrc/atari5200/y2k.inc b/libsrc/atari5200/y2k.inc index a44d027a1..f8531451c 100644 --- a/libsrc/atari5200/y2k.inc +++ b/libsrc/atari5200/y2k.inc @@ -32,10 +32,8 @@ Y2K3 STA $0732,X LDA #$60 ; Store RTS opcode @ end STA $0750 JSR $0600 ; Show title screen - LDY #$00 ; Clear RAM from $0600-$3FFF + LDY #<$0600 ; Clear RAM from $0600-$3FFF STY $80 - LDA #$06 + LDA #>$0600 STA $81 - JSR CLRRAM - RTS - + JMP CLRRAM From 07bd5089ec502a4aab1e2cfd381ba8a7d86d22c8 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 9 May 2021 19:27:33 +0200 Subject: [PATCH 2017/2161] Define CLOCKS_PER_SEC as _clocks_per_sec() if _clocks_per_sec() is actually available. There are programs checking for the existence of CLOCKS_PER_SEC before usage. We don't want to mislead them. --- include/time.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/time.h b/include/time.h index 49d7e6870..92cbeee37 100644 --- a/include/time.h +++ b/include/time.h @@ -98,11 +98,11 @@ extern struct _timezone { # define CLOCKS_PER_SEC 50 #elif defined(__PCE__) # define CLOCKS_PER_SEC 60 -#elif defined(__GAMATE__) +#elif defined(__GAMATE__) # define CLOCKS_PER_SEC 135 /* FIXME */ -#elif defined(__GEOS__) +#elif defined(__GEOS__) # define CLOCKS_PER_SEC 1 -#else +#elif defined(__ATARI__) || defined (__LYNX__) /* Read the clock rate at runtime */ clock_t _clocks_per_sec (void); # define CLOCKS_PER_SEC _clocks_per_sec() From 6e79379405f09d3c51765db44a16c69b28289797 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Sun, 9 May 2021 16:34:53 -0500 Subject: [PATCH 2018/2161] Synertek Systems Sym-1 machine-specific files --- libsrc/sym1/beep.s | 24 ++ libsrc/sym1/bitio.s | 230 +++++++++++++++++ libsrc/sym1/crt0.s | 65 +++++ libsrc/sym1/display.s | 154 ++++++++++++ libsrc/sym1/getchar.s | 21 ++ libsrc/sym1/libref.s | 3 + libsrc/sym1/putchar.s | 23 ++ libsrc/sym1/read.s | 54 ++++ libsrc/sym1/tapeio.s | 58 +++++ libsrc/sym1/write.s | 53 ++++ samples/symDisplay.c | 384 +++++++++++++++++++++++++++++ samples/symHello.c | 39 +++ samples/symIO.c | 170 +++++++++++++ samples/symTiny.c | 42 ++++ samples/tutorial/sym1/build | 36 +++ samples/tutorial/sym1/build_32k | 36 +++ samples/tutorial/sym1/build_4k | 36 +++ samples/tutorial/sym1/clean | 14 ++ samples/tutorial/sym1/readme.txt | 11 + samples/tutorial/sym1/symDisplay.c | 384 +++++++++++++++++++++++++++++ samples/tutorial/sym1/symHello.c | 39 +++ samples/tutorial/sym1/symIO.c | 170 +++++++++++++ samples/tutorial/sym1/symTiny.c | 42 ++++ 23 files changed, 2088 insertions(+) create mode 100644 libsrc/sym1/beep.s create mode 100644 libsrc/sym1/bitio.s create mode 100644 libsrc/sym1/crt0.s create mode 100644 libsrc/sym1/display.s create mode 100644 libsrc/sym1/getchar.s create mode 100644 libsrc/sym1/libref.s create mode 100644 libsrc/sym1/putchar.s create mode 100644 libsrc/sym1/read.s create mode 100644 libsrc/sym1/tapeio.s create mode 100644 libsrc/sym1/write.s create mode 100644 samples/symDisplay.c create mode 100644 samples/symHello.c create mode 100644 samples/symIO.c create mode 100644 samples/symTiny.c create mode 100644 samples/tutorial/sym1/build create mode 100644 samples/tutorial/sym1/build_32k create mode 100644 samples/tutorial/sym1/build_4k create mode 100644 samples/tutorial/sym1/clean create mode 100644 samples/tutorial/sym1/readme.txt create mode 100644 samples/tutorial/sym1/symDisplay.c create mode 100644 samples/tutorial/sym1/symHello.c create mode 100644 samples/tutorial/sym1/symIO.c create mode 100644 samples/tutorial/sym1/symTiny.c diff --git a/libsrc/sym1/beep.s b/libsrc/sym1/beep.s new file mode 100644 index 000000000..a1f978563 --- /dev/null +++ b/libsrc/sym1/beep.s @@ -0,0 +1,24 @@ +; --------------------------------------------------------------------------- +; beep.s +; +; for Sym-1 +; +; Wayne Parham +; +; wayne@parhamdata.com +; --------------------------------------------------------------------------- + +.include "sym1.inc" + +.export _beep + +.segment "CODE" + +.proc _beep: near +; --------------------------------------------------------------------------- + jsr BEEP ; Beep + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc diff --git a/libsrc/sym1/bitio.s b/libsrc/sym1/bitio.s new file mode 100644 index 000000000..5aa0fde8b --- /dev/null +++ b/libsrc/sym1/bitio.s @@ -0,0 +1,230 @@ +; --------------------------------------------------------------------------- +; bitio.s +; +; for Sym-1 +; +; Wayne Parham +; +; wayne@parhamdata.com +; --------------------------------------------------------------------------- + +.include "sym1.inc" + +.export _set_DDR1A, _get_DDR1A, _set_IOR1A, _get_IOR1A +.export _set_DDR1B, _get_DDR1B, _set_IOR1B, _get_IOR1B +.export _set_DDR2A, _get_DDR2A, _set_IOR2A, _get_IOR2A +.export _set_DDR2B, _get_DDR2B, _set_IOR2B, _get_IOR2B +.export _set_DDR3A, _get_DDR3A, _set_IOR3A, _get_IOR3A +.export _set_DDR3B, _get_DDR3B, _set_IOR3B, _get_IOR3B + +.segment "CODE" + +.proc _set_DDR1A: near +; --------------------------------------------------------------------------- + sta DDR1A ; Write data direction register for port 1A + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_DDR1A: near +; --------------------------------------------------------------------------- + lda DDR1A ; Read data direction register for port 1A + ldx #$00 ; + rts ; Return DDR1A +; --------------------------------------------------------------------------- +.endproc + +.proc _set_IOR1A: near +; --------------------------------------------------------------------------- + sta OR1A ; Write I/O register for port 1A + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_IOR1A: near +; --------------------------------------------------------------------------- + lda OR1A ; Read I/O register for port 1A + ldx #$00 ; + rts ; Return OR1A +; --------------------------------------------------------------------------- +.endproc + + +.proc _set_DDR1B: near +; --------------------------------------------------------------------------- + sta DDR1B ; Write data direction register for port 1B + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_DDR1B: near +; --------------------------------------------------------------------------- + lda DDR1B ; Read data direction register for port 1B + ldx #$00 ; + rts ; Return DDR1B +; --------------------------------------------------------------------------- +.endproc + +.proc _set_IOR1B: near +; --------------------------------------------------------------------------- + sta OR1B ; Write I/O register for port 1B + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_IOR1B: near +; --------------------------------------------------------------------------- + lda OR1B ; Read I/O register for port 1B + ldx #$00 ; + rts ; Return OR1B +; --------------------------------------------------------------------------- +.endproc + + +.proc _set_DDR2A: near +; --------------------------------------------------------------------------- + sta DDR2A ; Write data direction register for port 2A + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_DDR2A: near +; --------------------------------------------------------------------------- + lda DDR2A ; Read data direction register for port 2A + ldx #$00 ; + rts ; Return DDR2A +; --------------------------------------------------------------------------- +.endproc + +.proc _set_IOR2A: near +; --------------------------------------------------------------------------- + sta OR2A ; Write I/O register for port 2A + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_IOR2A: near +; --------------------------------------------------------------------------- + lda OR2A ; Read I/O register for port 2A + ldx #$00 ; + rts ; Return OR2A +; --------------------------------------------------------------------------- +.endproc + + +.proc _set_DDR2B: near +; --------------------------------------------------------------------------- + sta DDR2B ; Write data direction register for port 2B + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_DDR2B: near +; --------------------------------------------------------------------------- + lda DDR2B ; Read data direction register for port 2B + ldx #$00 ; + rts ; Return DDR2B +; --------------------------------------------------------------------------- +.endproc + +.proc _set_IOR2B: near +; --------------------------------------------------------------------------- + sta OR2B ; Write I/O register for port 2B + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_IOR2B: near +; --------------------------------------------------------------------------- + lda OR2B ; Read I/O register for port 2B + ldx #$00 ; + rts ; Return OR2B +; --------------------------------------------------------------------------- +.endproc + + +.proc _set_DDR3A: near +; --------------------------------------------------------------------------- + sta DDR3A ; Write data direction register for port 3A + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_DDR3A: near +; --------------------------------------------------------------------------- + lda DDR3A ; Read data direction register for port 3A + ldx #$00 ; + rts ; Return DDR3A +; --------------------------------------------------------------------------- +.endproc + +.proc _set_IOR3A: near +; --------------------------------------------------------------------------- + sta OR3A ; Write I/O register for port 3A + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_IOR3A: near +; --------------------------------------------------------------------------- + lda OR3A ; Read I/O register for port 3A + ldx #$00 ; + rts ; Return OR3A +; --------------------------------------------------------------------------- +.endproc + + +.proc _set_DDR3B: near +; --------------------------------------------------------------------------- + sta DDR3B ; Write data direction register for port 3B + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_DDR3B: near +; --------------------------------------------------------------------------- + lda DDR3B ; Read data direction register for port 3B + ldx #$00 ; + rts ; Return DDR3B +; --------------------------------------------------------------------------- +.endproc + +.proc _set_IOR3B: near +; --------------------------------------------------------------------------- + sta OR3B ; Write I/O register for port 3B + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_IOR3B: near +; --------------------------------------------------------------------------- + lda OR3B ; Read I/O register for port 3B + ldx #$00 ; + rts ; Return OR3B +; --------------------------------------------------------------------------- +.endproc + diff --git a/libsrc/sym1/crt0.s b/libsrc/sym1/crt0.s new file mode 100644 index 000000000..a85887991 --- /dev/null +++ b/libsrc/sym1/crt0.s @@ -0,0 +1,65 @@ +; --------------------------------------------------------------------------- +; crt0.s +; +; for Sym-1 +; +; Wayne Parham +; +; wayne@parhamdata.com +; --------------------------------------------------------------------------- + + .export _init, _exit + .export __STARTUP__ : absolute = 1 ; Mark as startup + + .import _main + .import initlib, donelib, copydata, zerobss + .import __RAM_START__, __RAM_SIZE__ ; Linker generated + .import __STACKSIZE__ ; Linker generated + + .include "zeropage.inc" + .include "sym1.inc" + +; --------------------------------------------------------------------------- +; Place the startup code in a special segment + +.segment "STARTUP" + +; --------------------------------------------------------------------------- +; A little light housekeeping + +_init: jsr ACCESS ; Unlock System RAM + cld ; Clear decimal mode +; --------------------------------------------------------------------------- +; Turn off console echo + + lda TECHO + and #$7F + sta TECHO +; --------------------------------------------------------------------------- +; Set cc65 argument stack pointer + + lda #<(__RAM_START__ + __RAM_SIZE__) + sta sp + lda #>(__RAM_START__ + __RAM_SIZE__) + sta sp+1 +; --------------------------------------------------------------------------- +; Initialize memory storage + + jsr zerobss ; Clear BSS segment + jsr copydata ; Initialize DATA segment + jsr initlib ; Run constructors +; --------------------------------------------------------------------------- +; Call main() + + jsr _main +; --------------------------------------------------------------------------- +; Back from main (this is also the _exit entry) + +_exit: jsr donelib ; Run destructors + lda TECHO + ora #$80 ; Re-enable console echo + sta TECHO + jsr NACCES ; Lock System RAM + rts ; Re-enter Sym-1 monitor +; --------------------------------------------------------------------------- + diff --git a/libsrc/sym1/display.s b/libsrc/sym1/display.s new file mode 100644 index 000000000..530435d87 --- /dev/null +++ b/libsrc/sym1/display.s @@ -0,0 +1,154 @@ +; --------------------------------------------------------------------------- +; display.s +; +; for Sym-1 +; +; Wayne Parham +; +; wayne@parhamdata.com +; --------------------------------------------------------------------------- + +.include "sym1.inc" + +.export _fdisp, _set_D0, _get_D0 +.export _set_D1, _get_D1, _set_D2, _get_D2 +.export _set_D3, _get_D3, _set_D4, _get_D4 +.export _set_D5, _get_D5, _set_D6, _get_D6 + +.segment "CODE" + +.proc _fdisp: near +; --------------------------------------------------------------------------- + jsr SCAND ; Flash Display + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + + +.proc _set_D0: near +; --------------------------------------------------------------------------- + sta DISBUF0 ; Write Digit 0 + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_D0: near +; --------------------------------------------------------------------------- + lda DISBUF0 ; Read Digit 0 + ldx #$00 ; + rts ; Return DISBUF0 +; --------------------------------------------------------------------------- +.endproc + + +.proc _set_D1: near +; --------------------------------------------------------------------------- + sta DISBUF1 ; Write Digit 1 + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_D1: near +; --------------------------------------------------------------------------- + lda DISBUF1 ; Read Digit 1 + ldx #$00 ; + rts ; Return DISBUF1 +; --------------------------------------------------------------------------- +.endproc + + +.proc _set_D2: near +; --------------------------------------------------------------------------- + sta DISBUF2 ; Write Digit 2 + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_D2: near +; --------------------------------------------------------------------------- + lda DISBUF2 ; Read Digit 2 + ldx #$00 ; + rts ; Return DISBUF2 +; --------------------------------------------------------------------------- +.endproc + + +.proc _set_D3: near +; --------------------------------------------------------------------------- + sta DISBUF3 ; Write Digit 3 + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_D3: near +; --------------------------------------------------------------------------- + lda DISBUF3 ; Read Digit 3 + ldx #$00 ; + rts ; Return DISBUF3 +; --------------------------------------------------------------------------- +.endproc + + +.proc _set_D4: near +; --------------------------------------------------------------------------- + sta DISBUF4 ; Write Digit 4 + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_D4: near +; --------------------------------------------------------------------------- + lda DISBUF4 ; Read Digit 4 + ldx #$00 ; + rts ; Return DISBUF4 +; --------------------------------------------------------------------------- +.endproc + + +.proc _set_D5: near +; --------------------------------------------------------------------------- + sta DISBUF5 ; Write Digit 5 + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_D5: near +; --------------------------------------------------------------------------- + lda DISBUF5 ; Read Digit 5 + ldx #$00 ; + rts ; Return DISBUF5 +; --------------------------------------------------------------------------- +.endproc + + +.proc _set_D6: near +; --------------------------------------------------------------------------- + sta DISBUF6 ; Write byte to the right of display + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc + +.proc _get_D6: near +; --------------------------------------------------------------------------- + lda DISBUF6 ; Read byte to the right of display + ldx #$00 ; + rts ; Return DISBUF6 +; --------------------------------------------------------------------------- +.endproc + diff --git a/libsrc/sym1/getchar.s b/libsrc/sym1/getchar.s new file mode 100644 index 000000000..d82519ce0 --- /dev/null +++ b/libsrc/sym1/getchar.s @@ -0,0 +1,21 @@ +; --------------------------------------------------------------------------- +; getchar.s +; +; for Sym-1 +; +; Wayne Parham +; --------------------------------------------------------------------------- + +.include "sym1.inc" +.export _getchar + +.segment "CODE" + +.proc _getchar: near +; --------------------------------------------------------------------------- + jsr INTCHR ; Get character using Monitor ROM call + and #$7F ; Strip off top bit + ldx #$00 ; + rts ; Return char +; --------------------------------------------------------------------------- +.endproc diff --git a/libsrc/sym1/libref.s b/libsrc/sym1/libref.s new file mode 100644 index 000000000..9356d18dc --- /dev/null +++ b/libsrc/sym1/libref.s @@ -0,0 +1,3 @@ + + .import _exit + diff --git a/libsrc/sym1/putchar.s b/libsrc/sym1/putchar.s new file mode 100644 index 000000000..1b84416fe --- /dev/null +++ b/libsrc/sym1/putchar.s @@ -0,0 +1,23 @@ +; --------------------------------------------------------------------------- +; putchar.s +; +; for Sym-1 +; +; Wayne Parham +; +; wayne@parhamdata.com +; --------------------------------------------------------------------------- + +.include "sym1.inc" +.export _putchar + +.segment "CODE" + +.proc _putchar: near +; --------------------------------------------------------------------------- + jsr OUTCHR ; Send character using Monitor ROM call + lda #$00 ; + ldx #$00 ; + rts ; Return 0000 +; --------------------------------------------------------------------------- +.endproc diff --git a/libsrc/sym1/read.s b/libsrc/sym1/read.s new file mode 100644 index 000000000..f0b0194d2 --- /dev/null +++ b/libsrc/sym1/read.s @@ -0,0 +1,54 @@ +; --------------------------------------------------------------------------- +; read.s +; +; for Sym-1 +; +; Wayne Parham +; +; wayne@parhamdata.com +; --------------------------------------------------------------------------- + +.include "sym1.inc" + +.import popax, popptr1 +.importzp ptr1, ptr2, ptr3 + +.export _read + +.proc _read +; --------------------------------------------------------------------------- + sta ptr3 + stx ptr3+1 ; Count in ptr3 + inx + stx ptr2+1 ; Increment and store in ptr2 + tax + inx + stx ptr2 + jsr popptr1 ; Buffer address in ptr1 + jsr popax + +begin: dec ptr2 + bne getch + dec ptr2+1 + beq done ; If buffer full, return + +getch: jsr INTCHR ; Get character using Monitor ROM call + jsr OUTCHR ; Echo it + and #$7F ; Clear hi bit and check for '\r' + cmp #$0D + bne putch + lda #$0A ; Replace with '\n' and set count to zero + +putch: ldy #$00 ; Put char into return buffer + sta (ptr1),y + inc ptr1 ; Increment pointer + bne begin + inc ptr1+1 + bne begin + +done: lda ptr3 + ldx ptr3+1 + rts ; Return count +; --------------------------------------------------------------------------- +.endproc + diff --git a/libsrc/sym1/tapeio.s b/libsrc/sym1/tapeio.s new file mode 100644 index 000000000..3a0c1fa5b --- /dev/null +++ b/libsrc/sym1/tapeio.s @@ -0,0 +1,58 @@ +; --------------------------------------------------------------------------- +; tapeio.s +; +; for Sym-1 +; +; Wayne Parham +; +; wayne@parhamdata.com +; --------------------------------------------------------------------------- + +.include "sym1.inc" + +.import popax + +.export _loadt, _dumpt + +.segment "CODE" + +.proc _loadt: near +; --------------------------------------------------------------------------- + sta P1L ; Tape record ID to P1L + ldx #$00 + stx P1H + ldy #$80 + jsr LOADT ; Read data from tape + bcs error + lda #$00 + ldx #$00 ; Return 0000 if successful + jmp done +error: ldx #$00 + lda #$FF ; or 00FF if not +done: rts +; --------------------------------------------------------------------------- +.endproc + +.proc _dumpt: near +; --------------------------------------------------------------------------- + sta P3L ; End address + stx P3H + jsr popax + sta P2L ; Start address + stx P2H + jsr popax + sta P1L ; Tape Record ID + ldx #$00 + stx P1H + ldy #$80 + jsr DUMPT ; Write data to tape + bcs error + lda #$00 + ldx #$00 ; Return 0000 if successful + jmp done +error: ldx #$00 + lda #$FF ; or 00FF if not +done: rts +; --------------------------------------------------------------------------- +.endproc + diff --git a/libsrc/sym1/write.s b/libsrc/sym1/write.s new file mode 100644 index 000000000..843dddf1f --- /dev/null +++ b/libsrc/sym1/write.s @@ -0,0 +1,53 @@ +; --------------------------------------------------------------------------- +; write.s +; +; for Sym-1 +; +; Wayne Parham +; +; wayne@parhamdata.com +; --------------------------------------------------------------------------- + +.include "sym1.inc" + +.import popax, popptr1 +.importzp ptr1, ptr2, ptr3, tmp1 + +.export _write + +.proc _write +; --------------------------------------------------------------------------- + sta ptr3 + stx ptr3+1 ; Count in ptr3 + inx + stx ptr2+1 ; Increment and store in ptr2 + tax + inx + stx ptr2 + jsr popptr1 ; Buffer address in ptr1 + jsr popax + +begin: dec ptr2 + bne outch + dec ptr2+1 + beq done + +outch : ldy #0 + lda (ptr1),y + jsr OUTCHR ; Send character using Monitor call + cmp #$0A + bne next + lda #$0D ; If it is LF, add CR + jsr OUTCHR + +next: inc ptr1 + bne begin + inc ptr1+1 + jmp begin + +done: lda ptr3 + ldx ptr3+1 + rts ; Return count +; --------------------------------------------------------------------------- +.endproc + diff --git a/samples/symDisplay.c b/samples/symDisplay.c new file mode 100644 index 000000000..41eaf8b49 --- /dev/null +++ b/samples/symDisplay.c @@ -0,0 +1,384 @@ +// -------------------------------------------------------------------------- +// Sym-1 front panel display example +// +// Wayne Parham +// +// wayne@parhamdata.com +// -------------------------------------------------------------------------- + +#include <symio.h> + +void main (void) { + int delay = 10; + int flashes = 255; + int displayable = 1; + int e = 0; + int r = 0; + int d = 0; + int i = 0; + int l = 0; + int t = 0; + int z = 0; + char c = 0x00; + char buffer[41] = { 0x00 }; + + puts( "\nType a message (40 chars max) and press ENTER, please:\n" ); + + while( (c != '\r') && (i < 41) ) { + c = getchar(); + putchar( c ); + buffer[i] = c; + i++; + if( i == 40 ) { + puts( "\n\n--- Reached 40 character limit. ---" ); + } + } + + i--; // index is one past end + + while( z == 0 ) { + puts( "\n\nHow many times (0 for forever) to repeat?" ); + c = getchar(); + putchar( c ); + if( (c >= '0') && (c <= '9') ) { // between 1 and 9 loops allowed + z = 1; // a number was pressed + t = c - '0'; // convert char to int + puts( "\n\nLook at the front panel.\n" ); + } + else { + puts( "\nWhat?" ); + z = 0; // keep asking for a number + } + } + + z = 0; + while( (z < t) || (t == 0) ) { + + z++; + + putchar( '\r' ); // Send CR to console + + + set_D0( DISP_SPACE ); // Clear the display + set_D1( DISP_SPACE ); + set_D2( DISP_SPACE ); + set_D3( DISP_SPACE ); + set_D4( DISP_SPACE ); + set_D5( DISP_SPACE ); + set_D6( DISP_SPACE ); + + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + + for( l = 0; l <= i; l++ ) { + + displayable = 1; // Assume character is mapped + + switch( buffer[l] ) { // Put the typed charaters + case '1': // into the display buffer + set_D6( DISP_1 ); // one at a time + break; + case '2': + set_D6( DISP_2 ); + break; + case '3': + set_D6( DISP_3 ); + break; + case '4': + set_D6( DISP_4 ); + break; + case '5': + set_D6( DISP_5 ); + break; + case '6': + set_D6( DISP_6 ); + break; + case '7': + set_D6( DISP_7 ); + break; + case '8': + set_D6( DISP_8 ); + break; + case '9': + set_D6( DISP_9 ); + break; + case '0': + set_D6( DISP_0 ); + break; + case 'A': + set_D6( DISP_A ); + break; + case 'a': + set_D6( DISP_A ); + break; + case 'B': + set_D6( DISP_b ); + break; + case 'b': + set_D6( DISP_b ); + break; + case 'C': + set_D6( DISP_C ); + break; + case 'c': + set_D6( DISP_c ); + break; + case 'D': + set_D6( DISP_d ); + break; + case 'd': + set_D6( DISP_d ); + break; + case 'E': + set_D6( DISP_E ); + break; + case 'e': + set_D6( DISP_e ); + break; + case 'F': + set_D6( DISP_F ); + break; + case 'f': + set_D6( DISP_F ); + break; + case 'G': + set_D6( DISP_G ); + break; + case 'g': + set_D6( DISP_g ); + break; + case 'H': + set_D6( DISP_H ); + break; + case 'h': + set_D6( DISP_h ); + break; + case 'I': + set_D6( DISP_I ); + break; + case 'i': + set_D6( DISP_i ); + break; + case 'J': + set_D6( DISP_J ); + break; + case 'j': + set_D6( DISP_J ); + break; + case 'K': + set_D6( DISP_K ); + break; + case 'k': + set_D6( DISP_K ); + break; + case 'L': + set_D6( DISP_L ); + break; + case 'l': + set_D6( DISP_L ); + break; + case 'M': + set_D0( get_D1() ); + set_D1( get_D2() ); + set_D2( get_D3() ); + set_D3( get_D4() ); + set_D4( get_D5() ); + set_D5( get_D6() ); + set_D6( DISP_M_1 ); + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + set_D6( DISP_M_2 ); + break; + case 'm': + set_D0( get_D1() ); + set_D1( get_D2() ); + set_D2( get_D3() ); + set_D3( get_D4() ); + set_D4( get_D5() ); + set_D5( get_D6() ); + set_D6( DISP_M_1 ); + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + set_D6( DISP_M_2 ); + break; + case 'N': + set_D6( DISP_n ); + break; + case 'n': + set_D6( DISP_n ); + break; + case 'O': + set_D6( DISP_O ); + break; + case 'o': + set_D6( DISP_o ); + break; + case 'P': + set_D6( DISP_P ); + break; + case 'p': + set_D6( DISP_P ); + break; + case 'Q': + set_D6( DISP_q ); + break; + case 'q': + set_D6( DISP_q ); + break; + case 'R': + set_D6( DISP_r ); + break; + case 'r': + set_D6( DISP_r ); + break; + case 'S': + set_D6( DISP_S ); + break; + case 's': + set_D6( DISP_S ); + break; + case 'T': + set_D6( DISP_t ); + break; + case 't': + set_D6( DISP_t ); + break; + case 'U': + set_D6( DISP_U ); + break; + case 'u': + set_D6( DISP_u ); + break; + case 'V': + set_D0( get_D1() ); + set_D1( get_D2() ); + set_D2( get_D3() ); + set_D3( get_D4() ); + set_D4( get_D5() ); + set_D5( get_D6() ); + set_D6( DISP_M_1 ); + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + set_D6( DISP_V_2 ); + break; + case 'v': + set_D0( get_D1() ); + set_D1( get_D2() ); + set_D2( get_D3() ); + set_D3( get_D4() ); + set_D4( get_D5() ); + set_D5( get_D6() ); + set_D6( DISP_M_1 ); + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + set_D6( DISP_V_2 ); + break; + case 'W': + set_D0( get_D1() ); + set_D1( get_D2() ); + set_D2( get_D3() ); + set_D3( get_D4() ); + set_D4( get_D5() ); + set_D5( get_D6() ); + set_D6( DISP_M_1 ); + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + set_D6( DISP_W_2 ); + break; + case 'w': + set_D0( get_D1() ); + set_D1( get_D2() ); + set_D2( get_D3() ); + set_D3( get_D4() ); + set_D4( get_D5() ); + set_D5( get_D6() ); + set_D6( DISP_M_1 ); + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + set_D6( DISP_W_2 ); + break; + case 'Y': + set_D6( DISP_Y ); + break; + case 'y': + set_D6( DISP_Y ); + break; + case 'Z': + set_D6( DISP_Z ); + break; + case 'z': + set_D6( DISP_Z ); + break; + case ' ': + set_D6( DISP_SPACE ); + break; + case '.': + set_D6( DISP_PERIOD ); + break; + case '-': + set_D6( DISP_HYPHEN ); + break; + case '\'': + set_D6( DISP_APOSTR ); + break; + case '"': + set_D6( DISP_APOSTR ); + break; + case '=': + set_D6( DISP_EQUAL ); + break; + case '_': + set_D6( DISP_BOTTOM ); + break; + case '/': + set_D6( DISP_SLASH ); + break; + case '\\': + set_D6( DISP_BACKSLASH ); + break; + default: + displayable = 0; // Character not mapped + } + + if( displayable ) { + + putchar( buffer[l] ); // Send it to the console + + set_D0( get_D1() ); // Scroll to the left + set_D1( get_D2() ); + set_D2( get_D3() ); + set_D3( get_D4() ); + set_D4( get_D5() ); + set_D5( get_D6() ); + + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + } + } + + for( e = 0; e < 6; e++ ) { // Gradually fill the + set_D0( get_D1() ); // display with spaces + set_D1( get_D2() ); + set_D2( get_D3() ); + set_D3( get_D4() ); + set_D4( get_D5() ); + set_D5( DISP_SPACE ); + set_D6( DISP_SPACE ); + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + } + } + + puts( "\n\nEnjoy your day!\n\n" ); + + return; +} diff --git a/samples/symHello.c b/samples/symHello.c new file mode 100644 index 000000000..99b4c57df --- /dev/null +++ b/samples/symHello.c @@ -0,0 +1,39 @@ +// -------------------------------------------------------------------------- +// Hello World for Sym-1 +// +// Wayne Parham +// +// wayne@parhamdata.com +// -------------------------------------------------------------------------- + +#include <symio.h>; + +void main(void) { + char c = 0x00; + int d = 0x00; + int l = 0x00; + + printf( "\nHello World!\n\n" ); + + for( l = 0; l < 2; l++ ) { + beep(); + for( d = 0; d < 10 ; d++ ) { + } + } + printf( "Type a line and press ENTER, please.\n\n" ); + + while( c != '\r' ) { + c = getchar(); + putchar( c ); + } + + printf( "\n\nThanks!\n\n" ); + + for( l = 0; l < 5; l++ ) { + beep(); + for( d = 0; d < 10 ; d++ ) { + } + } + + return; +} diff --git a/samples/symIO.c b/samples/symIO.c new file mode 100644 index 000000000..c52a71b11 --- /dev/null +++ b/samples/symIO.c @@ -0,0 +1,170 @@ +// -------------------------------------------------------------------------- +// Sym-1 digital I/O interface example +// +// Wayne Parham +// +// wayne@parhamdata.com +// -------------------------------------------------------------------------- + +#include <stdio.h>; +#include <symio.h>; +#include <stdlib.h>; +#include <string.h>; + +void main(void) { + int ddr1a = 0x00; + int ior1a = 0x00; + int ddr1b = 0x00; + int ior1b = 0x00; + int ddr2a = 0x00; + int ior2a = 0x00; + int ddr2b = 0x00; + int ior2b = 0x00; + int ddr3a = 0x00; + int ior3a = 0x00; + int ddr3b = 0x00; + int ior3b = 0x00; + int l = 0x00; + int val = 0x00; + int going = 0x01; + int instr = 0x01; + char* vp = 0x00; + char cmd[20] = { 0x00 }; + + while( going ) { + + putchar( '\r' ); + for( l = 0; l < 25; l++ ) { + putchar( '\n' ); + } + + ddr1a = get_DDR1A(); + ior1a = get_IOR1A(); + ddr1b = get_DDR1B(); + ior1b = get_IOR1B(); + ddr2a = get_DDR2A(); + ior2a = get_IOR2A(); + ddr2b = get_DDR2B(); + ior2b = get_IOR2B(); + ddr3a = get_DDR3A(); + ior3a = get_IOR3A(); + ddr3b = get_DDR3B(); + ior3b = get_IOR3B(); + + puts( "================== Digital I/O Status ==================" ); + puts( " Port1A Port1B Port2A Port2B Port3A Port3B" ); + printf( "DDR %02X %02X %02X %02X %02X %02X\n\r",ddr1a,ddr1b,ddr2a,ddr2b,ddr3a,ddr3b ); + printf( "IOR %02X %02X %02X %02X %02X %02X\n\r",ior1a,ior1b,ior2a,ior2b,ior3a,ior3b ); + puts( "========================================================\n" ); + + if( instr ) { + puts( "You can set any register by typing 'register value' so" ); + puts( "as an example, to set register IOR2A with the top five" ); + puts( "bits off and the bottom three on, type 'IOR2A 07'." ); + puts( "Press ENTER without any command to see register values" ); + puts( "without changing any of them. Type 'help' to see these" ); + puts( "instructions again and type 'stop' to end the program.\n"); + puts( "Available registers: DDR1A, IOR1A, DDR1B, IOR1B, DDR2A" ); + puts( "IOR2A, DDR2B, IOR2B, DDR3A, IOR3A, DDR3B and IOR3B." ); + instr = 0; + } + + printf( "\n Command: " ); + + fgets(cmd, sizeof(cmd)-1, stdin); + cmd[strlen(cmd)-1] = '\0'; + + if( strncasecmp(cmd, "stop", 4) == 0) { + going = 0; + } + else if( strncasecmp(cmd, "help", 4) == 0) { + instr = 1; + } + else if( strncasecmp(cmd, "ddr1a", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_DDR1A( val ); + } + } + else if( strncasecmp(cmd, "ior1a", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_IOR1A( val ); + } + } + else if( strncasecmp(cmd, "ddr1b", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_DDR1B( val ); + } + } + else if( strncasecmp(cmd, "ior1b", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_IOR1B( val ); + } + } + else if( strncasecmp(cmd, "ddr2a", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_DDR2A( val ); + } + } + else if( strncasecmp(cmd, "ior2a", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_IOR2A( val ); + } + } + else if( strncasecmp(cmd, "ddr2b", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_DDR2B( val ); + } + } + else if( strncasecmp(cmd, "ior2b", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_IOR2B( val ); + } + } + else if( strncasecmp(cmd, "ddr3a", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_DDR3A( val ); + } + } + else if( strncasecmp(cmd, "ior3a", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_IOR3A( val ); + } + } + else if( strncasecmp(cmd, "ddr3b", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_DDR3B( val ); + } + } + else if( strncasecmp(cmd, "ior3b", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_IOR3B( val ); + } + } + } + + return; +} diff --git a/samples/symTiny.c b/samples/symTiny.c new file mode 100644 index 000000000..b82e952ac --- /dev/null +++ b/samples/symTiny.c @@ -0,0 +1,42 @@ +// -------------------------------------------------------------------------- +// Hello World for Sym-1 +// +// Uses only getchar, putchar and puts, generating smaller code than printf +// +// Wayne Parham +// +// wayne@parhamdata.com +// -------------------------------------------------------------------------- + +#include <symio.h>; + +void main(void) { + char c = 0x00; + int d = 0x00; + int l = 0x00; + + puts( "Hello World!\n" ); + + puts( "Type a line and press ENTER, please:\n" ); + + for( l = 0; l < 2; l++ ) { + beep(); + for( d = 0; d < 10 ; d++ ) { + } + } + + while( c != '\r' ) { + c = getchar(); + putchar( c ); + } + + puts( "\n\nThanks!\n" ); + + for( l = 0; l < 5; l++ ) { + beep(); + for( d = 0; d < 10 ; d++ ) { + } + } + + return; +} diff --git a/samples/tutorial/sym1/build b/samples/tutorial/sym1/build new file mode 100644 index 000000000..6688da0a3 --- /dev/null +++ b/samples/tutorial/sym1/build @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# +# build.sh + +if [ -f $1.c ]; then + echo + echo "--- Building $1 ---" + + if [ -f $1.s ]; then + rm $1.s + fi + if [ -f $1.o ]; then + rm $1.o + fi + if [ -f $1.bin ]; then + rm $1.bin + fi + if [ -f $1.hex ]; then + rm $1.hex + fi + + cc65 -t sym1 -O $1.c + ca65 $1.s + ld65 -C sym1.cfg -m $1.map -o $1.bin $1.o sym1.lib + if [ -f $1.bin ]; then + bin2hex $1.bin $1.hex > /dev/null 2>&1 + fi + if [ -f $1.hex ]; then + echo "--- $1.hex made ---" + else + echo "--- $1.hex FAIL ---" + fi + + +fi + diff --git a/samples/tutorial/sym1/build_32k b/samples/tutorial/sym1/build_32k new file mode 100644 index 000000000..555bda0b4 --- /dev/null +++ b/samples/tutorial/sym1/build_32k @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# +# build.sh + +if [ -f $1.c ]; then + echo + echo "--- Building $1 ---" + + if [ -f $1.s ]; then + rm $1.s + fi + if [ -f $1.o ]; then + rm $1.o + fi + if [ -f $1.bin ]; then + rm $1.bin + fi + if [ -f $1.hex ]; then + rm $1.hex + fi + + cc65 -t sym1 -O $1.c + ca65 $1.s + ld65 -C sym1-32k.cfg -m $1.map -o $1.bin $1.o sym1.lib + if [ -f $1.bin ]; then + bin2hex $1.bin $1.hex > /dev/null 2>&1 + fi + if [ -f $1.hex ]; then + echo "--- $1.hex made ---" + else + echo "--- $1.hex FAIL ---" + fi + + +fi + diff --git a/samples/tutorial/sym1/build_4k b/samples/tutorial/sym1/build_4k new file mode 100644 index 000000000..502bb6aa9 --- /dev/null +++ b/samples/tutorial/sym1/build_4k @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# +# build.sh + +if [ -f $1.c ]; then + echo + echo "--- Building $1 ---" + + if [ -f $1.s ]; then + rm $1.s + fi + if [ -f $1.o ]; then + rm $1.o + fi + if [ -f $1.bin ]; then + rm $1.bin + fi + if [ -f $1.hex ]; then + rm $1.hex + fi + + cc65 -t sym1 -O $1.c + ca65 $1.s + ld65 -C sym1-4k.cfg -m $1.map -o $1.bin $1.o sym1.lib + if [ -f $1.bin ]; then + bin2hex $1.bin $1.hex > /dev/null 2>&1 + fi + if [ -f $1.hex ]; then + echo "--- $1.hex made ---" + else + echo "--- $1.hex FAIL ---" + fi + + +fi + diff --git a/samples/tutorial/sym1/clean b/samples/tutorial/sym1/clean new file mode 100644 index 000000000..c0d77390e --- /dev/null +++ b/samples/tutorial/sym1/clean @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# +# clean.sh + +if [ -f $1.c ]; then + echo + echo "--- Cleaning $1 ---" + + rm $1.s $1.o $1.map $1.bin $1.hex > /dev/null 2>&1 + + echo "--- Cleaned $1 ---" + +fi + diff --git a/samples/tutorial/sym1/readme.txt b/samples/tutorial/sym1/readme.txt new file mode 100644 index 000000000..74bcb5527 --- /dev/null +++ b/samples/tutorial/sym1/readme.txt @@ -0,0 +1,11 @@ +These simple build scripts can be used to build any single-file C program +you might write. Notice the diference in the linker line for the 4k build +compared with the 32k build. Small programs can be compiled with either +build script, but they won't run on a 4k machine if compiled for a 32k +system. So if you have a program that's small enough to fit in 4k, it is +probably better to build with the 4k script so it will run on Sym-1 machines +that do not have an expansion memory board. + +Usage: build <program> (don't include the .c extension) + clean <program> (removes intermediate and output files) + diff --git a/samples/tutorial/sym1/symDisplay.c b/samples/tutorial/sym1/symDisplay.c new file mode 100644 index 000000000..41eaf8b49 --- /dev/null +++ b/samples/tutorial/sym1/symDisplay.c @@ -0,0 +1,384 @@ +// -------------------------------------------------------------------------- +// Sym-1 front panel display example +// +// Wayne Parham +// +// wayne@parhamdata.com +// -------------------------------------------------------------------------- + +#include <symio.h> + +void main (void) { + int delay = 10; + int flashes = 255; + int displayable = 1; + int e = 0; + int r = 0; + int d = 0; + int i = 0; + int l = 0; + int t = 0; + int z = 0; + char c = 0x00; + char buffer[41] = { 0x00 }; + + puts( "\nType a message (40 chars max) and press ENTER, please:\n" ); + + while( (c != '\r') && (i < 41) ) { + c = getchar(); + putchar( c ); + buffer[i] = c; + i++; + if( i == 40 ) { + puts( "\n\n--- Reached 40 character limit. ---" ); + } + } + + i--; // index is one past end + + while( z == 0 ) { + puts( "\n\nHow many times (0 for forever) to repeat?" ); + c = getchar(); + putchar( c ); + if( (c >= '0') && (c <= '9') ) { // between 1 and 9 loops allowed + z = 1; // a number was pressed + t = c - '0'; // convert char to int + puts( "\n\nLook at the front panel.\n" ); + } + else { + puts( "\nWhat?" ); + z = 0; // keep asking for a number + } + } + + z = 0; + while( (z < t) || (t == 0) ) { + + z++; + + putchar( '\r' ); // Send CR to console + + + set_D0( DISP_SPACE ); // Clear the display + set_D1( DISP_SPACE ); + set_D2( DISP_SPACE ); + set_D3( DISP_SPACE ); + set_D4( DISP_SPACE ); + set_D5( DISP_SPACE ); + set_D6( DISP_SPACE ); + + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + + for( l = 0; l <= i; l++ ) { + + displayable = 1; // Assume character is mapped + + switch( buffer[l] ) { // Put the typed charaters + case '1': // into the display buffer + set_D6( DISP_1 ); // one at a time + break; + case '2': + set_D6( DISP_2 ); + break; + case '3': + set_D6( DISP_3 ); + break; + case '4': + set_D6( DISP_4 ); + break; + case '5': + set_D6( DISP_5 ); + break; + case '6': + set_D6( DISP_6 ); + break; + case '7': + set_D6( DISP_7 ); + break; + case '8': + set_D6( DISP_8 ); + break; + case '9': + set_D6( DISP_9 ); + break; + case '0': + set_D6( DISP_0 ); + break; + case 'A': + set_D6( DISP_A ); + break; + case 'a': + set_D6( DISP_A ); + break; + case 'B': + set_D6( DISP_b ); + break; + case 'b': + set_D6( DISP_b ); + break; + case 'C': + set_D6( DISP_C ); + break; + case 'c': + set_D6( DISP_c ); + break; + case 'D': + set_D6( DISP_d ); + break; + case 'd': + set_D6( DISP_d ); + break; + case 'E': + set_D6( DISP_E ); + break; + case 'e': + set_D6( DISP_e ); + break; + case 'F': + set_D6( DISP_F ); + break; + case 'f': + set_D6( DISP_F ); + break; + case 'G': + set_D6( DISP_G ); + break; + case 'g': + set_D6( DISP_g ); + break; + case 'H': + set_D6( DISP_H ); + break; + case 'h': + set_D6( DISP_h ); + break; + case 'I': + set_D6( DISP_I ); + break; + case 'i': + set_D6( DISP_i ); + break; + case 'J': + set_D6( DISP_J ); + break; + case 'j': + set_D6( DISP_J ); + break; + case 'K': + set_D6( DISP_K ); + break; + case 'k': + set_D6( DISP_K ); + break; + case 'L': + set_D6( DISP_L ); + break; + case 'l': + set_D6( DISP_L ); + break; + case 'M': + set_D0( get_D1() ); + set_D1( get_D2() ); + set_D2( get_D3() ); + set_D3( get_D4() ); + set_D4( get_D5() ); + set_D5( get_D6() ); + set_D6( DISP_M_1 ); + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + set_D6( DISP_M_2 ); + break; + case 'm': + set_D0( get_D1() ); + set_D1( get_D2() ); + set_D2( get_D3() ); + set_D3( get_D4() ); + set_D4( get_D5() ); + set_D5( get_D6() ); + set_D6( DISP_M_1 ); + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + set_D6( DISP_M_2 ); + break; + case 'N': + set_D6( DISP_n ); + break; + case 'n': + set_D6( DISP_n ); + break; + case 'O': + set_D6( DISP_O ); + break; + case 'o': + set_D6( DISP_o ); + break; + case 'P': + set_D6( DISP_P ); + break; + case 'p': + set_D6( DISP_P ); + break; + case 'Q': + set_D6( DISP_q ); + break; + case 'q': + set_D6( DISP_q ); + break; + case 'R': + set_D6( DISP_r ); + break; + case 'r': + set_D6( DISP_r ); + break; + case 'S': + set_D6( DISP_S ); + break; + case 's': + set_D6( DISP_S ); + break; + case 'T': + set_D6( DISP_t ); + break; + case 't': + set_D6( DISP_t ); + break; + case 'U': + set_D6( DISP_U ); + break; + case 'u': + set_D6( DISP_u ); + break; + case 'V': + set_D0( get_D1() ); + set_D1( get_D2() ); + set_D2( get_D3() ); + set_D3( get_D4() ); + set_D4( get_D5() ); + set_D5( get_D6() ); + set_D6( DISP_M_1 ); + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + set_D6( DISP_V_2 ); + break; + case 'v': + set_D0( get_D1() ); + set_D1( get_D2() ); + set_D2( get_D3() ); + set_D3( get_D4() ); + set_D4( get_D5() ); + set_D5( get_D6() ); + set_D6( DISP_M_1 ); + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + set_D6( DISP_V_2 ); + break; + case 'W': + set_D0( get_D1() ); + set_D1( get_D2() ); + set_D2( get_D3() ); + set_D3( get_D4() ); + set_D4( get_D5() ); + set_D5( get_D6() ); + set_D6( DISP_M_1 ); + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + set_D6( DISP_W_2 ); + break; + case 'w': + set_D0( get_D1() ); + set_D1( get_D2() ); + set_D2( get_D3() ); + set_D3( get_D4() ); + set_D4( get_D5() ); + set_D5( get_D6() ); + set_D6( DISP_M_1 ); + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + set_D6( DISP_W_2 ); + break; + case 'Y': + set_D6( DISP_Y ); + break; + case 'y': + set_D6( DISP_Y ); + break; + case 'Z': + set_D6( DISP_Z ); + break; + case 'z': + set_D6( DISP_Z ); + break; + case ' ': + set_D6( DISP_SPACE ); + break; + case '.': + set_D6( DISP_PERIOD ); + break; + case '-': + set_D6( DISP_HYPHEN ); + break; + case '\'': + set_D6( DISP_APOSTR ); + break; + case '"': + set_D6( DISP_APOSTR ); + break; + case '=': + set_D6( DISP_EQUAL ); + break; + case '_': + set_D6( DISP_BOTTOM ); + break; + case '/': + set_D6( DISP_SLASH ); + break; + case '\\': + set_D6( DISP_BACKSLASH ); + break; + default: + displayable = 0; // Character not mapped + } + + if( displayable ) { + + putchar( buffer[l] ); // Send it to the console + + set_D0( get_D1() ); // Scroll to the left + set_D1( get_D2() ); + set_D2( get_D3() ); + set_D3( get_D4() ); + set_D4( get_D5() ); + set_D5( get_D6() ); + + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + } + } + + for( e = 0; e < 6; e++ ) { // Gradually fill the + set_D0( get_D1() ); // display with spaces + set_D1( get_D2() ); + set_D2( get_D3() ); + set_D3( get_D4() ); + set_D4( get_D5() ); + set_D5( DISP_SPACE ); + set_D6( DISP_SPACE ); + for( d = 0; d < flashes ; d++ ) { + fdisp(); // Display + } + } + } + + puts( "\n\nEnjoy your day!\n\n" ); + + return; +} diff --git a/samples/tutorial/sym1/symHello.c b/samples/tutorial/sym1/symHello.c new file mode 100644 index 000000000..99b4c57df --- /dev/null +++ b/samples/tutorial/sym1/symHello.c @@ -0,0 +1,39 @@ +// -------------------------------------------------------------------------- +// Hello World for Sym-1 +// +// Wayne Parham +// +// wayne@parhamdata.com +// -------------------------------------------------------------------------- + +#include <symio.h>; + +void main(void) { + char c = 0x00; + int d = 0x00; + int l = 0x00; + + printf( "\nHello World!\n\n" ); + + for( l = 0; l < 2; l++ ) { + beep(); + for( d = 0; d < 10 ; d++ ) { + } + } + printf( "Type a line and press ENTER, please.\n\n" ); + + while( c != '\r' ) { + c = getchar(); + putchar( c ); + } + + printf( "\n\nThanks!\n\n" ); + + for( l = 0; l < 5; l++ ) { + beep(); + for( d = 0; d < 10 ; d++ ) { + } + } + + return; +} diff --git a/samples/tutorial/sym1/symIO.c b/samples/tutorial/sym1/symIO.c new file mode 100644 index 000000000..c52a71b11 --- /dev/null +++ b/samples/tutorial/sym1/symIO.c @@ -0,0 +1,170 @@ +// -------------------------------------------------------------------------- +// Sym-1 digital I/O interface example +// +// Wayne Parham +// +// wayne@parhamdata.com +// -------------------------------------------------------------------------- + +#include <stdio.h>; +#include <symio.h>; +#include <stdlib.h>; +#include <string.h>; + +void main(void) { + int ddr1a = 0x00; + int ior1a = 0x00; + int ddr1b = 0x00; + int ior1b = 0x00; + int ddr2a = 0x00; + int ior2a = 0x00; + int ddr2b = 0x00; + int ior2b = 0x00; + int ddr3a = 0x00; + int ior3a = 0x00; + int ddr3b = 0x00; + int ior3b = 0x00; + int l = 0x00; + int val = 0x00; + int going = 0x01; + int instr = 0x01; + char* vp = 0x00; + char cmd[20] = { 0x00 }; + + while( going ) { + + putchar( '\r' ); + for( l = 0; l < 25; l++ ) { + putchar( '\n' ); + } + + ddr1a = get_DDR1A(); + ior1a = get_IOR1A(); + ddr1b = get_DDR1B(); + ior1b = get_IOR1B(); + ddr2a = get_DDR2A(); + ior2a = get_IOR2A(); + ddr2b = get_DDR2B(); + ior2b = get_IOR2B(); + ddr3a = get_DDR3A(); + ior3a = get_IOR3A(); + ddr3b = get_DDR3B(); + ior3b = get_IOR3B(); + + puts( "================== Digital I/O Status ==================" ); + puts( " Port1A Port1B Port2A Port2B Port3A Port3B" ); + printf( "DDR %02X %02X %02X %02X %02X %02X\n\r",ddr1a,ddr1b,ddr2a,ddr2b,ddr3a,ddr3b ); + printf( "IOR %02X %02X %02X %02X %02X %02X\n\r",ior1a,ior1b,ior2a,ior2b,ior3a,ior3b ); + puts( "========================================================\n" ); + + if( instr ) { + puts( "You can set any register by typing 'register value' so" ); + puts( "as an example, to set register IOR2A with the top five" ); + puts( "bits off and the bottom three on, type 'IOR2A 07'." ); + puts( "Press ENTER without any command to see register values" ); + puts( "without changing any of them. Type 'help' to see these" ); + puts( "instructions again and type 'stop' to end the program.\n"); + puts( "Available registers: DDR1A, IOR1A, DDR1B, IOR1B, DDR2A" ); + puts( "IOR2A, DDR2B, IOR2B, DDR3A, IOR3A, DDR3B and IOR3B." ); + instr = 0; + } + + printf( "\n Command: " ); + + fgets(cmd, sizeof(cmd)-1, stdin); + cmd[strlen(cmd)-1] = '\0'; + + if( strncasecmp(cmd, "stop", 4) == 0) { + going = 0; + } + else if( strncasecmp(cmd, "help", 4) == 0) { + instr = 1; + } + else if( strncasecmp(cmd, "ddr1a", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_DDR1A( val ); + } + } + else if( strncasecmp(cmd, "ior1a", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_IOR1A( val ); + } + } + else if( strncasecmp(cmd, "ddr1b", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_DDR1B( val ); + } + } + else if( strncasecmp(cmd, "ior1b", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_IOR1B( val ); + } + } + else if( strncasecmp(cmd, "ddr2a", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_DDR2A( val ); + } + } + else if( strncasecmp(cmd, "ior2a", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_IOR2A( val ); + } + } + else if( strncasecmp(cmd, "ddr2b", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_DDR2B( val ); + } + } + else if( strncasecmp(cmd, "ior2b", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_IOR2B( val ); + } + } + else if( strncasecmp(cmd, "ddr3a", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_DDR3A( val ); + } + } + else if( strncasecmp(cmd, "ior3a", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_IOR3A( val ); + } + } + else if( strncasecmp(cmd, "ddr3b", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_DDR3B( val ); + } + } + else if( strncasecmp(cmd, "ior3b", 5) == 0) { + vp = strchr(cmd, ' '); + if( vp ) { + val = atoi( vp ); + set_IOR3B( val ); + } + } + } + + return; +} diff --git a/samples/tutorial/sym1/symTiny.c b/samples/tutorial/sym1/symTiny.c new file mode 100644 index 000000000..b82e952ac --- /dev/null +++ b/samples/tutorial/sym1/symTiny.c @@ -0,0 +1,42 @@ +// -------------------------------------------------------------------------- +// Hello World for Sym-1 +// +// Uses only getchar, putchar and puts, generating smaller code than printf +// +// Wayne Parham +// +// wayne@parhamdata.com +// -------------------------------------------------------------------------- + +#include <symio.h>; + +void main(void) { + char c = 0x00; + int d = 0x00; + int l = 0x00; + + puts( "Hello World!\n" ); + + puts( "Type a line and press ENTER, please:\n" ); + + for( l = 0; l < 2; l++ ) { + beep(); + for( d = 0; d < 10 ; d++ ) { + } + } + + while( c != '\r' ) { + c = getchar(); + putchar( c ); + } + + puts( "\n\nThanks!\n" ); + + for( l = 0; l < 5; l++ ) { + beep(); + for( d = 0; d < 10 ; d++ ) { + } + } + + return; +} From 044a0838a377fe17559a308bbb10ca21374e4ca1 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Sun, 9 May 2021 16:51:17 -0500 Subject: [PATCH 2019/2161] Changes to existing cc65 source to support Synertek Systems Sym-1 --- README.md | 1 + libsrc/Makefile | 49 +++++++++++++++++++++++++++++++-------------- samples/Makefile | 30 ++++++++++++++++++++------- src/cc65/main.c | 3 +++ src/common/target.c | 2 ++ src/common/target.h | 1 + 6 files changed, 64 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 2c84b7430..c1b8a8b59 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ including - the Lynx console. - the Ohio Scientific Challenger 1P. - the Commander X16. +- the Synertek Syetms Sym-1. The libraries are fairly portable, so creating a version for other 6502s shouldn't be too much work. diff --git a/libsrc/Makefile b/libsrc/Makefile index 3fac513af..eee18d0da 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -34,6 +34,7 @@ TARGETS = apple2 \ sim6502 \ sim65c02 \ supervision \ + sym1 \ telestrat DRVTYPES = emd \ @@ -148,18 +149,26 @@ GEOSDIRS = common \ runtime \ system +# MACHINE set independently of TARGET lets us easily define new targets +# without changing target.h and target.c in cc65/src/common. Useful +# for initial testing of ports to new systems. + ifeq ($(TARGET),apple2enh) SRCDIR = apple2 OBJPFX = a2 DRVPFX = a2e + MACHINE = $(TARGET) else ifeq ($(TARGET),atarixl) SRCDIR = atari OBJPFX = atr DRVPFX = atrx + MACHINE = $(TARGET) else ifeq ($(TARGET),sim65c02) SRCDIR = sim6502 + MACHINE = $(TARGET) else SRCDIR = $(TARGET) + MACHINE = $(TARGET) endif SRCDIRS = $(SRCDIR) @@ -173,16 +182,26 @@ ifeq ($(TARGET),$(filter $(TARGET),$(GEOS))) SRCDIRS += $(addprefix geos-common/,$(GEOSDIRS)) endif -SRCDIRS += common \ - conio \ - dbg \ - em \ - joystick \ - mouse \ - runtime \ - serial \ - tgi \ - zlib +ifeq ($(TARGET),sym1) + SRCDIRS += common \ + conio \ + dbg \ + em \ + runtime \ + serial \ + sym1 +else + SRCDIRS += common \ + conio \ + dbg \ + em \ + joystick \ + mouse \ + runtime \ + serial \ + tgi \ + zlib +endif vpath %.s $(SRCDIRS) vpath %.c $(SRCDIRS) @@ -231,7 +250,7 @@ $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 $$@ $$< + @$$(CA65) -t $$(MACHINE) -D DYN_DRV=0 $$(CA65FLAGS) --create-dep $$(@:.o=.d) -o $$@ $$< OBJS += $$($1_STCS) DEPS += $$($1_STCS:.o=.d) @@ -263,15 +282,15 @@ export CC65_HOME := $(abspath ..) define ASSEMBLE_recipe $(if $(QUIET),,@echo $(TARGET) - $<) -@$(CA65) -t $(TARGET) $(CA65FLAGS) --create-dep $(@:.o=.d) -o $@ $< +@$(CA65) -t $(MACHINE) $(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) +@$(CC65) -t $(MACHINE) $(CC65FLAGS) --create-dep $(@:.o=.d) --dep-target $@ -o $(@:.o=.s) $< +@$(CA65) -t $(MACHINE) -o $@ $(@:.o=.s) endef # COMPILE_recipe @@ -283,7 +302,7 @@ endef # COMPILE_recipe $(EXTRA_OBJPAT): $(EXTRA_SRCPAT) | ../libwrk/$(TARGET) ../lib @echo $(TARGET) - $(<F) - @$(CA65) -t $(TARGET) $(CA65FLAGS) --create-dep $(@:../lib/%.o=../libwrk/$(TARGET)/%.d) -o $@ $< + @$(CA65) -t $(MACHINE) $(CA65FLAGS) --create-dep $(@:../lib/%.o=../libwrk/$(TARGET)/%.d) -o $@ $< ../lib/$(TARGET).lib: $(OBJS) | ../lib $(AR65) a $@ $? diff --git a/samples/Makefile b/samples/Makefile index 6e89cb802..e3b28057f 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -135,31 +135,37 @@ LDFLAGS_tgidemo_atarixl = --start-addr 0x4000 %: %.s .c.o: - $(CC) $(CFLAGS) -Ors --codesize 500 -T -g -t $(SYS) $< + $(CC) $(CFLAGS) -Ors --codesize 500 -T -g -t $(MACHINE) $< $(AS) $(<:.c=.s) .s.o: - $(AS) $(ASFLAGS) -t $(SYS) $< + $(AS) $(ASFLAGS) -t $(MACHINE) $< .PRECIOUS: %.o .o: ifeq ($(SYS),vic20) $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -C vic20-32k.cfg -m $@.map $^ $(SYS).lib +else ifeq ($(SYS),sym1) + $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@.bin -C sym1.cfg -m $@.map $^ $(SYS).lib else - $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib + $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(MACHINE) -m $@.map $^ $(SYS).lib endif # -------------------------------------------------------------------------- # Lists of subdirectories # disasm depends on cpp -DIRLIST = tutorial geos + +ifneq ($(SYS),sym1) + DIRLIST = tutorial geos +endif # -------------------------------------------------------------------------- # Lists of executables EXELIST_c64 = \ + helloworld \ ascii \ enumdevdir \ fire \ @@ -175,6 +181,7 @@ EXELIST_c64 = \ tgidemo EXELIST_apple2 = \ + helloworld \ ascii \ diodemo \ enumdevdir \ @@ -190,6 +197,7 @@ EXELIST_apple2 = \ EXELIST_apple2enh = $(EXELIST_apple2) EXELIST_atari = \ + helloworld \ ascii \ gunzip65 \ hello \ @@ -208,6 +216,12 @@ EXELIST_atari2600 = \ EXELIST_supervision = \ supervisionhello +EXELIST_sym1 = \ + helloworld \ + symHello \ + symTiny \ + symDisplay + # Unlisted targets will try to build everything. # That lets us learn what they cannot build, and what settings # we need to use for programs that can be built and run. @@ -215,12 +229,13 @@ ifndef EXELIST_$(SYS) EXELIST_$(SYS) := ${patsubst %.c,%,$(wildcard *.c)} endif -define SUBDIR_recipe +define SUBDIR_recipe @$(MAKE) -C $(dir) --no-print-directory $@ endef # SUBDIR_recipe + # -------------------------------------------------------------------------- # Rules to make the binaries and the disk @@ -352,9 +367,10 @@ zip: # Clean-up rules mostlyclean: - @$(DEL) *.lbl *.map *.o *.s 2>$(NULLDEV) + @$(DEL) *.lbl *.map *.bin *.hex *.o *.s 2>$(NULLDEV) clean: mostlyclean @$(DEL) $(EXELIST_$(SYS)) $(DISK_$(SYS)) 2>$(NULLDEV) @$(DEL) multdemo.? ovrldemo.? 2>$(NULLDEV) - $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) + @$(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) + diff --git a/src/cc65/main.c b/src/cc65/main.c index 0b156fb74..9e9fab6b4 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -290,6 +290,9 @@ static void SetSys (const char* Sys) cbmsys ("__CX16__"); break; + case TGT_NONE: + break; + default: AbEnd ("Unknown target system type %d", Target); } diff --git a/src/common/target.c b/src/common/target.c index a21ef2125..a35bf67a8 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -174,6 +174,7 @@ static const TargetEntry TargetMap[] = { { "sim6502", TGT_SIM6502 }, { "sim65c02", TGT_SIM65C02 }, { "supervision", TGT_SUPERVISION }, + { "sym1", TGT_SYM1 }, { "telestrat", TGT_TELESTRAT }, { "vic20", TGT_VIC20 }, }; @@ -215,6 +216,7 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "gamate", CPU_6502, BINFMT_BINARY, CTNone }, { "c65", CPU_4510, BINFMT_BINARY, CTPET }, { "cx16", CPU_65C02, BINFMT_BINARY, CTPET }, + { "sym1", CPU_6502, BINFMT_BINARY, CTNone }, }; /* Target system */ diff --git a/src/common/target.h b/src/common/target.h index 50c400e2e..7f85713cf 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -85,6 +85,7 @@ typedef enum { TGT_GAMATE, TGT_C65, TGT_CX16, + TGT_SYM1, TGT_COUNT /* Number of target systems */ } target_t; From aea5db48cbc9207b5d947f0483f6f65e2ea2c31e Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Sun, 9 May 2021 16:55:17 -0500 Subject: [PATCH 2020/2161] fix typo in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c1b8a8b59..76b4cfcac 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ including - the Lynx console. - the Ohio Scientific Challenger 1P. - the Commander X16. -- the Synertek Syetms Sym-1. +- the Synertek Systems Sym-1. The libraries are fairly portable, so creating a version for other 6502s shouldn't be too much work. From f81aefe8bdc0b113bfb1d2ac7e5c7d8a40c33778 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Sun, 9 May 2021 17:13:24 -0500 Subject: [PATCH 2021/2161] Synertek Systems Sym-1 config files --- asminc/sym1.inc | 186 +++++++++++++++++++++++++++++++++++++++++++ cfg/sym1-32k.cfg | 46 +++++++++++ cfg/sym1-4k.cfg | 46 +++++++++++ cfg/sym1.cfg | 46 +++++++++++ doc/sym1.sgml | 135 +++++++++++++++++++++++++++++++ include/symio.h | 148 ++++++++++++++++++++++++++++++++++ samples/helloworld.c | 9 +++ src/ca65/main.c | 3 + 8 files changed, 619 insertions(+) create mode 100644 asminc/sym1.inc create mode 100644 cfg/sym1-32k.cfg create mode 100644 cfg/sym1-4k.cfg create mode 100644 cfg/sym1.cfg create mode 100644 doc/sym1.sgml create mode 100644 include/symio.h create mode 100644 samples/helloworld.c diff --git a/asminc/sym1.inc b/asminc/sym1.inc new file mode 100644 index 000000000..b6a6f17fe --- /dev/null +++ b/asminc/sym1.inc @@ -0,0 +1,186 @@ +; --------------------------------------------------------------------------- +; +; SYM-1 definitions +; +; --------------------------------------------------------------------------- + + +RAMSTART := $0200 ; Entry point + + +; --------------------------------------------------------------------------- +; Monitor Functions +; --------------------------------------------------------------------------- +WARM := $8003 ; Monitor entry +SVNMI := $809B ; Save NMI entry +INBYTE := $81D9 ; Get two HEX characters and pack +ASCNIB := $8275 ; Test for carriage-return +INCCMP := $82B2 ; Increment pointer +CHKSAD := $82DD ; Compute checksum +OUTPC := $82EE ; Display program counter +OUTBYT := $82FA ; Print byte as two ASCII characters +OUTS2 := $8319 ; Print pointer +INSTAT := $8386 ; Determine if key is pressed +GETKEY := $88AF ; Get key (disregarding monitor login) +SCAND := $8906 ; Flash LED display (once) +KEYQ := $8923 ; Test for keypress +BEEP := $8972 ; Make a beep +CONFIG := $89A5 ; Configure I/O +OUTDSP := $89C1 ; Output to on-board LED display +INCHR := $8A1B ; Input character and convert to uppercase +OUTCHR := $8A47 ; Output character +INTCHR := $8A58 ; Input character without case conversion +DLYF := $8AE6 ; Delay 1 bit time +DLYH := $8AE9 ; Delay 1/2 bit time +RESET := $8B4A ; Hard reset +ACCESS := $8B86 ; Unlock lowest 4K memory +NACCES := $8B9C ; Lock lowest 4K memory +L8C78 := $8C78 ; Link to tape +DUMPT := $8E87 ; Dump memory to tape +LOADT := $8C78 ; Load memory from tape +TAPEMODE := $00FD ; Top bit on for high-speed + + +; --------------------------------------------------------------------------- +; System Memory +; --------------------------------------------------------------------------- +DISBUF := $A640 ; On-Board Display Buffer +DISBUF0 := $A640 ; Left-Most digit +DISBUF1 := $A641 ; Second digit +DISBUF2 := $A642 ; Third +DISBUF3 := $A643 ; Fourth +DISBUF4 := $A644 ; Fifth +DISBUF5 := $A645 ; Sixth and right-most digit +DISBUF6 := $A646 ; Not-used / right of display (shift buffer) +RDIG := $A645 ; Right-most digit (same as DISBUF5) +P3L := $A64A ; Parameter 3 (low-byte) +P3H := $A64B ; (high-byte) +P2L := $A64C ; Parameter 2 +P2H := $A64D ; +P1L := $A64E ; Parameter 1 +P1H := $A64F +PARNR := $A649 ; Number of Parameters Entered +PADBIT := $A650 ; Pad Bits for Carriage Return +SDBYT := $A651 ; Baud Rate for RS232 (01-4800,06-2400,10-1200,24-600,4C-300,D5-110) +ERCNT := $A652 ; Error Count (Max FF) +TECHO := $A653 ; Terminal Echo (bit-7=ECHO/NO, 6=CTL-O TOGGLE) +TOUTFL := $A654 ; Output Flags (bit-7=CRT IN, 6=TTY IN, 5=TTY OUT, 4=CRT OUT) +KSHFL := $A655 ; Keyboard Shift Flag +TV := $A656 ; Trace Velocity (0=Single Step) +LSTCOM := $A657 ; Last Monitor Command +MAXRC := $A658 ; Maximum Record Length for Memory Dump + + +; --------------------------------------------------------------------------- +; Register Followers +; --------------------------------------------------------------------------- +PCLR := $A659 ; Program Counter (low-byte) +PCHR := $A65A ; (high-byte) +SR := $A65B ; Stack Pointer +FR := $A65C ; Status Register Flags +AR := $A65D ; A Register +XR := $A65E ; X Register +YR := $A65F ; Y Register + + +; --------------------------------------------------------------------------- +; I/O Vectors (3 bytes each) +; --------------------------------------------------------------------------- +INVEC := $A660 ; Input Character +OUTVEC := $A663 ; Output Character +INSVEC := $A666 ; Input Status +URSVEC := $A669 ; Unrecognized Syntax +URCVEC := $A66C ; Unrecognized Command / Error +SCNVEC := $A66F ; Scan On-board Display + + +; --------------------------------------------------------------------------- +; Trace and Interrupt Vectors (2 bytes each) +; --------------------------------------------------------------------------- +EXEVEC := $A672 ; Exec and Alternate InVec +TRCVEC := $A674 ; Trace +UBRKVC := $A676 ; User Break after Monitor +UIRQVC := $A678 ; User non-break IRQ after Monitor +NMIVEC := $A67A ; Non-Maskable Interrupt +RSTVEC := $A67C ; Reset +IRQVEC := $A67E ; Interrupt Request + + +; --------------------------------------------------------------------------- +; I/O Registers +; --------------------------------------------------------------------------- +; +; 6532 (U27) +; +PADA := $A400 ; Keyboard / Display +P3DA := $A402 ; Serial I/O +DDPADA := $A401 ; Data-Direction Register for PADA +DDP3DA := $A403 ; Data-Direction Register for P3DA +WEDRTA := $A404 ; Write-Edge Detect Read Timer A +WEDRFA := $A405 ; Write-Edge Detect Read-Int Flags A +WEDRTB := $A406 ; Write-Edge Detect Read Timer B +WEDRFB := $A407 ; Write-Edge Detect Read-Int Flags B +TIM0001 := $A41C ; Timer / 1 +TIM0008 := $A41D ; Timer / 8 +TIM0064 := $A41E ; Timer / 64 +TIM1024 := $A41F ; Timer / 1024 +; +; 6522 (U25) +; +OR1A := $A001 ; Input / Output Register for 1A +DDR1A := $A003 ; Data-Direction Register for 1A +OR1B := $A000 ; Input / Output Register for 1B +DDR1B := $A002 ; Data-Direction Register for 1B +TIC1L := $A004 ; +TIC1H := $A005 ; +TIL1L := $A006 ; +TIL1H := $A007 ; +T2L1L := $A008 ; +T2C1L := $A008 ; +T2C1H := $A009 ; +SR1 := $A00A ; +ACR1 := $A00B ; +PCR1 := $A00C ; +IFR1 := $A00D ; +IER1 := $A00E ; +DR1A := $A00F ; +; +; 6522 (U28) +; +OR2A := $A801 ; Input / Output Register for 2A +DDR2A := $A803 ; Data-Direction Register for 2A +OR2B := $A800 ; Input / Output Register for 2B +DDR2B := $A802 ; Data-Direction Register for 2B +TIC2L := $A804 ; +TIC2H := $A805 ; +TIL2L := $A806 ; +TIL2H := $A807 ; +T2L2L := $A808 ; +T2C2L := $A808 ; +T2C2H := $A809 ; +SR2 := $A80A ; +ACR2 := $A80B ; +PCR2 := $A80C ; +IFR2 := $A80D ; +IER2 := $A80E ; +DR2A := $A80F ; +; +; 6522 (U29) +; +OR3A := $AC01 ; Write-Protect RAM, Debug On/Off, I/O-3A +DDR3A := $AC03 ; Data-Direction Register for 3A +OR3B := $AC00 ; Input / Output Register for 3B +DDR3B := $AC02 ; Data-Direction Register for 3B +TIC3L := $AC04 ; +TIC3H := $AC05 ; +TIL3L := $AC06 ; +TIL3H := $AC07 ; +T2L3L := $AC08 ; +T2C3L := $AC08 ; +T2C3H := $AC09 ; +SR3 := $AC0A ; +ACR3 := $AC0B ; +PCR3 := $AC0C ; +IFR3 := $AC0D ; +IER3 := $AC0E ; +DR3A := $AC0F ; diff --git a/cfg/sym1-32k.cfg b/cfg/sym1-32k.cfg new file mode 100644 index 000000000..14ddfb98f --- /dev/null +++ b/cfg/sym1-32k.cfg @@ -0,0 +1,46 @@ +# sym1-32k.cfg (32k) +# +# for Sym-1 with 32kb RAM +# +# ld65 --config sym1-32k.cfg -o <prog>.bin <prog>.o + +FEATURES { + STARTADDRESS: default = $0200; + 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 = $0200; # 512 byte program stack + __STARTADDRESS__: type = export, value = %S; +} + +MEMORY { + ZP: start = $0000, size = $00F7, define = yes, file = %O; + CPUSTACK: start = $0100, size = $0100, define = yes; + RAM: start = %S, size = $8000 - %S - __STACKSIZE__, define = yes, file = %O; + MONROM: start = $8000, size = $1000, define = yes; + EXT: start = $9000, size = $1000, define = yes; + IO: start = $A000, size = $1000, define = yes; + RAE1: start = $B000, size = $1000, define = yes; + BASROM: start = $C000, size = $1000, define = yes; + RAE2: start = $E000, size = $1000, define = yes; + TOP: start = $F000, size = $1000, define = yes; +} + +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/sym1-4k.cfg b/cfg/sym1-4k.cfg new file mode 100644 index 000000000..240d7bc82 --- /dev/null +++ b/cfg/sym1-4k.cfg @@ -0,0 +1,46 @@ +# sym1-4k.cfg (4k) +# +# for Sym-1 with 4kb RAM +# +# ld65 --config sym1-4k.cfg -o <prog>.bin <prog>.o + +FEATURES { + STARTADDRESS: default = $0200; + 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: start = $0000, size = $00F7, define = yes, file = %O; + CPUSTACK: start = $0100, size = $0100, define = yes; + RAM: start = %S, size = $1000 - %S - __STACKSIZE__, define = yes, file = %O; + MONROM: start = $8000, size = $1000, define = yes; + EXT: start = $9000, size = $1000, define = yes; + IO: start = $A000, size = $1000, define = yes; + RAE1: start = $B000, size = $1000, define = yes; + BASROM: start = $C000, size = $1000, define = yes; + RAE2: start = $E000, size = $1000, define = yes; + TOP: start = $F000, size = $1000, define = yes; +} + +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/sym1.cfg b/cfg/sym1.cfg new file mode 100644 index 000000000..240d7bc82 --- /dev/null +++ b/cfg/sym1.cfg @@ -0,0 +1,46 @@ +# sym1-4k.cfg (4k) +# +# for Sym-1 with 4kb RAM +# +# ld65 --config sym1-4k.cfg -o <prog>.bin <prog>.o + +FEATURES { + STARTADDRESS: default = $0200; + 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: start = $0000, size = $00F7, define = yes, file = %O; + CPUSTACK: start = $0100, size = $0100, define = yes; + RAM: start = %S, size = $1000 - %S - __STACKSIZE__, define = yes, file = %O; + MONROM: start = $8000, size = $1000, define = yes; + EXT: start = $9000, size = $1000, define = yes; + IO: start = $A000, size = $1000, define = yes; + RAE1: start = $B000, size = $1000, define = yes; + BASROM: start = $C000, size = $1000, define = yes; + RAE2: start = $E000, size = $1000, define = yes; + TOP: start = $F000, size = $1000, define = yes; +} + +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/doc/sym1.sgml b/doc/sym1.sgml new file mode 100644 index 000000000..d02e3b1b1 --- /dev/null +++ b/doc/sym1.sgml @@ -0,0 +1,135 @@ +<!doctype linuxdoc system> + +<article> +<title>Synertek Systems Sym-1 specific information for cc65 +<author><url url="mailto:wayne@parhamdata.com" name="Wayne Parham"> + +<abstract> +An overview over the Sym-1 runtime system as it is implemented for the cc65 C compiler. +</abstract> + +<!-- Table of contents --> +<toc> + +<!-- Begin the document --> + +<sect>Overview<p> + +This file contains an overview of the Sym-1 runtime system as it comes with the cc65 C compiler. It describes the memory layout, Sym-1 specific header files, available drivers, and any pitfalls specific to the platform. + +Please note that Sym-1 specific functions are just mentioned here, they are described in detail in the separate <url url="funcref.html" name="function reference">. Even functions marked as "platform dependent" may be available on more than one platform. Please see the function reference for more information. + +<sect>Binary format<p> + +The standard binary output format generated by the linker for the Sym-1 target is a 4 kbyte machine language program. It is, of course, possible to change this behavior by using one of the different linker configs. + +<p> + +Included with this distribution is a 4k configuration file and a 32k config file. The Sym-1 on-board memory is limited to 4k but system memory can be increased to 32 kbytes of contiguous RAM with aftermarket add-on boards. So choose the config file that matches your system configuration before compiling and linking user programs. + +<sect>Memory layout<p> + +The ROMs and I/O areas are defined in the configuration files, as are most of the entry points for useful subroutines in the Sym-1 monitor ROM. cc65 generated programs compiled and linked using 4k config run in the memory range of $200 - $0FFF. The 32k config expands this range to $7FFF. The starting memory location and entry point for running the program is $200, so when the program is transferred to the Sym-1, it is executed by typing 'g 200'. The system returns control back to the monitor ROM when the program terminates, providing the '.' prompt. + +Special locations: + +<descrip> + <tag/Text screen/ + Conio support is not currently available for the Sym-1. But stdio console functions are available. + + <tag/Stack/ + The C runtime stack is located at $0FFF on 4kb Syms, or at $7FFFfor 32kb systems. The stack always grows downwards. + + <tag/Heap/ + The C heap is located at the end of the program and grows towards the C + runtime stack. + +</descrip><p> + +<sect>Platform specific header files<p> + +Programs containing Sym-1 code may use the <tt/symio.h/ header file. See the header file for more information. + +<sect1>Hardware access<p> + +The following pseudo variables declared in the <tt/sym1.inc/ include file allow access to hardware located in the address space. See the include file for more information. + +<sect>Loadable drivers<p> + +<sect1>Graphics drivers<p> + +No graphics drivers are currently available for the Sym-1. + +<sect1>Extended memory drivers<p> + +No extended memory drivers are currently available for the Sym-1. + +<sect1>Joystick drivers<p> + +No joystick driver is currently available for the Sym-1. + +<sect1>Mouse drivers<p> + +No mouse drivers are currently available for the Sym-1. + +<sect1>RS232 device drivers<p> + +No communication port drivers are currently available for the Sym-1. It has only the "master console" e.g. stdin and stdout. + +<sect>Limitations<p> + +<sect1>Disk I/O<p> + +The existing library for the Sym-1 doesn't implement C file I/O. + +To be more specific, this limitation means that you cannot use any of the following functions (and a few others): + +<itemize> +<item>fopen +<item>fclose +<item>fread +<item>fwrite +<item>... +</itemize> + +<sect>Other hints<p> + +<sect1>symio.h<p> +You can use stdio.h if you wish, which provides console I/O (like printf) but does not have access to a filesystem, as mentioned above. + +But there is another header available, which exposes Sym-specific I/O functions that are useful for reading and writing its ports and front panel. It also exposes functions normally included using stdio.h but <i>only</i> the console I/O functions and not the filesystem functions. See the symio.h include file for a list of the functions available. + +<sect2>Limited memory applications<p> + +As stated earlier, there are config files for 4kb and 32kb systems. If you have 32kb RAM, then you will probably want to use the sym1_32k configuration, but if not - if you are using the sym1_32k configuration - then you may want to use functions like getchar, putchar, gets and puts rather than printf. Printf requires about 1kb because it needs to know how to process all the format specifiers. + +<sect3>Sample programs<p> + +All the samples will run on the "stock" 4k Sym-1, except for symio.c, which requires 8k. Information on building and running it is in the samples/tutorial/sym1 directory. + +<itemize> +<item>helloworld is the traditional "Hello World!" program, using printf().</item> +<item>symHello prints "Hello World!" and then inputs characters, which are echoed on the screen. It also makes a "beep" sound.</item> +<item>symTiny does the same as symhello, but does it with puts() rather than printf() to show the difference in compiled binary size.</item> +<item>symDisplay allows entry of a message, which is then displayed by scrolling it across the front panel display.</item> +<item>symIO allows access to the Sym-1 digital I/O ports.</item> +</itemize> + +<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/include/symio.h b/include/symio.h new file mode 100644 index 000000000..bd90a42f9 --- /dev/null +++ b/include/symio.h @@ -0,0 +1,148 @@ +// symio.h +// +// I/O primitives for Sym-1 +// +// Wayne Parham + +#ifndef _SYMIO_H +#define _SYMIO_H + +#include <stddef.h> +#include <stdarg.h> + +int __fastcall__ beep (void); // Beep sound +int __fastcall__ set_D0 (char); // Set display digit 0 +int __fastcall__ get_D0 (void); // Get value of display digit 0 +int __fastcall__ set_D1 (char); // Set display digit 1 +int __fastcall__ get_D1 (void); // Get value of display digit 1 +int __fastcall__ set_D2 (char); // Set display digit 2 +int __fastcall__ get_D2 (void); // Get value of display digit 2 +int __fastcall__ set_D3 (char); // Set display digit 3 +int __fastcall__ get_D3 (void); // Get value of display digit 3 +int __fastcall__ set_D4 (char); // Set display digit 4 +int __fastcall__ get_D4 (void); // Get value of display digit 4 +int __fastcall__ set_D5 (char); // Set display digit 5 +int __fastcall__ get_D5 (void); // Get value of display digit 5 +int __fastcall__ set_D6 (char); // Set byte to the right of display (leading buffer) +int __fastcall__ get_D6 (void); // Get value of memory byte to the right of display +int __fastcall__ fdisp (void); // Flash display + +int __fastcall__ loadt (int); // Read from tape (id) +int __fastcall__ dumpt (int, int, int); // Write to tape (id, start_addr, end_addr) + +int __fastcall__ set_DDR1A (int); // Set data direction register 1A (U25) +int __fastcall__ get_DDR1A (void); // Get value of data direction register 1A +int __fastcall__ set_IOR1A (int); // Set I/O register 1A +int __fastcall__ get_IOR1A (void); // Get value of I/O register 1A + +int __fastcall__ set_DDR1B (int); // Set data direction register 1B (U25) +int __fastcall__ get_DDR1B (void); // Get value of data direction register 1B +int __fastcall__ set_IOR1B (int); // Set I/O register 1B +int __fastcall__ get_IOR1B (void); // Get value of I/O register 1B + +int __fastcall__ set_DDR2A (int); // Set data direction register 2A (U28) +int __fastcall__ get_DDR2A (void); // Get value of data direction register 2A +int __fastcall__ set_IOR2A (int); // Set I/O register 2A +int __fastcall__ get_IOR2A (void); // Get value of I/O register 2A + +int __fastcall__ set_DDR2B (int); // Set data direction register 2B (U28) +int __fastcall__ get_DDR2B (void); // Get value of data direction register 2B +int __fastcall__ set_IOR2B (int); // Set I/O register 2B +int __fastcall__ get_IOR2B (void); // Get value of I/O register 2B + +int __fastcall__ set_DDR3A (int); // Set data direction register 3A (U29) +int __fastcall__ get_DDR3A (void); // Get value of data direction register 3A +int __fastcall__ set_IOR3A (int); // Set I/O register 3A +int __fastcall__ get_IOR3A (void); // Get value of I/O register 3A + +int __fastcall__ set_DDR3B (int); // Set data direction register 3B (U29) +int __fastcall__ get_DDR3B (void); // Get value of data direction register 3B +int __fastcall__ set_IOR3B (int); // Set I/O register 3B +int __fastcall__ get_IOR3B (void); // Get value of I/O register 3B + +#ifndef _STDIO_H + +int __fastcall__ putchar (char); +int __fastcall__ puts (const char* s); +int printf (const char* format, ...); +int sprintf (char* buf, const char* format, ...); +int __fastcall__ vprintf (const char* format, va_list ap); +int __fastcall__ vsnprintf (char* buf, size_t size, const char* format, va_list ap); +int __fastcall__ vsprintf (char* buf, const char* format, va_list ap); +char __fastcall__ getchar (void); +char* __fastcall__ gets (char* s); +int scanf (const char* format, ...); +int sscanf (const char* s, const char* format, ...); +int __fastcall__ vscanf (const char* format, va_list ap); +int __fastcall__ vsscanf (const char* s, const char* format, va_list ap); + +#endif + +// Display character definitions + +#define DISP_1 0x06 // '1' +#define DISP_2 0x5B // '2' +#define DISP_3 0x4F // '3' +#define DISP_4 0x66 // '4' +#define DISP_5 0x6D // '5' +#define DISP_6 0x7C // '6' +#define DISP_7 0x07 // '7' +#define DISP_8 0x7F // '8' +#define DISP_9 0x67 // '9' +#define DISP_0 0x3F // '0' +#define DISP_A 0x77 // 'A' +#define DISP_b 0x7C // 'b' +#define DISP_C 0x39 // 'C' +#define DISP_c 0x58 // 'c' +#define DISP_d 0x5E // 'd' +#define DISP_E 0x79 // 'E' +#define DISP_e 0x7B // 'e' +#define DISP_F 0x71 // 'F' +#define DISP_G 0x7D // 'G' +#define DISP_g 0x6F // 'g' +#define DISP_H 0x76 // 'H' +#define DISP_h 0x74 // 'h' +#define DISP_I 0x06 // 'I' +#define DISP_i 0x04 // 'i' +#define DISP_J 0x1E // 'J' +#define DISP_K 0x74 // 'K' +#define DISP_L 0x38 // 'L' +#define DISP_M_1 0x33 // 'M' +#define DISP_M_2 0x27 // 2nd half +#define DISP_n 0x54 // 'n' +#define DISP_O 0x3F // 'O' +#define DISP_o 0x5C // 'o' +#define DISP_P 0x73 // 'P' +#define DISP_q 0x67 // 'q' +#define DISP_r 0x50 // 'r' +#define DISP_S 0x6D // 'S' +#define DISP_t 0x46 // 't' +#define DISP_U 0x3E // 'U' +#define DISP_u 0x1C // 'u' +#define DISP_V_1 0x64 // 'V' +#define DISP_V_2 0x52 // 2nd half +#define DISP_W_1 0x3C // 'W' +#define DISP_W_2 0x1E // 2nd half +#define DISP_Y 0x6E // 'Y' +#define DISP_Z 0x5B // 'Z' +#define DISP_SPACE 0x00 // ' ' +#define DISP_PERIOD 0x80 // '.' +#define DISP_HYPHEN 0x40 // '-' +#define DISP_APOSTR 0x20 // ''' +#define DISP_EQUAL 0x41 // '=' +#define DISP_3_BAR 0x49 // '=' +#define DISP_BOTTOM 0x04 // '_' +#define DISP_TOP 0x01 // Top segment +#define DISP_LEFT 0x30 // '|' Left side, both segments +#define DISP_RIGHT 0x06 // '|' Right side, both segments +#define DISP_DEGREE 0x63 // 'o' An 'o' character in the upper segments +#define DISP_HAT 0x23 // 'n' An 'n' character in the upper segments +#define DISP_FORK 0x62 // 'u' A 'u' character in the upper segments +#define DISP_SLASH 0x51 // '/' +#define DISP_BACKSLASH 0x34 // '\' +#define DISP_TOP_RIGHT 0x02 // Top right segment +#define DISP_TOP_LEFT 0x20 // Top left segment +#define DISP_LOW_RIGHT 0x04 // Lower right segment +#define DISP_LOW_LEFT 0x10 // Lower left segment + +#endif diff --git a/samples/helloworld.c b/samples/helloworld.c new file mode 100644 index 000000000..057a153e8 --- /dev/null +++ b/samples/helloworld.c @@ -0,0 +1,9 @@ +// Traditional "Hello World" program + +#include <stdio.h> + +void main (void) +{ + printf( "Hello World!\n" ); + return; +} diff --git a/src/ca65/main.c b/src/ca65/main.c index ab19d0b4d..bb0607b7c 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -334,6 +334,9 @@ static void SetSys (const char* Sys) CBMSystem ("__CX16__"); break; + case TGT_SYM1: + break; + default: AbEnd ("Invalid target name: '%s'", Sys); From 27e04b36b0e85cc73bd24f17e4d13417cd7290e2 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Sun, 9 May 2021 17:24:15 -0500 Subject: [PATCH 2022/2161] Makefile updates --- samples/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/samples/Makefile b/samples/Makefile index e3b28057f..8a3edc412 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -8,6 +8,10 @@ # var. to build for another target system. SYS ?= c64 +# New targets can define MACHINE separately +# from target if needed. +MACHINE=$(SYS) + # Just the usual way to define a variable # containing a single space character. SPACE := From a2def19de5dba20f52fcff6eb2cdfa9df899504e Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Mon, 10 May 2021 15:20:49 +0100 Subject: [PATCH 2023/2161] Added TGT_SYM1 --- src/cc65/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/main.c b/src/cc65/main.c index 9e9fab6b4..d0d756b3f 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -290,7 +290,7 @@ static void SetSys (const char* Sys) cbmsys ("__CX16__"); break; - case TGT_NONE: + case TGT_SYM1: break; default: From b7856ddd4f9b73b0a40a284bd782de545986f801 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Tue, 11 May 2021 10:40:44 +0200 Subject: [PATCH 2024/2161] Just some source formatting adjustments. --- src/cc65/funcdesc.c | 16 ++++++++-------- src/cc65/funcdesc.h | 34 +++++++++++++++++----------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/cc65/funcdesc.c b/src/cc65/funcdesc.c index 4c959fb6c..2291b35ee 100644 --- a/src/cc65/funcdesc.c +++ b/src/cc65/funcdesc.c @@ -54,14 +54,14 @@ FuncDesc* NewFuncDesc (void) FuncDesc* F = (FuncDesc*) xmalloc (sizeof (FuncDesc)); /* Nullify the fields */ - F->Flags = 0; - F->SymTab = 0; - F->TagTab = 0; - F->ParamCount = 0; - F->ParamSize = 0; - F->LastParam = 0; - F->FuncDef = 0; - F->WrappedCall = 0; + F->Flags = 0; + F->SymTab = 0; + F->TagTab = 0; + F->ParamCount = 0; + F->ParamSize = 0; + F->LastParam = 0; + F->FuncDef = 0; + F->WrappedCall = 0; F->WrappedCallData = 0; /* Return the new struct */ diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h index 423e7621f..b69cfa850 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -45,15 +45,15 @@ /* Masks for the Flags field in FuncDesc */ -#define FD_NONE 0x0000U /* No flags */ -#define FD_EMPTY 0x0001U /* Function with empty param list */ -#define FD_VOID_PARAM 0x0002U /* Function with a void param list */ -#define FD_VARIADIC 0x0004U /* Function with variable param list */ +#define FD_NONE 0x0000U /* No flags */ +#define FD_EMPTY 0x0001U /* Function with empty param list */ +#define FD_VOID_PARAM 0x0002U /* Function with a void param list */ +#define FD_VARIADIC 0x0004U /* Function with variable param list */ #define FD_INCOMPLETE_PARAM 0x0008U /* Function with param of unknown size */ -#define FD_OLDSTYLE 0x0010U /* Old style (K&R) function */ -#define FD_OLDSTYLE_INTRET 0x0020U /* K&R func has implicit int return */ -#define FD_UNNAMED_PARAMS 0x0040U /* Function has unnamed params */ -#define FD_CALL_WRAPPER 0x0080U /* This function is used as a wrapper */ +#define FD_OLDSTYLE 0x0010U /* Old style (K&R) function */ +#define FD_OLDSTYLE_INTRET 0x0020U /* K&R func has implicit int return */ +#define FD_UNNAMED_PARAMS 0x0040U /* Function has unnamed params */ +#define FD_CALL_WRAPPER 0x0080U /* This function is used as a wrapper */ /* Bits that must be ignored when comparing funcs */ #define FD_IGNORE (FD_INCOMPLETE_PARAM | FD_OLDSTYLE | FD_OLDSTYLE_INTRET | FD_UNNAMED_PARAMS | FD_CALL_WRAPPER) @@ -63,15 +63,15 @@ /* Function descriptor */ typedef struct FuncDesc FuncDesc; struct FuncDesc { - unsigned Flags; /* Bitmapped flags FD_... */ - struct SymTable* SymTab; /* Symbol table */ - struct SymTable* TagTab; /* Symbol table for structs/enums */ - unsigned ParamCount; /* Number of parameters */ - 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 char WrappedCallData;/* The WrappedCall's user data */ + unsigned Flags; /* Bitmapped flags FD_... */ + struct SymTable* SymTab; /* Symbol table */ + struct SymTable* TagTab; /* Symbol table for structs/enums */ + unsigned ParamCount; /* Number of parameters */ + 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 char WrappedCallData; /* The WrappedCall's user data */ }; From ef8c70c7affb4c423af17fcc87a2308ad4284a46 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 11 May 2021 13:36:30 +0200 Subject: [PATCH 2025/2161] use url instead of htmlurl, add note on least significant 8bits of the bank value --- doc/cc65.sgml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index f4b31b8bc..7912b85a9 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1389,9 +1389,11 @@ parameter with the <tt/#pragma/. in their prototypes). The identifier is an 8-bit number that's set into <tt/tmp4/. If the identifier - is "bank", then a <tt><htmlurl url="ca65.html#.BANK" name=".bank"></tt> operator will be used + is "bank", then a <tt><url url="ca65.html#.BANK" name=".bank"></tt> operator will be used to determine the number from the bank attribute defined in the linker config, - see <htmlurl url="ld65.html#MEMORY" name="Other MEMORY area attributes">. + see <htmlurl url="ld65.html#MEMORY" name="Other MEMORY area attributes">. Note that + this currently implies that only the least significant 8 bits of the bank attribute + can be used. The address of a wrapped function is passed in <tt/ptr4/. The wrapper can call that function by using "<tt/jsr callptr4/". From ef742269931a36142facca4e42d938ce7fd4257a Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 11 May 2021 13:37:53 +0200 Subject: [PATCH 2026/2161] improve error message --- src/cc65/pragma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 249e4f1b4..84869e60f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -532,7 +532,7 @@ static void WrappedCallPragma (StrBuf* B) /* Skip the following comma */ if (!GetComma (B)) { /* Error already flagged by GetComma */ - Error ("Value required for wrapped-call identifier"); + Error ("Value or the word 'bank' required for wrapped-call identifier"); goto ExitPoint; } From 18f94d1fe0b2b04c723419a4df9078f77c88c0a0 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 11 May 2021 14:00:49 +0200 Subject: [PATCH 2027/2161] rework to use a magic value instead of a flag, as suggested by Oliver --- src/cc65/declare.c | 6 ++---- src/cc65/expr.c | 2 +- src/cc65/funcdesc.h | 5 ++--- src/cc65/pragma.c | 7 +++---- src/cc65/wrappedcall.c | 9 ++++----- src/cc65/wrappedcall.h | 4 ++-- 6 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0b705a320..8879c46d8 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1738,8 +1738,7 @@ static FuncDesc* ParseFuncDecl (void) { SymEntry* Sym; SymEntry* WrappedCall; - unsigned char WrappedCallData; - int WrappedCallUseBank; + unsigned int WrappedCallData; /* Create a new function descriptor */ FuncDesc* F = NewFuncDesc (); @@ -1792,11 +1791,10 @@ static FuncDesc* ParseFuncDecl (void) RememberFunctionLevel (F); /* Did we have a WrappedCall for this function? */ - GetWrappedCall((void **) &WrappedCall, &WrappedCallData, &WrappedCallUseBank); + GetWrappedCall((void **) &WrappedCall, &WrappedCallData); if (WrappedCall) { F->WrappedCall = WrappedCall; F->WrappedCallData = WrappedCallData; - F->WrappedCallUseBank = WrappedCallUseBank; } /* Return the function descriptor */ diff --git a/src/cc65/expr.c b/src/cc65/expr.c index d2cd4ca5c..01bebf18e 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -997,7 +997,7 @@ static void FunctionCall (ExprDesc* Expr) char tmp[64]; StrBuf S = AUTO_STRBUF_INITIALIZER; - if (Func->WrappedCallUseBank) { + if (Func->WrappedCallData == WRAPPED_CALL_USE_BANK) { /* Store the bank attribute in tmp4 */ SB_AppendStr (&S, "ldy #<.bank(_"); SB_AppendStr (&S, (const char*) Expr->Name); diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h index 5875723fb..305fd14f5 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -58,7 +58,7 @@ /* Bits that must be ignored when comparing funcs */ #define FD_IGNORE (FD_INCOMPLETE_PARAM | FD_OLDSTYLE | FD_OLDSTYLE_INTRET | FD_UNNAMED_PARAMS | FD_CALL_WRAPPER) - +#define WRAPPED_CALL_USE_BANK 0x0100U /* WrappedCall uses .bank() */ /* Function descriptor */ typedef struct FuncDesc FuncDesc; @@ -71,8 +71,7 @@ struct FuncDesc { struct SymEntry* LastParam; /* Pointer to last parameter */ struct FuncDesc* FuncDef; /* Descriptor used in definition */ struct SymEntry* WrappedCall; /* Pointer to the WrappedCall */ - unsigned char WrappedCallData;/* The WrappedCall's user data */ - int WrappedCallUseBank;/* Flag: does WrappedCall use .bank() or literal value */ + unsigned int WrappedCallData;/* The WrappedCall's user data */ }; diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 84869e60f..e4bb4cdeb 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -497,7 +497,6 @@ static void WrappedCallPragma (StrBuf* B) const char *Name; long Val; SymEntry *Entry; - int UseBank = 0; /* Check for the "push" or "pop" keywords */ switch (ParsePushPop (B)) { @@ -538,13 +537,13 @@ static void WrappedCallPragma (StrBuf* B) /* Next must be either a numeric value, or "bank" */ if (HasStr (B, "bank")) { - UseBank = 1; + Val = WRAPPED_CALL_USE_BANK; } else if (!GetNumber (B, &Val)) { Error ("Value required for wrapped-call identifier"); goto ExitPoint; } - if (!UseBank && (Val < 0 || Val > 255)) { + if (!(Val == WRAPPED_CALL_USE_BANK) && (Val < 0 || Val > 255)) { Error ("Identifier must be between 0-255"); goto ExitPoint; } @@ -556,7 +555,7 @@ static void WrappedCallPragma (StrBuf* B) /* Check if the name is valid */ if (Entry && (Entry->Flags & SC_FUNC) == SC_FUNC) { - PushWrappedCall(Entry, (unsigned char) Val, UseBank); + PushWrappedCall(Entry, (unsigned int) Val); Entry->Flags |= SC_REF; GetFuncDesc (Entry->Type)->Flags |= FD_CALL_WRAPPER; diff --git a/src/cc65/wrappedcall.c b/src/cc65/wrappedcall.c index a67f9815d..ecf2c3a53 100644 --- a/src/cc65/wrappedcall.c +++ b/src/cc65/wrappedcall.c @@ -64,13 +64,13 @@ static IntPtrStack WrappedCalls; -void PushWrappedCall (void *Ptr, unsigned char Val, int UseBank) +void PushWrappedCall (void *Ptr, unsigned int Val) /* Push the current WrappedCall */ { if (IPS_IsFull (&WrappedCalls)) { Error ("WrappedCall stack overflow"); } else { - IPS_Push (&WrappedCalls, Val | (UseBank << 8), Ptr); + IPS_Push (&WrappedCalls, Val, Ptr); } } @@ -88,7 +88,7 @@ void PopWrappedCall (void) -void GetWrappedCall (void **Ptr, unsigned char *Val, int *UseBank) +void GetWrappedCall (void **Ptr, unsigned int *Val) /* Get the current WrappedCall */ { if (IPS_GetCount (&WrappedCalls) < 1) { @@ -97,7 +97,6 @@ void GetWrappedCall (void **Ptr, unsigned char *Val, int *UseBank) } else { long Temp; IPS_Get (&WrappedCalls, &Temp, Ptr); - *UseBank = (int) Temp >> 8; - *Val = (unsigned char) Temp & 0xff; + *Val = (unsigned int) Temp; } } diff --git a/src/cc65/wrappedcall.h b/src/cc65/wrappedcall.h index ddf6dd2b9..9a1bb51bf 100644 --- a/src/cc65/wrappedcall.h +++ b/src/cc65/wrappedcall.h @@ -50,13 +50,13 @@ -void PushWrappedCall (void *Ptr, unsigned char Val, int usebank); +void PushWrappedCall (void *Ptr, unsigned int Val); /* Push the current WrappedCall */ void PopWrappedCall (void); /* Pop the current WrappedCall */ -void GetWrappedCall (void **Ptr, unsigned char *Val, int *usebank); +void GetWrappedCall (void **Ptr, unsigned int *Val); /* Get the current WrappedCall, if any */ From 07dd1e3849672f8c1487ef652611f745a96a90da Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 11 May 2021 14:14:44 +0200 Subject: [PATCH 2028/2161] fix formatting --- src/cc65/funcdesc.c | 16 ++++++++-------- src/cc65/funcdesc.h | 34 +++++++++++++++++----------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/cc65/funcdesc.c b/src/cc65/funcdesc.c index 4c959fb6c..2291b35ee 100644 --- a/src/cc65/funcdesc.c +++ b/src/cc65/funcdesc.c @@ -54,14 +54,14 @@ FuncDesc* NewFuncDesc (void) FuncDesc* F = (FuncDesc*) xmalloc (sizeof (FuncDesc)); /* Nullify the fields */ - F->Flags = 0; - F->SymTab = 0; - F->TagTab = 0; - F->ParamCount = 0; - F->ParamSize = 0; - F->LastParam = 0; - F->FuncDef = 0; - F->WrappedCall = 0; + F->Flags = 0; + F->SymTab = 0; + F->TagTab = 0; + F->ParamCount = 0; + F->ParamSize = 0; + F->LastParam = 0; + F->FuncDef = 0; + F->WrappedCall = 0; F->WrappedCallData = 0; /* Return the new struct */ diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h index 305fd14f5..e065c7602 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -45,15 +45,15 @@ /* Masks for the Flags field in FuncDesc */ -#define FD_NONE 0x0000U /* No flags */ -#define FD_EMPTY 0x0001U /* Function with empty param list */ -#define FD_VOID_PARAM 0x0002U /* Function with a void param list */ -#define FD_VARIADIC 0x0004U /* Function with variable param list */ +#define FD_NONE 0x0000U /* No flags */ +#define FD_EMPTY 0x0001U /* Function with empty param list */ +#define FD_VOID_PARAM 0x0002U /* Function with a void param list */ +#define FD_VARIADIC 0x0004U /* Function with variable param list */ #define FD_INCOMPLETE_PARAM 0x0008U /* Function with param of unknown size */ -#define FD_OLDSTYLE 0x0010U /* Old style (K&R) function */ -#define FD_OLDSTYLE_INTRET 0x0020U /* K&R func has implicit int return */ -#define FD_UNNAMED_PARAMS 0x0040U /* Function has unnamed params */ -#define FD_CALL_WRAPPER 0x0080U /* This function is used as a wrapper */ +#define FD_OLDSTYLE 0x0010U /* Old style (K&R) function */ +#define FD_OLDSTYLE_INTRET 0x0020U /* K&R func has implicit int return */ +#define FD_UNNAMED_PARAMS 0x0040U /* Function has unnamed params */ +#define FD_CALL_WRAPPER 0x0080U /* This function is used as a wrapper */ /* Bits that must be ignored when comparing funcs */ #define FD_IGNORE (FD_INCOMPLETE_PARAM | FD_OLDSTYLE | FD_OLDSTYLE_INTRET | FD_UNNAMED_PARAMS | FD_CALL_WRAPPER) @@ -63,15 +63,15 @@ /* Function descriptor */ typedef struct FuncDesc FuncDesc; struct FuncDesc { - unsigned Flags; /* Bitmapped flags FD_... */ - struct SymTable* SymTab; /* Symbol table */ - struct SymTable* TagTab; /* Symbol table for structs/enums */ - unsigned ParamCount; /* Number of parameters */ - 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 */ + unsigned Flags; /* Bitmapped flags FD_... */ + struct SymTable* SymTab; /* Symbol table */ + struct SymTable* TagTab; /* Symbol table for structs/enums */ + unsigned ParamCount; /* Number of parameters */ + 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 */ }; From bcc670ee36ac00155e6a763f97eb3791ab9d0ddc Mon Sep 17 00:00:00 2001 From: Andrea Odetti <mariofutire@gmail.com> Date: Mon, 10 May 2021 09:56:40 +0100 Subject: [PATCH 2029/2161] Standard formatting of error messages. https://www.gnu.org/prep/standards/html_node/Errors.html Issue: https://github.com/cc65/cc65/issues/1494 --- src/ca65/error.c | 2 +- src/cc65/error.c | 8 ++++---- src/cc65/pragma.c | 2 +- src/cc65/preproc.c | 2 +- src/da65/asminc.c | 8 ++++---- src/da65/scanner.c | 4 ++-- src/ld65/asserts.c | 4 ++-- src/ld65/exports.c | 8 +++++--- src/ld65/scanner.c | 4 ++-- 9 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/ca65/error.c b/src/ca65/error.c index 69446b3fc..7e1457964 100644 --- a/src/ca65/error.c +++ b/src/ca65/error.c @@ -84,7 +84,7 @@ static void VPrintMsg (const FilePos* Pos, const char* Desc, SB_Terminate (&Msg); /* Format the message header */ - SB_Printf (&S, "%s(%u): %s: ", + SB_Printf (&S, "%s:%u: %s: ", SB_GetConstBuf (GetFileName (Pos->Name)), Pos->Line, Desc); diff --git a/src/cc65/error.c b/src/cc65/error.c index b1529d0b5..f0e023969 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -129,7 +129,7 @@ void Fatal (const char* Format, ...) LineNum = GetCurrentLine (); } - fprintf (stderr, "%s(%u): Fatal: ", FileName, LineNum); + fprintf (stderr, "%s:%u: Fatal: ", FileName, LineNum); va_start (ap, Format); vfprintf (stderr, Format, ap); @@ -159,7 +159,7 @@ void Internal (const char* Format, ...) LineNum = GetCurrentLine (); } - fprintf (stderr, "%s(%u): Internal compiler error:\n", + fprintf (stderr, "%s:%u: Internal compiler error:\n", FileName, LineNum); va_start (ap, Format); @@ -186,7 +186,7 @@ void Internal (const char* Format, ...) static void IntError (const char* Filename, unsigned LineNo, const char* Msg, va_list ap) /* Print an error message - internal function*/ { - fprintf (stderr, "%s(%u): Error: ", Filename, LineNo); + fprintf (stderr, "%s:%u: Error: ", Filename, LineNo); vfprintf (stderr, Msg, ap); fprintf (stderr, "\n"); @@ -250,7 +250,7 @@ static void IntWarning (const char* Filename, unsigned LineNo, const char* Msg, } else if (IS_Get (&WarnEnable)) { - fprintf (stderr, "%s(%u): Warning: ", Filename, LineNo); + fprintf (stderr, "%s:%u: Warning: ", Filename, LineNo); vfprintf (stderr, Msg, ap); fprintf (stderr, "\n"); diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index e4bb4cdeb..b0478ce2a 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -784,7 +784,7 @@ static void IntPragma (StrBuf* B, IntStack* Stack, long Low, long High) static void MakeMessage (const char* Message) { - fprintf (stderr, "%s(%u): Note: %s\n", GetInputName (CurTok.LI), GetInputLine (CurTok.LI), Message); + fprintf (stderr, "%s:%u: Note: %s\n", GetInputName (CurTok.LI), GetInputLine (CurTok.LI), Message); } diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index cc160c1c3..37073e784 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -1396,7 +1396,7 @@ void Preprocess (void) Done: if (Verbosity > 1 && SB_NotEmpty (Line)) { - printf ("%s(%u): %.*s\n", GetCurrentFile (), GetCurrentLine (), + printf ("%s:%u: %.*s\n", GetCurrentFile (), GetCurrentLine (), (int) SB_GetLen (Line), SB_GetConstBuf (Line)); } } diff --git a/src/da65/asminc.c b/src/da65/asminc.c index 59ba0aab4..4d9da2594 100644 --- a/src/da65/asminc.c +++ b/src/da65/asminc.c @@ -133,7 +133,7 @@ void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown) SB_Terminate (&Ident); } else { if (!IgnoreUnknown) { - Error ("%s(%u): Syntax error", Filename, Line); + Error ("%s:%u: Syntax error", Filename, Line); } continue; } @@ -148,7 +148,7 @@ void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown) ++L; } else { if (!IgnoreUnknown) { - Error ("%s(%u): Missing '='", Filename, Line); + Error ("%s:%u: Missing '='", Filename, Line); } continue; } @@ -192,7 +192,7 @@ void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown) /* Must have at least one digit */ if (Digits == 0) { if (!IgnoreUnknown) { - Error ("%s(%u): Error in number format", Filename, Line); + Error ("%s:%u: Error in number format", Filename, Line); } continue; } @@ -213,7 +213,7 @@ void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown) /* Check for a comment character or end of line */ if (*L != CommentStart && *L != '\0') { if (!IgnoreUnknown) { - Error ("%s(%u): Trailing garbage", Filename, Line); + Error ("%s:%u: Trailing garbage", Filename, Line); } continue; } diff --git a/src/da65/scanner.c b/src/da65/scanner.c index 85853d6c4..33fb3a826 100644 --- a/src/da65/scanner.c +++ b/src/da65/scanner.c @@ -94,7 +94,7 @@ void InfoWarning (const char* Format, ...) xvsprintf (Buf, sizeof (Buf), Format, ap); va_end (ap); - fprintf (stderr, "%s(%u): Warning: %s\n", + fprintf (stderr, "%s:%u: Warning: %s\n", InputSrcName, InfoErrorLine, Buf); } @@ -110,7 +110,7 @@ void InfoError (const char* Format, ...) xvsprintf (Buf, sizeof (Buf), Format, ap); va_end (ap); - fprintf (stderr, "%s(%u): Error: %s\n", + fprintf (stderr, "%s:%u: Error: %s\n", InputSrcName, InfoErrorLine, Buf); exit (EXIT_FAILURE); } diff --git a/src/ld65/asserts.c b/src/ld65/asserts.c index 626ed94a6..e9bae83e5 100644 --- a/src/ld65/asserts.c +++ b/src/ld65/asserts.c @@ -140,12 +140,12 @@ void CheckAssertions (void) case ASSERT_ACT_WARN: case ASSERT_ACT_LDWARN: - Warning ("%s(%u): %s", Module, Line, Message); + Warning ("%s:%u: %s", Module, Line, Message); break; case ASSERT_ACT_ERROR: case ASSERT_ACT_LDERROR: - Error ("%s(%u): %s", Module, Line, Message); + Error ("%s:%u: %s", Module, Line, Message); break; default: diff --git a/src/ld65/exports.c b/src/ld65/exports.c index 5df7a37c9..872db5143 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -774,17 +774,19 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data) if (E->Expr == 0 && E->ImpCount > 0 && F (E->Name, Data) == 0) { /* Unresolved external */ Import* Imp = E->ImpList; + const char * name = GetString (E->Name); fprintf (stderr, "Unresolved external '%s' referenced in:\n", - GetString (E->Name)); + name); while (Imp) { unsigned J; for (J = 0; J < CollCount (&Imp->RefLines); ++J) { const LineInfo* LI = CollConstAt (&Imp->RefLines, J); fprintf (stderr, - " %s(%u)\n", + " %s:%u: Error: Unresolved external '%s'\n", GetSourceName (LI), - GetSourceLine (LI)); + GetSourceLine (LI), + name); } Imp = Imp->Next; } diff --git a/src/ld65/scanner.c b/src/ld65/scanner.c index d6278abbd..256d47f07 100644 --- a/src/ld65/scanner.c +++ b/src/ld65/scanner.c @@ -92,7 +92,7 @@ void CfgWarning (const FilePos* Pos, const char* Format, ...) SB_VPrintf (&Buf, Format, ap); va_end (ap); - Warning ("%s(%u): %s", + Warning ("%s:%u: %s", GetString (Pos->Name), Pos->Line, SB_GetConstBuf (&Buf)); SB_Done (&Buf); } @@ -109,7 +109,7 @@ void CfgError (const FilePos* Pos, const char* Format, ...) SB_VPrintf (&Buf, Format, ap); va_end (ap); - Error ("%s(%u): %s", + Error ("%s:%u: %s", GetString (Pos->Name), Pos->Line, SB_GetConstBuf (&Buf)); SB_Done (&Buf); } From 467844963a7207afd8857d93caf7c6daa74901ce Mon Sep 17 00:00:00 2001 From: Andrea Odetti <mariofutire@gmail.com> Date: Mon, 10 May 2021 10:35:17 +0100 Subject: [PATCH 2030/2161] Update failing test due to error format changes. --- test/misc/goto.ref | 300 ++++++++++++++++++++++----------------------- 1 file changed, 150 insertions(+), 150 deletions(-) diff --git a/test/misc/goto.ref b/test/misc/goto.ref index d0a978436..2e0819887 100644 --- a/test/misc/goto.ref +++ b/test/misc/goto.ref @@ -1,150 +1,150 @@ -goto.c(8): Warning: Goto at line 8 to label start jumps into a block with initialization of an object that has automatic storage duration -goto.c(97): Warning: Variable 'a' is defined but never used -goto.c(117): Warning: Variable 'a' is defined but never used -goto.c(137): Warning: Variable 'a' is defined but never used -goto.c(159): Warning: Goto at line 23 to label l8 jumps into a block with initialization of an object that has automatic storage duration -goto.c(159): Warning: Goto at line 44 to label l8 jumps into a block with initialization of an object that has automatic storage duration -goto.c(159): Warning: Goto at line 65 to label l8 jumps into a block with initialization of an object that has automatic storage duration -goto.c(159): Warning: Goto at line 86 to label l8 jumps into a block with initialization of an object that has automatic storage duration -goto.c(159): Warning: Goto at line 106 to label l8 jumps into a block with initialization of an object that has automatic storage duration -goto.c(159): Warning: Goto at line 126 to label l8 jumps into a block with initialization of an object that has automatic storage duration -goto.c(159): Warning: Goto at line 146 to label l8 jumps into a block with initialization of an object that has automatic storage duration -goto.c(180): Warning: Goto at line 24 to label l9 jumps into a block with initialization of an object that has automatic storage duration -goto.c(180): Warning: Goto at line 45 to label l9 jumps into a block with initialization of an object that has automatic storage duration -goto.c(180): Warning: Goto at line 66 to label l9 jumps into a block with initialization of an object that has automatic storage duration -goto.c(180): Warning: Goto at line 87 to label l9 jumps into a block with initialization of an object that has automatic storage duration -goto.c(180): Warning: Goto at line 107 to label l9 jumps into a block with initialization of an object that has automatic storage duration -goto.c(180): Warning: Goto at line 127 to label l9 jumps into a block with initialization of an object that has automatic storage duration -goto.c(180): Warning: Goto at line 147 to label l9 jumps into a block with initialization of an object that has automatic storage duration -goto.c(180): Warning: Goto at line 168 to label l9 jumps into a block with initialization of an object that has automatic storage duration -goto.c(201): Warning: Goto at line 25 to label la jumps into a block with initialization of an object that has automatic storage duration -goto.c(201): Warning: Goto at line 46 to label la jumps into a block with initialization of an object that has automatic storage duration -goto.c(201): Warning: Goto at line 67 to label la jumps into a block with initialization of an object that has automatic storage duration -goto.c(201): Warning: Goto at line 88 to label la jumps into a block with initialization of an object that has automatic storage duration -goto.c(201): Warning: Goto at line 108 to label la jumps into a block with initialization of an object that has automatic storage duration -goto.c(201): Warning: Goto at line 128 to label la jumps into a block with initialization of an object that has automatic storage duration -goto.c(201): Warning: Goto at line 148 to label la jumps into a block with initialization of an object that has automatic storage duration -goto.c(201): Warning: Goto at line 169 to label la jumps into a block with initialization of an object that has automatic storage duration -goto.c(201): Warning: Goto at line 190 to label la jumps into a block with initialization of an object that has automatic storage duration -goto.c(221): Warning: Goto at line 26 to label lb jumps into a block with initialization of an object that has automatic storage duration -goto.c(221): Warning: Goto at line 47 to label lb jumps into a block with initialization of an object that has automatic storage duration -goto.c(221): Warning: Goto at line 68 to label lb jumps into a block with initialization of an object that has automatic storage duration -goto.c(221): Warning: Goto at line 89 to label lb jumps into a block with initialization of an object that has automatic storage duration -goto.c(221): Warning: Goto at line 109 to label lb jumps into a block with initialization of an object that has automatic storage duration -goto.c(221): Warning: Goto at line 129 to label lb jumps into a block with initialization of an object that has automatic storage duration -goto.c(221): Warning: Goto at line 149 to label lb jumps into a block with initialization of an object that has automatic storage duration -goto.c(221): Warning: Goto at line 170 to label lb jumps into a block with initialization of an object that has automatic storage duration -goto.c(231): Warning: Goto at line 231 to label la jumps into a block with initialization of an object that has automatic storage duration -goto.c(241): Warning: Goto at line 27 to label lc jumps into a block with initialization of an object that has automatic storage duration -goto.c(241): Warning: Goto at line 48 to label lc jumps into a block with initialization of an object that has automatic storage duration -goto.c(241): Warning: Goto at line 69 to label lc jumps into a block with initialization of an object that has automatic storage duration -goto.c(241): Warning: Goto at line 90 to label lc jumps into a block with initialization of an object that has automatic storage duration -goto.c(241): Warning: Goto at line 110 to label lc jumps into a block with initialization of an object that has automatic storage duration -goto.c(241): Warning: Goto at line 130 to label lc jumps into a block with initialization of an object that has automatic storage duration -goto.c(241): Warning: Goto at line 150 to label lc jumps into a block with initialization of an object that has automatic storage duration -goto.c(250): Warning: Goto at line 250 to label l9 jumps into a block with initialization of an object that has automatic storage duration -goto.c(251): Warning: Goto at line 251 to label la jumps into a block with initialization of an object that has automatic storage duration -goto.c(252): Warning: Goto at line 252 to label lb jumps into a block with initialization of an object that has automatic storage duration -goto.c(263): Warning: Goto at line 28 to label ld jumps into a block with initialization of an object that has automatic storage duration -goto.c(263): Warning: Goto at line 49 to label ld jumps into a block with initialization of an object that has automatic storage duration -goto.c(263): Warning: Goto at line 70 to label ld jumps into a block with initialization of an object that has automatic storage duration -goto.c(263): Warning: Goto at line 91 to label ld jumps into a block with initialization of an object that has automatic storage duration -goto.c(263): Warning: Goto at line 111 to label ld jumps into a block with initialization of an object that has automatic storage duration -goto.c(263): Warning: Goto at line 131 to label ld jumps into a block with initialization of an object that has automatic storage duration -goto.c(263): Warning: Goto at line 151 to label ld jumps into a block with initialization of an object that has automatic storage duration -goto.c(263): Warning: Goto at line 172 to label ld jumps into a block with initialization of an object that has automatic storage duration -goto.c(263): Warning: Goto at line 193 to label ld jumps into a block with initialization of an object that has automatic storage duration -goto.c(263): Warning: Goto at line 214 to label ld jumps into a block with initialization of an object that has automatic storage duration -goto.c(263): Warning: Goto at line 234 to label ld jumps into a block with initialization of an object that has automatic storage duration -goto.c(263): Warning: Goto at line 254 to label ld jumps into a block with initialization of an object that has automatic storage duration -goto.c(271): Warning: Goto at line 271 to label l8 jumps into a block with initialization of an object that has automatic storage duration -goto.c(272): Warning: Goto at line 272 to label l9 jumps into a block with initialization of an object that has automatic storage duration -goto.c(273): Warning: Goto at line 273 to label la jumps into a block with initialization of an object that has automatic storage duration -goto.c(274): Warning: Goto at line 274 to label lb jumps into a block with initialization of an object that has automatic storage duration -goto.c(275): Warning: Goto at line 275 to label lc jumps into a block with initialization of an object that has automatic storage duration -goto.c(284): Warning: Goto at line 29 to label le jumps into a block with initialization of an object that has automatic storage duration -goto.c(284): Warning: Goto at line 50 to label le jumps into a block with initialization of an object that has automatic storage duration -goto.c(284): Warning: Goto at line 71 to label le jumps into a block with initialization of an object that has automatic storage duration -goto.c(284): Warning: Goto at line 92 to label le jumps into a block with initialization of an object that has automatic storage duration -goto.c(284): Warning: Goto at line 112 to label le jumps into a block with initialization of an object that has automatic storage duration -goto.c(284): Warning: Goto at line 132 to label le jumps into a block with initialization of an object that has automatic storage duration -goto.c(284): Warning: Goto at line 152 to label le jumps into a block with initialization of an object that has automatic storage duration -goto.c(284): Warning: Goto at line 173 to label le jumps into a block with initialization of an object that has automatic storage duration -goto.c(284): Warning: Goto at line 194 to label le jumps into a block with initialization of an object that has automatic storage duration -goto.c(284): Warning: Goto at line 215 to label le jumps into a block with initialization of an object that has automatic storage duration -goto.c(284): Warning: Goto at line 235 to label le jumps into a block with initialization of an object that has automatic storage duration -goto.c(284): Warning: Goto at line 255 to label le jumps into a block with initialization of an object that has automatic storage duration -goto.c(284): Warning: Goto at line 277 to label le jumps into a block with initialization of an object that has automatic storage duration -goto.c(292): Warning: Goto at line 292 to label l8 jumps into a block with initialization of an object that has automatic storage duration -goto.c(293): Warning: Goto at line 293 to label l9 jumps into a block with initialization of an object that has automatic storage duration -goto.c(294): Warning: Goto at line 294 to label la jumps into a block with initialization of an object that has automatic storage duration -goto.c(295): Warning: Goto at line 295 to label lb jumps into a block with initialization of an object that has automatic storage duration -goto.c(296): Warning: Goto at line 296 to label lc jumps into a block with initialization of an object that has automatic storage duration -goto.c(305): Warning: Goto at line 30 to label lf jumps into a block with initialization of an object that has automatic storage duration -goto.c(305): Warning: Goto at line 51 to label lf jumps into a block with initialization of an object that has automatic storage duration -goto.c(305): Warning: Goto at line 72 to label lf jumps into a block with initialization of an object that has automatic storage duration -goto.c(305): Warning: Goto at line 93 to label lf jumps into a block with initialization of an object that has automatic storage duration -goto.c(305): Warning: Goto at line 113 to label lf jumps into a block with initialization of an object that has automatic storage duration -goto.c(305): Warning: Goto at line 133 to label lf jumps into a block with initialization of an object that has automatic storage duration -goto.c(305): Warning: Goto at line 153 to label lf jumps into a block with initialization of an object that has automatic storage duration -goto.c(305): Warning: Goto at line 174 to label lf jumps into a block with initialization of an object that has automatic storage duration -goto.c(305): Warning: Goto at line 195 to label lf jumps into a block with initialization of an object that has automatic storage duration -goto.c(305): Warning: Goto at line 216 to label lf jumps into a block with initialization of an object that has automatic storage duration -goto.c(305): Warning: Goto at line 236 to label lf jumps into a block with initialization of an object that has automatic storage duration -goto.c(305): Warning: Goto at line 256 to label lf jumps into a block with initialization of an object that has automatic storage duration -goto.c(305): Warning: Goto at line 278 to label lf jumps into a block with initialization of an object that has automatic storage duration -goto.c(305): Warning: Goto at line 299 to label lf jumps into a block with initialization of an object that has automatic storage duration -goto.c(313): Warning: Goto at line 313 to label l8 jumps into a block with initialization of an object that has automatic storage duration -goto.c(314): Warning: Goto at line 314 to label l9 jumps into a block with initialization of an object that has automatic storage duration -goto.c(315): Warning: Goto at line 315 to label la jumps into a block with initialization of an object that has automatic storage duration -goto.c(316): Warning: Goto at line 316 to label lb jumps into a block with initialization of an object that has automatic storage duration -goto.c(317): Warning: Goto at line 317 to label lc jumps into a block with initialization of an object that has automatic storage duration -goto.c(325): Warning: Goto at line 31 to label lg jumps into a block with initialization of an object that has automatic storage duration -goto.c(325): Warning: Goto at line 52 to label lg jumps into a block with initialization of an object that has automatic storage duration -goto.c(325): Warning: Goto at line 73 to label lg jumps into a block with initialization of an object that has automatic storage duration -goto.c(325): Warning: Goto at line 94 to label lg jumps into a block with initialization of an object that has automatic storage duration -goto.c(325): Warning: Goto at line 114 to label lg jumps into a block with initialization of an object that has automatic storage duration -goto.c(325): Warning: Goto at line 134 to label lg jumps into a block with initialization of an object that has automatic storage duration -goto.c(325): Warning: Goto at line 154 to label lg jumps into a block with initialization of an object that has automatic storage duration -goto.c(325): Warning: Goto at line 175 to label lg jumps into a block with initialization of an object that has automatic storage duration -goto.c(325): Warning: Goto at line 196 to label lg jumps into a block with initialization of an object that has automatic storage duration -goto.c(325): Warning: Goto at line 217 to label lg jumps into a block with initialization of an object that has automatic storage duration -goto.c(325): Warning: Goto at line 237 to label lg jumps into a block with initialization of an object that has automatic storage duration -goto.c(325): Warning: Goto at line 257 to label lg jumps into a block with initialization of an object that has automatic storage duration -goto.c(325): Warning: Goto at line 279 to label lg jumps into a block with initialization of an object that has automatic storage duration -goto.c(333): Warning: Goto at line 333 to label l8 jumps into a block with initialization of an object that has automatic storage duration -goto.c(334): Warning: Goto at line 334 to label l9 jumps into a block with initialization of an object that has automatic storage duration -goto.c(335): Warning: Goto at line 335 to label la jumps into a block with initialization of an object that has automatic storage duration -goto.c(336): Warning: Goto at line 336 to label lb jumps into a block with initialization of an object that has automatic storage duration -goto.c(337): Warning: Goto at line 337 to label lc jumps into a block with initialization of an object that has automatic storage duration -goto.c(340): Warning: Goto at line 340 to label lf jumps into a block with initialization of an object that has automatic storage duration -goto.c(345): Warning: Goto at line 32 to label lh jumps into a block with initialization of an object that has automatic storage duration -goto.c(345): Warning: Goto at line 53 to label lh jumps into a block with initialization of an object that has automatic storage duration -goto.c(345): Warning: Goto at line 74 to label lh jumps into a block with initialization of an object that has automatic storage duration -goto.c(345): Warning: Goto at line 95 to label lh jumps into a block with initialization of an object that has automatic storage duration -goto.c(345): Warning: Goto at line 115 to label lh jumps into a block with initialization of an object that has automatic storage duration -goto.c(345): Warning: Goto at line 135 to label lh jumps into a block with initialization of an object that has automatic storage duration -goto.c(345): Warning: Goto at line 155 to label lh jumps into a block with initialization of an object that has automatic storage duration -goto.c(345): Warning: Goto at line 176 to label lh jumps into a block with initialization of an object that has automatic storage duration -goto.c(345): Warning: Goto at line 197 to label lh jumps into a block with initialization of an object that has automatic storage duration -goto.c(345): Warning: Goto at line 218 to label lh jumps into a block with initialization of an object that has automatic storage duration -goto.c(345): Warning: Goto at line 238 to label lh jumps into a block with initialization of an object that has automatic storage duration -goto.c(345): Warning: Goto at line 258 to label lh jumps into a block with initialization of an object that has automatic storage duration -goto.c(353): Warning: Goto at line 353 to label l8 jumps into a block with initialization of an object that has automatic storage duration -goto.c(354): Warning: Goto at line 354 to label l9 jumps into a block with initialization of an object that has automatic storage duration -goto.c(355): Warning: Goto at line 355 to label la jumps into a block with initialization of an object that has automatic storage duration -goto.c(356): Warning: Goto at line 356 to label lb jumps into a block with initialization of an object that has automatic storage duration -goto.c(357): Warning: Goto at line 357 to label lc jumps into a block with initialization of an object that has automatic storage duration -goto.c(359): Warning: Goto at line 359 to label le jumps into a block with initialization of an object that has automatic storage duration -goto.c(360): Warning: Goto at line 360 to label lf jumps into a block with initialization of an object that has automatic storage duration -goto.c(361): Warning: Goto at line 361 to label lg jumps into a block with initialization of an object that has automatic storage duration -goto.c(373): Warning: Goto at line 373 to label l8 jumps into a block with initialization of an object that has automatic storage duration -goto.c(374): Warning: Goto at line 374 to label l9 jumps into a block with initialization of an object that has automatic storage duration -goto.c(375): Warning: Goto at line 375 to label la jumps into a block with initialization of an object that has automatic storage duration -goto.c(376): Warning: Goto at line 376 to label lb jumps into a block with initialization of an object that has automatic storage duration -goto.c(377): Warning: Goto at line 377 to label lc jumps into a block with initialization of an object that has automatic storage duration -goto.c(378): Warning: Goto at line 378 to label ld jumps into a block with initialization of an object that has automatic storage duration -goto.c(379): Warning: Goto at line 379 to label le jumps into a block with initialization of an object that has automatic storage duration -goto.c(380): Warning: Goto at line 380 to label lf jumps into a block with initialization of an object that has automatic storage duration -goto.c(381): Warning: Goto at line 381 to label lg jumps into a block with initialization of an object that has automatic storage duration -goto.c(382): Warning: Goto at line 382 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c:8: Warning: Goto at line 8 to label start jumps into a block with initialization of an object that has automatic storage duration +goto.c:97: Warning: Variable 'a' is defined but never used +goto.c:117: Warning: Variable 'a' is defined but never used +goto.c:137: Warning: Variable 'a' is defined but never used +goto.c:159: Warning: Goto at line 23 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c:159: Warning: Goto at line 44 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c:159: Warning: Goto at line 65 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c:159: Warning: Goto at line 86 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c:159: Warning: Goto at line 106 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c:159: Warning: Goto at line 126 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c:159: Warning: Goto at line 146 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c:180: Warning: Goto at line 24 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c:180: Warning: Goto at line 45 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c:180: Warning: Goto at line 66 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c:180: Warning: Goto at line 87 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c:180: Warning: Goto at line 107 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c:180: Warning: Goto at line 127 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c:180: Warning: Goto at line 147 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c:180: Warning: Goto at line 168 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c:201: Warning: Goto at line 25 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c:201: Warning: Goto at line 46 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c:201: Warning: Goto at line 67 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c:201: Warning: Goto at line 88 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c:201: Warning: Goto at line 108 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c:201: Warning: Goto at line 128 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c:201: Warning: Goto at line 148 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c:201: Warning: Goto at line 169 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c:201: Warning: Goto at line 190 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c:221: Warning: Goto at line 26 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c:221: Warning: Goto at line 47 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c:221: Warning: Goto at line 68 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c:221: Warning: Goto at line 89 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c:221: Warning: Goto at line 109 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c:221: Warning: Goto at line 129 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c:221: Warning: Goto at line 149 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c:221: Warning: Goto at line 170 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c:231: Warning: Goto at line 231 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c:241: Warning: Goto at line 27 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c:241: Warning: Goto at line 48 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c:241: Warning: Goto at line 69 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c:241: Warning: Goto at line 90 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c:241: Warning: Goto at line 110 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c:241: Warning: Goto at line 130 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c:241: Warning: Goto at line 150 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c:250: Warning: Goto at line 250 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c:251: Warning: Goto at line 251 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c:252: Warning: Goto at line 252 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c:263: Warning: Goto at line 28 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c:263: Warning: Goto at line 49 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c:263: Warning: Goto at line 70 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c:263: Warning: Goto at line 91 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c:263: Warning: Goto at line 111 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c:263: Warning: Goto at line 131 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c:263: Warning: Goto at line 151 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c:263: Warning: Goto at line 172 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c:263: Warning: Goto at line 193 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c:263: Warning: Goto at line 214 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c:263: Warning: Goto at line 234 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c:263: Warning: Goto at line 254 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c:271: Warning: Goto at line 271 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c:272: Warning: Goto at line 272 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c:273: Warning: Goto at line 273 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c:274: Warning: Goto at line 274 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c:275: Warning: Goto at line 275 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c:284: Warning: Goto at line 29 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c:284: Warning: Goto at line 50 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c:284: Warning: Goto at line 71 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c:284: Warning: Goto at line 92 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c:284: Warning: Goto at line 112 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c:284: Warning: Goto at line 132 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c:284: Warning: Goto at line 152 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c:284: Warning: Goto at line 173 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c:284: Warning: Goto at line 194 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c:284: Warning: Goto at line 215 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c:284: Warning: Goto at line 235 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c:284: Warning: Goto at line 255 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c:284: Warning: Goto at line 277 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c:292: Warning: Goto at line 292 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c:293: Warning: Goto at line 293 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c:294: Warning: Goto at line 294 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c:295: Warning: Goto at line 295 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c:296: Warning: Goto at line 296 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c:305: Warning: Goto at line 30 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c:305: Warning: Goto at line 51 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c:305: Warning: Goto at line 72 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c:305: Warning: Goto at line 93 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c:305: Warning: Goto at line 113 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c:305: Warning: Goto at line 133 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c:305: Warning: Goto at line 153 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c:305: Warning: Goto at line 174 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c:305: Warning: Goto at line 195 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c:305: Warning: Goto at line 216 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c:305: Warning: Goto at line 236 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c:305: Warning: Goto at line 256 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c:305: Warning: Goto at line 278 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c:305: Warning: Goto at line 299 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c:313: Warning: Goto at line 313 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c:314: Warning: Goto at line 314 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c:315: Warning: Goto at line 315 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c:316: Warning: Goto at line 316 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c:317: Warning: Goto at line 317 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c:325: Warning: Goto at line 31 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c:325: Warning: Goto at line 52 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c:325: Warning: Goto at line 73 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c:325: Warning: Goto at line 94 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c:325: Warning: Goto at line 114 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c:325: Warning: Goto at line 134 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c:325: Warning: Goto at line 154 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c:325: Warning: Goto at line 175 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c:325: Warning: Goto at line 196 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c:325: Warning: Goto at line 217 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c:325: Warning: Goto at line 237 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c:325: Warning: Goto at line 257 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c:325: Warning: Goto at line 279 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c:333: Warning: Goto at line 333 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c:334: Warning: Goto at line 334 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c:335: Warning: Goto at line 335 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c:336: Warning: Goto at line 336 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c:337: Warning: Goto at line 337 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c:340: Warning: Goto at line 340 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c:345: Warning: Goto at line 32 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c:345: Warning: Goto at line 53 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c:345: Warning: Goto at line 74 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c:345: Warning: Goto at line 95 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c:345: Warning: Goto at line 115 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c:345: Warning: Goto at line 135 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c:345: Warning: Goto at line 155 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c:345: Warning: Goto at line 176 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c:345: Warning: Goto at line 197 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c:345: Warning: Goto at line 218 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c:345: Warning: Goto at line 238 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c:345: Warning: Goto at line 258 to label lh jumps into a block with initialization of an object that has automatic storage duration +goto.c:353: Warning: Goto at line 353 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c:354: Warning: Goto at line 354 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c:355: Warning: Goto at line 355 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c:356: Warning: Goto at line 356 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c:357: Warning: Goto at line 357 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c:359: Warning: Goto at line 359 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c:360: Warning: Goto at line 360 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c:361: Warning: Goto at line 361 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c:373: Warning: Goto at line 373 to label l8 jumps into a block with initialization of an object that has automatic storage duration +goto.c:374: Warning: Goto at line 374 to label l9 jumps into a block with initialization of an object that has automatic storage duration +goto.c:375: Warning: Goto at line 375 to label la jumps into a block with initialization of an object that has automatic storage duration +goto.c:376: Warning: Goto at line 376 to label lb jumps into a block with initialization of an object that has automatic storage duration +goto.c:377: Warning: Goto at line 377 to label lc jumps into a block with initialization of an object that has automatic storage duration +goto.c:378: Warning: Goto at line 378 to label ld jumps into a block with initialization of an object that has automatic storage duration +goto.c:379: Warning: Goto at line 379 to label le jumps into a block with initialization of an object that has automatic storage duration +goto.c:380: Warning: Goto at line 380 to label lf jumps into a block with initialization of an object that has automatic storage duration +goto.c:381: Warning: Goto at line 381 to label lg jumps into a block with initialization of an object that has automatic storage duration +goto.c:382: Warning: Goto at line 382 to label lh jumps into a block with initialization of an object that has automatic storage duration From feccc68c547c7f74d6202db179181fdf31e3f946 Mon Sep 17 00:00:00 2001 From: Andrea Odetti <mariofutire@gmail.com> Date: Tue, 11 May 2021 13:54:05 +0100 Subject: [PATCH 2031/2161] ld65: avoid redundant error message information. --- src/ld65/exports.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/ld65/exports.c b/src/ld65/exports.c index 872db5143..6580033fb 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -774,16 +774,13 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data) if (E->Expr == 0 && E->ImpCount > 0 && F (E->Name, Data) == 0) { /* Unresolved external */ Import* Imp = E->ImpList; - const char * name = GetString (E->Name); - fprintf (stderr, - "Unresolved external '%s' referenced in:\n", - name); + const char* name = GetString (E->Name); while (Imp) { unsigned J; for (J = 0; J < CollCount (&Imp->RefLines); ++J) { const LineInfo* LI = CollConstAt (&Imp->RefLines, J); fprintf (stderr, - " %s:%u: Error: Unresolved external '%s'\n", + "%s:%u: Error: Unresolved external '%s'\n", GetSourceName (LI), GetSourceLine (LI), name); From 93762a2117760b97391c26f8f926a2a69cf921e5 Mon Sep 17 00:00:00 2001 From: Andrea Odetti <mariofutire@gmail.com> Date: Tue, 11 May 2021 13:54:36 +0100 Subject: [PATCH 2032/2161] ld65: move 2 more cases to the notation file:line. --- src/ld65/exports.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ld65/exports.c b/src/ld65/exports.c index 6580033fb..bb66ab2ce 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -166,7 +166,7 @@ Import* ReadImport (FILE* F, ObjData* Obj) */ if (ObjHasFiles (I->Obj)) { const LineInfo* LI = GetImportPos (I); - Error ("Invalid import size in for '%s', imported from %s(%u): 0x%02X", + Error ("Invalid import size in for '%s', imported from %s:%u: 0x%02X", GetString (I->Name), GetSourceName (LI), GetSourceLine (LI), @@ -1057,7 +1057,7 @@ void CircularRefError (const Export* E) /* Print an error about a circular reference using to define the given export */ { const LineInfo* LI = GetExportPos (E); - Error ("Circular reference for symbol '%s', %s(%u)", + Error ("Circular reference for symbol '%s', %s:%u", GetString (E->Name), GetSourceName (LI), GetSourceLine (LI)); From 05f545e18924a5fdea21d0d25b5462013847b2bd Mon Sep 17 00:00:00 2001 From: Andrea Odetti <mariofutire@gmail.com> Date: Tue, 11 May 2021 16:32:43 +0100 Subject: [PATCH 2033/2161] More line number related changes. --- libsrc/common/_afailed.c | 2 +- src/ld65/exports.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libsrc/common/_afailed.c b/libsrc/common/_afailed.c index ad50a8750..ab8b94ca6 100644 --- a/libsrc/common/_afailed.c +++ b/libsrc/common/_afailed.c @@ -15,6 +15,6 @@ void __fastcall__ _afailed (char* file, unsigned line) { raise (SIGABRT); - fprintf (stderr, "ASSERTION FAILED IN %s(%u)\n", file, line); + fprintf (stderr, "ASSERTION FAILED IN %s:%u\n", file, line); exit (EXIT_ASSERT); } diff --git a/src/ld65/exports.c b/src/ld65/exports.c index bb66ab2ce..35de5c8f2 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -690,12 +690,12 @@ static void CheckSymType (const Export* E) */ if (E->Obj) { /* The export comes from an object file */ - SB_Printf (&ExportLoc, "%s, %s(%u)", + SB_Printf (&ExportLoc, "%s, %s:%u", GetString (E->Obj->Name), GetSourceName (ExportLI), GetSourceLine (ExportLI)); } else if (ExportLI) { - SB_Printf (&ExportLoc, "%s(%u)", + SB_Printf (&ExportLoc, "%s:%u", GetSourceName (ExportLI), GetSourceLine (ExportLI)); } else { @@ -706,7 +706,7 @@ static void CheckSymType (const Export* E) } if (I->Obj) { /* The import comes from an object file */ - SB_Printf (&ImportLoc, "%s, %s(%u)", + SB_Printf (&ImportLoc, "%s, %s:%u", GetString (I->Obj->Name), GetSourceName (ImportLI), GetSourceLine (ImportLI)); @@ -714,7 +714,7 @@ static void CheckSymType (const Export* E) /* The import is linker generated and we have line ** information */ - SB_Printf (&ImportLoc, "%s(%u)", + SB_Printf (&ImportLoc, "%s:%u", GetSourceName (ImportLI), GetSourceLine (ImportLI)); } else { @@ -995,7 +995,7 @@ void PrintImportMap (FILE* F) const LineInfo* LI = GetImportPos (Imp); if (LI) { fprintf (F, - " %-25s %s(%u)\n", + " %-25s %s:%u\n", GetObjFileName (Imp->Obj), GetSourceName (LI), GetSourceLine (LI)); From f09ffb2a45e38338348ccd44cb36a5a9de63d614 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Wed, 12 May 2021 01:08:13 +0100 Subject: [PATCH 2034/2161] symNotepad.c --- doc/sym1.sgml | 1 + samples/symNotepad.c | 198 +++++++++++++++++++++++++++++ samples/tutorial/sym1/symNotepad.c | 198 +++++++++++++++++++++++++++++ 3 files changed, 397 insertions(+) create mode 100644 samples/symNotepad.c create mode 100644 samples/tutorial/sym1/symNotepad.c diff --git a/doc/sym1.sgml b/doc/sym1.sgml index d02e3b1b1..f04f36ae1 100644 --- a/doc/sym1.sgml +++ b/doc/sym1.sgml @@ -113,6 +113,7 @@ All the samples will run on the "stock" 4k Sym-1, except for symio.c, <item>symTiny does the same as symhello, but does it with puts() rather than printf() to show the difference in compiled binary size.</item> <item>symDisplay allows entry of a message, which is then displayed by scrolling it across the front panel display.</item> <item>symIO allows access to the Sym-1 digital I/O ports.</item> +<item>symNotepad is a simple text entry/retrieval program that uses tape storage.</item> </itemize> <sect>License<p> diff --git a/samples/symNotepad.c b/samples/symNotepad.c new file mode 100644 index 000000000..e9866e526 --- /dev/null +++ b/samples/symNotepad.c @@ -0,0 +1,198 @@ +// -------------------------------------------------------------------------- +// Sym-1 Notepad +// +// Wayne Parham +// +// wayne@parhamdata.com +// -------------------------------------------------------------------------- +// +// Note: This program requires RAM memory in locations 0xE000 - 0xEFFF +// Alternatively, the tape I/O buffer location and size can be +// changed by altering the defined TAPIO values below. +// +// -------------------------------------------------------------------------- + +#include <symio.h>; +#include <stdlib.h>; +#include <string.h>; + +#define TAPIO_ADDRESS 0xE000 +#define TAPIO_MAX_SIZE 0x0FFF + +void main(void) { + char c = 0x00; + int l = 0x00; + int p = 0x00; + int error = 0x00; + int running = 0x01; + int writing = 0x01; + int instruction_needed = 0x01; + int heap_size = 0x00; + char* tapio = (char*) TAPIO_ADDRESS; + char* buffer; + + heap_size = _heapmaxavail(); + + if( heap_size > TAPIO_MAX_SIZE ) { // No need to malloc more than + heap_size = TAPIO_MAX_SIZE; // the interface allows + } + + buffer = malloc( heap_size ); + memset( buffer, 0x00, heap_size ); + + if( buffer == 0x00 ) { + puts( "Memory full." ); + running = 0; + } + + tapio[0] = 0x00; // Check tape interface memory + if( tapio[0] != 0x00 ) + error = 1; + + tapio[0] = 0xFF; + if( tapio[0] != 0xFF ) + error = 1; + + tapio[TAPIO_MAX_SIZE] = 0x00; + if( tapio[TAPIO_MAX_SIZE] != 0x00 ) + error = 1; + + tapio[TAPIO_MAX_SIZE] = 0xFF; + if( tapio[TAPIO_MAX_SIZE] != 0xFF ) + error = 1; + + if( error ) { + printf( "\nNo memory at location %p, aborting.\n", tapio ); + running = 0; + } + else { + memset( tapio, 0, TAPIO_MAX_SIZE ); + } + + + while( running ) { + + putchar( '\r' ); + for( l = 0; l < 25; l++ ) { + putchar( '\n' ); + } + + puts( "===================== Sym-1 Notepad ====================" ); + + if( instruction_needed ) { + puts( "Enter text and you can save it to tape for reloading" ); + puts( "later. There are four special 'command' characters:\n" ); + puts( " Control-S Save to tape" ); + puts( " Control-L Load from tape" ); + puts( " Control-C Clear memory" ); + puts( " Control-X Exit" ); + puts( "========================================================\n" ); + } + + while( writing ) { + + c = getchar(); + + if( c == 0x08 ) { // Backspace + if( p > 0 ) { + buffer[p] = 0x00; + p--; + } + } + else if( c == 0x13 ) { // Save + puts( "\n========================= Save =========================" ); + puts( "\nPress any key to save." ); + c = getchar(); + for( l = 0; l <= p; l++ ) { + tapio[l] = buffer[l]; + } + l++; + tapio[l] = 0x00; + puts( "Saving to tape." ); + error = dumpt( 'N', (int) tapio, (int) tapio+p ); + if( error ) { + puts( "\nTape error." ); + } + else + { + putchar( '\r' ); + for( l = 0; l < 25; l++ ) { + putchar( '\n' ); + } + } + puts( "===================== Sym-1 Notepad ====================\n" ); + for( l = 0; l <= p; l++ ) { + putchar( buffer[l] ); + if( buffer[l] == '\r' ) { + putchar( '\n' ); + } + } + } + else if( c == 0x0C ) { // Load + p = 0; + puts( "\nLoading from tape." ); + memset( buffer, 0, heap_size ); + memset( tapio, 0, TAPIO_MAX_SIZE ); + error = loadt( 'N' ); + if( error ) { + puts( "\nTape error." ); + puts( "===================== Sym-1 Notepad ====================\n" ); + } + else + { + for( l = 0; l <= heap_size; l++ ) { + buffer[l] = tapio[l]; + } + + p = strlen( buffer ); + + putchar( '\r' ); + for( l = 0; l < 25; l++ ) { + putchar( '\n' ); + } + puts( "===================== Sym-1 Notepad ====================\n" ); + + for( l = 0; l <= p; l++ ) { + putchar( buffer[l] ); + if( buffer[l] == '\r' ) { + putchar( '\n' ); + } + } + } + } + else if( c == 0x03 ) { // Clear + p = 0; + memset( buffer, 0, heap_size ); + putchar( '\r' ); + for( l = 0; l < 25; l++ ) { + putchar( '\n' ); + } + puts( "===================== Sym-1 Notepad ====================\n" ); + } + else if( c == 0x18 ) { // Exit + writing = 0; + running = 0; + } + else { + if( p >= heap_size - 1 ) { + puts( "\n========================= End =========================" ); + puts( "Buffer full." ); + } + else { + if( c == '\r' ) { + putchar( '\n' ); + } + buffer[p] = c; + putchar( c ); + } + p++; + } + } + } + + free( buffer ); + + puts( "\nEnjoy your day!\n" ); + + return; +} diff --git a/samples/tutorial/sym1/symNotepad.c b/samples/tutorial/sym1/symNotepad.c new file mode 100644 index 000000000..e9866e526 --- /dev/null +++ b/samples/tutorial/sym1/symNotepad.c @@ -0,0 +1,198 @@ +// -------------------------------------------------------------------------- +// Sym-1 Notepad +// +// Wayne Parham +// +// wayne@parhamdata.com +// -------------------------------------------------------------------------- +// +// Note: This program requires RAM memory in locations 0xE000 - 0xEFFF +// Alternatively, the tape I/O buffer location and size can be +// changed by altering the defined TAPIO values below. +// +// -------------------------------------------------------------------------- + +#include <symio.h>; +#include <stdlib.h>; +#include <string.h>; + +#define TAPIO_ADDRESS 0xE000 +#define TAPIO_MAX_SIZE 0x0FFF + +void main(void) { + char c = 0x00; + int l = 0x00; + int p = 0x00; + int error = 0x00; + int running = 0x01; + int writing = 0x01; + int instruction_needed = 0x01; + int heap_size = 0x00; + char* tapio = (char*) TAPIO_ADDRESS; + char* buffer; + + heap_size = _heapmaxavail(); + + if( heap_size > TAPIO_MAX_SIZE ) { // No need to malloc more than + heap_size = TAPIO_MAX_SIZE; // the interface allows + } + + buffer = malloc( heap_size ); + memset( buffer, 0x00, heap_size ); + + if( buffer == 0x00 ) { + puts( "Memory full." ); + running = 0; + } + + tapio[0] = 0x00; // Check tape interface memory + if( tapio[0] != 0x00 ) + error = 1; + + tapio[0] = 0xFF; + if( tapio[0] != 0xFF ) + error = 1; + + tapio[TAPIO_MAX_SIZE] = 0x00; + if( tapio[TAPIO_MAX_SIZE] != 0x00 ) + error = 1; + + tapio[TAPIO_MAX_SIZE] = 0xFF; + if( tapio[TAPIO_MAX_SIZE] != 0xFF ) + error = 1; + + if( error ) { + printf( "\nNo memory at location %p, aborting.\n", tapio ); + running = 0; + } + else { + memset( tapio, 0, TAPIO_MAX_SIZE ); + } + + + while( running ) { + + putchar( '\r' ); + for( l = 0; l < 25; l++ ) { + putchar( '\n' ); + } + + puts( "===================== Sym-1 Notepad ====================" ); + + if( instruction_needed ) { + puts( "Enter text and you can save it to tape for reloading" ); + puts( "later. There are four special 'command' characters:\n" ); + puts( " Control-S Save to tape" ); + puts( " Control-L Load from tape" ); + puts( " Control-C Clear memory" ); + puts( " Control-X Exit" ); + puts( "========================================================\n" ); + } + + while( writing ) { + + c = getchar(); + + if( c == 0x08 ) { // Backspace + if( p > 0 ) { + buffer[p] = 0x00; + p--; + } + } + else if( c == 0x13 ) { // Save + puts( "\n========================= Save =========================" ); + puts( "\nPress any key to save." ); + c = getchar(); + for( l = 0; l <= p; l++ ) { + tapio[l] = buffer[l]; + } + l++; + tapio[l] = 0x00; + puts( "Saving to tape." ); + error = dumpt( 'N', (int) tapio, (int) tapio+p ); + if( error ) { + puts( "\nTape error." ); + } + else + { + putchar( '\r' ); + for( l = 0; l < 25; l++ ) { + putchar( '\n' ); + } + } + puts( "===================== Sym-1 Notepad ====================\n" ); + for( l = 0; l <= p; l++ ) { + putchar( buffer[l] ); + if( buffer[l] == '\r' ) { + putchar( '\n' ); + } + } + } + else if( c == 0x0C ) { // Load + p = 0; + puts( "\nLoading from tape." ); + memset( buffer, 0, heap_size ); + memset( tapio, 0, TAPIO_MAX_SIZE ); + error = loadt( 'N' ); + if( error ) { + puts( "\nTape error." ); + puts( "===================== Sym-1 Notepad ====================\n" ); + } + else + { + for( l = 0; l <= heap_size; l++ ) { + buffer[l] = tapio[l]; + } + + p = strlen( buffer ); + + putchar( '\r' ); + for( l = 0; l < 25; l++ ) { + putchar( '\n' ); + } + puts( "===================== Sym-1 Notepad ====================\n" ); + + for( l = 0; l <= p; l++ ) { + putchar( buffer[l] ); + if( buffer[l] == '\r' ) { + putchar( '\n' ); + } + } + } + } + else if( c == 0x03 ) { // Clear + p = 0; + memset( buffer, 0, heap_size ); + putchar( '\r' ); + for( l = 0; l < 25; l++ ) { + putchar( '\n' ); + } + puts( "===================== Sym-1 Notepad ====================\n" ); + } + else if( c == 0x18 ) { // Exit + writing = 0; + running = 0; + } + else { + if( p >= heap_size - 1 ) { + puts( "\n========================= End =========================" ); + puts( "Buffer full." ); + } + else { + if( c == '\r' ) { + putchar( '\n' ); + } + buffer[p] = c; + putchar( c ); + } + p++; + } + } + } + + free( buffer ); + + puts( "\nEnjoy your day!\n" ); + + return; +} From 5d198d6842c5183ed03f25e517e74607b1f9b4ec Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 12 May 2021 05:05:39 -0400 Subject: [PATCH 2035/2161] Fixed some URL links in a couple of documents. --- doc/cc65.sgml | 4 ++-- doc/funcref.sgml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 56a87ae72..004061518 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1391,9 +1391,9 @@ parameter with the <tt/#pragma/. in their prototypes). The identifier is an 8-bit number that's set into <tt/tmp4/. If the identifier - is "bank", then a <tt><url url="ca65.html#.BANK" name=".bank"></tt> operator will be used + is "bank", then ca65's <tt><url url="ca65.html#.BANK" name=".bank"></tt> function will be used to determine the number from the bank attribute defined in the linker config, - see <htmlurl url="ld65.html#MEMORY" name="Other MEMORY area attributes">. Note that + see <url url="ld65.html#MEMORY" name="Other MEMORY area attributes">. Note that this currently implies that only the least significant 8 bits of the bank attribute can be used. diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 3b3db2e09..4d1a278b0 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -5186,7 +5186,7 @@ the module just loaded. Possible error codes are: <item><tt/MLOAD_ERR_MEM/ - Not enough memory </itemize> <tag/Notes/<itemize> -<item>The <htmlurl url="ld65.html" name="ld65"> linker is needed to create +<item>The <url url="ld65.html" name="ld65 linker"> is needed to create relocatable o65 modules for use with this function. <item>The function is available only as a fastcall function; so, it may be used only in the presence of a prototype. From af4c4f6aaf8e2eb93249d6fa9418cc5d62c87ad9 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Wed, 12 May 2021 19:43:32 -0400 Subject: [PATCH 2036/2161] Removed a "return" keyword from an inline function that must return (void). --- src/cc65/codeent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/codeent.h b/src/cc65/codeent.h index bd542cc4c..ee1dd0220 100644 --- a/src/cc65/codeent.h +++ b/src/cc65/codeent.h @@ -184,7 +184,7 @@ INLINE CodeLabel* CE_GetLabel (CodeEntry* E, unsigned Index) INLINE void CE_ReplaceLabel (CodeEntry* E, CodeLabel* L, unsigned Index) /* Replace the code label at the specified index with L */ { - return CollReplace (&E->Labels, L, Index); + CollReplace (&E->Labels, L, Index); } #else # define CE_ReplaceLabel(E, L, Index) CollReplace (&(E)->Labels, (L), (Index)) From e5813cfb1ab7069c063d0a1a8a9fd14e58a3a1a9 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 13 May 2021 00:24:32 -0400 Subject: [PATCH 2037/2161] Removed two duplicate TYPEDEFs from a header. The first one is replaced by an #include of the header that has its original TYPEDEF. The second one is replaced by its base type. That change allows pedantic C90-compliant compilers to accept the header. --- src/cc65/codeoptutil.c | 2 +- src/cc65/datatype.c | 4 ++-- src/cc65/datatype.h | 24 +++++++++++------------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index 23c759fd1..16c41162a 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -1447,7 +1447,7 @@ void AdjustEntryIndices (Collection* Indices, int Index, int Change) } else if (Index <= *IndexPtr) { /* Has been removed */ *IndexPtr = -1; - //CollDelete (Indices, I); + /*CollDelete (Indices, I);*/ --I; } } diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 9e52027ce..90bf892ba 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -1242,7 +1242,7 @@ const Type* GetBaseElementType (const Type* T) -SymEntry* GetESUSymEntry (const Type* T) +struct SymEntry* GetESUSymEntry (const Type* T) /* Return a SymEntry pointer from an enum/struct/union type */ { /* Only enums, structs or unions have a SymEntry attribute */ @@ -1254,7 +1254,7 @@ SymEntry* GetESUSymEntry (const Type* T) -void SetESUSymEntry (Type* T, SymEntry* S) +void SetESUSymEntry (Type* T, struct SymEntry* S) /* Set the SymEntry pointer for an enum/struct/union type */ { /* Only enums, structs or unions have a SymEntry attribute */ diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 1140ee498..af1c6b8e4 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,6 +45,9 @@ #include "inline.h" #include "mmodel.h" +/* cc65 */ +#include "funcdesc.h" + /*****************************************************************************/ @@ -53,8 +56,8 @@ -typedef struct FuncDesc FuncDesc; -typedef struct SymEntry SymEntry; +struct StrBuf; +struct SymEntry; @@ -162,12 +165,12 @@ typedef unsigned long TypeCode; /* Type entry */ typedef struct Type Type; struct Type { - TypeCode C; /* Code for this entry */ + TypeCode C; /* Code for this entry */ union { - FuncDesc* F; /* Function description pointer */ - SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ - long L; /* Numeric attribute value */ - unsigned long U; /* Dito, unsigned */ + struct FuncDesc* F; /* Function description pointer */ + struct SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ + long L; /* Numeric attribute value */ + unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ }; @@ -221,11 +224,6 @@ extern const Type type_c_char_p[]; extern const Type type_void_p[]; extern const Type type_c_void_p[]; -/* Forward for the SymEntry struct */ -struct SymEntry; - -/* Forward for the StrBuf struct */ -struct StrBuf; /*****************************************************************************/ @@ -849,7 +847,7 @@ int IsVariadicFunc (const Type* T) attribute ((const)); */ int IsFastcallFunc (const Type* T) attribute ((const)); -/* Return true if this is a function type or pointer to function type by +/* Return true if this is a function type or pointer to function type with ** __fastcall__ calling convention. ** Check fails if the type is not a function or a pointer to function. */ From 09e0e7412467419a680b98f9b8cbe95fef7adeef Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 13 May 2021 18:12:12 +0200 Subject: [PATCH 2038/2161] (again) remove TABs --- libsrc/telestrat/syschdir.s | 2 +- test/val/bug1397.c | 43 ++++++++++++++++++------------------- test/val/bug1451.c | 2 +- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/libsrc/telestrat/syschdir.s b/libsrc/telestrat/syschdir.s index 149957215..09763bdbb 100644 --- a/libsrc/telestrat/syschdir.s +++ b/libsrc/telestrat/syschdir.s @@ -21,7 +21,7 @@ __syschdir: ; Get name jsr popax - + stx tmp1 ldy tmp1 diff --git a/test/val/bug1397.c b/test/val/bug1397.c index 4f8fb8697..191093efa 100644 --- a/test/val/bug1397.c +++ b/test/val/bug1397.c @@ -7,49 +7,48 @@ unsigned char c; int *p; void f1(void) { - int i = 1; - int *pa = (int *)0xaaaa; - int *pb = (int *)0xbbbb; + int i = 1; + int *pa = (int *)0xaaaa; + int *pb = (int *)0xbbbb; - p = (i == 0) ? pa : pb; - c = 0x5a; + p = (i == 0) ? pa : pb; + c = 0x5a; } struct data_t { - unsigned char c; - int *p; + unsigned char c; + int *p; }; struct data_t data; void f2(void) { - int i = 1; - int *pa = (int *)0xcccc; - int *pb = (int *)0xdddd; - struct data_t *po = &data; - - po->p = (i == 0) ? pa : pb; - po->c = 0xa5; + int i = 1; + int *pa = (int *)0xcccc; + int *pb = (int *)0xdddd; + struct data_t *po = &data; + + po->p = (i == 0) ? pa : pb; + po->c = 0xa5; } int ret = 0; int main(void) { - f1(); + f1(); if (c != 0x5a) { ret++; } - printf("c: %hhx\n", c); - printf("p: %p\n", p); - f2(); + printf("c: %hhx\n", c); + printf("p: %p\n", p); + f2(); if (data.c != 0xa5) { ret++; } - printf("c: %hhx\n", data.c); - printf("p: %p\n", data.p); + printf("c: %hhx\n", data.c); + printf("p: %p\n", data.p); - printf("failures: %d\n", ret); + printf("failures: %d\n", ret); return ret; } - diff --git a/test/val/bug1451.c b/test/val/bug1451.c index c00f19903..f9cca2561 100644 --- a/test/val/bug1451.c +++ b/test/val/bug1451.c @@ -15,7 +15,7 @@ int main(void) S b = {1, 4}; S m[1] = {{6, 3}}; S *p = &a; - + (&a)->a += b.a; p->b += b.b; m->a += b.a; From 321bac417845f589492182af522144aa821cb94f Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Thu, 13 May 2021 14:43:16 -0500 Subject: [PATCH 2039/2161] Remove TAB characters --- cfg/sym1-32k.cfg | 8 ++++---- cfg/sym1-4k.cfg | 8 ++++---- cfg/sym1.cfg | 8 ++++---- samples/symDisplay.c | 19 ++++++++++--------- samples/symIO.c | 2 +- samples/symNotepad.c | 7 ++++--- samples/tutorial/sym1/symDisplay.c | 19 ++++++++++--------- samples/tutorial/sym1/symIO.c | 2 +- samples/tutorial/sym1/symNotepad.c | 7 ++++--- 9 files changed, 42 insertions(+), 38 deletions(-) diff --git a/cfg/sym1-32k.cfg b/cfg/sym1-32k.cfg index 14ddfb98f..0665c8cf2 100644 --- a/cfg/sym1-32k.cfg +++ b/cfg/sym1-32k.cfg @@ -22,10 +22,10 @@ SYMBOLS { } MEMORY { - ZP: start = $0000, size = $00F7, define = yes, file = %O; + ZP: start = $0000, size = $00F7, define = yes, file = %O; CPUSTACK: start = $0100, size = $0100, define = yes; RAM: start = %S, size = $8000 - %S - __STACKSIZE__, define = yes, file = %O; - MONROM: start = $8000, size = $1000, define = yes; + MONROM: start = $8000, size = $1000, define = yes; EXT: start = $9000, size = $1000, define = yes; IO: start = $A000, size = $1000, define = yes; RAE1: start = $B000, size = $1000, define = yes; @@ -35,8 +35,8 @@ MEMORY { } SEGMENTS { - ZEROPAGE: load = ZP, type = zp, define = yes; - STARTUP: load = RAM, type = ro, define = yes; + 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; diff --git a/cfg/sym1-4k.cfg b/cfg/sym1-4k.cfg index 240d7bc82..de1be0b8a 100644 --- a/cfg/sym1-4k.cfg +++ b/cfg/sym1-4k.cfg @@ -22,10 +22,10 @@ SYMBOLS { } MEMORY { - ZP: start = $0000, size = $00F7, define = yes, file = %O; + ZP: start = $0000, size = $00F7, define = yes, file = %O; CPUSTACK: start = $0100, size = $0100, define = yes; RAM: start = %S, size = $1000 - %S - __STACKSIZE__, define = yes, file = %O; - MONROM: start = $8000, size = $1000, define = yes; + MONROM: start = $8000, size = $1000, define = yes; EXT: start = $9000, size = $1000, define = yes; IO: start = $A000, size = $1000, define = yes; RAE1: start = $B000, size = $1000, define = yes; @@ -35,8 +35,8 @@ MEMORY { } SEGMENTS { - ZEROPAGE: load = ZP, type = zp, define = yes; - STARTUP: load = RAM, type = ro, define = yes; + 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; diff --git a/cfg/sym1.cfg b/cfg/sym1.cfg index 240d7bc82..de1be0b8a 100644 --- a/cfg/sym1.cfg +++ b/cfg/sym1.cfg @@ -22,10 +22,10 @@ SYMBOLS { } MEMORY { - ZP: start = $0000, size = $00F7, define = yes, file = %O; + ZP: start = $0000, size = $00F7, define = yes, file = %O; CPUSTACK: start = $0100, size = $0100, define = yes; RAM: start = %S, size = $1000 - %S - __STACKSIZE__, define = yes, file = %O; - MONROM: start = $8000, size = $1000, define = yes; + MONROM: start = $8000, size = $1000, define = yes; EXT: start = $9000, size = $1000, define = yes; IO: start = $A000, size = $1000, define = yes; RAE1: start = $B000, size = $1000, define = yes; @@ -35,8 +35,8 @@ MEMORY { } SEGMENTS { - ZEROPAGE: load = ZP, type = zp, define = yes; - STARTUP: load = RAM, type = ro, define = yes; + 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; diff --git a/samples/symDisplay.c b/samples/symDisplay.c index 41eaf8b49..8a72d5863 100644 --- a/samples/symDisplay.c +++ b/samples/symDisplay.c @@ -43,7 +43,7 @@ void main (void) { if( (c >= '0') && (c <= '9') ) { // between 1 and 9 loops allowed z = 1; // a number was pressed t = c - '0'; // convert char to int - puts( "\n\nLook at the front panel.\n" ); + puts( "\n\nLook at the front panel.\n" ); } else { puts( "\nWhat?" ); @@ -185,7 +185,7 @@ void main (void) { set_D3( get_D4() ); set_D4( get_D5() ); set_D5( get_D6() ); - set_D6( DISP_M_1 ); + set_D6( DISP_M_1 ); for( d = 0; d < flashes ; d++ ) { fdisp(); // Display } @@ -198,7 +198,7 @@ void main (void) { set_D3( get_D4() ); set_D4( get_D5() ); set_D5( get_D6() ); - set_D6( DISP_M_1 ); + set_D6( DISP_M_1 ); for( d = 0; d < flashes ; d++ ) { fdisp(); // Display } @@ -259,7 +259,7 @@ void main (void) { set_D3( get_D4() ); set_D4( get_D5() ); set_D5( get_D6() ); - set_D6( DISP_M_1 ); + set_D6( DISP_M_1 ); for( d = 0; d < flashes ; d++ ) { fdisp(); // Display } @@ -272,7 +272,7 @@ void main (void) { set_D3( get_D4() ); set_D4( get_D5() ); set_D5( get_D6() ); - set_D6( DISP_M_1 ); + set_D6( DISP_M_1 ); for( d = 0; d < flashes ; d++ ) { fdisp(); // Display } @@ -285,7 +285,7 @@ void main (void) { set_D3( get_D4() ); set_D4( get_D5() ); set_D5( get_D6() ); - set_D6( DISP_M_1 ); + set_D6( DISP_M_1 ); for( d = 0; d < flashes ; d++ ) { fdisp(); // Display } @@ -298,7 +298,7 @@ void main (void) { set_D3( get_D4() ); set_D4( get_D5() ); set_D5( get_D6() ); - set_D6( DISP_M_1 ); + set_D6( DISP_M_1 ); for( d = 0; d < flashes ; d++ ) { fdisp(); // Display } @@ -344,10 +344,10 @@ void main (void) { set_D6( DISP_BACKSLASH ); break; default: - displayable = 0; // Character not mapped + displayable = 0; // Character not mapped } - if( displayable ) { + if( displayable ) { putchar( buffer[l] ); // Send it to the console @@ -382,3 +382,4 @@ void main (void) { return; } + diff --git a/samples/symIO.c b/samples/symIO.c index c52a71b11..d887c18b9 100644 --- a/samples/symIO.c +++ b/samples/symIO.c @@ -66,7 +66,7 @@ void main(void) { puts( "instructions again and type 'stop' to end the program.\n"); puts( "Available registers: DDR1A, IOR1A, DDR1B, IOR1B, DDR2A" ); puts( "IOR2A, DDR2B, IOR2B, DDR3A, IOR3A, DDR3B and IOR3B." ); - instr = 0; + instr = 0; } printf( "\n Command: " ); diff --git a/samples/symNotepad.c b/samples/symNotepad.c index e9866e526..bc28ef4b5 100644 --- a/samples/symNotepad.c +++ b/samples/symNotepad.c @@ -99,21 +99,21 @@ void main(void) { p--; } } - else if( c == 0x13 ) { // Save + else if( c == 0x13 ) { // Save puts( "\n========================= Save =========================" ); puts( "\nPress any key to save." ); c = getchar(); for( l = 0; l <= p; l++ ) { tapio[l] = buffer[l]; } - l++; + l++; tapio[l] = 0x00; puts( "Saving to tape." ); error = dumpt( 'N', (int) tapio, (int) tapio+p ); if( error ) { puts( "\nTape error." ); } - else + else { putchar( '\r' ); for( l = 0; l < 25; l++ ) { @@ -196,3 +196,4 @@ void main(void) { return; } + diff --git a/samples/tutorial/sym1/symDisplay.c b/samples/tutorial/sym1/symDisplay.c index 41eaf8b49..8a72d5863 100644 --- a/samples/tutorial/sym1/symDisplay.c +++ b/samples/tutorial/sym1/symDisplay.c @@ -43,7 +43,7 @@ void main (void) { if( (c >= '0') && (c <= '9') ) { // between 1 and 9 loops allowed z = 1; // a number was pressed t = c - '0'; // convert char to int - puts( "\n\nLook at the front panel.\n" ); + puts( "\n\nLook at the front panel.\n" ); } else { puts( "\nWhat?" ); @@ -185,7 +185,7 @@ void main (void) { set_D3( get_D4() ); set_D4( get_D5() ); set_D5( get_D6() ); - set_D6( DISP_M_1 ); + set_D6( DISP_M_1 ); for( d = 0; d < flashes ; d++ ) { fdisp(); // Display } @@ -198,7 +198,7 @@ void main (void) { set_D3( get_D4() ); set_D4( get_D5() ); set_D5( get_D6() ); - set_D6( DISP_M_1 ); + set_D6( DISP_M_1 ); for( d = 0; d < flashes ; d++ ) { fdisp(); // Display } @@ -259,7 +259,7 @@ void main (void) { set_D3( get_D4() ); set_D4( get_D5() ); set_D5( get_D6() ); - set_D6( DISP_M_1 ); + set_D6( DISP_M_1 ); for( d = 0; d < flashes ; d++ ) { fdisp(); // Display } @@ -272,7 +272,7 @@ void main (void) { set_D3( get_D4() ); set_D4( get_D5() ); set_D5( get_D6() ); - set_D6( DISP_M_1 ); + set_D6( DISP_M_1 ); for( d = 0; d < flashes ; d++ ) { fdisp(); // Display } @@ -285,7 +285,7 @@ void main (void) { set_D3( get_D4() ); set_D4( get_D5() ); set_D5( get_D6() ); - set_D6( DISP_M_1 ); + set_D6( DISP_M_1 ); for( d = 0; d < flashes ; d++ ) { fdisp(); // Display } @@ -298,7 +298,7 @@ void main (void) { set_D3( get_D4() ); set_D4( get_D5() ); set_D5( get_D6() ); - set_D6( DISP_M_1 ); + set_D6( DISP_M_1 ); for( d = 0; d < flashes ; d++ ) { fdisp(); // Display } @@ -344,10 +344,10 @@ void main (void) { set_D6( DISP_BACKSLASH ); break; default: - displayable = 0; // Character not mapped + displayable = 0; // Character not mapped } - if( displayable ) { + if( displayable ) { putchar( buffer[l] ); // Send it to the console @@ -382,3 +382,4 @@ void main (void) { return; } + diff --git a/samples/tutorial/sym1/symIO.c b/samples/tutorial/sym1/symIO.c index c52a71b11..d887c18b9 100644 --- a/samples/tutorial/sym1/symIO.c +++ b/samples/tutorial/sym1/symIO.c @@ -66,7 +66,7 @@ void main(void) { puts( "instructions again and type 'stop' to end the program.\n"); puts( "Available registers: DDR1A, IOR1A, DDR1B, IOR1B, DDR2A" ); puts( "IOR2A, DDR2B, IOR2B, DDR3A, IOR3A, DDR3B and IOR3B." ); - instr = 0; + instr = 0; } printf( "\n Command: " ); diff --git a/samples/tutorial/sym1/symNotepad.c b/samples/tutorial/sym1/symNotepad.c index e9866e526..bc28ef4b5 100644 --- a/samples/tutorial/sym1/symNotepad.c +++ b/samples/tutorial/sym1/symNotepad.c @@ -99,21 +99,21 @@ void main(void) { p--; } } - else if( c == 0x13 ) { // Save + else if( c == 0x13 ) { // Save puts( "\n========================= Save =========================" ); puts( "\nPress any key to save." ); c = getchar(); for( l = 0; l <= p; l++ ) { tapio[l] = buffer[l]; } - l++; + l++; tapio[l] = 0x00; puts( "Saving to tape." ); error = dumpt( 'N', (int) tapio, (int) tapio+p ); if( error ) { puts( "\nTape error." ); } - else + else { putchar( '\r' ); for( l = 0; l < 25; l++ ) { @@ -196,3 +196,4 @@ void main(void) { return; } + From dfba8d77ca84bb651276aa01f58ca63f61c00f7a Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 30 Aug 2020 01:31:23 +0800 Subject: [PATCH 2040/2161] Error messages shouldn't raise warnings about unused expressions by themselves. --- src/cc65/expr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 01bebf18e..a63214f49 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1301,6 +1301,7 @@ static void Primary (ExprDesc* E) /* Statement block */ NextToken (); Error ("Expression expected"); + E->Flags |= E_EVAL_MAYBE_UNUSED; hie0 (E); if (CurTok.Tok == TOK_RCURLY) { NextToken (); @@ -1332,6 +1333,7 @@ static void Primary (ExprDesc* E) } } else { Error ("Expression expected"); + E->Flags |= E_EVAL_MAYBE_UNUSED; NextToken (); } } From 18ae09f6821b3ed15121220100023b70ae393e30 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 14 Mar 2021 03:39:05 +0800 Subject: [PATCH 2041/2161] Less excessive errors with failed array declarations. --- src/cc65/compile.c | 5 ++--- src/cc65/declare.c | 2 +- src/cc65/locals.c | 3 +-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index f970edef7..94dfc3ffb 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -156,9 +156,8 @@ static void Parse (void) ** ** This means that "extern int i;" will not get storage allocated. */ - if ((Decl.StorageClass & SC_FUNC) != SC_FUNC && - (Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF && - (Decl.StorageClass & SC_FICTITIOUS) != SC_FICTITIOUS) { + if ((Decl.StorageClass & SC_FUNC) != 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 && diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 8879c46d8..a18c837b9 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2080,7 +2080,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (PrevErrorCount != ErrorCount) { /* Make the declaration fictitious if is is not parsed correctly */ - D->StorageClass |= SC_DECL | SC_FICTITIOUS; + D->StorageClass |= SC_FICTITIOUS; if (Mode == DM_NEED_IDENT && D->Ident[0] == '\0') { /* Use a fictitious name for the identifier if it is missing */ diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 7812acebd..c2e314485 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -476,8 +476,7 @@ static void ParseOneDecl (const DeclSpec* Spec) } /* If the symbol is not marked as external, it will be defined now */ - if ((Decl.StorageClass & SC_FICTITIOUS) == 0 && - (Decl.StorageClass & SC_DECL) == 0 && + if ((Decl.StorageClass & SC_DECL) == 0 && (Decl.StorageClass & SC_EXTERN) == 0) { Decl.StorageClass |= SC_DEF; } From 86bd6b9addc7650560826e3c21c7b393567d3cc0 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 15 May 2021 19:48:19 +0200 Subject: [PATCH 2042/2161] Added executable list for all targets and print a message when certain samples are not available for a target (instead of failing). This makes "make SYS=<target>" in samples recursively work for all supported targets. --- samples/Makefile | 152 ++++++++++++++++++++++++++++++++++---- samples/geos/Makefile | 35 +++++++-- samples/geos/grc/Makefile | 29 ++++++-- samples/tutorial/Makefile | 48 +++++++++++- 4 files changed, 234 insertions(+), 30 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index 6e89cb802..e8b9824d8 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -159,21 +159,6 @@ DIRLIST = tutorial geos # -------------------------------------------------------------------------- # Lists of executables -EXELIST_c64 = \ - ascii \ - enumdevdir \ - fire \ - gunzip65 \ - hello \ - mandelbrot \ - mousedemo \ - multdemo \ - nachtm \ - ovrldemo \ - plasma \ - sieve \ - tgidemo - EXELIST_apple2 = \ ascii \ diodemo \ @@ -204,10 +189,141 @@ EXELIST_atarixl = $(EXELIST_atari) EXELIST_atari2600 = \ atari2600hello - + +EXELIST_atmos = \ + ascii \ + hello \ + mandelbrot \ + sieve + +EXELIST_bbc = \ + notavailable + +EXELIST_c64 = \ + ascii \ + enumdevdir \ + fire \ + gunzip65 \ + hello \ + mandelbrot \ + mousedemo \ + multdemo \ + nachtm \ + ovrldemo \ + plasma \ + sieve \ + tgidemo + +EXELIST_c128 = \ + ascii \ + enumdevdir \ + fire \ + gunzip65 \ + hello \ + mandelbrot \ + mousedemo \ + nachtm \ + plasma \ + sieve \ + tgidemo + +EXELIST_c16 = \ + ascii \ + enumdevdir \ + hello + +EXELIST_cbm510 = \ + ascii \ + fire \ + gunzip65 \ + hello \ + mousedemo \ + nachtm \ + plasma \ + sieve + +EXELIST_cbm610 = \ + ascii \ + gunzip65 \ + hello \ + nachtm \ + sieve + +EXELIST_creativision = \ + ascii \ + hello + +EXELIST_cx16 = \ + ascii \ + enumdevdir \ + gunzip65 \ + hello \ + mandelbrot \ + mousedemo \ + sieve \ + tgidemo + +EXELIST_gamate = \ + hello + +EXELIST_geos-cbm = \ + ascii \ + diodemo + +EXELIST_geos-apple = \ + ascii \ + diodemo + +EXELIST_lunix = \ + notavailable + +EXELIST_lynx = \ + notavailable + +EXELIST_nes = \ + hello + +EXELIST_osic1p = \ + notavailable + +EXELIST_pce = \ + hello + +EXELIST_pet = \ + ascii \ + enumdevdir \ + hello \ + sieve + +EXELIST_plus4 = \ + ascii \ + enumdevdir \ + gunzip65 \ + hello \ + plasma \ + sieve + +EXELIST_sim6502 = \ + gunzip65 + +EXELIST_sim65c02 = $(EXELIST_sim6502) + EXELIST_supervision = \ supervisionhello +EXELIST_telestrat = \ + ascii \ + gunzip65 \ + hello + +EXELIST_vic20 = \ + ascii \ + enumdevdir \ + hello \ + mandelbrot \ + sieve \ + tgidemo + # Unlisted targets will try to build everything. # That lets us learn what they cannot build, and what settings # we need to use for programs that can be built and run. @@ -227,6 +343,10 @@ endef # SUBDIR_recipe samples: $(EXELIST_$(SYS)) $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) +# empty target used to skip systems that will not work with any program in this dir +notavailable: + @echo "warning: generic samples not available for" $(SYS) + disk: $(DISK_$(SYS)) all: diff --git a/samples/geos/Makefile b/samples/geos/Makefile index 00841ee8f..9ad555565 100644 --- a/samples/geos/Makefile +++ b/samples/geos/Makefile @@ -37,17 +37,42 @@ DIRLIST = grc define SUBDIR_recipe -@$(MAKE) -C $(dir) --no-print-directory $@ +@$(MAKE) SYS=$(SYS) -C $(dir) --no-print-directory $@ endef # SUBDIR_recipe +EXELIST_geos-cbm = \ + bitmap-demo.cvt \ + filesel.cvt \ + geosver.cvt \ + getid.cvt \ + hello1.cvt \ + hello2.cvt \ + overlay-demo.cvt \ + vector-demo.cvt \ + yesno.cvt + +EXELIST_geos-apple = \ + bitmap-demo.cvt \ + filesel.cvt \ + hello1.cvt \ + hello2.cvt \ + overlay-demo.cvt \ + vector-demo.cvt \ + yesno.cvt + # omitted: dialog.c grphstr.c inittab.c menu.c - # TODO: geosconio.cvt rmvprot.cvt -samples: bitmap-demo.cvt filesel.cvt geosver.cvt getid.cvt hello1.cvt hello2.cvt \ - overlay-demo.cvt vector-demo.cvt yesno.cvt - $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) +ifneq ($(EXELIST_$(SYS)),) +samples: $(EXELIST_$(SYS)) + $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) +else +samples: + @echo "warning: geos samples not available for" $(SYS) +endif + + bitmap.c: logo.pcx $(SP) -r logo.pcx -c geos-bitmap -w bitmap.c,ident=bitmap diff --git a/samples/geos/grc/Makefile b/samples/geos/grc/Makefile index 81f9ca045..0a432fd89 100644 --- a/samples/geos/grc/Makefile +++ b/samples/geos/grc/Makefile @@ -1,4 +1,8 @@ +# Run 'make SYS=<target>'; or, set a SYS env. +# var. to build for another target system. +SYS ?= geos-cbm + # Just the usual way to find out if we're # using cmd.exe to execute make rules. ifneq ($(shell echo),) @@ -29,22 +33,31 @@ else GRC := $(if $(wildcard ../../../bin/grc65*),../../../bin/grc65,grc65) endif -samples: test.s vlir.cvt +EXELIST_geos-cbm = \ + test.s \ + vlir.cvt + +ifneq ($(EXELIST_$(SYS)),) +samples: $(EXELIST_$(SYS)) +else +samples: + @echo "warning: grc sample not available for" $(SYS) +endif test.s: test.grc $(GRC) -s test.s test.grc vlir.cvt: vlir.grc vlir0.s vlir1.s vlir2.s # using seperate calls here for demonstration purposes: - $(GRC) -t geos-cbm -s vlir.s vlir.grc - $(AS) -t geos-cbm vlir.s - $(AS) -t geos-cbm vlir0.s - $(AS) -t geos-cbm vlir1.s - $(AS) -t geos-cbm vlir2.s - $(LD) -t geos-cbm -o vlir.cvt vlir.o vlir0.o vlir1.o vlir2.o geos-cbm.lib + $(GRC) -t $(SYS) -s vlir.s vlir.grc + $(AS) -t $(SYS) vlir.s + $(AS) -t $(SYS) vlir0.s + $(AS) -t $(SYS) vlir1.s + $(AS) -t $(SYS) vlir2.s + $(LD) -t $(SYS) -o vlir.cvt vlir.o vlir0.o vlir1.o vlir2.o $(SYS).lib # you can also do the above in one command: -# $(CL) -t geos-cbm -o vlir.cvt vlir.grc vlir0.s vlir1.s vlir2.s +# $(CL) -t $(SYS) -o vlir.cvt vlir.grc vlir0.s vlir1.s vlir2.s clean: @$(DEL) test.s test.h 2>$(NULLDEV) diff --git a/samples/tutorial/Makefile b/samples/tutorial/Makefile index 2c4bcb988..39b2d6e8c 100644 --- a/samples/tutorial/Makefile +++ b/samples/tutorial/Makefile @@ -31,10 +31,56 @@ else LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) endif -samples: hello +EXELIST_atari2600 = \ + notavailable + +EXELIST_bbc = \ + notavailable + +EXELIST_creativision = \ + notavailable + +EXELIST_gamate = \ + notavailable + +EXELIST_geos-cbm = \ + notavailable + +EXELIST_geos-apple = \ + notavailable + +EXELIST_lunix = \ + notavailable + +EXELIST_lynx = \ + notavailable + +EXELIST_nes = \ + notavailable + +EXELIST_osic1p = \ + notavailable + +EXELIST_pce = \ + notavailable + +EXELIST_supervision = \ + notavailable + +# Unlisted targets will try to build everything. +# That lets us learn what they cannot build, and what settings +# we need to use for programs that can be built and run. +ifndef EXELIST_$(SYS) +EXELIST_$(SYS) := ${patsubst %.c,%,$(wildcard *.c)} +endif + +samples: $(EXELIST_$(SYS)) hello: hello.c text.s $(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 +notavailable: + @echo "warning: tutorial sample not available for" $(SYS) clean: @$(DEL) hello 2>$(NULLDEV) From aecb01986a6c7154ce6e81ac1f319c9193eee979 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 16 May 2021 15:45:34 +0200 Subject: [PATCH 2043/2161] fix list of executables for geos-apple --- samples/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index e8b9824d8..90fba50c9 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -271,8 +271,7 @@ EXELIST_geos-cbm = \ diodemo EXELIST_geos-apple = \ - ascii \ - diodemo + ascii EXELIST_lunix = \ notavailable From 53f0552fe71f1aed5534c8e04f99fb0fa75256cf Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 16 May 2021 17:12:50 +0200 Subject: [PATCH 2044/2161] fix warnings --- samples/nachtm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/nachtm.c b/samples/nachtm.c index 0b962fa5d..02801da24 100644 --- a/samples/nachtm.c +++ b/samples/nachtm.c @@ -972,12 +972,12 @@ static void MakeNiceScreen (void) /* Clear the screen hide the cursor, set colors */ #ifdef __CBM610__ - textcolor (COLOR_WHITE); + (void)textcolor (COLOR_WHITE); #else - textcolor (COLOR_GRAY3); + (void)textcolor (COLOR_GRAY3); #endif - bordercolor (COLOR_BLACK); - bgcolor (COLOR_BLACK); + (void)bordercolor (COLOR_BLACK); + (void)bgcolor (COLOR_BLACK); clrscr (); cursor (0); From 4ba3ff3048e0baffac77f671c6947afdeee775df Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 16 May 2021 18:23:23 +0200 Subject: [PATCH 2045/2161] redirect c64 to geos-cbm and apple2enh to geos-apple when given with SYS= on the command line, as suggested by oliver --- samples/geos/Makefile | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/samples/geos/Makefile b/samples/geos/Makefile index 9ad555565..a894c5d01 100644 --- a/samples/geos/Makefile +++ b/samples/geos/Makefile @@ -3,6 +3,17 @@ # var. to build for another target system. SYS ?= geos-cbm +# If SYS was given on the commandline, redirect "c64" to "geos-cbm" and +# "apple2enh" to "geos-apple" +ifeq "$(origin SYS)" "command line" +ifeq "$(SYS)" "c64" + override SYS = geos-cbm +endif +ifeq "$(SYS)" "apple2enh" + override SYS = geos-apple +endif +endif + # Just the usual way to find out if we're # using cmd.exe to execute make rules. ifneq ($(shell echo),) From a9af6aa74334483c09fd367ab01c5d4358ab7120 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 16 May 2021 18:29:45 +0200 Subject: [PATCH 2046/2161] fix warnings --- samples/geos/geosver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/geos/geosver.c b/samples/geos/geosver.c index 1402d148e..3d68798a2 100644 --- a/samples/geos/geosver.c +++ b/samples/geos/geosver.c @@ -8,8 +8,8 @@ struct window wholeScreen = {0, SC_PIX_HEIGHT-1, 0, SC_PIX_WIDTH-1}; void main (void) { unsigned char os = get_ostype(); - unsigned char *machine = NULL; - unsigned char *version = NULL; + char *machine = NULL; + char *version = NULL; unsigned char good = 1; SetPattern(0); From 43ca88726344b82065bf83dd5b693f7b6006c94e Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 16 May 2021 16:06:52 +0800 Subject: [PATCH 2047/2161] Fixed 'case'/'default' labels in non-compound 'switch' body statement. --- src/cc65/function.c | 2 +- src/cc65/stmt.c | 177 ++++++++++++++++++++++++++------------------ src/cc65/stmt.h | 2 +- src/cc65/swstmt.c | 2 +- 4 files changed, 106 insertions(+), 77 deletions(-) diff --git a/src/cc65/function.c b/src/cc65/function.c index 4e61cc1d3..452181af9 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -644,7 +644,7 @@ void NewFunc (SymEntry* Func, FuncDesc* D) /* Now process statements in this block */ while (CurTok.Tok != TOK_RCURLY && CurTok.Tok != TOK_CEOF) { - Statement (0); + AnyStatement (0); } /* If this is not a void function, and not the main function in a C99 diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index ccb113978..022a8475c 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -163,7 +163,7 @@ static int IfStatement (void) TestResult = TestInParens (Label1, 0); /* Parse the if body */ - GotBreak = Statement (0); + GotBreak = AnyStatement (0); /* Else clause present? */ if (CurTok.Tok != TOK_ELSE) { @@ -195,7 +195,7 @@ static int IfStatement (void) g_defcodelabel (Label1); /* Total break only if both branches had a break. */ - GotBreak &= Statement (0); + GotBreak &= AnyStatement (0); /* Generate the label for the else clause */ g_defcodelabel (Label2); @@ -225,7 +225,7 @@ static void DoStatement (void) g_defcodelabel (LoopLabel); /* Parse the loop body */ - Statement (0); + AnyStatement (0); /* Output the label for a continue */ g_defcodelabel (ContinueLabel); @@ -283,7 +283,7 @@ static void WhileStatement (void) g_defcodelabel (LoopLabel); /* Loop body */ - Statement (&PendingToken); + AnyStatement (&PendingToken); /* Emit the while condition label */ g_defcodelabel (CondLabel); @@ -509,7 +509,7 @@ static void ForStatement (void) /* Loop body */ g_defcodelabel (BodyLabel); - Statement (&PendingToken); + AnyStatement (&PendingToken); /* If we had an increment expression, move the code to the bottom of ** the loop. In this case we don't need to jump there at the end of @@ -536,17 +536,20 @@ static void ForStatement (void) -static int CompoundStatement (void) +static int CompoundStatement (int* PendingToken) /* Compound statement. Allow any number of statements inside braces. The ** function returns true if the last statement was a break or return. */ { - int GotBreak; + int GotBreak = 0; /* Remember the stack at block entry */ int OldStack = StackPtr; unsigned OldBlockStackSize = CollCount (&CurrentFunc->LocalsBlockStack); + /* Skip '{' */ + NextToken (); + /* Enter a new lexical level */ EnterBlockLevel (); @@ -554,16 +557,15 @@ static int CompoundStatement (void) DeclareLocals (); /* Now process statements in this block */ - GotBreak = 0; while (CurTok.Tok != TOK_RCURLY) { if (CurTok.Tok != TOK_CEOF) { - GotBreak = Statement (0); + GotBreak = AnyStatement (0); } else { break; } } - /* Clean up the stack. */ + /* Clean up the stack if the codeflow may reach the end */ if (!GotBreak) { g_space (StackPtr - OldStack); } @@ -583,12 +585,80 @@ static int CompoundStatement (void) /* Leave the lexical level */ LeaveBlockLevel (); + /* Skip '}' */ + CheckTok (TOK_RCURLY, "'}' expected", PendingToken); + return GotBreak; } -int Statement (int* PendingToken) +static void Statement (int* PendingToken) +/* Single-line statement */ +{ + ExprDesc Expr; + unsigned PrevErrorCount; + CodeMark Start, End; + + /* Remember the current error count and code position */ + PrevErrorCount = ErrorCount; + GetCodePos (&Start); + + /* Actual statement */ + ED_Init (&Expr); + Expr.Flags |= E_NEED_NONE; + Expression0 (&Expr); + + /* If the statement didn't generate code, and is not of type + ** void, emit a warning. + */ + GetCodePos (&End); + if (!ED_YetToLoad (&Expr) && + !ED_MayHaveNoEffect (&Expr) && + CodeRangeIsEmpty (&Start, &End) && + IS_Get (&WarnNoEffect) && + PrevErrorCount == ErrorCount) { + Warning ("Expression result unused"); + } + CheckSemi (PendingToken); +} + + + +static int ParseAnyLabels (void) +/* Return -1 if there are any labels with a statement */ +{ + unsigned PrevErrorCount = ErrorCount; + int HasLabels = 0; + for (;;) { + if (CurTok.Tok == TOK_IDENT && NextTok.Tok == TOK_COLON) { + /* C 'goto' label */ + DoLabel (); + } else if (CurTok.Tok == TOK_CASE) { + /* C 'case' label */ + CaseLabel (); + } else if (CurTok.Tok == TOK_DEFAULT) { + /* C 'default' label */ + DefaultLabel (); + } else { + /* No labels */ + break; + } + HasLabels = 1; + } + + if (HasLabels) { + if (PrevErrorCount != ErrorCount || CheckLabelWithoutStatement ()) { + return -1; + } + } + + return 0; +} + + + +int AnyStatement (int* PendingToken) /* Statement parser. Returns 1 if the statement does a return/break, returns ** 0 otherwise. If the PendingToken pointer is not NULL, the function will ** not skip the terminating token of the statement (closing brace or @@ -598,40 +668,27 @@ int Statement (int* PendingToken) ** NULL, the function will skip the token. */ { - ExprDesc Expr; - int GotBreak; - unsigned PrevErrorCount; - CodeMark Start, End; - - ED_Init (&Expr); - /* Assume no pending token */ if (PendingToken) { *PendingToken = 0; } - /* Check for a label. A label is always part of a statement, it does not + /* Handle any labels. A label is always part of a statement, it does not ** replace one. */ - while (CurTok.Tok == TOK_IDENT && NextTok.Tok == TOK_COLON) { - /* Handle the label */ - DoLabel (); - if (CheckLabelWithoutStatement ()) { - return 0; - } + if (ParseAnyLabels ()) { + return 0; } switch (CurTok.Tok) { - case TOK_LCURLY: - NextToken (); - GotBreak = CompoundStatement (); - CheckTok (TOK_RCURLY, "'{' expected", PendingToken); - return GotBreak; - case TOK_IF: return IfStatement (); + case TOK_SWITCH: + SwitchStatement (); + break; + case TOK_WHILE: WhileStatement (); break; @@ -640,10 +697,15 @@ int Statement (int* PendingToken) DoStatement (); break; - case TOK_SWITCH: - SwitchStatement (); + case TOK_FOR: + ForStatement (); break; + case TOK_GOTO: + GotoStatement (); + CheckSemi (PendingToken); + return 1; + case TOK_RETURN: ReturnStatement (); CheckSemi (PendingToken); @@ -659,55 +721,22 @@ int Statement (int* PendingToken) CheckSemi (PendingToken); return 1; - case TOK_FOR: - ForStatement (); - break; - - case TOK_GOTO: - GotoStatement (); - CheckSemi (PendingToken); - return 1; - - case TOK_SEMI: - /* Ignore it */ - CheckSemi (PendingToken); - break; - case TOK_PRAGMA: DoPragma (); break; - case TOK_CASE: - CaseLabel (); - CheckLabelWithoutStatement (); + case TOK_SEMI: + /* Empty statement. Ignore it */ + CheckSemi (PendingToken); break; - case TOK_DEFAULT: - DefaultLabel (); - CheckLabelWithoutStatement (); - break; + case TOK_LCURLY: + return CompoundStatement (PendingToken); default: - /* Remember the current error count and code position */ - PrevErrorCount = ErrorCount; - GetCodePos (&Start); - - /* Actual statement */ - Expr.Flags |= E_NEED_NONE; - Expression0 (&Expr); - - /* If the statement didn't generate code, and is not of type - ** void, emit a warning. - */ - GetCodePos (&End); - if (!ED_YetToLoad (&Expr) && - !ED_MayHaveNoEffect (&Expr) && - CodeRangeIsEmpty (&Start, &End) && - IS_Get (&WarnNoEffect) && - PrevErrorCount == ErrorCount) { - Warning ("Expression result unused"); - } - CheckSemi (PendingToken); + /* Simple statement */ + Statement (PendingToken); + break; } return 0; } diff --git a/src/cc65/stmt.h b/src/cc65/stmt.h index 04ef728a3..8cff99d92 100644 --- a/src/cc65/stmt.h +++ b/src/cc65/stmt.h @@ -44,7 +44,7 @@ -int Statement (int* PendingToken); +int AnyStatement (int* PendingToken); /* Statement parser. Returns 1 if the statement does a return/break, returns ** 0 otherwise. If the PendingToken pointer is not NULL, the function will ** not skip the terminating token of the statement (closing brace or diff --git a/src/cc65/swstmt.c b/src/cc65/swstmt.c index 3878f7b67..ee0bd1a85 100644 --- a/src/cc65/swstmt.c +++ b/src/cc65/swstmt.c @@ -148,7 +148,7 @@ void SwitchStatement (void) /* Parse the following statement, which may actually be a compound ** statement if there is a curly brace at the current input position */ - HaveBreak = Statement (&RCurlyBrace); + HaveBreak = AnyStatement (&RCurlyBrace); /* Check if we had any labels */ if (CollCount (SwitchData.Nodes) == 0 && SwitchData.DefaultLabel == 0) { From 1450f146a50ac257eea145607801d4f6b1cb4bfb Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 16 May 2021 16:09:45 +0800 Subject: [PATCH 2048/2161] Fixed '[]', '()' '.' and '->' operators following a postfix increment/decrement. --- src/cc65/expr.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index a63214f49..b68b3abbb 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -80,6 +80,8 @@ static GenDesc GenOASGN = { TOK_OR_ASSIGN, GEN_NOPUSH, g_or }; static void parseadd (ExprDesc* Expr, int DoArrayRef); +static void PostInc (ExprDesc* Expr); +static void PostDec (ExprDesc* Expr); @@ -88,6 +90,7 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef); /*****************************************************************************/ + static unsigned GlobalModeFlags (const ExprDesc* Expr) /* Return the addressing mode flags for the given expression */ { @@ -1510,7 +1513,8 @@ static void hie11 (ExprDesc *Expr) Primary (Expr); /* Check for a rhs */ - while (CurTok.Tok == TOK_LBRACK || CurTok.Tok == TOK_LPAREN || + while (CurTok.Tok == TOK_INC || CurTok.Tok == TOK_DEC || + CurTok.Tok == TOK_LBRACK || CurTok.Tok == TOK_LPAREN || CurTok.Tok == TOK_DOT || CurTok.Tok == TOK_PTR_REF) { switch (CurTok.Tok) { @@ -1554,6 +1558,14 @@ static void hie11 (ExprDesc *Expr) StructRef (Expr); break; + case TOK_INC: + PostInc (Expr); + break; + + case TOK_DEC: + PostDec (Expr); + break; + default: Internal ("Invalid token in hie11: %d", CurTok.Tok); @@ -2106,13 +2118,6 @@ void hie10 (ExprDesc* Expr) /* An expression */ hie11 (Expr); - /* Handle post increment */ - switch (CurTok.Tok) { - case TOK_INC: PostInc (Expr); break; - case TOK_DEC: PostDec (Expr); break; - default: break; - } - } break; } From ce487651b09901fbd69183e69425d830505900e8 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 16 May 2021 22:24:35 +0200 Subject: [PATCH 2049/2161] as suggested by Oliver: - only output messages if MAKELEVEL is 0 - indent nested ifeq - use if (,) syntax --- samples/Makefile | 4 +++- samples/geos/Makefile | 20 ++++++++++++-------- samples/geos/grc/Makefile | 4 +++- samples/tutorial/Makefile | 5 ++++- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index 90fba50c9..f1e7a1e0b 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -344,7 +344,9 @@ samples: $(EXELIST_$(SYS)) # empty target used to skip systems that will not work with any program in this dir notavailable: - @echo "warning: generic samples not available for" $(SYS) +ifeq ($(MAKELEVEL),0) + @echo "info: generic samples not available for" $(SYS) +endif disk: $(DISK_$(SYS)) diff --git a/samples/geos/Makefile b/samples/geos/Makefile index a894c5d01..0bf862ca7 100644 --- a/samples/geos/Makefile +++ b/samples/geos/Makefile @@ -5,13 +5,15 @@ SYS ?= geos-cbm # If SYS was given on the commandline, redirect "c64" to "geos-cbm" and # "apple2enh" to "geos-apple" -ifeq "$(origin SYS)" "command line" -ifeq "$(SYS)" "c64" - override SYS = geos-cbm -endif -ifeq "$(SYS)" "apple2enh" - override SYS = geos-apple -endif +ifeq ($(origin SYS),command line) + ifeq ($(SYS),c64) + override SYS = geos-cbm + $(info GEOS: c64 -> geos-cbm) + endif + ifeq ($(SYS),apple2enh) + override SYS = geos-apple + $(info GEOS: apple2enh -> geos-apple) + endif endif # Just the usual way to find out if we're @@ -80,7 +82,9 @@ samples: $(EXELIST_$(SYS)) $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) else samples: - @echo "warning: geos samples not available for" $(SYS) + ifeq ($(MAKELEVEL),0) + @echo "info: geos samples not available for" $(SYS) + endif endif diff --git a/samples/geos/grc/Makefile b/samples/geos/grc/Makefile index 0a432fd89..4ad4f00a6 100644 --- a/samples/geos/grc/Makefile +++ b/samples/geos/grc/Makefile @@ -41,7 +41,9 @@ ifneq ($(EXELIST_$(SYS)),) samples: $(EXELIST_$(SYS)) else samples: - @echo "warning: grc sample not available for" $(SYS) + ifeq ($(MAKELEVEL),0) + @echo "info: grc sample not available for" $(SYS) + endif endif test.s: test.grc diff --git a/samples/tutorial/Makefile b/samples/tutorial/Makefile index 39b2d6e8c..911988db5 100644 --- a/samples/tutorial/Makefile +++ b/samples/tutorial/Makefile @@ -81,6 +81,9 @@ hello: hello.c text.s # empty target used to skip systems that will not work with any program in this dir notavailable: - @echo "warning: tutorial sample not available for" $(SYS) +ifeq ($(MAKELEVEL),0) + @echo "info: tutorial sample not available for" $(SYS) +endif + clean: @$(DEL) hello 2>$(NULLDEV) From 5fc9d3f048f8897bce1c56a4359af1221f6141b9 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 16 May 2021 22:57:28 +0200 Subject: [PATCH 2050/2161] change driver _install calls from taking "void*" to "const void*" --- include/em.h | 2 +- include/joystick.h | 2 +- include/serial.h | 2 +- include/tgi.h | 2 +- libsrc/em/em-kernel.s | 2 +- libsrc/joystick/joy-kernel.s | 2 +- libsrc/serial/ser-kernel.s | 2 +- libsrc/tgi/tgi-kernel.s | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/em.h b/include/em.h index b151800ae..47bd23222 100644 --- a/include/em.h +++ b/include/em.h @@ -82,7 +82,7 @@ unsigned char __fastcall__ em_load_driver (const char* driver); unsigned char em_unload (void); /* Uninstall, then unload the currently loaded driver. */ -unsigned char __fastcall__ em_install (void* driver); +unsigned char __fastcall__ em_install (const void* driver); /* Install an already loaded driver. Return an error code. */ unsigned char em_uninstall (void); diff --git a/include/joystick.h b/include/joystick.h index b6771c381..963c9ba95 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -89,7 +89,7 @@ unsigned char __fastcall__ joy_load_driver (const char* driver); unsigned char joy_unload (void); /* Uninstall, then unload the currently loaded driver. */ -unsigned char __fastcall__ joy_install (void* driver); +unsigned char __fastcall__ joy_install (const void* driver); /* Install an already loaded driver. Return an error code. */ unsigned char joy_uninstall (void); diff --git a/include/serial.h b/include/serial.h index 990f66521..58943d507 100644 --- a/include/serial.h +++ b/include/serial.h @@ -136,7 +136,7 @@ unsigned char __fastcall__ ser_load_driver (const char* driver); unsigned char ser_unload (void); /* Uninstall, then unload the currently loaded driver. */ -unsigned char __fastcall__ ser_install (void* driver); +unsigned char __fastcall__ ser_install (const void* driver); /* Install an already loaded driver. Return an error code. */ unsigned char ser_uninstall (void); diff --git a/include/tgi.h b/include/tgi.h index 135ef63f1..2ef65b856 100644 --- a/include/tgi.h +++ b/include/tgi.h @@ -82,7 +82,7 @@ void tgi_unload (void); ** necessary. */ -void __fastcall__ tgi_install (void* driver); +void __fastcall__ tgi_install (const void* driver); /* Install an already loaded driver. */ void tgi_uninstall (void); diff --git a/libsrc/em/em-kernel.s b/libsrc/em/em-kernel.s index c982dac88..d5be0ae23 100644 --- a/libsrc/em/em-kernel.s +++ b/libsrc/em/em-kernel.s @@ -36,7 +36,7 @@ emd_sig: .byte $65, $6d, $64, EMD_API_VERSION ; "emd", version ;---------------------------------------------------------------------------- -; unsigned char __fastcall__ em_install (void* driver); +; unsigned char __fastcall__ em_install (const void* driver); ; /* Install the driver once it is loaded */ diff --git a/libsrc/joystick/joy-kernel.s b/libsrc/joystick/joy-kernel.s index c2d50c8d8..53d475c57 100644 --- a/libsrc/joystick/joy-kernel.s +++ b/libsrc/joystick/joy-kernel.s @@ -33,7 +33,7 @@ joy_sig: .byte $6A, $6F, $79, JOY_API_VERSION ; "joy", version .code ;---------------------------------------------------------------------------- -; unsigned char __fastcall__ joy_install (void* driver); +; unsigned char __fastcall__ joy_install (const void* driver); ; /* Install the driver once it is loaded */ diff --git a/libsrc/serial/ser-kernel.s b/libsrc/serial/ser-kernel.s index 4c5b455b6..b6c57a3b5 100644 --- a/libsrc/serial/ser-kernel.s +++ b/libsrc/serial/ser-kernel.s @@ -39,7 +39,7 @@ ser_sig: .byte $73, $65, $72, SER_API_VERSION ; "ser", version .code ;---------------------------------------------------------------------------- -; unsigned char __fastcall__ ser_install (void* driver); +; unsigned char __fastcall__ ser_install (const void* driver); ; /* Install the driver once it is loaded */ diff --git a/libsrc/tgi/tgi-kernel.s b/libsrc/tgi/tgi-kernel.s index 3a388b6dc..cbd655279 100644 --- a/libsrc/tgi/tgi-kernel.s +++ b/libsrc/tgi/tgi-kernel.s @@ -88,7 +88,7 @@ tgi_sig: .byte $74, $67, $69, TGI_API_VERSION ; "tgi", version .code ;---------------------------------------------------------------------------- -; void __fastcall__ tgi_install (void* driver); +; void __fastcall__ tgi_install (const void* driver); ; /* Install an already loaded driver. */ From d2da30a7e25cb6f918af10b6d69dbabdc369512a Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 16 May 2021 23:38:17 +0200 Subject: [PATCH 2051/2161] give the "samples" target something to do to supress the "nothing to be done for 'samples'" message --- samples/geos/Makefile | 4 +++- samples/geos/grc/Makefile | 3 +++ samples/tutorial/Makefile | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/samples/geos/Makefile b/samples/geos/Makefile index 0bf862ca7..e792c52f1 100644 --- a/samples/geos/Makefile +++ b/samples/geos/Makefile @@ -84,10 +84,12 @@ else samples: ifeq ($(MAKELEVEL),0) @echo "info: geos samples not available for" $(SYS) + else +# suppress the "nothing to be done for 'samples' message + @echo > $(NULLDEV) endif endif - bitmap.c: logo.pcx $(SP) -r logo.pcx -c geos-bitmap -w bitmap.c,ident=bitmap diff --git a/samples/geos/grc/Makefile b/samples/geos/grc/Makefile index 4ad4f00a6..9dd9ebc5e 100644 --- a/samples/geos/grc/Makefile +++ b/samples/geos/grc/Makefile @@ -43,6 +43,9 @@ else samples: ifeq ($(MAKELEVEL),0) @echo "info: grc sample not available for" $(SYS) + else +# suppress the "nothing to be done for 'samples' message + @echo > $(NULLDEV) endif endif diff --git a/samples/tutorial/Makefile b/samples/tutorial/Makefile index 911988db5..af5062588 100644 --- a/samples/tutorial/Makefile +++ b/samples/tutorial/Makefile @@ -83,6 +83,9 @@ hello: hello.c text.s notavailable: ifeq ($(MAKELEVEL),0) @echo "info: tutorial sample not available for" $(SYS) +else +# suppress the "nothing to be done for 'samples' message + @echo > $(NULLDEV) endif clean: From c53059468e8a96e4ade3781aa87a0faa5f1abc4a Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 17 May 2021 14:25:18 +0200 Subject: [PATCH 2052/2161] fix documentation for the driver _init calls --- doc/funcref.sgml | 6 +++--- doc/tgi.sgml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 4d1a278b0..2cb8bbf44 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -3410,7 +3410,7 @@ loaded. <descrip> <tag/Function/Install an already loaded extended memory driver. <tag/Header/<tt/<ref id="em.h" name="em.h">/ -<tag/Declaration/<tt/unsigned char _fastcall__ em_install (void* driver);/ +<tag/Declaration/<tt/unsigned char _fastcall__ em_install (const void* driver);/ <tag/Description/The function installs an already loaded extended memory driver and returns an error code. The function may be used to install a driver linked statically to the program. @@ -4733,7 +4733,7 @@ There's no way to check for the number of actually connected joysticks. <descrip> <tag/Function/Install an already loaded driver and return an error code. <tag/Header/<tt/<ref id="joystick.h" name="joystick.h">/ -<tag/Declaration/<tt/unsigned char __fastcall__ joy_install (void* driver);/ +<tag/Declaration/<tt/unsigned char __fastcall__ joy_install (const void* driver);/ <tag/Description/The function installs a driver that was already loaded into memory (or linked statically to the program). It returns an error code (<tt/JOY_ERR_OK/ in case of success). @@ -6198,7 +6198,7 @@ while (ser_get(&ch) == SER_ERR_NO_DATA) <descrip> <tag/Function/Install an already loaded driver and return an error code. <tag/Header/<tt/<ref id="serial.h" name="serial.h">/ -<tag/Declaration/<tt/unsigned char __fastcall__ ser_install (void* driver);/ +<tag/Declaration/<tt/unsigned char __fastcall__ ser_install (const void* driver);/ <tag/Description/The function installs a driver that was already loaded into memory (or linked statically to the program). It returns an error code (<tt/SER_ERR_OK/ in case of success). diff --git a/doc/tgi.sgml b/doc/tgi.sgml index b1497ca70..29acd8ce6 100644 --- a/doc/tgi.sgml +++ b/doc/tgi.sgml @@ -555,7 +555,7 @@ tgi_init(); //Set up the default palette and clear the screen. <descrip> <tag/Function/Install an already loaded driver and return an error code. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/unsigned char __fastcall__ tgi_install (void* driver);/ +<tag/Declaration/<tt/unsigned char __fastcall__ tgi_install (const void* driver);/ <tag/Description/The function installs a driver that was already loaded into memory (or linked statically to the program). It returns an error code (<tt/TGI_ERR_OK/ in case of success). From d736032675dc998e9196ea7e6f392945fc17795d Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 17 May 2021 14:25:33 +0200 Subject: [PATCH 2053/2161] added a missing comment --- test/misc/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/test/misc/Makefile b/test/misc/Makefile index 397635afd..b17c69f5c 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -64,6 +64,7 @@ $(WORKDIR)/bug760.$1.$2.prg: bug760.c | $(WORKDIR) $(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) From 4a57656f692c5fb08fe80e0c665d852d8e32388b Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 17 May 2021 14:40:09 +0200 Subject: [PATCH 2054/2161] add test for issue #1504 --- test/val/bug1504.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test/val/bug1504.c diff --git a/test/val/bug1504.c b/test/val/bug1504.c new file mode 100644 index 000000000..bd93c7387 --- /dev/null +++ b/test/val/bug1504.c @@ -0,0 +1,13 @@ + +/* bug #1504 - Some compilation failures */ + +#include <stdio.h> + +int main(void) +{ + int i = 0, *p = &i; + switch (i) case 0: case 1: i = 21; /* Should be OK but fails */ + p++[0] += 21; /* Should be OK but fails */ + printf("%d\n", i); + return i != 42; +} From d14148ab4f9d8d1d52025eac31bfc09d977fbaa7 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Mon, 17 May 2021 19:48:47 -0400 Subject: [PATCH 2055/2161] Restricted commit b9a3c7888822732a0de92741cfe1a3e1b6bb272f to classic-style Assembly macros. .include will work at expansion-time for .define macros. --- src/ca65/macro.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 34d87e65f..d6c807035 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -438,9 +438,7 @@ void MacDef (unsigned Style) /* Parse the parameter list */ if (HaveParams) { - while (CurTok.Tok == TOK_IDENT) { - /* Create a struct holding the identifier */ IdDesc* I = NewIdDesc (&CurTok.SVal); @@ -449,6 +447,7 @@ void MacDef (unsigned Style) M->Params = I; } else { IdDesc* List = M->Params; + while (1) { if (SB_Compare (&List->Id, &CurTok.SVal) == 0) { Error ("Duplicate symbol '%m%p'", &CurTok.SVal); @@ -490,9 +489,8 @@ void MacDef (unsigned Style) ** the .LOCAL command is detected and removed, at this time. */ while (1) { - /* Check for include */ - if (CurTok.Tok == TOK_INCLUDE) { + if (CurTok.Tok == TOK_INCLUDE && Style == MAC_STYLE_CLASSIC) { /* Include another file */ NextTok (); /* Name must follow */ @@ -529,9 +527,7 @@ void MacDef (unsigned Style) /* Check for a .LOCAL declaration */ if (CurTok.Tok == TOK_LOCAL && Style == MAC_STYLE_CLASSIC) { - while (1) { - IdDesc* I; /* Skip .local or comma */ @@ -570,6 +566,7 @@ void MacDef (unsigned Style) if (CurTok.Tok == TOK_IDENT) { unsigned Count = 0; IdDesc* I = M->Params; + while (I) { if (SB_Compare (&I->Id, &CurTok.SVal) == 0) { /* Local param name, replace it */ From 6d560f42366ecbd12f05f6ce121ffa7685497114 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 18 May 2021 15:16:14 +0200 Subject: [PATCH 2056/2161] change prototype for GraphicsString() to void __fastcall__ GraphicsString(const void *myGfxString); --- doc/geos.sgml | 2 +- include/geos/ggraph.h | 2 +- libsrc/geos-common/graph/graphicsstring.s | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/geos.sgml b/doc/geos.sgml index 11ff9c534..f7943f8cd 100644 --- a/doc/geos.sgml +++ b/doc/geos.sgml @@ -205,7 +205,7 @@ see them together in the filling box in GeoPaint. <sect2>GraphicsString <p> -<tt/void GraphicsString (char *myGString)/ +<tt/void GraphicsString (const void *myGString)/ <p> One of the more powerfull routines of GEOS. This function calls other graphic functions depending on the given command string. See the structures chapter for a more detailed description. diff --git a/include/geos/ggraph.h b/include/geos/ggraph.h index ec9fb0fa1..b550d6ca1 100644 --- a/include/geos/ggraph.h +++ b/include/geos/ggraph.h @@ -43,7 +43,7 @@ void __fastcall__ BitOtherClip(void *proc1, void *proc2, char skipl, char skipr, unsigned skiptop, struct iconpic *myIcon); -void __fastcall__ GraphicsString(char *myGfxString); +void __fastcall__ GraphicsString(const void *myGfxString); #ifdef __GEOS_CBM__ void SetNewMode(void); diff --git a/libsrc/geos-common/graph/graphicsstring.s b/libsrc/geos-common/graph/graphicsstring.s index 86c74f1a6..282649284 100644 --- a/libsrc/geos-common/graph/graphicsstring.s +++ b/libsrc/geos-common/graph/graphicsstring.s @@ -3,7 +3,7 @@ ; ; 25.12.99 -; void GraphicsString (char *myString); +; void GraphicsString (const void *myString); .export _GraphicsString From 0ae1aad3d3705b5cbae0d0ff74fae711bc505f52 Mon Sep 17 00:00:00 2001 From: Olli Savia <ops@iki.fi> Date: Wed, 19 May 2021 21:08:43 +0300 Subject: [PATCH 2057/2161] Fix typo: VIAx_CR -> VIAx_ACR --- asminc/vic20.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asminc/vic20.inc b/asminc/vic20.inc index 41a935238..7184ab6ee 100644 --- a/asminc/vic20.inc +++ b/asminc/vic20.inc @@ -90,7 +90,7 @@ VIA1_T1LH := VIA1+$7 ; Timer 1 latch, high byte VIA1_T2CL := VIA1+$8 ; Timer 2, low byte VIA1_T2CH := VIA1+$9 ; Timer 2, high byte VIA1_SR := VIA1+$A ; Shift register -VIA1_CR := VIA1+$B ; Auxiliary control register +VIA1_ACR := VIA1+$B ; Auxiliary control register VIA1_PCR := VIA1+$C ; Peripheral control register VIA1_IFR := VIA1+$D ; Interrupt flag register VIA1_IER := VIA1+$E ; Interrupt enable register @@ -112,7 +112,7 @@ VIA2_T1LH := VIA2+$7 ; Timer 1 latch, high byte VIA2_T2CL := VIA2+$8 ; Timer 2, low byte VIA2_T2CH := VIA2+$9 ; Timer 2, high byte VIA2_SR := VIA2+$A ; Shift register -VIA2_CR := VIA2+$B ; Auxiliary control register +VIA2_ACR := VIA2+$B ; Auxiliary control register VIA2_PCR := VIA2+$C ; Peripheral control register VIA2_IFR := VIA2+$D ; Interrupt flag register VIA2_IER := VIA2+$E ; Interrupt enable register From 681c9594cc37581c50d48b67364398bdedeae4bf Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Fri, 21 May 2021 01:45:55 +0200 Subject: [PATCH 2058/2161] libsrc/atari5200/crt0.s: fix formatting --- libsrc/atari5200/crt0.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/atari5200/crt0.s b/libsrc/atari5200/crt0.s index 9538d3bb4..8f6e02273 100644 --- a/libsrc/atari5200/crt0.s +++ b/libsrc/atari5200/crt0.s @@ -44,4 +44,4 @@ _exit: jsr donelib ; Run module destructors ; A 5200 program isn't supposed to exit. -halt: jmp halt +halt: jmp halt From 663268dca98856a0280a49cc0582a77cd511a05f Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 21 May 2021 03:32:43 -0400 Subject: [PATCH 2059/2161] Syncronize the Supervision crt0.s with its ld65 config files. .segment "VECTOR" -> "VECTORS". Fixes #1506. --- libsrc/supervision/crt0.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/supervision/crt0.s b/libsrc/supervision/crt0.s index 203c681b8..fbae1fc46 100644 --- a/libsrc/supervision/crt0.s +++ b/libsrc/supervision/crt0.s @@ -67,13 +67,13 @@ not_dma: ; Removing this segment gives only a warning. .segment "FFF0" .proc reset32kcode - lda #(6<<5) | SV_LCD_ON | SV_NMI_ENABLE_ON + lda #(6<<5) | SV_LCD_ON | SV_NMI_ENABLE_ON sta sv_bank ; Now, the 32Kbyte image can reside in the top of 64Kbyte and 128Kbyte ROMs. jmp reset .endproc - .segment "VECTOR" + .segment "VECTORS" .word nmi .word reset32kcode From e13f57e86c37ae2601bed1d980fc1fa73915ff3b Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 21 May 2021 16:09:10 +0200 Subject: [PATCH 2060/2161] added another testcase for issue #1462 --- test/todo/bug1462-2.c | 51 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 test/todo/bug1462-2.c diff --git a/test/todo/bug1462-2.c b/test/todo/bug1462-2.c new file mode 100644 index 000000000..df94cfc59 --- /dev/null +++ b/test/todo/bug1462-2.c @@ -0,0 +1,51 @@ + +/* issue #1462 - Bit-fields are still broken */ +/* even the = operation is buggy in certain ways */ + +#include <stdio.h> + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +T *f(T *t) +{ + t->a = 0; + t->c = 0; + return t; +} + +void test(void) +{ + T a = { 7, 0, 7 }; + T *p = &a; + + a.b = f(p)->a; + + if (a.a != 0) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != 0) { + ++failures; + } + printf("%d\n", p->b); + + if ((&a)->c != 0) { + ++failures; + } + printf("%d\n", (&a)->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} From b08dc28cc1cb2241515d69ccdd89a3ac31afc788 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 22 May 2021 22:34:52 +0200 Subject: [PATCH 2061/2161] another testcase related to issue #1462 --- test/todo/bug1462-3.c | 95 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 test/todo/bug1462-3.c diff --git a/test/todo/bug1462-3.c b/test/todo/bug1462-3.c new file mode 100644 index 000000000..b75d568b9 --- /dev/null +++ b/test/todo/bug1462-3.c @@ -0,0 +1,95 @@ + +/* issue #1462 - Bit-fields are still broken */ +/* More testson "op= expression result value" that a naive fix might fail with */ + +#include <stdio.h> + +typedef struct { + signed int a : 3; + unsigned int b : 3; + signed int c : 3; + unsigned int d : 3; +} T1; + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; + signed int d : 3; +} T2; + + +int failures1 = 0; +int failures2 = 0; + +void test1(void) +{ + T1 a = { 3, 3, 3, 3 }; + int i; + + i = a.a += a.b + a.c; + if (i != 1) { + ++failures1; + } + printf("i = %d, a.a = %d\n", i, a.a); + + i = a.b *= -1; + if (i != 5 || a.b != 5) { + ++failures1; + } + printf("i = %d, a.b = %d\n", i, a.b); + + i = a.c * -1; + if (i != -3) { + ++failures1; + } + printf("i = %d, a.c = %d\n", i, a.c); + + i = a.d ^= -1; + if (i != 4 || a.d != 4) { + ++failures1; + } + printf("i = %d, a.d = %d\n", i, a.d); + + printf("Failures: %d\n", failures1); +} + +void test2(void) +{ + T2 b = { 3, 3, 4, 4 }; + int i; + + i = b.a++; + if (i != 3 || b.a != -4) { + ++failures2; + } + printf("i = %d, b.a = %d\n", i, b.a); + + i = ++b.b; + if (i != -4 || b.b != -4) { + ++failures2; + } + printf("i = %d, b.b = %d\n", i, b.b); + + i = b.c--; + if (i != -4 || b.c != 3) { + ++failures2; + } + printf("i = %d, b.c = %d\n", i, b.c); + + i = --b.d; + if (i != 3 || b.d != 3) { + ++failures2; + } + printf("i = %d, b.d = %d\n", i, b.d); + + printf("Failures: %d\n", failures2); +} + +int main(void) +{ + test1(); + test2(); + return failures1 + failures2; +} + From 0db23a8951ee43e8fdcb4377a58b045af6142983 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 23 May 2021 18:55:06 +0200 Subject: [PATCH 2062/2161] testcase for issue #263 --- test/val/bug263.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 test/val/bug263.c diff --git a/test/val/bug263.c b/test/val/bug263.c new file mode 100644 index 000000000..6f3f8f57e --- /dev/null +++ b/test/val/bug263.c @@ -0,0 +1,49 @@ + +/* issue #263 - cc65 miscompiles w/ a static variable and -O */ + +#include <stdint.h> +#include <stdio.h> + +int failures = 0; + +void __fastcall__ set_vram_update(unsigned char *ptr) +{ + printf("set_vram_update: %04x\n", ptr); + if (ptr != NULL) { + failures++; + } +} + +unsigned char __fastcall__ ppu_wait_nmi(void) +{ + // we need to make sure somehow the akku is not zero before the break + return 0x1234; +} + +unsigned char ctrl, ret, i; + +unsigned char gameloop (void) +{ + ctrl = 0; + ret = 0; + while(1) { + if (ctrl & 1) { + while (--i) { + ppu_wait_nmi(); + } + break; + } + ctrl = 1; + } + // This will pass garbage, not NULL. + set_vram_update(NULL); + return ret; +} + +int main(void) +{ + gameloop(); + printf("failures: %d\n", failures); + return failures; +} + From db395e59887fedbc3f690c0e13b076e0c24885a4 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Sun, 23 May 2021 13:31:28 -0500 Subject: [PATCH 2063/2161] Improved sample program symDisplay.c --- samples/symDisplay.c | 41 ++++++------------------------ samples/tutorial/sym1/symDisplay.c | 41 ++++++------------------------ 2 files changed, 16 insertions(+), 66 deletions(-) diff --git a/samples/symDisplay.c b/samples/symDisplay.c index 8a72d5863..fa94ce598 100644 --- a/samples/symDisplay.c +++ b/samples/symDisplay.c @@ -184,12 +184,8 @@ void main (void) { set_D2( get_D3() ); set_D3( get_D4() ); set_D4( get_D5() ); - set_D5( get_D6() ); - set_D6( DISP_M_1 ); - for( d = 0; d < flashes ; d++ ) { - fdisp(); // Display - } - set_D6( DISP_M_2 ); + set_D5( DISP_M_1 ); + set_D6( DISP_M_2 ); break; case 'm': set_D0( get_D1() ); @@ -197,12 +193,8 @@ void main (void) { set_D2( get_D3() ); set_D3( get_D4() ); set_D4( get_D5() ); - set_D5( get_D6() ); - set_D6( DISP_M_1 ); - for( d = 0; d < flashes ; d++ ) { - fdisp(); // Display - } - set_D6( DISP_M_2 ); + set_D5( DISP_M_1 ); + set_D6( DISP_M_2 ); break; case 'N': set_D6( DISP_n ); @@ -258,11 +250,7 @@ void main (void) { set_D2( get_D3() ); set_D3( get_D4() ); set_D4( get_D5() ); - set_D5( get_D6() ); - set_D6( DISP_M_1 ); - for( d = 0; d < flashes ; d++ ) { - fdisp(); // Display - } + set_D5( DISP_V_1 ); set_D6( DISP_V_2 ); break; case 'v': @@ -271,11 +259,7 @@ void main (void) { set_D2( get_D3() ); set_D3( get_D4() ); set_D4( get_D5() ); - set_D5( get_D6() ); - set_D6( DISP_M_1 ); - for( d = 0; d < flashes ; d++ ) { - fdisp(); // Display - } + set_D5( DISP_V_1 ); set_D6( DISP_V_2 ); break; case 'W': @@ -284,11 +268,7 @@ void main (void) { set_D2( get_D3() ); set_D3( get_D4() ); set_D4( get_D5() ); - set_D5( get_D6() ); - set_D6( DISP_M_1 ); - for( d = 0; d < flashes ; d++ ) { - fdisp(); // Display - } + set_D5( DISP_W_1 ); set_D6( DISP_W_2 ); break; case 'w': @@ -297,11 +277,7 @@ void main (void) { set_D2( get_D3() ); set_D3( get_D4() ); set_D4( get_D5() ); - set_D5( get_D6() ); - set_D6( DISP_M_1 ); - for( d = 0; d < flashes ; d++ ) { - fdisp(); // Display - } + set_D5( DISP_W_1 ); set_D6( DISP_W_2 ); break; case 'Y': @@ -382,4 +358,3 @@ void main (void) { return; } - diff --git a/samples/tutorial/sym1/symDisplay.c b/samples/tutorial/sym1/symDisplay.c index 8a72d5863..fa94ce598 100644 --- a/samples/tutorial/sym1/symDisplay.c +++ b/samples/tutorial/sym1/symDisplay.c @@ -184,12 +184,8 @@ void main (void) { set_D2( get_D3() ); set_D3( get_D4() ); set_D4( get_D5() ); - set_D5( get_D6() ); - set_D6( DISP_M_1 ); - for( d = 0; d < flashes ; d++ ) { - fdisp(); // Display - } - set_D6( DISP_M_2 ); + set_D5( DISP_M_1 ); + set_D6( DISP_M_2 ); break; case 'm': set_D0( get_D1() ); @@ -197,12 +193,8 @@ void main (void) { set_D2( get_D3() ); set_D3( get_D4() ); set_D4( get_D5() ); - set_D5( get_D6() ); - set_D6( DISP_M_1 ); - for( d = 0; d < flashes ; d++ ) { - fdisp(); // Display - } - set_D6( DISP_M_2 ); + set_D5( DISP_M_1 ); + set_D6( DISP_M_2 ); break; case 'N': set_D6( DISP_n ); @@ -258,11 +250,7 @@ void main (void) { set_D2( get_D3() ); set_D3( get_D4() ); set_D4( get_D5() ); - set_D5( get_D6() ); - set_D6( DISP_M_1 ); - for( d = 0; d < flashes ; d++ ) { - fdisp(); // Display - } + set_D5( DISP_V_1 ); set_D6( DISP_V_2 ); break; case 'v': @@ -271,11 +259,7 @@ void main (void) { set_D2( get_D3() ); set_D3( get_D4() ); set_D4( get_D5() ); - set_D5( get_D6() ); - set_D6( DISP_M_1 ); - for( d = 0; d < flashes ; d++ ) { - fdisp(); // Display - } + set_D5( DISP_V_1 ); set_D6( DISP_V_2 ); break; case 'W': @@ -284,11 +268,7 @@ void main (void) { set_D2( get_D3() ); set_D3( get_D4() ); set_D4( get_D5() ); - set_D5( get_D6() ); - set_D6( DISP_M_1 ); - for( d = 0; d < flashes ; d++ ) { - fdisp(); // Display - } + set_D5( DISP_W_1 ); set_D6( DISP_W_2 ); break; case 'w': @@ -297,11 +277,7 @@ void main (void) { set_D2( get_D3() ); set_D3( get_D4() ); set_D4( get_D5() ); - set_D5( get_D6() ); - set_D6( DISP_M_1 ); - for( d = 0; d < flashes ; d++ ) { - fdisp(); // Display - } + set_D5( DISP_W_1 ); set_D6( DISP_W_2 ); break; case 'Y': @@ -382,4 +358,3 @@ void main (void) { return; } - From ae9434e02e36cc629c76f68b5d9e18b7ddcb0dbb Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Sun, 23 May 2021 15:22:33 -0500 Subject: [PATCH 2064/2161] seven-segment display update --- include/symio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/symio.h b/include/symio.h index bd90a42f9..73b3ce18e 100644 --- a/include/symio.h +++ b/include/symio.h @@ -131,7 +131,7 @@ int __fastcall__ vsscanf (const char* s, const char* format, va_list ap); #define DISP_APOSTR 0x20 // ''' #define DISP_EQUAL 0x41 // '=' #define DISP_3_BAR 0x49 // '=' -#define DISP_BOTTOM 0x04 // '_' +#define DISP_BOTTOM 0x08 // '_' #define DISP_TOP 0x01 // Top segment #define DISP_LEFT 0x30 // '|' Left side, both segments #define DISP_RIGHT 0x06 // '|' Right side, both segments From adda9438d25212740e169443936ba3a79e2b6745 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 24 May 2021 13:53:14 +0200 Subject: [PATCH 2065/2161] testcase for issue #1357 --- test/misc/Makefile | 6 ++++++ test/misc/bug1357.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 test/misc/bug1357.c diff --git a/test/misc/Makefile b/test/misc/Makefile index b17c69f5c..c8b130ec4 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -106,6 +106,12 @@ $(WORKDIR)/bug1263.$1.$2.prg: bug1263.c | $(WORKDIR) $(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) + # 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) diff --git a/test/misc/bug1357.c b/test/misc/bug1357.c new file mode 100644 index 000000000..40415f868 --- /dev/null +++ b/test/misc/bug1357.c @@ -0,0 +1,30 @@ + +/* issue #1357 - X Macros don't work with C preprocessor */ + +#define OPCODES(X) \ + X(PUSHNIL) \ + X(PUSHTRUE) \ + X(PUSHFALSE) + +enum { +#define X(op) op, +OPCODES(X) +#undef X + N_OPS +}; + +/* cc65 -E bug1357.c -o bug1357.c.pre + should produce something like this: + +enum { +PUSHNIL, +PUSHTRUE, +PUSHFALSE, + N_OPS +}; +*/ + +int main(void) +{ + return 0; +} From ae3d3a4b5dd499406713e42254dc4b1626fd10dd Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 24 May 2021 13:53:44 +0200 Subject: [PATCH 2066/2161] make readme a bit more clear (hopefully) --- test/readme.txt | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/test/readme.txt b/test/readme.txt index 0523482fd..49ae363cc 100644 --- a/test/readme.txt +++ b/test/readme.txt @@ -1,6 +1,13 @@ This directory contains test code for automatic regression testing of the CC65 -compiler. +compiler and tools. +/asm - contains the assembler regression tests + +/dasm - contains the disassembler regression tests + + +/val, /ref and /err generally contain the tests that are used to verify that the +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. @@ -9,6 +16,9 @@ compiler. /err - contains tests that MUST NOT compile + +/todo and /misc generally contain the tests that fail because of known bugs: + /todo - These tests fail due to open compiler issues. The makefile in this directory _expects_ the tests to fail, because of @@ -16,9 +26,6 @@ compiler. moved to /val in the PR fixing the issue, which will make CI pass again. No changes to makefiles are required! -/asm - contains the assembler regression tests - -/dasm - contains the disassembler regression tests /misc - a few tests that need special care of some sort From 022935320c61ac491cf20afe887b30f1534d0117 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 24 May 2021 14:30:10 +0200 Subject: [PATCH 2067/2161] test for issue #897 --- test/val/bug897.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 test/val/bug897.c diff --git a/test/val/bug897.c b/test/val/bug897.c new file mode 100644 index 000000000..eaf751441 --- /dev/null +++ b/test/val/bug897.c @@ -0,0 +1,52 @@ + +/* issue #897 - __asm__()-referenced code-labels are generated for only branches and jumps */ + +#include <stdlib.h> +#include <stdio.h> + +static unsigned char *srcptr, *dstptr; + +#define COPY_LEN 16 + +void test(void) +{ + asm("lda %v", srcptr); + asm("sta %g+1", s2b_copy_from); + asm("lda %v+1", srcptr); + asm("sta %g+2", s2b_copy_from); + + asm("lda %v", dstptr); + asm("sta %g+1", s2b_copy_to); + asm("lda %v+1", dstptr); + asm("sta %g+2", s2b_copy_to); + + asm("ldy #%b", COPY_LEN-1); +s2b_copy_from: + asm("lda $FFFF,y"); +s2b_copy_to: + asm("sta $FFFF,y"); + asm("dey"); + asm("bpl %g", s2b_copy_from); +} + +unsigned char src[16] = "0123456789abcdef"; +unsigned char dest[16]; + +int failures = 0; + +unsigned char i; + +int main(void) +{ + srcptr = src; + dstptr = dest; + test(); + for (i = 0; i < COPY_LEN; i++) { + printf("%d %02x %02x\n", i, src[i], dest[i]); + if (src[i] != dest[i]) { + failures++; + } + } + printf("failures: %d\n", failures); + return failures; +} From 65c640d2cf1059e97e518feb3a3a348a70a95636 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 24 May 2021 15:15:07 +0200 Subject: [PATCH 2068/2161] added missing atari5200 target --- samples/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/samples/Makefile b/samples/Makefile index f1e7a1e0b..7e5c1934d 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -190,6 +190,9 @@ EXELIST_atarixl = $(EXELIST_atari) EXELIST_atari2600 = \ atari2600hello +EXELIST_atari5200 = \ + notavailable + EXELIST_atmos = \ ascii \ hello \ From 30830e1348f516626aab482b311e741428f411bc Mon Sep 17 00:00:00 2001 From: Polluks <polluks@sdf.lonestar.org> Date: Sun, 23 May 2021 10:19:00 +0200 Subject: [PATCH 2069/2161] Added missing Creativision functions --- doc/funcref.sgml | 112 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 2cb8bbf44..792a51741 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -298,6 +298,16 @@ function. </itemize> +<sect1><tt/creativision.h/<label id="creativision.h"><p> + +<itemize> +<item><ref id="bios_playsound" name="bios_playsound"> +<item><ref id="psg_delay" name="psg_delay"> +<item><ref id="psg_outb" name="psg_outb"> +<item><ref id="psg_silence" name="psg_silence"> +</itemize> + + <sect1><tt/ctype.h/<label id="ctype.h"><p> <itemize> @@ -1659,6 +1669,41 @@ used in presence of a prototype. </quote> +<sect1>bios_playsound<label id="bios_playsound"><p> + +<quote> +<descrip> +<tag/Function/Play sound sequence. +<tag/Header/<tt/<ref id="creativision.h" name="creativision.h">/ +<tag/Declaration/<tt/void __fastcall__ bios_playsound(void *a, unsigned char b);/ +<tag/Description/The function may play chords based on a BASIC statement, +note and duration are defined in the manual chapter 13 on page 102 resp. 103. +<tag/Notes/<itemize> +<item>BASIC has a fixed tempo of 18. +<item>The function is only available as fastcall function, so it may only be +used in presence of a prototype. +</itemize> +<tag/Availability/Creativision +<tag/See also/ +<ref id="psg_delay" name="psg_delay">, +<ref id="psg_outb" name="psg_outb"> +<tag/Example/ +<verb> +static const unsigned char notes[] = { + 0x77, 0x4F, 0x37, + 0x4B, 0x05, 0xBB, + 0x4F, 0x27, 0x83, + 0x93, 0x9B, 0x93, + 0x17, 0x4F, 0x96, + 0xAB, 0x17, 0x4F, + 0x0E +}; +bios_playsound (notes, sizeof notes); +</verb> +</descrip> +</quote> + + <sect1>bgcolor<label id="bgcolor"><p> <quote> @@ -5769,6 +5814,73 @@ be used in presence of a prototype. </quote> +<sect1>psg_delay<label id="psg_delay"><p> + +<quote> +<descrip> +<tag/Function/Delay for a short period of time. +<tag/Header/<tt/<ref id="creativision.h" name="creativision.h">/ +<tag/Declaration/<tt/void __fastcall__ psg_delay(unsigned char b);/ +<tag/Description/The function specifies how long each note or pause between +notes should last. +<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/Creativision +<tag/See also/ +<ref id="psg_outb" name="psg_outb">, +<ref id="psg_silence" name="psg_silence"> +<tag/Example/None. +</descrip> +</quote> + + +<sect1>psg_outb<label id="psg_outb"><p> + +<quote> +<descrip> +<tag/Function/Output a byte. +<tag/Header/<tt/<ref id="creativision.h" name="creativision.h">/ +<tag/Declaration/<tt/void __fastcall__ psg_outb(unsigned char b);/ +<tag/Description/The function will send a PSG byte and wait for acknowledge. +<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/Creativision +<tag/See also/ +<ref id="psg_delay" name="psg_delay">, +<ref id="psg_silence" name="psg_silence"> +<tag/Example/ +<verb> +psg_outb (0x80); // Latch frequency +psg_outb (0x07); // Frequency byte 2 +psg_outb (0x90); // Channel 0 full volume +</verb> +</descrip> +</quote> + + +<sect1>psg_silence<label id="psg_silence"><p> + +<quote> +<descrip> +<tag/Function/Set volume off on each channel. +<tag/Header/<tt/<ref id="creativision.h" name="creativision.h">/ +<tag/Declaration/<tt/void psg_silence(void);/ +<tag/Description/The function sends $9F, $BF, $DF, $FF to the PSG. +<tag/Notes/<itemize> +</itemize> +<tag/Availability/Creativision +<tag/See also/ +<ref id="psg_delay" name="psg_delay">, +<ref id="psg_outb" name="psg_outb"> +<tag/Example/None. +</descrip> +</quote> + + <sect1>qsort<label id="qsort"><p> <quote> From 010eea12a2fe03d6fd41aca307076aed8d1299c0 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 25 May 2021 13:38:06 +0200 Subject: [PATCH 2070/2161] move test for issue #1211 into misc --- test/misc/Makefile | 6 ++++++ test/{err => misc}/bug1211-ice-move-refs-2.c | 0 2 files changed, 6 insertions(+) rename test/{err => misc}/bug1211-ice-move-refs-2.c (100%) diff --git a/test/misc/Makefile b/test/misc/Makefile index c8b130ec4..e6c58c5a4 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -112,6 +112,12 @@ $(WORKDIR)/bug1357.$1.$2.prg: bug1357.c | $(WORKDIR) $(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." + $(if $(QUIET),echo misc/bug1211-ice-move-refs-2.$1.$2.prg) + $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + # 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) diff --git a/test/err/bug1211-ice-move-refs-2.c b/test/misc/bug1211-ice-move-refs-2.c similarity index 100% rename from test/err/bug1211-ice-move-refs-2.c rename to test/misc/bug1211-ice-move-refs-2.c From 6bedade593e2b34fae4f86e11579ca92d18d00f6 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 29 May 2021 08:37:38 -0400 Subject: [PATCH 2071/2161] Fixed the creativision function prototypes. Added const to a pointer parameter. --- include/creativision.h | 8 ++++---- libsrc/creativision/psg.s | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/creativision.h b/include/creativision.h index 40b9ee03a..6910ee0cf 100644 --- a/include/creativision.h +++ b/include/creativision.h @@ -70,9 +70,9 @@ #define COLOR_WHITE 15 /* Protos */ -void __fastcall__ psg_outb(unsigned char b); -void __fastcall__ psg_delay(unsigned char b); -void psg_silence(void); -void __fastcall__ bios_playsound(void *a, unsigned char b); +void __fastcall__ psg_outb (unsigned char b); +void __fastcall__ psg_delay (unsigned char b); +void psg_silence (void); +void __fastcall__ bios_playsound (const void *a, unsigned char b); #endif /* #ifndef _CVISION_H */ diff --git a/libsrc/creativision/psg.s b/libsrc/creativision/psg.s index a32e87f02..18f4ffe2e 100644 --- a/libsrc/creativision/psg.s +++ b/libsrc/creativision/psg.s @@ -1,7 +1,7 @@ -; void __fastcall__ psg_outb( unsigned char b ); -; void __fastcall__ psg_delayms( unsigned char c); -; void __fastcall__ bios_playsound( void *b, unsigned char c); -; void psg_silence( void ); +; void __fastcall__ psg_outb (unsigned char b); +; void __fastcall__ psg_delay (unsigned char c); +; void __fastcall__ bios_playsound (const void *b, unsigned char c); +; void psg_silence (void); .export _psg_outb, _psg_silence, _psg_delay .export _bios_playsound From c0f29993e06c1fbe81f7367e8445f51db05d5fc9 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 29 May 2021 08:53:13 -0400 Subject: [PATCH 2072/2161] Fixed the descriptions of the Creativision's functions. Fixed bios_playsound()'s position in the alphabetical list of functions. --- doc/funcref.sgml | 112 ++++++++++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 51 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 792a51741..28faa068a 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -1669,41 +1669,6 @@ used in presence of a prototype. </quote> -<sect1>bios_playsound<label id="bios_playsound"><p> - -<quote> -<descrip> -<tag/Function/Play sound sequence. -<tag/Header/<tt/<ref id="creativision.h" name="creativision.h">/ -<tag/Declaration/<tt/void __fastcall__ bios_playsound(void *a, unsigned char b);/ -<tag/Description/The function may play chords based on a BASIC statement, -note and duration are defined in the manual chapter 13 on page 102 resp. 103. -<tag/Notes/<itemize> -<item>BASIC has a fixed tempo of 18. -<item>The function is only available as fastcall function, so it may only be -used in presence of a prototype. -</itemize> -<tag/Availability/Creativision -<tag/See also/ -<ref id="psg_delay" name="psg_delay">, -<ref id="psg_outb" name="psg_outb"> -<tag/Example/ -<verb> -static const unsigned char notes[] = { - 0x77, 0x4F, 0x37, - 0x4B, 0x05, 0xBB, - 0x4F, 0x27, 0x83, - 0x93, 0x9B, 0x93, - 0x17, 0x4F, 0x96, - 0xAB, 0x17, 0x4F, - 0x0E -}; -bios_playsound (notes, sizeof notes); -</verb> -</descrip> -</quote> - - <sect1>bgcolor<label id="bgcolor"><p> <quote> @@ -1729,6 +1694,44 @@ used in presence of a prototype. </quote> +<sect1>bios_playsound<label id="bios_playsound"><p> + +<quote> +<descrip> +<tag/Function/Play a sequence of musical notes. +<tag/Header/<tt/<ref id="creativision.h" name="creativision.h">/ +<tag/Declaration/<tt/void __fastcall__ bios_playsound (const void *a, unsigned char b);/ +<tag/Description/The function plays chords based on a BASIC statement. Notes and +durations are defined in the BASIC manual, chapter 13 on pages 102 resp. 103. +<tag/Notes/<itemize> +<item>BASIC has a fixed tempo of 18. +<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/ +<ref id="psg_delay" name="psg_delay">, +<ref id="psg_outb" name="psg_outb"> +<tag/Example/<verb> +#include <creativision.h> +void main (void) +{ + static const unsigned char notes[] = { + 0x77, 0x4F, 0x37, + 0x4B, 0x05, 0xBB, + 0x4F, 0x27, 0x83, + 0x93, 0x9B, 0x93, + 0x17, 0x4F, 0x96, // played backwards + 0xAB, 0x17, 0x4F, // three-note chords + 0x0E // tempo + }; + bios_playsound (notes, sizeof notes); +} +</verb> +</descrip> +</quote> + + <sect1>bordercolor<label id="bordercolor"><p> <quote> @@ -1823,7 +1826,7 @@ be used in presence of a prototype. <item>The function is specific to the C128. <item>The function will not return to the caller. </itemize> -<tag/Availability/C128 +<tag/Availability/cc65 <tag/Example/None. </descrip> </quote> @@ -5820,14 +5823,14 @@ be used in presence of a prototype. <descrip> <tag/Function/Delay for a short period of time. <tag/Header/<tt/<ref id="creativision.h" name="creativision.h">/ -<tag/Declaration/<tt/void __fastcall__ psg_delay(unsigned char b);/ +<tag/Declaration/<tt/void __fastcall__ psg_delay (unsigned char b);/ <tag/Description/The function specifies how long each note or pause between notes should last. <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/Creativision +<tag/Availability/cc65 <tag/See also/ <ref id="psg_outb" name="psg_outb">, <ref id="psg_silence" name="psg_silence"> @@ -5840,23 +5843,29 @@ used in presence of a prototype. <quote> <descrip> -<tag/Function/Output a byte. +<tag/Function/Output a byte to the PSG. <tag/Header/<tt/<ref id="creativision.h" name="creativision.h">/ -<tag/Declaration/<tt/void __fastcall__ psg_outb(unsigned char b);/ -<tag/Description/The function will send a PSG byte and wait for acknowledge. +<tag/Declaration/<tt/void __fastcall__ psg_outb (unsigned char b);/ +<tag/Description/The function sends a byte to the Programmable Sound +Generator, then waits for the PSG to acknowledge. <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/Creativision +<tag/Availability/cc65 <tag/See also/ <ref id="psg_delay" name="psg_delay">, <ref id="psg_silence" name="psg_silence"> -<tag/Example/ -<verb> -psg_outb (0x80); // Latch frequency -psg_outb (0x07); // Frequency byte 2 -psg_outb (0x90); // Channel 0 full volume +<tag/Example/<verb> +#include <creativision.h> +void main (void) +{ + psg_outb (0x80); // Latch frequency + psg_outb (0x07); // Frequency byte 2 + psg_outb (0x90); // Channel 0 full volume + psg_delay (100); + psg_silence (); +} </verb> </descrip> </quote> @@ -5866,13 +5875,14 @@ psg_outb (0x90); // Channel 0 full volume <quote> <descrip> -<tag/Function/Set volume off on each channel. +<tag/Function/Set volume off on each PSG channel. <tag/Header/<tt/<ref id="creativision.h" name="creativision.h">/ -<tag/Declaration/<tt/void psg_silence(void);/ -<tag/Description/The function sends $9F, $BF, $DF, $FF to the PSG. +<tag/Declaration/<tt/void psg_silence (void);/ +<tag/Description/The function resets the Programmable Sound Generator, +then sends $9F, $BF, $DF, $FF to the PSG. <tag/Notes/<itemize> </itemize> -<tag/Availability/Creativision +<tag/Availability/cc65 <tag/See also/ <ref id="psg_delay" name="psg_delay">, <ref id="psg_outb" name="psg_outb"> From ee5014c5952cb0a50f0e870911941694fee291d6 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 29 May 2021 09:04:47 -0400 Subject: [PATCH 2073/2161] Simplified the Supervision "hello world" sample program. --- samples/supervisionhello.c | 134 +++++++++++++++++++------------------ 1 file changed, 69 insertions(+), 65 deletions(-) diff --git a/samples/supervisionhello.c b/samples/supervisionhello.c index db2b5f66c..ed03e82f3 100644 --- a/samples/supervisionhello.c +++ b/samples/supervisionhello.c @@ -3,89 +3,93 @@ /* Watara Supervision sample C program */ /* */ /* Fabrizio Caruso (fabrizio_caruso@hotmail.com), 2019 */ +/* Greg King (greg.king5@verizon.net), 2021 */ /* */ /*****************************************************************************/ #include <supervision.h> -#include <peekpoke.h> +#include <string.h> -// Number of bytes per screen line (Remark: Last 8 bytes are not displayed) -#define BYTES_PER_LINE 48 +/* Number of words per screen line (Remark: Last 4 words aren't displayed) */ +#define WORDS_PER_LINE (160/8+4) -// Character definitions in 8x8 format -const unsigned char h_char[] = {0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}; -const unsigned char e_char[] = {0x7E,0x60,0x60,0x78,0x60,0x60,0x7E,0x00}; -const unsigned char l_char[] = {0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00}; -const unsigned char o_char[] = {0x3C,0x66,0x66,0x66,0x66,0x66,0x3C,0x00}; -const unsigned char w_char[] = {0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00}; -const unsigned char r_char[] = {0x7C,0x66,0x66,0x7C,0x78,0x6C,0x66,0x00}; -const unsigned char d_char[] = {0x78,0x6C,0x66,0x66,0x66,0x6C,0x78,0x00}; +struct sv_vram { + unsigned int v[160/8][8][WORDS_PER_LINE]; +}; +#define SV_VRAM ((*(struct sv_vram *)0x4000).v) -void clear_screen(void) +/* Character definitions in 8x8 format */ +/* That format gives us a screen of 20 columns and 20 rows */ +static const unsigned char h_char[] = {0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}; +static const unsigned char e_char[] = {0x7E,0x60,0x60,0x78,0x60,0x60,0x7E,0x00}; +static const unsigned char l_char[] = {0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00}; +static const unsigned char o_char[] = {0x3C,0x66,0x66,0x66,0x66,0x66,0x3C,0x00}; +static const unsigned char w_char[] = {0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00}; +static const unsigned char r_char[] = {0x7C,0x66,0x66,0x7C,0x78,0x6C,0x66,0x00}; +static const unsigned char d_char[] = {0x78,0x6C,0x66,0x66,0x66,0x6C,0x78,0x00}; + +static void clear_screen(void) { - unsigned short i; - - for(i=0;i<0x2000;++i) + memset(SV_VIDEO, 0, 0x2000); +} + +/* Necessary conversion to have 2 bits per pixel with darkest hue */ +/* Remark: The Supervision uses 2 bits per pixel, and bits are mapped into pixels in reversed order */ +static unsigned int __fastcall__ double_reversed_bits(unsigned char) +{ + __asm__("stz ptr2"); + __asm__("stz ptr2+1"); + __asm__("ldy #$08"); +L1: __asm__("lsr a"); + __asm__("php"); + __asm__("rol ptr2"); + __asm__("rol ptr2+1"); + __asm__("plp"); + __asm__("rol ptr2"); + __asm__("rol ptr2+1"); + __asm__("dey"); + __asm__("bne %g", L1); + __asm__("lda ptr2"); + __asm__("ldx ptr2+1"); + return __AX__; +} + +static void display_char(const unsigned char x, const unsigned char y, const unsigned char *ch) +{ + unsigned char k; + + for(k=0;k<8;++k) { - POKE(SV_VIDEO+i,0); + SV_VRAM[y][k][x] = double_reversed_bits(ch[k]); } } -// Necessary conversion to have 2 bits per pixel with darkest hue -// Remark: The Supervision uses 2 bits per pixel and bits are mapped into pixel in reversed order -unsigned char reversed_map_one_to_two_lookup[16] = -{ - 0x00, 0xC0, 0x30, 0xF0, 0x0C, 0xCC, 0x3C, 0xFC, - 0x03, 0xC3, 0x33, 0xF3, 0x0F, 0xCF, 0x3F, 0xFF -}; - -unsigned char left_map_one_to_two(unsigned char n) -{ - return reversed_map_one_to_two_lookup[n >> 4]; -} - -unsigned char right_map_one_to_two(unsigned char n) -{ - return reversed_map_one_to_two_lookup[n&0x0F]; -} - -void display_char(const unsigned char x, const unsigned char y, const unsigned char *ch) -{ - unsigned char k; - - for(k=0;k<8;++k) - { \ - SV_VIDEO[2*(y)+BYTES_PER_LINE*k+BYTES_PER_LINE*(x<<3)] = left_map_one_to_two(ch[k]); - SV_VIDEO[2*(y)+BYTES_PER_LINE*k+BYTES_PER_LINE*(x<<3)+1] = right_map_one_to_two(ch[k]); - } -} - -void init_lcd(void) +static void init_lcd(void) { SV_LCD.width = 160; SV_LCD.height = 160; } -int main() -{ - init_lcd(); - clear_screen(); - - display_char(3,2, h_char); - display_char(3,3, e_char); - display_char(3,4, l_char); - display_char(3,5, l_char); - display_char(3,6, o_char); - - display_char(3,8, w_char); - display_char(3,9, o_char); - display_char(3,10,r_char); - display_char(3,11,l_char); - display_char(3,12,d_char); +static void hello(unsigned char x, unsigned char y) +{ + display_char(x+ 0,y,h_char); + display_char(x+ 1,y,e_char); + display_char(x+ 2,y,l_char); + display_char(x+ 3,y,l_char); + display_char(x+ 4,y,o_char); - while(1) {}; - - return 0; + display_char(x+ 6,y,w_char); + display_char(x+ 7,y,o_char); + display_char(x+ 8,y,r_char); + display_char(x+ 9,y,l_char); + display_char(x+10,y,d_char); } +void main(void) +{ + init_lcd(); + clear_screen(); + hello(2,3); + hello(7,16); +} From 0d3c827d803c573c9aa4a361658665a912e27402 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 30 May 2021 03:51:11 -0400 Subject: [PATCH 2074/2161] Made the C preprocessor #if nesting stack have 256 levels. Closes #1523. --- src/cc65/preproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index 37073e784..a607e3217 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -71,7 +71,7 @@ unsigned char Preprocessing = 0; /* Management data for #if */ -#define MAX_IFS 64 +#define MAX_IFS 256 #define IFCOND_NONE 0x00U #define IFCOND_SKIP 0x01U #define IFCOND_ELSE 0x02U From fe003eedd4e3554ec12ad4a234ce885f96e39c99 Mon Sep 17 00:00:00 2001 From: IrgendwerA8 <c.krueger.b@web.de> Date: Mon, 31 May 2021 00:24:46 +0200 Subject: [PATCH 2075/2161] Fix Atari keyboard code for cursor up key --- asminc/atari.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asminc/atari.inc b/asminc/atari.inc index 7c46b3252..c2a210ea0 100644 --- a/asminc/atari.inc +++ b/asminc/atari.inc @@ -924,7 +924,7 @@ KEY_QUESTIONMARK = KEY_SLASH | KEY_SHIFT KEY_CLEAR = KEY_LESSTHAN | KEY_SHIFT KEY_INSERT = KEY_GREATERTHAN | KEY_SHIFT -KEY_UP = KEY_UNDERLINE | KEY_CTRL +KEY_UP = KEY_DASH | KEY_CTRL KEY_DOWN = KEY_EQUALS | KEY_CTRL KEY_LEFT = KEY_PLUS | KEY_CTRL KEY_RIGHT = KEY_ASTERISK | KEY_CTRL From 0bfa13722bb72d8e8f99606f3ecddeedf360149c Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 18 Sep 2020 20:23:02 +0800 Subject: [PATCH 2076/2161] More funcinfo on register usage fixes. --- src/cc65/codeent.c | 4 + src/cc65/codeinfo.c | 586 ++++++++++++++++++++++------------------- src/cc65/codeinfo.h | 3 + src/cc65/codeoptutil.c | 105 +++++--- 4 files changed, 386 insertions(+), 312 deletions(-) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index dd2000db0..4f257a22e 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -172,6 +172,10 @@ static void SetUseChgInfo (CodeEntry* E, const OPCDesc* D) if (Info && Info->ByteUse != REG_NONE) { /* These addressing modes will never change the zp loc */ E->Use |= Info->WordUse; + + if ((E->Use & REG_SP) != 0) { + E->Use |= SLV_IND; + } } break; diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 46a7d76c6..88f8a5138 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -82,269 +82,296 @@ struct FuncInfo { unsigned Chg; /* Changed/destroyed registers */ }; -/* Note for the shift functions: Shifts are done modulo 32, so all shift +/* Functions that change the SP are regarded as using the SP as well. +** The callax/jmpvec functions may call a function that uses/changes more +** registers, so we should further check the info of the called function +** or just play it safe. +** Note for the shift functions: Shifts are done modulo 32, so all shift ** routines are marked to use only the A register. The remainder is ignored ** anyway. */ static const FuncInfo FuncInfoTable[] = { - { "addeq0sp", REG_AX, PSTATE_ALL | REG_AXY }, - { "addeqysp", REG_AXY, PSTATE_ALL | REG_AXY }, - { "addysp", REG_Y, PSTATE_ALL | REG_NONE }, - { "aslax1", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, - { "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 }, - { "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 }, - { "asleax3", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, - { "asleax4", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "asrax1", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, - { "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 }, - { "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 }, - { "asreax3", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, - { "asreax4", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "bcasta", REG_A, PSTATE_ALL | REG_AX }, - { "bcastax", REG_AX, PSTATE_ALL | REG_AX }, - { "bcasteax", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, - { "bnega", REG_A, PSTATE_ALL | REG_AX }, - { "bnegax", REG_AX, PSTATE_ALL | REG_AX }, - { "bnegeax", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, - { "booleq", PSTATE_Z, PSTATE_ALL | REG_AX }, - { "boolge", PSTATE_N, PSTATE_ALL | REG_AX }, - { "boolgt", PSTATE_ZN, PSTATE_ALL | REG_AX }, - { "boolle", PSTATE_ZN, PSTATE_ALL | REG_AX }, - { "boollt", PSTATE_N, PSTATE_ALL | REG_AX }, - { "boolne", PSTATE_Z, PSTATE_ALL | REG_AX }, - { "booluge", PSTATE_C, PSTATE_ALL | REG_AX }, - { "boolugt", PSTATE_CZ, PSTATE_ALL | REG_AX }, - { "boolule", PSTATE_CZ, PSTATE_ALL | REG_AX }, - { "boolult", PSTATE_C, PSTATE_ALL | REG_AX }, - { "callax", REG_AX, PSTATE_ALL | REG_ALL }, - { "complax", REG_AX, PSTATE_ALL | REG_AX }, - { "decax1", REG_AX, PSTATE_ALL | REG_AX }, - { "decax2", REG_AX, PSTATE_ALL | REG_AX }, - { "decax3", REG_AX, PSTATE_ALL | REG_AX }, - { "decax4", REG_AX, PSTATE_ALL | REG_AX }, - { "decax5", REG_AX, PSTATE_ALL | REG_AX }, - { "decax6", REG_AX, PSTATE_ALL | REG_AX }, - { "decax7", REG_AX, PSTATE_ALL | REG_AX }, - { "decax8", REG_AX, PSTATE_ALL | REG_AX }, - { "decaxy", REG_AXY, PSTATE_ALL | REG_AX | REG_TMP1 }, - { "deceaxy", REG_EAXY, PSTATE_ALL | REG_EAX }, - { "decsp1", REG_NONE, PSTATE_ALL | REG_Y }, - { "decsp2", REG_NONE, PSTATE_ALL | REG_A }, - { "decsp3", REG_NONE, PSTATE_ALL | REG_A }, - { "decsp4", REG_NONE, PSTATE_ALL | REG_A }, - { "decsp5", REG_NONE, PSTATE_ALL | REG_A }, - { "decsp6", REG_NONE, PSTATE_ALL | REG_A }, - { "decsp7", REG_NONE, PSTATE_ALL | REG_A }, - { "decsp8", REG_NONE, PSTATE_ALL | REG_A }, - { "incax1", REG_AX, PSTATE_ALL | REG_AX }, - { "incax2", REG_AX, PSTATE_ALL | REG_AX }, - { "incax3", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "incax4", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "incax5", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "incax6", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "incax7", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "incax8", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "incaxy", REG_AXY, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "incsp1", REG_NONE, PSTATE_ALL | REG_NONE }, - { "incsp2", REG_NONE, PSTATE_ALL | REG_Y }, - { "incsp3", REG_NONE, PSTATE_ALL | REG_Y }, - { "incsp4", REG_NONE, PSTATE_ALL | REG_Y }, - { "incsp5", REG_NONE, PSTATE_ALL | REG_Y }, - { "incsp6", REG_NONE, PSTATE_ALL | REG_Y }, - { "incsp7", REG_NONE, PSTATE_ALL | REG_Y }, - { "incsp8", REG_NONE, PSTATE_ALL | REG_Y }, - { "laddeq", REG_EAXY|REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI }, - { "laddeq0sp", REG_EAX, PSTATE_ALL | REG_EAXY }, - { "laddeq1", REG_Y | REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI }, - { "laddeqa", REG_AY | REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI }, - { "laddeqysp", REG_EAXY, PSTATE_ALL | REG_EAXY }, - { "ldaidx", REG_AXY, PSTATE_ALL | REG_AX | REG_PTR1 }, - { "ldauidx", REG_AXY, PSTATE_ALL | REG_AX | REG_PTR1 }, - { "ldax0sp", REG_NONE, PSTATE_ALL | REG_AXY }, - { "ldaxi", REG_AX, PSTATE_ALL | REG_AXY | REG_PTR1 }, - { "ldaxidx", REG_AXY, PSTATE_ALL | REG_AXY | REG_PTR1 }, - { "ldaxysp", REG_Y, PSTATE_ALL | REG_AXY }, - { "ldeax0sp", REG_NONE, PSTATE_ALL | REG_EAXY }, - { "ldeaxi", REG_AX, PSTATE_ALL | REG_EAXY | REG_PTR1 }, - { "ldeaxidx", REG_AXY, PSTATE_ALL | REG_EAXY | REG_PTR1 }, - { "ldeaxysp", REG_Y, PSTATE_ALL | REG_EAXY }, - { "leaa0sp", REG_A, PSTATE_ALL | REG_AX }, - { "leaaxsp", REG_AX, PSTATE_ALL | REG_AX }, - { "lsubeq", REG_EAXY|REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI }, - { "lsubeq0sp", REG_EAX, PSTATE_ALL | REG_EAXY }, - { "lsubeq1", REG_Y | REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI }, - { "lsubeqa", REG_AY | REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI }, - { "lsubeqysp", REG_EAXY, PSTATE_ALL | REG_EAXY }, - { "mulax10", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, - { "mulax3", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, - { "mulax5", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, - { "mulax6", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, - { "mulax7", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, - { "mulax9", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, - { "negax", REG_AX, PSTATE_ALL | REG_AX }, - { "push0", REG_NONE, PSTATE_ALL | REG_AXY }, - { "push0ax", REG_AX, PSTATE_ALL | REG_Y | REG_SREG }, - { "push1", REG_NONE, PSTATE_ALL | REG_AXY }, - { "push2", REG_NONE, PSTATE_ALL | REG_AXY }, - { "push3", REG_NONE, PSTATE_ALL | REG_AXY }, - { "push4", REG_NONE, PSTATE_ALL | REG_AXY }, - { "push5", REG_NONE, PSTATE_ALL | REG_AXY }, - { "push6", REG_NONE, PSTATE_ALL | REG_AXY }, - { "push7", REG_NONE, PSTATE_ALL | REG_AXY }, - { "pusha", REG_A, PSTATE_ALL | REG_Y }, - { "pusha0", REG_A, PSTATE_ALL | REG_XY }, - { "pusha0sp", REG_NONE, PSTATE_ALL | REG_AY }, - { "pushaFF", REG_A, PSTATE_ALL | REG_Y }, - { "pushax", REG_AX, PSTATE_ALL | REG_Y }, - { "pushaysp", REG_Y, PSTATE_ALL | REG_AY }, - { "pushc0", REG_NONE, PSTATE_ALL | REG_A | REG_Y }, - { "pushc1", REG_NONE, PSTATE_ALL | REG_A | REG_Y }, - { "pushc2", REG_NONE, PSTATE_ALL | REG_A | REG_Y }, - { "pusheax", REG_EAX, PSTATE_ALL | REG_Y }, - { "pushl0", REG_NONE, PSTATE_ALL | REG_AXY }, - { "pushw", REG_AX, PSTATE_ALL | REG_AXY | REG_PTR1 }, - { "pushw0sp", REG_NONE, PSTATE_ALL | REG_AXY }, - { "pushwidx", REG_AXY, PSTATE_ALL | REG_AXY | REG_PTR1 }, - { "pushwysp", REG_Y, PSTATE_ALL | REG_AXY }, - { "regswap", REG_AXY, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "regswap1", REG_XY, PSTATE_ALL | REG_A }, - { "regswap2", REG_XY, PSTATE_ALL | REG_A | REG_Y }, - { "return0", REG_NONE, PSTATE_ALL | REG_AX }, - { "return1", REG_NONE, PSTATE_ALL | REG_AX }, - { "shlax1", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, - { "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 }, - { "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 }, - { "shleax3", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, - { "shleax4", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "shrax1", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, - { "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 }, - { "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 }, - { "shreax3", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, - { "shreax4", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "staspidx", REG_A | REG_Y, PSTATE_ALL | REG_Y | REG_TMP1 | REG_PTR1 }, - { "stax0sp", REG_AX, PSTATE_ALL | REG_Y }, - { "staxspidx", REG_AXY, PSTATE_ALL | REG_TMP1 | REG_PTR1 }, - { "staxysp", REG_AXY, PSTATE_ALL | REG_Y }, - { "steax0sp", REG_EAX, PSTATE_ALL | REG_Y }, - { "steaxysp", REG_EAXY, PSTATE_ALL | REG_Y }, - { "subeq0sp", REG_AX, PSTATE_ALL | REG_AXY }, - { "subeqysp", REG_AXY, PSTATE_ALL | REG_AXY }, - { "subysp", REG_Y, PSTATE_ALL | REG_AY }, - { "tosadd0ax", REG_AX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "tosadda0", REG_A, PSTATE_ALL | REG_AXY }, - { "tosaddax", REG_AX, PSTATE_ALL | REG_AXY }, - { "tosaddeax", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "tosand0ax", REG_AX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "tosanda0", REG_A, PSTATE_ALL | REG_AXY }, - { "tosandax", REG_AX, PSTATE_ALL | REG_AXY }, - { "tosandeax", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "tosaslax", REG_A, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "tosasleax", REG_A, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "tosasrax", REG_A, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "tosasreax", REG_A, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "tosdiv0ax", REG_AX, PSTATE_ALL | REG_ALL }, - { "tosdiva0", REG_A, PSTATE_ALL | REG_ALL }, - { "tosdivax", REG_AX, PSTATE_ALL | REG_ALL }, - { "tosdiveax", REG_EAX, PSTATE_ALL | REG_ALL }, - { "toseq00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, - { "toseqa0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, - { "toseqax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, - { "toseqeax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, - { "tosge00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosgea0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosgeax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosgeeax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, - { "tosgt00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosgta0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosgtax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosgteax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, - { "tosicmp", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosicmp0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, - { "toslcmp", REG_EAX, PSTATE_ALL | REG_A | REG_Y | REG_PTR1 }, - { "tosle00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, - { "toslea0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosleax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosleeax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, - { "toslt00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, - { "toslta0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosltax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, - { "toslteax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, - { "tosmod0ax", REG_AX, PSTATE_ALL | REG_ALL }, - { "tosmodeax", REG_EAX, PSTATE_ALL | REG_ALL }, - { "tosmul0ax", REG_AX, PSTATE_ALL | REG_ALL }, - { "tosmula0", REG_A, PSTATE_ALL | REG_ALL }, - { "tosmulax", REG_AX, PSTATE_ALL | REG_ALL }, - { "tosmuleax", REG_EAX, PSTATE_ALL | REG_ALL }, - { "tosne00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosnea0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosneax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosneeax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, - { "tosor0ax", REG_AX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "tosora0", REG_A, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "tosorax", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "tosoreax", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "tosrsub0ax", REG_AX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "tosrsuba0", REG_A, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "tosrsubax", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "tosrsubeax", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "tosshlax", REG_A, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "tosshleax", REG_A, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "tosshrax", REG_A, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "tosshreax", REG_A, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "tossub0ax", REG_AX, PSTATE_ALL | REG_EAXY }, - { "tossuba0", REG_A, PSTATE_ALL | REG_AXY }, - { "tossubax", REG_AX, PSTATE_ALL | REG_AXY }, - { "tossubeax", REG_EAX, PSTATE_ALL | REG_EAXY }, - { "tosudiv0ax", REG_AX, PSTATE_ALL | (REG_ALL & ~REG_SAVE) }, - { "tosudiva0", REG_A, PSTATE_ALL | REG_EAXY | REG_PTR1 }, /* also ptr4 */ - { "tosudivax", REG_AX, PSTATE_ALL | REG_EAXY | REG_PTR1 }, /* also ptr4 */ - { "tosudiveax", REG_EAX, PSTATE_ALL | (REG_ALL & ~REG_SAVE) }, - { "tosuge00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosugea0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosugeax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosugeeax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, - { "tosugt00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosugta0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosugtax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosugteax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, - { "tosule00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosulea0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosuleax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosuleeax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, - { "tosult00", REG_NONE, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosulta0", REG_A, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosultax", REG_AX, PSTATE_ALL | REG_AXY | REG_SREG }, - { "tosulteax", REG_EAX, PSTATE_ALL | REG_AXY | REG_PTR1 }, - { "tosumod0ax", REG_AX, PSTATE_ALL | (REG_ALL & ~REG_SAVE) }, - { "tosumoda0", REG_A, PSTATE_ALL | REG_EAXY | REG_PTR1 }, /* also ptr4 */ - { "tosumodax", REG_AX, PSTATE_ALL | REG_EAXY | REG_PTR1 }, /* also ptr4 */ - { "tosumodeax", REG_EAX, PSTATE_ALL | (REG_ALL & ~REG_SAVE) }, - { "tosumul0ax", REG_AX, PSTATE_ALL | REG_ALL }, - { "tosumula0", REG_A, PSTATE_ALL | REG_ALL }, - { "tosumulax", REG_AX, PSTATE_ALL | REG_ALL }, - { "tosumuleax", REG_EAX, PSTATE_ALL | REG_ALL }, - { "tosxor0ax", REG_AX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "tosxora0", REG_A, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "tosxorax", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, - { "tosxoreax", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, - { "tsteax", REG_EAX, PSTATE_ALL | REG_Y }, - { "utsteax", REG_EAX, PSTATE_ALL | REG_Y }, + { "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 }, + { "along", REG_A, PSTATE_ALL | REG_X | REG_SREG }, + { "aslax1", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, + { "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 }, + { "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 }, + { "asleax3", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, + { "asleax4", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "asrax1", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, + { "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 }, + { "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 }, + { "asreax3", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, + { "asreax4", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "aulong", REG_NONE, PSTATE_ALL | REG_X | REG_SREG }, + { "axlong", REG_X, PSTATE_ALL | REG_Y | REG_SREG }, + { "axulong", REG_NONE, PSTATE_ALL | REG_Y | REG_SREG }, + { "bcasta", REG_A, PSTATE_ALL | REG_AX }, + { "bcastax", REG_AX, PSTATE_ALL | REG_AX }, + { "bcasteax", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, + { "bnega", REG_A, PSTATE_ALL | REG_AX }, + { "bnegax", REG_AX, PSTATE_ALL | REG_AX }, + { "bnegeax", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, + { "booleq", PSTATE_Z, PSTATE_ALL | REG_AX }, + { "boolge", PSTATE_N, PSTATE_ALL | REG_AX }, + { "boolgt", PSTATE_ZN, PSTATE_ALL | REG_AX }, + { "boolle", PSTATE_ZN, PSTATE_ALL | REG_AX }, + { "boollt", PSTATE_N, PSTATE_ALL | REG_AX }, + { "boolne", PSTATE_Z, PSTATE_ALL | REG_AX }, + { "booluge", PSTATE_C, PSTATE_ALL | REG_AX }, + { "boolugt", PSTATE_CZ, PSTATE_ALL | REG_AX }, + { "boolule", PSTATE_CZ, PSTATE_ALL | REG_AX }, + { "boolult", PSTATE_C, PSTATE_ALL | REG_AX }, + { "callax", REG_AX, PSTATE_ALL | REG_ALL }, /* PSTATE_ZN | REG_PTR1 */ + { "complax", REG_AX, PSTATE_ALL | REG_AX }, + { "decax1", REG_AX, PSTATE_ALL | REG_AX }, + { "decax2", REG_AX, PSTATE_ALL | REG_AX }, + { "decax3", REG_AX, PSTATE_ALL | REG_AX }, + { "decax4", REG_AX, PSTATE_ALL | REG_AX }, + { "decax5", REG_AX, PSTATE_ALL | REG_AX }, + { "decax6", REG_AX, PSTATE_ALL | REG_AX }, + { "decax7", REG_AX, PSTATE_ALL | REG_AX }, + { "decax8", REG_AX, PSTATE_ALL | REG_AX }, + { "decaxy", REG_AXY, PSTATE_ALL | REG_AX | REG_TMP1 }, + { "deceaxy", REG_EAXY, PSTATE_ALL | REG_EAX }, + { "decsp1", REG_SP, PSTATE_ALL | REG_SP | REG_Y }, + { "decsp2", REG_SP, PSTATE_ALL | REG_SP | REG_A }, + { "decsp3", REG_SP, PSTATE_ALL | REG_SP | REG_A }, + { "decsp4", REG_SP, PSTATE_ALL | REG_SP | REG_A }, + { "decsp5", REG_SP, PSTATE_ALL | REG_SP | REG_A }, + { "decsp6", REG_SP, PSTATE_ALL | REG_SP | REG_A }, + { "decsp7", REG_SP, PSTATE_ALL | REG_SP | REG_A }, + { "decsp8", REG_SP, PSTATE_ALL | REG_SP | REG_A }, + { "enter", REG_SP | REG_Y, PSTATE_ALL | REG_SP | REG_AY }, + { "incax1", REG_AX, PSTATE_ALL | REG_AX }, + { "incax2", REG_AX, PSTATE_ALL | REG_AX }, + { "incax3", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "incax4", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "incax5", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "incax6", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "incax7", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "incax8", REG_AX, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "incaxy", REG_AXY, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "incsp1", REG_SP, PSTATE_ALL | REG_SP }, + { "incsp2", REG_SP, PSTATE_ALL | REG_SP | REG_Y }, + { "incsp3", REG_SP, PSTATE_ALL | REG_SP | REG_Y }, + { "incsp4", REG_SP, PSTATE_ALL | REG_SP | REG_Y }, + { "incsp5", REG_SP, PSTATE_ALL | REG_SP | REG_Y }, + { "incsp6", REG_SP, PSTATE_ALL | REG_SP | REG_Y }, + { "incsp7", REG_SP, PSTATE_ALL | REG_SP | REG_Y }, + { "incsp8", REG_SP, PSTATE_ALL | REG_SP | REG_Y }, + { "jmpvec", REG_EVERYTHING, PSTATE_ALL | REG_ALL }, /* NONE */ + { "laddeq", REG_EAXY | REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI }, + { "laddeq0sp", SLV_TOP | REG_EAX, PSTATE_ALL | REG_EAXY }, + { "laddeq1", REG_Y | REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI }, + { "laddeqa", REG_AY | REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI }, + { "laddeqysp", SLV_IND | REG_EAXY, PSTATE_ALL | REG_EAXY }, + { "ldaidx", REG_AXY, PSTATE_ALL | REG_AX | REG_PTR1 }, + { "ldauidx", REG_AXY, PSTATE_ALL | REG_AX | REG_PTR1 }, + { "ldax0sp", SLV_TOP, PSTATE_ALL | REG_AXY }, + { "ldaxi", REG_AX, PSTATE_ALL | REG_AXY | REG_PTR1 }, + { "ldaxidx", REG_AXY, PSTATE_ALL | REG_AXY | REG_PTR1 }, + { "ldaxysp", SLV_IND | REG_Y, PSTATE_ALL | REG_AXY }, + { "ldeax0sp", SLV_TOP, PSTATE_ALL | REG_EAXY }, + { "ldeaxi", REG_AX, PSTATE_ALL | REG_EAXY | REG_PTR1 }, + { "ldeaxidx", REG_AXY, PSTATE_ALL | REG_EAXY | REG_PTR1 }, + { "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 }, + { "leavey", REG_SP | REG_Y, PSTATE_ALL | REG_SP | REG_Y }, + { "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 }, + { "lsubeqa", REG_AY | REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI }, + { "lsubeqysp", SLV_IND | REG_EAXY, PSTATE_ALL | REG_EAXY }, + { "mulax10", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, + { "mulax3", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, + { "mulax5", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, + { "mulax6", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, + { "mulax7", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, + { "mulax9", REG_AX, PSTATE_ALL | REG_AX | REG_PTR1 }, + { "negax", REG_AX, PSTATE_ALL | REG_AX }, + { "negeax", REG_EAX, PSTATE_ALL | REG_EAX }, + { "popa", SLV_TOP, PSTATE_ALL | REG_SP | REG_AY }, + { "popax", SLV_TOP, PSTATE_ALL | REG_SP | REG_AXY }, + { "popeax", SLV_TOP, PSTATE_ALL | REG_SP | REG_EAXY }, + { "push0", REG_SP, PSTATE_ALL | REG_SP | REG_AXY }, + { "push0ax", REG_SP | REG_AX, PSTATE_ALL | REG_SP | REG_Y | REG_SREG }, + { "push1", REG_SP, PSTATE_ALL | REG_SP | REG_AXY }, + { "push2", REG_SP, PSTATE_ALL | REG_SP | REG_AXY }, + { "push3", REG_SP, PSTATE_ALL | REG_SP | REG_AXY }, + { "push4", REG_SP, PSTATE_ALL | REG_SP | REG_AXY }, + { "push5", REG_SP, PSTATE_ALL | REG_SP | REG_AXY }, + { "push6", REG_SP, PSTATE_ALL | REG_SP | REG_AXY }, + { "push7", REG_SP, PSTATE_ALL | REG_SP | REG_AXY }, + { "pusha", REG_SP | REG_A, PSTATE_ALL | REG_SP | REG_Y }, + { "pusha0", REG_SP | REG_A, PSTATE_ALL | REG_SP | REG_XY }, + { "pusha0sp", SLV_TOP, PSTATE_ALL | REG_SP | REG_AY }, + { "pushaFF", REG_SP | REG_A, PSTATE_ALL | REG_SP | REG_Y }, + { "pushax", REG_SP | REG_AX, PSTATE_ALL | REG_SP | REG_Y }, + { "pushaysp", SLV_IND | REG_Y, PSTATE_ALL | REG_SP | REG_AY }, + { "pushc0", REG_SP, PSTATE_ALL | REG_SP | REG_A | REG_Y }, + { "pushc1", REG_SP, PSTATE_ALL | REG_SP | REG_A | REG_Y }, + { "pushc2", REG_SP, PSTATE_ALL | REG_SP | REG_A | REG_Y }, + { "pusheax", REG_SP | REG_EAX, PSTATE_ALL | REG_SP | REG_Y }, + { "pushl0", REG_SP, PSTATE_ALL | REG_SP | REG_AXY }, + { "pushw", REG_SP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY | REG_PTR1 }, + { "pushw0sp", SLV_TOP, PSTATE_ALL | REG_SP | REG_AXY }, + { "pushwidx", REG_SP | REG_AXY, PSTATE_ALL | REG_SP | REG_AXY | REG_PTR1 }, + { "pushwysp", SLV_IND | REG_Y, PSTATE_ALL | REG_SP | REG_AXY }, + { "regswap", REG_AXY, PSTATE_ALL | REG_AXY | REG_TMP1 }, + { "regswap1", REG_XY, PSTATE_ALL | REG_A }, + { "regswap2", REG_XY, PSTATE_ALL | REG_A | REG_Y }, + { "resteax", REG_SAVE, PSTATE_ZN | REG_EAX }, /* also uses regsave+2/+3 */ + { "return0", REG_NONE, PSTATE_ALL | REG_AX }, + { "return1", REG_NONE, PSTATE_ALL | REG_AX }, + { "saveeax", REG_EAX, PSTATE_ZN | REG_Y | REG_SAVE }, /* also regsave+2/+3 */ + { "shlax1", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, + { "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 }, + { "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 }, + { "shleax3", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, + { "shleax4", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "shrax1", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, + { "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 }, + { "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 }, + { "shreax3", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, + { "shreax4", REG_EAX, PSTATE_ALL | REG_EAXY | REG_TMP1 }, + { "staspidx", SLV_TOP | REG_AY, PSTATE_ALL | REG_SP | REG_Y | REG_TMP1 | REG_PTR1 }, + { "stax0sp", REG_SP | REG_AX, PSTATE_ALL | SLV_TOP | REG_Y }, + { "staxspidx", SLV_TOP | REG_AXY, PSTATE_ALL | REG_SP | REG_TMP1 | REG_PTR1 }, + { "staxysp", REG_SP | REG_AXY, PSTATE_ALL | SLV_IND | REG_Y }, + { "steax0sp", REG_SP | REG_EAX, PSTATE_ALL | SLV_TOP | REG_Y }, + { "steaxspidx", SLV_TOP | REG_EAXY, PSTATE_ALL | REG_SP | REG_Y | REG_TMP1 | REG_PTR1 }, /* also tmp2, tmp3 */ + { "steaxysp", REG_SP | REG_EAXY, PSTATE_ALL | SLV_IND | REG_Y }, + { "subeq0sp", SLV_TOP | REG_AX, PSTATE_ALL | REG_AXY }, + { "subeqysp", SLV_IND | REG_AXY, PSTATE_ALL | REG_AXY }, + { "subysp", REG_SP | REG_Y, PSTATE_ALL | REG_SP | REG_AY }, + { "swapstk", SLV_TOP | REG_AX, PSTATE_ALL | SLV_TOP | REG_AXY }, /* also ptr4 */ + { "tosadd0ax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_EAXY | REG_TMP1 }, + { "tosadda0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY }, + { "tosaddax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY }, + { "tosaddeax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_EAXY | REG_TMP1 }, + { "tosand0ax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_EAXY | REG_TMP1 }, + { "tosanda0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY }, + { "tosandax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY }, + { "tosandeax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_EAXY | REG_TMP1 }, + { "tosaslax", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_TMP1 }, + { "tosasleax", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_EAXY | REG_TMP1 }, + { "tosasrax", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_TMP1 }, + { "tosasreax", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_EAXY | REG_TMP1 }, + { "tosdiv0ax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_ALL }, + { "tosdiva0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_ALL }, + { "tosdivax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_ALL }, + { "tosdiveax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_ALL }, + { "toseq00", SLV_TOP, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "toseqa0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "toseqax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "toseqeax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_AXY | REG_PTR1 }, + { "tosge00", SLV_TOP, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosgea0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosgeax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosgeeax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_AXY | REG_PTR1 }, + { "tosgt00", SLV_TOP, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosgta0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosgtax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosgteax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_AXY | REG_PTR1 }, + { "tosicmp", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosicmp0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosint", SLV_TOP, PSTATE_ALL | REG_SP | REG_Y }, + { "toslcmp", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_A | REG_Y | REG_PTR1 }, + { "tosle00", SLV_TOP, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "toslea0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosleax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosleeax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_AXY | REG_PTR1 }, + { "toslong", SLV_TOP, PSTATE_ALL | REG_SP | REG_Y }, + { "toslt00", SLV_TOP, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "toslta0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosltax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "toslteax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_AXY | REG_PTR1 }, + { "tosmod0ax", SLV_TOP | REG_AX, PSTATE_ALL | REG_ALL }, + { "tosmodeax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_ALL }, + { "tosmul0ax", SLV_TOP | REG_AX, PSTATE_ALL | REG_ALL }, + { "tosmula0", SLV_TOP | REG_A, PSTATE_ALL | REG_ALL }, + { "tosmulax", SLV_TOP | REG_AX, PSTATE_ALL | REG_ALL }, + { "tosmuleax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_ALL }, + { "tosne00", SLV_TOP, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosnea0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosneax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosneeax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_AXY | REG_PTR1 }, + { "tosor0ax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_EAXY | REG_TMP1 }, + { "tosora0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_TMP1 }, + { "tosorax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY | REG_TMP1 }, + { "tosoreax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_EAXY | REG_TMP1 }, + { "tosrsub0ax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_EAXY | REG_TMP1 }, + { "tosrsuba0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_TMP1 }, + { "tosrsubax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY | REG_TMP1 }, + { "tosrsubeax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_EAXY | REG_TMP1 }, + { "tosshlax", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_TMP1 }, + { "tosshleax", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_EAXY | REG_TMP1 }, + { "tosshrax", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_TMP1 }, + { "tosshreax", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_EAXY | REG_TMP1 }, + { "tossub0ax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_EAXY }, + { "tossuba0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY }, + { "tossubax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY }, + { "tossubeax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_EAXY }, + { "tosudiv0ax", SLV_TOP | REG_AX, PSTATE_ALL | (REG_ALL & ~REG_SAVE) }, + { "tosudiva0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_EAXY | REG_PTR1 }, /* also ptr4 */ + { "tosudivax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_EAXY | REG_PTR1 }, /* also ptr4 */ + { "tosudiveax", SLV_TOP | REG_EAX, PSTATE_ALL | (REG_ALL & ~REG_SAVE) }, + { "tosuge00", SLV_TOP, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosugea0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosugeax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosugeeax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_AXY | REG_PTR1 }, + { "tosugt00", SLV_TOP, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosugta0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosugtax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosugteax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_AXY | REG_PTR1 }, + { "tosule00", SLV_TOP, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosulea0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosuleax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosuleeax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_AXY | REG_PTR1 }, + { "tosulong", SLV_TOP, PSTATE_ALL | REG_SP | REG_Y }, + { "tosult00", SLV_TOP, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosulta0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosultax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY | REG_SREG }, + { "tosulteax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_AXY | REG_PTR1 }, + { "tosumod0ax", SLV_TOP | REG_AX, PSTATE_ALL | (REG_ALL & ~REG_SAVE) }, + { "tosumoda0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_EAXY | REG_PTR1 }, /* also ptr4 */ + { "tosumodax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_EAXY | REG_PTR1 }, /* also ptr4 */ + { "tosumodeax", SLV_TOP | REG_EAX, PSTATE_ALL | (REG_ALL & ~REG_SAVE) }, + { "tosumul0ax", SLV_TOP | REG_AX, PSTATE_ALL | REG_ALL }, + { "tosumula0", SLV_TOP | REG_A, PSTATE_ALL | REG_ALL }, + { "tosumulax", SLV_TOP | REG_AX, PSTATE_ALL | REG_ALL }, + { "tosumuleax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_ALL }, + { "tosxor0ax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_EAXY | REG_TMP1 }, + { "tosxora0", SLV_TOP | REG_A, PSTATE_ALL | REG_SP | REG_AXY | REG_TMP1 }, + { "tosxorax", SLV_TOP | REG_AX, PSTATE_ALL | REG_SP | REG_AXY | REG_TMP1 }, + { "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 }, }; #define FuncInfoCount (sizeof(FuncInfoTable) / sizeof(FuncInfoTable[0])) @@ -481,6 +508,7 @@ fncls_t GetFuncInfo (const char* Name, unsigned int* Use, unsigned int* Chg) /* Did we find it in the top-level table? */ if (E && IsTypeFunc (E->Type)) { FuncDesc* D = GetFuncDesc (E->Type); + *Use = REG_NONE; /* A variadic function will use the Y register (the parameter list ** size is passed there). A fastcall function will use the A or A/X @@ -488,31 +516,40 @@ fncls_t GetFuncInfo (const char* Name, unsigned int* Use, unsigned int* Chg) ** we assume that any function will destroy all registers. */ if ((D->Flags & FD_VARIADIC) != 0) { - *Use = REG_Y; + *Use = REG_Y | REG_SP | SLV_TOP; } else if (D->Flags & FD_CALL_WRAPPER) { /* Wrappers may go to any functions, so mark them as using all ** registers. */ *Use = REG_EAXY; - } else if ((D->ParamCount > 0 || (D->Flags & FD_EMPTY) != 0) && - IsFastcallFunc (E->Type)) { + } else if (D->ParamCount > 0 || (D->Flags & FD_EMPTY) != 0) { /* Will use registers depending on the last param. If the last ** param has incomplete type, or if the function has not been ** prototyped yet, just assume __EAX__. */ - if (D->LastParam != 0) { - switch (SizeOf (D->LastParam->Type)) { - case 1u: - *Use = REG_A; - break; - case 2u: - *Use = REG_AX; - break; - default: - *Use = REG_EAX; + if (IsFastcallFunc (E->Type)) { + if (D->LastParam != 0) { + switch (SizeOf (D->LastParam->Type)) { + case 1u: + *Use = REG_A; + break; + case 2u: + *Use = REG_AX; + break; + default: + *Use = REG_EAX; + } + if (D->ParamCount > 1) { + /* Passes other params on the stack */ + *Use |= REG_SP | SLV_TOP; + } + } else { + /* We'll assume all */ + *Use = REG_EAX | REG_SP | SLV_TOP; } } else { - *Use = REG_EAX; + /* Passes all params on the stack */ + *Use = REG_SP | SLV_TOP; } } else { /* Will not use any registers */ @@ -551,6 +588,9 @@ fncls_t GetFuncInfo (const char* Name, unsigned int* Use, unsigned int* Chg) /* Use the information we have */ *Use = Info->Use; *Chg = Info->Chg; + if ((*Use & (SLV_TOP | SLV_IND)) != 0) { + *Use |= REG_SP; + } } else { /* It's an internal function we have no information for. If in ** debug mode, output an additional warning, so we have a chance diff --git a/src/cc65/codeinfo.h b/src/cc65/codeinfo.h index 88e26cdf4..14ef54d8f 100644 --- a/src/cc65/codeinfo.h +++ b/src/cc65/codeinfo.h @@ -75,6 +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_SP65 0x00200000U /* Accesses 6502 stack pointer */ #define SLV_PH65 0x00400000U /* Pushes onto 6502 stack */ #define SLV_PL65 0x00800000U /* Pops from 6502 stack */ @@ -104,6 +106,7 @@ struct RegContents; #define REG_EAXY (REG_EAX | REG_Y) #define REG_ZP 0xFFF8U #define REG_ALL 0xFFFFU + #define PSTATE_CZ (PSTATE_C | PSTATE_Z) #define PSTATE_CZN (PSTATE_C | PSTATE_Z | PSTATE_N) #define PSTATE_CZVN (PSTATE_C | PSTATE_Z | PSTATE_V | PSTATE_N) diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index 16c41162a..a4980aa3a 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -827,21 +827,28 @@ void AdjustStackOffset (StackOpData* D, unsigned Offs) CodeEntry* E = CS_GetEntry (D->Code, I); + /* Check against some things that should not happen */ + CHECK ((E->Use & SLV_TOP) != SLV_TOP); + /* Check if this entry does a stack access, and if so, if it's a plain ** load from stack, since this is needed later. */ int Correction = 0; - if ((E->Use & REG_SP) != 0) { + if ((E->Use & SLV_IND) == SLV_IND) { - /* Check for some things that should not happen */ - CHECK (E->AM == AM65_ZP_INDY || E->RI->In.RegY >= (short) Offs); - CHECK (strcmp (E->Arg, "sp") == 0); - /* We need to correct this one */ - Correction = (E->OPC == OP65_LDA)? 2 : 1; + 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); + + /* We need to correct this one */ + Correction = 2; + + } else { + /* We need to correct this one */ + Correction = 1; + } - } else if (CE_IsCallTo (E, "ldaxysp")) { - /* We need to correct this one */ - Correction = 1; } if (Correction) { @@ -849,7 +856,7 @@ void AdjustStackOffset (StackOpData* D, unsigned Offs) ** value. */ CodeEntry* P = CS_GetPrevEntry (D->Code, I); - if (P && P->OPC == OP65_LDY && CE_IsConstImm (P)) { + if (P && P->OPC == OP65_LDY && CE_IsConstImm (P) && !CE_HasLabel (E)) { /* The Y load is just before the stack access, adjust it */ CE_SetNumArg (P, P->Num - Offs); } else { @@ -860,39 +867,59 @@ void AdjustStackOffset (StackOpData* D, unsigned Offs) } /* If we need the value of Y later, be sure to reload it */ - if (RegYUsed (D->Code, I+1)) { - CodeEntry* N; + unsigned R = REG_Y | (E->Chg & ~REG_A); + R = GetRegInfo (D->Code, I + 1, R) & R; + if ((R & REG_Y) != 0) { const char* Arg = MakeHexArg (E->RI->In.RegY); - if (Correction == 2 && (N = CS_GetNextEntry(D->Code, I)) != 0 && - ((N->Info & OF_ZBRA) != 0) && N->JumpTo != 0) { - /* The Y register is used but the load instruction loads A - ** and is followed by a branch that evaluates the zero flag. - ** This means that we cannot just insert the load insn - ** for the Y register at this place, because it would - ** destroy the Z flag. Instead place load insns at the - ** target of the branch and after it. - ** Note: There is a chance that this code won't work. The - ** jump may be a backwards jump (in which case the stack - ** offset has already been adjusted) or there may be other - ** instructions between the load and the conditional jump. - ** Currently the compiler does not generate such code, but - ** it is possible to force the optimizer into something - ** invalid by use of inline assembler. - */ + if ((R & PSTATE_ZN) != 0 && (R & ~(REG_Y | PSTATE_ZN)) == 0) { + CodeEntry* N; + if ((N = CS_GetNextEntry (D->Code, I)) != 0 && + ((N->Info & OF_ZBRA) != 0) && N->JumpTo != 0) { + /* The Y register is used but the load instruction loads A + ** and is followed by a branch that evaluates the zero flag. + ** This means that we cannot just insert the load insn + ** for the Y register at this place, because it would + ** destroy the Z flag. Instead place load insns at the + ** target of the branch and after it. + ** Note: There is a chance that this code won't work. The + ** jump may be a backwards jump (in which case the stack + ** offset has already been adjusted) or there may be other + ** instructions between the load and the conditional jump. + ** Currently the compiler does not generate such code, but + ** it is possible to force the optimizer into something + ** invalid by use of inline assembler. + ** Note: In reality, this route is never taken as all + ** callers of this function will just give up with + ** optimization whenever they detect a branch. + */ - /* Add load insn after the branch */ - CodeEntry* X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); - InsertEntry (D, X, I+2); + /* Add load insn after the branch */ + CodeEntry* X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + InsertEntry (D, X, I+2); - /* Add load insn before branch target */ - CodeEntry* Y = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); - int J = CS_GetEntryIndex (D->Code, N->JumpTo->Owner); - CHECK (J > I); /* Must not happen */ - InsertEntry (D, Y, J); + /* Add load insn before branch target */ + CodeEntry* Y = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); + int J = CS_GetEntryIndex (D->Code, N->JumpTo->Owner); + CHECK (J > I); /* Must not happen */ + InsertEntry (D, Y, J); - /* Move the label to the new insn */ - CodeLabel* L = CS_GenLabel (D->Code, Y); - CS_MoveLabelRef (D->Code, N, L); + /* Move the label to the new insn */ + CodeLabel* L = CS_GenLabel (D->Code, Y); + CS_MoveLabelRef (D->Code, N, L); + + /* Skip the next two instructions in the next round */ + I += 2; + } else { + /* This could be suboptimal but it will always work (unless stack overflows) */ + CodeEntry* X = NewCodeEntry (OP65_PHP, AM65_IMP, 0, 0, E->LI); + InsertEntry (D, X, I+1); + X = NewCodeEntry (OP65_LDY, AM65_IMM, 0, 0, E->LI); + InsertEntry (D, X, I+2); + X = NewCodeEntry (OP65_PLP, AM65_IMP, 0, 0, E->LI); + InsertEntry (D, X, I+3); + /* Skip the three inserted instructions in the next round */ + I += 3; + } } else { CodeEntry* X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, E->LI); InsertEntry (D, X, I+1); From 79be6dec1625ca962ec01755d273f833c583b12c Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 18 Sep 2020 20:23:02 +0800 Subject: [PATCH 2077/2161] More quick hack for CE_GenRegInfo. --- src/cc65/codeent.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index 4f257a22e..0a1b917db 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -1781,6 +1781,13 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs) if (RegValIsKnown (In->RegX)) { Out->RegX = (In->RegX ^ 0xFF); } + } else if (strncmp (E->Arg, "asrax", 5) == 0 || + strncmp (E->Arg, "shrax", 5) == 0) { + if (RegValIsKnown (In->RegX)) { + if (In->RegX == 0x00 || In->RegX == 0xFF) { + Out->RegX = In->RegX; + } + } } else if (strcmp (E->Arg, "tosandax") == 0) { if (RegValIsKnown (In->RegA) && In->RegA == 0) { Out->RegA = 0; From 4d5fe3854033b1b24d20fa4eb40e38dbf34c7cc9 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Fri, 18 Sep 2020 20:23:03 +0800 Subject: [PATCH 2078/2161] Fixed OptStackOps when the stuff pushed on stack top is accessed before the op. --- src/cc65/codeoptutil.c | 87 ++++++++++++++++-------------------------- src/cc65/codeoptutil.h | 2 +- src/cc65/coptstop.c | 27 +++++++------ 3 files changed, 48 insertions(+), 68 deletions(-) diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index a4980aa3a..173d5185f 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -1224,66 +1224,43 @@ static int CmpHarmless (const void* Key, const void* Entry) -int HarmlessCall (const char* Name) +int HarmlessCall (const CodeEntry* E, int PushedBytes) /* Check if this is a call to a harmless subroutine that will not interrupt ** the pushax/op sequence when encountered. */ { - static const char* const Tab[] = { - "aslax1", - "aslax2", - "aslax3", - "aslax4", - "aslaxy", - "asrax1", - "asrax2", - "asrax3", - "asrax4", - "asraxy", - "bcastax", - "bnegax", - "complax", - "decax1", - "decax2", - "decax3", - "decax4", - "decax5", - "decax6", - "decax7", - "decax8", - "decaxy", - "incax1", - "incax2", - "incax3", - "incax4", - "incax5", - "incax6", - "incax7", - "incax8", - "incaxy", - "ldaidx", - "ldauidx", - "ldaxidx", - "ldaxysp", - "negax", - "shlax1", - "shlax2", - "shlax3", - "shlax4", - "shlaxy", - "shrax1", - "shrax2", - "shrax3", - "shrax4", - "shraxy", - }; + unsigned Use = 0, Chg = 0; + if (GetFuncInfo (E->Arg, &Use, &Chg) == FNCLS_BUILTIN) { + if ((Chg & REG_SP) != 0) { + return 0; + } + if ((Use & REG_SP) != 0 && + ((Use & (SLV_IND | SLV_TOP)) != SLV_IND || + RegValIsUnknown (E->RI->In.RegY) || + E->RI->In.RegY < PushedBytes)) { + /* If we are using the stack, and we don't have "indirect" + ** addressing mode, or the value of Y is unknown, or less + ** than two, we cannot cope with this piece of code. Having + ** an unknown value of Y means that we cannot correct the + ** stack offset, while having an offset less than PushedBytes + ** means that the code works with the value on stack which + ** is to be removed. + */ + return 0; + } + return 1; + } else { + static const char* const Tab[] = { + "_abs", + }; - void* R = bsearch (Name, - Tab, - sizeof (Tab) / sizeof (Tab[0]), - sizeof (Tab[0]), - CmpHarmless); - return (R != 0); + void* R = bsearch (E->Arg, + Tab, + sizeof (Tab) / sizeof (Tab[0]), + sizeof (Tab[0]), + CmpHarmless); + return (R != 0); + } } diff --git a/src/cc65/codeoptutil.h b/src/cc65/codeoptutil.h index 70aa5f462..140b11236 100644 --- a/src/cc65/codeoptutil.h +++ b/src/cc65/codeoptutil.h @@ -261,7 +261,7 @@ void RemoveRegLoads (StackOpData* D, LoadInfo* LI); void RemoveRemainders (StackOpData* D); /* Remove the code that is unnecessary after translation of the sequence */ -int HarmlessCall (const char* Name); +int HarmlessCall (const CodeEntry* E, int PushedBytes); /* Check if this is a call to a harmless subroutine that will not interrupt ** the pushax/op sequence when encountered. */ diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 01d0b039c..23636e533 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -1820,20 +1820,18 @@ unsigned OptStackOps (CodeSeg* S) Data.OpEntry = E; State = FoundOp; break; - } else if (!HarmlessCall (E->Arg)) { - /* A call to an unkown subroutine: We need to start - ** over after the last pushax. Note: This will also - ** happen if we encounter a call to pushax! + } else if (!HarmlessCall (E, 2)) { + /* The call might use or change the content that we are + ** going to access later via the stack pointer. In any + ** case, we need to start over after the last pushax. + ** Note: This will also happen if we encounter a call + ** to pushax! */ I = Data.PushIndex; State = Initialize; break; } - - } else if ((E->Use & REG_SP) != 0 && - (E->AM != AM65_ZP_INDY || - RegValIsUnknown (E->RI->In.RegY) || - E->RI->In.RegY < 2)) { + } else if (((E->Chg | E->Use) & REG_SP) != 0) { /* If we are using the stack, and we don't have "indirect Y" ** addressing mode, or the value of Y is unknown, or less @@ -1843,9 +1841,14 @@ unsigned OptStackOps (CodeSeg* S) ** that the code works with the value on stack which is to ** be removed. */ - I = Data.PushIndex; - State = Initialize; - break; + if (E->AM == AM65_ZPX_IND || + ((E->Chg | E->Use) & SLV_IND) == 0 || + (RegValIsUnknown (E->RI->In.RegY) || + E->RI->In.RegY < 2)) { + I = Data.PushIndex; + State = Initialize; + break; + } } From 3584c4c87fceb3771daaa054de1eed75ebc46b86 Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Mon, 22 Feb 2021 11:57:32 -0500 Subject: [PATCH 2079/2161] fix crash when a NULL ExprNode is checked for circular references --- src/ld65/expr.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ld65/expr.c b/src/ld65/expr.c index bc3d7941c..e106e09d0 100644 --- a/src/ld65/expr.c +++ b/src/ld65/expr.c @@ -464,6 +464,12 @@ static void GetSegExprValInternal (ExprNode* Expr, SegExprDesc* D, int Sign) { Export* E; + if (Expr == 0) + { + D->TooComplex = 1; + return; + } + switch (Expr->Op) { case EXPR_LITERAL: From 6ebe551919ba9acecd5d9caf6d8668d9fc11d09d Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Mon, 22 Feb 2021 18:14:27 -0500 Subject: [PATCH 2080/2161] return is sufficient, TooComplex flag is unnecessary to resolve this crash case suggested by greg-king5 in #1409 --- src/ld65/expr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ld65/expr.c b/src/ld65/expr.c index e106e09d0..23f52a16f 100644 --- a/src/ld65/expr.c +++ b/src/ld65/expr.c @@ -466,7 +466,6 @@ static void GetSegExprValInternal (ExprNode* Expr, SegExprDesc* D, int Sign) if (Expr == 0) { - D->TooComplex = 1; return; } From d5d9183ccfde833296a3e2d3f4d44fd7468b3a56 Mon Sep 17 00:00:00 2001 From: bbbradsmith <bbbradsmith@users.noreply.github.com> Date: Mon, 22 Feb 2021 18:17:11 -0500 Subject: [PATCH 2081/2161] conform to prevailing if bracket style --- src/ld65/expr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ld65/expr.c b/src/ld65/expr.c index 23f52a16f..5d6b56917 100644 --- a/src/ld65/expr.c +++ b/src/ld65/expr.c @@ -464,8 +464,7 @@ static void GetSegExprValInternal (ExprNode* Expr, SegExprDesc* D, int Sign) { Export* E; - if (Expr == 0) - { + if (Expr == 0) { return; } From 39ef63cbbc0f27968fdd044a0af22630969324e6 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 4 Jun 2021 08:49:10 -0400 Subject: [PATCH 2082/2161] Don't check for circular references of imports that don't have matching exports. This fix will avoid referring to a struct member through a null pointer. --- src/ld65/expr.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/ld65/expr.c b/src/ld65/expr.c index 5d6b56917..41db2326c 100644 --- a/src/ld65/expr.c +++ b/src/ld65/expr.c @@ -457,16 +457,14 @@ long GetExprVal (ExprNode* Expr) static void GetSegExprValInternal (ExprNode* Expr, SegExprDesc* D, int Sign) /* Check if the given expression consists of a segment reference and only -** constant values, additions and subtractions. If anything else is found, +** constant values, additions, and subtractions. If anything else is found, ** set D->TooComplex to true. ** Internal, recursive routine. */ { Export* E; - if (Expr == 0) { - return; - } + CHECK (Expr != 0); switch (Expr->Op) { @@ -483,7 +481,7 @@ static void GetSegExprValInternal (ExprNode* Expr, SegExprDesc* D, int Sign) */ if (ExportHasMark (E)) { CircularRefError (E); - } else { + } else if (E->Expr != 0) { MarkExport (E); GetSegExprValInternal (E->Expr, D, Sign); UnmarkExport (E); From 1c16e46f2369306fa7397dbde8750aad3b824816 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sat, 5 Jun 2021 11:31:28 -0400 Subject: [PATCH 2083/2161] Improved ld65's error messages about ca65's .BANK() function. * Split a message into two more specific messages. --- src/ld65/expr.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/ld65/expr.c b/src/ld65/expr.c index 41db2326c..7a2f37d4a 100644 --- a/src/ld65/expr.c +++ b/src/ld65/expr.c @@ -403,17 +403,20 @@ long GetExprVal (ExprNode* Expr) case EXPR_BANK: GetSegExprVal (Expr->Left, &D); - if (D.TooComplex || D.Seg == 0) { - Error ("Argument for .BANK is not segment relative or too complex"); + if (D.TooComplex) { + Error ("Argument of .BANK() is too complex"); + } + if (D.Seg == 0) { + Error ("Argument of .BANK() isn't a label attached to a segment"); } if (D.Seg->MemArea == 0) { - Error ("Segment '%s' is referenced by .BANK but " - "not assigned to a memory area", + Error ("Segment '%s' is referenced by .BANK()," + " but not assigned to a memory area", GetString (D.Seg->Name)); } if (D.Seg->MemArea->BankExpr == 0) { - Error ("Memory area '%s' is referenced by .BANK but " - "has no BANK attribute", + Error ("Memory area '%s' is referenced by .BANK()," + " but has no BANK attribute", GetString (D.Seg->MemArea->Name)); } return GetExprVal (D.Seg->MemArea->BankExpr); From 69e2313a63a37543032fb40658fcaacf64465431 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Sun, 6 Jun 2021 23:20:54 +0100 Subject: [PATCH 2084/2161] First round of requested code changes --- cfg/sym1-32k.cfg | 56 +++++++++---------- cfg/sym1-4k.cfg | 56 +++++++++---------- cfg/sym1.cfg | 56 +++++++++---------- doc/ca65.sgml | 1 + doc/cc65.sgml | 4 ++ libsrc/sym1/ctype.s | 5 ++ src/ca65/main.c | 1 + src/cc65/main.c | 1 + {samples/tutorial => targettest}/sym1/build | 0 .../tutorial => targettest}/sym1/build_32k | 0 .../tutorial => targettest}/sym1/build_4k | 0 {samples/tutorial => targettest}/sym1/clean | 0 .../tutorial => targettest}/sym1/readme.txt | 0 .../tutorial => targettest}/sym1/symDisplay.c | 0 .../tutorial => targettest}/sym1/symHello.c | 0 {samples/tutorial => targettest}/sym1/symIO.c | 0 .../tutorial => targettest}/sym1/symNotepad.c | 0 .../tutorial => targettest}/sym1/symTiny.c | 0 18 files changed, 96 insertions(+), 84 deletions(-) create mode 100644 libsrc/sym1/ctype.s rename {samples/tutorial => targettest}/sym1/build (100%) rename {samples/tutorial => targettest}/sym1/build_32k (100%) rename {samples/tutorial => targettest}/sym1/build_4k (100%) rename {samples/tutorial => targettest}/sym1/clean (100%) rename {samples/tutorial => targettest}/sym1/readme.txt (100%) rename {samples/tutorial => targettest}/sym1/symDisplay.c (100%) rename {samples/tutorial => targettest}/sym1/symHello.c (100%) rename {samples/tutorial => targettest}/sym1/symIO.c (100%) rename {samples/tutorial => targettest}/sym1/symNotepad.c (100%) rename {samples/tutorial => targettest}/sym1/symTiny.c (100%) diff --git a/cfg/sym1-32k.cfg b/cfg/sym1-32k.cfg index 0665c8cf2..9af125eaa 100644 --- a/cfg/sym1-32k.cfg +++ b/cfg/sym1-32k.cfg @@ -5,42 +5,42 @@ # ld65 --config sym1-32k.cfg -o <prog>.bin <prog>.o FEATURES { - STARTADDRESS: default = $0200; - CONDES: segment = STARTUP, - type = constructor, - label = __CONSTRUCTOR_TABLE__, - count = __CONSTRUCTOR_COUNT__; - CONDES: segment = STARTUP, - type = destructor, - label = __DESTRUCTOR_TABLE__, - count = __DESTRUCTOR_COUNT__; + STARTADDRESS: default = $0200; + 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 = $0200; # 512 byte program stack - __STARTADDRESS__: type = export, value = %S; + __STACKSIZE__: type = weak, value = $0200; # 512 byte program stack + __STARTADDRESS__: type = export, value = %S; } MEMORY { - ZP: start = $0000, size = $00F7, define = yes, file = %O; - CPUSTACK: start = $0100, size = $0100, define = yes; - RAM: start = %S, size = $8000 - %S - __STACKSIZE__, define = yes, file = %O; - MONROM: start = $8000, size = $1000, define = yes; - EXT: start = $9000, size = $1000, define = yes; - IO: start = $A000, size = $1000, define = yes; - RAE1: start = $B000, size = $1000, define = yes; - BASROM: start = $C000, size = $1000, define = yes; - RAE2: start = $E000, size = $1000, define = yes; - TOP: start = $F000, size = $1000, define = yes; + ZP: file = %O, define = yes, start = $0000, size = $00F7; + CPUSTACK: file = "", define = yes, start = $0100, size = $0100; + RAM: file = %O, define = yes, start = %S, size = $8000 - %S - __STACKSIZE__; + MONROM: file = "", define = yes, start = $8000, size = $1000; + EXT: file = "", define = yes, start = $9000, size = $1000; + IO: file = "", define = yes, start = $A000, size = $1000; + RAE1: file = "", define = yes, start = $B000, size = $1000; + BASROM: file = "", define = yes, start = $C000, size = $1000; + RAE2: 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; + 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/sym1-4k.cfg b/cfg/sym1-4k.cfg index de1be0b8a..eefb48a49 100644 --- a/cfg/sym1-4k.cfg +++ b/cfg/sym1-4k.cfg @@ -5,42 +5,42 @@ # ld65 --config sym1-4k.cfg -o <prog>.bin <prog>.o FEATURES { - STARTADDRESS: default = $0200; - CONDES: segment = STARTUP, - type = constructor, - label = __CONSTRUCTOR_TABLE__, - count = __CONSTRUCTOR_COUNT__; - CONDES: segment = STARTUP, - type = destructor, - label = __DESTRUCTOR_TABLE__, - count = __DESTRUCTOR_COUNT__; + STARTADDRESS: default = $0200; + 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; + __STACKSIZE__: type = weak, value = $0080; # 128 byte program stack + __STARTADDRESS__: type = export, value = %S; } MEMORY { - ZP: start = $0000, size = $00F7, define = yes, file = %O; - CPUSTACK: start = $0100, size = $0100, define = yes; - RAM: start = %S, size = $1000 - %S - __STACKSIZE__, define = yes, file = %O; - MONROM: start = $8000, size = $1000, define = yes; - EXT: start = $9000, size = $1000, define = yes; - IO: start = $A000, size = $1000, define = yes; - RAE1: start = $B000, size = $1000, define = yes; - BASROM: start = $C000, size = $1000, define = yes; - RAE2: start = $E000, size = $1000, define = yes; - TOP: start = $F000, size = $1000, define = yes; + ZP: file = %O, define = yes, start = $0000, size = $00F7; + CPUSTACK: file = "", define = yes, start = $0100, size = $0100; + RAM: file = %O, define = yes, start = %S, size = $1000 - %S - __STACKSIZE__; + MONROM: file = "", define = yes, start = $8000, size = $1000; + EXT: file = "", define = yes, start = $9000, size = $1000; + IO: file = "", define = yes, start = $A000, size = $1000; + RAE1: file = "", define = yes, start = $B000, size = $1000; + BASROM: file = "", define = yes, start = $C000, size = $1000; + RAE2: 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; + 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/sym1.cfg b/cfg/sym1.cfg index de1be0b8a..eefb48a49 100644 --- a/cfg/sym1.cfg +++ b/cfg/sym1.cfg @@ -5,42 +5,42 @@ # ld65 --config sym1-4k.cfg -o <prog>.bin <prog>.o FEATURES { - STARTADDRESS: default = $0200; - CONDES: segment = STARTUP, - type = constructor, - label = __CONSTRUCTOR_TABLE__, - count = __CONSTRUCTOR_COUNT__; - CONDES: segment = STARTUP, - type = destructor, - label = __DESTRUCTOR_TABLE__, - count = __DESTRUCTOR_COUNT__; + STARTADDRESS: default = $0200; + 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; + __STACKSIZE__: type = weak, value = $0080; # 128 byte program stack + __STARTADDRESS__: type = export, value = %S; } MEMORY { - ZP: start = $0000, size = $00F7, define = yes, file = %O; - CPUSTACK: start = $0100, size = $0100, define = yes; - RAM: start = %S, size = $1000 - %S - __STACKSIZE__, define = yes, file = %O; - MONROM: start = $8000, size = $1000, define = yes; - EXT: start = $9000, size = $1000, define = yes; - IO: start = $A000, size = $1000, define = yes; - RAE1: start = $B000, size = $1000, define = yes; - BASROM: start = $C000, size = $1000, define = yes; - RAE2: start = $E000, size = $1000, define = yes; - TOP: start = $F000, size = $1000, define = yes; + ZP: file = %O, define = yes, start = $0000, size = $00F7; + CPUSTACK: file = "", define = yes, start = $0100, size = $0100; + RAM: file = %O, define = yes, start = %S, size = $1000 - %S - __STACKSIZE__; + MONROM: file = "", define = yes, start = $8000, size = $1000; + EXT: file = "", define = yes, start = $9000, size = $1000; + IO: file = "", define = yes, start = $A000, size = $1000; + RAE1: file = "", define = yes, start = $B000, size = $1000; + BASROM: file = "", define = yes, start = $C000, size = $1000; + RAE2: 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; + 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/doc/ca65.sgml b/doc/ca65.sgml index 3fc534066..8ae8eabd9 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -4786,6 +4786,7 @@ compiler, depending on the target system selected: <item><tt/__SIM6502__/ - Target system is <tt/sim6502/ <item><tt/__SIM65C02__/ - Target system is <tt/sim65c02/ <item><tt/__SUPERVISION__/ - Target system is <tt/supervision/ +<item><tt/__SYM1__/ - Target system is <tt/sym1/ <item><tt/__VIC20__/ - Target system is <tt/vic20/ </itemize> diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 004061518..821e76586 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1022,6 +1022,10 @@ The compiler defines several macros at startup: This macro is defined if the target is the Supervision (-t supervision). + <tag><tt>__SYM1__</tt></tag> + + This macro is defined if the target is the Sym-1 (-t sym1). + <tag><tt>__TELESTRAT__</tt></tag> This macro is defined if the target is the Telestrat (-t telestrat). diff --git a/libsrc/sym1/ctype.s b/libsrc/sym1/ctype.s new file mode 100644 index 000000000..1301965eb --- /dev/null +++ b/libsrc/sym1/ctype.s @@ -0,0 +1,5 @@ +; Character specification table. +; +; uses the "common" definition + + .include "ctype_common.inc" diff --git a/src/ca65/main.c b/src/ca65/main.c index bb0607b7c..0eaf4ba6b 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -335,6 +335,7 @@ static void SetSys (const char* Sys) break; case TGT_SYM1: + NewSymbol ("__SYM1__", 1); break; default: diff --git a/src/cc65/main.c b/src/cc65/main.c index d0d756b3f..89c1b190e 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -291,6 +291,7 @@ static void SetSys (const char* Sys) break; case TGT_SYM1: + DefineNumericMacro ("__SYM1__", 1); break; default: diff --git a/samples/tutorial/sym1/build b/targettest/sym1/build similarity index 100% rename from samples/tutorial/sym1/build rename to targettest/sym1/build diff --git a/samples/tutorial/sym1/build_32k b/targettest/sym1/build_32k similarity index 100% rename from samples/tutorial/sym1/build_32k rename to targettest/sym1/build_32k diff --git a/samples/tutorial/sym1/build_4k b/targettest/sym1/build_4k similarity index 100% rename from samples/tutorial/sym1/build_4k rename to targettest/sym1/build_4k diff --git a/samples/tutorial/sym1/clean b/targettest/sym1/clean similarity index 100% rename from samples/tutorial/sym1/clean rename to targettest/sym1/clean diff --git a/samples/tutorial/sym1/readme.txt b/targettest/sym1/readme.txt similarity index 100% rename from samples/tutorial/sym1/readme.txt rename to targettest/sym1/readme.txt diff --git a/samples/tutorial/sym1/symDisplay.c b/targettest/sym1/symDisplay.c similarity index 100% rename from samples/tutorial/sym1/symDisplay.c rename to targettest/sym1/symDisplay.c diff --git a/samples/tutorial/sym1/symHello.c b/targettest/sym1/symHello.c similarity index 100% rename from samples/tutorial/sym1/symHello.c rename to targettest/sym1/symHello.c diff --git a/samples/tutorial/sym1/symIO.c b/targettest/sym1/symIO.c similarity index 100% rename from samples/tutorial/sym1/symIO.c rename to targettest/sym1/symIO.c diff --git a/samples/tutorial/sym1/symNotepad.c b/targettest/sym1/symNotepad.c similarity index 100% rename from samples/tutorial/sym1/symNotepad.c rename to targettest/sym1/symNotepad.c diff --git a/samples/tutorial/sym1/symTiny.c b/targettest/sym1/symTiny.c similarity index 100% rename from samples/tutorial/sym1/symTiny.c rename to targettest/sym1/symTiny.c From 7d5fc7eb439b0a9ee3ba58cf07ca2f892e85e4ac Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Sun, 6 Jun 2021 17:51:24 -0500 Subject: [PATCH 2085/2161] Changed kb references to KB --- doc/sym1.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/sym1.sgml b/doc/sym1.sgml index f04f36ae1..a52cf93de 100644 --- a/doc/sym1.sgml +++ b/doc/sym1.sgml @@ -38,7 +38,7 @@ Special locations: Conio support is not currently available for the Sym-1. But stdio console functions are available. <tag/Stack/ - The C runtime stack is located at $0FFF on 4kb Syms, or at $7FFFfor 32kb systems. The stack always grows downwards. + The C runtime stack is located at $0FFF on 4KB Syms, or at $7FFFfor 32KB systems. The stack always grows downwards. <tag/Heap/ The C heap is located at the end of the program and grows towards the C @@ -101,7 +101,7 @@ But there is another header available, which exposes Sym-specific I/O functions <sect2>Limited memory applications<p> -As stated earlier, there are config files for 4kb and 32kb systems. If you have 32kb RAM, then you will probably want to use the sym1_32k configuration, but if not - if you are using the sym1_32k configuration - then you may want to use functions like getchar, putchar, gets and puts rather than printf. Printf requires about 1kb because it needs to know how to process all the format specifiers. +As stated earlier, there are config files for 4KB and 32KB systems. If you have 32KB RAM, then you will probably want to use the sym1_32k configuration, but if not - if you are using the sym1_32k configuration - then you may want to use functions like getchar, putchar, gets and puts rather than printf. Printf requires about 1KB because it needs to know how to process all the format specifiers. <sect3>Sample programs<p> From e687f2f0480d1ba55c958e771139a1cd93ab34d6 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Sun, 6 Jun 2021 17:55:58 -0500 Subject: [PATCH 2086/2161] Clarified 'Limited memory applications' section --- doc/sym1.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sym1.sgml b/doc/sym1.sgml index a52cf93de..5e3e44dfd 100644 --- a/doc/sym1.sgml +++ b/doc/sym1.sgml @@ -101,7 +101,7 @@ But there is another header available, which exposes Sym-specific I/O functions <sect2>Limited memory applications<p> -As stated earlier, there are config files for 4KB and 32KB systems. If you have 32KB RAM, then you will probably want to use the sym1_32k configuration, but if not - if you are using the sym1_32k configuration - then you may want to use functions like getchar, putchar, gets and puts rather than printf. Printf requires about 1KB because it needs to know how to process all the format specifiers. +As stated earlier, there are config files for 4KB and 32KB systems. If you have 32KB RAM, then you will probably want to use the sym1-32k configuration, but if not - if you are using the sym1-4k configuration - then you may want to use functions like getchar, putchar, gets and puts rather than printf. Printf requires about 1KB because it needs to know how to process all the format specifiers. <sect3>Sample programs<p> From 6c4c959141161eba4ce02fb3b1f18be5ad5c21c2 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Sun, 6 Jun 2021 21:28:03 -0500 Subject: [PATCH 2087/2161] Sym-1 lib changes --- doc/sym1.sgml | 8 +- include/sym1.h | 154 ++++++++++++++++++++++++++++++++++++ include/symio.h | 148 ----------------------------------- libsrc/sym1/beep.s | 16 ++-- libsrc/sym1/bitio.s | 178 ++++++++++++++++++++---------------------- libsrc/sym1/crt0.s | 24 +++--- libsrc/sym1/display.s | 123 +++++++++++++---------------- libsrc/sym1/getchar.s | 21 ----- libsrc/sym1/putchar.s | 23 ------ libsrc/sym1/read.s | 12 +-- libsrc/sym1/tapeio.s | 17 ++-- libsrc/sym1/write.s | 12 +-- samples/symDisplay.c | 3 +- samples/symHello.c | 3 +- samples/symIO.c | 8 +- samples/symNotepad.c | 7 +- samples/symTiny.c | 3 +- 17 files changed, 339 insertions(+), 421 deletions(-) create mode 100644 include/sym1.h delete mode 100644 include/symio.h delete mode 100644 libsrc/sym1/getchar.s delete mode 100644 libsrc/sym1/putchar.s diff --git a/doc/sym1.sgml b/doc/sym1.sgml index 5e3e44dfd..59d1db3b7 100644 --- a/doc/sym1.sgml +++ b/doc/sym1.sgml @@ -48,7 +48,7 @@ Special locations: <sect>Platform specific header files<p> -Programs containing Sym-1 code may use the <tt/symio.h/ header file. See the header file for more information. +Programs containing Sym-1 code may use the <tt/sym1.h/ header file. See the header file for more information. <sect1>Hardware access<p> @@ -94,10 +94,8 @@ To be more specific, this limitation means that you cannot use any of the follow <sect>Other hints<p> -<sect1>symio.h<p> -You can use stdio.h if you wish, which provides console I/O (like printf) but does not have access to a filesystem, as mentioned above. - -But there is another header available, which exposes Sym-specific I/O functions that are useful for reading and writing its ports and front panel. It also exposes functions normally included using stdio.h but <i>only</i> the console I/O functions and not the filesystem functions. See the symio.h include file for a list of the functions available. +<sect1>sym1.h<p> +This header exposes Sym-specific I/O functions that are useful for reading and writing its ports and front panel. See the sym1.h include file for a list of the functions available. <sect2>Limited memory applications<p> diff --git a/include/sym1.h b/include/sym1.h new file mode 100644 index 000000000..0a919f84d --- /dev/null +++ b/include/sym1.h @@ -0,0 +1,154 @@ +// sym1.h +// +// I/O primitives for Sym-1 +// +// Wayne Parham + + + +#ifndef _SYM1_H +#define _SYM1_H + + + +/* Check for errors */ +#if !defined(__SYM1__) +# error This module may only be used when compiling for the Sym-1! +#endif + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Display character definitions */ +#define DISP_1 0x06 // '1' +#define DISP_2 0x5B // '2' +#define DISP_3 0x4F // '3' +#define DISP_4 0x66 // '4' +#define DISP_5 0x6D // '5' +#define DISP_6 0x7C // '6' +#define DISP_7 0x07 // '7' +#define DISP_8 0x7F // '8' +#define DISP_9 0x67 // '9' +#define DISP_0 0x3F // '0' +#define DISP_A 0x77 // 'A' +#define DISP_b 0x7C // 'b' +#define DISP_C 0x39 // 'C' +#define DISP_c 0x58 // 'c' +#define DISP_d 0x5E // 'd' +#define DISP_E 0x79 // 'E' +#define DISP_e 0x7B // 'e' +#define DISP_F 0x71 // 'F' +#define DISP_G 0x7D // 'G' +#define DISP_g 0x6F // 'g' +#define DISP_H 0x76 // 'H' +#define DISP_h 0x74 // 'h' +#define DISP_I 0x06 // 'I' +#define DISP_i 0x04 // 'i' +#define DISP_J 0x1E // 'J' +#define DISP_K 0x74 // 'K' +#define DISP_L 0x38 // 'L' +#define DISP_M_1 0x33 // 'M' +#define DISP_M_2 0x27 // 2nd half +#define DISP_n 0x54 // 'n' +#define DISP_O 0x3F // 'O' +#define DISP_o 0x5C // 'o' +#define DISP_P 0x73 // 'P' +#define DISP_q 0x67 // 'q' +#define DISP_r 0x50 // 'r' +#define DISP_S 0x6D // 'S' +#define DISP_t 0x46 // 't' +#define DISP_U 0x3E // 'U' +#define DISP_u 0x1C // 'u' +#define DISP_V_1 0x64 // 'V' +#define DISP_V_2 0x52 // 2nd half +#define DISP_W_1 0x3C // 'W' +#define DISP_W_2 0x1E // 2nd half +#define DISP_Y 0x6E // 'Y' +#define DISP_Z 0x5B // 'Z' +#define DISP_SPACE 0x00 // ' ' +#define DISP_PERIOD 0x80 // '.' +#define DISP_HYPHEN 0x40 // '-' +#define DISP_APOSTR 0x20 // ''' +#define DISP_EQUAL 0x41 // '=' +#define DISP_3_BAR 0x49 // '=' +#define DISP_BOTTOM 0x08 // '_' +#define DISP_TOP 0x01 // Top segment +#define DISP_LEFT 0x30 // '|' Left side, both segments +#define DISP_RIGHT 0x06 // '|' Right side, both segments +#define DISP_DEGREE 0x63 // 'o' An 'o' character in the upper segments +#define DISP_HAT 0x23 // 'n' An 'n' character in the upper segments +#define DISP_FORK 0x62 // 'u' A 'u' character in the upper segments +#define DISP_SLASH 0x51 // '/' +#define DISP_BACKSLASH 0x34 // '\' +#define DISP_TOP_RIGHT 0x02 // Top right segment +#define DISP_TOP_LEFT 0x20 // Top left segment +#define DISP_LOW_RIGHT 0x04 // Lower right segment +#define DISP_LOW_LEFT 0x10 // Lower left segment + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +int __fastcall__ beep (void); // Beep sound +void __fastcall__ set_D0 (unsigned char); // Set display digit 0 +int __fastcall__ get_D0 (void); // Get value of display digit 0 +void __fastcall__ set_D1 (unsigned char); // Set display digit 1 +int __fastcall__ get_D1 (void); // Get value of display digit 1 +void __fastcall__ set_D2 (unsigned char); // Set display digit 2 +int __fastcall__ get_D2 (void); // Get value of display digit 2 +void __fastcall__ set_D3 (unsigned char); // Set display digit 3 +int __fastcall__ get_D3 (void); // Get value of display digit 3 +void __fastcall__ set_D4 (unsigned char); // Set display digit 4 +int __fastcall__ get_D4 (void); // Get value of display digit 4 +void __fastcall__ set_D5 (unsigned char); // Set display digit 5 +int __fastcall__ get_D5 (void); // Get value of display digit 5 +void __fastcall__ set_D6 (unsigned char); // Set byte to the right of display (leading buffer) +int __fastcall__ get_D6 (void); // Get value of memory byte to the right of display +void __fastcall__ fdisp (void); // Flash display + +int __fastcall__ loadt (int); // Read from tape (id) +int __fastcall__ dumpt (int, int, int); // Write to tape (id, start_addr, end_addr) + +void __fastcall__ set_DDR1A (unsigned char); // Set data direction register 1A (U25) +int __fastcall__ get_DDR1A (void); // Get value of data direction register 1A +void __fastcall__ set_IOR1A (unsigned char); // Set I/O register 1A +int __fastcall__ get_IOR1A (void); // Get value of I/O register 1A + +void __fastcall__ set_DDR1B (unsigned char); // Set data direction register 1B (U25) +int __fastcall__ get_DDR1B (void); // Get value of data direction register 1B +void __fastcall__ set_IOR1B (unsigned char); // Set I/O register 1B +int __fastcall__ get_IOR1B (void); // Get value of I/O register 1B + +void __fastcall__ set_DDR2A (unsigned char); // Set data direction register 2A (U28) +int __fastcall__ get_DDR2A (void); // Get value of data direction register 2A +void __fastcall__ set_IOR2A (unsigned char); // Set I/O register 2A +int __fastcall__ get_IOR2A (void); // Get value of I/O register 2A + +void __fastcall__ set_DDR2B (unsigned char); // Set data direction register 2B (U28) +int __fastcall__ get_DDR2B (void); // Get value of data direction register 2B +void __fastcall__ set_IOR2B (unsigned char); // Set I/O register 2B +int __fastcall__ get_IOR2B (void); // Get value of I/O register 2B + +void __fastcall__ set_DDR3A (unsigned char); // Set data direction register 3A (U29) +int __fastcall__ get_DDR3A (void); // Get value of data direction register 3A +void __fastcall__ set_IOR3A (unsigned char); // Set I/O register 3A +int __fastcall__ get_IOR3A (void); // Get value of I/O register 3A + +void __fastcall__ set_DDR3B (unsigned char); // Set data direction register 3B (U29) +int __fastcall__ get_DDR3B (void); // Get value of data direction register 3B +void __fastcall__ set_IOR3B (unsigned char); // Set I/O register 3B +int __fastcall__ get_IOR3B (void); // Get value of I/O register 3B + + + +/* End of sym1.h */ +#endif diff --git a/include/symio.h b/include/symio.h deleted file mode 100644 index 73b3ce18e..000000000 --- a/include/symio.h +++ /dev/null @@ -1,148 +0,0 @@ -// symio.h -// -// I/O primitives for Sym-1 -// -// Wayne Parham - -#ifndef _SYMIO_H -#define _SYMIO_H - -#include <stddef.h> -#include <stdarg.h> - -int __fastcall__ beep (void); // Beep sound -int __fastcall__ set_D0 (char); // Set display digit 0 -int __fastcall__ get_D0 (void); // Get value of display digit 0 -int __fastcall__ set_D1 (char); // Set display digit 1 -int __fastcall__ get_D1 (void); // Get value of display digit 1 -int __fastcall__ set_D2 (char); // Set display digit 2 -int __fastcall__ get_D2 (void); // Get value of display digit 2 -int __fastcall__ set_D3 (char); // Set display digit 3 -int __fastcall__ get_D3 (void); // Get value of display digit 3 -int __fastcall__ set_D4 (char); // Set display digit 4 -int __fastcall__ get_D4 (void); // Get value of display digit 4 -int __fastcall__ set_D5 (char); // Set display digit 5 -int __fastcall__ get_D5 (void); // Get value of display digit 5 -int __fastcall__ set_D6 (char); // Set byte to the right of display (leading buffer) -int __fastcall__ get_D6 (void); // Get value of memory byte to the right of display -int __fastcall__ fdisp (void); // Flash display - -int __fastcall__ loadt (int); // Read from tape (id) -int __fastcall__ dumpt (int, int, int); // Write to tape (id, start_addr, end_addr) - -int __fastcall__ set_DDR1A (int); // Set data direction register 1A (U25) -int __fastcall__ get_DDR1A (void); // Get value of data direction register 1A -int __fastcall__ set_IOR1A (int); // Set I/O register 1A -int __fastcall__ get_IOR1A (void); // Get value of I/O register 1A - -int __fastcall__ set_DDR1B (int); // Set data direction register 1B (U25) -int __fastcall__ get_DDR1B (void); // Get value of data direction register 1B -int __fastcall__ set_IOR1B (int); // Set I/O register 1B -int __fastcall__ get_IOR1B (void); // Get value of I/O register 1B - -int __fastcall__ set_DDR2A (int); // Set data direction register 2A (U28) -int __fastcall__ get_DDR2A (void); // Get value of data direction register 2A -int __fastcall__ set_IOR2A (int); // Set I/O register 2A -int __fastcall__ get_IOR2A (void); // Get value of I/O register 2A - -int __fastcall__ set_DDR2B (int); // Set data direction register 2B (U28) -int __fastcall__ get_DDR2B (void); // Get value of data direction register 2B -int __fastcall__ set_IOR2B (int); // Set I/O register 2B -int __fastcall__ get_IOR2B (void); // Get value of I/O register 2B - -int __fastcall__ set_DDR3A (int); // Set data direction register 3A (U29) -int __fastcall__ get_DDR3A (void); // Get value of data direction register 3A -int __fastcall__ set_IOR3A (int); // Set I/O register 3A -int __fastcall__ get_IOR3A (void); // Get value of I/O register 3A - -int __fastcall__ set_DDR3B (int); // Set data direction register 3B (U29) -int __fastcall__ get_DDR3B (void); // Get value of data direction register 3B -int __fastcall__ set_IOR3B (int); // Set I/O register 3B -int __fastcall__ get_IOR3B (void); // Get value of I/O register 3B - -#ifndef _STDIO_H - -int __fastcall__ putchar (char); -int __fastcall__ puts (const char* s); -int printf (const char* format, ...); -int sprintf (char* buf, const char* format, ...); -int __fastcall__ vprintf (const char* format, va_list ap); -int __fastcall__ vsnprintf (char* buf, size_t size, const char* format, va_list ap); -int __fastcall__ vsprintf (char* buf, const char* format, va_list ap); -char __fastcall__ getchar (void); -char* __fastcall__ gets (char* s); -int scanf (const char* format, ...); -int sscanf (const char* s, const char* format, ...); -int __fastcall__ vscanf (const char* format, va_list ap); -int __fastcall__ vsscanf (const char* s, const char* format, va_list ap); - -#endif - -// Display character definitions - -#define DISP_1 0x06 // '1' -#define DISP_2 0x5B // '2' -#define DISP_3 0x4F // '3' -#define DISP_4 0x66 // '4' -#define DISP_5 0x6D // '5' -#define DISP_6 0x7C // '6' -#define DISP_7 0x07 // '7' -#define DISP_8 0x7F // '8' -#define DISP_9 0x67 // '9' -#define DISP_0 0x3F // '0' -#define DISP_A 0x77 // 'A' -#define DISP_b 0x7C // 'b' -#define DISP_C 0x39 // 'C' -#define DISP_c 0x58 // 'c' -#define DISP_d 0x5E // 'd' -#define DISP_E 0x79 // 'E' -#define DISP_e 0x7B // 'e' -#define DISP_F 0x71 // 'F' -#define DISP_G 0x7D // 'G' -#define DISP_g 0x6F // 'g' -#define DISP_H 0x76 // 'H' -#define DISP_h 0x74 // 'h' -#define DISP_I 0x06 // 'I' -#define DISP_i 0x04 // 'i' -#define DISP_J 0x1E // 'J' -#define DISP_K 0x74 // 'K' -#define DISP_L 0x38 // 'L' -#define DISP_M_1 0x33 // 'M' -#define DISP_M_2 0x27 // 2nd half -#define DISP_n 0x54 // 'n' -#define DISP_O 0x3F // 'O' -#define DISP_o 0x5C // 'o' -#define DISP_P 0x73 // 'P' -#define DISP_q 0x67 // 'q' -#define DISP_r 0x50 // 'r' -#define DISP_S 0x6D // 'S' -#define DISP_t 0x46 // 't' -#define DISP_U 0x3E // 'U' -#define DISP_u 0x1C // 'u' -#define DISP_V_1 0x64 // 'V' -#define DISP_V_2 0x52 // 2nd half -#define DISP_W_1 0x3C // 'W' -#define DISP_W_2 0x1E // 2nd half -#define DISP_Y 0x6E // 'Y' -#define DISP_Z 0x5B // 'Z' -#define DISP_SPACE 0x00 // ' ' -#define DISP_PERIOD 0x80 // '.' -#define DISP_HYPHEN 0x40 // '-' -#define DISP_APOSTR 0x20 // ''' -#define DISP_EQUAL 0x41 // '=' -#define DISP_3_BAR 0x49 // '=' -#define DISP_BOTTOM 0x08 // '_' -#define DISP_TOP 0x01 // Top segment -#define DISP_LEFT 0x30 // '|' Left side, both segments -#define DISP_RIGHT 0x06 // '|' Right side, both segments -#define DISP_DEGREE 0x63 // 'o' An 'o' character in the upper segments -#define DISP_HAT 0x23 // 'n' An 'n' character in the upper segments -#define DISP_FORK 0x62 // 'u' A 'u' character in the upper segments -#define DISP_SLASH 0x51 // '/' -#define DISP_BACKSLASH 0x34 // '\' -#define DISP_TOP_RIGHT 0x02 // Top right segment -#define DISP_TOP_LEFT 0x20 // Top left segment -#define DISP_LOW_RIGHT 0x04 // Lower right segment -#define DISP_LOW_LEFT 0x10 // Lower left segment - -#endif diff --git a/libsrc/sym1/beep.s b/libsrc/sym1/beep.s index a1f978563..40a3d42c6 100644 --- a/libsrc/sym1/beep.s +++ b/libsrc/sym1/beep.s @@ -1,12 +1,8 @@ -; --------------------------------------------------------------------------- -; beep.s ; -; for Sym-1 +; Wayne Parham (wayne@parhamdata.com) ; -; Wayne Parham +; void beep (void); ; -; wayne@parhamdata.com -; --------------------------------------------------------------------------- .include "sym1.inc" @@ -15,10 +11,8 @@ .segment "CODE" .proc _beep: near -; --------------------------------------------------------------------------- + jsr BEEP ; Beep - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc diff --git a/libsrc/sym1/bitio.s b/libsrc/sym1/bitio.s index 5aa0fde8b..94cd9c5ad 100644 --- a/libsrc/sym1/bitio.s +++ b/libsrc/sym1/bitio.s @@ -1,12 +1,31 @@ -; --------------------------------------------------------------------------- -; bitio.s ; -; for Sym-1 +; Wayne Parham (wayne@parhamdata.com) ; -; Wayne Parham +; void set_DDR1A (int value); +; int get_DDR1A (void); +; void set_IOR1A (int value); +; int get_IOR1A (void); +; void set_DDR1B (int value); +; int get_DDR1B (void); +; void set_IOR1B (int value); +; int get_IOR1B (void); +; void set_DDR2A (int value); +; int get_DDR2A (void); +; void set_IOR2A (int value); +; int get_IOR2A (void); +; void set_DDR2B (int value); +; int get_DDR2B (void); +; void set_IOR2B (int value); +; int get_IOR2B (void); +; void set_DDR3A (int value); +; int get_DDR3A (void); +; void set_IOR3A (int value); +; int get_IOR3A (void); +; void set_DDR3B (int value); +; int get_DDR3B (void); +; void set_IOR3B (int value); +; int get_IOR3B (void); ; -; wayne@parhamdata.com -; --------------------------------------------------------------------------- .include "sym1.inc" @@ -20,211 +39,182 @@ .segment "CODE" .proc _set_DDR1A: near -; --------------------------------------------------------------------------- + sta DDR1A ; Write data direction register for port 1A - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_DDR1A: near -; --------------------------------------------------------------------------- + lda DDR1A ; Read data direction register for port 1A ldx #$00 ; rts ; Return DDR1A -; --------------------------------------------------------------------------- + .endproc .proc _set_IOR1A: near -; --------------------------------------------------------------------------- + sta OR1A ; Write I/O register for port 1A - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_IOR1A: near -; --------------------------------------------------------------------------- + lda OR1A ; Read I/O register for port 1A ldx #$00 ; rts ; Return OR1A -; --------------------------------------------------------------------------- + .endproc - .proc _set_DDR1B: near -; --------------------------------------------------------------------------- + sta DDR1B ; Write data direction register for port 1B - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_DDR1B: near -; --------------------------------------------------------------------------- + lda DDR1B ; Read data direction register for port 1B ldx #$00 ; rts ; Return DDR1B -; --------------------------------------------------------------------------- + .endproc .proc _set_IOR1B: near -; --------------------------------------------------------------------------- + sta OR1B ; Write I/O register for port 1B - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_IOR1B: near -; --------------------------------------------------------------------------- + lda OR1B ; Read I/O register for port 1B ldx #$00 ; rts ; Return OR1B -; --------------------------------------------------------------------------- + .endproc - .proc _set_DDR2A: near -; --------------------------------------------------------------------------- + sta DDR2A ; Write data direction register for port 2A - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_DDR2A: near -; --------------------------------------------------------------------------- + lda DDR2A ; Read data direction register for port 2A ldx #$00 ; rts ; Return DDR2A -; --------------------------------------------------------------------------- + .endproc .proc _set_IOR2A: near -; --------------------------------------------------------------------------- + sta OR2A ; Write I/O register for port 2A - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_IOR2A: near -; --------------------------------------------------------------------------- + lda OR2A ; Read I/O register for port 2A ldx #$00 ; rts ; Return OR2A -; --------------------------------------------------------------------------- + .endproc - .proc _set_DDR2B: near -; --------------------------------------------------------------------------- + sta DDR2B ; Write data direction register for port 2B - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_DDR2B: near -; --------------------------------------------------------------------------- + lda DDR2B ; Read data direction register for port 2B ldx #$00 ; rts ; Return DDR2B -; --------------------------------------------------------------------------- + .endproc .proc _set_IOR2B: near -; --------------------------------------------------------------------------- + sta OR2B ; Write I/O register for port 2B - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_IOR2B: near -; --------------------------------------------------------------------------- + lda OR2B ; Read I/O register for port 2B ldx #$00 ; rts ; Return OR2B -; --------------------------------------------------------------------------- + .endproc - .proc _set_DDR3A: near -; --------------------------------------------------------------------------- + sta DDR3A ; Write data direction register for port 3A - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_DDR3A: near -; --------------------------------------------------------------------------- + lda DDR3A ; Read data direction register for port 3A ldx #$00 ; rts ; Return DDR3A -; --------------------------------------------------------------------------- + .endproc .proc _set_IOR3A: near -; --------------------------------------------------------------------------- + sta OR3A ; Write I/O register for port 3A - lda #$00 ; - ldx #$00 ; rts ; Return 0000 -; --------------------------------------------------------------------------- + .endproc .proc _get_IOR3A: near -; --------------------------------------------------------------------------- + lda OR3A ; Read I/O register for port 3A ldx #$00 ; rts ; Return OR3A -; --------------------------------------------------------------------------- + .endproc - .proc _set_DDR3B: near -; --------------------------------------------------------------------------- + sta DDR3B ; Write data direction register for port 3B - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_DDR3B: near -; --------------------------------------------------------------------------- + lda DDR3B ; Read data direction register for port 3B ldx #$00 ; rts ; Return DDR3B -; --------------------------------------------------------------------------- + .endproc .proc _set_IOR3B: near -; --------------------------------------------------------------------------- + sta OR3B ; Write I/O register for port 3B - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_IOR3B: near -; --------------------------------------------------------------------------- + lda OR3B ; Read I/O register for port 3B ldx #$00 ; rts ; Return OR3B -; --------------------------------------------------------------------------- + .endproc diff --git a/libsrc/sym1/crt0.s b/libsrc/sym1/crt0.s index a85887991..47cc67f07 100644 --- a/libsrc/sym1/crt0.s +++ b/libsrc/sym1/crt0.s @@ -1,12 +1,6 @@ -; --------------------------------------------------------------------------- -; crt0.s ; -; for Sym-1 +; Startup code for cc65 (Sym-1 version) ; -; Wayne Parham -; -; wayne@parhamdata.com -; --------------------------------------------------------------------------- .export _init, _exit .export __STARTUP__ : absolute = 1 ; Mark as startup @@ -19,40 +13,40 @@ .include "zeropage.inc" .include "sym1.inc" -; --------------------------------------------------------------------------- + ; Place the startup code in a special segment .segment "STARTUP" -; --------------------------------------------------------------------------- + ; A little light housekeeping _init: jsr ACCESS ; Unlock System RAM cld ; Clear decimal mode -; --------------------------------------------------------------------------- + ; Turn off console echo lda TECHO and #$7F sta TECHO -; --------------------------------------------------------------------------- + ; Set cc65 argument stack pointer lda #<(__RAM_START__ + __RAM_SIZE__) sta sp lda #>(__RAM_START__ + __RAM_SIZE__) sta sp+1 -; --------------------------------------------------------------------------- + ; Initialize memory storage jsr zerobss ; Clear BSS segment jsr copydata ; Initialize DATA segment jsr initlib ; Run constructors -; --------------------------------------------------------------------------- + ; Call main() jsr _main -; --------------------------------------------------------------------------- + ; Back from main (this is also the _exit entry) _exit: jsr donelib ; Run destructors @@ -61,5 +55,5 @@ _exit: jsr donelib ; Run destructors sta TECHO jsr NACCES ; Lock System RAM rts ; Re-enter Sym-1 monitor -; --------------------------------------------------------------------------- + diff --git a/libsrc/sym1/display.s b/libsrc/sym1/display.s index 530435d87..a8572f1b0 100644 --- a/libsrc/sym1/display.s +++ b/libsrc/sym1/display.s @@ -1,12 +1,22 @@ -; --------------------------------------------------------------------------- -; display.s ; -; for Sym-1 +; Wayne Parham (wayne@parhamdata.com) ; -; Wayne Parham +; int fdisp (void); +; void set_D0 (char segments); +; int get_D0 (void); +; void set_D1 (char segments); +; int get_D1 (void); +; void set_D2 (char segments); +; int get_D2 (void); +; void set_D3 (char segments); +; int get_D3 (void); +; void set_D4 (char segments); +; int get_D4 (void); +; void set_D5 (char segments); +; int get_D5 (void); +; void set_D6 (char segments); +; int get_D6 (void); ; -; wayne@parhamdata.com -; --------------------------------------------------------------------------- .include "sym1.inc" @@ -18,137 +28,114 @@ .segment "CODE" .proc _fdisp: near -; --------------------------------------------------------------------------- + jsr SCAND ; Flash Display - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc - .proc _set_D0: near -; --------------------------------------------------------------------------- + sta DISBUF0 ; Write Digit 0 - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_D0: near -; --------------------------------------------------------------------------- + lda DISBUF0 ; Read Digit 0 ldx #$00 ; rts ; Return DISBUF0 -; --------------------------------------------------------------------------- + .endproc - .proc _set_D1: near -; --------------------------------------------------------------------------- + sta DISBUF1 ; Write Digit 1 - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_D1: near -; --------------------------------------------------------------------------- + lda DISBUF1 ; Read Digit 1 ldx #$00 ; - rts ; Return DISBUF1 -; --------------------------------------------------------------------------- + rts + .endproc - .proc _set_D2: near -; --------------------------------------------------------------------------- + sta DISBUF2 ; Write Digit 2 - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_D2: near -; --------------------------------------------------------------------------- + lda DISBUF2 ; Read Digit 2 ldx #$00 ; rts ; Return DISBUF2 -; --------------------------------------------------------------------------- + .endproc - .proc _set_D3: near -; --------------------------------------------------------------------------- + sta DISBUF3 ; Write Digit 3 - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_D3: near -; --------------------------------------------------------------------------- + lda DISBUF3 ; Read Digit 3 ldx #$00 ; rts ; Return DISBUF3 -; --------------------------------------------------------------------------- + .endproc - .proc _set_D4: near -; --------------------------------------------------------------------------- + sta DISBUF4 ; Write Digit 4 - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_D4: near -; --------------------------------------------------------------------------- + lda DISBUF4 ; Read Digit 4 ldx #$00 ; rts ; Return DISBUF4 -; --------------------------------------------------------------------------- + .endproc - .proc _set_D5: near -; --------------------------------------------------------------------------- + sta DISBUF5 ; Write Digit 5 - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_D5: near -; --------------------------------------------------------------------------- + lda DISBUF5 ; Read Digit 5 ldx #$00 ; rts ; Return DISBUF5 -; --------------------------------------------------------------------------- + .endproc - .proc _set_D6: near -; --------------------------------------------------------------------------- + sta DISBUF6 ; Write byte to the right of display - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- + rts + .endproc .proc _get_D6: near -; --------------------------------------------------------------------------- + lda DISBUF6 ; Read byte to the right of display ldx #$00 ; rts ; Return DISBUF6 -; --------------------------------------------------------------------------- + .endproc diff --git a/libsrc/sym1/getchar.s b/libsrc/sym1/getchar.s deleted file mode 100644 index d82519ce0..000000000 --- a/libsrc/sym1/getchar.s +++ /dev/null @@ -1,21 +0,0 @@ -; --------------------------------------------------------------------------- -; getchar.s -; -; for Sym-1 -; -; Wayne Parham -; --------------------------------------------------------------------------- - -.include "sym1.inc" -.export _getchar - -.segment "CODE" - -.proc _getchar: near -; --------------------------------------------------------------------------- - jsr INTCHR ; Get character using Monitor ROM call - and #$7F ; Strip off top bit - ldx #$00 ; - rts ; Return char -; --------------------------------------------------------------------------- -.endproc diff --git a/libsrc/sym1/putchar.s b/libsrc/sym1/putchar.s deleted file mode 100644 index 1b84416fe..000000000 --- a/libsrc/sym1/putchar.s +++ /dev/null @@ -1,23 +0,0 @@ -; --------------------------------------------------------------------------- -; putchar.s -; -; for Sym-1 -; -; Wayne Parham -; -; wayne@parhamdata.com -; --------------------------------------------------------------------------- - -.include "sym1.inc" -.export _putchar - -.segment "CODE" - -.proc _putchar: near -; --------------------------------------------------------------------------- - jsr OUTCHR ; Send character using Monitor ROM call - lda #$00 ; - ldx #$00 ; - rts ; Return 0000 -; --------------------------------------------------------------------------- -.endproc diff --git a/libsrc/sym1/read.s b/libsrc/sym1/read.s index f0b0194d2..7ab88f1e8 100644 --- a/libsrc/sym1/read.s +++ b/libsrc/sym1/read.s @@ -1,12 +1,8 @@ -; --------------------------------------------------------------------------- -; read.s ; -; for Sym-1 +; Wayne Parham (wayne@parhamdata.com) ; -; Wayne Parham +; int read (int fd, void* buf, unsigned count); ; -; wayne@parhamdata.com -; --------------------------------------------------------------------------- .include "sym1.inc" @@ -16,7 +12,7 @@ .export _read .proc _read -; --------------------------------------------------------------------------- + sta ptr3 stx ptr3+1 ; Count in ptr3 inx @@ -49,6 +45,6 @@ putch: ldy #$00 ; Put char into return buffer done: lda ptr3 ldx ptr3+1 rts ; Return count -; --------------------------------------------------------------------------- + .endproc diff --git a/libsrc/sym1/tapeio.s b/libsrc/sym1/tapeio.s index 3a0c1fa5b..85c9c6fcc 100644 --- a/libsrc/sym1/tapeio.s +++ b/libsrc/sym1/tapeio.s @@ -1,12 +1,9 @@ -; --------------------------------------------------------------------------- -; tapeio.s ; -; for Sym-1 +; Wayne Parham (wayne@parhamdata.com) ; -; Wayne Parham +; int loadt (int id); +; int dumpt (int id, int start_addr, int end_addr); ; -; wayne@parhamdata.com -; --------------------------------------------------------------------------- .include "sym1.inc" @@ -17,7 +14,7 @@ .segment "CODE" .proc _loadt: near -; --------------------------------------------------------------------------- + sta P1L ; Tape record ID to P1L ldx #$00 stx P1H @@ -30,11 +27,11 @@ error: ldx #$00 lda #$FF ; or 00FF if not done: rts -; --------------------------------------------------------------------------- + .endproc .proc _dumpt: near -; --------------------------------------------------------------------------- + sta P3L ; End address stx P3H jsr popax @@ -53,6 +50,6 @@ done: rts error: ldx #$00 lda #$FF ; or 00FF if not done: rts -; --------------------------------------------------------------------------- + .endproc diff --git a/libsrc/sym1/write.s b/libsrc/sym1/write.s index 843dddf1f..f7eb4c55e 100644 --- a/libsrc/sym1/write.s +++ b/libsrc/sym1/write.s @@ -1,12 +1,8 @@ -; --------------------------------------------------------------------------- -; write.s ; -; for Sym-1 +; Wayne Parham (wayne@parhamdata.com) ; -; Wayne Parham +; int write (int fd, const void* buf, int count); ; -; wayne@parhamdata.com -; --------------------------------------------------------------------------- .include "sym1.inc" @@ -16,7 +12,7 @@ .export _write .proc _write -; --------------------------------------------------------------------------- + sta ptr3 stx ptr3+1 ; Count in ptr3 inx @@ -48,6 +44,6 @@ next: inc ptr1 done: lda ptr3 ldx ptr3+1 rts ; Return count -; --------------------------------------------------------------------------- + .endproc diff --git a/samples/symDisplay.c b/samples/symDisplay.c index fa94ce598..23df1e805 100644 --- a/samples/symDisplay.c +++ b/samples/symDisplay.c @@ -6,7 +6,8 @@ // wayne@parhamdata.com // -------------------------------------------------------------------------- -#include <symio.h> +#include <stdio.h> +#include <sym1.h> void main (void) { int delay = 10; diff --git a/samples/symHello.c b/samples/symHello.c index 99b4c57df..99a7745da 100644 --- a/samples/symHello.c +++ b/samples/symHello.c @@ -6,7 +6,8 @@ // wayne@parhamdata.com // -------------------------------------------------------------------------- -#include <symio.h>; +#include <stdio.h> +#include <sym1.h> void main(void) { char c = 0x00; diff --git a/samples/symIO.c b/samples/symIO.c index d887c18b9..1e93e941a 100644 --- a/samples/symIO.c +++ b/samples/symIO.c @@ -6,10 +6,10 @@ // wayne@parhamdata.com // -------------------------------------------------------------------------- -#include <stdio.h>; -#include <symio.h>; -#include <stdlib.h>; -#include <string.h>; +#include <sym1.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> void main(void) { int ddr1a = 0x00; diff --git a/samples/symNotepad.c b/samples/symNotepad.c index bc28ef4b5..79d621223 100644 --- a/samples/symNotepad.c +++ b/samples/symNotepad.c @@ -12,9 +12,10 @@ // // -------------------------------------------------------------------------- -#include <symio.h>; -#include <stdlib.h>; -#include <string.h>; +#include <sym1.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> #define TAPIO_ADDRESS 0xE000 #define TAPIO_MAX_SIZE 0x0FFF diff --git a/samples/symTiny.c b/samples/symTiny.c index b82e952ac..4d03338e6 100644 --- a/samples/symTiny.c +++ b/samples/symTiny.c @@ -8,7 +8,8 @@ // wayne@parhamdata.com // -------------------------------------------------------------------------- -#include <symio.h>; +#include <stdio.h> +#include <sym1.h> void main(void) { char c = 0x00; From 64afb50d5a3002497633ec49aa952496da0e9632 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Sun, 6 Jun 2021 21:45:58 -0500 Subject: [PATCH 2088/2161] Makefile changes --- libsrc/Makefile | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/libsrc/Makefile b/libsrc/Makefile index eee18d0da..fc07862e6 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -149,26 +149,18 @@ GEOSDIRS = common \ runtime \ system -# MACHINE set independently of TARGET lets us easily define new targets -# without changing target.h and target.c in cc65/src/common. Useful -# for initial testing of ports to new systems. - ifeq ($(TARGET),apple2enh) SRCDIR = apple2 OBJPFX = a2 DRVPFX = a2e - MACHINE = $(TARGET) else ifeq ($(TARGET),atarixl) SRCDIR = atari OBJPFX = atr DRVPFX = atrx - MACHINE = $(TARGET) else ifeq ($(TARGET),sim65c02) SRCDIR = sim6502 - MACHINE = $(TARGET) else SRCDIR = $(TARGET) - MACHINE = $(TARGET) endif SRCDIRS = $(SRCDIR) @@ -182,26 +174,16 @@ ifeq ($(TARGET),$(filter $(TARGET),$(GEOS))) SRCDIRS += $(addprefix geos-common/,$(GEOSDIRS)) endif -ifeq ($(TARGET),sym1) - SRCDIRS += common \ - conio \ - dbg \ - em \ - runtime \ - serial \ - sym1 -else - SRCDIRS += common \ - conio \ - dbg \ - em \ - joystick \ - mouse \ - runtime \ - serial \ - tgi \ - zlib -endif +SRCDIRS += common \ + conio \ + dbg \ + em \ + joystick \ + mouse \ + runtime \ + serial \ + tgi \ + zlib vpath %.s $(SRCDIRS) vpath %.c $(SRCDIRS) From 9d509735a8fff81c4f94cb343102540293540c23 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Sun, 6 Jun 2021 21:56:23 -0500 Subject: [PATCH 2089/2161] Makefile changes --- libsrc/Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libsrc/Makefile b/libsrc/Makefile index fc07862e6..60946b59f 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -232,7 +232,7 @@ $1_DRVS = $$(patsubst $$($1_DYNPAT),$$($1_DRVPAT),$$($1_DYNS)) $$($1_STCPAT): $$($1_SRCPAT) @echo $$(TARGET) - $$< - static - @$$(CA65) -t $$(MACHINE) -D DYN_DRV=0 $$(CA65FLAGS) --create-dep $$(@:.o=.d) -o $$@ $$< + @$$(CA65) -t $$(TARGET) -D DYN_DRV=0 $$(CA65FLAGS) --create-dep $$(@:.o=.d) -o $$@ $$< OBJS += $$($1_STCS) DEPS += $$($1_STCS:.o=.d) @@ -264,15 +264,15 @@ export CC65_HOME := $(abspath ..) define ASSEMBLE_recipe $(if $(QUIET),,@echo $(TARGET) - $<) -@$(CA65) -t $(MACHINE) $(CA65FLAGS) --create-dep $(@:.o=.d) -o $@ $< +@$(CA65) -t $(TARGET) $(CA65FLAGS) --create-dep $(@:.o=.d) -o $@ $< endef # ASSEMBLE_recipe define COMPILE_recipe $(if $(QUIET),,@echo $(TARGET) - $<) -@$(CC65) -t $(MACHINE) $(CC65FLAGS) --create-dep $(@:.o=.d) --dep-target $@ -o $(@:.o=.s) $< -@$(CA65) -t $(MACHINE) -o $@ $(@:.o=.s) +@$(CC65) -t $(TARGET) $(CC65FLAGS) --create-dep $(@:.o=.d) --dep-target $@ -o $(@:.o=.s) $< +@$(CA65) -t $(TARGET) -o $@ $(@:.o=.s) endef # COMPILE_recipe @@ -284,7 +284,7 @@ endef # COMPILE_recipe $(EXTRA_OBJPAT): $(EXTRA_SRCPAT) | ../libwrk/$(TARGET) ../lib @echo $(TARGET) - $(<F) - @$(CA65) -t $(MACHINE) $(CA65FLAGS) --create-dep $(@:../lib/%.o=../libwrk/$(TARGET)/%.d) -o $@ $< + @$(CA65) -t $(TARGET) $(CA65FLAGS) --create-dep $(@:../lib/%.o=../libwrk/$(TARGET)/%.d) -o $@ $< ../lib/$(TARGET).lib: $(OBJS) | ../lib $(AR65) a $@ $? From 33af3d79975d7b8b2b9bf381ab7193ef1df38561 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Sun, 6 Jun 2021 23:53:53 -0500 Subject: [PATCH 2090/2161] sym1.h updates --- include/sym1.h | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/include/sym1.h b/include/sym1.h index 0a919f84d..4fb66b251 100644 --- a/include/sym1.h +++ b/include/sym1.h @@ -100,53 +100,53 @@ int __fastcall__ beep (void); // Beep sound void __fastcall__ set_D0 (unsigned char); // Set display digit 0 -int __fastcall__ get_D0 (void); // Get value of display digit 0 +unsigned char __fastcall__ get_D0 (void); // Get value of display digit 0 void __fastcall__ set_D1 (unsigned char); // Set display digit 1 -int __fastcall__ get_D1 (void); // Get value of display digit 1 +unsigned char __fastcall__ get_D1 (void); // Get value of display digit 1 void __fastcall__ set_D2 (unsigned char); // Set display digit 2 -int __fastcall__ get_D2 (void); // Get value of display digit 2 +unsigned char __fastcall__ get_D2 (void); // Get value of display digit 2 void __fastcall__ set_D3 (unsigned char); // Set display digit 3 -int __fastcall__ get_D3 (void); // Get value of display digit 3 +unsigned char __fastcall__ get_D3 (void); // Get value of display digit 3 void __fastcall__ set_D4 (unsigned char); // Set display digit 4 -int __fastcall__ get_D4 (void); // Get value of display digit 4 +unsigned char __fastcall__ get_D4 (void); // Get value of display digit 4 void __fastcall__ set_D5 (unsigned char); // Set display digit 5 -int __fastcall__ get_D5 (void); // Get value of display digit 5 +unsigned char __fastcall__ get_D5 (void); // Get value of display digit 5 void __fastcall__ set_D6 (unsigned char); // Set byte to the right of display (leading buffer) -int __fastcall__ get_D6 (void); // Get value of memory byte to the right of display +unsigned char __fastcall__ get_D6 (void); // Get value of memory byte to the right of display void __fastcall__ fdisp (void); // Flash display int __fastcall__ loadt (int); // Read from tape (id) int __fastcall__ dumpt (int, int, int); // Write to tape (id, start_addr, end_addr) void __fastcall__ set_DDR1A (unsigned char); // Set data direction register 1A (U25) -int __fastcall__ get_DDR1A (void); // Get value of data direction register 1A +unsigned char __fastcall__ get_DDR1A (void); // Get value of data direction register 1A void __fastcall__ set_IOR1A (unsigned char); // Set I/O register 1A -int __fastcall__ get_IOR1A (void); // Get value of I/O register 1A +unsigned char __fastcall__ get_IOR1A (void); // Get value of I/O register 1A void __fastcall__ set_DDR1B (unsigned char); // Set data direction register 1B (U25) -int __fastcall__ get_DDR1B (void); // Get value of data direction register 1B +unsigned char __fastcall__ get_DDR1B (void); // Get value of data direction register 1B void __fastcall__ set_IOR1B (unsigned char); // Set I/O register 1B -int __fastcall__ get_IOR1B (void); // Get value of I/O register 1B +unsigned char __fastcall__ get_IOR1B (void); // Get value of I/O register 1B void __fastcall__ set_DDR2A (unsigned char); // Set data direction register 2A (U28) -int __fastcall__ get_DDR2A (void); // Get value of data direction register 2A +unsigned char __fastcall__ get_DDR2A (void); // Get value of data direction register 2A void __fastcall__ set_IOR2A (unsigned char); // Set I/O register 2A -int __fastcall__ get_IOR2A (void); // Get value of I/O register 2A +unsigned char __fastcall__ get_IOR2A (void); // Get value of I/O register 2A void __fastcall__ set_DDR2B (unsigned char); // Set data direction register 2B (U28) -int __fastcall__ get_DDR2B (void); // Get value of data direction register 2B +unsigned char __fastcall__ get_DDR2B (void); // Get value of data direction register 2B void __fastcall__ set_IOR2B (unsigned char); // Set I/O register 2B -int __fastcall__ get_IOR2B (void); // Get value of I/O register 2B +unsigned char __fastcall__ get_IOR2B (void); // Get value of I/O register 2B void __fastcall__ set_DDR3A (unsigned char); // Set data direction register 3A (U29) -int __fastcall__ get_DDR3A (void); // Get value of data direction register 3A +unsigned char __fastcall__ get_DDR3A (void); // Get value of data direction register 3A void __fastcall__ set_IOR3A (unsigned char); // Set I/O register 3A -int __fastcall__ get_IOR3A (void); // Get value of I/O register 3A +unsigned char __fastcall__ get_IOR3A (void); // Get value of I/O register 3A void __fastcall__ set_DDR3B (unsigned char); // Set data direction register 3B (U29) -int __fastcall__ get_DDR3B (void); // Get value of data direction register 3B +unsigned char __fastcall__ get_DDR3B (void); // Get value of data direction register 3B void __fastcall__ set_IOR3B (unsigned char); // Set I/O register 3B -int __fastcall__ get_IOR3B (void); // Get value of I/O register 3B +unsigned char __fastcall__ get_IOR3B (void); // Get value of I/O register 3B From 0bbff54378bec65843214a786a60684fc6af67bd Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Mon, 7 Jun 2021 00:03:44 -0500 Subject: [PATCH 2091/2161] return val updates --- libsrc/sym1/bitio.s | 24 ++++++++++++------------ libsrc/sym1/display.s | 14 +++++++------- libsrc/sym1/tapeio.s | 4 ++-- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/libsrc/sym1/bitio.s b/libsrc/sym1/bitio.s index 94cd9c5ad..a61dd4800 100644 --- a/libsrc/sym1/bitio.s +++ b/libsrc/sym1/bitio.s @@ -48,7 +48,7 @@ .proc _get_DDR1A: near lda DDR1A ; Read data direction register for port 1A - ldx #$00 ; + ldx #>$0000 ; rts ; Return DDR1A .endproc @@ -63,7 +63,7 @@ .proc _get_IOR1A: near lda OR1A ; Read I/O register for port 1A - ldx #$00 ; + ldx #>$0000 ; rts ; Return OR1A .endproc @@ -78,7 +78,7 @@ .proc _get_DDR1B: near lda DDR1B ; Read data direction register for port 1B - ldx #$00 ; + ldx #>$0000 ; rts ; Return DDR1B .endproc @@ -93,7 +93,7 @@ .proc _get_IOR1B: near lda OR1B ; Read I/O register for port 1B - ldx #$00 ; + ldx #>$0000 ; rts ; Return OR1B .endproc @@ -108,7 +108,7 @@ .proc _get_DDR2A: near lda DDR2A ; Read data direction register for port 2A - ldx #$00 ; + ldx #>$0000 ; rts ; Return DDR2A .endproc @@ -123,7 +123,7 @@ .proc _get_IOR2A: near lda OR2A ; Read I/O register for port 2A - ldx #$00 ; + ldx #>$0000 ; rts ; Return OR2A .endproc @@ -138,7 +138,7 @@ .proc _get_DDR2B: near lda DDR2B ; Read data direction register for port 2B - ldx #$00 ; + ldx #>$0000 ; rts ; Return DDR2B .endproc @@ -153,7 +153,7 @@ .proc _get_IOR2B: near lda OR2B ; Read I/O register for port 2B - ldx #$00 ; + ldx #>$0000 ; rts ; Return OR2B .endproc @@ -168,7 +168,7 @@ .proc _get_DDR3A: near lda DDR3A ; Read data direction register for port 3A - ldx #$00 ; + ldx #>$0000 ; rts ; Return DDR3A .endproc @@ -183,7 +183,7 @@ .proc _get_IOR3A: near lda OR3A ; Read I/O register for port 3A - ldx #$00 ; + ldx #>$0000 ; rts ; Return OR3A .endproc @@ -198,7 +198,7 @@ .proc _get_DDR3B: near lda DDR3B ; Read data direction register for port 3B - ldx #$00 ; + ldx #>$0000 ; rts ; Return DDR3B .endproc @@ -213,7 +213,7 @@ .proc _get_IOR3B: near lda OR3B ; Read I/O register for port 3B - ldx #$00 ; + ldx #>$0000 ; rts ; Return OR3B .endproc diff --git a/libsrc/sym1/display.s b/libsrc/sym1/display.s index a8572f1b0..9bef30c01 100644 --- a/libsrc/sym1/display.s +++ b/libsrc/sym1/display.s @@ -44,7 +44,7 @@ .proc _get_D0: near lda DISBUF0 ; Read Digit 0 - ldx #$00 ; + ldx #>$0000 ; rts ; Return DISBUF0 .endproc @@ -59,7 +59,7 @@ .proc _get_D1: near lda DISBUF1 ; Read Digit 1 - ldx #$00 ; + ldx #>$0000 ; rts .endproc @@ -74,7 +74,7 @@ .proc _get_D2: near lda DISBUF2 ; Read Digit 2 - ldx #$00 ; + ldx #>$0000 ; rts ; Return DISBUF2 .endproc @@ -89,7 +89,7 @@ .proc _get_D3: near lda DISBUF3 ; Read Digit 3 - ldx #$00 ; + ldx #>$0000 ; rts ; Return DISBUF3 .endproc @@ -104,7 +104,7 @@ .proc _get_D4: near lda DISBUF4 ; Read Digit 4 - ldx #$00 ; + ldx #>$0000 ; rts ; Return DISBUF4 .endproc @@ -119,7 +119,7 @@ .proc _get_D5: near lda DISBUF5 ; Read Digit 5 - ldx #$00 ; + ldx #>$0000 ; rts ; Return DISBUF5 .endproc @@ -134,7 +134,7 @@ .proc _get_D6: near lda DISBUF6 ; Read byte to the right of display - ldx #$00 ; + ldx #>$0000 ; rts ; Return DISBUF6 .endproc diff --git a/libsrc/sym1/tapeio.s b/libsrc/sym1/tapeio.s index 85c9c6fcc..e956b6eee 100644 --- a/libsrc/sym1/tapeio.s +++ b/libsrc/sym1/tapeio.s @@ -24,7 +24,7 @@ lda #$00 ldx #$00 ; Return 0000 if successful jmp done -error: ldx #$00 +error: ldx #>$0000 lda #$FF ; or 00FF if not done: rts @@ -47,7 +47,7 @@ done: rts lda #$00 ldx #$00 ; Return 0000 if successful jmp done -error: ldx #$00 +error: ldx #>$0000 lda #$FF ; or 00FF if not done: rts From c961782192f15c4f2099e526d8babcffcabd07fd Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Mon, 7 Jun 2021 00:07:09 -0500 Subject: [PATCH 2092/2161] Removed libref.s --- libsrc/sym1/libref.s | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 libsrc/sym1/libref.s diff --git a/libsrc/sym1/libref.s b/libsrc/sym1/libref.s deleted file mode 100644 index 9356d18dc..000000000 --- a/libsrc/sym1/libref.s +++ /dev/null @@ -1,3 +0,0 @@ - - .import _exit - From dc9333a3bbeef7d07535a505120af0205824d0c0 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Mon, 7 Jun 2021 00:18:26 -0500 Subject: [PATCH 2093/2161] tapeio.s updates --- libsrc/sym1/tapeio.s | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/libsrc/sym1/tapeio.s b/libsrc/sym1/tapeio.s index e956b6eee..dbb6963ca 100644 --- a/libsrc/sym1/tapeio.s +++ b/libsrc/sym1/tapeio.s @@ -7,7 +7,7 @@ .include "sym1.inc" -.import popax +.import popax, return0, return1 .export _loadt, _dumpt @@ -21,12 +21,8 @@ ldy #$80 jsr LOADT ; Read data from tape bcs error - lda #$00 - ldx #$00 ; Return 0000 if successful - jmp done -error: ldx #>$0000 - lda #$FF ; or 00FF if not -done: rts + jmp return 0 ; Return 0 if sucessful +error: jmp return 1 ; or 1 if not .endproc @@ -44,12 +40,8 @@ done: rts ldy #$80 jsr DUMPT ; Write data to tape bcs error - lda #$00 - ldx #$00 ; Return 0000 if successful - jmp done -error: ldx #>$0000 - lda #$FF ; or 00FF if not -done: rts + jmp return 0 ; Return 0 if sucessful +error: jmp return 1 ; or 1 if not .endproc From 88ee45e9ef33d88cd95ec0cb03bc22a29c53ba26 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Mon, 7 Jun 2021 00:35:20 -0500 Subject: [PATCH 2094/2161] tapeio.s updates --- libsrc/sym1/tapeio.s | 8 ++++---- samples/helloworld.c | 9 --------- 2 files changed, 4 insertions(+), 13 deletions(-) delete mode 100644 samples/helloworld.c diff --git a/libsrc/sym1/tapeio.s b/libsrc/sym1/tapeio.s index dbb6963ca..19eeb2444 100644 --- a/libsrc/sym1/tapeio.s +++ b/libsrc/sym1/tapeio.s @@ -21,8 +21,8 @@ ldy #$80 jsr LOADT ; Read data from tape bcs error - jmp return 0 ; Return 0 if sucessful -error: jmp return 1 ; or 1 if not + jmp return0 ; Return 0 if sucessful +error: jmp return1 ; or 1 if not .endproc @@ -40,8 +40,8 @@ error: jmp return 1 ; or 1 if not ldy #$80 jsr DUMPT ; Write data to tape bcs error - jmp return 0 ; Return 0 if sucessful -error: jmp return 1 ; or 1 if not + jmp return0 ; Return 0 if sucessful +error: jmp return1 ; or 1 if not .endproc diff --git a/samples/helloworld.c b/samples/helloworld.c deleted file mode 100644 index 057a153e8..000000000 --- a/samples/helloworld.c +++ /dev/null @@ -1,9 +0,0 @@ -// Traditional "Hello World" program - -#include <stdio.h> - -void main (void) -{ - printf( "Hello World!\n" ); - return; -} From a3fce656b7c8761346a2b565046f9a371413ca3f Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Mon, 7 Jun 2021 00:42:13 -0500 Subject: [PATCH 2095/2161] Samples updates --- samples/Makefile | 23 +++++------------------ samples/helloworld.c | 8 ++++++++ 2 files changed, 13 insertions(+), 18 deletions(-) create mode 100644 samples/helloworld.c diff --git a/samples/Makefile b/samples/Makefile index 0cd867054..c8c02dbe3 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -8,10 +8,6 @@ # var. to build for another target system. SYS ?= c64 -# New targets can define MACHINE separately -# from target if needed. -MACHINE=$(SYS) - # Just the usual way to define a variable # containing a single space character. SPACE := @@ -139,21 +135,19 @@ LDFLAGS_tgidemo_atarixl = --start-addr 0x4000 %: %.s .c.o: - $(CC) $(CFLAGS) -Ors --codesize 500 -T -g -t $(MACHINE) $< + $(CC) $(CFLAGS) -Ors --codesize 500 -T -g -t $(SYS) $< $(AS) $(<:.c=.s) .s.o: - $(AS) $(ASFLAGS) -t $(MACHINE) $< + $(AS) $(ASFLAGS) -t $(SYS) $< .PRECIOUS: %.o .o: ifeq ($(SYS),vic20) $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -C vic20-32k.cfg -m $@.map $^ $(SYS).lib -else ifeq ($(SYS),sym1) - $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@.bin -C sym1.cfg -m $@.map $^ $(SYS).lib else - $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(MACHINE) -m $@.map $^ $(SYS).lib + $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib endif # -------------------------------------------------------------------------- @@ -161,9 +155,7 @@ endif # disasm depends on cpp -ifneq ($(SYS),sym1) - DIRLIST = tutorial geos -endif +DIRLIST = tutorial geos # -------------------------------------------------------------------------- # Lists of executables @@ -276,12 +268,10 @@ EXELIST_gamate = \ hello EXELIST_geos-cbm = \ - helloworld \ ascii \ diodemo EXELIST_geos-apple = \ - helloworld \ ascii EXELIST_lunix = \ @@ -322,10 +312,7 @@ EXELIST_supervision = \ supervisionhello EXELIST_sym1 = \ - helloworld \ - symHello \ - symTiny \ - symDisplay + helloworld EXELIST_telestrat = \ ascii \ diff --git a/samples/helloworld.c b/samples/helloworld.c new file mode 100644 index 000000000..9aa4197d8 --- /dev/null +++ b/samples/helloworld.c @@ -0,0 +1,8 @@ +// Traditional "Hello World" program + +#include <stdio.h> + +int main() { + printf("Hello, World!"); + return 0; +} From 975e43892ff05462eeb23be37165c77247aba871 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Mon, 7 Jun 2021 00:48:02 -0500 Subject: [PATCH 2096/2161] Samples cleanup --- samples/symDisplay.c | 361 ------------------------------------- samples/symHello.c | 40 ---- samples/symIO.c | 170 ----------------- samples/symNotepad.c | 200 -------------------- samples/symTiny.c | 43 ----- targettest/sym1/build | 36 ---- targettest/sym1/build_32k | 36 ---- targettest/sym1/build_4k | 36 ---- targettest/sym1/clean | 14 -- targettest/sym1/readme.txt | 11 -- 10 files changed, 947 deletions(-) delete mode 100644 samples/symDisplay.c delete mode 100644 samples/symHello.c delete mode 100644 samples/symIO.c delete mode 100644 samples/symNotepad.c delete mode 100644 samples/symTiny.c delete mode 100644 targettest/sym1/build delete mode 100644 targettest/sym1/build_32k delete mode 100644 targettest/sym1/build_4k delete mode 100644 targettest/sym1/clean delete mode 100644 targettest/sym1/readme.txt diff --git a/samples/symDisplay.c b/samples/symDisplay.c deleted file mode 100644 index 23df1e805..000000000 --- a/samples/symDisplay.c +++ /dev/null @@ -1,361 +0,0 @@ -// -------------------------------------------------------------------------- -// Sym-1 front panel display example -// -// Wayne Parham -// -// wayne@parhamdata.com -// -------------------------------------------------------------------------- - -#include <stdio.h> -#include <sym1.h> - -void main (void) { - int delay = 10; - int flashes = 255; - int displayable = 1; - int e = 0; - int r = 0; - int d = 0; - int i = 0; - int l = 0; - int t = 0; - int z = 0; - char c = 0x00; - char buffer[41] = { 0x00 }; - - puts( "\nType a message (40 chars max) and press ENTER, please:\n" ); - - while( (c != '\r') && (i < 41) ) { - c = getchar(); - putchar( c ); - buffer[i] = c; - i++; - if( i == 40 ) { - puts( "\n\n--- Reached 40 character limit. ---" ); - } - } - - i--; // index is one past end - - while( z == 0 ) { - puts( "\n\nHow many times (0 for forever) to repeat?" ); - c = getchar(); - putchar( c ); - if( (c >= '0') && (c <= '9') ) { // between 1 and 9 loops allowed - z = 1; // a number was pressed - t = c - '0'; // convert char to int - puts( "\n\nLook at the front panel.\n" ); - } - else { - puts( "\nWhat?" ); - z = 0; // keep asking for a number - } - } - - z = 0; - while( (z < t) || (t == 0) ) { - - z++; - - putchar( '\r' ); // Send CR to console - - - set_D0( DISP_SPACE ); // Clear the display - set_D1( DISP_SPACE ); - set_D2( DISP_SPACE ); - set_D3( DISP_SPACE ); - set_D4( DISP_SPACE ); - set_D5( DISP_SPACE ); - set_D6( DISP_SPACE ); - - for( d = 0; d < flashes ; d++ ) { - fdisp(); // Display - } - - for( l = 0; l <= i; l++ ) { - - displayable = 1; // Assume character is mapped - - switch( buffer[l] ) { // Put the typed charaters - case '1': // into the display buffer - set_D6( DISP_1 ); // one at a time - break; - case '2': - set_D6( DISP_2 ); - break; - case '3': - set_D6( DISP_3 ); - break; - case '4': - set_D6( DISP_4 ); - break; - case '5': - set_D6( DISP_5 ); - break; - case '6': - set_D6( DISP_6 ); - break; - case '7': - set_D6( DISP_7 ); - break; - case '8': - set_D6( DISP_8 ); - break; - case '9': - set_D6( DISP_9 ); - break; - case '0': - set_D6( DISP_0 ); - break; - case 'A': - set_D6( DISP_A ); - break; - case 'a': - set_D6( DISP_A ); - break; - case 'B': - set_D6( DISP_b ); - break; - case 'b': - set_D6( DISP_b ); - break; - case 'C': - set_D6( DISP_C ); - break; - case 'c': - set_D6( DISP_c ); - break; - case 'D': - set_D6( DISP_d ); - break; - case 'd': - set_D6( DISP_d ); - break; - case 'E': - set_D6( DISP_E ); - break; - case 'e': - set_D6( DISP_e ); - break; - case 'F': - set_D6( DISP_F ); - break; - case 'f': - set_D6( DISP_F ); - break; - case 'G': - set_D6( DISP_G ); - break; - case 'g': - set_D6( DISP_g ); - break; - case 'H': - set_D6( DISP_H ); - break; - case 'h': - set_D6( DISP_h ); - break; - case 'I': - set_D6( DISP_I ); - break; - case 'i': - set_D6( DISP_i ); - break; - case 'J': - set_D6( DISP_J ); - break; - case 'j': - set_D6( DISP_J ); - break; - case 'K': - set_D6( DISP_K ); - break; - case 'k': - set_D6( DISP_K ); - break; - case 'L': - set_D6( DISP_L ); - break; - case 'l': - set_D6( DISP_L ); - break; - case 'M': - set_D0( get_D1() ); - set_D1( get_D2() ); - set_D2( get_D3() ); - set_D3( get_D4() ); - set_D4( get_D5() ); - set_D5( DISP_M_1 ); - set_D6( DISP_M_2 ); - break; - case 'm': - set_D0( get_D1() ); - set_D1( get_D2() ); - set_D2( get_D3() ); - set_D3( get_D4() ); - set_D4( get_D5() ); - set_D5( DISP_M_1 ); - set_D6( DISP_M_2 ); - break; - case 'N': - set_D6( DISP_n ); - break; - case 'n': - set_D6( DISP_n ); - break; - case 'O': - set_D6( DISP_O ); - break; - case 'o': - set_D6( DISP_o ); - break; - case 'P': - set_D6( DISP_P ); - break; - case 'p': - set_D6( DISP_P ); - break; - case 'Q': - set_D6( DISP_q ); - break; - case 'q': - set_D6( DISP_q ); - break; - case 'R': - set_D6( DISP_r ); - break; - case 'r': - set_D6( DISP_r ); - break; - case 'S': - set_D6( DISP_S ); - break; - case 's': - set_D6( DISP_S ); - break; - case 'T': - set_D6( DISP_t ); - break; - case 't': - set_D6( DISP_t ); - break; - case 'U': - set_D6( DISP_U ); - break; - case 'u': - set_D6( DISP_u ); - break; - case 'V': - set_D0( get_D1() ); - set_D1( get_D2() ); - set_D2( get_D3() ); - set_D3( get_D4() ); - set_D4( get_D5() ); - set_D5( DISP_V_1 ); - set_D6( DISP_V_2 ); - break; - case 'v': - set_D0( get_D1() ); - set_D1( get_D2() ); - set_D2( get_D3() ); - set_D3( get_D4() ); - set_D4( get_D5() ); - set_D5( DISP_V_1 ); - set_D6( DISP_V_2 ); - break; - case 'W': - set_D0( get_D1() ); - set_D1( get_D2() ); - set_D2( get_D3() ); - set_D3( get_D4() ); - set_D4( get_D5() ); - set_D5( DISP_W_1 ); - set_D6( DISP_W_2 ); - break; - case 'w': - set_D0( get_D1() ); - set_D1( get_D2() ); - set_D2( get_D3() ); - set_D3( get_D4() ); - set_D4( get_D5() ); - set_D5( DISP_W_1 ); - set_D6( DISP_W_2 ); - break; - case 'Y': - set_D6( DISP_Y ); - break; - case 'y': - set_D6( DISP_Y ); - break; - case 'Z': - set_D6( DISP_Z ); - break; - case 'z': - set_D6( DISP_Z ); - break; - case ' ': - set_D6( DISP_SPACE ); - break; - case '.': - set_D6( DISP_PERIOD ); - break; - case '-': - set_D6( DISP_HYPHEN ); - break; - case '\'': - set_D6( DISP_APOSTR ); - break; - case '"': - set_D6( DISP_APOSTR ); - break; - case '=': - set_D6( DISP_EQUAL ); - break; - case '_': - set_D6( DISP_BOTTOM ); - break; - case '/': - set_D6( DISP_SLASH ); - break; - case '\\': - set_D6( DISP_BACKSLASH ); - break; - default: - displayable = 0; // Character not mapped - } - - if( displayable ) { - - putchar( buffer[l] ); // Send it to the console - - set_D0( get_D1() ); // Scroll to the left - set_D1( get_D2() ); - set_D2( get_D3() ); - set_D3( get_D4() ); - set_D4( get_D5() ); - set_D5( get_D6() ); - - for( d = 0; d < flashes ; d++ ) { - fdisp(); // Display - } - } - } - - for( e = 0; e < 6; e++ ) { // Gradually fill the - set_D0( get_D1() ); // display with spaces - set_D1( get_D2() ); - set_D2( get_D3() ); - set_D3( get_D4() ); - set_D4( get_D5() ); - set_D5( DISP_SPACE ); - set_D6( DISP_SPACE ); - for( d = 0; d < flashes ; d++ ) { - fdisp(); // Display - } - } - } - - puts( "\n\nEnjoy your day!\n\n" ); - - return; -} diff --git a/samples/symHello.c b/samples/symHello.c deleted file mode 100644 index 99a7745da..000000000 --- a/samples/symHello.c +++ /dev/null @@ -1,40 +0,0 @@ -// -------------------------------------------------------------------------- -// Hello World for Sym-1 -// -// Wayne Parham -// -// wayne@parhamdata.com -// -------------------------------------------------------------------------- - -#include <stdio.h> -#include <sym1.h> - -void main(void) { - char c = 0x00; - int d = 0x00; - int l = 0x00; - - printf( "\nHello World!\n\n" ); - - for( l = 0; l < 2; l++ ) { - beep(); - for( d = 0; d < 10 ; d++ ) { - } - } - printf( "Type a line and press ENTER, please.\n\n" ); - - while( c != '\r' ) { - c = getchar(); - putchar( c ); - } - - printf( "\n\nThanks!\n\n" ); - - for( l = 0; l < 5; l++ ) { - beep(); - for( d = 0; d < 10 ; d++ ) { - } - } - - return; -} diff --git a/samples/symIO.c b/samples/symIO.c deleted file mode 100644 index 1e93e941a..000000000 --- a/samples/symIO.c +++ /dev/null @@ -1,170 +0,0 @@ -// -------------------------------------------------------------------------- -// Sym-1 digital I/O interface example -// -// Wayne Parham -// -// wayne@parhamdata.com -// -------------------------------------------------------------------------- - -#include <sym1.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -void main(void) { - int ddr1a = 0x00; - int ior1a = 0x00; - int ddr1b = 0x00; - int ior1b = 0x00; - int ddr2a = 0x00; - int ior2a = 0x00; - int ddr2b = 0x00; - int ior2b = 0x00; - int ddr3a = 0x00; - int ior3a = 0x00; - int ddr3b = 0x00; - int ior3b = 0x00; - int l = 0x00; - int val = 0x00; - int going = 0x01; - int instr = 0x01; - char* vp = 0x00; - char cmd[20] = { 0x00 }; - - while( going ) { - - putchar( '\r' ); - for( l = 0; l < 25; l++ ) { - putchar( '\n' ); - } - - ddr1a = get_DDR1A(); - ior1a = get_IOR1A(); - ddr1b = get_DDR1B(); - ior1b = get_IOR1B(); - ddr2a = get_DDR2A(); - ior2a = get_IOR2A(); - ddr2b = get_DDR2B(); - ior2b = get_IOR2B(); - ddr3a = get_DDR3A(); - ior3a = get_IOR3A(); - ddr3b = get_DDR3B(); - ior3b = get_IOR3B(); - - puts( "================== Digital I/O Status ==================" ); - puts( " Port1A Port1B Port2A Port2B Port3A Port3B" ); - printf( "DDR %02X %02X %02X %02X %02X %02X\n\r",ddr1a,ddr1b,ddr2a,ddr2b,ddr3a,ddr3b ); - printf( "IOR %02X %02X %02X %02X %02X %02X\n\r",ior1a,ior1b,ior2a,ior2b,ior3a,ior3b ); - puts( "========================================================\n" ); - - if( instr ) { - puts( "You can set any register by typing 'register value' so" ); - puts( "as an example, to set register IOR2A with the top five" ); - puts( "bits off and the bottom three on, type 'IOR2A 07'." ); - puts( "Press ENTER without any command to see register values" ); - puts( "without changing any of them. Type 'help' to see these" ); - puts( "instructions again and type 'stop' to end the program.\n"); - puts( "Available registers: DDR1A, IOR1A, DDR1B, IOR1B, DDR2A" ); - puts( "IOR2A, DDR2B, IOR2B, DDR3A, IOR3A, DDR3B and IOR3B." ); - instr = 0; - } - - printf( "\n Command: " ); - - fgets(cmd, sizeof(cmd)-1, stdin); - cmd[strlen(cmd)-1] = '\0'; - - if( strncasecmp(cmd, "stop", 4) == 0) { - going = 0; - } - else if( strncasecmp(cmd, "help", 4) == 0) { - instr = 1; - } - else if( strncasecmp(cmd, "ddr1a", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { - val = atoi( vp ); - set_DDR1A( val ); - } - } - else if( strncasecmp(cmd, "ior1a", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { - val = atoi( vp ); - set_IOR1A( val ); - } - } - else if( strncasecmp(cmd, "ddr1b", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { - val = atoi( vp ); - set_DDR1B( val ); - } - } - else if( strncasecmp(cmd, "ior1b", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { - val = atoi( vp ); - set_IOR1B( val ); - } - } - else if( strncasecmp(cmd, "ddr2a", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { - val = atoi( vp ); - set_DDR2A( val ); - } - } - else if( strncasecmp(cmd, "ior2a", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { - val = atoi( vp ); - set_IOR2A( val ); - } - } - else if( strncasecmp(cmd, "ddr2b", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { - val = atoi( vp ); - set_DDR2B( val ); - } - } - else if( strncasecmp(cmd, "ior2b", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { - val = atoi( vp ); - set_IOR2B( val ); - } - } - else if( strncasecmp(cmd, "ddr3a", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { - val = atoi( vp ); - set_DDR3A( val ); - } - } - else if( strncasecmp(cmd, "ior3a", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { - val = atoi( vp ); - set_IOR3A( val ); - } - } - else if( strncasecmp(cmd, "ddr3b", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { - val = atoi( vp ); - set_DDR3B( val ); - } - } - else if( strncasecmp(cmd, "ior3b", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { - val = atoi( vp ); - set_IOR3B( val ); - } - } - } - - return; -} diff --git a/samples/symNotepad.c b/samples/symNotepad.c deleted file mode 100644 index 79d621223..000000000 --- a/samples/symNotepad.c +++ /dev/null @@ -1,200 +0,0 @@ -// -------------------------------------------------------------------------- -// Sym-1 Notepad -// -// Wayne Parham -// -// wayne@parhamdata.com -// -------------------------------------------------------------------------- -// -// Note: This program requires RAM memory in locations 0xE000 - 0xEFFF -// Alternatively, the tape I/O buffer location and size can be -// changed by altering the defined TAPIO values below. -// -// -------------------------------------------------------------------------- - -#include <sym1.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#define TAPIO_ADDRESS 0xE000 -#define TAPIO_MAX_SIZE 0x0FFF - -void main(void) { - char c = 0x00; - int l = 0x00; - int p = 0x00; - int error = 0x00; - int running = 0x01; - int writing = 0x01; - int instruction_needed = 0x01; - int heap_size = 0x00; - char* tapio = (char*) TAPIO_ADDRESS; - char* buffer; - - heap_size = _heapmaxavail(); - - if( heap_size > TAPIO_MAX_SIZE ) { // No need to malloc more than - heap_size = TAPIO_MAX_SIZE; // the interface allows - } - - buffer = malloc( heap_size ); - memset( buffer, 0x00, heap_size ); - - if( buffer == 0x00 ) { - puts( "Memory full." ); - running = 0; - } - - tapio[0] = 0x00; // Check tape interface memory - if( tapio[0] != 0x00 ) - error = 1; - - tapio[0] = 0xFF; - if( tapio[0] != 0xFF ) - error = 1; - - tapio[TAPIO_MAX_SIZE] = 0x00; - if( tapio[TAPIO_MAX_SIZE] != 0x00 ) - error = 1; - - tapio[TAPIO_MAX_SIZE] = 0xFF; - if( tapio[TAPIO_MAX_SIZE] != 0xFF ) - error = 1; - - if( error ) { - printf( "\nNo memory at location %p, aborting.\n", tapio ); - running = 0; - } - else { - memset( tapio, 0, TAPIO_MAX_SIZE ); - } - - - while( running ) { - - putchar( '\r' ); - for( l = 0; l < 25; l++ ) { - putchar( '\n' ); - } - - puts( "===================== Sym-1 Notepad ====================" ); - - if( instruction_needed ) { - puts( "Enter text and you can save it to tape for reloading" ); - puts( "later. There are four special 'command' characters:\n" ); - puts( " Control-S Save to tape" ); - puts( " Control-L Load from tape" ); - puts( " Control-C Clear memory" ); - puts( " Control-X Exit" ); - puts( "========================================================\n" ); - } - - while( writing ) { - - c = getchar(); - - if( c == 0x08 ) { // Backspace - if( p > 0 ) { - buffer[p] = 0x00; - p--; - } - } - else if( c == 0x13 ) { // Save - puts( "\n========================= Save =========================" ); - puts( "\nPress any key to save." ); - c = getchar(); - for( l = 0; l <= p; l++ ) { - tapio[l] = buffer[l]; - } - l++; - tapio[l] = 0x00; - puts( "Saving to tape." ); - error = dumpt( 'N', (int) tapio, (int) tapio+p ); - if( error ) { - puts( "\nTape error." ); - } - else - { - putchar( '\r' ); - for( l = 0; l < 25; l++ ) { - putchar( '\n' ); - } - } - puts( "===================== Sym-1 Notepad ====================\n" ); - for( l = 0; l <= p; l++ ) { - putchar( buffer[l] ); - if( buffer[l] == '\r' ) { - putchar( '\n' ); - } - } - } - else if( c == 0x0C ) { // Load - p = 0; - puts( "\nLoading from tape." ); - memset( buffer, 0, heap_size ); - memset( tapio, 0, TAPIO_MAX_SIZE ); - error = loadt( 'N' ); - if( error ) { - puts( "\nTape error." ); - puts( "===================== Sym-1 Notepad ====================\n" ); - } - else - { - for( l = 0; l <= heap_size; l++ ) { - buffer[l] = tapio[l]; - } - - p = strlen( buffer ); - - putchar( '\r' ); - for( l = 0; l < 25; l++ ) { - putchar( '\n' ); - } - puts( "===================== Sym-1 Notepad ====================\n" ); - - for( l = 0; l <= p; l++ ) { - putchar( buffer[l] ); - if( buffer[l] == '\r' ) { - putchar( '\n' ); - } - } - } - } - else if( c == 0x03 ) { // Clear - p = 0; - memset( buffer, 0, heap_size ); - putchar( '\r' ); - for( l = 0; l < 25; l++ ) { - putchar( '\n' ); - } - puts( "===================== Sym-1 Notepad ====================\n" ); - } - else if( c == 0x18 ) { // Exit - writing = 0; - running = 0; - } - else { - if( p >= heap_size - 1 ) { - puts( "\n========================= End =========================" ); - puts( "Buffer full." ); - } - else { - if( c == '\r' ) { - putchar( '\n' ); - } - buffer[p] = c; - putchar( c ); - } - p++; - } - } - } - - free( buffer ); - - puts( "\nEnjoy your day!\n" ); - - return; -} - diff --git a/samples/symTiny.c b/samples/symTiny.c deleted file mode 100644 index 4d03338e6..000000000 --- a/samples/symTiny.c +++ /dev/null @@ -1,43 +0,0 @@ -// -------------------------------------------------------------------------- -// Hello World for Sym-1 -// -// Uses only getchar, putchar and puts, generating smaller code than printf -// -// Wayne Parham -// -// wayne@parhamdata.com -// -------------------------------------------------------------------------- - -#include <stdio.h> -#include <sym1.h> - -void main(void) { - char c = 0x00; - int d = 0x00; - int l = 0x00; - - puts( "Hello World!\n" ); - - puts( "Type a line and press ENTER, please:\n" ); - - for( l = 0; l < 2; l++ ) { - beep(); - for( d = 0; d < 10 ; d++ ) { - } - } - - while( c != '\r' ) { - c = getchar(); - putchar( c ); - } - - puts( "\n\nThanks!\n" ); - - for( l = 0; l < 5; l++ ) { - beep(); - for( d = 0; d < 10 ; d++ ) { - } - } - - return; -} diff --git a/targettest/sym1/build b/targettest/sym1/build deleted file mode 100644 index 6688da0a3..000000000 --- a/targettest/sym1/build +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash -# -# build.sh - -if [ -f $1.c ]; then - echo - echo "--- Building $1 ---" - - if [ -f $1.s ]; then - rm $1.s - fi - if [ -f $1.o ]; then - rm $1.o - fi - if [ -f $1.bin ]; then - rm $1.bin - fi - if [ -f $1.hex ]; then - rm $1.hex - fi - - cc65 -t sym1 -O $1.c - ca65 $1.s - ld65 -C sym1.cfg -m $1.map -o $1.bin $1.o sym1.lib - if [ -f $1.bin ]; then - bin2hex $1.bin $1.hex > /dev/null 2>&1 - fi - if [ -f $1.hex ]; then - echo "--- $1.hex made ---" - else - echo "--- $1.hex FAIL ---" - fi - - -fi - diff --git a/targettest/sym1/build_32k b/targettest/sym1/build_32k deleted file mode 100644 index 555bda0b4..000000000 --- a/targettest/sym1/build_32k +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash -# -# build.sh - -if [ -f $1.c ]; then - echo - echo "--- Building $1 ---" - - if [ -f $1.s ]; then - rm $1.s - fi - if [ -f $1.o ]; then - rm $1.o - fi - if [ -f $1.bin ]; then - rm $1.bin - fi - if [ -f $1.hex ]; then - rm $1.hex - fi - - cc65 -t sym1 -O $1.c - ca65 $1.s - ld65 -C sym1-32k.cfg -m $1.map -o $1.bin $1.o sym1.lib - if [ -f $1.bin ]; then - bin2hex $1.bin $1.hex > /dev/null 2>&1 - fi - if [ -f $1.hex ]; then - echo "--- $1.hex made ---" - else - echo "--- $1.hex FAIL ---" - fi - - -fi - diff --git a/targettest/sym1/build_4k b/targettest/sym1/build_4k deleted file mode 100644 index 502bb6aa9..000000000 --- a/targettest/sym1/build_4k +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash -# -# build.sh - -if [ -f $1.c ]; then - echo - echo "--- Building $1 ---" - - if [ -f $1.s ]; then - rm $1.s - fi - if [ -f $1.o ]; then - rm $1.o - fi - if [ -f $1.bin ]; then - rm $1.bin - fi - if [ -f $1.hex ]; then - rm $1.hex - fi - - cc65 -t sym1 -O $1.c - ca65 $1.s - ld65 -C sym1-4k.cfg -m $1.map -o $1.bin $1.o sym1.lib - if [ -f $1.bin ]; then - bin2hex $1.bin $1.hex > /dev/null 2>&1 - fi - if [ -f $1.hex ]; then - echo "--- $1.hex made ---" - else - echo "--- $1.hex FAIL ---" - fi - - -fi - diff --git a/targettest/sym1/clean b/targettest/sym1/clean deleted file mode 100644 index c0d77390e..000000000 --- a/targettest/sym1/clean +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -# -# clean.sh - -if [ -f $1.c ]; then - echo - echo "--- Cleaning $1 ---" - - rm $1.s $1.o $1.map $1.bin $1.hex > /dev/null 2>&1 - - echo "--- Cleaned $1 ---" - -fi - diff --git a/targettest/sym1/readme.txt b/targettest/sym1/readme.txt deleted file mode 100644 index 74bcb5527..000000000 --- a/targettest/sym1/readme.txt +++ /dev/null @@ -1,11 +0,0 @@ -These simple build scripts can be used to build any single-file C program -you might write. Notice the diference in the linker line for the 4k build -compared with the 32k build. Small programs can be compiled with either -build script, but they won't run on a 4k machine if compiled for a 32k -system. So if you have a program that's small enough to fit in 4k, it is -probably better to build with the 4k script so it will run on Sym-1 machines -that do not have an expansion memory board. - -Usage: build <program> (don't include the .c extension) - clean <program> (removes intermediate and output files) - From 5eafd8115f2077f668616c1534c21c0fd14ad9c4 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Mon, 7 Jun 2021 00:53:15 -0500 Subject: [PATCH 2097/2161] Cleanup whitespace in Makefile --- samples/Makefile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index c8c02dbe3..e455852c6 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -334,13 +334,12 @@ ifndef EXELIST_$(SYS) EXELIST_$(SYS) := ${patsubst %.c,%,$(wildcard *.c)} endif -define SUBDIR_recipe +define SUBDIR_recipe @$(MAKE) -C $(dir) --no-print-directory $@ endef # SUBDIR_recipe - # -------------------------------------------------------------------------- # Rules to make the binaries and the disk @@ -481,5 +480,4 @@ mostlyclean: clean: mostlyclean @$(DEL) $(EXELIST_$(SYS)) $(DISK_$(SYS)) 2>$(NULLDEV) @$(DEL) multdemo.? ovrldemo.? 2>$(NULLDEV) - @$(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) - + $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) From 732a5fb9a7409eca69faae7e7ce7423b77e493e1 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Mon, 7 Jun 2021 00:56:50 -0500 Subject: [PATCH 2098/2161] Remove bin and hex references from samples/Makefile --- samples/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Makefile b/samples/Makefile index e455852c6..32a0086d8 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -475,7 +475,7 @@ zip: # Clean-up rules mostlyclean: - @$(DEL) *.lbl *.map *.bin *.hex *.o *.s 2>$(NULLDEV) + @$(DEL) *.lbl *.map *.o *.s 2>$(NULLDEV) clean: mostlyclean @$(DEL) $(EXELIST_$(SYS)) $(DISK_$(SYS)) 2>$(NULLDEV) From 79757ee28093884e1b845a885a2a1e6e9b97c140 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Mon, 7 Jun 2021 01:04:55 -0500 Subject: [PATCH 2099/2161] Removed 'return' from samples (with void main) --- targettest/sym1/symDisplay.c | 2 -- targettest/sym1/symHello.c | 2 -- targettest/sym1/symIO.c | 2 -- targettest/sym1/symNotepad.c | 2 -- targettest/sym1/symTiny.c | 2 -- 5 files changed, 10 deletions(-) diff --git a/targettest/sym1/symDisplay.c b/targettest/sym1/symDisplay.c index fa94ce598..18ae54797 100644 --- a/targettest/sym1/symDisplay.c +++ b/targettest/sym1/symDisplay.c @@ -355,6 +355,4 @@ void main (void) { } puts( "\n\nEnjoy your day!\n\n" ); - - return; } diff --git a/targettest/sym1/symHello.c b/targettest/sym1/symHello.c index 99b4c57df..2cab3cbde 100644 --- a/targettest/sym1/symHello.c +++ b/targettest/sym1/symHello.c @@ -34,6 +34,4 @@ void main(void) { for( d = 0; d < 10 ; d++ ) { } } - - return; } diff --git a/targettest/sym1/symIO.c b/targettest/sym1/symIO.c index d887c18b9..d1cbe8137 100644 --- a/targettest/sym1/symIO.c +++ b/targettest/sym1/symIO.c @@ -165,6 +165,4 @@ void main(void) { } } } - - return; } diff --git a/targettest/sym1/symNotepad.c b/targettest/sym1/symNotepad.c index bc28ef4b5..f59eebda8 100644 --- a/targettest/sym1/symNotepad.c +++ b/targettest/sym1/symNotepad.c @@ -193,7 +193,5 @@ void main(void) { free( buffer ); puts( "\nEnjoy your day!\n" ); - - return; } diff --git a/targettest/sym1/symTiny.c b/targettest/sym1/symTiny.c index b82e952ac..7806d5629 100644 --- a/targettest/sym1/symTiny.c +++ b/targettest/sym1/symTiny.c @@ -37,6 +37,4 @@ void main(void) { for( d = 0; d < 10 ; d++ ) { } } - - return; } From 6cf4bd99bbb96e895ee93d255c555966672aa412 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Mon, 7 Jun 2021 11:50:47 -0500 Subject: [PATCH 2100/2161] Added Makefile for targettest/sym1 --- targettest/sym1/Makefile | 55 ++++++++++++++++++++++++++++++++++++ targettest/sym1/symDisplay.c | 3 +- targettest/sym1/symHello.c | 3 +- targettest/sym1/symIO.c | 8 +++--- targettest/sym1/symNotepad.c | 7 +++-- targettest/sym1/symTiny.c | 3 +- 6 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 targettest/sym1/Makefile diff --git a/targettest/sym1/Makefile b/targettest/sym1/Makefile new file mode 100644 index 000000000..c8508f1e0 --- /dev/null +++ b/targettest/sym1/Makefile @@ -0,0 +1,55 @@ +# Run 'make SYS=<target>'; or, set a SYS env. +# var. to build for another target system. +SYS ?= sym1 + +# 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 + +all: symHello.bin symTiny.bin symDisplay.bin symIO.bin symNotepad.bin + +symHello.bin: symHello.c + $(CL) -t $(SYS) -C sym1-4k.cfg -O -o symHello.bin symHello.c + +symTiny.bin: symTiny.c + $(CL) -t $(SYS) -C sym1-4k.cfg -O -o symTiny.bin symTiny.c + +symDisplay.bin: symDisplay.c + $(CL) -t $(SYS) -C sym1-4k.cfg -O -o symDisplay.bin symDisplay.c + +symIO.bin: symIO.c + $(CL) -t $(SYS) -C sym1-32k.cfg -O -o symIO.bin symIO.c + +symNotepad.bin: symNotepad.c + $(CL) -t $(SYS) -C sym1-32k.cfg -O -o symNotepad.bin symNotepad.c + +clean: + @$(DEL) symHello.bin 2>$(NULLDEV) + @$(DEL) symTiny.bin 2>$(NULLDEV) + @$(DEL) symDisplay.bin 2>$(NULLDEV) + @$(DEL) symIO.bin 2>$(NULLDEV) + @$(DEL) symNotepad.bin 2>$(NULLDEV) diff --git a/targettest/sym1/symDisplay.c b/targettest/sym1/symDisplay.c index 18ae54797..7b056c3ab 100644 --- a/targettest/sym1/symDisplay.c +++ b/targettest/sym1/symDisplay.c @@ -6,7 +6,8 @@ // wayne@parhamdata.com // -------------------------------------------------------------------------- -#include <symio.h> +#include <stdio.h> +#include <sym1.h> void main (void) { int delay = 10; diff --git a/targettest/sym1/symHello.c b/targettest/sym1/symHello.c index 2cab3cbde..7fb86f04e 100644 --- a/targettest/sym1/symHello.c +++ b/targettest/sym1/symHello.c @@ -6,7 +6,8 @@ // wayne@parhamdata.com // -------------------------------------------------------------------------- -#include <symio.h>; +#include <stdio.h> +#include <sym1.h> void main(void) { char c = 0x00; diff --git a/targettest/sym1/symIO.c b/targettest/sym1/symIO.c index d1cbe8137..67e898801 100644 --- a/targettest/sym1/symIO.c +++ b/targettest/sym1/symIO.c @@ -6,10 +6,10 @@ // wayne@parhamdata.com // -------------------------------------------------------------------------- -#include <stdio.h>; -#include <symio.h>; -#include <stdlib.h>; -#include <string.h>; +#include <sym1.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> void main(void) { int ddr1a = 0x00; diff --git a/targettest/sym1/symNotepad.c b/targettest/sym1/symNotepad.c index f59eebda8..683cea63f 100644 --- a/targettest/sym1/symNotepad.c +++ b/targettest/sym1/symNotepad.c @@ -12,9 +12,10 @@ // // -------------------------------------------------------------------------- -#include <symio.h>; -#include <stdlib.h>; -#include <string.h>; +#include <sym1.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> #define TAPIO_ADDRESS 0xE000 #define TAPIO_MAX_SIZE 0x0FFF diff --git a/targettest/sym1/symTiny.c b/targettest/sym1/symTiny.c index 7806d5629..1e9f86516 100644 --- a/targettest/sym1/symTiny.c +++ b/targettest/sym1/symTiny.c @@ -8,7 +8,8 @@ // wayne@parhamdata.com // -------------------------------------------------------------------------- -#include <symio.h>; +#include <stdio.h> +#include <sym1.h> void main(void) { char c = 0x00; From 886e9e83b2f26c4f6c0ceb5407dcd31646c9d039 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Mon, 7 Jun 2021 12:33:29 -0500 Subject: [PATCH 2101/2161] Removed stdin->stdout echo from read.s --- libsrc/sym1/read.s | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libsrc/sym1/read.s b/libsrc/sym1/read.s index 7ab88f1e8..b876a5915 100644 --- a/libsrc/sym1/read.s +++ b/libsrc/sym1/read.s @@ -29,11 +29,7 @@ begin: dec ptr2 beq done ; If buffer full, return getch: jsr INTCHR ; Get character using Monitor ROM call - jsr OUTCHR ; Echo it - and #$7F ; Clear hi bit and check for '\r' - cmp #$0D - bne putch - lda #$0A ; Replace with '\n' and set count to zero + and #$7F ; Clear hi bit putch: ldy #$00 ; Put char into return buffer sta (ptr1),y From ed9f9ccbabea58a2e2a688434290d0ad026acd13 Mon Sep 17 00:00:00 2001 From: polluks2 <74630735+polluks2@users.noreply.github.com> Date: Mon, 7 Jun 2021 20:56:24 +0000 Subject: [PATCH 2102/2161] Fix #1536 --- src/cc65/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/main.c b/src/cc65/main.c index 0b156fb74..5d1fd7487 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -291,7 +291,7 @@ static void SetSys (const char* Sys) break; default: - AbEnd ("Unknown target system type %d", Target); + AbEnd ("Unknown target system '%s'", Sys); } /* Initialize the translation tables for the target system */ From 89fb731e2e293d16686fe027a86e8eb12c213891 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Mon, 7 Jun 2021 19:01:06 -0500 Subject: [PATCH 2103/2161] samples/helloworld.c --- samples/helloworld.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/helloworld.c b/samples/helloworld.c index 9aa4197d8..b4e1ee6a3 100644 --- a/samples/helloworld.c +++ b/samples/helloworld.c @@ -2,7 +2,7 @@ #include <stdio.h> -int main() { - printf("Hello, World!"); +int main(void) { + printf("Hello, World!\n"); return 0; } From 2635655e8c1b7d7fdcacca619f412fcd93208528 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Mon, 7 Jun 2021 19:07:36 -0500 Subject: [PATCH 2104/2161] sym1.cfg cosmetic changes --- cfg/sym1-32k.cfg | 12 ++++++------ cfg/sym1-4k.cfg | 12 ++++++------ cfg/sym1.cfg | 12 ++++++------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/cfg/sym1-32k.cfg b/cfg/sym1-32k.cfg index 9af125eaa..ee3bc9d63 100644 --- a/cfg/sym1-32k.cfg +++ b/cfg/sym1-32k.cfg @@ -35,12 +35,12 @@ MEMORY { } 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; + 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/sym1-4k.cfg b/cfg/sym1-4k.cfg index eefb48a49..8570b6077 100644 --- a/cfg/sym1-4k.cfg +++ b/cfg/sym1-4k.cfg @@ -35,12 +35,12 @@ MEMORY { } 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; + 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/sym1.cfg b/cfg/sym1.cfg index eefb48a49..8570b6077 100644 --- a/cfg/sym1.cfg +++ b/cfg/sym1.cfg @@ -35,12 +35,12 @@ MEMORY { } 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; + 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; } From 2a25921515a5736b40b2bb7096339a0e912328e6 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Mon, 7 Jun 2021 20:00:18 -0500 Subject: [PATCH 2105/2161] Sym-1 documentation updates --- doc/sym1.sgml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/doc/sym1.sgml b/doc/sym1.sgml index 59d1db3b7..d2e5f09fd 100644 --- a/doc/sym1.sgml +++ b/doc/sym1.sgml @@ -21,11 +21,11 @@ Please note that Sym-1 specific functions are just mentioned here, they are desc <sect>Binary format<p> -The standard binary output format generated by the linker for the Sym-1 target is a 4 kbyte machine language program. It is, of course, possible to change this behavior by using one of the different linker configs. +The output format generated by the linker for the Sym-1 target is a raw binary BIN file, which is essentially a memory image. You can convert this to a HEX file using BIN2HEX, which is a popular open-source conversion utility program. A HEX file has ASCII representations of the hexadecimal byte values of the machine-language program. <p> -Included with this distribution is a 4k configuration file and a 32k config file. The Sym-1 on-board memory is limited to 4k but system memory can be increased to 32 kbytes of contiguous RAM with aftermarket add-on boards. So choose the config file that matches your system configuration before compiling and linking user programs. +Included with this distribution is a 4k configuration file and a 32k config file. The Sym-1 on-board memory is limited to 4 kbytes but system memory can be increased to 32 kbytes of contiguous RAM with aftermarket add-on boards. So choose the config file that matches your system configuration before compiling and linking user programs. <sect>Memory layout<p> @@ -41,8 +41,7 @@ Special locations: The C runtime stack is located at $0FFF on 4KB Syms, or at $7FFFfor 32KB systems. The stack always grows downwards. <tag/Heap/ - The C heap is located at the end of the program and grows towards the C - runtime stack. + The C heap is located at the end of the program and grows towards the C runtime stack. </descrip><p> @@ -52,7 +51,7 @@ Programs containing Sym-1 code may use the <tt/sym1.h/ header file. See the hea <sect1>Hardware access<p> -The following pseudo variables declared in the <tt/sym1.inc/ include file allow access to hardware located in the address space. See the include file for more information. +The pseudo variables declared in the <tt/sym1.inc/ include file allow access to hardware located in the address space. See the include file for more information. <sect>Loadable drivers<p> @@ -103,7 +102,7 @@ As stated earlier, there are config files for 4KB and 32KB systems. If you have <sect3>Sample programs<p> -All the samples will run on the "stock" 4k Sym-1, except for symio.c, which requires 8k. Information on building and running it is in the samples/tutorial/sym1 directory. +All the samples will run on the "stock" 4KB Sym-1, except for symIO and symNotepad, which require 32KB. Information on building and running the sample programs are in the targettest/sym1 directory. <itemize> <item>helloworld is the traditional "Hello World!" program, using printf().</item> From 09862e7ce908d7915e6341f626f2930e0cc62118 Mon Sep 17 00:00:00 2001 From: Filip Golewski <f.golewski@gmail.com> Date: Tue, 8 Jun 2021 20:05:22 +0200 Subject: [PATCH 2106/2161] Update src/msbuild.cmd script to optionally include Visual Studio 2019 Community build tools --- src/msbuild.cmd | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/msbuild.cmd b/src/msbuild.cmd index 5736846da..2e1821f0a 100644 --- a/src/msbuild.cmd +++ b/src/msbuild.cmd @@ -1,2 +1,18 @@ +@echo off + +if exist "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools\VsDevCmd.bat" goto vs2017 +if exist "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat" goto vs2019 + +echo Error: VsDevCmd.bat not found! +goto:eof + +:vs2017 call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools\VsDevCmd.bat" +goto run + +:vs2019 +call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat" +goto run + +:run msbuild.exe %* From dcacba472ae69c27146a7767bc7835e5b239d8ff Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Mon, 5 Apr 2021 16:40:33 +0800 Subject: [PATCH 2107/2161] Moved ArithmeticConvert() from cc65/expr.c to cc65/datatype.c. Reorganized a few functions in cc65/datatype.c. Added SignedType() and UnsignedType() for future usage. Made LimitExprValue() external so that it can be used more often. --- src/cc65/datatype.c | 480 ++++++++++++++++++++++++++++---------------- src/cc65/datatype.h | 90 +++++---- src/cc65/expr.c | 61 +----- src/cc65/expr.h | 3 + 4 files changed, 358 insertions(+), 276 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 90bf892ba..6465c27a6 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -546,14 +546,14 @@ unsigned long GetIntegerTypeMax (const Type* Type) -static unsigned TypeOfBySize (const Type* Type) +static unsigned TypeOfBySize (unsigned Size) /* Get the code generator replacement type of the object by its size */ { unsigned NewType; /* If the size is less than or equal to that of a a long, we will copy ** the struct using the primary register, otherwise we use memcpy. */ - switch (SizeOf (Type)) { + switch (Size) { case 1: NewType = CF_CHAR; break; case 2: NewType = CF_INT; break; case 3: /* FALLTHROUGH */ @@ -566,125 +566,6 @@ static unsigned TypeOfBySize (const Type* Type) -Type* NewPointerTo (const Type* T) -/* Return a type string that is "pointer to T". The type string is allocated -** on the heap and may be freed after use. -*/ -{ - /* Get the size of the type string including the terminator */ - unsigned Size = TypeLen (T) + 1; - - /* Allocate the new type string */ - Type* P = TypeAlloc (Size + 1); - - /* Create the return type... */ - P[0].C = T_PTR | (T[0].C & T_QUAL_ADDRSIZE); - memcpy (P+1, T, Size * sizeof (Type)); - - /* ...and return it */ - return P; -} - - - -void PrintType (FILE* F, const Type* T) -/* Print fulle name of the type */ -{ - StrBuf Buf = AUTO_STRBUF_INITIALIZER; - fprintf (F, "%s", SB_GetConstBuf (GetFullTypeNameBuf (&Buf, T))); - SB_Done (&Buf); -} - - - -void PrintFuncSig (FILE* F, const char* Name, const Type* T) -/* Print a function signature */ -{ - StrBuf Buf = AUTO_STRBUF_INITIALIZER; - StrBuf ParamList = AUTO_STRBUF_INITIALIZER; - StrBuf East = AUTO_STRBUF_INITIALIZER; - StrBuf West = AUTO_STRBUF_INITIALIZER; - - /* 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 (!HasAnonName (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 function qualifiers */ - if (GetQualifierTypeCodeNameBuf (&Buf, T->C, T_QUAL_NONE) > 0) { - /* Append a space between the qualifiers and the name */ - SB_AppendChar (&Buf, ' '); - } - SB_Terminate (&Buf); - - /* 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, GetFuncReturn (T)); - SB_Append (&West, &East); - SB_Terminate (&West); - - /* Output */ - fprintf (F, "%s", SB_GetConstBuf (&West)); - SB_Done (&East); - SB_Done (&West); -} - - - -void PrintRawType (FILE* F, const Type* T) -/* Print a type string in raw hex format (for debugging) */ -{ - while (T->C != T_END) { - fprintf (F, "%04lX ", T->C); - ++T; - } - fprintf (F, "\n"); -} - - - -int TypeHasAttr (const Type* T) -/* Return true if the given type has attribute data */ -{ - return IsClassStruct (T) || IsTypeArray (T) || IsClassFunc (T); -} - - - const Type* GetUnderlyingType (const Type* Type) /* Get the underlying type of an enum or other integer class type */ { @@ -906,7 +787,7 @@ unsigned TypeOf (const Type* T) case T_STRUCT: case T_UNION: - NewType = TypeOfBySize (T); + NewType = TypeOfBySize (SizeOf (T)); if (NewType != CF_NONE) { return NewType; } @@ -968,6 +849,48 @@ Type* IndirectModifiable (Type* T) +Type* NewPointerTo (const Type* T) +/* Return a type string that is "pointer to T". The type string is allocated +** on the heap and may be freed after use. +*/ +{ + /* Get the size of the type string including the terminator */ + unsigned Size = TypeLen (T) + 1; + + /* Allocate the new type string */ + Type* P = TypeAlloc (Size + 1); + + /* Create the return type... */ + P[0].C = T_PTR | (T[0].C & T_QUAL_ADDRSIZE); + memcpy (P+1, T, Size * sizeof (Type)); + + /* ...and return it */ + return P; +} + + + +const Type* AddressOf (const Type* T) +/* Return a type string that is "address of T". The type string is allocated +** on the heap and may be freed after use. +*/ +{ + /* Get the size of the type string including the terminator */ + unsigned Size = TypeLen (T) + 1; + + /* Allocate the new type string */ + Type* P = TypeAlloc (Size + 1); + + /* Create the return type... */ + P[0].C = T_PTR | (T[0].C & T_QUAL_ADDRSIZE) | T_QUAL_CONST; + memcpy (P+1, T, Size * sizeof (Type)); + + /* ...and return it */ + return P; +} + + + Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { @@ -977,6 +900,165 @@ Type* ArrayToPtr (const Type* T) +const Type* PtrConversion (const Type* T) +/* If the type is a function, convert it to pointer to function. If the +** expression is an array, convert it to pointer to first element. Otherwise +** return T. +*/ +{ + if (IsTypeFunc (T)) { + return AddressOf (T); + } else if (IsTypeArray (T)) { + return AddressOf (GetElementType (T)); + } else { + return T; + } +} + + + +const Type* IntPromotion (const Type* T) +/* Apply the integer promotions to T and return the result. The returned type +** string may be T if there is no need to change it. +*/ +{ + /* We must have an int to apply int promotions */ + PRECONDITION (IsClassInt (T)); + + /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.1 + ** A char, a short int, or an int bit-field, or their signed or unsigned varieties, or + ** an object that has enumeration type, may be used in an expression wherever an int or + ** unsigned int may be used. If an int can represent all values of the original type, + ** the value is converted to an int; otherwise it is converted to an unsigned int. + ** These are called the integral promotions. + */ + + if (IsTypeChar (T)) { + /* An integer can represent all values from either signed or unsigned char, so convert + ** chars to int. + */ + return type_int; + } else if (IsTypeShort (T)) { + /* An integer cannot represent all values from unsigned short, so convert unsigned short + ** to unsigned int. + */ + return IsSignUnsigned (T) ? type_uint : type_int; + } else if (!IsIncompleteESUType (T)) { + /* The type is a complete type not smaller than int, so leave it alone. */ + return T; + } else { + /* Otherwise, this is an incomplete enum, and there is expceted to be an error already. + ** Assume int to avoid further errors. + */ + return type_int; + } +} + + + +const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) +/* Perform the usual arithmetic conversions for binary operators. */ +{ + /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 + ** Many binary operators that expect operands of arithmetic type cause conversions and yield + ** result types in a similar way. The purpose is to yield a common type, which is also the type + ** of the result. This pattern is called the usual arithmetic conversions. + */ + + /* There are additional rules for floating point types that we don't bother with, since + ** floating point types are not (yet) supported. + ** The integral promotions are performed on both operands. + */ + lhst = IntPromotion (lhst); + rhst = IntPromotion (rhst); + + /* If either operand has type unsigned long int, the other operand is converted to + ** unsigned long int. + */ + if ((IsTypeLong (lhst) && IsSignUnsigned (lhst)) || + (IsTypeLong (rhst) && IsSignUnsigned (rhst))) { + return type_ulong; + } + + /* Otherwise, if one operand has type long int and the other has type unsigned int, + ** if a long int can represent all values of an unsigned int, the operand of type unsigned int + ** is converted to long int ; if a long int cannot represent all the values of an unsigned int, + ** both operands are converted to unsigned long int. + */ + if ((IsTypeLong (lhst) && IsTypeInt (rhst) && IsSignUnsigned (rhst)) || + (IsTypeLong (rhst) && IsTypeInt (lhst) && IsSignUnsigned (lhst))) { + /* long can represent all unsigneds, so we are in the first sub-case. */ + return type_long; + } + + /* Otherwise, if either operand has type long int, the other operand is converted to long int. + */ + if (IsTypeLong (lhst) || IsTypeLong (rhst)) { + return type_long; + } + + /* Otherwise, if either operand has type unsigned int, the other operand is converted to + ** unsigned int. + */ + if ((IsTypeInt (lhst) && IsSignUnsigned (lhst)) || + (IsTypeInt (rhst) && IsSignUnsigned (rhst))) { + return type_uint; + } + + /* Otherwise, both operands have type int. */ + CHECK (IsTypeInt (lhst)); + CHECK (IsSignSigned (lhst)); + CHECK (IsTypeInt (rhst)); + CHECK (IsSignSigned (rhst)); + return type_int; +} + + + +const Type* SignedType (const Type* T) +/* Get signed counterpart of the integral type */ +{ + switch (GetUnderlyingTypeCode (T) & T_MASK_TYPE) { + case T_TYPE_CHAR: + return type_schar; + + case T_TYPE_INT: + case T_TYPE_SHORT: + return type_int; + + case T_TYPE_LONG: + return type_long; + + default: + Internal ("Unknown type code: %lX", GetUnderlyingTypeCode (T)); + return T; + } +} + + + +const Type* UnsignedType (const Type* T) +/* Get unsigned counterpart of the integral type */ +{ + switch (GetUnderlyingTypeCode (T) & T_MASK_TYPE) { + case T_TYPE_CHAR: + return type_uchar; + + case T_TYPE_INT: + case T_TYPE_SHORT: + return type_uint; + + case T_TYPE_LONG: + return type_ulong; + + default: + Internal ("Unknown type code: %lX", GetUnderlyingTypeCode (T)); + return T; + } +} + + + int IsClassObject (const Type* T) /* Return true if this is a fully described object type */ { @@ -1266,62 +1348,6 @@ void SetESUSymEntry (Type* T, struct SymEntry* S) -const Type* IntPromotion (const Type* T) -/* Apply the integer promotions to T and return the result. The returned type -** string may be T if there is no need to change it. -*/ -{ - /* We must have an int to apply int promotions */ - PRECONDITION (IsClassInt (T)); - - /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.1 - ** A char, a short int, or an int bit-field, or their signed or unsigned varieties, or an - ** object that has enumeration type, may be used in an expression wherever an int or - ** unsigned int may be used. If an int can represent all values of the original type, the value - ** is converted to an int; otherwise it is converted to an unsigned int. - ** These are called the integral promotions. - */ - - if (IsTypeChar (T)) { - /* An integer can represent all values from either signed or unsigned char, so convert - ** chars to int. - */ - return type_int; - } else if (IsTypeShort (T)) { - /* An integer cannot represent all values from unsigned short, so convert unsigned short - ** to unsigned int. - */ - return IsSignUnsigned (T) ? type_uint : type_int; - } else if (!IsIncompleteESUType (T)) { - /* The type is a complete type not smaller than int, so leave it alone. */ - return T; - } else { - /* Otherwise, this is an incomplete enum, and there is expceted to be an error already. - ** Assume int to avoid further errors. - */ - return type_int; - } -} - - - -const Type* PtrConversion (const Type* T) -/* If the type is a function, convert it to pointer to function. If the -** expression is an array, convert it to pointer to first element. Otherwise -** return T. -*/ -{ - if (IsTypeFunc (T)) { - return NewPointerTo (T); - } else if (IsTypeArray (T)) { - return ArrayToPtr (T); - } else { - return T; - } -} - - - TypeCode AddrSizeQualifier (unsigned AddrSize) /* Return T_QUAL_NEAR or T_QUAL_FAR depending on the address size */ { @@ -1339,3 +1365,101 @@ TypeCode AddrSizeQualifier (unsigned AddrSize) } } + + + +int TypeHasAttr (const Type* T) +/* Return true if the given type has attribute data */ +{ + return IsClassStruct (T) || IsTypeArray (T) || IsClassFunc (T); +} + + + +void PrintType (FILE* F, const Type* T) +/* Print fulle name of the type */ +{ + StrBuf Buf = AUTO_STRBUF_INITIALIZER; + fprintf (F, "%s", SB_GetConstBuf (GetFullTypeNameBuf (&Buf, T))); + SB_Done (&Buf); +} + + + +void PrintFuncSig (FILE* F, const char* Name, const Type* T) +/* Print a function signature */ +{ + StrBuf Buf = AUTO_STRBUF_INITIALIZER; + StrBuf ParamList = AUTO_STRBUF_INITIALIZER; + StrBuf East = AUTO_STRBUF_INITIALIZER; + StrBuf West = AUTO_STRBUF_INITIALIZER; + + /* 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 (!HasAnonName (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 function qualifiers */ + if (GetQualifierTypeCodeNameBuf (&Buf, T->C, T_QUAL_NONE) > 0) { + /* Append a space between the qualifiers and the name */ + SB_AppendChar (&Buf, ' '); + } + SB_Terminate (&Buf); + + /* 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, GetFuncReturn (T)); + SB_Append (&West, &East); + SB_Terminate (&West); + + /* Output */ + fprintf (F, "%s", SB_GetConstBuf (&West)); + SB_Done (&East); + SB_Done (&West); +} + + + +void PrintRawType (FILE* F, const Type* T) +/* Print a type string in raw hex format (for debugging) */ +{ + while (T->C != T_END) { + fprintf (F, "%04lX ", T->C); + ++T; + } + fprintf (F, "\n"); +} diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index af1c6b8e4..4729284bd 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -288,33 +288,6 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* NewPointerTo (const Type* T); -/* Return a type string that is "pointer to T". The type string is allocated -** on the heap and may be freed after use. -*/ - -void PrintType (FILE* F, const Type* T); -/* Print fulle name of the type */ - -void PrintFuncSig (FILE* F, const char* Name, const Type* T); -/* Print a function signature */ - -void PrintRawType (FILE* F, const Type* T); -/* Print a type string in raw hex format (for debugging) */ - -int TypeHasAttr (const Type* T); -/* Return true if the given type has attribute data */ - -#if defined(HAVE_INLINE) -INLINE void CopyTypeAttr (const Type* Src, Type* Dest) -/* Copy attribute data from Src to Dest */ -{ - Dest->A = Src->A; -} -#else -# define CopyTypeAttr(Src, Dest) ((Dest)->A = (Src)->A) -#endif - #if defined(HAVE_INLINE) INLINE TypeCode UnqualifiedType (TypeCode T) /* Return the unqalified type code */ @@ -366,9 +339,39 @@ Type* IndirectModifiable (Type* T); ** given type points to. */ +Type* NewPointerTo (const Type* T); +/* Return a type string that is "pointer to T". The type string is allocated +** on the heap and may be freed after use. +*/ + +const Type* AddressOf (const Type* T); +/* Return a type string that is "address of T". The type string is allocated +** on the heap and may be freed after use. +*/ + Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ +const Type* PtrConversion (const Type* T); +/* If the type is a function, convert it to pointer to function. If the +** expression is an array, convert it to pointer to first element. Otherwise +** return T. +*/ + +const Type* IntPromotion (const Type* T); +/* Apply the integer promotions to T and return the result. The returned type +** string may be T if there is no need to change it. +*/ + +const Type* ArithmeticConvert (const Type* lhst, const Type* rhst); +/* Perform the usual arithmetic conversions for binary operators. */ + +const Type* SignedType (const Type* T); +/* Get signed counterpart of the integral type */ + +const Type* UnsignedType (const Type* T); +/* Get unsigned counterpart of the integral type */ + #if defined(HAVE_INLINE) INLINE TypeCode GetRawType (const Type* T) /* Get the raw type */ @@ -892,17 +895,6 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -const Type* IntPromotion (const Type* T); -/* Apply the integer promotions to T and return the result. The returned type -** string may be T if there is no need to change it. -*/ - -const Type* PtrConversion (const Type* T); -/* If the type is a function, convert it to pointer to function. If the -** expression is an array, convert it to pointer to first element. Otherwise -** return T. -*/ - TypeCode AddrSizeQualifier (unsigned AddrSize); /* Return T_QUAL_NEAR or T_QUAL_FAR depending on the address size */ @@ -926,6 +918,28 @@ INLINE TypeCode DataAddrSizeQualifier (void) # define DataAddrSizeQualifier() (AddrSizeQualifier (DataAddrSize)) #endif +int TypeHasAttr (const Type* T); +/* Return true if the given type has attribute data */ + +#if defined(HAVE_INLINE) +INLINE void CopyTypeAttr (const Type* Src, Type* Dest) +/* Copy attribute data from Src to Dest */ +{ + Dest->A = Src->A; +} +#else +# define CopyTypeAttr(Src, Dest) ((Dest)->A = (Src)->A) +#endif + +void PrintType (FILE* F, const Type* T); +/* Print fulle name of the type */ + +void PrintFuncSig (FILE* F, const char* Name, const Type* T); +/* Print a function signature */ + +void PrintRawType (FILE* F, const Type* T); +/* Print a type string in raw hex format (for debugging) */ + /* End of datatype.h */ diff --git a/src/cc65/expr.c b/src/cc65/expr.c index b68b3abbb..729b26942 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -153,65 +153,6 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) -/* Perform the usual arithmetic conversions for binary operators. */ -{ - /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 - ** Many binary operators that expect operands of arithmetic type cause conversions and yield - ** result types in a similar way. The purpose is to yield a common type, which is also the type - ** of the result. This pattern is called the usual arithmetic conversions. - */ - - /* There are additional rules for floating point types that we don't bother with, since - ** floating point types are not (yet) supported. - ** The integral promotions are performed on both operands. - */ - lhst = IntPromotion (lhst); - rhst = IntPromotion (rhst); - - /* If either operand has type unsigned long int, the other operand is converted to - ** unsigned long int. - */ - if ((IsTypeLong (lhst) && IsSignUnsigned (lhst)) || - (IsTypeLong (rhst) && IsSignUnsigned (rhst))) { - return type_ulong; - } - - /* Otherwise, if one operand has type long int and the other has type unsigned int, - ** if a long int can represent all values of an unsigned int, the operand of type unsigned int - ** is converted to long int ; if a long int cannot represent all the values of an unsigned int, - ** both operands are converted to unsigned long int. - */ - if ((IsTypeLong (lhst) && IsTypeInt (rhst) && IsSignUnsigned (rhst)) || - (IsTypeLong (rhst) && IsTypeInt (lhst) && IsSignUnsigned (lhst))) { - /* long can represent all unsigneds, so we are in the first sub-case. */ - return type_long; - } - - /* Otherwise, if either operand has type long int, the other operand is converted to long int. - */ - if (IsTypeLong (lhst) || IsTypeLong (rhst)) { - return type_long; - } - - /* Otherwise, if either operand has type unsigned int, the other operand is converted to - ** unsigned int. - */ - if ((IsTypeInt (lhst) && IsSignUnsigned (lhst)) || - (IsTypeInt (rhst) && IsSignUnsigned (rhst))) { - return type_uint; - } - - /* Otherwise, both operands have type int. */ - CHECK (IsTypeInt (lhst)); - CHECK (IsSignSigned (lhst)); - CHECK (IsTypeInt (rhst)); - CHECK (IsSignSigned (rhst)); - return type_int; -} - - - static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. @@ -263,7 +204,7 @@ static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) -static void LimitExprValue (ExprDesc* Expr) +void LimitExprValue (ExprDesc* Expr) /* Limit the constant value of the expression to the range of its type */ { switch (GetUnderlyingTypeCode (Expr->Type)) { diff --git a/src/cc65/expr.h b/src/cc65/expr.h index 02f9f7a5f..4909815ee 100644 --- a/src/cc65/expr.h +++ b/src/cc65/expr.h @@ -44,6 +44,9 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr); ** generated code. */ +void LimitExprValue (ExprDesc* Expr); +/* Limit the constant value of the expression to the range of its type */ + void PushAddr (const ExprDesc* Expr); /* If the expression contains an address that was somehow evaluated, ** push this address on the stack. This is a helper function for all From 004c60de396398a14bd75b17ef0f260c9ae19499 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 15 Apr 2021 22:46:25 +0800 Subject: [PATCH 2108/2161] Optional flags for the codegen to skip restoring the expression results into the primary registers. --- src/cc65/codegen.c | 71 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 22 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index f8a1dcdf6..cf10314b9 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -1166,7 +1166,9 @@ void g_putind (unsigned Flags, unsigned Offs) /* Overflow - we need to add the low byte also */ AddCodeLine ("ldy #$00"); AddCodeLine ("clc"); - AddCodeLine ("pha"); + if ((Flags & CF_NOKEEP) == 0) { + AddCodeLine ("pha"); + } AddCodeLine ("lda #$%02X", Offs & 0xFF); AddCodeLine ("adc (sp),y"); AddCodeLine ("sta (sp),y"); @@ -1174,7 +1176,9 @@ void g_putind (unsigned Flags, unsigned Offs) AddCodeLine ("lda #$%02X", (Offs >> 8) & 0xFF); AddCodeLine ("adc (sp),y"); AddCodeLine ("sta (sp),y"); - AddCodeLine ("pla"); + if ((Flags & CF_NOKEEP) == 0) { + AddCodeLine ("pla"); + } /* Complete address is on stack, new offset is zero */ Offs = 0; @@ -1184,12 +1188,15 @@ void g_putind (unsigned Flags, unsigned Offs) /* We can just add the high byte */ AddCodeLine ("ldy #$01"); AddCodeLine ("clc"); - AddCodeLine ("pha"); + if ((Flags & CF_NOKEEP) == 0) { + AddCodeLine ("pha"); + } AddCodeLine ("lda #$%02X", (Offs >> 8) & 0xFF); AddCodeLine ("adc (sp),y"); AddCodeLine ("sta (sp),y"); - AddCodeLine ("pla"); - + if ((Flags & CF_NOKEEP) == 0) { + AddCodeLine ("pla"); + } /* Offset is now just the low byte */ Offs &= 0x00FF; } @@ -1696,7 +1703,9 @@ void g_addeqstatic (unsigned flags, uintptr_t label, long offs, if (flags & CF_CONST) { if (val == 1) { AddCodeLine ("inc %s", lbuf); - AddCodeLine ("lda %s", lbuf); + if ((flags & CF_NOKEEP) == 0) { + AddCodeLine ("lda %s", lbuf); + } } else { AddCodeLine ("lda #$%02X", (int)(val & 0xFF)); AddCodeLine ("clc"); @@ -1726,8 +1735,10 @@ void g_addeqstatic (unsigned flags, uintptr_t label, long offs, AddCodeLine ("bne %s", LocalLabelName (L)); AddCodeLine ("inc %s+1", lbuf); g_defcodelabel (L); - AddCodeLine ("lda %s", lbuf); /* Hmmm... */ - AddCodeLine ("ldx %s+1", lbuf); + if ((flags & CF_NOKEEP) == 0) { + AddCodeLine ("lda %s", lbuf); /* Hmmm... */ + AddCodeLine ("ldx %s+1", lbuf); + } } else { AddCodeLine ("lda #$%02X", (int)(val & 0xFF)); AddCodeLine ("clc"); @@ -1738,13 +1749,17 @@ void g_addeqstatic (unsigned flags, uintptr_t label, long offs, AddCodeLine ("bcc %s", LocalLabelName (L)); AddCodeLine ("inc %s+1", lbuf); g_defcodelabel (L); - AddCodeLine ("ldx %s+1", lbuf); + if ((flags & CF_NOKEEP) == 0) { + AddCodeLine ("ldx %s+1", lbuf); + } } else { AddCodeLine ("lda #$%02X", (unsigned char)(val >> 8)); AddCodeLine ("adc %s+1", lbuf); AddCodeLine ("sta %s+1", lbuf); - AddCodeLine ("tax"); - AddCodeLine ("lda %s", lbuf); + if ((flags & CF_NOKEEP) == 0) { + AddCodeLine ("tax"); + AddCodeLine ("lda %s", lbuf); + } } } } else { @@ -1754,8 +1769,10 @@ void g_addeqstatic (unsigned flags, uintptr_t label, long offs, AddCodeLine ("txa"); AddCodeLine ("adc %s+1", lbuf); AddCodeLine ("sta %s+1", lbuf); - AddCodeLine ("tax"); - AddCodeLine ("lda %s", lbuf); + if ((flags & CF_NOKEEP) == 0) { + AddCodeLine ("tax"); + AddCodeLine ("lda %s", lbuf); + } } break; @@ -1837,9 +1854,11 @@ void g_addeqlocal (unsigned flags, int Offs, unsigned long val) AddCodeLine ("lda #$%02X", (int) ((val >> 8) & 0xFF)); AddCodeLine ("adc (sp),y"); AddCodeLine ("sta (sp),y"); - AddCodeLine ("tax"); - AddCodeLine ("dey"); - AddCodeLine ("lda (sp),y"); + if ((flags & CF_NOKEEP) == 0) { + AddCodeLine ("tax"); + AddCodeLine ("dey"); + AddCodeLine ("lda (sp),y"); + } } else { g_getimmed (flags, val, 0); AddCodeLine ("jsr addeqysp"); @@ -1919,7 +1938,9 @@ void g_subeqstatic (unsigned flags, uintptr_t label, long offs, if (flags & CF_CONST) { if (val == 1) { AddCodeLine ("dec %s", lbuf); - AddCodeLine ("lda %s", lbuf); + if ((flags & CF_NOKEEP) == 0) { + AddCodeLine ("lda %s", lbuf); + } } else { AddCodeLine ("lda %s", lbuf); AddCodeLine ("sec"); @@ -1953,13 +1974,17 @@ void g_subeqstatic (unsigned flags, uintptr_t label, long offs, AddCodeLine ("bcs %s", LocalLabelName (L)); AddCodeLine ("dec %s+1", lbuf); g_defcodelabel (L); - AddCodeLine ("ldx %s+1", lbuf); + if ((flags & CF_NOKEEP) == 0) { + AddCodeLine ("ldx %s+1", lbuf); + } } else { AddCodeLine ("lda %s+1", lbuf); AddCodeLine ("sbc #$%02X", (unsigned char)(val >> 8)); AddCodeLine ("sta %s+1", lbuf); - AddCodeLine ("tax"); - AddCodeLine ("lda %s", lbuf); + if ((flags & CF_NOKEEP) == 0) { + AddCodeLine ("tax"); + AddCodeLine ("lda %s", lbuf); + } } } else { AddCodeLine ("eor #$FF"); @@ -1970,8 +1995,10 @@ void g_subeqstatic (unsigned flags, uintptr_t label, long offs, AddCodeLine ("eor #$FF"); AddCodeLine ("adc %s+1", lbuf); AddCodeLine ("sta %s+1", lbuf); - AddCodeLine ("tax"); - AddCodeLine ("lda %s", lbuf); + if ((flags & CF_NOKEEP) == 0) { + AddCodeLine ("tax"); + AddCodeLine ("lda %s", lbuf); + } } break; From 1d7bf7355cb26d2da330d0173cecb5aa3213e1da Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sun, 16 May 2021 19:08:43 +0800 Subject: [PATCH 2109/2161] Better function naming in declare.c. Scalar initialization routines need only 'const Type*' as parameters. --- src/cc65/declare.c | 80 +++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index a18c837b9..2aa620a29 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2243,7 +2243,7 @@ static void DefineData (ExprDesc* Expr) -static void OutputBitFieldData (StructInitData* SI) +static void DefineBitFieldData (StructInitData* SI) /* Output bit field data */ { /* Ignore if we have no data */ @@ -2266,7 +2266,18 @@ static void OutputBitFieldData (StructInitData* SI) -static ExprDesc ParseScalarInitInternal (Type* T) +static void DefineStrData (Literal* Lit, unsigned Count) +{ + /* Translate into target charset */ + TranslateLiteral (Lit); + + /* Output the data */ + g_defbytes (GetLiteralStr (Lit), Count); +} + + + +static ExprDesc ParseScalarInitInternal (const Type* T) /* Parse initializaton for scalar data types. This function will not output the ** data but return it in ED. */ @@ -2293,7 +2304,7 @@ static ExprDesc ParseScalarInitInternal (Type* T) -static unsigned ParseScalarInit (Type* T) +static unsigned ParseScalarInit (const Type* T) /* Parse initializaton for scalar data types. Return the number of data bytes. */ { /* Parse initialization */ @@ -2311,7 +2322,7 @@ static unsigned ParseScalarInit (Type* T) -static unsigned ParsePointerInit (Type* T) +static unsigned ParsePointerInit (const Type* T) /* Parse initializaton for pointer data types. Return the number of data bytes. */ { /* Optional opening brace */ @@ -2364,9 +2375,6 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) NextToken (); } - /* Translate into target charset */ - TranslateLiteral (CurTok.SVal); - /* If the array is one too small for the string literal, omit the ** trailing zero. */ @@ -2379,7 +2387,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) } /* Output the data */ - g_defbytes (GetLiteralStr (CurTok.SVal), Count); + DefineStrData (CurTok.SVal, Count); /* Skip the string */ NextToken (); @@ -2453,7 +2461,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) /* Parse initialization of a struct or union. Return the number of data bytes. */ { - SymEntry* Entry; + SymEntry* Sym; SymTable* Tab; StructInitData SI; int HasCurly = 0; @@ -2468,15 +2476,15 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) } /* Get a pointer to the struct entry from the type */ - Entry = GetESUSymEntry (T); + Sym = GetESUSymEntry (T); /* Get the size of the struct from the symbol table entry */ - SI.Size = Entry->V.S.Size; + SI.Size = Sym->V.S.Size; /* Check if this struct definition has a field table. If it doesn't, it ** is an incomplete definition. */ - Tab = Entry->V.S.SymTab; + Tab = Sym->V.S.SymTab; if (Tab == 0) { Error ("Cannot initialize variables with incomplete type"); /* Try error recovery */ @@ -2486,7 +2494,7 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) } /* Get a pointer to the list of symbols */ - Entry = Tab->SymHead; + Sym = Tab->SymHead; /* Initialize fields */ SI.Offs = 0; @@ -2495,7 +2503,7 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) while (CurTok.Tok != TOK_RCURLY) { /* Check for excess elements */ - if (Entry == 0) { + if (Sym == 0) { /* Is there just one trailing comma before a closing curly? */ if (NextTok.Tok == TOK_RCURLY && CurTok.Tok == TOK_COMMA) { /* Skip comma and exit scope */ @@ -2511,7 +2519,7 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) } /* Check for special members that don't consume the initializer */ - if ((Entry->Flags & SC_ALIAS) == SC_ALIAS) { + if ((Sym->Flags & SC_ALIAS) == SC_ALIAS) { /* Just skip */ goto NextMember; } @@ -2519,17 +2527,17 @@ 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 (Entry) && (IsAnonName (Entry->Name))) { + if (SymIsBitField (Sym) && (IsAnonName (Sym->Name))) { /* Account for the data and output it if we have at least a full ** word. We may have more if there was storage unit overlap, for ** example two consecutive 10 bit fields. These will be packed ** into 3 bytes. */ - SI.ValBits += Entry->V.B.BitWidth; + SI.ValBits += Sym->V.B.BitWidth; /* TODO: Generalize this so any type can be used. */ CHECK (SI.ValBits <= CHAR_BITS + INT_BITS - 2); while (SI.ValBits >= CHAR_BITS) { - OutputBitFieldData (&SI); + DefineBitFieldData (&SI); } /* Avoid consuming the comma if any */ goto NextMember; @@ -2541,7 +2549,7 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) SkipComma = 0; } - if (SymIsBitField (Entry)) { + if (SymIsBitField (Sym)) { /* Parse initialization of one field. Bit-fields need a special ** handling. @@ -2552,14 +2560,14 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) unsigned Shift; /* Calculate the bitmask from the bit-field data */ - unsigned Mask = (1U << Entry->V.B.BitWidth) - 1U; + unsigned Mask = (1U << Sym->V.B.BitWidth) - 1U; /* Safety ... */ - CHECK (Entry->V.B.Offs * CHAR_BITS + Entry->V.B.BitOffs == - SI.Offs * CHAR_BITS + SI.ValBits); + CHECK (Sym->V.B.Offs * CHAR_BITS + Sym->V.B.BitOffs == + SI.Offs * CHAR_BITS + SI.ValBits); /* Read the data, check for a constant integer, do a range check */ - ED = ParseScalarInitInternal (Entry->Type); + ED = ParseScalarInitInternal (Sym->Type); if (!ED_IsConstAbsInt (&ED)) { Error ("Constant initializer expected"); ED_MakeConstAbsInt (&ED, 1); @@ -2569,31 +2577,31 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) ** any useful bits. */ Val = (unsigned) ED.IVal & Mask; - if (IsSignUnsigned (Entry->Type)) { + if (IsSignUnsigned (Sym->Type)) { if (ED.IVal < 0 || (unsigned long) ED.IVal != Val) { Warning ("Implicit truncation from '%s' to '%s : %u' in bit-field initializer" " changes value from %ld to %u", - GetFullTypeName (ED.Type), GetFullTypeName (Entry->Type), - Entry->V.B.BitWidth, ED.IVal, Val); + GetFullTypeName (ED.Type), GetFullTypeName (Sym->Type), + Sym->V.B.BitWidth, ED.IVal, Val); } } else { /* Sign extend back to full width of host long. */ - unsigned ShiftBits = sizeof (long) * CHAR_BIT - Entry->V.B.BitWidth; + unsigned ShiftBits = sizeof (long) * CHAR_BIT - Sym->V.B.BitWidth; long RestoredVal = asr_l(asl_l (Val, ShiftBits), ShiftBits); if (ED.IVal != RestoredVal) { Warning ("Implicit truncation from '%s' to '%s : %u' in bit-field initializer " "changes value from %ld to %ld", - GetFullTypeName (ED.Type), GetFullTypeName (Entry->Type), - Entry->V.B.BitWidth, ED.IVal, RestoredVal); + GetFullTypeName (ED.Type), GetFullTypeName (Sym->Type), + Sym->V.B.BitWidth, ED.IVal, RestoredVal); } } /* Add the value to the currently stored bit-field value */ - Shift = (Entry->V.B.Offs - SI.Offs) * CHAR_BITS + Entry->V.B.BitOffs; + Shift = (Sym->V.B.Offs - SI.Offs) * CHAR_BITS + Sym->V.B.BitOffs; SI.BitVal |= (Val << Shift); /* Account for the data and output any full bytes we have. */ - SI.ValBits += Entry->V.B.BitWidth; + SI.ValBits += Sym->V.B.BitWidth; /* Make sure unsigned is big enough to hold the value, 22 bits. ** This is 22 bits because the most we can have is 7 bits left ** over from the previous OutputBitField call, plus 15 bits @@ -2604,7 +2612,7 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) /* TODO: Generalize this so any type can be used. */ CHECK (SI.ValBits <= CHAR_BITS + INT_BITS - 2); while (SI.ValBits >= CHAR_BITS) { - OutputBitFieldData (&SI); + DefineBitFieldData (&SI); } } else { @@ -2618,7 +2626,7 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) /* Flexible array members may only be initialized if they are ** the last field (or part of the last struct field). */ - SI.Offs += ParseInitInternal (Entry->Type, Braces, AllowFlexibleMembers && Entry->NextSym == 0); + SI.Offs += ParseInitInternal (Sym->Type, Braces, AllowFlexibleMembers && Sym->NextSym == 0); } /* More initializers? */ @@ -2633,10 +2641,10 @@ NextMember: /* Next member. For unions, only the first one can be initialized */ if (IsTypeUnion (T)) { /* Union */ - Entry = 0; + Sym = 0; } else { /* Struct */ - Entry = Entry->NextSym; + Sym = Sym->NextSym; } } @@ -2647,7 +2655,7 @@ NextMember: /* If we have data from a bit-field left, output it now */ CHECK (SI.ValBits < CHAR_BITS); - OutputBitFieldData (&SI); + DefineBitFieldData (&SI); /* If there are struct fields left, reserve additional storage */ if (SI.Offs < SI.Size) { From 5adb29ce3165db1c5f525dc9a0b8160170e4613c Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Sat, 22 May 2021 19:15:47 +0800 Subject: [PATCH 2110/2161] Made "bit-field-ness" a type property instead of a SymbolEntry or ExprDesc property. Fixed integer promotion and result type in certain operations. Fixed bit-fields 'op=' and postfix inc/dec operators. --- src/cc65/assignment.c | 811 +++++++++++++++++++++++++++++++++++------- src/cc65/assignment.h | 28 +- src/cc65/datatype.c | 74 +++- src/cc65/datatype.h | 108 ++++-- src/cc65/declare.c | 20 +- src/cc65/expr.c | 720 +++++++++++-------------------------- src/cc65/expr.h | 8 + src/cc65/exprdesc.c | 44 +-- src/cc65/exprdesc.h | 40 +-- src/cc65/loadexpr.c | 66 ++-- src/cc65/stdfunc.c | 10 +- src/cc65/symentry.h | 7 - src/cc65/symtab.c | 12 +- src/cc65/typecmp.c | 15 + src/cc65/typeconv.c | 12 +- 15 files changed, 1171 insertions(+), 804 deletions(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index 7ebd2c4e1..be6a8116f 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -42,19 +42,35 @@ #include "expr.h" #include "loadexpr.h" #include "scanner.h" +#include "stackptr.h" #include "stdnames.h" #include "typecmp.h" #include "typeconv.h" +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Map a generator function and its attributes to a token */ +typedef struct GenDesc { + token_t Tok; /* Token to map to */ + unsigned Flags; /* Flags for generator function */ + void (*Func) (unsigned, unsigned long); /* Generator func */ +} GenDesc; + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ -static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) +static void CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) /* Copy the struct/union represented by RExpr to the one represented by LExpr */ { /* If the size is that of a basic type (char, int, long), we will copy @@ -127,14 +143,519 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) ** to a boolean in C, but there is no harm to be future-proof. */ ED_MarkAsUntested (LExpr); - - return 1; } -void Assignment (ExprDesc* Expr) -/* Parse an assignment */ +void DoIncDecBitField (ExprDesc* Expr, long Val, unsigned KeepResult) +/* Process inc/dec for bit-field */ +{ + int AddrSP; + unsigned Flags; /* Internal codegen flags */ + unsigned Mask; + unsigned ChunkFlags; + const Type* ChunkType; + const Type* ResType; + + /* If the bit-field fits within one byte, do the following operations + ** with bytes. + */ + if ((Expr->Type->A.B.Width - 1U) / CHAR_BITS == + (Expr->Type->A.B.Offs + Expr->Type->A.B.Width - 1U) / CHAR_BITS) { + ChunkType = GetUnderlyingType (Expr->Type); + } else { + /* We use the declarartion integer type as the chunk type. + ** Note: A bit-field will not occupy bits located in bytes more than + ** that of its declaration type in cc65. So this is OK. + */ + ChunkType = Expr->Type + 1; + } + + /* Determine code generator flags */ + Flags = TypeOf (Expr->Type) | CF_FORCECHAR; + ChunkFlags = TypeOf (ChunkType); + if ((ChunkFlags & CF_TYPEMASK) == CF_CHAR) { + ChunkFlags |= CF_FORCECHAR; + } + + /* Get the address on stack for the store */ + PushAddr (Expr); + + /* We may need the pushed address later */ + AddrSP = StackPtr; + + /* Get bit mask to limit the range of the value */ + Mask = (0x0001U << Expr->Type->A.B.Width) - 1U; + + /* Fetch the lhs into the primary register if needed */ + LoadExpr (CF_NONE, Expr); + + if (KeepResult == OA_NEED_OLD) { + /* Save the original expression value */ + g_save (Flags | CF_FORCECHAR); + } + + /* Handle for add and sub */ + if (Val > 0) { + g_inc (Flags | CF_CONST, Val); + } else if (Val < 0) { + g_dec (Flags | CF_CONST, -Val); + } + + /* Apply the mask */ + g_and (Flags | CF_CONST, Mask); + + if (KeepResult == OA_NEED_NEW) { + /* Save the result value */ + g_save (Flags | CF_FORCECHAR); + } + + /* Do integral promotion without sign-extension if needed */ + g_typecast (ChunkFlags | CF_UNSIGNED, Flags); + + /* Shift it into the right position */ + g_asl (ChunkFlags | CF_CONST, Expr->Type->A.B.Offs); + + /* Push the interim result on stack */ + g_push (ChunkFlags & ~CF_FORCECHAR, 0); + + /* If the original lhs was using the primary, it is now accessible only via + ** the pushed address. Reload that address. + */ + if (ED_IsLocPrimaryOrExpr (Expr)) { + g_getlocal (CF_PTR, AddrSP); + } + + /* Load the whole data chunk containing the bits to be changed */ + LoadExpr (ChunkFlags, Expr); + + /* Get the bits that are not to be affected */ + g_and (ChunkFlags | CF_CONST, ~(Mask << Expr->Type->A.B.Offs)); + + /* Restore the bits that are not to be affected */ + g_or (ChunkFlags & ~CF_FORCECHAR, 0); + + /* Store the whole data chunk containing the changed bits back */ + Store (Expr, ChunkType); + + /* Cache the expression result type */ + ResType = IntPromotion (Expr->Type); + + if (KeepResult != OA_NEED_NONE) { + /* Restore the expression result value */ + g_restore (Flags | CF_FORCECHAR); + + /* Promote if needed */ + if (KeepResult != OA_NEED_OLD) { + /* Do unsigned promotion first */ + g_typecast (TypeOf (ResType) | CF_UNSIGNED, Flags); + + /* Then do sign-extension */ + if (IsSignSigned (Expr->Type) && + Expr->Type->A.B.Width < CHAR_BITS * SizeOf (ResType)) { + /* The way is: + ** x = bits & bit_mask + ** m = 1 << (bit_width - 1) + ** r = (x ^ m) - m + ** Since we have already masked bits with bit_mask, we may skip the + ** first step. + */ + g_xor (Flags | CF_CONST, 1U << (Expr->Type->A.B.Width - 1U)); + g_dec ((Flags & ~CF_FORCECHAR) | CF_CONST, 1U << (Expr->Type->A.B.Width - 1U)); + } + } else { + /* Do promotion with sign-extension */ + g_typecast (TypeOf (ResType), Flags); + } + } + + /* Get the expression result type */ + Expr->Type = ResType; +} + + + +static void OpAssignBitField (const GenDesc* Gen, ExprDesc* Expr, const char* Op) +/* Parse an "=" (if 'Gen' is 0) or "op=" operation for bit-field lhs */ +{ + ExprDesc Expr2; + CodeMark PushPos; + int AddrSP; + unsigned Mask; + unsigned Flags; + unsigned ChunkFlags; + const Type* ChunkType; + const Type* ResType; + + /* Cache the expression result type */ + ResType = IntPromotion (Expr->Type); + + ED_Init (&Expr2); + Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; + + /* If the bit-field fits within one byte, do the following operations + ** with bytes. + */ + if ((Expr->Type->A.B.Width - 1U) / CHAR_BITS == + (Expr->Type->A.B.Offs + Expr->Type->A.B.Width - 1U) / CHAR_BITS) { + ChunkType = GetUnderlyingType (Expr->Type); + } else { + /* We use the declarartion integer type as the chunk type. + ** Note: A bit-field will not occupy bits located in bytes more than + ** that of its declaration type in cc65. So this is OK. + */ + ChunkType = Expr->Type + 1; + } + + /* Determine code generator flags */ + Flags = TypeOf (Expr->Type) | CF_FORCECHAR; + ChunkFlags = TypeOf (ChunkType); + if ((ChunkFlags & CF_TYPEMASK) == CF_CHAR) { + ChunkFlags |= CF_FORCECHAR; + } + + /* Get the address on stack for the store */ + PushAddr (Expr); + + /* We may need the pushed address later */ + AddrSP = StackPtr; + + /* Get bit mask to limit the range of the value */ + Mask = (0x0001U << Expr->Type->A.B.Width) - 1U; + + if (Gen != 0) { + + /* Fetch the lhs into the primary register if needed */ + LoadExpr (CF_NONE, Expr); + + /* Backup them on stack */ + GetCodePos (&PushPos); + g_push (Flags & ~CF_FORCECHAR, 0); + + } + + /* Read the expression on the right side of the '=' or 'op=' */ + MarkedExprWithCheck (hie1, &Expr2); + + /* The rhs must be an integer (or a float, but we don't support that yet */ + if (!IsClassInt (Expr2.Type)) { + Error ("Invalid right operand for binary operator '%s'", Op); + /* Continue. Wrong code will be generated, but the compiler won't + ** break, so this is the best error recovery. + */ + } + + /* Special treatment if the value is constant. + ** Beware: Expr2 may contain side effects, so there must not be + ** code generated for Expr2. + */ + if (ED_IsConstAbsInt (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) { + + if (Gen == 0) { + + /* Get the value and apply the mask */ + unsigned Val = (unsigned)(Expr2.IVal & Mask); + + /* Load the whole data chunk containing the bits to be changed */ + LoadExpr (ChunkFlags, Expr); + + /* If the value is equal to the mask now, all bits are one, and we + ** can skip the mask operation. + */ + if (Val != Mask) { + /* Get the bits that are not to be affected */ + g_and (ChunkFlags | CF_CONST, ~(Mask << Expr->Type->A.B.Offs)); + } + + /* Restore the bits that are not to be affected */ + g_or (ChunkFlags | CF_CONST, Val << Expr->Type->A.B.Offs); + + /* Store the whole data chunk containing the changed bits back */ + Store (Expr, ChunkType); + + /* Load the expression result value */ + if (IsSignSigned (Expr->Type)) { + unsigned SignExtensionMask = 1 << (Expr->Type->A.B.Width - 1); + Val = (Val^ SignExtensionMask) - SignExtensionMask; + } + ED_MakeConstAbs (Expr, Val, ResType); + LimitExprValue (Expr); + LoadExpr (CF_NONE, Expr); + + /* Done */ + goto Done; + + } else { + + /* Since we will operate with a constant, we can remove the push if + ** the generator has the NOPUSH flag set. + */ + if (Gen->Flags & GEN_NOPUSH) { + RemoveCode (&PushPos); + } + + /* Special handling for add and sub - some sort of a hack, but short code */ + if (Gen->Func == g_add) { + g_inc (Flags | CF_CONST, Expr2.IVal); + } else if (Gen->Func == g_sub) { + g_dec (Flags | CF_CONST, Expr2.IVal); + } else { + if (Expr2.IVal == 0) { + /* Check for div by zero/mod by zero */ + if (Gen->Func == g_div) { + Error ("Division by zero"); + } else if (Gen->Func == g_mod) { + Error ("Modulo operation with zero"); + } + } + + /* Adjust the types of the operands if needed */ + if (Gen->Func == g_div || Gen->Func == g_mod) { + unsigned AdjustedFlags = Flags; + if (Expr->Type->A.B.Width < INT_BITS || IsSignSigned (Expr->Type)) { + AdjustedFlags = (Flags & ~CF_UNSIGNED) | CF_CONST; + AdjustedFlags = g_typeadjust (AdjustedFlags, TypeOf (Expr2.Type) | CF_CONST); + } + Gen->Func (g_typeadjust (Flags, AdjustedFlags) | CF_CONST, Expr2.IVal); + } else { + Gen->Func ((Flags & ~CF_FORCECHAR) | CF_CONST, Expr2.IVal); + } + } + + } + + } else { + + /* Do 'op' if provided */ + if (Gen != 0) { + + /* Load rhs into the primary */ + LoadExpr (CF_NONE, &Expr2); + + /* Adjust the types of the operands if needed */ + if (Gen->Func == g_div || Gen->Func == g_mod) { + unsigned AdjustedFlags = Flags; + if (Expr->Type->A.B.Width < INT_BITS || IsSignSigned (Expr->Type)) { + AdjustedFlags = (Flags & ~CF_UNSIGNED) | CF_CONST; + AdjustedFlags = g_typeadjust (AdjustedFlags, TypeOf (Expr2.Type) | CF_CONST); + } + Gen->Func (g_typeadjust (Flags, AdjustedFlags), 0); + } else { + Gen->Func (g_typeadjust (Flags, TypeOf (Expr2.Type)), 0); + } + + } else { + + /* Do type conversion if necessary */ + TypeConversion (&Expr2, Expr->Type); + + /* If necessary, load rhs into the primary register */ + LoadExpr (CF_NONE, &Expr2); + + } + + } + + /* Apply the mask */ + g_and (Flags | CF_CONST, Mask); + + /* Save the expression result value */ + g_save (Flags); + + /* Do integral promotion without sign-extension if needed */ + g_typecast (ChunkFlags | CF_UNSIGNED, Flags); + + /* Shift it into the right position */ + g_asl (ChunkFlags | CF_CONST, Expr->Type->A.B.Offs); + + /* Push the interim result on stack */ + g_push (ChunkFlags & ~CF_FORCECHAR, 0); + + /* If the original lhs was using the primary, it is now accessible only via + ** the pushed address. Reload that address. + */ + if (ED_IsLocPrimaryOrExpr (Expr)) { + g_getlocal (CF_PTR, AddrSP); + } + + /* Load the whole data chunk containing the bits to be changed */ + LoadExpr (ChunkFlags, Expr); + + /* Get the bits that are not to be affected */ + g_and (ChunkFlags | CF_CONST, ~(Mask << Expr->Type->A.B.Offs)); + + /* Restore the bits that are not to be affected */ + g_or (ChunkFlags & ~CF_FORCECHAR, 0); + + /* Store the whole data chunk containing the changed bits back */ + Store (Expr, ChunkType); + + /* Restore the expression result value */ + g_restore (Flags); + + /* Do unsigned promotion first */ + g_typecast (TypeOf (ResType) | CF_UNSIGNED, Flags); + + /* Then do sign-extension */ + if (IsSignSigned (Expr->Type) && + Expr->Type->A.B.Width < CHAR_BITS * SizeOf (ResType)) { + /* The way is: + ** x = bits & bit_mask + ** m = 1 << (bit_width - 1) + ** r = (x ^ m) - m + ** Since we have already masked bits with bit_mask, we may skip the + ** first step. + */ + g_xor (Flags | CF_CONST, 1U << (Expr->Type->A.B.Width - 1U)); + g_dec ((Flags & ~CF_FORCECHAR) | CF_CONST, 1U << (Expr->Type->A.B.Width - 1U)); + } + +Done: + + /* Get the expression result type */ + Expr->Type = ResType; + + /* Value is in primary as an rvalue */ + ED_FinalizeRValLoad (Expr); +} + + + +static void OpAssignArithmetic (const GenDesc* Gen, ExprDesc* Expr, const char* Op) +/* Parse an "=" (if 'Gen' is 0) or "op=" operation for arithmetic lhs */ +{ + ExprDesc Expr2; + CodeMark PushPos; + + unsigned Flags; + int MustScale; + + ED_Init (&Expr2); + Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; + + /* Determine code generator flags */ + Flags = TypeOf (Expr->Type); + + /* Determine the type of the lhs */ + MustScale = Gen != 0 && (Gen->Func == g_add || Gen->Func == g_sub) && + IsTypePtr (Expr->Type); + + /* Get the address on stack for the store */ + PushAddr (Expr); + + if (Gen == 0) { + + /* Read the expression on the right side of the '=' */ + MarkedExprWithCheck (hie1, &Expr2); + + /* Do type conversion if necessary. Beware: Do not use char type + ** here! + */ + TypeConversion (&Expr2, Expr->Type); + + /* If necessary, load the value into the primary register */ + LoadExpr (CF_NONE, &Expr2); + + } else { + + /* Load the original value if necessary */ + LoadExpr (CF_NONE, Expr); + + /* Push lhs on stack */ + GetCodePos (&PushPos); + g_push (Flags, 0); + + /* Read the expression on the right side of the '=' or 'op=' */ + MarkedExprWithCheck (hie1, &Expr2); + + /* The rhs must be an integer (or a float, but we don't support that yet */ + if (!IsClassInt (Expr2.Type)) { + Error ("Invalid right operand for binary operator '%s'", Op); + /* Continue. Wrong code will be generated, but the compiler won't + ** break, so this is the best error recovery. + */ + } + + /* Special treatment if the value is constant. + ** Beware: Expr2 may contain side effects, so there must not be + ** code generated for Expr2. + */ + if (ED_IsConstAbsInt (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) { + + /* Since we will operate with a constant, we can remove the push if + ** the generator has the NOPUSH flag set. + */ + if (Gen->Flags & GEN_NOPUSH) { + RemoveCode (&PushPos); + } + if (MustScale) { + /* lhs is a pointer, scale rhs */ + Expr2.IVal *= CheckedSizeOf (Expr->Type+1); + } + + /* If the lhs is character sized, the operation may be later done + ** with characters. + */ + if (CheckedSizeOf (Expr->Type) == SIZEOF_CHAR) { + Flags |= CF_FORCECHAR; + } + + /* Special handling for add and sub - some sort of a hack, but short code */ + if (Gen->Func == g_add) { + g_inc (Flags | CF_CONST, Expr2.IVal); + } else if (Gen->Func == g_sub) { + g_dec (Flags | CF_CONST, Expr2.IVal); + } else { + if (Expr2.IVal == 0) { + /* Check for div by zero/mod by zero */ + if (Gen->Func == g_div) { + Error ("Division by zero"); + } else if (Gen->Func == g_mod) { + Error ("Modulo operation with zero"); + } + } + Gen->Func (Flags | CF_CONST, Expr2.IVal); + } + + } else { + + /* If necessary, load the value into the primary register */ + LoadExpr (CF_NONE, &Expr2); + + if (MustScale) { + /* lhs is a pointer, scale rhs */ + g_scale (TypeOf (Expr2.Type), CheckedSizeOf (Expr->Type+1)); + } + + /* If the lhs is character sized, the operation may be later done + ** with characters. + */ + if (CheckedSizeOf (Expr->Type) == SIZEOF_CHAR) { + Flags |= CF_FORCECHAR; + } + + /* Adjust the types of the operands if needed */ + Gen->Func (g_typeadjust (Flags, TypeOf (Expr2.Type)), 0); + + } + } + + /* Generate a store instruction */ + Store (Expr, 0); + + /* Get the expression result type */ + if (IsClassInt (Expr->Type)) { + Expr->Type = IntPromotion (Expr->Type); + } + + /* Value is in primary as an rvalue */ + ED_FinalizeRValLoad (Expr); +} + + + +void OpAssign (const GenDesc* Gen, ExprDesc* Expr, const char* Op) +/* Parse an "=" (if 'Gen' is 0) or "op=" operation */ { const Type* ltype = Expr->Type; @@ -142,28 +663,32 @@ void Assignment (ExprDesc* Expr) ED_Init (&Expr2); Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* We must have an lvalue for an assignment */ - if (ED_IsRVal (Expr)) { - if (IsTypeArray (Expr->Type)) { - Error ("Array type '%s' is not assignable", GetFullTypeName (Expr->Type)); - } else if (IsTypeFunc (Expr->Type)) { - Error ("Function type '%s' is not assignable", GetFullTypeName (Expr->Type)); - } else { - Error ("Assignment to rvalue"); + /* Only "=" accept struct/union */ + if (IsClassStruct (ltype) ? Gen != 0 : !IsClassScalar (ltype)) { + Error ("Invalid left operand for binary operator '%s'", Op); + /* Continue. Wrong code will be generated, but the compiler won't + ** break, so this is the best error recovery. + */ + } else { + /* Check for assignment to incomplete type */ + if (IsIncompleteESUType (ltype)) { + Error ("Assignment to incomplete type '%s'", GetFullTypeName (ltype)); + } else if (ED_IsRVal (Expr)) { + /* Assignment can only be used with lvalues */ + if (IsTypeArray (ltype)) { + Error ("Array type '%s' is not assignable", GetFullTypeName (ltype)); + } else if (IsTypeFunc (ltype)) { + Error ("Function type '%s' is not assignable", GetFullTypeName (ltype)); + } else { + Error ("Assignment to rvalue"); + } + } else if (IsQualConst (ltype)) { + /* Check for assignment to const */ + Error ("Assignment to const"); } } - /* Check for assignment to const */ - if (IsQualConst (ltype)) { - Error ("Assignment to const"); - } - - /* Check for assignment to incomplete type */ - if (IsIncompleteESUType (ltype)) { - Error ("Assignment to incomplete type '%s'", GetFullTypeName (ltype)); - } - - /* Skip the '=' token */ + /* Skip the '=' or 'op=' token */ NextToken (); /* cc65 does not have full support for handling structs or unions. Since @@ -174,114 +699,136 @@ void Assignment (ExprDesc* Expr) if (IsClassStruct (ltype)) { /* Copy the struct or union by value */ CopyStruct (Expr, &Expr2); - - } else if (ED_IsBitField (Expr)) { - - CodeMark AndPos; - CodeMark PushPos; - - unsigned Mask; - unsigned Flags; - - /* If the bit-field fits within one byte, do the following operations - ** with bytes. - */ - if (Expr->BitOffs / CHAR_BITS == (Expr->BitOffs + Expr->BitWidth - 1) / CHAR_BITS) { - Expr->Type = type_uchar; - } - - /* Determine code generator flags */ - Flags = TypeOf (Expr->Type); - - /* Assignment to a bit field. Get the address on stack for the store. */ - PushAddr (Expr); - - /* Load the value from the location */ - Expr->Flags &= ~E_BITFIELD; - LoadExpr (CF_NONE, Expr); - - /* Mask unwanted bits */ - Mask = (0x0001U << Expr->BitWidth) - 1U; - GetCodePos (&AndPos); - g_and (Flags | CF_CONST, ~(Mask << Expr->BitOffs)); - - /* Push it on stack */ - GetCodePos (&PushPos); - g_push (Flags, 0); - - /* Read the expression on the right side of the '=' */ - MarkedExprWithCheck (hie1, &Expr2); - - /* Do type conversion if necessary. Beware: Do not use char type - ** here! - */ - TypeConversion (&Expr2, ltype); - - /* Special treatment if the value is constant. */ - /* Beware: Expr2 may contain side effects, so there must not be - ** code generated for Expr2. - */ - if (ED_IsConstAbsInt (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) { - - /* Get the value and apply the mask */ - unsigned Val = (unsigned) (Expr2.IVal & Mask); - - /* Since we will do the OR with a constant, we can remove the push */ - RemoveCode (&PushPos); - - /* If the value is equal to the mask now, all bits are one, and we - ** can remove the mask operation from above. - */ - if (Val == Mask) { - RemoveCode (&AndPos); - } - - /* Generate the or operation */ - g_or (Flags | CF_CONST, Val << Expr->BitOffs); - - } else { - - /* If necessary, load the value into the primary register */ - LoadExpr (CF_NONE, &Expr2); - - /* Apply the mask */ - g_and (Flags | CF_CONST, Mask); - - /* Shift it into the right position */ - g_asl (Flags | CF_CONST, Expr->BitOffs); - - /* Or both values */ - g_or (Flags, 0); - } - - /* Generate a store instruction */ - Store (Expr, 0); - - /* Restore the expression type */ - Expr->Type = ltype; - - /* Value is in primary as an rvalue */ - ED_FinalizeRValLoad (Expr); - + } else if (IsTypeBitField (ltype)) { + /* Special care is needed for bit-field 'op=' */ + OpAssignBitField (Gen, Expr, Op); } else { - - /* Get the address on stack if needed */ - PushAddr (Expr); - - /* Read the expression on the right side of the '=' */ - hie1 (&Expr2); - - /* Do type conversion if necessary */ - TypeConversion (&Expr2, ltype); - - /* If necessary, load the value into the primary register */ - LoadExpr (CF_NONE, &Expr2); - - /* Generate a store instruction */ - Store (Expr, 0); - - /* Value is in primary as an rvalue */ - ED_FinalizeRValLoad (Expr); - + /* Normal straight 'op=' */ + OpAssignArithmetic (Gen, Expr, Op); } } + + + +void OpAddSubAssign (const GenDesc* Gen, ExprDesc *Expr, const char* Op) +/* Parse a "+=" or "-=" operation */ +{ + ExprDesc Expr2; + unsigned lflags; + unsigned rflags; + int MustScale; + + /* We currently only handle non-bit-fields in some addressing modes here */ + if (IsTypeBitField (Expr->Type) || ED_IsLocPrimaryOrExpr (Expr)) { + /* Use generic routine instead */ + OpAssign (Gen, Expr, Op); + return; + } + + /* There must be an integer or pointer on the left side */ + if (!IsClassInt (Expr->Type) && !IsTypePtr (Expr->Type)) { + Error ("Invalid left operand for binary operator '%s'", Op); + /* Continue. Wrong code will be generated, but the compiler won't + ** break, so this is the best error recovery. + */ + } else { + /* We must have an lvalue */ + if (ED_IsRVal (Expr)) { + Error ("Invalid lvalue in assignment"); + } else if (IsQualConst (Expr->Type)) { + /* The left side must not be const qualified */ + Error ("Assignment to const"); + } + } + + /* Skip the operator */ + NextToken (); + + /* Check if we have a pointer expression and must scale rhs */ + MustScale = IsTypePtr (Expr->Type); + + /* Initialize the code generator flags */ + lflags = 0; + rflags = 0; + + ED_Init (&Expr2); + Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; + + /* Evaluate the rhs. We expect an integer here, since float is not + ** supported + */ + hie1 (&Expr2); + if (!IsClassInt (Expr2.Type)) { + Error ("Invalid right operand for binary operator '%s'", Op); + /* Continue. Wrong code will be generated, but the compiler won't + ** break, so this is the best error recovery. + */ + } + + /* Setup the code generator flags */ + lflags |= TypeOf (Expr->Type) | GlobalModeFlags (Expr) | CF_FORCECHAR; + rflags |= TypeOf (Expr2.Type) | CF_FORCECHAR; + + if (ED_IsConstAbs (&Expr2)) { + /* The resulting value is a constant */ + rflags |= CF_CONST; + lflags |= CF_CONST; + + /* Scale it */ + if (MustScale) { + Expr2.IVal *= CheckedSizeOf (Indirect (Expr->Type)); + } + } else { + /* Not constant, load into the primary */ + LoadExpr (CF_NONE, &Expr2); + + /* Convert the type of the rhs to that of the lhs */ + g_typecast (lflags, rflags & ~CF_FORCECHAR); + + if (MustScale) { + /* lhs is a pointer, scale rhs */ + g_scale (TypeOf (Expr2.Type), CheckedSizeOf (Indirect (Expr->Type))); + } + } + + /* Output apropriate code depending on the location */ + switch (ED_GetLoc (Expr)) { + + case E_LOC_ABS: + case E_LOC_GLOBAL: + case E_LOC_STATIC: + case E_LOC_REGISTER: + case E_LOC_LITERAL: + case E_LOC_CODE: + /* Absolute numeric addressed variable, global variable, local + ** static variable, register variable, pooled literal or code + ** label location. + */ + if (Gen->Tok == TOK_PLUS_ASSIGN) { + g_addeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal); + } else { + g_subeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal); + } + break; + + case E_LOC_STACK: + /* Value on the stack */ + if (Gen->Tok == TOK_PLUS_ASSIGN) { + g_addeqlocal (lflags, Expr->IVal, Expr2.IVal); + } else { + g_subeqlocal (lflags, Expr->IVal, Expr2.IVal); + } + break; + + default: + Internal ("Invalid location in Store(): 0x%04X", ED_GetLoc (Expr)); + } + + /* Get the expression result type */ + if (IsClassInt (Expr->Type)) { + Expr->Type = IntPromotion (Expr->Type); + } + + /* Expression is an rvalue in the primary now */ + ED_FinalizeRValLoad (Expr); +} diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index b2cc1548b..6098118b4 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -43,14 +43,38 @@ +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Whether to save/restore the original lhs or result value */ +enum { + OA_NEED_NONE, + OA_NEED_OLD, + OA_NEED_NEW, +}; + +/* Forward */ +struct GenDesc; + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ -void Assignment (ExprDesc* lval); -/* Parse an assignment */ +void DoIncDecBitField (ExprDesc* Expr, long Val, unsigned KeepResult); +/* Process inc/dec for bit-field */ + +void OpAssign (const struct GenDesc* Gen, ExprDesc* lval, const char* Op); +/* Parse an "=" (if 'Gen' is 0) or "op=" operation */ + +void OpAddSubAssign (const struct GenDesc* Gen, ExprDesc *Expr, const char* Op); +/* Parse a "+=" or "-=" operation */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 6465c27a6..e5d3f8d96 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -207,7 +207,11 @@ static struct StrBuf* GetFullTypeNameWestEast (struct StrBuf* West, struct StrBu } } - SB_AppendStr (&Buf, GetSymTypeName (T)); + if (!IsTypeBitField (T)) { + SB_AppendStr (&Buf, GetSymTypeName (T)); + } else { + SB_AppendStr (&Buf, GetBasicTypeName (T + 1)); + } if (!SB_IsEmpty (West)) { SB_AppendChar (&Buf, ' '); @@ -231,6 +235,7 @@ const char* GetBasicTypeName (const Type* T) { switch (GetRawType (T)) { case T_TYPE_ENUM: return "enum"; + case T_TYPE_BITFIELD: return "bit-field"; case T_TYPE_FLOAT: return "float"; case T_TYPE_DOUBLE: return "double"; case T_TYPE_VOID: return "void"; @@ -581,6 +586,18 @@ const Type* GetUnderlyingType (const Type* Type) if (Type->A.S->V.E.Type != 0) { return Type->A.S->V.E.Type; } + } else if (IsTypeBitField (Type)) { + /* We consider the smallest type that can represent all values of the + ** bit-field, instead of the type used in the declaration, the truly + ** underlying of the bit-field. + */ + unsigned Size = (int)(Type->A.B.Width - 1) / (int)CHAR_BITS + 1; + switch (Size) { + case SIZEOF_CHAR: Type = IsSignSigned (Type) ? type_schar : type_uchar; break; + case SIZEOF_INT: Type = IsSignSigned (Type) ? type_int : type_uint; break; + case SIZEOF_LONG: Type = IsSignSigned (Type) ? type_long : type_ulong; break; + default: Type = IsSignSigned (Type) ? type_int : type_uint; break; + } } return Type; @@ -594,13 +611,14 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) */ { TypeCode Underlying = UnqualifiedType (Type->C); - TypeCode TCode; if (IsISOChar (Type)) { return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { + TypeCode TCode; + /* This should not happen, but just in case */ if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); @@ -623,6 +641,21 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) case T_SIZE_LONGLONG: Underlying |= T_TYPE_LONGLONG; break; default: Underlying |= T_TYPE_INT; break; } + } else if (IsTypeBitField (Type)) { + /* We consider the smallest type that can represent all values of the + ** bit-field, instead of the type used in the declaration, the truly + ** underlying of the bit-field. + */ + unsigned Size = (int)(Type->A.B.Width - 1) / (int)CHAR_BITS + 1; + switch (Size) { + case SIZEOF_CHAR: Underlying = T_CHAR; break; + case SIZEOF_INT: Underlying = T_INT; break; + case SIZEOF_LONG: Underlying = T_LONG; break; + case SIZEOF_LONGLONG: Underlying = T_LONGLONG; break; + default: Underlying = T_INT; break; + } + Underlying &= ~T_MASK_SIGN; + Underlying |= Type->C & T_MASK_SIGN; } return Underlying; @@ -933,7 +966,11 @@ const Type* IntPromotion (const Type* T) ** These are called the integral promotions. */ - if (IsTypeChar (T)) { + if (IsTypeBitField (T)) { + /* The standard rule is OK for now as we don't support bit-fields with widths > 16. + */ + return T->A.B.Width >= INT_BITS && IsSignUnsigned (T) ? type_uint : type_int; + } else if (IsTypeChar (T)) { /* An integer can represent all values from either signed or unsigned char, so convert ** chars to int. */ @@ -1059,6 +1096,37 @@ const Type* UnsignedType (const Type* T) +Type* NewBitFieldType (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. +*/ +{ + Type* P; + + /* The type specifier must be integeral */ + CHECK (IsClassInt (T)); + + /* Allocate the new type string */ + P = TypeAlloc (3); + + /* Create the return type... */ + P[0].C = IsSignSigned (T) ? T_SBITFIELD : T_UBITFIELD; + P[0].C |= (T[0].C & T_QUAL_ADDRSIZE); + P[0].A.B.Offs = BitOffs; + P[0].A.B.Width = BitWidth; + + /* Get the declaration type */ + memcpy (&P[1], GetUnderlyingType (T), sizeof (P[1])); + + /* Get done... */ + P[2].C = T_END; + + /* ...and return it */ + return P; +} + + + int IsClassObject (const Type* T) /* Return true if this is a fully described object type */ { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 4729284bd..e36d7c82e 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -78,54 +78,55 @@ enum { T_TYPE_INT = 0x000003, T_TYPE_LONG = 0x000004, T_TYPE_LONGLONG = 0x000005, - T_TYPE_ENUM = 0x000006, - T_TYPE_FLOAT = 0x000007, - T_TYPE_DOUBLE = 0x000008, - T_TYPE_VOID = 0x000009, - T_TYPE_STRUCT = 0x00000A, - T_TYPE_UNION = 0x00000B, - T_TYPE_ARRAY = 0x00000C, - T_TYPE_PTR = 0x00000D, - T_TYPE_FUNC = 0x00000E, - T_MASK_TYPE = 0x00000F, + T_TYPE_ENUM = 0x000008, + T_TYPE_BITFIELD = 0x000009, + T_TYPE_FLOAT = 0x00000A, + T_TYPE_DOUBLE = 0x00000B, + T_TYPE_VOID = 0x000010, + T_TYPE_STRUCT = 0x000011, + T_TYPE_UNION = 0x000012, + T_TYPE_ARRAY = 0x000018, + T_TYPE_PTR = 0x000019, + T_TYPE_FUNC = 0x00001A, + T_MASK_TYPE = 0x00001F, /* Type classes */ T_CLASS_NONE = 0x000000, - T_CLASS_INT = 0x000010, - T_CLASS_FLOAT = 0x000020, - T_CLASS_PTR = 0x000030, - T_CLASS_STRUCT = 0x000040, - T_CLASS_FUNC = 0x000050, - T_MASK_CLASS = 0x000070, + T_CLASS_INT = 0x000020, + T_CLASS_FLOAT = 0x000040, + T_CLASS_PTR = 0x000060, + T_CLASS_STRUCT = 0x000080, + T_CLASS_FUNC = 0x0000A0, + T_MASK_CLASS = 0x0000E0, /* Type signedness */ T_SIGN_NONE = 0x000000, - T_SIGN_UNSIGNED = 0x000080, - T_SIGN_SIGNED = 0x000100, - T_MASK_SIGN = 0x000180, + T_SIGN_UNSIGNED = 0x000100, + T_SIGN_SIGNED = 0x000200, + T_MASK_SIGN = 0x000300, /* Type size modifiers */ T_SIZE_NONE = 0x000000, - T_SIZE_CHAR = 0x000200, - T_SIZE_SHORT = 0x000400, - T_SIZE_INT = 0x000600, - T_SIZE_LONG = 0x000800, - T_SIZE_LONGLONG = 0x000A00, - T_MASK_SIZE = 0x000E00, + T_SIZE_CHAR = 0x001000, + T_SIZE_SHORT = 0x002000, + T_SIZE_INT = 0x003000, + T_SIZE_LONG = 0x004000, + T_SIZE_LONGLONG = 0x005000, + T_MASK_SIZE = 0x00F000, /* Type qualifiers */ T_QUAL_NONE = 0x000000, - T_QUAL_CONST = 0x001000, - T_QUAL_VOLATILE = 0x002000, - T_QUAL_RESTRICT = 0x004000, + T_QUAL_CONST = 0x010000, + T_QUAL_VOLATILE = 0x020000, + T_QUAL_RESTRICT = 0x040000, T_QUAL_CVR = T_QUAL_CONST | T_QUAL_VOLATILE | T_QUAL_RESTRICT, - T_QUAL_NEAR = 0x008000, - T_QUAL_FAR = 0x010000, + T_QUAL_NEAR = 0x080000, + T_QUAL_FAR = 0x100000, T_QUAL_ADDRSIZE = T_QUAL_NEAR | T_QUAL_FAR, - T_QUAL_FASTCALL = 0x020000, - T_QUAL_CDECL = 0x040000, + T_QUAL_FASTCALL = 0x200000, + T_QUAL_CDECL = 0x400000, T_QUAL_CCONV = T_QUAL_FASTCALL | T_QUAL_CDECL, - T_MASK_QUAL = 0x07F000, + T_MASK_QUAL = 0x7F0000, /* Types */ T_CHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_NONE | T_SIZE_CHAR, @@ -140,6 +141,8 @@ enum { T_LONGLONG = T_TYPE_LONGLONG | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_LONGLONG, T_ULONGLONG = T_TYPE_LONGLONG | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_LONGLONG, T_ENUM = T_TYPE_ENUM | T_CLASS_INT | T_SIGN_NONE | T_SIZE_NONE, + T_SBITFIELD = T_TYPE_BITFIELD | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_NONE, + T_UBITFIELD = T_TYPE_BITFIELD | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_NONE, T_FLOAT = T_TYPE_FLOAT | T_CLASS_FLOAT | T_SIGN_NONE | T_SIZE_NONE, T_DOUBLE = T_TYPE_DOUBLE | T_CLASS_FLOAT | T_SIGN_NONE | T_SIZE_NONE, T_VOID = T_TYPE_VOID | T_CLASS_NONE | T_SIGN_NONE | T_SIZE_NONE, @@ -171,6 +174,10 @@ struct Type { struct SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ + struct { + unsigned Offs; /* Bit offset into storage unit */ + unsigned Width; /* Width in bits */ + } B; /* Data for bit fields */ } A; /* Type attribute if necessary */ }; @@ -372,6 +379,11 @@ const Type* SignedType (const Type* T); const Type* UnsignedType (const Type* T); /* Get unsigned counterpart of the integral type */ +Type* NewBitFieldType (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. +*/ + #if defined(HAVE_INLINE) INLINE TypeCode GetRawType (const Type* T) /* Get the raw type */ @@ -514,6 +526,36 @@ INLINE int IsTypeEnum (const Type* T) # define IsTypeEnum(T) (GetRawType (T) == T_TYPE_ENUM) #endif +#if defined(HAVE_INLINE) +INLINE int IsTypeSignedBitField (const Type* T) +/* Return true if this is a signed bit-field */ +{ + return (UnqualifiedType (T->C) == T_SBITFIELD); +} +#else +# define IsTypeSignedBitField(T) (UnqualifiedType ((T)->C) == T_SBITFIELD) +#endif + +#if defined(HAVE_INLINE) +INLINE int IsTypeUnsignedBitField (const Type* T) +/* Return true if this is an unsigned bit-field */ +{ + return (UnqualifiedType (T->C) == T_UBITFIELD); +} +#else +# define IsTypeUnsignedBitField(T) (UnqualifiedType ((T)->C) == T_UBITFIELD) +#endif + +#if defined(HAVE_INLINE) +INLINE int IsTypeBitField (const Type* T) +/* Return true if this is a bit-field (either signed or unsigned) */ +{ + return IsTypeSignedBitField (T) || IsTypeUnsignedBitField (T); +} +#else +# define IsTypeBitField(T) (IsTypeSignedBitField (T) || IsTypeUnsignedBitField (T)) +#endif + #if defined(HAVE_INLINE) INLINE int IsTypeStruct (const Type* T) /* Return true if this is a struct type */ diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 2aa620a29..c1346e872 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2533,7 +2533,7 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) ** example two consecutive 10 bit fields. These will be packed ** into 3 bytes. */ - SI.ValBits += Sym->V.B.BitWidth; + SI.ValBits += Sym->Type->A.B.Width; /* TODO: Generalize this so any type can be used. */ CHECK (SI.ValBits <= CHAR_BITS + INT_BITS - 2); while (SI.ValBits >= CHAR_BITS) { @@ -2560,14 +2560,14 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) unsigned Shift; /* Calculate the bitmask from the bit-field data */ - unsigned Mask = (1U << Sym->V.B.BitWidth) - 1U; + unsigned Mask = (1U << Sym->Type->A.B.Width) - 1U; /* Safety ... */ - CHECK (Sym->V.B.Offs * CHAR_BITS + Sym->V.B.BitOffs == - SI.Offs * CHAR_BITS + SI.ValBits); + CHECK (Sym->V.Offs * CHAR_BITS + Sym->Type->A.B.Offs == + SI.Offs * CHAR_BITS + SI.ValBits); /* Read the data, check for a constant integer, do a range check */ - ED = ParseScalarInitInternal (Sym->Type); + ED = ParseScalarInitInternal (IntPromotion (Sym->Type)); if (!ED_IsConstAbsInt (&ED)) { Error ("Constant initializer expected"); ED_MakeConstAbsInt (&ED, 1); @@ -2582,26 +2582,26 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) Warning ("Implicit truncation from '%s' to '%s : %u' in bit-field initializer" " changes value from %ld to %u", GetFullTypeName (ED.Type), GetFullTypeName (Sym->Type), - Sym->V.B.BitWidth, ED.IVal, Val); + Sym->Type->A.B.Width, ED.IVal, Val); } } else { /* Sign extend back to full width of host long. */ - unsigned ShiftBits = sizeof (long) * CHAR_BIT - Sym->V.B.BitWidth; + unsigned ShiftBits = sizeof (long) * CHAR_BIT - Sym->Type->A.B.Width; long RestoredVal = asr_l(asl_l (Val, ShiftBits), ShiftBits); if (ED.IVal != RestoredVal) { Warning ("Implicit truncation from '%s' to '%s : %u' in bit-field initializer " "changes value from %ld to %ld", GetFullTypeName (ED.Type), GetFullTypeName (Sym->Type), - Sym->V.B.BitWidth, ED.IVal, RestoredVal); + Sym->Type->A.B.Width, ED.IVal, RestoredVal); } } /* Add the value to the currently stored bit-field value */ - Shift = (Sym->V.B.Offs - SI.Offs) * CHAR_BITS + Sym->V.B.BitOffs; + Shift = (Sym->V.Offs - SI.Offs) * CHAR_BITS + Sym->Type->A.B.Offs; SI.BitVal |= (Val << Shift); /* Account for the data and output any full bytes we have. */ - SI.ValBits += Sym->V.B.BitWidth; + SI.ValBits += Sym->Type->A.B.Width; /* Make sure unsigned is big enough to hold the value, 22 bits. ** This is 22 bits because the most we can have is 7 bits left ** over from the previous OutputBitField call, plus 15 bits diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 729b26942..c45005d65 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -47,13 +47,8 @@ -/* Generator attributes */ -#define GEN_NOPUSH 0x01 /* Don't push lhs */ -#define GEN_COMM 0x02 /* Operator is commutative */ -#define GEN_NOFUNC 0x04 /* Not allowed for function pointers */ - /* Map a generator function and its attributes to a token */ -typedef struct { +typedef struct GenDesc { token_t Tok; /* Token to map to */ unsigned Flags; /* Flags for generator function */ void (*Func) (unsigned, unsigned long); /* Generator func */ @@ -91,7 +86,7 @@ static void PostDec (ExprDesc* Expr); -static unsigned GlobalModeFlags (const ExprDesc* Expr) +unsigned GlobalModeFlags (const ExprDesc* Expr) /* Return the addressing mode flags for the given expression */ { switch (ED_GetLoc (Expr)) { @@ -390,117 +385,175 @@ static void DeferDec (const ExprDesc* Expr) -static void DeferredInc (ExprDesc* Expr) -/* Do the deferred post-inc */ +static void DoInc (ExprDesc* Expr, unsigned KeepResult) +/* Do increment */ { unsigned Flags; - unsigned long Val; - - /* Get the flags */ - Flags = TypeOf (Expr->Type) | GlobalModeFlags (Expr) | CF_FORCECHAR | CF_CONST | CF_NOKEEP; + long Val; /* Get the increment value in bytes */ Val = IsTypePtr (Expr->Type) ? CheckedSizeOf (Expr->Type + 1) : 1; - /* Check the location of the data */ - switch (ED_GetLoc (Expr)) { + /* Special treatment is needed for bit-fields */ + if (IsTypeBitField (Expr->Type)) { + DoIncDecBitField (Expr, Val, KeepResult); + return; + } - case E_LOC_ABS: - /* Absolute: numeric address or const */ - g_addeqstatic (Flags, Expr->IVal, 0, Val); - break; + /* Get the flags */ + Flags = TypeOf (Expr->Type) | GlobalModeFlags (Expr) | CF_FORCECHAR | CF_CONST; + if (KeepResult != OA_NEED_NEW) { + /* No need to get the result */ + Flags |= CF_NOKEEP; + } - case E_LOC_GLOBAL: - /* Global variable */ - g_addeqstatic (Flags, Expr->Name, Expr->IVal, Val); - break; + if (KeepResult == OA_NEED_OLD) { - case E_LOC_STATIC: - case E_LOC_LITERAL: - /* Static variable or literal in the literal pool */ - g_addeqstatic (Flags, Expr->Name, Expr->IVal, Val); - break; + Flags |= CF_FORCECHAR; - case E_LOC_REGISTER: - /* Register variable */ - g_addeqstatic (Flags, Expr->Name, Expr->IVal, Val); - break; + /* Push the address if needed */ + PushAddr (Expr); - case E_LOC_STACK: - /* Value on the stack */ - g_addeqlocal (Flags, Expr->IVal, Val); - break; + /* Save the original value */ + LoadExpr (CF_NONE, Expr); + g_save (Flags); - case E_LOC_PRIMARY: - /* The primary register */ - g_inc (Flags, Val); - break; + /* Do the increment */ + g_inc (Flags | CF_CONST, Val); - case E_LOC_EXPR: - /* An expression in the primary register */ - g_addeqind (Flags, Expr->IVal, Val); - break; + /* Store the result back */ + Store (Expr, 0); + + /* Restore the original value */ + g_restore (Flags); + + } else { + + /* Check the location of the data */ + switch (ED_GetLoc (Expr)) { + + case E_LOC_ABS: + /* Absolute numeric addressed variable */ + g_addeqstatic (Flags, Expr->IVal, 0, Val); + break; + + case E_LOC_GLOBAL: + case E_LOC_STATIC: + case E_LOC_REGISTER: + case E_LOC_LITERAL: + case E_LOC_CODE: + /* Global variabl, static variable, register variable, pooled + ** literal or code label location. + */ + g_addeqstatic (Flags, Expr->Name, Expr->IVal, Val); + break; + + case E_LOC_STACK: + /* Value on the stack */ + g_addeqlocal (Flags, Expr->IVal, Val); + break; + + case E_LOC_PRIMARY: + /* The primary register */ + g_inc (Flags, Val); + break; + + case E_LOC_EXPR: + /* An expression referenced in the primary register */ + g_addeqind (Flags, Expr->IVal, Val); + break; + + default: + Internal ("Invalid location in DoInc(): 0x%04X", ED_GetLoc (Expr)); + } - default: - Internal ("Invalid location in DeferredInc(): 0x%04X", ED_GetLoc (Expr)); } } -static void DeferredDec (ExprDesc* Expr) -/* Do the deferred post-dec */ +static void DoDec (ExprDesc* Expr, unsigned KeepResult) +/* Do decrement */ { unsigned Flags; - unsigned long Val; + long Val; - /* Get the flags */ - Flags = TypeOf (Expr->Type) | GlobalModeFlags (Expr) | CF_FORCECHAR | CF_CONST | CF_NOKEEP; - - /* Get the increment value in bytes */ + /* Get the decrement value in bytes */ Val = IsTypePtr (Expr->Type) ? CheckedSizeOf (Expr->Type + 1) : 1; - /* Check the location of the data */ - switch (ED_GetLoc (Expr)) { + /* Special treatment is needed for bit-fields */ + if (IsTypeBitField (Expr->Type)) { + DoIncDecBitField (Expr, -Val, KeepResult); + return; + } - case E_LOC_ABS: - /* Absolute: numeric address or const */ - g_subeqstatic (Flags, Expr->IVal, 0, Val); - break; + /* Get the flags */ + Flags = TypeOf (Expr->Type) | GlobalModeFlags (Expr) | CF_FORCECHAR | CF_CONST; + if (KeepResult != OA_NEED_NEW) { + /* No need to get the result */ + Flags |= CF_NOKEEP; + } - case E_LOC_GLOBAL: - /* Global variable */ - g_subeqstatic (Flags, Expr->Name, Expr->IVal, Val); - break; + if (KeepResult == OA_NEED_OLD) { - case E_LOC_STATIC: - case E_LOC_LITERAL: - /* Static variable or literal in the literal pool */ - g_subeqstatic (Flags, Expr->Name, Expr->IVal, Val); - break; + Flags |= CF_FORCECHAR; - case E_LOC_REGISTER: - /* Register variable */ - g_subeqstatic (Flags, Expr->Name, Expr->IVal, Val); - break; + /* Push the address if needed */ + PushAddr (Expr); - case E_LOC_STACK: - /* Value on the stack */ - g_subeqlocal (Flags, Expr->IVal, Val); - break; + /* Save the original value */ + LoadExpr (CF_NONE, Expr); + g_save (Flags); - case E_LOC_PRIMARY: - /* The primary register */ - g_dec (Flags, Val); - break; + /* Do the decrement */ + g_dec (Flags | CF_CONST, Val); - case E_LOC_EXPR: - /* An expression in the primary register */ - g_subeqind (Flags, Expr->IVal, Val); - break; + /* Store the result back */ + Store (Expr, 0); + + /* Restore the original value */ + g_restore (Flags); + + } else { + + /* Check the location of the data */ + switch (ED_GetLoc (Expr)) { + + case E_LOC_ABS: + /* Absolute numeric addressed variable */ + g_subeqstatic (Flags, Expr->IVal, 0, Val); + break; + + case E_LOC_GLOBAL: + case E_LOC_STATIC: + case E_LOC_REGISTER: + case E_LOC_LITERAL: + case E_LOC_CODE: + /* Global variabl, static variable, register variable, pooled + ** literal or code label location. + */ + g_subeqstatic (Flags, Expr->Name, Expr->IVal, Val); + break; + + case E_LOC_STACK: + /* Value on the stack */ + g_subeqlocal (Flags, Expr->IVal, Val); + break; + + case E_LOC_PRIMARY: + /* The primary register */ + g_dec (Flags, Val); + break; + + case E_LOC_EXPR: + /* An expression referenced in the primary register */ + g_subeqind (Flags, Expr->IVal, Val); + break; + + default: + Internal ("Invalid location in DoDec(): 0x%04X", ED_GetLoc (Expr)); + } - default: - Internal ("Invalid location in DeferredDec(): 0x%04X", ED_GetLoc (Expr)); } } @@ -564,11 +617,11 @@ void DoDeferred (unsigned Flags, ExprDesc* Expr) switch (Op->OpType) { case DOT_INC: - DeferredInc (&Op->Expr); + DoInc (&Op->Expr, OA_NEED_NONE); break; case DOT_DEC: - DeferredDec (&Op->Expr); + DoDec (&Op->Expr, OA_NEED_NONE); break; } xfree (&Op->Expr); @@ -595,6 +648,7 @@ void DoDeferred (unsigned Flags, ExprDesc* Expr) } + static unsigned FunctionArgList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) /* Parse the argument list of the called function and pass the arguments to it. ** Depending on several criteria, this may be done by just pushing into each @@ -724,14 +778,17 @@ static unsigned FunctionArgList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) if (IsClassStruct (Expr.Type)) { /* Use the replacement type */ Flags |= TypeOf (GetStructReplacementType (Expr.Type)); + + /* Load the value into the primary if it is not already there */ + LoadExpr (Flags, &Expr); } else { + /* Load the value into the primary if it is not already there */ + LoadExpr (CF_NONE, &Expr); + /* Use the type of the argument for the push */ Flags |= TypeOf (Expr.Type); } - /* Load the value into the primary if it is not already there */ - LoadExpr (Flags, &Expr); - /* If this is a fastcall function, don't push the last argument */ if ((CurTok.Tok == TOK_COMMA && NextTok.Tok != TOK_RPAREN) || !IsFastcall) { unsigned ArgSize = sizeofarg (Flags); @@ -1023,7 +1080,7 @@ static void Primary (ExprDesc* E) /* Floating point constant */ if (CurTok.Tok == TOK_FCONST) { - E->FVal = CurTok.FVal; + E->V.FVal = CurTok.FVal; E->Flags |= E_LOC_NONE | E_RTYPE_RVAL; E->Type = CurTok.Type; NextToken (); @@ -1198,9 +1255,9 @@ static void Primary (ExprDesc* E) case TOK_WCSCONST: /* String literal */ if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { - E->LVal = UseLiteral (CurTok.SVal); + E->V.LVal = UseLiteral (CurTok.SVal); } else { - E->LVal = CurTok.SVal; + E->V.LVal = CurTok.SVal; } E->Type = GetCharArrayType (GetLiteralSize (CurTok.SVal)); E->Flags = E_LOC_LITERAL | E_RTYPE_RVAL | E_ADDRESS_OF; @@ -1400,14 +1457,14 @@ static void StructRef (ExprDesc* Expr) */ BitOffs = Field.V.Offs * CHAR_BITS; if (SymIsBitField (&Field)) { - BitOffs += Field.V.B.BitOffs; + BitOffs += Field.Type->A.B.Offs; g_asr (Flags, BitOffs); /* Mask the value. This is unnecessary if the shift executed above ** moved only zeroes into the value. */ - if (BitOffs + Field.V.B.BitWidth != FieldSize * CHAR_BITS) { + if (BitOffs + Field.Type->A.B.Width != FieldSize * CHAR_BITS) { g_and (CF_INT | CF_UNSIGNED | CF_CONST, - (0x0001U << Field.V.B.BitWidth) - 1U); + (0x0001U << Field.Type->A.B.Width) - 1U); } } else { g_asr (Flags, BitOffs); @@ -1434,12 +1491,7 @@ static void StructRef (ExprDesc* Expr) ED_AddrExpr (Expr); } - /* Make the expression a bit field if necessary */ - if (SymIsBitField (&Field)) { - ED_MakeBitField (Expr, Field.V.B.BitOffs, Field.V.B.BitWidth); - } } - } @@ -1582,9 +1634,6 @@ void Store (ExprDesc* Expr, const Type* StoreType) static void PreInc (ExprDesc* Expr) /* Handle the preincrement operators */ { - unsigned Flags; - unsigned long Val; - /* Skip the operator token */ NextToken (); @@ -1600,49 +1649,8 @@ static void PreInc (ExprDesc* Expr) Error ("Increment of read-only variable"); } - /* Get the data type */ - Flags = TypeOf (Expr->Type) | GlobalModeFlags (Expr) | CF_FORCECHAR | CF_CONST; - - /* Get the increment value in bytes */ - Val = IsTypePtr (Expr->Type)? CheckedPSizeOf (Expr->Type) : 1; - - /* Check the location of the data */ - switch (ED_GetLoc (Expr)) { - - case E_LOC_ABS: - /* Absolute numeric addressed variable */ - g_addeqstatic (Flags, Expr->IVal, 0, Val); - break; - - case E_LOC_GLOBAL: - case E_LOC_STATIC: - case E_LOC_REGISTER: - case E_LOC_LITERAL: - case E_LOC_CODE: - /* Global variabl, static variable, register variable, pooled - ** literal or code label location. - */ - g_addeqstatic (Flags, Expr->Name, Expr->IVal, Val); - break; - - case E_LOC_STACK: - /* Value on the stack */ - g_addeqlocal (Flags, Expr->IVal, Val); - break; - - case E_LOC_PRIMARY: - /* The primary register */ - g_inc (Flags, Val); - break; - - case E_LOC_EXPR: - /* An expression referenced in the primary register */ - g_addeqind (Flags, Expr->IVal, Val); - break; - - default: - Internal ("Invalid location in PreInc(): 0x%04X", ED_GetLoc (Expr)); - } + /* Do the increment */ + DoInc (Expr, OA_NEED_NEW); /* Result is an expression, no reference */ ED_FinalizeRValLoad (Expr); @@ -1653,9 +1661,6 @@ static void PreInc (ExprDesc* Expr) static void PreDec (ExprDesc* Expr) /* Handle the predecrement operators */ { - unsigned Flags; - unsigned long Val; - /* Skip the operator token */ NextToken (); @@ -1671,49 +1676,8 @@ static void PreDec (ExprDesc* Expr) Error ("Decrement of read-only variable"); } - /* Get the data type */ - Flags = TypeOf (Expr->Type) | GlobalModeFlags (Expr) | CF_FORCECHAR | CF_CONST; - - /* Get the increment value in bytes */ - Val = IsTypePtr (Expr->Type)? CheckedPSizeOf (Expr->Type) : 1; - - /* Check the location of the data */ - switch (ED_GetLoc (Expr)) { - - case E_LOC_ABS: - /* Absolute numeric addressed variable */ - g_subeqstatic (Flags, Expr->IVal, 0, Val); - break; - - case E_LOC_GLOBAL: - case E_LOC_STATIC: - case E_LOC_REGISTER: - case E_LOC_LITERAL: - case E_LOC_CODE: - /* Global variabl, static variable, register variable, pooled - ** literal or code label location. - */ - g_subeqstatic (Flags, Expr->Name, Expr->IVal, Val); - break; - - case E_LOC_STACK: - /* Value on the stack */ - g_subeqlocal (Flags, Expr->IVal, Val); - break; - - case E_LOC_PRIMARY: - /* The primary register */ - g_dec (Flags, Val); - break; - - case E_LOC_EXPR: - /* An expression in the primary register */ - g_subeqind (Flags, Expr->IVal, Val); - break; - - default: - Internal ("Invalid location in PreDec(): 0x%04X", ED_GetLoc (Expr)); - } + /* Do the decrement */ + DoDec (Expr, OA_NEED_NEW); /* Result is an expression, no reference */ ED_FinalizeRValLoad (Expr); @@ -1724,7 +1688,7 @@ static void PreDec (ExprDesc* Expr) static void PostInc (ExprDesc* Expr) /* Handle the postincrement operator */ { - unsigned Flags, Loc; + unsigned Flags; NextToken (); @@ -1748,34 +1712,17 @@ static void PostInc (ExprDesc* Expr) */ /* Emit smaller code if a char variable is at a constant location */ - if ((Flags & CF_CHAR) == CF_CHAR && ED_IsLocConst (Expr)) { + if ((Flags & CF_TYPEMASK) == CF_CHAR && ED_IsLocConst (Expr) && !IsTypeBitField (Expr->Type)) { LoadExpr (CF_NONE, Expr); AddCodeLine ("inc %s", ED_GetLabelName (Expr, 0)); } else { - Loc = ED_GetLoc (Expr); - if (Loc == E_LOC_PRIMARY || Loc == E_LOC_EXPR) { - /* Push the address if needed */ - PushAddr (Expr); + if (ED_IsLocPrimaryOrExpr (Expr)) { - /* Fetch the value and save it (since it's the result of the expression) */ - LoadExpr (CF_NONE, Expr); - g_save (Flags | CF_FORCECHAR); - - /* If we have a pointer expression, increment by the size of the type */ - if (IsTypePtr (Expr->Type)) { - g_inc (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1)); - } else { - g_inc (Flags | CF_CONST | CF_FORCECHAR, 1); - } - - /* Store the result back */ - Store (Expr, 0); - - /* Restore the original value in the primary register */ - g_restore (Flags | CF_FORCECHAR); + /* Do the increment */ + DoInc (Expr, OA_NEED_OLD); } else { @@ -1787,6 +1734,11 @@ static void PostInc (ExprDesc* Expr) } } + /* Adjust the type of the expression */ + if (IsClassInt (Expr->Type)) { + Expr->Type = IntPromotion (Expr->Type); + } + /* The result is always an expression, no reference */ ED_FinalizeRValLoad (Expr); } @@ -1796,11 +1748,11 @@ static void PostInc (ExprDesc* Expr) static void PostDec (ExprDesc* Expr) /* Handle the postdecrement operator */ { - unsigned Flags, Loc; + unsigned Flags; NextToken (); - /* The expression to increment must be an lvalue */ + /* The expression to decrement must be an lvalue */ if (!ED_IsLVal (Expr)) { Error ("Invalid lvalue"); return; @@ -1815,34 +1767,17 @@ static void PostDec (ExprDesc* Expr) Flags = TypeOf (Expr->Type); /* Emit smaller code if a char variable is at a constant location */ - if ((Flags & CF_CHAR) == CF_CHAR && ED_IsLocConst (Expr)) { + if ((Flags & CF_TYPEMASK) == CF_CHAR && ED_IsLocConst (Expr) && !IsTypeBitField (Expr->Type)) { LoadExpr (CF_NONE, Expr); AddCodeLine ("dec %s", ED_GetLabelName (Expr, 0)); } else { - Loc = ED_GetLoc (Expr); - if (Loc == E_LOC_PRIMARY || Loc == E_LOC_EXPR) { - /* Push the address if needed */ - PushAddr (Expr); + if (ED_IsLocPrimaryOrExpr (Expr)) { - /* Fetch the value and save it (since it's the result of the expression) */ - LoadExpr (CF_NONE, Expr); - g_save (Flags | CF_FORCECHAR); - - /* If we have a pointer expression, increment by the size of the type */ - if (IsTypePtr (Expr->Type)) { - g_dec (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1)); - } else { - g_dec (Flags | CF_CONST | CF_FORCECHAR, 1); - } - - /* Store the result back */ - Store (Expr, 0); - - /* Restore the original value in the primary register */ - g_restore (Flags | CF_FORCECHAR); + /* Do the decrement */ + DoDec (Expr, OA_NEED_OLD); } else { @@ -1854,6 +1789,11 @@ static void PostDec (ExprDesc* Expr) } } + /* Adjust the type of the expression */ + if (IsClassInt (Expr->Type)) { + Expr->Type = IntPromotion (Expr->Type); + } + /* The result is always an expression, no reference */ ED_FinalizeRValLoad (Expr); } @@ -1863,8 +1803,6 @@ static void PostDec (ExprDesc* Expr) static void UnaryOp (ExprDesc* Expr) /* Handle unary -/+ and ~ */ { - unsigned Flags; - /* Remember the operator token and skip it */ token_t Tok = CurTok.Tok; NextToken (); @@ -1888,15 +1826,24 @@ static void UnaryOp (ExprDesc* Expr) default: Internal ("Unexpected token: %d", Tok); } + /* Adjust the type of the expression */ + Expr->Type = IntPromotion (Expr->Type); + /* Limit the calculated value to the range of its type */ LimitExprValue (Expr); } else { + unsigned Flags; + /* Value is not constant */ LoadExpr (CF_NONE, Expr); - /* Adjust the type of the value */ - Flags = g_typeadjust (TypeOf (Expr->Type), TypeOf (type_int) | CF_CONST); + /* Adjust the type of the expression */ + Expr->Type = IntPromotion (Expr->Type); + TypeConversion (Expr, Expr->Type); + + /* Get code generation flags */ + Flags = TypeOf (Expr->Type); /* Handle the operation */ switch (Tok) { @@ -1909,9 +1856,6 @@ static void UnaryOp (ExprDesc* Expr) /* The result is an rvalue in the primary */ ED_FinalizeRValLoad (Expr); } - - /* Adjust the type of the expression */ - Expr->Type = IntPromotion (Expr->Type); } @@ -2003,13 +1947,13 @@ void hie10 (ExprDesc* Expr) if (!IsTypeFunc (Expr->Type) && !IsTypeArray (Expr->Type)) { if (ED_IsRVal (Expr)) { Error ("Illegal address"); - break; + /* Continue anyway, just to avoid further warnings */ } - if (ED_IsBitField (Expr)) { + if (IsTypeBitField (Expr->Type)) { Error ("Cannot take address of bit-field"); - /* Do it anyway, just to avoid further warnings */ - ED_DisBitField (Expr); + /* Continue anyway, just to avoid further warnings */ + Expr->Type = GetUnderlyingType (Expr->Type); } /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); @@ -2034,7 +1978,7 @@ void hie10 (ExprDesc* Expr) ED_Init (&Uneval); ED_MarkForUneval (&Uneval); hie10 (&Uneval); - if (ED_IsBitField (&Uneval)) { + if (IsTypeBitField (Uneval.Type)) { Error ("Cannot apply 'sizeof' to bit-field"); Size = 0; } else { @@ -2536,6 +2480,8 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* Determine the signedness of the operands */ int LeftSigned = IsSignSigned (Expr->Type); int RightSigned = IsSignSigned (Expr2.Type); + int CmpSigned = IsClassInt (Expr->Type) && IsClassInt (Expr2.Type) && + IsSignSigned (ArithmeticConvert (Expr->Type, Expr2.Type)); /* If the right hand side is constant, and the generator function ** expects the lhs in the primary, remove the push of the primary @@ -2630,6 +2576,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ */ flags |= (CF_CHAR | CF_FORCECHAR); if (!LeftSigned || !RightSigned) { + CmpSigned = 0; flags |= CF_UNSIGNED; } @@ -2644,10 +2591,15 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ flags |= CF_FORCECHAR; } if (!LeftSigned || !RightSigned) { + CmpSigned = 0; flags |= CF_UNSIGNED; } } else { unsigned rtype = TypeOf (Expr2.Type) | (flags & CF_CONST); + if (CmpSigned) { + ltype &= ~CF_UNSIGNED; + rtype &= ~CF_UNSIGNED; + } flags |= g_typeadjust (ltype, rtype); } @@ -2655,7 +2607,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ ** constant, we may be able to change the compares to something more ** effective. */ - if ((!LeftSigned || !RightSigned) && rconst) { + if (!CmpSigned && rconst) { switch (Tok) { @@ -4121,248 +4073,6 @@ static void hieQuest (ExprDesc* Expr) -static void opeq (const GenDesc* Gen, ExprDesc* Expr, const char* Op) -/* Process "op=" operators. */ -{ - unsigned flags; - CodeMark Mark; - int MustScale; - - /* op= can only be used with lvalues */ - if (ED_IsRVal (Expr)) { - Error ("Invalid lvalue in assignment"); - return; - } - - /* The left side must not be const qualified */ - if (IsQualConst (Expr->Type)) { - Error ("Assignment to const"); - } - - /* There must be an integer or pointer on the left side */ - if (!IsClassInt (Expr->Type) && !IsTypePtr (Expr->Type)) { - Error ("Invalid left operand for binary operator '%s'", Op); - /* Continue. Wrong code will be generated, but the compiler won't - ** break, so this is the best error recovery. - */ - } - - /* Skip the operator token */ - NextToken (); - - /* Determine the type of the lhs */ - flags = TypeOf (Expr->Type); - MustScale = (Gen->Func == g_add || Gen->Func == g_sub) && IsTypePtr (Expr->Type); - - /* Get the lhs address on stack (if needed) */ - PushAddr (Expr); - - /* Fetch the lhs into the primary register if needed */ - LoadExpr (CF_NONE, Expr); - - /* Bring the lhs on stack */ - GetCodePos (&Mark); - g_push (flags, 0); - - ExprDesc Expr2; - ED_Init (&Expr2); - Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - - /* Evaluate the rhs */ - MarkedExprWithCheck (hie1, &Expr2); - - /* The rhs must be an integer (or a float, but we don't support that yet */ - if (!IsClassInt (Expr2.Type)) { - Error ("Invalid right operand for binary operator '%s'", Op); - /* Continue. Wrong code will be generated, but the compiler won't - ** break, so this is the best error recovery. - */ - } - - /* Check for a constant expression */ - if (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) { - /* The resulting value is a constant. If the generator has the NOPUSH - ** flag set, don't push the lhs. - */ - if (Gen->Flags & GEN_NOPUSH) { - RemoveCode (&Mark); - } - if (MustScale) { - /* lhs is a pointer, scale rhs */ - Expr2.IVal *= CheckedSizeOf (Expr->Type+1); - } - - /* If the lhs is character sized, the operation may be later done - ** with characters. - */ - if (CheckedSizeOf (Expr->Type) == SIZEOF_CHAR) { - flags |= CF_FORCECHAR; - } - - /* Special handling for add and sub - some sort of a hack, but short code */ - if (Gen->Func == g_add) { - g_inc (flags | CF_CONST, Expr2.IVal); - } else if (Gen->Func == g_sub) { - g_dec (flags | CF_CONST, Expr2.IVal); - } else { - if (Expr2.IVal == 0) { - /* Check for div by zero/mod by zero */ - if (Gen->Func == g_div) { - Error ("Division by zero"); - } else if (Gen->Func == g_mod) { - Error ("Modulo operation with zero"); - } - } - Gen->Func (flags | CF_CONST, Expr2.IVal); - } - } else { - - /* rhs is not constant. Load into the primary */ - LoadExpr (CF_NONE, &Expr2); - if (MustScale) { - /* lhs is a pointer, scale rhs */ - g_scale (TypeOf (Expr2.Type), CheckedSizeOf (Expr->Type+1)); - } - - /* If the lhs is character sized, the operation may be later done - ** with characters. - */ - if (CheckedSizeOf (Expr->Type) == SIZEOF_CHAR) { - flags |= CF_FORCECHAR; - } - - /* Adjust the types of the operands if needed */ - Gen->Func (g_typeadjust (flags, TypeOf (Expr2.Type)), 0); - } - Store (Expr, 0); - ED_FinalizeRValLoad (Expr); -} - - - -static void addsubeq (const GenDesc* Gen, ExprDesc *Expr, const char* Op) -/* Process the += and -= operators */ -{ - ExprDesc Expr2; - unsigned lflags; - unsigned rflags; - int MustScale; - - ED_Init (&Expr2); - Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - - /* We're currently only able to handle some addressing modes */ - if (ED_GetLoc (Expr) == E_LOC_EXPR || ED_GetLoc (Expr) == E_LOC_PRIMARY) { - /* Use generic routine */ - opeq (Gen, Expr, Op); - return; - } - - /* We must have an lvalue */ - if (ED_IsRVal (Expr)) { - Error ("Invalid lvalue in assignment"); - return; - } - - /* The left side must not be const qualified */ - if (IsQualConst (Expr->Type)) { - Error ("Assignment to const"); - } - - /* There must be an integer or pointer on the left side */ - if (!IsClassInt (Expr->Type) && !IsTypePtr (Expr->Type)) { - Error ("Invalid left operand for binary operator '%s'", Op); - /* Continue. Wrong code will be generated, but the compiler won't - ** break, so this is the best error recovery. - */ - } - - /* Skip the operator */ - NextToken (); - - /* Check if we have a pointer expression and must scale rhs */ - MustScale = IsTypePtr (Expr->Type); - - /* Initialize the code generator flags */ - lflags = 0; - rflags = 0; - - /* Evaluate the rhs. We expect an integer here, since float is not - ** supported - */ - hie1 (&Expr2); - if (!IsClassInt (Expr2.Type)) { - Error ("Invalid right operand for binary operator '%s'", Op); - /* Continue. Wrong code will be generated, but the compiler won't - ** break, so this is the best error recovery. - */ - } - - /* Setup the code generator flags */ - lflags |= TypeOf (Expr->Type) | GlobalModeFlags (Expr) | CF_FORCECHAR; - rflags |= TypeOf (Expr2.Type) | CF_FORCECHAR; - - if (ED_IsConstAbs (&Expr2)) { - /* The resulting value is a constant */ - rflags |= CF_CONST; - lflags |= CF_CONST; - - /* Scale it */ - if (MustScale) { - Expr2.IVal *= CheckedSizeOf (Indirect (Expr->Type)); - } - } else { - /* Not constant, load into the primary */ - LoadExpr (CF_NONE, &Expr2); - - /* Convert the type of the rhs to that of the lhs */ - g_typecast (lflags, rflags & ~CF_FORCECHAR); - - if (MustScale) { - /* lhs is a pointer, scale rhs */ - g_scale (TypeOf (Expr2.Type), CheckedSizeOf (Indirect (Expr->Type))); - } - } - - /* Output apropriate code depending on the location */ - switch (ED_GetLoc (Expr)) { - - case E_LOC_ABS: - case E_LOC_GLOBAL: - case E_LOC_STATIC: - case E_LOC_REGISTER: - case E_LOC_LITERAL: - case E_LOC_CODE: - /* Absolute numeric addressed variable, global variable, local - ** static variable, register variable, pooled literal or code - ** label location. - */ - if (Gen->Tok == TOK_PLUS_ASSIGN) { - g_addeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal); - } else { - g_subeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal); - } - break; - - case E_LOC_STACK: - /* Value on the stack */ - if (Gen->Tok == TOK_PLUS_ASSIGN) { - g_addeqlocal (lflags, Expr->IVal, Expr2.IVal); - } else { - g_subeqlocal (lflags, Expr->IVal, Expr2.IVal); - } - break; - - default: - Internal ("Invalid location in Store(): 0x%04X", ED_GetLoc (Expr)); - } - - /* Expression is an rvalue in the primary now */ - ED_FinalizeRValLoad (Expr); -} - - - void hie1 (ExprDesc* Expr) /* Parse first level of expression hierarchy. */ { @@ -4370,47 +4080,47 @@ void hie1 (ExprDesc* Expr) switch (CurTok.Tok) { case TOK_ASSIGN: - Assignment (Expr); + OpAssign (0, Expr, "="); break; case TOK_PLUS_ASSIGN: - addsubeq (&GenPASGN, Expr, "+="); + OpAddSubAssign (&GenPASGN, Expr, "+="); break; case TOK_MINUS_ASSIGN: - addsubeq (&GenSASGN, Expr, "-="); + OpAddSubAssign (&GenSASGN, Expr, "-="); break; case TOK_MUL_ASSIGN: - opeq (&GenMASGN, Expr, "*="); + OpAssign (&GenMASGN, Expr, "*="); break; case TOK_DIV_ASSIGN: - opeq (&GenDASGN, Expr, "/="); + OpAssign (&GenDASGN, Expr, "/="); break; case TOK_MOD_ASSIGN: - opeq (&GenMOASGN, Expr, "%="); + OpAssign (&GenMOASGN, Expr, "%="); break; case TOK_SHL_ASSIGN: - opeq (&GenSLASGN, Expr, "<<="); + OpAssign (&GenSLASGN, Expr, "<<="); break; case TOK_SHR_ASSIGN: - opeq (&GenSRASGN, Expr, ">>="); + OpAssign (&GenSRASGN, Expr, ">>="); break; case TOK_AND_ASSIGN: - opeq (&GenAASGN, Expr, "&="); + OpAssign (&GenAASGN, Expr, "&="); break; case TOK_XOR_ASSIGN: - opeq (&GenXOASGN, Expr, "^="); + OpAssign (&GenXOASGN, Expr, "^="); break; case TOK_OR_ASSIGN: - opeq (&GenOASGN, Expr, "|="); + OpAssign (&GenOASGN, Expr, "|="); break; default: diff --git a/src/cc65/expr.h b/src/cc65/expr.h index 4909815ee..841edcb62 100644 --- a/src/cc65/expr.h +++ b/src/cc65/expr.h @@ -28,6 +28,11 @@ #define SQP_KEEP_EAX 0x02U #define SQP_KEEP_EXPR 0x03U /* SQP_KEEP_TEST | SQP_KEEP_EAX */ +/* Generator attributes */ +#define GEN_NOPUSH 0x01 /* Don't push lhs */ +#define GEN_COMM 0x02 /* Operator is commutative */ +#define GEN_NOFUNC 0x04 /* Not allowed for function pointers */ + /*****************************************************************************/ @@ -36,6 +41,9 @@ +unsigned GlobalModeFlags (const ExprDesc* Expr); +/* Return the addressing mode flags for the given expression */ + void ExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr); /* Call an expression function with checks. */ diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index 1d4fd6872..3d7b7c384 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -56,30 +56,17 @@ ExprDesc* ED_Init (ExprDesc* Expr) /* Initialize an ExprDesc */ { - Expr->Sym = 0; Expr->Type = 0; Expr->Flags = E_NEED_EAX; Expr->Name = 0; + Expr->Sym = 0; Expr->IVal = 0; - Expr->FVal = FP_D_Make (0.0); - Expr->LVal = 0; - Expr->BitOffs = 0; - Expr->BitWidth = 0; + memset (&Expr->V, 0, sizeof (Expr->V)); return Expr; } -void ED_MakeBitField (ExprDesc* Expr, unsigned BitOffs, unsigned BitWidth) -/* Make this expression a bit field expression */ -{ - Expr->Flags |= E_BITFIELD; - Expr->BitOffs = BitOffs; - Expr->BitWidth = BitWidth; -} - - - #if !defined(HAVE_INLINE) int ED_IsLocQuasiConst (const ExprDesc* Expr) /* Return true if the expression is a constant location of some sort or on the @@ -231,12 +218,12 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { - Expr->Sym = 0; Expr->Type = Type; Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_MASK_KEEP_MAKE); Expr->Name = 0; + Expr->Sym = 0; Expr->IVal = Value; - Expr->FVal = FP_D_Make (0.0); + memset (&Expr->V, 0, sizeof (Expr->V)); return Expr; } @@ -245,12 +232,12 @@ ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value) /* Replace Expr with a constant integer expression with the given value */ { - Expr->Sym = 0; Expr->Type = type_int; Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_MASK_KEEP_MAKE); Expr->Name = 0; + Expr->Sym = 0; Expr->IVal = Value; - Expr->FVal = FP_D_Make (0.0); + memset (&Expr->V, 0, sizeof (Expr->V)); return Expr; } @@ -264,7 +251,7 @@ ExprDesc* ED_MakeConstBool (ExprDesc* Expr, long Value) Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_MASK_KEEP_MAKE); Expr->Name = 0; Expr->IVal = Value; - Expr->FVal = FP_D_Make (0.0); + memset (&Expr->V, 0, sizeof (Expr->V)); return Expr; } @@ -273,13 +260,13 @@ ExprDesc* ED_MakeConstBool (ExprDesc* Expr, long Value) ExprDesc* ED_FinalizeRValLoad (ExprDesc* Expr) /* Finalize the result of LoadExpr to be an rvalue in the primary register */ { - Expr->Sym = 0; - Expr->Flags &= ~(E_MASK_LOC | E_MASK_RTYPE | E_BITFIELD | E_ADDRESS_OF); + Expr->Flags &= ~(E_MASK_LOC | E_MASK_RTYPE | E_ADDRESS_OF); Expr->Flags &= ~E_CC_SET; Expr->Flags |= (E_LOC_PRIMARY | E_RTYPE_RVAL); + Expr->Sym = 0; Expr->Name = 0; Expr->IVal = 0; /* No offset */ - Expr->FVal = FP_D_Make (0.0); + memset (&Expr->V, 0, sizeof (Expr->V)); return Expr; } @@ -464,8 +451,8 @@ int ED_IsQuasiConstAddr (const ExprDesc* Expr) int ED_IsNullPtr (const ExprDesc* Expr) /* Return true if the given expression is a NULL pointer constant */ { - return (Expr->Flags & (E_MASK_LOC|E_MASK_RTYPE|E_BITFIELD)) == - (E_LOC_NONE|E_RTYPE_RVAL) && + return (Expr->Flags & (E_MASK_LOC|E_MASK_RTYPE)) == + (E_LOC_NONE|E_RTYPE_RVAL) && Expr->IVal == 0 && IsClassInt (Expr->Type); } @@ -503,7 +490,7 @@ void PrintExprDesc (FILE* F, ExprDesc* E) "Raw type: (unknown)\n"); } fprintf (F, "IVal: 0x%08lX\n", E->IVal); - fprintf (F, "FVal: %f\n", FP_D_ToFloat (E->FVal)); + fprintf (F, "FVal: %f\n", FP_D_ToFloat (E->V.FVal)); Flags = E->Flags; Sep = '('; @@ -558,11 +545,6 @@ void PrintExprDesc (FILE* F, ExprDesc* E) Flags &= ~E_LOC_CODE; Sep = ','; } - if (Flags & E_BITFIELD) { - fprintf (F, "%cE_BITFIELD", Sep); - Flags &= ~E_BITFIELD; - Sep = ','; - } if (Flags & E_NEED_TEST) { fprintf (F, "%cE_NEED_TEST", Sep); Flags &= ~E_NEED_TEST; diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a46685b59..a1487a0bd 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -114,7 +114,6 @@ enum { E_LOC_QUASICONST = E_LOC_CONST | E_LOC_STACK, /* Expression type modifiers */ - E_BITFIELD = 0x0200, /* Expression is a bit-field */ E_ADDRESS_OF = 0x0400, /* Expression is the address of the lvalue */ /* lvalue/rvalue in C language's sense */ @@ -198,17 +197,15 @@ struct Literal; /* Describe the result of an expression */ typedef struct ExprDesc ExprDesc; struct ExprDesc { - struct SymEntry* Sym; /* Symbol table entry if known */ - const Type* Type; /* Type array of expression */ - unsigned Flags; + const Type* Type; /* C type of the expression */ + unsigned Flags; /* Properties of the expression */ uintptr_t Name; /* Name pointer or label number */ + struct SymEntry* Sym; /* Symbol table entry if any */ long IVal; /* Integer value if expression constant */ - Double FVal; /* Floating point value */ - struct Literal* LVal; /* Literal value */ - - /* Bit field stuff */ - unsigned BitOffs; /* Bit offset for bit fields */ - unsigned BitWidth; /* Bit width for bit fields */ + union { + Double FVal; /* Floating point value */ + struct Literal* LVal; /* Literal value */ + } V; /* Start and end of generated code */ CodeMark Start; @@ -331,29 +328,6 @@ int ED_IsLocQuasiConst (const ExprDesc* Expr); */ #endif -#if defined(HAVE_INLINE) -INLINE int ED_IsBitField (const ExprDesc* Expr) -/* Return true if the expression is a bit field */ -{ - return (Expr->Flags & E_BITFIELD) != 0; -} -#else -# define ED_IsBitField(Expr) (((Expr)->Flags & E_BITFIELD) != 0) -#endif - -#if defined(HAVE_INLINE) -INLINE void ED_DisBitField (ExprDesc* Expr) -/* Make the expression no longer a bit field */ -{ - Expr->Flags &= ~E_BITFIELD; -} -#else -# define ED_DisBitField(Expr) ((Expr)->Flags &= ~E_BITFIELD) -#endif - -void ED_MakeBitField (ExprDesc* Expr, unsigned BitOffs, unsigned BitWidth); -/* Make this expression a bit field expression */ - #if defined(HAVE_INLINE) INLINE void ED_RequireTest (ExprDesc* Expr) /* Mark the expression for a test. */ diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index 95617f596..a742087b7 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -124,38 +124,40 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) */ int AdjustBitField = 0; unsigned BitFieldFullWidthFlags = 0; - if (ED_IsBitField (Expr)) { - unsigned EndBit = Expr->BitOffs + Expr->BitWidth; - AdjustBitField = Expr->BitOffs != 0 || (EndBit != CHAR_BITS && EndBit != INT_BITS); + if ((Flags & CF_TYPEMASK) == 0) { + if (IsTypeBitField (Expr->Type)) { + unsigned EndBit = Expr->Type->A.B.Offs + Expr->Type->A.B.Width; + AdjustBitField = Expr->Type->A.B.Offs != 0 || (EndBit != CHAR_BITS && EndBit != INT_BITS); - /* TODO: This probably needs to be guarded by AdjustBitField when long bit-fields are - ** supported. - */ - Flags |= (EndBit <= CHAR_BITS) ? CF_CHAR : CF_INT; - if (IsSignUnsigned (Expr->Type)) { - Flags |= CF_UNSIGNED; - } - - /* Flags we need operate on the whole bit-field, without CF_FORCECHAR. */ - BitFieldFullWidthFlags = Flags; - - /* If we're adjusting, then only load a char (not an int) and do only char ops; - ** We will clear the high byte in the adjustment. CF_FORCECHAR does nothing if the - ** type is not CF_CHAR. - */ - if (AdjustBitField) { - /* If adjusting, then we're sign extending manually, so do everything unsigned - ** to make shifts faster. + /* TODO: This probably needs to be guarded by AdjustBitField when long bit-fields are + ** supported. */ - Flags |= CF_UNSIGNED | CF_FORCECHAR; - BitFieldFullWidthFlags |= CF_UNSIGNED; + Flags |= (EndBit <= CHAR_BITS) ? CF_CHAR : CF_INT; + if (IsSignUnsigned (Expr->Type)) { + Flags |= CF_UNSIGNED; + } + + /* Flags we need operate on the whole bit-field, without CF_FORCECHAR. */ + BitFieldFullWidthFlags = Flags; + + /* If we're adjusting, then only load a char (not an int) and do only char ops; + ** We will clear the high byte in the adjustment. CF_FORCECHAR does nothing if the + ** type is not CF_CHAR. + */ + if (AdjustBitField) { + /* If adjusting, then we're sign extending manually, so do everything unsigned + ** to make shifts faster. + */ + Flags |= CF_UNSIGNED | CF_FORCECHAR; + BitFieldFullWidthFlags |= CF_UNSIGNED; + } + } else { + /* If Expr is an incomplete ESY type, bail out */ + if (IsIncompleteESUType (Expr->Type)) { + return; + } + Flags |= TypeOf (Expr->Type); } - } else if ((Flags & CF_TYPEMASK) == 0) { - /* If Expr is an incomplete ESY type, bail out */ - if (IsIncompleteESUType (Expr->Type)) { - return; - } - Flags |= TypeOf (Expr->Type); } if (ED_YetToTest (Expr)) { @@ -254,13 +256,13 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) /* We always need to do something with the low byte, so there is no opportunity ** for optimization by skipping it. */ - CHECK (Expr->BitOffs < CHAR_BITS); + CHECK (Expr->Type->A.B.Offs < CHAR_BITS); if (ED_YetToTest (Expr)) { - g_testbitfield (Flags, Expr->BitOffs, Expr->BitWidth); + g_testbitfield (Flags, Expr->Type->A.B.Offs, Expr->Type->A.B.Width); } else { g_extractbitfield (Flags, BitFieldFullWidthFlags, IsSignSigned (Expr->Type), - Expr->BitOffs, Expr->BitWidth); + Expr->Type->A.B.Offs, Expr->Type->A.B.Width); } } diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index bdc7be006..37566a455 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -832,8 +832,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) */ if (ED_IsLocLiteral (&Arg2.Expr) && IS_Get (&WritableStrings) == 0 && - GetLiteralSize (Arg2.Expr.LVal) == 1 && - GetLiteralStr (Arg2.Expr.LVal)[0] == '\0') { + GetLiteralSize (Arg2.Expr.V.LVal) == 1 && + GetLiteralStr (Arg2.Expr.V.LVal)[0] == '\0') { /* Drop the generated code so we have the first argument in the ** primary @@ -841,7 +841,7 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) RemoveCode (&Arg1.Push); /* We don't need the literal any longer */ - ReleaseLiteral (Arg2.Expr.LVal); + ReleaseLiteral (Arg2.Expr.V.LVal); /* We do now have Arg1 in the primary. Load the first character from ** this string and cast to int. This is the function result. @@ -1232,10 +1232,10 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) if (ED_IsLocLiteral (&Arg) && IS_Get (&WritableStrings) == 0) { /* Constant string literal */ - ED_MakeConstAbs (Expr, GetLiteralSize (Arg.LVal) - 1, type_size_t); + ED_MakeConstAbs (Expr, GetLiteralSize (Arg.V.LVal) - 1, type_size_t); /* We don't need the literal any longer */ - ReleaseLiteral (Arg.LVal); + ReleaseLiteral (Arg.V.LVal); /* Bail out, no need for further improvements */ goto ExitPoint; diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 56d884bb6..bb87c7472 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -183,13 +183,6 @@ struct SymEntry { const Type* Type; /* Underlying type */ } E; - /* Data for bit fields */ - struct { - unsigned Offs; /* Byte offset into struct */ - unsigned BitOffs; /* Bit offset into storage unit */ - unsigned BitWidth; /* Width in bits */ - } B; - /* Data for functions */ struct { struct Segments* Seg; /* Segments for this function */ diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 4073a38bc..5d7bd1436 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -881,10 +881,8 @@ SymEntry* AddBitField (const char* Name, const Type* T, unsigned Offs, Entry = NewSymEntry (Name, SC_BITFIELD); /* Set the symbol attributes. Bit-fields are always integral types. */ - Entry->Type = TypeDup (T); - Entry->V.B.Offs = Offs; - Entry->V.B.BitOffs = BitOffs; - Entry->V.B.BitWidth = BitWidth; + Entry->Type = NewBitFieldType (T, BitOffs, BitWidth); + Entry->V.Offs = Offs; if (!SignednessSpecified) { /* int is treated as signed int everywhere except bit-fields; switch it to unsigned, @@ -896,8 +894,10 @@ SymEntry* AddBitField (const char* Name, const Type* T, unsigned Offs, */ CHECK ((Entry->Type->C & T_MASK_SIGN) == T_SIGN_SIGNED || IsTypeChar (Entry->Type)); - Entry->Type->C &= ~T_MASK_SIGN; - Entry->Type->C |= T_SIGN_UNSIGNED; + Entry->Type[0].C &= ~T_MASK_SIGN; + Entry->Type[0].C |= T_SIGN_UNSIGNED; + Entry->Type[1].C &= ~T_MASK_SIGN; + Entry->Type[1].C |= T_SIGN_UNSIGNED; } /* Add the entry to the symbol table */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 8c9da3445..6052f4a84 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -278,6 +278,21 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) SetResult (Result, TC_STRICT_COMPATIBLE); } + /* Bit-fields are considered compatible if they have the same + ** signedness, bit-offset and bit-width. + */ + if (IsTypeBitField (lhs) || IsTypeBitField (rhs)) { + if (!IsTypeBitField (lhs) || + !IsTypeBitField (rhs) || + lhs->A.B.Offs != rhs->A.B.Offs || + lhs->A.B.Width != rhs->A.B.Width) { + SetResult (Result, TC_INCOMPATIBLE); + } + if (LeftType != RightType) { + SetResult (Result, TC_STRICT_COMPATIBLE); + } + } + /* If the underlying types are not identical, the types are incompatible */ if (LeftType != RightType) { SetResult (Result, TC_INCOMPATIBLE); diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 16f173cc4..a7528a2f8 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -83,11 +83,16 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Get the sizes of the types. Since we've excluded void types, checking ** for known sizes makes sense here. */ - if (ED_IsBitField (Expr)) { - OldBits = Expr->BitWidth; + if (IsTypeBitField (OldType)) { + OldBits = OldType->A.B.Width; } else { OldBits = CheckedSizeOf (OldType) * CHAR_BITS; } + + /* If the new type is a bit-field, we use its underlying type instead */ + if (IsTypeBitField (NewType)) { + NewType = GetUnderlyingType (NewType); + } NewBits = CheckedSizeOf (NewType) * CHAR_BITS; /* lvalue? */ @@ -167,9 +172,6 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) ExitPoint: /* The expression has always the new type */ ReplaceType (Expr, NewType); - - /* Bit-fields are converted to integers */ - ED_DisBitField (Expr); } From d69e81cd66e7bb8ba307ea654a7c643fc8d3d4a6 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Thu, 27 May 2021 15:44:52 +0800 Subject: [PATCH 2111/2161] Moved and improved test cases for Issue #1462. Fixed an old test case for unsigned enum bit-fields that are supposed to be int-promoted. --- test/{todo => val}/bug1462-2.c | 0 test/{todo => val}/bug1462-3.c | 18 +++---- test/val/bug1462-4.c | 85 ++++++++++++++++++++++++++++++++++ test/{todo => val}/bug1462.c | 0 test/val/enum-bitfield.c | 37 +++++++++++---- 5 files changed, 122 insertions(+), 18 deletions(-) rename test/{todo => val}/bug1462-2.c (100%) rename test/{todo => val}/bug1462-3.c (82%) create mode 100644 test/val/bug1462-4.c rename test/{todo => val}/bug1462.c (100%) diff --git a/test/todo/bug1462-2.c b/test/val/bug1462-2.c similarity index 100% rename from test/todo/bug1462-2.c rename to test/val/bug1462-2.c diff --git a/test/todo/bug1462-3.c b/test/val/bug1462-3.c similarity index 82% rename from test/todo/bug1462-3.c rename to test/val/bug1462-3.c index b75d568b9..12559b94f 100644 --- a/test/todo/bug1462-3.c +++ b/test/val/bug1462-3.c @@ -1,6 +1,6 @@ /* issue #1462 - Bit-fields are still broken */ -/* More testson "op= expression result value" that a naive fix might fail with */ +/* More tests on "op= expression result value" that a naive fix might fail with */ #include <stdio.h> @@ -27,26 +27,26 @@ void test1(void) T1 a = { 3, 3, 3, 3 }; int i; - i = a.a += a.b + a.c; - if (i != 1) { + i = a.a -= a.b + a.c; + if (i != -3 || a.a != -3) { ++failures1; } printf("i = %d, a.a = %d\n", i, a.a); - i = a.b *= -1; - if (i != 5 || a.b != 5) { + a.b = i = a.b / -1; + if (i != -3 || a.b != 5) { ++failures1; } printf("i = %d, a.b = %d\n", i, a.b); - i = a.c * -1; - if (i != -3) { + i = a.c = 0; + if (i != 0 || a.c != 0) { ++failures1; } printf("i = %d, a.c = %d\n", i, a.c); - i = a.d ^= -1; - if (i != 4 || a.d != 4) { + i = a.d /= -1; + if (i != 5 || a.d != 5) { ++failures1; } printf("i = %d, a.d = %d\n", i, a.d); diff --git a/test/val/bug1462-4.c b/test/val/bug1462-4.c new file mode 100644 index 000000000..f811ddbd6 --- /dev/null +++ b/test/val/bug1462-4.c @@ -0,0 +1,85 @@ + +/* issue #1462 - Bit-fields are still broken */ +/* More tests on "op= expression result value" that a naive fix might fail with */ + +#include <stdio.h> +#include <limits.h> + +#define SMALL_WIDTH 4 +#define LARGE_WIDTH (CHAR_BIT * sizeof (unsigned int)) + +typedef struct { + unsigned int a : SMALL_WIDTH; + unsigned int b : SMALL_WIDTH; + unsigned int c : SMALL_WIDTH; + unsigned int d : SMALL_WIDTH; +} T1; + +typedef struct { + unsigned int a : LARGE_WIDTH; + unsigned int b : LARGE_WIDTH; + unsigned int c : LARGE_WIDTH; + unsigned int d : LARGE_WIDTH; +} T2; + + +int failures1 = 0; +int failures2 = 0; + +void test1(void) +{ + T1 a = { 0, 0, 0, 0 }; + + printf("\nunsigned int : %d\n", SMALL_WIDTH); + if (!(~a.a < 0)) { + ++failures1; + } + printf("~a.a < 0 : %d\n", ~a.a < 0); + if (!(0 > ~a.b)) { + ++failures1; + } + printf("0 > ~a.b : %d\n",0 > ~a.b); + if (!(a.c > -1)) { + ++failures1; + } + printf("a.c > -1 : %d\n", a.c > -1); + if (!(-1 < a.d)) { + ++failures1; + } + printf("-1 < a.d : %d\n", -1 < a.d); + + printf("Failures: %d\n", failures1); +} + +void test2(void) +{ + T1 b = { 0, 0, 0, 0 }; + + printf("\nunsigned int : %d\n", LARGE_WIDTH); + if (!(~b.a < 0)) { + ++failures2; + } + printf("~b.a < 0 : %d\n", ~b.a < 0); + if (!(0 > ~b.b)) { + ++failures2; + } + printf("0 > ~b.b : %d\n", 0 > ~b.b); + if (!(b.c > -1)) { + ++failures2; + } + printf("b.c > -1 : %d\n", b.c > -1); + if (!(-1 < b.d)) { + ++failures2; + } + printf("-1 < b.d : %d\n", -1 < b.d); + + printf("Failures: %d\n", failures2); +} + +int main(void) +{ + test1(); + test2(); + return failures1 + failures2; +} + diff --git a/test/todo/bug1462.c b/test/val/bug1462.c similarity index 100% rename from test/todo/bug1462.c rename to test/val/bug1462.c diff --git a/test/val/enum-bitfield.c b/test/val/enum-bitfield.c index a942091c2..5669978c9 100644 --- a/test/val/enum-bitfield.c +++ b/test/val/enum-bitfield.c @@ -23,6 +23,7 @@ */ #include <stdio.h> +#include <limits.h> static unsigned char failures = 0; @@ -35,7 +36,7 @@ enum e10u { static struct enum_bitfield_uint { enum e10u x : 1; enum e10u y : 8; - enum e10u z : 16; + enum e10u z : CHAR_BIT * sizeof (enum e10u); } e10ubf = {0, E10U_200, E10U_1000}; static void test_enum_bitfield_uint(void) @@ -68,11 +69,11 @@ static void test_enum_bitfield_uint(void) failures++; } - /* Check signedness, should be unsigned. */ + /* Check signedness, should be signed. */ { long v = e10ubf.x - 2; - if (v < 0) { - printf ("Got negative v = %ld, expected large positive.\n", v); + if (v >= 0) { + printf ("Got non-negative v (= e10ubf.x - 2) = %ld, expected negative.\n", v); failures++; } } @@ -85,6 +86,15 @@ static void test_enum_bitfield_uint(void) printf ("Got e10ubf.z = %u, expected 1023.\n", e10ubf.z); failures++; } + + /* Check signedness, should be unsigned. */ + { + long v = e10ubf.z - 1024; + if (v < 0) { + printf ("Got negative v (= e10ubf.z - 1024) = %ld, expected positive.\n", v); + failures++; + } + } } /* Enum with underlying type signed int. */ @@ -97,7 +107,7 @@ enum e11i { static struct enum_bitfield_int { enum e11i x : 2; enum e11i y : 8; - enum e11i z : 16; + enum e11i z : CHAR_BIT * sizeof (enum e11i); } e11ibf = {E11I_M1, E11I_100, E11I_1000}; static void test_enum_bitfield_int(void) @@ -133,8 +143,8 @@ static void test_enum_bitfield_int(void) /* Check signedness, should be signed. */ { long v = e11ibf.x - 2; - if (v > 0) { - printf ("Got positive v = %ld, expected negative.\n", v); + if (v >= 0) { + printf ("Got non-negative v (= e11ibf.x - 2) = %ld, expected negative.\n", v); failures++; } } @@ -147,6 +157,15 @@ static void test_enum_bitfield_int(void) printf ("Got e11ibf.z = %d, expected 1023.\n", e11ibf.z); failures++; } + + /* Check signedness, should be signed. */ + { + long v = e11ibf.z - 1024; + if (v >= 0) { + printf ("Got non-negative v (= e11ibf.z - 1024) = %ld, expected negative.\n", v); + failures++; + } + } } /* Enum with underlying type unsigned char. */ @@ -157,7 +176,7 @@ enum e7uc { static struct enum_bitfield_uchar { enum e7uc x : 1; enum e7uc y : 4; - enum e7uc z : 8; + enum e7uc z : CHAR_BIT; } e7ucbf = {0, 10, E7UC_100}; static void test_enum_bitfield_uchar(void) @@ -212,7 +231,7 @@ enum e8sc { static struct enum_bitfield_char { enum e8sc x : 1; enum e8sc y : 4; - enum e8sc z : 8; + enum e8sc z : CHAR_BIT; } e8scbf = {0, 5, E8SC_100}; static void test_enum_bitfield_char(void) From 7d6541274d58a9bff7bdf1092b48b3644d960bad Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Wed, 9 Jun 2021 10:23:42 -0500 Subject: [PATCH 2112/2161] Changes to I/O access --- include/sym1.h | 77 ++++------- libsrc/sym1/bitio.s | 220 ------------------------------ libsrc/sym1/display.s | 126 +---------------- libsrc/sym1/read.s | 6 +- targettest/sym1/symDisplay.c | 255 +++++++++++++++++------------------ targettest/sym1/symHello.c | 3 +- targettest/sym1/symIO.c | 112 +++++++-------- targettest/sym1/symTiny.c | 3 +- 8 files changed, 219 insertions(+), 583 deletions(-) delete mode 100644 libsrc/sym1/bitio.s diff --git a/include/sym1.h b/include/sym1.h index 4fb66b251..bedaa7913 100644 --- a/include/sym1.h +++ b/include/sym1.h @@ -91,6 +91,30 @@ #define DISP_LOW_LEFT 0x10 // Lower left segment +/*****************************************************************************/ +/* Hardware */ +/*****************************************************************************/ + + + +#include <_6522.h> +#define VIA1 (*(struct __6522*)0xA000) // U25 +#define VIA2 (*(struct __6522*)0xA800) // U28 +#define VIA3 (*(struct __6522*)0xAC00) // U29 + + +struct _display { + unsigned char d0; // left-most seven-segment display + unsigned char d1; // second seven-segment display + unsigned char d2; // third seven-segment display + unsigned char d3; // fouth seven-segment display + unsigned char d4; // fifth seven-segment display + unsigned char d5; // sixth seven-segment display + unsigned char d6; // buffer byte to the right +}; +#define DISPLAY (*(struct _display*)0xA640) + + /*****************************************************************************/ /* Code */ @@ -98,55 +122,10 @@ -int __fastcall__ beep (void); // Beep sound -void __fastcall__ set_D0 (unsigned char); // Set display digit 0 -unsigned char __fastcall__ get_D0 (void); // Get value of display digit 0 -void __fastcall__ set_D1 (unsigned char); // Set display digit 1 -unsigned char __fastcall__ get_D1 (void); // Get value of display digit 1 -void __fastcall__ set_D2 (unsigned char); // Set display digit 2 -unsigned char __fastcall__ get_D2 (void); // Get value of display digit 2 -void __fastcall__ set_D3 (unsigned char); // Set display digit 3 -unsigned char __fastcall__ get_D3 (void); // Get value of display digit 3 -void __fastcall__ set_D4 (unsigned char); // Set display digit 4 -unsigned char __fastcall__ get_D4 (void); // Get value of display digit 4 -void __fastcall__ set_D5 (unsigned char); // Set display digit 5 -unsigned char __fastcall__ get_D5 (void); // Get value of display digit 5 -void __fastcall__ set_D6 (unsigned char); // Set byte to the right of display (leading buffer) -unsigned char __fastcall__ get_D6 (void); // Get value of memory byte to the right of display -void __fastcall__ fdisp (void); // Flash display - -int __fastcall__ loadt (int); // Read from tape (id) -int __fastcall__ dumpt (int, int, int); // Write to tape (id, start_addr, end_addr) - -void __fastcall__ set_DDR1A (unsigned char); // Set data direction register 1A (U25) -unsigned char __fastcall__ get_DDR1A (void); // Get value of data direction register 1A -void __fastcall__ set_IOR1A (unsigned char); // Set I/O register 1A -unsigned char __fastcall__ get_IOR1A (void); // Get value of I/O register 1A - -void __fastcall__ set_DDR1B (unsigned char); // Set data direction register 1B (U25) -unsigned char __fastcall__ get_DDR1B (void); // Get value of data direction register 1B -void __fastcall__ set_IOR1B (unsigned char); // Set I/O register 1B -unsigned char __fastcall__ get_IOR1B (void); // Get value of I/O register 1B - -void __fastcall__ set_DDR2A (unsigned char); // Set data direction register 2A (U28) -unsigned char __fastcall__ get_DDR2A (void); // Get value of data direction register 2A -void __fastcall__ set_IOR2A (unsigned char); // Set I/O register 2A -unsigned char __fastcall__ get_IOR2A (void); // Get value of I/O register 2A - -void __fastcall__ set_DDR2B (unsigned char); // Set data direction register 2B (U28) -unsigned char __fastcall__ get_DDR2B (void); // Get value of data direction register 2B -void __fastcall__ set_IOR2B (unsigned char); // Set I/O register 2B -unsigned char __fastcall__ get_IOR2B (void); // Get value of I/O register 2B - -void __fastcall__ set_DDR3A (unsigned char); // Set data direction register 3A (U29) -unsigned char __fastcall__ get_DDR3A (void); // Get value of data direction register 3A -void __fastcall__ set_IOR3A (unsigned char); // Set I/O register 3A -unsigned char __fastcall__ get_IOR3A (void); // Get value of I/O register 3A - -void __fastcall__ set_DDR3B (unsigned char); // Set data direction register 3B (U29) -unsigned char __fastcall__ get_DDR3B (void); // Get value of data direction register 3B -void __fastcall__ set_IOR3B (unsigned char); // Set I/O register 3B -unsigned char __fastcall__ get_IOR3B (void); // Get value of I/O register 3B +void beep (void); // Beep sound +void fdisp (void); // Flash display +int __fastcall__ loadt (unsigned char); // Read from tape (id) +int __fastcall__ dumpt (unsigned char, const void*, const void*); // Write to tape (id, start_addr, end_addr) diff --git a/libsrc/sym1/bitio.s b/libsrc/sym1/bitio.s deleted file mode 100644 index a61dd4800..000000000 --- a/libsrc/sym1/bitio.s +++ /dev/null @@ -1,220 +0,0 @@ -; -; Wayne Parham (wayne@parhamdata.com) -; -; void set_DDR1A (int value); -; int get_DDR1A (void); -; void set_IOR1A (int value); -; int get_IOR1A (void); -; void set_DDR1B (int value); -; int get_DDR1B (void); -; void set_IOR1B (int value); -; int get_IOR1B (void); -; void set_DDR2A (int value); -; int get_DDR2A (void); -; void set_IOR2A (int value); -; int get_IOR2A (void); -; void set_DDR2B (int value); -; int get_DDR2B (void); -; void set_IOR2B (int value); -; int get_IOR2B (void); -; void set_DDR3A (int value); -; int get_DDR3A (void); -; void set_IOR3A (int value); -; int get_IOR3A (void); -; void set_DDR3B (int value); -; int get_DDR3B (void); -; void set_IOR3B (int value); -; int get_IOR3B (void); -; - -.include "sym1.inc" - -.export _set_DDR1A, _get_DDR1A, _set_IOR1A, _get_IOR1A -.export _set_DDR1B, _get_DDR1B, _set_IOR1B, _get_IOR1B -.export _set_DDR2A, _get_DDR2A, _set_IOR2A, _get_IOR2A -.export _set_DDR2B, _get_DDR2B, _set_IOR2B, _get_IOR2B -.export _set_DDR3A, _get_DDR3A, _set_IOR3A, _get_IOR3A -.export _set_DDR3B, _get_DDR3B, _set_IOR3B, _get_IOR3B - -.segment "CODE" - -.proc _set_DDR1A: near - - sta DDR1A ; Write data direction register for port 1A - rts - -.endproc - -.proc _get_DDR1A: near - - lda DDR1A ; Read data direction register for port 1A - ldx #>$0000 ; - rts ; Return DDR1A - -.endproc - -.proc _set_IOR1A: near - - sta OR1A ; Write I/O register for port 1A - rts - -.endproc - -.proc _get_IOR1A: near - - lda OR1A ; Read I/O register for port 1A - ldx #>$0000 ; - rts ; Return OR1A - -.endproc - -.proc _set_DDR1B: near - - sta DDR1B ; Write data direction register for port 1B - rts - -.endproc - -.proc _get_DDR1B: near - - lda DDR1B ; Read data direction register for port 1B - ldx #>$0000 ; - rts ; Return DDR1B - -.endproc - -.proc _set_IOR1B: near - - sta OR1B ; Write I/O register for port 1B - rts - -.endproc - -.proc _get_IOR1B: near - - lda OR1B ; Read I/O register for port 1B - ldx #>$0000 ; - rts ; Return OR1B - -.endproc - -.proc _set_DDR2A: near - - sta DDR2A ; Write data direction register for port 2A - rts - -.endproc - -.proc _get_DDR2A: near - - lda DDR2A ; Read data direction register for port 2A - ldx #>$0000 ; - rts ; Return DDR2A - -.endproc - -.proc _set_IOR2A: near - - sta OR2A ; Write I/O register for port 2A - rts - -.endproc - -.proc _get_IOR2A: near - - lda OR2A ; Read I/O register for port 2A - ldx #>$0000 ; - rts ; Return OR2A - -.endproc - -.proc _set_DDR2B: near - - sta DDR2B ; Write data direction register for port 2B - rts - -.endproc - -.proc _get_DDR2B: near - - lda DDR2B ; Read data direction register for port 2B - ldx #>$0000 ; - rts ; Return DDR2B - -.endproc - -.proc _set_IOR2B: near - - sta OR2B ; Write I/O register for port 2B - rts - -.endproc - -.proc _get_IOR2B: near - - lda OR2B ; Read I/O register for port 2B - ldx #>$0000 ; - rts ; Return OR2B - -.endproc - -.proc _set_DDR3A: near - - sta DDR3A ; Write data direction register for port 3A - rts - -.endproc - -.proc _get_DDR3A: near - - lda DDR3A ; Read data direction register for port 3A - ldx #>$0000 ; - rts ; Return DDR3A - -.endproc - -.proc _set_IOR3A: near - - sta OR3A ; Write I/O register for port 3A - rts ; Return 0000 - -.endproc - -.proc _get_IOR3A: near - - lda OR3A ; Read I/O register for port 3A - ldx #>$0000 ; - rts ; Return OR3A - -.endproc - -.proc _set_DDR3B: near - - sta DDR3B ; Write data direction register for port 3B - rts - -.endproc - -.proc _get_DDR3B: near - - lda DDR3B ; Read data direction register for port 3B - ldx #>$0000 ; - rts ; Return DDR3B - -.endproc - -.proc _set_IOR3B: near - - sta OR3B ; Write I/O register for port 3B - rts - -.endproc - -.proc _get_IOR3B: near - - lda OR3B ; Read I/O register for port 3B - ldx #>$0000 ; - rts ; Return OR3B - -.endproc - diff --git a/libsrc/sym1/display.s b/libsrc/sym1/display.s index 9bef30c01..1d3b0abfa 100644 --- a/libsrc/sym1/display.s +++ b/libsrc/sym1/display.s @@ -1,29 +1,12 @@ ; ; Wayne Parham (wayne@parhamdata.com) ; -; int fdisp (void); -; void set_D0 (char segments); -; int get_D0 (void); -; void set_D1 (char segments); -; int get_D1 (void); -; void set_D2 (char segments); -; int get_D2 (void); -; void set_D3 (char segments); -; int get_D3 (void); -; void set_D4 (char segments); -; int get_D4 (void); -; void set_D5 (char segments); -; int get_D5 (void); -; void set_D6 (char segments); -; int get_D6 (void); +; void fdisp (void); ; .include "sym1.inc" -.export _fdisp, _set_D0, _get_D0 -.export _set_D1, _get_D1, _set_D2, _get_D2 -.export _set_D3, _get_D3, _set_D4, _get_D4 -.export _set_D5, _get_D5, _set_D6, _get_D6 +.export _fdisp .segment "CODE" @@ -34,108 +17,3 @@ .endproc -.proc _set_D0: near - - sta DISBUF0 ; Write Digit 0 - rts - -.endproc - -.proc _get_D0: near - - lda DISBUF0 ; Read Digit 0 - ldx #>$0000 ; - rts ; Return DISBUF0 - -.endproc - -.proc _set_D1: near - - sta DISBUF1 ; Write Digit 1 - rts - -.endproc - -.proc _get_D1: near - - lda DISBUF1 ; Read Digit 1 - ldx #>$0000 ; - rts - -.endproc - -.proc _set_D2: near - - sta DISBUF2 ; Write Digit 2 - rts - -.endproc - -.proc _get_D2: near - - lda DISBUF2 ; Read Digit 2 - ldx #>$0000 ; - rts ; Return DISBUF2 - -.endproc - -.proc _set_D3: near - - sta DISBUF3 ; Write Digit 3 - rts - -.endproc - -.proc _get_D3: near - - lda DISBUF3 ; Read Digit 3 - ldx #>$0000 ; - rts ; Return DISBUF3 - -.endproc - -.proc _set_D4: near - - sta DISBUF4 ; Write Digit 4 - rts - -.endproc - -.proc _get_D4: near - - lda DISBUF4 ; Read Digit 4 - ldx #>$0000 ; - rts ; Return DISBUF4 - -.endproc - -.proc _set_D5: near - - sta DISBUF5 ; Write Digit 5 - rts - -.endproc - -.proc _get_D5: near - - lda DISBUF5 ; Read Digit 5 - ldx #>$0000 ; - rts ; Return DISBUF5 - -.endproc - -.proc _set_D6: near - - sta DISBUF6 ; Write byte to the right of display - rts - -.endproc - -.proc _get_D6: near - - lda DISBUF6 ; Read byte to the right of display - ldx #>$0000 ; - rts ; Return DISBUF6 - -.endproc - diff --git a/libsrc/sym1/read.s b/libsrc/sym1/read.s index b876a5915..7ab88f1e8 100644 --- a/libsrc/sym1/read.s +++ b/libsrc/sym1/read.s @@ -29,7 +29,11 @@ begin: dec ptr2 beq done ; If buffer full, return getch: jsr INTCHR ; Get character using Monitor ROM call - and #$7F ; Clear hi bit + jsr OUTCHR ; Echo it + and #$7F ; Clear hi bit and check for '\r' + cmp #$0D + bne putch + lda #$0A ; Replace with '\n' and set count to zero putch: ldy #$00 ; Put char into return buffer sta (ptr1),y diff --git a/targettest/sym1/symDisplay.c b/targettest/sym1/symDisplay.c index 7b056c3ab..e97518c79 100644 --- a/targettest/sym1/symDisplay.c +++ b/targettest/sym1/symDisplay.c @@ -25,9 +25,8 @@ void main (void) { puts( "\nType a message (40 chars max) and press ENTER, please:\n" ); - while( (c != '\r') && (i < 41) ) { + while( (c != '\n') && (i < 40) ) { c = getchar(); - putchar( c ); buffer[i] = c; i++; if( i == 40 ) { @@ -40,7 +39,6 @@ void main (void) { while( z == 0 ) { puts( "\n\nHow many times (0 for forever) to repeat?" ); c = getchar(); - putchar( c ); if( (c >= '0') && (c <= '9') ) { // between 1 and 9 loops allowed z = 1; // a number was pressed t = c - '0'; // convert char to int @@ -59,14 +57,13 @@ void main (void) { putchar( '\r' ); // Send CR to console - - set_D0( DISP_SPACE ); // Clear the display - set_D1( DISP_SPACE ); - set_D2( DISP_SPACE ); - set_D3( DISP_SPACE ); - set_D4( DISP_SPACE ); - set_D5( DISP_SPACE ); - set_D6( DISP_SPACE ); + DISPLAY.d0 = DISP_SPACE; // Clear the display + DISPLAY.d1 = DISP_SPACE; + DISPLAY.d2 = DISP_SPACE; + DISPLAY.d3 = DISP_SPACE; + DISPLAY.d4 = DISP_SPACE; + DISPLAY.d5 = DISP_SPACE; + DISPLAY.d6 = DISP_SPACE; for( d = 0; d < flashes ; d++ ) { fdisp(); // Display @@ -78,247 +75,247 @@ void main (void) { switch( buffer[l] ) { // Put the typed charaters case '1': // into the display buffer - set_D6( DISP_1 ); // one at a time + DISPLAY.d6 = DISP_1; // one at a time break; case '2': - set_D6( DISP_2 ); + DISPLAY.d6 = DISP_2; break; case '3': - set_D6( DISP_3 ); + DISPLAY.d6 = DISP_3; break; case '4': - set_D6( DISP_4 ); + DISPLAY.d6 = DISP_4; break; case '5': - set_D6( DISP_5 ); + DISPLAY.d6 = DISP_5; break; case '6': - set_D6( DISP_6 ); + DISPLAY.d6 = DISP_6; break; case '7': - set_D6( DISP_7 ); + DISPLAY.d6 = DISP_7; break; case '8': - set_D6( DISP_8 ); + DISPLAY.d6 = DISP_8; break; case '9': - set_D6( DISP_9 ); + DISPLAY.d6 = DISP_9; break; case '0': - set_D6( DISP_0 ); + DISPLAY.d6 = DISP_0; break; case 'A': - set_D6( DISP_A ); + DISPLAY.d6 = DISP_A; break; case 'a': - set_D6( DISP_A ); + DISPLAY.d6 = DISP_A; break; case 'B': - set_D6( DISP_b ); + DISPLAY.d6 = DISP_b; break; case 'b': - set_D6( DISP_b ); + DISPLAY.d6 = DISP_b; break; case 'C': - set_D6( DISP_C ); + DISPLAY.d6 = DISP_C; break; case 'c': - set_D6( DISP_c ); + DISPLAY.d6 = DISP_c; break; case 'D': - set_D6( DISP_d ); + DISPLAY.d6 = DISP_d; break; case 'd': - set_D6( DISP_d ); + DISPLAY.d6 = DISP_d; break; case 'E': - set_D6( DISP_E ); + DISPLAY.d6 = DISP_E; break; case 'e': - set_D6( DISP_e ); + DISPLAY.d6 = DISP_e; break; case 'F': - set_D6( DISP_F ); + DISPLAY.d6 = DISP_F; break; case 'f': - set_D6( DISP_F ); + DISPLAY.d6 = DISP_F; break; case 'G': - set_D6( DISP_G ); + DISPLAY.d6 = DISP_G; break; case 'g': - set_D6( DISP_g ); + DISPLAY.d6 = DISP_g; break; case 'H': - set_D6( DISP_H ); + DISPLAY.d6 = DISP_H; break; case 'h': - set_D6( DISP_h ); + DISPLAY.d6 = DISP_h; break; case 'I': - set_D6( DISP_I ); + DISPLAY.d6 = DISP_I; break; case 'i': - set_D6( DISP_i ); + DISPLAY.d6 = DISP_i; break; case 'J': - set_D6( DISP_J ); + DISPLAY.d6 = DISP_J; break; case 'j': - set_D6( DISP_J ); + DISPLAY.d6 = DISP_J; break; case 'K': - set_D6( DISP_K ); + DISPLAY.d6 = DISP_K; break; case 'k': - set_D6( DISP_K ); + DISPLAY.d6 = DISP_K; break; case 'L': - set_D6( DISP_L ); + DISPLAY.d6 = DISP_L; break; case 'l': - set_D6( DISP_L ); + DISPLAY.d6 = DISP_L; break; case 'M': - set_D0( get_D1() ); - set_D1( get_D2() ); - set_D2( get_D3() ); - set_D3( get_D4() ); - set_D4( get_D5() ); - set_D5( DISP_M_1 ); - set_D6( DISP_M_2 ); + DISPLAY.d0 = DISPLAY.d1; + DISPLAY.d1 = DISPLAY.d2; + DISPLAY.d2 = DISPLAY.d3; + DISPLAY.d3 = DISPLAY.d4; + DISPLAY.d4 = DISPLAY.d5; + DISPLAY.d5 = DISP_M_1; + DISPLAY.d6 = DISP_M_2; break; case 'm': - set_D0( get_D1() ); - set_D1( get_D2() ); - set_D2( get_D3() ); - set_D3( get_D4() ); - set_D4( get_D5() ); - set_D5( DISP_M_1 ); - set_D6( DISP_M_2 ); + DISPLAY.d0 = DISPLAY.d1; + DISPLAY.d1 = DISPLAY.d2; + DISPLAY.d2 = DISPLAY.d3; + DISPLAY.d3 = DISPLAY.d4; + DISPLAY.d4 = DISPLAY.d5; + DISPLAY.d5 = DISP_M_1; + DISPLAY.d6 = DISP_M_2; break; case 'N': - set_D6( DISP_n ); + DISPLAY.d6 = DISP_n; break; case 'n': - set_D6( DISP_n ); + DISPLAY.d6 = DISP_n; break; case 'O': - set_D6( DISP_O ); + DISPLAY.d6 = DISP_O; break; case 'o': - set_D6( DISP_o ); + DISPLAY.d6 = DISP_o; break; case 'P': - set_D6( DISP_P ); + DISPLAY.d6 = DISP_P; break; case 'p': - set_D6( DISP_P ); + DISPLAY.d6 = DISP_P; break; case 'Q': - set_D6( DISP_q ); + DISPLAY.d6 = DISP_q; break; case 'q': - set_D6( DISP_q ); + DISPLAY.d6 = DISP_q; break; case 'R': - set_D6( DISP_r ); + DISPLAY.d6 = DISP_r; break; case 'r': - set_D6( DISP_r ); + DISPLAY.d6 = DISP_r; break; case 'S': - set_D6( DISP_S ); + DISPLAY.d6 = DISP_S; break; case 's': - set_D6( DISP_S ); + DISPLAY.d6 = DISP_S; break; case 'T': - set_D6( DISP_t ); + DISPLAY.d6 = DISP_t; break; case 't': - set_D6( DISP_t ); + DISPLAY.d6 = DISP_t; break; case 'U': - set_D6( DISP_U ); + DISPLAY.d6 = DISP_U; break; case 'u': - set_D6( DISP_u ); + DISPLAY.d6 = DISP_u; break; case 'V': - set_D0( get_D1() ); - set_D1( get_D2() ); - set_D2( get_D3() ); - set_D3( get_D4() ); - set_D4( get_D5() ); - set_D5( DISP_V_1 ); - set_D6( DISP_V_2 ); + DISPLAY.d0 = DISPLAY.d1; + DISPLAY.d1 = DISPLAY.d2; + DISPLAY.d2 = DISPLAY.d3; + DISPLAY.d3 = DISPLAY.d4; + DISPLAY.d4 = DISPLAY.d5; + DISPLAY.d5 = DISP_V_1; + DISPLAY.d6 = DISP_V_2; break; case 'v': - set_D0( get_D1() ); - set_D1( get_D2() ); - set_D2( get_D3() ); - set_D3( get_D4() ); - set_D4( get_D5() ); - set_D5( DISP_V_1 ); - set_D6( DISP_V_2 ); + DISPLAY.d0 = DISPLAY.d1; + DISPLAY.d1 = DISPLAY.d2; + DISPLAY.d2 = DISPLAY.d3; + DISPLAY.d3 = DISPLAY.d4; + DISPLAY.d4 = DISPLAY.d5; + DISPLAY.d5 = DISP_V_1; + DISPLAY.d6 = DISP_V_2; break; case 'W': - set_D0( get_D1() ); - set_D1( get_D2() ); - set_D2( get_D3() ); - set_D3( get_D4() ); - set_D4( get_D5() ); - set_D5( DISP_W_1 ); - set_D6( DISP_W_2 ); + DISPLAY.d0 = DISPLAY.d1; + DISPLAY.d1 = DISPLAY.d2; + DISPLAY.d2 = DISPLAY.d3; + DISPLAY.d3 = DISPLAY.d4; + DISPLAY.d4 = DISPLAY.d5; + DISPLAY.d5 = DISP_W_1; + DISPLAY.d6 = DISP_W_2; break; case 'w': - set_D0( get_D1() ); - set_D1( get_D2() ); - set_D2( get_D3() ); - set_D3( get_D4() ); - set_D4( get_D5() ); - set_D5( DISP_W_1 ); - set_D6( DISP_W_2 ); + DISPLAY.d0 = DISPLAY.d1; + DISPLAY.d1 = DISPLAY.d2; + DISPLAY.d2 = DISPLAY.d3; + DISPLAY.d3 = DISPLAY.d4; + DISPLAY.d4 = DISPLAY.d5; + DISPLAY.d5 = DISP_W_1; + DISPLAY.d6 = DISP_W_2; break; case 'Y': - set_D6( DISP_Y ); + DISPLAY.d6 = DISP_Y; break; case 'y': - set_D6( DISP_Y ); + DISPLAY.d6 = DISP_Y; break; case 'Z': - set_D6( DISP_Z ); + DISPLAY.d6 = DISP_Z; break; case 'z': - set_D6( DISP_Z ); + DISPLAY.d6 = DISP_Z; break; case ' ': - set_D6( DISP_SPACE ); + DISPLAY.d6 = DISP_SPACE; break; case '.': - set_D6( DISP_PERIOD ); + DISPLAY.d6 = DISP_PERIOD; break; case '-': - set_D6( DISP_HYPHEN ); + DISPLAY.d6 = DISP_HYPHEN; break; case '\'': - set_D6( DISP_APOSTR ); + DISPLAY.d6 = DISP_APOSTR; break; case '"': - set_D6( DISP_APOSTR ); + DISPLAY.d6 = DISP_APOSTR; break; case '=': - set_D6( DISP_EQUAL ); + DISPLAY.d6 = DISP_EQUAL; break; case '_': - set_D6( DISP_BOTTOM ); + DISPLAY.d6 = DISP_BOTTOM; break; case '/': - set_D6( DISP_SLASH ); + DISPLAY.d6 = DISP_SLASH; break; case '\\': - set_D6( DISP_BACKSLASH ); + DISPLAY.d6 = DISP_BACKSLASH; break; default: displayable = 0; // Character not mapped @@ -328,12 +325,12 @@ void main (void) { putchar( buffer[l] ); // Send it to the console - set_D0( get_D1() ); // Scroll to the left - set_D1( get_D2() ); - set_D2( get_D3() ); - set_D3( get_D4() ); - set_D4( get_D5() ); - set_D5( get_D6() ); + DISPLAY.d0 = DISPLAY.d1; // Scroll to the left + DISPLAY.d1 = DISPLAY.d2; + DISPLAY.d2 = DISPLAY.d3; + DISPLAY.d3 = DISPLAY.d4; + DISPLAY.d4 = DISPLAY.d5; + DISPLAY.d5 = DISPLAY.d6; for( d = 0; d < flashes ; d++ ) { fdisp(); // Display @@ -342,13 +339,13 @@ void main (void) { } for( e = 0; e < 6; e++ ) { // Gradually fill the - set_D0( get_D1() ); // display with spaces - set_D1( get_D2() ); - set_D2( get_D3() ); - set_D3( get_D4() ); - set_D4( get_D5() ); - set_D5( DISP_SPACE ); - set_D6( DISP_SPACE ); + DISPLAY.d0 = DISPLAY.d1; // display with spaces + DISPLAY.d1 = DISPLAY.d2; + DISPLAY.d2 = DISPLAY.d3; + DISPLAY.d3 = DISPLAY.d4; + DISPLAY.d4 = DISPLAY.d5; + DISPLAY.d5 = DISP_SPACE; + DISPLAY.d6 = DISP_SPACE; for( d = 0; d < flashes ; d++ ) { fdisp(); // Display } diff --git a/targettest/sym1/symHello.c b/targettest/sym1/symHello.c index 7fb86f04e..543e00cb2 100644 --- a/targettest/sym1/symHello.c +++ b/targettest/sym1/symHello.c @@ -23,9 +23,8 @@ void main(void) { } printf( "Type a line and press ENTER, please.\n\n" ); - while( c != '\r' ) { + while( c != '\n' ) { c = getchar(); - putchar( c ); } printf( "\n\nThanks!\n\n" ); diff --git a/targettest/sym1/symIO.c b/targettest/sym1/symIO.c index 67e898801..99b020be2 100644 --- a/targettest/sym1/symIO.c +++ b/targettest/sym1/symIO.c @@ -12,24 +12,24 @@ #include <string.h> void main(void) { - int ddr1a = 0x00; - int ior1a = 0x00; - int ddr1b = 0x00; - int ior1b = 0x00; - int ddr2a = 0x00; - int ior2a = 0x00; - int ddr2b = 0x00; - int ior2b = 0x00; - int ddr3a = 0x00; - int ior3a = 0x00; - int ddr3b = 0x00; - int ior3b = 0x00; - int l = 0x00; - int val = 0x00; - int going = 0x01; - int instr = 0x01; - char* vp = 0x00; - char cmd[20] = { 0x00 }; + unsigned char ddr1a = 0x00; + unsigned char ior1a = 0x00; + unsigned char ddr1b = 0x00; + unsigned char ior1b = 0x00; + unsigned char ddr2a = 0x00; + unsigned char ior2a = 0x00; + unsigned char ddr2b = 0x00; + unsigned char ior2b = 0x00; + unsigned char ddr3a = 0x00; + unsigned char ior3a = 0x00; + unsigned char ddr3b = 0x00; + unsigned char ior3b = 0x00; + unsigned char val = 0x00; + int going = 0x01; + int instr = 0x01; + int l = 0x00; + char* vp = 0x00; + char cmd[20] = { 0x00 }; while( going ) { @@ -38,18 +38,18 @@ void main(void) { putchar( '\n' ); } - ddr1a = get_DDR1A(); - ior1a = get_IOR1A(); - ddr1b = get_DDR1B(); - ior1b = get_IOR1B(); - ddr2a = get_DDR2A(); - ior2a = get_IOR2A(); - ddr2b = get_DDR2B(); - ior2b = get_IOR2B(); - ddr3a = get_DDR3A(); - ior3a = get_IOR3A(); - ddr3b = get_DDR3B(); - ior3b = get_IOR3B(); + ddr1a = VIA1.ddra; + ior1a = VIA1.pra; + ddr1b = VIA1.ddrb; + ior1b = VIA1.prb; + ddr2a = VIA2.ddra; + ior2a = VIA2.pra; + ddr2b = VIA2.ddrb; + ior2b = VIA2.prb; + ddr3a = VIA3.ddra; + ior3a = VIA3.pra; + ddr3b = VIA3.ddrb; + ior3b = VIA3.prb; puts( "================== Digital I/O Status ==================" ); puts( " Port1A Port1B Port2A Port2B Port3A Port3B" ); @@ -63,7 +63,7 @@ void main(void) { puts( "bits off and the bottom three on, type 'IOR2A 07'." ); puts( "Press ENTER without any command to see register values" ); puts( "without changing any of them. Type 'help' to see these" ); - puts( "instructions again and type 'stop' to end the program.\n"); + puts( "instructions again and type 'quit' to end the program.\n"); puts( "Available registers: DDR1A, IOR1A, DDR1B, IOR1B, DDR2A" ); puts( "IOR2A, DDR2B, IOR2B, DDR3A, IOR3A, DDR3B and IOR3B." ); instr = 0; @@ -74,7 +74,7 @@ void main(void) { fgets(cmd, sizeof(cmd)-1, stdin); cmd[strlen(cmd)-1] = '\0'; - if( strncasecmp(cmd, "stop", 4) == 0) { + if( strncasecmp(cmd, "quit", 4) == 0) { going = 0; } else if( strncasecmp(cmd, "help", 4) == 0) { @@ -83,85 +83,85 @@ void main(void) { else if( strncasecmp(cmd, "ddr1a", 5) == 0) { vp = strchr(cmd, ' '); if( vp ) { - val = atoi( vp ); - set_DDR1A( val ); + val = (unsigned char) strtol( vp, NULL, 0 ); + VIA1.ddra = val; } } else if( strncasecmp(cmd, "ior1a", 5) == 0) { vp = strchr(cmd, ' '); if( vp ) { - val = atoi( vp ); - set_IOR1A( val ); + val = (unsigned char) strtol( vp, NULL, 0 ); + VIA1.pra = val; } } else if( strncasecmp(cmd, "ddr1b", 5) == 0) { vp = strchr(cmd, ' '); if( vp ) { - val = atoi( vp ); - set_DDR1B( val ); + val = (unsigned char) strtol( vp, NULL, 0 ); + VIA1.ddrb = val; } } else if( strncasecmp(cmd, "ior1b", 5) == 0) { vp = strchr(cmd, ' '); if( vp ) { - val = atoi( vp ); - set_IOR1B( val ); + val = (unsigned char) strtol( vp, NULL, 0 ); + VIA1.prb = val; } } else if( strncasecmp(cmd, "ddr2a", 5) == 0) { vp = strchr(cmd, ' '); if( vp ) { - val = atoi( vp ); - set_DDR2A( val ); + val = (unsigned char) strtol( vp, NULL, 0 ); + VIA2.ddra = val; } } else if( strncasecmp(cmd, "ior2a", 5) == 0) { vp = strchr(cmd, ' '); if( vp ) { - val = atoi( vp ); - set_IOR2A( val ); + val = (unsigned char) strtol( vp, NULL, 0 ); + VIA2.pra = val; } } else if( strncasecmp(cmd, "ddr2b", 5) == 0) { vp = strchr(cmd, ' '); if( vp ) { - val = atoi( vp ); - set_DDR2B( val ); + val = (unsigned char) strtol( vp, NULL, 0 ); + VIA2.ddrb = val; } } else if( strncasecmp(cmd, "ior2b", 5) == 0) { vp = strchr(cmd, ' '); if( vp ) { - val = atoi( vp ); - set_IOR2B( val ); + val = (unsigned char) strtol( vp, NULL, 0 ); + VIA2.prb = val; } } else if( strncasecmp(cmd, "ddr3a", 5) == 0) { vp = strchr(cmd, ' '); if( vp ) { - val = atoi( vp ); - set_DDR3A( val ); + val = (unsigned char) strtol( vp, NULL, 0 ); + VIA3.ddra = val; } } else if( strncasecmp(cmd, "ior3a", 5) == 0) { vp = strchr(cmd, ' '); if( vp ) { - val = atoi( vp ); - set_IOR3A( val ); + val = (unsigned char) strtol( vp, NULL, 0 ); + VIA3.pra = val; } } else if( strncasecmp(cmd, "ddr3b", 5) == 0) { vp = strchr(cmd, ' '); if( vp ) { - val = atoi( vp ); - set_DDR3B( val ); + val = (unsigned char) strtol( vp, NULL, 0 ); + VIA3.ddrb = val; } } else if( strncasecmp(cmd, "ior3b", 5) == 0) { vp = strchr(cmd, ' '); if( vp ) { - val = atoi( vp ); - set_IOR3B( val ); + val = (unsigned char) strtol( vp, NULL, 0 ); + VIA3.prb = val; } } } diff --git a/targettest/sym1/symTiny.c b/targettest/sym1/symTiny.c index 1e9f86516..bbca4f9d1 100644 --- a/targettest/sym1/symTiny.c +++ b/targettest/sym1/symTiny.c @@ -26,9 +26,8 @@ void main(void) { } } - while( c != '\r' ) { + while( c != '\n' ) { c = getchar(); - putchar( c ); } puts( "\n\nThanks!\n" ); From 9a523abbfbb2c0939807e1e85fd1d1ef555b044d Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 10 Jun 2021 15:48:21 +0200 Subject: [PATCH 2113/2161] limits.h: provide PATH_MAX - stdio.h: define FILENAME_MAX to PATH_MAX - stdio.h, stdio.inc: increase FILENAME_MAX/PATH_MAX for Atari (For DOSes with subdirectory support.) --- asminc/stdio.inc | 2 +- include/limits.h | 12 ++++++++++++ include/stdio.h | 14 ++------------ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/asminc/stdio.inc b/asminc/stdio.inc index c727e8d0b..feb061d70 100644 --- a/asminc/stdio.inc +++ b/asminc/stdio.inc @@ -44,7 +44,7 @@ EOF = -1 .if .defined(__APPLE2__) FILENAME_MAX = 64+1 .elseif .defined(__ATARI__) -FILENAME_MAX = 12+1 +FILENAME_MAX = 63+1 .elseif .defined(__LUNIX__) FILENAME_MAX = 80+1 .elseif .defined(__TELESTRAT__) diff --git a/include/limits.h b/include/limits.h index 23474c78c..8dbc83ff2 100644 --- a/include/limits.h +++ b/include/limits.h @@ -63,6 +63,18 @@ #define ULONG_MAX 4294967295UL +/* These defines that are platform dependent */ +#if defined(__APPLE2__) +# define PATH_MAX (64+1) +#elif defined(__ATARI__) +# define PATH_MAX (63+1) +#elif defined(__LUNIX__) +# define PATH_MAX (80+1) +#elif defined(__TELESTRAT__) +# define PATH_MAX (50+1) +#else +# define PATH_MAX (16+1) +#endif /* End of limits.h */ diff --git a/include/stdio.h b/include/stdio.h index 73dc05bdb..916affe71 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -40,6 +40,7 @@ #include <stddef.h> #include <stdarg.h> +#include <limits.h> @@ -64,18 +65,7 @@ extern FILE* stderr; #define SEEK_SET 2 #define TMP_MAX 256 -/* Standard defines that are platform dependent */ -#if defined(__APPLE2__) -# define FILENAME_MAX (64+1) -#elif defined(__ATARI__) -# define FILENAME_MAX (12+1) -#elif defined(__LUNIX__) -# define FILENAME_MAX (80+1) -#elif defined(__TELESTRAT__) -# define FILENAME_MAX (50+1) -#else -# define FILENAME_MAX (16+1) -#endif +#define FILENAME_MAX PATH_MAX #define L_tmpnam FILENAME_MAX From ae9101961e149d75d46440390a772b1de0ba0311 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 10 Jun 2021 16:06:37 +0200 Subject: [PATCH 2114/2161] stdio.inc,stdio.h: increase CBM PATH_MAX/FILENAME_MAX value to 256+1 --- asminc/stdio.inc | 2 ++ include/limits.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/asminc/stdio.inc b/asminc/stdio.inc index feb061d70..6eb458b62 100644 --- a/asminc/stdio.inc +++ b/asminc/stdio.inc @@ -45,6 +45,8 @@ EOF = -1 FILENAME_MAX = 64+1 .elseif .defined(__ATARI__) FILENAME_MAX = 63+1 +.elseif .defined(__CBM__) +FILENAME_MAX = 256+1 .elseif .defined(__LUNIX__) FILENAME_MAX = 80+1 .elseif .defined(__TELESTRAT__) diff --git a/include/limits.h b/include/limits.h index 8dbc83ff2..532f5104a 100644 --- a/include/limits.h +++ b/include/limits.h @@ -68,6 +68,8 @@ # define PATH_MAX (64+1) #elif defined(__ATARI__) # define PATH_MAX (63+1) +#elif defined(__CBM__) +# define PATH_MAX (256+1) #elif defined(__LUNIX__) # define PATH_MAX (80+1) #elif defined(__TELESTRAT__) From c90c3c9133cc561c015562390c869a982c603cad Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 10 Jun 2021 16:17:43 +0200 Subject: [PATCH 2115/2161] stdio.inc,stdio.h: set CBM PATH_MAX/FILENAME_MAX value to 255 Some parts of the runtime library cannot handle larger paths. --- asminc/stdio.inc | 2 +- include/limits.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/asminc/stdio.inc b/asminc/stdio.inc index 6eb458b62..426389de3 100644 --- a/asminc/stdio.inc +++ b/asminc/stdio.inc @@ -46,7 +46,7 @@ FILENAME_MAX = 64+1 .elseif .defined(__ATARI__) FILENAME_MAX = 63+1 .elseif .defined(__CBM__) -FILENAME_MAX = 256+1 +FILENAME_MAX = 255 .elseif .defined(__LUNIX__) FILENAME_MAX = 80+1 .elseif .defined(__TELESTRAT__) diff --git a/include/limits.h b/include/limits.h index 532f5104a..531c6bef2 100644 --- a/include/limits.h +++ b/include/limits.h @@ -69,7 +69,7 @@ #elif defined(__ATARI__) # define PATH_MAX (63+1) #elif defined(__CBM__) -# define PATH_MAX (256+1) +# define PATH_MAX (255) /* should be 256+1, see libsrc/common/_cmd.s why it's not */ #elif defined(__LUNIX__) # define PATH_MAX (80+1) #elif defined(__TELESTRAT__) From 7f1f0249f3d79a091f16b8b8462a25ae5c7f701c Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 10 Jun 2021 17:15:29 +0200 Subject: [PATCH 2116/2161] enumdevdir.c: allocate path name buffers from the heap. --- samples/enumdevdir.c | 46 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/samples/enumdevdir.c b/samples/enumdevdir.c index ce2dc99ec..97d69d8a6 100644 --- a/samples/enumdevdir.c +++ b/samples/enumdevdir.c @@ -16,31 +16,47 @@ #include <cc65.h> -void printdir (char *newdir) +int printdir (char *newdir) { - char olddir[FILENAME_MAX]; - char curdir[FILENAME_MAX]; + char *olddir; + char *curdir; DIR *dir; struct dirent *ent; char *subdirs = NULL; unsigned dirnum = 0; unsigned num; - getcwd (olddir, sizeof (olddir)); + olddir = malloc (FILENAME_MAX); + if (olddir != NULL) { + + perror ("cannot allocate memory"); + return 1; + } + + getcwd (olddir, FILENAME_MAX); if (chdir (newdir)) { /* If chdir() fails we just print the ** directory name - as done for files. */ printf (" Dir %s\n", newdir); - return; + free (olddir); + return 0; + } + + curdir = malloc (FILENAME_MAX); + if (curdir != NULL) { + + perror ("cannot allocate memory"); + return 1; } /* We call getcwd() in order to print the ** absolute pathname for a subdirectory. */ - getcwd (curdir, sizeof (curdir)); + getcwd (curdir, FILENAME_MAX); printf (" Dir %s:\n", curdir); + free (curdir); /* Calling opendir() always with "." avoids ** fiddling around with pathname separators. @@ -65,18 +81,28 @@ void printdir (char *newdir) closedir (dir); for (num = 0; num < dirnum; ++num) { - printdir (subdirs + FILENAME_MAX * num); + if (printdir (subdirs + FILENAME_MAX * num)) + break; } free (subdirs); chdir (olddir); + free (olddir); + return 0; } void main (void) { unsigned char device; - char devicedir[FILENAME_MAX]; + char *devicedir; + + devicedir = malloc (FILENAME_MAX); + if (devicedir != NULL) { + + perror ("cannot allocate memory"); + return; + } /* Calling getfirstdevice()/getnextdevice() does _not_ turn on the motor ** of a drive-type device and does _not_ check for a disk in the drive. @@ -88,7 +114,7 @@ void main (void) /* Calling getdevicedir() _does_ check for a (formatted) disk in a ** floppy-disk-type device and returns NULL if that check fails. */ - if (getdevicedir (device, devicedir, sizeof (devicedir))) { + if (getdevicedir (device, devicedir, FILENAME_MAX)) { printdir (devicedir); } else { printf (" N/A\n"); @@ -100,4 +126,6 @@ void main (void) if (doesclrscrafterexit ()) { getchar (); } + + free (devicedir); } From f3db74395d830d4f5b02573e37ee58ffea1f0c87 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Thu, 10 Jun 2021 18:11:45 +0200 Subject: [PATCH 2117/2161] fix last change and use stdbool.h --- samples/enumdevdir.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/samples/enumdevdir.c b/samples/enumdevdir.c index 97d69d8a6..bf1ff3bbb 100644 --- a/samples/enumdevdir.c +++ b/samples/enumdevdir.c @@ -11,12 +11,14 @@ #include <string.h> #include <unistd.h> #include <stdlib.h> +#include <stdbool.h> #include <device.h> #include <dirent.h> #include <cc65.h> -int printdir (char *newdir) +/* returns true for error, false for OK */ +bool printdir (char *newdir) { char *olddir; char *curdir; @@ -27,10 +29,9 @@ int printdir (char *newdir) unsigned num; olddir = malloc (FILENAME_MAX); - if (olddir != NULL) { - + if (olddir == NULL) { perror ("cannot allocate memory"); - return 1; + return true; } getcwd (olddir, FILENAME_MAX); @@ -41,14 +42,13 @@ int printdir (char *newdir) */ printf (" Dir %s\n", newdir); free (olddir); - return 0; + return false; } curdir = malloc (FILENAME_MAX); - if (curdir != NULL) { - + if (curdir == NULL) { perror ("cannot allocate memory"); - return 1; + return true; } /* We call getcwd() in order to print the @@ -88,7 +88,7 @@ int printdir (char *newdir) chdir (olddir); free (olddir); - return 0; + return false; } @@ -98,8 +98,7 @@ void main (void) char *devicedir; devicedir = malloc (FILENAME_MAX); - if (devicedir != NULL) { - + if (devicedir == NULL) { perror ("cannot allocate memory"); return; } From 25a35d6b59b718803d99bb058e6c5ee719e65573 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 9 Jun 2021 17:48:09 +0800 Subject: [PATCH 2118/2161] Fixed result type of certain operations, which was broken with the bit-field fix. --- src/cc65/assignment.c | 100 ++++-------------------------------------- src/cc65/expr.c | 22 +++------- 2 files changed, 14 insertions(+), 108 deletions(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index be6a8116f..05a6d9a96 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -155,7 +155,6 @@ void DoIncDecBitField (ExprDesc* Expr, long Val, unsigned KeepResult) unsigned Mask; unsigned ChunkFlags; const Type* ChunkType; - const Type* ResType; /* If the bit-field fits within one byte, do the following operations ** with bytes. @@ -190,11 +189,6 @@ void DoIncDecBitField (ExprDesc* Expr, long Val, unsigned KeepResult) /* Fetch the lhs into the primary register if needed */ LoadExpr (CF_NONE, Expr); - if (KeepResult == OA_NEED_OLD) { - /* Save the original expression value */ - g_save (Flags | CF_FORCECHAR); - } - /* Handle for add and sub */ if (Val > 0) { g_inc (Flags | CF_CONST, Val); @@ -205,11 +199,6 @@ void DoIncDecBitField (ExprDesc* Expr, long Val, unsigned KeepResult) /* Apply the mask */ g_and (Flags | CF_CONST, Mask); - if (KeepResult == OA_NEED_NEW) { - /* Save the result value */ - g_save (Flags | CF_FORCECHAR); - } - /* Do integral promotion without sign-extension if needed */ g_typecast (ChunkFlags | CF_UNSIGNED, Flags); @@ -229,6 +218,11 @@ void DoIncDecBitField (ExprDesc* Expr, long Val, unsigned KeepResult) /* Load the whole data chunk containing the bits to be changed */ LoadExpr (ChunkFlags, Expr); + if (KeepResult == OA_NEED_OLD) { + /* Save the original expression value */ + g_save (ChunkFlags | CF_FORCECHAR); + } + /* Get the bits that are not to be affected */ g_and (ChunkFlags | CF_CONST, ~(Mask << Expr->Type->A.B.Offs)); @@ -238,39 +232,10 @@ void DoIncDecBitField (ExprDesc* Expr, long Val, unsigned KeepResult) /* Store the whole data chunk containing the changed bits back */ Store (Expr, ChunkType); - /* Cache the expression result type */ - ResType = IntPromotion (Expr->Type); - - if (KeepResult != OA_NEED_NONE) { - /* Restore the expression result value */ - g_restore (Flags | CF_FORCECHAR); - - /* Promote if needed */ - if (KeepResult != OA_NEED_OLD) { - /* Do unsigned promotion first */ - g_typecast (TypeOf (ResType) | CF_UNSIGNED, Flags); - - /* Then do sign-extension */ - if (IsSignSigned (Expr->Type) && - Expr->Type->A.B.Width < CHAR_BITS * SizeOf (ResType)) { - /* The way is: - ** x = bits & bit_mask - ** m = 1 << (bit_width - 1) - ** r = (x ^ m) - m - ** Since we have already masked bits with bit_mask, we may skip the - ** first step. - */ - g_xor (Flags | CF_CONST, 1U << (Expr->Type->A.B.Width - 1U)); - g_dec ((Flags & ~CF_FORCECHAR) | CF_CONST, 1U << (Expr->Type->A.B.Width - 1U)); - } - } else { - /* Do promotion with sign-extension */ - g_typecast (TypeOf (ResType), Flags); - } + if (KeepResult == OA_NEED_OLD) { + /* Restore the original expression value */ + g_restore (ChunkFlags | CF_FORCECHAR); } - - /* Get the expression result type */ - Expr->Type = ResType; } @@ -285,10 +250,6 @@ static void OpAssignBitField (const GenDesc* Gen, ExprDesc* Expr, const char* Op unsigned Flags; unsigned ChunkFlags; const Type* ChunkType; - const Type* ResType; - - /* Cache the expression result type */ - ResType = IntPromotion (Expr->Type); ED_Init (&Expr2); Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; @@ -373,15 +334,6 @@ static void OpAssignBitField (const GenDesc* Gen, ExprDesc* Expr, const char* Op /* Store the whole data chunk containing the changed bits back */ Store (Expr, ChunkType); - /* Load the expression result value */ - if (IsSignSigned (Expr->Type)) { - unsigned SignExtensionMask = 1 << (Expr->Type->A.B.Width - 1); - Val = (Val^ SignExtensionMask) - SignExtensionMask; - } - ED_MakeConstAbs (Expr, Val, ResType); - LimitExprValue (Expr); - LoadExpr (CF_NONE, Expr); - /* Done */ goto Done; @@ -459,9 +411,6 @@ static void OpAssignBitField (const GenDesc* Gen, ExprDesc* Expr, const char* Op /* Apply the mask */ g_and (Flags | CF_CONST, Mask); - /* Save the expression result value */ - g_save (Flags); - /* Do integral promotion without sign-extension if needed */ g_typecast (ChunkFlags | CF_UNSIGNED, Flags); @@ -490,31 +439,8 @@ static void OpAssignBitField (const GenDesc* Gen, ExprDesc* Expr, const char* Op /* Store the whole data chunk containing the changed bits back */ Store (Expr, ChunkType); - /* Restore the expression result value */ - g_restore (Flags); - - /* Do unsigned promotion first */ - g_typecast (TypeOf (ResType) | CF_UNSIGNED, Flags); - - /* Then do sign-extension */ - if (IsSignSigned (Expr->Type) && - Expr->Type->A.B.Width < CHAR_BITS * SizeOf (ResType)) { - /* The way is: - ** x = bits & bit_mask - ** m = 1 << (bit_width - 1) - ** r = (x ^ m) - m - ** Since we have already masked bits with bit_mask, we may skip the - ** first step. - */ - g_xor (Flags | CF_CONST, 1U << (Expr->Type->A.B.Width - 1U)); - g_dec ((Flags & ~CF_FORCECHAR) | CF_CONST, 1U << (Expr->Type->A.B.Width - 1U)); - } - Done: - /* Get the expression result type */ - Expr->Type = ResType; - /* Value is in primary as an rvalue */ ED_FinalizeRValLoad (Expr); } @@ -643,11 +569,6 @@ static void OpAssignArithmetic (const GenDesc* Gen, ExprDesc* Expr, const char* /* Generate a store instruction */ Store (Expr, 0); - /* Get the expression result type */ - if (IsClassInt (Expr->Type)) { - Expr->Type = IntPromotion (Expr->Type); - } - /* Value is in primary as an rvalue */ ED_FinalizeRValLoad (Expr); } @@ -824,11 +745,6 @@ void OpAddSubAssign (const GenDesc* Gen, ExprDesc *Expr, const char* Op) Internal ("Invalid location in Store(): 0x%04X", ED_GetLoc (Expr)); } - /* Get the expression result type */ - if (IsClassInt (Expr->Type)) { - Expr->Type = IntPromotion (Expr->Type); - } - /* Expression is an rvalue in the primary now */ ED_FinalizeRValLoad (Expr); } diff --git a/src/cc65/expr.c b/src/cc65/expr.c index c45005d65..3b9307a37 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1726,17 +1726,12 @@ static void PostInc (ExprDesc* Expr) } else { - /* Fetch the value and use it (since it's the result of the expression) */ - LoadExpr (CF_NONE, Expr); - /* Defer the increment until after the value of this expression is used */ DeferInc (Expr); - } - } - /* Adjust the type of the expression */ - if (IsClassInt (Expr->Type)) { - Expr->Type = IntPromotion (Expr->Type); + /* Just return */ + return; + } } /* The result is always an expression, no reference */ @@ -1781,17 +1776,12 @@ static void PostDec (ExprDesc* Expr) } else { - /* Fetch the value and save it (since it's the result of the expression) */ - LoadExpr (CF_NONE, Expr); - /* Defer the decrement until after the value of this expression is used */ DeferDec (Expr); - } - } - /* Adjust the type of the expression */ - if (IsClassInt (Expr->Type)) { - Expr->Type = IntPromotion (Expr->Type); + /* Just return */ + return; + } } /* The result is always an expression, no reference */ From 31128d48099f869331b3b7308150b6c599921202 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Wed, 9 Jun 2021 18:43:25 +0800 Subject: [PATCH 2119/2161] Added test cases for result types of certain operations. --- test/val/opsize.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 test/val/opsize.c diff --git a/test/val/opsize.c b/test/val/opsize.c new file mode 100644 index 000000000..20c7f0511 --- /dev/null +++ b/test/val/opsize.c @@ -0,0 +1,33 @@ + +/* Test for result types of certain unary operations */ + +#include <stdio.h> + +signed char x; +struct S { + unsigned char a : 3; + unsigned int b : 3; +} s; + +int main(void) +{ + _Static_assert(sizeof (++x) == sizeof (char), "++x result should not have promoted type"); + _Static_assert(sizeof (--x) == sizeof (char), "--x result should not have promoted type"); + _Static_assert(sizeof (x++) == sizeof (char), "x++ result should not have promoted type"); + _Static_assert(sizeof (x--) == sizeof (char), "x-- result should not have promoted type"); + _Static_assert(sizeof (x=0) == sizeof (char), "x=0 result should not have promoted type"); + + _Static_assert(sizeof (+x) == sizeof (int), "+x result should have promoted type"); + _Static_assert(sizeof (-x) == sizeof (int), "-x result should have promoted type"); + _Static_assert(sizeof (~x) == sizeof (int), "~x result should have promoted type"); + + _Static_assert(sizeof (+s.a) == sizeof (int), "+s.a result should have promoted type"); + _Static_assert(sizeof (-s.a) == sizeof (int), "-s.a result should have promoted type"); + _Static_assert(sizeof (~s.a) == sizeof (int), "~s.a result should have promoted type"); + + _Static_assert(sizeof (+s.b) == sizeof (int), "+s.b result should have promoted type"); + _Static_assert(sizeof (-s.b) == sizeof (int), "-s.b result should have promoted type"); + _Static_assert(sizeof (~s.b) == sizeof (int), "~s.b result should have promoted type"); + + return 0; +} From 24f5bac8994a1a009ae46f5e4db2cdb927bee001 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Thu, 10 Jun 2021 16:07:39 -0500 Subject: [PATCH 2120/2161] Added BEL -> beep() functionality --- libsrc/sym1/read.s | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libsrc/sym1/read.s b/libsrc/sym1/read.s index 7ab88f1e8..fe4990601 100644 --- a/libsrc/sym1/read.s +++ b/libsrc/sym1/read.s @@ -30,10 +30,13 @@ begin: dec ptr2 getch: jsr INTCHR ; Get character using Monitor ROM call jsr OUTCHR ; Echo it - and #$7F ; Clear hi bit and check for '\r' - cmp #$0D - bne putch - lda #$0A ; Replace with '\n' and set count to zero + and #$7F ; Clear hi bit + cmp #$07 ; Check for '\a' + bne chkcr ; ...if BEL character + jsr BEEP ; Make beep sound +chkcr: cmp #$0D ; Check for '\r' + bne putch ; ...if CR character + lda #$0A ; Replace with '\n' putch: ldy #$00 ; Put char into return buffer sta (ptr1),y From f636d4e634fd2553e4b40f0c39b6e845bb49b902 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 14 May 2021 19:12:59 -0400 Subject: [PATCH 2121/2161] Fixed the Creativision library's bios_playsound(). It was disabling interrupts permanently. --- libsrc/creativision/psg.s | 76 ++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/libsrc/creativision/psg.s b/libsrc/creativision/psg.s index 18f4ffe2e..c84f92f43 100644 --- a/libsrc/creativision/psg.s +++ b/libsrc/creativision/psg.s @@ -1,63 +1,67 @@ ; void __fastcall__ psg_outb (unsigned char b); -; void __fastcall__ psg_delay (unsigned char c); -; void __fastcall__ bios_playsound (const void *b, unsigned char c); +; void __fastcall__ psg_delay (unsigned char b); +; void __fastcall__ bios_playsound (void *a, unsigned char b); ; void psg_silence (void); - .export _psg_outb, _psg_silence, _psg_delay - .export _bios_playsound - .import popa + + .export _psg_outb, _psg_silence, _psg_delay + .export _bios_playsound + + .import popax + .include "creativision.inc" -_psg_outb: - ;* Let BIOS output the value - jmp $FE77 +songptr := $00 ; Points to current tune data +volptr := $04 ; Points to current volume table + +_psg_outb: + ;* Let BIOS output the value. + jmp $FE77 + _psg_silence: - - jmp $FE54 + jmp $FE54 _psg_delay: - tay -l1: lda #200 -l2: sbc #1 - bne l2 +l1: lda #200 +l2: sbc #1 + bne l2 - lda #200 -l3: sbc #1 - bne l3 + lda #200 +l3: sbc #1 + bne l3 dey - bne l1 - + bne l1 rts ;* Creativision Sound Player +;* Based on BIOS song player. ;* -;* Based on BIOS sound player. -;* Pass a pointer to a set of note triples, terminated with a tempo byte -;* and the len (max 255) +;* Pass a pointer to a set of note triples, terminated with a tempo byte; +;* and pass the length of the triples and tempo (max 255). +;* +;* Note: tune data must be stored backwards. _bios_playsound: - - pha ; Save Length Byte + php + pha ; Save tune length sei - lda #$D5 ; BIOS volume table low - sta $4 - lda #$FC ; BIOS volume table high - sta $5 + lda #<$FCD5 ; A BIOS volume table + ldx #>$FCD5 + sta volptr + stx volptr+1 - jsr popa ; Get Sound table pointer low - sta $0 - jsr popa ; Get Sound table pointer high - sta $1 + jsr popax ; Get tune array pointer + sta songptr + stx songptr+1 pla - tay ; Put length in Y - dey - php - jmp $FBED ; Let BIOS do it's thing + tay + dey ; Point to tempo byte + jmp $FBED ; Let BIOS do its thing From af3d4581d306f00c4a7f0aba62f9d79962a3ff79 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 30 May 2021 13:30:08 -0400 Subject: [PATCH 2122/2161] Moved Creativision's playsound() into a separate file. It won't waste space in a cartridge if it isn't used. --- asminc/creativision.inc | 47 ++++++++++++++++++--------------- libsrc/creativision/playsound.s | 40 ++++++++++++++++++++++++++++ libsrc/creativision/psg.s | 43 +++--------------------------- 3 files changed, 69 insertions(+), 61 deletions(-) create mode 100644 libsrc/creativision/playsound.s diff --git a/asminc/creativision.inc b/asminc/creativision.inc index 49d55a342..a0259ecce 100644 --- a/asminc/creativision.inc +++ b/asminc/creativision.inc @@ -5,21 +5,21 @@ ;** Screen SCREEN_ROWS = 24 SCREEN_COLS = 32 -SCREEN_PTR = $3A -CURSOR_X = $3C -CURSOR_Y = $3D +SCREEN_PTR := $3A +CURSOR_X := $3C +CURSOR_Y := $3D ;** VDP -VDP_DATA_R = $2000 -VDP_STATUS_R = $2001 -VDP_DATA_W = $3000 -VDP_CONTROL_W = $3001 +VDP_DATA_R := $2000 +VDP_STATUS_R := $2001 +VDP_DATA_W := $3000 +VDP_CONTROL_W := $3001 ;** PIA -PIA0_DATA = $1000 -PIA0_STATUS = $1001 -PIA1_DATA = $1002 -PIA1_STATUS = $1003 +PIA0_DATA := $1000 +PIA0_STATUS := $1001 +PIA1_DATA := $1002 +PIA1_STATUS := $1003 ;** General CH_VLINE = 33 @@ -30,11 +30,11 @@ CH_LLCORNER = 37 CH_LRCORNER = 38 ;** I/O (Zero-page variables) -ZP_KEYBOARD = $10 -ZP_JOY0_DIR = $11 -ZP_JOY1_DIR = $13 -ZP_JOY0_BUTTONS = $16 -ZP_JOY1_BUTTONS = $17 +ZP_KEYBOARD := $10 +ZP_JOY0_DIR := $11 +ZP_JOY1_DIR := $13 +ZP_JOY0_BUTTONS := $16 +ZP_JOY1_BUTTONS := $17 ;** Joystick direction values (ZP_JOY0_DIR/ZP_JOY1_DIR) JOY_N = $49 @@ -54,8 +54,13 @@ JOY_WNW = $4C JOY_NW = $4B JOY_NNW = $4A -;** BIOS -BIOS_IRQ1_ADDR = $FF3F -BIOS_IRQ2_ADDR = $FF52 -BIOS_NMI_RESET_ADDR = $F808 -BIOS_WRITE_VDP_REG = $FE1F +;** BIOS routines +BIOS_NMI_RESET_ADDR := $F808 +BIOS_PLAY_TUNE1 := $FBD6 +BIOS_PLAY_SONG := $FBED +BIOS_PLAY_TUNE2 := $FCE6 +BIOS_WRITE_VDP_REG := $FE1F +BIOS_QUIET_PSG := $FE54 +BIOS_POKE_PSG := $FE77 +BIOS_IRQ1_ADDR := $FF3F +BIOS_IRQ2_ADDR := $FF52 diff --git a/libsrc/creativision/playsound.s b/libsrc/creativision/playsound.s new file mode 100644 index 000000000..55c7a3fed --- /dev/null +++ b/libsrc/creativision/playsound.s @@ -0,0 +1,40 @@ +; void __fastcall__ bios_playsound (void *a, unsigned char b); + + + .export _bios_playsound + + .import popax + + .include "creativision.inc" + + +songptr := $00 ; Points to current tune data +volptr := $04 ; Points to current volume table + + +;* Creativision Sound Player +;* Based on BIOS song player. +;* +;* Pass a pointer to a set of note triples, terminated with a tempo byte; +;* and pass the length of the triples and tempo (max 255). +;* +;* Note: tune data must be stored backwards. + +_bios_playsound: + php + pha ; Save tune length + sei + + lda #<$FCD5 ; BIOS decreasing-volume table + ldx #>$FCD5 + sta volptr + stx volptr+1 + + jsr popax ; Get tune array pointer + sta songptr + stx songptr+1 + + pla + tay + dey ; Point to tempo byte + jmp BIOS_PLAY_SONG ; Let BIOS do its thing diff --git a/libsrc/creativision/psg.s b/libsrc/creativision/psg.s index c84f92f43..ec878af31 100644 --- a/libsrc/creativision/psg.s +++ b/libsrc/creativision/psg.s @@ -1,27 +1,18 @@ ; void __fastcall__ psg_outb (unsigned char b); ; void __fastcall__ psg_delay (unsigned char b); -; void __fastcall__ bios_playsound (void *a, unsigned char b); ; void psg_silence (void); .export _psg_outb, _psg_silence, _psg_delay - .export _bios_playsound - - .import popax .include "creativision.inc" -songptr := $00 ; Points to current tune data -volptr := $04 ; Points to current volume table - -_psg_outb: - ;* Let BIOS output the value. - jmp $FE77 +;* Let BIOS output the value. +_psg_outb := BIOS_POKE_PSG -_psg_silence: - jmp $FE54 +_psg_silence := BIOS_QUIET_PSG _psg_delay: @@ -37,31 +28,3 @@ l3: sbc #1 dey bne l1 rts - - -;* Creativision Sound Player -;* Based on BIOS song player. -;* -;* Pass a pointer to a set of note triples, terminated with a tempo byte; -;* and pass the length of the triples and tempo (max 255). -;* -;* Note: tune data must be stored backwards. - -_bios_playsound: - php - pha ; Save tune length - sei - - lda #<$FCD5 ; A BIOS volume table - ldx #>$FCD5 - sta volptr - stx volptr+1 - - jsr popax ; Get tune array pointer - sta songptr - stx songptr+1 - - pla - tay - dey ; Point to tempo byte - jmp $FBED ; Let BIOS do its thing From 14d05c61b67ab1a856f6b1202a2706e08e1eac6e Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Fri, 4 Jun 2021 07:30:26 -0400 Subject: [PATCH 2123/2161] Made Creativision's joystick driver more efficient. --- libsrc/creativision/joy/creativision-stdjoy.s | 100 ++++++++---------- 1 file changed, 46 insertions(+), 54 deletions(-) diff --git a/libsrc/creativision/joy/creativision-stdjoy.s b/libsrc/creativision/joy/creativision-stdjoy.s index 5cf46c39f..73b0c249f 100644 --- a/libsrc/creativision/joy/creativision-stdjoy.s +++ b/libsrc/creativision/joy/creativision-stdjoy.s @@ -1,11 +1,11 @@ ; ; Standard joystick driver for the Creativision. ; -; Christian Groessler, 2017-03-08 +; 2017-03-08, Christian Groessler +; 2021-06-01, Greg King ; .include "zeropage.inc" - .include "joy-kernel.inc" .include "joy-error.inc" .include "creativision.inc" @@ -13,10 +13,12 @@ .macpack module +buttons := tmp2 + ; ------------------------------------------------------------------------ ; Header. Includes jump table - module_header _creativisionstd_joy + module_header _creativisionstd_joy ; Driver signature @@ -39,16 +41,14 @@ JOY_COUNT = 2 ; Number of joysticks we support -; Symbolic names for joystick masks (similar names like the defines in joystick.h, but not related to them) +; Symbolic names for joystick masks (similar names to the macros in joystick.h, +; with the same values as the masks in creativision.h) JOY_UP = $10 JOY_DOWN = $04 JOY_LEFT = $20 JOY_RIGHT = $08 -; ------------------------------------------------------------------------ -; Code - .code ; ------------------------------------------------------------------------ @@ -59,7 +59,7 @@ JOY_RIGHT = $08 ; INSTALL: lda #JOY_ERR_OK - ldx #0 + ldx #>$0000 ; rts ; Fall through ; ------------------------------------------------------------------------ @@ -82,14 +82,14 @@ COUNT: lda #<JOY_COUNT ; READ: Read a particular joystick passed in A. ; -READJOY: and #1 ; fix joystick number - bne READJOY_1 ; read right joystick +READJOY: lsr a ; Get joystick number + bcs READJOY_1 ; Read right joystick ; Read left joystick ldx ZP_JOY0_DIR lda ZP_JOY0_BUTTONS - jmp convert ; convert joystick state to cc65 values + bcc convert ; Convert joystick state to cc65 values ; Read right joystick @@ -97,11 +97,11 @@ READJOY_1: ldx ZP_JOY1_DIR lda ZP_JOY1_BUTTONS lsr a lsr a - ;jmp convert ; convert joystick state to cc65 values - ; fall thru... + ;jmp convert ; Convert joystick state to cc65 values + ; Fall thru... ; ------------------------------------------------------------------------ -; convert: make runtime lib compatible values +; convert: make runtime lib-compatible values ; inputs: ; A - buttons ; X - direction @@ -111,24 +111,24 @@ convert: ; ------ ; buttons: -; Port values are for the left hand joystick (right hand joystick +; Port values are for the left-hand joystick (right-hand joystick ; values were shifted to the right to be identical). ; Why are there two bits indicating a pressed trigger? ; According to the "Second book of programs for the Dick Smith Wizard" -; (pg. 88ff), the left hand button gives the value of -; %00010001 and the right hand button gives %00100010 +; (pg. 88ff), the left-hand button gives the value of +; %00010001 and the right-hand button gives %00100010 ; Why two bits? Can there be cases that just one of those bits is set? -; Until these questions have been answered, we only use the lower two -; bits and ignore the upper ones... +; Until those questions have been answered, we only use the lower two +; bits, and ignore the upper ones. - and #%00000011 ; button status came in in A, strip high bits - sta retval ; initialize 'retval' with button status + and #%00000011 ; Button status came in A, strip high bits + sta buttons ; ------ ; direction: -; CV has a 16-direction joystick +; CV has a 16-direction joystick. ; -; port values: (compass points) +; Port values: (compass points) ; N - $49 - %01001001 ; NNE - $48 - %01001000 ; NE - $47 - %01000111 @@ -147,55 +147,51 @@ convert: ; NNW - $4A - %01001010 ; center - $00 - %00000000 ; -; mapping to cc65 definitions (4-direction joystick with 8 possible directions thru combinations) +; Mapping to cc65 definitions (4-direction joystick with 8 possible directions thru combinations): ; N, E, S, W -> JOY_UP, JOY_RIGHT, JOY_DOWN, JOY_LEFT ; NE, SE, SW, NW -> (JOY_UP | JOY_RIGHT), (JOY_DOWN | JOY_RIGHT), (JOY_DOWN | JOY_LEFT), (JOY_UP | JOY_LEFT) ; NNE, ENE, ESE, SSE, SSW, WSW, WNW, NNW: -; toggle between straight and diagonal direction for every call, e.g. +; toggle between the straight and diagonal directions for each call, e.g., ; NNE: ; call to READJOY: return JOY_UP | JOY_RIGHT ; call to READJOY: return JOY_UP ; call to READJOY: return JOY_UP | JOY_RIGHT ; call to READJOY: return JOY_UP ; call to READJOY: return JOY_UP | JOY_RIGHT -; etc... +; etc. - txa ; move direction status into A - beq done ; center position (no bits are set), nothing to do + txa ; Move direction status into A + beq done ; Center position (no bits are set), nothing to do - and #$0F ; get rid of the "$40" bit - bit bit0 ; is it a "three letter" direction (NNE, ENE, etc.)? - beq special ; yes (bit #0 is zero) + and #$0F ; Get rid of the "$40" bit + lsr a ; Is it "three-letter" direction (NNE, ENE, etc.)? + tax ; Create index into table + bcc special ; Yes (bit #0 was zero) - lsr a ; create index into table - tax lda dirtable,x -done: ora retval ; include "button" bits - ldx #0 +done: ora buttons ; Include button bits + ldx #>$0000 rts ; NNE, ENE, ESE, SSE, SSW, WSW, WNW, NNW -special: lsr a - tax - - lda toggler ; toggle the toggler +special: lda toggle ; Toggle the flag eor #$01 - sta toggler - bne spec_1 ; toggler is 1, use spectable_1 entry + sta toggle + bne spec_1 ; Flag is 1, use spectable_1 entry - lda spectable_0,x ; toggler is 0, use spectable_0 entry - bne done ; jump always + lda spectable_0,x + bne done ; Jump always spec_1: lda spectable_1,x - bne done ; jump always + bne done ; Jump always ; ------------------------------------------------------------------------ ; .rodata - ; a mapping table of "port values" to "cc65 values" - ; port value had been shifted one bit to the right (range 0..7) + ; A mapping table of "port values" to "cc65 values" + ; Port value had been shifted one bit to the right (range 0..7) dirtable: .byte JOY_DOWN ; S .byte JOY_DOWN | JOY_RIGHT ; SE .byte JOY_RIGHT ; E @@ -205,12 +201,12 @@ dirtable: .byte JOY_DOWN ; S .byte JOY_LEFT ; W .byte JOY_DOWN | JOY_LEFT ; SW - ; two "special" mapping tables for three-letter directions (NNE, etc.) + ; Two "special" mapping tables for three-letter directions (NNE, etc.) spectable_0: .byte JOY_DOWN ; SSW .byte JOY_DOWN ; SSE .byte JOY_RIGHT ; ESE .byte JOY_RIGHT ; ENE - .byte JOY_RIGHT ; NNE + .byte JOY_UP ; NNE .byte JOY_UP ; NNW .byte JOY_LEFT ; WNW .byte JOY_LEFT ; WSW @@ -224,14 +220,10 @@ spectable_1: .byte JOY_DOWN | JOY_LEFT ; SSW .byte JOY_UP | JOY_LEFT ; WNW .byte JOY_DOWN | JOY_LEFT ; WSW -; ------------------------------------------------------------------------ -; -bit0: .byte $01 - ; ------------------------------------------------------------------------ ; .bss -toggler: .res 1 -retval: .res 1 + +toggle: .res 1 .end From 9e6c1d1303b2efae34712f51a1a9a915fb3d6856 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Fri, 11 Jun 2021 19:55:13 -0500 Subject: [PATCH 2124/2161] tapeio and symNotepad updates --- libsrc/sym1/tapeio.s | 8 ++++---- targettest/sym1/symNotepad.c | 11 ++--------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/libsrc/sym1/tapeio.s b/libsrc/sym1/tapeio.s index 19eeb2444..13579dca7 100644 --- a/libsrc/sym1/tapeio.s +++ b/libsrc/sym1/tapeio.s @@ -1,13 +1,13 @@ ; ; Wayne Parham (wayne@parhamdata.com) ; -; int loadt (int id); -; int dumpt (int id, int start_addr, int end_addr); +; int __fastcall__ loadt (unsigned char id); +; int __fastcall__ dumpt (unsigned char id, void* start_addr, void* end_addr); ; .include "sym1.inc" -.import popax, return0, return1 +.import popa, popax, return0, return1 .export _loadt, _dumpt @@ -33,7 +33,7 @@ error: jmp return1 ; or 1 if not jsr popax sta P2L ; Start address stx P2H - jsr popax + jsr popa sta P1L ; Tape Record ID ldx #$00 stx P1H diff --git a/targettest/sym1/symNotepad.c b/targettest/sym1/symNotepad.c index 683cea63f..c47d1ac98 100644 --- a/targettest/sym1/symNotepad.c +++ b/targettest/sym1/symNotepad.c @@ -110,7 +110,7 @@ void main(void) { l++; tapio[l] = 0x00; puts( "Saving to tape." ); - error = dumpt( 'N', (int) tapio, (int) tapio+p ); + error = dumpt( 'N', tapio, tapio+p ); if( error ) { puts( "\nTape error." ); } @@ -124,9 +124,6 @@ void main(void) { puts( "===================== Sym-1 Notepad ====================\n" ); for( l = 0; l <= p; l++ ) { putchar( buffer[l] ); - if( buffer[l] == '\r' ) { - putchar( '\n' ); - } } } else if( c == 0x0C ) { // Load @@ -155,9 +152,6 @@ void main(void) { for( l = 0; l <= p; l++ ) { putchar( buffer[l] ); - if( buffer[l] == '\r' ) { - putchar( '\n' ); - } } } } @@ -180,11 +174,10 @@ void main(void) { puts( "Buffer full." ); } else { - if( c == '\r' ) { + if( c == '\n' ) { putchar( '\n' ); } buffer[p] = c; - putchar( c ); } p++; } From c9bb1483ac57030981ee77d2e851c3fabf05697d Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Sat, 12 Jun 2021 06:17:03 -0500 Subject: [PATCH 2125/2161] Add BEL->beep functionality --- libsrc/sym1/write.s | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/libsrc/sym1/write.s b/libsrc/sym1/write.s index f7eb4c55e..314a7760b 100644 --- a/libsrc/sym1/write.s +++ b/libsrc/sym1/write.s @@ -7,7 +7,7 @@ .include "sym1.inc" .import popax, popptr1 -.importzp ptr1, ptr2, ptr3, tmp1 +.importzp ptr1, ptr2, ptr3 .export _write @@ -28,12 +28,15 @@ begin: dec ptr2 dec ptr2+1 beq done -outch : ldy #0 +outch: ldy #0 lda (ptr1),y jsr OUTCHR ; Send character using Monitor call - cmp #$0A - bne next - lda #$0D ; If it is LF, add CR + cmp #$07 ; Check for '\a' + bne chklf ; ...if BEL character + jsr BEEP ; Make beep sound +chklf: cmp #$0A ; Check for 'n' + bne next ; ...if LF character + lda #$0D ; Add a carriage return jsr OUTCHR next: inc ptr1 From faf6266cded2d45d6020fd9a27e622fc17b4e47e Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Sat, 12 Jun 2021 06:28:53 -0500 Subject: [PATCH 2126/2161] typo in comment --- libsrc/sym1/read.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/sym1/read.s b/libsrc/sym1/read.s index fe4990601..177472270 100644 --- a/libsrc/sym1/read.s +++ b/libsrc/sym1/read.s @@ -30,7 +30,7 @@ begin: dec ptr2 getch: jsr INTCHR ; Get character using Monitor ROM call jsr OUTCHR ; Echo it - and #$7F ; Clear hi bit + and #$7F ; Clear top bit cmp #$07 ; Check for '\a' bne chkcr ; ...if BEL character jsr BEEP ; Make beep sound From 4db50e8e931e10951436310e7837c2bc5de66b5a Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Sun, 13 Jun 2021 11:29:30 -0500 Subject: [PATCH 2127/2161] Documentation update: Mention where to find sym1 sample programs --- doc/sym1.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/sym1.sgml b/doc/sym1.sgml index d2e5f09fd..c32fcf2cb 100644 --- a/doc/sym1.sgml +++ b/doc/sym1.sgml @@ -94,7 +94,7 @@ To be more specific, this limitation means that you cannot use any of the follow <sect>Other hints<p> <sect1>sym1.h<p> -This header exposes Sym-specific I/O functions that are useful for reading and writing its ports and front panel. See the sym1.h include file for a list of the functions available. +This header exposes Sym-specific I/O functions that are useful for reading and writing its ports and front panel. See the <tt/sym1.h/ include file for a list of the functions available. <sect2>Limited memory applications<p> @@ -102,7 +102,7 @@ As stated earlier, there are config files for 4KB and 32KB systems. If you have <sect3>Sample programs<p> -All the samples will run on the "stock" 4KB Sym-1, except for symIO and symNotepad, which require 32KB. Information on building and running the sample programs are in the targettest/sym1 directory. +All the samples will run on the "stock" 4KB Sym-1, except for symIO and symNotepad, which require 32KB. These sample programs can be found in the samples and targettest/sym1 directories: <itemize> <item>helloworld is the traditional "Hello World!" program, using printf().</item> From fcda94f25895ed792c11bc254052abed7f964617 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Sun, 13 Jun 2021 20:36:05 -0400 Subject: [PATCH 2128/2161] Made a slight improvement in the ld65 expression evaluator. --- src/ld65/expr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ld65/expr.c b/src/ld65/expr.c index 7a2f37d4a..ff210e315 100644 --- a/src/ld65/expr.c +++ b/src/ld65/expr.c @@ -321,20 +321,18 @@ long GetExprVal (ExprNode* Expr) return GetExprVal (Expr->Left) * GetExprVal (Expr->Right); case EXPR_DIV: - Left = GetExprVal (Expr->Left); Right = GetExprVal (Expr->Right); if (Right == 0) { Error ("Division by zero"); } - return Left / Right; + return GetExprVal (Expr->Left) / Right; case EXPR_MOD: - Left = GetExprVal (Expr->Left); Right = GetExprVal (Expr->Right); if (Right == 0) { Error ("Modulo operation with zero"); } - return Left % Right; + return GetExprVal (Expr->Left) % Right; case EXPR_OR: return GetExprVal (Expr->Left) | GetExprVal (Expr->Right); From 11d81b1f436f4f1fc4e5f6e0b952b2df500e76c4 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Tue, 15 Jun 2021 16:39:28 -0500 Subject: [PATCH 2129/2161] Stylistic changes --- cfg/sym1-32k.cfg | 54 ++++++++++++++++++------------------ cfg/sym1-4k.cfg | 54 ++++++++++++++++++------------------ cfg/sym1.cfg | 54 ++++++++++++++++++------------------ doc/sym1.sgml | 7 ++--- include/sym1.h | 50 +++++++++++++++++++++++++++------ samples/Makefile | 2 +- samples/helloworld.c | 8 ------ targettest/sym1/Makefile | 14 ++++------ targettest/sym1/symDisplay.c | 23 ++++++++------- targettest/sym1/symIO.c | 36 ++++++++++++------------ targettest/sym1/symNotepad.c | 23 +++++++-------- 11 files changed, 170 insertions(+), 155 deletions(-) delete mode 100644 samples/helloworld.c diff --git a/cfg/sym1-32k.cfg b/cfg/sym1-32k.cfg index ee3bc9d63..ad0d760f3 100644 --- a/cfg/sym1-32k.cfg +++ b/cfg/sym1-32k.cfg @@ -6,41 +6,41 @@ FEATURES { STARTADDRESS: default = $0200; - CONDES: segment = STARTUP, - type = constructor, - label = __CONSTRUCTOR_TABLE__, - count = __CONSTRUCTOR_COUNT__; - CONDES: segment = STARTUP, - type = destructor, - label = __DESTRUCTOR_TABLE__, - count = __DESTRUCTOR_COUNT__; + 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 = $0200; # 512 byte program stack - __STARTADDRESS__: type = export, value = %S; + __STACKSIZE__: type = weak, value = $0200; # 512 byte program stack + __STARTADDRESS__: type = export, value = %S; } MEMORY { - ZP: file = %O, define = yes, start = $0000, size = $00F7; - CPUSTACK: file = "", define = yes, start = $0100, size = $0100; - RAM: file = %O, define = yes, start = %S, size = $8000 - %S - __STACKSIZE__; - MONROM: file = "", define = yes, start = $8000, size = $1000; - EXT: file = "", define = yes, start = $9000, size = $1000; - IO: file = "", define = yes, start = $A000, size = $1000; - RAE1: file = "", define = yes, start = $B000, size = $1000; - BASROM: file = "", define = yes, start = $C000, size = $1000; - RAE2: file = "", define = yes, start = $E000, size = $1000; - TOP: file = "", define = yes, start = $F000, size = $1000; + ZP: file = %O, define = yes, start = $0000, size = $00F7; + CPUSTACK: file = "", define = yes, start = $0100, size = $0100; + RAM: file = %O, define = yes, start = %S, size = $8000 - %S - __STACKSIZE__; + MONROM: file = "", define = yes, start = $8000, size = $1000; + EXT: file = "", define = yes, start = $9000, size = $1000; + IO: file = "", define = yes, start = $A000, size = $1000; + RAE1: file = "", define = yes, start = $B000, size = $1000; + BASROM: file = "", define = yes, start = $C000, size = $1000; + RAE2: 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; + 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/sym1-4k.cfg b/cfg/sym1-4k.cfg index 8570b6077..32d3cbb3a 100644 --- a/cfg/sym1-4k.cfg +++ b/cfg/sym1-4k.cfg @@ -6,41 +6,41 @@ FEATURES { STARTADDRESS: default = $0200; - CONDES: segment = STARTUP, - type = constructor, - label = __CONSTRUCTOR_TABLE__, - count = __CONSTRUCTOR_COUNT__; - CONDES: segment = STARTUP, - type = destructor, - label = __DESTRUCTOR_TABLE__, - count = __DESTRUCTOR_COUNT__; + 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; + __STACKSIZE__: type = weak, value = $0080; # 128 byte program stack + __STARTADDRESS__: type = export, value = %S; } MEMORY { - ZP: file = %O, define = yes, start = $0000, size = $00F7; - CPUSTACK: file = "", define = yes, start = $0100, size = $0100; - RAM: file = %O, define = yes, start = %S, size = $1000 - %S - __STACKSIZE__; - MONROM: file = "", define = yes, start = $8000, size = $1000; - EXT: file = "", define = yes, start = $9000, size = $1000; - IO: file = "", define = yes, start = $A000, size = $1000; - RAE1: file = "", define = yes, start = $B000, size = $1000; - BASROM: file = "", define = yes, start = $C000, size = $1000; - RAE2: file = "", define = yes, start = $E000, size = $1000; - TOP: file = "", define = yes, start = $F000, size = $1000; + ZP: file = %O, define = yes, start = $0000, size = $00F7; + CPUSTACK: file = "", define = yes, start = $0100, size = $0100; + RAM: file = %O, define = yes, start = %S, size = $1000 - %S - __STACKSIZE__; + MONROM: file = "", define = yes, start = $8000, size = $1000; + EXT: file = "", define = yes, start = $9000, size = $1000; + IO: file = "", define = yes, start = $A000, size = $1000; + RAE1: file = "", define = yes, start = $B000, size = $1000; + BASROM: file = "", define = yes, start = $C000, size = $1000; + RAE2: 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; + 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/sym1.cfg b/cfg/sym1.cfg index 8570b6077..32d3cbb3a 100644 --- a/cfg/sym1.cfg +++ b/cfg/sym1.cfg @@ -6,41 +6,41 @@ FEATURES { STARTADDRESS: default = $0200; - CONDES: segment = STARTUP, - type = constructor, - label = __CONSTRUCTOR_TABLE__, - count = __CONSTRUCTOR_COUNT__; - CONDES: segment = STARTUP, - type = destructor, - label = __DESTRUCTOR_TABLE__, - count = __DESTRUCTOR_COUNT__; + 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; + __STACKSIZE__: type = weak, value = $0080; # 128 byte program stack + __STARTADDRESS__: type = export, value = %S; } MEMORY { - ZP: file = %O, define = yes, start = $0000, size = $00F7; - CPUSTACK: file = "", define = yes, start = $0100, size = $0100; - RAM: file = %O, define = yes, start = %S, size = $1000 - %S - __STACKSIZE__; - MONROM: file = "", define = yes, start = $8000, size = $1000; - EXT: file = "", define = yes, start = $9000, size = $1000; - IO: file = "", define = yes, start = $A000, size = $1000; - RAE1: file = "", define = yes, start = $B000, size = $1000; - BASROM: file = "", define = yes, start = $C000, size = $1000; - RAE2: file = "", define = yes, start = $E000, size = $1000; - TOP: file = "", define = yes, start = $F000, size = $1000; + ZP: file = %O, define = yes, start = $0000, size = $00F7; + CPUSTACK: file = "", define = yes, start = $0100, size = $0100; + RAM: file = %O, define = yes, start = %S, size = $1000 - %S - __STACKSIZE__; + MONROM: file = "", define = yes, start = $8000, size = $1000; + EXT: file = "", define = yes, start = $9000, size = $1000; + IO: file = "", define = yes, start = $A000, size = $1000; + RAE1: file = "", define = yes, start = $B000, size = $1000; + BASROM: file = "", define = yes, start = $C000, size = $1000; + RAE2: 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; + 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/doc/sym1.sgml b/doc/sym1.sgml index c32fcf2cb..75c44b422 100644 --- a/doc/sym1.sgml +++ b/doc/sym1.sgml @@ -21,7 +21,7 @@ Please note that Sym-1 specific functions are just mentioned here, they are desc <sect>Binary format<p> -The output format generated by the linker for the Sym-1 target is a raw binary BIN file, which is essentially a memory image. You can convert this to a HEX file using BIN2HEX, which is a popular open-source conversion utility program. A HEX file has ASCII representations of the hexadecimal byte values of the machine-language program. +The output format generated by the linker for the Sym-1 target is a raw binary BIN file, which is essentially a memory image. You can convert this to a HEX file using BIN2HEX, which is a popular open-source conversion utility program. A HEX file has ASCII representations of the hexadecimal byte values of the machine-language program. So the HEX file can be transferred to the Sym-1 using the RS-232 terminal port, just as if the machine-code was entered by hand. Enter 'm 200' in the monitor and start the HEX file transfer. <p> @@ -98,14 +98,13 @@ This header exposes Sym-specific I/O functions that are useful for reading and w <sect2>Limited memory applications<p> -As stated earlier, there are config files for 4KB and 32KB systems. If you have 32KB RAM, then you will probably want to use the sym1-32k configuration, but if not - if you are using the sym1-4k configuration - then you may want to use functions like getchar, putchar, gets and puts rather than printf. Printf requires about 1KB because it needs to know how to process all the format specifiers. +As stated earlier, there are config files for 4KB and 32KB systems. If you have 32KB RAM, then you will probably want to use the sym1-32k configuration, but if not - if you are using the sym1-4k configuration - then you may want to use functions like getchar, putchar, gets and puts rather than functions like scanf and printf. Printf, for example, requires about 1KB because it needs to know how to process all the format specifiers. <sect3>Sample programs<p> -All the samples will run on the "stock" 4KB Sym-1, except for symIO and symNotepad, which require 32KB. These sample programs can be found in the samples and targettest/sym1 directories: +All the samples will run on the "stock" 4KB Sym-1, except for symIO and symNotepad, which require 32KB. These sample programs can be found in the targettest/sym1 directory: <itemize> -<item>helloworld is the traditional "Hello World!" program, using printf().</item> <item>symHello prints "Hello World!" and then inputs characters, which are echoed on the screen. It also makes a "beep" sound.</item> <item>symTiny does the same as symhello, but does it with puts() rather than printf() to show the difference in compiled binary size.</item> <item>symDisplay allows entry of a message, which is then displayed by scrolling it across the front panel display.</item> diff --git a/include/sym1.h b/include/sym1.h index bedaa7913..e0eb81ecf 100644 --- a/include/sym1.h +++ b/include/sym1.h @@ -1,8 +1,33 @@ -// sym1.h -// -// I/O primitives for Sym-1 -// -// Wayne Parham +/*****************************************************************************/ +/* */ +/* sym1.h */ +/* */ +/* Sym-1 system-specific definitions */ +/* */ +/* */ +/* */ +/* (C) 2020 Wayne Parham */ +/* EMail: wayne@parhamdata.com */ +/* */ +/* */ +/* 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. */ +/* */ +/*****************************************************************************/ @@ -122,10 +147,17 @@ struct _display { -void beep (void); // Beep sound -void fdisp (void); // Flash display -int __fastcall__ loadt (unsigned char); // Read from tape (id) -int __fastcall__ dumpt (unsigned char, const void*, const void*); // Write to tape (id, start_addr, end_addr) +void beep (void); +/* Beep sound. */ + +void fdisp (void); +/* Flash display */ + +int __fastcall__ loadt (unsigned char); +/* Read from tape */ + +int __fastcall__ dumpt (unsigned char, const void*, const void*); +/* Write to tape */ diff --git a/samples/Makefile b/samples/Makefile index 32a0086d8..1679b7d96 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -312,7 +312,7 @@ EXELIST_supervision = \ supervisionhello EXELIST_sym1 = \ - helloworld + notavailable EXELIST_telestrat = \ ascii \ diff --git a/samples/helloworld.c b/samples/helloworld.c deleted file mode 100644 index b4e1ee6a3..000000000 --- a/samples/helloworld.c +++ /dev/null @@ -1,8 +0,0 @@ -// Traditional "Hello World" program - -#include <stdio.h> - -int main(void) { - printf("Hello, World!\n"); - return 0; -} diff --git a/targettest/sym1/Makefile b/targettest/sym1/Makefile index c8508f1e0..23742f6d1 100644 --- a/targettest/sym1/Makefile +++ b/targettest/sym1/Makefile @@ -1,7 +1,3 @@ -# Run 'make SYS=<target>'; or, set a SYS env. -# var. to build for another target system. -SYS ?= sym1 - # Just the usual way to find out if we're # using cmd.exe to execute make rules. ifneq ($(shell echo),) @@ -33,19 +29,19 @@ endif all: symHello.bin symTiny.bin symDisplay.bin symIO.bin symNotepad.bin symHello.bin: symHello.c - $(CL) -t $(SYS) -C sym1-4k.cfg -O -o symHello.bin symHello.c + $(CL) -t sym1 -O -o symHello.bin symHello.c symTiny.bin: symTiny.c - $(CL) -t $(SYS) -C sym1-4k.cfg -O -o symTiny.bin symTiny.c + $(CL) -t sym1 -O -o symTiny.bin symTiny.c symDisplay.bin: symDisplay.c - $(CL) -t $(SYS) -C sym1-4k.cfg -O -o symDisplay.bin symDisplay.c + $(CL) -t sym1 -O -o symDisplay.bin symDisplay.c symIO.bin: symIO.c - $(CL) -t $(SYS) -C sym1-32k.cfg -O -o symIO.bin symIO.c + $(CL) -t sym1 -C sym1-32k.cfg -O -o symIO.bin symIO.c symNotepad.bin: symNotepad.c - $(CL) -t $(SYS) -C sym1-32k.cfg -O -o symNotepad.bin symNotepad.c + $(CL) -t sym1 -C sym1-32k.cfg -O -o symNotepad.bin symNotepad.c clean: @$(DEL) symHello.bin 2>$(NULLDEV) diff --git a/targettest/sym1/symDisplay.c b/targettest/sym1/symDisplay.c index e97518c79..ff9ff90b2 100644 --- a/targettest/sym1/symDisplay.c +++ b/targettest/sym1/symDisplay.c @@ -10,18 +10,18 @@ #include <sym1.h> void main (void) { - int delay = 10; - int flashes = 255; + int delay = 10; + int flashes = 255; int displayable = 1; - int e = 0; - int r = 0; - int d = 0; - int i = 0; - int l = 0; - int t = 0; - int z = 0; - char c = 0x00; - char buffer[41] = { 0x00 }; + int e = 0; + int r = 0; + int d = 0; + int i = 0; + int l = 0; + int t = 0; + int z = 0; + char c = 0x00; + char buffer[41] = { 0x00 }; puts( "\nType a message (40 chars max) and press ENTER, please:\n" ); @@ -351,6 +351,5 @@ void main (void) { } } } - puts( "\n\nEnjoy your day!\n\n" ); } diff --git a/targettest/sym1/symIO.c b/targettest/sym1/symIO.c index 99b020be2..0b1dee40b 100644 --- a/targettest/sym1/symIO.c +++ b/targettest/sym1/symIO.c @@ -12,24 +12,24 @@ #include <string.h> void main(void) { - unsigned char ddr1a = 0x00; - unsigned char ior1a = 0x00; - unsigned char ddr1b = 0x00; - unsigned char ior1b = 0x00; - unsigned char ddr2a = 0x00; - unsigned char ior2a = 0x00; - unsigned char ddr2b = 0x00; - unsigned char ior2b = 0x00; - unsigned char ddr3a = 0x00; - unsigned char ior3a = 0x00; - unsigned char ddr3b = 0x00; - unsigned char ior3b = 0x00; - unsigned char val = 0x00; - int going = 0x01; - int instr = 0x01; - int l = 0x00; - char* vp = 0x00; - char cmd[20] = { 0x00 }; + unsigned char ddr1a = 0x00; + unsigned char ior1a = 0x00; + unsigned char ddr1b = 0x00; + unsigned char ior1b = 0x00; + unsigned char ddr2a = 0x00; + unsigned char ior2a = 0x00; + unsigned char ddr2b = 0x00; + unsigned char ior2b = 0x00; + unsigned char ddr3a = 0x00; + unsigned char ior3a = 0x00; + unsigned char ddr3b = 0x00; + unsigned char ior3b = 0x00; + unsigned char val = 0x00; + int going = 0x01; + int instr = 0x01; + int l = 0x00; + char* vp = 0x00; + char cmd[20] = { 0x00 }; while( going ) { diff --git a/targettest/sym1/symNotepad.c b/targettest/sym1/symNotepad.c index c47d1ac98..f2c85756c 100644 --- a/targettest/sym1/symNotepad.c +++ b/targettest/sym1/symNotepad.c @@ -17,18 +17,18 @@ #include <stdlib.h> #include <string.h> -#define TAPIO_ADDRESS 0xE000 -#define TAPIO_MAX_SIZE 0x0FFF +#define TAPIO_ADDRESS 0xE000 +#define TAPIO_MAX_SIZE 0x0FFF void main(void) { - char c = 0x00; - int l = 0x00; - int p = 0x00; - int error = 0x00; - int running = 0x01; - int writing = 0x01; - int instruction_needed = 0x01; - int heap_size = 0x00; + cha c = 0x00; + int l = 0x00; + int p = 0x00; + int error = 0x00; + int running = 0x01; + int writing = 0x01; + int instruction_needed = 0x01; + int heap_size = 0x00; char* tapio = (char*) TAPIO_ADDRESS; char* buffer; @@ -183,9 +183,6 @@ void main(void) { } } } - free( buffer ); - puts( "\nEnjoy your day!\n" ); } - From f98e5f4feb28f6e786ca48551fdad50d1e1f6a7a Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Tue, 15 Jun 2021 17:14:27 -0500 Subject: [PATCH 2130/2161] Stylistic changes --- doc/sym1.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sym1.sgml b/doc/sym1.sgml index 75c44b422..60eb1c020 100644 --- a/doc/sym1.sgml +++ b/doc/sym1.sgml @@ -106,7 +106,7 @@ All the samples will run on the "stock" 4KB Sym-1, except for symIO an <itemize> <item>symHello prints "Hello World!" and then inputs characters, which are echoed on the screen. It also makes a "beep" sound.</item> -<item>symTiny does the same as symhello, but does it with puts() rather than printf() to show the difference in compiled binary size.</item> +<item>symTiny does the same as symHello, but does it with puts() rather than printf() to show the difference in compiled binary size.</item> <item>symDisplay allows entry of a message, which is then displayed by scrolling it across the front panel display.</item> <item>symIO allows access to the Sym-1 digital I/O ports.</item> <item>symNotepad is a simple text entry/retrieval program that uses tape storage.</item> From f1f700799b6f175e66f4258c634b205a71519cf7 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Wed, 16 Jun 2021 07:35:18 -0500 Subject: [PATCH 2131/2161] All samples use 'int main' and 'return int' --- targettest/sym1/symDisplay.c | 5 ++++- targettest/sym1/symHello.c | 4 +++- targettest/sym1/symIO.c | 6 +++++- targettest/sym1/symNotepad.c | 8 ++++++-- targettest/sym1/symTiny.c | 4 +++- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/targettest/sym1/symDisplay.c b/targettest/sym1/symDisplay.c index ff9ff90b2..9176b5234 100644 --- a/targettest/sym1/symDisplay.c +++ b/targettest/sym1/symDisplay.c @@ -9,7 +9,7 @@ #include <stdio.h> #include <sym1.h> -void main (void) { +int main (void) { int delay = 10; int flashes = 255; int displayable = 1; @@ -351,5 +351,8 @@ void main (void) { } } } + puts( "\n\nEnjoy your day!\n\n" ); + + return 0; } diff --git a/targettest/sym1/symHello.c b/targettest/sym1/symHello.c index 543e00cb2..a37bc1994 100644 --- a/targettest/sym1/symHello.c +++ b/targettest/sym1/symHello.c @@ -9,7 +9,7 @@ #include <stdio.h> #include <sym1.h> -void main(void) { +int main(void) { char c = 0x00; int d = 0x00; int l = 0x00; @@ -34,4 +34,6 @@ void main(void) { for( d = 0; d < 10 ; d++ ) { } } + + return 0; } diff --git a/targettest/sym1/symIO.c b/targettest/sym1/symIO.c index 0b1dee40b..0659b71f3 100644 --- a/targettest/sym1/symIO.c +++ b/targettest/sym1/symIO.c @@ -11,7 +11,7 @@ #include <stdlib.h> #include <string.h> -void main(void) { +int main(void) { unsigned char ddr1a = 0x00; unsigned char ior1a = 0x00; unsigned char ddr1b = 0x00; @@ -165,4 +165,8 @@ void main(void) { } } } + + puts( "\n\nEnjoy your day!\n\n" ); + + return 0; } diff --git a/targettest/sym1/symNotepad.c b/targettest/sym1/symNotepad.c index f2c85756c..f2e923bb5 100644 --- a/targettest/sym1/symNotepad.c +++ b/targettest/sym1/symNotepad.c @@ -20,8 +20,8 @@ #define TAPIO_ADDRESS 0xE000 #define TAPIO_MAX_SIZE 0x0FFF -void main(void) { - cha c = 0x00; +int main(void) { + char c = 0x00; int l = 0x00; int p = 0x00; int error = 0x00; @@ -183,6 +183,10 @@ void main(void) { } } } + free( buffer ); + puts( "\nEnjoy your day!\n" ); + + return 0; } diff --git a/targettest/sym1/symTiny.c b/targettest/sym1/symTiny.c index bbca4f9d1..27b8840d8 100644 --- a/targettest/sym1/symTiny.c +++ b/targettest/sym1/symTiny.c @@ -11,7 +11,7 @@ #include <stdio.h> #include <sym1.h> -void main(void) { +int main(void) { char c = 0x00; int d = 0x00; int l = 0x00; @@ -37,4 +37,6 @@ void main(void) { for( d = 0; d < 10 ; d++ ) { } } + + return 0; } From a93542e80cb0e15d790d4ac1882f1d6d64600736 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Wed, 16 Jun 2021 16:24:26 -0500 Subject: [PATCH 2132/2161] Added __fastcall__ to comments --- libsrc/sym1/read.s | 3 ++- libsrc/sym1/write.s | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libsrc/sym1/read.s b/libsrc/sym1/read.s index 177472270..a2549fd9c 100644 --- a/libsrc/sym1/read.s +++ b/libsrc/sym1/read.s @@ -1,7 +1,7 @@ ; ; Wayne Parham (wayne@parhamdata.com) ; -; int read (int fd, void* buf, unsigned count); +; int __fastcall__ read (int fd, void* buf, unsigned count); ; .include "sym1.inc" @@ -37,6 +37,7 @@ getch: jsr INTCHR ; Get character using Monitor ROM call chkcr: cmp #$0D ; Check for '\r' bne putch ; ...if CR character lda #$0A ; Replace with '\n' + jsr OUTCHR ; and echo it putch: ldy #$00 ; Put char into return buffer sta (ptr1),y diff --git a/libsrc/sym1/write.s b/libsrc/sym1/write.s index 314a7760b..7b7428b9b 100644 --- a/libsrc/sym1/write.s +++ b/libsrc/sym1/write.s @@ -1,7 +1,7 @@ ; ; Wayne Parham (wayne@parhamdata.com) ; -; int write (int fd, const void* buf, int count); +; int __fastcall__ write (int fd, const void* buf, int count); ; .include "sym1.inc" From bed61df8377c42ad7c1cf4e4e32e61691d84ffd7 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Wed, 16 Jun 2021 16:28:17 -0500 Subject: [PATCH 2133/2161] Removed unnecessary blank line from samples/Makefile --- samples/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/Makefile b/samples/Makefile index 1679b7d96..502748ea1 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -154,7 +154,6 @@ endif # Lists of subdirectories # disasm depends on cpp - DIRLIST = tutorial geos # -------------------------------------------------------------------------- From 82bdc77e41b4e46471ce26be3580f641afe730ac Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Wed, 16 Jun 2021 16:47:38 -0500 Subject: [PATCH 2134/2161] puts() whitespace style change --- targettest/sym1/symDisplay.c | 10 ++++---- targettest/sym1/symHello.c | 2 +- targettest/sym1/symIO.c | 26 ++++++++++---------- targettest/sym1/symNotepad.c | 46 ++++++++++++++++++------------------ targettest/sym1/symTiny.c | 8 +++---- 5 files changed, 46 insertions(+), 46 deletions(-) diff --git a/targettest/sym1/symDisplay.c b/targettest/sym1/symDisplay.c index 9176b5234..350d261f9 100644 --- a/targettest/sym1/symDisplay.c +++ b/targettest/sym1/symDisplay.c @@ -30,22 +30,22 @@ int main (void) { buffer[i] = c; i++; if( i == 40 ) { - puts( "\n\n--- Reached 40 character limit. ---" ); + puts ("\n\n--- Reached 40 character limit. ---"); } } i--; // index is one past end while( z == 0 ) { - puts( "\n\nHow many times (0 for forever) to repeat?" ); + puts ("\n\nHow many times (0 for forever) to repeat?"); c = getchar(); if( (c >= '0') && (c <= '9') ) { // between 1 and 9 loops allowed z = 1; // a number was pressed t = c - '0'; // convert char to int - puts( "\n\nLook at the front panel.\n" ); + puts ("\n\nLook at the front panel.\n"); } else { - puts( "\nWhat?" ); + puts ("\nWhat?"); z = 0; // keep asking for a number } } @@ -352,7 +352,7 @@ int main (void) { } } - puts( "\n\nEnjoy your day!\n\n" ); + puts ("\n\nEnjoy your day!\n\n"); return 0; } diff --git a/targettest/sym1/symHello.c b/targettest/sym1/symHello.c index a37bc1994..8ca3ac4aa 100644 --- a/targettest/sym1/symHello.c +++ b/targettest/sym1/symHello.c @@ -9,7 +9,7 @@ #include <stdio.h> #include <sym1.h> -int main(void) { +int main (void) { char c = 0x00; int d = 0x00; int l = 0x00; diff --git a/targettest/sym1/symIO.c b/targettest/sym1/symIO.c index 0659b71f3..65bd6e2e1 100644 --- a/targettest/sym1/symIO.c +++ b/targettest/sym1/symIO.c @@ -11,7 +11,7 @@ #include <stdlib.h> #include <string.h> -int main(void) { +int main (void) { unsigned char ddr1a = 0x00; unsigned char ior1a = 0x00; unsigned char ddr1b = 0x00; @@ -51,21 +51,21 @@ int main(void) { ddr3b = VIA3.ddrb; ior3b = VIA3.prb; - puts( "================== Digital I/O Status ==================" ); - puts( " Port1A Port1B Port2A Port2B Port3A Port3B" ); + puts ("================== Digital I/O Status =================="); + puts (" Port1A Port1B Port2A Port2B Port3A Port3B" ); printf( "DDR %02X %02X %02X %02X %02X %02X\n\r",ddr1a,ddr1b,ddr2a,ddr2b,ddr3a,ddr3b ); printf( "IOR %02X %02X %02X %02X %02X %02X\n\r",ior1a,ior1b,ior2a,ior2b,ior3a,ior3b ); - puts( "========================================================\n" ); + puts ("========================================================\n"); if( instr ) { - puts( "You can set any register by typing 'register value' so" ); - puts( "as an example, to set register IOR2A with the top five" ); - puts( "bits off and the bottom three on, type 'IOR2A 07'." ); - puts( "Press ENTER without any command to see register values" ); - puts( "without changing any of them. Type 'help' to see these" ); - puts( "instructions again and type 'quit' to end the program.\n"); - puts( "Available registers: DDR1A, IOR1A, DDR1B, IOR1B, DDR2A" ); - puts( "IOR2A, DDR2B, IOR2B, DDR3A, IOR3A, DDR3B and IOR3B." ); + puts ("You can set any register by typing 'register value' so"); + puts ("as an example, to set register IOR2A with the top five"); + puts ("bits off and the bottom three on, type 'IOR2A 07'."); + puts ("Press ENTER without any command to see register values"); + puts ("without changing any of them. Type 'help' to see these"); + puts ("instructions again and type 'quit' to end the program.\n"); + puts ("Available registers: DDR1A, IOR1A, DDR1B, IOR1B, DDR2A"); + puts ("IOR2A, DDR2B, IOR2B, DDR3A, IOR3A, DDR3B and IOR3B."); instr = 0; } @@ -166,7 +166,7 @@ int main(void) { } } - puts( "\n\nEnjoy your day!\n\n" ); + puts ("\n\nEnjoy your day!\n\n"); return 0; } diff --git a/targettest/sym1/symNotepad.c b/targettest/sym1/symNotepad.c index f2e923bb5..7a603bd93 100644 --- a/targettest/sym1/symNotepad.c +++ b/targettest/sym1/symNotepad.c @@ -20,7 +20,7 @@ #define TAPIO_ADDRESS 0xE000 #define TAPIO_MAX_SIZE 0x0FFF -int main(void) { +int main (void) { char c = 0x00; int l = 0x00; int p = 0x00; @@ -42,7 +42,7 @@ int main(void) { memset( buffer, 0x00, heap_size ); if( buffer == 0x00 ) { - puts( "Memory full." ); + puts ("Memory full."); running = 0; } @@ -78,16 +78,16 @@ int main(void) { putchar( '\n' ); } - puts( "===================== Sym-1 Notepad ====================" ); + puts ("===================== Sym-1 Notepad ===================="); if( instruction_needed ) { - puts( "Enter text and you can save it to tape for reloading" ); - puts( "later. There are four special 'command' characters:\n" ); - puts( " Control-S Save to tape" ); - puts( " Control-L Load from tape" ); - puts( " Control-C Clear memory" ); - puts( " Control-X Exit" ); - puts( "========================================================\n" ); + puts ("Enter text and you can save it to tape for reloading"); + puts ("later. There are four special 'command' characters:\n"); + puts (" Control-S Save to tape"); + puts (" Control-L Load from tape"); + puts (" Control-C Clear memory"); + puts (" Control-X Exit"); + puts ("========================================================\n"); } while( writing ) { @@ -101,18 +101,18 @@ int main(void) { } } else if( c == 0x13 ) { // Save - puts( "\n========================= Save =========================" ); - puts( "\nPress any key to save." ); + puts ("\n========================= Save ========================="); + puts ("\nPress any key to save."); c = getchar(); for( l = 0; l <= p; l++ ) { tapio[l] = buffer[l]; } l++; tapio[l] = 0x00; - puts( "Saving to tape." ); + puts ("Saving to tape."); error = dumpt( 'N', tapio, tapio+p ); if( error ) { - puts( "\nTape error." ); + puts ("\nTape error."); } else { @@ -121,20 +121,20 @@ int main(void) { putchar( '\n' ); } } - puts( "===================== Sym-1 Notepad ====================\n" ); + puts ("===================== Sym-1 Notepad ====================\n"); for( l = 0; l <= p; l++ ) { putchar( buffer[l] ); } } else if( c == 0x0C ) { // Load p = 0; - puts( "\nLoading from tape." ); + puts ("\nLoading from tape."); memset( buffer, 0, heap_size ); memset( tapio, 0, TAPIO_MAX_SIZE ); error = loadt( 'N' ); if( error ) { - puts( "\nTape error." ); - puts( "===================== Sym-1 Notepad ====================\n" ); + puts ("\nTape error."); + puts ("===================== Sym-1 Notepad ====================\n"); } else { @@ -148,7 +148,7 @@ int main(void) { for( l = 0; l < 25; l++ ) { putchar( '\n' ); } - puts( "===================== Sym-1 Notepad ====================\n" ); + puts ("===================== Sym-1 Notepad ====================\n"); for( l = 0; l <= p; l++ ) { putchar( buffer[l] ); @@ -162,7 +162,7 @@ int main(void) { for( l = 0; l < 25; l++ ) { putchar( '\n' ); } - puts( "===================== Sym-1 Notepad ====================\n" ); + puts ("===================== Sym-1 Notepad ====================\n"); } else if( c == 0x18 ) { // Exit writing = 0; @@ -170,8 +170,8 @@ int main(void) { } else { if( p >= heap_size - 1 ) { - puts( "\n========================= End =========================" ); - puts( "Buffer full." ); + puts ("\n========================= End ========================="); + puts ("Buffer full."); } else { if( c == '\n' ) { @@ -186,7 +186,7 @@ int main(void) { free( buffer ); - puts( "\nEnjoy your day!\n" ); + puts ("\nEnjoy your day!\n"); return 0; } diff --git a/targettest/sym1/symTiny.c b/targettest/sym1/symTiny.c index 27b8840d8..be7d02824 100644 --- a/targettest/sym1/symTiny.c +++ b/targettest/sym1/symTiny.c @@ -11,14 +11,14 @@ #include <stdio.h> #include <sym1.h> -int main(void) { +int main (void) { char c = 0x00; int d = 0x00; int l = 0x00; - puts( "Hello World!\n" ); + puts ("Hello World!\n"); - puts( "Type a line and press ENTER, please:\n" ); + puts ("Type a line and press ENTER, please:\n"); for( l = 0; l < 2; l++ ) { beep(); @@ -30,7 +30,7 @@ int main(void) { c = getchar(); } - puts( "\n\nThanks!\n" ); + puts ("\n\nThanks!\n"); for( l = 0; l < 5; l++ ) { beep(); From 5d90087e664bdd564f09c78b6cbacee2edef5561 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Wed, 16 Jun 2021 17:14:44 -0500 Subject: [PATCH 2135/2161] Add space after every function or statement, before parenthesis --- targettest/sym1/symDisplay.c | 30 +++++------ targettest/sym1/symHello.c | 16 +++--- targettest/sym1/symIO.c | 94 ++++++++++++++++---------------- targettest/sym1/symNotepad.c | 100 +++++++++++++++++------------------ targettest/sym1/symTiny.c | 10 ++-- 5 files changed, 125 insertions(+), 125 deletions(-) diff --git a/targettest/sym1/symDisplay.c b/targettest/sym1/symDisplay.c index 350d261f9..dce39f6b9 100644 --- a/targettest/sym1/symDisplay.c +++ b/targettest/sym1/symDisplay.c @@ -23,23 +23,23 @@ int main (void) { char c = 0x00; char buffer[41] = { 0x00 }; - puts( "\nType a message (40 chars max) and press ENTER, please:\n" ); + puts ("\nType a message (40 chars max) and press ENTER, please:\n"); - while( (c != '\n') && (i < 40) ) { + while ( (c != '\n') && (i < 40) ) { c = getchar(); buffer[i] = c; i++; - if( i == 40 ) { + if ( i == 40 ) { puts ("\n\n--- Reached 40 character limit. ---"); } } i--; // index is one past end - while( z == 0 ) { + while ( z == 0 ) { puts ("\n\nHow many times (0 for forever) to repeat?"); c = getchar(); - if( (c >= '0') && (c <= '9') ) { // between 1 and 9 loops allowed + if ( (c >= '0') && (c <= '9') ) {// between 1 and 9 loops allowed z = 1; // a number was pressed t = c - '0'; // convert char to int puts ("\n\nLook at the front panel.\n"); @@ -51,11 +51,11 @@ int main (void) { } z = 0; - while( (z < t) || (t == 0) ) { + while ( (z < t) || (t == 0) ) { z++; - putchar( '\r' ); // Send CR to console + putchar ( '\r' ); // Send CR to console DISPLAY.d0 = DISP_SPACE; // Clear the display DISPLAY.d1 = DISP_SPACE; @@ -65,15 +65,15 @@ int main (void) { DISPLAY.d5 = DISP_SPACE; DISPLAY.d6 = DISP_SPACE; - for( d = 0; d < flashes ; d++ ) { + for ( d = 0; d < flashes ; d++ ) { fdisp(); // Display } - for( l = 0; l <= i; l++ ) { + for ( l = 0; l <= i; l++ ) { displayable = 1; // Assume character is mapped - switch( buffer[l] ) { // Put the typed charaters + switch ( buffer[l] ) { // Put the typed charaters case '1': // into the display buffer DISPLAY.d6 = DISP_1; // one at a time break; @@ -321,9 +321,9 @@ int main (void) { displayable = 0; // Character not mapped } - if( displayable ) { + if ( displayable ) { - putchar( buffer[l] ); // Send it to the console + putchar ( buffer[l] ); // Send it to the console DISPLAY.d0 = DISPLAY.d1; // Scroll to the left DISPLAY.d1 = DISPLAY.d2; @@ -332,13 +332,13 @@ int main (void) { DISPLAY.d4 = DISPLAY.d5; DISPLAY.d5 = DISPLAY.d6; - for( d = 0; d < flashes ; d++ ) { + for ( d = 0; d < flashes ; d++ ) { fdisp(); // Display } } } - for( e = 0; e < 6; e++ ) { // Gradually fill the + for ( e = 0; e < 6; e++ ) { // Gradually fill the DISPLAY.d0 = DISPLAY.d1; // display with spaces DISPLAY.d1 = DISPLAY.d2; DISPLAY.d2 = DISPLAY.d3; @@ -346,7 +346,7 @@ int main (void) { DISPLAY.d4 = DISPLAY.d5; DISPLAY.d5 = DISP_SPACE; DISPLAY.d6 = DISP_SPACE; - for( d = 0; d < flashes ; d++ ) { + for ( d = 0; d < flashes ; d++ ) { fdisp(); // Display } } diff --git a/targettest/sym1/symHello.c b/targettest/sym1/symHello.c index 8ca3ac4aa..afc1d94c5 100644 --- a/targettest/sym1/symHello.c +++ b/targettest/sym1/symHello.c @@ -14,24 +14,24 @@ int main (void) { int d = 0x00; int l = 0x00; - printf( "\nHello World!\n\n" ); + printf ("\nHello World!\n\n"); - for( l = 0; l < 2; l++ ) { + for ( l = 0; l < 2; l++ ) { beep(); - for( d = 0; d < 10 ; d++ ) { + for ( d = 0; d < 10 ; d++ ) { } } - printf( "Type a line and press ENTER, please.\n\n" ); + printf ("Type a line and press ENTER, please.\n\n"); - while( c != '\n' ) { + while ( c != '\n' ) { c = getchar(); } - printf( "\n\nThanks!\n\n" ); + printf ("\n\nThanks!\n\n"); - for( l = 0; l < 5; l++ ) { + for ( l = 0; l < 5; l++ ) { beep(); - for( d = 0; d < 10 ; d++ ) { + for ( d = 0; d < 10 ; d++ ) { } } diff --git a/targettest/sym1/symIO.c b/targettest/sym1/symIO.c index 65bd6e2e1..50fefc303 100644 --- a/targettest/sym1/symIO.c +++ b/targettest/sym1/symIO.c @@ -31,11 +31,11 @@ int main (void) { char* vp = 0x00; char cmd[20] = { 0x00 }; - while( going ) { + while ( going ) { - putchar( '\r' ); - for( l = 0; l < 25; l++ ) { - putchar( '\n' ); + putchar ( '\r' ); + for ( l = 0; l < 25; l++ ) { + putchar ( '\n' ); } ddr1a = VIA1.ddra; @@ -53,11 +53,11 @@ int main (void) { puts ("================== Digital I/O Status =================="); puts (" Port1A Port1B Port2A Port2B Port3A Port3B" ); - printf( "DDR %02X %02X %02X %02X %02X %02X\n\r",ddr1a,ddr1b,ddr2a,ddr2b,ddr3a,ddr3b ); - printf( "IOR %02X %02X %02X %02X %02X %02X\n\r",ior1a,ior1b,ior2a,ior2b,ior3a,ior3b ); + printf ("DDR %02X %02X %02X %02X %02X %02X\n\r",ddr1a,ddr1b,ddr2a,ddr2b,ddr3a,ddr3b); + printf ("IOR %02X %02X %02X %02X %02X %02X\n\r",ior1a,ior1b,ior2a,ior2b,ior3a,ior3b); puts ("========================================================\n"); - if( instr ) { + if ( instr ) { puts ("You can set any register by typing 'register value' so"); puts ("as an example, to set register IOR2A with the top five"); puts ("bits off and the bottom three on, type 'IOR2A 07'."); @@ -69,97 +69,97 @@ int main (void) { instr = 0; } - printf( "\n Command: " ); + printf ("\n Command: "); - fgets(cmd, sizeof(cmd)-1, stdin); + fgets ( cmd, sizeof(cmd)-1, stdin ); cmd[strlen(cmd)-1] = '\0'; - if( strncasecmp(cmd, "quit", 4) == 0) { + if ( strncasecmp(cmd, "quit", 4) == 0 ) { going = 0; } - else if( strncasecmp(cmd, "help", 4) == 0) { + else if ( strncasecmp(cmd, "help", 4) == 0 ) { instr = 1; } - else if( strncasecmp(cmd, "ddr1a", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { + else if ( strncasecmp(cmd, "ddr1a", 5) == 0 ) { + vp = strchr ( cmd, ' ' ); + if ( vp ) { val = (unsigned char) strtol( vp, NULL, 0 ); VIA1.ddra = val; } } - else if( strncasecmp(cmd, "ior1a", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { + else if ( strncasecmp(cmd, "ior1a", 5) == 0 ) { + vp = strchr ( cmd, ' ' ); + if ( vp ) { val = (unsigned char) strtol( vp, NULL, 0 ); VIA1.pra = val; } } - else if( strncasecmp(cmd, "ddr1b", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { + else if ( strncasecmp(cmd, "ddr1b", 5) == 0 ) { + vp = strchr ( cmd, ' ' ); + if ( vp ) { val = (unsigned char) strtol( vp, NULL, 0 ); VIA1.ddrb = val; } } - else if( strncasecmp(cmd, "ior1b", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { + else if ( strncasecmp(cmd, "ior1b", 5) == 0 ) { + vp = strchr ( cmd, ' ' ); + if ( vp ) { val = (unsigned char) strtol( vp, NULL, 0 ); VIA1.prb = val; } } - else if( strncasecmp(cmd, "ddr2a", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { + else if ( strncasecmp(cmd, "ddr2a", 5) == 0 ) { + vp = strchr ( cmd, ' ' ); + if ( vp ) { val = (unsigned char) strtol( vp, NULL, 0 ); VIA2.ddra = val; } } - else if( strncasecmp(cmd, "ior2a", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { + else if ( strncasecmp(cmd, "ior2a", 5) == 0 ) { + vp = strchr ( cmd, ' ' ); + if ( vp ) { val = (unsigned char) strtol( vp, NULL, 0 ); VIA2.pra = val; } } - else if( strncasecmp(cmd, "ddr2b", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { + else if ( strncasecmp(cmd, "ddr2b", 5) == 0 ) { + vp = strchr ( cmd, ' ' ); + if ( vp ) { val = (unsigned char) strtol( vp, NULL, 0 ); VIA2.ddrb = val; } } - else if( strncasecmp(cmd, "ior2b", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { + else if ( strncasecmp(cmd, "ior2b", 5) == 0 ) { + vp = strchr ( cmd, ' ' ); + if ( vp ) { val = (unsigned char) strtol( vp, NULL, 0 ); VIA2.prb = val; } } - else if( strncasecmp(cmd, "ddr3a", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { + else if ( strncasecmp(cmd, "ddr3a", 5) == 0 ) { + vp = strchr ( cmd, ' ' ); + if ( vp ) { val = (unsigned char) strtol( vp, NULL, 0 ); VIA3.ddra = val; } } - else if( strncasecmp(cmd, "ior3a", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { + else if ( strncasecmp(cmd, "ior3a", 5) == 0 ) { + vp = strchr ( cmd, ' ' ); + if ( vp ) { val = (unsigned char) strtol( vp, NULL, 0 ); VIA3.pra = val; } } - else if( strncasecmp(cmd, "ddr3b", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { + else if ( strncasecmp(cmd, "ddr3b", 5) == 0 ) { + vp = strchr ( cmd, ' ' ); + if ( vp ) { val = (unsigned char) strtol( vp, NULL, 0 ); VIA3.ddrb = val; } } - else if( strncasecmp(cmd, "ior3b", 5) == 0) { - vp = strchr(cmd, ' '); - if( vp ) { + else if ( strncasecmp(cmd, "ior3b", 5) == 0 ) { + vp = strchr (cmd, ' ' ); + if ( vp ) { val = (unsigned char) strtol( vp, NULL, 0 ); VIA3.prb = val; } diff --git a/targettest/sym1/symNotepad.c b/targettest/sym1/symNotepad.c index 7a603bd93..1d0541ab6 100644 --- a/targettest/sym1/symNotepad.c +++ b/targettest/sym1/symNotepad.c @@ -34,53 +34,53 @@ int main (void) { heap_size = _heapmaxavail(); - if( heap_size > TAPIO_MAX_SIZE ) { // No need to malloc more than + if ( heap_size > TAPIO_MAX_SIZE ) { // No need to malloc more than heap_size = TAPIO_MAX_SIZE; // the interface allows } - buffer = malloc( heap_size ); - memset( buffer, 0x00, heap_size ); + buffer = malloc ( heap_size ); + memset ( buffer, 0x00, heap_size ); - if( buffer == 0x00 ) { + if ( buffer == 0x00 ) { puts ("Memory full."); running = 0; } tapio[0] = 0x00; // Check tape interface memory - if( tapio[0] != 0x00 ) + if ( tapio[0] != 0x00 ) error = 1; tapio[0] = 0xFF; - if( tapio[0] != 0xFF ) + if ( tapio[0] != 0xFF ) error = 1; tapio[TAPIO_MAX_SIZE] = 0x00; - if( tapio[TAPIO_MAX_SIZE] != 0x00 ) + if ( tapio[TAPIO_MAX_SIZE] != 0x00 ) error = 1; tapio[TAPIO_MAX_SIZE] = 0xFF; - if( tapio[TAPIO_MAX_SIZE] != 0xFF ) + if ( tapio[TAPIO_MAX_SIZE] != 0xFF ) error = 1; - if( error ) { - printf( "\nNo memory at location %p, aborting.\n", tapio ); + if ( error ) { + printf ("\nNo memory at location %p, aborting.\n", tapio); running = 0; } else { - memset( tapio, 0, TAPIO_MAX_SIZE ); + memset ( tapio, 0, TAPIO_MAX_SIZE ); } - while( running ) { + while ( running ) { - putchar( '\r' ); - for( l = 0; l < 25; l++ ) { - putchar( '\n' ); + putchar ( '\r' ); + for ( l = 0; l < 25; l++ ) { + putchar ( '\n' ); } puts ("===================== Sym-1 Notepad ===================="); - if( instruction_needed ) { + if ( instruction_needed ) { puts ("Enter text and you can save it to tape for reloading"); puts ("later. There are four special 'command' characters:\n"); puts (" Control-S Save to tape"); @@ -90,92 +90,92 @@ int main (void) { puts ("========================================================\n"); } - while( writing ) { + while ( writing ) { c = getchar(); - if( c == 0x08 ) { // Backspace - if( p > 0 ) { + if ( c == 0x08 ) { // Backspace + if ( p > 0 ) { buffer[p] = 0x00; p--; } } - else if( c == 0x13 ) { // Save + else if ( c == 0x13 ) { // Save puts ("\n========================= Save ========================="); puts ("\nPress any key to save."); c = getchar(); - for( l = 0; l <= p; l++ ) { + for ( l = 0; l <= p; l++ ) { tapio[l] = buffer[l]; } l++; tapio[l] = 0x00; puts ("Saving to tape."); - error = dumpt( 'N', tapio, tapio+p ); - if( error ) { + error = dumpt ( 'N', tapio, tapio+p ); + if ( error ) { puts ("\nTape error."); } else { - putchar( '\r' ); - for( l = 0; l < 25; l++ ) { - putchar( '\n' ); + putchar ( '\r' ); + for ( l = 0; l < 25; l++ ) { + putchar ( '\n' ); } } puts ("===================== Sym-1 Notepad ====================\n"); - for( l = 0; l <= p; l++ ) { - putchar( buffer[l] ); + for ( l = 0; l <= p; l++ ) { + putchar ( buffer[l] ); } } - else if( c == 0x0C ) { // Load + else if ( c == 0x0C ) { // Load p = 0; puts ("\nLoading from tape."); - memset( buffer, 0, heap_size ); - memset( tapio, 0, TAPIO_MAX_SIZE ); - error = loadt( 'N' ); - if( error ) { + memset ( buffer, 0, heap_size ); + memset ( tapio, 0, TAPIO_MAX_SIZE ); + error = loadt ( 'N' ); + if ( error ) { puts ("\nTape error."); puts ("===================== Sym-1 Notepad ====================\n"); } else { - for( l = 0; l <= heap_size; l++ ) { + for ( l = 0; l <= heap_size; l++ ) { buffer[l] = tapio[l]; } - p = strlen( buffer ); + p = strlen ( buffer ); - putchar( '\r' ); - for( l = 0; l < 25; l++ ) { - putchar( '\n' ); + putchar ( '\r' ); + for ( l = 0; l < 25; l++ ) { + putchar ( '\n' ); } puts ("===================== Sym-1 Notepad ====================\n"); - for( l = 0; l <= p; l++ ) { - putchar( buffer[l] ); + for ( l = 0; l <= p; l++ ) { + putchar ( buffer[l] ); } } } - else if( c == 0x03 ) { // Clear + else if ( c == 0x03 ) { // Clear p = 0; - memset( buffer, 0, heap_size ); - putchar( '\r' ); - for( l = 0; l < 25; l++ ) { - putchar( '\n' ); + memset ( buffer, 0, heap_size ); + putchar ( '\r' ); + for ( l = 0; l < 25; l++ ) { + putchar ( '\n' ); } puts ("===================== Sym-1 Notepad ====================\n"); } - else if( c == 0x18 ) { // Exit + else if ( c == 0x18 ) { // Exit writing = 0; running = 0; } else { - if( p >= heap_size - 1 ) { + if ( p >= heap_size - 1 ) { puts ("\n========================= End ========================="); puts ("Buffer full."); } else { - if( c == '\n' ) { - putchar( '\n' ); + if ( c == '\n' ) { + putchar ( '\n' ); } buffer[p] = c; } @@ -184,7 +184,7 @@ int main (void) { } } - free( buffer ); + free ( buffer ); puts ("\nEnjoy your day!\n"); diff --git a/targettest/sym1/symTiny.c b/targettest/sym1/symTiny.c index be7d02824..574ac36bc 100644 --- a/targettest/sym1/symTiny.c +++ b/targettest/sym1/symTiny.c @@ -20,21 +20,21 @@ int main (void) { puts ("Type a line and press ENTER, please:\n"); - for( l = 0; l < 2; l++ ) { + for ( l = 0; l < 2; l++ ) { beep(); - for( d = 0; d < 10 ; d++ ) { + for ( d = 0; d < 10 ; d++ ) { } } - while( c != '\n' ) { + while ( c != '\n' ) { c = getchar(); } puts ("\n\nThanks!\n"); - for( l = 0; l < 5; l++ ) { + for ( l = 0; l < 5; l++ ) { beep(); - for( d = 0; d < 10 ; d++ ) { + for ( d = 0; d < 10 ; d++ ) { } } From 85d345088dd46ed4529c156c671d72e7ec9f94ed Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Wed, 16 Jun 2021 17:19:28 -0500 Subject: [PATCH 2136/2161] Remove trailing two blank lines from libsrc/sym1/crt0.s --- libsrc/sym1/crt0.s | 2 -- 1 file changed, 2 deletions(-) diff --git a/libsrc/sym1/crt0.s b/libsrc/sym1/crt0.s index 47cc67f07..5d398b311 100644 --- a/libsrc/sym1/crt0.s +++ b/libsrc/sym1/crt0.s @@ -55,5 +55,3 @@ _exit: jsr donelib ; Run destructors sta TECHO jsr NACCES ; Lock System RAM rts ; Re-enter Sym-1 monitor - - From d6ef8326f9836a8f417bfc187daf57fab42806eb Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Wed, 16 Jun 2021 17:24:18 -0500 Subject: [PATCH 2137/2161] Remove trailing blank line from libsrc/sym1/display.s --- libsrc/sym1/display.s | 1 - 1 file changed, 1 deletion(-) diff --git a/libsrc/sym1/display.s b/libsrc/sym1/display.s index 1d3b0abfa..f3b2923d6 100644 --- a/libsrc/sym1/display.s +++ b/libsrc/sym1/display.s @@ -16,4 +16,3 @@ rts .endproc - From 5f4605c4fc0dc0f3266edcc811df31a67ef724e6 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Wed, 16 Jun 2021 17:28:19 -0500 Subject: [PATCH 2138/2161] Remove trailing blank lines from read.s, write.s and tapeio.s --- libsrc/sym1/read.s | 1 - libsrc/sym1/tapeio.s | 1 - libsrc/sym1/write.s | 1 - 3 files changed, 3 deletions(-) diff --git a/libsrc/sym1/read.s b/libsrc/sym1/read.s index a2549fd9c..c041664da 100644 --- a/libsrc/sym1/read.s +++ b/libsrc/sym1/read.s @@ -51,4 +51,3 @@ done: lda ptr3 rts ; Return count .endproc - diff --git a/libsrc/sym1/tapeio.s b/libsrc/sym1/tapeio.s index 13579dca7..078ea7abd 100644 --- a/libsrc/sym1/tapeio.s +++ b/libsrc/sym1/tapeio.s @@ -44,4 +44,3 @@ error: jmp return1 ; or 1 if not error: jmp return1 ; or 1 if not .endproc - diff --git a/libsrc/sym1/write.s b/libsrc/sym1/write.s index 7b7428b9b..dbe738468 100644 --- a/libsrc/sym1/write.s +++ b/libsrc/sym1/write.s @@ -49,4 +49,3 @@ done: lda ptr3 rts ; Return count .endproc - From 62da869e49bee55b3f0d7dab2dc7bdf9721b6f07 Mon Sep 17 00:00:00 2001 From: Spiro Trikaliotis <spiro.trikaliotis@gmx.de> Date: Mon, 21 Jun 2021 21:34:19 +0200 Subject: [PATCH 2139/2161] doc: psg_silence: Remove empty notes The notes section of psg_silence (Creativision funcref) contained an empty Notes section, consisting of an empty <itemize> only. Newer sgmltools fail on this, as they insist on having an <item> element, or they fail compilation: [ 225s] Processing file ../doc/funcref.sgml [ 225s] onsgmls:/tmp/linuxdoc-tools.NfxbjODQbW/sgmltmp.funcref.01.precmdout:5884:9:E:end tag for "ITEMIZE" which is not finished Fixed this by removing the (empty) Notes section altogether. --- doc/funcref.sgml | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 28faa068a..e6cb42a0f 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -5880,8 +5880,6 @@ void main (void) <tag/Declaration/<tt/void psg_silence (void);/ <tag/Description/The function resets the Programmable Sound Generator, then sends $9F, $BF, $DF, $FF to the PSG. -<tag/Notes/<itemize> -</itemize> <tag/Availability/cc65 <tag/See also/ <ref id="psg_delay" name="psg_delay">, From 52e43879298c2fb30c7bc6fd95fae3b3f1458793 Mon Sep 17 00:00:00 2001 From: Greg King <gregdk@users.sf.net> Date: Thu, 12 Aug 2021 13:21:24 -0400 Subject: [PATCH 2140/2161] Added a program that tests the Commodore-specific directory functions. --- targettest/cbm/Makefile | 7 ++- targettest/cbm/cbmdir-test.c | 119 +++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 targettest/cbm/cbmdir-test.c diff --git a/targettest/cbm/Makefile b/targettest/cbm/Makefile index fb7af1a9a..298f80d62 100644 --- a/targettest/cbm/Makefile +++ b/targettest/cbm/Makefile @@ -30,10 +30,13 @@ else LD := $(if $(wildcard ../../../bin/ld65*),../../../bin/ld65,ld65) endif -all: petscii.prg +all: petscii.prg cbmdir-test.prg petscii.prg: petscii.c $(CL) -t $(SYS) -O -o petscii.prg petscii.c +cbmdir-test.prg: cbmdir-test.c + $(CL) -t $(SYS) -Oris -o $@ $< + clean: - @$(DEL) petscii.prg 2>$(NULLDEV) + @$(DEL) petscii.prg cbmdir-test.prg 2>$(NULLDEV) diff --git a/targettest/cbm/cbmdir-test.c b/targettest/cbm/cbmdir-test.c new file mode 100644 index 000000000..0db9856b7 --- /dev/null +++ b/targettest/cbm/cbmdir-test.c @@ -0,0 +1,119 @@ +/* +** Tests the CBM-specific directory functions. +** +** 2021-08-12, Greg King +*/ + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <conio.h> +#include <cbm.h> + + +/* device number */ +#define UNIT 8 + +/* directory patterm */ +static const char name[] = "$"; + + +static const char* const type[] = { + "DEL", + "CBM", + "DIR", + "LNK", + "???", + "Directory header", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "SEQ", + "PRG", + "USR", + "REL", + "VRP" +}; + +static const char* const access[] = { + "unknown", + "read-only", + "write-only", + "read/write" +}; + +static const char* const error[] = { + "", + "couldn't read it", + "", + "couldn't find start of file-name", + "couldn't find end of file-name", + "couldn't read file-type", + "premature end of file" +}; + + +int main(void) +{ + unsigned char go = 0; + unsigned char rc; + struct cbm_dirent E; + + /* Explain use, and wait for a key. */ + printf ("use the following keys:\n" + " g -> go ahead without stopping\n" + " q -> quit directory lister\n" + "tap any key to start ...\n\n"); + cgetc (); + + /* Open the directory. */ + if (cbm_opendir (1, UNIT, name) != 0) { + printf("error opening %s:\n %s\n", name, _stroserror (_oserror)); + return 1; + } + + /* Output the directory. */ + printf("contents of \"%s\":\n", name); + while ((rc = cbm_readdir (1, &E)) != 2) { + if (rc != 0) { + goto oops; + } + + printf (" name[]: \"%s\"\n", E.name); + printf (" size :%6u\n", E.size); + printf (" type : %s\n", type[E.type]); + printf (" access: %s\n", access[E.access > 3 ? 0 : E.access]); + printf ("----\n"); + + if (!go) { + switch (cgetc ()) { + case 'q': + goto done; + + case 'g': + go = 1; + } + } + } + + printf (" size :%6u free.\n", E.size); + +done: + /* Close the directory. */ + cbm_closedir (1); + return 0; + +oops: + if (rc <= 6) { + printf ("\ndirectory error:\n %s.\n", error[rc]); + } + cbm_closedir (1); + return 1; +} From 28b1687aafc4c124cbb6664d20d4b0759125d350 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 26 Sep 2021 12:09:50 +0200 Subject: [PATCH 2141/2161] Be explicit about hardware flow control (RTS/CTS) being the only supported option. --- doc/apple2.sgml | 4 ++-- doc/apple2enh.sgml | 4 ++-- doc/atari.sgml | 6 +++--- doc/atmos.sgml | 9 +++++---- doc/c128.sgml | 6 +++--- doc/c64.sgml | 6 +++--- doc/cbm510.sgml | 8 ++++---- doc/cbm610.sgml | 8 ++++---- doc/plus4.sgml | 8 ++++---- 9 files changed, 30 insertions(+), 29 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index f957e1247..bd01b68dc 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -428,8 +428,8 @@ The names in the parentheses denote the symbols to be used for static linking of <tag><tt/a2.ssc.ser (a2_ssc_ser)/</tag> Driver for the Apple II Super Serial Card. Supports up to 19200 baud, - hardware flow control (RTS/CTS) and interrupt driven receives. Note - that because of the peculiarities of the 6551 chip transmits are not + requires hardware flow control (RTS/CTS) and does interrupt driven receives. + 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. diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 4aafbc256..56fc05e31 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -428,8 +428,8 @@ The names in the parentheses denote the symbols to be used for static linking of <tag><tt/a2e.ssc.ser (a2e_ssc_ser)/</tag> Driver for the Apple II Super Serial Card. Supports up to 19200 baud, - hardware flow control (RTS/CTS) and interrupt driven receives. Note - that because of the peculiarities of the 6551 chip transmits are not + requires hardware flow control (RTS/CTS) and does interrupt driven receives. + 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. diff --git a/doc/atari.sgml b/doc/atari.sgml index f2ced13e1..903895d17 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -675,9 +675,9 @@ The default callbacks definition (<tt/mouse_def_callbacks/) is an alias for the <sect1>RS232 device drivers<p> -Currently there is one RS232 driver. It uses the R: device (therefore -an R: driver needs to be installed) and was tested with the 850 -interface module. +Currently there is one RS232 driver. It supports up to 9600 baud, requires hardware flow control +(RTS/CTS) and uses the R: device (therefore an R: driver needs to be installed). It was tested +with the 850 interface module. <table> <tabular ca="rr"> diff --git a/doc/atmos.sgml b/doc/atmos.sgml index 3fd61abcf..cef7770e4 100644 --- a/doc/atmos.sgml +++ b/doc/atmos.sgml @@ -176,10 +176,11 @@ No mouse drivers are currently available for the Atmos. <tag><tt/atmos-acia.ser (atmos_acia_ser)/</tag> Driver for the Telestrat integrated serial controller and the Atmos with a - serial add-on. - Note that, because of the peculiarities of the 6551 chip, together with the - use of the NMI, transmits are not interrupt driven; and, the transceiver - blocks if the receiver asserts flow control because of a full buffer. + serial add-on. Supports up to 19200 baud, requires hardware flow control + (RTS/CTS) and does interrupt driven receives. Note that, because of the + peculiarities of the 6551 chip, together with the use of the NMI, transmits + are not interrupt driven; and, the transceiver blocks if the receiver + asserts flow control because of a full buffer. </descrip><p> diff --git a/doc/c128.sgml b/doc/c128.sgml index 8c62b6ad1..60306814c 100644 --- a/doc/c128.sgml +++ b/doc/c128.sgml @@ -324,9 +324,9 @@ The default drivers, <tt/mouse_stddrv (mouse_static_stddrv)/, point to <tt/c128- <descrip> <tag><tt/c128-swlink.ser (c128_swlink_ser)/</tag> - Driver for the SwiftLink cartridge. Supports up to 38400 BPS, hardware flow - control (RTS/CTS), and interrupt-driven receives. Note that, because of the - peculiarities of the 6551 chip, together with the use of the NMI, transmits + Driver for the SwiftLink cartridge. Supports up to 38400 baud, requires hardware + flow control (RTS/CTS) and does interrupt driven receives. Note that, because of + the peculiarities of the 6551 chip, together with the use of the NMI, transmits are not interrupt driven; and, the transceiver blocks if the receiver asserts flow control because of a full buffer. diff --git a/doc/c64.sgml b/doc/c64.sgml index 7e00f3b93..de37ed4b7 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -410,9 +410,9 @@ The default drivers, <tt/mouse_stddrv (mouse_static_stddrv)/, point to <tt/c64-1 <descrip> <tag><tt/c64-swlink.ser (c64_swlink_ser)/</tag> - Driver for the SwiftLink cartridge. Supports up to 38400 BPS, hardware flow - control (RTS/CTS), and interrupt-driven receives. Note that, because of the - peculiarities of the 6551 chip, together with the use of the NMI, transmits + Driver for the SwiftLink cartridge. Supports up to 38400 baud, requires hardware + flow control (RTS/CTS) and does interrupt driven receives. Note that, because of + the peculiarities of the 6551 chip, together with the use of the NMI, transmits are not interrupt driven; and, the transceiver blocks if the receiver asserts flow control because of a full buffer. diff --git a/doc/cbm510.sgml b/doc/cbm510.sgml index c208f3ead..86bed7607 100644 --- a/doc/cbm510.sgml +++ b/doc/cbm510.sgml @@ -231,10 +231,10 @@ The default drivers, <tt/mouse_stddrv (mouse_static_stddrv)/, point to <tt/cbm51 <tag><tt/cbm510-std.ser (cbm510_std_ser)/</tag> Driver for the 6551 ACIA chip built into the Commodore 510. Supports up to - 19200 BPS, hardware flow control (RTS/CTS), and interrupt-driven receives. - 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. + 19200 baud, requires hardware flow control (RTS/CTS) and does interrupt driven + receives. 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. </descrip><p> diff --git a/doc/cbm610.sgml b/doc/cbm610.sgml index 37a445dd1..d86950abc 100644 --- a/doc/cbm610.sgml +++ b/doc/cbm610.sgml @@ -212,10 +212,10 @@ No mouse drivers are currently available for the Commodore 610. <tag><tt/cbm610-std.ser (cbm610_std_ser)/</tag> Driver for the 6551 ACIA chip built into the Commodore 610. Supports up to - 19200 BPS, hardware flow control (RTS/CTS), and interrupt-driven receives. - 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. + 19200 baud, requires hardware flow control (RTS/CTS) and does interrupt driven + receives. 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. </descrip><p> diff --git a/doc/plus4.sgml b/doc/plus4.sgml index 645de5161..79a2597d0 100644 --- a/doc/plus4.sgml +++ b/doc/plus4.sgml @@ -195,10 +195,10 @@ No mouse drivers are currently available for the Plus/4. <tag><tt/plus4-stdser.ser (plus4_stdser_ser)/</tag> Driver for the 6551 ACIA chip built into the Plus/4. Supports up to 19200 - baud, hardware flow control (RTS/CTS) and interrupt driven receives. 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. + baud, requires hardware flow control (RTS/CTS) and does interrupt driven + receives. 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. You need an adapter to use the builtin port, since the output levels available at the user port don't follow the RS232 standard. From eeaa111835d5c82cc821e120a4eba2d548bd2c32 Mon Sep 17 00:00:00 2001 From: acqn <acqn163@outlook.com> Date: Tue, 28 Sep 2021 17:30:10 +0800 Subject: [PATCH 2142/2161] Fixed crash in Opt_a_toscmpbool caused by wrong order of condition checks. --- src/cc65/coptstop.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 23636e533..08f6c820e 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -1113,9 +1113,9 @@ static unsigned Opt_a_toscmpbool (StackOpData* D, const char* BoolTransformer) D->IP = D->OpIndex + 1; - if (!D->RhsMultiChg && - (D->Rhs.A.LoadEntry->Flags & CEF_DONT_REMOVE) == 0 && - (D->Rhs.A.Flags & LI_DIRECT) != 0) { + if (!D->RhsMultiChg && + (D->Rhs.A.Flags & LI_DIRECT) != 0 && + (D->Rhs.A.LoadEntry->Flags & CEF_DONT_REMOVE) == 0) { /* cmp */ AddOpLow (D, OP65_CMP, &D->Rhs); From 6ba8a385a0b81af5388f47d18ce45c3753cde6ba Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 28 Sep 2021 15:59:54 +0200 Subject: [PATCH 2143/2161] add test related tu issue #1562 --- test/val/bug1562.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 test/val/bug1562.c diff --git a/test/val/bug1562.c b/test/val/bug1562.c new file mode 100644 index 000000000..7e6c1751e --- /dev/null +++ b/test/val/bug1562.c @@ -0,0 +1,30 @@ + +/* bug 1562: cc65 generates incorrect code for logical expression with -O */ + +#include <stdio.h> +#include <string.h> + +int failures = 0; + +char input[256]; + +#define DEBUGTRUE(x) printf("%s=%d\n", #x, (x)); failures += (x) ? 0 : 1 + +#define DEBUGFALSE(x) printf("%s=%d\n", #x, (x)); failures += (x) ? 1 : 0 + +int main(void) { + char* r; + strcpy(input, "\"XYZ\""); + r = input+4; + DEBUGFALSE(*r != '"'); // = false + DEBUGTRUE(*r == '"'); // = true + DEBUGFALSE(*(r+1) == '"'); // = false + // Next answer should be false because + // (false || true && false) is false, but it is true with -O. + DEBUGFALSE(*r != '"' || *r == '"' && *(r+1) == '"'); + // Adding parens fixes it even with -O. + DEBUGFALSE(*r != '"' || (*r == '"' && *(r+1) == '"')); + + printf("failures: %d\n", failures); + return failures; +} From 86f19652022ed7c6cc5152c219ee9e8976f78d9e Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 28 Sep 2021 18:55:23 +0200 Subject: [PATCH 2144/2161] added test related to issue #1552 fixed in pr #1571 --- test/val/bug1552.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 test/val/bug1552.c diff --git a/test/val/bug1552.c b/test/val/bug1552.c new file mode 100644 index 000000000..42f39eec6 --- /dev/null +++ b/test/val/bug1552.c @@ -0,0 +1,42 @@ + +/* + bug #1552 - crash in fuzix xec.c + + cc65 -t none -O bug1552.c +*/ + +#include <stdio.h> + +typedef struct trenod *TREPTR; +typedef struct whnod *WHPTR; + +struct trenod { + int tretyp; +}; + +struct whnod { + int whtyp; + TREPTR whtre; +}; + +int execute(TREPTR argt, int execflg, int *pf1, int *pf2) +{ + register TREPTR t; + int type; + switch (type) + { + case 6: + { + while ((execute(((WHPTR) t)->whtre, 0, NULL, NULL) == 0) == (type == 5)) { + + } + break; + } + } + return 0; +} + +int main(void) +{ + return execute((TREPTR)42, 2, (int *)3, (int *)4); +} From cf1c0b67747be04a6a0b9aabff4c1aae2f761214 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 28 Sep 2021 22:18:49 +0200 Subject: [PATCH 2145/2161] move hints on how to run binaries from the target specific pages to the intro page, where they should be. --- doc/gamate.sgml | 11 ++---- doc/intro.sgml | 94 ++++++++++++++++++++++++++++++++++++++++--------- doc/pce.sgml | 7 +--- 3 files changed, 80 insertions(+), 32 deletions(-) diff --git a/doc/gamate.sgml b/doc/gamate.sgml index 8e18ab76d..b61053ce8 100644 --- a/doc/gamate.sgml +++ b/doc/gamate.sgml @@ -3,7 +3,7 @@ <article> <title>Gamate System specific information for cc65 <author> -<url url="mailto:groepaz@gmx.net" name="Groepaz/Hitmen"> +<url url="mailto:groepaz@gmx.net" name="Groepaz"> <abstract> An overview over the Gamate runtime system as it is implemented for the @@ -117,14 +117,7 @@ following functions (and a few others): <sect>Other hints<p> <itemize> -<item>The Gamate is emulated by MESS (<url url="http://www.mess.org/">), -run like this: <tt>mess gamate -debug -window -skip_gameinfo -cart test.bin</tt> -</itemize> - -some resources on the Gamate: - -<itemize> -<item><url url="http://en.wikipedia.org/wiki/Gamate"> +<item>some resources on the Gamate: <url url="http://en.wikipedia.org/wiki/Gamate"> </itemize> <sect>License<p> diff --git a/doc/intro.sgml b/doc/intro.sgml index b2b141d10..0617b0ab3 100644 --- a/doc/intro.sgml +++ b/doc/intro.sgml @@ -6,6 +6,7 @@ <url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <url url="mailto:cbmnut@hushmail.com" name="CbmNut">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King">,<newline> +<url url="mailto:groepaz@gmx.net" name="Groepaz">,<newline> <url url="mailto:stephan.muehlstrasser@web.de" name="Stephan Mühlstrasser"> <abstract> @@ -458,12 +459,8 @@ Substitute the name of a Commodore computer for that <tt/<sys>/: Start the desired version of the emulator (CBM610 programs run on the CBM II [<tt/xcbm2/] emulator). -In the Windows versions of VICE, choose <bf>File>Autoboot disk/tape -image...</bf>, choose your executable, and click <bf/OK/. - -In the Unix versions, hold down the mouse's first button. Move the pointer to -<bf>Smart-attach disk/tape...</bf>, and release the button. Choose your -executable, and click <bf/Autostart/. +Choose <bf>File>Autostart disk/tape image...</bf>, choose your executable, +and click <bf/OK/. The file has a 14-byte header which corresponds to a PRG-format BASIC program, consisting of a single line, similar to this: @@ -499,6 +496,29 @@ The output will appear on a separate line, and you will be returned to a BASIC prompt. +<sect1>Gamate<p> + +Before you can run the cartridge image produced by the linker, the binary has to +be patched using the <bf/gamate-fixcart/ tool that is included in the cc65 +package in the util/gamata directory. + +<tscreen><verb> +gamate-fixcart <image.bin> +</verb></tscreen> + +<sect2>MESS<p> +Available at <url +url="https://www.mamedev.org">: + +MESS (Multiple Emulator Super System) is a multi system emulator that emulates +various cc65 targets. It once started as a MAME fork, but was marged into MAME +again at some point. + +<tscreen><verb> +mess gamate -debug -window -skip_gameinfo -cart <image.bin> +</verb></tscreen> + + <sect1>GEOS<p> Available at <it/Click Here Software's/ <url url="http://cbmfiles.com/geos/index.html" name="GEOS download section">: @@ -535,17 +555,8 @@ feature on. </quote> <quote> -VICE even has different ways that depend on which operating system is running -the emulator. -<itemize> -<item>In Windows, you must click on <bf/Options/ (in an always visible menu). - Then, you must click on <bf/True drive emulation/. -<item>In Unix, you must <em/hold down/ the second button on your mouse. Move - the pointer down to <bf/Drive settings/. Then, move the pointer over to - <bf/Enable true drive emulation/. (If there is a check-mark in front of - those words, that feature already is turned on -- then, move the pointer - off of that menu.) Release the mouse button. -</itemize> +In VICE, got to <bf/Settings/ -> <bf/Settings/, then <bf/Peripherial devices/ -> +<bf/Drive/. Then, you must enable the <bf/True drive emulation/ checkbox. </quote> Find the <bf/CONVERT/ program on the boot disk [tap the 6-key; then, you @@ -572,6 +583,29 @@ directory notePad. Look at the eight file-positions on each page until you see The output is shown in a GEOS dialog box; click <bf/OK/ when you have finished reading it. +Alternatively you can use the <bf/c1541/ program that comes with VICE to write the +file to a disk image directly in GEOS format, so it can be used in GEOS directly +without having to use the <bf/CONVERT/ program. + +<tscreen><verb> +c1541 -attach geos.d64 -geoswrite hello1 +</verb></tscreen> + + +<sect1>Nintendo Entertainment System<p> + +<sect2>Mednafen (NES)<p> +Available at <url +url="https://mednafen.github.io/releases/">: + +Mednafen is a multi system emulator that emulates a couple of the supported +targets of cc65: Apple II/II+, Atari Lynx, Nintendo Entertainment System and +PC Engine/TurboGrafx 16. + +<tscreen><verb> +mednafen -force_module nes <image.bin> +</verb></tscreen> + <sect1>Ohio Scientific Challenger 1P<p> The <tt/osic1p/ runtime library returns to the boot prompt when the main() @@ -694,6 +728,32 @@ Press <RETURN>. After hitting the RETURN key, you should see the boot prompt again. +<sect1>PC Engine/TurboGrafx 16<p> + +For the cartridge image produced by the linker to work in emulators and on real +hardware, its content must be rearranged so the first 8k block becomes the last +8k block in the image. + +For example, for a 32k image this can be done using <bf/dd/ as follows: + +<tscreen><verb> +dd if=infile.bin bs=8K skip=3 > outfile.pce +dd if=infile.bin bs=8K count=3 >> outfile.pce +</verb></tscreen> + +<sect2>Mednafen<p> +Available at <url +url="https://mednafen.github.io/releases/">: + +Mednafen is a multi system emulator that emulates a couple of the supported +targets of cc65: Apple II/II+, Atari Lynx, Nintendo Entertainment System and +PC Engine/TurboGrafx 16. + +<tscreen><verb> +mednafen -force_module pce <image.pce> +</verb></tscreen> + + <sect1>Contributions wanted<p> We need your help! Recommended emulators and instructions for other targets diff --git a/doc/pce.sgml b/doc/pce.sgml index 42a1ca9d3..47eeabcfd 100644 --- a/doc/pce.sgml +++ b/doc/pce.sgml @@ -2,7 +2,7 @@ <article> <title>PC-Engine (TurboGrafx 16) System-specific information for cc65 -<author><url url="mailto:groepaz@gmx.net" name="Groepaz/Hitmen">,<newline> +<author><url url="mailto:groepaz@gmx.net" name="Groepaz">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> <abstract> @@ -206,11 +206,6 @@ following functions (and a few others): <sect>Other hints<p> -<itemize> -<item><url url="https://mednafen.github.io/" name= "Mednafen"> is a good -emulator to use for the PC-Engine. -</itemize> - Some useful resources on PCE coding: <itemize> From 94445cd16ffdcd245e1c0d1a1f23a2375fac2ca9 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 28 Sep 2021 22:37:34 +0200 Subject: [PATCH 2146/2161] remove conio.pce from the default target and print a message instead --- targettest/pce/Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/targettest/pce/Makefile b/targettest/pce/Makefile index 1ecc0566f..f91f0eed8 100644 --- a/targettest/pce/Makefile +++ b/targettest/pce/Makefile @@ -42,14 +42,15 @@ else COUNT := 1 endif -all: conio.pce +all: conio.bin + +%.bin: %.c + $(CL) -t pce $< -Wl -D__CARTSIZE__=${CARTSIZE} -m $*.map -o $@ + @echo "use 'make conio.pce' to produce a .pce file using dd" %.pce: %.bin dd if=$< bs=8K skip=${COUNT} > $@ dd if=$< bs=8K count=${COUNT} >> $@ -%.bin: %.c - $(CL) -t pce $< -Wl -D__CARTSIZE__=${CARTSIZE} -m $*.map -o $@ - clean: @$(DEL) conio.o conio.??? 2>$(NULLDEV) From 2338e70709294a93d69d1f8bdc50d51509566b24 Mon Sep 17 00:00:00 2001 From: cc65 Owner <41281059+cc65-github@users.noreply.github.com> Date: Wed, 29 Sep 2021 10:37:44 +0200 Subject: [PATCH 2147/2161] travis-ci.org -> travis-ci.com --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2c84b7430..36a4b56cd 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [Wiki](https://github.com/cc65/wiki/wiki) -[![Build Status](https://api.travis-ci.org/cc65/cc65.svg?branch=master)](https://travis-ci.org/cc65/cc65/builds) +[![Build Status](https://app.travis-ci.com/cc65/cc65.svg?branch=master)](https://app.travis-ci.com/cc65/cc65) cc65 is a complete cross development package for 65(C)02 systems, including a powerful macro assembler, a C compiler, linker, librarian and several From 674a5439096b6bb16a3622e45b8a5f0c5218c998 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 29 Sep 2021 12:33:51 +0200 Subject: [PATCH 2148/2161] Parallelize build Travis CI defaults to 2 core environments. --- .travis.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0b25e5d16..c9068193a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,14 +9,14 @@ jobs: - sudo apt-get update - sudo apt-get install linuxdoc-tools linuxdoc-tools-info binutils-mingw-w64-i686 gcc-mingw-w64-i686 sshpass script: - - make bin USER_CFLAGS=-Werror - - make lib QUIET=1 - - make test QUIET=1 - - make samples + - make -j2 bin USER_CFLAGS=-Werror + - make -j2 lib QUIET=1 + - make -j2 test QUIET=1 + - make -j2 samples - make -C src clean - - make bin USER_CFLAGS=-Werror CROSS_COMPILE=i686-w64-mingw32- + - make -j2 bin USER_CFLAGS=-Werror CROSS_COMPILE=i686-w64-mingw32- - make -C samples clean - - make doc zip + - make -j2 doc zip after_success: - make -f Makefile.travis From c48e821c4bfe9d4bd178a742261808c79bd65e1a Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 29 Sep 2021 14:48:09 +0200 Subject: [PATCH 2149/2161] Don --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c9068193a..4b0919a10 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ jobs: script: - make -j2 bin USER_CFLAGS=-Werror - make -j2 lib QUIET=1 - - make -j2 test QUIET=1 + - make test QUIET=1 - make -j2 samples - make -C src clean - make -j2 bin USER_CFLAGS=-Werror CROSS_COMPILE=i686-w64-mingw32- From f6636635fae4ed40bb687ed13eff5f8e91e56883 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 5 Oct 2021 19:17:16 +0200 Subject: [PATCH 2150/2161] targettest/atari/multi-xex.cfg: fix comments --- targettest/atari/multi-xex.cfg | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/targettest/atari/multi-xex.cfg b/targettest/atari/multi-xex.cfg index 7558aa895..f13a9eabe 100644 --- a/targettest/atari/multi-xex.cfg +++ b/targettest/atari/multi-xex.cfg @@ -5,13 +5,13 @@ MEMORY { ZP: file = "", define = yes, start = $0082, size = $007E; # First memory segment in file, show message LOADER: file = %O, start = $680, size = 128; - # First memory segment in file, load over COLOR registers: + # Second memory segment in file, load over COLOR registers: COLOR: file = %O, start = $2C4, size = 5; - # Second memory segment, load at page 6: + # Third memory segment, load at page 6: PAGE6: file = %O, start = $600, size = 128; - # Third memory segment in file, load over SDLST register: + # Fourth memory segment in file, load over SDLST register: SDLST: file = %O, start = $230, size = 2; - # Main segment, load at "STARTADDRESS" + # Fifth/Main segment, load at "STARTADDRESS" MAIN: file = %O, start = %S, size = $BC20 - %S; } FILES { From c3d7a900844673cc4a85f0c132a2faa00886f711 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 5 Oct 2021 19:19:54 +0200 Subject: [PATCH 2151/2161] targettest/atari/ostype.c: remove warnings --- targettest/atari/ostype.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targettest/atari/ostype.c b/targettest/atari/ostype.c index 552735ac8..5561f64fd 100644 --- a/targettest/atari/ostype.c +++ b/targettest/atari/ostype.c @@ -9,9 +9,9 @@ int main(void) { + char *rev; unsigned int t, v; unsigned char palntsc; - unsigned char *rev; unsigned char minor; unsigned char c; From 4f87c7cc645c72903f99c78abcf52124b1e14623 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 23 Oct 2021 01:18:17 +0200 Subject: [PATCH 2152/2161] move samples that only work for a specific target into subdirs named the same as the target --- samples/Makefile | 23 +-- samples/atari2600/Makefile | 59 +++++++ .../{atari2600hello.c => atari2600/hello.c} | 0 samples/cbm/Makefile | 164 ++++++++++++++++++ samples/{ => cbm}/fire.c | 0 samples/{ => cbm}/nachtm.c | 0 samples/{ => cbm}/plasma.c | 0 samples/readme.txt | 89 ++++++---- samples/supervision/Makefile | 59 +++++++ .../hello.c} | 0 10 files changed, 343 insertions(+), 51 deletions(-) create mode 100644 samples/atari2600/Makefile rename samples/{atari2600hello.c => atari2600/hello.c} (100%) create mode 100644 samples/cbm/Makefile rename samples/{ => cbm}/fire.c (100%) rename samples/{ => cbm}/nachtm.c (100%) rename samples/{ => cbm}/plasma.c (100%) create mode 100644 samples/supervision/Makefile rename samples/{supervisionhello.c => supervision/hello.c} (100%) diff --git a/samples/Makefile b/samples/Makefile index 7e5c1934d..db7bb0d84 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -154,7 +154,7 @@ endif # Lists of subdirectories # disasm depends on cpp -DIRLIST = tutorial geos +DIRLIST = tutorial geos atari2600 supervision cbm # -------------------------------------------------------------------------- # Lists of executables @@ -205,28 +205,22 @@ EXELIST_bbc = \ EXELIST_c64 = \ ascii \ enumdevdir \ - fire \ gunzip65 \ hello \ mandelbrot \ mousedemo \ multdemo \ - nachtm \ ovrldemo \ - plasma \ sieve \ tgidemo EXELIST_c128 = \ ascii \ enumdevdir \ - fire \ gunzip65 \ hello \ mandelbrot \ mousedemo \ - nachtm \ - plasma \ sieve \ tgidemo @@ -237,19 +231,15 @@ EXELIST_c16 = \ EXELIST_cbm510 = \ ascii \ - fire \ gunzip65 \ hello \ mousedemo \ - nachtm \ - plasma \ sieve EXELIST_cbm610 = \ ascii \ gunzip65 \ hello \ - nachtm \ sieve EXELIST_creativision = \ @@ -302,7 +292,6 @@ EXELIST_plus4 = \ enumdevdir \ gunzip65 \ hello \ - plasma \ sieve EXELIST_sim6502 = \ @@ -311,7 +300,7 @@ EXELIST_sim6502 = \ EXELIST_sim65c02 = $(EXELIST_sim6502) EXELIST_supervision = \ - supervisionhello + notavailable EXELIST_telestrat = \ ascii \ @@ -398,7 +387,7 @@ $(C1541) -attach $@ -write "$(subst ?,$(SPACE),$(file))" $(notdir $(file)),s >$( endef # D64_WRITE_SEQ_recipe samples.d64: samples - @$(C1541) -format samples,AA d64 $@ >$(NULLDEV) + @$(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)) @@ -460,11 +449,17 @@ install: $(INSTALL) -d $(DESTDIR)$(samplesdir) $(INSTALL) -d $(DESTDIR)$(samplesdir)/geos $(INSTALL) -d $(DESTDIR)$(samplesdir)/tutorial + $(INSTALL) -d $(DESTDIR)$(samplesdir)/atari2600 + $(INSTALL) -d $(DESTDIR)$(samplesdir)/cbm + $(INSTALL) -d $(DESTDIR)$(samplesdir)/supervision $(INSTALL) -m0644 *.* $(DESTDIR)$(samplesdir) $(INSTALL) -m0644 readme.txt $(DESTDIR)$(samplesdir) $(INSTALL) -m0644 Makefile $(DESTDIR)$(samplesdir) $(INSTALL) -m0644 geos/*.* $(DESTDIR)$(samplesdir)/geos $(INSTALL) -m0644 tutorial/*.* $(DESTDIR)$(samplesdir)/tutorial + $(INSTALL) -m0644 atari2600/*.* $(DESTDIR)$(samplesdir)/atari2600 + $(INSTALL) -m0644 cbm/*.* $(DESTDIR)$(samplesdir)/cbm + $(INSTALL) -m0644 supervision/*.* $(DESTDIR)$(samplesdir)/supervision # -------------------------------------------------------------------------- # Packaging rules diff --git a/samples/atari2600/Makefile b/samples/atari2600/Makefile new file mode 100644 index 000000000..a02ec9e80 --- /dev/null +++ b/samples/atari2600/Makefile @@ -0,0 +1,59 @@ + +# Run 'make SYS=<target>'; or, set a SYS env. +# var. to build for another target system. +SYS ?= atari2600 + +# 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 + SP = $(CC65_HOME)/bin/sp65 +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) + SP := $(if $(wildcard ../../bin/sp65*),../../bin/sp65,sp65) +endif + +EXELIST_atari2600 = \ + hello + +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: atari 2600 samples not available for" $(SYS) +else +# suppress the "nothing to be done for 'samples' message + @echo > $(NULLDEV) +endif + +hello: hello.c + $(CL) -t $(SYS) -O -o hello -m hello.map hello.c + +clean: + @$(DEL) $(EXELIST_atari2600) 2>$(NULLDEV) + @$(DEL) *.map 2>$(NULLDEV) diff --git a/samples/atari2600hello.c b/samples/atari2600/hello.c similarity index 100% rename from samples/atari2600hello.c rename to samples/atari2600/hello.c diff --git a/samples/cbm/Makefile b/samples/cbm/Makefile new file mode 100644 index 000000000..989710932 --- /dev/null +++ b/samples/cbm/Makefile @@ -0,0 +1,164 @@ + +# Run 'make SYS=<target>'; or, set a SYS env. +# var. to build for another target system. +SYS ?= c64 + +# 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 + SP = $(CC65_HOME)/bin/sp65 +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) + SP := $(if $(wildcard ../../bin/sp65*),../../bin/sp65,sp65) +endif + +ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),) + ifdef CC65_HOME + TARGET_PATH = $(CC65_HOME)/target + else + TARGET_PATH := $(if $(wildcard ../target),../target,$(shell $(CL) --print-target-path)) + endif + + # If TARGET_PATH contains spaces then it is presumed to contain escaped spaces. GNU make + # has very limited support for paths containing spaces. $(wildcard) is the only function + # that is aware of escaped spaces. However, $(wildcard) never returns paths with escaped + # spaces !!! So if it e.g. finds 4 files in a path with 2 spaces then one ends up with a + # return value consisting of 12 plain words :-(( + # + # Fortunately we can work around that behaviour here because we know that the files we + # are looking for have known extensions. So we can $(filter) the in our example above 12 + # words for file extensions so we come up with 4 path fragments. Then we remove those + # path fragments with $(notdir) from the file names. + # + # So far so good. But here we want to process files from different paths in a single + # recipe further down below and therefore want to prepend the paths to the files with + # $(addprefix). However, $(foreach) isn't aware of escaped spaces (only $(wildcard) is). + # Therefore, we need to replace the spaces with some other character temporarily in order + # to have $(foreach) generate one invocation per file. We use the character '?' for that + # purpose here, just because it is known to not be part of file names. + # + # Inside the recipe generated per file we then replace the '?' again with a space. As we + # want to be compatible with cmd.exe for execution we're not using an escaped space but + # rather double-quote the whole path. + # + # Note: The "strange" $(wildcard) further down below just serves the purpose to unescape + # spaces for cmd.exe. This could have as well been done with another $(subst). + + SUBST_TARGET_PATH := $(subst \$(SPACE),?,$(TARGET_PATH)) + + EMD := $(wildcard $(TARGET_PATH)/$(SYS)/drv/emd/*) + MOU := $(wildcard $(TARGET_PATH)/$(SYS)/drv/mou/*) + TGI := $(wildcard $(TARGET_PATH)/$(SYS)/drv/tgi/*) + + 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)))) + + # This one comes with the VICE emulator. + # See http://vice-emu.sourceforge.net/ + C1541 ?= c1541 +endif + +DISK_c64 = samples.d64 + +EXELIST_c64 = \ + fire \ + plasma \ + nachtm + +EXELIST_c128 = \ + fire \ + plasma \ + nachtm + +EXELIST_cbm510 = \ + fire \ + plasma \ + nachtm + +EXELIST_cbm610 = \ + nachtm + +EXELIST_plus4 = \ + plasma + +EXELIST_c16 = \ + notavailable + +EXELIST_pet = \ + notavailable + +EXELIST_vic20 = \ + notavailable + +ifneq ($(EXELIST_$(SYS)),) +samples: $(EXELIST_$(SYS)) +else +samples: notavailable +endif + +disk: $(DISK_$(SYS)) + +# empty target used to skip systems that will not work with any program in this dir +notavailable: +ifeq ($(MAKELEVEL),0) + @echo "info: cbm samples not available for" $(SYS) +else +# suppress the "nothing to be done for 'samples' message + @echo > $(NULLDEV) +endif + +fire: fire.c + $(CL) -t $(SYS) -O -o fire -m fire.map fire.c +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 + +# -------------------------------------------------------------------------- +# Rule to make a CBM disk with all samples. Needs the c1541 program that comes +# with the VICE emulator. + +define D64_WRITE_PRG_recipe + +$(C1541) -attach $@ -write "$(subst ?,$(SPACE),$(file))" $(notdir $(file)),p >$(NULLDEV) + +endef # D64_WRITE_PRG_recipe + +define D64_WRITE_SEQ_recipe + +$(C1541) -attach $@ -write "$(subst ?,$(SPACE),$(file))" $(notdir $(file)),s >$(NULLDEV) + +endef # D64_WRITE_SEQ_recipe + +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)) + +clean: + @$(DEL) $(EXELIST_$(SYS)) 2>$(NULLDEV) + @$(DEL) *.map 2>$(NULLDEV) + @$(DEL) $(DISK_$(SYS)) 2>$(NULLDEV) diff --git a/samples/fire.c b/samples/cbm/fire.c similarity index 100% rename from samples/fire.c rename to samples/cbm/fire.c diff --git a/samples/nachtm.c b/samples/cbm/nachtm.c similarity index 100% rename from samples/nachtm.c rename to samples/cbm/nachtm.c diff --git a/samples/plasma.c b/samples/cbm/plasma.c similarity index 100% rename from samples/plasma.c rename to samples/cbm/plasma.c diff --git a/samples/readme.txt b/samples/readme.txt index 3c9247c39..56b275764 100644 --- a/samples/readme.txt +++ b/samples/readme.txt @@ -10,11 +10,13 @@ Please note: similar systems. If you're using Windows, then consider installing Cygwin or MSys2. - * The makefile specifies the C64 as the default target system because all - but three of the programs run on that platform. When compiling for another - system, you will have to change the line that specifies the target system - at the top of the makefile, specify the system with SYS=<target> on the - make command line, or set a SYS environment variable. + * The makefile specifies the C64 as the default target system because most + of the programs run on that platform. When compiling for another system, + you will have to change the line that specifies the target system at the + top of the makefile, specify the system with SYS=<target> on the make + command line, or set a SYS environment variable. For example: + + make SYS=apple2 * Use "make disk" to build a disk image with all sample programs. @@ -31,11 +33,6 @@ Description: Shows the ASCII (or ATASCII, PETSCII) codes of typed <greg.king5@verizon.com>. Platforms: All platforms with conio or stdio (compile time configurable). ------------------------------------------------------------------------------ -Name: atari2600hello -Description: A "Hello world" type program. -Platforms: Runs on only the Atari 2600 Video Console System. - ----------------------------------------------------------------------------- Name: diodemo Description: A disc copy program written and contributed by Oliver @@ -52,12 +49,6 @@ Platforms: All systems with device enumeration and directory access (currently the Commodore machines, the Commander X16, and the Apple ][). ------------------------------------------------------------------------------ -Name: fire -Description: Another graphics demo written by groepaz/hitmen. -Platforms: The program currently is running on only the C64, but should - be portable to the C128 and CBM510 (and maybe more machines). - ----------------------------------------------------------------------------- Name: gunzip65 Description: A gunzip utility for 6502-based machines, written by Piotr @@ -76,8 +67,8 @@ Platforms: Runs on all platforms that support conio, which means: ----------------------------------------------------------------------------- Name: mandelbrot Description: A mandelbrot demo using integer arithmetic. The demo was - written by groepaz/hitmen, and converted to cc65 using TGI - graphics by Stephan Haubenthal. + written by groepaz, and converted to cc65 using TGI graphics + by Stephan Haubenthal. Platforms: Runs on all platforms that have TGI support: Apple ][, Atari, C64, C128, Oric Atmos and Telestrat, GEOS, NES, and Lynx. @@ -97,13 +88,6 @@ Platforms: All systems with an overlay linker config., disk directory access, and EMD support (currently the C64, the C128, the Atari, and the Apple ][). ------------------------------------------------------------------------------ -Name: nachtm -Description: Plays "Eine kleine Nachtmusik" by Wolfgang Amadeus Mozart. -Platforms: All systems that have the Commodore SID (Sound Interface - Device): - C64, C128, CBM510, CBM610. - ----------------------------------------------------------------------------- Name: overlaydemo Description: Shows how to load overlay files from disk. Written and @@ -111,13 +95,6 @@ Description: Shows how to load overlay files from disk. Written and Platforms: All systems with an overlay linker config. (currently the C64, the C128, the Atari, and the Apple ][). ------------------------------------------------------------------------------ -Name: plasma -Description: A fancy graphics demo written by groepaz/hitmen. -Platforms: The program needs a VIC-II or a TED, so it runs on the following - systems: - C64, C128, CBM510, Plus/4. - ----------------------------------------------------------------------------- Name: sieve Description: Implements the "Sieve of Eratosthenes" as a way to find all @@ -128,11 +105,6 @@ Platforms: All systems with conio and clock support: Commander X16, Apple ][ (without timing due to missing clock support). ------------------------------------------------------------------------------ -Name: supervisionhello -Description: A "Hello world" type program. -Platforms: Runs on only the Watara Supervision game console. - ----------------------------------------------------------------------------- Name: tgidemo Description: Shows some of the graphics capabilities of the "Tiny Graphics @@ -140,3 +112,46 @@ Description: Shows some of the graphics capabilities of the "Tiny Graphics Platforms: Runs on all platforms that have TGI support: Apple ][, Atari, C64, C128, Oric Atmos and Telestrat, GEOS, NES, and Lynx. + +============================================================================= + +Platform specific samples follow: + +atari 2600: +----------- + +Name: hello +Description: A "Hello world" type program. +Platforms: Runs on only the Atari 2600 Video Console System. +----------------------------------------------------------------------------- + +cbm: +---- + +Name: fire +Description: Another graphics demo written by groepaz. +Platforms: C64, C128, CBM510 + +----------------------------------------------------------------------------- +Name: nachtm +Description: Plays "Eine kleine Nachtmusik" by Wolfgang Amadeus Mozart. +Platforms: All systems that have the Commodore SID (Sound Interface + Device): + C64, C128, CBM510, CBM610. + +----------------------------------------------------------------------------- +Name: plasma +Description: A fancy graphics demo written by groepaz. +Platforms: The program needs a VIC-II or a TED, so it runs on the following + systems: + C64, C128, CBM510, Plus/4. +----------------------------------------------------------------------------- + + +supervision: +------------ + +Name: hello +Description: A "Hello world" type program. +Platforms: Runs on only the Watara Supervision game console. +---------------------------------------------------------------------------- diff --git a/samples/supervision/Makefile b/samples/supervision/Makefile new file mode 100644 index 000000000..5829b3f01 --- /dev/null +++ b/samples/supervision/Makefile @@ -0,0 +1,59 @@ + +# Run 'make SYS=<target>'; or, set a SYS env. +# var. to build for another target system. +SYS ?= supervision + +# 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 + SP = $(CC65_HOME)/bin/sp65 +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) + SP := $(if $(wildcard ../../bin/sp65*),../../bin/sp65,sp65) +endif + +EXELIST_supervision = \ + hello + +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: supervision samples not available for" $(SYS) +else +# suppress the "nothing to be done for 'samples' message + @echo > $(NULLDEV) +endif + +hello: hello.c + $(CL) -t $(SYS) -O -o hello -m hello.map hello.c + +clean: + @$(DEL) $(EXELIST_supervision) 2>$(NULLDEV) + @$(DEL) *.map 2>$(NULLDEV) diff --git a/samples/supervisionhello.c b/samples/supervision/hello.c similarity index 100% rename from samples/supervisionhello.c rename to samples/supervision/hello.c From f796c260910cf6047623c3c550fa1153f4e839ae Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 21 Nov 2021 22:56:02 +0100 Subject: [PATCH 2153/2161] Added hint on clock(). clock() isn't available on the Apple II - and never will be. --- doc/library.sgml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/library.sgml b/doc/library.sgml index 303809c59..bcd5db86e 100644 --- a/doc/library.sgml +++ b/doc/library.sgml @@ -59,6 +59,9 @@ Functions that are <em/not/ available: Functions not available on all supported systems: <itemize> + <item><tt>clock</tt>: Support depends on the capabilities of the target + machine. + <p> <item><tt>fopen/fread/fwrite/fclose/fputs/fgets/fscanf</tt>: The functions are built on open/read/write/close. Those latter functions are not available on all systems. From 6637e288318f10cf789faedb3ef46f2323691fa3 Mon Sep 17 00:00:00 2001 From: Gabriele Gorla <44734244+gorlik@users.noreply.github.com> Date: Wed, 8 Sep 2021 15:00:20 -0700 Subject: [PATCH 2154/2161] saves 2 bytes in the standard c64 joystick driver remove redundant code and add jmp to the common sequence two more bytes could be saved at the expense of longer sequence with interrupts disabled by moving sei/cli --- libsrc/c64/joy/c64-stdjoy.s | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/libsrc/c64/joy/c64-stdjoy.s b/libsrc/c64/joy/c64-stdjoy.s index c983d81bb..d11093fba 100644 --- a/libsrc/c64/joy/c64-stdjoy.s +++ b/libsrc/c64/joy/c64-stdjoy.s @@ -93,9 +93,7 @@ joy1: lda #$7F sta CIA1_PRA lda CIA1_PRB cli - and #$1F - eor #$1F - rts + jmp end ; Read joystick 2 @@ -107,8 +105,6 @@ joy2: ldx #0 lda CIA1_PRA sty CIA1_DDRA cli - and #$1F +end: and #$1F eor #$1F rts - - From 1918f0ac9b81e119256b6c71b6bab79e3d55d47a Mon Sep 17 00:00:00 2001 From: gorlik <44734244+gorlik@users.noreply.github.com> Date: Mon, 13 Sep 2021 12:27:37 -0700 Subject: [PATCH 2155/2161] adding missing VIC register definition to c64.inc --- asminc/c64.inc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asminc/c64.inc b/asminc/c64.inc index 2cfc50db4..d131c7860 100644 --- a/asminc/c64.inc +++ b/asminc/c64.inc @@ -77,6 +77,8 @@ 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 From a7e6f9840ca12798629efaf7e992b12d31a929e4 Mon Sep 17 00:00:00 2001 From: Gerhard Gruber <gerhard.gruber@gdata.de> Date: Wed, 22 Sep 2021 11:38:49 +0200 Subject: [PATCH 2156/2161] VIC-20 and C128 cfg added for ASM programming --- cfg/c128-asm.cfg | 20 ++++++++++++++++++++ cfg/vic20-asm.cfg | 19 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 cfg/c128-asm.cfg create mode 100644 cfg/vic20-asm.cfg diff --git a/cfg/c128-asm.cfg b/cfg/c128-asm.cfg new file mode 100644 index 000000000..0da296c71 --- /dev/null +++ b/cfg/c128-asm.cfg @@ -0,0 +1,20 @@ +FEATURES { + STARTADDRESS: default = $1c01; +} +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/vic20-asm.cfg b/cfg/vic20-asm.cfg new file mode 100644 index 000000000..7ab70888c --- /dev/null +++ b/cfg/vic20-asm.cfg @@ -0,0 +1,19 @@ +FEATURES { + STARTADDRESS: default = $1001; +} +SYMBOLS { + __LOADADDR__: type = import; +} +MEMORY { + ZP: file = "", start = $0002, size = $001A, define = yes; + LOADADDR: file = %O, start = $1001, size = $0002; + MAIN: file = %O, start = %S, size = $0DF3 - %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; +} From cb0dca0ca76d0ea8abd582fdf283d73bb616895d Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 24 Nov 2021 14:17:18 +0100 Subject: [PATCH 2157/2161] No more Travis-CI ! --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 2a31d42be..f6142e2c1 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@ [Wiki](https://github.com/cc65/wiki/wiki) -[![Build Status](https://app.travis-ci.com/cc65/cc65.svg?branch=master)](https://app.travis-ci.com/cc65/cc65) - cc65 is a complete cross development package for 65(C)02 systems, including a powerful macro assembler, a C compiler, linker, librarian and several other tools. From 1d36f255ecf401f1c69ce5f337b936fd0cf08154 Mon Sep 17 00:00:00 2001 From: Wayne Parham <wayne@parhamdata.com> Date: Wed, 24 Nov 2021 14:30:19 -0600 Subject: [PATCH 2158/2161] Added Sym-1 link to documentation doc/index.sgml --- doc/index.sgml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/index.sgml b/doc/index.sgml index 01325529d..3bb085bf6 100644 --- a/doc/index.sgml +++ b/doc/index.sgml @@ -172,6 +172,9 @@ <tag><htmlurl url="supervision.html" name="supervision.html"></tag> Topics specific to the Watara Supervision Console. + <tag><htmlurl url="sym1.html" name="sym1.html"></tag> + Topics specific to the Synertek Systems Sym-1. + <tag><htmlurl url="telestrat.html" name="telestrat.html"></tag> Topics specific to the Oric Telestrat. From 4eaf68d414c4adf0c2fd7b8746d9e6c9462d2464 Mon Sep 17 00:00:00 2001 From: David Hogan <david.q.hogan@gmail.com> Date: Sat, 11 Dec 2021 11:30:21 +1100 Subject: [PATCH 2159/2161] Automated Github pull request build and test --- .github/workflows/build-on-pull-request.yml | 56 +++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 .github/workflows/build-on-pull-request.yml diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml new file mode 100644 index 000000000..53f79fef4 --- /dev/null +++ b/.github/workflows/build-on-pull-request.yml @@ -0,0 +1,56 @@ +name: Build Pull Request +on: [pull_request] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build_linux: + name: Build and Test (Linux) + runs-on: ubuntu-latest + + steps: + - shell: bash + run: git config --global core.autocrlf input + + - name: Checkout Source + uses: actions/checkout@v2 + + - name: Install Dependencies + shell: bash + run: | + sudo apt-get update + sudo apt-get install linuxdoc-tools linuxdoc-tools-info binutils-mingw-w64-i686 gcc-mingw-w64-i686 sshpass + + - name: Build + id: build + shell: bash + run: | + make -j2 bin USER_CFLAGS=-Werror + make -j2 lib QUIET=1 + make test QUIET=1 + make -j2 samples + make -C src clean + make -j2 bin USER_CFLAGS=-Werror CROSS_COMPILE=i686-w64-mingw32- + make -C samples clean + make -j2 doc zip + + build_windows: + name: Build (Windows) + runs-on: windows-latest + + steps: + - shell: bash + run: git config --global core.autocrlf input + + - name: Checkout Source + uses: actions/checkout@v2 + + - 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 (release) + run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release From a39c23f7960c1909e452e8f59257c178d93822fb Mon Sep 17 00:00:00 2001 From: David Hogan <david.q.hogan@gmail.com> Date: Sat, 11 Dec 2021 13:53:53 +1100 Subject: [PATCH 2160/2161] Snapshot build on push master. For now, the snapshot zip can be obtained from the latest successful snapshot build at: https://github.com/cc65/cc65/actions/workflows/snapshot-on-push-master.yml TODO: Update docs at https://github.com/cc65/doc TODO: Publish snapshot zip at https://github.com/cc65/cc65.github.io --- .github/workflows/snapshot-on-push-master.yml | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 .github/workflows/snapshot-on-push-master.yml diff --git a/.github/workflows/snapshot-on-push-master.yml b/.github/workflows/snapshot-on-push-master.yml new file mode 100644 index 000000000..aefc7f2f5 --- /dev/null +++ b/.github/workflows/snapshot-on-push-master.yml @@ -0,0 +1,69 @@ +name: Snapshot Build +on: + push: + branches: + master +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build_windows: + name: Build (Windows) + runs-on: windows-latest + + steps: + - shell: bash + run: git config --global core.autocrlf input + + - name: Checkout Source + uses: actions/checkout@v2 + + - 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 (release) + run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release + + build_linux: + name: Build, Test and Snaphot (Linux) + runs-on: ubuntu-latest + needs: build_windows + + steps: + - shell: bash + run: git config --global core.autocrlf input + + - name: Checkout Source + uses: actions/checkout@v2 + + - name: Install Dependencies + shell: bash + run: | + sudo apt-get update + sudo apt-get install linuxdoc-tools linuxdoc-tools-info binutils-mingw-w64-i686 gcc-mingw-w64-i686 sshpass + + - name: Build + id: build + shell: bash + run: | + make -j2 bin USER_CFLAGS=-Werror + make -j2 lib QUIET=1 + make test QUIET=1 + make -j2 samples + make -C src clean + make -j2 bin USER_CFLAGS=-Werror CROSS_COMPILE=i686-w64-mingw32- + make -C samples clean + make -j2 doc zip + + - name: Upload Snapshot Zip + uses: actions/upload-artifact@v2 + with: + name: cc65-snapshot-win32.zip + path: cc65.zip + + # TODO: Update docs at https://github.com/cc65/doc + # TODO: Publish snapshot zip at https://github.com/cc65/cc65.github.io From bd94879be21719356b4f987c8d9c1dfeccf3bf32 Mon Sep 17 00:00:00 2001 From: dqh-github <david.q.hogan@gmail.com> Date: Sat, 11 Dec 2021 15:28:29 +1100 Subject: [PATCH 2161/2161] Re-added build status badge (Github Actions is now doing a snapshot build and test for updates to the master branch) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f6142e2c1..33c7d2830 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ [Wiki](https://github.com/cc65/wiki/wiki) +[![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) + cc65 is a complete cross development package for 65(C)02 systems, including a powerful macro assembler, a C compiler, linker, librarian and several other tools.